{
    % load static %
  }

  a {
    color: #21211f;
    transition: 0.3s;
    -webkit-transition: 0.3s;
    -moz-transition: 0.3s;
    -o-transition: 0.3s;
    -ms-transition: 0.3s;
    text-decoration: none;
  }

  a:hover,
  a:focus {
    color: #20aec8;
  }

  .tooltip {
    z-index: 2 !important;
  }

  /* Bulle « qui a réagi » : on reprend l'aspect du panneau de choix des
     réactions des commentaires (``.reactions-panel`` du paquet : carte blanche,
     coins arrondis, ombre) au lieu du bloc gris sombre d'origine, qui laissait
     une colonne très haute et étroite.
     ``width: max-content`` est le point clé : le paquet fixe ``width: 180px``
     et une position centrée (``left: 50%; margin-left: -90px``). Or la boîte
     est en position absolue dans ``.reaction``, qui ne fait qu'une dizaine de
     pixels de large : en ``width: auto`` le texte s'empilait donc sur une seule
     colonne. On prend la largeur du contenu, plafonnée, et on ancre la bulle au
     **bord gauche** de l'icône (elle s'étale vers la droite, là où il y a de la
     place) : centrée, elle dépassait à gauche dès que l'icône était près du
     bord (``body`` a ``overflow-x: clip``). Seules les bulles des messages de
     l'utilisateur connecté, rangées à droite, sont ancrées à droite.
     Le sélecteur porte ``body`` (et non ``.reaction`` seul) : ``reactions.css``
     du paquet est chargée *après* ``styles.css`` et écrase à spécificité égale
     ses propres règles. */
  body .reaction .tooltip,
  body .flag .tooltip,
  body .vote .tooltip {
    width: max-content;
    min-width: 150px;
    max-width: 260px;
    background-color: #fff;
    color: #21211f;
    border: 1px solid rgba(0, 0, 0, .2);
    border-radius: .3rem;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .2), 0 3px 10px 0 rgba(0, 0, 0, .19);
    padding: 8px 10px;
    line-height: 1.4;
    text-align: left;
    /* La bulle vit dans ``.reaction``, qui porte ``font-size: 10px`` (compteur)
       et la classe ``small`` : sans taille explicite le texte serait minuscule,
       ce qui participait à l'aspect « colonne » illisible. */
    font-size: .825rem;
    white-space: normal;
    left: 0;
    right: auto;
    margin-left: 0;
    transform: none;
  }

  /* La flèche pointe l'icône, restée au bord gauche de la bulle. */
  body .reaction .tooltip::after,
  body .flag .tooltip::after,
  body .vote .tooltip::after {
    left: 8px;
    margin-left: 0;
    border-top-color: #fff;
  }

  /* Messages de l'utilisateur connecté (rangés à droite) : la bulle s'étale
     vers la gauche pour ne pas sortir de l'écran. */
  body .conversation-bubble-own .reaction .tooltip {
    left: auto;
    right: 0;
  }

  body .conversation-bubble-own .reaction .tooltip::after {
    left: auto;
    right: 8px;
  }

  @media (max-width: 767.98px) {
    body .reaction .tooltip,
    body .flag .tooltip,
    body .vote .tooltip {
      max-width: min(260px, calc(100vw - 32px));
    }
  }

  .navbar-nav .nav-link {
    padding-top: 0;
    padding-bottom: 0;
    height: 42px;
    line-height: 42px;
  }

  body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 16px;
    font-weight: 400;
    overflow-x: clip;
    color: #1e293b;
    background-color: var(--sc-bg, #f4f6fb);
  }

  /* ``overflow-x`` doit être ``clip`` (et non ``hidden``) sur ``html`` **et**
     ``body``. Avec ``hidden`` le navigateur crée un conteneur de défilement : la
     barre de navigation ``sticky`` ne colle plus (elle défile avec la page) et
     le débordement horizontal des bulles « qui a réagi » — larges de 260 px même
     masquées — élargit le viewport de mise en page. Résultat sur mobile : la
     navbar et la barre d'onglets fixe sortaient de l'écran. ``clip`` coupe le
     débordement sans créer de défilement ni casser le ``sticky``. */
  html {
    overflow-x: clip;
  }

  /* ===== Design system =====
     Jetons réutilisés par les cartes et les en-têtes de section. La couleur
     primaire (``--app-color``) reste définie par le site dans ``base_generic`` ;
     on ne fait ici que fixer des neutres doux (gris ardoise plutôt que noir pur)
     et des rayons / ombres communs, pour que toutes les pages se ressemblent. */
  :root {
    --sc-ink: #1e293b;
    --sc-muted: #64748b;
    --sc-bg: #f4f6fb;
    --sc-line: #eef2f6;
    --sc-line-strong: #dbe2ea;
    --sc-radius: 1rem;
    --sc-radius-sm: .75rem;
    --sc-gap: 1rem;
    --sc-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 4px 16px rgba(15, 23, 42, .06);
    --sc-shadow-hover: 0 4px 12px rgba(15, 23, 42, .08), 0 12px 32px rgba(15, 23, 42, .10);
  }

  /* Cartes : plus de bordure grise, des angles arrondis et une ombre douce au
     lieu du rendu plat « template Bootstrap ». On passe par les variables de
     Bootstrap 5.3 plutôt que par ``border: 0`` : la bordure reste déclarée (1 px
     transparent) donc les cartes qui portent ``border-primary`` (badges
     débloqués) gardent leur liseré coloré. L'élévation au survol n'est ajoutée
     qu'aux cartes explicitement cliquables (``.card-hover``) pour ne pas faire
     sautiller les grilles. */
  .card {
    --bs-card-border-color: transparent;
    --bs-card-border-radius: var(--sc-radius);
    box-shadow: var(--sc-shadow);
  }

  .card-hover {
    transition: transform .2s ease, box-shadow .2s ease;
  }

  .card-hover:hover {
    transform: translateY(-3px);
    box-shadow: var(--sc-shadow-hover);
  }

  /* En-tête d'une page : listes (courses, sorties, actus, changelog...), mais
     aussi formulaires de création / modification et confirmations de
     suppression. Une seule apparence pour toutes les pages, qu'elles utilisent
     un ``<h1>`` ou un ``<h2>`` : les gabarits gardent leur niveau de titre, la
     classe uniformise le rendu (capitales + trait souligné à la couleur du
     site, comme les intitulés de colonnes de l'index). */
  .page-heading {
    text-align: center;
    margin: 1.25rem 0 1rem;
    font-family: 'Poppins', sans-serif;
    font-weight: 600;
    font-size: 1.15rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    line-height: 1.3;
    color: var(--sc-ink);
  }

  .page-heading::after {
    content: "";
    display: block;
    width: 56px;
    height: 3px;
    margin: .55rem auto 0;
    border-radius: 3px;
    background-color: var(--app-color);
  }

  .page-heading a {
    color: inherit;
  }

  .page-heading a:hover,
  .page-heading a:focus {
    color: var(--app-color);
  }

  .page-heading .material-icons {
    color: var(--sc-muted);
    transition: color .2s ease;
  }

  .page-heading .material-icons:hover {
    color: var(--app-color);
  }

  /* Titre d'une colonne de l'index (« Actus », « Sorties et Événements »,
     « Courses et Résultats »). On remplace la carte à en-tête centré par un
     simple intitulé en capitales, souligné d'un trait à la couleur du site. */
  .section-heading {
    text-align: center;
    margin: 0 0 1rem;
    font-family: 'Poppins', sans-serif;
    font-weight: 600;
    font-size: .95rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--sc-ink);
  }

  .section-heading::after {
    content: "";
    display: block;
    width: 44px;
    height: 3px;
    margin: .55rem auto 0;
    border-radius: 3px;
    background-color: var(--app-color);
  }

  .section-heading a {
    color: inherit;
  }

  .section-heading a:hover,
  .section-heading a:focus {
    color: var(--app-color);
  }

  /* Boutons et champs : mêmes angles arrondis que les cartes, et focus à la
     couleur du site, pour que l'ensemble paraisse dessiné par la même main. */
  .btn {
    border-radius: var(--sc-radius-sm);
  }

  .form-control,
  .form-select {
    border-radius: var(--sc-radius-sm);
    border-color: var(--sc-line);
  }

  .form-control:focus,
  .form-select:focus {
    border-color: var(--app-color);
    box-shadow: 0 0 0 .2rem rgba(var(--bs-primary-rgb), .15);
  }

  /* Rythme vertical des cartes. L'index, les pages de liste et les profils
     partagent le même écart (``--sc-gap``, 1rem = 16 px, celui des pages de
     liste) au lieu des marges en dur qui rendaient l'ensemble serré et inégal
     (4 px sur l'index, 8 px ailleurs). ``.index-card + .index-card`` annule la
     marge haute des cartes suivantes : l'écart entre deux cartes reste un seul
     ``--sc-gap``, la première carte garde le sien. */
  .index-card {
    margin: var(--sc-gap) 0;
  }

  .index-card + .index-card {
    margin-top: 0;
  }

  /* Sur mobile les cartes de l'index touchaient le bord gauche : la gouttière
     du conteneur n'est pas symétrique (12 px à gauche, 5 px à droite). On pose
     donc une petite marge explicite pour que les deux bords respirent, avec des
     valeurs qui donnent 12 px de chaque côté (les colonnes de contenu et le
     programme de la semaine n'ont pas le même conteneur). */
  @media (max-width: 767.98px) {
    .tn-cols-to-tabs.main-cols .index-card {
      margin-left: 12px;
      margin-right: 7px;
    }

    .tn-cols-to-tabs:not(.main-cols) .index-card {
      margin-left: 8px;
      margin-right: 3px;
    }
  }

  /* Programme de la semaine : les événements d'une même journée se suivent dans
     une seule carte, séparés par un filet **pleine largeur**. L'ancien ``<hr>``
     vivait dans le rembourrage du ``card-body`` : il s'arrêtait avant les bords
     de la carte et collait en haut (``margin-top:0``), d'où l'écart asymétrique.
     Chaque bloc porte désormais un rembourrage symétrique. */
  .week-events {
    padding: 0;
  }

  .week-event {
    padding: .9rem 1rem;
  }

  .week-event + .week-event {
    border-top: 2px solid var(--sc-line-strong);
  }

  /* La dernière sortie d'une journée : sa barre de réactions doit laisser la
     même marge basse que les autres cartes de l'index (le ``.card-actions`` en
     bas du ``.card-body``, soit 15 px), et non celle du bloc ``.week-event``
     qui ajoutait un rembourrage de trop. */
  .week-events > .week-event:last-child {
    padding-bottom: 0;
  }

  /* Barre de réactions d'un événement de la semaine : comme sur les cartes
     d'actus, de sorties et de courses, le filet qui la sépare du contenu court
     sur **toute** la largeur de la carte (les marges négatives annulent le
     rembourrage horizontal du bloc) au lieu de s'arrêter avant les bords. */
  .week-event-actions {
    margin: .6rem -1rem -.9rem;
  }

  .week-events > .week-event:last-child .week-event-actions {
    margin-bottom: 0;
  }

  /* Champ message (CKEditor 5). Le paquet impose des angles quasi carrés (2 px),
     une bordure grise et aucun rembourrage vertical : le champ jurait avec les
     cartes arrondies du reste du site. On reprend les jetons de design (rayon,
     filet, focus à la couleur du site). Le sélecteur porte ``body`` pour dépasser
     la feuille de ``ckeditor.js``, injectée après ``styles.css``. */
  body .ck.ck-editor {
    width: 100%;
  }

  body .ck.ck-editor__main > .ck-editor__editable,
  body .ck.ck-editor .ck.ck-editor__editable.ck-content {
    border: 1px solid var(--sc-line);
    border-radius: var(--sc-radius-sm);
    padding: .55rem .75rem;
    min-height: 44px;
    background-color: #fff;
    box-shadow: none;
  }

  body .ck.ck-editor__main > .ck-editor__editable.ck-focused {
    border-color: var(--app-color);
    box-shadow: 0 0 0 .2rem rgba(var(--bs-primary-rgb), .15);
  }

  body .ck.ck-editor__editable .ck-placeholder::before {
    color: var(--sc-muted);
  }

  /* Barre d'outils de l'éditeur. Le paquet lui donne ses propres bords gris
     (rayon 2 px) qui ne suivent pas le champ arrondi juste en dessous : les
     deux blocs paraissaient collés et de styles différents. On habille la barre
     avec les mêmes jetons que le champ (rayon, filet, fond clair) et on fusionne
     les deux en un seul cadre : la barre perd sa bordure basse et le champ sa
     bordure haute, arrondi uniquement en bas.
     ``!important`` est nécessaire : les règles de ``ckeditor.js`` ciblent la
     barre avec cinq classes (``.ck-rounded-corners .ck.ck-editor__top
     .ck-sticky-panel .ck-toolbar``), donc elles l'emportent sur un sélecteur à
     spécificité inférieure, et la barre gardait son rayon de 2 px.
     La fusion ne vaut que pour les éditeurs à barre d'outils (``full-editor`` /
     ``full-editor-with-html``) : le champ des commentaires (``comment-editor``)
     n'a pas de barre visible et doit donc garder ses quatre bords arrondis. */
  body .ck.ck-editor__top .ck-sticky-panel .ck-toolbar {
    background-color: var(--sc-bg);
    border: 1px solid var(--sc-line) !important;
    border-bottom: 0 !important;
    border-radius: var(--sc-radius-sm) var(--sc-radius-sm) 0 0 !important;
    padding: .25rem .4rem;
  }

  body .ck.ck-editor__top .ck-sticky-panel .ck-toolbar .ck-toolbar__separator {
    background-color: var(--sc-line-strong);
  }

  body .ck.ck-editor__main > .ck-editor__editable.full-editor,
  body .ck.ck-editor__main > .ck-editor__editable.full-editor-with-html {
    border-top: 0 !important;
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
  }

  body .ck.ck-editor__main > .ck-editor__editable.full-editor.ck-focused,
  body .ck.ck-editor__main > .ck-editor__editable.full-editor-with-html.ck-focused {
    border-top: 0 !important;
    border-radius: 0 0 var(--sc-radius-sm) var(--sc-radius-sm) !important;
  }

  /* Bouton d'envoi du champ message : une pastille ronde de la couleur du site,
     avec un léger relief au survol, au lieu du rond plat qui jurait avec les
     autres boutons. Le rembourrage est symétrique et l'icône centrée (elle était
     décalée par des marges en ligne). */
  #sendComment {
    width: 42px;
    height: 42px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--sc-shadow);
    transition: transform .15s ease, box-shadow .15s ease;
  }

  #sendComment:hover {
    transform: translateY(-1px);
    box-shadow: var(--sc-shadow-hover);
  }

  #sendComment .material-symbols-outlined {
    font-size: 20px;
    margin: 0;
  }

  /* En-tête du jour dans le programme de la semaine : bandeau clair, texte
     ardoise et liseré à la couleur du site, à la place de l'en-tête gris
     standard. */
  .day-heading {
    text-align: center;
    padding: .6rem 1rem;
    font-family: 'Poppins', sans-serif;
    font-weight: 600;
    font-size: .85rem;
    letter-spacing: .04em;
    color: var(--sc-ink);
    background-color: #f8fafc;
    border-bottom: 2px solid var(--app-color);
    border-radius: var(--sc-radius) var(--sc-radius) 0 0;
  }

  /* Barre de navigation collante : léger effet de verre dépoli et un seul filet
     de séparation en bas, au lieu des deux bordures et du blanc opaque. */
  .navbar.sticky-top {
    background-color: rgba(255, 255, 255, .85) !important;
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-top: 0 !important;
    border-bottom-color: var(--sc-line) !important;
  }

  /* Pied de carte des sorties / actus / courses : plus de bandeau gris. On ne
     garde qu'un fin filet de séparation, et la barre de réactions + le compteur
     de commentaires s'y alignent proprement. */
  .card-actions {
    display: flex;
    align-items: center;
    gap: .25rem;
    padding: .5rem .9rem;
    background-color: transparent;
    border-top: 1px solid var(--sc-line);
  }

  /* Barre de réactions : les icônes sont des boutons nus, sans fond ni bordure.
     La couleur de l'icône vient d'un ``text-shadow`` posé en ligne (couleur du
     site quand l'utilisateur a réagi, gris sinon) ; la classe ne fait que
     neutraliser l'apparence par défaut du bouton. */
  .reaction-btn {
    position: relative;
    padding: .1rem .35rem;
    border: 0;
    border-radius: 999px;
    background-color: transparent;
    font-size: 16px;
    color: transparent;
    cursor: pointer;
    transition: background-color .15s ease;
  }

  .reaction-btn:hover {
    background-color: rgba(15, 23, 42, .06);
  }

  /* Contenu de la barre : les réactions à gauche, le compteur de commentaires
     poussé à droite (``margin-left: auto`` sur ``.comment-chip``). */
  .sc-reaction-bar {
    display: flex;
    align-items: center;
    width: 100%;
  }

  /* Le compteur de commentaires devient une petite pastille cliquable. */
  .comment-chip {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    margin-left: auto;
    padding: .15rem .6rem;
    font-size: .72rem;
    color: var(--sc-muted);
    background-color: #f1f5f9;
    border-radius: 999px;
    transition: background-color .2s ease, color .2s ease;
  }

  a.comment-chip:hover,
  a.comment-chip:focus {
    color: var(--sc-ink);
    background-color: #e2e8f0;
  }

  .comment-chip .material-icons {
    font-size: 14px;
  }

  .site-logo {
    margin-bottom: 20px;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    height: 80px;
    width: auto;
  }

  .site-title {
    text-align: center;
    letter-spacing: 3px;
    margin: 0;
    text-transform: uppercase;
    font-family: 'Khand', sans-serif;
    letter-spacing: calc(rfs-value(1px) + 1vw);
    line-height: calc(rfs-value(1px) + 1vw);
    font-size: calc(rfs-value(1px) + 1vw);
    font-weight: bold;
  }

  .site-title a {
    color: #21211f;
  }

  .site-description {
    text-align: center;
    margin: 0;
    font-size: calc(2vw);
    text-transform: uppercase;
    color: #21211f;
    letter-spacing: calc(1vw);
  }

  @media (min-width: 500px) {
    .site-title {
      font-size: 36px;
      letter-spacing: 10px;
      line-height: 38px;
    }

    .site-description {
      font-size: 15px;
      letter-spacing: 7px;
    }
  }

  .site-branding {
    margin: 0 auto;
    background-image: url("../header_background-800x400.5aa6064fcdd4.jpg");
    background-repeat: no-repeat;
    background-position: right;
    background-size: contain;
    width: auto;
  }

  .navbar-hr {
    margin: 0;
  }

  .navbar ul li a {
    text-transform: uppercase;
    color: #21211f;
    font-family: 'Poppins', sans-serif;
    font-size: 16px;
  }

  /* Le lien de recherche n'est pas toujours dans un ``ul li`` (menu replié sur
     petit écran) : on lui applique la même typographie en capitales que les
     autres entrées de la navbar, quel que soit son conteneur. */
  .search-nav-link {
    text-transform: uppercase;
    color: #21211f;
    font-family: 'Poppins', sans-serif;
    font-size: 16px;
  }

  .text-site-uppercase {
    text-transform: uppercase;
    color: #21211f;
    font-family: 'Poppins', sans-serif;
    font-size: 16px;
  }

  .nav ul li a {
    text-transform: uppercase;
    color: #21211f;
    font-family: 'Poppins', sans-serif;
    font-size: 16px;
  }

  .back-btn {
    text-transform: uppercase;
    color: #21211f;
    font-family: 'Poppins', sans-serif;
    font-size: 16px;
  }

  .back-btn:focus,
  .back-btn:active {
    outline: none !important;
    box-shadow: none;
    color: #21211f;
  }

  .navbar-notif {
    color: #21211f;
    font-family: 'Poppins', sans-serif;
    font-size: 8px;
  }

  h1 {
    font-size: 20px;
    color: #21211f;
    margin: 20px 20px 20px 20px;
  }

  .runner-list {
    margin: 0;
  }

  .material-icons.md-12 {
    font-size: 12px;
    vertical-align: middle
  }

  .material-symbols-outlined.md-12 {
    font-size: 12px;
    vertical-align: middle
  }

  .material-icons.md-18 {
    font-size: 18px;
    vertical-align: middle
  }

  .material-symbols-outlined.md-18 {
    font-size: 18px;
    vertical-align: middle
  }

  .material-icons.md-30 {
    font-size: 30px;
    vertical-align: middle
  }

  .material-icons.md-60 {
    font-size: 30px;
    vertical-align: middle
  }

  .material-icons.md-120 {
    font-size: 120px;
    vertical-align: middle
  }

  .material-icons.md-300 {
    font-size: 300px;
    vertical-align: middle
  }

  .material-icons-outlined.md-18 {
    font-size: 18px;
    vertical-align: middle
  }

  /* Icon-only dropdown toggles (registration "+", status arrow) are plain
     spans, so Bootstrap never gives them the pointer cursor. */
  span.material-icons[data-bs-toggle="dropdown"] {
    cursor: pointer;
  }

  /* Dropdown entries built as anchors without href (htmx actions) otherwise
     show a text-selection cursor. */
  .dropdown-item:not(.disabled) {
    cursor: pointer;
  }

  /* Pastille d'inscription d'une sortie ou d'un format de course : l'icône « + »
     (ou la flèche de statut) était posée nue à côté des photos des inscrits, sans
     repère visuel, et sa taille (30 px) la rendait plus grosse que les photos.
     On en fait une pastille ronde de la taille d'une photo d'inscrit, pour que
     « s'inscrire / changer mon inscription » se repère d'un coup d'œil. Elle est
     en **gris clair** (comme la pastille de commentaires), avec l'icône en gris
     plus foncé : ce n'est pas une action primaire, elle ne doit donc pas
     arborer la couleur du site. Le bouton « + » de la navbar reprend la même
     pastille (``.nav-add-trigger``). */
  span.material-icons.registration-trigger,
  .nav-add-trigger > span.material-icons {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    margin-bottom: 5px;
    border-radius: 50%;
    font-size: 20px;
    color: #475569;
    background-color: #f1f5f9;
    vertical-align: middle;
    box-shadow: 0 1px 2px rgba(15, 23, 42, .15);
    transition: background-color .15s ease;
  }

  span.material-icons.registration-trigger:hover,
  .nav-add-trigger:hover > span.material-icons {
    background-color: #e2e8f0;
  }

  .filter_form {
    display: flex;
    align-items: center;
    /* Vertical alignment */
  }

  .card-challenge {
    display: flex;
    flex: 1 1 auto;
  }

  .img-runner {
    width: 30px;
    height: 30px;
    object-fit: cover;
    border-radius: 50%;
  }

  .carousel-control-prev {
    margin: auto auto;
    height: 50px;
    width: 50px;
  }

  .carousel-control-next {
    margin: auto auto;
    height: 50px;
    width: 50px;
  }

  .tabs-footer {
    position: fixed;
    left: 0;
    bottom: 0;
    width: 100%;
    background-color: white;
    color: #21211f;
    text-align: center;
  }


  .nav-pills .nav-link.active,
  .nav-pills .show>.nav-link {
    color: #21211f;
    background-color: var(--app-color);
  }

  .tabs-footer ul li button {
    text-transform: uppercase;
    color: #21211f;
    font-family: 'Poppins', sans-serif;
    font-size: 16px;
  }

  .tabs-trainings ul li button {
    text-transform: uppercase;
    color: #21211f;
    font-family: 'Poppins', sans-serif;
    font-size: 16px;
  }

  .tabs-activities ul li button {
    text-transform: uppercase;
    color: #21211f;
    font-family: 'Poppins', sans-serif;
    font-size: 16px;
  }

  .tabs-races ul li button {
    text-transform: uppercase;
    color: #21211f;
    font-family: 'Poppins', sans-serif;
    font-size: 16px;
  }

  .pills-heading {
    display: none;
  }

  .my-footer {
    display: none;
  }

  #tab-pane-activities {
    margin-top: -25px
  }

  #tab-pane-races {
    margin-top: -35px
  }

  #tab-pane-weeks {
    margin-top: -10px
  }

  @media only screen and (min-width: 768px) {

    .index-col {
      max-width: 25% !important;
    }

    .next-past-header {
      margin-top: 0px !important;
    }

    .tn-cols-to-tabs>.tab-pane {
      display: block;
    }

    .pills-heading {
      display: block;
    }

    .my-footer {
      display: block;
    }

    .footer-margin {
      margin-bottom: 0px !important;
    }

    .main-cols {
      width: 0;
    }

    #tab-pane-activities {
      margin-top: 0px
    }

    #tab-pane-races {
      margin-top: 0px
    }

    #tab-pane-weeks {
      margin-top: 0px
    }
  }

  .dropdown-menu-center {
    left: 50% !important;
    right: auto !important;
    transform: translate(-50%, 0) !important;
  }

  @media only screen and (min-width: 768px) {
    .dropdown-menu-center {
      left: auto !important;
      right: auto !important;
    }
  }

  .myspinner {
    margin-top: 20px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }

  /* ============ desktop view ============ */
  @media all and (min-width: 992px) {
    .dropdown-menu li {
      position: relative;
    }

    .nav-item .submenu {
      display: none;
      position: absolute;
      left: 100%;
      top: -7px;
    }

    .nav-item .submenu-left {
      right: 100%;
      left: auto;
    }

    .dropdown-menu>li:hover {
      background-color: #f1f1f1
    }

    .dropdown-menu>li:hover>.submenu {
      display: block;
    }
  }

  /* ============ desktop view .end// ============ */

  /* ============ small devices ============ */
  @media (max-width: 991px) {
    .dropdown-menu .dropdown-menu {
      margin-left: 0.7rem;
      margin-right: 0.7rem;
      margin-bottom: .5rem;
    }
  }

  /* ============ small devices .end// ============ */


  .select2-selection {
    height: 58px !important;
    padding: 26px 36px 6px 12px !important;
  }

  .select2-selection__arrow {
    visibility: hidden;
  }

  .select2-container {
    width: 100% !important;
  }


  @media (max-width: 500px) {
    .strava-segment-chart {
      height: 200px !important;
    }
  }

  @media (min-width: 501px) and (max-width: 768px) {
    .strava-segment-chart {
      height: 240px !important;
    }
  }

  @media (min-width: 769px) and (max-width: 991px) {
    .strava-segment-chart {
      height: 330px !important;
    }
  }

  @media (min-width: 992px) {
    .strava-segment-chart {
      height: 380px !important;
    }
  }

  .gsi-material-button {
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    -webkit-appearance: none;
    background-color: WHITE;
    background-image: none;
    border: 1px solid #747775;
    -webkit-border-radius: 20px;
    border-radius: 20px;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    color: #1f1f1f;
    cursor: pointer;
    font-family: 'Roboto', arial, sans-serif;
    font-size: 14px;
    height: 40px;
    letter-spacing: 0.25px;
    outline: none;
    overflow: hidden;
    padding: 0 12px;
    position: relative;
    text-align: center;
    -webkit-transition: background-color .218s, border-color .218s, box-shadow .218s;
    transition: background-color .218s, border-color .218s, box-shadow .218s;
    vertical-align: middle;
    white-space: nowrap;
    width: auto;
    max-width: 400px;
    min-width: min-content;
  }

  .gsi-material-button .gsi-material-button-icon {
    height: 20px;
    margin-right: 12px;
    min-width: 20px;
    width: 20px;
  }

  .gsi-material-button .gsi-material-button-content-wrapper {
    -webkit-align-items: center;
    align-items: center;
    display: flex;
    -webkit-flex-direction: row;
    flex-direction: row;
    -webkit-flex-wrap: nowrap;
    flex-wrap: nowrap;
    height: 100%;
    justify-content: space-between;
    position: relative;
    width: 100%;
  }

  .gsi-material-button .gsi-material-button-contents {
    -webkit-flex-grow: 1;
    flex-grow: 1;
    font-family: 'Roboto', arial, sans-serif;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: top;
  }

  .gsi-material-button .gsi-material-button-state {
    -webkit-transition: opacity .218s;
    transition: opacity .218s;
    bottom: 0;
    left: 0;
    opacity: 0;
    position: absolute;
    right: 0;
    top: 0;
  }

  .gsi-material-button:disabled {
    cursor: default;
    background-color: #ffffff61;
    border-color: #1f1f1f1f;
  }

  .gsi-material-button:disabled .gsi-material-button-contents {
    opacity: 38%;
  }

  .gsi-material-button:disabled .gsi-material-button-icon {
    opacity: 38%;
  }

  .gsi-material-button:not(:disabled):active .gsi-material-button-state,
  .gsi-material-button:not(:disabled):focus .gsi-material-button-state {
    background-color: #303030;
    opacity: 12%;
  }

  .gsi-material-button:not(:disabled):hover {
    -webkit-box-shadow: 0 1px 2px 0 rgba(60, 64, 67, .30), 0 1px 3px 1px rgba(60, 64, 67, .15);
    box-shadow: 0 1px 2px 0 rgba(60, 64, 67, .30), 0 1px 3px 1px rgba(60, 64, 67, .15);
  }

  .gsi-material-button:not(:disabled):hover .gsi-material-button-state {
    background-color: #303030;
    opacity: 8%;
  }


  .separator {
    display: flex;
    align-items: center;
    text-align: center;
  }

  .separator::before,
  .separator::after {
    content: '';
    flex: 1;
    border-bottom: 1px solid #000;
  }

  .separator:not(:empty)::before {
    margin-right: .25em;
  }

  .separator:not(:empty)::after {
    margin-left: .25em;
  }


  /* Résultats de recherche : les onglets reprennent la typo de la navbar
     (gris, capitales) au lieu du bleu des liens Bootstrap, et alignent icône,
     libellé et compteur. On force la couleur sur tous les états pour que les
     onglets inactifs restent gris, comme les entrées de la navbar. */
  .search-tabs .nav-link,
  .search-tabs .nav-link:link,
  .search-tabs .nav-link:visited,
  .search-tabs .nav-link:hover,
  .search-tabs .nav-link:focus {
    color: #21211f;
    text-transform: uppercase;
    font-family: 'Poppins', sans-serif;
    font-size: 14px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
  }

  .search-tabs .nav-link .material-icons {
    color: #6c757d;
  }

  /* Onglets de recherche sur une seule ligne : le bandeau défile
     horizontalement quand il déborde, au lieu de passer à la ligne. Les
     onglets ne se compriment pas (``flex-shrink: 0``) pour rester lisibles.
     La largeur suit celle du conteneur (``.search-container``), pour que la
     barre d'onglets et les blocs de résultats restent alignés sur les bords. */
  .search-tabs-scroll {
    overflow-x: auto;
    overflow-y: hidden;
  }

  .search-tabs-scroll .nav-tabs {
    flex-wrap: nowrap;
  }

  .search-tabs-scroll .nav-item {
    flex-shrink: 0;
  }

  /* Conteneur des résultats de recherche (formulaire, onglets et cartes) : une
     largeur unique et centrée, plus large que les 800px d'origine pour que
     tous les onglets tiennent sans défilement sur un grand écran. La barre
     d'onglets et les cartes partagent ce conteneur, donc leurs bords gauche et
     droit sont alignés (avant, ``.search-tabs-scroll`` était centré à 800px
     tandis que ``.tab-content`` restait en ``container-fluid``). */
  .search-container {
    max-width: 1100px;
    margin: 0 auto;
    padding-left: 12px;
    padding-right: 12px;
  }

  /* ``min-width: 0`` sur un enfant flex : sans lui, un enfant ``flex-grow-1``
     garde une largeur minimale (``min-width: auto``) et son contenu long
     déborde du parent au lieu d'être tronqué ou renvoyé à la ligne. La classe
     est utilisée par les cartes de résultats de recherche et l'en-tête des
     fils de conversation. */
  .min-width-0 {
    min-width: 0;
  }

  /* Message complet d'un résultat de conversation : on conserve les retours à
     la ligne et on casse les mots trop longs (l'extrait d'un message peut
     dépasser du cadre blanc sur petit écran sans cela). */
  .search-result-message {
    white-space: pre-line;
    word-break: break-word;
    overflow-wrap: anywhere;
  }

  /* Extrait d'un résultat « actus » : il remplit la largeur de la carte au lieu
     de tenir sur une seule ligne (``text-truncate`` laissait, sur grand écran,
     un texte bien plus court que le cadre blanc). On garde les retours à la
     ligne de l'auteur et on plafonne à deux lignes pour des cartes régulières. */
  .search-result-excerpt {
    white-space: pre-line;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* Liste des conversations : l'extrait vient de ``slice_text``, qui peut
     laisser un <p> autour du texte. La marge par defaut de <p> ajoutait une
     ligne vide dans la ligne tronquee (la conv' prenait 3 lignes au lieu de 2).
     On l'affiche en ligne, sans marge, donc sur une seule ligne. */
  .conversation-snippet p {
    display: inline;
    margin: 0;
  }

  /* Bulle d'un message (tous les fils : conv' générale, fil privé, commentaires
     de course / sortie / actualité) : elle s'adapte au contenu
     (``fit-content``) pour minimiser l'espace vide des messages courts, tout en
     restant plafonnée par la place restante (``max-width: 100%``) pour ne
     jamais déborder. */
  .conversation-bubble {
    width: fit-content;
    max-width: 100%;
    min-width: 0;
  }

  /* Bulle de l'utilisateur connecté : elle reste rangée à droite, mais sa marge
     gauche la cale sur le bord gauche des bulles des autres (icône 24 px +
     ``me-2`` 8 px). Un message long ne dépasse donc jamais sous l'icône de
     l'auteur, quel que soit le fil. */
  .conversation-bubble-own {
    margin-left: 32px;
  }

  /* Fil privé : le nom de l'auteur et les photos des deux participants sont
     masqués. Sans icône de 24 px à gauche des bulles des autres, la marge de la
     bulle de l'utilisateur retombe à zéro pour que les bords gauche et droit des
     deux bulles soient alignés (même rendu que la conv' générale, sans nom ni
     photo). */
  .conv-private .conversation-bubble-own {
    margin-left: 0;
  }

  /* Champ message : le même rembourrage partout (panneau de conversation, page
     du fil, commentaires de course / sortie / actu). Il était asymétrique selon
     la page (5 px en haut sans marge basse dans le panneau, 10 px partout
     ailleurs, avec un fond gris), d'où un rendu inégal d'une page à l'autre. */
  .comment-form-pad {
    padding: 10px 8px;
  }

  /* Fils de commentaires des courses, sorties et actus. Le champ de saisie et
     le bouton d'envoi s'alignent sur les **bords de la carte** de contenu : le
     bord gauche du champ CKEditor sur le bord gauche de la carte, le bord droit
     du bouton d'envoi sur le bord droit. Le conteneur n'a donc plus de
     rembourrage horizontal, et les 16 px du ``.card-body`` sont reportés sur la
     boîte des messages : les bulles et les photos de profil restent alignées sur
     le texte de la carte du dessus. La marge haute détache le fil de la carte
     au-dessus (le message du haut était collé à son bord). */
  #commentbox-container.thread-aligned {
    margin-top: 1rem;
    padding: 0;
  }

  #commentbox-container.thread-aligned .commentbox {
    margin: 0;
    padding: 0 16px;
  }

  #commentbox-container.thread-aligned > [data-dci="comment-form"] {
    padding: 10px 0;
  }

  #commentbox-container.thread-aligned .commentbox .animate-comment {
    padding-left: 0;
    padding-right: 0;
  }

  /* Hauteur du fil : dans le popup desktop on garde la hauteur historique
     (``70vh``). Dans l'onglet Conv' mobile (l'index n'est pas la page dediee),
     le fil doit remplir l'espace entre la barre de navigation (sticky, ~60px,
     en haut) et la barre d'onglets fixe (~57px, en bas) : sinon le formulaire
     flotte au milieu de l'ecran au lieu d'etre colle en bas. On reprend la
     meme approche en unites viewport que le reste du site. */
  #conv-panel-thread {
    height: calc(70vh - 90px);
  }

  .app-fullscreen #conv-in-tab #conv-panel-thread {
    height: calc(100vh - 117px);
    height: calc(100dvh - 117px);
  }

  /* Page « conversations » en plein écran (PWA / mobile) : il n'y a pas de barre
     d'onglets en bas, donc le fil descend jusqu'au bord. ``conv-page`` et
     ``app-fullscreen`` sont posées toutes les deux sur ``<body>`` : le
     sélecteur les enchaîne donc sans espace (``.app-fullscreen.conv-page``),
     sinon la règle ne s'applique jamais et le champ message reste au milieu de
     l'écran. */
  .app-fullscreen.conv-page #conv-panel-thread {
    height: calc(100vh - 60px);
    height: calc(100dvh - 60px);
  }

  /* Hauteur calculée sur la navbar (60 px) : si la navbar est plus haute (liens
     passés sur deux lignes) ou si ``dvh`` ne colle pas à la vue réelle au
     premier affichage, le fil dépasse la vue et le pied collant
     (``position: sticky``) recouvre le dernier message. On laisse donc la
     colonne flex remplir l'espace restant, sans offset codé en dur : la navbar
     garde sa hauteur, le fil prend le reste. Le ``:has(.column)`` distingue le
     conteneur de contenu du conteneur (vide) du pied de page, qui porte lui
     aussi ``.container`` mais pas ``.column`` ; ``@supports`` laisse les
     navigateurs sans ``:has()`` sur la règle ``calc()`` ci-dessus. */
  @supports selector(:has(*)) {
    .app-fullscreen.conv-page {
      height: 100vh;
      height: 100dvh;
      display: flex;
      flex-direction: column;
      overflow: hidden;
    }

    .app-fullscreen.conv-page > nav.navbar {
      flex-shrink: 0;
    }

    .app-fullscreen.conv-page > .container:has(.column) {
      flex: 1 1 0;
      min-height: 0;
      display: flex;
      flex-direction: column;
    }

    .app-fullscreen.conv-page > .container:has(.column) > .row {
      flex: 1 1 0;
      min-height: 0;
      display: flex;
      flex-direction: column;
      flex-wrap: nowrap;
    }

    .app-fullscreen.conv-page > .container:has(.column) > .row > .column,
    .app-fullscreen.conv-page .conv-page-container,
    .app-fullscreen.conv-page .conv-page-card,
    .app-fullscreen.conv-page .conv-page-card > .card-body,
    .app-fullscreen.conv-page .conv-panel {
      flex: 1 1 0;
      min-height: 0;
      display: flex;
      flex-direction: column;
    }

    .app-fullscreen.conv-page #conv-panel-thread {
      height: auto;
      flex: 1 1 0;
      min-height: 0;
    }
  }

  /* Vue mobile : le pied du fil porte le champ message. Une petite marge sous
     lui (8 px, l'unité des petits écarts du site) le décolle de la barre
     d'onglets (onglet Conv' de l'index, ``#conv-in-tab``) ou du bord de l'écran
     (fil privé, ``.conv-page``), sans coller au dernier message.

     Le pied porte ``p-0`` (Bootstrap, ``padding: 0 !important``) : sans
     ``!important`` la marge serait ignorée (mesuré : 0 px au navigateur). La
     règle est bornée au mobile, donc le popup desktop (``#conv-float-list``) et
     la carte centrée gardent leur rendu. */
  @media (max-width: 767.98px) {
    #conv-in-tab #commentbox-container .card-footer,
    .conv-page #commentbox-container .card-footer {
      padding-bottom: 8px !important;
    }
  }

  /* Page « conversations » (celle qu'ouvre la notification push d'un message
     reçu) : sur mobile elle reprend l'apparence de l'onglet Conv' de l'index.
     Le conteneur et la carte ne laissent plus de bandes grises sur les côtés ni
     entre la navbar et la liste, et le pied de page est masqué comme sur
     l'index. Sur grand écran la carte centrée d'origine est conservée. */
  @media (max-width: 767.98px) {
    /* Seul le conteneur de contenu est visé (``body > .container``) : le
       conteneur interne de la navbar garde ses marges. Le conteneur et la carte
       de la page sont ensuite mis à plat pour que la liste occupe toute la
       largeur, sans bande grise. */
    .conv-page > .container,
    .conv-page .conv-page-container {
      max-width: 100% !important;
      padding-left: 0 !important;
      padding-right: 0 !important;
    }

    /* ``.column`` est un enfant direct de ``.row`` : Bootstrap lui applique la
       gouttière (12 px de chaque côté), d'où les bandes grises à gauche et à
       droite. L'onglet Conv' de l'index n'en a pas (son ``col-md`` porte
       ``p-0``), on les annule donc ici pour retrouver le même rendu. */
    .conv-page > .container > .row {
      margin-left: 0 !important;
      margin-right: 0 !important;
    }

    .conv-page > .container > .row > .column {
      padding-left: 0 !important;
      padding-right: 0 !important;
    }

    .conv-page .conv-page-card {
      border: 0 !important;
      border-radius: 0 !important;
      margin-top: 0 !important;
    }

    /* Le pied de page de ``base_generic`` porte ``d-flex`` : sa règle
       ``display: flex !important`` l'emporterait sur un simple ``display:
       none``, d'où le ``!important`` (comme pour ``.my-footer``, masqué lui
       aussi sur l'index mobile). */
    .conv-page footer,
    .conv-page .my-footer {
      display: none !important;
    }
  }

/* Aperçu d'image (affiche de course, de famille de courses, photo de profil,
   inscription) : une fois l'image choisie, les boutons « Choisir une autre
   image » et « Supprimer l'image » se placent sous l'aperçu au lieu d'être
   alignés à sa droite, avec une marge qui les aère.
   ``display: block`` sur l'aperçu fait passer le ``<label>`` qui porte le
   bouton « Choisir » sur la ligne suivante.
   Attention à la spécificité : la feuille du paquet (``cropping_widget.css``)
   est chargée *après* ``styles.css`` et ses sélecteurs ``.dcsic_wrapper.has_image
   .dcsic_*`` pèsent trois classes, autant que ``.image-buttons-page
   .dcsic_wrapper .dcsic_*`` — à spécificité égale, c'est elle qui gagnait, donc
   les boutons restaient ``inline``. Or une marge verticale n'est pas appliquée
   à un élément en ligne : ils restaient collés sous l'aperçu (et le
   recouvraient même de quelques pixels). On reprend donc le ``.has_image`` du
   paquet dans le sélecteur (quatre classes) pour le dépasser. */
.image-buttons-page .dcsic_wrapper.has_image .dcsic_current_img {
  display: block;
}

.image-buttons-page .dcsic_wrapper.has_image .dcsic_choose_other_img,
.image-buttons-page .dcsic_wrapper.has_image .dcsic_delete_image {
  /* ``inline-block`` : ``margin-top`` est ignoré sur un ``<span>`` resté
     ``inline``. */
  display: inline-block;
  /* Même hauteur pour les deux boutons : « Choisir une autre image » vit dans
     un ``<label>`` que le paquet met en ``line-height: normal``, alors que
     « Supprimer l'image » hérite du ``line-height`` du ``<body>`` ; sans
     hauteur de ligne commune les deux pastilles n'avaient pas la même taille. */
  line-height: 1.5;
  margin-left: 0;
  margin-top: 12px;
  /* Même apparence que les boutons du site : le paquet les dessinait en gris
     plat (coins 4 px, texte blanc, fond #999) sans rapport avec les pastilles
     arrondies du reste. On reprend le rayon et le rembourrage des ``.btn``. */
  padding: .375rem .75rem;
  border: 1px solid transparent;
  border-radius: var(--sc-radius-sm);
  font-size: .875rem;
  font-weight: 500;
  text-decoration: none;
  transition: background-color .15s ease, color .15s ease;
}

.image-buttons-page .dcsic_wrapper.has_image .dcsic_choose_other_img {
  color: #fff;
  background-color: var(--app-color);
}

.image-buttons-page .dcsic_wrapper.has_image .dcsic_choose_other_img:hover {
  color: #fff;
  background-color: var(--app-color);
  filter: brightness(.92);
}

.image-buttons-page .dcsic_wrapper.has_image .dcsic_delete_image {
  color: var(--sc-ink);
  background-color: #e2e8f0;
}

.image-buttons-page .dcsic_wrapper.has_image .dcsic_delete_image:hover {
  color: var(--sc-ink);
  background-color: #cbd5e1;
}

/* Aperçu encore vide : le bouton « Choisir une image » n'est pas dans un
   ``.has_image`` et gardait le gris du paquet. On l'habille comme la variante
   « choisir une autre image » pour que le premier choix et le remplacement se
   ressemblent. */
.image-buttons-page .dcsic_wrapper .dcsic_choose_img {
  display: inline-block;
  padding: .375rem .75rem;
  border: 1px solid transparent;
  border-radius: var(--sc-radius-sm);
  font-size: .875rem;
  font-weight: 500;
  line-height: 1.5;
  color: #fff;
  background-color: var(--app-color);
}

.image-buttons-page .dcsic_wrapper .dcsic_choose_img:hover {
  background-color: var(--app-color);
  filter: brightness(.92);
}

/* Bandeau de consentement aux cookies (vanilla-cookieconsent) : on reprend la
   couleur du site pour les boutons et les interrupteurs, comme le reste de
   l'interface. La bibliothèque expose des variables CSS préfixées ``--cc-``. */
#cc-main {
  --cc-font-family: "Open Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --cc-btn-primary-bg: var(--app-color, #2C59A6);
  --cc-btn-primary-border-color: var(--app-color, #2C59A6);
  --cc-btn-primary-hover-bg: var(--app-color, #2C59A6);
  --cc-btn-primary-hover-border-color: var(--app-color, #2C59A6);
  --cc-toggle-on-bg: var(--app-color, #2C59A6);
  --cc-toggle-on-knob-bg: #ffffff;
  --cc-link-color: var(--app-color, #2C59A6);
}

#cc-main .cm,
#cc-main .pm {
  border-radius: 10px;
}

/* La modale de préférences ne doit pas être rognée sur petit écran. */
@media (max-width: 767.98px) {
  #cc-main .pm {
    border-radius: 10px 10px 0 0;
  }
}

/* Sélecteur de famille du formulaire de modification d'une course (Tagify).
   Deux retouches sur le paquet (``tagify.css``, chargée après ``styles.css`` :
   les sélecteurs portent ``body`` pour la dépasser en spécificité) :
   1. La pastille s'appuie sur un ``box-shadow`` en incrustation de
      ``1.2em`` (``--tag-inset-shadow-size``) pour dessiner son fond. Sur un nom
      de famille assez long pour passer sur deux lignes (petit écran), cette
      incrustation ne couvre plus le milieu de la pastille : une bande blanche
      apparaît entre les lignes. On passe la variable sur ``.tagify`` (elle y
      est *déclarée*, donc une valeur posée sur un ancêtre serait ignorée) à une
      taille qui déborde toujours de la boîte.
   2. Le ``placeholder`` du champ (« — Ne pas changer — ») réapparaît dès que le
      champ a le focus, alors qu'une pastille est déjà posée : ``tagify.css``
      réaffiche ``.tagify__input::before`` sur ``:focus`` pour laisser voir
      l'invite quand la zone est vide, mais le ``:focus`` s'applique aussi à la
      zone de saisie qui suit la pastille. On le masque tant que le champ n'est
      pas vide. */
body.family-picker-page .tagify {
  --tag-inset-shadow-size: 9999px;
}

body.family-picker-page .tagify:not(.tagify--empty) .tagify__input::before {
  content: none;
}
