/* ================== ONAS Multi-role launcher ================== */
/* [v244] Pulse vert pour usagers/admins en ligne (avatar/list dots) */
@keyframes onasOnlinePulse {
  0%, 100% { transform: scale(1);   box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.6); }
  50%      { transform: scale(1.15); box-shadow: 0 0 0 5px rgba(34, 197, 94, 0); }
}

/* [v250] Grid responsive pour les listes de cartes côté usager (demandes,
   déclarations). En mobile : 1 colonne pleine largeur. En tablette/desktop :
   2-4 colonnes selon la viewport — utile quand l'APK tourne sur tablette
   Android ou en PWA grand écran. */
/* [v481] Cards historique : meme hauteur via grid-auto-rows + stretch */
.usager-cards-grid {
  padding: 0 16px;
  display: grid;
  grid-template-columns: 1fr;
  grid-auto-rows: 1fr;
  gap: 10px;
  align-items: stretch;
}
.usager-cards-grid > button {
  height: 100%;
  display: flex;
  flex-direction: column;
}
@media (min-width: 600px) {
  .usager-cards-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; padding: 0 22px; }
}
@media (min-width: 900px) {
  .usager-cards-grid { grid-template-columns: repeat(3, 1fr); gap: 14px; padding: 0 28px; }
}
@media (min-width: 1200px) {
  .usager-cards-grid { grid-template-columns: repeat(4, 1fr); gap: 16px; padding: 0 32px; max-width: 1400px; margin: 0 auto; }
}


/* Layered on top of app-styles.css + hifi-styles.css. Provides role
   switcher, multi-frame stage, landing screen, admin desktop wrapper,
   plus a polish layer that lifts the whole design. */

:root {
  --landing-bg: radial-gradient(ellipse at 20% -10%, #2c4f7a 0%, #14294a 35%, #050b18 70%);
  --orange-glow: 0 18px 48px -12px rgba(232, 90, 44, 0.55);
  --navy-glow: 0 22px 60px -16px rgba(15, 37, 64, 0.7);
  --glass: rgba(255, 255, 255, 0.06);
  --glass-strong: rgba(255, 255, 255, 0.1);
  --glass-line: rgba(255, 255, 255, 0.14);
  --aurora-1: rgba(232, 90, 44, 0.18);
  --aurora-2: rgba(46, 184, 114, 0.12);
  --aurora-3: rgba(91, 145, 215, 0.18);
}

html, body { height: 100%; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--landing-bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  overflow-x: hidden;
  position: relative;
}

/* Animated aurora behind everything */
body::before {
  content: "";
  position: fixed;
  inset: -10%;
  background:
    radial-gradient(60% 50% at 15% 20%, var(--aurora-1) 0%, transparent 60%),
    radial-gradient(50% 40% at 85% 30%, var(--aurora-3) 0%, transparent 70%),
    radial-gradient(40% 30% at 60% 90%, var(--aurora-2) 0%, transparent 70%);
  filter: blur(40px);
  z-index: 0;
  pointer-events: none;
  animation: aurora 18s ease-in-out infinite alternate;
}
@keyframes aurora {
  0%   { transform: translate3d(0, 0, 0) scale(1); opacity: 0.85; }
  50%  { transform: translate3d(2%, -2%, 0) scale(1.05); opacity: 1; }
  100% { transform: translate3d(-2%, 1%, 0) scale(1.02); opacity: 0.9; }
}

/* Subtle starfield grain */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  background-image:
    radial-gradient(1px 1px at 25% 30%, rgba(255,255,255,0.4), transparent),
    radial-gradient(1px 1px at 50% 80%, rgba(255,255,255,0.25), transparent),
    radial-gradient(1px 1px at 80% 15%, rgba(255,255,255,0.35), transparent),
    radial-gradient(1px 1px at 10% 60%, rgba(255,255,255,0.2), transparent),
    radial-gradient(1px 1px at 70% 50%, rgba(255,255,255,0.3), transparent);
  opacity: 0.4;
  z-index: 0;
  pointer-events: none;
}

/* ===== Persona launcher (landing) — soft light-gray with animated bg ===== */
.launcher {
  min-height: 100vh;
  padding: 72px 24px 56px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 44px;
  color: var(--ink);
  text-align: center;
  position: relative;
  z-index: 1;
  overflow: hidden;
  background:
    radial-gradient(60% 40% at 25% 5%,  rgba(232, 90, 44, 0.04), transparent 70%),
    radial-gradient(50% 35% at 80% 95%, rgba(44, 114, 183, 0.03), transparent 70%),
    #F4F6F9;
}

/* Animated background — pipes, water flow, droplets, trucks */
.launcher-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  opacity: 0.4;          /* more visible mesh per user feedback */
}
.launcher-bg-svg {
  width: 100%;
  height: 100%;
  display: block;
}
/* All direct children of .launcher should sit above the animated bg */
.launcher > .launcher-brand,
.launcher > .launcher-personas,
.launcher > .launcher-foot {
  position: relative;
  z-index: 2;
}

/* === Organic curved pipe segments drawing themselves === */
.mesh-line {
  stroke-dasharray: 800;
  stroke-dashoffset: 800;
  animation: mesh-draw 14s ease-in-out infinite;
}
.mesh-line.organic {
  stroke-dasharray: 600;
  stroke-dashoffset: 600;
}
.mesh-line.senegal {
  stroke-dasharray: 3500;
  stroke-dashoffset: 3500;
  animation: senegal-draw 14s ease-in-out infinite;
}
.mesh-line.senegal-river {
  stroke-dasharray: 1200;
  stroke-dashoffset: 1200;
  animation: senegal-river 14s ease-in-out infinite;
}
.senegal-pin {
  opacity: 0;
  transform-origin: center;
  animation: pin-pulse 14s ease-in-out infinite;
}
@keyframes mesh-draw {
  0%   { stroke-dashoffset: 800; opacity: 0; }
  18%  { stroke-dashoffset: 0;   opacity: 0.85; }
  72%  { stroke-dashoffset: 0;   opacity: 0.85; }
  88%  { stroke-dashoffset: -800; opacity: 0.4; }
  100% { stroke-dashoffset: -800; opacity: 0; }
}
@keyframes senegal-draw {
  0%   { stroke-dashoffset: 3500; opacity: 0.1; }
  25%  { stroke-dashoffset: 0;    opacity: 0.95; }
  78%  { stroke-dashoffset: 0;    opacity: 0.95; }
  90%  { stroke-dashoffset: -3500; opacity: 0.4; }
  100% { stroke-dashoffset: -3500; opacity: 0; }
}
@keyframes senegal-river {
  0%   { stroke-dashoffset: 1200; opacity: 0; }
  35%  { stroke-dashoffset: 0;    opacity: 0.8; }
  78%  { stroke-dashoffset: 0;    opacity: 0.8; }
  90%  { stroke-dashoffset: -1200; opacity: 0.3; }
  100% { stroke-dashoffset: -1200; opacity: 0; }
}
@keyframes pin-pulse {
  0%, 22% { opacity: 0; transform: scale(0); }
  28%      { opacity: 1; transform: scale(1.3); }
  35%, 75% { opacity: 0.85; transform: scale(1); }
  88%      { opacity: 0.3; transform: scale(0.8); }
  100%     { opacity: 0; transform: scale(0); }
}

/* Joint rivets pulsing at intersections */
.mesh-rivet {
  opacity: 0;
  animation: rivet-pulse 14s ease-in-out infinite;
}
@keyframes rivet-pulse {
  0%, 18% { opacity: 0; transform: scale(0); }
  22%     { opacity: 0.8; transform: scale(1.4); }
  30%, 70% { opacity: 0.6; transform: scale(1); }
  85%      { opacity: 0.3; transform: scale(0.8); }
  100%     { opacity: 0; transform: scale(0); }
}

/* Water droplets at intersections — pulsing */
.mesh-drop {
  opacity: 0;
  transform-origin: center;
  animation: drop-pulse 4s ease-in-out infinite;
}
@keyframes drop-pulse {
  0%, 100% { opacity: 0; r: 4; }
  50%      { opacity: 0.8; r: 8; }
}

/* Title BROADCAST — concentric rings expanding from the title position */
.broadcast-ring {
  transform-origin: 800px 265px;
  opacity: 0;
  animation: broadcast-ring 3.6s ease-out infinite;
}
@keyframes broadcast-ring {
  0%   { transform: scale(0.2); opacity: 0; stroke-width: 3; }
  20%  { opacity: 0.85; }
  100% { transform: scale(7);   opacity: 0; stroke-width: 0.5; }
}

/* Title BROADCAST — directed lines emanating outward toward mission points */
.broadcast-line {
  stroke-dasharray: 1500;
  stroke-dashoffset: 1500;
  opacity: 0;
  animation: broadcast-line 4.2s ease-out infinite;
}
@keyframes broadcast-line {
  0%   { stroke-dashoffset: 1500; opacity: 0; }
  20%  { opacity: 0.95; }
  60%  { stroke-dashoffset: 0;    opacity: 0.95; }
  85%  { stroke-dashoffset: 0;    opacity: 0.5; }
  100% { stroke-dashoffset: -1500; opacity: 0; }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .broadcast-ring, .broadcast-line { animation: none !important; opacity: 0; }
}

/* "SUNU ONAS" letters drawn inside the mesh — runs once, then fades
   so the real H1 title can appear under the logo. */
.mesh-text {
  /* Lift this above the launcher-bg's 0.18 opacity so the in-mesh
     SUNU ONAS is clearly visible while drawing. */
  opacity: 1;
}
.text-draw {
  stroke-dasharray: 4500;
  stroke-dashoffset: 4500;
  animation: text-draw 5s cubic-bezier(0.5, 0, 0.5, 1) 0.5s 1 forwards;
  filter: drop-shadow(0 6px 14px rgba(44, 114, 183, 0.25));
}
@keyframes text-draw {
  0%   { stroke-dashoffset: 4500; opacity: 0; }
  10%  { stroke-dashoffset: 4500; opacity: 1; }
  60%  { stroke-dashoffset: 0;    opacity: 1; }
  78%  { stroke-dashoffset: 0;    opacity: 1; }
  100% { stroke-dashoffset: 0;    opacity: 0; }
}

/* Slow-motion when user prefers reduced motion */
@media (prefers-reduced-motion: reduce) {
  .mesh-line, .mesh-rivet, .mesh-drop, .text-draw,
  .launcher-logo {
    animation: none !important;
  }
  .mesh-line { stroke-dashoffset: 0; opacity: 0.3; }
  .text-draw { stroke-dashoffset: 0; opacity: 0.5; }
}
/* Hide body's dark aurora behind the launcher */
body:has(.launcher)::before,
body:has(.launcher)::after { display: none; }
.launcher-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  animation: fadeUp 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.launcher-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0;
  box-shadow: none;
  position: relative;
  animation: float 4s ease-in-out infinite;
}
.launcher-logo::after { content: none; }
.launcher-logo img { display: block; }
@keyframes float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-6px) rotate(-2deg); }
}
/* Static fallback if .launcher-title-anim not used */
.launcher-title {
  font-size: 52px;
  font-weight: 800;
  letter-spacing: -1.5px;
  line-height: 1;
  color: var(--navy-deep);
}

/* === Animated SVG title — sits directly under the logo.
   The mesh lines trace out "Sunu ONAS" in place (no big/centred phase).
   The slot reserves space so nothing overlaps. */
.launcher-title-anim {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 88px;
  margin: 0;
  padding: 0;
}
.title-svg {
  display: block;
  width: 380px;
  height: 88px;
  /* Simple fade + tiny slide up, no big/centred phase */
  animation: title-pop 0.6s ease-out 0.2s 1 both;
}
@keyframes title-pop {
  0%   { opacity: 0; transform: translateY(8px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* Sub-text appears AFTER the lines finish tracing the title */
.launcher-sub {
  opacity: 0;
  animation: sub-reveal 0.8s ease-out 4.5s 1 forwards;
}
@keyframes sub-reveal {
  0%   { opacity: 0; transform: translateY(8px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* Letters are drawn (stroke) then filled with color */
.title-text { dominant-baseline: middle; }
.title-piece {
  stroke-width: 3;
  stroke-dasharray: 1800;
  stroke-dashoffset: 1800;
  fill-opacity: 0;
  animation:
    title-piece-stroke 2.4s ease-out 0.4s 1 forwards,
    title-piece-fill   1.4s ease-out 2.6s 1 forwards;
}
@keyframes title-piece-stroke {
  0%   { stroke-dashoffset: 1800; }
  100% { stroke-dashoffset: 0; }
}
@keyframes title-piece-fill {
  0%   { fill-opacity: 0; stroke-width: 3; }
  100% { fill-opacity: 1; stroke-width: 0; }
}

/* === Admin footer — copyright + Apple/Google store buttons === */
.admin-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 28px;
  background: white;
  border-top: 1px solid var(--line);
  margin-top: auto; /* pushes the footer to the very bottom of the dashboard column */
  flex-wrap: wrap;
}

/* Make the dashboard a vertical flex column so margin-top:auto lifts
   the footer all the way to the bottom of the viewport. */
.dashboard-main {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* === Admin demand drawer (read-only) === */
/* Drawer = panneau interne sans flou ni voile sombre.
   Le clic sur la zone hors drawer ferme tout de même. */
.admin-drawer-overlay {
  position: fixed;
  inset: 0;
  background: transparent;
  z-index: 9000;
  display: flex;
  justify-content: flex-end;
  pointer-events: none;       /* la zone vide laisse passer les clics au dashboard */
  animation: drawerFadeIn 0.18s ease-out;
}

/* === [v113] PUSH DE L'ENVIRONNEMENT — le drawer pousse son contexte ===
   Quand un drawer admin est ouvert dans .dashboard-main, on pousse TOUT le
   contenu de .dashboard-main (KPIs, listes, header, footer) vers la GAUCHE
   pour libérer la place du drawer. Ainsi : zéro chevauchement, le drawer
   "déplace" l'environnement comme un panel persistant.

   Implémenté via :has() (Chrome 105+, Safari 15.4+, Firefox 121+ — tous
   modernes). Fallback gracieux : sans :has(), comportement classique
   (drawer en overlay).

   On exclut .admin-drawer-overlay (et .ai-drawer si présent) du décalage —
   ils restent en position fixed, c'est l'environnement non-overlay qui bouge. */
.dashboard-main { transition: padding-right 0.3s cubic-bezier(0.2, 0.9, 0.3, 1); }
.dashboard-main:has(> .admin-drawer-overlay) {
  /* [v320] La largeur réelle du drawer = min(480px, 100%). On ajoute 8px de marge.
     Mise à jour 560 → 480 après réduction de la largeur du drawer. */
  padding-right: min(488px, 100vw);
}
/* Sur petits écrans (< 1100px) : drawer prend toute la largeur, pas de push
   (sinon le contenu serait poussé hors de l'écran). */
@media (max-width: 1100px) {
  .dashboard-main:has(> .admin-drawer-overlay) {
    padding-right: 0;
  }
}
/* Bouton "danger" — utilisé par confirmDialog pour les suppressions.
   Rouge plein, hover plus foncé, focus ring contrasté. */
.btn.btn-danger {
  background: var(--red, #d04a3b);
  color: #fff;
  border: 1.5px solid transparent;
}
.btn.btn-danger:hover { background: #b13c2f; }
.btn.btn-danger:focus-visible {
  outline: 2px solid var(--red, #d04a3b);
  outline-offset: 2px;
}
.admin-drawer-overlay > .admin-drawer {
  pointer-events: auto;        /* mais le drawer reste interactif */
}
@keyframes drawerFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.admin-drawer {
  /* [v320] Largeur réduite 560 → 480px pour libérer plus de zone de fond
     (la liste/table reste lisible sous le drawer). */
  width: min(480px, 100%);
  height: 100%;
  background: white;
  display: flex;
  flex-direction: column;
  box-shadow: -20px 0 40px -12px rgba(7, 24, 45, 0.25);
  /* === ANIMATION D'ENTRÉE ===
     Slide-in depuis la droite via clip-path (PAS via transform/translateX).
     `transform` créerait un stacking context persistant sur le drawer parent,
     ce qui casserait `position: fixed` des overlays enfants : le drawer
     chauffeur enfant ne serait plus collé au bord droit du viewport mais
     positionné par rapport au parent. clip-path n'affecte pas le stacking
     context, donc on a le glissement visuel + la fixation correcte des
     enfants. animation-fill-mode: backwards garantit que la from-keyframe
     s'applique avant le démarrage (pas de flash visible). */
  animation: drawerSlideIn 0.28s cubic-bezier(0.2, 0.9, 0.3, 1) backwards;
  /* Transition sur margin-right + opacity (pas transform) pour le push-left
     et le dim quand un drawer enfant s'ouvre, sans stacking context. */
  transition: margin-right 0.3s cubic-bezier(0.2, 0.9, 0.3, 1),
              opacity      0.2s ease-out;
}
@keyframes drawerSlideIn {
  from { clip-path: inset(0 0 0 100%); opacity: 0; }
  to   { clip-path: inset(0 0 0 0);    opacity: 1; }
}
/* Rétro-compat — au cas où drawerSlide est référencé ailleurs (inerte) */
@keyframes drawerSlide {
  from, to { opacity: 1; }
}

/* === DRAWERS EMPILÉS — push-to-left ===
   Quand un drawer (enfant) s'ouvre à l'intérieur d'un autre drawer (parent),
   le parent glisse vers la GAUCHE pour faire de la place à l'enfant qui prend
   la position du right edge. Pattern Notion/Linear/macOS Finder push.

   IMPORTANT — utilise `margin-right` et non `transform`.
   `transform` casse le `position: fixed` des descendants (l'overlay enfant
   serait fixé par rapport au drawer parent translaté, pas au viewport), donc
   le drawer chauffeur ne resterait plus collé au bord droit de l'écran.
   `margin-right` pousse le parent dans son flex container `.admin-drawer-overlay`
   (justify-content: flex-end) sans créer de stacking context.

   Implémenté via :has() (Chrome 105+, Safari 15.4+, Firefox 121+ — tous les
   navigateurs modernes). Sur les anciens navigateurs : les drawers se
   superposent comme avant (fallback gracieux).

   NOTE : `:has()` ne peut PAS être imbriqué dans un autre `:has()` (interdit
   par le standard CSS). On gère donc seulement 2 niveaux d'empilement, ce qui
   couvre 99 % des cas (presta → SubManager → Modifier chauffeur/véhicule). */
.admin-drawer:has(.admin-drawer-overlay) {
  margin-right: var(--admin-drawer-shift, 540px);
  /* Indique visuellement que ce drawer est "en arrière-plan" :
     léger dim + ombre droite plus marquée + bordure gauche bleue (depth ribbon). */
  opacity: 0.94;
  box-shadow: -20px 0 40px -12px rgba(7, 24, 45, 0.25),
              20px 0 0 -8px rgba(7, 24, 45, 0.04),
              inset 4px 0 0 var(--brand, #1a73e8);
}
/* Sur petits écrans (< 1280px) : on désactive le push (pas la place),
   les drawers se superposent normalement comme avant. */
@media (max-width: 1280px) {
  .admin-drawer:has(.admin-drawer-overlay) {
    margin-right: 0;
    opacity: 1;
    box-shadow: -20px 0 40px -12px rgba(7, 24, 45, 0.25);
  }
}
.admin-drawer-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 20px 22px;
  border-bottom: 1px solid var(--line);
}
.admin-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: 18px 22px 22px;
}
.admin-drawer-section-lbl {
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 8px;
}
.admin-copy {
  font-size: 12px;
  color: var(--ink-3);
}
.admin-copy strong { color: var(--navy-deep); font-weight: 700; }
.admin-stores {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.admin-stores-lbl {
  font-size: 11px;
  color: var(--ink-3);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-right: 4px;
}
.store-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: #1B1B1B;
  color: white;
  padding: 8px 14px;
  border-radius: 10px;
  text-decoration: none;
  transition: all 0.18s ease;
  border: 1px solid #2a2a2a;
}
.store-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 20px -6px rgba(0, 0, 0, 0.35);
  background: #000;
}
.store-btn svg { flex: 0 0 auto; }
.store-btn div {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}
.store-btn small {
  font-size: 9px;
  font-weight: 500;
  opacity: 0.8;
  letter-spacing: 0.3px;
}
.store-btn strong {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.2px;
}

/* Larger variant for the landing page */
.store-btn.lg {
  padding: 10px 18px;
  border-radius: 12px;
}
.store-btn.lg small { font-size: 10px; }
.store-btn.lg strong { font-size: 16px; }

/* [v115] Bouton principal "Telecharger APK Android" - vert ONAS, pulse pour attirer le clic */
.store-btn-primary {
  background: linear-gradient(135deg, #2EB872 0%, #1F9D5C 100%) !important;
  border-color: #2EB872 !important;
  box-shadow: 0 6px 18px -4px rgba(46, 184, 114, 0.45);
  animation: storeBtnPulse 2.4s ease-in-out infinite;
}
.store-btn-primary:hover {
  background: linear-gradient(135deg, #1F9D5C 0%, #2EB872 100%) !important;
  box-shadow: 0 10px 24px -6px rgba(46, 184, 114, 0.6);
  transform: translateY(-2px);
}
@keyframes storeBtnPulse {
  0%, 100% { box-shadow: 0 6px 18px -4px rgba(46, 184, 114, 0.45); }
  50%      { box-shadow: 0 8px 22px -4px rgba(46, 184, 114, 0.75); }
}

/* [v115] Boutons stores "Bientot" - grise, sans pulse, cursor not-allowed */
.store-btn-soon {
  opacity: 0.55;
  cursor: not-allowed !important;
  background: #333 !important;
}
.store-btn-soon:hover {
  transform: none !important;
  box-shadow: none !important;
  background: #2a2a2a !important;
}

/* === Landing page download buttons block === */
.launcher-stores {
  position: relative;
  z-index: 3;
  margin: 32px auto 0;
  text-align: center;
  max-width: 720px;
  padding: 0 20px;
}
.launcher-stores-lbl {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--ink-3);
  margin-bottom: 14px;
}
.launcher-stores-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}
.launcher-stores-hint {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 14px;
}
.launcher-stores-hint strong {
  color: var(--navy-deep);
  font-weight: 700;
}

/* === Hover snake — wavy mesh that travels from the hovered persona
   card up to the SUNU ONAS title. Floats freely (not glued to either edge). */
.hover-snakes {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  pointer-events: none;
  overflow: visible;
}
.hover-snakes path {
  opacity: 0;
  filter: drop-shadow(0 0 6px currentColor);
  transition: opacity 0.5s ease;
}
/* When a persona card is hovered, the matching snake comes alive */
.launcher:has(.persona-card.usager:hover) .snake-usager,
.launcher:has(.persona-card.presta:hover) .snake-presta,
.launcher:has(.persona-card.admin:hover)  .snake-admin {
  opacity: 0.85;
  animation: snake-slide 6s linear infinite;
}
@keyframes snake-slide {
  from { stroke-dashoffset: 0; }
  to   { stroke-dashoffset: -260; }
}
@media (prefers-reduced-motion: reduce) {
  .hover-snakes path { animation: none !important; opacity: 0; }
}

/* Mesh overlay — dashes flowing along the letter outlines forever */
.title-mesh {
  stroke-width: 2.5;
  stroke-dasharray: 14 18;
  fill: none;
  /* Hidden while letters are drawing/filling, then flows forever */
  opacity: 0;
  animation:
    title-mesh-show 0.6s ease-out 4s 1 forwards,
    title-mesh-flow 5s linear 4s infinite;
}
@keyframes title-mesh-show {
  from { opacity: 0; }
  to   { opacity: 0.85; }
}
@keyframes title-mesh-flow {
  from { stroke-dashoffset: 0; }
  to   { stroke-dashoffset: -640; }
}
.launcher-title span {
  background: linear-gradient(135deg, var(--orange) 0%, #ff8a5c 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.launcher-tag {
  display: inline-block;
  padding: 0;
  background: none;
  border: none;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 2.4px;
  text-transform: uppercase;
  color: var(--ink-3);
}
.launcher-sub {
  font-size: 17px;
  color: var(--ink-2);
  max-width: 600px;
  line-height: 1.6;
}
.launcher-personas {
  display: grid;
  /* [v155] auto-fit responsive : 1/2/3 colonnes selon largeur dispo.
     Le min(240px, 100%) évite tout débordement sur mobiles < 280px. */
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: 20px;
  max-width: 980px;
  width: 100%;
  margin-top: 12px;
  animation: fadeUp 1s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  animation-delay: 0.15s;
}
.persona-card {
  background: white;
  border: 1px solid rgba(226, 232, 240, 0.95);
  border-radius: 22px;
  padding: 28px 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  text-align: left;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
  position: relative;
  overflow: hidden;
  box-shadow: 0 6px 18px -8px rgba(15, 37, 64, 0.08);
}
.persona-card::after {
  content: "";
  position: absolute;
  top: -60%; right: -30%;
  width: 220px; height: 220px;
  border-radius: 50%;
  opacity: 0;
  transition: all 0.4s ease;
  pointer-events: none;
  filter: blur(40px);
}
.persona-card.usager::after { background: rgba(232, 90, 44, 0.25); }
.persona-card.presta::after { background: rgba(46, 184, 114, 0.22); }
.persona-card.admin::after  { background: rgba(91, 145, 215, 0.25); }
.persona-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 24px 50px -16px rgba(15, 37, 64, 0.18);
}
.persona-card.usager:hover { border-color: rgba(232, 90, 44, 0.4); }
.persona-card.presta:hover { border-color: rgba(46, 184, 114, 0.4); }
.persona-card.admin:hover  { border-color: rgba(91, 145, 215, 0.4); }
.persona-card:hover::after  { opacity: 0.6; top: -40%; }
.persona-card .ic {
  width: 56px; height: 56px;
  border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  color: white;
  font-size: 22px;
  position: relative;
  z-index: 1;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.persona-card.usager .ic { background: linear-gradient(135deg, var(--orange) 0%, #c84616 100%); box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), 0 12px 28px -8px rgba(232,90,44,0.5); }
.persona-card.presta .ic { background: linear-gradient(135deg, var(--green) 0%, #1d8e54 100%); box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), 0 12px 28px -8px rgba(46,184,114,0.45); }
.persona-card.admin .ic  { background: linear-gradient(135deg, #4a78b6 0%, var(--navy-deep) 100%); box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), 0 12px 28px -8px rgba(15,37,64,0.6); }
.persona-card h3 {
  font-size: 20px;
  font-weight: 800;
  color: var(--navy-deep);
  letter-spacing: -0.4px;
  position: relative;
  z-index: 1;
}
.persona-card p {
  font-size: 13.5px;
  color: var(--ink-2);
  line-height: 1.6;
  position: relative;
  z-index: 1;
}
.persona-card ul {
  list-style: none;
  padding: 0;
  margin: 6px 0 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: relative;
  z-index: 1;
}
.persona-card li {
  font-size: 12.5px;
  color: var(--ink-2);
  display: flex;
  align-items: center;
  gap: 10px;
}
.persona-card li::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  flex: 0 0 auto;
  box-shadow: 0 0 0 3px rgba(15, 37, 64, 0.04);
}
.persona-card.usager li::before { background: var(--orange); }
.persona-card.presta li::before { background: var(--green); }
.persona-card.admin li::before  { background: #5b91d7; }
.persona-card .open {
  margin-top: 12px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  font-weight: 700;
  position: relative;
  z-index: 1;
  transition: gap 0.3s;
}
.persona-card.usager .open { color: var(--orange); }
.persona-card.presta .open { color: #4cd494; }
.persona-card.admin  .open { color: #7baee6; }
.persona-card:hover .open { gap: 12px; }

/* Footer hint on launcher */
.launcher-foot {
  position: fixed;
  bottom: 22px; left: 50%;
  transform: translateX(-50%);
  font-size: 11px;
  color: rgba(255, 255, 255, 0.42);
  letter-spacing: 0.5px;
  z-index: 1;
}

/* ===== Persona-bar (in-app) ===== */
.persona-bar {
  position: fixed;
  top: 18px;
  /* Centré horizontalement */
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 4px;
  z-index: 200;
  background: rgba(15, 37, 64, 0.7);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  padding: 5px;
  box-shadow: 0 16px 40px -10px rgba(0, 0, 0, 0.5);
}
.persona-bar button {
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.7);
  padding: 8px 16px;
  border-radius: 999px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: all 0.2s ease;
}
.persona-bar button:hover { color: white; background: rgba(255, 255, 255, 0.06); }
.persona-bar button.active {
  background: linear-gradient(135deg, var(--orange) 0%, #c84616 100%);
  color: white;
  box-shadow: 0 4px 14px -2px rgba(232, 90, 44, 0.55);
}
.persona-bar .home-btn {
  color: rgba(255, 255, 255, 0.55);
  padding: 8px 12px;
}
.persona-bar .home-btn:hover { color: white; }

/* [v348] PersonaBar déplaçable :
   - cursor grab sur la zone neutre (entre les boutons)
   - grip ⋮⋮ à gauche pour signaler que c'est déplaçable
   - active → cursor grabbing
   - position custom → on retire la transition pour rester réactif au drag */
.persona-bar {
  cursor: grab;
  transition: top .25s ease, left .25s ease, box-shadow .2s ease;
}
.persona-bar:active { cursor: grabbing; }
.persona-bar.is-dragged { transition: none; box-shadow: 0 20px 50px -8px rgba(0,0,0,0.55); }
.persona-bar-grip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px 0 8px;
  color: rgba(255,255,255,0.32);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -2px;
  user-select: none;
  cursor: grab;
  pointer-events: none; /* le drag se déclenche sur le parent */
}
.persona-bar:hover .persona-bar-grip { color: rgba(255,255,255,0.6); }

/* ===== Mobile stage ===== */
.mobile-stage {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 80px 20px 96px;
  position: relative;
  z-index: 1;
}
.mobile-stage .phone {
  flex: 0 0 auto;
  box-shadow:
    0 40px 80px -20px rgba(0, 0, 0, 0.55),
    0 16px 32px -12px rgba(232, 90, 44, 0.18),
    inset 0 0 0 2px #1f1f1f;
  animation: fadeUp 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

/* Floating dev controls (advance request, etc.) */
.dev-controls {
  position: fixed;
  bottom: 22px; left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
  z-index: 200;
  flex-wrap: wrap;
  justify-content: center;
  max-width: 92vw;
}
.dev-controls .stage-btn {
  background: rgba(15, 37, 64, 0.7);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: white;
  padding: 9px 16px;
  border-radius: 999px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
  box-shadow: 0 8px 20px -6px rgba(0, 0, 0, 0.4);
}
.dev-controls .stage-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  transform: translateY(-1px);
  box-shadow: 0 12px 24px -8px rgba(0, 0, 0, 0.45);
}

/* ============================================================
   AUTH SCREENS — Admin & Prestataire login
   Affichés après l'animation splash, gating l'entrée à la console
   admin ou à l'app prestataire tant qu'aucun token n'est présent.
   ============================================================ */
.auth-stage {
  position: fixed; inset: 0;
  z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: linear-gradient(135deg, #0F2540 0%, #1B3A5C 50%, #2C4F77 100%);
  animation: fadeIn 0.35s ease both;
  overflow-y: auto;
}
.auth-stage.presta-auth {
  background: linear-gradient(135deg, #1B3A5C 0%, #E85A2C 100%);
}

/* Pipe-mesh animé en background des écrans de login */
.auth-bg {
  position: absolute !important;
  inset: 0;
  z-index: 0 !important;
  opacity: 0.45;
  pointer-events: none;
}
.auth-bg .launcher-bg-svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* La card doit passer au-dessus du fond animé */
.auth-stage .auth-card {
  position: relative;
  z-index: 1;
}

/* Logo ONAS sur les écrans de login — PNG officiel uniquement */
.auth-real-logo {
  margin: 0 auto 14px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* === Animation "Sunu ONAS" mini-version pour les écrans de login === */
.auth-title-anim {
  height: 56px !important;
  margin: 12px 0 4px !important;     /* spacer au-dessus pour décoller du logo */
  padding: 0 !important;
  width: 100% !important;
  display: flex !important;
  justify-content: center !important;
  align-items: center !important;
  overflow: visible !important;
}
.auth-title-svg {
  width: 240px !important;          /* plus large pour ne pas couper "ONAS" */
  height: 56px !important;
  max-width: 100% !important;
  display: block !important;
  overflow: visible !important;
}

/* Admin et Prestataire utilisent désormais le MÊME gradient bleu+orange
   (variant="color"). Plus de surcharge blanche sur l'admin. */

/* Rôle (admin / prestataire) sous le titre animé */
.auth-brand-role {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-top: 8px;
  padding: 4px 12px;
  border-radius: 999px;
  display: inline-block;
  animation: authRoleFade 0.6s ease-out 4.2s both;
}
.auth-brand-role.admin {
  background: rgba(255,255,255,0.12);
  color: rgba(255,255,255,0.95);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,0.18);
}
.auth-brand-role.presta {
  background: rgba(232,90,44,0.25);
  color: white;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,0.18);
}
@keyframes authRoleFade {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Brand container = colonne propre (logo, titre, role) sans overlap */
.auth-stage .auth-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  margin-bottom: 18px;
  text-align: center;
}

/* (style logo géré dans la règle principale plus haut — float + halo) */

/* Mobile : version compacte mais on conserve le halo */
@media (max-width: 480px) {
  .auth-title-svg { width: 200px !important; height: 48px !important; }
  .auth-title-anim { height: 48px !important; margin: 10px 0 4px !important; }
  .auth-real-logo img { width: 120px !important; height: auto !important; }
  .auth-stage .auth-brand { margin-bottom: 14px; }
}
.auth-card {
  width: 100%;
  max-width: 460px;
  background: transparent;
  border-radius: 0;
  padding: 24px 22px 24px;
  box-shadow: none;
  animation: authPop 0.5s cubic-bezier(0.2, 0.9, 0.3, 1) both;
}
@keyframes authPop {
  from { opacity: 0; transform: translateY(20px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.auth-brand {
  text-align: center;
  margin-bottom: 24px;
}
.auth-logo {
  width: 72px; height: 72px;
  border-radius: 18px;
  background: linear-gradient(135deg, #1B3A5C, #2C4F77);
  color: white;
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 14px;
  box-shadow: 0 12px 30px -8px rgba(27,58,92,0.4);
}
.auth-logo.presta {
  background: linear-gradient(135deg, #E85A2C, #F39236);
  box-shadow: 0 12px 30px -8px rgba(232,90,44,0.45);
}
.auth-brand-name {
  font-size: 22px;
  font-weight: 800;
  color: var(--navy-deep);
  letter-spacing: -0.2px;
}
.auth-brand-sub {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 4px;
  font-weight: 500;
}
.auth-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* Apparaît à mesure que la chrono SunuOnas se trace (synchronisé) */
}
/* Champs et bouton apparaissent en cascade pendant que "Sunu ONAS"
   se dessine (stroke 0.4s → 2.8s). Total : entre 0.6s et 3.4s. */
.auth-form .auth-field,
.auth-form .auth-submit,
.auth-form .auth-error,
.auth-form .auth-help {
  opacity: 0;
  transform: translateY(8px);
  animation: authFieldFade 0.5s ease-out forwards;
}
.auth-form .auth-field:nth-child(1) { animation-delay: 0.6s; }
.auth-form .auth-field:nth-child(2) { animation-delay: 1.2s; }
.auth-form .auth-error            { animation-delay: 1.8s; }
.auth-form .auth-submit           { animation-delay: 1.8s; }
.auth-form .auth-help             { animation-delay: 2.4s; }
@keyframes authFieldFade {
  to { opacity: 1; transform: translateY(0); }
}
.auth-foot {
  opacity: 0;
  animation: authFieldFade 0.5s ease-out 3.0s forwards;
}
.auth-field label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  color: rgba(255,255,255,0.75);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 6px;
}
.auth-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
  background: transparent;
  border: 1.5px solid rgba(255,255,255,0.25);
  border-radius: 12px;
  padding: 12px 14px;
  gap: 10px;
  transition: all 0.18s ease;
}
.auth-input-wrap:focus-within {
  background: transparent;
  border-color: var(--orange);
  box-shadow: 0 0 0 4px rgba(232,90,44,0.18);
}
.auth-input-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  opacity: 0.85;
  flex: 0 0 auto;
}
.auth-input-icon svg {
  display: block;
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: none;
}
.auth-input-wrap:focus-within .auth-input-icon {
  opacity: 1;
}
.auth-prefix {
  display: inline-flex;
  align-items: center;
  color: #ffffff;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.2px;
  flex: 0 0 auto;
  border-right: 1px solid rgba(255,255,255,0.25);
  padding-right: 10px;
}
.auth-input-wrap input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  font-size: 14px;
  font-family: inherit;
  color: white;
  font-weight: 600;
}
.auth-input-wrap input::placeholder {
  color: rgba(255,255,255,0.45);
  font-weight: 400;
}
/* Empêche le navigateur d'ajouter un fond clair lors de l'autofill */
.auth-input-wrap input:-webkit-autofill,
.auth-input-wrap input:-webkit-autofill:hover,
.auth-input-wrap input:-webkit-autofill:focus,
.auth-input-wrap input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px transparent inset !important;
  box-shadow: 0 0 0 1000px transparent inset !important;
  -webkit-text-fill-color: white !important;
  caret-color: white !important;
  background-clip: content-box !important;
  transition: background-color 9999s ease-in-out 0s;
}
.auth-eye {
  background: none;
  border: none;
  cursor: pointer;
  padding: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  opacity: 0.7;
  transition: opacity 0.18s ease;
}
.auth-eye svg {
  display: block;
  stroke: currentColor;
  fill: none;
}
.auth-eye:hover { opacity: 1; }
.auth-eye:focus-visible {
  opacity: 1;
  outline: 2px solid rgba(255,255,255,0.35);
  outline-offset: 2px;
  border-radius: 4px;
}
.auth-error {
  background: var(--red-soft);
  color: var(--red);
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid rgba(217,67,76,0.2);
}
.auth-submit {
  margin-top: 6px;
  padding: 14px 18px;
  background: linear-gradient(135deg, #E85A2C, #F39236);
  color: white;
  border: none;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
  letter-spacing: 0.3px;
  transition: all 0.18s ease;
  box-shadow: 0 8px 22px -4px rgba(232,90,44,0.45);
}
.auth-submit:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 14px 28px -4px rgba(232,90,44,0.55);
  filter: brightness(1.05);
}
.auth-submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.auth-submit.presta {
  background: linear-gradient(135deg, #E85A2C, #F39236);
  box-shadow: 0 8px 18px -4px rgba(232,90,44,0.35);
}
.auth-submit.presta:hover:not(:disabled) {
  box-shadow: 0 12px 24px -4px rgba(232,90,44,0.5);
}
.auth-help {
  text-align: center;
  font-size: 12px;
  color: rgba(255,255,255,0.7);
  margin-top: 8px;
}
.auth-help a {
  color: #FFA770;
  text-decoration: none;
  font-weight: 700;
  margin-left: 4px;
}
.auth-help a:hover { text-decoration: underline; color: #FFC9A8; }
.auth-foot {
  text-align: center;
  font-size: 10px;
  color: rgba(255,255,255,0.45);
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid rgba(255,255,255,0.12);
}
.auth-eye {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 16px;
  padding: 2px;
  opacity: 0.7;
  filter: brightness(1.5);
}
.auth-eye:hover { opacity: 1; }

/* Mobile : carte plus compacte */
@media (max-width: 480px) {
  .auth-stage { padding: 14px; }
  .auth-card { padding: 24px 20px 18px; border-radius: 14px; }
  .auth-logo { width: 60px; height: 60px; border-radius: 14px; }
  .auth-brand-name { font-size: 19px; }
}

/* ===== Admin desktop wrapper — fullscreen ===== */
.admin-stage {
  position: fixed;
  inset: 0;
  background: var(--bg);
  z-index: 1;
  overflow: hidden;
}
.admin-stage .desktop {
  width: 100vw;
  height: 100vh;
  border-radius: 0;
  border: none;
  box-shadow: none;
  display: flex;
  flex-direction: column;
  /* Animation : seulement opacity. Plus de translateY car
     `transform` persistant via animation-fill-mode: both crée un
     containing block qui casse `position: fixed` des drawers descendants. */
  animation: fadeIn 0.4s ease both;
}
@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
.admin-stage .desktop-bar {
  flex: 0 0 auto;
}
.admin-stage .desktop-body {
  flex: 1 1 0;
  height: auto;
  min-height: 0;
}
.admin-stage .sidebar {
  height: 100%;
  overflow-y: auto;
}
.admin-stage .dashboard-main {
  height: 100%;
}

/* ===== Loader (legacy fallback) ===== */
.boot {
  position: fixed; inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--landing-bg);
  color: white;
  font-size: 14px;
  letter-spacing: 0.4px;
}
.boot .ring {
  width: 36px; height: 36px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.18);
  border-top-color: var(--orange);
  animation: spin 0.9s linear infinite;
  margin-bottom: 14px;
}
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* === [v113] Bannière marketing usager — animations === */
@keyframes bannerFadeUp {
  from { opacity: 0; transform: translateY(12px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* [v480] Banner = 1 seul contenant, marges 0. La couleur de fond vient
   de l'inline style (currentBanner.bgColor defini par l'admin). */
.usager-banner {
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  margin: 0 !important;
  border-radius: 0 !important;
  overflow: hidden;
  box-shadow: none !important;
}
.usager-banner > img {
  border-radius: 0 !important;
  box-shadow: none !important;
  margin: 0 !important;
  display: block;
}
.usager-banner:active { transform: scale(0.98); }
/* Tablet+ : header + banner sur la meme ligne via CSS grid sur .usager-page */
@media (min-width: 768px) {
  .mobile-stage-fullscreen .usager-page {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto 1fr;
    column-gap: 0;
  }
  .mobile-stage-fullscreen .usager-page > .usager-header {
    grid-column: 1;
    grid-row: 1;
    margin-right: 6px !important;
  }
  .mobile-stage-fullscreen .usager-page > .presta-scroll {
    grid-column: 2;
    grid-row: 1 / span 2;
    padding-top: calc(8px + env(safe-area-inset-top, 0px));
  }
  .mobile-stage-fullscreen .usager-page > .presta-scroll > .usager-banner:first-child,
  .mobile-stage-fullscreen .usager-page > .presta-scroll > .usager-hero + .usager-banner {
    margin-left: 6px !important;
  }
  /* Si pas de banner en premier (hero present) : le hero prend la place du banner */
  .mobile-stage-fullscreen .usager-page > .presta-scroll > .usager-hero {
    margin-left: 6px !important;
  }
}
.usager-banner-shine {
  position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,0.18) 45%, rgba(255,255,255,0.08) 55%, transparent 70%);
  animation: bannerShine 4s ease-in-out infinite;
  pointer-events: none;
}
@keyframes bannerShine {
  0%   { transform: translateX(-100%); }
  60%  { transform: translateX(120%); }
  100% { transform: translateX(120%); }
}
.usager-banner-icon {
  animation: bannerIconPulse 3.5s ease-in-out infinite;
}
@keyframes bannerIconPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.08); }
}

/* === [v113] Animations organigramme workflow PrestationsPage === */
@keyframes flowPhaseSlide {
  from { opacity: 0; transform: translateY(-12px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes flowStepFade {
  from { opacity: 0; transform: translateX(-10px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes flowArrowPulse {
  0%, 100% { transform: translateY(0); opacity: 0.7; }
  50%      { transform: translateY(4px); opacity: 1; }
}
@keyframes flowFinalPop {
  0%   { opacity: 0; transform: scale(0.8); }
  60%  { opacity: 1; transform: scale(1.05); }
  100% { opacity: 1; transform: scale(1); }
}

/* [v113] Maillage SVG sur le splash boot — opacity boostée car le fond
   est dark navy (vs launcher en bleu clair). Le mesh existant utilise
   opacity:0.4 → 0.6 sur le boot pour rester nettement visible. */
.boot-v2 .launcher-bg.boot-bg-mesh {
  opacity: 0.55;
  z-index: 0;
}
.boot-v2 .launcher-bg.boot-bg-mesh .mesh-line.organic {
  /* Strokes plus claires sur fond sombre */
  filter: brightness(1.2);
}
.boot-v2 .launcher-bg.boot-bg-mesh .mesh-rivet {
  fill: rgba(255, 255, 255, 0.7);
}

/* ===== Boot v2 — splash screen console admin v113 =====
   Logo ONAS + fond animé (grille tactique + halo + bulles) + jauge
   de progression avec messages d'état. Pure CSS animations, zero JS overhead. */
.boot-v2 {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #07182d 0%, #0f2540 35%, #1B3A5C 70%, #234876 100%);
  overflow: hidden;
  font-family: 'Inter', system-ui, sans-serif;
  color: white;
}
/* Grille tactique qui dérive lentement (style Leaflet dark) */
.boot-bg-grid {
  position: absolute; inset: -40px;
  background-image:
    linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
  background-size: 40px 40px;
  animation: bootGridDrift 18s linear infinite;
  opacity: 0.7;
}
@keyframes bootGridDrift {
  from { transform: translate(0, 0); }
  to   { transform: translate(40px, 40px); }
}
/* Halo orange ONAS pulsant centré */
.boot-bg-glow {
  position: absolute;
  width: 80vmin; height: 80vmin;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle at center, rgba(232, 90, 44, 0.22) 0%, rgba(232, 90, 44, 0.08) 30%, transparent 60%);
  animation: bootGlowPulse 3.5s ease-in-out infinite;
  filter: blur(20px);
  pointer-events: none;
}
@keyframes bootGlowPulse {
  0%, 100% { opacity: 0.6; transform: translate(-50%, -50%) scale(1); }
  50%      { opacity: 1;   transform: translate(-50%, -50%) scale(1.18); }
}
/* Bulles montantes (style fluide assainissement / eau) */
.boot-bg-bubbles {
  position: absolute; inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.boot-bubble {
  position: absolute;
  bottom: -30px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.4), rgba(232, 90, 44, 0.15));
  border: 1px solid rgba(255,255,255,0.15);
  animation: bootBubbleRise linear infinite;
  opacity: 0;
}
@keyframes bootBubbleRise {
  0%   { transform: translateY(0) scale(0.5); opacity: 0; }
  10%  { opacity: 0.5; }
  90%  { opacity: 0.4; }
  100% { transform: translateY(-110vh) scale(1.3); opacity: 0; }
}
/* Contenu central (logo + titre + jauge) */
.boot-content {
  position: relative;
  z-index: 2;
  text-align: center;
  max-width: 480px;
  width: 90%;
  padding: 40px 30px;
  animation: bootFadeUp 0.7s cubic-bezier(0.2, 0.9, 0.3, 1) backwards;
}
@keyframes bootFadeUp {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 1; transform: translateY(0); }
}
.boot-logo {
  margin-bottom: 26px;
  display: flex; justify-content: center;
  align-items: center;
  /* [v113] Pas de fond — logo affiché directement sur le splash navy.
     On garde juste un glow orange ambiant pour donner du relief. */
  background: transparent;
  filter: drop-shadow(0 8px 24px rgba(232, 90, 44, 0.45)) drop-shadow(0 0 18px rgba(255, 255, 255, 0.12));
  animation: bootLogoFloat 3s ease-in-out infinite;
}
.boot-logo svg, .boot-logo img { display: block; }
@keyframes bootLogoFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
.boot-title {
  font-size: 28px;
  font-weight: 800;
  margin: 0 0 6px 0;
  letter-spacing: -0.5px;
  background: linear-gradient(90deg, #ffffff 0%, #ffd9c8 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}
.boot-subtitle {
  font-size: 11px;
  color: rgba(255,255,255,0.55);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1.8px;
  margin-bottom: 38px;
}
.boot-progress-wrap {
  width: 100%;
  max-width: 380px;
  margin: 0 auto;
}
.boot-progress-track {
  width: 100%;
  height: 6px;
  background: rgba(255,255,255,0.1);
  border-radius: 999px;
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.3);
}
.boot-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #E85A2C 0%, #F4B740 100%);
  border-radius: 999px;
  transition: width 0.4s cubic-bezier(0.2, 0.9, 0.3, 1);
  position: relative;
  overflow: hidden;
  box-shadow: 0 0 12px rgba(232, 90, 44, 0.6), 0 0 24px rgba(232, 90, 44, 0.3);
}
.boot-progress-shine {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.5) 50%, transparent 100%);
  animation: bootShine 1.4s linear infinite;
}
@keyframes bootShine {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}
.boot-progress-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 12px;
  font-size: 11px;
  font-family: 'JetBrains Mono', 'Consolas', monospace;
  color: rgba(255,255,255,0.75);
  min-height: 18px;
}
.boot-progress-msg {
  flex: 1;
  text-align: left;
  letter-spacing: 0.3px;
  animation: bootMsgFade 0.4s ease-out;
}
@keyframes bootMsgFade {
  from { opacity: 0; transform: translateX(-4px); }
  to   { opacity: 1; transform: translateX(0); }
}
.boot-progress-pct {
  font-weight: 800;
  color: #ffd9c8;
  letter-spacing: 0.5px;
  margin-left: 12px;
}
/* Timeline horizontale 6 étapes (dots) */
.boot-steps {
  display: flex; justify-content: space-between;
  margin-top: 20px;
  padding: 0 4px;
}
.boot-step {
  display: flex; flex-direction: column; align-items: center;
  flex: 1;
}
.boot-step-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: rgba(255,255,255,0.18);
  border: 1px solid rgba(255,255,255,0.25);
  transition: all 0.3s ease;
}
.boot-step.active .boot-step-dot {
  background: #F4B740;
  box-shadow: 0 0 8px rgba(244, 183, 64, 0.7);
  animation: bootStepPulse 1s ease-in-out infinite;
}
.boot-step.done .boot-step-dot {
  background: #2EB872;
  border-color: #2EB872;
  box-shadow: 0 0 6px rgba(46, 184, 114, 0.5);
}
@keyframes bootStepPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.4); }
}
.boot-version {
  margin-top: 36px;
  font-size: 10px;
  color: rgba(255,255,255,0.35);
  letter-spacing: 1px;
  font-family: 'JetBrains Mono', monospace;
  text-transform: uppercase;
}

/* ============================================================
   Polish layer — overrides on existing app-styles + hifi-styles
   to lift visual hierarchy across all screens.
   ============================================================ */

/* Phone bezel: a touch more refined */
.phone {
  border-radius: 50px;
}
.phone-screen {
  border-radius: 42px;
}

/* Service tiles (used in HomeScreen) — slight depth + better hover */
.svc-tile {
  background: linear-gradient(180deg, #ffffff 0%, #fafbfd 100%);
  border-radius: 18px;
  padding: 16px;
  border: 1px solid var(--line);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.6) inset,
    0 1px 2px rgba(15, 37, 64, 0.04);
  transition: all 0.2s ease;
}
.svc-tile:hover {
  transform: translateY(-2px);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.6) inset,
    0 8px 24px -8px rgba(15, 37, 64, 0.18);
  border-color: rgba(232, 90, 44, 0.25);
}
.svc-icon {
  width: 46px; height: 46px;
  border-radius: 14px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.25),
    0 6px 14px -6px currentColor;
}

/* Hero cards: more depth */
.hero-card {
  background: linear-gradient(135deg, var(--navy) 0%, var(--navy-2) 60%, var(--navy-deep) 100%);
  box-shadow:
    var(--navy-glow),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

/* Bottom nav: refined glass + active state */
.bottom-nav {
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-top: 1px solid rgba(226, 232, 240, 0.8);
  box-shadow: 0 -10px 30px -8px rgba(15, 37, 64, 0.08);
}

/* Buttons: slightly more depth */
.btn {
  transition: all 0.18s cubic-bezier(0.2, 0.8, 0.2, 1);
  letter-spacing: 0.1px;
}
.btn-primary {
  box-shadow: var(--navy-glow), inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
.btn-primary:hover { transform: translateY(-1px); }
.btn-accent, .btn-orange {
  background: linear-gradient(135deg, var(--orange) 0%, #c84616 100%) !important;
  box-shadow: var(--orange-glow), inset 0 1px 0 rgba(255, 255, 255, 0.18) !important;
}
.btn-success {
  background: linear-gradient(135deg, var(--green) 0%, #1d8e54 100%) !important;
  box-shadow: 0 18px 40px -10px rgba(46, 184, 114, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.18) !important;
}

/* Cards across all screens: subtle gradient */
.card {
  background: linear-gradient(180deg, #ffffff 0%, #fcfdff 100%);
  border: 1px solid rgba(226, 232, 240, 0.8);
  box-shadow: 0 1px 3px rgba(15, 37, 64, 0.04);
  transition: all 0.18s ease;
}

/* Badges: better padding/typography */
.badge {
  padding: 5px 11px;
  font-weight: 700;
  letter-spacing: 0.2px;
}

/* Stepper: better active state */
.stepper-h .st.active,
.stepper .st.active {
  box-shadow: 0 0 0 4px rgba(27, 58, 92, 0.14), 0 6px 14px -4px rgba(27, 58, 92, 0.5);
}

/* Toggle: smoother shadow */
.toggle.on {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.18), 0 4px 12px -4px rgba(46, 184, 114, 0.5);
}

/* ============================================================
   Admin desktop polish
   ============================================================ */

/* Sidebar: gradient + better separation */
.sidebar {
  background: linear-gradient(180deg, var(--navy-deep) 0%, #07182d 100%);
  border-right: 1px solid rgba(255, 255, 255, 0.04);
}
.sidebar .menu-it {
  position: relative;
  transition: all 0.2s ease;
}
.sidebar .menu-it.active {
  background: linear-gradient(90deg, rgba(232, 90, 44, 0.18) 0%, rgba(232, 90, 44, 0.04) 100%);
  border-left: 3px solid var(--orange);
  padding-left: 7px;
}
.sidebar .menu-it.active::before {
  content: "";
  position: absolute;
  left: -10px; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 18px;
  border-radius: 0 2px 2px 0;
  background: var(--orange);
  box-shadow: 0 0 12px var(--orange);
}
.sidebar .menu-it:not(.active):hover {
  background: rgba(255, 255, 255, 0.04);
  transform: translateX(2px);
}

/* KPI cards in admin: subtle gradient */
.kpi-card {
  background: linear-gradient(180deg, #ffffff 0%, #fafbfd 100%);
  border: 1px solid rgba(226, 232, 240, 0.85);
  box-shadow: 0 1px 3px rgba(15, 37, 64, 0.04);
  transition: all 0.2s ease;
  position: relative;
  overflow: hidden;
}
.kpi-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--orange), var(--navy));
  opacity: 0;
  transition: opacity 0.3s;
}
.kpi-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 28px -10px rgba(15, 37, 64, 0.18);
}
.kpi-card:hover::before { opacity: 1; }

/* Chart bars: smoother gradient */
.chart-h .b {
  background: linear-gradient(180deg, #2c5380 0%, var(--navy) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.chart-h .b.alt {
  background: linear-gradient(180deg, #ff8a5c 0%, var(--orange) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 6px 14px -4px rgba(232, 90, 44, 0.4);
}

/* Donut: stronger shadow */
.donut-h {
  box-shadow: 0 8px 24px -8px rgba(15, 37, 64, 0.18);
}

/* Table: cleaner rows + hover */
.tbl tr {
  transition: background 0.15s ease;
}
.tbl tr:hover td {
  background: linear-gradient(90deg, rgba(232, 90, 44, 0.05) 0%, transparent 100%);
}
.tbl th {
  background: linear-gradient(180deg, #f7f9fc 0%, #f1f4f8 100%);
}

/* Avatars: subtle ring */
.avatar {
  box-shadow: 0 4px 10px -3px rgba(15, 37, 64, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

/* ============================================================
   Home Usager — fix overlap of services section with navy banner
   The screen wraps the content in .page-scroll with marginTop: -36
   to create a curved hand-off, but without rounded corners and
   z-index it just hid the section title under the dark banner.
   ============================================================ */
.page.with-tabs > .page-scroll {
  position: relative;
  z-index: 2;
  background: white;
  border-radius: 28px 28px 0 0;
  box-shadow: 0 -8px 24px -8px rgba(15, 37, 64, 0.15);
}
.page.with-tabs > .page-scroll > div {
  padding-top: 24px;
}
.page.with-tabs > .page-scroll > div > .sec-title-row,
.page.with-tabs > .page-scroll > div > .f15:first-child,
.page.with-tabs > .page-scroll > div > .hero-card:first-child {
  margin-top: 4px;
}

/* ============================================================
   Admin — Modal + Form fields + Detail page chrome
   ============================================================ */
.admin-modal-bg {
  position: fixed;
  inset: 0;
  background: rgba(15, 37, 64, 0.45);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  animation: modalBgIn 0.18s ease both;
  padding: 24px;
}
@keyframes modalBgIn { from { opacity: 0; } to { opacity: 1; } }

.admin-modal {
  background: white;
  border-radius: 18px;
  width: 100%;
  max-height: calc(100vh - 48px);
  display: flex;
  flex-direction: column;
  box-shadow: 0 30px 60px -16px rgba(15, 37, 64, 0.4);
  animation: modalIn 0.24s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  overflow: hidden;
}
@keyframes modalIn {
  from { transform: translateY(20px) scale(0.97); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.admin-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--line);
}
.admin-modal-close {
  width: 32px; height: 32px;
  border-radius: 10px;
  background: var(--bg);
  border: none;
  color: var(--ink-2);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease;
}
.admin-modal-close:hover { background: var(--line); color: var(--ink); }
.admin-modal-body {
  padding: 18px 22px;
  overflow-y: auto;
  flex: 1;
}
.admin-modal-foot {
  padding: 14px 22px;
  border-top: 1px solid var(--line);
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  background: var(--bg);
}

.admin-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 14px;
}
.admin-field-lbl {
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-2);
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.admin-field input[type="text"],
.admin-field input[type="email"],
.admin-field input[type="tel"],
.admin-field input[type="number"],
.admin-field select,
.admin-field textarea {
  width: 100%;
  padding: 10px 14px;
  border: 1.5px solid var(--line-2);
  border-radius: 10px;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink);
  background: white;
  transition: border 0.15s ease, box-shadow 0.15s ease;
}
.admin-field input:focus,
.admin-field select:focus,
.admin-field textarea:focus {
  outline: none;
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(232, 90, 44, 0.15);
}
.admin-field-hint { font-size: 11px; color: var(--ink-3); }
.admin-field-err  { font-size: 11px; color: var(--red); font-weight: 600; }
.admin-field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

/* ----- Prestataire detail page (admin) ----- */
.admin-detail-back {
  background: none;
  border: none;
  color: var(--ink-2);
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 0;
  margin-bottom: 8px;
}
.admin-detail-back:hover { color: var(--orange); }

.admin-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 18px;
  padding: 0 0 0;
}
.admin-tabs button {
  background: none;
  border: none;
  color: var(--ink-2);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 10px 16px;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.admin-tabs button:hover { color: var(--navy-deep); }
.admin-tabs button.active {
  color: var(--navy-deep);
  border-bottom-color: var(--orange);
  font-weight: 800;
}
.admin-tabs button .count {
  background: var(--bg);
  color: var(--ink-2);
  border-radius: 999px;
  padding: 1px 7px;
  font-size: 10px;
  font-weight: 700;
}
.admin-tabs button.active .count {
  background: var(--orange-soft);
  color: var(--orange);
}

.admin-empty {
  padding: 40px;
  text-align: center;
  color: var(--ink-3);
  font-size: 13px;
}
.admin-empty .ic {
  width: 56px; height: 56px;
  margin: 0 auto 12px;
  border-radius: 16px;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-3);
}

/* row actions (icon buttons) */
.admin-row-actions { display: inline-flex; gap: 6px; }
.admin-row-actions button {
  width: 30px; height: 30px;
  border-radius: 8px;
  background: var(--bg);
  border: none;
  cursor: pointer;
  color: var(--ink-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease;
}
.admin-row-actions button:hover { background: var(--line); color: var(--ink); }
.admin-row-actions button.danger:hover { background: var(--red-soft); color: var(--red); }

/* ============================================================
   Admin Cartographie — fullscreen map with floating overlays
   ============================================================ */

/* New: split layout — map on the left, side drawer on the right */
.map-page-with-drawer {
  display: flex;
  flex-direction: row;
  width: 100%;
  flex: 1;
  min-height: 0;
  height: calc(100vh - 80px); /* leave space for the admin footer */
  overflow: hidden;
}
.map-page-with-drawer .map-page-fullscreen {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
}
.map-side-drawer {
  /* Élargi à 460px pour accueillir confortablement le grid 2-cols
     des missions sans tronquer le nom du chauffeur ni l'adresse. */
  width: 460px;
  flex: 0 0 460px;
  height: 100%;
  background: white;
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  box-shadow: -10px 0 30px -16px rgba(15, 37, 64, 0.2);
  z-index: 10;
  transition: width 0.3s cubic-bezier(0.2, 0.9, 0.3, 1),
              flex-basis 0.3s cubic-bezier(0.2, 0.9, 0.3, 1),
              transform 0.3s cubic-bezier(0.2, 0.9, 0.3, 1),
              opacity 0.2s ease-out;
}
@media (max-width: 1280px) {
  .map-side-drawer { width: 380px; flex: 0 0 380px; }
}
@media (max-width: 1024px) {
  .map-side-drawer { width: 320px; flex: 0 0 320px; }
}
/* === Panneau MASQUÉ : largeur 0 + transform out + opacity 0 ===
   La carte récupère tout l'espace. Animation 300ms douce. */
.map-side-drawer.closed {
  width: 0 !important;
  flex: 0 0 0 !important;
  border-left: 0;
  transform: translateX(20px);
  opacity: 0;
  pointer-events: none;
  overflow: hidden;
}
/* Bouton "›" interne au panneau pour le masquer */
.onas-map-panel-hide {
  width: 32px;
  height: 32px;
  border: 1px solid var(--line);
  background: white;
  border-radius: 8px;
  cursor: pointer;
  font-size: 18px;
  font-weight: 800;
  color: var(--ink-2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  transition: all 0.15s;
  flex-shrink: 0;
}
.onas-map-panel-hide:hover {
  background: var(--orange);
  color: white;
  border-color: var(--orange);
  transform: scale(1.05);
}
/* Bouton flottant top-left "🗂 Filtres" qui apparaît quand le panneau
   est masqué — placé dans l'overlay onas-map-header à droite du titre. */
.onas-map-panel-launcher {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: linear-gradient(135deg, var(--orange) 0%, #d44d20 100%);
  color: white;
  border: none;
  border-radius: 999px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.2px;
  font-family: inherit;
  box-shadow: 0 6px 16px -6px rgba(232, 90, 44, 0.6),
              0 2px 4px -2px rgba(15, 37, 64, 0.2);
  transition: all 0.18s cubic-bezier(0.2, 0.9, 0.3, 1);
  flex-shrink: 0;
  animation: onas-launcher-in 0.32s cubic-bezier(0.2, 0.9, 0.3, 1) both;
}
.onas-map-panel-launcher:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 22px -6px rgba(232, 90, 44, 0.7),
              0 3px 6px -2px rgba(15, 37, 64, 0.25);
}
.onas-map-panel-launcher:active {
  transform: translateY(0);
}
@keyframes onas-launcher-in {
  0%   { opacity: 0; transform: translateX(-8px) scale(0.92); }
  100% { opacity: 1; transform: translateX(0)    scale(1);    }
}
.map-side-drawer-head {
  padding: 16px 18px;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}
.map-side-drawer-list {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 10px 12px 18px;
  display: block;
}
.map-side-item {
  display: block;
  width: 100%;
  background: white;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px;
  margin-bottom: 8px;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.18s ease;
}
.map-side-item:hover {
  border-color: var(--orange);
  box-shadow: 0 8px 18px -10px rgba(232, 90, 44, 0.35);
  transform: translateY(-1px);
}
.map-side-item.sel {
  border-color: var(--orange);
  background: linear-gradient(180deg, #FFF7F2 0%, #FFFFFF 80%);
  box-shadow: 0 0 0 3px rgba(232, 90, 44, 0.12);
}

/* === Animated green route line — flowing dashes ("walking ants") === */
.leaflet-overlay-pane .onas-route-flow {
  animation: routeFlow 1.4s linear infinite;
}
@keyframes routeFlow {
  to { stroke-dashoffset: -48; }
}

/* === Live stats overlay (Vitesse, ETA, Restant) shown when a mission is selected === */
.map-live-stats {
  bottom: 22px;
  right: 22px;
  width: 280px;
  padding: 14px 16px;
  z-index: 700;
  animation: liveStatsIn 0.25s cubic-bezier(0.2, 0.9, 0.3, 1) both;
}
@keyframes liveStatsIn {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
.map-live-stats-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 8px;
}
.map-live-stat {
  background: var(--bg);
  border-radius: 10px;
  padding: 8px 10px;
  text-align: center;
}
.map-live-stat-lbl {
  font-size: 9px;
  font-weight: 700;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}
.map-live-stat-val {
  font-size: 18px;
  font-weight: 800;
  margin-top: 2px;
}
.map-live-stat-val small {
  font-size: 9px;
  font-weight: 600;
  color: var(--ink-3);
  margin-left: 2px;
}

/* === Map popups (truck / client markers) === */
.onas-popup .leaflet-popup-content-wrapper {
  border-radius: 12px;
  padding: 0;
  box-shadow: 0 12px 30px -8px rgba(15, 37, 64, 0.22);
}
.onas-popup .leaflet-popup-content { margin: 0; }
.onas-popup .leaflet-popup-tip { display: none; }
.onas-popup-simple { padding: 10px 14px; font-size: 12px; font-weight: 600; color: var(--navy-deep); }

/* Tooltip permanent (bulle fixe) — utilisé pour les centres de dépotage */
.onas-station-tooltip {
  background: #1A1A1A !important;
  color: #FFF !important;
  border: none !important;
  border-radius: 8px !important;
  padding: 6px 10px !important;
  font-family: inherit !important;
  font-size: 10.5px !important;
  font-weight: 600 !important;
  line-height: 1.3 !important;
  box-shadow: 0 4px 12px -3px rgba(0,0,0,0.45) !important;
  white-space: nowrap;
}
.onas-station-tooltip::before {
  border-top-color: #1A1A1A !important;
}
.onas-station-tooltip strong { color: #FFF; font-weight: 800; }
.map-popup { padding: 14px 16px; min-width: 240px; }
.map-popup-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.map-popup-av {
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--navy);
  color: white; font-weight: 800; font-size: 12px;
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
}
.map-popup-name { font-size: 13px; font-weight: 800; color: var(--navy-deep); }
.map-popup-presta { font-size: 11px; color: var(--ink-3); margin-top: 2px; }
.map-popup-status {
  font-size: 10px;
  font-weight: 700;
  padding: 4px 8px;
  border-radius: 999px;
  white-space: nowrap;
}
.map-popup-row {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  padding: 4px 0;
  color: var(--ink-2);
}
.map-popup-row strong { color: var(--navy-deep); font-weight: 700; }

.map-page-fullscreen {
  position: relative;
  width: 100%;
  height: 100%;
}
.map-page-fullscreen .onas-map-wrap {
  height: 100% !important;
  width: 100%;
  border-radius: 0;
  box-shadow: none;
}
.map-overlay {
  position: absolute;
  z-index: 600;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: 0 12px 30px -10px rgba(15, 37, 64, 0.25);
}
.map-overlay-tl { top: 16px; left: 16px; }
.map-overlay-tr { top: 16px; right: 16px; }
.map-overlay-bl { bottom: 22px; left: 16px; padding: 6px 10px; }
.map-overlay-title h2 {
  font-size: 18px;
  font-weight: 800;
  color: var(--navy-deep);
  letter-spacing: -0.3px;
}
.map-overlay-title h2 small {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-3);
  margin-top: 2px;
}

/* push the GPS button up above the bottom-left overlay if they overlap */
.map-page-fullscreen .onas-map-gps {
  bottom: 22px;
  right: 16px;
}

@media (max-width: 720px) {
  .map-overlay-tr { display: none; }
  .map-overlay-tl { left: 12px; right: 12px; top: 12px; padding: 12px; }
  .map-overlay-title h2 { font-size: 16px; }
}

/* ============================================================
   OnasMap (Leaflet) — wrapper, pin/truck markers, GPS button
   ============================================================ */
.onas-map-wrap {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(15, 37, 64, 0.06), inset 0 0 0 1px rgba(226, 232, 240, 0.8);
  isolation: isolate;
}
.onas-map-canvas { z-index: 0; }

/* ============================================================
   Prestataire — modern design (curved header + white cards)
   Inspired by health-tracker UIs but with ONAS blue palette.
   ============================================================ */
:root {
  --presta-blue:       #2C72B7;
  --presta-blue-deep:  #1F5A93;
  --presta-blue-soft:  #E5F0FA;
}

.presta-page {
  position: absolute;
  inset: 0;
  /* [v455] Fond tinte clair pour faire ressortir la card header arrondie */
  background: #F4F6F9;
  display: flex;
  flex-direction: column;
  /* [v456] La page entiere scroll (header inclus). BottomNav reste sticky. */
  overflow-y: auto;
  overflow-x: hidden;
}

/* Curved blue header — [v455] floating card with all corners rounded */
.presta-header {
  background: linear-gradient(135deg, var(--presta-blue) 0%, var(--presta-blue-deep) 100%);
  color: white;
  padding: 14px 22px 22px;
  /* [v455] Tous coins arrondis + margin pour effet card floating sur fond tinte.
     margin-top inclut env(safe-area-inset-top) pour respecter notch iOS. */
  border-radius: 26px;
  margin: calc(8px + env(safe-area-inset-top, 0px)) 12px 0;
  position: relative;
  flex: 0 0 auto;
  box-shadow: 0 6px 20px -8px rgba(15,37,64,0.25);
  overflow: hidden;
}
.presta-header::before {
  content: "";
  position: absolute;
  top: -40px; right: -60px;
  width: 200px; height: 200px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  pointer-events: none;
}
.presta-header::after {
  content: "";
  position: absolute;
  bottom: 30px; left: -30px;
  width: 120px; height: 120px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.04);
  pointer-events: none;
}
.presta-mode-btn {
  background: rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: white;
  padding: 7px 12px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}
.presta-mode-btn:hover { background: rgba(255, 255, 255, 0.28); }
.presta-avatar {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: white;
  color: var(--presta-blue-deep);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 14px;
  border: 3px solid rgba(255, 255, 255, 0.4);
}

/* Availability pill (in-header) */
.presta-avail {
  margin-top: 18px;
  padding: 12px 14px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.16);
  display: flex;
  align-items: center;
  gap: 12px;
  position: relative;
  z-index: 1;
}
.presta-avail.on {
  background: rgba(255, 255, 255, 0.16);
  border-color: rgba(255, 255, 255, 0.32);
}
.presta-avail .dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: #94a3b8;
  flex: 0 0 auto;
}
.presta-avail.on .dot {
  background: #4cd494;
  box-shadow: 0 0 0 4px rgba(76, 212, 148, 0.3);
}

/* Scroll body */
.presta-scroll {
  /* [v456] Plus de scroll interne — la .presta-page scroll tout */
  flex: 0 1 auto;
  overflow: visible;
  /* [v464] BottomNav remplace par drawer -> padding-bottom reduit (etait 110px
     pour reserver l'espace sous la bottom-nav fixe). */
  padding: 18px 18px calc(24px + env(safe-area-inset-bottom, 0px));
  background: transparent;
}
/* [v458] BottomNav FIXED a la viewport — jamais cachee par URL bar mobile ni home indicator
   iPhone. Safe-area-inset-bottom respecte. Scoped a .presta-page pour ne pas casser
   les autres ecrans. !important pour battre onas-sobre.css qui set position: relative. */
.presta-page > .bottom-nav,
.presta-page .bottom-nav,
.phone-screen .presta-page .bottom-nav {
  position: fixed !important;
  bottom: 0 !important; left: 0; right: 0;
  padding-bottom: max(22px, calc(env(safe-area-inset-bottom, 0px) + 8px)) !important;
  z-index: 50;
}

/* Generic white card */
.presta-card {
  background: white;
  border-radius: 22px;
  padding: 16px 18px;
  box-shadow: 0 4px 16px -6px rgba(15, 37, 64, 0.1);
  border: 1px solid rgba(226, 232, 240, 0.85);
}

/* ============================================================
   [v463] Top row (header + calendrier)
   Mobile (<768px) : empile (header puis calendrier dessous).
   Tablet (>=768px) : grid 2 colonnes, les deux cards alignees
   sur la meme ligne, meme hauteur (align-items: stretch).
   Scoped a .mobile-stage-fullscreen pour ne pas casser le
   phone-frame du web (qui simule un mobile en 375x812).
   ============================================================ */
.presta-top-row {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
}
/* En mobile, calendrier ressemble au padding qu'il avait dans .presta-scroll */
.presta-top-row > .presta-card.presta-month-card {
  margin: 18px 18px 0;
}

@media (min-width: 768px) {
  .mobile-stage-fullscreen .presta-top-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 12px;
    align-items: stretch;
    padding: 0 12px;
  }
  /* En tablet, header occupe sa colonne (pas de margin laterale supplementaire) */
  .mobile-stage-fullscreen .presta-top-row > .presta-header {
    margin-left: 0;
    margin-right: 0;
  }
  /* En tablet, calendrier aligne en haut avec le header + meme hauteur */
  .mobile-stage-fullscreen .presta-top-row > .presta-card.presta-month-card {
    margin: calc(8px + env(safe-area-inset-top, 0px)) 0 0;
    align-self: stretch;
    display: flex;
    flex-direction: column;
  }
  /* La grille des jours s'etire pour remplir la hauteur de la card */
  .mobile-stage-fullscreen .presta-top-row > .presta-card.presta-month-card .presta-month-grid {
    flex: 1 1 auto;
  }
}

.presta-pill {
  background: var(--presta-blue-soft);
  color: var(--presta-blue-deep);
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
}
.presta-link {
  color: var(--presta-blue);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

/* Week strip */
.presta-week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  /* [v451b] espace en bas pour accueillir le badge rouge (compte demandes restantes) */
  padding-bottom: 18px;
}

/* ============================================================
   [v454] Calendrier MENSUEL (grille 6x7) — remplace l'ancienne strip
   ============================================================ */
.presta-month-header {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  margin-bottom: 4px;
}
.presta-month-dow {
  font-size: 10px;
  font-weight: 700;
  color: var(--ink-3);
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 4px 0;
}
.presta-month-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.presta-month-day {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease;
  user-select: none;
}
.presta-month-day:hover {
  background: var(--blue-pale);
}
.presta-month-num {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-deep);
  line-height: 1;
}
.presta-month-day.out-month .presta-month-num {
  color: var(--ink-4);
  opacity: 0.55;
}
.presta-month-day.today {
  background: var(--blue-bg);
}
.presta-month-day.today .presta-month-num {
  color: var(--navy);
  font-weight: 800;
}
.presta-month-day.selected {
  background: var(--navy);
}
.presta-month-day.selected .presta-month-num {
  color: white;
}
/* [v460] FOND ORANGE plein + texte BLANC sur la cellule date si demandes restantes
   a traiter (remplace l'ancien cadre rouge v457) */
.presta-month-day.has-demands {
  background: var(--orange, #E85A2C);
  box-shadow: 0 4px 10px -4px rgba(232, 90, 44, 0.45);
}
.presta-month-day.has-demands .presta-month-num {
  color: white;
  font-weight: 800;
}
.presta-month-day.has-demands.selected {
  /* [v462] Selectionne + a-demandes : animation pulse orange + ring navy qui s'etend */
  background: var(--orange, #E85A2C);
  box-shadow: 0 0 0 3px var(--navy, #1B3A5C), 0 4px 10px -4px rgba(232, 90, 44, 0.5);
  animation: prestaDayPulse 1.6s ease-in-out infinite;
}
@keyframes prestaDayPulse {
  0%, 100% {
    box-shadow: 0 0 0 3px var(--navy, #1B3A5C),
                0 0 0 5px rgba(232, 90, 44, 0),
                0 4px 10px -4px rgba(232, 90, 44, 0.5);
  }
  50% {
    box-shadow: 0 0 0 3px var(--navy, #1B3A5C),
                0 0 0 8px rgba(232, 90, 44, 0.35),
                0 6px 14px -4px rgba(232, 90, 44, 0.7);
  }
}
.presta-month-day.has-demands.selected .presta-month-num {
  color: white;
}
.presta-month-day.has-demands.today .presta-month-num {
  /* Today + has-demands : on garde le fond orange (priorite a l'action) */
  color: white;
}
/* [v464] Cellule calendrier VIDE (jour sans demandes) : transparente, non-cliquable,
   sans hover. Preserve l'alignement de la grille avec les colonnes jour-semaine. */
.presta-month-day.empty {
  cursor: default;
  pointer-events: none;
  background: transparent !important;
  box-shadow: none !important;
}
.presta-month-day.empty:hover {
  background: transparent !important;
}

/* ============================================================
   [v466] CALENDRIER ULTRA-COMPACT — flex row des jours avec
   demandes UNIQUEMENT, cote-a-cote. Pas d'entete weekday, pas
   de cellules vides. Petite etiquette weekday (D/L/M/J/V/S)
   au-dessus du chiffre pour contexte minimal.
   ============================================================ */
.presta-month-days-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 4px 0 2px;
}
.presta-month-days-row .presta-month-day {
  /* Override pour le mode flex-row : taille fixe + reset button defaults */
  width: 52px;
  height: 52px;
  aspect-ratio: auto;
  flex: 0 0 auto;
  appearance: none;
  font-family: inherit;
  padding: 4px 0;
  border: none;
  /* Conserve les styles has-demands deja existants (bg orange, shadow, etc) */
}
.presta-month-days-row .presta-month-day .dow {
  font-size: 9px;
  font-weight: 800;
  color: rgba(255, 255, 255, 0.75);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  line-height: 1;
  margin-bottom: 3px;
}
.presta-month-days-row .presta-month-day .presta-month-num {
  font-size: 15px;
  line-height: 1;
  color: white;
  font-weight: 800;
}
.presta-day {
  text-align: center;
  padding: 8px 0;
  border-radius: 14px;
  cursor: pointer;
  transition: all 0.2s ease;
}
.presta-day .lbl {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-3);
}
.presta-day .num {
  font-size: 16px;
  font-weight: 800;
  color: var(--ink);
  margin-top: 4px;
}
.presta-day:hover {
  background: var(--presta-blue-soft, #E8F1FA);
  transform: scale(1.05);
}
.presta-day.today {
  background: linear-gradient(135deg, var(--presta-blue) 0%, var(--presta-blue-deep) 100%);
  box-shadow: 0 6px 14px -4px rgba(44, 114, 183, 0.45);
}
.presta-day.today .lbl,
.presta-day.today .num {
  color: white;
}
/* [v313] Jour sélectionné dans le calendrier prestataire */
.presta-day.selected {
  background: linear-gradient(135deg, #1a5c9e 0%, #0d3b6e 100%);
  box-shadow: 0 6px 14px -4px rgba(13, 59, 110, 0.55);
  transform: scale(1.08);
}
.presta-day.selected .lbl,
.presta-day.selected .num {
  color: white;
}
/* Quand today ET selected sont sur le même jour → ring doré */
.presta-day.today.selected {
  box-shadow: 0 0 0 3px #FFB020, 0 6px 14px -4px rgba(44, 114, 183, 0.45);
}

/* Mission cards (with accept/decline) */
.presta-mission {
  margin-bottom: 12px;
}
.presta-mission-icon {
  width: 48px; height: 48px;
  border-radius: 14px;
  background: var(--presta-blue-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}
.presta-urgent {
  background: #FDE5E7;
  color: var(--red);
  font-size: 10px;
  font-weight: 800;
  padding: 3px 8px;
  border-radius: 999px;
  letter-spacing: 0.3px;
}

.presta-action {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 14px;
  border-radius: 14px;
  background: white;
  border: 1.5px solid var(--line);
  color: var(--ink-2);
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.18s ease;
}
.presta-action .radio {
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 2px solid var(--line-2);
  display: inline-block;
}
.presta-action.accept {
  background: linear-gradient(135deg, var(--presta-blue) 0%, var(--presta-blue-deep) 100%);
  color: white;
  border-color: transparent;
  box-shadow: 0 6px 16px -4px rgba(44, 114, 183, 0.45);
}
.presta-action.accept .radio {
  border-color: rgba(255, 255, 255, 0.5);
  background: white;
  position: relative;
}
.presta-action.accept .radio::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: var(--presta-blue);
}
.presta-action.declined  { background: #fef2f2; border-color: var(--red); color: var(--red); }
.presta-action.accepted  {
  /* keep the gradient but slightly darker to indicate selected state */
  filter: brightness(0.9);
}

/* Goal card with circular progress */
.presta-goal {
  display: flex;
  align-items: center;
  gap: 16px;
}
.presta-goal-info { flex: 1; }
.presta-ring {
  /* [v460] Ring ORANGE (gradient) avec animation de remplissage au mount */
  --p: 0%;
  width: 110px; height: 110px;
  border-radius: 50%;
  background:
    conic-gradient(var(--orange, #E85A2C) 0% var(--p), rgba(232,90,44,0.15) var(--p) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  box-shadow: 0 8px 18px -6px rgba(232, 90, 44, 0.4);
  animation: prestaRingFill 1.1s cubic-bezier(0.2, 0.85, 0.3, 1) both;
}
@keyframes prestaRingFill {
  from { --p: 0%; transform: scale(0.85); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}
@property --p {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}
.presta-ring .inner {
  width: 80px; height: 80px;
  border-radius: 50%;
  background: white;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  box-shadow: inset 0 2px 4px rgba(15, 37, 64, 0.05);
}
.presta-ring .pct {
  /* [v460] Pourcentage en BLEU pour contraster avec le ring orange */
  font-size: 20px;
  font-weight: 800;
  color: var(--presta-blue-deep, #1B3A5C);
}
.presta-ring .lbl {
  font-size: 9px;
  font-weight: 700;
  color: var(--presta-blue, #2C72B7);
  text-transform: uppercase;
  letter-spacing: 0.6px;
}

/* ============================================================
   [v464] Bottom row : Objectif + Depotages cards.
   Mobile (<768px) : empile (flex column).
   Tablet (>=768px) : grid 2 colonnes, meme hauteur (stretch).
   Scoped a .mobile-stage-fullscreen pour ne pas casser phone-frame web.
   ============================================================ */
.presta-bottom-row {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
@media (min-width: 768px) {
  .mobile-stage-fullscreen .presta-bottom-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    align-items: stretch;
  }
  .mobile-stage-fullscreen .presta-bottom-row > .presta-card {
    height: 100%;
  }
}

/* ============================================================
   [v464] PRESTA DRAWER — menu lateral gauche (remplace BottomNav)
   Style sidebar admin : fond navy gradient, items blancs, item actif
   orange. Slide-in depuis la gauche avec backdrop semi-transparent.
   ============================================================ */
.presta-drawer-wrap {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(15, 26, 46, 0);
  backdrop-filter: blur(0px);
  -webkit-backdrop-filter: blur(0px);
  visibility: hidden;
  pointer-events: none;
  transition:
    background 0.22s ease,
    backdrop-filter 0.22s ease,
    -webkit-backdrop-filter 0.22s ease,
    visibility 0s linear 0.22s;
}
.presta-drawer-wrap.is-open {
  background: rgba(15, 26, 46, 0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  visibility: visible;
  pointer-events: auto;
  transition:
    background 0.22s ease,
    backdrop-filter 0.22s ease,
    -webkit-backdrop-filter 0.22s ease;
}
.presta-drawer {
  position: absolute;
  top: 0;
  left: 0;
  width: min(82vw, 320px);
  height: 100%;
  background: linear-gradient(180deg, #0F2540 0%, #1B3A5C 100%);
  color: rgba(255, 255, 255, 0.92);
  box-shadow: 6px 0 24px -6px rgba(0, 0, 0, 0.35);
  display: flex;
  flex-direction: column;
  transform: translateX(-100%);
  transition: transform 0.22s cubic-bezier(0.2, 0.85, 0.3, 1);
  padding-top: max(18px, calc(env(safe-area-inset-top, 0px) + 18px));
  padding-bottom: max(18px, calc(env(safe-area-inset-bottom, 0px) + 18px));
  overflow: hidden;
}
.presta-drawer-wrap.is-open .presta-drawer {
  transform: translateX(0);
}
/* [v465] Header drawer : LOGO centre + bouton fermer absolu top-right */
.presta-drawer-head {
  position: relative;
  padding: 4px 18px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  display: block;
}
.presta-drawer-logo {
  display: block;
  margin: 0 auto;
  /* [v483] Logo plus grand (96px), pas de frame ni fond, pas de padding qui
     "rentre" le logo. Border-radius 20px pour suivre les coins arrondis de
     l'icone source — plus de rebord visible (demande user "cela coupe dans
     les bord"). object-fit contain garantit l'image entiere visible. */
  width: 96px;
  height: 96px;
  border-radius: 20px;
  object-fit: contain;
  background: transparent;
  box-shadow: none;
  padding: 0;
}
/* Brand text legacy : conserve mais inutilise dans le markup actuel */
.presta-drawer-brand-block { min-width: 0; flex: 1 1 auto; }
.presta-drawer-brand {
  font-size: 16px; font-weight: 800; color: white; letter-spacing: 0.3px;
}
.presta-drawer-sub {
  font-size: 11px; font-weight: 700; color: var(--orange, #E85A2C);
  margin-top: 2px; text-transform: uppercase; letter-spacing: 0.8px;
}
.presta-drawer-close {
  appearance: none;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: white;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.12s ease;
  /* [v465] Position absolue top-right pour ne pas decentrer le logo */
  position: absolute;
  top: 6px;
  right: 14px;
  z-index: 2;
}
.presta-drawer-close:hover {
  background: rgba(255, 255, 255, 0.16);
}
.presta-drawer-items {
  padding: 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow-y: auto;
  flex: 1 1 auto;
}
.presta-drawer-item {
  appearance: none;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.85);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  padding: 12px 14px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  gap: 14px;
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease, transform 0.08s ease;
  /* Animation d'apparition decalee a l'ouverture */
  opacity: 0;
  transform: translateX(-8px);
}
.presta-drawer-wrap.is-open .presta-drawer-item {
  animation: prestaDrawerItemIn 0.32s cubic-bezier(0.2, 0.85, 0.3, 1) forwards;
}
.presta-drawer-wrap.is-open .presta-drawer-item:nth-child(1) { animation-delay: 0.08s; }
.presta-drawer-wrap.is-open .presta-drawer-item:nth-child(2) { animation-delay: 0.13s; }
.presta-drawer-wrap.is-open .presta-drawer-item:nth-child(3) { animation-delay: 0.18s; }
.presta-drawer-wrap.is-open .presta-drawer-item:nth-child(4) { animation-delay: 0.23s; }
.presta-drawer-wrap.is-open .presta-drawer-item:nth-child(5) { animation-delay: 0.28s; }
@keyframes prestaDrawerItemIn {
  to { opacity: 1; transform: translateX(0); }
}
.presta-drawer-item:hover {
  background: rgba(255, 255, 255, 0.06);
  color: white;
}
.presta-drawer-item:active {
  transform: scale(0.98);
}
.presta-drawer-item.is-active {
  background: linear-gradient(135deg, var(--orange, #E85A2C) 0%, #d44d20 100%);
  color: white;
  box-shadow: 0 6px 18px -6px rgba(232, 90, 44, 0.55);
}
.presta-drawer-item .icn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  flex-shrink: 0;
}
.presta-drawer-item .lbl {
  flex: 1 1 auto;
}

/* ============================================================
   [v468] CHAT FAB — bouton flottant orange en bas a droite.
   Visible sur PrestaHome, ouvre l'aide/chat. Position fixed +
   safe-area pour ne JAMAIS etre cache par URL bar mobile ou
   home indicator iPhone. z-index sous le drawer (1000).
   ============================================================ */
.presta-chat-fab {
  position: fixed;
  /* [v491] Remonte encore + plus de gap vertical avec le FAB phone au-dessus.
     Bottom 96 -> 130 (deux pas vers le haut). */
  bottom: max(130px, calc(env(safe-area-inset-bottom, 0px) + 122px));
  right: max(20px, calc(env(safe-area-inset-right, 0px) + 16px));
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--orange, #E85A2C) 0%, #d44d20 100%);
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 20px -4px rgba(232, 90, 44, 0.55),
              0 4px 8px -2px rgba(0, 0, 0, 0.18);
  z-index: 90;
  opacity: 1;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  animation: fabBreatheOrange 3.2s ease-in-out infinite;
}
.presta-chat-fab::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 2px solid rgba(232, 90, 44, 0.55);
  animation: fabRippleOrange 2.4s ease-out infinite;
  pointer-events: none;
}
.presta-chat-fab > svg {
  animation: fabIconSpark 2.4s ease-in-out infinite;
}
.presta-chat-fab:hover {
  transform: scale(1.06);
  box-shadow: 0 10px 26px -4px rgba(232, 90, 44, 0.65),
              0 5px 10px -2px rgba(0, 0, 0, 0.22);
}
.presta-chat-fab:active { transform: scale(0.95); }

/* [v492] FABs draggable : cursor grab + touch-action none pour eviter
   le scroll du body pendant le drag tactile. */
.presta-chat-fab[data-draggable="true"],
.presta-phone-fab[data-draggable="true"] {
  cursor: grab;
  touch-action: none;
}
.presta-chat-fab[data-draggable="true"]:active,
.presta-phone-fab[data-draggable="true"]:active {
  cursor: grabbing;
}

/* [v493] FAB call center : couleur BLEU ONAS (avant vert) sur demande user
   "mais le en fond bleu onas". */
.presta-phone-fab {
  position: fixed;
  bottom: max(220px, calc(env(safe-area-inset-bottom, 0px) + 212px));
  right: max(20px, calc(env(safe-area-inset-right, 0px) + 16px));
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--presta-blue, #2C72B7) 0%, var(--presta-blue-deep, #1F5A93) 100%);
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 20px -4px rgba(44, 114, 183, 0.55),
              0 4px 8px -2px rgba(0, 0, 0, 0.18);
  z-index: 90;
  opacity: 1;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  animation: fabBreatheBlue 3.2s ease-in-out infinite;
}
.presta-phone-fab::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 2px solid rgba(44, 114, 183, 0.55);
  animation: fabRippleBlue 2.4s ease-out infinite;
  animation-delay: 1.2s;
  pointer-events: none;
}
.presta-phone-fab > svg {
  animation: fabIconRing 2s ease-in-out infinite;
  transform-origin: 50% 35%;
}
.presta-phone-fab:hover {
  transform: scale(1.06);
  box-shadow: 0 10px 26px -4px rgba(44, 114, 183, 0.65),
              0 5px 10px -2px rgba(0, 0, 0, 0.22);
}
.presta-phone-fab:active { transform: scale(0.95); }

/* [v499] WAKE FAB — petit micro a cote du FAB chat IA pour activer le mot
   d eveil "ONAS". Demande user "le bouton de discussion s active
   directement quand on active le micro". */
.presta-wake-fab {
  position: fixed;
  bottom: max(86px, calc(env(safe-area-inset-bottom, 0px) + 84px));
  right: max(94px, calc(env(safe-area-inset-right, 0px) + 90px));
  width: 40px; height: 40px;
  border-radius: 999px;
  background: linear-gradient(135deg, #1F5A93 0%, #0F2540 100%);
  border: none;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 14px -3px rgba(15, 37, 64, 0.45), 0 0 0 1px rgba(15, 37, 64, 0.1);
  z-index: 90;
  transition: transform 160ms ease, box-shadow 160ms ease;
}
.presta-wake-fab:hover { transform: scale(1.06); }
.presta-wake-fab:active { transform: scale(0.94); }
.presta-wake-fab.is-on {
  background: linear-gradient(135deg, #D9434C 0%, #b13c2f 100%);
  animation: onasChatMicPulse 1.4s ease-in-out infinite;
}
.presta-wake-fab > svg { display: block; flex: 0 0 auto; }

/* Petit dot rouge sur le FAB chat quand le mot d eveil est actif. */
.presta-chat-fab-wake-dot {
  position: absolute;
  top: 6px; right: 6px;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: #D9434C;
  border: 2px solid white;
  box-shadow: 0 0 0 0 rgba(217, 67, 76, 0.7);
  animation: onasChatMicPulse 1.2s ease-in-out infinite;
}
.presta-chat-fab.is-wake {
  box-shadow: 0 8px 22px -3px rgba(217, 67, 76, 0.55), 0 0 0 2px rgba(217, 67, 76, 0.35);
}

/* [v504] PUSH CONTENT — quand le chat est ouvert, on ajoute un
   padding-bottom dans les conteneurs scrollables pour que le contenu se
   pousse vers le bas (l usager peut scroller jusqu en bas sans que
   le chat couvre les boutons/cards). Demande user "le chat pousse son
   environnement vers le bas a l ouverture". */
body.onas-chat-open .phone-screen .page,
body.onas-chat-open .phone-screen .page-scroll,
body.onas-chat-open .phone-screen .presta-scroll,
body.onas-chat-open .phone-screen .usager-page,
body.onas-chat-open .phone-screen .admin-scroll {
  padding-bottom: calc(var(--onas-chat-h, 480px) + 100px) !important;
  transition: padding-bottom 220ms ease;
}

/* [v494] CHAT WIDGET FLOTTANT — petite fenetre 360x520 (responsive) qui
   glisse depuis le bas-droite. Overlay non-bloquant, ne cache pas l UI. */
.onas-chat-widget {
  position: fixed;
  /* [v502] Remonte encore (296->340px) avec marge basse plus confortable.
     Demande user "fait monter les champs un peu plus pour laisser les
     bords du bas avec une bonne marge". */
  bottom: max(340px, calc(env(safe-area-inset-bottom, 0px) + 330px));
  right: max(86px, calc(env(safe-area-inset-right, 0px) + 82px));
  width: min(360px, calc(100vw - 32px));
  height: min(480px, calc(100vh - 370px));
  background: #FFFFFF;
  border-radius: 18px;
  box-shadow: 0 20px 60px -16px rgba(15, 37, 64, 0.35),
              0 8px 24px -8px rgba(15, 37, 64, 0.22),
              0 0 0 1px rgba(15, 37, 64, 0.06);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 95;
  animation: onasChatWidgetIn 220ms cubic-bezier(.4, 1.4, .6, 1) both;
}
@keyframes onasChatWidgetIn {
  0%   { opacity: 0; transform: translate3d(0, 12px, 0) scale(0.96); }
  100% { opacity: 1; transform: translate3d(0, 0, 0)   scale(1);    }
}
.onas-chat-widget-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  background: linear-gradient(180deg, #FFFFFF 0%, #F7F9FC 100%);
  border-bottom: 1px solid rgba(15, 37, 64, 0.08);
  cursor: grab;
  touch-action: none;
  position: relative;
  user-select: none;
}
.onas-chat-widget-head::before {
  content: "";
  position: absolute;
  top: 5px; left: 50%;
  transform: translateX(-50%);
  width: 28px; height: 3px;
  border-radius: 2px;
  background: rgba(15, 37, 64, 0.14);
}
.onas-chat-widget-avatar {
  width: 32px; height: 32px;
  border-radius: 10px;
  background: linear-gradient(135deg, #FF8A5C 0%, var(--orange, #E85A2C) 100%);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 10px -2px rgba(232, 90, 44, 0.45);
}
.onas-chat-widget-close {
  width: 28px; height: 28px;
  border-radius: 8px;
  background: rgba(15, 37, 64, 0.06);
  border: none;
  cursor: pointer;
  color: var(--ink-deep);
  display: flex; align-items: center; justify-content: center;
  transition: background 160ms ease;
}
.onas-chat-widget-close:hover { background: rgba(15, 37, 64, 0.12); }
.onas-chat-widget-body {
  flex: 1 1 auto;
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch;
  /* [v505] Plus d air sous la derniere bulle pour que la barre input
     ne soit pas collee. */
  padding: 12px 12px 24px 12px;
  display: flex; flex-direction: column; gap: 10px;
  background: #FAFBFD;
  /* [v510] Scrollbar TOUJOURS VISIBLE (ascenseur). Demande user
     "le chat possede un ascenseur". */
  scrollbar-width: thin;
  scrollbar-color: rgba(15, 37, 64, 0.35) rgba(15, 37, 64, 0.06);
}
.onas-chat-widget-body::-webkit-scrollbar {
  width: 10px;
}
.onas-chat-widget-body::-webkit-scrollbar-track {
  background: rgba(15, 37, 64, 0.06);
  border-radius: 8px;
  margin: 4px 0;
}
.onas-chat-widget-body::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, rgba(15, 37, 64, 0.35) 0%, rgba(15, 37, 64, 0.55) 100%);
  border-radius: 8px;
  border: 2px solid #FAFBFD;
}
.onas-chat-widget-body::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, var(--orange, #E85A2C) 0%, #c84616 100%);
}
.onas-chat-widget-bubble {
  max-width: 82%;
  padding: 9px 12px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.4;
  word-wrap: break-word;
  animation: onasChatBubbleIn 200ms ease-out both;
}
@keyframes onasChatBubbleIn {
  0%   { opacity: 0; transform: translateY(6px); }
  100% { opacity: 1; transform: translateY(0); }
}
.onas-chat-widget-bubble.ai {
  align-self: flex-start;
  background: #FFFFFF;
  color: var(--ink-deep);
  border: 1px solid rgba(15, 37, 64, 0.08);
  border-bottom-left-radius: 4px;
}
.onas-chat-widget-bubble.me {
  align-self: flex-end;
  background: linear-gradient(135deg, var(--presta-blue, #2C72B7) 0%, var(--presta-blue-deep, #1F5A93) 100%);
  color: white;
  border-bottom-right-radius: 4px;
}
.onas-chat-typing {
  display: inline-flex; gap: 4px; padding: 12px 14px;
}
.onas-chat-typing span {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ink-3, #8794A4);
  animation: onasChatDot 1.2s ease-in-out infinite;
}
.onas-chat-typing span:nth-child(2) { animation-delay: 0.2s; }
.onas-chat-typing span:nth-child(3) { animation-delay: 0.4s; }
@keyframes onasChatDot {
  0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
  30%           { opacity: 1;   transform: translateY(-3px); }
}
.onas-chat-widget-input {
  display: flex; gap: 8px;
  /* [v506] Plus haut et contenu centre verticalement.
     Demande user "elargi la cellule en hauteur et centre son contenu". */
  padding: 16px 14px;
  min-height: 68px;
  margin-top: 4px;
  background: #FFFFFF;
  border-top: 1px solid rgba(15, 37, 64, 0.08);
  box-shadow: 0 -2px 8px -4px rgba(15, 37, 64, 0.08);
  box-sizing: border-box;
  max-width: 100%;
  overflow: hidden;
  align-items: center;
  justify-content: center;
}
.onas-chat-widget-input input[type="text"] {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  /* [v506] Hauteur d input plus genereuse, centree dans la cellule. */
  height: 40px;
  border: 1px solid rgba(15, 37, 64, 0.1);
  border-radius: 12px;
  padding: 0 14px;
  font-size: 13.5px;
  line-height: 40px;
  font-family: inherit;
  background: #F7F9FC;
  color: var(--ink-deep);
  outline: none;
  box-sizing: border-box;
  transition: border-color 160ms ease, background 160ms ease;
}
.onas-chat-widget-input input[type="text"]:focus {
  border-color: var(--orange, #E85A2C);
  background: #FFFFFF;
}
.onas-chat-widget-input button {
  /* [v506] Boutons mieux dimensionnes + auto-centre dans la cellule. */
  width: 40px; height: 40px;
  border-radius: 11px;
  background: linear-gradient(135deg, var(--orange, #E85A2C) 0%, #c84616 100%);
  border: none;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 8px -2px rgba(232, 90, 44, 0.35);
  flex-shrink: 0;
  flex-grow: 0;
  color: white;
  box-sizing: border-box;
  align-self: center;
}
/* [v496] Icon buttons (paperclip + mic) : style discret, pas orange. */
.onas-chat-widget-input .onas-chat-widget-icon-btn {
  width: 38px; height: 38px;
  border-radius: 11px;
  background: rgba(15, 37, 64, 0.06);
  color: var(--ink-3, #8794A4);
  box-shadow: none;
}
.onas-chat-widget-input .onas-chat-widget-icon-btn:hover {
  background: rgba(15, 37, 64, 0.10);
  color: var(--ink-deep);
}
.onas-chat-widget-input .onas-chat-widget-icon-btn.is-listening {
  background: linear-gradient(135deg, #D9434C 0%, #b13c2f 100%);
  color: white;
  animation: onasChatMicPulse 1.2s ease-in-out infinite;
}
@keyframes onasChatMicPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(217, 67, 76, 0.5); }
  50%      { box-shadow: 0 0 0 8px rgba(217, 67, 76, 0); }
}

/* [v511] BOUTON MIC AGRANDI : cible tactile 46px (Apple/Android HIG min
   44px), couleur distincte hors etat ecoute pour le rendre identifiable.
   Demande user "j ai des difficultes pour appuyer sur le bouton micro,
   il ne passe pas au rouge". */
.onas-chat-widget-input .onas-chat-widget-mic-btn {
  width: 46px !important;
  height: 46px !important;
  border-radius: 50% !important;
  background: linear-gradient(135deg, #2EB872 0%, #1FA065 100%) !important;
  color: white !important;
  box-shadow: 0 3px 10px -2px rgba(46, 184, 114, 0.45) !important;
  transition: transform 120ms ease, box-shadow 160ms ease, background 160ms ease;
}
.onas-chat-widget-input .onas-chat-widget-mic-btn:hover {
  transform: scale(1.06);
  background: linear-gradient(135deg, #2EB872 0%, #1a8f54 100%) !important;
}
.onas-chat-widget-input .onas-chat-widget-mic-btn:active {
  transform: scale(0.92);
}
.onas-chat-widget-input .onas-chat-widget-mic-btn.is-listening {
  background: linear-gradient(135deg, #FF3B47 0%, #b71d28 100%) !important;
  color: white !important;
  animation: onasChatMicPulseStrong 1.1s ease-in-out infinite !important;
}
@keyframes onasChatMicPulseStrong {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 59, 71, 0.55); transform: scale(1); }
  50%      { box-shadow: 0 0 0 14px rgba(255, 59, 71, 0); transform: scale(1.05); }
}

/* [v499] BUBBLE AVEC IMAGE : pas de padding, juste l image arrondie,
   clic pour ouvrir en grand. */
.onas-chat-widget-bubble.has-image {
  padding: 4px;
  max-width: 86%;
}
.onas-chat-widget-img {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  max-height: 220px;
  object-fit: cover;
  border-radius: 10px;
  cursor: zoom-in;
  background: #0F2540;
}
.onas-chat-widget-bubble.has-image .onas-chat-widget-text {
  padding: 6px 6px 2px 6px;
  font-size: 12px;
  opacity: 0.92;
}

/* [v499] CAMERA INLINE — la camera s affiche directement dans une bulle ai
   au lieu de couvrir tout le widget. Demande user "la camera vois
   directement dans le chat et donne ces commentaires". */
/* [v509] Camera inline aggrandie + plus visible. Demande user
   "l interface de la camera sur le chat est ecrasee, il faut qu elle
   soit bien visible". */
.onas-chat-widget-bubble.has-camera {
  padding: 6px;
  max-width: 100%;
  width: 100%;
  align-self: stretch;
  background: #0F2540;
  border: 1px solid rgba(15, 37, 64, 0.18);
  position: relative;
  overflow: hidden;
  border-radius: 14px;
}
.onas-chat-widget-cam-video {
  display: block;
  width: 100%;
  height: auto;
  min-height: 220px;
  max-height: 360px;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: 10px;
  background: #000;
}
.onas-chat-widget-cam-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 8px 4px 8px;
  gap: 10px;
}
.onas-chat-widget-cam-cancel {
  border: none;
  cursor: pointer;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  padding: 10px 18px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.22);
  color: white;
}
.onas-chat-widget-cam-cancel:hover { background: rgba(255, 255, 255, 0.32); }
.onas-chat-widget-cam-shoot {
  width: 58px; height: 58px;
  border-radius: 50%;
  background: white;
  padding: 0;
  border: none;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.30), 0 4px 12px -3px rgba(0,0,0,0.4);
}
.onas-chat-widget-cam-shoot span {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--orange, #E85A2C);
  display: block;
}
.onas-chat-widget-cam-shoot:active { transform: scale(0.94); }

/* [v510] Bouton ANALYSER 3D (panoramique + IA libre). */
.onas-chat-widget-cam-analyze {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: 64px;
  height: 52px;
  padding: 6px 12px;
  border-radius: 14px;
  background: linear-gradient(135deg, #2C72B7 0%, #1F5A93 100%);
  border: 2px solid rgba(255, 255, 255, 0.18);
  color: white;
  cursor: pointer;
  box-shadow: 0 4px 12px -3px rgba(44, 114, 183, 0.5);
  transition: transform 160ms ease, box-shadow 160ms ease;
}
.onas-chat-widget-cam-analyze:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px -3px rgba(44, 114, 183, 0.6);
}
.onas-chat-widget-cam-analyze:active { transform: scale(0.95); }
.onas-chat-widget-cam-analyze-label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.6px;
  line-height: 1;
}

/* [v509] Combo langue dans le head du chat. */
.onas-chat-widget-lang {
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid rgba(15, 37, 64, 0.12);
  background: rgba(15, 37, 64, 0.04);
  color: var(--ink-deep);
  border-radius: 8px;
  padding: 4px 18px 4px 8px;
  font-size: 11px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  outline: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%230F2540' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 6px center;
}
.onas-chat-widget-lang:hover { background-color: rgba(15, 37, 64, 0.10); }
.onas-chat-widget-lang:focus { border-color: var(--orange, #E85A2C); }

.onas-chat-widget-close.is-on {
  box-shadow: 0 0 0 2px rgba(46, 184, 114, 0.35);
}

/* [v503] Modal config IA (admin only) */
.onas-ai-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 37, 64, 0.45);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  animation: onasChatBubbleIn 180ms ease-out both;
}
.onas-ai-modal {
  background: #fff;
  border-radius: 16px;
  width: min(420px, 100%);
  max-height: 90vh;
  overflow: auto;
  box-shadow: 0 24px 60px -12px rgba(15, 37, 64, 0.4);
  font-family: inherit;
}
.onas-ai-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid rgba(15, 37, 64, 0.08);
}
.onas-ai-modal-close {
  background: rgba(15, 37, 64, 0.06);
  border: none;
  width: 28px; height: 28px;
  border-radius: 8px;
  font-size: 18px; font-weight: 700; line-height: 1;
  cursor: pointer; color: var(--ink-deep);
  display: flex; align-items: center; justify-content: center;
}
.onas-ai-modal-close:hover { background: rgba(15, 37, 64, 0.12); }
.onas-ai-modal-body { padding: 14px 18px 6px; }
.onas-ai-modal-label {
  font-size: 11px; font-weight: 700;
  color: var(--ink-3, #8794A4);
  letter-spacing: 0.6px; text-transform: uppercase;
  margin-bottom: 6px;
}
.onas-ai-modal-select,
.onas-ai-modal-input {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid rgba(15, 37, 64, 0.12);
  background: #F7F9FC;
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 13px;
  font-family: inherit;
  color: var(--ink-deep);
  outline: none;
  transition: border-color 160ms ease, background 160ms ease;
}
.onas-ai-modal-select:focus,
.onas-ai-modal-input:focus {
  border-color: var(--orange, #E85A2C);
  background: #fff;
}
.onas-ai-modal-helper {
  font-size: 11.5px; color: var(--ink-2, #4A5868);
  margin-top: 6px; line-height: 1.45;
}
.onas-ai-modal-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  padding: 14px 18px 16px;
  border-top: 1px solid rgba(15, 37, 64, 0.06);
}
.onas-ai-modal-btn {
  border: none; cursor: pointer;
  padding: 10px 16px;
  border-radius: 10px;
  font-family: inherit; font-weight: 700; font-size: 13px;
}
.onas-ai-modal-btn.ghost {
  background: rgba(15, 37, 64, 0.06); color: var(--ink-deep);
}
.onas-ai-modal-btn.ghost:hover { background: rgba(15, 37, 64, 0.12); }
.onas-ai-modal-btn.primary {
  background: linear-gradient(135deg, var(--orange, #E85A2C) 0%, #c84616 100%);
  color: #fff;
  box-shadow: 0 3px 8px -2px rgba(232, 90, 44, 0.35);
}
.onas-ai-modal-btn.primary:active { transform: scale(0.97); }

/* [v499] RESPONSIVE — sur tres petit ecran, le widget occupe quasi tout
   sans deborder. Demande user "que la fenetre soit responsive pas de
   debordement". */
@media (max-width: 420px) {
  .onas-chat-widget {
    width: calc(100vw - 16px) !important;
    height: min(68vh, calc(100vh - 320px)) !important;
    bottom: max(310px, calc(env(safe-area-inset-bottom, 0px) + 300px));
    right: 8px !important;
    left: auto;
  }
  .onas-chat-widget-bubble { max-width: 90%; font-size: 12.5px; }
  /* [v505/v506] Cellule plus haute + contenu centre, padding genereux. */
  .onas-chat-widget-input { padding: 14px 10px; gap: 6px; margin-top: 4px; min-height: 64px; }
  .onas-chat-widget-body { padding: 10px 10px 20px 10px; gap: 10px; }
  .onas-chat-widget-input button { width: 38px; height: 38px; border-radius: 11px; }
  .onas-chat-widget-input .onas-chat-widget-icon-btn { width: 36px; height: 36px; }
  .onas-chat-widget-input input[type="text"] { height: 38px; line-height: 38px; padding: 0 12px; font-size: 12.5px; }
}
@media (max-width: 320px) {
  .onas-chat-widget { width: calc(100vw - 8px) !important; right: 4px !important; }
}
.presta-chat-fab.is-active {
  background: linear-gradient(135deg, #1F5A93 0%, #0F2540 100%) !important;
}

/* [v489] Animations FAB — breathing pulse, rippling halo, icon micro-anims. */
@keyframes fabBreatheOrange {
  0%, 100% { transform: scale(1);    box-shadow: 0 8px 20px -4px rgba(232, 90, 44, 0.55), 0 4px 8px -2px rgba(0, 0, 0, 0.18); }
  50%      { transform: scale(1.06); box-shadow: 0 12px 28px -4px rgba(232, 90, 44, 0.7),  0 6px 12px -2px rgba(0, 0, 0, 0.22); }
}
@keyframes fabBreatheGreen {
  0%, 100% { transform: scale(1);    box-shadow: 0 8px 20px -4px rgba(46, 184, 114, 0.55), 0 4px 8px -2px rgba(0, 0, 0, 0.18); }
  50%      { transform: scale(1.06); box-shadow: 0 12px 28px -4px rgba(46, 184, 114, 0.7),  0 6px 12px -2px rgba(0, 0, 0, 0.22); }
}
@keyframes fabBreatheBlue {
  0%, 100% { transform: scale(1);    box-shadow: 0 8px 20px -4px rgba(44, 114, 183, 0.55), 0 4px 8px -2px rgba(0, 0, 0, 0.18); }
  50%      { transform: scale(1.06); box-shadow: 0 12px 28px -4px rgba(44, 114, 183, 0.7),  0 6px 12px -2px rgba(0, 0, 0, 0.22); }
}
@keyframes fabRippleOrange {
  0%   { transform: scale(0.85); opacity: 0.9; border-color: rgba(232, 90, 44, 0.7); }
  100% { transform: scale(1.6);  opacity: 0;   border-color: rgba(232, 90, 44, 0); }
}
@keyframes fabRippleGreen {
  0%   { transform: scale(0.85); opacity: 0.9; border-color: rgba(46, 184, 114, 0.7); }
  100% { transform: scale(1.6);  opacity: 0;   border-color: rgba(46, 184, 114, 0); }
}
@keyframes fabRippleBlue {
  0%   { transform: scale(0.85); opacity: 0.9; border-color: rgba(44, 114, 183, 0.7); }
  100% { transform: scale(1.6);  opacity: 0;   border-color: rgba(44, 114, 183, 0); }
}
@keyframes fabIconSpark {
  0%, 100% { transform: rotate(0deg)   scale(1); }
  50%      { transform: rotate(-8deg)  scale(1.1); }
}
@keyframes fabIconRing {
  0%, 100% { transform: rotate(0deg); }
  20%      { transform: rotate(-14deg); }
  40%      { transform: rotate(14deg); }
  60%      { transform: rotate(-8deg); }
  80%      { transform: rotate(8deg); }
}

/* ============================================================
   [v469] PRESTA FLOATING MENU — hamburger flottant top-right.
   Visible sur toutes les pages prestataire (History, Profile,
   ChatAI...) sauf PrestaHome qui a son hamburger dans le header.
   Rendu par BottomNav quand persona === 'prestataire'.
   ============================================================ */
.presta-floating-menu {
  position: fixed;
  top: max(12px, calc(env(safe-area-inset-top, 0px) + 10px));
  right: max(12px, calc(env(safe-area-inset-right, 0px) + 10px));
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: var(--orange, #E85A2C);
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 80;
  box-shadow: 0 4px 14px -4px rgba(232, 90, 44, 0.5),
              0 2px 6px -1px rgba(0, 0, 0, 0.18);
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}
.presta-floating-menu:hover {
  background: #d44d20;
  transform: scale(1.05);
}
.presta-floating-menu:active { transform: scale(0.95); }

/* ============================================================
   [v472] DRAGGABLE SHEET — fenetre flottante draggable.
   Position initiale centree, devient {left, top} en pixels apres
   un drag. Cursor grab/grabbing sur la barre de titre.
   ============================================================ */
.draggable-sheet {
  position: fixed;
  top: 60px;
  left: 50%;
  transform: translateX(-50%);
  width: min(94vw, 560px);
  max-height: calc(100vh - 100px);
  background: white;
  border-radius: 16px;
  box-shadow: 0 24px 60px -10px rgba(15, 37, 64, 0.4),
              0 8px 18px -6px rgba(0, 0, 0, 0.2);
  z-index: 200;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Light entry animation : fade + slight lift, only opacity-based to avoid
     transform conflict with drag positioning */
  animation: dragSheetIn 0.18s ease-out;
}
@keyframes dragSheetIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.draggable-sheet.is-dragging {
  box-shadow: 0 30px 70px -10px rgba(15, 37, 64, 0.5),
              0 12px 24px -6px rgba(0, 0, 0, 0.25);
  cursor: grabbing;
}
.draggable-sheet-handle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  background: linear-gradient(180deg, #F8FAFC 0%, #FFFFFF 100%);
  border-bottom: 1px solid var(--line);
  cursor: grab;
  user-select: none;
  touch-action: none;
  gap: 10px;
  flex-shrink: 0;
}
.draggable-sheet.is-dragging .draggable-sheet-handle { cursor: grabbing; }
.draggable-sheet-handle .handle-grip {
  width: 32px;
  height: 4px;
  border-radius: 999px;
  background: var(--ink-4, #C7CFD9);
  flex-shrink: 0;
}
.draggable-sheet-handle .handle-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-deep, #14202E);
  flex: 1 1 auto;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.draggable-sheet-handle .handle-close {
  appearance: none;
  background: var(--blue-bg, rgba(44,114,183,0.08));
  border: none;
  color: var(--ink-2, #2D3F55);
  width: 28px;
  height: 28px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 20px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-weight: 600;
  font-family: inherit;
  padding: 0;
  transition: background 0.12s ease, color 0.12s ease;
}
.draggable-sheet-handle .handle-close:hover {
  background: var(--orange, #E85A2C);
  color: white;
}
.draggable-sheet-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 16px 18px 18px;
  -webkit-overflow-scrolling: touch;
}

/* ============================================================
   Ticket Screen — boarding pass style (sky gradient + notched card)
   ============================================================ */
:root {
  --sky-1: #B6DCFF;
  --sky-2: #6FB6F7;
  --sky-3: #4F95E8;
}

.ticket-page {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(60% 40% at 25% 10%, rgba(255,255,255,0.5), transparent 70%),
    radial-gradient(50% 35% at 80% 80%, rgba(255,255,255,0.4), transparent 70%),
    linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 60%, var(--sky-3) 100%);
  display: flex;
  flex-direction: column;
  padding-top: 32px;
  overflow: hidden;
}
.ticket-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px 4px;
  position: relative;
  z-index: 2;
}
.ticket-iconbtn {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.32);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: white;
}
.ticket-title {
  color: white;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 0.3px;
  text-shadow: 0 1px 2px rgba(15, 37, 64, 0.12);
}

.ticket-content {
  flex: 1;
  overflow-y: auto;
  padding: 36px 22px 30px;
  position: relative;
}

.ticket-floating-icon {
  position: absolute;
  top: 16px; left: 50%;
  transform: translateX(-50%);
  width: 56px; height: 56px;
  border-radius: 50%;
  background: white;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 18px -4px rgba(15, 37, 64, 0.25), inset 0 0 0 4px rgba(111, 182, 247, 0.2);
  z-index: 3;
}

.ticket-card {
  background: white;
  border-radius: 22px;
  padding: 36px 22px 22px;
  box-shadow: 0 30px 60px -20px rgba(15, 37, 64, 0.4);
  position: relative;
  margin-top: 8px;
}

.ticket-instructions {
  text-align: center;
  font-size: 12px;
  color: var(--ink-2);
  margin-bottom: 16px;
}
.ticket-qr {
  display: flex;
  justify-content: center;
  margin: 4px 0 18px;
}
.ticket-qr svg {
  fill: #2C72B7;
}
.ticket-qr svg rect[fill="#1B3A5C"] { fill: #2C72B7; }

/* Notched separator (cut-out semicircles + dashed line) */
.ticket-notch-row {
  position: relative;
  margin: 10px -22px 14px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ticket-notch-row::before, .ticket-notch-row::after {
  content: "";
  position: absolute;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--sky-2);
  background: linear-gradient(135deg, var(--sky-1), var(--sky-2));
  top: 0;
}
.ticket-notch-row::before { left: -14px; }
.ticket-notch-row::after  { right: -14px; }
.ticket-notch-row {
  background-image: repeating-linear-gradient(90deg, var(--line-2) 0 6px, transparent 6px 12px);
  background-position: 0 50%;
  background-repeat: no-repeat;
  background-size: 100% 1.5px;
}

/* Route line (CDG ✈ PEK) */
.ticket-route {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 10px 0 18px;
}
.ticket-route-side { text-align: center; }
.ticket-route-code {
  font-size: 26px;
  font-weight: 800;
  color: var(--ink);
  letter-spacing: 0.5px;
}
.ticket-route-city {
  font-size: 11px;
  color: var(--presta-blue);
  font-weight: 600;
  margin-top: 2px;
  text-transform: capitalize;
}
.ticket-route-icon {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--presta-blue-soft);
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
}

/* Info rows */
.ticket-row-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 10px;
}
.ticket-cell .lbl {
  font-size: 10px;
  color: var(--ink-3);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.ticket-cell .val {
  font-size: 14px;
  color: var(--ink);
  font-weight: 800;
  margin-top: 4px;
}

/* Action buttons */
.ticket-actions {
  display: flex;
  gap: 10px;
  margin-top: 18px;
}
.ticket-btn {
  flex: 1;
  padding: 14px;
  border-radius: 14px;
  border: none;
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.18s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.ticket-btn.ghost {
  background: rgba(255, 255, 255, 0.85);
  color: var(--ink);
  backdrop-filter: blur(8px);
}
.ticket-btn.primary {
  background: linear-gradient(135deg, #2C72B7 0%, #1F5A93 100%);
  color: white;
  box-shadow: 0 10px 24px -8px rgba(44, 114, 183, 0.5);
}
.ticket-btn.share {
  width: 100%;
  margin-top: 10px;
  background: rgba(255, 255, 255, 0.18);
  border: 1.5px dashed rgba(255, 255, 255, 0.55);
  color: white;
  backdrop-filter: blur(8px);
}
.ticket-btn:hover { transform: translateY(-1px); }

.ticket-autoback {
  margin-top: 14px;
  padding: 10px 14px;
  background: rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(8px);
  border-radius: 999px;
  text-align: center;
  font-size: 11px;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  letter-spacing: 0.3px;
  font-weight: 600;
}
.ticket-autoback .cancel {
  font-size: 10px;
  opacity: 0.65;
  font-weight: 500;
}

/* ============================================================
   Usager — same design language as the prestataire (curved blue
   header + clean white cards). Padded for the bottom nav.
   ============================================================ */
.usager-page {
  position: absolute;
  inset: 0;
  background: white;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* [v476] Header usager refait comme presta : floating card avec margin top
   safe-area + tous coins arrondis. Plus de coupe au notch. */
.usager-header {
  background: linear-gradient(135deg, var(--presta-blue) 0%, var(--presta-blue-deep) 100%);
  color: white;
  padding: 14px 20px 22px;
  border-radius: 26px;
  margin: calc(8px + env(safe-area-inset-top, 0px)) 12px 0;
  position: relative;
  flex: 0 0 auto;
  box-shadow: 0 6px 20px -8px rgba(15,37,64,0.25);
  overflow: hidden;
}
.usager-header::before {
  content: "";
  position: absolute;
  top: -50px; right: -50px;
  width: 200px; height: 200px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  pointer-events: none;
}
.usager-header::after {
  content: "";
  position: absolute;
  bottom: 30px; left: -30px;
  width: 120px; height: 120px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.04);
  pointer-events: none;
}

/* Hero card for the active request */
.usager-hero {
  background: linear-gradient(135deg, #FF8A5C 0%, var(--orange) 100%);
  color: white;
  padding: 18px;
  border-radius: 20px;
  cursor: pointer;
  margin-bottom: 4px;
  box-shadow: 0 14px 28px -10px rgba(232, 90, 44, 0.5);
  transition: transform 0.2s ease;
}
.usager-hero:hover { transform: translateY(-2px); }
.usager-hero-icon {
  width: 48px; height: 48px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.18);
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
}
.usager-hero-foot {
  margin-top: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: rgba(255, 255, 255, 0.15);
  border-radius: 10px;
}

/* Service tiles grid (4 tiles) — clean centered cards */
.usager-svc-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 16px;
}

/* [v244] Overlay "Tous les services" — plein écran, grid responsive.
   Mobile = 2 cols par défaut, ≥600px (tablette portrait) = 3 cols,
   ≥900px (tablette paysage) = 4 cols, ≥1200px (desktop) = 5 cols.
   Animation fade + slide + stagger sur les cartes. */
.usager-svc-overlay {
  position: fixed;
  inset: 0;
  z-index: 1500;
  background: linear-gradient(180deg, #f5f7fb 0%, #ffffff 100%);
  overflow-y: auto;
  animation: usagerOverlayIn 320ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
  padding: 0 0 32px;
}
@keyframes usagerOverlayIn {
  0%   { opacity: 0; transform: translateY(12px); }
  100% { opacity: 1; transform: translateY(0); }
}
.usager-svc-overlay-header {
  position: sticky;
  top: 0;
  z-index: 2;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid rgba(15, 37, 64, 0.07);
  padding: 14px 18px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.usager-svc-overlay-back {
  background: none;
  border: 0;
  padding: 6px 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--orange);
  cursor: pointer;
  align-self: flex-start;
  font-family: inherit;
}
.usager-svc-overlay-title {
  font-size: 22px;
  font-weight: 800;
  color: var(--navy-deep);
  margin-top: 2px;
}
.usager-svc-overlay-count {
  font-size: 12px;
  color: var(--ink-3);
}
.usager-svc-overlay-grid {
  padding: 20px 18px 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
}
.usager-svc-overlay-card {
  animation: usagerSvcCardIn 360ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@keyframes usagerSvcCardIn {
  0%   { opacity: 0; transform: translateY(10px) scale(0.97); }
  100% { opacity: 1; transform: translateY(0)   scale(1); }
}
/* Responsive : tablette portrait 3 cols, paysage 4 cols, desktop 5 cols */
@media (min-width: 600px) {
  .usager-svc-overlay-grid { grid-template-columns: repeat(3, 1fr); gap: 16px; padding: 24px 32px 0; }
}
@media (min-width: 900px) {
  .usager-svc-overlay-grid { grid-template-columns: repeat(4, 1fr); }
  .usager-svc-overlay-header { padding: 18px 32px 14px; }
}
@media (min-width: 1200px) {
  .usager-svc-overlay-grid { grid-template-columns: repeat(5, 1fr); max-width: 1400px; margin: 0 auto; }
  .usager-svc-overlay-header { max-width: 1400px; margin: 0 auto; }
}
.usager-svc {
  background: #ffffff;
  border: 1px solid rgba(226, 232, 240, 0.85);
  border-radius: 22px;
  padding: 22px 14px 18px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  font-family: inherit;
  cursor: pointer;
  transition: all 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
  box-shadow: 0 2px 6px -2px rgba(15, 37, 64, 0.06);
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
/* No colored halo — keep the tile pure white */
.usager-svc::before { display: none; }
.usager-svc:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 32px -10px rgba(15, 37, 64, 0.18);
  border-color: rgba(15, 37, 64, 0.18);
}

.usager-svc-icon {
  width: 56px; height: 56px;
  border-radius: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  flex: 0 0 auto;
  position: relative;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.32),
    inset 0 -2px 0 rgba(0, 0, 0, 0.08),
    0 8px 18px -6px currentColor;
}
.usager-svc-icon::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.22) 0%, transparent 55%);
  pointer-events: none;
}
.usager-svc h3 {
  font-size: 15px;
  font-weight: 800;
  color: var(--navy-deep);
  margin: 0;
  letter-spacing: -0.3px;
  line-height: 1.2;
}
.usager-svc p {
  font-size: 11px;
  color: var(--ink-3);
  margin: 0;
  line-height: 1.5;
  font-weight: 500;
}

/* Per-service ghost color via CSS variable on the button */
.usager-svc:nth-child(1) { --svc-ghost: rgba(27, 58, 92, 0.08); }
.usager-svc:nth-child(2) { --svc-ghost: rgba(232, 90, 44, 0.10); }
.usager-svc:nth-child(3) { --svc-ghost: rgba(217, 67, 76, 0.10); }
.usager-svc:nth-child(4) { --svc-ghost: rgba(46, 184, 114, 0.10); }

/* Urgence sanitaire alert card */
.usager-urgence {
  margin-top: 16px;
  padding: 14px;
  background: var(--red-soft);
  border: 1.5px solid #FCC0C5;
  border-radius: 16px;
  display: flex;
  gap: 12px;
  align-items: center;
  cursor: pointer;
  transition: transform 0.2s ease;
}
.usager-urgence:hover { transform: translateY(-1px); }
.usager-urgence-icon {
  width: 40px; height: 40px;
  border-radius: 12px;
  background: var(--red);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  box-shadow: 0 6px 14px -4px rgba(217, 67, 76, 0.5);
}

/* Blinking notification dot on the QR account button */
.qr-notif-dot {
  animation: blinkDot 1.4s ease-in-out infinite;
}
@keyframes blinkDot {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 0 0 2px var(--navy), 0 0 0 0 rgba(232, 90, 44, 0.7);
  }
  50% {
    transform: scale(1.18);
    box-shadow: 0 0 0 2px var(--navy), 0 0 0 6px rgba(232, 90, 44, 0);
  }
}

/* Multi-channel share sheet — used by TicketScreen */
.share-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 4px;
}
.share-tile {
  background: white;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 12px 6px 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.18s ease;
}
.share-tile:hover {
  border-color: var(--orange);
  transform: translateY(-1px);
  box-shadow: 0 6px 14px -8px rgba(15,37,64,0.18);
}
.share-tile span {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink);
}
.share-ic {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 10px -3px rgba(15,37,64,0.25);
}

/* Blinking red dot on a History card with a fresh update (latest cotation, etc.) */
.history-card.has-update {
  border-color: rgba(229, 57, 53, 0.45) !important;
  box-shadow: 0 0 0 3px rgba(229, 57, 53, 0.06), 0 6px 14px -10px rgba(229, 57, 53, 0.45);
}
.card-blink-dot {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: #E53935;
  box-shadow: 0 0 0 0 rgba(229, 57, 53, 0.55);
  animation: cardBlinkDot 1.3s ease-in-out infinite;
  z-index: 2;
  pointer-events: none;
}
@keyframes cardBlinkDot {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(229, 57, 53, 0.55);
  }
  50% {
    transform: scale(1.2);
    box-shadow: 0 0 0 8px rgba(229, 57, 53, 0);
  }
}

/* Blinking red dot on the bottom-nav History tab when there's new info */
.bottom-nav .nav-item .ic-wrap { position: relative; }
.nav-blink-dot {
  position: absolute;
  top: -3px;
  right: -6px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #E53935;
  border: 2px solid white;
  box-shadow: 0 0 0 0 rgba(229, 57, 53, 0.55);
  animation: navBlinkDot 1.3s ease-in-out infinite;
  pointer-events: none;
}
@keyframes navBlinkDot {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(229, 57, 53, 0.55);
  }
  50% {
    transform: scale(1.18);
    box-shadow: 0 0 0 7px rgba(229, 57, 53, 0);
  }
}

/* QR scanner overlay scan-line animation */
@keyframes scan {
  0%   { top: 14px; }
  50%  { top: calc(100% - 16px); }
  100% { top: 14px; }
}

/* Custom pin/truck divIcons — strip default Leaflet styling */
.onas-pin-icon, .onas-truck-icon {
  background: transparent !important;
  border: none !important;
}
.onas-truck-marker {
  width: 32px; height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  box-shadow:
    0 6px 14px -4px rgba(0, 0, 0, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.25),
    0 0 0 2px rgba(255, 255, 255, 0.85);
  animation: truck-pulse 2.6s ease-in-out infinite;
}
@keyframes truck-pulse {
  0%, 100% { box-shadow: 0 6px 14px -4px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.25), 0 0 0 2px rgba(255,255,255,0.85); }
  50%      { box-shadow: 0 6px 14px -4px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.25), 0 0 0 6px rgba(255,255,255,0); }
}

/* Layer switcher (basemap toggle) */
.onas-layer-switcher {
  position: absolute;
  bottom: 14px;
  right: 14px;
  z-index: 400;
}
.onas-layer-switcher.with-gps {
  /* push the layer button up so the GPS button stays at the bottom */
  bottom: 64px;
}
.onas-map-layer-btn {
  width: 42px; height: 42px;
  border-radius: 50%;
  background: white;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--navy);
  box-shadow: 0 6px 18px -4px rgba(15, 37, 64, 0.25), inset 0 0 0 1px rgba(226, 232, 240, 0.8);
  transition: all 0.15s ease;
}
.onas-map-layer-btn:hover { transform: translateY(-1px); }
.onas-layer-menu {
  position: absolute;
  bottom: 50px;
  right: 0;
  background: white;
  border-radius: 12px;
  padding: 6px;
  box-shadow: 0 18px 40px -10px rgba(15, 37, 64, 0.35), inset 0 0 0 1px rgba(226, 232, 240, 0.8);
  min-width: 130px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  animation: layerMenuIn 0.18s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@keyframes layerMenuIn {
  from { opacity: 0; transform: translateY(8px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.onas-layer-menu button {
  background: transparent;
  border: none;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-2);
  padding: 8px 12px;
  border-radius: 8px;
  text-align: left;
  cursor: pointer;
  transition: all 0.15s ease;
}
.onas-layer-menu button:hover { background: var(--bg); color: var(--navy-deep); }
.onas-layer-menu button.active {
  background: var(--orange);
  color: white;
}

/* Locate-me button */
.onas-map-gps {
  position: absolute;
  bottom: 14px; right: 14px;
  width: 42px; height: 42px;
  border-radius: 50%;
  background: white;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--navy);
  box-shadow: 0 6px 18px -4px rgba(15, 37, 64, 0.25), inset 0 0 0 1px rgba(226, 232, 240, 0.8);
  z-index: 400;
  transition: all 0.15s ease;
}
.onas-map-gps:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 22px -6px rgba(15, 37, 64, 0.3);
}

/* Leaflet attribution + zoom control polish */
.leaflet-control-attribution {
  background: rgba(255, 255, 255, 0.85) !important;
  font-size: 9px !important;
  padding: 1px 6px !important;
}
.leaflet-control-zoom a {
  background: white !important;
  color: var(--navy) !important;
  border: 1px solid rgba(226, 232, 240, 0.8) !important;
  font-weight: 700 !important;
}
.leaflet-control-zoom a:hover {
  background: var(--blue-bg) !important;
}
.leaflet-popup-content-wrapper {
  border-radius: 10px !important;
  box-shadow: 0 12px 28px -8px rgba(15, 37, 64, 0.25) !important;
}
.leaflet-popup-content {
  font-family: inherit !important;
  font-size: 12px !important;
  margin: 10px 14px !important;
}

/* ============================================================
   Page transitions
   ============================================================ */
.phone-screen .page,
.phone-screen .page-enter {
  animation: pageIn 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@keyframes pageIn {
  from { opacity: 0; transform: translateX(8px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* ============================================================
   Responsive tweaks — v155 : breakpoints landing mobile + tablette
   ============================================================ */

/* Tablette portrait (601-1024px) : 2 colonnes (au lieu de 3 qui déborde) */
@media (min-width: 601px) and (max-width: 1024px) {
  .launcher-personas {
    grid-template-columns: repeat(2, minmax(240px, 1fr));
    max-width: 720px;
  }
  .launcher { padding: 56px 28px 72px; gap: 36px; }
  .launcher-sub { font-size: 16px; }
}

/* Mobile (≤ 600px) : 1 colonne + ajustements généreux */
@media (max-width: 600px) {
  .launcher-personas {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  .launcher { padding: 44px 16px 60px; gap: 28px; }
  .launcher-title,
  .launcher-title-anim,
  .sunu-onas-html-title {
    /* Override l'inline style React clamp(48px, 13vw, 130px) qui déborde
       en nowrap sur mobiles < 360px. */
    font-size: clamp(34px, 11vw, 64px) !important;
    letter-spacing: -1px !important;
    padding: 0 8px !important;
  }
  .launcher-sub {
    font-size: 15px;
    line-height: 1.55;
    padding: 0 4px;
  }
  .launcher-logo img { width: 76px !important; }
  .persona-card {
    padding: 22px 18px;
    border-radius: 18px;
  }
  .persona-card h3 { font-size: 18px; }
  .persona-card p { font-size: 13px; }
  .persona-card .ic { width: 48px; height: 48px; border-radius: 14px; }
  .persona-bar button { padding: 7px 12px; font-size: 11px; }
  .admin-stage .desktop { height: auto; min-height: 70vh; }
}

/* Petit mobile (≤ 380px) : compression supplémentaire pour ne pas couper */
@media (max-width: 380px) {
  .launcher-title,
  .launcher-title-anim,
  .sunu-onas-html-title {
    font-size: clamp(30px, 10vw, 50px) !important;
  }
  .launcher-logo img { width: 64px !important; }
  .launcher { padding: 36px 12px 48px; gap: 22px; }
}

/* ===========================================================
   Mobile real device — edge-to-edge real app behavior
   On combine 3 critères pour capter TOUS les vrais mobiles :
     • largeur ≤ 900px (téléphones + tablettes en portrait)
     • pointeur grossier + pas de hover (vrais écrans tactiles)
     • PWA / TWA en standalone (app installée)
   Tout ça dans un même bloc via la syntaxe CSS3 (postlist coalescée).
   =========================================================== */

/* ----- Sélecteurs mobile-fullscreen, factorisés ----- */
@media (max-width: 900px),
       (hover: none) and (pointer: coarse),
       (display-mode: standalone) {

  /* Stage : retire le centrage / le padding qui faisait apparaître
     le téléphone comme une preview au milieu d'un fond bleu. */
  .mobile-stage {
    min-height: 100vh !important;
    height: 100vh !important;
    width: 100vw !important;
    max-width: 100vw !important;
    display: block !important;
    align-items: stretch !important;
    justify-content: stretch !important;
    padding: 0 !important;
    margin: 0 !important;
    position: fixed !important;
    inset: 0 !important;
    z-index: 1 !important;
    background: white !important;
    overflow: auto !important;
  }
  .mobile-stage .phone {
    flex: 1 1 auto !important;
  }

  /* Plus de frame iPhone décorative */
  .phone {
    width: 100vw !important;
    height: 100vh !important;
    min-height: 100vh !important;
    max-width: 100vw !important;
    background: white !important;
    border-radius: 0 !important;
    border: none !important;
    padding: 0 !important;
    box-shadow: none !important;
    margin: 0 !important;
    position: relative !important;
  }
  .phone-screen {
    border-radius: 0 !important;
    width: 100% !important;
    height: 100% !important;
    min-height: 100vh !important;
    overflow-y: auto !important;
    background: var(--bg) !important;
  }

  /* Encoche : retirée */
  .phone::after,
  .phone::before { display: none !important; }

  /* Persona-bar + dev-controls cachés sur vrai mobile */
  .persona-bar, .dev-controls { display: none !important; }

  /* Safe-area iOS / Android pour la status bar et home indicator */
  .phone-screen {
    padding-top: env(safe-area-inset-top, 0);
    padding-bottom: env(safe-area-inset-bottom, 0);
    padding-left: env(safe-area-inset-left, 0);
    padding-right: env(safe-area-inset-right, 0);
  }

  /* Le fond bleu de la persona-bar n'est plus utile : forcer body en blanc
     pour que le bottom safe-area ne révèle pas de couleur */
  body { background: white !important; }
}

/* Mobile mode standalone (PWA / TWA installée) — alias spécifique
   pour conserver la règle même si la breakpoint width n'est pas atteinte */
@media (display-mode: standalone) {
  .launcher { display: none !important; }
  /* On force aussi à charger usager.html en plein écran natif */
}
