/* =============================================================================
   motion.css — kit motion partagé des maquettes « refonte outils » (22/09/2026)
   -----------------------------------------------------------------------------
   Se charge APRÈS base.css. Ne redéfinit aucun composant du socle : il ajoute
   des états animés pilotés par des attributs data-* et cinq utilitaires.

     <link rel="stylesheet" href="../_assets/fonts/fonts.css">
     <link rel="stylesheet" href="../_assets/base.css">
     <link rel="stylesheet" href="../_assets/motion.css">
     <script src="../_assets/motion.js" defer></script>   <-- dans <head>

   Règles tenues :
     · on n'anime que transform et opacity (plus stroke-dashoffset sur les SVG),
       jamais top/left/width/height/margin : aucun recalcul de mise en page ;
     · l'état masqué des révélations est conditionné à la classe .has-motion
       posée par motion.js — sans JavaScript, toute la page reste lisible ;
     · prefers-reduced-motion: reduce == état final immédiat, partout.
   ========================================================================== */


/* -----------------------------------------------------------------------------
   0. Jetons du kit
   -------------------------------------------------------------------------- */
:root {
  --motion-t: 620ms;                            /* révélations */
  --motion-ease: cubic-bezier(.2, .7, .3, 1);
  --motion-stagger: 60ms;                       /* décalage par enfant */
  --marquee-gap: 32px;
  --ring-size: 132px;
}

/* Les panneaux masqués le sont même quand la maquette leur donne un display. */
[hidden] { display: none !important; }


/* -----------------------------------------------------------------------------
   1. Révélation au défilement — [data-reveal] (up par défaut | left | right | scale)
   -------------------------------------------------------------------------- */
.has-motion [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition:
    opacity var(--motion-t) var(--motion-ease),
    transform var(--motion-t) var(--motion-ease);
}
.has-motion [data-reveal="left"]  { transform: translate3d(-26px, 0, 0); }
.has-motion [data-reveal="right"] { transform: translate3d(26px, 0, 0); }
.has-motion [data-reveal="scale"] { transform: scale(.955); }
.has-motion [data-reveal="fade"]  { transform: none; }

/* Le navigateur ne garde la couche composite que tant qu'il y a du mouvement. */
.has-motion [data-reveal]:not(.is-revealed) { will-change: opacity, transform; }

.has-motion [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* En colonne, un bloc large décalé horizontalement déborde de 26 px avant sa
   révélation : sous 720 px, left/right retombent sur le décalage vertical. */
@media (max-width: 720px) {
  .has-motion [data-reveal="left"],
  .has-motion [data-reveal="right"] { transform: translate3d(0, 18px, 0); }
}


/* -----------------------------------------------------------------------------
   2. Compteur — [data-count]
   -------------------------------------------------------------------------- */
[data-count] {
  font-variant-numeric: tabular-nums;   /* les chiffres ne font pas tressauter le bloc */
  font-feature-settings: "tnum" 1;
}


/* -----------------------------------------------------------------------------
   3. Machine à écrire — [data-type]
   -------------------------------------------------------------------------- */
.type__cursor {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  vertical-align: -.12em;
  background: var(--accent);
  border-radius: 1px;
  animation: motion-caret 1s steps(1) infinite;
}
.type__cursor.is-idle { animation-duration: 1.2s; opacity: .45; }

@keyframes motion-caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }


/* -----------------------------------------------------------------------------
   4. Marquee — .marquee > .marquee__track
   -------------------------------------------------------------------------- */
.marquee {
  position: relative;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.marquee[data-direction="up"],
.marquee[data-direction="down"] {
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 10%, #000 90%, transparent);
          mask-image: linear-gradient(180deg, transparent, #000 10%, #000 90%, transparent);
}

.marquee__track {
  display: flex;
  align-items: center;
  gap: var(--marquee-gap);
  width: max-content;
  animation: motion-marquee-x var(--marquee-duration, 30s) linear infinite;
}
.marquee__group {
  display: flex;
  align-items: center;
  gap: var(--marquee-gap);
  flex: 0 0 auto;
}

.marquee[data-direction="right"] .marquee__track { animation-direction: reverse; }

.marquee[data-direction="up"] .marquee__track,
.marquee[data-direction="down"] .marquee__track {
  flex-direction: column;
  width: auto;
  height: max-content;
  animation-name: motion-marquee-y;
}
.marquee[data-direction="up"] .marquee__group,
.marquee[data-direction="down"] .marquee__group { flex-direction: column; }
.marquee[data-direction="down"] .marquee__track { animation-direction: reverse; }

/* Pause au survol ET au clavier : la bande ne fuit pas sous le focus. */
.marquee:hover .marquee__track,
.marquee:focus-within .marquee__track { animation-play-state: paused; }

@keyframes motion-marquee-x {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(calc(-1 * var(--marquee-shift, 50%)), 0, 0); }
}
@keyframes motion-marquee-y {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, calc(-1 * var(--marquee-shift, 50%)), 0); }
}


/* -----------------------------------------------------------------------------
   5. Onglets auto-cyclés — [data-autocycle]
   -------------------------------------------------------------------------- */
[data-autocycle] {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1, 8px);
  border-bottom: 1px solid var(--line);
}
[data-autocycle] [role="tab"] {
  position: relative;
  appearance: none;
  border: 0;
  background: none;
  padding: 12px 16px 14px;
  margin-bottom: -1px;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  transition: color var(--t) var(--ease), background-color var(--t) var(--ease);
}
[data-autocycle] [role="tab"]:hover { color: var(--ink); background: var(--soft); }
[data-autocycle] [role="tab"][aria-selected="true"] { color: var(--accent); }

.autocycle__bar {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  pointer-events: none;
}
.autocycle__bar.is-running {
  transform: scaleX(1);
  transition-property: transform;
  transition-timing-function: linear;
}
/* L'onglet actif garde un filet plein quand le cycle est arrêté. */
[data-autocycle] [role="tab"][aria-selected="true"] .autocycle__bar { transform: scaleX(1); }


/* -----------------------------------------------------------------------------
   6. Tracé SVG — [data-draw]
   -------------------------------------------------------------------------- */
[data-draw] { overflow: visible; }


/* -----------------------------------------------------------------------------
   7. Anneau de score — .ring[data-value][data-max]
   -------------------------------------------------------------------------- */
.ring {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: var(--ring-size);
  height: var(--ring-size);
  flex: 0 0 auto;
}
.ring svg {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
  overflow: visible;
}
.ring circle { fill: none; stroke-width: 9; }
.ring__track { stroke: var(--line); }
.ring__bar {
  stroke: var(--accent);
  stroke-linecap: round;
  transition-property: stroke-dashoffset;
  transition-timing-function: var(--motion-ease);
}
.ring__center {
  position: absolute;
  display: grid;
  justify-items: center;
  gap: 2px;
  max-width: 74%;                       /* un libellé long ne mord pas sur l'arc */
  text-align: center;
}
.ring__value {
  font-family: var(--font-title);
  font-weight: 700;
  /* proportionnel à l'anneau : un montant de 5 caractères garde de l'air */
  font-size: clamp(16px, calc(var(--ring-size, 132px) * .2), 30px);
  line-height: 1.1;
  letter-spacing: -.01em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.ring__label {
  font-size: 11px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
}


/* -----------------------------------------------------------------------------
   8. Cursor tour — .tour[data-tour]
   -------------------------------------------------------------------------- */
.tour { position: relative; }

.tour__layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 5;
}
.tour__cursor,
.tour__label,
.tour__ripple {
  position: absolute;
  top: 0;
  left: 0;
  will-change: transform;
}
.tour__cursor {
  transition: transform 600ms var(--motion-ease);
  filter: drop-shadow(0 4px 10px rgba(17, 24, 39, .28));
}
.tour__cursor svg { width: 26px; height: 26px; }

.tour__label {
  max-width: 220px;
  padding: 7px 12px;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
  white-space: nowrap;
  opacity: 0;
  /* la bulle ne glisse jamais d'une cible à l'autre (elle traverserait le texte) :
     elle se pose, puis apparaît */
  transition: opacity 220ms var(--motion-ease);
  box-shadow: 0 6px 18px rgba(17, 24, 39, .18);
}
.tour__label.is-on { opacity: 1; }

.tour__ripple {
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0;
}
.tour__ripple.is-on { animation: motion-ripple 460ms var(--motion-ease) forwards; }

@keyframes motion-ripple {
  from { opacity: .35; transform: translate3d(var(--rx, 0), var(--ry, 0), 0) scale(.4); }
  to   { opacity: 0;   transform: translate3d(var(--rx, 0), var(--ry, 0), 0) scale(3.6); }
}

/* Cibles pendant le tour : aucune propriété de mise en page n'est touchée. */
.tour .is-tour-hover,
.tour .is-tour-active {
  box-shadow: 0 0 0 3px var(--accent-ring);
  border-color: var(--accent);
}
.tour .is-tour-active { transform: translateY(1px); }

.tour__controls {
  position: absolute;
  right: var(--tour-controls-inset, 12px);
  bottom: var(--tour-controls-inset, 12px);
  display: flex;
  gap: 8px;
  z-index: 6;
}
/* Option : Pause / Rejouer sous la démo, dans le flux (rien n'est recouvert). */
.tour--controls-flow .tour__controls {
  position: static;
  grid-column: 1 / -1;
  justify-content: flex-end;
  margin-top: 12px;
}
/* emplacement choisi par la page : <div data-tour-controls></div> dans la zone */
[data-tour-controls] > .tour__controls { position: static; justify-content: center; }
.only-reduced { display: none; }
@media (prefers-reduced-motion: reduce) { .only-reduced { display: revert; } }
.tour__btn {
  appearance: none;
  min-height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, .92);
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  backdrop-filter: blur(6px);
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.tour__btn:hover { color: var(--ink); border-color: var(--line-strong); }


/* -----------------------------------------------------------------------------
   9. Parallaxe — [data-parallax]
   -------------------------------------------------------------------------- */
[data-parallax] { will-change: transform; }

@media (max-width: 900px) {
  [data-parallax] { transform: none !important; will-change: auto; }
}


/* -----------------------------------------------------------------------------
   10. Utilitaires
   -------------------------------------------------------------------------- */
.hover-lift {
  transition: transform var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.hover-lift:hover {
  transform: translateY(-3px);
  box-shadow: 0 2px 4px rgba(17, 24, 39, .05), 0 14px 32px rgba(17, 24, 39, .09);
}

.halo {
  background-image: radial-gradient(
    62% 62% at 50% 38%,
    color-mix(in srgb, var(--accent) 6%, transparent),
    transparent 72%
  );
}
@supports not (color: color-mix(in srgb, #000 6%, #fff)) {
  .halo { background-image: none; background-color: var(--soft); }
}

.glow-border {
  border: 2px solid var(--line);
  border-radius: var(--radius);
  transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.glow-border:hover,
.glow-border:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-ring);
}

.kpi { display: grid; gap: 4px; }
.kpi__num {
  font-family: var(--font-title);
  font-weight: 700;
  font-size: 44px;
  line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.kpi__num .kpi__unit { font-size: .52em; color: var(--muted); margin-left: 4px; }
.kpi__label { font-size: 14px; color: var(--muted); }

/* .chip appartient à base.css. La copie ci-dessous vit dans une couche en
   cascade : elle ne sert que si motion.css est utilisé seul — dès que base.css
   est chargé, sa règle (hors couche) l'emporte quel que soit l'ordre. */
@layer motion-fallback {
  .chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    align-self: flex-start;
    padding: 5px 11px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
  }
  .chip--neutral { background: var(--soft); color: var(--muted); }
  .chip svg { width: 14px; height: 14px; }
}

@media (max-width: 720px) {
  .kpi__num { font-size: 34px; }
  /* la bulle reste sur une ligne (le script la tient dans la zone) */
  .tour__label { max-width: calc(100% - 16px); overflow: hidden; text-overflow: ellipsis; }
}
/* curseur caché tant qu'il n'a pas reçu sa première position (plus de flèche au coin 0,0) */
.tour__cursor:not([style*="translate"]) { opacity: 0; }
/* cible invisible posée sur une vraie capture : ni contour ni décalage pendant le tour */
.tour .tour-hit { position: absolute; display: block; }
.tour .tour-hit, .tour .tour-hit.is-tour-hover, .tour .tour-hit.is-tour-active {
  box-shadow: none; border: 0; outline: 0; background: transparent; transform: none; padding: 0;
}
/* point de toucher forcé : .tour--touch (téléphone affiché sur ordinateur) */
.tour--touch .tour__layer.is-typing .tour__cursor { opacity: 0; }
.tour--touch .tour__cursor svg { display: none; }
.tour--touch .tour__cursor::before {
  content: "";
  display: block;
  width: 28px;
  height: 28px;
  margin: -14px 0 0 -14px;
  border-radius: 50%;
  background: rgba(17, 24, 39, .28);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .9);
}
/* écran tactile : un point de toucher à la place de la flèche de souris */
@media (hover: none) {
  .tour__layer.is-typing .tour__cursor { opacity: 0; }  /* le point ne cache pas la frappe */
  .tour__cursor svg { display: none; }
  .tour__cursor::before {
    content: "";
    display: block;
    width: 28px;
    height: 28px;
    margin: -14px 0 0 -14px;
    border-radius: 50%;
    background: rgba(17, 24, 39, .28);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, .9);
  }
}


/* -----------------------------------------------------------------------------
   11. Mouvement réduit — état final, immédiatement, sans exception
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .has-motion [data-reveal],
  .has-motion [data-reveal].is-revealed {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    will-change: auto;
  }
  .type__cursor { display: none !important; }        /* état final : plus de curseur de frappe */
  .only-motion { display: none !important; }        /* textes du type « défilent seuls » */
  .marquee__track { animation: none !important; transform: none !important; }
  /* piste figée : alignée sur la gouttière du contenu */
  .marquee:not([data-direction="up"]):not([data-direction="down"]):not(.container .marquee) .marquee__track {
    padding-inline-start: max(var(--gutter, 16px), calc((100% - var(--container, 1200px)) / 2 + var(--gutter, 16px)));
  }
  /* .marquee--wrap-static : piste figée centrée, repliée, sans fondu */
  .marquee--wrap-static { -webkit-mask-image: none !important; mask-image: none !important; }
  .marquee--wrap-static .marquee__track { flex-wrap: wrap; justify-content: center; width: auto !important; padding-inline: var(--gutter, 16px) !important; }
  .marquee--wrap-static .marquee__group[aria-hidden="true"] { display: none; }
  .marquee--wrap-static .marquee__group { flex: 1 1 auto; flex-wrap: wrap; justify-content: center; }
  /* piste figée : fondu d'un seul côté, pour ne pas trancher une pastille net */
  .marquee {
    -webkit-mask-image: linear-gradient(90deg, #000 82%, transparent);
            mask-image: linear-gradient(90deg, #000 82%, transparent);
  }
  .marquee[data-direction="up"],
  .marquee[data-direction="down"] {
    -webkit-mask-image: linear-gradient(180deg, #000 82%, transparent);
            mask-image: linear-gradient(180deg, #000 82%, transparent);
  }
  .autocycle__bar.is-running { transition: none !important; }
  .ring__bar { transition: none !important; }
  .tour__cursor,
  .tour__label { transition: none !important; }
  .tour__ripple { animation: none !important; opacity: 0 !important; }
  [data-parallax] { transform: none !important; }
  .hover-lift:hover { transform: none; }
}

/* ---------------------------------------------------------------------------
   Écrans d'un parcours (boucle 5) : captures réelles empilées dans un appareil,
   une seule visible (.is-on), fondu court (140 ms) : pas de double exposition visible. La première donne la hauteur.
   <div class="tour-screens"><img data-screen="brut" class="is-on" …><img data-screen="srt" …></div>
   --------------------------------------------------------------------------- */
.tour-screens { position: relative; }
.tour-screens > [data-screen] {
  display: block;
  width: 100%;
  height: auto;
  max-width: none;
  transition: none; /* coupe franche, comme une vraie interface (plus de double exposition) */
}
.tour-screens[data-fade] > [data-screen] { transition: opacity 140ms ease-out; }
.tour-screens > [data-screen] ~ [data-screen] { position: absolute; top: 0; left: 0; }
.tour-screens > [data-screen]:first-child { position: relative; }
.tour-screens > [data-screen]:not(.is-on):not(.is-prev) { opacity: 0; }
.tour-screens > [data-screen].is-prev { opacity: 1; z-index: 1; transition: none; }
.tour-screens > [data-screen].is-on { opacity: 1; z-index: 2; }
@media (prefers-reduced-motion: reduce) { .tour-screens > [data-screen] { transition: none; } }
