/* ══════════════════════════════════════════════════════════════════════════
 * pro-global.css — Design System Seba · Espace Professionnel
 * Tactical Dark — cockpit de pilotage (charte 2026-07-06)
 * Lié dans : dashboard, clients, client-fiche, planning, devis,
 *            devis-nouveau, factures, equipe, employe-fiche,
 *            reglages, historique
 * ══════════════════════════════════════════════════════════════════════════ */

/* ── 1. Design Tokens ────────────────────────────────────────────────────── */
/* Extraits vers src/ui/theme.css (Seba-Core V2) — valeurs inchangees, juste
   deplacees dans un fichier partage. Ne pas ajouter de token ici : theme.css
   est desormais la source de verite. */
@import url('src/ui/theme.css');

/* ── 1bis. Anti-scroll horizontal parasite (cahier des charges mobile
   2026-07-19) ── */
/* Ne bloque pas les conteneurs a scroll horizontal INTENTIONNEL (ex.
   .table-wrap{overflow-x:auto}, section 13 plus bas) : overflow-x:hidden
   ici ne s'applique qu'a html/body eux-memes, jamais a leurs enfants. */
html, body { overflow-x: hidden; }
/* THEME-MOBILE-001 (2026-07-29) : html/body n'avaient JAMAIS de
   background-color -- le canevas restait transparent, donc le blanc par
   défaut du navigateur restait visible partout où aucun élément explicite
   ne peignait de fond (rebond de scroll élastique iOS, grands espaces
   entre modules). En thème sombre, un texte clair (ex. #db-greeting)
   posé directement sur ce blanc non peint devenait invisible alors que
   son propre style calculé était pourtant correct -- confirmé par un
   diagnostic Playwright dédié (couleur calculée correcte, élément bien au
   premier plan, mais fond de html/body totalement transparent) et par
   les captures iPhone réelles du fondateur (texte invisible + "grand
   espace vide" au même endroit -- un seul et même bug, pas deux).
   min-height:100dvh avec repli 100vh : couvre tout le viewport même sur
   une page courte, y compris sous la barre d'adresse/barre inférieure
   Safari dynamiques. */
html, body {
  background: var(--bg);
  min-height: 100vh;
  min-height: 100dvh;
}

/* ── 2. Transitions — boutons ────────────────────────────────────────────── */
button,
.btn,
[class*="btn-"],
.action-btn,
.cta-btn {
  transition:
    background-color var(--t-std) var(--ease-std),
    color            var(--t-std) var(--ease-std),
    border-color     var(--t-std) var(--ease-std),
    opacity          var(--t-std) var(--ease-std),
    box-shadow       var(--t-std) var(--ease-std),
    transform        var(--t-fast) var(--ease-out);
}
/* Hover gardé derrière @media(hover:hover) : sur tactile, :hover se
   déclenche au tap et reste "collé" jusqu'au tap suivant -- :active
   (juste en dessous, jamais gardé) donne le retour visuel au doigt. */
@media (hover: hover) {
  button:hover,  .btn:hover,  [class*="btn-"]:hover { transform: translateY(-1px); }
}
button:active, .btn:active, [class*="btn-"]:active { transform: translateY(0) scale(0.98); }

/* ── 2bis. Bandeau d'identité fixe (nom + secteur) ──────────────────────────
 * Ajouté pour que le positionnement initial du contenu soit identique en
 * naviguant entre le dashboard (bandeau riche, dashboard-v2.css) et les 10
 * autres pages connectées (bandeau léger ici) -- demande fondateur, avant ce
 * correctif seul le dashboard avait un bandeau fixe en haut de page.
 * --identity-bar-height doit rester égal à --v2-fixed-header-space
 * (dashboard-v2.css, 105px) : une seule valeur, dupliquée par nécessité
 * technique (fichiers CSS chargés indépendamment), pas par choix. */
:root {
  --identity-bar-height: 105px;
}
.identity-bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 1000;
  height: var(--identity-bar-height);
  box-sizing: border-box;
  padding: 0 32px;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.identity-bar-name { font-weight: 700; font-size: 1rem; color: var(--ink); }
.identity-bar-sector { font-size: .78rem; color: var(--text-2); padding: 3px 10px; border: 1px solid var(--border); border-radius: 20px; }
@media (max-width: 840px) {
  /* Le bandeau mobile existant (.mobile-header, logo + hamburger) porte déjà
     l'identité visuelle sur petit écran -- éviter d'empiler un second
     bandeau fixe (dette déjà connue sur le dashboard lui-même, pas à
     reproduire ici). */
  .identity-bar { display: none; }
}
@media (min-width: 841px) {
  /* .layout est déclaré localement dans chaque page (display/grid-template-
     columns) -- cette règle ne fait qu'ajouter la marge nécessaire pour
     laisser la place au bandeau fixe, sans dupliquer le reste. */
  .layout { margin-top: var(--identity-bar-height); }
}

/* ── 3. Sidebar — hauteur, nav-items, footer (unifié sur toutes les pages) ─ */
.sidebar {
  /* THEME-MOBILE-001 (2026-07-29) : la sidebar suit désormais le thème de
     la page (décision produit explicite, renverse l'ancien "rail toujours
     sombre" -- voir --sidebar-* dans theme.css pour les deux jeux de
     valeurs). Tous les états ci-dessous (hover/active/label/footer)
     utilisent maintenant ces tokens plutôt que du blanc en dur. */
  background: var(--sidebar-bg);
  color: var(--sidebar-ink);
  display: flex;
  flex-direction: column;
  padding: 18px 0;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  /* largeur imposée par la grille de chaque page,
     mais min/max alignent le contenu correctement */
}
/* Sidebar sans logo "Seba" (posée par sidebar.js sur les 12 pages hors
   tableau de bord, demande fondateur 2026-07-20) : sans ce repère en tête,
   les groupes de nav restaient plaqués en haut avec un grand vide en
   dessous -- centre le bloc nav-group verticalement dans l'espace
   disponible. .sidebar-footer garde margin-top:auto (règle plus bas), qui
   prime sur justify-content et le maintient collé en bas quoi qu'il arrive.
   SETTINGS-BRAND-001 (2026-07-29) : "safe center", pas "center" seul --
   sur un viewport bas (paysage téléphone, ou desktop court), le nombre
   réel d'items ne tient pas toujours dans l'espace disponible ; "center"
   centre alors le débordement des DEUX côtés, pousuant le premier item à
   un top négatif (caché au-dessus du viewport) et le dernier hors du bas
   -- confirmé par mesure réelle (Playwright, 844×390). "safe center"
   revient automatiquement à un alignement "start" dès que le contenu
   déborderait, sans perdre l'avantage du centrage quand tout tient. */
.sidebar.sidebar-no-logo { justify-content: safe center; }
@media (min-width: 841px) {
  /* position:fixed (pas sticky) -- demande fondateur explicite 2026-07-20 :
     la sidebar ne doit JAMAIS bouger, sur aucune page, quel que soit le
     scroll. sticky s'est avéré non fiable ici : son ancrage dépend de la
     hauteur du contenu de .layout (bloc de scroll), et sur les pages avec
     peu de contenu (page courte, juste un peu plus haute que le viewport)
     le calcul de sticky se brise et la sidebar dérive vers le haut au lieu
     de rester à top:var(--identity-bar-height) (mesuré via Puppeteer,
     scroll simulé -- avant ce correctif). fixed est insensible à la
     hauteur du contenu : ancrage viewport pur, aucune dérive possible.
     width explicite obligatoire : la sidebar sort du flux de la grille
     .layout/.app (elle ne peut plus hériter la largeur de sa piste de
     grille), donc doit maintenant fixer elle-même sa largeur -- doit rester
     synchronisée avec le 220px de chaque .layout{grid-template-columns:...}
     local. */
  .sidebar {
    position: fixed;
    top: var(--identity-bar-height);
    left: 0;
    width: 220px;
    height: calc(100vh - var(--identity-bar-height));
  }
  /* .sidebar étant sortie du flux (fixed), elle ne compte plus comme item
     de grille -- sans cette règle, .main deviendrait le seul enfant de
     grille restant et hériterait par défaut la 1ère piste (220px, sous la
     sidebar fixe) au lieu de la 2ème. Recale explicitement le contenu dans
     la piste de droite, laissant la 1ère piste vide (visuellement occupée
     par la sidebar fixe qui la recouvre). */
  .layout > .main,
  .app > .main {
    grid-column: 2;
  }
}

/* Logo (compatible .s-logo dashboard + .logo clients/autres) */
.sidebar .s-logo,
.sidebar .logo {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  padding: 0 20px 18px;
  border-bottom: 1px solid var(--sidebar-border);
  margin-bottom: 12px;
}
.sidebar .s-logo-dot,
.sidebar .logo-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--emerald);
  flex-shrink: 0;
}
/* "Se" gras / "ba" fin -- meme traitement que le logo marketing (PR #74).
   REVUE THEME-MOBILE-001 (2026-07-29) : cette regle globale sert en
   pratique uniquement .mobile-header .mobile-logo dans ce fichier (le
   logo de la sidebar elle-meme est un texte simple pose par sidebar.js,
   ".s-logo", jamais ce balisage .logo-se/.logo-ba span-split) -- --ink/
   --text-2 sont deja theme-aware, donc deja corrects ici sans variante
   "toujours sombre". .mobile-logo .logo-se plus bas dans ce fichier
   reste une simple redondance explicite, pas une correction necessaire. */
.logo-se { font-weight: 800; color: var(--ink); }
.logo-ba { font-weight: 300; color: var(--text-2); }

/* ── Reset d'état du menu (Design System, IV) ────────────────────────────────
   Une seule source de vérité pour le box model du menu : repos, survol,
   pression, sélection et focus clavier partagent EXACTEMENT les mêmes
   dimensions, padding, marge et bordure. Rien ne doit jamais "sauter" —
   seule une transition fluide (background/couleur/opacité) signale le
   changement d'état, jamais un changement de forme. */
.sidebar .nav-item,
.sidebar .nav-item:hover,
.sidebar .nav-item:active,
.sidebar .nav-item.active,
.sidebar .nav-item:focus-visible {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 12px;
  min-height: 40px;
  margin-bottom: 2px;
  border: 1px solid transparent; /* toujours présente : le focus ne pousse jamais le contenu */
  border-radius: var(--rs);
  font-size: .875rem;
  font-weight: 500;
  text-decoration: none;
  transform: none;
  position: relative; /* ancre le repère ::before de l'état actif, hors du flux */
}
.sidebar .nav-item {
  color: var(--sidebar-ink-muted);
  cursor: pointer;
  transition:
    background-color var(--t-fast) var(--ease-std),
    color             var(--t-fast) var(--ease-std),
    opacity           var(--t-fast) var(--ease-std),
    border-color      var(--t-fast) var(--ease-std);
}
@media (hover: hover) {
  .sidebar .nav-item:hover {
    background-color: var(--sidebar-hover-bg);
    color: var(--sidebar-hover-ink);
  }
}
.sidebar .nav-item:active { opacity: .75; } /* pression : fondu, jamais un changement de forme */
/* Repère "rail tactique" : une fine barre à gauche plutôt qu'un fond teinté —
   ::before est en position:absolute, donc jamais de saut de box model. */
.sidebar .nav-item.active {
  background-color: transparent;
  color: var(--sidebar-ink);
}
.sidebar .nav-item.active::before {
  content: '';
  position: absolute;
  left: -1px; top: 6px; bottom: 6px;
  width: 3px;
  border-radius: 2px;
  background: var(--emerald);
}
.sidebar .nav-item:focus-visible { border-color: var(--emerald); }

/* Indice de raccourci — visible seulement au survol, jamais gênant */
.sidebar .nav-shortcut {
  margin-left: auto;
  font-size: .68rem;
  font-weight: 600;
  color: var(--sidebar-shortcut);
  border: 1px solid var(--sidebar-shortcut-border);
  border-radius: 4px;
  padding: 1px 5px;
  opacity: 0;
  transition: opacity var(--t-fast) var(--ease-std);
}
@media (hover: hover) {
  .sidebar .nav-item:hover .nav-shortcut { opacity: 1; }
}

/* Grand espace entre les opérations (Principal) et le reste (Équipe/Compte/Découvrir) */
.sidebar .nav-group-gap { margin-top: 14px; }

/* Labels de groupe */
.sidebar .nav-label {
  font-size: .65rem;
  font-weight: var(--weight-label);
  color: var(--sidebar-label);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  padding: 8px 12px 5px;
  display: block;
}

/* Dot indicateur */
.sidebar .nav-item .ni-dot,
.sidebar .nav-item .dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--emerald);
  opacity: 0;
  flex-shrink: 0;
  transition: opacity var(--t-fast);
}
.sidebar .nav-item.active .ni-dot,
.sidebar .nav-item.active .dot { opacity: 1; }

/* Footer */
.sidebar .sidebar-footer {
  margin-top: auto;
  padding: 12px 20px;
  border-top: 1px solid var(--sidebar-border);
  font-size: .76rem;
  color: var(--sidebar-footer-ink);
}
.sidebar .sidebar-footer strong {
  display: block;
  color: var(--sidebar-footer-strong);
  font-weight: 500;
  margin-bottom: 2px;
}

/* ── 4. Badges sémantiques ───────────────────────────────────────────────── */
/* Classe de base */
.badge {
  display: inline-flex;
  align-items: center;
  font-size: .72rem;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 20px;
  white-space: nowrap;
  line-height: 1.4;
}

/* Succès / Actif / Payé / Signé */
.badge.actif,
.badge.success,
.badge.paid,
.badge.signe    { background: var(--badge-success-bg);  color: var(--badge-success-txt); }

/* Attention / En attente */
.badge.attente,
.badge.warning,
.badge.pending  { background: var(--badge-warning-bg);  color: var(--badge-warning-txt); }

/* Erreur / Retard / Relance / Refusé */
.badge.relance,
.badge.error,
.badge.retard,
.badge.refuse   { background: var(--badge-error-bg);    color: var(--badge-error-txt);   }

/* Info / Repos / Neutre */
.badge.info,
.badge.repos,
.badge.neutral  { background: var(--badge-info-bg);     color: var(--badge-info-txt);    }

/* ── 5. Inputs — focus émeraude cohérent partout ─────────────────────────── */
input,
select,
textarea {
  color: var(--ink);
  transition:
    border-color var(--t-fast) var(--ease-std),
    box-shadow   var(--t-fast) var(--ease-std);
}
input::placeholder,
textarea::placeholder {
  color: var(--text-2);
  opacity: 1;
}
input:focus,
select:focus,
textarea:focus {
  border-color: var(--emerald) !important;
  box-shadow: 0 0 0 3px rgba(0,255,157,.1) !important;
  outline: none;
}

/* ── 6. Lignes de tableau — hover cohérent ───────────────────────────────── */
.client-row,
.client-card,
.employe-card,
.fiche-card,
.event-row,
.table-row {
  transition:
    background-color var(--t-fast) var(--ease-std),
    box-shadow       var(--t-std)  var(--ease-std);
}
@media (hover: hover) {
  .client-row:hover,
  .client-card:hover,
  .employe-card:hover,
  .fiche-card:hover,
  .event-row:hover,
  .table-row:hover { background-color: var(--row-hover-bg) !important; }

  tbody tr:hover { background-color: var(--tbody-hover-bg); }
}
@media (hover: none) {
  .client-row:active,
  .client-card:active,
  .employe-card:active,
  .fiche-card:active,
  .event-row:active,
  .table-row:active { background-color: var(--row-active-bg) !important; }

  tbody tr:active { background-color: var(--tbody-active-bg); }
}
tbody tr { transition: background-color var(--t-fast) var(--ease-std); }

/* ── 7. Modules / Cards — hover cohérent ────────────────────────────────── */
.module,
.metric-card,
.card,
[class*="-card"] {
  transition:
    border-color var(--t-std) var(--ease-std),
    box-shadow   var(--t-std) var(--ease-std);
}
@media (hover: hover) {
  .module:hover,
  .metric-card:hover {
    box-shadow: var(--shadow-glow);
    border-color: var(--module-hover-border);
  }
}

/* ── 98. Mobile safety overrides (site-wide) ───────────────────────────── */
/* Conservative overrides to prevent full-screen / sticky panels
   from breaking layout on small viewports and emulators. */
@media (max-width: 880px) {
  html, body { height: auto !important; min-height: 100%; }
  /* .sidebar reste gérée par la section "Mobile nav" (position:fixed, tiroir coulissant) —
     une règle position:relative!important ici l'empêchait de jamais passer hors-écran. */
  .sidebar .sidebar-footer { position: static; }
  /* Prevent panels using 100vh from covering content */
  [style*="100vh"]{ min-height: auto !important; height: auto !important; }
  /* Generic sticky safety: convert tall sticky elements to static flow */
  .sticky, .ob-right, .phone-frame, .phone-device { position: static !important; height: auto !important; }
  /* Reduce hero/title sizes on small screens */
  .w-title, h1.w-title, .hero-title { font-size: clamp(1.6rem, 6.2vw, 2.4rem) !important; line-height: 1.05 !important; }
  .w-sub, .hero-sub { max-width: 92% !important; margin: 0 auto 12px !important; }
  /* CTA full width */
  .btn-em, .btn { width: 100% !important; max-width: 420px !important; margin-left: auto !important; margin-right: auto !important; }
  /* Hide decorative globes or heavy visuals if present */
  .globe-wrap, .ob-globe-panel, .globe-panel, .phone-device, .phone-screen { display: none !important; }

  /* Exception au CTA full-width ci-dessus : un .btn-em a cote d'un champ
     dans une rangee flex (ex. .msg-input-row d'un panneau de messagerie
     -- client-fiche.html/employe-fiche.html) n'est PAS un CTA marketing
     isole. Meme classe de bug que le cas deja documente (CLAUDE.md,
     "barre d'outils a plusieurs boutons") : width:100%!important force
     le bouton a occuper toute la largeur de la rangee, ecrasant le champ
     texte a cote et poussant le bouton hors de l'ecran. Cible tactile
     >= 48px conservee, mais taille au contenu, pas a 100%. */
  .msg-input-row .btn-em,
  .msg-input-row input,
  .demande-controls .btn-em {
    width: auto !important;
    flex-shrink: 0;
  }
  .msg-input-row input,
  .msg-input { min-width: 0; font-size: 16px; min-height: 48px; }
  .msg-input-row .btn-em { min-height: 48px; }
}


/* ── 8. Focus visible global ─────────────────────────────────────────────── */
:focus-visible {
  outline: 2px solid var(--emerald);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ── 9. Liens sidebar ────────────────────────────────────────────────────── */
.sidebar a,
.nav-item {
  transition:
    color            var(--t-std) var(--ease-std),
    background-color var(--t-std) var(--ease-std),
    border-color     var(--t-std) var(--ease-std);
}

/* ── 10. Scrollbar discrète ──────────────────────────────────────────────── */
::-webkit-scrollbar       { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.22); }

/* ── 11. Skeleton Loading ────────────────────────────────────────────────── */
@keyframes shimmer {
  0%   { background-position: -600px 0; }
  100% { background-position:  600px 0; }
}
.skeleton {
  background:
    linear-gradient(90deg,
      rgba(5,5,5,0)          0%,
      rgba(0,255,157,.08)   40%,
      rgba(201,169,218,.06) 60%,
      rgba(5,5,5,0)        100%
    ) rgba(255,255,255,.05);
  background-size: 600px 100%;
  animation: shimmer 1.5s infinite linear;
  border-radius: 6px;
  color: transparent !important;
  user-select: none;
  pointer-events: none;
}
.skeleton-text   { height: 14px; margin-bottom: 8px; }
.skeleton-title  { height: 22px; margin-bottom: 12px; }
.skeleton-badge  { height: 20px; width: 70px; border-radius: 20px; }
.skeleton-metric { height: 40px; }
.skeleton-avatar { width: 36px; height: 36px; border-radius: 50%; }
.skeleton-line   { height: 12px; }
.skeleton-block  { height: 80px; }
.skeleton-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}
.skeleton-fade-out {
  animation: skFadeOut .4s var(--ease-std) forwards;
}
@keyframes skFadeOut {
  to { opacity: 0; height: 0; overflow: hidden; margin: 0; padding: 0; }
}
.content-fade-in {
  animation: skFadeIn .5s var(--ease-out) both;
}
@keyframes skFadeIn {
  from { opacity: 0; transform: translateY(6px); }
}

/* ── 12. Mobile — sidebar cachée + header hamburger ─────────────────────── */
.mobile-header {
  display: none;
  align-items: center;
  justify-content: space-between;
  padding: 13px 18px;
  background: var(--white);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 100;
}
.mobile-logo {
  font-size: .95rem;
  font-weight: 700;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 6px;
}
/* THEME-MOBILE-001 : .mobile-logo réutilise le balisage .logo-se/.logo-ba
   du logo marketing, mais .logo-se est câblé sur --ink-inverse (texte
   TOUJOURS blanc, prévu pour la sidebar qui reste toujours sombre — voir
   commentaire plus haut). .mobile-header, lui, SUIT le thème
   (background: var(--white)) : en thème clair, "Se" blanc sur fond blanc
   devenait invisible, seul "ba" (--text-2, gris, correctement adapté au
   thème) restait lisible -- remonté par le fondateur comme un logo
   tronqué "ba". Réaffecte --ink (thème-aware) uniquement dans ce
   contexte précis, sans toucher .logo-se/.logo-ba ailleurs (sidebar,
   pages marketing). */
.mobile-logo .logo-se { color: var(--ink); }
.mobile-logo-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--emerald);
}
.hamburger {
  width: 48px; height: 48px;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 5px;
  cursor: pointer;
  border: 1.5px solid var(--border);
  border-radius: var(--rs);
  background: transparent;
  padding: 0;
  transition: border-color var(--t-fast);
}
.hamburger span {
  width: 15px; height: 1.5px;
  background: var(--ink);
  border-radius: 99px;
  display: block;
}
@media (hover: hover) { .hamburger:hover { border-color: var(--ink); } }
@media (hover: none)  { .hamburger:active { border-color: var(--ink); opacity: .8; } }

/* Overlay (fermer la sidebar mobile en cliquant dehors) */
.sidebar-overlay {
  display: none;
  position: fixed;
  inset: 0;
  /* THEME-MOBILE-001 : .3 laissait trop voir/deviner le contenu derriere
     sur mobile (remonte fondateur, captures iPhone) -- .3 -> .5, la
     sidebar mobile ne fait que 224px avant ce chantier, contre un
     viewport souvent > 375px : le contenu visible derriere restait
     large et lisible. */
  background: var(--overlay-backdrop);
  z-index: 149;
}
.sidebar-overlay.open { display: block; }

/* THEME-MOBILE-001 (2026-07-29) : le FAB/panneau/backdrop de l'Assistant
   Seba (docs/ai-assistant.js, z-index 299-301) sont ajoutés en enfants
   directs de <body>, tout comme la sidebar mobile -- leur z-index les
   plaçait toujours AU-DESSUS de .sidebar/.sidebar-overlay (149-150), donc
   visibles et cliquables par-dessus le tiroir ouvert (remonté fondateur,
   captures iPhone : "Assistant flottant visible au-dessus de la
   sidebar"). Fix CSS pur (pas de nouvelle logique JS, pas de duplication
   dans les ~12 copies de toggleSidebar() par page) : masquer ces trois
   éléments tant que .sidebar.open existe quelque part dans <body>. */
body:has(.sidebar.open) .ai-chat-fab,
body:has(.sidebar.open) .ai-chat-panel,
body:has(.sidebar.open) .ai-chat-backdrop {
  display: none !important;
}

@media (max-width: 840px) {
  /* Cacher la sidebar dans la grille, l'afficher en overlay */
  /* minmax(0,1fr), pas 1fr seul : une piste de grille "1fr" garde un
     min-width:auto implicite = min-content de son contenu. Sur les pages
     avec un tableau responsive (table{min-width:560px} plus bas), la piste
     grandissait donc jusqu'a ~560-670px au lieu de tenir dans le viewport,
     poussant tout le contenu (et le bouton hamburger) hors de l'ecran. */
  .app,
  .layout { grid-template-columns: minmax(0,1fr) !important; }

  .sidebar {
    position: fixed;
    left: 0; top: 0; bottom: 0;
    z-index: 150;
    /* THEME-MOBILE-001 : 224px fixe = ~60% de la largeur d'un iPhone SE
       (375px) -- trop large (remonte fondateur, captures iPhone). Reste
       borne des deux cotes : jamais plus de 86% du viewport (petits
       ecrans), jamais plus de 320px (grands mobiles/tablette portrait). */
    width: min(86vw, 320px);
    height: 100%;
    transform: translateX(-100%);
    transition: transform .25s var(--ease-std);
    box-shadow: none;
    /* SETTINGS-BRAND-001 (2026-07-29) : la sidebar est position:fixed,
       top:0, bottom:0 -- couvre tout l'écran y compris sous l'encoche/la
       barre de statut et au-dessus de la barre d'accueil iOS. padding:18px 0
       (règle de base, non mobile) ne réservait AUCUN espace pour ces zones
       -- le premier item ("Tableau de bord") se retrouvait partiellement
       sous l'encoche, le dernier au ras de la barre d'accueil (remonté
       fondateur : "le premier item... est partiellement caché en haut").
       Même mécanisme déjà utilisé par .mobile-header juste en dessous,
       jamais appliqué ici jusqu'à présent. */
    padding-top: calc(18px + env(safe-area-inset-top, 0px));
    padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  }
  .sidebar.open {
    transform: translateX(0);
    box-shadow: 4px 0 24px rgba(0,0,0,.12);
  }

  .mobile-header {
    display: flex !important;
    padding-top: calc(13px + env(safe-area-inset-top, 0px));
  }

  .main,
  .page-main {
    padding: 20px 16px calc(48px + env(safe-area-inset-bottom, 0px)) !important;
  }

  /* Cibles tactiles >= 48px + espacement >= 16px (cahier des charges
     mobile 2026-07-19). Le rail desktop reste a 40px (densite visuelle
     voulue en usage souris) -- uniquement releve sous ce seuil, jamais en
     desktop. */
  .sidebar .nav-item,
  .sidebar .nav-item:hover,
  .sidebar .nav-item:active,
  .sidebar .nav-item.active,
  .sidebar .nav-item:focus-visible { min-height: 48px; }

  /* iOS zoome automatiquement au focus sur tout champ < 16px. */
  input, select, textarea { font-size: 16px !important; -webkit-appearance: none; appearance: none; }

  /* Pas de min-height:48px generique sur button/.btn/[class*="btn-"] ici :
     cette classe de regle globale a deja casse une barre d'outils par le
     passe quand appliquee sans verifier chaque page (CLAUDE.md, "Leçons
     apprises" -- .btn-em width:100%). Les boutons/toggles concretement
     verifies sous 48px sur mobile sont corriges au cas par cas
     (.hamburger ci-dessus, .msg-input-row .btn-em plus bas, .sidebar
     .nav-item ci-dessus) plutot qu'un forçage aveugle. */
}

@media (min-width: 841px) {
  .mobile-header { display: none !important; }
  .sidebar-overlay { display: none !important; }
}

/* ── 13. Responsive tableaux (scroll horizontal sur mobile) ─────────────── */
@media (max-width: 640px) {
  .panel,
  .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  table { min-width: 560px; }
}

/* ── 14. Typographie — hiérarchie unifiée ───────────────────────────────── */
/* H1 de page */
.page-title,
.topbar h1 { font-size: 1.45rem; font-weight: 700; letter-spacing: -.025em; }

/* H2 section / module-title */
.module-title,
.section-title { font-size: .85rem; font-weight: 600; }

/* Labels de champs */
label,
.field-label { font-size: .82rem; font-weight: 600; color: var(--text-2); }

/* Texte secondaire */
.text-2,
.sub { color: var(--text-2); font-size: .83rem; }

/* ── 15. Espacements unifiés — utilitaires 8px grid ─────────────────────── */
.gap-8  { gap: 8px; }
.gap-12 { gap: 12px; }
.gap-16 { gap: 16px; }
.gap-24 { gap: 24px; }
.mb-8   { margin-bottom: 8px; }
.mb-16  { margin-bottom: 16px; }
.mb-24  { margin-bottom: 24px; }
.mb-32  { margin-bottom: 32px; }

/* ── 16. Entrée de page — fluidité navigation ───────────────────────────── */
@keyframes pageIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
.main,
.page-main {
  animation: pageIn .32s cubic-bezier(0.0, 0, 0.2, 1) both;
}

/* Sortie douce avant navigation */
@keyframes pageOut {
  to { opacity: 0; transform: translateY(-8px); }
}
body.page-leaving .main,
body.page-leaving .page-main {
  animation: pageOut .2s var(--ease-in) forwards;
}

/* ── 17. Liens de navigation — exit hook ────────────────────────────────── */
