/* landing-claire-mouvement.css : tout ce qui bouge sur la landing claire.

   DEUX VERROUS, ET ILS SONT VOULUS.
   1. Tout est sous `prefers-reduced-motion: no-preference`. Quelqu'un qui
      demande moins d'animations veut lire, pas regarder.
   2. Les états de départ cachés (opacité nulle) n'existent que sous des
      classes posées par le script : `.anime` sur <html>, `.a-venir` sur les
      blocs. Sans script, ou si le script casse, rien n'est caché. Une page
      qui reste invisible parce qu'une animation n'est jamais partie est la
      pire panne possible ici, et elle ne se voit dans aucun journal. */

@media (prefers-reduced-motion: no-preference) {

    /* ===== Le titre monte mot par mot ===== */
    .anime .hero h1:not(.par-mots) { opacity: 0; animation: none; }
    .hero h1.par-mots { animation: none; }

    /* Le masque coupe le mot tant qu'il n'est pas monté. Le remplissage du
       bas, repris en marge négative, laisse la place aux jambages : sans
       lui le « p » de « pour » est rogné. */
    .mot-masque {
        display: inline-block;
        overflow: hidden;
        vertical-align: bottom;
        padding-bottom: 0.14em;
        margin-bottom: -0.14em;
    }

    .mot-dedans {
        display: inline-block;
        animation: lever 1s var(--detente) backwards;
        animation-delay: calc(var(--i) * 70ms);
    }

    @keyframes lever { from { transform: translateY(115%); } }

    /* ===== Les halos dérivent lentement =====
       Un fond immobile est une image ; celui-ci respire. Seul `transform`
       bouge, donc le flou n'est calculé qu'une fois. */
    .scene::before, .ia-panneau::before, .fin::before, .hero--page::before, .fondateurs::before {
        animation: deriver 16s ease-in-out infinite alternate;
    }
    .ia-panneau::before { animation-duration: 22s; }
    .fin::before { animation-duration: 19s; }

    @keyframes deriver {
        from { transform: translate(-2%, 1.5%) scale(1); }
        to { transform: translate(2.5%, -2%) scale(1.08); }
    }

    /* ===== La fenêtre du produit se remplit dans l'ordre réel =====
       La phrase, puis l'ordre de grandeur attendu, puis la réponse, pendant
       que les tuiles se posent. C'est le produit raconté en trois secondes. */
    .anime .fenetre:not(.joue) :is(.bulle-moi, .bulle-pense, .bulle-ia, .tuile) { opacity: 0; }

    .joue .bulle-moi {
        transform-origin: 100% 100%;
        animation: surgir 0.6s var(--detente) 0.5s backwards;
    }
    .joue .bulle-pense { animation: monter 0.7s var(--detente) 1.2s backwards; }
    .joue .bulle-ia { animation: monter 0.7s var(--detente) 2s backwards; }

    .joue .tuile {
        animation: surgir 0.7s var(--detente) backwards;
        animation-delay: calc(0.8s + var(--i) * 110ms);
    }
    .tuile:nth-child(1) { --i: 0; }
    .tuile:nth-child(2) { --i: 1; }
    .tuile:nth-child(3) { --i: 2; }
    .tuile:nth-child(4) { --i: 3; }
    .tuile:nth-child(5) { --i: 4; }
    .tuile:nth-child(6) { --i: 5; }

    @keyframes surgir { from { opacity: 0; transform: scale(0.86); } }
    @keyframes monter { from { opacity: 0; transform: translateY(1.75rem); } }

    /* La courbe se découvre par un cache qui recule, et non par un trait en
       pointillé qu'on déroule : avec `non-scaling-stroke`, la longueur d'un
       pointillé se compte en pixels d'écran et le tracé s'arrête en route. */
    .joue .tuile-courbe { animation: decouvrir 1.5s var(--detente) 1.3s backwards; }
    @keyframes decouvrir { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0); } }

    .joue .tuile-barres i {
        transform-origin: 50% 100%;
        animation: pousser 0.8s var(--detente) backwards;
    }
    .tuile-barres i:nth-child(1) { animation-delay: 1.4s; }
    .tuile-barres i:nth-child(2) { animation-delay: 1.47s; }
    .tuile-barres i:nth-child(3) { animation-delay: 1.54s; }
    .tuile-barres i:nth-child(4) { animation-delay: 1.61s; }
    .tuile-barres i:nth-child(5) { animation-delay: 1.68s; }
    .tuile-barres i:nth-child(6) { animation-delay: 1.75s; }
    @keyframes pousser { from { transform: scaleY(0); } }

    .joue .tuile-anneau .part { animation: tourner 1.4s var(--detente) 1.5s backwards; }
    @keyframes tourner { from { stroke-dasharray: 0 100; } }

    .joue .tuile-jauge i {
        transform-origin: 0 50%;
        animation: remplir 1.2s var(--detente) 1.9s backwards;
    }
    @keyframes remplir { from { transform: scaleX(0); } }

    /* ===== Les blocs se posent en entrant dans l'écran =====
       En animation et pas en transition : une transition resterait attachée
       à `transform` et retarderait ensuite le survol des cartes. L'image clé
       n'a qu'un départ, donc une fois jouée elle ne retient plus rien. */
    .a-venir { opacity: 0; }

    .a-venir.vu {
        opacity: 1;
        animation: monter 0.9s var(--detente) backwards;
        animation-delay: calc(var(--i, 0) * 90ms);
    }

    /* Le trait de chaque étape se tire de gauche à droite après elle. */
    .etape.a-venir::before { transform: scaleX(0); }
    .etape.vu::before {
        transform: none;
        transition: transform 1.2s var(--detente) calc(var(--i, 0) * 90ms + 0.25s);
    }

    /* ===== Les cartes d'app répondent au pointeur ===== */
    .app-marque { transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); }
    .app:hover .app-marque { transform: scale(1.1) rotate(-6deg); }

    .bouton--plein:hover, .bouton--creme:hover { transform: translateY(-2px); }

    /* ===== Le panneau de l'IA s'ouvre au défilement ===== */
    @supports (animation-timeline: view()) {
        .ia-panneau {
            animation: grandir linear both;
            animation-timeline: view();
            animation-range: entry 0% cover 35%;
        }
    }

    /* ===== Les sources défilent en bande continue =====
       `--pas` est la largeur d'un jeu de pastilles, mesurée par le script qui
       les a recopiées : la bande avance d'un jeu exactement puis recommence,
       donc la reprise ne se voit pas. */
    .ia-bande.defile {
        overflow: hidden;
        -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
        mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
    }

    .defile .ia-sources {
        flex-wrap: nowrap;
        width: max-content;
        animation: defiler 26s linear infinite;
    }
    .defile .ia-sources li { flex: none; white-space: nowrap; }

    @keyframes defiler { to { transform: translateX(calc(-1 * var(--pas))); } }

    /* ===== Le mot du fondateur s'encre en défilant ===== */
    .par-mots .w { color: rgba(26, 23, 18, 0.2); transition: color 0.4s ease; }
    .par-mots .w.lu { color: inherit; }

    /* =====================================================================
       LE MOUVEMENT DE FOND : ce qui bouge sans qu'on touche à rien.

       Tout ce qui flotte passe par `translate` et `rotate`, les propriétés
       séparées, et jamais par `transform`. Une animation sur `transform`
       écrase le `transform` du survol et celui de l'entrée : la carte ne
       répondrait plus au pointeur tant que son icône respire.
       ===================================================================== */

    /* ----- Les icônes des apps flottent autour de la fenêtre ----- */
    /* 1250 ET NON 1400. Les icônes débordent de 6 rem de chaque côté de la
       fenêtre : il leur faut 82 rem. À 1400 px elles disparaissaient sur
       tous les portables, alors que le rem y vaut maintenant 14 px et que
       82 rem font 1148 px. */
    @media (min-width: 1250px) {
        .flotte {
            position: absolute;
            z-index: 2;
            display: block;
            width: 4rem;
            height: 4rem;
            border-radius: 24%;
            box-shadow: 0 1.25rem 2rem -0.75rem rgba(26, 23, 18, 0.35);
            animation:
                surgir 0.8s var(--detente) backwards,
                flotter 7s ease-in-out infinite alternate;
        }
        /* Quatre places, quatre rythmes : des durées égales les feraient
           monter et descendre ensemble, comme un seul objet. */
        .flotte--1 { left: -5.5rem; top: 14%; rotate: -8deg; animation-delay: 1.5s, 0s; }
        .flotte--2 { right: -6rem; top: 4%; width: 3.25rem; height: 3.25rem; rotate: 7deg; animation-delay: 1.7s, -2s; animation-duration: 0.8s, 8.5s; }
        .flotte--3 { left: -4rem; bottom: 12%; width: 3.25rem; height: 3.25rem; rotate: 6deg; animation-delay: 1.9s, -4s; animation-duration: 0.8s, 9.5s; }
        .flotte--4 { right: -5rem; bottom: 20%; rotate: -6deg; animation-delay: 2.1s, -1s; animation-duration: 0.8s, 6.5s; }
    }

    @keyframes flotter {
        from { translate: 0 0.6rem; }
        to { translate: 0 -0.8rem; }
    }

    /* ----- Le dernier relevé de la courbe bat, comme une mesure en cours ----- */
    .joue .tuile-point {
        position: absolute;
        right: -0.2rem;
        top: calc(20.6% - 0.2rem);
        display: block;
        width: 0.4rem;
        height: 0.4rem;
        border-radius: 50%;
        background: var(--vert);
        animation: surgir 0.4s var(--detente) 2.7s backwards;
    }
    .joue .tuile-point::after {
        content: '';
        position: absolute;
        inset: 0;
        border-radius: 50%;
        background: var(--vert);
        animation: battre 2.2s ease-out 2.9s infinite;
    }
    @keyframes battre {
        from { transform: scale(1); opacity: 0.6; }
        to { transform: scale(4.5); opacity: 0; }
    }

    /* Les barres respirent une fois posées. Deux animations sur la même
       propriété : la seconde ne prend la main qu'après son retard, quand la
       première a fini de les faire pousser. */
    .joue .tuile-barres i {
        animation:
            pousser 0.8s var(--detente) backwards,
            respirer 3.2s ease-in-out infinite alternate;
    }
    .joue .tuile-barres i:nth-child(1) { animation-delay: 1.4s, 2.6s; }
    .joue .tuile-barres i:nth-child(2) { animation-delay: 1.47s, 3s; }
    .joue .tuile-barres i:nth-child(3) { animation-delay: 1.54s, 3.4s; }
    .joue .tuile-barres i:nth-child(4) { animation-delay: 1.61s, 3.8s; }
    .joue .tuile-barres i:nth-child(5) { animation-delay: 1.68s, 4.2s; }
    .joue .tuile-barres i:nth-child(6) { animation-delay: 1.75s, 4.6s; }
    @keyframes respirer { to { transform: scaleY(0.82); } }

    /* Un reflet traverse la jauge d'avancement, de temps en temps. */
    .tuile-jauge i { position: relative; overflow: hidden; }
    .joue .tuile-jauge i::after {
        content: '';
        position: absolute;
        inset: 0;
        background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6), transparent);
        animation: glisser 3.6s ease-in-out 3.4s infinite backwards;
    }
    @keyframes glisser {
        from { transform: translateX(-100%); }
        45%, to { transform: translateX(100%); }
    }

    /* ----- La barre du chat s'écrit toute seule (texte posé par le script) ----- */
    .fil-barre.ecrit { color: var(--encre); }
    .fil-barre.ecrit .fil-saisie::after {
        content: '';
        display: inline-block;
        width: 1.5px;
        height: 1.05em;
        margin-left: 2px;
        vertical-align: -0.15em;
        background: var(--encre);
        animation: clignoter 1s steps(1) infinite;
    }
    @keyframes clignoter { 50% { opacity: 0; } }

    /* ----- Les deux boutons d'appel émettent une onde ----- */
    .hero .bouton--plein { animation: onde-encre 3s ease-out 2.5s infinite; }
    .bouton--creme { animation: onde-creme 3s ease-out infinite; }
    /* `.a-venir.vu` pose l'animation d'entrée sur ce bouton et effacerait
       l'onde : on les déclare ensemble, l'entrée d'abord. */
    .bouton--creme.a-venir.vu {
        animation: monter 0.9s var(--detente) backwards, onde-creme 3s ease-out 1s infinite;
    }
    @keyframes onde-encre {
        from { box-shadow: 0 0 0 0 rgba(26, 23, 18, 0.28); }
        60%, to { box-shadow: 0 0 0 0.9rem rgba(26, 23, 18, 0); }
    }
    @keyframes onde-creme {
        from { box-shadow: 0 0 0 0 rgba(247, 242, 233, 0.4); }
        60%, to { box-shadow: 0 0 0 1rem rgba(247, 242, 233, 0); }
    }

    /* ----- Les cartes d'app : l'icône respire, le reflet se promène ----- */
    .app-marque { animation: flotter-peu 4.5s ease-in-out infinite alternate; }
    .app:nth-child(2) .app-marque { animation-delay: -1.2s; }
    .app:nth-child(3) .app-marque { animation-delay: -2.4s; }
    .app:nth-child(4) .app-marque { animation-delay: -3.6s; }
    @keyframes flotter-peu { to { translate: 0 -0.4rem; } }

    .app::after { animation: errer 13s ease-in-out infinite alternate; }
    .app:nth-child(even)::after { animation-duration: 17s; }
    @keyframes errer { to { translate: -9rem 7rem; } }

    /* ----- Une lueur traverse le titre de l'IA -----
       Le vert et le bleu sont ceux du thème sombre du produit. */
    .ia-titre {
        background: linear-gradient(100deg, var(--creme) 0 40%, #9ac8a4 47%, #8fb8d9 53%, var(--creme) 60% 100%);
        background-size: 260% 100%;
        background-position: 100% 0;
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        /* Le remplissage : en découpe de texte, les jambages et l'accent du
           « é » sortent de la boîte et seraient coupés. */
        padding: 0.08em 0 0.12em;
        animation: luire 7s ease-in-out infinite;
    }
    .ia-titre.a-venir.vu {
        animation: monter 0.9s var(--detente) backwards, luire 7s ease-in-out 1s infinite;
    }
    @keyframes luire {
        from { background-position: 100% 0; }
        55%, to { background-position: 0% 0; }
    }
}
