/* Barre de progression */
.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 6px; /* [cite_start] [cite: 235] */
  background-color: var(--cobalt);
  display: none; /* [cite_start] [cite: 236] */
  z-index: 9999;
  animation: progress-animation 1.5s infinite linear;
}

@keyframes progress-animation {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}

/* MODE CHIFFRÉ.
   Une opération qui sait où elle en est le dit : le ruban cesse de glisser et la
   largeur devient la mesure. On coupe l'animation — un ruban qui glisse ET une largeur
   qui avance donneraient deux informations contradictoires sur le même pixel. */
.progress-bar.is-determinate {
  animation: none;
  width: 0;
  transition: width 0.25s ease-out;
}

/* Étiquette de progression : six pixels de haut ne portent aucun texte, et savoir
   QUE ça avance ne dit pas COMBIEN de temps il reste. */
.jsb-progress-label {
  position: fixed;
  top: 10px;
  right: 14px;
  z-index: 10000;
  display: none;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  background: var(--cobalt);
  color: #ffffff;
  font-size: 0.78rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
  pointer-events: none;
}

/* Layout Principal */
body,
html {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  font-family: sans-serif;
}

/* LE BLOCAGE DU DÉFILEMENT APPARTIENT À L'ESPACE DE TRAVAIL, PAS À TOUT LE SITE.
   `overflow: hidden` était posé sur `body, html` sans condition, alors que cette
   feuille est chargée sur CHAQUE page : la vitrine, les CGU et les pages de compte
   héritaient d'un corps qui ne défile pas, et devaient le défaire à coups de
   `!important` (cf. home/_home_styles). Surtout, sur un écran étroit, une colonne
   qui débordait devenait inatteignable — pas de barre de défilement pour aller la
   chercher. On garde donc la règle là où elle a un sens (l'espace de travail est
   une coquille d'application : ce sont ses panneaux qui défilent, jamais la page)
   et on la retire partout ailleurs.

   `:has()` et non une classe sur `<body>` : le gabarit du workspace est inclus par
   des vues qui ne maîtrisent pas la balise `body`. Le sélecteur est déjà employé
   ailleurs dans le projet (cf. app.css, `[role="tabpanel"]:has(…)`). */
body:has(.interactive-menu) {
  overflow: hidden;
}

.interactive-menu {
  display: flex;
  width: 100%;
  /* `dvh` et non `vh` : sur mobile, la barre d'URL du navigateur mange une bande
     que `vh` ignore — la coquille dépassait donc par le bas, et sa dernière rangée
     (la zone de saisie du chat, le pied d'une liste) restait sous le pli, hors
     d'atteinte puisque la page ne défile pas. Le `vh` reste en repli pour les
     navigateurs qui ignorent `dvh`. */
  height: 100vh;
  height: 100dvh;
}

/* Colonne 1 : Navigation */
.menu-col-1 {
  width: var(--ws-col1-width); /* [cite_start] [cite: 191] */
  flex-shrink: 0;
  background-color: var(--bg-dark-secondary);
  display: flex;
  flex-direction: column;
  color: var(--bg-muted);
}

.menu-col-1 nav {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.menu-col-1-row-1 {
  height: 100px; /* [cite_start] [cite: 198] */
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Séparateur discret entre le tableau de bord et les groupes */
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  padding: 0.5rem 0.4rem;
}

.menu-col-1-row-2 {
  /* NOUVEAU : On transforme ce conteneur en colonne flex pour pouvoir y positionner des éléments. */
  display: flex;
  flex-direction: column;

  flex-grow: 1; /* On conserve cette propriété pour que la zone s'étende. [cite: 201] */
  min-height: 0; /* Autorise le défilement interne au lieu de pousser la colonne */
  overflow-y: auto; /* [cite_start] [cite: 201] */
  padding: 16px 8px;
  gap: 4px;
}

.menu-col-1-row-3 {
  /* Cet espace n'a plus besoin de hauteur fixe. Il peut être utilisé pour des éléments futurs comme un bouton de déconnexion. */
  flex-shrink: 0;
}

.nav-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 14px 10px;
  cursor: pointer;
  text-align: center;
  border-radius: var(--nav-radius-sm);

  /* --- Indicateur actif : barre gauche arrondie via ::before --- */
  border-left: none;
  transition: background-color var(--nav-transition), color var(--nav-transition);
}

/* Barre indicatrice gauche (remplace l'ancienne border-left, coins arrondis) */
.nav-item::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 50%;
  transform: translateY(-50%) scaleY(0.4);
  width: 4px;
  height: 60%;
  border-radius: 4px;
  background-color: transparent;
  opacity: 0;
  transition: opacity var(--nav-transition), transform var(--nav-transition), background-color var(--nav-transition);
}

.nav-icon {
  width: 28px;
  height: 28px;
  margin-bottom: 6px;
  color: var(--bg-muted);
  transition: color var(--nav-transition);
}

.nav-text {
  font-size: 0.82rem;
  line-height: 1.2;
  color: var(--bg-muted);
  transition: color var(--nav-transition);
}

/* --- Survol : léger fond + indicateur discret --- */
.nav-item:hover {
  background-color: rgba(255, 255, 255, 0.06);
}

.nav-item:hover::before {
  opacity: 1;
  transform: translateY(-50%) scaleY(1);
  background-color: var(--border-light);
}

.nav-item:hover .nav-icon,
.nav-item:hover .nav-text {
  color: #fafafa;
  font-weight: bold;
}

/* --- Focus clavier visible (WCAG 2.4.7) --- */
.nav-item:focus-visible {
  outline: none;
  background-color: rgba(255, 255, 255, 0.10);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.55);
}

/* --- Sélection (rubrique active du tableau de bord) --- */
.nav-item.active {
  background-color: rgba(255, 255, 255, 0.10);
}

.nav-item.active::before {
  opacity: 1;
  transform: translateY(-50%) scaleY(1);
  background-color: var(--text-white);
}

.nav-item.active .nav-icon,
.nav-item.active .nav-text {
  color: var(--text-white);
  font-weight: bold;
}

/* NOUVEAU : Style pour l'élément de menu qui doit être aligné en bas. */
.nav-item-bottom {
    margin-top: auto; /* La magie opère ici : pousse l'élément vers le bas de son conteneur flex. */
}

/* Groupe « Paramètres » rendu comme lien <a> (administrateur) : on neutralise la
   décoration de lien pour conserver l'aspect d'un .nav-item classique. */
a.nav-item-bottom,
a.nav-item-bottom:hover {
    text-decoration: none;
}

/* Groupe « Paramètres » désactivé pour les invités : visible mais grisé et non cliquable.
   On verrouille la couleur grise même au survol (override des règles .nav-item:hover). */
.nav-item-disabled,
.nav-item-disabled:hover {
    cursor: not-allowed;
    background-color: transparent;
}

.nav-item-disabled::before,
.nav-item-disabled:hover::before {
    opacity: 0;
}

.nav-item-disabled .nav-icon,
.nav-item-disabled .nav-text,
.nav-item-disabled:hover .nav-icon,
.nav-item-disabled:hover .nav-text {
    color: var(--text-muted); /* gris muted — état désactivé */
    font-weight: normal;
}

/* Lien de déconnexion : la classe .nav-item est conçue pour des <div>, on neutralise
   la décoration du lien <a> et on applique la couleur dédiée #ff7676 (rouge clair
   volontaire pour un contraste suffisant sur le fond sombre). */
.nav-item-logout,
.nav-item-logout:hover {
    text-decoration: none;
}

.nav-item-logout .nav-icon,
.nav-item-logout .nav-text {
    color: #ff7676;
}

/* Au survol, on éclaircit vers #ffc3c3 (override du gris clair hérité de .nav-item)
   et on accorde l'indicateur gauche à cette même couleur. */
.nav-item-logout:hover .nav-icon,
.nav-item-logout:hover .nav-text {
    color: #ffc3c3;
    font-weight: bold;
}

.nav-item-logout:hover::before {
    opacity: 1;
    transform: translateY(-50%) scaleY(1);
    background-color: #ffc3c3;
}

/* NOUVEAU : Style pour le groupe qui contient la rubrique active.
   Ce style est persistant et doit prévaloir sur les autres états. */
.nav-item.group-active {
    background-color: rgba(0, 71, 171, 0.18);
}

.nav-item.group-active::before {
    opacity: 1;
    transform: translateY(-50%) scaleY(1);
    background-color: var(--cobalt);
}

.nav-item.group-active .nav-icon,
.nav-item.group-active .nav-text {
    color: var(--text-white);
    font-weight: bold;
}

.nav-item.group-active:hover::before {
    background-color: var(--cobalt-hover); /* Reste bleu cobalt au survol */
}


/* Colonne 2 : Info & Rubriques */
.menu-col-2 {
  min-width: var(--ws-col2-width);
  max-width: var(--ws-col2-width);
  background-color: var(--bg-light);
  color: var(--text-dark-secondary);
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  border-right: 1px solid var(--border-light);
}

.menu-col-2-row-1 {
  flex-shrink: 0;
  padding: 0.65rem 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  border-bottom: 1px solid var(--border-light);
}

/* Logo + nom alignés sur une seule ligne pour une marque compacte */
.company-brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}

.company-brand:hover {
  opacity: 0.85;
}

/* Carte d'identité de l'entreprise courante */
.menu-col-2-company {
  flex-shrink: 0;
  margin: 0.85rem 1rem;
  padding: 1rem;
  text-align: center;
  background-color: var(--bg-white);
  border: 1px solid var(--border-light);
  border-radius: var(--nav-radius);
  box-shadow: var(--shadow-sm);
}

.company-card-logo {
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: var(--nav-radius-sm);
  border: 1px solid var(--border-light);
  margin-bottom: 0.5rem;
}

.company-card-name {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--text-dark-secondary);
  margin: 0 0 0.25rem;
}

.company-card-address {
  font-size: 0.8rem;
  color: var(--text-body);
  margin: 0 0 0.75rem;
  line-height: 1.35;
}

.company-card-details {
  margin: 0;
  text-align: left;
}

.company-card-line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.3rem 0;
  border-top: 1px solid var(--bg-light);
}

.company-card-line dt {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--cobalt);
  flex-shrink: 0;
}

.company-card-line dd {
  font-size: 0.8rem;
  color: var(--text-dark-secondary);
  margin: 0;
  text-align: right;
  word-break: break-word;
}

.company-logo {
  max-width: 32px;
  margin-bottom: 0;
}

.company-title {
  font-size: 1.1rem;
  font-weight: bold;
  color: var(--text-dark-secondary);
  margin: 0;
}

.company-description {
  color: var(--text-body);
  margin: 0.25rem 0 0;
  font-size: 0.75rem;
  line-height: 1.3;
}

.company-version {
  display: inline-block;
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-top: 0.35rem;
  text-decoration: none;
  transition: color var(--nav-transition);
}

a.company-version:hover {
  color: var(--cobalt);
  text-decoration: underline;
}

.menu-col-2-row-2 {
  flex-grow: 1; /* [cite_start] [cite: 223] */
  overflow-y: auto; /* [cite_start] [cite: 223] */
  min-height: 0; /* Indispensable : permet le scroll de l'enfant flex au lieu de pousser la colonne */
  padding: 0.5rem 0;
}

/* Style des rubriques dans la colonne 2 */
.rubriques-list {
  padding: 0 0.75rem;
}
.rubrique-item {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 44px; /* Cible cliquable confortable (WCAG 2.5.5) */
  padding: 10px 14px;
  cursor: pointer;
  border-radius: var(--nav-radius-sm);
  margin: 3px 0;
  color: var(--text-dark-secondary);
  transition: background-color var(--nav-transition), color var(--nav-transition), box-shadow var(--nav-transition);
}
.rubrique-icon {
  width: 18px; /* [cite_start] [cite: 226] */
  height: 18px; /* [cite_start] [cite: 226] */
  margin-right: 12px;
  flex-shrink: 0;
  color: var(--text-muted);
  transition: color var(--nav-transition);
}
.rubrique-item:hover {
  background-color: var(--bg-cobalt-subtle);
  color: var(--cobalt);
}
.rubrique-item:hover .rubrique-icon {
  color: var(--cobalt);
}
.rubrique-item:focus-visible {
  outline: none;
  background-color: var(--bg-cobalt-subtle);
  box-shadow: 0 0 0 2px var(--cobalt-focus-ring);
}
.rubrique-item.active {
  font-weight: 700;
  background-color: var(--bg-cobalt-subtle);
  color: var(--cobalt);
}
.rubrique-item.active .rubrique-icon {
  color: var(--cobalt);
}
/* Accent gauche cobalt sur la rubrique active (indice non colorimétrique = poids + accent) */
.rubrique-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 60%;
  border-radius: 3px;
  background-color: var(--cobalt);
}

/* ══════════════════════════════════════════════════════════════════════════
   COLONNE 2 REPLIABLE
   ══════════════════════════════════════════════════════════════════════════
   Sur un petit écran, les 350 px de la colonne 2 sont pris en permanence alors
   que leur contenu ne sert qu'au moment de naviguer. Repliée, la colonne quitte
   le flux (position: fixed) et la colonne 3 récupère la place aussitôt, sans
   rien déformer : c'est `.menu-col-3 { flex-grow: 1 }` qui s'en charge.

   La colonne repliée n'est pas dupliquée : c'est LE MÊME élément qui devient le
   panneau flottant. Les conteneurs de rubriques et de description restent donc
   les mêmes nœuds du DOM, et tout le JavaScript de navigation continue de les
   viser sans savoir que la colonne a changé de nature.

   `position: fixed` et non `absolute` : cela évite de poser `position: relative`
   sur `.interactive-menu`, qui reparenterait tous les descendants absolus des
   colonnes 3 et 4. Comme `body` ne défile jamais (`overflow: hidden`) et que
   `.interactive-menu` fait 100vh, les coordonnées `fixed` sont exactement celles
   de getBoundingClientRect() — aucune correction de défilement à écrire.

   Deux classes d'état, posées sur la RACINE du contrôleur comme
   `chat-fullscreen` : `col2-collapsed` (la colonne est repliée) et
   `col2-flyout-open` (le panneau est visible). Sur la racine, et non sur la
   colonne, pour que la poignée puisse se styler selon l'état sans `:has()`. */

.col2-collapsed .menu-col-2 {
  position: fixed;
  /* La gouttière laisse la poignée cliquable à gauche du panneau. */
  left: calc(var(--ws-col1-width) + var(--ws-handle-gutter));
  top: var(--ws-flyout-top, 8px);
  /* Le panneau épouse son contenu : c'est ce qui donne l'ombre portée « en bas
     du bloc », impossible avec une colonne de 100vh. */
  height: auto;
  max-height: calc(100dvh - 16px);
  z-index: var(--ws-flyout-z);
  border: 1px solid var(--border-light);
  border-radius: var(--nav-radius);
  /* Ombre à deux étages : le halo rapproché détache la carte, l'ombre longue et
     diffuse la fait planer au-dessus de la liste. */
  box-shadow: var(--shadow-md), 0 12px 28px rgba(0, 0, 0, 0.12);
  /* Indispensable avec le border-radius : sans lui, l'enfant qui défile déborde
     par les coins arrondis. */
  overflow: hidden;

  /* Fermé par défaut. `visibility` et NON `display: none` : le panneau reste
     mis en page, donc son offsetHeight est mesurable avant d'être révélé —
     c'est ce qui permet de l'ancrer sans saut visible. `visibility: hidden` le
     retire aussi du survol, de la tabulation et de l'arbre d'accessibilité :
     aucun `aria-hidden` ni `inert` à gérer à la main. */
  visibility: hidden;
  transition: opacity var(--nav-transition), visibility var(--nav-transition);
  opacity: 0;
}

.col2-collapsed.col2-flyout-open .menu-col-2 {
  visibility: visible;
  opacity: 1;
}

/* La marque et la carte d'identité de l'entreprise appartiennent à la COLONNE,
   pas au sous-menu : le panneau flottant ne porte que la navigation. */
.col2-collapsed .menu-col-2-row-1,
.col2-collapsed .menu-col-2-company {
  display: none;
}

.col2-collapsed .menu-col-2-row-2 {
  padding: 0.4rem 0;
  /* Une barre de défilement native de 15 px dans un panneau de 350 px mangerait
     le confort de lecture des rubriques. */
  scrollbar-width: thin;
}

/* Dans la colonne, la description est une carte posée sur le fond gris. Dans le
   panneau flottant, le panneau EST la carte : garder les deux donnerait une
   carte dans une carte. On ne conserve que le liseré cobalt, qui reste le repère
   de « ceci est une description, pas une liste ». */
.col2-collapsed .description-wrapper {
  margin: 0;
  border: none;
  border-left: 4px solid var(--cobalt);
  border-radius: 0;
  box-shadow: none;
  background-color: var(--bg-white);
  /* L'animation d'entrée se rejouerait à CHAQUE survol dans un panneau flottant
     (le contenu est réinjecté à chaque fois) : un tremblement permanent. */
  animation: none;
}

/* ── Poignées de bord ──────────────────────────────────────────────────────
   Deux poignées, un seul geste : une pastille posée sur la frontière d'une
   colonne, qui l'escamote et la rétablit en un clic.

   - `.ws-col2-handle` sur le joint du menu : replie / déplie la colonne 2.
   - `.ws-col4-handle` sur le bord gauche de la colonne 4 : bascule son plein
     écran. C'est un RACCOURCI, pas un remplacement — la même bascule reste
     accessible depuis le menu ⋮ du chat et la barre d'outils d'une fiche, et
     les trois commandes partagent le même état (workspace-manager).

   L'apparence est mutualisée ici ; seules la position et l'attribut d'état
   changent d'une poignée à l'autre. */
.ws-edge-handle {
  position: fixed;
  top: 50%;
  /* Juste au-dessus du panneau flottant : même si les deux se touchent, la
     poignée reste saisissable. */
  z-index: calc(var(--ws-flyout-z) + 1);

  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 60px;
  padding: 0;
  border: 1px solid var(--border-light);
  border-radius: 999px;
  background-color: var(--bg-white);
  color: var(--cobalt);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: background-color var(--nav-transition), border-color var(--nav-transition),
    color var(--nav-transition);
}

/* La pastille reste fine pour ne pas encombrer la frontière, mais la cible
   réelle atteint 44×82 px (WCAG 2.5.5). */
.ws-edge-handle::after {
  content: '';
  position: absolute;
  inset: -11px;
}

.ws-edge-handle:hover {
  background-color: var(--bg-cobalt-subtle);
  border-color: var(--cobalt);
}

.ws-edge-handle:focus-visible {
  outline: none;
  border-color: var(--cobalt);
  box-shadow: 0 0 0 3px var(--cobalt-focus-ring);
}

.ws-edge-handle svg {
  width: 14px;
  height: 14px;
  transition: transform var(--nav-transition);
}

/* ── Poignée de la colonne 2 ───────────────────────────────────────────────
   Toujours sur la frontière visible entre le menu et l'espace de travail : le
   joint colonne 2 / colonne 3 quand la colonne est dépliée, le joint colonne 1 /
   colonne 3 quand elle est repliée. Elle ne bouge PAS à l'ouverture du panneau
   — la gouttière lui réserve sa place — sinon elle sauterait de 350 px à chaque
   survol d'un groupe. */
.ws-col2-handle {
  left: calc(var(--ws-col1-width) + var(--ws-col2-width));
  transform: translate(-50%, -50%);
}

.col2-collapsed .ws-col2-handle {
  left: var(--ws-col1-width);
}

/* Le sens du chevron dit l'état sans recourir à la couleur seule : il pointe
   vers l'endroit où la colonne va aller. */
.ws-col2-handle[aria-expanded='false'] svg {
  transform: rotate(180deg);
}

/* ── Poignée de la colonne 4 ───────────────────────────────────────────────
   Sur le bord GAUCHE de la colonne de visualisation. Elle vit dans la colonne :
   celle-ci est `display: none` tant qu'aucun panneau n'est ouvert, ce qui suffit
   à masquer la poignée — un raccourci vers une colonne absente n'aurait aucun
   sens. Position `fixed`, donc aucune incidence sur la mise en page interne. */
.ws-col4-handle {
  right: var(--ws-col4-width);
  transform: translate(50%, -50%);
}

/* En plein écran, la colonne 4 commence exactement là où le menu s'arrête : les
   deux poignées partagent alors le même joint. On ancre celle-ci à gauche et on
   la décale verticalement, pour qu'elles restent deux cibles bien distinctes. */
.chat-fullscreen .ws-col4-handle {
  right: auto;
  left: calc(var(--ws-col1-width) + var(--ws-col2-width));
  top: calc(50% + 76px);
  transform: translate(-50%, -50%);
}

.chat-fullscreen.col2-collapsed .ws-col4-handle {
  left: var(--ws-col1-width);
}

/* Chevron vers la gauche pour agrandir (la colonne va s'étendre par la gauche),
   vers la droite pour réduire. `aria-pressed` est tenu à jour par
   `_syncFullscreenButtons`, qui synchronise TOUTES les commandes de plein écran :
   la poignée ne peut donc pas afficher un état que le menu ⋮ contredirait. */
.ws-col4-handle[aria-pressed='true'] svg {
  transform: rotate(180deg);
}

/* Colonne 3 : Espace de travail */
.menu-col-3 {
  flex-grow: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: width 0.3s ease-in-out;
}

/* --- Barre d'onglets col-3 --- */

/* LE DESSIN DE CETTE BARRE N'EST PLUS ÉCRIT ICI. Le bandeau, la rangée et l'onglet
   lui-même viennent de `.jsb-onglets-barre` / `.jsb-onglets-rangee` / `.jsb-onglet`
   (app.css), que porte aussi la barre d'onglets d'une rubrique : c'était la même barre
   dessinée deux fois, et elles avaient fini par ne plus se ressembler.

   Ne subsiste ci-dessous que ce qui est PROPRE au workspace — ce que la barre
   contextuelle n'a pas : des onglets qu'on ferme, qu'on rouvre, et une rangée qui peut
   être vide. app.css se charge AVANT ce fichier : à spécificité égale, ces règles-ci
   gardent le dernier mot. */

/* Aucun onglet ouvert : la barre ET son cadre s'effacent. Propre au workspace — la barre
   d'une rubrique garde toujours son onglet « Principal », elle n'est jamais vide. */
.workspace-tab-bar-wrapper:has(.workspace-tab-bar:empty) {
  display: none;
}

/* ONGLET RÉUTILISÉ : le halo dit que le geste a porté.
   Rouvrir la rubrique de l'onglet déjà actif ne déplace plus rien à l'écran depuis qu'un
   second onglet n'est plus créé. Sans retour perceptible, le geste passe pour un bug et
   l'utilisateur re-clique. Le halo emprunte l'anneau de focus cobalt : même couleur, même
   grammaire visuelle qu'un élément qui prend la main. */
@keyframes onglet-reutilise {
  from { box-shadow: inset 0 2px 0 0 var(--cobalt), 0 0 0 3px var(--cobalt-focus-ring); }
  to   { box-shadow: inset 0 2px 0 0 var(--cobalt), 0 0 0 3px transparent; }
}

.workspace-tab-item.is-onglet-reutilise {
  animation: onglet-reutilise 600ms ease-out 1;
}

/* Le libellé cède la place à la croix dans les 200 px de l'onglet. La barre d'une
   rubrique n'a pas de croix : son titre y dispose de toute la largeur, et « Partenaires
   Associés » s'y écrit en entier. */
.workspace-tab-title {
  max-width: 120px;
}

.workspace-tab-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  padding: 2px;
  border-radius: 50%;
  margin-left: 4px;
  flex-shrink: 0;
  cursor: pointer;
  line-height: 0;
  transition: background-color 0.15s;
}

.workspace-tab-close svg {
  width: 14px;
  height: 14px;
  color: var(--text-label);
  transition: color var(--nav-transition);
}

.workspace-tab-item:hover .workspace-tab-close svg,
.workspace-tab-item.active .workspace-tab-close svg {
  color: var(--text-muted);
}

.workspace-tab-close:hover {
  background-color: var(--danger-bg);
}

.workspace-tab-close:hover svg {
  color: var(--danger-dark);
}

.workspace-tab-close:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--cobalt-focus-ring);
}

/* --- Zone de panneaux col-3 --- */
.workspace-tab-panels {
  flex: 1;
  overflow-y: auto;
  position: relative;
}

.workspace-tab-panel {
  display: none;
  min-height: 100%;
}

.workspace-tab-panel.active {
  display: block;
  height: 100%;
}

.workspace-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--text-muted);
  font-size: 1.2rem;
}

.menu-col-1 ::-webkit-scrollbar-track {
  background: var(--bg-dark-secondary);
}
.menu-col-1 ::-webkit-scrollbar-thumb {
  background: var(--bg-dark-hover);
  border-radius: 4px;
}
/* Style pour la zone de description dans la colonne 2 */
.description-wrapper {
  padding: 1.5rem;
  margin: 1rem;
  background-color: var(--bg-white); /* Carte claire posée sur le fond de colonne */
  border: 1px solid var(--border-light);
  border-left: 4px solid var(--cobalt);
  color: var(--text-body);
  font-size: 0.95rem;
  line-height: 1.6; /* Hauteur de ligne pour une meilleure lisibilité */
  border-radius: var(--nav-radius-sm); /* Coins arrondis */
  box-shadow: var(--shadow-sm);

  /* NOUVEAU : Animation d'apparition pour un effet de chargement subtil */
  animation: fadeInDescription 0.4s ease-in-out;
}

/* NOUVEAU : Keyframes pour l'animation d'apparition de la description */
@keyframes fadeInDescription {
  from {
    opacity: 0;
    transform: translateX(-10px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* NOUVEAU : Style pour les paragraphes dans la description pour une meilleure structure */
.description-wrapper p {
    margin-bottom: 1rem; /* Espace entre les paragraphes */
}

.description-wrapper p:last-child {
    margin-bottom: 0; /* Pas de marge pour le dernier paragraphe */
}

/* NOUVEAU : Style pour le texte en gras (la partie "indispensable") pour plus d'impact */
.description-wrapper strong {
    color: var(--text-dark);
    font-weight: 700;
}

/* Colonne de visualisation  */
.menu-col-4 {
  display: none; /* Cachée par défaut [cite: 22, 31] */
  flex-direction: column;
  min-width: var(--ws-col4-width); /* Largeur doublée pour une meilleure visibilité */
  max-width: var(--ws-col4-width);
  height: 100%; /* [cite: 29] */
  background-color: var(--bg-light);
  color: var(--text-dark-secondary);
  border-left: 1px solid var(--border-light);
  font-size: 0.9em; /* Texte légèrement plus petit [cite: 30] */
}

/* Colonne de visualisation en plein écran : elle s'étend sur la zone des colonnes
   3 + 4 (les colonnes 1 et 2 restent visibles). La classe est posée sur la racine
   du workspace par workspace-manager#toggleChatFullscreen. La colonne 3 est masquée
   sans perdre son contenu (display:none), la colonne 4 remplit l'espace libéré
   (flex). État persisté et restauré au rechargement (cf. contrôleur).
   Le nom de classe dit « chat » pour des raisons d'histoire : le mode vaut pour
   TOUT ce que la colonne affiche — une fiche ouverte depuis un chat agrandi garde
   la largeur choisie, et sa barre d'outils porte le même bouton de bascule. */
.chat-fullscreen .menu-col-3 { display: none; }
.chat-fullscreen .menu-col-4 { min-width: 0; max-width: none; flex: 1 1 auto; }

/* ── Restauration de la COLONNE 4 (avant que Stimulus ne prenne la main) ─────
   La classe est posée par le script inline du gabarit, pendant l'analyse du
   document : la colonne s'ouvre donc DÈS le premier rendu, avec son squelette,
   au lieu d'apparaître après coup et de faire bouger la mise en page. Elle vaut
   dans les deux dispositions — normale et plein écran (où `chat-fullscreen`, posé
   en plus, lui donne la largeur des colonnes 3 + 4). Le contrôleur la retire quand
   le panneau est prêt. */
.workspace-restoring-visualization .menu-col-4 { display: flex; }
/* Sélecteur aussi précis que `.menu-col-4 .tab-panel-container` (défini plus bas,
   il l'emporterait sinon) : le panneau réel, encore vide, ne doit pas se montrer
   à côté du squelette. */
.workspace-restoring-visualization .menu-col-4 .tab-panel-container { display: none; }

.visualization-skeleton { display: none; }

.workspace-restoring-visualization .visualization-skeleton {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  padding: 10px 12px;
  gap: 10px;
}

.visualization-skeleton__tabs {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.visualization-skeleton__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

/* Deux colonnes, comme les accordéons une fois la fiche chargée : le squelette
   annonce la disposition qui arrive, il ne la contredit pas. */
.visualization-skeleton__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 14px;
}

/* --- Styles pour le panneau à onglets --- */
.menu-col-4 .tab-panel-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%; /* [cite: 37] */
}

.menu-col-4 .tab-header {
  display: flex;
  flex-shrink: 0;
  overflow-x: auto;
  white-space: nowrap; /* Empêche les onglets de passer à la ligne pour activer le défilement. */
  background-color: var(--bg-light);
  border-bottom: 1px solid var(--border-light);
  gap: 2px;
  padding: 6px 8px 0;
}

.menu-col-4 .tab-content-container {
  flex-grow: 1;
  position: relative;
  overflow-y: auto; /* [cite: 38] */
}

/* --- Styles pour un onglet individuel --- */
.tab-item {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  cursor: pointer;
  border: 1px solid transparent;
  border-bottom: none;
  background-color: var(--bg-muted);
  border-radius: var(--nav-radius-sm) var(--nav-radius-sm) 0 0;
  color: var(--text-muted);
  white-space: nowrap;
  transition: background-color var(--nav-transition), color var(--nav-transition), box-shadow var(--nav-transition);
}

.tab-item:hover {
  background-color: #d0d5dd;
  color: var(--text-dark-secondary);
}

.tab-item:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--cobalt-focus-ring);
}

.tab-item.active {
  background-color: var(--bg-white);
  border-color: var(--border-light);
  box-shadow: inset 0 2px 0 0 var(--cobalt);
  color: var(--cobalt);
}

.tab-item.active .tab-item-icon,
.tab-item.active .tab-item-title {
  font-weight: bold; /* [cite: 44] */
}

.tab-item-icon {
  margin-right: 8px; /* [cite: 52] */
  width: 18px;
}

/* Le libellé est BORNÉ. Un titre de conversation est libre (jusqu'à 120
   caractères) : sans plafond, un seul onglet étirerait la barre et repousserait
   les autres hors de vue. L'infobulle native de l'onglet donne le titre entier. */
.tab-item-title {
  max-width: 18ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Champ de renommage inline, aux dimensions du libellé qu'il remplace : sans
   cela l'onglet sursaute au double-clic, et la barre se réorganise sous le
   curseur au moment précis où l'on vise. */
.tab-item-edit {
  width: 18ch;
  min-width: 0;
  font: inherit;
  color: var(--text-dark-secondary);
  background: var(--bg-white);
  border: 1px solid var(--cobalt);
  border-radius: var(--nav-radius-sm);
  padding: 0 4px;
}

.tab-item-edit:focus {
  outline: none;
  box-shadow: 0 0 0 2px var(--cobalt-focus-ring);
}

.tab-item-close {
  border: none;
  background: transparent;
  padding: 3px; /* Léger espace intérieur */
  margin-left: 12px;
  cursor: pointer;
  border-radius: 50%; /* Pour un effet de survol circulaire */
  line-height: 0; /* Empêche les hauteurs de ligne indésirables */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s ease;
}

/* Cible directement l'icône SVG pour contrôler sa taille */
.tab-item-close svg {
  width: 16px;
  height: 16px;
  color: var(--danger);
  transition: color 0.2s ease;
}

.tab-item-close:hover {
  background-color: var(--danger-bg);
}

.tab-item-close:hover svg {
  color: var(--danger-dark);
}

.tab-item-close:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--cobalt-focus-ring);
}

/* Le contenu d'un onglet INACTIF (uniquement dans la colonne 4) */
.menu-col-4 .tab-content {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
  padding: 10px;
}

/* Le contenu de l'onglet ACTIF (uniquement dans la colonne 4) */
.menu-col-4 .tab-content.active {
  position: relative;
  opacity: 1;
  visibility: visible;
}

/* Panneau HTML arbitraire ouvert en col-4 via app:workspace.open-html-in-visualization
   (ex. chat de l'assistant IA) : occupe toute la hauteur, le défilement est géré
   à l'intérieur du panneau (fil de messages), pas par le conteneur d'onglets. */
.menu-col-4 .tab-content--html.active {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 0;
  overflow: hidden;
}

/* --- Styles pour l'accordéon --- */
.accordion-item {
  border: 1px solid var(--border-light);
  border-radius: var(--nav-radius-sm); /* Bordures arrondies pour l'ensemble */
  margin-bottom: 8px; /* Espace entre les éléments de l'accordéon */
  overflow: hidden; /* Assure que le contenu ne dépasse pas les coins arrondis */
  box-shadow: var(--shadow-sm); /* Ombre légère pour un effet de profondeur */
}

/* PLEIN ÉCRAN : la colonne de visualisation occupe la place des colonnes 3 + 4.
   Les accordéons y passent sur DEUX colonnes — c'est tout l'intérêt d'agrandir :
   voir davantage de données d'un coup d'œil, au lieu d'une colonne étirée sur
   toute la largeur avec du vide à droite. `columns` (et non une grille) parce
   qu'il ÉQUILIBRE les hauteurs : les attributs, très inégaux, se répartissent
   sans laisser de trous. `break-inside: avoid` garde chaque attribut d'un seul
   tenant — un panneau coupé en deux colonnes serait illisible. */
.chat-fullscreen .menu-col-4 .accordion {
  columns: 2;
  column-gap: 14px;
}

.chat-fullscreen .menu-col-4 .accordion .accordion-item {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  /* Sans cette marge nulle en tête, la première ligne de chaque colonne
     « flotte » à une hauteur différente de sa voisine. */
  margin-top: 0;
}

/* Le titre cliquable de l'accordéon */
.accordion-title {
  display: flex; /* Permet d'aligner le titre et l'icône '+' */
  justify-content: flex-start;
  align-items: center; /* Centre verticalement les éléments */
  background-color: var(--bg-muted);
  color: var(--text-dark);
  font-weight: bold;
  padding: 8px 10px;
  cursor: pointer;
  transition: background-color 0.2s ease; /* Transition douce pour le survol */
}

/* Effet au survol de la souris */
.accordion-title:hover {
  background-color: var(--border-light);
}

.accordion-title:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--cobalt-focus-ring);
}

.accordion-toggle {
  font-size: 1.2em; /* Agrandit légèrement l'icône */
  font-weight: bold;
  transition: transform 0.3s ease; /* Ajoute une animation de rotation à l'icône */
  margin-right: 8px;
}

/* Le contenu de l'accordéon (panneau qui se déplie) */
.accordion-content {
  padding: 0 15px; /* Padding horizontal, le vertical sera géré par l'animation */
  background-color: var(--bg-white);
  border-top: 1px solid var(--border-light);

  /* Propriétés pour l'animation de dépliage */
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-in-out, padding 0.2s ease-in-out;
}

/* Classe ajoutée par JavaScript pour ouvrir le panneau.
   `max-height: none` et non une valeur « assez grande » : les panneaux étant
   désormais OUVERTS DÈS L'OUVERTURE DE LA FICHE, un plafond chiffré (1000px)
   amputerait silencieusement les longues collections — un attribut tronqué sans
   barre de défilement ni indice est pire qu'un dépliage sans animation. Le
   défilement appartient à l'onglet, qui porte déjà le sien. */
.accordion-content.open {
  padding: 15px;
  max-height: none;
  overflow: visible;
}

/* S'applique à la barre de défilement de l'en-tête des onglets */
.tab-header::-webkit-scrollbar {
  height: 5px; /* Hauteur réduite de la barre */
}

/* Le fond de la barre (la piste) */
.tab-header::-webkit-scrollbar-track {
  background: var(--bg-light);
}

/* La partie mobile de la barre (le curseur) */
.tab-header::-webkit-scrollbar-thumb {
  background: var(--text-label);
  border-radius: 5px;
}

/* Le curseur au survol de la souris */
.tab-header::-webkit-scrollbar-thumb:hover {
  background: var(--text-muted);
}

/* Style pour la liste numérotée des collections dans l'accordéon */
.accordion-collection-list {
  list-style: decimal inside; /* Numérotation décimale, à l'intérieur du padding */
  padding-left: 5px; /* Léger retrait pour aligner les numéros */
  margin-top: 10px;
  margin-bottom: 5px;
}

.accordion-collection-list li {
  padding: 8px 0;
  border-bottom: 1px solid var(--border-light);
  font-size: 0.95em;
}

/* Enlève la bordure du dernier élément pour un rendu plus propre */
.accordion-collection-list li:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.accordion-collection-list li a {
  color: var(--cobalt);
  text-decoration: none;
  font-weight: 500;
  transition: color 0.2s ease;
}

.accordion-collection-list li a:hover {
  color: var(--cobalt-dark);
  text-decoration: underline;
}

.accordion-collection-list li a:focus-visible {
  outline: none;
  border-radius: 3px;
  box-shadow: 0 0 0 2px var(--cobalt-focus-ring);
}

/* Style pour la liste clé-valeur dans l'accordéon */
.accordion-key-value-list {
  list-style: none;
  padding: 0;
  margin: 5px 0;
}

.accordion-key-value-list li {
  display: flex;
  justify-content: space-between;
  padding: 6px 0;
  border-bottom: 1px solid var(--bg-muted);
  font-size: 0.95em;
}

.accordion-key-value-list li:last-child {
  border-bottom: none;
}

.accordion-key-value-list li strong {
  color: var(--text-body);
  margin-right: 15px;
}

.accordion-key-value-list li span {
  font-weight: 500;
  text-align: right;
}

/* --- Style pour le moteur de recherche de l'accordéon --- */

.accordion-search-bar {
  /* Pour que la barre reste figée en haut lors du défilement */
  position: sticky;
  top: 0;
  z-index: 10;

  /* Styles existants pour l'apparence */
  display: flex;
  align-items: center;
  padding: 8px 12px;
  background-color: var(--bg-dark-secondary);
  border-radius: 25px;
  margin-bottom: 10px;
  transition: box-shadow var(--nav-transition);
}

/* Focus clavier sur la barre de recherche (le champ n'a pas de bordure propre) */
.accordion-search-bar:focus-within {
  box-shadow: 0 0 0 3px var(--cobalt-focus-ring);
}

.accordion-search-bar .search-icon {
  width: 23px;
  height: 23px;
  color: white;
  margin-right: 8px;
  flex-shrink: 0;
  stroke-width: 10;
}

.accordion-search-input {
  flex-grow: 1;
  background: transparent;
  border: none;
  outline: none;
  color: white;
  font-size: 1em;
  min-width: 0;

  /* --- CORRECTION POUR FORCER LA SUPPRESSION DES BORDURES --- */
  border: none !important;
  outline: none !important;
  box-shadow: none !important;
  border-radius: 0; /* S'assure qu'il n'y a pas de coins arrondis par défaut */
}

/* Style du placeholder */
.accordion-search-input::placeholder {
  color: rgba(255,255,255,0.55);
  font-style: italic;
}

/* Style du texte lors de la saisie */
.accordion-search-input:not(:placeholder-shown) {
  font-style: normal;
  font-weight: bold;
}

.accordion-search-bar .icon-button {
  background: transparent;
  border: none;
  padding: 0 8px;
  cursor: pointer;
  color: white; /* Gris clair */
  flex-shrink: 0;
}

.accordion-search-bar .icon-button svg {
  width: 23px;
  height: 23px;
  stroke-width: 10;
}

/* Bascule plein écran de la colonne de visualisation. Ses deux icônes sont
   LINÉAIRES (tracés au trait) : le `stroke-width: 10` ci-dessus, taillé pour les
   icônes pleines de la barre, les transformerait en pâtés. L'icône visible suit
   `aria-pressed`, synchronisé par le contrôleur — on propose toujours l'action à
   venir : agrandir quand la colonne est réduite, réduire quand elle est étendue. */
.accordion-search-bar .vis-fullscreen svg {
  width: 19px;
  height: 19px;
  stroke-width: 2;
}
.accordion-search-bar .vis-fullscreen .vis-ic-collapse { display: none; }
.accordion-search-bar .vis-fullscreen[aria-pressed="true"] .vis-ic-expand { display: none; }
.accordion-search-bar .vis-fullscreen[aria-pressed="true"] .vis-ic-collapse { display: block; }

.accordion-search-bar .icon-button:focus-visible {
  outline: none;
  border-radius: 4px;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.65);
}

.accordion-search-bar .separator {
  width: 2px;
  height: 22px;
  background-color: white;
  margin: 0 0px;
  flex-shrink: 0;
}

/* Style pour le texte surligné dans les résultats */
.search-highlight {
  background-color: var(--cobalt);
  color: var(--text-white);
  padding: 0 2px;
  border-radius: 3px;
}

/* Message affiché si aucun résultat n'est trouvé */
.no-results-message {
  padding: 20px;
  text-align: center;
  color: var(--text-muted);
  font-style: italic;
}

/* --- NOUVEAU : Styles pour le bouton "Ajouter" de l'accordéon collection --- */
.collection-manager-accordion.is-disabled .title-right-block {
  display: none; /* Complètement caché et ne prend pas de place en mode désactivé */
}

/* --- Accessibilité : respect de la préférence « animations réduites » (WCAG 2.3.3) ---
   Neutralise les transitions/animations décoratives ajoutées à la navigation pour les
   utilisateurs sensibles au mouvement, sans changer aucun comportement fonctionnel. */
@media (prefers-reduced-motion: reduce) {
  .nav-item,
  .nav-item::before,
  .nav-icon,
  .nav-text,
  .rubrique-item,
  .rubrique-icon,
  .company-version,
  .workspace-tab-close,
  .workspace-tab-close svg,
  .tab-item,
  .tab-item-close,
  .tab-item-close svg,
  .accordion-title,
  .accordion-content,
  .accordion-toggle,
  .accordion-search-bar,
  .menu-col-3,
  .ws-edge-handle,
  .ws-edge-handle svg,
  .col2-collapsed .menu-col-2 {
    transition: none !important;
  }

  .description-wrapper,
  .progress-bar,
  /* Le halo de réutilisation se tait ici : l'annonce aria-live, elle, reste émise
     dans tous les cas — c'est elle qui porte l'information, pas le mouvement. */
  .workspace-tab-item.is-onglet-reutilise {
    animation: none !important;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   ADAPTATION AUX ÉCRANS ÉTROITS
   ══════════════════════════════════════════════════════════════════════════
   L'espace de travail était bâti pour une seule taille. Les colonnes 1, 2 et 4
   portaient un `min-width` en pixels : 130 + 350 + 450 = 930 px étaient pris
   AVANT que la colonne 3 — celle où l'on travaille — reçoive quoi que ce soit.
   Sous ~1100 px elle était écrasée à zéro, la colonne 4 sortait de l'écran, et
   comme la coquille ne défile pas, ce qui débordait devenait inatteignable.

   LE PRINCIPE : les seuils ne décident que d'UNE chose — combien de colonnes
   tiennent côte à côte. Tout ce qui vit À L'INTÉRIEUR d'une colonne s'adapte
   déjà à la largeur de son conteneur, et non à celle de la fenêtre (barre de
   recherche en `@container`, cellules de liste via responsive-cell). On ne
   touche donc pas à ces mécanismes : une colonne rétrécie est, pour eux, une
   situation déjà connue.

   RIEN DE NEUF N'EST INVENTÉ. Le repli de la colonne 2 en panneau flottant et
   le plein écran de la colonne 4 existaient déjà, écrits et testés ; ils
   n'étaient simplement jamais déclenchés par la largeur. On ajoute ici les
   deux dispositions manquantes et, côté JavaScript, le déclencheur.

   ⚠ LES DEUX SEUILS SONT ÉCRITS EN DOUBLE — ici et dans
   `workspace-manager_controller.js`. Une media query ne sait pas lire une
   variable CSS, et le contrôleur doit connaître le même point de bascule pour
   replier la colonne au bon moment. `AdaptationEcransEtroitsTest` vérifie que
   les deux fichiers portent les mêmes nombres.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── TABLETTE ET PETIT PORTABLE (≤ 1199.98 px) ─────────────────────────────
   Deux colonnes de travail : la navigation (repliée en panneau flottant) et
   l'espace de travail. La colonne 4 cesse d'être une colonne : elle se pose
   PAR-DESSUS. C'est ce qui rend la largeur de travail indépendante du chat —
   ouvrir Ket ne rétrécit plus la liste qu'on est en train de lire. */
@media (max-width: 1199.98px) {
  /* Le plancher tombe. Le contrôleur replie la colonne, mais si le JavaScript
     n'a pas encore pris la main (ou pas du tout), elle doit au moins pouvoir
     céder du terrain plutôt que d'évincer l'espace de travail. */
  .menu-col-2 {
    min-width: 0;
  }

  .menu-col-4 {
    position: fixed;
    top: 0;
    right: 0;
    /* `dvh` : la barre d'URL mobile ne doit pas rogner la zone de saisie du chat. */
    height: 100vh;
    height: 100dvh;
    /* La largeur nominale tant qu'elle tient, sinon une marge est laissée à
       gauche : un panneau qui couvre exactement 100 % ne se distingue plus de
       la page, et l'on perd le repère « ceci est posé par-dessus ». */
    width: min(var(--ws-col4-width), 88vw);
    min-width: 0;
    max-width: none;
    z-index: var(--ws-flyout-z);
    box-shadow: var(--shadow-md), 0 12px 28px rgba(0, 0, 0, 0.12);
  }

  .ws-col4-handle {
    right: min(var(--ws-col4-width), 88vw);
  }

  /* LE PLEIN ÉCRAN N'A PLUS D'OBJET quand la colonne flotte déjà au-dessus de
     tout. Le laisser agir masquerait la colonne 3 (`display: none`) pour ne
     rien mettre à la place : le fond deviendrait blanc derrière le panneau.
     On neutralise donc les deux règles, sans toucher à l'état ni au bouton —
     retrouver un grand écran retrouve le plein écran tel qu'il était. */
  .chat-fullscreen .menu-col-3 {
    display: flex;
  }

  .chat-fullscreen .menu-col-4 {
    flex: none;
    width: min(var(--ws-col4-width), 88vw);
  }

  .chat-fullscreen .ws-col4-handle {
    left: auto;
    right: min(var(--ws-col4-width), 88vw);
    transform: translate(50%, -50%);
  }
}

/* ── SMARTPHONE (≤ 767.98 px) : UNE SEULE COLONNE À LA FOIS ────────────────
   130 px de navigation sur un écran de 390 en prennent le tiers en permanence,
   pour un usage qui ne dure que le temps de choisir où aller. La colonne 1
   quitte donc le flux et devient un TIROIR, ouvert par la poignée de bord qui
   sert déjà à replier la colonne 2 — pas de nouveau bouton, pas de nouveau
   geste à apprendre. Le panneau des rubriques, lui, reste ce qu'il est déjà :
   il s'ouvre à droite du tiroir, contre la colonne 1 sortie.

   L'espace de travail occupe alors toute la largeur, et le chat devient une
   feuille pleine page. Une colonne visible à la fois : celle dont on se sert. */
@media (max-width: 767.98px) {
  .menu-col-1 {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    /* Au-dessus du panneau des rubriques ET du voile : le tiroir est la couche
       de navigation, il ne passe sous rien de ce qu'il commande. */
    z-index: calc(var(--ws-flyout-z) + 2);
    transform: translateX(-100%);
    transition: transform var(--nav-transition);
    box-shadow: 0 0 24px rgba(0, 0, 0, 0.35);
  }

  .ws-tiroir-ouvert .menu-col-1 {
    transform: translateX(0);
  }

  /* Le voile assombrit le travail sans le masquer : on garde le contexte, et
     un appui n'importe où referme — le geste attendu d'un tiroir. Il est posé
     en `fixed`, donc sans effet sur la mise en page des colonnes. */
  .ws-tiroir-ouvert::before {
    content: '';
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.35);
    z-index: calc(var(--ws-flyout-z) + 1);
  }

  /* Le panneau des rubriques épouse la place restante à droite du tiroir : à
     350 px fixes, il déborderait de l'écran sur un téléphone. */
  .col2-collapsed .menu-col-2 {
    left: var(--ws-col1-width);
    width: calc(100vw - var(--ws-col1-width) - 12px);
    max-width: none;
    min-width: 0;
  }

  /* La poignée devient la commande du tiroir. Fermée, elle se tient au bord de
     l'écran ; ouverte, elle suit le tiroir et se lit alors comme « refermer ».
     `translate(-25%)` la laisse mordre le bord sans jamais sortir : sur un
     téléphone, une cible à moitié hors écran n'est pas atteignable. */
  .ws-col2-handle,
  .col2-collapsed .ws-col2-handle {
    left: 0;
    transform: translate(-25%, -50%);
  }

  .ws-tiroir-ouvert .ws-col2-handle,
  .ws-tiroir-ouvert.col2-collapsed .ws-col2-handle {
    left: var(--ws-col1-width);
    transform: translate(-50%, -50%);
  }

  /* Le chat prend toute la page : à cette largeur, une feuille partielle ne
     laisserait derrière elle qu'une lisière inutilisable. */
  .menu-col-4 {
    width: 100%;
  }

  /* Sa poignée n'a plus de bord droit où se poser (le panneau touche les deux
     bords) : elle rentre à l'intérieur, contre le bord gauche de la feuille. */
  .ws-col4-handle,
  .chat-fullscreen .ws-col4-handle {
    right: auto;
    left: 6px;
    transform: translate(0, -50%);
  }
}

/* ── CIBLES TACTILES (WCAG 2.5.5) ──────────────────────────────────────────
   Les boutons de la barre d'outils mesurent ~35 px : confortables à la souris,
   trop petits au doigt. On agrandit la ZONE SAISISSABLE sans toucher au dessin
   — exactement le procédé déjà employé par les poignées de bord, dont le
   `::after` en retrait négatif porte la cible à 44 px. La charte est donc
   inchangée : rien ne grossit à l'écran, seule la surface d'appui grandit. */
@media (pointer: coarse) {
  .context-toolbar .btn {
    position: relative;
  }

  .context-toolbar .btn::after {
    content: '';
    position: absolute;
    /* 35 px de dessin + 2 × 4.5 px = 44 px de cible. */
    inset: -4.5px;
  }
}

/* ===================================================================
   VOYANT DE DÉMARRAGE (colonne 1, rangée 3)
   ===================================================================
   Il siège au-dessus de « Fermer », dans la rangée qui NE DÉFILE PAS : une dette
   qui disparaîtrait en faisant défiler les groupes ne serait plus un rappel.

   Il n'existe que pour le propriétaire, et seulement tant que la configuration
   est incomplète (cf. _onboarding_rappel.html.twig) : un voyant bloqué à 100 %
   n'est plus que du bruit.
   =================================================================== */

.ws-onboarding-jauge {
    /* Reprend .nav-item, dont il hérite déjà la classe : on ne redéfinit que ce
       qu'un <button> apporte de différent d'un <div>. */
    width: 100%;
    border: none;
    background: transparent;
    font-family: inherit;
    gap: 2px;
    padding: 10px 6px;
}

/* L'anneau de progression. `--ws-jauge-pct` est posé par le gabarit : la seule
   valeur qui vient du serveur, et elle vient une fois.

   ── POURQUOI L'AMBRE ET NON LE COBALT ──────────────────────────────────────
   L'anneau était cobalt, comme toute la marque. Sur le fond sombre de cette
   colonne (#343a40), le cobalt tombe à 1,36:1 — très en deçà des 3:1 qu'exige
   WCAG 1.4.11 pour un composant d'interface porteur de sens. L'arc était donc
   là sans se voir : du bleu foncé sur du gris foncé.
   Les autres couleurs sémantiques n'y survivent pas davantage — rouge et vert
   plafonnent tous deux à 2,54:1. L'ambre (#ffc107) monte à 7,06:1 : c'est la
   seule couleur VIVE de la charte lisible ici, et elle dit la bonne chose —
   un reste à faire, pas une erreur.
   L'information ne repose de toute façon jamais sur la couleur seule : le
   pourcentage est écrit dessous et repris dans l'`aria-label` (WCAG 1.4.1). */
.ws-jauge-anneau {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    margin-bottom: 4px;
    border-radius: 50%;
    background: conic-gradient(
        var(--warning) calc(var(--ws-jauge-pct, 0) * 1%),
        rgba(255, 255, 255, 0.18) 0
    );
    /* Un halo très discret : de quoi accrocher l'œil dans une colonne sombre
       sans ajouter une seconde teinte. */
    box-shadow: 0 0 0 3px rgba(255, 193, 7, 0.14);
    transition: box-shadow var(--nav-transition);
}

.ws-onboarding-jauge:hover .ws-jauge-anneau,
.ws-onboarding-jauge:focus-visible .ws-jauge-anneau {
    box-shadow: 0 0 0 4px rgba(255, 193, 7, 0.26);
}

/* Le disque intérieur : c'est lui qui transforme le camembert en anneau. */
.ws-jauge-anneau::after {
    content: '';
    position: absolute;
    inset: 4px;
    border-radius: 50%;
    background-color: var(--bg-dark-secondary);
}

.ws-jauge-icone {
    position: relative; /* au-dessus du disque intérieur */
    z-index: 1;
    display: inline-flex;
    color: var(--text-white);
}

/* Le pourcentage est écrit en clair : l'anneau seul ne porterait l'information
   que par la couleur et la forme (WCAG 1.4.1).

   Il reprend l'ambre de l'anneau — 7,06:1 sur ce fond, bien au-delà des 4,5:1
   exigés pour du texte — de sorte que le chiffre et l'arc se lisent comme une
   seule et même chose. Le libellé « Démarrage », lui, reste blanc : c'est un
   nom, pas une mesure. */
.ws-jauge-pct {
    font-size: 0.74rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--warning);
}

/* --- L'infobulle, déplacée sous <body> par le contrôleur ------------------
   Elle est en position: fixed (posée par le JS) pour échapper à l'`overflow`
   de la colonne et au tiroir mobile. Son z-index la met au-dessus des listes
   et sous les modales, comme le panneau flottant de la colonne 2. */
.ws-onboarding-detail {
    position: fixed;
    z-index: var(--ws-flyout-z);
    width: 330px;
    max-height: 70vh;
    overflow-y: auto;
    padding: 14px 16px;
    border-radius: var(--nav-radius);
    border-top: 3px solid var(--cobalt);
    background-color: var(--bg-dark);
    color: var(--text-white);
    box-shadow: var(--shadow-md);
}

.ws-onboarding-detail-titre {
    margin: 0 0 10px;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-white);
}

.ws-onboarding-liste {
    list-style: none;
    margin: 12px 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.ws-onboarding-liste-item {
    display: flex;
    align-items: baseline;
    gap: 7px;
    font-size: 0.8rem;
    /* #adb5bd sur #212529 : le contraste reste insuffisant pour du texte courant,
       on utilise donc le gris clair de la charte réservé aux fonds sombres. */
    color: var(--bg-muted);
}

.ws-onboarding-liste-item.est-fait {
    color: var(--text-label);
}

.ws-onboarding-puce {
    flex: 0 0 auto;
    width: 12px;
    font-weight: 700;
}

.ws-onboarding-liste-item.est-fait .ws-onboarding-puce {
    color: var(--success);
}

.ws-onboarding-liste-libelle {
    flex: 1 1 auto;
}

.ws-onboarding-liste-etat {
    flex: 0 0 auto;
    font-size: 0.72rem;
    white-space: nowrap;
    color: var(--text-label);
}

.ws-onboarding-cta {
    /* `inline-flex` et non `block` : le bouton porte une icône, qu'il faut centrer avec
       le texte. `width: 100%` conserve la pleine largeur du panneau. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    margin-top: 4px;
    padding: 9px 14px;
    border: none;
    border-radius: var(--nav-radius-sm);
    background-color: var(--cobalt);
    color: var(--text-white);
    font-size: 0.84rem;
    font-weight: 700;
    cursor: pointer;
    transition: background-color var(--nav-transition);
}

.ws-onboarding-cta:hover {
    background-color: var(--cobalt-dark);
}

.ws-onboarding-cta:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--cobalt-focus-ring);
}
