/* ── HIC SUNT · Sillage — features: carte, budget, activités, chat… ── */

/* ── carte plein écran — carte pleine, feuille inférieure ── */
.carte-full{flex:1;position:relative;overflow:hidden;background:var(--surface2)}
.carte-map-bg{position:absolute;top:0;left:0;width:100%;height:100%;background:var(--surface2);z-index:1}
.carte-map-real{position:absolute;inset:0;width:100%;height:100%}
/* Le géocodage (Nominatim) prend un instant avant que la carte ne se
   recentre sur les vraies étapes du voyage — sans indicateur, cette
   attente affiche une vue "tout le pays" dézoomée qui a l'air d'un bug
   figé plutôt que d'un chargement en cours. */
.hs-map-loading{
  position:absolute; inset:0; z-index:5;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px;
  background:var(--surface2);
  font-family:var(--mono); font-size:10.5px; font-weight:700; letter-spacing:0.8px;
  text-transform:uppercase; color:var(--sub);
  transition:opacity 0.3s var(--ease-out);
}
.hs-map-loading.out{ opacity:0; pointer-events:none }
.hs-map-spin{
  width:22px; height:22px; border-radius:50%;
  border:2.5px solid var(--line2); border-top-color:var(--gold);
  animation:hsMapSpin 0.8s linear infinite;
}
@keyframes hsMapSpin{ to{ transform:rotate(360deg) } }
.carte-top{position:absolute;top:14px;left:20px;right:20px;display:flex;justify-content:space-between;align-items:center;z-index:20}
/* Ne porte plus que le bouton rejouer (icône seule, mode Track) — la
   destination/le nombre de jours vivent maintenant dans .carte-sheet-head
   (retour de Charlotte : "le gros Sardaigne en haut on enlève"). */
.carte-pill{display:flex;align-items:center;gap:10px;padding:9px 16px 9px 11px;border-radius:var(--r-pill);background:var(--surface);box-shadow:0 6px 16px -8px rgba(31,26,20,.4);cursor:pointer;color:var(--ink);transition:transform 0.12s var(--spring),opacity 0.12s}
.carte-pill:active{transform:scale(0.95);opacity:0.8}
.carte-sheet{position:absolute;bottom:0;left:0;right:0;background:var(--surface);border-radius:var(--r-xl) var(--r-xl) 0 0;padding:0 20px calc(28px + env(safe-area-inset-bottom,0px));box-shadow:0 -14px 40px -18px rgba(31,26,20,.3);max-height:40%;display:flex;flex-direction:column;z-index:15;
  transition:transform 0.32s var(--spring)}
/* Repliée par la poignée (voir _enableCarteSheetCollapse, app.js) — ne
   quitte pas l'écran carte, juste assez remonté pour rester tapable et
   redéplier (retour de Charlotte : "je veux pouvoir voir la carte
   entière" sans être renvoyée à la fiche voyage). */
.carte-sheet.collapsed{transform:translateY(calc(100% - 40px))}
/* Le mode Track met les photos au centre du jeu (voir .track-step-big
   ci-dessous) — la feuille standard (40%, pensée pour la liste Plan)
   les aurait coupées à mi-hauteur. height (pas seulement max-height) :
   .track-steps{flex:1} a besoin d'une hauteur de conteneur ferme pour
   remplir l'espace, pas juste un plafond sur une hauteur "auto". */
.carte-sheet.track-big{height:58%; max-height:58%}
/* Voyage pas encore vécu : que des cartes d'étape compactes, aucune photo
   à cadrer — la feuille épouse son contenu au lieu d'imposer 58% d'écran
   à moitié vides (voir _trackSyncSheetHeight, track.js). */
.carte-sheet.track-big.track-lean{height:auto; max-height:46%}
.carte-sheet.track-big.track-lean .track-steps{flex:none; align-items:stretch}
/* En-tête de la feuille : destination + statistiques réelles du voyage
   (retour de Charlotte : retire le gros bandeau "Sardaigne · 7J" flottant
   sur la carte, remplacé par ceci, à l'intérieur de la card). .eyebrow
   (core.css) déjà la référence pour ce libellé mono/majuscule dans toute
   l'app — pas de nouvelle classe pour ça. */
.carte-sheet-head{flex:none;padding-top:14px;padding-bottom:12px}
.carte-sheet-title{font-family:var(--serif);font-weight:600;font-size:21px;letter-spacing:-0.2px;color:var(--ink);margin-top:3px}
.carte-sheet-stats{font-family:var(--mono);font-size:11.5px;color:var(--sub);margin-top:3px}

/* ── Bascule Plan/Track (mode Track façon Polarsteps — voir track.js) ── */
.track-toggle{display:flex;background:var(--surface);border-radius:var(--r-pill);padding:3px;gap:2px;box-shadow:0 6px 16px -8px rgba(31,26,20,.4)}
.track-toggle button{border:none;background:none;padding:7px 14px;border-radius:var(--r-pill);font-family:var(--sans);font-size:12.5px;font-weight:600;color:var(--sub);cursor:pointer;transition:all .15s}
.track-toggle button.on{background:var(--ink);color:var(--onink)}
[data-track-sheet]{display:flex;flex-direction:column;flex:1;min-height:0}
.track-scrubber{display:flex;align-items:center;gap:10px;flex:none;padding:10px 0 6px}
.track-scrubber input[type="range"]{flex:1;accent-color:var(--gold)}
.track-scrubber-label{font-family:var(--mono);font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--sub);white-space:nowrap}
/* Carrousel de photos "grand format" façon carrousel "For you" Polarsteps —
   capture envoyée par Charlotte : chaque étape prend l'essentiel de la
   largeur (la suivante se devine sur le bord), défilement avec accroche
   (scroll-snap) plutôt qu'un simple overflow libre. La carte au centre
   ressort en pleine taille/opacité, les voisines se réduisent légèrement
   (voir _trackWireStepsScale, track.js) — c'est ce mouvement au doigt qui
   fait "interactif" plutôt qu'une rangée statique. */
.track-steps{display:flex;gap:14px;overflow-x:auto;padding:6px 4px 4px;margin:0 -20px;padding-left:20px;padding-right:20px;
  flex:1; min-height:0; scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch}
.track-step-big{
  flex:none; width:78vw; max-width:260px; height:100%; min-height:180px;
  border-radius:var(--r-lg); overflow:hidden; position:relative; cursor:pointer;
  background:var(--fog-soft); scroll-snap-align:center;
  transform-origin:center; transition:transform .18s ease-out, opacity .18s ease-out;
  box-shadow:0 16px 30px -16px rgba(31,26,20,.4);
}
/* Zoom lent continu (même keyframe que .tile .wash, screens.css) — c'est
   l'"animation" demandée : la photo respire au lieu de rester figée comme
   sur une capture d'écran. */
.track-step-wash{position:absolute;inset:0;background-size:cover;background-position:center;
  animation:washKenBurns 16s ease-in-out infinite alternate; will-change:transform}
.track-step-scrim{position:absolute;inset:0;background:linear-gradient(180deg,rgba(20,17,14,0) 42%,rgba(20,17,14,.74) 100%)}
.track-step-transport{position:absolute;top:12px;right:12px;z-index:2;width:28px;height:28px;border-radius:50%;background:rgba(20,17,14,.42);color:#FFF;display:flex;align-items:center;justify-content:center}
.track-step-cap{position:absolute;left:14px;right:14px;bottom:14px;z-index:2;color:#FFF;
  font-family:var(--sans);font-size:15px;font-weight:700;line-height:1.28;
  text-shadow:0 1px 8px rgba(0,0,0,.4)}
/* Petite pastille de transport posée sur le marqueur photo du trail (voir
   .atlas-mb-pin/.atlas-mb-pin-photo, atlas.css — réutilisées telles
   quelles pour les étapes du mode Track). */
.track-pin-transport{position:absolute;bottom:-2px;right:-2px;width:18px;height:18px;border-radius:50%;background:var(--ink);color:#FFF;display:flex;align-items:center;justify-content:center;border:2px solid #FFF}
/* Étape simulée (itinéraire pas encore vécu, pas de photo réelle) — pastille
   pleine avec juste l'icône de transport plutôt qu'un fond image inexistant. */
/* Carte de carrousel équivalente, sans wash photo — même gabarit que
   .track-step-big, juste un dégradé plein à la place de la photo. */
/* Étape à venir (aucune photo — voyage pas encore vécu). Ce n'est pas une
   photo manquante, c'est une étape future : elle a sa propre forme, sur le
   fond clair de l'app, au lieu du grand aplat sombre qui ressemblait à une
   image cassée. Plus étroite aussi : il n'y a pas d'image à faire respirer,
   donc rien à justifier la largeur d'une carte photo. */
.track-step-plain{
  background:var(--surface); cursor:default;
  border:1px solid var(--fog-soft);
  box-shadow:0 10px 22px -14px rgba(31,26,20,.35);
  width:auto; min-width:186px; max-width:212px;
  /* Elle épouse son contenu et se centre, au lieu de s'étirer sur toute la
     hauteur de la feuille : sans photo à faire vivre, une carte pleine
     hauteur n'est qu'un grand vide avec trois mots dedans. */
  height:auto; min-height:0; align-self:flex-start;
  display:flex; flex-direction:column; padding:16px 18px;
}
.track-step-plain .tsp-top{display:flex;align-items:center;justify-content:space-between;gap:10px;flex:none}
.track-step-plain .tsp-num{font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--accent-texte,var(--accent))}
.track-step-plain .tsp-mode{display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;border-radius:var(--r-pill);background:var(--accent-tint);color:var(--accent-texte,var(--accent));flex:none}
.track-step-plain .tsp-body{padding:16px 0 14px}
.track-step-plain .tsp-lieu{font-family:var(--serif);font-weight:600;font-size:21px;line-height:1.15;
  letter-spacing:-.2px;color:var(--ink)}
.track-step-plain .tsp-zone{font-family:var(--sans);font-size:12px;color:var(--sub);margin-top:5px;line-height:1.35}
.track-step-plain .tsp-leg{font-family:var(--sans);font-size:10.5px;color:var(--ink-faint);flex:none;
  border-top:1px solid var(--fog-soft);padding-top:10px}

/* Marqueur mobile du replay animé (_trackPlayReplay, track.js) — un petit
   véhicule illustré posé sur la route plutôt qu'une pastille (retour de
   Charlotte, captures TikTok/Trip.com à l'appui) : pas de fond rond ni de
   pulsation, l'ombre portée (drop-shadow) suffit à le poser sur la carte,
   le déplacement + la rotation suffisent à lire "en mouvement". Simple
   point doré (sans forme de véhicule) quand l'étape d'arrivée n'a pas de
   moyen de transport renseigné, jamais une icône devinée pour un vrai
   trail. .track-replay-icon reste le point que Mapbox positionne (son
   transform lui appartient) ; .track-replay-icon-inner, un enfant, porte
   la rotation qui pointe le véhicule dans le sens du trajet sans jamais
   toucher au positionnement. */
/* Format d'un véhicule vu de profil (plus large que haut) — voir
   _trackVehicleSVG. L'ombre portée CSS reste très douce : le dessin porte
   déjà sa propre ombre au sol. */
.track-replay-icon{width:58px;height:41px;filter:drop-shadow(0 2px 6px rgba(20,18,14,.3))}
.track-replay-icon.empty{width:14px;height:14px;border-radius:50%;background:var(--gold,#9c7c44);border:2px solid #FFF}
.track-replay-icon-inner{display:flex;align-items:center;justify-content:center;width:100%;height:100%}
.track-replay-icon-inner svg{width:100%;height:100%;overflow:visible}

/* Sélecteur de mode de transport à l'ajout d'une photo (screens-detail.js
   addTripPhoto) — toggle simple, un seul mode actif à la fois. */
.trip-step-mode-btn{flex:1;height:52px;border-radius:var(--r-md);border:1px solid var(--line);background:var(--bg);display:flex;align-items:center;justify-content:center;color:var(--ink-soft);cursor:pointer;transition:all .15s}
.trip-step-mode-btn:active{transform:scale(.94)}
.trip-step-mode-btn.on{background:var(--ink);border-color:var(--ink);color:var(--onink)}
/* Zone tactile plus généreuse que le trait visible (38x4) — 20px de haut
   se ratait trop facilement au doigt (retour répété de Charlotte). */
.carte-handle-wrap{width:100%;height:32px;display:flex;align-items:center;justify-content:center;flex:none;margin-top:-4px;margin-bottom:-2px}
.carte-handle{width:38px;height:4px;border-radius:2px;background:var(--line2)}
.carte-daychips{display:flex;gap:8px;overflow-x:auto;padding-bottom:14px;margin:0 -20px;padding-left:20px;padding-right:20px;flex:none}
.map-chip{flex:none;width:46px;height:58px;border-radius:var(--r-md);border:1px solid var(--line);background:var(--bg);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;cursor:pointer;transition:all 0.18s}
.map-chip:active{transform:scale(0.92)}
.map-chip .mono{font-size:9px;color:var(--sub)}
.map-chip .serif{font-size:17px;color:var(--ink-soft)}
.map-chip.on{background:var(--surface);border-color:var(--ink);border-width:1.5px}
.map-chip.on .mono{color:var(--ink)}
.map-chip.on .serif{color:var(--ink);font-weight:600}
.carte-daytitle{display:flex;align-items:baseline;justify-content:space-between;margin:6px 0 14px;flex:none}
.carte-daytitle .serif{font-size:27px}
.carte-daytitle .serif em{font-style:italic;color:var(--gold)}
.carte-daytitle .mono{font-size:11px;color:var(--gold)}
.carte-agenda{overflow-y:auto}
.carte-mo{display:flex;gap:14px}
.carte-mo-rail{display:flex;flex-direction:column;align-items:center}
.carte-mo-dot{width:10px;height:10px;border-radius:50%;background:var(--gold);flex:none}
.carte-mo-line{width:2px;flex:1;background:var(--line2)}
.carte-mo:last-child .carte-mo-line{display:none}
.carte-mo-b{padding-bottom:16px}
.carte-mo-b .mono{font-size:11px;color:var(--sub)}
.carte-mo-t{font-size:15px;font-weight:600;margin-top:2px}
.carte-mo-d{font-size:12.5px;color:var(--ink-soft);margin-top:2px}
.map-svg{position:absolute;inset:0;width:100%;height:100%}
.map-svg .route{stroke:var(--gold);stroke-width:1.6;fill:none;stroke-dasharray:4 5;opacity:0.85}
.map-svg .mpin circle{fill:var(--ink);stroke:var(--bg);stroke-width:2}
.map-svg .mpin.on circle{fill:var(--gold)}
.map-svg .mpin text{fill:var(--onink);font-family:var(--mono);font-weight:700;text-anchor:middle}
.map-pop{position:absolute;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-card);padding:12px 14px;width:188px;z-index:4}
.map-pop .mp-k{font-family:var(--mono);font-size:9px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:var(--gold-deep)}
.map-pop .mp-t{font-family:var(--serif);font-weight:600;font-size:17px;margin-top:4px;line-height:1.2}
.map-pop .mp-m{display:flex;align-items:center;justify-content:space-between;margin-top:9px}
.map-pop .mp-wx{display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);font-size:9.5px;font-weight:700;color:var(--ink-soft)}
.map-pop .mp-wx .ico{color:var(--gold)}
.map-pop .mp-l{font-family:var(--mono);font-size:9px;font-weight:700;letter-spacing:0.6px;color:var(--gold);cursor:pointer;text-transform:uppercase;transition:opacity 0.1s}
.map-pop .mp-l:active{opacity:0.55}

/* ── budget ── */
.bud-card{margin-top:12px;margin-bottom:6px;background:var(--surface-raised);border:1px solid var(--line);border-radius:var(--card-radius);box-shadow:var(--shadow-raised);padding:24px;position:relative;overflow:hidden}
.bud-card::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(to right,transparent,var(--gold-soft),transparent);opacity:0.5}
.bud-card .contour{opacity:0.06}
.bud-l{font-family:var(--mono);font-size:9px;font-weight:700;letter-spacing:1.6px;text-transform:uppercase;color:var(--gold);position:relative}
.bud-v{font-family:var(--serif);font-weight:600;font-size:48px;letter-spacing:-1.5px;margin-top:10px;position:relative;line-height:1}
.bud-s{font-family:var(--mono);font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--sub);margin-top:7px;position:relative}
.bline{display:flex;align-items:center;gap:14px;padding:15px 0;border-bottom:1px solid var(--line2)}
.bline:last-child{border-bottom:none}
.bline .ico{color:var(--gold);flex:none}
.bline .bl-m{flex:1;min-width:0}
.bline .bl-n{font-size:14px;font-weight:600}
.bline .bl-s{font-family:var(--mono);font-size:9px;letter-spacing:0.6px;text-transform:uppercase;color:var(--sub);margin-top:3px}
.bline .bl-r{text-align:right;flex:none}
.bline .bl-v{font-family:var(--serif);font-weight:600;font-size:16px}
.bline .status{margin-top:5px}
.exp-del{flex:none;width:var(--tap-min);height:var(--tap-min);margin:calc((var(--tap-min) - 26px) / -2);border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--sub);cursor:pointer;-webkit-tap-highlight-color:transparent}
.exp-del:active{background:var(--surface2);color:var(--ink)}

/* ── activities ──
   Fusionne ce qui vivait ici et dans overlays.css (deux définitions
   complètes du même composant, silencieusement mélangées propriété par
   propriété par la cascade — désormais une seule source). Seul .ac-s
   change réellement : le poids 300 hérité de l'ancien bloc overlays.css
   n'avait jamais été repris ici, ce qui laissait ce libellé tout-capitales
   anormalement fin au lieu de 700 comme ses équivalents (.eyebrow, .bud-l…). */
.act-day{font-family:var(--mono);font-size:12px;font-weight:500;letter-spacing:1.4px;text-transform:uppercase;color:var(--sub);margin:22px 0 6px;padding-top:6px;border-top:1px solid var(--line2)}
.act-day:first-child{border-top:none;margin-top:8px}
.act{display:flex;align-items:center;gap:13px;min-height:var(--tap-comfortable);padding:13px 0;border-bottom:1px solid var(--line2);transition:opacity 0.1s}
.act:active{opacity:0.6}
.act:last-child{border-bottom:none}
.act .a-th{width:60px;height:60px;border-radius:var(--r-md);background:var(--tile-bg);display:flex;align-items:center;justify-content:center;color:var(--ink);flex:none}
.act .a-th .ico{opacity:0.3}
.act .ac-m{flex:1;min-width:0}
.act .ac-tag{font-family:var(--serif);font-style:italic;font-size:11px;font-weight:700;letter-spacing:0.8px;text-transform:uppercase;color:var(--gold-deep);margin-bottom:3px}
.act .ac-n{font-size:14px;font-weight:600;letter-spacing:-0.1px;line-height:1.3;margin-top:2px}
.act .ac-s{font-family:var(--mono);font-size:9px;font-weight:700;letter-spacing:0.5px;text-transform:uppercase;color:var(--sub);margin-top:4px;display:flex;align-items:center;gap:4px}
.act .ac-s .ico{color:var(--gold)}
.act .ac-r{display:flex;flex-direction:column;align-items:flex-end;gap:8px;flex:none}
.act .ac-p{font-family:var(--serif);font-weight:600;font-size:16px;letter-spacing:-0.2px}
.act-add{width:40px;height:40px;border-radius:50%;border:1px solid var(--line);background:var(--surface);color:var(--ink);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all 0.18s}
.act-add:active{transform:scale(0.88)}
.act-add.on{background:var(--ink);border-color:var(--ink);color:var(--gold-soft)}

/* ── review (réutilisé par gemsView pour les pépites) ── */
.review{padding:17px 0;border-bottom:1px solid var(--line2)}
.review:last-child{border-bottom:none}
.review .rv-top{display:flex;align-items:center;gap:11px}
.review .rv-n{font-size:13.5px;font-weight:600}
.review .rv-d{font-family:var(--mono);font-size:9px;letter-spacing:0.5px;text-transform:uppercase;color:var(--sub);margin-top:2px}
.review p{font-size:13.5px;font-weight:300;line-height:1.55;color:var(--ink-soft);margin-top:11px}

/* ── chat (cartographe) ── voir overlays.css pour .chat-nav/.chat-id/
   .chat-av/.bub/.composer/etc — ne pas les redéfinir ici, la cascade (chargement
   après overlays.css) les écraserait silencieusement. ── */

/* ── cercle — carte claire, plus de fond noir plein ── */
.cercle-card{margin-top:12px;background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:var(--card-radius);padding:22px;position:relative;overflow:hidden}
.cercle-card .contour{stroke:var(--gold-soft);opacity:0.15}
.cc-tier{font-family:var(--serif);font-weight:600;font-size:27px;position:relative}
.cc-pts{font-family:var(--mono);font-size:9.5px;letter-spacing:1.2px;text-transform:uppercase;color:var(--gold-deep);margin-top:6px;position:relative}
.cc-prog{height:3px;background:var(--line2);border-radius:3px;margin-top:18px;overflow:hidden;position:relative}
.cc-prog i{display:block;height:100%;background:var(--gold);width:0;transition:width 1.1s cubic-bezier(.22,.68,.2,1)}
.cc-next{font-family:var(--mono);font-size:8.5px;letter-spacing:0.8px;text-transform:uppercase;color:rgba(246,246,243,0.6);margin-top:9px;position:relative}
.perks{display:grid;grid-template-columns:1fr 1fr;gap:11px;margin-top:14px}
.perk{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);padding:14px}
.perk .ico{color:var(--gold)}
.perk .p-t{font-family:var(--serif);font-weight:600;font-size:14.5px;margin-top:9px;line-height:1.25}
.perk .p-d{font-size:11px;font-weight:300;color:var(--sub);line-height:1.45;margin-top:5px}
.hist{display:flex;align-items:center;justify-content:space-between;padding:13px 0;border-bottom:1px solid var(--line2)}
.hist:last-child{border-bottom:none}
.hist .hi-n{font-size:13.5px;font-weight:500}
.hist .hi-w{font-family:var(--mono);font-size:9px;letter-spacing:0.6px;text-transform:uppercase;color:var(--sub);margin-top:3px}
.hist .hi-p{font-family:var(--mono);font-size:11px;font-weight:700;color:var(--gold-deep)}

/* ── share ── */
.contrib{display:flex;align-items:center;gap:13px;padding:13px 0;border-bottom:1px solid var(--line2)}
.contrib:last-child{border-bottom:none}
.contrib .c-n{font-size:14px;font-weight:600}
.contrib .c-r{font-family:var(--mono);font-size:9px;letter-spacing:0.6px;text-transform:uppercase;color:var(--sub);margin-top:3px}
.contrib .c-you{margin-left:auto;font-family:var(--mono);font-size:8.5px;font-weight:700;letter-spacing:0.8px;text-transform:uppercase;color:var(--gold-deep)}

/* ── notifications ── */
/* Cartes plutôt que lignes séparées par un filet, groupées par jour comme
   dans un centre de notifications iOS : l'heure ne se lit plus comme une
   étiquette technique posée sous le texte, elle prend sa place naturelle
   en haut à droite. La pastille "non lu" qui flottait dans le coin est
   remplacée par un rail d'accent le long du bord gauche — on voit d'un
   coup d'œil ce qui est neuf sans chercher un point de 8 px. */
.notif-day{
  font-family:var(--mono); font-size:9.5px; letter-spacing:0.09em;
  text-transform:uppercase; color:var(--sub); margin:22px 2px 10px;
}
.notif-day:first-child{margin-top:2px}

/* ── Le bandeau « rejoindre », au-dessus d'un fil lu sans compte ────────
   Au-DESSUS des cartes, jamais devant : le visiteur est venu voir des
   voyages, il en voit. Le bandeau dit ce qu'un compte ouvre, une fois,
   sans revenir entre chaque carte. */
.fil-rejoindre{
  display:flex; align-items:center; gap:12px;
  padding:var(--p-md); margin-bottom:16px;
  border-radius:var(--card-radius); border:none;
  background:var(--surface); box-shadow:var(--shadow-card);
}
.fil-rejoindre-m{flex:1; min-width:0}
.fil-rejoindre-t{font-family:var(--sans); font-size:14px; font-weight:600; color:var(--ink)}
.fil-rejoindre-s{font-family:var(--sans); font-size:12.5px; font-weight:300; color:var(--sub); margin-top:2px; line-height:1.45}
/* .notif-wrap ne masque plus rien (le balayage a disparu) mais reste la
   ligne : c'est elle qui porte l'espacement et qui s'efface en hauteur à
   la suppression. */
.notif-wrap{position:relative; border-radius:var(--card-radius); margin-bottom:10px}
.notif-wrap:last-child{margin-bottom:0}
/* La gouttière de gauche appartient à TOUTES les cartes, lue ou non :
   c'est elle qui garde la pile alignée quand une pastille de non-lu
   apparaît ou disparaît (voir .notif.unread plus bas). */
.notif{
  display:flex; gap:13px; align-items:flex-start; padding:14px 15px 14px 26px;
  position:relative; cursor:pointer; touch-action:pan-y;
  border-radius:var(--card-radius); border:1px solid var(--line);
  background:var(--surface); box-shadow:var(--shadow-card);
  transition:opacity 0.1s, transform 0.18s ease;
}
.notif:active{opacity:0.62}
/* Le rond d'icône était en accent pâle avec une icône orange dedans,
   juste à côté d'avatars en teintes neutres : deux grammaires pour la
   même place dans la même liste. Il prend la même matière que les
   avatars. */
.notif .n-i{
  width:38px; height:38px; border-radius:50%; flex:none;
  display:flex; align-items:center; justify-content:center;
  background:var(--n-2); color:var(--ink);
}
.notif .n-m{flex:1; min-width:0}
.notif .n-h{display:flex; align-items:flex-start; gap:10px}
/* Deux lignes plutôt qu'une seule coupée : le titre porte la destination,
   qui se trouvait en fin de phrase et sautait donc systématiquement
   (« Ana Ribeiro a commenté votre… »). L'heure reste alignée sur la
   PREMIÈRE ligne — d'où le flex-start sur .n-h. */
.notif .n-t{
  font-size:14.5px; font-weight:600; letter-spacing:-0.005em;
  flex:1; min-width:0; overflow:hidden;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  line-height:1.32;
}
.notif .n-w{font-size:11.5px; color:var(--sub); flex:none; font-variant-numeric:tabular-nums; line-height:1.6}
/* Deux lignes au plus : un corps long ne doit pas faire d'une carte un
   pavé qui déséquilibre la liste. */
.notif .n-d{
  font-size:13px; font-weight:300; color:var(--sub); line-height:1.45; margin-top:3px;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
/* Le « non lu » ne se voyait pas. Le fond était un dégradé horizontal de
   #FEFCFB vers #FFFFFF — mesuré : UN point de valeur, un signal qui
   n'existe pas à l'œil. Et le liseré d'accent était rentré de treize
   pixels en haut et en bas, à bouts carrés, contre une carte à 20 pt
   d'arrondi : il flottait au milieu du bord, ça se lisait comme un
   accident. Fond plein, liseré sur toute la hauteur, épousant la carte. */
/* Le non-lu se disait par un FOND rose sur toute la carte plus un liseré
   d'accent sur toute la hauteur. Sur une pile de notifications fraîches,
   l'écran entier devenait rose et l'accent cessait de désigner quoi que
   ce soit — le défaut que Charlotte a nommé « ça fait vieillotte ».

   Il se dit maintenant comme dans toutes les boîtes de réception du
   monde : une PASTILLE, dans la gouttière prévue pour elle, plus le
   titre en gras. Un point de couleur de sept pixels sur du papier ivoire
   se voit d'un coup d'œil — c'est même le seul point de couleur de la
   pile, donc le plus visible qui soit. La carte, elle, reste une carte
   comme les autres. */
.notif.unread{
  border-color:var(--line);
  background:var(--surface);
}
.notif::before{
  content:''; position:absolute; left:11px; top:24px;
  width:7px; height:7px; border-radius:50%; background:transparent;
}
.notif.unread::before{ background:var(--accent) }
.notif.unread .n-t{font-weight:700}
.notif-load{display:flex;justify-content:center;padding:40px 0}
.notif-load i{width:22px;height:22px;border:2px solid var(--line);border-top-color:var(--accent, var(--gold));border-radius:50%;animation:spin 0.9s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ── fab ── */
.fab{position:absolute;right:22px;bottom:36px;width:54px;height:54px;border-radius:50%;border:1.5px solid var(--ink);background:var(--bg);color:var(--ink);display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-float);cursor:pointer;z-index:20;transition:transform 0.15s}
.fab:active{transform:scale(0.92)}

/* Repère d'étape SANS photo (tracé prévu) — voir _trackDrawLayers,
   track.js. Remplace la pastille photo de 48px, qui n'affichait qu'un
   grand disque vide tant que le voyage n'avait pas été vécu et masquait
   le tracé sous elle. */
.track-pin-step{
  cursor:pointer; width:26px; height:26px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:var(--accent, #1FA8A8); color:#FFFFFF;
  border:2px solid #FFFFFF;
  font-family:var(--mono); font-size:11px; font-weight:700; line-height:1;
  box-shadow:0 2px 8px rgba(31,26,20,.35);
}

/* ══ Mode cinéma du tracé (voir _trackCineHUD, track.js) ═══════════════
   Pendant la lecture, l'écran appartient à l'animation : la feuille du bas
   sort par le bas, la barre du haut s'efface, l'incrustation prend le
   relais. Rien n'est démonté du DOM — tout se joue en transformations,
   pour que la première frame de l'animation ne coûte aucun calcul de
   mise en page. */
.carte-full.cine .carte-sheet{
  transform:translateY(102%);
  transition:transform .5s cubic-bezier(.32,.72,0,1);
  pointer-events:none;
}
.carte-full.cine .carte-top{opacity:0; pointer-events:none; transition:opacity .3s ease}
.carte-sheet{transition:transform .5s cubic-bezier(.32,.72,0,1)}
.carte-top{transition:opacity .3s ease}

.track-cine{
  position:absolute; inset:0; z-index:6;
  display:flex; flex-direction:column; justify-content:space-between;
  opacity:0; pointer-events:none; transition:opacity .35s ease;
  /* 14px comme .carte-top, et SANS env(safe-area-inset-top) : la barre du
     repos n'en applique pas non plus (le conteneur d'overlay s'en charge).
     Avec l'inset en plus, la ligne du haut descendait de toute la hauteur
     de l'encoche — visiblement plus bas que le bouton retour qu'elle
     remplace (retour de Charlotte : « les titres du haut sont trop bas »).
     AUCUNE marge en bas : c'est le bandeau lui-même qui va jusqu'au bord
     et porte la marge de sécurité. Avec une marge ici, le bandeau
     s'arrêtait ~34px au-dessus du bord et laissait voir une bande claire
     de carte en dessous — le « bandeau blanc en bas » signalé par
     Charlotte, qui n'était ni la feuille ni un fond, juste la carte. */
  padding:14px 20px 0;
}
.track-cine.on{opacity:1}
.track-cine.on .tc-stop{pointer-events:auto}

.track-cine .tc-top{display:flex; align-items:center; justify-content:space-between; gap:12px}
.track-cine .tc-dest{
  font-family:var(--mono); font-size:10.5px; font-weight:600; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink);
  background:rgba(252,251,250,.82); border-radius:var(--r-pill); padding:7px 14px;
  box-shadow:0 4px 14px -6px rgba(31,26,20,.35);
}
.track-cine .tc-stop{
  width:34px; height:34px; border-radius:var(--r-pill); border:none; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  background:rgba(252,251,250,.82); color:var(--ink);
  box-shadow:0 4px 14px -6px rgba(31,26,20,.35);
}

/* Le bloc du bas : un seul texte à la fois, en grand, qui change au moment
   où on arrive — c'est toute la grammaire de ces vidéos. Le voile sombre
   ne sert qu'à garantir la lisibilité au-dessus d'une carte claire. */
/* Le voile ne doit pas ressembler à une brume grise posée sur la mer : il
   monte vite vers un fond franc, pour que le texte repose sur une matière
   et non sur un dégradé mou. Pas de flou d'arrière-plan — iOS le désactive
   quand « Réduire la transparence » est actif, et la lisibilité ne peut
   pas dépendre d'un réglage d'accessibilité. */
.track-cine .tc-bottom{
  display:flex; flex-direction:column; gap:15px;
  background:linear-gradient(180deg,
    rgba(16,36,31,0) 0%,
    rgba(16,36,31,.38) 26%,
    rgba(16,36,31,.86) 58%,
    rgba(16,36,31,.96) 78%,
    rgba(16,36,31,.98) 100%);
  margin:0 -20px 0;
  /* Le bas du bandeau réserve une bande pour l'attribution Mapbox, qui
     vient s'y poser (voir .mapboxgl-ctrl-bottom-*). Sans cette réserve,
     le logo chevauchait la barre de progression. */
  padding:74px 20px calc(42px + env(safe-area-inset-bottom,0px));
}
.track-cine .tc-step{display:flex; flex-direction:column; gap:5px}
.track-cine .tc-step.in{animation:tcStepIn .55s cubic-bezier(.22,1,.36,1) both}
@keyframes tcStepIn{
  from{opacity:0; transform:translateY(14px)}
  to{opacity:1; transform:none}
}
/* L'accent pur sur fond vert profond passait juste sous le seuil de
   lisibilité à 10px. Version éclaircie, réservée à ce fond sombre. */
.track-cine .tc-num{
  font-family:var(--mono); font-size:10.5px; font-weight:700; letter-spacing:.16em;
  text-transform:uppercase; color:#7FE0DA;
}
.track-cine .tc-name{
  font-family:var(--serif); font-weight:600; font-size:27px; line-height:1.08;
  letter-spacing:-.5px; color:#FCFBFA;
}
.track-cine .tc-meta{font-family:var(--sans); font-size:13px; color:rgba(252,251,250,.72)}
.track-cine .tc-bar{height:3px; border-radius:var(--r-pill); background:rgba(252,251,250,.24); overflow:hidden}
.track-cine .tc-bar i{
  display:block; height:100%; width:0%; border-radius:var(--r-pill);
  background:var(--accent, #1FA8A8); transition:width .12s linear;
}

/* Le bouton de lecture porte enfin son intention. */
.carte-pill-play{display:inline-flex; align-items:center; gap:7px; padding:9px 15px 9px 13px;
  font-family:var(--sans); font-size:12.5px; font-weight:700; color:var(--ink)}

@media (prefers-reduced-motion: reduce){
  .track-cine .tc-step.in{animation:none}
  .carte-full.cine .carte-sheet, .carte-sheet, .carte-top{transition:none}
}

/* Bouton de lecture pendant la construction du tracé (voir
   _trackSetPreparing, track.js) : il reste visible et lisible, mais dit
   qu'il n'y a rien à jouer pour l'instant. */
.carte-pill-play.busy{opacity:.72; cursor:default}
.carte-pill-play.busy .hs-map-spin{width:13px;height:13px;border-width:2px;
  border-top-color:var(--accent, #1FA8A8)} /* --gold est un reste de l'ancienne charte */

/* ── Attribution Mapbox ────────────────────────────────────────────────
   En bas, DANS le bandeau sombre de la lecture (choix de Charlotte : « le
   mapbox peut être en bas là où il y a du texte ») : c'est le seul endroit
   où elle ne recouvre rien et se fond dans une matière. Sur ce fond vert
   profond, le logo passe en blanc et l'attribution en blanc translucide.
   Au repos, le bandeau n'existe pas et la feuille occuperait sa place :
   elle remonte alors juste au-dessus, via la hauteur publiée dans
   --carte-bas (voir _trackSyncSheetHeight).
   Seul le PLACEMENT et la teinte changent : les conditions d'utilisation
   de Mapbox interdisent de masquer le logo ou d'en réduire la taille. */
/* .carte-map-bg porte z-index:1, ce qui crée un CONTEXTE D'EMPILEMENT :
   ses enfants, aussi haut soit leur z-index, restent enfermés dessous et
   passaient donc SOUS le voile de la lecture — l'attribution devenait
   invisible, ce que les conditions d'utilisation de Mapbox n'autorisent
   pas. Pendant la lecture, on rend son empilement transparent : la carte
   reste sous l'incrustation (elle n'a pas de z-index propre) mais ses
   contrôles peuvent enfin passer par-dessus. */
.carte-full.cine .carte-map-bg{z-index:auto}
.carte-full .mapboxgl-ctrl-bottom-left,
.carte-full .mapboxgl-ctrl-bottom-right{
  transition:margin-bottom .4s cubic-bezier(.32,.72,0,1);
  margin-bottom:calc(var(--carte-bas, 0px) + 4px);
  z-index:7;
}
.carte-full.cine .mapboxgl-ctrl-bottom-left,
.carte-full.cine .mapboxgl-ctrl-bottom-right{
  margin-bottom:calc(env(safe-area-inset-bottom,0px) + 2px);
}
.carte-full .mapboxgl-ctrl-attrib{opacity:.55}
.carte-full .mapboxgl-ctrl-logo{opacity:.55}
/* Sur le bandeau sombre : versions claires, même taille, même visibilité. */
.carte-full.cine .mapboxgl-ctrl-logo{filter:brightness(0) invert(1); opacity:.6}
.carte-full.cine .mapboxgl-ctrl-attrib{
  background:rgba(252,251,250,.14); color:#FCFBFA; opacity:.8;
}
.carte-full.cine .mapboxgl-ctrl-attrib a{color:#FCFBFA}
.carte-full.cine .mapboxgl-ctrl-attrib-button{filter:brightness(0) invert(1); opacity:.75}

/* ── Carte plein cadre ─────────────────────────────────────────────────
   Le conteneur d'overlay (.ov, core.css) réserve la hauteur de l'encoche
   pour que le contenu ne passe pas dessous. Sur cet écran, ça donnait une
   bande ivoire pleine largeur au-dessus de la carte — un bandeau qui n'a
   aucune raison d'être quand le sujet est une image plein écran (retour de
   Charlotte : « on enlève le bandeau blanc en haut »).
   La carte monte donc jusqu'au bord. Ce sont les éléments POSÉS dessus qui
   reprennent la marge de l'encoche à leur compte : la barre du repos et
   l'incrustation de lecture. */
.ov[data-ov="map"]{padding-top:0}
.ov[data-ov="map"] .carte-top{top:calc(14px + env(safe-area-inset-top,0px))}
.ov[data-ov="map"] .track-cine{padding-top:calc(14px + env(safe-area-inset-top,0px))}

/* ── menu contextuel (appui long) ──────────────────────────────────────
   Voir menu.js. Le fond se retire, l'objet touché se soulève, le menu se
   déplie depuis son coin : trois mouvements liés, pas trois animations
   indépendantes — c'est ce lien qui fait que le geste paraît physique. */
.ctx-ov{position:fixed; inset:0; z-index:120}
.ctx-back{
  position:absolute; inset:0;
  background:rgba(20,17,14,.28);
  backdrop-filter:blur(18px) saturate(1.05);
  -webkit-backdrop-filter:blur(18px) saturate(1.05);
  opacity:0; transition:opacity .22s ease;
}
.ctx-ov.ouvert .ctx-back{opacity:1}

/* La carte clonée est posée à la place exacte de l'originale, puis se
   soulève : l'œil ne perd jamais l'objet qu'il vient de toucher. */
.ctx-lift{
  position:absolute; border-radius:var(--card-radius,20px);
  transform:scale(.97); opacity:.999;
  transition:transform .26s cubic-bezier(.2,.9,.3,1), box-shadow .26s ease;
  pointer-events:auto;
}
.ctx-ov.ouvert .ctx-lift{
  transform:scale(var(--ctx-echelle,1));
  box-shadow:0 26px 60px rgba(31,26,20,.34), 0 6px 18px rgba(31,26,20,.16);
}
.ctx-lift > *{margin:0 !important; pointer-events:none}

.ctx-menu{
  position:absolute; width:258px; padding:5px;
  border-radius:var(--r-md); overflow:hidden;
  background:color-mix(in srgb, var(--surface) 93%, transparent);
  backdrop-filter:blur(26px) saturate(1.6);
  -webkit-backdrop-filter:blur(26px) saturate(1.6);
  border:1px solid color-mix(in srgb, var(--ink) 8%, transparent);
  box-shadow:0 18px 44px rgba(31,26,20,.22);
  opacity:0; transform:scale(.84); transform-origin:top left;
  transition:opacity .2s ease, transform .24s cubic-bezier(.2,.9,.3,1);
}
.ctx-ov.ouvert .ctx-menu{opacity:1; transform:scale(1)}
.ctx-item{
  width:100%; height:46px; padding:0 13px; border:none; background:none;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  font-family:var(--sans); font-size:15px; font-weight:500; color:var(--ink);
  cursor:pointer; border-radius:var(--r-sm); text-align:left;
  white-space:nowrap;
  -webkit-tap-highlight-color:transparent;
}
.ctx-item > span{overflow:hidden; text-overflow:ellipsis}
.ctx-item + .ctx-item{
  box-shadow:0 -1px 0 color-mix(in srgb, var(--ink) 7%, transparent);
}
.ctx-item:active{background:color-mix(in srgb, var(--ink) 7%, transparent)}
/* Le rouge ne sert plus qu'à qualifier UNE ligne de texte, au lieu de
   couvrir un tiers de l'écran comme le faisait le balayage. */
.ctx-item.destructif{color:var(--danger)}
.ctx-item.destructif svg{stroke:var(--danger)}

/* Pendant l'appui, avant le déclenchement : un enfoncement discret qui
   dit que quelque chose est en train de se passer. */
.ctx-presse{transition:transform .18s ease; transform:scale(.985)}

/* Mention d'apprentissage, posée une seule fois dans la vie de l'app
   (voir _astuceAppuiLongHTML). Volontairement discrète : elle informe,
   elle ne réclame rien. */
.astuce{
  display:flex; align-items:center; justify-content:center; gap:7px;
  margin:2px 0 14px; color:var(--sub); font-size:12.5px; font-weight:300;
}
.astuce svg{stroke:var(--accent, var(--sub)); flex:none}

/* Action « Suivre la journée » (en-tête du programme) — voir cartes.js.
   Bouton et non lien : il ne mène pas à un écran de l'app, il fait sortir
   vers l'app de cartes du téléphone. */
.jour-carte{
  display:inline-flex; align-items:center; gap:6px;
  border:1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  background:var(--accent-tint); color:var(--accent-texte,var(--accent));
  border-radius:var(--r-pill); padding:5px 11px 5px 9px;
  font-family:var(--sans); font-size:12px; font-weight:600; letter-spacing:.01em;
  cursor:pointer; -webkit-tap-highlight-color:transparent;
}
/* Même traitement que .mo-book : 26 px de haut, agrandi en zone tactile
   seulement — la pastille garde sa taille dessinée. */
.jour-carte{position:relative}
.jour-carte::after{content:'';position:absolute;left:0;right:0;
  top:50%;height:var(--tap-min);transform:translateY(-50%)}
.jour-carte:active{opacity:.7}
.jour-carte svg{stroke:var(--accent); flex:none}

/* ── Les mots des voyageurs, sous un lieu (voir mots.js) ────────────────
   Rattaché visuellement au moment qui précède : léger dégradé d'accent
   depuis le haut, comme si le bandeau sortait de la ligne du programme
   plutôt que d'être une carte de plus. Une journée reste une journée. */
.mots{
  margin:-6px 0 14px 44px; padding:11px 14px 12px;
  border-left:2px solid color-mix(in srgb, var(--accent) 34%, transparent);
  border-radius:0 var(--r-sm) var(--r-sm) 0;
  background:linear-gradient(180deg, var(--accent-tint), transparent 88%);
  cursor:pointer; -webkit-tap-highlight-color:transparent;
}
.mots:active{opacity:.72}
.mots-qui{display:flex; align-items:center; gap:9px; margin-bottom:7px}
.mot-piles{display:flex}
.mot-av{
  width:22px; height:22px; border-radius:50%; margin-left:-7px;
  background:var(--accent); color:var(--accent-ink,#fff);
  border:2px solid var(--surface);
  display:flex; align-items:center; justify-content:center;
  font-family:var(--sans); font-size:10px; font-weight:700;
}
.mot-av:first-child{margin-left:0}
.mots-n{font-size:12.5px; font-weight:600; color:var(--accent-texte,var(--accent))}
.mots-t{font-size:13px; font-weight:300; color:var(--ink-soft); line-height:1.5}
.mots-s{
  font-family:var(--mono); font-size:9px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--sub); margin-top:6px;
}
/* Écran « tous les mots d'un lieu » */
.mot-carte{
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--card-radius-sm); box-shadow:var(--shadow-card);
  padding:14px 15px; margin-bottom:11px;
}
.mots-lieu{font-family:var(--serif); font-size:21px; font-weight:600; color:var(--ink); margin:0 0 6px}
.mots-aide{font-size:13px; font-weight:300; color:var(--sub); line-height:1.55; margin:0 0 16px}

/* ── Le fil des traces (traces.js) ───────────────────────────────────────
   Direction B. Une carte par voyage publié : photo, qui, où, quand, puis
   la ligne de chiffres et « Emporter ». Volontairement proche de la carte
   d'un voyage enregistré (.trip-card) plutôt qu'un troisième langage de
   carte — c'est le même objet vu de l'extérieur. */
.trace-carte{
  display:block; margin-bottom:18px;
  border-radius:var(--card-radius,18px); overflow:hidden;
  background:var(--surface); border:none;
  box-shadow:var(--shadow-card);
}
.tr-ph{
  position:relative; height:196px;
  background-size:cover; background-position:center;
  background-color:var(--fog-soft, var(--surface2));
  display:flex; flex-direction:column; justify-content:space-between;
  padding:12px 14px 14px;
}
/* Le voile ne couvre que le bas : la photo doit rester une photo, pas un
   aplat sombre avec du texte dessus. */
.tr-veil{
  position:absolute; inset:0; z-index:0;
  /* Le bas descend franchement : sur une photo claire à cet endroit (sable,
     ciel, écume), « 9 jours · août » se lisait à peine. Même correctif que
     la carte pays de l'Atlas, pour la même raison. */
  /* Réglé une fois le voile réellement en place : les valeurs d'avant
     avaient été poussées pour compenser un voile qui ne s'affichait pas,
     et noircissaient inutilement le bas de la photo. */
  background:linear-gradient(180deg, rgba(20,17,14,.28) 0%, rgba(20,17,14,0) 26%, rgba(20,17,14,.16) 52%, rgba(20,17,14,.52) 78%, rgba(20,17,14,.74) 100%);
}
/* :not(.tr-veil) n'est pas un raffinement : sans lui, cette règle ANNULE
   le position:absolute du voile. Les deux sélecteurs ont la même
   spécificité et celui-ci vient après, donc il gagnait — le voile
   repassait en position:relative, perdait son inset:0 et se retrouvait
   réduit à un bloc de hauteur nulle. Il ne couvrait donc rien, et le nom
   de la destination se lisait à même la photo. Invisible sur une image
   sombre, flagrant sur une eau turquoise en plein soleil. */
.tr-ph>*:not(.tr-veil){position:relative; z-index:1}
/* C'est un <button> depuis qu'il ouvre le profil de l'auteur : sans
   border:0, le navigateur ajoute son propre contour par-dessus la
   pastille en verre. */
.tr-qui{
  border:0; cursor:pointer; text-align:left;
  display:inline-flex; align-items:center; gap:8px; align-self:flex-start;
  height:var(--b-sm); padding:0 var(--b-sm-x) 0 5px; border-radius:var(--r-pill);
  background:rgba(20,17,14,.42);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);
  backdrop-filter:blur(14px) saturate(1.4);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);
  font-family:var(--sans); font-size:12px; font-weight:600; color:#FFFFFF;
}
.tr-av{
  width:24px; height:24px; border-radius:50%; flex:none;
  background-size:cover; background-position:center;
  background-color:var(--accent);
  display:flex; align-items:center; justify-content:center;
}
/* Plus de blanc en dur : les pastilles sont passées au fond PÂLE avec des
   initiales en encre, et chaque teinte porte la sienne (hsTeintePastille,
   data.js). Le blanc ici ne servait que l'ancien fond sombre — laissé, il
   aurait fait des initiales invisibles partout où le style inline manque. */
.tr-av.sans-photo{ font-size:10px; font-weight:700 }
/* Le voile seul ne suffisait pas sur les photos les plus claires (eau
   turquoise en plein soleil) : le nom de la destination s'y délavait. Le
   dégradé descend plus tôt ET l'ombre du texte se resserre — une ombre
   large se dilue sur un fond clair, une ombre courte y tient. */
.tr-d{
  font-family:var(--serif); font-weight:600; font-size:27px; line-height:1.06;
  letter-spacing:-.025em; color:#FFFFFF;
  text-shadow:0 1px 3px rgba(2,12,20,.75), 0 2px 18px rgba(2,12,20,.6);
}
.tr-r{
  font-family:var(--sans); font-size:12.5px; font-weight:500; margin-top:3px;
  color:rgba(255,255,255,.9);
  text-shadow:0 1px 3px rgba(2,12,20,.8), 0 1px 12px rgba(2,12,20,.6);
}
.tr-pd{
  display:flex; align-items:center; gap:12px;
  padding:13px 14px;
}
.tr-ch{ display:flex; gap:18px; flex:1; min-width:0 }
.tr-ch>div{ display:flex; flex-direction:column; min-width:0 }
.tr-ch-v{
  font-family:var(--sans); font-size:15px; font-weight:700; color:var(--ink);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}
.tr-ch-l{
  font-family:var(--sans); font-size:10.5px; font-weight:500; color:var(--sub);
  letter-spacing:.02em; margin-top:1px;
}
.tr-emp{
  flex:none; display:inline-flex; align-items:center; gap:6px;
  /* 44 px : c'était la seule cible du fil sous le minimum tactile. */
  height:var(--tap-min); padding:0 16px; border-radius:var(--r-pill); border:none; cursor:pointer;
  background:var(--accent); color:var(--on-accent, #0B1D1B);
  font-family:var(--sans); font-size:13px; font-weight:600;
  -webkit-tap-highlight-color:transparent;
  transition:transform .18s var(--spring);
}
.tr-emp:active{ transform:scale(.94) }
/* ── Ce qu'on emporte ─────────────────────────────────────────────────
   Le bloc qui remplace la rangée compacte quand la trace porte le nom de
   ses étapes. Les pastilles sont reliées par un tiret : sans lui on lit
   une liste de villes, avec lui on lit un itinéraire — l'ordre compte. */
.tr-sq{ padding:14px 14px 16px }
.tr-sq-t{
  font-family:var(--sans); font-size:11px; font-weight:700;
  letter-spacing:.09em; text-transform:uppercase; color:var(--sub);
  margin-bottom:10px;
}
.tr-etapes{ display:flex; align-items:center; flex-wrap:wrap; gap:6px 9px }
/* Les pastilles nomment des LIEUX : elles informent, elles ne s'actionnent
   pas. Sur un fil de six voyages, l'aplat teinté d'accent revenait vingt
   fois — assez pour que l'accent cesse de vouloir dire quoi que ce soit.
   Fond neutre : le nom du lieu se lit aussi bien, et l'orange redevient
   rare. */
.tr-etapes .tr-et{
  font-family:var(--serif); font-size:13.5px; font-weight:600; color:var(--ink);
  background:var(--fog-soft); border-radius:var(--r-pill); padding:5px 11px;
}
/* Le couple « tiret + étape » : c'est LUI qui passe à la ligne. Un tiret
   nu entre deux pastilles finissait sinon en bout de ligne, à pointer
   vers rien. */
.tr-et-l{ display:inline-flex; align-items:center; gap:9px }
/* Le tiret qui relie deux étapes. C'est un élément à lui, entre les deux
   pastilles : en ::before sur la pastille suivante, il se dessinait
   DEDANS, sur l'aplat teinté, et ne reliait plus rien. */
.tr-etapes i{
  width:10px; height:1.5px; flex:none;
  background:var(--line2); border-radius:2px;
}
.tr-etapes .tr-et-plus{
  font-family:var(--sans); font-size:12px; color:var(--sub);
  background:transparent; padding:5px 2px;
}
.tr-sq .tr-ch{ border:0; padding:13px 0 0 }
.tr-partir{ width:100%; margin-top:14px; height:44px; font-size:14px; font-weight:600 }

/* Le compteur de reprises n'est pas une décoration : c'est la seule preuve
   qu'une trace a servi à quelqu'un. Il ne s'affiche donc jamais à zéro. */
.tr-rep{
  display:flex; align-items:center; gap:7px;
  padding:9px 14px 11px; border-top:1px solid var(--line);
  font-family:var(--sans); font-size:11.5px; font-weight:500; color:var(--sub);
}
.tr-rep svg{ color:var(--accent-texte,var(--accent)); flex:none }

/* ── L'en-tête du fil ─────────────────────────────────────────────────
   L'invitation à publier et la rangée des amis. Les deux sont
   facultatives : sans voyage terminé et sans ami, rien ne s'affiche et le
   fil commence directement par les cartes. */
.fil-inv{
  display:flex; align-items:center; gap:12px; margin-bottom:18px;
  padding:10px; border-radius:var(--r-md);
  background:var(--accent-tint);
  border:1px solid color-mix(in srgb, var(--accent) 26%, transparent);
}
.fil-inv-ph{
  width:52px; height:52px; flex:none; border-radius:var(--r-sm);
  background-size:cover; background-position:center;
  background-color:var(--fog-soft, var(--surface2));
}
.fil-inv-m{ flex:1; min-width:0 }
/* Deux lignes plutôt qu'une coupée : « Votre Sardaigne est terminé »
   tenait tout juste, « Votre République dominicaine est terminé » se
   perdait dans des points de suspension — et c'est le nom du voyage qu'on
   y perdait, c'est-à-dire la seule information de la ligne. */
.fil-inv-t{
  font-family:var(--serif); font-size:14.5px; font-weight:600; color:var(--ink);
  line-height:1.28;
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2;
  overflow:hidden;
}
.fil-inv-s{
  font-family:var(--sans); font-size:11.5px; color:var(--sub);
  margin-top:2px; line-height:1.4;
}
.fil-amis{
  display:flex; gap:14px; overflow-x:auto;
  padding:2px 0 6px; margin-bottom:4px;
  -webkit-overflow-scrolling:touch;
}
.fil-ami{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  flex:none; border:none; background:transparent; padding:0;
  font:inherit; color:inherit;
}
.fil-ami .tr-av{ width:52px; height:52px; font-size:16px }
.fil-ami>span:last-child{
  font-family:var(--sans); font-size:11.5px; color:var(--ink-soft);
  max-width:60px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.fil-ami-plus{ cursor:pointer; -webkit-tap-highlight-color:transparent }
.fil-ami-plus .tr-av{
  background:var(--surface2); color:var(--sub);
  border:1px dashed var(--line2); font-size:21px; font-weight:400;
}
.fil-ami-plus:active{ opacity:.6 }

/* Sélecteur de l'onglet Tendances — l'onglet garde son contenu, le fil
   s'ajoute à côté (« je ne veux pas supprimer mon onglet tendance »). */
.trend-seg{ margin-bottom:2px }

/* Publier sa trace, sous la carte postale du récap : une action de second
   rang, pas un second CTA plein qui ferait hésiter entre les deux. */
.rc-trace{
  width:100%; margin-top:10px;
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
}
.rc-trace.publiee{ color:var(--accent-texte,var(--accent)); border-color:var(--accent) }
/* La vidéo : même rang que « publier », sous la carte postale qui garde
   le CTA plein — elle est instantanée là où la vidéo demande une minute. */
.rc-video{ width:100%; margin-top:10px;
  display:inline-flex; align-items:center; justify-content:center; gap:8px }

/* Signalement du contenu public — un seul traitement pour le fil des
   traces et les mots des voyageurs, comme il n'y a qu'une seule feuille
   « Bloquer / Signaler » (_openBlockReportSheet, app.js). Discret par
   construction : c'est un recours, pas une action qu'on propose. */
/* Le coin haut-droit de la photo porte maintenant DEUX boutons — réagir
   et signaler. Le positionnement absolu quitte donc .tr-plus pour passer
   sur le conteneur : deux éléments posés chacun en absolu au même endroit
   se seraient superposés. */
/* Sélecteur volontairement écrit « .tr-ph > .tr-coin » : la règle
   .tr-ph>*:not(.tr-veil) plus haut impose position:relative à tous les
   enfants, et elle est PLUS SPÉCIFIQUE qu'une simple classe. Écrite
   « .tr-coin{position:absolute} », la déclaration est ignorée en silence
   et les deux boutons retombent au milieu de la photo. Mesuré dans le
   navigateur, pas deviné : position calculée « relative ». */
.tr-ph > .tr-coin{
  position:absolute; top:10px; right:10px; z-index:2;
  display:flex; align-items:center; gap:8px;
}
.tr-reac{
  min-width:var(--b-sm); height:var(--b-sm); padding:0 var(--b-sm-x); border-radius:var(--r-pill); border:none; cursor:pointer;
  display:flex; align-items:center; gap:5px;
  background:rgba(20,17,14,.38); color:rgba(255,255,255,.92);
  -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px);
  -webkit-tap-highlight-color:transparent;
  font-family:var(--sans); font-size:12.5px; font-weight:700;
  font-variant-numeric:tabular-nums;
  transition:transform .12s var(--spring), background .15s ease;
}
.tr-reac:active{ transform:scale(.9) }
/* Partager : même allure que les réactions, classe distincte. Sans
   compteur — un nombre de partages sur un récit qui n'en a aucun est une
   humiliation gratuite, et sur un réseau qui démarre ils sont tous à
   zéro. */
.tr-part{
  min-width:var(--b-sm); height:var(--b-sm); padding:0 var(--b-sm-x);
  border-radius:var(--r-pill); border:none; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  background:rgba(20,17,14,.38); color:rgba(255,255,255,.92);
  -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px);
  -webkit-tap-highlight-color:transparent;
  transition:transform .12s var(--spring), background .15s ease;
}
.tr-part:active{ transform:scale(.9) }
/* Réagi : le cœur se remplit. C'est la seule couleur chaude de la carte,
   et c'est voulu — elle doit se voir d'un coup d'œil en défilant. */
.tr-reac.on{ background:#B3452C; color:#FFFFFF }
.tr-reac.on .ico{ fill:currentColor }
.tr-reac span:empty{ display:none }
.tr-plus{
  width:var(--b-sm); height:var(--b-sm); border-radius:50%; border:none; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  background:rgba(20,17,14,.38); color:rgba(255,255,255,.9);
  -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px);
  -webkit-tap-highlight-color:transparent;
}
.tr-plus:active{ transform:scale(.9) }
.mot-pied{ display:flex; align-items:center; gap:8px; margin-top:6px }
.mot-pied .mots-s{ flex:1; min-width:0; margin-top:0 }
.mot-plus{
  flex:none; width:30px; height:30px; border-radius:50%; border:none; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  background:transparent; color:var(--sub);
  -webkit-tap-highlight-color:transparent;
}
.mot-plus:active{ background:var(--surface2) }

/* ── La page publique d'une trace (trace-publique.js) ────────────────────
   Vue par quelqu'un qui n'a pas l'app et n'a peut-être jamais entendu
   parler de Hic Sunt. Elle a donc trois secondes pour dire ce qu'elle
   montre et ce qu'on peut en faire — d'où la photo pleine largeur, les
   trois chiffres, et un seul bouton. */
.tpub{ min-height:100%; background:var(--bg); overflow-y:auto }
.tpub-ph{
  position:relative; height:56vh; min-height:340px;
  background-size:cover; background-position:center;
  background-color:var(--fog-soft, var(--surface2));
  display:flex; flex-direction:column; justify-content:flex-end;
  padding:20px 22px 24px;
}
.tpub-ph>*{ position:relative; z-index:1 }
.tpub-veil{
  position:absolute; inset:0; z-index:0;
  background:linear-gradient(180deg, rgba(20,17,14,.42) 0%, rgba(20,17,14,0) 30%, rgba(20,17,14,.24) 56%, rgba(20,17,14,.78) 100%);
}
.tpub-marque{
  position:absolute; top:20px; left:22px; z-index:2;
  font-family:var(--mono, var(--sans)); font-size:11px; font-weight:700;
  letter-spacing:.34em; color:rgba(255,255,255,.94);
  text-shadow:0 1px 10px rgba(2,12,20,.7);
}
.tpub-k{
  font-family:var(--sans); font-size:11px; font-weight:700;
  letter-spacing:.1em; text-transform:uppercase; color:rgba(255,255,255,.82);
  text-shadow:0 1px 8px rgba(2,12,20,.8); margin-bottom:8px;
}
.tpub-ti h1{
  font-family:var(--serif); font-weight:700; font-size:44px; line-height:1;
  letter-spacing:-.03em; color:#FFFFFF; margin:0;
  text-shadow:0 2px 20px rgba(2,12,20,.55);
}
.tpub-ti p{
  font-family:var(--sans); font-size:14px; font-weight:500; margin:8px 0 0;
  color:rgba(255,255,255,.9); text-shadow:0 1px 8px rgba(2,12,20,.7);
}
.tpub-corps{ padding:24px 22px calc(28px + env(safe-area-inset-bottom,0px)) }
.tpub-ch{ display:flex; gap:26px; padding-bottom:18px; border-bottom:1px solid var(--line2) }
.tpub-ch>div{ display:flex; flex-direction:column }
.tpub-v{
  font-family:var(--sans); font-size:21px; font-weight:700; color:var(--ink);
  font-variant-numeric:tabular-nums; line-height:1.1;
}
.tpub-l{ font-family:var(--sans); font-size:11px; font-weight:500; color:var(--sub); margin-top:3px }
.tpub-rep{
  font-family:var(--sans); font-size:12px; font-weight:600; color:var(--accent-texte,var(--accent));
  margin-top:14px;
}
.tpub-dit{
  font-family:var(--sans); font-size:14px; line-height:1.6; color:var(--sub);
  margin:16px 0 22px;
}
.tpub-cta{
  display:block; width:100%; text-align:center; text-decoration:none;
  line-height:52px; height:52px;
}
.tpub-pied{
  font-family:var(--sans); font-size:11px; color:var(--sub);
  text-align:center; margin-top:16px; letter-spacing:.02em;
}

/* « Ajouter le lien vers ma trace », dans l'aperçu de la carte postale.
   Sur le fond sombre de l'aperçu, en verre comme le reste de cet écran. */
.pc-lien{
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
  margin-top:12px; padding:11px 18px; border-radius:var(--r-pill); cursor:pointer;
  background:rgba(255,255,255,.14); border:1px solid rgba(255,255,255,.24);
  -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
  color:#FFFFFF; font-family:var(--sans); font-size:13px; font-weight:600;
  -webkit-tap-highlight-color:transparent;
}
.pc-lien:active{ transform:scale(.96) }

/* ── Parrainage (parrainage.js) ──────────────────────────────────────────
   Le code est l'objet de cet écran : il est gros, il se copie d'un doigt,
   et rien ne se dispute son attention. */
.par-t{ font-family:var(--serif); font-weight:600; font-size:21px; line-height:1.15; letter-spacing:-.02em; color:var(--ink); margin:0 0 8px }
.par-t2{ font-family:var(--serif); font-weight:600; font-size:17px; color:var(--ink); margin:0 0 6px }
.par-s{ font-family:var(--sans); font-size:13.5px; line-height:1.6; color:var(--sub); margin:0 }
.par-code{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  margin-top:18px; padding:20px 16px 16px; border-radius:var(--r-md); cursor:pointer;
  background:var(--accent-tint); border:1px dashed var(--accent);
  -webkit-tap-highlight-color:transparent;
}
.par-code span{
  font-family:var(--mono, var(--sans)); font-size:27px; font-weight:700;
  letter-spacing:.16em; color:var(--accent-texte,var(--accent)); line-height:1;
}
.par-code small{ font-family:var(--sans); font-size:11px; color:var(--sub) }
.par-code:active{ transform:scale(.98) }
.par-solde{
  font-family:var(--sans); font-size:12.5px; font-weight:600; color:var(--accent-texte,var(--accent));
  text-align:center; margin-top:12px; min-height:16px;
}

/* ── Choix du véhicule (voir hsTrackOuvrirVehicules, track.js) ──────────
   Un bouton rond à côté de « Voir le tracé », qui porte la silhouette
   courante : c'est la silhouette elle-même qui dit qu'on peut en changer,
   pas un libellé. Il partage la matière de .carte-pill (fond clair, ombre
   portée) pour ne pas ouvrir une deuxième grammaire de bouton sur cette
   barre. */
.carte-pill-veh{padding:7px; width:42px; height:42px; justify-content:center; flex:none}
.carte-pill-veh span{display:block; width:100%; line-height:0}
.carte-pill-veh svg{width:100%; height:auto; display:block}

.tv-feuille{background:var(--surface-raised); border-radius:var(--r-xl) var(--r-xl) 0 0;
  padding:26px 20px calc(22px + env(safe-area-inset-bottom,0px)); width:100%;
  max-width:520px; max-height:82vh; overflow-y:auto; -webkit-overflow-scrolling:touch}
.tv-tete{margin-bottom:18px}
.tv-titre{font-family:var(--serif); font-size:21px; font-weight:600; color:var(--ink)}
.tv-sous{font-family:var(--sans); font-size:13px; color:var(--sub); line-height:1.5; margin-top:5px}
.tv-fam{margin-bottom:18px}
.tv-fam h3{font-family:var(--sans); font-size:11px; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; color:var(--sub); margin:0 0 9px}
/* Trois par ligne : en dessous les silhouettes deviennent des taches, et
   au-dessus la ligne de la famille « route » (sept véhicules) déborderait
   sur trois rangs déséquilibrés. */
.tv-grille{display:grid; grid-template-columns:repeat(3,1fr); gap:9px}
.tv-tuile{display:flex; flex-direction:column; align-items:center; gap:6px;
  padding:11px 6px 9px; border-radius:var(--r-md); background:var(--surface);
  border:1.5px solid transparent; cursor:pointer;
  transition:transform .12s var(--spring), border-color .12s, background .12s}
.tv-tuile:active{transform:scale(.95)}
.tv-tuile.on{border-color:var(--accent, #1FA8A8); background:var(--accent-soft, rgba(31,168,168,.09))}
.tv-dessin{display:block; width:100%; max-width:62px; line-height:0}
.tv-dessin svg{width:100%; height:auto; display:block}
.tv-nom{font-family:var(--sans); font-size:11.5px; font-weight:600; color:var(--ink)}
.tv-tuile.on .tv-nom{color:var(--accent-ink, var(--ink))}

/* ── Emporter la vidéo (voir hsVideoFabriquer, video.js) ───────────────
   Troisième pastille de la barre, à côté du véhicule : regarder le tracé,
   choisir sa voiture, repartir avec le film. Les trois gestes se suivent,
   les trois boutons aussi. */
.carte-pill-film{padding:0; width:42px; height:42px; justify-content:center; flex:none;
  color:var(--accent, #1FA8A8)}

/* L'écran d'attente. Fabriquer une vidéo prend du temps et ce temps doit
   se voir avancer : une barre qui progresse et un compteur d'images, pas
   un tourniquet qui laisse croire que l'app a lâché. */
.vid-att{width:100%; max-width:330px; text-align:center}
.vid-att-t{font-family:var(--serif); font-size:21px; font-weight:600; color:#FFFFFF}
.vid-att-s{font-family:var(--sans); font-size:13.5px; color:rgba(255,255,255,.76);
  margin:9px 0 20px; min-height:19px}
.vid-att-piste{height:6px; border-radius:var(--r-pill); background:rgba(255,255,255,.2); overflow:hidden}
.vid-att-piste i{display:block; height:100%; width:0; border-radius:var(--r-pill);
  background:var(--accent, #1FA8A8); transition:width .35s ease}
.vid-att-n{font-family:var(--sans); font-size:12px; line-height:1.55;
  color:rgba(255,255,255,.55); margin-top:18px}

/* ── Les commentaires d'un voyage publié ─────────────────────────────── */
.tr-com{ background:rgba(20,17,14,.38) }
.com-l{display:flex;align-items:flex-start;gap:10px;padding:12px 0;border-bottom:1px solid var(--line)}
.com-l:last-of-type{border-bottom:0}
.com-l .tr-av{width:30px;height:30px;margin-top:1px}
.com-m{flex:1;min-width:0}
.com-h{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.com-n{font-family:var(--sans);font-size:13.5px;font-weight:700;color:var(--ink)}
.com-q{font-family:var(--sans);font-size:11.5px;color:var(--sub)}
.com-b{font-family:var(--sans);font-size:14px;line-height:1.55;color:var(--ink);
  margin-top:3px;overflow-wrap:anywhere}
.com-act{flex:none;width:30px;height:30px;border:0;background:transparent;color:var(--sub);
  border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;
  -webkit-tap-highlight-color:transparent}
.com-act:active{transform:scale(.9)}
.com-vide{color:var(--sub);font-size:13.5px;line-height:1.6;padding:18px 0;margin:0}

/* La saisie reste au pied de la feuille, au-dessus du clavier. */
.com-saisie{display:flex;align-items:flex-end;gap:9px;margin-top:16px;
  padding:8px 8px 8px 14px;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface)}
.com-saisie textarea{flex:1;min-width:0;border:0;background:transparent;resize:none;
  font-family:var(--sans);font-size:14.5px;line-height:1.5;color:var(--ink);
  padding:8px 0;max-height:132px;outline:none}
.com-envoi{flex:none;width:36px;height:36px;border-radius:50%;border:0;cursor:pointer;
  background:var(--accent);color:var(--accent-ink,#FFFFFF);
  display:flex;align-items:center;justify-content:center;
  transition:transform .12s var(--spring)}
.com-envoi:active{transform:scale(.92)}

/* Le fil sans un seul voyage : l'écran le plus vu tant que personne n'a
   publié. Il propose l'acte qui le remplirait. */
.fil-vide{text-align:center;padding:40px 24px 30px}
.fil-vide-ic{color:var(--accent-texte,var(--accent));margin-bottom:14px;display:flex;justify-content:center}
.fil-vide-t{font-family:var(--serif);font-size:17px;font-weight:600;color:var(--ink);margin:0 0 8px}
.fil-vide-s{font-family:var(--sans);font-size:13.5px;line-height:1.65;color:var(--sub);
  max-width:280px;margin:0 auto}

/* ── Le rail des visages ────────────────────────────────────────────────
   Charlotte : « ça fait très fade et plat ». Une rangée de pastilles de
   24 px sous un titre de section, c'était une LISTE. Un réseau social
   s'ouvre sur des visages qu'on fait défiler du pouce — plus gros,
   cerclés, et qui mènent quelque part. */
/* ── Tous / Vos amis ─────────────────────────────────────────────────────
   Deux vues d'un même fil, pas deux écrans : c'est un CHOIX, donc une
   pilule — la grammaire réservée aux sélecteurs d'option (le soulignement
   disait « vous êtes ici », il servait à la navigation qui n'existe plus
   dans cet onglet). Posé sous le rail des amis, juste avant les cartes. */
.fil-vues{display:flex;gap:8px;margin:2px 0 14px}
.fil-vue{flex:none;padding:0 15px;height:33px;border:1px solid var(--line);
  border-radius:var(--r-pill,999px);background:none;box-shadow:none;
  font-family:var(--sans);font-size:13px;font-weight:500;color:var(--sub);
  cursor:pointer;-webkit-tap-highlight-color:transparent;
  transition:transform .12s var(--spring),background .16s ease,color .16s ease}
.fil-vue.on{background:var(--ink);border-color:var(--ink);color:var(--surface);font-weight:600}
.fil-vue:active{transform:scale(.96)}
/* .fil-rail / .rail-* : le rail des visages d'amis, sous le rail des lieux
   vécus. Retiré le 5 septembre — deux carrousels de pastilles rondes
   empilés, à deux tailles, dont le second ne menait qu'à des profils. Les
   amis ont désormais leur rangée dans le carnet et leur écran à eux. Les
   règles partent avec lui : du CSS qui ne décrit plus rien est du CSS que
   le prochain croira encore utile. */


/* ── Un moment dans le fil ──────────────────────────────────────────────
   Décision du 6 septembre : le fil s'ouvre aux publications du quotidien.
   Une carte de voyage est une COUVERTURE — photo plein cadre, titre posé
   dessus, chiffres en pied. Un moment n'a ni titre ni chiffres : c'est
   quelqu'un qui dit quelque chose. Il prend donc la disposition qu'on
   attend d'un message — l'auteur en haut, l'image au milieu, le texte en
   dessous — et non celle d'une affiche.

   Les deux cartes partagent .trace-carte : le fond, le rayon, l'ombre et
   l'espacement du fil restent communs. Ce fichier n'ajoute que ce qui
   diffère. */
.moment-carte{ padding:14px 0 4px }
.mo-tete{ display:flex; align-items:center; gap:10px; padding:0 14px 12px }
.mo-qui{
  display:flex; align-items:center; gap:9px; min-width:0;
  background:none; border:0; padding:0; cursor:pointer; font-family:inherit;
  -webkit-tap-highlight-color:transparent;
}
.mo-qui:active{ opacity:.7 }
.mo-n{
  font-family:var(--serif); font-size:14.5px; font-weight:600; color:var(--ink);
  letter-spacing:-.02em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* Le lieu et l'heure sur une seule ligne, en gris : ce sont des
   circonstances, pas le sujet. Elles se coupent avant le nom, qui est le
   seul élément dont on ne peut pas se passer pour savoir qui parle. */
.mo-ou{
  flex:1; min-width:0; font-size:12px; color:var(--sub);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.moment-carte .tr-plus{ position:static; flex:none }
/* 4/5 comme la photo du composeur : ce qu'on cadre est ce qu'on publie.
   Un format différent entre les deux ferait découvrir après coup qu'on a
   coupé la moitié de la scène. */
.mo-ph{
  width:100%; aspect-ratio:4/5; max-height:62vh;
  background-size:cover; background-position:center; background-color:var(--fog-soft);
}
.mo-tx{
  padding:12px 14px 0; font-size:14.5px; line-height:1.55; color:var(--ink);
  white-space:pre-wrap; word-break:break-word;
}
.mo-pd{ display:flex; align-items:center; gap:8px; padding:12px 14px 12px }
/* Réactions et commentaires vivaient en surimpression sur la photo d'une
   couverture. Ici il n'y a pas de photo garantie : ils redeviennent des
   boutons ordinaires, sur le fond de la carte. */
.mo-pd .tr-reac, .mo-pd .tr-com{
  position:static; background:var(--surface2); color:var(--ink);
  border:1px solid rgba(10,15,12,.08); box-shadow:none;
}

/* ── La porte : publier un moment ───────────────────────────────────────
   Toujours présente, même quand le fil est vide et qu'aucun voyage
   terminé n'attend d'être publié : c'est le geste qui REMPLIT le fil, il
   ne peut pas dépendre d'en avoir déjà rempli une partie. */
.fil-tete-h{ display:flex; align-items:baseline; justify-content:space-between; gap:12px }
.fil-publier{
  flex:none; display:inline-flex; align-items:center; gap:5px;
  background:none; border:0; padding:6px 0; cursor:pointer;
  font-family:var(--sans); font-size:13px; font-weight:600;
  /* --accent-texte, pas --accent : la teinte de la saison est calibrée
     pour des aplats, pas pour du texte de 13 px sur de l'ivoire. La
     variante assombrie (da.css, posée par da-accent.js) passe le
     contraste. Écrit --accent d'abord, et banc-saison l'a refusé — la
     règle existe précisément parce que l'erreur est facile. */
  color:var(--accent-texte,var(--accent));
  -webkit-tap-highlight-color:transparent;
}
.fil-publier svg{ stroke:currentColor; fill:none; stroke-width:2.2 }
.fil-publier:active{ opacity:.6 }


/* ── La vidéo dans le fil ───────────────────────────────────────────────
   Même cadre que la photo (4/5) : ce qu'on cadre est ce qu'on publie, et
   deux formats différents feraient découvrir après coup qu'on a coupé la
   moitié de la scène. object-fit:cover parce qu'une vidéo verticale et
   une vidéo horizontale ne peuvent pas partager un cadre sans que l'une
   des deux soit rognée — on rogne, on ne laisse pas de bandes noires. */
.mo-vid{ display:block; object-fit:cover; background:#0A0F0C }
/* Le choix de ce qu'on publie. Trois portes de même taille : aucune n'est
   la principale, et une vidéo ne doit pas être un sous-produit de la
   photo. */
.moment-choix{ display:flex; flex-direction:column; gap:10px; margin-top:12px }
.moment-choix-b{
  display:flex; align-items:center; gap:13px; width:100%;
  padding:15px 16px; border-radius:var(--r-md);
  background:var(--surface2); border:1px solid rgba(10,15,12,.08);
  font-family:var(--sans); font-size:15px; font-weight:600; color:var(--ink);
  cursor:pointer; -webkit-tap-highlight-color:transparent;
}
.moment-choix-b svg{ stroke:var(--accent-texte,var(--accent)); fill:none; flex:none }
.moment-choix-b:active{ transform:scale(.985) }


/* ── Les voyageurs à suivre ─────────────────────────────────────────────
   Un rail, pas une liste : dans le fil, la découverte est une invitation
   qu'on parcourt du pouce, pas un annuaire qu'on lit. L'écran Découvrir,
   lui, prend la même carte en pleine largeur — même brique, deux
   dispositions, jamais deux dessins qui divergeraient. */
.voy-rail{
  display:flex; gap:12px; overflow-x:auto;
  margin:0 -10px; padding:4px 10px 12px; scrollbar-width:none;
}
.voy-rail::-webkit-scrollbar{ display:none }
.voy-rail .voy-c{ flex:none; width:148px; flex-direction:column; align-items:stretch; text-align:center }
.voy-rail .voy-ouvre{ flex-direction:column; align-items:center; gap:8px; text-align:center; width:100%; min-width:0 }
/* Le nom, dans la carte étroite : deux lignes au plus, coupées proprement.
   Charlotte, 11 septembre : « les noms longs débordent » — « RABENANTENAINA
   Clévin » sortait de la carte des deux côtés. En colonne, align-items:center
   laissait le nom prendre sa largeur naturelle, plus large que la carte. */
.voy-rail .voy-n{ white-space:normal; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden; overflow-wrap:break-word; hyphens:auto; -webkit-hyphens:auto; width:100%; line-height:1.2;
  font-size:13.5px; text-overflow:clip }
.voy-rail .voy-b{ width:100%; white-space:normal; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden }
.voy-rail .voy-s{ width:100%; margin-top:10px }

.voy-liste{ display:flex; flex-direction:column; gap:10px }
.voy-liste .voy-c{ width:100% }

.voy-c{
  display:flex; align-items:center; gap:12px;
  background:var(--surface2); border:1px solid rgba(10,15,12,.07);
  border-radius:var(--r-md); padding:14px;
}
.voy-ouvre{
  display:flex; align-items:center; gap:12px; min-width:0; flex:1;
  background:none; border:0; padding:0; cursor:pointer; font-family:inherit; text-align:left;
  -webkit-tap-highlight-color:transparent;
}
.voy-ouvre:active{ opacity:.7 }
.voy-n{
  font-family:var(--serif); font-size:14.5px; font-weight:600; color:var(--ink);
  letter-spacing:-.02em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%;
}
/* La biographie ne prend jamais plus de deux lignes : au-delà, la carte
   d'à côté n'a plus la même hauteur et le rail boite. */
.voy-b{
  font-size:12px; line-height:1.4; color:var(--sub);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden; max-width:100%;
}
.voy-s{
  flex:none; padding:9px 16px; border-radius:999px;
  /* --accent-ink, pas #fff : la variable choisit à chaque changement de
     saison entre le blanc et l'encre sombre celle qui contraste le mieux
     sur la teinte du jour. Écrit #FFFFFF d'abord, et banc-saison l'a
     refusé — sous le terracotta, du blanc sur cet aplat tombe à 3,39:1
     quand il faut 4,5. La règle existe parce que le défaut ne se voit
     qu'en changeant de palette, donc jamais le jour où on l'écrit. */
  background:var(--accent); border:0; color:var(--accent-ink, #FFFFFF);
  font-family:var(--sans); font-size:13px; font-weight:600;
  cursor:pointer; -webkit-tap-highlight-color:transparent;
}
/* Suivi : le bouton devient un contour. Il reste touchable — se
   désabonner doit être aussi facile que s'abonner. */
.voy-s.ghost{
  background:transparent; color:var(--sub);
  border:1px solid rgba(10,15,12,.16);
}
.voy-s:active{ transform:scale(.97) }

/* Une demande reçue appelle DEUX réponses, et elles ne pèsent pas pareil :
   accepter est le geste attendu (plein), refuser reste disponible sans
   être proposé (contour). Empilées plutôt que côte à côte : sur 390 px,
   deux pilules et un nom se marchent dessus. */
/* ── Public ou privé ────────────────────────────────────────────────────
   Une ligne, pas une case à cocher perdue dans un formulaire : la phrase
   sous le titre dit ce que le réglage FAIT, et elle change avec lui. Un
   interrupteur muet oblige à deviner ce que « privé » recouvre. */
/* ── Tirer pour rafraîchir ──────────────────────────────────────────────
   Une jauge de hauteur zéro, qui grandit sous le doigt. Pas de texte :
   « relâchez pour rafraîchir » est une notice, et le geste n'en a pas
   besoin — l'anneau qui se remplit puis tourne dit tout. */
.fil-tirer{
  height:0; overflow:hidden; display:flex; align-items:center; justify-content:center;
  transition:height .18s ease;
}
.fil-tirer-r{
  width:20px; height:20px; border-radius:50%;
  border:2px solid var(--line2, rgba(10,15,12,.16));
  border-top-color:var(--sub);
  opacity:.55; transition:opacity .18s ease, transform .18s ease;
}
.fil-tirer.pret .fil-tirer-r{ opacity:1; transform:scale(1.12); border-top-color:var(--accent) }
.fil-tirer.tourne .fil-tirer-r{ opacity:1; border-top-color:var(--accent); animation:hs-spin .8s linear infinite }

/* Le cœur du double-tap : il monte, il grandit, il s'efface. Personne ne
   le regarde vraiment — il sert à accuser réception d'un geste qui n'a
   aucun autre retour visible, et c'est pour ça qu'il doit être bref. */
.fp-coeur{
  position:absolute; width:96px; height:96px; pointer-events:none;
  color:#fff; z-index:5; filter:drop-shadow(0 6px 18px rgba(0,0,0,.45));
  animation:hs-coeur .7s cubic-bezier(.2,.9,.3,1) forwards;
}
.fp-coeur svg{ width:96px; height:96px; fill:#fff }
@keyframes hs-coeur{
  0%   { opacity:0; transform:scale(.5) }
  22%  { opacity:1; transform:scale(1.12) }
  45%  { transform:scale(.96) }
  100% { opacity:0; transform:scale(1.05) translateY(-26px) }
}
@media (prefers-reduced-motion:reduce){
  .fp-coeur{ animation:hs-coeur-sobre .5s ease forwards }
  @keyframes hs-coeur-sobre{ 0%{opacity:0} 25%{opacity:1} 100%{opacity:0} }
}

.prive-bloc{ margin-top:18px }
.prive-ligne{
  width:100%; display:flex; align-items:center; gap:14px; text-align:left;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-lg);
  padding:14px 16px; cursor:pointer; font-family:var(--sans);
  -webkit-tap-highlight-color:transparent;
}
.prive-ligne:active{ transform:scale(.995) }
.prive-t{ flex:1; min-width:0; display:flex; flex-direction:column; gap:3px }
.prive-h{ font-size:14px; font-weight:600; color:var(--ink) }
.prive-s{ font-size:12px; color:var(--sub); line-height:1.45 }
.prive-inter{
  flex:none; width:44px; height:26px; border-radius:999px; position:relative;
  background:var(--line2, rgba(10,15,12,.16)); transition:background .18s ease;
}
.prive-inter::after{
  content:''; position:absolute; top:3px; left:3px; width:20px; height:20px;
  border-radius:50%; background:var(--surface);
  box-shadow:0 2px 6px -1px rgba(31,26,20,.35); transition:transform .18s ease;
}
.prive-inter.on{ background:var(--accent) }
.prive-inter.on::after{ transform:translateX(18px) }

.voy-deux{ display:flex; flex-direction:column; gap:6px; flex:none }
.voy-deux .voy-s{ padding:7px 14px; font-size:12px; text-align:center }

/* ── Le fil en plein écran ──────────────────────────────────────────────
   Un élément par écran, aimanté. Sans scroll-snap on s'arrête entre deux
   voyages et on ne voit ni l'un ni l'autre — c'est ce qui distingue un
   fil immersif d'une page qui défile. */
.ov.fil-plein-ov{ background:#0A0F0C; padding-top:0 }
.fp{
  height:100%; overflow-y:auto; overscroll-behavior:contain;
  scroll-snap-type:y mandatory; scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
}
.fp::-webkit-scrollbar{ display:none }
.fp-item{
  position:relative; height:100%; width:100%;
  scroll-snap-align:start; scroll-snap-stop:always;
  overflow:hidden; background:#0A0F0C;
}
.fp-media{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; background-size:cover; background-position:center;
}
/* Deux dégradés, pas un : le haut porte le bouton de signalement, le bas
   porte tout le texte. Un voile uniforme assombrirait la photo au milieu,
   là où il n'y a rien à lire. */
.fp-voile{
  position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(180deg, rgba(10,15,12,.5) 0%, rgba(10,15,12,0) 22%,
             rgba(10,15,12,0) 44%, rgba(10,15,12,.82) 100%);
}
.fp-haut{
  position:absolute; top:calc(14px + var(--encoche)); right:14px; z-index:2;
}
.fp-haut .tr-plus{ position:static; color:#fff }
.fp-bas{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  padding:0 20px calc(30px + env(safe-area-inset-bottom,0px));
  display:flex; flex-direction:column; gap:8px; align-items:flex-start;
}
.fp-n{
  font-family:var(--serif); font-size:16px; font-weight:600; color:#fff;
  letter-spacing:-.02em; text-shadow:0 1px 12px rgba(0,0,0,.5);
}
.fp-ou{ font-size:13px; color:#ffffffc4; text-shadow:0 1px 10px rgba(0,0,0,.5) }
.fp-tx{
  font-size:15px; line-height:1.5; color:#fff; white-space:pre-wrap;
  text-shadow:0 1px 12px rgba(0,0,0,.55); max-width:34ch;
}
.fp-chiffres{ margin-top:2px }
.fp-chiffres, .fp-chiffres *{ color:#ffffffd6 !important; border-color:#ffffff2e !important }
.fp-actions{ display:flex; align-items:center; gap:9px; margin-top:6px; flex-wrap:wrap }
/* Les réactions vivaient en surimpression sur une photo de carte : ici
   tout est déjà sur une photo. Elles prennent le verre sombre, comme les
   ronds de l'Atlas — la seule famille de boutons de l'app conçue pour se
   poser sur une image. */
.fp-actions .tr-reac, .fp-actions .tr-com{
  position:static; background:#0E141766; border:1px solid #ffffff2b; color:#fff;
  box-shadow:none;
}
.fp-partir{
  border-color:#ffffff59 !important; color:#fff !important; background:transparent !important;
  padding:0 16px; height:38px;
}
.fp-fermer{
  position:absolute; top:calc(14px + var(--encoche)); left:14px; z-index:3;
  width:38px; height:38px; border-radius:50%;
  background:#0E141766; border:1px solid #ffffff2b; color:#fff;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer; -webkit-tap-highlight-color:transparent;
}
.fp-fermer svg{ stroke:currentColor; fill:none }
