/* ============================================================
   CREA AI — Premium Styles
   ============================================================ */

/* Échelle racine pilotée par le Universal Interface Engine (src/crea-uie.js) —
   la quasi-totalité des classes Tailwind par défaut de l'app est en `rem`, donc
   relative à cette taille de police racine : ce point unique fait bouger texte,
   marges, paddings et la plupart des icônes selon la densité calculée (téléphone
   étroit → un peu plus compact, grand écran → un peu plus spacieux), sans toucher
   chaque composant un par un. `%` (pas px) pour rester relatif au réglage navigateur
   de l'utilisateur. Fallback 100% (comportement identique à avant) si le script n'a
   pas encore tourné ou est indisponible. */
html { font-size: calc(100% * var(--uie-root-scale, 1)); }

/* Animation Engine (src/crea-uie.js) : coupe transitions/animations quand le plan le
   décide — mode voiture (sécurité, aucun signal OS standard ne couvre ce cas) ou
   accessibilité. S'ajoute à la règle prefers-reduced-motion plus bas (redondant pour
   ce cas précis, mais pas en conflit) : celle-là ne réagit qu'à la préférence système,
   celle-ci réagit aussi au tier calculé par l'UIE. */
html.uie-motion-reduced *,
html.uie-motion-reduced *::before,
html.uie-motion-reduced *::after {
  animation-duration: .001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: .001ms !important;
}

/* Component Engine (src/crea-uie.js) : boutons d'icônes du header pilotés par la
   densité calculée. Liste explicite (pas de sélecteur générique `.w-8.h-8`) car ces
   classes Tailwind sont partagées avec des avatars, pastilles de statut et swatches
   de couleur qui ne doivent PAS suivre cette règle. */
#btn-close-notices, #btn-fullscreen-mode, #btn-tools-panel, #btn-close-tracking,
#btn-bgtasks-panel,
#btn-new-chat-top, #btn-ephemeral,
#btn-close-work-panel, #btn-work-panel {
  width: var(--uie-button-height, 32px);
  height: var(--uie-button-height, 32px);
}
/* CETTE LISTE EST POUR LES BOUTONS CARRÉS. DEUX N'EN SONT PAS.
   • #btn-top-menu vit en paire avec #btn-new-chat-barre, qui n'y a jamais été.
     La densité en faisait un 36 à côté d'un 28 — deux tailles pour deux
     boutons collés.
   • #btn-categories-menu n'est pas une icône : il porte l'icône ET le nom de
     l'espace ouvert (Le Fil, Finance, Projets…). Mesuré : le bouton bloqué à
     36 px de large, et le nom écrasé à ZÉRO. Le mot était rendu, personne ne
     le voyait, et le bouton ne disait plus où l'on est — c'est-à-dire tout ce
     pour quoi il avait été écrit.
   Les deux portent leur taille dans leur balisage, et c'est le balisage qui
   décide. */
/* … sauf la HAUTEUR de #btn-categories-menu, qui reste à la densité. Il partage
   sa pilule avec #btn-ephemeral : deux voisins de 32 et 36 se lisent comme un
   défaut d'alignement, et une hauteur écrite dans le balisage se figerait
   pendant que le voisin suivrait le réglage. La largeur, elle, appartient au
   contenu — icône plus nom d'espace, ce n'est pas un carré. */
#btn-categories-menu { height: var(--uie-button-height, 32px); }
#btn-close-notices svg, #btn-fullscreen-mode svg, #btn-tools-panel svg, #btn-close-tracking svg,
#btn-bgtasks-panel svg,
#btn-new-chat-top svg, #btn-ephemeral svg,
#btn-close-work-panel svg, #btn-work-panel svg {
  width: var(--uie-icon-size, 18px);
  height: var(--uie-icon-size, 18px);
}

/* --- CSS Variables — LIGHT par défaut (comme ChatGPT/Claude) --- */
:root {
  /* ===== BLANC CASSÉ =====
     SEULS LES FONDS sont légèrement cassés — les textes et les bordures restent
     NEUTRES. Première version : tout avait été teinté, y compris les gris de texte
     (#7B7365) et les bordures (#E6E1D6) ; l'écran entier virait au beige sale.
     C'est l'erreur classique : ce qui donne à un blanc cassé son élégance, c'est
     précisément que l'encre reste neutre par-dessus. Deux fonds, et rien d'autre.

     Le blanc demandé est un blanc LÉGÈREMENT GRIS, pas un crème : les versions
     précédentes tiraient sur le jaune (#FAF9F5 / #F1EFE9) et l'écran paraissait
     beige à côté d'une interface grise. Ces deux valeurs sont donc neutres —
     aucune dominante chaude, juste un blanc légèrement descendu vers le gris. */
  --bg-primary:   #FCFCFC;
  /* La barre latérale doit se DEVINER, pas trancher. À #F0F0F0 elle formait une
     bande franchement grise à côté de la page : deux zones au lieu d'une seule
     interface. L'écart est ramené à quelques points — assez pour délimiter, trop
     peu pour faire une couleur à part. */
  --bg-secondary: #F6F6F6;
  /* LE FOND DU TERMINAL — IL ÉTAIT LU ET DÉCLARÉ NULLE PART.
     `crea-terminal-atelier.js` lit `--bg-terminal` pour le thème de xterm, avec
     `#0a0e16` en repli. Le jeton n'existait dans aucun thème : le repli gagnait
     toujours. Or l'encre, elle, vient de `--t-primary` — qui suit le thème.
     MESURÉ : en thème clair, texte #0d0d0d sur fond #0a0e16 → contraste de
     1,01 : 1. Le terminal n'était pas « noir » : il était ILLISIBLE. En sombre
     il tombait juste, ce qui est exactement pourquoi ça n'a jamais sauté aux
     yeux de qui travaille en sombre.
     Un terminal suit maintenant l'application. LA VALEUR N'EST PAS CHOISIE À
     L'ŒIL : c'est le fond le plus sombre sur lequel les CINQ intentions
     (danger, succès, avertissement, info, accent-texte) tiennent encore le
     seuil de lecture en thème clair — mesuré, #F3F3F3. Un cran de plus et la
     sortie d'erreur repasse sous 4,5 : la palette n'est pas calibrée pour un
     ardoise en thème clair, et le prétendre en assombrissant aurait rendu
     illisible ce que le terminal a de plus important à dire. */
  --bg-terminal:  #F3F3F3;
  /* FOND DE LA BARRE LATÉRALE — CELUI DE L'ESPACE CHAT, PAS UN AUTRE.
     Demandé explicitement : « la barre latérale doit être de la même couleur que
     celle que contient l'espace chat ». Elle en était séparée dans les deux
     thèmes — #F6F6F6 contre #FCFCFC en clair, #1A1A1A contre #1E1E1E en sombre.
     Peu d'écart, mais assez pour lire deux zones au lieu d'une seule interface.

     La valeur n'est pas recopiée : elle RENVOIE à --bg-primary, qui change avec
     le thème. Recopier les deux teintes, c'est se garantir qu'un jour l'une
     bougera sans l'autre. Ce qui sépare la barre du fil n'est plus la couleur
     mais le liseré d'un pixel déjà posé sur #sidebar (voir plus bas). */
  --sidebar-bg:   var(--bg-primary);
  /* LA LARGEUR DE LA BARRE LATÉRALE, DÉCLARÉE UNE FOIS.
     Elle était écrite en clair à cinq endroits de src/app.js (`width:264px`) et
     nulle part ailleurs — donc invisible pour tout ce qui n'est pas dans la
     mise en page. La barre de fenêtre d'Electron, qui est POSÉE AU-DESSUS de
     celle-ci, en avait pourtant besoin : c'est le seul chiffre qui manque pour
     centrer ses onglets sur la conversation plutôt que sur l'écran.
     Elle passait donc par une MESURE, qui arrivait toujours une image trop tard
     — 234 px d'écart relevés pendant l'ouverture de la barre. Une variable,
     lue par l'aside comme par les onglets, et le retard n'a plus de place où
     exister. */
  /* 264 px, C'ÉTAIT ÉTROIT — « j'ai demandé d'agrandir en largeur la barre
     latérale, tu as oublié de le faire ». 300 px, la mesure de la référence :
     de quoi loger un titre en grand, les deux mondes à sa droite, et des noms
     de session qui ne se coupent plus au troisième mot. */
  --crea-sb-largeur: 300px;
  /* Le rail de la barre Créative — une barre posée, mais de 84 px. Elle était
     écrite en clair à son seul point d'usage, et la feuille décalait les
     onglets comme si elle en faisait 264 : 80 px d'écart avec la barre de
     questions. Un jeton pour que l'emprise se calcule sur la vraie largeur. */
  --crea-sb-largeur-rail: 84px;
  /* La marge qui DÉTACHE la barre survolée des bords de la fenêtre. C'est elle
   * qui la fait lire comme une carte posée par-dessus la page, et non comme la
   * barre ordinaire qui vient de s'ouvrir. Voir .sidebar-carte. */
  --crea-sb-marge: 12px;
  /* CE QUI L'EMPÊCHE DE DEVENIR UNE COLONNE.
   *
   * « Tu l'as fait trop long. Le but de cette barre-là, c'est qu'elle est
   *  COURTE, et que tout le reste à l'intérieur d'elle est scrollable. »
   *
   * Mesuré avant correction : 876 px de haut sur une fenêtre de 900. D'un bord
   * à l'autre — c'est-à-dire exactement la barre ordinaire, avec des coins
   * arrondis. Une carte qui occupe toute la hauteur ne se lit plus comme une
   * carte posée par-dessus la page : elle se lit comme la page.
   *
   * Ce nombre-ci est un CHOIX, pas une mesure — d'où la variable : il se
   * change ici, en un endroit, sans toucher au rendu. Le plafond réel est le
   * plus petit des deux (voir cadreDeLaCarteFlottante) : sur une petite
   * fenêtre c'est la fenêtre qui commande, sur une grande c'est ce chiffre. */
  --crea-sb-survol-hauteur: 620px;
  /* ET SON MOUVEMENT, pour la même raison. Les onglets de la barre de fenêtre
     doivent partir en même temps que la colonne et arriver en même temps
     qu'elle : sans ça ils sautent à leur place finale pendant que la
     conversation glisse encore — mesuré, 43 px d'écart au milieu du geste.
     Deux objets qui doivent bouger ensemble ne peuvent pas avoir chacun leur
     durée. */
  --crea-sb-duree: .32s;
  --crea-sb-courbe: cubic-bezier(.16,1,.3,1);
  /* LE TRAIT QUI SÉPARE LA BARRE DU FIL — plus marqué que --border, et pour une
     raison mesurable : --border contre le fond de l'application donne un
     contraste de 1,24 en thème clair. C'est assez pour souligner une carte qui
     a déjà sa couleur propre ; ce n'est pas assez quand le trait porte SEUL la
     séparation, ce qui est le cas depuis que la barre a pris la couleur du fil.
     Une variable à part, parce que --border sert partout ailleurs et n'a aucune
     raison de s'assombrir avec lui. */
  --sidebar-trait: #D5D5D5;
  /* Anneau de découpe des pastilles de compteur (notifications, onglets Mode).
     Doit toujours valoir le fond RÉEL derrière la pastille, sinon on voit un
     halo. Les groupes de boutons du header n'ayant plus de fond propre, c'est
     celui de la page — d'où une variable qui s'hérite : chaque coquille qui
     change de fond la redéfinit (cf. .studio-shell). */
  --badge-ring:   var(--bg-primary);
  --bg-tertiary:  #E7E7E7;
  --bg-glass:     rgba(252,252,252,0.9);
  --bg-glass-hov: rgba(246,246,246,0.95);
  --bg-input:     #FFFFFF;
  --bg-elevated:  #FFFFFF;
  --bg-hover:     rgba(0,0,0,0.045);
  --border:       #E4E4E4;
  --border-dim:   #EFEFEF;
  --border-hov:   #D4D4D4;
  --border-focus: rgba(16,163,127,0.4);
  --accent-dim:   rgba(16,163,127,0.55);
  --t-primary:    #0d0d0d;
  --t-secondary:  #171717;
  --t-muted:      #404040;
  --t-dim:        #737373;
  --t-faint:      #a3a3a3;
  --accent:       #10a37f;
  --accent-l:     #1db992;
  --accent-ll:    #34c4a0;
  --accent-glow:  rgba(16,163,127,0.18);
  --accent-bg:    rgba(16,163,127,0.07);
  /* ═══════════════════════════════════════════════════════════════════════
   * LES COULEURS QUI DISENT QUELQUE CHOSE — ET QUI SE LISENT
   *
   * ── CE QUI A ÉTÉ MESURÉ ────────────────────────────────────────────────
   *
   * Le contraste de chaque couleur sémantique, calculé sur les deux fonds
   * réels de CRÉA (#FCFCFC en clair, #0a0a0a en sombre). Le seuil de lecture
   * d'un texte est 4,5 pour 1.
   *
   *   --success  #22c55e   sur clair : 2,22   — À PEINE VISIBLE
   *   --warn     #f59e0b   sur clair : 2,09   — PIRE
   *   --danger   #ef4444   sur clair : 3,67   — insuffisant
   *   --accent   #10a37f   sur clair : 3,12   — insuffisant pour du texte
   *
   * Un mot « Succès » écrit en vert sur le fond clair était donc à la limite
   * de l'invisible. Ce n'est pas une affaire de goût : c'est une affaire de
   * lecture, et ça se calcule.
   *
   * ── LA CAUSE, ET ELLE EST STRUCTURELLE ─────────────────────────────────
   *
   * UNE SEULE VALEUR PAR INTENTION NE PEUT PAS TENIR DANS DEUX THÈMES. Ce qui
   * se détache sur du noir se dissout sur du blanc — c'est de la physique, pas
   * un réglage. Ces trois jetons étaient déclarés une fois, jamais redéfinis
   * en sombre : il fallait donc qu'une seule valeur serve les deux, et aucune
   * ne le peut.
   *
   * Même correction que pour l'élévation : la valeur claire ici, la valeur
   * sombre dans `html.dark`. Le nom ne bouge pas, ce qu'il vaut change.
   *
   * ── DEUX RÔLES, DEUX JETONS ────────────────────────────────────────────
   *
   * `--X` est la couleur du TEXTE et du TRAIT : elle doit se lire, donc elle
   * est foncée en clair et vive en sombre. `--X-fond` est le fond teinté :
   * il n'a pas à se lire, il a à rester discret — d'où l'opacité faible et la
   * teinte vive dans les deux thèmes.
   *
   * Les confondre était l'autre moitié du défaut : un même jeton servait de
   * texte ici et de fond là, et satisfaire l'un condamnait l'autre.
   */
  --danger:       #c81e1e;   /* 5,59 sur le fond primaire, 5,31 sur le secondaire */
  --success:      #15803d;   /* 4,89 */
  --warn:         #b45309;   /* 4,89 */
  --info:         #2563eb;   /* 5,04 */
  --accent-texte: #0a7558;   /* 5,53 — le vert CRÉA, assez foncé pour se lire */
  --danger-fond:  rgba(200,30,30,.08);
  --success-fond: rgba(21,128,61,.08);
  --warn-fond:    rgba(180,83,9,.08);
  --info-fond:    rgba(37,99,235,.08);
  --danger-trait: rgba(200,30,30,.28);
  --success-trait: rgba(21,128,61,.28);
  --warn-trait:   rgba(180,83,9,.28);
  --info-trait:   rgba(37,99,235,.28);
  /* ═══════════════════════════════════════════════════════════════════════
   * LA FORME — CINQ PALIERS, ET UN ROND
   *
   * Relevé : 524 rayons dans l'interface, 55 VALEURS DISTINCTES. Les quatre
   * jetons ci-dessous existaient déjà et servaient QUATRE fois.
   *
   * Ce que la dispersion cachait, en regardant ce que chaque valeur habille :
   *
   *   8px, 9px, 10px    la MÊME famille — petits boutons, vignettes, puces.
   *                     Trois valeurs pour un seul geste, à un pixel près.
   *   14px, 16px        les conteneurs moyens — panneau, barre, carte.
   *   50%               un CERCLE. Ce n'est pas une taille, c'est une nature :
   *                     il reste tel quel.
   *   999px, 9999px,    une PILULE. Trois écritures du même effet — le rayon
   *   99px              dépasse la demi-hauteur, donc les trois donnent
   *                     exactement le même dessin.
   *   0                 un angle vif, choisi. Il reste.
   *
   * UN RAYON SE LIT PAR RAPPORT À LA TAILLE DE L'OBJET : 8px sur un bouton de
   * 24px est un galet, le même sur un panneau de 400px est presque un angle.
   * C'est pour ça qu'une échelle de forme suit les FAMILLES d'objets, et pas
   * une progression abstraite.
   *
   * On garde le vocabulaire existant plutôt que d'en poser un second à côté :
   * quatre usages en dépendent déjà, et deux vocabulaires pour une dimension,
   * c'est la dispersion qui recommence sous un autre nom.
   */

  --radius-xs:    4px;    /* puce, pastille, marqueur */
  --radius-sm:    8px;    /* le courant : bouton, vignette, petit champ */
  --radius:       12px;   /* champ, carte compacte */
  --radius-lg:    16px;   /* panneau, carte, image dans une réponse */
  --radius-xl:    20px;   /* grande surface, feuille, boîte de dialogue */
  --radius-rond:  999px;  /* pilule — une nature, pas une taille */
  /* L'écart qui détache les panneaux de la tablette droite de leurs bords.
     C'est une DISTANCE, pas un rayon : elle se lit avec --radius (12 px) que
     ces cartes portent. 10 px suffit à faire exister la courbe sans que la
     colonne principale perde une bande visible. */
  --carte-marge: 10px;
  --rail-bg:      #F6F6F6;
  --rail-border:  #E4E4E4;
  --msg-user-bg:  #F1F1F1;

  /* ═══════════════════════════════════════════════════════════════════════
   * L'ÉLÉVATION — CINQ NIVEAUX, ET PLUS QUATRE-VINGT-ONZE OMBRES
   *
   * Relevé avant d'écrire : quatre-vingt-onze ombres distinctes dans
   * `app.js` + `styles.css`, dont TRENTE-SEPT de la même famille — « une
   * surface au-dessus des autres, en noir ».
   *
   * Trente-sept, ce n'était pas trente-sept intentions. Deux causes :
   *
   *   1. la même élévation écrite UNE FOIS POUR LE CLAIR et une fois pour le
   *      sombre — une ombre à .08 est invisible sur #1E1E1E, il en fallait
   *      une à .45. Deux valeurs pour une seule idée, et rien pour les relier.
   *   2. la dérive : .10 ici, .12 là, 28px un jour, 32px le lendemain.
   *
   * Un jeton qui se REDÉFINIT PAR THÈME supprime la première cause d'un coup.
   * L'échelle supprime la seconde.
   *
   * DEUX COUCHES PAR NIVEAU, ET C'EST CE QUI FAIT LE MODERNE : une ombre de
   * CONTACT, courte et serrée, qui pose l'objet sur la page ; et une ombre
   * AMBIANTE, large et très diluée, qui donne la profondeur. Une seule couche
   * donne toujours l'un ou l'autre — soit un objet collé, soit un objet qui
   * flotte sans être posé.
   *
   * Le décalage négatif (« -6px ») resserre l'ambiante sous l'objet au lieu de
   * la laisser déborder en halo. C'est la différence entre une ombre portée et
   * une auréole.
   * ═══════════════════════════════════════════════════════════════════════ */
  --ombre-1: 0 1px 2px rgba(0,0,0,.04), 0 1px 3px rgba(0,0,0,.06);
  --ombre-2: 0 2px 4px rgba(0,0,0,.04), 0 6px 16px -6px rgba(0,0,0,.10);
  --ombre-3: 0 4px 8px -2px rgba(0,0,0,.05), 0 12px 28px -8px rgba(0,0,0,.12);
  --ombre-4: 0 8px 16px -4px rgba(0,0,0,.06), 0 24px 48px -12px rgba(0,0,0,.16);
  --ombre-5: 0 12px 24px -6px rgba(0,0,0,.08), 0 40px 80px -20px rgba(0,0,0,.22);

  /* ═══════════════════════════════════════════════════════════════════════
   * LE MOUVEMENT — TROIS DURÉES, ET PLUS SOIXANTE-SEIZE
   *
   * Soixante-seize transitions distinctes, dont cinq paires qui sont la MÊME
   * durée écrite de deux façons (« .2s » et « 0.2s »). Deux écrans qui
   * répondent au doigt à des vitesses différentes se lisent comme deux
   * applications — c'est ce qu'on ressent avant de savoir le nommer.
   *
   * Trois durées suffisent, et le choix se fait sur la DISTANCE parcourue :
   * une couleur qui change ne bouge pas, elle doit être immédiate ; un panneau
   * qui traverse l'écran a besoin qu'on suive son trajet.
   *
   * La courbe est la même partout : départ franc, arrivée qui se pose. C'est
   * elle, plus que la durée, qui fait la différence entre « ça bouge » et
   * « c'est vivant » — une transition linéaire s'arrête net, comme un objet
   * qui n'aurait pas de masse.
   * ═══════════════════════════════════════════════════════════════════════ */
  --duree-1: 120ms;   /* couleur, opacité — ce qui ne se déplace pas */
  --duree-2: 200ms;   /* survol, apparition d'un petit élément */
  --duree-3: 320ms;   /* un panneau, un tiroir — ce qui traverse */

  /* ═══════════════════════════════════════════════════════════════════════
   * LA TYPOGRAPHIE — SEIZE MARCHES, ET PLUS TRENTE-DEUX TAILLES
   *
   * L'échelle ne vient pas d'une théorie : elle vient du RELEVÉ. La
   * distribution des trente-deux tailles montre six pics nets —
   * 13px (151 fois), 11px (112), 12px (69), 10px (35), 14px (34), 15px (27) —
   * et, tout autour, soixante-douze demi-pixels : 9.5, 10.5, 11.5, 12.5,
   * 13.5, 14.5, 15.5.
   *
   * Un demi-pixel n'est jamais une décision. C'est la trace d'un ajustement à
   * l'œil, sur un écran, un jour — et personne ne l'a jamais remis en question
   * parce qu'il ne se voit pas isolément. Il se voit en MASSE : c'est ce qui
   * fait qu'un texte de 12.5 à côté d'un texte de 13 donne une impression de
   * flou sans qu'on sache la nommer.
   *
   * L'échelle est donc le vocabulaire réel de l'application, NETTOYÉ : chaque
   * marche existe déjà et porte du poids ; ce qui disparaît, c'est le bruit
   * entre les marches. Aucun déplacement ne dépasse deux pixels.
   *
   * LES TAILLES D'AFFICHE GARDENT LEURS MARCHES (32, 36, 44, 48). Elles
   * apparaissent une fois par écran : les rapprocher ne gagne aucune cohérence
   * — personne ne voit deux titres de page côte à côte — et changerait la
   * proportion entière de la page.
   *
   * CE QUE CETTE ÉCHELLE NE COMMANDE PAS : la taille de lecture des messages.
   * Elle a son propre réglage (`--msg-font-size`, 13 à 18) que la personne
   * choisit. Poser une marche par-dessus lui retirerait son choix.
   * ═══════════════════════════════════════════════════════════════════════ */
  --texte-1:  max(0.625rem, 10px);   /* mention, étiquette minuscule */
  --texte-2:  max(0.6875rem, 11px);   /* petit — deuxième plus employé */
  --texte-3:  max(0.75rem, 12px);
  --texte-4:  max(0.8125rem, 13px);   /* le courant : une déclaration sur cinq */
  --texte-5:  max(0.875rem, 14px);
  --texte-6:  max(0.9375rem, 15px);
  --texte-7:  max(1rem, 16px);   /* accroche */
  --texte-8:  max(1.125rem, 18px);
  --texte-9:  max(1.25rem, 20px);
  --texte-10: max(1.375rem, 22px);
  --texte-11: max(1.625rem, 26px);
  --texte-12: max(1.75rem, 28px);
  --texte-13: max(2rem, 32px);   /* à partir d'ici : de l'affiche, une par écran */
  --texte-14: max(2.25rem, 36px);
  --texte-15: max(2.75rem, 44px);
  --texte-16: max(3rem, 48px);

  /* ═══════════════════════════════════════════════════════════════════════
   * L'ESPACE — LE RYTHME DE DEUX, QUI EXISTAIT DÉJÀ SANS ÊTRE DIT
   *
   * Relevé sur les propriétés d'espacement (padding, margin, gap, y compris
   * les raccourcis) : quarante-deux valeurs distinctes, mille deux cents
   * occurrences. Et une évidence dans la distribution —
   *
   *   les valeurs PAIRES portent 880 occurrences
   *   les IMPAIRES en portent 210
   *
   * L'application avait donc déjà son rythme : DEUX. Personne ne l'avait
   * écrit, et c'est pour ça qu'il fuyait — un 9 par-ci, un 11 par-là, chacun
   * posé une fois pour régler un cas particulier et jamais revu.
   *
   * L'échelle ne décide donc rien de neuf : elle NOMME ce qui était là, et
   * absorbe les deux cent dix exceptions. Chaque déplacement vaut un pixel.
   *
   * ON ARRONDIT VERS LE HAUT, et c'est un choix : dans une interface dense, un
   * texte qui frôle son bord se voit tout de suite, une boîte un pixel plus
   * large ne se voit pas. Le risque n'est pas symétrique.
   *
   * CE QUI RESTE ÉCRIT À LA MAIN, ET POURQUOI :
   *
   *   les marges NÉGATIVES  elles servent à faire chevaucher deux éléments,
   *                         à un pixel près et volontairement. Les arrondir
   *                         défait le chevauchement qu'elles existent pour
   *                         créer.
   *   au-delà de 20px       ce ne sont plus des respirations mais des
   *                         dimensions (une gouttière de page, un retrait de
   *                         colonne). Elles sont rares et chacune répond à
   *                         une contrainte précise.
   * ═══════════════════════════════════════════════════════════════════════ */
  --espace-1:  max(0.125rem, 2px);
  --espace-2:  max(0.25rem, 4px);
  --espace-3:  max(0.375rem, 6px);
  --espace-4:  max(0.5rem, 8px);    /* le plus employé : 213 fois */
  --espace-5:  max(0.625rem, 10px);
  --espace-6:  max(0.75rem, 12px);
  --espace-7:  max(0.875rem, 14px);
  --espace-8:  max(1rem, 16px);
  --espace-9:  max(1.125rem, 18px);
  --espace-10: max(1.25rem, 20px);
  --courbe: cubic-bezier(.2, .8, .2, 1);
}

html.dark {
  /* Sombre : à peine tiédi, jamais brun. Même règle qu'en clair — les fonds
     bougent d'un cheveu, l'encre reste neutre. */
  --bg-primary:   #1E1E1E;
  --bg-secondary: #232323;
  /* En sombre, le terminal descend d'un cran sous le fond secondaire — même
     geste qu'en clair, dans l'autre sens. */
  --bg-terminal:  #1A1A1A;
  --bg-tertiary:  #343434;
  --bg-glass:     rgba(30,30,30,0.9);
  --bg-glass-hov: rgba(35,35,35,0.9);
  --bg-input:     #232323;
  --bg-elevated:  #303030;
  --bg-hover:     rgba(255,255,255,0.06);
  --border:       #404040;
  --border-dim:   #313131;
  --border-hov:   #525252;
  --border-focus: rgba(16,163,127,0.5);
  --accent-dim:   rgba(16,163,127,0.55);
  --t-primary:    #ececec;
  --t-secondary:  #d1d1d1;
  --t-muted:      #a8a8a8;
  --t-dim:        #8a8a8a;
  --t-faint:      #555555;
  --accent:       #10a37f;
  --accent-l:     #1db992;
  --accent-ll:    #34c4a0;
  --accent-glow:  rgba(16,163,127,0.2);
  /* LES MÊMES NOMS, DES VALEURS QUI SE LISENT SUR CE FOND-CI.
     Mesuré sur les DEUX surfaces sombres (#1E1E1E et #232323, la pire des
     deux) : #ef4444 tombe à 4,18 sur la seconde — sous le seuil de lecture.
     On monte donc d'un cran en clarté, là où le clair descendait d'un cran. */
  --danger:       #f87171;   /* 6,03 / 5,68 */
  --success:      #22c55e;   /* 7,32 / 6,90 */
  --warn:         #f59e0b;   /* 7,76 / 7,32 */
  --info:         #60a5fa;   /* 6,56 / 6,18 */
  --accent-texte: #1db992;   /* 6,67 / 6,29 */
  --danger-fond:  rgba(248,113,113,.12);
  --success-fond: rgba(34,197,94,.12);
  --warn-fond:    rgba(245,158,11,.12);
  --info-fond:    rgba(96,165,250,.12);
  --danger-trait: rgba(248,113,113,.32);
  --success-trait: rgba(34,197,94,.32);
  --warn-trait:   rgba(245,158,11,.32);
  --info-trait:   rgba(96,165,250,.32);
  --accent-bg:    rgba(16,163,127,0.1);
  --rail-bg:      #1A1A1A;
  --sidebar-trait: #4A4A4A;
  --rail-border:  #313131;
  --msg-user-bg:  #292929;

  /* L'ÉLÉVATION EN SOMBRE — MÊME GÉOMÉTRIE, ENCRE PLUS DENSE.
   *
   * Une ombre à .06 sur un fond #1E1E1E n'existe pas : il n'y a pas assez
   * d'écart pour qu'un œil la voie. C'est POUR ÇA qu'il y avait deux séries
   * d'ombres dans ce dépôt, et pas parce que quelqu'un avait deux intentions.
   *
   * Les distances ne bougent pas — un objet ne monte pas plus haut parce qu'il
   * fait sombre. Seule l'encre se densifie. */
  --ombre-1: 0 1px 2px rgba(0,0,0,.30), 0 1px 3px rgba(0,0,0,.24);
  --ombre-2: 0 2px 4px rgba(0,0,0,.30), 0 6px 16px -6px rgba(0,0,0,.40);
  --ombre-3: 0 4px 8px -2px rgba(0,0,0,.34), 0 12px 28px -8px rgba(0,0,0,.46);
  --ombre-4: 0 8px 16px -4px rgba(0,0,0,.38), 0 24px 48px -12px rgba(0,0,0,.55);
  --ombre-5: 0 12px 24px -6px rgba(0,0,0,.44), 0 40px 80px -20px rgba(0,0,0,.65);
}

/* --- Reset / Global --- */
*, *::before, *::after { box-sizing: border-box; }
* { scrollbar-width: thin; scrollbar-color: rgba(100,116,139,0.25) transparent; }
*::-webkit-scrollbar { width: 5px; height: 5px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: rgba(100,116,139,0.25); border-radius: var(--radius); }
*::-webkit-scrollbar-thumb:hover { background: var(--crea-universe, rgba(100,116,139,0.45)); }
::selection { background: var(--accent-glow); color: var(--t-primary); }

body { background: var(--bg-primary); color: var(--t-primary); transition:  background var(--duree-2), color var(--duree-2) var(--courbe); }

/* --- Glass / Surface --- */
.glass {
  background: var(--bg-glass);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  border: 1px solid var(--border);
  /* LA COURBE MANQUAIT SUR LA PREMIÈRE PROPRIÉTÉ. `background var(--duree-2)`
     sans courbe tombe sur `ease` par défaut, pas sur la nôtre : le fond et la
     bordure de la même surface partaient ensemble et n'arrivaient pas
     ensemble. L'idiome majoritaire ici (36 usages) dit les deux d'un mot. */
  transition: all var(--duree-2) var(--courbe);
}
.glass:hover { border-color: var(--border-hov); }
.surface { background: var(--bg-secondary); border: 1px solid var(--border); }

/* Gradient text */
.gradient-text {
  background: linear-gradient(130deg, var(--accent) 0%, var(--accent-ll) 60%, var(--accent-l) 100%);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}

/* --- Animations --- */
@keyframes fadeInUp   { from { opacity:0; transform:translateY(12px); } to { opacity:1; transform:translateY(0); } }
@keyframes fadeIn     { from { opacity:0; } to { opacity:1; } }
@keyframes slideLeft  { from { opacity:0; transform:translateX(-16px); } to { opacity:1; transform:translateX(0); } }
@keyframes slideRight { from { opacity:0; transform:translateX(16px); } to { opacity:1; transform:translateX(0); } }
@keyframes slideUp    { from { opacity:0; transform:translateY(100%); } to { opacity:1; transform:translateY(0); } }
@keyframes slideDown  { from { opacity:0; transform:translateY(-8px); } to { opacity:1; transform:translateY(0); } }
@keyframes pulseDot   { 0%,100%{opacity:.3;}50%{opacity:1;} }
@keyframes blink      { 50%{opacity:0;} }
@keyframes scaleIn    { from{opacity:0;transform:scale(.94);} to{opacity:1;transform:scale(1);} }
@keyframes spin       { to { transform: rotate(360deg); } }
@keyframes shimmer    { 0%{background-position:-200% 0;} 100%{background-position:200% 0;} }
@keyframes gradMove   { 0%{background-position:0% 50%;} 50%{background-position:100% 50%;} 100%{background-position:0% 50%;} }
/* voicePulse et glow : opacity au lieu de box-shadow → composite-only, pas de repaint */
@keyframes voicePulse { 0%,100%{opacity:.7;transform:scale(1);}50%{opacity:1;transform:scale(1.08);} }
@keyframes glow       { 0%,100%{opacity:.6;}50%{opacity:1;} }
@keyframes bounceIn   { 0%{transform:scale(.3);opacity:0;} 50%{transform:scale(1.06);} 70%{transform:scale(.97);} 100%{transform:scale(1);opacity:1;} }
@keyframes ripple     { to { transform:scale(4); opacity:0; } }
@keyframes skeletonPulse { 0%,100%{opacity:.6;} 50%{opacity:.3;} }

.anim-fade-up    { animation: fadeInUp .35s ease-out both; }
.anim-fade       { animation: fadeIn .25s ease-out both; }
/* Tiroir de travail : supprimé — voir renderReflexion dans src/app.js. */

/* ── Step cards — expand/collapse chevron ─────────────────── */
details[open] > summary .step-chevron { transform: rotate(90deg); }
.step-chevron { transition:  transform var(--duree-2) var(--courbe); }
details > summary::-webkit-details-marker { display: none; }
details > summary::marker { display: none; }
.crea-step-card { border-radius: 0; }
.crea-step-card:last-child { border-bottom: none !important; }

.anim-slide-l    { animation: slideLeft .25s ease-out both; }
.anim-slide-r    { animation: slideRight .25s ease-out both; }
.anim-slide-up   { animation: slideUp .3s cubic-bezier(.16,1,.3,1) both; }
.anim-slide-down { animation: slideDown .2s ease-out both; }
.anim-scale-in   { animation: scaleIn .2s cubic-bezier(.16,1,.3,1) both; }
.anim-bounce-in  { animation: bounceIn .45s ease-out both; }
.anim-spin       { animation: spin 1s linear infinite; }
.anim-glow       { animation: glow 2s ease-in-out infinite; }

/* ── ON N'ENTRE PAS DEUX FOIS DANS LE MÊME ÉCRAN ──────────────────────────
 * Toutes les animations ci-dessus sont des ENTRÉES : elles font passer un
 * élément de opacity:0 / translate / scale à son état normal. Une animation CSS
 * démarre quand l'élément entre dans le document — or render() fait
 * `app.innerHTML = …`, donc TOUS les nœuds sont recréés à chaque rendu, et
 * toutes ces entrées rejouent. Pendant que le modèle écrit, c'est plusieurs fois
 * par seconde : la barre latérale, les panneaux et les boutons repartent sans
 * cesse de scale(.96) et d'opacité nulle. C'est « ça tremble », « les boutons
 * bougent », « ça se fait en deux temps ».
 *
 * `sans-entrees` est posée sur #app quand le rendu redessine le MÊME écran
 * (voir marquerEntrees dans app.js). `entree-voulue` est l'exception : ce que le
 * rendu déclare comme réellement nouveau (un message qui arrive), via animEntree.
 *
 * Les animations en boucle — anim-spin, anim-glow, typing-dot, pulse — ne sont
 * pas des entrées et ne sont pas touchées : un chargement doit continuer de
 * tourner pendant que le modèle écrit.
 */
.sans-entrees .anim-fade-up:not(.entree-voulue),
.sans-entrees .anim-fade:not(.entree-voulue),
.sans-entrees .anim-slide-l:not(.entree-voulue),
.sans-entrees .anim-slide-r:not(.entree-voulue),
.sans-entrees .anim-slide-up:not(.entree-voulue),
.sans-entrees .anim-slide-down:not(.entree-voulue),
.sans-entrees .anim-slide-in-right:not(.entree-voulue),
.sans-entrees .anim-scale-in:not(.entree-voulue),
.sans-entrees .anim-bounce-in:not(.entree-voulue),
.sans-entrees .dropdown-enter:not(.entree-voulue) {
  animation: none !important;
}

/* Typing dots */
.typing-dot { animation: pulseDot 1.4s ease-in-out infinite; }
.typing-dot:nth-child(2) { animation-delay:.2s; }
.typing-dot:nth-child(3) { animation-delay:.4s; }

/* Thinking bar */
.thinking-bar {
  background: linear-gradient(90deg, transparent, var(--accent-glow), transparent);
  background-size: 200% 100%;
  animation: shimmer 1.8s linear infinite;
}

/* Voice pulse */
.voice-pulse { animation: voicePulse 1.5s ease-in-out infinite; }

/* Welcome gradient bg */
.gradient-bg {
  background: linear-gradient(-45deg, #060912, #0f172a, #090d1f, #0c1029);
  background-size: 400% 400%;
  animation: gradMove 18s ease infinite;
}
html.light .gradient-bg {
  background: linear-gradient(-45deg, #f8fafc, #eef2ff, #f0f4ff, #e8edfe);
  background-size: 400% 400%;
}

/* --- Markdown content --- */
/* ══ LA TAILLE DU TEXTE ET LA POLICE DE LA DISCUSSION ══════════════════════
 *
 * « Il y a plein de choses qui manquent » — deux d'entre elles sont ici.
 *
 * LA TAILLE JOUE SUR LA RACINE, pas sur chaque règle. Toute l'échelle
 * typographique est écrite en `max(X rem, Y px)` : changer la taille du `html`
 * déplace la part en `rem` et l'application entière suit, d'un coup, sans
 * qu'aucune règle n'ait à connaître ce réglage.
 *
 * LE PLANCHER EN PIXELS RESTE, ET C'EST VOULU. « Plus petit » resserre ce qui
 * est déjà grand mais ne descend jamais sous le plancher de chaque niveau :
 * on peut tasser une interface, on ne doit pas pouvoir la rendre illisible.
 *
 * LA POLICE NE CHANGE QUE DANS LA DISCUSSION. Elle ne touche ni les menus, ni
 * les réglages, ni les boutons : quelqu'un qui choisit une serif pour lire des
 * réponses ne demande pas à ce que toute l'application change d'habit. Le code
 * garde sa chasse fixe dans tous les cas — une police proportionnelle
 * désaligne l'indentation, et du code désaligné est du code faux à lire.
 */
html.crea-texte-petit      { font-size: 93.75%; }
html.crea-texte-grand      { font-size: 112.5%; }
html.crea-texte-tres-grand { font-size: 125%; }

.msg-content { font-family: var(--police-discussion, inherit); }
.msg-content code, .msg-content pre, .msg-content pre * { font-family: 'JetBrains Mono', ui-monospace, monospace; }

.msg-content { overflow-wrap: break-word; word-break: break-word; min-width: 0; }
.msg-content p { margin-bottom:.6rem; line-height:1.78; }
.msg-content p:last-child { margin-bottom:0; }
.msg-content ul,.msg-content ol { margin-bottom:.6rem; padding-left:1.5rem; }
.msg-content ul { list-style: disc; }
.msg-content ol { list-style: decimal; }
.msg-content li { margin-bottom:.25rem; line-height:1.65; }
.msg-content li > ul, .msg-content li > ol { margin-top:.2rem; margin-bottom:0; }
.msg-content h1,.msg-content h2,.msg-content h3,.msg-content h4 { font-weight:600; margin:1rem 0 .4rem; color:var(--t-secondary); }
.msg-content h1 { font-size:1.3rem; } .msg-content h2 { font-size:1.15rem; }
.msg-content h3 { font-size:1.05rem; } .msg-content h4 { font-size:.95rem; }
.msg-content code:not(pre code) {
  background: rgba(92,124,250,.1); color: var(--accent-ll);
  padding:.12rem .38rem; border-radius: var(--radius-xs); font-size:.84em;
  font-family:'JetBrains Mono',monospace; border:1px solid rgba(92,124,250,.12);
}
html.light .msg-content code:not(pre code) { background:rgba(76,110,245,.08); color:#4263eb; }
.msg-content pre { margin-bottom:.75rem; border-radius:var(--radius); overflow-x:auto; }
.msg-content blockquote {
  border-left:3px solid var(--accent); padding-left:1rem; margin-bottom:.75rem;
  color:var(--t-muted); font-style:italic; background: var(--accent-bg);
  padding:.5rem 1rem; border-radius:0 var(--radius-sm) var(--radius-sm) 0;
}
.msg-content img { max-width:min(100%,400px); border-radius: var(--radius-lg); margin:.5rem 0; border:1px solid var(--border); }

/* --- Responsive mobile --- */
.md-hide-desktop { display:none; }
@media (max-width:767px) {
  .md-hide-desktop { display:flex; }                 /* burger + bouton onglets visibles sur mobile */
  .banner-new { font-size:var(--texte-2); padding:var(--espace-3) var(--espace-5); }  /* bannière compacte */
  .banner-new span:nth-child(2) { display:none; }    /* cacher texte long, garder badge */
  #messages-container .mx-auto { padding-left:.75rem; padding-right:.75rem; }
  #crea-tabbar { display:none; }                     /* barre d'onglets navigateur masquée : gérée par le bouton à côté du menu */
}
/* Modale Réglages — plein écran sur mobile, sidebar centrée sur desktop */
.settings-modal { height: 100dvh; max-height: 100dvh; border-radius: 0 !important; }
/* LA MODALE DES RÉGLAGES EST UNE PAGE, PAS UNE ALERTE — elle a donc la taille
   d'une page. 620px de haut la rabotaient à 69% d'un écran de 900 : les cinq
   groupes du rail n'y tenaient pas, le dernier était coupé, et le panneau de
   droite ne faisait que 576px — les descriptions y revenaient à la ligne au
   troisième mot. Mesuré sur la référence : 84% de la hauteur de la fenêtre. */
@media (min-width: 640px) { .settings-modal { height: 86vh; max-height: 820px; border-radius: var(--radius-lg) !important; } }

/* LE VOILE COUVRE TOUT, ET IL FLOUTE POUR DE BON. Il couvre déjà l'en-tête de
   l'application (vérifié), mais à 4px on lisait encore la conversation
   derrière et l'œil y retournait : le flou n'est pas une décoration, c'est ce
   qui dit que le reste attend. La saturation baissée enlève au fond ses
   couleurs vives, qui traversent le flou intactes. */
#settings-overlay {
  backdrop-filter: blur(14px) saturate(0.9);
  -webkit-backdrop-filter: blur(14px) saturate(0.9);
}

/* UNE SEULE MESURE POUR TOUT LE PANNEAU. Chaque onglet portait la sienne —
   max-w-lg (512px) sur Général, max-w-2xl (672) ailleurs — donc la largeur du
   texte changeait d'un onglet à l'autre, et sur le panneau élargi il restait
   jusqu'à 300px de vide à droite. La mesure appartient au panneau : c'est lui
   qui sait de quelle place il dispose, pas chacun de ses contenus.
   Bornée aux enfants DIRECTS : un formulaire imbriqué garde le droit d'être
   étroit là où c'est lui qui le décide. */
#settings-tab-content > * { max-width: none; }

/* LE PANNEAU DES ESPACES SORT SUR LE CÔTÉ DU BLOC COMPTE, AU SURVOL.
   Il est dans le DOM en permanence et c'est `:hover` qui le montre : un survol
   qui déclencherait un rendu remplacerait le nœud sous le curseur, le
   navigateur tirerait un `mouseleave` sur l'élément détruit, et le panneau se
   refermerait tout seul — mesuré, il clignotait.
   Le délai à l'apparition évite qu'il jaillisse quand on ne fait que passer au
   dessus pour atteindre autre chose. */
/* Le panneau des espaces se rend à la RACINE (voir renderEspacesRoot) : posé
   dans le pied de la barre latérale, il se faisait rogner — la barre contient
   jusqu'aux éléments en position:fixe. Il n'a donc plus de règle ici. */
/* Onglets : border-bottom sur mobile (tabs en haut), border-right sur desktop (sidebar gauche) */
.settings-tabs { border-top: none; border-right: none; border-bottom: 1px solid var(--border); }
@media (min-width: 640px) { .settings-tabs { border-bottom: none; border-right: 1px solid var(--border); } }

/* Tableaux : le style complet est plus bas (« === Tableaux === »), avec la carte
   .md-table-card qui porte le défilement horizontal. Les anciennes règles qui
   vivaient ici — display:block, white-space:nowrap, bordure sur chaque cellule,
   en-tête vert accentué — ont été retirées : `display:block` neutralisait la
   largeur du tableau (colonnes tassées à gauche) et un quadrillage complet
   alourdissait la lecture. */
.msg-content a { color:var(--accent-l); text-decoration:underline; text-underline-offset:2px; }
.msg-content a:hover { color:var(--accent-ll); }
.msg-content hr { border:none; border-top:1px solid var(--border); margin:1rem 0; }
.msg-content strong { color:var(--t-secondary); font-weight:600; }
.msg-content em { color:var(--t-muted); }
.msg-content .katex-display { margin:.75rem 0; overflow-x:auto; }
.msg-content .katex { font-size:1.05em; }
.mermaid-container { margin:.75rem 0; border-radius:var(--radius); overflow:hidden; background:var(--bg-tertiary); padding:1.25rem; border:1px solid var(--border); }
.mermaid-container svg { max-width:100%; }

/* Orbe live mini — bouton flottant au-dessus de la barre de saisie */
.live-orbe {
  width:44px; height:44px; border-radius:50%;
  background:linear-gradient(135deg,#f43f5e,#ec4899);
  display:flex; align-items:center; justify-content:center;
  color:white; border:none; cursor:pointer;
  box-shadow:0 4px 16px rgba(244,63,94,.35);
  transition: transform var(--duree-2) var(--courbe), box-shadow var(--duree-2) var(--courbe);
}
.live-orbe:hover { transform:scale(1.08); }
.live-orbe:active { transform:scale(0.95); }
@keyframes orbe-pulse {
  0%,100% { box-shadow:0 0 0 0 rgba(244,63,94,.5), 0 4px 16px rgba(244,63,94,.35); }
  50% { box-shadow:0 0 0 10px rgba(244,63,94,0), 0 4px 16px rgba(244,63,94,.35); }
}
@keyframes orbe-breathe {
  0%,100% { transform:scale(1); box-shadow:0 4px 16px rgba(244,63,94,.35); }
  50% { transform:scale(1.12); box-shadow:0 8px 28px rgba(244,63,94,.55); }
}
.live-orbe-listening { animation:orbe-pulse 1.2s ease-in-out infinite; }
.live-orbe-speaking  { animation:orbe-breathe 1.8s ease-in-out infinite; }

/* ── NAVIGATEUR DE CONVERSATION ─────────────────────────────────────────────
   DEUX CHOSES DISTINCTES, JAMAIS MÉLANGÉES.

     au repos   un peigne de traits serrés, et rien d'autre
     au survol  le peigne s'efface, LE BLOC apparaît à sa place

   Les traits ne « deviennent » pas les lignes du bloc — c'était mon erreur
   précédente, et elle donnait une chose hybride qui ne ressemblait ni à l'un
   ni à l'autre. Le peigne est un repère ; le bloc est une liste. L'un laisse
   la place à l'autre.

   LA DENSITÉ SE LIT, ELLE NE SE DEVINE PAS. Deux erreurs successives, dans
   les deux sens : d'abord des traits si espacés qu'ils formaient une colonne
   de tirets sans rapport entre eux ; puis, en corrigeant, des traits si
   serrés qu'ils se fondaient en une barre pleine.

   Le bon réglage est celui où CHAQUE TRAIT SE LIT SÉPARÉMENT tout en formant
   un ensemble : l'écart doit dépasser l'épaisseur, sans quoi l'anticrénelage
   les soude. Deux pixels de trait, quatre d'écart — un pas de six. */
.chat-nav {
  /* AU MILIEU DU BORD, pas en haut. C'est la position de la référence, et elle
     a une raison : le peigne représente TOUTE la conversation, donc son centre
     tombe naturellement au centre de la hauteur, et le repère actif s'y
     déplace de haut en bas comme un curseur de règle. Accroché en haut, il
     avait l'air d'un menu oublié dans un coin. */
  position:absolute; top:50%; transform:translateY(-50%); right:16px; z-index:20;
  display:flex; align-items:center; justify-content:flex-end;
}

/* PLACE DISPONIBLE. Deux choses décident, et elles seules : la largeur de
   l'espace de chat, et le fait qu'un panneau latéral soit ouvert — ouvert, il a
   déjà pris la largeur ; refermé, la place revient et le peigne avec elle.
   Posé par mesurerPlace() (app.js) après chaque rendu, donc à chaque ouverture
   ou fermeture de panneau, et sur redimensionnement de la fenêtre. */
.chat-nav[data-place="0"] { display:none; }
/* SA VOIE, quand la marge naturelle ne suffit plus (fenêtre ancrée à la moitié
   ou au tiers de l'écran) : la colonne de lecture lui cède 44px à droite. Il est
   là sans rien recouvrir, au lieu de disparaître alors que la place existe.
   Classe posée par mesurerPlace() (app.js), jamais en dessous d'une largeur de
   lecture décente. */
#messages-container.crea-peigne-voie .chat-thread { padding-right:44px; }

/* ── LE PEIGNE ─────────────────────────────────────────────────────────── */
.chat-nav-ticks {
  display:flex; flex-direction:column; align-items:flex-end;
  gap:var(--espace-3); padding:var(--espace-2) var(--espace-1); cursor:pointer;
  transition: opacity var(--duree-1) var(--courbe);
}
.chat-nav-tick {
  display:block; width:17px; height:2px; border-radius: var(--radius-xs);
  background:var(--t-faint); opacity:.5;
  transition: width var(--duree-2) var(--courbe), opacity var(--duree-2) var(--courbe), background-color var(--duree-2) var(--courbe);
}
/* Le message où l'on se trouve dans le fil : le repère qui donne son sens au
   peigne. Sans lui, ce ne sont que des tirets.

   IL S'ALLONGE **ET** IL BAT. Demandé en deux temps, et je n'avais retenu que
   le premier : « la partie clignote en vert, elle devient plus longue que les
   autres, c'est stylé ». L'allongement seul se voit quand on cherche le repère ;
   c'est le battement qui le fait trouver sans le chercher, dans une colonne de
   tirets tous identiques.

   Un battement, pas un clignotement : l'opacité descend et remonte, le trait ne
   disparaît jamais. Un repère qui s'éteint cesse d'être un repère la moitié du
   temps, et l'œil finit par le fuir. */
@keyframes chatNavPouls {
  0%, 100% { opacity:1;   box-shadow:0 0 0 0 transparent; }
  50%      { opacity:.55; box-shadow:0 0 7px 0 var(--accent-glow); }
}
.chat-nav-tick[data-actif="1"] {
  width:26px; opacity:1; background:var(--accent);
  animation:chatNavPouls 1.6s ease-in-out infinite;
}
/* Le mouvement perpétuel au bord de l'écran est exactement ce que ce réglage
   système demande de couper. L'allongement, lui, reste : il ne bouge pas. */
@media (prefers-reduced-motion: reduce) {
  .chat-nav-tick[data-actif="1"] { animation:none; }
}
/* PAS DE COULEUR PARTICULIÈRE POUR LES CHAPITRES. Un peigne dit une seule
   chose : où l'on est dans le fil. Y ajouter une seconde information par la
   couleur oblige à se demander ce que veut dire chaque teinte, pour un gain
   nul — le repère actif suffit, et lui seul mérite d'être distingué. */

/* ── LE BLOC ───────────────────────────────────────────────────────────── */
/* Il PREND LA PLACE du peigne — il ne se pose pas à côté. C'est ce qui faisait
   voir la conversation en double : la liste, et le peigne encore là. */
.chat-nav:hover .chat-nav-ticks { opacity:0; pointer-events:none; }
.chat-nav-panel {
  position:absolute; top:0; right:0;
  display:none; flex-direction:column;
  width:250px; max-height:min(60vh,430px); overflow-y:auto;
  padding:var(--espace-3); border-radius: var(--radius-lg);
  background:var(--bg-primary); border:1px solid var(--border-hov);
  box-shadow: var(--ombre-4);
  scrollbar-width:thin;
}
.chat-nav:hover .chat-nav-panel { display:flex; }
/* IL SUIT LA TAILLE DE L'APPLICATION. 250px sur une fenêtre ancrée au tiers ou
   à la moitié d'un écran couvriraient une part trop large de la colonne de
   lecture au survol. Le peigne au repos, lui, ne bouge pas : il tient dans la
   marge à toutes les tailles. */
@media (max-width: 1100px) { .chat-nav-panel { width:210px; } }
@media (max-width: 900px)  { .chat-nav-panel { width:180px; } }
/* Fenêtre courte : le bloc ne doit pas dépasser en haut et en bas. */
@media (max-height: 600px) { .chat-nav-panel { max-height:min(72vh,300px); } }

/* Les lignes sont SERRÉES. Une liste de repères se parcourt du regard : de
   l'air entre chaque ligne oblige à défiler pour voir ce qui tenait à l'écran. */
.chat-nav-ligne {
  display:block; width:100%; text-align:left;
  /* ARRONDI VERS LE BAS ICI, ET C'EST UNE EXCEPTION ASSUMÉE. Le rythme arrondit
     vers le haut partout ailleurs — un texte qui frôle son bord se voit, une
     boîte un pixel plus large ne se voit pas. Mais cette liste est une DENSITÉ :
     sa garde exige qu'on la parcoure du regard sans défiler, et un pixel de plus
     par ligne se paie sur toute la hauteur. La règle générale cède devant une
     exigence nommée, elle ne l'écrase pas. */
  padding:var(--espace-2) var(--espace-4); border:none; background:none; cursor:pointer;
  font-size:var(--texte-3); line-height:16px; border-radius: var(--radius-sm);
  color:var(--t-secondary);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.chat-nav-ligne:hover { background:var(--bg-secondary); }
/* LÀ OÙ L'ON SE TROUVE EST TOUJOURS ENCADRÉ, même sans survol — c'est le seul
   repère du bloc, il ne doit pas dépendre d'un geste. Un fond plus soutenu que
   celui du survol : sinon la ligne survolée et la ligne courante se
   ressemblent, et l'on ne sait plus laquelle dit quoi. */
.chat-nav-ligne[data-actif="1"] {
  color:var(--t-primary); font-weight:600;
  background:var(--bg-tertiary, var(--border));
  box-shadow:inset 2px 0 0 var(--accent);
}

/* Écrans tactiles : sans survol, un peigne ne s'ouvre jamais. La feuille de
   chapitres mobile joue ce rôle. */
@media (hover:none) { .chat-nav { display:none; } }

/* --- Pouls des dossiers vivants (chantier 7) : vitesse/couleur = phase de vie --- */
.folder-pulse-dot { width:6px; height:6px; border-radius:50%; background:var(--folder-pulse-color, var(--accent)); flex-shrink:0; }
@keyframes folderPulse { 0%,100% { opacity:.4; box-shadow:0 0 0 0 color-mix(in srgb, var(--folder-pulse-color, var(--accent)) 50%, transparent); } 50% { opacity:1; box-shadow:0 0 0 4px color-mix(in srgb, var(--folder-pulse-color, var(--accent)) 0%, transparent); } }
@media (prefers-reduced-motion: reduce) { .folder-pulse-dot { animation:none !important; } }

/* Flash quand on saute à un message via la minimap / les fichiers */
.jump-flash { animation:jumpFlash 1.2s ease; border-radius: var(--radius-lg); }
@keyframes jumpFlash { 0%,100%{ background:transparent } 25%{ background:var(--accent-bg) } }

/* Panneau latéral fichiers du chat */
.anim-slide-in-right { animation:slideInRight .22s ease; }
@keyframes slideInRight { from{ transform:translateX(12px); opacity:0 } to{ transform:translateX(0); opacity:1 } }

/* Suggestions de la barre de questions (type Google) */
/* Le panneau vit DANS la barre : il n'a plus ni fond ni ombre à lui, sinon on
   revoit deux boîtes. `overflow:hidden` avec le rayon du haut empêche la
   première ligne de déborder du coin arrondi de la barre. */
.input-suggest { max-height:240px; overflow:hidden auto; animation:suggIn .14s ease; }
.input-suggest button + button { border-top:1px solid var(--border); }
@keyframes suggIn { from{ opacity:0; transform:translateY(4px) } to{ opacity:1; transform:translateY(0) } }

/* Vue Réponse / Images / Liens / + — bandeau au-dessus de TOUT l'espace chat
   (façon Perplexity/Comet : clic sur un onglet remplace le fil entier par la
   vue agrégée, pas un bandeau répété dans chaque bulle de message). */
/* Réponse / Liens / Images / Actualités / Vidéos : les onglets se suffisent —
   celui qui est actif est déjà marqué. Le cadre gris qui les entourait ajoutait
   une boîte dans une boîte au milieu de l'en-tête, sans rien distinguer. */
/* =====================================================================
   MODALES — FEUILLE DU BAS SUR TÉLÉPHONE
   Piloté par html.uie-tier-phone, la classe que le Rendering Engine de
   crea-uie.js pose déjà sur <html>. Le moteur classait l'appareil depuis
   le début ; personne ne lisait sa décision. Ici, on la lit.

   Mesuré : sur les 40 fonds de modale de l'app, 3 seulement prévoyaient
   le téléphone. Les 37 autres sont des boîtes de dialogue de bureau —
   carte centrée, max-w-* qui ne mord jamais sur un écran de 440px, et
   max-h de 80 à 92vh. Sur un téléphone ça donne une dalle de ~93% de
   large sur jusqu'à 90% de haut : l'usager voit du plein écran là où il
   attend une carte.

   Une feuille ancrée en bas règle les trois problèmes d'un coup : elle
   se lit comme un bloc POSÉ sur l'écran et non comme une nouvelle page,
   elle laisse voir le contexte derrière, et ses actions tombent sous le
   pouce au lieu d'être en haut de l'écran.

   Les panneaux latéraux (justify-end sans items-*, comme #living-backdrop)
   ne portent PAS la classe : leur intention est différente.
   ===================================================================== */
html.uie-tier-phone .crea-modale {
  align-items: flex-end !important;
  justify-content: center !important;
  padding: 0 !important;
}
html.uie-tier-phone .crea-modale > * {
  width: 100% !important;
  max-width: 100% !important;
  /* Jamais toute la hauteur : la bande visible au-dessus est ce qui dit
     « ceci est un bloc, pas une page ». Et elle reste tapable pour fermer. */
  max-height: 86vh !important;
  margin: 0 !important;
  border-radius: 22px 22px 0 0 !important;
  /* La barre d'accueil du système ne doit pas manger les boutons du bas. */
  padding-bottom: var(--crea-composer-bottom, 6px) !important;
  animation: creaFeuilleMonte .22s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes creaFeuilleMonte { from { transform: translateY(14px); opacity: .6 } to { transform: none; opacity: 1 } }
html.uie-motion-reduced .crea-modale > * { animation: none; }

/* Bloc derrière chaque rangée de boutons de l'en-tête. Sans lui, les trois
   groupes (menu · onglets de vue · actions) se lisaient comme une seule
   rangée continue : les boutons du bord d'un groupe paraissaient collés à
   ceux du groupe voisin. Le fond dit où commence et où finit chaque rangée ;
   l'écart entre groupes fait le reste. */
.crea-barre-groupe { background:var(--bg-secondary); border-radius: var(--radius-lg); padding:var(--espace-1); }
.chat-view-tabs-bar { display:flex; align-items:center; gap:var(--espace-1); padding:var(--espace-1); border-radius: var(--radius-lg); background:var(--bg-secondary); min-width:0; max-width:100%; overflow-x:auto; scrollbar-width:none; }
.chat-view-tabs-bar::-webkit-scrollbar { display:none; }
/* Sur les fenêtres étroites, tous les onglets ne tiennent pas — dégradé en
   bord droit (plutôt qu'une coupe nette en plein mot) pour signaler qu'il y a
   plus de contenu à faire défiler horizontalement. Classe posée par JS
   (bindEvents) seulement quand il reste vraiment du contenu à droite —
   scrollWidth > clientWidth ET pas déjà scrollé jusqu'au bout. */
.chat-view-tabs-bar.is-overflowing-right { -webkit-mask-image:linear-gradient(to right, #000 calc(100% - 18px), transparent 100%); mask-image:linear-gradient(to right, #000 calc(100% - 18px), transparent 100%); }
/* Le bandeau d'onglets reste visible sur les cinq onglets. Les règles .autohide /
   .peek / .chat-view-tabs-handle qui l'effaçaient sur Liens/Images ont été retirées
   avec le mode « navigateur plein écran » auquel elles servaient. */
/* Centré DANS sa colonne, plus dans le viewport. Les colonnes latérales
   étaient en 1fr chacune : la droite (136px de boutons) débordait de sa
   moitié et venait recouvrir le bandeau — mesuré à -15px sur 440, -55px
   sur 360. Les côtés prennent maintenant leur largeur réelle, le centre
   récupère le reste et défile s'il le faut. */
.chat-view-tabs-wrap { position:relative; min-width:0; display:flex; justify-content:center; }
.chat-view-tab { display:inline-flex; align-items:center; justify-content:center; gap:var(--espace-3); font-size:var(--texte-3); font-weight:600; padding:var(--espace-3) var(--espace-5); border-radius: var(--radius-rond); border:1px solid transparent; background:transparent; color:var(--t-dim); cursor:pointer; transition: all var(--duree-2) var(--courbe); white-space:nowrap; }
/* Taille pilotée par le Density Engine de l'UIE (src/crea-uie.js) — fallback 17px
   si le script n'a pas encore tourné (première peinture) ou est indisponible. */
.chat-view-tab svg { flex-shrink:0; width:var(--uie-icon-size, 17px); height:var(--uie-icon-size, 17px); }
.chat-view-tab:hover { background:rgba(0,0,0,.05); color:var(--t-secondary); }
/* L'ANNEAU VERT EST PARTI.
   « Quand on clique dessus la page va juste s'ouvrir, il n'y aura pas cet effet
     vert bizarre qui entoure. Il faut trouver un autre effet pour signaler. »
   Il y avait TROIS signaux empilés pour dire la même chose : un fond accentué,
   un contour accentué et un texte accentué. Le contour est ce qui « entoure »,
   et le fond coloré le redouble. Un onglet actif se signale comme dans une
   vraie barre d'onglets : il RESSORT, en relief, sans se peindre. */
.chat-view-tab.on { background:var(--bg-primary); border-color:transparent; color:var(--t-primary); font-weight:700; box-shadow: var(--ombre-1); }
/* Libellé texte à côté de l'icône (façon Réponse/Liens/Images/Actualités/Vidéos
   des moteurs de recherche IA) — masqué sur mobile pour rester compact, l'icône
   seule suffit là où la place manque. */
.chat-view-tab-label { display:inline; }
.chat-view-tab-count { font-size:var(--texte-1); font-weight:700; opacity:.65; }
@media (max-width: 560px) { .chat-view-tab-label { display:none; } .chat-view-tab { padding:var(--espace-4) var(--espace-5); } }
.chat-view-empty { padding:32px var(--espace-8); text-align:center; color:var(--t-faint); font-size:var(--texte-4); }
.chat-view-aggregate { padding:var(--espace-8); overflow-y:auto; height:100%; }
.msg-tab-imggrid { display:grid; grid-template-columns:repeat(auto-fill,minmax(140px,1fr)); gap:var(--espace-5); }
.msg-tab-img { display:block; position:relative; border-radius: var(--radius); overflow:hidden; border:1px solid var(--border); aspect-ratio:1; }
.msg-tab-img img { width:100%; height:100%; object-fit:cover; display:block; }
.msg-tab-img-badge { position:absolute; left:6px; bottom:6px; max-width:calc(100% - 12px); padding:var(--espace-2) var(--espace-4); border-radius: var(--radius-rond); background:rgba(0,0,0,.55); backdrop-filter:blur(2px); color:#fff; font-size:var(--texte-1); font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.msg-tab-linklist { display:flex; flex-direction:column; gap:var(--espace-4); max-width:640px; }

/* ── Onglet Actualités ─────────────────────────────────────────────────────── */
.chat-view-news-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(min(260px,100%),1fr)); gap:var(--espace-6); }
.chat-news-card { display:flex; flex-direction:column; border-radius: var(--radius); border:1px solid var(--border); background:var(--bg-secondary); overflow:hidden; text-decoration:none; color:inherit; transition: box-shadow var(--duree-2),border-color var(--duree-2) var(--courbe); }
.chat-news-card:hover { border-color:var(--accent); box-shadow: var(--ombre-2); }
.chat-news-thumb { width:100%; aspect-ratio:16/9; background:var(--bg-tertiary,#1a1a1a); overflow:hidden; }
.chat-news-thumb img { width:100%; height:100%; object-fit:cover; display:block; }
.chat-news-no-thumb { background:linear-gradient(135deg,#1e1e2e,#2d2d44); }
.chat-news-card-body { padding:var(--espace-6) var(--espace-7); display:flex; flex-direction:column; gap:var(--espace-3); }
.chat-news-meta { display:flex; align-items:center; gap:var(--espace-3); }
.chat-news-source { font-size:var(--texte-2); font-weight:600; color:var(--accent); text-transform:uppercase; letter-spacing:.4px; }
.chat-news-date { font-size:var(--texte-2); color:var(--t-faint); }
.chat-news-title { font-size:var(--texte-4); font-weight:600; color:var(--t-primary); line-height:1.4; margin:0; display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }

/* ── Onglet Vidéos ─────────────────────────────────────────────────────────── */
.chat-view-videos-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:var(--espace-6); }
.chat-video-card { display:flex; flex-direction:column; border-radius: var(--radius); border:1px solid var(--border); background:var(--bg-secondary); overflow:hidden; text-decoration:none; color:inherit; transition: box-shadow var(--duree-2),border-color var(--duree-2) var(--courbe); }
.chat-video-card:hover { border-color:var(--accent); box-shadow: var(--ombre-2); }
.chat-video-thumb { position:relative; width:100%; aspect-ratio:16/9; background:var(--bg-tertiary,#1a1a1a) center/cover no-repeat; }
.chat-video-no-thumb { background:linear-gradient(135deg,#1e1e2e,#2d2d44); }
.chat-video-play { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; font-size:var(--texte-12); color:#fff; background:rgba(0,0,0,.25); opacity:0; transition: opacity var(--duree-2) var(--courbe); }
.chat-video-card:hover .chat-video-play { opacity:1; }
.chat-video-info { padding:var(--espace-5) var(--espace-6); display:flex; flex-direction:column; gap:var(--espace-2); }
.chat-video-title { font-size:var(--texte-4); font-weight:600; color:var(--t-primary); line-height:1.4; margin:0; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.chat-video-channel { font-size:var(--texte-2); color:var(--t-dim); }
.msg-tab-link { display:flex; flex-direction:column; gap:var(--espace-1); padding:var(--espace-5) var(--espace-7); border-radius: var(--radius); border:1px solid var(--border); background:var(--bg-secondary); text-decoration:none; transition: background var(--duree-2) var(--courbe); }
.msg-tab-link:hover { background:rgba(0,0,0,.05); }
.msg-tab-link-title { font-size:var(--texte-4); font-weight:600; color:var(--t-primary); }
.msg-tab-link-url { font-size:var(--texte-2); color:var(--t-faint); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* === Blocs de code =========================================================
   Le bloc précédent était un pavé #050b15 (noir bleuté, plus sombre que
   n'importe quelle autre surface de l'app) surmonté d'un en-tête criant
   « POWERSHELL 1 LIGNES » et flanqué d'une gouttière de numéros — pour une
   commande d'une seule ligne. Ici : une surface qui appartient au thème, un
   en-tête calme, des numéros seulement quand ils servent, et un format compact
   dédié aux commandes d'une ligne.
   ========================================================================= */
:root {
  --code-bg:      #fafbfc;
  --code-head:    #f2f4f7;
  --code-border:  #e3e6ea;
  --code-fg:      #1f2937;
  --code-gutter:  #b6bcc6;
}
html.dark {
  --code-bg:      #191919;
  --code-head:    #232323;
  --code-border:  #333333;
  --code-fg:      #e3e6ec;
  --code-gutter:  #5c5c5c;
}

.code-card {
  margin: 1.15em 0;
  border: 1px solid var(--code-border);
  border-radius: var(--radius);
  background: var(--code-bg);
  overflow: hidden;
  transition:  border-color var(--duree-2) var(--courbe);
}
.code-card:hover { border-color: var(--border-hov); }

/* LA CARTE D'ARTEFACT — compacte, premium, façon Claude. Un artefact (maquette,
   document, composant, visuel) ne se déverse pas en pavé de code : il se pose
   en carte cliquable qui ouvre le visualiseur. */
.artefact-carte {
  display: flex; align-items: center; gap: .75rem;
  width: 100%;
  margin: 1.15em 0;
  padding: .7rem .85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-secondary);
  cursor: pointer;
  transition: all var(--duree-2) var(--courbe);
}
.artefact-carte-ic svg { width: 20px; height: 20px; }
.artefact-carte:hover {
  border-color: var(--accent);
  box-shadow: var(--ombre-2);
  transform: translateY(-1px);
}
.artefact-carte-ic {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--radius); flex-shrink: 0;
  color: #fff;
}
.artefact-carte-corps { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.artefact-carte-nom {
  font-weight: 600; font-size: max(0.84375rem, 13.5px); color: var(--t-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.artefact-carte-type {
  font-size: max(0.6875rem, 11px); color: var(--t-faint);
  text-transform: uppercase; letter-spacing: .04em; margin-top: 1px;
}
.artefact-carte-actions { display: flex; align-items: center; gap: .25rem; flex-shrink: 0; }
.artefact-carte-globe,
.artefact-carte-dl {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--radius-sm); color: var(--t-dim);
  transition: all var(--duree-2) var(--courbe);
}
.artefact-carte-globe:hover,
.artefact-carte-dl:hover { background: var(--accent-bg); color: var(--accent); }
.artefact-carte-ouvrir {
  display: flex; align-items: center; gap: .35rem;
  font-size: max(0.75rem, 12px); font-weight: 600; color: var(--accent);
  padding: .35rem .6rem; border-radius: var(--radius-sm); background: var(--accent-bg);
}

.code-card-head {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  min-height: 34px; padding: .3rem .45rem .3rem .8rem;
  background: var(--code-head);
  border-bottom: 1px solid var(--code-border);
}
.code-card-lang {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .78rem; font-weight: 500; letter-spacing: .01em;
  color: var(--t-muted);
  /* pas de text-transform : « PowerShell », pas « POWERSHELL » */
}
.code-card-pastille {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 8%, transparent);
}
.code-card-compte {
  font-size: .72rem; color: var(--t-faint); font-variant-numeric: tabular-nums;
}
.code-card-compte::before { content: '·'; margin: 0 .4rem 0 .15rem; }

.code-card-actions { display: inline-flex; align-items: center; gap: .1rem; flex: none; }
/* Au repos les actions s'effacent ; elles reviennent au survol du bloc ou dès
   qu'on les navigue au clavier. Sur écran tactile (pas de survol), elles
   restent visibles — sinon elles seraient inatteignables. */
@media (hover: hover) {
  .code-card-actions { opacity: .55; transition:  opacity var(--duree-2) var(--courbe); }
  .code-card:hover .code-card-actions,
  .code-card-actions:focus-within { opacity: 1; }
}

.code-act {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .28rem .5rem; border: none; background: transparent;
  border-radius: var(--radius-sm); cursor: pointer;
  font-size: .74rem; font-weight: 500; color: var(--t-dim);
  transition:  background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe);
}
.code-act:hover { background: var(--bg-hover); color: var(--t-primary); }
.code-act:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.code-act svg { width: 13px; height: 13px; }
.code-act--icone { padding: .3rem; }
.code-act.copied { color: var(--success); }
/* Alias conservé : d'anciens rendus (aperçus mermaid, vues studio) utilisent
   encore cette classe. */
.copy-btn-code {
  display: inline-flex; align-items: center; gap: .375rem; padding: .28rem .5rem;
  border-radius: var(--radius-sm); font-size: .74rem; cursor: pointer; border: none;
  color: var(--t-dim); background: transparent; transition:  background var(--duree-2), color var(--duree-2) var(--courbe);
}
.copy-btn-code:hover { background: var(--bg-hover); color: var(--t-primary); }
.copy-btn-code.copied { color: var(--success); }

/* C'est la SOURCE qui défile, pas la carte : la gouttière de numéros reste en
   place quand on suit une ligne longue vers la droite. Deux conteneurs à
   défilement imbriqués donneraient deux barres et un décalage de la gouttière. */
.code-card-body { display: flex; align-items: stretch; overflow: hidden; }
.msg-content .code-card-body { overflow: hidden; }
.code-card-num {
  flex: none; margin: 0; padding: .8rem .65rem .8rem .85rem;
  text-align: right; user-select: none;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .8rem; line-height: 1.65; font-variant-numeric: tabular-nums;
  color: var(--code-gutter); border-right: 1px solid var(--code-border);
  background: transparent;
}
/* La hauteur de ligne DOIT être posée sur le <pre> lui-même, pas seulement sur
   le <code> qu'il contient : c'est le bloc qui gouverne les boîtes de ligne. En
   la posant sur l'inline seulement, le code héritait du 1.7 de .msg-content
   pendant que la gouttière tournait à 1.65 — les numéros décrochaient d'un
   demi-interligne dès la sixième ligne. */
.code-card-src {
  flex: 1 1 auto; min-width: 0; margin: 0; padding: .8rem 1rem;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  background: transparent; border: none; border-radius: 0;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .8rem; line-height: 1.65; color: var(--code-fg);
}
.code-card-src code {
  font: inherit; line-height: inherit; color: inherit;
  white-space: pre; background: transparent; padding: 0; border: none;
}

/* --- L'inventaire : Artéfacts en lignes, Contenu en vignettes --------------
   Ce qui sépare les deux sections n'est pas le format, c'est l'ORIGINE : ce que
   CRÉA a construit d'un côté, ce qui est entré ou sorti comme matière de
   l'autre. Deux formes différentes parce que ce sont deux natures différentes —
   une ligne se lit, une vignette se reconnaît. */
.inv-section-titre {
  font-size: var(--texte-1); font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--t-faint); margin-bottom: var(--espace-4);
}
.inv-vide { font-size: var(--texte-3); color: var(--t-faint); padding: var(--espace-4) 0; }
.inv-tout-dl {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  font-size: var(--texte-2); color: var(--t-secondary);
  padding: var(--espace-2) var(--espace-5); border-radius: var(--radius-sm);
}
.inv-tout-dl:hover { background: var(--bg-secondary); color: var(--t-primary); }

.inv-ligne {
  display: flex; align-items: center; gap: var(--espace-4); width: 100%;
  padding: var(--espace-4); margin-bottom: var(--espace-3);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-primary); text-align: left; cursor: pointer;
  transition: all var(--duree-2) var(--courbe);
}
.inv-ligne:hover { border-color: var(--accent); box-shadow: var(--ombre-2); transform: translateY(-1px); }
/* L'icône dans un carré arrondi teinté — le repère du type, à gauche, comme
   une vignette. C'est ce qui donne le rythme « premium » d'une liste de
   fichiers, plutôt qu'un pictogramme flottant. */
.inv-ligne-ic {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--radius-sm);
  background: var(--accent-bg); color: var(--accent);
}
/* min-width:0 sur le conteneur ET sur l'enfant : sans les deux, un nom long
   pousse la ligne au lieu d'être tronqué, et la carte déborde du panneau. */
.inv-ligne-txt { display: flex; flex-direction: column; min-width: 0; gap: 1px; flex: 1; }
/* Le globe « ouvrir dans le navigateur » sur une ligne d'artefact web — poussé
   à droite, discret, il s'allume au survol. */
.inv-ligne-globe {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--radius-sm);
  color: var(--t-dim); transition: all var(--duree-2) var(--courbe);
}
.inv-ligne-globe:hover { background: var(--accent-bg); color: var(--accent); }
.inv-ligne-nom {
  font-size: var(--texte-3); font-weight: 600; color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.inv-ligne-type {
  font-size: var(--texte-1); color: var(--t-faint);
  text-transform: uppercase; letter-spacing: .04em; margin-top: 1px;
}

.inv-grille { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--espace-4); }
.inv-vignette {
  position: relative; aspect-ratio: 1; overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-input);
}
.inv-vignette--texte {
  display: flex; flex-direction: column; justify-content: space-between;
  padding: var(--espace-4); text-align: left;
}
.inv-vignette-apercu {
  font-size: var(--texte-1); line-height: 1.35; color: var(--t-dim);
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.inv-vignette-badge {
  align-self: flex-start; font-size: var(--texte-1); font-weight: 600;
  padding: 1px var(--espace-4); border-radius: var(--radius-rond);
  border: 1px solid var(--border); color: var(--t-faint);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* --- Texte rédigé : la même carte, mais ce n'est pas du code ---------------
   « Il y a aussi le canvas où CRÉA rédige du texte dans un carré qui l'entoure,
    avec une icône copier. »

   Le carré existait, mais réservé au code. Un texte qui y arrivait héritait de
   la chasse fixe, des numéros de ligne et de la coloration syntaxique : une
   lettre affichée comme un fichier source.

   Même enveloppe (bordure, rayon, en-tête, bouton copier) pour qu'on les lise
   comme une famille ; ce qui change, c'est ce que la carte MONTRE.

   Le fond suit celui de la page, pas celui du code : un texte à lire n'est pas
   un extrait de programme, et le pavé sombre du code le ferait ressortir comme
   tel. C'est la remarque « le noir, c'était mal structuré, je voulais une
   couleur sobre » — appliquée ici aussi. */
.code-card--texte {
  background: var(--bg-secondary);
  border-color: var(--border);
}
.code-card--texte .code-card-head {
  background: transparent;
  border-bottom: 1px solid var(--border);
}
.code-card-texte {
  flex: 1 1 auto; min-width: 0; margin: 0; padding: var(--espace-6) var(--espace-8);
  /* pre-wrap et non pre : le texte se replie dans la largeur disponible. Avec
     `pre`, un paragraphe rédigé partait en défilement horizontal — illisible
     sur téléphone, et personne ne fait défiler une lettre de gauche à droite. */
  white-space: pre-wrap; overflow-wrap: anywhere;
  font-family: inherit; font-size: var(--texte-5); line-height: 1.7;
  color: var(--t-primary);
}

/* --- Commande d'une ligne : format compact --------------------------------
   Un prompt, la commande, un bouton copier. Pas d'en-tête, pas de gouttière. */
.code-card--ligne {
  display: flex; align-items: center; gap: .55rem;
  padding: .4rem .4rem .4rem .8rem; margin: .9em 0;
  border-radius: var(--radius);
}
.code-card--ligne .code-card-prompt {
  flex: none; font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .8rem; font-weight: 600; color: var(--accent); user-select: none;
}
.code-card--ligne .code-card-src { padding: 0; overflow-x: auto; min-width: 0; }
.code-card--ligne .code-act { flex: none; }
@media (hover: hover) {
  .code-card--ligne .code-act { opacity: .5; transition:  opacity var(--duree-2) var(--courbe); }
  .code-card--ligne:hover .code-act,
  .code-card--ligne .code-act:focus-visible { opacity: 1; }
}

/* Vue « Tableau » d'un bloc JSON : héritée du style de tableau des réponses. */
.code-card .json-table-view { padding: .25rem .8rem .8rem; overflow-x: auto; }
.code-card .json-table-view table { border-collapse: collapse; width: max-content; min-width: 100%; font-size: .78rem; }
.code-card .json-table-view th,
.code-card .json-table-view td { padding: .38em .7em; text-align: left; border-bottom: 1px solid var(--code-border); }
.code-card .json-table-view th { color: var(--t-primary); font-weight: 600; white-space: nowrap; }
.code-card .json-table-view td { color: var(--t-secondary); font-variant-numeric: tabular-nums; }
.code-card .json-table-view tr:last-child td { border-bottom: none; }

/* Surfaces studio (documents, bulles IA) : le bloc doit rester lisible sur un
   fond clair même en thème sombre. */
.studio-doc-surface .code-card,
.studio-ai-msg .code-card {
  --code-bg: #fafbfc; --code-head: #f2f4f7; --code-border: #e3e6ea;
  --code-fg: #1f2937; --code-gutter: #b6bcc6;
}

/* --- Coloration syntaxique ------------------------------------------------
   highlight.js n'est chargé qu'avec le thème « github-dark » (une seule feuille
   pour les deux thèmes de l'app). Ses couleurs, posées sur la surface claire
   d'un bloc en thème clair, virent au pastel illisible. On repose donc la
   palette ici, une fois par thème, avec des jetons qui tiennent le contraste
   des deux côtés. styles.css est chargé après la feuille CDN : ces règles
   gagnent à spécificité égale. */
.code-card .hljs, .code-card-src code.hljs { background: transparent; color: var(--code-fg); }
.code-card .hljs-comment, .code-card .hljs-quote { color: #6b7280; font-style: italic; }
.code-card .hljs-keyword, .code-card .hljs-selector-tag, .code-card .hljs-literal,
.code-card .hljs-doctag, .code-card .hljs-formula { color: #b3319b; }
.code-card .hljs-string, .code-card .hljs-regexp, .code-card .hljs-addition,
.code-card .hljs-meta .hljs-string { color: #0a7d4e; }
.code-card .hljs-number, .code-card .hljs-symbol, .code-card .hljs-bullet,
.code-card .hljs-variable, .code-card .hljs-template-variable,
.code-card .hljs-link, .code-card .hljs-selector-attr { color: #b45309; }
.code-card .hljs-title, .code-card .hljs-title.function_, .code-card .hljs-section,
.code-card .hljs-name, .code-card .hljs-selector-id, .code-card .hljs-selector-class { color: #1d5fc4; }
.code-card .hljs-attr, .code-card .hljs-attribute, .code-card .hljs-property,
.code-card .hljs-params, .code-card .hljs-type, .code-card .hljs-built_in,
.code-card .hljs-class .hljs-title { color: #0f6f8f; }
.code-card .hljs-meta, .code-card .hljs-tag { color: #5b6472; }
.code-card .hljs-deletion { color: #b91c1c; }
.code-card .hljs-emphasis { font-style: italic; }
.code-card .hljs-strong { font-weight: 600; }

html.dark .code-card .hljs-comment,
html.dark .code-card .hljs-quote { color: #7d8590; }
html.dark .code-card .hljs-keyword, html.dark .code-card .hljs-selector-tag,
html.dark .code-card .hljs-literal, html.dark .code-card .hljs-doctag,
html.dark .code-card .hljs-formula { color: #ff7b9c; }
html.dark .code-card .hljs-string, html.dark .code-card .hljs-regexp,
html.dark .code-card .hljs-addition, html.dark .code-card .hljs-meta .hljs-string { color: #7ee0a8; }
html.dark .code-card .hljs-number, html.dark .code-card .hljs-symbol,
html.dark .code-card .hljs-bullet, html.dark .code-card .hljs-variable,
html.dark .code-card .hljs-template-variable, html.dark .code-card .hljs-link,
html.dark .code-card .hljs-selector-attr { color: #ffb86b; }
html.dark .code-card .hljs-title, html.dark .code-card .hljs-title.function_,
html.dark .code-card .hljs-section, html.dark .code-card .hljs-name,
html.dark .code-card .hljs-selector-id, html.dark .code-card .hljs-selector-class { color: #79b8ff; }
html.dark .code-card .hljs-attr, html.dark .code-card .hljs-attribute,
html.dark .code-card .hljs-property, html.dark .code-card .hljs-params,
html.dark .code-card .hljs-type, html.dark .code-card .hljs-built_in,
html.dark .code-card .hljs-class .hljs-title { color: #6fd7e0; }
html.dark .code-card .hljs-meta, html.dark .code-card .hljs-tag { color: #9aa4b2; }
html.dark .code-card .hljs-deletion { color: #ff8a8a; }
/* Les surfaces studio restent claires même en thème sombre : la palette claire
   y reste donc de mise. */
html.dark .studio-doc-surface .code-card .hljs-comment,
html.dark .studio-ai-msg .code-card .hljs-comment { color: #6b7280; }
html.dark .studio-doc-surface .code-card .hljs-keyword,
html.dark .studio-ai-msg .code-card .hljs-keyword { color: #b3319b; }
html.dark .studio-doc-surface .code-card .hljs-string,
html.dark .studio-ai-msg .code-card .hljs-string { color: #0a7d4e; }
html.dark .studio-doc-surface .code-card .hljs-title,
html.dark .studio-ai-msg .code-card .hljs-title { color: #1d5fc4; }

/* --- Textarea --- */
textarea { field-sizing:content; }
/* Empêche la textarea de collapser à 0 pendant le re-render → évite le tremblement barre saisie */
#chat-input { min-height:44px; }
#chat-input-welcome { min-height:44px; }

/* --- Input toolbar buttons --- */
.input-tool-btn {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .3rem .55rem; border-radius: var(--radius-sm);
  font-size: .72rem; font-weight: 500; cursor: pointer;
  color: var(--t-dim); background: transparent; border: none;
  transition:  all var(--duree-2) var(--courbe); white-space: nowrap; position: relative;
}
.input-tool-btn:hover { background: var(--bg-glass-hov); color: var(--t-primary); }
.input-tool-btn svg { flex-shrink: 0; }

.input-tool-toggle { border: 1px solid transparent; }
.input-tool-toggle:hover { border-color: var(--border-hov); }

.input-tool-toggle.active-web {
  background: rgba(34,197,94,.1); color: #22c55e;
  border-color: rgba(34,197,94,.25);
}
.input-tool-toggle.active-think {
  background: rgba(167,139,250,.1); color: #a78bfa;
  border-color: rgba(167,139,250,.25);
}

/* Model pill in toolbar */
.input-tool-model {
  border: 1px solid var(--border-hov);
  background: var(--bg-tertiary);
  padding: .28rem .6rem;
  gap: .4rem;
}
.input-tool-model:hover {
  border-color: var(--border-focus);
  background: var(--bg-glass-hov);
}

.input-tool-dot {
  width: 5px; height: 5px; border-radius: 50%;
  display: inline-block; margin-left: .1rem;
  animation: pulse 2s ease-in-out infinite;
}

/* --- Send button --- */
.send-btn {
  display: inline-flex; align-items: center; gap: .375rem;
  padding: .45rem .875rem; border-radius: var(--radius);
  font-size: .8125rem; font-weight: 500; cursor: pointer;
  background: linear-gradient(135deg, #4c6ef5, #5c7cfa);
  color: white; border: none;
  box-shadow: 0 2px 8px rgba(92,124,250,.3);
  transition:  all var(--duree-2) var(--courbe); white-space: nowrap;
}
.send-btn:hover { filter: brightness(1.1); box-shadow: 0 4px 16px rgba(92,124,250,.4); }
.send-btn:active { transform: scale(.96); }

.send-btn.stop-btn {
  background: rgba(239,68,68,.12);
  color: #f87171;
  box-shadow: none;
  border: 1px solid rgba(239,68,68,.2);
}
.send-btn.stop-btn:hover { background: rgba(239,68,68,.2); }

/* --- Sidebar items --- */
.sidebar-item { transition: all var(--duree-2) var(--courbe); position:relative; }
.sidebar-item:hover { background:var(--bg-glass-hov); }
.sidebar-item.active { background:var(--accent-bg); border-color:rgba(92,124,250,.15) !important; }

/* --- Dropdown --- */
.dropdown-enter { animation:scaleIn .15s cubic-bezier(.16,1,.3,1); transform-origin:top left; }

/* --- Animations intelligentes globales --- */
/* Overlay semi-transparent derrière tout dropdown ouvert */
.panel-overlay {
  position:fixed;inset:0;z-index:49;
  background:transparent;
  cursor:default;
  pointer-events:auto;
}
/* Transitions fluides sur tous les éléments interactifs */
.modenav-btn { transition: all var(--duree-2) var(--courbe); }
.modenav-btn:active { transform:scale(.95); }

/* Sidebar slide-in/out */
#sidebar { transition: transform var(--duree-2) var(--courbe); }
#sidebar-backdrop { animation:fadeIn .18s ease-out; }

/* Input toolbar — masquer scrollbar */
.input-toolbar::-webkit-scrollbar { display:none; }

/* Modal/panel : backdrop + scale-in */
.modal-backdrop { animation:fadeIn .18s ease-out; }
.modal-panel    { animation:scaleIn .2s cubic-bezier(.16,1,.3,1); }

/* Studios nav dropdown rows */
#studios-nav-drop button { transition: all var(--duree-1) var(--courbe); }
#studios-nav-drop button:active { transform:scale(.97); }

/* Chips input — pas d'overflow visible */
.input-chip { flex-shrink:0; white-space:nowrap; }

/* ============================================================
   PREMIUM FEATURES
   ============================================================ */

/* --- Command Palette --- */
.cmd-palette-backdrop {
  position:fixed; inset:0; z-index:300;
  background:rgba(0,0,0,.55); backdrop-filter:blur(8px);
  display:flex; align-items:flex-start; justify-content:center;
  padding-top:14vh;
  animation: fadeIn .15s ease-out;
}
.cmd-palette {
  width:100%; max-width:580px; margin:0 1rem;
  border-radius:var(--radius-xl); overflow:hidden;
  background:var(--bg-secondary); border:1px solid var(--border-hov);
  box-shadow:0 32px 80px rgba(0,0,0,.5), 0 0 0 1px rgba(92,124,250,.08);
  animation: scaleIn .18s cubic-bezier(.16,1,.3,1);
}
html.light .cmd-palette { box-shadow: var(--ombre-5); }
.cmd-input-wrap {
  display:flex; align-items:center; gap:.75rem;
  padding:.875rem 1.125rem; border-bottom:1px solid var(--border);
}
.cmd-input {
  flex:1; background:transparent; border:none; outline:none;
  font-size:1rem; color:var(--t-primary); font-family:inherit;
}
.cmd-input::placeholder { color:var(--t-faint); }
.cmd-results { max-height:380px; overflow-y:auto; padding:.375rem; }
.cmd-group-label {
  padding:.375rem .75rem .25rem; font-size:.65rem; font-weight:600;
  text-transform:uppercase; letter-spacing:.08em; color:var(--t-dim);
}
.cmd-item {
  display:flex; align-items:center; gap:.75rem; padding:.6rem .875rem;
  border-radius:var(--radius-sm); cursor:pointer; transition: all var(--duree-1) var(--courbe);
  color:var(--t-secondary);
}
.cmd-item:hover, .cmd-item.active {
  background:var(--accent-bg); color:var(--t-primary);
}
.cmd-item .cmd-icon { width:1.75rem; height:1.75rem; border-radius: var(--radius-sm); display:flex; align-items:center; justify-content:center; background:var(--bg-tertiary); flex-shrink:0; font-size:.875rem; }
.cmd-item .cmd-label { flex:1; font-size:.875rem; }
.cmd-item .cmd-hint { font-size:.7rem; color:var(--t-dim); font-family:'JetBrains Mono',monospace; }
.cmd-empty { padding:2.5rem 1rem; text-align:center; color:var(--t-dim); font-size:.875rem; }

/* --- Context Menu --- */
.ctx-menu {
  position:fixed; z-index:400; min-width:180px;
  background:var(--bg-secondary); border:1px solid var(--border-hov);
  border-radius:var(--radius); padding:.3rem;
  box-shadow: var(--ombre-3);
  animation: scaleIn .12s cubic-bezier(.16,1,.3,1);
}
html.light .ctx-menu { box-shadow: var(--ombre-3); }
.ctx-item {
  display:flex; align-items:center; gap:.625rem; padding:.45rem .75rem;
  border-radius: var(--radius-sm); cursor:pointer; font-size:.8125rem; color:var(--t-secondary);
  transition: all var(--duree-1) var(--courbe); white-space:nowrap;
}
.ctx-item:hover { background:var(--accent-bg); color:var(--t-primary); }
.ctx-item.danger:hover { background:rgba(239,68,68,.1); color:var(--danger); }
.ctx-separator { height:1px; background:var(--border); margin:.25rem 0; }

/* --- Slash command autocomplete menu --- */
.slash-item { transition: background var(--duree-1) var(--courbe); }
.slash-item.slash-active, .slash-item:hover { background:var(--accent-bg); }
#slash-menu { animation:fadeInUp .12s ease; }
@keyframes fadeInUp { from { opacity:0; transform:translateY(4px) } to { opacity:1; transform:translateY(0) } }

/* LE TITRE DE LA CONVERSATION, EN TÊTE DU FIL — pas dans l'en-tête.
   Une ligne sobre, alignée sur la colonne, qui défile avec la conversation :
   elle ne prend aucune hauteur permanente à l'écran. Le chevron ouvre la liste
   des sessions de même nature (chat ou Work) ; il ne se colore qu'au survol,
   pour ne pas attirer l'œil plus que le titre lui-même. */
.conv-titre-fil {
  /* L'ÉCART, PAS LE COLLAGE. « Tu as trop collé l'icône qui signale le cloud ou
     l'ordinateur avec le titre. » Quatre pixels serraient l'icône contre la
     première lettre ; on passe à l'espace suivant de l'échelle, et le chevron
     de fin garde le sien — d'où un écart posé par ÉLÉMENT plutôt qu'un `gap`
     unique, qui aurait écarté les trois pareil. */
  display: inline-flex; align-items: center; gap: var(--espace-3);
  /* LA LARGEUR DÉPEND DE QUI PARTAGE LA RANGÉE.
     Dans l'application de bureau, les onglets montent dans la barre de fenêtre :
     cette rangée-ci ne porte que les icônes de gauche et les actions de droite,
     et le titre peut respirer. C'est le cas par défaut. */
  max-width: min(38vw, 460px); min-width: 0; padding: var(--espace-2) var(--espace-3);
  border-radius: var(--radius-sm); background: transparent; border: 0;
  cursor: pointer; text-align: left;
  transition: background var(--duree-2) var(--courbe);
}
.conv-titre-fil:hover { background: var(--bg-secondary); }
/* Sans barre de fenêtre (navigateur), le bandeau d'onglets retombe dans cette
   rangée. Il est en position absolue d'un bord à l'autre et ignore les groupes
   latéraux : un titre trop long passerait DESSOUS.
   La place libre a été MESURÉE dans l'application, barre latérale ouverte (le
   cas le plus serré) : 55 px à 1024, 183 à 1280, 343 à 1600 — soit la moitié de
   la largeur moins 457. On borne là-dessus, avec treize pixels de marge. */
.conv-titre-fil--serre { max-width: min(calc(50vw - 470px), 200px); }
/* En dessous de 1400 px, la place qui reste avant le bandeau tombe sous deux
   cent trente pixels : le titre y est coupé au tiers et vient toucher l'onglet
   « Réponse ». Un titre illisible collé à un onglet est pire que pas de titre —
   il reste dans la barre latérale et dans l'onglet du navigateur. Ce seuil ne
   concerne QUE le cas sans barre de fenêtre ; dans l'application de bureau, la
   rangée est libre et le titre s'affiche toujours. */
@media (max-width: 1399px) { .conv-titre-fil--serre { display: none; } }
.conv-titre-fil-nom {
  /* 15 px, pas 17 : le titre partage une rangée de 44 px avec les icônes. Plus
     gros, il la ferait grandir — et une rangée qui grandit, c'est le bandeau
     qu'on avait retiré. */
  font-size: max(0.9375rem, 15px); font-weight: 600; color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.conv-titre-fil-chev {
  flex: none; color: var(--t-faint); margin-left: calc(var(--espace-1) * -1);
  /* Il dit l'état du panneau qu'il ouvre, comme celui des studios. */
  transition: transform var(--duree-2) var(--courbe);
}
.conv-titre-fil-chev.est-ouvert { transform: rotate(180deg); }

/* --- Inline title edit --- */
.conv-title-input {
  background:var(--accent-bg); border:1px solid var(--border-focus);
  border-radius: var(--radius-sm); padding:.1rem .4rem; font-size:.875rem;
  color:var(--t-primary); outline:none; width:100%;
}

/* --- Token counter --- */
.token-counter {
  display:inline-flex; align-items:center; gap:.375rem;
  padding:.2rem .5rem; border-radius: var(--radius-rond); font-size:.65rem;
  font-family:'JetBrains Mono',monospace;
  background:var(--bg-tertiary); border:1px solid var(--border);
  color:var(--t-dim); transition: all var(--duree-3) var(--courbe);
}
.token-counter.warn { border-color:rgba(245,158,11,.3); color:var(--warn); background:rgba(245,158,11,.05); }
.token-counter.crit { border-color:rgba(239,68,68,.3); color:var(--danger); background:rgba(239,68,68,.05); }

/* --- Conversation search (Ctrl+F) --- */
.conv-search-bar {
  position:absolute; top:0; right:0; z-index:20;
  display:flex; align-items:center; gap:.5rem;
  padding:.5rem .75rem; border-radius:0 0 0 var(--radius);
  background:var(--bg-secondary); border:1px solid var(--border-hov);
  border-top:none; border-right:none;
  animation: slideDown .2s ease-out;
  box-shadow: var(--ombre-2);
}
.conv-search-input {
  background:transparent; border:none; outline:none;
  font-size:.8125rem; color:var(--t-primary); width:180px;
}
.conv-search-input::placeholder { color:var(--t-dim); }
.search-highlight { background:rgba(245,158,11,.3); border-radius: var(--radius-xs); padding:0 var(--espace-1); }
.search-highlight.current { background:rgba(245,158,11,.6); }

/* --- Status bar supprimée — renderStatusBar() retourne '' ---
   Le .status-bar CSS est conservé vide pour éviter les erreurs si
   l'élément existe encore dans un cache SW ancien. */
.status-bar { display:none!important; }
.status-dot  { display:none!important; }

/* Indicateur offline discret : petit point rouge sur le logo CREA dans le rail */
html.crea-offline #btn-user-rail::after,
html.crea-offline [data-rail="logo"]::after {
  content:'';
  position:absolute; top:2px; right:2px;
  width:7px; height:7px; border-radius:50%;
  background:#ef4444;
  box-shadow:0 0 0 2px var(--bg-secondary);
  animation:pulse 1.5s ease-in-out infinite;
}
html.crea-offline #btn-user-rail { position:relative; }
html.crea-offline [data-rail="logo"] { position:relative; }

/* --- Skeleton loaders --- */
.skeleton {
  background:linear-gradient(90deg, var(--bg-tertiary) 25%, var(--bg-secondary) 50%, var(--bg-tertiary) 75%);
  background-size:200% 100%;
  animation: shimmer 1.4s ease-in-out infinite; border-radius:var(--radius-sm);
}

/* --- Premium message bubbles --- */
/* Bulle user — gris clair comme ChatGPT */
.msg-user-bubble {
  background: var(--msg-user-bg);
  border:1px solid var(--border);
  /* TOTALEMENT ARRONDIE. Elle portait trois coins à 16 px et un quatrième à 8 —
     un angle plus dur que les autres, qui se lit comme un défaut plutôt que
     comme une intention. Le même rayon partout, et celui de la barre de saisie :
     ce qu'on écrit et ce qu'on a envoyé ont la même forme. */
  border-radius: var(--radius-xl);
}
html.dark .msg-user-bubble {
  background: var(--bg-secondary);
  border-color: var(--border);
}
.msg-ai-container { position:relative; }

/* --- Message timestamp --- */
.msg-ts { font-size:.6rem; color:var(--t-faint); opacity:0; transition: opacity var(--duree-2) var(--courbe); margin-top:.25rem; }
.msg-ts.visible { opacity:1; }

/* --- File chips --- */
.file-chip {
  display:inline-flex; align-items:center; gap:.375rem; padding:.25rem .6rem;
  border-radius: var(--radius-sm); background:var(--accent-bg); border:1px solid rgba(92,124,250,.15);
  font-size:.72rem; color:var(--accent-l); transition: all var(--duree-2) var(--courbe);
}
.file-chip:hover { border-color:var(--accent); }

/* --- LES PIÈCES JOINTES ONT TOUTES LA MÊME GRAMMAIRE ---------------------
   Trois choses partaient dans le même message et s'affichaient de trois façons
   différentes : un gros collé en carte, une image en vignette nue, un fichier en
   petite puce. Trois traitements pour un même geste — « j'ajoute quelque chose à
   mon message » — et rien ne les reliait à l'œil.
   Même largeur, même hauteur, même rayon, même badge : ce qui change d'une carte
   à l'autre, c'est ce qu'elles montrent, pas comment elles sont faites. */
.piece-carte {
  width:132px; min-width:132px; height:92px;
  border-radius: var(--radius); background:var(--bg-secondary); border:1px solid var(--border);
  position:relative; overflow:hidden; cursor:pointer;
  transition:border-color .15s ease, transform .12s ease;
}
.piece-carte:hover { border-color:var(--accent); transform:translateY(-1px); }
/* L'image occupe toute la carte ; son nom repose sur un voile, lisible quel que
   soit le cliché — un texte blanc sur une photo claire ne se lit pas. */
.piece-carte-image img { width:100%; height:100%; object-fit:cover; display:block; }
.piece-carte-nom {
  position:absolute; left:0; right:0; bottom:0; padding:var(--espace-7) var(--espace-4) var(--espace-3);
  font-size:var(--texte-1); line-height:1.2; color:#fff; text-align:left;
  background:linear-gradient(to top, rgba(0,0,0,.72), rgba(0,0,0,0));
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* Un fichier n'a rien à montrer : on montre donc ce qu'on sait de lui —
   son extension en grand, son nom, son poids. */
.piece-carte-fichier { display:flex; flex-direction:column; justify-content:space-between; padding:var(--espace-4) var(--espace-5); }
.piece-carte-ext {
  font-size:var(--texte-9); font-weight:700; letter-spacing:.02em; color:var(--t-faint);
  text-transform:uppercase; line-height:1;
}
.piece-carte-meta { font-size:var(--texte-1); color:var(--t-dim); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* AVANT D'ENVOYER, ON PEUT ENCORE RETIRER — c'est la seule différence entre la
   carte du composeur et celle du message. Elle est donc un détail de la même
   carte, et non une seconde carte.

   Fond opaque, et non une simple opacité : posée sur une photo claire, une croix
   translucide devient invisible — exactement le défaut qu'on vient de corriger
   sur le nom du fichier. Elle reste visible en permanence : sur écran tactile il
   n'y a pas de survol, et une croix qui n'apparaît qu'au survol n'existe pas. */
.piece-carte-retirer {
  position:absolute; top:5px; right:5px; z-index:2;
  width:20px; height:20px; display:flex; align-items:center; justify-content:center;
  border-radius:50%; border:none; cursor:pointer; padding:0;
  background:rgba(0,0,0,.62); color:#fff; line-height:0;
  transition: background-color var(--duree-2) var(--courbe);
}
.piece-carte-retirer:hover { background:rgba(220,38,38,.92); }
.piece-carte-badge {
  align-self:flex-start; font-size:var(--texte-1); font-weight:600; letter-spacing:.02em;
  padding:var(--espace-1) var(--espace-4); border-radius: var(--radius-rond); border:1px solid var(--border); color:var(--t-faint);
  background:var(--bg-primary);
}

/* --- Carte "collé" (gros copier-coller) : aperçu + badge, cliquable → visionneuse --- */
.paste-card {
  /* Mêmes dimensions et même rayon que .piece-carte : c'est ce qui fait que les
     trois pièces jointes se lisent comme une même rangée, et non comme trois
     objets sans rapport. Les valeurs sont répétées plutôt que factorisées pour
     ne rien changer à l'apparence existante en le faisant. */
  width:132px; min-width:132px; height:92px; padding:var(--espace-4) var(--espace-5);
  border-radius: var(--radius); background:var(--bg-secondary); border:1px solid var(--border);
  display:flex; flex-direction:column; justify-content:space-between;
  cursor:pointer; position:relative; overflow:hidden; transition:border-color .15s ease, transform .12s ease;
}
.paste-card:hover { transform:translateY(-1px); }
.paste-card:hover { border-color:var(--accent); }
.paste-card-preview {
  font-size:var(--texte-1); line-height:1.35; color:var(--t-dim);
  display:-webkit-box; -webkit-line-clamp:4; -webkit-box-orient:vertical; overflow:hidden;
}
.paste-card-badge {
  align-self:flex-start; font-size:var(--texte-1); font-weight:600; letter-spacing:.02em;
  padding:var(--espace-1) var(--espace-4); border-radius: var(--radius-rond); border:1px solid var(--border); color:var(--t-faint);
}
.paste-card-remove {
  position:absolute; top:4px; right:4px; width:18px; height:18px; border-radius: var(--radius-rond);
  display:flex; align-items:center; justify-content:center; background:var(--bg-primary); opacity:.7;
}
.paste-card-remove:hover { opacity:1; }

/* --- Visionneuse "Contenu collé" (plein écran) --- */
#pasted-content-modal .pcm-actbtn { display:flex; flex-direction:column; align-items:center; gap:var(--espace-1); padding:var(--espace-3) var(--espace-5); border-radius: var(--radius); font-size:var(--texte-1); color:var(--t-secondary); }
#pasted-content-modal .pcm-actbtn:hover { background:rgba(0,0,0,.05); }
#pasted-content-modal .pcm-actbtn svg { width:15px; height:15px; }

/* ── LES ONGLETS DE LA BARRE DE FENÊTRE SUIVENT LA COLONNE ──────────────
   Sur le web, l'en-tête a déjà la géométrie de la colonne : .app-header-centre
   n'a rien à calculer (voir juste en dessous). Sur la coquille de bureau, les
   onglets montent dans la barre de fenêtre, qui est posée AU-DESSUS de la mise
   en page et ne connaît donc ni la barre latérale ni la colonne.

   Il ne lui manque qu'un chiffre : la largeur de la barre latérale. On le lui
   donne par la variable que l'aside utilise lui-même — pas par une mesure. Une
   mesure d'une boîte en train de bouger rend une position intermédiaire :
   relevé 234 px d'écart, cent millisecondes après l'ouverture. C'est ce que
   l'usager voyait « bouger bizarre ».

   La borne à 769 px n'est pas décorative : en dessous, la barre se pose PAR-
   DESSUS la colonne (position:fixed) au lieu de la pousser. Décaler les onglets
   là les enverrait sous les boutons de fenêtre. Même frontière que
   isMobileSidebarLayout() dans src/app.js. */
#tb-onglets { transform: translateX(-50%); }
@media (min-width: 769px) {
  /* ── ON SUIT CE QUI POUSSE, PAS CE QUI EST POSÉ ────────────────────────
     « Dès que je clique, il se décale. Son centre doit être le centre de la
      barre de questions. »
     La règle lisait `[data-barre-laterale="ouverte"]` et décalait de
     --crea-sb-largeur/2. Trois choses lui échappaient, toutes mesurées en
     navigateur réel : la carte FLOTTANTE ne pousse rien (132 px d'écart au
     premier clic), la carte ANCRÉE est détachée de --carte-marge des deux
     côtés (10 px), et le rail Créative ne fait que 84 px (80 px).
     --crea-barre-poussee dit l'emprise réelle, publiée par le rendu depuis
     l'état — jamais depuis une mesure. Zéro quand rien ne pousse : la règle
     retombe alors d'elle-même sur le centrage fenêtre, sans branche. */
  html[data-barre-laterale="ouverte"] #tb-onglets {
    transform: translateX(calc(-50% + var(--crea-barre-poussee, 0px) / 2));
  }

  /* ── ET ILS VOYAGENT COMME LE CONTENU, PAS COMME EUX-MÊMES ─────────────
     Une simple transition ne suffisait pas, et la mesure l'a montré : le
     contenu ne va PAS d'une position à l'autre. Il est mis en place large de
     sa taille finale dès la première image, puis glisse depuis la gauche
     (creaMainShiftIn) — donc son centre part de 588, saute 132 px à gauche de
     là où il était, et parcourt 264. Les onglets, eux, n'avaient que 132 à
     faire : avec la même durée ils prenaient de l'avance et se retrouvaient à
     130 px devant la barre de questions au milieu du geste.
     Ils rejouent donc le MÊME trajet, à partir des MÊMES keyframes de largeur :
     départ à une largeur de barre du point d'arrivée, comme le contenu.
     Le geste est publié pour un seul rendu (data-barre-laterale-geste), sinon
     l'animation repartirait à chaque repeinture de la barre de fenêtre. */
  /* Le trajet part de l'emprise QUI S'ACHÈVE : à la fermeture, la poussée
     courante vaut déjà zéro, et une sortie partant de zéro ne bougerait pas. */
  @keyframes creaOngletsEntree {
    from { transform: translateX(calc(-50% - var(--crea-barre-poussee-geste, 0px) / 2)); }
  }
  @keyframes creaOngletsSortie {
    from { transform: translateX(calc(-50% + var(--crea-barre-poussee-geste, 0px))); }
  }
  html[data-barre-laterale-geste="entree"] #tb-onglets {
    animation: creaOngletsEntree var(--crea-sb-duree) var(--crea-sb-courbe);
  }
  html[data-barre-laterale-geste="sortie"] #tb-onglets {
    animation: creaOngletsSortie var(--crea-sb-duree) var(--crea-sb-courbe);
  }
}

/* LE TITRE DU CHAT — SUPPRIMÉ.
   « Supprime le titre des chats, c'est bon, je n'en veux plus. »
   .crea-titre-chat, ses deux règles de hauteur d'en-tête et l'empilement qui
   les portait sont partis avec lui. Une classe orpheline finit toujours par
   être rebranchée « puisqu'elle est là ». Voir retire/README.md. */

/* ── L'ACCUEIL : DEUX PHRASES, ET LA PREMIÈRE EST GRANDE ───────────────────
   « Et être plus grand, vraiment plus grand. »

   Le salut était en 20 px et la proposition en 16 — deux lignes moyennes qui se
   partageaient l'attention sans qu'aucune ne la prenne. Fusionnées, elles n'ont
   plus à se départager : une seule phrase, à la taille de ce qu'elle est —
   la première chose qu'on lit en ouvrant CREA.

   Elle grandit avec l'écran (clamp) au lieu de sauter à un palier : sur un
   téléphone elle reste lisible, sur un grand écran elle tient son rang.

   C'est un BOUTON, parce qu'elle invite : le survol le dit, sans lui donner
   l'apparence d'une commande — une phrase soulignée d'un trait au survol, pas
   une pastille. */
.crea-phrase-accueil {
  /* Le logo ouvre la phrase, et la phrase est CENTRÉE SUR SON MILIEU.
     Posée sur la ligne de base, elle était décalée vers le bas du signe ; c'est
     le milieu du logo qui doit rencontrer le milieu du mot. */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--espace-5);
  max-width: min(96%, 40ch);
  margin: 0 auto;
  /* UNE LIGNE, jamais deux. La longueur est déjà bornée à la composition
     (phraseAccueil) ; ceci est la seconde barrière, pour les noms très longs
     et les langues qui s'étalent. */
  white-space: nowrap;
  padding: 0;
  border: none;
  background: none;
  text-align: center;
  /* « C'est trop grand, réduis vraiment un peu — mais pas petit comme avant. »
     Elle sortait à 36 px en 1440 et prenait trois lignes. Elle redescend à 28,
     ce qui reste très au-dessus des 20 px d'où elle vient. */
  font-size: clamp(1.35rem, 1.05rem + 0.95vw, 1.75rem);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -0.01em;
  color: var(--t-primary);
  cursor: pointer;
  transition: color var(--duree-2) var(--courbe);
}
.crea-phrase-accueil:hover { color: var(--accent); }
/* Le logo ne grandit pas avec la phrase : il l'accompagne. Aligné sur la ligne
   de base du premier mot, il se lit comme une initiale, pas comme une icône
   posée à côté. */
.crea-phrase-logo {
  /* 1em rendait le logo minuscule : l'atome occupe tout son viewBox, mais ses
     trois ellipses sont fines et l'œil ne voit qu'un point. 1,5em puis 2em
     restaient petits à côté de la référence. 2,6em : nettement plus grand que
     la ligne qu'il ouvre, sans repasser dans l'excès d'où l'on vient. */
  width: 2.6em; height: 2.6em; flex: none;
  align-self: center;
}

/* La seconde ligne porte plus loin que la journée : elle reste discrète, et
   elle change toutes les quinze secondes. Le fondu est court — assez pour que
   le changement se remarque, trop court pour qu'on l'attende. */
.crea-sagesse-accueil {
  margin-top: var(--espace-7);
  max-width: 96%;
  /* « Le texte de la Bible vaut plus que le texte du haut, même s'il est affiché
     plus grand — donc donne-lui de la taille. Et il était bien en vert. »
     Elle était à 13 px : discrète au point d'être illisible. Elle monte à 17 et
     reprend l'accent. Ce n'est pas une note de bas de page — c'est la ligne
     dont il dit qu'elle pèse le plus lourd des deux. */
  /* UNE SEULE LIGNE, elle aussi. Une parole coupée en deux se lit comme deux
     morceaux ; d'un trait, elle se lit comme une phrase. Les entrées sont
     bornées en longueur à la source (VERSES et SAGESSES). */
  white-space: nowrap;
  font-size: clamp(0.95rem, 0.88rem + 0.22vw, 1.0625rem);
  font-style: italic;
  line-height: 1.55;
  color: var(--accent);
  /* PAS de `text-wrap: balance` ici. Il est plus récent que `white-space` et le
     ré-autorise à couper : la parole repartait sur deux lignes malgré le
     nowrap, et rien ne le disait. Encore deux déclarations pour une seule
     décision, et c'est la dernière qui gagnait. */
  transition: opacity var(--duree-2) var(--courbe);
}
.crea-sagesse-accueil.crea-sagesse-change { opacity: 0; }

.app-header-centre {
  /* D'UN BORD À L'AUTRE DE L'EN-TÊTE, ET CENTRÉ DEDANS.
     L'en-tête a déjà la géométrie de la colonne de conversation — mesuré :
     centre 852 barre ouverte, 720 barre fermée, identique à la conversation
     dans les deux cas. Il n'y a donc rien à calculer : il suffit que le centre
     s'étende sur toute la largeur au lieu de recevoir « ce qui reste » de la
     grille. Aucune mesure, aucun observateur, aucun retard. */
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  /* LA SOURIS PASSE À TRAVERS LE BANDEAU, PAS À TRAVERS SES BOUTONS. Sans ça,
     une bande invisible couvrirait toute la largeur et avalerait les clics des
     commandes de gauche et de droite. */
  pointer-events: none;
}
.app-header-centre > * { pointer-events: auto; }

/* --- Toast : SUPPRIMÉ ---
   Le nœud flottant passait devant la barre de saisie et emportait son message
   au bout de 3,2 secondes. Tout arrive maintenant au centre de signal, sous la
   cloche : un seul organe, un historique, un badge de non-lus. Voir showToast
   dans src/app.js. La règle du dépôt : retiré de l'affichage n'est pas
   supprimé — donc la règle part avec la fonction. */

/* --- KBD --- */
.kbd {
  display:inline-block; padding:.1rem .4rem; border-radius: var(--radius-xs);
  background:var(--bg-tertiary); border:1px solid var(--border-hov);
  font-size:.625rem; font-family:'JetBrains Mono',monospace; color:var(--t-dim);
  line-height:1.5; letter-spacing:.03em;
}

/* --- Badges --- */
.badge {
  display:inline-flex; align-items:center; gap:.25rem; padding:.1rem .5rem;
  border-radius: var(--radius-rond); font-size:.65rem; font-weight:500;
}
.badge-web    { background:rgba(34,197,94,.1); border:1px solid rgba(34,197,94,.2); color:#22c55e; }
.badge-think  { background:rgba(167,139,250,.1); border:1px solid rgba(167,139,250,.2); color:#a78bfa; }
.badge-folder { font-size:.6rem; font-weight:600; text-transform:uppercase; letter-spacing:.05em; }

/* ══════════════════════════════════════════════════════════════════════════
   LA TABLETTE DROITE, D'APRÈS LA RÉFÉRENCE — ET CE QUI AVAIT ÉTÉ MAL LU

   Artefact, Aperçu, Outils, Suivi CREA, Travail arrière-plan, Suivi de tâche
   et Fichiers partagent la rangée de droite (RIGHT_TRAY_PANELS dans app.js).

   La référence, capture à l'appui : une carte DÉTACHÉE des quatre bords par un
   petit écart, coins arrondis DISCRETS sur les quatre coins, un filet d'un
   pixel pour tout contour, AUCUNE ombre, et pas un seul trait à l'intérieur —
   le titre se pose en haut, petit, et le contenu suit.

   Ce qui avait été mal lu, et qui compte pour ne pas y revenir :

   « En haut on voit les zones, ça fait comme un bloc de noir en haut et en
    bas. » Ce n'était PAS l'écart : c'était l'OMBRE. Une ombre portée peint le
   fond juste autour de la carte, donc précisément la bande que l'écart laisse
   voir — et une bande peinte en sombre ne se lit pas comme un espace, elle se
   lit comme un objet noir. Retirer l'écart était la mauvaise réponse (la
   version d'après collait la carte aux bords et perdait la référence) ; la
   bonne est de retirer l'ombre et de garder l'écart. Sans ombre, la bande
   reprend le fond de la rangée, qui ne s'écarte que de quelques niveaux du
   fond de la carte : on lit un objet posé, pas un cadre noir.

   « Des petits arrondis tranquilles, alors que toi tu as fait des gros
    arrondis. » --radius-xl (20 px) était deux fois trop. --radius (12 px) est
   l'échelon « carte » du système, et c'est ce que montre la référence.

   « Arrête de mettre des traits partout. » Voir plus bas, § 10 bis : les
   séparations internes passent en transparent.

   « Les ombres que tu as mises autour, ça fait trop — regarde la barre de
    questions, c'est léger, ça donne l'impression qu'elle est impactante. »
   Ce qui faisait « trop » n'était même pas une ombre : c'était une BANDE.
   L'écart de 10 px laissait voir le fond de la rangée (--bg-secondary) autour
   d'une carte en --bg-primary — soit un cadre plein, de couleur franche, sur
   les quatre côtés. Un cadre plein pèse toujours plus qu'une ombre, parce
   qu'il ne se dégrade pas : il commence et il s'arrête.
   La bande reprend donc le fond de la carte (le conteneur est peint), et
   l'élévation revient sous la forme exacte de la barre de questions —
   --ombre-2, voir .composer-enveloppe dans app.js. Même filet, même ombre,
   même famille d'objet.

   Tout ceci NE s'applique QUE sur desktop, parce que la classe n'est posée que
   là (voir chaque render...Panel()) : sous 769 px, chaque panneau bascule en
   plein écran (position:fixed;inset:0), où un écart et un arrondi ne
   dessineraient que des encoches sur le bord de l'écran.

   Le !important n'est pas un raccourci — chaque panneau écrit son fond et son
   border-left en style en ligne dans son propre render(), et rien d'autre
   qu'un !important ne passe devant.
   ═══════════════════════════════════════════════════════════════════════ */
.crea-panneau-carte,
.crea-panneau-carte--seule {
  border: 1px solid var(--border) !important;
  border-radius: var(--radius);
  box-shadow: var(--ombre-2);
  background: var(--bg-primary) !important;
  overflow: hidden;
}

/* L'écart est porté par le CONTENEUR (padding + gap), pas par les cartes : posé
   sur chacune, il doublerait entre deux panneaux ouverts côte à côte, et il n'y
   a qu'ici qu'on sait lequel est le dernier de la rangée. */
.crea-tiroir-cartes {
  /* PEINT, et c'est tout le sujet : sans ça, l'écart montre --bg-secondary de
     .crea-plan-travail, ce qui fabrique un cadre plein autour de chaque carte.
     Au même fond que les cartes, il ne reste que le filet et l'ombre. */
  background: var(--bg-primary);
  /* En HAUT, l'écart n'est pas le même qu'ailleurs, et ce n'est pas un oubli.
     « Monte-la au même niveau que le bloc des boutons. » La tablette est la
     SŒUR de la colonne principale dans .crea-plan-travail : elles démarrent
     toutes deux au même y. Ce qui décalait le panneau vers le bas, c'était les
     10 px d'écart, appliqués aussi en haut.
     La valeur juste n'est donc pas zéro mais --espace-2 (4 px) : c'est
     exactement le `py-1` de #app-header (src/app.js), donc la distance entre
     le haut de la rangée et le haut du bloc des boutons. Le panneau démarre au
     même y qu'eux. Si le rembourrage de l'en-tête change un jour, celui-ci
     doit suivre — c'est la même mesure, pas une coïncidence. */
  padding: var(--espace-2) var(--carte-marge) var(--carte-marge);
  gap: var(--carte-marge);
  align-items: stretch;
  /* SANS CECI, LE TIROIR NE PEUT PAS RÉTRÉCIR, ET C'EST LUI QUI POUSSAIT LA
     CROIX DE FERMETURE HORS DE L'ÉCRAN.

     « Le navigateur est mal structuré au niveau de l'agrandissement : la croix
      de fermeture disparaît derrière la ligne d'encadrement de l'app. »

     Un élément flex a `min-width: auto` par défaut : il refuse de descendre
     sous la taille de son contenu. Quand « Développer » demandait un panneau
     large de toute la fenêtre, le tiroir prenait cette largeur À SON TOUR et
     débordait de la rangée — en emportant le coin haut-droit du panneau, où
     vit la croix.

     Mesuré, fenêtre de 1440 : le panneau commençait à x=274 (après la barre
     latérale), finissait à 1714, et la croix se retrouvait à 265 px hors écran.
     Avec min-width:0, le tiroir rend la place qu'il n'a pas : panneau ramené à
     1156, bord droit à 1430, croix à 19 px À L'INTÉRIEUR du bord.

     Le panneau porte le reste de la réponse (max-width:100%, flex-shrink:1,
     voir renderPreview) : les deux vont ensemble, l'un sans l'autre ne corrige
     rien — vérifié en les retirant tour à tour. */
  min-width: 0;
}

/* Ceux qui se posent seuls dans une rangée (Contexte vivant, Journal vivant,
   Fichiers du chat) n'ont pas de conteneur pour eux : ils portent leur écart.
   Pas de hauteur : ce sont des éléments flex, étirés par leur rangée. Leur
   ajouter height:100 % EN PLUS de la marge les ferait dépasser du bas
   d'exactement deux écarts. */
.crea-panneau-carte--seule {
  /* LES QUATRE CÔTÉS, ET LE CÔTÉ CHAT EST LE PLUS IMPORTANT DES QUATRE.
     La marge de gauche était à zéro : ces panneaux touchaient le plan de
     travail, et le filet du bord gauche — seul pixel entre les deux — se
     lisait comme l'ancienne ligne de séparation, celle qu'on cherchait
     justement à supprimer. « Tu les as quand même laissés liés à l'espace
     chat, du coup ça donne un rendu moche. »
     Même écart partout, comme le tiroir juste au-dessus. Le haut garde
     --espace-2 pour la même raison que lui : c'est le py-1 de #app-header. */
  margin: var(--espace-2) var(--carte-marge) var(--carte-marge) var(--carte-marge);
}
@media (max-width: 768px) {
  .crea-panneau-carte--seule { margin: 0; border-radius: 0; }
}

/* La poignée de redimensionnement de l'Aperçu déborde de 4 px à gauche
   (left:-4px) pour être attrapable des deux côtés du trait. Il n'y a plus de
   trait, et overflow:hidden lui coupait la moitié qui dépasse : elle rentre
   dans le panneau et suit sa courbe. */
.crea-panneau-carte .preview-resize-handle {
  left: 0;
  border-radius: var(--radius) 0 0 var(--radius);
}

/* --- Artifacts panel --- */
/* Le border-left ne sert plus qu'au plein écran mobile et au mode plein écran,
   qui ne portent pas la classe carte ; ailleurs .crea-panneau-carte repasse
   devant avec sa bordure complète. */
.artifacts-panel { animation:slideRight .28s cubic-bezier(.16,1,.3,1); border-left:1px solid var(--border); }
/* ── LE SÉLECTEUR APERÇU / CODE DE L'ARTEFACT ────────────────────────────────
   « Il a même trois onglets — Aperçu / Code / Split. Il faut le supprimer
    définitivement, on va en créer un nouveau. »

   La rangée d'onglets (.artifact-tab) prenait une ligne entière de hauteur pour
   deux états, et donnait à Split le rang d'un onglet alors que c'est une
   DISPOSITION, pas un contenu. Elle est remplacée par un segment compact posé
   dans l'en-tête, à deux états — la forme qu'a Claude, et celle que le reste de
   CREA emploie déjà pour dire « choisi » (fond --accent-bg, texte lisible).

   Le creux du segment porte --bg-secondary : sans lui, deux boutons côte à côte
   sur le fond du panneau ne se lisent pas comme UN choix entre deux, mais comme
   deux boutons indépendants. */
.art-seg {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  margin-right: var(--espace-3);
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  border: 1px solid var(--border);
}
.art-seg-btn {
  padding: .22rem .6rem;
  border: 0;
  border-radius: var(--radius-xs);
  background: transparent;
  color: var(--t-dim);
  font-size: .72rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe);
}
/* La bascule œil / chevrons : deux icônes, pas deux mots — c'est la forme
   relevée sur le panneau de Claude. Une icône seule a besoin d'être carrée,
   sinon elle flotte dans un bouton taillé pour du texte. */
.art-seg-btn--icone {
  padding-left: var(--espace-4); padding-right: var(--espace-4);
  display: inline-flex; align-items: center; justify-content: center;
}

/* « Copier » et son menu. L'hôte est positionné pour que le menu s'ancre sous
   la flèche ; sans lui, le menu se poserait par rapport au panneau entier et
   atterrirait n'importe où. */
.art-menu-hote { position: relative; display: inline-flex; flex-shrink: 0; }
.art-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  min-width: 216px; padding: var(--espace-2);
  background: var(--bg-primary); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--ombre-4);
}

/* La bascule œil / code et les commandes de fenêtre : des icônes NUES, sans
   cadre qui les entoure. « Ils ont pas de carré qui les entoure. » Un survol
   discret, l'active teintée à l'accent — rien de plus. */
.art-icone-nue {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--radius-sm);
  color: var(--t-secondary); flex-shrink: 0;
  transition: background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe);
}
.art-icone-nue:hover { background: var(--bg-secondary); color: var(--t-primary); }
.art-icone-nue.active { color: var(--accent); background: var(--accent-bg); }

/* « Copier » : un seul bouton propre, texte + chevron, pas un segment encadré.
   C'est la commande principale — elle se voit, elle ne s'entoure pas. */
.art-copier-btn {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  height: 30px; padding: 0 var(--espace-4); border-radius: var(--radius-sm);
  font-size: var(--texte-2); font-weight: 500; color: var(--t-secondary);
  transition: background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe);
}
.art-copier-btn:hover, .art-copier-btn.active { background: var(--bg-secondary); color: var(--t-primary); }

.art-seg-btn:hover { color: var(--t-primary); }
.art-seg-btn.active { background: var(--accent-bg); color: var(--accent-texte); font-weight: 600; }
.art-tool-btn { display:inline-flex; align-items:center; justify-content:center; width:30px; height:30px; border-radius: var(--radius-sm); color:var(--t-dim); cursor:pointer; transition: all var(--duree-2) var(--courbe); background:transparent; border:0; }
.art-tool-btn:hover { color:var(--t-primary); background:var(--bg-glass-hov); }

/* --- Navigateur réel (rbrowser) — Preview/onglet Web ET Simplifica, même composant --- */
.rbrowser { background:var(--bg-primary); position:relative; }
/* 26px de côté tombait bien en dessous des ~44px recommandés pour un public non technique/
   âgé — relevé à 34px (compromis avec la densité de la barre d'outils, qui compte plusieurs
   boutons côte à côte). */
.rbrowser-tool-btn { flex-shrink:0; display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px; border-radius: var(--radius-sm); color:var(--t-dim); cursor:pointer; transition: all var(--duree-2) var(--courbe); background:transparent; border:0; font-size:var(--texte-6); flex-shrink:0; }
.rbrowser-tool-btn:hover { color:var(--t-primary); background:var(--bg-glass-hov); }
.rbrowser-tool-btn.active { color:var(--accent); background:var(--accent-bg); }
/* Rangée non-scrollable (position:relative pour ancrer les menus déroulants — surtout
   pas overflow ici, sinon un dropdown positionné en dessous se ferait couper) ; la
   zone des onglets, elle, scrolle indépendamment dans .rbrowser-tabs-scroll. */
/* LA BARRE DÉBORDAIT, ET SES BOUTONS SORTAIENT DU CADRE.
   Mesuré à 900 px de fenêtre : « Extensions » dépassait de 26 px et « Menu » de
   64 px, hors du bloc, coupés par ce qui borne la page. La barre n'avait pas de
   `min-width:0` — un enfant flex ne descend jamais sous la taille de son
   contenu sans elle — et ses outils pouvaient être compressés au lieu que les
   ONGLETS défilent, ce qui est pourtant à ça que sert leur `overflow-x:auto`.
   La barre accepte d'être contrainte, la liste d'onglets prend ce qui RESTE
   (base 0) et défile, les outils ne se compressent jamais.

   ET QUAND MÊME ÇA NE SUFFIT PAS, ELLE PASSE À LA LIGNE. Dans un studio étroit
   la barre fait 219 px : sept outils de 34 px n'y tiennent pas, même onglets
   repliés à zéro. Trois issues possibles — couper (ce qu'elle faisait), cacher
   dans un menu (une capacité qu'on ne trouve plus), ou grandir. Elle grandit.
   Rien n'est masqué, rien n'est coupé, et `overflow` reste `visible` : les deux
   panneaux qui s'ancrent dedans seraient rognés par un conteneur défilant. */
.rbrowser-tabs { display:flex; flex-wrap:wrap; align-items:center; gap:.25rem; padding:.35rem .5rem; border-bottom:1px solid var(--border); background:var(--bg-secondary); position:relative; min-width:0; }
.rbrowser-tabs-scroll { display:flex; align-items:center; gap:.25rem; overflow-x:auto; min-width:0; flex:1 1 0; scrollbar-width:none; }
.rbrowser-tab { display:flex; align-items:center; gap:.35rem; max-width:180px; min-width:90px; padding:.3rem .55rem; border-radius: var(--radius-sm); font-size:.72rem; color:var(--t-dim); cursor:pointer; background:transparent; transition: all var(--duree-2) var(--courbe); }
.rbrowser-tab:hover { background:var(--bg-glass-hov); }
.rbrowser-tab.active { color:var(--t-primary); background:var(--bg-primary); border:1px solid var(--border); }
.rbrowser-tab-title { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1; min-width:0; }
.rbrowser-tab-close { flex-shrink:0; width:20px; height:20px; display:inline-flex; align-items:center; justify-content:center; border-radius:50%; color:var(--t-faint); border:0; background:transparent; cursor:pointer; font-size:var(--texte-3); line-height:1; }
.rbrowser-tab-close:hover { background:var(--bg-glass-hov); color:var(--t-primary); }
.rbrowser-tab-new { flex-shrink:0; width:24px; height:24px; display:inline-flex; align-items:center; justify-content:center; border-radius: var(--radius-sm); color:var(--t-dim); border:0; background:transparent; cursor:pointer; font-size:var(--texte-6); }
.rbrowser-tab-new:hover { color:var(--t-primary); background:var(--bg-glass-hov); }
.rbrowser-tabs-spacer { flex:1; min-width:.5rem; }
.rbrowser-urlbar { display:flex; align-items:center; gap:.35rem; padding:.4rem .5rem; border-bottom:1px solid var(--border); background:var(--bg-primary); position:relative; }
/* Onglet Web du chat (renderRealBrowser(..., {seamless:true})) : mêmes onglets/barre
   d'adresse fonctionnels, mais sans fond ni ligne de séparation qui les feraient
   ressortir comme une boîte à part — se fond avec l'espace chat au lieu de
   l'encadrer visiblement. */
.rbrowser-seamless.rbrowser { background:transparent; }
.rbrowser-seamless .rbrowser-tabs,
.rbrowser-seamless .rbrowser-urlbar { background:transparent; border-bottom-color:transparent; }
.rbrowser-nav-btn { display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; border-radius:50%; color:var(--t-dim); cursor:pointer; transition: all var(--duree-2) var(--courbe); background:transparent; border:0; font-size:var(--texte-6); flex-shrink:0; }
.rbrowser-nav-btn:hover:not(:disabled) { color:var(--t-primary); background:var(--bg-glass-hov); }
.rbrowser-nav-btn:disabled { opacity:.3; cursor:default; }
.rbrowser-url-input { flex:1; min-width:0; padding:.4rem .9rem; border-radius: var(--radius-rond); border:1px solid var(--border); background:var(--bg-input); color:var(--t-primary); font-size:.75rem; outline:none; }
.rbrowser-url-input:focus { border-color:var(--accent); box-shadow:0 0 0 2px var(--accent-bg); }
.rbrowser-dropdown { position:absolute; top:100%; right:.5rem; z-index:20; min-width:200px; max-width:260px; margin-top:.25rem; padding:.3rem; border-radius: var(--radius); border:1px solid var(--border); background:var(--bg-secondary); box-shadow: var(--ombre-3); display:flex; flex-direction:column; gap:.1rem; }
.rbrowser-dropdown-item { display:flex; align-items:center; gap:.5rem; width:100%; text-align:left; padding:.45rem .6rem; border-radius: var(--radius-sm); border:0; background:transparent; color:var(--t-primary); font-size:.75rem; cursor:pointer; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.rbrowser-dropdown-item svg { flex-shrink:0; }
.rbrowser-dropdown-item .rbrowser-dropdown-check { margin-left:auto; }
.rbrowser-dropdown-item:hover { background:var(--bg-glass-hov); }
.rbrowser-dropdown-add { color:var(--accent); font-weight:600; border-top:1px solid var(--border); margin-top:.2rem; padding-top:.5rem; }
.rbrowser-dropdown-empty { padding:.45rem .6rem; font-size:.72rem; color:var(--t-faint); }
.preview-resize-handle { position:absolute; left:-4px; top:0; bottom:0; width:8px; cursor:ew-resize; z-index:10; background:transparent; }
.preview-resize-handle:hover, .preview-resize-handle.dragging { background:var(--accent); opacity:.35; }
/* Même poignée que .preview-resize-handle, mais sur le bord DROIT du panneau chat des
   Studios (Simplifica compris) — la ligne entre la colonne chat et le carré atelier. */
.studio-chat-resize-handle { position:absolute; right:-4px; top:0; bottom:0; width:8px; cursor:ew-resize; z-index:10; background:transparent; }
.studio-chat-resize-handle:hover, .studio-chat-resize-handle.dragging { background:var(--accent); opacity:.35; }
.rbrowser-empty { display:flex; flex-direction:column; align-items:center; justify-content:center; height:100%; gap:.7rem; padding:2rem; text-align:center; color:var(--t-secondary); }
.rbrowser-empty-icon { font-size:var(--texte-13); opacity:.35; }
.rbrowser-empty-title { font-size:.85rem; font-weight:600; color:var(--t-primary); }
.rbrowser-empty-text { font-size:.72rem; opacity:.7; max-width:320px; line-height:1.5; }
.rbrowser-configdev-btn { margin-top:.3rem; padding:.45rem 1rem; border-radius: var(--radius-sm); font-size:.75rem; font-weight:600; color:var(--t-primary); background:var(--bg-input); border:1px solid var(--border); cursor:pointer; transition: all var(--duree-2) var(--courbe); }
.rbrowser-configdev-btn:hover { background:var(--bg-glass-hov); border-color:var(--accent); }
.rbrowser-annotate-canvas { position:absolute; inset:0; z-index:5; cursor:crosshair; touch-action:none; }
.rbrowser-annotate-toolbar { position:absolute; top:8px; right:8px; z-index:6; display:flex; gap:var(--espace-2); }
.rbrowser-picker-tip { position:absolute; z-index:8; pointer-events:none; max-width:280px; padding:.4rem .55rem; border-radius: var(--radius-sm); background:rgba(15,23,42,.94); color:#e2e8f0; font:500 10.5px/1.5 ui-monospace,monospace; box-shadow: var(--ombre-2); }
.rbrowser-picker-tip b { color:#93c5fd; }
.rbrowser-picker-tip .rbpt-section { color:#94a3b8; font-weight:700; text-transform:uppercase; font-size:var(--texte-1); margin-top:.3rem; }
/* Rectangle de sélection glissé sur le flux en direct (voir _rbStartPick/_rbUpdatePickRect) */
.rbrowser-picker-rect { position:absolute; z-index:7; border:2px solid #3b82f6; background:rgba(59,130,246,.15); pointer-events:none; }
.rbrowser-live-img { user-select:none; }

/* .art-launch* retiré — voir retire/extraits/bloc-apercu-interactif.md */

/* Sliders des paramètres de génération */
.gp-range { accent-color:var(--accent); height:4px; cursor:pointer; }

/* LA RÉFLEXION, DANS LE FIL — un bloc qu'on déplie, pas une fenêtre par-dessus.
   Le CSS existait déjà et n'était appliqué à rien : le seul balisage qui portait
   `.reasoning-body` vivait dans le tiroir de travail, lequel n'était plus
   dessiné. Ces règles servent enfin. */
.reasoning-box { margin:0 0 var(--espace-6); border:1px solid var(--border); border-radius: var(--radius-sm); background:var(--bg-secondary); overflow:hidden; }
.reasoning-label {
  padding:var(--espace-5) var(--espace-7); font-size:var(--texte-4); color:var(--t-dim);
  display:flex; align-items:center; gap:var(--espace-3); user-select:none; cursor:pointer;
  list-style:none; transition:color var(--duree-1) var(--courbe);
}
.reasoning-label::-webkit-details-marker { display:none; }
.reasoning-label:hover { color:var(--t-secondary); }
/* Le chevron dit dans quel sens ça va ; il tourne au lieu de sauter. */
.reasoning-label::after {
  content:'▶'; font-size:var(--texte-1); opacity:.45; margin-left:auto;
  transition:transform var(--duree-2) var(--courbe);
}
.reasoning-box[open] > .reasoning-label::after { transform:rotate(90deg); }
.reasoning-duree { color:var(--t-faint); font-variant-numeric:tabular-nums; }
.reasoning-body {
  padding:var(--espace-3) var(--espace-8) var(--espace-6); font-size:var(--texte-5);
  color:var(--t-dim); border-top:1px solid var(--border);
  max-height:22rem; overflow-y:auto;
}
/* Elle pense encore : le bloc respire tant que rien n'est écrit. */
.reasoning-box[open] > .reasoning-label > svg { opacity:.7; }
/* CREA × CREA — système de duel interne (conscience émergente) */
.duel-wrap { border:1px solid var(--border); border-radius: var(--radius); overflow:hidden; margin-bottom:.8rem; }
.duel-phase-bar { padding:.4rem .75rem; font-size:.72rem; color:var(--t-faint); background:var(--bg-secondary); border-bottom:1px solid var(--border); display:flex; align-items:center; gap:.4rem; }
.duel-box { border-bottom:1px solid var(--border); background:var(--bg-secondary); }
.duel-box:last-child { border-bottom:0; }
.duel-box summary { padding:.5rem .75rem; font-size:.76rem; cursor:pointer; display:flex; align-items:center; gap:.5rem; list-style:none; user-select:none; }
.duel-box summary::-webkit-details-marker { display:none; }
.duel-box summary::before { content:'▶'; font-size:.6rem; opacity:.5; transition: transform var(--duree-2) var(--courbe); flex-shrink:0; }
.duel-box[open] summary::before { transform:rotate(90deg); }
.duel-a summary { color:#3b82f6; }
.duel-b summary { color:#ef4444; }
.duel-body { padding:.4rem .9rem .75rem; font-size:.8rem; color:var(--t-secondary); border-top:1px solid var(--border); }
.duel-synth-label { padding:.4rem .75rem; font-size:.72rem; color:var(--accent); background:var(--bg-secondary); border-top:1px solid var(--border); font-weight:600; letter-spacing:.01em; }
.duel-juge-wrap { border-top:1px solid rgba(245,158,11,.2); background:rgba(245,158,11,.04); }
.duel-juge-row { display:flex; align-items:flex-start; gap:.6rem; padding:.45rem .75rem; border-bottom:1px solid rgba(245,158,11,.08); }
.duel-juge-row:last-child { border-bottom:0; }
.dj-label { font-size:.7rem; font-weight:700; color:#f59e0b; flex-shrink:0; min-width:72px; padding-top:.1rem; letter-spacing:.01em; }
.dj-val { font-size:.76rem; color:var(--t-secondary); line-height:1.5; font-style:italic; }
.dj-drift .dj-label { color:#ef4444; }
.dj-drift .dj-val { color:#fca5a5; }
.dj-questions .dj-label { color:#a78bfa; }
.dj-questions .dj-val { color:#c4b5fd; font-style:normal; }
.duel-q-chips { display:flex; flex-wrap:wrap; gap:.4rem; padding:.4rem .75rem .55rem; border-top:1px solid rgba(167,139,250,.15); background:rgba(167,139,250,.04); }
.duel-q-chip { border:1px solid rgba(167,139,250,.35); background:rgba(167,139,250,.08); color:#c4b5fd; border-radius: var(--radius-rond); padding:.25rem .75rem; font-size:.72rem; cursor:pointer; transition: all var(--duree-2) var(--courbe); text-align:left; line-height:1.4; }
.duel-q-chip:hover { background:rgba(167,139,250,.18); border-color:#a78bfa; color:#fff; }
.duel-a-reply summary { color:#60a5fa; }
.duel-compare-bar { padding:.35rem .75rem; background:var(--bg-secondary); border-top:1px solid var(--border); }
.duel-compare-btn { font-size:.72rem; color:var(--t-faint); background:none; border:1px solid var(--border); border-radius: var(--radius-rond); padding:.2rem .65rem; cursor:pointer; transition: all var(--duree-2) var(--courbe); }
.duel-compare-btn:hover { color:var(--t-primary); border-color:var(--accent); }
.duel-spiral-btn { font-size:.72rem; color:#f59e0b; background:rgba(245,158,11,.08); border:1px solid rgba(245,158,11,.35); border-radius: var(--radius-rond); padding:.2rem .65rem; cursor:pointer; transition: all var(--duree-2) var(--courbe); margin-left:.4rem; }
.duel-spiral-btn:hover { background:rgba(245,158,11,.18); border-color:#f59e0b; }
/* Progress dots */
.duel-progress { display:flex; align-items:center; gap:var(--espace-2); margin-left:auto; margin-right:.4rem; }
.dp-dot { width:6px; height:6px; border-radius:50%; background:var(--border); transition: all var(--duree-2) var(--courbe); }
.dp-dot.dp-done { background:var(--accent); }
.dp-dot.dp-active { background:#f59e0b; box-shadow:0 0 4px #f59e0b88; }
/* Export button */
.duel-export-btn { background:none; border:none; color:var(--t-faint); cursor:pointer; font-size:.8rem; padding:.1rem .3rem; border-radius: var(--radius-xs); transition: all var(--duree-2) var(--courbe); flex-shrink:0; }
.duel-export-btn:hover { color:var(--t-primary); background:var(--bg-hover,rgba(255,255,255,.06)); }
/* Rating buttons */
.duel-rate-btns { display:inline-flex; gap:var(--espace-1); margin-left:auto; }
.dr-btn { background:none; border:none; cursor:pointer; font-size:.75rem; opacity:.4; padding:.1rem .25rem; border-radius: var(--radius-xs); transition: all var(--duree-2) var(--courbe); }
.dr-btn:hover { opacity:1; background:rgba(255,255,255,.06); }
.dr-btn.dr-on { opacity:1; }
/* B reply box */
.duel-b-reply summary { color:#f87171; }
/* Miroir utilisateur */
.dj-miroir .dj-label { color:#22d3ee; }
.dj-miroir .dj-val { color:#67e8f9; font-style:italic; }
/* ===== MOTEUR ÉPISTÉMIQUE — Audit de vérité ===== */
.epis-wrap { border:1px solid var(--border); border-radius: var(--radius); overflow:hidden; margin-top:.6rem; font-size:.75rem; }
.epis-wrap.epis-auto { border-style:dashed; border-color:rgba(99,102,241,.35); }
.epis-header { display:flex; align-items:center; gap:.5rem; padding:.4rem .75rem; cursor:pointer; list-style:none; background:var(--bg-secondary); flex-wrap:wrap; gap:.3rem .6rem; }
.epis-header::-webkit-details-marker { display:none; }
.epis-score { font-weight:700; font-size:.78rem; }
.epis-by { margin-left:auto; font-size:.68rem; flex-shrink:0; }
.epis-body { padding:.5rem .75rem; display:flex; flex-direction:column; gap:.35rem; border-top:1px solid var(--border); }
/* Claims */
.epis-claims { display:flex; flex-direction:column; gap:.2rem; }
.epis-claim { display:flex; align-items:baseline; gap:.4rem; }
.epis-claim-status { flex-shrink:0; font-size:.78rem; }
.epis-claim-text { color:var(--t-secondary); font-size:.75rem; line-height:1.4; }
/* Sections */
.epis-section { display:flex; align-items:flex-start; gap:.4rem; flex-wrap:wrap; }
.epis-label { font-size:.68rem; font-weight:600; text-transform:uppercase; letter-spacing:.05em; color:var(--t-faint); white-space:nowrap; padding-top:.1rem; }
/* Tags */
.epis-tag { display:inline-flex; font-size:.68rem; padding:.1rem .45rem; border-radius: var(--radius-rond); border:1px solid var(--border); color:var(--t-faint); background:var(--bg-tertiary,rgba(255,255,255,.03)); }
.epis-tag-zone { color:#818cf8; border-color:rgba(129,140,248,.35); background:rgba(129,140,248,.07); }
.epis-zones { display:inline-flex; flex-wrap:wrap; gap:.25rem; }
/* Conseil */
.epis-conseil { color:var(--t-dim); font-size:.75rem; padding:.3rem .5rem; border-radius: var(--radius-sm); background:rgba(255,255,255,.03); border-left:2px solid var(--accent); }
/* Tables interactives (tri + filtre) dans les réponses */
.md-table-wrap { overflow-x:auto; margin:.6rem 0; }
.md-table-toolbar { display:flex; align-items:center; gap:.5rem; margin-bottom:.4rem; }
.md-table-filter { width:100%; max-width:260px; font-size:.78rem; padding:.32rem .6rem; border-radius: var(--radius-sm); background:var(--bg-input); color:var(--t-primary); border:1px solid var(--border); outline:none; }
.md-table-filter:focus { border-color:var(--accent); }
.md-table-count { font-size:.7rem; color:var(--t-faint); white-space:nowrap; }
.md-th-sortable { cursor:pointer; user-select:none; white-space:nowrap; transition: color var(--duree-1) var(--courbe); }
.md-th-sortable:hover { color:var(--accent); }
.md-th-sortable::after { content:"⇅"; opacity:.3; margin-left:.3rem; font-size:.72em; }
.md-th-sortable[data-sort="asc"]::after { content:"↑"; opacity:1; color:var(--accent); }
.md-th-sortable[data-sort="desc"]::after { content:"↓"; opacity:1; color:var(--accent); }

/* Contrôles du Studio Design (style / format / nombre) */
.design-chip { font-size:.7rem; padding:.18rem .55rem; border-radius: var(--radius-rond); cursor:pointer; color:var(--t-dim); background:var(--bg-secondary); border:1px solid var(--border); transition: all var(--duree-1) var(--courbe); white-space:nowrap; }
.design-chip:hover { color:var(--t-primary); border-color:var(--border-hov); }
.design-chip-on { color:var(--accent); background:var(--accent-bg); border-color:var(--accent); font-weight:500; }

/* Puces de suggestions de questions de suivi */
.sug-chip {
  font-size:.74rem; padding:.3rem .65rem; border-radius: var(--radius-rond); cursor:pointer;
  color:var(--accent); background:var(--accent-bg); border:1px solid transparent;
  transition: all var(--duree-2) var(--courbe); text-align:left; line-height:1.2;
}
.sug-chip:hover { border-color:var(--accent); transform:translateY(-1px); }

/* Sources — une seule pastille : favicons empilés + « N sources ».
   Au clic, un popover compact ancré dessous liste les sources. */
/* Dans la rangée d'actions : poussée à l'extrémité droite, sur la même ligne. */
.src-badge-wrap { position:relative; display:inline-block; }
.chat-actions .src-badge-wrap { margin-left:auto; }
.chat-actions .src-panel { left:auto; right:0; }
.src-badge {
  display:inline-flex; align-items:center; gap:var(--espace-4);
  padding:var(--espace-1) var(--espace-2); border:none; background:transparent;
  cursor:pointer; font-family:inherit; border-radius: var(--radius-rond);
  transition: background var(--duree-2) var(--courbe);
}
.src-badge:hover { background:var(--bg-secondary); }
.src-avs { display:inline-flex; align-items:center; }
.src-av {
  width:15px; height:15px; border-radius:50%; position:relative;
  border:1.5px solid var(--bg-primary); background:var(--bg-secondary);
  object-fit:cover; flex-shrink:0;
}
.src-av + .src-av { margin-left:-6px; }
.src-badge-count { font-size:var(--texte-2); color:var(--t-faint); white-space:nowrap; }
.src-badge:hover .src-badge-count { color:var(--t-secondary); }

.src-panel {
  position:absolute; top:calc(100% + 5px); left:0; z-index:60;
  min-width:190px; max-width:300px; max-height:260px; overflow-y:auto;
  padding:var(--espace-2); border-radius: var(--radius);
  background:var(--bg-primary); border:1px solid var(--border);
  box-shadow: var(--ombre-3); scrollbar-width:thin;
}
.src-row {
  display:flex; align-items:center; gap:var(--espace-4);
  padding:var(--espace-3) var(--espace-4); border-radius: var(--radius-sm); text-decoration:none;
  color:var(--t-secondary); font-size:var(--texte-3); transition: background var(--duree-1) var(--courbe);
}
.src-row:hover { background:var(--bg-secondary); }
.src-row-fav { width:13px; height:13px; border-radius: var(--radius-xs); flex-shrink:0; }
.src-row-host { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* Cards riches : YouTube, articles, produits */
.rich-card-btn {
  font-size:var(--texte-2); padding:var(--espace-2) var(--espace-5); border-radius: var(--radius-rond); cursor:pointer;
  color:var(--accent); background:var(--accent-bg); border:1px solid rgba(16,163,127,.25);
  transition: all var(--duree-2) var(--courbe); font-family:inherit; white-space:nowrap;
}
.rich-card-btn:hover { border-color:var(--accent); opacity:.8; }

/* Diagramme en cours d'écriture : on montre le source, pas un dessin qui se
   refait soixante fois par seconde (voir buildCodeBlockHtml). Même allure qu'un
   bloc de code, pour que le passage au vrai diagramme ne surprenne pas. */
.mermaid-en-cours {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: var(--texte-3); line-height: 1.6;
  padding: var(--espace-6) var(--espace-7); margin: var(--espace-4) 0;
  border-radius: var(--radius); overflow-x: auto;
  background: var(--bg-tertiary); color: var(--t-dim);
  border: 1px solid var(--border);
}

/* ── FICHES PRODUIT / LIEU ──────────────────────────────────────────────────
   Ces deux cartes se réduisaient à un nom et un prix dans un rectangle : sans
   `image`, tout le bandeau haut disparaissait et il ne restait qu'une étiquette.
   Le champ était vide la plupart du temps (voir fetch_url, src/app.js : l'URL de
   l'image réelle était jetée avant d'arriver au modèle).
   Règle tenue ici : une fiche n'a jamais de trou. À défaut de photo, elle porte
   un visuel construit à partir de son nom — même nom, même couleur, toujours. */

.crea-fiche {
  display:flex; flex-direction:column;
  width:min(340px, 100%); margin:var(--espace-5) 0;
  border:1px solid var(--border); border-radius: var(--radius-lg);
  background:var(--bg-secondary); overflow:hidden;
  transition: border-color var(--duree-2) var(--courbe), transform var(--duree-2) var(--courbe), box-shadow var(--duree-2) var(--courbe);
}
.crea-fiche-lien { text-decoration:none; color:inherit; display:flex; }
.crea-fiche:hover {
  border-color:var(--border-hov);
  transform:translateY(-2px);
  box-shadow: var(--ombre-3);
}
/* Un appareil sans survol (doigt) ne doit pas hériter d'un état de survol collant. */
@media (hover:none) { .crea-fiche:hover { transform:none; box-shadow:none; } }
@media (prefers-reduced-motion:reduce) { .crea-fiche { transition:none } .crea-fiche:hover { transform:none } }

/* Plusieurs fiches d'affilée se rangent côte à côte au lieu de s'empiler sur
   toute la hauteur de l'écran — c'est le cas d'usage réel : « trouve-moi trois
   restaurants ». Le sélecteur ne prend QUE des suites de fiches. */
.crea-fiche + .crea-fiche { margin-top:var(--espace-5) }
@supports (display:grid) {
  .crea-fiches-grille {
    display:grid; gap:var(--espace-6); margin:var(--espace-5) 0;
    grid-template-columns:repeat(auto-fill, minmax(260px, 1fr));
  }
  .crea-fiches-grille .crea-fiche { width:auto; margin:0 }
}

.crea-fiche-visuel { position:relative; width:100%; background:var(--bg-tertiary); overflow:hidden; flex-shrink:0 }
.crea-fiche-visuel img { width:100%; height:100%; object-fit:cover; display:block }
/* L'image distante a échoué (403, lien mort) : on retombe sur le visuel de repli
   au lieu de laisser l'icône d'image cassée du navigateur. */
.crea-fiche-cassee img { display:none }
.crea-fiche-cassee { background:linear-gradient(135deg, var(--bg-tertiary), var(--bg-secondary)) }

.crea-fiche-sansimage {
  display:flex; align-items:center; justify-content:center;
  background:linear-gradient(135deg, var(--f1), var(--f2));
}
.crea-fiche-mono {
  font-size:var(--texte-13); font-weight:700; letter-spacing:.02em;
  color:rgba(255,255,255,.95); text-shadow:0 1px 12px rgba(0,0,0,.22);
}
.crea-fiche-glyphe { position:absolute; right:10px; bottom:8px; font-size:var(--texte-6); opacity:.55 }

.crea-fiche-badge {
  position:absolute; top:10px; right:10px;
  background:rgba(17,17,17,.72); color:#fff; backdrop-filter:blur(6px);
  font-size:var(--texte-1); font-weight:600; letter-spacing:.01em;
  padding:var(--espace-2) var(--espace-5); border-radius: var(--radius-rond);
}

.crea-fiche-corps { padding:var(--espace-6) var(--espace-7) var(--espace-7); display:flex; flex-direction:column; gap:var(--espace-3); flex:1 }
.crea-fiche-entete { display:flex; align-items:flex-start; gap:var(--espace-4) }
.crea-fiche-titre {
  flex:1; min-width:0;
  font-size:var(--texte-5); font-weight: 700; line-height:1.3; color:var(--t-primary);
}
.crea-fiche-meta { font-size:var(--texte-2); color:var(--t-faint) }
.crea-fiche-desc {
  font-size:var(--texte-3); line-height:1.5; color:var(--t-secondary); margin:0;
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
}

.crea-fiche-note { display:flex; align-items:center; gap:var(--espace-3); font-size:var(--texte-2); color:var(--t-secondary) }
.crea-fiche-etoiles { color:#f59e0b; letter-spacing:.5px; font-size:var(--texte-2) }
.crea-fiche-vides { color:var(--t-faint); opacity:.45 }
.crea-fiche-note b { color:var(--t-primary); font-weight: 700 }
.crea-fiche-avis { color:var(--t-faint) }

.crea-fiche-lignes { display:flex; flex-direction:column; gap:var(--espace-2); margin-top:var(--espace-1) }
.crea-fiche-ligne { display:flex; gap:var(--espace-4); align-items:flex-start; font-size:var(--texte-3); color:var(--t-dim); line-height:1.4 }
.crea-fiche-ligne > span:first-child { opacity:.6; flex-shrink:0 }
.crea-fiche-ligne a { color:var(--t-dim); text-decoration:none; border-bottom:1px dotted var(--border-hov) }
.crea-fiche-ligne a:hover { color:var(--accent); border-bottom-color:var(--accent) }

.crea-fiche-statut {
  font-size:var(--texte-1); font-weight: 700; padding:var(--espace-1) var(--espace-4); border-radius: var(--radius-rond); flex-shrink:0; white-space:nowrap;
}
.crea-fiche-statut.est-ouvert { background:rgba(34,197,94,.14); color:#16a34a }
.crea-fiche-statut.est-ferme  { background:rgba(239,68,68,.12); color:#dc2626 }

.crea-fiche-pied {
  display:flex; align-items:center; justify-content:space-between; gap:var(--espace-5);
  margin-top:auto; padding-top:var(--espace-5);
}
.crea-fiche-prix { font-size:var(--texte-7); font-weight:700; color:var(--t-primary); letter-spacing:-.01em }
.crea-fiche-cta {
  font-size:var(--texte-3); font-weight:600; padding:var(--espace-3) var(--espace-7); border-radius: var(--radius-rond);
  color:var(--accent); background:var(--accent-bg); border:1px solid rgba(16,163,127,.28);
  text-decoration:none; white-space:nowrap; transition: all var(--duree-2) var(--courbe);
}
.crea-fiche-cta:hover { background:var(--accent); color:#fff; border-color:var(--accent) }

/* Panel de présence — actions de transformation */
.presence-action-btn {
  font-size:var(--texte-2); padding:var(--espace-2) var(--espace-5); border-radius: var(--radius-rond); cursor:pointer;
  color:var(--t-secondary); background:var(--bg-primary); border:1px solid var(--border);
  transition: all var(--duree-2) var(--courbe); font-family:inherit; white-space:nowrap;
}
.presence-action-btn:hover { color:var(--accent); border-color:var(--accent); background:var(--accent-bg); }

/* Mode focus : SUPPRIMÉ — code archivé dans retire/extraits/mode-focus.md.
   (.chat-form-focus, plus bas, est autre chose : une des sept formes de la
   fenêtre de chat, toujours active.) */

/* --- Lightbox --- */
.lightbox {
  position:fixed; inset:0; z-index:600;
  display:flex; align-items:center; justify-content:center;
  background:rgba(0,0,0,.92); cursor:zoom-out; animation:fadeIn .2s ease-out;
}
.lightbox img { max-width:92vw; max-height:92vh; border-radius: var(--radius-sm); }

/* --- Model badge colors --- */
.model-openai   { color:#10a37f; } .model-anthropic { color:#d97706; }
.model-deepseek { color:#6366f1; } .model-google    { color:#4285f4; }
.model-local    { color:#22c55e; }
.model-groq     { color:#f55036; } .model-mistral   { color:#ff7000; }
.model-xai      { color:#1a1a1a; } .model-cerebras  { color:#7c3aed; }
.model-sambanova { color:#0ea5e9; } .model-perplexity { color:#20b2aa; }
.model-together  { color:#ff6b6b; } .model-cohere    { color:#39c5bb; }
.model-fireworks { color:#ff4500; } .model-openrouter { color:#6d28d9; }

/* --- Responsive --- */
@media (max-width:768px) {
  /* Le tiroir occupe --crea-sb-w (78% de la largeur d'écran, plafonné à 420px
     pour les tablettes — cf. la définition de la variable), PAS tout l'écran : c'est exactement la distance dont l'animation de poussée
     décale le contenu (.main-pushed), donc la carte du contenu reste visible
     à droite — comme dans la référence. En 100% la poussée décalait quelque
     chose d'entièrement recouvert. Pas de !important sur la largeur : les
     tiroirs la posent en style inline avec la même variable. */
  #sidebar { position:fixed; z-index:40; }

  /* ---- Rythme commun à TOUTES les barres latérales, mobile uniquement ----
     Chat, Studios, Espaces, Créatif et Menu partagent le même emplacement
     physique mais sont rendus par cinq fonctions distinctes. Plutôt que de
     répéter le même habillage dans chacune (et de l'oublier dans la
     prochaine), la structure de la référence est posée ici une seule fois :
     rangées à 44px (minimum tactile), libellés lisibles, titres de section
     qui ressemblent à des titres. Desktop n'est pas concerné. */

  /* Rangées pleine largeur = les vraies lignes cliquables de chaque tiroir.
     Volontairement PAS "#sidebar button" : les pastilles de couleur et les
     petits boutons en ligne (« + ouvrir », ✕ d'un onglet) deviendraient des
     ovales de 44px au milieu d'une ligne. */
  #sidebar button.w-full,
  #sidebar [data-conv-sheet],
  #sidebar [data-conv],
  #sidebar [data-tab],
  #sidebar [data-studio-quick] {
    min-height: 44px;
  }

  /* Libellés de ligne : 12/12.5/13px → 15px. Les tailles plus petites
     (badges, compteurs, « ● actif ») gardent leur rôle secondaire. */
  #sidebar .text-\[12px\],
  #sidebar .text-\[12\.5px\],
  #sidebar .text-\[13px\] { font-size: var(--texte-6); }

  /* Titres de section : la capitale 10px se lisait comme une légende. */
  #sidebar .text-\[10px\].uppercase { font-size: var(--texte-3); letter-spacing: .04em; }

  /* Garde-fou : un tiroir ne défile jamais horizontalement. Une icône dont la
     taille n'est pas appliquée retombe sur la taille intrinsèque du SVG (~300px)
     et pousse la largeur du tiroir ; à 280px ça se voit tout de suite. Ne
     change rien aux icônes correctement dimensionnées. */
  #sidebar { overflow-x: hidden; }
  #sidebar svg { max-width: 100%; }
  .sidebar-backdrop { position:fixed; inset:0; z-index:39; background:rgba(0,0,0,.5); }
  .artifacts-panel { position:fixed; right:0; top:0; bottom:0; z-index:35; width:100%!important; max-width:100%!important; }

  /* Les modales ne sont PLUS forcees en plein ecran ici. Il y avait a cet
     endroit une liste de 27 identifiants a qui on imposait
     width/height/max-height:100% et border-radius:0 — c'est exactement le
     « les affiches s'affichent en plein ecran alors que ca devrait etre un
     bloc » remonte par l'usager. Une liste ecrite a la main, en plus : 13
     modales ajoutees depuis n'y ont jamais figure, donc l'app avait deux
     comportements selon l'age de la modale.
     La forme est maintenant decidee par la classe .crea-modale et le palier
     html.uie-tier-phone du moteur (voir plus bas) : une feuille ancree en
     bas, qui se lit comme un bloc pose sur l'ecran. Un seul endroit, et plus
     aucune liste a tenir a jour. */
}

/* ANTI-ZOOM iOS — CAUSE RACINE du « la page s'agrandit quand je tape » :
   tout champ de saisie en dessous de 16px declenche un zoom AUTO au focus sur iPhone.
   On force 16px UNIQUEMENT sur mobile pour les champs ; l'apparence desktop ne bouge pas.
   Le !important est necessaire pour battre les styles inline (ex: font-size:var(--texte-5) du composer). */
@media (max-width:767px) {
  input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]),
  textarea,
  select,
  [contenteditable="true"] { font-size:var(--texte-7) !important; }
}

/* ===== CADRE APP-LIKE — la HAUTEUR est gérée par crea-adapt.js (source unique) =====
   crea-adapt.js règle #app = 100dvh, et = var(--crea-vh) quand le clavier est ouvert
   (classe .crea-kb-open) — var(--crea-vh) = visualViewport.height exclut déjà le clavier,
   donc la barre de saisie arrive PILE au-dessus du clavier (header + composer figés,
   seules les zones .overflow-y-auto défilent). Les zones sûres (encoche / barre home) sont
   aussi gérées par crea-adapt. Ici on empêche juste le scroll/rebond de page et on garantit
   que les colonnes flex peuvent rétrécir. Zoom verrouillé via le meta viewport. */
html { overflow: hidden; }
html, body { overscroll-behavior: none; }
#app, #app main { min-height: 0; }

/* Bas des barres de saisie — valeur unique pour l'accueil ET le fil de chat.
   Définie ici en dur pour ne pas dépendre du chargement de crea-adapt.js, qui
   la redéfinit à l'identique. Le plancher couvre Android et tout écran sans
   retrait système. */
:root { --crea-composer-bottom: 6px; }

/* iPhone — zone sûre (encoche / barre home). N'a d'effet que sur les appareils concernés. */
@supports (padding:env(safe-area-inset-bottom)) {
  /* La barre d'accueil du système ne fait que ~13px de haut alors que le
     retrait annoncé en fait ~34 : on en récupère 16, il en reste ~18, la
     barre arrive au ras de la pastille sans passer dessous. */
  :root { --crea-composer-bottom: max(6px, calc(env(safe-area-inset-bottom) - 16px)); }
  /* #messages-container n'est PAS collé au bas de l'écran : la barre de saisie
     est son frère et vient après, et c'est ELLE qui porte le retrait système.
     Le mettre ici aussi le comptait deux fois et remontait tout le contenu. */
  #messages-container { padding-bottom:1rem; }
  .chat-files-panel, .input-suggest { padding-bottom:env(safe-area-inset-bottom); }
}

/* ORDINATEUR : il n'y a pas de barre d'accueil système sous la fenêtre.
   Les 6px ci-dessus sont réglés POUR elle — sur téléphone ils laissent la
   barre au ras de la pastille sans passer dessous, et c'est juste. Sur un
   écran d'ordinateur il n'y a rien en dessous : la barre touche alors le bord
   de la fenêtre. Mesuré : bas de la barre à 900px sur un écran de 900px, la
   ligne « CREA peut faire des erreurs » à 14px du bord.
   Cette règle vient APRÈS le @supports ci-dessus, et il faut qu'elle y reste :
   sur bureau env(safe-area-inset-bottom) vaut 0, donc ce bloc y recalcule 6px,
   et c'est la dernière déclaration qui gagne.
   Bornée à ≥640px : le téléphone garde son réglage, qui répond à un autre
   problème. Valeur unique, tenue à l'identique dans crea-adapt.js. */
/* ── ET « TOUT EN BAS » VEUT DIRE TOUT EN BAS ─────────────────────────────
   « Une fois qu'on a ouvert le chat, qu'on a commencé à discuter, la barre de
    questions doit descendre tout en bas. Sauf qu'elle laisse un petit espace
    tout en bas, alors que normalement elle doit vraiment descendre tout en
    bas. »
   Elle valait 20 px sur écran d'ordinateur — et la note juste au-dessus disait
   pourtant « la barre touche alors le bord de la fenêtre » : le commentaire et
   la valeur ne disaient pas la même chose. Mesuré : bas de la barre à 793 px
   dans une fenêtre de 813. Le téléphone garde ses 6 px, qui répondent à un
   autre problème — la barre d'accueil du système passe dessous. */
@media (min-width: 640px) {
  :root { --crea-composer-bottom: 0px; }
}

/* LA BARRE AU MILIEU, PAS LE GROUPE.
   « La barre de questions dans chat et work, elle est trop basse, elle n'est
     pas bien alignée au milieu. Et ce n'est pas qu'une impression. »
   Ce n'était pas qu'une impression : #welcome-screen centre l'ENSEMBLE
   salutation + barre. La barre étant dessous, elle tombe sous la ligne
   médiane — mesuré 63px trop bas, avec 284px de vide sous elle contre 260px
   au-dessus de la salutation. Le groupe était centré ; la barre, non.
   C'est la barre qu'on regarde et dans laquelle on écrit : c'est elle qui doit
   être au milieu. On donne à la salutation et au vide qui la suit la même
   hauteur souple ; la barre se retrouve pile entre les deux, la salutation
   juste au-dessus d'elle. Pas de nœud ajouté au DOM : le second bloc souple
   est un ::after.
   Bornée à ≥640px : sur téléphone la barre descend VOLONTAIREMENT tout en bas
   (règles plus loin), pour rester sous le pouce. */
@media (min-width: 640px) {
  #welcome-screen > #welcome-greeting { flex: 1 1 0; justify-content: flex-end; }
  /* L'écart `mb-6` entre la salutation et la barre vit ENTRE les deux blocs
     souples : il ne pèse donc que d'un côté et décalait la barre de sa moitié
     — 12px, mesurés. On le reflète sous la barre, où il ne se voit pas (le
     bloc est vide) mais où il rétablit la symétrie : écart 0.
     1.5rem est la valeur de `mb-6` porté par #welcome-greeting dans app.js ;
     la garde `tiroir-plus` remesure le centrage, et parlera si l'un des deux
     bouge sans l'autre. */
  #welcome-screen::after { content: ''; flex: 1 1 0; margin-top: 1.5rem; }
}

/* --- Print --- */
@media print {
  body { background:white; color:black; }
  #sidebar, header, .glass, .status-bar { display:none!important; }
  .artifacts-panel { display:none!important; }
}

@keyframes pulse { 0%,100%{opacity:1;}50%{opacity:.4;} }
.anim-pulse-soft { animation: pulse 1.4s ease-in-out infinite; }

/* ===== LOGO CRÉA VIVANT (doré, animé dans toute l'app) =====
   .crea-logo-live : respiration douce + halo doré, partout (premium, discret).
   .crea-logo-think : pulsation plus marquée pendant que l'IA répond. */
/* Plus de rotation : le logo ne doit jamais partir de travers. Une respiration
   d'intensité (halo + très léger grossissement) suffit à dire « ça travaille »,
   sans déformer la marque. */
@keyframes creaLogoThink {
  0%,100% { transform: scale(1);    filter: drop-shadow(0 0 1px rgba(16,163,127,.35)); }
  50%     { transform: scale(1.06); filter: drop-shadow(0 0 8px rgba(16,163,127,.75)); }
}
/* statique par défaut (premium, perf) ; s'illumine au survol */
.crea-logo-live  { transition:  transform var(--duree-3) var(--courbe), filter var(--duree-3) var(--courbe); }
.crea-logo-live:hover { transform: scale(1.06); filter: drop-shadow(0 0 5px rgba(16,163,127,.55)); }
/* motion PORTEUSE DE SENS : pulse doré pendant que l'IA répond */
/* ===== LOGO DU MODE AGENTIQUE — une signature de mouvement par studio =====
   Le logo est inséré en SVG dans la page (cf. creaLogoSvg) : c'est la seule façon
   d'atteindre les anneaux un par un. transform-box:view-box est ICI le point
   crucial — avec fill-box, l'origine se compterait depuis la boîte de chaque
   ellipse et les anneaux partiraient hors cadre, le bug d'origine. */
.crea-logo-svg { display:block; overflow:visible }
.crea-logo-svg .cl-r,
.crea-logo-svg .cl-noyau,
.crea-logo-svg .cl-coque { transform-origin:100px 100px; transform-box:view-box }

/* A — Orbite : les trois anneaux tournent sur eux-mêmes, à des vitesses différentes */
@keyframes clSpin    { to { transform:rotate(360deg) } }
@keyframes clSpinInv { to { transform:rotate(-360deg) } }
.cl-orbite .cl-r1 { animation:clSpin    9s   linear infinite }
.cl-orbite .cl-r2 { animation:clSpinInv 13s  linear infinite }
.cl-orbite .cl-r3 { animation:clSpin    6.5s linear infinite }

/* B — Respiration : aucune rotation, le logo inspire et le noyau bat */
@keyframes clSouffle { 0%,100% { transform:scale(1); opacity:.92 } 50% { transform:scale(1.06); opacity:1 } }
@keyframes clBattement { 0%,100% { transform:scale(1) } 50% { transform:scale(1.35) } }
.cl-respiration .cl-coque { animation:clSouffle   2.6s ease-in-out infinite }
.cl-respiration .cl-noyau { animation:clBattement 2.6s ease-in-out infinite }

/* C — Traçage : les orbites se dessinent l'une après l'autre, puis s'effacent */
@keyframes clTrace { 0% { stroke-dashoffset:352 } 55% { stroke-dashoffset:0 } 100% { stroke-dashoffset:-352 } }
.cl-tracage ellipse { stroke-dasharray:176 176; animation:clTrace 2.8s ease-in-out infinite }
.cl-tracage .cl-r2 ellipse { animation-delay:-.45s }
.cl-tracage .cl-r3 ellipse { animation-delay:-.9s }

/* D — Comète : les orbites s'effacent au second plan, un point les parcourt */
@keyframes clLueur { 0%,100% { opacity:.3 } 50% { opacity:1 } }
.cl-comete ellipse   { opacity:.3 }
.cl-comete .cl-noyau { animation:clLueur 2s ease-in-out infinite }

@media (prefers-reduced-motion: reduce) {
  .crea-logo-svg *, .crea-logo-svg { animation:none !important }
}

/* Le logo ne bouge NULLE PART, y compris pendant que CREA travaille : c'était le
   dernier endroit où il flottait encore, en haut de la barre latérale. Le mouvement
   reviendra ici, et seulement ici, quand le thème d'animation du mode agentique
   aura été choisi. La classe reste posée par le rendu pour servir d'accroche. */
.crea-logo-think { animation: none; }
/* Les anneaux du logo tournent chacun sur eux-mêmes, directement dans le SVG
   (public/crea-logo.svg) — vivant par nature, pas besoin de faire tourner
   l'<img> entier en plus depuis la page (ça doublerait le mouvement). */
.crea-gen-logo { width:20px; height:20px; flex-shrink:0; animation: creaStepBreath 1.6s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .crea-gen-logo { animation: none; opacity: .8; } }
.crea-gen-time { font-size:var(--texte-2); color:var(--t-faint); font-variant-numeric:tabular-nums; margin-left:var(--espace-1); }
@media (prefers-reduced-motion: reduce) {
  .crea-logo-live, .crea-logo-think { animation: none; transition: none; }
}

/* --- Scroll chat ---
   scroll-behavior:smooth retiré — causait des sauts au reload/IDB hydrate (scrollIntoView instant ignoré)
   overflow-anchor:auto ancre le bas du chat quand la textarea grandit (évite le tremblement à la saisie) */
#messages-container { overflow-x:hidden; overflow-y:auto; overflow-anchor:auto; }

/* Sidebar : will-change évite le reflow du content pendant l'animation transform */
#sidebar { will-change:transform; }

/* Composer bar : contain layout évite que la textarea-resize propage un reflow au chat */
.crea-composer-bar { contain:layout; }

/* Chat épuré — sans avatars, messages pleine largeur */
/* ── LA LARGEUR DU FIL, DÉCIDÉE À UN SEUL ENDROIT ────────────────────────
   « L'écran de l'espace chat, il faut le réduire en largeur dans tous les
   espaces. Les bords, ils sont un peu plus aérés chez Claude, et là ça prend
   toute la largeur : ça laisse pas respirer. »
   Le fil ET sa barre de question portaient `max-w-4xl` — 896 px — chacun de son
   côté. Deux valeurs pour une seule colonne, c'est deux valeurs qui finissent
   par diverger : le jour où l'une bouge, le texte et le champ ne s'alignent
   plus. Une variable, deux lecteurs. */
:root { --crea-fil-max: 48rem; }
.crea-largeur-fil { max-width: var(--crea-fil-max); }
.chat-thread { width:100%; }
.chat-message-row {
  display:flex;
  flex-direction:column;
  margin-bottom:var(--espace-10);
}
.group\/convrow:hover .conv-select-cb { opacity:1 !important; }
.chat-message-ai  { align-items:flex-start; }
.chat-message-user{ align-items:flex-end; }
.chat-message-ai  .chat-message-content { text-align:left; }
.chat-message-user .chat-message-content { text-align:right; }
.chat-message-content {
  min-width:0;
  overflow-wrap:anywhere;
}
.chat-message-content-ai   { width:100%; max-width:100%; }
.chat-message-content-user { max-width:min(80%, 720px); }
.chat-avatar {
  width:36px;
  height:36px;
  min-width:36px;
  min-height:36px;
  display:flex;
  align-items:center;
  justify-content:center;
  border-radius: var(--radius);
  overflow:hidden;
  background:var(--avatar-color, #10a37f);
  background:linear-gradient(135deg, var(--avatar-color, #10a37f), color-mix(in srgb, var(--avatar-color, #10a37f) 64%, #111827));
  border:1px solid var(--border);
  border-color:color-mix(in srgb, var(--avatar-color, #10a37f) 36%, var(--border));
  box-shadow: var(--ombre-2);
  color:#fff;
}
.chat-message-ai > .chat-avatar { grid-column:1; justify-self:end; }
.chat-message-user > .chat-avatar { grid-column:3; justify-self:start; }
.chat-avatar-img,
.chat-avatar-logo {
  width:100%;
  height:100%;
  object-fit:cover;
  display:block;
}
.chat-avatar-logo { padding:var(--espace-3); object-fit:contain; }
.chat-avatar-emoji {
  font-size:var(--texte-9);
  line-height:1;
  font-weight:700;
}
.chat-avatar-settings {
  width:56px;
  height:56px;
  min-width:56px;
  min-height:56px;
  border-radius: var(--radius-xl);
}
.chat-avatar-settings .chat-avatar-emoji { font-size:var(--texte-12); }
.chat-actions {
  display:flex;
  flex-wrap:wrap;
  gap:var(--espace-2);
  margin-top:var(--espace-2);
  opacity:1;
  pointer-events:auto;
}
.chat-actions-user { justify-content:flex-end; }
.chat-actions-ai { justify-content:flex-start; align-items:center; }
.msg-action-chip {
  display:inline-flex;
  align-items:center;
  gap:var(--espace-2);
  min-height:28px;
  border-radius: var(--radius-sm);
  padding:var(--espace-2) var(--espace-4);
  font-size:var(--texte-2);
  color:var(--t-faint);
  border:1px solid transparent;
  transition: background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe), border-color var(--duree-2) var(--courbe);
}
.msg-action-chip:hover {
  color:var(--t-secondary);
  background:var(--bg-secondary);
  border-color:var(--border);
}
.img-action-btn {
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:26px;
  height:26px;
  border-radius: var(--radius-sm);
  font-size:var(--texte-3);
  background:rgba(0,0,0,.55);
  color:#fff;
  border:1px solid rgba(255,255,255,.15);
  cursor:pointer;
  backdrop-filter:blur(4px);
  transition: background var(--duree-2) var(--courbe);
}
.img-action-btn:hover { background:rgba(0,0,0,.75); }
.avatar-choice {
  width:34px;
  height:34px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  border-radius: var(--radius);
  background:var(--bg-input);
  border:1px solid var(--border);
  font-size:var(--texte-8);
  transition: transform var(--duree-1) var(--courbe), border-color var(--duree-1) var(--courbe);
}
.avatar-choice:hover { transform:translateY(-1px); border-color:var(--accent); }
.avatar-choice-active { outline:2px solid var(--accent); outline-offset:1px; }
.avatar-swatch {
  width:28px;
  height:28px;
  border-radius: var(--radius-rond);
  border:2px solid rgba(255,255,255,.75);
  box-shadow:0 0 0 1px var(--border);
}
.avatar-swatch-active { box-shadow:0 0 0 2px var(--accent); }
.crea-welcome-logo { box-shadow:0 12px 36px rgba(16,163,127,.12); }
/* Empty-state icon: scale SVG from icon size to ~40px */
.crea-icon-xl svg { width:40px; height:40px; }

@media (max-width:640px) {
  .chat-message-row { margin-bottom:var(--espace-7); }
  .chat-message-content-user { max-width:88%; }
  .chat-message-content-ai   { max-width:100%; }
  .msg-action-btn { width:26px; height:26px; }
  .msg-action-chip { min-height:26px; font-size:var(--texte-1); padding:var(--espace-2) var(--espace-3); }
}

/* --- Sidebar border glow on hover --- */
.sidebar-item:hover::before {
  content:''; position:absolute; left:0; top:20%; bottom:20%;
  width:2px; background:var(--accent); border-radius:0 2px 2px 0; opacity:.5;
}
.sidebar-item.active::before { opacity:1; }

/* Bouton microphone — pro, discret au repos, expressif quand actif */
.mic-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: var(--t-faint);
  transition:  all var(--duree-2) var(--courbe);
  flex-shrink: 0;
}
.mic-btn:hover {
  color: var(--t-secondary);
  background: rgba(0,0,0,0.06);
}
.mic-btn.mic-listening {
  color: #ef4444;
  background: rgba(239,68,68,0.1);
  animation: micPulse 1.5s ease-in-out infinite;
}
html.dark .mic-btn:hover { background: rgba(255,255,255,0.08); }
html.dark .mic-btn.mic-listening { background: rgba(239,68,68,0.15); }

/* LE MODE LIVE A LA MÊME FORME QUE LE MICRO, PARCE QUE C'EST LA MÊME NATURE.
   Il portait un disque rose plein en dégradé et un halo qui pulsait sans
   arrêt. Dans une barre où le « + », le micro et les onglets sont des traits
   sur du vide, c'était la seule chose qui criait — et elle criait tout le
   temps, y compris quand personne ne parle. Le dessin ne dit plus « regarde
   moi » ; il dit ce que fait le bouton, et le survol répond. */
.voice-mode-btn {
  color: var(--t-faint);
  background: transparent;
}
.voice-mode-btn:hover {
  color: var(--t-secondary);
  background: rgba(0,0,0,0.06);
}
html.dark .voice-mode-btn:hover { background: rgba(255,255,255,0.08); }

@keyframes micPulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(239,68,68,0.3); }
  50%      { box-shadow: 0 0 0 6px rgba(239,68,68,0); }
}

/* Rail d'icônes — mode réduit */
/* Quick studio buttons in sidebar */
.studio-quick-btn {
  background: rgba(0,0,0,0.03);
  border: 1px solid var(--border);
}
.studio-quick-btn:hover { background: rgba(0,0,0,0.07); }
html.dark .studio-quick-btn { background: rgba(255,255,255,0.04); }
html.dark .studio-quick-btn:hover { background: rgba(255,255,255,0.09); }
.studio-quick-active {
  background: rgba(16,163,127,0.12);
  border: 1px solid rgba(16,163,127,0.35);
}
html.dark .studio-quick-active { background: rgba(16,163,127,0.18); }

/* --- Chips actifs dans la toolbar input --- */
.input-chip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  transition: opacity .15s, transform .1s;
  font-size: var(--texte-4); border: 1px solid transparent;
}
.input-chip:hover { opacity: .75; transform: scale(1.05); }
.input-chip:active { transform: scale(.93); }
.input-chip-green  { background: rgba(34,197,94,.12);  color: #16a34a; border-color: rgba(34,197,94,.3); }
.input-chip-purple { background: rgba(139,92,246,.12); color: #7c3aed; border-color: rgba(139,92,246,.3); }
.input-chip-red    { background: rgba(239,68,68,.12);  color: #dc2626; border-color: rgba(239,68,68,.3); }
.input-chip-amber  { background: rgba(245,158,11,.12); color: #d97706; border-color: rgba(245,158,11,.3); }

/* --- Carousel infini des studios rapides --- */
.studio-carousel-wrap {
  mask-image: linear-gradient(to right, transparent 0%, black 12%, black 88%, transparent 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0%, black 12%, black 88%, transparent 100%);
}
.studio-carousel-track {
  display: flex;
  gap: var(--espace-3);
  width: max-content;
  animation: studio-scroll 22s linear infinite;
  cursor: default;
}
.studio-carousel-wrap:hover .studio-carousel-track {
  animation-play-state: paused;
}
@keyframes studio-scroll {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

.rail-btn {
  display:flex; align-items:center; justify-content:center;
  width:36px; height:36px; border-radius: var(--radius);
  color:var(--t-faint); transition: all var(--duree-2) var(--courbe); flex-shrink:0;
}
.rail-btn:hover { background:rgba(0,0,0,0.06); color:var(--t-secondary); }
.rail-btn svg { width:18px; height:18px; }
html.dark .rail-btn:hover { background:rgba(255,255,255,0.07); }

/* Icônes dans la sidebar pleine */
.sidebar-icon-btn {
  display:flex; align-items:center; justify-content:center;
  width:28px; height:28px; border-radius: var(--radius-sm);
  color:var(--t-faint); transition: all var(--duree-2) var(--courbe); flex-shrink:0;
}
.sidebar-icon-btn:hover { background:rgba(0,0,0,0.06); color:var(--t-secondary); }
.sidebar-icon-btn svg { width:16px; height:16px; }

/* --- CREA LM : badge Bibliothèque + bouton Retenir --- */
.crea-biblio-badge {
  display:inline-flex; align-items:center; gap:.3rem;
  font-size:.7rem; color:var(--t-dim); opacity:.72;
  margin-top:var(--espace-4); user-select:none;
  padding:.2rem .55rem; border-radius: var(--radius-rond);
  background:var(--accent-bg); border:1px solid rgba(16,163,127,.15);
  transition: opacity var(--duree-2) var(--courbe);
}
.crea-biblio-badge:hover { opacity:1; }

.crea-retenir {
  display:inline-flex; align-items:center; gap:.3rem;
  font-size:.7rem; color:var(--t-dim); opacity:.5;
  margin-top:var(--espace-3); padding:.2rem .55rem; border-radius: var(--radius-rond);
  background:none; border:1px solid var(--border); cursor:pointer;
  transition: all var(--duree-2) var(--courbe); font-family:inherit;
}
.crea-retenir:hover { opacity:.95; border-color:var(--accent); color:var(--accent); background:var(--accent-bg); }
.crea-retenir.retenu { opacity:.8; border-color:rgba(34,197,94,.3); color:var(--success); background:rgba(34,197,94,.06); cursor:default; }

/* Modèle maison 🌱 dans le sélecteur */
.model-maison { color:#22c55e; }
.model-maison-badge {
  display:inline-flex; align-items:center; gap:.25rem;
  font-size:.6rem; font-weight:600; color:#22c55e;
  background:rgba(34,197,94,.1); border:1px solid rgba(34,197,94,.2);
  border-radius: var(--radius-rond); padding:.1rem .45rem; margin-left:.3rem;
}

/* Items conversations */
.sidebar-item-hover:hover { background:rgba(0,0,0,0.05); }
.sidebar-item-active { background:rgba(0,0,0,0.08) !important; }
html.dark .sidebar-item-hover:hover { background:rgba(255,255,255,0.06); }
html.dark .sidebar-item-active { background:rgba(255,255,255,0.1) !important; }

/* Sidebar sombre façon référence (--rail-bg, cf. renderSidebar) : le noir sur noir
   de .hover\:bg-black\/5 est invisible sur ce fond plus sombre que --bg-secondary. */
.sidebar-dark { border-right:1px solid var(--rail-border); }
.sidebar-dark .hover\:bg-black\/5:hover { background:rgba(255,255,255,0.07) !important; }

/* Menu contextuel conversation / profil */
/* LES LIGNES DE MENU SONT RESSERRÉES D'UN CRAN — 10px de haut à 8px.
   Le menu du bloc compte s'ouvre VERS LE HAUT depuis le pied de la barre : sa
   hauteur ne se lit pas comme une longueur mais comme une montée, et il
   remontait jusqu'à 274px du haut d'un écran de 900. Trois entrées ont été
   retirées ou déplacées ; le cran de moins par ligne finit le travail sans
   toucher à la taille du texte ni à la surface cliquable, qui reste au-dessus
   du minimum tactile. */
.conv-menu-item {
  display:flex; align-items:center; gap:var(--espace-5);
  width:100%; padding:var(--espace-4) var(--espace-7);
  font-size:var(--texte-4); text-align:left;
  color:var(--t-secondary); transition: background var(--duree-1) var(--courbe);
}
.conv-menu-item:hover { background:rgba(0,0,0,0.05); }
/* LE TRAIT DE SÉPARATION NE TOUCHE PAS LES BORDS.
   Un <hr> pleine largeur coupe la carte en deux et se voit plus que ce qu'il
   sépare : il redessine le bord du menu à chaque groupe. Rentré de douze
   pixels, il fait ce qu'on lui demande — marquer une respiration — sans
   prétendre au statut de bordure. C'est ainsi que les menus soignés le font,
   et c'était le reproche : « les traits, ils ne vont pas au bout de chaque
   côté ». */
.conv-menu-sep {
  border: 0;
  border-top: 1px solid var(--border);
  margin: var(--espace-2) var(--espace-6);
}
html.dark .conv-menu-item:hover { background:rgba(255,255,255,0.06); }
.conv-menu-item svg { width:16px; height:16px; flex-shrink:0; opacity:.7; }
.conv-menu-danger { color:#ef4444; }
.conv-menu-danger:hover { background:rgba(239,68,68,0.08); }
.conv-menu-btn:hover { background:rgba(0,0,0,0.08); }
html.dark .conv-menu-btn:hover { background:rgba(255,255,255,0.1); }

/* LE TRAIT DE LA RÉFÉRENCE — 1,5 ET NON 2.
 *
 * Les icônes du dépôt sont dessinées en 2 ; celles des captures sont en 1,5.
 * C'est la différence entre un panneau qui pèse et un panneau qui respire, et
 * c'est ce qui se voit d'abord quand on met les deux écrans côte à côte.
 *
 * Une règle, pas cent icônes redessinées : `stroke-width` posé en CSS l'emporte
 * sur l'attribut de présentation écrit dans le SVG, donc les deux répertoires
 * (I.* et _icon()) s'alignent d'un coup — et sans toucher au reste de
 * l'application, qui garde son trait. Le sélecteur descend jusqu'aux enfants :
 * un <path> qui porte son propre stroke-width ne l'écouterait pas autrement.
 *
 * Les bouts arrondis viennent de la même comparaison : la référence n'a pas un
 * seul angle vif au bout d'un trait. */
.settings-modal svg, .settings-modal svg * {
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Le logo de marque et les avatars ne sont pas des icônes au trait : les amincir
 * les abîmerait. */
.settings-modal img, .settings-modal .avatar-choice svg { stroke-width: initial; }

/* LA RANGÉE DE MÉMOIRE RESTE PROPRE JUSQU'À CE QU'ON L'APPROCHE.
 * La référence ne montre aucun bouton dans ses listes : le verbe apparaît au
 * survol. Sans ça, une corbeille rouge sur chaque ligne fait lire la page
 * comme un écran de suppression au lieu d'un écran de lecture. Au clavier, le
 * focus l'appelle aussi — sinon le verbe serait inatteignable sans souris. */
.crea-mem-verbe { opacity: 0; transition: all var(--duree-1) var(--courbe); }
.crea-mem-rangee:hover .crea-mem-verbe,
.crea-mem-verbe:focus-within { opacity: 1; }
@media (hover: none) { .crea-mem-verbe { opacity: 1; } }

/* MOUVEMENT RÉDUIT — LE RÉGLAGE AGIT VRAIMENT.
 *
 * CREA respectait déjà `prefers-reduced-motion`, mais sans laisser choisir :
 * qui trouvait l'interface trop remuante devait aller changer un réglage de
 * son système d'exploitation. La référence propose « Système / Réduit », et
 * ce choix doit AGIR — on a retiré trois interrupteurs aujourd'hui parce
 * qu'ils ne faisaient rien.
 *
 * On ne met pas 0s : une durée nulle supprime les événements transitionend,
 * dont du code dépend parfois pour enchaîner. 1ms est instantané à l'œil et
 * laisse les événements partir.
 *
 * Le curseur qui clignote au bout d'une réponse en cours d'écriture est
 * épargné : ce n'est pas une décoration, c'est ce qui dit « ça continue ». */
html.crea-mouvement-reduit *,
html.crea-mouvement-reduit *::before,
html.crea-mouvement-reduit *::after {
  animation-duration: 1ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 1ms !important;
  scroll-behavior: auto !important;
}
html.crea-mouvement-reduit .crea-curseur-frappe {
  animation-duration: 1s !important;
  animation-iteration-count: infinite !important;
}

/* Onglet paramètres actif */
.settings-tab-active { background:rgba(16,163,127,0.1) !important; }
html.dark .settings-tab-active { background:rgba(16,163,127,0.15) !important; }

/* Boutons d'action sur messages (comme ChatGPT) */
.msg-action-btn {
  display:flex; align-items:center; justify-content:center;
  width:30px; height:30px; border-radius: var(--radius-sm);
  color:var(--t-dim); transition: all var(--duree-1) var(--courbe);
}
.msg-action-btn:hover { background:rgba(0,0,0,0.06); color:var(--t-secondary); }
html.dark .msg-action-btn:hover { background:rgba(255,255,255,0.08); }
.msg-action-btn svg { width:15px; height:15px; }
.msg-action-active { color:var(--accent) !important; }

/* Mode voix — orbe animé */
.voice-orb-wrap { position:relative; width:160px; height:160px; display:flex; align-items:center; justify-content:center; }
.voice-orb {
  width:120px; height:120px; border-radius:50%;
  background:radial-gradient(circle at 35% 35%, #34c4a0, #10a37f 60%, #0a7a5e);
  box-shadow:0 0 60px rgba(16,163,127,0.4);
  transition: transform var(--duree-3) var(--courbe);
}
.voice-orb-active { animation:orbPulse 1.4s ease-in-out infinite; }
@keyframes orbPulse {
  0%,100% { transform:scale(1); box-shadow:0 0 60px rgba(16,163,127,0.4); }
  50%      { transform:scale(1.12); box-shadow:0 0 90px rgba(16,163,127,0.65); }
}
.voice-ring {
  position:absolute; inset:0; border-radius:50%;
  border:2px solid rgba(16,163,127,0.25);
}
.voice-ring-1 { animation:ringExpand 2.4s ease-out infinite; }
.voice-ring-2 { animation:ringExpand 2.4s ease-out infinite .8s; }
.voice-ring-3 { animation:ringExpand 2.4s ease-out infinite 1.6s; }
@keyframes ringExpand {
  0%   { transform:scale(0.75); opacity:.8; }
  100% { transform:scale(1.5);  opacity:0; }
}

/* .voice-pulse ET @keyframes voicePulse ÉTAIENT DÉCLARÉS DEUX FOIS.
   Ligne 455, la bonne version : opacity et transform, « composite-only, pas de
   repaint » — c'est écrit juste au-dessus. Ici, quatre-vingt-dix lignes plus
   bas, une seconde déclaration en box-shadow, qui gagnait par l'ordre de la
   feuille. L'optimisation était donc annulée par sa propre copie, en silence,
   et le halo rose n'était plus le halo qu'on croyait avoir écrit.
   Une seule déclaration, celle du haut. Ce qui reste porte .voice-pulse : les
   pastilles d'état du mode vocal, où un battement d'opacité est juste et où un
   anneau de 8 px déborderait d'un point de 8 px. */

.anim-fade-up { animation: fadeUp 0.4s ease-out; }
@keyframes fadeUp {
  0% { opacity:0; transform: translateY(8px); }
  100% { opacity:1; transform: translateY(0); }
}

/* Points de saisie (IA avenante en train d'écrire) */
.typing-dot {
  width:7px; height:7px; border-radius:50%;
  background:var(--accent);
  display:inline-block;
  animation: typingBounce 1.3s ease-in-out infinite;
}
.typing-dot:nth-child(2) { animation-delay:.18s; }
.typing-dot:nth-child(3) { animation-delay:.36s; }
@keyframes typingBounce {
  0%, 60%, 100% { transform: translateY(0); opacity:.4; }
  30% { transform: translateY(-5px); opacity:1; }
}

/* Bannière nouveauté */
.banner-new {
  display:flex; align-items:center; gap:var(--espace-5);
  padding:var(--espace-4) var(--espace-8); font-size:var(--texte-4);
  background:linear-gradient(90deg, rgba(16,163,127,0.08), rgba(52,196,160,0.04));
  border-bottom:1px solid var(--border);
}

/* Welcome centré dans le scroll area */
#messages-container:has(> div.flex) {
  display:flex; flex-direction:column;
}

/* ============================================================
 * MICRO-INTERACTIONS VIVANTES — le site « respire », premium et tactile.
 * Global mais sûr : transitions (n'affectent pas la mise en page) + feedback
 * d'appui momentané. Les classes Tailwind plus spécifiques gardent la priorité.
 * ============================================================ */
/* transform retiré du global — causait des repaints sur tous les boutons en continu */
button { transition:  background-color var(--duree-1) var(--courbe), border-color var(--duree-1) var(--courbe), color var(--duree-1) var(--courbe), opacity var(--duree-1) var(--courbe); }
button:not([disabled]):active { transform: scale(.97); transition: transform var(--duree-1) var(--courbe); }
a { transition:  color var(--duree-2) var(--courbe), opacity var(--duree-2) var(--courbe), background-color var(--duree-2) var(--courbe); }

/* Items de barre latérale : léger glissement vivant au survol */
.sidebar-item-hover { transition:  background-color var(--duree-2) var(--courbe); }

/* Puces d'action & chips : douceur */
.msg-action-chip, .file-chip { transition: all var(--duree-2) var(--courbe); }
.file-chip:hover { transform: translateY(-1px); }

/* Toasts : ombre colorée selon le type (plus vivant) */

/* Apparition douce des cartes média de la Médiathèque */
.media-card, [data-mode] { will-change: transform; }

/* Respiration discrète de l'accent (badges « live ») */
@keyframes creaBreathe { 0%,100%{ opacity:.85 } 50%{ opacity:1 } }
.crea-live-dot { animation: creaBreathe 2.4s ease-in-out infinite; }

/* LE BALAYAGE LUMINEUX DU PORTAIL EST PARTI AVEC LE PORTAIL. La liste des
   studios ne se dessine plus en tuiles à dégradé animé : voir renderStudioPortal
   et .portail-studio plus bas. Une règle sans balise à qui l'appliquer se lit
   comme une mise en forme qui existe encore. */

/* L'orbe de la barre (logo vivant) respire au repos */
.crea-logo-live { transition:  filter var(--duree-3) var(--courbe), transform var(--duree-3) var(--courbe); }
.crea-logo-live:hover { transform: scale(1.05); }

/* Accessibilité + premium : anneau de focus CLAVIER net (jamais à la souris),
 * teinté par l'univers du studio courant. Purement additif (rien retiré). */
:focus-visible { outline: 2px solid var(--crea-universe, var(--accent, #10a37f)); outline-offset: 2px; border-radius: var(--radius-xs); }
input:focus-visible, textarea:focus-visible, select:focus-visible, [contenteditable="true"]:focus-visible {
  outline: none; box-shadow: 0 0 0 2px var(--crea-universe, var(--accent, #10a37f));
}

/* Respect des préférences d'accessibilité : on coupe les animations si demandé */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; }
}

/* ── LES BOUTONS SYSTÈME SONT DANS LA PAGE, ET ILS PRENNENT DE LA PLACE ──────
   Sur Windows la fenêtre de bureau n'a pas de cadre : réduire / agrandir /
   fermer sont peints PAR-DESSUS le haut de la page, à droite. Rien ne le dit au
   document — pour lui, la page commence à zéro.

   En temps normal la barre de fenêtre (#crea-electron-titlebar) occupe ces
   36 px et pousse l'application d'autant : personne ne passe dessous. Mais si
   elle ne se construit pas, l'en-tête remonte tout en haut et ses boutons de
   droite — éphémère, [⋯] — finissent SOUS les trois boutons système. On les
   voit à moitié, on clique à côté, et rien n'indique pourquoi.

   Cette règle est le repli, et elle ne coûte rien quand la barre est là (le
   :not l'éteint). 138 px = la largeur des trois boutons Windows, plus une
   marge : elle ne dépend pas d'un thème, seulement de la fenêtre. */
body.crea-electron-win:not(.crea-electron-titlebar) #app-header { padding-right: 138px; }

/* ============================================================
 * CREA VISUAL POLISH — layout harmony, icons, typography
 * ============================================================ */

/* ── 1. SIDEBAR / WORKSPACE BORDER ────────────────────────────────────────
   LE TRAIT PORTE MAINTENANT TOUTE LA SÉPARATION, DONC IL SE VOIT.

   « Comme on a mis une couleur homogène, on ne voit plus la ligne de séparation
    de la barre latérale. Il faut bien la faire. »

   C'est mon défaut, et il vient d'un raisonnement à moitié fait. En unifiant la
   barre sur le fond de l'espace chat, j'ai écrit que « ce qui sépare n'est plus
   la couleur mais le liseré » — sans regarder ce liseré. Il valait 60 % de
   --border, une atténuation qui n'avait de sens que TANT QUE la couleur faisait
   le gros du travail. La couleur partie, il ne restait qu'un trait fantôme.

   Le trait est donc plein. « Doux » se règle par la valeur de --border, qui est
   déjà discrète dans les deux thèmes — pas en effaçant à moitié ce qui est
   devenu la seule frontière.

   ET IL EST DANS LA BARRE, PAS À CÔTÉ. Deuxième signalement : « je t'ai demandé
   de lui remettre son trait, il n'y est pas, il est transparent. » Exact, et
   deux fois de suite j'avais corrigé la COULEUR d'un trait qui n'était pas
   peint du tout.

   Mesuré au pixel, capture d'écran à l'appui : la barre s'arrête à x=264, la
   règle calculait bien `rgb(213,213,213) 1px 0 0 0`… et le pixel 264 valait
   (252,252,252), le fond de la page. Une ombre externe se pose HORS de la boîte,
   donc sur le territoire du voisin — et le voisin, peint après, la recouvrait.
   Elle était présente dans la feuille de style et absente de l'écran.

   Une bordure, elle, est DANS la boîte : elle est peinte avec la barre, et le
   voisin commence après. Rien ne peut passer par-dessus. C'est la même ligne,
   au même endroit, mais à un pixel qui lui appartient. */
#sidebar {
  border-right: 1px solid var(--sidebar-trait, var(--border)) !important;
  box-shadow: none;
}
/* ...SAUF SUR MOBILE, où ce trait est précisément « la ligne ».
   Elle longe toute la hauteur de la barre et CONTINUE TOUT DROIT là où la carte
   s'incurve — donc elle traverse la courbe et casse l'emboîtement.
   Sur mobile la séparation est déjà faite par la carte elle-même : elle est
   plus claire que la barre (~20 niveaux, la valeur de la référence) et son
   bord porte la courbe. Ce trait n'ajoute rien, il ne fait que la barrer. */
@media (max-width: 768px) {
  #sidebar { border-right: none !important; box-shadow: none !important; }
}

/* ── 2. INNER BORDER-RADIUS — workspace comme une carte posée sur le rail ── */
/* L'outer row prend la couleur du rail pour que le radius "creux" soit visible.

   ELLE NE VISE QUE LA RANGÉE QUI CONTIENT VRAIMENT LE PLAN DE TRAVAIL.
   « Sur la page d'inscription il y a un gros bloc gris qui vient s'afficher
    derrière les blocs d'inscription et le bloc d'image qui défile. »

   Mesuré dans un vrai navigateur : 1440 × 765 en #F6F6F6, sans aucun style
   dans le HTML. La règle ne désignait rien de particulier — elle attrapait
   TOUT élément portant ces quatre classes utilitaires, et les écrans de
   connexion et d'inscription portent exactement les mêmes. Ils héritaient donc
   du fond destiné au rail, derrière le formulaire et le diaporama.

   Sélectionner par classes utilitaires, c'est peindre par coïncidence de noms.
   Le `:has()` rétablit l'intention : cette rangée-ci, celle qui contient le
   plan de travail — et elle seule. */
.crea-plan-travail {
  /* LE SOL SUR LEQUEL LES CARTES SE POSENT — ET IL EST DEVENU VISIBLE.
     Il valait --bg-secondary, et ça n'avait aucune conséquence tant que les
     barres et les panneaux touchaient leurs voisins : on n'en voyait rien.
     Maintenant qu'ils sont détachés des quatre côtés, ce sol se voit dans
     chaque écart — et --bg-secondary contre --bg-primary, c'est une bande
     grise autour de chaque carte. Mesuré en clair : 246 contre 252.
     C'est exactement le défaut déjà corrigé sur le tiroir des panneaux de
     droite, et par le même geste : « sans ça, l'écart montre --bg-secondary,
     ce qui fabrique un cadre plein autour de chaque carte. Au même fond que
     les cartes, il ne reste que le filet et l'ombre. »
     Ce que ça retire : l'effet de rayon « creux » du plan de travail, qui
     demandait un sol d'une autre couleur pour se voir. C'est le prix, et il
     est voulu — cet effet était précisément ce qui donnait l'air « collé ». */
  background: var(--bg-primary);
}
/* Le workspace principale est une carte avec arrondis en haut-gauche/bas-gauche */
/* NOTE : #main-workspace n'existe dans AUCUN fichier de l'application — ni dans
   src/app.js, ni dans le HTML. Cette règle n'a donc jamais rien peint. Elle est
   laissée telle quelle plutôt que supprimée à l'aveugle : c'est peut-être un
   identifiant prévu et jamais posé. Mais elle ne compte pas comme un acquis. */
#main-workspace {
  border-top-left-radius: 14px;
  border-bottom-left-radius: 14px;
  overflow: hidden;
  /* Légère élévation pour détacher la carte du rail */
  background: var(--bg-primary);
}

/* ── 3. SUPPRESSION DES SÉPARATEURS INTRUSIFS ── */
/* Retirer le border-top entre sections dans le chat/studios */
.crea-composer-bar {
  border-top: none !important;
}
/* Messages container — pas de séparateur en haut */
#messages-container {
  border-top: none !important;
}

/* ── 4. CONFIRMATION BUTTON ANIMATION (remplace les toasts) ── */
@keyframes btnConfirm {
  0%   { transform:scale(1); }
  30%  { transform:scale(.88); }
  60%  { transform:scale(1.08); }
  100% { transform:scale(1); }
}
.btn-confirm-flash {
  animation: btnConfirm .32s cubic-bezier(.34,1.56,.64,1);
  color: #10a37f !important;
  border-color: #10a37f !important;
}

/* ── 5. ICÔNES MESSAGE — plus grandes, plus lisibles ── */
.msg-action-chip {
  font-size: var(--texte-3) !important;
  padding: var(--espace-2) var(--espace-4) !important;
  gap: var(--espace-3) !important;
}
.msg-action-chip svg {
  width: 13px !important;
  height: 13px !important;
}

/* ── 6. TYPOGRAPHIE — plus ancrée, moins pâle ── */
/* t-dim trop pâle sur fond dark → légèrement remontée */
:root {
  --t-dim: color-mix(in srgb, var(--t-secondary) 70%, var(--t-faint) 30%);
}
/* Corps du message AI — taille lisible garantie */
.msg-content {
  font-size: var(--texte-5) !important;
  line-height: 1.65 !important;
  color: var(--t-primary) !important;
}
/* Metadata sous les messages (model, tokens) — présent mais discret */
.msg-content + p[class*="opacity-40"] {
  opacity: .5 !important;
}
/* Labels et captions dans la sidebar — pas trop pâles */
.sidebar-item-hover,
.sidebar-item-active {
  font-size: var(--texte-4);
}

/* ── 7. SCROLL — premier message ancré en HAUT, messages multiples en BAS ── */
/* overflow-anchor guide déjà le comportement.
   On ajoute align-items:flex-start pour que le 1er message colle au haut */
#messages-container {
  display: flex;
  flex-direction: column;
}

/* ── 8. ICÔNE PROFIL (rail) — plus grande et lisible ── */
#btn-user-rail {
  width: 34px !important;
  height: 34px !important;
  font-size: var(--texte-4) !important;
  font-weight: 700 !important;
}

/* ── 9. ICONS RAIL — légèrement plus grandes ── */
.rail-btn svg {
  width: 18px !important;
  height: 18px !important;
}

/* ── 10. SUPPRESSION des borders top/bottom superflus dans les studios ── */
/* Barre de fichiers des studios */
[style*="border-bottom:1px solid var(--border)"][class*="shrink-0"],
[style*="border-top:1px solid var(--border)"][class*="shrink-0"] {
  border-color: color-mix(in srgb, var(--border) 50%, transparent) !important;
}

/* ── ...ET PLUS UN SEUL TRAIT DANS UN PANNEAU LATÉRAL ──────────────────────
   « Tu as mis une ligne pour séparer le travail en arrière-plan. Arrête de
    mettre des traits partout. Regarde comment c'est écrit en haut : en tout
    petit, de manière simple, pour laisser le plein de la page. »

   Cette règle est ICI, juste après celle du § 10 ci-dessus, et pas avec le
   reste du style des panneaux — parce que celle du § 10 est en !important et
   la vise. Entre deux déclarations !important, c'est la spécificité qui
   tranche, puis l'ordre : `.crea-panneau-carte > *[style]` pèse une classe et
   un attribut, exactement comme `[style*=…][class*=…]`. À égalité, c'est la
   dernière écrite qui gagne. La remonter de trois cents lignes la ferait
   perdre, sans rien changer d'autre — d'où ce commentaire, pour qu'un futur
   rangement par thème ne la déplace pas par propreté.

   On ne vise que les enfants DIRECTS : ce sont exactement les zones de
   structure du panneau (titre, onglets, corps, pied). Le contenu — cartes de
   tâche, blocs de code, tableaux — est plus bas dans l'arbre et garde ses
   bordures, qui sont des objets et pas des séparations.

   Et c'est la COULEUR qui passe à transparent, pas la bordure qui passe à
   none : le pixel reste réservé, donc aucune zone ne se décale d'un cran. */
.crea-panneau-carte > *[style],
.crea-panneau-carte--seule > *[style] {
  border-top-color: transparent !important;
  border-bottom-color: transparent !important;
}

/* ── Menu "⋯" actions secondaires messages ── */
.msg-more-menu {
  position:absolute; bottom:34px; left:0; z-index:9000;
  min-width:188px; background:var(--bg-secondary);
  border:1px solid var(--border-hov); border-radius: var(--radius);
  box-shadow: var(--ombre-3); padding:var(--espace-2);
  flex-direction:column; gap:var(--espace-1);
  animation:fadeIn .12s ease;
}
.msg-more-menu .msg-action-btn {
  width:100% !important; height:auto !important; justify-content:flex-start !important;
  gap:var(--espace-4); padding:var(--espace-3) var(--espace-5); border-radius: var(--radius-sm); font-size:var(--texte-3);
  color:var(--t-secondary) !important; text-align:left;
}
.msg-more-menu .msg-action-btn:hover { background:var(--bg-hover,rgba(0,0,0,.06)); color:var(--t-primary) !important; }
.msg-more-menu .msg-action-btn svg { flex-shrink:0; }
.msg-more-menu hr { border:none; border-top:1px solid var(--border); margin:var(--espace-2) 0; }
.msg-more-label { display:none; }

/* --- Indicateur de génération visible --- */
.crea-gen-indicator{display:flex;align-items:center;gap:var(--espace-3);padding:var(--espace-3) 0 var(--espace-1)}
.crea-gen-pulse{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--accent,#10a37f);animation:crea-gen-bounce .9s ease-in-out infinite}
@keyframes crea-gen-bounce{0%,100%{transform:translateY(0);opacity:.5}50%{transform:translateY(-5px);opacity:1}}
.crea-gen-label{font-size:var(--texte-3);color:var(--t-faint,#888);margin-left:var(--espace-2);letter-spacing:.02em}

/* ===================================================================
   MOBILE FIXES — crea-ai (< 640px) — correctifs visuels profonds
   =================================================================== */
@media (max-width: 639px) {

  /* HEADER : cacher les boutons secondaires sur mobile */
  /* Sur mobile on garde SEULEMENT : Partager, Nouveau chat, Suivi CREA, ⋯ */
  #btn-work-panel,
  #btn-bgtasks-panel,
  #btn-preview-chat { display: none !important; }

  /* Bascule Chat / Work : retirée sur mobile, uniquement. Le groupe entier et
     pas seulement les deux boutons, sinon il resterait un conteneur vide dans
     la rangée. Desktop et grandes surfaces la gardent : la règle est bornée à
     ce media query, comme les boutons ci-dessus. */
  [data-bar-mode-group] { display: none !important; }

  /* ACCUEIL : rien sous la barre de questions, et la barre descend tout en bas.
     Les pastilles de suggestions (Parler / Apprendre / …) disparaissent sur
     téléphone ; elles restent sur desktop, cette règle étant bornée ici. */
  #welcome-suggestions { display: none !important; }

  /* La barre au ras du bas : seul le retrait de la barre d'accueil du système
     est conservé, sinon elle serait sous le doigt. Les marges auto du bloc de
     salutation absorbent l'espace libre, ce qui garde la salutation centrée
     au-dessus au lieu de la coller à la barre. */
  #welcome-screen {
    justify-content: flex-start !important;
    /* Même bas EXACTEMENT que la barre du chat : les deux barres de saisie
       doivent s'arrêter à la même ligne, sinon passer de l'accueil au fil
       fait sauter la barre. Valeur unique : --crea-composer-bottom. */
    padding-bottom: var(--crea-composer-bottom, 6px) !important;
  }
  /* L'accueil remplit #messages-container (min-h-full) : la respiration de
     1rem du conteneur le poussait vers le haut au lieu de séparer un dernier
     message d'une barre. Sur l'accueil il n'y a ni l'un ni l'autre. */
  #messages-container:has(#welcome-screen) { padding-bottom: 0 !important; }
  #welcome-greeting { margin-top: auto !important; margin-bottom: auto !important; }
  #welcome-input-wrap { margin-top: 0 !important; margin-bottom: 0 !important; }

  /* SIDEBAR SEARCH : compact sur mobile — évite de toucher les boutons voisins */
  #sidebar-search {
    padding-top: var(--espace-4) !important;
    padding-bottom: var(--espace-4) !important;
    font-size: var(--texte-4) !important;
    /* `--radius` est LE palier des champs — son commentaire le dit à la ligne
       où il est déclaré. Quatorze pixels étaient deux de plus, pour personne. */
    border-radius: var(--radius) !important;
  }

  /* SIDEBAR ITEMS : aligner à gauche (bug centrage sessions) */
  .sidebar-item,
  .sidebar-item-hover,
  .sidebar-item-active { text-align: left !important; justify-content: flex-start !important; }

  /* Session titles : tronquer proprement */
  [data-conv-id] .truncate,
  [data-conv-sheet] .truncate { max-width: calc(100vw - 120px); }

  /* SIDEBAR BUTTONS : éviter le shrink sur petits écrans */
  #btn-sidebar-studios, #btn-sidebar-espaces {
    min-width: 0;
    font-size: var(--texte-2) !important;
    padding-left: var(--espace-4) !important;
    padding-right: var(--espace-4) !important;
  }

  /* Studio mode toggles : keep natural size on mobile */

  /* RAIL SIDEBAR : éviter overflow sur mobile */
  #rail-sidebar { overflow-x: hidden !important; }
}

/* < 380px — très petits écrans */
@media (max-width: 380px) {
  #btn-sidebar-studios span:not(.emoji),
  #btn-sidebar-espaces span:not(.emoji) { display: none !important; }
  #btn-sidebar-studios, #btn-sidebar-espaces { min-width: 42px; justify-content: center; }
}

/* =====================================================================
   MOBILE GLASSMORPHISM HEADER + LAYOUT ADAPTATIF
   Normes : iPhone SE (375) → iPhone 16 Pro Max (430), Android 360-430px
   ===================================================================== */

/* --- Header vitre transparente (mobile uniquement) ------------------- */
@media (max-width: 639px) {
  /* Le header sort du flux et flotte EN HAUT → les messages défilent DERRIÈRE */
  /* overflow-x:clip ne crée PAS de stacking context → backdrop-filter fonctionne */
  /* main n'a plus besoin de position:relative car le header est fixed (pas absolute) */
  main { overflow-x: clip !important; }

  /* --- LA SURFACE MONTE JUSQU'AU BORD DE L'ÉCRAN ---------------------
     Mesuré sur la référence : le fond de la barre latérale y est uniforme
     depuis y=0, sans aucune rupture sous l'horloge. Sur la capture de CREA
     il y avait au contraire une bande de 62px en --bg-primary au-dessus du
     tiroir en --bg-secondary : 62px, c'est exactement le retrait système de
     l'appareil. Deux filets, parce que la cause peut venir d'ailleurs que
     de cette feuille.

     1) Aucun retrait haut sur #app. La règle qui en mettait un a déjà été
        retirée de crea-adapt.js, mais elle y avait été réintroduite une fois
        par une autre session : ce !important la neutralise pour de bon. */
  #app { padding-top: 0 !important; }

  /* 2) Fond continu. Tiroir ouvert, la racine prend la MÊME couleur que le
        tiroir : s'il subsiste un décalage en haut, il devient invisible au
        lieu de dessiner une bande. Même principe que l'arrondi entre le
        tiroir et la carte — la continuité, pas le contraste.
        La classe est posée par render() sur <html> : body:has(.sb-drawer-open)
        a été essayé et mesuré non appliqué, le :has() ne se réinvalidant pas
        de façon fiable sur une classe posée profond après un innerHTML. */
  html.crea-tiroir-ouvert body,
  html.crea-tiroir-ouvert #app { background: var(--bg-secondary) !important; }

  #app-header {
    /* FIXED → ne bouge PAS quand le clavier virtuel ouvre/ferme */
    position: fixed !important;
    /* Retrait système ENTIER. Ce qui doit monter jusqu'au bord de l'écran,
       c'est la SURFACE (le fond, plus bas), pas les boutons : mesuré sur la
       référence, l'encre du titre y commence à 76px alors que le retrait en
       vaut 62 — le contenu reste franchement sous l'horloge. En reprendre
       14px plaçait un bouton de 44px à 52-96px, donc à cheval sur l'horloge
       (dont l'encre s'arrête à 51px). */
    top: env(safe-area-inset-top, 0px) !important;
    left: 0 !important; right: 0 !important;
    z-index: 20 !important;
    background: transparent !important;
    border-bottom: none !important;
    height: 48px !important;
    min-height: 48px !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    transition:  opacity var(--duree-2) var(--courbe) !important;
    overflow: visible !important;
  }

  /* Messages démarrent sous le header fixe (hauteur + safe-area notch) */
  #messages-container { padding-top: calc(52px + env(safe-area-inset-top, 0px)) !important; }

  /* touch-action:manipulation supprime le délai 300ms sur iOS Safari */
  button, [onclick], a, .conv-menu-item, [role="button"] {
    touch-action: manipulation !important;
  }

  /* --- BOUTONS DE L'EN-TÊTE : vraie cible tactile -----------------------
     Mesuré sur 440px : #btn-burger faisait 18×48. Il est dans une colonne de
     grille en minmax(0,1fr) au milieu de plusieurs boutons, et c'est lui que
     le flex a écrasé — 18px de large pour la commande la plus utilisée de
     l'en-tête. Les onglets Réponse/Liens/Images/Actualités/Vidéos/Labs, eux,
     faisaient 37×33 : sous les 44px partout.
     La hauteur monte à 44 pour tous (l'en-tête en fait 52, c'est gratuit).
     La largeur n'est forcée QUE sur les boutons-icônes isolés : forcer 44 sur
     les six onglets ajouterait 42px à une rangée qui remplit déjà l'écran. */
  #app-header button { min-height: 44px; }
  #btn-burger, #btn-burger-studio,
  #btn-search-nav, #btn-search-nav-studio,
  #btn-notif-nav, #btn-notif-nav-studio,
  #btn-top-menu, #btn-new-chat-barre, #btn-ephemeral, #btn-categories-menu {
    min-width: 44px;
    flex-shrink: 0;
  }

  /* --- BARRE DE QUESTION DE L'ACCUEIL : même largeur que celle du chat ---
     Mesuré : la barre du fil fait 440px sur 440 (bord à bord), celle de
     l'accueil 408 — les 16px de px-4 de #welcome-screen de chaque côté. Deux
     largeurs pour la même barre, et la plus visible était la plus étroite. */
  #welcome-screen { padding-left: 0 !important; padding-right: 0 !important; }
  #welcome-greeting { padding-left: var(--espace-8); padding-right: var(--espace-8); }

  /* Filet : la deuxième ligne est raccourcie côté JS (sousTitreAccueil), mais
     elle reprend parfois un titre de conversation, donc sa longueur n'est
     jamais garantie. whitespace-nowrap la faisait alors sortir de l'écran,
     coupée net. Elle passe à la ligne plutôt que d'être tronquée — deux lignes
     lisibles valent mieux qu'une phrase amputée. */
  #welcome-subtitle {
    white-space: normal !important;
    text-wrap: balance;
    max-width: 100%;
  }

  /* Welcome screen */
  #welcome-greeting, #welcome-input-wrap { margin-top: 0; }
  #app-header .flex.items-center { height: 48px; }
}

/* --- Stats de génération : masquées sur mobile (données internes) ----- */
@media (max-width: 639px) {
  /* La ligne "· ~78 tok · 6.3s · 12 tok/s · 13:05" est invisible */
  .mt-1.text-\[10px\].opacity-40 { display: none !important; }
}

/* --- Sidebar mobile : overlays Studios / Espaces compacts ------------- */
@media (max-width: 639px) {
  /* Cards dans l'overlay Espaces/Studios : padding réduit */
  #espaces-overlay .anim-scale-in > div:last-child > button,
  #studios-overlay .anim-scale-in > div:last-child > button {
    padding: var(--espace-5) !important;
    gap: var(--espace-3) !important;
  }
  /* Grille : 2 colonnes mini sur petits écrans */
  #espaces-overlay [style*="grid-template-columns"],
  #studios-overlay [style*="grid-template-columns"] {
    grid-template-columns: repeat(2, 1fr) !important;
    gap: var(--espace-4) !important;
    padding: var(--espace-6) !important;
  }
  /* Icônes dans les cards : plus petites */
  #espaces-overlay .anim-scale-in span[style*="width:36px"],
  #studios-overlay .anim-scale-in span[style*="width:36px"] {
    width: 28px !important; height: 28px !important;
  }
  /* Boutons Studios + Espaces dans sidebar header */
  #btn-sidebar-studios, #btn-sidebar-espaces {
    font-size: var(--texte-3) !important;
    padding: var(--espace-3) var(--espace-4) !important;
  }
  /* Folder items dans sidebar : taille cohérente */
  [data-folder-filter] { min-height: 36px !important; }
  [data-folder-filter] .text-\[13px\] { font-size: var(--texte-4) !important; }
}

/* --- Logo CREA : svg propre, pas d'écrasement ------------------------- */
img.crea-logo-live, img[alt="CREA"], img[alt="Créa"] {
  object-fit: contain !important;
  display: block !important;
}

/* --- Layout adaptatif : hauteur disponible par profil d'écran -------- */
/* Les valeurs ci-dessous couvrent les écrans les plus courants 2024-2026 :
   iPhone SE (667px), iPhone 14/15 (844px), Pro Max (926px), Android (800-900px) */

/* Petit téléphone ≤ 680px de haut → moins d'espace → composer plus compact */
@media (max-width: 639px) and (max-height: 680px) {
  .crea-composer-bar { padding-top: var(--espace-2) !important; padding-bottom: var(--crea-composer-bottom, 6px) !important; }
  #app-header { height: 44px !important; min-height: 44px !important; }
  #messages-container { padding-top: calc(48px + env(safe-area-inset-top, 0px)) !important; }
}

/* Téléphone standard ≥ 750px → espace normal */
@media (max-width: 639px) and (min-height: 750px) {
  #app-header { height: 52px !important; min-height: 52px !important; }
  #messages-container { padding-top: calc(56px + env(safe-area-inset-top, 0px)) !important; }
}

/* --- Barre de saisie collée au bas absolu du téléphone ---------------
   Une seule valeur, --crea-composer-bottom (définie plus haut, et redéfinie à
   l'identique par crea-adapt.js), pour TOUTES les tailles d'écran. Il y avait ici trois valeurs concurrentes selon
   la hauteur (12px, 8px, 4px) qui se battaient avec celle de crea-adapt : la
   dernière chargée gagnait de toute façon, et les autres n'étaient que du
   bruit trompeur. La hauteur d'écran ne change pas où est la barre d'accueil
   du système ; elle n'a donc pas à changer ce retrait. */
@media (max-width: 639px) {
  .crea-composer-bar {
    padding-bottom: var(--crea-composer-bottom, 6px) !important;
  }
  /* Clavier ouvert : le retrait système ne s'applique plus, le clavier occupe
     déjà le bas de l'écran. */
  html.crea-kb-open .crea-composer-bar {
    padding-bottom: var(--espace-1) !important;
  }
}

/* --- Boutons header secondaires masqués sur mobile ---------------------
   Ne reste ici que Suivi de tâche : Tâches arrière-plan, Preview et Fichiers
   ne sont plus DU TOUT dans l'en-tête (ils vivent dans le menu ⋯, bloc
   « Outils » de convMenuItems) et le Mode focus est supprimé. Masquer des
   boutons qui n'existent plus ne servait à rien. */
@media (max-width: 639px) {
  #btn-work-panel { display: none !important; }
}

/* Bloc Menu+Recherche+Notifications+Mode (renderNavDuoButtons, chat ET studios) :
   Recherche et Notifications restent sur desktop/tablette — masquées uniquement
   sur mobile, où seuls Menu + Mode restent dans ce bloc. */
@media (max-width: 639px) {
  #btn-search-nav, #btn-search-nav-studio,
  #btn-search-nav-sep, #btn-search-nav-sep-studio,
  #btn-notif-nav, #btn-notif-nav-studio { display: none !important; }
}

/* =====================================================================
   MOBILE — CORRECTIFS BUGS AUDIT
   ===================================================================== */

/* Touch targets — bouton fermer onglet (audit: 16×16px → besoin ≥ 44px) */
@media (max-width: 639px) {
  [data-tabclose] {
    padding: var(--espace-5) !important;
    margin: -8px !important;
  }

  /* Dropdowns : ne pas dépasser le viewport sur mobile */
  .conv-dropdown,
  .dropdown-enter,
  [class*="absolute"][class*="shadow-xl"] {
    max-width: calc(100vw - 16px) !important;
  }

  /* Barre de sélection de texte : toujours dans le viewport */
  #sel-toolbar {
    max-width: calc(100vw - 8px) !important;
    flex-wrap: wrap !important;
  }

  /* Chat form indicator : ne pas chevaucher le composer */
  #chat-form-indicator {
    bottom: max(88px, calc(72px + env(safe-area-inset-bottom, 0px))) !important;
    right: max(12px, env(safe-area-inset-right, 12px)) !important;
  }

  /* Éviter le scroll horizontal sur main (clip ne crée pas de stacking context) */
  main { overflow-x: clip !important; }

  /* Overflow sur les titres longs dans les listes de projets */
  [style*="white-space:nowrap"] {
    text-overflow: ellipsis !important;
    overflow: hidden !important;
    max-width: 100% !important;
  }
}

/* ============================================================
   ESPACES STUDIO — fond gris clair, chat épuré à gauche, atelier en carte
   claire flottante à droite. Aucune couleur propre : tout dérive des variables
   globales, donc les studios et les espaces suivent le thème sans exception.
   ============================================================ */
/* Couleurs des studios & du portail = thème CREA
   (suivent automatiquement le thème clair/sombre et l'accent CREA) */
:root {
  /* LE FOND D'UN STUDIO EST CELUI DE L'ESPACE CHAT. PAS UN GRIS À PART.
     « Le fond, ils doivent tous suivre cette couleur-là. J'ai été sur Creative,
     le fond de Creative il est gris, c'est deux couleurs différentes. »

     C'était --bg-secondary : tous les studios et tous les espaces (Découvrir,
     Finance, CFO, Éducation, Brevets, Santé) étaient peints en gris pendant que
     le chat restait blanc. C'est aussi ce qui donnait l'impression que la barre
     latérale « tirait vers le blanc » : elle ne tirait nulle part, c'est le
     studio à côté d'elle qui était gris.

     LA CARTE DE L'ATELIER NE DISPARAÎT PAS POUR AUTANT. --studio-card valait
     déjà --bg-primary : à fond égal, ce qui la détache n'est plus la couleur
     mais sa bordure et son ombre portée, toutes deux déjà posées sur
     .studio-card. Même raisonnement que pour la barre latérale et son liseré. */
  --studio-bg:          var(--bg-primary);
  --studio-card:        var(--bg-primary);
  --studio-card-border: var(--border);
  --studio-ink:         var(--t-primary);   /* encre du bouton primaire */
  --studio-ink-t:       var(--bg-primary);
}
.studio-shell { background: var(--studio-bg); --badge-ring: var(--studio-bg); }
.studio-card {
  background: var(--studio-card);
  border: 1px solid var(--studio-card-border);
  border-radius: var(--radius-lg);
  box-shadow:  var(--ombre-3);
  overflow: hidden;
}
.studio-toolbar {
  display: flex; align-items: center; gap: var(--espace-1);
  padding: var(--espace-3) var(--espace-5); flex-shrink: 0;
  border-bottom: 1px solid var(--studio-card-border);
  background: var(--studio-card);
}
.studio-tool-btn {
  font-size: var(--texte-3); font-weight: 500; color: var(--t-secondary);
  padding: var(--espace-3) var(--espace-5); border-radius: var(--radius-sm); white-space: nowrap;
  transition:  background var(--duree-1) var(--courbe); cursor: pointer;
}
.studio-tool-btn:hover { background: rgba(0,0,0,.055); }
html.dark .studio-tool-btn:hover { background: rgba(255,255,255,.08); }
.studio-share-btn {
  background: var(--studio-ink); color: var(--studio-ink-t);
  font-size: var(--texte-3); font-weight: 600;
  padding: var(--espace-3) var(--espace-7); border-radius: var(--radius-rond); white-space: nowrap;
  transition:  opacity var(--duree-1) var(--courbe); cursor: pointer;
}
.studio-share-btn:hover { opacity: .85; }
.studio-avatar {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff;
  font-size: var(--texte-2); font-weight: 700;
}
.studio-toolbar-sep { width: 1px; height: 18px; background: var(--studio-card-border); margin: 0 var(--espace-3); flex-shrink: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   L'ACCUEIL DES STUDIOS — refondu (src/app-accueil-studios.js)

   L'éventail de cartes penchées est parti avec les deux blocs du bas. La page
   se lit maintenant de haut en bas : l'accueil, deux onglets, ce qui attend
   une saisie — ou l'écran d'entrée quand rien n'attend — et la barre de
   question tout en bas, hors du défilement.
   ═══════════════════════════════════════════════════════════════════════════ */
.hub-corps { max-width: 46rem; margin: 0 auto; padding: var(--espace-10) var(--espace-7) var(--espace-8); }
/* L'ACCUEIL SE LIT À GAUCHE, COMME LE RESTE DE LA PAGE. Il vient de l'écran du
   chat, où il est centré au milieu du vide ; ici il ouvre une page qui
   s'aligne, et le logo reprend la taille d'un signe plutôt que d'un titre. */
.hub-tete { display: flex; flex-direction: column; align-items: flex-start; gap: var(--espace-4); margin-bottom: var(--espace-9); }
.hub-tete .crea-phrase-accueil { justify-content: flex-start; text-align: left; margin: 0; max-width: 100%; }
.hub-tete .crea-phrase-logo { width: 22px; height: 22px; }
.hub-tete .crea-sagesse-accueil { text-align: left; }
.hub-pied { flex-shrink: 0; max-width: 46rem; width: 100%; margin: 0 auto; padding: 0 var(--espace-7) var(--espace-5); }

.hub-onglets { display: flex; align-items: center; gap: var(--espace-4); margin-bottom: var(--espace-5); }
.hub-onglet {
  border: none; background: none; cursor: pointer; padding: var(--espace-2) 0;
  font-size: var(--texte-5); font-weight: 600; color: var(--t-faint);
  border-bottom: 2px solid transparent; transition: all var(--duree-1) var(--courbe);
}
.hub-onglet:hover { color: var(--t-secondary); }
.hub-onglet--vif { color: var(--t-primary); border-bottom-color: var(--accent); }
.hub-plus {
  border: none; background: none; cursor: pointer;
  font-size: var(--texte-3); color: var(--t-dim); transition: color var(--duree-1) var(--courbe);
}
.hub-plus:hover { color: var(--accent); }

/* --- Ce qui attend une saisie --- */
.hub-sessions { display: flex; flex-direction: column; gap: var(--espace-3); }
.hub-session {
  display: flex; align-items: center; gap: var(--espace-5); width: 100%; text-align: left;
  padding: var(--espace-5) var(--espace-6); cursor: pointer;
  background: var(--studio-card); border: 1px solid var(--studio-card-border);
  border-radius: var(--radius-lg); color: var(--t-faint);
  transition: all var(--duree-1) var(--courbe);
}
.hub-session:hover { border-color: var(--border-hov); transform: translateX(2px); }
.hub-session-etat {
  display: inline-flex; align-items: center; gap: var(--espace-3); flex-shrink: 0;
  font-size: var(--texte-2); font-weight: 600; color: #b45309;
}
.hub-session-point { width: 6px; height: 6px; border-radius: 50%; background: #d97706; flex-shrink: 0; }
.hub-session-titre {
  font-size: var(--texte-4); font-weight: 600; color: var(--t-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex-shrink: 1; min-width: 0;
}
.hub-session-detail {
  flex: 1; min-width: 0; font-size: var(--texte-2); color: var(--t-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hub-session-lieu {
  display: inline-flex; align-items: center; gap: var(--espace-2); flex-shrink: 0;
  font-size: var(--texte-2); color: var(--t-dim);
}
@media (max-width: 640px) {
  .hub-session-detail, .hub-session-lieu { display: none; }
}

/* --- L'écran d'entrée : ce qu'on voit quand rien n'attend --- */
.hub-creer { display: flex; flex-direction: column; align-items: center; gap: var(--espace-7); padding: var(--espace-8) 0; }
.hub-creer-titre { font-size: var(--texte-7); font-weight: 700; color: var(--t-primary); text-align: center; }
.hub-cartes { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--espace-4); width: 100%; }
.hub-carte {
  display: flex; flex-direction: column; align-items: center; gap: var(--espace-4);
  padding: var(--espace-7) var(--espace-4); cursor: pointer;
  background: var(--studio-card); border: 1px solid var(--studio-card-border);
  border-radius: var(--radius-lg); transition: all var(--duree-1) var(--courbe);
}
.hub-carte:hover { border-color: var(--accent); transform: translateY(-2px); }
.hub-carte-ill {
  width: 42px; height: 42px; border-radius: var(--radius);
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-secondary); color: var(--accent);
}
.hub-carte-nom { font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); text-align: center; }
.hub-explorer {
  display: inline-flex; align-items: center; gap: var(--espace-3); cursor: pointer;
  padding: var(--espace-4) var(--espace-7); border-radius: var(--radius-rond);
  background: none; border: 1px solid var(--border);
  font-size: var(--texte-3); font-weight: 600; color: var(--t-secondary);
  transition: all var(--duree-1) var(--courbe);
}
.hub-explorer:hover { border-color: var(--accent); color: var(--accent); }

/* --- L'utilisation, et le ruban de flux --- */
:root { --hub-flux-0: var(--accent); --hub-flux-1: #6366f1; --hub-flux-2: #a855f7; --hub-flux-3: #94a3b8; }
.hub-usage { display: flex; flex-direction: column; gap: var(--espace-7); }
.hub-usage-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-4); flex-wrap: wrap; }
.hub-sous-onglets, .hub-fenetres { display: flex; align-items: center; gap: var(--espace-2); }
.hub-sous-onglet, .hub-fenetre {
  border: none; background: none; cursor: pointer;
  padding: var(--espace-2) var(--espace-5); border-radius: var(--radius-sm);
  font-size: var(--texte-2); font-weight: 600; color: var(--t-dim);
  transition: background var(--duree-1) var(--courbe), color var(--duree-1) var(--courbe);
}
.hub-sous-onglet:hover, .hub-fenetre:hover { color: var(--t-primary); }
.hub-sous-onglet--vif, .hub-fenetre--vif { background: var(--studio-card); color: var(--t-primary); }
.hub-chiffres { display: grid; grid-template-columns: repeat(auto-fit, minmax(158px, 1fr)); gap: var(--espace-3); }
.hub-chiffre {
  display: flex; flex-direction: column; gap: var(--espace-2);
  padding: var(--espace-5) var(--espace-6); border-radius: var(--radius);
  background: var(--studio-card); border: 1px solid var(--studio-card-border);
}
.hub-chiffre-nom { font-size: var(--texte-2); color: var(--t-dim); }
.hub-chiffre-val { font-size: var(--texte-6); font-weight: 700; color: var(--t-primary); }
.hub-usage-vide { padding: var(--espace-10) 0; text-align: center; font-size: var(--texte-3); color: var(--t-dim); }
/* Ce que la mesure NE COUVRE PAS, dit sous la répartition et pas à sa place :
   les échanges d'avant la mesure par studio comptent dans les totaux et n'ont
   pas de lieu. Les taire ferait croire à une somme qui ne tombe pas juste. */
.hub-usage-note { margin-top: var(--espace-3); font-size: var(--texte-2); color: var(--t-faint); line-height: 1.5; }

/* LE FLUX, PAS UN CALENDRIER. Un segment par jour : sa hauteur dit le volume,
   sa couleur dit le modèle qui a porté la journée. Une grille de cases dit
   seulement COMBIEN de jours ont été actifs — jamais quand ça monte. */
.hub-flux { display: flex; flex-direction: column; gap: var(--espace-3); }
.hub-flux-piste {
  display: flex; align-items: flex-end; gap: 2px; height: 96px;
  padding: var(--espace-4); border-radius: var(--radius);
  background: var(--studio-card); border: 1px solid var(--studio-card-border);
  overflow-x: auto;
}
.hub-flux-jour { flex: 1 1 4px; min-width: 3px; border-radius: var(--radius-xs) var(--radius-xs) 0 0; opacity: .85; transition: opacity var(--duree-1) var(--courbe); }
.hub-flux-jour:hover { opacity: 1; }
.hub-flux-bornes { display: flex; justify-content: space-between; font-size: var(--texte-1); color: var(--t-faint); }
.hub-modeles { display: flex; flex-direction: column; gap: var(--espace-3); }
.hub-modele { display: flex; align-items: center; gap: var(--espace-4); font-size: var(--texte-2); }
.hub-modele-puce { width: 9px; height: 9px; border-radius: var(--radius-xs); flex-shrink: 0; }
.hub-modele-nom { font-weight: 600; color: var(--t-primary); flex-shrink: 0; }
.hub-modele-detail { flex: 1; min-width: 0; color: var(--t-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hub-modele-part { font-weight: 600; color: var(--t-secondary); flex-shrink: 0; }

/* --- La destination, dans la barre de question, contre le « + » --- */
.hub-destination {
  display: inline-flex; align-items: center; gap: var(--espace-2); cursor: pointer;
  padding: var(--espace-2) var(--espace-4); border-radius: var(--radius-rond);
  background: var(--studio-card); border: 1px solid var(--studio-card-border);
  font-size: var(--texte-2); font-weight: 600; color: var(--t-primary);
  transition: all var(--duree-1) var(--courbe);
}
.hub-destination:hover { border-color: var(--accent); }
.hub-destination-liste {
  position: absolute; left: 0; bottom: 100%; margin-bottom: var(--espace-3); z-index: 50;
  min-width: 200px; max-height: 300px; overflow-y: auto; padding: var(--espace-2);
  border-radius: var(--radius-lg); background: var(--studio-card);
  border: 1px solid var(--studio-card-border); box-shadow: var(--ombre-4);
}
.hub-destination-choix {
  display: flex; align-items: center; gap: var(--espace-4); width: 100%; text-align: left;
  padding: var(--espace-3) var(--espace-5); border: none; background: none; cursor: pointer;
  border-radius: var(--radius-sm); font-size: var(--texte-3); color: var(--t-primary);
}
.hub-destination-choix:hover { background: var(--bg-secondary); }
.hub-destination-choix--vif { background: var(--accent-bg); color: var(--accent); }

/* ═══════════════════════════════════════════════════════════════════════════
   CHOISIR UN STUDIO — la même langue que l'accueil des Studios

   Onze tuiles à dégradé animé sont devenues onze lignes qui se lisent. La
   couleur du studio n'a pas disparu : elle est passée dans le SIGNE, ce qui
   l'identifie, au lieu de remplir la tuile.
   ═══════════════════════════════════════════════════════════════════════════ */
.portails-cadre {
  display: flex; flex-direction: column; overflow: hidden;
  width: 100%; max-width: 40rem; max-height: 84vh;
  border-radius: var(--radius-lg); background: var(--bg-primary);
  border: 1px solid var(--border); box-shadow: var(--ombre-5);
}
.portails-tete {
  display: flex; align-items: center; gap: var(--espace-5); flex-shrink: 0;
  padding: var(--espace-6) var(--espace-7); border-bottom: 1px solid var(--border);
}
.portails-titre { font-size: var(--texte-5); font-weight: 700; color: var(--t-primary); flex-shrink: 0; }
.portails-recherche {
  display: flex; align-items: center; gap: var(--espace-3); flex: 1; min-width: 0;
  padding: var(--espace-3) var(--espace-5); border-radius: var(--radius-rond);
  background: var(--bg-secondary); border: 1px solid var(--border); color: var(--t-faint);
}
.portails-recherche input {
  flex: 1; min-width: 0; background: none; border: none; outline: none;
  font-size: var(--texte-3); color: var(--t-primary);
}
.portails-fermer {
  flex-shrink: 0; border: none; background: none; cursor: pointer;
  padding: var(--espace-3); border-radius: var(--radius-sm); color: var(--t-dim);
}
.portails-fermer:hover { background: var(--bg-secondary); color: var(--t-primary); }
.portails-corps { overflow-y: auto; padding: var(--espace-7); }
.portails-section + .portails-section { margin-top: var(--espace-8); }
.portails-rubrique {
  margin-bottom: var(--espace-4); font-size: var(--texte-1); font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em; color: var(--t-faint);
}
.portails-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); gap: var(--espace-3); }
.portails-vide { padding: var(--espace-10) 0; text-align: center; font-size: var(--texte-3); color: var(--t-dim); }

.portail-studio {
  display: flex; align-items: center; gap: var(--espace-5); width: 100%; text-align: left;
  padding: var(--espace-5) var(--espace-6); cursor: pointer;
  background: var(--studio-card); border: 1px solid var(--studio-card-border);
  border-radius: var(--radius); transition: all var(--duree-1) var(--courbe);
}
.portail-studio:hover { border-color: var(--border-hov); }
.portail-studio:active { transform: scale(.99); }
.portail-studio--ici { border-color: var(--accent); background: var(--accent-bg); }
.portail-studio-signe {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 34px; height: 34px; border-radius: var(--radius-sm); background: var(--bg-secondary);
}
.portail-studio-texte { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.portail-studio-nom { font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); }
.portail-studio-quoi {
  font-size: var(--texte-1); color: var(--t-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.portail-studio-marque {
  flex-shrink: 0; font-size: var(--texte-1); font-weight: 600; color: var(--accent);
}

/* ═══════════════════════════════════════════════════════════════════════════
   LE TERMINAL DU STUDIO CODE

   Six couleurs étaient écrites à la main dans le gabarit — dont un fond
   `#0a0e16` qui ne bougeait dans aucun thème pendant que l'encre, elle,
   suivait. En clair : contraste 1,01 : 1, texte invisible. Tout vient
   maintenant des jetons, et `--bg-terminal` existe dans les deux thèmes.
   ═══════════════════════════════════════════════════════════════════════════ */
.term-cadre {
  display: flex; flex-direction: column; flex-shrink: 0; height: 190px;
  border-top: 1px solid var(--border); background: var(--bg-terminal);
}
.term-cadre--replie { height: auto; background: var(--bg-secondary); }
.term-entete {
  display: flex; align-items: center; justify-content: space-between; gap: var(--espace-4);
  flex-shrink: 0; padding: var(--espace-2) var(--espace-6); min-height: 28px;
}
.term-cadre:not(.term-cadre--replie) .term-entete { border-bottom: 1px solid var(--border); }
/* LA BASCULE EST AU MÊME PIXEL, OUVERTE OU FERMÉE : c'est le même bouton, et
   seul son chevron change. Deux en-têtes écrits séparément mettaient le bouton
   qui ouvre et celui qui ferme à deux endroits différents. */
.term-bascule {
  display: flex; align-items: center; gap: var(--espace-3); min-width: 0;
  border: none; background: none; cursor: pointer; padding: 0;
  font-size: var(--texte-1); font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--t-dim);
  transition: all var(--duree-1) var(--courbe);
}
.term-bascule:hover { color: var(--t-primary); }
.term-compte {
  padding: 0 var(--espace-3); border-radius: var(--radius-rond);
  background: var(--bg-tertiary); color: var(--t-dim);
  font-size: var(--texte-1); font-weight: 600; letter-spacing: 0; text-transform: none;
}
.term-atelier {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--t-faint); letter-spacing: 0; text-transform: none; font-weight: 400;
}
.term-commandes { display: flex; align-items: center; gap: var(--espace-4); flex-shrink: 0; }
.term-commande {
  border: none; background: none; cursor: pointer; padding: 0;
  font-size: var(--texte-1); color: var(--t-dim); transition: all var(--duree-1) var(--courbe);
}
.term-commande:hover { color: var(--t-primary); }

.term-hote { flex: 1; overflow: hidden; padding: var(--espace-3) var(--espace-4); }
.term-sortie {
  flex: 1; overflow: auto; padding: var(--espace-4) var(--espace-6);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--texte-2); line-height: 1.65; color: var(--t-secondary);
}
.term-aide { color: var(--t-faint); }
.term-ligne { white-space: pre-wrap; color: var(--t-secondary); }
.term-ligne--erreur { color: var(--danger); }
.term-invite { color: var(--accent-texte); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.term-frappe { color: var(--t-primary); font-weight: 600; }
.term-saisie {
  display: flex; align-items: center; gap: var(--espace-4); flex-shrink: 0;
  padding: var(--espace-3) var(--espace-6); border-top: 1px solid var(--border);
}
.term-saisie input {
  flex: 1; min-width: 0; background: none; border: none; outline: none;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--texte-2); color: var(--t-primary);
}

/* --- Panneau "Sessions" (💬) de l'en-tête d'un studio : largeur bornée à la
   fenêtre pour ne jamais être coupée sur le bord de l'écran (bug signalé sur
   Studio Démarches, où les libellés démarche+titre sont plus longs) --- */
.studio-sessions-panel {
  position: absolute; top: 100%; right: 0; margin-top: var(--espace-3); z-index: 30;
  padding: var(--espace-3);
  border-radius: var(--radius-lg);
  /* --bg-tertiary (#E7E7E7) est le gris des champs, pas celui des surfaces
     flottantes : ce panneau était donc nettement plus sombre que TOUTES les
     autres cartes de l'application, posées sur --bg-primary. « C'est dans un
     gris bizarre. » Il rejoint la surface commune ; c'est le filet et l'ombre
     qui le détachent du fond, comme partout ailleurs. */
  background: var(--bg-primary);
  border: 1px solid var(--border);
  box-shadow:  var(--ombre-4);
  width: 280px;
  max-width: min(280px, calc(100vw - 24px));
  max-height: 320px;
  overflow-y: auto;
  overflow-x: hidden;
}
@media (max-width: 480px) {
  .studio-sessions-panel { right: -8px; width: calc(100vw - 24px); }
}

/* ── UNE SEULE RANGÉE DE SESSION, POUR TOUS LES STUDIOS ──────────────────────
   Même dessin dans chaque studio et dans Simplifica : pastille d'état, nom,
   compteur discret, et des actions qui ne se montrent qu'au survol de LEUR
   rangée — la liste sert à choisir une session, pas à exposer trois outils par
   ligne. Au clavier, le focus les révèle aussi : sans ça elles seraient
   atteignables par Tab tout en restant invisibles. */
.sessions-rangee {
  display: flex; align-items: center; gap: var(--espace-2);
  padding: var(--espace-2) var(--espace-2) var(--espace-2) var(--espace-3);
  border-radius: var(--radius);
  transition: background var(--duree-2) var(--courbe);
}
.sessions-rangee:hover { background: color-mix(in srgb, var(--t-primary) 5%, transparent); }
.sessions-rangee.est-active { background: var(--accent-bg); }
.sessions-pastille {
  width: 6px; height: 6px; border-radius: var(--radius-rond); flex-shrink: 0;
  background: var(--border);
}
.sessions-nom {
  flex: 1; min-width: 0; text-align: left;
  font-size: max(0.75rem, 12px); line-height: 1.35;
  padding: var(--espace-1) 0;
  color: var(--t-primary);
  background: none; border: none; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sessions-rangee.est-active .sessions-nom { color: var(--accent); font-weight: 600; }
.sessions-compte {
  flex-shrink: 0; font-size: max(0.625rem, 10px);
  font-variant-numeric: tabular-nums;
  color: var(--t-faint);
}
.sessions-actions {
  display: flex; align-items: center; gap: 2px; flex-shrink: 0;
  opacity: 0; transition: opacity var(--duree-2) var(--courbe);
}
.sessions-rangee:hover .sessions-actions,
.sessions-rangee:focus-within .sessions-actions { opacity: 1; }
.sessions-action {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: var(--radius-sm);
  color: var(--t-faint); background: none; border: none; cursor: pointer;
  transition: all var(--duree-2) var(--courbe);
}
.sessions-action:hover { color: var(--t-primary); background: color-mix(in srgb, var(--t-primary) 8%, transparent); }
/* Le menu natif de transfert couvre son icône sans se voir : on garde le
   comportement du système (liste déroulante, clavier, mobile) sans son dessin. */
.sessions-action--menu { position: relative; }
.sessions-action--menu > select {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer; border: none; background: none;
}
.sessions-filet { height: 1px; background: var(--border); margin: var(--espace-2) var(--espace-1); }
/* Le même panneau, ancré sous le TITRE du fil — donc à gauche, et au-dessus de
   la nappe de fermeture (#dismiss-overlay, z-49) qui couvre l'écran dès qu'un
   menu est ouvert : sans ce z-index, le panneau s'afficherait sous elle et
   aucune de ses rangées ne serait cliquable. */
.sessions-panneau--gauche { left: 0; right: auto; z-index: 9000; width: 300px; max-width: min(300px, calc(100vw - 24px)); max-height: min(60vh, 420px); }
.sessions-entete {
  padding: var(--espace-1) var(--espace-3) var(--espace-2);
  font-size: max(0.5625rem, 9px); font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--t-faint);
}
.sessions-neuf {
  display: flex; width: 100%; align-items: center; gap: var(--espace-2);
  border-radius: var(--radius);
  padding: var(--espace-2) var(--espace-3);
  font-size: max(0.75rem, 12px); font-weight: 600;
  color: var(--accent); background: none; border: none; cursor: pointer;
  transition: background var(--duree-2) var(--courbe);
}
.sessions-neuf:hover { background: var(--accent-bg); }

/* --- Galerie de modèles dans l'atelier Studio (remplace l'ancien bloc Preview) :
   grandes cartes premium sur 2 rangées qui REMPLISSENT toute la largeur du bloc
   (grille à colonnes élastiques, pas de colonnes figées qui laissent du vide) —
   ne défilent horizontalement que si le nombre de modèles dépasse ce qui tient
   lisiblement (largeur de colonne minimale atteinte). --- */
.studio-template-gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--espace-9);
  width: 100%;
  max-width: 100%;
  padding: var(--espace-2) var(--espace-2) var(--espace-5);
}
.studio-template-card {
  display: flex; flex-direction: column;
  gap: var(--espace-5);
  min-width: 0;
  padding: var(--espace-6);
  border-radius: var(--radius-xl);
  background: var(--studio-card);
  border: 1px solid var(--studio-card-border);
  box-shadow:  var(--ombre-2);
  cursor: pointer;
  text-align: left;
  transition:  transform var(--duree-2) var(--courbe), box-shadow var(--duree-2) var(--courbe), border-color var(--duree-2) var(--courbe);
}
.studio-template-card:hover {
  transform: translateY(-4px);
  border-color: var(--tpl-fg, var(--accent));
  box-shadow:  var(--ombre-3);
}
.studio-template-card-label {
  font-size: var(--texte-4); font-weight: 600; line-height: 1.3;
  color: var(--t-primary);
  padding: 0 var(--espace-1);
}
/* La variante étroite est partie avec ses appels : la galerie ne s'affiche plus
   dans la colonne de chat d'un studio — « seulement sur les blocs des studios,
   pas dans l'espace de leur chat ». Une règle sans plus personne pour la porter
   est une promesse qu'on croit tenir. --- */
/* --- Miniature "esquisse de contenu" (remplace l'icône plate) : occupe la
   majorité de la carte, montre la forme réelle du modèle (lignes de texte,
   slide, page web, email, checklist, graphique) + un badge SVG du studio --- */
.tpl-thumb {
  position: relative;
  flex: 1;
  min-height: 76px;
  width: 100%;
  border-radius: var(--radius-lg);
  background: var(--tpl-bg, var(--accent-bg));
  overflow: hidden;
  padding: var(--espace-7);
  display: flex; flex-direction: column; justify-content: center; gap: var(--espace-4);
  transition:  transform var(--duree-2) var(--courbe);
}
.studio-template-card:hover .tpl-thumb { transform: scale(1.02); }
.tpl-thumb-badge {
  position: absolute; top: 8px; right: 8px;
  width: 22px; height: 22px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--tpl-fg, var(--accent)) 18%, transparent);
  color: var(--tpl-fg, var(--accent));
  display: flex; align-items: center; justify-content: center;
}
.tpl-thumb-badge svg { width: 12px; height: 12px; }
.tpl-thumb-bar { height: 8px; width: 38%; border-radius: var(--radius-xs); background: var(--tpl-fg, var(--accent)); opacity: .85; }
.tpl-thumb-line { height: 6px; border-radius: var(--radius-xs); background: var(--tpl-fg, var(--accent)); opacity: .28; }
.tpl-thumb-stamp { position: absolute; bottom: 12px; right: 14px; width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--tpl-fg, var(--accent)); opacity: .5; }
.tpl-thumb-slide { flex: 1; display: flex; flex-direction: column; gap: var(--espace-5); position: relative; }
.tpl-thumb-slide-title { height: 9px; width: 55%; border-radius: var(--radius-xs); background: var(--tpl-fg, var(--accent)); opacity: .85; }
.tpl-thumb-slide-bul { display: flex; flex-direction: column; gap: var(--espace-3); }
.tpl-thumb-slide-bul span { height: 5px; border-radius: var(--radius-xs); background: var(--tpl-fg, var(--accent)); opacity: .25; }
.tpl-thumb-slide-bul span:nth-child(1) { width: 82% } .tpl-thumb-slide-bul span:nth-child(2) { width: 64% } .tpl-thumb-slide-bul span:nth-child(3) { width: 72% }
.tpl-thumb-slide-accent { position: absolute; bottom: 0; right: 0; width: 28px; height: 28px; border-radius: var(--radius-sm); background: var(--tpl-fg, var(--accent)); opacity: .16; }
.tpl-thumb-web-bar { display: flex; gap: var(--espace-2); }
.tpl-thumb-web-bar span { width: 6px; height: 6px; border-radius: 50%; background: var(--tpl-fg, var(--accent)); opacity: .4; }
.tpl-thumb-web-hero { height: 22px; border-radius: var(--radius-sm); background: var(--tpl-fg, var(--accent)); opacity: .22; }
.tpl-thumb-web-grid { display: flex; gap: var(--espace-3); flex: 1; min-height: 14px; }
.tpl-thumb-web-grid span { flex: 1; border-radius: var(--radius-sm); background: var(--tpl-fg, var(--accent)); opacity: .14; }
.tpl-thumb-email-row { display: flex; align-items: center; gap: var(--espace-4); }
.tpl-thumb-email-avatar { width: 18px; height: 18px; border-radius: 50%; background: var(--tpl-fg, var(--accent)); opacity: .5; flex-shrink: 0; }
.tpl-thumb-email-lines { flex: 1; display: flex; flex-direction: column; gap: var(--espace-3); min-width: 0; }
.tpl-thumb-email-lines span { display: block; height: 6px; border-radius: var(--radius-xs); background: var(--tpl-fg, var(--accent)); opacity: .28; }
.tpl-thumb-list-row { display: flex; align-items: center; gap: var(--espace-4); }
.tpl-thumb-list-box { width: 11px; height: 11px; border-radius: var(--radius-xs); border: 2px solid var(--tpl-fg, var(--accent)); opacity: .6; flex-shrink: 0; }
.tpl-thumb-list-row span { display: block; height: 6px; border-radius: var(--radius-xs); background: var(--tpl-fg, var(--accent)); opacity: .25; }
.tpl-thumb-chart { display: flex; align-items: flex-end; gap: var(--espace-3); flex: 1; min-height: 40px; }
.tpl-thumb-chart b { flex: 1; border-radius: var(--radius-xs) var(--radius-xs) 0 0; background: var(--tpl-fg, var(--accent)); opacity: .55; display: block; }
/* --- Page de modèles : l'en-tête au-dessus de la galerie (renderPageDeModeles).
   Même bloc dans les quatorze studios, pour que « la page d'accueil » veuille
   dire la même chose partout. --- */
.page-modeles { display: flex; flex-direction: column; gap: var(--espace-7); width: 100%; min-height: 0; }
.page-modeles-tete { text-align: center; padding: 0 var(--espace-5); }
.page-modeles-titre { font-size: var(--texte-6); font-weight: 700; color: var(--t-primary); }
.page-modeles-sous { font-size: var(--texte-3); color: var(--t-dim); margin-top: var(--espace-2); }
/* La ligne d'exemple : deux lignes au plus, sinon une carte sur cinq colonnes
   deviendrait un mur de texte. Le titre reste l'accroche, l'exemple la preuve. */
.studio-template-card-ex {
  font-size: var(--texte-1); line-height: 1.35; color: var(--t-dim);
  padding: 0 var(--espace-1);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; text-align: left;
}
@media (max-width: 640px) { .studio-template-card-ex { display: none; } }
/* Esquisses des quatre studios ajoutés — code, image, vidéo, son. Même grammaire
   que les précédentes : des formes en `--tpl-fg` sur la tuile teintée, jamais un
   pictogramme, pour qu'on reconnaisse le GENRE de sortie d'un coup d'œil. */
.tpl-thumb-code { display: flex; flex-direction: column; gap: var(--espace-3); flex: 1; justify-content: center; }
.tpl-thumb-code span { display: block; height: 6px; border-radius: var(--radius-xs); background: var(--tpl-fg, var(--accent)); opacity: .3; }
.tpl-thumb-code span:first-child { opacity: .75; }
.tpl-thumb-image { position: relative; flex: 1; min-height: 44px; border-radius: var(--radius-sm); overflow: hidden; background: color-mix(in srgb, var(--tpl-fg, var(--accent)) 12%, transparent); }
.tpl-thumb-image i { position: absolute; display: block; }
.tpl-thumb-image-sun { width: 12px; height: 12px; border-radius: 50%; top: 9px; left: 14px; background: var(--tpl-fg, var(--accent)); opacity: .6; }
.tpl-thumb-image-mont { left: 0; right: 0; bottom: 0; height: 62%; background: var(--tpl-fg, var(--accent)); opacity: .35; clip-path: polygon(0 100%, 28% 30%, 48% 100%, 68% 48%, 100% 100%); }
.tpl-thumb-video { position: relative; flex: 1; min-height: 44px; border-radius: var(--radius-sm); background: color-mix(in srgb, var(--tpl-fg, var(--accent)) 12%, transparent); display: flex; align-items: center; justify-content: center; }
.tpl-thumb-video-play { display: block; width: 0; height: 0; border-left: 15px solid var(--tpl-fg, var(--accent)); border-top: 10px solid transparent; border-bottom: 10px solid transparent; opacity: .7; margin-bottom: 8px; }
.tpl-thumb-video-strip { position: absolute; left: 0; right: 0; bottom: 0; height: 9px; display: flex; gap: 3px; padding: 0 3px 2px; }
.tpl-thumb-video-strip i { flex: 1; display: block; border-radius: var(--radius-xs); background: var(--tpl-fg, var(--accent)); opacity: .28; }
.tpl-thumb-wave { display: flex; align-items: center; gap: 3px; flex: 1; min-height: 42px; padding-right: 18px; }
.tpl-thumb-wave b { flex: 1; border-radius: var(--radius-xs); background: var(--tpl-fg, var(--accent)); opacity: .55; display: block; }
/* Palette de tuiles — teintes douces et distinctes (façon Linear/Notion), cycle
   par index de carte pour que chaque modèle se distingue visuellement, y compris
   en thème sombre. */
.tpl-swatch-0 { --tpl-bg: #eef2ff; --tpl-fg: #4f46e5; }
.tpl-swatch-1 { --tpl-bg: #ecfdf5; --tpl-fg: #059669; }
.tpl-swatch-2 { --tpl-bg: #fff7ed; --tpl-fg: #ea580c; }
.tpl-swatch-3 { --tpl-bg: #fdf2f8; --tpl-fg: #db2777; }
.tpl-swatch-4 { --tpl-bg: #f0f9ff; --tpl-fg: #0284c7; }
.tpl-swatch-5 { --tpl-bg: #f5f3ff; --tpl-fg: #7c3aed; }
.tpl-swatch-6 { --tpl-bg: #fffbeb; --tpl-fg: #d97706; }
.tpl-swatch-7 { --tpl-bg: #f0fdfa; --tpl-fg: #0d9488; }
html.dark .tpl-swatch-0 { --tpl-bg: #26264a; --tpl-fg: #a5b4fc; }
html.dark .tpl-swatch-1 { --tpl-bg: #14332a; --tpl-fg: #6ee7b7; }
html.dark .tpl-swatch-2 { --tpl-bg: #3a2411; --tpl-fg: #fdba74; }
html.dark .tpl-swatch-3 { --tpl-bg: #3a1830; --tpl-fg: #f9a8d4; }
html.dark .tpl-swatch-4 { --tpl-bg: #122a3a; --tpl-fg: #7dd3fc; }
html.dark .tpl-swatch-5 { --tpl-bg: #241c3a; --tpl-fg: #c4b5fd; }
html.dark .tpl-swatch-6 { --tpl-bg: #382b0f; --tpl-fg: #fcd34d; }
html.dark .tpl-swatch-7 { --tpl-bg: #10322e; --tpl-fg: #5eead4; }
@media (max-width: 640px) {
  /* Deux colonnes sur téléphone : trois cartes de 122 px plus leurs gouttières
     redemanderaient le débordement horizontal qu'on vient de retirer. */
  .studio-template-gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--espace-5); }
  .studio-template-card { padding: var(--espace-5); gap: var(--espace-4); border-radius: var(--radius-lg); }
  .tpl-thumb { min-height: 58px; padding: var(--espace-5); border-radius: var(--radius); }
  .studio-template-card-label { font-size: var(--texte-2); }
}

/* ============================================================
   TRANSITION SIDEBAR — style "drawer" (DeepSeek/ChatGPT mobile) :
   la sidebar glisse, le contenu est poussé à droite et devient
   une carte arrondie visible sur le bord. Desktop : glissement fluide.
   ============================================================ */
/* LARGEUR PROPORTIONNELLE, PAS UN PLAFOND FIXE.
   C'était min(280px, 85vw) : un plafond en pixels, réglé sur un écran de 390 px
   où il valait bien 72 % — la proportion de la référence. Mais 280 px restent
   280 px : sur un téléphone de 440 px ils ne font plus que 64 %, et le tiroir
   paraît d'autant plus étroit que l'écran est grand. Mesuré sur la référence :
   70 % de la largeur d'écran, quelle que soit la taille.
   On pose 72vw et non 70 : la mesure vient d'une photo d'écran, à ±1 point
   près, et 72 était déjà la proportion obtenue sur un écran de 390 px — la
   seule taille où l'ancienne valeur tombait juste. Rester dessus évite de
   déplacer ce qui allait bien tout en corrigeant le reste.
   Le plafond ne sert plus qu'aux tablettes : 72 % d'un écran de 768 px
   feraient 553 px, et il ne resterait plus rien du contenu derrière. */
:root { --crea-sb-w: min(78vw, 420px); }
/* UN SEUL RAYON POUR LES DEUX BORDS. La carte et la barre le partagent : c'est
   ce qui fait qu'on lit UN tracé et non deux formes qui se rencontrent. Deux
   valeurs séparées avaient déjà divergé une fois. */
:root { --crea-sb-r: 78px; }

/* Mobile : contenu poussé pendant que la barre latérale est ouverte.
   L'ARRONDI EST ICI, sur le côté GAUCHE de la carte de contenu — celui qui
   donne sur la barre. La barre, elle, reste droite. Sens vérifié sur les
   captures de référence en thème clair : la barre va d'un bord à l'autre sans
   courbe, et c'est l'espace chat qui est une carte aux coins gauches arrondis.
   Coins gauches seulement : le bord droit de la carte sort de l'écran. */
.main-pushed {
  transform: translateX(var(--crea-sb-w));
  /* RAYON MESURÉ SUR LA RÉFÉRENCE — au deuxième essai, le bon.
     La première mesure donnait ~43 px : elle traversait la barre de saisie, dont
     le fort contraste captait le détecteur de bord au lieu du bord de la carte.
     En ne retenant que les lignes où le bord est franc, la verticale se lit à
     x=959 et la courbe la quitte 238 px d'image plus haut — soit ~79 px CSS en 3x.
     28 px puis 40 px donnaient donc toujours « une ligne droite avec une
     encoche » : le coin existait, mais deux fois trop court pour se lire. */
  border-top-left-radius: var(--crea-sb-r);
  border-bottom-left-radius: var(--crea-sb-r);
  overflow: hidden;
  /* OMBRE MESURÉE, PAS ESTIMÉE. Une ombre trop forte ne souligne pas le coin :
     elle creuse un angle sombre entre le bord de la barre et la courbe de la
     carte — le « creux », que la référence n'a pas. Relevé de luminance au point
     le plus sombre : référence 234, nous 191 sur 255. Divisée par quatre.
     UNE SEULE ombre, large et diffuse : une deuxième, serrée à 1 px, redessinait
     exactement le trait qu'on venait de supprimer. */
  box-shadow: -12px 0 28px -12px rgba(0,0,0,.10);
  /* La carte est PLUS CLAIRE que la barre — mesuré sur la référence : 255 pour
     la carte, 252 qui descend à 235 côté barre en approchant du bord. Ce sont ces
     ~20 niveaux qui rendent la frontière lisible sur TOUTE sa longueur, partie
     courbe comprise. Au même ton, le bord disparaît au milieu. */
  background: #fff;
}
html.dark .main-pushed { box-shadow: -3px 0 18px rgba(0,0,0,.42); }

/* Fond de la rangée = EXACTEMENT la couleur de la barre latérale. La barre et
   l'espace chat partagent UNE SEULE ligne de séparation : quand la carte se
   courbe, ce que sa découpe laisse voir doit être la barre qui se prolonge,
   pour que la ligne suive la courbe d'un seul tenant.
   Un fond contrasté (ce que j'avais mis) creuse au contraire un biseau sombre
   entre le bord droit de la barre, resté droit, et la courbe de la carte : on
   voit alors deux bords distincts et un trou entre les deux. Ce qui dessine la
   séparation, c'est l'OMBRE de la carte, pas une différence de couleur.
   !important nécessaire : une autre règle (parmi les 45 feuilles chargées,
   injectées par les modules crea-*) pose background:var(--bg-secondary) sur
   ce conteneur et gagnait la cascade — constaté en mesurant, la couleur ne
   bougeait pas quelle que soit la valeur posée ici tant qu'elle n'était pas
   en !important. */
/* Le fond derrière la carte est celui de la BARRE, pas un aplat de contraste.
   L'aplat réglait un problème en en créant un autre : un rectangle gris
   apparaissait dans l'angle, là où la carte s'incurve, et le bord se lisait
   comme deux formes qui se heurtent au lieu d'un seul tracé.
   La barre ne porte AUCUN rayon, et ce n'est pas un oubli : un border-radius
   coupe vers l'intérieur, alors qu'épouser la courbe demanderait un coin
   concave. Essayé, rendu, annulé — les deux arrondis partaient en sens opposés
   et ouvraient une lentille plus large que le creux d'origine. */
@media (max-width: 768px) {
  /* LE PUZZLE. La barre ne peint plus son propre fond : son élément s'arrête à sa
     largeur, et c'est son COIN CARRÉ qui apparaissait dans l'angle dès que la
     carte s'incurvait — deux formes, deux bords, un creux entre les deux.
     Le fond est porté par la rangée pleine largeur, qui passe SOUS la carte d'un
     bord à l'autre. La barre occupe alors exactement « tout ce que la carte ne
     couvre pas », coins arrondis compris : son bord est le négatif de la courbe,
     dessiné par elle. Une seule ligne pour les deux pièces. */
  #sidebar { background: transparent !important; }
  .sb-drawer-open { background: var(--bg-secondary) !important; }
  html.dark .sb-drawer-open { background: var(--rail-bg) !important; }
}

/* LA BARRE NE PORTE AUCUN RAYON — ET C'EST VÉRIFIÉ, PAS SUPPOSÉ.
   J'ai essayé de lui faire « suivre » la courbe avec le même rayon que la carte.
   Rendu et photographié : c'est pire. Un border-radius COUPE le coin vers
   l'intérieur ; pour épouser la courbe de la carte il faudrait un coin CONCAVE,
   que border-radius ne sait pas produire. Les deux arrondis partent donc en sens
   opposés et ouvrent une lentille — un creux plus grand que celui qu'on voulait
   supprimer.
   Ce qui fait disparaître le creux n'est pas une deuxième courbe : c'est que
   rien ne contraste dans l'angle. Le fond derrière la carte est celui de la
   barre, et l'ombre est assez faible pour ne pas creuser (mesuré : point le plus
   sombre à 231 sur 255, contre 234 sur la référence). Le seul tracé visible est
   alors celui de la carte, comme sur la référence. */
/* Rayon 0 comme .main-pushed : une animation en fill-mode:both fige sa dernière
   image ET l'emporte sur les déclarations normales. Une valeur différente ici
   redonnerait un arrondi à la carte de contenu, qui doit rester droite. */
@keyframes creaMainPush   { from { transform: translateX(0) } to { transform: translateX(var(--crea-sb-w)) } }
@keyframes creaMainUnpush { from { transform: translateX(var(--crea-sb-w)) } to { transform: translateX(0) } }
.main-anim-push   { animation: creaMainPush   .32s cubic-bezier(.16,1,.3,1) both; }
.main-anim-unpush { animation: creaMainUnpush .32s cubic-bezier(.16,1,.3,1) both; }

/* Desktop : le contenu glisse en douceur quand la sidebar s'ouvre/se ferme */
/* 264px était écrit ici en clair — cinquième copie de la largeur de la barre
   latérale, et la plus traître : celle qui décide de combien le contenu voyage.
   Elle vient maintenant de --crea-sb-largeur, comme l'aside et comme les
   onglets de la barre de fenêtre. Les trois ne peuvent plus diverger. */
/* MÊME EMPRISE QUE LES ONGLETS, ET C'EST TOUT L'INTÉRÊT. Le contenu part de
   sa place d'avant : 284 px pour une carte ancrée, pas 264. Les onglets
   rejouent ce trajet-là — deux nombres pour un seul déplacement finissent
   toujours par se séparer, et l'écart se voit au milieu du geste. */
@keyframes creaMainShiftIn  { from { transform: translateX(calc(-1 * var(--crea-barre-poussee-geste, 0px))) } to { transform: translateX(0) } }
@keyframes creaMainShiftOut { from { transform: translateX(var(--crea-barre-poussee-geste, 0px))  } to { transform: translateX(0) } }
.main-shift-in  { animation: creaMainShiftIn  var(--crea-sb-duree) var(--crea-sb-courbe) both; }
.main-shift-out { animation: creaMainShiftOut var(--crea-sb-duree) var(--crea-sb-courbe) both; }

/* Sidebar : glissement synchronisé avec le contenu (une seule réalité fluide) */
@keyframes creaSbIn  { from { transform: translateX(-100%) } to { transform: translateX(0) } }
@keyframes creaSbOut { from { transform: translateX(0) } to { transform: translateX(-100%) } }
.sidebar-glide-in  { animation: creaSbIn  var(--crea-sb-duree) var(--crea-sb-courbe) both; }
.sidebar-glide-out { animation: creaSbOut var(--crea-sb-duree) var(--crea-sb-courbe) both; pointer-events: none; }

/* --- Page de connexion : galerie promo (images/vidéos) à défilement automatique --- */
.promo-slide { opacity: 0; animation-name: promoFade; animation-timing-function: ease-in-out; animation-iteration-count: infinite; }
@keyframes promoFade {
  0%   { opacity: 0; }
  4%   { opacity: 1; }
  33%  { opacity: 1; }
  38%  { opacity: 0; }
  100% { opacity: 0; }
}

/* --- Widget (météo+actualités fusionnés) : carrousel crossfade Heure/Date <-> Météo --- */
.widget-slide {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  transition:  opacity var(--duree-3) var(--courbe);
}

/* ══════════════════════════════════════════════════════════════════
   TYPOGRAPHIE PREMIUM — lecture longue, rythme régulier, hiérarchie
   nette. Placé en fin de feuille : gagne sur les règles génériques.
   ══════════════════════════════════════════════════════════════════ */
.msg-content {
  /* 16px par défaut. La feuille annonçait 15px « lecture longue » mais
     applyTheme() imposait 14 (STATE.chatFontSize) : la valeur de repli n'était
     jamais atteinte, et le texte restait sous ce que la typographie prévoyait.
     Les deux disent 16 maintenant, et le réglage Aa continue de commander. */
  font-size: var(--msg-font-size, 16px);
  line-height: 1.8;
  letter-spacing: -0.003em;
  color: var(--t-secondary);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-variant-ligatures: common-ligatures;
  font-feature-settings: "kern" 1, "liga" 1;
}

/* Rythme vertical : un seul interligne entre blocs, pas de double marge. */
.msg-content > :first-child { margin-top: 0; }
.msg-content > :last-child { margin-bottom: 0; }
.msg-content p { margin: 0 0 1.15em; line-height: 1.8; }

/* Titres : hiérarchie par le poids et le tracking, pas par la taille seule. */
.msg-content h1,
.msg-content h2,
.msg-content h3,
.msg-content h4,
.msg-content h5,
.msg-content h6 {
  color: var(--t-primary);
  line-height: 1.3;
  letter-spacing: -0.018em;
  margin: 1.6em 0 .6em;
  scroll-margin-top: 1rem;
}
.msg-content h1 { font-size: 1.45em; font-weight: 700; letter-spacing: -0.024em; }
.msg-content h2 { font-size: 1.24em; font-weight: 700; }
.msg-content h3 { font-size: 1.09em; font-weight: 700; }
.msg-content h4 { font-size: 1em;    font-weight: 700; }
.msg-content h5,
.msg-content h6 {
  font-size: .92em; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--t-dim);
}

/* Listes : marqueurs discrets, interligne resserré, imbrication lisible. */
.msg-content ul,
.msg-content ol { margin: 0 0 1.15em; padding-left: 1.4em; }
.msg-content li { margin: 0 0 .5em; line-height: 1.75; padding-left: .15em; }
.msg-content li::marker { color: var(--t-faint); font-weight: 500; }
.msg-content ol > li::marker { font-variant-numeric: tabular-nums; }
.msg-content li > ul,
.msg-content li > ol { margin: .38em 0 0; }
.msg-content li > p { margin-bottom: .38em; }

/* Emphase : le gras porte la structure, l'italique reste discret. */
.msg-content strong,
.msg-content b { color: var(--t-primary); font-weight: 700; letter-spacing: -0.006em; }
.msg-content em,
.msg-content i { font-style: italic; color: inherit; opacity: .94; }
.msg-content del { opacity: .6; }

/* Citations : un filet, pas un encadré coloré. */
.msg-content blockquote {
  margin: 1.15em 0;
  padding: .1em 0 .1em 1.05em;
  border-left: 2.5px solid var(--border-hov);
  background: transparent;
  border-radius: 0;
  color: var(--t-dim);
  font-style: normal;
}
.msg-content blockquote p { margin-bottom: .5em; }
.msg-content blockquote > :last-child { margin-bottom: 0; }

/* Code inline : neutre, sans halo coloré. */
.msg-content code:not(pre code) {
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  color: var(--t-primary);
  padding: .1em .36em;
  border-radius: .32em;
  font-size: .86em;
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-variant-ligatures: none;
  white-space: break-spaces;
}
html.light .msg-content code:not(pre code) { background: #f1f3f5; color: #1e293b; }

/* Liens : soulignement fin, ancré sur la ligne de base. */
.msg-content a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  text-decoration-color: color-mix(in srgb, var(--accent) 38%, transparent);
  transition:  text-decoration-color var(--duree-2) var(--courbe);
}
.msg-content a:hover { text-decoration-color: var(--accent); }

/* === Tableaux ==============================================================
   Le conteneur .md-table-card (posé par habillerTableaux) porte la carte et le
   défilement horizontal ; le <table> redevient un vrai tableau et occupe toute
   la largeur disponible au lieu de se tasser à gauche.
   ========================================================================= */
.msg-content .md-table-card {
  margin: 1.15em 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--bg-primary);
}
.msg-content table {
  border-collapse: collapse;
  width: 100%;
  min-width: max-content;
  margin: 0;
  font-size: .9em;
  white-space: normal;
}
.msg-content th,
.msg-content td {
  border: none;
  border-bottom: 1px solid var(--border-dim);
  padding: .62em 1em;
  text-align: left;
  vertical-align: top;
  font-variant-numeric: tabular-nums;
}
.msg-content thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--bg-secondary);
  color: var(--t-primary);
  font-weight: 600;
  font-size: .93em;
  letter-spacing: .01em;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.msg-content td { color: var(--t-secondary); }
/* Colonnes entièrement numériques (repérées au rendu) : alignées à droite,
   chiffres de largeur fixe — les ordres de grandeur se comparent d'un coup d'œil. */
.msg-content th.num, .msg-content td.num { text-align: right; }
.msg-content tbody tr:last-child td { border-bottom: none; }
.msg-content tbody tr:hover td { background: color-mix(in srgb, var(--t-primary) 3.5%, transparent); }
/* Première colonne : c'est l'intitulé de la ligne, il porte la lecture. */
.msg-content tbody td:first-child { color: var(--t-primary); font-weight: 500; }
/* Un tableau resté hors carte (contenu injecté ailleurs) garde un défilement. */
.msg-content > table { display: block; overflow-x: auto; }

/* Séparateur : discret, respiration large. */
.msg-content hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: 2em 0;
}

/* Images : coins doux, pas de cadre lourd. */
.msg-content img {
  max-width: min(100%, 480px);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  margin: 1em 0;
}

/* Blocs de code : marge cohérente avec le reste du rythme. Les <pre> internes
   d'une carte de code n'en prennent pas — la carte porte déjà la marge. */
.msg-content pre,
.msg-content .code-card { margin: 1.15em 0; }
.msg-content .code-card pre { margin: 0; }
.msg-content .code-card--ligne { margin: .9em 0; }

/* Sections repliables ([details:Titre] … [/details]) : annexes, justifications
   longues, variantes.
   La règle globale `details > summary::marker { display:none }` (plus haut,
   pour les pastilles du travail en cours) supprime le triangle natif — sans
   chevron explicite ici, une section repliable dans une réponse n'aurait
   AUCUNE affordance et passerait pour un titre mort. */
.msg-content details {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin: 1.15em 0;
  overflow: hidden;
}
.msg-content details > summary {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .6rem .85rem;
  cursor: pointer;
  list-style: none;
  user-select: none;
  font-weight: 600;
  font-size: .94em;
  color: var(--t-primary);
  transition:  background var(--duree-2) var(--courbe);
}
.msg-content details > summary:hover { background: color-mix(in srgb, var(--t-primary) 4%, transparent); }
.msg-content details > summary::before {
  content: '›';
  flex-shrink: 0;
  font-size: 1.15em;
  line-height: 1;
  opacity: .55;
  transition:  transform var(--duree-2) var(--courbe);
}
.msg-content details[open] > summary::before { transform: rotate(90deg); }
.msg-content details[open] > summary { border-bottom: 1px solid var(--border); }
.msg-content details > :not(summary) { padding: 0 .85rem; }
.msg-content details > :not(summary):first-of-type { padding-top: .7rem; }
.msg-content details > :not(summary):last-child { padding-bottom: .7rem; }

/* ══════════════════════════════════════════════════════════════════
   FORMATS RICHES — galerie, entités, tableur interactif
   ══════════════════════════════════════════════════════════════════ */

/* Galerie : plusieurs images d'affilée deviennent une grille. */
.md-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--espace-4);
  margin: 1.15em 0;
}
.md-gallery .md-img-wrap { margin: 0 !important; }
.md-gallery .md-img-wrap img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  margin: 0 !important; border-radius: var(--radius); cursor: zoom-in;
}

/* Entité cliquable : [[Nom|type]] — discrète en ligne, sans casser le texte. */
.md-entity {
  display: inline; cursor: pointer;
  color: var(--t-primary); font-weight: 600;
  border-bottom: 1px dotted var(--border-hov);
  transition:  color var(--duree-2), border-color var(--duree-2) var(--courbe);
}
.md-entity:hover,
.md-entity:focus-visible {
  color: var(--accent);
  border-bottom-color: var(--accent);
  outline: none;
}

/* Tableur : en-têtes triables + barre d'outils au survol. Même grammaire
   visuelle que les tableaux de réponse ci-dessus — un seul tableau, pas deux
   styles selon d'où il vient. */
.crea-sheet-table { border-collapse: collapse; width: 100%; min-width: max-content; font-size: .9em; margin: 0; }
.crea-sheet-table th {
  cursor: pointer; user-select: none; white-space: nowrap;
  position: sticky; top: 0; z-index: 1;
  background: var(--bg-secondary);
  color: var(--t-primary); font-weight: 600; text-align: left; font-size: .93em;
  padding: .62em 1em; border-bottom: 1px solid var(--border);
}
.crea-sheet-table th:hover { color: var(--accent); }
.crea-sheet-table td {
  padding: .62em 1em; border-bottom: 1px solid var(--border-dim);
  color: var(--t-secondary); font-variant-numeric: tabular-nums; vertical-align: top;
}
.crea-sheet-table tbody td:first-child { color: var(--t-primary); font-weight: 500; }
.crea-sheet-table th.num, .crea-sheet-table td.num { text-align: right; }
.crea-sheet-table tbody tr:last-child td { border-bottom: none; }
.crea-sheet-table tbody tr:hover td { background: color-mix(in srgb, var(--t-primary) 3.5%, transparent); }
.crea-sheet-arrow { font-size: .8em; }

.md-table-wrap { position: relative; }
.md-table-tools {
  position: absolute; top: 5px; right: 6px; z-index: 3;
  display: flex; gap: var(--espace-2); opacity: 0; transition:  opacity var(--duree-2) var(--courbe);
}
.md-table-wrap:hover .md-table-tools,
.md-table-tools:focus-within { opacity: 1; }
.md-table-tools button {
  font-size: var(--texte-1); font-weight: 500; letter-spacing: .02em;
  padding: var(--espace-2) var(--espace-4); border-radius: var(--radius-sm); cursor: pointer;
  background: var(--bg-elevated); border: 1px solid var(--border);
  color: var(--t-dim); font-family: inherit; transition:  color var(--duree-2), border-color var(--duree-2) var(--courbe);
}
.md-table-tools button:hover { color: var(--accent); border-color: var(--accent); }

/* ══════════════════════════════════════════════════════════════════
   BOUCLE AGENT — étapes à nu : pas de cadre, une flèche par ligne.
   La ligne est l'information ; la flèche ouvre ce qui s'est passé.
   ══════════════════════════════════════════════════════════════════ */
/* PAS DE CADRE. J'avais ajouté une bordure et un fond en croyant qu'on me
   demandait « un cadre » ; la référence montrée était l'inverse — des lignes
   nues, une par action, sans boîte autour. Un bloc gris posé au milieu d'une
   réponse est précisément le « gros bloc » qu'on me reprochait. */
.crea-steps { margin: 0 0 .7rem; }

/* En-tête : logo qui respire + phase, puis chrono et jetons. */
.crea-steps-head {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .55rem .9rem; margin-bottom: .35rem;
}

/* LA LIGNE VIVANTE — ce que CREA fait EN CE MOMENT, sa cible qui change à
   chaque appel d'outil. C'est la partie « en mouvement » : sans elle, on voyait
   une pile d'étapes finies et rien qui bouge, donc rien qui dise que ça
   travaille encore. */
.crea-step-courant {
  display: flex; align-items: center; gap: .45rem;
  padding: .25rem 0;
  font-size: var(--texte-3); color: var(--t-secondary);
  min-width: 0;
}
.crea-step-courant .verbe { font-weight: 600; color: var(--t-primary); white-space: nowrap; }
.crea-step-courant .cible {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: var(--texte-2); color: var(--t-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
/* Trois points qui avancent — le signe le plus lisible que quelque chose court. */
.crea-step-courant .points::after {
  content: '';
  animation: creaPoints 1.4s steps(4, end) infinite;
}
@keyframes creaPoints {
  0%   { content: ''; }
  25%  { content: '.'; }
  50%  { content: '..'; }
  75%  { content: '...'; }
}
/* Barre de progression indéterminée, collée au bas du cadre pendant le travail. */
.crea-steps-jauge {
  height: 2px; border-radius: var(--radius-rond); overflow: hidden;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  margin: .35rem 0 .1rem; max-width: 180px;
}
.crea-steps-jauge::after {
  content: ''; display: block; height: 100%; width: 35%;
  background: var(--accent);
  animation: creaJauge 1.5s ease-in-out infinite;
}
@keyframes creaJauge {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(320%); }
}
@media (prefers-reduced-motion: reduce) {
  .crea-step-courant .points::after { animation: none; content: '…'; }
  .crea-steps-jauge::after { animation: none; width: 100%; opacity: .4; }
}
.crea-step-phase {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: var(--texte-2); color: var(--t-dim); white-space: nowrap;
}
.crea-step-meta {
  font-size: var(--texte-2); color: var(--t-faint);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* Le logo Créa respire pendant le travail — jamais un spinner générique. */
.crea-step-spark {
  width: 12px; height: 12px; flex-shrink: 0;
  animation: creaStepBreath 1.6s ease-in-out infinite;
}
@keyframes creaStepBreath {
  0%, 100% { opacity: .45; transform: scale(.9); }
  50%      { opacity: 1;   transform: scale(1.06); }
}
@media (prefers-reduced-motion: reduce) {
  .crea-step-spark { animation: none; opacity: .8; }
}

/* ── LE LOGO QUI OUVRE LA BOUCLE ────────────────────────────────────────────
   « On ne le remarque même pas. » Mesuré : 13 px de côté, sous une ligne de 18
   et devant un texte de 12 — il était plus petit que ce qu'il annonce.
   C'est la première chose que CREA montre quand elle se met au travail : il
   mène la ligne au lieu de s'y fondre. La marge à droite ouvre l'espace que le
   `gap` de la ligne, réglé pour une puce, ne donnait pas. */
.crea-step-spark.est-ouverture {
  width: 20px; height: 20px; margin-right: .15rem;
}

/* Une étape = une ligne. Rien derrière elle. */
.crea-step { border: none; background: none; }
.crea-step-line {
  display: flex; align-items: center; gap: .45rem;
  padding: .25rem 0; cursor: pointer; user-select: none;
  list-style: none; outline: none; border-radius: var(--radius-sm);
  transition:  background var(--duree-1) var(--courbe);
}
.crea-step-line::-webkit-details-marker { display: none; }
.crea-step-line:hover { background: color-mix(in srgb, var(--t-primary) 4%, transparent); }
.crea-step-line:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.crea-step-chev {
  width: 12px; height: 12px; flex-shrink: 0;
  color: var(--t-faint); opacity: .55;
}
.crea-step-dot {
  width: 6px; height: 6px; border-radius: var(--radius-rond); flex-shrink: 0;
}
/* Une étape se lit « VERBE cible chiffre » : ce qui a été fait, sur quoi, ce
   que ça a produit. Le verbe porte, la cible suit en retrait, le chiffre ferme
   la ligne. Trois graisses, trois niveaux de gris — la ligne se lit d'un coup
   d'œil sans qu'aucune partie n'écrase les autres. */
.crea-step-label {
  font-size: var(--texte-3); color: var(--t-secondary); white-space: nowrap; font-weight: 500;
}
.crea-step-label.is-run { color: var(--t-primary); font-weight: 600; }
.crea-step-arg {
  min-width: 0; max-width: 22rem; font-size: var(--texte-2); color: var(--t-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.crea-step-chiffre {
  font-size: var(--texte-1); color: var(--t-faint); flex-shrink: 0;
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
}
.crea-step-chiffre.est-echec { color: var(--danger); }
.crea-step-spacer { flex: 1; min-width: .5rem; }
.crea-step-time {
  font-size: var(--texte-1); color: var(--t-faint); flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
/* LA FLÈCHE FERME LA LIGNE. Elle était en tête, avant le libellé ; la référence
   montrée la met en bout, après le chrono — « Vérifier l'état des
   téléchargements ⋯ 2,4s › ». Le libellé commence alors toujours au même x,
   quelle que soit la ligne, et la colonne se lit d'un trait. */
.crea-step-line > .crea-step-chev:last-child { margin-left: .3rem; }

/* ── LA FRISE — PENSÉE, ACTION, PENSÉE, ACTION ─────────────────────────────
   Le message se montait en trois tas : toutes les étapes, toute la réflexion,
   tout le texte. On lisait donc une pile d'actions d'un côté et un pavé de
   pensée de l'autre, sans jamais savoir laquelle avait décidé laquelle. Ici
   chaque action est précédée du segment de pensée qui l'a amenée, dans l'ordre
   où les choses se sont passées. */
.crea-frise { display: flex; flex-direction: column; }
.crea-frise-pensee {
  font-size: var(--texte-2);
  line-height: 1.65;
  color: var(--t-dim);
  padding: .3rem 0 .45rem;
  /* La pensée est du texte suivi, pas une ligne d'état : elle se replie et
     respire, là où les lignes d'action tiennent sur une seule ligne. */
  white-space: normal;
  overflow-wrap: anywhere;
}
/* Deux pensées de suite — une action sans réflexion entre elles — ne doivent
   pas creuser un trou : elles se lisent comme un seul paragraphe. */
.crea-frise-pensee + .crea-frise-pensee { padding-top: 0; }

/* CE QUE CREA DIT ENTRE DEUX ACTIONS. Pas une pensée grisée : c'est la réponse
   elle-même, écrite par morceaux au fil du travail. Elle garde donc la couleur
   et la taille du corps du message — c'est le même texte, simplement rendu là
   où il a été écrit. */
.crea-frise-dit {
  color: var(--t-primary);
  padding: .25rem 0 .5rem;
}
.crea-frise-dit > :first-child { margin-top: 0; }
.crea-frise-dit > :last-child { margin-bottom: 0; }

/* LE PLAN. Ce à quoi CREA s'est engagée, et où elle en est.

   Il ne se replie pas avec le reste : replié, il faudrait ouvrir pour voir
   qu'une étape est restée ouverte — c'est-à-dire cacher précisément ce qu'on
   veut montrer. Le détail des outils se replie ; l'engagement, non. */
.crea-plan { margin: .35rem 0 .5rem; }
.crea-plan-tete {
  margin: 0 0 .25rem; font-size: var(--texte-1); font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em; color: var(--t-faint);
  font-variant-numeric: tabular-nums;
}
.crea-plan-ligne {
  display: flex; align-items: baseline; gap: .4rem;
  font-size: var(--texte-3); line-height: 1.55; color: var(--t-dim);
}
.crea-plan-case { flex-shrink: 0; width: .8rem; font-size: var(--texte-1); }
/* L'étape faite s'efface, celle en cours porte. Sans ce contraste, dix lignes
   grises se lisent comme un paragraphe et non comme un avancement. */
.crea-plan-ligne.est-fait { color: var(--t-faint); text-decoration: line-through; text-decoration-thickness: 1px; }
.crea-plan-ligne.est-fait .crea-plan-case { color: #22c55e; }
.crea-plan-ligne.est-courant { color: var(--t-primary); font-weight: 600; }
.crea-plan-ligne.est-courant .crea-plan-case { color: var(--accent); }

/* LE TOUR REPLIÉ. Une seule ligne pour tout ce qui a été fait — « Exécuté 2
   commandes, utilisé 2 outils » — et le détail dessous quand on l'ouvre.

   Le filet de gauche du corps est retiré ICI, et seulement ici : à l'intérieur
   du repli, chaque étape porte déjà le sien. Deux filets emboîtés font un
   escalier de traits gris, c'est-à-dire exactement le « gros bloc » qu'on
   cherchait à supprimer. */
.crea-tour > .crea-step-body {
  margin-left: .55rem; padding-left: .5rem; border-left: none;
}
/* La rotation de la flèche vient déjà de `details[open] > summary
   .step-chevron` : la redéclarer ici ferait une deuxième source de vérité pour
   le même geste, et la première divergence serait invisible. */
.crea-tour > .crea-step-line > .crea-step-label { color: var(--t-dim); }

/* CE QUI TOURNE AILLEURS. Même ligne que les étapes — c'est le même genre de
   fait — mais elle ne se déplie pas : ni curseur de main, ni surbrillance au
   survol, qui promettraient un clic qui ne vient pas. Le point pulse : c'est ce
   qui distingue « en train de tourner » de « fait ». */
.crea-tache-fond { cursor: default; }
.crea-tache-fond:hover { background: none; }
.crea-tache-fond > .crea-step-dot { animation: crea-pulse 1.4s ease-in-out infinite; }
@keyframes crea-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }

/* Le détail : décalé sous la flèche, filet fin à gauche plutôt qu'un encadré. */
.crea-step-body {
  margin: .2rem 0 .5rem 1.05rem;
  padding-left: .75rem;
  border-left: 1px solid var(--border);
}
/* ── CE QUE L'ÉTAPE A TROUVÉ ────────────────────────────────────────────────
   Une liste de lignes nues : le titre à gauche, la provenance à droite. Ni
   fond, ni cadre, ni puce — la même sobriété que la ligne d'étape au-dessus,
   dont ceci n'est que le détail. Le survol souligne, comme partout ailleurs :
   c'est le seul signe qu'une ligne mène quelque part, et il n'apparaît qu'au
   moment où l'on vise. */

.crea-trouvailles { display: flex; flex-direction: column; margin-bottom: .45rem; }
.crea-trouvaille {
  display: flex; align-items: baseline; gap: .5rem;
  padding: .2rem 0; min-width: 0;
  font-size: var(--texte-2); color: var(--t-secondary); text-decoration: none;
}
a.crea-trouvaille:hover .crea-trouvaille-titre,
a.crea-trouvaille:focus-visible .crea-trouvaille-titre {
  color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
}
/* Le titre cède la place en premier : une provenance coupée ne dit plus d'où
   ça vient, alors qu'un titre coupé se devine encore. */
.crea-trouvaille-titre {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--t-primary);
}
.crea-trouvaille-source {
  flex-shrink: 0; color: var(--t-faint); font-size: var(--texte-1);
  max-width: 42%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* « lue » : la page a vraiment été ouverte, pas seulement résumée par le
   moteur. Le serveur seul le sait — ça ne se devine pas d'une URL. */
.crea-trouvaille-lu {
  flex-shrink: 0; font-size: var(--texte-1); color: var(--accent);
  background: var(--accent-bg); border-radius: var(--radius-xs);
  padding: 0 .3rem; line-height: 1.5;
}

.crea-step-io + .crea-step-io { margin-top: .4rem; }
.crea-step-io p {
  margin: 0 0 .2rem; font-size: var(--texte-1); font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em; color: var(--t-faint);
}
.crea-step-io pre {
  margin: 0; font-size: var(--texte-2); line-height: 1.5;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  color: var(--t-secondary); white-space: pre-wrap; word-break: break-word;
  max-height: 200px; overflow-y: auto;
}
.crea-step-wait { margin: 0; font-size: var(--texte-2); color: var(--accent); }

/* Listes de tâches markdown — « - [ ] » devient une case cochable. */
.msg-content li:has(> input[type=checkbox]) { list-style: none; margin-left: -1.1em; }
.msg-content input[type=checkbox] {
  width: 14px; height: 14px; margin-right: .5em;
  vertical-align: -1px; cursor: pointer; accent-color: var(--accent);
}
.msg-content li:has(> input[type=checkbox]:checked) { color: var(--t-faint); }

/* ══════════════════════════════════════════════════════════════════
   L'ESPACE ARTÉFACTS — la galerie, rangée par surface.
   Copiée sur celle de Claude Code : titre, filtre, recherche, onglets,
   grille de cartes à vignette. Ce qui change ici, ce sont les sections :
   quatorze studios rangés à plat feraient un tas.
   ══════════════════════════════════════════════════════════════════ */
.art-espace {
  max-width: 1080px; margin: 0 auto; padding: var(--espace-10) var(--espace-9) 64px;
  overflow-y: auto; height: 100%;
}
.art-entete { display: flex; align-items: center; gap: var(--espace-7); flex-wrap: wrap; margin-bottom: var(--espace-8); }
.art-titre { font-size: var(--texte-13); font-weight: 700; color: var(--t-primary); margin: 0; flex: 1; }
.art-entete-actions { display: flex; align-items: center; gap: var(--espace-5); }
.art-filtre {
  font-size: var(--texte-4); color: var(--t-dim); background: var(--bg-input);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: var(--espace-4) var(--espace-6); transition: all var(--duree-1) var(--courbe);
}
.art-nouveau {
  font-size: var(--texte-4); font-weight: 600; color: var(--bg-primary);
  background: var(--t-primary); border: 0; border-radius: var(--radius-sm);
  padding: var(--espace-4) var(--espace-7); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.art-nouveau:hover { opacity: .88; }
.art-recherche {
  display: flex; align-items: center; gap: var(--espace-5);
  background: var(--bg-input); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--espace-5) var(--espace-7);
  color: var(--t-faint); margin-bottom: var(--espace-7);
}
.art-recherche input {
  flex: 1; background: none; border: 0; outline: none;
  font-size: var(--texte-4); color: var(--t-primary);
}
.art-onglets { display: flex; gap: var(--espace-4); margin-bottom: var(--espace-9); }
.art-onglet {
  font-size: var(--texte-4); color: var(--t-dim); background: transparent;
  border: 0; border-radius: var(--radius-sm); padding: var(--espace-4) var(--espace-6);
  cursor: pointer; transition: all var(--duree-1) var(--courbe);
}
.art-onglet.est-actif { background: var(--bg-tertiary); color: var(--t-primary); font-weight: 600; }

.art-groupe { margin-bottom: var(--espace-10); }
.art-groupe-titre {
  display: flex; align-items: center; gap: var(--espace-5);
  font-size: var(--texte-5); font-weight: 600; color: var(--t-primary);
  margin: 0 0 var(--espace-6);
}
.art-groupe-compte {
  font-size: var(--texte-2); font-weight: 500; color: var(--t-faint);
  background: var(--bg-tertiary); border-radius: var(--radius-rond);
  padding: 0 var(--espace-5); font-variant-numeric: tabular-nums;
}
/* UN GROUPE VIDE LE DIT. Le masquer laisserait croire que ce studio n'existe
   pas, alors qu'il n'a simplement rien produit — deux choses différentes. */
.art-groupe-vide { font-size: var(--texte-4); color: var(--t-faint); margin: 0; }
.art-vide-total { font-size: var(--texte-5); color: var(--t-faint); text-align: center; padding: 64px var(--espace-8); }

.art-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--espace-7); }
/* LA CARTE CONTIENT DEUX BOUTONS, elle n'en est plus un : un bouton ne peut pas
   en imbriquer un autre, et le menu « ⋮ » des photos de référence l'exigeait.
   `overflow: visible` — le menu déborde de la carte, sinon il serait coupé. */
.art-carte {
  position: relative; display: flex; flex-direction: column;
  background: var(--bg-secondary); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: all var(--duree-2) var(--courbe);
}
.art-carte:hover { border-color: var(--t-faint); box-shadow: var(--ombre-2); }
.art-carte-ouvrir {
  display: flex; flex-direction: column; text-align: left; padding: 0; cursor: pointer;
  background: none; border: 0; border-radius: var(--radius-lg); overflow: hidden;
}
/* IL N'APPARAÎT QU'AU SURVOL, comme sur les photos — mais il reste atteignable
   au clavier : `:focus-visible` le montre, sans quoi il n'existerait que pour
   la souris. */
.art-carte-menu {
  position: absolute; top: var(--espace-5); right: var(--espace-5); z-index: 2;
  width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--bg-primary); color: var(--t-secondary); cursor: pointer;
  opacity: 0; transition: opacity var(--duree-1) var(--courbe);
}
.art-carte:hover .art-carte-menu,
.art-carte.est-menu-ouvert .art-carte-menu,
.art-carte-menu:focus-visible { opacity: 1; }
.art-carte-menu:hover { background: var(--bg-tertiary); }
.art-carte-menu-liste {
  position: absolute; top: calc(var(--espace-5) + 28px); right: var(--espace-5); z-index: 3;
  min-width: 210px; padding: var(--espace-3);
  background: var(--bg-primary); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--ombre-3);
}
.art-carte-menu-note {
  margin: var(--espace-3) 0 0; padding: 0 var(--espace-5) var(--espace-3);
  font-size: var(--texte-2); color: var(--t-faint); line-height: 1.4;
}
.art-vignette {
  height: 148px; padding: var(--espace-7); overflow: hidden;
  background: var(--bg-primary); border-bottom: 1px solid var(--border);
}
.art-vignette--code { display: flex; align-items: center; justify-content: center; color: var(--t-faint); }
/* L'APERÇU RÉEL, EN PETIT. Le document est rendu à sa vraie largeur puis
   réduit : une page dessinée dans 148 px de haut ne ressemble à rien, alors
   qu'une page de 1000 px vue au tiers ressemble à elle-même.
   `pointer-events: none` — la carte entière est un bouton ; un clic qui
   tomberait DANS l'aperçu n'ouvrirait rien. */
.art-vignette--rendu { padding: 0; position: relative; }
.art-vignette-cadre {
  position: absolute; top: 0; left: 0; border: 0; pointer-events: none;
  width: 333.34%; height: 493px;  /* 100 / 0.3 et 148 / 0.3 — l'aperçu réduit remplit exactement la vignette */
  transform: scale(0.3); transform-origin: 0 0;
  background: #fff;
}
.art-vignette-titre { font-size: var(--texte-4); font-weight: 600; color: var(--t-secondary); line-height: 1.35; }
.art-vignette-type { font-size: var(--texte-2); color: var(--t-faint); margin-top: var(--espace-4); }
.art-carte-pied { padding: var(--espace-6) var(--espace-7); }
.art-carte-titre {
  font-size: var(--texte-4); font-weight: 500; color: var(--t-primary); margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.art-carte-meta {
  display: flex; align-items: center; gap: var(--espace-4);
  font-size: var(--texte-2); color: var(--t-faint); margin: var(--espace-3) 0 0;
}
.art-note-absents {
  font-size: var(--texte-2); color: var(--t-faint); line-height: 1.6;
  border-top: 1px solid var(--border); padding-top: var(--espace-7); margin-top: var(--espace-9);
}
@media (max-width: 640px) {
  .art-espace { padding-left: var(--espace-7); padding-right: var(--espace-7); }
  .art-entete-actions { width: 100%; }
  .art-filtre { flex: 1; min-width: 0; }
}

/* ══════════════════════════════════════════════════════════════════
   MODE RECHERCHE — les blocs des onglets Réponse/Liens/Images/
   Actualités/Vidéos. Pas de cadre lourd : de l'air, une hiérarchie
   nette (source → url → titre → extrait) et des séparateurs fins.
   ══════════════════════════════════════════════════════════════════ */

/* La barre de reglages, au-dessus des onglets. Deux menus et une phrase de
   cout : discrete tant qu'on ne la regarde pas, atteignable des qu'on la
   cherche. Meme largeur que la page pour qu'elle ne flotte pas a cote. */
.rch-reglages {
  max-width: 780px; margin: 0 auto; padding: var(--espace-6) var(--espace-10) 0;
  display: flex; align-items: center; gap: var(--espace-7); flex-wrap: wrap;
}
.rch-reglage { display: inline-flex; align-items: center; gap: var(--espace-4); }
.rch-reglage > span { font-size: var(--texte-4); color: var(--t-faint); }
.rch-reglage select {
  font-size: var(--texte-4); color: var(--t-dim);
  background: var(--bg-input); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: var(--espace-3) var(--espace-5);
  transition: all var(--duree-1) var(--courbe);
}
.rch-reglage select:hover { border-color: var(--t-faint); }
/* Le cout, dit SOUS les reglages : un curseur dont on ne dit pas le prix se
   regle a l'aveugle, et quand le quota tombe l'onglet se vide sans raison.
   Toujours sur sa propre ligne, alignee a gauche comme les etiquettes : pousse
   a droite, il tombait tantot au bout de la rangee tantot seul en dessous,
   selon la largeur de la fenetre — une place decidee par le hasard. */
.rch-cout {
  font-size: var(--texte-4); color: var(--t-faint);
  flex-basis: 100%; margin-top: calc(var(--espace-4) * -1);
}

.rch-page { max-width: 780px; margin: 0 auto; padding: var(--espace-9) var(--espace-10) 64px; }
.rch-entete { font-size: var(--texte-4); color: var(--t-faint); margin: 0 0 var(--espace-9); }
.rch-entete span { color: var(--t-dim); }
/* Le compte de resultats : discret, pousse a droite de la ligne d'en-tete. */
.rch-entete .rch-compte {
  float: right; color: var(--t-faint); font-variant-numeric: tabular-nums;
}
.rch-etat {
  display: flex; align-items: center; gap: var(--espace-5);
  color: var(--t-faint); font-size: var(--texte-4); padding-top: 40px; justify-content: center;
}
.rch-spin {
  width: 13px; height: 13px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid var(--border); border-top-color: var(--t-dim);
  animation: rch-tourne .7s linear infinite;
}
@keyframes rch-tourne { to { transform: rotate(360deg) } }

/* Ligne de provenance — favicon + domaine. Commune à tous les blocs :
   c'est elle qui donne l'impression d'un moteur, pas d'un fil de chat. */
.rch-source {
  display: flex; align-items: center; gap: var(--espace-3);
  font-size: var(--texte-3); color: var(--t-dim); min-width: 0;
}
.rch-source > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rch-fav { border-radius: var(--radius-xs); flex-shrink: 0; object-fit: contain; }
.rch-lien-ext { opacity: .45; flex-shrink: 0; }
.rch-url {
  font-size: var(--texte-2); color: var(--t-faint); margin-top: var(--espace-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Liens ── */
.rch-liens { display: flex; flex-direction: column; }
.rch-lien {
  display: flex; gap: var(--espace-8); align-items: flex-start;
  padding: var(--espace-8) 0; text-decoration: none;
  border-top: 1px solid var(--border);
}
.rch-lien:first-child { border-top: none; padding-top: 0; }
.rch-lien:hover .rch-lien-titre { text-decoration: underline; }
.rch-lien-corps { flex: 1; min-width: 0; }
.rch-lien-titre {
  font-size: var(--texte-6); font-weight: 600; line-height: 1.4; margin-top: var(--espace-3);
  color: var(--t-primary);
}
.rch-lien-extrait {
  font-size: var(--texte-4); line-height: 1.55; color: var(--t-dim); margin: var(--espace-3) 0 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.rch-lien-vignette {
  width: 108px; height: 78px; flex-shrink: 0; border-radius: var(--radius);
  overflow: hidden; background: var(--bg-tertiary);
}
.rch-lien-vignette img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── Images ── grille dense, la légende sous chaque vignette */
.rch-images {
  display: grid; gap: var(--espace-7);
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
}
.rch-image { text-decoration: none; display: block; min-width: 0; }
/* `> img` — LE CHEVRON N'EST PAS DÉCORATIF. Sans lui, la règle attrapait aussi
   le favicon de la source, niché dans .rch-image-source : un logo de 12 px
   étiré à 100 % de la tuile en 4/3. Le résultat s'est vu à l'écran — les gros
   ronds roses et bleus étaient le logo de Flickr, les damiers noir et blanc
   celui de Wikimedia Commons, tous deux pris pour des photos. */
.rch-image > img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block;
  border-radius: var(--radius); background: var(--bg-tertiary);
  transition:  transform var(--duree-2) var(--courbe);
}
.rch-image:hover > img { transform: scale(1.015); }
/* Et une taille par défaut sur le favicon lui-même : la même erreur ailleurs
   ne pourrait plus le laisser s'étirer. */
.rch-image-source .rch-fav { width: 12px; height: 12px; aspect-ratio: auto; border-radius: var(--radius-xs); }
.rch-image-source {
  display: flex; align-items: center; gap: var(--espace-3); margin-top: var(--espace-3);
  font-size: var(--texte-2); color: var(--t-faint); min-width: 0;
}
.rch-image-source > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Actualités ── carte : vignette, titre, source · date */
.rch-actus {
  display: grid; gap: var(--espace-8);
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.rch-actus-compact { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); margin-bottom: var(--espace-5); }
.rch-actu {
  display: flex; flex-direction: column; text-decoration: none;
  border-radius: var(--radius); overflow: hidden; min-width: 0;
  transition:  background var(--duree-2) var(--courbe);
}
.rch-actu:hover { background: color-mix(in srgb, var(--t-primary) 4%, transparent); }
.rch-actu-vignette {
  width: 100%; aspect-ratio: 16 / 9; background: var(--bg-tertiary);
  border-radius: var(--radius); overflow: hidden; margin-bottom: var(--espace-4);
}
.rch-actu-vignette img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rch-actu-corps { padding: 0 var(--espace-1) var(--espace-3); min-width: 0; }
.rch-actu-titre {
  font-size: var(--texte-4); font-weight: 600; line-height: 1.4; margin: 0 0 var(--espace-3);
  color: var(--t-primary);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.rch-actu-meta {
  display: flex; align-items: center; gap: var(--espace-3);
  font-size: var(--texte-2); color: var(--t-faint); min-width: 0;
}
.rch-actu-source { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rch-actu-date { flex-shrink: 0; }

/* ── Vidéos ── vignette + bouton lecture superposé */
.rch-videos {
  display: grid; gap: var(--espace-9);
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.rch-video { text-decoration: none; display: block; min-width: 0; }
.rch-video-vignette {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  border-radius: var(--radius); overflow: hidden; background: var(--bg-tertiary);
}
.rch-video-vignette img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rch-video-play {
  position: absolute; inset: 0; margin: auto;
  width: 42px; height: 42px; border-radius: 50%;
  background: rgba(0,0,0,.62); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--texte-6); padding-left: var(--espace-2); box-sizing: border-box;
  transition:  transform var(--duree-2) var(--courbe), background var(--duree-2) var(--courbe);
}
.rch-video:hover .rch-video-play { transform: scale(1.08); background: rgba(0,0,0,.78); }
.rch-video-titre {
  font-size: var(--texte-4); font-weight: 600; line-height: 1.4; margin: var(--espace-5) 0 var(--espace-3);
  color: var(--t-primary);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ── En-tête de l'onglet Réponse : fiche d'entité + actualités ── */
.rch-entete-reponse { max-width: 780px; margin: 0 auto; padding: var(--espace-8) var(--espace-10) 0; }
.rch-entite {
  display: flex; gap: var(--espace-8); align-items: flex-start; text-decoration: none;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--espace-7) var(--espace-8); margin-bottom: var(--espace-9);
  transition:  background var(--duree-2) var(--courbe);
}
.rch-entite:hover { background: color-mix(in srgb, var(--t-primary) 3%, transparent); }
.rch-entite-corps { flex: 1; min-width: 0; }
.rch-entite-titre {
  font-size: var(--texte-7); font-weight: 700; margin-top: var(--espace-4); color: var(--t-primary);
}
.rch-entite-resume {
  font-size: var(--texte-4); line-height: 1.6; color: var(--t-dim); margin: var(--espace-3) 0 0;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.rch-entite-image {
  width: 96px; height: 96px; flex-shrink: 0; border-radius: var(--radius);
  overflow: hidden; background: var(--bg-tertiary);
}
.rch-entite-image img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rch-plus {
  display: block; margin: var(--espace-2) 0 var(--espace-9); padding: 0;
  background: none; border: 0; cursor: pointer;
  font-size: var(--texte-4); color: var(--t-dim);
}
.rch-plus:hover { color: var(--t-primary); text-decoration: underline; }

/* ── Pastille de source au fil de la réponse ── */
/* La pastille de citation : un repère, pas un encart. Elle portait le domaine
   complet en monospace — « learning.google » au milieu d'une phrase forme un
   pavé plus large que les mots voisins, et une réponse qui cite dix fois
   devient illisible. Elle porte maintenant le NUMÉRO de la source, le domaine
   passant au survol. */
.rch-pastille {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  vertical-align: super; margin: 0 var(--espace-1);
  padding: 0 var(--espace-2); border-radius: var(--radius-rond); height: 1.35em;
  background: color-mix(in srgb, var(--t-primary) 8%, transparent);
  font-size: .62em; line-height: 1; color: var(--t-dim);
  text-decoration: none; white-space: nowrap;
  transition:  background var(--duree-1) var(--courbe), color var(--duree-1) var(--courbe);
}
.rch-pastille .rch-fav { width: 9px; height: 9px; border-radius: var(--radius-xs); }
.rch-pastille-num { font-variant-numeric: tabular-nums; font-weight: 600; }
.rch-pastille:hover { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--t-primary); }
.rch-pastille-plus { opacity: .55; }

/* L'en-tête de recherche vit maintenant DANS le message : il ne doit plus se
   recentrer ni ajouter sa propre gouttière, la colonne du message la donne. */
.msg-ai-container > .rch-entete-reponse {
  max-width: none; margin: 0 0 var(--espace-7); padding: 0;
}

/* ── Mobile ── la référence passe en icônes seules et en une colonne */
@media (max-width: 640px) {
  .rch-page, .rch-entete-reponse { padding-left: var(--espace-7); padding-right: var(--espace-7); }
  .rch-reglages { padding-left: var(--espace-7); padding-right: var(--espace-7); }
  .rch-lien { gap: var(--espace-6); }
  .rch-lien-vignette { width: 84px; height: 62px; }
  .rch-images { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: var(--espace-5); }
  .rch-actus, .rch-actus-compact { grid-template-columns: 1fr 1fr; gap: var(--espace-6); }
  .rch-videos { grid-template-columns: 1fr; }
  .rch-entite { flex-direction: column-reverse; gap: var(--espace-6); }
  .rch-entite-image { width: 100%; height: 140px; }
}

/* Ligne « N sources consultées » — repliable, discrète, au-dessus de la fiche. */
.rch-etapes { margin-bottom: var(--espace-6); }
.rch-etapes > summary {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  cursor: pointer; list-style: none;
  font-size: var(--texte-3); color: var(--t-faint);
}
.rch-etapes > summary::-webkit-details-marker { display: none; }
.rch-etapes > summary::before {
  content: '›'; font-size: 1.1em; line-height: 1; opacity: .6;
  transition:  transform var(--duree-2) var(--courbe);
}
.rch-etapes[open] > summary::before { transform: rotate(90deg); }
.rch-etapes > summary:hover { color: var(--t-dim); }
.rch-etapes ul {
  margin: var(--espace-3) 0 0; padding-left: var(--espace-9);
  font-size: var(--texte-2); color: var(--t-faint); line-height: 1.7;
}

/* ══════════════════════════════════════════════════════════════════
   FIL DÉCOUVRIR — cartes de sujets, défilement infini
   Une carte par SUJET (les reprises d'une même dépêche sont fondues et
   comptées en « N sources »), pas une carte par article.
   ══════════════════════════════════════════════════════════════════ */

/* Les onglets tiennent leur propre ligne, centrée, sous le titre — comme la
   référence. Collés au titre et alignés à gauche, ils se lisaient comme un
   sous-titre plutôt que comme une navigation. */
.dec-onglets {
  display: flex; align-items: center; justify-content: center;
  gap: var(--espace-3); margin: 0 0 var(--espace-10);
}
.dec-onglet {
  border-radius: var(--radius-rond); padding: var(--espace-3) var(--espace-7);
  font-size: var(--texte-3); font-weight: 600; color: var(--t-dim);
  white-space: nowrap;
}
.dec-onglet:hover { color: var(--t-secondary); }
.dec-onglet.on { background: var(--t-primary); color: var(--bg-primary); }

.dec-fil { display: block; }
.dec-grille {
  display: grid; gap: var(--espace-8); margin-top: var(--espace-8);
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
}

.dec-carte {
  display: flex; flex-direction: column;
  border-radius: var(--radius-lg); overflow: hidden;
  background: var(--bg-secondary); border: 1px solid var(--border);
  text-decoration: none; color: inherit;
  transition:  border-color var(--duree-2) var(--courbe), box-shadow var(--duree-2) var(--courbe);
}
.dec-carte:hover { border-color: var(--accent); box-shadow:  var(--ombre-2); }
.dec-visuel { display: block; width: 100%; aspect-ratio: 16 / 9; background: var(--bg-tertiary); }
.dec-carte-large .dec-visuel { aspect-ratio: 16 / 7; }
.dec-visuel img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dec-corps { display: flex; flex-direction: column; gap: var(--espace-4); padding: var(--espace-7) var(--espace-8) var(--espace-8); }
.dec-date { font-size: var(--texte-1); color: var(--t-faint); }
.dec-titre { font-size: var(--texte-5); font-weight: 700; line-height: 1.35; color: var(--t-primary); }
.dec-carte-large .dec-titre { font-size: var(--texte-8); line-height: 1.28; }
.dec-desc {
  font-size: var(--texte-3); line-height: 1.6; color: var(--t-dim);
  /* Trois lignes au plus : au-delà, les cartes d'une même rangée n'ont plus
     la même hauteur et la grille se déchire. */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.dec-carte-large .dec-desc { -webkit-line-clamp: 4; font-size: var(--texte-4); }
.dec-sources { display: flex; align-items: center; gap: var(--espace-3); margin-top: var(--espace-1); }
.dec-fav { border-radius: var(--radius-xs); flex: 0 0 auto; }
.dec-sources-n { font-size: var(--texte-1); color: var(--t-faint); margin-left: var(--espace-2); }

.dec-etat {
  display: flex; align-items: center; justify-content: center; gap: var(--espace-5);
  padding: 28px var(--espace-6); font-size: var(--texte-4); color: var(--t-faint); text-align: center;
}
.dec-etat-suite { padding: var(--espace-10) var(--espace-6); font-size: var(--texte-3); }
.dec-relancer { color: var(--accent); text-decoration: underline; }
/* La sentinelle du défilement infini : invisible, mais elle doit avoir une
   hauteur réelle — un élément de hauteur nulle n'intersecte jamais rien et
   l'observateur ne se déclencherait pas. */
.dec-sentinelle { height: 1px; width: 100%; }
.dec-maj { text-align: center; font-size: var(--texte-1); color: var(--t-faint); padding-bottom: var(--espace-4); }
.dec-spin {
  width: 14px; height: 14px; border-radius: 50%; flex: 0 0 auto;
  border: 2px solid var(--border); border-top-color: var(--accent);
  animation: dec-tourne .7s linear infinite;
}
@keyframes dec-tourne { to { transform: rotate(360deg); } }

@media (max-width: 640px) {
  .dec-grille { grid-template-columns: 1fr; gap: var(--espace-6); }
  .dec-carte-large .dec-titre { font-size: var(--texte-7); }
}

/* ══════════════════════════════════════════════════════════════════
   TOUT RESTE DANS CRÉA — lecture d'article, lecteur vidéo
   Ces vues remplacent le contenu tant qu'elles sont ouvertes ; « Retour »
   ramène exactement d'où l'on vient, y compris d'une vidéo ouverte depuis
   une autre vidéo.
   ══════════════════════════════════════════════════════════════════ */

.int-vue { height: 100%; display: flex; flex-direction: column; min-height: 0; }
.int-barre {
  display: flex; align-items: center; gap: var(--espace-5); flex: 0 0 auto;
  padding: var(--espace-5) var(--espace-8); border-bottom: 1px solid var(--border);
  background: var(--bg-primary); position: sticky; top: 0; z-index: 5;
}
.int-retour {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  border-radius: var(--radius-rond); padding: var(--espace-3) var(--espace-6) var(--espace-3) var(--espace-5);
  font-size: var(--texte-3); font-weight: 600; color: var(--t-secondary);
  border: 1px solid var(--border); background: var(--bg-secondary);
}
.int-retour:hover { color: var(--t-primary); border-color: var(--accent); }
.int-barre-titre { flex: 1; min-width: 0; font-size: var(--texte-3); color: var(--t-faint); truncate: ellipsis; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.int-fermer { color: var(--t-faint); font-size: var(--texte-6); padding: var(--espace-1) var(--espace-3); }
.int-fermer:hover { color: var(--t-primary); }

/* ── Lecture d'article ── largeur de colonne de lecture, pas pleine page :
   au-delà d'environ 70 caractères par ligne, l'œil perd la ligne suivante. */
.int-article { flex: 1; min-height: 0; overflow-y: auto; max-width: 720px; margin: 0 auto; padding: 24px 22px 72px; width: 100%; }
.int-hero { width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-lg); overflow: hidden; background: var(--bg-tertiary); margin-bottom: var(--espace-9); }
.int-hero img { width: 100%; height: 100%; object-fit: cover; display: block; }
.int-titre { font-size: var(--texte-11); font-weight: 800; line-height: 1.22; color: var(--t-primary); margin: 0 0 var(--espace-5); }
.int-meta { font-size: var(--texte-3); color: var(--t-faint); margin: 0 0 var(--espace-9); }
.int-chapo { font-size: var(--texte-7); line-height: 1.62; color: var(--t-secondary); font-weight: 500; margin: 0 0 var(--espace-10); }
.int-p { font-size: var(--texte-6); line-height: 1.78; color: var(--t-secondary); margin: 0 0 var(--espace-9); }
.int-h3 { font-size: var(--texte-8); font-weight: 700; color: var(--t-primary); margin: 28px 0 var(--espace-6); }
.int-cite { border-left: 3px solid var(--accent); padding-left: var(--espace-7); margin: 0 0 var(--espace-9); font-style: italic; color: var(--t-dim); font-size: var(--texte-6); line-height: 1.7; }
.int-li { font-size: var(--texte-6); line-height: 1.72; color: var(--t-secondary); margin: 0 0 var(--espace-5) var(--espace-10); list-style: disc; }
.int-pied { margin-top: 30px; padding-top: var(--espace-9); border-top: 1px solid var(--border); }
.int-lien-nav {
  display: inline-block; margin-top: var(--espace-4); border-radius: var(--radius-rond); padding: var(--espace-4) var(--espace-8);
  font-size: var(--texte-3); font-weight: 600; color: var(--accent);
  border: 1px solid var(--border); background: var(--bg-secondary);
}
.int-lien-nav:hover { border-color: var(--accent); }
.int-lien-inline { margin: var(--espace-3) 0 0; }

/* ── Lecteur vidéo ── la vidéo en grand, les autres en colonne à droite,
   comme la référence. Sous 900 px la colonne passe dessous : côte à côte,
   aucune des deux n'aurait la place. */
.int-video { flex: 1; min-height: 0; overflow-y: auto; display: grid; gap: 22px; padding: var(--espace-10); grid-template-columns: minmax(0, 1fr) 320px; align-items: start; }
.int-video-principal { min-width: 0; }
.int-lecteur { width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-lg); overflow: hidden; background: #000; }
.int-lecteur iframe { width: 100%; height: 100%; border: 0; display: block; }
.int-video-titre { font-size: var(--texte-8); font-weight: 700; line-height: 1.3; color: var(--t-primary); margin: var(--espace-7) 0 var(--espace-3); }
/* ── Vidéo citée dans un message ──
   Le chat montrait un lecteur nu : ni titre, ni chaîne, ni durée. On ne
   savait pas ce qu'on allait lancer. Le bloc porte maintenant sa fiche. */
/* ── LA CARTE VIDÉO ────────────────────────────────────────────────────────
   « Visuellement c'est moche comme elle structure l'affichage de la vidéo. »

   Ce qui n'allait pas, et qui se voit sur la capture : la vignette portait son
   propre arrondi À L'INTÉRIEUR d'une carte déjà arrondie — quatre coins de fond
   noir entre les deux ; le titre en 700 sur deux lignes pesait plus lourd que
   la réponse qui l'entoure ; le bouton « Ouvrir en grand » était une pastille
   bordée, aussi appuyée qu'une action principale, pour un geste secondaire.

   La carte se tait et laisse l'image parler : le titre en 600, la ligne de
   contexte juste dessous, et l'accès à la description en simple lien. */
.yt-bloc { margin: var(--espace-6) 0; max-width: 560px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-secondary); overflow: hidden; }
.yt-bloc-titre { font-size: var(--texte-4); font-weight: 600; line-height: 1.4; color: var(--t-primary); margin: var(--espace-6) var(--espace-6) 0; }
.yt-bloc-attente { color: var(--t-faint); font-weight: 500; }
.yt-bloc-meta { font-size: var(--texte-2); color: var(--t-faint); margin: var(--espace-2) var(--espace-6) 0; }
.yt-bloc-grand {
  display: block; margin: var(--espace-4) var(--espace-6) var(--espace-6); padding: 0;
  font-size: var(--texte-2); font-weight: 600; color: var(--t-dim);
  border: none; background: none; text-align: left;
}
.yt-bloc-grand:hover { color: var(--accent); }

/* La description sous le lecteur : repliée par défaut, sinon un pavé de
   2 000 caractères repousse les commentaires hors de l'écran. */
.int-desc { margin: var(--espace-2) 0 0; border-radius: var(--radius); background: var(--bg-secondary); padding: var(--espace-5) var(--espace-7); }
.int-desc summary { font-size: var(--texte-3); font-weight: 600; color: var(--t-dim); cursor: pointer; }
.int-desc p { font-size: var(--texte-4); line-height: 1.7; color: var(--t-secondary); margin: var(--espace-5) 0 0; white-space: normal; }

.int-commentaires { margin-top: var(--espace-10); padding-top: var(--espace-8); border-top: 1px solid var(--border); }
.int-comm-vide { display: flex; align-items: center; gap: var(--espace-4); flex-wrap: wrap; font-size: var(--texte-3); line-height: 1.65; color: var(--t-faint); }
.int-comm-entete { font-size: var(--texte-4); font-weight: 700; color: var(--t-primary); margin: 0 0 var(--espace-8); }
.int-comm { display: flex; gap: var(--espace-6); margin-bottom: var(--espace-9); }
/* L'initiale de la personne quand l'avatar manque ou est refusé : un rond
   vide au même endroit ferait croire à une image en train de charger. */
.int-comm-av {
  flex: 0 0 34px; width: 34px; height: 34px; border-radius: 50%; overflow: hidden;
  background: var(--bg-tertiary); display: flex; align-items: center; justify-content: center;
  font-size: var(--texte-4); font-weight: 700; color: var(--t-faint);
}
.int-comm-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.int-comm-corps { min-width: 0; flex: 1; }
.int-comm-tete { display: flex; align-items: baseline; gap: var(--espace-4); margin: 0 0 var(--espace-2); }
.int-comm-auteur { font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); }
.int-comm-date { font-size: var(--texte-2); color: var(--t-faint); }
.int-comm-txt { font-size: var(--texte-4); line-height: 1.6; color: var(--t-secondary); margin: 0; overflow-wrap: anywhere; }
.int-comm-pied { display: flex; gap: var(--espace-7); margin: var(--espace-3) 0 0; font-size: var(--texte-2); color: var(--t-faint); }
.int-video-cote { min-width: 0; display: flex; flex-direction: column; gap: var(--espace-5); }
.int-cote-entete { font-size: var(--texte-2); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--t-faint); margin: 0 0 var(--espace-1); }
.int-cote { display: flex; gap: var(--espace-5); text-align: left; border-radius: var(--radius); padding: var(--espace-3); background: transparent; }
.int-cote:hover { background: var(--bg-secondary); }
.int-cote-vig { flex: 0 0 128px; height: 72px; border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-tertiary); }
.int-cote-vig img { width: 100%; height: 100%; object-fit: cover; display: block; }
.int-cote-txt { min-width: 0; display: flex; flex-direction: column; gap: var(--espace-2); }
.int-cote-titre {
  font-size: var(--texte-3); font-weight: 600; line-height: 1.35; color: var(--t-primary);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.int-cote-chaine { font-size: var(--texte-2); color: var(--t-faint); }

/* ── Visionneuse d'image ──
   Une image se regarde SUR PLACE, comme une vidéo. `contain` et non `cover` :
   une photo recadrée n'est plus la photo qu'on a cliquée. La hauteur est bornée
   pour qu'un panorama ne repousse pas le reste hors de l'écran. */
.int-photo {
  width: 100%; max-height: 66vh; border-radius: var(--radius-lg); overflow: hidden;
  background: var(--bg-tertiary); display: flex; align-items: center; justify-content: center;
}
.int-photo img { max-width: 100%; max-height: 66vh; object-fit: contain; display: block; }
.int-cote-grille { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--espace-4); }
.int-cote-img { border-radius: var(--radius-sm); overflow: hidden; aspect-ratio: 1 / 1; background: var(--bg-tertiary); padding: 0; }
.int-cote-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.int-cote-img:hover { outline: 2px solid var(--accent); }

.int-etat { display: flex; flex-direction: column; align-items: center; gap: var(--espace-5); padding: 40px var(--espace-10); color: var(--t-faint); font-size: var(--texte-4); text-align: center; }
.int-spin { width: 15px; height: 15px; border-radius: 50%; border: 2px solid var(--border); border-top-color: var(--accent); animation: dec-tourne .7s linear infinite; }

@media (max-width: 900px) {
  .int-video { grid-template-columns: 1fr; }
  .int-cote-vig { flex-basis: 108px; height: 61px; }
}
@media (max-width: 640px) {
  .int-article { padding: var(--espace-8) var(--espace-7) 60px; }
  .int-titre { font-size: var(--texte-10); }
}

/* ── Le visuel d'une carte n'est jamais vide ──
   Sans image, la carte le DIT — une icône « pas de photo » et le nom complet
   de la source, sur un fond dérivé de son domaine — plutôt qu'une initiale
   géante qui se lisait comme un chargement qui traîne. Un fil où une carte
   sur trois n'a qu'un rectangle gris ne ressemble pas à un fil d'actualité ;
   celui-ci se lit d'un coup d'œil comme un état assumé. */
.dec-visuel-vide {
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg,
    hsl(var(--dec-teinte, 210deg) 42% 42%),
    hsl(calc(var(--dec-teinte, 210deg) + 38deg) 46% 30%));
}
.dec-sans-image {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 0 14px; color: rgba(255,255,255,.9); max-width: 100%;
}
.dec-sans-image-nom {
  font-size: var(--texte-12); font-weight: 700; letter-spacing: .01em;
  text-align: center; overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.dec-carte-large .dec-sans-image-nom { font-size: var(--texte-14); }

/* Les cartes sont devenues des <button> : rétablir l'alignement du texte, que
   le style par défaut des boutons centre. */
.dec-carte, .rch-lien, .rch-actu, .rch-video, .rch-entite, .rch-image { text-align: left; }

/* ── LE SIXIÈME ÉCRAN : LA RÉALITÉ ────────────────────────────────────────────
   Les cinq premiers écrans montrent ce que la conversation a RAMENÉ. Celui-ci
   montre ce que CREA EST : l'émulateur lit les organes, compose le corps, et
   l'écran le rend habitable.

   Tout passe par les variables de thème existantes. Un écran immersif qui code
   ses couleurs en dur est un écran qui ne suit pas le thème sombre — et c'est
   celui-là qu'on regarde le plus longtemps. */
.realite-ecran { display:flex; flex-direction:column; gap:var(--espace-7); }
.realite-tete { display:flex; align-items:flex-start; justify-content:space-between; gap:var(--espace-6); flex-wrap:wrap; }
.realite-titre { font-size:var(--texte-6); font-weight: 700; color:var(--t-primary); }
.realite-sous { font-size:var(--texte-2); color:var(--t-faint); margin-top:var(--espace-1); }
.realite-actions { display:flex; gap:var(--espace-3); }
.realite-btn { font-size:var(--texte-3); padding:var(--espace-3) var(--espace-6); border-radius: var(--radius-sm); border:1px solid var(--border); background:var(--bg-secondary); color:var(--t-secondary); cursor:pointer; }
.realite-btn:hover { background:var(--bg-input); }
.realite-btn-sortir { color:var(--accent); }

/* PLUSIEURS RÉALITÉS OUVERTES. Les onglets n'apparaissent qu'à partir de deux :
   un sélecteur à un élément n'apprend rien et prend une ligne. */
.realite-onglets { display:flex; flex-wrap:wrap; gap:var(--espace-3); }
.realite-onglet { font-size:var(--texte-2); padding:var(--espace-2) var(--espace-5); border-radius: var(--radius-rond); border:1px solid var(--border); background:var(--bg-secondary); color:var(--t-dim); cursor:pointer; }
.realite-onglet:hover { background:var(--bg-input); color:var(--t-secondary); }
.realite-onglet-actif { background:var(--accent-bg); border-color:var(--accent); color:var(--accent); }
.realite-onglet-plus { color:var(--t-faint); }

/* LA TENSION — pas une panne, pas un fonctionnement ordinaire non plus.
   Elle est donc dessinée entre les deux : visible sans crier. Un bandeau
   d'alerte ici ferait passer pour cassé un cas qui, la plupart du temps, se
   résoudra tout seul selon l'ordre de sortie. */
.realite-tension { border:1px dashed var(--accent); border-radius: var(--radius); padding:var(--espace-5) var(--espace-6); background:var(--bg-secondary); }
.realite-tension-titre { font-size:var(--texte-3); font-weight: 700; color:var(--t-primary); }
.realite-tension-l { font-size:var(--texte-2); color:var(--t-secondary); margin-top:var(--espace-2); }
.realite-tension-note { font-size:var(--texte-1); color:var(--t-faint); margin-top:var(--espace-3); font-style:italic; }

/* Le battement est la seule chose de cet écran qui bouge sans qu'on la
   touche : il se distingue du reste, sans clignoter. */
.realite-battement { border-color:var(--accent); }
.realite-battement .realite-organe { margin-right:var(--espace-2); }

.realite-corps { display:grid; grid-template-columns:repeat(auto-fill,minmax(min(220px,100%),1fr)); gap:var(--espace-5); }
.realite-partie { border:1px solid var(--border); border-radius: var(--radius); padding:var(--espace-6) var(--espace-6); background:var(--bg-secondary); }
.realite-partie-nom { font-size:var(--texte-3); font-weight: 700; color:var(--t-primary); }
.realite-partie-role { font-size:var(--texte-2); color:var(--t-faint); margin-top:var(--espace-1); }
.realite-partie-organes { display:flex; flex-wrap:wrap; gap:var(--espace-2); margin-top:var(--espace-4); }
.realite-organe { font-size:var(--texte-1); padding:var(--espace-1) var(--espace-4); border-radius: var(--radius-rond); background:var(--accent-bg); color:var(--accent); }
.realite-vide { font-size:var(--texte-1); color:var(--t-faint); font-style:italic; }

.realite-bloc { border:1px solid var(--border); border-radius: var(--radius); padding:var(--espace-6) var(--espace-6); }
.realite-bloc-titre { font-size:var(--texte-2); font-weight: 700; text-transform:uppercase; letter-spacing:.04em; color:var(--t-faint); margin-bottom:var(--espace-3); }
.realite-bloc-l { font-size:var(--texte-2); color:var(--t-secondary); line-height:1.6; word-break:break-word; }
.realite-bloc-note { font-size:var(--texte-1); color:var(--t-faint); margin-top:var(--espace-3); font-style:italic; }
.realite-horscarte { color:var(--t-dim); }

/* Une réalité dont on ne sort pas doit se voir de loin. */
.realite-piege { border:1px solid var(--accent); border-radius: var(--radius); padding:var(--espace-6) var(--espace-6); background:var(--accent-bg); }
.realite-piege-titre { font-size:var(--texte-3); font-weight: 700; color:var(--accent); }
.realite-piege-l { font-size:var(--texte-2); color:var(--t-secondary); margin-top:var(--espace-2); }
.realite-piege-note { font-size:var(--texte-2); color:var(--t-faint); margin:var(--espace-3) 0 var(--espace-4); }

/* ── LES RENVOIS DE CITATION ──────────────────────────────────────────────────
   Les modèles citent en notes de bas de page. marked ne connaît pas cette
   syntaxe : `[^1]` devenait un lien libellé « ^1 » au milieu d'une phrase, et
   la ligne de définition s'affichait avec l'adresse en clair.

   Le renvoi emprunte le langage visuel de la pastille de recherche, à dessein :
   deux façons de citer dans la même réponse, avec deux apparences, se liraient
   comme deux choses différentes alors que c'en est une seule. */
/* Le renvoi porte un NOM DE SITE, plus un chiffre (voir src/crea-citations.js).
   Ce qui change ici : `min-width` et `tabular-nums` visaient un caractère isolé
   et n'ont plus d'objet ; le nom, lui, ne doit jamais être coupé en fin de
   ligne — un domaine tronqué sur deux lignes devient deux mots qui ne veulent
   rien dire. La pastille reste discrète : elle accompagne la phrase, elle ne la
   remplace pas. */
.cite-ref {
  display: inline-flex; align-items: center; justify-content: center;
  height: 16px; padding: 0 var(--espace-3); margin: 0 var(--espace-1);
  border-radius: var(--radius-xs); vertical-align: 1px;
  font-size: var(--texte-1); font-weight: 600; line-height: 1;
  white-space: nowrap;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent); text-decoration: none;
  transition:  background var(--duree-1) var(--courbe);
}
.cite-ref:hover { background: color-mix(in srgb, var(--accent) 20%, transparent); text-decoration: none; }

/* LE NOM DE LA BRANCHE S'EFFACE QUAND LA BARRE SE SERRE.
   La barre du haut porte déjà le duo de navigation et le bouton éphémère. Sous
   380 px, le nom serait tronqué à deux lettres — une icône lisible vaut mieux
   qu'un mot coupé. Le bouton garde son intitulé dans son `title`. */
@media (max-width: 380px) {
  .crea-branche-nom { display: none; }
}

/* ── LU, ET GARDÉ ────────────────────────────────────────────────────────
   « Tu reviens trois fois dans la journée et tu revois les mêmes titres. »

   ON ATTÉNUE, ON NE CACHE PAS. Masquer un sujet lu ferait disparaître celui
   qu'on voulait justement retrouver, et un fil qui efface ce qu'on a vu
   devient impossible à parcourir deux fois dans la même journée. Un titre
   pâli se saute d'un coup d'œil et se relit quand on veut.

   L'atténuation revient au SURVOL : sans ça, une carte lue serait aussi une
   carte difficile à relire, et on aurait remplacé une gêne par une autre. */
.dec-carte-enveloppe { position: relative; display: block; }
.dec-carte-lu { opacity: .58; }
.dec-carte-lu:hover { opacity: 1; }
.dec-carte-lu .dec-titre { font-weight: 500; }

/* Le signet vit À CÔTÉ de la carte, pas dedans : un <button> dans un <button>
   n'est pas du HTML valide, et le navigateur défait l'imbrication — le signet
   se retrouverait hors du cadre de sa carte. */
.dec-signet {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: var(--radius-sm); cursor: pointer;
  color: #fff; background: rgba(0,0,0,.42);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  opacity: 0; transition:  opacity var(--duree-2) var(--courbe), background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe);
}
/* Il apparaît au survol — sauf quand il est ACTIF : un article gardé doit se
   voir sans avoir à passer la souris dessus, sinon on ne sait plus ce qu'on a
   gardé. Et au doigt, il n'y a pas de survol : il reste visible en tactile. */
.dec-carte-enveloppe:hover .dec-signet,
.dec-signet:focus-visible,
.dec-signet.on { opacity: 1; }
.dec-signet.on { color: #f59e0b; background: rgba(0,0,0,.55); }
.dec-signet:hover { background: rgba(0,0,0,.62); }
@media (hover: none) { .dec-signet { opacity: .85; } }

/* Le champ de recherche du Fil rétrécit plutôt que de pousser les onglets à la
   ligne : sur un écran étroit, une barre d'onglets qui saute d'une ligne à
   l'autre selon ce qu'on tape est plus gênante qu'un champ court. */
@media (max-width: 640px) {
  .dec-recherche input { width: 92px !important; }
}

/* Les propositions d'orthographe, sous la barre de question.
   Discrètes par construction : elles n'apparaissent que s'il y a quelque chose
   à dire, et elles ne déplacent jamais la barre — une barre qui saute pendant
   qu'on écrit est insupportable. */
.crea-propositions {
  display: flex; flex-wrap: wrap; gap: var(--espace-3); align-items: center;
  padding: var(--espace-2) var(--espace-5) var(--espace-3);
}
.crea-propositions .crea-prop-label { font-size: var(--texte-2); color: var(--t-faint); }
.crea-prop {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  border-radius: var(--radius-rond); padding: var(--espace-1) var(--espace-5);
  font-size: var(--texte-2); font-weight: 500; cursor: pointer;
  background: var(--bg-input); border: 1px solid var(--border); color: var(--t-secondary);
  transition:  background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe), border-color var(--duree-2) var(--courbe);
}
.crea-prop:hover { border-color: var(--accent); color: var(--accent); }
.crea-prop .crea-prop-de { text-decoration: line-through; opacity: .55; }
/* Une SUITE n'est pas une correction : elle ne barre rien, elle propose. On la
   distingue à l'œil, sinon les deux se lisent comme la même chose et on clique
   sur l'une en croyant cliquer sur l'autre. */
.crea-prop-suite {
  max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: var(--accent-bg); border-color: transparent; color: var(--accent);
}
.crea-prop-suite:hover { border-color: var(--accent); }

/* ── LA RANGÉE D'ONGLETS DANS LA BARRE DE FENÊTRE ───────────────────────────
   Elle y monte depuis l'en-tête (voir mountElectronTitlebar). Son fond propre
   (--bg-secondary) y dessinerait une pastille grise au milieu d'une bande unie
   de --bg-primary : la couture qu'on vient justement d'effacer reviendrait,
   juste au centre au lieu du bord. */
#tb-onglets .chat-view-tabs-bar { background:transparent; padding:0; }
#tb-onglets .chat-view-tab { padding:var(--espace-2) var(--espace-5); font-size:var(--texte-3); }
/* PAS DE width:100% ICI. Le conteneur est en position absolue et se dimensionne
   sur son contenu ; lui demander 100 % de ce contenu est circulaire, et le
   navigateur tranche à ZÉRO. Mesuré : wrap et barre à 0 px de large, les six
   boutons débordant d'un conteneur vide, posés à x=202 au lieu du centre. */
#tb-onglets .chat-view-tabs-wrap { width:auto; }

/* ═══════════════════════════════════════════════════════════════════════════
 * L'ANNEAU DE FOCUS NE S'ANIME PAS
 *
 * ── CE QUE J'AI CRU, ET CE QUI ÉTAIT VRAI ──────────────────────────────────
 *
 * Relevé du source : 54 `outline:none`, une seule règle `:focus-visible`, 69
 * cliquables hors du parcours clavier. J'en ai conclu que le focus manquait.
 *
 * En tabulant vraiment dans l'application : 16 commandes sur 19 avaient déjà un
 * anneau, et AUCUN cliquable n'était hors parcours. L'anneau existait — il est
 * plus haut dans cette feuille (ligne ~2546), il gère les champs à part avec une
 * `box-shadow`, et il prend même la couleur de l'univers du studio courant.
 * C'est la quatrième fois cette session que je mesure l'absence d'un MOT au
 * lieu de l'absence d'un COMPORTEMENT.
 *
 * ── LE DÉFAUT RÉEL, TROUVÉ AU DÉBOGUEUR ────────────────────────────────────
 *
 * Trois commandes ressortaient avec `outline-width: 0` alors que la règle
 * disait 2px. La cause n'était pas la cascade : c'était `transition-all`, la
 * classe utilitaire posée sur ces boutons. Elle anime TOUT, y compris
 * l'épaisseur de l'anneau — et la `box-shadow` qui sert d'anneau aux champs.
 * Le signe part donc de zéro et met cent cinquante millisecondes à arriver.
 *
 * Au clavier, on enchaîne les tabulations plus vite que ça. Ce n'est pas un
 * anneau invisible, c'est un anneau EN RETARD : ça se lit pareil, et ça se
 * diagnostique beaucoup moins bien.
 *
 * On énumère donc ce qui a le droit de s'animer, au lieu de laisser `all` tout
 * embarquer. Le fond, la couleur, la bordure et l'échelle gardent leur
 * transition. Ni l'anneau, ni l'ombre qui en tient lieu.
 * ═══════════════════════════════════════════════════════════════════════════ */
:focus-visible {
  transition-property: background-color, color, border-color, opacity, transform !important;
}

/* LA ZONE DE SAISIE DE L'ACCUEIL — LA DERNIÈRE SANS SIGNE.
 *
 * Mesurée en tabulant : 18 commandes sur 19 montraient leur anneau, celle-ci
 * non. Sa classe utilitaire `outline-none` et l'ombre de la règle générique se
 * neutralisaient — l'une retirait le contour, l'autre n'arrivait pas jusqu'à
 * elle. C'est la commande la plus utilisée de l'application : c'est là qu'on
 * écrit.
 *
 * `box-shadow` et non `outline` : le champ est posé DANS une barre arrondie,
 * et un contour extérieur déborderait sur elle. L'ombre épouse la boîte.
 */
/* ── L'ANNEAU EST PARTI DU CHAMP, IL EST PASSÉ SUR L'ENVELOPPE ──────────
 *
 * « il y a un carré vert qui vient entourer la barre de questions, à chaque
 *  fois que je clique dessus pour écrire. C'est moche, supprime-le. »
 *
 * C'était bien un carré, et c'était moi. L'anneau portait
 * `border-radius: var(--radius-sm)` — 8 px — à l'intérieur d'une barre
 * arrondie à 20. Un rectangle plus anguleux que ce qu'il entoure ne se lit pas
 * comme un contour : il se lit comme un cadre posé par-dessus.
 *
 * ET IL SORTAIT À CHAQUE CLIC, ce qui n'est pas un défaut mais la règle du
 * navigateur : `:focus-visible` s'applique TOUJOURS aux champs de texte, souris
 * comprise, parce qu'on est censé y taper. Le réserver au clavier n'était donc
 * pas une option.
 *
 * ── CE QU'ON NE FAIT PAS : LE SUPPRIMER TOUT COURT ─────────────────────
 *
 * Savoir où l'on écrit reste nécessaire. Mais dans un champ de texte, le
 * curseur qui clignote EST déjà l'indicateur le plus fort qui soit — l'anneau
 * n'ajoutait qu'un cadre.
 *
 * Le signal passe donc sur L'ENVELOPPE, qui a la bonne forme et le bon rayon :
 * sa bordure prend l'accent quand le champ reçoit le focus. Discret, épousant
 * la barre, et toujours là. */
.composer-enveloppe:focus-within {
  border-color: var(--accent) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * LA MAIN QUI TREMBLE — VINGT-QUATRE PIXELS, PAS MOINS
 *
 * ── CE QUI A ÉTÉ MESURÉ ────────────────────────────────────────────────────
 *
 * Les six conditions de la couche « contexte », éprouvées dans un navigateur :
 *
 *   téléphone (390 px)      rien à signaler
 *   écran large (1600 px)   TROIS cibles sous 24×24
 *   texte à 200 %           aucun débordement, la page tient
 *   animations coupées      ZÉRO élément encore animé — respecté partout
 *
 * L'application tenait déjà. Le seul défaut réel : trois commandes qui manquent
 * de un à quatre pixels sur UNE dimension.
 *
 *   #btn-deplier-sessions    20 × 56   (il manque 4 en largeur)
 *   #btn-crea-space         167 × 23   (il manque 1 en hauteur)
 *   #btn-dismiss-install     23 × 32   (il manque 1 en largeur)
 *
 * ── POURQUOI VINGT-QUATRE, ET POURQUOI ÇA COMPTE ───────────────────────────
 *
 * C'est le minimum de WCAG 2.2 (critère 2.5.8). Ce n'est pas une marge de
 * confort : c'est la taille en dessous de laquelle une main qui tremble, un
 * doigt sur un écran, ou une souris tenue de travers ratent la cible et
 * cliquent à côté — souvent sur ce qui se trouve juste à côté.
 *
 * Un pixel qui manque ne se voit pas ; il se rate. C'est exactement le genre de
 * défaut qu'on n'attrape pas en regardant, seulement en mesurant.
 *
 * ── ON VISE, ON NE RATISSE PAS ─────────────────────────────────────────────
 *
 * Une règle qui imposerait 24 px à TOUS les boutons casserait des mises en page
 * réglées au pixel, pour corriger trois cas. On nomme les trois.
 * ═══════════════════════════════════════════════════════════════════════════ */
#btn-deplier-sessions, #btn-crea-space, #btn-dismiss-install {
  min-width: 24px;
  min-height: 24px;
}

/* ── LA BARRE LATÉRALE EN SURVOL ──────────────────────────────────────────
 *
 * « Quand on approche la souris du bouton menu, elle apparaît en survol, et on
 *  peut naviguer dedans sans l'ouvrir en grand. Notre système, ça rend tout
 *  magnifique. »
 *
 * Elle entre depuis le bord, posée par-dessus la conversation. Rien ne se
 * décale sous elle — c'est ce qui distingue consulter d'ouvrir : la phrase
 * qu'on est en train de lire ne bouge pas d'un pixel.
 *
 * Même durée et même courbe que l'ouverture pour de vrai (--crea-sb-duree,
 * --crea-sb-courbe) : deux gestes voisins qui n'auraient pas le même rythme se
 * verraient comme deux mécanismes différents. */
/* Elle part de HORS de l'écran, marge comprise : sans elle, la carte
 * commencerait son entrée en montrant déjà douze pixels d'elle-même au bord. */
@keyframes creaCarteEntree {
  from { transform: translateX(calc(-1 * (var(--crea-sb-largeur) + var(--crea-sb-marge)))); opacity: .4 }
  to   { transform: translateX(0); opacity: 1 }
}
.sidebar-carte {
  animation: creaCarteEntree var(--crea-sb-duree) var(--crea-sb-courbe) both;
}
/* Les coins arrondis tiennent par `overflow:hidden`, posé sur la barre
 * elle-même : les rangées à fond plein qu'elle contient sont alors coupées par
 * la courbe au lieu de la recarrer par le haut et par le bas. */

/* ── LA DEMANDE D'AUTORISATION SE LIT ──────────────────────────────────────
   La commande était collée dans la phrase et coupée à 200 caractères : une
   ligne PowerShell arrivait tronquée au milieu d'un Select-Object, en prose,
   dans une boîte de 360px. On autorisait sans avoir lu — donc sans décider.
   Ici elle est entière, en monospace, et défile si elle est longue. */
.crea-accord-code {
  margin: 0 0 var(--espace-6);
  padding: var(--espace-6) var(--espace-7);
  max-height: 40vh; overflow: auto;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: var(--texte-2); line-height: 1.6;
  color: var(--t-primary);
  /* Une commande ne se coupe pas n'importe où : on préserve les espaces et on
     ne replie que quand il n'y a plus le choix. */
  white-space: pre-wrap; overflow-wrap: anywhere;
}
/* Les faits — outil, dossier, interpréteur — chacun sur sa ligne, jamais
   noyés dans le texte : ce sont eux qu'on relit avant de cliquer. */
.crea-accord-meta { margin-bottom: var(--espace-8); display: flex; flex-direction: column; gap: 2px; }
.crea-accord-meta > div { display: flex; gap: var(--espace-5); align-items: baseline; font-size: var(--texte-2); }
.crea-accord-meta span { color: var(--t-faint); min-width: 6.5rem; flex-shrink: 0; }
.crea-accord-meta code {
  color: var(--t-secondary); font-family: 'JetBrains Mono', ui-monospace, monospace;
  overflow-wrap: anywhere;
}

/* ── LA DEMANDE EST DANS LE FIL, PAS AU MILIEU DE L'ÉCRAN ─────────────────
   « Pourquoi tu commences à me faire des choses en plein milieu de l'écran
    comme ça ? Il y a un bloc qui apparaît PAR-DESSUS LA BARRE DE QUESTIONS. »

   J'avais fait une modale centrée avec un fond noirci. Une modale dit « arrête
   tout et réponds » — et en noircissant la page, elle cache justement ce qui
   permet de juger : ce que CREA vient d'écrire, l'étape qu'elle exécute. On
   répond alors hors contexte, et « Autoriser » devient un réflexe.

   Ici : posé au-dessus de la saisie, à la largeur de la barre, rien de masqué.
   Pas d'ombre portée — elle ferait flotter le bloc au-dessus de la page, et
   c'est précisément ce qu'on ne veut plus. Une bordure discrète, pas la
   couleur d'accent : le bloc n'a pas à crier, il a à être lu. */
.crea-accord-bloc {
  /* POSÉ SUR LA BARRE, pas flottant au-dessus. « T'as bien vu comment c'est
     posé sur la barre de questions ? » Il y avait une marge entre les deux :
     deux cartes, chacune avec ses quatre coins ronds — donc deux objets, alors
     que c'est un seul geste. Le -1px fait se recouvrir les deux bordures : une
     seule ligne au lieu de deux collées, qui feraient un trait épais. */
  margin-bottom: -1px;
  padding: var(--espace-7) var(--espace-8);
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  /* EN LONGHAND, COMME LA BARRE EN DESSOUS. Écrire les quatre coins d'un coup
     aurait posé une valeur de rayon de plus dans un dépôt qui en tolère trente
     (tests/forme-echelle-smoke.mjs) — pour une forme qui n'est pas nouvelle :
     c'est le rayon habituel, avec deux coins mis à plat parce qu'ils touchent
     la barre. Dire QUELS coins sont plats décrit ce qui se passe ; réécrire les
     quatre inventait une forme pour n'en changer que la moitié. */
  border-top-left-radius: var(--radius-xl);
  border-top-right-radius: var(--radius-xl);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
/* Et la barre en dessous perd ses coins hauts : l'ensemble n'en a plus que
   quatre, aux extrémités, comme un seul bloc. */
.composer-enveloppe.composer-sous-accord {
  /* Même raison qu'au-dessus : la barre garde exactement le rayon qu'elle
     avait, on lui retire seulement ses deux coins hauts, qui touchent le bloc.
     (Et le commentaire ne réécrit pas la règle qu'il explique : le compteur de
     formes lit le fichier, pas seulement le code — une écriture citée en prose
     compte comme une forme de plus. Vingt-et-unième fois qu'une garde pleure
     sur ma propre phrase.) */
  border-top-left-radius: 0 !important;
  border-top-right-radius: 0 !important;
}
.crea-accord-ou {
  margin: 0 0 var(--espace-3);
  font-size: var(--texte-1); color: var(--t-faint);
  text-transform: uppercase; letter-spacing: .04em;
}
.crea-accord-question {
  margin: 0 0 var(--espace-6);
  font-size: var(--texte-4); font-weight: 600; line-height: 1.45;
  color: var(--t-primary);
}
/* CE QUI COURT PENDANT QU'ON LIT. Le bloc restait affiché pour toujours alors
   que le serveur, lui, renonce au bout de deux minutes : on répondait à 8 h à
   une demande morte à 4 h 08, et rien ne partait. L'heure est donc DITE — et
   elle est dite en gris, sous la question : c'est une échéance, pas un
   avertissement, et la peindre en rouge ferait tourner l'œil vers elle plutôt
   que vers la commande qu'on est censé lire. */
.crea-accord-delai {
  display: flex; flex-wrap: wrap; gap: var(--espace-4);
  margin: calc(-1 * var(--espace-4)) 0 var(--espace-6);
  font-size: var(--texte-1); color: var(--t-faint);
}
.crea-accord-delai span {
  padding: 0 var(--espace-4);
  border-left: 1px solid var(--border);
  color: var(--t-secondary);
}

/* ── LA DEMANDE D'AUTORISATION SE LIT ──────────────────────────────────────
   La commande était collée dans la phrase et coupée à 200 caractères : une
   ligne PowerShell arrivait tronquée au milieu d'un Select-Object, en prose,
   dans une boîte de 360px. On autorisait sans avoir lu — donc sans décider.
   Ici elle est entière, en monospace, et défile si elle est longue. */
.crea-accord-code {
  margin: 0 0 var(--espace-6);
  padding: var(--espace-6) var(--espace-7);
  max-height: 40vh; overflow: auto;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: var(--texte-2); line-height: 1.6;
  color: var(--t-primary);
  /* Une commande ne se coupe pas n'importe où : on préserve les espaces et on
     ne replie que quand il n'y a plus le choix. */
  white-space: pre-wrap; overflow-wrap: anywhere;
}
/* Les faits — outil, dossier, interpréteur — chacun sur sa ligne, jamais
   noyés dans le texte : ce sont eux qu'on relit avant de cliquer. */
/* ── LA QUESTION À CHOIX ───────────────────────────────────────────────────
   Sa photo : chaque option porte un TITRE et une EXPLICATION, pas seulement un
   libellé. Une option sans ce qu'elle implique se choisit au hasard.
   Le numéro (ou la case) est à GAUCHE, comme sur sa capture : c'est par lui
   qu'on entre dans la ligne, au clavier comme à l'œil. */
/* ── PLUSIEURS QUESTIONS, UNE À LA FOIS ────────────────────────────────────
   « Cette forme que tu utilises aussi par-dessus la barre de questions, pour
    en plusieurs étapes. »
   Sa photo : « 2 sur 2 » entre deux flèches à gauche, la croix à droite. Le
   compteur n'est pas décoratif — il dit qu'il RESTE quelque chose, et c'est la
   seule chose qui empêche d'envoyer en croyant avoir tout vu. */
.crea-question-entete {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--espace-5); margin-bottom: var(--espace-4);
}
.crea-question-pas { display: flex; align-items: center; gap: var(--espace-3); }
.crea-question-pas span {
  font-size: var(--texte-2); color: var(--t-secondary); font-variant-numeric: tabular-nums;
}
.crea-question-pas button, .crea-question-fermer {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.75rem; height: 1.75rem;
  background: transparent; border: none; border-radius: var(--radius-rond);
  font-size: var(--texte-4); line-height: 1; color: var(--t-secondary); cursor: pointer;
  transition: background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe), border-color var(--duree-2) var(--courbe);
}
.crea-question-pas button:hover:not(:disabled), .crea-question-fermer:hover { background: var(--bg-secondary); color: var(--t-primary); }
/* Une flèche au bout de la liste reste VISIBLE et cesse d'agir : la faire
   disparaître déplacerait le compteur à chaque pas, et on perdrait le repère
   qu'on vient de lire. */
.crea-question-pas button:disabled { opacity: .3; cursor: default; }

.crea-question-options {
  margin: 0 0 var(--espace-6);
  display: flex; flex-direction: column; gap: var(--espace-2);
}
.crea-question-option {
  display: flex; align-items: flex-start; gap: var(--espace-5);
  width: 100%; text-align: left;
  padding: var(--espace-5) var(--espace-6);
  background: transparent;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe), border-color var(--duree-2) var(--courbe);
}
.crea-question-option:hover { border-color: var(--border-hov); background: var(--bg-secondary); }
.crea-question-option.crea-question-prise { border-color: var(--accent); background: var(--accent-bg); }
.crea-question-marque {
  flex-shrink: 0; margin-top: 1px;
  font-size: var(--texte-3); color: var(--t-faint); line-height: 1.4;
}
.crea-question-corps { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.crea-question-titre {
  font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); line-height: 1.4;
}
/* « Recommandé » se lit à côté du titre, pas au-dessus : c'est une nuance de
   l'option, pas une catégorie. */
.crea-question-titre em {
  margin-left: var(--espace-3);
  font-style: normal; font-size: var(--texte-1); font-weight: 500;
  color: var(--accent);
}
.crea-question-detail {
  font-size: var(--texte-2); line-height: 1.5; color: var(--t-dim);
  overflow-wrap: anywhere;
}
/* « AUTRE » A LE MÊME POIDS QU'UNE OPTION. Une réponse hors de la liste n'est
   pas un contournement : c'est le signe que les options manquaient quelque
   chose. Un trait, pas un cadre : le champ appartient à la liste au-dessus. */
.crea-question-autre {
  display: flex; align-items: baseline; gap: var(--espace-5);
  margin: 0 0 var(--espace-7); padding: var(--espace-4) var(--espace-6);
  border: 1px dashed var(--border); border-radius: var(--radius-sm);
}
.crea-question-autre span {
  flex-shrink: 0; font-size: var(--texte-2); color: var(--t-faint);
}
.crea-question-autre input {
  flex: 1; min-width: 0;
  background: transparent; border: none; outline: none;
  font-size: var(--texte-2); color: var(--t-primary);
}

/* ── LE PLAN SE LIT AVANT D'ÊTRE ACCEPTÉ ───────────────────────────────────
   Même cadre que la demande d'autorisation, même emplacement, même grammaire
   de boutons : un seul endroit où CREA pose ses questions. Ce qui change, c'est
   le contenu — un texte suivi et des étapes, là où l'autorisation montre une
   commande. */
.crea-plan-texte {
  margin: 0 0 var(--espace-6);
  font-size: var(--texte-3); line-height: 1.6;
  color: var(--t-secondary);
  white-space: pre-wrap; overflow-wrap: anywhere;
  max-height: 34vh; overflow: auto;
}
.crea-plan-etapes {
  margin: 0 0 var(--espace-6); padding-left: var(--espace-8);
  display: flex; flex-direction: column; gap: var(--espace-2);
  font-size: var(--texte-2); line-height: 1.55;
  color: var(--t-secondary);
  list-style: decimal;
}
/* CE QU'ELLE N'A PAS PU VÉRIFIER SE LIT AVANT DE DÉCIDER, PAS APRÈS.
   Un plan qui n'affiche que ses certitudes se fait accepter plus vite et se
   paie plus tard. Un trait à gauche, sans fond : présent, pas alarmant. */
.crea-plan-angle {
  margin: 0 0 var(--espace-7); padding-left: var(--espace-6);
  border-left: 2px solid var(--border-hov);
}
.crea-plan-angle span {
  display: block; margin-bottom: 2px;
  font-size: var(--texte-1); color: var(--t-faint);
  text-transform: uppercase; letter-spacing: .04em;
}
.crea-plan-angle p {
  margin: 0; font-size: var(--texte-2); line-height: 1.5; color: var(--t-secondary);
}

.crea-accord-meta { margin-bottom: var(--espace-7); display: flex; flex-direction: column; gap: 2px; }
.crea-accord-meta > div { display: flex; gap: var(--espace-5); align-items: baseline; font-size: var(--texte-2); }
.crea-accord-meta span { color: var(--t-faint); min-width: 6.5rem; flex-shrink: 0; }
.crea-accord-meta code {
  color: var(--t-secondary); font-family: 'JetBrains Mono', ui-monospace, monospace;
  overflow-wrap: anywhere;
}

/* ── LES CHOIX SONT DES BOUTONS EN LIGNE ───────────────────────────────────
   Sur sa photo : « Refuser 1 Esc » puis « Autoriser une fois 2 Ctrl+Enter ».
   Le libellé d'abord, le numéro et le raccourci ensuite, en petit — on lit
   d'abord ce qu'on choisit, la touche n'est là que pour ceux qui la veulent.

   REFUSER EN PREMIER, et non par politesse : c'est le choix le plus sûr, et il
   arrive sous le curseur avant l'autre. Mettre « Autoriser » en tête ferait de
   l'accord le geste par défaut. */
/* ÉCARTÉS, ET GROUPÉS PAR NATURE. « Tu dois les écarter. Ou sinon tu laisses
   refuser, autoriser une fois d'un côté, et autoriser pour toujours tu le mets
   de l'autre côté tout seul. »
   Les deux réponses à CETTE demande à gauche ; la décision qui vaut pour la
   suite, seule à droite. Collés, les trois se lisaient comme trois réponses de
   même poids, et « toujours » se donnait dans l'élan du geste précédent. */
.crea-accord-choix {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--espace-5);
}
.crea-accord-maintenant { display: flex; flex-wrap: wrap; gap: var(--espace-3); }
/* ── L'ÉCART SURVIT AU REPLI ───────────────────────────────────────────────
   « Tu laisses refuser, autoriser une fois d'un côté, et autoriser pour
    toujours tu le mets de l'autre côté tout seul. »
   `space-between` tient l'écart tant que tout rentre sur une ligne. Dès que ça
   déborde — et les libellés du plan débordent — l'élément qui passe à la ligne
   revient se COLLER à gauche, sous le groupe : les trois se relisent alors
   comme trois réponses de même poids, ce que l'écart existait pour empêcher.
   `margin-left: auto` le renvoie à droite dans les deux cas. */
.crea-accord-choix > :last-child { margin-left: auto; }
.crea-accord-choix button {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  padding: var(--espace-3) var(--espace-6);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-input); color: var(--t-primary);
  font-size: var(--texte-3); cursor: pointer;
  /* CETTE ÉCRITURE-CI EXISTE DÉJÀ dans la feuille — on la reprend au lieu d'en
     inventer une. Le cliquet de la matière visuelle compte les valeurs
     DISTINCTES de mouvement : `background … , border-color …` en --duree-1
     aurait été la cinquante-et-unième pour cinquante tolérées. Une durée de
     plus n'est pas une durée mieux choisie ; c'est une de plus à ne pas
     regarder. */
  transition: background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe), border-color var(--duree-2) var(--courbe);
}
.crea-accord-choix button:hover { background: var(--bg-tertiary); border-color: var(--border-hov); }
.crea-accord-choix button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.crea-accord-choix .crea-accord-libelle { font-weight: 500; }
/* Le numéro : une touche, donc dessinée comme une touche. */
.crea-accord-choix .crea-accord-num {
  flex-shrink: 0; min-width: 1.1rem; height: 1.1rem;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius-xs);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: var(--texte-1); color: var(--t-secondary);
}
.crea-accord-choix .crea-accord-touche {
  flex-shrink: 0;
  font-size: var(--texte-1); color: var(--t-faint);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
/* Autoriser porte la couleur — c'est le geste qui engage. Refuser reste nu :
   le rouge dirait « attention », alors qu'ici c'est autoriser qui demande de
   l'attention, pas refuser. */
.crea-accord-choix button.crea-accord-oui {
  border-color: var(--accent);
  color: var(--accent-texte); background: var(--accent-bg);
}
.crea-accord-choix button.crea-accord-oui:hover { border-color: var(--accent); }
/* La décision durable se tient à l'écart, et se donne à voir comme telle : pas
   de fond, un trait pointillé. Elle n'est pas de la même famille que les deux
   autres — on ne répond pas, on décide pour la suite. */
.crea-accord-choix button.crea-accord-durable {
  background: none; border-style: dashed; color: var(--t-secondary);
}
.crea-accord-choix button.crea-accord-durable:hover { background: var(--bg-input); }

/* ══════════════════════════════════════════════════════════════════════════
   LE FORMULAIRE STRUCTURÉ — décrit par le modèle, dessiné par l'application

   Le modèle n'écrit pas ce style : il écrit un bloc ```crea-form qui dit
   « choix unique, titre, options ». Tout ce qui suit appartient donc à
   l'application, et peut changer sans toucher à une ligne de prompt.

   Même famille que le reste : --radius-lg, le filet d'un pixel, --ombre-2,
   l'élévation de la barre de questions. Un formulaire est une surface posée
   dans la réponse, pas un encadré de plus.
   ═══════════════════════════════════════════════════════════════════════ */
.crea-form {
  margin: 1.15em 0; padding: var(--espace-7);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--bg-primary); box-shadow: var(--ombre-2);
}
.crea-form-titre { font-size: var(--texte-5); font-weight: 700; color: var(--t-primary); margin: 0 0 .2rem; }
.crea-form-intro { font-size: var(--texte-3); color: var(--t-secondary); margin: 0 0 1.1rem; }
.crea-form-bloc { margin: 0 0 1.15rem; }
.crea-form-q { font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); margin: 0 0 .15rem; }
.crea-form-aide { font-size: var(--texte-2); color: var(--t-faint); margin: 0 0 .5rem; }

/* Choix unique, allure segmentée : trois options courtes sur une rangée. */
.crea-form-segments { display: flex; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.crea-form-segment {
  flex: 1; padding: var(--espace-5) var(--espace-6); border: 0; background: transparent;
  font-size: var(--texte-3); color: var(--t-secondary); cursor: pointer;
  transition: background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe);
}
.crea-form-segment + .crea-form-segment { border-left: 1px solid var(--border); }
.crea-form-segment:hover { background: var(--bg-secondary); }
.crea-form-segment.on { background: var(--accent-bg); color: var(--accent); font-weight: 600; }

/* Choix unique, allure liste : au-delà de trois options, ou d'options longues. */
.crea-form-liste { display: flex; flex-direction: column; gap: var(--espace-3); }
.crea-form-radio, .crea-form-ligne {
  display: flex; align-items: center; gap: var(--espace-5);
  width: 100%; text-align: left; cursor: pointer;
  padding: var(--espace-5) var(--espace-6);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-primary); color: var(--t-primary); font-size: var(--texte-3);
  transition: border-color var(--duree-2) var(--courbe), background var(--duree-2) var(--courbe);
}
.crea-form-radio:hover, .crea-form-ligne:hover { border-color: var(--border-hov); background: var(--bg-secondary); }
.crea-form-radio.on { border-color: var(--accent); background: var(--accent-bg); }
.crea-form-puce {
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--border-hov); transition: all var(--duree-2) var(--courbe);
}
.crea-form-radio.on .crea-form-puce { border-color: var(--accent); border-width: 5px; }

/* Cases à cocher : même ligne, la case native suffit et reste accessible. */
.crea-form-ligne { margin-bottom: var(--espace-3); }
.crea-form-ligne input { width: 16px; height: 16px; flex: none; accent-color: var(--accent); }

/* Étiquettes : plusieurs réponses courtes, en pilules. */
.crea-form-chips { display: flex; flex-wrap: wrap; gap: var(--espace-3); }
.crea-form-chip {
  padding: var(--espace-3) var(--espace-6); border-radius: var(--radius-rond);
  border: 1px solid var(--border); background: var(--bg-primary);
  color: var(--t-secondary); font-size: var(--texte-3); cursor: pointer;
  transition: all var(--duree-2) var(--courbe);
}
.crea-form-chip:hover { border-color: var(--border-hov); }
.crea-form-chip.on { border-color: var(--accent); background: var(--accent-bg); color: var(--accent); font-weight: 600; }

/* Texte libre : le compteur est sous le champ, discret, jamais alarmant. */
.crea-form-texte {
  width: 100%; min-height: 88px; resize: vertical;
  padding: var(--espace-5) var(--espace-6);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-input); color: var(--t-primary);
  font: inherit; font-size: var(--texte-3); outline: none;
}
.crea-form-texte:focus { border-color: var(--accent); }
.crea-form-compte { text-align: right; font-size: var(--texte-1); color: var(--t-faint); margin: .25rem 0 0; }

.crea-form-curseur-ligne { display: flex; align-items: center; gap: var(--espace-6); }
.crea-form-curseur { flex: 1; accent-color: var(--accent); }
.crea-form-curseur-ligne output { font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); min-width: 3ch; }

.crea-form-pied { display: flex; justify-content: flex-start; margin-top: var(--espace-7); }
.crea-form-envoi {
  padding: var(--espace-5) var(--espace-8); border: 0; border-radius: var(--radius);
  background: var(--accent); color: #fff; font-size: var(--texte-3); font-weight: 600; cursor: pointer;
  transition: opacity var(--duree-2) var(--courbe);
}
.crea-form-envoi:hover { opacity: .92; }
.crea-form-envoi:disabled { opacity: .55; cursor: default; }
.crea-form :disabled { opacity: .6; }

/* Un formulaire illisible s'affiche en source plutôt que de disparaître : une
   question mal formée doit se voir. */
.crea-form-illisible {
  margin: 1.15em 0; padding: var(--espace-6); border-radius: var(--radius);
  border: 1px dashed var(--warn); background: var(--bg-secondary);
  color: var(--t-secondary); font-size: var(--texte-2); white-space: pre-wrap;
}

/* ── LE PIED DU TOUR ───────────────────────────────────────────────────────
   « ✳ 2m 16s · 2,2k tokens · 3 tâches en cours » — le compte se lit quand il
   est fait, pas avant. Il était posé en TÊTE du bloc, donc annoncé avant que
   le travail commence. Le logo respire tant que ça tourne, se fige une fois
   fini : c'est lui qui dit « ça avance » sans qu'on lise quoi que ce soit. */
.crea-steps-pied {
  display: flex; align-items: center; gap: var(--espace-5);
  padding-top: var(--espace-5);
}
.crea-steps-pied .crea-step-spark.est-fini { animation: none; opacity: .45; }

/* Dépôt de fichiers du formulaire — le pointillé dit « pose quelque chose ici »
   sans imiter un bouton, et l'état plein remplace l'invite par le compte. */
.crea-form-depot {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: var(--espace-8); cursor: pointer; text-align: center;
  border: 1px dashed var(--border-hov); border-radius: var(--radius);
  background: var(--bg-secondary);
  transition: border-color var(--duree-2) var(--courbe), background var(--duree-2) var(--courbe);
}
.crea-form-depot:hover, .crea-form-depot.survol { border-color: var(--accent); background: var(--accent-bg); }
.crea-form-depot.on { border-style: solid; border-color: var(--accent); }
.crea-form-depot-titre { font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); }
.crea-form-depot-aide { font-size: var(--texte-2); color: var(--t-faint); }

/* Intertitre : elle découpe elle-même un formulaire long. */
.crea-form-section {
  margin: var(--espace-8) 0 var(--espace-5); padding-top: var(--espace-6);
  border-top: 1px solid var(--border);
  font-size: var(--texte-2); font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--t-faint);
}

/* Le séparateur du pied : il appartient à la ligne, pas aux mesures qu'il
   sépare — sans quoi le chrono ne pourrait pas être remplacé seul. */
.crea-pied-sep { color: var(--t-faint); }

/* LA SEULE PORTE DU PIED. « Les tâches en cours, quand on clique dessus, ça
   ouvre le panneau de tâches en arrière-plan. » Elle se lit comme le reste du
   pied — même taille, même couleur, aucun cadre : ce n'est pas un bouton posé
   dans une ligne de mesures, c'est une mesure sur laquelle on peut appuyer.
   Le soulignement pointillé au survol est le seul signe qu'elle mène quelque
   part, et il n'apparaît qu'au moment où l'on vise. */
.crea-pied-porte {
  font: inherit; color: inherit; background: none; border: 0; padding: 0;
  cursor: pointer; text-underline-offset: 3px;
}
.crea-pied-porte:hover,
.crea-pied-porte:focus-visible { color: var(--accent); text-decoration: underline dotted; }

/* ── DÉMARRAGE DE SECOURS ──────────────────────────────────────────────────
   Une protection dont on ne peut pas sortir n'est plus une protection. Le mode
   dégradé ne se signalait que par un console.warn : l'usager voyait une
   application vide, sans explication, et son réflexe — recharger — relançait le
   compteur qui l'y avait mis. Ce bandeau dit ce qui se passe et rend la main. */
#crea-bandeau-degrade {
  position: fixed; inset: auto 0 0 0; z-index: 99999;
  display: flex; align-items: center; justify-content: center; gap: var(--espace-7);
  padding: var(--espace-7) var(--espace-8);
  background: var(--warn, #b45309); color: #fff;
  font-size: var(--texte-3); text-align: center;
  box-shadow: 0 -4px 20px rgba(0,0,0,.25);
}
#crea-bandeau-degrade button {
  flex-shrink: 0; padding: var(--espace-4) var(--espace-8);
  border: 1px solid rgba(255,255,255,.5); border-radius: var(--radius-sm);
  background: rgba(255,255,255,.14); color: #fff;
  font-size: var(--texte-3); font-weight: 600; cursor: pointer;
}
#crea-bandeau-degrade button:hover { background: rgba(255,255,255,.24); }

/* ── LES PORTES ─────────────────────────────────────────────────────────────
 *
 * « Je ne veux pas être balancé dans Work. »
 *
 * Une porte se PROPOSE. Elle a donc l'air de ce qu'elle est : une suggestion
 * discrète sous la réponse, pas un appel à l'action qui réclame le clic. Elle
 * emprunte les jetons du thème — elle n'a pas sa propre couleur, parce qu'elle
 * n'a pas à se distinguer du reste de la réponse.
 */
.crea-portes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espace-3, .5rem);
  margin-top: var(--espace-4, .75rem);
}
.crea-porte {
  display: inline-flex;
  align-items: center;
  gap: var(--espace-2, .35rem);
  padding: var(--espace-2, .35rem) var(--espace-5, .8rem);
  border: 1px solid var(--t-faint, rgba(0,0,0,.15));
  border-radius: var(--radius-rond);
  background: transparent;
  color: var(--t-secondary, inherit);
  font-size: max(0.8125rem, 13px);
  cursor: pointer;
  /* DÉCLARATION REPRISE À L'IDENTIQUE, PAS RÉÉCRITE. Le cliquet visuel compte
     les transitions DISTINCTES, pas les durées : une variante qui dit la même
     chose autrement en ajoute une, et « une de plus n'est pas une dérive de
     plus, c'est celle qui rend la suivante normale ». Celle-ci est déjà
     utilisée ailleurs pour exactement ce geste — un cadre qui s'allume au
     survol. La couleur du texte suit la même durée, en héritage. */
  transition: border-color var(--duree-2) var(--courbe), background var(--duree-2) var(--courbe);
}
.crea-porte:hover {
  background: var(--accent-bg, rgba(0,0,0,.04));
  border-color: var(--accent, currentColor);
  color: var(--t-primary, inherit);
}
.crea-porte:active { transform: scale(.97); }
.crea-porte-fleche { flex-shrink: 0; opacity: .6; }
.crea-porte:hover .crea-porte-fleche { opacity: 1; }

/* ══════════════════════════════════════════════════════════════════════════
   L'EFFORT — l'état dans la barre, et la carte qui le règle.

   DEUX CHOSES, PAS UNE. Dans la barre, l'effort en cours s'AFFICHE (un point,
   un mot) : c'est une information, au même titre que le nom du modèle à côté.
   Le bouton à glissières, lui, RÈGLE — et c'est le seul à ouvrir la carte.
   Confondre les deux donnait un libellé qui se comporte en bouton sans le dire.

   SIX CRANS. Trois se règlent mais ne se dosent pas : entre « normal » et
   « profond » on triplait la pensée d'un seul geste. La piste montre les six
   positions de l'échelle (server/effort.js) — pleines jusqu'à la position
   courante, qui porte un repère allongé.

   LE « ? » DIT CE QUE ÇA COÛTE. Un réglage dont on ignore le prix se pousse au
   maximum une fois, puis on se demande pourquoi tout est lent.
   ══════════════════════════════════════════════════════════════════════════ */
.effort-etat {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--t-primary); font-size: max(0.8125rem, 13px); font-weight: 500;
  white-space: nowrap; padding: 6px 2px 6px 4px;
}
.effort-etat .effort-pt {
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: 0 0 auto;
}
@media (max-width: 640px) { .effort-etat { display: none; } }

.effort-regle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; flex: 0 0 auto;
  border: 0; background: transparent; color: var(--t-faint);
  border-radius: var(--radius-rond); cursor: pointer;
  transition: background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe);
}
.effort-regle:hover { background: var(--bg-tertiary, rgba(0,0,0,.05)); color: var(--t-secondary); }
.effort-regle.on { color: var(--accent); background: var(--accent-bg); }

.effort-carte {
  width: 244px; padding: 11px 13px 12px;
  background: var(--bg-input); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--ombre-3, 0 10px 32px rgba(0,0,0,.18));
}
.effort-tete { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
.effort-titre { flex: 1; color: var(--t-primary); font-size: max(0.8125rem, 13px); font-weight: 600; }
.effort-titre strong { color: var(--accent); font-weight: 600; }
.effort-x {
  border: 0; background: none; color: var(--t-faint); cursor: pointer;
  font-size: max(0.6875rem, 11px); padding: 1px 4px; border-radius: var(--radius-xs); line-height: 1;
}
.effort-x:hover { background: var(--bg-hover, rgba(0,0,0,.06)); color: var(--t-primary); }

/* Le « ? » et sa bulle : au survol comme au focus clavier. */
.effort-aide {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; flex: 0 0 auto; cursor: help; outline: none;
  border: 1px solid var(--border-hov, var(--border)); border-radius: 50%;
  color: var(--t-faint); font-size: max(0.5625rem, 9px); font-weight: 700;
}
.effort-aide:hover, .effort-aide:focus-visible { border-color: var(--accent); color: var(--accent); }
.effort-bulle {
  position: absolute; bottom: calc(100% + 7px); right: -6px; z-index: 10;
  display: none; width: 216px; padding: 9px 11px;
  background: var(--bg-tertiary, var(--bg-secondary)); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--ombre-2, 0 6px 20px rgba(0,0,0,.16));
  color: var(--t-secondary); font-size: max(0.6875rem, 11px); font-weight: 400;
  line-height: 1.45; text-align: left; cursor: default;
}
.effort-bulle strong { display: block; margin-bottom: 3px; color: var(--t-primary); font-weight: 600; }
.effort-aide:hover .effort-bulle, .effort-aide:focus-visible .effort-bulle { display: block; }

.effort-bornes {
  display: flex; justify-content: space-between; margin-bottom: 5px;
  color: var(--t-secondary); font-size: max(0.6875rem, 11px); font-weight: 500;
}
/* UN BLOC GRADUÉ, PAS UN TRAIT. Une gouttière épaisse, six graduations
   dedans, et une poignée qui s'y déplace : on voit l'étendue de la course
   AVANT de la parcourir, ce qu'un filet de deux pixels ne montre pas. Toute la
   largeur est cliquable, cran par cran — on vise une graduation, pas un point. */
.effort-piste {
  position: relative; display: flex; align-items: stretch;
  height: 26px; padding: 0;
  background: var(--bg-secondary); border: 1px solid var(--border);
  border-radius: var(--radius-sm); overflow: hidden;
}
.effort-cran {
  position: relative; flex: 1 1 0; min-width: 0; height: 100%; padding: 0;
  border: 0; background: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.effort-grad {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--t-faint); opacity: .5;
  transition: opacity var(--duree-2) var(--courbe), background var(--duree-2) var(--courbe);
}
.effort-cran:hover .effort-grad { opacity: 1; background: var(--accent); }
.effort-poignee {
  position: absolute; top: 3px; width: 22px; height: 18px;
  background: var(--bg-input); border: 1px solid var(--border-hov, var(--border));
  border-radius: var(--radius-xs); box-shadow: var(--ombre-1);
  pointer-events: none;
  transition: left var(--duree-2) var(--courbe);
}

/* ═══════════════════════════════════════════════════════════════════════════
   OFFRIR CREA — LA VITRINE
   ═══════════════════════════════════════════════════════════════════════════

   « C'est propre, mais ce n'est pas vendeur. »

   Un écran de cadeau n'est pas un formulaire. Trois listes et un bouton
   décrivent CORRECTEMENT ce qu'on achète, et ne donnent envie de rien : on
   n'offre pas un identifiant de forfait et un nombre de mois, on offre un
   objet à quelqu'un. La carte est cet objet — elle se remplit à mesure qu'on
   choisit, et c'est elle qu'on regarde, pas les cases.

   Tout passe par les échelles (--radius-*, --ombre-*, --duree-*) : une valeur
   écrite à la main ici serait invisible en thème sombre, et c'est exactement
   par là que les trente-sept ombres d'avant étaient entrées. */

/* ELLE PREND TOUTE LA LARGEUR, ET ELLE EST COUCHÉE.
   Debout et étroite, elle laissait un grand vide de chaque côté et se lisait
   comme une vignette. Un bon d'achat, une carte cadeau, une carte bancaire :
   tout ce qui s'offre est couché — c'est la forme qu'on reconnaît sans y
   penser, et elle occupe la page au lieu de s'y perdre. */
.cadeau-carte {
  position: relative;
  width: 100%; aspect-ratio: 16 / 5.5; min-height: 172px;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 28px 32px;
  border-radius: var(--radius-xl);
  background: linear-gradient(120deg, var(--accent), color-mix(in srgb, var(--accent) 68%, #000));
  box-shadow: var(--ombre-4);
  color: #fff;
  overflow: hidden;
}
/* Sous 640 px la carte se redresse un peu : couchée à l'extrême, son texte
   deviendrait illisible sur un téléphone. */
@media (max-width: 640px) {
  .cadeau-carte { aspect-ratio: 16 / 8; padding: 22px 22px; }
  .cadeau-noeud { width: 52px; height: 52px; }
  .cadeau-carte-duree { font-size: max(1.5rem, 24px); }
}
/* Le reflet — une carte plate ressemble à un rectangle coloré ; celle-ci a une
   surface. Purement décoratif, donc retiré de l'arbre d'accessibilité. */
.cadeau-carte::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(115deg, rgba(255,255,255,.22) 0%, rgba(255,255,255,0) 42%);
  pointer-events: none;
}
.cadeau-noeud { width: 76px; height: 76px; opacity: .96; flex: 0 0 auto; position: relative; z-index: 1; }
.cadeau-carte-texte { position: relative; z-index: 1; text-align: right; min-width: 0; }
.cadeau-carte-duree {
  font-size: max(2rem, 32px); font-weight: 600; line-height: 1.05;
}
.cadeau-carte-plan {
  font-size: max(0.9375rem, 15px); opacity: .9; margin-top: 4px;
}

/* Un forfait se choisit sur ce qu'il apporte À QUELQU'UN, pas sur son prix
   seul : « 7,99 € ou 19,99 € » demande à celui qui offre de deviner. */
.cadeau-forfait {
  display: flex; flex-direction: column; gap: 2px;
  padding: 12px 14px; text-align: left; cursor: pointer;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: transparent;
  transition: all var(--duree-2) var(--courbe);
}
.cadeau-forfait:hover { border-color: var(--t-faint); }
.cadeau-forfait.on { border-color: var(--accent); background: var(--accent-bg); }
.cadeau-forfait-nom { font-size: max(0.9375rem, 15px); font-weight: 600; color: var(--t-primary); }
.cadeau-forfait-pour { font-size: max(0.75rem, 12px); color: var(--t-dim); line-height: 1.35; }

.cadeau-duree {
  flex: 1 1 0; min-width: 0; padding: 9px 4px; cursor: pointer;
  font-size: max(0.8125rem, 13px); font-weight: 500;
  border-radius: var(--radius-rond);
  border: 1px solid var(--border);
  background: transparent; color: var(--t-secondary);
  transition: all var(--duree-2) var(--courbe);
}
.cadeau-duree:hover { border-color: var(--t-faint); }
.cadeau-duree.on { border-color: var(--accent); background: var(--accent-bg); color: var(--accent); }

/* Le total se lit AVANT de cliquer. Un montant découvert sur la page de
   paiement est un montant qu'on n'a pas choisi. */
.cadeau-total { font-size: max(1.75rem, 28px); font-weight: 600; color: var(--t-primary); line-height: 1; }

/* CENTRÉ DANS LA PAGE, PAS COLLÉ EN HAUT.
   « Quand il y a une grande page et que tu viens mettre le truc en haut ou
   dans un coin », l'écran a l'air inachevé — le contenu flotte et les trois
   quarts du bas restent vides.

   `safe center` et non `center` : sur un petit écran, un contenu plus haut que
   la fenêtre serait coupé PAR LE HAUT avec un centrage ordinaire, et le début
   deviendrait inatteignable même en défilant. Le mot « safe » demande au
   navigateur de retomber sur un alignement en haut dans ce cas précis. Les
   moteurs qui ne le connaissent pas ignorent la déclaration entière et gardent
   l'alignement en haut — c'est-à-dire l'état d'avant, jamais un écran cassé. */
.cadeau-scene {
  display: flex; flex-direction: column;
  justify-content: safe center;
}

/* ══════════════════════════════════════════════════════════════════════════
 * LA FILE D'ATTENTE — les rangées au-dessus de la barre de question.
 *
 * Elles vivaient DANS l'enveloppe du composeur, avec des classes utilitaires
 * empilées à même le balisage. Deux conséquences : elles se lisaient comme un
 * contenu de la barre alors qu'elles n'en sont pas un, et chaque retouche
 * visuelle demandait de rouvrir le JavaScript.
 *
 * Elles flottent maintenant au-dessus, comme les chips git, et leur apparence
 * tient ici — en quatre classes qui portent un rôle, pas une couleur.
 * ══════════════════════════════════════════════════════════════════════════ */

/* AU-DESSUS DU RIDEAU DE FERMETURE.
 *
 * `#dismiss-overlay` est une nappe transparente posée à z-index 49 dès qu'un
 * menu est ouvert quelque part (sélecteur de modèle, notifications, menu +…).
 * Sans z-index, la file passait DESSOUS : les rangées restaient parfaitement
 * visibles et parfaitement inertes — chaque clic atterrissait sur la nappe.
 *
 * C'est ce que l'usager a signalé, et ça ne se reproduit qu'avec un autre menu
 * ouvert : voilà pourquoi rien ne cassait en test à froid. Un bouton visible
 * qui ne répond pas ne donne aucune piste — il n'a l'air ni désactivé, ni
 * absent, ni en erreur.
 *
 * 50, soit un cran au-dessus de la nappe : assez pour recevoir le clic, pas
 * assez pour passer devant les menus eux-mêmes, qui montent bien plus haut. */
.file-pile {
  position: relative; z-index: 50;
  display: flex; flex-direction: column; gap: 5px;
  padding: 0 2px 7px;
}

/* LA RANGÉE. Un peu plus haute que ne l'exige le texte (34 px), parce qu'une
   rangée serrée avec trois boutons dedans se lit comme une barre d'outils —
   or c'est une PHRASE qu'on a écrite, et elle doit garder son air de phrase. */
.file-rang {
  display: flex; align-items: center; gap: 8px;
  min-height: 34px;
  padding: 0 6px 0 11px;
  border-radius: var(--radius);
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  color: var(--t-secondary);
  font-size: max(0.78125rem, 12.5px);
  /* Une ombre d'un seul pixel, très basse : elle décolle la rangée du fond
     sans la faire flotter. Au-delà, une pile de trois messages ressemble à
     trois fenêtres empilées. */
  box-shadow: var(--ombre-1);
  transition: all var(--duree-1) var(--courbe);
}
.file-rang:hover { border-color: var(--border-hov); }
.file-rang-ouvert { border-color: var(--accent); }

/* L'INCIDENT PORTE L'ACCENT, LE MESSAGE NON. Un arrêt doit se voir avant
   d'être lu ; trois messages en attente ne doivent pas crier plus fort que
   l'incident qui les retient. */
.file-rang-alerte {
  background: color-mix(in srgb, var(--accent) 7%, var(--bg-secondary));
  border-color: color-mix(in srgb, var(--accent) 28%, var(--border));
  color: var(--t-primary);
}
/* Le choix tenu, lui, s'efface : pointillés, pas de teinte, pas d'ombre. */
.file-rang-eteint {
  background: transparent;
  border-style: dashed;
  box-shadow: none;
  color: var(--t-faint);
}

.file-glyphe { flex-shrink: 0; display: inline-flex; color: var(--t-faint); }
.file-texte {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* LES GESTES S'ESTOMPENT AU REPOS. Ce qui compte au repos, c'est ce qu'on a
   écrit — pas les boutons. À pleine encre, une file de trois messages devient
   une grille de neuf boutons. */
.file-gestes {
  flex-shrink: 0; display: flex; align-items: center; gap: 1px;
  opacity: .55;
  transition: opacity var(--duree-1) var(--courbe);
}
.file-rang:hover .file-gestes,
.file-rang:focus-within .file-gestes,
.file-rang-ouvert .file-gestes { opacity: 1; }
/* SANS SURVOL, PAS D'ESTOMPAGE. Sur un écran tactile il n'existe aucun état
   intermédiaire entre « pas touché » et « appuyé » : un geste qui n'apparaît
   qu'au survol n'y apparaîtrait jamais. */
@media (hover: none) { .file-gestes { opacity: 1; } }

.file-geste {
  display: inline-flex; align-items: center; gap: 4px;
  height: 26px; padding: 0 6px;
  border-radius: var(--radius-sm);
  color: var(--t-dim);
  font-size: max(0.71875rem, 11.5px);
  transition: all var(--duree-1) var(--courbe);
}
.file-geste:hover { background: var(--bg-hover, rgba(0, 0, 0, .05)); color: var(--t-primary); }
.file-geste-texte { padding-right: 8px; }

/* RELANCER EST LE SEUL BOUTON PLEIN DE LA RANGÉE. C'est le seul geste qui
   remet quelque chose en marche : il se distingue par la masse, pas par la
   couleur — une seconde couleur dans une rangée déjà teintée la rendrait
   illisible. */
.file-relancer {
  flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 5px;
  height: 25px; padding: 0 10px;
  border-radius: var(--radius-rond);
  background: var(--bg-input);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
  color: var(--t-primary);
  font-size: max(0.71875rem, 11.5px); font-weight: 500;
  transition: all var(--duree-1) var(--courbe);
}
.file-relancer:hover {
  background: color-mix(in srgb, var(--accent) 10%, var(--bg-input));
  border-color: var(--accent);
}
.file-relancer-nu {
  background: transparent; border-color: transparent; color: var(--t-dim);
  font-weight: 400;
}
.file-relancer-nu:hover { background: var(--bg-secondary); border-color: var(--border); color: var(--t-primary); }

/* LE MENU s'ouvre VERS LE HAUT et s'aligne à droite, sous les trois points :
   il naît là où le doigt vient de cliquer. */
.file-menu {
  position: absolute; bottom: 100%; right: 4px; z-index: 50;
  /* Assez large pour que « Désactiver la mise en file d'attente » tienne sur
     UNE ligne : replié sur deux, l'item devenait deux fois plus haut que ses
     voisins et cassait le rythme de la liste. */
  margin-bottom: 6px; width: 300px; padding: 5px;
  border-radius: var(--radius-lg);
  background: var(--bg-input);
  border: 1px solid var(--border);
  box-shadow: var(--ombre-4);
}
.file-menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px;
  border-radius: var(--radius);
  text-align: left;
  color: var(--t-primary);
  font-size: max(0.8125rem, 13px);
  white-space: nowrap;
  transition: background var(--duree-1) var(--courbe);
}
.file-menu-item:hover { background: var(--bg-secondary); }
.file-menu-item svg { color: var(--t-dim); }

/* ══════════════════════════════════════════════════════════════════════════
   L'OBJECTIF — la rangée qui reste, et son panneau à onglets.

   « Une fois qu'on a défini un objectif, il reste par-dessus la barre de
     questions. Tant qu'on n'est pas venu supprimer cet objectif. »
   ══════════════════════════════════════════════════════════════════════════ */

/* LA RANGÉE. Elle hérite de .file-rang — même hauteur, même rayon, même
   ombre — parce qu'elle vit dans la même pile. Ce qui la distingue tient en
   deux traits : un liseré à gauche, et une teinte plus froide que l'alerte.
   Un objectif n'est pas un incident : il ne doit pas crier comme un arrêt,
   mais il ne doit pas non plus se confondre avec une ligne en attente. */
.obj-rang {
  border-left: 2px solid var(--accent);
  padding-left: 9px;
  background: color-mix(in srgb, var(--accent) 4%, var(--bg-secondary));
}
.obj-rang:hover { border-color: var(--border-hov); border-left-color: var(--accent); }
.obj-glyphe { color: var(--accent); }

/* MIS DE CÔTÉ SE VOIT. Le liseré s'éteint et le texte pâlit : sans ça, rien
   à l'écran ne distinguerait un objectif qu'on poursuit d'un objectif qu'on
   a rangé — et le second ne part plus dans le prompt. */
.obj-rang-pause {
  border-left-color: var(--border);
  background: var(--bg-secondary);
  opacity: .72;
}
.obj-rang-pause .obj-glyphe { color: var(--t-faint); }

/* Le titre en encre pleine, le reste en gris : on lit le but d'abord, le
   détail ensuite. Les deux sur une seule ligne qui se coupe proprement. */
.obj-texte b { font-weight: 600; color: var(--t-primary); }
.obj-rang-pause .obj-texte b { color: var(--t-secondary); }
.obj-apercu { color: var(--t-faint); font-weight: 400; }

/* LE CHRONO. Chiffres tabulaires, sinon la largeur saute à chaque seconde et
   les trois boutons d'à côté tressautent avec elle. */
.obj-chrono {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  font-size: max(0.6875rem, 11px);
  color: var(--t-faint);
  padding-right: 2px;
}

/* ── LES DEUX ENTRÉES DU BOUTON « + » ──────────────────────────────────────
   Le nom, puis la phrase pâle qui dit ce que ça fait. Sans elle, « Objectif »
   et « Mode plan » sont deux mots qu'il faut cliquer pour comprendre. */
.obj-entree-plus {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 10px 16px;
  font-size: max(0.875rem, 14px);
  color: var(--t-secondary);
  text-align: left;
  transition: background var(--duree-1) var(--courbe);
}
.obj-entree-plus:hover { background: rgba(0, 0, 0, .05); }
.obj-entree-icone { flex-shrink: 0; display: flex; color: var(--t-dim); }
.obj-entree-nom { flex-shrink: 0; }
/* La description s'efface la première quand la place manque : c'est elle
   qu'on relit le moins, une fois qu'on a compris. */
.obj-entree-desc {
  flex: 1; min-width: 0;
  color: var(--t-faint);
  font-size: max(0.8125rem, 13px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.obj-entree-active .obj-entree-icone,
.obj-entree-active .obj-entree-nom { color: var(--accent); }

/* ══════════════════════════════════════════════════════════════════════════
   LE PANNEAU À ONGLETS — ET IL N'EST PAS ARRONDI.

   Ce n'est pas un oubli. Tous les panneaux flottants de cette application
   sont arrondis : ils passent AU-DESSUS du contenu et le rayon dit qu'ils
   s'en vont. Celui-ci est un second volet de la fenêtre — collé au bord, du
   sol au plafond, et il reste. La forme le dit avant qu'on ait lu le titre.
   ══════════════════════════════════════════════════════════════════════════ */
.obj-panneau {
  position: fixed;
  /* IL COMMENCE SOUS LA BARRE DE FENÊTRE, PAS EN HAUT DU VIEWPORT.
     « Toi, comme mesure, tu as la mesure de la fenêtre Chromium — du coup pas
       la barre Windows, du coup tu règles mal la hauteur. »
     Exactement ça : `top: 0` vise le haut du viewport, et sur le bureau la
     barre de fenêtre (#crea-electron-titlebar, z-index 99999) est posée
     dessus. Le volet passait donc SOUS elle et sa barre d'onglets — sa tête —
     disparaissait.

     `--crea-barre-fenetre` est LA mesure, posée une fois sur `body` par
     mountElectronTitlebar. J'en avais introduit une seconde du même nom à une
     lettre près pendant que celle-ci naissait de son côté ; deux variables
     pour une seule mesure, c'est précisément le défaut qu'elle existe pour
     supprimer. Elle vaut 0 sur le web, où il n'y a pas de barre. */
  top: var(--crea-barre-fenetre, 0px); right: 0; bottom: 0;
  width: min(640px, 46vw);
  /* MÊME NATURE, MÊME NIVEAU. 8800 était un barreau neuf pour un objet qui en
     a déjà un : le panneau du support, plein écran et collé au bord lui aussi,
     vit à 8700 — sous le menu + (9000), qui doit rester cliquable par-dessus.
     Inventer un niveau par panneau est exactement la « surenchère » que
     l'échelle d'empilement existe pour arrêter : chaque nombre choisi pour
     passer au-dessus du précédent, sans que personne sache lequel doit gagner.
     Les deux panneaux ne s'ouvrent pas ensemble. */
  z-index: 8700;
  display: flex; flex-direction: column;
  background: var(--bg-primary);
  border-left: 1px solid var(--border);
  border-radius: 0;           /* explicite : c'est une DÉCISION, pas un défaut */
  box-shadow: -8px 0 28px rgba(0, 0, 0, .07);
}
.obj-panneau-plein { width: 100vw; border-left: none; }
@media (max-width: 720px) { .obj-panneau { width: 100vw; border-left: none; } }

/* ── LE VOLET POUSSE, IL NE RECOUVRE PAS ───────────────────────────────────
   « Cette barre-là, tu l'as faite trop haute — on ne voit même pas la tête. »

   Il était `position: fixed` sans rien derrière : il se posait SUR la
   conversation et coupait la barre de questions en deux. La moitié droite de
   l'application disparaissait — le fil, le composeur, tout.

   Un volet qui recouvre n'est pas un volet, c'est une modale : on ne peut plus
   travailler pendant qu'il est ouvert, alors que sa raison d'être est
   exactement l'inverse — relire son objectif SANS quitter ce qu'on fait.

   `:has()` plutôt qu'une classe posée en JavaScript : la largeur suit alors
   l'EXISTENCE du panneau, pas un drapeau qu'il faudrait penser à lever et à
   baisser. Le jour où un chemin ferme le volet sans repasser par le bon
   endroit, il n'y a rien à oublier. Une seule source, et c'est le DOM lui-même.

   Sur mobile le volet prend l'écran (voir la requête ci-dessus) : il n'y a
   alors rien à pousser, et pousser rendrait le contenu illisible. */
#app:has(#obj-panneau) { padding-right: min(640px, 46vw); }
#app:has(.obj-panneau-plein) { padding-right: 0; }
@media (max-width: 720px) { #app:has(#obj-panneau) { padding-right: 0; } }

/* ── LA BARRE D'ONGLETS ───────────────────────────────────────────────── */
.obj-barre-onglets {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-secondary);
}
/* Les onglets défilent, la rangée d'actions ne bouge pas : dix onglets
   ouverts ne doivent pas pousser le bouton « fermer » hors de l'écran. */
.obj-onglets {
  display: flex; align-items: center; gap: 4px;
  flex: 1; min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.obj-onglets::-webkit-scrollbar { display: none; }
.obj-barre-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }

.obj-onglet {
  display: flex; align-items: center; gap: 7px;
  flex-shrink: 0;
  max-width: 210px;
  padding: 6px 8px 6px 10px;
  border-radius: var(--radius-sm);
  font-size: max(0.8125rem, 13px);
  color: var(--t-faint);
  background: transparent;
  transition: all var(--duree-1) var(--courbe);
}
.obj-onglet:hover { background: rgba(0, 0, 0, .04); color: var(--t-secondary); }
.obj-onglet-actif {
  background: var(--bg-primary);
  color: var(--t-primary);
  border: 1px solid var(--border);
  padding: 5px 7px 5px 9px;
}
.obj-onglet-icone { display: flex; flex-shrink: 0; }
.obj-onglet-titre { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* La croix reste en place, allumée ou non : la faire apparaître au survol
   ferait sauter la largeur de l'onglet sous le curseur. */
.obj-onglet-croix {
  display: flex; flex-shrink: 0;
  padding: 2px; border-radius: var(--radius-xs);
  opacity: .45;
  transition: opacity var(--duree-1) var(--courbe), background var(--duree-1) var(--courbe);
}
.obj-onglet:hover .obj-onglet-croix { opacity: .8; }
.obj-onglet-croix:hover { opacity: 1; background: rgba(0, 0, 0, .08); }

.obj-plus, .obj-action {
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  width: 28px; height: 28px;
  border-radius: var(--radius-sm);
  color: var(--t-dim);
  transition: all var(--duree-1) var(--courbe);
}
.obj-plus:hover, .obj-action:hover { background: rgba(0, 0, 0, .06); color: var(--t-primary); }
.obj-action:disabled { opacity: .3; pointer-events: none; }

/* ── LE MENU DU « + » ─────────────────────────────────────────────────── */
.obj-menu-plus {
  position: absolute;
  top: 44px; left: 8px;
  z-index: 10;
  min-width: 268px; max-width: calc(100% - 16px);
  padding: 5px;
  /* Le repli disait 12 là où l'échelle dit 16 : deux formes pour un seul nom,
     et c'est le repli qu'on voit le jour où la variable manque. */
  border-radius: var(--radius-lg);
  background: var(--bg-input);
  border: 1px solid var(--border);
  box-shadow: var(--ombre-3, 0 10px 32px rgba(0, 0, 0, .14));
}
.obj-menu-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  font-size: max(0.84375rem, 13.5px);
  color: var(--t-secondary);
  text-align: left;
  white-space: nowrap;
}
.obj-menu-item:hover { background: rgba(0, 0, 0, .05); }
.obj-menu-item > span:not(.obj-menu-url) { flex: 1; }
/* Le raccourci se lit, il ne se crie pas : un raccourci qu'on ne voit jamais
   n'est pas un raccourci, mais il ne doit pas concurrencer le libellé. */
.obj-menu-item kbd {
  flex-shrink: 0;
  font-family: inherit;
  font-size: max(0.6875rem, 11px);
  color: var(--t-faint);
}
.obj-menu-titre {
  padding: 8px 10px 4px;
  font-size: max(0.625rem, 10px);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--t-faint);
}
.obj-menu-url {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--t-faint);
}

/* ── LE CORPS ─────────────────────────────────────────────────────────── */
.obj-corps { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.obj-edit { flex: 1; min-height: 0; display: flex; flex-direction: column; }

.obj-vide {
  flex: 1;
  display: flex; align-items: center; justify-content: center;
  padding: 28px;
  color: var(--t-faint);
  font-size: max(0.84375rem, 13.5px);
  text-align: center;
}
.obj-lateral-fil { flex: 1; overflow-y: auto; padding: 18px 22px; display: flex; flex-direction: column; }
.obj-lateral-msg { color: var(--t-primary); font-size: max(0.875rem, 14px); line-height: 1.6; }
.obj-navigateur { flex: 1; min-height: 0; }
.obj-navigateur iframe { width: 100%; height: 100%; border: none; background: #fff; }

/* ── LA PUCE D'OBJECTIF, DANS LA BARRE DE QUESTIONS ────────────────────────
   « Il vient s'afficher dans la barre de questions. Il va à côté de Computer,
     et on met un transparent vite fait entre les deux. »

   L'écart est transparent parce que la barre a déjà assez de traits : un
   séparateur dessiné de plus ferait trois zones là où il n'y en a que deux. */
.obj-puce-ecart { display: inline-block; width: 10px; flex-shrink: 0; }

/* Elle porte l'accent, contrairement aux bascules Recherche/Computer qui ne
   l'ont qu'une fois choisies : la puce N'EXISTE que pendant la saisie, et ce
   qu'elle annonce — « ce que tu tapes ne partira pas comme message » — doit se
   voir avant qu'on appuie sur Entrée, pas après. */
.obj-puce {
  display: inline-flex; align-items: center; gap: 6px;
  flex-shrink: 0;
  padding: 5px 5px 5px 9px;
  border-radius: var(--radius-rond);
  background: var(--accent-bg);
  color: var(--accent-texte);
  font-size: max(0.75rem, 12px);
  font-weight: 500;
  animation: obj-puce-entree var(--duree-2, .18s) var(--courbe);
}
@keyframes obj-puce-entree {
  from { opacity: 0; transform: translateX(-4px); }
  to   { opacity: 1; transform: none; }
}
.obj-puce-icone { display: flex; flex-shrink: 0; }
/* La croix est un vrai bouton et pas une icône décorative : annuler la saisie
   doit être aussi facile que l'avoir lancée. */
.obj-puce-croix {
  display: flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
  border-radius: var(--radius-rond);
  opacity: .6;
  transition: opacity var(--duree-1) var(--courbe), background var(--duree-1) var(--courbe);
}
.obj-puce-croix:hover { opacity: 1; background: rgba(0, 0, 0, .1); }
@media (hover: none) { .obj-puce-croix { opacity: 1; } }

/* ══════════════════════════════════════════════════════════════════════════
   LES FICHIERS DU PROJET — le panneau (rangée courte) et la page (liste +
   aperçu). Voir src/crea-fichiers-projet.js pour ce que chaque section
   contient et pourquoi.

   Une seule règle de forme gouverne tout ce bloc : la LISTE est dense (on
   balaye des noms) et l'APERÇU est aéré (on regarde une seule chose). C'est
   ce contraste qui rend la page lisible ; l'uniformiser la rendrait plate.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── LE PANNEAU ─────────────────────────────────────────────────────────── */
.fich-panneau {
  display: flex; flex-direction: column; width: 300px; max-width: 100%; height: 100%;
  background: var(--bg-primary);
}
.fich-panneau-tete {
  display: flex; align-items: center; justify-content: space-between; gap: var(--espace-4);
  padding: var(--espace-5) var(--espace-6);
  padding-top: max(var(--espace-5), env(safe-area-inset-top));
  border-bottom: 1px solid var(--border);
}
.fich-panneau-titre { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.fich-panneau-nom {
  font-size: var(--texte-4); font-weight: 600; color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fich-panneau-compte { font-size: var(--texte-1); color: var(--t-faint); }
.fich-panneau-corps { flex: 1; min-height: 0; overflow-y: auto; padding: var(--espace-3) var(--espace-3) var(--espace-5); }
.fich-groupe {
  font-size: var(--texte-1); font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--t-faint); padding: var(--espace-4) var(--espace-4) var(--espace-3);
}
.fich-ligne {
  display: flex; align-items: center; gap: var(--espace-4); width: 100%; text-align: left;
  padding: var(--espace-4); border-radius: var(--radius-sm); cursor: pointer;
  background: transparent; border: 0; color: inherit;
  transition: background var(--duree-1) var(--courbe);
}
.fich-ligne:hover { background: var(--bg-secondary); }
/* La page blanche est une CRÉATION, pas un fichier : le cadre pointillé la
   sépare des lignes qui, elles, désignent quelque chose qui existe déjà. */
.fich-ligne--neuve { border: 1px dashed var(--border); margin-bottom: var(--espace-3); }
.fich-ligne--neuve:hover { border-color: var(--accent); }
.fich-ligne-ic {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: var(--radius);
  background: var(--accent-bg); color: var(--accent);
}
.fich-ligne-ic svg { width: 21px; height: 21px; }
.fich-ligne-txt { display: flex; flex-direction: column; min-width: 0; gap: 1px; flex: 1; }
.fich-ligne-nom {
  font-size: var(--texte-3); font-weight: 500; color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fich-ligne-meta { font-size: var(--texte-1); color: var(--t-faint); }
/* La page ouverte est marquée dans le panneau : sur la photo, c'est la ligne
   claire qui dit « c'est celle-ci que tu regardes en ce moment ». */
.fich-ligne--courante { background: var(--accent-bg); }
.fich-ligne--courante .fich-ligne-nom { color: var(--accent); }
.fich-vide { font-size: var(--texte-2); color: var(--t-faint); padding: var(--espace-5) var(--espace-4); }
.fich-pied {
  display: flex; align-items: center; justify-content: space-between; gap: var(--espace-4);
  padding: var(--espace-5) var(--espace-6); border-top: 1px solid var(--border);
  font-size: var(--texte-3); font-weight: 500; color: var(--t-secondary);
  background: transparent; border-left: 0; border-right: 0; border-bottom: 0; cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.fich-pied:hover { background: var(--bg-secondary); color: var(--t-primary); }
.fich-pied-fleche { display: inline-flex; }
.fich-pied-fleche svg { width: 15px; height: 15px; }

/* ── LA PAGE ────────────────────────────────────────────────────────────── */
.fich-page {
  position: fixed; inset: 0; z-index: 60;
  display: flex; flex-direction: column;
  background: var(--bg-primary);
}
/* Posée DANS l'atelier d'un studio : elle occupe la place qu'on lui donne au
   lieu de recouvrir l'application. Même composant, deux ancrages. */
.fich-page--integre { position: relative; inset: auto; z-index: auto; height: 100%; }
.fich-page-tete {
  display: flex; align-items: center; justify-content: space-between; gap: var(--espace-5);
  padding: var(--espace-5) var(--espace-8);
  padding-top: max(var(--espace-5), env(safe-area-inset-top));
  border-bottom: 1px solid var(--border);
}
.fich-page-titre { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.fich-page-nom { font-size: var(--texte-5); font-weight: 600; color: var(--t-primary); }
.fich-page-compte { font-size: var(--texte-1); color: var(--t-faint); }

.fich-outils {
  display: flex; align-items: center; gap: var(--espace-3); flex-wrap: wrap;
  padding: var(--espace-4) var(--espace-8);
  border-bottom: 1px solid var(--border);
}
.fich-outils-espace { flex: 1; }
/* LA RECHERCHE EST UN CHAMP, PAS UN BOUTON QUI OUVRE UN CHAMP. Un clic de
   moins, et on voit tout de suite ce qui est cherché — c'est ce que fait la
   barre d'un explorateur de fichiers. */
.fich-chercher {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  height: 28px; padding: 0 var(--espace-4); border-radius: var(--radius-rond);
  background: var(--bg-secondary); border: 1px solid transparent;
  /* L'IDIOME DÉJÀ MAJORITAIRE ICI — `all var(--duree-1) var(--courbe)`, seize
     déclarations. Un `border-color` seul aurait été une cinquante-cinquième
     valeur de transition distincte, et le cliquet du mouvement l'a dit tout de
     suite : une de plus n'est pas une dérive de plus, c'est celle qui rend la
     suivante normale. */
  transition: all var(--duree-1) var(--courbe);
  max-width: 200px; min-width: 0;
}
.fich-chercher:focus-within, .fich-chercher--pleine { border-color: var(--border); }
.fich-chercher-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.fich-chercher-ic svg { width: 14px; height: 14px; }
.fich-chercher-champ {
  flex: 1; min-width: 0; border: 0; background: transparent; outline: none;
  color: var(--t-primary); font-size: var(--texte-2);
}
.fich-chercher-champ::placeholder { color: var(--t-faint); }
.fich-tri {
  height: 28px; padding: 0 var(--espace-3); border-radius: var(--radius-sm);
  background: var(--bg-secondary); border: 1px solid transparent;
  color: var(--t-dim); font-size: var(--texte-2); cursor: pointer;
}
.fich-tri:focus { outline: none; border-color: var(--border); }
.fich-icone {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: var(--radius-sm);
  color: var(--t-dim); background: transparent; border: 0; cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.fich-icone svg { width: 15px; height: 15px; }
.fich-icone:hover { background: var(--bg-secondary); color: var(--t-primary); }
.fich-icone:disabled { opacity: .35; cursor: default; }
.fich-icone:disabled:hover { background: transparent; color: var(--t-dim); }
.fich-bouton {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  padding: var(--espace-3) var(--espace-5); border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg-primary);
  font-size: var(--texte-2); font-weight: 500; color: var(--t-secondary); cursor: pointer;
  /* L'IDIOME MAJORITAIRE — 36 usages. Écrire sa propre liste de propriétés
     ajoute une valeur distincte à une dimension qui dérive déjà, pour un
     résultat visuel identique. */
  transition: all var(--duree-1) var(--courbe);
}
.fich-bouton svg { width: 14px; height: 14px; }
.fich-bouton:hover { border-color: var(--accent); color: var(--t-primary); }
.fich-bouton--ouvrir { margin: var(--espace-6) auto 0; }
.fich-bouton--fort { background: var(--accent); border-color: var(--accent); color: #fff; }
.fich-bouton--fort:hover { color: #fff; opacity: .92; }

.fich-fil { display: flex; align-items: center; gap: var(--espace-3); min-width: 0; font-size: var(--texte-2); }
.fich-fil-lien { color: var(--t-dim); background: none; border: 0; cursor: pointer; padding: 0; }
.fich-fil-lien:hover { color: var(--accent); }
.fich-fil-sep { color: var(--t-faint); }
.fich-fil-actuel { color: var(--t-primary); font-weight: 500; }

.fich-corps { flex: 1; min-height: 0; display: flex; }
.fich-liste { flex: 1; min-width: 0; overflow-y: auto; padding: 0 0 var(--espace-8); }
/* Le titre de section est une BANDE, pas une ligne flottante : sur la photo
   c'est un bandeau clair qui traverse la colonne, et c'est lui qui découpe la
   liste en blocs lisibles quand elle est longue. */
.fich-section-titre {
  font-size: var(--texte-1); font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  color: var(--t-faint); padding: var(--espace-4) var(--espace-8);
  background: var(--bg-secondary); border-bottom: 1px solid var(--border);
}
/* Pleine largeur, séparateur fin, aucun arrondi — une ligne de fichier, pas
   une pastille. Les pastilles arrondies que j'avais mises faisaient une liste
   de boutons ; la photo montre un tableau. */
.fich-rangee {
  display: flex; align-items: center; gap: var(--espace-5); width: 100%; text-align: left;
  padding: var(--espace-4) var(--espace-8); border: 0; border-bottom: 1px solid var(--border);
  background: transparent; color: inherit; cursor: pointer;
  transition: background var(--duree-1) var(--courbe);
}
.fich-rangee:hover { background: var(--bg-secondary); }
/* La ligne choisie est pleine, pas soulignée : c'est elle qui commande le
   cadre de droite, et ce lien-là doit se voir d'un coup d'œil depuis l'aperçu. */
.fich-rangee--choisie, .fich-rangee--choisie:hover { background: var(--accent); }
.fich-rangee--choisie .fich-rangee-nom,
.fich-rangee--choisie .fich-rangee-sous,
.fich-rangee--choisie .fich-rangee-date { color: #fff; }
/* L'OBJET GARDE SES COULEURS SUR LA LIGNE CHOISIE — c'est le texte qui
   s'inverse, pas lui. La règle d'avant le repeignait en blanc sur un fond
   blanc translucide : avec des icônes en TRAIT ça donnait un contour clair
   lisible, avec des icônes PLEINES ça donne une tache blanche, et le fichier
   perd sa silhouette au moment précis où on le regarde. Vu à l'écran. */
.fich-rangee--choisie .fich-rangee-ic { background: rgba(255,255,255,.92); }
/* PLUS GROS, ET ARRONDI COMME UNE ICÔNE, PAS COMME UNE CASE. Trente pixels de
   fond pour seize pixels de trait donnaient une pastille avec un dessin perdu
   au milieu ; l'objet doit remplir sa place. */
.fich-rangee-ic {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--radius);
  background: var(--bg-secondary); color: var(--t-dim);
}
/* LA COULEUR DIT LE TYPE AVANT QUE LE NOM SOIT LU. C'est ce que fait la photo :
   la page est rose, le script est jaune. Dans une liste de trente lignes, la
   couleur trie l'œil ; un gris uniforme oblige à lire chaque nom. */
.fich-ic--page     { background: rgba(244,114,182,.14); color: #db2777; }
.fich-ic--scenario { background: rgba(234,179,8,.16);   color: #a16207; }
.fich-ic--croquis  { background: rgba(139,92,246,.14);  color: #7c3aed; }
.fich-ic--image    { background: rgba(6,182,212,.14);   color: #0e7490; }
.fich-ic--son      { background: rgba(168,85,247,.14);  color: #7e22ce; }
.fich-ic--document { background: rgba(100,116,139,.16); color: #475569; }
.fich-ic--dossier  { background: rgba(59,130,246,.14);  color: #1d4ed8; }
/* La réalisation prend l'indigo : ni le bleu des dossiers qui la contiennent,
   ni le rose des pages qu'elle contient. Elle n'est ni l'un ni l'autre. */
.fich-ic--realisation { background: rgba(99,102,241,.15); color: #4338ca; }
html.dark .fich-ic--page     { background: rgba(244,114,182,.18); color: #f9a8d4; }
html.dark .fich-ic--scenario { background: rgba(234,179,8,.18);   color: #fde047; }
html.dark .fich-ic--croquis  { background: rgba(139,92,246,.20);  color: #c4b5fd; }
html.dark .fich-ic--image    { background: rgba(6,182,212,.18);   color: #67e8f9; }
html.dark .fich-ic--son      { background: rgba(168,85,247,.18);  color: #d8b4fe; }
html.dark .fich-ic--document { background: rgba(148,163,184,.18); color: #cbd5e1; }
html.dark .fich-ic--dossier  { background: rgba(59,130,246,.20);  color: #93c5fd; }
html.dark .fich-ic--realisation { background: rgba(99,102,241,.24); color: #a5b4fc; }
.fich-rangee-ic svg { width: 24px; height: 24px; }
/* L'objet du cadre est une VIGNETTE, pas une puce : quand il n'y a pas de
   visage à montrer, c'est lui qui tient la place de l'image. */
.fich-cadre-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; border-radius: var(--radius-xl);
}
.fich-cadre-ic svg { width: 40px; height: 40px; }

/* ══ LA GRILLE ══════════════════════════════════════════════════════════════
   La liste dit « lequel est le plus récent ». La grille dit « lequel est-ce ».
   Une réalisation y montre son visage — la capture que le registre garde — et
   tout le reste montre son objet, en grand. */
.fich-grille {
  display: grid; gap: var(--espace-5);
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  padding: var(--espace-6) var(--espace-8);
}
.fich-carte {
  display: flex; flex-direction: column; align-items: center; gap: var(--espace-2);
  padding: var(--espace-4) var(--espace-3) var(--espace-5); border: 0; border-radius: var(--radius-lg);
  background: transparent; color: inherit; cursor: pointer; text-align: center; min-width: 0;
  transition: background var(--duree-1) var(--courbe);
}
.fich-carte:hover { background: var(--bg-secondary); }
.fich-carte--choisie, .fich-carte--choisie:hover { background: var(--accent); }
.fich-carte--choisie .fich-carte-nom, .fich-carte--choisie .fich-carte-sous { color: #fff; }
/* Le cadre garde sa hauteur qu'il porte une image ou un objet : sans elle, une
   grille où deux réalisations sur cinq ont un visage se déchire en escalier. */
.fich-carte-cadre {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 100%; height: 96px; border-radius: var(--radius-sm); overflow: hidden;
}
.fich-carte-visage {
  width: 100%; height: 100%; object-fit: cover; object-position: top center;
  border-radius: var(--radius-sm); border: 1px solid var(--border); background: #fff;
}
.fich-carte-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 68px; height: 68px; border-radius: var(--radius-xl);
}
.fich-carte-ic svg { width: 44px; height: 44px; }
/* Le visage se fabrique : un tour discret dans le coin, pas un carré vide. */
.fich-carte-attente {
  position: absolute; right: 6px; bottom: 6px; width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--accent); animation: spin 1s linear infinite;
}
.fich-carte-nom {
  font-size: var(--texte-2); font-weight: 500; color: var(--t-primary); max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fich-carte-sous {
  font-size: var(--texte-1); color: var(--t-faint); max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fich-rangee-txt { display: flex; flex-direction: column; min-width: 0; gap: 1px; flex: 1; }
.fich-rangee-nom {
  font-size: var(--texte-3); font-weight: 500; color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fich-rangee-sous { font-size: var(--texte-1); color: var(--t-faint); }
.fich-rangee-date { flex: none; font-size: var(--texte-1); color: var(--t-faint); }

/* L'APERÇU EST UN CADRE POSÉ SUR LA PAGE, PAS LA MOITIÉ DROITE.
   « Il y a un petit encadrement qui me montre visuellement la réalité
   contenue dans les dossiers. Toi, tu as carrément séparé la page en deux. »
   Il avait raison : un fond teinté plus une bordure épaisse, et l'œil lit
   deux surfaces côte à côte au lieu d'une page avec un aperçu dedans. Même
   fond que la liste, un filet pour la séparation, et c'est la CARTE qui
   porte la matière — c'est elle qu'on regarde. */
.fich-apercu {
  flex: none; width: 420px; max-width: 45%; overflow-y: auto;
  padding: var(--espace-8); border-left: 1px solid var(--border);
  background: var(--bg-primary);
  text-align: center;
}
.fich-apercu-vide {
  display: flex; align-items: center; justify-content: center; height: 100%;
  font-size: var(--texte-2); color: var(--t-faint);
}
.fich-cadre {
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--bg-primary); box-shadow: var(--ombre-2); overflow: hidden;
}
/* LA VIGNETTE D'UNE PAGE. L'iframe rend à 1280 px de large — la largeur d'un
   écran, pas celle du cadre — puis on la réduit : rendue à 400 px, une page
   déclencherait ses propres règles mobiles et montrerait une mise en page que
   personne ne verra. L'échelle est posée après coup par fichAjusterEchelle(),
   qui seule connaît la largeur réelle du cadre. */
.fich-cadre-zone { position: relative; width: 100%; aspect-ratio: 4 / 3; overflow: hidden; background: #fff; }
.fich-cadre-frame {
  position: absolute; top: 0; left: 0; width: 1280px; height: 960px; border: 0;
  transform: scale(var(--fich-echelle, .32)); transform-origin: top left;
  pointer-events: none;
}
.fich-cadre-image { display: block; width: 100%; height: 100%; object-fit: contain; background: var(--bg-tertiary); }
.fich-cadre-texte {
  margin: 0; padding: var(--espace-6); max-height: 320px; overflow: auto; text-align: left;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--texte-1); line-height: 1.55; color: var(--t-secondary);
  white-space: pre-wrap; word-break: break-word;
}
.fich-cadre-neutre {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--espace-4);
  aspect-ratio: 4 / 3; color: var(--t-faint); font-size: var(--texte-2);
}
.fich-cadre-neutre svg { width: 28px; height: 28px; }
/* LA FICHE, PAS UN APERÇU RATÉ. Le cadre montre ce qui a été CONSTRUIT ; un
   fichier sans surface visuelle n'a rien à y montrer, et le dire vaut mieux que
   d'y verser sa source. La deuxième ligne renvoie au geste qui, lui, l'ouvre. */
.fich-cadre-neutre-sous {
  max-width: 26ch; text-align: center; line-height: 1.4;
  font-size: var(--texte-1); color: var(--t-faint); opacity: .8;
}
/* Le visage se fabrique : un rond qui tourne, pour que l'attente ne ressemble
   pas à une panne. */
.fich-cadre-attente {
  width: 20px; height: 20px; border-radius: var(--radius-rond);
  border: 2px solid var(--border); border-top-color: var(--accent);
  /* `spin` et sa seconde existent déjà (.anim-spin) : un rond qui tourne n'a
     aucune raison d'avoir sa propre durée. Une valeur de plus dans l'échelle du
     mouvement, c'est celle qui rend la suivante normale. */
  animation: spin 1s linear infinite;
}
.fich-fiche-nom { margin-top: var(--espace-6); font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); word-break: break-word; }
.fich-fiche-type { margin-top: var(--espace-1); font-size: var(--texte-2); color: var(--t-dim); }
.fich-fiche-meta { margin-top: var(--espace-3); font-size: var(--texte-1); color: var(--t-faint); }
/* La légende d'un croquis : en italique, sous la fiche — c'est une phrase de
   son auteur, pas une donnée du fichier. */
.fich-fiche-note {
  margin-top: var(--espace-5); padding-top: var(--espace-5); border-top: 1px solid var(--border);
  font-size: var(--texte-2); font-style: italic; color: var(--t-secondary); text-align: left;
  white-space: pre-wrap; word-break: break-word;
}

.fich-depot {
  display: flex; align-items: center; justify-content: center; gap: var(--espace-4); flex-wrap: wrap;
  padding: var(--espace-6) var(--espace-8);
  padding-bottom: max(var(--espace-6), env(safe-area-inset-bottom));
  border-top: 1px dashed var(--border); color: var(--t-faint);
  transition: all var(--duree-1) var(--courbe);
}
.fich-depot.survol { background: var(--accent-bg); border-color: var(--accent); color: var(--accent); }
.fich-depot-ic { display: inline-flex; }
.fich-depot-ic svg { width: 15px; height: 15px; }
.fich-depot-titre { font-size: var(--texte-1); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; }
.fich-depot-sous { font-size: var(--texte-2); }
.fich-depot-choisir {
  font-size: var(--texte-2); font-weight: 500; color: var(--accent);
  padding: var(--espace-2) var(--espace-5); border-radius: var(--radius-rond);
  border: 1px solid var(--border);
}
.fich-depot:hover .fich-depot-choisir { border-color: var(--accent); }

/* Sous 900 px, l'aperçu passe SOUS la liste au lieu de la comprimer : deux
   colonnes de 200 px ne montrent ni un nom entier ni une vignette lisible. */
@media (max-width: 900px) {
  .fich-corps { flex-direction: column; }
  .fich-liste { flex: none; max-height: 55%; }
  .fich-apercu {
    width: 100%; max-width: 100%; flex: 1;
    border-left: 0; border-top: 1px solid var(--border);
    padding: var(--espace-6);
  }
  .fich-outils { padding-left: var(--espace-5); padding-right: var(--espace-5); }
  .fich-page-tete { padding-left: var(--espace-5); padding-right: var(--espace-5); }
  .fich-depot-sous { display: none; }
}

/* ── LA SURFACE DE CROQUIS ───────────────────────────────────────────────
   Dessin ET légende dans le même geste (voir crea-fichiers-projet.js). Posée
   à la main dans le document, hors de render() : un canevas reconstruit perd
   ses pixels, on dessinerait un trait et le rendu suivant l'effacerait. */
.fich-croquis-fond {
  /* MÊME ÉTAGE QUE LES AUTRES VOILES PLEIN ÉCRAN (80). Il était à 120 — un
     nombre choisi pour passer au-dessus, alors que RIEN n'habite entre les
     deux : c'est la surenchère que le cliquet des élévations compte, et une
     valeur de moins ici est une valeur de moins pour tout le fichier. */
  position: fixed; inset: 0; z-index: 80;
  display: flex; align-items: center; justify-content: center;
  padding: var(--espace-6); background: rgba(0,0,0,.45);
}
.fich-croquis-boite {
  display: flex; flex-direction: column; gap: var(--espace-5);
  width: min(980px, 96vw); max-height: 94vh; overflow: auto;
  padding: var(--espace-7); border-radius: var(--radius-xl);
  background: var(--bg-primary); border: 1px solid var(--border); box-shadow: var(--ombre-4);
}
.fich-croquis-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-5); }
.fich-croquis-titre { font-size: var(--texte-5); font-weight: 600; color: var(--t-primary); }
/* La scène garde le rapport du canevas (3/2) : sans elle, la toile s'étire et
   le trait ne suit plus le doigt. */
.fich-croquis-scene {
  aspect-ratio: 3 / 2; width: 100%; overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--radius-lg); background: #fff;
}
.fich-croquis-toile { display: block; width: 100%; height: 100%; touch-action: none; cursor: crosshair; }
.fich-croquis-outils { display: flex; align-items: center; gap: var(--espace-4); flex-wrap: wrap; }
.fich-croquis-groupe { display: inline-flex; align-items: center; gap: var(--espace-3); }
.fich-croquis-couleur {
  width: 22px; height: 22px; border-radius: var(--radius-rond);
  border: 2px solid transparent; cursor: pointer; padding: 0;
}
.fich-croquis-couleur.on { border-color: var(--t-primary); }
.fich-croquis-taille {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: transparent; cursor: pointer;
}
.fich-croquis-taille i { display: block; border-radius: var(--radius-rond); background: var(--t-primary); }
.fich-croquis-taille.on { border-color: var(--accent); background: var(--accent-bg); }
.fich-croquis-note {
  width: 100%; resize: vertical; padding: var(--espace-5);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-primary); color: var(--t-primary);
  font-size: var(--texte-3); font-family: inherit;
}
.fich-croquis-note:focus { outline: none; border-color: var(--accent); }
.fich-croquis-pied { display: flex; justify-content: flex-end; gap: var(--espace-4); }

/* Les gestes de rangement, sous la fiche d'un fichier : ouvrir, renommer,
   déplacer, supprimer. Ils tiennent sur deux rangs plutôt que de rétrécir —
   un bouton « Supprimer » illisible est un bouton qu'on clique par erreur. */
.fich-gestes {
  display: flex; flex-wrap: wrap; justify-content: center; gap: var(--espace-3);
  margin-top: var(--espace-6);
}
.fich-gestes .fich-bouton--ouvrir { margin: 0; }
.fich-bouton--danger { color: var(--danger); }
.fich-bouton--danger:hover { border-color: var(--danger); color: var(--danger); }

/* ── PARTAGER ET EXPORTER ────────────────────────────────────────────────
   Le panneau s'ouvre SOUS la fiche du fichier, dans la colonne d'aperçu, et
   non en boîte de dialogue par-dessus l'écran : ce qu'on partage doit rester
   visible pendant qu'on choisit avec qui. */
.fich-partage {
  margin-top: var(--espace-6); padding-top: var(--espace-6);
  border-top: 1px solid var(--border); text-align: left;
}
.fich-partage-titre {
  font-size: var(--texte-1); font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--t-faint); margin-bottom: var(--espace-4);
}
.fich-partage-acces { display: flex; gap: var(--espace-3); align-items: center; flex-wrap: wrap; }
.fich-partage-select {
  flex: 1; min-width: 150px; padding: var(--espace-3) var(--espace-5);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-primary); color: var(--t-primary); font-size: var(--texte-2); font-family: inherit;
}
.fich-partage-select:disabled { opacity: .5; }
/* L'adresse publiée s'affiche EN ENTIER et se coupe où elle veut : un lien
   tronqué par des points de suspension ne se recopie pas à la main quand la
   copie automatique est refusée par le navigateur. */
.fich-partage-note {
  margin: var(--espace-4) 0 var(--espace-7); font-size: var(--texte-1); color: var(--t-dim);
  word-break: break-all;
}
.fich-partage-liste { display: flex; flex-direction: column; gap: var(--espace-2); }
.fich-partage-item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px; width: 100%;
  padding: var(--espace-4) var(--espace-5); border-radius: var(--radius-sm);
  border: 1px solid transparent; background: transparent; cursor: pointer; text-align: left;
  transition: background var(--duree-1) var(--courbe), border-color var(--duree-1) var(--courbe);
}
.fich-partage-item:hover { background: var(--bg-secondary); border-color: var(--border); }
.fich-partage-nom { font-size: var(--texte-3); font-weight: 500; color: var(--t-primary); }
.fich-partage-sous { font-size: var(--texte-1); color: var(--t-faint); }
/* Ce qui n'existe pas est ÉCRIT, pas dessiné en bouton gris : un bouton
   désactivé promet pour plus tard sans dire quand ; une phrase dit pourquoi. */
.fich-partage-absent {
  margin-top: var(--espace-6); padding-top: var(--espace-5); border-top: 1px dashed var(--border);
  font-size: var(--texte-1); color: var(--t-faint); font-style: italic;
}

/* ── LE MENU DU BOUTON NOIR « PARTAGER » ─────────────────────────────────
   Ancré sous le bouton, en haut à droite, sur les deux surfaces (accueil d'un
   studio et espace fichiers). Structure reprise de la référence : accès,
   publication, export, puis un second écran pour le reste.
   Distinct du panneau posé sous la fiche d'un fichier, qui reste ce qu'il est. */
.part-menu {
  position: fixed; z-index: 9000;
  width: min(380px, calc(100vw - 24px));
  max-height: min(78vh, 640px); overflow-y: auto;
  padding: var(--espace-6);
  background: var(--bg-primary); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--ombre-4);
}
.part-titre {
  font-size: var(--texte-2); font-weight: 600; color: var(--t-primary);
  margin-bottom: var(--espace-4);
}
.part-acces { display: flex; gap: var(--espace-3); align-items: center; }
.part-select {
  flex: 1; min-width: 0; padding: var(--espace-4) var(--espace-5);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-primary); color: var(--t-primary);
  font-size: var(--texte-2); font-family: inherit;
}
.part-select:disabled { opacity: .5; }
/* Le bouton du lien est PLEIN et noir, comme sur la photo : c'est l'action que
   l'on vient chercher en ouvrant ce menu. */
.part-lien {
  display: inline-flex; align-items: center; gap: var(--espace-3); flex: none;
  padding: var(--espace-4) var(--espace-6); border-radius: var(--radius-sm); border: 0;
  background: var(--studio-ink); color: var(--studio-ink-t);
  font-size: var(--texte-2); font-weight: 600; cursor: pointer; white-space: nowrap;
}
.part-lien svg { width: 14px; height: 14px; }
.part-lien:disabled { opacity: .4; cursor: default; }
.part-note {
  margin: var(--espace-4) 0 var(--espace-5);
  font-size: var(--texte-1); color: var(--t-dim); word-break: break-all;
}
.part-sep { height: 1px; background: var(--border); margin: var(--espace-5) 0; }

.part-ligne {
  display: flex; align-items: center; gap: var(--espace-5); width: 100%; text-align: left;
  padding: var(--espace-4); border: 0; border-radius: var(--radius-sm);
  background: transparent; cursor: pointer;
  transition: background var(--duree-1) var(--courbe);
}
.part-ligne:hover { background: var(--bg-secondary); }
/* GRISÉ AVEC SA RAISON, PAS ABSENT. C'est l'idiome de la référence elle-même
   (« Publier en tant qu'artefact » y est grisé, avec son infobulle) : une
   ligne éteinte qui dit pourquoi vaut mieux qu'un trou — où l'on cherche — et
   qu'un bouton qui échoue — où l'on essaie. */
.part-ligne--off { opacity: .45; cursor: default; }
.part-ligne--off:hover { background: transparent; }
.part-ligne-ic {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--radius-xs);
  background: var(--bg-secondary); color: var(--t-dim);
}
.part-ligne-ic svg { width: 16px; height: 16px; }
.part-ligne-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.part-ligne-nom { font-size: var(--texte-3); font-weight: 500; color: var(--t-primary); }
.part-ligne-sous { font-size: var(--texte-1); color: var(--t-faint); }
.part-ligne-fin { flex: none; display: inline-flex; align-items: center; color: var(--t-dim); }
.part-ligne-fin svg { width: 14px; height: 14px; }
.part-action { font-size: var(--texte-1); color: var(--t-dim); }
.part-retour {
  display: flex; align-items: center; gap: var(--espace-3); width: 100%;
  padding: 0 0 var(--espace-5); border: 0; background: transparent; cursor: pointer;
  font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); text-align: left;
}
.part-retour svg { width: 15px; height: 15px; color: var(--t-dim); }

/* ── L'ÉTAT DE LA MISSION, DANS LA RANGÉE ──────────────────────────────────
   « Une fois l'objectif lancé, Créa se met au travail. »
   Un chrono seul ne dit pas si elle travaille, si elle a fini, ou si une
   borne l'a arrêtée — c'est pourtant la question qu'on vient poser à cette
   rangée. L'état se lit donc avant le temps, et il nomme sa cause. */
.obj-etat {
  flex-shrink: 0;
  font-size: max(0.6875rem, 11px);
  color: var(--t-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 34ch;
}
/* Au travail : l'accent, parce que quelque chose se dépense en ce moment. */
.obj-rang:not(.obj-rang-pause) .obj-etat { color: var(--accent); }
/* Atteint : la rangée cesse de pâlir. Un objectif fini n'est pas un objectif
   en pause — le confondre ferait relancer une mission déjà close. */
.obj-rang-atteint { opacity: 1; border-left-color: var(--ok, #10a37f); }
.obj-rang-atteint .obj-glyphe,
.obj-rang-atteint .obj-etat { color: var(--ok, #10a37f); }
/* Sur une rangée étroite, l'état s'efface avant l'aperçu du texte : ce qu'on a
   écrit compte plus qu'un libellé qu'on peut relire au survol. */
@media (max-width: 620px) { .obj-etat { display: none; } }

/* ══════════════════════════════════════════════════════════════════════════
   LE PLAN — sa rangée, et son parcours dans le volet.

   « Il crée un bloc par-dessus la barre de questions qui définit les étapes,
     et le plan est gardé dans le dossier de la personne. »
   ══════════════════════════════════════════════════════════════════════════ */

/* La rangée hérite de .file-rang : même hauteur, même rayon, même pile. Ce qui
   la distingue de l'objectif tient au liseré — l'objectif porte l'accent, le
   plan porte une teinte froide. Deux liserés de la même couleur dans une même
   pile se liraient comme une seule chose en deux morceaux. */
.plan-rang {
  border-left: 2px solid var(--plan, #8b5cf6);
  padding-left: 9px;
  background: color-mix(in srgb, var(--plan, #8b5cf6) 4%, var(--bg-secondary));
}
.plan-glyphe { color: var(--plan, #8b5cf6); }
.plan-texte b { font-weight: 600; color: var(--t-primary); }
.plan-apercu { color: var(--t-faint); font-weight: 400; }

/* Terminé : le liseré passe au vert et la teinte tombe. Un plan fini n'est pas
   un plan en cours — les confondre ferait chercher une étape suivante qui
   n'existe plus. */
.plan-rang-fini { border-left-color: var(--ok, #10a37f); background: var(--bg-secondary); }
.plan-rang-fini .plan-glyphe, .plan-rang-fini .plan-avance { color: var(--ok, #10a37f); }

.plan-avance {
  flex-shrink: 0;
  font-size: max(0.6875rem, 11px);
  color: var(--plan, #8b5cf6);
  white-space: nowrap;
}

/* LA JAUGE EST FINE ET MUETTE. Elle double le compte « 2/5 » — elle ne le
   remplace pas : un trait sans nombre ne dit pas combien il reste. Elle est là
   pour que la progression se voie SANS lire, du coin de l'œil. */
.plan-jauge {
  flex-shrink: 0;
  width: 46px; height: 3px;
  border-radius: var(--radius-rond);
  background: color-mix(in srgb, var(--plan, #8b5cf6) 18%, transparent);
  overflow: hidden;
}
.plan-jauge > span {
  display: block; height: 100%;
  background: var(--plan, #8b5cf6);
  transition: width var(--duree-2, .18s) var(--courbe);
}
.plan-rang-fini .plan-jauge > span { background: var(--ok, #10a37f); }
@media (max-width: 620px) { .plan-jauge { display: none; } }

/* ── LE PARCOURS, DANS LE VOLET ────────────────────────────────────────── */
.plan-corps { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 22px 24px; }
.plan-resume {
  margin-bottom: 16px;
  color: var(--t-secondary);
  font-size: max(0.875rem, 14px);
  line-height: 1.6;
  white-space: pre-wrap;
}
.plan-etapes { list-style: none; display: flex; flex-direction: column; gap: 2px; }
.plan-etape {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 8px 8px 8px 4px;
  border-radius: var(--radius-sm);
  font-size: max(0.875rem, 14px);
  color: var(--t-primary);
  line-height: 1.5;
}
.plan-etape:hover { background: rgba(0, 0, 0, .03); }
/* La puce est un BOUTON : cliquer une étape la fait avancer. Elle garde donc
   sa cible tactile pleine, même si le dessin est petit. */
.plan-etape-puce {
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  width: 24px; height: 24px;
  margin-top: -1px;
  border-radius: var(--radius-rond);
  color: var(--t-faint);
  transition: all var(--duree-1) var(--courbe);
}
.plan-etape-puce:hover { background: rgba(0, 0, 0, .06); color: var(--t-primary); }
.plan-etape-texte { flex: 1; min-width: 0; }
.plan-etape-encours .plan-etape-puce { color: var(--plan, #8b5cf6); }
.plan-etape-faite .plan-etape-puce { color: var(--ok, #10a37f); }
/* Faite : le texte se barre et pâlit. C'est le seul état où l'on n'a plus rien
   à lire — les autres restent en pleine encre. */
.plan-etape-faite .plan-etape-texte { color: var(--t-faint); text-decoration: line-through; }
.plan-etape-ecartee .plan-etape-texte { color: var(--t-faint); opacity: .6; }

/* Le cadenas n'apparaît que sur une étape RÉELLEMENT bloquée par le niveau
   d'accès. Le poser sur tout ce qui demande quelque chose apprendrait à ne
   plus le voir. */
.plan-etape-bloc { flex-shrink: 0; display: flex; align-items: center; color: var(--warn, #d97706); margin-top: 3px; }

/* Ce que l'étape a produit : un artefact, un fichier, une branche, une PR.
   C'est ce champ qui fait la différence entre une case cochée et une trace de
   ce qui a été fait. */
.plan-etape-produit { display: flex; flex-wrap: wrap; gap: 5px; flex-shrink: 0; margin-top: 2px; }
.plan-etape-produit a, .plan-etape-produit span {
  padding: 2px 7px;
  border-radius: var(--radius-rond);
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  font-size: max(0.6875rem, 11px);
  color: var(--t-secondary);
  white-space: nowrap;
}
.plan-etape-produit a:hover { border-color: var(--accent); color: var(--accent); }

/* LE PLAN SE MODIFIE À LA MAIN. Le texte d'une étape est `contenteditable` :
   discret au repos, cadré au focus. Le retrait ne se montre qu'au survol de
   l'étape — présent quand on le cherche, absent le reste du temps. */
.plan-etape-texte[contenteditable] {
  cursor: text;
  padding: 1px 5px; margin: -1px -5px;
  border-radius: var(--radius-xs);
  outline: none;
  transition: all var(--duree-1) var(--courbe);
}
.plan-etape-texte[contenteditable]:hover { background: rgba(0, 0, 0, .04); }
.plan-etape-texte[contenteditable]:focus { background: var(--bg-input, var(--bg-secondary)); box-shadow: 0 0 0 2px var(--accent, #0b8c66); }
.plan-etape-suppr {
  flex-shrink: 0;
  width: 20px; height: 20px; margin-top: 1px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-rond);
  color: var(--t-faint); font-size: max(1rem, 16px); line-height: 1;
  opacity: 0;
  transition: all var(--duree-1) var(--courbe);
}
.plan-etape:hover .plan-etape-suppr, .plan-etape-suppr:focus-visible { opacity: 1; }
.plan-etape-suppr:hover { color: var(--danger, #dc2626); background: color-mix(in srgb, var(--danger, #dc2626) 12%, transparent); }
.plan-ajout {
  margin-top: 6px; padding: 6px 8px;
  font-size: max(0.8125rem, 13px);
  color: var(--t-dim);
  border-radius: var(--radius-sm);
  transition: all var(--duree-1) var(--courbe);
}
.plan-ajout:hover { color: var(--accent, #0b8c66); background: rgba(0, 0, 0, .03); }

/* L'ANGLE MORT RESTE, ET IL EST EN BAS. C'est la seule partie du plan qui dit
   ce qu'on NE SAIT PAS, et c'est celle qu'on veut relire quand une étape se
   passe mal. Il était jeté avec le reste. */
.plan-angle {
  margin-top: 20px;
  padding: 12px 14px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--warn, #d97706) 7%, var(--bg-secondary));
  border: 1px solid color-mix(in srgb, var(--warn, #d97706) 22%, var(--border));
}
.plan-angle b { display: block; margin-bottom: 4px; font-size: max(0.75rem, 12px); color: var(--warn, #d97706); }
.plan-angle p { font-size: max(0.8125rem, 13px); color: var(--t-secondary); line-height: 1.55; }
.plan-pied { margin-top: 18px; font-size: max(0.75rem, 12px); color: var(--t-faint); }

/* ══════════════════════════════════════════════════════════════════════════
   LA VEILLE, DANS PLANIFIÉ — une rangée par objectif, toutes surfaces.

   Elle reprend la forme de `.file-rang` : même hauteur, mêmes gestes qui
   s'estompent. Une deuxième forme pour dire la même chose (« un travail en
   cours, et ce qu'on peut en faire ») obligerait à réapprendre à lire.

   TROIS ÉTATS, ET LA COULEUR NE MENT PAS. « Au travail » porte l'accent ;
   « en attente de sa surface » reste gris — c'est un objectif qui n'avance
   pas, et une pastille verte le ferait passer pour le contraire ; « en
   pause » s'efface en pointillés, comme le choix tenu de la file.
   ══════════════════════════════════════════════════════════════════════════ */
.veille-rang {
  display: flex; align-items: center; gap: 10px;
  min-height: 40px;
  padding: 4px 6px 4px 11px;
  margin-bottom: 8px;
  border-radius: var(--radius);
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  color: var(--t-secondary);
  font-size: max(0.78125rem, 12.5px);
  box-shadow: var(--ombre-1);
  transition: all var(--duree-1) var(--courbe);
}
.veille-rang:hover { border-color: var(--border-hov); }
.veille-travail {
  background: color-mix(in srgb, var(--accent) 7%, var(--bg-secondary));
  border-color: color-mix(in srgb, var(--accent) 28%, var(--border));
  color: var(--t-primary);
}
.veille-arret { background: transparent; border-style: dashed; box-shadow: none; color: var(--t-faint); }

.veille-glyphe { flex-shrink: 0; display: inline-flex; color: var(--t-faint); }
.veille-texte { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.veille-texte b { font-size: max(0.8125rem, 13px); color: var(--t-primary); }
.veille-objet {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--t-dim);
}
/* L'ÉTAT SE LIT SOUS LE TEXTE, PAS À CÔTÉ. Sur une surface étroite, une
   colonne d'état se fait écraser par le texte de l'objectif — et c'est
   justement le mot qu'on est venu chercher. */
.veille-etat { font-size: max(0.6875rem, 11px); color: var(--t-faint); }
.veille-travail .veille-etat { color: var(--accent); }

.veille-chrono, .veille-tours {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  font-size: max(0.71875rem, 11.5px);
  color: var(--t-faint);
}

/* ══════════════════════════════════════════════════════════════════════════
   LES PLUGINS — le menu « + » et le panneau, sur la forme des photos.
   ══════════════════════════════════════════════════════════════════════════ */

/* « Fichiers et dossiers » : une rangée, trois portes. Le corps porte le clic
   courant ; les deux gestes du bout gardent le dossier entier et l'appareil
   photo à portée. Ils s'estompent au repos comme ceux de la file — ce qu'on
   lit au repos, c'est le libellé, pas deux icônes de plus. */
.plus-fichiers { padding: 0 6px 0 0; gap: 0; }
.plus-fichiers-corps {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px;
  text-align: left;
  color: inherit;
}
.plus-fichiers-geste {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border-radius: var(--radius-sm);
  color: var(--t-dim);
  opacity: .55;
  transition: all var(--duree-1) var(--courbe);
}
.plus-fichiers:hover .plus-fichiers-geste,
.plus-fichiers:focus-within .plus-fichiers-geste { opacity: 1; }
@media (hover: none) { .plus-fichiers-geste { opacity: 1; } }
.plus-fichiers-geste:hover { background: rgba(0, 0, 0, .07); color: var(--t-primary); }

/* Le logo d'un plugin est une IMAGE, pas un trait : il ne prend pas la couleur
   du texte, et il garde sa place même quand la route logo rend 404. */
.plug-icone {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px;
  color: var(--t-dim);
}

/* ── LE PANNEAU ─────────────────────────────────────────────────────────
   Il s'ouvre VERS LE HAUT depuis la barre basse, comme les deux menus qui
   l'encadrent (dossier, exécution) : un panneau qui descendrait de la barre
   basse sortirait de la fenêtre. Deux colonnes côte à côte, la seconde
   n'apparaissant qu'une fois « Connecter des plugins » ouvert — c'est la
   forme de la photo. Sous 560 px, elles s'empilent : deux colonnes de 260 px
   sur un téléphone, c'est une colonne coupée en deux. */
.plug-panneau {
  position: absolute; left: 0; bottom: 100%;
  margin-bottom: 8px;
  z-index: 50;
  /* ALIGNÉES PAR LE BAS, PAS ÉTIRÉES. `stretch` donnait à la colonne des
     plugins la hauteur du catalogue d'à côté : quatre lignes dans une boîte
     de vingt, et un grand vide au milieu du panneau. Chacune prend la sienne,
     et elles partent du même bord — celui du bouton qui les ouvre. */
  display: flex; align-items: flex-end; gap: 8px;
}
@media (max-width: 560px) {
  .plug-panneau { flex-direction: column; align-items: stretch; }
}
.plug-colonne {
  display: flex; flex-direction: column;
  width: min(260px, calc(100vw - 2rem));
  max-height: min(420px, 60vh);
  border-radius: var(--radius-lg);
  background: var(--bg-input);
  border: 1px solid var(--border);
  box-shadow: var(--ombre-3, 0 18px 50px rgba(0, 0, 0, .35));
  overflow: hidden;
}
.plug-colonne-2 { width: min(280px, calc(100vw - 2rem)); }

.plug-recherche {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
}
.plug-recherche-loupe { display: inline-flex; color: var(--t-faint); flex-shrink: 0; }
.plug-recherche input {
  flex: 1; min-width: 0;
  background: none; border: none; outline: none;
  color: var(--t-primary);
  font-size: max(0.8125rem, 13px);
}
.plug-recherche input::placeholder { color: var(--t-faint); }

.plug-liste { flex: 1; min-height: 0; overflow-y: auto; padding: 4px; }
.plug-rang {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 7px 8px;
  border-radius: var(--radius-sm);
  color: var(--t-secondary);
  font-size: max(0.8125rem, 13px);
  text-align: left;
  transition: background var(--duree-1) var(--courbe);
}
.plug-rang:hover { background: rgba(0, 0, 0, .06); }
.plug-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Seul ce qui est ALLUMÉ porte l'accent. Un connecteur simplement présent au
   catalogue n'est pas un connecteur branché. */
.plug-rang-actif { color: var(--accent); }
.plug-rang-on .plug-nom { color: var(--t-primary); }
.plug-vide { padding: 14px 10px; font-size: max(0.75rem, 12px); color: var(--t-faint); line-height: 1.5; }

.plug-pied {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 9px 12px;
  border-top: 1px solid var(--border);
  color: var(--t-secondary);
  font-size: max(0.8125rem, 13px);
  text-align: left;
  transition: background var(--duree-1) var(--courbe);
}
.plug-pied:hover { background: rgba(0, 0, 0, .06); }
.plug-pied-ouvert { color: var(--accent); }
.plug-chevron { flex-shrink: 0; display: inline-flex; color: var(--t-faint); }

/* Le « + » de chaque connecteur. Il ne change pas de couleur selon ce qu'il
   va faire : quatre teintes pour quatre chemins feraient un code à apprendre.
   C'est l'infobulle qui dit le verbe — Connecter, Ouvrir, Autoriser, Bientôt. */
.plug-brancher {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  border-radius: var(--radius-sm);
  color: var(--t-dim);
  font-size: max(0.75rem, 12px);
  transition: all var(--duree-1) var(--courbe);
}
.plug-brancher:hover { background: rgba(0, 0, 0, .08); color: var(--t-primary); }
.plug-rang-on .plug-brancher { color: var(--accent); }
/* Ce qui n'est pas câblé le montre AVANT le clic — c'est la seule différence
   de forme, et elle porte sur la seule chose qu'on regretterait d'apprendre
   après coup. */
.plug-brancher-pas-cable { opacity: .4; }

/* LE BOUTON N'A PAS DE MOT. Trois logos qui se chevauchent, et le compte du
   reste quand il y en a plus. Les marques se reconnaissent plus vite qu'un
   libellé se lit — c'est toute la raison d'un logo. Le nom part dans
   l'infobulle et l'aria-label : ce qui disparaît de l'écran ne doit jamais
   disparaître de ce qu'un lecteur d'écran annonce. */
.plug-bouton {
  display: inline-flex; align-items: center; gap: 5px;
  height: 26px; padding: 0 6px;
  border-radius: var(--radius-sm);
  transition: background var(--duree-1) var(--courbe);
}
.plug-bouton:hover { background: rgba(0, 0, 0, .07); }
.plug-bouton-ouvert { background: rgba(0, 0, 0, .09); }
.plug-vignettes { display: inline-flex; align-items: center; }
.plug-vignette {
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px;
  color: var(--t-dim);
}
/* Le chevauchement demande un fond derrière chaque vignette, sinon deux logos
   se mêlent au lieu de se superposer. */
.plug-vignette + .plug-vignette {
  margin-left: -5px;
  border-radius: var(--radius-xs);
  box-shadow: 0 0 0 2px var(--bg-secondary);
}
.plug-reste {
  font-size: max(0.6875rem, 11px);
  font-variant-numeric: tabular-nums;
  color: var(--t-faint);
}

/* Le titre d'une section du panneau Plugins. Il porte l'aide en infobulle :
   « une app a un compte, un serveur MCP a une adresse » est ce qu'on a besoin
   de savoir une fois, pas à chaque lecture. */
.plug-section {
  padding: 8px 8px 3px;
  font-size: max(0.625rem, 10px);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--t-faint);
}
.plug-section-tete { padding: 10px 12px 6px; border-bottom: 1px solid var(--border); }

/* Le rang d'un plugin et son geste de retrait, côte à côte. Le geste
   s'estompe au repos : ce qu'on lit au repos, c'est le nom du serveur, pas la
   croix qui l'enlève. */
.plug-rang-hote { display: flex; align-items: center; }
.plug-rang-hote .plug-rang { flex: 1; min-width: 0; }
.plug-oter {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; margin-right: 4px;
  border-radius: var(--radius-sm);
  color: var(--t-faint);
  opacity: 0;
  transition: all var(--duree-1) var(--courbe);
}
.plug-rang-hote:hover .plug-oter,
.plug-rang-hote:focus-within .plug-oter { opacity: .7; }
.plug-oter:hover { opacity: 1; background: rgba(0, 0, 0, .08); color: var(--t-primary); }
@media (hover: none) { .plug-oter { opacity: .7; } }

/* ── L'INTERRUPTEUR D'UNE COMPÉTENCE ──────────────────────────────────────
 *
 * « Les compétences, elles doivent être alignées dans le style [de la
 *   référence], comme je te l'ai montré. »
 *
 * Sur la photo, l'état d'une compétence est un VRAI interrupteur : une pastille
 * qui glisse, bleue quand elle est active, et rien d'écrit à côté. On avait une
 * case à cocher suivie des mots « Active » / « En veille » — la même
 * information, dans une forme qui ne se lit pas d'un coup d'œil et qui prend
 * trois fois la place.
 *
 * La case reste DESSOUS, invisible : c'est elle qui porte l'état, le clavier et
 * les lecteurs d'écran. On n'habille pas un bouton, on habille une vraie
 * commande de formulaire.
 */
.crea-inter { position: relative; display: inline-flex; align-items: center; flex: none; width: 40px; height: 24px; cursor: pointer; }
.crea-inter input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.crea-inter-piste {
  width: 40px; height: 24px; border-radius: var(--radius-rond); background: var(--bg-tertiary);
  border: 1px solid var(--border); transition: background .18s ease, border-color .18s ease; pointer-events: none;
}
.crea-inter-bille {
  position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%;
  /* L'OMBRE SUIT LE THÈME. Elle était figée à rgba(0,0,0,.28) : juste en
     sombre, trop lourde en clair, où elle posait une ombre de nuit sous une
     pastille de jour. `--ombre-1` porte les deux valeurs. Comparé à l'écran,
     dans les deux thèmes : en sombre c'est indiscernable, en clair la pastille
     reste nettement détachée de sa piste. */
  background: #fff; box-shadow: var(--ombre-1); transition: transform .18s ease; pointer-events: none;
}
.crea-inter input:checked ~ .crea-inter-piste { background: var(--accent); border-color: var(--accent); }
.crea-inter input:checked ~ .crea-inter-bille { transform: translateX(16px); }
/* Le focus clavier doit se voir : sans lui, la commande est inatteignable
   autrement qu'à la souris. */
.crea-inter input:focus-visible ~ .crea-inter-piste { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ═══════════════════════════════════════════════════════════════════════════
 * LA PAGE D'UNE COMPÉTENCE — deux colonnes, comme sur la référence.
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * L'arborescence des fichiers à gauche, le texte à droite. En une seule
 * colonne, le sélecteur de fichiers était un menu déroulant : on ne voyait pas
 * ce que la compétence CONTIENT — et une compétence, ce sont ses fichiers
 * autant que sa notice.
 *
 * Sur un écran étroit, les deux colonnes se remettent l'une sous l'autre :
 * treize rem de largeur fixe sur un téléphone laisseraient au texte de quoi
 * afficher quatre mots par ligne.
 */
.crea-comp-grille { display: grid; gap: 1rem; grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 768px) {
  .crea-comp-grille { grid-template-columns: 13.5rem minmax(0, 1fr); }
}
/* L'arbre défile seul : c'est la colonne qui peut faire soixante et une
   lignes, et la page entière ne doit pas s'allonger pour elle. */
.crea-comp-arbre { max-height: 30rem; overflow-y: auto; overscroll-behavior: contain; }
.crea-comp-ligne {
  display: flex; align-items: center; gap: 0.375rem; width: 100%;
  padding: 0.3125rem 0.5rem; border: none; background: none; cursor: pointer;
  /* L'ÉCHELLE, PAS UNE VALEUR DE PLUS. `0.5rem` valait exactement
     `--radius-sm`, et c'était une trente-quatrième valeur distincte pour rien :
     le cliquet des formes compte les valeurs, pas les pixels. */
  border-radius: var(--radius-sm); text-align: left; color: var(--t-secondary);
  font-size: max(0.75rem, 12px); line-height: 1.35;
}
.crea-comp-ligne:hover { background: var(--bg-secondary); }
.crea-comp-ligne[aria-current="true"] { background: var(--bg-secondary); color: var(--t-primary); font-weight: 600; }
/* Le nom d'un fichier ne se coupe pas en deux lignes : il se tronque, et son
   titre complet reste dans l'infobulle. Une colonne d'arborescence dont les
   lignes font deux hauteurs différentes ne se lit plus comme un arbre. */
.crea-comp-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ═══════════════════════════════════════════════════════════════════════════
   LES DEUX BARRES — un cadre, deux mondes (voir src/crea-barres.js)

   Le cadre est écrit ici UNE fois : bascule, menu, sections, arbre. Les deux
   mondes ne fournissent que leur contenu. C'est la réponse au vrai défaut —
   six barres existaient, chacune avec son propre en-tête et sa propre liste,
   et c'est ce qui rendait une septième impensable.
   ═══════════════════════════════════════════════════════════════════════════ */
.bar {
  position: relative;
  display: flex; flex-direction: column; height: 100%; min-height: 0;
  background: var(--bg-primary); color: var(--t-primary);
  font-size: var(--texte-2);
}
/* Plus de croix : les boutons du haut ouvrent et referment déjà cette barre.
   Un second geste de fermeture DANS la barre dirait deux fois la même chose. */

/* ── LA BASCULE ─────────────────────────────────────────────────────────────
   Deux onglets dans une gouttière, comme un segment de contrôle : c'est le
   geste le plus fréquent de l'application, il mérite d'être le plus haut et le
   plus large. Le compte sur l'onglet INACTIF dit ce qu'on va trouver — c'est
   ce qui en fait un transport plutôt qu'un interrupteur. */
/* ── LA RANGÉE DU HAUT ──────────────────────────────────────────────────
   Le titre à gauche, les deux mondes groupés à droite : une seule ligne pour
   ce qui en occupait deux pleine largeur. */
.bar-tete {
  display: flex; align-items: center; gap: var(--espace-4);
  margin: var(--espace-4) var(--espace-5) var(--espace-3);
  min-width: 0;
}
.bar-bascule {
  display: flex; flex: none; gap: 2px;
  padding: 2px; border-radius: var(--radius); background: var(--bg-secondary);
}
.bar-bascule-onglet {
  display: flex; align-items: center; justify-content: center; gap: var(--espace-2);
  /* L'échelle, pas un rayon calculé à l'œil. Un « 10px » — le 12 du contenant
     moins ses 2 de gouttière — était une 35ᵉ valeur distincte, et le cliquet
     des formes l'a dit tout de suite. */
  padding: var(--espace-4) var(--espace-3); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-dim); cursor: pointer;
  font-size: var(--texte-3); font-weight: 500; min-width: 0;
  transition: all var(--duree-1) var(--courbe);
}
.bar-bascule-onglet:hover { color: var(--t-primary); }
.bar-bascule-onglet.est-actif {
  background: var(--bg-primary); color: var(--t-primary);
  /* `--ombre-1`, pas une ombre à la main. Elles étaient trente-sept écrites une
     à une — dont la moitié en double, la même élévation réécrite pour le clair
     puis pour le sombre. L'échelle porte les deux thèmes ; en rouvrir une seule
     rouvre la porte par où la dérive était entrée. */
  box-shadow: var(--ombre-1);
}
.bar-bascule-ic { display: inline-flex; flex: none; }
.bar-bascule-ic svg { width: 17px; height: 17px; }
/* DEUX CARRÉS, PAS DEUX PILULES. Sans libellé, un bouton qui garde la largeur
   d'un mot devient une plage vide autour d'un dessin. 28 px et non 32 : « tu
   viens le réduire aussi, parce qu'il est beaucoup trop gros » — le titre est
   ce qu'on lit, ces deux-là sont ce qu'on vise. */
.bar-bascule-onglet { width: 28px; height: 28px; padding: 0; }
.bar-bascule-ic svg { width: 16px; height: 16px; }

/* ── LE MENU ────────────────────────────────────────────────────────────── */
/* LE HAUT DE LA BARRE DÉFILE, ET IL EST BORNÉ.
   « Tu vas venir la rendre scrollable, comme ça tu pourras rajouter diverses
   catégories de choses. » Sans borne, chaque catégorie ajoutée poussait les
   projets et les sessions hors de l'écran — et ce sont eux qu'on vient
   chercher. `max-height` en pourcentage de la fenêtre plutôt qu'en pixels :
   sur un portable la moitié de la barre, sur un grand écran une part plus
   petite, ce qui est le bon partage dans les deux cas. */
/* LA COUPE TOMBE APRÈS UNE RANGÉE, PAS AU MILIEU D'UNE.
   « Le défilement ne prend pas à partir du bon niveau : il doit laisser jusqu'à
   Coworker, et après, tout le reste défile. » C'était `max-height: 42vh` — une
   fraction d'écran, donc une coupe qui tombe où elle veut. C'est maintenant un
   NOMBRE de rangées, posé par `blocMenu` (src/crea-barres.js) qui compte les
   rangées jusqu'à Coworker : la hauteur suit la liste, elle ne la devine plus.
   `--bar-entree-h` est déclarée ici et IMPOSÉE à `.bar-entree` : si la rangée
   grandissait sans que ce chiffre suive, le calcul couperait de nouveau au
   milieu d'une entrée. */
.bar-menu {
  --bar-entree-h: 36px;
  display: flex; flex-direction: column; padding: 0 var(--espace-4) var(--espace-3);
  /* `flex: none`, ET C'EST LE POINT. Avec `0 1 auto`, le menu se laissait
     écraser par la liste du dessous : mesuré à 6 px de haut sur une fenêtre de
     700, `max-height` bien calculée à 366 et jamais atteinte. Une hauteur qui
     ne tient pas contre son voisin n'est pas une hauteur. */
  flex: none; min-height: 0;
  max-height: calc(var(--bar-entree-h) * var(--bar-menu-rangees, 6) + var(--espace-3));
  overflow-y: auto; scrollbar-width: thin;
}
/* TRANSLUCIDE ET COURT, AU MILIEU : il ferme la zone sans se faire remarquer. */
.bar-filet { flex: none; height: 1px; width: 38%; margin: var(--espace-2) auto var(--espace-3); background: var(--border); opacity: .5; }
/* « C'est écrit tout petit — agrandis un peu plus chaque chose. Comme dans
   Claude, c'est bien agrandi. » Les entrées passent de --texte-3 à --texte-5,
   et leur hauteur est FIXÉE : c'est elle que `.bar-menu` multiplie pour poser
   la borne du défilement. Une hauteur qui dépendrait du texte ferait dériver
   la coupe au premier changement de police. */
.bar-entree {
  display: flex; align-items: center; gap: var(--espace-4); width: 100%; text-align: left;
  height: var(--bar-entree-h, 36px); flex: none;
  padding: 0 var(--espace-4); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-secondary); cursor: pointer;
  font-size: var(--texte-5);
  transition: all var(--duree-1) var(--courbe);
}
.bar-entree:hover { background: var(--bg-secondary); color: var(--t-primary); }
.bar-entree--fort { color: var(--t-primary); font-weight: 500; }
/* La poignée du pli (« Afficher plus ») est partie avec le pli : le menu défile
   après Coworker, donc rien n'est plus caché derrière un clic. Sa règle part
   avec elle — une règle que plus personne ne porte est une promesse qu'on croit
   tenir. */
.bar-entree-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.bar-entree-ic svg { width: 19px; height: 19px; }
.bar-entree:hover .bar-entree-ic { color: var(--t-dim); }
.bar-entree-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── LE CORPS ───────────────────────────────────────────────────────────── */
/* `.bar-filtre` EST PARTIE — c'était la grosse barre.
   « Un tout petit bouton, comme dans Claude, à côté de chaque studio. Toi tu es
   parti, tu m'as mis une grosse barre. » Le filtre est maintenant `.fl-ic`, une
   icône au bout de la ligne d'un titre : celle d'une section, celle d'un
   studio. Voir `.fl--petit` plus bas. */

/* LE RANG D'UN STUDIO, et l'en-tête d'une section : ils portent le BOUTON du
   filtre. Le panneau, lui, n'est plus ici — il se rend à la racine, hors du
   corps qui défile. */
.bar-section-tete, .bar-rang { position: relative; }
/* LE RANG D'UN STUDIO : la branche, et le filtre à côté. Un `<button>` ne peut
   pas contenir un second bouton — le navigateur donne le clic au parent. */
.bar-rang { display: flex; align-items: center; }
/* LE RANG D'UNE SESSION : la feuille, et son geste d'archivage à côté. Un
   `<button>` ne peut pas contenir un second bouton — le navigateur donne le
   clic au parent —, et le geste ne se montre qu'au survol pour ne pas peser
   sur une liste qu'on parcourt des yeux. */
/* ── CE QUE LA PUCE D'UNE SESSION RACONTE ─────────────────────────────────
 *
 * « Les petits points, ils viennent clignoter en vert. Là sur la photo ils
 *  sont oranges. »
 *
 * Quatre états, et les couleurs sont les JETONS SÉMANTIQUES du dépôt —
 * `--success`, `--warn`, `--danger` — que `couleur-lisible` a déjà mesurés sur
 * les deux fonds des deux thèmes. Poser un vert à moi ici, c'est reposer les
 * 2,22 de contraste que ce travail a corrigés.
 *
 * SEUL « TRAVAILLE » BAT. Une liste où quatre pastilles clignotent ne dit plus
 * laquelle regarder ; le battement est réservé à ce qui change vraiment sous
 * les yeux. Et il s'arrête quand le système le demande — une animation qu'on
 * ne peut pas éteindre est un mur pour qui la supporte mal. */
.bar-feuille-puce.est-travaille { color: var(--success); animation: bar-puce-bat 1.4s ease-in-out infinite; }
.bar-feuille-puce.est-alire     { color: var(--warn); }
.bar-feuille-puce.est-erreur    { color: var(--danger); }
/* LES QUATRE ÉTATS D'UNE CADENCE, dans la même colonne que la puce d'une
   session. Le vocabulaire des couleurs est celui du dépôt : vert ce qui
   tourne, rouge ce qui est cassé, creux ce qui ne partira pas. LA PUCE NE BAT
   PAS — `est-travaille` clignote parce qu'une étape est EN COURS ; une cadence
   active attend son heure, et un point qui clignote toute la journée pour dire
   « prévue » userait le seul signal qui veut dire « ça se passe maintenant ». */
.bar-feuille-puce.est-actif     { color: var(--success); opacity: 1; }
.bar-feuille-puce.est-panne     { color: var(--danger); opacity: 1; }
/* CELLE QUI ATTEND UNE RÉPONSE. En orange, la couleur que la barre emploie déjà
   pour « à lire » : c'est la même famille — quelque chose vous attend — et lui
   donner une sixième couleur ferait un vocabulaire de plus à apprendre. */
.bar-feuille-puce.est-attend    { color: var(--warn); opacity: 1; }
.bar-feuille-date.est-attend    { color: var(--warn); }
.bar-feuille-puce.est-pause,
.bar-feuille-puce.est-arret,
.bar-feuille-puce.est-finie     { color: var(--t-faint); opacity: .45; }
@keyframes bar-puce-bat { 0%, 100% { opacity: 1 } 50% { opacity: .25 } }
@media (prefers-reduced-motion: reduce) {
  .bar-feuille-puce.est-travaille { animation: none; }
}
.bar-feuille-rang { display: flex; align-items: center; }
.bar-feuille-rang > .bar-feuille { flex: 1; min-width: 0; }
/* LES DEUX GESTES DE SURVOL D'UNE SESSION SONT PARTIS AVEC LEUR BALISE : ils
   vivent dans le menu ⋮, comme ceux d'une conversation. Une règle sans personne
   à qui l'appliquer se lit comme une mise en forme qui existe encore. */
/* UNE SESSION ARCHIVÉE SE VOIT : sans marque, « Statut › Toutes » rendrait deux
   listes mêlées qu'on ne distingue pas. */
.bar-feuille.est-archivee .bar-feuille-nom { color: var(--t-faint); font-style: italic; }
.bar-rang > .bar-branche { flex: 1; min-width: 0; }
.bar-rang > .fl { flex: none; margin-right: var(--espace-3); }
.bar-section-tete > .fl, .bar-rang > .fl { position: static; }
.bar-corps { flex: 1; min-height: 0; overflow-y: auto; padding: 0 var(--espace-4) var(--espace-6); }
.bar-section-tete {
  display: flex; align-items: center; gap: var(--espace-2);
  padding: var(--espace-5) var(--espace-4) var(--espace-2);
}
/* LE TITRE D'UNE SECTION EST UN BOUTON QUAND ELLE SE PLIE. Même chevron et
   même rotation que les branches des studios : deux moitiés d'une même barre
   qui doivent se manœuvrer pareil. */
.bar-section-titre {
  display: flex; align-items: center; gap: var(--espace-2);
  flex: 1; min-width: 0; padding: 0; border: 0;
  background: transparent; cursor: pointer; text-align: left;
}
.bar-section-titre .bar-branche-chevron { color: var(--t-faint); }
.bar-section-titre:hover .bar-section-nom { color: var(--t-dim); }

/* LE NOM POUSSE, LES GESTES SE TIENNENT. Avec `space-between` et deux gestes,
   l'espace se répartissait ENTRE les trois : la loupe se retrouvait au milieu
   de la ligne, loin du tri avec qui elle fait paire. */
.bar-section-nom {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--texte-4); color: var(--t-faint); letter-spacing: .01em;
}
.bar-section-geste {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border: 0; border-radius: var(--radius-xs);
  background: transparent; color: var(--t-faint); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.bar-section-geste { flex: none; }
.bar-section-geste:hover { background: var(--bg-secondary); color: var(--t-primary); }
.bar-section-geste.est-actif { background: var(--accent-bg, var(--bg-secondary)); color: var(--accent); }
.bar-section-geste svg { width: 14px; height: 14px; }
/* Le titre d'une rangée n'apparaît que lorsqu'il y en a DEUX — un titre au-dessus
   d'une liste homogène n'apprend rien (voir rangeesAccueil). */
.bar-rangee-titre {
  font-size: var(--texte-2); color: var(--t-faint); font-weight: 500;
  padding: var(--espace-4) var(--espace-4) var(--espace-2); margin: 0;
}
.bar-vide {
  font-size: var(--texte-2); color: var(--t-faint); line-height: 1.5;
  padding: var(--espace-2) var(--espace-4) var(--espace-4); margin: 0;
}

/* ── LA FEUILLE : une conversation, une session ─────────────────────────── */
.bar-feuille {
  display: flex; align-items: center; gap: var(--espace-3); width: 100%; text-align: left;
  padding: var(--espace-4) var(--espace-4); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-secondary); cursor: pointer;
  font-size: var(--texte-5); min-width: 0;
  transition: all var(--duree-1) var(--courbe);
}
.bar-feuille:hover { background: var(--bg-secondary); color: var(--t-primary); }
.bar-feuille.est-active { background: var(--accent-bg); color: var(--accent); font-weight: 500; }
/* DEUX CRANS, PARCE QU'IL Y A DEUX APPARTENANCES. `--n1` : la session pend du
   studio. `--n2` : elle pend d'un projet. Un seul cran pour les deux faisait
   lire une session libre comme la dernière du groupe au-dessus. */
.bar-feuille--n1 { padding-left: calc(var(--espace-4) + 17px); }
.bar-feuille--n2 { padding-left: calc(var(--espace-4) + 34px); }
.bar-feuille-puce { display: inline-flex; flex: none; color: var(--t-faint); opacity: .7; }
.bar-feuille-puce svg { width: 14px; height: 14px; }
.bar-feuille.est-active .bar-feuille-puce { color: var(--accent); opacity: 1; }
.bar-feuille-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* UNE SESSION SANS CHAT N'A PAS DE NOM, et elle le dit en gris plutôt que
   d'afficher « Session 3 » — un compteur interne n'apprend rien à personne. */
.bar-feuille-nom.est-sans-nom { color: var(--t-faint); font-style: italic; }
.bar-feuille-date { flex: none; font-size: var(--texte-1); color: var(--t-faint); }
/* ── L'ICÔNE D'UNE ROUTINE ────────────────────────────────────────────────
 *
 * Sa capture ne porte pas de pastille de couleur : une icône sombre, le nom, et
 * rien à droite. L'icône vaut la place de la puce — même colonne, même largeur,
 * pour que les lignes des deux sortes s'alignent dans une barre qui les mêle.
 *
 * ELLE NE PORTE QUE DEUX ÉTATS, ET AUCUN AU REPOS. Une routine qui attend son
 * heure n'a rien à signaler ; ce qui mérite une couleur, c'est ce qui demande
 * quelque chose (une autorisation qui court) ou ce qui est cassé. Le vocabulaire
 * est celui du dépôt, déjà mesuré sur les deux fonds des deux thèmes. */
.bar-feuille-ic { display: inline-flex; flex: none; color: var(--t-dim); }
.bar-feuille-ic svg { width: 14px; height: 14px; }
.bar-feuille-ic.est-attend { color: var(--warn); }
.bar-feuille-ic.est-panne  { color: var(--danger); }
.bar-feuille.est-active .bar-feuille-ic { color: var(--accent); }

/* ── LA RECHERCHE ─────────────────────────────────────────────────────────
   Le champ est celui d'app.js — mêmes identifiants, mêmes gestionnaires, même
   `STATE.searchQuery`. Un second champ avec son propre réglage aurait divergé
   du premier au premier changement. */
.bar-cherche {
  display: flex; align-items: center; gap: var(--espace-3);
  margin: 0 var(--espace-4) var(--espace-3); padding: 0 var(--espace-4);
  min-height: 38px;
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  background: var(--bg-secondary);
  transition: all var(--duree-1) var(--courbe);
}
.bar-cherche:focus-within { border-color: var(--accent); background: var(--bg-primary); }
.bar-cherche-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.bar-cherche-ic svg { width: 16px; height: 16px; }
.bar-cherche-champ {
  flex: 1; min-width: 0; border: 0; outline: none; background: transparent;
  color: var(--t-primary); font-size: var(--texte-3); font-family: inherit;
}
.bar-cherche-vider {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 20px; height: 20px; padding: 0;
  border: 0; border-radius: var(--radius-rond); background: transparent;
  color: var(--t-faint); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.bar-cherche-vider:hover { background: var(--bg-tertiary, var(--bg-secondary)); color: var(--t-primary); }
.bar-cherche-vider svg { width: 12px; height: 12px; }

/* ── LA LIGNE D'UNE CONVERSATION : le titre, ses marques, son menu ────────
   Le menu « … » n'apparaît qu'au survol — sur mobile il reste visible, il n'y
   a pas de survol pour le faire venir. */
.bar-feuille-rang { position: relative; display: flex; align-items: center; }
/* LES SESSIONS DU DOSSIER OUVERT, D'UN CRAN PLUS PROFOND — l'indentation DIT
   à qui elles appartiennent. Le trait à gauche les rattache visuellement au
   dossier au-dessus, comme le fait déjà la profondeur des sessions de studio. */
.bar-sous-projet {
  display: flex; flex-direction: column;
  margin-left: calc(var(--espace-4) + 6px);
  padding-left: var(--espace-3);
  border-left: 1px solid var(--border);
}
.bar-feuille-rang > .bar-feuille { padding-right: calc(var(--espace-4) + 22px); }
.bar-feuille-marque { display: inline-flex; flex: none; color: var(--accent); }
.bar-feuille-marque svg { width: 12px; height: 12px; }
/* LE BADGE WORK. Il se lit AVANT le nom — c'est ce qu'on cherche en parcourant
   la liste — et il porte l'accent, comme la punaise : deux marques de la même
   famille, une seule couleur. Sa place est dans le balisage, juste après la
   puce : `order: -1` l'aurait fait passer devant la puce elle-même, deux
   glyphes collés avant le titre. */
.bar-feuille-work { display: inline-flex; flex: none; color: var(--accent); }
.bar-feuille-work svg { width: 12px; height: 12px; }
.bar-feuille-teinte {
  flex: none; width: 8px; height: 8px; border-radius: var(--radius-rond);
}
.bar-feuille-menu {
  position: absolute; right: var(--espace-3);
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: var(--radius-sm);
  color: var(--t-faint); cursor: pointer; opacity: 0;
  transition: all var(--duree-1) var(--courbe);
}
.bar-feuille-rang:hover .bar-feuille-menu,
.bar-feuille-menu.est-ouvert { opacity: 1; }
.bar-feuille-menu:hover { background: var(--bg-tertiary, var(--bg-secondary)); color: var(--t-primary); }
.bar-feuille-menu svg { width: 14px; height: 14px; }
@media (hover: none) { .bar-feuille-menu { opacity: .55; } }

/* ── LA BRANCHE : un studio, un projet ──────────────────────────────────── */
.bar-branche {
  display: flex; align-items: center; gap: var(--espace-3); width: 100%; text-align: left;
  padding: var(--espace-4) var(--espace-4); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-primary); cursor: pointer;
  font-size: var(--texte-5); font-weight: 500; min-width: 0;
  transition: all var(--duree-1) var(--courbe);
}
.bar-branche:hover { background: var(--bg-secondary); }
.bar-branche:hover .bar-branche-geste { opacity: 1; }
.bar-branche--profonde {
  padding-left: calc(var(--espace-4) + 16px);
  font-weight: 400; color: var(--t-secondary);
}
/* Le chevron TOURNE — il dit l'état, il ne change pas de dessin. Deux glyphes
   pour un même état, c'est deux occasions de diverger. */
.bar-branche-chevron {
  display: inline-flex; flex: none; color: var(--t-faint);
  transition: transform var(--duree-1) var(--courbe);
}
.bar-branche-chevron.est-ouvert { transform: rotate(90deg); }
.bar-branche-chevron svg { width: 15px; height: 15px; }
.bar-branche-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.bar-branche-ic svg { width: 18px; height: 18px; }
/* La teinte du studio est sa signature — la même que dans la galerie. */
.bar-branche-teinte { display: inline-flex; flex: none; }
.bar-branche-teinte svg { width: 19px; height: 19px; }
.bar-branche-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-branche-compte {
  flex: none; font-size: var(--texte-1); font-weight: 400; color: var(--t-faint);
  font-variant-numeric: tabular-nums;
}
.bar-branche-geste {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 20px; height: 20px; border-radius: var(--radius-xs);
  color: var(--t-faint); opacity: 0;
  transition: all var(--duree-1) var(--courbe);
}
.bar-branche-geste:hover { background: var(--bg-tertiary, var(--bg-secondary)); color: var(--t-primary); }
.bar-branche-geste svg { width: 13px; height: 13px; }

/* ── CRÉASPACE ────────────────────────────────────────────────────────────
   Sous la bascule et distinct d'elle : la bascule tient les deux MONDES,
   celui-ci ouvre les ESPACES. Le mettre en troisième onglet les aurait mis à
   égalité avec les deux mondes, ce qu'ils ne sont pas. */
.bar-espaces {
  display: flex; align-items: center; gap: var(--espace-3);
  flex: 1 1 auto; min-width: 0;
  margin: 0; padding: var(--espace-2) 0;
  border: 0; background: transparent; color: var(--accent); cursor: pointer;
  font-size: var(--texte-8); font-weight: 700; letter-spacing: .01em;
  transition: opacity var(--duree-1) var(--courbe);
}
.bar-espaces:hover { opacity: .78; }
/* LE LOGO DEVANT LE NOM, ET IL SE VOIT. Il a d'abord été un filigrane à 16 %
   derrière les lettres — « ce n'est pas le logo, il est en fond ; il faut
   vraiment qu'il apparaisse, bien ancré, et ensuite le nom ». Pleine opacité,
   à la hauteur des capitales, dans le flux : c'est le premier signe qu'on lit.
   `pointer-events: none` : il fait partie du bouton, il ne lui vole pas le
   clic. */
.bar-espaces-logo-cadre {
  display: inline-flex; flex: none; align-items: center; justify-content: center;
  width: 24px; height: 24px; pointer-events: none;
}
.bar-espaces-logo-cadre svg { width: 100%; height: 100%; }
.bar-espaces-nom { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-espaces-chevron { display: inline-flex; flex: none; color: var(--t-faint); transform: rotate(90deg); }
.bar-espaces-chevron svg { width: 13px; height: 13px; }

/* ── LES TROIS BOUTONS DU PIED, SUR LE WEB ────────────────────────────────
   « Comme les boutons ils sont installés devant, eux, ils viennent un peu plus
   en arrière. » Le compte est la chose qu'on vient chercher ici ; menu,
   recherche et journal sont des outils. Ils gardent leur cible tactile et
   perdent leur poids : pas de fond, une couleur effacée, et ils ne reprennent
   la couleur du texte qu'au survol. */
.crea-pied-boutons { opacity: .62; transition: opacity var(--duree-1) var(--courbe); }
.crea-pied-boutons:hover { opacity: 1; }
.crea-pied-boutons .crea-barre-groupe { background: transparent; border: 0; }

/* ── LE BLOC DU PIED : LA COULEUR DE LA BARRE, D'UN TON EN DESSOUS ─────────
   « Enlève cette couleur sombre sur le bloc d'en bas. Donne-lui la même
    couleur que la barre latérale du chat, mais une petite teinte un peu plus
    foncée pour faire la distinction quand même — et qu'il vienne s'y coller
    sans changer l'arrondi de la barre. »
   Le fond ne se choisit donc pas : c'est celui de la barre, un cran plus bas —
   `--bg-secondary` est exactement ce cran, et il suit les deux thèmes.
   ET IL ÉPOUSE L'ARRONDI plutôt que de le carrer : la barre a 12 px en bas, le
   bloc les reprend. Un rectangle plein dans un cadre arrondi déborde des deux
   coins, et c'est ce qui se lit comme « un autre bloc posé par-dessus ». */
.crea-bloc-compte {
  background: var(--bg-secondary);
  /* LE RAYON DE LA BARRE, MESURÉ SUR ELLE — 12 px, soit --radius. Prendre
     --radius-lg (16) aurait débordé de deux coins qu'on prétend épouser. */
  border-radius: 0 0 var(--radius) var(--radius);
}

/* LE MÊME BOUTON MENU, EN HAUT, QUAND LA BARRE EST FERMÉE — rendu à la racine
   (renderMenuFlottantWeb) pour qu'aucun en-tête ne puisse en garder un second. */
.crea-menu-flottant {
  position: fixed; top: var(--espace-4); left: var(--espace-4); z-index: 40;
  display: flex; align-items: center;
}
.crea-pied-boutons button { padding: var(--espace-3) var(--espace-4); }

/* ── LE PROJET REGARDÉ ────────────────────────────────────────────────────
   Un bandeau, pas un réglage caché : un filtre qu'on a oublié fait croire à
   une application vide. Il dit ce qu'on regarde et donne la sortie. */
.bar-projet {
  display: flex; align-items: center; gap: var(--espace-3);
  margin: 0 var(--espace-5) var(--espace-4); padding: var(--espace-3) var(--espace-4);
  border-radius: var(--radius); background: var(--accent-bg);
  font-size: var(--texte-2); color: var(--accent); min-width: 0;
}
.bar-projet-ic { display: inline-flex; flex: none; }
.bar-projet-ic svg { width: 15px; height: 15px; }
.bar-projet-nom { flex: 1; min-width: 0; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-projet-quitter {
  flex: none; border: 0; background: transparent; cursor: pointer;
  color: var(--accent); font-size: var(--texte-1); text-decoration: underline;
  text-underline-offset: 2px; padding: 0;
}

/* ── CE QUI EST DEHORS SE REPLIE ──────────────────────────────────────────
   « Ailleurs · 12 », fermé par défaut. Rien ne disparaît, et le filtre
   s'annonce par ce qu'il a mis de côté. */
.bar-ailleurs {
  display: flex; align-items: center; gap: var(--espace-3); width: 100%; text-align: left;
  padding: var(--espace-3) var(--espace-4); margin-top: var(--espace-2);
  border: 0; border-radius: var(--radius-sm); background: transparent;
  color: var(--t-faint); cursor: pointer; font-size: var(--texte-2);
  transition: all var(--duree-1) var(--courbe);
}
.bar-ailleurs:hover { background: var(--bg-secondary); color: var(--t-dim); }
.bar-ailleurs-compte { font-variant-numeric: tabular-nums; }
/* Sous un studio, il se met au cran de ses sessions : il leur appartient. */
.bar-ailleurs--n1 { padding-left: calc(var(--espace-4) + 17px); }

/* ── LE PIED : LE COMPTE, SUR LES DEUX FACES ──────────────────────────────
   Il vivait dans la barre de menu générale. Il n'appartient à aucun des deux
   mondes et on en a besoin dans les deux : il suit la barre, pas le monde. */
/* LE PIED NE DOUBLE PAS LE CADRE DU BLOC COMPTE.
   `renderUserProfile()` porte déjà son propre trait de séparation et ses
   marges. En rajouter ici faisait deux traits et deux fois la hauteur — « tu
   l'avais fait plus petit, tu l'as agrandi pour rien ». Le pied ne fait plus
   que le tenir en bas ; le repli simple, lui, a besoin d'un cadre. */
.bar-pied { flex: none; }
.bar-pied > .bar-compte { margin: var(--espace-3) var(--espace-4); width: auto; }
.bar-pied:has(> .bar-compte) { border-top: 1px solid var(--border); }
.bar-compte {
  display: flex; align-items: center; gap: var(--espace-3); width: 100%;
  padding: var(--espace-3) var(--espace-3); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-primary); cursor: pointer;
  font-size: var(--texte-2); min-width: 0; text-align: left;
  transition: all var(--duree-1) var(--courbe);
}
.bar-compte:hover { background: var(--bg-secondary); }
.bar-compte-pastille {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 26px; height: 26px; border-radius: var(--radius-rond);
  background: var(--accent); color: #fff; font-size: var(--texte-1); font-weight: 600;
}
.bar-compte-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-compte-plan { color: var(--t-faint); }
.bar-compte-chevron { display: inline-flex; flex: none; color: var(--t-faint); transform: rotate(90deg); }
.bar-compte-chevron svg { width: 13px; height: 13px; }

/* ══════════════════════════════════════════════════════════════════════════
   L'ESPACE PROJET — leur accueil, et la création en deux temps.
   Voir src/crea-espace-projets.js. Même vocabulaire que la page des fichiers
   (`fich-`) et que les barres (`bar-`) : deux surfaces qui se ressemblent
   doivent se manœuvrer pareil.
   ══════════════════════════════════════════════════════════════════════════ */
.proj-espace {
  display: flex; flex-direction: column; flex: 1; min-width: 0; min-height: 0;
  background: var(--bg-primary);
}
.proj-tete {
  display: flex; align-items: center; gap: var(--espace-5); flex-wrap: wrap;
  flex: none; padding: var(--espace-8) var(--espace-9) var(--espace-5);
}
.proj-titre {
  flex: 1; min-width: 0; margin: 0;
  font-size: var(--texte-8); font-weight: 600; letter-spacing: -.01em;
  color: var(--t-primary);
}
.proj-tete-gestes { display: flex; align-items: center; gap: var(--espace-3); flex-wrap: wrap; }
.proj-geste {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 34px; height: 34px; padding: 0;
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  background: transparent; color: var(--t-dim); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.proj-geste:hover { background: var(--bg-secondary); color: var(--t-primary); }
.proj-geste.est-actif { background: var(--accent-bg, var(--bg-secondary)); color: var(--accent); border-color: var(--accent); }
.proj-geste svg { width: 16px; height: 16px; }
/* `.proj-tri` EST PARTI avec le bouton à deux ordres. Le tri et les filtres des
   dossiers portent maintenant le dessin commun `.fl-*`, celui de la page des
   sessions : « il faut ajouter à ce système notre système de tri de fichiers,
   et aussi le mettre pour dossier ». */

/* L'EN-TÊTE D'UN GROUPE DE PROJETS — même dessin que celui des sessions, pour
   que « Grouper par » se lise pareil d'un écran à l'autre. */
.proj-groupe {
  display: flex; align-items: center; gap: var(--espace-3);
  margin: var(--espace-6) 0 var(--espace-4);
  font-size: var(--texte-1); font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--t-faint);
}
.proj-groupe:first-child { margin-top: 0; }
.proj-groupe-nom { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proj-groupe-compte {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  min-width: 20px; height: 18px; padding: 0 var(--espace-2);
  border-radius: var(--radius-rond); background: var(--bg-secondary);
  color: var(--t-dim); font-size: var(--texte-1); font-weight: 700; letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
/* Les deux formes de la liste, dans une gouttière — même objet que la bascule
   des mondes, donc même dessin : on ne réinvente pas un segment de contrôle. */
.proj-vues {
  display: inline-flex; gap: 2px; padding: 2px;
  border-radius: var(--radius-rond); background: var(--bg-secondary);
}
.proj-vue {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; border: 0;
  border-radius: var(--radius-rond); background: transparent;
  color: var(--t-faint); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.proj-vue:hover { color: var(--t-primary); }
.proj-vue.est-actif { background: var(--bg-primary); color: var(--t-primary); box-shadow: var(--ombre-1); }
.proj-vue svg { width: 15px; height: 15px; }
.proj-neuf {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  padding: 0 var(--espace-6); min-height: 34px;
  border: 0; border-radius: var(--radius-rond);
  background: var(--t-primary); color: var(--bg-primary); cursor: pointer;
  font-size: var(--texte-2); font-weight: 600; font-family: inherit;
  transition: all var(--duree-1) var(--courbe);
}
.proj-neuf:hover { opacity: .88; }
.proj-neuf svg { width: 15px; height: 15px; }

.proj-cherche {
  display: flex; align-items: center; gap: var(--espace-3);
  margin: 0 var(--espace-9) var(--espace-5); padding: 0 var(--espace-5);
  min-height: 40px;
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  background: var(--bg-secondary);
  transition: all var(--duree-1) var(--courbe);
}
.proj-cherche:focus-within { border-color: var(--accent); background: var(--bg-primary); }
.proj-cherche-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.proj-cherche-ic svg { width: 16px; height: 16px; }
.proj-cherche-champ {
  flex: 1; min-width: 0; border: 0; outline: none; background: transparent;
  color: var(--t-primary); font-size: var(--texte-3); font-family: inherit;
}
.proj-cherche-vider {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 22px; height: 22px; padding: 0; border: 0;
  border-radius: var(--radius-rond); background: transparent;
  color: var(--t-faint); cursor: pointer;
}
.proj-cherche-vider:hover { background: var(--bg-tertiary, var(--bg-secondary)); color: var(--t-primary); }
.proj-cherche-vider svg { width: 12px; height: 12px; }

.proj-corps { flex: 1; min-height: 0; overflow-y: auto; padding: 0 var(--espace-9) var(--espace-9); }

/* LE GLYPHE PORTE LA COULEUR DE SON STYLE, sur un fond de la même teinte very
   diluée : c'est ce qui rend seize projets distinguables d'un coup d'œil sans
   lire un seul nom. */
.proj-ic {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 40px; height: 40px;
  border-radius: var(--radius); color: var(--t-dim);
  background: var(--bg-secondary);
}
.proj-ic svg { width: 21px; height: 21px; }
.proj-ic--petit { width: 30px; height: 30px; border-radius: var(--radius-sm); }
.proj-ic--petit svg { width: 17px; height: 17px; }

/* ── LA GRILLE : on la parcourt pour CHOISIR ─────────────────────────────── */
/* LES CARTES ONT UNE LARGEUR, PAS UNE PART. Avec `1fr`, quatre projets sur un
   écran large donnaient quatre cartes de trois cent cinquante pixels pour deux
   lignes de texte — la grille s'étirait au lieu de se remplir. Un plafond, et
   elles se rangent à gauche à taille constante quel que soit l'écran. */
.proj-grille {
  display: grid; gap: var(--espace-5); justify-content: start;
  grid-template-columns: repeat(auto-fill, minmax(240px, 300px));
}
.proj-carte {
  display: flex; flex-direction: column; gap: var(--espace-3);
  padding: var(--espace-6); text-align: left;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--bg-primary); cursor: pointer; min-width: 0;
  transition: all var(--duree-1) var(--courbe);
}
.proj-carte:hover { background: var(--bg-secondary); border-color: var(--t-faint); }
.proj-carte-tete { display: flex; align-items: center; gap: var(--espace-3); }
.proj-etiquette {
  margin-left: auto; padding: 2px var(--espace-4);
  border-radius: var(--radius-rond); background: var(--bg-secondary);
  color: var(--t-faint); font-size: var(--texte-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 55%;
}
.proj-carte:hover .proj-etiquette { background: var(--bg-primary); }
.proj-carte-nom {
  font-size: var(--texte-4); font-weight: 600; color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Trois lignes puis on coupe : une description longue ferait des cartes de
   hauteurs différentes, et une grille cesse d'être une grille. */
.proj-carte-desc {
  font-size: var(--texte-2); color: var(--t-dim); line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; min-height: calc(1.5em * 3);
}
.proj-carte-pied { display: flex; align-items: center; gap: var(--espace-5); flex-wrap: wrap; margin-top: auto; }

/* ── LA LISTE : on la parcourt pour RETROUVER ────────────────────────────── */
/* LA LISTE A UNE MESURE. Étirée sur toute la largeur d'un grand écran, le nom
   est à gauche et ses compteurs à mille pixels de là : l'œil traverse l'écran
   pour relier deux informations qui parlent du même projet. */
.proj-liste { display: flex; flex-direction: column; max-width: 960px; }
.proj-rangee {
  display: flex; align-items: center; gap: var(--espace-5); width: 100%;
  padding: var(--espace-4) var(--espace-5); text-align: left;
  border: 0; border-bottom: 1px solid var(--border); border-radius: 0;
  background: transparent; cursor: pointer; min-width: 0;
  transition: all var(--duree-1) var(--courbe);
}
.proj-rangee:hover { background: var(--bg-secondary); }
.proj-rangee-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.proj-rangee-nom {
  font-size: var(--texte-3); font-weight: 500; color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.proj-rangee-sous {
  font-size: var(--texte-2); color: var(--t-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.proj-rangee-mesures { display: flex; align-items: center; gap: var(--espace-5); flex: none; }

.proj-mesure {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  font-size: var(--texte-1); color: var(--t-faint);
  font-variant-numeric: tabular-nums;
}
.proj-mesure svg { width: 13px; height: 13px; }
.proj-mesure--date { white-space: nowrap; }

.proj-vide {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--espace-4); padding: var(--espace-9) var(--espace-6); text-align: center;
}
.proj-vide-ic { display: inline-flex; color: var(--t-faint); opacity: .4; }
.proj-vide-ic svg { width: 44px; height: 44px; }
.proj-vide-titre { margin: 0; font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); }
.proj-vide-sous { margin: 0; max-width: 42ch; font-size: var(--texte-2); color: var(--t-dim); line-height: 1.6; }
.proj-vide-geste {
  border: 0; background: transparent; color: var(--accent); cursor: pointer;
  font-size: var(--texte-2); font-family: inherit;
}

/* ── LA CRÉATION, EN DEUX TEMPS ──────────────────────────────────────────── */
.proj-voile {
  position: fixed; inset: 0; z-index: 80;
  display: flex; align-items: center; justify-content: center;
  padding: var(--espace-6); background: rgba(0, 0, 0, .5);
}
.proj-modale {
  display: flex; flex-direction: column;
  width: 100%; max-width: 540px; max-height: 86vh;
  border: 1px solid var(--border); border-radius: var(--radius-xl);
  background: var(--bg-primary); box-shadow: var(--ombre-3, var(--ombre-1));
  overflow: hidden;
}
.proj-modale-tete {
  display: flex; align-items: flex-start; gap: var(--espace-5);
  flex: none; padding: var(--espace-7) var(--espace-7) var(--espace-5);
}
.proj-modale-titres { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--espace-2); }
.proj-modale-titre { margin: 0; font-size: var(--texte-5); font-weight: 600; color: var(--t-primary); }
.proj-modale-sous { margin: 0; font-size: var(--texte-2); color: var(--t-dim); line-height: 1.5; }
.proj-modale-corps {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 0 var(--espace-7) var(--espace-6);
  display: flex; flex-direction: column; gap: var(--espace-4);
}
.proj-modale-pied {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--espace-4);
  flex: none; padding: var(--espace-5) var(--espace-7) var(--espace-7);
}
.proj-btn {
  padding: 0 var(--espace-6); min-height: 36px;
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  background: transparent; color: var(--t-primary); cursor: pointer;
  font-size: var(--texte-2); font-weight: 500; font-family: inherit;
  transition: all var(--duree-1) var(--courbe);
}
.proj-btn:hover { background: var(--bg-secondary); }
.proj-btn--fort { border-color: transparent; background: var(--t-primary); color: var(--bg-primary); }
.proj-btn--fort:hover { opacity: .88; background: var(--t-primary); }
/* UN BOUTON QUI REFUSE DOIT LE DIRE AVANT LE CLIC. Sans nom, « Créer » ne peut
   rien créer : il l'annonce en s'éteignant, plutôt qu'en ne répondant pas. */
.proj-btn[disabled] { opacity: .4; cursor: not-allowed; }
.proj-btn[disabled]:hover { opacity: .4; }

.proj-styles { display: grid; gap: var(--espace-3); grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.proj-style {
  display: flex; align-items: center; gap: var(--espace-4); width: 100%;
  padding: var(--espace-4); text-align: left;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: transparent; cursor: pointer; min-width: 0;
  transition: all var(--duree-1) var(--courbe);
}
.proj-style:hover { background: var(--bg-secondary); border-color: var(--t-faint); }
.proj-style--libre { border-style: dashed; }
.proj-style-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.proj-style-nom {
  font-size: var(--texte-2); font-weight: 600; color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.proj-style-sous {
  font-size: var(--texte-1); color: var(--t-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.proj-choisi {
  display: flex; align-items: center; gap: var(--espace-4);
  padding: var(--espace-4); border-radius: var(--radius);
  background: var(--bg-secondary);
}
.proj-choisi-nom { flex: 1; min-width: 0; font-size: var(--texte-2); font-weight: 600; color: var(--t-primary); }
.proj-choisi-changer {
  border: 0; background: transparent; color: var(--accent); cursor: pointer;
  font-size: var(--texte-2); font-family: inherit; padding: 0;
}
.proj-label { font-size: var(--texte-2); font-weight: 600; color: var(--t-primary); }
.proj-champ, .proj-zone {
  width: 100%; padding: var(--espace-4) var(--espace-5);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-input, var(--bg-secondary)); color: var(--t-primary);
  font-size: var(--texte-3); font-family: inherit; outline: none;
  transition: all var(--duree-1) var(--courbe);
}
.proj-champ:focus, .proj-zone:focus { border-color: var(--accent); }
.proj-zone { resize: vertical; min-height: 88px; line-height: 1.55; }
.proj-note { margin: 0; font-size: var(--texte-1); color: var(--t-faint); line-height: 1.5; }

@media (max-width: 720px) {
  .proj-tete { padding: var(--espace-6) var(--espace-5) var(--espace-4); }
  .proj-titre { font-size: var(--texte-6); }
  .proj-corps { padding: 0 var(--espace-5) var(--espace-7); }
  .proj-cherche { margin-inline: var(--espace-5); }
  .proj-grille { grid-template-columns: minmax(0, 1fr); }
}

/* ══════════════════════════════════════════════════════════════════════════
   LA PAGE D'UN PROJET OUVERT — composeur, onglets, panneau.
   Voir src/crea-espace-projets.js. Les trois structures des captures, réunies.
   ══════════════════════════════════════════════════════════════════════════ */
.projo { display: flex; flex-direction: column; flex: 1; min-width: 0; min-height: 0; background: var(--bg-primary); }
.projo-fil {
  display: flex; align-items: center; gap: var(--espace-3); flex: none;
  padding: var(--espace-5) var(--espace-8) 0; font-size: var(--texte-2);
}
.projo-fil-lien { border: 0; background: transparent; color: var(--t-dim); cursor: pointer; font-size: inherit; font-family: inherit; padding: 0; }
.projo-fil-lien:hover { color: var(--t-primary); text-decoration: underline; }
.projo-fil-sep { color: var(--t-faint); }
.projo-fil-ici { color: var(--t-primary); font-weight: 500; }
/* LA TÊTE PORTE L'ANCRAGE DU MENU « ⋯ » — voir `.proj-menu`, qui se pose sous
   elle. Sans `position: relative` ici, le menu remonterait chercher le premier
   ancêtre positionné et retomberait n'importe où : c'est exactement ce qui
   arrivait quand il était ancré à `top: 92px`, en plein sur le panneau de
   droite. Vu à l'écran. */
.projo-tete {
  position: relative;
  display: flex; align-items: flex-start; gap: var(--espace-5); flex: none;
  padding: var(--espace-5) var(--espace-8) var(--espace-6);
}
.projo-tete-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--espace-2); }
.projo-titre { margin: 0; font-size: var(--texte-7); font-weight: 600; letter-spacing: -.01em; color: var(--t-primary); }
.projo-sous { margin: 0; font-size: var(--texte-2); color: var(--t-dim); }
/* LE BLOC D'ORIGINE — la page ouvre une réalité différente selon le type de
   source (github/local/connecteur). Une puce sobre sous le titre : le type à
   gauche, la référence (owner/repo, dossier, id) en évidence. Un projet natif
   n'en a pas — la tête reste sobre sur le cas le plus courant. */
.projo-origine {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  align-self: flex-start; margin-top: var(--espace-1);
  padding: 3px var(--espace-3) 3px var(--espace-2);
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  background: var(--bg-input); max-width: 100%;
}
.projo-origine-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.projo-origine-ic svg { width: 14px; height: 14px; }
.projo-origine-txt { display: inline-flex; align-items: baseline; gap: var(--espace-2); min-width: 0; }
.projo-origine-type { font-size: var(--texte-1); color: var(--t-dim); white-space: nowrap; }
.projo-origine-ref {
  font-size: var(--texte-2); color: var(--t-secondary); font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.projo-origine--github { border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.projo-geste {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--radius-rond);
  background: transparent; color: var(--t-faint); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.projo-geste:hover { background: var(--bg-secondary); color: var(--t-primary); }
.projo-geste.est-actif { color: var(--accent); }
.projo-geste svg { width: 16px; height: 16px; }

/* DEUX COLONNES : ce qu'on FAIT à gauche, ce que le projet SAIT à droite. */
/* LES DEUX COLONNES VONT JUSQU'EN BAS. Avec `flex-start`, la colonne gauche
   s'arrêtait à la hauteur de sa liste, et la barre de questions se collait
   dessous au lieu de descendre au bas de l'écran. */
.projo-corps {
  display: flex; align-items: stretch; gap: var(--espace-7);
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 0 var(--espace-8) var(--espace-8);
}
.projo-gauche { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--espace-5); position: relative; }
/* CE QUI EST ÉCRIT POUSSE, CE QU'ON VA ÉCRIRE RESTE EN BAS. */
.projo-gauche > .projo-onglet-corps { flex: 1; min-height: 0; }
.projo-gauche > .projo-zone-compose { margin-top: auto; }
/* LE FIL DE LA SESSION OUVERTE DANS LE PROJET.
   Il porte `#messages-container` — le même identifiant que le fil du chat, pour
   hériter de toute la mécanique de défilement. Ce qu'il faut ajouter ici, c'est
   seulement sa PLACE : il prend la hauteur qui reste et défile à l'intérieur,
   sinon c'est la page entière qui s'allonge et la barre de saisie descend hors
   de l'écran à chaque message. */
.projo-gauche > .projo-fil-messages { flex: 1; min-height: 0; }

/* ── LE COMPOSEUR ────────────────────────────────────────────────────────── */






/* ── LES TROIS PORTES DES SOURCES ────────────────────────────────────────── */
/* LE MENU S'OUVRE SOUS LE BOUTON QUI L'APPELLE, pas à une hauteur devinée.
   Il était ancré à `top: 96px` — un nombre écrit à l'œil, qui tombait au milieu
   du composeur et recouvrait la rangée d'onglets. Vu à l'écran. La zone du
   composeur porte l'ancrage ; le menu se pose sous elle, quelle que soit sa
   hauteur. */
.projo-zone-compose { position: relative; }
/* La barre de saisie est celle de Work (`renderUniversalInputBar`) : son
   habillage lui appartient, ce module ne fait que lui donner sa place. */
/* LE MENU S'OUVRE AU-DESSUS, puisque la barre de questions est en bas. */
.projo-sources-menu {
  position: absolute; bottom: calc(100% + var(--espace-3)); left: 0; z-index: 30; min-width: 300px;
  display: flex; flex-direction: column; padding: var(--espace-2);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-input, var(--bg-primary)); box-shadow: var(--ombre-2);
}
.projo-source-porte {
  display: flex; align-items: center; gap: var(--espace-4); width: 100%; text-align: left;
  padding: var(--espace-4); border: 0; border-radius: var(--radius-sm);
  background: transparent; cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.projo-source-porte:hover { background: var(--bg-secondary); }
/* Une porte qui annonce ce qu'elle ne fait pas encore le dit par son ton. */
.projo-source-porte.est-sourde { opacity: .6; }
.projo-source-ic { display: inline-flex; flex: none; color: var(--t-dim); }
.projo-source-ic svg { width: 17px; height: 17px; }
.projo-source-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.projo-source-nom { font-size: var(--texte-2); font-weight: 500; color: var(--t-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.projo-source-sous { font-size: var(--texte-1); color: var(--t-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── LES ONGLETS ─────────────────────────────────────────────────────────── */
.projo-onglets { display: flex; align-items: center; gap: var(--espace-2); border-bottom: 1px solid var(--border); }
.projo-onglet {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  padding: var(--espace-4) var(--espace-5); border: 0; border-bottom: 2px solid transparent;
  background: transparent; color: var(--t-dim); cursor: pointer;
  font-size: var(--texte-2); font-weight: 500; font-family: inherit;
  transition: all var(--duree-1) var(--courbe);
}
.projo-onglet:hover { color: var(--t-primary); }
.projo-onglet.est-actif { color: var(--t-primary); border-bottom-color: var(--t-primary); }
.projo-onglet-ic { display: inline-flex; }
.projo-onglet-ic svg { width: 15px; height: 15px; }
.projo-onglet-compte {
  font-size: var(--texte-1); font-variant-numeric: tabular-nums;
  padding: 0 var(--espace-3); border-radius: var(--radius-rond);
  background: var(--bg-secondary); color: var(--t-faint);
}
/* « Nouveau chat » se tient à l'autre bout de la rangée d'onglets : c'est un
   geste, pas une quatrième destination — il ne porte donc pas le soulignement
   des onglets. */
.projo-onglets-espace { flex: 1; }
.projo-onglet-geste {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  padding: var(--espace-3) var(--espace-4); margin-bottom: var(--espace-2);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: transparent; color: var(--t-secondary); cursor: pointer;
  font-size: var(--texte-1); font-weight: 500; font-family: inherit;
  transition: all var(--duree-1) var(--courbe);
}
.projo-onglet-geste:hover { background: var(--bg-secondary); color: var(--t-primary); }
.projo-onglet-corps { display: flex; flex-direction: column; gap: var(--espace-3); }
/* ── L'ONGLET « STUDIOS » D'UN PROJET ─────────────────────────────────────
 *
 * « Le projet doit refléter toute une réalité. » Ce que les studios ont fait
 * dans ce projet, groupé par studio : un bandeau de tête qui compte, puis une
 * branche par studio avec ses sessions et ce qu'elles ont produit.
 *
 * AUCUNE COULEUR NEUVE, aucun rayon neuf : les deux cliquets du dépôt
 * (`matiere-visuelle` sur les z-index, `forme-echelle` sur les rayons) comptent
 * les valeurs DISTINCTES. Tout ici reprend des jetons déjà posés. */
.projo-chaine { padding: var(--espace-4) var(--espace-6); }
.projo-chaine-titre { font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); }
.projo-chaine-sous { margin-top: var(--espace-2); font-size: var(--texte-2); color: var(--t-dim); }
.projo-studio { padding: var(--espace-4) var(--espace-6); border-top: 1px solid var(--border); }
.projo-studio-nom {
  font-size: var(--texte-1); font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--t-faint); margin-bottom: var(--espace-2);
}
.projo-sess {
  display: flex; align-items: center; gap: var(--espace-4); width: 100%; text-align: left;
  padding: var(--espace-3) var(--espace-4); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-primary); cursor: pointer;
  font-size: var(--texte-3); font-family: inherit;
}
.projo-sess:hover { background: var(--bg-secondary); }
/* UNE SESSION ARCHIVÉE RESTE LÀ, EN RETRAIT. Ce n'est pas la barre : ici on
   demande ce que le projet CONTIENT, et une réalisation rangée en fait encore
   partie — la taire ferait disparaître du travail livré. */
.projo-sess.est-archivee { color: var(--t-faint); }
.projo-sess-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.projo-sess-br {
  display: inline-flex; align-items: center; gap: var(--espace-2); flex: none;
  color: var(--t-faint); font-size: var(--texte-1);
}
.projo-sess-br svg { width: 12px; height: 12px; }
.projo-studio-real { margin-top: var(--espace-2); font-size: var(--texte-2); color: var(--t-dim); }
.projo-vide { margin: 0; padding: var(--espace-8) 0; text-align: center; font-size: var(--texte-2); color: var(--t-faint); line-height: 1.6; }

.projo-chats { display: flex; flex-direction: column; }
.projo-chat {
  display: flex; align-items: center; gap: var(--espace-4); width: 100%; text-align: left;
  padding: var(--espace-4) var(--espace-3); border: 0; border-bottom: 1px solid var(--border);
  background: transparent; cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.projo-chat:hover { background: var(--bg-secondary); }
.projo-chat-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.projo-chat-ic svg { width: 15px; height: 15px; }
.projo-chat-nom { flex: 1; min-width: 0; font-size: var(--texte-3); color: var(--t-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.projo-chat-date { flex: none; font-size: var(--texte-1); color: var(--t-faint); }

.projo-sources { display: flex; flex-direction: column; }
.projo-source {
  display: flex; align-items: center; gap: var(--espace-4);
  padding: var(--espace-4) var(--espace-3); border-bottom: 1px solid var(--border);
}
.projo-depot {
  display: flex; flex-direction: column; align-items: center; gap: var(--espace-4);
  padding: var(--espace-9) var(--espace-6); text-align: center;
  border: 1px dashed var(--border); border-radius: var(--radius-lg);
}
.projo-depot-titre { margin: 0; font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); }
.projo-depot-sous { margin: 0; max-width: 46ch; font-size: var(--texte-2); color: var(--t-dim); line-height: 1.6; }
.projo-btn-fort {
  padding: 0 var(--espace-6); min-height: 34px; border: 0; border-radius: var(--radius-rond);
  background: var(--t-primary); color: var(--bg-primary); cursor: pointer;
  font-size: var(--texte-2); font-weight: 600; font-family: inherit;
}
.projo-btn-fort:hover { opacity: .88; }

/* ── LE PANNEAU : ce que le projet SAIT ──────────────────────────────────── */
.projo-panneau {
  flex: none; width: 320px; align-self: flex-start; display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden;
}
.projo-bloc { padding: var(--espace-5) var(--espace-6); border-bottom: 1px solid var(--border); }
.projo-bloc:last-child { border-bottom: 0; }
.projo-bloc-tete { display: flex; align-items: center; gap: var(--espace-3); }
.projo-bloc-titre { flex: 1; min-width: 0; margin: 0; font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); }
.projo-bloc-note {
  flex: none; padding: 2px var(--espace-4); border-radius: var(--radius-rond);
  background: var(--bg-secondary); color: var(--t-faint); font-size: var(--texte-1);
}
.projo-bloc-plus {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 22px; height: 22px; padding: 0; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-faint); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.projo-bloc-plus:hover { background: var(--bg-secondary); color: var(--t-primary); }
.projo-bloc-plus svg { width: 14px; height: 14px; }
.projo-bloc-vide { margin: var(--espace-3) 0 0; font-size: var(--texte-2); color: var(--t-faint); line-height: 1.5; }
.projo-bloc-valeur { margin: var(--espace-3) 0 0; font-size: var(--texte-2); color: var(--t-secondary); line-height: 1.5; white-space: pre-wrap; }
.projo-bloc-champ {
  width: 100%; margin-top: var(--espace-3); padding: var(--espace-4);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-input, var(--bg-secondary)); color: var(--t-primary);
  font-size: var(--texte-2); font-family: inherit; line-height: 1.5; outline: none; resize: vertical;
}
.projo-bloc-champ:focus { border-color: var(--accent); }
.projo-bloc-ok {
  margin-top: var(--espace-3); padding: 0 var(--espace-5); min-height: 28px;
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  background: transparent; color: var(--t-primary); cursor: pointer;
  font-size: var(--texte-1); font-family: inherit;
}
.projo-bloc-ok:hover { background: var(--bg-secondary); }

/* LE PANNEAU PASSE SOUS LE TRAVAIL quand la place manque : à 1020 px, deux
   colonnes donnent une conversation de 380 px — on lit moins bien qu'on ne
   range. */
@media (max-width: 1020px) {
  .projo-corps { flex-direction: column; }
  .projo-panneau { width: 100%; }
}
@media (max-width: 720px) {
  .projo-fil, .projo-tete { padding-inline: var(--espace-5); }
  .projo-corps { padding-inline: var(--espace-5); }
  .projo-titre { font-size: var(--texte-6); }
}

/* ── LE PANNEAU : QUATRE NATURES DE BLOC ────────────────────────────────── */
/* Contexte ne se TAPE pas, il se REMPLIT : sa forme au repos est une zone de
   dépôt avec des feuilles dessinées, comme sur la capture. */
.projo-depot-mini {
  display: flex; flex-direction: column; align-items: center; gap: var(--espace-3);
  width: 100%; margin-top: var(--espace-3); padding: var(--espace-6) var(--espace-4);
  border: 1px dashed var(--border); border-radius: var(--radius);
  background: var(--bg-secondary); cursor: pointer; text-align: center;
  transition: all var(--duree-1) var(--courbe);
}
.projo-depot-mini:hover { border-color: var(--t-faint); }
.projo-depot-feuilles { display: inline-flex; color: var(--t-faint); }
.projo-depot-feuilles svg { width: 54px; height: 40px; }
.projo-depot-mot { font-size: var(--texte-2); color: var(--t-faint); line-height: 1.5; }
.projo-pieces { display: flex; flex-wrap: wrap; gap: var(--espace-2); margin-top: var(--espace-3); }
.projo-piece {
  display: inline-flex; align-items: center; gap: var(--espace-2); max-width: 100%;
  padding: var(--espace-2) var(--espace-4); border: 1px solid var(--border);
  border-radius: var(--radius-rond); background: transparent;
  font-size: var(--texte-1); color: var(--t-secondary); font-family: inherit;
}
.projo-piece-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.projo-piece-ic svg { width: 12px; height: 12px; }
.projo-piece-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.projo-piece--plus { cursor: pointer; color: var(--accent); border-color: var(--accent); }
.projo-items { list-style: none; margin: var(--espace-3) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--espace-2); }
.projo-item { display: flex; align-items: center; gap: var(--espace-3); font-size: var(--texte-2); color: var(--t-secondary); }
.projo-item.est-fait .projo-item-nom { text-decoration: line-through; color: var(--t-faint); }
.projo-item-case {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 15px; height: 15px; border: 1px solid var(--border);
  border-radius: var(--radius-xs); color: var(--accent);
}
.projo-item-case svg { width: 11px; height: 11px; }
.projo-item-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── LES PORTES DU PROJET — modales des « + » ─────────────────────────────
   Voir src/crea-espace-projets.js. Elles partagent le cadre de la création de
   projet (`.proj-modale`) : quatre cadres séparés, c'est quatre boutons
   « Annuler » à tenir en phase. */
.proj-modale--large { max-width: 680px; }
.proj-requis { color: var(--danger); margin-left: 3px; }
.proj-lien {
  border: 0; padding: 0; background: transparent; cursor: pointer;
  color: var(--accent); font-size: inherit; font-family: inherit; text-decoration: underline;
}
.proj-zone--haute { min-height: 220px; }
.proj-ligne { display: flex; align-items: center; gap: var(--espace-5); }
.proj-label--ligne { flex: none; width: 118px; margin: 0; }
.proj-select {
  flex: 1; min-width: 0; padding: var(--espace-3) var(--espace-4);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-input, var(--bg-secondary)); color: var(--t-primary);
  font-size: var(--texte-2); font-family: inherit; cursor: pointer;
}
.proj-erreur { margin: 0; font-size: var(--texte-2); color: var(--danger); }
/* La zone de dépôt de la modale — celle de la capture : un grand cadre en
   pointillés, l'icône au milieu, et les portes en tuiles dessous. */
.proj-depot-zone {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--espace-4); min-height: 168px; padding: var(--espace-7);
  border: 1px dashed var(--border); border-radius: var(--radius);
}
.proj-depot-ic { display: inline-flex; color: var(--t-faint); }
.proj-depot-ic svg { width: 34px; height: 34px; }
.proj-depot-zone .proj-depot-mot { font-size: var(--texte-2); color: var(--t-dim); }
.proj-tuiles { display: grid; gap: var(--espace-3); grid-template-columns: repeat(auto-fit, minmax(122px, 1fr)); }
.proj-tuile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--espace-3); padding: var(--espace-5) var(--espace-3); min-height: 84px;
  border: 0; border-radius: var(--radius); background: var(--bg-secondary);
  color: var(--t-primary); cursor: pointer; text-align: center;
  font-size: var(--texte-1); font-family: inherit;
  transition: all var(--duree-1) var(--courbe);
}
.proj-tuile:hover { background: var(--bg-tertiary, var(--border)); }
/* Une porte qui n'existe pas encore reste VISIBLE, éteinte : on comprend
   qu'elle viendra. L'absence, elle, ne dit rien. */
.proj-tuile.est-sourde { opacity: .45; cursor: not-allowed; }
.proj-tuile.est-sourde:hover { background: var(--bg-secondary); }
.proj-tuile-ic { display: inline-flex; color: var(--t-dim); }
.proj-tuile-ic svg { width: 18px; height: 18px; }
.proj-tuile-nom { line-height: 1.35; }

/* ── LE MENU « ⋯ » DU PROJET ──────────────────────────────────────────── */
/* DEUX ÉTAGES QUI EXISTAIENT DÉJÀ, PAS DEUX NOMBRES DE PLUS. J'avais écrit 78
   et 79 — deux valeurs neuves choisies pour se glisser sous le voile des
   modales (80), c'est-à-dire exactement la surenchère que le cliquet des
   élévations compte. 50 et 60 sont déjà des étages de ce fichier, ils passent
   au-dessus de tout ce que la page du projet dessine (le menu des sources est
   à 30) et restent sous les modales. */
.proj-menu-voile { position: fixed; inset: 0; z-index: 50; background: transparent; }
.proj-menu {
  position: absolute; top: calc(100% - var(--espace-4)); right: var(--espace-8); z-index: 60; min-width: 212px;
  display: flex; flex-direction: column; padding: var(--espace-2);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-input, var(--bg-primary)); box-shadow: var(--ombre-2);
}
.proj-menu-entree {
  display: flex; align-items: center; gap: var(--espace-4); width: 100%; text-align: left;
  padding: var(--espace-3) var(--espace-4); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-primary); cursor: pointer;
  font-size: var(--texte-2); font-family: inherit;
  transition: all var(--duree-1) var(--courbe);
}
.proj-menu-entree:hover { background: var(--bg-secondary); }
.proj-menu-entree.est-danger { color: var(--danger); }
.proj-menu-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.proj-menu-entree.est-danger .proj-menu-ic { color: var(--danger); }
.proj-menu-ic svg { width: 15px; height: 15px; }

/* ── LES TÂCHES REPÉRÉES, ET LE RYTHME ────────────────────────────────── */
.projo-items--propose { margin-bottom: var(--espace-3); }
.projo-item--propose {
  gap: var(--espace-3); padding: var(--espace-2) var(--espace-3);
  border: 1px dashed var(--border); border-radius: var(--radius-sm);
}
.projo-item-oui, .projo-item-non {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 20px; height: 20px; padding: 0; border: 0; border-radius: var(--radius-xs);
  background: transparent; cursor: pointer;
}
.projo-item-oui { color: var(--success, var(--accent)); }
.projo-item-non { color: var(--t-faint); }
.projo-item-oui:hover, .projo-item-non:hover { background: var(--bg-secondary); }
.projo-item-oui svg, .projo-item-non svg { width: 13px; height: 13px; }
.projo-item-case--inerte { border-color: transparent; color: var(--t-faint); }
.projo-item-quand { flex: none; font-size: var(--texte-1); color: var(--t-faint); }
.projo-bloc-note-fine { margin: var(--espace-3) 0 0; font-size: var(--texte-1); color: var(--t-faint); line-height: 1.5; }

/* ══════════════════════════════════════════════════════════════════════════
 * LE FILTRE PARTAGÉ — sessions ET dossiers (src/crea-filtres.js)
 *
 * Une pilule, un panneau, une rangée par réglage, et le sous-menu qui se
 * déplie SOUS sa rangée. Il se déplie sous, et non à côté : un sous-menu posé
 * à droite sort de l'écran dès que la pilule est près du bord droit — et elle
 * l'est, la tête d'une page range ses gestes à droite.
 * ══════════════════════════════════════════════════════════════════════════ */
.fl { position: relative; display: inline-flex; }
/* ── LE PETIT BOUTON, celui de sa capture ────────────────────────────────
   Même gabarit que les autres gestes d'un titre de section (`.bar-section-geste`)
   et d'une branche (`.bar-branche-geste`) : il se range avec eux, il ne se
   remarque pas plus qu'eux, et il n'ajoute aucune ligne. */
.fl-ic {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  /* 24 et non 22 : le compteur juste en dessous tient dans le coin sans
     déborder du bouton, et la barre latérale rognerait ce qui dépasse. */
  width: 24px; height: 24px; padding: 0;
  border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-faint); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.fl-ic:hover { background: var(--bg-secondary); color: var(--t-primary); }
.fl-ic.est-ouvert { background: var(--bg-secondary); color: var(--t-primary); }
.fl-ic.est-posee { color: var(--accent); }
.fl-ic svg { width: 14px; height: 14px; }
/* LE COMPTEUR, ET PAS UN POINT.
 *
 * « Mon compteur, ce n'est pas une réalité qu'il y a sur les photos et que tu
 *  n'as pas mise ? »
 *
 * Il y avait un point de 5 px, et j'avais écrit ici pourquoi : à 22 px, une
 * pastille chiffrée déborde. C'était vrai du bouton, pas du chiffre — le
 * bouton passe à 24 px et la pastille tient dans son coin. Et le point ne
 * disait qu'une chose, « quelque chose est posé » ; le chiffre dit COMBIEN,
 * donc combien il faudra en défaire, sans ouvrir le menu ni survoler pour lire
 * l'infobulle. C'est la seule information que le bouton pouvait encore porter.
 *
 * IL RESTE DANS LES BORNES DU BOUTON. La barre latérale défile, et son CSS
 * force l'autre axe à `hidden` : une pastille qui déborde du coin serait
 * rognée à droite — la leçon déjà payée par le sous-menu. */
.fl-ic-compte {
  /* DANS LES BORNES DU BOUTON, pas débordant de son coin : la barre latérale
     défile, son CSS force l'autre axe à `hidden`, et un débordement de 1 px se
     faisait rogner en haut — visible à l'écran. */
  position: absolute; top: 0; right: 0;
  min-width: 12px; height: 12px; padding: 0 2px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-rond); background: var(--accent); color: #fff;
  font-size: var(--texte-1); font-weight: 700; line-height: 1;
}
/* LE VOILE FERME LE MENU AU PREMIER CLIC AILLEURS, et il est SOUS le panneau :
   au-dessus, il avalerait les clics du menu qu'il sert à fermer. */
.fl-voile { position: fixed; inset: 0; z-index: 39; background: transparent; }
/* 39 / 40 SONT DES VALEURS QUI EXISTAIENT DÉJÀ, et c'est délibéré : le dépôt
   compte les étages d'empilement distincts (`matiere-visuelle-smoke`) et refuse
   d'en ajouter. La pilule et le panneau partagent le 40 — frères dans le DOM,
   le panneau vient après, il passe donc devant sans qu'on ait à le dire. */
.fl-pilule {
  position: relative; z-index: 40;
  display: inline-flex; align-items: center; gap: var(--espace-3);
  height: 38px; padding: 0 var(--espace-5);
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  background: var(--bg-primary); color: var(--t-primary); cursor: pointer;
  font-size: var(--texte-2); font-family: inherit; white-space: nowrap;
  transition: all var(--duree-1) var(--courbe);
}
.fl-pilule:hover { background: var(--bg-secondary); }
.fl-pilule.est-ouvert { border-color: var(--t-primary); background: var(--bg-secondary); }
.fl-pilule.est-posee { border-color: var(--accent); }
.fl-pilule-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.fl-pilule-ic svg { width: 15px; height: 15px; }
.fl-pilule-etiquette { color: var(--t-faint); }
.fl-pilule-valeur { font-weight: 600; }
/* LA PASTILLE DIT COMBIEN DE RÉGLAGES MORDENT. Une liste courte sans raison
   visible se cherche longtemps ; ce chiffre est la raison. */
.fl-pilule-pastille {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: var(--radius-rond); background: var(--accent); color: #fff;
  font-size: var(--texte-1); font-weight: 700; font-variant-numeric: tabular-nums;
}
.fl-pilule-chevron { display: inline-flex; color: var(--t-faint); }
.fl-pilule-chevron svg { width: 14px; height: 14px; }
.fl-pilule.est-ouvert .fl-pilule-chevron { transform: rotate(180deg); }

/* LE PANNEAU EST À LA RACINE, en `fixed`, placé sous son bouton par
   `filtrePlacer()` après chaque rendu — comme le menu d'une conversation.
   Rendu dans la barre, il s'y faisait rogner : `.bar-corps` défile, et une
   boîte ne peut pas déborder horizontalement d'un conteneur qui défile. Son
   sous-menu latéral n'apparaissait pas du tout. Vu à l'écran.
   80, LA MÊME COUCHE QUE LA PAGE PLEINE, et rendu APRÈS elle donc devant : à
   40 il passait dessous, le bouton se marquait ouvert et rien n'apparaissait.
   80 existait déjà — le dépôt compte les étages d'empilement distincts. */
.fl-racine { position: relative; z-index: 80; }
.fl-menu {
  position: fixed; top: -9999px; left: -9999px; z-index: 40;
  /* « Tu les as faits beaucoup trop larges, ils sont beaucoup trop gros. »
     Mesuré à l'écran avant de toucher : 288 px de large, des rangées de 33 px.
     Sur sa capture le menu tient dans la colonne d'une barre latérale et ses
     rangées sont serrées. 232 × 27 : les libellés les plus longs — « Afficher
     les projets vides », « Alphabétique inversé » — tiennent encore sur une
     ligne, ce qui est la vraie borne basse. */
  width: 232px;
  display: flex; flex-direction: column; padding: var(--espace-2);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--bg-input, var(--bg-primary)); box-shadow: var(--ombre-3, var(--ombre-2));
}
.fl-rangee { display: flex; flex-direction: column; }
.fl-rangee-tete {
  display: flex; align-items: center; gap: var(--espace-3); width: 100%; text-align: left;
  padding: var(--espace-3) var(--espace-4); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-primary); cursor: pointer;
  font-size: var(--texte-2); font-family: inherit;
}
.fl-rangee-tete:hover { background: var(--bg-secondary); }
.fl-rangee-nom { flex: 1; min-width: 0; }
/* C'EST LA VALEUR QUI CÈDE, PAS LE NOM. Deux essais à l'écran : sans borne,
   « 2 sélectionnés » se collait au nom de la rangée ; en laissant le nom céder,
   « Environnement » devenait « Environnem… », et on ne savait plus ce qu'on
   réglait. Le nom garde sa place, la valeur s'abrège — c'est elle qu'on
   redécouvre en dépliant la rangée. */
.fl-rangee-valeur {
  color: var(--t-dim); font-weight: 600; flex: none; max-width: 92px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fl-rangee-chevron { display: inline-flex; flex: none; color: var(--t-faint); }
.fl-rangee-chevron svg { width: 14px; height: 14px; transition: transform var(--duree-1) var(--courbe); }
.fl-rangee.est-depliee .fl-rangee-chevron svg { transform: rotate(90deg); }
.fl-rangee.est-depliee > .fl-rangee-tete { color: var(--t-primary); font-weight: 600; }
/* ── LE SOUS-MENU SORT À CÔTÉ, comme sur ses captures ─────────────────────
 *
 * Je l'avais déplié EN ACCORDÉON sous sa rangée, et je m'étais donné une raison
 * — « à droite, il sortirait de l'écran ». Ses quatre photos montrent un
 * PANNEAU SÉPARÉ qui vole à côté du menu, la rangée restant à sa place. Ce
 * n'est pas un détail de goût : l'accordéon pousse les rangées du dessous
 * pendant qu'on choisit, et on perd de vue celle qu'on règle.
 *
 * Le côté n'est pas deviné. Dans la barre, le menu est collé au bord gauche de
 * l'écran : le sous-menu part à DROITE, où il y a toute la page. Sur une page
 * pleine, le menu est ancré à droite d'une tête d'écran : il part à GAUCHE.
 * C'est la seule chose que le contexte décide, et elle se lit dans la classe du
 * panneau — pas dans une mesure au chargement. */
.fl-rangee { position: relative; }
.fl-sous {
  position: absolute; top: -4px; left: calc(100% + var(--espace-3)); z-index: 1;
  display: flex; flex-direction: column; min-width: 172px; padding: var(--espace-2);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--bg-input, var(--bg-primary)); box-shadow: var(--ombre-3, var(--ombre-2));
}
.fl-menu--gauche .fl-sous { left: auto; right: calc(100% + var(--espace-3)); }
/* LE FILET DE SA PHOTO : au-dessus, ce qui RETIRE des éléments ; en dessous, ce
   qui les RANGE. Deux gestes qu'on ne confond pas. */
.fl-filet { height: 1px; margin: var(--espace-2) var(--espace-3); background: var(--border); }
.fl-sous-choix {
  display: flex; align-items: center; gap: var(--espace-3); width: 100%; text-align: left;
  padding: var(--espace-2) var(--espace-4); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-secondary); cursor: pointer;
  font-size: var(--texte-2); font-family: inherit;
}
.fl-sous-choix:hover { background: var(--bg-secondary); color: var(--t-primary); }
.fl-sous-choix.est-actif { color: var(--t-primary); font-weight: 600; }
/* LE NOM PREND LA LARGEUR, LE CARRÉ NON. La règle visait `span:first-child`,
   et le petit carré d'une rangée à cases EST le premier span : il s'étirait à
   toute la ligne et se lisait comme une pilule de 60 px. Vu à l'écran. */
.fl-sous-choix > span:not(.fl-carre):not(.fl-sous-coche) { flex: 1; min-width: 0; }
/* ── LE PETIT CARRÉ DE SA CAPTURE ─────────────────────────────────────────
 *
 * « Sur Environnement, tu vois qu'il y a des petits carrés derrière. »
 *
 * Il est À GAUCHE du nom, pas à droite comme la coche d'un choix unique, et
 * c'est ce qui distingue les deux formes AVANT le clic : à gauche on ajoute
 * des lignes à une sélection, à droite on remplace la valeur d'un réglage.
 * Carré, jamais rond : le rond est la marque du choix qui exclut les autres. */
.fl-carre {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  /* `--radius-xs`, pas `--radius-sm` : à 8 px de rayon sur une boîte de 14, le
     carré se lit comme un rond — et le rond est la marque du choix qui exclut
     les autres. Vu à l'écran, corrigé à l'écran. */
  width: 14px; height: 14px; border: 1px solid var(--border-hov); border-radius: var(--radius-xs);
  color: transparent; background: transparent;
}
.fl-carre.est-coche { border-color: var(--accent); background: var(--accent); color: #fff; }
.fl-carre svg { width: 10px; height: 10px; }
.fl-sous-coche { display: inline-flex; flex: none; color: var(--accent); }
.fl-sous-coche svg { width: 14px; height: 14px; }
/* « EFFACER LES FILTRES » est séparé par un filet : c'est le seul choix du
   panneau qui défait tous les autres, il ne doit pas se cliquer par erreur en
   visant la rangée du dessus. */
.fl-pied { margin-top: var(--espace-2); padding-top: var(--espace-2); border-top: 1px solid var(--border); }
.fl-effacer {
  width: 100%; text-align: left;
  padding: var(--espace-3) var(--espace-4); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--t-dim); cursor: pointer;
  font-size: var(--texte-2); font-family: inherit;
}
.fl-effacer:hover { background: var(--bg-secondary); color: var(--t-primary); }

/* ══════════════════════════════════════════════════════════════════════════
 * LA PAGE PLEINE DES SESSIONS (src/crea-fils.js)
 *
 * Un titre large, une rangée de gestes à droite, puis la liste — une ligne par
 * fil, sa date à droite.
 *
 * ── CE QUI EST REVENU, ET POURQUOI ───────────────────────────────────────
 *
 * J'avais refait cette page : bande fixe hors du défilement, rangées de 68 px
 * à deux lignes, glyphe encadré, colonnes fixes. « J'aime pas du tout comment
 * tu as fait. Là t'es en train de partir loin pour rien. Les filtres que je
 * t'ai donnés visaient la barre latérale. »
 *
 * Il a raison sur les deux points : ses captures montraient la BARRE, la page
 * n'était pas dans la demande, et je l'ai refaite par-dessus le marché. Elle
 * revient donc à ce qu'elle était — rangées d'une ligne, tête dans le flux, le
 * même défilement qu'avant.
 *
 * LE FILTRE N'Y EST PLUS NON PLUS, ni le mien ni l'ancien : il vit dans les
 * barres, là où ses photos le montrent. La page affiche ce qu'elles règlent.
 * ══════════════════════════════════════════════════════════════════════════ */
.fils-page {
  position: fixed; inset: 0; z-index: 80;
  overflow-y: auto; background: var(--bg-primary);
}
.fils-dedans {
  max-width: 900px; margin: 0 auto;
  padding: var(--espace-9) var(--espace-8) var(--espace-10);
  display: flex; flex-direction: column; gap: var(--espace-6);
}
.fils-tete { display: flex; align-items: center; gap: var(--espace-4); flex-wrap: wrap; }
.fils-tete-espace { flex: 1; }
.fils-retour {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 32px; height: 32px; margin-left: calc(-1 * var(--espace-4));
  border: 0; border-radius: var(--radius-rond); background: transparent;
  color: var(--t-secondary); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.fils-retour:hover { background: var(--bg-secondary); color: var(--t-primary); }
.fils-retour svg { width: 17px; height: 17px; }
.fils-titre { margin: 0; font-size: var(--texte-9); font-weight: 600; color: var(--t-primary); letter-spacing: -0.01em; }
.fils-rond {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 34px; height: 34px;
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  background: transparent; color: var(--t-secondary); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.fils-rond:hover { background: var(--bg-secondary); color: var(--t-primary); }
.fils-rond.est-actif { border-color: var(--t-primary); color: var(--t-primary); }
.fils-rond svg { width: 16px; height: 16px; }
.fils-pilule {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  padding: var(--espace-3) var(--espace-5);
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  background: transparent; color: var(--t-primary); cursor: pointer;
  font-size: var(--texte-2); font-family: inherit;
  transition: all var(--duree-1) var(--courbe);
}
.fils-pilule:hover { background: var(--bg-secondary); }
.fils-pilule.est-actif { border-color: var(--t-primary); }
.fils-pilule-etiquette { color: var(--t-faint); }
.fils-pilule-valeur { font-weight: 500; }
.fils-pilule-chevron { display: inline-flex; color: var(--t-faint); }
.fils-pilule-chevron svg { width: 14px; height: 14px; }
.fils-fort {
  padding: var(--espace-3) var(--espace-6);
  border: 0; border-radius: var(--radius-rond);
  background: var(--t-primary); color: var(--bg-primary); cursor: pointer;
  font-size: var(--texte-2); font-weight: 600; font-family: inherit;
  transition: opacity var(--duree-1) var(--courbe);
}
.fils-fort:hover { opacity: .88; }

.fils-cherche {
  display: flex; align-items: center; gap: var(--espace-3);
  padding: var(--espace-3) var(--espace-5);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-secondary);
}
.fils-cherche-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.fils-cherche-ic svg { width: 15px; height: 15px; }
.fils-cherche-champ {
  flex: 1; min-width: 0; border: 0; background: transparent; outline: none;
  color: var(--t-primary); font-size: var(--texte-3); font-family: inherit;
}
.fils-cherche-vider { border: 0; background: transparent; color: var(--t-faint); cursor: pointer; display: inline-flex; }
.fils-cherche-vider svg { width: 13px; height: 13px; }

/* LA BARRE DU LOT n'apparaît qu'en mode sélection : une rangée de gestes
   permanente au-dessus d'une liste qu'on ne sélectionne pas serait du bruit. */
.fils-lot {
  display: flex; align-items: center; gap: var(--espace-4); flex-wrap: wrap;
  padding: var(--espace-4) var(--espace-5);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-secondary);
}
.fils-lot-espace { flex: 1; }
.fils-lot-compte { font-size: var(--texte-2); color: var(--t-dim); font-variant-numeric: tabular-nums; }
.fils-lot-geste {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  padding: var(--espace-2) var(--espace-4);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-primary); color: var(--t-primary); cursor: pointer;
  font-size: var(--texte-2); font-family: inherit;
  transition: all var(--duree-1) var(--courbe);
}
.fils-lot-geste:hover:not([disabled]) { background: var(--bg-tertiary, var(--bg-secondary)); }
.fils-lot-geste[disabled] { opacity: .45; cursor: default; }
.fils-lot-geste.est-danger { color: var(--danger); }
.fils-lot-ic { display: inline-flex; }
.fils-lot-ic svg { width: 14px; height: 14px; }

.fils-liste { display: flex; flex-direction: column; }
.fils-rangee {
  display: flex; align-items: center; gap: var(--espace-4);
  border-bottom: 1px solid var(--border);
  transition: background var(--duree-1) var(--courbe);
}
.fils-rangee:hover { background: var(--bg-secondary); }
.fils-rangee.est-choisie { background: var(--accent-bg, var(--bg-secondary)); }
.fils-rangee-corps {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--espace-4);
  padding: var(--espace-5) var(--espace-4); text-align: left;
  border: 0; background: transparent; cursor: pointer;
  font-size: var(--texte-3); font-family: inherit; color: var(--t-primary);
}
.fils-rangee-ic { display: inline-flex; flex: none; color: var(--t-faint); }
.fils-rangee-ic svg { width: 16px; height: 16px; }
.fils-rangee-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* UN TITRE ABSENT SE DIT, EN GRIS — c'est une information, pas un trou. */
.fils-rangee-nom.est-vide { color: var(--t-faint); }
.fils-rangee.est-active .fils-rangee-nom { font-weight: 600; }
.fils-rangee-marque { color: var(--accent); flex: none; }
.fils-rangee-date {
  flex: none; padding-right: var(--espace-4);
  font-size: var(--texte-2); color: var(--t-faint); font-variant-numeric: tabular-nums;
}
/* LE « ⋮ » PREND LA PLACE DE LA DATE AU SURVOL, comme sur la photo. */
.fils-rangee-menu {
  display: none; align-items: center; justify-content: center; flex: none;
  width: 28px; height: 28px; margin-right: var(--espace-3);
  border-radius: var(--radius-sm); color: var(--t-faint); cursor: pointer;
}
.fils-rangee-menu:hover { background: var(--bg-tertiary, var(--bg-primary)); color: var(--t-primary); }
.fils-rangee-menu svg { width: 15px; height: 15px; }
.fils-rangee:hover .fils-rangee-menu,
.fils-rangee-menu.est-ouvert { display: inline-flex; }
.fils-rangee:hover .fils-rangee-date { display: none; }

.fils-case {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 17px; height: 17px;
  border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  color: var(--bg-primary);
}
.fils-case.est-cochee { background: var(--accent); border-color: var(--accent); }
.fils-case svg { width: 12px; height: 12px; }

.fils-vide { margin: 0; padding: var(--espace-10) 0; text-align: center; font-size: var(--texte-3); color: var(--t-faint); }

@media (max-width: 768px) {
  .fils-dedans { padding: var(--espace-6) var(--espace-5) var(--espace-9); }
  .fils-titre { font-size: var(--texte-7); }
  /* Sans survol, le « ⋮ » doit rester atteignable. */
  .fils-rangee-menu { display: inline-flex; }
  .fils-rangee-date { display: none; }
}

/* L'EN-TÊTE D'UN GROUPE, quand « Grouper par » est réglé depuis la barre. Sans
   lui, ce réglage ne se verrait pas ici — et un réglage qui ne change rien à
   l'écran est un réglage mort. Au repos (« Aucun »), rien ne s'affiche : la
   page est exactement celle d'avant. */
.fils-groupe {
  display: flex; align-items: center; gap: var(--espace-3);
  margin: var(--espace-5) 0 var(--espace-2);
  font-size: var(--texte-1); font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--t-faint);
}
.fils-groupe:first-child { margin-top: 0; }
.fils-groupe-compte { color: var(--t-faint); font-variant-numeric: tabular-nums; }

/* ═══════════════════════════════════════════════════════════════════════════
 * AUTOWORK — LES DEUX FAÇADES
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * « Automate intervient dans Planifier et dans AutoWork. »
 *
 * Un seul registre, deux fenêtres dessus : ces règles servent les DEUX pages.
 * Deux jeux de styles auraient fait deux listes qui se ressemblent puis
 * divergent — exactement le défaut que la façade unique répare.
 *
 * AUCUNE COULEUR NEUVE, AUCUN RAYON NEUF : `couleur-lisible` a déjà mesuré
 * `--danger` et `--warn` sur les deux fonds des deux thèmes, et les deux
 * cliquets visuels comptent les valeurs DISTINCTES.
 */
.aw { display: flex; flex-direction: column; gap: var(--espace-4); }
.aw-vide { font-size: var(--texte-3); color: var(--t-faint); }

/* CE QUI EST CASSÉ PASSE DEVANT. Une automatisation en panne qu'on découvre en
   faisant défiler est une automatisation qu'on découvre trop tard — et le
   journal oublie ce qui est réparé, donc ce bandeau part tout seul. */
.aw-alerte {
  padding: var(--espace-4) var(--espace-6);
  border: 1px solid var(--danger); border-radius: var(--radius-lg);
  background: var(--danger-fond);
}
.aw-alerte-titre { font-size: var(--texte-3); font-weight: 700; color: var(--danger); }
.aw-alerte-ligne { margin-top: var(--espace-2); font-size: var(--texte-2); color: var(--t-secondary); }

.aw-liste { display: flex; flex-direction: column; gap: var(--espace-2); }
.aw-ligne {
  display: flex; align-items: center; gap: var(--espace-4);
  padding: var(--espace-4) var(--espace-6);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--bg-secondary);
}
/* ÉTEINTE, ELLE RESTE LISIBLE. La griser jusqu'à l'illisible ferait perdre de
   vue ce qu'on vient de désactiver, et c'est justement le moment où l'on veut
   pouvoir le rallumer. */
.aw-ligne.est-eteinte .aw-nom { color: var(--t-dim); }
.aw-ligne-corps { flex: 1; min-width: 0; }
.aw-nom { font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); }
.aw-quand { margin-top: var(--espace-1); font-size: var(--texte-2); color: var(--t-faint); }
.aw-panne { margin-top: var(--espace-1); font-size: var(--texte-2); color: var(--danger); }
.aw-bascule {
  flex: none; padding: var(--espace-2) var(--espace-5);
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  background: var(--bg-tertiary); color: var(--t-dim);
  font-size: var(--texte-2); font-weight: 700; font-family: inherit; cursor: pointer;
}
.aw-bascule.est-active { background: var(--accent); border-color: var(--accent); color: #fff; }

.aw-titre {
  margin-top: var(--espace-2); font-size: var(--texte-2);
  color: var(--t-faint);
}
/* DEUX COLONNES, COMME SES DEUX CAPTURES. Sous 640 px, une seule : deux cartes
   côte à côte sur un téléphone coupent leur phrase au troisième mot. */
/* ══ LE CATALOGUE DE MODÈLES — LA SECTION « MODÈLES » ══════════════════════
   Rangé par famille, en cartes plus grandes que le rappel de pied qu'elles
   remplacent : c'est la page entière maintenant. Une grille qui respire, parce
   qu'on vient y CHOISIR — pas y reconnaître ce qu'on cherchait déjà. */
.aw-cat { display: flex; flex-direction: column; gap: var(--espace-6); padding: var(--espace-2) 0 var(--espace-6); }
.aw-cat-fam-nom { font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); margin: 0; }
.aw-cat-fam-quoi { font-size: var(--texte-2); color: var(--t-dim); margin: 2px 0 var(--espace-3); line-height: 1.5; }
.aw-cat-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: var(--espace-3); }
.aw-cat-carte { display: flex; flex-direction: column; gap: 6px; text-align: left; padding: var(--espace-4);
  background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-lg);
  cursor: pointer; transition: all var(--duree-1) var(--courbe); }
.aw-cat-carte:hover { border-color: var(--accent); box-shadow: var(--ombre-2); transform: translateY(-1px); }
.aw-cat-ic { display: inline-flex; width: 32px; height: 32px; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); background: var(--bg-input); color: var(--accent); margin-bottom: 2px; }
.aw-cat-ic svg { width: 17px; height: 17px; }
.aw-cat-nom { font-size: var(--texte-2); font-weight: 600; color: var(--t-primary); }
.aw-cat-quoi { font-size: var(--texte-1); color: var(--t-dim); line-height: 1.55; }
.aw-cat-pied { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--espace-3); margin-top: auto; padding-top: var(--espace-2); }
.aw-cat-quand { display: inline-flex; align-items: center; gap: 5px; font-size: var(--texte-1); color: var(--t-dim); }
.aw-cat-quand svg { width: 13px; height: 13px; }
.aw-cat-avec { font-size: var(--texte-1); color: var(--t-dim); opacity: .8; }

/* ══ « PLANIFIEZ AVEC CRÉA » — LA CONVERSATION QUI POSE UNE CADENCE ═══════
   « Un espace chat propre… l'espace chat, elle aura la pleine hauteur. »
   Tant qu'on n'a rien écrit, la présentation est centrée et le champ en bas.
   Dès le premier message, le fil prend toute la colonne et pousse le champ
   contre le bord : c'est le même conteneur, pas une seconde mise en page. */
/* ── LA BARRE EST FIXE, C'EST LA CONVERSATION QUI DÉFILE ─────────────────
 *
 * « J'ai remarqué qu'elle descend, elle défile, et on ne la voit même plus. Ce
 *  n'est pas la barre qui doit descendre à chaque fois que la conversation
 *  s'allonge. »
 *
 * LA CAUSE : la console est posée dans un conteneur qui défile (`flex-1
 * overflow-y-auto`, src/app.js). Un `margin-top: auto` sur la barre la colle au
 * bas du CONTENU, pas de l'écran — donc plus la conversation s'allonge, plus la
 * barre s'éloigne vers le bas du défilement. Elle finit hors de vue.
 *
 * LE REMÈDE : la section prend la HAUTEUR DISPONIBLE et devient elle-même la
 * colonne. Le fil défile À L'INTÉRIEUR (`flex: 1; min-height: 0`), la barre ne
 * défile pas du tout. Le `min-height: 0` n'est pas un détail : sans lui, un
 * enfant de flex refuse de rétrécir sous la taille de son contenu, et le fil
 * repousserait la barre exactement comme avant. */
.aw.a-vue-poser { height: 100%; display: flex; flex-direction: column; min-height: 0; }
.aw.a-vue-poser > .aw-tete,
.aw.a-vue-poser > .aw-barre { flex-shrink: 0; }
.aw-poser { display: flex; flex-direction: column; gap: var(--espace-3);
  flex: 1; min-height: 0; padding: var(--espace-4) 0 0; }
.aw-poser-bas { flex-shrink: 0; width: 100%; max-width: 46rem; margin: 0 auto; }
/* SANS RIEN D'ÉCRIT, la présentation occupe la place et se centre — mais la
   barre reste au même endroit qu'après le premier message : elle ne bouge
   jamais, et c'est tout l'intérêt. */
/* L'ACCUEIL NE REMPLIT PLUS L'ÉCRAN. Il se pose en haut, la barre reste en
   bas : entre les deux, du vide assumé — c'est une page où l'on formule une
   demande, pas une salle de conversation. */
.aw-poser-haut {
  flex: 1; display: flex; flex-direction: column;
  text-align: left; width: 100%; max-width: 46rem; margin: 0 auto;
}
/* L'ESPACE ENTRE UN MESSAGE ET SA RÉPONSE DOIT EXISTER. « Si c'est trop
   proche, comment on arrivera à lire ? » — et il avait raison : `--espace-3`
   vaut SIX PIXELS. Ce qui ressemblait à de l'air sur la capture était le
   rembourrage de la bulle, pas l'écart entre les tours. Vingt pixels séparent
   maintenant une demande de sa réponse ; huit séparent une réponse de la carte
   qu'elle propose, parce que ces deux-là vont ensemble. */
.aw-poser-fil {
  flex: 1; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--espace-10);
  width: 100%; max-width: 46rem; margin: 0 auto;
}
/* ── CE QUE J'ENVOIE SE DISTINGUE DE CE QU'ELLE RÉPOND ────────────────────
 *
 * « Ce que je lui envoie, c'est écrit en beaucoup trop petit — on n'arrive pas
 *  à faire la différence. »
 *
 * Trois choses les séparent, et il en faut trois : la taille (les deux sont
 * maintenant à la taille du texte courant, pas à celle d'une légende), le fond
 * (une bulle pour la demande, rien pour la réponse) et le côté. Une seule de
 * ces trois différences se perd de vue dès qu'on lit vite. */
.aw-bulle { display: flex; flex-direction: column; gap: var(--espace-4); max-width: 100%; }
.aw-bulle.est-moi { align-self: flex-end; align-items: flex-end; max-width: 82%; }
.aw-bulle.est-moi .aw-bulle-txt {
  padding: var(--espace-2) var(--espace-4); border-radius: var(--radius);
  background: var(--bg-secondary); border: 1px solid var(--border);
  color: var(--t-primary); font-size: var(--texte-3);
}
.aw-bulle-txt { font-size: var(--texte-3); color: var(--t-primary); line-height: 1.65; }
.aw-bulle.est-crea .aw-bulle-txt > *:first-child { margin-top: 0; }
.aw-bulle.est-crea .aw-bulle-txt > *:last-child { margin-bottom: 0; }
.aw-bulle-attend { font-size: var(--texte-2); color: var(--t-faint); }
.aw-bulle-err { font-size: var(--texte-2); color: var(--danger); }

/* LA CARTE D'UNE PROPOSITION. Elle ne crée rien : « Accepter » ouvre le
   formulaire du lieu proposé, rempli, et c'est là qu'on valide. */
.aw-propos {
  display: flex; flex-direction: column; gap: var(--espace-1);
  margin-top: var(--espace-1);
  padding: var(--espace-3); border: 1px solid var(--accent);
  border-radius: var(--radius-sm); background: var(--bg-secondary);
}
.aw-propos-nom { font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); }
.aw-propos-quand { display: flex; align-items: center; gap: var(--espace-1); font-size: var(--texte-2); color: var(--t-dim); }
.aw-propos-quand svg { width: 14px; height: 14px; flex-shrink: 0; }
.aw-propos-quoi { font-size: var(--texte-2); color: var(--t-secondary); white-space: pre-wrap; }
.aw-propos-pied { display: flex; align-items: center; gap: var(--espace-2); margin-top: var(--espace-2); }
.aw-propos-lieu {
  display: inline-flex; align-items: center; gap: var(--espace-1); margin-right: auto;
  padding: 1px var(--espace-2); border-radius: var(--radius-xs);
  background: var(--bg-input); color: var(--t-dim); font-size: var(--texte-1);
}
.aw-propos-lieu svg { width: 13px; height: 13px; }
.aw-propos-ok {
  padding: var(--espace-1) var(--espace-4); border-radius: var(--radius-sm);
  background: var(--t-primary); color: var(--bg-primary); border: none;
  font-size: var(--texte-2); font-weight: 600; cursor: pointer;
}

/* LE PIED N'EXISTE PLUS QUE SANS LA BARRE DU DÉPÔT. Il portait deux menus que
   `renderUniversalInputBar` rend déjà — modèle, effort, niveau d'accès, lieu —
   et un « Envoyer » qui doublait celui de la barre. Ce qui reste sert au repli :
   sans la barre, il faut bien un bouton pour envoyer. */
.aw-poser-pied { display: flex; justify-content: flex-end; margin-top: var(--espace-2); }
/* « NOUVELLE CONVERSATION » VIT DANS LA BARRE DES SECTIONS, à droite, avec les
   autres outils — « sur la même ligne que là où il y a les sections ». Sa règle
   de haut de fil est partie avec elle. */
.aw-poser-neuve {
  padding: var(--espace-1) var(--espace-3); border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: none; color: var(--t-dim);
  font-size: var(--texte-2); cursor: pointer;
  transition: color var(--duree-1) var(--courbe);
}
.aw-poser-neuve:hover { color: var(--t-primary); }
.aw-poser-fil::-webkit-scrollbar { width: 8px; }
.aw-poser-fil::-webkit-scrollbar-thumb { background: var(--border); border-radius: var(--radius-rond); }
.aw-poser-ic { display: inline-flex; align-items: center; justify-content: center; color: var(--accent); }
.aw-poser-ic svg { width: 16px; height: 16px; }
.aw-poser-titre { display: flex; align-items: center; gap: var(--espace-2); font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); margin: 0; }
.aw-poser-quoi { font-size: var(--texte-2); color: var(--t-dim); margin: var(--espace-2) 0 0; line-height: 1.6; max-width: 40rem; }
.aw-poser-bas { width: 100%; max-width: 46rem; margin: 0 auto; }

.aw-modeles { display: grid; grid-template-columns: 1fr 1fr; gap: var(--espace-4); }
@media (max-width: 640px) { .aw-modeles { grid-template-columns: 1fr; } }
.aw-modele {
  display: flex; flex-direction: column; gap: var(--espace-2); text-align: left;
  padding: var(--espace-5) var(--espace-6);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--bg-secondary); color: var(--t-primary);
  font-family: inherit; cursor: pointer;
}
.aw-modele:hover { border-color: var(--border-hov); }
.aw-modele-nom { font-size: var(--texte-4); font-weight: 600; }
.aw-modele-quoi { font-size: var(--texte-2); color: var(--t-dim); }
/* LE RENDEZ-VOUS SOUS LE NOM, comme sur ses captures — « En semaine à 8:00 »
   sous « Briefing quotidien ». C'est ce qui permet de choisir SANS poser : un
   catalogue de noms seuls oblige à en essayer un pour savoir ce qu'il fait. */
.aw-modele-quand { font-size: var(--texte-1); color: var(--t-faint); }

/* LE JOURNAL EST EN BAS ET REPLIÉ. On ne vient pas ici pour lire l'historique,
   on y vient pour voir ce qui tourne — mais il est ATTEIGNABLE, et c'était
   tout le manque : `lastError` était écrit, aucune page ne le montrait. */
.aw-journal { font-size: var(--texte-2); color: var(--t-dim); }
.aw-journal summary { cursor: pointer; padding: var(--espace-3) 0; }
.aw-journal-ligne {
  display: flex; gap: var(--espace-4); justify-content: space-between;
  padding: var(--espace-2) 0; border-top: 1px solid var(--border);
}
.aw-journal-ligne.est-echec { color: var(--danger); }

/* ── LE FORMULAIRE D'UNE ROUTINE (src/crea-autowork-forme.js) ─────────────
   Une colonne, pas une grille : ses captures posent tout l'un sous l'autre,
   du nom jusqu'aux deux boutons. Rien n'est centré — la lecture part
   toujours du même bord gauche, et l'œil n'a pas à rechercher où commence
   le champ suivant. */
.aw-entete { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--espace-4); }
.aw-entete-quoi { font-size: var(--texte-3); color: var(--t-dim); max-width: 46ch; }
.aw-entete-b { display: flex; gap: var(--espace-2); flex-shrink: 0; }
/* UN SEUL BOUTON, ET SON PANNEAU. Sa capture montre « Nouvelle routine ⌄ » —
   un bouton, un chevron. Deux boutons cote a cote mettaient les deux lieux
   d'execution au rang d'une action principale : on lisait deux verbes la ou il
   n'y en a qu'un. */
.aw-neuve-boite { position: relative; flex-shrink: 0; }
.aw-neuve {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  padding: var(--espace-2) var(--espace-5); border-radius: var(--radius);
  font-size: var(--texte-3); font-weight: 600; cursor: pointer;
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
}
.aw-neuve-ch { display: inline-flex; width: .85em; height: .85em; }
.aw-neuve-ch > svg, .aw-neuve-ic > svg { width: 100%; height: 100%; }
.aw-neuve-menu {
  position: absolute; right: 0; top: calc(100% + var(--espace-2)); z-index: 30;
  display: flex; flex-direction: column; min-width: 11rem; overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-primary); box-shadow: var(--ombre-3);
}
.aw-neuve-choix {
  display: flex; align-items: center; gap: var(--espace-3);
  padding: var(--espace-3) var(--espace-4); background: none; border: none;
  color: var(--t-primary); font-size: var(--texte-3); text-align: left; cursor: pointer;
}
.aw-neuve-choix:hover { background: var(--bg-input); }
.aw-neuve-ic { display: inline-flex; width: 1rem; height: 1rem; color: var(--t-dim); flex-shrink: 0; }

/* LE FORMULAIRE PREND TOUTE LA PAGE, PAS UNE COLONNE.
   « La page sur laquelle ça ramène ne prend pas toute la page. Elle prend un
   côté. Une fois que la barre latérale est fermée, elle est censée remplir.
   Pourquoi laisser des gros bouts de blanc ? »
   Il avait `max-width: 46rem` : sur un large écran, la moitie droite restait
   vide. La largeur suit maintenant la place disponible ; seule une borne haute
   tres large empeche les champs de s'etirer sur trois metres. */
.awf { display: flex; flex-direction: column; gap: var(--espace-3); width: 100%; max-width: 100%; }
.awf-fil { font-size: var(--texte-3); color: var(--t-dim); margin-bottom: var(--espace-3); }
.awf-bandeau {
  padding: var(--espace-4) var(--espace-5); border-radius: var(--radius);
  background: var(--bg-secondary); border: 1px solid var(--border);
  font-size: var(--texte-3); color: var(--t-secondary);
}
.awf-etiq { font-size: var(--texte-3); color: var(--t-secondary); margin-top: var(--espace-4); }
.awf-obl { color: var(--danger); }
.awf-champ {
  width: 100%; padding: var(--espace-3) var(--espace-4);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-primary); color: var(--t-primary); font-size: var(--texte-3);
}
.awf-court { width: 9rem; }
.awf-select { width: auto; }
.awf-zone { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-primary); overflow: hidden; }
.awf-texte {
  width: 100%; min-height: 8rem; padding: var(--espace-4); border: none; resize: vertical;
  background: none; color: var(--t-primary); font-size: var(--texte-3); font-family: inherit;
}
.awf-pied {
  display: flex; align-items: center; justify-content: space-between; gap: var(--espace-3);
  padding: var(--espace-2) var(--espace-4); border-top: 1px solid var(--border); background: var(--bg-secondary);
}
.awf-pied-b { font-size: var(--texte-4); color: var(--t-dim); background: none; border: none; cursor: pointer; }
.awf-pied-e { font-size: var(--texte-4); color: var(--t-dim); }
/* LA SECONDE RANGÉE DU PIED, côté local : « Sélectionner un dossier » et
   « Arbre de travail ». Elle se pose sous la première, dans le même cadre. */
.awf-pied-2 { border-top: 1px solid var(--border); }
/* LA CROIX DE LA CARTE : la phrase à gauche, elle tout à droite. */
.awf-carte-tete { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--espace-3); }
.awf-carte-x {
  background: none; border: none; color: var(--t-faint); cursor: pointer;
  font-size: var(--texte-5); line-height: 1; flex-shrink: 0;
}
.awf-pied-coche { display: flex; align-items: center; gap: var(--espace-2); font-size: var(--texte-4); color: var(--t-dim); }

/* LA CARTE DU DÉCLENCHEUR. Sa phrase EN TÊTE, puis les pastilles, puis le
   champ de la forme choisie : on lit ce qu'on vient de poser avant de voir
   avec quoi on l'a posé. */
.awf-carte {
  display: flex; flex-direction: column; gap: var(--espace-3);
  padding: var(--espace-4); border-radius: var(--radius); background: var(--bg-secondary);
}
.awf-phrase { font-size: var(--texte-3); color: var(--t-secondary); }
.awf-pastilles { display: flex; flex-wrap: wrap; gap: var(--espace-1); }
.awf-pastille {
  padding: var(--espace-1) var(--espace-3); border-radius: var(--radius-sm);
  font-size: var(--texte-4); color: var(--t-dim); background: none; border: none; cursor: pointer;
}
.awf-pastille.est-prise { background: var(--bg-input); color: var(--t-primary); font-weight: 600; }
.awf-rangee { display: flex; align-items: center; gap: var(--espace-3); font-size: var(--texte-3); color: var(--t-secondary); }
.awf-indice { font-size: var(--texte-4); color: var(--t-faint); }
.awf-plus { font-size: var(--texte-3); color: var(--t-dim); background: none; border: none; cursor: pointer; text-align: left; }

/* CE QUI N'EST PAS DISPONIBLE GARDE SA PLACE ET DIT POURQUOI — sa propre
   forme, celle d'« Événement GitHub … Sélectionnez d'abord un dépôt. » */
.awf-rangee-bloc {
  display: flex; align-items: center; justify-content: space-between; gap: var(--espace-4);
  padding: var(--espace-4); border-radius: var(--radius); background: var(--bg-secondary);
}
.awf-rangee-bloc.est-inerte { opacity: .55; }
.awf-rangee-nom { font-size: var(--texte-3); color: var(--t-primary); display: block; }
.awf-rangee-quoi { font-size: var(--texte-4); color: var(--t-dim); display: block; }
/* L'ADRESSE D'APPEL D'UNE ROUTINE « API ». Elle se copie à la main : en police
   fixe, sur une ligne qui déborde plutôt que de se couper au milieu du jeton. */
.awf-adresse { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--texte-1); color: var(--t-dim); background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 6px 8px; margin: 6px 0 2px; overflow-x: auto; white-space: nowrap; }
.awf-raison { font-size: var(--texte-4); color: var(--t-faint); text-align: right; flex-shrink: 0; max-width: 18ch; }

.awf-onglets { display: flex; gap: var(--espace-1); margin-top: var(--espace-4); }
.awf-onglet {
  padding: var(--espace-1) var(--espace-3); border-radius: var(--radius-sm);
  font-size: var(--texte-4); color: var(--t-dim); background: none; border: none; cursor: pointer;
}
.awf-onglet.est-pris { background: var(--bg-input); color: var(--t-primary); font-weight: 600; }
.awf-compte { color: var(--t-faint); }
.awf-volet { display: flex; flex-direction: column; gap: var(--espace-2); }
.awf-titre { font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); }
.awf-sous { font-size: var(--texte-4); color: var(--t-dim); }
.awf-puces { display: flex; flex-wrap: wrap; gap: var(--espace-2); align-items: center; }
.awf-puce {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  padding: var(--espace-1) var(--espace-3); border-radius: var(--radius-sm);
  border: 1px solid var(--border); font-size: var(--texte-4); color: var(--t-secondary);
}
.awf-puce-x { background: none; border: none; color: var(--t-faint); cursor: pointer; }
.awf-ajout {
  padding: var(--espace-1) var(--espace-3); border-radius: var(--radius-sm);
  border: 1px dashed var(--border); background: none; color: var(--t-dim);
  font-size: var(--texte-4); cursor: pointer;
}
.awf-avert {
  padding: var(--espace-3) var(--espace-4); border-radius: var(--radius);
  background: var(--warn-fond); color: var(--warn); font-size: var(--texte-4);
}
.awf-coche { display: flex; align-items: flex-start; gap: var(--espace-3); padding: var(--espace-4);
  border-radius: var(--radius); background: var(--bg-secondary); }
.aw-inter, .awf-inter {
  width: 2.25rem; height: 1.25rem; border-radius: var(--radius-rond); background: var(--bg-input);
  border: 1px solid var(--border); cursor: pointer; padding: 2px; flex-shrink: 0;
}
.aw-inter > span, .awf-inter > span { display: block; width: .875rem; height: .875rem; border-radius: var(--radius-rond); background: var(--t-faint); }
.aw-inter.est-on, .awf-inter.est-on { background: var(--accent); border-color: var(--accent); }
.aw-inter.est-on > span, .awf-inter.est-on > span { background: #fff; margin-left: auto; }
.awf-boutons { display: flex; justify-content: flex-end; gap: var(--espace-2); margin-top: var(--espace-5); }
.awf-annuler, .awf-creer {
  padding: var(--espace-2) var(--espace-5); border-radius: var(--radius);
  font-size: var(--texte-3); cursor: pointer;
}
.awf-annuler { background: none; border: 1px solid var(--border); color: var(--t-secondary); }
.awf-creer { background: var(--t-primary); color: var(--bg-primary); border: 1px solid var(--t-primary); }
.awf-creer:disabled { opacity: .4; cursor: not-allowed; }

/* LE FORMULAIRE PREND TOUTE LA PAGE, comme sur sa capture : « Routines /
   Nouvelle routine » remplace ce qu'il y avait, il ne s'y ajoute pas. On
   n'écrit pas une routine en gardant un œil sur les intégrations externes et
   les boucles serveur.
   PAS UNE LIGNE DE PLUS DANS LE TRONC pour ça : la page marque seulement son
   conteneur, et c'est la feuille de style qui range ses frères. */
/* `:not(.awf)` EST LA MOITIÉ QUI MANQUAIT, ET ELLE COÛTAIT UNE PAGE BLANCHE.
   « J'ai cliqué sur Nouvelle routine chez AutoWork, ça m'a mis page blanche, et
   quand j'ai voulu aller sur Planifier, la page blanche elle etait la. »
   La règle cache les FRÈRES du formulaire. Quand la console est devenue
   l'unique enfant du conteneur, le formulaire s'est retrouvé enfant direct — et
   `:has(.awf)` ne matche pas un élément qui EST `.awf` sans en contenir un
   autre. Il se cachait donc lui-même, et il ne restait rien à l'écran. */
.aw-forme-ouverte > *:not(.awf):not(:has(.awf)),
.aw-forme-ouverte > *:has(.awf) > *:not(.awf):not(:has(.awf)) { display: none; }

/* ── LA CONSOLE AUTOWORK (src/crea-autowork.js) ───────────────────────────
   L'écran de sa capture, dans son ordre : titre et sous-titre à gauche, les
   deux portes à droite ; la boîte « Que souhaitez-vous automatiser ? » avec
   ses puces ; la liste ou le vide illustré ; les modèles sur deux colonnes. */
.aw-tete { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--espace-5); }
.aw-tete-g { min-width: 0; }
.aw-tete-nom {
  display: flex; align-items: center; gap: var(--espace-2);
  font-size: var(--texte-6); font-weight: 700; color: var(--t-primary);
}
.aw-tete-ic { display: inline-flex; width: 1.05em; height: 1.05em; color: var(--accent); }
.aw-tete-ic > svg, .aw-modele-ic > svg, .aw-rien-ic > svg { width: 100%; height: 100%; }
/* LA PHRASE TIENT SUR UNE LIGNE. « Elle doit être sur une ligne, elle doit
   être droite. » Elle se coupait en deux parce qu'un `max-width` en caractères
   la bornait plus court que la place disponible : deux lignes sous un titre
   d'une seule, et le bloc penchait. On la laisse aller jusqu'au bout, et si la
   fenêtre devient vraiment étroite elle s'abrège plutôt que de se plier. */
.aw-tete-quoi {
  font-size: var(--texte-3); color: var(--t-dim); margin-top: var(--espace-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.aw-tete-b { display: flex; gap: var(--espace-2); flex-shrink: 0; }

/* LA BOÎTE. Elle décrit, elle ne crée pas : « Rédiger une routine » ouvre le
   formulaire déjà rempli, et les trois puces la remplissent. */
.aw-boite {
  display: flex; flex-direction: column; gap: var(--espace-3);
  padding: var(--espace-4); border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-primary);
}
.aw-boite-champ {
  width: 100%; border: none; background: none; resize: vertical;
  color: var(--t-primary); font-size: var(--texte-3); font-family: inherit; min-height: 3.4rem;
}
.aw-boite-champ:focus { outline: none; }
/* LES RÈGLES DES TROIS PHRASES D'EXEMPLE SONT PARTIES AVEC ELLES. Elles
   survivaient à ce que plus rien ne rendait — et une règle sans balisage finit
   par rappeler son balisage. */
.aw-rediger {
  padding: var(--espace-2) var(--espace-4); border-radius: var(--radius-sm);
  background: var(--t-primary); color: var(--bg-primary); border: none;
  font-size: var(--texte-2); font-weight: 600; cursor: pointer;
}

/* LE VIDE EST ILLUSTRÉ. « Tu aurais pu mettre un bloc image au milieu pour
   illustrer » — sa capture le fait déjà. Une page vide sans image a l'air
   cassée ; avec elle, elle a l'air prête. */
.aw-rien {
  display: flex; flex-direction: column; align-items: center; gap: var(--espace-3);
  padding: var(--espace-9) var(--espace-5);
}
.aw-rien-ic { display: inline-flex; width: 2rem; height: 2rem; color: var(--t-faint); }
.aw-rien-mot { font-size: var(--texte-3); color: var(--t-dim); }

.aw-modele-tete { display: flex; align-items: center; gap: var(--espace-2); }
.aw-modele-ic { display: inline-flex; width: 1rem; height: 1rem; color: var(--t-secondary); flex-shrink: 0; }
.aw-modele-quand { display: flex; align-items: center; gap: var(--espace-2); }
.aw-modele-quand > svg { width: .8em; height: .8em; flex-shrink: 0; }
.aw-modele-avec { font-size: var(--texte-1); color: var(--t-faint); }

/* ── LA BARRE DES ROUTINES (src/crea-autowork.js) ─────────────────────────
   Ses deux captures : « Tous | Calendrier » à gauche ; à droite « Inclure les
   terminées (N) » avec sa bascule, « Filtrer », et la recherche. */
.aw-barre {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--espace-4); flex-wrap: wrap;
}
.aw-vues { display: flex; gap: var(--espace-1); background: var(--bg-input); border-radius: var(--radius-sm); padding: 2px; }
.aw-vue {
  padding: var(--espace-1) var(--espace-4); border-radius: var(--radius-xs);
  font-size: var(--texte-2); color: var(--t-dim); background: none; border: none; cursor: pointer;
}
.aw-vue.est-prise { background: var(--bg-primary); color: var(--t-primary); font-weight: 600; }
.aw-barre-d { display: flex; align-items: center; gap: var(--espace-3); flex-wrap: wrap; }
.aw-finies {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  background: none; border: none; color: var(--t-dim); font-size: var(--texte-2); cursor: pointer;
}
.aw-finies-n { color: var(--t-faint); }
.aw-cherche {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  padding: var(--espace-1) var(--espace-3); min-width: 15rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-primary);
}
.aw-cherche > svg { width: .9rem; height: .9rem; color: var(--t-faint); flex-shrink: 0; }
.aw-cherche > input { flex: 1; min-width: 0; border: none; background: none; color: var(--t-primary); font-size: var(--texte-2); }
.aw-cherche > input:focus { outline: none; }
.aw-masquees { padding: var(--espace-8) 0; text-align: center; font-size: var(--texte-2); color: var(--t-faint); }

/* ── LE CALENDRIER, EN QUATRE VUES (src/crea-autowork.js) ────────────────
   « Il ne permet pas de voir les réalités d'une tâche sur l'année, sur le mois,
   selon l'heure. » Un en-tête commun — les flèches, le titre de la période, les
   quatre vues — puis la vue elle-même. L'ancienne bande d'une semaine et sa
   liste de jours sont parties avec le reste : elles ne montraient qu'un
   rendez-vous par cadence. */
.aw-cal { display: flex; flex-direction: column; gap: var(--espace-3); }
.aw-cal-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-3); flex-wrap: wrap; }
.aw-cal-nav { display: flex; align-items: center; gap: var(--espace-2); min-width: 0; }
.aw-cal-fl {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.75rem; height: 1.75rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: none; color: var(--t-dim);
  font-size: var(--texte-4); line-height: 1; cursor: pointer;
  transition: color var(--duree-1) var(--courbe);
}
.aw-cal-fl:hover { color: var(--t-primary); }
.aw-cal-auj {
  padding: var(--espace-1) var(--espace-3); border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: none; color: var(--t-secondary);
  font-size: var(--texte-2); cursor: pointer; white-space: nowrap;
  transition: color var(--duree-1) var(--courbe);
}
.aw-cal-auj:hover { color: var(--t-primary); }
.aw-cal-titre { font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); text-transform: capitalize; }
.aw-cal-vues { display: inline-flex; gap: 2px; padding: 2px; border-radius: var(--radius-sm); background: var(--bg-secondary); }
.aw-cal-vue {
  padding: var(--espace-1) var(--espace-3); border: none; border-radius: var(--radius-xs);
  background: none; color: var(--t-dim); font-size: var(--texte-2); cursor: pointer;
  transition: color var(--duree-1) var(--courbe);
}
.aw-cal-vue.est-prise { background: var(--bg-primary); color: var(--t-primary); box-shadow: var(--ombre-1); }

/* LE CRÉNEAU CLIQUÉ, ET LE CHOIX DU LIEU. Sous l'en-tête plutôt que collé à la
   case : un panneau posé dans une grille se ferait couper par le débordement de
   sa colonne, et on lirait un menu à moitié. */
.aw-cre {
  display: flex; align-items: center; gap: var(--espace-2); flex-wrap: wrap;
  padding: var(--espace-2) var(--espace-3); border: 1px solid var(--accent);
  border-radius: var(--radius-sm); background: var(--bg-secondary);
}
.aw-cre-quand { font-size: var(--texte-2); color: var(--t-primary); margin-right: auto; }
.aw-cre-choix {
  display: inline-flex; align-items: center; gap: var(--espace-1);
  padding: var(--espace-1) var(--espace-3); border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg-primary);
  color: var(--t-primary); font-size: var(--texte-2); cursor: pointer;
  transition: color var(--duree-1) var(--courbe);
}
.aw-cre-choix:hover { color: var(--accent); }
.aw-cre-ic { display: inline-flex; }
.aw-cre-ic svg { width: 14px; height: 14px; }
.aw-cre-x { background: none; border: none; color: var(--t-faint); font-size: var(--texte-4); line-height: 1; cursor: pointer; }

/* UNE PUCE D'ÉVÈNEMENT — la même dans les quatre vues. Ce qui est passé perd sa
   couleur : il ne se lit pas comme un rendez-vous à tenir. */
.aw-evt {
  display: flex; align-items: baseline; gap: var(--espace-1); width: 100%;
  padding: 1px var(--espace-1); border: none; border-radius: var(--radius-xs);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--t-primary); font-size: var(--texte-1); text-align: left; cursor: pointer;
  overflow: hidden; transition: color var(--duree-1) var(--courbe);
}
.aw-evt:hover { color: var(--accent); }
.aw-evt.est-passe { background: var(--bg-input); color: var(--t-dim); }
.aw-evt.est-echec { background: color-mix(in srgb, var(--danger) 18%, transparent); color: var(--danger); }
.aw-evt-h { flex-shrink: 0; opacity: .7; font-variant-numeric: tabular-nums; }
.aw-evt-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── LA GRILLE HORAIRE : semaine (sept colonnes) et jour (une seule) ──── */
.aw-gr-tete { display: grid; grid-template-columns: 3.25rem repeat(7, 1fr); gap: 1px; }
.aw-cal.a-jour .aw-gr-tete { grid-template-columns: 3.25rem 1fr; }
.aw-gr-jour {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: var(--espace-2) 0; border: none; border-radius: var(--radius-sm);
  background: none; cursor: pointer; transition: color var(--duree-1) var(--courbe);
}
.aw-gr-jour:hover { color: var(--accent); }
.aw-gr-jn { font-size: var(--texte-1); color: var(--t-faint); letter-spacing: .04em; }
.aw-gr-jd { font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); }
.aw-gr-jour.est-aujourdhui .aw-gr-jd { color: var(--accent); }
.aw-gr {
  max-height: 32rem; overflow-y: auto;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.aw-gr-ligne { display: grid; grid-template-columns: 3.25rem repeat(7, 1fr); gap: 1px; }
.aw-cal.a-jour .aw-gr-ligne { grid-template-columns: 3.25rem 1fr; }
.aw-gr-h {
  padding: var(--espace-1) var(--espace-2); text-align: right;
  font-size: var(--texte-1); color: var(--t-faint); font-variant-numeric: tabular-nums;
  border-top: 1px solid var(--border);
}
.aw-gr-case {
  min-height: 2.25rem; padding: 2px; display: flex; flex-direction: column; gap: 1px;
  border-top: 1px solid var(--border); border-left: 1px solid var(--border);
  cursor: pointer; transition: background var(--duree-1) var(--courbe);
}
.aw-gr-case:hover { background: var(--bg-secondary); }
.aw-gr-case.est-maintenant { background: color-mix(in srgb, var(--accent) 8%, transparent); }

/* ── LA GRILLE DU MOIS ─────────────────────────────────────────────────── */
.aw-mo-tete { display: grid; grid-template-columns: repeat(7, 1fr); }
.aw-mo-nom { padding: var(--espace-1) var(--espace-2); font-size: var(--texte-1); color: var(--t-faint); letter-spacing: .04em; }
.aw-mo {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px;
  border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden;
}
.aw-mo-case {
  min-height: 5.5rem; padding: var(--espace-1); display: flex; flex-direction: column; gap: 1px;
  border-top: 1px solid var(--border); border-left: 1px solid var(--border);
  cursor: pointer; transition: background var(--duree-1) var(--courbe);
}
.aw-mo-case:hover { background: var(--bg-secondary); }
.aw-mo-case.est-hors { background: var(--bg-secondary); }
.aw-mo-case.est-hors .aw-mo-num { color: var(--t-faint); }
.aw-mo-num { font-size: var(--texte-2); color: var(--t-dim); }
.aw-mo-case.est-aujourdhui .aw-mo-num { color: var(--accent); font-weight: 600; }
.aw-mo-plus { background: none; border: none; padding: 0 var(--espace-1); color: var(--t-faint); font-size: var(--texte-1); text-align: left; cursor: pointer; }

/* ── LA VUE ANNÉE : douze mini-mois, un point par jour occupé ──────────── */
.aw-an { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--espace-4); }
@media (max-width: 1100px) { .aw-an { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .aw-an { grid-template-columns: 1fr; } }
.aw-an-mois { display: flex; flex-direction: column; gap: var(--espace-1); min-width: 0; }
.aw-an-nom {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--espace-2);
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--t-primary); font-size: var(--texte-2); font-weight: 500;
  transition: color var(--duree-1) var(--courbe);
}
.aw-an-nom:hover { color: var(--accent); }
.aw-an-compte { font-size: var(--texte-1); font-weight: 400; color: var(--t-faint); }
.aw-an-grille { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; }
.aw-an-j {
  aspect-ratio: 1; display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: var(--radius-rond); background: none;
  color: var(--t-dim); font-size: var(--texte-1); cursor: pointer;
  font-variant-numeric: tabular-nums;
  transition: color var(--duree-1) var(--courbe);
}
.aw-an-j:hover { color: var(--accent); }
.aw-an-j.est-hors { visibility: hidden; pointer-events: none; }
.aw-an-j.est-plein { background: color-mix(in srgb, var(--accent) 20%, transparent); color: var(--t-primary); }
.aw-an-j.est-aujourdhui { outline: 1px solid var(--accent); }

/* ── LA PAGE D'UNE CADENCE (src/crea-autowork.js) ─────────────────────────
   Sa dernière capture : un fil, une ligne d'état, deux colonnes de cartes.
   ELLE REMPLACE LE TIROIR LATÉRAL — un panneau de 20 rem qui glissait
   par-dessus la liste, où la configuration ne tenait pas. Ses règles sont
   parties avec lui : les garder aurait laissé deux mises en page pour une
   seule information. */
.aw-fiche { display: flex; flex-direction: column; gap: var(--espace-4); }
.aw-fiche-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-3); flex-wrap: wrap; }
.aw-fiche-fil { display: flex; align-items: center; gap: var(--espace-1); font-size: var(--texte-4); color: var(--t-primary); min-width: 0; }
.aw-fiche-retour {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--t-faint); font-size: var(--texte-4);
  transition: color var(--duree-1) var(--courbe);
}
.aw-fiche-retour:hover { color: var(--t-secondary); }
.aw-fiche-fil span { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aw-fiche-actions { display: flex; align-items: center; gap: var(--espace-2); flex-shrink: 0; }
.aw-fiche-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: none; color: var(--t-dim); cursor: pointer;
  transition: color var(--duree-1) var(--courbe);
}
.aw-fiche-ic:hover { color: var(--t-primary); }
/* CHAQUE PORTE-ICÔNE DIT SA TAILLE. Un `<svg viewBox>` sans largeur prend
   celle de son parent : la petite horloge du rendez-vous s'affichait à 200 px
   au milieu de la carte. Rien dans la feuille ne borne les svg globalement —
   et c'est voulu, chaque endroit a sa mesure. */
.aw-fiche-ic svg { width: 15px; height: 15px; }
.aw-fiche-lancer {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  padding: var(--espace-2) var(--espace-3); border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg-secondary);
  color: var(--t-primary); font-size: var(--texte-2); cursor: pointer;
  white-space: nowrap;
  transition: color var(--duree-1) var(--courbe);
}
.aw-fiche-lancer:hover { color: var(--accent); }
.aw-fiche-lancer svg { width: 13px; height: 13px; flex-shrink: 0; }
.aw-fiche-etat { display: flex; align-items: center; gap: var(--espace-3); flex-wrap: wrap; }
.aw-fiche-puce { width: .45rem; height: .45rem; border-radius: var(--radius-rond); background: var(--t-faint); flex-shrink: 0; }
.aw-fiche-puce.est-actif { background: var(--success); }
.aw-fiche-puce.est-pause { background: var(--warn); }
.aw-fiche-puce.est-finie { background: var(--t-faint); }
.aw-fiche-puce.est-arret { background: var(--danger); }
.aw-fiche-mot { font-size: var(--texte-2); color: var(--t-primary); }
.aw-fiche-lieu {
  padding: 1px var(--espace-2); border-radius: var(--radius-xs);
  background: var(--bg-input); color: var(--t-dim); font-size: var(--texte-1);
}
.aw-fiche-fait { font-size: var(--texte-2); color: var(--t-faint); }

/* DEUX COLONNES QUAND IL Y A LA PLACE, UNE SEULE SINON. La configuration à
   gauche, les exécutions à droite : c'est l'ordre de lecture de sa capture. */
.aw-fiche-cols { display: grid; grid-template-columns: 1fr 1fr; gap: var(--espace-4); align-items: start; }
@media (max-width: 1100px) { .aw-fiche-cols { grid-template-columns: 1fr; } }
.aw-fiche-col { display: flex; flex-direction: column; gap: var(--espace-2); min-width: 0; }
.aw-fiche-col-nom { font-size: var(--texte-1); color: var(--t-faint); }
.aw-fiche-carte {
  display: flex; flex-direction: column; gap: var(--espace-2);
  padding: var(--espace-3); border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--bg-secondary);
}
.aw-fiche-rang { display: flex; align-items: center; gap: var(--espace-2); flex-wrap: wrap; }
.aw-fiche-cle { font-size: var(--texte-2); color: var(--t-dim); }
.aw-fiche-val { display: inline-flex; align-items: center; gap: var(--espace-1); font-size: var(--texte-2); color: var(--t-primary); margin-right: auto; }
.aw-fiche-val svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--t-faint); }
.aw-fiche-quoi { font-size: var(--texte-2); color: var(--t-dim); margin-right: auto; min-width: 0; }
.aw-fiche-modif {
  display: inline-flex; align-items: center; gap: var(--espace-1);
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--t-faint); font-size: var(--texte-2); flex-shrink: 0;
  margin-left: auto;
  transition: color var(--duree-1) var(--courbe);
}
.aw-fiche-modif:hover { color: var(--accent); }
.aw-fiche-modif svg { width: 13px; height: 13px; }
.aw-fiche-instr { font-size: var(--texte-2); color: var(--t-secondary); white-space: pre-wrap; }
/* CONSOMMATION, CHAÎNE, MODIFICATIONS PRENNENT LA MÊME CARTE. Ces trois blocs
   viennent du tiroir, où ils flottaient sur le fond du panneau ; posés tels
   quels dans une colonne, ils se lisaient comme du texte oublié entre deux
   cartes. */
.aw-fiche-col > .aw-bu,
.aw-fiche-col > .aw-ch,
.aw-fiche-col > .aw-hi {
  padding: var(--espace-3); border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--bg-secondary);
}
.aw-fiche-col > .aw-bu > .aw-pan-section,
.aw-fiche-col > .aw-ch > .aw-pan-section,
.aw-fiche-col > .aw-hi > .aw-pan-section { margin-top: 0; margin-bottom: var(--espace-2); }
.aw-pan-section { font-size: var(--texte-1); color: var(--t-faint); margin-top: var(--espace-3); }

/* ── CE QUI ENCADRE LA ROUTINE, DANS SON PANNEAU ──────────────────────────
   Le frein, la consommation, la trace. Le frein porte sa couleur : un plafond
   atteint n'est pas une panne — c'est une borne qui a fonctionné. */
.aw-frein {
  display: flex; gap: var(--espace-2); align-items: flex-start;
  margin-top: var(--espace-3); padding: var(--espace-3);
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--bg-secondary); font-size: var(--texte-2); color: var(--t-secondary);
}
.aw-frein-puce { width: .45rem; height: .45rem; border-radius: var(--radius-rond); background: var(--t-faint); margin-top: .35rem; flex-shrink: 0; }
.aw-frein.est-plafond .aw-frein-puce { background: var(--warn); }
.aw-frein.est-arret-auto .aw-frein-puce { background: var(--danger); }
.aw-frein-note { margin-top: var(--espace-1); font-size: var(--texte-1); color: var(--t-faint); }
.aw-bu-ligne { font-size: var(--texte-2); color: var(--t-dim); }
.aw-bu-fort { color: var(--t-primary); font-weight: 500; }
.aw-bu-muet { color: var(--t-faint); }
.aw-hi-l { padding: var(--espace-2) 0; border-top: 1px solid var(--border); }
.aw-hi-quoi { font-size: var(--texte-2); color: var(--t-secondary); }
.aw-hi-l.est-auto .aw-hi-quoi { color: var(--t-dim); }
.aw-hi-val { color: var(--t-faint); }
.aw-hi-qui { font-size: var(--texte-1); color: var(--t-faint); margin-top: .1rem; }
.aw-ch-l { font-size: var(--texte-2); color: var(--t-dim); }
.aw-ch-nom { color: var(--t-secondary); }
.aw-ex-chaine { font-size: var(--texte-1); color: var(--t-faint); }
/* CE QUI SORT DE L'ORDINAIRE SE VOIT. Un lancement à la main au milieu de six
   rendez-vous de 4 h 06 est l'information qu'on cherche en lisant la liste. */
.aw-ex-origine {
  padding: 0 var(--espace-2); border-radius: var(--radius-xs);
  background: var(--bg-input); color: var(--t-dim); font-size: var(--texte-1);
}
.aw-pan-ou { font-size: var(--texte-1); margin-top: .15rem; }
.aw-pan-ou.est-serveur { color: var(--success); }
.aw-pan-ou.est-onglet { color: var(--warn); }
.aw-pan-vide { font-size: var(--texte-2); color: var(--t-faint); }
.aw-ex { display: flex; gap: var(--espace-3); padding: var(--espace-3); border-radius: var(--radius-sm); background: var(--bg-secondary); }
.aw-ex-puce { width: .4rem; height: .4rem; border-radius: var(--radius-rond); background: var(--t-faint); margin-top: .45rem; flex-shrink: 0; }
.aw-ex.est-encours .aw-ex-puce { background: var(--accent); }
.aw-ex.est-echec .aw-ex-puce { background: var(--danger); }
.aw-ex-corps { min-width: 0; flex: 1; }
.aw-ex-quand { font-size: var(--texte-2); color: var(--t-primary); }
.aw-ex-etat { font-size: var(--texte-1); color: var(--t-dim); }
.aw-ex.est-echec .aw-ex-etat { color: var(--danger); }
/* CE À QUOI UNE EXÉCUTION A EU DROIT, et par où on a prévenu. Discret : c'est
   une pièce à conviction, pas une information de première lecture. */
.aw-ex-acces { font-size: var(--texte-1); color: var(--t-dim); margin-top: 2px; line-height: 1.45; }
.aw-ex-sortie { margin-top: var(--espace-2); font-size: var(--texte-1); color: var(--t-secondary); }
.aw-ex-sortie > p { margin-top: var(--espace-1); white-space: pre-wrap; }
.aw-details { background: none; border: none; color: var(--t-dim); font-size: var(--texte-2); cursor: pointer; }

/* ══ LE PANNEAU « EXÉCUTIONS », À CÔTÉ DU FIL D'UNE ROUTINE ═════════════════
 *
 * « Sa page n'est pas QUE un fil. Sur le côté, il y a un système de comment il
 *  organisait ses propres sessions internes. »
 *
 * Sa photo : un en-tête « Exécutions » avec ses deux gestes, le nom de la
 * routine avec son badge de lieu et « Détails », le rendez-vous en clair, puis
 * deux groupes — « En cours », « Terminé.e.s ».
 *
 * LES LIGNES SONT CELLES DE LA FICHE, à l'identique (`.aw-ex`). Elles étaient
 * justes ; c'est leur ENDROIT qui ne l'était pas. En redessiner une seconde
 * paire ici les aurait fait diverger au premier changement. */
.awx { overflow-y: auto; padding: var(--espace-4); gap: var(--espace-2); }
.awx-tete { display: flex; align-items: center; gap: var(--espace-2); }
.awx-titre { flex: 1; font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); }
.awx-gestes { display: flex; gap: var(--espace-1); }
.awx-geste {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.75rem; height: 1.75rem; border: none; background: none;
  border-radius: var(--radius-sm); color: var(--t-dim); cursor: pointer;
}
/* `--survol` N'EXISTE PAS DANS CE DÉPÔT — `frontend-coherence-smoke` l'a vu.
   Le jeton du survol y est `--bg-secondary`, employé cent quarante-trois fois. */
.awx-geste:hover { background: var(--bg-secondary); color: var(--t-primary); }
.awx-geste svg { width: 14px; height: 14px; }

/* LA COIFFE — ce qu'on veut savoir AVANT de lire la liste : de quelle routine
   il s'agit, où elle tourne, et à quelle heure elle a rendez-vous. Sans cette
   dernière ligne, six « 4 h 06 » de suite ne veulent rien dire. */
.awx-coiffe { margin-top: var(--espace-2); }
.awx-coiffe-haut { display: flex; align-items: center; gap: var(--espace-2); }
.awx-nom { font-size: var(--texte-2); font-weight: 600; color: var(--t-primary); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.awx-lieu {
  display: inline-flex; align-items: center; gap: var(--espace-1); flex: none;
  padding: 1px var(--espace-2); border-radius: var(--radius-sm);
  border: 1px solid var(--border); font-size: var(--texte-1); color: var(--t-dim);
}
.awx-lieu svg { width: 11px; height: 11px; }
.awx-lieu.est-nuage { color: var(--accent); border-color: var(--accent); }
.awx-details { margin-left: auto; flex: none; background: none; border: none; color: var(--t-dim); font-size: var(--texte-1); cursor: pointer; }
.awx-details:hover { color: var(--t-primary); text-decoration: underline; }
.awx-quand { margin-top: 2px; font-size: var(--texte-1); color: var(--t-dim); }

/* LES DEUX GROUPES. « Terminé.e.s » est le mot de sa photo, et il dit autre
   chose que « déclenchements récents » : un déclenchement est un départ, une
   terminaison est un verdict. */
.awx-section { margin-top: var(--espace-4); margin-bottom: var(--espace-2); font-size: var(--texte-1); font-weight: 600; color: var(--t-dim); }
.awx .aw-ex { margin-bottom: var(--espace-2); }
.awx-vide { font-size: var(--texte-1); color: var(--t-faint); }

/* ═══════════════════════════════════════════════════════════════════════════
 * LES TÂCHES DE FOND — LA CARTE, ET LE FIL DANS LA CONVERSATION
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * L'ANCIENNE CARTE EMPILAIT QUATRE SÉPARATIONS pour délimiter une seule chose :
 * une bordure, un fond différent du panneau, un filet plein sous l'en-tête, un
 * filet POINTILLÉ sous la pensée. Quatre traits pour dire « ceci est une
 * tâche », et à six tâches le panneau devenait une grille de cases.
 *
 * ICI, UNE SEULE : le fond. La carte se détache par sa surface, pas par son
 * contour, et les étages internes se séparent par de l'ESPACE. C'est la même
 * grammaire que les étapes du chat (`crea-step-*`) — un panneau qui se lit
 * comme la conversation, au lieu d'être une deuxième langue à apprendre.
 */
.crea-tache {
  background: var(--bg-secondary);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: background var(--duree-1) var(--courbe);
}
.crea-tache[data-etat="running"] {
  /* CE QUI TRAVAILLE SE SIGNALE PAR UN LISERÉ, pas par une bordure complète :
     entourer la carte la ferait sauter en avant-plan à chaque changement
     d'état, et le panneau clignoterait pendant qu'on le lit. */
  box-shadow: inset 2px 0 0 var(--accent);
}
.crea-tache[data-etat="error"] { box-shadow: inset 2px 0 0 var(--danger); }

.crea-tache-tete {
  display: flex; align-items: center; gap: .5rem;
  padding: .5rem .625rem;
  cursor: pointer; user-select: none; list-style: none; outline: none;
}
.crea-tache-tete::-webkit-details-marker { display: none; }
.crea-tache-tete:hover { background: color-mix(in srgb, var(--t-primary) 4%, transparent); }
.crea-tache-tete:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.crea-tache-dot { width: 6px; height: 6px; border-radius: var(--radius-rond); flex-shrink: 0; }
.crea-tache-dot--mini { width: 4px; height: 4px; border-radius: var(--radius-rond); flex-shrink: 0; }

/* DEUX LIGNES DANS LA LIGNE REPLIÉE : l'intitulé, et ce qui se passe dessous.
   La pensée vivante était derrière un clic — c'est pourtant la seule chose
   qu'on vient chercher quand on ouvre le panneau. */
.crea-tache-corps { display: flex; flex-direction: column; gap: .1rem; flex: 1; min-width: 0; }
.crea-tache-titre {
  font-size: var(--texte-3); font-weight: 600; color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.crea-tache-pensee {
  font-size: var(--texte-1); color: var(--accent);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* L'APERÇU D'UNE TÂCHE REPLIÉE EST LU, pas deviné : c'est la seule chose
   qu'une tâche finie dit d'elle sans qu'on l'ouvre. En `--t-faint` (#555 sur
   #1E1E1E) il fallait s'approcher de l'écran — mesuré au rendu, pas supposé. */
.crea-tache-pensee.est-calme { color: var(--t-dim); }
.crea-tache-horo {
  font-size: var(--texte-1); color: var(--t-faint); flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
.crea-tache-chev { width: 12px; height: 12px; flex-shrink: 0; color: var(--t-faint); opacity: .55; }

.crea-tache-pli { padding: 0 .625rem .625rem; display: flex; flex-direction: column; gap: .625rem; }
.crea-tache-chips { display: flex; flex-wrap: wrap; gap: .25rem; }
.crea-tache-chip {
  font-size: var(--texte-1); color: var(--t-faint);
  background: var(--bg-input); border-radius: var(--radius-xs);
  padding: .05rem .375rem; font-variant-numeric: tabular-nums;
}
/* LA PORTÉE N'EST PAS UNE ÉTIQUETTE COMME LES AUTRES. « lecture seule » change
   ce que la tâche POUVAIT faire ; la noyer parmi le modèle et le compte
   d'étapes reviendrait à ne pas la dire. */
.crea-tache-chip.est-portee { color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }

.crea-tache-bloc { display: flex; flex-direction: column; gap: .2rem; }
.crea-tache-etiq {
  font-size: var(--texte-1); color: var(--t-dim);
  text-transform: uppercase; letter-spacing: .04em;
}
.crea-tache-consigne {
  font-size: var(--texte-2); color: var(--t-secondary);
  white-space: pre-wrap; word-break: break-word;
  /* LA CONSIGNE EST UNE CITATION : c'est le texte de quelqu'un d'autre, pas
     une phrase du panneau. Le filet à gauche le dit sans un mot. */
  border-left: 2px solid var(--border); padding-left: .5rem;
}
.crea-tache-result {
  font-size: var(--texte-2); color: var(--t-secondary);
  white-space: pre-wrap; word-break: break-word;
}
.crea-tache-etapes { display: flex; flex-direction: column; gap: .1rem; }
.crea-tache-etape { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.crea-tache-etape-n {
  font-size: var(--texte-1); color: var(--t-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.crea-tache-verbes { display: flex; flex-wrap: wrap; gap: .375rem; }
.crea-tache-verbe {
  font-size: var(--texte-1); color: var(--t-secondary);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: .15rem .5rem; background: none; cursor: pointer;
  /* UNE SEULE DURÉE, ÉNONCÉE UNE FOIS. Les deux propriétés bougent ensemble ;
     les écrire en deux temps ajoutait une cinquantième valeur distincte au
     vocabulaire du mouvement — et le cliquet `matiere-visuelle` a raison :
     une de plus n'est pas une dérive de plus, c'est celle qui rend la
     suivante normale. */
  transition: color var(--duree-1) var(--courbe);
  transition-property: color, border-color;
}
.crea-tache-verbe:hover { border-color: var(--t-faint); color: var(--t-primary); }
.crea-tache-verbe.est-danger:hover { border-color: var(--danger); color: var(--danger); }

.crea-tache-reste {
  font-size: var(--texte-1); color: var(--t-dim);
  padding: .375rem .25rem; text-align: center;
}

/* ── LE FIL D'UNE ÉQUIPE, DANS LA CONVERSATION ─────────────────────────────
 *
 * Il vit à l'intérieur d'une étape du chat, pas dans le panneau : il doit donc
 * se taire visuellement. Pas de fond, pas de bordure — un simple retrait, et
 * les mêmes points que partout ailleurs. */
.crea-equipe-fil { display: flex; flex-direction: column; gap: .15rem; padding: .25rem 0; }
.crea-equipe-fil-h {
  font-size: var(--texte-1); color: var(--t-faint);
  font-variant-numeric: tabular-nums; margin-bottom: .15rem;
}
.crea-equipe-fil-l { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.crea-equipe-fil-p { width: 5px; height: 5px; border-radius: var(--radius-rond); flex-shrink: 0; }
.crea-equipe-fil-n {
  font-size: var(--texte-1); color: var(--t-secondary); flex-shrink: 0;
  max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.crea-equipe-fil-t {
  font-size: var(--texte-1); color: var(--t-dim); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .crea-tache-dot, .crea-tache-dot--mini, .crea-equipe-fil-p { animation: none; }
}

/* L'ÉQUIPE SE LIT COMME SES MEMBRES. Le bloc était écrit en utilitaires pendant
   que la carte vivait dans cette feuille : deux langues dans le même panneau,
   qui n'avaient aucune chance de s'accorder sur une taille ou un espacement.
   Il n'entoure plus d'une bordure pleine — un liseré à gauche, comme une tâche
   en cours, parce qu'une équipe EST un groupe de tâches, pas un autre objet. */
.crea-equipe {
  background: color-mix(in srgb, var(--t-primary) 3%, transparent);
  border-radius: var(--radius-lg);
  box-shadow: inset 2px 0 0 var(--border);
  overflow: hidden;
}
.crea-equipe.est-actif { box-shadow: inset 2px 0 0 var(--accent); }
.crea-equipe.est-echec { box-shadow: inset 2px 0 0 var(--danger); }
.crea-equipe-tete { display: flex; align-items: center; gap: .4rem; padding: .5rem .625rem .375rem; }
.crea-equipe-n { font-size: var(--texte-2); font-weight: 600; color: var(--t-primary); }
.crea-equipe-etat { font-size: var(--texte-1); color: var(--t-faint); flex: 1; min-width: 0; }
.crea-equipe-membres { padding: 0 .375rem .375rem; display: flex; flex-direction: column; gap: .25rem; }

/* LE RENVOI D'UN MESSAGE VERS LE TRAVAIL QUI L'A PRODUIT.
   Il coiffe une livraison d'agent de fond. Il doit se voir sans peser : le
   message qu'il annonce est le contenu, lui n'est qu'une provenance. Pas de
   fond, pas de bordure pleine — un filet, et la même grammaire de points et de
   pastilles que le panneau et la frise. */
.crea-renvoi {
  display: flex; align-items: center; gap: .4rem;
  width: 100%; padding: .25rem .5rem; margin-bottom: .35rem;
  background: none; border: none; border-left: 2px solid var(--border);
  cursor: pointer; text-align: left;
  /* LA DURÉE EST DÉJÀ DITE AILLEURS. Écrire `border-color var(--duree-1)…`
     ajoutait une cinquantième valeur distincte au vocabulaire du mouvement,
     pour un geste identique aux quinze autres. On reprend la chaîne qui
     existe, et on nomme la propriété à part. */
  transition: color var(--duree-1) var(--courbe);
  transition-property: border-left-color;
}
.crea-renvoi:hover { border-left-color: var(--accent); }
.crea-renvoi:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.crea-renvoi-n {
  font-size: var(--texte-1); color: var(--t-dim); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.crea-renvoi-v { font-size: var(--texte-1); color: var(--t-faint); margin-left: auto; flex-shrink: 0; }
.crea-renvoi:hover .crea-renvoi-v { color: var(--accent); }

/* UN RENVOI DONT LA TÂCHE A ÉTÉ EFFACÉE. Il dit encore d'où vient le résultat —
   c'est la seule chose qui le dise depuis que la livraison n'a plus d'en-tête —
   mais il n'ouvre rien, et il ne doit pas faire semblant : pas de curseur, pas
   de survol qui promette un geste. */
.crea-renvoi.est-clos { cursor: default; }
.crea-renvoi.est-clos:hover { border-left-color: var(--border); }
.crea-renvoi.est-clos .crea-renvoi-v { color: var(--t-faint); }
.crea-renvoi.est-clos:hover .crea-renvoi-v { color: var(--t-faint); }

/* CHERCHER ET FILTRER DANS LES TÂCHES. La barre coiffe la liste sans la
   séparer : c'est un outil de lecture, pas une section. */
.crea-taches-filtres { display: flex; flex-direction: column; gap: .375rem; margin-bottom: .25rem; }
.crea-taches-champ {
  width: 100%; padding: .35rem .55rem;
  font-size: var(--texte-2); color: var(--t-primary);
  background: var(--bg-secondary); border: 1px solid var(--border);
  border-radius: var(--radius-sm); outline: none;
  transition: color var(--duree-1) var(--courbe);
  transition-property: border-color;
}
.crea-taches-champ::placeholder { color: var(--t-dim); }
.crea-taches-champ:focus { border-color: var(--accent); }
.crea-taches-onglets { display: flex; flex-wrap: wrap; gap: .25rem; }
.crea-taches-onglet {
  display: inline-flex; align-items: center; gap: .25rem;
  font-size: var(--texte-1); color: var(--t-dim);
  background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
  padding: .1rem .4rem; cursor: pointer;
  transition: color var(--duree-1) var(--courbe);
  transition-property: color, border-color;
}
.crea-taches-onglet:hover { color: var(--t-primary); }
.crea-taches-onglet.est-actif { color: var(--accent); border-color: var(--accent); }

/* « Trier » précède ses onglets : sans ce mot, la seconde rangée de pastilles
   se lit comme une suite de filtres, et « Durée » passe pour une origine. */
.crea-taches-tri-etiq {
  font-size: var(--texte-1); color: var(--t-dim);
  align-self: center; margin-right: .15rem;
}

/* CE QUI TRAVAILLE SUR UN JALON. Même grammaire que le fil d'équipe — un point,
   une pensée, un compte — parce que c'est la même chose : un agent au travail.
   Le verbe d'arrêt ferme la ligne : un jalon parti de travers doit pouvoir être
   coupé d'ici, sans passer par le panneau. */
.crea-jalon-agent { display: flex; align-items: center; gap: .4rem; min-width: 0; margin-top: .25rem; }
.crea-jalon-agent-t {
  font-size: var(--texte-2); color: var(--accent); min-width: 0; flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════════════
   LA FUSION RÉSEAU · MISSIONS · COMMUNAUTÉ
   ══════════════════════════════════════════════════════════════════════════

   Trois espaces qui se répondent, donc UNE seule grammaire visuelle. Elle
   tient en cinq briques, et tout le reste s'y raccroche :

     .*-carte      un objet qu'on peut prendre — fond secondaire, bordure, rayon
     .*-primaire   le geste principal, plein, teinte d'accent
     .*-plat       le geste secondaire, cerclé, sans fond
     .*-puce       un filtre — pilule, deux états
     .*-vide       ce qui reste quand il n'y a rien, avec la sortie à côté

   Les préfixes séparent les portées (rz = réseau, ms = missions,
   cm = communauté, dc = découvrir des espaces, pt = poste) : les modules
   posent leur HTML dans le même document, et une classe partagée aurait fait
   qu'un ajustement dans l'un déplacerait l'autre sans qu'on le voie.

   TOUT PASSE PAR LES JETONS. Une couleur écrite en dur ici serait juste en
   thème clair et fausse en sombre — la feuille bascule les jetons, pas les
   règles.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Le socle commun aux trois espaces ─────────────────────────────────── */
.rz-carte, .ms-carte, .cm-carte {
  background: var(--bg-secondary); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.rz-primaire, .ms-primaire, .cm-primaire {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  background: var(--accent); color: #fff; border: none;
  border-radius: var(--radius-rond); padding: var(--espace-4) var(--espace-8);
  font-size: var(--texte-4); font-weight: 600; cursor: pointer;
  transition: opacity var(--duree-1) var(--courbe);
}
.rz-primaire:hover, .ms-primaire:hover, .cm-primaire:hover { opacity: .88; }
.rz-plat, .ms-plat, .cm-plat {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  background: transparent; color: var(--t-secondary);
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  padding: var(--espace-3) var(--espace-7);
  font-size: var(--texte-4); font-weight: 500; cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.rz-plat:hover, .ms-plat:hover, .cm-plat:hover { color: var(--t-primary); border-color: var(--t-faint); }
.rz-plat-mini, .ms-plat-mini, .cm-mini, .rz-primaire-mini, .ms-icone, .cm-icone, .rz-icone {
  font-size: var(--texte-2);
}
.rz-plat-mini, .ms-plat-mini, .cm-mini { padding: var(--espace-2) var(--espace-5); }
.rz-primaire-mini { padding: var(--espace-3) var(--espace-6); font-size: var(--texte-3); }
.rz-icone, .ms-icone, .cm-icone {
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; color: var(--t-faint);
  padding: var(--espace-2); border-radius: var(--radius-sm); cursor: pointer;
  transition: color var(--duree-1) var(--courbe);
}
.rz-icone:hover, .ms-icone:hover { color: var(--t-primary); }
.cm-icone:hover { color: var(--danger); }
.rz-puce, .ms-puce, .cm-puce {
  background: var(--bg-input); color: var(--t-dim);
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  padding: var(--espace-2) var(--espace-6);
  font-size: var(--texte-2); font-weight: 500; cursor: pointer; white-space: nowrap;
  transition: all var(--duree-1) var(--courbe);
}
.rz-puce.on, .ms-puce.on, .cm-puce.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.rz-puce-inerte, .ms-puce-inerte { cursor: default; }
.rz-vide, .ms-vide, .cm-vide {
  display: flex; flex-direction: column; align-items: center; gap: var(--espace-5);
  text-align: center; padding: var(--espace-10) var(--espace-8);
  color: var(--t-dim);
}
.ms-vide, .cm-vide { background: var(--bg-secondary); border: 1px dashed var(--border); border-radius: var(--radius-lg); }
.rz-vide p:first-child, .ms-vide-titre, .cm-vide-titre {
  font-size: var(--texte-6); font-weight: 600; color: var(--t-primary); margin: 0;
}
.rz-vide-sous, .ms-vide-sous, .cm-vide-sous {
  font-size: var(--texte-3); color: var(--t-faint); max-width: 46ch; margin: 0; line-height: 1.55;
}
.rz-vide-mini, .cm-vide-mini { font-size: var(--texte-3); color: var(--t-faint); margin: var(--espace-3) 0; }
.rz-champ, .ms-formulaire input, .ms-formulaire textarea, .ms-formulaire select,
.rz-recherche input, .ms-recherche input, .cm-reponse-saisie input {
  width: 100%; background: var(--bg-input); color: var(--t-primary);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--espace-4) var(--espace-6); font-size: var(--texte-4);
  outline: none; font-family: inherit;
}
.rz-champ:focus, .ms-formulaire input:focus, .ms-formulaire textarea:focus { border-color: var(--accent); }
.rz-zone { resize: vertical; }
.rz-mono { font-family: var(--police-mono, monospace); font-size: var(--texte-3); }
.rz-badge, .cm-onglet b, .ms-onglet b {
  background: var(--accent); color: #fff; border-radius: var(--radius-rond);
  padding: 0 var(--espace-3); font-size: var(--texte-1); font-weight: 700; line-height: 1.5;
}

/* ── Les onglets d'espace ──────────────────────────────────────────────── */
.rz-onglets, .ms-onglets, .cm-onglets {
  display: flex; align-items: stretch; gap: var(--espace-2);
  padding: 0 var(--espace-8); overflow-x: auto; flex-shrink: 0;
  border-bottom: 1px solid var(--border); scrollbar-width: none;
}
.rz-onglets::-webkit-scrollbar, .ms-onglets::-webkit-scrollbar, .cm-onglets::-webkit-scrollbar { display: none; }
.rz-onglet, .cm-onglet {
  display: flex; flex-direction: column; align-items: center; gap: var(--espace-1);
  background: none; border: none; border-bottom: 2px solid transparent;
  padding: var(--espace-5) var(--espace-7) var(--espace-4);
  color: var(--t-faint); font-size: var(--texte-2); font-weight: 500;
  cursor: pointer; white-space: nowrap;
  transition: color var(--duree-1) var(--courbe);
}
.ms-onglet {
  background: none; border: none; border-bottom: 2px solid transparent;
  padding: var(--espace-5) var(--espace-7);
  color: var(--t-faint); font-size: var(--texte-4); font-weight: 500;
  cursor: pointer; white-space: nowrap;
}
.rz-onglet:hover, .ms-onglet:hover, .cm-onglet:hover { color: var(--t-secondary); }
.rz-onglet.on, .ms-onglet.on, .cm-onglet.on { color: var(--t-primary); border-bottom-color: var(--t-primary); }
.rz-onglet-sortie, .ms-onglet-sortie, .cm-onglet-sortie { margin-left: auto; color: var(--accent); }

/* ── Réseau : les trois colonnes du fil ────────────────────────────────── */
.rz-colonnes {
  display: grid; grid-template-columns: 1fr; gap: var(--espace-8);
  padding: var(--espace-8); align-items: start;
}
/* MÊME DÉFAUT QU'AU POSTE, MÊME RÉPARATION — et il fallait le réparer ici
   AUSSI : ces trois colonnes sont écrites sur le même patron, donc le rail de
   droite tombait au même endroit, en bas à gauche sous la carte d'identité,
   entre 900 et 1239 px de fenêtre. Un défaut copié se répare des deux côtés,
   sinon on croit l'avoir corrigé et il reste visible un écran plus loin. */
.rz-defilement { container-type: inline-size; }
.rz-centre { display: flex; flex-direction: column; gap: var(--espace-6); min-width: 0; }
.rz-rail { display: flex; flex-direction: column; gap: var(--espace-6); }
/* Sous 700 px d'espace, la carte d'identité et le rail passent APRÈS le fil :
   sur un téléphone, ce qu'on est venu lire doit arriver en premier. */
@container (max-width: 699px) { .rz-identite { order: 2 } .rz-centre { order: 1 } .rz-rail { order: 3 } }
@container (min-width: 700px) {
  .rz-colonnes { grid-template-columns: 250px minmax(0, 1fr); }
  .rz-identite { grid-column: 1; grid-row: 1; }
  .rz-rail     { grid-column: 1; grid-row: 2; }
  .rz-centre   { grid-column: 2; grid-row: 1 / span 2; }
}
@container (min-width: 960px) {
  .rz-colonnes { grid-template-columns: 250px minmax(0, 1fr) 300px; }
  .rz-centre { grid-column: 2; grid-row: 1; }
  .rz-rail   { grid-column: 3; grid-row: 1; }
}

.rz-identite { overflow: hidden; position: relative; }
.rz-banniere {
  height: 56px; background: linear-gradient(120deg, var(--accent), #6366f1);
  background-size: cover; background-position: center;
}
.rz-banniere-large { height: 96px; }
.rz-avatar {
  display: flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; border-radius: var(--radius-rond);
  background: var(--bg-input); border: 3px solid var(--bg-secondary);
  font-size: var(--texte-9); cursor: pointer;
  margin: -28px 0 0 var(--espace-8);
}
.rz-avatar-mini { width: 38px; height: 38px; font-size: var(--texte-7); margin: 0; border-width: 0; flex-shrink: 0; }
/* Pas de taille en pixels écrite ici : l'échelle typographique s'arrête à
   --texte-9, et un nombre choisi à l'œil est exactement ce que le cliquet de
   la matière visuelle existe pour empêcher. On MULTIPLIE le dernier barreau. */
.rz-avatar-grand { width: 78px; height: 78px; font-size: calc(var(--texte-9) * 1.7); margin: -39px 0 0 var(--espace-8); }
.rz-identite-corps { padding: var(--espace-4) var(--espace-8) var(--espace-6); }
.rz-nom { font-size: var(--texte-6); font-weight: 700; color: var(--t-primary); margin: 0; }
.rz-titre { font-size: var(--texte-3); color: var(--t-dim); margin: var(--espace-1) 0 0; line-height: 1.45; }
.rz-lieu { display: flex; align-items: center; gap: var(--espace-2); font-size: var(--texte-2); color: var(--t-faint); margin: var(--espace-3) 0 0; }
.rz-identite-chiffres { display: flex; border-top: 1px solid var(--border); }
.rz-chiffre {
  flex: 1; display: flex; align-items: center; justify-content: space-between;
  background: none; border: none; padding: var(--espace-4) var(--espace-8);
  font-size: var(--texte-2); color: var(--t-faint); cursor: pointer;
}
.rz-chiffre b { color: var(--accent); font-size: var(--texte-4); }
.rz-identite-liens { border-top: 1px solid var(--border); padding: var(--espace-3) 0; }
.rz-lien-rail {
  display: flex; align-items: center; gap: var(--espace-5); width: 100%;
  background: none; border: none; padding: var(--espace-4) var(--espace-8);
  color: var(--t-secondary); font-size: var(--texte-3); cursor: pointer;
}
.rz-lien-rail:hover { background: var(--bg-input); }
.rz-lien-rail span { flex: 1; text-align: left; }
.rz-lien-rail b { color: var(--t-faint); font-weight: 600; }

/* L'AMORCE VIT DANS LA LIGNE DES ONGLETS. Elle ne prend aucune hauteur à
   l'écran — la ligne existait — et elle reste visible sur les cinq onglets :
   on publie depuis Relations sans repasser par l'Accueil. Sous 720 px, le
   texte s'efface et il ne reste que l'avatar et le +, parce qu'à cette largeur
   c'est la place des onglets qui compte. */
.rz-amorce {
  display: flex; align-items: center; gap: var(--espace-4);
  margin: var(--espace-3) 0 var(--espace-3) auto; flex-shrink: 0;
  max-width: 300px; background: var(--bg-input); color: var(--t-dim);
  border: 1px solid var(--border); border-radius: var(--radius-rond);
  padding: var(--espace-2) var(--espace-6) var(--espace-2) var(--espace-2);
  font-size: var(--texte-3); cursor: pointer; white-space: nowrap;
  transition: all var(--duree-1) var(--courbe);
}
.rz-amorce:hover { border-color: var(--accent); color: var(--t-secondary); }
.rz-amorce span:last-child { overflow: hidden; text-overflow: ellipsis; }
.rz-avatar-puce { width: 26px; height: 26px; font-size: var(--texte-4); margin: 0; border-width: 0; flex-shrink: 0; }
@media (max-width: 720px) { .rz-amorce span:last-child { display: none } .rz-amorce { padding-right: var(--espace-2) } }

/* La fenêtre d'écriture : la place quand on écrit, et seulement là. */
.rz-modale {
  position: fixed; inset: 0; z-index: 60; display: flex;
  align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .5); padding: var(--espace-6); overflow-y: auto;
}
.rz-compose {
  width: min(620px, 100%); max-height: 92vh; overflow-y: auto;
  background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--espace-8); display: flex; flex-direction: column; gap: var(--espace-4);
}
.rz-compose-tete { display: flex; align-items: center; gap: var(--espace-5); }
.rz-compose-qui { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rz-compose-qui b { font-size: var(--texte-4); color: var(--t-primary); }
.rz-compose-qui span { font-size: var(--texte-2); color: var(--t-faint); }
.rz-compose-types { display: flex; flex-wrap: wrap; gap: var(--espace-3); }
.rz-compose-media img { max-height: 180px; border-radius: var(--radius); }
.rz-compose-pied { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-4); }

.rz-filtres { display: flex; align-items: center; flex-wrap: wrap; gap: var(--espace-4); padding: 0 var(--espace-2); }
.rz-filtre {
  background: none; border: none; padding: var(--espace-2) 0;
  color: var(--t-faint); font-size: var(--texte-3); font-weight: 500; cursor: pointer;
  border-bottom: 2px solid transparent;
}
.rz-filtre.on { color: var(--t-primary); border-bottom-color: var(--accent); }
.rz-filtres-etat { margin-left: auto; font-size: var(--texte-1); color: var(--t-faint); }

.rz-post { padding: var(--espace-6); display: flex; flex-direction: column; gap: var(--espace-4); }
.rz-post-tete { display: flex; align-items: flex-start; gap: var(--espace-5); }
.rz-post-qui { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rz-post-qui b { font-size: var(--texte-4); color: var(--t-primary); }
.rz-post-qui span { font-size: var(--texte-2); color: var(--t-dim); }
.rz-post-qui em { font-size: var(--texte-1); color: var(--t-faint); font-style: normal; }
.rz-post-titre { font-size: var(--texte-6); font-weight: 600; color: var(--t-primary); margin: 0; }
.rz-post-texte { font-size: var(--texte-4); color: var(--t-secondary); margin: 0; white-space: pre-wrap; line-height: 1.55; }
.rz-post-media img, .rz-post-media video { width: 100%; max-height: 420px; object-fit: cover; border-radius: var(--radius); display: block; }
.rz-post-lien { display: flex; align-items: center; gap: var(--espace-3); font-size: var(--texte-3); color: var(--accent); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rz-post-compte { display: flex; gap: var(--espace-6); font-size: var(--texte-2); color: var(--t-faint); }
.rz-post-compte button { background: none; border: none; color: inherit; font-size: inherit; cursor: pointer; }
.rz-post-actions { display: flex; gap: var(--espace-2); border-top: 1px solid var(--border); padding-top: var(--espace-3); }
.rz-action {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: var(--espace-3);
  background: none; border: none; border-radius: var(--radius-sm);
  padding: var(--espace-4); color: var(--t-dim); font-size: var(--texte-3); font-weight: 500; cursor: pointer;
}
.rz-action:hover { background: var(--bg-input); color: var(--t-primary); }
.rz-action.on { color: var(--accent); }
/* LES QUATRE NUANCES SORTENT AU SURVOL, ET SEULEMENT LÀ. Toujours visibles,
   elles feraient quatre boutons là où l'usage courant en demande un. */
.rz-reaction-hote { position: relative; flex: 1; display: flex; }
.rz-reaction-choix {
  position: absolute; bottom: 100%; left: 0; display: flex; gap: var(--espace-2);
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-rond);
  padding: var(--espace-2) var(--espace-4); margin-bottom: var(--espace-2);
  opacity: 0; pointer-events: none; transform: translateY(4px);
  transition: all var(--duree-1) var(--courbe);
  z-index: 5;
}
.rz-reaction-hote:hover .rz-reaction-choix,
.rz-reaction-hote:focus-within .rz-reaction-choix { opacity: 1; pointer-events: auto; transform: translateY(0); }
.rz-reaction-choix button { background: none; border: none; font-size: var(--texte-7); cursor: pointer; line-height: 1; padding: var(--espace-1); }
.rz-reaction-choix button:hover { transform: scale(1.25); }
.rz-reaction-signe { font-size: var(--texte-5); line-height: 1; }
.rz-commentaires { border-top: 1px solid var(--border); padding-top: var(--espace-4); display: flex; flex-direction: column; gap: var(--espace-3); }
.rz-commentaire { font-size: var(--texte-3); color: var(--t-secondary); }
.rz-commentaire b { color: var(--t-primary); margin-right: var(--espace-3); }
.rz-commentaire-saisie { display: flex; gap: var(--espace-3); }

.rz-bloc { padding: var(--espace-6); }
.rz-bloc-titre { font-size: var(--texte-3); font-weight: 700; color: var(--t-primary); margin: 0 0 var(--espace-5); }
.rz-suggestion { display: flex; align-items: center; gap: var(--espace-4); padding: var(--espace-3) 0; text-align: left; }
.rz-suggestion-cliquable { width: 100%; background: none; border: none; cursor: pointer; }
.rz-suggestion > div { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rz-suggestion b { font-size: var(--texte-3); color: var(--t-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rz-suggestion span { font-size: var(--texte-1); color: var(--t-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rz-pastille {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 34px; height: 34px; border-radius: var(--radius-rond);
  background: var(--accent-bg); color: var(--accent);
  font-size: var(--texte-4); font-weight: 700;
}
.rz-pastille-grande { width: 42px; height: 42px; font-size: var(--texte-6); }

.rz-page { padding: var(--espace-8); display: flex; flex-direction: column; gap: var(--espace-6); }
.rz-page-etroite { max-width: 760px; margin: 0 auto; width: 100%; }
.rz-page-titre, .ms-page-titre, .cm-page-titre { font-size: var(--texte-7); font-weight: 700; color: var(--t-primary); margin: 0; }
.rz-barre-outils { display: flex; align-items: center; flex-wrap: wrap; gap: var(--espace-4); }
.rz-recherche, .ms-recherche {
  flex: 1; min-width: 200px; display: flex; align-items: center; gap: var(--espace-4);
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-rond);
  padding: 0 var(--espace-6); color: var(--t-faint);
}
.rz-recherche input, .ms-recherche input { border: none; background: none; padding: var(--espace-4) 0; }
.rz-select {
  background: var(--bg-input); color: var(--t-secondary); border: 1px solid var(--border);
  border-radius: var(--radius-rond); padding: var(--espace-4) var(--espace-6); font-size: var(--texte-3); cursor: pointer;
}
.rz-etiquettes { display: flex; flex-wrap: wrap; gap: var(--espace-3); }
.rz-etiquettes-mini { margin-top: var(--espace-2); }
.rz-grille-relations { display: grid; gap: var(--espace-6); grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); }
.rz-relation { padding: var(--espace-6); display: flex; flex-direction: column; gap: var(--espace-4); }
.rz-relation header { display: flex; align-items: flex-start; gap: var(--espace-5); }
.rz-relation-qui { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rz-relation-qui b { font-size: var(--texte-5); color: var(--t-primary); }
.rz-relation-qui span { font-size: var(--texte-3); color: var(--t-dim); }
.rz-relation-qui em { font-size: var(--texte-2); color: var(--accent); font-style: normal; margin-top: var(--espace-2); }
.rz-relation-outils { display: flex; gap: var(--espace-1); }
.rz-relation-note { font-size: var(--texte-3); color: var(--t-secondary); margin: 0; }
.rz-relation-delai { display: flex; align-items: center; gap: var(--espace-3); font-size: var(--texte-1); color: var(--t-faint); margin: 0; }
.rz-relation-delai.rz-tiede { color: var(--warn); }
.rz-relation-delai.rz-chaud { color: var(--danger); }
.rz-relation-actions { display: flex; flex-wrap: wrap; gap: var(--espace-3); border-top: 1px solid var(--border); padding-top: var(--espace-4); }
.rz-relation-actions button {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  background: none; border: none; color: var(--t-dim);
  font-size: var(--texte-2); cursor: pointer; padding: var(--espace-2) var(--espace-3);
  border-radius: var(--radius-sm);
}
.rz-relation-actions button:hover { background: var(--bg-input); color: var(--t-primary); }

.rz-conversation { display: flex; align-items: center; gap: var(--espace-5); padding: var(--espace-6); width: 100%; text-align: left; cursor: pointer; }
.rz-conversation-corps { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rz-conversation-corps b { font-size: var(--texte-4); color: var(--t-primary); }
.rz-conversation-corps span { font-size: var(--texte-2); color: var(--t-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rz-conversation-fin { display: flex; flex-direction: column; align-items: flex-end; gap: var(--espace-2); }
.rz-conversation-fin em { font-size: var(--texte-1); color: var(--t-faint); font-style: normal; }
.rz-avis { padding: var(--espace-6); font-size: var(--texte-3); color: var(--t-dim); }
.rz-avis p { margin: 0; }

.rz-salon { display: flex; align-items: center; gap: var(--espace-6); padding: var(--espace-6); flex-wrap: wrap; }
.rz-salon-corps { flex: 1; min-width: 180px; display: flex; flex-direction: column; gap: var(--espace-2); }
.rz-salon-corps b { font-size: var(--texte-5); color: var(--t-primary); }
.rz-salon-corps span { font-size: var(--texte-2); color: var(--t-faint); }
.rz-salon-corps code { font-size: var(--texte-1); color: var(--t-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rz-salon-actions { display: flex; align-items: center; gap: var(--espace-3); flex-wrap: wrap; }

.rz-profil { overflow: hidden; }
.rz-profil-champs { display: flex; flex-direction: column; gap: var(--espace-4); padding: var(--espace-6) var(--espace-8) var(--espace-8); }
.rz-champ-fort { font-size: var(--texte-6); font-weight: 600; }
.rz-avatars { display: flex; flex-wrap: wrap; gap: var(--espace-3); }
.rz-avatar-choix {
  width: 36px; height: 36px; border-radius: var(--radius-sm);
  background: var(--bg-input); border: 1px solid var(--border);
  font-size: var(--texte-7); cursor: pointer;
}
.rz-avatar-choix.on { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-bg); }
.rz-dispo { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-3); }
.rz-dispo > span { font-size: var(--texte-2); color: var(--t-faint); width: 100%; }
.rz-profil-pied { display: flex; align-items: center; gap: var(--espace-5); flex-wrap: wrap; }
.rz-profil-etat { font-size: var(--texte-1); color: var(--t-faint); }
.rz-entete-repli, .ms-entete-repli, .cm-entete-repli {
  padding: var(--espace-6) var(--espace-8); font-size: var(--texte-6);
  font-weight: 700; color: var(--t-primary);
}

/* ── Missions ──────────────────────────────────────────────────────────── */
.ms-page { padding: var(--espace-8); display: flex; flex-direction: column; gap: var(--espace-6); }
.ms-page-etroite { max-width: 760px; margin: 0 auto; width: 100%; }
.ms-page-titre-second { margin-top: var(--espace-8); }
.ms-chercher { display: flex; align-items: center; gap: var(--espace-5); flex-wrap: wrap; }
.ms-filtres { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espace-3); }
.ms-filtres-second { padding-bottom: var(--espace-4); border-bottom: 1px solid var(--border); }
.ms-separateur { width: 1px; height: 18px; background: var(--border); margin: 0 var(--espace-3); }
.ms-grille { display: grid; gap: var(--espace-6); grid-template-columns: repeat(auto-fill, minmax(min(330px, 100%), 1fr)); }
.ms-carte { padding: var(--espace-7); display: flex; flex-direction: column; gap: var(--espace-4); }
.ms-carte-tete { display: flex; align-items: center; gap: var(--espace-3); flex-wrap: wrap; }
.ms-forme {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  font-size: var(--texte-1); font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
  color: var(--t-faint);
}
/* L'URGENCE PORTE SA COULEUR, PAS UN MOT DE PLUS. C'est le seul endroit de la
   carte où la teinte veut dire quelque chose — partout ailleurs elle décorerait. */
.ms-urgence {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  color: var(--teinte); border: 1px solid currentColor; border-radius: var(--radius-rond);
  padding: 0 var(--espace-4); font-size: var(--texte-1); font-weight: 700;
}
.ms-etat, .cm-etat {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  font-size: var(--texte-1); font-weight: 600; color: var(--success);
}
.ms-titre { font-size: var(--texte-6); font-weight: 700; color: var(--t-primary); margin: 0; line-height: 1.35; }
.ms-org { font-size: var(--texte-3); color: var(--t-dim); margin: 0; }
.ms-resume { font-size: var(--texte-3); color: var(--t-secondary); margin: 0; line-height: 1.55; }
.ms-faits { display: flex; flex-wrap: wrap; gap: var(--espace-5); }
.ms-faits span { display: inline-flex; align-items: center; gap: var(--espace-2); font-size: var(--texte-2); color: var(--t-secondary); }
.ms-fait-doux { color: var(--t-faint) !important; }
.ms-competences { display: flex; flex-wrap: wrap; gap: var(--espace-2); }
.ms-carte-pied { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-4); flex-wrap: wrap; border-top: 1px solid var(--border); padding-top: var(--espace-4); }
.ms-carte-verbes { display: flex; align-items: center; gap: var(--espace-3); }
.ms-meta { font-size: var(--texte-1); color: var(--t-faint); }
.ms-description { font-size: var(--texte-3); color: var(--t-secondary); margin: 0; white-space: pre-wrap; }
.ms-suivi { font-size: var(--texte-2); color: var(--t-faint); margin: var(--espace-3) var(--espace-7) var(--espace-7); }
.ms-candidats { display: flex; flex-direction: column; gap: var(--espace-3); border-top: 1px solid var(--border); padding-top: var(--espace-4); }
.ms-candidat { display: flex; align-items: center; gap: var(--espace-4); font-size: var(--texte-2); flex-wrap: wrap; }
.ms-candidat b { color: var(--t-primary); }
.ms-candidat span { flex: 1; min-width: 120px; color: var(--t-secondary); }
.ms-candidat em { color: var(--t-faint); font-style: normal; }
.ms-note { font-size: var(--texte-2); color: var(--t-dim); margin: 0; max-width: 70ch; line-height: 1.55; }
.ms-note-doux { color: var(--t-faint); }
.ms-alerte { display: flex; align-items: center; gap: var(--espace-5); padding: var(--espace-6); background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius); flex-wrap: wrap; }
.ms-alerte > div { flex: 1; min-width: 160px; display: flex; flex-direction: column; }
.ms-alerte b { font-size: var(--texte-4); color: var(--t-primary); }
.ms-alerte span { font-size: var(--texte-2); color: var(--t-faint); }
.ms-alerte-compte { font-size: var(--texte-2); color: var(--accent); font-weight: 600; }

.ms-modale {
  position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .5); padding: var(--espace-6); overflow-y: auto;
}
.ms-formulaire {
  width: min(620px, 100%); max-height: 92vh; overflow-y: auto;
  background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--espace-8); display: flex; flex-direction: column; gap: var(--espace-5);
}
.ms-formulaire header { display: flex; align-items: center; justify-content: space-between; }
.ms-formulaire header p { font-size: var(--texte-7); font-weight: 700; color: var(--t-primary); margin: 0; }
.ms-formulaire label { display: flex; flex-direction: column; gap: var(--espace-3); font-size: var(--texte-2); color: var(--t-dim); }
.ms-formulaire-duo { display: grid; grid-template-columns: 1fr 1fr; gap: var(--espace-5); }
.ms-interrupteur { flex-direction: row !important; align-items: center; font-size: var(--texte-3) !important; color: var(--t-secondary) !important; }
.ms-interrupteur input { width: auto; }
.ms-formulaire footer { display: flex; justify-content: flex-end; gap: var(--espace-4); }

/* ── Communauté ────────────────────────────────────────────────────────── */
.cm-page { padding: var(--espace-8); display: flex; flex-direction: column; gap: var(--espace-5); max-width: 900px; margin: 0 auto; width: 100%; }
.cm-barre { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-5); flex-wrap: wrap; }
.cm-filtres { display: flex; flex-wrap: wrap; gap: var(--espace-3); }
.cm-note { font-size: var(--texte-2); color: var(--t-faint); margin: 0; max-width: 72ch; line-height: 1.55; }
.cm-avis { margin: 0; padding: var(--espace-4) var(--espace-8); font-size: var(--texte-2); color: var(--t-dim); background: var(--bg-secondary); border-bottom: 1px solid var(--border); }
.cm-grille { display: grid; gap: var(--espace-5); grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); }
.cm-carte { padding: var(--espace-6); }
.cm-cercle { display: flex; align-items: center; gap: var(--espace-5); }
.cm-cercle-corps { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.cm-cercle-corps b { font-size: var(--texte-5); color: var(--t-primary); }
.cm-cercle-corps span { font-size: var(--texte-2); color: var(--t-dim); }
.cm-cercle-corps em { font-size: var(--texte-1); color: var(--t-faint); font-style: normal; margin-top: var(--espace-2); }
.cm-cercle-verbes, .cm-evenement-verbes, .cm-ressource-verbes { display: flex; align-items: center; gap: var(--espace-3); }
.cm-pastille {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 38px; height: 38px; border-radius: var(--radius); background: var(--accent-bg); color: var(--accent);
}
.cm-evenement { display: flex; align-items: center; gap: var(--espace-6); flex-wrap: wrap; }
.cm-passe { opacity: .55; }
.cm-date {
  display: flex; flex-direction: column; align-items: center; justify-content: center; flex-shrink: 0;
  width: 52px; height: 52px; border-radius: var(--radius); background: var(--accent-bg); color: var(--accent);
}
.cm-date b { font-size: var(--texte-7); line-height: 1; }
.cm-date span { font-size: var(--texte-1); text-transform: uppercase; }
.cm-evenement-corps { flex: 1; min-width: 180px; display: flex; flex-direction: column; }
.cm-evenement-corps b { font-size: var(--texte-5); color: var(--t-primary); }
.cm-evenement-corps span { font-size: var(--texte-3); color: var(--t-secondary); }
.cm-evenement-corps em { display: flex; align-items: center; gap: var(--espace-2); font-size: var(--texte-1); color: var(--t-faint); font-style: normal; margin-top: var(--espace-2); }
.cm-evenement-corps p { font-size: var(--texte-3); color: var(--t-secondary); margin: var(--espace-3) 0 0; }
.cm-question { display: flex; flex-direction: column; gap: var(--espace-3); }
.cm-resolue { border-color: color-mix(in srgb, var(--success) 40%, var(--border)); }
.cm-question header { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--espace-5); }
.cm-question header b { font-size: var(--texte-5); color: var(--t-primary); }
.cm-question-detail { font-size: var(--texte-3); color: var(--t-secondary); margin: 0; white-space: pre-wrap; }
.cm-meta { font-size: var(--texte-1); color: var(--t-faint); margin: 0; }
.cm-question footer { display: flex; align-items: center; gap: var(--espace-3); }
.cm-reponses { border-top: 1px solid var(--border); padding-top: var(--espace-4); display: flex; flex-direction: column; gap: var(--espace-4); }
.cm-reponse { display: flex; align-items: center; gap: var(--espace-4); font-size: var(--texte-3); flex-wrap: wrap; }
.cm-reponse b { color: var(--t-primary); }
.cm-reponse span { flex: 1; min-width: 140px; color: var(--t-secondary); }
.cm-reponse em { font-size: var(--texte-1); color: var(--t-faint); font-style: normal; }
.cm-retenue { padding: var(--espace-4); border-radius: var(--radius); background: color-mix(in srgb, var(--success) 10%, transparent); }
.cm-reponse-saisie { display: flex; gap: var(--espace-3); }
.cm-ressource { display: flex; align-items: center; gap: var(--espace-5); flex-wrap: wrap; }
.cm-ressource-corps { flex: 1; min-width: 180px; display: flex; flex-direction: column; gap: var(--espace-1); }
.cm-ressource-corps b { font-size: var(--texte-5); color: var(--t-primary); }
.cm-ressource-corps a { display: inline-flex; align-items: center; gap: var(--espace-2); font-size: var(--texte-2); color: var(--accent); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-ressource-corps span { font-size: var(--texte-3); color: var(--t-secondary); }
.cm-ressource-corps em { font-size: var(--texte-1); color: var(--t-faint); font-style: normal; }
.cm-plat.on { color: var(--accent); border-color: var(--accent); }

/* ── Le Découvrir des Espaces ──────────────────────────────────────────── */
.dc-decouvrir { display: flex; flex-direction: column; gap: var(--espace-9); margin-bottom: var(--espace-10); }
.dc-rayon { display: flex; flex-direction: column; gap: var(--espace-5); }
.dc-rayon-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-5); }
.dc-rayon-titre {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  font-size: var(--texte-3); font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--t-faint);
}
.dc-tout {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  background: none; border: none; color: var(--accent);
  font-size: var(--texte-2); font-weight: 600; cursor: pointer;
}
/* UNE PISTE QUI DÉFILE, PAS UNE GRILLE QUI S'ÉTIRE. Un rayon doit laisser
   deviner qu'il continue : c'est ce qui donne envie de pousser. */
.dc-piste {
  display: flex; gap: var(--espace-5); overflow-x: auto; padding-bottom: var(--espace-3);
  scrollbar-width: thin;
}
.dc-vignette {
  flex: 0 0 208px; display: flex; flex-direction: column; gap: var(--espace-3);
  background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--espace-6); text-align: left; cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.dc-vignette:hover { border-color: var(--accent); }
.dc-marque { font-size: var(--texte-7); line-height: 1; }
.dc-marque-douce, .dc-urgent {
  align-self: flex-start; font-size: var(--texte-1); font-weight: 700;
  border-radius: var(--radius-rond); padding: 0 var(--espace-4);
  background: var(--bg-input); color: var(--t-faint);
}
.dc-urgent { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.dc-vignette-titre {
  font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.dc-vignette-sous { font-size: var(--texte-1); color: var(--t-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-portes-liste { display: grid; gap: var(--espace-4); grid-template-columns: repeat(auto-fill, minmax(min(190px, 100%), 1fr)); }
.dc-porte {
  display: flex; flex-direction: column; gap: var(--espace-1);
  background: none; border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--espace-5) var(--espace-6); text-align: left; cursor: pointer;
}
.dc-porte:hover { border-color: var(--accent); }
.dc-porte b { font-size: var(--texte-4); color: var(--t-primary); }
.dc-porte span { font-size: var(--texte-1); color: var(--t-faint); }
.dc-rien { font-size: var(--texte-3); color: var(--t-faint); margin: 0; max-width: 70ch; line-height: 1.6; }

/* ══ COWORKER — LE POSTE DE TRAVAIL (src/crea-poste.js) ═══════════════════
   « Co » veut dire qu'on est plusieurs. L'espace tient donc quatre matières :
   la journée, les gens, le lieu et l'heure. Trois colonnes sur grand écran,
   une seule sur téléphone — et dans cet ordre-là : la journée d'abord, parce
   que c'est ce qu'on vient voir.
   Aucune valeur écrite à la main : les cliquets de la matière visuelle
   comptent chaque taille, chaque durée et chaque barreau d'empilement. */
.pt-espace { min-height: 0; }
.pt-entete-repli {
  padding: var(--espace-6) var(--espace-8); font-size: var(--texte-7); font-weight: 700;
  color: var(--t-primary); border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.pt-entete-fin { display: flex; align-items: center; gap: var(--espace-5); }
.pt-presence { display: flex; align-items: center; }
.pt-pastille {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--radius-rond);
  border: 2px solid var(--bg-primary); margin-left: calc(var(--espace-5) * -1);
  color: #fff; font-size: var(--texte-1); font-weight: 700; flex-shrink: 0;
}
.pt-presence .pt-pastille:first-child { margin-left: 0; }

.pt-onglets {
  display: flex; align-items: stretch; gap: var(--espace-2);
  padding: 0 var(--espace-8); overflow-x: auto; flex-shrink: 0;
  border-bottom: 1px solid var(--border); scrollbar-width: none;
}
.pt-onglets::-webkit-scrollbar { display: none; }
.pt-onglet {
  display: flex; align-items: center; gap: var(--espace-3);
  background: none; border: none; border-bottom: 2px solid transparent;
  padding: var(--espace-5) var(--espace-7);
  color: var(--t-faint); font-size: var(--texte-4); font-weight: 500;
  cursor: pointer; white-space: nowrap;
  transition: color var(--duree-1) var(--courbe);
}
.pt-onglet:hover { color: var(--t-secondary); }
.pt-onglet.on { color: var(--t-primary); border-bottom-color: var(--t-primary); }
.pt-onglet b {
  background: var(--accent); color: #fff; border-radius: var(--radius-rond);
  padding: 0 var(--espace-3); font-size: var(--texte-1); font-weight: 700; line-height: 1.5;
}

/* MESURER L'ESPACE, ET NON LA FENÊTRE.
   Les points de rupture étaient écrits en `@media`, donc sur la largeur de la
   FENÊTRE — alors que ces colonnes vivent dans un espace amputé des 273 px de
   la barre latérale. Relevé : à 1239 px de fenêtre l'espace ne fait que 945 px,
   et de 900 à 1239 la troisième colonne tombait EN BAS À GAUCHE, sous la plus
   étroite. Une bande de trois cents pixels d'écrans réels, dont un portable
   dont la fenêtre n'est pas au maximum.
   `container-type: inline-size` fait mesurer ce qui porte vraiment le contenu.
   Et au palier à deux colonnes, la troisième ne s'auto-place plus : elle est
   POSÉE sous le rail de gauche, qui est étroit comme elle, pendant que la
   journée garde toute la hauteur à droite. */
.pt-defilement { flex: 1; min-height: 0; overflow-y: auto; container-type: inline-size; }
.pt-colonnes {
  display: grid; grid-template-columns: 1fr; gap: var(--espace-8);
  padding: var(--espace-8); align-items: start;
}
/* SOUS 700 PX D'ESPACE, LA JOURNÉE PASSE EN PREMIER. Sur un téléphone, la liste
   des membres du poste n'est pas ce qu'on ouvre l'espace pour voir. */
@container (max-width: 699px) {
  .pt-colonnes > .pt-col:nth-child(1) { order: 2 }
  .pt-colonnes > .pt-col:nth-child(2) { order: 1 }
  .pt-colonnes > .pt-col:nth-child(3) { order: 3 }
}
@container (min-width: 700px) {
  .pt-colonnes { grid-template-columns: 250px minmax(0, 1fr); }
  .pt-colonnes > .pt-col:nth-child(1) { grid-column: 1; grid-row: 1; }
  .pt-colonnes > .pt-col:nth-child(3) { grid-column: 1; grid-row: 2; }
  .pt-colonnes > .pt-col:nth-child(2) { grid-column: 2; grid-row: 1 / span 2; }
}
@container (min-width: 960px) {
  .pt-colonnes { grid-template-columns: 250px minmax(0, 1fr) 300px; }
  .pt-colonnes > .pt-col:nth-child(2) { grid-column: 2; grid-row: 1; }
  .pt-colonnes > .pt-col:nth-child(3) { grid-column: 3; grid-row: 1; }
}
.pt-col { display: flex; flex-direction: column; gap: var(--espace-6); min-width: 0; }

/* ── Les blocs ────────────────────────────────────────────────────────── */
.pt-bloc {
  background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--espace-6);
  display: flex; flex-direction: column; gap: var(--espace-4);
}
.pt-etiq {
  display: flex; align-items: center; gap: var(--espace-3);
  font-size: var(--texte-1); font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--t-faint); margin: 0;
}
.pt-compte {
  background: var(--bg-input); color: var(--t-dim); border-radius: var(--radius-rond);
  padding: 0 var(--espace-3); font-weight: 700; letter-spacing: 0;
}

/* ── Colonne 1 : le poste et les gens ─────────────────────────────────── */
.pt-poste {
  display: flex; flex-direction: column; gap: var(--espace-1); width: 100%;
  background: none; border: none; padding: 0; text-align: left; cursor: pointer;
}
.pt-poste-nom {
  display: flex; align-items: center; gap: var(--espace-3);
  font-size: var(--texte-6); font-weight: 700; color: var(--t-primary);
}
.pt-poste-sous { font-size: var(--texte-2); color: var(--t-faint); }
.pt-membre { display: flex; align-items: center; gap: var(--espace-5); min-width: 0; }
.pt-avatar {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 30px; height: 30px; border-radius: var(--radius-rond);
  color: #fff; font-size: var(--texte-2); font-weight: 700;
}
.pt-avatar.pt-agent { background: var(--bg-input); color: var(--accent); }
.pt-membre-nom {
  flex: 1; min-width: 0; font-size: var(--texte-4); color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pt-doux { color: var(--t-faint); font-weight: 400; }
/* LA PRÉSENCE N'EST PAS RÉELLE : aucun point vert n'est dessiné ici. Ce qui
   s'affiche est la dernière trace connue, en mots. */
.pt-etat { flex-shrink: 0; font-size: var(--texte-1); color: var(--t-faint); }
.pt-etat.pt-vif { color: var(--accent); font-weight: 600; }
.pt-membre-carte {
  background: var(--bg-secondary); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--espace-5) var(--espace-6);
}

/* ── Colonne 2 : la journée ───────────────────────────────────────────── */
.pt-maintenant {
  display: flex; flex-direction: column; gap: var(--espace-4);
  background: var(--bg-primary); border: 1px solid var(--accent);
  border-radius: var(--radius); padding: var(--espace-6);
}
.pt-maintenant-tete { display: flex; align-items: baseline; gap: var(--espace-5); }
.pt-maintenant .pt-quoi { font-size: var(--texte-7); font-weight: 700; color: var(--t-primary); }
.pt-chrono {
  margin-left: auto; flex-shrink: 0; font-variant-numeric: tabular-nums;
  font-size: var(--texte-6); font-weight: 700; color: var(--accent);
}
.pt-avec { display: flex; align-items: center; gap: var(--espace-3); font-size: var(--texte-2); color: var(--t-dim); margin: 0; }

.pt-item {
  display: flex; align-items: flex-start; gap: var(--espace-5);
  padding: var(--espace-4) 0; border-top: 1px solid var(--border);
}
.pt-bloc .pt-item:first-of-type { border-top: none; padding-top: 0; }
.pt-case {
  flex-shrink: 0; width: 17px; height: 17px; margin-top: var(--espace-1);
  border: 2px solid var(--border); border-radius: var(--radius-rond);
  background: none; cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.pt-case:hover { border-color: var(--accent); }
.pt-case.on { background: var(--accent); border-color: var(--accent); }
.pt-case-attente { border-style: dashed; cursor: default; }
.pt-item-corps { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--espace-1); }
.pt-t { font-size: var(--texte-4); color: var(--t-primary); line-height: 1.45; }
.pt-m { display: flex; align-items: center; gap: var(--espace-3); flex-wrap: wrap; font-size: var(--texte-1); color: var(--t-faint); }
.pt-source {
  flex-shrink: 0; font-size: var(--texte-1); font-weight: 600; color: var(--t-faint);
  background: var(--bg-input); border-radius: var(--radius-rond); padding: 0 var(--espace-4);
}
.pt-source-vif { color: var(--accent); }
.pt-retard { color: var(--danger); font-weight: 600; }
.pt-attend { color: var(--warn); font-weight: 600; }
.pt-quoi { flex: 1; min-width: 140px; color: var(--t-secondary); }
.pt-quoi em { color: var(--t-faint); font-style: normal; }

.pt-attend-ligne {
  display: flex; align-items: center; gap: var(--espace-4); flex-wrap: wrap;
  padding: var(--espace-4) 0; border-top: 1px solid var(--border);
}
.pt-bloc .pt-attend-ligne:first-of-type { border-top: none; padding-top: 0; }
.pt-attend-ligne .pt-t { flex: 1; min-width: 160px; color: var(--t-secondary); font-size: var(--texte-3); }
.pt-attend-ligne .pt-t em { color: var(--t-faint); font-style: normal; }
.pt-urgent .pt-t { color: var(--t-primary); font-weight: 600; }
.pt-urgent .pt-source { color: var(--danger); }

.pt-saisie { display: flex; align-items: center; gap: var(--espace-4); }
.pt-champ {
  flex: 1; min-width: 0; background: var(--bg-input); color: var(--t-primary);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--espace-4) var(--espace-6); font-size: var(--texte-3);
  outline: none; font-family: inherit;
}
.pt-champ:focus { border-color: var(--accent); }

/* ── Colonne 3 : le lieu, l'heure, le cercle ──────────────────────────── */
.pt-carte {
  display: flex; flex-direction: column; gap: var(--espace-1);
  background: var(--bg-primary); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--espace-6);
}
.pt-carte-vive { border-color: var(--accent); }
.pt-carte-creuse { border-style: dashed; align-items: flex-start; gap: var(--espace-4); }
.pt-carte-t { font-size: var(--texte-5); font-weight: 600; color: var(--t-primary); }
.pt-carte-s { font-size: var(--texte-3); color: var(--t-dim); }
.pt-carte-m { font-size: var(--texte-1); color: var(--t-faint); }
.pt-carte-large { flex-direction: row; align-items: center; gap: var(--espace-6); flex-wrap: wrap; }
/* Deux et trois colonnes de blocs : c'est ce qui fait que ces pages REMPLISSENT
   la largeur au lieu de la laisser en blanc à droite. Elles retombent à une
   colonne quand l'espace ne les porte plus — mesuré sur l'espace, jamais sur
   la fenêtre. */
.pt-deux, .pt-trois { display: grid; gap: var(--espace-6); align-items: start; grid-template-columns: 1fr; }
@container (min-width: 700px) { .pt-deux { grid-template-columns: 1fr 1fr; } }
@container (min-width: 700px) { .pt-trois { grid-template-columns: 1fr 1fr; } }
@container (min-width: 1020px) { .pt-trois { grid-template-columns: 1fr 1fr 1fr; } }
.pt-etiq svg { flex-shrink: 0; }
.pt-carte-corps { flex: 1; min-width: 180px; display: flex; flex-direction: column; gap: var(--espace-1); }
.pt-passe { opacity: .55; }

.pt-lieu { display: flex; align-items: center; gap: var(--espace-5); color: var(--t-dim); min-width: 0; }
.pt-lieu-corps { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pt-lieu-nom {
  font-size: var(--texte-4); color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pt-lieu-d { font-size: var(--texte-1); color: var(--t-faint); }
.pt-dispo {
  flex-shrink: 0; font-size: var(--texte-1); font-weight: 600; color: var(--t-faint);
  background: var(--bg-input); border-radius: var(--radius-rond); padding: 0 var(--espace-4);
}
.pt-dispo.pt-ouvert { color: var(--success); }
/* LA SOURCE SE DIT. Les lieux viennent d'OpenStreetMap par la même porte que
   Monde Réel : l'écrire n'est pas une politesse, c'est ce qui distingue une
   donnée relevée d'une donnée inventée. */
.pt-attribution { font-size: var(--texte-1); color: var(--t-faint); margin: 0; }

.pt-blocage { display: flex; align-items: center; gap: var(--espace-4); }
.pt-blocage-corps { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pt-blocage-q {
  font-size: var(--texte-3); color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pt-blocage-p { font-size: var(--texte-1); color: var(--t-faint); }

/* ── Les pages pleines : séances, lieux, le poste ─────────────────────── */
/* « SOIT C'EST BIEN CENTRÉ, SOIT ÇA PREND LA LARGEUR DE L'ÉCRAN. DES FOIS,
   LAISSER DES BOUTS DE BLANC COMME ÇA, C'EST MOCHE. »
   Un bloc de 980 px calé à gauche dans un espace de 1400 n'est ni l'un ni
   l'autre : c'est un tiers de page en blanc, sans raison lisible. On prend
   toute la largeur — et ce qui s'y trouve devient une grille, sinon on aurait
   juste changé un blanc pour une ligne de texte de deux mètres.
   La PROSE, elle, reste bornée : au-delà de 74 caractères l'œil perd la ligne
   suivante. Ce n'est pas le même besoin que la largeur d'une page. */
.pt-page {
  display: flex; flex-direction: column; gap: var(--espace-6);
  padding: var(--espace-8);
}
.pt-barre { display: flex; align-items: center; gap: var(--espace-6); flex-wrap: wrap; }
.pt-page-titre { flex: 1; font-size: var(--texte-9); font-weight: 700; color: var(--t-primary); margin: 0; }
.pt-note { font-size: var(--texte-3); color: var(--t-faint); margin: 0; max-width: 74ch; line-height: 1.6; }
.pt-grille { display: grid; gap: var(--espace-5); grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr)); }
.pt-jetons { display: flex; flex-wrap: wrap; gap: var(--espace-3); }
.pt-jeton {
  display: flex; align-items: center; gap: var(--espace-2);
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-rond);
  padding: var(--espace-2) var(--espace-5); color: var(--t-secondary);
  font-size: var(--texte-2); cursor: pointer;
  transition: color var(--duree-1) var(--courbe);
}
.pt-jeton:hover { color: var(--accent); }

/* ── Les verbes ───────────────────────────────────────────────────────── */
.pt-verbes { display: flex; align-items: center; gap: var(--espace-3); flex-wrap: wrap; }
.pt-primaire {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  border-radius: var(--radius-sm); padding: var(--espace-4) var(--espace-7);
  font-size: var(--texte-3); font-weight: 600; cursor: pointer; white-space: nowrap;
}
.pt-plat {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--espace-3);
  background: none; color: var(--t-secondary); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: var(--espace-4) var(--espace-7);
  font-size: var(--texte-3); font-weight: 500; cursor: pointer; white-space: nowrap;
  transition: color var(--duree-1) var(--courbe);
}
.pt-plat:hover { color: var(--accent); }
.pt-large { width: 100%; }
.pt-mini { padding: var(--espace-2) var(--espace-5); font-size: var(--texte-2); }
.pt-verbe {
  flex-shrink: 0; background: none; border: none; color: var(--accent);
  font-size: var(--texte-1); font-weight: 600; cursor: pointer;
  padding: var(--espace-1) var(--espace-3); border-radius: var(--radius-sm);
}
.pt-verbe:hover { background: var(--bg-input); }
.pt-icone {
  flex-shrink: 0; background: none; border: none; color: var(--t-faint);
  font-size: var(--texte-3); cursor: pointer; padding: 0 var(--espace-2);
}
.pt-icone:hover { color: var(--danger); }
.pt-lien {
  display: flex; align-items: center; gap: var(--espace-4); width: 100%;
  background: none; border: none; padding: var(--espace-2) 0;
  color: var(--t-secondary); font-size: var(--texte-3); cursor: pointer; text-align: left;
  transition: color var(--duree-1) var(--courbe);
}
.pt-lien:hover { color: var(--accent); }

/* Le choix de résidence : une ligne d'item cliquable, éteinte quand la réponse
   n'est pas portée. Éteinte veut dire éteinte — pas grisée et cliquable. */
.pt-choix {
  width: 100%; background: none; border: none; border-top: 1px solid var(--border);
  text-align: left; cursor: pointer; font: inherit;
}
.pt-choix .pt-t { font-weight: 600; }
.pt-choix .pt-m { display: block; line-height: 1.5; color: var(--t-faint); }
.pt-choix.on .pt-t { color: var(--accent); }
.pt-item-mort { cursor: not-allowed; opacity: .55; }

/* ── Le vide ──────────────────────────────────────────────────────────── */
.pt-vide {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--espace-4);
  padding: var(--espace-8) 0;
}
.pt-vide-t { font-size: var(--texte-6); font-weight: 600; color: var(--t-primary); margin: 0; }
.pt-vide-s { font-size: var(--texte-3); color: var(--t-faint); margin: 0; max-width: 52ch; line-height: 1.55; }
.pt-vide-mini { font-size: var(--texte-3); color: var(--t-faint); margin: 0; }

/* ══ LE PARTAGE D'UNE CADENCE — TROIS PORTES ═══════════════════════════════
 *
 * « Partager » veut dire trois choses de sûreté très différentes : la recette,
 * un tour de fil, la cadence vivante. Les trois portes sont donc VISIBLES
 * ENSEMBLE — un menu déroulant en aurait montré une à la fois, et on aurait
 * pris la première sans savoir que les deux autres existaient.
 *
 * Le panneau se pose DANS la page de la cadence, pas dans une fenêtre modale.
 * Ce qu'on partage est sous les yeux pendant qu'on choisit comment.
 */
.pa {
  display: flex; flex-direction: column; gap: var(--espace-7);
  padding: var(--espace-8);
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.pa-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-6); }
.pa-titre { margin: 0; font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); }
.pa-fermer, .pa-retirer {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; flex: none;
  background: transparent; border: none; border-radius: var(--radius-sm);
  color: var(--t-faint); cursor: pointer;
  transition: background var(--duree-2) var(--courbe), color var(--duree-2) var(--courbe);
}
.pa-fermer:hover, .pa-retirer:hover { background: var(--bg-glass-hov); color: var(--t-primary); }
.pa-fermer svg, .pa-retirer svg { width: 14px; height: 14px; }

/* LES TROIS PORTES. Chacune porte son nom ET ce qu'elle fait : sans la
   seconde ligne, « La recette » et « La cadence vivante » se lisent comme deux
   façons de dire la même chose, alors qu'elles n'engagent pas du tout la même
   confiance. */
.pa-portes { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: var(--espace-5); }
.pa-porte {
  display: flex; flex-direction: column; gap: var(--espace-3);
  padding: var(--espace-6) var(--espace-7);
  text-align: left;
  background: var(--bg-primary);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color var(--duree-2) var(--courbe), background var(--duree-2) var(--courbe);
}
.pa-porte:hover { border-color: var(--t-faint); }
.pa-porte.est-prise { border-color: var(--accent); background: var(--accent-bg); }
.pa-porte-nom { font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); }
.pa-porte-quoi { font-size: var(--texte-1); line-height: 1.45; color: var(--t-faint); }

.pa-corps { display: flex; flex-direction: column; gap: var(--espace-6); }
.pa-note { margin: 0; font-size: var(--texte-2); line-height: 1.5; color: var(--t-secondary); }
.pa-note--vu { color: var(--warn); }
.pa-vide { margin: 0; font-size: var(--texte-2); color: var(--t-faint); }
.pa-erreur { margin: 0; font-size: var(--texte-2); line-height: 1.5; color: var(--danger); }

/* CE QUI PART, CE QUI RESTE — CÔTE À CÔTE. C'est la seule disposition qui
   répond à la question qu'on se pose vraiment en partageant : non pas « qu'est-ce
   qui part » dans l'absolu, mais « qu'est-ce qui part PLUTÔT QUE de rester ».
   L'une sous l'autre, on lit la première et on ferme. */
.pa-deux { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--espace-8); }
.pa-col { display: flex; flex-direction: column; gap: var(--espace-4); min-width: 0; }
.pa-col-nom {
  margin: 0; font-size: var(--texte-1); font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em; color: var(--t-faint);
}
.pa-champs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--espace-2); }
.pa-champs li { display: flex; gap: var(--espace-5); align-items: baseline; min-width: 0; }
.pa-champ { flex: none; width: 108px; font-size: var(--texte-1); color: var(--t-faint); }
.pa-val { flex: 1; min-width: 0; font-size: var(--texte-2); color: var(--t-primary); overflow-wrap: anywhere; }
/* CE QUI RESTE EST ÉCRIT EN CREUX, et c'est juste : ce n'est pas une liste
   d'actions, c'est une liste de soulagements. La peindre comme la colonne de
   gauche ferait hésiter sur laquelle des deux part. */
.pa-champs--reste .pa-val { color: var(--t-faint); font-style: italic; }

.pa-texte {
  margin: 0; padding: var(--espace-6) var(--espace-7);
  max-height: 30vh; overflow: auto;
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-family: var(--police-mono, monospace); font-size: var(--texte-1); line-height: 1.55;
  color: var(--t-secondary); white-space: pre-wrap; overflow-wrap: anywhere;
}
.pa-pied { display: flex; align-items: center; gap: var(--espace-6); flex-wrap: wrap; }
.pa-pied-note { font-size: var(--texte-1); color: var(--t-faint); }
.pa-copier, .pa-ajouter, .pa-relu {
  display: inline-flex; align-items: center; gap: var(--espace-4);
  padding: var(--espace-4) var(--espace-7);
  font-size: var(--texte-2); font-weight: 500;
  border-radius: var(--radius-sm); cursor: pointer;
  transition: border-color var(--duree-2) var(--courbe), background var(--duree-2) var(--courbe);
}
.pa-copier { background: var(--bg-primary); border: 1px solid var(--border); color: var(--t-primary); }
.pa-copier:hover { border-color: var(--accent); }
.pa-copier svg { width: 14px; height: 14px; }
.pa-ajouter { background: var(--accent); border: 1px solid var(--accent); color: #fff; }
.pa-ajouter:hover { filter: brightness(1.06); }

/* L'ALERTE DU SECRET. Elle ARRÊTE — le bouton de copie n'existe pas tant
   qu'elle est là. Un avertissement qu'on peut ignorer sans geste est un
   avertissement décoratif. */
.pa-alerte {
  display: flex; gap: var(--espace-6);
  padding: var(--espace-7);
  background: var(--danger-bg, rgba(220,80,80,.08));
  border: 1px solid var(--danger); border-radius: var(--radius-sm);
}
.pa-alerte-ic { flex: none; color: var(--danger); }
.pa-alerte-ic svg { width: 18px; height: 18px; }
.pa-alerte-quoi { margin: 0 0 var(--espace-3); font-size: var(--texte-2); line-height: 1.5; color: var(--t-primary); }
.pa-alerte-liste { margin: 0 0 var(--espace-6); font-size: var(--texte-1); color: var(--t-secondary); }
.pa-relu { background: transparent; border: 1px solid var(--danger); color: var(--danger); }
.pa-relu:hover { background: var(--danger); color: #fff; }

/* LES TOURS À RELIRE. Un tour est un choix, pas une liste à parcourir : on en
   ouvre UN, on le lit, on le copie. */
.pa-tours { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--espace-4); }
.pa-tour {
  display: inline-flex; align-items: center; gap: var(--espace-5);
  padding: var(--espace-4) var(--espace-6);
  font-size: var(--texte-1);
  background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--t-secondary); cursor: pointer;
}
.pa-tour:hover { border-color: var(--t-faint); }
.pa-tour.est-pris { border-color: var(--accent); background: var(--accent-bg); color: var(--t-primary); }
.pa-tour-etat { color: var(--success); }
.pa-tour-etat.est-rate { color: var(--danger); }

/* QUI PAIE. Le fait le plus important de cette porte, et le seul qu'on ne
   pense pas à demander avant d'avoir invité quelqu'un. Il est donc DIT, en
   premier, avant même le champ. */
.pa-paie {
  margin: 0; padding: var(--espace-6) var(--espace-7);
  font-size: var(--texte-2); line-height: 1.55; color: var(--t-secondary);
  background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.pa-paie strong { color: var(--t-primary); }
.pa-inviter { display: flex; gap: var(--espace-5); flex-wrap: wrap; }
.pa-qui {
  flex: 1; min-width: 180px;
  padding: var(--espace-4) var(--espace-6);
  font-size: var(--texte-2); color: var(--t-primary);
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.pa-role {
  padding: var(--espace-4) var(--espace-6);
  font-size: var(--texte-2); color: var(--t-primary);
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-sm);
  cursor: pointer;
}
/* CE QUE CHAQUE RÔLE RÉPOND, écrit sous le champ et pas dans une infobulle :
   on choisit un rôle UNE fois, et c'est au moment de choisir qu'on a besoin de
   savoir lequel décroche à 4 h 06. */
.pa-roles { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--espace-3); }
.pa-roles li { display: flex; gap: var(--espace-5); align-items: baseline; }
.pa-role-nom { flex: none; width: 108px; font-size: var(--texte-2); font-weight: 600; color: var(--t-primary); }
.pa-role-quoi { flex: 1; font-size: var(--texte-1); line-height: 1.45; color: var(--t-faint); }
.pa-invites { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--espace-3); }
.pa-invites li {
  display: flex; align-items: center; gap: var(--espace-5);
  padding: var(--espace-4) var(--espace-5) var(--espace-4) var(--espace-7);
  background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.pa-invite-qui { flex: 1; min-width: 0; font-size: var(--texte-2); color: var(--t-primary); overflow-wrap: anywhere; }

/* RECEVOIR — l'autre bout. Le même cadre, parce que c'est le même sujet. */
.pa--recevoir { margin-bottom: var(--espace-8); }
.pa-coller {
  min-height: 120px; resize: vertical;
  padding: var(--espace-6) var(--espace-7);
  font-family: var(--police-mono, monospace); font-size: var(--texte-1); line-height: 1.55;
  color: var(--t-primary);
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.pa-recu {
  display: flex; flex-direction: column; gap: var(--espace-4); align-items: flex-start;
  padding: var(--espace-7);
  background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.pa-recu-nom { margin: 0; font-size: var(--texte-3); font-weight: 600; color: var(--t-primary); }
.pa-recu-perdu, .pa-recu-remplir { margin: 0; font-size: var(--texte-1); line-height: 1.5; color: var(--warn); }
.aw-recevoir {
  padding: var(--espace-4) var(--espace-7);
  font-size: var(--texte-2);
  background: transparent; border: 1px solid var(--border); border-radius: var(--radius-rond);
  color: var(--t-secondary); cursor: pointer;
}
.aw-recevoir:hover { border-color: var(--accent); color: var(--t-primary); }

/* ── LES DEUX FACES D'UNE MÊME PIÈCE ────────────────────────────────────────
 *
 * Créative et le Portail des Studios posent la même question et occupent le
 * même emplacement (cf. src/app-face-studios.js). Le bouton de bascule les
 * RETOURNE : la face qui arrive entre par-dessus celle qui part, au lieu de
 * remplacer la page d'un coup — un remplacement sec se lit comme une
 * navigation, un retournement se lit comme deux faces du même objet.
 *
 * La classe n'est posée que pendant FACE_ANIMATION_MS (420 ms) après un
 * retournement. Sans cette borne, chaque rendu de la page — et une frappe
 * dans la barre de recherche en déclenche un par caractère — rejouerait
 * l'animation sous les doigts de celui qui écrit.
 *
 * `prefers-reduced-motion` coupe le mouvement et garde le fondu : le
 * retournement porte une information (« ce n'est pas la même face »), la
 * perdre entièrement rendrait la bascule invisible.
 */
@keyframes creaFaceRetourne {
  from { opacity: 0; transform: perspective(1400px) rotateY(-7deg) translateZ(-26px); }
  to   { opacity: 1; transform: none; }
}
.face-retournee { animation: creaFaceRetourne .42s cubic-bezier(.22,.61,.36,1) both; transform-origin: left center; will-change: opacity, transform; }
@media (prefers-reduced-motion: reduce) {
  .face-retournee { animation: creaFaceRetourne .42s ease both; }
  @keyframes creaFaceRetourne { from { opacity: 0; } to { opacity: 1; } }
}

/* ══ LA MÉDIATHÈQUE — LE CATALOGUE (src/crea-mediatheque.js) ══════════════
   Seize sections en quatre familles, chacune avec sa teinte : ce que vous
   avez, ce que CRÉA a fait, ce qu'elle a lu, dehors. La teinte n'est pas un
   décor — c'est ce qui fait qu'on retrouve une section sans lire son nom.
   Les points de rupture mesurent l'ESPACE et non la fenêtre, pour la raison
   déjà écrite plus haut : le contenu vit dans un conteneur amputé de la barre
   latérale, et un @media y ferait tomber le rail au mauvais endroit. */
.mq-espace { min-height: 0; }
.mq-entete-repli {
  padding: var(--espace-6) var(--espace-8); font-size: var(--texte-7); font-weight: 700;
  color: var(--t-primary); border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.mq-entete-fin { display: flex; align-items: center; gap: var(--espace-5); }
.mq-compte { font-size: var(--texte-2); color: var(--t-faint); }

.mq-fil {
  display: flex; align-items: center; gap: var(--espace-3); flex-shrink: 0;
  padding: var(--espace-5) var(--espace-8); border-bottom: 1px solid var(--border);
  overflow-x: auto; scrollbar-width: none;
}
.mq-fil::-webkit-scrollbar { display: none; }
.mq-fil-seg {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  background: none; border: none; padding: var(--espace-2) var(--espace-4);
  border-radius: var(--radius-sm); color: var(--t-dim); font-size: var(--texte-3);
  cursor: pointer; white-space: nowrap;
  transition: color var(--duree-1) var(--courbe);
}
.mq-fil-seg:hover { color: var(--t-primary); }
.mq-fil-seg.on { color: var(--t-primary); font-weight: 600; }
.mq-fil-sep { color: var(--t-faint); }

.mq-defilement { flex: 1; min-height: 0; overflow-y: auto; container-type: inline-size; }
.mq-colonnes { display: grid; grid-template-columns: 1fr; align-items: start; }
@container (min-width: 700px) { .mq-colonnes { grid-template-columns: 222px minmax(0, 1fr); } }

.mq-rail {
  display: flex; flex-direction: column; gap: 1px;
  padding: var(--espace-7) var(--espace-5);
}
@container (min-width: 700px) { .mq-rail { border-right: 1px solid var(--border); } }
@container (max-width: 699px) { .mq-rail { border-bottom: 1px solid var(--border); } }
.mq-fam {
  font-size: var(--texte-1); letter-spacing: .1em; text-transform: uppercase;
  color: var(--t-faint); padding: var(--espace-7) var(--espace-5) var(--espace-3); margin: 0;
}
.mq-fam:first-child { padding-top: 0; }
.mq-item {
  display: flex; align-items: center; gap: var(--espace-5); width: 100%;
  background: none; border: none; padding: var(--espace-3) var(--espace-5);
  border-radius: var(--radius-sm); color: var(--t-secondary); font-size: var(--texte-3);
  cursor: pointer; text-align: left;
  transition: color var(--duree-1) var(--courbe);
}
.mq-item:hover { background: var(--bg-secondary); }
.mq-item.on { font-weight: 600; }
.mq-item.on.f-avoir { background: rgba(180,83,9,.11); color: var(--warn); }
.mq-item.on.f-crea { background: rgba(16,163,127,.1); color: var(--accent); }
.mq-item.on.f-lu { background: rgba(99,102,241,.11); color: #6366f1; }
.mq-item.on.f-dehors { background: rgba(14,165,233,.11); color: #0ea5e9; }
.mq-item .n { margin-left: auto; font-size: var(--texte-1); color: var(--t-faint); }
.mq-porte { color: var(--t-faint); font-size: var(--texte-1); }
.i-avoir { color: var(--warn); } .i-crea { color: var(--accent); }
.i-lu { color: #6366f1; } .i-dehors { color: #0ea5e9; }

.mq-centre { min-width: 0; }
.mq-page { display: flex; flex-direction: column; gap: var(--espace-6); padding: var(--espace-8); }
.mq-barre { display: flex; align-items: center; gap: var(--espace-6); flex-wrap: wrap; }
.mq-page-titre { flex: 1; font-size: var(--texte-9); font-weight: 700; color: var(--t-primary); margin: 0; }

.mq-bloc {
  background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--espace-6); display: flex; flex-direction: column; gap: var(--espace-4);
}
.mq-etiq {
  display: flex; align-items: center; gap: var(--espace-3); flex-wrap: wrap;
  font-size: var(--texte-1); font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--t-faint); margin: 0;
}
.mq-n { background: var(--bg-input); color: var(--t-dim); border-radius: var(--radius-rond); padding: 0 var(--espace-3); }
.mq-apres { margin-left: auto; text-transform: none; letter-spacing: 0; font-weight: 400; }

.mq-grande-recherche {
  display: flex; align-items: center; gap: var(--espace-6);
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--espace-6) var(--espace-8); color: var(--accent);
}
.mq-champ-grand {
  flex: 1; min-width: 0; background: none; border: none; outline: none;
  color: var(--t-primary); font-size: var(--texte-6); font-family: inherit;
}
.mq-touche { font-size: var(--texte-1); color: var(--t-faint); }

.mq-ligne, .mq-ligne-plate {
  display: flex; align-items: center; gap: var(--espace-5); flex-wrap: wrap;
  padding: var(--espace-4) 0; border-top: 1px solid var(--border);
}
.mq-bloc .mq-ligne:first-of-type, .mq-bloc .mq-ligne-plate:first-of-type { border-top: none; padding-top: 0; }
.mq-ligne { width: 100%; background: none; border-top: 1px solid var(--border); text-align: left; cursor: pointer; flex-direction: column; align-items: flex-start; gap: var(--espace-1); }
.mq-t { flex: 1; min-width: 140px; font-size: var(--texte-3); color: var(--t-primary); line-height: 1.45; }
.mq-m { font-size: var(--texte-1); color: var(--t-faint); }
.mq-source {
  flex-shrink: 0; font-size: var(--texte-1); font-weight: 600; color: var(--t-faint);
  background: var(--bg-input); border-radius: var(--radius-rond); padding: 0 var(--espace-4);
}
.mq-source-vif { color: var(--accent); }
.mq-eteint { opacity: .6; }
/* UN VIDE SE MONTRE. Une marque, une phrase courte, la raison en petit — et
 * la porte à pousser s'il y en a une. Ce qui remplace le paragraphe. */
.mq-titre-bloc { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--espace-2); }
.mq-titre-bloc > .mq-page-titre { flex: 0 0 auto; }
.mq-dit { font-size: var(--texte-3); color: var(--t-faint); margin: 0; max-width: 76ch; line-height: 1.5; }
.mq-dit b { color: var(--t-secondary); font-weight: 600; }
.mq-vide { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--espace-3); padding: var(--espace-9) var(--espace-6); }
.mq-vide-marque { display: grid; place-items: center; width: 56px; height: 56px; border-radius: var(--radius-rond); background: var(--bg-tertiary); color: var(--t-dim); }
.mq-vide-titre { font-size: var(--texte-5); font-weight: 600; color: var(--t-secondary); margin: 0; }
.mq-vide-dit { font-size: var(--texte-3); color: var(--t-faint); margin: 0; max-width: 52ch; line-height: 1.6; }
.mq-vide-dit b { color: var(--t-secondary); font-weight: 600; }
.mq-bloc .mq-vide { padding: var(--espace-6) var(--espace-4); gap: var(--espace-2); }
.mq-bloc .mq-vide-marque { width: 40px; height: 40px; }
.mq-bloc .mq-vide-titre { font-size: var(--texte-4); }

.mq-grille { display: grid; gap: var(--espace-5); grid-template-columns: repeat(auto-fill, minmax(min(230px, 100%), 1fr)); }
.mq-carte {
  display: flex; flex-direction: column; gap: var(--espace-2);
  background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--espace-6); cursor: pointer; min-width: 0;
  transition: all var(--duree-1) var(--courbe);
}
.mq-carte:hover { border-color: var(--accent); }
.mq-carte-t { font-size: var(--texte-4); font-weight: 600; color: var(--t-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mq-carte-m { font-size: var(--texte-1); color: var(--t-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.mq-bande {
  display: flex; gap: var(--espace-5); overflow-x: auto; scrollbar-width: thin;
  padding-bottom: var(--espace-2);
}
.mq-bande-c {
  flex: 0 0 168px; display: flex; flex-direction: column; gap: var(--espace-3);
  background: none; border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: var(--espace-5); text-align: left; cursor: pointer; min-width: 0;
}
.mq-bande-c:hover { border-color: var(--accent); }
.mq-vig { height: 62px; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; color: #fff; }
.mq-bande-n { font-size: var(--texte-2); color: var(--t-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mq-bande-s { font-size: var(--texte-1); color: var(--t-faint); }

.mq-jetons { display: flex; flex-wrap: wrap; gap: var(--espace-3); }
.mq-jeton {
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-rond);
  padding: var(--espace-1) var(--espace-5); color: var(--t-secondary); font-size: var(--texte-2);
}

.mq-verbes { display: flex; gap: var(--espace-3); flex-wrap: wrap; }
.mq-verbe {
  flex-shrink: 0; background: none; border: none; color: var(--accent);
  font-size: var(--texte-1); font-weight: 600; cursor: pointer;
  padding: var(--espace-1) var(--espace-3); border-radius: var(--radius-sm);
}
.mq-verbe:hover { background: var(--bg-input); }
.mq-primaire {
  display: inline-flex; align-items: center; gap: var(--espace-3);
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  border-radius: var(--radius-sm); padding: var(--espace-4) var(--espace-7);
  font-size: var(--texte-3); font-weight: 600; cursor: pointer; white-space: nowrap;
}
.mq-mini { padding: var(--espace-2) var(--espace-5); font-size: var(--texte-2); }

.mq-etat {
  display: flex; align-items: center; gap: var(--espace-6); flex-shrink: 0; flex-wrap: wrap;
  padding: var(--espace-4) var(--espace-8); border-top: 1px solid var(--border);
  background: var(--bg-secondary); font-size: var(--texte-1); color: var(--t-dim);
}
.mq-etat .droite { margin-left: auto; }


/* ═══════════════════════════════════════════════════════════════════════════
   EXPLORATEUR DE FICHIERS — src/crea-explorateur-fichiers.js

   LE CHÂSSIS DE WINDOWS 11, REPRIS VOLONTAIREMENT : onglets, navigation, fil
   d'Ariane, barre de commandes, volet d'arbre, volet de détails, barre
   d'état. Pas un hommage — des millions de gens le savent déjà, et on
   n'apprend un espace qu'une fois.

   LES BORNES SONT DES `@container`, JAMAIS DES `@media`, ET C'EST MESURÉ :
   cet écran vit DANS la Médiathèque, elle-même amputée des 273 px du rail.
   Une fenêtre de 1239 px laisse 945 px ici. Un `@media (min-width: 1060px)`
   dépliait donc trois colonnes qui n'avaient la place que pour deux, et le
   volet de détails tombait en bas à gauche avec du blanc à droite.
   ═══════════════════════════════════════════════════════════════════════════ */

/* À PLAT SUR LA PAGE — pas de carte dans une fenêtre.
   Il y avait ici un `.xp-fen` : bordure, rayon, ombre, autour d'un écran déjà
   posé dans une fenêtre. Deux cadres concentriques, et l'explorateur perdait
   la moitié de la largeur qu'on lui donnait.
   C'EST CETTE COQUILLE QUI EST LE CONTENEUR des `@container` : elle a la
   largeur réelle, ce que l'espace parent n'a pas tant que le tronc ne la lui
   a pas posée. */
.xp-plein {
  flex: 1; min-height: 0; min-width: 0; display: flex; flex-direction: column;
  background: var(--bg-primary);
  container-type: inline-size; container-name: explo;
}

/* 1 · les onglets */
.xp-onglets {
  flex-shrink: 0; display: flex; align-items: flex-end; gap: var(--espace-2);
  padding: var(--espace-4) var(--espace-5) 0;
  background: var(--bg-secondary); border-bottom: 1px solid var(--border);
  overflow-x: auto; scrollbar-width: none;
}
.xp-onglets::-webkit-scrollbar { display: none; }
.xp-tab {
  display: flex; align-items: center; gap: var(--espace-5);
  padding: var(--espace-4) var(--espace-6); border-radius: var(--radius-xs) var(--radius-xs) 0 0;
  font-size: var(--texte-3); color: var(--t-dim); background: none; border: none;
  font-family: inherit; cursor: pointer; white-space: nowrap;
  transition: all var(--duree-1) var(--courbe);
}
.xp-tab.on {
  background: var(--bg-primary); color: var(--t-primary); font-weight: 600;
  box-shadow: inset 0 1px 0 var(--border), inset 1px 0 0 var(--border), inset -1px 0 0 var(--border);
}
.xp-tab .x { color: var(--t-faint); display: inline-flex; }
.xp-tab-plus {
  margin-left: var(--espace-2); color: var(--t-dim); background: none; border: none;
  cursor: pointer; padding: var(--espace-4);
}

/* 2 · la barre de navigation */
.xp-nav {
  flex-shrink: 0; display: flex; align-items: center; gap: var(--espace-5);
  padding: var(--espace-5) var(--espace-7); border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.xp-nb {
  width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); border: none; background: none; color: var(--t-dim);
  cursor: pointer; transition: all var(--duree-1) var(--courbe);
}
.xp-nb:hover { background: var(--bg-tertiary); color: var(--t-primary); }
.xp-nb[aria-disabled="true"] { color: var(--t-faint); cursor: default; }
.xp-nb[aria-disabled="true"]:hover { background: none; color: var(--t-faint); }
.xp-fil {
  display: flex; align-items: center; gap: var(--espace-3); flex: 1; min-width: 180px;
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: var(--espace-3) var(--espace-6); font-size: var(--texte-3); flex-wrap: wrap;
}
.xp-fil .seg { color: var(--t-secondary); cursor: pointer; }
.xp-fil .seg.fin { color: var(--t-primary); font-weight: 600; cursor: default; }
.xp-fil .sep { color: var(--t-faint); }
.xp-cherche {
  display: flex; align-items: center; gap: var(--espace-4);
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: var(--espace-3) var(--espace-6); color: var(--t-faint); min-width: 180px;
}
.xp-cherche input {
  border: none; background: none; outline: none; font-family: inherit;
  font-size: var(--texte-3); color: var(--t-primary); width: 100%; min-width: 0;
}

/* 3 · la barre de commandes */
.xp-cmd {
  flex-shrink: 0; display: flex; align-items: center; gap: var(--espace-2);
  padding: var(--espace-4) var(--espace-7); border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.xp-c {
  display: inline-flex; align-items: center; gap: var(--espace-4); border: none; background: none;
  color: var(--t-secondary); font-family: inherit; font-size: var(--texte-3);
  padding: var(--espace-3) var(--espace-5); border-radius: var(--radius-sm);
  cursor: pointer; white-space: nowrap; transition: all var(--duree-1) var(--courbe);
}
.xp-c:hover { background: var(--bg-tertiary); }
/* UNE COMMANDE ÉTEINTE RESTE VISIBLE, ET C'EST VOULU : la cacher ferait
   croire qu'elle n'existe pas. On veut qu'elle dise « pas ici, pas encore ». */
.xp-c.mort { color: var(--t-faint); cursor: default; }
.xp-c.mort:hover { background: none; }
.xp-c.neuf { color: var(--accent-texte); font-weight: 600; }
.xp-c .chev { color: var(--t-faint); }
.xp-sepv { width: 1px; align-self: stretch; background: var(--border); margin: var(--espace-2) var(--espace-4); }
.xp-cmd-droite { margin-left: auto; display: flex; gap: var(--espace-2); align-items: center; }

/* 4 · le corps : volet d'arbre / centre / détails */
.xp-corps { display: grid; grid-template-columns: 1fr; min-width: 0; flex: 1; min-height: 0; }
@container explo (min-width: 700px) { .xp-corps { grid-template-columns: 206px minmax(0, 1fr); } }
@container explo (min-width: 1000px) { .xp-corps { grid-template-columns: 206px minmax(0, 1fr) 250px; } }
.xp-corps.sans-details { grid-template-columns: 1fr; }
@container explo (min-width: 700px) { .xp-corps.sans-details { grid-template-columns: 206px minmax(0, 1fr); } }

.xp-vg {
  border-right: 1px solid var(--border); padding: var(--espace-6) var(--espace-5); overflow-y: auto;
  display: flex; flex-direction: column; gap: 1px; background: var(--bg-primary); min-width: 0;
}
.xp-vgi {
  display: flex; align-items: center; gap: var(--espace-5);
  padding: var(--espace-3) var(--espace-5); border-radius: var(--radius-sm);
  color: var(--t-secondary); font-size: var(--texte-3); border: none; background: none;
  font-family: inherit; cursor: pointer; text-align: left; width: 100%;
  transition: all var(--duree-1) var(--courbe);
}
.xp-vgi:hover { background: var(--bg-secondary); }
.xp-vgi.on { background: var(--accent-bg); color: var(--accent-texte); font-weight: 600; }
.xp-vgi.racine { font-weight: 600; color: var(--t-primary); }
.xp-vgi .chev { color: var(--t-faint); width: 12px; flex-shrink: 0; }
.xp-vgi.enfant { padding-left: var(--espace-10); }
.xp-vgi .epingle { margin-left: auto; color: var(--t-faint); font-size: var(--texte-1); }
.xp-vgsep { height: 1px; background: var(--border); margin: var(--espace-5); }

.xp-centre { min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; }

/* Le tableau — cinq colonnes, dont une que Windows ne peut pas écrire */
.xp-tbl-boite { overflow-x: auto; }
table.xp-tbl { width: 100%; border-collapse: collapse; font-size: var(--texte-3); }
table.xp-tbl thead th {
  text-align: left; font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: var(--texte-1); font-weight: 500; letter-spacing: .07em; text-transform: uppercase;
  color: var(--t-faint); padding: var(--espace-4) var(--espace-8);
  border-bottom: 1px solid var(--border); white-space: nowrap; cursor: pointer;
}
table.xp-tbl thead th.trie { color: var(--accent-texte); }
table.xp-tbl tbody td { padding: var(--espace-5) var(--espace-8); border-bottom: 1px solid var(--border); vertical-align: middle; }
table.xp-tbl tbody tr { cursor: pointer; }
table.xp-tbl tbody tr:hover { background: var(--bg-secondary); }
table.xp-tbl tbody tr.choisi { background: var(--accent-bg); }
table.xp-tbl tbody tr.choisi td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.xp-nomc { display: flex; align-items: center; gap: var(--espace-5); min-width: 0; }
.xp-nomc > span:nth-child(2) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--t-primary); }
table.xp-tbl .mono, .xp-etat, .xp-d-chemin {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-variant-numeric: tabular-nums;
}
table.xp-tbl .mono { color: var(--t-dim); white-space: nowrap; }

/* Les couleurs de type — l'œil trie avant de lire */
.xp-plein .i-dos, .xp-plein .i-ordi { color: var(--warn); }
.xp-plein .i-img { color: var(--info); }
.xp-plein .i-doc { color: var(--t-dim); }
.xp-plein .i-code { color: var(--accent); }
.xp-plein .i-son { color: var(--danger); }
.xp-plein .i-dsk { color: var(--info); }

/* La mosaïque — on reconnaît une affiche à son image, jamais à son nom */
.xp-mosaique {
  display: grid; gap: var(--espace-6);
  grid-template-columns: repeat(auto-fill, minmax(min(158px, 100%), 1fr));
  padding: var(--espace-5) var(--espace-8) var(--espace-8);
}
.xp-vign {
  display: flex; flex-direction: column; gap: var(--espace-4);
  border: 1px solid transparent; border-radius: var(--radius-sm); padding: var(--espace-4);
  background: none; font-family: inherit; text-align: left; cursor: pointer; min-width: 0;
  transition: all var(--duree-1) var(--courbe);
}
.xp-vign:hover { background: var(--bg-secondary); border-color: var(--border); }
.xp-vign.choisi { background: var(--accent-bg); border-color: var(--accent); }
.xp-vign-img {
  height: 92px; border-radius: var(--radius-xs); display: flex; align-items: center;
  justify-content: center; background: var(--bg-secondary); border: 1px solid var(--border);
}
.xp-vign-nom { font-size: var(--texte-2); color: var(--t-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.xp-vign-sous {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: var(--texte-1);
  color: var(--t-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Le volet de détails */
.xp-vd {
  border-left: 1px solid var(--border); padding: var(--espace-7); overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--espace-6);
  background: var(--bg-primary); min-width: 0;
}
@container explo (max-width: 999px) { .xp-vd { border-left: none; border-top: 1px solid var(--border); } }
.xp-apercu {
  border: 1px solid var(--border); border-radius: var(--radius); height: 120px;
  display: flex; align-items: center; justify-content: center; background: var(--bg-secondary);
}
.xp-vd-titre, .xp-d-titre {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: var(--texte-1);
  letter-spacing: .1em; text-transform: uppercase; color: var(--t-faint); margin: 0;
}
.xp-d-nom { font-size: var(--texte-5); font-weight: 700; line-height: 1.35; word-break: break-word; margin: 0; }
.xp-d-chemin { font-size: var(--texte-1); color: var(--t-faint); word-break: break-all; margin: 2px 0 0; }
dl.xp-d-liste { margin: 0; display: flex; flex-direction: column; gap: var(--espace-3); }
.xp-d-l { display: flex; justify-content: space-between; gap: var(--espace-5); font-size: var(--texte-2); align-items: baseline; }
.xp-d-l dt { color: var(--t-faint); white-space: nowrap; }
.xp-d-l dd {
  margin: 0; font-family: 'JetBrains Mono', ui-monospace, monospace;
  color: var(--t-secondary); font-variant-numeric: tabular-nums; text-align: right;
}
.xp-d-actions { display: flex; flex-direction: column; gap: var(--espace-3); }
.xp-d-actions button {
  display: flex; align-items: center; gap: var(--espace-5); width: 100%; text-align: left;
  padding: var(--espace-4) var(--espace-5); border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg-elevated); color: var(--t-secondary);
  font-family: inherit; font-size: var(--texte-3); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.xp-d-actions button:hover { color: var(--accent-texte); border-color: var(--border-hov); }
.xp-d-actions button .fl { margin-left: auto; color: var(--t-faint); }
.xp-d-actions button.mort { color: var(--t-faint); cursor: default; }
.xp-d-actions button.mort:hover { color: var(--t-faint); border-color: var(--border); }
hr.xp-filet { border: none; border-top: 1px solid var(--border); margin: 0; }

/* La barre d'état */
.xp-etat {
  flex-shrink: 0; display: flex; align-items: center; gap: var(--espace-6);
  padding: var(--espace-4) var(--espace-8); border-top: 1px solid var(--border);
  background: var(--bg-secondary); font-size: var(--texte-1); color: var(--t-dim); flex-wrap: wrap;
}
.xp-etat .droite { margin-left: auto; display: flex; gap: var(--espace-6); }

/* UN DOSSIER VIDE — OU UNE PORTE FERMÉE — SE MONTRE. Souvent ce n'est pas un
 * vide mais un diagnostic : la marque et l'accroche disent lequel d'un coup
 * d'œil, la raison dit quoi en faire. */
.xp-fig { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--espace-3); padding: var(--espace-10) var(--espace-8); }
.xp-fig-marque { display: grid; place-items: center; width: 56px; height: 56px; border-radius: var(--radius-rond); background: var(--bg-tertiary); color: var(--t-dim); }
.xp-fig-titre { font-size: var(--texte-5); font-weight: 600; color: var(--t-secondary); margin: 0; }
.xp-fig-dit { font-size: var(--texte-3); color: var(--t-faint); margin: 0; max-width: 56ch; line-height: 1.6; }
.xp-vide-mini { color: var(--t-faint); font-size: var(--texte-2); line-height: 1.55; margin: 0; }

/* Les pastilles — « Dans CRÉA », la colonne que le système ne sait pas écrire */
.xp-puce {
  display: inline-flex; align-items: center; gap: var(--espace-2);
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: var(--texte-1);
  font-weight: 500; padding: 1px var(--espace-4); border-radius: var(--radius-rond);
  background: var(--bg-tertiary); color: var(--t-dim); white-space: nowrap;
}
.xp-puce.vert { background: var(--success-fond); color: var(--success); }
.xp-puce.violet { background: var(--info-fond); color: var(--info); }
.xp-puce.ambre { background: var(--warn-fond); color: var(--warn); }
.xp-puce.rouge { background: var(--danger-fond); color: var(--danger); }


/* Les droits — portée, verbe, qui, durée, et la trace */
.xp-droits { display: grid; gap: var(--espace-8); grid-template-columns: 1fr; align-items: start; padding: var(--espace-8); }
@container explo (min-width: 860px) { .xp-droits { grid-template-columns: minmax(0, 340px) minmax(0, 1fr); } }
.xp-bd {
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-primary);
  box-shadow: var(--ombre-2); overflow: hidden; align-self: start;
}
.xp-bd-tete {
  padding: var(--espace-7) var(--espace-8); border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: var(--espace-5);
}
.xp-bd-tete b { font-size: var(--texte-5); font-weight: 700; }
.xp-bd-tete .xp-c { margin-left: auto; }
.xp-bd-corps { padding: var(--espace-7) var(--espace-8); display: flex; flex-direction: column; gap: var(--espace-7); }
.xp-champ { display: flex; flex-direction: column; gap: var(--espace-4); }
.xp-champ-nom {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: var(--texte-1);
  letter-spacing: .09em; text-transform: uppercase; color: var(--t-faint);
}
.xp-lc {
  display: flex; align-items: flex-start; gap: var(--espace-5); padding: var(--espace-4) 0;
  font-size: var(--texte-3); color: var(--t-secondary); cursor: pointer;
}
.xp-case {
  width: 15px; height: 15px; border-radius: var(--radius-xs); border: 2px solid var(--border-hov);
  flex-shrink: 0; margin-top: 2px; transition: all var(--duree-1) var(--courbe);
}
.xp-case.on { background: var(--accent); border-color: var(--accent); }
.xp-case.rond { border-radius: var(--radius-rond); }
/* NOMMÉ À L'ÉCRAN, ÉTEINT DANS LES FAITS — et c'est plus honnête que de ne
   pas l'écrire : à plusieurs sur un même dossier, la sauvegarde range un
   instantané entier par personne et le dernier à écrire effacerait les autres. */
.xp-lc.eteinte { color: var(--t-faint); cursor: default; }
.xp-lc small { display: block; color: var(--t-faint); font-size: var(--texte-1); line-height: 1.5; }
.xp-bd-pied {
  padding: var(--espace-6) var(--espace-8); border-top: 1px solid var(--border);
  background: var(--bg-secondary); display: flex; gap: var(--espace-5); justify-content: flex-end;
}
.xp-btn {
  display: inline-flex; align-items: center; gap: var(--espace-3); font-family: inherit;
  font-size: var(--texte-3); border-radius: var(--radius-sm); padding: var(--espace-4) var(--espace-7);
  cursor: pointer; border: 1px solid var(--border); background: var(--bg-elevated); color: var(--t-secondary);
  transition: all var(--duree-1) var(--courbe);
}
.xp-btn.primaire { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.xp-journal { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; min-width: 0; }
.xp-journal-tete {
  padding: var(--espace-6) var(--espace-8); border-bottom: 1px solid var(--border);
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: var(--texte-1);
  letter-spacing: .09em; text-transform: uppercase; color: var(--t-faint);
}

/* La page d'entrée — les tuiles et leur ligne de droits.
   Windows écrit « stocké localement » sous chaque tuile : c'est la place des
   droits, et le seul endroit de l'écran où l'on voit d'un coup d'œil à qui
   appartient quoi. On la reprend, et on y met ce que Windows ne dit pas. */
.xp-accueil { display: flex; flex-direction: column; min-width: 0; }
.xp-bloc-titre {
  display: flex; align-items: center; gap: var(--espace-5);
  padding: var(--espace-7) var(--espace-8) var(--espace-5);
  color: var(--t-primary); font-size: var(--texte-6); font-weight: 700;
}
.xp-bloc-titre .chev { color: var(--t-dim); }
.xp-rapide {
  display: grid; gap: var(--espace-5);
  grid-template-columns: repeat(auto-fill, minmax(min(226px, 100%), 1fr));
  padding: 0 var(--espace-8) var(--espace-7);
}
.xp-tuile {
  display: flex; align-items: flex-start; gap: var(--espace-6);
  padding: var(--espace-5) var(--espace-6); border-radius: var(--radius-sm);
  border: 1px solid transparent; background: none; font-family: inherit; text-align: left;
  cursor: pointer; min-width: 0; transition: all var(--duree-1) var(--courbe);
}
.xp-tuile:hover { background: var(--bg-secondary); border-color: var(--border); }
.xp-tuile-corps { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.xp-tuile-nom { font-size: var(--texte-4); color: var(--t-primary); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.xp-tuile-droit {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: var(--texte-1);
  color: var(--t-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.xp-pilules { display: flex; gap: var(--espace-4); padding: 0 var(--espace-8) var(--espace-6); flex-wrap: wrap; }
.xp-pil {
  display: inline-flex; align-items: center; gap: var(--espace-4);
  border-radius: var(--radius-rond); padding: var(--espace-3) var(--espace-7);
  font-family: inherit; font-size: var(--texte-3); border: 1px solid var(--border);
  background: var(--bg-elevated); color: var(--t-secondary); cursor: pointer;
  transition: all var(--duree-1) var(--courbe);
}
.xp-pil.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }

/* Les quatre sortes de droits, et ce que chaque surface peut vraiment faire */
.xp-droits-col { display: flex; flex-direction: column; gap: var(--espace-8); min-width: 0; }
.xp-deux { display: grid; gap: var(--espace-6); grid-template-columns: 1fr; }
@container explo (min-width: 820px) { .xp-deux { grid-template-columns: 1fr 1fr; } }
.xp-carte {
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-primary);
  padding: var(--espace-7); display: flex; flex-direction: column; gap: var(--espace-4);
}
.xp-carte-tete { display: flex; align-items: center; gap: var(--espace-5); }
.xp-carte h3 { font-size: var(--texte-4); margin: 0; font-weight: 700; }
.xp-carte p { margin: 0; font-size: var(--texte-3); color: var(--t-dim); line-height: 1.55; }
.xp-carte p em { color: var(--t-secondary); font-style: normal; }
.xp-etiq {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: var(--texte-1);
  letter-spacing: .04em; padding: 1px var(--espace-4); border-radius: var(--radius-rond);
  margin-left: auto; white-space: nowrap;
}
.xp-etiq.socle { background: var(--accent-bg); color: var(--accent-texte); }
.xp-etiq.neuf { background: var(--bg-tertiary); color: var(--t-dim); }
.xp-etiq.mur { background: var(--danger-fond); color: var(--danger); }

table.xp-verite { width: 100%; border-collapse: collapse; font-size: var(--texte-3); }
table.xp-verite th {
  text-align: left; font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: var(--texte-1); font-weight: 500; letter-spacing: .07em; text-transform: uppercase;
  color: var(--t-faint); padding: var(--espace-5) var(--espace-6);
  border-bottom: 1px solid var(--border-hov); vertical-align: bottom;
}
table.xp-verite td { padding: var(--espace-6); border-bottom: 1px solid var(--border); vertical-align: top; color: var(--t-dim); line-height: 1.5; }
table.xp-verite td:first-child { font-weight: 600; color: var(--t-primary); }
table.xp-verite tbody tr:last-child td { border-bottom: none; }
table.xp-verite .oui { color: var(--success); font-weight: 700; }
table.xp-verite .non { color: var(--danger); font-weight: 700; }
table.xp-verite .partiel { color: var(--warn); font-weight: 700; }

/* Le volet gauche de l'explorateur : accès rapide, puis les disques.
   Il portait quatre « racines » dont trois étaient des réalités de CRÉA —
   un arbre de catalogue planté dans un explorateur de fichiers. */
.xp-vg-titre {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: var(--texte-1);
  letter-spacing: .09em; text-transform: uppercase; color: var(--t-faint);
  margin: 0; padding: var(--espace-4) var(--espace-5) var(--espace-2);
}
/* L'ÉTAT VIDE PORTE SON GESTE. Sur un compte neuf dans un navigateur, c'est
   TOUT l'écran : le bouton qui ouvre un dossier ne peut pas être en bas de
   page sous un paragraphe d'excuses. */
.xp-rien {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--espace-5);
  padding: var(--espace-8);
}
.xp-rien-t { margin: 0; font-size: var(--texte-5); font-weight: 600; color: var(--t-primary); }
.xp-rien .xp-vide-mini { max-width: 62ch; }

/* L'ÉTOILE DES FAVORIS — posée SUR la ligne qui ouvre, pas à côté.
   Discrète tant qu'on ne survole pas : une colonne d'étoiles éteintes est du
   bruit sur chaque ligne, et c'est la ligne qu'on vient lire. */
.xp-etoile {
  margin-left: auto; border: none; background: none; padding: var(--espace-2);
  color: var(--t-faint); cursor: pointer; display: inline-flex; opacity: 0;
  transition: all var(--duree-1) var(--courbe);
}
.xp-tbl tbody tr:hover .xp-etoile, .xp-etoile:focus-visible { opacity: 1; }
.xp-etoile.on { opacity: 1; color: var(--warn); }
.xp-etoile.on svg { fill: currentColor; }

/* L'APERÇU D'UNE PIÈCE — « dans la maquette c'est imagé, là tu ne m'as fait
   que des écritures ». La même carte sert les seize sections : la rendre
   visible ici les rend toutes visibles.
   L'image n'est montrée que si elle EXISTE ; sinon l'icône du type sur le
   fond teinté de sa famille — ce qui se reconnaît d'un coup d'œil sans
   fabriquer un faux aperçu. */
.mq-apercu {
  height: 96px; border-radius: var(--radius-sm); display: flex;
  align-items: center; justify-content: center; overflow: hidden;
  border: 1px solid var(--border); background: var(--bg-secondary); color: var(--t-dim);
}
.mq-apercu-img { padding: 0; }
.mq-apercu img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mq-apercu.t-img { background: var(--info-fond); color: var(--info); }
.mq-apercu.t-son { background: var(--danger-fond); color: var(--danger); }
.mq-apercu.t-vid { background: var(--warn-fond); color: var(--warn); }
.mq-apercu.t-code { background: var(--accent-bg); color: var(--accent-texte); }
.mq-carte-lignes { display: flex; align-items: center; gap: var(--espace-4); min-width: 0; flex-wrap: wrap; }
.mq-puce {
  font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: var(--texte-1);
  padding: 1px var(--espace-4); border-radius: var(--radius-rond);
  background: var(--accent-bg); color: var(--accent-texte); white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════════════
 * LE BLOC DES FICHIERS D'UN STUDIO — celui que « Fichiers » déplie sous la barre
 *
 * Il se pose ENTRE la barre d'outils et l'atelier, sans le recouvrir : c'est
 * toute la différence avec la page plein écran qu'il remplace. Hauteur bornée,
 * défilement à l'intérieur — un studio qui a fabriqué quarante fichiers ne doit
 * pas pousser l'atelier hors de l'écran.
 * ═══════════════════════════════════════════════════════════════════════════ */
.stud-fich-bloc {
  flex-shrink: 0;
  margin: 0 var(--espace-4) var(--espace-3);
  border: 1px solid var(--studio-card-border, var(--border));
  border-radius: var(--radius-lg);
  background: var(--bg-secondary);
  overflow: hidden;
}
.stud-fich-tete {
  display: flex; align-items: center; gap: var(--espace-4);
  padding: var(--espace-4) var(--espace-5);
  border-bottom: 1px solid var(--border);
}
.stud-fich-titre { font-size: var(--texte-2); font-weight: 600; color: var(--t-secondary); }
.stud-fich-lien {
  font: inherit; font-size: var(--texte-1); color: var(--t-dim);
  background: none; border: 0; padding: 0; cursor: pointer;
}
.stud-fich-lien:hover, .stud-fich-lien:focus-visible { color: var(--t-primary); text-decoration: underline dotted; }
.stud-fich-partage {
  font: inherit; font-size: var(--texte-2); font-weight: 600;
  padding: var(--espace-2) var(--espace-5);
  border-radius: var(--radius-rond);
  background: var(--studio-ink, #1a1a1a); color: var(--studio-ink-t, #fff);
  border: 0; cursor: pointer;
}
.stud-fich-partage[disabled] { opacity: .4; cursor: default; }
.stud-fich-liste { max-height: 240px; overflow-y: auto; }
.stud-fich-rang {
  display: flex; align-items: center; gap: var(--espace-4);
  width: 100%; text-align: left;
  padding: var(--espace-3) var(--espace-5);
  background: none; border: 0; cursor: pointer; color: inherit;
}
.stud-fich-rang:hover { background: var(--bg-hover, rgba(127,127,127,.08)); }
.stud-fich-rang--coche { background: var(--accent-bg); }
.stud-fich-case {
  display: flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; flex-shrink: 0;
  border: 1.5px solid var(--border); border-radius: var(--radius-xs);
  color: #fff;
}
.stud-fich-rang--coche .stud-fich-case { background: var(--accent); border-color: var(--accent); }
.stud-fich-case svg { width: 11px; height: 11px; }
.stud-fich-ic { display: flex; align-items: center; flex-shrink: 0; color: var(--t-faint); }
.stud-fich-ic svg { width: 16px; height: 16px; }
.stud-fich-txt { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.stud-fich-nom {
  font-size: var(--texte-2); color: var(--t-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stud-fich-sous { font-size: var(--texte-1); color: var(--t-faint); }
.stud-fich-vide { padding: var(--espace-6) var(--espace-5); font-size: var(--texte-2); color: var(--t-faint); text-align: center; }
.stud-fich-pied {
  display: flex; align-items: center; gap: var(--espace-3);
  width: 100%; padding: var(--espace-3) var(--espace-5);
  border-top: 1px solid var(--border);
  font: inherit; font-size: var(--texte-1); color: var(--t-dim);
  background: none; border-left: 0; border-right: 0; border-bottom: 0; cursor: pointer;
}
.stud-fich-pied:hover { color: var(--t-primary); }
.stud-fich-pied svg { width: 14px; height: 14px; }

/* LA BANDE D'OUTILS DE L'ATELIER — sous le contenu, pas dans la barre du haut.
 * Elle porte les rangées qui AGISSENT sur ce qu'on regarde (mise en forme d'un
 * document, générateurs de l'Audio, montage de la Vidéo). Un seul rang, qui
 * défile horizontalement : une bande qui passe à la ligne repousse le contenu
 * hors de l'écran à chaque bouton ajouté. */
.studio-outils-pied {
  display: flex; align-items: center; gap: var(--espace-2);
  flex-shrink: 0;
  padding: var(--espace-3) var(--espace-5);
  border-top: 1px solid var(--border);
  background: var(--bg-secondary);
  overflow-x: auto;
  scrollbar-width: none;
}
.studio-outils-pied::-webkit-scrollbar { display: none; }
.studio-outils-pied > * { flex-shrink: 0; }

/* LA QUEUE D'UNE RÉPONSE EN TRAIN DE S'ÉCRIRE.
 * Le bloc dont la forme n'est pas encore décidée s'affiche tel quel, en texte.
 * Il doit être INDISCERNABLE d'un paragraphe ordinaire : c'est la réponse qui
 * arrive, pas un état d'attente. Lui donner une couleur, une opacité ou une
 * animation ferait clignoter la moitié basse de chaque réponse pendant toute
 * la génération — le remède serait plus visible que le mal.
 * `pre-wrap` rend les retours à la ligne sans <br> qu'il faudrait retirer au
 * fragment suivant. */
.crea-flux-queue {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 0 0 var(--espace-5);
}
.crea-flux-queue:last-child { margin-bottom: 0; }
