/* GeoPresence — charte graphique dérivée du logo (docs/logo.jpeg).
   Bleu/marine + vert uniquement. Pas de violet, pas de dégradé générique. */

:root {
  --gp-navy: #0A1E45;
  --gp-navy-deep: #071233;
  /* Aligné sur --nav-accent (barre de navigation) : même bleu de marque
     partout dans l'app, pas deux bleus différents entre la nav et le reste. */
  --gp-blue: #2C5CE0;
  --gp-blue-bright: #4A72E8;
  --gp-green: #16C74E;
  --gp-green-deep: #0FA23D;
  --gp-amber: #B7791F;
  --gp-amber-bg: #FFFAEB;
  --gp-red: #DC2626;
  --gp-red-bg: #FEF2F2;
  /* Accent réservé aux actions importantes / indicateurs clés qui demandent
     une action (ex. badge "à valider") — jamais utilisé pour du décoratif,
     et distinct de l'ambre (--gp-amber) qui reste la couleur d'avertissement
     neutre (ex. "Retard"). */
  --gp-orange: #F97316;
  --gp-orange-deep: #C2410C;
  --gp-orange-bg: #FFF7ED;

  --gp-ink: #101828;
  --gp-gray-700: #344054;
  --gp-gray-600: #475467;
  --gp-gray-400: #98A2B3;
  --gp-gray-200: #E4E7EC;
  --gp-gray-100: #F2F4F7;
  --gp-gray-50: #F8FAFC;
  --gp-white: #FFFFFF;

  /* Texte lisible sur les éléments d'accent (boutons, avatars). Tokens de
     navigation (--nav-*) : définis sur .gp-app-body, cf. plus bas — suit
     maintenant le mode sombre comme le reste de l'app (cf. bloc
     [data-bs-theme="dark"] .gp-app-body). */
  --gp-accent-text: #FFFFFF;

  --gp-radius: 12px;
  --gp-shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.10);
  --gp-shadow-lg: 0 8px 24px rgba(10, 30, 69, 0.12);
  --gp-focus-ring: 0 0 0 3px rgba(11, 99, 246, 0.35);
}

/* Mode sombre (RM-UI-THEME, 18/08/2026) — activé via l'attribut natif
   data-bs-theme sur <html> (posé par templates/core/_theme_init.html) :
   Bootstrap applique automatiquement son propre habillage sombre aux
   composants natifs (form-control, dropdown-menu, alert...) sur cet
   attribut, on branche donc notre propre système de jetons dessus plutôt
   que d'inventer un attribut séparé à garder synchronisé. Inversion
   sémantique assumée : --gp-navy (normalement texte sombre sur fond clair)
   devient un ton clair, --gp-white (normalement fond clair) devient un fond
   sombre — tout le reste de l'app référence déjà exclusivement ces
   variables, donc ce seul bloc suffit à retourner la quasi-totalité des
   écrans sans les toucher un par un. */
[data-bs-theme="dark"] {
  --gp-navy: #E4E9F5;
  --gp-navy-deep: #FFFFFF;
  --gp-blue: #6C8EEB;
  --gp-blue-bright: #8DA8F0;
  --gp-green: #2FE070;
  --gp-green-deep: #4ADE80;
  --gp-amber: #F0B858;
  --gp-amber-bg: #3A2E10;
  --gp-red: #F87171;
  --gp-red-bg: #3A1418;
  --gp-orange: #FB923C;
  --gp-orange-deep: #FDBA74;
  --gp-orange-bg: #3A2410;
  --gp-ink: #F1F4F9;
  --gp-gray-700: #D0D5DD;
  --gp-gray-600: #98A2B3;
  --gp-gray-400: #667085;
  --gp-gray-200: #2A3350;
  --gp-gray-100: #1B2340;
  --gp-gray-50: #141A33;
  --gp-white: #0E1330;
  --gp-shadow: 0 1px 2px rgba(0, 0, 0, 0.24), 0 1px 3px rgba(0, 0, 0, 0.32);
  --gp-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.45);
  --gp-focus-ring: 0 0 0 3px rgba(108, 142, 235, 0.4);
  color-scheme: dark;
}
[data-bs-theme="dark"] body { background: var(--gp-white); }
/* La sidebar/barre du haut/barre d'onglets étaient volontairement en thème
   clair fixe (cf. commentaire plus bas) — elles suivent maintenant le mode
   sombre comme le reste de l'app, la bascule étant désormais une vraie
   préférence utilisateur et non plus un détail d'implémentation interne. */
[data-bs-theme="dark"] .gp-app-body {
  --nav-accent: #6C8EEB;
  --nav-accent-soft: rgba(108, 142, 235, 0.14);
  --nav-accent-soft-strong: rgba(108, 142, 235, 0.2);
  --nav-accent-border: rgba(108, 142, 235, 0.32);
  --nav-ink: #E4E9F5;
  --nav-text: #C3CADA;
  --nav-text-soft: #8B93A7;
  --nav-text-faint: #667085;
  --nav-bg: #0E1330;
  --nav-bg-soft: #1B2340;
  --nav-border: #2A3350;
  --nav-red: #F87171;
}

body {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--gp-ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Anneau de focus clavier cohérent (WCAG 2.2 §2.4.11) — remplace le contour
   par défaut, très inégal d'un navigateur à l'autre, sur tous les éléments
   interactifs custom qui n'ont pas déjà leur propre style de focus. */
.gp-btn:focus-visible,
.gp-navbar-link:focus-visible,
.gp-navbar-brand:focus-visible,
.gp-navbar-avatar-btn:focus-visible,
.gp-navbar-menu .dropdown-item:focus-visible,
.gp-bottomnav-link:focus-visible,
.gp-row-action-btn:focus-visible,
.gp-row-link:focus-visible,
.gp-chat-suggestion-btn:focus-visible,
.gp-pagination a:focus-visible,
.gp-footer-col a:focus-visible,
.gp-home-action-card:focus-visible,
.gp-sidebar-brand:focus-visible,
.gp-sidebar-link:focus-visible,
.gp-sidebar-profile-link:focus-visible,
.gp-sidebar-logout-btn:focus-visible {
  outline: none;
  box-shadow: var(--gp-focus-ring);
  border-radius: 6px;
}

/* ---------- Navbar applicative (pages internes) ---------- */
.gp-app-navbar {
  background: var(--gp-white);
  border-bottom: 1px solid var(--gp-gray-200);
}
.gp-app-navbar .navbar-brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  color: var(--gp-navy) !important;
}
.gp-app-navbar .navbar-brand img {
  height: 28px;
  width: auto;
}
.gp-app-navbar .navbar-text {
  color: var(--gp-gray-600) !important;
}

/* Boutons primaires : bleu de marque plutôt que le bleu Bootstrap par défaut. */
.btn-primary {
  background-color: var(--gp-blue);
  border-color: var(--gp-blue);
}
.btn-primary:hover, .btn-primary:focus {
  background-color: #094fc4;
  border-color: #094fc4;
}
.btn-outline-primary {
  color: var(--gp-blue);
  border-color: var(--gp-blue);
}
.btn-outline-primary:hover {
  background-color: var(--gp-blue);
  border-color: var(--gp-blue);
}
a {
  color: var(--gp-blue);
}

/* ================= Page d'accueil publique ================= */

/* Identité typographique propre à la vitrine publique (pas de fuite vers le
   reste de l'app, qui reste Inter seul) — Unbounded pour les titres, une
   géométrique large plus affirmée qu'Inter, JetBrains Mono pour les repères
   courts (eyebrow, kicker, numéros d'étape), en écho direct au sujet du
   produit : coordonnées GPS, précision, lecture de capteur. */
.gp-landing {
  overflow-x: hidden;
  --gp-font-display: "Unbounded", "Inter", sans-serif;
  --gp-font-mono: "JetBrains Mono", ui-monospace, monospace;
  --gp-tint: #EEF3FF;
}
[data-bs-theme="dark"] .gp-landing { --gp-tint: #131B36; }

.gp-nav {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--gp-gray-200);
}
[data-bs-theme="dark"] .gp-nav { background: rgba(14, 19, 48, 0.86); }
.gp-nav-inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0.85rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.gp-brand {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--gp-navy);
  text-decoration: none;
}
.gp-brand img { height: 30px; width: auto; }
.gp-nav-links {
  display: flex;
  align-items: center;
  gap: 1.75rem;
}
.gp-nav-links a {
  color: var(--gp-gray-700);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 500;
}
.gp-nav-links a:hover { color: var(--gp-navy); }

.gp-nav-actions { display: flex; align-items: center; gap: 0.75rem; }
.gp-theme-toggle-btn {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px;
  border-radius: 999px;
  background: var(--gp-gray-100);
  border: 1px solid var(--gp-gray-200);
  color: var(--gp-gray-700);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.gp-theme-toggle-btn:hover { background: var(--gp-gray-200); color: var(--gp-navy); }

.gp-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.6rem 1.3rem;
  border-radius: 8px;
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.08s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
.gp-btn-primary {
  background: var(--gp-blue);
  color: var(--gp-accent-text);
  box-shadow: var(--gp-shadow);
}
.gp-btn-primary:hover { background: color-mix(in srgb, var(--gp-blue) 80%, black); color: var(--gp-accent-text); }
.gp-btn-ghost {
  background: transparent;
  color: var(--gp-navy);
  border-color: var(--gp-gray-200);
}
.gp-btn-ghost:hover { background: var(--gp-gray-50); color: var(--gp-navy); }
.gp-btn-lg { padding: 0.85rem 1.75rem; font-size: 1.02rem; border-radius: 10px; }

/* ---------- Hero ---------- */
/* Bleu clair texturé — ni dégradé, ni aplat uni, ni bleu sombre. La grille de
   points reprend exactement le motif de .gp-mock-map plus bas (le même
   "papier millimétré GPS" que la carte du mockup) : un vrai choix ancré dans
   le sujet du produit, pas une texture décorative arbitraire. Couleurs
   fixes (pas var(--gp-*)) : ce bandeau reste dans cette teinte claire dans
   les deux thèmes, cf. bloc [data-bs-theme="dark"] plus bas. */
.gp-hero {
  background-color: #E4ECFF;
  background-image: radial-gradient(circle, #C9DBFA 1.5px, transparent 1.5px);
  background-size: 20px 20px;
  padding: 4.5rem 0 5rem;
}
.gp-hero-inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 1.5rem;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 3rem;
  align-items: center;
}
@media (max-width: 900px) {
  .gp-hero-inner { grid-template-columns: 1fr; text-align: center; }
  .gp-hero-visual { order: -1; }
}

.gp-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: rgba(10, 30, 69, 0.05);
  color: #0A1E45;
  border: 1px solid rgba(10, 30, 69, 0.12);
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  font-family: var(--gp-font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.gp-eyebrow .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--gp-green); display: inline-block; }

.gp-hero h1 {
  font-family: var(--gp-font-display);
  font-size: 2.6rem;
  line-height: 1.18;
  font-weight: 700;
  color: #0A1E45;
  margin: 1.25rem 0 1.25rem;
  letter-spacing: -0.01em;
}
.gp-hero h1 .accent { color: #2C5CE0; }
@media (max-width: 560px) { .gp-hero h1 { font-size: 2rem; } }

.gp-hero p.lead {
  font-size: 1.12rem;
  color: #475467;
  max-width: 46ch;
  margin-bottom: 1.75rem;
}
@media (max-width: 900px) { .gp-hero p.lead { margin-left: auto; margin-right: auto; } }

.gp-hero-ctas { display: flex; gap: 0.85rem; flex-wrap: wrap; }
@media (max-width: 900px) { .gp-hero-ctas { justify-content: center; } }
.gp-hero .gp-btn-ghost { color: #0A1E45; border-color: rgba(10, 30, 69, 0.18); }
.gp-hero .gp-btn-ghost:hover { background: rgba(10, 30, 69, 0.05); color: #0A1E45; }

.gp-trust-row {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  margin-top: 2rem;
  color: #475467;
  font-size: 0.88rem;
}
.gp-trust-row span { display: flex; align-items: flex-start; gap: 0.5rem; }
.gp-trust-row svg { flex: none; color: var(--gp-green); margin-top: 0.15rem; }
@media (max-width: 900px) { .gp-trust-row span { justify-content: center; } }

/* ---------- Mockup visuel du hero (pas une capture, une illustration fidèle) ----------
   Fond fixe (#FFFFFF, pas var(--gp-white)) : cette carte représente un écran
   d'appareil, comme une capture — elle ne doit pas s'inverser avec le thème,
   un téléphone ne change pas de couleur quand on bascule le mode sombre. */
.gp-mock {
  background: #FFFFFF;
  border: 1px solid var(--gp-gray-200);
  border-radius: 20px;
  box-shadow: 0 30px 70px -20px rgba(2, 8, 30, 0.55);
  padding: 1.1rem;
  max-width: 380px;
  margin: 0 auto;
  animation: gp-mock-float 6s ease-in-out infinite;
}
/* Flottement continu très léger — la carte "respire" au lieu de rester
   figée, comme les visuels de héros des sites premium (ex. stripe.com). */
@keyframes gp-mock-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
@media (prefers-reduced-motion: reduce) { .gp-mock { animation: none; } }
.gp-mock-map {
  position: relative;
  height: 220px;
  border-radius: 14px;
  background-color: #EAF1FF;
  background-image:
    radial-gradient(circle, #C9DBFA 1px, transparent 1px);
  background-size: 16px 16px;
  overflow: hidden;
}
.gp-mock-coords {
  position: absolute;
  top: 10px; left: 10px;
  z-index: 1;
  background: rgba(10, 30, 69, 0.85);
  color: #B9C4DA;
  font-family: var(--gp-font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.01em;
  padding: 0.2rem 0.5rem;
  border-radius: 6px;
}
.gp-mock-zone {
  position: absolute;
  top: 50%; left: 50%;
  width: 168px; height: 168px;
  border-radius: 50%;
  border: 2px dashed var(--gp-blue-bright);
  background: rgba(11, 99, 246, 0.08);
  transform: translate(-50%, -50%);
}
/* Deuxième anneau, purement décoratif, qui pulse doucement pour suggérer une
   zone "en direct" — signature visuelle du hero, un seul endroit sur toute
   la vitrine publique où ce mouvement d'ambiance apparaît. */
.gp-mock-zone-pulse { animation: gp-zone-pulse 2.8s ease-out infinite; }
@keyframes gp-zone-pulse {
  0% { width: 168px; height: 168px; opacity: 0.5; }
  100% { width: 260px; height: 260px; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .gp-mock-zone-pulse { animation: none; display: none; } }
.gp-mock-pin {
  position: absolute;
  top: 50%; left: 50%;
  width: 46px; height: auto;
  transform: translate(-50%, -66%);
  filter: drop-shadow(0 4px 6px rgba(10,30,69,.25));
}
/* Couleurs fixes sur .gp-mock-radius-label/-result(-text) : toujours dans le
   même illustration figée en clair que .gp-mock/.gp-mock-map, cf. plus haut. */
.gp-mock-radius-label {
  position: absolute;
  bottom: 10px; left: 10px;
  background: #FFFFFF;
  border: 1px solid #E4E7EC;
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
  font-family: var(--gp-font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  color: #344054;
}
.gp-mock-result {
  margin-top: 1rem;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  background: #F0FDF4;
  border: 1px solid #BBF0CE;
  border-radius: 12px;
  padding: 0.75rem 0.9rem;
}
.gp-mock-check {
  flex: none;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: #16C74E;
  display: flex; align-items: center; justify-content: center;
}
.gp-mock-result-text { line-height: 1.25; }
.gp-mock-result-text strong { display: block; color: #101828; font-size: 0.92rem; }
.gp-mock-result-text span { color: #475467; font-size: 0.8rem; }

/* ---------- Sections génériques ---------- */
.gp-section {
  max-width: 1180px;
  margin: 0 auto;
  padding: 4.5rem 1.5rem;
}
/* Bande alternée pour casser la monotonie du blanc répété section après
   section — pleine largeur ; le contenu direct retrouve le padding latéral
   perdu en même temps que le max-width du parent. */
.gp-tint { background: var(--gp-tint); max-width: none; padding-left: 0; padding-right: 0; }
.gp-tint > .gp-section-head { padding: 0 1.5rem; }
.gp-tint > .gp-how-grid { max-width: 1180px; margin-left: auto; margin-right: auto; padding: 0 1.5rem; }
.gp-section-head {
  max-width: 640px;
  margin: 0 auto 3rem;
  text-align: center;
}
.gp-kicker {
  display: inline-block;
  color: var(--gp-blue);
  font-family: var(--gp-font-mono);
  font-weight: 600;
  font-size: 0.76rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.gp-section-head h1,
.gp-section-head h2 {
  font-family: var(--gp-font-display);
  font-size: 1.9rem;
  font-weight: 700;
  color: var(--gp-navy);
  margin: 0.6rem 0 0.75rem;
  letter-spacing: -0.005em;
  line-height: 1.25;
}
.gp-section-head p { color: var(--gp-gray-600); font-size: 1.02rem; }

/* ---------- Aperçu produit (vraie capture d'écran, pas un mockup) ---------- */
.gp-preview-frame {
  max-width: 1100px; margin: 0 auto; border-radius: 14px; overflow: hidden;
  border: 1px solid var(--gp-gray-200); background: var(--gp-white);
  box-shadow: 0 24px 60px -12px rgba(10, 30, 69, 0.18);
}
.gp-preview-bar { display: flex; align-items: center; gap: 6px; padding: 0.7rem 0.9rem; background: var(--gp-gray-50); border-bottom: 1px solid var(--gp-gray-200); }
.gp-preview-dot { width: 10px; height: 10px; border-radius: 50%; background: #ED6A5E; }
.gp-preview-dot:nth-child(2) { background: #F4BF4F; }
.gp-preview-dot:nth-child(3) { background: #61C554; }
.gp-preview-img { display: block; width: 100%; height: auto; }

/* ---------- How it works ---------- */
.gp-how-grid { display: grid; grid-template-columns: 1fr auto; gap: 3.5rem; align-items: center; }
@media (max-width: 900px) { .gp-how-grid { grid-template-columns: 1fr; justify-items: center; gap: 2.5rem; } }

.gp-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
}
@media (max-width: 800px) { .gp-steps { grid-template-columns: 1fr; } }
.gp-how-grid .gp-steps { grid-template-columns: 1fr; gap: 1.75rem; }

/* Couleurs fixes (bezel de téléphone) : même raison que .gp-hero/.gp-mock. */
.gp-phone-frame {
  position: relative; flex: none; width: 250px;
  background: #0A1E45; border-radius: 34px;
  padding: 22px 9px 9px;
  box-shadow: 0 24px 50px -14px rgba(10, 30, 69, 0.35);
}
.gp-phone-notch {
  position: absolute; top: 8px; left: 50%; transform: translateX(-50%);
  width: 60px; height: 16px; background: #071233; border-radius: 10px;
}
.gp-phone-img { display: block; width: 100%; height: auto; border-radius: 22px; }
.gp-step-num {
  display: inline-block;
  font-family: var(--gp-font-mono);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--gp-blue);
  letter-spacing: 0.02em;
  margin-bottom: 0.6rem;
}
.gp-step h3 { font-size: 1.1rem; font-weight: 700; color: var(--gp-navy); margin-bottom: 0.4rem; }
.gp-step p { color: var(--gp-gray-600); font-size: 0.95rem; margin: 0; }

/* ---------- Features grid ---------- */
.gp-features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}
@media (max-width: 900px) { .gp-features { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .gp-features { grid-template-columns: 1fr; } }

.gp-card {
  background: var(--gp-white);
  border: 1px solid var(--gp-gray-200);
  border-top: 2px solid var(--gp-blue);
  border-radius: var(--gp-radius);
  padding: 1.5rem;
}
/* Le survol "carte qui se soulève" reste réservé à la vitrine publique (page
   d'accueil) où c'est un choix éditorial délibéré — appliqué globalement, il
   ferait aussi bouger les cartes de contenu statique du dashboard/formulaires
   (pas cliquables), ce qui distrait sans raison (cf. consigne micro-interactions). */
.gp-features .gp-card { transition: box-shadow 0.15s ease, transform 0.15s ease; }
.gp-features .gp-card:hover { box-shadow: var(--gp-shadow-lg); transform: translateY(-2px); }
/* Icône nue, sans pastille carrée — l'habillage "icône dans un carré pâle
   arrondi" est le tell visuel le plus reconnaissable d'une page SaaS
   générée par IA, on l'évite délibérément ici. */
.gp-card-icon {
  width: 30px; height: 30px;
  color: var(--gp-blue);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 1rem;
}
.gp-card-icon svg { width: 28px; height: 28px; }
.gp-card h3 { font-size: 1.02rem; font-weight: 700; color: var(--gp-navy); margin-bottom: 0.4rem; }
.gp-card p { color: var(--gp-gray-600); font-size: 0.9rem; margin: 0; }

/* ---------- Secteurs (pills) ---------- */
.gp-pills { display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: center; }
.gp-pill {
  background: var(--gp-white);
  border: 1px solid var(--gp-gray-200);
  border-radius: 999px;
  padding: 0.45rem 1rem;
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--gp-gray-700);
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease;
}
a.gp-pill:hover, a.gp-pill:focus-visible {
  border-color: var(--gp-blue);
  color: var(--gp-blue);
}

/* ---------- Sécurité ---------- */
.gp-security {
  background: var(--gp-gray-50);
  border-top: 1px solid var(--gp-gray-200);
  border-bottom: 1px solid var(--gp-gray-200);
}
.gp-security-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3rem;
  align-items: center;
}
@media (max-width: 800px) { .gp-security-grid { grid-template-columns: 1fr; } }
.gp-security-grid h2 {
  font-family: var(--gp-font-display); font-size: 1.9rem; font-weight: 700;
  color: var(--gp-navy); line-height: 1.25;
}
.gp-security ul { list-style: none; padding: 0; margin: 1.25rem 0 0; }
.gp-security li {
  display: flex; align-items: flex-start; gap: 0.65rem;
  padding: 0.55rem 0;
  color: var(--gp-gray-700);
  font-size: 0.95rem;
}
.gp-security li svg { flex: none; color: var(--gp-green); margin-top: 0.15rem; }

/* ---------- CTA finale (couleurs fixes, même raison que .gp-hero) ---------- */
.gp-cta-band {
  background: #0A1E45;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 24px;
  max-width: 1180px;
  margin: 0 auto 5rem;
  padding: 3.5rem 2rem;
  text-align: center;
  color: #FFFFFF;
}
.gp-cta-band h2 { font-family: var(--gp-font-display); font-size: 1.7rem; font-weight: 700; margin-bottom: 0.6rem; }
.gp-cta-band p { color: #B9C4DA; margin-bottom: 1.75rem; }

/* ---------- Footer ---------- */
.gp-footer {
  border-top: 1px solid var(--gp-gray-200);
  padding: 3rem 1.5rem 2rem;
}
.gp-footer-inner {
  max-width: 1180px;
  margin: 0 auto;
}
.gp-footer-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: 2rem;
  padding-bottom: 2rem;
}
.gp-footer-brand { display: flex; align-items: center; gap: 0.5rem; color: var(--gp-navy); font-weight: 700; }
.gp-footer-brand img { height: 22px; }
.gp-footer-tagline { color: var(--gp-gray-400); font-size: 0.9rem; margin: 0.75rem 0 0; max-width: 26rem; }
.gp-footer-col h4 { font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--gp-navy); margin-bottom: 0.9rem; }
.gp-footer-col { display: flex; flex-direction: column; gap: 0.6rem; }
.gp-footer-col a { color: var(--gp-gray-400); font-size: 0.9rem; text-decoration: none; }
.gp-footer-col a:hover { color: var(--gp-navy); }
.gp-footer-col button {
  background: none; border: none; padding: 0; margin: 0; text-align: left;
  color: var(--gp-gray-400); font-size: 0.9rem; font-family: inherit; cursor: pointer;
}
.gp-footer-col button:hover { color: var(--gp-navy); }

/* ---------- Révélation au défilement (JS : voir _landing_base.html) ----------
   Un seul mouvement, jamais répété au-delà de la première apparition (pas de
   re-déclenchement en remontant, cf. consigne micro-interactions). Courbe
   "ease-out-expo" et légère mise à l'échelle plutôt qu'un simple fondu
   linéaire : rythme plus posé, dans l'esprit du défilement de stripe.com,
   sans reprendre ses formes ni ses couleurs. */
.gp-reveal {
  opacity: 0;
  transform: translateY(22px) scale(0.985);
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
.gp-reveal.is-visible { opacity: 1; transform: translateY(0) scale(1); }
.gp-reveal[data-reveal-delay="1"] { transition-delay: 0.1s; }
.gp-reveal[data-reveal-delay="2"] { transition-delay: 0.2s; }
@media (prefers-reduced-motion: reduce) {
  .gp-reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------- Bandeau de consentement cookies (Google Analytics) ---------- */
.gp-consent-banner {
  position: fixed; left: 1rem; right: 1rem; bottom: 1rem; z-index: 1000;
  max-width: 760px; margin: 0 auto;
  background: #0A1E45; color: rgba(255, 255, 255, 0.9);
  border-radius: 14px; padding: 1.1rem 1.4rem;
  box-shadow: 0 24px 60px -12px rgba(10, 30, 69, 0.4);
  display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.5rem;
}
.gp-consent-banner p { margin: 0; font-size: 0.88rem; line-height: 1.5; flex: 1 1 380px; }
.gp-consent-banner a { color: #FFFFFF; text-decoration: underline; }
.gp-consent-actions { display: flex; gap: 0.6rem; flex-shrink: 0; }
.gp-consent-banner .gp-btn-ghost {
  border-color: rgba(255, 255, 255, 0.3); color: #FFFFFF;
}
.gp-consent-banner .gp-btn-ghost:hover { border-color: rgba(255, 255, 255, 0.6); }
@media (max-width: 560px) {
  .gp-consent-banner { flex-direction: column; align-items: stretch; }
  .gp-consent-actions { justify-content: flex-end; }
}
.gp-footer-bottom {
  border-top: 1px solid var(--gp-gray-200);
  padding-top: 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
}
.gp-footer-bottom p { color: var(--gp-gray-400); font-size: 0.85rem; margin: 0; }
@media (max-width: 720px) {
  .gp-footer-grid { grid-template-columns: 1fr 1fr; }
}

/* ---------- Pages légales / FAQ (contenu texte simple) ---------- */
.gp-legal {
  max-width: 800px;
  margin: 0 auto;
  padding: 3.5rem 1.5rem 4rem;
  color: var(--gp-gray-600);
  line-height: 1.7;
}
.gp-legal h1 { color: var(--gp-navy); font-size: 2rem; font-weight: 800; margin-bottom: 0.5rem; }
.gp-legal .gp-legal-updated { color: var(--gp-gray-400); font-size: 0.9rem; margin-bottom: 2.5rem; }
.gp-legal h2 { color: var(--gp-navy); font-size: 1.25rem; font-weight: 700; margin: 2rem 0 0.75rem; }
.gp-legal p, .gp-legal li { margin-bottom: 0.75rem; }
.gp-legal ul { padding-left: 1.25rem; }
.gp-faq-item { border-bottom: 1px solid var(--gp-gray-200); padding: 1.5rem 0; }
.gp-faq-item:first-child { padding-top: 0; }
.gp-faq-item h2 { margin: 0 0 0.6rem; font-size: 1.05rem; }

/* ================= Pages d'authentification (login, reset...) ================= */

.gp-auth-page { min-height: 100vh; background: var(--gp-white); }

.gp-auth-shell { min-height: 100vh; display: flex; }

/* ---- Panneau de marque (visible à partir de 960px, façon Facebook/Stripe) ----
   Couleurs fixes, même raison que .gp-hero : ce panneau reste sombre dans les
   deux thèmes. ---- */
.gp-auth-aside {
  display: none;
  position: relative;
  flex: 0 0 42%;
  max-width: 560px;
  padding: 3rem;
  background: #0A1E45;
  color: #FFFFFF;
  overflow: hidden;
}
@media (min-width: 960px) {
  .gp-auth-aside { display: flex; flex-direction: column; justify-content: space-between; }
}

.gp-auth-aside-logo {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
  color: #FFFFFF;
  font-weight: 800;
  font-size: 1.1rem;
}
.gp-auth-aside-logo img { height: 34px; width: auto; }

.gp-auth-aside-content { max-width: 380px; }

/* Illustration géofencing — flat, pas de dégradé/glow, rattachée au produit. */
.gp-auth-geofence { position: relative; width: 84px; height: 84px; margin-bottom: 2.25rem; }
.gp-auth-geofence-ring {
  position: absolute;
  inset: 0;
  border: 2px dashed rgba(255, 255, 255, 0.3);
  border-radius: 50%;
}
.gp-auth-geofence-pin {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--gp-blue-bright);
  color: #0A1E45;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gp-auth-aside-content h2 {
  font-size: 1.9rem;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 0 0 0.85rem;
}
.gp-auth-aside-content p {
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.98rem;
  line-height: 1.55;
  margin-bottom: 1.75rem;
}

.gp-auth-aside-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.85rem; }
.gp-auth-aside-list li {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: 0.92rem;
  color: rgba(255, 255, 255, 0.9);
}
.gp-auth-check {
  flex: none;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: rgba(22, 199, 78, 0.18);
  color: var(--gp-green);
  display: flex; align-items: center; justify-content: center;
}

.gp-auth-aside-foot { font-size: 0.82rem; color: rgba(255, 255, 255, 0.5); }

/* ---- Panneau formulaire ---- */
.gp-auth-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2.5rem 1.5rem;
}

.gp-auth-card { width: 100%; max-width: 380px; }

.gp-auth-logo-mobile {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  margin-bottom: 2rem;
}
.gp-auth-logo-mobile img { height: 40px; width: auto; }
.gp-auth-logo-mobile span { font-weight: 800; font-size: 1.1rem; color: var(--gp-navy); }
@media (min-width: 960px) { .gp-auth-logo-mobile { display: none; } }

.gp-auth-logo-mobile-row { margin-bottom: 0.5rem; }
.gp-auth-topbar { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 1.25rem; }
.gp-lang-switch { margin-bottom: 0; }
.gp-lang-switch select { width: auto; min-width: 140px; display: inline-block; }

.gp-auth-title {
  font-size: 1.6rem;
  font-weight: 800;
  color: var(--gp-navy);
  letter-spacing: -0.02em;
  margin-bottom: 0.4rem;
}
.gp-auth-subtitle {
  color: var(--gp-gray-600);
  font-size: 0.94rem;
  line-height: 1.5;
  margin-bottom: 2rem;
}

/* ---- Champs ---- */
.gp-auth-card .form-label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--gp-gray-700);
  margin-bottom: 0.4rem;
}
.gp-auth-card .form-control {
  height: 48px;
  padding: 0.6rem 1rem;
  font-size: 0.96rem;
  border: 1.5px solid var(--gp-gray-200);
  border-radius: 10px;
  background: var(--gp-gray-50);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.gp-auth-card .form-control:focus {
  border-color: var(--gp-blue);
  background: var(--gp-white);
  box-shadow: 0 0 0 4px rgba(11, 99, 246, 0.12);
}
.gp-auth-card .mb-3 { margin-bottom: 1.15rem !important; }

.gp-pass-wrap { position: relative; }
.gp-pass-wrap .form-control { padding-right: 2.75rem; }
.gp-pass-toggle {
  position: absolute;
  top: 50%; right: 0.6rem;
  transform: translateY(-50%);
  display: flex;
  border: none;
  background: transparent;
  color: var(--gp-gray-400);
  cursor: pointer;
  padding: 0.3rem;
  border-radius: 6px;
  line-height: 0;
}
.gp-pass-toggle:hover { color: var(--gp-gray-700); }
.gp-pass-toggle.is-visible { color: var(--gp-blue); }

/* ---- Bouton ---- */
.gp-auth-card .btn-primary {
  height: 48px;
  border-radius: 10px;
  font-weight: 600;
  font-size: 0.98rem;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
  transition: background-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}
.gp-auth-card .btn-primary:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(11, 99, 246, 0.25); }
.gp-auth-card .btn-primary:active { transform: translateY(0); }

.gp-auth-label-row { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; }
.gp-auth-forgot { font-size: 0.85rem; color: var(--gp-blue); font-weight: 600; text-decoration: none; white-space: nowrap; }
.gp-auth-forgot:hover { text-decoration: underline; }

.gp-auth-footer { text-align: center; margin-top: 1.75rem; font-size: 0.85rem; color: var(--gp-gray-600); }
.gp-auth-footer a { color: var(--gp-blue); font-weight: 600; text-decoration: none; }
.gp-auth-footer a:hover { text-decoration: underline; }
@media (min-width: 960px) { .gp-auth-footer-mobile { display: none; } }

.gp-auth-icon-circle {
  width: 56px; height: 56px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 1.25rem;
}
.gp-auth-icon-circle.success { background: #F0FDF4; color: var(--gp-green); }
.gp-auth-icon-circle.info { background: var(--gp-gray-100); color: var(--gp-blue); }
.gp-auth-icon-circle.danger { background: #FEF2F2; color: #DC2626; }

/* ================= Application interne (shell + composants) ================= */

.gp-app-body { background: var(--gp-gray-50); min-height: 100vh; }

.gp-shell { display: flex; min-height: 100vh; }

/* ---------- Navigation. RM-UI-NAV-DESKTOP (18/08/2026) : sidebar verticale
   fixe sur desktop (≥992px), barre du haut compacte + barre d'onglets sur
   mobile (<992px, inchangées). Tokens --nav-* partagés par les trois, posés
   sur .gp-app-body (ancêtre commun) plutôt que dupliqués : le reste de l'app
   (dashboard, cartes, formulaires, tableaux) continue d'utiliser
   --gp-navy/--gp-blue partagés sans aucun changement. Aucune couleur par
   organisation (cf. décision produit) : --nav-accent est une constante
   GeoPresence, jamais une donnée tenant. */
.gp-app-body {
  --nav-accent: #2C5CE0;
  --nav-accent-soft: rgba(44, 92, 224, 0.07);
  --nav-accent-soft-strong: rgba(44, 92, 224, 0.1);
  --nav-accent-border: rgba(44, 92, 224, 0.16);
  --nav-ink: #0A1E45;
  --nav-text: #334155;
  --nav-text-soft: #64748B;
  --nav-text-faint: #94A3B8;
  --nav-bg: #FFFFFF;
  --nav-bg-soft: #F8FAFC;
  --nav-border: #E2E8F0;
  --nav-red: #DC3545;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* ---------- Sidebar desktop (≥992px uniquement — masquée sur mobile/tablette,
   où .gp-navbar + .gp-bottomnav prennent le relais sans aucun changement).
   Largeur fixe, position fixed (hors du flux) : .gp-titlebar/.gp-content
   compensent avec un margin-left égal à cette largeur, cf. plus bas. ---------- */
.gp-sidebar { display: none; }
@media (min-width: 992px) {
  .gp-sidebar {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 264px;
    background: var(--nav-bg);
    border-right: 1px solid var(--nav-border);
    z-index: 30;
    overflow-y: auto;
  }
  .gp-navbar { display: none; }
}
[dir="rtl"] .gp-sidebar { left: auto; right: 0; border-right: none; border-left: 1px solid var(--nav-border); }

.gp-sidebar-brand {
  flex: none;
  display: flex; align-items: center; gap: 0.65rem;
  padding: 1.35rem 1.25rem 1rem;
  text-decoration: none;
}
.gp-sidebar-brand img { height: 30px; width: auto; flex: none; }
.gp-sidebar-brand-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.gp-sidebar-brand-name { font-weight: 800; font-size: 1rem; color: var(--nav-ink); letter-spacing: -0.01em; }
.gp-sidebar-brand-tagline { font-size: 0.7rem; color: var(--nav-text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Organisation active : simple repère de contexte, teinte bleue fixe
   GeoPresence — jamais dérivée de l'organisation (cf. décision produit,
   même règle que l'ancienne pastille de la barre du haut). */
.gp-sidebar-org {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 0.4rem;
  margin: 0 1.25rem 1.1rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  background: var(--nav-accent-soft-strong);
  border: 1px solid var(--nav-accent-border);
  color: var(--nav-ink); font-weight: 700; font-size: 0.8rem;
  max-width: calc(100% - 2.5rem);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gp-sidebar-org-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--nav-accent); }
.gp-sidebar-org-platform { background: var(--nav-bg-soft); border-color: var(--nav-border); color: var(--nav-text-soft); }
.gp-sidebar-org-platform .gp-sidebar-org-dot { background: var(--nav-text-faint); }

.gp-sidebar-nav { flex: 1; display: flex; flex-direction: column; gap: 0.1rem; padding: 0.25rem 0.75rem 1rem; overflow-y: auto; }
.gp-sidebar-section-title {
  display: flex; align-items: center;
  margin: 1rem 0.6rem 0.35rem;
  font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--nav-text-faint);
}
.gp-sidebar-nav .gp-sidebar-link:first-child,
.gp-sidebar-section-title:first-child { margin-top: 0; }

.gp-sidebar-link {
  display: flex; align-items: center; gap: 0.65rem;
  padding: 0.55rem 0.6rem;
  border-left: 3px solid transparent;
  border-radius: 8px;
  color: var(--nav-text); text-decoration: none;
  font-size: 0.88rem; font-weight: 600;
  transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.gp-sidebar-link svg { flex: none; color: var(--nav-text-soft); transition: color 0.12s ease; }
.gp-sidebar-link span { flex: 1; min-width: 0; }
.gp-sidebar-link:hover { background: var(--nav-bg-soft); color: var(--nav-ink); text-decoration: none; }
.gp-sidebar-link:hover svg { color: var(--nav-ink); }
/* État actif : un simple repère à gauche + fond très pâle, jamais un gros
   bloc plein — cf. consigne d'origine sur le style de la sidebar. */
.gp-sidebar-link.is-active {
  background: var(--nav-accent-soft);
  border-left-color: var(--nav-accent);
  color: var(--nav-accent);
}
.gp-sidebar-link.is-active svg { color: var(--nav-accent); }

.gp-sidebar-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 17px; height: 17px; padding: 0 0.3rem;
  border-radius: 999px; background: var(--nav-accent); color: #FFFFFF;
  font-size: 0.65rem; font-weight: 700; margin-inline-start: 0.35rem;
}
.gp-sidebar-item-badge {
  margin-inline-start: auto; flex: none;
  min-width: 20px; height: 20px; padding: 0 0.4rem;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: var(--nav-accent-soft-strong); color: var(--nav-accent);
  font-size: 0.72rem; font-weight: 700;
}

/* ---------- Zone profil, épinglée en bas de sidebar ---------- */
.gp-sidebar-profile { flex: none; border-top: 1px solid var(--nav-border); padding: 0.75rem; }
.gp-sidebar-profile-link {
  display: flex; align-items: center; gap: 0.65rem;
  padding: 0.5rem;
  border-radius: 8px;
  text-decoration: none; color: inherit;
}
.gp-sidebar-profile-link:hover { background: var(--nav-bg-soft); text-decoration: none; color: inherit; }
.gp-sidebar-profile-link svg { flex: none; color: var(--nav-text-faint); }
.gp-sidebar-avatar {
  position: relative;
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  background: var(--nav-accent); color: var(--gp-accent-text);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 0.82rem;
}
/* Signature visuelle unique de l'app (un seul endroit, jamais un motif
   répété) — reprend le rôle de l'ancien anneau de l'avatar de la barre du
   haut, qui ne s'affiche plus nulle part côté desktop maintenant que la
   sidebar la remplace. L'avatar de la barre d'onglets mobile n'a
   délibérément pas cet anneau. */
.gp-sidebar-avatar::before {
  content: "";
  position: absolute; inset: -4px;
  border-radius: 50%;
  border: 1.5px dashed var(--nav-accent-border);
  pointer-events: none;
}
.gp-sidebar-profile-text { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.gp-sidebar-user-name { font-weight: 700; font-size: 0.85rem; color: var(--nav-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gp-sidebar-user-role { font-size: 0.74rem; color: var(--nav-text-soft); }

.gp-sidebar-logout-form { margin: 0.15rem 0 0; }
.gp-sidebar-logout-btn {
  width: 100%;
  display: flex; align-items: center; gap: 0.65rem;
  padding: 0.5rem; border-radius: 8px;
  background: none; border: none; text-align: start;
  color: var(--nav-text); font-size: 0.85rem; font-weight: 600; cursor: pointer;
}
.gp-sidebar-logout-btn svg { flex: none; color: var(--nav-text-soft); }
.gp-sidebar-logout-btn:hover { background: rgba(220, 53, 69, 0.08); color: var(--nav-red); }
.gp-sidebar-logout-btn:hover svg { color: var(--nav-red); }

/* Même gabarit que .gp-sidebar-logout-btn mais sans le survol rouge (pas une
   action destructive) — classe séparée plutôt qu'un modificateur, pour ne
   pas risquer de faire hériter le rouge par erreur ailleurs. */
.gp-sidebar-toggle-btn {
  width: 100%; margin-bottom: 0.15rem;
  display: flex; align-items: center; gap: 0.65rem;
  padding: 0.5rem; border-radius: 8px;
  background: none; border: none; text-align: start;
  color: var(--nav-text); font-size: 0.85rem; font-weight: 600; cursor: pointer;
}
.gp-sidebar-toggle-btn svg { flex: none; color: var(--nav-text-soft); }
.gp-sidebar-toggle-btn:hover { background: var(--nav-bg-soft); color: var(--nav-ink); }
.gp-sidebar-toggle-btn:hover svg { color: var(--nav-ink); }

/* ---------- Bascule de thème : icône + libellé affichent l'ACTION (ce que
   le clic va activer), pas l'état courant — "Mode sombre" + lune tant qu'on
   est en clair, "Mode clair" + soleil une fois en sombre. Piloté uniquement
   par l'attribut data-bs-theme (posé par _theme_init.html), aucun JS de
   bascule d'icône nécessaire. ---------- */
.gp-theme-icon-sun, .gp-theme-label-to-light { display: none; }
[data-bs-theme="dark"] .gp-theme-icon-sun,
[data-bs-theme="dark"] .gp-theme-label-to-light { display: inline-flex; }
[data-bs-theme="dark"] .gp-theme-icon-moon,
[data-bs-theme="dark"] .gp-theme-label-to-dark { display: none; }
.gp-theme-toggle-item { display: flex; align-items: center; gap: 0.6rem; width: 100%; background: none; border: none; }

/* ---------- Barre du haut (mobile/tablette <992px uniquement) ---------- */
.gp-navbar {
  flex: none;
  position: sticky; top: 0; z-index: 40;
  background: var(--nav-bg);
  border-bottom: 1px solid var(--nav-border);
}
.gp-navbar-inner {
  max-width: 1400px; margin: 0 auto;
  height: 60px;
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0 1.5rem;
}
.gp-navbar-brand { flex: none; display: flex; align-items: center; gap: 0.55rem; text-decoration: none; }
.gp-navbar-brand img { height: 28px; width: auto; }
.gp-navbar-brand-name { font-weight: 800; font-size: 1rem; color: var(--nav-ink); letter-spacing: -0.01em; }
@media (max-width: 560px) { .gp-navbar-brand-name { display: none; } }

/* Organisation active : simple repère de contexte (dans quel tenant on
   travaille), pas une donnée décorative — teinte bleue fixe GeoPresence,
   jamais dérivée de l'organisation (cf. décision produit). */
.gp-navbar-org-chip {
  flex: none;
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  background: var(--nav-accent-soft-strong);
  border: 1px solid var(--nav-accent-border);
  color: var(--nav-ink); font-weight: 700; font-size: 0.82rem;
  max-width: 180px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gp-navbar-org-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--nav-accent); }
.gp-navbar-org-chip-platform { background: var(--nav-bg-soft); border-color: var(--nav-border); color: var(--nav-text-soft); }
.gp-navbar-org-chip-platform .gp-navbar-org-dot { background: var(--nav-text-faint); }
@media (max-width: 700px) { .gp-navbar-org-chip { display: none; } }

.gp-navbar-nav { display: flex; align-items: center; gap: 0.15rem; margin-inline-start: 0.5rem; min-width: 0; }
@media (max-width: 991px) { .gp-navbar-nav { display: none; } }

.gp-navbar-link {
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.5rem 0.75rem;
  border-radius: 8px;
  border: none; background: transparent;
  color: var(--nav-text); text-decoration: none;
  font: inherit; font-size: 0.88rem; font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.12s ease, color 0.12s ease;
}
.gp-navbar-link svg { flex: none; color: var(--nav-text-soft); transition: color 0.12s ease; }
.gp-navbar-link:hover { background: var(--nav-bg-soft); color: var(--nav-ink); }
.gp-navbar-link:hover svg { color: var(--nav-ink); }
.gp-navbar-link.is-active { background: var(--nav-accent-soft); color: var(--nav-accent); }
.gp-navbar-link.is-active svg { color: var(--nav-accent); }
.gp-navbar-link-icon { padding: 0.5rem; }
.gp-navbar-link-icon span { display: none; }

.gp-navbar-group { position: relative; }
.gp-navbar-group-trigger svg:last-child { color: var(--nav-text-faint); margin-inline-start: -0.15rem; }

.gp-navbar-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--nav-accent); color: #FFFFFF;
  font-size: 0.68rem; font-weight: 700;
}

.gp-navbar-spacer { flex: 1; }

/* Le profil est déjà accessible via l'onglet "Profil" de la barre du bas —
   sans ça, l'avatar apparaissait deux fois sur mobile (haut ET bas). */
@media (max-width: 991px) { .gp-navbar-profile { display: none; } }

.gp-navbar-avatar-btn { flex: none; background: none; border: none; padding: 0; cursor: pointer; display: flex; }
.gp-navbar-avatar {
  position: relative;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--nav-accent); color: var(--gp-accent-text);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 0.82rem;
}
/* Signature visuelle unique de l'app (cf. consigne : un seul élément, jamais
   un motif répété) — écho discret et statique du rayon de géofencing autour
   de l'avatar de profil, seul endroit où ce motif apparaît. */
.gp-navbar-avatar::before {
  content: "";
  position: absolute; inset: -4px;
  border-radius: 50%;
  border: 1.5px dashed var(--nav-accent-border);
  pointer-events: none;
}

/* ---------- Menus déroulants (groupes de nav, profil, barre du bas —
   même habillage partout) ---------- */
.gp-navbar-menu {
  min-width: 15rem;
  padding: 0.5rem;
  border: 1px solid var(--nav-border);
  border-radius: 12px;
  box-shadow: 0 12px 32px -8px rgba(10, 30, 69, 0.18);
  margin-top: 0.4rem !important;
  max-height: min(70vh, 420px);
  overflow-y: auto;
}

/* Tant que son menu est ouvert, le déclencheur d'un groupe (ex. "Organisation")
   prend le même habillage que l'onglet actif : sans ça, rien ne montrait
   visuellement qu'on venait de taper dessus (l'onglet restait gris, "Accueil"
   restait bleu). */
.gp-navbar-link[aria-expanded="true"],
.gp-bottomnav-link[aria-expanded="true"] {
  background: var(--nav-accent-soft); color: var(--nav-accent);
}
.gp-navbar-link[aria-expanded="true"] svg,
.gp-bottomnav-link[aria-expanded="true"] svg { color: var(--nav-accent); }

/* Mobile : le menu d'un groupe de la barre du bas s'ancre en feuille pleine
   largeur au-dessus de la barre plutôt que de flotter là où Popper trouve de
   la place — sur un écran étroit, avec le bouton "Organisation" excentré à
   droite, ça pouvait atterrir au milieu du contenu de la page, sans lien
   visuel avec l'onglet appuyé. */
@media (max-width: 991px) {
  .gp-bottomnav-group .dropdown-menu {
    position: fixed !important;
    inset: auto 0.5rem calc(4.35rem + env(safe-area-inset-bottom, 0px)) 0.5rem !important;
    transform: none !important;
    width: auto; max-width: none; min-width: 0;
  }
}
.gp-navbar-menu .dropdown-item {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.65rem;
  border-radius: 8px;
  font-size: 0.88rem; font-weight: 500;
  color: var(--nav-text);
}
.gp-navbar-menu .dropdown-item svg { flex: none; color: var(--nav-text-soft); }
.gp-navbar-menu .dropdown-item:hover, .gp-navbar-menu .dropdown-item:focus { background: var(--nav-bg-soft); color: var(--nav-ink); }
.gp-navbar-menu .dropdown-item.is-active { background: var(--nav-accent-soft); color: var(--nav-accent); font-weight: 600; }
.gp-navbar-menu .dropdown-item.is-active svg { color: var(--nav-accent); }
.gp-navbar-item-badge {
  margin-inline-start: auto; flex: none;
  min-width: 20px; height: 20px; padding: 0 0.4rem;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: var(--nav-accent-soft-strong); color: var(--nav-accent);
  font-size: 0.72rem; font-weight: 700;
}

.gp-navbar-profile-head { padding: 0.5rem 0.65rem 0.6rem; }
.gp-navbar-user-name { display: block; font-weight: 700; font-size: 0.9rem; color: var(--nav-ink); }
.gp-navbar-user-role { display: block; font-size: 0.78rem; color: var(--nav-text-soft); }
.gp-navbar-logout-form { margin: 0; }
.gp-navbar-logout-item { width: 100%; background: none; border: none; text-align: start; cursor: pointer; color: var(--nav-text); }
.gp-navbar-logout-item:hover { background: rgba(220, 53, 69, 0.08) !important; color: var(--nav-red) !important; }
.gp-navbar-logout-item:hover svg { color: var(--nav-red); }

/* ---------- Titre de page (bandeau discret sous la barre principale —
   alimenté par {% block page_title %}, inchangé depuis l'ancienne topbar) --- */
.gp-titlebar { border-bottom: 1px solid var(--gp-gray-200); background: var(--gp-white); }
.gp-titlebar-inner {
  max-width: 1400px; margin: 0 auto; padding: 0.85rem 1.5rem;
  font-weight: 700; color: var(--gp-navy); font-size: 1.05rem;
  display: flex; align-items: center; gap: 0.75rem;
}
.gp-titlebar-title:empty { display: none; }
/* Bouton « Retour » — masqué par défaut (attribut hidden), révélé par
   gpGoBack/gpInitBack uniquement s'il y a un historique de navigation. */
.gp-back-btn {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.32rem 0.7rem 0.32rem 0.5rem; border-radius: 999px;
  border: 1px solid var(--gp-gray-200); background: var(--gp-gray-50);
  color: var(--gp-gray-700); font-size: 0.82rem; font-weight: 600;
  cursor: pointer; flex-shrink: 0;
}
.gp-back-btn:hover { background: var(--gp-gray-100); color: var(--gp-navy); border-color: var(--gp-gray-400); }
.gp-back-btn svg { transform: rotate(180deg); }

.gp-content { flex: 1; padding: 1.75rem; max-width: 1400px; width: 100%; margin: 0 auto; }
@media (max-width: 576px) { .gp-content { padding: 1.1rem; } }
@media (max-width: 991px) { .gp-content { padding-bottom: 5.5rem; } }
/* Décalage pour la sidebar fixe (cf. règle .gp-sidebar plus haut) — placé ici,
   après la règle de base, pour ne pas se faire écraser par elle dans la
   cascade (même spécificité, l'ordre dans le fichier tranche). */
@media (min-width: 992px) {
  .gp-titlebar, .gp-content { margin-left: 264px; margin-right: 0; }
  /* width:auto (pas 100%) : avec un margin-left fixe, width:100% se rajoute
     par-dessus au lieu de s'y soustraire et déborde du viewport de 264px —
     width:auto laisse le bloc combler exactement l'espace restant. */
  .gp-content { width: auto; }
  [dir="rtl"] .gp-titlebar, [dir="rtl"] .gp-content { margin-left: 0; margin-right: 264px; }
}

/* ---------- Barre d'onglets mobile (<992px), façon Instagram — mêmes liens
   que la barre du haut, juste regroupés différemment pour tenir en 4-5
   onglets (cf. base.html pour le détail du regroupement par rôle). ---------- */
.gp-bottomnav {
  display: none;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--nav-bg);
  border-top: 1px solid var(--nav-border);
  padding: 0.35rem 0.3rem calc(0.35rem + env(safe-area-inset-bottom, 0px));
  align-items: stretch;
  justify-content: space-around;
  gap: 0.1rem;
}
@media (max-width: 991px) { .gp-bottomnav { display: flex; } }

.gp-bottomnav-link {
  position: relative;
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.2rem;
  padding: 0.35rem 0.2rem;
  border-radius: 10px;
  border: none; background: transparent;
  color: var(--nav-text-soft); text-decoration: none;
  font: inherit; font-size: 0.66rem; font-weight: 600;
  cursor: pointer;
}
.gp-bottomnav-link span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.gp-bottomnav-link.is-active { color: var(--nav-accent); font-weight: 700; background: var(--nav-accent-soft); }
.gp-bottomnav-group { position: relative; flex: 1; min-width: 0; display: flex; }
.gp-bottomnav-group .gp-bottomnav-link { width: 100%; }
.gp-bottomnav-badge { position: absolute; top: 0.1rem; right: 22%; min-width: 15px; height: 15px; font-size: 0.6rem; padding: 0 0.25rem; }
[dir="rtl"] .gp-bottomnav-badge { right: auto; left: 22%; }
.gp-bottomnav-avatar {
  width: 21px; height: 21px; border-radius: 50%;
  background: var(--nav-accent); color: var(--gp-accent-text);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 0.64rem;
}

.gp-profile-card {
  display: flex; align-items: center; gap: 1.25rem;
  padding: 1.5rem;
}
.gp-profile-avatar {
  flex: none; width: 68px; height: 68px; border-radius: 50%;
  background: var(--gp-blue); color: var(--gp-accent-text);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem; font-weight: 800;
}
.gp-profile-info { min-width: 0; }
.gp-profile-name { font-size: 1.15rem; font-weight: 800; color: var(--gp-navy); }
.gp-profile-email { color: var(--gp-gray-600); font-size: 0.9rem; margin-bottom: 0.5rem; }

[dir="rtl"] .gp-pass-wrap .form-control { padding-right: 1rem; padding-left: 2.75rem; }
[dir="rtl"] .gp-pass-toggle { right: auto; left: 0.6rem; }

/* ---------- En-tête de page ---------- */
.gp-page-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.gp-page-header h1 { font-size: 1.4rem; font-weight: 800; color: var(--gp-navy); margin: 0; letter-spacing: -0.01em; }
.gp-page-header p { color: var(--gp-gray-600); font-size: 0.9rem; margin: 0.2rem 0 0; }
.gp-page-header-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; }

/* ---------- Cartes ---------- */
.gp-card { background: var(--gp-white); border: 1px solid var(--gp-gray-200); border-radius: var(--gp-radius); box-shadow: var(--gp-shadow); }
.gp-card-body { padding: 1.35rem 1.5rem; }
.gp-card-header { padding: 1.1rem 1.5rem; border-bottom: 1px solid var(--gp-gray-200); font-weight: 700; color: var(--gp-navy); font-size: 0.98rem; }

/* ---------- Statistiques (KPI) ---------- */
.gp-stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; margin-bottom: 1.75rem; }
@media (max-width: 900px) { .gp-stat-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .gp-stat-grid { grid-template-columns: 1fr; } }

.gp-stat { position: relative; background: var(--gp-white); border: 1px solid var(--gp-gray-200); border-radius: var(--gp-radius); padding: 1.25rem 1.4rem; box-shadow: var(--gp-shadow); }
.gp-stat-icon {
  position: absolute; top: 1.15rem; right: 1.15rem;
  width: 34px; height: 34px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  background: var(--gp-gray-100); color: var(--gp-gray-400);
}
[dir="rtl"] .gp-stat-icon { right: auto; left: 1.15rem; }
.gp-stat.success .gp-stat-icon { background: #F0FDF4; color: var(--gp-green-deep); }
.gp-stat.danger .gp-stat-icon { background: var(--gp-red-bg); color: var(--gp-red); }
.gp-stat.warning .gp-stat-icon { background: var(--gp-amber-bg); color: var(--gp-amber); }
.gp-stat.info .gp-stat-icon { background: #EFF6FF; color: var(--gp-blue); }
.gp-stat-label { font-size: 0.8rem; color: var(--gp-gray-600); font-weight: 600; margin-bottom: 0.5rem; padding-right: 2.6rem; }
[dir="rtl"] .gp-stat-label { padding-right: 0; padding-left: 2.6rem; }
.gp-stat-value { font-size: 1.75rem; font-weight: 800; color: var(--gp-navy); line-height: 1.2; }
.gp-stat-value .unit { font-size: 0.95rem; font-weight: 600; color: var(--gp-gray-400); }
.gp-stat-sub { font-size: 0.78rem; color: var(--gp-gray-600); margin-top: 0.25rem; }
.gp-stat.success .gp-stat-value { color: var(--gp-green-deep); }
.gp-stat.danger .gp-stat-value { color: var(--gp-red); }
.gp-stat.warning .gp-stat-value { color: var(--gp-amber); }
.gp-stat.info .gp-stat-value { color: var(--gp-blue); }
.gp-stat-trend { font-size: 0.78rem; font-weight: 700; }
.gp-stat-trend.up { color: var(--gp-green-deep); }
.gp-stat-trend.down { color: var(--gp-red); }

/* ---------- Barre de recherche / filtres au-dessus d'un tableau ---------- */
.gp-table-toolbar { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 1rem; }
.gp-search-field { position: relative; flex: 1 1 260px; min-width: 200px; }
.gp-search-field svg { position: absolute; top: 50%; left: 0.8rem; transform: translateY(-50%); color: var(--gp-gray-400); pointer-events: none; }
.gp-search-field input {
  width: 100%; padding: 0.55rem 0.85rem 0.55rem 2.5rem;
  border: 1.5px solid var(--gp-gray-200); border-radius: 8px; font-size: 0.9rem;
  background: var(--gp-white); transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.gp-search-field input:focus { outline: none; border-color: var(--gp-blue); box-shadow: 0 0 0 3px rgba(11, 99, 246, 0.12); }
[dir="rtl"] .gp-search-field svg { left: auto; right: 0.8rem; }
[dir="rtl"] .gp-search-field input { padding: 0.55rem 2.5rem 0.55rem 0.85rem; }
.gp-table-toolbar select {
  border: 1.5px solid var(--gp-gray-200); border-radius: 8px; padding: 0.55rem 2rem 0.55rem 0.85rem;
  font-size: 0.9rem; background: var(--gp-white); color: var(--gp-gray-700);
}
.gp-table-toolbar select:focus { outline: none; border-color: var(--gp-blue); box-shadow: 0 0 0 3px rgba(11, 99, 246, 0.12); }
.gp-table-toolbar .gp-toolbar-reset { color: var(--gp-gray-400); font-size: 0.85rem; text-decoration: none; white-space: nowrap; }
.gp-table-toolbar .gp-toolbar-reset:hover { color: var(--gp-navy); text-decoration: underline; }

/* ---------- Tableaux ---------- */
.gp-table-card { background: var(--gp-white); border: 1px solid var(--gp-gray-200); border-radius: var(--gp-radius); box-shadow: var(--gp-shadow); overflow: hidden; }
.gp-table-scroll { overflow-x: auto; }

.gp-slot-table th, .gp-slot-table td { vertical-align: middle; }
.gp-slot-table thead th { font-size: 0.78rem; white-space: nowrap; }
.gp-slot-table .gp-slot-num-cell input {
  width: 56px; padding-left: 0.35rem; padding-right: 0.35rem; text-align: center;
}
.gp-slot-table td select { width: 92px; }
table.gp-table { width: 100%; border-collapse: collapse; margin: 0; font-size: 0.89rem; }
.gp-table thead th {
  background: var(--gp-gray-50); color: var(--gp-gray-600);
  font-size: 0.74rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  text-align: left; padding: 0.75rem 1.1rem;
  border-bottom: 1px solid var(--gp-gray-200);
  white-space: nowrap;
}
.gp-table tbody td { padding: 0.85rem 1.1rem; border-bottom: 1px solid var(--gp-gray-100); color: var(--gp-ink); vertical-align: middle; }
.gp-table tbody tr:last-child td { border-bottom: none; }
.gp-table tbody tr:hover td { background: var(--gp-gray-50); }
.gp-table .text-muted-cell { color: var(--gp-gray-400); }
.gp-table-empty { padding: 2.5rem 1.5rem; text-align: center; color: var(--gp-gray-600); font-size: 0.9rem; }

/* Sur mobile : chaque ligne de tableau devient une carte empilée (label : valeur)
   plutôt qu'un tableau à défilement horizontal. Chaque <td> porte data-label
   (repris du <th> correspondant) ; sans data-label la valeur s'empile seule,
   ce qui reste préférable au défilement latéral. Ajouter .gp-table--keep-scroll
   sur un tableau vraiment large (grille) pour garder l'ancien comportement. */
@media (max-width: 700px) {
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) thead {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); border: 0;
  }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll),
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody,
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tr,
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) td { display: block; width: 100%; }

  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody tr {
    position: relative; padding: 0.9rem 1rem;
    border-bottom: 1px solid var(--gp-gray-200);
  }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody tr:last-child { border-bottom: none; }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody tr:hover td { background: transparent; }

  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td {
    display: flex; gap: 1rem; justify-content: space-between; align-items: baseline;
    padding: 0.3rem 0; border: none; text-align: right;
  }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td[data-label]::before {
    content: attr(data-label); flex-shrink: 0; text-align: left;
    font-size: 0.78rem; font-weight: 600; color: var(--gp-gray-600);
  }
  /* 1re cellule = titre de la carte */
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td:first-child {
    display: block; padding: 0 2.5rem 0.5rem 0; font-weight: 700; font-size: 1rem; text-align: left;
  }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td:first-child::before { display: none; }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td:empty { display: none; }

  /* Menu d'actions (⋮) : coin haut-droit de la carte */
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td.gp-row-menu {
    position: absolute; top: 0.55rem; right: 0.5rem; width: auto; padding: 0;
  }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td.gp-row-menu::before { display: none; }

  /* Boutons d'action en ligne (approuver / rejeter, annuler…) : pleine largeur en bas */
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td:has(.gp-table-actions),
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td:has(.gp-row-action-btn) { padding-top: 0.7rem; display: block; }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td:has(.gp-table-actions)::before,
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) tbody td:has(.gp-row-action-btn)::before { display: none; }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) .gp-table-actions { width: 100%; }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) .gp-table-actions form { flex: 1; }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) .gp-table-actions .btn,
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) td:has(.gp-row-action-btn) .gp-row-action-btn { width: 100%; }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) td:has(.gp-row-action-btn) form { width: 100%; }

  /* Ligne « aucun résultat » (colspan) */
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) td[colspan] { padding: 0; text-align: center; }
  .gp-table-card .gp-table:not(.gp-table--keep-scroll) td[colspan]::before { display: none; }
}
.gp-sub-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; max-width: 22rem; }

/* Sélecteur de jour (planning des salles) */
.gp-daytabs { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1rem; }
.gp-daytab {
  padding: 0.4rem 0.9rem; border-radius: 999px; font-size: 0.85rem; font-weight: 600;
  color: var(--gp-gray-600); background: var(--gp-gray-100); text-decoration: none;
  border: 1px solid transparent;
}
.gp-daytab:hover { color: var(--gp-blue); border-color: var(--gp-gray-200); }
.gp-daytab.is-active { background: var(--gp-blue); color: var(--gp-white); }

/* Grille visuelle d'occupation des salles — axe du temps horizontal, une
   ligne par salle. Largeur mini pour que l'axe reste lisible ; le conteneur
   .gp-table-scroll gère le défilement horizontal sur petit écran. */
.gp-room-grid { min-width: 720px; font-size: 0.85rem; }
.gp-room-row { display: grid; grid-template-columns: 140px 1fr; border-bottom: 1px solid var(--gp-gray-100); }
.gp-room-row:last-child { border-bottom: none; }
.gp-room-grid-head { background: var(--gp-gray-50); border-bottom: 1px solid var(--gp-gray-200); }
.gp-room-grid-corner {
  padding: 0.6rem 0.9rem; font-weight: 700; font-size: 0.74rem; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--gp-gray-600);
}
.gp-room-axis { position: relative; height: 34px; }
.gp-room-hour {
  position: absolute; top: 50%; transform: translate(-50%, -50%);
  font-size: 0.72rem; font-weight: 600; color: var(--gp-gray-400); white-space: nowrap;
}
.gp-room-name {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.25rem;
  padding: 0.6rem 0.9rem; font-weight: 600; color: var(--gp-ink);
  border-right: 1px solid var(--gp-gray-100);
}
.gp-room-track { position: relative; min-height: 58px; padding: 0.4rem 0; }
.gp-room-gridline { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--gp-gray-100); }
.gp-room-slot {
  position: absolute; top: 0.4rem; bottom: 0.4rem; box-sizing: border-box;
  padding: 0.25rem 0.45rem; border-radius: 6px; overflow: hidden;
  background: color-mix(in srgb, var(--gp-blue) 14%, var(--gp-white));
  border: 1px solid color-mix(in srgb, var(--gp-blue) 35%, var(--gp-white));
  display: flex; flex-direction: column; gap: 0.05rem; line-height: 1.25;
}
.gp-room-slot.is-conflict {
  background: var(--gp-red-bg);
  border-color: color-mix(in srgb, var(--gp-red) 45%, var(--gp-white));
}
.gp-room-slot-time { font-size: 0.68rem; font-weight: 700; color: var(--gp-gray-600); }
.gp-room-slot-main { font-weight: 600; color: var(--gp-ink); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
.gp-room-slot-sub { font-size: 0.72rem; color: var(--gp-gray-600); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }

/* Présence enseignants */
.gp-presence-toolbar {
  display: flex; flex-wrap: wrap; gap: 0.75rem 1.5rem; align-items: center;
  justify-content: space-between; margin-bottom: 1rem;
}
.gp-presence-datenav { display: flex; align-items: center; gap: 0.4rem; }
.gp-presence-dateform { margin: 0; }
.gp-presence-dateform input { width: 10rem; }
.gp-presence-summary { font-size: 0.9rem; color: var(--gp-gray-600); margin-bottom: 1rem; }
.gp-presence-summary strong { color: var(--gp-ink); }
.gp-presence-group-head {
  padding: 0.7rem 1.1rem; font-weight: 700; font-size: 0.85rem;
  background: var(--gp-gray-50); border-bottom: 1px solid var(--gp-gray-200);
}
.gp-presence-row-missing td { background: color-mix(in srgb, var(--gp-red-bg) 60%, transparent); }
.gp-presence-row-exception td { background: var(--gp-gray-50); color: var(--gp-gray-600); }

/* Tri des colonnes au clic (cf. static/js/table-sort.js) — appliqué en JS à
   toutes les colonnes triables, colonne d'actions exclue. */
.gp-table th.gp-th-sortable {
  cursor: pointer; user-select: none; padding-right: 1.6rem; position: relative;
}
.gp-table th.gp-th-sortable:hover,
.gp-table th.gp-th-sortable:focus-visible { color: var(--gp-navy); background: var(--gp-gray-100); }
.gp-table th.gp-th-sortable:focus-visible { outline: 2px solid var(--gp-blue); outline-offset: -2px; }
.gp-table th.gp-th-sortable .gp-th-sort-icon {
  position: absolute; right: 0.85rem; top: 50%; transform: translateY(-50%);
  width: 10px; height: 10px; opacity: 0.35;
}
.gp-table th.gp-th-sortable .gp-th-sort-icon::before,
.gp-table th.gp-th-sortable .gp-th-sort-icon::after {
  content: ""; position: absolute; left: 50%; transform: translateX(-50%);
  border-left: 4px solid transparent; border-right: 4px solid transparent;
}
.gp-table th.gp-th-sortable .gp-th-sort-icon::before { top: 0; border-bottom: 4px solid currentColor; }
.gp-table th.gp-th-sortable .gp-th-sort-icon::after { bottom: 0; border-top: 4px solid currentColor; }
.gp-table th.gp-th-sortable.is-sorted-asc .gp-th-sort-icon,
.gp-table th.gp-th-sortable.is-sorted-desc .gp-th-sort-icon { opacity: 1; color: var(--gp-blue); }
.gp-table th.gp-th-sortable.is-sorted-asc .gp-th-sort-icon::before { border-bottom-color: transparent; }
.gp-table th.gp-th-sortable.is-sorted-desc .gp-th-sort-icon::after { border-top-color: transparent; }

/* Vue calendrier des congés (templates/leaves/leave_calendar.html). */
.gp-calendar-toolbar {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: 0.75rem; margin-bottom: 1rem;
}
.gp-calendar-nav { display: flex; align-items: center; gap: 0.6rem; }
.gp-calendar-nav-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 8px; border: 1px solid var(--gp-gray-200);
  background: var(--gp-white); color: var(--gp-gray-600);
}
.gp-calendar-nav-btn:hover { background: var(--gp-gray-50); color: var(--gp-navy); }
.gp-calendar-title { margin: 0; font-size: 1.1rem; font-weight: 700; color: var(--gp-navy); min-width: 9rem; text-align: center; }
.gp-calendar-card {
  background: var(--gp-white); border: 1px solid var(--gp-gray-200); border-radius: var(--gp-radius);
  box-shadow: var(--gp-shadow); overflow: hidden;
}
.gp-calendar-weekdays, .gp-calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.gp-calendar-weekdays {
  border-bottom: 1px solid var(--gp-gray-200); background: var(--gp-gray-50);
}
.gp-calendar-weekdays span {
  padding: 0.55rem 0.4rem; text-align: center; font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--gp-gray-600);
}
.gp-calendar-day {
  min-height: 100px; padding: 0.4rem 0.45rem; border-right: 1px solid var(--gp-gray-100);
  border-bottom: 1px solid var(--gp-gray-100); display: flex; flex-direction: column; gap: 0.3rem;
}
.gp-calendar-grid .gp-calendar-day:nth-child(7n) { border-right: none; }
.gp-calendar-day.is-outside { background: var(--gp-gray-50); }
.gp-calendar-day.is-outside .gp-calendar-daynum { color: var(--gp-gray-400); }
.gp-calendar-day.is-weekend { background: var(--gp-gray-50); }
.gp-calendar-daynum { font-size: 0.8rem; font-weight: 600; color: var(--gp-ink); }
.gp-calendar-day.is-today .gp-calendar-daynum {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%; background: var(--gp-blue); color: #fff;
}
.gp-calendar-leaves { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.gp-calendar-leaves li {
  font-size: 0.72rem; line-height: 1.3; padding: 0.15rem 0.4rem; border-radius: 6px;
  background: rgba(44, 92, 224, 0.1); color: var(--gp-navy); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gp-calendar-leaves li.gp-calendar-more { background: none; color: var(--gp-gray-400); padding-left: 0.2rem; }
@media (max-width: 700px) {
  .gp-calendar-day { min-height: 68px; padding: 0.3rem; gap: 0.2rem; }
  .gp-calendar-weekdays span { padding: 0.4rem 0.1rem; font-size: 0.62rem; }
  .gp-calendar-leaves li { font-size: 0.62rem; padding: 0.1rem 0.25rem; }
  .gp-calendar-title { font-size: 0.95rem; min-width: 7rem; }
}
@media (max-width: 480px) {
  .gp-calendar-day { min-height: 58px; padding: 0.25rem; }
  .gp-calendar-leaves li { padding: 0.05rem 0.2rem; }
}

.gp-table-actions { display: flex; gap: 0.55rem; align-items: center; justify-content: flex-end; white-space: nowrap; }

/* Menu d'actions discret (⋮) — remplace une liste d'actions séparées par
   des "·" qui forçait un défilement horizontal important sur les tableaux
   de gestion (ex. Suspendre/Archiver/Sessions sur la liste des employés). */
.gp-row-menu { text-align: right; }
.gp-row-menu-btn {
  background: transparent; border: none; padding: 0.4rem;
  border-radius: 6px; color: var(--gp-gray-400); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.gp-row-menu-btn:hover, .gp-row-menu-btn:focus { background: var(--gp-gray-100); color: var(--gp-gray-700); }
.gp-row-menu-btn::after { display: none; }
.gp-row-menu .dropdown-menu { min-width: 11rem; padding: 0.4rem; border-color: var(--gp-gray-200); box-shadow: var(--gp-shadow-lg); }
.gp-row-menu .dropdown-item { border-radius: 6px; font-size: 0.88rem; padding: 0.5rem 0.7rem; }
.gp-row-menu .dropdown-item:hover, .gp-row-menu .dropdown-item:focus { background: var(--gp-gray-50); }
.gp-row-menu .dropdown-item.text-danger:hover, .gp-row-menu .dropdown-item.text-danger:focus { background: var(--gp-red-bg); }
.gp-row-menu form { margin: 0; }
.gp-row-menu form button.dropdown-item { width: 100%; text-align: left; background: none; border: none; }
[dir="rtl"] .gp-row-menu form button.dropdown-item { text-align: right; }
.gp-row-link { color: var(--gp-blue); font-weight: 600; text-decoration: none; font-size: 0.85rem; }
.gp-row-link:hover { text-decoration: underline; }
.gp-row-action-btn { background: none; border: none; padding: 0; font: inherit; cursor: pointer; color: var(--gp-blue); font-weight: 600; font-size: 0.85rem; }
.gp-row-action-btn:hover { text-decoration: underline; }
.gp-row-action-btn.danger { color: var(--gp-red); }
.gp-row-sep { color: var(--gp-gray-200); }

/* ---------- Badges ---------- */
.gp-badge { display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.22rem 0.6rem; border-radius: 999px; font-size: 0.74rem; font-weight: 700; white-space: nowrap; }
.gp-badge.success { background: #F0FDF4; color: var(--gp-green-deep); }
.gp-badge.danger { background: var(--gp-red-bg); color: var(--gp-red); }
.gp-badge.warning { background: var(--gp-amber-bg); color: var(--gp-amber); }
.gp-badge.info { background: #EFF6FF; color: var(--gp-blue); }
.gp-badge.neutral { background: var(--gp-gray-100); color: var(--gp-gray-600); }
.gp-badge .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* ---------- Formulaires internes ---------- */
.gp-form-card { max-width: 720px; }

/* Regroupement logique des champs sur les formulaires longs — remplace le
   "mur de champs" par des sections nommées, plus faciles à parcourir et à
   comprendre en un coup d'œil (ex. superadmin/organization_form.html). */
/* Django rend le conteneur de CheckboxSelectMultiple avec la même classe que
   les cases individuelles (form-check-input) — Bootstrap le réduit alors à
   1em de large (taille d'une case à cocher) ; on annule ça explicitement. */
.gp-checkbox-list > div { display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; width: auto; height: auto; border: none; background: none; appearance: none; }
.gp-checkbox-list label { display: flex; align-items: center; gap: 0.4rem; font-weight: 500; font-size: 0.92rem; margin: 0; cursor: pointer; }
.gp-checkbox-list input[type="checkbox"] { margin: 0; }

.gp-form-section { padding: 1.6rem 0; border-bottom: 1px solid var(--gp-gray-100); }
.gp-form-section:first-child { padding-top: 0; }
.gp-form-section:last-of-type { border-bottom: none; padding-bottom: 0; }
.gp-form-section-head { margin-bottom: 1.1rem; }
.gp-form-section-head h3 { font-size: 0.95rem; font-weight: 700; color: var(--gp-navy); margin: 0 0 0.2rem; }
.gp-form-section-head p { font-size: 0.82rem; color: var(--gp-gray-400); margin: 0; }

.gp-form-card .form-label { font-size: 0.85rem; font-weight: 600; color: var(--gp-gray-700); }
.gp-form-card .form-control, .gp-form-card .form-select {
  border: 1.5px solid var(--gp-gray-200); border-radius: 8px; padding: 0.5rem 0.8rem;
}
.gp-form-card .form-control:focus, .gp-form-card .form-select:focus {
  border-color: var(--gp-blue); box-shadow: 0 0 0 3px rgba(11, 99, 246, 0.12);
}
.gp-form-actions { display: flex; gap: 0.6rem; margin-top: 1.25rem; }

/* ---------- États vides ---------- */
.gp-empty { text-align: center; padding: 3rem 1.5rem; color: var(--gp-gray-600); }
.gp-empty-icon { width: 48px; height: 48px; border-radius: 50%; background: var(--gp-gray-100); color: var(--gp-gray-400); display: flex; align-items: center; justify-content: center; margin: 0 auto 1rem; }

/* ---------- Pagination ---------- */
.gp-pagination { display: flex; justify-content: center; align-items: center; gap: 0.4rem; margin-top: 1.5rem; }
.gp-pagination a, .gp-pagination span {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 34px; height: 34px; padding: 0 0.6rem;
  border-radius: 8px; font-size: 0.85rem; font-weight: 600;
  text-decoration: none; color: var(--gp-gray-700);
  border: 1px solid var(--gp-gray-200);
}
.gp-pagination a:hover { background: var(--gp-gray-50); }
.gp-pagination .current { background: var(--gp-navy); color: var(--gp-white); border-color: var(--gp-navy); }
.gp-pagination .disabled { color: var(--gp-gray-400); border-color: var(--gp-gray-100); }

.gp-content .alert { border-radius: 10px; border: 1px solid transparent; }

/* ---------- Assistant IA (CDC §15.3.3) ---------- */
.gp-chat-shell { display: flex; gap: 1.25rem; height: calc(100vh - 160px); min-height: 480px; }
.gp-chat-sidebar {
  flex: 0 0 260px;
  background: var(--gp-white);
  border: 1px solid var(--gp-gray-200);
  border-radius: var(--gp-radius);
  overflow-y: auto;
  padding: 0.75rem;
}
@media (max-width: 850px) { .gp-chat-sidebar { display: none; } }
.gp-chat-conv-link {
  display: block; padding: 0.6rem 0.7rem; border-radius: 8px;
  color: var(--gp-gray-700); text-decoration: none; font-size: 0.85rem; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gp-chat-conv-link:hover { background: var(--gp-gray-50); }
.gp-chat-conv-link.is-active { background: var(--gp-gray-100); color: var(--gp-navy); font-weight: 700; }

.gp-chat-main {
  flex: 1; display: flex; flex-direction: column; min-width: 0;
  background: var(--gp-white);
  border: 1px solid var(--gp-gray-200);
  border-radius: var(--gp-radius);
  overflow: hidden;
}
.gp-chat-thread { flex: 1; overflow-y: auto; padding: 1.5rem; display: flex; flex-direction: column; gap: 1rem; }
.gp-chat-bubble { max-width: 78%; padding: 0.75rem 1rem; border-radius: 14px; font-size: 0.92rem; line-height: 1.5; white-space: pre-wrap; }
/* var(--gp-blue), pas var(--gp-navy) : une bulle "envoyée" doit rester dans
   la couleur de marque dans les deux thèmes (comme la plupart des messageries),
   pas s'inverser en bulle claire en mode sombre. */
.gp-chat-bubble.user { align-self: flex-end; background: var(--gp-blue); color: #FFFFFF; border-bottom-right-radius: 4px; }
.gp-chat-bubble.assistant { align-self: flex-start; background: var(--gp-gray-100); color: var(--gp-ink); border-bottom-left-radius: 4px; }
[dir="rtl"] .gp-chat-bubble.user { border-bottom-right-radius: 14px; border-bottom-left-radius: 4px; }
[dir="rtl"] .gp-chat-bubble.assistant { border-bottom-left-radius: 14px; border-bottom-right-radius: 4px; }
.gp-chat-form { flex: none; border-top: 1px solid var(--gp-gray-200); padding: 1rem; display: flex; gap: 0.6rem; }
.gp-chat-form textarea { flex: 1; resize: none; border-radius: 10px; border: 1.5px solid var(--gp-gray-200); padding: 0.6rem 0.9rem; font-size: 0.92rem; }
.gp-chat-form textarea:focus { outline: none; border-color: var(--gp-blue); box-shadow: 0 0 0 4px rgba(11, 99, 246, 0.12); }

.gp-chat-suggestions { flex: none; display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0 1rem 0.85rem; }
.gp-chat-suggestion-btn {
  background: var(--gp-white);
  border: 1.5px solid var(--gp-gray-200);
  color: var(--gp-blue);
  font-size: 0.85rem; font-weight: 600;
  padding: 0.45rem 0.9rem;
  border-radius: 999px;
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.gp-chat-suggestion-btn:hover { background: var(--gp-gray-50); border-color: var(--gp-blue); }

.gp-chat-bubble.gp-chat-typing { display: flex; align-items: center; gap: 0.3rem; padding: 0.9rem 1rem; }
.gp-chat-bubble.gp-chat-typing span {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--gp-gray-400);
  animation: gp-chat-typing-bounce 1.1s infinite ease-in-out;
}
.gp-chat-bubble.gp-chat-typing span:nth-child(2) { animation-delay: 0.15s; }
.gp-chat-bubble.gp-chat-typing span:nth-child(3) { animation-delay: 0.3s; }
@keyframes gp-chat-typing-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.5; }
  30% { transform: translateY(-4px); opacity: 1; }
}

/* En dessous de 850px : pas de hauteur fixe ni de défilement interne au fil
   de discussion — un seul niveau de défilement (celui de la page), comme le
   reste de l'application. Deux zones de défilement imbriquées (fil + page)
   se piègent l'une l'autre sur mobile : le doigt fait défiler le fil, qui
   n'a souvent rien à défiler, et la page ne bouge pas — le champ de saisie
   devient inatteignable. Le compromis assumé : sur une conversation longue,
   il faut redescendre jusqu'au champ à chaque envoi plutôt qu'il reste
   "collé" en bas comme une appli de chat native — fiabilité avant tout sur
   mobile. Placé après les règles de base ci-dessus : à spécificité égale,
   c'est l'ordre dans le fichier qui décide, cette règle doit rester APRÈS
   celle qu'elle surcharge.*/
@media (max-width: 850px) {
  .gp-chat-shell { height: auto; min-height: 0; }
  .gp-chat-thread { overflow-y: visible; max-height: none; }
}

/* ==========================================================================
   Page d'accueil — refonte mobile-first (RM-UI-HOME, 15/08/2026)
   Remplace l'ancien namespace .gp-ov-* (bandeau KPI + grille de panneaux
   "dashboard administratif") par une composition façon appli mobile :
   bienvenue → contexte du jour → actions à traiter → résumé en cartes →
   panneaux. Namespace dédié (.gp-home-*), toujours volontairement séparé
   du système .gp-card partagé par le reste de l'app (formulaires, listes) :
   cette refonte ne doit avoir aucun effet de bord ailleurs. Utilisé par
   core/admin_dashboard.html, core/manager_dashboard.html et
   core/employee_dashboard.html.
   ========================================================================== */

.gp-home { display: flex; flex-direction: column; gap: 1.75rem; }

/* Sur la page d'accueil uniquement, les cartes/tableaux partagés (annonces,
   planning...) adoptent le radius plus généreux de la nouvelle identité —
   sans toucher à .gp-card/.gp-table-card eux-mêmes, utilisés tels quels sur
   toutes les autres pages (listes, formulaires...). */
.gp-home .gp-card,
.gp-home .gp-table-card { border-radius: 16px; }

/* ---------- 1. Bloc de bienvenue ---------- */
.gp-home-welcome h1 {
  font-size: 1.5rem; font-weight: 800; color: var(--gp-navy);
  margin: 0 0 0.25rem; letter-spacing: -0.02em; line-height: 1.25;
}
.gp-home-welcome > p { margin: 0; color: var(--gp-gray-600); font-size: 0.92rem; }
@media (min-width: 992px) { .gp-home-welcome h1 { font-size: 1.7rem; } }

/* ---------- 2. Contexte du jour ---------- */
.gp-home-context { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.9rem; }
.gp-home-context-pill {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.4rem 0.75rem; border-radius: 999px;
  background: var(--gp-gray-50); border: 1px solid var(--gp-gray-200);
  color: var(--gp-gray-600); font-size: 0.8rem; font-weight: 600;
}
.gp-home-context-pill svg { flex: none; color: var(--gp-gray-400); }

/* ---------- Titres de section ---------- */
.gp-home-section { display: flex; flex-direction: column; gap: 0.85rem; }
.gp-home-section-title { font-size: 1.05rem; font-weight: 700; color: var(--gp-navy); margin: 0; }

/* ---------- 3. Statut du jour / action de pointage — carte primaire
   (équivalent "à traiter" pour sa propre journée, sur manager/employé) ---------- */
.gp-home-status-card {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  background: var(--gp-white); border: 1px solid var(--gp-gray-200); border-radius: 16px;
  box-shadow: var(--gp-shadow); padding: 1.1rem 1.25rem;
}

/* ---------- 3bis. À traiter / accès rapides — cartes d'action tactiles ---------- */
.gp-home-actions { display: flex; flex-direction: column; gap: 0.65rem; }
.gp-home-action-card {
  display: flex; align-items: center; gap: 0.85rem;
  padding: 0.95rem 1.1rem; border-radius: 16px;
  background: var(--gp-white); border: 1px solid var(--gp-gray-200);
  box-shadow: var(--gp-shadow);
  text-decoration: none; color: inherit;
  transition: border-color 0.15s ease, transform 0.1s ease;
}
.gp-home-action-card:hover { border-color: var(--gp-gray-400); text-decoration: none; color: inherit; }
.gp-home-action-card:active { transform: scale(0.99); }
.gp-home-action-icon {
  flex: none; width: 42px; height: 42px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: var(--gp-orange-bg); color: var(--gp-orange);
}
/* variante neutre : accès rapide qui ne demande pas d'action (ex. "Mes congés"
   côté employé) — même carte, mais sans la teinte orange réservée à ce qui
   nécessite une intervention. */
.gp-home-action-card.is-neutral .gp-home-action-icon { background: var(--gp-gray-100); color: var(--gp-gray-600); }
.gp-home-action-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.gp-home-action-title { display: flex; align-items: center; gap: 0.5rem; font-size: 0.95rem; font-weight: 650; color: var(--gp-navy); }
.gp-home-action-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 0.4rem; border-radius: 999px;
  background: var(--gp-orange); color: var(--gp-white); font-size: 0.74rem; font-weight: 700;
}
.gp-home-action-desc { font-size: 0.82rem; color: var(--gp-gray-400); }
.gp-home-action-card > svg:last-child { flex: none; color: var(--gp-gray-400); }

/* ---------- 4. Résumé — cartes statistiques compactes (2 colonnes mobile,
   4 colonnes dès que la largeur le permet) ---------- */
.gp-home-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.75rem; }
@media (min-width: 700px) { .gp-home-stats { grid-template-columns: repeat(4, 1fr); } }
.gp-home-stat {
  background: var(--gp-white); border: 1px solid var(--gp-gray-200); border-radius: 16px;
  box-shadow: var(--gp-shadow); padding: 1rem 1.1rem;
  display: flex; flex-direction: column; gap: 0.55rem;
}
.gp-home-stat-icon {
  width: 34px; height: 34px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: var(--gp-gray-100); color: var(--gp-gray-600);
}
.gp-home-stat.tone-success .gp-home-stat-icon { background: #F0FDF4; color: var(--gp-green-deep); }
.gp-home-stat.tone-danger .gp-home-stat-icon { background: var(--gp-red-bg); color: var(--gp-red); }
.gp-home-stat.tone-warning .gp-home-stat-icon { background: var(--gp-amber-bg); color: var(--gp-amber); }
.gp-home-stat.tone-info .gp-home-stat-icon { background: #EFF6FF; color: var(--gp-blue); }
.gp-home-stat-label { font-size: 0.8rem; font-weight: 600; color: var(--gp-gray-600); }
.gp-home-stat-value {
  font-size: 1.7rem; font-weight: 800; color: var(--gp-navy); line-height: 1.1;
  letter-spacing: -0.01em; font-variant-numeric: tabular-nums;
  display: flex; align-items: baseline; gap: 0.3rem; flex-wrap: wrap;
}
.gp-home-stat.tone-danger .gp-home-stat-value { color: var(--gp-red); }
.gp-home-stat.tone-warning .gp-home-stat-value { color: var(--gp-amber); }
.gp-home-stat.tone-success .gp-home-stat-value { color: var(--gp-green-deep); }
.gp-home-stat.tone-info .gp-home-stat-value { color: var(--gp-blue); }
.gp-home-stat-unit { font-size: 0.85rem; font-weight: 600; color: var(--gp-gray-400); }
.gp-home-stat-trend { font-size: 0.78rem; font-weight: 700; }
.gp-home-stat-trend.up { color: var(--gp-green-deep); }
.gp-home-stat-trend.down { color: var(--gp-red); }

/* ---------- 5. Grille de panneaux (graphiques / listes) ---------- */
.gp-home-panels { display: grid; grid-template-columns: 1fr; gap: 1rem; }
@media (min-width: 992px) {
  .gp-home-panels.is-wide { grid-template-columns: 2fr 1fr; }
  .gp-home-panels.is-even { grid-template-columns: 1fr 1fr; }
}
.gp-home-panel {
  background: var(--gp-white); border: 1px solid var(--gp-gray-200); border-radius: 16px;
  box-shadow: var(--gp-shadow); padding: 1.2rem 1.25rem 1.35rem; display: flex; flex-direction: column;
}
/* Conteneur à hauteur fixe pour un graphe Chart.js en maintainAspectRatio:false —
   empêche le doughnut « Absences par motif » de devenir un cercle plein écran
   sur mobile. */
.gp-chart-box { position: relative; width: 100%; height: 260px; }
.gp-chart-box--doughnut { max-width: 300px; margin: 0 auto; }
.gp-home-panel-head { display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 1.1rem; flex-wrap: wrap; }
.gp-home-panel-head h3 { font-size: 0.95rem; font-weight: 700; color: var(--gp-navy); margin: 0; }
.gp-home-panel-sub { font-size: 0.78rem; color: var(--gp-gray-400); }

.gp-home-empty {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.6rem; padding: 2.5rem 1rem; color: var(--gp-gray-400); text-align: center;
}
.gp-home-empty svg { color: var(--gp-gray-200); }
.gp-home-empty span { font-size: 0.86rem; color: var(--gp-gray-400); }

/* Widget "qui est en congé / absent aujourd'hui" (liste de noms, pas un graphique). */
.gp-people-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }
.gp-people-list li {
  font-size: 0.88rem; color: var(--gp-ink); padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--gp-gray-100);
}
.gp-people-list li:last-child { border-bottom: none; padding-bottom: 0; }
.gp-people-list-more { display: block; margin-top: 0.7rem; font-size: 0.78rem; color: var(--gp-gray-400); }

/* ---------- Check-list de démarrage (onboarding) ---------- */
.gp-onboarding-card {
  background: linear-gradient(135deg, var(--gp-blue) 0%, var(--gp-navy) 100%);
  border-radius: 16px; padding: 1.3rem 1.4rem 1.5rem; color: #fff;
}
.gp-onboarding-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.gp-onboarding-title { font-size: 1.05rem; font-weight: 700; color: #fff; margin: 0; }
.gp-onboarding-sub { font-size: 0.82rem; color: rgba(255, 255, 255, 0.75); margin: 0.2rem 0 0; }
.gp-onboarding-dismiss-btn {
  background: rgba(255, 255, 255, 0.14); border: none; border-radius: 999px;
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  color: rgba(255, 255, 255, 0.85); cursor: pointer; flex-shrink: 0;
}
.gp-onboarding-dismiss-btn:hover { background: rgba(255, 255, 255, 0.24); color: #fff; }
.gp-onboarding-steps { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 1.1rem; }
.gp-onboarding-step {
  display: flex; align-items: center; gap: 0.85rem; padding: 0.75rem 0.9rem;
  background: rgba(255, 255, 255, 0.1); border-radius: 12px; text-decoration: none; color: #fff;
}
.gp-onboarding-step:hover { background: rgba(255, 255, 255, 0.18); color: #fff; }
.gp-onboarding-step.is-done { opacity: 0.6; }
.gp-onboarding-step-check {
  flex-shrink: 0; width: 26px; height: 26px; border-radius: 50%;
  background: rgba(255, 255, 255, 0.18); display: flex; align-items: center; justify-content: center;
  font-size: 0.8rem; font-weight: 700;
}
.gp-onboarding-step.is-done .gp-onboarding-step-check { background: var(--gp-green); color: #fff; }
.gp-onboarding-step-body { flex: 1; display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.gp-onboarding-step-title { font-size: 0.9rem; font-weight: 600; }
.gp-onboarding-step-detail { font-size: 0.78rem; color: rgba(255, 255, 255, 0.7); }
.gp-onboarding-step.is-done .gp-onboarding-step-title { text-decoration: line-through; }

/* ---------- Fil d'activité ---------- */
.gp-home-feed { display: flex; flex-direction: column; }
.gp-home-feed-row {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.7rem 0.25rem; border-bottom: 1px solid var(--gp-gray-100);
}
.gp-home-feed-row:last-child { border-bottom: none; }
.gp-home-feed-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--gp-gray-400); }
.gp-home-feed-dot.status-on_time, .gp-home-feed-dot.status-manually_validated { background: var(--gp-green-deep); }
.gp-home-feed-dot.status-late, .gp-home-feed-dot.status-early_leave { background: var(--gp-amber); }
.gp-home-feed-dot.status-overtime { background: var(--gp-blue); }
.gp-home-feed-dot.status-rejected { background: var(--gp-red); }
.gp-home-feed-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.gp-home-feed-name { font-size: 0.88rem; font-weight: 600; color: var(--gp-ink); }
.gp-home-feed-meta { font-size: 0.78rem; color: var(--gp-gray-400); }
.gp-home-feed-time { flex: none; font-size: 0.78rem; color: var(--gp-gray-400); font-variant-numeric: tabular-nums; }

/* ---------- Micro-interactions : apparition légère au chargement, jamais
   d'effet permanent ni de rebond ---------- */
@media (prefers-reduced-motion: no-preference) {
  .gp-home > * { animation: gp-home-rise 0.35s ease both; }
  .gp-home > *:nth-child(2) { animation-delay: 0.04s; }
  .gp-home > *:nth-child(3) { animation-delay: 0.08s; }
  .gp-home > *:nth-child(4) { animation-delay: 0.12s; }
  .gp-home > *:nth-child(5) { animation-delay: 0.16s; }
  .gp-home > *:nth-child(n+6) { animation-delay: 0.2s; }
}
@keyframes gp-home-rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ==========================================================================
   Code QR de pointage par agence (RM-QR-001, 15/08/2026) — affiche imprimable
   ========================================================================== */
.gp-qr-card {
  background: var(--gp-white); border: 1px solid var(--gp-gray-200); border-radius: 16px;
  box-shadow: var(--gp-shadow); padding: 2rem 1.75rem; text-align: center;
}
.gp-qr-eyebrow { display: block; font-size: 0.78rem; font-weight: 700; color: var(--gp-blue); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 0.5rem; }
.gp-qr-card h2 { font-size: 1.3rem; font-weight: 800; color: var(--gp-navy); margin: 0 0 0.3rem; }
.gp-qr-address { font-size: 0.88rem; color: var(--gp-gray-600); margin: 0 0 1.5rem; }
.gp-qr-image { width: 100%; max-width: 280px; height: auto; image-rendering: pixelated; margin: 0 auto; display: block; }
.gp-qr-caption { margin: 1.25rem 0 0; font-size: 0.92rem; font-weight: 600; color: var(--gp-gray-700); }

/* Isolation d'impression : seule .gp-qr-print-area doit apparaître sur le
   papier — pas la nav, pas les boutons "Imprimer"/"Régénérer". */
@media print {
  .gp-qr-noprint, .gp-navbar, .gp-titlebar, .gp-bottomnav { display: none !important; }
  body * { visibility: hidden; }
  .gp-qr-print-area, .gp-qr-print-area * { visibility: visible; }
  .gp-qr-print-area { position: absolute; top: 0; left: 0; width: 100%; padding: 2rem; }
  .gp-qr-card { box-shadow: none; border: 2px solid #000; }
}
