/* ============================================================
   Parcours d'accueil : écran de bienvenue, checklist de première
   semaine, documents RH et éditeur Markdown.
   Aucune couleur ni typographie propre : tout vient du DS.
   ============================================================ */

.onboarding { max-width: 860px; margin: 0 auto; }

/* Fil des trois étapes. */
.onboarding__steps {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-6);
}
.onboarding__step {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px 6px 6px;
  border-radius: var(--radius-full);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--gray-500);
  background: var(--gray-100);
}
.onboarding__step-num {
  width: 22px;
  height: 22px;
  flex: none;
  border-radius: 50%;
  background: #fff;
  color: var(--gray-500);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: var(--weight-semibold);
}
/* Étape courante en teinte pâle, jamais en aplat : la règle 1 du DS réserve
   la pilule indigo pleine à l'action primaire. */
.onboarding__step.is-current {
  background: var(--brand-indigo-tint);
  color: var(--accent);
  font-weight: var(--weight-semibold);
}
.onboarding__step.is-current .onboarding__step-num { background: var(--accent); color: #fff; }
.onboarding__step.is-done .onboarding__step-num {
  background: var(--status-success-bg);
  color: var(--status-success-fg);
}

.onboarding__hero { text-align: center; padding: var(--space-10) var(--space-8); }
.onboarding__wave { font-size: 48px; line-height: 1; margin-bottom: var(--space-4); }
.onboarding__title {
  font-size: 28px;
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  margin: 0 0 var(--space-3);
}
.onboarding__lead {
  font-size: var(--text-md);
  color: var(--text-secondary);
  line-height: var(--leading-relaxed);
  max-width: 46ch;
  margin: 0 auto var(--space-6);
}
.onboarding__note {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  margin-bottom: var(--space-6);
  border-radius: var(--radius-full);
  background: var(--status-info-bg);
  color: var(--status-info-fg);
  font-size: var(--text-sm);
}
.onboarding__note .lucide { width: 15px; height: 15px; }

.onboarding__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

/* ===== Suivi RH sur la fiche ===== */
.onboarding-summary { display: grid; gap: 1px; }
.onboarding-summary__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: 9px 4px;
  border-top: 1px solid #F4F5F9;
  font-size: var(--text-sm);
}
/* Temps passé sur le document : une précision, pas un titre — elle suit le
   nom du document sans lui disputer la lecture. */
.onboarding-summary__reading { color: var(--gray-400); margin-left: 6px; }
.onboarding-summary__state { color: var(--gray-500); }
.onboarding-summary__state--done { color: var(--status-success-fg); }
.onboarding-summary__state--waiting { color: var(--status-warning-fg); }
.onboarding-summary__state .lucide { width: 15px; height: 15px; }

/* ===== Document adressé ===== */
.doc-page { max-width: 860px; margin: 0 auto; }
.doc-instructions {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-5);
  margin-bottom: var(--space-4);
  border-radius: var(--radius-xl);
  background: var(--status-info-bg);
  color: var(--status-info-fg);
}
.doc-instructions__icon { flex: none; }
.doc-instructions__title { font-weight: var(--weight-semibold); margin-bottom: 4px; }
.doc-instructions__steps { margin: 0; padding-left: 18px; font-size: var(--text-sm); }

/* Le corps du document : un texte long, donc une mesure lisible et une
   hiérarchie de titres marquée. */
.doc-body { line-height: var(--leading-relaxed); }
.doc-body h1 { font-size: 24px; font-weight: var(--weight-semibold); margin: 0 0 var(--space-5); }
.doc-body h2 { font-size: 18px; font-weight: var(--weight-semibold); margin: var(--space-6) 0 var(--space-2); }
.doc-body h3 { font-size: 15px; font-weight: var(--weight-semibold); margin: var(--space-5) 0 var(--space-2); }
.doc-body p, .doc-body li { max-width: 72ch; }
.doc-body table { width: 100%; margin: var(--space-4) 0; border-collapse: collapse; }
.doc-body th, .doc-body td { border: 1px solid var(--gray-200); padding: 8px 10px; text-align: left; }
.doc-body hr { border: 0; border-top: 1px solid var(--gray-200); margin: var(--space-6) 0; }

.doc-declare { margin-top: var(--space-4); }
.doc-declare__hint { font-size: var(--text-sm); color: var(--gray-500); margin: 8px 0 var(--space-4); }
.doc-declare__done { display: flex; align-items: flex-start; gap: 10px; }
.doc-declare__done .lucide { color: var(--status-success-fg); flex: none; margin-top: 2px; }

/* ===== Éditeur Markdown ===== */
.doc-editor__tabs { display: flex; gap: 2px; padding: 10px 14px 0; }
.doc-editor__tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 0;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  background: transparent;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--gray-500);
  cursor: pointer;
}
.doc-editor__tab.is-active { background: var(--gray-100); color: var(--text-primary); }
.doc-editor__tab .lucide { width: 14px; height: 14px; }
.doc-editor__area { border-radius: 0; border-left: 0; border-right: 0; }
/* Hors carte, l'aperçu porte lui-même sa marge intérieure. */
.doc-editor__preview { min-height: 320px; padding: var(--space-5) var(--space-6); }
.doc-editor__vars {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  padding: 12px 14px;
  border-top: 1px solid var(--gray-150);
  font-size: var(--text-sm);
  color: var(--gray-500);
}
.doc-editor__vars code {
  background: var(--gray-100);
  border-radius: var(--radius-sm);
  padding: 2px 6px;
  font-size: 12px;
  color: var(--accent);
}

/* ===== Vue d'impression ===== */
.print-body { background: #fff; }
.doc-print { max-width: 18cm; margin: 1.5cm auto; color: #111; }
.doc-print__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding-bottom: 10px;
  margin-bottom: 24px;
  border-bottom: 1px solid #ccc;
}
.doc-print__brand { font-weight: 700; }
.doc-print__meta { font-size: 12px; color: #555; }
.doc-print__body { line-height: 1.6; }
.doc-print__body h1 { font-size: 20px; margin: 0 0 16px; }
.doc-print__body h2 { font-size: 15px; margin: 22px 0 8px; }
.doc-print__signature {
  display: flex;
  gap: 48px;
  margin-top: 64px;
  page-break-inside: avoid;
}
.doc-print__signature > div { flex: 1; }
.doc-print__label { font-size: 12px; color: #555; margin-bottom: 44px; }
.doc-print__line { border-top: 1px solid #333; }

@media print {
  .doc-print { margin: 0; }
}

.onboarding-summary__reset {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-4) 4px 0;
  margin-top: var(--space-2);
  border-top: 1px solid #F4F5F9;
}
.onboarding-summary__reset form { margin: 0; }
.onboarding-summary__reset-hint {
  flex: 1;
  min-width: 180px;
  font-size: var(--text-sm);
  color: var(--gray-500);
}

/* Sur la fiche de modification, l'encart se cale sur la largeur du dossier. */
.user-onboarding { margin-top: var(--space-4); }

/* ============================================================
   Parcours d'accueil — refonte sur le patron de wizard existant
   (interview-wizard). Aucun token propre : tout vient du DS.
   ============================================================ */
.ob-wizard { max-width: 1120px; }
.ob-sidebar__count {
  text-align: center;
  font-size: var(--text-sm);
  color: var(--gray-500);
  margin-bottom: var(--space-4);
}
.ob-sidebar__count b { color: var(--text-primary); font-weight: var(--weight-semibold); }
/* Une étape hors d'atteinte tant que le socle manque : visible, mais inerte. */
.wizard-page-item.is-locked { opacity: 0.45; pointer-events: none; }

.ob-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}
.ob-head__lead { font-size: var(--text-base); color: var(--text-secondary); }

/* Témoin d'enregistrement : discret, et jamais un bandeau qui pousse le
   contenu. */
.ob-indicator {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  background: var(--gray-100);
  color: var(--gray-500);
  transition: background 0.16s ease, color 0.16s ease;
}
.ob-indicator[data-state="saving"] { background: var(--status-info-bg); color: var(--status-info-fg); }
.ob-indicator[data-state="saved"] { background: var(--status-success-bg); color: var(--status-success-fg); }
.ob-indicator[data-state="error"] { background: var(--status-danger-bg); color: var(--status-danger-fg); }

/* Ce qui reste à renseigner : la boussole de l'écran. */
.ob-missing {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-5);
  margin-bottom: var(--space-4);
  border-radius: var(--radius-xl);
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
}
.ob-missing__icon { flex: none; }
.ob-missing__title { font-weight: var(--weight-semibold); margin-bottom: 4px; }
.ob-missing__list { margin: 0; padding-left: 18px; font-size: var(--text-sm); }

.ob-card { margin-bottom: var(--space-4); }
.ob-card__title { font-size: var(--text-md); font-weight: var(--weight-semibold); margin: 0 0 2px; }
.ob-card__hint { font-size: var(--text-sm); color: var(--gray-500); margin-bottom: var(--space-5); }

.ob-note {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  margin-bottom: var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--status-info-bg);
  color: var(--status-info-fg);
  font-size: var(--text-sm);
}
.ob-note .lucide { width: 15px; height: 15px; flex: none; }

.ob-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-4);
}
.ob-field--wide { grid-column: 1 / -1; }
.ob-field__required,
.ob-field__optional {
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  margin-left: 6px;
}
.ob-field__required { color: var(--accent); }
.ob-field__optional { color: var(--gray-400); }
.ob-field__error {
  font-size: var(--text-sm);
  color: var(--status-danger-fg);
  margin-top: 4px;
}

.ob-hero { text-align: center; padding: var(--space-10) var(--space-8); }
.ob-hero__wave { font-size: 48px; line-height: 1; margin-bottom: var(--space-4); }

/* Le logo remplace un mot dans le titre : il doit donc se lire comme un mot.
   Le wordmark est bas-de-casse, ses ascendantes touchent le haut de l'image et
   sa ligne de base est à 94 % de la hauteur ; sa hauteur d'x vaut environ 66 %.
   À 0,78em, cette hauteur d'x tombe sur celle du texte voisin et les
   ascendantes s'alignent. Le décalage vertical rattrape le peu d'image qui
   passe sous la ligne de base. Mesuré sur le fichier, pas deviné. */
.ob-hero__logo {
  height: 0.78em;
  width: auto;
  aspect-ratio: 1773 / 270;
  vertical-align: -0.05em;
  /* Les bouts ronds du masque dépassent des lettres : rien à rogner. */
  overflow: visible;
}

/* Le mot s'écrit.
   ------------------------------------------------------------
   Un premier essai révélait le logo par un rideau vertical. Ça se voyait pour
   ce que c'était : un rideau. Une écriture, c'est la plume qui suit la forme —
   la hampe descend, l'arche monte et retombe, la panse tourne.

   Le tracé vit donc dans un masque SVG (voir onboarding/_wordmark) : des traits
   blancs posés sur le squelette de chaque lettre, qui se découvrent en avançant
   le long de leur chemin. Le tiret fait toute la longueur du chemin — `--len`,
   porté par chaque tracé — et son décalage va de cette longueur à zéro.
   `pathLength` aurait permis de normaliser à 1 ; Chrome ne l'applique pas au
   tiret, et révélait alors la lettre presque entière d'un coup.

   L'état de base est le tracé complet, et le remplissage est `backwards` : la
   lettre n'est cachée que pendant son attente, et l'animation ne laisse rien
   derrière elle. Même règle que partout ailleurs sur cet écran.
   ------------------------------------------------------------ */
.ob-pen path {
  stroke-dasharray: var(--len);
  stroke-dashoffset: 0;
  animation: obPen var(--dur, 120ms) linear calc(640ms + var(--wait, 0ms)) backwards;
}

@keyframes obPen {
  from { stroke-dashoffset: var(--len); }
  to { stroke-dashoffset: 0; }
}

.ob-hero__title {
  font-size: 28px;
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  margin: 0 0 var(--space-3);
}
.ob-hero__lead {
  font-size: var(--text-md);
  color: var(--text-secondary);
  line-height: var(--leading-relaxed);
  max-width: 46ch;
  margin: 0 auto var(--space-6);
}
.ob-hero__note {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  margin-bottom: var(--space-6);
  border-radius: var(--radius-full);
  background: var(--status-info-bg);
  color: var(--status-info-fg);
  font-size: var(--text-sm);
}
.ob-hero__note .lucide { width: 15px; height: 15px; }

/* Encart d'invitation, après le déblocage. */
.ob-invite {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  margin-bottom: var(--space-4);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.16s ease;
}
.ob-invite:hover { border-color: #D6D8FC; color: inherit; }
.ob-invite__ring { flex: none; }
.ob-invite__body { flex: 1; min-width: 0; }
.ob-invite__title { font-size: var(--text-md); font-weight: var(--weight-semibold); }
.ob-invite__hint { font-size: var(--text-sm); color: var(--gray-500); margin-top: 2px; }
.ob-invite__cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--accent);
}
.ob-invite__cta .lucide { width: 15px; height: 15px; }

@media (max-width: 767.98px) {
  .ob-invite { flex-wrap: wrap; }
  .ob-grid { grid-template-columns: 1fr; }
}

/* ===== Fil d'avancement du parcours =====
   Il emprunte le composant du récapitulatif d'entretien : seuls la place du
   point et l'accueil des étincelles sont propres à cet écran. */
.ob-stepper .iw-stepper__track { position: relative; }

/* Fil centré, quel que soit le nombre d'étapes.
   Le gabarit de colonnes est posé par le gabarit HTML : `repeat(n-1, 1fr) auto`,
   où n est le nombre réel d'étapes. La dernière n'a pas de trait à tirer — lui
   laisser une colonne pleine réserverait un vide à droite et collerait le fil à
   gauche. Écrire ce gabarit en dur cassait à la moindre étape ajoutée : c'est
   arrivé au passage de trois à quatre, les deux dernières se chevauchaient.
   `repeat()` n'accepte pas une variable CSS pour son compte, d'où le calcul
   côté vue.
   `max-width` : tiré sur toute la largeur du parcours, le fil serait une barre
   au-dessus d'un contenu resserré. Il s'élargit avec le nombre d'étapes. */
.ob-stepper {
  grid-auto-columns: unset;
  max-width: calc(var(--steps, 3) * 200px);
  margin-inline: auto;
}

/* Gerbe d'étincelles sur une étape franchie. Exception assumée à la règle de
   mouvement du design system : un instant, une seule fois, à la bascule. */
.ob-spark {
  position: absolute;
  top: 9px;
  left: 9px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  pointer-events: none;
  opacity: 0;
  animation: obSpark 0.7s ease-out var(--delay, 0ms) forwards;
}
.ob-spark:nth-child(3n) { background: var(--status-success-fg); }
.ob-spark:nth-child(4n) { background: #F2C14E; }

@keyframes obSpark {
  0% { opacity: 1; transform: translate(0, 0) scale(1); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(0.4); }
}

@media (prefers-reduced-motion: reduce) {
  .ob-spark { display: none; }
}

/* ============================================================
   Transition d'étape du parcours
   ------------------------------------------------------------
   Deuxième exception assumée à la règle de mouvement du DS, et pour la même
   raison que la gerbe : c'est le premier écran d'un nouvel arrivant, et passer
   d'une étape à l'autre doit se lire comme un geste.

   Le décor ne bouge pas. Le fil d'avancement et l'en-tête de l'application
   restent en place — les animer donnerait un carrousel de pages, pas un
   parcours qu'on traverse. Seul le contenu de l'étape entre et sort, dans le
   sens de la marche.

   L'entrée est écrite ici, pas en JS : elle doit être posée avant le premier
   rendu, sinon le contenu s'affiche en place une image avant de glisser. Le
   sens par défaut est l'avancée ; `--ob-dir` est retourné par le contrôleur
   quand on revient en arrière, avant que le navigateur ne peigne. La sortie,
   elle, est en JS : Turbo doit l'attendre avant de remplacer la page.

   `backwards` et non `both`, partout : une animation qui remplit vers l'avant
   reste attachée à son élément une fois finie, et sa valeur calculée de
   `transform` devient `matrix(1, 0, 0, 1, 0, 0)` — l'identité, mais pas `none`.
   Or tout transform autre que `none` fait de l'élément un contexte
   d'empilement, à vie. Chaque carte en devenait un, et le calendrier de la date
   de naissance — `position: absolute`, `z-index: 40` dans sa carte — se
   retrouvait enfermé : le bas de sa grille des années passait sous la carte
   suivante, hors d'atteinte du clic. En production depuis la v47, découvert par
   un test qui échouait sous charge.
   `backwards` ne remplit qu'avant le départ, le temps du retard : après, chaque
   élément retrouve son style de base, sans transform. Toutes ces animations
   finissent sur leur état de base — c'est ce qui rend la bascule sans effet
   visible.

   Le respect de `prefers-reduced-motion` vient de la fondation, qui écrase
   toutes les durées : chaque animation d'ici tombe alors sur son état final.
   Les retards, eux, ne sont pas écrasés — ils le sont ci-dessous, sinon le
   contenu resterait invisible le temps d'un décalage qu'on a justement refusé.
   ============================================================ */

/* Le parcours pose sa propre arrivée : celle du shell la doublerait. */
.app-shell--locked .app-content__inner { animation: none; }

.ob-slide {
  --ob-shift: 44px;
  /* Le glissement sort de la largeur utile : on le rogne, plutôt que de voir
     une barre de défilement horizontale apparaître le temps de l'animation.
     La marge de rognage laisse passer l'ombre des cartes ; l'axe vertical
     reste libre, lui, pour ne rien couper au-dessus ni en dessous. */
  overflow-x: clip;
  overflow-clip-margin: 40px;
}

/* Les blocs de l'étape se posent l'un après l'autre. La courbe est celle des
   glissements d'iOS : départ franc, arrivée qui s'étale. */
.ob-slide > * {
  animation: obStepEnter 480ms cubic-bezier(0.32, 0.72, 0, 1) backwards;
}
/* Au-delà du cinquième bloc le décalage ne se lit plus, il ne fait qu'allonger
   l'attente : le même plafond est posé côté JS pour la sortie. */
.ob-slide > *:nth-child(2) { animation-delay: 42ms; }
.ob-slide > *:nth-child(3) { animation-delay: 84ms; }
.ob-slide > *:nth-child(4) { animation-delay: 126ms; }
.ob-slide > *:nth-child(n+5) { animation-delay: 168ms; }

@keyframes obStepEnter {
  from {
    opacity: 0;
    transform: translate3d(calc(var(--ob-dir, 1) * var(--ob-shift)), 0, 0) scale(0.985);
  }
  to { opacity: 1; transform: none; }
}

/* Le titre de l'étape ne glisse pas : il se relève. */
.ob-head { animation: obHeadEnter 440ms cubic-bezier(0.32, 0.72, 0, 1) backwards; }

@keyframes obHeadEnter {
  from { opacity: 0; transform: translate3d(0, 8px, 0); }
  to { opacity: 1; transform: none; }
}

/* Écran de bienvenue et fin de parcours : la carte arrive, puis son contenu se
   pose. C'est le premier et le dernier écran du parcours — ils ont droit à une
   phrase de plus que les autres. */
.ob-slide .ob-hero > * {
  animation: obHeroRise 440ms cubic-bezier(0.32, 0.72, 0, 1) backwards;
}
.ob-slide .ob-hero > *:nth-child(1) { animation-delay: 130ms; }
.ob-slide .ob-hero > *:nth-child(2) { animation-delay: 200ms; }
.ob-slide .ob-hero > *:nth-child(3) { animation-delay: 270ms; }
.ob-slide .ob-hero > *:nth-child(n+4) { animation-delay: 340ms; }

@keyframes obHeroRise {
  from { opacity: 0; transform: translate3d(0, 10px, 0); }
  to { opacity: 1; transform: none; }
}

/* La main salue, une fois, à l'ouverture du parcours. Le geste passe par
   `rotate` et non par `transform` : les deux propriétés se composent, la
   montée du bloc n'a donc pas à céder la place au salut.
   Réservé au 👋 de la bienvenue : sur les autres écrans, l'émoji ne salue
   personne. */
.ob-slide .ob-hero__wave--hello {
  transform-origin: 68% 82%;
  animation: obHeroRise 440ms cubic-bezier(0.32, 0.72, 0, 1) 130ms backwards,
             obWave 1.5s ease-in-out 2200ms backwards;
}

@keyframes obWave {
  0%, 100% { rotate: 0deg; }
  12% { rotate: 15deg; }
  26% { rotate: -9deg; }
  40% { rotate: 14deg; }
  54% { rotate: -5deg; }
  68% { rotate: 9deg; }
}

/* Fin de parcours : le 🎉 n'a pas de bloc à lui, il se pose seul. */
.ob-slide .onboarding__wave {
  animation: obFinalePop 620ms cubic-bezier(0.32, 0.72, 0, 1) 160ms backwards;
}

@keyframes obFinalePop {
  0% { opacity: 0; transform: scale(0.4); }
  62% { transform: scale(1.14); }
  100% { opacity: 1; transform: none; }
}

/* ===== L'étape qu'on vient de franchir =====
   Elle se referme sous les yeux du collaborateur : son trait se tire jusqu'au
   point suivant, son point se gonfle, la gerbe part dessus. Sans cela, la
   bascule des états du fil est un saut sec, au moment précis où le parcours
   avance. Posé par le contrôleur, et seulement en avançant.

   Le trait accent est un calque au-dessus du gris, pas le trait lui-même : le
   réduire à zéro pour le faire croître aurait fait disparaître la ligne avant
   de la redessiner. */
.ob-stepper .iw-stepper__step.is-advanced .iw-stepper__line {
  position: relative;
  background: var(--gray-200);
  overflow: hidden;
}
.ob-stepper .iw-stepper__step.is-advanced .iw-stepper__line::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform-origin: left center;
  animation: obLineFill 460ms cubic-bezier(0.32, 0.72, 0, 1) 60ms backwards;
}

@keyframes obLineFill {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

.ob-stepper .iw-stepper__step.is-advanced .iw-stepper__dot {
  animation: obDotPop 420ms cubic-bezier(0.32, 0.72, 0, 1) 400ms backwards;
}

@keyframes obDotPop {
  0%, 100% { transform: scale(1); }
  45% { transform: scale(1.32); }
}

/* Sur mobile, le contenu tient toute la largeur : un glissement de 44px y
   paraît une secousse. */
@media (max-width: 767.98px) {
  .ob-slide { --ob-shift: 26px; }
}

/* La page occupe toute la largeur utile : le formulaire est le sujet, plus un
   panneau latéral ne lui dispute la place. */
/* Le parcours est centré dans la zone de contenu, verrouillé ou non : c'est un
   écran qu'on traverse, pas un tableau de bord adossé à la navigation. */
.ob-page { max-width: 940px; margin-inline: auto; }
.ob-lock {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border-radius: var(--radius-full);
  background: var(--brand-indigo-tint);
  color: var(--accent);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}
.ob-lock .lucide { width: 14px; height: 14px; }

/* ===== Écran verrouillé : le parcours occupe seul la fenêtre =====
   La barre latérale est retirée du DOM tant que le socle manque. Le logo, qu'elle
   portait, revient donc dans l'en-tête, et le contenu se recentre — sans elle,
   il se serait collé au bord gauche en laissant un vide à droite. */
.app-shell--locked .app-header__logo { display: block; }
/* Centrage par la marge, pas par flex : en conteneur flex, la page se
   rétrécissait à la largeur de son contenu et le fil d'avancement s'y
   écrasait, mentions superposées. */
/* En-tête sans titre : sur l'écran de bienvenue, la carte porte déjà le
   message ; l'en-tête ne garde que la pastille de verrou. */
.page-head--bare { margin-bottom: var(--space-4); }

/* ============================================================
   Ma photo — étape 3 du parcours
   ============================================================ */
.ob-photo { display: flex; gap: var(--space-8); align-items: center; flex-wrap: wrap; }
.ob-photo__preview { flex: none; }
.ob-photo__img {
  width: 128px;
  height: 128px;
  border-radius: 50%;
  object-fit: cover;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 34px;
  font-weight: var(--weight-semibold);
}
.ob-photo__side { flex: 1; min-width: 260px; display: grid; gap: var(--space-3); }
.ob-photo__hint { margin: 0; color: var(--text-secondary); }
.ob-photo__form { display: grid; gap: var(--space-3); justify-items: start; }
/* Microsoft reste la source : on le dit là où la photo se remplace, pas dans
   une note de bas de page que personne ne lit. */
.ob-photo__note { margin: 0; font-size: var(--text-sm); color: var(--gray-500); }

/* ============================================================
   Mon arrivée
   ============================================================ */

/* Rappel sur le tableau de bord : une ligne cliquable, pas un encart qui
   rejoue le parcours. */
.arrival-nudge { text-decoration: none; color: inherit; margin-bottom: var(--space-4); }
.arrival-nudge__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  color: var(--accent);
}
.arrival-nudge__icon .lucide { width: 17px; height: 17px; }

.section-title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  margin: var(--space-6) 0 var(--space-3);
}


/* ===== Composition du parcours, côté RH ===== */
.onboarding-form { display: grid; gap: var(--space-4); }
/* Rythme vertical de la fiche d'un élément d'arrivée : les cartes s'y suivent
   toutes au même écart, plutôt qu'une marge recopiée sur chacune. */
.arrival-doc { display: grid; gap: var(--space-4); }

/* État réglé : une ligne discrète, pas un aplat. La règle 1 du DS réserve
   l'indigo plein à l'action principale — ici il n'y en a plus. */
.arrival-settled { display: flex; align-items: center; gap: 9px; margin: 0; }
.arrival-settled .lucide { width: 18px; height: 18px; color: var(--status-success-fg); flex: none; }
/* Document déjà traité : l'état remplace l'action. Vert quand il n'y a plus
   rien à faire, ambre tant que la RH attend le papier — c'est la seule nuance
   qui change quelque chose pour le collaborateur. */
.doc-status { display: flex; align-items: flex-start; gap: var(--space-4); }
.doc-status__icon {
  width: 32px;
  height: 32px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--status-success-bg);
  color: var(--status-success-fg);
}
.doc-status--waiting .doc-status__icon {
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
}
.doc-status__icon .lucide { width: 17px; height: 17px; }
.doc-status__title {
  margin: 4px 0 0;
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}
.doc-status__hint { margin: 4px 0 0; color: var(--text-secondary); max-width: 68ch; }

.arrival-action__hint { color: var(--text-secondary); margin: 0 0 var(--space-4); max-width: 68ch; }
.arrival-action__note { font-size: var(--text-sm); color: var(--gray-500); margin: 8px 0 0; }
.arrival-action form { margin: 0; }

/* Ciblage rangé par critère : le libellé à gauche, ses valeurs à droite. Une
   grille plutôt qu'une traînée d'étiquettes — avec trois BU et soixante
   personnes nommées, on ne distinguait plus ce qui relevait de quoi. */
.audience {
  display: grid;
  grid-template-columns: minmax(120px, max-content) 1fr;
  gap: var(--space-3) var(--space-5);
  margin: 0;
  align-items: baseline;
}
.audience__criterion {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--gray-500);
  margin: 0;
}
.audience__values {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
}
.audience__fold summary {
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--accent);
}
.audience__fold summary::marker { color: var(--gray-400); }

@media (max-width: 640px) {
  .audience { grid-template-columns: 1fr; gap: 4px var(--space-3); }
  .audience__criterion { margin-top: var(--space-3); }
}
@media (max-width: 640px) {
  .ob-photo { justify-content: center; text-align: center; }
}


/* Récapitulatif d'un document : les critères à gauche, les personnes à droite.
   Avant de publier, la question utile est « qui », pas « quels critères ». */
.audience-recap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: var(--space-6);
  align-items: start;
}
.audience-recap__preview {
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--surface-sunken);
}
@media (max-width: 1000px) {
  .audience-recap { grid-template-columns: 1fr; }
}

/* ============================================================
   Ciblage — composant partagé (documents à signer, communication RH, sondages)
   ------------------------------------------------------------
   Le ciblage s'écrit en toutes lettres. La règle — les valeurs d'un même
   critère s'additionnent, deux critères se croisent, les personnes nommées
   s'ajoutent par-dessus — était énoncée une fois en tête et jamais montrée.
   Elle se lit désormais dans la phrase, et se défait pastille par pastille.

   Les cases à cocher n'ont pas disparu : elles vivent dans le sélecteur,
   replié. Cinq blocs dépliés en permanence faisaient quarante-quatre pastilles
   à l'écran avant d'avoir rien choisi.
   ============================================================ */

.aud { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: var(--space-5); align-items: start; }
.aud__main { min-width: 0; }

/* ===== La phrase ===== */
.aud-sentence {
  padding: var(--space-5) var(--space-6);
  background: var(--surface-sunken);
  border: 1px solid var(--border-default);
  border-radius: 16px;
  margin-bottom: var(--space-4);
}
.aud-sentence__lead {
  margin: 0 0 var(--space-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}
.aud-sentence__body { display: flex; flex-direction: column; gap: 6px; }
.aud-sentence__row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.aud-sentence__criterion {
  flex: none;
  min-width: 84px;
  font-size: var(--text-sm);
  color: var(--text-muted);
}
/* Le mot de liaison porte toute la règle : c'est lui qu'on lit en diagonale
   pour savoir si l'on restreint ou si l'on ajoute. */
.aud-sentence__joiner {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--accent);
  letter-spacing: var(--tracking-wider);
  padding-left: 2px;
}
.aud-sentence__or { font-size: var(--text-xs); color: var(--text-muted); }
.aud-sentence__empty { margin: 0; font-size: var(--text-sm); color: var(--text-muted); max-width: 68ch; }
.aud-sentence__total {
  margin: var(--space-4) 0 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-subtle);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.aud-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px 3px 11px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--brand-indigo-tint);
  color: var(--accent);
  font-size: var(--text-sm);
  cursor: pointer;
}
.aud-chip i { font-style: normal; font-size: 11px; opacity: 0.6; }
.aud-chip:hover { background: var(--accent); color: #fff; }
.aud-chip:hover i { opacity: 1; }

/* ===== Le sélecteur ===== */
.aud-add__tabs { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-3); }
.aud-add__tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  border: 1px solid var(--border-default);
  border-radius: 999px;
  background: var(--surface-card);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: border-color 0.14s ease, color 0.14s ease;
}
.aud-add__tab:hover { border-color: var(--gray-300); color: var(--text-primary); }
.aud-add__tab.is-filled { border-color: var(--accent); color: var(--accent); }
.aud-add__tab.is-open { background: var(--brand-indigo-tint); border-color: var(--accent); color: var(--accent); }
.aud-add__badge {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}
.aud-add__badge:empty { display: none; }

.aud-panel {
  padding: var(--space-4) var(--space-5);
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: 14px;
}
.aud-panel__hint { margin: 0 0 var(--space-3); font-size: var(--text-sm); color: var(--text-muted); max-width: 68ch; }
.aud-panel__choices { display: flex; flex-wrap: wrap; gap: 6px; }
.aud-panel__bulk { display: flex; gap: var(--space-2); margin: var(--space-2) 0; }

.aud-choice { cursor: pointer; }
.aud-choice input { position: absolute; opacity: 0; pointer-events: none; }
.aud-choice span {
  display: inline-block;
  padding: 5px 12px;
  border: 1px solid var(--border-default);
  border-radius: 999px;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  transition: border-color 0.14s ease, background 0.14s ease, color 0.14s ease;
}
.aud-choice:hover span { border-color: var(--gray-300); }
.aud-choice input:checked + span {
  background: var(--brand-indigo-tint);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: var(--weight-medium);
}
.aud-choice input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.aud-people { max-height: 320px; overflow: auto; border: 1px solid var(--border-subtle); border-radius: 12px; }
.aud-people__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 7px var(--space-3);
  cursor: pointer;
}
.aud-people__row:hover { background: var(--gray-50); }
.aud-people__body { display: flex; flex-direction: column; min-width: 0; }
.aud-people__name { font-size: var(--text-base); color: var(--text-primary); }
.aud-people__job { font-size: var(--text-sm); color: var(--text-muted); }

/* ===== L'aperçu ===== */
.aud-preview {
  position: sticky;
  top: var(--space-6);
  padding: var(--space-4) var(--space-5);
  background: var(--surface-card);
  border: 1px solid var(--border-default);
  border-radius: 16px;
}
.aud-preview__head {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  margin-bottom: var(--space-3);
}
.aud-preview__count { margin: 0 0 var(--space-3); font-size: var(--text-sm); color: var(--text-secondary); }
.aud-preview__count b { color: var(--accent); font-size: var(--text-md); }
.aud-preview__empty { margin: 0; font-size: var(--text-sm); color: var(--text-muted); }
.aud-preview__list { list-style: none; margin: 0; padding: 0; max-height: 460px; overflow: auto;
                     display: flex; flex-direction: column; gap: 2px; }
.aud-preview__row { display: flex; align-items: center; gap: var(--space-3); padding: 4px 2px; }
.aud-preview__body { display: flex; flex-direction: column; min-width: 0; }
.aud-preview__name { font-size: var(--text-base); color: var(--text-primary); }
/* La raison de présence : c'est elle qui fait comprendre le croisement mieux
   qu'une explication en tête d'écran. */
.aud-preview__why { font-size: var(--text-xs); color: var(--text-muted); }

@media (max-width: 1100px) {
  .aud { grid-template-columns: minmax(0, 1fr); }
  .aud-preview { position: static; }
}

@media (prefers-reduced-motion: reduce) {
  .ob-slide > *,
  .ob-head,
  .ob-slide .ob-hero > *,
  .ob-slide .ob-hero__wave--hello,
  .ob-pen path,
  .ob-slide .onboarding__wave,
  .ob-stepper .iw-stepper__step.is-advanced .iw-stepper__line::after,
  .ob-stepper .iw-stepper__step.is-advanced .iw-stepper__dot { animation-delay: 0ms !important; }
}
