/* ==========================================================
   Couleurs
   ==========================================================
   Deux jeux de variables : le thème clair sur :root, le thème
   sombre en dessous. Tout le reste de la feuille n'utilise que
   des variables — changer de thème n'exige donc aucune règle
   en double.

   Le choix du visiteur est écrit dans data-theme sur <html>.
   Sans choix explicite, on suit le réglage du système.
   ========================================================== */
:root {
    /* ==========================================================
       Palette RidePaddle
       ==========================================================
       Trois couleurs viennent du logo, et rien d'autre :
         --marine  le bleu nuit du « Ride »
         --ride    le bleu vif du « Paddle »
         --ecume   l'écume de la vague sous le mot

       --ride est superbe en aplat, mais trop clair pour écrire
       dessus en blanc ou pour servir de texte sur du blanc :
       --ride-encre est sa version foncée, calculée pour rester
       lisible (contraste AA). L'un peint, l'autre écrit.
       ========================================================== */
    --marine: #0b203c;
    --marine-2: #123454;
    --ride: #1b9df0;
    --ride-encre: #0f76c4;
    --ecume: #6fd3e6;

    /* Surfaces et texte : redéfinis en thème sombre */
    --fond: #f4f7fa;
    --surface: #ffffff;
    --surface-2: #e9f1f7;
    --ombre: rgba(11, 32, 60, .06);

    /* Réussite et alerte. Ces deux teintes portent un SENS — c'est
       fait, c'est raté — et elles étaient codées en dur, donc figées
       en clair : un bandeau « défi réussi » restait vert pâle sur fond
       noir, avec un texte vert foncé illisible dessus. */
    --reussi-fond: #e6f7ec;
    --reussi-texte: #17603a;
    --reussi-bord: #9ad9b3;
    --alerte-fond: #fff1ec;
    --alerte-texte: #8a3b28;

    --blue-deep: var(--marine);
    /* --blue-deep sert à deux choses incompatibles : peindre un fond
       foncé, et écrire un titre foncé. En thème sombre, la première
       reste juste, la seconde devient un texte noir sur fond noir.
       --titre ne sert qu'à écrire, et suit donc le thème. */
    --titre: #0b203c;
    --blue: var(--ride-encre);
    --blue-light: var(--ecume);
    --sand: #eef4f9;
    --green: #2e8b57;
    --red: #c0392b;
    --accent: #ff7a45;
    --accent-dark: #e5502c;
    --text: #16283a;
    --muted: #5b7386;
    --border: #d6e2ec;
    --radius: 12px;
    --navbar-height: 68px;
    --font-heading: 'Outfit', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    --font-body: 'Inter', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

    /* Fait adopter notre palette à tous les composants Bootstrap (boutons, liens, badges...) */
    --bs-primary: var(--ride-encre);
    --bs-primary-rgb: 15, 118, 196;
    --bs-link-color: var(--ride-encre);
    --bs-link-hover-color: var(--marine);
    --bs-body-font-family: var(--font-body);
    --bs-body-color: var(--text);
    --bs-border-radius: .6rem;
    --bs-border-radius-lg: .85rem;
    --bs-border-radius-sm: .42rem;
    --bs-body-bg: var(--fond);
    --bs-emphasis-color: var(--text);
    color-scheme: light;
}

/* --- Thème sombre ------------------------------------------------
   Bleus adoucis et fonds gris-bleu : sur un écran allumé la nuit,
   du noir pur avec du texte blanc fatigue plus qu'il n'aide. */
:root[data-theme="sombre"] {
    --marine: #0a1826;
    --marine-2: #12293f;
    --ride: #3fb0f5;
    --ride-encre: #5cbdf7;
    --ecume: #7fdcec;

    --fond: #0d1720;
    --surface: #142330;
    --surface-2: #1c3040;
    --ombre: rgba(0, 0, 0, .4);

    --blue-deep: #0a1826;
    --titre: #e8f1f8;
    --blue: #5cbdf7;
    --blue-light: #7fdcec;
    --sand: #16242f;
    --text: #e8f1f8;
    --muted: #9db4c4;
    --border: #27404f;

    /* Mêmes rôles, teintes assombries : le vert et l'orange restent
       reconnaissables, et le texte redevient lisible dessus. */
    --reussi-fond: #14372a;
    --reussi-texte: #7fd6a3;
    --reussi-bord: #2c6a4b;
    --alerte-fond: #3a1f18;
    --alerte-texte: #ffab8f;

    --bs-primary: #3fb0f5;
    --bs-primary-rgb: 63, 176, 245;
    --bs-link-color: #6fc9fa;
    --bs-link-hover-color: #9adcfd;
    --bs-body-color: var(--text);
    --bs-body-bg: var(--fond);
    --bs-emphasis-color: var(--text);
    --bs-secondary-color: var(--muted);
    color-scheme: dark;
}

/* Sans choix explicite, on respecte le réglage du téléphone
   ou de l'ordinateur. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) {
        --marine: #0a1826;
        --marine-2: #12293f;
        --ride: #3fb0f5;
        --ride-encre: #5cbdf7;
        --ecume: #7fdcec;

        --fond: #0d1720;
        --surface: #142330;
        --surface-2: #1c3040;
        --ombre: rgba(0, 0, 0, .4);

        --blue-deep: #0a1826;
        --titre: #e8f1f8;
        --blue: #5cbdf7;
        --blue-light: #7fdcec;
        --sand: #16242f;
        --text: #e8f1f8;
        --muted: #9db4c4;
        --border: #27404f;

        --reussi-fond: #14372a;
        --reussi-texte: #7fd6a3;
        --reussi-bord: #2c6a4b;
        --alerte-fond: #3a1f18;
        --alerte-texte: #ffab8f;

        --bs-primary: #3fb0f5;
        --bs-primary-rgb: 63, 176, 245;
        --bs-link-color: #6fc9fa;
        --bs-link-hover-color: #9adcfd;
        --bs-body-color: var(--text);
        --bs-body-bg: var(--fond);
        --bs-emphasis-color: var(--text);
        --bs-secondary-color: var(--muted);
        color-scheme: dark;
    }
}

body {
    /* Fond uni : les dégradés d'ambiance fatiguaient la lecture
       sur les pages longues (profil, paramètres, communauté). */
    background: var(--fond);
    color: var(--text);
    min-height: 100vh;
    /* Pied de page collé en bas même sur une page courte */
    display: flex;
    flex-direction: column;
}
.site-main { flex: 1 0 auto; }
.site-footer { flex-shrink: 0; }

h1, h2, h3, h4, .navbar-brand, .fw-heading { font-family: var(--font-heading); }

/* --- Navbar --- */
.site-navbar {
    background: var(--blue-deep);
    box-shadow: 0 1px 0 rgba(11,61,85,.12);
    min-height: var(--navbar-height);
    border-bottom: 1px solid rgba(255,255,255,.08);
}
.site-navbar .navbar-brand { letter-spacing: -.01em; }
.site-navbar .nav-link {
    color: #eaf6fb;
    font-weight: 500;
    position: relative;
    transition: color .15s ease;
}
.site-navbar .nav-link:hover { color: #fff; }
.site-navbar .nav-item .nav-link:not(.nav-admin-link)::after {
    content: '';
    position: absolute;
    left: .5rem; right: .5rem; bottom: -2px;
    height: 2px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: center;
    transition: transform .18s ease;
}
.site-navbar .nav-item .nav-link:not(.nav-admin-link):hover::after { transform: scaleX(1); }
.nav-user-label { color: #cfeaf5; }
.nav-admin-link {
    background: rgba(255,255,255,.12);
    border: 1px solid rgba(255,255,255,.28);
    color: #fff !important;
    border-radius: 8px;
    padding: .3rem .8rem !important;
    font-weight: 600;
}
.nav-admin-link:hover { filter: brightness(1.05); }

.site-main:has(.map-page), .site-main:has(.add-spot-page), .site-main:has(.auth-page) { padding: 0; }

/* --- Hero --- */
.hero {
    position: relative;
    background: linear-gradient(165deg, var(--blue-deep) 0%, #10557a 100%);
    overflow: hidden;
    padding-bottom: 3.5rem;
}
.hero__inner {
    max-width: 1240px;
    margin: 0 auto;
    padding: 3.5rem 1.5rem 2.5rem;
    display: flex;
    align-items: center;
    gap: 2.5rem;
    flex-wrap: wrap;
}
.hero__text { flex: 1 1 420px; color: #fff; }
.hero__eyebrow {
    display: inline-block;
    background: rgba(255,255,255,.16);
    border: 1px solid rgba(255,255,255,.3);
    color: #eaf6fb;
    font-size: .8rem;
    font-weight: 600;
    padding: .35rem .8rem;
    border-radius: 999px;
    margin-bottom: 1.1rem;
}
.hero__text h1 {
    font-size: clamp(1.9rem, 4vw, 3rem);
    line-height: 1.12;
    margin: 0 0 1rem;
    /*  Le navigateur répartit le titre sur ses lignes au lieu de laisser
        un mot seul en dernière ligne. Sans cela, « trouve où te garer »
        se coupait n'importe où selon la largeur de l'écran. Les
        navigateurs qui ne connaissent pas la propriété l'ignorent : le
        titre reste comme avant. */
    text-wrap: balance;
    font-weight: 800;
    letter-spacing: -.01em;
}
.hero__tagline {
    font-size: 1.05rem;
    line-height: 1.6;
    color: #dcecf3;
    max-width: 42ch;
    margin: 0 0 1.75rem;
}
.hero__stats { display: flex; gap: 1.5rem; margin-bottom: 2rem; flex-wrap: wrap; }
.hero-stat__value {
    display: block;
    font-family: var(--font-heading);
    font-size: 1.7rem;
    font-weight: 700;
    color: #fff;
}
.hero-stat__label { font-size: .78rem; color: #bcdbe8; }
.hero__actions { display: flex; gap: .85rem; flex-wrap: wrap; }
.btn-cta {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
    font-weight: 600;
    transition: background .15s ease;
}
.btn-cta:hover, .btn-cta:focus {
    background: var(--accent-dark);
    border-color: var(--accent-dark);
    color: #fff;
}
.btn-ghost {
    background: transparent;
    color: #fff;
    border: 1.5px solid rgba(255,255,255,.55);
    font-weight: 600;
    transition: background .15s ease, border-color .15s ease;
}
.btn-ghost:hover { background: rgba(255,255,255,.12); border-color: #fff; color: #fff; }

/*  La bannière et la carte de France, l'une au-dessus de l'autre.
    En colonne, pas en ligne : côte à côte, chacune tombe sous les
    200 px sur un portable en paysage et les deux deviennent illisibles. */
.hero__map {
    flex: 1 1 340px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: .5rem;
    min-width: 0;
}
.hero__marque {
    width: 100%;
    max-width: 440px;
    height: auto;
    /*  Marge négative : le fichier de la bannière porte sa propre
        bande transparente en haut et en bas. Sans cela, la signature
        flotte à trois fois la bonne distance du logo — un espace que
        rien à l'écran ne justifie, puisqu'il est dans l'image. */
    margin-bottom: -1.75rem;
    /*  L'ombre portée détache le blanc du bleu : sans elle, le tracé
        fin du logo se fond dans le dégradé du bandeau. */
    filter: drop-shadow(0 10px 22px rgba(0, 0, 0, .35));
}
.hero-map__svg { width: 100%; max-width: 420px; height: auto; filter: drop-shadow(0 18px 30px rgba(0,0,0,.35)); }
.hero-map__shape { stroke: rgba(255,255,255,.55); stroke-width: 1.6; stroke-linejoin: round; }
.hero-pin { transform-box: fill-box; transform-origin: center; }
.hero-pin__dot { fill: var(--accent); stroke: #fff; stroke-width: 2; }
.hero-pin__pulse {
    fill: var(--accent);
    opacity: .45;
    transform-box: fill-box;
    transform-origin: center;
    animation: heroPulse 2.6s ease-out infinite;
}
@keyframes heroPulse {
    0%   { transform: scale(.3); opacity: .55; }
    70%  { transform: scale(1.6); opacity: 0; }
    100% { transform: scale(1.6); opacity: 0; }
}

.hero__wave {
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    height: 70px;
    background-repeat: repeat-x;
    background-size: 1440px 70px;
    background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 70' preserveAspectRatio='none'%3E%3Cpath fill='%23f5efe3' d='M0,40 C240,90 480,0 720,20 C960,40 1200,90 1440,40 L1440,70 L0,70 Z'%3E%3C/path%3E%3C/svg%3E");
}

/* --- Cartes / pages de contenu --- */
.page-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 1px 2px var(--ombre);
    position: relative;
}
.muted { color: var(--muted); }

.site-main > .container, .site-main > .container-fluid { position: relative; }
.site-main > .container > h1:first-child,
.site-main > .container > .h3:first-child {
    position: relative;
    padding-left: .95rem;
}
.site-main > .container > h1:first-child::before,
.site-main > .container > .h3:first-child::before {
    content: '';
    position: absolute;
    left: 0; top: .15em; bottom: .15em;
    width: 4px;
    border-radius: 999px;
    background: var(--blue);
}

/* --- Boutons --- */
.btn { font-weight: 600; }
.btn-primary { transition: filter .15s ease; }
.btn-primary:hover, .btn-primary:focus { filter: brightness(1.06); }
.btn-outline-secondary { font-weight: 600; }

/* --- Formulaires --- */
.form-control:focus, .form-select:focus {
    border-color: var(--blue-light);
    box-shadow: 0 0 0 .2rem rgba(72,192,217,.25);
}
.form-label { font-weight: 600; color: var(--titre); font-size: .92rem; }

/* --- Tableaux --- */
.table thead th {
    text-transform: uppercase;
    font-size: .72rem;
    letter-spacing: .04em;
    color: var(--muted);
    border-bottom-width: 1px;
    font-weight: 700;
}

/* --- Admin --- */
.admin-card {
    background: linear-gradient(155deg, var(--surface), var(--surface-2));
    border: 1px solid #dfeef3;
    border-radius: var(--radius);
    padding: 1.1rem 1.2rem;
    text-align: center;
    transition: transform .15s ease, box-shadow .15s ease;
}
.admin-card:hover { transform: translateY(-2px); box-shadow: 0 8px 18px rgba(11,61,85,.1); }
.admin-card__value { display: block; font-family: var(--font-heading); font-size: 1.9rem; font-weight: 700; color: var(--titre); }
.admin-card__label { font-size: .78rem; color: var(--muted); font-weight: 600; }
/* La pastille « admin » d'une liste de membres. Elle s'appelait
   .badge-admin — comme les LIGNES du catalogue de badges, un composant
   entièrement différent défini plus bas. Le catalogue héritait donc de
   ce fond orange, et devenait illisible. Deux choses distinctes, deux
   noms distincts. */
.pastille-admin { background: #f2a516; color: #3a2600; }
.pastille-moderateur { background: #2b8fd0; color: #fff; }

/* --- Footer --- */
.site-footer {
    background: linear-gradient(180deg, transparent, rgba(15,111,168,.06));
    border-top: 1px solid var(--border);
    margin-top: 2rem;
}

/* --- Pages d'authentification (connexion / inscription) --- */
.auth-page {
    display: flex;
    min-height: calc(100vh - var(--navbar-height));
}
.auth-panel {
    flex: 1 1 46%;
    background: linear-gradient(160deg, var(--blue-deep) 0%, var(--blue) 55%, var(--blue-light) 100%);
    color: #fff;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 3rem 3.5rem;
    position: relative;
    overflow: hidden;
}
.auth-panel::after {
    content: '';
    position: absolute;
    inset: 0;
    background-image: radial-gradient(circle, rgba(255,255,255,.55) 1.5px, transparent 1.5px);
    background-size: 26px 26px;
    opacity: .12;
    pointer-events: none;
}
.auth-panel__brand {
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: 1.5rem;
    margin-bottom: 2.5rem;
    position: relative;
}
.auth-panel__title {
    font-family: var(--font-heading);
    font-weight: 800;
    text-wrap: balance;
    font-size: clamp(1.6rem, 3vw, 2.2rem);
    line-height: 1.2;
    margin-bottom: 1rem;
    position: relative;
    max-width: 20ch;
}
.auth-panel__tagline {
    color: #dcecf3;
    max-width: 34ch;
    line-height: 1.6;
    margin-bottom: 2rem;
    position: relative;
}
.auth-features { list-style: none; padding: 0; margin: 0; position: relative; }
.auth-features li {
    display: flex;
    align-items: center;
    gap: .65rem;
    margin-bottom: .85rem;
    color: #eaf6fb;
    font-weight: 500;
}
.auth-features li .icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px; height: 32px;
    background: rgba(255,255,255,.15);
    border-radius: 8px;
    flex-shrink: 0;
}
.auth-form-side {
    flex: 1 1 54%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2.5rem 1.5rem;
    background: var(--sand);
}
.auth-form-card { width: 100%; max-width: 420px; }
.auth-form-card .page-card { border: none; box-shadow: 0 10px 34px rgba(11,61,85,.12); }

@media (max-width: 900px) {
    .auth-page { flex-direction: column; min-height: auto; }
    .auth-panel { padding: 2.5rem 1.75rem; }
    .auth-panel__tagline, .auth-features { display: none; }
}

/* --- Map page (application plein écran) --- */
.map-page {
    display: flex;
    height: calc(100vh - var(--navbar-height));
    min-height: 500px;
    /* Le lien "Explorer la carte ↓" ne doit pas s'arrêter sous la barre fixe */
    scroll-margin-top: var(--navbar-height);
}
#map {
    flex: 1;
    background: linear-gradient(160deg, #cfe9f0 0%, #eef6f4 60%, var(--sand) 100%);
}
.sidebar {
    width: 340px;
    flex-shrink: 0;
    background: var(--surface);
    border-right: 1px solid var(--border);
    overflow-y: auto;
    padding: 1.25rem;
}
.panel { margin-bottom: 1.5rem; padding-bottom: 1.25rem; border-bottom: 1px solid var(--border); }
.panel:last-child { border-bottom: none; }
.panel h2 { font-size: 1rem; margin: 0 0 .75rem; }

.hidden { display: none !important; }

.stat-pill { flex: 1; background: var(--surface-2); border-radius: 8px; padding: .6rem; text-align: center; }
.stat-pill__value { display: block; font-size: 1.4rem; font-weight: 700; color: var(--titre); }
.stat-pill__label { font-size: .75rem; color: var(--muted); }

/* --- Add spot page --- */
.add-spot-page {
    display: flex;
    height: calc(100vh - var(--navbar-height));
    min-height: 500px;
}
.add-spot-form {
    width: 400px;
    flex-shrink: 0;
    background: var(--surface);
    border-right: 1px solid var(--border);
    overflow-y: auto;
    padding: 1.5rem;
}

/* --- Contenu des popups Leaflet --- */
.spot-popup h3 { margin: 0 0 .3rem; font-size: 1rem; }
.spot-popup .badge-type { background: var(--blue-light); color: #fff; }
.spot-popup p { margin: .3rem 0; font-size: .85rem; }

/* --- Alerte dans une bulle de carte ---
   Les bulles Leaflet gardent un fond clair dans les deux thèmes (voir
   plus bas) : ces couleurs sont donc écrites en dur, comme le reste de
   la bulle. Un jeton de thème y deviendrait faux la moitié du temps. */
.spot-popup .popup-alerte {
    margin: .4rem 0;
    padding: .4rem .55rem;
    border-radius: 6px;
    border-left: 3px solid #d98324;
    background: #fff6e8;
    color: #7a4a12;
    font-size: .82rem;
    line-height: 1.35;
}
.spot-popup .popup-alerte--stop {
    border-left-color: #c0392b;
    background: #fdeceb;
    color: #8a2118;
}
.spot-popup .popup-alerte span { margin-top: .15rem; opacity: .9; }

/* --- Marqueurs Leaflet personnalisés --- */
.spot-marker-icon, .waypoint-marker-icon, .picker-marker-icon { background: transparent; border: none; }
.marker-emoji {
    font-size: 1.5rem;
    text-align: center;
    line-height: 1;
    filter: drop-shadow(0 2px 2px rgba(0,0,0,.35));
}
/* --- Les grappes d'épingles (voir js/regroupement.js) ---
 *
 *  Une pastille ronde au logo du site, avec le nombre de lieux qu'elle
 *  cache en médaillon. Elle est volontairement plus grosse qu'une
 *  épingle : c'est ce qui fait comprendre, sans explication, qu'elle en
 *  vaut plusieurs. */
.grappe-icone { background: transparent; border: none; }
.grappe {
    position: relative;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: #fff;
    /*  Couleur de texte POSÉE, et non héritée : la pastille garde son
        fond blanc dans les deux thèmes, alors que la couleur héritée,
        elle, s'éclaircit en mode sombre. L'emblème devenait alors blanc
        sur blanc — invisible dès qu'un navigateur rend l'emoji en
        monochrome, ce que font les lecteurs d'écran et certains Linux. */
    color: #0b203c;
    border: 3px solid var(--blue-deep, #0b203c);
    box-shadow: 0 3px 10px rgba(0,0,0,.35);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.35rem;
    line-height: 1;
    cursor: pointer;
    transition: transform .12s ease;
}
.grappe:hover { transform: scale(1.08); }
.grappe--l  { width: 54px; height: 54px; font-size: 1.5rem; }
.grappe--xl { width: 62px; height: 62px; font-size: 1.7rem; }
.grappe__embleme {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 76%;
    height: 76%;
}
.grappe__embleme img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    display: block;
}
/*  Le nombre en médaillon, et non au centre : le centre porte déjà le
 *  logo, qui est ce qui identifie la pastille d'un coup d'œil.
 *
 *  Sur bleu nuit, et non sur l'orange de la marque : blanc sur orange ne
 *  dépasse pas 2,6 de contraste, très en dessous du minimum lisible. Le
 *  bleu profond passe à plus de 15. */
.grappe__nombre {
    position: absolute;
    right: -6px;
    bottom: -4px;
    background: var(--blue-deep, #0b203c);
    color: #fff;
    font-size: .72rem;
    font-weight: 800;
    line-height: 1;
    padding: .2rem .35rem;
    border-radius: 999px;
    border: 2px solid #fff;
    font-family: var(--font-heading, inherit);
    white-space: nowrap;
}
/*  La pastille des parkings est décalée d'un quart de tour : un parking
 *  et un spot sont presque toujours au même endroit, et leurs deux
 *  pastilles se posaient exactement l'une sur l'autre — ce qui donnait
 *  une icône « cassée » au dézoom. Décalées, on lit les deux d'un coup
 *  d'œil, et on comprend qu'elles vont ensemble. */
.grappe--parking {
    background: #eef4fb;
    transform: translate(16px, 14px);
}
.grappe--parking:hover { transform: translate(16px, 14px) scale(1.08); }

.waypoint-marker {
    background: var(--blue-deep);
    color: #fff;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: .75rem;
    font-weight: 700;
    border: 2px solid #fff;
    box-shadow: 0 1px 3px rgba(0,0,0,.4);
}
.picker-marker {
    background: var(--red);
    color: #fff;
    width: 26px;
    height: 26px;
    border-radius: 50% 50% 50% 0;
    transform: rotate(-45deg);
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid #fff;
    box-shadow: 0 1px 3px rgba(0,0,0,.4);
}

/* ==========================================================
   MOBILE — la carte occupe tout l'écran, les réglages sont
   dans un panneau coulissant qu'on ouvre d'un pouce.
   ========================================================== */

/* La poignée n'existe que sur téléphone */
.sheet-poignee { display: none; }

@media (max-width: 991.98px) {

    /* ---------- Page carte ---------- */
    .map-page {
        display: block;
        position: relative;
        /* dvh suit la barre d'adresse mobile, contrairement à vh */
        height: calc(100dvh - var(--navbar-height));
        min-height: 420px;
        /* Sans ça, la feuille repliée (translatée vers le bas) dépasse
           sous la carte et son contenu reste visible : c'est le défaut
           qu'on voyait en bas de l'écran. */
        overflow: hidden;
    }
    #map {
        position: absolute;
        inset: 0;
        height: 100%;
    }

    /* Le panneau devient une feuille qui glisse depuis le bas */
    .sidebar {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        width: auto;
        max-height: 80%;
        padding: 0;
        border-right: none;
        border-top: 1px solid var(--border);
        border-radius: 20px 20px 0 0;
        box-shadow: 0 -8px 28px rgba(11,61,85,.22);
        display: flex;
        flex-direction: column;
        overflow: hidden;
        z-index: 1100;             /* au-dessus des contrôles Leaflet (z-index 1000) */
        transform: translateY(calc(100% - var(--sheet-hauteur-poignee, 62px)));
        transition: transform .28s cubic-bezier(.32,.72,0,1);
    }
    .sidebar.est-ouvert { transform: translateY(0); }

    .sheet-poignee {
        display: block;
        width: 100%;
        border: none;
        background: transparent;
        padding: .55rem 1rem .7rem;
        text-align: center;
        cursor: pointer;
        flex-shrink: 0;
    }
    .sheet-poignee__barre {
        display: block;
        width: 42px;
        height: 5px;
        margin: 0 auto .5rem;
        border-radius: 999px;
        background: var(--border);
    }
    .sheet-poignee__texte {
        display: block;
        font-size: .88rem;
        font-weight: 600;
        color: var(--titre);
        line-height: 1.25;
    }
    /* Quand un parcours est en cours, la poignée affiche les chiffres */
    .sheet-poignee__texte.est-parcours { color: var(--accent-dark); }

    .sidebar__contenu {
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        /* marge basse supplémentaire pour la barre gestuelle des iPhone */
        padding: 0 1rem calc(1.25rem + env(safe-area-inset-bottom, 0px));
        overscroll-behavior: contain;
    }

    .panel { margin-bottom: 1.1rem; padding-bottom: 1rem; }

    /* ---------- Confort tactile ---------- */
    .sidebar .btn,
    .sidebar .form-control,
    .sidebar .form-select {
        min-height: 46px;
        font-size: 1rem;          /* évite le zoom automatique iOS */
    }
    .sidebar .form-check-input {
        width: 1.35em;
        height: 1.35em;
        margin-top: .1em;
    }
    .sidebar .form-check-label { padding-left: .25rem; font-size: 1rem; }
    .sidebar .form-check { margin-bottom: .75rem; }
    .stat-pill__value { font-size: 1.6rem; }
    #speed-range { height: 2rem; }

    /* Les contrôles Leaflet remontent au-dessus de la poignée.
       Sélecteur double : leaflet.css est chargé après cette feuille,
       il faut donc être plus spécifique que lui. */
    .map-page .leaflet-bottom,
    .map-page .leaflet-control-container .leaflet-bottom {
        bottom: var(--sheet-hauteur-poignee, 62px);
    }
    .map-page .leaflet-control-attribution {
        font-size: .62rem;
        padding: 1px 5px;
        background: rgba(255,255,255,.75);
    }
    .map-page .leaflet-control-zoom a { width: 38px; height: 38px; line-height: 38px; font-size: 1.25rem; }

    /* ---------- Hero plus compact ---------- */
    .hero__inner { padding: 2rem 1.25rem 1.5rem; gap: 1.5rem; }
    .hero__tagline { margin-bottom: 1.25rem; }
    .hero__stats { gap: 1rem; margin-bottom: 1.25rem; }
    .hero-stat__value { font-size: 1.4rem; }
    .hero__map { display: none; }          /* la carte décorative prend trop de place */
    .hero { padding-bottom: 3rem; }
    .hero__actions .btn { flex: 1 1 auto; min-height: 46px; }

    /* ---------- Page "ajouter un lieu" ---------- */
    .add-spot-page {
        flex-direction: column-reverse;    /* la carte d'abord, le formulaire dessous */
        height: auto;
    }
    .add-spot-form {
        width: auto;
        max-height: none;
        border-right: none;
        padding: 1.25rem 1rem 1.5rem;
    }
    .add-spot-page #map {
        position: relative;
        height: 45dvh;
        min-height: 260px;
        inset: auto;
    }
    .add-spot-form .btn[type="submit"] {
        position: sticky;
        bottom: .75rem;
        min-height: 50px;
        box-shadow: 0 6px 20px rgba(15,111,168,.35);
    }

    /* ---------- Tableaux plus lisibles ---------- */
    .table thead th { font-size: .66rem; }
    .table td, .table th { padding: .55rem .4rem; }
}

/* Très petits écrans */
@media (max-width: 400px) {
    .hero__text h1 { font-size: 1.6rem; }
    .sheet-poignee__texte { font-size: .82rem; }
}

/* --- Avatars des membres --- */
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
    border: 2px solid #fff;
    box-shadow: 0 2px 8px rgba(11,61,85,.15);
    background: var(--surface-2);
}
.avatar--initiales {
    background: linear-gradient(140deg, var(--blue), var(--blue-light));
    color: #fff;
    font-weight: 700;
    font-family: var(--font-heading);
    letter-spacing: .02em;
}

/* --- Grades --- */
.grade-badge {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    background: color-mix(in srgb, var(--grade-color) 14%, #fff);
    color: color-mix(in srgb, var(--grade-color) 75%, #000);
    border: 1px solid color-mix(in srgb, var(--grade-color) 35%, #fff);
    border-radius: 999px;
    padding: .3rem .8rem;
    font-weight: 700;
    font-size: .9rem;
}
.grade-badge--sm { font-size: .78rem; padding: .18rem .6rem; font-weight: 600; }
.grade-badge--actif { box-shadow: 0 0 0 2px color-mix(in srgb, var(--grade-color) 30%, #fff); }

/* Repli si color-mix n'est pas géré par le navigateur */
@supports not (background: color-mix(in srgb, red 10%, white)) {
    .grade-badge { background: var(--surface-2); color: var(--titre); border-color: var(--border); }
}

/* --- Cartes membre --- */
.membre-carte { transition: transform .15s ease, box-shadow .15s ease; }
.membre-carte:hover { border-color: var(--blue-light); }
.min-w-0 { min-width: 0; }
.lien-discret { color: inherit; text-decoration: none; }
.lien-discret:hover { color: var(--blue); text-decoration: underline; }

/* --- Avis --- */
.note-etoiles { color: #f2a516; letter-spacing: .08em; }
.avis-item { padding: 1rem 0; border-top: 1px solid var(--border); }
.avis-item:first-of-type { border-top: none; padding-top: 0; }

/* --- Notifications --- */
.liste-notifs { list-style: none; margin: 0; padding: 0; }
.liste-notifs li { padding: .7rem 0 .7rem .9rem; border-top: 1px solid var(--border); border-left: 3px solid transparent; }
.liste-notifs li:first-child { border-top: none; }
.liste-notifs .notif--non-lue { border-left-color: var(--accent); background: var(--alerte-fond); }
.spot-popup .popup-badges { display: flex; flex-wrap: wrap; gap: .25rem; margin: .4rem 0; }
.spot-popup .btn { margin-top: .4rem; }
.notif-pastille {
    display: inline-block;
    background: var(--accent);
    color: #fff;
    border-radius: 999px;
    padding: 0 .45rem;
    font-size: .7rem;
    font-weight: 700;
}

/* ==========================================================
   Nouveautés : menu compte, paramètres, messagerie,
   chronomètre, parkings de parcours, anti-robot
   ========================================================== */

/* --- Menu déroulant du compte --- */
.menu-compte__declencheur {
    display: flex;
    align-items: center;
    gap: .5rem;
}
.menu-compte__declencheur .avatar {
    border-width: 1px;
    box-shadow: none;
}
.menu-compte__pseudo {
    font-weight: 600;
    max-width: 12ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.menu-compte .dropdown-menu {
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 12px 34px rgba(11,61,85,.18);
    padding: .4rem;
    min-width: 15rem;
}
.menu-compte .dropdown-item {
    border-radius: 9px;
    padding: .55rem .7rem;
    font-weight: 500;
}
.menu-compte .dropdown-item:active { background: var(--blue); }

/* --- Page Paramètres --- */
.reglages {
    display: grid;
    grid-template-columns: 230px minmax(0, 1fr);
    gap: 1.25rem;
    align-items: start;
}
.reglages__menu {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    position: sticky;
    top: calc(var(--navbar-height) + 1rem);
}
.reglages__lien {
    display: block;
    padding: .6rem .85rem;
    border-radius: 10px;
    color: var(--titre);
    text-decoration: none;
    font-weight: 500;
    border: 1px solid transparent;
}
.reglages__lien:hover { background: var(--surface); border-color: var(--border); }
.reglages__lien.est-actif {
    background: var(--blue);
    color: #fff;
    box-shadow: 0 4px 14px rgba(15,111,168,.28);
}
.zone-danger { border: 1px solid #f3c9c4; }
.liste-simple { list-style: none; margin: 0; padding: 0; }
.liste-simple li { padding: .6rem 0; border-top: 1px solid var(--border); }
.liste-simple li:first-child { border-top: none; }
.etat-emoji { font-size: 2.6rem; line-height: 1; margin-bottom: .5rem; }
.mt--1 { margin-top: -.5rem; }

/* --- Anti-robot --- */
.anti-robot {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: .9rem 1rem;
}
.anti-robot .form-label { font-weight: 600; margin-bottom: .5rem; }
.anti-robot__question {
    display: block;
    font-weight: 500;
    color: var(--titre);
    margin-top: .2rem;
}
/* --- La case « Je ne suis pas un robot » ---
   Volontairement grande et cliquable partout : c'est le seul geste
   demandé, autant qu'il soit facile au doigt comme à la souris. */
.case-robot {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .15rem .1rem;
}
.case-robot__case {
    width: 26px; height: 26px;
    flex: none;
    margin: 0;
    cursor: pointer;
    accent-color: var(--accent);
}
.case-robot__texte {
    font-weight: 600;
    color: var(--titre);
    cursor: pointer;
    user-select: none;
    margin: 0;
}
/* La coche verte, qui n'apparaît qu'une fois la case cochée : un
   retour visible vaut mieux qu'un formulaire qui ne dit rien. */
.case-robot__marque {
    margin-left: auto;
    width: 22px; height: 22px;
    color: var(--succes, #1a6349);
    opacity: 0;
    transform: scale(.6);
    transition: opacity .18s ease, transform .18s ease;
}
.case-robot__case:checked ~ .case-robot__marque {
    opacity: 1;
    transform: scale(1);
}
.case-robot__marque svg { width: 100%; height: 100%; }
@media (prefers-reduced-motion: reduce) {
    .case-robot__marque { transition: none; }
}

/* Le pot de miel : invisible pour un humain, rempli par les robots. */
.anti-robot__piege {
    position: absolute !important;
    left: -9999px !important;
    width: 1px; height: 1px;
    overflow: hidden;
}

/* --- Messagerie --- */
.messagerie {
    display: grid;
    grid-template-columns: 300px minmax(0, 1fr);
    gap: 1rem;
    align-items: stretch;
    min-height: 60vh;
}
.messagerie__liste {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    overflow: hidden auto;
    max-height: 70vh;
}
.conv {
    display: flex;
    gap: .7rem;
    align-items: center;
    padding: .7rem .8rem;
    border-bottom: 1px solid var(--border);
    text-decoration: none;
    color: inherit;
}
.conv:last-child { border-bottom: none; }
.conv:hover { background: var(--surface-2); }
.conv.est-actif { background: var(--surface-2); }
.conv.est-non-lue .conv__nom { font-weight: 700; }
.conv__texte { min-width: 0; flex: 1; }
.conv__nom { display: block; font-weight: 600; }
.conv__apercu {
    display: block;
    font-size: .85rem;
    color: var(--muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.messagerie__fil {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    overflow: hidden;
    max-height: 70vh;
}
.messagerie__vide {
    margin: auto;
    text-align: center;
    padding: 2rem 1rem;
}
.fil__entete {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .7rem .9rem;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.fil__membre { display: flex; align-items: center; gap: .6rem; font-weight: 600; }
.fil__messages {
    flex: 1;
    overflow-y: auto;
    padding: 1rem;
    /* En couleurs de thème, et non en dur : le fil restait blanc en
       mode sombre, avec un pseudo gris clair devenu illisible dessus. */
    background: var(--surface);
}
.fil__jour {
    text-align: center;
    font-size: .75rem;
    color: var(--muted);
    margin: .8rem 0 .5rem;
}
.bulle {
    max-width: min(78%, 560px);
    padding: .55rem .8rem;
    border-radius: 16px;
    margin-bottom: .45rem;
    position: relative;
    word-break: break-word;
}
.bulle--moi {
    margin-left: auto;
    background: var(--blue);
    color: #fff;
    border-bottom-right-radius: 5px;
}
.bulle--autre {
    background: var(--surface-2);
    color: var(--text);
    border-bottom-left-radius: 5px;
}
.bulle__heure { font-size: .7rem; opacity: .75; text-align: right; margin-top: .15rem; }
.fil__saisie {
    display: flex;
    gap: .5rem;
    padding: .7rem;
    border-top: 1px solid var(--border);
    background: var(--surface);
}
.fil__saisie textarea { resize: none; border-radius: 14px; }
.fil__bloque {
    padding: .9rem;
    border-top: 1px solid var(--border);
    background: var(--alerte-fond);
    color: var(--alerte-texte);
    font-size: .9rem;
    text-align: center;
}

/* --- Parkings trouvés autour d'un parcours --- */
.parkings-resultat {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: .8rem .9rem;
    font-size: .9rem;
}
.liste-parkings { list-style: none; margin: 0 0 .2rem; padding: 0; }
.liste-parkings li { padding: .2rem 0; }
.lien-parking {
    background: none;
    border: none;
    padding: 0;
    color: var(--blue);
    font-weight: 600;
    text-align: left;
    text-decoration: underline;
    cursor: pointer;
}
.marker-emoji--proche {
    filter: drop-shadow(0 0 6px rgba(255,107,69,.9));
    transform: scale(1.1);
}
.marker-emoji--lie { opacity: .85; }

/* Une épingle sous alerte : un halo rouge qui bat lentement. Le
   battement ne sert pas à décorer — il sert à ce que l'œil s'y pose
   avant d'avoir lu quoi que ce soit. Il s'arrête pour qui a demandé
   moins d'animations (voir la règle « prefers-reduced-motion »). */
.marker-alerte {
    position: relative;
    filter: drop-shadow(0 0 4px rgba(192, 57, 43, .9)) drop-shadow(0 2px 2px rgba(0,0,0,.35));
    animation: alerte-battement 2.2s ease-in-out infinite;
}
@keyframes alerte-battement {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.12); }
}
@media (prefers-reduced-motion: reduce) {
    .marker-alerte { animation: none; }
}

/* --- Le bandeau d'alerte d'une fiche ---
   Il s'appuie sur les alertes Bootstrap (alert-danger / alert-warning),
   qui ont déjà leurs variantes sombres : il ne reste que la mise en
   page à écrire. */
.bandeau-alerte { border-left-width: 5px; }
.bandeau-alerte__titre {
    margin: 0;
    font-weight: 700;
    font-size: 1.02rem;
    display: flex;
    align-items: center;
    gap: .4rem;
}
.bandeau-alerte__motif { margin: .35rem 0 0; }
/* La ligne de provenance reste discrète, mais lisible : en thème
   sombre, une opacité plus basse la faisait disparaître dans le fond. */
.bandeau-alerte__source {
    margin: .4rem 0 0;
    font-size: .85rem;
    opacity: .95;
}

/* Une ligne d'alerte dans une liste de la page (pas dans une bulle) :
   là, le thème s'applique, donc on passe par un jeton. */
.texte-alerte { color: var(--alerte-texte); font-weight: 600; }

/* --- Chronomètre --- */
.bloc-chrono {
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: .9rem;
    background: var(--surface);
}
.chrono__chiffres {
    display: flex;
    gap: .5rem;
    text-align: center;
}
.chrono__chiffres > div {
    flex: 1;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: .5rem .2rem;
}
.chrono__valeur {
    display: block;
    font-family: var(--font-heading);
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--titre);
    font-variant-numeric: tabular-nums;
}
.chrono__libelle { display: block; font-size: .7rem; color: var(--muted); }
.chrono__gps { margin: .5rem 0 0; }

/* La ligne d'objectif : volontairement discrète, et sur une ligne à
   part. C'est une estimation du tracé, pas une de tes statistiques —
   la mettre à côté des trois chiffres reviendrait à la faire passer
   pour l'une d'elles. */
.chrono__objectif { font-variant-numeric: tabular-nums; }

/* --- La carte de la sortie en cours ---
   Une hauteur en `vh` plutôt qu'en pixels : sur un grand téléphone la
   carte respire, sur un petit elle ne mange pas les boutons
   « Abandonner » et « Terminer », qui doivent rester atteignables. */
.chrono__carte {
    height: 34vh;
    min-height: 180px;
    max-height: 340px;
    margin-bottom: .75rem;
    border: 1px solid var(--border);
    border-radius: 12px;
    overflow: hidden;
    background: var(--surface);
}
.chrono__recentrer {
    display: block;
    margin: -.4rem 0 .75rem auto;
    padding: .25rem .6rem;
    font-size: .78rem;
    color: var(--titre);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 999px;
}

/* Le point bleu : un disque plein, un anneau blanc pour le détacher du
   fond de carte, et un halo qui bat lentement — assez pour qu'on le
   trouve d'un coup d'œil, assez lent pour qu'on l'oublie. */
.chrono-carte-moi span {
    display: block;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #0f6fa8;
    border: 3px solid #fff;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .25);
    animation: chrono-carte-battement 2.4s ease-in-out infinite;
}
@keyframes chrono-carte-battement {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.18); }
}
@media (prefers-reduced-motion: reduce) {
    .chrono-carte-moi span { animation: none; }
}

/* Les pastilles de départ et d'arrivée du tracé. */
.chrono-carte-pastille span {
    display: block;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 3px solid #fff;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .25);
}
.chrono__arrivee {
    background: var(--reussi-fond);
    border: 1px solid #9ad9b3;
    color: var(--reussi-texte);
    border-radius: 10px;
    padding: .6rem .8rem;
    margin-bottom: .6rem;
    text-align: center;
    animation: pulsation 1.1s ease-in-out 3;
}
.bloc-chrono.est-arrive { border-color: var(--reussi-bord); background: var(--reussi-fond); }
@keyframes pulsation {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.03); }
}
@media (prefers-reduced-motion: reduce) {
    .chrono__arrivee { animation: none; }
}

/* --- Le panneau d'essai du chronomètre (administrateurs) ---
 *
 *  Replié par défaut, et visiblement à part : c'est un outil de
 *  vérification posé au milieu d'un écran qui sert, lui, à pagayer. Le
 *  fond hachuré dit « ceci n'est pas le site normal » sans avoir à
 *  l'écrire. */
.chrono-essai {
    border: 1px dashed var(--border);
    border-radius: 10px;
    padding: .5rem .75rem;
    background: repeating-linear-gradient(
        45deg, transparent, transparent 8px,
        rgba(127, 127, 127, .05) 8px, rgba(127, 127, 127, .05) 16px);
    font-size: .9rem;
}
.chrono-essai > summary {
    cursor: pointer;
    font-weight: 600;
    list-style: none;
}
.chrono-essai > summary::-webkit-details-marker { display: none; }
.chrono-essai > summary::before { content: '▸ '; }
.chrono-essai[open] > summary::before { content: '▾ '; }
.chrono-essai__corps { padding-top: .6rem; }

/* --- Ajouter un lieu : bloc parking --- */
.bloc-parking {
    border: 1px dashed var(--border);
    border-radius: 12px;
    padding: .9rem;
    background: var(--surface);
}
.bloc-parking legend { float: none; width: auto; font-size: 1rem; }
.picker-marker--parking {
    background: var(--blue-deep) !important;   /* bien distinct du marqueur du lieu (rouge) */
}
/* Un « P » lisible malgré la rotation de la goutte. */
.picker-marker--parking::after {
    content: 'P';
    transform: rotate(45deg);
    font-weight: 700;
    font-size: .85rem;
    line-height: 1;
}
#map.curseur-parking { cursor: crosshair; }

/* --- Accueil : les 3 points clés --- */
.hero__points {
    list-style: none;
    margin: 1.5rem 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem 1.5rem;
    color: #d7ecf5;
    font-size: .92rem;
}
/* Une PHRASE, pas deux colonnes.
   Ces éléments étaient des conteneurs flex : « <strong>Une fiche par
   lieu</strong>, créée et corrigée par les membres » se retrouvait donc
   coupé en deux blocs côte à côte — le gras se repliait sur deux lignes
   d'un côté, la suite de la phrase attendait de l'autre, séparée par un
   trou. Sur téléphone, c'était illisible.
   Le gras fait partie du texte : il doit couler avec lui. */
.hero__points li { display: block; }

/* --- Adaptations téléphone --- */
@media (max-width: 991.98px) {
    .reglages { grid-template-columns: 1fr; }
    .reglages__menu {
        position: static;
        flex-direction: row;
        overflow-x: auto;
        padding-bottom: .3rem;
        gap: .4rem;
    }
    .reglages__lien { white-space: nowrap; padding: .55rem .8rem; }

    /* Messagerie : une seule colonne à la fois */
    .messagerie { grid-template-columns: 1fr; min-height: 0; }
    .messagerie__liste { max-height: none; }
    .messagerie.est-ouverte .messagerie__liste { display: none; }
    .messagerie:not(.est-ouverte) .messagerie__fil { display: none; }
    .messagerie__fil { max-height: calc(100dvh - var(--navbar-height) - 7rem); min-height: 55vh; }
    .fil__saisie textarea { font-size: 1rem; }

    .menu-compte__pseudo { max-width: none; }
    .menu-compte .dropdown-menu { box-shadow: none; }
    .hero__points { font-size: .86rem; gap: .35rem 1rem; }
    .chrono__valeur { font-size: 1.5rem; }
    .bloc-chrono .btn { min-height: 50px; font-size: 1.05rem; }
}

/* --- Cartes « Mes parcours » --- */
.carte-parcours {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transition: transform .15s ease, box-shadow .15s ease;
}
.carte-parcours:hover { border-color: var(--blue-light); }
.carte-parcours__apercu {
    display: block;
    position: relative;
    background: linear-gradient(160deg, #e4f2f7, #f3f8f6 60%, var(--sand));
    border-bottom: 1px solid var(--border);
    padding: .4rem;
}
.apercu-parcours { display: block; width: 100%; height: 90px; }
.apercu-parcours--vide {
    height: 90px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--muted);
    font-size: .85rem;
}
.carte-parcours__compteur {
    position: absolute;
    top: .5rem; right: .5rem;
    background: var(--blue);
    color: #fff;
    font-weight: 700;
    font-size: .78rem;
    border-radius: 999px;
    padding: .12rem .55rem;
    box-shadow: 0 2px 8px rgba(11,61,85,.25);
}
.carte-parcours__corps { padding: .85rem 1rem 1rem; display: flex; flex-direction: column; flex: 1; }
.carte-parcours__chiffres {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem .9rem;
    font-size: .88rem;
    margin-bottom: .4rem;
}
.carte-parcours__chiffres strong { color: var(--titre); font-family: var(--font-heading); }
.carte-parcours__actions {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-top: auto;
}

/* ==========================================================
   Communauté : fil, classement, défis, badges, favoris,
   profils enrichis, découverte
   ========================================================== */

/* --- Fil d'activité --- */
.fil-activite { list-style: none; margin: 0; padding: 0; }
.fil-activite__ligne {
    display: flex;
    gap: .75rem;
    align-items: flex-start;
    padding: .75rem 0;
    border-top: 1px solid var(--border);
}
.fil-activite__ligne:first-child { border-top: none; padding-top: 0; }
.fil-activite__avatar { flex-shrink: 0; }
.fil-activite__texte { min-width: 0; line-height: 1.45; }
.fil-activite__date {
    display: block;
    font-size: .78rem;
    color: var(--muted);
    margin-top: .1rem;
}

/* --- Classement --- */
.classement { list-style: none; margin: 0; padding: 0; counter-reset: rang; }
.classement__ligne {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem 0;
    border-top: 1px solid var(--border);
}
.classement__ligne:first-child { border-top: none; }
.classement__ligne.est-moi {
    background: var(--surface-2);
    border-radius: 8px;
    padding-left: .4rem;
    padding-right: .4rem;
}
.classement__rang {
    flex-shrink: 0;
    width: 24px;
    text-align: center;
    font-weight: 700;
    font-size: .85rem;
    color: var(--muted);
}
.classement__rang--1 { color: #c9971b; }
.classement__rang--2 { color: #8f9ba3; }
.classement__rang--3 { color: #b5763c; }
.classement__nom { flex: 1; min-width: 0; }
.classement__nom a { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.classement__km { font-weight: 600; font-size: .9rem; white-space: nowrap; }
.classement--compact .classement__ligne { padding: .3rem 0; font-size: .88rem; }

/* --- Défis --- */
.carte-defi { transition: border-color .15s ease; }
.carte-defi.est-reussi { border-color: var(--reussi-bord); background: var(--reussi-fond); }
.carte-defi__emoji {
    font-size: 1.9rem;
    line-height: 1;
    flex-shrink: 0;
}
.defi-mini {
    display: flex;
    gap: .6rem;
    align-items: center;
    padding: .5rem 0;
    border-top: 1px solid var(--border);
    text-decoration: none;
}
.defi-mini:first-of-type { border-top: none; }
.defi-mini__emoji { font-size: 1.3rem; flex-shrink: 0; }
.defi-mini__corps { flex: 1; min-width: 0; }
.defi-mini__titre { display: block; font-weight: 600; font-size: .9rem; }
.defi-mini__barre { height: 5px; margin-top: .25rem; display: flex; }

/* --- Boutons favori / à faire --- */
.boutons-favoris {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin-bottom: 1rem;
}
.bouton-favori {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: .4rem .9rem;
    font-weight: 600;
    font-size: .9rem;
    color: var(--titre);
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, transform .1s ease;
}
.bouton-favori:hover { border-color: var(--blue-light); }
.bouton-favori:active { transform: scale(.97); }
.bouton-favori:disabled { opacity: .6; cursor: wait; }
.bouton-favori.est-actif {
    background: var(--alerte-fond);
    border-color: var(--accent);
    color: var(--accent-dark);
}
.bouton-favori__emoji { font-size: 1.05rem; filter: grayscale(1); opacity: .55; }
.bouton-favori.est-actif .bouton-favori__emoji { filter: none; opacity: 1; }
.bouton-favori__compteur {
    /* Fond codé en dur, donc toujours clair : le texte doit l'être
       aussi, sinon il disparaît en thème sombre. */
    color: #1c2b33;
    background: #eef4f7;
    border-radius: 999px;
    padding: 0 .45rem;
    font-size: .8rem;
    min-width: 1.5rem;
    text-align: center;
}
.bouton-favori.est-actif .bouton-favori__compteur { background: var(--alerte-fond); color: var(--alerte-texte); }

/* --- Profil enrichi --- */
.profil-entete { overflow: hidden; padding: 0; }
.profil-banniere {
    /* La hauteur vient du membre : les comptes Premium ont droit à une
       bannière plus haute (voir premium_banniere_hauteur). */
    height: var(--banniere-h, 170px);
    background-size: cover;
    background-position: center;
    background-color: var(--surface-2);
}
.profil-banniere--vide {
    background-image: linear-gradient(140deg, var(--blue-deep), var(--blue) 60%, var(--blue-light));
    height: 90px;
}
.profil-entete__corps { margin-top: -46px; }
.profil-entete__corps > .avatar { border-width: 4px; }
/* Seul l'avatar chevauche la bannière : le texte et les boutons redescendent. */
.profil-entete__corps > .flex-fill,
.profil-entete__corps > .text-end { margin-top: 46px; }
.apercu-banniere {
    display: block;
    width: 100%;
    max-height: 150px;
    object-fit: cover;
    border-radius: 10px;
    border: 1px solid var(--border);
}

.fiche-materiel { display: grid; grid-template-columns: auto 1fr; gap: .35rem 1rem; margin: 0; }
.fiche-materiel dt { color: var(--muted); font-weight: 500; font-size: .88rem; }
.fiche-materiel dd { margin: 0; font-weight: 600; font-size: .88rem; }

/* --- Galerie --- */
.galerie {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: .75rem;
}
.galerie__item {
    margin: 0;
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
    background: var(--surface);
}
.galerie__item img {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
}
.galerie__item figcaption {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .4rem .6rem;
    font-size: .8rem;
    color: var(--muted);
}
.galerie--profil .galerie__item figcaption { justify-content: center; }

/* --- Listes de spots --- */
.liste-spots { list-style: none; margin: 0; padding: 0; }
.liste-spots li {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .55rem 0;
    border-top: 1px solid var(--border);
}
.liste-spots li:first-child { border-top: none; }
.liste-spots__emoji { font-size: 1.3rem; flex-shrink: 0; }
.texte-coupe {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* --- Page Découvrir --- */
.carte-decouverte {
    height: 340px;
    border-radius: 12px;
    border: 1px solid var(--border);
    overflow: hidden;
}

/* --- Page À propos --- */
.liste-engagements { list-style: none; margin: 0; padding: 0; }
.liste-engagements li {
    padding: .6rem 0 .6rem 1.6rem;
    border-top: 1px solid var(--border);
    position: relative;
    font-size: .92rem;
}
.liste-engagements li:first-child { border-top: none; }
.liste-engagements li::before {
    content: '✓';
    position: absolute;
    left: 0;
    color: var(--green);
    font-weight: 700;
}

/* --- Pied de page --- */
.site-footer { border-top: 1px solid var(--border); background: var(--surface); }
.site-footer__marque {
    font-family: var(--font-heading);
    font-weight: 700;
    color: var(--titre);
    font-size: 1.05rem;
}
.site-footer__liens { list-style: none; margin: 0; padding: 0; }
.site-footer__liens li { padding: .15rem 0; }
.site-footer__liens a { color: var(--muted); text-decoration: none; font-size: .88rem; }
.site-footer__liens a:hover { color: var(--blue); text-decoration: underline; }

/* --- Adaptations téléphone --- */
@media (max-width: 991.98px) {
    .profil-banniere {
    /* La hauteur vient du membre : les comptes Premium ont droit à une
       bannière plus haute (voir premium_banniere_hauteur). */
    height: var(--banniere-h, 150px); height: 120px; }
    .profil-entete__corps { margin-top: -38px; }
    .profil-entete__corps > .flex-fill,
    .profil-entete__corps > .text-end { margin-top: 0; }
    .galerie { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
    .carte-decouverte { height: 260px; }
    .bouton-favori { flex: 1 1 auto; justify-content: center; min-height: 44px; }
    .fiche-materiel { grid-template-columns: 1fr; gap: 0 0; }
    .fiche-materiel dt { margin-top: .5rem; }
}

/* --- Bande « en ce moment » sous la carte d'accueil --- */
.bande-communaute { background: var(--surface); border-top: 1px solid var(--border); }
.bande-communaute .fil-activite__ligne { padding: .6rem 0; }

/* ==========================================================
   Interface mobile — inspirée des maquettes
   ==========================================================
   Trois idées reprises des captures :
     1. le chronomètre en carte blanche posée en bas de l'écran,
        avec de très gros chiffres et un bouton pleine largeur ;
     2. les défis en liste, chacun avec sa pastille ronde colorée
        et sa progression chiffrée à droite ;
     3. le profil en colonne : avatar, niveau, barre de progression,
        badges, puis les statistiques sur une seule ligne.
   ========================================================== */

/* --- Chronomètre : carte fixe en bas, façon application ---------- */
.chrono {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 1rem;
}
/* Quatre chiffres : distance, durée, vitesse du moment, vitesse moyenne.

   DEUX PAR DEUX SUR UN TÉLÉPHONE, quatre de front dès qu'il y a la place.
   Quatre colonnes sur 390 px donneraient moins de quatre-vingt-dix pixels
   par tuile : « 21.6 » tiendrait, « km/h en moyenne » non, et le libellé
   passerait sur trois lignes. Or c'est le libellé qui distingue l'instant
   de la moyenne — le tronquer rendrait les deux chiffres impossibles à
   départager. */
.chrono__chiffres {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: .5rem;
    text-align: center;
}
@media (min-width: 560px) {
    .chrono__chiffres { grid-template-columns: repeat(4, 1fr); }
}

/* La distance : le kilomètre en gros, les mètres en petit.

   Le coup d'œil donne l'ordre de grandeur — « 4 km » —, le détail reste
   lisible pour qui le cherche — « 237 m ». Tout écrire à la même taille
   donnerait « 4237 » qui ne se lit pas, et tout écrire en petit
   supprimerait le seul chiffre qu'on regarde en marchant.

   `font-variant-numeric: tabular-nums` sur le parent tient les colonnes :
   sans lui, le compteur qui avance ferait danser la ligne entière à
   chaque chiffre changé. */
/* Le pied de la fenêtre porte trois boutons au lieu de deux : ils
   passent à la ligne plutôt que de se comprimer, et « Pause » — le seul
   qu'on presse plusieurs fois par sortie — reste large sous le pouce. */
/* Le pied de la fenêtre, en deux étages : la pause au-dessus sur toute
   la largeur, les deux gestes irréversibles en dessous. */
.chrono__pied {
    display: block;
}
.chrono__pied-fin {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .5rem;
    margin-top: .5rem;
}
.chrono__pied-fin .btn { width: 100%; }
/* Le bouton de pause se voit sans crier : il est large et cliquable les
   mains mouillées, mais il ne dispute pas la vedette à « Terminer ». Un
   fond légèrement teinté et une bordure franche suffisent — au ras du
   fond du pied de fenêtre, il disparaissait. */
.btn-pause {
    width: 100%;
    background: rgba(15, 111, 168, .08);
    border: 1px solid rgba(15, 111, 168, .35);
    color: var(--titre);
    font-weight: 700;
    min-height: 48px;
    font-size: 1.05rem;
}
.btn-pause:hover, .btn-pause:focus-visible {
    background: rgba(15, 111, 168, .16);
    border-color: rgba(15, 111, 168, .55);
    color: var(--titre);
}
/* En pause, tout le panneau le dit : le bouton devient l'action de
   sortie de pause, et sa couleur tranche pour qu'on ne le cherche pas. */
.chrono--pause .btn-pause {
    background: #16794f;
    border-color: #16794f;
    color: #fff;
}
/* Et les chiffres passent en retrait : ils ne bougent plus, et une
   valeur figée qui garde l'air vivante fait douter de tout le reste. */
.chrono--pause .chrono__valeur { opacity: .55; }

.chrono__valeur--distance b { font-weight: 700; }
.chrono__valeur--distance i {
    font-style: normal;
    font-size: .52em;
    font-weight: 600;
    color: var(--muted);
    /* Collées à leur nombre : « 1 km 241 m » se lit comme deux blocs,
       pas comme quatre mots séparés. */
    margin-inline-start: -.12em;
}
.chrono__valeur {
    display: block;
    font-family: var(--font-heading);
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--titre);
    font-variant-numeric: tabular-nums;
}
.chrono__libelle {
    display: block;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--muted);
}
.chrono__arrivee {
    background: var(--reussi-fond);
    border: 1px solid #b7e2c4;
    color: var(--reussi-texte);
    border-radius: 12px;
    padding: .6rem .8rem;
    margin-bottom: .75rem;
    text-align: center;
}
.btn-terminer {
    display: block;
    width: 100%;
    margin-top: .9rem;
    min-height: 50px;
    border: none;
    border-radius: 999px;
    background: #12805a;
    color: #fff;
    font-weight: 700;
    font-size: 1.05rem;
    box-shadow: 0 4px 14px rgba(18, 128, 90, .3);
}
.btn-terminer:hover, .btn-terminer:focus { background: #0e6b4b; color: #fff; }

/* --- Défis en liste ---------------------------------------------- */
.defis-onglets { gap: .4rem; flex-wrap: nowrap; overflow-x: auto; padding-bottom: .25rem; }
.defis-onglets .nav-link {
    border-radius: 999px;
    padding: .4rem 1rem;
    font-size: .9rem;
    font-weight: 600;
    color: var(--titre);
    background: var(--surface-2);
    white-space: nowrap;
}
.defis-onglets .nav-link.active { background: var(--blue-deep); color: #fff; }

.defi-ligne {
    display: flex;
    align-items: center;
    gap: .85rem;
    padding: .85rem .25rem;
    border-top: 1px solid var(--border);
}
.defi-ligne:first-child { border-top: none; }
.defi-ligne__pastille {
    flex-shrink: 0;
    width: 44px; height: 44px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%;
    font-size: 1.25rem;
    background: var(--surface-2);
}
.defi-ligne.est-reussi .defi-ligne__pastille { background: var(--reussi-fond); }
.defi-ligne__corps { flex: 1 1 auto; min-width: 0; }
.defi-ligne__titre { font-weight: 600; line-height: 1.25; }
.defi-ligne__barre { height: 5px; border-radius: 999px; margin-top: .4rem; background: var(--surface-2); }
.defi-ligne__barre .progress-bar { border-radius: 999px; }
.defi-ligne__score {
    flex-shrink: 0;
    text-align: right;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--titre);
}
.defi-ligne__score .muted { font-weight: 400; }
.defi-ligne__coche { flex-shrink: 0; color: #12805a; font-size: 1.3rem; }

/* --- Les badges d'un profil --------------------------------------
   Plus de carte beige derrière chaque badge : ce fond parchemin
   venait d'une première version, jurait avec la charte, et surtout
   il entourait d'un rectangle des images qui portent DÉJÀ leur
   propre cadre. Deux encadrements pour un badge, c'en était un de
   trop. Le badge se suffit ; le titre se pose dessous. */
.badges-rangee { display: flex; flex-wrap: wrap; gap: .6rem; }
.badge-gagne {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: .35rem;
    width: 96px;
    padding: .4rem .2rem;
    border-radius: 12px;
    text-align: center;
    transition: transform .15s ease;
}
/* Un léger grossissement au survol : de quoi montrer que la bulle
   d'explication attend, sans que la rangée entière bouge. */
.badge-gagne:hover { transform: translateY(-2px); }
.badge-gagne__titre {
    font-size: .7rem;
    font-weight: 600;
    color: var(--muted);
    line-height: 1.2;
}

/* --- Fil d'activité ---------------------------------------------- */
.fil-activite { list-style: none; margin: 0; padding: 0; }
.fil-activite__ligne { display: flex; gap: .75rem; padding: .8rem 0; border-top: 1px solid var(--border); }
.fil-activite__ligne:first-child { border-top: none; }
.fil-activite__avatar { flex-shrink: 0; }
.fil-activite__texte { min-width: 0; line-height: 1.4; }
.fil-activite__date { display: block; font-size: .78rem; color: var(--muted); margin-top: .1rem; }

/* --- Classement --------------------------------------------------- */
.classement { list-style: none; margin: 0; padding: 0; counter-reset: rang; }
.classement__ligne { display: flex; align-items: center; gap: .6rem; padding: .5rem 0; border-top: 1px solid var(--border); }
.classement__ligne:first-child { border-top: none; }
.classement__ligne.est-moi { background: var(--surface-2); border-radius: 10px; padding-inline: .5rem; }
.classement__rang {
    flex-shrink: 0; width: 24px; height: 24px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%; font-size: .78rem; font-weight: 700;
    background: var(--surface-2); color: var(--titre);
}
.classement__rang--1 { background: #f6d879; color: #6b5200; }
.classement__rang--2 { background: #dfe4e8; color: #4a555c; }
.classement__rang--3 { background: #e9c39a; color: #6d4520; }
.classement__nom { flex: 1 1 auto; min-width: 0; line-height: 1.25; }
.classement__km { flex-shrink: 0; font-weight: 700; font-variant-numeric: tabular-nums; }
.classement--compact .classement__ligne { padding: .35rem 0; font-size: .9rem; }

/* --- Petits blocs partagés --------------------------------------- */
.defi-mini { display: flex; gap: .7rem; align-items: center; padding: .6rem 0; border-top: 1px solid var(--border); }
.defi-mini:first-of-type { border-top: none; }
.defi-mini__emoji { font-size: 1.3rem; }
.defi-mini__corps { flex: 1 1 auto; min-width: 0; }
.defi-mini__titre { display: block; font-weight: 600; font-size: .92rem; }
.defi-mini__barre { display: block; height: 5px; border-radius: 999px; background: var(--surface-2); margin-top: .3rem; }
.etat-emoji { font-size: 2.4rem; line-height: 1; margin-bottom: .5rem; }
.liste-spots { list-style: none; margin: 0; padding: 0; }
.liste-spots li { display: flex; align-items: center; gap: .6rem; padding: .6rem 0; border-top: 1px solid var(--border); }
.liste-spots li:first-child { border-top: none; }
.liste-spots__emoji { font-size: 1.3rem; flex-shrink: 0; }
.liste-engagements { padding-left: 1.1rem; }
.liste-engagements li { margin-bottom: .5rem; }
.liste-simple { list-style: none; margin: 0; padding: 0; }
.liste-simple li { padding: .5rem 0; border-top: 1px solid var(--border); }
.liste-simple li:first-child { border-top: none; }
.texte-coupe { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.carte-decouverte { height: 320px; border-radius: 14px; overflow: hidden; border: 1px solid var(--border); }
.carte-defi.est-reussi { border-color: var(--reussi-bord); background: var(--reussi-fond); }
.carte-defi__emoji { font-size: 1.8rem; line-height: 1; }
.bloc-miseeau { border-left: 3px solid var(--blue-light); }
.picker-marker--miseeau { background: var(--blue); }
.btn-demarrer { font-weight: 600; }

/* ==========================================================
   Téléphone : le chrono passe au premier plan
   ========================================================== */
@media (max-width: 991.98px) {

    /* Le chrono devient une carte posée en bas de l'écran, au-dessus
       de la feuille coulissante. Gros chiffres, bouton pleine largeur :
       tout doit être lisible et cliquable les mains mouillées. */
    body.chrono-en-cours .chrono:not(.hidden) {
        /* `fixed` et non `absolute` : la carte du chrono reste collée au
           bas de l'écran quoi qu'il arrive, même si la page défile ou si
           la barre d'adresse du téléphone se replie. */
        position: fixed;
        left: .6rem;
        right: .6rem;
        /* Deux déclarations : la seconde n'est appliquée que si le
           navigateur sait lire env(). Tout mettre dans un seul calc()
           rendrait la règle invalide là où env() n'existe pas — et la
           carte du chrono remonterait en haut de l'écran. */
        bottom: .6rem;
        bottom: calc(.6rem + env(safe-area-inset-bottom, 0px));
        z-index: 1200;
        border-radius: 20px;
        padding: 1rem 1rem 1.1rem;
        box-shadow: 0 -6px 24px rgba(11, 61, 85, .22);
    }
    body.chrono-en-cours .chrono__valeur { font-size: 2rem; }
    /* Pendant une sortie, le panneau de réglages disparaît complètement.
       On le masque plutôt que de le faire glisser hors cadre : un simple
       translate reste affiché si un ancêtre ne le rogne pas, et on se
       retrouve avec le formulaire visible sous la carte. */
    body.chrono-en-cours .sidebar { display: none; }
    body.chrono-en-cours .map-page .leaflet-bottom { bottom: 0; }

    .chrono__chiffres { gap: .25rem; }
    .carte-decouverte { height: 260px; }

    .defi-ligne__pastille { width: 40px; height: 40px; font-size: 1.15rem; }
    .badge-gagne { width: 84px; }
}

/* ==========================================================
   Bouton clair / sombre
   ========================================================== */
.bouton-theme {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, .28);
    background: rgba(255, 255, 255, .12);
    color: #fff;
    padding: 0;
    flex-shrink: 0;
    transition: background .15s ease;
}
.bouton-theme:hover { background: rgba(255, 255, 255, .22); color: #fff; }
.bouton-theme svg { width: 19px; height: 19px; }

/* Une seule des deux icônes est visible, selon le thème actif. */
.bouton-theme .icone-lune { display: block; }
.bouton-theme .icone-soleil { display: none; }
:root[data-theme="sombre"] .bouton-theme .icone-lune { display: none; }
:root[data-theme="sombre"] .bouton-theme .icone-soleil { display: block; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) .bouton-theme .icone-lune { display: none; }
    :root:not([data-theme="clair"]) .bouton-theme .icone-soleil { display: block; }
}

/* ==========================================================
   Étapes du panneau de la carte
   ========================================================== */
.etape {
    padding: 1rem 0;
    border-bottom: 1px solid var(--border);
}
.etape:last-child { border-bottom: none; }
.etape--discrete { padding-top: .75rem; }
.etape__titre {
    display: flex;
    align-items: center;
    gap: .55rem;
    font-size: 1rem;
    font-weight: 700;
    margin: 0 0 .6rem;
    color: var(--text);
}
.etape__num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px; height: 24px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--blue);
    color: #fff;
    font-size: .82rem;
    font-weight: 700;
}
.etape__plus summary {
    cursor: pointer;
    font-size: .86rem;
    color: var(--muted);
    list-style: none;
}
.etape__plus summary::-webkit-details-marker { display: none; }
.etape__plus summary::before { content: '▸ '; }
.etape__plus[open] summary::before { content: '▾ '; }

/* ==========================================================
   Barre de tracé, posée sur la carte
   ========================================================== */
.trace-barre {
    position: absolute;
    top: .75rem;
    left: .75rem;
    right: .75rem;
    z-index: 1150;
    background: rgba(11, 61, 85, .94);
    color: #fff;
    border-radius: 14px;
    padding: .8rem 1rem .9rem;
    box-shadow: 0 6px 22px rgba(0, 0, 0, .25);
    text-align: center;
}
.trace-barre__consigne { margin: 0 0 .15rem; font-weight: 600; line-height: 1.3; }
.trace-barre__compteur {
    margin: 0 0 .6rem;
    font-size: .88rem;
    color: #bcdbe8;
    font-variant-numeric: tabular-nums;
    min-height: 1.2em;
}
.trace-barre__actions { display: flex; gap: .4rem; justify-content: center; flex-wrap: wrap; }
.trace-barre .btn-outline-light:disabled { opacity: .45; }
.btn-clair {
    background: #fff;
    color: var(--titre);
    font-weight: 700;
}
.btn-clair:hover:not(:disabled), .btn-clair:focus:not(:disabled) { background: #e9f4f9; color: var(--titre); }
.btn-clair:disabled { background: rgba(255,255,255,.35); color: rgba(11,61,85,.55); }

/* Sur ordinateur la barre ne couvre que la carte, pas le panneau. */
@media (min-width: 992px) {
    .trace-barre { left: calc(340px + .75rem); }
}

/* Pendant le tracé, les commandes de zoom descendent sous la barre :
   sinon elles se retrouvent cachées derrière elle. */
body.en-trace .map-page .leaflet-top { top: 10.5rem; }
@media (min-width: 992px) {
    body.en-trace .map-page .leaflet-top { top: 8rem; }
}

/* ==========================================================
   Thème sombre : quelques retouches ciblées
   ========================================================== */
:root[data-theme="sombre"] .site-navbar,
:root[data-theme="sombre"] .hero { background: var(--marine); }
:root[data-theme="sombre"] .admin-card { background: var(--surface-2); border-color: var(--border); }
:root[data-theme="sombre"] .table { --bs-table-color: var(--text); --bs-table-bg: transparent; }
:root[data-theme="sombre"] .form-control,
:root[data-theme="sombre"] .form-select {
    background-color: var(--surface-2);
    border-color: var(--border);
    color: var(--text);
}
:root[data-theme="sombre"] .form-control::placeholder { color: #7f97a4; }
:root[data-theme="sombre"] .modal-content,
:root[data-theme="sombre"] .dropdown-menu { background: var(--surface); color: var(--text); border-color: var(--border); }
:root[data-theme="sombre"] .dropdown-item { color: var(--text); }
:root[data-theme="sombre"] .dropdown-item:hover { background: var(--surface-2); color: var(--text); }
:root[data-theme="sombre"] .bg-light { background: var(--surface-2) !important; color: var(--text); }
:root[data-theme="sombre"] .text-bg-light { background: var(--surface-2) !important; color: var(--text) !important; }
/* Les onglets inactifs se lisaient à peine : bleu foncé sur fond foncé. */
:root[data-theme="sombre"] .defis-onglets .nav-link { color: var(--text); }
:root[data-theme="sombre"] .defis-onglets .nav-link.active { background: var(--blue); color: #fff; }
:root[data-theme="sombre"] .btn-outline-secondary { color: var(--text); border-color: var(--border); }
:root[data-theme="sombre"] .btn-outline-secondary:hover { background: var(--surface-2); color: var(--text); }
/* Les tuiles de carte sont conçues pour un fond clair : on les
   adoucit un peu la nuit, sans les rendre illisibles. */
:root[data-theme="sombre"] .leaflet-tile-pane { filter: brightness(.82) saturate(.9); }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) .site-navbar,
    :root:not([data-theme="clair"]) .hero { background: var(--marine); }
    :root:not([data-theme="clair"]) .admin-card { background: var(--surface-2); border-color: var(--border); }
    :root:not([data-theme="clair"]) .form-control,
    :root:not([data-theme="clair"]) .form-select {
        background-color: var(--surface-2);
        border-color: var(--border);
        color: var(--text);
    }
    :root:not([data-theme="clair"]) .modal-content,
    :root:not([data-theme="clair"]) .dropdown-menu { background: var(--surface); color: var(--text); border-color: var(--border); }
    :root:not([data-theme="clair"]) .dropdown-item { color: var(--text); }
    :root:not([data-theme="clair"]) .bg-light { background: var(--surface-2) !important; color: var(--text); }
    :root:not([data-theme="clair"]) .text-bg-light { background: var(--surface-2) !important; color: var(--text) !important; }
    :root:not([data-theme="clair"]) .leaflet-tile-pane { filter: brightness(.82) saturate(.9); }
    :root:not([data-theme="clair"]) .defis-onglets .nav-link { color: var(--text); }
    :root:not([data-theme="clair"]) .defis-onglets .nav-link.active { background: var(--blue); color: #fff; }
    :root:not([data-theme="clair"]) .btn-outline-secondary { color: var(--text); border-color: var(--border); }
    :root:not([data-theme="clair"]) .btn-outline-secondary:hover { background: var(--surface-2); color: var(--text); }
}

/* ==========================================================
   Badges dessinés
   ========================================================== */

/* Le mur de badges : ce qui est gagné en couleur, le reste en creux */
.mur-badges {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 1rem .5rem;
}
.badge-case {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .35rem;
    margin: 0;
    text-align: center;
}
.badge-case.est-verrouille { opacity: .62; }
.badge-case__titre {
    display: block;
    font-size: .74rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--text);
}
.badge-case__aide {
    display: block;
    font-size: .68rem;
    color: var(--muted);
    line-height: 1.25;
}

/* En-tête de la page Défis */
.defis-entete {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}
.defis-entete__chiffres { display: flex; gap: 1.5rem; }
.defis-entete__chiffre {
    text-align: center;
    font-family: var(--font-heading);
    font-size: 1.5rem;
    line-height: 1.1;
    color: var(--text);
}
.defis-entete__chiffre .muted { font-size: 1.1rem; }
.defis-entete__chiffre .small { font-family: var(--font-body); font-size: .72rem; font-weight: 400; }

/* Choix d'icône et de couleur, côté administration */
.choix-icones { display: flex; flex-wrap: wrap; gap: .4rem; }
.choix-icone { cursor: pointer; border-radius: 10px; padding: 3px; border: 2px solid transparent; }
.choix-icone input { position: absolute; opacity: 0; width: 0; height: 0; }
.choix-icone:hover { background: var(--surface-2); }
.choix-icone:has(input:checked) { border-color: var(--blue); background: var(--surface-2); }

.choix-couleurs { display: flex; flex-wrap: wrap; gap: .45rem; }
.choix-couleur { cursor: pointer; border-radius: 50%; padding: 3px; border: 2px solid transparent; line-height: 0; }
.choix-couleur input { position: absolute; opacity: 0; width: 0; height: 0; }
.choix-couleur .pastille { display: block; width: 26px; height: 26px; border-radius: 50%; }
.choix-couleur:has(input:checked) { border-color: var(--text); }

.badge-admin {
    display: flex;
    align-items: center;
    gap: .9rem;
    padding: .8rem 0;
    border-top: 1px solid var(--border);
}
.badge-admin:first-of-type { border-top: none; }
.badge-admin__corps { flex: 1 1 auto; min-width: 0; }
.badge-admin__actions { display: flex; flex-wrap: wrap; gap: .35rem; flex-shrink: 0; }
.bloc-modif { background: var(--surface-2); }

@media (max-width: 575.98px) {
    .badge-admin { flex-wrap: wrap; }
    .badge-admin__actions { width: 100%; }
    .mur-badges { grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); }
}

/* ==========================================================
   Page « Créer un parcours »
   ==========================================================
   Ordinateur : panneau à gauche, carte à droite.
   Téléphone : la carte prend tout, et une barre en bas
   regroupe chiffres et actions — gros boutons, rien à viser.
   ========================================================== */
.createur {
    display: flex;
    height: calc(100vh - var(--navbar-height));
    min-height: 520px;
}
.createur__panneau {
    width: 340px;
    flex-shrink: 0;
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.createur__entete {
    padding: 1.1rem 1.25rem;
    border-bottom: 1px solid var(--border);
}
.createur__corps { overflow-y: auto; padding: 0 1.25rem; flex: 1 1 auto; }
.createur__bloc { padding: 1.1rem 0; border-bottom: 1px solid var(--border); }
.createur__bloc--fin { border-bottom: none; }

.createur__chiffres {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .4rem;
    text-align: center;
}
.createur__valeur {
    display: block;
    font-family: var(--font-heading);
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.createur__libelle {
    display: block;
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--muted);
}

.createur__carte { position: relative; flex: 1 1 auto; min-width: 0; }
#cp-map { position: absolute; inset: 0; background: var(--surface-2); }

/* La consigne, posée en haut de la carte */
.createur__consigne {
    position: absolute;
    top: .75rem; left: .75rem; right: .75rem;
    z-index: 1100;
    display: flex;
    align-items: center;
    gap: .5rem;
    background: rgba(11, 61, 85, .94);
    color: #fff;
    border-radius: 12px;
    padding: .6rem .5rem .6rem 1rem;
    box-shadow: 0 4px 18px rgba(0, 0, 0, .22);
    font-weight: 600;
    line-height: 1.3;
}
.createur__fermer {
    border: none;
    background: transparent;
    color: #fff;
    font-size: 1.4rem;
    line-height: 1;
    padding: 0 .5rem;
    flex-shrink: 0;
    opacity: .8;
}
.createur__fermer:hover { opacity: 1; }

/* Points du tracé : départ et arrivée se repèrent d'un coup d'œil */
.waypoint-marker--depart { background: #12805a; }
.waypoint-marker--arrivee { background: var(--accent); }

.liste-parkings { list-style: none; margin: .25rem 0 .5rem; padding: 0; font-size: .85rem; }
.liste-parkings li { display: flex; justify-content: space-between; gap: .5rem; padding: .2rem 0; }

/* La barre du bas n'existe que sur téléphone */
.createur__barre { display: none; }

@media (max-width: 991.98px) {
    .createur { display: block; position: relative; height: calc(100dvh - var(--navbar-height)); }
    .createur__panneau { display: none; }
    .createur__carte { position: absolute; inset: 0; }

    /* ==========================================================
       LA BARRE DU BAS : aussi discrète qu'elle peut l'être
       ==========================================================
       ⚠️ ELLE PRENAIT LE TIERS DE L'ÉCRAN, et on trace un parcours
       EN REGARDANT LA CARTE. Chaque pixel qu'elle occupe est un
       pixel de rivière en moins.

       Trois économies, dans l'ordre de ce qu'elles rapportent :
       les réglages se replient derrière une pastille (on les
       touche une fois par parcours, la carte tout le temps), les
       chiffres passent sur une ligne au lieu de trois colonnes en
       gros, et tout le reste se resserre. */
    .createur__barre {
        display: block;
        position: absolute;
        left: .5rem; right: .5rem;
        bottom: calc(.5rem + env(safe-area-inset-bottom, 0px));
        z-index: 1200;
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: 14px;
        padding: .5rem .6rem .55rem;
        box-shadow: 0 -4px 18px rgba(11, 61, 85, .18);
    }

    /* Les chiffres et la pastille sur la même ligne : c'est cette
       ligne-là, à elle seule, qui remplace l'ancien pavé. */
    .createur__barre-haut {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: .5rem;
        margin-bottom: .5rem;
    }
    .createur__barre-chiffres {
        display: flex;
        gap: .7rem;
        font-size: .82rem;
        color: var(--muted);
        white-space: nowrap;
    }
    .createur__barre-chiffres strong {
        font-size: 1.05rem;
        color: var(--text);
        font-weight: 700;
    }

    /* La pastille des réglages. Elle montre en permanence ce qui est
       choisi — objectif et allure — pour qu'on n'ait pas à l'ouvrir
       juste pour vérifier. */
    .createur__reglages {
        display: inline-flex;
        align-items: center;
        gap: .25rem;
        flex: 0 0 auto;
        border: 1px solid var(--border);
        background: transparent;
        color: var(--text);
        border-radius: 999px;
        padding: .25rem .6rem;
        font-size: .78rem;
        line-height: 1.2;
    }
    .createur__chevron {
        display: inline-block;
        font-size: .7rem;
        transition: transform .15s ease;
    }
    .createur__reglages[aria-expanded="false"] .createur__chevron {
        transform: rotate(180deg);
    }

    .createur__barre-reglages {
        margin-bottom: .5rem;
    }
    .createur__barre-reglages label {
        display: block;
        font-size: .75rem;
        color: var(--muted);
        margin-bottom: 0;
    }
    .createur__barre-reglages strong { color: var(--text); }
    .createur__barre-reglages .form-range { margin: 0; }
    .createur__barre-actions { display: flex; gap: .4rem; }
    .createur__barre-actions .btn {
        min-height: 40px;
        font-size: .875rem;
        padding-inline: .5rem;
    }

    /* La consigne remonte au-dessus des commandes de zoom */
    .createur__carte .leaflet-top { top: 4.2rem; }
    .createur__carte .leaflet-bottom { bottom: 8.5rem; }

    /* ==========================================================
       QUAND UNE SORTIE EST EN COURS, LA BARRE REMONTE
       ==========================================================
       Le bandeau « Sortie en cours » est fixé en bas de l'écran et
       passe par-dessus tout. Il recouvrait « Annuler / Parkings /
       Enregistrer » : trois boutons rendus intouchables parce
       qu'on avait un chronomètre qui tournait.

       Le cas est rare — tracer un parcours pendant une sortie —
       mais il ne coûte qu'une règle. `:has()` évite d'avoir à
       poser une classe sur <body> depuis PHP : là où il n'est pas
       reconnu, rien ne change et on retombe sur l'état d'avant. */
    body:has(.sortie-bandeau) .createur__barre {
        bottom: calc(4rem + env(safe-area-inset-bottom, 0px));
    }
    body:has(.sortie-bandeau) .createur__carte .leaflet-bottom { bottom: 12rem; }
}

/* Bandeau d'un parcours ouvert sur la carte d'accueil */
.parcours-ouvert {
    position: absolute;
    left: .75rem; right: .75rem; bottom: .75rem;
    z-index: 1150;
    display: flex;
    align-items: center;
    gap: 1rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: .85rem 1rem;
    box-shadow: 0 -4px 20px rgba(11, 61, 85, .18);
}
.parcours-ouvert__infos { flex: 1 1 auto; min-width: 0; line-height: 1.3; }
.parcours-ouvert .btn { flex-shrink: 0; min-height: 46px; }

@media (min-width: 992px) {
    .parcours-ouvert { left: calc(340px + .75rem); max-width: 520px; }
}
@media (max-width: 991.98px) {
    .parcours-ouvert {
        bottom: calc(4.4rem + env(safe-area-inset-bottom, 0px));
        flex-direction: column;
        align-items: stretch;
        gap: .6rem;
        text-align: center;
    }
    .parcours-ouvert .btn { width: 100%; }
}

/* Le badge d'un défi, dans la liste */
.defi-ligne__badge { flex-shrink: 0; line-height: 0; }
.defi-mini__emoji { line-height: 0; flex-shrink: 0; }

/* ==========================================================
   Infobulle des badges
   ==========================================================
   `title` seul est lent à apparaître et invisible au doigt.
   Cette bulle-ci s'affiche au survol, au clavier (focus) et
   à l'appui, et reste lisible en thème sombre.
   ========================================================== */
.badge-case { position: relative; cursor: help; }
.badge-case:focus { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 8px; }

/*  ⚠️ LA BULLE DES BADGES N'EST PLUS DESSINÉE ICI, ET C'ÉTAIT LE BUG.
 *
 *  Il y avait DEUX bulles pour un seul badge : celle-ci, faite d'un
 *  pseudo-élément collé au badge, et la bulle flottante commune
 *  (#bulle-flottante, js/interface.js). Les deux s'affichaient en même
 *  temps. Sur ordinateur cela passait inaperçu — elles se superposaient.
 *  Sur téléphone, non : le pseudo-élément est positionné par rapport au
 *  badge, sans aucune notion de bord d'écran, si bien qu'un badge de la
 *  colonne de droite envoyait sa bulle hors de l'écran, coupée, pendant
 *  que la vraie s'affichait ailleurs.
 *
 *  Une seule bulle reste : la flottante. Elle est posée en coordonnées
 *  d'écran et se recale toute seule pour rester visible, quel que soit
 *  le badge touché et quelle que soit la largeur de l'appareil.
 */

/* Émoji d'une notification */
.notif-emoji { font-size: 1.15rem; line-height: 1.3; flex-shrink: 0; }

/* ==========================================================
   Captcha
   ========================================================== */
.captcha {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: .5rem;
}
.captcha__image {
    display: block;
    border-radius: 10px;
    border: 1px solid var(--border);
    max-width: 100%;
    height: auto;
    /* L'image est dessinée sur fond clair : en thème sombre on
       l'entoure de blanc plutôt que de l'assombrir, sinon le code
       devient illisible. */
    background: #fff;
}
.captcha__recharger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--muted);
    padding: 0;
    transition: color .15s ease, border-color .15s ease;
}
.captcha__recharger:hover { color: var(--blue); border-color: var(--blue); }
.captcha__recharger svg { width: 18px; height: 18px; }
.captcha__champ {
    letter-spacing: .18em;
    font-weight: 600;
    text-transform: uppercase;
    max-width: 260px;
}
.captcha__champ::placeholder { letter-spacing: normal; font-weight: 400; text-transform: none; }

/* Icône personnalisée dans la pastille d'un grade */
.grade-badge__image { vertical-align: -3px; border-radius: 3px; }

/* ==========================================================
   La page d'un parcours (view-parcours.php)
   ========================================================== */
.vue-parcours__carte {
    height: min(70vh, 620px);
    min-height: 340px;
    width: 100%;
}
/* Les outils de la carte, dans son pied plutôt que sous elle : posés
   dehors, ils avaient l'air de flotter entre deux blocs. */
.vue-parcours__outils {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    padding: .7rem .9rem;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
}

.vue-parcours__entete {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}
.vue-parcours__identite {
    display: flex;
    align-items: center;
    gap: .85rem;
    min-width: 0;
}

/* Une case par chiffre, en grille : en ligne libre, « 73 h 50 » venait
   coller son voisin et le dernier chiffre touchait le bord. */
.vue-parcours__chiffres {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: .75rem;
}
.vue-parcours__chiffre {
    text-align: center;
    padding: .85rem .6rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}
.vue-parcours__valeur {
    display: block;
    font-family: var(--font-heading);
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--titre);
    font-variant-numeric: tabular-nums;
}
.vue-parcours__libelle {
    display: block;
    margin-top: .15rem;
    font-size: .75rem;
    color: var(--muted);
}

/* Le panneau suit la carte pendant le défilement : sans ça, la moitié
   droite de la page se vidait dès qu'on descendait. */
.vue-parcours__panneau { position: sticky; top: 84px; }

.vue-parcours__faits { list-style: none; margin: 0; padding: 0; }
.vue-parcours__faits li {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .75rem;
    padding: .4rem 0;
    border-bottom: 1px dashed var(--border);
}
.vue-parcours__faits li:last-child { border-bottom: 0; }
.vue-parcours__fait-cle { font-size: .82rem; color: var(--muted); }
.vue-parcours__fait-val { font-weight: 600; color: var(--titre); text-align: right; }

@media (max-width: 991.98px) {
    .vue-parcours__carte { height: 55vh; }
    .vue-parcours__panneau { position: static; }
}

/* Bandeau « la carte est tenue par la communauté » (accueil) */
.bande-contribuer {
    background: var(--surface);
    border-top: 1px solid var(--border);
}
.bande-contribuer p { color: var(--muted); }
.bande-contribuer p strong { color: var(--text); }

/* Bouton « copier » (adresse d'une fiche, coordonnées GPS…) */
.btn-copier {
    background: none;
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--muted);
    font-size: .75rem;
    line-height: 1;
    padding: .2rem .4rem;
    margin-left: .4rem;
    cursor: pointer;
    white-space: nowrap;
    vertical-align: middle;
    transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.btn-copier:hover { color: var(--blue); border-color: var(--blue); }
.btn-copier.est-copie {
    color: #fff;
    background: var(--green, #198754);
    border-color: var(--green, #198754);
}
.copiable__texte { vertical-align: middle; }

/* ==========================================================
   Propositions sous un champ (js/autocomplete.js)
   ========================================================== */
.autocomplete { position: relative; flex: 1 1 auto; }
.autocomplete__liste {
    position: absolute;
    z-index: 1200;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    margin: 0;
    padding: .25rem;
    list-style: none;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 10px 28px rgba(0, 0, 0, .16);
    max-height: 280px;
    overflow-y: auto;
}
.autocomplete__item {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    padding: .4rem .55rem;
    border-radius: 7px;
    cursor: pointer;
    font-size: .875rem;
}
.autocomplete__item.est-actif { background: var(--surface-2, rgba(13, 110, 253, .08)); }
.autocomplete__label { font-weight: 600; color: var(--text); }
.autocomplete__detail {
    color: var(--muted);
    font-size: .78rem;
    margin-left: auto;
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 55%;
}
.autocomplete__source { color: var(--blue); font-size: .6rem; }

/* Quand le champ vit déjà dans un input-group, c'est le groupe
   lui-même qui porte la liste : rien d'autre à corriger. */
.autocomplete--groupe { position: relative; }

/* ==========================================================
   Régler le cadrage d'une image (js/cadrage.js)
   ==========================================================
   L'aperçu a exactement la forme de l'affichage final : rond
   pour la photo, très large pour la bannière. Ce qu'on voit
   ici est ce qui sera montré, sans surprise après coup.
   ========================================================== */
.cadreur-bloc { text-align: center; }
.cadreur {
    position: relative;
    overflow: hidden;
    background: var(--surface-2);
    border: 1px solid var(--border);
    cursor: grab;
    touch-action: none;
    user-select: none;
}
.cadreur:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.cadreur.est-attrape { cursor: grabbing; }
.cadreur__image {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: 50% 50%;
    background-repeat: no-repeat;
}
.cadreur--rond {
    width: 110px;
    height: 110px;
    border-radius: 50%;
    border-width: 2px;
}
.cadreur--banniere {
    width: 100%;
    /* Exactement la règle du haut du profil (.profil-banniere) : même
       hauteur, même « cover ». Ce qu'on cadre ici est ce qui s'affichera. */
    height: 170px;
    border-radius: 10px;
}
.cadreur__consigne {
    position: absolute;
    left: 50%;
    bottom: .5rem;
    transform: translateX(-50%);
    background: rgba(0, 0, 0, .55);
    color: #fff;
    font-size: .72rem;
    padding: .15rem .5rem;
    border-radius: 20px;
    pointer-events: none;
    opacity: .9;
}
/* Sans image, il n'y a rien à recadrer : on le dit au lieu de
   laisser un rectangle gris énigmatique. */
.cadreur--vide { cursor: default; }
.cadreur--vide .cadreur__image {
    background-image: linear-gradient(140deg, var(--blue-deep), var(--blue) 60%, var(--blue-light));
}
.cadreur--vide .cadreur__consigne::after { content: ' (choisis d’abord une image)'; }

/* ==========================================================
   Écran « Créer » : le carrefour
   ==========================================================
   Deux grandes cartes cliquables plutôt que deux boutons muets.
   Chacune dit ce qu'elle fait et à qui ça sert : sur un écran
   de choix, le libellé seul ne suffit jamais.
   ========================================================== */
/* La colonne : la carte prend la hauteur disponible, le rail de
   raccourcis reste collé dessous. Sans cette enveloppe, une carte
   en height:100% s'étirait par-dessus son propre rail. */
.choix-bloc { display: flex; flex-direction: column; height: 100%; }
.choix-bloc > .carte-choix { flex: 1 1 auto; }

.carte-choix {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 1.15rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 18px;
    box-shadow: 0 1px 2px var(--ombre);
    text-decoration: none;
    color: var(--text);
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.carte-choix:hover,
.carte-choix:focus-visible {
    transform: translateY(-2px);
    border-color: var(--blue);
    box-shadow: 0 10px 26px rgba(11, 61, 85, .12);
    color: var(--text);
}
.carte-choix:active { transform: none; }

.carte-choix__icone {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 54px;
    height: 54px;
    border-radius: 16px;
    font-size: 1.7rem;
    line-height: 1;
}
.carte-choix__icone--lieu     { background: rgba(255, 107, 69, .14); }
.carte-choix__icone--parcours { background: rgba(15, 111, 168, .14); }

.carte-choix__corps { flex: 1 1 auto; min-width: 0; }
.carte-choix__titre {
    display: block;
    font-family: var(--font-heading);
    font-size: 1.12rem;
    font-weight: 700;
    margin-bottom: .3rem;
}
.carte-choix__texte {
    display: block;
    color: var(--muted);
    font-size: .9rem;
    line-height: 1.45;
}
.carte-choix__pied {
    display: block;
    margin-top: .6rem;
    font-size: .82rem;
    color: var(--blue);
    font-weight: 600;
}
.carte-choix__lien { text-decoration: underline; }

.carte-choix__fleche {
    flex-shrink: 0;
    align-self: center;
    color: var(--muted);
    opacity: .6;
}
.carte-choix__fleche svg { width: 20px; height: 20px; display: block; }

/* Les raccourcis vers un type précis */
.puce-choix {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .45rem .8rem;
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text);
    font-size: .85rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    border: 1px solid transparent;
    transition: border-color .15s ease, color .15s ease;
}
.puce-choix:hover, .puce-choix:focus-visible { border-color: var(--blue); color: var(--blue); }

/* Sur ordinateur, le rail n'est qu'une simple ligne de puces. */
.ecran-creer .rail { flex-wrap: wrap; margin-inline: 0; padding-inline: 0; }

/* Une notification non lue se repère à sa barre bleue, pas seulement
   à une nuance de fond : la couleur seule ne suffit pas. */
.liste-app__ligne.est-non-lue { background: rgba(15, 111, 168, .06); }
.liste-app__ligne.est-non-lue .liste-app__lien { border-left: 3px solid var(--blue); }
.liste-app__ligne.est-non-lue .liste-app__titre { font-weight: 700; }
/* Le texte d'une notification peut être long : il passe à la ligne
   plutôt que d'être coupé au milieu d'un mot. */
.notif-texte { white-space: normal !important; overflow: visible !important; }

/* ==========================================================
   Bouton « Continuer avec Google »
   ==========================================================
   Le logo garde ses quatre couleurs officielles : Google
   demande qu'il ne soit ni recoloré ni déformé, d'où les
   codes en dur dans le SVG plutôt que des variables de thème.
   Le bouton, lui, suit le thème du site.
   ========================================================== */
.ou-google { margin-bottom: 1.25rem; }

.btn-google {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .65rem;
    width: 100%;
    min-height: 48px;
    padding: .6rem 1rem;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
    color: var(--text);
    font-weight: 600;
    font-size: .98rem;
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.btn-google:hover,
.btn-google:focus-visible {
    border-color: var(--blue);
    box-shadow: 0 2px 10px rgba(11, 61, 85, .1);
    color: var(--text);
}
.btn-google svg { width: 20px; height: 20px; flex-shrink: 0; }

/* Le séparateur « ou » : un trait de chaque côté du mot. */
.ou-google__separateur {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-top: 1.1rem;
    color: var(--muted);
    font-size: .82rem;
}
.ou-google__separateur::before,
.ou-google__separateur::after {
    content: '';
    flex: 1 1 auto;
    height: 1px;
    background: var(--border);
}

/* ==========================================================
   Lisibilité : les cas où un texte passait sur un fond proche
   ==========================================================
   Bootstrap donne à .btn-primary une couleur de texte calculée
   à partir du thème. Dans une bulle de carte — fond clair même
   en thème sombre — elle retombait sur un bleu à peine
   distinguable du bouton. On tranche : sur un aplat bleu, le
   texte est blanc, point.
   ========================================================== */
.leaflet-popup-content .btn-primary,
.leaflet-popup-content .btn-primary:hover,
.leaflet-popup-content .btn-primary:focus,
.spot-popup .btn-primary,
.btn-primary, .btn-success, .btn-danger, .btn-terminer,
.btn-cta {
    color: #fff !important;
}
.btn-outline-primary { color: var(--blue) !important; }
.btn-outline-primary:hover, .btn-outline-primary:focus { color: #fff !important; }

/* Les bulles de carte gardent un fond clair : Leaflet les dessine
   au-dessus de la carte, qui reste claire même en thème sombre.
   Sans ça, le texte passait en blanc sur blanc. */
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
    background: #fff;
    color: #1c2b33;
}
.leaflet-popup-content h3,
.leaflet-popup-content .spot-popup h3 { color: #0b203c; }
.leaflet-popup-content .muted { color: #5c7382 !important; }
.leaflet-popup-content a:not(.btn) { color: #0f6fa8; }

/* Idem pour les infobulles posées sur la carte. */
.leaflet-tooltip { color: #1c2b33; }

/* ==========================================================
   REFONTE BUREAUTIQUE — direction artistique RidePaddle
   ==========================================================
   Ce bloc vient APRÈS le reste de la feuille : il a donc le
   dernier mot sans qu'on ait eu à réécrire l'existant, et la
   couche téléphone (css/mobile.css) garde le sien puisqu'elle
   est chargée ensuite.

   Trois principes, tirés du logo :
     - le marine porte, le bleu vif signale ;
     - tout ce qui sépare est une vague, jamais un trait droit ;
     - les surfaces sont blanches et posées, avec une ombre
       basse et large plutôt qu'un contour marqué.
   ========================================================== */

/* --- La marque dans la barre ------------------------------- */
.site-navbar {
    background: linear-gradient(100deg, var(--marine) 0%, var(--marine-2) 100%);
    border-bottom: 1px solid rgba(255, 255, 255, .07);
    box-shadow: 0 2px 18px rgba(11, 32, 60, .18);
}
.marque {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    padding-block: .1rem;
}
.marque__signe {
    height: 28px;
    width: auto;
    /* L'image est déjà blanche : la légère ombre la décolle du
       dégradé sans lui ajouter de couleur. */
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .35));
}
.marque__mot {
    font-family: var(--font-heading);
    font-weight: 800;
    font-style: italic;
    font-size: 1.32rem;
    letter-spacing: -.02em;
    line-height: 1;
    white-space: nowrap;
}
.marque__ride { color: #fff; }
.marque__paddle { color: var(--ride); }

.site-navbar .nav-link {
    color: #d7e7f5;
    border-radius: 999px;
    padding-inline: .85rem;
}
.site-navbar .nav-item .nav-link:not(.nav-admin-link)::after {
    background: var(--ride);
    left: .85rem; right: .85rem;
    height: 2.5px;
    border-radius: 2px;
}
.nav-admin-link {
    background: rgba(27, 157, 240, .18);
    border-color: rgba(27, 157, 240, .5);
}

.menu-compte__xp { padding: .35rem 1rem .5rem; min-width: 250px; }
.dropdown-item--premium { color: var(--ride-encre); font-weight: 600; }

.fanion-premium {
    display: inline-grid;
    place-items: center;
    width: 18px; height: 18px;
    border-radius: 50%;
    background: linear-gradient(140deg, #f7c948, #d99b1c);
    color: #4a3405;
    font-size: .7rem;
    line-height: 1;
    box-shadow: 0 1px 4px rgba(0, 0, 0, .25);
}

/* --- Le héros --------------------------------------------- */
.hero {
    background:
        radial-gradient(120% 90% at 82% 8%, rgba(27, 157, 240, .55) 0%, rgba(27, 157, 240, 0) 62%),
        linear-gradient(160deg, var(--marine) 0%, #123c66 55%, #0f5b96 100%);
}
.hero__eyebrow {
    background: rgba(27, 157, 240, .22);
    border-color: rgba(111, 211, 230, .5);
    color: #cdeeff;
    text-transform: uppercase;
    letter-spacing: .09em;
}
/*  La signature sous le logo du bandeau.
    ⚠️ UNE SEULE DÉFINITION, ET C'EST CELLE-CI. La classe avait
    survécu à la disparition de son élément : le style était resté
    ici pendant que le HTML, lui, ne l'écrivait plus nulle part.
    En le réécrivant on a failli en ajouter une seconde plus haut
    dans le fichier, que celle-ci aurait écrasée en silence. */
.hero__signature {
    display: block;
    margin: 0 0 1.25rem;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: .82rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    text-align: center;
    white-space: nowrap;
    color: #fff;
}
/* La vague du bas reprend la couleur de fond de la page. Le
   dégradé ne pouvant pas entrer dans une image encodée, on
   redéclare simplement l'image en thème sombre. */
.hero__wave {
    background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 70' preserveAspectRatio='none'%3E%3Cpath fill='%23f4f7fa' d='M0,40 C240,90 480,0 720,20 C960,40 1200,90 1440,40 L1440,70 L0,70 Z'%3E%3C/path%3E%3C/svg%3E");
}
:root[data-theme="sombre"] .hero__wave {
    background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 70' preserveAspectRatio='none'%3E%3Cpath fill='%230d1720' d='M0,40 C240,90 480,0 720,20 C960,40 1200,90 1440,40 L1440,70 L0,70 Z'%3E%3C/path%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) .hero__wave {
        background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 70' preserveAspectRatio='none'%3E%3Cpath fill='%230d1720' d='M0,40 C240,90 480,0 720,20 C960,40 1200,90 1440,40 L1440,70 L0,70 Z'%3E%3C/path%3E%3C/svg%3E");
    }
}

.btn-cta {
    background: linear-gradient(135deg, var(--ride) 0%, #0f76c4 100%);
    border: none;
    box-shadow: 0 8px 20px rgba(15, 118, 196, .38);
}
.btn-cta:hover, .btn-cta:focus {
    background: linear-gradient(135deg, #35abf5 0%, #1483d4 100%);
    box-shadow: 0 10px 26px rgba(15, 118, 196, .46);
}

/* --- Surfaces ---------------------------------------------- */
.page-card, .admin-card, .carte-choix {
    border-radius: var(--radius);
    box-shadow: 0 10px 28px var(--ombre);
}

/* Un liseré bleu en haut des cartes de contenu : c'est le seul
   endroit où le bleu vif sert de décor, et il suffit à relier
   toutes les pages entre elles. */
.page-card { position: relative; overflow: hidden; }
.page-card::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    background: linear-gradient(90deg, var(--marine), var(--ride) 55%, var(--ecume));
    opacity: .9;
}

/* --- Titres à double couleur -------------------------------- */
.titre-double { color: var(--titre); }
.titre-double em { font-style: normal; color: var(--ride-encre); }

/* ==========================================================
   Expérience (XP)
   ========================================================== */
.xp-barre { min-width: 190px; }
.xp-barre__entete {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .6rem;
    margin-bottom: .3rem;
}
.xp-barre__niveau {
    font-family: var(--font-heading);
    font-weight: 700;
    color: var(--titre);
    font-size: .95rem;
}
.xp-barre__total { font-size: .78rem; color: var(--muted); }
.xp-barre__piste {
    height: 9px;
    border-radius: 999px;
    background: var(--surface-2);
    overflow: hidden;
}
.xp-barre__remplissage {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--ride-encre), var(--ride) 60%, var(--ecume));
    transition: width .5s ease;
}
.xp-barre__legende {
    margin: .3rem 0 0;
    font-size: .74rem;
    color: var(--muted);
}
.xp-barre--compacte .xp-barre__niveau { font-size: .85rem; }
.xp-barre--compacte .xp-barre__piste { height: 7px; }

/* La barre de grade : même forme que celle d'XP, teinte différente.
   Deux compteurs distincts — les kilomètres et l'expérience — qui se
   lisent d'un coup d'œil parce qu'ils sont posés côte à côte. */
.progressions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 1rem 1.6rem;
    max-width: 640px;
}
.xp-barre--grade .xp-barre__remplissage {
    background: linear-gradient(90deg, var(--marine), var(--ecume));
}

.xp-pastille {
    display: inline-grid;
    place-items: center;
    width: 26px; height: 26px;
    border-radius: 50%;
    background: linear-gradient(140deg, var(--ride), var(--ride-encre));
    color: #fff;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: .78rem;
    line-height: 1;
    box-shadow: 0 2px 6px rgba(15, 118, 196, .35);
    flex: 0 0 auto;
}
.xp-pastille--sm { width: 20px; height: 20px; font-size: .66rem; }

.xp-recompense {
    display: flex;
    gap: .85rem;
    align-items: flex-start;
    padding: .75rem .9rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}
.xp-recompense--verrouillee { opacity: .62; }
.xp-recompense__palier {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 42px; height: 42px;
    border-radius: 12px;
    background: var(--surface-2);
    color: var(--titre);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: .8rem;
    line-height: 1.1;
    text-align: center;
}
.xp-recompense--ouverte .xp-recompense__palier {
    background: linear-gradient(140deg, var(--ride), var(--ride-encre));
    color: #fff;
}
.xp-recompense__titre { font-weight: 600; color: var(--titre); }
.xp-recompense__texte { font-size: .85rem; color: var(--muted); margin: .15rem 0 0; }

/* ==========================================================
   Cadres : photos de profil et badges
   ==========================================================
   Le principe est le même pour les deux : une pile de deux
   couches, la photo (ou le disque du badge) en dessous, le
   cadre en image par-dessus.

   Le cadre ne doit JAMAIS intercepter un clic : il recouvre
   entièrement la photo, et un avatar cliquable deviendrait
   inerte. D'où le pointer-events: none.
   ========================================================== */
.deco {
    position: relative;
    display: inline-block;
    width: var(--deco-taille);
    height: var(--deco-taille);
    flex: 0 0 auto;
    vertical-align: middle;
}
/* La photo est posée sur l'AXE DU TROU du cadre, pas au centre du carré :
   beaucoup de cadres portent un ornement en haut, qui décale l'anneau vers
   le bas dans son image. Largeur et hauteur sont réglées séparément —
   plusieurs cadres sont franchement elliptiques. Les quatre valeurs
   viennent de la mesure, ou d'Admin → Cadres. */
.deco__photo {
    position: absolute;
    left: var(--deco-x, 50%);
    top: var(--deco-y, 50%);
    width: var(--deco-l, 60%);
    height: var(--deco-h, 60%);
    transform: translate(-50%, -50%);
    display: grid;
    place-items: center;
    overflow: hidden;
    border-radius: 50%;
}
/* L'avatar remplit la zone : c'est elle, et non lui, qui porte la forme. */
.deco__photo > * {
    display: block;
    width: 100% !important;
    height: 100% !important;
    border-radius: 50%;
}

/* Le liseré blanc de l'avatar n'a rien à faire sous un cadre : c'est
   exactement le blanc qu'on voyait apparaître entre la photo et l'anneau.
   L'ombre portée disparaît pour la même raison. */
.deco .avatar { border: none; box-shadow: none; }
.deco__cadre {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    user-select: none;
}

/* --- Les animations de cadre (Premium) ---------------------
   Seul le CADRE bouge, jamais la photo : faire tourner un
   visage donne le mal de mer, et le texte à côté deviendrait
   illisible. */
@keyframes cadreRotation { to { transform: rotate(360deg); } }
/* Un balancement de barque : la rotation revient au point de
   départ, donc rien ne dérive au fil des minutes. */
@keyframes cadreBalance {
    0%, 100% { transform: rotate(-3.5deg); }
    50%      { transform: rotate(3.5deg); }
}
@keyframes cadreHalo {
    0%, 100% { filter: drop-shadow(0 0 2px rgba(111, 211, 230, .5)); }
    50%      { filter: drop-shadow(0 0 9px rgba(111, 211, 230, .95)); }
}
@keyframes cadreScintille {
    0%, 88%, 100% { filter: brightness(1); }
    93%           { filter: brightness(1.5); }
}
.deco--rotation  .deco__cadre { animation: cadreRotation 18s linear infinite; }
.deco--balance   .deco__cadre { animation: cadreBalance 4.2s ease-in-out infinite; }
.deco--halo      .deco__cadre { animation: cadreHalo 2.8s ease-in-out infinite; }
.deco--scintille .deco__cadre { animation: cadreScintille 4.5s ease-in-out infinite; }

/* Qui a demandé moins d'animations dans son système en a moins.
   Ce n'est pas une préférence esthétique : pour certaines personnes,
   le mouvement continu déclenche des nausées ou des migraines. */
@media (prefers-reduced-motion: reduce) {
    .deco__cadre { animation: none !important; }
}

/* ==========================================================
   Badges
   ==========================================================
   Un disque coloré, le motif au centre, le cadre par-dessus.
   ========================================================== */
.badge-icone {
    position: relative;
    display: inline-block;
    width: var(--badge-taille);
    height: var(--badge-taille);
    flex: 0 0 auto;
    vertical-align: middle;
}
/* Même principe que pour les photos de profil : le disque se cale sur
   l'axe réel de l'anneau, et déborde légèrement dessous pour qu'aucun
   liseré de fond ne subsiste entre les deux. */
.badge-icone__disque {
    position: absolute;
    left: var(--badge-x, 50%);
    top: var(--badge-y, 50%);
    width: var(--badge-l, 60%);
    height: var(--badge-h, 60%);
    transform: translate(-50%, -50%);
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 28%,
                color-mix(in srgb, var(--badge-couleur) 78%, white),
                var(--badge-couleur) 72%);
    box-shadow: inset 0 -2px 6px rgba(0, 0, 0, .18);
}
.badge-icone__motif { width: 58%; height: 58%; }
.badge-icone__image {
    width: 72%;
    height: 72%;
    object-fit: contain;
}
.badge-icone__cadre {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    user-select: none;
}
.badge-icone--verrouille { opacity: .38; filter: grayscale(.85); }
.badge-icone--anime .badge-icone__cadre { animation: cadreRotation 22s linear infinite; }

/* color-mix n'est pas compris partout ; sans lui le disque serait
   transparent, ce qui est bien pire qu'un aplat sans dégradé. */
@supports not (background: color-mix(in srgb, red 50%, white)) {
    .badge-icone__disque { background: var(--badge-couleur); }
}

/* ==========================================================
   Premium
   ========================================================== */
.premium-entete {
    background:
        radial-gradient(110% 90% at 85% 10%, rgba(247, 201, 72, .3) 0%, rgba(247, 201, 72, 0) 60%),
        linear-gradient(155deg, var(--marine) 0%, #123c66 100%);
    color: #fff;
    border-radius: var(--radius);
    padding: 2rem 1.75rem;
}
.premium-entete h1 { color: #fff; }
.premium-entete__signature { color: var(--ecume); font-style: italic; font-weight: 600; }

.premium-avantage {
    display: flex;
    gap: .9rem;
    padding: 1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    height: 100%;
}
.premium-avantage__icone {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 40px; height: 40px;
    border-radius: 11px;
    background: var(--surface-2);
    color: var(--ride-encre);
}
.premium-avantage__titre { font-weight: 600; color: var(--titre); margin: 0; }
.premium-avantage__texte { font-size: .87rem; color: var(--muted); margin: .2rem 0 0; }

.premium-formule {
    border: 2px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 1.4rem;
    height: 100%;
    display: flex;
    flex-direction: column;
}
.premium-formule--vedette {
    border-color: var(--ride);
    box-shadow: 0 12px 30px rgba(15, 118, 196, .18);
}
.premium-formule__prix {
    font-family: var(--font-heading);
    font-size: 2.1rem;
    font-weight: 800;
    color: var(--titre);
    line-height: 1;
}
.premium-formule__unite { font-size: .9rem; color: var(--muted); font-weight: 500; }
.premium-formule__note { font-size: .8rem; color: var(--muted); }

/* ==========================================================
   Administration
   ========================================================== */
.admin-grille {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1rem;
}
.admin-tuile {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    padding: 1.1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: inherit;
    text-decoration: none;
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.admin-tuile:hover {
    transform: translateY(-2px);
    border-color: var(--ride);
    box-shadow: 0 12px 26px var(--ombre);
    color: inherit;
}
.admin-tuile__titre {
    font-family: var(--font-heading);
    font-weight: 700;
    color: var(--titre);
    display: flex;
    align-items: center;
    gap: .5rem;
}
.admin-tuile__texte { font-size: .85rem; color: var(--muted); margin: 0; }
.admin-tuile__compteur {
    margin-left: auto;
    background: var(--surface-2);
    color: var(--titre);
    border-radius: 999px;
    padding: .05rem .5rem;
    font-size: .78rem;
    font-weight: 700;
}
.admin-tuile__compteur--alerte { background: var(--red); color: #fff; }

.admin-chiffres {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: .8rem;
}
.admin-chiffre {
    padding: .9rem 1rem;
    border-radius: var(--radius);
    background: var(--surface);
    border: 1px solid var(--border);
}
.admin-chiffre__valeur {
    display: block;
    font-family: var(--font-heading);
    font-size: 1.6rem;
    font-weight: 800;
    color: var(--titre);
    line-height: 1.1;
}
.admin-chiffre__libelle { font-size: .76rem; color: var(--muted); }

.reglage-ligne {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    padding: .9rem 0;
    border-bottom: 1px solid var(--border);
}
.reglage-ligne:last-child { border-bottom: none; }
.reglage-ligne__texte { flex: 1 1 auto; min-width: 0; }
.reglage-ligne__titre { font-weight: 600; color: var(--titre); }
.reglage-ligne__aide { font-size: .82rem; color: var(--muted); margin: .1rem 0 0; }
.reglage-ligne__champ { flex: 0 0 auto; width: min(260px, 45%); }

.etat-pastille {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .78rem;
    font-weight: 600;
    padding: .15rem .55rem;
    border-radius: 999px;
}
.etat-pastille--on { background: rgba(46, 139, 87, .14); color: #1f6b40; }
.etat-pastille--off { background: rgba(91, 115, 134, .16); color: var(--muted); }
.etat-pastille--premium {
    background: linear-gradient(120deg, #f0c14b, #e0a020);
    color: #3a2600;
    text-transform: none;
}
/* Le doré est le même dans les deux thèmes : c'est une teinte de
   marque, pas une couleur de surface. Le texte brun foncé tient
   dessus quel que soit le fond de la page. */
:root[data-theme="sombre"] .etat-pastille--premium,
:root[data-theme="sombre"] .badge-premium { color: #3a2600; }
:root[data-theme="sombre"] .etat-pastille--on { background: rgba(46, 139, 87, .22); color: #7ed6a4; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) .etat-pastille--on { background: rgba(46, 139, 87, .22); color: #7ed6a4; }
}
.hero__map { flex-direction: column; }
.hero-map__svg { max-width: 320px; opacity: .95; }
.hero-pin__dot { fill: #fff; stroke: var(--marine); }
.hero-pin__pulse { fill: #fff; }

/* --- Navigation de l'administration ------------------------ */
.admin-nav {
    margin: .5rem 0 1.5rem;
    border-bottom: 1px solid var(--border);
}
.admin-nav__piste {
    display: flex;
    gap: .25rem;
    overflow-x: auto;
    scrollbar-width: thin;
    padding-bottom: 2px;
}
.admin-nav__lien {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .5rem .85rem;
    border-radius: 8px 8px 0 0;
    color: var(--muted);
    text-decoration: none;
    font-weight: 500;
    font-size: .92rem;
    white-space: nowrap;
    border-bottom: 2.5px solid transparent;
    transition: color .15s ease, background .15s ease, border-color .15s ease;
}
.admin-nav__lien:hover { color: var(--titre); background: var(--surface-2); }
.admin-nav__lien.est-actif {
    color: var(--ride-encre);
    border-bottom-color: var(--ride);
    font-weight: 600;
}
.badge-case { position: relative; }
.badge-case__paliers {
    position: absolute;
    top: 4px; right: 6px;
    background: var(--marine);
    color: #fff;
    font-size: .68rem;
    font-weight: 700;
    padding: .05rem .38rem;
    border-radius: 999px;
    box-shadow: 0 1px 4px rgba(0,0,0,.3);
}

/* ==========================================================
   L'AURA : ce qui tourne autour de la photo (niveau 60)
   ==========================================================
    Des caractères en orbite, placés par la CSS seule : aucune image
    à charger, net sur tous les écrans, et rien à mettre en cache.

    LE CALCUL DE LA POSITION. Chaque grain porte deux nombres :
    `--i`, son rang, et `--n`, combien ils sont. Son angle de départ
    vaut donc i/n de tour — c'est ce qui les répartit régulièrement au
    lieu de les empiler. Le même rapport décale son animation dans le
    temps, pour que les scintillements ne battent pas tous ensemble.

    POURQUOI DEUX ROTATIONS. La première fait tourner le grain AUTOUR
    de la photo ; la seconde, en sens inverse, le fait tourner sur
    lui-même à la même vitesse. Résultat : la flamme reste droite tout
    le long de son tour, au lieu de finir la tête en bas.
   ========================================================== */
.aura {
    position: relative;
    display: inline-grid;
    place-items: center;
    /*  L'aura ne doit jamais intercepter un clic : sous elle, il y a
        souvent un lien vers le profil. */
    isolation: isolate;
}
.aura > .aura__grain {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 1em;
    height: 1em;
    margin: -.5em 0 0 -.5em;
    /*  Rayon et taille de caractère viennent du PHP, en PIXELS, calculés
        d'après la taille de la photo. En pourcentage, `translateX` se
        rapporterait à la largeur du GRAIN — un caractère — et les flammes
        tourneraient au milieu de la photo au lieu d'en faire le tour. */
    font-size: var(--aura-grain, 16px);
    --rayon: var(--aura-rayon, 34px);
    line-height: 1;
    pointer-events: none;
    --tour: 9s;
    animation: aura-orbite var(--tour) linear infinite;
    animation-delay: calc(var(--tour) * -1 * var(--i) / var(--n));
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .35));
}
@keyframes aura-orbite {
    from { transform: rotate(0turn) translateX(var(--rayon)) rotate(0turn); }
    to   { transform: rotate(1turn) translateX(var(--rayon)) rotate(-1turn); }
}

/*  Chaque aura a son tempérament : le vent file, la vague traîne. */
.aura--flammes > .aura__grain { --tour: 7s; }
.aura--eau     > .aura__grain { --tour: 11s; }
.aura--vent    > .aura__grain { --tour: 5s; }
.aura--vagues  > .aura__grain { --tour: 13s; }
.aura--orage   > .aura__grain { --tour: 6s; }

/*  Les étincelles tournent ET clignotent, sur deux durées différentes :
    un scintillement calé sur le tour donnerait un battement mécanique. */
.aura--etoiles > .aura__grain {
    --tour: 10s;
    animation: aura-orbite var(--tour) linear infinite,
               aura-scintille 1.7s ease-in-out infinite;
    animation-delay: calc(var(--tour) * -1 * var(--i) / var(--n)),
                     calc(-1.7s * var(--i) / var(--n));
}
@keyframes aura-scintille {
    0%, 100% { opacity: .45; }
    50%      { opacity: 1; }
}

/*  Respecter le réglage du système. Quelqu'un qui a demandé moins
    d'animations ne doit pas voir six flammes tourner sous ses yeux —
    on garde les grains, immobiles et répartis, plutôt que de tout
    effacer : l'aura reste visible, elle ne bouge plus. */
@media (prefers-reduced-motion: reduce) {
    .aura > .aura__grain {
        animation: none;
        transform: rotate(calc(1turn * var(--i) / var(--n)))
                   translateX(var(--rayon))
                   rotate(calc(-1turn * var(--i) / var(--n)));
    }
}

/* --- Choix d'une aura, dans les paramètres --- */
.choix-auras {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    gap: .75rem;
}
.choix-aura {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .4rem;
    padding: .8rem .5rem .6rem;
    border: 2px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    cursor: pointer;
    text-align: center;
}
.choix-aura input { position: absolute; opacity: 0; pointer-events: none; }
.choix-aura:has(input:checked) {
    border-color: var(--ride);
    box-shadow: 0 6px 18px rgba(15, 118, 196, .18);
}
.choix-aura.est-verrouille { opacity: .5; cursor: not-allowed; }
.choix-aura__apercu { display: grid; place-items: center; min-height: 86px; }
.choix-aura__nom { font-size: .8rem; color: var(--titre); font-weight: 500; }

/* --- Choix d'une décoration de profil ---------------------- */
.choix-decos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
    gap: .75rem;
}
.choix-deco {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .4rem;
    padding: .8rem .5rem .6rem;
    border: 2px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    cursor: pointer;
    text-align: center;
}
.choix-deco input { position: absolute; opacity: 0; pointer-events: none; }
.choix-deco:has(input:checked) {
    border-color: var(--ride);
    box-shadow: 0 6px 18px rgba(15, 118, 196, .18);
}
.choix-deco.est-verrouille { opacity: .5; cursor: not-allowed; }
.choix-deco__apercu { display: grid; place-items: center; min-height: 124px; }
.choix-deco__nom { font-size: .8rem; color: var(--titre); font-weight: 500; }
.choix-deco__verrou {
    font-size: .68rem;
    font-weight: 700;
    color: var(--muted);
    background: var(--surface-2);
    border-radius: 999px;
    padding: .05rem .45rem;
}
.site-footer__logo { height: 54px; width: auto; }
:root[data-theme="sombre"] .site-footer__logo { filter: brightness(0) invert(1) opacity(.9); }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) .site-footer__logo { filter: brightness(0) invert(1) opacity(.9); }
}


/* ==========================================================
   Listes façon application
   ==========================================================
   Une suite de rangées cliquables, séparées par un filet, avec
   un chevron à droite. Sert aux notifications, aux réglages et
   au menu du profil — sur téléphone COMME sur ordinateur, d'où
   sa place ici et non dans la couche téléphone.
   ========================================================== */
.liste-app {
    list-style: none;
    margin: 0;
    padding: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    overflow: hidden;
}
.liste-app__ligne { border-bottom: 1px solid var(--border); }
.liste-app__ligne:last-child { border-bottom: none; }

.liste-app__lien {
    display: flex;
    align-items: center;
    gap: .8rem;
    min-height: 54px;
    padding: .7rem 1rem;
    color: var(--text);
    text-decoration: none;
    font-weight: 500;
}
.liste-app__lien:active { background: var(--surface-2); }
.liste-app__lien.est-danger { color: var(--red); }

.liste-app__icone {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--blue);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
}
.liste-app__texte { flex: 1 1 auto; min-width: 0; }
.liste-app__titre {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.liste-app__aide {
    display: block;
    font-size: .78rem;
    color: var(--muted);
    font-weight: 400;
}
.liste-app__fin {
    flex-shrink: 0;
    color: var(--muted);
    font-size: .82rem;
    display: inline-flex;
    align-items: center;
    gap: .4rem;
}
.liste-app__chevron { width: 18px; height: 18px; opacity: .55; }

.xp-recompense__cadre { flex: 0 0 auto; width: 52px; height: 52px; }
.xp-recompense--verrouillee .xp-recompense__cadre { filter: grayscale(1); opacity: .55; }

/* --- Réglage des cadres (administration) -------------------- */
.reglage-cadres {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1rem;
}
.cadre-reglage {
    padding: 1rem .9rem .8rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}
.cadre-reglage__scene {
    display: grid;
    place-items: center;
    min-height: 160px;
    /* Un damier discret : sans lui, impossible de voir si un liseré de
       fond subsiste entre la photo et le trait du cadre. */
    background-image:
        linear-gradient(45deg, var(--surface-2) 25%, transparent 25%),
        linear-gradient(-45deg, var(--surface-2) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, var(--surface-2) 75%),
        linear-gradient(-45deg, transparent 75%, var(--surface-2) 75%);
    background-size: 14px 14px;
    background-position: 0 0, 0 7px, 7px -7px, -7px 0;
    border-radius: 10px;
    margin-bottom: .6rem;
}
.cadre-reglage__nom {
    font-size: .8rem;
    font-weight: 600;
    color: var(--titre);
    margin: 0 0 .5rem;
    word-break: break-all;
}
.cadre-reglage__ligne {
    display: grid;
    grid-template-columns: 5.2rem 1fr 2.4rem;
    align-items: center;
    gap: .4rem;
    margin-bottom: .15rem;
}
.cadre-reglage__libelle { font-size: .74rem; color: var(--muted); }
.cadre-reglage__valeur {
    font-size: .74rem;
    color: var(--titre);
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.cadre-reglage .form-range { margin: 0; }
/* Les deux liens du bas tiennent sur une ligne : sur deux, ils
   décalaient la hauteur des blocs les uns par rapport aux autres. */
.cadre-reglage__actions { font-size: .74rem; }
.cadre-reglage__actions .btn { font-size: inherit; text-align: left; }
/* La barre d'enregistrement est collée en bas ; sans cette réserve
   elle recouvrirait la dernière rangée de cadres. */
#form-cadres { padding-bottom: 3.5rem; }

/* Le séparateur entre les quatre anciens onglets, réunis en un seul.
   Sans lui, les sections s'enchaînaient sans qu'on voie où l'une
   finit et l'autre commence. */
.reglages__separateur {
    margin: 2.2rem 0 1.4rem;
    border: 0;
    border-top: 2px solid var(--border);
    opacity: 1;
}

/* --- Notifications sur téléphone ---------------------------- */
.push-etat { font-size: .85rem; color: var(--muted); margin: 0; }
.push-etat--ok { color: #1f6b40; }
.push-etat--ko { color: #a4342c; }
:root[data-theme="sombre"] .push-etat--ok { color: #7ed6a4; }
:root[data-theme="sombre"] .push-etat--ko { color: #ff9c93; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) .push-etat--ok { color: #7ed6a4; }
    :root:not([data-theme="clair"]) .push-etat--ko { color: #ff9c93; }
}

/*  Le bandeau qui propose les notifications après l'inscription.
 *  Une bordure teintée, pas une alerte colorée en plein : c'est une
 *  proposition, pas un problème à régler. */
.bienvenue-push {
    border-left: 4px solid var(--ride);
}
.bienvenue-push__icone { font-size: 1.7rem; line-height: 1; }

.liste-appareils { list-style: none; margin: 0; padding: 0; }
.liste-appareils li {
    padding: .5rem 0;
    border-bottom: 1px dashed var(--border);
}
.liste-appareils li:last-child { border-bottom: 0; }
.liste-appareils__nom { font-weight: 600; color: var(--titre); display: block; }

/* Le diagnostic : une coche ou une croix, et la raison à côté.
   Dire CE QUI manque vaut mieux que « ça ne marche pas ». */
.liste-diagnostic { list-style: none; margin: 0; padding: 0; }
.liste-diagnostic li {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .45rem 0;
}
.liste-diagnostic__marque {
    flex: 0 0 auto;
    width: 22px; height: 22px;
    display: grid; place-items: center;
    border-radius: 50%;
    font-size: .8rem; font-weight: 700;
}
.liste-diagnostic .est-ok > .liste-diagnostic__marque,
.liste-diagnostic li.est-ok .liste-diagnostic__marque {
    background: rgba(46, 139, 87, .16); color: #1f6b40;
}
.liste-diagnostic li.est-ko .liste-diagnostic__marque {
    background: rgba(190, 60, 48, .14); color: #a4342c;
}

.bloc-cles {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: .8rem 1rem;
    font-size: .82rem;
    overflow-x: auto;
    user-select: all;
}

/* L'encart iPhone : le push y exige l'ajout à l'écran d'accueil,
   et personne ne devine ce geste tout seul. */
.encart-ios {
    display: flex;
    gap: .75rem;
    align-items: flex-start;
    padding: .9rem 1rem;
    border: 1px solid var(--border);
    border-left: 4px solid var(--ride);
    border-radius: var(--radius);
    background: var(--surface);
    margin-bottom: 1rem;
}
.encart-ios__icone { font-size: 1.4rem; line-height: 1; }

/* ==========================================================
   La page « Installer l'application »
   ==========================================================
    Un mode d'emploi se lit en le SUIVANT : les étapes sont donc
    numérotées, espacées, et chacune tient sur une ligne ou deux. Un
    paragraphe compact obligerait à retrouver du regard où l'on en
    était après chaque geste sur le téléphone.
   ========================================================== */
.page-installer__icone {
    border-radius: 22%;
    box-shadow: 0 6px 20px rgba(0, 0, 0, .22);
}
.etapes-installer {
    counter-reset: etape;
    list-style: none;
    padding: 0;
    margin: 0 0 1rem;
}
.etapes-installer li {
    counter-increment: etape;
    position: relative;
    padding: .1rem 0 .1rem 2.2rem;
    margin-bottom: .7rem;
    line-height: 1.5;
}
.etapes-installer li::before {
    content: counter(etape);
    position: absolute;
    left: 0;
    top: 0;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 50%;
    background: var(--ride);
    color: #fff;
    font-size: .82rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}
.encart-ios p { margin: 0; font-size: .85rem; }
.encart-ios__fermer {
    background: none; border: 0; color: var(--muted);
    font-size: 1.1rem; line-height: 1; padding: 0 .2rem; cursor: pointer;
}

/* Une ligne de membre suspendu : reconnaissable d'un coup d'œil dans
   une liste, sans devenir illisible pour autant. */
.ligne-suspendue > td { background: rgba(190, 60, 48, .05); }
.pastille-admin, .pastille-moderateur, .table .badge.text-bg-info { font-size: .7rem; }

/* La pastille Premium, dans la liste des statuts. */
.badge-premium {
    background: linear-gradient(120deg, #f0c14b, #e0a020);
    color: #3a2600;
}

/* Les cases « ce que je montre » : dix-sept réglages en colonne
   faisaient un mur. En grille, on les embrasse d'un regard. */
.grille-cases {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: .1rem 1.4rem;
}

/* La barre d'enregistrement de la page des paramètres : collée en bas,
   parce que la page est longue et qu'il ne doit jamais falloir la
   remonter pour valider. */
.barre-enregistrer {
    position: sticky;
    bottom: 0;
    z-index: 5;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem;
    padding: .8rem 0 1rem;
    background: linear-gradient(to bottom, transparent, var(--fond) 35%);
}

/* --- « Ajouter une fiche, en trois minutes » (accueil) ------------- */
.carte-contribuer {
    padding: 1.5rem;
    border-radius: 18px;
    background: linear-gradient(150deg, var(--marine), var(--ride-encre));
    color: #fff;
    box-shadow: 0 14px 34px rgba(11, 32, 60, .22);
}
.carte-contribuer__titre {
    font-family: var(--font-heading);
    font-size: 1.15rem;
    font-weight: 700;
    margin: 0 0 1.1rem;
    color: #fff;
}
.etapes-contribuer {
    list-style: none;
    margin: 0 0 1.3rem;
    padding: 0;
    display: grid;
    gap: .9rem;
}
.etapes-contribuer li {
    display: flex;
    gap: .75rem;
    align-items: flex-start;
    font-size: .88rem;
    line-height: 1.45;
    color: rgba(255, 255, 255, .82);
}
.etapes-contribuer strong { color: #fff; font-weight: 600; }
.etapes-contribuer__num {
    flex: 0 0 auto;
    width: 26px; height: 26px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: rgba(255, 255, 255, .16);
    border: 1px solid rgba(255, 255, 255, .28);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: .82rem;
    color: #fff;
}
.carte-contribuer .btn-cta { margin-bottom: .7rem; }
.carte-contribuer__lien {
    display: block;
    text-align: center;
    font-size: .82rem;
    color: rgba(255, 255, 255, .78);
    text-decoration: none;
}
.carte-contribuer__lien:hover { color: #fff; text-decoration: underline; }

/* --- Les actions d'un profil --------------------------------------
   Deux gestes en clair (écrire, ajouter), le reste derrière « … ».
   Même forme, même taille, même poids : c'est ce qui les rend
   discrets sans les rendre difficiles à trouver. */
.profil-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
}
.profil-actions__forme { display: flex; align-items: center; gap: .4rem; margin: 0; }

.profil-action {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .42rem .8rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--titre);
    font-size: .82rem;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease, transform .15s ease;
}
.profil-action:hover {
    background: var(--surface-2);
    border-color: var(--ride);
    color: var(--titre);
    transform: translateY(-1px);
}
.profil-action svg { width: 16px; height: 16px; flex: 0 0 auto; }

.profil-action--primaire {
    background: var(--ride);
    border-color: var(--ride);
    color: #fff;
}
.profil-action--primaire:hover { background: var(--ride-encre); border-color: var(--ride-encre); color: #fff; }

/* L'état « vous êtes amis » n'est pas un bouton : rien ne se passe
   si on clique dessus, il ne doit donc pas y ressembler. */
.profil-action--etat {
    background: transparent;
    border-style: dashed;
    color: var(--muted);
    cursor: default;
}
.profil-action--etat:hover { background: transparent; border-color: var(--border); transform: none; }

.profil-action--discret { padding: .42rem .55rem; color: var(--muted); }
.profil-action--discret svg { width: 18px; height: 18px; }

/* ==========================================================
   Les encarts Bootstrap en thème sombre
   ==========================================================
   .alert-secondary, .alert-info et compagnie ont leurs couleurs
   écrites dans bootstrap.min.css, sans variante sombre. Résultat :
   un bloc blanc cassé posé au milieu d'une page noire, et — pire —
   les pastilles qu'il contient devenaient illisibles, leur texte
   clair se retrouvant sur ce fond clair.

   On les redéfinit ici pour les trois états du thème. Le sens de
   chaque couleur est conservé : gris pour une note, bleu pour une
   information, jaune pour un avertissement, rouge pour une erreur,
   vert pour une réussite.
   ========================================================== */
:root[data-theme="sombre"] .alert-secondary,
:root[data-theme="sombre"] .alert-light {
    background-color: var(--surface-2);
    border-color: var(--border);
    color: var(--text);
}
:root[data-theme="sombre"] .alert-info {
    background-color: rgba(63, 176, 245, .12);
    border-color: rgba(63, 176, 245, .3);
    color: #b9e2fb;
}
:root[data-theme="sombre"] .alert-warning {
    background-color: rgba(242, 165, 22, .12);
    border-color: rgba(242, 165, 22, .32);
    color: #f3cd8a;
}
:root[data-theme="sombre"] .alert-danger {
    background-color: var(--alerte-fond);
    border-color: rgba(190, 60, 48, .35);
    color: var(--alerte-texte);
}
:root[data-theme="sombre"] .alert-success {
    background-color: var(--reussi-fond);
    border-color: var(--reussi-bord);
    color: var(--reussi-texte);
}
:root[data-theme="sombre"] .alert code {
    background: rgba(255, 255, 255, .08);
    color: inherit;
}

/* Les liens DANS un encart.
   Bootstrap donne à .alert-link une version assombrie de la couleur de
   l'encart — pensée pour un fond clair. Sur nos encarts sombres, elle
   tombait à 2,03 de contraste : lisible pour personne. On reprend la
   couleur du texte de l'encart, qui est déjà validée contre son propre
   fond, et on souligne pour que le lien reste reconnaissable comme
   lien sans dépendre de la seule couleur. */
:root[data-theme="sombre"] .alert .alert-link,
:root[data-theme="sombre"] .alert a:not(.btn) {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
    font-weight: 600;
}
:root[data-theme="sombre"] .alert .alert-link:hover,
:root[data-theme="sombre"] .alert a:not(.btn):hover {
    opacity: .82;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) .alert-secondary,
    :root:not([data-theme="clair"]) .alert-light {
        background-color: var(--surface-2);
        border-color: var(--border);
        color: var(--text);
    }
    :root:not([data-theme="clair"]) .alert-info {
        background-color: rgba(63, 176, 245, .12);
        border-color: rgba(63, 176, 245, .3);
        color: #b9e2fb;
    }
    :root:not([data-theme="clair"]) .alert-warning {
        background-color: rgba(242, 165, 22, .12);
        border-color: rgba(242, 165, 22, .32);
        color: #f3cd8a;
    }
    :root:not([data-theme="clair"]) .alert-danger {
        background-color: var(--alerte-fond);
        border-color: rgba(190, 60, 48, .35);
        color: var(--alerte-texte);
    }
    :root:not([data-theme="clair"]) .alert-success {
        background-color: var(--reussi-fond);
        border-color: var(--reussi-bord);
        color: var(--reussi-texte);
    }
    :root:not([data-theme="clair"]) .alert code {
        background: rgba(255, 255, 255, .08);
        color: inherit;
    }

/* Les liens DANS un encart.
   Bootstrap donne à .alert-link une version assombrie de la couleur de
   l'encart — pensée pour un fond clair. Sur nos encarts sombres, elle
   tombait à 2,03 de contraste : lisible pour personne. On reprend la
   couleur du texte de l'encart, qui est déjà validée contre son propre
   fond, et on souligne pour que le lien reste reconnaissable comme
   lien sans dépendre de la seule couleur. */
    :root:not([data-theme="clair"]) .alert .alert-link,
    :root:not([data-theme="clair"]) .alert a:not(.btn) {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
    font-weight: 600;
}
    :root:not([data-theme="clair"]) .alert .alert-link:hover,
    :root:not([data-theme="clair"]) .alert a:not(.btn):hover {
    opacity: .82;
}
}

/* Même oubli sur les pastilles claires de Bootstrap : text-bg-light
   pose un fond blanc, et le texte sombre qu'il impose disparaît si on
   ne le reprend pas. */
:root[data-theme="sombre"] .text-bg-light,
:root[data-theme="sombre"] .badge.bg-light {
    background-color: var(--surface-2) !important;
    color: var(--text) !important;
}

/* La pastille de rôle, posée à côté d'un pseudo.
   Une icône plutôt qu'un mot : « ADMIN » en capitales pesait autant que
   le pseudo lui-même. L'écu se reconnaît d'un coup d'œil et ne vole la
   vedette à personne. Sa taille suit celle du texte voisin (en em), donc
   elle reste juste dans un titre de profil comme dans une carte
   d'annuaire, sans réglage supplémentaire. */
.pastille-role {
    display: inline-grid;
    place-items: center;
    vertical-align: -.15em;
    margin-left: .3rem;
    width: 1.25em;
    height: 1.25em;
    flex: 0 0 auto;
}
.pastille-role svg { width: 100%; height: 100%; display: block; }
/* Le doré de l'administrateur, le bleu du modérateur : les deux teintes
   que le site emploie déjà pour ces deux rôles ailleurs. */
.pastille-role--admin { color: #d99a12; }
.pastille-role--modo  { color: var(--ride-encre); }
/* Le vert de la confiance : ni doré ni bleu, pour qu'on ne prenne pas
   un contributeur reconnu pour un membre de l'équipe. */
.pastille-role--confiance { color: var(--green); }
:root[data-theme="sombre"] .pastille-role--admin { color: #f0c14b; }
:root[data-theme="sombre"] .pastille-role--confiance { color: #6fce9b; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) .pastille-role--admin { color: #f0c14b; }
    :root:not([data-theme="clair"]) .pastille-role--confiance { color: #6fce9b; }
}

/* --- Les photos d'une fiche de lieu -------------------------------
   La première occupe la place — c'est celle qu'on regarde — les
   suivantes l'accompagnent en colonne. Avec une seule photo, elle
   prend toute la largeur ; l'agencement suit le nombre. */
.photos-lieu {
    display: grid;
    gap: .5rem;
    border-radius: 14px;
    overflow: hidden;
}
.photos-lieu--2 { grid-template-columns: 1fr 1fr; }
.photos-lieu--3 { grid-template-columns: 2fr 1fr; grid-template-rows: 1fr 1fr; }
.photos-lieu--3 .photos-lieu__item:first-child { grid-row: 1 / 3; }

.photos-lieu__item {
    position: relative;
    margin: 0;
    overflow: hidden;
    border-radius: 10px;
    background: var(--surface-2);
}
.photos-lieu__item img {
    display: block;
    width: 100%;
    height: 100%;
    min-height: 150px;
    max-height: 340px;
    object-fit: cover;
    transition: transform .3s ease;
}
.photos-lieu__item:hover img { transform: scale(1.03); }
.photos-lieu--1 .photos-lieu__item img { max-height: 380px; }
.photos-lieu--3 .photos-lieu__item:not(:first-child) img { min-height: 100px; max-height: 165px; }

.photos-lieu__retirer { position: absolute; top: .4rem; right: .4rem; margin: 0; }
.photos-lieu__retirer button {
    width: 26px; height: 26px;
    display: grid; place-items: center;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, .55);
    color: #fff;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}
.photos-lieu__retirer button:hover { background: rgba(190, 60, 48, .9); }

@media (max-width: 575.98px) {
    .photos-lieu--3 { grid-template-columns: 1fr 1fr; grid-template-rows: auto auto; }
    .photos-lieu--3 .photos-lieu__item:first-child { grid-row: auto; grid-column: 1 / 3; }
}

/* La signature d'une fiche : qui l'a créée, qui l'a mise à jour.
   Discrète par construction — c'est un pied de page d'information,
   pas un titre — mais les pseudos ressortent en gras : ce sont les
   deux mots qu'on cherche quand on lit cette ligne. */
.signature-fiche { margin-bottom: 1rem; }
.signature-fiche strong { font-weight: 600; color: var(--text); }
.leaflet-popup-content .signature-fiche strong { color: #1c2b33; }

/* ==========================================================
   Texte sur aplat clair, en thème sombre
   ==========================================================
   En thème sombre, les bleus de marque s'éclaircissent pour
   rester visibles sur fond noir (--blue passe à #5cbdf7). Le
   texte posé dessus, lui, restait blanc : blanc sur bleu
   ciel, c'est 2,08 pour 1 — sous le minimum lisible, et
   nettement pire que le reste du site.

   Sur un aplat clair, le texte est FONCÉ. C'est déjà la règle
   retenue pour la pastille Premium dorée ; elle vaut ici pour
   les mêmes raisons. L'encre foncée sur ces bleus donne 7,8
   pour 1 — largement au-dessus du seuil.

   L'orange de --accent est clair dans les deux thèmes : la
   pastille de notification prend donc la même correction,
   sans condition de thème.
   ========================================================== */
/* Couleur écrite en dur, et non var(--titre) : ce jeton s'éclaircit en
   thème sombre, alors que l'orange du fond, lui, ne change pas. Il
   faut donc un texte foncé dans les DEUX thèmes. */
.notif-pastille { color: #4a1c08; font-weight: 700; }

:root[data-theme="sombre"] .reglages__lien.est-actif,
:root[data-theme="sombre"] .defis-onglets .nav-link.active,
:root[data-theme="sombre"] .profil-action--primaire,
:root[data-theme="sombre"] .profil-action--primaire:hover {
    color: #0b203c;
    font-weight: 600;
}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) .reglages__lien.est-actif,
    :root:not([data-theme="clair"]) .defis-onglets .nav-link.active,
    :root:not([data-theme="clair"]) .profil-action--primaire,
    :root:not([data-theme="clair"]) .profil-action--primaire:hover {
        color: #0b203c;
        font-weight: 600;
    }
}

/* Une pastille de fiche ne déborde jamais de sa carte.
   Filet de sécurité : même avec une valeur inhabituellement longue,
   l'étiquette se replie au lieu de pousser la mise en page vers la
   droite. Sur téléphone, un seul débordement décale toute la page. */
.table-fiche + .badge, .page-card .badge {
    white-space: normal;
    text-align: left;
    max-width: 100%;
}

/* ==========================================================
   Le fond de carte des vignettes de parcours
   ==========================================================
   La carte se glisse SOUS le tracé SVG, qui reste en place :
   il s'affiche instantanément et sert de repli quand les
   tuiles n'arrivent pas. Une fois la carte prête, le SVG
   s'efface — le tracé est alors dessiné par Leaflet, à la
   bonne échelle et au bon endroit.
   ========================================================== */
.carte-parcours__apercu { overflow: hidden; }

.apercu-carte {
    position: absolute;
    inset: 0;
    z-index: 0;
    /* La vignette est une image, pas une carte : aucun geste ne doit
       l'attraper. Le clic traverse jusqu'au lien qui l'entoure. */
    pointer-events: none;
    background: var(--surface-2);
}
.apercu-carte .leaflet-container { background: var(--surface-2); }

/* Le tracé SVG passe au-dessus tant que la carte n'est pas prête… */
.carte-parcours__apercu .apercu-parcours {
    position: relative;
    z-index: 1;
    transition: opacity .25s ease;
}
/* …puis s'efface en douceur quand elle l'est. */
.carte-parcours__apercu.a-sa-carte .apercu-parcours { opacity: 0; }

.carte-parcours__compteur { z-index: 2; }

/* --- Les captures jointes à un signalement ---
   Des vignettes carrées : on doit pouvoir balayer quatre images d'un
   regard, puis ouvrir celle qui compte en grand. */
.preuves-signalement {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}
.preuves-signalement a {
    display: block;
    width: 92px;
    height: 92px;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--border);
    background: var(--surface-2);
}
.preuves-signalement img { width: 100%; height: 100%; object-fit: cover; display: block; }
.preuves-signalement a:hover { border-color: var(--ride); }

/* Le bloc d'actions d'un signalement : détaché de la lecture, mais
   toujours visible — il n'y a rien à déplier pour agir. */
.actions-signalement {
    border-top: 1px solid var(--border);
    padding-top: .9rem;
}

/* --- Rappel de confirmation d'adresse ---
   Un bandeau fin, présent sans être criard : il doit rappeler sans
   donner l'impression que le compte est cassé. */
.rappel-email {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .6rem .9rem;
    padding: .55rem .9rem;
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: 10px;
    background: var(--surface-2);
    font-size: .93rem;
}
.rappel-email__icone {
    flex: none;
    display: inline-flex;
    color: var(--accent);
}
.rappel-email__icone svg { width: 1.25rem; height: 1.25rem; display: block; }
.rappel-email__texte { flex: 1 1 15rem; color: var(--titre); }
.rappel-email__action { margin: 0; flex: none; }
.rappel-email__bouton {
    border: 1px solid var(--accent);
    background: transparent;
    color: var(--accent);
    border-radius: 999px;
    padding: .2rem .8rem;
    font-size: .85rem;
    font-weight: 600;
    cursor: pointer;
}
.rappel-email__bouton:hover,
.rappel-email__bouton:focus-visible {
    background: var(--accent);
    color: #fff;
}

/* --- Fenêtre de confirmation d'adresse --- */
.fenetre-email__adresse {
    font-weight: 600;
    word-break: break-all;
}

/* Le logo remplace le texte sur les écrans de connexion et d'inscription. */

/* ==========================================================
   Photos en grand, bulles au doigt, listes repliées
   ========================================================== */

/* --- La photo en grand --- */
.fenetre-photo {
    position: fixed; inset: 0; z-index: 2000;
    display: none;
    align-items: center; justify-content: center;
    padding: 1.5rem;
    background: rgba(6, 16, 30, .92);
}
.fenetre-photo--ouverte { display: flex; }
.fenetre-photo__cadre { margin: 0; max-width: 100%; max-height: 100%; text-align: center; }
.fenetre-photo__image {
    max-width: 100%; max-height: 82vh;
    border-radius: 10px; box-shadow: 0 20px 60px rgba(0,0,0,.5);
}
.fenetre-photo__legende { margin-top: .8rem; color: #cfe0f2; font-size: .92rem; }
.fenetre-photo__fermer {
    position: absolute; top: .8rem; right: 1rem;
    width: 44px; height: 44px;
    border: none; border-radius: 50%;
    background: rgba(255,255,255,.12); color: #fff;
    font-size: 1.8rem; line-height: 1; cursor: pointer;
}
.fenetre-photo__fermer:hover, .fenetre-photo__fermer:focus-visible {
    background: rgba(255,255,255,.24);
}
body.sans-defilement { overflow: hidden; }

/* Le curseur annonce qu'une image s'ouvre. */
.galerie-photo img, .photo-fiche img, .spot-photo img,
img[data-agrandir], .fiche-photos img, .photos-lieu img { cursor: zoom-in; }

/* --- La bulle, qui marche aussi au doigt --- */
.bulle-flottante {
    /*  Fixe, et non absolue : voir js/interface.js. La bulle se place en
        coordonnées d'écran, sans avoir à deviner quel conteneur défile. */
    position: fixed; z-index: 2100;
    max-width: min(20rem, 90vw);
    padding: .45rem .7rem;
    border-radius: 8px;
    background: var(--titre, #0b203c);
    color: #fff;
    font-size: .82rem; line-height: 1.4;
    text-align: center;
    pointer-events: none;
    opacity: 0; transform: translateY(3px);
    transition: opacity .12s ease, transform .12s ease;
}
.bulle-flottante--visible { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) { .bulle-flottante { transition: none; } }
[data-bulle] { cursor: help; }

/* ==========================================================
   Le bandeau d'information
   ==========================================================
    Une bande pleine largeur, sans marge, collée sous la barre du site :
    c'est ce qui évite la bande blanche du fond de page entre les deux.
    Elle porte sa propre couleur de fond, donc elle se lit aussi bien
    au-dessus d'un grand visuel sombre qu'au-dessus d'une page claire.
   ========================================================== */
.bandeau-info {
    --bandeau-fond: #0f4c75;
    --bandeau-texte: #ffffff;
    background: var(--bandeau-fond);
    color: var(--bandeau-texte);
    border-bottom: 1px solid rgba(255, 255, 255, .15);
}
.bandeau-info__contenu {
    max-width: 1320px;
    margin: 0 auto;
    padding: .7rem 1rem;
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    font-size: .92rem;
    line-height: 1.45;
}
.bandeau-info__signe { flex: none; display: inline-flex; margin-top: .05rem; }

/*  La photo encadrée de l'annuaire : le cadre déborde de la photo, et
 *  sans largeur fixe il repousserait le pseudo à droite de la carte. */
.membre-carte__photo { flex: none; display: inline-flex; width: 56px; justify-content: center; }
.membre-carte__photo .deco { flex: none; }
.bandeau-info__signe svg { width: 1.15rem; height: 1.15rem; display: block; }

.bandeau-info--attention { --bandeau-fond: #8a5a00; }
.bandeau-info--alerte    { --bandeau-fond: #8a2118; }

@media (min-width: 992px) {
    .bandeau-info__contenu { padding-inline: 1.5rem; }
}

/* --- Les listes repliées --- */
.replie { display: none !important; }
.voir-plus {
    display: block;
    margin: .85rem auto 0;
    padding: .35rem 1.1rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--titre);
    font-size: .88rem; font-weight: 600;
    cursor: pointer;
}
.voir-plus:hover, .voir-plus:focus-visible {
    border-color: var(--accent); color: var(--accent);
}

/* ==========================================================
   Ce qui n'est pas sur la carte  (/admin/carte.php)
   ==========================================================
   Une fiche par bloc, empilée sur téléphone, en trois colonnes
   dès qu'il y a la place. On n'utilise pas de tableau : les
   trois colonnes portent ici des PHRASES, et un tableau les
   comprime jusqu'à un mot par ligne sur un écran étroit.
   ========================================================== */
.absents {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .75rem;
}
.absent {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    padding: 1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}
.absent__quoi { display: flex; flex-direction: column; gap: .15rem; }
.absent__nom { font-weight: 600; color: var(--titre); text-decoration: none; }
.absent__nom:hover, .absent__nom:focus-visible { color: var(--accent); text-decoration: underline; }
.absent__sous { font-size: .82rem; color: var(--muted); }
.absent__detail { margin: .35rem 0 0; font-size: .85rem; color: var(--muted); }
.absent__gestes { display: flex; flex-wrap: wrap; gap: .5rem; }
.absent__gestes form { margin: 0; }
.absent__gestes .btn { flex: 1 1 auto; }

@media (min-width: 768px) {
    .absent {
        flex-direction: row;
        align-items: flex-start;
        gap: 1rem;
    }
    /* Le nom d'abord, le motif au milieu — qui prend le plus de
       place parce que c'est lui qu'on est venu lire — les boutons
       en bout de ligne, à largeur fixe pour qu'ils s'alignent
       d'une rangée à l'autre. */
    .absent__quoi   { flex: 0 0 26%; }
    .absent__motif  { flex: 1 1 auto; }
    .absent__gestes { flex: 0 0 11rem; flex-direction: column; }
    .absent__gestes .btn { width: 100%; }
}

/* ==========================================================
   Préparation au Play Store  (/admin/playstore.php)
   ========================================================== */
.ps-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .6rem; }
.ps-ligne { display: flex; gap: .6rem; align-items: flex-start; line-height: 1.45; }
.ps-ligne__marque {
    flex: 0 0 1.4rem;
    height: 1.4rem;
    display: grid;
    place-items: center;
    border-radius: 999px;
    font-size: .8rem;
    font-weight: 700;
    margin-top: .1rem;
}
.ps-ligne--ok .ps-ligne__marque    { background: rgba(46, 139, 87, .16); color: #1f6b40; }
.ps-ligne--souci .ps-ligne__marque { background: rgba(200, 90, 40, .16); color: #a2481c; }
.ps-ligne--info .ps-ligne__marque  { background: var(--surface-2); color: var(--muted); }
.ps-ligne__texte { display: block; font-size: .87rem; color: var(--muted); }
.ps-etapes { padding-left: 1.15rem; display: flex; flex-direction: column; gap: .7rem; }
.ps-etapes li { line-height: 1.5; font-size: .9rem; }
.ps-etapes strong { color: var(--titre); }

:root[data-theme="sombre"] .ps-ligne--ok .ps-ligne__marque    { background: rgba(46, 139, 87, .24); color: #7ed6a4; }
:root[data-theme="sombre"] .ps-ligne--souci .ps-ligne__marque { background: rgba(230, 130, 70, .22); color: #ffb98a; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) .ps-ligne--ok .ps-ligne__marque    { background: rgba(46, 139, 87, .24); color: #7ed6a4; }
    :root:not([data-theme="clair"]) .ps-ligne--souci .ps-ligne__marque { background: rgba(230, 130, 70, .22); color: #ffb98a; }
}

/* ==========================================================
   L'écran des autorisations, au premier lancement
   ==========================================================
   Plein écran et opaque : ce n'est pas une bannière qu'on
   chasse d'un revers de pouce, c'est un moment de la mise en
   route. Deux boutons seulement, et « Plus tard » reste
   parfaitement lisible — un refus discret est un refus qu'on
   n'assume pas.
   ========================================================== */
.bienvenue {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: linear-gradient(160deg, var(--marine) 0%, #123c66 55%, #0f5b96 100%);
    opacity: 1;
    transition: opacity .25s ease;
}
.bienvenue.est-parti { opacity: 0; pointer-events: none; }

.bienvenue__carte {
    width: 100%;
    max-width: 22rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: .85rem;
    color: #fff;
}
.bienvenue__logo {
    width: 88px;
    height: 88px;
    border-radius: 22px;
    filter: drop-shadow(0 12px 26px rgba(0, 0, 0, .35));
    margin-bottom: .35rem;
}
.bienvenue__titre {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 1.45rem;
    margin: 0;
    text-wrap: balance;
}
.bienvenue__texte {
    margin: 0 0 .4rem;
    font-size: .95rem;
    line-height: 1.5;
    color: rgba(255, 255, 255, .88);
}
.bienvenue__oui { min-height: 50px; font-size: 1rem; }
.bienvenue__plus-tard {
    background: none;
    border: 0;
    padding: .5rem 1rem;
    /* Assez visible pour être choisi sans hésiter. Un « plus tard »
       délavé pousse à accepter par défaut, ce qui produit surtout
       des autorisations révoquées le lendemain. */
    color: rgba(255, 255, 255, .82);
    font-size: .92rem;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}
.bienvenue__plus-tard:hover,
.bienvenue__plus-tard:focus-visible { color: #fff; }

.bienvenue__points { display: flex; gap: .4rem; margin-top: .3rem; }
.bienvenue__point {
    width: 7px; height: 7px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .32);
}
.bienvenue__point.est-actif { background: #fff; }

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

/* ==========================================================
   Le bandeau « sortie en cours »
   ==========================================================
   Il apparaît sur TOUTES les pages tant qu'une sortie est
   suivie par le service Android. Le panneau du chronomètre,
   lui, ne vit que sur les trois pages qui savent en lancer
   une : sans ce bandeau, aller voir la communauté ou un spot
   ferait disparaître toute trace d'une sortie qui, elle,
   continue.

   Discret par construction : une ligne, pas un panneau. Il
   doit se remarquer sans jamais gêner la lecture.
   ========================================================== */
.sortie-bandeau {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: 1rem;
    z-index: 1030;

    display: flex;
    align-items: center;
    gap: .7rem;

    max-width: min(26rem, calc(100vw - 1.6rem));
    padding: .55rem .8rem .55rem .7rem;

    background: var(--marine);
    color: #fff;
    border-radius: 999px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .28);

    text-decoration: none;
    line-height: 1.25;
}
.sortie-bandeau:hover,
.sortie-bandeau:focus-visible {
    color: #fff;
    text-decoration: none;
    box-shadow: 0 12px 34px rgba(0, 0, 0, .36);
}
.sortie-bandeau:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

/* La pastille qui bat : le seul mouvement de tout le bandeau, et il
   dit quelque chose de vrai — quelque chose tourne en ce moment. */
.sortie-bandeau__pastille {
    flex: 0 0 auto;
    width: .6rem;
    height: .6rem;
    border-radius: 50%;
    background: #46d17f;
    box-shadow: 0 0 0 0 rgba(70, 209, 127, .7);
    animation: sortie-battement 2s infinite;
}
@keyframes sortie-battement {
    0%   { box-shadow: 0 0 0 0 rgba(70, 209, 127, .6); }
    70%  { box-shadow: 0 0 0 .5rem rgba(70, 209, 127, 0); }
    100% { box-shadow: 0 0 0 0 rgba(70, 209, 127, 0); }
}

.sortie-bandeau__texte {
    display: flex;
    flex-direction: column;
    min-width: 0;
    /* Prend toute la place restante : sans ça, le chevron se colle au
       texte au lieu de tenir le bord droit, et le bandeau a l'air mal
       terminé. */
    flex: 1 1 auto;
}
.sortie-bandeau__titre {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .01em;
}
.sortie-bandeau__chiffres {
    font-size: .8rem;
    opacity: .85;
    /* Les chiffres ne doivent pas danser d'une seconde à l'autre. */
    font-variant-numeric: tabular-nums;
}
.sortie-bandeau__aller {
    flex: 0 0 auto;
    font-size: 1.3rem;
    opacity: .6;
    padding-right: .2rem;
}

/* Le bandeau flotte au-dessus de la page : on rend au contenu la
   hauteur qu'il lui prend, sinon le dernier champ d'un formulaire ou
   le dernier bouton d'une liste finit caché dessous. */
body.a-sortie-en-cours { padding-bottom: 4.25rem; }

/* Arrivé : le bandeau passe au vert et la pastille cesse de battre —
   il n'y a plus rien à attendre, il reste à terminer. */
.sortie-bandeau.est-arrive { background: #16794f; }
.sortie-bandeau.est-arrive .sortie-bandeau__pastille {
    animation: none;
    background: #fff;
}
.sortie-bandeau.est-arrive .sortie-bandeau__titre::after {
    content: ' · arrivé 🏁';
    font-weight: 400;
}

@media (prefers-reduced-motion: reduce) {
    .sortie-bandeau__pastille { animation: none; }
}
