/* ======================================================================
   LE FILAREADER EN SCÈNE — page d'accueil
   Gabarit : src/vue-filatag-vitrine.php · script : assets/filatag-vitrine.js

   Une scène sombre, quel que soit le thème du site : le boîtier est un objet
   lumineux, il se lit mieux dans le noir — c'est ainsi qu'on le voit dans un
   atelier. Le violet est la couleur de ce qui touche au FilaReader sur tout le
   site ; le vert ne sert qu'à « terminé », qui est un état.

   Tout ce qui bouge passe par transform et opacity, et s'arrête quand la
   section sort de l'écran (classe .ftshow-dort posée par le script).
   ====================================================================== */

.ftshow {
  position: relative; isolation: isolate; overflow: hidden;
  margin: 44px 0; padding: clamp(22px, 4vw, 46px);
  border-radius: 24px; color: #ecebff;
  background:
    radial-gradient(60% 70% at 72% 42%, rgba(124, 58, 237, .38), transparent 70%),
    radial-gradient(45% 55% at 12% 88%, rgba(37, 99, 235, .26), transparent 70%),
    radial-gradient(35% 40% at 95% 0%, rgba(56, 189, 248, .16), transparent 70%),
    linear-gradient(160deg, #0c0a1d 0%, #151034 52%, #0a1224 100%);
  box-shadow: 0 30px 80px -30px rgba(76, 29, 149, .55), inset 0 0 0 1px rgba(167, 139, 250, .14);
}

/* ---- Le décor : une grille qui glisse, des poussières qui montent ---- */
.ftshow-fond { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.ftshow-grille {
  position: absolute; inset: -44px;
  background-image:
    linear-gradient(rgba(167, 139, 250, .08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(167, 139, 250, .08) 1px, transparent 1px);
  background-size: 44px 44px;
  -webkit-mask-image: radial-gradient(70% 70% at 60% 45%, #000 20%, transparent 75%);
          mask-image: radial-gradient(70% 70% at 60% 45%, #000 20%, transparent 75%);
  animation: ftshow-pan 18s linear infinite;
}
.ftshow-poussiere {
  position: absolute; left: var(--x); top: var(--y);
  width: 4px; height: 4px; border-radius: 50%;
  background: #ddd6fe; box-shadow: 0 0 10px 2px rgba(167, 139, 250, .7);
  opacity: 0; animation: ftshow-flotte var(--t) linear infinite var(--r);
}

/* ---- L'en-tête ---- */
.ftshow-entete { position: relative; text-align: center; max-width: 780px; margin: 0 auto; }
.ftshow-etiquette {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 12px; border-radius: 999px;
  font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: #ddd6fe; background: rgba(124, 58, 237, .22);
  box-shadow: inset 0 0 0 1px rgba(167, 139, 250, .4), 0 0 24px rgba(124, 58, 237, .35);
}
.ftshow-badges { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 0; }
/* « Fonction Premium » dès le premier regard, en or comme le bouton du bas. */
.ftshow-premium {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 12px; border-radius: 999px; text-decoration: none;
  font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: #1c1033; background: linear-gradient(135deg, #fde68a, #f59e0b);
  box-shadow: 0 0 24px rgba(245, 158, 11, .45);
}
.ftshow-premium:hover { box-shadow: 0 0 30px rgba(245, 158, 11, .7); }
.ftshow-premium:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* Le h2 du site porte une barre et s'aligne en flex : ici le titre est centré,
   en dégradé, et la barre se lirait comme un trait parasite. */
.ftshow-titre::before { content: none; }
.ftshow-titre {
  display: block;
  margin: 16px 0 10px; font-size: clamp(26px, 3.7vw, 42px); line-height: 1.12; letter-spacing: -.015em;
  background: linear-gradient(100deg, #ffffff 0%, #ede9fe 35%, #a78bfa 62%, #67e8f9 82%, #ffffff 100%);
  background-size: 220% auto;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: ftshow-lueur 9s linear infinite;
}
.ftshow-chapo { margin: 0 auto; max-width: 62ch; font-size: 16px; line-height: 1.6; color: rgba(236, 235, 255, .74); }

/* La compatibilité, EN GROS ET EN HAUT : demandé le 14 octobre 2026. Une
   machine d'une autre marque ne doit pas découvrir la limite après l'achat
   du boîtier. La coche est verte parce que « compatible » est un état. */
.ftshow-compat {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px 16px;
  margin: 18px auto 4px; max-width: 900px;
}
.ftshow-compat-oui {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 10px 20px; border-radius: 999px;
  font-size: clamp(18px, 2.3vw, 26px); font-weight: 650; color: #fff;
  background: linear-gradient(135deg, rgba(124, 58, 237, .5), rgba(37, 99, 235, .35));
  box-shadow: inset 0 0 0 1px rgba(196, 181, 253, .55), 0 10px 30px -10px rgba(124, 58, 237, .8);
}
.ftshow-compat-oui svg { flex: none; width: 1.05em; height: 1.05em; color: #4ade80; }
.ftshow-compat-oui b, .ftshow-compat-bientot b { font-weight: 800; }
.ftshow-compat-bientot {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 16px; border-radius: 999px;
  font-size: clamp(15px, 1.7vw, 19px); color: #e9e5ff;
  background: rgba(255, 255, 255, .06); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .16);
}
.ftshow-compat-bientot::before {
  content: ''; width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: #a78bfa; box-shadow: 0 0 0 0 rgba(167, 139, 250, .7);
  animation: ftshow-bientot 2.2s ease-out infinite;
}
@keyframes ftshow-bientot {
  0%   { box-shadow: 0 0 0 0 rgba(167, 139, 250, .7); }
  100% { box-shadow: 0 0 0 10px rgba(167, 139, 250, 0); }
}

/* ---- Le corps : la scène à gauche, les mots à droite ---- */
.ftshow-corps {
  position: relative; margin-top: 30px;
  display: grid; grid-template-columns: minmax(0, 1.18fr) minmax(0, 1fr);
  gap: clamp(18px, 3vw, 40px); align-items: center;
}

/* ======================= LA SCÈNE ======================= */
.ftshow-scene {
  position: relative; aspect-ratio: 16 / 11; min-height: 260px;
  container-type: inline-size;
  /* LA GÉOMÉTRIE, EN UNITÉS DE LA SCÈNE (cqw) — redéfinie pour le téléphone.
     Les deux bobines qui bougent sont dessinées hors de l'étagère pour pouvoir
     en sortir ou y entrer. L'ORANGE, celle qu'on monte, part de sa place sur
     le rayon A (3e place). La ROSE, celle qu'on démonte, est d'abord dans
     l'emplacement 2 de l'AMS et finit sur sa place : rayon B, place 7.
     L'étagère descend de 3cqw pour laisser le haut de la scène aux bulles. */
  --ftk-x: 2cqw;  --ftk-y: 13cqw; --ftk-l: 46cqw; --ftk-h: 38cqw;   /* l'étagère */
  --b-l: 6.8cqw;  --b-h: 10cqw;                                     /* une bobine */
  --b-x0: 3.2cqw; --b-pas: 8.2cqw;                                  /* 1re place, pas */
  --ra-y: 5cqw;   --rb-y: 23cqw;                                    /* haut des bobines A et B */
  --fts-repos-x: 21.6cqw; --fts-repos-y: 18cqw;                    /* orange : rayon A, 3e place */
  /* Devant le boîtier, un peu plus grosse : on la tient vers soi — sur la
     bague, à gauche, sans masquer l'écran (ni la ligne des emplacements). */
  --fts-approche: translate(30cqw, 10.5cqw) scale(1.2) rotate(-10deg);
  /* Dans l'emplacement 2 de l'AMS de l'imprimante. */
  --fts-ams: translate(-9.1cqw, 7.5cqw) scale(.31);
  --dem-x: 21.6cqw; --dem-y: 36cqw;                                 /* rose : rayon B, place 7 */
  --dem-ams: translate(-9.1cqw, -10.5cqw) scale(.31);               /* dans l'emplacement 2 */
  --dem-attente: translate(-9cqw, -23.5cqw) scale(1.05);            /* sortie, au-dessus de l'AMS */
  --ondes-x: 51cqw; --ondes-y: 26cqw; --ondes-t: 18cqw;
  --moins-x: 15.9cqw; --moins-y: 21cqw;
  --bulle-y: 7.5cqw;                                                /* pied des bulles */
}
/* La bobine du site, à la taille de la scène : flasques et rouleau en
   proportion plutôt qu'en pixels. `display: block` parce que c'est un <span> :
   inline, il ignorerait largeur et hauteur et tomberait à 0 × 0 (même piège
   que la vitrine, voir style.css). */
.ftshow .bobine-forme { display: block; width: 100%; height: 100%; }
.ftshow .bobine-forme::before, .ftshow .bobine-forme::after { width: 17%; }
.ftshow .bobine-forme i { left: 11%; right: 11%; }

/* ---- LE STOCK : l'étagère d'où l'on prend la bobine ---- */
.ftk {
  position: absolute; z-index: 1; left: var(--ftk-x); top: var(--ftk-y);
  width: var(--ftk-l); height: var(--ftk-h);
  --carte: #2a2541; opacity: 0; transition: opacity .6s ease;
}
.ftk-titre {
  position: absolute; left: 0; top: -4.4cqw; white-space: nowrap;
  font-size: max(11px, 1.9cqw); font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: #c4b5fd;
}
.ftk-montant {
  position: absolute; top: 0; bottom: 0; width: 1.1cqw; border-radius: 3px;
  background: linear-gradient(90deg, #4c4766, #29263d); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .08);
}
.ftk-gauche { left: 0; }
.ftk-droite { right: 0; }
.ftk-planche {
  position: absolute; left: 0; right: 0; height: 1.25cqw; border-radius: 3px;
  background: linear-gradient(#716a90, #3a3553); box-shadow: 0 8px 16px rgba(0, 0, 0, .45);
}
.ftk-planche.ftk-a { top: calc(var(--ra-y) + var(--b-h)); }
.ftk-planche.ftk-b { top: calc(var(--rb-y) + var(--b-h)); }
.ftk-lettre {
  position: absolute; z-index: 3; left: -1.4cqw; display: grid; place-items: center;
  width: 2.8cqw; height: 2.8cqw; min-width: 16px; min-height: 16px; border-radius: 50%;
  font-size: max(10px, 1.6cqw); font-weight: 800; color: #fff;
  background: #7c3aed; box-shadow: 0 0 10px rgba(124, 58, 237, .75);
}
.ftk-lettre.ftk-a { top: calc(var(--ra-y) + var(--b-h) * .5 - 1.4cqw); }
.ftk-lettre.ftk-b { top: calc(var(--rb-y) + var(--b-h) * .5 - 1.4cqw); }
.ftk-bobine, .ftk-place-vide {
  position: absolute; left: calc(var(--b-x0) + var(--i) * var(--b-pas));
  width: var(--b-l); height: var(--b-h);
}
.ftk-a.ftk-bobine, .ftk-a.ftk-place-vide { top: var(--ra-y); }
.ftk-b.ftk-bobine, .ftk-b.ftk-place-vide { top: var(--rb-y); }
/* La place vide se voit dès que la bobine en sort : c'est d'elle qu'on parle. */
.ftk-place-vide { border-radius: 4px; border: 1.5px dashed rgba(196, 181, 253, .45); }
.ftk-numero {
  position: absolute; left: calc(var(--b-x0) + var(--i) * var(--b-pas)); width: var(--b-l);
  top: calc(var(--rb-y) + var(--b-h) + 1.8cqw); text-align: center;
  font-size: max(10px, 1.6cqw); font-variant-numeric: tabular-nums; color: rgba(236, 235, 255, .5);
}
.ftk-numero-pris { color: #ddd6fe; font-weight: 800; }

/* L'imprimante */
.ftp { position: absolute; z-index: 1; left: 1%; bottom: 5%; width: 35%; overflow: visible; transition: opacity .6s; }
.ftp-ams { fill: rgba(255, 255, 255, .06); stroke: rgba(255, 255, 255, .2); stroke-width: 1.5; }
.ftp-bac { stroke: rgba(0, 0, 0, .35); stroke-width: 1; }
.ftp-tube { fill: none; stroke: rgba(255, 255, 255, .22); stroke-width: 2; stroke-dasharray: 3 4; }
.ftp-cadre { stroke: rgba(255, 255, 255, .2); stroke-width: 2; }
.ftp-portique { fill: rgba(255, 255, 255, .18); }
.ftp-tete { fill: #d8d6e8; }
.ftp-tete path { fill: #a78bfa; }
.ftp-piece-ombre { fill: rgba(255, 255, 255, .04); stroke: rgba(255, 255, 255, .14); stroke-dasharray: 3 3; }
.ftp-piece {
  transform-box: fill-box; transform-origin: 50% 100%;
  transform: scaleY(.04); transition: transform .8s cubic-bezier(.2, .8, .2, 1), opacity .5s;
}
.ftp-plateau { fill: rgba(255, 255, 255, .26); }

/* Ce qui circule : la machine parle au boîtier, le tag aussi */
.ftshow-liens { position: absolute; left: 16%; top: 6%; width: 58%; height: 46%; overflow: visible; }
.ftshow-flux {
  fill: none; stroke: #a78bfa; stroke-width: 2; stroke-linecap: round;
  stroke-dasharray: 2 9; vector-effect: non-scaling-stroke; opacity: 0; transition: opacity .5s;
  filter: drop-shadow(0 0 4px rgba(167, 139, 250, .9));
}
.ftshow-ondes {
  position: absolute; z-index: 3; left: var(--ondes-x); top: var(--ondes-y);
  width: var(--ondes-t); height: var(--ondes-t); pointer-events: none;
}
.ftshow-ondes i {
  position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid #a78bfa; box-shadow: 0 0 14px rgba(167, 139, 250, .6), inset 0 0 10px rgba(167, 139, 250, .35);
  opacity: 0;
}

/* ---- LA BOBINE QU'ON TIENT : de profil, et AU-DESSUS du boîtier ----
   Elle sort de sa place sur l'étagère, passe devant le boîtier, puis part
   dans l'AMS. Au premier plan : c'est elle qu'on a dans la main. Hors de la
   première scène elle est DANS l'AMS, donc invisible. */
.fts {
  position: absolute; z-index: 4; left: var(--fts-repos-x); top: var(--fts-repos-y);
  width: var(--b-l); height: var(--b-h); --carte: #2a2541;
  transform-origin: 50% 50%; transform: var(--fts-ams); opacity: 0;
  transition: transform 1.1s cubic-bezier(.2, .8, .2, 1), opacity .5s ease, filter .5s ease;
}
/* ---- LA BOBINE QU'ON DÉMONTE : elle sort de l'emplacement 2, attend
   au-dessus de l'AMS, puis va sur sa place — celle que le FilaReader affiche.
   Posée sur l'étagère, elle suit l'étagère (cachée avec elle, à moitié en
   veille). */
.ftdem {
  position: absolute; z-index: 4; left: var(--dem-x); top: var(--dem-y);
  width: var(--b-l); height: var(--b-h); --carte: #2a2541;
  transform-origin: 50% 50%; opacity: 0;
  transition: transform 1.1s cubic-bezier(.2, .8, .2, 1), opacity .6s ease;
}
/* « C'est celle-là » : un cadre qui bat deux fois autour d'elle, pendant
   qu'elle est encore sur l'étagère. */
.fts::before {
  content: ''; position: absolute; inset: -1cqw; border-radius: 8px; pointer-events: none;
  border: 2px solid #c4b5fd; box-shadow: 0 0 14px rgba(167, 139, 250, .8);
  opacity: 0;
}
/* La pastille du tag, collée sur la joue tournée vers le boîtier. */
.fts-puce {
  position: absolute; z-index: 3; right: -1.4cqw; top: 50%;
  display: grid; place-items: center;
  width: 3cqw; height: 3cqw; min-width: 15px; min-height: 15px; border-radius: 50%;
  transform: translateY(-50%); color: #fff; background: #7c3aed;
  box-shadow: 0 0 0 1.5px #ddd6fe, 0 0 10px rgba(124, 58, 237, .75);
}
.fts-puce svg { width: 70%; height: 70%; }
/* Les grammes qui partent, au-dessus de l'emplacement 2 de l'AMS. */
.ftshow-moins {
  position: absolute; z-index: 4; left: var(--moins-x); top: var(--moins-y); pointer-events: none;
  font-size: max(13px, 3.2cqw); font-weight: 800; color: #fdba74; white-space: nowrap;
  text-shadow: 0 0 12px rgba(249, 140, 54, .7);
  opacity: 0; transform: translate(-50%, 0);
}

/* ---- LES BULLES : ce que fait la personne, au moment où elle le fait ----
   Une bulle de bande dessinée par geste, en haut de la scène, la pointe vers
   ce dont elle parle. Leur pied est fixe (--bulle-y) : un texte plus long
   dans une autre langue la fait grandir vers le haut, pas sur le décor.
   Chaque scène les fait entrer et sortir à son rythme (voir LES SCÈNES). */
.ftbulle {
  position: absolute; z-index: 5; left: var(--bx, 50cqw); top: var(--bulle-y);
  width: max-content; max-width: var(--bmax, 46cqw);
  padding: .5em .95em; border-radius: 1.1em;
  font-size: max(12.5px, 2.4cqw); font-weight: 700; line-height: 1.25; text-align: center;
  color: #1c1033; background: #fff;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .45), 0 0 0 1px rgba(167, 139, 250, .35);
  transform: translate(-50%, -100%) scale(.6); transform-origin: var(--bq, 50%) 100%;
  opacity: 0; pointer-events: none;
}
/* La pointe : un carré tourné, sous le texte et sur le fond de la bulle. */
.ftbulle::after {
  content: ''; position: absolute; z-index: -1; left: var(--bq, 50%); bottom: -.42em;
  width: .9em; height: .9em; border-radius: 0 0 .2em 0;
  background: #fff; transform: translateX(-50%) rotate(45deg);
}
/* Où se met chaque bulle : au-dessus de ce dont elle parle. */
.ftbulle-prise   { --bx: 26cqw; --bmax: 48cqw; }
.ftbulle-devant  { --bx: 47cqw; --bq: 62%; }
.ftbulle-molette, .ftbulle-ranger { --bx: 68cqw; --bmax: 60cqw; }
.ftbulle-ams     { --bx: 22cqw; --bmax: 40cqw; }
.ftbulle-direct, .ftbulle-reel, .ftbulle-veille { --bmax: 70cqw; }

/* ---- Le boîtier ---- */
.ftd {
  --d: 47cqw; z-index: 2;
  position: absolute; right: 2%; top: 50%; width: var(--d); aspect-ratio: 1;
  transform: translateY(-50%);
  filter: drop-shadow(0 26px 40px rgba(0, 0, 0, .55));
}
.ftd > span, .ftd-ecran { position: absolute; border-radius: 50%; }
.ftd-halo {
  inset: -16%;
  background: radial-gradient(circle, rgba(124, 58, 237, .62) 0%, rgba(124, 58, 237, .18) 42%, transparent 66%);
  animation: ftshow-respire 4.5s ease-in-out infinite; transition: opacity .6s;
}
/* La bague crantée qu'on tourne : moletage en dégradé conique, un repère violet. */
.ftd-bague {
  inset: 0;
  background:
    radial-gradient(circle, transparent 60%, rgba(0, 0, 0, .55) 69%, transparent 71%),
    radial-gradient(circle at 30% 22%, rgba(255, 255, 255, .22), transparent 45%),
    repeating-conic-gradient(#3d3c4b 0deg 1.7deg, #1f1e29 1.7deg 3.4deg);
  box-shadow: inset 0 2px 3px rgba(255, 255, 255, .28), inset 0 -4px 8px rgba(0, 0, 0, .65), 0 0 0 1px rgba(0, 0, 0, .6);
}
.ftd-bague::after {
  content: ''; position: absolute; left: 50%; top: 1.6%; width: 1.4%; height: 4.5%;
  border-radius: 4px; transform: translateX(-50%);
  background: #c4b5fd; box-shadow: 0 0 8px #a78bfa;
}
.ftd-corps {
  inset: 6.5%;
  background: radial-gradient(circle at 35% 28%, #2b2a38, #0b0a12 72%);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .04), inset 0 8px 16px rgba(0, 0, 0, .75);
}
.ftd-ecran {
  inset: 11.5%; overflow: hidden;
  background: radial-gradient(circle at 50% 38%, #1b1736, #07060f 76%);
  box-shadow: inset 0 0 0 1px rgba(167, 139, 250, .28), inset 0 0 28px rgba(124, 58, 237, .32);
  font-size: calc(var(--d) * .05); color: #f5f3ff; line-height: 1.15;
}
.ftd-reflet {
  position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: linear-gradient(140deg, rgba(255, 255, 255, .18) 0%, rgba(255, 255, 255, .04) 30%, transparent 44%);
}

/* Une « vue » par scène, empilées ; celle de la scène courante s'allume. */
.ftd-vue {
  position: absolute; inset: 0; padding: 13%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .32em;
  text-align: center; opacity: 0; transform: scale(.92) translateY(5%);
  transition: opacity .45s ease, transform .6s cubic-bezier(.2, .8, .2, 1);
}
.ftshow[data-scene="tag"]    .ftd-vue-tag,
.ftshow[data-scene="bac"]    .ftd-vue-ranger,
.ftshow[data-scene="direct"] .ftd-vue-direct,
.ftshow[data-scene="reel"]   .ftd-vue-reel,
.ftshow[data-scene="veille"] .ftd-vue-veille { opacity: 1; transform: none; }

.ftd-petit { display: inline-flex; align-items: center; gap: .35em; font-size: .78em; color: rgba(236, 235, 255, .72); }
.ftd-petit svg { width: 1.15em; height: 1.15em; }
.ftd-moyen { font-size: 1.2em; font-weight: 600; }
.ftd-grand { font-size: 2.05em; font-weight: 750; letter-spacing: -.01em; line-height: 1; }
.ftd-geant { font-size: 3.2em; font-weight: 800; line-height: .95; font-variant-numeric: tabular-nums; }
.ftd-geant small { font-size: .42em; margin-left: .06em; opacity: .8; }
.ftd-horloge { font-size: 3.3em; font-weight: 300; letter-spacing: .02em; font-variant-numeric: tabular-nums; text-shadow: 0 0 18px rgba(167, 139, 250, .55); }
.ftd-violet { color: #c4b5fd; }
.ftd-ligne-bobine { margin-top: .2em; }

.ftd-pastilles { display: flex; gap: .5em; margin-top: .35em; }
.ftd-pastille {
  display: inline-block; width: .85em; height: .85em; border-radius: 50%; flex: none;
  background: var(--c); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .28);
}
.ftd-pastille.ftd-sert { box-shadow: 0 0 0 2px #fff, 0 0 12px var(--c); }

/* Les bacs, et le curseur que la molette déplace */
.ftd-bacs { position: relative; display: flex; gap: .6em; margin: .45em 0 .3em; }
.ftd-bac {
  position: relative; display: grid; place-items: center;
  width: 1.7em; height: 1.7em; border-radius: 50%; background: var(--c);
  box-shadow: inset 0 -3px 0 rgba(0, 0, 0, .28), inset 0 0 0 1px rgba(255, 255, 255, .22);
}
.ftd-bac em { font-style: normal; font-size: .62em; font-weight: 800; color: #fff; text-shadow: 0 0 3px #000, 0 0 2px #000; }
.ftd-curseur {
  position: absolute; left: -.3em; top: -.3em; width: 2.3em; height: 2.3em; border-radius: 50%;
  border: 2px solid #ddd6fe; box-shadow: 0 0 14px rgba(167, 139, 250, .9);
}

/* L'anneau de progression : il fait le tour de l'écran rond. */
.ftd-anneau { position: absolute; inset: 3%; width: 94%; height: 94%; transform: rotate(-90deg); overflow: visible; }
.ftd-anneau circle { fill: none; stroke-width: 3.6; }
.ftd-anneau-fond { stroke: rgba(255, 255, 255, .08); }
.ftd-anneau-plein {
  stroke: url(#ftd-degrade); stroke-linecap: round;
  stroke-dasharray: 289.03; stroke-dashoffset: 17.34;
  filter: drop-shadow(0 0 3px rgba(167, 139, 250, .95));
}

/* Terminé : la coche verte — c'est un état. */
.ftd-coche {
  display: grid; place-items: center; width: 2.5em; height: 2.5em; border-radius: 50%;
  background: rgba(74, 222, 128, .14); box-shadow: 0 0 0 2px #4ade80, 0 0 20px rgba(74, 222, 128, .5);
}
.ftd-coche svg { width: 62%; height: 62%; }
.ftd-coche path { fill: none; stroke: #4ade80; stroke-width: 2.8; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 24; stroke-dashoffset: 0; }

/* Le bouton pause : une animation qui tourne plus de cinq secondes doit pouvoir s'arrêter. */
.ftshow-pause {
  position: absolute; right: 0; bottom: 0; z-index: 2;
  display: grid; place-items: center; width: 40px; height: 40px; padding: 0;
  border-radius: 50%; border: 1px solid rgba(255, 255, 255, .22); cursor: pointer;
  color: #fff; background: rgba(12, 10, 29, .6);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.ftshow-pause:hover { background: rgba(124, 58, 237, .45); }
.ftshow-pause:focus-visible { outline: 2px solid #ddd6fe; outline-offset: 3px; }
.ftshow-pause svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.ftshow-icone-lecture { display: none; fill: currentColor; stroke: none; }
.ftshow-en-pause .ftshow-icone-pause { display: none; }
.ftshow-en-pause .ftshow-icone-lecture { display: inline; }
.ftshow-sans-js .ftshow-pause { display: none; }

/* ======================= LES MOTS ======================= */
.ftshow-etapes { position: relative; list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.ftshow-bouton {
  position: relative; overflow: hidden; width: 100%;
  display: grid; grid-template-columns: 42px minmax(0, 1fr); gap: 0 14px; align-items: start;
  padding: 13px 16px 15px; border-radius: 16px; cursor: pointer;
  font: inherit; text-align: left; color: inherit;
  background: rgba(255, 255, 255, .035); border: 1px solid rgba(255, 255, 255, .09);
  transition: background .35s, border-color .35s, box-shadow .35s, transform .35s;
}
.ftshow-bouton:hover { background: rgba(255, 255, 255, .065); }
.ftshow-bouton:focus-visible { outline: 2px solid #ddd6fe; outline-offset: 2px; }
.ftshow-bouton[aria-pressed="true"] {
  background: linear-gradient(135deg, rgba(124, 58, 237, .32), rgba(56, 189, 248, .08));
  border-color: rgba(196, 181, 253, .55);
  box-shadow: 0 16px 34px -16px rgba(124, 58, 237, .75);
  transform: translateX(-4px);
}
.ftshow-numero {
  display: grid; place-items: center; width: 42px; height: 42px; border-radius: 12px;
  color: #c4b5fd; background: rgba(167, 139, 250, .12);
  transition: background .35s, color .35s, box-shadow .35s;
}
.ftshow-bouton[aria-pressed="true"] .ftshow-numero { color: #fff; background: #7c3aed; box-shadow: 0 0 22px rgba(124, 58, 237, .8); }
.ftshow-mots { min-width: 0; padding-top: 2px; }
.ftshow-etape-titre { display: block; font-size: 15.5px; font-weight: 650; color: #fff; }
.ftshow-etape-texte {
  display: block; max-height: 0; opacity: 0; overflow: hidden;
  font-size: 13.5px; line-height: 1.55; color: rgba(236, 235, 255, .74);
  transition: max-height .55s ease, opacity .4s ease, margin .4s ease;
}
.ftshow-bouton[aria-pressed="true"] .ftshow-etape-texte { max-height: 9em; opacity: 1; margin-top: 4px; }
/* Sans script, les cinq textes se lisent tous. */
.ftshow-sans-js .ftshow-etape-texte { max-height: none; opacity: 1; margin-top: 4px; }
.ftshow-sans-js .ftshow-bouton { cursor: default; }

/* La barre du temps restant sur l'étape en cours, façon « histoires ». */
.ftshow-barre { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(255, 255, 255, .06); }
.ftshow-barre i { display: block; width: 0; height: 100%; background: linear-gradient(90deg, #7c3aed, #38bdf8); box-shadow: 0 0 8px rgba(124, 58, 237, .8); }
.ftshow-bouton[aria-pressed="true"] .ftshow-barre i { animation: ftshow-barre var(--duree, 6200ms) linear both; }
.ftshow-sans-js .ftshow-barre, .ftshow-en-pause .ftshow-barre { visibility: hidden; }

/* ======================= LE PIED : le vrai boîtier, et l'offre ======================= */
.ftshow-pied {
  position: relative; margin-top: 30px;
  display: grid; gap: 22px 34px; align-items: center; justify-items: center;
}
.ftshow-pied.avec-photo { grid-template-columns: minmax(0, 300px) minmax(0, 1fr); justify-items: stretch; }
/* La photo du vrai boîtier, DÉTOURÉE (fond transparent, 14 octobre 2026) :
   sur la section sombre, un fond blanc aurait fait un carré éclatant. Le
   boîtier flotte donc sur un halo violet, avec son ombre — la même lumière
   que celui de la scène, pour qu'on les reconnaisse l'un dans l'autre. */
.ftshow-photo {
  justify-self: center; width: 100%; max-width: 300px; margin: 0; padding: 14px 14px 12px;
  border-radius: 18px;
  background:
    radial-gradient(closest-side at 50% 46%, rgba(124, 58, 237, .42), rgba(124, 58, 237, 0) 78%),
    rgba(255, 255, 255, .045);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12), 0 22px 44px -20px rgba(0, 0, 0, .75);
}
.ftshow-photo img {
  display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: contain;
  filter: drop-shadow(0 16px 20px rgba(0, 0, 0, .55));
}
.ftshow-photo figcaption { margin-top: 8px; text-align: center; font-size: 12.5px; color: rgba(236, 235, 255, .72); }
.ftshow-offre { text-align: center; }
.ftshow-pied.avec-photo .ftshow-offre { text-align: left; }
.ftshow-offre-texte { display: inline-flex; align-items: center; gap: 9px; margin: 0 0 14px; font-size: 16.5px; color: #f5f3ff; }
.ftshow-offre-texte svg { flex: none; color: #fbbf24; }
/* « Devenez Premium » : l'or de l'offre supérieure, pour trancher sur le violet
   du FilaReader — ni vert ni rouge, qui sont réservés aux états. */
.ftshow-cta {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 13px 28px; border-radius: 999px; text-decoration: none;
  font-size: 17px; font-weight: 800; color: #1c1033;
  background: linear-gradient(135deg, #fde68a 0%, #fbbf24 45%, #f59e0b 100%);
  box-shadow: 0 14px 32px -10px rgba(245, 158, 11, .7), inset 0 1px 0 rgba(255, 255, 255, .6);
  transition: transform .2s ease, box-shadow .2s ease;
}
.ftshow-cta::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 40%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .6), transparent);
  transform: skewX(-20deg); animation: ftshow-reflet 4.5s ease-in-out infinite 1.2s;
}
.ftshow-cta:hover { transform: translateY(-2px); box-shadow: 0 18px 38px -10px rgba(245, 158, 11, .85), inset 0 1px 0 rgba(255, 255, 255, .6); }
.ftshow-cta:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
/* Là où mène le bouton : les tarifs, plus bas sur la même page, sous l'en-tête collant. */
#tarifs { scroll-margin-top: 84px; }
@media (max-width: 760px) { #tarifs { scroll-margin-top: 132px; } }
.ftshow-mention { position: relative; margin: 14px auto 0; max-width: 70ch; font-size: 12.5px; color: rgba(236, 235, 255, .55); }
.ftshow-pied.avec-photo .ftshow-mention { margin-left: 0; }

/* ======================= LES SCÈNES ======================= */

/* L'ORDRE DES GESTES est celui qu'il a donné le 14 octobre 2026, bulle par
   bulle : je prends la bobine, je la passe devant le FilaReader, je tourne la
   molette, je la mets dans l'AMS, le FilaReader me dit où ranger la bobine
   démontée — « surtout montrer la bobine sortante et son emplacement ».
   Les secondes de chaque scène vont avec DUREES, dans le script.

   Qui se voit quand : l'étagère pour prendre et ranger, la machine pour
   charger et imprimer. Les deux partagent la même place. */
.ftshow[data-scene="tag"] .ftk,    .ftshow[data-scene="veille"] .ftk { opacity: 1; }
.ftshow[data-scene="veille"] .ftk  { opacity: .5; }
.ftshow[data-scene="tag"] .ftp,    .ftshow[data-scene="veille"] .ftp { opacity: 0; }

/* 1. JE PRENDS LA BOBINE, JE LA PASSE DEVANT LE FILAREADER — 8,5 s.
     0,4 s  « Je prends la bobine dans mon stock » — un cadre bat autour
            d'elle, sur sa place du rayon A
     2,2 s  elle se soulève ; sa place reste vide, en pointillés
     2,8 s  « Je la passe devant le FilaReader » — elle traverse, lentement (2,7 s)
     5,6 s  elle est devant : la pastille brille, les ondes partent
     5,7 s  l'écran quitte l'heure : « Tag lu », PLA Orange, 742 g */
.ftshow[data-scene="tag"] .fts {
  transform: var(--fts-approche); opacity: 1; filter: drop-shadow(0 18px 22px rgba(0, 0, 0, .6));
  animation: fts-prise 5.6s ease-in-out both;
}
.ftshow[data-scene="tag"] .fts::before { animation: fts-repere .9s ease-in-out .5s 2 both; }
.ftshow[data-scene="tag"] .fts-puce { animation: ftshow-tag 1.3s ease-in-out infinite 5.6s; }
.ftshow[data-scene="tag"] .ftshow-ondes i { animation: ftshow-onde 1.9s ease-out infinite 5.6s; }
.ftshow[data-scene="tag"] .ftshow-ondes i:nth-child(2) { animation-delay: 6.23s; }
.ftshow[data-scene="tag"] .ftshow-ondes i:nth-child(3) { animation-delay: 6.86s; }
.ftshow[data-scene="tag"] .ftd-halo { animation-duration: 1.6s; }
/* L'écran garde l'heure tant que le tag n'est pas lu. */
.ftshow[data-scene="tag"] .ftd-vue-veille { animation: ftd-vue-attend 5.9s both; }
.ftshow[data-scene="tag"] .ftd-vue-tag    { animation: ftd-vue-arrive .5s 5.7s both; }
/* La rose est encore dans l'AMS : elle s'efface où elle est, puis y retourne. */
.ftshow[data-scene="tag"] .ftdem { transform: var(--dem-ams); opacity: 0; transition: opacity .4s ease, transform 0s .4s; }
.ftshow[data-scene="tag"] .ftbulle-prise  { animation: ftbulle-entre .45s .4s both, ftbulle-sort .3s 2.5s forwards; }
.ftshow[data-scene="tag"] .ftbulle-devant { animation: ftbulle-entre .45s 2.8s both; }

/* 2. LA MOLETTE, L'AMS, ET LA BOBINE DÉMONTÉE — 11 s.
     0,3 s  « Je tourne la molette : emplacement 2 de l'AMS » — la bague
            tourne à 0,8 s, le curseur passe du 1 au 2 (rose : ce qui y est)
     2,0 s  l'étagère s'efface, l'imprimante paraît
     2,4 s  « Je la mets dans l'AMS »
     2,6 s  la ROSE sort de l'emplacement 2 et attend au-dessus de l'AMS
     3,0 s  l'orange y entre (1,3 s) : l'emplacement 2 devient orange
     4,8 s  l'écran : « Ranger — Rayon B — Place 7 », PLA Rose
     4,9 s  « Le FilaReader me dit où ranger la bobine démontée »
     5,4 s  l'imprimante s'efface, l'étagère revient ; la place 7 bat
     6,0 s  la rose y va (2 s) et s'y pose — trois secondes pour le voir */
.ftshow[data-scene="bac"] .ftk { opacity: 1; animation: ftk-va-vient 11s linear both; }
.ftshow[data-scene="bac"] .ftp { opacity: 0; animation: ftp-vient-va 11s linear both; }
.ftshow[data-scene="bac"] .ftd-bague { animation: ftshow-cran 6s cubic-bezier(.3, 1.5, .45, 1) both; }
.ftshow[data-scene="bac"] .ftd-curseur { animation: ftshow-curseur 6s cubic-bezier(.3, 1.5, .45, 1) both; }
.ftshow[data-scene="bac"] .ftd-bac:nth-child(2) { animation: ftd-bac-change 4.4s linear both; }
.ftshow[data-scene="bac"] .ftd-vue-bac    { animation: ftd-vue-passe 5s both; }
.ftshow[data-scene="bac"] .ftd-vue-ranger { animation: ftd-vue-arrive .5s 4.8s both; }
.ftshow[data-scene="bac"] .ftp-bac-actif {
  animation: ftp-bac-change 11s linear both, ftshow-bac 1.2s ease-in-out infinite 4.3s;
}
.ftshow[data-scene="bac"] .fts { animation: fts-rangee 4.6s ease-in-out both; }
.ftshow[data-scene="bac"] .ftdem { opacity: 1; animation: ftdem-sortie 11s ease-in-out both; }
.ftshow[data-scene="bac"] .ftk-place-vide.ftk-b { animation: ftk-appel 1.1s ease-in-out 5.8s 2 both; }
.ftshow[data-scene="bac"] .ftbulle-molette { animation: ftbulle-entre .45s .3s both, ftbulle-sort .3s 2.1s forwards; }
.ftshow[data-scene="bac"] .ftbulle-ams     { animation: ftbulle-entre .45s 2.4s both, ftbulle-sort .3s 4.5s forwards; }
.ftshow[data-scene="bac"] .ftbulle-ranger  { animation: ftbulle-entre .45s 4.9s both; }

/* 3. En direct : la tête va et vient, la pièce monte, les données filent, l'anneau se remplit. */
.ftshow[data-scene="direct"] .ftd-anneau-plein { animation: ftshow-progression 4.2s cubic-bezier(.25, .1, .2, 1) both; }
.ftshow[data-scene="direct"] .ftp-tete { animation: ftshow-tete 1.5s ease-in-out infinite; }
.ftshow[data-scene="direct"] .ftp-piece { animation: ftshow-pousse 4.2s cubic-bezier(.25, .1, .2, 1) both; }
.ftshow[data-scene="direct"] .ftp-tube { animation: ftshow-tube .7s linear infinite; }
.ftshow[data-scene="direct"] .ftp-bac-actif { stroke: #fff; stroke-width: 2.2; }
.ftshow[data-scene="direct"] .ftshow-flux { opacity: .95; animation: ftshow-flux 1.3s linear infinite; }
.ftshow[data-scene="direct"] .ftp { filter: drop-shadow(0 0 18px rgba(124, 58, 237, .45)); }
.ftshow[data-scene="direct"] .ftbulle-direct { animation: ftbulle-entre .45s .5s both; }

/* 4. C'est fini : la pièce est là, la coche se trace, la bobine maigrit de 38 g. */
.ftshow[data-scene="reel"] .ftp-piece { transform: scaleY(1); }
.ftshow[data-scene="reel"] .ftd-coche path { animation: ftshow-coche .7s .25s ease-out both; }
.ftshow[data-scene="reel"] .ftshow-moins { animation: ftshow-moins 2.6s .6s ease-out both; }
.ftshow[data-scene="reel"] .ftbulle-reel { animation: ftbulle-entre .45s .5s both; }

/* 5. En veille : l'atelier s'éteint — l'orange est dans l'AMS, la rose sur
   sa place —, le FilaReader garde l'heure. */
.ftshow[data-scene="veille"] .ftdem { opacity: .5; }
.ftshow[data-scene="veille"] .ftp-piece { opacity: 0; }
.ftshow[data-scene="veille"] .ftd-halo { opacity: .55; animation-duration: 7s; }
.ftshow[data-scene="veille"] .ftbulle-veille { animation: ftbulle-entre .45s .5s both; }

/* ---- En pause : plus rien ne tourne en boucle, les changements de scène
   choisis au clic se jouent quand même. Hors écran : tout s'arrête. ---- */
.ftshow-en-pause .ftshow-grille, .ftshow-en-pause .ftshow-poussiere, .ftshow-en-pause .ftd-halo,
.ftshow-en-pause .fts-puce, .ftshow-en-pause .ftshow-ondes i, .ftshow-en-pause .ftshow-cta::after,
.ftshow-en-pause .ftp-tete, .ftshow-en-pause .ftp-tube, .ftshow-en-pause .ftshow-flux,
.ftshow-en-pause .ftp-bac-actif, .ftshow-en-pause .ftshow-titre,
.ftshow-en-pause .ftshow-compat-bientot::before { animation-play-state: paused; }
.ftshow-dort, .ftshow-dort * { animation-play-state: paused !important; }

/* ======================= TÉLÉPHONE ======================= */
@media (max-width: 900px) {
  .ftshow-corps { grid-template-columns: minmax(0, 1fr); }
  .ftshow-scene { max-width: 560px; width: 100%; margin: 0 auto; }
  .ftshow-bouton[aria-pressed="true"] { transform: none; }
}
@media (max-width: 600px) {
  .ftshow { margin: 28px 0; border-radius: 18px; }
  .ftshow-chapo { font-size: 15px; }
  /* La scène se dresse : les bulles en haut, le boîtier, puis l'étagère ou
     la machine en bas. 15cqw de plus qu'avant en hauteur, pour les bulles :
     tout ce qui se place depuis le haut est descendu d'autant. */
  .ftshow-scene {
    aspect-ratio: 5 / 7;
    --ftk-x: 4cqw;  --ftk-y: 95cqw; --ftk-l: 58cqw; --ftk-h: 42cqw;
    --b-l: 8cqw;    --b-h: 12cqw;
    --b-x0: 4cqw;   --b-pas: 10cqw;
    --ra-y: 2cqw;   --rb-y: 20cqw;
    --fts-repos-x: 28cqw; --fts-repos-y: 97cqw;                    /* orange : rayon A, 3e place */
    --fts-approche: translate(-4cqw, -32cqw) scale(1.3) rotate(-10deg);
    --fts-ams: translate(-9.5cqw, -8.8cqw) scale(.35);
    --dem-x: 28cqw; --dem-y: 115cqw;                                  /* rose : rayon B, place 7 */
    --dem-ams: translate(-9.5cqw, -26.8cqw) scale(.35);
    --dem-attente: translate(38cqw, -15cqw) scale(1);                 /* à droite de la machine */
    --ondes-x: 21cqw; --ondes-y: 59cqw; --ondes-t: 24cqw;
    --moins-x: 22.5cqw; --moins-y: 83cqw;
    --bulle-y: 13.5cqw;
  }
  /* Une seule colonne : toutes les bulles au milieu, sur toute la largeur. */
  .ftbulle { --bx: 50cqw; --bq: 50%; --bmax: 94cqw; }
  /* Un boîtier plus grand, et un écran un peu plus gros en proportion : à
     64 % de la largeur, les petites lignes de l'écran tombaient à 7 pixels. */
  .ftd { --d: 70cqw; right: auto; left: 50%; top: 18.75cqw; transform: translateX(-50%); }
  .ftd-ecran { font-size: calc(var(--d) * .056); }
  .ftp { left: 3cqw; bottom: 0; width: 46%; }
  .ftshow-liens { left: 12%; top: 51.8%; width: 34%; height: 17.9%; }
  .ftshow-pied.avec-photo { grid-template-columns: minmax(0, 1fr); justify-items: center; }
  .ftshow-pied.avec-photo .ftshow-offre { text-align: center; }
  .ftshow-pied.avec-photo .ftshow-mention { margin-left: auto; }
  .ftshow-photo { max-width: 240px; }
  .ftshow-numero { width: 38px; height: 38px; }
  .ftshow-bouton { grid-template-columns: 38px minmax(0, 1fr); padding: 12px 14px 14px; }
}

/* Réduire les animations : la scène se pose sans bouger, et rien ne défile seul. */
@media (prefers-reduced-motion: reduce) {
  .ftshow *, .ftshow *::before, .ftshow *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    animation-delay: 0s !important; transition-duration: .001ms !important;
  }
  .ftshow-grille, .ftshow-poussiere { display: none; }
  .ftshow-titre { background-position: 0 center; }
}

/* ======================= LES MOUVEMENTS ======================= */
@keyframes ftshow-pan { to { background-position: 44px 44px; } }
@keyframes ftshow-flotte {
  0%   { transform: translateY(0) scale(var(--s)); opacity: 0; }
  15%  { opacity: .85; }
  80%  { opacity: .5; }
  100% { transform: translateY(-140px) scale(var(--s)); opacity: 0; }
}
@keyframes ftshow-lueur { to { background-position: 220% center; } }
@keyframes ftshow-respire { 0%, 100% { opacity: .6; transform: scale(.97); } 50% { opacity: 1; transform: scale(1.04); } }
@keyframes ftshow-tourne { to { transform: rotate(360deg); } }
@keyframes ftshow-onde {
  0%   { transform: scale(.2); opacity: 0; }
  15%  { opacity: .95; }
  100% { transform: scale(1.75); opacity: 0; }
}
@keyframes ftshow-tag {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(167, 139, 250, 0)); }
  50%      { filter: drop-shadow(0 0 7px rgba(196, 181, 253, 1)); }
}
@keyframes ftshow-cran     { 0%, 14% { transform: rotate(0); }     28%, 100% { transform: rotate(-24deg); } }
@keyframes ftshow-curseur  { 0%, 14% { transform: translateX(0); } 28%, 100% { transform: translateX(2.3em); } }
/* La bobine qu'on prend : posée, soulevée de sa place, portée devant le boîtier.
   Les trois étapes écrivent les mêmes fonctions dans le même ordre, pour que
   le navigateur les fasse glisser l'une vers l'autre sans détour. */
@keyframes fts-prise {
  0%, 39% { transform: translate(0, 0) scale(1) rotate(0deg); }
  52%     { transform: translate(0, -4cqw) scale(1.06) rotate(-3deg); }
  100%    { transform: var(--fts-approche); }
}
/* Elle reste devant le boîtier le temps qu'on tourne la molette et que la
   rose sorte, puis entre dans l'AMS (3,0 → 4,3 s) et s'y fond. */
@keyframes fts-rangee {
  0%, 65% { transform: var(--fts-approche); opacity: 1; }
  93.5%   { transform: var(--fts-ams); opacity: 1; }
  100%    { transform: var(--fts-ams); opacity: 0; }
}
/* La rose, sur 11 s : dans l'emplacement 2, elle en sort (2,6 s), attend
   au-dessus de l'AMS, puis va sur sa place (6,0 → 8,0 s). */
@keyframes ftdem-sortie {
  0%, 22.7% { transform: var(--dem-ams); opacity: 0; }
  23.6%     { transform: var(--dem-ams); opacity: 1; }
  29.1%     { transform: var(--dem-attente); opacity: 1; }
  54.5%     { transform: var(--dem-attente); }
  72.7%     { transform: translate(0, 0) scale(1); }
  100%      { transform: translate(0, 0) scale(1); opacity: 1; }
}
/* L'étagère et la machine se passent la place deux fois dans la scène 2 :
   l'étagère jusqu'à 2 s, la machine de 2,6 à 5,4 s, l'étagère dès 6 s. */
@keyframes ftk-va-vient {
  0%, 18.2%   { opacity: 1; }
  23.6%, 49.1% { opacity: 0; }
  54.5%, 100% { opacity: 1; }
}
@keyframes ftp-vient-va {
  0%, 18.2%   { opacity: 0; }
  23.6%, 49.1% { opacity: 1; }
  54.5%, 100% { opacity: 0; }
}
/* L'emplacement 2 de l'AMS : rose, vide quand elle sort, orange quand l'autre entre. */
@keyframes ftp-bac-change {
  0%, 23%    { fill: #ec407a; }
  24%, 38.5% { fill: rgba(255, 255, 255, .08); }
  39.5%, 100% { fill: #F98C36; }
}
/* Sur l'écran du FilaReader, la pastille de l'emplacement 2 suit. */
@keyframes ftd-bac-change {
  0%, 97% { background: #ec407a; }
  100%    { background: #F98C36; }
}
/* La place où ranger la rose : elle bat jusqu'à ce que la bobine s'y pose. */
@keyframes ftk-appel {
  0%, 100% { border-color: rgba(196, 181, 253, .45); box-shadow: 0 0 0 0 rgba(167, 139, 250, 0); }
  50%      { border-color: #ddd6fe; box-shadow: 0 0 0 .6cqw rgba(167, 139, 250, .3), 0 0 18px rgba(167, 139, 250, .9); }
}
/* Une vue d'écran qui paraît, reste, puis laisse la place (5 s). */
@keyframes ftd-vue-passe {
  0%        { opacity: 0; transform: scale(.92) translateY(5%); }
  9%, 91%   { opacity: 1; transform: none; }
  100%      { opacity: 0; transform: scale(.92) translateY(5%); }
}
@keyframes fts-repere {
  0%   { opacity: 0; transform: scale(1.25); }
  50%  { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1); }
}
@keyframes ftd-vue-attend {
  0%, 94% { opacity: 1; transform: none; }
  100%    { opacity: 0; transform: scale(.92) translateY(5%); }
}
@keyframes ftd-vue-arrive {
  from { opacity: 0; transform: scale(.92) translateY(5%); }
  to   { opacity: 1; transform: none; }
}
@keyframes ftbulle-entre {
  0%   { opacity: 0; transform: translate(-50%, -100%) scale(.6); }
  60%  { opacity: 1; transform: translate(-50%, -100%) scale(1.05); }
  100% { opacity: 1; transform: translate(-50%, -100%) scale(1); }
}
@keyframes ftbulle-sort {
  from { opacity: 1; transform: translate(-50%, -100%) scale(1); }
  to   { opacity: 0; transform: translate(-50%, -106%) scale(.94); }
}
@keyframes ftshow-bac      { 0%, 100% { stroke: rgba(0, 0, 0, .35); stroke-width: 1; } 50% { stroke: #fff; stroke-width: 2.6; } }
@keyframes ftshow-progression { from { stroke-dashoffset: 289.03; } to { stroke-dashoffset: 17.34; } }
@keyframes ftshow-tete     { 0%, 100% { transform: translateX(-42px); } 50% { transform: translateX(42px); } }
@keyframes ftshow-pousse   { from { transform: scaleY(.04); } to { transform: scaleY(.94); } }
@keyframes ftshow-tube     { to { stroke-dashoffset: -14; } }
@keyframes ftshow-flux     { to { stroke-dashoffset: -110; } }
@keyframes ftshow-coche    { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
@keyframes ftshow-moins {
  0%   { opacity: 0; transform: translate(-50%, 10%); }
  18%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -90%); }
}
@keyframes ftshow-barre    { from { width: 0; } to { width: 100%; } }
@keyframes ftshow-reflet   { 0%, 62% { left: -60%; } 100% { left: 130%; } }
