/* ENDURIA — Section "Ce qu'on automatise" (#metiers).
   BRIEF_METIERS_AUTOPLAY : refonte façon Limova auto-play séquencé.
   - Header aligné GAUCHE (pilule + H2 + sous-titre)
   - Layout 2 colonnes : liste 6 points numérotés (gauche) | panneau qui change (droite)
   - Étape 1 STATIQUE : point 1 actif en dur, anneau de progression + JS d'auto-play
     viendront en étapes 2 et 3.
*/

/* ===== Glows violets latéraux — COPIE EXACTE du hero, isolés dans un wrapper.
   .metiers__glows porte overflow:hidden pour clipper les glows aux bords de la section.
   #metiers reste en overflow VISIBLE → les ombres/bordures/notif du contenu peuvent
   déborder librement (notamment en light où la box-shadow est plus large). ===== */
#metiers {
  position: relative;
  /* PAS de overflow:hidden ici — sinon ombres + bordures + notif clippées en light. */
}
.metiers__glows {
  position: absolute;
  inset: 0;
  overflow: hidden;   /* clipping localisé : seulement pour les pseudo-glows */
  pointer-events: none;
  z-index: 0;
}
.metiers__glows::before,
.metiers__glows::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 60vw;
  max-width: 720px;
  aspect-ratio: 1 / 1;
  transform: translateY(-50%);
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(124, 79, 201, 0.22) 0%,
    rgba(124, 79, 201, 0.10) 30%,
    rgba(124, 79, 201, 0.03) 55%,
    transparent 75%);
  pointer-events: none;
  filter: blur(20px);
}
.metiers__glows::before { left: -30vw; }
.metiers__glows::after  { right: -30vw; }
[data-theme="light"] .metiers__glows { display: none; }
@media (max-width: 768px) {
  .metiers__glows::before,
  .metiers__glows::after { width: 80vw; max-width: 480px; }
}
/* Le contenu (.container avec layout, header) passe AU-DESSUS du wrapper glows (z-index 0). */
#metiers > .container { position: relative; z-index: 1; }

/* ===== Header CENTRÉ (cohérent avec "Comment ça marche") ===== */
.metiers__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.5rem, 3vh, 2.2rem);
  /* Gap généreux entre le header et la liste/panneau du dessous — l'ensemble respire. */
  margin-bottom: clamp(4.5rem, 9vh, 7rem);
  text-align: center;
}
.metiers__eyebrow {
  align-self: center;
  margin: 0;
}
.metiers__title {
  max-width: 22ch;
  margin-inline: auto;
  text-align: center;
  color: var(--paper);
  font-size: clamp(1.8rem, 3vw, 2.6rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
}
/* Accent "On les connaît." — dégradé violet-rosé subtil (cohérent avec #mecanisme). */
.metiers__title-accent {
  color: var(--paper);
  background-image: linear-gradient(135deg, #c5d0ff 0%, #d1acdf 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
}
[data-theme="light"] .metiers__title-accent {
  background-image: linear-gradient(135deg, #5a4b9e 0%, #7e5fae 100%);
}
.metiers__intro {
  max-width: 52ch;
  margin-inline: auto;
  text-align: center;
  color: var(--text-secondary);
}

/* ===== Pilule glass (partagée #metiers + #why + #results) =====
   Même structure visuelle que la pilule #method, adaptée au fond sombre/clair.
   Les sélecteurs sont mutualisés → un seul style pour toutes les sections
   (évite la divergence future). Composant générique extensible. */
#metiers .eyebrow--pill,
#why .eyebrow--pill,
#results .eyebrow--pill,
#demo .eyebrow--pill,
#temoignages .eyebrow--pill,
#faq .eyebrow--pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  position: relative;
  padding: 7px 14px 7px 12px;
  border-radius: 99px;
  background: rgba(241, 240, 236, 0.04);
  text-transform: none;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.005em;
}
#metiers .eyebrow--pill::before,
#why .eyebrow--pill::before,
#results .eyebrow--pill::before,
#demo .eyebrow--pill::before,
#temoignages .eyebrow--pill::before,
#faq .eyebrow--pill::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.25) 0%, rgba(255, 255, 255, 0.05) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}
#metiers .eyebrow--pill > span,
#why .eyebrow--pill > span,
#results .eyebrow--pill > span,
#demo .eyebrow--pill > span,
#temoignages .eyebrow--pill > span,
#faq .eyebrow--pill > span {
  color: var(--paper);
  background: linear-gradient(135deg, #ffffff 0%, #a0a0a0 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  font-size: var(--type-label);
  line-height: 1;
}
[data-theme="light"] #metiers .eyebrow--pill,
[data-theme="light"] #why .eyebrow--pill,
[data-theme="light"] #results .eyebrow--pill,
[data-theme="light"] #demo .eyebrow--pill,
[data-theme="light"] #temoignages .eyebrow--pill,
[data-theme="light"] #faq .eyebrow--pill {
  background: rgba(12, 13, 16, 0.04);
}
[data-theme="light"] #metiers .eyebrow--pill::before,
[data-theme="light"] #why .eyebrow--pill::before,
[data-theme="light"] #results .eyebrow--pill::before,
[data-theme="light"] #demo .eyebrow--pill::before,
[data-theme="light"] #temoignages .eyebrow--pill::before,
[data-theme="light"] #faq .eyebrow--pill::before {
  background: linear-gradient(135deg, rgba(12, 13, 16, 0.25) 0%, rgba(12, 13, 16, 0.05) 100%);
}
[data-theme="light"] #metiers .eyebrow--pill > span,
[data-theme="light"] #why .eyebrow--pill > span,
[data-theme="light"] #results .eyebrow--pill > span,
[data-theme="light"] #demo .eyebrow--pill > span,
[data-theme="light"] #temoignages .eyebrow--pill > span,
[data-theme="light"] #faq .eyebrow--pill > span {
  background: linear-gradient(135deg, #1b1b1b 0%, #7a7a7a 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Header CENTRÉ de #why / #results / #demo / #temoignages (calé sur .metiers__head).
   Le .section__head générique est aligné gauche par défaut ; on override. */
#why .why__head,
#results .results__head,
#demo .demo__head,
#temoignages .temoignages__head,
#faq .faq__head {
  align-items: center;
  text-align: center;
  gap: clamp(1.5rem, 3vh, 2.2rem);
}
#why .why__title,
#results .results__title,
#demo .demo__title,
#temoignages .temoignages__title,
#faq .faq__title {
  text-align: center;
  max-width: 28ch;
  margin-inline: auto;
}

/* #temoignages suit maintenant le thème standard du site (section-light retirée
   du HTML). Les règles partagées ci-dessus (base + before + span + overrides
   [data-theme="light"]) fonctionnent naturellement, aucun cas spécial. */
/* Icône Sparkles : le gradient SVG #metiers-pill-grad est violet-rosé en dark (illisible
   sur fond clair en light). On override les stops via CSS pour passer en dégradé sombre. */
[data-theme="light"] .eyebrow--pill__ico stop:first-child {
  stop-color: #1b1b1b;
}
[data-theme="light"] .eyebrow--pill__ico stop:last-child {
  stop-color: #7a7a7a;
}

/* ===== Layout 2 colonnes — recentré (BRIEF_METIERS_LAYOUT_ET_SUITE §1) =====
   - max-width plus serrée que .container → ramène le bloc vers le centre,
     plus d'air sur les côtés de la section.
   - Panneau droit avec largeur bornée (minmax 340-480) → ne domine plus la liste gauche.
   - Gap entre colonnes nettement bumpé. */
.metiers__layout {
  display: grid;
  grid-template-columns: minmax(360px, 440px) minmax(340px, 480px);
  gap: clamp(3.5rem, 7vw, 6rem);
  align-items: start;
  max-width: 1080px;
  margin-inline: auto;
}

/* ===== Colonne GAUCHE : liste 6 points ===== */
.metiers__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.metiers__item {
  position: relative;
  padding-block: 0.85rem;
  opacity: 0.5;
  transition: opacity 0.4s var(--ease-out);
}
.metiers__item.is-active { opacity: 1; }
/* Séparateur en TIRETS + dégradé violet-rosé (BRIEF §2). Technique : ::after avec
   - background = linear-gradient violet-rosé pour la couleur
   - mask-image = repeating-linear-gradient (tirets 6px on / 4px off)
   → CSS pur, aucun JS, supporte le dégradé sur une "dashed line". */
.metiers__item:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(to right,
    transparent 0%,
    rgba(209, 172, 223, 0.45) 15%,
    rgba(197, 208, 255, 0.45) 85%,
    transparent 100%);
  -webkit-mask-image: repeating-linear-gradient(to right,
    #000 0, #000 6px, transparent 6px, transparent 10px);
          mask-image: repeating-linear-gradient(to right,
    #000 0, #000 6px, transparent 6px, transparent 10px);
  pointer-events: none;
}

/* Bouton invisible (reset) — clic sur tout le numéro + titre. */
.metiers__btn {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  cursor: pointer;
  text-align: left;
  color: inherit;
  font: inherit;
}

/* Rond numéroté — STRUCTURE DEAD SIMPLE :
   un span 36×36 avec border (= le cercle visible), un span enfant avec le chiffre,
   inline-flex centré. Aucun SVG, aucune complication. L'anneau de progression
   animé (étape 2) sera ajouté plus tard comme overlay séparé (::after ou élément
   sibling positionné absolute par-dessus), sans toucher à ce cercle de base. */
.metiers__num {
  /* Pas de border : l'anneau SVG (track + prog parfaitement superposés à inset:0) est
     l'unique cercle visible. Plus de risque de "flotter" à côté d'un border séparé. */
  position: relative;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.metiers__num-val {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 0.92rem;
  line-height: 1;
  color: var(--paper);
}

/* Anneau de progression : SVG dimensionné EXACTEMENT comme le rond (inset:0).
   - Track : cercle gris/subtle TOUJOURS visible = forme le contour du rond
   - Prog  : cercle violet superposé, contrôlé par stroke-dashoffset (full→0 sur 6s)
   Les 2 cercles ont les MÊMES cx/cy/r/stroke-width → ils se superposent au pixel près.
   Plus de "flottement", l'animation suit pile la ligne du rond. */
.metiers__ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
  transform: rotate(-90deg);   /* part du haut (12h) */
  transform-origin: 50% 50%;
}
.metiers__ring-track,
.metiers__ring-prog {
  fill: none;
  stroke-width: 1.5;
}
.metiers__ring-track {
  stroke: rgba(242, 241, 236, 0.5);
}
[data-theme="light"] .metiers__ring-track {
  stroke: rgba(12, 13, 16, 0.4);
}
.metiers__ring-prog {
  stroke: #c5d0ff;
  stroke-linecap: round;
  /* circumference = 2π × 17 ≈ 106.81 */
  stroke-dasharray: 106.81;
  stroke-dashoffset: 106.81;   /* full = prog invisible, on voit que le track */
}
/* Light : le violet-rosé ne se voit pas sur fond clair → on passe en sombre (--paper). */
[data-theme="light"] .metiers__ring-prog {
  stroke: var(--paper);
}
/* Durée de l'anneau = variable CSS --ring-duration injectée par metiers-autoplay au moment
   de l'activation, lue depuis data-duration du panneau actif. Default 6s pour les panneaux
   sans animation custom. L'anneau atteint 100% pile quand l'anim du panneau se termine. */
.metiers__item.is-active .metiers__ring-prog {
  animation: metiers-ring-fill var(--ring-duration, 6s) linear forwards;
}
@keyframes metiers-ring-fill {
  from { stroke-dashoffset: 106.81; }
  to   { stroke-dashoffset: 0; }
}

/* Chip = container titre. Sans style par défaut, juste flex.
   Devient une PUCE violette quand le point est actif. */
.metiers__chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 5px 10px;
  border-radius: 9px;
  border: 1px solid transparent;
  transition: background 0.4s var(--ease-out), border-color 0.4s var(--ease-out), padding 0.3s var(--ease-out);
}
.metiers__chip-text {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.98rem;
  color: var(--paper);
}
/* Icône (polygon/sparkle) à gauche du titre — visible uniquement sur l'item actif.
   Couleur violet-rosé directement via fill currentColor (couleur posée par .is-active). */
.metiers__chip-ico {
  width: 11px;
  height: 11px;
  flex-shrink: 0;
  display: none;
  fill: currentColor;
  color: #d1acdf;
}
/* PUCE ACTIVE : fond gradient violet translucide + bordure + icône visible. */
.metiers__item.is-active .metiers__chip {
  background: linear-gradient(135deg, rgba(209, 172, 223, 0.14) 0%, rgba(197, 208, 255, 0.14) 100%);
  border-color: rgba(242, 241, 236, 0.1);
}
[data-theme="light"] .metiers__item.is-active .metiers__chip {
  border-color: rgba(12, 13, 16, 0.08);
}
.metiers__item.is-active .metiers__chip-ico {
  display: inline-block;
}

/* Description : technique GRID 0fr→1fr pour animer height:auto en DOUCEUR.
   - .metiers__desc : grid 1 ligne dont la rangée passe de 0fr (collapsed) → 1fr (auto-fit content)
     → la hauteur RÉELLE est animée smooth, pas une max-height surestimée qui poppe.
   - .metiers__desc-inner : overflow hidden + min-height 0 (obligatoire pour que la rangée
     puisse vraiment être à 0fr) + montée+blur léger pour fade-in du contenu lui-même.
   Les items en dessous se repositionnent en CONTINU au pixel près, jamais d'un coup. */
.metiers__desc {
  display: grid;
  grid-template-rows: 0fr;
  margin: 0 0 0 48px;
  max-width: 38ch;
  transition: grid-template-rows 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.metiers__desc-inner {
  overflow: hidden;
  min-height: 0;  /* OBLIGATOIRE pour que la rangée 0fr puisse vraiment être à 0 */
  opacity: 0;
  transform: translateY(6px);
  filter: blur(4px);
  transition:
    opacity 0.4s cubic-bezier(0.16, 1, 0.3, 1) 0.05s,
    transform 0.4s cubic-bezier(0.16, 1, 0.3, 1) 0.05s,
    filter 0.4s cubic-bezier(0.16, 1, 0.3, 1) 0.05s;
}
.metiers__desc-inner p {
  margin: 0;
  padding-top: 0.55rem;  /* petit espace entre le chip et la description */
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--text-secondary);
}
.metiers__item.is-active .metiers__desc {
  grid-template-rows: 1fr;
}
.metiers__item.is-active .metiers__desc-inner {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

/* ===== Colonne DROITE : panneau placeholder ===== */
.metiers__panel-stack {
  position: relative;
  display: grid;
  grid-template-areas: "stack";
  /* Hauteur minimale pour visuel cohérent même si placeholder peu rempli.
     À ajuster quand Théo intègrera ses vrais designs. */
  min-height: 480px;
}
.metiers__panel {
  grid-area: stack;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  filter: blur(4px);
  transition:
    opacity 0.45s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.45s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.45s cubic-bezier(0.16, 1, 0.3, 1),
    visibility 0.45s;
  display: grid;
  place-items: center;
  border-radius: 24px;
  border: 1px solid var(--line);
  background: linear-gradient(180deg,
    rgba(242, 241, 236, 0.04) 0%,
    rgba(242, 241, 236, 0.02) 100%);
  overflow: hidden;
}
[data-theme="light"] .metiers__panel {
  background: linear-gradient(180deg,
    rgba(12, 13, 16, 0.03) 0%,
    rgba(12, 13, 16, 0.01) 100%);
}
.metiers__panel.is-active {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  filter: blur(0);
}

/* Placeholder (à remplacer par les designs de Théo) */
.metiers__panel-placeholder {
  text-align: center;
  padding: 3rem 2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}
.metiers__panel-num {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(4rem, 9vw, 7rem);
  line-height: 1;
  background: linear-gradient(180deg, var(--paper) 0%, rgba(242, 241, 236, 0.25) 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--paper);
}
[data-theme="light"] .metiers__panel-num {
  background: linear-gradient(180deg, var(--paper) 0%, rgba(12, 13, 16, 0.25) 100%);
}
.metiers__panel-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.2rem, 1.8vw, 1.5rem);
  color: var(--paper);
  letter-spacing: -0.02em;
}
.metiers__panel-hint {
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-tertiary);
}

/* ===================================================================
   STORYBOARD_PANEL1 — Panel "Devis & facturation" : File Tree Magic UI.
   Sous-étape 1 statique : arborescence imbriquée + guide-lines verticales
   + bouton "Nouveau" en bas + curseur souris au repos.
   - Aucun cadre/fond/bordure sur le panneau (panel data-panel="1" rendu transparent).
   - Pas de badges d'état, pas de couleurs vert/orange — juste hiérarchie + icônes.
   ===================================================================*/

/* Override : pas de carte/fond pour data-panel="1" — le File Tree flotte directement.
   overflow: visible (vs hidden hérité) → laisse le badge "1" de la notif déborder du
   coin haut-droit de la card sans être clippé par le panneau. */
.metiers__panel[data-panel="1"] {
  background: transparent;
  border-color: transparent;
  place-items: start stretch;
  overflow: visible;
}

.metiers__panel > .panel-ft {
  width: 100%;
  align-self: stretch;
  justify-self: stretch;
}
.panel-ft {
  position: relative;
  padding: 0.5rem 0 1.2rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  font-family: var(--font-display);
}

/* ===== Arborescence imbriquée (Magic UI File Tree) =====
   Hiérarchie via vrais <ul>/<li> imbriqués. Guide-lines verticales via border-left
   sur .ft-children (s'étend pile sur la zone des enfants). */
.ft-tree {
  list-style: none;
  margin: 0;
  padding: 0;
}
.ft-tree li { list-style: none; }
.ft-children {
  list-style: none;
  margin: 0;
  /* padding-left = espace à gauche pour la guide-line ET indentation des enfants.
     border-left = la guide-line elle-même, fine et discrète. */
  padding-left: 1.1rem;
  margin-left: 0.45rem;   /* aligne la guide-line sous le caret du parent */
  border-left: 1px solid rgba(242, 241, 236, 0.12);
}
[data-theme="light"] .ft-children {
  border-left-color: rgba(12, 13, 16, 0.12);
}

/* Node : un dossier (avec caret) ou un fichier (ft-leaf, sans caret) */
.ft-node,
.ft-leaf {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.32rem 0.5rem;
  border-radius: 5px;
  font-size: 0.82rem;
  color: var(--paper);
  cursor: default;
  user-select: none;
}
.ft-node:hover,
.ft-leaf:hover {
  background: rgba(242, 241, 236, 0.04);
}
[data-theme="light"] .ft-node:hover,
[data-theme="light"] .ft-leaf:hover {
  background: rgba(12, 13, 16, 0.04);
}

/* Caret : chevron qui pointe à droite par défaut (replié), tourne 90° quand ouvert */
.ft-caret {
  width: 11px;
  height: 11px;
  flex-shrink: 0;
  color: var(--text-tertiary);
  transition: transform 0.2s var(--ease-out);
}
.ft-node--open .ft-caret {
  transform: rotate(90deg);
}
/* Pas de caret pour les fichiers — on ajoute un placeholder de même width pour aligner */
.ft-leaf::before {
  content: "";
  width: 11px;
  flex-shrink: 0;
}

/* Icône (folder closed / folder open / file). Variants pour les dossiers en violet pâle. */
.ft-ico {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}
.ft-ico--folder {
  color: #c5b3e1;
}
.ft-leaf .ft-ico {
  color: var(--text-secondary);
}

/* Nom : Geist normal pour fichiers, medium pour dossiers.
   flex: 1 + min-width: 0 → permet à la name de shrink avec ellipsis quand un tag/bouton
   prend de la place à droite (sinon le contenu déborde et l'élément à droite est clippé
   hors du leaf par overflow: hidden). */
.ft-name {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--font-display);
  font-weight: 400;
  color: var(--paper);
}
.ft-node .ft-name { font-weight: 500; }

/* ===== Bouton "Nouveau" — placé en bas, sobre et stylisable ===== */
.panel-ft__new {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: auto;       /* pousse en bas (panel-ft est flex-col) */
  padding: 0.42rem 0.8rem;
  border-radius: 6px;
  border: 1px dashed rgba(242, 241, 236, 0.2);
  background: transparent;
  color: var(--paper);
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 500;
  cursor: default;
  transition: background 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
}
.panel-ft__new:hover {
  background: rgba(242, 241, 236, 0.04);
  border-color: rgba(242, 241, 236, 0.32);
}
[data-theme="light"] .panel-ft__new {
  border-color: rgba(12, 13, 16, 0.2);
}
[data-theme="light"] .panel-ft__new:hover {
  background: rgba(12, 13, 16, 0.04);
  border-color: rgba(12, 13, 16, 0.32);
}
.panel-ft__new-ico {
  width: 11px;
  height: 11px;
  flex-shrink: 0;
  color: var(--text-secondary);
}

/* ===== Curseur souris (animé en transform GPU, will-change pour layer dédié) ===== */
.panel-ft__cursor {
  position: absolute;
  bottom: 0.6rem;
  right: 1.5rem;
  width: 16px;
  height: 16px;
  pointer-events: none;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.45));
  z-index: 2;
  will-change: transform;
}

/* ===== STORYBOARD_PANEL1 sous-étape 2 — feedback clic + grow-row + typewriter ===== */

/* Feedback de clic sur le bouton "Nouveau" : scale léger + halo violet-rosé.
   Class .is-pressed ajoutée/retirée par la timeline GSAP. */
.panel-ft__new {
  transition:
    transform 0.15s var(--ease-out),
    box-shadow 0.3s var(--ease-out),
    background 0.2s var(--ease-out),
    border-color 0.2s var(--ease-out);
}
.panel-ft__new.is-pressed {
  transform: scale(0.95);
  box-shadow:
    0 0 0 4px rgba(197, 208, 255, 0.12),
    0 0 18px rgba(197, 208, 255, 0.35);
}

/* Conteneur grid pour animer height 0 → auto en douceur (technique grid-template-rows
   0fr→1fr — pas de saut/pop). Utilisé pour l'apparition du nouveau leaf. */
.ft-leaf-grow {
  list-style: none;
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.45s cubic-bezier(0.16, 1, 0.3, 1);
  margin: 0;
  padding: 0;
}
.ft-leaf-grow > .ft-leaf {
  overflow: hidden;
  min-height: 0;
}
.ft-leaf-grow.is-open {
  grid-template-rows: 1fr;
}

/* Caret texte (curseur typewriter "|") : clignote en CSS pur via @keyframes. */
.ft-caret-text {
  display: inline-block;
  margin-left: 1px;
  color: #c5b3e1;
  font-weight: 400;
  animation: ft-caret-blink 1s steps(2) infinite;
}
@keyframes ft-caret-blink {
  to { opacity: 0; }
}
/* Caret hidden dès que le typing est terminé — pour TOUS les états post-typing
   (sinon il revenait pendant loading/done/validated quand .is-typed était retiré). */
.ft-leaf-grow.is-typed .ft-caret-text,
.ft-leaf-grow.is-loading .ft-caret-text,
.ft-leaf-grow.is-done .ft-caret-text,
.ft-leaf-grow.is-validated .ft-caret-text,
.ft-leaf-grow.is-fading .ft-caret-text {
  display: none;
}

/* ===== STORYBOARD_PANEL1 sous-étape 3 — Enregistrer / Spinner / Check / Tag ===== */

/* Bouton "Enregistrer" inline dans le leaf, à droite. Hidden tant que typewriter pas fini.
   Contient 3 enfants (label, spinner, check) qu'on swap via states. */
.ft-leaf__save {
  margin-left: auto;
  display: none;
  align-items: center;
  justify-content: center;
  position: relative;
  min-width: 70px;
  height: 22px;
  padding: 0 8px;
  border-radius: 5px;
  border: 1px solid rgba(197, 208, 255, 0.25);
  background: rgba(197, 208, 255, 0.06);
  color: var(--paper);
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 500;
  cursor: default;
  transition: transform 0.15s var(--ease-out), box-shadow 0.25s var(--ease-out);
}
/* Bouton visible pendant TOUS les états où il a un rôle : typed (label), loading (spinner),
   done (check). Hidden seulement par défaut, validated, fading. Sans cette règle, le
   bouton disparaissait dès que .is-typed était retiré → spinner/check invisibles. */
.ft-leaf-grow.is-typed .ft-leaf__save,
.ft-leaf-grow.is-loading .ft-leaf__save,
.ft-leaf-grow.is-done .ft-leaf__save {
  display: inline-flex;
}
/* Anim d'arrivée du bouton : seulement à la transition vers .is-typed (1ère apparition). */
.ft-leaf-grow.is-typed .ft-leaf__save {
  animation: ft-save-in 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
/* Apparition montée + fade + léger scale (v2 §1) — plus de pop sec. */
@keyframes ft-save-in {
  from { opacity: 0; transform: translateY(8px) scale(0.92); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.ft-leaf__save.is-pressed {
  transform: scale(0.92);
  box-shadow:
    0 0 0 3px rgba(197, 208, 255, 0.12),
    0 0 12px rgba(197, 208, 255, 0.3);
}

/* Label, spinner, check : 1 seul visible à la fois selon state du leaf. */
.ft-leaf__save-label,
.ft-leaf__save-spinner,
.ft-leaf__save-check {
  display: none;
  line-height: 1;
}
.ft-leaf-grow.is-typed .ft-leaf__save-label,
.ft-leaf-grow.is-loading .ft-leaf__save-spinner,
.ft-leaf-grow.is-done .ft-leaf__save-check {
  display: inline-block;
}
/* Default state (avant is-typed) : label visible mais le bouton est masqué (display: none sur .ft-leaf__save) */

.ft-leaf__save-spinner {
  width: 11px;
  height: 11px;
  border: 1.5px solid rgba(197, 208, 255, 0.22);
  border-top-color: #c5d0ff;
  border-radius: 50%;
  animation: ft-spinner 0.7s linear infinite;
}
@keyframes ft-spinner {
  to { transform: rotate(360deg); }
}

/* Check "Enduria Action" : couleur violet-rosé #c5d0ff (signature du site) au lieu du
   vert standard → souligne que c'est NOTRE automatisation qui agit. */
.ft-leaf__save-check {
  width: 13px;
  height: 13px;
  color: #c5d0ff;
}
.ft-leaf__save-check polyline {
  stroke-dasharray: 25;
  stroke-dashoffset: 25;
}
.ft-leaf-grow.is-done .ft-leaf__save-check polyline {
  animation: ft-check-draw 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.ft-leaf-grow.is-done .ft-leaf__save {
  background: linear-gradient(135deg, rgba(209, 172, 223, 0.14) 0%, rgba(197, 208, 255, 0.14) 100%);
  border-color: rgba(197, 208, 255, 0.32);
}
@keyframes ft-check-draw {
  to { stroke-dashoffset: 0; }
}

/* Étiquette finale (v2 §3) — pilule en dégradé violet-rosé translucide #d1acdf→#c5d0ff
   (signature du site), texte --paper (lisibilité), coche restant verte. */
.ft-leaf__tag {
  margin-left: auto;
  display: none;
  align-items: center;
  gap: 5px;
  font-size: 0.7rem;
  padding: 3px 9px;
  border-radius: 99px;
  background: linear-gradient(135deg, rgba(209, 172, 223, 0.20) 0%, rgba(197, 208, 255, 0.20) 100%);
  border: 1px solid rgba(255, 255, 255, 0.10);
  color: var(--paper);
  font-family: var(--font-display);
  font-weight: 500;
  white-space: nowrap;
}
[data-theme="light"] .ft-leaf__tag {
  border-color: rgba(12, 13, 16, 0.10);
}
.ft-leaf__tag-ico {
  width: 9px;
  height: 9px;
  color: #c5d0ff;   /* check violet-rosé "Enduria Action" — plus de vert */
}
.ft-leaf-grow.is-validated .ft-leaf__save { display: none; }
.ft-leaf-grow.is-validated .ft-leaf__tag {
  display: inline-flex;
  animation: ft-tag-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
/* Motion + blur (v2 §3) — légèrement plus marqué que la v1. */
@keyframes ft-tag-in {
  from { opacity: 0; transform: translateY(6px); filter: blur(8px); }
  to   { opacity: 1; transform: translateY(0); filter: blur(0); }
}

/* Flash violet sur la ligne au moment du succès. */
.ft-leaf-grow.is-validated > .ft-leaf {
  animation: ft-success-flash 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes ft-success-flash {
  0%   { background: rgba(197, 208, 255, 0); }
  30%  { background: rgba(197, 208, 255, 0.14); }
  100% { background: rgba(197, 208, 255, 0); }
}

/* Fade-out + collapse du leaf en fin de cycle (reset avant boucle). */
.ft-leaf-grow.is-fading {
  grid-template-rows: 0fr;
  opacity: 0;
  transition:
    grid-template-rows 0.45s cubic-bezier(0.16, 1, 0.3, 1) 0.15s,
    opacity 0.35s var(--ease-out);
}

/* ===== Slot notification (STORYBOARD_PANEL1 sous-étape B) =====
   Slot vide initialement. Le JS y insère un wrapper .panel-ft__notif-inner contenant
   la .al-card. Le wrapper SÉPARÉ porte le overflow:hidden + min-height:0 (nécessaires
   au grid trick) + padding-top/right pour donner à voir le badge "1" qui déborde du
   coin haut-droit de la card. */
.panel-ft__notif {
  /* Spring hero exact (linear sur-amortie, stiffness 350 damping 40) : copié depuis
     .al-wrap dans animated-list.css. Utilisé par la card pour reproduire le pop EXACT
     du hero (smooth, sans overshoot/pulse). */
  --spring: linear(
    0, 0.0276, 0.0928, 0.1763, 0.2662, 0.3552, 0.4392, 0.516, 0.5849, 0.6456,
    0.6986, 0.7444, 0.7838, 0.8174, 0.8461, 0.8704, 0.891, 0.9084, 0.9231,
    0.9355, 0.9458, 0.9546, 0.9619, 0.9681, 0.9733, 0.9776, 0.9812, 0.9843,
    0.9868, 0.989, 0.9908, 0.9923, 0.9935, 0.9946, 0.9955, 0.9962, 0.9968,
    0.9973, 0.9978, 0.9981, 0.9984
  );
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.panel-ft__notif.is-open {
  grid-template-rows: 1fr;
}
.panel-ft__notif-inner {
  overflow: hidden;        /* nécessaire pour le grid trick 0fr→1fr */
  min-height: 0;           /* nécessaire pour que la row puisse réellement être à 0 */
  /* Room pour que le badge (top:-6, right:-6 de la card) ne soit pas clippé. */
  padding-top: 10px;
  padding-right: 10px;
}
/* Une fois la transition d'OUVERTURE terminée, on passe en overflow VISIBLE → la
   box-shadow de la card (notamment en light, plus large) ne sera plus clippée par
   le wrapper. JS toggle .is-stable après ~0.6s, et le retire juste avant le close
   pour que le collapse soit propre. */
.panel-ft__notif.is-stable .panel-ft__notif-inner {
  overflow: visible;
}

/* Notif AGRANDIE — généreuse, remplit bien l'espace dédié entre tree et bouton.
   position:relative pour le badge iOS absolute en haut-droite. */
.al-card--notif {
  position: relative;
  padding: 14px 16px;
  border-radius: 14px;
  gap: 13px;
  pointer-events: none;
}
.al-card--notif .al-card__title {
  font-size: 0.95rem;
  line-height: 1.2;
}
.al-card--notif .al-card__subtitle {
  font-size: 0.78rem;
  white-space: normal;          /* peut wrap si subtitle long */
}

/* Animation d'arrivée EXACTE du hero (cf. .al-card.al-enter dans animated-list.css) :
   - scale(0) → scale(1) = pop magic UI (la carte grandit depuis son centre)
   - translateY(18px) → translateY(0) = ajout pour effet "du bas" clair
   - Courbe = var(--spring) (linear sur-amortie, AUCUN overshoot/pulse)
   - Durée = 0.55s (identique hero). */
.al-card--notif.al-enter {
  opacity: 0;
  transform: translateY(18px) scale(0);
}
.al-card--notif.al-enter-active {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition:
    opacity 0.55s var(--spring),
    transform 0.55s var(--spring);
}

/* Conteneur logo (Gmail) AGRANDI cohérent avec la notif plus généreuse. */
.al-card__logo {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
[data-theme="light"] .al-card__logo {
  background: rgba(12, 13, 16, 0.04);
}
.al-card__logo img {
  width: 20px;
  height: 20px;
  display: block;
}

/* Badge notification façon iOS : petit rond rouge en haut-droite, légèrement débordant
   du coin. Pop avec petit délai après la notif (scale-in spring). */
.al-card__badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 19px;
  height: 19px;
  padding: 0 5px;
  border-radius: 999px;
  background: #ef4444;
  color: #ffffff;
  font-size: 0.66rem;
  font-weight: 700;
  font-family: var(--font-display);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  box-shadow: 0 2px 8px rgba(239, 68, 68, 0.45);
  /* État initial caché — anim déclenchée par .al-enter-active sur le parent. */
  opacity: 0;
  transform: scale(0);
}
.al-card--notif.al-enter-active .al-card__badge {
  /* Délai 0.3s : pop APRÈS que la notif soit posée (effet "ding" iOS).
     Overshoot subtil (1.3 au lieu de 1.56) pour un pop discret, pas un gros pulse. */
  animation: ft-badge-in 0.4s 0.3s cubic-bezier(0.34, 1.3, 0.64, 1) forwards;
}
@keyframes ft-badge-in {
  from { opacity: 0; transform: scale(0); }
  to   { opacity: 1; transform: scale(1); }
}

/* ===================================================================
   STORYBOARD_PANEL2 v2 — Panel "Reporting & pilotage" : sous-étape 1 refonte.
   Décor INTÉGRÉ au site (pas de cadre/fond) : pile de cards business en
   désordre + loupe qui révèle le NET via une couche dupliquée clippée dans
   un cercle déplacé en transform GPU. Fondu mask sur les bords.
   ===================================================================*/

/* Panel 2 : pas de cadre/fond ni d'overflow:hidden (le mask fait le boulot de fondu). */
.metiers__panel[data-panel="2"] {
  background: transparent;
  border-color: transparent;
  place-items: start stretch;
  overflow: visible;
}
.metiers__panel > .panel-rep {
  width: 100%;
  height: 100%;
  align-self: stretch;
  justify-self: stretch;
}
.panel-rep {
  position: relative;
}

/* Stage = conteneur des couches de cards, avec fondu radial sur les bords pour
   l'intégration "incrustée dans le site" (façon Reflect). La loupe est en-dehors
   du stage donc reste crisp et nette à 100% (pas affectée par le mask). */
.panel-rep__stage {
  position: absolute;
  inset: 0;
  -webkit-mask-image: radial-gradient(ellipse 95% 85% at center 50%,
    #000 45%, rgba(0, 0, 0, 0.5) 75%, transparent 100%);
          mask-image: radial-gradient(ellipse 95% 85% at center 50%,
    #000 45%, rgba(0, 0, 0, 0.5) 75%, transparent 100%);
}

/* Layer = couche absolute qui contient les cards en positions absolutes (specs Figma).
   Les cards ont chacune leurs propres top/left + --blur + --op via inline style. */
.panel-rep__layer {
  position: absolute;
  inset: 0;
}
.panel-rep__layer--blur {
  /* Transition opacity TOUJOURS active → quand reset retire .is-generating/.is-result,
     les cards fade back in smooth (au lieu de snap). */
  transition: opacity 1.2s cubic-bezier(0.16, 1, 0.3, 1);
}
.panel-rep__layer--sharp {
  will-change: transform;
}

/* (Loupe retirée — nouvelle mécanique : curseur qui essaie de ranger les cards.) */

/* Card individuelle — STYLE EXACT Figma + icône fichier à gauche + badge × top-droite.
   - bg dégradé violet-rosé #d1acdf→#c5d0ff à 0.14 alpha
   - border #f1f0ec 0.10 alpha, radius 9px, padding 6px 13px
   - texte Geist Regular 14px, color #f1f0ec
   - flex inline pour aligner icône + texte + badge */
.rep-card {
  position: absolute;
  top: var(--top, 0);
  left: var(--left, 0);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  border-radius: 9px;
  background: linear-gradient(135deg,
    rgba(209, 172, 223, 0.14) 0%,
    rgba(197, 208, 255, 0.14) 100%);
  border: 1px solid rgba(241, 240, 236, 0.10);
  color: #f1f0ec;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.2;
  white-space: nowrap;
}

/* Icône fichier à gauche du texte — discrète, violet-rosé subtile (cohérence
   visuelle avec "bilan-semaine.pdf" qui a aussi une icône fichier). */
.rep-card__ico {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
  color: #c5d0ff;
  opacity: 0.85;
}
[data-theme="light"] .rep-card__ico {
  /* Light : icône fichier en gris sombre (au lieu du violet accent qui faisait double
     emploi avec les boutons signature). */
  color: rgba(12, 13, 16, 0.55);
}
.rep-card__text {
  display: inline-block;
}

/* Badge "élément perturbateur" : petit rond blanc avec × en haut-droite, légèrement
   débordant du coin (façon badge iPhone mais blanc + croix au lieu de rouge + chiffre). */
.rep-card__badge {
  position: absolute;
  top: -5px;
  right: -5px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #f1f0ec;
  color: #0b0c0e;
  display: inline-grid;
  place-items: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}
.rep-card__badge svg {
  width: 7px;
  height: 7px;
}
[data-theme="light"] .rep-card__badge {
  background: #ffffff;
  border: 1px solid rgba(12, 13, 16, 0.10);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.10);
}
[data-theme="light"] .rep-card {
  /* Light : fond gris sombre translucide (au lieu du violet-rosé qui se noyait sur blanc). */
  background: rgba(12, 13, 16, 0.05);
  border-color: rgba(12, 13, 16, 0.12);
  color: #0c0d10;
}

/* Profondeur : blur + opacity DIFFÉRENTS par carte (via --blur/--op inline).
   Scopé à la layer pour qu'on puisse override en .is-grabbed. */
.panel-rep__layer--blur .rep-card {
  filter: blur(var(--blur, 1.5px));
  opacity: var(--op, 0.8);
  will-change: transform;
  transition: filter 0.18s var(--ease-out), opacity 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out);
}

/* État "saisie par le curseur" : la card est en avant, pleinement nette, ombre marquée. */
.panel-rep__layer--blur .rep-card.is-grabbed {
  filter: none;
  opacity: 1;
  z-index: 10;
  box-shadow: 0 14px 32px -8px rgba(0, 0, 0, 0.55);
}
[data-theme="light"] .panel-rep__layer--blur .rep-card.is-grabbed {
  box-shadow: 0 14px 32px -8px rgba(0, 0, 0, 0.18);
}

/* Curseur organique : z-index 10 → passe AU-DESSUS de la barre LLM (z-index 5)
   pour qu'on voie les clics (sinon il passait sous la barre = clic invisible). */
.panel-rep__cursor {
  position: absolute;
  bottom: 28px;
  right: 32px;
  width: 18px;
  height: 18px;
  pointer-events: none;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.45));
  z-index: 10;
  will-change: transform;
}

/* ===== Barre LLM (phase 2) — Specs Figma exactes (channel d0fniutt) =====
   RECTANGLE (pas pilule), radius 9px, fond #f1f0ec 0.08, border 0.10.
   Structure : texte/placeholder EN HAUT, rangée d'icônes EN BAS.
   Le seul accent coloré = bouton envoyer (dégradé violet-rosé plein). */
.panel-rep__bar {
  position: absolute;
  /* Remontée (fix §4) : laisse de la place au centre pour la génération phase 3. */
  bottom: 95px;
  left: 50%;
  translate: -50% 0;
  width: calc(100% - 40px);
  max-width: 378px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 14px 16px;
  border-radius: 9px;
  background: rgba(241, 240, 236, 0.08);
  border: 1px solid rgba(241, 240, 236, 0.10);
  /* Initial : par le BAS (+28px) + blur léger, animé par .is-visible (cf brief §pt1). */
  opacity: 0;
  transform: translateY(28px);
  filter: blur(4px);
  transition:
    opacity 0.55s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.55s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.55s cubic-bezier(0.16, 1, 0.3, 1),
    background-color 0.1s var(--ease-out),
    border-color 0.2s var(--ease-out),
    box-shadow 0.2s var(--ease-out);
  pointer-events: none;
  z-index: 5;
}
.panel-rep__bar.is-visible {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}
[data-theme="light"] .panel-rep__bar {
  background: rgba(12, 13, 16, 0.04);
  border-color: rgba(12, 13, 16, 0.10);
}

/* Focus state : bordure légèrement violet-rosé (subtle). */
.panel-rep__bar.is-focused {
  border-color: rgba(197, 208, 255, 0.28);
}
[data-theme="light"] .panel-rep__bar.is-focused {
  /* Light : bordure focus en gris sombre (au lieu du violet qui se noyait sur fond clair). */
  border-color: rgba(12, 13, 16, 0.32);
}

/* Cascade INTERNE : texte d'abord (le contenu), puis +, puis micro, puis send.
   stagger via transition-delay (cf brief §pt1). */
.panel-rep__bar-text,
.panel-rep__bar-plus,
.panel-rep__bar-mic-btn,
.panel-rep__bar-send {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.35s var(--ease-out), transform 0.35s var(--ease-out);
}
.panel-rep__bar.is-visible .panel-rep__bar-text    { transition-delay: 0.20s; opacity: 1; transform: translateY(0); }
.panel-rep__bar.is-visible .panel-rep__bar-plus    { transition-delay: 0.32s; opacity: 1; transform: translateY(0); }
.panel-rep__bar.is-visible .panel-rep__bar-mic-btn { transition-delay: 0.44s; opacity: 1; transform: translateY(0); }
.panel-rep__bar.is-visible .panel-rep__bar-send    { transition-delay: 0.56s; opacity: 1; transform: translateY(0); }

/* Zone texte (haut) : placeholder en absolute, typewriter inline.
   white-space: normal + word-break pour wrap NATUREL sur 2 lignes (fix §5).
   min-height transitionne smooth quand on passe à 2 lignes via .is-multiline. */
.panel-rep__bar-text {
  position: relative;
  min-height: 18px;
  font-family: var(--font-display);
  font-size: 14px;
  line-height: 1.35;
  color: #f1f0ec;
  white-space: normal;
  word-break: keep-all;
  overflow-wrap: break-word;
  transition:
    min-height 0.4s cubic-bezier(0.16, 1, 0.3, 1),
    background-color 0.1s var(--ease-out);
  border-radius: 4px;
  padding: 1px 3px;
  margin: -1px -3px;
}
/* Quand le typewriter passe à 2 lignes (JS toggle), la hauteur min grandit smooth. */
.panel-rep__bar-text.is-multiline {
  min-height: 38px;
}
[data-theme="light"] .panel-rep__bar-text {
  color: #0c0d10;
}
.panel-rep__bar-placeholder {
  position: absolute;
  left: 0;
  top: 0;
  color: rgba(241, 240, 236, 0.5);
  pointer-events: none;
}
[data-theme="light"] .panel-rep__bar-placeholder {
  color: rgba(12, 13, 16, 0.5);
}
.panel-rep__bar.is-focused .panel-rep__bar-placeholder { display: none; }
.panel-rep__bar-typewriter { display: inline; }

/* Quick click feedback (fix §3) : flash subtle violet-rosé ~0.12s sur le champ texte. */
.panel-rep__bar-text.is-clicking {
  background-color: rgba(197, 208, 255, 0.10);
}
[data-theme="light"] .panel-rep__bar-text.is-clicking {
  /* Light : flash gris sombre subtil (au lieu du violet quasi-invisible sur fond clair). */
  background-color: rgba(12, 13, 16, 0.08);
}
.panel-rep__bar-caret {
  display: none;
  margin-left: 1px;
  color: #c5d0ff;
  font-weight: 400;
  animation: rep-bar-caret-blink 1s steps(2) infinite;
}
[data-theme="light"] .panel-rep__bar-caret {
  /* Light : caret en sombre (le violet-rosé pâle disparaît sur fond clair). */
  color: #0c0d10;
}
.panel-rep__bar.is-focused .panel-rep__bar-caret { display: inline; }
@keyframes rep-bar-caret-blink {
  to { opacity: 0; }
}

/* Rangée d'icônes (bas) : flex avec spacer pour pousser micro/send à droite. */
.panel-rep__bar-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.panel-rep__bar-spacer { flex: 1; }

/* Plus à gauche : décoratif, neutre, transparent. */
.panel-rep__bar-plus {
  display: inline-grid;
  place-items: center;
  width: 21px;
  height: 21px;
  border-radius: 5px;
  background: transparent;
  border: 0;
  color: var(--text-secondary);
  cursor: default;
  padding: 0;
}
.panel-rep__bar-plus svg { width: 13px; height: 13px; }

/* Micro : carré arrondi fond blanc 0.22 (sobre, pas accent). */
.panel-rep__bar-mic-btn {
  display: inline-grid;
  place-items: center;
  width: 21px;
  height: 21px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.22);
  border: 0;
  color: #f1f0ec;
  cursor: default;
  padding: 0;
}
.panel-rep__bar-mic-btn svg { width: 12px; height: 12px; }
[data-theme="light"] .panel-rep__bar-mic-btn {
  background: rgba(12, 13, 16, 0.16);
  color: #0c0d10;
}

/* ENVOYER : SEUL accent coloré = dégradé violet-rosé PLEIN (specs Figma). */
.panel-rep__bar-send {
  display: inline-grid;
  place-items: center;
  width: 21px;
  height: 21px;
  border-radius: 5px;
  background: linear-gradient(90deg, #d1acdf 0%, #c5d0ff 100%);
  border: 0;
  /* Icône en NOIR pour ressortir sur le fond violet-rosé (cohérent avec download). */
  color: #0b0c0e;
  cursor: default;
  padding: 0;
  transition: opacity 0.35s var(--ease-out);
}
.panel-rep__bar-send svg { width: 12px; height: 12px; }
/* Click feedback PRONONCÉ : scale plus marqué + halo qui pulse visible (animation
   keyframe au lieu d'une simple transition → effet "tap" clair). Partagé avec download. */
@keyframes rep-press-pulse {
  0%   { transform: scale(1);    box-shadow: 0 0 0 0 rgba(197, 208, 255, 0.5); }
  35%  { transform: scale(0.88); box-shadow: 0 0 0 7px rgba(197, 208, 255, 0.35),
                                              0 0 24px rgba(209, 172, 223, 0.55); }
  100% { transform: scale(1);    box-shadow: 0 0 0 14px rgba(197, 208, 255, 0),
                                              0 0 36px rgba(197, 208, 255, 0); }
}
.panel-rep__bar-send.is-pressed {
  animation: rep-press-pulse 0.42s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

/* ===== PHASE 3 — Génération / Désintégration / Fichier / Téléchargement =====
   Trois états : default (cards visibles) → .is-generating (cards fade out + canvas
   particules + spinner gen) → .is-result (gen fade out + fichier émerge). Reset
   = retrait des deux classes → tout revient à default via transitions CSS. */

/* === Canvas désintégration LOCALISÉE (particules par-card) ===
   Le canvas couvre la zone des cards. Le JS spawn des particules AUX POSITIONS des
   cards individuelles (pas un pattern global plaqué). Animation one-shot, 24fps, RAF
   qui s'arrête quand toutes les particules sont mortes. */
.panel-rep__disintegrate {
  position: absolute;
  inset: 0 0 auto 0;
  width: 100%;
  height: 60%;
  pointer-events: none;
  z-index: 1;
  opacity: 1;        /* géré par le JS qui ne dessine que pendant la dissolution */
}

/* Cards fade out pendant la génération (effet "absorbé par l'IA"). La transition
   est déclarée sur .panel-rep__layer--blur ci-dessus pour qu'elle joue aussi au RETOUR. */
.panel-rep.is-generating .panel-rep__layer--blur,
.panel-rep.is-result .panel-rep__layer--blur {
  opacity: 0;
}

/* === GÉNÉRATION — Figma "Génération" 277:230 ===
   Format inline compact "[⟳] Génération..." : petit loader 14px + texte shimmer.
   Centré dans la zone réservée, remonté de ~7% (≥20px) par rapport au centre vertical. */
.panel-rep__gen {
  position: absolute;
  top: 38%;
  left: 50%;
  translate: -50% -50%;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  z-index: 3;
  opacity: 0;
  transform: translateY(0);
  filter: blur(2px);
  transition:
    opacity 0.4s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.4s cubic-bezier(0.16, 1, 0.3, 1);
  pointer-events: none;
}
.panel-rep.is-generating .panel-rep__gen {
  opacity: 1;
  filter: blur(0);
}
.panel-rep.is-result .panel-rep__gen {
  opacity: 0;
  filter: blur(6px);
}

/* Loader inline : petit cercle qui tourne, ~14px, à gauche du texte. */
.panel-rep__gen-loader {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: #707070;
  animation: rep-spin 0.9s linear infinite;
}
[data-theme="light"] .panel-rep__gen-loader {
  color: #909090;
}
@keyframes rep-spin {
  to { transform: rotate(360deg); }
}

/* Texte "Génération..." en shimmer : gradient gris qui balaie le texte horizontalement. */
.panel-rep__gen-text {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0;
  /* Gradient gris clair → gris foncé → gris clair (selon spec brief §2). */
  background: linear-gradient(90deg,
    #b9b9b9 0%,
    #b9b9b9 25%,
    #424242 50%,
    #b9b9b9 75%,
    #b9b9b9 100%);
  background-size: 200% 100%;
  background-position: 100% 0;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: rep-shimmer 1.8s linear infinite;
}
@keyframes rep-shimmer {
  to { background-position: -100% 0; }
}

/* === OUTPUT — Figma "OUTPUT" 277:216 ===
   Pilule claire #f1f0ec + bouton download violet-rosé, ARRIVE PAR LE BAS en blur
   (façon animated list) au moment où .is-result remplace .is-generating. */
.panel-rep__output {
  position: absolute;
  top: 38%;             /* même position que .gen (remplace au même endroit) */
  left: 50%;
  translate: -50% -50%;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  z-index: 3;
  /* Initial : caché en bas + blur + opacity 0 → arrive au passage .is-result. */
  opacity: 0;
  transform: translateY(28px);
  filter: blur(6px);
  transition:
    opacity 0.55s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.55s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.55s cubic-bezier(0.16, 1, 0.3, 1);
  pointer-events: none;
}
.panel-rep.is-result .panel-rep__output {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

/* Pilule claire : fond #f1f0ec plein, texte sombre. Geist Medium 16px.
   white-space: nowrap → le nom de fichier reste TOUJOURS sur 1 seule ligne. */
.panel-rep__output-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  height: 34px;
  border-radius: 9px;
  background: #f1f0ec;
  border: 1px solid rgba(241, 240, 236, 0.10);
  color: #0b0c0e;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.005em;
  white-space: nowrap;
}
.panel-rep__output-ico {
  width: 18px;
  height: 18px;
  color: #0b0c0e;
  flex-shrink: 0;
}
[data-theme="light"] .panel-rep__output-pill {
  background: #ffffff;
  border-color: rgba(12, 13, 16, 0.10);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}

/* Bouton download : carré 34×34, dégradé violet-rosé plein, icône download dedans. */
.panel-rep__output-dl {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: linear-gradient(90deg, #d1acdf 0%, #c5d0ff 100%);
  border: 1px solid rgba(241, 240, 236, 0.10);
  /* Icône en NOIR pour ressortir sur le fond violet-rosé (cohérent avec envoyer). */
  color: #0b0c0e;
  cursor: default;
  padding: 0;
  pointer-events: none;
  position: relative;
}
.panel-rep__output-dl-ico,
.panel-rep__output-dl-check {
  width: 16px;
  height: 16px;
  position: absolute;
  inset: 0;
  margin: auto;
}
.panel-rep__output-dl-check {
  display: none;
}
.panel-rep__output-dl.is-pressed {
  animation: rep-press-pulse 0.42s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.panel-rep__output-dl.is-done .panel-rep__output-dl-ico { display: none; }
.panel-rep__output-dl.is-done .panel-rep__output-dl-check { display: block; }
.panel-rep__output-dl.is-done .panel-rep__output-dl-check polyline {
  stroke-dasharray: 25;
  stroke-dashoffset: 25;
  animation: rep-check-draw 0.45s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes rep-check-draw {
  to { stroke-dashoffset: 0; }
}

/* ===================================================================
   STORYBOARD_PANEL3 — Panel "Prospection & relances" : sous-étape 1.
   Décor + arrivée en cascade de 3 cartes dirigeant. 2 paniers dash en
   bas ("À contacter" / "À relancer"). Curseur "Agent Enduria" (pilule
   claire + logo Enduria pointillé + label Geist Medium) au repos.
   Le tri (mouvement curseur → grab carte → drop dans le bon panier)
   arrive en sous-étape 2.

   Réutilisations max : pattern d'entrée des cartes copié sur
   .al-card.al-enter/.al-enter-active (animated-list hero), spring
   sur-amortie partagée, bordure dashed des paniers cousine de
   .panel-ft__new (panel 1), curseur SVG = même hand-style que panels 1/2.
   ===================================================================*/

.metiers__panel[data-panel="3"] {
  background: transparent;
  border-color: transparent;
  place-items: start stretch;
  overflow: visible;
}
.metiers__panel > .panel-pros {
  width: 100%;
  height: 100%;
  align-self: stretch;
  justify-self: stretch;
}

/* Conteneur racine : flex col. PANIERS EN HAUT, stack AU CENTRE/BAS, curseur en bas-droite.
   Spring partagée (linear sur-amortie identique au hero) pour les entrées de cards
   et les transitions futures (sous-étape 2). */
.panel-pros {
  --spring: linear(
    0, 0.0276, 0.0928, 0.1763, 0.2662, 0.3552, 0.4392, 0.516, 0.5849, 0.6456,
    0.6986, 0.7444, 0.7838, 0.8174, 0.8461, 0.8704, 0.891, 0.9084, 0.9231,
    0.9355, 0.9458, 0.9546, 0.9619, 0.9681, 0.9733, 0.9776, 0.9812, 0.9843,
    0.9868, 0.989, 0.9908, 0.9923, 0.9935, 0.9946, 0.9955, 0.9962, 0.9968,
    0.9973, 0.9978, 0.9981, 0.9984
  );
  position: relative;
  padding: 0.6rem 0.5rem 1rem;
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
}

/* ===== Stack de cartes dirigeant — AU CENTRE / BAS du panneau =====
   margin-top: auto la pousse en bas (panel-pros est flex-col, paniers en haut).
   Cards plus grosses qu'avant (44 vs 31px) → mieux lisibles, plus présentes.
   Ancrée en bas → les premières cartes apparaissent en bas, les suivantes s'empilent
   vers le haut, cohérent avec la sensation "liste qui se remplit" de l'animated-list. */
.pros-stack {
  list-style: none;
  /* margin-top auto = pousse au plus bas (sous les paniers). Marges latérales pour
     centrer la liste sans dépasser. Bottom margin laisse de la place au curseur. */
  margin: auto auto 70px;
  padding: 0;
  width: min(340px, 96%);
  /* Place pour ~3 cartes (44×3 + gap 10×2 = ~152) + un peu de respiration. */
  min-height: 168px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  justify-content: flex-end;
}

/* ===== Carte dirigeant — VERSION AGRANDIE (specs Figma adaptées) =====
   Hauteur 44px (vs 31 initial), padding L/R 12px, gap interne 10px.
   Avatar rond 26px (vs 17) → photo bien lisible. Nom 13px / statut 10px.
   Fond #f3f3f3, radius 10 (specs Figma respectées). */
.pros-card {
  list-style: none;
  position: relative;       /* pour que z-index:5 sur .is-grabbed prenne effet */
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 44px;
  padding: 0 12px;
  border-radius: 10px;
  /* Fond clair (specs Figma). Garde le même rendu en dark : la card reste claire
     → contraste fort sur le panneau sombre, lisible immédiatement. */
  background: #f3f3f3;
  border: 1px solid rgba(12, 13, 16, 0.04);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  transform-origin: center;
  will-change: transform, opacity;
  /* Transition sur box-shadow uniquement → l'ombre "souffle" en douceur quand l'agent
     attrape/lâche la carte. transform reste piloté par GSAP (sans transition CSS) pour
     que les keyframes du scale 1.05 ne soient pas court-circuités par une transition. */
  transition: box-shadow 0.2s var(--ease-out);
}

/* État "saisie par l'agent" : ombre forte (carte "soulevée" du fond), z-index pour
   passer au-dessus des autres cartes et des paniers pendant le carry. Le scale 1.05
   et le déplacement (translate) sont pilotés par GSAP côté JS (cf panel3-prospection). */
.pros-card.is-grabbed {
  z-index: 5;
  box-shadow:
    0 10px 24px -4px rgba(0, 0, 0, 0.35),
    0 3px 8px rgba(0, 0, 0, 0.20);
}

/* Avatar = photo de dirigeant (libres de droits, self-hostée dans assets/demo/).
   Cercle 26px, photo cover, fond fallback en cas de chargement lent. */
.pros-card__avatar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  flex-shrink: 0;
  overflow: hidden;
  background: #e3e1dc;     /* fallback gris très clair pendant le chargement */
}
.pros-card__avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;   /* cadrage visage si la photo est large */
}

/* Nom · rôle : Geist Medium 13px, #7a7a7a (specs Figma). */
.pros-card__name {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 13px;
  line-height: 1.15;
  color: #7a7a7a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Statut à droite : Geist Regular 10px, #7a7a7a (specs Figma, gris sobre).
   PAS de teinte violette : le tri se comprend par l'ACTION de l'agent
   (vers quel panier il porte la carte), pas par une couleur sur le statut. */
.pros-card__status {
  flex-shrink: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 10px;
  line-height: 1.15;
  color: #7a7a7a;
  white-space: nowrap;
}

/* ===== Entrée des cartes (mécanique animated-list hero, calibrée brief §COMPORTEMENT) =====
   - .pros-card.al-enter        → état initial (opacity 0, translateY 18px depuis le bas,
                                  scale 0.96 SUBTIL — pas scale(0) qui poppe trop sur des
                                  cartes 44px de haut, on perd la fluidité du hero)
   - .pros-card.al-enter-active → état final (opacity 1, translateY 0, scale 1)
   - Courbe = var(--spring) (linear sur-amortie hero, AUCUN overshoot)
   - Durée = 0.55s (identique hero, ENTER_MS côté JS)
   Le glissement EN DOUCEUR des cartes existantes lors d'une insertion est géré côté
   JS via la mécanique FLIP du hero (mesure avant/après + translateY(delta) sans
   transition + RAF + remise à 0 avec transition spring FLIP_MS=700). */
.pros-card.al-enter {
  opacity: 0;
  transform: translateY(18px) scale(0.96);
}
.pros-card.al-enter-active {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition:
    opacity 0.55s var(--spring),
    transform 0.55s var(--spring);
}

/* ===== Paniers dash — EN HAUT du panneau, BIEN SÉPARÉS =====
   "À contacter" en haut-GAUCHE, "À relancer" en haut-DROITE. Gap large entre les
   deux (~36px) pour qu'ils respirent et soient clairement perçus comme 2 cibles
   distinctes. Cousins esthétiques du bouton "Nouveau" panel 1 (border dashed +
   accent violet-rosé subtil sur le label). Slot interne (.pros-basket__slot) prêt
   à recevoir les cartes triées en sous-étape 2. */
.pros-baskets {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 36px;
  padding: 0 4px;
}
.pros-basket {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px dashed rgba(242, 241, 236, 0.22);
  background: rgba(242, 241, 236, 0.02);
  /* min-height : capacité visuelle pour 2 cartes empilées (cas panier "relance"
     qui reçoit Julien + Marc dans le même cycle).
     Budget : 2 cartes 44px avec step 26px d'empilement = 70px + 4px settle drop
     = ~74px occupés. + 14px label + 8px gap + 20px padding T/B + 14px breathing
     = ~130px. On vise 138px pour que la 2e carte se cale franchement à l'intérieur
     du cadre dashed, sans flirter avec la bordure inférieure. */
  min-height: 138px;
  transition: border-color 0.25s var(--ease-out), background 0.25s var(--ease-out);
}
[data-theme="light"] .pros-basket {
  border-color: rgba(12, 13, 16, 0.22);
  background: rgba(12, 13, 16, 0.015);
}

.pros-basket__label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Texte du label en dégradé violet-rosé subtil (signature site) — clairement
     "Enduria action" sans crier. */
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0.01em;
  color: var(--paper);
  text-transform: uppercase;
  opacity: 0.7;
}
.pros-basket__ico {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  color: #c5b3e1;
}
[data-theme="light"] .pros-basket__ico {
  color: #8e5fae;
}

/* Slot interne : zone où les cartes triées seront déposées (sous-étape 2).
   Vide pour l'instant (les cartes restent dans .pros-stack en sous-étape 1). */
.pros-basket__slot {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 0;
}

/* ===== Badge "✓ Envoyé" sur les cartes (payoff) =====
   Superposé au .pros-card__status (mêmes coordonnées : flex à droite). Quand le
   parent .pros-card prend .is-sent, le badge fade-in (opacity + scale) et le statut
   précédent fade-out → on a l'illusion que le statut a basculé en "Envoyé". */
.pros-card__sent {
  position: absolute;
  top: 50%;
  right: 12px;
  transform: translateY(-50%) scale(0.85);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 7px 3px 5px;
  border-radius: 999px;
  /* Dégradé violet-rosé translucide : on garde la teinte signature CTA mais soft
     pour ne pas hurler dans la carte. Texte foncé pour lisibilité sur fond clair. */
  background: linear-gradient(135deg, #d1acdf 0%, #c5d0ff 100%);
  color: #0b0c0e;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 9.5px;
  letter-spacing: 0.01em;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.10);
  transition:
    opacity 0.35s var(--ease-out),
    transform 0.45s var(--spring);
}
.pros-card__sent-ico {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
}
.pros-card.is-sent .pros-card__sent {
  opacity: 1;
  transform: translateY(-50%) scale(1);
}
/* Statut d'origine fade-out doucement quand le badge apparaît → swap propre. */
.pros-card__status {
  transition: opacity 0.3s var(--ease-out);
}
.pros-card.is-sent .pros-card__status {
  opacity: 0;
}

/* ===== Bouton "Tout envoyer" (payoff) — apparaît au CENTRE du panneau =====
   Style cousin des CTA du site : pilule à dégradé violet-rosé (#d1acdf→#c5d0ff),
   texte foncé, légère ombre + glow violet pour le présenter comme un vrai bouton
   cliquable. Caché par défaut (opacity 0, scale 0.92) ; .is-visible le révèle ;
   .is-pressed simule le clic de l'agent (scale down + halo flash). */
.pros-send {
  position: absolute;
  /* Centré horizontalement, à mi-hauteur du panel (entre les paniers et la stack
     vide où les cartes étaient avant d'être triées). */
  left: 50%;
  top: 56%;
  transform: translate(-50%, -50%) scale(0.92);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px 9px 14px;
  border: none;
  border-radius: 999px;
  background: linear-gradient(135deg, #d1acdf 0%, #c5d0ff 100%);
  color: #0b0c0e;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: default;     /* anim — pas d'interaction utilisateur */
  pointer-events: none;
  opacity: 0;
  z-index: 6;          /* au-dessus des cartes droppées (z-index 5 quand grabbed) */
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.18),
    0 10px 28px -8px rgba(199, 178, 224, 0.55);
  will-change: transform, opacity, box-shadow;
  transition:
    opacity 0.4s var(--ease-out),
    transform 0.45s var(--spring),
    box-shadow 0.3s var(--ease-out);
}
.pros-send__ico {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.pros-send.is-visible {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
/* État cliqué : scale léger vers le bas + halo en double anneau violet-rosé
   qui simule le ripple/feedback de pression. */
.pros-send.is-pressed {
  transform: translate(-50%, -50%) scale(0.94);
  box-shadow:
    0 0 0 6px rgba(209, 172, 223, 0.32),
    0 0 0 14px rgba(197, 208, 255, 0.16),
    0 2px 6px rgba(0, 0, 0, 0.18),
    0 10px 28px -8px rgba(199, 178, 224, 0.55);
}

/* ===== Curseur "Agent Enduria" — ENSEMBLE [flèche custom + pilule label] =====
   Position au repos = bas-droite (sous la stack des cartes). C'est de là que l'agent
   partira piocher (sous-étape suivante).
   Wrapper en flex column : flèche EN HAUT (sa pointe top-left = position réelle du
   curseur), pilule EN DESSOUS légèrement décalée à droite — convention "cursor avec
   label trailing" (macOS / Figma).
   L'ensemble se déplace solidairement : pour animer le curseur, le JS translatera
   seulement .panel-pros__cursor → la flèche et la pilule suivent ensemble. */
.panel-pros__cursor {
  position: absolute;
  bottom: 14px;
  right: 14px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  pointer-events: none;
  z-index: 10;
  will-change: transform;
}

/* Flèche custom : SVG 20×20 affichée à 16px, légèrement inclinée vers la gauche
   (convention curseur de pointeur). Drop-shadow douce pour la détacher du fond. */
.panel-pros__cursor-arrow {
  width: 16px;
  height: 16px;
  display: block;
  flex-shrink: 0;
  transform: rotate(-6deg);
  transform-origin: 25% 25%;   /* pivot près de la pointe pour rotation lisible */
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.25));
}

/* Pilule "Agent Enduria" : décalée vers la droite par rapport à la pointe de la
   flèche (label trailing). Reprend les specs Figma 284:103 (fond #f3f3f3, radius 10). */
.panel-pros__cursor-pill {
  margin-left: 12px;          /* offset horizontal = label "à côté" de la flèche */
  margin-top: -2px;           /* léger chevauchement vertical = label "collé" à la base de la flèche */
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px 6px 6px;
  height: 29px;
  border-radius: 10px;
  background: #f3f3f3;
  border: 1px solid rgba(12, 13, 16, 0.04);
  box-shadow:
    0 1px 3px rgba(0, 0, 0, 0.10),
    0 4px 12px -4px rgba(0, 0, 0, 0.18);
}
.panel-pros__cursor-logo {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  /* currentColor pilote les dots du pattern → on contrôle la teinte du logo
     pointillé par color sur le parent (violet sombre Enduria). */
  color: #3320A1;
}
.panel-pros__cursor-label {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 12px;
  line-height: 1;
  color: #0b0c0e;
  white-space: nowrap;
}

/* prefers-reduced-motion : cartes affichées en statique (état final), pas d'anim. */
@media (prefers-reduced-motion: reduce) {
  .pros-card,
  .pros-card.al-enter,
  .pros-card.al-enter-active {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ===================================================================
   STORYBOARD_PANEL4 — Panel "Service client, 24/7" : fenêtre de chat.
   Sous-étape 1 : décor (en-tête minimal Assistant Enduria + heure 24/7)
   + conversation 1 jouée (bulle client → typing dots → agent typewriter
   → bulle client merci) avec mécanique FLIP hero pour l'apparition et
   l'empilement des bulles.

   Réutilisations : var(--spring) partagée (linear sur-amortie hero),
   pattern d'entrée .al-enter/.al-enter-active cousin des panels 3 et
   du hero animated-list. Typewriter piloté par JS (setTimeout, cf
   panel4-chat.js) sur .chat-bubble__typewriter (même style que
   .ft-typewriter panel 1 / .panel-rep__bar-typewriter panel 2).
   ===================================================================*/

.metiers__panel[data-panel="4"] {
  background: transparent;
  border-color: transparent;
  place-items: start stretch;
  overflow: visible;
}
.metiers__panel > .panel-chat {
  width: 100%;
  height: 100%;
  align-self: stretch;
  justify-self: stretch;
}

/* Chat imbriqué directement dans le panneau : PAS de "fenêtre" autour.
   Ni fond, ni bordure, ni ombre — les bulles flottent dans le panneau
   comme les autres panels (file tree, prospection). Spring partagée
   (identique panel 3) pour le feel FLIP hero. */
.panel-chat {
  --spring: linear(
    0, 0.0276, 0.0928, 0.1763, 0.2662, 0.3552, 0.4392, 0.516, 0.5849, 0.6456,
    0.6986, 0.7444, 0.7838, 0.8174, 0.8461, 0.8704, 0.891, 0.9084, 0.9231,
    0.9355, 0.9458, 0.9546, 0.9619, 0.9681, 0.9733, 0.9776, 0.9812, 0.9843,
    0.9868, 0.989, 0.9908, 0.9923, 0.9935, 0.9946, 0.9955, 0.9962, 0.9968,
    0.9973, 0.9978, 0.9981, 0.9984
  );
  position: relative;
  margin: auto;
  width: min(360px, 96%);
  min-height: 420px;
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
}

/* En-tête compacte : avatar (logo Enduria pointillé) + nom + pastille
   "en ligne". Pas de séparateur visuel (pas de border-bottom) → tout
   respire dans le panneau sans cadre de fenêtre. */
.panel-chat__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 2px 14px;
}
.panel-chat__avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #d1acdf 0%, #c5d0ff 100%);
}
.panel-chat__avatar-logo {
  width: 15px;
  height: 15px;
  /* Logo pointillé en sombre — meilleur contraste sur le dégradé pastel
     violet-rosé de l'avatar (le blanc se noyait dans le fond clair). */
  color: #0b0c0e;
}
.panel-chat__head-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}
.panel-chat__name {
  font-weight: 500;
  font-size: 13px;
  line-height: 1;
  color: var(--paper);
  letter-spacing: -0.005em;
}
.panel-chat__status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-weight: 400;
  font-size: 10.5px;
  line-height: 1;
  color: var(--text-tertiary);
}
.panel-chat__status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #22c55e;
  box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18);
  flex-shrink: 0;
}

/* Corps du chat : container scrollable en théorie (jamais nécessaire vu
   la longueur). Padding retiré latéralement (le chat n'a plus de "fenêtre"
   qui l'entoure → alignement des bulles direct sur le panel). */
.panel-chat__body {
  flex: 1;
  padding: 4px 2px 8px;
  overflow: hidden;
}
.chat-stack {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 100%;
  justify-content: flex-start;
}

/* ===== Bulle de chat =====
   Base commune : max-width 76%, radius 14 avec un coin "queue" moins
   arrondi (côté expéditeur), padding compact. Typo Geist 13px lisible.
   L'alignement gauche/droite est piloté par les modifiers --client / --agent. */
.chat-bubble {
  list-style: none;
  max-width: 78%;
  padding: 8px 12px;
  border-radius: 14px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13px;
  line-height: 1.35;
  letter-spacing: -0.003em;
  word-wrap: break-word;
  transform-origin: bottom center;
  will-change: transform, opacity;
}

/* CLIENT (gauche) : gris neutre clair, texte sombre, coin bas-gauche
   moins arrondi (queue de bulle du côté expéditeur). */
.chat-bubble--client {
  align-self: flex-start;
  background: #eeeeee;
  color: #0c0d10;
  border-bottom-left-radius: 4px;
}
[data-theme="light"] .chat-bubble--client {
  background: #f1f0ec;
}

/* AGENT (droite) : dégradé signature violet-rosé, texte clair,
   coin bas-droite moins arrondi. */
.chat-bubble--agent {
  align-self: flex-end;
  background: linear-gradient(135deg, #d1acdf 0%, #c5d0ff 100%);
  color: #1a1030;   /* texte sombre-violet pour rester lisible sur le dégradé pastel */
  border-bottom-right-radius: 4px;
  box-shadow: 0 2px 8px -2px rgba(197, 172, 223, 0.35);
}

/* Curseur du typewriter (dans la bulle agent) : trait fin qui clignote
   pendant l'écriture, retiré une fois le texte complet. */
.chat-bubble__typewriter {
  white-space: pre-wrap;
}
.chat-bubble__caret {
  display: inline-block;
  width: 1px;
  height: 0.95em;
  margin-left: 1px;
  vertical-align: -1px;
  background: currentColor;
  opacity: 0.85;
  animation: chat-caret-blink 0.9s steps(2, end) infinite;
}
.chat-bubble.is-typed .chat-bubble__caret {
  display: none;
}
@keyframes chat-caret-blink {
  0%, 50%    { opacity: 0.85; }
  50.01%,100%{ opacity: 0; }
}

/* ===== Entrée FLIP (identique hero animated-list / panel 3) =====
   .al-enter        → opacity 0 + translateY 12px + scale 0.96
   .al-enter-active → opacity 1 + translateY 0 + scale 1
   Courbe = var(--spring) partagée (linear sur-amortie hero, aucun overshoot).
   Durée 0.55s (calée sur ENTER_MS côté JS).
   L'empilement des bulles existantes lors de l'apparition d'une nouvelle
   est piloté par le JS (mesure top avant/après, translateY(delta) sans
   transition, RAF, remise à 0 avec transition spring FLIP_MS ~700ms). */
.chat-bubble.al-enter {
  opacity: 0;
  transform: translateY(12px) scale(0.96);
}
.chat-bubble.al-enter-active {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition:
    opacity 0.55s var(--spring),
    transform 0.55s var(--spring);
}

/* ===== Indicateur "en train d'écrire" (3 points pulsés) =====
   Même côté que les bulles agent (droite) puisque c'est l'agent qui écrit.
   Rendu compact façon bulle : radius 14, fond clair discret, 3 dots qui
   pulsent avec un décalage → sensation de rythme humain. CSS pur, pas de JS. */
.chat-typing {
  list-style: none;
  /* Côté AGENT (droite) puisque c'est l'agent qui écrit sa réponse. */
  align-self: flex-end;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 10px 12px;
  border-radius: 14px;
  border-bottom-right-radius: 4px;
  background: rgba(197, 172, 223, 0.22);
  border: 1px solid rgba(197, 172, 223, 0.32);
  transform-origin: bottom right;
  will-change: transform, opacity;
}
[data-theme="light"] .chat-typing {
  background: rgba(197, 172, 223, 0.28);
  border-color: rgba(197, 172, 223, 0.42);
}
.chat-typing__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: linear-gradient(135deg, #d1acdf 0%, #c5d0ff 100%);
  opacity: 0.55;
  animation: chat-typing-pulse 1.1s ease-in-out infinite;
}
.chat-typing__dot:nth-child(2) { animation-delay: 0.15s; }
.chat-typing__dot:nth-child(3) { animation-delay: 0.30s; }
@keyframes chat-typing-pulse {
  0%, 60%, 100% { opacity: 0.35; transform: translateY(0);     }
  30%           { opacity: 1;    transform: translateY(-3px);  }
}
/* Entrée / sortie de l'indicateur typing (fade + scale, court). */
.chat-typing.al-enter {
  opacity: 0;
  transform: translateY(8px) scale(0.94);
}
.chat-typing.al-enter-active {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition:
    opacity 0.28s var(--spring),
    transform 0.28s var(--spring);
}
.chat-typing.is-leaving {
  opacity: 0;
  transform: translateY(-4px) scale(0.96);
  transition:
    opacity 0.22s var(--ease-out),
    transform 0.22s var(--ease-out);
}

/* prefers-reduced-motion : conversation affichée en statique, pas d'anim. */
@media (prefers-reduced-motion: reduce) {
  .chat-bubble,
  .chat-bubble.al-enter,
  .chat-bubble.al-enter-active,
  .chat-typing,
  .chat-typing.al-enter,
  .chat-typing.al-enter-active {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .chat-typing__dot { animation: none !important; opacity: 0.55 !important; }
  .chat-bubble__caret { animation: none !important; opacity: 0 !important; }
}

/* ===================================================================
   STORYBOARD_PANEL5 V2 — Panel "Paiements & impayés" : demi-dashboard.

   REFONTE COMPLÈTE : l'ancienne version (une facture qui morph seule)
   n'était pas assez lisible. Nouveau concept = une DEMI-INTERFACE de
   dashboard (moitié gauche visible, côté droit fond en dégradé vers
   transparent → "on regarde dans un vrai outil"). Contenu : 2 KPI
   cards en haut (En attente orange / Encaissé vert) + une liste de
   3 factures impayées.

   Sous-étape 1 (ICI) : DÉCOR STATIQUE. Cadre premium + fondu droite
   via mask-image linear-gradient (statique, aucune anim sur le mask) +
   les 2 KPI à l'état initial + les 3 lignes factures "En retard".

   Sous-étapes à venir :
   2. L'agent traite les factures une par une (statut → Payé) +
      compteurs animés qui bougent en sync (En attente ↓ / Encaissé ↑).
   3. Payoff final + boucle + data-duration final.

   ⚠️ PERF : mask-image linear-gradient CSS statique (aucune anim sur le
   mask → 0 coût par frame). Aucun WebGL, aucun mask SVG lourd. Testé
   fluide Chrome/Safari.
   ===================================================================*/

.metiers__panel[data-panel="5"] {
  background: transparent;
  border-color: transparent;
  place-items: stretch;
  overflow: visible;
}
.metiers__panel > .panel-dash {
  width: 100%;
  height: 100%;
  align-self: stretch;
  justify-self: stretch;
}

.panel-dash {
  --spring: linear(
    0, 0.0276, 0.0928, 0.1763, 0.2662, 0.3552, 0.4392, 0.516, 0.5849, 0.6456,
    0.6986, 0.7444, 0.7838, 0.8174, 0.8461, 0.8704, 0.891, 0.9084, 0.9231,
    0.9355, 0.9458, 0.9546, 0.9619, 0.9681, 0.9733, 0.9776, 0.9812, 0.9843,
    0.9868, 0.989, 0.9908, 0.9923, 0.9935, 0.9946, 0.9955, 0.9962, 0.9968,
    0.9973, 0.9978, 0.9981, 0.9984
  );
  position: relative;
  padding: 8px 0;
  display: flex;
  align-items: center;
  font-family: var(--font-display);
}

/* ===== .dash — LE demi-dashboard =====
   Astuce "moitié de dashboard" : la largeur EXCÈDE la largeur du panneau
   (width supérieure à 100% + décalage à gauche = 0) → le contenu déborde
   naturellement à droite HORS du panneau. Le mask-image linear-gradient
   fond ce débordement en douceur vers transparent → effet "on voit une
   moitié de vrai outil, ça continue hors cadre".

   Cadre premium : fond sombre discret, radius généreux (comme un vrai
   card d'app), border fine, ombre douce. Le fond n'a PAS de points
   animés cette fois (message plus produit, plus concret). */
.dash {
  position: relative;
  isolation: isolate;
  width: 128%;
  max-width: 620px;
  padding: 0;
  border-radius: 16px 0 0 16px;   /* radius sur la gauche uniquement (le droit part en fondu) */
  background: linear-gradient(180deg, #14161c 0%, #0e1015 100%);
  border: 1px solid rgba(242, 241, 236, 0.08);
  border-right: none;              /* pas de bord droit visible : il se fond */
  box-shadow:
    0 1px 3px rgba(0, 0, 0, 0.35),
    0 26px 50px -18px rgba(0, 0, 0, 0.45);
  color: var(--paper);
  overflow: hidden;
  display: flex;
  flex-direction: column;

  /* ===== FONDU DROITE — clé du concept "demi-dashboard" =====
     Mask-image linear-gradient statique : le contenu est complètement
     opaque de 0% à 62%, puis fond en douceur vers transparent à 100%.
     Résultat : le côté droit du dashboard disparaît en dégradé,
     suggérant qu'il continue hors cadre. Aucune anim = coût 0. */
  -webkit-mask-image: linear-gradient(to right, #000 0%, #000 62%, transparent 100%);
          mask-image: linear-gradient(to right, #000 0%, #000 62%, transparent 100%);
  will-change: auto;
  transform-origin: left center;
}
/* Light mode : fond clair du dashboard + border/shadow adaptés. Les enfants
   utilisent des rgba blancs (opaques sur fond dark) qui deviennent invisibles
   sur fond blanc → on les ré-inverse en rgba noirs juste en dessous. */
[data-theme="light"] .dash {
  background: linear-gradient(180deg, #ffffff 0%, #fafaf7 100%);
  border-color: rgba(12, 13, 16, 0.10);
  box-shadow:
    0 1px 3px rgba(12, 13, 16, 0.06),
    0 20px 40px -18px rgba(12, 13, 16, 0.18);
}

/* ===== Header du dashboard : titre + tabs (Impayés / Toutes / Payées) ===== */
.dash__head {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 14px 20px;
  border-bottom: 1px solid rgba(242, 241, 236, 0.06);
}
.dash__head-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
  font-size: 13px;
  color: var(--paper);
  letter-spacing: -0.005em;
}
.dash__head-ico {
  width: 15px;
  height: 15px;
  color: #c5b3e1;   /* violet-rosé signature */
}
.dash__head-tabs {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px;
  border-radius: 8px;
  background: rgba(242, 241, 236, 0.04);
}
.dash__head-tab {
  padding: 4px 10px;
  border-radius: 6px;
  font-weight: 500;
  font-size: 11px;
  color: var(--text-tertiary);
  letter-spacing: 0.005em;
}
.dash__head-tab.is-active {
  background: rgba(242, 241, 236, 0.08);
  color: var(--paper);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

/* ===== 2 KPI cards : "En attente" / "Encaissé" =====
   Grid 2 colonnes, gap étroit, chaque KPI porte son propre accent via
   [data-tone]. */
.dash__kpis {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding: 14px 20px;
}
.dash__kpi {
  position: relative;
  padding: 12px 13px 12px;
  border-radius: 10px;
  background: rgba(242, 241, 236, 0.03);
  border: 1px solid rgba(242, 241, 236, 0.06);
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color 0.35s var(--ease-out), background 0.35s var(--ease-out);
}
.dash__kpi-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.dash__kpi-label {
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.dash__kpi-trend {
  width: 16px;
  height: 16px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(242, 241, 236, 0.05);
  color: var(--text-tertiary);
}
.dash__kpi-trend svg { width: 10px; height: 10px; }
.dash__kpi-amount {
  font-weight: 500;
  font-size: 22px;
  line-height: 1;
  letter-spacing: -0.015em;
  color: var(--paper);
  font-variant-numeric: tabular-nums;
  transition: color 0.4s var(--ease-out);
}
.dash__kpi-amount-val { font-variant-numeric: tabular-nums; }
.dash__kpi-amount-unit { opacity: 0.75; }
.dash__kpi-bar {
  height: 4px;
  border-radius: 2px;
  background: rgba(242, 241, 236, 0.06);
  overflow: hidden;
  margin-top: 2px;
}
.dash__kpi-bar-fill {
  height: 100%;
  width: var(--fill, 0%);
  border-radius: 2px;
  transition: width 0.5s var(--spring), background 0.35s var(--ease-out);
}
.dash__kpi-meta {
  font-weight: 400;
  font-size: 10.5px;
  color: var(--text-tertiary);
  letter-spacing: 0.005em;
}

/* Teinte "pending" : accent orange sur amount, trend et bar. */
.dash__kpi[data-tone="pending"] .dash__kpi-amount { color: #fb923c; }
.dash__kpi[data-tone="pending"] .dash__kpi-trend {
  background: rgba(251, 146, 60, 0.14);
  color: #fb923c;
}
.dash__kpi[data-tone="pending"] .dash__kpi-bar-fill {
  background: linear-gradient(90deg, #fb923c 0%, #f97316 100%);
}

/* Teinte "cashed" : accent vert sur amount, trend et bar. */
.dash__kpi[data-tone="cashed"] .dash__kpi-amount { color: #4ade80; }
.dash__kpi[data-tone="cashed"] .dash__kpi-trend {
  background: rgba(74, 222, 128, 0.14);
  color: #4ade80;
}
.dash__kpi[data-tone="cashed"] .dash__kpi-bar-fill {
  background: linear-gradient(90deg, #4ade80 0%, #22c55e 100%);
}

/* ===== Section "Impayés" : titre + count + tableau ===== */
.dash__section {
  padding: 4px 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.dash__section-head {
  position: relative;   /* ancre pour .dash__paidoff-badge en absolute */
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 4px 8px;
}
.dash__section-title {
  font-weight: 500;
  font-size: 12px;
  color: var(--paper);
  letter-spacing: -0.005em;
}
.dash__section-count {
  font-weight: 500;
  font-size: 10.5px;
  color: var(--text-tertiary);
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(242, 241, 236, 0.06);
  font-variant-numeric: tabular-nums;
}
.dash__section-spacer { flex: 1; }
.dash__section-action {
  font-weight: 400;
  font-size: 11px;
  color: var(--text-tertiary);
  letter-spacing: 0.005em;
}

/* Liste : simple ul, gap fin entre les rows. */
.dash__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* ===== Ligne facture — layout tableau =====
   Grid : avatar (24px) | main (client + ref, 1fr) | montant (auto) | status (auto).
   Padding compact, séparateur hairline entre rows via border-bottom. */
.dash-row {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  padding: 10px 8px;
  border-radius: 8px;
  transition: background 0.25s var(--ease-out);
}
.dash-row + .dash-row {
  border-top: 1px solid rgba(242, 241, 236, 0.05);
}

/* Avatar cercle avec la 1ère lettre du client — cousin visuel des avatars
   panel 3 mais en initiale (pas de vraie photo, plus "dashboard-y"). */
.dash-row__avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 500;
  font-size: 11px;
  color: var(--paper);
  background: linear-gradient(135deg, rgba(197, 172, 223, 0.35), rgba(197, 208, 255, 0.25));
  letter-spacing: 0;
}

.dash-row__main {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.dash-row__client {
  font-weight: 500;
  font-size: 12.5px;
  color: var(--paper);
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dash-row__ref {
  font-weight: 400;
  font-size: 10.5px;
  color: var(--text-tertiary);
  letter-spacing: 0.005em;
}

.dash-row__amount {
  font-weight: 500;
  font-size: 12.5px;
  color: var(--paper);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.005em;
}

.dash-row__status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0.005em;
}
.dash-row__status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* État "late" (défaut de sous-étape 1) : accent orange + pastille pulsée subtile. */
.dash-row[data-state="late"] .dash-row__status-text { color: #fb923c; }
.dash-row[data-state="late"] .dash-row__status-dot {
  background: #fb923c;
  box-shadow: 0 0 0 3px rgba(251, 146, 60, 0.16);
  animation: dash-late-pulse 2.4s ease-in-out infinite;
}
@keyframes dash-late-pulse {
  0%, 100% { transform: scale(1);    opacity: 1;    }
  50%      { transform: scale(1.15); opacity: 0.72; }
}

/* ===== États pilotés par le JS pendant la cascade (sous-étape 2) =====
   processing → l'IA agit sur cette facture (indicateur violet-rosé signature).
   sent       → relance envoyée, transitoire.
   paid       → encaissée, accent vert.
   Transitions bg/color en GPU compositing (color/opacity), aucune reflow. */

/* Transition douce du background quand la ligne change d'état. */
.dash-row { transition: background 0.35s var(--ease-out), box-shadow 0.35s var(--ease-out); }
.dash-row__amount { transition: color 0.4s var(--ease-out); }
.dash-row__status-text { transition: color 0.35s var(--ease-out); }
.dash-row__status-dot { transition: background 0.35s var(--ease-out), box-shadow 0.35s var(--ease-out); }

/* processing : ligne surlignée en violet-rosé + label "Agent en cours…" pulsé. */
.dash-row[data-state="processing"] {
  background: rgba(197, 172, 223, 0.08);
  box-shadow: inset 2px 0 0 rgba(197, 172, 223, 0.55);
}
.dash-row[data-state="processing"] .dash-row__status-text { color: #c5b3e1; }
.dash-row[data-state="processing"] .dash-row__status-dot {
  background: #c5b3e1;
  box-shadow: 0 0 0 3px rgba(197, 172, 223, 0.24);
  animation: dash-agent-pulse 0.85s ease-in-out infinite;
}
@keyframes dash-agent-pulse {
  0%, 100% { transform: scale(1);   opacity: 1;   }
  50%      { transform: scale(1.4); opacity: 0.55;}
}

/* sent : relance envoyée — bleu clair, transitoire. */
.dash-row[data-state="sent"] .dash-row__status-text { color: #93c5fd; }
.dash-row[data-state="sent"] .dash-row__status-dot {
  background: #93c5fd;
  box-shadow: 0 0 0 3px rgba(147, 197, 253, 0.16);
  animation: none;
}

/* paid : encaissée — accent vert (dot + status + amount). */
.dash-row[data-state="paid"] {
  background: rgba(74, 222, 128, 0.05);
}
.dash-row[data-state="paid"] .dash-row__status-text { color: #4ade80; }
.dash-row[data-state="paid"] .dash-row__status-dot {
  background: #4ade80;
  box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.16);
  animation: none;
}
.dash-row[data-state="paid"] .dash-row__amount { color: #4ade80; }

/* ===== SOUS-ÉTAPE 3 — BORDER BEAM =====
   Segment lumineux violet-rosé (DA signature) qui parcourt le CONTOUR du
   cadre du dashboard en boucle. Technique cousine du .vs-center__node de
   la section versus : un ::before qui reçoit un conic-gradient (wedge
   étroit → trail lumineux), masqué via mask-composite: xor pour ne
   révéler que l'anneau border (padding: 1px). L'angle du gradient est
   animé via @property → rotation continue.

   PERF :
   - Aucun élément HTML ajouté (juste un pseudo-elem).
   - Le conic-gradient est un fill de fond ; mask-composite est compositée
     une fois par frame côté GPU. Coût par frame = repaint d'un rect,
     négligeable.
   - Pausé hors viewport via .dash.is-off-screen (IntersectionObserver JS).
   - La portion droite du beam tombe dans le fondu existant du .dash
     (mask-image linear-gradient) → naturellement invisible côté droit,
     ce qui renforce l'illusion "on regarde une moitié d'app". Zéro clip
     supplémentaire à gérer. */
@property --dash-beam-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
.dash::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(
    from var(--dash-beam-angle, 0deg),
    transparent 0deg,
    rgba(197, 179, 225, 0.18) 4deg,
    rgba(197, 179, 225, 0.62) 14deg,
    rgba(232, 210, 255, 1.00) 24deg,     /* peak violet-rosé signature */
    rgba(197, 179, 225, 0.62) 34deg,
    rgba(197, 179, 225, 0.18) 44deg,
    transparent 56deg,
    transparent 360deg
  );
  /* mask-composite: xor → ne montre que l'anneau (padding-box minus content-box). */
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
          mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
  z-index: 3;
  animation: dash-beam-rotate 5.5s linear infinite;
}
@keyframes dash-beam-rotate {
  to { --dash-beam-angle: 360deg; }
}
/* Pausé hors viewport (IntersectionObserver côté JS toggle .is-off-screen). */
.dash.is-off-screen::before { animation-play-state: paused; }

/* ===== SOUS-ÉTAPE 3 — BADGE PAYOFF "Tout est encaissé ✓" =====
   Absolute dans .dash__section-head → ne casse pas le layout flex du
   header, se superpose (fade + translateX depuis la droite) à l'action
   "Trier par…" qui s'efface en simultané. Discret : petit pill vert
   cousin visuel des accents .dash-row[data-state="paid"]. */
.dash__paidoff-badge {
  position: absolute;
  right: 4px;
  top: 50%;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px 3px;
  border-radius: 999px;
  font-weight: 500;
  font-size: 10.5px;
  color: #4ade80;
  background: rgba(74, 222, 128, 0.10);
  border: 1px solid rgba(74, 222, 128, 0.28);
  letter-spacing: 0.005em;
  white-space: nowrap;
  opacity: 0;
  transform: translate3d(6px, -50%, 0);
  transition:
    opacity 0.4s var(--ease-out),
    transform 0.45s var(--spring);
  pointer-events: none;
}
.dash__paidoff-badge svg {
  width: 10px;
  height: 10px;
  color: #4ade80;
}
.dash__section-action {
  transition: opacity 0.3s var(--ease-out);
}

.dash.is-paid-off .dash__paidoff-badge {
  opacity: 1;
  transform: translate3d(0, -50%, 0);
}
.dash.is-paid-off .dash__section-action {
  opacity: 0;
}
/* Glow discret sur la KPI "Encaissé" quand tout est payé — cousin visuel
   des états paid des lignes. Le pulse (scale yoyo) est piloté par GSAP côté
   JS et s'ajoute par-dessus ce glow. */
.dash__kpi[data-tone="cashed"] {
  transition:
    border-color 0.4s var(--ease-out),
    background 0.4s var(--ease-out),
    box-shadow 0.55s var(--ease-out);
}
.dash.is-paid-off .dash__kpi[data-tone="cashed"] {
  border-color: rgba(74, 222, 128, 0.32);
  background: rgba(74, 222, 128, 0.055);
  box-shadow:
    0 0 0 1px rgba(74, 222, 128, 0.18),
    0 8px 26px -10px rgba(74, 222, 128, 0.35);
}

/* ===== LIGHT MODE — Panel 5 dashboard =====
   Le fond .dash a déjà été overridé en blanc plus haut. Ici on ré-inverse
   tous les rgba(242, 241, 236, X) (blanc-cassé sur fond sombre) en
   rgba(12, 13, 16, X) (noir sur fond clair) pour que les hairlines, tabs,
   KPI cards, barre KPI, count section et separators de rows restent
   visibles avec le MÊME poids visuel. Les couleurs de texte (var(--paper),
   var(--text-tertiary)) et les accents colorés (orange/vert/violet) sont
   auto-adaptatifs et n'ont pas besoin d'override. */
[data-theme="light"] .dash__head {
  border-bottom-color: rgba(12, 13, 16, 0.08);
}
[data-theme="light"] .dash__head-tabs {
  background: rgba(12, 13, 16, 0.04);
}
[data-theme="light"] .dash__head-tab.is-active {
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 1px 2px rgba(12, 13, 16, 0.08), 0 0 0 1px rgba(12, 13, 16, 0.06);
}
[data-theme="light"] .dash__kpi {
  background: rgba(12, 13, 16, 0.03);
  border-color: rgba(12, 13, 16, 0.08);
}
[data-theme="light"] .dash__kpi-trend {
  background: rgba(12, 13, 16, 0.05);
}
[data-theme="light"] .dash__kpi-bar {
  background: rgba(12, 13, 16, 0.06);
}
[data-theme="light"] .dash__section-count {
  background: rgba(12, 13, 16, 0.06);
}
[data-theme="light"] .dash-row + .dash-row {
  border-top-color: rgba(12, 13, 16, 0.06);
}
/* États des rows (processing/paid) : les tints violet/vert sont légèrement
   remontés en light pour compenser le fond blanc (0.08 → 0.10 environ). */
[data-theme="light"] .dash-row[data-state="processing"] {
  background: rgba(115, 92, 168, 0.09);
  box-shadow: inset 2px 0 0 rgba(115, 92, 168, 0.55);
}
[data-theme="light"] .dash-row[data-state="processing"] .dash-row__status-text {
  color: #735ca8;
}
[data-theme="light"] .dash-row[data-state="paid"] {
  background: rgba(34, 197, 94, 0.06);
}
/* Badge payoff en light : garde le vert accent, mais fond/border un peu plus
   marqués pour rester lisibles sur blanc. */
[data-theme="light"] .dash__paidoff-badge {
  background: rgba(34, 197, 94, 0.10);
  border-color: rgba(34, 197, 94, 0.32);
}
/* Border beam (::before) : le peak violet-rosé du conic-gradient garde son
   éclat, mais on ne cast plus un halo blanc sur blanc — la conic reste OK
   telle quelle car les stops utilisent des rgba violet-rosé qui rendent bien
   sur les 2 fonds. Rien à changer ici. */

/* ===== Entrée FLIP du dashboard (identique autres panels) =====
   Déclenché par le JS sur metiers:activate (idx=4). La cascade des enfants
   (header/kpis/rows) depuis la droite est gérée en GSAP côté JS. */
.dash.al-enter {
  opacity: 0;
  transform: translateY(14px) scale(0.98);
}
.dash.al-enter-active {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition:
    opacity 0.65s var(--spring),
    transform 0.65s var(--spring);
}

/* prefers-reduced-motion : tout figé, dashboard visible, pastille "late" sans pulse,
   trail arrêté, badge payoff invisible (pas d'anim intrusive). */
@media (prefers-reduced-motion: reduce) {
  .dash,
  .dash.al-enter,
  .dash.al-enter-active {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .dash-row[data-state="late"] .dash-row__status-dot,
  .dash-row[data-state="processing"] .dash-row__status-dot {
    animation: none !important;
  }
  .dash::before { animation: none !important; opacity: 0 !important; }
  .dash__paidoff-badge { transition: none !important; }
}

/* ====================================================================
   STORYBOARD_PANEL6 — Panel "Planning & RDV" : zone VOIX (sous-étape 1).

   L'utilisateur parle à l'agent en langage naturel (simulé) → l'agent
   comprend et cale un RDV. Cette sous-étape 1 traite UNIQUEMENT la
   zone voix (haut du panneau) : micro + waveform + label + transcript.

   Layout : mic (56px rond) + waveform inline sur une ligne haute, puis
   label "À l'écoute…" et transcript typewriter en dessous. Centré
   verticalement dans le panneau (les sous-étapes 2/3 ajouteront un
   calendrier dessous et rééquilibreront l'axe vertical).

   PERF :
   - Waveform : 40 barres <span>, chacune anime scaleY via keyframes CSS
     avec --dur et --amp aléatoires par barre (posés en inline par le JS
     à l'init). Aucune boucle RAF, aucun tween GSAP → l'animation vit
     100% côté compositing GPU.
   - Halo micro : ring ::after, scale + opacity keyframes.
   - Typewriter : 1 setTimeout récursif (identique panels 1/2/4).
   - Pause hors viewport / panneau inactif : classe .voice.is-inactive
     (pilotée par le JS via metiers:activate/deactivate + IntersectionObserver).
   ==================================================================== */

.metiers__panel[data-panel="6"] {
  background: transparent;
  border-color: transparent;
  place-items: stretch;
  overflow: visible;
}
.metiers__panel > .panel-voice {
  width: 100%;
  height: 100%;
  align-self: stretch;
  justify-self: stretch;
  overflow: visible;   /* laisse le .cal déborder à droite (fondu mask) */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 22px;
  padding: 20px 0 20px 22px;
  font-family: var(--font-display);
  /* --spring : ease sur-amortie partagée (cousine des autres panels) — utilisée
     par le RDV target qui se cale + le badge de confirmation. */
  --spring: linear(
    0, 0.0276, 0.0928, 0.1763, 0.2662, 0.3552, 0.4392, 0.516, 0.5849, 0.6456,
    0.6986, 0.7444, 0.7838, 0.8174, 0.8461, 0.8704, 0.891, 0.9084, 0.9231,
    0.9355, 0.9458, 0.9546, 0.9619, 0.9681, 0.9733, 0.9776, 0.9812, 0.9843,
    0.9868, 0.989, 0.9908, 0.9923, 0.9935, 0.9946, 0.9955, 0.9962, 0.9968,
    0.9973, 0.9978, 0.9981, 0.9984
  );
}

/* Conteneur voix : stack vertical (input-row, label, transcript). */
.voice {
  width: 100%;
  max-width: 460px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  color: var(--paper);
}

/* ===== Ligne haute : bouton micro + waveform inline ===== */
.voice__input-row {
  display: flex;
  align-items: center;
  gap: 18px;
}

/* Bouton micro : rond premium, dégradé violet-rosé DA + inset highlight. */
.voice__mic {
  position: relative;
  flex-shrink: 0;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: linear-gradient(135deg, #d1acdf 0%, #a894c8 100%);
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow:
    0 8px 24px rgba(197, 179, 225, 0.30),
    0 2px 6px rgba(0, 0, 0, 0.20),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  cursor: default;
  padding: 0;
  isolation: isolate;
}
[data-theme="light"] .voice__mic {
  box-shadow:
    0 8px 24px rgba(115, 92, 168, 0.22),
    0 2px 6px rgba(0, 0, 0, 0.10),
    inset 0 1px 0 rgba(255, 255, 255, 0.30);
}
.voice__mic-ico {
  width: 22px;
  height: 22px;
  display: block;
}

/* Halo pulsé (ring qui grandit + fade) : ::after révélé par .is-listening. */
.voice__mic::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 2px solid rgba(197, 179, 225, 0.55);
  opacity: 0;
  pointer-events: none;
  z-index: -1;
}
.voice.is-listening .voice__mic::after {
  animation: voice-mic-halo 2s cubic-bezier(0.16, 1, 0.3, 1) infinite;
}
@keyframes voice-mic-halo {
  0%   { transform: scale(0.95); opacity: 0.75; }
  100% { transform: scale(1.85); opacity: 0;    }
}

/* ===== Waveform : ~40 barres fines qui montent/descendent =====
   Chaque barre est un <span> avec :
   - --i (index 0..39) — sert au stagger via animation-delay négatif
   - --dur (durée aléatoire 0.55-1.35s posée par le JS) — hétérogène
   - --amp (amplitude max 0.4-1.0) — hauteur cible par barre
   L'animation `alternate infinite` fait osciller scaleY entre 0.15 et --amp.
   Comme les durées diffèrent, les barres se déphasent au fil du temps → look
   organique (pas de pattern répété visible). */
.voice__wave {
  flex: 1;
  min-width: 0;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 3px;
}
.voice__bar {
  flex: 1;
  min-width: 2px;
  max-width: 4px;
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(180deg, #d1acdf 0%, #a894c8 100%);
  transform: scaleY(0.15);
  transform-origin: center center;
  animation: voice-wave var(--dur, 1s) ease-in-out infinite alternate;
  animation-delay: calc(var(--i, 0) * -73ms);
  animation-play-state: paused;   /* démarre à froid, JS active via .is-listening */
  will-change: transform;
}
@keyframes voice-wave {
  0%   { transform: scaleY(0.15); }
  100% { transform: scaleY(var(--amp, 0.75)); }
}
.voice.is-listening .voice__bar {
  animation-play-state: running;
}
/* Pause explicite hors viewport (IntersectionObserver côté JS). */
.voice.is-inactive .voice__bar,
.voice.is-inactive .voice__mic::after {
  animation-play-state: paused;
}

/* ===== Label 2-états : "À l'écoute…" ↔ "L'agent planifie…" =====
   Crossfade CSS via 2 spans absolute superposés. La hauteur du .voice__label
   est fixée pour éviter tout shift de contenu quand la variante change. */
.voice__label {
  position: relative;
  height: 14px;
  padding-left: 74px;   /* aligne sous la waveform (mic 56px + gap 18px) */
  font-weight: 500;
  font-size: 11.5px;
  color: var(--text-tertiary);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.voice__label-txt {
  position: absolute;
  left: 74px;
  top: 0;
  opacity: 0;
  transform: translateY(3px);
  transition:
    opacity 0.3s var(--ease-out),
    transform 0.3s var(--ease-out);
  white-space: nowrap;
}
.voice.is-listening .voice__label-txt--listening,
.voice.is-processing .voice__label-txt--processing {
  opacity: 1;
  transform: translateY(0);
}
/* Accent violet-rosé sur le libellé "L'agent planifie…" pour signaler qu'on
   passe en mode "traitement" (cohérent avec le glow micro processing). */
.voice__label-txt--processing {
  color: #c5b3e1;
}

/* ===== État PROCESSING (post-typewriter, avant apparition du RDV) =====
   La waveform se calme (transition douce vers un scaleY faible et fixe,
   plus d'oscillation), le micro pulse légèrement (scale interne 1 → 1.04),
   le halo disparaît. Le caret du transcript s'éteint aussi (le message a
   été "envoyé" à l'agent, il n'y a plus de dictée en cours). */
.voice.is-processing .voice__bar {
  animation: none;
  transform: scaleY(0.16);
  transition: transform 0.55s var(--ease-out);
}
.voice.is-processing .voice__mic {
  animation: voice-mic-processing 1.25s ease-in-out infinite;
}
@keyframes voice-mic-processing {
  0%, 100% { transform: scale(1);    box-shadow: 0 8px 24px rgba(197, 179, 225, 0.30), 0 2px 6px rgba(0, 0, 0, 0.20), inset 0 1px 0 rgba(255, 255, 255, 0.22); }
  50%      { transform: scale(1.04); box-shadow: 0 10px 28px rgba(197, 179, 225, 0.55), 0 2px 6px rgba(0, 0, 0, 0.20), inset 0 1px 0 rgba(255, 255, 255, 0.30); }
}
.voice.is-processing .voice__mic::after {
  animation: none;
  opacity: 0;
  transition: opacity 0.3s var(--ease-out);
}
.voice.is-processing .voice__transcript-caret {
  animation: none;
  opacity: 0;
  transition: opacity 0.25s var(--ease-out);
}

/* ===== Transcript typewriter =====
   Bloc "quote" discret pour poser la parole transcrite. Le caret clignote
   via keyframes. Padding généreux + accent violet-rosé sur le bord gauche. */
.voice__transcript {
  padding: 14px 16px 14px 18px;
  border-radius: 10px;
  background: rgba(242, 241, 236, 0.03);
  border: 1px solid rgba(242, 241, 236, 0.06);
  border-left: 2px solid rgba(197, 179, 225, 0.55);
  font-weight: 400;
  font-size: 14px;
  line-height: 1.5;
  color: var(--paper);
  letter-spacing: -0.005em;
  min-height: 3em;
}
[data-theme="light"] .voice__transcript {
  background: rgba(12, 13, 16, 0.03);
  border-color: rgba(12, 13, 16, 0.08);
  border-left-color: rgba(115, 92, 168, 0.55);
}
.voice__transcript-text {
  color: var(--paper);
}
.voice__transcript-caret {
  display: inline-block;
  width: 2px;
  height: 1.05em;
  background: currentColor;
  color: #c5b3e1;
  vertical-align: -3px;
  margin-left: 2px;
  opacity: 0;
  animation: voice-caret 1s steps(2, end) infinite;
  animation-play-state: paused;
}
.voice.is-listening .voice__transcript-caret {
  animation-play-state: running;
}
.voice.is-inactive .voice__transcript-caret {
  animation-play-state: paused;
}
@keyframes voice-caret {
  0%, 50%     { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}

/* ===== Entrée FLIP (identique autres panels) ===== */
.voice.al-enter {
  opacity: 0;
  transform: translateY(14px) scale(0.98);
}
.voice.al-enter-active {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition:
    opacity 0.6s var(--ease-out),
    transform 0.6s var(--ease-out);
}

/* ============================================================
   STORYBOARD_PANEL6 — MINI-CALENDRIER (sous-étape 2).

   Vue semaine simplifiée : gutter horaire (10h/12h/14h/16h) +
   7 colonnes jours. Le contenu déborde à droite (width 122%) et
   fond en dégradé (mask-image linear-gradient) pour suggérer un
   agenda plus large qui continue hors cadre → même astuce que
   .dash du panneau 5 (cohérence de langue).

   Le RDV Martin est présent dans le DOM dès le départ, positionné
   sur Jeudi row 5 (14h), mais invisible (opacity 0 + scale 0.85).
   Il se cale via 2 transitions CSS :
     - .cal.is-scheduled → apparition (opacity + scale + translateY, spring)
     - .cal.is-confirmed → bascule accent vert (background + border-left)
                           + révèle le badge "RDV confirmé" et la notif
                           "Invitation envoyée à Martin" en cascade.

   PERF :
   - Calendrier statique (grille CSS + events posés).
   - Seul le RDV cible + le badge + la notif ont des transitions
     (transform/opacity → GPU).
   - Aucun tween JS, tout est CSS pur, orchestré par les classes
     posées par le module JS.
   ============================================================ */
.cal {
  position: relative;
  isolation: isolate;
  width: 122%;
  max-width: 620px;
  padding: 0 0 42px 0;   /* padding-bottom : réserve pour le footer confirm/notif */
  border-radius: 12px 0 0 12px;
  background: linear-gradient(180deg, #14161c 0%, #0e1015 100%);
  border: 1px solid rgba(242, 241, 236, 0.08);
  border-right: none;
  box-shadow:
    0 1px 3px rgba(0, 0, 0, 0.35),
    0 18px 38px -16px rgba(0, 0, 0, 0.45);
  color: var(--paper);
  overflow: hidden;
  /* Fondu droite (identique .dash panneau 5) — la Sam/Dim col disparaît
     progressivement, ce qui donne le "vrai agenda qui continue hors cadre". */
  -webkit-mask-image: linear-gradient(to right, #000 0%, #000 66%, transparent 100%);
          mask-image: linear-gradient(to right, #000 0%, #000 66%, transparent 100%);
}
[data-theme="light"] .cal {
  background: linear-gradient(180deg, #ffffff 0%, #fafaf7 100%);
  border-color: rgba(12, 13, 16, 0.10);
  box-shadow:
    0 1px 3px rgba(12, 13, 16, 0.06),
    0 14px 30px -14px rgba(12, 13, 16, 0.16);
  /* PAS de override sur color : var(--paper) est déjà auto-adaptatif
     (dark en light mode → bien lisible sur fond blanc). */
}
/* Light mode — INVERSION rgba(242,241,236,X) → rgba(12,13,16,X) sur toutes
   les hairlines/backgrounds légers du calendrier, sinon light-on-light =
   invisible. Les couleurs de texte (var(--paper) / var(--text-tertiary))
   et les accents colorés (violet/vert) s'auto-adaptent, on ne les touche pas. */
[data-theme="light"] .cal__head {
  border-bottom-color: rgba(12, 13, 16, 0.08);
}
[data-theme="light"] .cal__head-nav-btn {
  background: rgba(12, 13, 16, 0.05);
}
[data-theme="light"] .cal__col-head {
  border-bottom-color: rgba(12, 13, 16, 0.07);
}
[data-theme="light"] .cal__col--weekend .cal__col-head {
  color: rgba(12, 13, 16, 0.35);
}
[data-theme="light"] .cal__event--soft {
  background: rgba(12, 13, 16, 0.03);
  border-left-color: rgba(12, 13, 16, 0.15);
}
[data-theme="light"] .cal__event-time {
  color: rgba(12, 13, 16, 0.55);
}
/* RDV confirmé en light : renforce le vert du "→ 16h" (rgba(74,222,128,0.85)
   sur fond vert clair passe très pâle). */
[data-theme="light"] .cal.is-confirmed .cal__event--new .cal__event-time {
  color: #15803d;
}
/* Badge confirm : renforce l'accent vert pour rester lisible sur fond blanc. */
[data-theme="light"] .cal__confirm {
  color: #15803d;
  background: rgba(34, 197, 94, 0.10);
  border-color: rgba(34, 197, 94, 0.32);
}
/* Notif "Invitation envoyée" en light : fond/border en rgba dark. */
[data-theme="light"] .cal__notif {
  background: rgba(12, 13, 16, 0.04);
  border-color: rgba(12, 13, 16, 0.10);
}

/* Header : titre agenda + mini-nav semaine (visuel uniquement). */
.cal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border-bottom: 1px solid rgba(242, 241, 236, 0.06);
}
.cal__head-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
  font-size: 12px;
  color: var(--paper);
  letter-spacing: -0.005em;
}
.cal__head-ico {
  width: 14px;
  height: 14px;
  color: #c5b3e1;
}
.cal__head-nav {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  font-size: 10.5px;
  color: var(--text-tertiary);
  letter-spacing: 0.005em;
}
.cal__head-nav-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  background: rgba(242, 241, 236, 0.05);
  font-size: 12px;
  line-height: 1;
}

/* Grille : gutter horaire (32px) + 7 col jours. */
.cal__grid {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 8px;
  padding: 10px 16px 12px;
}
.cal__gutter {
  display: grid;
  /* Aligné SUR le grid du col-body (7 rows × 18px + 6 gaps × 2px = 138px)
     + offset supérieur pour compenser la hauteur du col-head (≈ 22px). */
  grid-template-rows: repeat(7, 18px);
  gap: 2px;
  padding-top: 22px;
  font-size: 9.5px;
  color: var(--text-tertiary);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.cal__gutter span {
  line-height: 1;
  padding-top: 1px;   /* micro-nudge pour aligner avec le haut de la row */
}
/* Les 4 labels (10h/12h/14h/16h) tombent sur les rows 1/3/5/7 → mêmes lignes
   horaires que le col-body (les autres rows = heures intermédiaires masquées). */
.cal__gutter span:nth-child(1) { grid-row: 1; }
.cal__gutter span:nth-child(2) { grid-row: 3; }
.cal__gutter span:nth-child(3) { grid-row: 5; }
.cal__gutter span:nth-child(4) { grid-row: 7; }
.cal__days {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
}
.cal__col {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.cal__col-head {
  font-size: 10px;
  font-weight: 500;
  color: var(--text-tertiary);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 3px 4px 5px;
  border-bottom: 1px solid rgba(242, 241, 236, 0.05);
  text-align: center;
}
/* Weekend : contenu très discret (dans la fade zone de toutes façons). */
.cal__col--weekend .cal__col-head {
  color: rgba(242, 241, 236, 0.28);
}
/* Colonne cible (Jeudi) : le col-head est marqué en violet-rosé + accent line
   plus prononcée pour signaler "c'est le jour de la demande vocale". Effet
   discret jusqu'à ce que le RDV se cale. */
.cal__col--target .cal__col-head {
  color: #c5b3e1;
  border-bottom-color: rgba(197, 179, 225, 0.35);
}

/* Corps de colonne : grille 6 rows (10h..15h). Les events se placent via
   --start (grid-row start) et --span (nb rows). */
.cal__col-body {
  position: relative;
  display: grid;
  /* 7 rows = 10h→16h (rows 1/3/5/7 alignées avec les labels du gutter). */
  grid-template-rows: repeat(7, 18px);
  gap: 2px;
  min-height: 138px;
}
.cal__event {
  grid-row: var(--start, 1) / span var(--span, 1);
  padding: 2px 5px 3px;
  border-radius: 4px;
  font-size: 9.5px;
  font-weight: 500;
  color: var(--paper);
  background: rgba(242, 241, 236, 0.06);
  border-left: 2px solid rgba(242, 241, 236, 0.25);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.25;
  min-width: 0;
}
[data-theme="light"] .cal__event {
  /* PAS de override color : var(--paper) devient dark en light mode,
     donc le titre du RDV reste lisible sur fond clair (bug précédent :
     color: var(--ink) rendait le texte de la même couleur que le fond →
     invisible, notamment sur le RDV vert confirmé). */
  background: rgba(12, 13, 16, 0.05);
  border-left-color: rgba(12, 13, 16, 0.25);
}
/* Variante douce : événement "soft" (moins d'accent). */
.cal__event--soft {
  color: var(--text-tertiary);
  background: rgba(242, 241, 236, 0.03);
  border-left-color: rgba(242, 241, 236, 0.15);
}
.cal__event-title {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cal__event-time {
  display: block;
  font-size: 8.5px;
  color: rgba(242, 241, 236, 0.68);
  font-weight: 400;
  letter-spacing: 0.01em;
}

/* ===== RDV target — apparition + confirmation =====
   État initial : invisible (opacity 0 + scale 0.85 + léger translateY 8px).
   .cal.is-scheduled → apparition avec spring (transform-origin: top left
   pour que le "grow" parte du coin haut-gauche du créneau, donnant l'effet
   d'un bloc qui vient se caler dans la grille).
   .cal.is-confirmed → bascule accent vert. */
.cal__event--new {
  background: rgba(197, 179, 225, 0.16);
  border-left-color: #c5b3e1;
  opacity: 0;
  transform: scale(0.85) translateY(8px);
  transform-origin: top left;
  transition:
    opacity 0.4s var(--ease-out),
    transform 0.65s var(--spring),
    background 0.5s var(--ease-out),
    border-left-color 0.5s var(--ease-out);
}
[data-theme="light"] .cal__event--new {
  background: rgba(115, 92, 168, 0.14);
}
.cal.is-scheduled .cal__event--new {
  opacity: 1;
  transform: scale(1) translateY(0);
}
.cal.is-confirmed .cal__event--new {
  background: rgba(74, 222, 128, 0.16);
  border-left-color: #4ade80;
}
[data-theme="light"] .cal.is-confirmed .cal__event--new {
  background: rgba(34, 197, 94, 0.12);
}
.cal.is-confirmed .cal__event--new .cal__event-time {
  color: rgba(74, 222, 128, 0.85);
}

/* ===== Footer : badge "RDV confirmé" + notif "Invitation envoyée" =====
   Position absolue en bas gauche du .cal, cascade révélée par .is-confirmed.
   La notif a un delay léger pour l'effet "cascade discrète". */
.cal__foot {
  position: absolute;
  bottom: 12px;
  left: 16px;
  right: 16px;
  display: flex;
  align-items: center;
  gap: 10px;
  pointer-events: none;
}
.cal__confirm,
.cal__notif {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px 4px 8px;
  border-radius: 999px;
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0.005em;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(6px);
  transition:
    opacity 0.35s var(--ease-out),
    transform 0.5s var(--spring);
}
.cal__confirm {
  color: #4ade80;
  background: rgba(74, 222, 128, 0.10);
  border: 1px solid rgba(74, 222, 128, 0.28);
}
.cal__confirm-ico { width: 10px; height: 10px; }
.cal__notif {
  color: var(--text-tertiary);
  background: rgba(242, 241, 236, 0.05);
  border: 1px solid rgba(242, 241, 236, 0.10);
  /* Delay uniquement pour l'ENTRÉE (opacity 0→1) — la sortie doit rester
     symétrique au badge pour ne pas laisser de traînée en reset. */
  transition:
    opacity 0.35s var(--ease-out) 0.22s,
    transform 0.5s var(--spring) 0.22s;
}
.cal__notif-ico { width: 11px; height: 11px; }
.cal.is-confirmed .cal__confirm,
.cal.is-confirmed .cal__notif {
  opacity: 1;
  transform: translateY(0);
}
/* Reset : quand .is-confirmed est retirée en boucle, on veut que la sortie
   soit rapide et synchrone (pas de delay retardataire côté notif → sinon
   elle reste visible plus longtemps après le badge). */
.cal:not(.is-confirmed) .cal__notif {
  transition:
    opacity 0.2s var(--ease-out),
    transform 0.25s var(--ease-out);
}

/* ===== Entrée FLIP du calendrier (léger décalage / respire par rapport au
        .voice pour que la cascade globale ait un rythme). Piloté par le JS
        avec les mêmes classes al-enter / al-enter-active. */
.cal.al-enter {
  opacity: 0;
  transform: translateY(14px) scale(0.98);
}
.cal.al-enter-active {
  opacity: 1;
  transform: translateY(0) scale(1);
  transition:
    opacity 0.6s var(--ease-out),
    transform 0.6s var(--ease-out);
  transition-delay: 0.15s;   /* le cal arrive juste après la .voice */
}

/* prefers-reduced-motion : état statique, transcript entier posé, waveform
   au repos (scaleY faible, sans anim), micro sans halo. Le RDV est calé
   d'entrée (posé sur son créneau, accent violet, sans anim). Le badge
   confirmation et la notif restent invisibles (moins d'infos = moins
   d'agitation visuelle demandée par prefers-reduced-motion). */
@media (prefers-reduced-motion: reduce) {
  .voice,
  .voice.al-enter,
  .voice.al-enter-active,
  .cal,
  .cal.al-enter,
  .cal.al-enter-active {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .voice__bar,
  .voice__mic::after,
  .voice__mic,
  .voice__transcript-caret,
  .voice__label-txt {
    animation: none !important;
    transition: none !important;
  }
  .voice__bar { transform: scaleY(0.35); }
  .voice__transcript-caret { opacity: 0; }
  /* Label reduced-motion : affiche "À l'écoute…" statique. */
  .voice__label-txt--listening { opacity: 1; transform: none; }
  .cal__event--new {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  /* Badge / notif : cachés en reduced-motion pour éviter le scintillement. */
  .cal__confirm,
  .cal__notif {
    opacity: 0 !important;
    transition: none !important;
  }
}

/* ===== Responsive : mobile = empilement vertical (liste au-dessus, panneau en dessous) ===== */
@media (max-width: 900px) {
  .metiers__layout {
    grid-template-columns: 1fr;
    gap: 2rem;
  }
  /* Panel stack rallongé sur mobile pour avoir la place pour cards + gen/output + bar
     sans chevauchement (était 320px → tout se serrait).
     overflow-x: clip → contient les éléments du panel 3 prospection qui dépassent à
     droite pendant l'animation de carry (la carte 312px + curseur "Agent Enduria"
     ~112px s'étendent vers la droite quand l'agent porte une carte vers le panier
     "relance"). Sans cette clip, l'overflow remontait jusqu'au document et décalait
     toute la page (toggle/navbar). On clip ici (au plus près) plutôt qu'au body,
     pour ne pas masquer un éventuel autre symptôme ailleurs. `clip` au lieu de
     `hidden` → ne crée pas de contexte de scroll, ne casse pas position:sticky
     éventuel dans la section. */
  .metiers__panel-stack {
    min-height: 540px;
    overflow-x: clip;
  }
  .metiers__desc {
    margin-left: 48px;
  }

  /* === Panel 2 reporting — cards recentrées et resserrées pour le viewport mobile ===
     Le panel fait ~345px de large sur mobile (vs 480px desktop). Les cards avec
     left: 240px débordaient à droite. Positions adaptées (max left ~165px) pour
     que la pile reste centrée DANS le cadre. */
  .panel-rep .rep-card[data-card="1"] { --top: 22px;  --left: 14px;  }
  .panel-rep .rep-card[data-card="2"] { --top: 52px;  --left: 108px; }
  .panel-rep .rep-card[data-card="3"] { --top: 82px;  --left: 22px;  }
  .panel-rep .rep-card[data-card="4"] { --top: 62px;  --left: 158px; }
  .panel-rep .rep-card[data-card="5"] { --top: 114px; --left: 78px;  }

  /* Gen + output : centrés verticalement entre la pile (top ~150px) et la bar (bottom).
     Sur 540px de panel, 42% = ~227px → bien au milieu. */
  .panel-rep__gen,
  .panel-rep__output {
    top: 42%;
  }

  /* Bar plus basse + un peu plus étroite pour respirer mobile. */
  .panel-rep__bar {
    bottom: 26px;
    width: calc(100% - 24px);
    max-width: 340px;
  }

  /* Output mobile : font + padding compactés pour que "bilan-semaine.pdf" tienne
     sur 1 ligne dans sa pill (avec le nowrap). */
  .panel-rep__output-pill {
    font-size: 14px;
    padding: 0 11px;
    height: 32px;
    gap: 7px;
  }
  .panel-rep__output-ico {
    width: 16px;
    height: 16px;
  }
  .panel-rep__output-dl {
    width: 32px;
    height: 32px;
  }

  /* Panel 3 — curseur Agent Enduria : reste collé en bas (la stack remonte avec
     margin-bottom 70px pour ne pas le chevaucher). Position bas-droite inchangée. */

  /* === Panel 3 prospection — compactage mobile =============================
     Sur mobile (panel ~340px, baskets 2×~150px), une carte calée dans un panier
     descend à ~120-130px de large. Avec le statut desktop (flex-shrink: 0 + nowrap),
     "Pas de réponse · 3j" déborde franchement du cadre dashed. On compacte
     paniers/cartes et on autorise le STATUT à se tronquer en ellipsis (nom du
     dirigeant prioritaire, statut secondaire). Cartes en stack (340px) restent
     larges → ellipsis ne se déclenche pas, statut reste lisible. */
  .panel-pros .pros-baskets {
    /* Gap entre les 2 paniers réduit (36 → 10) pour redonner ~26px de slot à chaque carte. */
    gap: 10px;
    padding: 0 2px;
  }
  .panel-pros .pros-basket {
    padding: 6px 8px;
    gap: 6px;
  }
  .panel-pros .pros-card {
    padding: 0 7px;
    gap: 6px;
  }
  /* Avatar légèrement réduit (26 → 24) → libère 2px pour le texte sans abîmer la photo. */
  .panel-pros .pros-card__avatar {
    width: 24px;
    height: 24px;
  }
  .panel-pros .pros-card__name {
    font-size: 12.5px;
  }
  .panel-pros .pros-card__status {
    /* Plus de flex-shrink 0 : le statut peut maintenant rétrécir + ellipser
       quand la carte est étroite (cas panier). En stack (340px de large) il
       garde sa taille naturelle → pas d'ellipsis visible.
       flex-shrink: 2 → rétrécit 2× plus vite que le nom (shrink 1) pour garder
       le nom du dirigeant lisible en priorité. */
    flex: 0 1 auto;
    flex-shrink: 2;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 9px;
  }
  /* Badge "✓ Envoyé" du payoff aussi compacté (sinon il déborde des cartes étroites
     en panier). Placé un peu plus proche du bord droit, font + ico réduits. */
  .panel-pros .pros-card__sent {
    right: 7px;
    font-size: 8.5px;
    padding: 2px 6px 2px 4px;
  }
  .panel-pros .pros-card__sent-ico {
    width: 9px;
    height: 9px;
  }
  /* Bouton "Tout envoyer" du payoff : un cran plus compact pour ne pas écraser le
     centre du panneau sur mobile (panel étroit, paniers + stack déjà denses). */
  .panel-pros .pros-send {
    padding: 8px 14px 8px 12px;
    font-size: 12px;
    gap: 6px;
  }
  .panel-pros .pros-send__ico {
    width: 13px;
    height: 13px;
  }
}
@media (max-width: 640px) {
  .metiers__title { font-size: clamp(1.5rem, 6vw, 2rem); }
  .metiers__desc { margin-left: 0; padding-left: 48px; }
}

/* ===== prefers-reduced-motion ===== */
@media (prefers-reduced-motion: reduce) {
  .metiers__item,
  .metiers__chip,
  .metiers__desc,
  .metiers__desc-inner,
  .metiers__panel,
  .metiers__ring-prog {
    transition: none !important;
    animation: none !important;
  }
  .metiers__item.is-active .metiers__ring-prog {
    stroke-dashoffset: 0;  /* ring plein, statique */
  }
  .metiers__desc-inner,
  .metiers__panel {
    transform: none !important;
    filter: none !important;
  }
}
