/* =============================================================================
   narrator.css : LE RAIL (V2)
   Barre fixe en haut de la scène (« sous le capot ») : progression, idée grand
   public, volets « Côté technique » et « </> Voir le code » repliables,
   navigation Précédent / Suivant. Le rail est un RANG de grille de #stage (voir
   tour.css), il n'est plus en position flottante et ne fait plus de spotlight.
   Tokens du design system, style sobre, accent en HAUT jamais à gauche.
   ========================================================================== */

/* Le spotlight V1 n'existe plus en V2 (la scène révèle une vue à la fois). */
#spotlight-backdrop { display: none; }

/* Conteneur du rail : rang HAUT de la grille #stage. Replié si pas de contenu. */
/* Le rail vit EN HAUT de la scène (au-dessus du dual-pane) : accent dessous,
   ombre portée vers le bas. Accent horizontal uniquement, jamais latéral. */
#narrator {
  background: var(--rs-surface);
  border-bottom: 3px solid var(--rs-main);
  box-shadow: 0 6px 20px rgba(34, 60, 82, 0.10);
  max-height: 46vh; overflow: auto;
  box-sizing: border-box;
}
#narrator:not(.is-visible) { display: none; }

/* Contenu centré, lisible. */
/* `box-sizing: border-box` est INDISPENSABLE ici : avec `width: 100%` et un
   padding horizontal, la boîte dépassait son parent de la valeur du padding
   (462 px dans 430 px) et #narrator, qui masque le débordement, rognait le
   bord droit du bouton « Suivant » sur mobile. On aligne .narrator-rail sur
   #narrator (l. 21), sans toucher à la convention globale de design-system.css. */
.narrator-rail {
  box-sizing: border-box;
  width: 100%; max-width: 980px; margin: 0 auto;
  padding: var(--rs-sp-4) var(--rs-sp-5) var(--rs-sp-5);
  display: flex; flex-direction: column; gap: var(--rs-sp-3);
}
/* Même raison, par prudence : la barre de navigation ne doit jamais déborder. */
.narrator-rail__top,
.narrator-rail__head,
.narrator-rail__panels,
.narrator-rail__nav { box-sizing: border-box; max-width: 100%; }

/* -- Bandeau HAUT : progression à gauche, Précédent / Suivant à droite ------ */
/* Les boutons sont ancrés en tête du rail : leur position verticale ne dépend
   plus de la longueur du texte de l'étape (le rail est à hauteur fixe et le
   corps, lui, défile). Ils ne peuvent donc plus sortir du cadre. */
.narrator-rail__top {
  display: flex; align-items: center; gap: var(--rs-sp-4);
  flex-shrink: 0;
}
.narrator-rail__top .narrator-rail__head { flex: 1 1 auto; min-width: 0; }
.narrator-rail__top .narrator-rail__nav { flex: 0 0 auto; margin-top: 0; }

/* -- En-tête : étape + barre de progression -------------------------------- */
.narrator-rail__head { display: flex; align-items: center; gap: var(--rs-sp-4); }
.narrator-rail__step {
  flex-shrink: 0;
  font-size: var(--rs-fs-xs); font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--rs-main-600);
}
/* La barre porte les PASTILLES d'étape : `overflow` doit rester visible (elles
   débordent des 5 px de la barre) et les marges latérales évitent que la
   première et la dernière soient rognées par le bandeau. */
.narrator-track {
  position: relative;
  flex: 1; height: 5px; border-radius: var(--rs-radius-pill);
  background: var(--rs-surface-2); overflow: visible;
  margin: 0 14px;
}
.narrator-track__fill {
  display: block; height: 100%; border-radius: inherit;
  background: linear-gradient(90deg, var(--rs-main), var(--rs-main-600));
  transition: width var(--rs-dur-slow) var(--rs-ease);
}

/* -- Pastilles d'étape ------------------------------------------------------
   Une pastille numérotée par sous-étape DÉJÀ FRANCHIE : elles se posent une à
   une pendant la simulation (une par seconde) et servent de sommaire cliquable
   une fois la lecture passée. C'est le seul moyen de relire un texte que la
   cadence n'a pas laissé le temps de lire. */
.narrator-track__dot {
  position: absolute; top: 50%; left: 0;
  transform: translate(-50%, -50%);
  width: 22px; height: 22px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--rs-surface); border-radius: 50%;
  background: var(--rs-main); color: #fff;
  font-family: inherit; font-size: 11px; font-weight: 800; line-height: 1;
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(34, 60, 82, 0.22);
  transition: transform var(--rs-dur) var(--rs-ease),
              background var(--rs-dur) var(--rs-ease);
}
.narrator-track__dot:hover { transform: translate(-50%, -50%) scale(1.18); }
.narrator-track__dot:focus-visible { outline: 2px solid var(--rs-secondary); outline-offset: 2px; }
/* L'étape affichée : orange d'action, comme le bouton du rail. */
.narrator-track__dot.is-current {
  background: var(--rs-accent);
  box-shadow: 0 0 0 3px rgba(242, 104, 44, 0.24);
  transform: translate(-50%, -50%) scale(1.12);
}
.narrator-track__dot.is-current:hover { transform: translate(-50%, -50%) scale(1.22); }
/* Apparition de la pastille de l'étape qui vient d'arriver. */
.narrator-track__dot.is-fresh { animation: rail-dot-pop 420ms var(--rs-ease) both; }
@keyframes rail-dot-pop {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.2); }
  60%  { opacity: 1; transform: translate(-50%, -50%) scale(1.45); }
  /* On finit à l'échelle de `.is-current` : la pastille fraîche EST l'étape
     affichée, l'animation ne doit pas la rapetisser en atterrissant. */
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1.12); }
}
@media (prefers-reduced-motion: reduce) {
  .narrator-track__dot.is-fresh { animation: none; }
}

/* -- Corps : titre + texte grand public ------------------------------------ */
.narrator-rail__title {
  font-size: var(--rs-fs-xl); line-height: 1.2; font-weight: 800; color: var(--rs-secondary);
}
.narrator-rail__text {
  margin-top: 6px; color: var(--rs-ink-soft); font-size: var(--rs-fs-md); line-height: 1.55;
  max-width: 70ch;
}
.narrator-rail__text strong { color: var(--rs-secondary); font-weight: 800; }
.narrator-rail__text code,
.narrator-rail__tech-text code {
  font-family: var(--rs-mono); font-size: 0.92em;
  background: var(--rs-surface-2); border-radius: var(--rs-radius-sm); padding: 0.05em 0.35em;
}

/* -- Volets repliables : Côté technique + Voir le code --------------------- */
.narrator-rail__panels { display: flex; flex-direction: column; gap: var(--rs-sp-2); margin-top: 4px; }
.narrator-panel__toggle {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px;
  background: var(--rs-surface-2); color: var(--rs-main-600);
  border: 1px solid var(--rs-line); border-radius: var(--rs-radius-pill);
  font-size: var(--rs-fs-xs); font-weight: 800; letter-spacing: 0.04em;
  text-transform: uppercase; cursor: pointer;
  transition: background var(--rs-dur) var(--rs-ease), color var(--rs-dur) var(--rs-ease);
}
.narrator-panel__toggle:hover { background: var(--rs-line); }
.narrator-panel__toggle.is-open { background: var(--rs-secondary); color: #fff; border-color: var(--rs-secondary); }
.narrator-panel--code .narrator-panel__toggle { font-family: var(--rs-mono); }
.narrator-panel__caret { font-size: 10px; transition: transform var(--rs-dur) var(--rs-ease); }
.narrator-panel__toggle.is-open .narrator-panel__caret { transform: rotate(180deg); }
.narrator-panel__block { display: none; margin-top: 8px; }
.narrator-panel__block.is-open { display: block; }

/* -- Détail technique : déplié en permanence (plus de bouton repliable) ----- */
.narrator-rail__tech { margin-top: 4px; }
.narrator-rail__tech-label {
  display: inline-block; margin-bottom: 6px;
  font-size: var(--rs-fs-xs); font-weight: 800; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--rs-main-600);
}
.narrator-rail__tech-text {
  margin: 0; padding: 10px 12px;
  background: var(--rs-surface-2); border-radius: var(--rs-radius);
  color: var(--rs-ink-soft); font-size: var(--rs-fs-sm); line-height: 1.5;
}
.narrator-rail__tech-text strong { color: var(--rs-secondary); font-weight: 800; }

/* Bloc code : thème monospace de l'inspecteur (pre.code-block est déjà stylé). */
.narrator-code { position: relative; }
.narrator-code__lang {
  position: absolute; top: 8px; right: 12px; z-index: 1;
  font-family: var(--rs-mono); font-size: var(--rs-fs-xs); font-weight: 700;
  color: var(--rs-dev-accent); letter-spacing: 0.04em; text-transform: uppercase;
}
.narrator-code__pre {
  margin: 0; max-height: 240px; overflow: auto;
  line-height: 1.5;
}

/* -- Navigation (dans le bandeau haut) ------------------------------------- */
.narrator-rail__nav { display: flex; align-items: center; gap: var(--rs-sp-2); }
.narrator-rail__nav-spacer { flex: 1; }

/* Bouton « Suivant » / « Terminer » : LE point d'action du rail. On le rend
   nettement plus visible (taille, ombre portée colorée, pulsation douce) pour
   qu'on comprenne d'un coup d'œil qu'il faut cliquer, sinon la démo paraît figée.
   Il porte l'ORANGE de charte (rs-btn--accent) et non le vert : c'est le seul
   bouton du rail qui fait avancer, il ne doit pas se confondre avec les actions
   vertes de la vitrine rejouée juste en dessous. */
.narrator-rail__next, .narrator-rail__finish {
  font-weight: 800; font-size: var(--rs-fs-md);
  padding: 12px 30px; border-radius: var(--rs-radius-pill);
  box-shadow: 0 6px 18px rgba(242, 104, 44, 0.32);
}
.narrator-rail__next:not([disabled]):not(.narrator-rail__pause),
.narrator-rail__finish:not([disabled]) {
  animation: rail-next-pulse 1.8s var(--rs-ease) infinite;
}
/* Pendant la lecture, le bouton devient « Pause » : plus rien à réclamer, il ne
   pulse donc plus et s'efface au profit de ce qui se joue dans les colonnes. */
.narrator-rail__pause { animation: none; box-shadow: none; opacity: .85; }
/* Le libellé de lancement est long : sur écran étroit il passe à la ligne au
   lieu de pousser Précédent hors du rail. */
.narrator-rail__run { white-space: normal; text-wrap: balance; }
.narrator-rail__next:not([disabled]):hover,
.narrator-rail__finish:not([disabled]):hover { animation-play-state: paused; transform: translateY(-1px); }
@keyframes rail-next-pulse {
  0%, 100% { box-shadow: 0 6px 18px rgba(242, 104, 44, 0.28); transform: translateY(0); }
  50%      { box-shadow: 0 9px 28px rgba(242, 104, 44, 0.55); transform: translateY(-3px); }
}
@media (prefers-reduced-motion: reduce) {
  .narrator-rail__next, .narrator-rail__finish { animation: none; }
}
.narrator-rail__nav .rs-btn[disabled] { opacity: 0.4; cursor: default; pointer-events: none; }

/* -- Responsive ------------------------------------------------------------ */
/* Rail compact sur les écrans de démo courants (jusqu'au 1080p inclus) : en
   layout 3 bandes, chaque pixel du rail est pris sur le dual-pane et la
   vitrine en dessous. */
@media (max-height: 1000px) {
  .narrator-rail { padding: var(--rs-sp-3) var(--rs-sp-4); gap: var(--rs-sp-2); }
  .narrator-rail__title { font-size: var(--rs-fs-lg); }
  .narrator-rail__next, .narrator-rail__finish { padding: 9px 22px; font-size: var(--rs-fs-sm); }
}
/* Hauteur stable pendant le parcours : les étapes peuvent changer de texte,
   mais le dual-pane ne doit pas remonter ou descendre à chaque clic.
   Le rail occupe toute cette hauteur et c'est le CORPS qui défile : le bandeau
   haut (progression + Précédent / Suivant) reste ainsi cloué en place, quelle
   que soit la longueur de l'étape. */
@media (min-width: 721px) {
  html[data-tour-state="under_the_hood"] #narrator {
    height: 300px;
    max-height: 300px;
    overflow: hidden;
  }
}
html[data-tour-state="under_the_hood"] .narrator-rail { height: 100%; }
html[data-tour-state="under_the_hood"] .narrator-rail__body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
}
/* -- Pendant la simulation (une étape par seconde) --------------------------
   À cette cadence, personne ne lit un paragraphe : on masque le texte et le
   détail technique, on garde le titre (une ligne) et la timeline, dont les
   pastilles se posent une à une. Le rail cesse alors d'occuper sa hauteur
   fixe : les colonnes du dual-pane, elles, ont quelque chose à montrer.
   Tout revient dès la pause ou le clic sur une pastille. */
.narrator-rail.is-running .narrator-rail__text,
.narrator-rail.is-running .narrator-rail__tech { display: none; }
/* Le titre change chaque seconde : il ENTRE (comme les blocs des colonnes) au
   lieu d'être remplacé sèchement, et il réserve deux lignes pour que le
   dual-pane ne monte ni ne descende selon la longueur du titre. */
.narrator-rail.is-running .narrator-rail__title {
  font-size: var(--rs-fs-lg);
  min-height: 2.4em;
  animation: rail-title-in .35s ease both;
}
@keyframes rail-title-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .narrator-rail.is-running .narrator-rail__title { animation: none; }
}

@media (max-width: 720px) {
  #narrator { height: 360px; max-height: 360px; overflow: hidden; }
  .narrator-rail { padding: var(--rs-sp-3) var(--rs-sp-4) var(--rs-sp-4); }
  .narrator-rail__title { font-size: var(--rs-fs-lg); }
  /* Sur petit écran, la progression passe au-dessus des boutons plutôt que de
     les comprimer : les deux restent dans le bandeau haut. */
  .narrator-rail__top { flex-wrap: wrap; gap: var(--rs-sp-2); }
  .narrator-rail__top .narrator-rail__head { flex: 1 1 100%; }
  .narrator-rail__nav { flex-wrap: wrap; width: 100%; justify-content: flex-end; }
}

/* Hauteur du rail en lecture : elle suit le contenu (titre + timeline) au lieu
   des 300/360 px réservés à une étape lue. Déclaré APRÈS les deux blocs de
   hauteur fixe, et avec la classe en plus, pour gagner sur les deux. */
#narrator.is-running,
html[data-tour-state="under_the_hood"] #narrator.is-running {
  height: auto; max-height: none; overflow: hidden;
}
