/* VALIDEO — Mode Board (refonte UI)
   Thème via [data-theme="light"|"dark"] sur <html>.
   Accent bleu réutilise la palette existante. */

/* ── Garde anti-animation au chargement ──
   Pendant le boot (classe posée par le head, retirée par board.js après le
   1er paint), on coupe les transitions des colonnes rétractables. Le JS
   restaure l'état replié/déplié APRÈS le paint ; sans ce garde, la largeur
   s'anime de déplié→replié à chaque rechargement (le "redéploiement"
   désagréable). Les toggles manuels après boot restent animés. */
html.board-booting .board-sidebar,
html.board-booting .board-sidebar *,
html.board-booting .bsub,
html.board-booting .bsub * {
  transition: none !important;
  animation: none !important;
}

:root {
  /* Marge latérale commune à TOUTES les pages du board — un outil ne doit pas
     respirer autrement qu'un autre. Elle vit ici, pas dans chaque feuille
     d'outil, sinon elle diverge au premier oubli. */
  --b-page-gutter: 32px;
}

:root,
[data-theme="light"] {
  --b-bg:        #f5f6f8;
  --b-surface:   #ffffff;
  --b-surface-2: #fafbfc;
  --b-border:    #e3e5ea;
  --b-border-strong: #cdd0d7;
  --b-text:      #1a1d23;
  --b-text-muted:#6b7280;
  --b-text-soft: #9aa0aa;
  /* ── Palette de marque (dérivée du logo Validz) ──────────────────
     Le logo va du vert #5AF583 au bleu #3B80E7 en passant par le teal
     #42C1C0. On en tire trois rôles, jamais mélangés :
       bleu = action (boutons, liens, focus, sélection)
       teal = accent secondaire (outils IA, états actifs, progression)
       vert = succès uniquement (validé, en ligne, terminé)
     Les valeurs sont assombries par rapport au logo pour tenir le
     contraste AA du texte blanc (4.7:1 sur le bleu, 4.65:1 sur
     --b-teal-strong). Orange et rouge restent hors marque : ce sont des
     signaux d'alerte, les teindre en vert ou bleu les rendrait muets. */
  --b-accent:    #2c71d6;   /* bleu logo, assombri pour le contraste */
  --b-accent-hover:#2260be;
  --b-accent-soft:#dce9fb;
  --b-teal:      #0e9c93;   /* aplats, bordures, pastilles */
  --b-teal-strong:#0b7f78;  /* fonds portant du texte blanc */
  --b-teal-soft: #d8f1ee;
  --b-ok:        #12a150;
  --b-warn:      #f59e0b;
  --b-bad:       #dc2626;
  --b-shadow:    none;
  --b-topbar-bg: #ffffff;
  --b-sidebar-bg:#ffffff;
  --b-sidebar-active-bg: #eef4fd;
}

[data-theme="dark"] {
  --b-bg:        #0f1115;
  --b-surface:   #171a21;
  --b-surface-2: #1d2128;
  --b-border:    #262b34;
  --b-border-strong: #353c47;
  --b-text:      #e8eaef;
  --b-text-muted:#9098a4;
  --b-text-soft: #6b7280;
  --b-accent:    #3b80e7;   /* le bleu du logo tel quel : lisible sur fond sombre */
  --b-accent-hover:#5c97ee;
  --b-accent-soft:#1b2a3f;
  --b-teal:      #2fc0b4;
  --b-teal-strong:#12a79d;
  --b-teal-soft: #14312f;
  --b-ok:        #34c77b;
  --b-warn:      #fbbf24;
  --b-bad:       #ef4444;
  --b-shadow:    none;
  --b-topbar-bg: #14171d;
  --b-sidebar-bg:#14171d;
  --b-sidebar-active-bg: #1e2530;
}

* { box-sizing: border-box; }

/* Icônes SVG inline */
.b-ico { display: inline-block; vertical-align: -3px; flex-shrink: 0; }
.board-btn .b-ico,
.board-iconbtn .b-ico { vertical-align: middle; }
.board-btn { display: inline-flex; align-items: center; gap: 6px; }
.board-tab { display: inline-flex; align-items: center; gap: 6px; }
.board-breadcrumb { display: inline-flex; align-items: center; gap: 6px; }
.bt-badge { display: inline-flex; align-items: center; gap: 4px; }
.board-radio span { display: inline-flex; align-items: center; gap: 8px; }

html, body { margin: 0; padding: 0; }

/* ─── Chat docké en sous-rail bis (déclenché par .board-chat-docked sur <html>) ─── */

/* En mode board, on neutralise toujours le handle/backdrop legacy.
   L'ouverture passe exclusivement par le menu "Chat" de la sidebar. */
.board-body .gchat__handle,
.board-body .gchat__handle-text,
.board-body .gchat__handle-arrow,
.board-body #gchatHandle,
.board-body .gchat__backdrop { display: none !important; }

/* Quand le chat est docké, on l'affiche en sous-rail à droite du menu,
   pleine hauteur (top: 0) et restylé au thème board. */
:root {
  --bchat-w: 320px;            /* largeur "ouverte" (resizable) */
  --bchat-shrunk: 200px;       /* largeur "bande" auto */
}
html.board-chat-docked .gchat__panel {
  position: fixed !important;
  top: 0 !important;
  left: 80px !important;
  right: auto !important;
  bottom: 0 !important;
  width: var(--bchat-w) !important;
  height: auto !important;
  transform: none !important;
  z-index: 25 !important;
  opacity: 1 !important;
  visibility: visible !important;
  transition: width .25s ease !important;

  /* ─── Restyle au thème board (clair/sombre via variables) ─── */
  background: var(--b-sidebar-bg) !important;
  color: var(--b-text) !important;
  border-right: 1px solid var(--b-border) !important;
  border-left: none !important;
  box-shadow: none !important;
  font-family: inherit !important;
}

/* Force toutes les couleurs de texte sur fond clair (sinon texte blanc legacy invisible) */
html.board-chat-docked .gchat__panel,
html.board-chat-docked .gchat__panel * { color: var(--b-text); }
html.board-chat-docked .gchat__panel [class*="muted"],
html.board-chat-docked .gchat__panel [class*="meta"],
html.board-chat-docked .gchat__panel [class*="time"],
html.board-chat-docked .gchat__panel [class*="hint"] { color: var(--b-text-muted) !important; }
html.board-chat-docked .gchat__panel .gchat__msg.is-mine .gchat__bubble,
html.board-chat-docked .gchat__panel .gchat__msg.is-mine .gchat__bubble * { color: #fff !important; }
/* Conversations NON LUES : les règles legacy `.is-unread .…-title/-preview` (spécificité
   0,3,0) battent le `*` ci-dessus (0,2,1) → texte blanc invisible sur fond clair. On les
   ré-override explicitement au thème board (titre + preview = texte plein, le gras legacy reste). */
html.board-chat-docked .gchat__panel .gchat__convitem.is-unread .gchat__convitem-title,
html.board-chat-docked .gchat__panel .gchat__convitem.is-unread .gchat__convitem-preview { color: var(--b-text) !important; }
/* Override les couleurs RGBA blanches du legacy (texte sur fond sombre original) */
html.board-chat-docked .gchat__panel [style*="rgba(255"] { color: var(--b-text) !important; }

/* Header du chat : padding-top pour décaler la barre native macOS si besoin */
html.board-chat-docked .gchat__head {
  background: var(--b-surface) !important;
  border-bottom: 1px solid var(--b-border) !important;
  color: var(--b-text) !important;
}
html.board-chat-docked .gchat__head-title { color: var(--b-text) !important; }
html.board-chat-docked .gchat__head-meta { color: var(--b-text-muted) !important; }

/* Boutons icône */
html.board-chat-docked .gchat__icon-btn,
html.board-chat-docked .gchat__close {
  background: transparent !important;
  border: 1px solid var(--b-border) !important;
  color: var(--b-text-muted) !important;
  border-radius: 6px !important;
}
html.board-chat-docked .gchat__icon-btn:hover,
html.board-chat-docked .gchat__close:hover {
  background: var(--b-surface-2) !important;
  color: var(--b-accent) !important;
  border-color: var(--b-accent) !important;
}

/* Liste conversations / messages : fond neutre */
html.board-chat-docked .gchat__view,
html.board-chat-docked .gchat__body,
html.board-chat-docked .gchat__list { background: var(--b-sidebar-bg) !important; }

html.board-chat-docked .gchat__conv,
html.board-chat-docked .gchat__convo-item {
  background: transparent !important;
  border-bottom: 1px solid var(--b-border) !important;
  color: var(--b-text) !important;
}
html.board-chat-docked .gchat__conv:hover,
html.board-chat-docked .gchat__convo-item:hover { background: var(--b-surface-2) !important; }
html.board-chat-docked .gchat__conv.is-active,
html.board-chat-docked .gchat__convo-item.is-active {
  background: var(--b-sidebar-active-bg) !important;
  color: var(--b-accent) !important;
  border-left: 3px solid var(--b-accent) !important;
}

/* Bulles de messages.
   Le markup réel met la coloration sur .gchat__body (variantes is-mine/is-ai/
   is-system), PAS sur .gchat__bubble. On laisse donc le bubble transparent
   (sinon chaque ligne de texte se retrouve encadrée), et on stylise le body. */
html.board-chat-docked .gchat__bubble {
  background: transparent !important;
  color: var(--b-text) !important;
  border: 0 !important;
  box-shadow: none !important;
}
/* Mes messages : bulle accent (le body porte le fond) */
html.board-chat-docked .gchat__msg.is-mine .gchat__body {
  background: var(--b-accent) !important;
  border: 1px solid var(--b-accent) !important;
}
html.board-chat-docked .gchat__msg.is-mine .gchat__bubble,
html.board-chat-docked .gchat__msg.is-mine .gchat__name,
html.board-chat-docked .gchat__msg.is-mine .gchat__time { color: #fff !important; }
/* Messages IA */
html.board-chat-docked .gchat__msg.is-ai .gchat__body {
  background: #f3effe !important;
  border: 1px solid #d9cdf7 !important;
}
/* Messages système : pastille discrète */
html.board-chat-docked .gchat__msg.is-system .gchat__body {
  background: var(--b-surface-2) !important;
  border: 1px solid var(--b-border) !important;
}

/* Inputs / textarea */
html.board-chat-docked .gchat__input,
html.board-chat-docked .gchat__composer textarea,
html.board-chat-docked .gchat__search input {
  background: var(--b-surface) !important;
  border: 1px solid var(--b-border) !important;
  color: var(--b-text) !important;
  border-radius: 6px !important;
}
html.board-chat-docked .gchat__input:focus,
html.board-chat-docked .gchat__composer textarea:focus,
html.board-chat-docked .gchat__search input:focus {
  border-color: var(--b-accent) !important;
  outline: none !important;
  box-shadow: 0 0 0 3px var(--b-accent-soft) !important;
}

/* Onglets Conversations / Notifications — repeints aux couleurs du thème board
   (le CSS du widget est écrit pour le panneau sombre historique). */
html.board-chat-docked .gchat__tab {
  background: var(--b-surface-2) !important;
  border: 1px solid var(--b-border) !important;
  color: var(--b-text-muted) !important;
}
html.board-chat-docked .gchat__tab:hover { background: var(--b-sidebar-active-bg) !important; color: var(--b-text) !important; }
html.board-chat-docked .gchat__tab.is-active {
  background: var(--b-accent-soft) !important;
  border-color: var(--b-accent) !important;
  color: var(--b-accent) !important;
}
html.board-chat-docked .gchat__tab-badge { background: var(--b-bad) !important; color: #fff !important; }

/* Annuaire « Nouveau message » : la pastille de sélection doit rester vide tant
   que la personne n'est pas choisie. La règle générique du thème board
   (`.gchat__panel *` → couleur de texte) rendait la coche visible partout. */
html.board-chat-docked .gchat__panel .gchat__useritem-check {
  color: transparent !important;
  border-color: var(--b-border-strong) !important;
}
html.board-chat-docked .gchat__panel .gchat__useritem.is-selected .gchat__useritem-check {
  background: var(--b-accent) !important;
  border-color: var(--b-accent) !important;
  color: #fff !important;
}

/* État "bande" : largeur réduite quand l'utilisateur travaille à droite */
html.board-chat-docked.is-chat-shrunk .gchat__panel { width: var(--bchat-shrunk) !important; }

/* Décale le contenu principal ET la topbar */
html.board-chat-docked .board-main   { margin-left: calc(80px + var(--bchat-w)); transition: margin-left .25s ease; }
html.board-chat-docked .board-topbar { left: calc(80px + var(--bchat-w)); transition: left .25s ease; }
html.board-chat-docked.is-chat-shrunk .board-main   { margin-left: calc(80px + var(--bchat-shrunk)); }
html.board-chat-docked.is-chat-shrunk .board-topbar { left: calc(80px + var(--bchat-shrunk)); }

/* Poignée de redimensionnement */
.bchat-resize {
  position: absolute;
  top: 0; bottom: 0;
  right: -3px;
  width: 6px;
  cursor: ew-resize;
  background: transparent;
  z-index: 26;
}
.bchat-resize:hover,
.bchat-resize.is-dragging {
  background: color-mix(in srgb, var(--b-accent) 45%, transparent);
}
body.bchat-resizing,
body.bchat-resizing * { user-select: none !important; cursor: ew-resize !important; }

/* Le legacy ajoute `gchat-shift-open` qui décale le body — on neutralise. */
html.board-chat-docked.gchat-shift-open body { margin-left: 0 !important; }

/* Le legacy applique `body { padding-left: var(--gchat-shift) }` (rail
   placeholder de 40px par défaut, 360px chat ouvert). En mode board on a
   notre propre layout — toujours neutraliser ce rail, qu'on soit docké ou
   chat fermé : ça créait sinon une bande grise inutile entre la sidebar
   principale et le contenu / sous-sidebar projet. */
body.board-body { padding-left: 0 !important; }

@media (max-width: 1024px) {
  html.board-chat-docked .gchat__panel { width: calc(100vw - 80px) !important; left: 80px; }
  html.board-chat-docked .board-main   { margin-left: 80px; }
  html.board-chat-docked .board-topbar { left: 80px; }
}

/* ─── Page dédiée « Chat » plein écran, 2 panneaux façon Slack (board-chat-page)
   Colonne GAUCHE = liste des conversations (toujours visible) ; colonne DROITE
   = conversation active (messages Slack : avatar + nom + heure + texte à gauche).
   N'affecte QUE cette page (tout est scopé html.board-chat-page). */
html.board-chat-page .gchat__panel {
  left: 80px !important;
  right: 0 !important;
  top: 0 !important;
  bottom: 0 !important;
  width: auto !important;
  display: flex !important;
  flex-direction: row !important;
  background: var(--b-bg, #fff) !important;
}
/* Les vues sont empilées en position:absolute par défaut (1 seule à la fois).
   Sur la page on les remet EN FLUX pour un vrai 2 panneaux côte à côte. */
html.board-chat-page .gchat__view {
  position: relative !important;
  inset: auto !important;
}
/* Pas de topbar ni de main board : le chat EST la page. */
html.board-chat-page .board-topbar { display: none !important; }
html.board-chat-page #board-main    { display: none !important; }
html.board-chat-page .board-main    { margin-left: 80px !important; }
html.board-chat-page .bchat-resize  { display: none !important; }
html.board-chat-page.is-chat-shrunk .gchat__panel { width: auto !important; }

/* Colonne gauche : liste, toujours affichée (on force malgré [hidden] de setView). */
html.board-chat-page .gchat__view--home {
  display: flex !important;
  flex: 0 0 300px !important;
  width: 300px !important;
  max-width: 300px !important;
  margin: 0 !important;
  border-right: 1px solid var(--b-border) !important;
}
/* Colonne droite : la vue active (conv / new / présence / corbeille) remplit. */
html.board-chat-page .gchat__view:not(.gchat__view--home) {
  flex: 1 1 auto !important;
  width: auto !important;
  max-width: none !important;
  margin: 0 !important;
}
/* ─── Page dédiée : « Nouveau message » en vraie fenêtre modale centrée ───
   Ailleurs (volet docké étroit), la vue reste une sous-page plein panneau. */
/* `absolute` et non `fixed` : le panneau est en `overflow:hidden`, et un enfant
   `position:fixed` n'y était pas repeint de façon fiable (voile invisible).
   Le panneau couvre déjà toute la page hors rail → centrer dessus suffit. */
html.board-chat-page .gchat__view--new {
  position: absolute !important;
  top: 50% !important; left: 50% !important;
  transform: translate(-50%, -50%) !important;
  flex: 0 0 auto !important;
  width: min(460px, calc(100vw - 140px)) !important;
  max-width: none !important;
  height: min(600px, calc(100vh - 80px)) !important;
  background: var(--b-surface) !important;
  border: 1px solid var(--b-border) !important;
  border-radius: 14px !important;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .28) !important;
  overflow: hidden !important;
  z-index: 61 !important;
}
/* Voile : élément dédié, affiché seulement sur la page Chat quand la fenêtre
   est ouverte (ailleurs la vue « new » reste une sous-page, sans voile). */
/* Couleur opaque + `opacity` séparée : en `background: rgba(…)` le voile
   n'était pas peint sur cette page (couche composite du panneau), alors qu'il
   mesurait bien toute la surface. */
html.board-chat-page .gchat__modal-veil {
  position: absolute !important; inset: 0 !important;
  background: #0f1115 !important;
  opacity: .55 !important;
  z-index: 60 !important;
}
/* Dans une fenêtre, la flèche « retour » n'a pas de sens — le ✕ la remplace
   (il est masqué par défaut sur cette page, on le réaffiche ici). */
html.board-chat-page .gchat__view--new .gchat__back { display: none !important; }
html.board-chat-page .gchat__view--new .gchat__close {
  display: inline-flex !important;
  color: var(--b-text-muted) !important;
}

/* Messages en style Slack : plus de « boîte » pour mes propres messages. */
html.board-chat-page .gchat__msg.is-mine .gchat__body {
  background: transparent !important;
  border: 0 !important;
  padding: 0 !important;
}
html.board-chat-page .gchat__msg.is-mine .gchat__name { color: var(--b-accent, #2c71d6) !important; }
/* Le mode docké met le texte de MES messages en blanc (ancienne box bleue) →
   invisible sur fond clair ici. On force la couleur de texte du thème.
   `.gchat__panel` dans le sélecteur pour battre la spécificité du docké. */
html.board-chat-page .gchat__panel .gchat__msg.is-mine .gchat__bubble,
html.board-chat-page .gchat__panel .gchat__msg.is-mine .gchat__bubble * { color: var(--b-text) !important; }
html.board-chat-page .gchat__msg { padding: 3px 6px; border-radius: 6px; }
html.board-chat-page .gchat__msg:hover { background: var(--b-surface-2); }
/* Zone messages large et aérée. */
html.board-chat-page .gchat__messages { padding-inline: 8px; }
/* L'aperçu de pièce jointe (fond sombre) restait rendu → barre noire. On
   garantit qu'il reste masqué tant qu'il est vide, et au thème sinon. */
html.board-chat-page .gchat__attach-preview[hidden] { display: none !important; }
html.board-chat-page .gchat__attach-preview { background: var(--b-surface-2) !important; }
/* Bouton « retour » de la conversation inutile en 2 panneaux. */
html.board-chat-page #gchatCloseConv { display: none !important; }
/* Le ✕ « fermer » et le « plein écran » n'ont pas de sens ici. */
html.board-chat-page .gchat__close,
html.board-chat-page .gchat__fullscreen { display: none !important; }

/* ═══ Page dédiée : messages en BULLES façon WhatsApp (implémentation maison) ═══ */
html.board-chat-page .gchat__messages {
  --wa-bg: #efeae2; --wa-in: #ffffff; --wa-out: #d9fdd3;
  --wa-meta: rgba(0,0,0,.45); --wa-check: #2f9fd0;
  background-color: var(--wa-bg) !important;
  padding: 10px 7% 18px !important;
}
html.board-chat-page[data-theme="dark"] .gchat__messages {
  --wa-bg: #0b141a; --wa-in: #202c33; --wa-out: #005c4b; --wa-meta: rgba(233,237,239,.6);
  --wa-check: #53bdeb;
}
/* Alignement : autres à gauche, moi à droite. Pas d'avatar par message. */
html.board-chat-page .gchat__msg { align-items: flex-end !important; gap: 0 !important; margin: 2px 0 !important; justify-content: flex-start !important; }
html.board-chat-page .gchat__msg.is-mine { justify-content: flex-end !important; }
html.board-chat-page .gchat__msg .gchat__avatar { display: none !important; }
/* La bulle = le corps du message. */
html.board-chat-page .gchat__body {
  position: relative !important;
  flex: 0 1 auto !important;
  /* Cap en px en plus du % : sur un écran large, 74 % donnait des bulles qui
     traversaient tout l'écran, illisibles (WhatsApp s'arrête ~600 px). */
  max-width: min(65%, 600px) !important; min-width: 58px !important;
  background: var(--wa-in) !important;
  color: var(--b-text) !important;
  border: 0 !important;
  border-radius: 8px !important;
  padding: 5px 9px 16px !important;             /* place en bas pour l'heure */
  box-shadow: 0 1px .6px rgba(0,0,0,.13) !important;
}
html.board-chat-page .gchat__msg.is-mine .gchat__body { background: var(--wa-out) !important; }
/* 1re bulle d'un groupe : coin pointu + petite queue côté expéditeur. */
html.board-chat-page .gchat__msg:not(.is-grouped) .gchat__body { border-top-left-radius: 0 !important; }
html.board-chat-page .gchat__msg.is-mine:not(.is-grouped) .gchat__body { border-top-left-radius: 8px !important; border-top-right-radius: 0 !important; }
html.board-chat-page .gchat__msg:not(.is-grouped):not(.is-mine) .gchat__body::before {
  content: '' !important; position: absolute !important; left: -7px !important; top: 0 !important;
  width: 0 !important; height: 0 !important;
  border-style: solid !important; border-width: 0 8px 8px 0 !important;
  border-color: transparent var(--wa-in) transparent transparent !important;
}
html.board-chat-page .gchat__msg.is-mine:not(.is-grouped) .gchat__body::before {
  content: '' !important; position: absolute !important; right: -7px !important; top: 0 !important;
  width: 0 !important; height: 0 !important;
  border-style: solid !important; border-width: 0 0 8px 8px !important;
  border-color: transparent transparent transparent var(--wa-out) !important;
}
/* Nom de l'expéditeur : en GROUPE seulement (pas moi), en haut de la bulle. */
html.board-chat-page .gchat__messages.gchat--dm .gchat__name { display: none !important; }
html.board-chat-page .gchat__messages.gchat--group .gchat__msg.is-mine .gchat__name { display: none !important; }
html.board-chat-page .gchat__name { font-size: 12.5px !important; font-weight: 600 !important; }
/* On réaffiche la ligne pour les messages groupés (pour l'heure), sans le nom. */
html.board-chat-page .gchat__msg.is-grouped .gchat__row { display: block !important; min-height: 0 !important; margin: 0 !important; }
html.board-chat-page .gchat__msg.is-grouped .gchat__name { display: none !important; }
/* Mes messages n'ont jamais besoin de mon propre nom : la bulle est à droite. */
html.board-chat-page .gchat__panel .gchat__msg.is-mine .gchat__name { display: none !important; }
/* Heure ancrée en bas-droite dans la bulle (+ coches pour mes messages).
   Sélecteurs préfixés `.gchat__panel` : sinon la règle générique du thème board
   (`html.board-chat-docked .gchat__panel [class*="time"]`, elle aussi
   `!important` et plus spécifique) repeignait l'heure en gris très pâle,
   illisible sur le vert des bulles sortantes. */
html.board-chat-page .gchat__row { position: static !important; }
html.board-chat-page .gchat__panel .gchat__time {
  position: absolute !important; right: 8px !important; bottom: 3px !important;
  font-size: 10.5px !important; color: var(--wa-meta) !important;
  white-space: nowrap !important; pointer-events: none !important;
}
html.board-chat-page .gchat__panel .gchat__msg.is-mine .gchat__time,
html.board-chat-page .gchat__panel .gchat__msg.is-mine .gchat__time * { color: var(--wa-meta) !important; }
html.board-chat-page .gchat__panel .gchat__msg.is-mine .gchat__time::after {
  content: '✓✓' !important; margin-left: 3px !important; letter-spacing: -2px !important;
  font-size: 10px !important; color: var(--wa-check, #53bdeb) !important;
}
html.board-chat-page .gchat__bubble { font-size: 13.5px !important; color: var(--b-text) !important; }
/* Boutons modifier / supprimer : HORS FLUX. En flux ils réservaient 22 px sous
   chaque message et creusaient un grand vide dans la bulle. Ils viennent se
   poser à côté de la bulle, révélés au survol du message (comme WhatsApp). */
html.board-chat-page .gchat__panel .gchat__msg-edit,
html.board-chat-page .gchat__panel .gchat__msg-delete {
  position: absolute !important; top: 0 !important; margin: 0 !important;
  background: var(--b-surface) !important; border-color: var(--b-border) !important;
  color: var(--b-text-muted) !important;
}
html.board-chat-page .gchat__panel .gchat__msg:not(.is-mine) .gchat__msg-delete { right: -26px !important; }
html.board-chat-page .gchat__panel .gchat__msg:not(.is-mine) .gchat__msg-edit   { right: -52px !important; }
html.board-chat-page .gchat__panel .gchat__msg.is-mine .gchat__msg-delete { left: -26px !important; }
html.board-chat-page .gchat__panel .gchat__msg.is-mine .gchat__msg-edit   { left: -52px !important; }
/* Séparateur de jour = pastille centrée (style WhatsApp). Le nœud rendu est un
   simple <div> sans <span> interne : `width: max-content` + marges auto le font
   se rétracter au texte, sinon on obtenait une barre blanche pleine largeur. */
html.board-chat-page .gchat__day { text-transform: none !important; }
html.board-chat-page .gchat__day::before, html.board-chat-page .gchat__day::after { display: none !important; }
html.board-chat-page .gchat__day {
  display: block !important;
  width: max-content !important; max-width: 80% !important;
  margin: 14px auto !important;
  background: var(--wa-in) !important; color: var(--wa-meta) !important;
  border-radius: 8px !important; padding: 5px 12px !important;
  box-shadow: 0 1px .6px rgba(0,0,0,.13) !important; font-size: 12px !important; font-weight: 500 !important;
}

/* ─── Quick chat docké : RAIL d'avatars horizontal en haut + CONVERSATION en
   dessous (≈3/4 hauteur). Volet étroit, non surchargé. Scopé
   `:not(.board-chat-page)` pour ne pas toucher la page dédiée (2 colonnes). */
:root { --bchat-w: 360px; }
/* Panneau en colonne ; vues remises EN FLUX pour empiler rail (home) + conv. */
html.board-chat-docked:not(.board-chat-page) .gchat__panel {
  display: flex !important;
  flex-direction: column !important;
}
html.board-chat-docked:not(.board-chat-page) .gchat__view {
  position: relative !important;
  inset: auto !important;
}
/* HOME = rail compact en haut, toujours visible (même conv ouverte). */
html.board-chat-docked:not(.board-chat-page) .gchat__view--home {
  display: flex !important;
  flex: 0 0 auto !important;
  height: auto !important;
  border-bottom: 1px solid var(--b-border) !important;
}
/* Dans le rail : masquer la grosse recherche + le FAB (place au rail). */
html.board-chat-docked:not(.board-chat-page) .gchat__view--home .gchat__search,
html.board-chat-docked:not(.board-chat-page) .gchat__view--home .gchat__fab { display: none !important; }
/* La liste devient une bande horizontale d'avatars. */
html.board-chat-docked:not(.board-chat-page) .gchat__convlist {
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: wrap !important;            /* multi-lignes : toutes les pastilles visibles */
  align-content: flex-start !important;
  justify-content: flex-start !important;
  overflow-x: hidden !important;
  overflow-y: auto !important;           /* filet si vraiment trop de conversations */
  max-height: 46vh !important;           /* garde de la place pour la conversation */
  gap: 2px !important;
  padding: 6px 6px 7px !important;
}
html.board-chat-docked:not(.board-chat-page) .gchat__section-header { display: none !important; }
/* Chaque conv = puce verticale compacte : avatar rond + nom minuscule dessous. */
html.board-chat-docked:not(.board-chat-page) .gchat__convitem {
  flex: 0 0 auto !important;
  flex-direction: column !important;
  align-items: center !important;
  width: 42px !important;
  padding: 1px !important;
  gap: 2px !important;
  background: transparent !important;
}
html.board-chat-docked:not(.board-chat-page) .gchat__convitem::before { display: none !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__convitem-time,
html.board-chat-docked:not(.board-chat-page) .gchat__convitem-preview { display: none !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__convitem-avatar { width: 30px !important; height: 30px !important; font-size: 11px !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__convitem-avatar.is-online::after { width: 7px !important; height: 7px !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__convitem-body { flex: none !important; width: 100% !important; min-width: 0 !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__convitem-row { justify-content: center !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__convitem-title {
  font-size: 8.5px !important; font-weight: 600 !important; line-height: 1.1 !important;
  max-width: 40px !important; text-align: center !important;
}
/* Badge non-lu = petite pastille en coin d'avatar. */
html.board-chat-docked:not(.board-chat-page) .gchat__convitem-badge {
  position: absolute !important;
  top: -1px !important; right: 3px !important;
  min-width: 13px !important; height: 13px !important; padding: 0 3px !important;
  line-height: 13px !important; font-size: 8px !important;
}
/* Conv active = anneau accent autour de l'avatar. */
html.board-chat-docked:not(.board-chat-page) .gchat__convitem.is-active .gchat__convitem-avatar {
  box-shadow: 0 0 0 2px var(--b-accent) !important;
}
/* CONVERSATION = dessous, prend le reste (~3/4). */
html.board-chat-docked:not(.board-chat-page) .gchat__view[data-view="conv"],
html.board-chat-docked:not(.board-chat-page) .gchat__view[data-view="new"],
html.board-chat-docked:not(.board-chat-page) .gchat__view[data-view="presence"],
html.board-chat-docked:not(.board-chat-page) .gchat__view[data-view="trash"] {
  flex: 1 1 auto !important;
  min-height: 0 !important;
}
/* Messages Slack : pas de boîte is-mine + texte au thème (docké met #fff → invisible clair). */
html.board-chat-docked:not(.board-chat-page) .gchat__msg.is-mine .gchat__body { background: transparent !important; border: 0 !important; padding: 0 !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__panel .gchat__msg.is-mine .gchat__bubble,
html.board-chat-docked:not(.board-chat-page) .gchat__panel .gchat__msg.is-mine .gchat__bubble * { color: var(--b-text) !important; }
/* Retour conv inutile (le rail sert à changer). Aperçu PJ sombre masqué. */
html.board-chat-docked:not(.board-chat-page) #gchatCloseConv { display: none !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__attach-preview[hidden] { display: none !important; }
/* En-tête conv : on retire la flèche retour + l'avatar (redondants avec le
   rail), mais on GARDE le nom de la personne. Nom à gauche, actions à droite. */
html.board-chat-docked:not(.board-chat-page) .gchat__view--conv .gchat__back,
html.board-chat-docked:not(.board-chat-page) .gchat__view--conv .gchat__head-avatar { display: none !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__view--conv .gchat__head {
  padding-top: 5px !important; padding-bottom: 5px !important;
  min-height: 0 !important;
}
html.board-chat-docked:not(.board-chat-page) .gchat__view--conv .gchat__head-info { flex: 1 1 auto !important; min-width: 0 !important; }
/* Le contenu s'adapte à la largeur du volet : rien ne déborde horizontalement. */
html.board-chat-docked:not(.board-chat-page) .gchat__panel,
html.board-chat-docked:not(.board-chat-page) .gchat__view,
html.board-chat-docked:not(.board-chat-page) .gchat__messages,
html.board-chat-docked:not(.board-chat-page) .gchat__msg { max-width: 100% !important; box-sizing: border-box !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__messages { overflow-x: hidden !important; }
html.board-chat-docked:not(.board-chat-page) .gchat__bubble { overflow-wrap: anywhere !important; word-break: break-word !important; }

/* Transition fondue light ↔ dark, activée uniquement le temps du switch. */
html.board-theme-anim,
html.board-theme-anim body,
html.board-theme-anim .board-sidebar,
html.board-theme-anim .board-topbar,
html.board-theme-anim .board-kpi,
html.board-theme-anim .board-card,
html.board-theme-anim .board-btn,
html.board-theme-anim .board-iconbtn,
html.board-theme-anim .board-tab,
html.board-theme-anim .board-search,
html.board-theme-anim .board-ws-switch,
html.board-theme-anim .board-radio,
html.board-theme-anim .board-sidebar__item,
html.board-theme-anim .board-donut::after {
  transition:
    background-color .45s ease,
    color .45s ease,
    border-color .45s ease,
    box-shadow .45s ease !important;
}

.board-body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  color: var(--b-text);
  background: var(--b-bg);
  min-height: 100vh;
}

/* ───── Sidebar principale (rail) — labels sous icônes, toujours visibles ───── */
.board-sidebar {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: 80px;
  background: var(--b-sidebar-bg);
  border-right: 1px solid var(--b-border);
  display: flex;
  flex-direction: column;
  z-index: 30;
}

.board-sidebar__logo {
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 22px;
  color: var(--b-accent);
}

.board-sidebar__logo .vz-logo {
  width: 28px;
  height: 28px;
  object-fit: contain;
  display: block;
}

.board-sidebar__nav {
  flex: 1;
  padding: 6px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.board-sidebar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 8px 4px;
  border-radius: 8px;
  color: var(--b-text-muted);
  text-decoration: none;
  font-size: 10px;
  font-weight: 500;
  text-align: center;
  position: relative;
  white-space: nowrap;
}
.board-sidebar__item:hover {
  background: var(--b-surface-2);
  color: var(--b-text);
}
.board-sidebar__item.is-active {
  background: var(--b-sidebar-active-bg);
  color: var(--b-accent);
}
.board-sidebar__item.is-active .b-ico { color: var(--b-accent); }
.board-sidebar__item.is-soon {
  cursor: not-allowed;
  opacity: 0.45;
  pointer-events: auto;
}
.board-sidebar__item.is-soon:hover { background: transparent; color: inherit; }
.board-sidebar__item.is-soon .b-ico { color: var(--b-text-soft); }
.board-sidebar__soon {
  margin-left: auto;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  padding: 1px 5px;
  border-radius: 8px;
  background: var(--b-surface-2);
  color: var(--b-text-soft);
  text-transform: uppercase;
}
.board-sidebar.is-rail .board-sidebar__soon { display: none; }
.board-sidebar__label {
  font-size: 10px;
  letter-spacing: 0.2px;
  max-width: 64px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ───── Chat : pastille « non lu » + bulle « nouveau message » ───── */
.board-sidebar__ico-wrap {
  position: relative;
  display: inline-flex;
  line-height: 0;
}
.board-sidebar__dot {
  position: absolute;
  top: -3px;
  right: -4px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ff4d6a;
  border: 2px solid var(--b-sidebar-bg);
  box-shadow: 0 0 0 1px rgba(255,77,106,0.35);
}
.board-sidebar__dot[hidden] { display: none; }

/* Bouton ↗ « ouvrir la page Chat » superposé sur l'item Chat (survol). */
.board-sidebar__jump {
  position: absolute;
  top: 3px; right: 3px;
  width: 16px; height: 16px;
  padding: 0;
  border: 0;
  border-radius: 5px;
  background: var(--b-surface-2);
  color: var(--b-text-muted);
  font-size: 10px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.12s, background 0.12s, color 0.12s;
}
.board-sidebar__item:hover .board-sidebar__jump,
.board-sidebar__jump:focus-visible { opacity: 1; }
.board-sidebar__jump:hover { background: var(--b-accent); color: #fff; }

/* Bulle éphémère qui sort de l'icône Chat (ancrée en JS, 3 s puis disparaît) */
.board-chat-bubble {
  position: fixed;
  z-index: 60;
  max-width: 260px;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 9px 11px;
  border-radius: 12px;
  background: var(--b-surface, #fff);
  border: 2px solid var(--bubble-border, var(--b-border, #e5e7eb));
  box-shadow: 0 10px 28px rgba(15,23,42,0.18);
  color: var(--b-text, #0f172a);
  cursor: pointer;
  opacity: 0;
  transform: translateX(-8px) scale(0.96);
  transform-origin: left center;
  transition: opacity .18s ease, transform .18s ease;
}
.board-chat-bubble.is-in { opacity: 1; transform: translateX(0) scale(1); }
.board-chat-bubble.is-leaving { opacity: 0; transform: translateX(-8px) scale(0.96); }
.board-chat-bubble::before {              /* flèche pointant vers l'icône */
  content: "";
  position: absolute;
  left: -6px;
  top: 16px;
  width: 12px;
  height: 12px;
  background: inherit;
  border-left: 2px solid var(--bubble-border, var(--b-border, #e5e7eb));
  border-bottom: 2px solid var(--bubble-border, var(--b-border, #e5e7eb));
  transform: rotate(45deg);
}
.board-chat-bubble__av {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  background: var(--b-accent, #2c71d6);
}
.board-chat-bubble__body { min-width: 0; }
.board-chat-bubble__title {
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.board-chat-bubble__text {
  font-size: 11px;
  color: var(--b-text-muted, #64748b);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Pointeur laser du studio collaboratif (Mode Réalisateur). Ancré en JS sur
   l'élément visé, au-dessus de tout (y compris le Quick Look plein écran). */
.bst-laser-dot {
  position: fixed;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--laser-color, #ff3b30) 0%, var(--laser-color, #ff3b30) 32%, transparent 70%);
  box-shadow: 0 0 10px 3px var(--laser-color, #ff3b30);
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 100000;
  opacity: 0;
  transition: opacity 0.15s ease, left 0.05s linear, top 0.05s linear;
}
.bst-laser-dot.is-on { opacity: 1; }

/* ═══ Mode Client (affichage simplifié, réversible via html.studio-client-mode) ═══
   Masque tout le chrome technique. Garde : storyboard (lecture), vignettes,
   images/vidéos, bande des versions, validation, commentaires. */
#boardClientModeToggle.is-active {
  color: var(--b-accent);
  background: var(--b-sidebar-active-bg, rgba(44,113,214,0.12));
}
/* Pastille d'indication permanente (une par strate de prévisualisation). */
html.studio-member-mode body::after,
html.studio-participant-mode body::after {
  position: fixed;
  bottom: 14px; left: 50%;
  transform: translateX(-50%);
  color: #fff;
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  z-index: 95;
  pointer-events: none;
  box-shadow: 0 6px 18px rgba(0,0,0,0.22);
}
html.studio-member-mode body::after      { content: "👁 Vue Membre";      background: #0a8f5b; }
html.studio-participant-mode body::after { content: "👁 Vue Participant"; background: var(--b-accent, #2c71d6); }

/* ═══ Vue Membre : masque le chrome admin-only (garde les outils techniques) ═══ */
html.studio-member-mode .board-profile__admin-block,
html.studio-member-mode .board-scope-chip--platform { display: none !important; }
/* Outils « Bientôt » (grisés) masqués : pas de teasers pour les non-décideurs.
   S'applique à la prévisualisation admin (studio-member/client-mode) ET, en
   permanence, au VRAI rôle non-admin (board-role-reduced, posé côté serveur).
   Rail gauche + sous-menu projet. */
html.studio-member-mode .board-sidebar__item.is-soon,
html.studio-participant-mode .board-sidebar__item.is-soon,
html.board-role-reduced  .board-sidebar__item.is-soon,
html.studio-member-mode .bsub__item--soon,
html.studio-participant-mode .bsub__item--soon,
html.board-role-reduced  .bsub__item--soon { display: none !important; }
/* Vraie simulation Membre/Client pour l'ADMIN : les outils réservés admin/prod
   sont rendus côté serveur en liens ACTIFS (bsub__item--pro), pas en « Bientôt ».
   Le CSS de prévisu ne les voyait donc pas → l'admin voyait le menu complet en
   « Vue Membre ». On les masque ici pour refléter ce que voit un vrai membre
   (qui, lui, les reçoit en « Bientôt » → déjà masqués par board-role-reduced). */
/* Prévisu Membre (œil) → masque les outils cachés au Membre (--pro).
   Prévisu Participant (œil) → masque ceux cachés au Participant (--participant-hidden).
   Ces classes sont posées par $psbCls d'après la matrice Rôles & outils. */
html.studio-member-mode .bsub__item--pro,
html.studio-participant-mode .bsub__item--participant-hidden { display: none !important; }
/* Section devenue vide (tous ses items masqués) → on masque aussi son en-tête
   pour éviter un titre orphelin. Un item ne « compte » que s'il reste visible
   dans la strate simulée. */
html.studio-member-mode .bsub__section:not(:has(.bsub__item:not(.bsub__item--soon):not(.bsub__item--pro))),
html.studio-participant-mode .bsub__section:not(:has(.bsub__item:not(.bsub__item--soon):not(.bsub__item--participant-hidden))),
html.board-role-reduced  .bsub__section:not(:has(.bsub__item:not(.bsub__item--soon):not(.bsub__item--pro))) { display: none !important; }
/* Nav latérale : items techniques. */
html.studio-client-mode .board-sidebar__item[data-tip="Mes tâches"],
html.studio-client-mode .board-sidebar__item[data-tip="Bibliothèque"],
html.studio-client-mode .board-sidebar__item[data-tip="Reporting"],
html.studio-client-mode .board-sidebar__item[data-tip="Devis"],
html.studio-client-mode .board-sidebar__item[data-tip="Contacts"] { display: none !important; }
/* Sous-menu projet : sections IA / montage / livraison. */
html.studio-client-mode .bsub__section[data-section="pipeline-prod-ia"],
html.studio-client-mode .bsub__section[data-section="pipeline-edit"],
html.studio-client-mode .bsub__section[data-section="pipeline-delivery"] { display: none !important; }
/* Topbar : plus rien à masquer ici. Les boutons « AI Sidekick » et « Inbox »
   que cette règle cachait au client ont été supprimés le 2026-08-15 — ils
   n'avaient jamais été branchés (cf. pages/board/_layout.php). */
/* Storyboard : actions d'édition / structure / assets. */
html.studio-client-mode .bst__head-actions .board-btn[data-action="add-sequence"],
html.studio-client-mode .bst__head-actions .board-btn[data-action="add-asset"],
html.studio-client-mode #studioAttribAssetsBtn,
html.studio-client-mode #studioResetAssetsBtn,
html.studio-client-mode #studioResetStructureBtn,
html.studio-client-mode #studioToggleAllAssetsBtn { display: none !important; }
/* Vignette plan : bouton d'insertion (upload). */
html.studio-client-mode .bst-thumb--add { display: none !important; }
/* Quick Look : colonnes prompt + analyse IA, et boutons de génération. */
html.studio-client-mode #bstQuickLookColPrompt,
html.studio-client-mode #bstQuickLookColAi,
html.studio-client-mode #bstQuickLookGenerate,
html.studio-client-mode #bstQuickLookRegen,
html.studio-client-mode #bstQuickLookSave { display: none !important; }

/* Annotations (dessin synchronisé) — overlay sur le viewport du Quick Look. */
.bst-quicklook__viewport { position: relative; }   /* ancre l'overlay canvas (idempotent) */
.bst-annot-canvas {
  position: absolute;
  inset: 0;
  z-index: 6;
  pointer-events: none;          /* laisse passer zoom/pan tant qu'inactif */
  touch-action: none;
}
.bst-annot-canvas.is-active {
  pointer-events: auto;
  cursor: crosshair;
}
.bst-annot-toolbar {
  position: absolute;
  top: 14px; left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 4px;
  padding: 5px;
  border-radius: 999px;
  background: rgba(13, 16, 24, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 30;
}
.bst-annot-toolbar button {
  border: 0;
  width: 32px; height: 32px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  background: rgba(255, 255, 255, 0.10);
  color: #fff;
  transition: background 0.12s;
}
.bst-annot-toolbar button:hover { background: rgba(255, 255, 255, 0.22); }
.bst-annot-toolbar button.is-on { background: var(--b-accent, #2c71d6); }

/* Statut de revue 4 états — badge vignette + boutons Quick Look. */
.studio-review-badge {
  position: absolute;
  top: 4px; left: 4px;
  width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  font-size: 11px;
  color: #fff;
  z-index: 4;
  box-shadow: 0 1px 4px rgba(0,0,0,0.3);
}
.studio-review-badge.is-approved { background: #34c77b; }
.studio-review-badge.is-rejected { background: #ef4444; }
.studio-review-badge.is-rework   { background: #f59e0b; }
.studio-thumb.rev-approved { box-shadow: inset 0 0 0 2px #34c77b; }
.studio-thumb.rev-rejected { box-shadow: inset 0 0 0 2px #ef4444; }
.studio-thumb.rev-rework   { box-shadow: inset 0 0 0 2px #f59e0b; }

.bst-review-bar { display: inline-flex; gap: 6px; margin-right: 8px; }
.bst-review-btn {
  border: 1px solid var(--b-border, #e5e7eb);
  background: var(--b-surface, #fff);
  color: var(--b-text, #0f172a);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.bst-review-btn:hover { filter: brightness(0.97); }
.bst-review-btn.is-approved.is-on { background: #34c77b; color: #fff; border-color: #34c77b; }
.bst-review-btn.is-rejected.is-on { background: #ef4444; color: #fff; border-color: #ef4444; }
.bst-review-btn.is-rework.is-on   { background: #f59e0b; color: #fff; border-color: #f59e0b; }

.board-sidebar__bottom {
  border-top: 1px solid var(--b-border);
  padding: 6px;
}
.board-sidebar__expand { display: none; }

/* ───── Topbar ───── */
.board-topbar {
  position: fixed;
  top: 0; right: 0;
  left: 80px;
  height: 56px;
  background: var(--b-topbar-bg);
  border-bottom: 1px solid var(--b-border);
  display: flex;
  align-items: center;
  padding: 0 16px;
  gap: 16px;
  z-index: 20;
}

.board-topbar__left   { width: 240px; }
.board-topbar__center { flex: 1; display: flex; justify-content: center; }
.board-topbar__right  { display: flex; align-items: center; gap: 8px; }

.board-ws-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  height: 36px;
  padding: 0 12px;
  background: var(--b-surface-2);
  border: 1px solid var(--b-border);
  border-radius: 8px;
  color: var(--b-text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  overflow: hidden;
}
.board-ws-switch:hover { background: var(--b-surface); }
.board-ws-switch__dot {
  width: 8px; height: 8px;
  background: var(--b-accent);
  border-radius: 50%;
  flex-shrink: 0;
}
.board-ws-switch__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
}
.board-ws-switch__chev { color: var(--b-text-soft); margin-left: 4px; flex-shrink: 0; }

.board-search {
  width: 100%;
  max-width: 560px;
  height: 36px;
  background: var(--b-surface-2);
  border: 1px solid var(--b-border);
  border-radius: 8px;
  display: flex;
  align-items: center;
  padding: 0 12px;
  gap: 8px;
}
.board-search:focus-within {
  border-color: var(--b-accent);
  background: var(--b-surface);
}
.board-search__ico { color: var(--b-text-soft); }
.board-search input,
.board-search input[type="text"] {
  flex: 1;
  /* !important : contre les règles globales legacy `input[type="text"]{background:#111}`
     (client-project.css / workspace-films.css) qui noircissaient le champ. */
  background: transparent !important;
  border: none;
  outline: none;
  color: var(--b-text);
  font-size: 13px;
}
.board-search input::placeholder { color: var(--b-text-soft); }
.board-search__kbd {
  font-size: 11px;
  color: var(--b-text-soft);
  border: 1px solid var(--b-border);
  border-radius: 4px;
  padding: 1px 6px;
  font-family: -apple-system, monospace;
}

.board-iconbtn {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  font-size: 16px;
  color: var(--b-text-muted);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.board-iconbtn:hover {
  background: var(--b-surface-2);
  color: var(--b-text);
}

.board-profile {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px 4px 4px;
  border-radius: 8px;
  cursor: pointer;
}
.board-profile:hover { background: var(--b-surface-2); }
.board-profile__avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  /* Couleur unifiée par utilisateur (cf. --owner-hue injecté inline). */
  background: hsl(var(--owner-hue, 226), 60%, 46%);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.board-profile__name {
  font-size: 13px;
  font-weight: 500;
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.board-scope-chip {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 8px;
  border-radius: 10px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
  white-space: nowrap;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  background: color-mix(in srgb, var(--b-accent) 14%, transparent);
  color: var(--b-accent);
  border: 1px solid color-mix(in srgb, var(--b-accent) 28%, transparent);
}
.board-scope-chip--platform {
  background: color-mix(in srgb, #0e9c93 14%, transparent);
  color: #0e9c93;
  border-color: color-mix(in srgb, #0e9c93 30%, transparent);
}
[data-theme="dark"] .board-scope-chip--platform { color: #2fb3a9; border-color: color-mix(in srgb, #2fb3a9 35%, transparent); }
.board-profile__menu-role {
  font-size: 11px;
  font-weight: 600;
  color: var(--b-accent);
  margin-top: 2px;
  text-transform: uppercase;
  letter-spacing: .03em;
}
.board-profile { position: relative; outline: none; }
.board-profile__chev {
  color: var(--b-text-soft);
  transition: transform .15s ease;
}
.board-profile.is-open .board-profile__chev { transform: rotate(180deg); }

.board-profile__menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 220px;
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.18), 0 2px 6px rgba(0,0,0,0.08);
  padding: 6px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  animation: bp-menu-in .14s ease-out;
}
.board-profile__menu[hidden] { display: none; }
@keyframes bp-menu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.board-profile__menu-head {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 8px 10px 10px;
  border-bottom: 1px solid var(--b-border);
  margin-bottom: 4px;
}
.board-profile__menu-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--b-text);
  line-height: 1.3;
}
.board-profile__menu-mail {
  font-size: 11px;
  color: var(--b-text-muted);
  line-height: 1.3;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.board-profile__menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--b-text);
  text-decoration: none;
  cursor: pointer;
}
.board-profile__menu-item:hover { background: var(--b-surface-2); }
.board-profile__menu-sep {
  height: 1px;
  background: var(--b-border);
  margin: 6px -4px;
}
.board-profile__menu-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--b-text-muted);
  padding: 4px 10px 2px;
}
.board-profile__menu-item--danger { color: #dc2626; }
.board-profile__menu-item--danger:hover {
  background: rgba(220, 38, 38, 0.08);
  color: #b91c1c;
}
[data-theme="dark"] .board-profile__menu-item--danger { color: #f87171; }

/* ───── Main ───── */
.board-main {
  margin-left: 80px;
  padding-top: 56px;
  min-height: 100vh;
}

.board-page { padding: 32px var(--b-page-gutter); max-width: 1400px; }
.board-page__title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 24px;
}
.board-page__title h1 {
  margin: 0;
  font-size: 24px;
  font-weight: 700;
}
.board-page__sub { margin: 4px 0 0; color: var(--b-text-muted); }

/* ───── KPI tiles ───── */
.board-kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}
.board-kpi {
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-left: 3px solid var(--b-accent);
  border-radius: 10px;
  padding: 16px 16px 16px 18px;
  box-shadow: var(--b-shadow);
}
.board-kpi:nth-child(1) { border-left-color: #2c71d6; }
.board-kpi:nth-child(2) { border-left-color: #0e9c93; }
.board-kpi:nth-child(3) { border-left-color: #12a150; }
.board-kpi:nth-child(4) { border-left-color: #f59e0b; }
[data-theme="dark"] .board-kpi:nth-child(1) { border-left-color: #3b80e7; }
[data-theme="dark"] .board-kpi:nth-child(2) { border-left-color: #2fb3a9; }
[data-theme="dark"] .board-kpi:nth-child(3) { border-left-color: #34c77b; }
[data-theme="dark"] .board-kpi:nth-child(4) { border-left-color: #fbbf24; }
.board-kpi__label {
  font-size: 12px;
  color: var(--b-text-muted);
  margin-bottom: 8px;
}
.board-kpi__label--ok   { color: var(--b-ok); }
.board-kpi__label--warn { color: var(--b-warn); }
.board-kpi__value {
  font-size: 28px;
  font-weight: 700;
  color: var(--b-text);
}

/* ───── Cards ───── */
.board-card {
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-radius: 10px;
  padding: 20px;
  box-shadow: var(--b-shadow);
  margin-bottom: 16px;
}
.board-card h3 { margin: 0 0 12px; font-size: 14px; font-weight: 600; }
.board-card--ok {
  border-color: var(--b-ok);
  background: color-mix(in srgb, var(--b-ok) 8%, var(--b-surface));
}
.board-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-bottom: 16px;
}
.board-muted { color: var(--b-text-muted); }
.board-list { padding-left: 0; list-style: none; }
.board-list li { padding: 6px 0; color: var(--b-text-muted); }

/* ───── Donut placeholder ───── */
.board-donut {
  width: 140px;
  height: 140px;
  border-radius: 50%;
  background:
    conic-gradient(var(--b-ok) calc(var(--ok)*1%), var(--b-border) 0);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  margin: 12px auto 0;
}
.board-donut::after {
  content: "";
  position: absolute;
  inset: 12px;
  background: var(--b-surface);
  border-radius: 50%;
}
.board-donut span {
  position: relative;
  z-index: 1;
  font-size: 22px;
  font-weight: 700;
}

/* ───── Buttons ───── */
.board-btn {
  height: 36px;
  padding: 0 14px;
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--b-text);
  cursor: pointer;
}
.board-btn:hover { background: var(--b-surface-2); border-color: var(--b-border-strong); }
.board-btn--primary {
  background: var(--b-accent);
  color: #fff;
  border-color: var(--b-accent);
}
.board-btn--primary:hover { background: var(--b-accent-hover); border-color: var(--b-accent-hover); }

/* ───── Tabs ───── */
.board-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--b-border);
  margin: 16px 0;
}
.board-tab {
  height: 48px;
  padding: 0 16px;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--b-text-muted);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}
.board-tab:hover { color: var(--b-text); background: var(--b-surface-2); }
.board-tab.is-active {
  color: var(--b-accent);
  border-bottom-color: var(--b-accent);
}
.board-tab--add { font-size: 18px; padding: 0 12px; color: var(--b-text-soft); }

.board-toolbar {
  display: flex;
  gap: 8px;
  padding: 12px 0;
  flex-wrap: wrap;
}

.board-breadcrumb {
  font-size: 13px;
  color: var(--b-text-muted);
  margin-bottom: 8px;
}
.board-breadcrumb a { color: var(--b-text-muted); text-decoration: none; }
.board-breadcrumb a:hover { color: var(--b-accent); }

/* ───── Radio (settings) ───── */
.board-radio {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--b-border);
  border-radius: 8px;
  margin-bottom: 8px;
  cursor: pointer;
}
.board-radio:hover { background: var(--b-surface-2); }
.board-radio input { accent-color: var(--b-accent); }

/* ───── Sous-sidebar contextuelle (subnav) — style Monday épuré ───── */
.board-shell {
  display: flex;
  align-items: stretch;
  gap: 0;
  padding: 0;
  min-height: calc(100vh - 56px);
}
.board-shell--full {
  height: calc(100vh - 56px);
  min-height: 0;
  overflow: hidden;
}
.board-shell--full .board-shell__content {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.board-shell--full .board-page--full {
  height: 100% !important;
  flex: 1;
}

.bsub {
  flex-shrink: 0;
  width: 260px;
  background: var(--b-sidebar-bg);
  border-right: 1px solid var(--b-border);
  padding: 14px 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* Reste visible quand la page (body) scrolle : collée sous la topbar,
     hauteur viewport, scroll interne si le menu dépasse. */
  align-self: flex-start;
  position: sticky;
  top: 56px;
  height: calc(100vh - 56px);
  overflow-y: auto;
}

/* Menu ENTITÉ : plus étroit que le menu projet.
   260 px est la mesure du menu PROJET, qui doit loger « Conso IA & coûts » et
   une cinquantaine d'outils. Le menu entité n'a que cinq entrées d'un mot —
   Régie, Tâches, Planning, Équipe, Budget : la même largeur y laissait une
   colonne de vide à droite des libellés, et volait cette place au calendrier.
   Le repli garde sa largeur de rail, réglée plus bas. */
#bsubEntity:not(.is-collapsed) { width: 194px; }

/* Header en haut : titre du contexte + chevron collapse (visuel pour l'instant) */
.bsub__header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--b-border);
}
.bsub__header-title {
  flex: 1;
  font-size: 13px;
  font-weight: 700;
  color: var(--b-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bsub__header-actions {
  display: flex;
  gap: 2px;
  color: var(--b-text-soft);
}
.bsub__header-btn {
  width: 26px; height: 26px;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--b-text-soft);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.bsub__header-btn:hover {
  background: color-mix(in srgb, var(--b-accent) 12%, transparent);
  color: var(--b-accent);
  border-color: var(--b-accent);
}

/* Section collapsible */
.bsub__section { display: flex; flex-direction: column; gap: 2px; }
.bsub__section-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  cursor: pointer;
  user-select: none;
  font-size: 12px;
  font-weight: 600;
  color: var(--b-text);
  border-radius: 6px;
}
.bsub__section-head:hover { background: var(--b-surface-2); }
.bsub__section-chev {
  color: var(--b-text-soft);
  transition: transform .15s ease, background .12s ease, color .12s ease;
  padding: 4px;
  margin: -4px;
  border-radius: 4px;
  cursor: pointer;
}
.bsub__section-chev:hover {
  background: color-mix(in srgb, var(--b-accent) 12%, transparent);
  color: var(--b-accent);
}
.bsub__section.is-collapsed .bsub__section-chev { transform: rotate(-90deg); }
.bsub__section.is-collapsed .bsub__section-body { display: none; }
.bsub__section-body { display: flex; flex-direction: column; gap: 1px; padding: 2px 0 8px; }

/* Titre simple (sans chevron) */
.bsub__title {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--b-text-soft);
  padding: 10px 10px 4px;
}

/* Items : pill arrondie + barre verticale fine comme accent */
.bsub__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px 7px 14px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--b-text);
  text-decoration: none;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  width: 100%;
}
.bsub__item:hover { background: var(--b-surface-2); }
.bsub__item.is-active {
  background: var(--b-sidebar-active-bg);
  color: var(--b-accent);
  font-weight: 600;
}
.bsub__item::before {
  content: "";
  position: absolute;
  left: 6px; top: 9px; bottom: 9px;
  width: 2px;
  border-radius: 2px;
  background: transparent;
}
.bsub__item.is-active::before { background: var(--bsub-bar, var(--b-accent)); }
.bsub__item:hover::before { background: var(--bsub-bar, transparent); opacity: .4; }
.bsub__item .b-ico { color: var(--b-text-soft); flex-shrink: 0; }
.bsub__item.is-active .b-ico { color: var(--bsub-bar, var(--b-accent)); }
/* Filtre "Plans" (vue Assets) : plan actif = même traitement que .is-active ;
   plan sans asset attribué = atténué. */
.bsub__item.is-plan-active {
  background: var(--b-sidebar-active-bg);
  color: var(--b-accent);
  font-weight: 600;
}
.bsub__item.is-plan-active::before { background: var(--bsub-bar, var(--b-accent)); }
.bsub__item.is-empty { opacity: .5; }
.bsub__badge {
  margin-left: auto;
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 8px;
  background: var(--b-surface);
  color: var(--b-text-muted);
  border: 1px solid var(--b-border);
}
.bsub__sep {
  height: 1px;
  background: var(--b-border);
  margin: 8px 0;
}

/* ───── Item "Aperçu projet" — léger relief ───── */
.bsub__item--overview {
  margin: 0 0 8px;
  background: var(--b-surface-2);
  font-weight: 600;
}

/* ───── Item "Bientôt" (outils non encore implémentés) ───── */
.bsub__item--soon {
  cursor: not-allowed;
  color: var(--b-text-soft);
  opacity: 0.7;
}
.bsub__item--soon:hover { background: transparent; }
.bsub__item--soon::before { opacity: 0.3; }
.bsub__item--soon .b-ico { color: var(--b-text-soft); }
.bsub__pill {
  margin-left: auto;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  padding: 1px 5px;
  border-radius: 8px;
  background: var(--b-surface-2);
  color: var(--b-text-soft);
  border: 1px solid var(--b-border);
  text-transform: uppercase;
}

/* KPIs compactes dans la subnav (ou n'importe où ailleurs) */
.bsub-kpis {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 0;
}
.bsub-kpi {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 10px 5px 14px;
  font-size: 11px;
  color: var(--b-text-muted);
  border-radius: 4px;
}
.bsub-kpi:hover { background: var(--b-surface-2); }
.bsub-kpi::before {
  content: "";
  position: absolute;
  left: 6px; top: 7px; bottom: 7px;
  width: 3px;
  border-radius: 2px;
  background: var(--bsub-kpi-bar, var(--b-border));
}
.bsub-kpi__label {
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-weight: 500;
}
.bsub-kpi__value {
  font-size: 13px;
  font-weight: 700;
  color: var(--b-text);
  font-variant-numeric: tabular-nums;
}

.board-shell__content {
  flex: 1;
  min-width: 0;
}
/* ───── Gouttière de page : la MÊME respiration sur tous les outils ─────
   Une page posée dans une shell (menu + contenu) recevait padding:0 : son
   contenu collait au menu à gauche et au bord de la fenêtre à droite, alors
   que les pages hors shell avaient 40 px. D'un outil à l'autre, la marge
   changeait — c'est ce décalage qu'on voit quand on navigue.

   Une seule valeur tient désormais tout le board : --b-page-gutter. Les outils
   qui portent .btool la reprennent telle quelle (cf. tool.css) ; les pages en
   plein écran (canvas, storyboard) restent à zéro — leur contenu VA jusqu'au
   bord, c'est leur raison d'être. */
.board-shell__content > .board-page {
  padding: 0 !important;
}
.board-shell__content > .board-page:not(.btool):not(.board-page--full) {
  padding: 20px var(--b-page-gutter) 36px !important;
}

/* Quand la subnav est présente, la page n'a plus son padding latéral interne */
.board-page--in-shell {
  padding: 0 !important;
  max-width: none !important;
}

/* ───── Flyout Projets (déclenché depuis la sidebar) ───── */
.board-sidebar__item { background: transparent; border: none; font-family: inherit; }
button.board-sidebar__item { cursor: pointer; }

.bproj-flyout {
  position: fixed;
  top: 64px;
  left: 96px;
  max-height: calc(100vh - 80px);
  width: 320px;
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.08);
  z-index: 40;
  display: flex;
  flex-direction: column;
  padding: 12px;
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity .15s ease, transform .15s ease;
}
.bproj-flyout.is-open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
[hidden].bproj-flyout { display: none; }

.bproj-flyout__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.bproj-flyout__title {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 700;
  color: var(--b-text);
}
.bproj-flyout__new {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  padding: 4px 8px;
  border-radius: 6px;
  background: var(--b-accent);
  color: #fff;
  text-decoration: none;
}
.bproj-flyout__new:hover { background: var(--b-accent-hover); }

.bproj-flyout__search {
  position: relative;
  margin-bottom: 10px;
}
.bproj-flyout__search-ico {
  position: absolute;
  left: 8px; top: 50%;
  transform: translateY(-50%);
  color: var(--b-text-soft);
}
.bproj-flyout__search input {
  width: 100%;
  height: 30px;
  background: var(--b-surface-2);
  border: 1px solid var(--b-border);
  border-radius: 6px;
  padding: 0 8px 0 28px;
  font-size: 12px;
  color: var(--b-text);
  outline: none;
}
.bproj-flyout__search input:focus { border-color: var(--b-accent); background: var(--b-surface); }

.bproj-flyout__section { margin-bottom: 8px; min-height: 0; display: flex; flex-direction: column; }
#boardProjectsAll { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
/* Les listes internes ne scrollent plus chacune : c'est le wrapper qui scrolle. */
#boardProjectsAll .bproj-flyout__list { flex: none; overflow: visible; }
.bproj-flyout__label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--b-text-soft);
  padding: 4px 4px 6px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.bproj-flyout__count {
  font-size: 10px;
  padding: 0 5px;
  border-radius: 8px;
  background: var(--b-surface-2);
  color: var(--b-text-muted);
}
.bproj-flyout__list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}
.bproj-flyout__item {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 8px 7px 14px;
  border-radius: 6px;
  text-decoration: none;
  color: var(--b-text);
  font-size: 13px;
}
.bproj-flyout__item:hover { background: var(--b-surface-2); }
.bproj-flyout__item::before {
  content: "";
  position: absolute;
  left: 6px; top: 8px; bottom: 8px;
  width: 2px;
  border-radius: 2px;
  background: var(--bproj-bar, var(--b-border));
}
.bproj-flyout__name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}
.bproj-flyout__meta {
  font-size: 10px;
  color: var(--b-text-muted);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.bproj-flyout__empty {
  font-size: 12px;
  color: var(--b-text-soft);
  padding: 8px 10px;
  text-align: center;
}
/* Flyout groupé (Mes productions / Productions externes / Toutes les prods) */
.bproj-flyout__section + .bproj-flyout__section { margin-top: 8px; }
.bproj-flyout__role {
  flex-shrink: 0;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: 1px 6px;
  border-radius: 6px;
  background: var(--b-surface-2);
  color: var(--b-text-muted);
}
/* Section admin « Toutes les prods » : sous-groupes par production */
.bproj-flyout__prodgroup { margin: 2px 0 4px; }
.bproj-flyout__prodname {
  font-size: 11px;
  font-weight: 700;
  color: var(--b-accent);
  padding: 4px 4px 2px 10px;
}
/* Sous-groupe « série » (Apocalypse, Rome…) sous une prod ou dans une liste. */
.bproj-flyout__seriesname {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--b-text-muted);
  padding: 6px 4px 2px 14px;
}
.bproj-flyout__seriesname--none {
  opacity: .7;
}
.board-sidebar__item.is-flyout-open { background: var(--b-sidebar-active-bg); color: var(--b-accent); }
.board-sidebar__item.is-flyout-open .b-ico { color: var(--b-accent); }

/* ───── Bsub rétractable (utilisée pour la sidebar projet) ─────
   - Bsub générique (ex: menu3 sur sources) : ouverture rapide 0.35s
   - Bsub--project (menu2) : repli lent 0.8s pour effet "le rail se range
     après que le menu3 se soit ouvert". */
.bsub {
  transition: width .35s cubic-bezier(.4,0,.2,1),
              padding .35s cubic-bezier(.4,0,.2,1);
}
.bsub--project {
  transition: width .35s cubic-bezier(.4,0,.2,1),
              padding .35s cubic-bezier(.4,0,.2,1);
}
/* Les labels du menu2 doivent fondre au même rythme que sa largeur. */
.bsub--project .bsub__item > span,
.bsub--project .bsub__section-head > span,
.bsub--project .bsub__header-title {
  transition: opacity .6s ease,
              max-width .35s cubic-bezier(.4,0,.2,1),
              max-height .35s cubic-bezier(.4,0,.2,1),
              margin .35s cubic-bezier(.4,0,.2,1),
              padding .35s cubic-bezier(.4,0,.2,1);
}
.bsub.is-collapsed {
  width: 56px;
  padding: 14px 6px;
}
/* Menu3 (bsub générique, hors sidebar projet) : rail plus serré quand replié. */
.bsub:not(.bsub--project).is-collapsed {
  width: 44px;
  padding: 10px 4px;
  min-width: 0;
}
.bsub:not(.bsub--project).is-collapsed .bsub__item {
  padding: 8px 0;
  justify-content: center;
}
.bsub:not(.bsub--project).is-collapsed .bsub__item::before { left: 0; }
.bsub:not(.bsub--project).is-collapsed .bsub__header { padding: 0 0 8px; }
.bsub:not(.bsub--project).is-collapsed .bsub__section-head { padding: 6px 0; }

/* État "entrée" : un bsub qui doit s'ouvrir depuis 0 au load.
   JS retire la classe après une frame → transition .35s width vers 260px. */
.bsub.bsub--enter {
  width: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  overflow: hidden;
}

/* Si le menu3 a déjà été ouvert dans la session, on neutralise bsub--enter
   pour qu'il s'affiche tout de suite à sa largeur naturelle, sans anim
   de gauche-à-droite à chaque navigation entre items du menu3. */
html[data-menu3-opened="1"] .bsub.bsub--enter {
  width: auto !important;
  padding-left: 10px !important;
  padding-right: 10px !important;
  overflow: visible;
  transition: none !important;
}

/* Quand le menu2 est déjà replié dans la session (data-menu2-railed sur
   <html>, posé par le script inline du head), on l'affiche tout de suite
   en rail sans transition pour éviter le déploiement-repli visible à
   chaque navigation entre items du menu3. JS rétablira la transition
   après le premier paint. */
html[data-menu2-railed="1"] .bsub--project[data-rail-after-load] {
  width: 56px;
  padding: 14px 6px;
  transition: none !important;
}
html[data-menu2-railed="1"] .bsub--project[data-rail-after-load] .bsub__header-title,
html[data-menu2-railed="1"] .bsub--project[data-rail-after-load] .bsub__section-head > span,
html[data-menu2-railed="1"] .bsub--project[data-rail-after-load] .bsub__item > span {
  opacity: 0;
  max-width: 0;
  max-height: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
  transition: none !important;
}

/* bsub--fit : largeur calée sur le plus long label (au lieu de 260px fixe).
   Utilisé pour les menu3 quand les items sont courts (Workflow, Sources…). */
.bsub.bsub--fit {
  width: max-content;
  min-width: 140px;
  max-width: 260px;
}

/* Labels & blocs qui s'effacent en douceur quand on replie le bsub.
   On évite display:none pour pouvoir transitionner — opacity + max-width
   se transitionnent, contrairement à display. */
/* Valeurs explicites en mode déployé pour permettre la transition
   (entre auto/none et 0px, aucune anim n'est interpolée). */
.bsub__item > span,
.bsub__section-head > span,
.bsub__header-title {
  max-width: 240px;
  opacity: 1;
}
.bsub__item > span,
.bsub__section-head > span,
.bsub__header-title,
.bsub__pill,
.bsub__badge {
  transition: opacity .25s ease,
              max-width .35s cubic-bezier(.4,0,.2,1),
              max-height .35s cubic-bezier(.4,0,.2,1),
              margin .35s cubic-bezier(.4,0,.2,1),
              padding .35s cubic-bezier(.4,0,.2,1);
}
.bsub.is-collapsed .bsub__header { padding: 4px 0 10px; justify-content: center; }
/* PAS .bsub--project : là, .bsub__header-title EST le <button> #bsubProjectSwitch
   qui ouvre le sélecteur de projet (cf. _project_sidebar.php) — le repli du
   libellé est déjà géré par `.bsub__header-name { display:none }` plus bas. Le
   `pointer-events:none` ci-dessous, lui, désactivait le bouton ENTIER en mode
   rail : plus aucun moyen de rouvrir le sélecteur au clic une fois replié (seul
   le survol — lui-même cassé après une nav htmx, cf. isMainSwap dans board.js —
   pouvait encore l'ouvrir). Corrigé le 16/09/2026. */
.bsub:not(.bsub--project).is-collapsed .bsub__header-title {
  opacity: 0;
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  pointer-events: none;
}
.bsub.is-collapsed .bsub__header-actions { margin: 0 auto; }
.bsub.is-collapsed .bsub__header-btn:not(.bsub__lock-btn) .b-ico { transform: rotate(180deg); transition: transform .35s cubic-bezier(.4,0,.2,1); }
/* Lock button : masqué en mode rail (impossible de l'activer s'il n'y a pas la place) */
.bsub.is-collapsed .bsub__lock-btn { display: none; }
/* Lock button : tiny picto à côté de la flèche, opacité douce, accent quand verrouillé */
.bsub__lock-btn {
  position: relative;
  opacity: .55;
  transition: opacity .15s ease, color .15s ease;
}
.bsub__lock-btn:hover { opacity: 1; }
.bsub__lock-ico { display: block; }
.bsub__lock-ico--closed { display: none; }
.bsub.is-locked .bsub__lock-btn { opacity: 1; color: var(--b-accent, #2c71d6); }
.bsub.is-locked .bsub__lock-ico--open   { display: none; }
.bsub.is-locked .bsub__lock-ico--closed { display: block; }
.bsub.is-collapsed .bsub__section-head { justify-content: center; padding: 6px 4px; }
.bsub.is-collapsed .bsub__section-head > span {
  opacity: 0;
  max-width: 0;
  overflow: hidden;
  pointer-events: none;
}
.bsub.is-collapsed .bsub__section-chev { display: none; }
/* En mode rail : afficher les initiales du titre de section à la place du libellé */
.bsub.is-collapsed .bsub__section-head[data-initials]::after,
html[data-menu2-railed="1"] .bsub--project[data-rail-after-load] .bsub__section-head[data-initials]::after {
  content: attr(data-initials);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--b-text-muted);
  text-transform: uppercase;
  line-height: 1;
}
.bsub.is-collapsed .bsub__title[data-initials] {
  display: block;
  font-size: 0;
  text-align: center;
  padding: 4px 0;
  line-height: 1;
}
.bsub.is-collapsed .bsub__title[data-initials]::before {
  content: attr(data-initials);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--b-text-muted);
  text-transform: uppercase;
}
.bsub.is-collapsed .bsub__sep { margin: 4px 0; }
.bsub.is-collapsed .bsub__pill { display: none; }
.bsub.is-collapsed .bsub__item--overview { margin: 0 0 4px; }
.bsub.is-collapsed .bsub__item {
  justify-content: center;
  padding: 8px 4px 8px 8px;
  gap: 0;
}
.bsub.is-collapsed .bsub__item > span {
  opacity: 0;
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  pointer-events: none;
}
.bsub.is-collapsed .bsub__item::before { left: 2px; }
.bsub.is-collapsed .bsub__badge {
  position: absolute;
  top: 2px; right: 2px;
  margin: 0;
  font-size: 9px;
  padding: 0 4px;
  line-height: 14px;
  min-width: 14px;
  text-align: center;
}
/* Tooltip simple en mode rétracté */
.bsub.is-collapsed .bsub__item { position: relative; }
.bsub.is-collapsed .bsub__item:hover::after {
  content: attr(data-tip);
  position: absolute;
  left: calc(100% + 8px);
  top: 50%;
  transform: translateY(-50%);
  background: var(--b-text);
  color: var(--b-surface);
  font-size: 11px;
  padding: 4px 8px;
  border-radius: 4px;
  white-space: nowrap;
  z-index: 50;
  pointer-events: none;
}

/* Responsive : sous 1024px la subnav passe au-dessus en ligne horizontale */
@media (max-width: 1024px) {
  .board-shell { flex-direction: column; padding: 16px; }
  .bsub {
    width: 100%;
    position: static;
    flex-direction: row;
    overflow-x: auto;
    padding: 6px;
    align-self: stretch;
    height: auto;
    overflow-y: visible;
  }
  .bsub__item { flex-shrink: 0; padding: 8px 12px 8px 16px; }
  .bsub__sep { display: none; }
  .bsub__title { display: none; }
}

/* ───── Liste projets (overview) ───── */
.board-projects {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}
.board-project {
  display: block;
  padding: 12px 14px 12px 14px;
  background: var(--b-surface-2);
  border: 1px solid var(--b-border);
  border-left: 3px solid var(--b-accent);
  border-radius: 8px;
  text-decoration: none;
  color: var(--b-text);
}
.board-project:nth-child(6n+1) { border-left-color: #2c71d6; }
.board-project:nth-child(6n+2) { border-left-color: #0e9c93; }
.board-project:nth-child(6n+3) { border-left-color: #12a150; }
.board-project:nth-child(6n+4) { border-left-color: #f59e0b; }
.board-project:nth-child(6n+5) { border-left-color: #0e9c93; }
.board-project:nth-child(6n+6) { border-left-color: #e11d48; }
.board-project:hover {
  border-color: var(--b-accent);
  background: var(--b-surface);
}
.board-project__name {
  font-weight: 600;
  font-size: 13px;
  margin-bottom: 6px;
}
.board-project__meta {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--b-text-muted);
  margin-bottom: 8px;
}
.board-project__ok { color: var(--b-ok); }
.board-project__bar {
  height: 4px;
  background: var(--b-border);
  border-radius: 2px;
  overflow: hidden;
}
.board-project__bar > div {
  height: 100%;
  background: var(--b-ok);
}

/* ───── Page wide ───── */
.board-page--wide { max-width: none; padding-right: var(--b-page-gutter); }

/* ───── Groupes ───── */
.board-group { margin-bottom: 24px; }
.board-group__header {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  padding: 8px 12px;
  border-radius: 6px;
  background: var(--b-surface-2);
  border-left: 3px solid var(--b-accent);
  margin-bottom: 8px;
  user-select: none;
}
.board-group:nth-of-type(6n+1) .board-group__header { border-left-color: #2c71d6; }
.board-group:nth-of-type(6n+2) .board-group__header { border-left-color: #0e9c93; }
.board-group:nth-of-type(6n+3) .board-group__header { border-left-color: #12a150; }
.board-group:nth-of-type(6n+4) .board-group__header { border-left-color: #f59e0b; }
.board-group:nth-of-type(6n+5) .board-group__header { border-left-color: #0e9c93; }
.board-group:nth-of-type(6n+6) .board-group__header { border-left-color: #e11d48; }
.board-group__header:hover { background: var(--b-surface); }
.board-group__chev {
  display: inline-block;
  transition: transform .15s ease;
  color: var(--b-accent);
}
.board-group.is-collapsed .board-group__chev { transform: rotate(-90deg); }
.board-group.is-collapsed .board-grid { display: none; }
.board-group__name { font-weight: 600; font-size: 14px; color: var(--b-accent); }
.board-group__count { font-size: 12px; color: var(--b-text-muted); margin-left: 4px; }

/* ───── Table ───── */
.board-grid {
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-radius: 8px;
  overflow: hidden;
  box-shadow: var(--b-shadow);
}
.board-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.board-table thead th {
  background: var(--b-surface-2);
  color: var(--b-text-muted);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 10px 12px;
  text-align: left;
  border-bottom: 1px solid var(--b-border);
}
.board-table tbody td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--b-border);
  vertical-align: middle;
}
.board-table tbody tr:last-child td { border-bottom: none; }
.board-table tbody tr:hover { background: var(--b-surface-2); }

.bt-thumb { width: 64px; }
.bt-thumb img {
  width: 56px;
  height: 36px;
  object-fit: cover;
  border-radius: 4px;
  display: block;
}
.bt-thumb__empty {
  display: inline-flex;
  width: 56px; height: 36px;
  align-items: center;
  justify-content: center;
  background: var(--b-surface-2);
  border: 1px dashed var(--b-border);
  border-radius: 4px;
  color: var(--b-text-soft);
}

.bt-title { min-width: 260px; }
.bt-cell {
  outline: none;
  padding: 4px 6px;
  border-radius: 4px;
  border: 1px solid transparent;
  cursor: text;
}
.bt-cell:hover { border-color: var(--b-border); background: var(--b-surface); }
.bt-cell:focus { border-color: var(--b-accent); background: var(--b-surface); box-shadow: 0 0 0 3px var(--b-accent-soft); }

.bt-num, .bt-kind, .bt-version { width: 80px; color: var(--b-text-muted); }
.bt-color { width: 160px; }
.bt-validated { width: 110px; }

.bt-select {
  width: 100%;
  height: 30px;
  padding: 0 8px;
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-radius: 4px;
  font-size: 13px;
  color: var(--b-text);
}
.bt-select:focus { border-color: var(--b-accent); outline: none; }

.bt-badge {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
}
.bt-badge--ok { background: color-mix(in srgb, var(--b-ok) 15%, transparent); color: var(--b-ok); }
.bt-badge--neutral { background: var(--b-surface-2); color: var(--b-text-muted); }

/* ───── Vue Kanban ───── */
.bk-board {
  display: grid;
  grid-template-columns: repeat(4, minmax(240px, 1fr));
  gap: 12px;
  margin-top: 4px;
  align-items: start;
}
.bk-col {
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  min-height: 200px;
  box-shadow: var(--b-shadow);
  overflow: hidden;
}
.bk-col__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px 10px 14px;
  border-bottom: 1px solid var(--b-border);
  background: var(--b-surface-2);
  position: relative;
}
.bk-col__bar {
  position: absolute;
  left: 0; top: 8px; bottom: 8px;
  width: 3px;
  background: var(--bk-bar, var(--b-accent));
  border-radius: 0 2px 2px 0;
}
.bk-col__name {
  flex: 1;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--b-text);
}
.bk-col__count {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--b-surface);
  color: var(--b-text-muted);
  border: 1px solid var(--b-border);
}

.bk-col__list {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  min-height: 60px;
  transition: background .15s ease;
}
.bk-col__list.is-over {
  background: var(--b-accent-soft);
}
.bk-col__empty {
  font-size: 11px;
  color: var(--b-text-soft);
  text-align: center;
  padding: 16px 8px;
  border: 1px dashed var(--b-border);
  border-radius: 6px;
}

.bk-col__list .bk-card { border-left-color: var(--bk-bar, var(--b-accent)); }
.bk-card {
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-left: 3px solid var(--bk-bar, var(--b-accent));
  border-radius: 8px;
  padding: 8px;
  display: flex;
  gap: 10px;
  cursor: grab;
  transition: transform .12s ease, border-color .12s ease;
}
.bk-card:hover {
  border-color: var(--b-accent);
  transform: translateY(-1px);
}
.bk-card.is-dragging {
  opacity: .35;
  cursor: grabbing;
}
.bk-card__thumb {
  flex-shrink: 0;
  width: 52px;
  height: 36px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--b-surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
}
.bk-card__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bk-card__thumb--empty { color: var(--b-text-soft); border: 1px dashed var(--b-border); }
.bk-card__body { flex: 1; min-width: 0; }
.bk-card__title {
  font-size: 13px;
  font-weight: 500;
  color: var(--b-text);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 4px;
}
.bk-card__meta {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  font-size: 10px;
  color: var(--b-text-muted);
}
.bk-card__tag {
  background: var(--b-surface-2);
  padding: 1px 6px;
  border-radius: 8px;
  font-weight: 600;
}
.bk-card__ver {
  color: var(--b-text-soft);
  font-family: -apple-system, monospace;
}

@keyframes bkFlash { 0%{box-shadow:0 0 0 0 var(--b-ok);} 100%{box-shadow:0 0 0 6px transparent;} }
.bk-card.bk-flash { animation: bkFlash .7s ease; }

/* Responsive : 2 colonnes en dessous de 1100px, 1 colonne en mobile */
@media (max-width: 1100px) { .bk-board { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .bk-board { grid-template-columns: 1fr; } }

/* ───── Vue Storyboard ───── */
.bv-story { display: flex; flex-direction: column; gap: 20px; }
.bv-story__seq { background: var(--b-surface); border: 1px solid var(--b-border); border-radius: 10px; padding: 12px 14px; }
.bv-story__seq-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px; }
.bv-story__seq-name { font-weight: 700; font-size: 14px; color: var(--b-accent); }
.bv-story__seq-count { font-size: 11px; color: var(--b-text-muted); }
.bv-story__strip { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 6px; }
.bv-story__card {
  flex: 0 0 180px;
  background: var(--b-surface-2);
  border: 1px solid var(--b-border);
  border-left: 3px solid var(--bv-bar, var(--b-border));
  border-radius: 8px;
  padding: 8px;
  transition: transform .12s ease, border-color .12s ease;
  cursor: pointer;
}
.bv-story__card:hover { border-color: var(--b-accent); transform: translateY(-1px); }
.bv-story__thumb {
  position: relative;
  aspect-ratio: 16/9;
  border-radius: 4px;
  overflow: hidden;
  background: var(--b-surface);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 6px;
}
.bv-story__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bv-story__empty { color: var(--b-text-soft); }
.bv-story__num {
  position: absolute; bottom: 4px; left: 4px;
  background: rgba(0,0,0,.6); color: #fff;
  font-size: 10px; font-weight: 700;
  padding: 1px 6px; border-radius: 8px;
}
.bv-story__check {
  position: absolute; top: 4px; right: 4px;
  background: var(--b-ok); color: #fff;
  width: 18px; height: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
}
.bv-story__title {
  font-size: 12px; font-weight: 500; color: var(--b-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-bottom: 2px;
}
.bv-story__meta {
  display: flex; justify-content: space-between;
  font-size: 10px; color: var(--b-text-muted);
}
.bv-story__ver { font-family: -apple-system, monospace; color: var(--b-text-soft); }

/* ───── Vue Galerie ───── */
.bv-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
}
.bv-gallery__tile {
  position: relative;
  margin: 0;
  aspect-ratio: 4/3;
  border: 1px solid var(--b-border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--b-surface-2);
  cursor: pointer;
  transition: transform .12s ease, border-color .12s ease;
}
.bv-gallery__tile:hover { transform: translateY(-1px); border-color: var(--b-accent); }
.bv-gallery__tile::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px; background: var(--bv-bar, transparent); z-index: 2;
}
.bv-gallery__tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bv-gallery__empty {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  color: var(--b-text-soft);
}
.bv-gallery__cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 6px 8px;
  background: linear-gradient(to top, rgba(0,0,0,.7), transparent);
  color: #fff;
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 11px;
  pointer-events: none;
}
.bv-gallery__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 70%; }
.bv-gallery__seq { font-family: -apple-system, monospace; opacity: .9; }
.bv-gallery__check {
  position: absolute; top: 6px; right: 6px;
  background: var(--b-ok); color: #fff;
  width: 18px; height: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
}

/* ───── Vue Calendrier ───── */
.bv-cal {
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-radius: 10px;
  padding: 16px;
}
.bv-cal__head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.bv-cal__title { flex: 1; margin: 0; font-size: 18px; font-weight: 700; }
.bv-cal__dow {
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: 4px; margin-bottom: 4px;
}
.bv-cal__dow-cell {
  text-align: center;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.6px;
  color: var(--b-text-soft);
  text-transform: uppercase;
  padding: 4px;
}
.bv-cal__grid {
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.bv-cal__cell {
  min-height: 90px;
  padding: 6px;
  border: 1px solid var(--b-border);
  border-radius: 6px;
  background: var(--b-surface-2);
  display: flex; flex-direction: column; gap: 2px;
}
.bv-cal__cell--out { background: transparent; border-color: transparent; }
.bv-cal__cell.is-today { border-color: var(--b-accent); background: var(--b-accent-soft); }
.bv-cal__day { font-size: 12px; font-weight: 600; color: var(--b-text); }
.bv-cal__cell.is-today .bv-cal__day { color: var(--b-accent); }
.bv-cal__task {
  font-size: 10px;
  padding: 2px 4px;
  border-radius: 3px;
  background: var(--b-surface);
  border-left: 2px solid var(--c, var(--b-accent));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--b-text);
}
.bv-cal__more { font-size: 10px; color: var(--b-text-muted); padding: 0 4px; }

/* ───── Vue Gantt ───── */
.bv-gantt {
  background: var(--b-surface);
  border: 1px solid var(--b-border);
  border-radius: 10px;
  padding: 16px;
}
.bv-gantt__scale {
  display: flex;
  gap: 0;
  padding-left: 200px;
  border-bottom: 1px solid var(--b-border);
  margin-bottom: 8px;
}
.bv-gantt__tick {
  flex: 1;
  font-size: 10px;
  color: var(--b-text-soft);
  text-align: center;
  padding: 4px 2px;
  border-right: 1px dashed var(--b-border);
}
.bv-gantt__tick:last-child { border-right: none; }
.bv-gantt__row {
  display: flex;
  align-items: center;
  gap: 0;
  padding: 6px 0;
  border-bottom: 1px solid var(--b-border);
}
.bv-gantt__row:last-child { border-bottom: none; }
.bv-gantt__label {
  flex: 0 0 200px;
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 500;
  padding-right: 12px;
}
.bv-gantt__seq-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.bv-gantt__count { margin-left: auto; font-size: 10px; color: var(--b-text-muted); }
.bv-gantt__track {
  flex: 1;
  height: 22px;
  background: var(--b-surface-2);
  border-radius: 4px;
  overflow: hidden;
  position: relative;
}
.bv-gantt__bar {
  height: 100%;
  border-radius: 4px;
  position: relative;
  display: flex; align-items: center;
  opacity: .85;
}
.bv-gantt__bar-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: rgba(255,255,255,.35);
  border-right: 2px solid rgba(255,255,255,.9);
}
.bv-gantt__bar-label {
  position: relative;
  margin-left: 8px;
  font-size: 11px; font-weight: 700;
  color: #fff;
  z-index: 1;
}

/* ───── Flash feedback ───── */
@keyframes btFlashOk  { 0%{box-shadow:0 0 0 0 var(--b-ok);} 100%{box-shadow:0 0 0 4px transparent;} }
@keyframes btFlashBad { 0%{box-shadow:0 0 0 0 var(--b-bad);} 100%{box-shadow:0 0 0 4px transparent;} }
.bt-flash-ok  { animation: btFlashOk .7s ease; }
.bt-flash-bad { animation: btFlashBad .7s ease; }

/* ───── Responsive ───── */
@media (max-width: 1024px) {
  .board-kpis { grid-template-columns: repeat(2, 1fr); }
  .board-grid-2 { grid-template-columns: 1fr; }
  .board-profile__name { display: none; }
}

/* ───── FAB "Agent IA" — rendu par _layout.php, donc présent sur toutes
   les pages board. Les pages script/workflow chargent en plus leur propre
   override (sources.css / workflow.css), mais le style de base vit ici. */
.aiw-chat-fab {
  position: fixed;
  left: 100px; /* à droite de la sidebar principale (80px) */
  bottom: 20px;
  cursor: grab;
  user-select: none;
  touch-action: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 14px;
  background: var(--b-accent);
  color: #fff;
  border: none;
  border-radius: 20px;
  box-shadow: 0 4px 14px rgba(0,0,0,0.12);
  cursor: pointer;
  z-index: 50;
  transition: transform .15s ease, background .15s ease;
}
.aiw-chat-fab:hover {
  background: var(--b-accent-hover);
  transform: translateY(-1px);
}
.aiw-chat-fab.is-dragging {
  cursor: grabbing;
  opacity: 0.85;
  transform: scale(1.02);
  transition: none;
}
.aiw-chat-fab .b-ico { color: #fff; }
.aiw-chat-fab__label { font-size: 13px; font-weight: 600; }

/* Tooltip raccourci clavier au survol */
.aiw-chat-fab { position: fixed; }
.aiw-chat-fab::after {
  content: "Ctrl + Espace";
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(4px);
  background: var(--b-text, #1a1d23);
  color: var(--b-surface, #fff);
  font-size: 11px;
  font-weight: 500;
  padding: 4px 8px;
  border-radius: 4px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease, transform .12s ease;
  z-index: 51;
}
.aiw-chat-fab::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: calc(100% + 3px);
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: var(--b-text, #1a1d23);
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
  z-index: 51;
}
.aiw-chat-fab:hover::after,
.aiw-chat-fab:hover::before { opacity: 1; }
.aiw-chat-fab:hover::after { transform: translateX(-50%) translateY(0); }
.aiw-chat-fab.is-dragging::after,
.aiw-chat-fab.is-dragging::before { opacity: 0 !important; }

/* ══════════════════════════════════════════════════════════════
   Contexte : PRODUCTION › PROJET dans la barre du haut
   ──────────────────────────────────────────────────────────────
   Un seul repère, deux segments. Le segment production n'est
   cliquable que si l'utilisateur pilote plusieurs sociétés ;
   sinon il se dégrade en libellé (--static).
   ══════════════════════════════════════════════════════════════ */
.board-topbar__left { position: relative; display: flex; align-items: center; gap: 6px; min-width: 0; }
.board-topbar__sep { color: var(--b-text-soft); font-size: 13px; flex: 0 0 auto; }

.board-prod-switch {
  display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
  font: inherit; font-size: 12.5px; font-weight: 700; color: var(--b-text);
  background: transparent; border: 1px solid transparent; border-radius: 8px;
  padding: 6px 8px; cursor: pointer; max-width: 190px;
}
.board-prod-switch:hover { background: var(--b-surface-2); border-color: var(--b-border); }
.board-prod-switch:focus-visible { outline: 2px solid var(--b-accent); outline-offset: 2px; }
.board-prod-switch--static { cursor: default; color: var(--b-text-muted); }
.board-prod-switch--static:hover { background: transparent; border-color: transparent; }
.board-prod-switch__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-prod-switch__chev { flex: 0 0 auto; color: var(--b-text-soft); }

.board-prod-menu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 60;
  min-width: 220px; padding: 6px;
  background: var(--b-surface); border: 1px solid var(--b-border);
  border-radius: 10px; box-shadow: 0 12px 32px -12px rgba(0,0,0,.28);
}
.board-prod-menu[hidden] { display: none; }
.board-prod-menu__label {
  padding: 6px 10px 4px; font-size: 9.5px; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; color: var(--b-text-soft);
}
.board-prod-menu__item {
  display: block; padding: 8px 10px; border-radius: 7px;
  font-size: 12.5px; font-weight: 600; color: var(--b-text); text-decoration: none;
}
.board-prod-menu__item:hover { background: var(--b-surface-2); }
.board-prod-menu__item.is-on { background: var(--b-sidebar-active-bg, var(--b-accent-soft)); color: var(--b-accent); }
.board-prod-menu__item:focus-visible { outline: 2px solid var(--b-accent); outline-offset: -2px; }

/* ══════════════════════════════════════════════════════════════════════════
   Fil d'Ariane de la topbar : ENTITÉ › PROJET

   `.board-topbar__left` portait une largeur FIXE de 240 px (cf. plus haut),
   dimensionnée à l'époque où cette zone ne contenait QUE le sélecteur de
   projet. Depuis que le sélecteur d'entité s'y ajoute, « PERNEL MEDIA › »
   remplit la boîte à lui seul : il ne restait qu'une quarantaine de pixels au
   projet, affiché « E… ».

   La zone se dimensionne donc sur son contenu, et c'est la recherche (centre,
   flex:1) qui cède la place. Quand la fenêtre devient vraiment étroite, c'est
   l'ENTITÉ qui se tronque en premier : on sait toujours dans quelle société on
   travaille, alors que le projet ouvert, lui, a besoin d'être lu.
   ══════════════════════════════════════════════════════════════════════════ */
.board-topbar__left { width: auto; flex: 0 1 auto; max-width: 46vw; }
.board-ws-switch    { flex: 1 1 auto; min-width: 160px; }
.board-prod-switch  { flex: 0 1 auto; min-width: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   BARRES DE DÉFILEMENT — fines et teintées, partout dans le board

   Les barres natives sont larges et grises : sur un fond sombre elles tranchent
   comme un bloc blanc (constaté dans la carte « Équipe » du hub prod), et sur
   fond clair elles alourdissent chaque panneau qui défile — et il y en a
   beaucoup ici (timelines, listes de cartes, menus, sidebars).

   Deux syntaxes, aucune n'est de trop :
     - `scrollbar-width` / `scrollbar-color` : Firefox, et Chrome ≥ 121 ;
     - `::-webkit-scrollbar` : Safari, et les Chrome plus anciens.
   Les deux disent la même chose ; la seconde permet en plus le pouce arrondi.

   ⚠️ La couleur passe par les variables du thème : une valeur figée serait
   invisible dans l'un des deux thèmes. Le pouce s'appuie sur --b-border-strong,
   qui existe en clair comme en sombre (contrairement à --b-card-bg ou --b-hover,
   qui ne sont définies nulle part).
   ══════════════════════════════════════════════════════════════════════════ */
.board-platform,
.board-body,
.board-body * {
  scrollbar-width: thin;
  scrollbar-color: var(--b-border-strong) transparent;
}

.board-body ::-webkit-scrollbar,
.board-body::-webkit-scrollbar { width: 8px; height: 8px; }

.board-body ::-webkit-scrollbar-track,
.board-body::-webkit-scrollbar-track { background: transparent; }

.board-body ::-webkit-scrollbar-thumb,
.board-body::-webkit-scrollbar-thumb {
  background: var(--b-border-strong);
  border-radius: 10px;
  /* La bordure transparente amincit le pouce au repos sans réduire la zone
     cliquable : on garde 8 px de prise pour ~4 px de trait visible. */
  border: 2px solid transparent;
  background-clip: content-box;
}
.board-body ::-webkit-scrollbar-thumb:hover,
.board-body::-webkit-scrollbar-thumb:hover {
  background: var(--b-accent);
  background-clip: content-box;
}

/* Les deux barres d'un coin ne doivent pas laisser un carré gris. */
.board-body ::-webkit-scrollbar-corner,
.board-body::-webkit-scrollbar-corner { background: transparent; }

/* ── Rails horizontaux du storyboard : barre TOUJOURS visible ──────────────
   Constaté le 14/10/2026 (Martin, graphiste, Mac) : la barre du rail de plans
   d'une séquence apparaissait au chargement puis disparaissait — impossible de
   faire défiler la ligne à la souris (molette verticale seulement).

   Cause : macOS en barres « superposées » (réglage « Afficher les barres de
   défilement : automatiquement / pendant le défilement ») les fait s'effacer
   après un instant. Les barres ::-webkit-scrollbar, elles, restent toujours
   affichées — mais depuis Chrome 121, dès que `scrollbar-width` ou
   `scrollbar-color` sont posés (règle `.board-body *` ci-dessus), Chrome
   IGNORE ::-webkit-scrollbar et retombe sur la barre native superposée.

   Ici on remet donc les deux propriétés standard à `auto` pour que Chrome et
   Safari dessinent la barre ::-webkit-scrollbar : persistante, et plus épaisse
   (12 px) pour être attrapée à la souris. Limité aux navigateurs qui la
   connaissent : Firefox garde la barre fine standard. */
@supports selector(::-webkit-scrollbar) {
  .board-body .bst-seq__rows,
  .board-body .bst-scene__rows {
    scrollbar-width: auto;
    scrollbar-color: auto;
  }
  .board-body .bst-seq__rows::-webkit-scrollbar,
  .board-body .bst-scene__rows::-webkit-scrollbar { height: 12px; }
  .board-body .bst-seq__rows::-webkit-scrollbar-track,
  .board-body .bst-scene__rows::-webkit-scrollbar-track {
    background: var(--b-border);
    background-clip: content-box;
    border: 4px solid transparent;
    border-radius: 10px;
  }
}

/* ── Sélecteur de projet dans la sidebar projet ─────────────────────────────
   Le nom du projet devient le bouton qui ouvre la liste : c'est là qu'on le
   cherche quand on travaille dans un projet, plutôt que dans la barre du haut.
   Il garde l'aspect d'un titre — on n'ajoute qu'un chevron et un fond au
   survol, pour signaler qu'il est cliquable sans en faire un bouton de plus. */
.bsub__header-switch {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font: inherit;
  text-align: left;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 7px;
  padding: 3px 6px;
  margin: -3px -6px;
  cursor: pointer;
}
.bsub__header-switch:hover { background: var(--b-surface-2); border-color: var(--b-border); }
.bsub__header-switch:focus-visible { outline: 2px solid var(--b-accent); outline-offset: 1px; }
.bsub__header-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bsub__header-chev { flex: 0 0 auto; color: var(--b-text-soft); }
.bsub__header-switch[aria-expanded="true"] { background: var(--b-surface-2); border-color: var(--b-border); }
.bsub__header-switch[aria-expanded="true"] .bsub__header-chev { transform: rotate(180deg); }

/* Hors d'un projet, le sélecteur annonce la portée réelle de la page (« Tous
   les projets ») : il reste cliquable, mais ne doit pas se présenter comme un
   projet ouvert. D'où la pastille éteinte et le libellé en retrait — la couleur
   d'accent est réservée à « vous êtes DANS ce projet ». */
.board-ws-switch.is-scope-all .board-ws-switch__dot { background: var(--b-text-soft); }
.board-ws-switch.is-scope-all .board-ws-switch__name { color: var(--b-text-muted); font-weight: 500; }

/* Dans un projet, le nom n'est plus un bouton mais un segment de fil d'Ariane :
   ni cadre, ni fond, ni curseur main. La pastille colorée reste — c'est elle qui
   dit « tu es dans ce projet ». Le sélecteur, lui, est dans la sidebar projet. */
.board-ws-switch--static {
  background: transparent;
  border-color: transparent;
  cursor: default;
  padding-left: 4px;
}
.board-ws-switch--static:hover { background: transparent; }

/* ── Nom du projet en ENTIER dans la sidebar ────────────────────────────────
   Le titre était en `white-space: nowrap` + ellipse : « E3 SPARTE apoca… ».
   Sur un 14", la colonne est trop étroite pour la plupart des noms d'épisode,
   et un nom tronqué dans le seul endroit qui sert à choisir un projet est un
   contresens — c'est précisément là qu'il faut pouvoir le lire.
   Il passe donc à la ligne autant que nécessaire. Le chevron reste calé en
   haut pour ne pas flotter au milieu d'un nom sur deux lignes. */
.bsub__header { align-items: flex-start; }
.bsub__header-switch { align-items: flex-start; }
.bsub__header-title,
.bsub__header-name {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  overflow-wrap: anywhere;   /* coupe un mot interminable plutôt que de déborder */
  line-height: 1.25;
}
.bsub__header-chev { margin-top: 3px; }
/* Repliée en rail, la sidebar n'a plus la place : le nom disparaît de toute
   façon, inutile de lui réserver deux lignes de hauteur. */
.bsub.is-collapsed .bsub__header-name { display: none; }

/* ── Étapes de fabrication : des SECTIONS, plus des sous-groupes ────────────
   Le chapeau « Médias » qui les coiffait a été retiré (cf. _project_sidebar.php).
   Elles prennent donc l'aspect des titres de section — gris, capitales, petites —
   au lieu du texte sombre d'un sous-niveau, sinon le menu paraîtrait garder une
   hiérarchie qu'il n'a plus.
   Le chevron et le repli sont CONSERVÉS : c'est un titre à l'œil, un bouton au
   clic. On perdrait sinon la possibilité de fermer les étapes qu'on n'utilise
   pas — la raison d'être des sous-groupes à l'origine. */
.bsub__section-head {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--b-text-soft);
  padding: 10px 8px 4px;
  border-radius: 6px;
}
.bsub__section-head:hover { background: transparent; color: var(--b-text-muted); }
.bsub__section-chev { opacity: .55; }
/* Un peu d'air entre deux étapes : sans le chapeau commun, elles se touchaient. */
.bsub__section + .bsub__section { margin-top: 6px; }
