/* Pages alimentées par un feed (plugin content-feeds) : courses, ouvertures,
 * engagements, records.
 *
 * N'utilise que les tokens --q2-* définis par theme.css : le mode sombre suit
 * donc automatiquement, sans règle [data-theme="dark"] dédiée.
 *
 * Feuille partagée par les quatre feeds : la mécanique (méta, filtres,
 * tableau, cartes) est la même partout, seules les colonnes changent. */

/* feeds.js masque en posant l'attribut `hidden`. Sans ce garde-fou, les
 * règles `display:` de la vue mobile (qui transforment les lignes en cartes)
 * l'emporteraient et les lignes filtrées resteraient visibles. */
.feed-courses [hidden],
.feed-cards [hidden],
.feed-records [hidden] {
  display: none !important;
}

.feed-courses,
.feed-cards,
.feed-records {
  margin-block: 1.5rem;
}

.feed-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.25rem;
  margin-bottom: 1rem;
  font-size: 0.875rem;
  color: var(--q2-text-muted);
}

/* Nombre de résultats après filtrage. Détaché du reste du bandeau parce que
 * c'est la seule valeur qui bouge quand on manipule les filtres — noyée dans
 * la ligne grise, elle passait inaperçue. */
.feed-badge {
  display: inline-flex;
  flex-wrap: wrap;
  /* `center` et non `baseline` : le nombre est plus gros que le texte qui le
   * suit, et un alignement sur les lignes de base laissait le contenu assis
   * trop bas dans la pastille. */
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.3125rem;
  padding: 0.3125rem 0.75rem;
  color: var(--q2-text-strong);
  background: color-mix(in srgb, var(--brand-sky) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--brand-sky) 32%, transparent);
  border-radius: var(--q2-radius-pill);
}

.feed-badge strong {
  font-size: 1.0625rem;
  /* Interligne neutralisé : sans ça la boîte de ligne du nombre, plus haute
   * que celle du reste, dictait la hauteur de la pastille et rompait la
   * symétrie du remplissage. */
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.feed-badge [data-count-detail] {
  color: var(--q2-text-muted);
}

/* Surlignage bref à chaque changement de résultat : le badge doit se lire
 * comme une valeur qui réagit, pas comme un constat figé. */
@keyframes feed-badge-pulse {
  from {
    background: color-mix(in srgb, var(--brand-sky) 42%, transparent);
    border-color: color-mix(in srgb, var(--brand-sky) 70%, transparent);
  }
}

.feed-badge.is-updated {
  animation: feed-badge-pulse 0.6s ease-out;
}

@media (prefers-reduced-motion: reduce) {
  .feed-badge.is-updated {
    animation: none;
  }
}

/* ---- Filtres ---- */

.feed-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem 1rem;
  padding: 1rem;
  margin-bottom: 1rem;
  background: var(--q2-bg-elev);
  border-radius: var(--q2-radius-md);
  box-shadow: var(--q2-shadow-card);
}

.feed-filter {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}

.feed-filter > label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--q2-text-muted);
}

.feed-filter input,
.feed-filter select {
  margin: 0;
  height: 2.5rem;
  padding-block: 0;
  font-size: 0.9375rem;
}

.feed-filter--range > div {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.feed-filter--range input {
  width: 7.5rem;
}

.feed-filter--check label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.9375rem;
  white-space: nowrap;
}

.feed-filter--check input {
  height: auto;
  margin: 0;
}

.feed-reset {
  /* Le framework (Pico, blades.min.css) pose `margin-bottom: var(--pico-spacing)`
   * — 1rem, soit 16px — sous tout `button`, comme il le fait sous les champs de
   * formulaire. La règle `.feed-filter input, .feed-filter select { margin: 0 }`
   * plus haut neutralise cette marge pour les champs, mais ne couvrait pas les
   * boutons : le bouton se retrouvait donc poussé 16px au-dessus du bas de la
   * rangée, alors que `align-items: flex-end` alignait correctement sa boîte.
   * Mesuré en devtools (2026-08-27) : bloc de 86,8px là où un filtre en fait
   * 70,8, l'écart étant intégralement sous le bouton. */
  margin: 0;
  height: 2.5rem;
  padding-inline: 1rem;
  font-size: 0.9375rem;
  background: transparent;
  color: var(--q2-text-muted);
  border: 1px solid var(--q2-border-strong);
  border-radius: var(--q2-radius-sm);
  cursor: pointer;
}

.feed-reset:hover {
  color: var(--q2-text-strong);
  background: var(--q2-bg-muted);
}

/* ---- Tableau ---- */

.feed-table-wrap {
  overflow-x: auto;
  border-radius: var(--q2-radius-md);
  box-shadow: var(--q2-shadow-card);
}

.feed-table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
  font-size: 0.9375rem;
  background: var(--q2-bg-elev);
}

.feed-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 0;
  text-align: left;
  background: var(--q2-bg-muted);
  border-bottom: 1px solid var(--q2-border-strong);
}

.feed-table thead button {
  width: 100%;
  padding: 0.625rem 0.75rem;
  font: inherit;
  font-weight: 600;
  text-align: left;
  color: var(--q2-text-strong);
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
}

.feed-table thead button::after {
  content: "";
  margin-left: 0.375rem;
  opacity: 0.45;
}

.feed-table thead th[aria-sort="ascending"] button::after {
  content: "▲";
}

.feed-table thead th[aria-sort="descending"] button::after {
  content: "▼";
}

.feed-table tbody th,
.feed-table tbody td {
  padding: 0.5rem 0.75rem;
  vertical-align: top;
  border-bottom: 1px solid var(--q2-divider);
}

.feed-table tbody th {
  font-weight: 500;
  text-align: left;
}

/* theme.css impose `white-space: nowrap` à tous les td/th pour garder les
 * petits tableaux compacts : les deux colonnes de texte libre doivent le
 * reprendre à leur compte, sinon la ligne s'étire sur toute la largeur. */
.feed-table tbody th[data-label="Épreuve"],
.feed-table tbody td[data-label="Événement"] {
  white-space: normal;
  min-width: 14rem;
}

/* La cellule Club (pastille + chevron du détail des engagés) collait pile au
 * bord de la colonne dans l'auto-layout du tableau — le chevron, plus petit
 * que la pastille, n'avait pas la place de s'afficher en entier. */
.feed-table tbody td[data-label="Club"] {
  min-width: 8rem;
}

.feed-table tbody tr:hover {
  background: var(--q2-bg-muted);
}

.feed-none {
  color: var(--q2-text-muted);
}

.feed-cat {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  font-size: 0.8125rem;
  color: var(--q2-text-muted);
  background: var(--q2-bg-muted);
  border-radius: var(--q2-radius-pill);
  white-space: normal;
}

/* Jauge de remplissage : le fond porte l'information, le texte reste lisible
 * par-dessus (et seul lui est lu par un lecteur d'écran). */
.feed-fill {
  display: inline-block;
  position: relative;
  min-width: 3.5rem;
  padding: 0.125rem 0.5rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
  border-radius: var(--q2-radius-xs);
  background:
    linear-gradient(
      to right,
      color-mix(in srgb, var(--brand-sky) 28%, transparent) var(--fill, 0%),
      var(--q2-bg-muted) var(--fill, 0%)
    );
}

.feed-fill.is-high {
  background:
    linear-gradient(
      to right,
      color-mix(in srgb, #e8a33d 34%, transparent) var(--fill, 0%),
      var(--q2-bg-muted) var(--fill, 0%)
    );
}

.feed-fill.is-full {
  background:
    linear-gradient(
      to right,
      color-mix(in srgb, #d1495b 34%, transparent) var(--fill, 0%),
      var(--q2-bg-muted) var(--fill, 0%)
    );
}

.feed-noresult,
.feed-empty {
  padding: 1.5rem;
  text-align: center;
  color: var(--q2-text-muted);
}

/* ---- Mobile : le tableau devient une liste de cartes ---- */

@media (max-width: 48rem) {
  .feed-filters {
    flex-direction: column;
    align-items: stretch;
  }

  .feed-filter--range input {
    width: 100%;
  }

  .feed-table-wrap {
    overflow-x: visible;
    box-shadow: none;
  }

  .feed-table thead {
    display: none;
  }

  .feed-table,
  .feed-table tbody,
  .feed-table tr {
    display: block;
  }

  .feed-table tbody tr {
    margin-bottom: 0.75rem;
    padding: 0.75rem;
    background: var(--q2-bg-elev);
    border-radius: var(--q2-radius);
    box-shadow: var(--q2-shadow-card);
  }

  .feed-table tbody th,
  .feed-table tbody td {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.25rem 0;
    border: 0;
    white-space: normal;
  }

  .feed-table tbody th::before,
  .feed-table tbody td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--q2-text-muted);
  }

  .feed-table tbody th[data-label="Épreuve"] {
    order: -1;
    padding-bottom: 0.5rem;
    font-size: 1rem;
    font-weight: 600;
  }

  .feed-table tbody th[data-label="Épreuve"]::before {
    display: none;
  }

  .feed-table tbody td[data-label="Club"] {
    align-items: flex-start;
  }

  .feed-table tbody td[data-label="Club"] .feed-club-runners {
    min-width: 0;
    text-align: right;
  }

  .feed-table tbody td[data-label="Club"] .feed-club-runners > ul {
    text-align: left;
  }
}

/* ---- Vue en cartes : un bloc par événement (engagements) ---- */

.feed-card {
  margin-bottom: 1.25rem;
  padding: 1rem;
  background: var(--q2-bg-elev);
  border-radius: var(--q2-radius-md);
  box-shadow: var(--q2-shadow-card);
}

/* ---- Accordéon d'événement ---- */

.feed-card {
  padding: 0;
  overflow: hidden;
}

.feed-card-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 1rem;
  cursor: pointer;
  list-style: none;
}

/* Le marqueur natif est remplacé par un chevron qui pivote : celui de Safari
 * ne se stylise pas, et `list-style: none` seul ne suffit pas à le retirer. */
.feed-card-head::-webkit-details-marker {
  display: none;
}

.feed-card-head::after {
  content: "";
  flex: 0 0 auto;
  width: 0.5rem;
  height: 0.5rem;
  margin-left: 0.25rem;
  border-right: 2px solid var(--q2-text-muted);
  border-bottom: 2px solid var(--q2-text-muted);
  transform: rotate(45deg) translate(-0.125rem, -0.125rem);
  transition: transform 0.15s ease-out;
}

.feed-accordion[open] > .feed-card-head::after {
  transform: rotate(-135deg) translate(-0.125rem, -0.125rem);
}

.feed-card-head:hover {
  background: var(--q2-bg-muted);
}

/* Liste compacte des adhérents inscrits, directement depuis le calendrier. */
.feed-club-runners {
  margin-top: 0.35rem;
}

/* Dans le calendrier, la présence du club a sa propre cellule : elle n'a pas
 * besoin de l'espacement qui la séparait auparavant du nom de l'événement. */
.feed-table td[data-label="Club"] .feed-club-runners {
  margin-top: 0;
}

.feed-club-runners > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
  list-style: none;
}

.feed-club-runners > summary::-webkit-details-marker {
  display: none;
}

.feed-club-toggle {
  /* `flex-shrink: 0` : sans lui, cette icône de taille fixe est le premier
   * élément que l'algorithme flex compresse quand la ligne (carte mobile,
   * ou colonne trop juste) manque de place — elle finit tronquée, lue comme
   * un demi-chevron plutôt qu'un chevron plein. La pastille voisine a déjà
   * son propre `flex-wrap: wrap` comme soupape ; c'est elle qui doit céder
   * de la place, pas cette icône. */
  flex-shrink: 0;
  width: 0.45rem;
  height: 0.45rem;
  border-right: 2px solid var(--q2-text-muted);
  border-bottom: 2px solid var(--q2-text-muted);
  transform: rotate(45deg) translate(-0.1rem, -0.1rem);
  transition: transform 0.15s ease-out;
}

.feed-club-runners[open] .feed-club-toggle {
  transform: rotate(-135deg) translate(-0.1rem, -0.1rem);
}

.feed-club-runners > ul {
  margin: 0.5rem 0 0;
  padding: 0.5rem 0.65rem 0.5rem 1.75rem;
  border-left: 3px solid #238636;
  border-radius: var(--q2-radius-sm);
  background: color-mix(in srgb, #238636 8%, transparent);
}

.feed-club-runners li + li {
  margin-top: 0.25rem;
}

.feed-club-runners li > span {
  display: block;
  color: var(--q2-text-muted);
  font-size: 0.8125rem;
}

.feed-card-titles {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.feed-card-body {
  padding: 0 1rem 1rem;
  border-top: 1px solid var(--q2-divider);
}

.feed-card-link {
  margin: 0.75rem 0 0;
  font-size: 0.875rem;
}

/* ---- Épreuves et coureurs dans un événement ---- */

.feed-course > h4 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 1rem 0 0.375rem;
  font-size: 0.9375rem;
}

.feed-course-count {
  padding: 0 0.4375rem;
  font-size: 0.8125rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--q2-text-muted);
  background: var(--q2-bg-muted);
  border-radius: var(--q2-radius-pill);
}

/* Une ligne = un nom. Les colonnes dossard / catégorie / sexe ont été
 * retirées : le sexe reste filtrable via data-sexe sans être affiché. */
/* Un coureur par ligne. En colonne et non en `flex-wrap` : les noms se
 * plaçaient côte à côte tant qu'il restait de la place, ce qui rendait
 * l'effectif d'une épreuve difficile à lire d'un coup d'œil.
 * `align-items: flex-start` garde chaque pastille à la largeur de son nom
 * plutôt que de l'étirer sur toute la colonne. */
.feed-runners {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.feed-runners li {
  padding: 0.25rem 0.625rem;
  font-size: 0.9375rem;
  background: var(--q2-bg-muted);
  border-radius: var(--q2-radius-sm);
}

.feed-toggle-all {
  height: 2.5rem;
  padding-inline: 1rem;
  font-size: 0.9375rem;
  color: var(--q2-text-strong);
  background: var(--q2-bg-muted);
  border: 1px solid var(--q2-border-strong);
  border-radius: var(--q2-radius-sm);
  cursor: pointer;
}

.feed-toggle-all:hover {
  background: var(--q2-bg-elev);
}

.feed-badge--sm {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 0.1875rem 0.5625rem;
  font-size: 0.8125rem;
}

.feed-badge--sm strong {
  font-size: 0.9375rem;
}

.feed-card-affiche {
  flex: 0 0 auto;
  width: 5rem;
  height: 5rem;
  object-fit: cover;
  border-radius: var(--q2-radius-sm);
  background: var(--q2-bg-muted);
}

.feed-card-title {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.3;
}

.feed-card-date {
  font-size: 0.875rem;
  color: var(--q2-text-muted);
}

.feed-card .feed-table-wrap {
  box-shadow: none;
}

.feed-card .feed-table {
  background: transparent;
}

/* Le sexe est une donnée du feed, rendue en pastille plutôt qu'en lettre nue. */
.feed-sexe {
  display: inline-block;
  min-width: 1.5rem;
  padding: 0 0.375rem;
  font-size: 0.8125rem;
  font-weight: 600;
  text-align: center;
  border-radius: var(--q2-radius-pill);
  background: var(--q2-bg-muted);
  color: var(--q2-text-muted);
}

/* ---- Onglets (records) ---- */

.feed-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-bottom: 1rem;
  padding: 0.25rem;
  background: var(--q2-bg-muted);
  border-radius: var(--q2-radius-md);
}

.feed-tabs button {
  padding: 0.5rem 0.875rem;
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--q2-text-muted);
  background: transparent;
  border: 0;
  border-radius: var(--q2-radius-sm);
  cursor: pointer;
}

.feed-tabs button:hover {
  color: var(--q2-text-strong);
}

.feed-tabs button[aria-selected="true"] {
  color: var(--q2-text-strong);
  background: var(--q2-bg-elev);
  box-shadow: var(--q2-shadow-card);
}

.feed-section {
  margin-bottom: 1.5rem;
}

.feed-section > h4 {
  margin: 0 0 0.5rem;
  font-size: 1.0625rem;
}

/* Intertitre de famille (« Sprint », « Lancers ») : sépare visiblement des
 * dizaines de sections qui s'aligneraient sinon à plat sous un onglet. */
.feed-famille {
  margin: 2rem 0 0.75rem;
  padding-bottom: 0.375rem;
  font-size: 1.25rem;
  border-bottom: 1px solid var(--q2-border-strong);
}

.feed-famille:first-of-type {
  margin-top: 0.5rem;
}

/* Le rang n'existe que dans les tableaux classés : colonne étroite, chiffres
 * alignés. Les tableaux « par catégorie » ne la rendent pas du tout. */
.feed-table td[data-label="Rang"] {
  width: 3rem;
  font-variant-numeric: tabular-nums;
  color: var(--q2-text-muted);
}

.feed-perf {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}

/* ---- Podium (sections classées de la page records) ---- */

/* Seule entorse assumée au « rien que des tokens --q2-* » de cette feuille :
 * or, argent et bronze sont le sujet du podium, aucune nuance neutre ne les
 * remplace. Elles ne servent que de lavis sur le socle et de filet sur la
 * carte — le texte, lui, reste sur les tokens du thème, ce qui garantit son
 * contraste dans les deux modes sans avoir à doser les teintes. */
.feed-podium {
  --medaille-or: #a8801f;
  --medaille-argent: #7f8794;
  --medaille-bronze: #a0663a;

  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

:root[data-theme="dark"] .feed-podium {
  --medaille-or: #d9b64a;
  --medaille-argent: #b6bcc6;
  --medaille-bronze: #c98a5c;
}

.feed-step {
  display: flex;
  flex-direction: column;
  /* `1 1 0` et non `auto` : les trois marches gardent la même largeur quel que
   * soit le nombre de caractères du nom, sinon l'escalier penche. Le plafond
   * évite qu'une section incomplète (une ou deux places seulement, ça existe
   * dans le feed) n'étale ses cartes sur toute la largeur. */
  flex: 1 1 0;
  min-width: 0;
  max-width: 16rem;
}

/* L'ordre visuel du podium (2 - 1 - 3) ne vaut que pour l'œil : le DOM reste
 * dans l'ordre du classement, c'est lui qui fait foi pour la lecture
 * linéaire, l'impression et le rendu sans CSS. */
.feed-step--1 {
  order: 2;
  --medaille: var(--medaille-or);
}

.feed-step--2 {
  order: 1;
  --medaille: var(--medaille-argent);
}

.feed-step--3 {
  order: 3;
  --medaille: var(--medaille-bronze);
}

.feed-step-card {
  flex: 1;
  padding: 0.75rem;
  text-align: center;
  background: var(--q2-bg-elev);
  border-top: 3px solid var(--medaille);
  border-radius: var(--q2-radius) var(--q2-radius) 0 0;
  box-shadow: var(--q2-shadow-card);
}

.feed-step-athlete {
  margin: 0;
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.3;
  color: var(--q2-text-strong);
  /* Les noms complets sont longs et la colonne fait un tiers de la largeur :
   * sans ça, un patronyme composé déborde de sa carte. */
  overflow-wrap: anywhere;
}

.feed-step-perf {
  margin: 0.375rem 0 0;
}

.feed-step-perf .feed-perf {
  font-size: 1.125rem;
  color: var(--q2-text-strong);
}

.feed-step-details {
  margin: 0.375rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.35;
  color: var(--q2-text-muted);
}

/* C'est la hauteur du socle, et elle seule, qui dessine l'escalier : les
 * cartes gardent leur hauteur de contenu et s'alignent par le bas. */
.feed-step-base {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  font-size: 1.375rem;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--q2-text-strong);
  background: color-mix(in srgb, var(--medaille) 30%, var(--q2-bg-muted));
  border-radius: 0 0 var(--q2-radius) var(--q2-radius);
}

.feed-step--1 .feed-step-base {
  height: 4.5rem;
}

.feed-step--2 .feed-step-base {
  height: 3rem;
}

.feed-step--3 .feed-step-base {
  height: 2rem;
}

/* Le rang en toutes lettres, pour qui n'a pas accès à la hauteur des marches
 * ni au chiffre décoratif du socle. */
.feed-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Sous cette largeur, une carte ne dispose plus que d'un tiers de l'écran :
 * le nom, la performance et la ligne de détails s'y empilent en colonne de
 * deux ou trois caractères. On abandonne donc l'escalier au profit d'une
 * pile 1-2-3, où le rang passe dans une pastille latérale. */
@media (max-width: 48rem) {
  .feed-podium {
    flex-direction: column;
    align-items: stretch;
    gap: 0.5rem;
  }

  .feed-step {
    order: 0;
    flex-direction: row;
    max-width: none;
  }

  /* Le socle est après la carte dans le DOM (il est sous elle sur l'escalier) :
     couché en ligne, il faut le ramener à gauche pour qu'il se lise comme une
     pastille de rang et non comme une pièce rapportée en fin de carte. */
  .feed-step .feed-step-base {
    order: -1;
    width: 2.75rem;
    height: auto;
    flex: none;
    font-size: 1.125rem;
    border-radius: var(--q2-radius) 0 0 var(--q2-radius);
  }

  .feed-step-card {
    text-align: left;
    border-top: 0;
    border-radius: 0 var(--q2-radius) var(--q2-radius) 0;
  }
}

/* Affiche en vignette dans un tableau (ouvertures). */
.feed-thumb {
  width: 3rem;
  height: 3rem;
  object-fit: cover;
  border-radius: var(--q2-radius-xs);
  background: var(--q2-bg-muted);
}

@media (max-width: 48rem) {
  .feed-card-affiche {
    width: 3.5rem;
    height: 3.5rem;
  }

  .feed-tabs {
    flex-direction: column;
  }
}

/* ---- Préréglages de distance (pastilles à cocher) ---- */

.feed-presets {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.feed-presets > legend {
  padding: 0;
  margin-bottom: 0.25rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--q2-text-muted);
}

.feed-presets > div {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

/* La case elle-même est masquée visuellement mais reste focusable et lue par
 * les lecteurs d'écran : c'est le libellé qui fait office de bouton bascule. */
.feed-chip {
  margin: 0;
  cursor: pointer;
}

.feed-chip input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.feed-chip span {
  display: inline-block;
  padding: 0.4375rem 0.875rem;
  font-size: 0.9375rem;
  line-height: 1.2;
  color: var(--q2-text-muted);
  background: var(--q2-bg-muted);
  border: 1px solid transparent;
  border-radius: var(--q2-radius-pill);
}

.feed-chip:hover span {
  color: var(--q2-text-strong);
}

.feed-chip input:focus-visible + span {
  outline: 2px solid var(--brand-sky);
  outline-offset: 2px;
}

.feed-chip input:checked + span {
  color: var(--q2-text-strong);
  background: color-mix(in srgb, var(--brand-sky) 18%, transparent);
  border-color: color-mix(in srgb, var(--brand-sky) 45%, transparent);
  font-weight: 600;
}

.feed-filter--check {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  align-self: center;
}

/* Deux badges dans un en-tête d'événement : ils restent groupés à droite et
 * passent à la ligne ensemble sur écran étroit. */
.feed-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  margin-left: auto;
}

.feed-badges .feed-badge--sm {
  margin-left: 0;
}

/* Le nombre d'épreuves est un repère secondaire face à l'effectif engagé :
 * même forme, teinte neutre, pour hiérarchiser sans ajouter de couleur. */
.feed-badge--quiet {
  color: var(--q2-text-muted);
  background: var(--q2-bg-muted);
  border-color: transparent;
}

/* ---- Statut d'inscription (feed courses) : « Complet » / « Bourse aux
   dossards » ---- */

/* Réutilise .feed-badges (déjà utilisé pour les en-têtes d'événement), sans
 * son alignement à droite (`margin-left: auto`, neutralisé par la règle
 * `.feed-badges .feed-badge--sm { margin-left: 0; }` déjà en place plus
 * haut) : dans une cellule de tableau, les badges suivent simplement la
 * jauge de remplissage plutôt que de se pousser vers un bord. */
.feed-table .feed-badges {
  margin-top: 0.25rem;
}

/* Course complète au sens strict (remplissage à 100 %) : même teinte que la
 * jauge pleine (.feed-fill.is-full juste au-dessus), pour que les deux
 * signaux se lisent comme une seule et même idée. */
.feed-badge--full {
  color: var(--q2-text-strong);
  background: color-mix(in srgb, #d1495b 16%, transparent);
  border-color: color-mix(in srgb, #d1495b 38%, transparent);
}

/* Clôture dépassée sans remplissage connu à 100 % : on ne peut plus
 * s'inscrire, mais on n'affirme pas que la course est pleine — teinte
 * neutre plutôt que le rouge de .feed-badge--full, pour ne pas suggérer
 * la même chose. */
.feed-badge--closed {
  color: var(--q2-text-muted);
  background: color-mix(in srgb, var(--q2-text-muted) 12%, transparent);
  border-color: color-mix(in srgb, var(--q2-text-muted) 32%, transparent);
}

/* Bourse aux dossards confirmée : c'est une voie d'inscription qui
 * fonctionne malgré une inscription normale complète, donc une teinte
 * positive plutôt qu'alarmante — le bleu par défaut de .feed-badge convient
 * déjà, ce modificateur ne fait qu'expliciter l'intention à côté de
 * .feed-badge--full. */
.feed-badge--exchange {
  color: var(--q2-text-strong);
  background: color-mix(in srgb, var(--brand-sky) 16%, transparent);
  border-color: color-mix(in srgb, var(--brand-sky) 38%, transparent);
}

.feed-badge--club {
  display: inline-flex;
  margin-top: 0.35rem;
  background: #e8f5eb;
  border-color: #9bc9a6;
  color: #205c2e;
}

/* Bourse aux dossards non vérifiée pour cette source (sporkrono, à ce
 * jour — voir docs/registration_watch_feed_stable_id_and_exchange_plan.md) :
 * ni confirmé oui ni confirmé non. Un ton neutre et un lien plutôt qu'une
 * affirmation — se taire ici se lirait comme un « non » alors que
 * l'information manque simplement. */
.feed-badge--unknown {
  color: var(--q2-text-muted);
  background: transparent;
  border-style: dashed;
}

.feed-badge--unknown a {
  color: inherit;
}

/* ---- Performances à signaler (feed records) ---- */

/* Volontairement en retrait visuel du tableau/podium juste au-dessus : ces
 * lignes ne sont jamais des records (voir
 * docs/records-marqueur-signalements.md, dépôt racine) — taille réduite et
 * teinte atténuée les distinguent d'un coup d'œil, sans les cacher. */
/* La boîte (fond/coin arrondi/ombre) est sur ce conteneur, pas sur le
 * `<ul>` interne : l'intitulé doit être la première ligne DANS l'encart,
 * pas un paragraphe à part au-dessus. */
.feed-signalements {
  margin: 0.5rem 0 0;
  padding: 0.75rem 1rem;
  font-size: 0.8125rem;
  color: var(--q2-text-muted);
  background: var(--q2-bg-elev);
  border-radius: var(--q2-radius-md);
  box-shadow: var(--q2-shadow-card);
}

/* theme.css a une règle globale `p, li { font-size: 1rem; line-height: 1.7;
 * color: var(--q2-text); }` qui cible directement <p>/<li> — une règle qui
 * vise l'élément lui-même l'emporte toujours sur l'héritage depuis
 * `.feed-signalements`, quelle que soit la spécificité du parent. D'où les
 * redéclarations explicites ci-dessous plutôt qu'un simple `font-size` sur
 * le conteneur. */
.feed-signalements-label {
  margin: 0 0 0.25rem;
  font-size: 0.8125rem;
  line-height: inherit;
  font-weight: 600;
  color: var(--q2-text-muted);
}

/* Grille plutôt qu'une simple liste : quand une section a plusieurs
 * signalements, nom/performance/explication s'alignent en colonnes d'une
 * ligne à l'autre — un peu comme un tableau, sans en être un (pas de
 * `<table>` : ce ne sont justement pas des records, l'implicite d'un
 * tableau serait trompeur). `.feed-signalement` passe en `display: contents`
 * pour que ses enfants (et sa flèche générée, voir plus bas) deviennent
 * directement des cellules de cette grille, sans boîte de `<li>`
 * intermédiaire qui casserait l'alignement. */
.feed-signalements-list {
  display: grid;
  grid-template-columns: 1rem minmax(9rem, auto) minmax(6rem, auto) 1fr;
  column-gap: 0.5rem;
  row-gap: 0.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.feed-signalement {
  display: contents;
  font-size: 0.8125rem;
  line-height: inherit;
  color: var(--q2-text-muted);
}

/* Flèche plutôt que la puce par défaut (déjà retirée par `list-style: none`
 * ci-dessus, mais explicite ici pour ne pas dépendre d'une absence) :
 * devient la première colonne de la grille grâce à `display: contents`
 * sur `.feed-signalement`. */
.feed-signalement::before {
  content: "→";
  color: var(--q2-text-muted);
}

/* Le `<strong>` du thème est à 600 (theme.css) — plus lourd que le nom
 * d'athlète d'un vrai record (.feed-table tbody th, 500). Ramené à 400 ici
 * spécifiquement : une performance à signaler ne doit jamais rivaliser
 * visuellement avec un record réel. */
.feed-signalement strong {
  font-weight: 400;
}

.feed-signalement-note::before {
  content: "— ";
}

/* Sous cette largeur, les colonnes n'ont plus la place de s'aligner
 * proprement : chaque signalement redevient une ligne de texte au fil de
 * l'eau, comme le tableau des records lui-même bascule en cartes (voir
 * plus haut, même seuil). */
@media (max-width: 48rem) {
  .feed-signalements-list {
    display: block;
  }

  .feed-signalement {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
  }

  .feed-signalement + .feed-signalement {
    margin-top: 0.25rem;
  }
}

/* ---- Encarts « nouveaux records » / « records battus » (feed records) ---- */

/* Deux encarts, une seule mécanique : la couleur passe par `--highlight-accent`,
 * que chaque variante redéfinit. Ils sont optionnels dans la donnée
 * (`data.publication`) et n'apparaissent que s'il y a quelque chose à dire —
 * d'où le liseré à gauche plutôt qu'un cadre complet, qui donnerait à un bloc
 * parfois absent le même poids visuel que les tableaux, eux toujours là. */
.feed-highlight {
  --highlight-accent: var(--brand-sky);

  margin: 0 0 1rem;
  padding: 1rem 1.25rem;
  border-left: 3px solid var(--highlight-accent);
  border-radius: var(--q2-radius-sm);
  background: color-mix(in srgb, var(--highlight-accent) 8%, transparent);
}

/* Un record du club qui tombe est l'information la plus forte de la page : il
 * prend le rouge, le reste garde le bleu. Teintes reprises telles quelles des
 * alertes « caution » du thème (theme.css) plutôt qu'un rouge inventé ici — la
 * paire clair/sombre y est déjà éprouvée. Le lavis reste à 8 % : « pastel »
 * signifie que l'encart se remarque sans crier, le liseré suffisant à le
 * distinguer de son voisin bleu. */
.feed-highlight--new {
  --highlight-accent: #cf222e;
}

:root[data-theme="dark"] .feed-highlight--new {
  --highlight-accent: #e5534b;
}

/* Deux encarts qui se suivent : le second se recolle au premier, l'ensemble
 * gardant sa respiration avant les filtres. */
.feed-highlight + .feed-highlight {
  margin-top: -0.25rem;
}

.feed-highlight > h3 {
  margin: 0 0 0.75rem;
  font-size: 1.0625rem;
  color: var(--q2-text-strong);
}

.feed-highlight-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.feed-highlight-item + .feed-highlight-item {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid color-mix(in srgb, var(--highlight-accent) 22%, transparent);
}

/* Marges posées ligne par ligne plutôt qu'un `margin: 0` global suivi de
 * réouvertures. */
.feed-highlight-item > p {
  margin: 0 0 0.125rem;
}

.feed-highlight-item > p:last-child {
  margin-bottom: 0;
}

/* N'apparaît que pour un `type` inattendu — le titre de l'encart porte déjà la
 * nature des entrées ordinaires. */
.feed-highlight-kind {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--q2-text-muted);
}

.feed-highlight-who,
.feed-highlight-diff {
  font-size: 1rem;
  line-height: 1.5;
  color: var(--q2-text-strong);
}

/* La performance remplacée reste lisible mais visiblement révolue. Pas de
 * `line-through` : barrée, elle devient pénible à lire, alors que c'est
 * justement ce qu'on veut comparer. */
.feed-highlight-before {
  color: var(--q2-text-muted);
  font-weight: 400;
}

.feed-highlight-where {
  margin-top: 0.25rem;
  font-size: 0.875rem;
}

.feed-highlight-ctx,
.feed-highlight-details,
.feed-highlight-since {
  color: var(--q2-text-muted);
  font-size: 0.8125rem;
}

.feed-highlight-ctx::before {
  content: " · ";
}

.feed-highlight-since {
  margin: 0 0 1rem;
  font-style: italic;
}

/* La section visée par un lien d'encart reçoit le focus au clavier (voir
 * feeds.js) : sans ce repère, le déplacement est invisible pour qui navigue
 * sans souris. */
.feed-section:focus-visible {
  outline: 2px solid var(--brand-sky);
  outline-offset: 4px;
}

/* Une ligne visée directement (résultat de recherche du site — un id
 * `rec-gN-sM-rK` par record, voir feed-records.html.twig — pointant sur
 * cette ligne précise plutôt que juste le bon onglet) reçoit le même focus
 * programmatique que .feed-section ci-dessus via revealAndFocus() (feeds.js,
 * mécanisme générique et déjà partagé). Sans repère visuel, arriver au bon
 * endroit d'un tableau de plusieurs dizaines de lignes ne se voit pas —
 * `data-row` marque une ligne de record sur les quatre feeds (courses,
 * ouvertures, engagements, records), donc cette règle profite aux quatre
 * si le même mécanisme de lien direct y est ajouté un jour. */
[data-row]:focus-visible {
  outline: 2px solid var(--brand-sky);
  outline-offset: 2px;
  background: var(--q2-bg-muted, rgba(0, 0, 0, 0.05));
}
