/* ===========================================================
   AgentMondial — Design System applicatif (dashboard + admin)
   VAGUE 1 — Direction artistique "OLED premium"
   Apple × Linear × Midjourney : noir pur, glassmorphism,
   ressorts iOS, dégradé conique de marque.

   RÈGLE ABSOLUE DE CETTE REFONTE :
   on ne renomme AUCUN sélecteur ni AUCUNE variable — les 25 pages
   les utilisent en style inline (var(--surf), var(--cyan)…).
   Seules les VALEURS changent. Zéro JS métier touché.

   Typo : SF Pro Rounded sur appareils Apple, Inter partout ailleurs
   (SF Pro est sous licence Apple : fallback assumé, pas de promesse creuse).
   =========================================================== */
:root{
  /* — ANTHRACITE, PAS NOIR —
       Le fond était à #000000. Sur un écran ordinaire le noir absolu ne rend pas
       « premium » : il étouffe, et il écrase les paliers au-dessus (#15, #1F)
       qui n'ont plus de marge pour se détacher. Kanté l'a dit en une phrase :
       « trop sombre ».
       PREMIÈRE TENTATIVE RATÉE, ET C'EST INSTRUCTIF : j'étais passé à #0E0E12,
       soit 5 % de luminosité. Techniquement plus clair, visuellement identique —
       il n'a vu aucune différence, et il avait raison. Déplacer une valeur n'est
       pas changer une sensation.
       #17171D est le niveau où le fond cesse de se lire comme du noir. Toute
       l'échelle suit (#1D #22 #2C #38) : les écarts restent les mêmes, chaque
       palier respire. Les filets montent avec (.09 -> .14), sinon les cartes
       flottent sans contour. Choisi par Kanté sur comparatif à quatre niveaux —
       pas deviné une troisième fois. */
  /* `--surf2` a ete ASSOMBRI apres mesure : a #204450, une legende en `--faint`
     posee dessus tombait a 4,11 de contraste. Eclaircir encore le gris l'aurait
     rendu indistinguable de `--muted` ; on baisse donc la surface. La hierarchie
     des paliers reste lisible, le texte redevient conforme. */
  /* ===== 01/08/2026 — LE FOND PASSE DU PETROLE AU BLEU NUIT (#070C16) =====
     Kante a donne UNE couleur, celle du fond. Les quatre autres paliers ne sont
     pas choisis a l'oeil : on a mesure les ECARTS DE CLARTE de l'ancienne rampe
     (en L* CIELAB, qui suit la perception et non les octets) et on les a rejoues
     depuis la nouvelle couleur, dans sa teinte a elle (220°, 52 % de saturation).
       ancien  #0E2027 #122A32 #17323C #1D3D48 #254B57   L* 11,1 -> 29,7
       nouveau #070C16 #0D172A #111E36 #172848 #1E335E   L*  3,3 -> 21,8
     Les paliers gardent donc exactement les memes ecarts relatifs : une carte se
     detache toujours autant de son fond. Ne changer QUE `--bg` aurait laisse des
     cartes petrole sur un fond bleu nuit — le defaut deja signale deux fois.

     LE CONTRASTE A ETE RECALCULE, PAS SUPPOSE — et il s'ameliore partout. Deux
     combinaisons de l'ancienne palette etaient d'ailleurs SOUS le seuil WCAG AA
     et deviennent conformes :
       `--muted` sur `--surf3` : 4,40 -> 5,79
       `--faint` sur `--surf3` : 3,70 -> 4,87
     Le fond plus sombre paie ce que la mesure du 29/07 ne pouvait pas corriger
     sans rendre les gris indistinguables. */
  --bg:#070C16; --bg2:#0D172A; --surf:#111E36; --surf2:#172848; --surf3:#1E335E;
  --line:rgba(255,255,255,.14); --line2:rgba(255,255,255,.22);
  /* LES GRIS SONT LEGEREMENT BLEUTES, ET C'EST NECESSAIRE. Un gris neutre posé
     sur un fond pétrole paraît sale — l'œil compare toujours une couleur à son
     voisinage. On les teinte donc dans la même famille. Contraste vérifié
     après coup, pas supposé : ils doivent rester au-dessus de 4,5. */
  /* `--faint` a ete remonte APRES MESURE : a #7F949C il passait sur le fond
     (5,28) mais tombait a 4,25 SUR UNE CARTE — sous le seuil de 4,5. Or c'est
     justement dans les cartes qu'on lit des legendes. Le contraste ne se juge
     pas contre le fond de page, mais contre la surface reelle du texte. */
  --txt:rgba(255,255,255,.98); --muted:#A2B4BB; --faint:#8FA6AE;
  /* VOILE DE PROFONDEUR SUPPRIMÉ EN MODE SOMBRE.
     C'était un dégradé radial posé en haut de page. Combiné au halo violet du
     coin supérieur gauche, il faisait que le haut de l'écran n'avait pas la même
     couleur que le bas — exactement ce que Kanté a repéré et redit deux fois :
     « toute la plateforme doit avoir la même couleur ».
     Un fond uniforme, c'est une décision, pas un appauvrissement : la profondeur
     se fabrique alors par les surfaces et les filets, qui eux sont mesurés et
     cohérents, pas par un halo qui varie selon l'endroit de l'écran. */
  --depth:none;
  /* — Accents (noms conservés, valeurs mises à jour) — */
  --indigo:#7C3AED; --cyan:#06B6D4; --emerald:#30D158; --gold:#FF9F0A; --rose:#FF453A;
  --blue:#3B82F6;
  --grad:linear-gradient(120deg,#7C3AED 0%,#3B82F6 55%,#06B6D4 100%);
  --grad-conic:conic-gradient(from 180deg at 50% 50%,#7C3AED,#3B82F6,#06B6D4,#7C3AED);
  --grad-soft:linear-gradient(135deg,rgba(124,58,237,.18),rgba(59,130,246,.12),rgba(6,182,212,.10));
  /* — Rayons (grille 8pt) — */
  --r:10px; --rs:8px; --rx:6px; --r-modal:16px;
  --shadow:0 32px 64px rgba(0,0,0,.6),0 0 1px rgba(255,255,255,.1);
  /* ANNEAU DE FOCUS — il indique OU l'on se trouve quand on navigue au clavier.
     Ce n'est pas une decoration : sans lui, quiconque remplit un formulaire a la
     tabulation ne sait plus quel champ est actif (et c'est une exigence
     d'accessibilite, WCAG 2.4.7). Le retirer serait une regression, pas un
     choix esthetique.
     EN REVANCHE il etait trop lourd : 3 px a 35 % d'opacite font un halo flou
     qui bave autour du champ. On passe a 2 px plus francs — il se lit comme un
     trait voulu, plus comme une aura. */
  --ring:0 0 0 2px rgba(124,58,237,.55);
  --hair:inset 0 1px 0 rgba(255,255,255,.04);
  --side-w:260px;
  /* ===== REFONTE 2026 — fondations additives (rien renommé, aucune page cassée) =====
     Direction 1 « Nuit & Aurore » : front clair / admin sombre, marque violet→cyan. */
  /* Échelle d'espacement (grille 4 pt) */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px; --sp-7:48px; --sp-8:64px;
  /* Rayons complémentaires (cartes très arrondies façon réfs) */
  --r-lg:10px; --r-xl:12px; --pill:999px;
  /* Élévations douces (surtout utiles au thème clair du front) */
  --e1:0 1px 2px rgba(9,9,11,.06),0 1px 3px rgba(9,9,11,.10);
  --e2:0 6px 16px -6px rgba(9,9,11,.14),0 2px 6px -2px rgba(9,9,11,.08);
  --e3:0 22px 48px -16px rgba(9,9,11,.20);
  /* Échelle z-index (fini les valeurs magiques éparpillées) */
  --z-nav:50; --z-side:60; --z-tabbar:70; --z-modal:100; --z-toast:120;
  /* — Motion : ressort iOS — */
  --spring:cubic-bezier(.32,.72,0,1);
  --sans:"SF Pro Rounded","SF Pro Display",-apple-system,BlinkMacSystemFont,Inter,system-ui,sans-serif;
}
/* ---- Thème CLAIR (conservé) ---- */
:root[data-theme="light"]{
  --bg:#F6F7F9; --bg2:#FFFFFF; --surf:#FFFFFF; --surf2:#F2F3F6; --surf3:#E7E9EE;
  --line:rgba(9,9,11,.08); --line2:rgba(9,9,11,.16);
  /* `--faint` du thème CLAIR : mon script d'unification l'avait remplacé par le
     bleu-gris pâle du thème sombre — illisible sur blanc. Il reste donc une
     valeur propre au clair, simplement teintée dans la même famille froide pour
     que les deux thèmes se répondent. Contraste vérifié sur fond blanc. */
  --txt:#09090B; --muted:#6B6B73; --faint:#6E7E85;
  --grad-soft:linear-gradient(135deg,rgba(124,58,237,.12),rgba(59,130,246,.09),rgba(6,182,212,.07));
  --shadow:0 24px 60px -30px rgba(124,58,237,.28),0 12px 40px -24px rgba(9,9,11,.14);
  --hair:inset 0 1px 0 rgba(255,255,255,.6);
  --depth:radial-gradient(1100px 620px at 50% -8%,#EDEBFB 0%,rgba(246,247,249,0) 62%);
}
:root[data-theme="light"] .glow{opacity:.14}
:root[data-theme="light"] .side{background:rgba(255,255,255,.78)}
:root[data-theme="light"] .kpi::after{background:radial-gradient(150px 90px at 88% -12%,rgba(124,58,237,.10),transparent)}
/* ":not(.ghost)" est INDISPENSABLE. Sans lui, cette règle (0,3,0) écrase
   `.btn.ghost{color:var(--txt)}` (0,2,0) : en thème clair, tous les boutons
   secondaires avaient le texte BLANC sur un fond quasi blanc — donc illisibles
   partout sur le site. Les boutons pleins (dégradé) gardent bien le texte blanc. */
:root[data-theme="light"] .btn:not(.ghost){color:#fff}
/* Le fond d'origine (blanc à 5%) est invisible sur une carte blanche : en thème
   clair on prend un voile SOMBRE, pour que le bouton se détache vraiment. */
:root[data-theme="light"] .btn.ghost{background:rgba(9,9,11,.05);border-color:rgba(9,9,11,.14);color:var(--txt)}
:root[data-theme="light"] .btn.ghost:hover{background:rgba(9,9,11,.09);border-color:rgba(9,9,11,.24)}
:root[data-theme="light"] .ava{color:#fff}
/* ===== REFONTE 2026 — FINITION PREMIUM (surtout thème clair) =====
   Coins plus ronds partout + ombres douces sur les surfaces (le clair paraissait plat). */
.panel,.card,.kpi{border-radius:var(--r-lg)}
.brandcard,.item{border-radius:var(--rs)}
:root[data-theme="light"] .panel,
:root[data-theme="light"] .card,
:root[data-theme="light"] .kpi,
:root[data-theme="light"] .brandcard{box-shadow:var(--e1)}
:root[data-theme="light"] .card.hover:hover,
:root[data-theme="light"] .kpi:hover{box-shadow:var(--e2)}
:root[data-theme="light"] .top-r .search{box-shadow:var(--e1)}
/* En clair, les voiles blancs (rgba 255) deviennent invisibles → on les remplace par un voile SOMBRE léger */
:root[data-theme="light"] .nav:hover{background:rgba(9,9,11,.05)}
:root[data-theme="light"] .nav.on{background:rgba(9,9,11,.06)}

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}

/* ═══ LES LISTES DEROULANTES ETAIENT ILLISIBLES EN MODE SOMBRE ═══
   Nos `<select>` sont transparents avec un texte quasi blanc (voir `.input
   select`). Mais la liste qui s'ouvre n'est PAS peinte par la page : c'est le
   SYSTEME qui la dessine. Windows posait donc un fond blanc sous notre texte
   blanc — on ne voyait plus les choix. « 7 jours / 14 jours / 30 jours »
   existaient bien, ils etaient juste invisibles.

   `color-scheme` est la vraie reponse : il annonce au navigateur dans quelle
   ambiance peindre TOUS ses widgets natifs — listes deroulantes, mais aussi
   selecteurs de date (page Calendrier, planification de publication),
   ascenseurs et cases a cocher. Une seule declaration, tous les cas.

   Les regles sur `option` suivent en second rideau : quelques navigateurs
   ignorent `color-scheme` sur les options. Ecrire les deux coute une ligne. */
:root{color-scheme:dark}
:root[data-theme="light"]{color-scheme:light}
select option,select optgroup{background-color:var(--surf);color:var(--txt)}
/* La fleche du select suit aussi le theme : sans cela elle restait noire sur
   fond sombre, donc invisible. */
select{color:var(--txt)}
/* pas de `background-attachment:fixed` : repaint à chaque scroll (coûteux sur mobile) */
body{background:var(--depth) no-repeat top center,var(--bg);color:var(--txt);font-family:var(--sans);
  -webkit-font-smoothing:antialiased;line-height:1.5;overflow-x:hidden;letter-spacing:-.011em}
a{color:inherit;text-decoration:none}
::selection{background:rgba(124,58,237,.4);color:#fff}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--surf3);border-radius:8px;border:3px solid var(--bg)}
::-webkit-scrollbar-thumb:hover{background:var(--line2)}
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{outline:none;box-shadow:var(--ring)}
h1,h2,h3{letter-spacing:-.03em;font-weight:800}
.kpi .v,.table,.amt,.num{font-variant-numeric:tabular-nums}
.grad-txt{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.muted{color:var(--muted)} .faint{color:var(--faint)}

/* glows d'ambiance (dégradés radiaux : beaucoup moins coûteux qu'un blur) */
/* HALOS D'AMBIANCE ÉTEINTS EN MODE SOMBRE.
   `.glow.v` était un disque VIOLET de 560 px posé en haut à gauche, `.glow.c`
   un disque cyan en bas à droite. Sur 51 pages. Résultat : le coin supérieur
   gauche tirait au violet pendant que le reste était pétrole — la « autre
   couleur » que Kanté voyait, et qu'aucun changement de palette n'expliquait,
   puisqu'elle ne venait pas de la palette.
   On les éteint plutôt que de les retirer des 51 pages : les balises restent en
   place, inertes. Les rallumer un jour ne demandera qu'une ligne ici.
   En thème CLAIR ils sont laissés (à 14 % d'opacité, à peine perceptibles) :
   la plainte portait sur le sombre, et je ne touche pas à ce qui n'a pas été
   signalé. */
.glow{display:none}
:root[data-theme="light"] .glow{display:block;position:fixed;border-radius:50%;filter:blur(120px);z-index:0;pointer-events:none}
.glow.v{width:560px;height:560px;background:rgba(124,58,237,.42);top:-220px;left:-160px}
.glow.c{width:480px;height:480px;background:rgba(6,182,212,.26);bottom:-200px;right:-160px}

/* ---------- Layout app ---------- */
.app{display:grid;grid-template-columns:var(--side-w) 1fr;min-height:100vh;position:relative;z-index:1}
.side{border-right:1px solid var(--line);background:rgba(18,40,48,.74);backdrop-filter:blur(40px) saturate(1.4);
  -webkit-backdrop-filter:blur(40px) saturate(1.4);padding:22px 14px;display:flex;flex-direction:column;gap:2px;position:sticky;top:0;height:100vh;overflow-y:auto}
.brand{display:flex;align-items:center;gap:11px;font-weight:800;font-size:18px;letter-spacing:-.02em;padding:6px 8px 20px}
.brand .mark{width:34px;height:34px;border-radius:10px;background:#000 url(logo-mark.png) center/cover;display:grid;place-items:center;font-size:0;color:transparent;box-shadow:0 6px 20px -6px rgba(124,58,237,.8)}
.brand .badge{font-size:9px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#A78BFA;
  border:1px solid rgba(124,58,237,.3);background:rgba(124,58,237,.16);border-radius:6px;padding:3px 7px;margin-left:auto}
/* Arc Browser : le fond glisse sous le curseur */
.nav{position:relative;display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:10px;color:var(--muted);
  font-size:14px;font-weight:500;cursor:pointer;border:1px solid transparent;margin-bottom:2px;
  transition:background .22s var(--spring),color .22s var(--spring),transform .22s var(--spring)}
.nav .i{width:18px;text-align:center;font-size:15px;opacity:.9;transition:transform .22s var(--spring)}
.nav:hover{background:rgba(255,255,255,.05);color:var(--txt);transform:translateX(3px)}
.nav:hover .i{transform:scale(1.12)}
.nav.on{background:rgba(255,255,255,.07);color:var(--txt);border-color:transparent}
.nav.on::before{content:"";position:absolute;left:0;top:9px;bottom:9px;width:3px;border-radius:0 3px 3px 0;background:var(--grad)}
.nav-sep{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);padding:18px 12px 6px;font-weight:600}
.spacer{flex:1}
.brandcard{border:1px solid var(--line);border-radius:12px;padding:12px;background:var(--surf)}
.brandcard small{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);font-weight:600}
.brandcard .b{display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px;margin-top:6px}
.brandcard .dot{width:8px;height:8px;border-radius:50%;background:var(--emerald);box-shadow:0 0 10px var(--emerald)}

.main{padding:26px 30px 60px;min-width:0;width:100%;max-width:1240px;margin-inline:auto}
/* Sur tres grand ecran, le contenu est PLAFONNE et centre : l'espace en plus ne doit
   jamais etirer les cartes. Le chat plein ecran gere sa propre largeur. */
.main.cmain{max-width:none;margin-inline:0}
.top{display:flex;align-items:center;justify-content:space-between;gap:18px;margin-bottom:26px;flex-wrap:wrap}
.top h1{font-size:34px;line-height:41px;font-weight:800;letter-spacing:-.03em}
.top .desc{color:var(--muted);font-size:15px;margin-top:2px}
/* 12 px separaient les boutons : entre deux carres de 38 px, ca les fait lire
   comme deux elements sans rapport. La langue et le theme sont pourtant le meme
   genre de reglage — ils doivent former un GROUPE. On resserre a 6 px entre eux,
   et on garde 12 px avant le reste de la barre (recherche, avatar) pour que le
   groupe se detache de ce qui l'entoure. */
.top-r{display:flex;align-items:center;gap:6px}
.top-r > .search,.top-r > .ava{margin-left:6px}
.search{display:flex;align-items:center;gap:8px;background:var(--surf);border:1px solid var(--line);border-radius:11px;
  padding:9px 14px;color:var(--muted);font-size:13px;min-width:200px;transition:border-color .18s,box-shadow .18s}
/* Le champ de recherche cumulait DEUX marques de focus : sa bordure virait au
   violet ET l'anneau s'ajoutait par-dessus. D'ou l'effet de contour epais que
   Kante a repere. Une seule suffit — on garde l'anneau, commun a tous les
   champs, et la bordure ne bouge plus. */
.search:focus-within{box-shadow:var(--ring)}
.search input{background:transparent;border:none;outline:none;color:var(--txt);font-size:13px;width:100%;font-family:inherit}
.ava{width:38px;height:38px;border-radius:50%;background:var(--grad);display:grid;place-items:center;font-weight:800;
  color:#000;box-shadow:0 8px 22px -10px rgba(124,58,237,.8),inset 0 1px 0 rgba(255,255,255,.35);overflow:hidden}
/* La photo REMPLIT le disque. `cover` recadre le trop-plein au lieu de réduire
   l'image : sans lui, un portrait vertical rentrerait en entier et laisserait
   deux bandes vides sur les côtés — une photo qui flotte au milieu du rond.
   Le `grid` du parent centre l'image ; width/height 100 % lui donnent tout le
   disque, à quoi `object-fit` ajoute le recadrage. */
.ava img{width:100%;height:100%;object-fit:cover;display:block;border-radius:50%}

/* ---------- Boutons (hover 1.02 · tap 0.98) ---------- */
.btn{display:inline-flex;align-items:center;gap:8px;padding:11px 18px;border-radius:11px;font-weight:600;font-size:14px;
  background:var(--grad);color:#000;border:none;cursor:pointer;font-family:inherit;
  transition:transform .18s var(--spring),box-shadow .18s var(--spring),filter .18s;
  box-shadow:0 10px 26px -12px rgba(124,58,237,.85),inset 0 1px 0 rgba(255,255,255,.28)}
.btn:hover{transform:scale(1.02);filter:brightness(1.1);box-shadow:0 16px 34px -12px rgba(124,58,237,.95),inset 0 1px 0 rgba(255,255,255,.32)}
.btn:active{transform:scale(.98);box-shadow:0 6px 16px -12px rgba(124,58,237,.6),inset 0 1px 0 rgba(255,255,255,.2)}
.btn.ghost{background:rgba(255,255,255,.05);color:var(--txt);border:1px solid var(--line2);box-shadow:none;backdrop-filter:blur(20px)}
.btn.ghost:hover{background:rgba(255,255,255,.09);border-color:rgba(255,255,255,.2);filter:none}
.btn.sm{padding:8px 14px;font-size:13px}
.btn.lg{padding:14px 24px;font-size:15px}
.btn[disabled]{opacity:.5;cursor:not-allowed;transform:none;filter:none}

/* ---------- Cartes & panneaux (glassmorphism) ---------- */
.card{background:var(--surf);border:1px solid var(--line);border-radius:var(--r);padding:22px;
  backdrop-filter:blur(40px);-webkit-backdrop-filter:blur(40px);box-shadow:var(--hair);
  transition:transform .28s var(--spring),border-color .28s,box-shadow .28s,filter .28s}
.card.hover:hover{transform:translateY(-3px) scale(1.01);border-color:var(--line2);filter:brightness(1.08);box-shadow:var(--shadow)}
.panel{background:var(--surf);border:1px solid var(--line);border-radius:var(--r);overflow:hidden;margin-bottom:22px;
  backdrop-filter:blur(40px);-webkit-backdrop-filter:blur(40px);box-shadow:var(--hair)}
.panel-h{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--line)}
.panel-h h2{font-size:16px;font-weight:700;letter-spacing:-.01em}
.panel-b{padding:20px}

.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:20px}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}

/* ---------- KPI premium ---------- */
.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:22px}
.kpi{position:relative;overflow:hidden;background:var(--surf);border:1px solid var(--line);border-radius:var(--r);padding:18px;
  backdrop-filter:blur(40px);-webkit-backdrop-filter:blur(40px);box-shadow:var(--hair);
  transition:transform .28s var(--spring),border-color .28s}
.kpi:hover{transform:translateY(-3px) scale(1.01);border-color:var(--line2)}
.kpi::after{content:"";position:absolute;inset:0;background:radial-gradient(180px 100px at 88% -20%,rgba(124,58,237,.18),transparent);pointer-events:none}
.kpi .ic{width:40px;height:40px;border-radius:12px;background:var(--grad-soft);border:1px solid var(--line2);display:grid;place-items:center;font-size:18px;margin-bottom:14px}
.kpi .v{font-size:32px;font-weight:800;letter-spacing:-.03em}
.kpi .l{color:var(--muted);font-size:13px;margin-top:2px}
.kpi .t{font-size:12.5px;font-weight:600;margin-top:6px;color:var(--emerald)}
.kpi .t.down{color:var(--rose)}
.spark{display:flex;align-items:flex-end;gap:3px;height:32px;margin-top:12px}
.spark i{flex:1;background:var(--grad);border-radius:3px 3px 0 0;opacity:.8;animation:rise .8s var(--spring) both}
@keyframes rise{from{height:0;opacity:0}to{opacity:.8}}

/* ---------- Graphique SVG ---------- */
.chart{position:relative;height:200px;margin-top:6px}
.chart svg{width:100%;height:100%;overflow:visible}
.chart .grid line{stroke:var(--line);stroke-width:1}
.area{fill:url(#agArea);opacity:.5}
.line{fill:none;stroke:url(#agLine);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;filter:drop-shadow(0 6px 16px rgba(124,58,237,.55))}
.seg{display:flex;gap:8px}
.seg .s{padding:6px 13px;border-radius:9px;font-size:12px;font-weight:600;border:1px solid var(--line);color:var(--muted);cursor:pointer;transition:.2s var(--spring)}
.seg .s:hover{color:var(--txt)}
.seg .s.on{background:var(--grad);color:#000;border-color:transparent;box-shadow:0 8px 20px -10px rgba(124,58,237,.9)}

/* anneau conique */
.ring{--p:86;width:120px;height:120px;border-radius:50%;background:conic-gradient(var(--indigo) calc(var(--p)*1%),var(--line) 0);display:grid;place-items:center;margin:0 auto}
.ring .in{width:92px;height:92px;border-radius:50%;background:var(--surf);display:grid;place-items:center;flex-direction:column}
.ring .in b{font-size:26px;font-weight:800;letter-spacing:-.03em}
.ring .in span{font-size:11px;color:var(--muted)}

/* barres horizontales (réseaux/plans) */
.legrow{display:flex;gap:14px;align-items:center;margin-bottom:12px}
.legrow .nm{flex:1;font-size:13px}
.legrow .track{flex:2;height:6px;border-radius:3px;background:rgba(255,255,255,.08);overflow:hidden}
.legrow .fill{height:100%;background:var(--grad);border-radius:3px;transition:width 1s var(--spring)}
.legrow .pct{font-size:13px;color:var(--muted);min-width:54px;text-align:right}

/* feed / items */
.item{display:flex;gap:14px;align-items:center;background:var(--bg2);border:1px solid var(--line);border-radius:var(--rs);
  padding:13px;margin-bottom:10px;transition:.24s var(--spring)}
.item:hover{border-color:var(--line2);transform:translateX(3px);filter:brightness(1.1)}
.item .th{width:52px;height:52px;border-radius:12px;display:grid;place-items:center;font-size:22px;flex-shrink:0}
.item .m{flex:1;min-width:0}
.item .m .ttl{font-weight:600;font-size:14px}
.item .m .sb{color:var(--muted);font-size:12px;margin-top:2px}

/* tags & statuts */
.tag{font-size:11px;font-weight:600;padding:5px 10px;border-radius:10px;background:var(--grad-soft);border:1px solid var(--line);color:var(--muted)}
.tag.green{background:rgba(48,209,88,.14);color:var(--emerald);border-color:rgba(48,209,88,.3)}
.tag.cyan{background:rgba(6,182,212,.14);color:var(--cyan);border-color:rgba(6,182,212,.3)}
.tag.violet{background:rgba(124,58,237,.16);color:#A78BFA;border-color:rgba(124,58,237,.3)}
.tag.gold{background:rgba(255,159,10,.14);color:var(--gold);border-color:rgba(255,159,10,.3)}
.status{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;font-weight:600}
.status .d{width:8px;height:8px;border-radius:50%}
.status.active{color:var(--emerald)} .status.active .d{background:var(--emerald);box-shadow:0 0 8px var(--emerald);animation:dotpulse 2s var(--spring) infinite}
.status.paused{color:var(--gold)} .status.paused .d{background:var(--gold)}
.status.off{color:var(--faint)} .status.off .d{background:var(--faint)}
@keyframes dotpulse{0%,100%{transform:scale(.85);opacity:.7}50%{transform:scale(1.15);opacity:1}}

/* tableaux */
.table{width:100%;border-collapse:collapse}
.table thead th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--faint);font-weight:600;padding:0 20px 12px}
.table tbody td{padding:14px 20px;border-top:1px solid var(--line);font-size:14px}
.table tbody tr{transition:background .2s}
.table tbody tr:hover{background:rgba(255,255,255,.03)}

/* inputs */
.input{display:flex;align-items:center;gap:10px;background:var(--bg2);border:1px solid var(--line);border-radius:12px;
  padding:12px 16px;transition:border-color .18s,box-shadow .18s}
/* Meme doublon que sur `.search` : bordure violette PLUS anneau. On garde le
   seul anneau, identique partout — un champ actif doit se signaler de la meme
   facon quel que soit l'ecran. */
.input:focus-within{box-shadow:var(--ring)}
.input input,.input textarea,.input select{background:transparent;border:none;outline:none;color:var(--txt);font-size:14px;width:100%;font-family:inherit}
.input input::placeholder,.input textarea::placeholder{color:var(--faint)}
.field{margin-bottom:16px}
.field label{display:block;font-size:13px;color:var(--muted);margin-bottom:7px;font-weight:600}

.reveal{opacity:0;transform:translateY(20px);transition:opacity .6s var(--spring),transform .6s var(--spring)}
.reveal.in{opacity:1;transform:none}

/* Squelettes de chargement (shimmer) */
.skel{position:relative;overflow:hidden;background:var(--surf2);border-radius:var(--rs)}
.skel::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.07),transparent);animation:shim 1.4s infinite}
@keyframes shim{100%{transform:translateX(100%)}}

/* === Responsive : tablette, téléphone, paysage === */
@media(max-width:980px){
  .app{grid-template-columns:1fr}
  .side{position:fixed;left:-300px;transition:left .3s var(--spring);z-index:60;width:270px}
  .side.open{left:0}
  .kpis,.grid-4{grid-template-columns:repeat(2,1fr)}
  .grid-2,.grid-3{grid-template-columns:repeat(2,1fr)}
  .menu-btn{display:grid !important}
  .top h1{font-size:28px;line-height:34px}
}
@media(max-width:640px){
  .kpis,.grid-2,.grid-3,.grid-4{grid-template-columns:1fr}
  /* La barre d'action peut passer a la ligne ; la recherche cede sa largeur minimale. */
  .top-r{flex-wrap:wrap}
  .search{min-width:0;flex:1}
  .main{padding:18px 16px 48px}
}
/* ---- MOBILE/TABLETTE ÉTROITE : les tableaux de données deviennent des cartes empilées ----
   (fini le scroll horizontal, les colonnes coupées et les lignes géantes).
   Générique : 1re cellule = en-tête de carte, dernière = actions ; les <td data-label="…">
   affichent leur libellé. S'applique à tout .table / .ctab (admin uniquement). */
@media(max-width:720px){
  .panel{overflow-x:visible}
  table.table, table.ctab{min-width:0;width:100%;display:block}
  table.table thead, table.ctab thead{display:none}
  table.table tbody, table.ctab tbody, table.table tfoot, table.ctab tfoot{display:block}
  table.table tr, table.ctab tr{display:block;border:1px solid var(--line2);border-radius:16px;
    background:var(--surf2);margin-bottom:14px;padding:4px 0;overflow:hidden}
  table.table td, table.ctab td{display:flex;justify-content:space-between;align-items:center;gap:14px;
    padding:10px 16px;border:0;font-size:13.5px;text-align:right;min-width:0}
  table.table td::before, table.ctab td::before{content:attr(data-label);color:var(--faint);font-size:11px;
    text-transform:uppercase;letter-spacing:.05em;font-weight:700;flex:none;text-align:left}
  table.table td:first-child, table.ctab td:first-child{
    border-bottom:1px solid var(--line);padding:14px 16px;text-align:left;font-weight:600}
  table.table td:first-child::before, table.ctab td:first-child::before{display:none}
  table.table td:last-child, table.ctab td:last-child{flex-wrap:wrap;justify-content:flex-end;gap:8px}
  table.table td[colspan], table.ctab td[colspan]{justify-content:center;text-align:center;font-weight:400}
  table.table td[colspan]::before, table.ctab td[colspan]::before{display:none}
  .cli{width:100%}.cli .hd{white-space:normal;word-break:break-word}
  select.mini{max-width:62%}
}
@media(orientation:landscape) and (max-height:520px){
  .side{padding:12px;gap:3px;overflow-y:auto}
  .main{padding:14px 20px 28px}
  .top{margin-bottom:14px}
  .kpis{margin-bottom:14px}
  .kpi,.card,.panel{padding-top:14px;padding-bottom:14px}
}
.menu-btn{display:none;place-items:center;width:40px;height:40px;border-radius:11px;border:1px solid var(--line2);
  background:var(--surf);cursor:pointer;font-size:18px;transition:.2s var(--spring)}
.menu-btn:active{transform:scale(.92)}
.theme-btn{display:grid;place-items:center;width:38px;height:38px;border-radius:11px;border:1px solid var(--line2);
  background:var(--surf);cursor:pointer;font-size:17px;transition:.2s var(--spring)}
.theme-btn:hover{background:var(--surf2);transform:scale(1.05)}
.theme-btn:active{transform:scale(.94)}

/* ===========================================================
   Mobile app premium : barre d'onglets basse, safe-areas, confort tactile
   (injectée par auth.js — visible uniquement sur téléphone/tablette étroite)
   =========================================================== */
.tabbar{display:none}
.side-scrim{display:none}
@media(max-width:980px){
  .tabbar{
    display:grid;grid-template-columns:repeat(5,1fr);align-items:end;
    position:fixed;left:0;right:0;bottom:0;z-index:70;
    background:rgba(18,40,48,.84);backdrop-filter:blur(40px) saturate(1.4);-webkit-backdrop-filter:blur(40px) saturate(1.4);
    border-top:1px solid var(--line);
    padding:9px 6px calc(9px + env(safe-area-inset-bottom));
    box-shadow:0 -14px 34px -22px rgba(0,0,0,.85);
  }
  /* liseré dégradé au-dessus de la barre */
  .tabbar::before{content:"";position:absolute;top:-1px;left:0;right:0;height:1px;
    background:linear-gradient(90deg,transparent,rgba(124,58,237,.5),rgba(6,182,212,.5),transparent)}
  :root[data-theme="light"] .tabbar{background:rgba(255,255,255,.92)}
  .tabbar a{
    display:flex;flex-direction:column;align-items:center;gap:3px;text-align:center;
    font-size:10.5px;font-weight:600;color:var(--faint);
    padding:4px 2px;border-radius:12px;transition:color .18s,transform .14s var(--spring);
    -webkit-tap-highlight-color:transparent;user-select:none;
  }
  .tabbar a .ti{font-size:21px;line-height:1;transition:filter .2s var(--spring)}
  .tabbar a.on{color:var(--txt)}
  /* pas de background-clip:text sur un emoji (il deviendrait un aplat) : on éclaire */
  .tabbar a.on .ti{filter:drop-shadow(0 0 10px rgba(124,58,237,.75)) saturate(1.25)}
  .tabbar a:active{transform:scale(.9)}
  /* onglet central « Créer » en relief (FAB) */
  .tabbar a.mid{color:var(--txt)}
  .tabbar a.mid .ti{
    width:48px;height:48px;margin-top:-20px;border-radius:16px;font-size:23px;
    background:var(--grad);color:#000;display:grid;place-items:center;filter:none;
    box-shadow:0 12px 26px -8px rgba(124,58,237,.85),inset 0 1px 0 rgba(255,255,255,.4);
  }
  .tabbar a.mid.on .ti{filter:none}
  .main{padding-bottom:calc(92px + env(safe-area-inset-bottom))}
  .side-scrim{display:block;position:fixed;inset:0;z-index:76;background:rgba(0,0,0,.6);opacity:0;pointer-events:none;transition:opacity .3s var(--spring)}
  .side-scrim.on{opacity:1;pointer-events:auto}
  .side{z-index:80;padding-top:calc(22px + env(safe-area-inset-top))}
}

/* ===========================================================
   Perf mobile : les flous plein écran (blur 120px) + backdrop-filter
   sont très coûteux en GPU sur téléphone. On les neutralise au profit
   de dégradés déjà "flous" et de fonds quasi opaques -> ouverture rapide.
   =========================================================== */
@media(max-width:820px){
  .glow{filter:none;opacity:.5}
  .glow.v{background:radial-gradient(circle,rgba(124,58,237,.42),transparent 68%)}
  .glow.c{background:radial-gradient(circle,rgba(6,182,212,.26),transparent 68%)}
  .side{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(16,36,44,.97)}
  .tabbar{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(16,36,44,.97)}
  .card,.panel,.kpi{backdrop-filter:none;-webkit-backdrop-filter:none}
  .btn.ghost{backdrop-filter:none}
  :root[data-theme="light"] .side{background:rgba(255,255,255,.97)}
  :root[data-theme="light"] .tabbar{background:rgba(255,255,255,.98)}
}

/* Respect de la préférence système */
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
}

/* ============================================================
   PRÉSENCE DES PERSONNAGES DANS L'ADMIN (décoratif, thème sombre)
   Rail d'avatars de l'équipe (toutes pages) + bandeau héros (vue d'ensemble).
   100% présentation — aucune logique, aucun clic. Masqué proprement en mobile.
   ============================================================ */
.ateam{margin:12px 6px 4px;padding:12px 13px;border:1px solid var(--line);border-radius:16px;
  background:var(--surf2);box-shadow:var(--e1)}
.ateam .lbl{font-size:10.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--faint);margin-bottom:9px}
.ateam .row{display:flex;align-items:center}
.ateam .row img{width:32px;height:32px;border-radius:50%;object-fit:cover;object-position:top center;
  border:2px solid var(--surf);background:var(--surf3,var(--surf2));margin-left:-9px;box-shadow:0 3px 9px rgba(0,0,0,.4)}
.ateam .row img:first-child{margin-left:0}
/* Le compteur passait a la ligne DANS la carte et debordait : on le met sous la
   rangee, sur toute la largeur. Plus de depassement possible. */
.ateam .row{flex-wrap:wrap}
.ateam .more{margin-left:0;margin-top:9px;width:100%;font-size:12px;color:var(--muted);font-weight:700}

.ahero{position:relative;overflow:hidden;border:1px solid var(--line);border-radius:14px;
  padding:28px 30px;margin-bottom:20px;min-height:188px;display:flex;align-items:flex-end;gap:24px;
  background:
    radial-gradient(120% 180% at 92% 130%,rgba(6,182,212,.16),transparent 56%),
    radial-gradient(90% 150% at 4% -30%,rgba(124,58,237,.20),transparent 60%),
    var(--surf);
  box-shadow:var(--e2)}
.ahero h2{font-size:22px;font-weight:800;letter-spacing:-.03em;position:relative;z-index:1}
.ahero p{color:var(--muted);font-size:13.5px;margin-top:6px;position:relative;z-index:1}
/* Personnages du bandeau admin : MÊME traitement et MÊME taille que le grand
   personnage du tableau de bord (.hero-char) — portraits détourés de 180 px,
   posés au bas du bandeau et débordant légèrement, avec la même ombre portée.
   Pas de pastilles rondes : c'était un traitement différent, et ça se voyait. */
.ahero .team,.hero .team{display:flex;align-items:flex-end;flex:none;
  margin-bottom:-6px;pointer-events:none;z-index:0}
/* On fixe la HAUTEUR, pas la largeur : les portraits n'ont pas tous le même
   rapport d'image. À largeur fixe, un portrait cadré serré (Nina) montait à
   230 px et sa TÊTE se faisait couper par le bord du bandeau (overflow:hidden).
   À hauteur fixe, tous les visages sont alignés et entiers. */
.ahero .team img,.hero .team img{height:180px;width:auto;display:block;
  filter:drop-shadow(0 22px 44px rgba(59,130,246,.35))}
/* Recouvrement MODÉRÉ : à -104 px, un portrait était couvert à plus de la moitié
   et le visage disparaissait (cas de Nina, cadrée serrée). À -52 px, seul le bord
   de l'épaule est masqué : tous les visages restent entiers. */
.ahero .team img + img,.hero .team img + img{margin-left:-52px}
/* Le nombre de personnages s'adapte à la largeur RÉELLEMENT disponible : on n'en
   affiche un de plus que si la place existe, sinon ils mordraient sur le texte.
   La taille, elle, ne change jamais — c'est celle du tableau de bord (180 px).
   Seuils calculés : 1 portrait = 180 px, chacun en plus = +128 px. */
.ahero .team img:nth-child(-n+5),.hero .team img:nth-child(-n+5){display:none}          /* base : 1 personnage */
@media(min-width:921px) {.ahero .team img:nth-child(5),.hero .team img:nth-child(5){display:block}}  /* 2 */
@media(min-width:1135px){.ahero .team img:nth-child(4),.hero .team img:nth-child(4){display:block}}  /* 3 */
@media(min-width:1348px){.ahero .team img:nth-child(3),.hero .team img:nth-child(3){display:block}}  /* 4 */
@media(min-width:1562px){.ahero .team img:nth-child(2),.hero .team img:nth-child(2){display:block}}  /* 5 */
@media(min-width:1775px){.ahero .team img:nth-child(1),.hero .team img:nth-child(1){display:block}}  /* 6 */
@media(max-width:720px){.ahero .team,.hero .team{display:none}.ahero p{max-width:100%}}

/* Portrait décoratif au coin des panneaux clés (léger, non intrusif) */
.panel.hasface{position:relative}
.panel.hasface > .pface{position:absolute;right:16px;top:-14px;width:52px;height:52px;border-radius:50%;
  object-fit:cover;object-position:top center;border:3px solid var(--surf);background:var(--surf2);
  box-shadow:0 8px 20px rgba(0,0,0,.4);pointer-events:none}
@media(max-width:600px){.panel.hasface > .pface{display:none}}

/* Le texte et la rangée de personnages sont des VOISINS dans une rangée flex :
   ils ne peuvent plus se chevaucher, quelle que soit la largeur de l'écran.
   (Avant, les personnages étaient en position absolue et passaient sous le texte
   dès que la place manquait — d'où « vous avez be… » masqué par une épaule.) */
.hero-txt{flex:1;min-width:0;position:relative;z-index:1;align-self:center}
@media(max-width:720px){.hero-txt{align-self:auto}}

/* ============================================================
   HIÉRARCHIE TYPOGRAPHIQUE — une règle par intention, pas du gras partout.
     400  corps de texte, descriptions
     600  semi-gras : interface (navigation, boutons, libellés, pastilles, en-têtes)
     700  gras : noms, titres de cartes et de panneaux
     800  très gras : titres de page et chiffres clés uniquement
   Placé en fin de fichier : à spécificité égale, c'est la dernière règle qui gagne.
   ============================================================ */

/* — 800 : réservé aux titres de page et aux valeurs qui doivent frapper — */
.top h1,.main > h1{font-weight:800;letter-spacing:-.03em}
.kpi .v,.kc .v,.plan .amt,.grad-txt{font-weight:800}
.crail-t,.mlist .hd .who{font-weight:800}

/* — 700 : titres de section, noms, en-têtes de panneaux — */
.panel-h h2,.sec > h2,.card h3,.card h4,.plan h4{font-weight:700}
.agc .nm,.conv .nm,.mthread .hd .who,.chead h1,.fttl,.gcard .t{font-weight:700}
.brand{font-weight:700}

/* — 600 : tout ce qui est interface. C'est ici que se joue la lisibilité. — */
.nav,.btn,.tag,.hchip,.chip,.mode,.qchip,.sug,.pill,.role,.cyb,.clr,.arow .nm{font-weight:600}
.table th,.field label,.toc a,.faq summary{font-weight:600}
.conv .pv,.stamp,.dmtime{font-weight:400}

/* — 400 : le corps de texte respire. Le gras n'y sert qu'à souligner un mot. — */
.desc,.sub,.lead,.muted,.sec p,.sec li,.gcard .d,.agc .rl,.kpi .l,.kc .l{font-weight:400}
.sec p b,.sec li b,.hchip b,strong{font-weight:700}

/* Les libellés en petites capitales gardent leur graisse : sans elle, ils s'effacent. */
.nav-sep,.ateam .lbl,.toc .grp,.agrp,.crail-b .agrp{font-weight:800}

/* ---------------------------------------------------------------------------
   ADMIN — vocabulaire visuel commun aux pages d'administration.
   Avant : des panneaux plats, un titre nu, et les explications reléguées en
   petit texte gris en bas de page. Ces trois blocs donnent à chaque panneau une
   identité lisible (icône + titre + sous-titre) et un encart d'information net.
   --------------------------------------------------------------------------- */
/* En-tête de panneau : pastille d'icône + titre + sous-titre explicatif */
.ph{display:flex;align-items:center;gap:13px}
.ph .ico{width:40px;height:40px;flex:none;border-radius:11px;display:grid;place-items:center;font-size:19px;
  background:var(--grad-soft);border:1px solid var(--line2)}
.ph .tt h2{font-size:16.5px;font-weight:800;letter-spacing:-.02em;line-height:1.2}
.ph .tt small{display:block;color:var(--muted);font-size:12.5px;margin-top:2px;font-weight:500}
/* Encart d'information (remplace le paragraphe gris perdu en bas de page) */
.note{display:flex;gap:12px;align-items:flex-start;padding:15px 17px;border-radius:12px;
  background:var(--grad-soft);border:1px solid var(--line2);margin-top:6px}
.note .n-i{font-size:17px;line-height:1.2}
.note p{font-size:13px;color:var(--muted);line-height:1.6;margin:0}
/* Barre d'action en pied de panneau : bouton + message de statut alignés */
.actbar{display:flex;align-items:center;gap:12px;margin-top:4px;padding-top:14px;border-top:1px solid var(--line)}
/* Champs de formulaire admin : libellé fort, aide discrète, focus net */
.panel-b .field label{font-size:12.5px;font-weight:700;letter-spacing:.01em;color:var(--txt);margin-bottom:6px;display:block}
.panel-b .field .hint{font-size:12px;color:var(--faint);margin-top:5px}
.panel-b .input{transition:border-color .18s,box-shadow .18s}
.panel-b .input:focus-within{border-color:rgba(124,58,237,.6);box-shadow:0 0 0 3px rgba(124,58,237,.13)}
/* Titres de sous-panneaux admin (h3 : « Nouveau client », « Agents du client »…).
   Ils étaient de simples lignes de texte, noyées dans le panneau : un liseré coloré
   les ancre visuellement, sans toucher au HTML ni aux IDs manipulés par le script. */
.admin-h3, .main .panel-b > h3, .main .card > h3{
  font-size:15px;font-weight:800;letter-spacing:-.01em;margin:0 0 14px;padding-left:11px;
  border-left:3px solid transparent;
  border-image:linear-gradient(180deg,var(--violet,#7C3AED),var(--cyan,#22D3EE)) 1;
}

/* ===== GRAISSE DES TEXTES SECONDAIRES (2026-07-29) =====
   Meme raisonnement que sur la landing : ces textes sont deja attenues par la
   couleur `--muted`. En graisse normale, les traits s'amincissent une seconde
   fois et l'information se lit comme une note de bas de page — alors qu'il
   s'agit du libelle des indicateurs, de la description des pages et du sous-titre
   des elements de liste. 500 leur rend leur poids sans les faire crier.
   Ajoute EN FIN DE FICHIER pour passer apres les declarations existantes, sans
   avoir a modifier six regles eparpillees. */
.top .desc,
.kpi .l,
.legrow .pct,
.item .m .sb,
.ahero p,
.note p,
.muted{font-weight:500}
