/* Surcharge de la palette Pico.css.
 *
 * Chargé après pico.classless.min.css (voir base.html) : les variables ci-dessous
 * remplacent celles du thème clair de Pico. Fond allégé (#F4F6F5, quasi-blanc à
 * peine bleuté) depuis la refonte graphique de l'accueil/bandeau/pied de page
 * (maquette validée par l'utilisateur, 2026-08-05) — l'ancien fond plein
 * #DAE5ED devient --qvq-carte-tint (voir plus bas), réutilisé comme teinte
 * d'accent sur des zones ponctuelles (bandeau, encarts) plutôt que sur toute la
 * page : continuité de marque, pas une rupture de palette.
 *
 * Contrastes vérifiés par calcul de luminance relative WCAG 2.x par rapport au
 * NOUVEAU fond #F4F6F5 (recalculés à cette occasion, l'ancien calcul contre
 * #DAE5ED n'est plus la référence) :
 *   - --pico-color (texte principal, hérité de Pico, pas touché) : 15,17:1.
 *   - --pico-muted-color (texte secondaire : footer, pagination) : #4b5a63,
 *     6,58:1 — toujours largement AA malgré un fond plus clair.
 *   - --pico-primary (couleur des liens) : unifié sur le bleu marine
 *     institutionnel de la refonte (--qvq-marine, #1f3a5c, 10,64:1) plutôt que
 *     l'ancien #015887 — un seul bleu d'accent sur tout le site désormais,
 *     partagé avec les nouveaux composants (masthead, hero...).
 *
 * Sélecteur `:root:not([data-theme="dark"])` et non `[data-theme="light"]` :
 * c'est la portée qui couvre aussi le cas où le <html> ne porte AUCUN
 * attribut `data-theme` — donc le cas sans JavaScript, où l'on veut ce fond
 * clair. En pratique `site/js/theme.js` pose toujours "light" ou "dark" (le
 * mode automatique y est résolu en JavaScript, cf. son commentaire) : le
 * sélecteur large ne sert plus que de filet de sécurité.
 */
:root:not([data-theme="dark"]) {
    --pico-background-color: #F4F6F5;
    --pico-muted-color: #4b5a63;
    --pico-primary: #1f3a5c;
    --pico-primary-background: #1f3a5c;
    --pico-primary-underline: rgba(31, 58, 92, 0.5);
    --pico-primary-hover: #14283f;
    --pico-primary-hover-background: #14283f;
    --pico-primary-focus: rgba(31, 58, 92, 0.5);
}

/* --- Tokens de la refonte graphique (accueil, bandeau, pied de page) ---
 * Espace de noms --qvq- distinct de --pico- : composants propres au site,
 * pas une surcharge du thème Pico. Polices en pile système (pas de webfont à
 * embarquer, cohérent avec l'absence de pipeline de build du projet — voir
 * CLAUDE.md) : une sérif à caractère pour les titres (ton éditorial/
 * institutionnel), une sans-serif système pour le texte courant (déjà géré
 * par Pico via --pico-font-family, pas dupliqué ici), une monospace pour les
 * chiffres/dates/libellés techniques (nombres tabulaires alignés en colonne).
 * Couleurs vérifiées WCAG 2.x contre --pico-background-color (#F4F6F5) ET
 * --qvq-carte-tint (#DCE6ED, fond des encarts) :
 *   - --qvq-marine (texte/liens) : 10,64:1 / 9,12:1.
 *   - --qvq-encre-douce (texte secondaire) : 6,58:1 / 5,64:1.
 *   - --qvq-or : 3,69:1 sur #F4F6F5 — sous le seuil AA texte (4,5:1), donc
 *     jamais utilisé comme couleur de texte ; réservé aux accents graphiques
 *     (puces, contours, dégradé du spectre politique), qui ne demandent que
 *     3:1 (WCAG 1.4.11, composants non textuels).
 */
:root {
    --qvq-police-affichage: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Georgia, serif;
    --qvq-police-donnees: "SF Mono", "Cascadia Code", "Consolas", ui-monospace, monospace;
    --qvq-encre-douce: #4b5a63;
    --qvq-marine: #1f3a5c;
    --qvq-marine-forte: #14283f;
    --qvq-or: #9c7a34;
    --qvq-ligne: #c7d2d3;
    --qvq-carte-tint: #dce6ed;
    /* Encre posée SUR un aplat d'accent (--qvq-marine). Elle suit l'aplat et
     * non le thème, sinon le texte disparaît dès que l'un des deux bascule :
     * c'est exactement ce qui rendait les boutons « Rechercher », « Où suis-je
     * ? » et la puce d'échelon active illisibles en thème sombre. */
    --qvq-sur-accent: #f4f6f5;
    /* Pico compose ses boutons avec ce token ; sa valeur par défaut est
     * `#fff` dans les deux thèmes, ce qui ne va pas dès lors qu'on éclaircit
     * le fond d'accent en thème sombre (voir plus bas). */
    --pico-primary-inverse: #f4f6f5;
}

/* --- Variante sombre ---
 * Passés en thème sombre, on ne peut pas se contenter d'enlever l'ancien
 * `data-theme="light"` (choix d'avant, cf. commentaire du bloc Pico en haut
 * de ce fichier) : il faut redéfinir chaque token dont la valeur claire
 * n'est pas lisible sur fond sombre. Ce bloc et le bloc clair ci-dessus sont
 * donc les deux seules sources de palette du site ; `site/js/theme.js` pose
 * `data-theme="dark"` pour le choix explicite du visiteur comme pour le mode
 * automatique sous un système sombre, ce qui évite d'avoir à dupliquer cette
 * liste dans un `@media (prefers-color-scheme: dark`) — Pico n'appliquant sa
 * propre palette sombre qu'à `:root:not([data-theme])`, de spécificité égale
 * mais dans une feuille chargée avant la nôtre : il l'écrasait en mode auto.
 * Contraste recalculé (luminance relative WCAG 2.x) contre le fond #121a1e ET
 * le fond d'encart #1b262c :
 *   - --pico-primary / --qvq-marine (liens, titres d'encart) : 10,24:1 / 8,97:1.
 *   - --pico-muted-color / --qvq-encre-douce (texte secondaire) : 8,16:1 / 7,15:1.
 *   - --qvq-or : 8,39:1 / 7,35:1 — en clair il était à 3,69:1, sous le seuil
 *     AA texte, d'où son usage réservé aux accents graphiques ; en sombre il
 *     devient franchement lisible, on le garde donc strictement au même
 *     usage (aucun texte n'y est écrit).
 *   - --qvq-ligne (filets) : 1,50:1 — décoratif, comme les filets clairs.
 */
:root[data-theme="dark"] {
    --pico-background-color: #121a1e;
    --pico-card-background: #1b262c;
    --pico-muted-color: #a3b3bb;
    --pico-primary: #a9c9e8;
    --pico-primary-background: #a9c9e8;
    --pico-primary-underline: rgba(169, 201, 232, 0.5);
    --pico-primary-hover: #cfe2f5;
    --pico-primary-hover-background: #cfe2f5;
    --pico-primary-focus: rgba(169, 201, 232, 0.5);

    --qvq-encre-douce: #a3b3bb;
    --qvq-marine: #a9c9e8;
    --qvq-marine-forte: #cfe2f5;
    --qvq-or: #d3ae63;
    --qvq-ligne: #2c3a41;
    --qvq-carte-tint: #1b262c;
    /* Le fond d'accent sombre du projet est un bleu CLAIR (#a9c9e8, au lieu
     * du bleu soutenu de Pico) : le texte des boutons doit donc être sombre,
     * sans quoi ils sont blancs sur clair — 1,6:1, illisibles. Ces deux tokens
     * corrigeaient tous les boutons du site en thème sombre, pas seulement
     * ceux de la carte. Contraste vérifié : 10,5:1 (#0f1a20 sur #a9c9e8). */
    --pico-primary-inverse: #0f1a20;
    --qvq-sur-accent: #0f1a20;
}

/* --- Bandeau (masthead) : remplace le <nav> Pico par défaut, voir base.html ---
 * Centré, wordmark en sérif d'affichage + sous-titre technique en majuscules
 * espacées, puis une seconde ligne de navigation ("rubriques") — plutôt que le
 * <nav> gauche/droite par défaut de Pico classless, jugé trop "app" pour un
 * site de transparence institutionnelle. */
.masthead {
    text-align: center;
    padding: 2rem 0 0.9rem;
    border-bottom: 3px double var(--qvq-ligne);
}

.masthead .marque {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    text-decoration: none;
    color: inherit;
}

.masthead .marque img {
    align-self: center;
}

.masthead .nom {
    font-family: var(--qvq-police-affichage);
    font-size: clamp(1.7rem, 4vw, 2.3rem);
    font-weight: 600;
    letter-spacing: 0.01em;
    margin: 0;
}

.masthead .dateline {
    font-family: var(--qvq-police-donnees);
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--qvq-encre-douce);
    margin: 0.4rem 0 0;
}

.rubriques {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 1.75rem;
    padding: 0.8rem 0;
    border-bottom: 1px solid var(--qvq-ligne);
    font-size: 0.92rem;
}

.rubriques a { text-decoration: none; }
.rubriques a:hover { color: var(--qvq-marine); }

/* --- Pied de page ---
 * Disposition en deux colonnes (mentions à gauche, sélecteur de thème à
 * droite) : `flex-wrap` fait passer le sélecteur sous les mentions sur
 * mobile, sans media query. */
footer.pied-de-page {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem 1.5rem;
    margin-top: 2.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--qvq-ligne);
    color: var(--qvq-encre-douce);
    font-size: 0.85rem;
}

footer.pied-de-page small {
    flex: 1 1 22rem;
}

/* Sélecteur de thème : au fil du texte des mentions, pas dans le bandeau —
 * voir le commentaire de base.html. Pico dessine un <select> assez lourd
 * (fond, bordure basse, flèche) : on le ramène à la taille du texte
 * secondaire du pied de page, police de données comme le reste des libellés
 * techniques du site. `width: auto` : Pico impose une largeur de 100% aux
 * formulaires, hors sujet ici. */
.choix-theme {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    white-space: nowrap;
}

.choix-theme > span {
    font-family: var(--qvq-police-donnees);
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.choix-theme select {
    width: auto;
    margin: 0;
    padding: 0.15rem 2.1rem 0.15rem 0.7rem;
    border: 1px solid var(--qvq-ligne);
    border-radius: 999px;
    background-color: transparent;
    color: inherit;
    font-family: var(--qvq-police-donnees);
    font-size: 0.75rem;
}

/* --- Hero d'accueil : recherche par circonscription + carte, voir accueil.html ---
 * La carte (fragment site/_widget_recherche_circonscription.html, partagée
 * avec recherche_circonscription.html) est mise en avant ici sur demande
 * explicite de l'utilisateur après comparaison de plusieurs maquettes — d'où
 * .panneau-carte qui l'habille (fond marine, coins arrondis, ombre légère),
 * absent de la page /circonscriptions/ dédiée qui n'en a pas besoin (déjà
 * pleine page). */
.hero-carte {
    display: grid;
    grid-template-columns: 1fr 1.05fr;
    gap: 2.5rem;
    align-items: center;
    padding: 2.25rem 0 2.5rem;
    border-bottom: 1px solid var(--qvq-ligne);
}

.hero-carte .eyebrow {
    font-family: var(--qvq-police-donnees);
    font-size: 0.7rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--qvq-encre-douce);
    margin: 0 0 0.6rem;
}

.hero-carte h1 {
    font-family: var(--qvq-police-affichage);
    font-size: clamp(1.9rem, 3.6vw, 2.5rem);
    line-height: 1.15;
    margin: 0 0 0.8rem;
    text-wrap: balance;
    font-weight: 600;
}

.hero-carte p.chapo {
    font-size: 1.02rem;
    color: var(--qvq-encre-douce);
    max-width: 32rem;
    margin: 0 0 1.3rem;
}

.hero-carte .hero-micro {
    margin-top: 0.7rem;
    font-size: 0.85rem;
    color: var(--qvq-encre-douce);
}

.panneau-carte {
    border-radius: var(--pico-border-radius);
    overflow: hidden;
    box-shadow: 0 1.5rem 3rem -1.75rem rgba(20, 40, 63, 0.45);
}

/* La carte de l'accueil est celle de la page « Trouver mes élus », en plus
 * petit : elle accompagne l'accroche, elle n'est pas l'objet de la page. Sa
 * hauteur a été relevée de 26 à 34 rem — jugée trop petite pour servir d'appel
 * à l'action — tout en restant bornée à la fenêtre, pour que la fiche de
 * résultat juste en dessous ne soit pas repoussée hors de l'écran. */
.panneau-carte [data-carte-circonscriptions] {
    height: min(34rem, 62vh);
    min-height: 22rem;
}

/* --- Panneaux posés SUR la carte (puces de niveau, légende, popup) ---
 * `.carte-zone` est le repère de positionnement : les trois panneaux en sont
 * des frères du conteneur Leaflet, absolus, donc jamais rognés par
 * `.panneau-carte` (`overflow: hidden`, accueil) ni déplacés par les
 * translations Leaflet lors d'un zoom. */
.carte-zone {
    position: relative;
}

/* Puces de niveau : seul contrôle de l'échelon affiché, désormais sur tous
 * les écrans (le <select> de la barre d'outils, qui les doublait, a été
 * supprimé). Fond translucide plutôt que plein : la carte reste lisible
 * dessous. */
.carte-puces {
    position: absolute;
    z-index: 500;
    top: 0.5rem;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.25rem;
    max-width: calc(100% - 1rem);
    margin: 0;
    padding: 0.25rem;
    background: color-mix(in srgb, var(--pico-background-color) 88%, transparent);
    border-radius: var(--pico-border-radius);
    border: 1px solid var(--qvq-ligne);
}

.carte-puces button {
    margin: 0;
    padding: 0.15rem 0.55rem;
    font-size: 0.72rem;
    line-height: 1.5;
    border: 1px solid transparent;
    border-radius: 0.6rem;
    background: transparent;
    color: var(--qvq-encre-douce);
    cursor: pointer;
}

.carte-puces button[aria-checked="true"] {
    background: var(--qvq-marine);
    border-color: var(--qvq-marine);
    /* `--qvq-sur-accent` et non un blanc figé : en thème sombre, `--qvq-marine`
     * est un bleu clair, sur lequel un texte clair était invisible. */
    color: var(--qvq-sur-accent);
    font-weight: 600;
}

.carte-puces button:hover:not([aria-checked="true"]) {
    background: var(--qvq-carte-tint);
}

/* Pico utilise `--pico-primary-hover` pour le texte des boutons **et** pour
 * la couleur des liens au survol. En thème sombre, ce token est un bleu clair
 * pensé pour les liens : laissé tel quel, le survol d'un bouton rendait son
 * texte clair sur fond clair. On ne le corrige donc que pour les boutons, où
 * le texte suit l'encre d'accent. */
button:is(:hover, :active, :focus),
[role="button"]:is(:hover, :active, :focus),
[type="submit"]:is(:hover, :active, :focus) {
    --pico-color: var(--pico-primary-inverse);
}

/* Légende : le filtre par parti est la liste elle-même (chaque ligne est un
 * bouton), donc pas de contrôle séparé à maintenir en plus. Son titre est
 * lui-même le repli/dépliage — sur téléphone, la liste ouverte masquait la
 * moitié de la carte, et une carte qu'on ne voit plus ne sert plus à filtrer. */
.carte-legende {
    position: absolute;
    z-index: 500;
    bottom: 0.5rem;
    left: 0.5rem;
    max-width: 15rem;
    padding: 0.4rem 0.5rem;
    font-size: 0.72rem;
    background: color-mix(in srgb, var(--pico-background-color) 90%, transparent);
    border: 1px solid var(--qvq-ligne);
    border-radius: var(--pico-border-radius);
}

.carte-legende-titre {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    width: 100%;
    margin: 0;
    padding: 0;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--qvq-encre-douce);
    background: none;
    border: none;
    text-align: left;
}

.carte-legende-titre:hover {
    color: var(--pico-color);
}

.carte-legende-indice {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--pico-primary);
}

.carte-legende-corps {
    margin-top: 0.25rem;
}

.carte-legende ul {
    margin: 0;
    padding: 0;
    list-style: none;
    /* Douze partis (échelon « circonscriptions ») débordent la carte : la
     * liste défile dans sa boîte plutôt que de la recouvrir. Sept lignes
     * environ : au-delà, la légende prenait la moitié de la carte de
     * l'accueil, dont la seule fonction est de donner envie de cliquer. */
    max-height: 7rem;
    overflow-y: auto;
}

.carte-legende-parti {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    width: 100%;
    margin: 0;
    padding: 0.1rem 0.15rem;
    font-size: 0.72rem;
    background: none;
    border: none;
    color: inherit;
    cursor: pointer;
    text-align: left;
}

/* Ligne désactivée : la pastille se vide et le nom passe en discret — le
 * territoire reste dessiné mais presque transparent. */
.carte-legende-parti[aria-pressed="false"] {
    opacity: 0.45;
}

/* Parti sans aucun territoire en tête dans la zone : rien à filtrer. */
.carte-legende-parti:disabled {
    cursor: default;
}

.carte-legende-parti:hover:not(:disabled) {
    background: var(--qvq-carte-tint);
}

.carte-legende-nom {
    font-weight: 600;
}

.carte-legende-compte {
    color: var(--qvq-encre-douce);
}

.carte-legende-tout {
    margin: 0.25rem 0 0;
    padding: 0.1rem 0.4rem;
    font-size: 0.7rem;
    border: 1px solid var(--qvq-ligne);
}

/* Pastille de parti : la couleur vient des données (`--parti-couleur` posé
 * par le JS), donc les mêmes teintes que l'hémicycle et la liste des élus. */
.pastille-parti {
    display: inline-block;
    flex: 0 0 auto;
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 50%;
    background: var(--parti-couleur, var(--qvq-encre-douce));
    border: 1px solid rgba(0, 0, 0, 0.15);
}

/* --- Fiche de résultat, dans le flux de la page ------------------------
 *
 * Elle remplace le panneau flottant (coin de l'écran sur desktop, bandeau en
 * bas sur mobile) et la popup au-dessus de la carte : un seul bloc, toujours
 * au même endroit, jamais recouvert par la carte ni rogné par elle. L'ordre
 * de lecture devient « je cherche, je regarde sur la carte, je lis ma fiche ».
 */
.fiche-territoire {
    position: relative;
    /* La carte occupe toute la largeur de la fenêtre : la fiche, elle, reste
     * sur une largeur de lecture. Une liste de 200 élus sur 1 900 px serait
     * impossible à parcourir d'un œil à l'autre. */
    max-width: 70rem;
    margin: 1.5rem auto 0;
    padding: 1.25rem 1.5rem 1.5rem;
    background: var(--pico-card-background);
    border: 1px solid var(--qvq-ligne);
    border-radius: var(--pico-border-radius);
    /* Marge de défilement : sans elle, le titre du résultat se retrouve collé
     * sous le bord de la fenêtre après le `scrollIntoView`. */
    scroll-margin-top: 1rem;
}

/* Le lieu résolu, sous le titre de la fiche : c'est la réponse à « où suis-je
 * ? », et la seule ligne qui relie le nom de la circonscription à un point
 * connu du visiteur. */
.fiche-lieu {
    margin: 0 0 0.75rem;
    font-size: 0.95rem;
    color: var(--qvq-encre-douce);
}

.fiche-territoire:focus-visible {
    outline: 2px solid var(--pico-primary-focus);
    outline-offset: 2px;
}

.fiche-territoire-barre {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
}

.fiche-territoire-barre button {
    margin: 0;
    padding: 0.15rem 0.5rem;
    font-size: 1rem;
    line-height: 1;
    background: none;
    border: none;
    color: var(--qvq-encre-douce);
    cursor: pointer;
}

.fiche-territoire-entete {
    margin-bottom: 0.75rem;
    padding-right: 2rem;
}

.fiche-territoire-niveau {
    margin: 0;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--qvq-encre-douce);
}

.fiche-territoire h2 {
    margin: 0.1rem 0 0;
    font-size: 1.5rem;
    line-height: 1.2;
}

.fiche-bloc {
    margin: 1.25rem 0;
}

.fiche-bloc h3 {
    margin: 0 0 0.35rem;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--qvq-encre-douce);
}

.fiche-elus {
    margin: 0;
    padding: 0;
    list-style: none;
}

.fiche-elus li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0;
    border-bottom: 1px solid var(--qvq-ligne);
}

.fiche-parti {
    font-size: 0.78rem;
    color: var(--qvq-encre-douce);
}

.fiche-territoire-pied {
    margin-top: 1.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--qvq-ligne);
}

.fiche-chargement,
.fiche-vide,
.fiche-territoire-erreur {
    margin: 0.2rem 0;
    font-size: 0.85rem;
    color: var(--qvq-encre-douce);
}

/* Petits écrans : la légende se resserre en bas de carte (le contrôle de zoom
 * est en haut à droite) et se replie d'elle-même — les puces, elles, disparaissent
 * : le <select> de la barre d'outils fait le même office (voir plus bas). */
@media (max-width: 700px) {
    /* Repliée, la légende doit tenir sur **une** ligne : c'est le seul élément
     * que l'on garde par-dessus la carte, et un intitulé sur trois lignes
     * mange autant de place que la carte. */
    .carte-legende {
        max-width: 14rem;
        font-size: 0.68rem;
    }

    .carte-legende-titre {
        font-size: 0.62rem;
    }
}

/* Les couleurs de contour sont portées par les expressions `fill-color` du
 * style MapLibre (voir carte-circonscriptions.js), à partir de la colonne
 * `parti_couleur` : aucune couleur de tracé n'est définie ici. Le fond raster,
 * lui, est inversé en thème sombre (cf. `.maplibregl-canvas` plus bas). */


/* Message d'état de la carte (role="status") : vide la plupart du temps, il ne
 * prend de la place que lorsqu'il a quelque chose à dire (chargement, échec,
 * résultat). `min-height` évite que la barre d'outils remonte à chaque
 * apparition/disparition du texte. */
.carte-message {
    margin: 0;
    padding: 0 0.6rem;
    font-size: 0.78rem;
    color: var(--qvq-encre-douce);
    min-height: 1.2em;
}


/* Recherche et page « Trouver mes élus ».
 *
 * L'ordre visuel suit l'ordre d'usage : on dit ce qu'on cherche (formulaire),
 * on regarde (carte), on lit (fiche, plus bas). */
.recherche-territoire {
    display: grid;
    gap: 0.6rem;
    margin: 0 0 1rem;
}

/* Le libellé est une vraie étiquette reliée au champ par `for` : le texte
 * d'aide qui suivait expliquait la saisie, pas le label. */
.recherche-libelle {
    display: block;
    margin-bottom: 0.3rem;
    font-size: 0.82rem;
    font-weight: 600;
}

/* Champ et bouton de validation sur la MÊME ligne : c'est là qu'on le cherche
 * après avoir tapé. `min-width: 0` sur le champ est ce qui permet à la ligne
 * de rétrécir sur téléphone au lieu de faire passer le bouton à la ligne. */
.recherche-ligne {
    display: flex;
    gap: 0.5rem;
}

.recherche-ligne input {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
}

.recherche-ligne button {
    flex: 0 0 auto;
    width: auto;
    margin: 0;
}

.recherche-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.recherche-actions button {
    flex: 0 0 auto;
    width: auto;
    margin: 0;
    font-size: 0.85rem;
}


/* Suggestions : groupes repliables (les communes sont nombreuses) dans une
 * boîte bornée, pour ne pas pousser la carte hors de l'écran. */
#suggestions {
    margin-bottom: 1rem;
}

.suggestions-groupe {
    margin: 0 0 0.5rem;
    padding: 0.35rem 0.6rem;
    background: var(--qvq-carte-tint);
    border-radius: var(--pico-border-radius);
    max-height: 15rem;
    overflow-y: auto;
}

.suggestions-groupe summary {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    cursor: pointer;
}

.suggestions-groupe ul {
    margin: 0.3rem 0 0;
    padding: 0;
    list-style: none;
    font-size: 0.88rem;
}

.suggestions-groupe li {
    padding: 0.1rem 0;
}

.suggestions-rien {
    margin: 0 0 0.5rem;
    padding: 0.5rem 0.6rem;
    font-size: 0.85rem;
    background: var(--qvq-carte-tint);
    border-radius: var(--pico-border-radius);
}

.page-entete {
    max-width: 46rem;
    margin-bottom: 1.5rem;
}

.page-entete .chapo {
    margin: 0.5rem 0 0;
    font-size: 1.02rem;
    color: var(--qvq-encre-douce);
}

/* Carte de la page « Trouver mes élus » : sortie de la gouttière du conteneur
 * et nettement plus haute que le bandeau de repérage qu'elle était (440 px).
 * La hauteur reste bornée à la fenêtre : au-delà, la fiche de résultat passe
 * si bas qu'un clic sur la carte exigeait de faire défiler pour la voir.
 * `100vw` inclut la barre de défilement verticale, d'où le `overflow-x: clip`
 * plus bas — sans lui, la page débordait horizontalement d'une largeur de
 * barre de défilement. */
.carte-pleine-largeur {
    width: 100vw;
    margin-left: calc(50% - 50vw);
}

.carte-pleine-largeur [data-carte-circonscriptions] {
    height: min(76vh, 44rem);
    min-height: 26rem;
}

/* `clip` et non `hidden` : ce dernier transformerait `body` en conteneur de
 * défilement et neutraliserait le `position: sticky` du formulaire, qui est
 * ce qui permet de changer d'échelle sans remonter la page sur téléphone. */
body {
    overflow-x: clip;
}
.carte-pleine-largeur {
    width: 100vw;
    margin-left: calc(50% - 50vw);
}

.carte-pleine-largeur [data-carte-circonscriptions] {
    height: min(76vh, 44rem);
    min-height: 26rem;
}

.page-suite {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin-top: 2rem;
    padding-top: 1rem;
    border-top: 1px solid var(--qvq-ligne);
    font-size: 0.9rem;
}

/* Téléphone : la carte occupe la moitié de l'écran, la fiche reste visible
 * en dessous, et le formulaire colle en haut — seul moyen de changer
 * d'échelle sans remonter la page. */
@media (max-width: 700px) {
    .carte-pleine-largeur [data-carte-circonscriptions] {
        height: 56vh;
        min-height: 20rem;
    }

    /* Les puces de niveau restent affichées sur téléphone : le <select> qui
     * les doublait a été supprimé, ce sont donc le seul contrôle de l'échelon.
     * Elles se resserrent pour tenir sur une ou deux lignes — la carte occupe
     * 56vh, donc une rangée de plus ne lui coûte rien — et restent en haut,
     * la légende (repliée) occupant le bas. */
    .carte-puces {
        max-width: calc(100% - 0.5rem);
        padding: 0.2rem;
    }

    .carte-puces button {
        padding: 0.15rem 0.4rem;
        font-size: 0.68rem;
    }

    .fiche-territoire {
        padding: 1rem 1rem 1.25rem;
    }

    .recherche-territoire {
        position: sticky;
        top: 0;
        z-index: 400;
        padding: 0.5rem 0;
        background: var(--pico-background-color);
    }
}

/* Contrôles MapLibre : anneau de focus visible. Pico ne les style pas (ils sont
 * hors du HTML sémantique) et MapLibre ne le fournit pas sur ses boutons, donc
 * un visiteur au clavier ne voyait pas où il se trouve dans la barre de zoom. */
.maplibregl-ctrl-group button:focus-visible,
.maplibregl-ctrl-attrib a:focus-visible {
    outline: 2px solid var(--pico-primary-focus);
    outline-offset: 2px;
}

/* Infobulle de territoire au survol : le nom vient de la propriété `libelle`
 * des contours (voir carte-circonscriptions.js). Fond opaque pour rester
 * lisible sur les tuiles claires comme sur celles, inversées, du thème
 * sombre. */
.carte-infobulle {
    position: absolute;
    z-index: 600;
    display: flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.45rem;
    font-size: 0.75rem;
    white-space: nowrap;
    pointer-events: none;
    background: var(--pico-background-color);
    color: var(--pico-color);
    border: 1px solid var(--qvq-ligne);
    border-radius: 0.4rem;
    box-shadow: 0 2px 6px rgba(20, 40, 63, 0.25);
}

/* Barre d'échelle : lisible sur les tuiles claires de l'IGN. */
.maplibregl-ctrl-scale {
    background: rgba(255, 255, 255, 0.75);
    border-color: #1f3a5c;
    color: #1f3a5c;
}

/* Thème sombre : les tuiles raster de l'IGN n'existent qu'en version claire,
 * d'où une limite assumée — la carte reste claire sur une page sombre.
 *
 * La version Leaflet inversait le calque de tuiles, pas celui des contours ;
 * ce n'est plus possible ici, MapLibre dessinant fond **et** territoires dans
 * un seul canvas : inverser le canvas inverserait aussi les couleurs
 * politiques, qui sont précisément ce que la carte doit montrer fidèlement.
 * Une carte claire vaut mieux que des couleurs de parti fausses. Un fond
 * vectoriel, qui existe en palette sombre, lèverait la limite — voir
 * docs/architecture.md. */

:root[data-theme="dark"] .maplibregl-ctrl-attrib,
:root[data-theme="dark"] .maplibregl-ctrl-scale {
    background: rgba(18, 26, 30, 0.8);
    color: #dce6ed;
    border-color: #2b3a43;
}

:root[data-theme="dark"] .maplibregl-ctrl-group {
    background: #1b262c;
}

:root[data-theme="dark"] .maplibregl-ctrl-group button + button {
    border-top-color: #2b3a43;
}

:root[data-theme="dark"] .maplibregl-ctrl-group button .maplibregl-ctrl-icon {
    filter: invert(1);
}

/* --- Grille éditoriale contenu + colonne latérale : introduite pour
 * l'accueil ("à la une" + fil / encarts), réutilisée telle quelle sur les
 * fiches détail (élu/loi) pour leur propre colonne latérale (identité/stats,
 * résultat/auteurs) plutôt que dupliquer ratio+gap+breakpoint. */
.grille-deux-colonnes {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 3rem;
}

/* Respiration avant la grille éditoriale : sur l'accueil, la fiche de résultat
 * se referme juste au-dessus d'elle, et les deux se lisaient comme un seul
 * bloc — d'où l'impression qu'ils n'étaient « pas assez séparés ». */
.fiche-territoire:not([hidden]) + .grille-deux-colonnes {
    margin-top: 3.5rem;
}

.une h2 {
    font-family: var(--qvq-police-affichage);
    font-size: clamp(1.6rem, 3vw, 2.1rem);
    line-height: 1.18;
    margin: 0.7rem 0 0.8rem;
    text-wrap: balance;
    font-weight: 600;
}

.une p.chapo {
    font-size: 1.02rem;
    color: var(--qvq-encre-douce);
    max-width: 40rem;
    margin: 0 0 0.8rem;
}

.une .meta {
    font-family: var(--qvq-police-donnees);
    font-size: 0.8rem;
    color: var(--qvq-encre-douce);
}

.fil { margin-top: 2.25rem; }

.fil h2 {
    font-family: var(--qvq-police-affichage);
    font-size: 1.05rem;
    font-weight: 600;
    margin: 0 0 0.5rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--qvq-ligne);
}

.fil-item {
    display: grid;
    grid-template-columns: 5.5rem 1fr auto;
    gap: 1rem;
    align-items: baseline;
    padding: 0.85rem 0;
    border-top: 1px solid var(--qvq-ligne);
    text-decoration: none;
    color: inherit;
}

.fil-item:first-child { border-top: none; }

.fil-item time {
    font-family: var(--qvq-police-donnees);
    font-size: 0.78rem;
    color: var(--qvq-encre-douce);
    font-variant-numeric: tabular-nums;
}

.fil-item:hover .titre-loi { color: var(--qvq-marine); }

.fil-item .meta {
    font-size: 0.78rem;
    color: var(--qvq-encre-douce);
    white-space: nowrap;
}

.encart {
    border: 1px solid var(--qvq-ligne);
    border-radius: var(--pico-border-radius);
    padding: 1.25rem 1.3rem;
    background: var(--qvq-carte-tint);
}

.encart h2 {
    font-family: var(--qvq-police-affichage);
    font-size: 1.1rem;
    margin: 0 0 0.7rem;
    font-weight: 600;
}

/* Second niveau à l'intérieur d'un h2 sur deux lignes (ex: "Scrutins" /
 * "toutes législatures" sur elu_detail.html) : plus petit et moins appuyé
 * que la ligne principale, sans être une définition de champ (dl.definitions
 * dt, plus bas) ni un nouveau titre de section. */
.encart-sous-titre {
    display: block;
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--qvq-encre-douce);
}

.encart + .encart { margin-top: 1.75rem; }

.chiffres-encart dl {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin: 0;
    padding: 0.5rem 0;
    border-top: 1px solid var(--qvq-ligne);
}

.chiffres-encart dl:first-of-type { border-top: none; padding-top: 0; }
.chiffres-encart dt { font-size: 0.85rem; color: var(--qvq-encre-douce); }
.chiffres-encart dd {
    margin: 0;
    font-family: var(--qvq-police-donnees);
    font-size: 1.02rem;
    font-variant-numeric: tabular-nums;
}
/* Un pourcentage ne se coupe pas ("25,0" / "%") : c'est le libellé (dt),
 * plus long, qui passe à la ligne dans l'encart étroit desktop. Pas les
 * paragraphes de dl.definitions ci-dessous. */
.chiffres-encart dl:not(.definitions) dd {
    white-space: nowrap;
    padding-left: 0.5rem;
}

/* Définitions de champs (ex: "Absent (officiel)"/"Taux d'absence (déduit)"
 * sur elu_detail.html, section AN) : un vrai <dl> terme/explication (dt
 * au-dessus, dd — un paragraphe — en dessous), pas la ligne étiquette:valeur
 * en flex de .chiffres-encart dl ci-dessus (pensée pour un nombre sur une
 * ligne, pas un paragraphe) — d'où l'override display:block ici. Même
 * langage visuel que .encart-info plus bas (étiquette discrète en
 * majuscules) plutôt qu'un 3e style de dl sur le site. */
.chiffres-encart dl.definitions {
    display: block;
    border-top: 1px solid var(--qvq-ligne);
    padding-top: 0.75rem;
    margin-top: 0.5rem;
}
.chiffres-encart dl.definitions dt {
    font-family: var(--qvq-police-donnees);
    font-size: 0.72rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--qvq-encre-douce);
    margin: 0 0 0.2rem;
}
.chiffres-encart dl.definitions dd {
    margin: 0 0 1rem;
    font-family: inherit;
    font-size: 0.9rem;
    font-variant-numeric: normal;
    color: var(--qvq-encre-douce);
}
.chiffres-encart dl.definitions dd:last-child { margin-bottom: 0; }

/* --- Spectre politique : un repère graphique, pas décoratif — chaque segment
 * représente un parti actuel réel (voir AccueilView.get_context_data), ordonné
 * gauche→droite selon Parti.position_politique (même tri que l'hémicycle de
 * scrutin_detail.html), large de son effectif réel, coloré avec Parti.couleur
 * (couleur officielle du groupe fournie par la source, déjà le principe
 * établi ailleurs sur ce champ — voir apps/partis/tasks.py) plutôt qu'un
 * dégradé inventé : pas de couleur arbitraire à choisir, et pas de risque de
 * réutiliser accidentellement le vert/rouge déjà porteurs de sens pour/contre
 * ailleurs (.hemicycle-segment-* plus bas), puisque chaque teinte est celle,
 * réelle, du parti concerné. Couleur posée en style inline par le template
 * (valeur dynamique par parti), pas ici. */
/* Une barre .spectre par chambre (voir AccueilView.get_context_data,
 * spectres_par_chambre) : le badge_chambre réutilise ses propres couleurs
 * .badge-chambre-*, pas de nouvelle couleur à inventer ici. */
.spectre-chambre { margin-bottom: 1.1rem; }
.spectre-chambre:last-of-type { margin-bottom: 0; }

.spectre-chambre-titre {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.8rem;
    font-weight: 600;
    margin: 0 0 0.35rem;
}

.spectre {
    display: flex;
    height: 10px;
    border-radius: 999px;
    overflow: hidden;
    margin-bottom: 0.5rem;
}

.spectre-segment { height: 100%; }

/* Axe gauche/droite et segment "sans groupe" côte à côte, chacun avec sa
 * propre légende (voir AccueilView._spectre_chambre) : la légende
 * Gauche/Centre/Droite ne couvre que l'axe, les élus sans groupe n'ayant
 * pas de position. flex-grow = effectif (posé inline par le template) et
 * base 0 pour que les largeurs restent proportionnelles à l'hémicycle. */
.spectre-ligne {
    display: flex;
    gap: 0.35rem;
}

.spectre-axe,
.spectre-hors-axe {
    flex-shrink: 1;
    flex-basis: 0;
    min-width: 0;
}

.spectre-hors-axe {
    flex-shrink: 1;
    flex-basis: 0;
    min-width: 4.5rem;
}

.spectre-hors-axe .spectre-legende { justify-content: flex-end; }

/* Hachures plutôt qu'un aplat : se distingue de tout parti, y compris des
 * partis gris faute de couleur officielle (RDSE, UC...), sans introduire de
 * nouvelle teinte porteuse de sens. */
.spectre-segment.spectre-segment-sans-groupe {
    background-image: repeating-linear-gradient(
        -45deg,
        transparent 0 3px,
        rgba(255, 255, 255, 0.75) 3px 5px
    );
}

.spectre-renouvellement {
    font-size: 0.8rem;
    color: var(--qvq-encre-douce);
    margin: 0 0 0.4rem;
}

.spectre-legende {
    display: flex;
    justify-content: space-between;
    font-family: var(--qvq-police-donnees);
    font-size: 0.66rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--qvq-encre-douce);
}

/* Segment cliquable de l'échiquier (voir spectre-popup.js) : bouton natif
 * pour l'accessibilité clavier (focus, Entrée/Espace), chrome par défaut
 * retiré pour ne garder que la couleur posée en style inline par le
 * template. */
.spectre-segment {
    height: 100%;
    border: none;
    padding: 0;
    margin: 0;
    display: block;
    cursor: pointer;
}

/* Popup d'identification du parti au clic sur un segment (voir
 * spectre-popup.js) : `position: fixed` + coordonnées posées en JS depuis
 * getBoundingClientRect(), pas de calcul de scroll nécessaire. Même teinte
 * d'ombre et de rayon que la fiche de territoire (carte de circonscription),
 * pour rester visuellement cohérent. */
.spectre-popup {
    position: fixed;
    z-index: 1000;
    max-width: 240px;
    background: var(--pico-background-color);
    border: 1px solid var(--qvq-ligne);
    border-radius: var(--pico-border-radius);
    box-shadow: 0 0.5rem 1.5rem rgba(20, 40, 63, 0.25);
    padding: 0.7rem 0.9rem;
}

.spectre-popup-titre {
    font-weight: 600;
    margin: 0 0 0.2rem;
}

.spectre-popup-effectif {
    font-size: 0.85rem;
    color: var(--qvq-encre-douce);
    margin: 0 0 0.5rem;
}

.spectre-popup-lien { font-size: 0.9rem; }

.encart p.note {
    font-size: 0.88rem;
    color: var(--qvq-encre-douce);
    margin: 0.8rem 0 0;
}

@media (max-width: 860px) {
    .hero-carte { grid-template-columns: 1fr; }
    .grille-deux-colonnes { grid-template-columns: 1fr; }
    .fil-item { grid-template-columns: 1fr; gap: 0.2rem; }
    /* Fiche élu et fiche loi (pas les autres pages partageant aussi
     * .grille-deux-colonnes) : en mobile empilé, l'aside (Identité +
     * Statistiques de vote / Informations générales + Auteurs et
     * rapporteurs) passe avant le contenu principal plutôt qu'après —
     * demande explicite utilisateur, ces infos de repère sont plus utiles
     * en premier sur petit écran. `order` réordonne juste l'affichage, le
     * HTML garde le contenu principal en premier dans le DOM (pas d'impact
     * SEO). */
    .grille-fiche-elu aside,
    .grille-fiche-loi aside { order: -1; }
}

/* --- Pages de liste (Élus/Lois/Scrutins/Partis) : deuxième passe de la
 * refonte graphique (2026-08-05), après l'accueil + l'habillage commun.
 * Les 4 pages partagent le même gabarit Pico.css par défaut (h1, formulaire
 * de filtres htmx, liste à puces, pagination) — un seul jeu de classes
 * partagé plutôt que du CSS par page. Les fiches détail (élu/loi/parti/
 * scrutin_detail) ne sont volontairement PAS concernées par cette passe
 * (prévu pour un chantier suivant, périmètre confirmé avec l'utilisateur). */
main > h1 {
    font-family: var(--qvq-police-affichage);
    font-weight: 600;
    font-size: clamp(1.6rem, 3.4vw, 2.2rem);
}

/* Sous-titres de section, toutes pages (ex: "Partis actuels" sur /partis/,
 * "Appartenance politique"/"Votes" sur une fiche élu...) : élargi depuis un
 * `#parti-liste h2` scopé (passe 2) maintenant que les fiches détail entrent
 * dans le périmètre de la refonte (passe 3). */
main h2 {
    font-family: var(--qvq-police-affichage);
    font-weight: 600;
    font-size: 1.25rem;
}

/* Barre de filtres (recherche + selects) : ligne horizontale plutôt que les
 * champs empilés par défaut de Pico classless, même esprit que .recherche du
 * hero d'accueil. */
.filtres {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: 1.1rem 1.5rem;
    padding: 1.1rem 1.25rem;
    margin: 1.25rem 0 1.75rem;
    background: var(--qvq-carte-tint);
    border-radius: var(--pico-border-radius);
}

.filtres label {
    flex: 1 1 11rem;
    margin: 0;
    font-size: 0.85rem;
    color: var(--qvq-encre-douce);
}

.filtres input, .filtres select {
    margin-top: 0.35rem;
}

@media (max-width: 700px) {
    .filtres { flex-direction: column; align-items: stretch; }
}

/* Liste de résultats (élus/lois/scrutins/partis) : lignes séparées par un
 * filet, pas des puces — même esprit que .fil-item de l'accueil, généralisé
 * ici puisque le contenu de chaque ligne diffère d'une liste à l'autre
 * (badges + lien toujours en tête, métadonnées poussées à droite via
 * margin-left:auto sur .meta). */
ul.liste-simple {
    list-style: none;
    margin: 0;
    padding: 0;
}

.rangee-liste {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    row-gap: 0.2rem;
    column-gap: 0.6rem;
    padding: 0.85rem 0;
    border-top: 1px solid var(--qvq-ligne);
}

ul.liste-simple li.rangee-liste:first-child {
    border-top: none;
}

.rangee-liste .meta {
    margin-left: auto;
    font-size: 0.85rem;
    color: var(--qvq-encre-douce);
    white-space: nowrap;
}

/* Sur mobile, la métadonnée revient à la ligne : en `nowrap`, une ligne
 * longue ("En commission à l'Assemblée · dernière activité le 30 septembre
 * 2026", ou date + résultat + titre de loi d'un scrutin) faisait déborder la
 * page entière (jusqu'à 581 px de large pour un écran de 390 px sur /lois/,
 * mesuré le 2026-10-02). Même seuil que le reste de la mise en page mobile. */
@media (max-width: 700px) {
    .rangee-liste .meta {
        white-space: normal;
    }
}

/* Ligne de description secondaire dans une .rangee-liste (ex: extrait d'un
 * exposé sommaire sous une "mesure phare" de loi_detail.html) : forcée sur sa
 * propre ligne pleine largeur plutôt que de participer au flex-wrap comme un
 * élément de plus, sans quoi un texte long se retrouverait mal placé entre
 * le lien et .meta. */
.rangee-liste-detail {
    flex-basis: 100%;
    color: var(--qvq-encre-douce);
}

/* Variante "compacte" de .rangee-liste : .meta collé au lien (léger espacement)
 * plutôt que poussé à l'extrémité droite de la ligne (`margin-left: auto`,
 * comportement par défaut de .rangee-liste .meta). Le renvoi à droite ne se
 * justifie que pour une VRAIE liste à parcourir (plusieurs dizaines de lignes
 * empilées, où l'alignement en colonne aide à comparer visuellement — voir
 * les 4 pages de liste, ou "Élus membres" de parti_detail.html) : sur une
 * poignée de lignes (appartenances/rôles d'un élu, vote sur l'ensemble/
 * mesures phares d'une loi), le même espacement ne fait que créer un grand
 * vide illisible entre le lien et sa métadonnée (signalé par l'utilisateur,
 * 2026-08-05). Utilisée sur elu_detail.html (appartenances, rôles) et
 * loi_detail.html (rôles, résumé) — PAS sur les 4 pages de liste ni
 * "Élus membres"/"Tous les scrutins", qui gardent l'alignement en colonne. */
.liste-compacte .meta {
    margin-left: 0.6rem;
}

/* Pagination : remplace le <ul> à puces par défaut de Pico pour ce cas
 * précis (Précédent / Page X sur Y / Suivant), centré, police données pour
 * les chiffres. */
nav.pagination-liste ul {
    display: flex;
    list-style: none;
    justify-content: center;
    align-items: center;
    gap: 1.5rem;
    margin: 1.5rem 0 0;
    padding: 0;
    font-family: var(--qvq-police-donnees);
    font-size: 0.85rem;
}

/* Retour pendant une requête htmx : htmx ajoute la classe `htmx-request` sur
 * l'élément déclencheur (le lien cliqué, ici), ce qui suffit à le signaler
 * sans markup ni script supplémentaire. `transition` pour que ça ne clignote
 * pas sur les réponses immédiates. */
nav.pagination-liste a {
    transition: opacity 0.15s ease-in-out;
}

nav.pagination-liste a.htmx-request {
    opacity: 0.4;
}

/* États vides ("Aucun X pour l'instant") : en retrait visuel, pas une
 * erreur — cohérent avec --qvq-encre-douce utilisé pour tout texte
 * secondaire ailleurs dans la refonte. */
.etat-vide {
    color: var(--qvq-encre-douce);
}

/* Bascule "Afficher les anciens..." (parti_liste, et parti_detail existant) :
 * couleur d'accent cohérente avec le reste des liens de la refonte, pas la
 * couleur de texte par défaut du <summary> Pico.
 *
 * display:flex (plutôt que le float:right par défaut de Pico sur le
 * chevron ::after) : avec un texte de résumé assez long pour passer sur
 * deux lignes (ex: "Intercommunalité — Rennes Metropole (121 élu(s))" sur
 * la recherche d'élus territoriaux), le chevron flottant se retrouvait
 * accroché à la fin du texte, donc sur la 2e ligne pour certaines
 * collectivités et sur la 1re pour d'autres selon la longueur du nom —
 * signalé par l'utilisateur comme visuellement incohérent d'une section à
 * l'autre. En flex, le chevron reste sur sa propre colonne, aligné en haut,
 * quel que soit le nombre de lignes du texte à sa gauche. */
main details summary {
    cursor: pointer;
    color: var(--qvq-marine);
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.5rem;
}

main details summary::after {
    float: none;
    flex-shrink: 0;
}

/* --- Fiches détail (élu/loi/scrutin) : troisième passe de la refonte
 * graphique (2026-08-05), après l'accueil/habillage commun et les pages de
 * liste. `.fiche-entete` habille le `<hgroup>` titre+méta commun aux 3
 * (parti_detail.html n'a qu'un h1 nu, déjà couvert par `main > h1`). */
.fiche-entete h1 {
    font-family: var(--qvq-police-affichage);
    font-weight: 600;
    font-size: clamp(1.6rem, 3.4vw, 2.2rem);
}

.fiche-entete p {
    color: var(--qvq-encre-douce);
    font-size: 0.95rem;
}

/* Tableaux de données (historique de vote d'un élu, votes d'un scrutin) :
 * seuls tableaux du site, remplace le style par défaut de Pico classless par
 * quelque chose de cohérent avec le reste de la refonte (en-tête façon
 * étiquette, filets plutôt que zébrage, survol de ligne). */
main table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.92rem;
}

main table th {
    text-align: left;
    font-family: var(--qvq-police-donnees);
    font-size: 0.72rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--qvq-encre-douce);
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--qvq-ligne);
}

/* Étiquette/valeur empilées dans un .encart (ex: "Identité" sur elu_detail,
 * "Informations générales" sur loi_detail) : même langage visuel que
 * main table th ci-dessus (étiquette en majuscules, police données,
 * discrète) plutôt qu'un <strong> qui rivalise en poids visuel avec la
 * valeur juste en dessous — signalé par l'utilisateur (2026-08-09) sur les
 * premiers encarts de la refonte des fiches détail. */
.encart-info dt {
    font-family: var(--qvq-police-donnees);
    font-size: 0.72rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--qvq-encre-douce);
    margin: 0 0 0.2rem;
}

.encart-info dd {
    margin: 0 0 1rem;
}

.encart-info dd:last-child {
    margin-bottom: 0;
}

main table td {
    padding: 0.55rem 0.75rem;
    border-bottom: 1px solid var(--qvq-ligne);
}

main table tbody tr:hover {
    background: var(--qvq-carte-tint);
}

/* Exposé sommaire (citation officielle d'un amendement, scrutin_detail.html) :
 * seul blockquote du site, traité comme une vraie citation (filet, italique)
 * plutôt que le cadre plein de Pico par défaut. */
main blockquote {
    border-left: 3px solid var(--qvq-ligne);
    margin-left: 0;
    padding: 0.3rem 0 0.3rem 1.15rem;
    color: var(--qvq-encre-douce);
    font-style: italic;
}

/* Histogramme "répartition par parti" de la page scrutin (scrutin_detail.html) :
 * une barre verticale par parti, ordonnées de gauche à droite selon
 * Parti.position_politique (façon hémicycle), hauteur totale proportionnelle au
 * nombre de votes du parti, segments internes empilés pour/contre/neutre.
 *
 * .hemicycle-panneau (ajouté à la refonte graphique, 2026-08-05) : enveloppe
 * légende + histogramme dans un encart teinté (--qvq-carte-tint), même
 * langage visuel que .filtres/.encart ailleurs sur le site — jusque-là
 * l'histogramme flottait sur fond blanc, seul élément de la page à ne pas
 * avoir reçu de traitement de "panneau" (signalé par l'utilisateur : mal
 * intégré au reste du graphisme). Ne touche PAS aux couleurs sémantiques
 * pour/contre/neutre (.hemicycle-segment-*) ni à la mécanique JS/Django
 * existante (hauteurs en %, repère d'effectif) — uniquement l'habillage. */
.hemicycle-panneau {
    background: var(--qvq-carte-tint);
    border-radius: var(--pico-border-radius);
    padding: 1.25rem 1.5rem 0.5rem;
}

.hemicycle-cles {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.25rem;
    font-size: 0.9rem;
}

.hemicycle-cle {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.hemicycle-pastille {
    display: inline-block;
    width: 0.8rem;
    height: 0.8rem;
    border-radius: 2px;
}

/* Repère de légende pour .hemicycle-repere : un segment de ligne pointillée
 * plutôt qu'un carré plein, pour rester visuellement cohérent avec le repère
 * affiché dans l'histogramme (ligne, pas une aire colorée). */
.hemicycle-pastille-repere {
    display: inline-block;
    width: 0.8rem;
    height: 0;
    border-top: 2px dashed var(--pico-muted-color);
}

.hemicycle {
    display: flex;
    align-items: stretch;
    gap: 0.5rem;
    height: 260px;
    padding: 0.5rem 0.25rem 0;
    overflow-x: auto;
}

.hemicycle-parti {
    display: flex;
    flex-direction: column;
    flex: 1 1 0;
    min-width: 3rem;
}

/* Zone qui grandit pour occuper toute la hauteur disponible au-dessus de la
 * légende : c'est par rapport à SA hauteur (définie par flexbox, pas fixée en
 * dur) que .hemicycle-bar calcule son pourcentage de hauteur. */
.hemicycle-track {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    flex: 1 1 auto;
    /* Ancre .hemicycle-repere (position absolute) à cette boîte plutôt qu'à un
     * ancêtre plus large : sans ça son bottom/left/right se calculeraient par
     * rapport au premier ancêtre positionné trouvé, potentiellement .hemicycle. */
    position: relative;
}

.hemicycle-bar {
    display: flex;
    /* column-reverse : le premier segment (pour) empile depuis le bas de la
     * barre, comme un histogramme classique plutôt que depuis le haut. */
    flex-direction: column-reverse;
    width: 100%;
    max-width: 2.5rem;
    border-radius: 4px 4px 0 0;
    overflow: hidden;
}

/* Repère "effectif mobilisable" (nombre d'élus du parti à la date du scrutin,
 * indépendant des votes réellement enregistrés) : une ligne pointillée dont la
 * hauteur partage l'échelle de .hemicycle-bar (même diviseur votes_par_parti_max),
 * pas une aire colorée — évite toute confusion avec les segments pour/contre/neutre
 * empilés dans la barre à côté. position: absolute pour ne pas participer au
 * centrage flex de .hemicycle-track (qui ne doit régir que .hemicycle-bar). */
.hemicycle-repere {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    border-top: 2px dashed var(--pico-muted-color);
    pointer-events: none;
}

.hemicycle-segment-pour {
    background-color: #2e7d32;
}

.hemicycle-segment-contre {
    background-color: #c62828;
}

.hemicycle-segment-neutre {
    background-color: #9e9e9e;
}

.hemicycle-legende {
    flex: 0 0 auto;
    margin-top: 0.4rem;
    text-align: center;
    font-size: 0.8rem;
    line-height: 1.25;
}

.hemicycle-total {
    font-family: var(--qvq-police-donnees);
    font-variant-numeric: tabular-nums;
    color: var(--pico-muted-color);
}

/* Pastille "AN"/"Sénat" (voir _badge_chambre.html) : sans elle, seul le texte
 * "Assemblée nationale"/"Sénat" distinguait les deux chambres dans les listes
 * de lois et de scrutins — peu visible en lecture rapide, et carrément absent
 * de certaines listes (accueil, liste des lois). Couleurs volontairement à
 * l'écart du vert/rouge/gris déjà utilisés ailleurs pour pour/contre/neutre
 * (.hemicycle-segment-*) : une pastille de chambre rouge à côté d'un résultat
 * "contre" rouge aurait suggéré un lien qui n'existe pas entre les deux.
 * Contrastes texte blanc vérifiés par luminance relative WCAG 2.x :
 *   - AN (#000091, bleu institutionnel "Marianne") : 14,9:1
 *   - Sénat (#7a1f3d, bordeaux) : 10,0:1
 *   - UE (#003399, bleu institutionnel du drapeau européen) : 10,9:1
 * Bien au-dessus du seuil AA (4,5:1) déjà visé ailleurs dans ce fichier. */
.badge-chambre {
    display: inline-block;
    padding: 0.05rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.6;
    color: #fff;
    white-space: nowrap;
}

.badge-chambre-an {
    background-color: #000091;
}

.badge-chambre-senat {
    background-color: #7a1f3d;
}

.badge-chambre-ue {
    background-color: #003399;
}

/* Pastille "Ancien mandat" (voir _badge_mandat_ancien.html) : contours
 * (pas de fond plein) plutôt qu'une couleur pleine comme .badge-chambre-* —
 * volontairement en retrait visuellement (info secondaire, pas une catégorie
 * à parcourir comme la chambre) et surtout pour ne réutiliser AUCUNE couleur
 * déjà chargée de sens ailleurs sur le site (bleu/bordeaux des chambres,
 * vert/rouge/gris pour/contre/neutre de l'hémicycle — .hemicycle-segment-*) :
 * un badge "ancien" ne doit suggérer ni une chambre, ni un résultat de vote.
 * --pico-muted-color hérite déjà du contraste WCAG AA vérifié en haut de ce
 * fichier, pas de nouveau calcul de contraste nécessaire. */
.badge-mandat-ancien {
    display: inline-block;
    padding: 0.05rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.6;
    color: var(--pico-muted-color);
    border: 1px solid var(--pico-muted-color);
    white-space: nowrap;
}

/* Pastille de thématique de loi (voir _badge_thematique.html) : même style
 * contour que .badge-mandat-ancien, même raison — 12 thématiques (voir
 * apps.scrutins.migrations.0016_seed_thematiques), pas question d'inventer
 * 12 couleurs distinctes sans clash avec le sens déjà porté par les couleurs
 * existantes (chambre, pour/contre). Une loi pouvant porter plusieurs
 * thématiques (ManyToMany), plusieurs pastilles peuvent s'afficher côte à
 * côte : margin-right pour l'espacement entre elles. */
.badge-thematique {
    display: inline-block;
    margin-right: 0.25rem;
    padding: 0.05rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.6;
    color: var(--pico-muted-color);
    border: 1px solid var(--pico-muted-color);
    white-space: nowrap;
}

/* Parcours d'un texte (loi_detail.html) : une phase repliable par lecture et
 * par chambre. Filet à gauche plutôt qu'une frise graphique : lisible sur
 * mobile sans CSS spécifique, et les phases longues (dizaines de réunions
 * de commission d'un budget) restent de simples listes. */
.parcours details {
    border-left: 3px solid var(--qvq-marine);
    padding-left: 0.75rem;
    margin-bottom: 0.75rem;
}

.parcours details:not([open]) {
    border-left-color: var(--qvq-encre-douce);
}

/* Réunion de commission déjà inscrite à l'agenda mais pas encore tenue :
 * visible (c'est une information utile), mais en retrait. */
/* Synthèse PE de la fiche loi : un `<summary>` nu se lit comme une ligne de
 * texte ; l'encadré et le libellé souligné, comme un lien, disent qu'on peut
 * le déplier. Tokens de `.encart`, définis dans les deux thèmes. */
.synthese-loi {
    border: 1px solid var(--qvq-ligne);
    border-radius: var(--pico-border-radius);
    padding: 0.8rem 1.1rem;
    margin-bottom: 1.5rem;
    background: var(--qvq-carte-tint);
}

.synthese-loi > summary { font-weight: 600; }
.synthese-loi > summary span { text-decoration: underline; text-underline-offset: 0.2em; }
.synthese-loi[open] > summary { margin-bottom: 0.8rem; }

.parcours .etape-a-venir {
    color: var(--qvq-encre-douce);
    font-style: italic;
}

/* Métadonnées d'une étape (date · nom de commission) : retour à la ligne
 * autorisé, contrairement au `white-space: nowrap` général de
 * `.rangee-liste .meta` (pensé pour une date ou un compteur). Le nom d'une
 * commission spéciale dépasse 200 caractères ("Commission spéciale chargée
 * d'examiner la proposition de loi...") : insécable, il élargissait toute la
 * page sur mobile. */
.parcours .rangee-liste .meta {
    white-space: normal;
    overflow-wrap: anywhere;
}
