/* =============================================================================
   Composants
   =============================================================================
   Un composant = une classe racine + ses parties en `.racine-partie`.
   Aucune valeur littérale : tout vient de tokens.css.
   ========================================================================== */

/* ── En-tête de site ─────────────────────────────────────────────────────── */

.navbar {
    position: sticky;
    top: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    height: var(--header-height);
    padding-inline: var(--space-5);
    background: rgba(255, 255, 255, 0.85);
    backdrop-filter: saturate(1.6) blur(12px);
    -webkit-backdrop-filter: saturate(1.6) blur(12px);
    border-bottom: 1px solid var(--line);
}

.navbar-brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-family: var(--font-display);
    font-size: var(--text-md);
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--ink);
    text-decoration: none;
}
.navbar-brand:hover { color: var(--ink); }
.navbar-brand .logo-mark { width: 1.75rem; height: 1.75rem; flex-shrink: 0; }
/* Le « où » du nom reprend le bleu de la marque, comme sur le logo. */
.navbar-brand em { font-style: normal; color: var(--brand); }

.navbar-links { display: flex; align-items: center; gap: var(--space-4); }
/* `:not(.btn)` est indispensable : un descendant `.navbar-links a` pèse plus
   lourd qu'une classe seule comme `.btn-primary`, et lui volerait sa couleur —
   du gris de lien sur un fond bleu de bouton. */
.navbar-links a:not(.btn) {
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--ink-muted);
    text-decoration: none;
}
.navbar-links a:not(.btn):hover { color: var(--ink); }

/* ── Acceptation des conditions ──────────────────────────────────────────── */

/* La case et son libellé alignés en haut : sur deux ou trois lignes de texte,
   un alignement centré ferait flotter la case au milieu du paragraphe. */
.form-consent {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    margin-top: var(--space-5);
}
.form-consent input[type="checkbox"] {
    /* La cible reste confortable au doigt sans grossir le carré lui-même. */
    width: 1.05rem;
    height: 1.05rem;
    margin: 0;
    flex: 0 0 auto;
    accent-color: var(--brand);
    /* Aligne le carré sur la première ligne du libellé plutôt que sur le haut
       de la boîte, que la hauteur de ligne décale. */
    margin-top: 0.15rem;
    cursor: pointer;
}
.form-consent label {
    font-size: var(--text-sm);
    color: var(--ink-muted);
    line-height: 1.5;
    cursor: pointer;
}
.form-consent label a { color: var(--ink); }

/* ── État de l'offre dans la barre de navigation ─────────────────────────── */

.navbar-account { display: inline-flex; align-items: center; gap: 0.35rem; }
.plan-star { display: inline-flex; color: var(--brand); }

/* Le compteur ne s'affiche qu'à deux tests ou moins, et vire à l'ambre puis au
   rouge : c'est un avertissement, pas une décoration. */
.plan-left {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.15rem;
    height: 1.15rem;
    padding: 0 0.25rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--amber) 16%, transparent);
    color: var(--amber-text);
    font-size: var(--text-2xs);
    font-weight: 700;
}
.plan-left-empty {
    background: color-mix(in srgb, var(--danger) 14%, transparent);
    color: var(--danger);
}

/* ── Indicateur de chargement sur la carte ───────────────────────────────── */

/* Le logo se dessine lui-même : la marque est un tracé au trait, il suffit de
   faire courir un tiret le long du chemin. Pas d'image supplémentaire à
   charger, et l'attente porte l'identité du site plutôt qu'un rond générique. */
.map-loader {
    position: absolute;
    /* En bas à gauche : le contrôle de zoom de Leaflet occupe le coin supérieur
       gauche et masquait l'indicateur. Le coin inférieur droit porte
       l'attribution OpenStreetMap, qui ne doit pas être recouverte. */
    bottom: var(--space-3);
    left: var(--space-3);
    z-index: 900;
    display: none;
    align-items: center;
    gap: var(--space-2);
    padding: 0.35rem 0.6rem 0.35rem 0.4rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--paper) 92%, transparent);
    border: 1px solid var(--line);
    box-shadow: 0 2px 10px rgb(0 0 0 / 0.08);
    font-size: var(--text-2xs);
    color: var(--ink-muted);
    backdrop-filter: blur(6px);
}
.map-loader[data-visible] { display: inline-flex; }

/* La marque porte sa propre animation, en SMIL. Rien à animer ici : le viewBox
   d'origine (680×584) inclut de la marge, d'où une boîte un peu plus grande que
   celle du logo statique pour un tracé de taille comparable. */
.map-loader-mark { width: 30px; height: 26px; display: block; }

/* ── Autour de ce logement ───────────────────────────────────────────────── */

/* Une vraie carte sous la carte, pas une note de bas de page. La première
   version était en 12px gris sur fond blanc : personne ne la voyait, et deux
   personnes de suite ne l'ont pas trouvée. Une commande qu'on ne voit pas
   n'existe pas. */
.poi-bar {
    margin-top: var(--space-4);
    padding: var(--space-4) var(--space-5);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.poi-bar-head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-md);
    margin-bottom: var(--space-3);
}
.poi-bar-head strong { font-weight: 700; }

.poi-bar-select,
.poi-bar-single {
    font-size: var(--text-md);
    font-weight: 700;
    color: var(--brand);
}
.poi-bar-select {
    padding: 0.2rem 1.6rem 0.2rem 0.5rem;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--paper-sunken);
    cursor: pointer;
    max-width: 22ch;
}

/* ── Le bloc de consentement ─────────────────────────────────────────────── */

.poi-bar-consent { display: grid; gap: var(--space-3); }
.poi-bar-consent > div > strong { font-size: var(--text-md); display: block; margin-bottom: var(--space-1); }
.poi-bar-consent p {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--ink-muted);
    line-height: 1.55;
    max-width: 74ch;
}
.poi-bar-consent form { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.poi-bar-note { font-size: var(--text-xs); color: var(--ink-subtle); }

/* ── Les puces ───────────────────────────────────────────────────────────── */

.poi-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* Assez grandes pour se voir et se toucher : 13px et 36px de haut, contre 12px
   et 26px auparavant. */
.poi-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 2.25rem;
    padding: 0.4rem 0.85rem;
    border: 1.5px solid var(--line);
    border-radius: 999px;
    background: var(--paper);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink);
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.poi-chip:hover { border-color: var(--poi-color); }
.poi-chip-dot {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 50%;
    border: 2.5px solid var(--poi-color);
    background: transparent;
}
.poi-chip[aria-pressed="true"] {
    border-color: var(--poi-color);
    background: color-mix(in srgb, var(--poi-color) 12%, transparent);
}
.poi-chip[aria-pressed="true"] .poi-chip-dot { background: var(--poi-color); }
.poi-chip.is-loading { opacity: 0.55; cursor: progress; }

/* ── Messages ────────────────────────────────────────────────────────────── */

.poi-message,
.poi-legend { line-height: 1.55; max-width: 74ch; }
.poi-message {
    margin: var(--space-3) 0 0 0;
    font-size: var(--text-sm);
    color: var(--amber-text);
    font-weight: 500;
}
.poi-message:empty { display: none; }
.poi-legend {
    margin: var(--space-3) 0 0 0;
    font-size: var(--text-xs);
    color: var(--ink-muted);
}

/* ── Marqueurs ───────────────────────────────────────────────────────────── */

/* Volontairement en retrait : ils situent, ils ne réclament pas. */
.poi-marker { opacity: 0.88; transition: opacity 0.15s ease; }
.poi-marker:hover { opacity: 1; }

.poi-popup strong { font-size: var(--text-sm); }
.poi-popup-meta { font-size: var(--text-xs); color: var(--ink-muted); margin-top: 2px; }
/* « un aller » : sans cette precision, le temps calcule vers un lieu a
   proximite se comparait a un total hebdomadaire du scenario. */
.poi-popup-note { color: var(--ink-subtle); font-weight: 400; }
.poi-popup-actions { display: flex; gap: var(--space-2); margin-top: var(--space-3); }
.poi-popup-actions button {
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--paper);
    font-size: var(--text-xs);
    cursor: pointer;
    color: var(--ink);
}
.poi-popup-actions button:hover { border-color: var(--brand); color: var(--brand); }
.poi-popup-result { margin-top: var(--space-2); font-size: var(--text-xs); color: var(--ink); }

/* ── Transports en commun ────────────────────────────────────────────────── */

/* Troisième famille visuelle : CARRÉ arrondi, là où les lieux du scénario sont
   des pastilles pleines et les repères OSM des pastilles creuses. La forme
   distingue, pas la couleur — seul contraste qui survive au dézoom. */
.transit-marker { opacity: 0.94; transition: opacity 0.15s ease; }
.transit-marker:hover { opacity: 1; }

.poi-chip-transit { font-weight: 700; }

/* Étiquette d'arrêt, visible à partir du zoom 15. Discrète : elle nomme, elle
   ne réclame pas l'attention — les lieux du scénario restent les points qui
   comptent. Fond blanc translucide plutôt qu'opaque, pour ne pas trouer la
   carte sous elle. */
.transit-label {
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid var(--line);
    border-radius: 7px;
    box-shadow: 0 1px 3px rgb(0 0 0 / 0.08);
    padding: 2px 6px;
    font-size: 11px;
    line-height: 1.3;
    white-space: nowrap;
    color: var(--ink);
}
/* Leaflet dessine une flèche par défaut : elle alourdit sans rien apporter à
   une étiquette collée au marqueur. */
.transit-label::before { display: none !important; }
.transit-label-name { display: block; font-weight: 600; }
.transit-label-lines { display: block; color: var(--ink-muted); font-size: 10px; }

.transit-popup strong { font-size: var(--text-sm); }
.leaflet-popup-content:has(.transit-popup) { width: auto !important; min-width: 19rem; }
.transit-lines { margin-top: var(--space-2); }
.transit-line-row {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    font-size: var(--text-xs);
    line-height: 1.6;
}
.transit-line-icon { font-size: var(--text-sm); }
.transit-popup-meta {
    margin-top: var(--space-2);
    font-size: var(--text-xs);
    color: var(--ink-muted);
}
.transit-popup-actions {
    display: flex;
    gap: var(--space-2);
    margin-top: var(--space-3);
    flex-wrap: wrap;
}
.transit-popup-actions button {
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--paper);
    font-size: var(--text-xs);
    cursor: pointer;
    color: var(--ink);
}
.transit-popup-actions button:hover { border-color: var(--brand); color: var(--brand); }

/* Hauteur bornee : huit passages font deborder la bulle hors de la carte, et
   Leaflet ne la repositionne pas — elle sort simplement du cadre par le haut. */
/* 8rem, soit cinq passages visibles et le reste au defilement. A 11rem la
   bulle depassait encore du cadre par le haut : Leaflet l'ancre AU-DESSUS du
   marqueur, et un arret situe dans la moitie haute de la carte n'a pas la place
   au-dessus de lui. Cinq passages suffisent a juger une desserte. */
.transit-schedule {
    margin-top: var(--space-3);
    max-height: 8rem;
    overflow-y: auto;
}
/* Leaflet borne le contenu d'une bulle a 300px : la grille a quatre colonnes
   y rentrait de force, et la DESTINATION comme l'HEURE sortaient du cadre. On
   voyait « 12 min · 89 » puis « 13 min · 89 » sans pouvoir distinguer les deux
   directions — deux passages identiques en apparence, pour deux bus opposes. */
.transit-popup { min-width: 19rem; }

.transit-departure {
    display: grid;
    grid-template-columns: 3.6rem 3.4rem 1fr auto;
    gap: var(--space-2);
    align-items: baseline;
    font-size: var(--text-xs);
    padding: 3px 0;
    border-bottom: 1px solid var(--line);
}
.transit-departure:last-of-type { border-bottom: 0; }
.transit-departure-when { font-weight: 700; color: var(--brand); }
.transit-departure-to {
    color: var(--ink-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.transit-departure-time { color: var(--ink-muted); font-variant-numeric: tabular-nums; }

/* La mention n'est pas décorative : ces horaires sont planifiés, et un bus
   supprimé y figure encore. */
.transit-theorique {
    margin: var(--space-2) 0 0 0;
    font-size: var(--text-2xs);
    color: var(--ink-subtle);
}

/* ── Pied de page ────────────────────────────────────────────────────────── */

.site-footer {
    max-width: var(--container);
    margin: var(--space-8) auto 0;
    padding: var(--space-5);
    border-top: 1px solid var(--line);
    text-align: center;
    font-size: var(--text-xs);
}
.footer-links { display: flex; justify-content: center; gap: var(--space-2); margin-bottom: var(--space-2); }
.footer-links a { color: var(--ink-muted); text-decoration: none; }
.footer-links a:hover { color: var(--brand); }
.footer-sep { color: var(--line-strong); }
.footer-copy { color: var(--ink-subtle); }

/* ── Messages flash ──────────────────────────────────────────────────────── */

.flash-messages {
    max-width: var(--container);
    margin: var(--space-4) auto 0;
    padding-inline: var(--space-5);
}
.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid;
    font-size: var(--text-sm);
}
.alert + .alert { margin-top: var(--space-2); }
.alert-success { background: var(--success-wash); border-color: color-mix(in srgb, var(--success) 25%, transparent); color: var(--success-text); }
.alert-error   { background: var(--danger-wash);  border-color: color-mix(in srgb, var(--danger) 25%, transparent);  color: var(--danger); }

/* ── Cartes ──────────────────────────────────────────────────────────────── */
/* Définie UNE fois. Elle l'était onze fois, à `padding` près. */

.card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    box-shadow: var(--shadow-sm);
}
.card-tight { padding: var(--space-4); }
.card-flush { padding: var(--space-2); }
.card-narrow { max-width: 34rem; }
.card-interactive { transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease); }
.card-interactive:hover { border-color: var(--brand-wash-firm); box-shadow: var(--shadow-md); }

.section-header {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}
.section-header h2 { display: flex; align-items: center; gap: var(--space-2); }
.section-subtitle { font-size: var(--text-sm); color: var(--ink-muted); margin-top: var(--space-1); }

/* ── Boutons ─────────────────────────────────────────────────────────────── */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 0.5rem var(--space-4);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--paper);
    color: var(--ink-body);
    font-size: var(--text-sm);
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--duration) var(--ease), border-color var(--duration) var(--ease),
                color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
}
.btn:hover { background: var(--paper-sunken); color: var(--ink); border-color: var(--line-strong); }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn[aria-disabled='true'] { opacity: 0.5; pointer-events: none; }

.btn-primary {
    background: var(--brand);
    border-color: transparent;
    color: #fff;
    box-shadow: var(--shadow-sm);
}
.btn-primary:hover { background: var(--brand-strong); color: #fff; box-shadow: var(--shadow-brand); }

.btn-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, transparent); background: var(--paper); }
.btn-danger:hover { background: var(--danger-wash); color: var(--danger); }

.btn-focus { color: var(--amber-text); border-color: color-mix(in srgb, var(--amber) 40%, transparent); background: var(--paper); }
.btn-focus:hover { background: var(--amber-wash); color: var(--amber-text); }

.btn-ghost { border-color: transparent; background: transparent; color: var(--ink-muted); }
.btn-ghost:hover { background: var(--paper-sunken); color: var(--ink); }

.btn-sm { padding: 0.3rem var(--space-3); font-size: var(--text-xs); }
.btn-lg { padding: 0.7rem var(--space-5); font-size: var(--text-base); }

/* Action discrète en ligne — les crayons et corbeilles des tableaux. */
.icon-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem; height: 1.75rem;
    padding: 0;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--ink-subtle);
    cursor: pointer;
    transition: background var(--duration) var(--ease), color var(--duration) var(--ease);
}
.icon-action:hover { background: var(--paper-sunken); color: var(--brand); }
.icon-action-danger:hover { background: var(--danger-wash); color: var(--danger); }

/* ── Formulaires ─────────────────────────────────────────────────────────── */

.form-group + .form-group { margin-top: var(--space-4); }
.form-group label {
    display: block;
    margin-bottom: var(--space-1);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink);
}
.form-group input,
.form-group select,
.form-group textarea,
.field {
    width: 100%;
    padding: 0.55rem var(--space-3);
    background: var(--paper);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    color: var(--ink);
    transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
}
.form-group input::placeholder,
.form-group textarea::placeholder,
.field::placeholder { color: var(--ink-subtle); }

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus,
.field:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 15%, transparent);
}
.form-group .form-error,
.form-error { margin-top: var(--space-1); font-size: var(--text-xs); color: var(--danger); }
.form-error-list { padding-left: 1.1em; margin-bottom: 0; }

/* ── Cases a cocher dans un formulaire ────────────────────────────────────── */

/* La regle generique `.form-group input` donnait a TOUTE case a cocher une
   largeur de 100 %, un fond, une bordure et du rembourrage — comme a une zone de
   saisie. Chrome etirait alors le controle natif et centrait le carre au milieu
   de sa colonne. Le defaut etait invisible en lisant le CSS : la regle ne
   mentionne pas les cases, elle les attrape. */
.form-group input[type="checkbox"],
.form-group input[type="radio"] {
    width: auto;
    padding: 0;
    border: 0;
    background: none;
}

/* Une case se lit « carre puis libelle », sur une ligne. */
.form-check {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-4);
}
.form-check input[type="checkbox"] {
    width: 1.05rem;
    height: 1.05rem;
    margin: 0;
    flex: 0 0 auto;
    accent-color: var(--brand);
    cursor: pointer;
}
/* Le libelle perd la mise en forme des etiquettes de champ — il ne surplombe
   rien, il accompagne. */
.form-check label {
    margin: 0;
    font-weight: 500;
    cursor: pointer;
}

.form-row { display: flex; gap: var(--space-3); }
.form-help { font-size: var(--text-xs); color: var(--ink-muted); margin-top: var(--space-1); }

.form-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-5); }

/* ── Authentification ────────────────────────────────────────────────────── */

.auth-container {
    max-width: 25rem;
    margin: var(--space-8) auto;
    padding: var(--space-6);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
}
.auth-container h1 { margin-bottom: var(--space-5); font-size: var(--text-lg); }
.auth-link { margin-top: var(--space-4); font-size: var(--text-sm); color: var(--ink-muted); }

/* ── Fil d'Ariane ────────────────────────────────────────────────────────── */

.breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
    font-size: var(--text-sm);
    color: var(--ink-subtle);
}
.breadcrumb a { color: var(--ink-muted); text-decoration: none; }
.breadcrumb a:hover { color: var(--brand); }

/* ── Étiquettes ──────────────────────────────────────────────────────────── */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.15rem var(--space-2);
    border-radius: var(--radius-full);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* Type de lieu : pastille teintée plutôt qu'aplat saturé. Sur fond blanc, neuf
   aplats vifs côte à côte deviennent une guirlande ; la teinte claire garde la
   couleur reconnaissable sans crier. */
.place-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem var(--space-2);
    border-radius: var(--radius-full);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--place-color, var(--ink-muted));
    background: color-mix(in srgb, var(--place-color, var(--ink-muted)) 10%, var(--paper));
    border: 1px solid color-mix(in srgb, var(--place-color, var(--ink-muted)) 22%, transparent);
}
.place-school    { --place-color: var(--place-school); }
.place-coparent  { --place-color: var(--place-coparent); }
.place-work      { --place-color: var(--place-work); }
.place-childcare { --place-color: var(--place-childcare); }
.place-family    { --place-color: var(--place-family); }
.place-health    { --place-color: var(--place-health); }
.place-shopping  { --place-color: var(--place-shopping); }
.place-leisure   { --place-color: var(--place-leisure); }
.place-other     { --place-color: var(--place-other); }

.mode-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.1rem var(--space-2);
    border-radius: var(--radius-full);
    font-size: var(--text-2xs);
    font-weight: 600;
    color: var(--mode-color, var(--ink-muted));
    background: color-mix(in srgb, var(--mode-color, var(--ink-muted)) 10%, var(--paper));
    border: 1px solid color-mix(in srgb, var(--mode-color, var(--ink-muted)) 22%, transparent);
    white-space: nowrap;
}
.mode-car    { --mode-color: var(--mode-car); }
.mode-bike   { --mode-color: var(--mode-bike); }
.mode-foot   { --mode-color: var(--mode-foot); }
.mode-custom { --mode-color: var(--mode-custom); }

/* ── Choix du mode, sur la ligne d'un résultat ────────────────────────────── */
/* Le contrôle reprend l'apparence de la pastille qu'il remplace : c'est la même
   information, elle devient seulement modifiable. Un menu déroulant gris
   standard aurait fait perdre la couleur qui distingue voiture et marche d'un
   coup d'œil dans la colonne. */

.mode-switch { display: inline-block; margin: 0; }

.mode-select {
    appearance: none;
    padding: 0.1rem 1.35rem 0.1rem var(--space-2);
    border-radius: var(--radius-full);
    font-size: var(--text-2xs);
    font-weight: 600;
    font-family: inherit;
    color: var(--mode-color, var(--ink-muted));
    background-color: color-mix(in srgb, var(--mode-color, var(--ink-muted)) 10%, var(--paper));
    border: 1px solid color-mix(in srgb, var(--mode-color, var(--ink-muted)) 22%, transparent);
    /* Le chevron est dessiné ici : `appearance: none` retire celui du système,
       et sans lui rien ne signale que la pastille s'ouvre. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23666' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.4rem center;
    background-size: 0.5rem;
    cursor: pointer;
    white-space: nowrap;
}
.mode-select:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 1px;
}

/* Dit que ce mode a été choisi à la main pour CE test. Sans cette marque, on
   revient une semaine plus tard sans savoir ce qu'on a modifié soi-même — et on
   compare deux logements en croyant qu'ils suivent les mêmes règles. */
.mode-overridden {
    display: inline-block;
    margin-left: var(--space-1);
    font-size: var(--text-2xs);
    font-style: italic;
    color: var(--ink-subtle);
    cursor: help;
}

.badge-stale {
    display: inline-flex;
    padding: 0.1rem var(--space-2);
    border-radius: var(--radius-full);
    background: var(--amber-wash);
    color: var(--amber-text);
    border: 1px solid color-mix(in srgb, var(--amber) 30%, transparent);
    font-size: var(--text-2xs);
    font-weight: 700;
    text-transform: uppercase;
}

/* Étiquette de section en capitales — sert d'ancrage typographique. */
.eyebrow {
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--brand);
}

/* ── Tableaux ────────────────────────────────────────────────────────────── */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}
.data-table th {
    padding: var(--space-2) var(--space-3);
    text-align: left;
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-subtle);
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}
.data-table td {
    padding: var(--space-3);
    border-bottom: 1px solid var(--line);
    color: var(--ink-body);
    vertical-align: middle;
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover td { background: var(--paper-tint); }
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.actions-cell { white-space: nowrap; text-align: right; }

/* ── État vide ───────────────────────────────────────────────────────────── */
/* Un écran vide est une invitation à agir, pas un constat de manque. */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-7) var(--space-4);
    text-align: center;
}
.empty-state svg { color: var(--line-strong); }
.empty-state-title { font-family: var(--font-display); font-size: var(--text-md); font-weight: 600; color: var(--ink); }
.empty-state-desc { max-width: 26rem; font-size: var(--text-sm); color: var(--ink-muted); }
.empty-state .btn { margin-top: var(--space-2); }

/* ── Encadré d'avertissement en ligne ────────────────────────────────────── */

.notice {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
}
.notice-warning { background: var(--amber-wash); border: 1px dashed color-mix(in srgb, var(--amber) 35%, transparent); color: var(--amber-text); }
.notice-info    { background: var(--brand-wash); border: 1px solid var(--brand-wash-firm); color: var(--brand-strong); }
.notice-success { background: var(--success-wash); border: 1px solid color-mix(in srgb, var(--success) 25%, transparent); color: var(--success-text); }
.notice-danger  { background: var(--danger-wash); border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent); color: var(--danger); }

/* ── Progression ─────────────────────────────────────────────────────────── */
/* Trois étapes réellement séquentielles : on ne peut pas tester un domicile
   sans trajets, ni définir de trajets sans lieux. La numérotation encode donc
   une vraie contrainte, elle ne décore pas. */

.stepper {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-4) var(--space-5);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
}
.stepper-step { display: flex; align-items: center; gap: var(--space-3); flex: 1; min-width: 0; }
.stepper-number {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2rem; height: 2rem;
    flex-shrink: 0;
    border-radius: var(--radius-full);
    background: var(--paper-sunken);
    color: var(--ink-subtle);
    font-family: var(--font-display);
    font-size: var(--text-sm);
    font-weight: 700;
}
.stepper-text { min-width: 0; }
.stepper-title { display: block; font-size: var(--text-sm); font-weight: 600; color: var(--ink-subtle); }
.stepper-desc  { display: block; font-size: var(--text-xs); color: var(--ink-subtle); }
.stepper-connector { flex: 0 0 2rem; height: 2px; background: var(--line); border-radius: var(--radius-full); }

.stepper-active .stepper-number { background: var(--brand); color: #fff; box-shadow: var(--shadow-brand); }
.stepper-active .stepper-title  { color: var(--ink); }
.stepper-active .stepper-desc   { color: var(--ink-muted); }

.stepper-done .stepper-number { background: var(--success-wash); color: var(--success-text); }
.stepper-done .stepper-title  { color: var(--ink-body); }
.stepper-connector-done { background: color-mix(in srgb, var(--success) 40%, transparent); }

/* Version compacte, pour les vignettes de scénario : mêmes trois étapes,
   réduites à des pastilles. */
.mini-stepper { display: flex; align-items: center; gap: var(--space-1); }
.mini-step { display: flex; align-items: center; gap: var(--space-1); }
.mini-dot {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.125rem; height: 1.125rem;
    flex-shrink: 0;
    border-radius: var(--radius-full);
    background: var(--paper-sunken);
    color: var(--ink-subtle);
}
.mini-label { font-size: var(--text-xs); color: var(--ink-subtle); white-space: nowrap; }
.mini-sep { width: 1rem; height: 1.5px; flex-shrink: 0; margin-inline: var(--space-1); background: var(--line); }

.mini-step-active .mini-dot { background: var(--brand); color: #fff; }
.mini-step-active .mini-label { color: var(--ink-body); font-weight: 600; }
.mini-step-done .mini-dot { background: var(--success-wash); color: var(--success-text); }
.mini-step-done .mini-label { color: var(--ink-muted); }
.mini-sep-done { background: color-mix(in srgb, var(--success) 40%, transparent); }

/* Prochaine action suggérée sur une vignette : un lien, pas un bouton — c'est
   une invitation, pas l'action principale de la page. */
.next-step-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--brand-strong);
    text-decoration: none;
}
.next-step-link:hover { color: var(--brand); text-decoration: underline; }

/* ── Carte ───────────────────────────────────────────────────────────────── */

.map-shell {
    /* Repere de positionnement pour l'indicateur de chargement, qui doit se
       placer dans un coin de la carte et non dans un coin de la page. */
    position: relative;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--paper);
    box-shadow: var(--shadow-sm);
}
.map-canvas { height: 22rem; width: 100%; }
.map-canvas-sm { height: 18rem; }
.map-canvas-fill { height: 100%; min-height: 22rem; }

.map-fullscreen-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.125rem; height: 2.125rem;
    background: var(--paper);
    color: var(--ink-muted);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
    transition: color var(--duration) var(--ease), border-color var(--duration) var(--ease);
}
.map-fullscreen-btn:hover { color: var(--brand); border-color: var(--brand); }

.map-fullscreen {
    position: fixed !important;
    inset: 0 !important;
    z-index: 9999 !important;
    width: 100vw !important;
    height: 100vh !important;
    border-radius: 0 !important;
    background: var(--paper);
}

.map-form-row { display: flex; gap: var(--space-4); align-items: stretch; }
.map-col { flex: 3; min-width: 0; }
.form-col { flex: 2; min-width: 0; }

/* Résultats de géocodage sous le champ d'adresse. */
.geocoding-wrap { position: relative; }
.geocoding-results {
    position: absolute;
    top: calc(100% + 4px); left: 0; right: 0;
    z-index: 1000;
    max-height: 14rem;
    overflow-y: auto;
    background: var(--paper);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
}
.geocoding-result-item {
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    color: var(--ink-body);
    cursor: pointer;
    border-bottom: 1px solid var(--line);
}
.geocoding-result-item:last-child { border-bottom: none; }
.geocoding-result-item:hover { background: var(--brand-wash); color: var(--brand-strong); }

/* ── Étiquettes de la carte Leaflet ──────────────────────────────────────── */

.candidate-tooltip {
    padding: 0.15rem var(--space-2);
    background: var(--amber);
    color: #fff;
    border: none;
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    box-shadow: var(--shadow-md);
}
.candidate-tooltip::before { border-right-color: var(--amber); }

/* ── Légende ─────────────────────────────────────────────────────────────── */

.legend-summary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-sm);
    color: var(--ink-muted);
    cursor: pointer;
    list-style: none;
}
.legend-summary::-webkit-details-marker { display: none; }
.legend-summary::before {
    content: '';
    width: 0; height: 0;
    border-left: 5px solid currentColor;
    border-block: 4px solid transparent;
    transition: transform var(--duration) var(--ease);
}
details[open] > .legend-summary::before { transform: rotate(90deg); }
.legend-summary:hover { color: var(--ink); }

.legend-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(9rem, 100%), 1fr));
    gap: var(--space-2) var(--space-4);
    margin-top: var(--space-3);
    padding: var(--space-4);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
}
.legend-item { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--ink-body); }

/* ── Lieux ───────────────────────────────────────────────────────────────── */

.place-item {
    padding: var(--space-4);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--paper);
}
.place-item + .place-item { margin-top: var(--space-3); }
.place-header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.place-identity { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.place-picto { width: 1.5rem; height: 1.5rem; flex-shrink: 0; }
.place-actions { display: flex; gap: var(--space-2); flex-shrink: 0; }

/* ── Résultats de recherche ──────────────────────────────────────────────── */

.results-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    padding: 0 0.4rem;
    border-radius: var(--radius-full);
    background: var(--brand-wash);
    color: var(--brand-strong);
    font-size: var(--text-xs);
    font-weight: 700;
}

.result-card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    box-shadow: var(--shadow-sm);
    transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
}
.result-card + .result-card { margin-top: var(--space-3); }
.result-card:hover { border-color: var(--brand-wash-firm); box-shadow: var(--shadow-md); }

.result-header { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); }
.result-rank {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem; height: 1.5rem;
    flex-shrink: 0;
    border-radius: var(--radius-full);
    background: var(--paper-sunken);
    color: var(--ink-muted);
    font-family: var(--font-display);
    font-size: var(--text-xs);
    font-weight: 700;
}
.result-label { display: flex; align-items: center; gap: var(--space-2); font-family: var(--font-display); font-size: var(--text-md); font-weight: 600; color: var(--ink); }
.result-date { font-size: var(--text-xs); color: var(--ink-subtle); }
.result-actions { display: flex; gap: var(--space-2); flex-shrink: 0; }

/* Le total hebdomadaire est le chiffre que l'application existe pour produire :
   il est traité comme tel, en display et au plus grand corps de la page. */
.result-total {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}
.result-total-unit { font-size: var(--text-sm); font-weight: 500; color: var(--ink-muted); letter-spacing: 0; }
.result-km { font-size: var(--text-sm); color: var(--ink-muted); }

/* Meilleur résultat : ambre, la couleur déjà associée aux candidats sur la
   carte. Le liseré suffit à le distinguer sans doubler l'information. */
.best-result { border-left: 3px solid var(--amber); }
.best-label {
    display: inline-flex;
    padding: 0.1rem var(--space-2);
    border-radius: var(--radius-full);
    background: var(--amber-wash);
    color: var(--amber-text);
    border: 1px solid color-mix(in srgb, var(--amber) 30%, transparent);
    font-size: var(--text-2xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.best-total { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }

.coord-status {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    background: var(--success-wash);
    border: 1px solid color-mix(in srgb, var(--success) 25%, transparent);
    color: var(--success-text);
    font-size: var(--text-sm);
}
.map-validation-error {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-3);
    padding: var(--space-3);
    border-radius: var(--radius-md);
    background: var(--danger-wash);
    border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent);
    color: var(--danger);
    font-size: var(--text-sm);
    font-weight: 600;
}

/* ── Tableau de bord ─────────────────────────────────────────────────────── */

.scenario-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr)); gap: var(--space-4); }
.scenario-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-5);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease), transform var(--duration) var(--ease);
}
.scenario-card:hover { border-color: var(--brand-wash-firm); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.scenario-name {
    font-family: var(--font-display);
    font-size: var(--text-md);
    font-weight: 600;
    color: var(--ink);
    text-decoration: none;
}
.scenario-name:hover { color: var(--brand); text-decoration: underline; text-underline-offset: 3px; }
.scenario-meta { display: flex; flex-wrap: wrap; gap: var(--space-3); font-size: var(--text-xs); color: var(--ink-muted); }

/* ── Barre de temps ──────────────────────────────────────────────────────── */
/* L'élément signature : le total hebdomadaire décomposé par lieu, chaque
   segment large en proportion des minutes qu'il coûte. Le tableau dit combien ;
   la barre dit d'où ça vient — on voit d'un coup que la sortie d'école pèse
   plus que tout le reste. Les largeurs viennent des données, elles sont donc
   posées en style inline : c'est le seul cas où c'est légitime. */

.time-bar {
    display: flex;
    height: 0.5rem;
    border-radius: var(--radius-full);
    overflow: hidden;
    background: var(--paper-sunken);
}
.time-bar-segment { height: 100%; }
.time-bar-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1) var(--space-3);
    margin-top: var(--space-2);
    font-size: var(--text-xs);
    color: var(--ink-muted);
}
.time-bar-key { display: inline-flex; align-items: center; gap: 0.3rem; }
.time-bar-dot { width: 0.5rem; height: 0.5rem; border-radius: var(--radius-full); flex-shrink: 0; }

/* ── Page d'accueil ──────────────────────────────────────────────────────── */

.landing { max-width: var(--container); margin-inline: auto; padding: var(--space-7) var(--space-5) var(--space-8); }

.hero { max-width: 40rem; }
.hero h1 {
    font-size: clamp(2rem, 5vw, var(--text-3xl));
    line-height: 1.05;
    letter-spacing: -0.035em;
    font-weight: 700;
    margin-top: var(--space-3);
}
/* Le mot qui porte la thèse prend le dégradé de la marque, une seule fois. */
.hero h1 em {
    font-style: normal;
    background: var(--brand-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.hero-subtitle { margin-top: var(--space-4); font-size: var(--text-md); color: var(--ink-muted); max-width: 34rem; }
.hero-cta { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-6); }

/* Démonstration : la sortie réelle de l'application, en miniature. */
.demo {
    margin-top: var(--space-7);
    padding: var(--space-5);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}
.demo-row + .demo-row { margin-top: var(--space-5); padding-top: var(--space-5); border-top: 1px solid var(--line); }
.demo-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-1) var(--space-3); margin-bottom: var(--space-2); }
.demo-place { font-family: var(--font-display); font-size: var(--text-base); font-weight: 600; color: var(--ink); }
/* C'est le nombre que l'application existe pour produire : il est traité comme
   tel, et non comme une ligne de tableau. */
.demo-total { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: -0.03em; line-height: 1.1; }
.demo-total small { font-size: var(--text-sm); font-weight: 500; color: var(--ink-muted); letter-spacing: 0; }
.demo-verdict {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-5);
    padding: var(--space-3);
    border-radius: var(--radius-md);
    background: var(--brand-wash);
    color: var(--brand-strong);
    font-size: var(--text-sm);
    font-weight: 600;
}

/* Les trois étapes de la page d'accueil sont celles de l'application, dans le
   même ordre : la numérotation décrit une contrainte réelle, pas un habillage. */
.steps-section { margin-top: var(--space-8); }
.steps-section > h2 { font-size: var(--text-lg); }
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); gap: var(--space-6); margin-top: var(--space-5); }
/* Le chiffre est un repère de lecture, pas une note de bas de page : à 13 px il
   se lisait comme une décoration. À 36 px il ancre le bloc et fait comprendre
   d'un coup d'œil qu'il y a trois étapes, dans cet ordre. */
.step-num {
    display: block;
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.04em;
    color: var(--brand);
    font-variant-numeric: tabular-nums;
    margin-bottom: var(--space-2);
}
.step h3 { margin-top: 0; font-size: var(--text-md); }
.step p { margin-top: var(--space-2); font-size: var(--text-base); line-height: 1.6; color: var(--ink-muted); }

.landing-footer { margin-top: var(--space-8); padding-top: var(--space-5); border-top: 1px solid var(--line); font-size: var(--text-xs); color: var(--ink-subtle); }
.landing-footer a { color: var(--ink-muted); text-decoration: none; }
.landing-footer a:hover { color: var(--brand); }

/* ── Contenu légal ───────────────────────────────────────────────────────── */

.legal-content { max-width: 44rem; }
.legal-content h2 { margin-top: var(--space-6); margin-bottom: var(--space-2); font-size: var(--text-md); }
.legal-content p  { margin-bottom: var(--space-3); color: var(--ink-body); }
.legal-content ul { margin: 0 0 var(--space-3) var(--space-5); color: var(--ink-body); }
.legal-content li { margin-bottom: var(--space-1); }

/* ── Responsive ──────────────────────────────────────────────────────────── */

@media (max-width: 768px) {
    .map-form-row { flex-direction: column; }
    .map-col, .form-col { flex: none; }
    .result-header { flex-direction: column; }
}

@media (max-width: 640px) {
    .navbar { padding-inline: var(--space-3); gap: var(--space-2); }
    .navbar-links { gap: var(--space-3); }
    .stepper { flex-direction: column; align-items: stretch; gap: var(--space-1); padding: var(--space-4); }
    .stepper-connector { width: 2px; height: 1rem; margin-left: 1rem; flex: none; }

    .place-header { flex-direction: column; align-items: flex-start; }
    .place-actions { margin-left: 0; }
    .form-row { flex-direction: column; }
    .card { padding: var(--space-4); }
    /* Les boutons d'action ne gardent que leur icône en petite largeur. */
    .action-label { display: none; }
}

/* ── Questions fréquentes ────────────────────────────────────────────────── */
/* Affichées sur la page d'accueil et balisées en FAQPage à partir de la même
   source. Deux colonnes en large, une seule en étroit : les réponses sont
   courtes, une pleine largeur les rendrait pénibles à lire. */

.faq { margin-top: var(--space-8); }
.faq > h2 { font-size: var(--text-lg); }
/* `min(20rem, 100%)` et non `20rem` : un minmax ne descend jamais sous son
   minimum, si bien qu'a 320 px de large la colonne faisait 320 px et debordait
   la page de 16 px. Constate a la mesure, invisible a l'oeil sur un ecran
   d'ordinateur. */
.faq-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: var(--space-5) var(--space-6);
    margin-top: var(--space-5);
}
.faq-item h3 { font-size: var(--text-base); font-weight: 600; }
.faq-item p { margin-top: var(--space-2); font-size: var(--text-sm); color: var(--ink-muted); }

/* ── État de l'offre ─────────────────────────────────────────────────────── */
/* Un quota qui ne se voit qu'au moment où il bloque est une mauvaise surprise.
   Il est donc affiché en permanence, discrètement, et ne devient insistant
   qu'à l'approche de la limite. */

.plan-status {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--paper);
    font-size: var(--text-sm);
}
.plan-name {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: 600;
    color: var(--ink);
}
.plan-quota { color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.plan-quota strong { color: var(--ink); }

/* Il reste peu : on prévient sans dramatiser. */
.plan-status-low { border-color: color-mix(in srgb, var(--amber) 35%, transparent); background: var(--amber-wash); }
.plan-status-low .plan-quota { color: var(--amber-text); }
.plan-status-low .plan-quota strong { color: var(--amber-text); }

/* Plus rien : l'état devient une invitation à agir, pas un constat d'échec. */
.plan-status-empty { border-color: color-mix(in srgb, var(--brand) 30%, transparent); background: var(--brand-wash); }
.plan-status-empty .plan-quota { color: var(--brand-strong); }
.plan-status-empty .plan-quota strong { color: var(--brand-strong); }

/* Mention sous l'appel à l'action : présente, sans peser. */
.hero-note { margin-top: var(--space-3); font-size: var(--text-sm); color: var(--ink-subtle); }

/* ── Les offres ──────────────────────────────────────────────────────────── */
/* Trois cartes de même hauteur, la gratuite mise en avant : c'est par là qu'on
   entre, et c'est la seule dont l'action est immédiate. */

/* ── Accueil : galerie d'aperçus ─────────────────────────────────────────── */

.gallery { margin-top: var(--space-8); }
.gallery > h2 { font-size: var(--text-lg); }
.gallery-intro {
    margin-top: var(--space-2);
    max-width: 40rem;
    font-size: var(--text-sm);
    color: var(--ink-muted);
}
.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: var(--space-5);
    margin-top: var(--space-5);
}
.gallery-item { margin: 0; }

/* Le bouton porte l'image : cliquer pour agrandir est une ACTION, et un
   <div> avec un écouteur ne s'atteint pas au clavier. */
.gallery-open {
    display: block;
    width: 100%;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--paper);
    cursor: zoom-in;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.gallery-open:hover { border-color: var(--brand); box-shadow: var(--shadow-sm); }
.gallery-open:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
.gallery-open img { display: block; width: 100%; height: auto; }

.gallery-item figcaption {
    margin-top: var(--space-3);
    font-size: var(--text-sm);
    color: var(--ink-muted);
    line-height: 1.55;
}
.gallery-item figcaption strong { display: block; color: var(--ink); margin-bottom: 2px; }

/* ── La visionneuse ──────────────────────────────────────────────────────── */

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-5);
    background: rgb(10 10 16 / 0.92);
}
.lightbox[hidden] { display: none; }

.lightbox-figure {
    margin: 0;
    max-width: min(72rem, 100%);
    max-height: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}
.lightbox-figure img {
    max-width: 100%;
    /* La légende doit toujours tenir sous l'image, d'où la réserve verticale. */
    max-height: calc(100vh - 12rem);
    object-fit: contain;
    border-radius: 10px;
    background: var(--paper);
}
.lightbox-figure figcaption {
    color: rgb(255 255 255 / 0.82);
    font-size: var(--text-sm);
    line-height: 1.55;
    text-align: center;
}
.lightbox-figure figcaption strong { display: block; color: #fff; margin-bottom: 2px; }
.lightbox-count { display: block; margin-top: var(--space-2); font-size: var(--text-xs); color: rgb(255 255 255 / 0.5); }

.lightbox button {
    position: absolute;
    border: 0;
    background: rgb(255 255 255 / 0.1);
    color: #fff;
    cursor: pointer;
    border-radius: 999px;
    line-height: 1;
    transition: background 0.15s ease;
}
.lightbox button:hover { background: rgb(255 255 255 / 0.22); }
.lightbox button:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.lightbox-close { top: var(--space-4); right: var(--space-4); width: 2.5rem; height: 2.5rem; font-size: 1.5rem; }
.lightbox-prev, .lightbox-next {
    top: 50%;
    transform: translateY(-50%);
    width: 3rem; height: 3rem;
    font-size: 2rem;
}
.lightbox-prev { left: var(--space-4); }
.lightbox-next { right: var(--space-4); }

/* Sur un écran étroit, les flèches latérales mangeraient l'image : elles
   passent sous la légende, côte à côte. */
@media (max-width: 640px) {
    .lightbox-prev, .lightbox-next { top: auto; bottom: var(--space-4); transform: none; }
    .lightbox-prev { left: 25%; }
    .lightbox-next { right: 25%; }
}

/* ── Accueil : ce qu'on voit autour du logement ──────────────────────────── */

.around { margin-top: var(--space-8); }
.around > h2 { font-size: var(--text-lg); }
.around-intro {
    margin-top: var(--space-2);
    max-width: 40rem;
    font-size: var(--text-sm);
    color: var(--ink-muted);
}
.around-grid {
    display: grid;
    /* min() : sans lui, une colonne de 18rem déborde sous 320 px. */
    grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
    gap: var(--space-4);
    margin-top: var(--space-5);
}
.around-card {
    padding: var(--space-5);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
}
.around-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 12px;
    margin-bottom: var(--space-3);
    color: var(--around-color);
    background: color-mix(in srgb, var(--around-color) 11%, transparent);
}
.around-card h3 { font-size: var(--text-md); margin: 0 0 var(--space-2) 0; }
.around-card p {
    margin: 0;
    color: var(--ink-muted);
    font-size: var(--text-sm);
    line-height: 1.6;
}
/* D'où viennent les données et ce qu'on en transmet : une promesse de
   confidentialité qui ne se vérifie nulle part n'en est pas une. */
.around-note {
    margin-top: var(--space-3) !important;
    padding-top: var(--space-3);
    border-top: 1px solid var(--line);
    font-size: var(--text-xs) !important;
    color: var(--ink-subtle) !important;
}

.plans { margin-top: var(--space-8); }
.plans > h2 { font-size: var(--text-lg); }
.plans-intro { margin-top: var(--space-2); max-width: 40rem; font-size: var(--text-sm); color: var(--ink-muted); }

.plans-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
    gap: var(--space-4);
    margin-top: var(--space-5);
    align-items: stretch;
}

.plan-card {
    display: flex;
    flex-direction: column;
    padding: var(--space-5);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}
.plan-card h3 { font-size: var(--text-md); }
.plan-price {
    margin-top: var(--space-1);
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--ink);
    letter-spacing: -0.02em;
}
.plan-desc { margin-top: var(--space-2); font-size: var(--text-sm); color: var(--ink-muted); }

.plan-features { list-style: none; margin: var(--space-4) 0 0; padding: 0; font-size: var(--text-sm); }
.plan-features li { position: relative; padding-left: var(--space-5); margin-bottom: var(--space-2); }
/* Coche dessinée en CSS plutôt qu'en SVG répété quinze fois dans le gabarit. */
.plan-features li::before {
    content: '';
    position: absolute;
    left: 2px; top: 0.45em;
    width: 0.5rem; height: 0.3rem;
    border-left: 2px solid var(--brand);
    border-bottom: 2px solid var(--brand);
    transform: rotate(-45deg);
}

/* Le bouton se colle en bas quelle que soit la longueur de la liste, pour que
   les trois cartes s'alignent.

   L'espacement minimal vient de la marge basse de la liste, et NON d'une règle
   `.plan-features + .btn` : celle-ci pèse autant que `.plan-card .btn` et,
   déclarée après, écrasait le `margin-top: auto` — les boutons suivaient alors
   la longueur de chaque liste au lieu de s'aligner. */
.plan-features { margin-bottom: var(--space-5); }
.plan-card .btn { margin-top: auto; }

.plan-card-current { border-color: var(--brand); box-shadow: var(--shadow-md); }


/* ── Ajustements mobiles de la page d'accueil ────────────────────────────────
   Mesuré à 386 px avant correction : la barre de navigation occupait exactement
   la largeur du viewport, les marges de `.landing` restaient celles du bureau
   (48/24/64), et les libellés descendaient à 11 px — lisibles sur un écran
   d'ordinateur, pénibles à bout de bras. */

@media (max-width: 640px) {
    .landing { padding: var(--space-5) var(--space-4) var(--space-7); }

    .hero-cta { gap: var(--space-2); }
    .hero-cta .btn { flex: 1 1 auto; justify-content: center; }

    .demo { padding: var(--space-4); }

    /* Les libellés secondaires remontent d'un cran : à 11 px, des capitales
       espacées deviennent de la texture plutôt que du texte. */
    .eyebrow { font-size: var(--text-xs); }
    .time-bar-legend { font-size: var(--text-sm); gap: var(--space-1) var(--space-3); }

    .plans, .faq, .steps { margin-top: var(--space-7); }
    .plans-grid, .faq-list { gap: var(--space-3); }
}

/* En dessous de 430 px, le nom écrit en toutes lettres et les deux actions ne
   tiennent plus ensemble. La marque garde son symbole — reconnaissable seul —
   et son nom reste accessible aux lecteurs d'écran. */
@media (max-width: 430px) {
    .navbar { padding-inline: var(--space-3); gap: var(--space-2); }
    .navbar-brand span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
    .navbar-brand .logo-mark { width: 2rem; height: 2rem; }
    .navbar-links { gap: var(--space-3); }
}

/* ── Comparaison des logements testés ────────────────────────────────────── */
/* Le tableau que le rapport PDF portait seul. Comparer est le geste du
   service : il n'avait rien à faire uniquement dans un document imprimé. */

.comparison-table .result-rank { width: 1.375rem; height: 1.375rem; }

/* Le premier n'est pas mis en avant par une couleur d'alerte mais par la
   couleur de marque : c'est un résultat, pas un avertissement. */
.result-rank-best {
    background: var(--brand-wash);
    color: var(--brand);
}

/* L'écart se lit en négatif du meilleur : il coûte, donc il se voit. Mais
   discrètement — aucun de ces logements n'est « mauvais », ils sont comparés. */
.comparison-table .ecart { color: var(--ink-body); font-variant-numeric: tabular-nums; }

/* « + 6 h 20 » coupé en deux lignes se lit « + 6 h » puis « 20 » : deux nombres
   là où il n'y en a qu'un. Une durée ne se césure pas. */
.comparison-table .num { white-space: nowrap; }

/* Un bouton qui doit se lire comme du texte : le libellé mène à la carte, mais
   ce n'est pas une action au sens d'un bouton — d'où l'apparence de lien. */
.link-plain {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    color: var(--ink);
    font-weight: 600;
    text-align: left;
    cursor: pointer;
    text-decoration: underline;
    text-decoration-color: var(--line-strong);
    text-underline-offset: 2px;
}
.link-plain:hover { color: var(--brand); text-decoration-color: currentColor; }

/* Sous 640 px, six colonnes ne tiennent pas. Plutôt que de tout comprimer, on
   retire les deux qui se déduisent : « sur un an » est une lecture de l'écart,
   et la distance ne départage presque jamais deux logements que le temps a
   déjà classés. Le tableau reste défilable pour qui les veut. */
@media (max-width: 640px) {
    .comparison-table .col-secondaire { display: none; }
}

/* La période sur laquelle porte une colonne, sous son intitulé. « Distance »
   seule se lisait comme un trajet vers quelque part ; c'est un kilométrage
   hebdomadaire. En minuscules et sans graisse, pour rester une précision et
   ne pas concurrencer l'intitulé. */
.th-unit {
    display: block;
    margin-top: 1px;
    font-weight: 500;
    font-size: var(--text-2xs);
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink-subtle);
}

/* ── Le meilleur résultat, sur la carte d'un scénario ─────────────────────── */
/* La liste annonçait « 1 test » sans jamais dire ce qu'il avait donné. Or c'est
   le seul chiffre pour lequel on revient : le voir ici, c'est se souvenir d'où
   l'on en est sans ouvrir quoi que ce soit.

   Le bloc est un LIEN vers la comparaison : lire un résultat donne
   immédiatement envie de voir les autres. */

.scenario-best {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2);
    margin-top: var(--space-3);
    padding: var(--space-3);
    border-radius: var(--radius-sm);
    /* Bordure à gauche plutôt qu'un fond coloré : la carte reste calme, et
       l'accent suffit à faire remonter la ligne à l'œil. Même dispositif que le
       meilleur résultat sur la page d'un scénario. */
    border-left: 3px solid var(--amber);
    background: var(--paper-sunken);
    text-decoration: none;
    transition: background var(--duration) var(--ease);
}
.scenario-best:hover { background: var(--brand-wash); }

.scenario-best-tag {
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-subtle);
}
.scenario-best-name { font-weight: 600; color: var(--ink); }
.scenario-best-figure {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    margin-left: auto;
}
.scenario-best-total {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}
.scenario-best-unit { font-size: var(--text-xs); color: var(--ink-muted); }

/* Sur téléphone, le chiffre passe à la ligne ENTIER — avec son unité — plutôt
   que de comprimer le nom du logement, qui est ce qui identifie le résultat. */
@media (max-width: 560px) {
    .scenario-best-figure { margin-left: 0; flex-basis: 100%; }
}

/* ── Décor du haut de la page d'accueil ──────────────────────────────────── */
/* Une trame et quelques trajets qui se tracent lentement, derrière le titre.

   Trois règles tenues : ça ne déplace rien, ça n'intercepte rien, et ça
   s'arrête pour qui demande moins de mouvement. Le reste est du réglage
   d'opacité — un décor qu'on remarque est un décor raté. */

.landing { position: relative; }
/* Le contenu passe devant, sans quoi le décor le recouvrirait. */
.landing > *:not(.hero-decor) { position: relative; z-index: 1; }

.hero-decor {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 34rem;
    overflow: hidden;      /* aucune barre de défilement horizontale possible */
    pointer-events: none;  /* le décor n'attrape jamais un clic */
    z-index: 0;
}
/* Le décor s'efface là où le titre passe. Un tracé qui traverse le texte ne se
   lit pas comme un décor mais comme un défaut d'affichage — vu en capture, et
   c'est exactement ce que ça donnait. Le hero fait 40rem : le dégradé rend la
   moitié gauche muette et laisse les trajets vivre dans l'espace vide. */
.hero-decor svg {
    width: 100%;
    height: 100%;
    display: block;
    /* Un fondu doux sur le bord gauche du dessin, pour qu'aucun tracé ne
       commence par un bout franc. Le placement fait le gros du travail : ce
       masque n'est qu'une sécurité. */
    mask-image: linear-gradient(to right, transparent 0%, #000 22%);
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 22%);
}

/* La trame : un semis de points, comme un papier millimétré très pâle. Le
   dégradé de masque la fait disparaître vers le bas, pour qu'elle n'ait pas de
   bord franc — une texture qui s'arrête net se voit, et se met à compter. */
.hero-decor::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image: radial-gradient(circle, var(--line-strong) 1px, transparent 1px);
    background-size: 26px 26px;
    opacity: 0.5;
    mask-image: linear-gradient(to bottom, #000 0%, transparent 78%);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 78%);
}

.trajet {
    fill: none;
    stroke: url(#fondTrajet);
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: 0.4;
    /* Un court segment qui parcourt un très long vide : c'est ce qui donne le
       « chemin furtif » plutôt qu'une ligne qui clignote. */
    stroke-dasharray: 90 1400;
    animation: trajet-passe 19s linear infinite;
}
/* Décalés, sinon les trois partent ensemble et le fond se met à battre. */
.trajet-2 { animation-duration: 25s; animation-delay: -7s; }
.trajet-3 { animation-duration: 22s; animation-delay: -14s; }

@keyframes trajet-passe {
    from { stroke-dashoffset: 1490; }
    to   { stroke-dashoffset: 0; }
}

/* Le mouvement s'arrête, les tracés restent. Retirer aussi le dessin
   priverait la page de sa texture sans raison : c'est le MOUVEMENT qui gêne. */
@media (prefers-reduced-motion: reduce) {
    .trajet { animation: none; stroke-dasharray: none; opacity: 0.16; }
}

/* Sur téléphone, LES TRAJETS DISPARAISSENT.

   Vu en capture : le titre occupe toute la largeur, il ne reste aucune zone
   vide, et les tracés retombaient pile sur le texte — deux traits verticaux au
   bord des mots, qui se lisent comme un défaut d'affichage.

   Les atténuer n'aurait rien réglé : le problème est leur PLACE, pas leur
   intensité. La trame, elle, reste — c'est elle qui porte l'essentiel, et elle
   ne gêne personne. La fantaisie vit là où il y a de la place pour elle. */
@media (max-width: 900px) {
    .hero-decor { height: 26rem; }
    .hero-decor::before { opacity: 0.35; }
    .trajet { display: none; }
}

/* ── Suivi des inscriptions (administration) ──────────────────────────────── */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: var(--space-3);
    margin-bottom: var(--space-5);
}
.stat-tile { display: flex; flex-direction: column; gap: var(--space-1); }
.stat-label { font-size: var(--text-2xs); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-subtle); }
.stat-figure { font-family: var(--font-display); font-size: var(--text-2xl); font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.1; }
.stat-note { font-size: var(--text-xs); color: var(--ink-muted); }

/* Les deux couleurs du graphique.

   Ce n'est pas une palette d'IDENTITÉ mais une part et son reste : la portion
   mesurée porte la couleur de marque, ce qui manque reste neutre. Le gris est
   donc volontairement sans teinte.

   Vérifié au validateur : séparation ΔE 21,2 en protanopie et 25,6 en vision
   normale — très au-dessus des seuils — et 3:1 de contraste sur le blanc, ce
   qui rend la portion « en attente » visible sans qu'elle crie. Un gris plus
   clair tombait à 1,7:1 : le manque devenait invisible, alors que c'est
   précisément lui qu'on vient regarder. */
.chart { --chart-confirme: #4f46ff; --chart-attente: #8f8fa8; width: 100%; height: auto; display: block; }
.chart-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.chart-grid { stroke: var(--line); stroke-width: 1; }
.chart-tick { fill: var(--ink-subtle); font-size: 10px; font-family: inherit; }

.chart-bar-confirme { fill: var(--chart-confirme); }
.chart-bar-attente  { fill: var(--chart-attente); }
/* Le trait de fond entre les deux segments empilés : sans lui, deux aplats
   voisins se lisent comme un seul dès qu'on recule un peu. */
.chart-bar { stroke: var(--paper); stroke-width: 2; }

.chart-legend { display: flex; gap: var(--space-4); margin: var(--space-3) 0; font-size: var(--text-xs); color: var(--ink-muted); }
.chart-legend span { display: inline-flex; align-items: center; gap: var(--space-2); }
.chart-key { width: 0.7rem; height: 0.7rem; border-radius: 3px; }
.chart-key-confirme { background: #4f46ff; }
.chart-key-attente  { background: #8f8fa8; }

.etat-oui { color: var(--success-text); font-weight: 600; }
.etat-non { color: var(--amber-text); font-weight: 600; }
