/* ==========================================================================
   Flex Timer · landing — couche d'effets (styles de assets/fx.js)
   Couleurs : uniquement les tokens de site.css (--mode, --ink, --line...).
   Tout est décoratif : sans JS, la page s'affiche comme sans ce fichier
   (seul le bandeau [data-fx~="marquee"] devient balayable au doigt).
   Calques fixes : .ft-stage (-2) < ambiance, halo, onde (-1) < contenu.
   ========================================================================== */

/* ---------- Barre de progression (comme la barre de l'écran de séance) ----------
   Remplissage à l'encre (blanc, noir sur TABATA) : en --mode il disparaîtrait
   sur les scènes de mode, dont le haut du dégradé est exactement --mode. La
   couleur de la scène passe dans la lueur, et devient le remplissage sur l'or. */
.ft-fx-progress {
  --fx-bar: var(--ink);
  position: fixed;
  left: 0;
  right: 0;
  top: env(safe-area-inset-top, 0px);
  height: 3px;
  z-index: 60;
  pointer-events: none;
  background: var(--line);
}
:root[data-stage="gold"] .ft-fx-progress { --fx-bar: var(--mode); }
.ft-fx-progress__fill {
  position: absolute;
  inset: 0;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: var(--fx-bar);
  box-shadow: 0 0 12px color-mix(in srgb, var(--mode) 70%, transparent);
}
/* Encoche : discrète tant qu'elle est devant, puis elle « coupe » le remplissage
   dans la couleur inverse de l'encre (trackNotch de l'app). */
.ft-fx-progress__notch {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 2px;
  margin-left: -1px;
  border-radius: 2px;
  background: var(--ink-muted);
  transition: background-color .3s ease, transform .4s var(--ease-forward);
}
.ft-fx-progress__notch.is-passed { background: var(--cta-ink); transform: scaleY(1.4); }

/* ---------- Ambiance (canvas de braises + anneau géant) ---------- */
.ft-fx-ambient {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: -1;
  pointer-events: none;
}

/* ---------- Halo sous le curseur ----------
   Le parent ne fait que suivre la souris (transform) ; l'échelle vit sur ::before
   pour ne pas fausser la position. Fusion posée sur le parent : c'est lui qui
   est dans le contexte d'empilement de la page. */
.ft-fx-halo {
  position: fixed;
  left: 0;
  top: 0;
  z-index: -1;
  width: 38rem;
  height: 38rem;
  margin: -19rem 0 0 -19rem;
  pointer-events: none;
  mix-blend-mode: screen;
  will-change: transform;
}
.ft-fx-halo::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(closest-side,
    color-mix(in srgb, var(--mode) 40%, transparent),
    color-mix(in srgb, var(--mode) 12%, transparent) 55%,
    transparent);
  opacity: 0;
  transform: scale(.85);
  transition: opacity .7s ease, transform .6s var(--ease-forward);
}
.ft-fx-halo.is-on::before { opacity: .6; transform: scale(1); }
.ft-fx-halo.is-on.is-hot::before { opacity: .85; transform: scale(1.18); }
/* TABATA : jaune sur jaune, la fusion « lumière douce » reste discrète. */
:root[data-ink="dark"] .ft-fx-halo { mix-blend-mode: soft-light; }

/* ---------- Onde de changement de scène ---------- */
.ft-fx-wave {
  --fx-wave: var(--mode);
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: -1;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(closest-side,
    color-mix(in srgb, var(--fx-wave) 10%, transparent) 0%,
    color-mix(in srgb, var(--fx-wave) 6%, transparent) 55%,
    color-mix(in srgb, var(--fx-wave) 34%, transparent) 86%,
    color-mix(in srgb, var(--fx-wave) 70%, transparent) 97%,
    transparent 100%);
  transform: scale(.04);
  opacity: 0;
  animation: ft-fx-wave 700ms var(--ease-impact) forwards;
}
@keyframes ft-fx-wave {
  0% { transform: scale(.04); opacity: 0; }
  14% { opacity: .9; }
  100% { transform: scale(1); opacity: 0; }
}

/* ---------- Onde au clic des boutons ----------
   currentColor = couleur du texte du bouton : sombre sur la porcelaine, claire
   sur l'accent. z-index -1 dans le bouton isolé : sous le texte. */
.ft-fx-ripple {
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  pointer-events: none;
  background: currentColor;
  opacity: 0;
  transform: scale(0);
  animation: ft-fx-ripple 620ms var(--ease-impact) forwards;
}
@keyframes ft-fx-ripple {
  0% { transform: scale(0); opacity: .3; }
  100% { transform: scale(1); opacity: 0; }
}

/* ---------- magnetic : le contenu suit un peu plus que le bouton (profondeur) ---------- */
.ft-btn[data-fx~="magnetic"] > :not(.ft-fx-ripple),
.ft-iconbtn[data-fx~="magnetic"] > :not(.ft-fx-ripple) {
  translate: calc(var(--fx-mx, 0px) * .35) calc(var(--fx-my, 0px) * .35);
}

/* ---------- tilt : reflet qui glisse ----------
   Fusion « écran » avec la couleur de la scène : toujours un éclaircissement
   (blanc sur le noir d'ouverture, jaune lumineux sur TABATA...). */
.ft-fx-glare {
  --gx: 50%;
  --gy: 30%;
  position: absolute;
  inset: 0;
  z-index: 6;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle at var(--gx) var(--gy),
    color-mix(in srgb, var(--mode) 55%, transparent) 0%,
    color-mix(in srgb, var(--mode) 18%, transparent) 28%,
    transparent 58%);
  mix-blend-mode: screen;
  transition: opacity .45s var(--ease-impact);
}
.is-fx-tilting { will-change: transform; }

/* ---------- split : mots insécables, lettres animables ---------- */
.ft-fx-word { display: inline-block; white-space: nowrap; }
.ft-fx-char { display: inline-block; transform-origin: 50% 90%; }

/* ---------- count / scramble : chiffres à chasse fixe (pas de tremblement) ---------- */
[data-fx~="count"],
[data-fx~="scramble"] { font-variant-numeric: tabular-nums; }

/* ---------- marquee ----------
   Sans JS : balayable au doigt (rien n'est perdu). En marche : piste infinie,
   bords fondus. */
[data-fx~="marquee"] {
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
[data-fx~="marquee"]::-webkit-scrollbar { display: none; }
[data-fx~="marquee"].is-running {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, var(--black) 7%, var(--black) 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, var(--black) 7%, var(--black) 93%, transparent);
}
.ft-fx-marquee__track {
  display: flex;
  width: max-content;
  will-change: transform;
}
.ft-fx-marquee__group {
  display: flex;
  flex: none;
  align-items: center;
  white-space: nowrap;
}

/* ---------- Mouvement réduit : plus aucun calque animé ---------- */
@media (prefers-reduced-motion: reduce) {
  .ft-fx-ambient,
  .ft-fx-halo,
  .ft-fx-wave,
  .ft-fx-ripple,
  .ft-fx-glare { display: none !important; }
  .ft-fx-progress__notch { transition: none; }
}

@media print {
  .ft-fx-progress,
  .ft-fx-ambient,
  .ft-fx-halo,
  .ft-fx-wave { display: none; }
}
