/* Hich's iDroid — pack de mouvement (V1.1). Toutes les durées et courbes vivent ici.
   Règle : transforms et opacité seulement, plus les tracés SVG par stroke-dashoffset.
   Jamais de largeur, de hauteur ni de position animées. */
:root{
  --ease-out:cubic-bezier(.2,.7,.2,1);
  --ease-snap:cubic-bezier(.4,0,.2,1);
  --m-press:60ms;      /* M14 pression */
  --m-tab:180ms;       /* M2 onglet */
  --m-stagger:24ms;    /* échelonnement des lignes, 8 lignes au maximum */
  --m-stagger-tab:18ms;
  --m-stagger-sheet:16ms;
  --m-row:200ms;       /* apparition d'une ligne */
  --m-sel:120ms;       /* M3 balayage de la sélection */
  --m-stamp:120ms;     /* tampon de la sélection */
  --m-task:160ms;      /* M4 tâche cochée */
  --m-box:90ms;
  --m-count:240ms;     /* M5 nombre qui défile */
  --m-fill:300ms;      /* barres */
  --m-banner:1600ms;   /* M6 bannière */
  --m-banner-in:220ms;
  --m-day:900ms;       /* M7 journée complète */
  --m-map:1000ms;      /* M8 carte */
  --m-terrain:800ms;   /* M9 terrain */
  --m-sheet:200ms;     /* M10 feuille */
  --m-decode:12ms;     /* M11 par caractère */
  --m-missed:400ms;    /* M12 pulsation */
  --m-minute:120ms;    /* M13 minute qui glisse */
  --m-boot-line:120ms; --m-boot-wipe:180ms; --m-boot-type:300ms;
}
/* Niveau réduit : durées des tokens v2, aucune boucle, aucun son. Niveau off : tout instantané. */
html[data-motion="reduit"]{--m-stagger:0ms;--m-stagger-tab:0ms;--m-banner:900ms;--m-map:0ms;--m-terrain:0ms;--m-decode:0ms}
html[data-motion="off"] *,html[data-motion="off"] *::before,html[data-motion="off"] *::after{animation-duration:0s!important;animation-delay:0s!important;transition-duration:0s!important;transition-delay:0s!important}

/* ---------- M14 pression ---------- */
.pressing{opacity:.7;transform:scale(.98);transition:transform var(--m-press) var(--ease-snap)}
[data-tap],[data-long]{transition:transform var(--m-press) var(--ease-snap)}

/* ---------- lignes qui s'échelonnent (M1, M2, M10) ---------- */
@keyframes m-row-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.m-in{animation:m-row-in var(--m-row) var(--ease-out) both}
html[data-motion="off"] .m-in{animation:none}

/* ---------- M3 sélection : coupe nette puis balayage ---------- */
.sel{position:relative;overflow:hidden}
@keyframes m-sweep{from{transform:translateX(-120%)}to{transform:translateX(220%)}}
.sel.m-sweep::after{content:"";position:absolute;top:0;bottom:0;left:0;width:45%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.2),transparent);animation:m-sweep var(--m-sel) var(--ease-out) 1;pointer-events:none}
@keyframes m-stamp{from{transform:scale(1.03)}to{transform:scale(1)}}
.sel.m-stamp{animation:m-stamp var(--m-stamp) var(--ease-snap) 1}

/* ---------- M4 tâche cochée ---------- */
@keyframes m-pop{from{transform:scale(.6)}to{transform:scale(1)}}
.box.ok.m-pop{animation:m-pop var(--m-box) var(--ease-snap) 1}
.task{position:relative;overflow:hidden}
@keyframes m-line{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
.task.m-done::after{content:"";position:absolute;left:0;right:0;top:50%;height:1px;background:var(--cyan);opacity:.5;animation:m-line var(--m-task) var(--ease-out) 1;pointer-events:none}

/* ---------- M6 bannière mission accomplie ---------- */
.m-banner{position:relative;overflow:hidden;margin:0 calc(-1 * var(--gutter));padding:7px var(--gutter);background:var(--orange);color:var(--orange-ink);font-size:var(--fs-hint);font-weight:600;letter-spacing:var(--ls-head);clip-path:var(--clip-btn);animation:m-banner-in var(--m-banner-in) var(--ease-out) both,m-banner-out var(--m-banner-in) var(--ease-out) calc(var(--m-banner) - var(--m-banner-in)) both}
@keyframes m-banner-in{from{transform:translateX(-101%)}to{transform:none}}
@keyframes m-banner-out{from{transform:none}to{transform:translateX(101%)}}

/* ---------- M7 journée complète ---------- */
@keyframes m-pulse-cy{0%,100%{background:var(--orange)}50%{background:var(--cyan)}}
.bar.m-day i{animation:m-pulse-cy var(--m-day) var(--ease-out) 1}

/* ---------- M8 carte ---------- */
.map .m-draw{stroke-dasharray:var(--len);stroke-dashoffset:var(--len);animation:m-draw 600ms var(--ease-out) forwards;animation-delay:var(--d,0ms)}
@keyframes m-draw{to{stroke-dashoffset:0}}
.map .m-mark{opacity:0;animation:m-mark 200ms var(--ease-out) forwards;animation-delay:var(--d,0ms)}
@keyframes m-mark{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.map .m-you{opacity:0;animation:m-you 200ms var(--ease-out) forwards;animation-delay:var(--d,0ms)}
@keyframes m-you{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:none}}
/* au repos : bande de balayage et pulsation du marqueur d'objectif */
.map .m-scan{position:absolute;left:0;right:0;height:64px;background:linear-gradient(180deg,transparent,rgba(138,217,245,.04),transparent);pointer-events:none;animation:m-scan 6s linear infinite}
@keyframes m-scan{from{transform:translateY(-64px)}to{transform:translateY(322px)}}
.map .m-obj{transform-box:fill-box;transform-origin:center;animation:m-obj 2.4s var(--ease-out) infinite}
@keyframes m-obj{0%{transform:scale(1);opacity:.35}70%{transform:scale(1.6);opacity:0}100%{opacity:0}}
html[data-motion="reduit"] .m-scan,html[data-motion="reduit"] .m-obj,html[data-motion="off"] .m-scan,html[data-motion="off"] .m-obj{animation:none;opacity:.35}

/* ---------- M9 terrain ---------- */
.terrain .m-col{transform-box:fill-box;transform-origin:bottom;animation:m-col 260ms var(--ease-out) both;animation-delay:var(--d,0ms)}
@keyframes m-col{from{transform:scaleY(0)}to{transform:scaleY(1)}}
.terrain .m-poly{stroke-dasharray:var(--len);stroke-dashoffset:var(--len);animation:m-draw 300ms var(--ease-out) 520ms forwards}
.segs.m-segs i{animation:m-seg 120ms var(--ease-out) both;animation-delay:var(--d,0ms)}
@keyframes m-seg{from{opacity:0;transform:scaleX(.2)}to{opacity:1;transform:none}}

/* ---------- M12 fenêtre manquée ---------- */
@keyframes m-missed{0%,100%{opacity:1}50%{opacity:.35}}
.row.missed.m-missed{animation:m-missed var(--m-missed) var(--ease-out) 2}

/* ---------- M13 barre haute ---------- */
@keyframes m-minute{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.read.m-minute{animation:m-minute var(--m-minute) var(--ease-out) 1}
.sig{display:inline-flex;align-items:flex-end;gap:2px;margin-left:8px;vertical-align:-1px}
.sig i{width:2px;background:var(--dim-2);animation:m-sig 3s ease-in-out infinite}
.sig i:nth-child(1){height:4px;animation-delay:0ms}
.sig i:nth-child(2){height:7px;animation-delay:120ms}
.sig i:nth-child(3){height:10px;animation-delay:240ms}
@keyframes m-sig{0%,100%{opacity:.3}50%{opacity:1}}
html[data-motion="reduit"] .sig i,html[data-motion="off"] .sig i{animation:none;opacity:.6}

/* ---------- M1 ouverture ---------- */
#boot{background:var(--ground)}
#boot .m-line{position:absolute;left:50%;top:50%;width:0;height:1px;background:var(--cyan);transform:translate(-50%,-50%);animation:m-line-grow var(--m-boot-line) var(--ease-out) forwards}
@keyframes m-line-grow{to{width:100%}}
#boot.m-wipe{animation:m-wipe var(--m-boot-wipe) var(--ease-snap) forwards}
@keyframes m-wipe{0%{clip-path:inset(0 0 0 0);opacity:1}30%{opacity:.75}45%{opacity:1}60%{opacity:.85}100%{clip-path:inset(100% 0 0 0);opacity:1}}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:0s!important;animation-delay:0s!important;transition-duration:0s!important}
}
