/* =============================================================================
   LIVEROK — SOCLE D'INTERFACE, TÉLÉPHONE D'ABORD
   -----------------------------------------------------------------------------
   POURQUOI CE FICHIER EXISTE
   `app-styles.css` a été écrit pour le bureau : la barre latérale et `main{margin-left:260px}`
   sont l'état NORMAL, et le téléphone est rattrapé après coup par une quarantaine de blocs
   `@media(max-width:720px)` répartis sur plus de mille lignes, avec des points de rupture
   ajoutés au fil de l'eau (420, 560, 640, 720, 900, 1000, 1050). Chaque nouvelle
   fonctionnalité ajoute sa rustine, et les tailles de base (9, 10, 11 px, `svg{width:18px}`)
   restent celles d'un écran de bureau regardé à 60 cm. Sur un téléphone tenu à 30 cm, ces
   valeurs produisent exactement ce qu'on observe : icônes minuscules, libellés illisibles,
   cibles tactiles sous le seuil.

   Ce fichier ne réécrit pas app-styles.css — ce serait un chantier à haut risque pour le
   bureau, qui fonctionne. Il pose une COUCHE DE SOCLE chargée en dernier :
     1. il redéfinit les variables de marque, donc tout ce qui utilise déjà `var(--coral)`
        et consorts est re-habillé d'un coup, sans toucher aux règles existantes ;
     2. il ajoute les jetons qui manquaient (échelle typographique, espacement, rayons,
        élévations, durées, hauteur de barre, zone sûre, cible tactile) ;
     3. il fixe un PLANCHER de lisibilité et de tactilité sur téléphone.

   RÈGLE DE COHABITATION
   Aucun `@layer` : les styles non calqués de app-styles.css battraient toujours un calque.
   On s'appuie donc sur l'ordre de chargement (ce fichier est mis en file en dernier) et sur
   une spécificité égale ou légèrement supérieure. Les `!important` sont réservés aux cas où
   la règle visée en porte déjà un — ils sont commentés un par un.

   ACCESSIBILITÉ DES COULEURS — la nuance qui explique deux variables au lieu d'une
   Le coral de marque #FF624A ne donne que 2,97:1 avec du blanc : il est INTERDIT comme fond
   de bouton portant un libellé en texte courant. On garde donc :
     --lr-coral  = la marque. Graphismes, icônes, indicateurs, bordures, grands titres.
     --lr-action = le fond des boutons pleins (#D93A1E, 4,55:1 avec du blanc) — conforme AA.
     --lr-coral-ink = le coral en TEXTE sur fond clair (#C7381F, 5,17:1) — conforme AA.
   Ne jamais échanger les trois : la marque reste vive, le texte reste lisible.
   ============================================================================= */

:root {
  /* --- Marque : surcharge des variables historiques -------------------------
     Ces quatre-là existaient déjà et sont utilisées partout dans app-styles.css.
     Les redéfinir ici re-habille l'application entière sans éditer une seule règle.
     Les valeurs viennent de l'identité déjà écrite pour les pages de connexion
     (functions.php) : elle n'était appliquée qu'à wp-login, jamais à l'application. */
  --coral: #FF624A;
  --coral-dark: #D93A1E;
  --ink: #17332D;
  --mint: #86D1BB;
  --mint-pale: #EAF6F1;
  --muted: #5C7169;      /* 5,9:1 sur blanc — l'ancien #697872 passait tout juste */
  --line: #E8E6E0;
  --cream: #FFFFFF;      /* direction « clair et vif » : le fond de page devient blanc */
  --paper: #FFFFFF;
  --yellow: #F4B942;
  --radius: 20px;

  /* --- Couleurs de socle ---------------------------------------------------- */
  --lr-bg: #FFFFFF;              /* fond de page */
  --lr-bg-soft: #F6F6F3;         /* fond secondaire : regroupements, champs, zones calmes */
  --lr-surface: #FFFFFF;         /* cartes, feuilles, barres */
  --lr-surface-raised: #FFFFFF;
  --lr-ink: #17332D;             /* texte principal — 13,9:1 */
  --lr-ink-2: #47605A;           /* texte secondaire — 7,3:1 */
  --lr-ink-3: #6B817B;           /* texte tertiaire — 4,6:1, plancher AA */
  --lr-line: #E8E6E0;
  --lr-line-strong: #D6D3CA;

  --lr-coral: #FF624A;           /* MARQUE — jamais sous un texte courant blanc */
  --lr-coral-soft: #FFEDE9;
  --lr-coral-ink: #C7381F;       /* le coral quand c'est du TEXTE */
  --lr-action: #D93A1E;          /* fond des boutons pleins */
  --lr-action-press: #BE3116;

  --lr-mint: #86D1BB;
  --lr-mint-soft: #EAF6F1;
  --lr-mint-ink: #0F6B54;        /* menthe lisible en texte — 4,9:1 */

  --lr-warn: #F4B942;
  --lr-warn-soft: #FFF6E2;
  --lr-warn-ink: #8A5B00;
  --lr-danger: #C0392B;
  --lr-danger-soft: #FDEDEB;

  /* --- Échelle typographique ------------------------------------------------
     Plancher assumé : 13 px. Le 12 px n'est autorisé QUE pour les sur-titres en
     capitales espacées, où la forme des lettres compense la taille. Tout ce qui
     descendait à 8, 9 ou 10 px dans app-styles.css est relevé plus bas. */
  --lr-t-display: 30px;
  --lr-t-2xl: 25px;
  --lr-t-xl: 21px;
  --lr-t-lg: 18px;
  --lr-t-md: 16px;   /* corps de texte */
  --lr-t-sm: 15px;
  --lr-t-xs: 13px;   /* plancher */
  --lr-t-eyebrow: 12px;

  --lr-lh-tight: 1.15;
  --lr-lh-snug: 1.3;
  --lr-lh-body: 1.55;

  --lr-font-display: 'Baloo 2', 'DM Sans', system-ui, sans-serif;
  --lr-font-text: 'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* --- Espacement (base 4) -------------------------------------------------- */
  --lr-s1: 4px;  --lr-s2: 8px;  --lr-s3: 12px; --lr-s4: 16px;
  --lr-s5: 20px; --lr-s6: 24px; --lr-s8: 32px; --lr-s10: 40px; --lr-s12: 48px;

  /* --- Rayons --------------------------------------------------------------- */
  --lr-r-sm: 10px; --lr-r-md: 14px; --lr-r-lg: 18px; --lr-r-xl: 24px; --lr-r-full: 999px;

  /* --- Élévation : douce, jamais grise sale --------------------------------- */
  --lr-e1: 0 1px 2px rgba(23,51,45,.06), 0 2px 8px rgba(23,51,45,.05);
  --lr-e2: 0 2px 6px rgba(23,51,45,.07), 0 10px 26px rgba(23,51,45,.08);
  --lr-e3: 0 6px 14px rgba(23,51,45,.09), 0 24px 60px rgba(23,51,45,.14);
  --lr-glow: 0 8px 22px rgba(255,98,74,.28);

  /* --- Mouvement ------------------------------------------------------------ */
  --lr-ease: cubic-bezier(.2,.8,.2,1);
  --lr-ease-out: cubic-bezier(.16,1,.3,1);
  --lr-d-fast: 120ms; --lr-d-mid: 200ms; --lr-d-slow: 320ms;

  /* --- Métriques de coquille ------------------------------------------------
     `--lr-safe-*` existe pour qu'un module n'ait JAMAIS à réécrire `env(...)` :
     une seule définition, lisible partout, et modifiable en un point. */
  --lr-safe-t: env(safe-area-inset-top, 0px);
  --lr-safe-b: env(safe-area-inset-bottom, 0px);
  --lr-safe-l: env(safe-area-inset-left, 0px);
  --lr-safe-r: env(safe-area-inset-right, 0px);
  /* 72 px et non 62 : retour de terrain du 07/08 après déploiement, « les boutons en bas sont trop petits ».
     Le 62 px venait de la barre d'onglets iOS (49 pt ≈ 65 px), mais celle d'iOS porte des icônes PLEINES très
     lisibles ; les nôtres sont en trait fin, où le même encombrement paraît plus maigre. Et sur un iPhone la
     zone sûre du bas ajoute encore ~34 px qui n'appartiennent pas au doigt : ce qui reste réellement tactile,
     c'est cette valeur-ci. */
  --lr-nav-h: 72px;                                  /* hauteur utile de la barre du bas */
  --lr-nav-total: calc(var(--lr-nav-h) + var(--lr-safe-b));
  --lr-tap: 44px;                                    /* cible tactile minimale */
  --lr-gutter: 16px;

  /* --- Plans (fini les 9997 / 9998 / 10000 posés au jugé) -------------------- */
  --lr-z-sticky: 30;
  --lr-z-nav: 50;
  --lr-z-sheet: 60;
  --lr-z-scrim: 59;
  --lr-z-modal: 80;
  --lr-z-toast: 90;
}

/* =============================================================================
   1. BASE — ce qui vaut sur tous les écrans
   ============================================================================= */

html {
  /* Empêche iOS d'agrandir tout seul le texte en paysage, ce qui casse les
     grilles calculées au pixel. Le zoom manuel de l'utilisateur reste possible. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  background: var(--lr-bg);
  color: var(--lr-ink);
  font-family: var(--lr-font-text);
  font-size: var(--lr-t-md);
  line-height: var(--lr-lh-body);
  /* Le halo gris d'iOS au toucher donne un rendu « page web » sur une application
     installée. On le retire et on rend le retour tactile explicite (voir §4). */
  -webkit-tap-highlight-color: transparent;
}

/* Le rebond de fin de page qui découvre le fond du navigateur trahit lui aussi la
   page web. `overscroll-behavior-y:none` le supprime sur la coquille. */
.app-shell { overscroll-behavior-y: none; }

h1, h2, h3, h4 { font-family: var(--lr-font-display); letter-spacing: -.02em; }

/* Les sur-titres en capitales : seul endroit où 12 px est acceptable, parce que
   l'espacement des lettres et la graisse compensent la petite taille. */
.eyebrow, .nav-section-label { font-size: var(--lr-t-eyebrow); letter-spacing: .12em; font-weight: 800; }
.eyebrow.coral { color: var(--lr-coral-ink); }   /* l'ancien #997463 / --coral échouait en AA */
.eyebrow.mint { color: var(--lr-mint-ink); }

/* --- Icônes : une taille par contexte, plus une taille pour tout -------------
   app-styles.css finit sur `svg{width:18px;height:18px}`, appliqué à TOUTES les
   icônes du produit — d'où des pictogrammes de barre de navigation aussi petits
   que des puces de liste. Même spécificité, chargé plus tard : on reprend la main. */
svg { width: 20px; height: 20px; }
.nav-item svg { width: 22px; height: 22px; }
.icon-button svg { width: 22px; height: 22px; }
.section-icon { width: 18px !important; height: 18px !important; } /* la règle d'origine porte déjà !important */

/* --- Champs de saisie -------------------------------------------------------
   16 px n'est pas un choix esthétique : EN DESSOUS DE 16 px, iOS ZOOME
   automatiquement sur le champ au moment de la mise au point, décale toute la
   page, et l'utilisateur doit repincer pour revenir. C'est le défaut le plus
   universellement ressenti d'un formulaire web sur iPhone. */
input, textarea, select {
  font-family: var(--lr-font-text);
  font-size: var(--lr-t-md);
  color: var(--lr-ink);
  border-radius: var(--lr-r-md);
  border-color: var(--lr-line-strong);
}
input::placeholder, textarea::placeholder { color: var(--lr-ink-3); }
input:focus, textarea:focus, select:focus {
  border-color: var(--lr-coral);
  box-shadow: 0 0 0 3px rgba(255,98,74,.16);
}

/* --- Boutons ---------------------------------------------------------------- */
.primary, .secondary {
  font-family: var(--lr-font-text);
  font-size: var(--lr-t-sm);
  font-weight: 700;
  border-radius: var(--lr-r-md);
  min-height: var(--lr-tap);
  padding: 12px 18px;
  transition: transform var(--lr-d-fast) var(--lr-ease), box-shadow var(--lr-d-fast) var(--lr-ease), background var(--lr-d-fast) linear;
}
.primary {
  /* Aplat plutôt que dégradé : le dégradé `--coral → #f2824e` posé plus haut fait
     passer une partie du bouton sous le seuil de contraste avec son libellé blanc. */
  background: var(--lr-action);
  color: #fff;
  box-shadow: var(--lr-glow);
}
.primary:hover { background: var(--lr-action-press); }
.primary:active, .secondary:active { transform: scale(.97); }
.secondary {
  background: var(--lr-surface);
  color: var(--lr-ink);
  border: 1px solid var(--lr-line-strong);
}
.link-button, .text-link, .back-button { font-size: var(--lr-t-sm); font-weight: 700; }

/* --- Focus visible : une seule écriture pour tout le produit ---------------- */
:focus-visible { outline: 3px solid var(--lr-coral); outline-offset: 3px; border-radius: 4px; }

/* =============================================================================
   2. TÉLÉPHONE — le plancher de lisibilité et de tactilité
   Tout ce bloc ne concerne QUE les écrans étroits : le bureau garde sa densité.
   ============================================================================= */
@media (max-width: 720px) {

  /* --- 2.1 Zone sûre ---------------------------------------------------------
     Le `viewport-fit=cover` posé dans header.php fait passer la page SOUS l'encoche
     et sous la barre d'accueil. C'est voulu (le fond remonte, l'application ne
     paraît plus « posée dans un cadre »), mais cela impose de réserver ces zones
     partout où du contenu peut s'y trouver. Sans ce qui suit, activer viewport-fit
     rendrait le défaut de l'heure iOS PIRE, pas meilleur. */
  .app-shell { padding-left: var(--lr-safe-l); padding-right: var(--lr-safe-r); }

  main {
    /* Hauteur de la barre du bas + zone sûre, en un seul jeton : plus aucun module
       n'a à deviner cette valeur (elle était recopiée en dur à cinq endroits). */
    padding-bottom: calc(var(--lr-nav-total) + var(--lr-s4));
  }

  .topbar {
    padding-top: var(--lr-safe-t);
    height: calc(64px + var(--lr-safe-t));
    padding-left: var(--lr-gutter);
    padding-right: var(--lr-gutter);
  }

  /* Les vues qui n'ont pas de barre supérieure doivent réserver l'encoche elles-mêmes,
     sinon leur premier titre passe sous l'heure — c'est ce qu'on voit sur Accueil
     et sur Quêtes dès qu'on fait défiler. */
  .page-view { padding-top: calc(var(--lr-s6) + var(--lr-safe-t)); }

  /* --- 2.2 Lisibilité --------------------------------------------------------
     Relève d'un coup tout ce qui était descendu à 8-11 px. Les sélecteurs listés
     sont exactement ceux qui portent une taille inférieure au plancher dans
     app-styles.css ; on ne touche pas au reste. */
  .card-body .when,
  .meta, .meta span,
  .spots, .trust,
  .location-pill small, .location-pill strong,
  .floating-card, .floating-card small,
  .category,
  .conversation small, .chat-head small,
  .bubble, .bubble b, .bubble small,
  .people-cards p, .notification-list p, .notification-list small,
  .safety-card p, .safety-card strong,
  .privacy-line, .visibility-explainer,
  .week-timeline small, .week-timeline span,
  .next-event p, .event-date small,
  .review-author span, .reviews-preview article > small,
  .person-trust span, .friend-limit small,
  .interest-list span, .chip,
  .distance-badge, .org-badge,
  .activity-row-body .meta, .activity-row-footer,
  .calendar-legend, .calendar-legend span,
  .form-section-head p, .choice-card small,
  .settings-card small, .help-grid p, .legal-grid p,
  .empty-state p, .result-meta, .result-meta span {
    font-size: var(--lr-t-xs);
    line-height: var(--lr-lh-snug);
  }

  /* Les sous-titres de liste étaient en gris clair très petit : deux défauts
     cumulés (taille ET contraste). On corrige les deux ensemble. */
  .people-cards p, .notification-list p, .conversation small,
  .settings-card small, .empty-state p, .meta, .spots {
    color: var(--lr-ink-2);
  }

  /* LE TITRE ÉCRASÉ D'EXPLORER, expliqué. `.hero h1,.page-head h1,.create-header h1` porte
     `letter-spacing:-2.5px`, une valeur ABSOLUE calibrée pour un titre de 59 px sur grand écran. Ramené à
     30 px sur téléphone, ce même -2,5 px vaut -8 % du corps : les lettres se chevauchent et « Trouvez votre
     prochaine sortie » se lit « Trouvezvotreprochainesortie ». La règle est refaite en `em`, donc elle suit
     la taille au lieu de la combattre. */
  h1, .page-head h1, .create-header h1 {
    font-size: var(--lr-t-display); line-height: var(--lr-lh-tight); letter-spacing: -.025em;
  }
  .hero h1, .detail-copy h1, .profile-intro h1 { letter-spacing: -.025em; }

  /* L'EN-TÊTE DE PAGE NE POUSSE PLUS SON ACTION HORS DE L'ÉCRAN.
     `.page-head` est un `flex` en `space-between` sans droit de repli : un titre large (« Messages ») et un
     bouton nommé (« Mes amis ») se disputaient donc une largeur qu'ils n'avaient pas, et le bouton — dernier
     de la ligne, sans `min-width:0` — sortait par la droite. Il passe à la ligne quand il ne tient pas, ce qui
     est la seule issue correcte : rétrécir le bouton couperait son libellé, et rétrécir le titre le rendrait
     illisible. */
  .page-head { flex-wrap: wrap; gap: var(--lr-s3); }
  .page-head > * { min-width: 0; }
  .page-head > button, .page-head > a { flex: 0 1 auto; }

  /* DES CIBLES QU'ON PEUT VISER — mesure au banc, viewport 375 px.
     `.section-heading .text-link{font-size:0}` masque le libelle et ne laisse que la fleche : le bouton
     « Tous les resultats » tombait a 20 px de LARGE. Une fleche de 20 px au bout d'une ligne de titre est
     un piege : on la rate, on touche le titre, il ne se passe rien, et on croit l'application figee.
     Le libelle reste masque (la place manque vraiment), mais la surface, elle, redevient visable. */
  .section-heading .text-link { min-width: var(--lr-tap); justify-content: flex-end; }
  /* Les deux bascules Liste/Carte d'Explorer mesuraient 40 px de haut. Quatre pixels manquants, mais ce sont
     les quatre qui font la difference entre viser et appuyer. */
  .explore-view-toggle button, .calendar-view-toggle button { min-height: var(--lr-tap); }

  /* Les pastilles de visibilité (« 🌱 Membres ») étaient en position absolue à `right:0` avec un corps de
     10,5 px et `max-width:150px` : sur 393 px elles sortaient du cadre, se faisaient couper en plein mot, et
     flottaient au-dessus du champ PRÉCÉDENT — donc on ne savait pas à quoi elles s'appliquaient. Elles
     rentrent dans le flux, sous leur propre champ, à taille lisible. */
  .field-visibility { position: static; margin: 6px 0 0; text-align: right; }
  .field-visibility select { font-size: var(--lr-t-xs); max-width: 100%; padding: 8px 10px; min-height: 36px; }
  h2, .section-heading h2, .profile-section h2 { font-size: var(--lr-t-xl); }
  .card-body h3, .activity-row-body h3, .people-cards h3, .notification-list h3 { font-size: var(--lr-t-lg); }
  .hero h1 { font-size: 32px; }
  .hero p, .hero-copy p { font-size: var(--lr-t-md); }

  /* --- 2.3 Cibles tactiles ---------------------------------------------------
     Le seuil de 44 px n'est pas une convention de style : c'est la taille moyenne
     de la surface de contact d'un pouce. En dessous, l'erreur de visée devient
     mesurable, et c'est elle qui donne l'impression que « l'application ne répond
     pas ». Le CSS existant ne l'appliquait qu'à six sélecteurs nommés. */
  button, .chip, .subtabs button, .settings-nav button, .participant-tabs button,
  .message-tabs button, .template, .onboarding-choices button, .help-links button,
  .mobile-more-item, .place-results button, a.secondary, a.primary {
    min-height: var(--lr-tap);
  }
  /* Un lien ou un bouton posé dans une phrase ne doit pas se voir imposer 44 px de
     haut — il ferait sauter l'interligne. On l'élargit plutôt par une zone
     tactile invisible, technique standard et sans effet visuel. */
  .text-link, .link-button, .danger-link { position: relative; }
  .text-link::after, .link-button::after, .danger-link::after {
    content: ""; position: absolute; inset: -10px -8px;
  }

  .chips { gap: var(--lr-s2); }
  .chip { padding: 10px 14px; font-size: var(--lr-t-xs); border-radius: var(--lr-r-full); }

  /* --- 2.4 Débordements horizontaux ------------------------------------------
     Toute rangée qui défile horizontalement doit le faire DANS son conteneur et
     annoncer qu'elle continue. Les rangées de filtres coupées net au bord de
     l'écran (« En oré… ») viennent de l'absence de ces deux règles. */
  .chips, .subtabs, .settings-nav, .participant-tabs, .message-tabs, .calendar-legend {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    /* Le dégradé de fin dit « ça continue » sans ajouter un chevron à cliquer. */
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent);
    padding-right: 24px;
  }
  .chips::-webkit-scrollbar, .subtabs::-webkit-scrollbar { display: none; }
  .chip, .subtabs button { flex: 0 0 auto; }

  /* --- 2.5 Cartes et surfaces ------------------------------------------------ */
  .activity-card, .settings-card, .help-grid article, .legal-grid article,
  .people-cards article, .notification-list article, .activity-row {
    border-radius: var(--lr-r-lg);
    box-shadow: var(--lr-e1);
    border-color: var(--lr-line);
  }
  .empty-state { border-radius: var(--lr-r-lg); padding: var(--lr-s8) var(--lr-s5); }
  .empty-state p { font-size: var(--lr-t-sm); }

  /* --- 2.6 Pied de page public ----------------------------------------------
     Sur téléphone, six liens juridiques empilés sous chaque écran d'application
     donnent l'impression d'être arrivé au bout d'un site, pas dans une app. Ils
     restent atteignables (Profil → mentions), mais quittent le flux principal. */
  .public-footer { display: none; }
}

/* =============================================================================
   3. BARRE DE NAVIGATION DU BAS
   Reconstruite : c'est l'élément le plus vu de toute l'application.
   ============================================================================= */
@media (max-width: 720px) {
  .mobile-nav {
    display: grid;
    /* Colonnes automatiques et non `repeat(5,...)` : l'onglet Quêtes naît masqué tant que le
       serveur n'a pas confirmé le module. Avec un gabarit figé, il laisserait un trou dans la
       barre ; ici, la barre se referme sur quatre colonnes et personne ne voit la différence.

       `grid-template-columns:none` N'EST PAS DÉCORATIF, c'est la moitié utile de la règle.
       app-styles.css déclare encore `grid-template-columns:repeat(6,minmax(0,1fr))`, hérité de
       l'époque où Messages occupait une sixième place — place rendue vacante quand il est remonté
       dans la barre d'application (3.64.0). Or un gabarit EXPLICITE l'emporte toujours sur des
       colonnes automatiques : `grid-auto-columns` ne s'applique qu'aux pistes IMPLICITES, donc
       au-delà de la sixième. La barre gardait donc six colonnes pour cinq boutons, et cette
       sixième colonne vide poussait tout le monde vers la gauche — un cinquième d'écran de
       décalage, visible immédiatement sur iPhone. Il faut effacer le gabarit pour que les
       colonnes automatiques reprennent la main. */
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: var(--lr-z-nav);
    height: var(--lr-nav-total);
    padding: 6px var(--lr-safe-r) var(--lr-safe-b) var(--lr-safe-l);
    background: color-mix(in srgb, var(--lr-surface) 88%, transparent);
    /* Le flou laisse deviner le contenu qui passe dessous : la barre appartient à
       l'écran au lieu de le couper. Repli propre si le navigateur ne sait pas faire. */
    -webkit-backdrop-filter: saturate(180%) blur(18px);
    backdrop-filter: saturate(180%) blur(18px);
    border-top: 1px solid var(--lr-line);
    box-shadow: 0 -1px 0 rgba(23,51,45,.03);
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .mobile-nav { background: var(--lr-surface); }
  }

  .mobile-nav button {
    display: grid;
    grid-template-rows: 28px auto;
    justify-items: center;
    align-content: center;
    gap: 4px;
    min-height: var(--lr-tap);
    border: 0;
    background: none;
    color: var(--lr-ink-3);
    font-family: var(--lr-font-text);
    transition: color var(--lr-d-fast) linear;
  }
  .mobile-nav button svg { width: 27px; height: 27px; stroke-width: 1.9; }
  .mobile-nav small {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: -.01em;
    line-height: 1;
  }
  /* L'onglet courant se signale par la COULEUR ET par une pastille : sur une barre claire, la couleur seule
     demande de comparer cinq icônes entre elles pour savoir où l'on est. La pastille se voit sans comparer. */
  .mobile-nav button.active { color: var(--lr-coral-ink); }
  .mobile-nav button.active svg { stroke-width: 2.4; }
  .mobile-nav button.active::before {
    content: ""; position: absolute; top: 2px; left: 50%; transform: translateX(-50%);
    width: 46px; height: 32px; border-radius: var(--lr-r-full);
    background: var(--lr-coral-soft);
  }
  /* `z-index:-1` sur la pastille l'enverrait DERRIÈRE le fond de la barre, donc invisible : la barre porte un
     fond, elle crée son propre plan. On élève plutôt le contenu du bouton au-dessus de la pastille. */
  .mobile-nav button > * { position: relative; z-index: 1; }
  .mobile-nav button:active { transform: none; }

  /* Le bouton central d'action. Il ne monte plus hors de la barre (le débord
     de 16 px du modèle précédent chevauchait le contenu et coupait les listes) :
     il reste dans la barre, mais il est le seul élément plein. */
  .mobile-nav .create-mobile {
    width: 54px; height: 54px;
    margin: auto;
    border-radius: 17px;
    background: var(--lr-action);
    color: #fff;
    transform: none;
    box-shadow: var(--lr-glow);
    grid-template-rows: auto;
    place-content: center;
  }
  .mobile-nav .create-mobile svg { width: 30px; height: 30px; stroke-width: 2.4; }
  .mobile-nav .create-mobile.active::before { display: none; }   /* il est déjà plein : la pastille ferait double emploi */
  .mobile-nav .create-mobile:active { transform: scale(.94); }

  /* Pastille de non-lus : posée sur l'icône, pas à côté du libellé. */
  .mobile-nav button .lr-dot {
    position: absolute; top: 4px; right: calc(50% - 18px);
    min-width: 17px; height: 17px; padding: 0 5px;
    border-radius: var(--lr-r-full);
    background: var(--lr-action); color: #fff;
    font-size: 11px; font-weight: 800; line-height: 17px;
    border: 2px solid var(--lr-surface);
  }
  .mobile-nav button { position: relative; }
  /* `.mobile-nav button` est en display:grid ; sans cette ligne, l'attribut `hidden` de
     l'onglet Quêtes serait sans effet (display gagne sur la sémantique HTML). */
  .mobile-nav button[hidden] { display: none; }

  /* --- 3.1 Barre supérieure de l'accueil ------------------------------------
     `.top-actions img{display:none}` masquait l'AVATAR mais laissait son bouton :
     d'où le carré gris vide en haut à droite. Sur téléphone, l'onglet Profil de la
     barre du bas rend ce raccourci redondant — on retire le bouton entier. */
  .top-actions .avatar-button { display: none; }
  .top-actions { gap: var(--lr-s2); }
  .location-pill { min-height: var(--lr-tap); border-radius: var(--lr-r-md); }
  .location-pill strong { font-size: var(--lr-t-xs); max-width: 42vw; }
  .location-pill small { font-size: var(--lr-t-eyebrow); color: var(--lr-ink-3); }
}

/* --- 3.2 « Tout LIVEROK » : le menu Plus, sorti de la barre ------------------
   Une rangée pleine largeur en bas du profil plutôt qu'une 6e cible tactile.
   Elle est dessinée comme une action, pas comme un lien perdu. */
.lr-launcher-trigger {
  display: flex;
  align-items: center;
  gap: var(--lr-s3);
  width: 100%;
  margin: var(--lr-s6) 0 var(--lr-s4);
  padding: var(--lr-s4);
  min-height: 68px;
  border: 1px solid var(--lr-line);
  border-radius: var(--lr-r-lg);
  background: var(--lr-surface);
  box-shadow: var(--lr-e1);
  color: var(--lr-ink);
  text-align: left;
  cursor: pointer;
}
.lr-launcher-trigger .mm-ic {
  flex: none;
  display: grid; place-items: center;
  width: 42px; height: 42px;
  border-radius: var(--lr-r-md);
  background: var(--lr-coral-soft);
  color: var(--lr-coral-ink);
}
.lr-launcher-trigger .mm-ic svg { width: 22px; height: 22px; }
.lr-launcher-copy { display: grid; gap: 2px; min-width: 0; }
.lr-launcher-copy strong { font-family: var(--lr-font-display); font-size: var(--lr-t-lg); }
.lr-launcher-copy small {
  font-size: var(--lr-t-xs); color: var(--lr-ink-2); line-height: var(--lr-lh-snug);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lr-launcher-go { margin-left: auto; flex: none; color: var(--lr-ink-3); }
.lr-launcher-trigger:active { background: var(--lr-bg-soft); }

/* =============================================================================
   4. PRIMITIVES RÉUTILISABLES — préfixe `lr-`
   Ce que chaque module réécrivait dans son coin, écrit une fois.
   ============================================================================= */

/* --- 4.1 Feuille du bas -----------------------------------------------------
   Trois crans, glissable, et surtout : elle ne recouvre JAMAIS la barre de
   navigation, et son contenu est la seule surface qui défile. Le défaut observé
   sur l'écran des quêtes — la feuille épinglée par-dessus le pied de page pendant
   que la page continue de défiler derrière — vient de deux surfaces de défilement
   concurrentes. Ici il n'y en a qu'une. */
.lr-sheet {
  position: fixed;
  left: 0; right: 0;
  bottom: var(--lr-nav-total);
  z-index: var(--lr-z-sheet);
  display: flex;
  flex-direction: column;
  background: var(--lr-surface);
  border-radius: var(--lr-r-xl) var(--lr-r-xl) 0 0;
  box-shadow: var(--lr-e3);
  /* `dvh` et non `vh` : sur iOS, `vh` mesure l'écran barre d'adresse RÉTRACTÉE,
     donc une feuille en `88vh` dépasse de l'écran tant que la barre est visible. */
  max-height: calc(92dvh - var(--lr-nav-total));
  transition: height var(--lr-d-slow) var(--lr-ease-out);
  touch-action: none;               /* la poignée pilote le geste, pas le défilement */
}
.lr-sheet[hidden] { display: none; }
.lr-sheet-grip {
  flex: none;
  padding: 10px 0 6px;
  display: grid; place-items: center;
  cursor: grab;
}
.lr-sheet-grip::before {
  content: ""; width: 40px; height: 5px; border-radius: 3px; background: var(--lr-line-strong);
}
.lr-sheet-body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;     /* le geste ne « traverse » pas vers la page */
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  padding: 0 var(--lr-gutter) calc(var(--lr-s6) + var(--lr-safe-b));
}
.lr-sheet.is-peek { height: 112px; }
.lr-sheet.is-half { height: 52dvh; }
.lr-sheet.is-full { height: calc(92dvh - var(--lr-nav-total)); }
.lr-sheet.is-dragging { transition: none; }

.lr-scrim {
  position: fixed; inset: 0;
  z-index: var(--lr-z-scrim);
  background: rgba(23,51,45,.45);
  border: 0;
  opacity: 0;
  transition: opacity var(--lr-d-mid) linear;
}
.lr-scrim.is-on { opacity: 1; }
.lr-scrim[hidden] { display: none; }

/* --- 4.2 En-tête d'écran collant -------------------------------------------
   Réserve l'encoche, se pose au-dessus du contenu et s'annonce par une ombre
   seulement une fois qu'on a commencé à faire défiler (classe posée en JS). */
.lr-appbar {
  position: sticky;
  top: 0;
  z-index: var(--lr-z-sticky);
  display: flex;
  align-items: center;
  gap: var(--lr-s3);
  min-height: 52px;
  padding: calc(var(--lr-safe-t) + 8px) var(--lr-gutter) 8px;
  background: color-mix(in srgb, var(--lr-surface) 90%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  backdrop-filter: saturate(180%) blur(16px);
  transition: box-shadow var(--lr-d-mid) linear;
}
.lr-appbar.is-stuck { box-shadow: var(--lr-e1); }
.lr-appbar h1, .lr-appbar h2 {
  margin: 0; font-size: var(--lr-t-lg); font-weight: 800;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lr-appbar-actions { margin-left: auto; display: flex; gap: var(--lr-s2); }

/* --- 4.3 Bouton rond posé sur une carte / une image -------------------------- */
.lr-fab {
  width: var(--lr-tap); height: var(--lr-tap);
  display: grid; place-items: center;
  border: 1px solid var(--lr-line);
  border-radius: var(--lr-r-full);
  background: color-mix(in srgb, var(--lr-surface) 92%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  color: var(--lr-ink);
  box-shadow: var(--lr-e1);
  transition: transform var(--lr-d-fast) var(--lr-ease);
}
.lr-fab:active { transform: scale(.94); }
.lr-fab.is-on { background: var(--lr-mint-soft); border-color: var(--lr-mint); color: var(--lr-mint-ink); }

/* --- 4.4 Squelettes de chargement -------------------------------------------
   « Chargement de vos informations… » écrit en texte est un aveu d'attente ;
   un squelette est une promesse de contenu. Il occupe en plus la place définitive,
   donc l'écran ne saute pas au moment où les données arrivent. */
.lr-skeleton {
  background: linear-gradient(100deg, var(--lr-bg-soft) 30%, #EFEFEA 50%, var(--lr-bg-soft) 70%);
  background-size: 220% 100%;
  animation: lr-shimmer 1.3s linear infinite;
  border-radius: var(--lr-r-sm);
  color: transparent !important;   /* neutralise un texte de remplissage éventuel */
}
@keyframes lr-shimmer { to { background-position: -220% 0; } }

/* --- 4.5 Le cachet : la signature visuelle du produit ------------------------
   C'est la seule forme que LIVEROK possède en propre — la preuve qu'une sortie a
   été RÉELLEMENT vécue. Elle mérite d'être dessinée une fois et réutilisée
   partout (quête réussie, haut fait, profil), plutôt que redessinée par écran. */
.lr-stamp {
  display: inline-grid; place-items: center;
  width: 56px; height: 56px;
  border-radius: var(--lr-r-full);
  border: 2.5px dashed var(--lr-coral);
  color: var(--lr-coral-ink);
  background: var(--lr-coral-soft);
  font-family: var(--lr-font-display);
  font-weight: 800;
  transform: rotate(-8deg);
}
.lr-stamp.is-locked { border-color: var(--lr-line-strong); color: var(--lr-ink-3); background: var(--lr-bg-soft); }

/* --- 4.6 Retour tactile ------------------------------------------------------
   Le halo gris d'iOS a été retiré plus haut ; il faut le remplacer, sinon un
   appui ne produit AUCUN retour et l'utilisateur appuie deux fois. */
@media (hover: none) {
  .activity-card:active, .activity-row:active, .people-cards article:active,
  .notification-list article:active, .mobile-more-item:active, .lr-row:active {
    background: var(--lr-bg-soft);
    transition: none;
  }
}

/* --- 4.7 Mouvement réduit ---------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .lr-skeleton { animation: none; }
  .lr-sheet { transition: none; }
}

/* --- 4.8 Squelette du profil -------------------------------------------------
   Il reproduit la FORME du profil chargé (rond d'avatar + trois lignes), pas un
   rectangle générique : c'est ce qui fait qu'on reconnaît l'écran avant qu'il
   arrive, et que rien ne se déplace quand il arrive. */
.lr-profile-boot { display: flex; align-items: center; gap: var(--lr-s4); width: 100%; }
.lr-sk-avatar { width: 84px; height: 84px; border-radius: 26px; flex: none; }
.lr-sk-lines { display: grid; gap: var(--lr-s2); flex: 1 1 auto; min-width: 0; }
@media (max-width: 720px) {
  .lr-sk-avatar { width: 68px; height: 68px; border-radius: 22px; }
}

/* --- 4.9 « Votre exploration » : l'écusson de la rubrique ---------------------
   Les territoires ont quitté la carte des quêtes. Ce qu'on a ouvert sur Terre
   est un fait acquis qui s'accumule tout seul : ça se contemple depuis son
   profil, ça ne se filtre pas à côté de « à faire à plusieurs ».
   Il n'en reste que l'écusson : la CARTE-LIEN qui vivait ici (`.lr-explore-card`,
   `.lr-explore-copy`, `.lr-explore-go`) a été retirée le 07/08 avec le saut vers
   l'écran Quêtes qu'elle déclenchait. La rubrique est désormais entière dans le
   profil — voir 4.10 juste en dessous. */
.lr-explore-mark {
  flex: none; display: grid; place-items: center; width: 48px; height: 48px;
  border-radius: var(--lr-r-full); background: var(--lr-surface);
  border: 2px solid var(--lr-mint); color: var(--lr-mint-ink); box-shadow: var(--lr-e1);
}
.lr-explore-mark svg { width: 26px; height: 26px; }

/* En mode exploration, la carte cesse d'annoncer un catalogue : ni bandeau de création,
   ni onglets de journal — on regarde ce qu'on a parcouru, on ne cherche pas quoi faire. */
#quests.is-exploring .quests-brief .quests-head-actions,
#quests.is-exploring .quests-terrains { display: none; }

/* --- 4.10 La rubrique « Votre exploration », ENTIÈRE, DANS LE PROFIL ----------
   Elle a remplacé la carte-lien : plus de saut vers l'écran Quêtes pour consulter
   son propre passé. Trois strates, dans l'ordre où on les lit :
     1. les CHIFFRES — ce qu'on a accompli, lisible sans rien toucher ;
     2. la CARTE — les lieux réellement atteints, situés les uns par rapport aux
        autres, ce qu'aucune liste ne sait montrer ;
     3. la LISTE — l'ordre du temps, que la carte ne sait pas montrer.
   Elle est posée haut dans le profil, juste après l'en-tête. */
/* --- 4.11 Le profil rangé : consultation d'abord, réglages repliés ------------
   Le rang de chaque bloc est posé ici plutôt que par déplacement DOM : trois
   modules greffent des sections sur cette vue à des instants qu'aucun d'eux ne
   contrôle, et se disputer l'ordre par insertions successives est la course dont
   on ne sort pas. Un rang tient quel que soit l'ordre d'arrivée.
   Rangs : 0 la couverture · 1 l'identité et ce qu'on a accompli · 10 les avis ·
   20+ les tiroirs de réglages · 30 la navigation · 40 la déconnexion. */
/* `.view.lr-profile-tidy.active` ET NON `.lr-profile-tidy` SEUL — c'est la différence entre un profil rangé et un
   site inutilisable, et elle tient à deux classes.
   `app-styles.css` déclare `.view{display:none}` puis `.view.active{display:block}`. Un `.lr-profile-tidy{display:flex}`
   nu pèse exactement autant que `.view` (une classe), mais `ui.css` est imprimé APRÈS : il gagnait donc, et le profil
   restait AFFICHÉ EN PERMANENCE, empilé sous tous les autres écrans. Toucher la cloche ouvrait bien les
   notifications — on tombait simplement sur le profil resté visible en dessous.
   La règle exige donc `.active`, ce qui la rend inopérante quand la vue est masquée, et porte trois classes, ce qui
   la place au-dessus de `.view.active` sans dépendre de l'ordre des feuilles. */
.view.lr-profile-tidy.active { display: flex; flex-direction: column; }
.lr-profile-tidy > .profile-cover { order: 0; }
.lr-profile-tidy > .profile-main { order: 1; }
.lr-profile-tidy > .received-reviews-real { order: 10; }
.lr-profile-tidy > .lr-launcher-trigger { order: 30; }
.lr-profile-tidy > .lr-profile-signout { order: 40; margin-top: var(--lr-s6); }

/* Dans l'en-tête : qui je suis, puis ce que j'ai fait. Le formulaire de compte a quitté ce bloc
   pour un tiroir, mais le rang le renvoie en queue si un jour il y revenait. */
.lr-profile-tidy .profile-main { display: flex; flex-direction: column; }
.lr-profile-tidy .profile-main > .profile-intro { order: 0; }
.lr-profile-tidy .profile-main > .lr-xp { order: 1; }
.lr-profile-tidy .profile-main > .xp-block { order: 2; }
.lr-profile-tidy .profile-main > .profile-section { order: 9; }

/* Le tiroir. Fermé, c'est UNE LIGNE qui dit ce qu'il y a derrière — jamais un titre seul :
   « Zone de recherche » ne dit pas qu'on y règle son rayon, et on ne l'ouvrirait donc jamais. */
.lr-fold {
  margin: var(--lr-s3) 0; border: 1px solid var(--lr-line);
  border-radius: var(--lr-r-lg); background: var(--lr-surface); overflow: hidden;
}
.lr-fold > summary {
  display: flex; align-items: center; gap: var(--lr-s3);
  padding: var(--lr-s4); min-height: 64px; cursor: pointer; list-style: none;
}
.lr-fold > summary::-webkit-details-marker { display: none; }
.lr-fold > summary:hover { background: var(--lr-bg-soft); }
.lr-fold-copy { display: grid; gap: 2px; min-width: 0; flex: 1; }
.lr-fold-copy strong { font-family: var(--lr-font-display); font-size: var(--lr-t-md); }
.lr-fold-copy small { font-size: var(--lr-t-xs); color: var(--lr-ink-2); line-height: var(--lr-lh-snug); }
/* Le chevron tourne : c'est le seul signe qui dit « ceci s'ouvre » avant qu'on l'ait touché. */
.lr-fold-chevron {
  flex: none; width: 10px; height: 10px; border-right: 2px solid var(--lr-ink-3);
  border-bottom: 2px solid var(--lr-ink-3); transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .18s ease;
}
.lr-fold[open] > summary { border-bottom: 1px solid var(--lr-line); }
.lr-fold[open] .lr-fold-chevron { transform: rotate(-135deg) translate(-2px, -2px); }
@media (prefers-reduced-motion: reduce) { .lr-fold-chevron { transition: none; } }
/* Le bloc rangé perd sa marge propre et son titre : le tiroir porte déjà les deux, et les voir
   deux fois ferait croire à deux sections imbriquées. */
.lr-fold > :not(summary) { margin: 0; padding: var(--lr-s4); }
.lr-fold > :not(summary) > h2:first-child { display: none; }

/* La marge vit ICI et non dans `.profile-section` : reprendre cette classe ferait écraser la rubrique
   par le formulaire de compte (voir le commentaire dans quests.js). */
.lr-xp { display: grid; gap: var(--lr-s4); margin: var(--lr-s8) 0; }
.lr-xp-head { display: flex; align-items: center; gap: var(--lr-s4); }
.lr-xp-head > div { display: grid; gap: 2px; min-width: 0; }
.lr-xp-head h2 { margin: 0; }
.lr-xp-head p { margin: 0; font-size: var(--lr-t-xs); color: var(--lr-ink-2); line-height: var(--lr-lh-snug); }

/* Les vignettes de chiffres. `auto-fit` plutôt qu'un nombre de colonnes figé : le nombre d'échelons
   ouverts change avec la personne, et une grille à trois colonnes laisserait un trou béant chez
   quelqu'un qui n'a encore ouvert qu'une commune. */
.lr-xp-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: var(--lr-s2); }
.lr-xp-stats:empty { display: none; }
.lr-xp-stat {
  display: grid; gap: 2px; justify-items: center; text-align: center;
  padding: var(--lr-s3) var(--lr-s2); border: 1px solid var(--lr-line);
  border-radius: var(--lr-r-md); background: var(--lr-surface);
}
/* Une distance par activité tient sur deux colonnes : « 310 km » suivi de « Vélo » ne se plie pas
   dans 96 px, et le chiffre coupé en deux lignes cesse d'être lisible d'un coup d'œil. */
.lr-xp-stat.is-wide { grid-column: span 2; }
.lr-xp-stat b { font-family: var(--lr-font-display); font-size: var(--lr-t-xl); line-height: 1; color: var(--lr-ink); }
.lr-xp-stat small { font-size: var(--lr-t-xs); color: var(--lr-ink-2); line-height: var(--lr-lh-snug); }
/* L'emblème est le MÊME que sur la carte : un signe vu sur la carte et une ligne lue dans le carnet
   doivent parler du même monde, sinon il faut apprendre deux vocabulaires. */
.lr-xp-stat-glyph { font-size: 20px; line-height: 1; }

.lr-xp-map {
  height: 260px; border: 1px solid var(--lr-line); border-radius: var(--lr-r-lg);
  overflow: hidden; background: var(--lr-bg-soft);
}
.lr-xp-map[hidden] { display: none; }
/* Un territoire touché SITUE, il ne réclame pas l'attention : pastille sourde, jamais cliquable. */
.lr-xp-territory {
  display: block; width: 12px; height: 12px; border-radius: var(--lr-r-full);
  background: rgba(15,107,84,.34); box-shadow: 0 0 0 3px rgba(134,209,187,.22);
}
/* Un passage réel, lui, est un FAIT : il se voit, et il se touche. */
.lr-xp-place {
  display: grid; place-items: center; width: 30px; height: 30px; border-radius: var(--lr-r-full);
  background: var(--lr-surface); border: 2px solid var(--lr-mint);
  box-shadow: var(--lr-e1); font-size: 15px; cursor: pointer;
}
.lr-xp-popup .leaflet-popup-content { margin: 12px 14px; display: grid; gap: 2px; }
.lr-xp-popup .leaflet-popup-content b { font-family: var(--lr-font-display); font-size: var(--lr-t-sm); }
.lr-xp-popup .leaflet-popup-content span { font-size: var(--lr-t-xs); color: var(--lr-ink-2); }
.lr-xp-when { color: var(--lr-mint-ink) !important; font-weight: 700; }

.lr-xp-list { display: grid; gap: var(--lr-s2); }
.lr-xp-subtitle { margin: var(--lr-s2) 0 0; font-family: var(--lr-font-display); font-size: var(--lr-t-sm); }
.lr-xp-runs, .lr-xp-territories { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--lr-s2); }
.lr-xp-runs li, .lr-xp-territories li {
  display: flex; align-items: center; gap: var(--lr-s3);
  padding: var(--lr-s3); border: 1px solid var(--lr-line);
  border-radius: var(--lr-r-md); background: var(--lr-surface);
}
.lr-xp-glyph, .lr-xp-tier { flex: none; font-size: 19px; line-height: 1; }
.lr-xp-run-copy { display: grid; gap: 2px; min-width: 0; flex: 1; }
.lr-xp-run-copy b { font-size: var(--lr-t-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lr-xp-run-copy small { font-size: var(--lr-t-xs); color: var(--lr-ink-2); }
.lr-xp-percent { flex: none; font-weight: 800; font-size: var(--lr-t-xs); color: var(--lr-mint-ink); }
.lr-xp-empty { margin: 0; font-size: var(--lr-t-sm); color: var(--lr-ink-2); line-height: var(--lr-lh-snug); }
.lr-xp-feedback { display: grid; gap: var(--lr-s2); justify-items: start; }
.lr-xp-feedback[hidden] { display: none; }

@media (max-width: 720px) {
  /* La carte gagne de la hauteur sur téléphone : c'est la strate qu'on regarde le plus longtemps,
     et 260 px sur un écran étroit ne montrent qu'une poignée de repères collés les uns aux autres. */
  .lr-xp-map { height: 300px; }
  .lr-xp-stats { grid-template-columns: repeat(auto-fit, minmax(88px, 1fr)); }
}

/* =============================================================================
   5. BARRE D'APPLICATION GLOBALE — « en haut, ce qui m'attend »
   -----------------------------------------------------------------------------
   Elle vivait DANS l'écran d'accueil, donc elle n'existait que là : c'est la
   raison structurelle pour laquelle Messages avait dû descendre occuper une des
   cinq places du bas. Sortie de #home, elle porte maintenant sur chaque écran :
     — à gauche le CONTEXTE (la zone de recherche : « où je regarde ») ;
     — à droite la COUCHE PERSONNELLE (messages, notifications), avec pastilles.
   Le partage est celui des applications grand public, et il n'est pas
   esthétique : le bas répond à « où je vais », il doit donc rester stable et peu
   nombreux ; le haut répond à « qu'est-ce qui m'attend », il doit donc être
   présent partout et savoir réclamer l'attention. Mélanger les deux, c'est
   obtenir six onglets dont trois clignotent.
   ============================================================================= */
@media (max-width: 720px) {
  .topbar {
    position: sticky; top: 0; z-index: var(--lr-z-sticky);
    display: flex; align-items: center; gap: var(--lr-s2);
    background: color-mix(in srgb, var(--lr-surface) 88%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(18px);
    backdrop-filter: saturate(180%) blur(18px);
    border-bottom: 1px solid var(--lr-line);
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .topbar { background: var(--lr-surface); }
  }
  .search-zone-control { min-width: 0; flex: 1 1 auto; }
  .location-pill { max-width: 100%; }
  .location-pill strong { max-width: 46vw; }

  .top-actions { flex: none; margin-left: auto; }
  .top-actions .icon-button { border: 0; background: transparent; position: relative; }
  .top-actions .icon-button svg { width: 25px; height: 25px; }
  /* Pastille de non-lus CHIFFRÉE et non un simple point : un point dit qu'il se passe
     quelque chose, un chiffre dit s'il faut y aller maintenant. C'est le seul élément de
     l'interface autorisé à réclamer l'attention, il doit donc être exact. */
  .top-actions .lr-dot {
    position: absolute; top: 2px; right: 0;
    min-width: 18px; height: 18px; padding: 0 5px;
    border-radius: var(--lr-r-full);
    background: var(--lr-action); color: #fff;
    font-size: 11px; font-weight: 800; line-height: 18px; text-align: center;
    border: 2px solid var(--lr-surface);
  }
  /* L'ancien point sans chiffre ferait doublon avec la pastille. */
  .top-actions .icon-button i[data-notification-dot] { display: none; }

  /* L'écran des Quêtes est une carte plein écran avec ses propres commandes flottantes : une barre
     d'application par-dessus lui volerait 60 px et ferait deux rangées d'outils.
     `:has()` et non un sélecteur de fratrie : la barre PRÉCÈDE les vues dans le gabarit, donc aucun
     combinateur `~` ne peut l'atteindre depuis #quests. Sur un navigateur sans `:has()`, la règle est
     simplement ignorée — et c'est sans conséquence, la carte étant en position fixe elle recouvre déjà
     la barre. La règle sert la propreté, pas la correction. */
  .app-shell:has(#quests.view.active) .topbar { display: none; }
}

/* --- 5.1 Le garde-fou anti-débordement cassait le collage ---------------------
   `app-styles.css` pose `html,body{overflow-x:hidden}` pour empêcher un élément
   trop large de faire défiler la page latéralement. Effet de bord peu connu et
   décisif ici : `overflow-x:hidden` fait de l'élément un CONTENEUR DE DÉFILEMENT,
   ce qui coupe `position:sticky` pour tout ce qu'il contient — mesuré au banc,
   la barre d'application repartait vers le haut au premier glissement.
   `clip` interdit exactement le même débordement mais ne crée PAS de conteneur
   de défilement : le collage fonctionne, la protection reste.
   Les navigateurs qui ignorent `clip` conservent la déclaration `hidden`
   précédente — ils perdent le collage, jamais la protection. */
html, body { overflow-x: clip; }
