/* Styles de l'outil (page d'accueil), posés sur design-system.css. Couleurs,
   typographie, rayons et ombres viennent exclusivement de ses tokens --o-* :
   le thème sombre y est défini une fois, rien n'est à dupliquer ici.
   Exceptions assumées, hors système : le voile de la fiche détail, l'ombre
   des épingles de la carte (reprise telle quelle de la maquette) et les
   couleurs d'enseigne des badges (app.js). */

/* Bandeau hors ligne : collé en haut de l'écran tant que la connexion manque. */
.offline-banner {
  position: sticky;
  top: 0;
  z-index: 50;
  padding: 10px var(--space-4);
  background: var(--o-ink);
  color: var(--o-bg);
  text-align: center;
  font-size: 13px;
  font-weight: 500;
}

/* ═══════════════════ Formulaire de recherche ═══════════════════
   Carte blanche posée sur le fond de carte. Partagée avec la page Alertes,
   qui n'en reprend que la carte : sa grille est dans alertes.css. */
.search-panel {
  position: relative;
  padding: clamp(16px, 2.4vw, 24px);
  border: 1px solid var(--o-line);
  border-radius: clamp(18px, 2vw, 22px);
  background: var(--o-surface);
  box-shadow: var(--o-sh-card);
}

/* Trois dispositions, celles de la maquette : une ligne sur ordinateur,
   champs sur deux lignes sur tablette, une colonne (rayon et réservoir
   côte à côte) sur téléphone. Le bouton reste en dernier dans le DOM, après
   les options qu'il prend en compte. */
.search-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-areas: "addr addr" "fuel fuel" "rad tank" "opts opts" "cta cta";
  gap: 14px;
  align-items: end;
}
@media (min-width: 640px) {
  .search-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-areas: "addr addr addr" "fuel rad tank" "opts opts opts" "cta cta cta";
  }
}
@media (min-width: 1024px) {
  .search-grid {
    grid-template-columns: minmax(0, 2.2fr) minmax(0, 1.1fr) minmax(0, .75fr) minmax(0, .85fr) 168px;
    grid-template-areas: "addr fuel rad tank cta" "opts opts opts opts opts";
  }
}
.search-grid .field-address { grid-area: addr; }
.search-grid .field-fuel { grid-area: fuel; }
.search-grid .field-radius { grid-area: rad; }
.search-grid .field-tank { grid-area: tank; }
.search-grid .search-opts { grid-area: opts; }
.search-grid .search-cta { grid-area: cta; }

/* Champ composé : icône ou unité dans le même cadre que la saisie. */
.field-box {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 52px;
  padding: 0 14px;
  border: 1px solid var(--o-line);
  border-radius: var(--o-radius-md);
  background: var(--o-field);
  color: var(--o-faint);
}
.field-box:hover { border-color: var(--o-faint); }
/* La maquette n'a pas d'état de focus : sans lui, impossible de savoir au
   clavier quel champ est actif. */
.field-box:focus-within { border-color: var(--o-accent); box-shadow: 0 0 0 3px var(--o-accent-soft2); }
.field-box input,
.field-box select {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--o-ink);
  font: inherit;
  font-size: 16px; /* 16 px minimum : en dessous, iOS zoome au focus */
}
.field-box select {
  appearance: none;
  margin: 0 -14px;
  padding: 0 36px 0 14px;
  cursor: pointer;
}
.field-icon,
.field-chevron { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.field-icon { width: 18px; height: 18px; }
.field-chevron { position: absolute; right: 12px; width: 16px; height: 16px; color: var(--o-subtle); pointer-events: none; }
.field-unit { font-size: 14px; color: var(--o-subtle); }

/* — Bouton Chercher : libellé à gauche, loupe (ou roue) à droite — */
.search-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  height: 52px;
  padding: 0 18px 0 20px;
  border: 0;
  border-radius: var(--o-radius-md);
  background: var(--o-accent);
  color: var(--o-on-accent);
  box-shadow: var(--o-sh-cta);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 16px;
  cursor: pointer;
}
.search-cta:hover { background: var(--o-accent-hover); }
.search-cta:active { background: var(--o-accent-press); }
.cta-icon { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.cta-spinner {
  width: 18px;
  height: 18px;
  flex: none;
  border: 2.4px solid color-mix(in srgb, currentColor 35%, transparent);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: octSpin .8s linear infinite;
}
.cta-busy,
.cta-spinner,
.search-cta[aria-busy="true"] .cta-idle,
.search-cta[aria-busy="true"] .cta-icon { display: none; }
.search-cta[aria-busy="true"] .cta-busy,
.search-cta[aria-busy="true"] .cta-spinner { display: inline-block; }
.search-cta[aria-busy="true"] { cursor: progress; }

/* — Options : géolocalisation et mode de distance — */
.search-opts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 24px;
  margin-top: 6px;
  padding-top: 18px;
  border-top: 1px solid var(--o-line-soft);
}
.geo-btn {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 5px 16px 5px 5px;
  border: 1px solid transparent;
  border-radius: var(--o-radius-pill);
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.geo-btn:hover { background: var(--o-accent-soft); border-color: var(--o-accent-soft2); }
.geo-btn:disabled { cursor: progress; }
.geo-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: var(--o-radius-pill);
  background: var(--o-accent-soft);
  color: var(--o-accent);
  transition: background .2s;
}
.geo-btn.is-done .geo-icon { background: var(--o-accent); color: var(--o-on-accent); }
.geo-icon svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.geo-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.geo-label { font-size: 15px; font-weight: 600; color: var(--o-ink); }
.geo-sub { font-size: 13px; color: var(--o-subtle); overflow-wrap: anywhere; }

.distance-mode { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.distance-mode-label { font-size: 13px; font-weight: 500; color: var(--o-muted); }
.distance-mode .seg { width: 320px; }
.distance-mode .icon-car { width: 16px; height: 16px; stroke-width: 2; }
@media (max-width: 639.98px) {
  .distance-mode,
  .distance-mode .seg { width: 100%; }
}

/* — Autocomplétion (adresses de la Géoplateforme, recherches récentes) — */
.suggestions {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 20;
  max-height: 320px;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--o-line);
  border-radius: 14px;
  background: var(--o-surface);
  box-shadow: var(--o-sh-card);
  list-style: none;
}
.suggestions li {
  padding: 10px 12px;
  border-radius: var(--o-radius-sm);
  font-size: 15px;
  color: var(--o-ink);
  cursor: pointer;
}
.suggestions li .sg-ctx { display: block; margin-top: 1px; font-size: 12.5px; color: var(--o-subtle); }
.suggestions li:hover,
.suggestions li[aria-selected="true"] { background: var(--o-hover); }
.suggestions .sg-history {
  padding: 8px 12px 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--o-subtle);
  cursor: default;
}
.suggestions .sg-history:hover { background: none; }
/* Horloge dessinée par un masque : elle prend la couleur du thème. */
.suggestions li.sg-hist-item { display: flex; align-items: center; gap: 10px; }
.suggestions li.sg-hist-item::before {
  content: "";
  width: 16px;
  height: 16px;
  flex: none;
  background: var(--o-faint);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 6v6l4 2'/></svg>") center / contain no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 6v6l4 2'/></svg>") center / contain no-repeat;
}

/* — Barre d'état (chargement, erreurs avec action de rattrapage) — */
.status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  margin-top: var(--space-4);
  padding: 14px 18px;
  border: 1px solid var(--o-line);
  border-radius: 14px;
  background: var(--o-surface);
  box-shadow: var(--o-sh-sm);
  font-size: 14px;
  color: var(--o-muted);
}
.status.error {
  border-color: var(--o-accent-soft2);
  background: var(--o-accent-soft);
  color: var(--o-accent-ink);
}
.status .status-cta { margin-left: auto; }

/* Roue de la barre d'état. */
.loader {
  display: inline-block;
  flex: none;
  width: 14px;
  height: 14px;
  border: 2px solid var(--o-line);
  border-top-color: var(--o-accent);
  border-radius: 50%;
  animation: octSpin .8s linear infinite;
}

/* ═══════════════════ Résultats ═══════════════════
   Ordre de la maquette : méta et onglets, bloc « Le moins cher », écart, puis
   le panneau de l'onglet actif (liste, carte ou historique). Le bloc gagnant
   et l'écart restent en place quel que soit l'onglet. */
.results {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: clamp(28px, 4vw, 48px);
  scroll-margin-top: 16px;
}
.results-top { display: flex; flex-direction: column; gap: 16px; }
.results-top:empty,
.results-bottom:empty,
.station-list:empty { display: none; }
/* Panneaux des onglets : même marge que la section quand la page y descend
   (showView dans app.js). */
.station-list,
.station-map,
.history-list { scroll-margin-top: 16px; }

.results-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 20px;
}
.results-heading { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
/* Ligne de méta de la maquette : « GAZOLE · AVIGNON · 5 KM · 24 STATIONS ».
   Reste un <h2> pour la structure du document, mais s'affiche comme une
   légende — le titre de la page, c'est le prix du bloc gagnant. */
.results-meta {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--o-muted);
}
.results-count { font-size: 12px; color: var(--o-subtle); }
.results-count:empty { display: none; }
/* Pendant le chargement, la maquette ne montre que le squelette. */
.results.is-loading .view-toggle { visibility: hidden; }

/* — Onglets Liste / Carte / Historique — */
.view-toggle {
  display: flex;
  padding: 4px;
  border: 1px solid var(--o-line-soft);
  border-radius: var(--o-radius-md);
  background: var(--o-chip);
}
.view-btn {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 38px;
  padding: 0 14px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--o-subtle);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.view-btn:hover { color: var(--o-ink); }
.view-btn.active { background: var(--o-thumb); box-shadow: var(--o-sh-thumb); color: var(--o-ink); }
.view-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* — Cartes de résultats — */
.winner,
.list-card,
.notice {
  border: 1px solid var(--o-line);
  background: var(--o-surface);
  box-shadow: var(--o-sh-card);
}

/* ═══════════════════ Bloc « Le moins cher » ═══════════════════
   Le prix est l'information qu'on vient chercher : il est posé à l'échelle
   qu'elle mérite, tout le reste la commente. */
.winner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: clamp(20px, 3vw, 40px);
  align-items: end;
  padding: clamp(20px, 3vw, 32px);
  border-radius: var(--o-radius-xl);
}
.winner-main { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.winner-tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 28px;
  padding: 0 12px;
  border-radius: var(--o-radius-pill);
  background: var(--o-accent-soft);
  color: var(--o-accent-ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.winner-tag .ic { width: 14px; height: 14px; stroke-width: 2.4; }
.winner-price {
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: clamp(64px, 13vw, 112px);
  line-height: .86;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
  color: var(--o-ink);
  white-space: nowrap;
}
.winner-unit {
  margin-left: .35em;
  font-size: .24em;
  font-weight: 700;
  letter-spacing: .02em;
  vertical-align: .95em;
  color: var(--o-subtle);
}
.winner-trend { display: flex; align-items: center; gap: 7px; font-size: 14px; font-weight: 500; }
.winner-trend .ic { stroke-width: 2.2; }

.winner-info { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.winner-title { display: flex; align-items: center; gap: 12px; }
.winner-title .brand-badge { min-width: 34px; height: 34px; padding: 0 6px; border-radius: 9px; font-size: 11px; }
.winner-name { margin: 0; font-size: clamp(20px, 2.4vw, 26px); line-height: 1.15; letter-spacing: -0.02em; }
/* Nom officiel de la station (« Relais des Invalides »), entre le titre
   (enseigne + ville) et l'adresse. */
.winner-station,
.sheet-station { font-size: 15px; font-weight: 600; color: var(--o-muted); }
.winner-addr { font-size: 14px; color: var(--o-subtle); }
.winner-facts {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 28px;
  margin-top: 12px;
  font-size: 14px;
  color: var(--o-subtle);
}
.winner-num { font-family: var(--font-heading); font-weight: 800; font-size: 22px; color: var(--o-ink); }
.winner-fresh { display: inline-flex; align-items: center; gap: 6px; }
.winner-fresh .ic { width: 14px; height: 14px; }
.winner-warn {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: var(--o-radius-sm);
  background: var(--o-accent-soft);
  color: var(--o-accent-ink);
  font-size: 13px;
}
.winner-warn .ic { margin-top: 1px; }
/* « Trajet compris, X te revient 1,80 € de moins » : note cliquable (ouvre
   la fiche de X), neutre, l'icône au vert des économies. */
.winner-trip {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 12px;
  padding: 10px 12px;
  border: 0;
  border-radius: var(--o-radius-sm);
  background: var(--o-chip);
  color: var(--o-text);
  font: inherit;
  font-size: 13.5px;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
}
.winner-trip:hover { background: var(--o-hover); }
.winner-trip:focus-visible { outline: 2px solid var(--o-accent); outline-offset: 2px; }
.winner-trip .ic { flex: none; margin-top: 1px; color: var(--o-down); }
.winner-trip strong { color: var(--o-ink); font-weight: 700; }
.winner-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.winner-actions .btn { flex: 1 1 auto; justify-content: flex-start; white-space: nowrap; }
.winner-actions .btn-primary { padding: 0 20px 0 18px; }

/* ═══════════════════ Écart dans le rayon ═══════════════════
   En bas des résultats (#resultsBottom), après le panneau de l'onglet. */
.savings {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: clamp(22px, 3.4vw, 36px) clamp(20px, 3vw, 32px);
  border-radius: var(--o-radius-xl);
  background: var(--o-accent);
  color: var(--o-on-accent);
  box-shadow: var(--o-sh-cta);
}
.savings-kicker { font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; opacity: .85; }
.savings-line {
  max-width: 20ch;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: clamp(28px, 4.6vw, 48px);
  line-height: 1.04;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

/* — Note : aucune station, ou aucun prix récent dans le rayon — */
.notice {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 14px;
  padding: 18px 20px;
  border-radius: var(--o-radius-lg);
  font-size: 15px;
  color: var(--o-text);
}
.notice > .ic { width: 20px; height: 20px; color: var(--o-subtle); }
.notice p { flex: 1 1 260px; margin: 0; }

/* ═══════════════════ Tableau des autres stations ═══════════════════
   Un vrai <table>, mais chaque ligne est une grille : mêmes colonnes que la
   maquette (44 · station · 100 · 90 · 120 px, gouttière 16 px), et la même
   ligne se replie en deux étages sur téléphone sans second balisage. */
.list-card { border-radius: 20px; overflow: hidden; }
.station-table,
.station-table thead,
.station-table tbody { display: block; width: 100%; border-collapse: collapse; }
.station-table tr {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 100px 90px 120px;
  gap: 16px;
  align-items: center;
  padding: 14px 24px;
}
.station-table th,
.station-table td { display: block; padding: 0; border: 0; text-align: left; }
.station-table thead tr {
  border-bottom: 1px solid var(--o-line);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--o-subtle);
}
.station-table thead th { font-weight: inherit; }
.station-table tbody tr { border-bottom: 1px solid var(--o-line-soft); }
.station-table tbody tr:last-child { border-bottom: 0; }
.station-table .col-dist,
.station-table .col-price,
.station-table .col-extra { text-align: right; }

.station-row { color: var(--o-ink); cursor: pointer; }
.station-row:hover { background: var(--o-hover); }
.station-row:focus-visible { outline: 2px solid var(--o-accent); outline-offset: -2px; }
.station-table td.col-rank { font-family: var(--font-heading); font-weight: 800; font-size: 15px; color: var(--o-faint); }

/* Pastille, nom et adresse : grille nommée, pour que le téléphone n'ait qu'à
   redistribuer les zones. */
.station-id {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "badge name" "badge sub";
  align-items: center;
  column-gap: 12px;
}
.station-id .brand-badge { grid-area: badge; min-width: 28px; height: 28px; padding: 0 5px; border-radius: 7px; font-size: 10px; }
.station-name { grid-area: name; min-width: 0; font-size: 15px; font-weight: 600; }
.station-sub { grid-area: sub; min-width: 0; font-size: 12.5px; color: var(--o-subtle); }
.station-sub-phone { display: none; }
.row-warn { display: inline-flex; margin-left: 6px; vertical-align: -2px; color: var(--o-accent); cursor: help; }
.row-warn .ic { width: 14px; height: 14px; }

.station-table td.col-dist { font-size: 14px; white-space: nowrap; }
.col-eta { display: block; font-size: 12px; color: var(--o-subtle); }
.station-table td.col-price {
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 17px;
  font-variant-numeric: tabular-nums;
}
.station-table td.col-extra { font-size: 14px; font-variant-numeric: tabular-nums; color: var(--o-subtle); }

/* Prix périmés (plus de STALE_DAYS jours, voir app.js) : hors classement, en
   queue de tableau, en ton atténué, avec la date du relevé en orange. */
.station-row.is-stale { color: var(--o-subtle); }
.station-row.is-stale td.col-rank { color: inherit; }
.station-stale { font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--o-stale); }
.station-table tr.stale-sep { display: block; padding: 20px 24px 10px; border-bottom: 0; }
.stale-sep td {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--o-subtle);
}
.stale-sep .ic { width: 14px; height: 14px; }

.list-more { padding: 16px 24px; border-top: 1px solid var(--o-line-soft); text-align: center; }

/* Stations en rupture du carburant recherché (voir fetchRuptures dans app.js) :
   carte repliable sous le classement, lignes au gabarit du tableau mais
   inertes, et l'orange des signaux d'attention. */
.list-card + .rupture-card { margin-top: 16px; }
.rupture-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 24px;
  font-size: 14px;
  font-weight: 600;
  color: var(--o-ink);
  list-style: none;
  cursor: pointer;
}
.rupture-summary::-webkit-details-marker { display: none; }
.rupture-summary:hover { background: var(--o-hover); }
.rupture-summary:focus-visible { outline: 2px solid var(--o-accent); outline-offset: -2px; }
.rupture-summary > .ic:first-child { color: var(--o-stale); }
.rupture-summary > span { flex: 1; min-width: 0; }
.rupture-summary > .ic:last-child { color: var(--o-subtle); transition: transform .2s; }
.rupture-card[open] > .rupture-summary { border-bottom: 1px solid var(--o-line-soft); }
.rupture-card[open] > .rupture-summary > .ic:last-child { transform: rotate(180deg); }
.rupture-row { color: var(--o-subtle); }
.rupture-tag { font-family: var(--font-body); font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--o-stale); }

/* Sous 760 px, la colonne « Sur un plein » saute (elle reste dans la fiche). */
@media (max-width: 759.98px) {
  .station-table tr { grid-template-columns: 40px minmax(0, 1fr) 90px 80px; }
  .station-table .col-extra { display: none; }
}
/* Téléphone : rang · (pastille + nom / distance, trajet, ville) · (prix / surcoût). */
@media (max-width: 639.98px) {
  .station-table thead { display: none; }
  .station-table tr {
    grid-template-columns: 30px minmax(0, 1fr) auto;
    grid-template-areas: "rank id price" "rank id extra";
    gap: 2px 12px;
    padding: 14px 16px;
  }
  .station-table td.col-rank { grid-area: rank; font-size: 14px; }
  .station-table td.col-station { grid-area: id; }
  .station-table td.col-dist { display: none; }
  .station-table td.col-price { grid-area: price; align-self: end; }
  .station-table td.col-extra { display: block; grid-area: extra; align-self: start; font-size: 12px; }
  .station-row.is-stale td.col-extra { display: none; }
  .station-row.is-stale td.col-price { grid-row: 1 / 3; align-self: center; }
  .station-id { grid-template-areas: "badge name" "sub sub"; gap: 2px 8px; }
  .station-id .brand-badge { min-width: 22px; height: 22px; padding: 0 4px; border-radius: 6px; font-size: 9px; }
  .station-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .station-sub-wide { display: none; }
  .station-sub-phone { display: block; }
  .station-table tr.stale-sep { padding: 18px 16px 8px; }
  .list-more { padding: 14px 16px; }
  .rupture-summary { padding: 14px 16px; }
}

/* ═══════════════════ Squelette de chargement ═══════════════════ */
.sk {
  border-radius: 6px;
  background: var(--o-chip);
  animation: octFade 1.4s ease-in-out infinite;
}
.sk-meta { display: block; width: 260px; max-width: 70%; height: 14px; }
.winner-skeleton .winner-info { gap: 12px; }
.sk-tag { width: 120px; height: 24px; border-radius: var(--o-radius-pill); }
.sk-price { width: 280px; max-width: 100%; height: 86px; border-radius: var(--o-radius-md); }
.sk-name { width: 70%; height: 22px; }
.sk-addr { width: 90%; height: 14px; }
.sk-btn { width: 50%; height: 44px; margin-top: 10px; border-radius: var(--o-radius-md); }
@media (prefers-reduced-motion: reduce) {
  .sk { animation: none; }
}

/* ═══════════════════ Tendance et fraîcheur ═══════════════════
   Ces classes sont composées dynamiquement (`trend-${sign}`,
   `freshness-${tier}`), d'où leur absence de toute recherche littérale dans
   app.js. Elles habillent le bloc gagnant et la fiche détail. Teintes
   sémantiques du design system (--o-up, --o-down, --o-stale) : une hausse
   signalée par l'accent de la marque serait illisible. */
.trend-up { color: var(--o-up); }
.trend-down { color: var(--o-down); }
.trend-flat { color: var(--o-subtle); }

.freshness-fresh { color: var(--o-subtle); }
.freshness-stale { color: var(--o-stale); }
.freshness-veryStale { color: var(--o-up); }

/* ═══════════════════ Badge d'enseigne ═══════════════════
   Les couleurs viennent des marques elles-mêmes (Total, Shell…), pas du
   système : c'est leur identité, la neutraliser rendrait le repère inutile.
   Enseigne inconnue ou prix périmé : pastille neutre. Taille de base (22 px),
   agrandie par le bloc gagnant (34) et le tableau (28). */
.brand-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  min-width: 22px;
  height: 22px;
  padding: 0 4px;
  border-radius: 6px;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 9px;
  letter-spacing: .02em;
}
.brand-badge-neutral { background: var(--o-chip); color: var(--o-subtle); }

/* ═══════════════════ Bandeau « reprendre la dernière recherche » ═══════════
   Posé au-dessus du hero, vitré comme sa carte. */
.resume-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 14px;
  margin-top: 4px;
  padding: 10px 10px 10px 12px;
  border: 1px solid var(--o-line);
  border-radius: 16px;
  background: var(--o-glass);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  box-shadow: var(--o-sh-badge);
}
.resume-text { flex: 1 1 240px; margin: 0; font-size: 14px; color: var(--o-muted); }
.resume-text strong { font-weight: 600; color: var(--o-ink); }
.resume-actions { display: flex; gap: 8px; margin-left: auto; }

/* ═══════════════════ Indication de chargement des enseignes ═══════════════ */
.osm-hint {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 12px;
  color: var(--o-subtle);
}
.loader-sm {
  display: inline-block;
  width: 10px; height: 10px; flex: none;
  border: 2px solid var(--o-line);
  border-top-color: var(--o-accent);
  border-radius: 50%;
  animation: octSpin .8s linear infinite;
}

/* ═══════════════════ Carte ═══════════════════
   Plan IGN en gris (token --o-tile-filter, inversé en thème sombre) et
   épingles de la maquette : la moins chère en accent avec son prix, les
   autres à leur rang, un point d'encre pour la position de départ. */
.station-map {
  position: relative;
  z-index: 0;          /* contient les z-index de Leaflet (jusqu'à 1000) */
  isolation: isolate;
  height: 500px;
  overflow: hidden;
  border: 1px solid var(--o-line);
  border-radius: 20px;
  background: var(--o-chip);
  box-shadow: var(--o-sh-card);
}
.station-map.leaflet-container { background: var(--o-chip); font: inherit; }
.station-map .leaflet-tile-pane { filter: var(--o-tile-filter); }
@media (max-width: 639.98px) {
  .station-map { height: 400px; }
}

/* Épingle : étiquette et pointe en losange. Leaflet pose l'élément sur la
   coordonnée ; la translation y amène le bas de la pointe. */
.map-pin { background: none; border: 0; }
.pin {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  transform: translate(-50%, -100%);
}
.pin-label {
  display: flex;
  align-items: center;
  height: 28px;
  padding: 0 8px;
  border-radius: var(--o-radius-sm);
  background: var(--o-surface);
  color: var(--o-ink);
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 12px;
  white-space: nowrap;
  box-shadow: 0 6px 16px -4px rgba(24, 24, 27, .4);
}
.pin::after {
  content: "";
  width: 10px;
  height: 10px;
  margin-top: -5px;
  background: var(--o-surface);
  transform: rotate(45deg);
}
.pin-best .pin-label { height: 36px; padding: 0 12px; background: var(--o-accent); color: var(--o-on-accent); font-size: 14px; }
.pin-best::after { background: var(--o-accent); }
.pin-stale .pin-label { background: var(--o-chip); color: var(--o-subtle); box-shadow: none; }
.pin-stale::after { background: var(--o-chip); }
.pin-rupture .pin-label { min-width: 24px; justify-content: center; background: var(--o-chip); color: var(--o-stale); box-shadow: none; }
.pin-rupture::after { background: var(--o-chip); }
.map-pin:focus-visible { outline: 0; }
.map-pin:focus-visible .pin-label { outline: 2px solid var(--o-accent); outline-offset: 2px; }

/* Position de départ. */
.map-me { background: none; border: 0; }
.map-me span {
  display: block;
  width: 16px;
  height: 16px;
  border: 3px solid var(--o-surface);
  border-radius: 50%;
  background: var(--o-ink);
  box-shadow: 0 0 0 6px rgba(24, 24, 27, .12);
}

/* Regroupements (Leaflet.markercluster) : pastille d'encre au nombre de
   stations, dessinée par app.js (iconCreateFunction). */
.map-cluster { background: none; border: 0; }
.map-cluster span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 3px solid var(--o-surface);
  border-radius: 50%;
  background: var(--o-ink);
  color: var(--o-bg);
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 13px;
  box-shadow: 0 6px 16px -4px rgba(24, 24, 27, .4);
}

/* Contrôles, attribution et bulles de Leaflet, réaccordés au design system. */
.station-map .leaflet-bar {
  overflow: hidden;
  border: 1px solid var(--o-line);
  border-radius: var(--o-radius-sm);
  box-shadow: var(--o-sh-sm);
}
.station-map .leaflet-bar a {
  width: 34px;
  height: 34px;
  border-bottom-color: var(--o-line-soft);
  background: var(--o-surface);
  color: var(--o-ink);
  font: 600 18px/34px var(--font-body);
}
.station-map .leaflet-bar a:hover { background: var(--o-chip); color: var(--o-ink); }
.station-map .leaflet-bar a.leaflet-disabled { background: var(--o-surface); color: var(--o-faint); }
.station-map .leaflet-control-attribution {
  margin: 0 8px 8px 0;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--o-glass);
  color: var(--o-subtle);
  font-size: 11px;
}
.station-map .leaflet-control-attribution a { color: var(--o-subtle); }
.station-map .leaflet-popup-content-wrapper {
  border: 1px solid var(--o-line);
  border-radius: 14px;
  background: var(--o-surface);
  color: var(--o-ink);
  box-shadow: var(--o-sh-card);
}
.station-map .leaflet-popup-tip { background: var(--o-surface); box-shadow: none; }
.station-map .leaflet-popup-content { margin: 14px 16px; font-family: var(--font-body); font-size: 13px; line-height: 1.45; }
.station-map a.leaflet-popup-close-button { top: 6px; right: 6px; color: var(--o-subtle); }
.pop { display: flex; flex-direction: column; gap: 4px; }
.pop-head { display: flex; align-items: center; gap: 8px; padding-right: 14px; }
.pop-name { font-family: var(--font-heading); font-weight: 800; font-size: 15px; line-height: 1.2; }
.pop-addr { font-size: 12px; color: var(--o-subtle); }
.pop-facts { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin-top: 4px; color: var(--o-muted); }
.pop-price { font-family: var(--font-heading); font-weight: 800; font-size: 16px; font-variant-numeric: tabular-nums; color: var(--o-ink); }
.pop-stale,
.pop-rupture { font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--o-stale); }
.pop .btn { align-self: flex-start; margin-top: 8px; }

/* ═══════════════════ Onglet Historique ═══════════════════
   Même carte que la liste : une ligne par station, rang, identité, courbe. */
.history-list {
  overflow: hidden;
  border: 1px solid var(--o-line);
  border-radius: 20px;
  background: var(--o-surface);
  box-shadow: var(--o-sh-card);
}
.history-card {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) minmax(240px, 1.2fr);
  gap: 16px;
  align-items: center;
  padding: 16px 24px;
  border-bottom: 1px solid var(--o-line-soft);
}
.history-card:last-child { border-bottom: 0; }
/* La dernière carte porte déjà le filet qui sépare le bouton « Afficher les
   N autres ». */
.history-list > .list-more { border-top: 0; }
.history-card .rank { font-family: var(--font-heading); font-weight: 800; font-size: 15px; color: var(--rank-color, var(--o-faint)); }
.history-card .info { min-width: 0; }
.history-card .name { display: flex; align-items: center; gap: 12px; font-size: 15px; font-weight: 600; }
.history-card .name .brand-badge { min-width: 28px; height: 28px; padding: 0 5px; border-radius: 7px; font-size: 10px; }
.history-card .addr { margin-top: 2px; padding-left: 40px; font-size: 12.5px; color: var(--o-subtle); }
.name-text { min-width: 0; overflow-wrap: anywhere; }

.hist-body { min-width: 0; }
.hist-empty { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--o-subtle); }
.sparkline { display: block; width: 100%; max-width: 260px; height: 60px; color: var(--o-accent); }
.hist-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-top: 4px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--o-subtle);
}
.hist-stats strong { font-weight: 600; color: var(--o-ink); }
.hist-trend { width: 100%; }
.hist-trend.up { color: var(--o-up); }
.hist-trend.down { color: var(--o-down); }
.hist-trend.flat { color: var(--o-subtle); }
.hist-note { display: flex; align-items: center; gap: 10px; padding: 18px 24px; font-size: 14px; color: var(--o-text); }
.hist-note .ic { width: 18px; height: 18px; color: var(--o-subtle); }

@media (max-width: 639.98px) {
  .history-card { grid-template-columns: 30px minmax(0, 1fr); gap: 8px 12px; padding: 14px 16px; }
  .history-card .rank { font-size: 14px; }
  .history-card .name { gap: 8px; }
  .history-card .name .brand-badge { min-width: 22px; height: 22px; padding: 0 4px; border-radius: 6px; font-size: 9px; }
  .history-card .name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .history-card .addr { padding-left: 30px; }
  .history-card .hist-body { grid-column: 1 / -1; }
  .sparkline { max-width: 100%; }
}

/* ═══════════════════ Fiche détail d'une station ═══════════════════
   Ordinateur : panneau centré. Téléphone : feuille qui monte du bas de
   l'écran. Le voile est la seule couleur hors tokens : un noir translucide,
   comme celui d'une ombre portée. */
.station-sheet {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 15, 17, .45);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  animation: sheetFade .18s ease-out;
}
:root[data-theme="dark"] .sheet-backdrop { background: rgba(0, 0, 0, .6); }
@keyframes sheetFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes sheetSlideUp { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.sheet-panel {
  position: relative;
  width: min(560px, calc(100% - 32px));
  max-height: 85vh;
  overflow-y: auto;
  padding: 24px;
  border: 1px solid var(--o-line);
  border-radius: var(--o-radius-xl);
  background: var(--o-surface);
  box-shadow: var(--o-sh-card);
  animation: sheetSlideUp .22s cubic-bezier(.16, 1, .3, 1);
  outline: none;
}
.sheet-close { position: absolute; top: 16px; right: 16px; }
body.sheet-open { overflow: hidden; }

.sheet-header { display: flex; flex-direction: column; gap: 6px; }
.sheet-title-row { display: flex; align-items: center; gap: 12px; margin-right: 48px; }
.sheet-title-row .brand-badge { min-width: 34px; height: 34px; padding: 0 6px; border-radius: 9px; font-size: 11px; }
.sheet-title-row h2 { margin: 0; font-size: 22px; line-height: 1.15; letter-spacing: -0.02em; }
.sheet-station { margin-top: -2px; }
.sheet-addr { font-size: 14px; color: var(--o-subtle); }
.sheet-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.sheet-actions .btn { flex: 1 1 auto; }

.sheet-section { margin-top: 22px; }
.sheet-section h3 {
  margin: 0 0 10px;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--o-subtle);
}

/* Bloc principal : le prix du carburant recherché, son relevé, la distance. */
.sheet-key {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px 24px;
  margin-top: 18px;
  padding: 16px 18px;
  border-radius: 16px;
  background: var(--o-chip);
}
.sheet-key-price { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.sheet-key-fuel {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--o-accent-ink);
}
.sheet-key-value {
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 40px;
  line-height: .95;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--o-ink);
  white-space: nowrap;
}
.sheet-key-unit { margin-left: .3em; font-size: .35em; font-weight: 700; letter-spacing: .02em; color: var(--o-subtle); }
.sheet-key-fresh { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }
.sheet-key-fresh .ic { width: 14px; height: 14px; }
.sheet-key-dist { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; font-size: 13px; color: var(--o-subtle); text-align: right; }
.sheet-key-num { font-family: var(--font-heading); font-weight: 800; font-size: 22px; color: var(--o-ink); }
.sheet-key-trip { margin-top: 2px; font-variant-numeric: tabular-nums; }

/* Autres carburants vendus : liste à filets, encadrée. */
.sheet-others {
  overflow: hidden;
  margin: 0;
  padding: 0;
  border: 1px solid var(--o-line-soft);
  border-radius: 14px;
  list-style: none;
}
.sheet-others li { display: flex; align-items: baseline; gap: 12px; padding: 10px 14px; font-size: 14px; }
.sheet-others li + li { border-top: 1px solid var(--o-line-soft); }
.sheet-fuel { flex: none; width: 84px; font-weight: 500; color: var(--o-muted); }
.sheet-other-price { font-family: var(--font-heading); font-weight: 800; font-variant-numeric: tabular-nums; }
.sheet-fresh { margin-left: auto; font-size: 12px; }
.sheet-rupture { font-size: 13px; color: var(--o-accent-ink); }

/* Réserves : prix aberrant (accent) ou prix ancien (neutre). */
.sheet-warn,
.sheet-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 16px;
  padding: 12px 14px;
  border-radius: var(--o-radius-md);
  font-size: 13px;
  line-height: 1.5;
}
.sheet-warn p,
.sheet-note p { margin: 0; }
.sheet-warn .ic,
.sheet-note .ic { margin-top: 2px; }
.sheet-warn { background: var(--o-accent-soft); color: var(--o-accent-ink); }
.sheet-note { background: var(--o-chip); color: var(--o-text); }

@media (max-width: 639.98px) {
  .station-sheet { align-items: flex-end; }
  .sheet-panel {
    width: 100%;
    max-height: 90vh;
    padding: 20px 16px 24px;
    border-bottom: 0;
    border-radius: var(--o-radius-xl) var(--o-radius-xl) 0 0;
  }
  .sheet-close { top: 12px; right: 12px; }
  @keyframes sheetSlideUp {
    from { transform: translateY(100%); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
  }
  .sheet-title-row h2 { font-size: 19px; }
}
