/* ═══════════ PaKego — habillage ═══════════ */
:root{
  --ink:#0C1411; --ink-2:#141F1B;
  --paper:#F1F3EF; --paper-2:#E7EBE5; --paper-3:#DBE1D9; --blanc:#fff;
  --lat:#D2542B; --lat-2:#F0764A; --lat-ink:#7E2B12;
  --vert:#0E5C4A; --vert-2:#14806A;
  --soleil:#F5B72E;
  --t1:#13201C; --t2:#4E5D57; --t3:#7C8A84;
  --ok:#1F8A5B; --warn:#C9861A; --crit:#8E2340; --info:#2C6E9B;
  --line:rgba(19,32,28,.11); --line-2:rgba(19,32,28,.2);
  --r:14px; --r-l:20px;
  --sh:0 1px 2px rgba(12,20,17,.06),0 6px 18px rgba(12,20,17,.05);
  --ease:cubic-bezier(.22,1,.36,1); --spring:cubic-bezier(.34,1.4,.5,1);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%}
body{margin:0;background:var(--paper);color:var(--t1);
  font-family:"Schibsted Grotesk",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased;overscroll-behavior-y:none}
h1,h2,h3{font-family:"Bricolage Grotesque","Schibsted Grotesk",system-ui,sans-serif;
  font-weight:800;letter-spacing:-.025em;margin:0;text-wrap:balance}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer;border:0;background:none}
.mono{font-family:"IBM Plex Mono",ui-monospace,monospace;font-variant-numeric:tabular-nums}
:focus-visible{outline:2px solid var(--lat);outline-offset:2px;border-radius:8px}

/* ── structure ── */
#ecran{min-height:100%;display:flex;flex-direction:column}
.vue{flex:1;display:none;flex-direction:column;animation:apparait .32s var(--ease)}
.vue.on{display:flex}
@keyframes apparait{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.corps{flex:1;padding:0 18px 100px;max-width:520px;width:100%;margin:0 auto}
.corps.large{max-width:1100px}

/* ── barre du haut ──────────────────────────────────────────────────

   CE QU'EMMANUEL A SIGNALÉ : « sur iPhone c'est compliqué de cliquer sur
   retour, le bouton est trop en haut et des fois ça reste caché. »

   Il avait raison, et la cause était dans le fichier index.html :
   viewport-fit=cover fait passer la page SOUS l'encoche et sous la barre
   d'état. Le bas de l'écran était protégé — env(safe-area-inset-bottom)
   est utilisé trois fois plus bas — mais pas le haut. Sur un iPhone à
   encoche, le bouton retour se retrouvait donc à moitié dessous.

   env(safe-area-inset-top) vaut 47 px sur un iPhone à encoche, 20 px sur
   les anciens, et 0 partout ailleurs : la barre descend exactement de ce
   qu'il faut, sans gaspiller de place sur les téléphones qui n'en ont
   pas besoin. On ajoute 22 px au lieu de 14 : un peu plus bas, comme
   demandé, y compris sur Android.

   Et le bouton passe de 36 à 44 px. Quarante-quatre, ce n'est pas un
   chiffre en l'air : c'est la taille minimale qu'Apple donne pour qu'un
   doigt atteigne une cible sans viser. */
.barre{display:flex;align-items:center;gap:12px;
  padding:calc(22px + env(safe-area-inset-top)) 18px 10px;
  max-width:520px;width:100%;margin:0 auto}
.barre.large{max-width:1100px}
.barre h2{font-size:21px;flex:1;min-width:0}
.retour{width:44px;height:44px;border-radius:14px;background:var(--paper-2);display:grid;place-items:center;flex:0 0 auto}
.retour:active{background:var(--paper-3)}

/* ── blocs ── */
.bloc{background:var(--blanc);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh);padding:16px;margin-bottom:12px}
.rang{display:flex;align-items:center;gap:12px}
.pousse{flex:1;min-width:0}
.pile{display:flex;flex-direction:column;gap:12px}
.mini{font-size:11.5px;letter-spacing:.07em;text-transform:uppercase;font-weight:700;color:var(--t3)}
.pt{font-size:13.5px;color:var(--t2)}
.sep{height:1px;background:var(--line);margin:14px 0}

/* ── lien discret ─────────────────────────────────────────────────
   « Mot de passe oublié ? » ne doit pas ressembler à un bouton : sinon
   il rivalise avec « Se connecter », et on clique dessus par erreur.
   Un lien souligné, centré, à sa place — visible quand on le cherche,
   invisible quand on ne le cherche pas. */
.lien-discret{
  display:block; width:100%; margin:14px 0 0; padding:10px;
  background:none; border:0; color:var(--t3);
  font-family:inherit; font-size:14px; text-decoration:underline;
  text-underline-offset:3px; cursor:pointer;
}
.lien-discret:active{ color:var(--lat) }

/* ── choisir un lieu ──────────────────────────────────────────────
   La recherche d'adresse passe devant, le quartier passe derrière.
   Raison : le centre d'un quartier ne dit rien de la distance réelle.
   Owendo fait des kilomètres de long — deux clients du même quartier
   peuvent être à 8 km ou à 22 km de Nzeng-Ayong. */
.cherche-boite{position:relative}
.cherche-res{position:relative}
.cherche-ligne{
  display:block;width:100%;text-align:left;padding:11px 13px;
  background:var(--blanc);border:1px solid var(--line);border-top:0;
}
.cherche-ligne:first-child{border-top:1px solid var(--line);border-radius:12px 12px 0 0;margin-top:6px}
.cherche-ligne:last-child{border-radius:0 0 12px 12px}
.cherche-ligne:only-child{border-radius:12px}
.cherche-ligne:active{background:var(--paper-2)}
.cherche-ligne b{display:block;font-size:14.5px}
.cherche-ligne .pt{display:block;font-size:12.5px}

/* Le point retenu : vert, nommé, avec sa croix pour le retirer. */
.lieu-pose{
  background:rgba(31,138,91,.07);border:1px solid rgba(31,138,91,.3);
  border-radius:13px;padding:12px 13px;
}

/* Le quartier, replié : présent pour les endroits qu'aucune carte ne
   connaît, mais jamais mis en avant. */
.repli{margin-top:10px}
.repli summary{cursor:pointer;padding:6px 0;list-style:none;text-decoration:underline;
  text-underline-offset:3px}
.repli summary::-webkit-details-marker{display:none}

/* ── boutons ── */
.btn{display:flex;align-items:center;justify-content:center;gap:9px;width:100%;padding:16px 20px;
  border-radius:14px;font-weight:700;font-size:16px;background:var(--t1);color:#fff;
  transition:transform .16s var(--spring),filter .2s}
.btn:active{transform:scale(.985)}
.btn.pri{background:linear-gradient(160deg,var(--lat-2),var(--lat));box-shadow:0 8px 22px rgba(210,84,43,.3)}
.btn.vert{background:linear-gradient(160deg,var(--vert-2),var(--vert));box-shadow:0 8px 22px rgba(14,92,74,.28)}
.btn.doux{background:var(--paper-2);color:var(--t1);box-shadow:none}
.btn.trait{background:transparent;border:1.5px solid var(--line-2);color:var(--t1);box-shadow:none}
/* Le rouge est réservé aux gestes qu'on ne défait pas : annuler la
   course d'un client, suspendre un compte. Il doit se distinguer du
   bouton neutre au premier coup d'œil. */
.btn.ko{background:linear-gradient(160deg,#A8324C,var(--crit));box-shadow:0 8px 22px rgba(142,35,64,.28)}
.btn.pt{padding:11px 16px;font-size:14px;border-radius:11px;width:auto}
.btn[disabled]{opacity:.45;pointer-events:none}
.btn .tourne{width:16px;height:16px;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;
  border-radius:99px;animation:tourne .7s linear infinite}
@keyframes tourne{to{transform:rotate(360deg)}}

/* ── champs ── */
.champ{display:block;margin-bottom:14px}
.champ .lab{display:block;font-size:13px;font-weight:600;color:var(--t2);margin-bottom:6px}
.saisie{width:100%;padding:14px;border-radius:13px;border:1.5px solid var(--line-2);background:var(--blanc);font-size:16px}
.saisie:focus{outline:none;border-color:var(--lat);box-shadow:0 0 0 4px rgba(210,84,43,.11)}
textarea.saisie{resize:none;min-height:80px}
.duo{display:flex;gap:12px}
.duo>*{flex:1;min-width:0}

/* ── portrait ── */
.avatar{border-radius:99px;object-fit:cover;display:grid;place-items:center;flex:0 0 auto;
  background:var(--paper-2);border:2px solid var(--blanc);box-shadow:var(--sh)}
.avatar-init{background:linear-gradient(150deg,var(--lat-2),var(--lat));color:#fff;
  font-family:"Bricolage Grotesque",sans-serif;font-weight:800}
.portrait{padding:0;border-radius:99px;flex:0 0 auto}
.photo-plus{position:absolute;right:-2px;bottom:-2px;width:24px;height:24px;border-radius:99px;
  background:var(--t1);color:#fff;display:grid;place-items:center;cursor:pointer;
  border:2px solid var(--blanc)}

/* ── étoiles de notation ── */
.etoiles{display:flex;gap:4px;justify-content:center}
.etoile{color:var(--paper-3);padding:4px;transition:transform .15s var(--spring),color .2s}
.etoile.on{color:var(--soleil)}
.etoile.on svg path{fill:currentColor}
.etoile:active{transform:scale(.88)}

/* ── annonces ── */
.annonce{display:flex;align-items:center;gap:12px;padding:15px;border-radius:var(--r);
  margin-bottom:10px;text-decoration:none;color:var(--t1);
  background:linear-gradient(150deg,#13201C,#1E3A31);box-shadow:var(--sh)}
.annonce,.annonce b,.annonce span{color:#fff}
.annonce b{display:block;font-size:15px;margin-bottom:2px}
.annonce>.pousse>span:last-child{font-size:13px;color:#A8B5AF}
.annonce-tag{display:inline-block;font-size:10.5px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;background:var(--lat);color:#fff;padding:3px 8px;border-radius:99px;
  margin-bottom:6px}

/* ── champ de mot de passe avec son œil ── */
.mdp-boite{position:relative;display:block}
.mdp-boite .saisie{padding-right:52px}
.mdp-oeil{position:absolute;right:4px;top:50%;transform:translateY(-50%);
  width:44px;height:44px;display:grid;place-items:center;color:var(--t3);border-radius:11px}
.mdp-oeil:active{background:var(--paper-2)}
.mdp-oeil:hover{color:var(--t2)}

/* ── pastilles ── */
.puce{display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:99px;
  font-size:12.5px;font-weight:600;background:var(--paper-2);color:var(--t2)}
.puce.ok{background:rgba(31,138,91,.13);color:var(--ok)}
.puce.att{background:rgba(201,134,26,.15);color:var(--warn)}
.puce.ko{background:rgba(142,35,64,.11);color:var(--crit)}
.puce.lat{background:rgba(210,84,43,.13);color:var(--lat-ink)}
.puce.sombre{background:var(--t1);color:#fff}

/* ── choix (cartes cliquables) ── */
.choix{width:100%;text-align:left;background:var(--blanc);border:1px solid var(--line);border-radius:var(--r);
  padding:15px;box-shadow:var(--sh);transition:.18s var(--ease);margin-bottom:10px;display:block}
.choix:active{transform:scale(.99)}
.choix.actif{border-color:var(--lat);box-shadow:0 0 0 3px rgba(210,84,43,.12)}
.icone{width:44px;height:44px;border-radius:14px;display:grid;place-items:center;flex:0 0 auto;
  background:var(--paper-2);color:var(--t2)}
.icone.plein{background:var(--lat);color:#fff}

/* ── segments ── */
.seg{display:flex;gap:6px;background:var(--paper-2);padding:4px;border-radius:13px}
.seg button{flex:1;padding:11px 6px;border-radius:10px;font-size:14px;font-weight:600;color:var(--t2);transition:.22s}
.seg button.on{background:var(--blanc);color:var(--t1);box-shadow:var(--sh)}

/* ── messages ── */
.note{border-radius:13px;padding:14px;font-size:14px;margin-bottom:12px}
.note.ok{background:rgba(31,138,91,.1);color:#12603D;border:1px solid rgba(31,138,91,.3)}
.note.ko{background:rgba(142,35,64,.07);color:var(--crit);border:1px solid rgba(142,35,64,.28)}
.note.att{background:#FFF6EC;color:#7A5209;border:1px solid rgba(201,138,18,.3)}
.note.info{background:rgba(44,110,155,.07);color:#1F5477;border:1px solid rgba(44,110,155,.22)}
/* ton posé : un avertissement que l'on lit, pas un panneau d'interdiction */
.note.tenue{background:var(--blanc);color:var(--t2);border:1px solid var(--line);
  border-left:3px solid var(--vert);border-radius:6px 13px 13px 6px;line-height:1.6}
.note.tenue b{color:var(--t1);font-weight:700}
.note b{display:block;margin-bottom:3px}
.note strong{font-weight:700;color:var(--t1)}   /* accent au fil du texte, sans passer à la ligne */

/* ── conditions de livraison (lues et acceptées avant commande) ── */
.cond{background:#FDF6F7;border:1px solid rgba(142,35,64,.32);border-left:4px solid var(--crit);
  border-radius:6px 14px 14px 6px;padding:15px 16px;margin-bottom:12px}
.cond-titre{display:flex;align-items:center;gap:8px;font-weight:800;font-size:15px;color:var(--crit);
  font-family:"Bricolage Grotesque","Schibsted Grotesk",sans-serif;letter-spacing:-.015em;margin-bottom:10px}
.cond-liste{margin:0;padding-left:18px;font-size:13px;line-height:1.62;color:#5B2233}
.cond-liste li{margin-bottom:6px}
.cond-liste li::marker{color:rgba(142,35,64,.5)}
.cond-case{display:flex;align-items:flex-start;gap:11px;width:100%;text-align:left;margin-top:13px;
  padding:12px 13px;border-radius:12px;background:var(--blanc);border:1.5px solid rgba(142,35,64,.28);
  font-size:13.5px;font-weight:600;color:#5B2233;line-height:1.45;transition:.18s var(--ease)}
.cond-case:active{transform:scale(.99)}
.cond-case.on{border-color:var(--ok);color:#12603D;background:rgba(31,138,91,.06)}
.cond-case .coche{width:21px;height:21px;flex:0 0 auto;border-radius:6px;display:grid;place-items:center;
  border:1.5px solid rgba(142,35,64,.4);background:var(--blanc);margin-top:1px}
.cond-case.on .coche{background:var(--ok);border-color:var(--ok);color:#fff}

/* ── interrupteur en ligne / hors ligne ── */
.bascule{width:52px;height:30px;border-radius:99px;background:var(--paper-3);flex:0 0 auto;
  padding:3px;display:flex;transition:background .24s var(--ease)}
.bascule .pastille{width:24px;height:24px;border-radius:99px;background:var(--blanc);
  box-shadow:0 2px 6px rgba(12,20,17,.25);transition:transform .24s var(--spring)}
.bascule.on{background:var(--ok)}
.bascule.on .pastille{transform:translateX(22px)}

/* ── fil des étapes d'une course ── */
.fil{display:flex;flex-direction:column;gap:2px;margin-top:4px}
.fil-etape{display:flex;align-items:center;gap:10px;font-size:13.5px;color:var(--t3);padding:3px 0}
.fil-etape .fil-point{width:18px;height:18px;flex:0 0 auto;border-radius:99px;display:grid;place-items:center;
  border:2px solid var(--paper-3);background:var(--blanc);color:#fff}
.fil-etape.faite{color:var(--t2)}
.fil-etape.faite .fil-point{background:var(--ok);border-color:var(--ok)}
.fil-etape.ici{color:var(--lat-ink);font-weight:700}
.fil-etape.ici .fil-point{border-color:var(--lat);box-shadow:0 0 0 4px rgba(210,84,43,.15)}

/* ── tableau des comptes ── */
.compte{width:100%;border-collapse:collapse;font-size:13.5px}
.compte th{font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;font-weight:700;
  color:var(--t3);text-align:right;padding:0 0 8px;font-family:"Schibsted Grotesk",sans-serif}
.compte th:first-child{text-align:left}
.compte td{padding:7px 0;border-top:1px solid var(--line);font-variant-numeric:tabular-nums}

/* ── pièces d'un dossier ── */
.piece{width:100%;border-radius:11px;display:block;background:var(--paper-2);
  border:1px solid var(--line);max-height:420px;object-fit:contain}

/* ── palmarès ── */
.rang-num{width:26px;height:26px;flex:0 0 auto;border-radius:99px;display:grid;place-items:center;
  background:var(--paper-2);color:var(--t2);font-size:12.5px;font-weight:800;
  font-family:"Bricolage Grotesque",sans-serif}
.point-vert{display:inline-block;width:8px;height:8px;border-radius:99px;background:var(--ok);
  margin-left:5px;vertical-align:1px}

/* ── la semaine en barres ── */
.semaine{display:flex;align-items:flex-end;gap:6px;height:120px}
.semaine-jour{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;
  height:100%;gap:5px;min-width:0}
.semaine-val{font-family:"IBM Plex Mono",monospace;font-size:9.5px;font-weight:600;color:var(--t3);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.semaine-barre{width:100%;border-radius:5px 5px 2px 2px;background:var(--paper-3);
  transition:height .4s var(--ease)}
.semaine-nom{font-size:11px;color:var(--t3);font-weight:600}
.semaine-jour.auj .semaine-barre{background:linear-gradient(180deg,var(--lat-2),var(--lat))}
.semaine-jour.auj .semaine-nom{color:var(--lat);font-weight:700}
.semaine-jour.auj .semaine-val{color:var(--lat-ink)}

/* ── sceau de certification ── */
.sceau{display:inline-flex;align-items:center;color:var(--vert-2);vertical-align:-3px;flex:0 0 auto}
.bandeau-certif{display:flex;align-items:center;gap:10px;padding:12px 14px;margin-bottom:12px;
  border-radius:13px;background:rgba(20,128,106,.09);border:1px solid rgba(20,128,106,.26);color:var(--vert)}
.bandeau-certif>span{display:flex;flex-direction:column;line-height:1.35}
.bandeau-certif b{font-size:14.5px}
.bandeau-certif span span{font-size:12.5px;color:var(--t2)}

/* ── trois boutons de contact côte à côte ── */
.trio{display:flex;gap:8px}
.trio>*{flex:1;min-width:0;padding:11px 8px;font-size:13.5px;border-radius:11px;width:auto}

/* ── code de réception ── */
.code-bloc{text-align:center;padding:6px 0 2px}
.code-valeur{font-size:44px;font-weight:600;letter-spacing:.34em;text-indent:.34em;color:var(--lat-ink);
  background:rgba(210,84,43,.08);border:1px dashed rgba(210,84,43,.4);border-radius:12px;
  padding:12px 8px;margin:7px 0 8px}

/* ── bandeau bas ── */
/* Même oubli qu'en haut : sur iPhone, la barre de navigation du bas
   mangeait le bas des onglets. Le trait horizontal du téléphone passe
   par-dessus, et « Mon compte » devenait difficile à atteindre. */
.onglets{position:fixed;bottom:0;left:0;right:0;
  height:calc(72px + env(safe-area-inset-bottom));display:flex;
  padding:8px 8px calc(14px + env(safe-area-inset-bottom));z-index:30;
  background:linear-gradient(to top,var(--paper) 62%,rgba(241,243,239,0));backdrop-filter:blur(10px)}
.onglets .in{display:flex;max-width:520px;width:100%;margin:0 auto}
.onglets button{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;
  font-size:10.5px;font-weight:600;color:var(--t3)}
.onglets button.on{color:var(--lat)}

/* ── bas de page collé ── */
.socle{position:fixed;bottom:0;left:0;right:0;padding:12px 18px calc(12px + env(safe-area-inset-bottom));
  background:linear-gradient(to top,var(--paper) 70%,rgba(241,243,239,0));z-index:20}
.socle .in{max-width:520px;margin:0 auto}

/* ── accueil sombre ── */
.heros{flex:1;position:relative;display:flex;flex-direction:column;justify-content:flex-end;
  padding:30px 22px calc(28px + env(safe-area-inset-bottom));color:#fff;min-height:100dvh;
  background:linear-gradient(165deg,#13201C 0%,#0E2A22 52%,#3A1A0E 100%)}
.heros:before{content:"";position:absolute;inset:0;opacity:.5;
  background:radial-gradient(600px 400px at 80% 15%,rgba(210,84,43,.25),transparent 60%)}
.heros>*{position:relative}
.heros h1{font-size:clamp(28px,8vw,36px);line-height:1.08;color:#fff}
.heros p{color:#A8B5AF;font-size:15px;margin:12px 0 22px;max-width:32ch}
.marque{width:48px;height:48px;border-radius:15px;display:grid;place-items:center;margin-bottom:18px;
  background:linear-gradient(150deg,var(--lat-2),#A83A16);box-shadow:0 8px 24px rgba(210,84,43,.35)}
.porte{width:100%;text-align:left;padding:15px;border-radius:17px;margin-bottom:10px;color:#fff;
  background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.14);backdrop-filter:blur(8px)}
.porte:active{background:rgba(255,255,255,.12)}

/* ── divers ── */
.charge{padding:50px 20px;text-align:center;color:var(--t3);font-size:14px}
.vide{padding:36px 20px;text-align:center;color:var(--t3);font-size:14px}
.prix{font-family:"Bricolage Grotesque";font-weight:800;letter-spacing:-.03em}
.toast{position:fixed;left:14px;right:14px;bottom:88px;z-index:60;background:var(--t1);color:#fff;
  border-radius:14px;padding:14px 16px;font-size:14.5px;font-weight:600;box-shadow:0 12px 30px rgba(0,0,0,.3);
  transform:translateY(18px);opacity:0;pointer-events:none;transition:.3s var(--spring);max-width:490px;margin:0 auto}
.toast.on{transform:none;opacity:1}
.jauge{height:4px;background:var(--paper-3);border-radius:9px;overflow:hidden}
.jauge i{display:block;height:100%;background:var(--lat);transition:width .35s var(--ease)}
@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;transition-duration:.01ms!important}}

/* ── Jauge de force du mot de passe ──────────────────────────────── */
.jauge-mdp{
  flex:1; height:5px; border-radius:99px; background:var(--paper-2);
  display:block; overflow:hidden;
}
.jauge-mdp > i{
  display:block; height:100%; width:0; border-radius:99px;
  transition:width .18s ease, background .18s ease;
}

/* ── La carte ────────────────────────────────────────────────────
   La carte occupe tout ce qui reste entre la barre du haut et le
   socle du bas : sur un téléphone, une carte trop petite ne sert
   à rien. La mire est fixe au centre ; c'est le fond qui glisse. */
.carte-recherche{
  display:flex; gap:8px; padding:10px 16px 6px; align-items:stretch;
}
.carte-recherche .saisie{ flex:1; margin:0 }
.carte-recherche .btn{ width:auto; padding:0 16px; white-space:nowrap }

.carte-resultats{ padding:0 16px; max-height:190px; overflow-y:auto }
.carte-res{
  display:block; width:100%; text-align:left; background:var(--paper-2);
  border:1px solid var(--trait); border-radius:12px;
  padding:9px 12px; margin-bottom:6px; color:inherit; font:inherit; cursor:pointer;
}
.carte-res:active{ background:var(--trait) }
.carte-res b{ display:block; font-size:14px }
.carte-res .pt{ display:block }

.carte-boite{ position:relative; flex:1; margin:8px 0 0; min-height:280px }
.carte-zone{ position:absolute; inset:0; background:var(--paper-2) }
.carte-mire{
  position:absolute; left:50%; top:50%; margin-left:-17px; margin-top:-46px;
  pointer-events:none; z-index:500;
  filter:drop-shadow(0 4px 6px rgba(0,0,0,.35));
}
.carte-moi{
  position:absolute; right:14px; bottom:14px; z-index:500;
  width:44px; height:44px; border-radius:50%;
  background:var(--paper); border:1px solid var(--trait); color:var(--encre);
  display:grid; place-items:center; cursor:pointer;
  box-shadow:0 3px 10px rgba(0,0,0,.28);
}
.carte-socle{
  padding:12px 16px calc(16px + env(safe-area-inset-bottom));
  border-top:1px solid var(--trait); background:var(--paper);
}
.carte-socle .pt{ margin-bottom:10px }

/* L'écran carte est une colonne pleine hauteur, sans défilement. */
#ecran .vue:has(.carte-boite){ display:flex; flex-direction:column; height:100dvh }
#ecran .vue:has(.carte-boite) .carte-resultats{ flex:0 0 auto }

/* Leaflet pose ses propres couleurs ; on les ramène à celles de PaKego. */
.leaflet-control-attribution{
  font-size:10px !important; background:rgba(255,255,255,.78) !important;
}
.leaflet-bar a{ color:#1a1a1a !important }

/* ── Annonces avec image ─────────────────────────────────────────
   Ici la bannière, c'est l'image. Elle prend toute la largeur de la
   carte, en format horizontal 2,1:1 — le format des bannières qu'on
   voit partout. Le texte descend en dessous, en petit : il explique,
   il ne domine plus. Et s'il n'y a pas de texte du tout, l'image
   seule fait la bannière.

   aspect-ratio tient la hauteur quelle que soit la photo envoyée :
   une image carrée ou verticale est recadrée au centre plutôt que
   de déformer la page. */
.annonce.avec-image{
  display:block; padding:0; overflow:hidden; position:relative;
}
/* L'étiquette (« Nouveau », « Promo ») se pose SUR l'image, dans le
   coin, comme sur les vraies bannières. Elle ne mange donc pas une
   ligne sous l'image. Si l'image ne charge pas, la classe avec-image
   tombe et l'étiquette reprend sa place normale dans le texte. */
.annonce.avec-image .annonce-tag{
  position:absolute; top:10px; left:10px; margin:0; z-index:1;
  box-shadow:0 2px 10px rgba(0,0,0,.35);
}
.annonce-img{
  display:block; width:100%; aspect-ratio:21 / 10; height:auto;
  object-fit:cover; object-position:center;
  background:rgba(255,255,255,.08);
}
.annonce-bas{
  display:block; padding:11px 14px 13px;
}
.annonce-bas .annonce-tag{ margin-bottom:5px }
.annonce-bas b{ display:block; font-size:14.5px; margin-bottom:2px }
/* Deux lignes au maximum sous l'image : au-delà, le texte reprend le
   dessus sur la bannière, ce qui est exactement ce qu'on corrige ici. */
.annonce-bas>span:last-child:not(.annonce-tag){
  font-size:12.5px; line-height:1.35; color:#A8B5AF;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden;
}
/* Repli quand l'image n'a pas chargé : la carte redevient une carte
   texte, donc son propre rembourrage suffit. */
.annonce:not(.avec-image) .annonce-bas{ padding:0 }

/* ── le défilement des annonces ──────────────────────────────────────
   Deux pistes identiques bout à bout ; le rail glisse de sa moitié puis
   repart à zéro. Comme les deux moitiés sont les mêmes, l'œil ne voit
   aucune coupure : le défilement paraît sans fin.

   overflow:hidden sur la zone, et rien d'autre : pas de barre de
   défilement, pas de balayage à apprendre. Ça bouge tout seul. */
.annonce-zone{
  overflow:hidden;
  /* Une diapositive, et le pas d'un cran. Les deux servent à la fois à
     la largeur des cartes et aux images-clés fabriquées dans app.js :
     une seule définition, donc impossible qu'elles se contredisent. */
  --diapo:min(calc(100vw - 64px), 460px);
  --pas:calc(var(--diapo) + 12px);
}

.annonce-rail{
  display:flex; width:max-content;
  animation-duration:var(--duree,15s);
  animation-timing-function:cubic-bezier(.65,0,.35,1);
  animation-iteration-count:infinite;
}
.annonce-piste{ display:flex; flex:0 0 auto }

/* Chaque diapositive fait la largeur de la zone moins un souffle : on
   aperçoit le bord de la suivante, ce qui dit sans un mot qu'il y en a
   d'autres derrière. */
.diapo{ flex:0 0 auto; width:var(--diapo); margin-right:12px }
.diapo>.annonce{ margin:0; width:100% }

/* Un doigt posé dessus arrête tout : sans ça, impossible d'appuyer sur
   une annonce qui bouge. */
.annonce-rail:hover, .annonce-rail:active,
.annonce-zone:focus-within .annonce-rail{ animation-play-state:paused }

/* Certains téléphones sont réglés pour ne rien animer — souvent parce
   que le mouvement donne la nausée à leur propriétaire. On respecte ce
   réglage : les annonces deviennent une bande qu'on fait glisser du
   doigt, ce qui marche tout aussi bien. */
@media (prefers-reduced-motion:reduce){
  .annonce-zone{ overflow-x:auto; scroll-snap-type:x mandatory;
                 -webkit-overflow-scrolling:touch }
  .annonce-rail{ animation:none }
  .annonce-piste[aria-hidden="true"]{ display:none }
  .diapo{ scroll-snap-align:center }
}

/* ── la jauge d'envoi ────────────────────────────────────────────────
   Une photo de pièce d'identité met parfois quarante secondes à partir
   sur une connexion de Libreville. Sans cette barre, l'écran affiche
   « Envoi… » sans bouger, et la moitié des gens réappuient — ce qui
   fait tout recommencer depuis zéro. */
.jauge-envoi{
  height:8px; border-radius:99px; background:var(--paper-3); overflow:hidden;
}
.jauge-envoi>span{
  display:block; height:100%; border-radius:99px;
  background:linear-gradient(90deg, #F0764A, #C24A22);
  transition:width .25s var(--ease);
}
/* Quand le serveur ne donne pas la taille du fichier, on ne peut pas
   compter : la barre balaie au lieu de mentir avec un pourcentage
   inventé. */
.jauge-envoi>span.indecise{
  background:linear-gradient(90deg, var(--paper-3) 25%, #F0764A 50%, var(--paper-3) 75%);
  background-size:200% 100%;
  animation:balayage 1.1s linear infinite;
}
@keyframes balayage{ from{ background-position:200% 0 } to{ background-position:-200% 0 } }

/* ── le prix négocié ─────────────────────────────────────────────────
   Le tarif barré n'est pas décoratif : c'est lui qui permet au livreur
   de juger en une seconde. Sans lui, 3 500 F peut être une petite course
   ou une grosse course au rabais. Il reste donc lisible — gris, plus
   petit, mais pas effacé. */
.barre-prix{
  display:block; font-size:12.5px; color:var(--t3);
  text-decoration:line-through; text-decoration-thickness:1.5px;
  line-height:1.2;
}

/* ── deux courses à la fois ──────────────────────────────────────────
   Le livreur peut en porter deux. L'écran n'en montre qu'une — celle
   qu'il fait — et ces deux onglets disent clairement laquelle, parce
   qu'un code de remise tapé sur la mauvaise course est une erreur qu'on
   ne rattrape pas. */
.deux-courses{ display:flex; gap:8px; margin-bottom:12px }
.onglet-course{
  flex:1; min-width:0; text-align:left; padding:10px 12px;
  background:var(--blanc); border:1px solid var(--line); border-radius:14px;
}
.onglet-course b{
  display:block; font-size:13.5px; margin:2px 0 1px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.onglet-course .pt{ font-size:11.5px }
.onglet-course.on{
  border-color:var(--lat); background:var(--paper-2);
  box-shadow:0 0 0 3px rgba(210,84,43,.12);
}
.onglet-course.on .mini{ color:var(--lat) }

/* Back-office : la vignette dans la liste, l'aperçu dans le formulaire. */
.annonce-vignette{
  width:74px; height:35px; flex:0 0 74px; border-radius:9px;
  object-fit:cover; border:1px solid var(--trait); background:var(--paper-2);
}
/* L'aperçu du back-office montre EXACTEMENT le cadrage que verra le
   client : même format 2,1:1, même recadrage au centre. Sans ça on
   choisit une belle photo verticale et on découvre le désastre une
   fois l'annonce en ligne. */
.annonce-apercu{
  display:block; width:100%; aspect-ratio:21 / 10; height:auto;
  object-fit:cover; object-position:center;
  border-radius:var(--r); border:1px solid var(--trait);
  background:var(--paper-2); margin-bottom:10px;
}
