/* Job Fortera — mobile first (iPhone 12, 390px), THÈME SOMBRE forcé, sans scroll latéral. */
:root {
  --bg:#0d1117; --card:#161b22; --ink:#e6edf3; --muted:#8b949e; --line:#293040;
  /* OR, et non plus bleu (15/08). La marque était déjà dorée partout ailleurs —
     le monogramme, le bandeau de la page de connexion, sa `theme-color`
     #3a220d — et seul l'accent de l'application était resté bleu. Un bouton
     bleu sous un bandeau doré, ce n'était pas un parti pris, c'était un oubli. */
  --or:#d9a441; --or-clair:#f0c86a; --or-sourd:#8a6a2c; --bronze:#241708;
  --accent:var(--or); --accent-ink:#1a1206;
  --vert:#3fb950; --vert-bg:#123020; --orange:#e3a008; --orange-bg:#2b2310;
  --target:#a371f7; --danger:#f85149;
  --radius:14px; --tap:44px;
  /* Hauteurs des deux barres fixes. Nommées parce que trois règles en
     dépendent : la réserve de bas de page, la barre elle-même, et la carte
     qui occupe l'espace entre les deux. */
  --h-entete:65px; --h-barre:59px;
}

* { box-sizing:border-box; }
html,body { margin:0; padding:0; overflow-x:hidden; }

/* Le fond de la PAGE, pas seulement celui de la colonne (16/08). `body` est
   limité à 520 px et centré : au-delà, ce sont les marges de `html` qu'on voit.
   Il n'était peint qu'à partir de 640 px, pour l'encadrement du bureau — donc
   entre 520 et 640 px (fenêtre réduite, téléphone couché) deux bandes BLANCHES
   encadraient une application sombre. Peint sans condition, le défaut disparaît
   à toutes les largeurs ; le bloc 640 px ne garde que l'encadrement. */
html { background:#07090d; }
body {
  background:var(--bg); color:var(--ink); font:15px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  max-width:520px; margin:0 auto; padding-bottom:24px; -webkit-text-size-adjust:100%;
}
a { color:var(--accent); text-decoration:none; }

/* Header */
header.top {
  position:sticky; top:0; z-index:20; display:flex; align-items:center; gap:10px;
  padding:10px 14px; background:var(--card); border-bottom:1px solid var(--line);
}
header.top .brand-mark { width:26px; height:26px; border-radius:7px; }
header.top .logo { font-weight:800; font-size:17px; letter-spacing:-.3px; }
header.top .logo b { color:var(--accent); }
header.top .spacer { flex:1; }
/* Le hamburger a disparu (15/08) : tout est dans la barre basse. Reste une
   PORTE, seule à droite de l'en-tête. */
.sortie {
  width:var(--tap); height:var(--tap); display:flex; align-items:center; justify-content:center;
  color:var(--muted); flex:0 0 auto;
}
.sortie svg { width:21px; height:21px; fill:none; stroke:currentColor; }
.sortie:hover, .sortie:focus { color:var(--danger); }

/* Retour, en haut à GAUCHE — MÊME boîte que la porte, au même retrait du bord.
   Pas de marge négative : elle alignerait la flèche sur le texte du dessous,
   mais désaxerait les deux boutons de l'en-tête l'un par rapport à l'autre —
   or c'est cette barre-là qu'on regarde, et sa symétrie qui se voit. */
.retour {
  width:var(--tap); height:var(--tap); display:flex; align-items:center; justify-content:center;
  color:var(--ink); flex:0 0 auto;
}
.retour svg { width:22px; height:22px; fill:none; stroke:currentColor; }
.retour:hover, .retour:focus { color:var(--accent); }

/* `nav.menu` (hamburger) retiré le 15/08 avec son balisage. */

/* Champs de saisie (base commune) */
input, select, textarea, button {
  font:inherit; color:var(--ink); background:var(--card); border:1px solid var(--line);
  border-radius:10px; padding:10px 12px; min-height:var(--tap); width:100%;
}
button.primary { background:var(--accent); color:var(--accent-ink); border-color:var(--accent); font-weight:600; cursor:pointer; }

/* Puces (chips) — liens, boutons ou cases à cocher, même apparence */
.chip { flex:0 0 auto; width:auto; padding:7px 12px; min-height:36px; font-size:13px; border-radius:999px; cursor:pointer; }
.chip.on { background:var(--accent); color:var(--accent-ink); border-color:var(--accent); }
label.chip, a.chip { display:inline-flex; align-items:center; gap:6px; background:var(--card); border:1px solid var(--line); color:var(--ink); }
label.chip input { width:auto; min-height:0; margin:0; }
.chip.ghost { background:transparent; color:var(--muted); text-decoration:none; }

/* ───────── Barre du haut : cockpit + filtres posés ─────────
   Les styles `.searchrow`, `.vues`, `.quickrow` et `.pill` ont été retirés le
   15/08 avec la recherche, les onglets de vue et la rangée de raccourcis. */
.bar { padding:10px 14px 0; }

/* Résumé du résultat + filtres posés (chaque puce se retire d'un tap) */
.resume { display:flex; flex-wrap:wrap; align-items:center; gap:6px; font-size:12.5px; color:var(--muted); padding-bottom:8px; }
.resume b { color:var(--ink); font-size:14px; }
.resume .dot { color:var(--muted); white-space:nowrap; }
/* Teinte du prototype (`.actif`) : un critère POSÉ se distingue d'un bouton
   ordinaire par sa couleur, pas seulement par sa croix. */
.af { display:inline-flex; align-items:center; gap:6px; font-size:12px; background:#1d1608; border:1px solid var(--or-sourd); border-radius:999px; padding:6px 11px; min-height:32px; color:var(--or-clair); }
.af.off { border-style:dashed; color:var(--muted); }
/* Retirer un filtre est LE geste de correction : cible confortable au doigt,
   contrairement aux puces décoratives de la page CV qui gardent leur taille. */
.resume .af { min-height:34px; padding:6px 12px; font-size:12.5px; }
.resume .af span { color:var(--danger); font-weight:700; font-size:14px; }

/* ───────── Panneau de filtres (feuille remontant du bas) ───────── */
body.noscroll { overflow:hidden; }
.sheet { position:fixed; inset:0; z-index:40; display:flex; align-items:flex-end; justify-content:center; }
.sheet[hidden] { display:none; }
.sheet-bg { position:absolute; inset:0; background:rgba(0,0,0,.62); }
.sheet-panel {
  position:relative; width:100%; max-width:520px; max-height:88vh; display:flex; flex-direction:column;
  background:var(--card); border:1px solid var(--line); border-bottom:0; border-radius:18px 18px 0 0;
  animation:sheetin .18s ease-out;
}
@keyframes sheetin { from { transform:translateY(16px); opacity:.5 } to { transform:none; opacity:1 } }
.sheet-head { display:flex; align-items:center; gap:12px; padding:14px 16px 10px; border-bottom:1px solid var(--line); }
.sheet-head b { font-size:16px; flex:1; }
.sheet-head .raz { font-size:13px; }
.sheet-head .x { width:auto; padding:0 12px; min-height:36px; flex:0 0 auto; cursor:pointer; }
.sheet-body { overflow-y:auto; padding:2px 16px 14px; }
.sheet-body .field { margin:12px 0 0; }
.sheet-body .field select { margin-top:5px; }
.sheet-body .note { padding:14px 0 0; }
/* `.ck-coupe` sert à deux marqueurs du cockpit : « liste tronquée » (un <b>) et
   « collecte il y a N h » (un <a> vers le journal, qui dit POURQUOI). Le second
   ne doit pas se souligner ni changer de couleur : au milieu d'une ligne de
   compteurs, un lien bleu souligné se lirait comme une erreur de mise en page. */
.ck-coupe { color:var(--danger); font-weight:600; text-decoration:none; }
a.ck-coupe:active { opacity:.6; }

/* Porte discrète vers les pages sans onglet, en bas du panneau de filtres.
   Discrète VOLONTAIREMENT : on y va rarement, mais quand on la cherche, elle
   doit exister. */
.reglages-lien { display:flex; gap:8px; align-items:center; padding-top:14px; border-top:1px solid var(--line); margin-top:16px; }

.sw { display:flex; align-items:center; gap:10px; margin-top:16px; font-size:14px; }
.sw input[type=checkbox] { width:22px; height:22px; min-height:0; flex:0 0 auto; accent-color:var(--accent); }

/* Choix MULTIPLE (type de poste). Deux colonnes : huit familles tiennent alors
   dans un écran de téléphone sans faire défiler le panneau, et chaque libellé
   garde sa ligne. `fieldset` remis à plat — son cadre et ses marges par défaut
   n'ont rien à voir avec le reste du panneau. */
.champ-groupe { border:0; padding:0; margin:0 0 4px; min-width:0; }
.champ-groupe legend { padding:0; margin-bottom:8px; font-size:13px; color:var(--muted); }
.cases { display:grid; grid-template-columns:1fr 1fr; gap:8px 12px; }
.case {
  display:flex; align-items:center; gap:8px; font-size:14px;
  /* La zone tactile couvre le libellé, pas seulement la case de 20 px. */
  min-height:var(--tap); cursor:pointer;
}
.case input[type=checkbox] {
  width:20px; height:20px; min-height:0; flex:0 0 auto; accent-color:var(--accent); cursor:pointer;
}
.case span { line-height:1.25; }
@media (max-width:359px) { .cases { grid-template-columns:1fr; } }
.sheet-foot { display:flex; gap:10px; align-items:center; padding:12px 16px calc(14px + env(safe-area-inset-bottom)); border-top:1px solid var(--line); }
.sheet-foot .primary { flex:1; }

/* ───────── Liste d'offres ───────── */
main { padding:0 14px 6px; }
.card {
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  padding:11px 12px 9px; margin-bottom:9px;
}
.card.vert   { border-left:4px solid var(--vert); }
.card.orange { border-left:4px solid var(--orange); }
.cardlink { display:block; color:inherit; }   /* toute la carte ouvre l'offre */
.card .head { display:flex; justify-content:space-between; align-items:flex-start; gap:10px; }
.card .title { font-weight:650; font-size:15px; line-height:1.3; color:var(--ink); }
.card .sal { flex:0 0 auto; text-align:right; white-space:nowrap; font-weight:800; }
.card .sal.vert { color:var(--vert); } .card .sal.orange { color:var(--orange); }
.card .sal small { display:block; font-weight:500; font-size:10.5px; color:var(--muted); }
.card .meta { color:var(--muted); font-size:13px; margin-top:4px; }
.meta.synthese { font-size:12.5px; line-height:1.55; margin-top:3px; }
.card .foot { display:flex; align-items:center; gap:8px; margin-top:8px; }
.badges { display:flex; gap:5px; flex-wrap:wrap; align-items:center; flex:1; }
.b { font-size:11px; padding:2px 8px; border-radius:999px; border:1px solid var(--line); color:var(--muted); }
.b.target { background:transparent; color:var(--target); border-color:var(--target); }
.srclogo { display:inline-flex; align-items:center; justify-content:center; border-radius:5px; color:#fff; font-weight:800; line-height:1; flex:0 0 auto; }
.srcname { display:inline-flex; align-items:center; gap:6px; }

/* Actions de carte : deux icônes, pas deux gros boutons (2 offres de plus par écran) */
.quick { display:flex; gap:6px; flex:0 0 auto; }
.quick form { display:flex; width:auto; }
/* `.ic` a été supprimée le 15/08. C'étaient les boutons Suivre/Masquer des
   cartes, parties avec render_card() — mais la règle, elle, est restée, et
   `width:40px; min-height:40px; color:var(--muted)` s'appliquait aux icônes de
   la barre basse, qui portaient la même classe. Résultat visible à l'écran :
   une icône dans une boîte de 40 px (d'où l'écart avec son libellé) et
   toujours grise, même sur l'onglet actif. Une règle morte n'est pas inerte
   quand un nom de classe est générique. */

/* Pagination de la liste */
.pages { display:flex; align-items:center; justify-content:center; gap:10px; padding:8px 0 16px; font-size:13px; color:var(--muted); }
.pages .chip { min-height:40px; }

/* Actions pleine largeur (page détail) */
.actions { display:flex; gap:8px; margin-top:10px; }
.actions form { flex:1; }
.act { width:100%; min-height:40px; border-radius:10px; cursor:pointer; font-size:14px; }
.act.down.on { background:var(--orange-bg); color:var(--danger); border-color:var(--danger); }
.act.follow.on { background:var(--vert-bg); color:var(--vert); border-color:var(--vert); }

/* Âge de publication (code couleur de fraîcheur) */
.b.age-fresh { background:var(--vert-bg); color:var(--vert); border-color:transparent; }
.b.age-mid  { color:var(--muted); }
.b.age-old  { background:var(--orange-bg); color:var(--danger); border-color:transparent; }

/* Déconnexion : icône rouge (porte + flèche sortante) */
nav.menu a.logout { color:var(--danger); font-weight:600; }
nav.menu a.logout svg { width:20px; height:20px; margin-right:10px; stroke:var(--danger); fill:none; }

/* Détail */
.detail h1 { font-size:19px; margin:14px 0 4px; }
.detail .desc { white-space:pre-wrap; background:var(--card); border:1px solid var(--line); border-radius:var(--radius); padding:12px; margin-top:12px; font-size:14px; color:var(--ink); }
.kv { display:flex; gap:8px; flex-wrap:wrap; margin-top:10px; }
.kv .k { background:var(--card); border:1px solid var(--line); border-radius:10px; padding:6px 10px; font-size:13px; }
.big { display:block; width:100%; text-align:center; background:var(--accent); color:#fff; border-radius:12px; padding:14px; font-weight:700; margin-top:14px; min-height:var(--tap); }

/* Carte des offres (Leaflet) — empilée sur mobile, à côté de la liste sur grand écran */
.layout { display:block; }
/* `.mapcol` retiré : la carte a quitté l'accueil pour son onglet. */
/* `#map` n'a plus de hauteur ni de cadre imposés : la carte est plein écran
   dans son onglet, et `.mapfull` la dimensionne. Un sélecteur d'ID gagnait sur
   la classe et lui remettait 340 px et une bordure. */
#map { background:var(--card); }
.leaflet-popup-content-wrapper, .leaflet-popup-tip { background:var(--card); color:var(--ink); }
.leaflet-popup-content a { color:var(--accent); }
/* ═══ DESKTOP = LA MÊME VUE MOBILE, POSÉE SUR UN PLAN ═══════════════════════
   Arbitrage du propriétaire (15/08) : « la nav bar n'est pas cohérente avec le
   reste du site sur un desktop. Appli mobile uniquement, donc on affiche la vue
   mobile sur un desktop. »

   Ce qu'il voyait : une règle `@media (min-width:900px) { body { max-width:1100px } }`
   élargissait le contenu à 1 100 px pendant que la barre basse restait à 520 —
   mesuré, 1 100 contre 520 sur un écran de 1 280. Deux largeurs pour une même
   application. Cette règle datait de l'époque où la carte s'affichait À CÔTÉ de
   la liste ; la carte a son onglet depuis, `.layout` et `.mapcol` ont disparu du
   balisage, mais l'élargissement était resté.

   Il n'y a donc plus de « vue desktop » : une seule largeur, partout. L'écran
   large se contente d'encadrer la colonne pour qu'elle se lise comme un objet
   posé, au lieu de flotter au milieu du vide. */
@media (min-width:640px) {
  body {
    min-height:100vh;
    border-left:1px solid var(--line); border-right:1px solid var(--line);
    box-shadow:0 0 60px rgba(0,0,0,.55);
  }
  /* Les deux barres fixes suivent la colonne, pas la fenêtre. */
  .tabbar { border-left:1px solid var(--line); border-right:1px solid var(--line); }
}

/* Divers */
.empty { text-align:center; color:var(--muted); padding:40px 20px; }
.note { color:var(--muted); font-size:12px; padding:4px 14px 14px; }
label.field { display:block; font-size:13px; color:var(--muted); margin:10px 0 4px; }
table.journal { width:100%; border-collapse:collapse; font-size:13px; }
table.journal td { padding:8px 6px; border-bottom:1px solid var(--line); }
.login-wrap { max-width:420px; margin:12vh auto 0; padding:0 20px; text-align:center; }
.login-wrap .banner { width:100%; height:auto; border-radius:var(--radius); margin-bottom:10px; }
.err { background:var(--orange-bg); color:var(--danger); border-radius:10px; padding:10px; margin:10px 0; font-size:14px; }

/* ───────────── Générateur de CV ───────────── */
.cvpage { padding:14px; }
.cvpage .big-label { font-size:15px; font-weight:700; color:var(--ink); }
.cvform .field { margin-top:10px; }
.cvform textarea { min-height:120px; resize:vertical; }
.cvform .primary { margin-top:12px; width:100%; }
.cvor { text-align:center; color:var(--muted); font-size:12px; margin:4px 0; }
.cvresult { margin-top:18px; }
.cvats { display:flex; gap:14px; align-items:center; background:var(--card); border:1px solid var(--line); border-radius:12px; padding:12px 14px; margin-bottom:12px; }
.cvats-score { text-align:center; flex:0 0 auto; }
.cvats-score span { font-size:26px; font-weight:800; color:var(--accent); display:block; line-height:1; }
.cvats-score small { font-size:11px; color:var(--muted); }
.cvats-body { font-size:13px; color:var(--ink); }
.cvchips { margin-top:6px; display:flex; gap:6px; flex-wrap:wrap; align-items:center; }
.cvchips.muted { color:var(--muted); font-size:12px; }
.cvactions { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:14px; }
.cvactions form.inline { display:flex; gap:8px; width:auto; }
.cvactions .primary { width:auto; padding:10px 16px; }
.cvactions .chip { min-height:40px; }

/* Aperçu CV — feuille blanche = rendu d'impression (mono-colonne, lisible ATS) */
.cv { background:#fff; color:#1a1a1a; border-radius:10px; padding:26px 30px; font-size:13px; line-height:1.45; box-shadow:0 4px 22px rgba(0,0,0,.45); }
.cv .cv-head { border-bottom:2px solid #2456A6; padding-bottom:10px; margin-bottom:6px; }
.cv h1 { font-size:24px; margin:0; color:#111; letter-spacing:-.3px; }
.cv .cv-role { font-size:15px; font-weight:700; color:#2456A6; margin-top:2px; }
.cv .cv-devise { font-size:12px; color:#666; font-style:italic; margin-top:1px; }
.cv .cv-contact { font-size:12px; color:#333; margin-top:6px; }
.cv .cv-sec { margin-top:14px; }
.cv .cv-sec h2 { font-size:12.5px; text-transform:uppercase; letter-spacing:.6px; color:#2456A6; border-bottom:1px solid #dde3ec; padding-bottom:3px; margin:0 0 8px; }
.cv .cv-sec p { margin:0; }
.cv .cv-atouts { background:#f3f6fc; border-left:3px solid #2456A6; padding:7px 10px; margin-top:8px; font-size:12.5px; color:#1a1a1a; }
.cv .cv-skills { display:grid; gap:5px; }
.cv .cv-skill-g { font-weight:700; color:#111; }
.cv .cv-xp { margin-bottom:11px; }
.cv .cv-xp-h { display:flex; justify-content:space-between; gap:10px; align-items:baseline; }
.cv .cv-xp-role { font-weight:700; color:#111; }
.cv .cv-xp-date { font-size:11.5px; color:#666; white-space:nowrap; }
.cv .cv-xp-org { font-size:12px; color:#444; margin:1px 0 4px; }
.cv .cv-xp ul { margin:0; padding-left:18px; }
.cv .cv-xp li { margin-bottom:2px; }

@media print {
  @page { margin:12mm; }
  html, body { max-width:none; margin:0; background:#fff; }
  body * { visibility:hidden; }
  #cvdoc, #cvdoc * { visibility:visible; }
  #cvdoc { position:absolute; inset:0; width:100%; box-shadow:none; border-radius:0; padding:0; }
  header.top, nav.menu, .burger { display:none !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ACCUEIL — cockpit + tableau dense + barre basse (prototype validé, 15/08)
   ═══════════════════════════════════════════════════════════════════════════ */

/* La barre basse est FIXE : sans cette réserve, la dernière ligne du tableau
   vit sous elle et l'étoile de la dernière offre est intouchable. */
body { padding-bottom:calc(var(--h-barre) + env(safe-area-inset-bottom, 0px)); }

/* ── Cockpit ─────────────────────────────────────────────────────────────── */
.cockpit { padding:11px 14px 12px; background:var(--card); border-bottom:1px solid var(--line); }
.ck-head {
  display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:6px;
}
.ck-t { font-weight:600; font-size:10px; line-height:1; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.ck-n { font-size:11.5px; color:var(--muted); display:flex; align-items:center; gap:6px; }
.ck-n b { color:var(--ink); font-variant-numeric:tabular-nums; }
.ck-map {
  background:none; border:0; color:var(--muted); font-size:15px; cursor:pointer;
  min-width:32px; min-height:32px; padding:0; line-height:1;
}
.ck-map[aria-pressed="true"] { color:var(--or-clair); }
.ck-bar { display:flex; gap:2px; height:10px; border-radius:3px; overflow:hidden; background:#11161d; }
.ck-bar span { display:block; height:100%; }
.ck-leg { display:flex; flex-wrap:wrap; gap:4px 11px; margin-top:7px; }
.ck-leg > span {
  display:inline-flex; align-items:center; gap:5px; font-size:11px; color:var(--muted);
  font-variant-numeric:tabular-nums;
}
.ck-leg b { color:var(--ink); font-weight:700; }
.ck-leg .srclogo { width:15px; height:15px; font-size:7.5px; }

/* ── Tableau dense ───────────────────────────────────────────────────────── */
/* En-tête et lignes partagent la MÊME grille : c'est ce qui aligne les colonnes
   d'une ligne à l'autre. Une grille posée sur chaque ligne les ferait danser. */
.gh, .gr { display:grid; grid-template-columns:minmax(0,1fr) 70px 78px 30px; gap:7px; align-items:center; }
.gh {
  position:sticky; top:0; z-index:3; background:var(--bg); border-bottom:1px solid var(--line);
  padding:0 14px; font-weight:600; font-size:10px; line-height:1; letter-spacing:.05em; text-transform:uppercase; color:var(--muted);
}
.gh .th, .gh .th-fav { display:flex; align-items:center; min-height:38px; color:inherit; white-space:nowrap; }
.gh .th { text-decoration:none; }
.gh .th.on { color:var(--or-clair); }
.gh > .th:nth-child(3) { justify-content:flex-end; }   /* Salaire, aligné à droite comme ses chiffres */
.gh .th-fav { justify-content:center; }
.th-mid { display:flex; align-items:center; justify-content:flex-end; gap:6px; min-width:0; }
/* Choix de la colonne : nettement séparé de la flèche de tri, sinon « ▲ Net »
   se lit comme un seul contrôle. */
/* Chevron de changement de colonne : séparé de la flèche de tri par un filet,
   sinon « ▲ ▾ » se lit comme un seul contrôle à deux crans. */
.th-alt {
  color:var(--muted); text-decoration:none; font-size:11px; font-weight:400;
  padding-left:6px; border-left:1px solid var(--line); line-height:1;
}
.th-alt:hover, .th-alt:focus { color:var(--ink); }

.gr { padding:8px 14px; border-bottom:1px solid #1c222c; position:relative; }
.gr:active { background:#161d27; }
.c-poste { min-width:0; }
/* Lien ÉTIRÉ : le texte du poste est le libellé du lien (lisible au lecteur
   d'écran), mais la zone cliquable couvre toute la ligne. L'étoile repasse
   au-dessus grâce à son z-index. */
.c-poste .etire {
  display:block; font-weight:650; font-size:13.5px; line-height:1.25; color:var(--ink);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-decoration:none;
}
.c-poste .etire::after { content:''; position:absolute; inset:0; }
.c-poste .c {
  display:block; font-size:11.5px; color:var(--muted); margin-top:2px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.c-poste .tgt { font-size:10px; }
/* Une annonce morte ne s'affiche que sur demande : elle doit se voir tout de
   suite, sinon on ne comprend pas ce qu'elle fait dans la liste. */
.c-poste .morte {
  font-size:10px; font-weight:700; color:var(--danger);
  border:1px solid var(--danger); border-radius:4px; padding:0 4px; margin-left:2px;
}
.bandeau-morte {
  display:flex; gap:9px; align-items:flex-start; margin:12px 14px 0;
  background:var(--orange-bg); border:1px solid var(--danger); border-radius:11px;
  padding:11px 13px; font-size:13.5px; color:var(--ink); line-height:1.5;
}
.bandeau-morte b { color:var(--danger); }
.bandeau-morte small { display:block; color:var(--muted); font-size:12px; margin-top:3px; }
.c-mid {
  text-align:right; font-size:13px; font-weight:600; white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.c-mid.ok { color:var(--vert); }
.c-mid.ko { color:var(--danger); }
.c-mid.age-fresh { color:var(--vert); }
.c-mid.age-old { color:var(--danger); }
.c-mid small, .c-sal small { display:block; font-size:9.5px; color:var(--muted); font-weight:400; }
.c-sal {
  text-align:right; font-weight:800; font-size:13.5px; white-space:nowrap;
  font-variant-numeric:tabular-nums; color:var(--muted);
}
.c-sal.vert { color:var(--vert); }
.c-sal.orange { color:var(--orange); }
.c-fav { position:relative; z-index:1; display:flex; justify-content:center; }
.c-fav .fav {
  width:30px; height:36px; border:0; background:none; cursor:pointer; padding:0;
  color:#3d4551; font-size:16px; line-height:1;
}
.c-fav .fav.on { color:var(--or); }
/* Fraîcheur en 2ᵉ ligne, quand la colonne du milieu montre autre chose. */
.c-poste .age { font-style:normal; font-weight:700; }
.c-poste .age.age-fresh { color:var(--vert); }
.c-poste .age.age-mid { color:var(--ink); }
.c-poste .age.age-old { color:var(--danger); }

/* ── Barre de navigation basse ───────────────────────────────────────────── */
/* Cotes REPRISES DU PROTOTYPE, à l'unité près : bouton 52 px, padding 7/4,
   6 px sous la barre, icône 17 px, écart de 3 px, pastille à `top:4px;
   left:calc(50% + 6px)`. Les valeurs approchées d'une première passe (54 px,
   pastille collée au bord droit de l'icône) donnaient une barre plus haute et
   une pastille flottante — « la nav bar du bas ne correspond pas au
   prototype ». */
.tabbar {
  position:fixed; left:0; right:0; bottom:0; z-index:15; display:flex;
  max-width:520px; margin:0 auto;
  background:var(--card); border-top:1px solid var(--line);
  padding-bottom:calc(6px + env(safe-area-inset-bottom, 0px));
}
.tab {
  flex:1; background:none; border:0; cursor:pointer; color:var(--muted); position:relative;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  min-height:52px; font-weight:600; font-size:10.5px; line-height:1; padding:7px 0 4px;
  text-decoration:none; border-radius:0;
}
/* Sélecteur porté par `.tab` : `.ic` seul avait déjà servi ailleurs une fois. */
.tab .ic { font-size:17px; line-height:1; width:auto; min-height:0; padding:0; color:inherit; }
.tab.on, .tab.on .ic { color:var(--or-clair); }
.tab .badge {
  position:absolute; top:4px; left:calc(50% + 6px); background:var(--accent); color:var(--accent-ink);
  border-radius:999px; font-weight:800; font-size:9px; line-height:1; padding:3px 5px;
  min-width:15px; text-align:center; font-style:normal;
}

/* ── Filtres à saisie libre ──────────────────────────────────────────────── */
.grid2 { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.field.num { display:flex; flex-direction:column; gap:5px; }
/* L'unité vit DANS l'encadré, à droite du chiffre. Posée sous le champ, elle
   passait pour une légende et le cadre paraissait vide. */
.field.num .box {
  display:flex; align-items:center; gap:6px;
  background:var(--bg); border:1px solid var(--line); border-radius:10px; padding:0 10px;
  min-height:var(--tap);
}
.field.num .box:focus-within { border-color:var(--or-sourd); }
.field.num input {
  flex:1; min-width:0; width:100%; background:none; border:0; color:var(--ink);
  font-weight:600; font-size:15px; line-height:1; font-variant-numeric:tabular-nums; padding:0; outline:none;
}
.field.num .box i { font-style:normal; font-size:11px; color:var(--muted); white-space:nowrap; }

/* ── Carte, quatrième onglet ─────────────────────────────────────────────── */
/* La carte occupe TOUT ce qui reste sous l'en-tête et au-dessus de la barre
   basse. `dvh` suit la barre d'adresse des navigateurs mobiles, qui se replie
   au défilement : en `vh`, le bas de la carte passait sous la barre basse. */
/* Calée ENTRE les deux barres fixes, sans arithmétique de hauteur de fenêtre.
   Une première version soustrayait les barres de `100dvh` : mesurée, elle
   laissait 340 px de carte pour 844 px d'écran — `dvh` ne résout pas ce qu'on
   croit selon le navigateur, et une soustraction fausse ne se voit pas dans le
   code. Ici la carte prend simplement ce qui reste. */
.cartepage {
  position:fixed; top:var(--h-entete); bottom:var(--h-barre); left:0; right:0;
  max-width:520px; margin:0 auto; display:flex; flex-direction:column;
}
.mapfull { flex:1 1 auto; min-height:0; background:#11161d; }
.mapbar { flex:0 0 auto; }
.mapbar {
  display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;
  padding:8px 14px; border-top:1px solid var(--line); background:var(--card);
}
/* Cotes du prototype (`.actif`) : 32 px de haut, 12 px de texte, teinte dorée
   pour le cadrage EN COURS, contour sourd pour l'action secondaire. La
   première version reprenait `.chip` (36 px, 13 px, gris) : plus haute et plus
   pâle que tout ce que le prototype montre. */
.mapacts .chip { min-height:32px; padding:6px 11px; font-size:12px; gap:6px; }
.mapacts #recentrer { background:#1d1608; border-color:var(--or-sourd); color:var(--or-clair); }
.mapacts #toutvoir { background:transparent; border-color:var(--line); color:var(--muted); }
.mapinfo { font-size:12.5px; color:var(--muted); min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mapinfo b { color:var(--ink); font-variant-numeric:tabular-nums; }
.mapinfo .dot::before { content:'· '; }
.mapacts { display:flex; gap:6px; }
.mapacts .chip { white-space:nowrap; }
/* Les fonds de carte OpenStreetMap sont clairs : le texte des popups doit
   rester lisible dessus, pas hériter de l'encre du thème sombre. */
.leaflet-popup-content { color:#111; font-size:13px; line-height:1.45; }
.leaflet-popup-content a { color:#0a58ca; font-weight:600; }
/* Quatre onglets tiennent sur 390 px, mais de justesse : le libellé ne doit
   jamais passer à la ligne, sinon la barre grandit et pousse le contenu. */
.tab span:last-child { white-space:nowrap; }
