/* ================================================================
   MOTRO FRANCE — parcours.css
   Le parcours client en motion design.

   1. Le hero de motro.fr, a l'echelle   2. La plaque se tape
   3. Le clic sur le bouton jaune        4. Le toast du site
   5. Le clic -> Gmail, le devis, paye   6. La reception du moteur
   7. L'avis ecrit, puis 5 etoiles

   ────────────────────────────────────────────────────────────────
   FIDELITE AU REEL

   Le hero n'est pas redessine : la voiture est un RENDU du
   visualiseur 3D du site, la plaque, le bouton et le toast sont
   les composants du site avec leurs valeurs exactes (voir TEMPS 1).

   Le mail n'est pas invente : il reprend le modele `tpl_devis` du
   CRM (crm/js/logic.js), expediteur compris.

     objet : « Votre devis moteur {code_moteur} »
     corps : « Bonjour {prenom_client}, Suite a votre demande,
              veuillez trouver ci-joint votre devis pour le moteur
              {code_moteur}, au tarif de {prix_devis}. Pour passer
              au paiement de votre moteur veuillez cliquer ici.
              Ce devis est valable 7 jours. [...] L'equipe Motro »
     de     : contact@motro.fr

   Les variables sont substituees avec des valeurs plausibles
   (Julien, N47D20C, 2 178 € TTC), exactement comme le fait le CRM.

   ────────────────────────────────────────────────────────────────
   POURQUOI ELLE A LE DROIT D'EXISTER

   Le portail : combien de fois par jour ? Une, a la premiere
   visite. Et son but est EXPLICATIF — montrer un parcours de
   commande qu'un paragraphe raconte mal. C'est l'un des rares
   usages ou une duree longue est legitime.

   Deux garde-fous : en pause hors ecran, et rien ne joue du tout
   en mouvement reduit.

   ────────────────────────────────────────────────────────────────
   TECHNIQUE

   Une timeline maitre unique de 20s. Chaque element s'anime sur
   CETTE meme timeline avec ses propres plateaux en pourcentage :
   il n'y a pas huit horloges a recaler, il n'y en a qu'une.

   Animations CSS, pas JS : elles tournent hors du thread principal
   et ne saccadent pas pendant que la page charge ses images.
   transform et opacity — plus la largeur pour la frappe.

   Banc : _interne/bancs/banc-parcours-hero.js (styles compares au
   vrai hero, curseur sur sa cible a chaque clic, frappe lettre a
   lettre).
   ================================================================ */

.pj-stage {
    --pj: 20s;
    /* Echelle COMMUNE de la plaque et du bouton : ils sont construits a
       leur taille reelle (155 x 46 px, padding 12/20 px...) puis reduits
       ensemble, pour garder exactement leurs proportions du site. */
    --pj-k: 0.75;
    position: relative;
    width: 100%;
    height: 470px;
    border-radius: 20px;
    background: linear-gradient(180deg, #f7f7f9 0%, #ededf1 100%);
    overflow: hidden;
    isolation: isolate;
    font-family: var(--font-corps);
}

/* ────────────────────────────────────────────────────────────────
   L'ETAT AU REPOS
   motion.js ajoute .is-playing a l'entree dans le viewport. Tant
   qu'il n'est pas la on ne met pas les animations en pause : figees
   a 0%, elles laisseraient tout a opacity 0 et la scene serait un
   rectangle vide si le JS ne s'executait jamais. On les coupe, et
   on ecrit un etat lisible : le hero, plaque saisie.
   ⚠ `*` n'atteint pas les pseudo-elements : ::before et ::after
   sont coupes a part.
   ──────────────────────────────────────────────────────────────── */
.pj-stage:not(.is-playing) *,
.pj-stage:not(.is-playing) *::before,
.pj-stage:not(.is-playing) *::after { animation: none !important; }
.pj-stage:not(.is-playing) .pj-site  { opacity: 1; transform: none; }
.pj-stage:not(.is-playing) .pj-plaque-texte { width: 9ch; }
.pj-stage:not(.is-playing) .pj-plaque-indice,
.pj-stage:not(.is-playing) .pj-caret,
.pj-stage:not(.is-playing) .pj-toast,
.pj-stage:not(.is-playing) .pj-gmail,
.pj-stage:not(.is-playing) .pj-paid,
.pj-stage:not(.is-playing) .pj-engine,
.pj-stage:not(.is-playing) .pj-review,
.pj-stage:not(.is-playing) .pj-cursor,
.pj-stage:not(.is-playing) .pj-tap { opacity: 0; }


/* ================================================================
   TEMPS 1 — LE HERO DE MOTRO.FR, A L'ECHELLE
   ================================================================
   Le visiteur doit reconnaitre la page qu'il vient de quitter, pas
   une interface « inspiree » d'elle.

   - La voiture est un RENDU du visualiseur 3D du site (js/clio3d.js,
     vue de face, palette blanc nacre), detoure, en WebP : la meme
     voiture au pixel pres, sans second contexte WebGL ni 1,9 Mo de
     modele 3D a charger pour une scene decorative. A refaire si le
     rendu de la voiture du hero change.
   - La plaque, le bouton, les onglets et le toast sont construits a
     leur TAILLE REELLE avec les valeurs de css/style.css recopiees
     telles quelles (§9 plaque, §11 bouton, §14 onglets, §18 toast),
     puis reduits d'un seul transform: scale(). Aucune valeur « a
     l'oeil » : le banc compare les styles calcules du mockup a ceux
     du vrai hero et rougit au premier ecart.
   - Geometrie FIXE en px, centree : plaque et bouton tombent au meme
     endroit quelle que soit la largeur de la colonne. C'est ce qui
     permet au curseur de les viser juste a toutes les tailles.
   ================================================================ */

.pj-site {
    position: absolute;
    left: 5%; right: 5%; top: 18px;
    border-radius: 16px;
    background: #fff;
    box-shadow: var(--elev-3, 0 14px 40px rgba(17,17,17,0.10));
    overflow: hidden;
    /* L'en-tete s'adapte a la largeur de la CARTE (requetes de
       conteneur), pas a celle de l'ecran : c'est elle qui deborde. */
    container-type: inline-size;
    transform-origin: 50% 30%;
    animation: pjSite var(--pj) var(--ease-out) infinite both;
}

/* L'en-tete du site en haut de page, avant defilement. */
.pj-site-nav {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    height: 36px;
    padding: 0 14px;
    border-bottom: 1px solid rgba(17,17,17,0.07);
}
/* Le vrai logo (images/logos/motro-logo.svg), deja en cache : c'est
   celui de l'en-tete, il se dessine donc avec la meme police. */
.pj-logo { display: block; flex: none; height: 17px; width: auto; }
.pj-liens { display: flex; gap: 11px; margin: 0 auto; }
.pj-liens i {
    font-style: normal;
    font-size: 8.5px;
    font-weight: 500;
    color: var(--c-noir);
    white-space: nowrap;
}
.pj-tel {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex: none;
    padding: 4px 9px;
    border-radius: 999px;
    background: var(--c-noir);
    color: #fff;
    font-size: 8.5px;
    font-weight: 700;
    white-space: nowrap;
}
.pj-tel svg { width: 8px; height: 8px; }
/* En-tete du site sur telephone : burger a gauche, logo au centre. */
.pj-burger { display: none; flex-direction: column; gap: 3px; }
.pj-burger i { display: block; width: 13px; height: 1.5px; border-radius: 1px; background: var(--c-noir); }

@container (max-width: 440px) {
    .pj-liens i:nth-child(2) { display: none; }   /* « Suivre ma commande » */
}
@container (max-width: 380px) {
    .pj-liens, .pj-tel { display: none; }
    .pj-burger { display: flex; }
    .pj-logo   { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
}

.pj-hero { padding: 12px 12px 12px; text-align: center; }

/* Le titre du hero (css/prime.css) : 800, interligne 0,98, -0,035em,
   « au bon prix. » en jaune sombre. */
.pj-h1 {
    margin: 0 0 6px;
    font-size: 25px;
    font-weight: 800;
    line-height: 0.98;
    letter-spacing: -0.035em;
    color: var(--c-noir);
}
.pj-h1 span { display: block; color: var(--c-jaune-sombre); }

/* Le sous-titre du hero (css/prime.css) : 400, interligne 1,55, 46ch. */
.pj-sous-titre {
    max-width: 46ch;
    margin: 0 auto 4px;
    font-size: 10px;
    font-weight: 400;
    line-height: 1.55;
    color: #55555b;
}

/* La scene : voiture, plaque, bouton, onglets. Hauteur fixe, enfants
   en absolu : tout est cote en px depuis son bord haut. */
.pj-scene { position: relative; height: 268px; margin-top: 2px; }

.pj-clio {
    position: absolute;
    left: 50%; top: 0;
    width: 236px; height: auto;
    transform: translateX(-50%);
}


/* ================================================================
   TEMPS 2 — LA PLAQUE SE TAPE
   ================================================================
   La plaque SIV du hero (css/style.css §9), a sa taille reelle :
   155 px (PLATE_MIN_PX de hero.js) sur 46. Elle est posee comme
   hero.js pose la vraie : son haut a 0,802 de la hauteur de la
   voiture (haut de la plaque du modele 3D, moins 7 % de sa largeur).

   La frappe reproduit le vrai champ : il ne garde que lettres et
   chiffres et intercale lui-meme les espaces — taper « AB-123-CD »
   affiche A, AB, AB 1, AB 12, AB 123, AB 123 C, AB 123 CD. Sept
   touches, neuf caracteres : la largeur avance par 1 ou 2 ch.
   ================================================================ */

.pj-plaque {
    position: absolute;
    left: 50%; top: 150px;
    width: 155px; height: 46px;
    transform: translateX(-50%) scale(var(--pj-k));
    transform-origin: 50% 0;
    display: flex;
    align-items: stretch;
    border-radius: 5px;
    overflow: hidden;
    border: 2.5px solid var(--c-noir);
    box-shadow:
        0 6px 24px rgba(0,0,0,0.40),
        0 2px 8px rgba(0,0,0,0.25),
        0 0 0 1.5px rgba(0,0,0,0.15);
    font-family: var(--font-mono);
}

.pj-plaque-ue {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #003399;
    color: #FFCC00;
    padding: 3px 7px;
    flex-shrink: 0;
    gap: 1px;
    min-width: 24px;
}
.pj-plaque-ue i { font-style: normal; font-size: 7px; line-height: 1; }
.pj-plaque-ue b { font-size: 11px; font-weight: 800; line-height: 1; }

/* Le champ. Au clic il prend le fond de :focus (#FFD700) et l'anneau
   de :focus-visible du site (css/motion.css §6) — un champ texte le
   recoit aussi a la souris. */
.pj-plaque-champ {
    position: relative;
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 2px;
    background: #FFCC00;
    outline: 2px solid transparent;
    outline-offset: 2px;
    animation: pjChamp var(--pj) steps(1, end) infinite both;
}
.pj-plaque-indice {
    position: absolute;
    left: 0; right: 0; top: 50%;
    transform: translateY(-50%);
    text-align: center;
    white-space: nowrap;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 1.5px;
    color: rgba(17,17,17,0.28);
    animation: pjIndice var(--pj) steps(1, end) infinite both;
}
.pj-plaque-texte {
    display: inline-block;
    overflow: hidden;
    white-space: nowrap;
    width: 0;
    font-size: 17px;
    font-weight: 900;
    line-height: 1.2;
    letter-spacing: 0;
    text-transform: uppercase;
    color: var(--c-noir);
    /* Revelation par la LARGEUR, en ch (police a chasse fixe, sans
       interlettre : n caracteres = n ch). Le curseur de saisie, element
       frere, suit la frappe ; le couple reste centre comme le texte du
       vrai champ (text-align: center). */
    animation: pjType var(--pj) steps(1, end) infinite both;
}
/* Deux animations sur l'opacite d'un MEME element : la derniere
   ecrase la premiere — le trait ne clignotait jamais. L'affichage est
   donc porte par l'element, le clignotement par son ::before. */
.pj-caret {
    display: inline-block;
    width: 2px; height: 20px;
    margin-left: 1px;
    opacity: 0;
    animation: pjCaretShow var(--pj) steps(1, end) infinite both;
}
.pj-caret::before {
    content: '';
    display: block;
    width: 100%; height: 100%;
    background: var(--c-noir);
    animation: pjCaretBlink 1s steps(1, end) infinite;
}

.pj-plaque-dept {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #003399;
    padding: 3px 5px;
    gap: 2px;
    flex-shrink: 0;
    min-width: 28px;
}
.pj-plaque-dept svg { display: block; }
.pj-plaque-dept b { font-size: 10px; font-weight: 800; line-height: 1; color: #FFCC00; }


/* ================================================================
   TEMPS 3 — LE CLIC SUR LE BOUTON JAUNE
   ================================================================
   Le bouton du hero (css/style.css §11), a sa taille reelle, pose
   sous la plaque avec l'ecart de hero.js (14 px). Ses trois etats
   sont ceux du site : survol (jaune sombre, -2 px, halo plus large),
   pression (css/motion.css : translateY(0) scale(0.97), 140 ms),
   relachement.
   ================================================================ */

.pj-cta {
    position: absolute;
    left: 50%; top: 195px;
    transform: translateX(-50%) scale(var(--pj-k));
    transform-origin: 50% 0;
}
.pj-cta-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    padding: 12px 20px;
    background: var(--c-jaune);
    color: var(--c-noir);
    border-radius: 9px;
    font-size: 13px;
    font-weight: 700;
    white-space: nowrap;
    letter-spacing: -0.01em;
    font-family: var(--font-corps);
    box-shadow:
        0 5px 20px rgba(255, 204, 0, 0.55),
        0 2px 8px rgba(0, 0, 0, 0.20);
    animation: pjCta var(--pj) var(--ease-out) infinite both;
}
.pj-cta-btn svg { flex: none; }

/* La barre d'onglets du hero (css/style.css §14), onglet Plaque actif.
   Jamais plus large que la scene : sur un petit telephone, les onglets
   sont coupes a droite, comme ceux du vrai hero (qui defilent). */
.pj-onglets {
    position: absolute;
    left: 50%; top: 237px;
    width: 520px;
    width: min(520px, calc(100% / 0.6));
    transform: translateX(-50%) scale(0.6);
    transform-origin: 50% 0;
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px;
    overflow: hidden;
    border: 1px solid var(--c-gris-clair);
    border-radius: var(--r-full);
    background: var(--c-gris-bg);
}
.pj-onglets i {
    flex: 1;
    padding: 10px 8px;
    border-radius: var(--r-full);
    font-style: normal;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: -0.01em;
    text-align: center;
    white-space: nowrap;
    color: var(--c-gris-moyen);
}
.pj-onglets i:first-child {
    background: var(--c-noir);
    color: var(--c-blanc);
    box-shadow: 0 2px 10px rgba(0,0,0,0.22);
}


/* ================================================================
   TEMPS 4 — LE TOAST DU SITE
   ================================================================
   Le toast de motro.fr (css/style.css §18, variante « succes ») :
   anthracite, filet vert a gauche, coche verte. Il entre comme le
   vrai — par le bas, translateY(20px) scale(0.97), 0,28 s — et au
   meme endroit, en bas a droite. On le clique : c'est de son coin
   que Gmail va s'ouvrir.
   ================================================================ */

.pj-notif {
    position: absolute;
    z-index: 3;
    right: 16px; bottom: 16px;
    transform: scale(0.85);
    transform-origin: 100% 100%;
}
.pj-toast {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--c-anthracite);
    color: var(--c-blanc);
    padding: 13px 18px;
    border-radius: var(--r-md);
    border-left: 3px solid var(--c-vert);
    font-size: 13px;
    font-weight: 500;
    box-shadow: var(--ombre-lg);
    min-width: 240px;
    max-width: 340px;
    animation: pjNotif var(--pj) var(--ease-out) infinite both;
}
.pj-toast svg { flex-shrink: 0; }
.pj-toast strong { display: block; font-weight: 600; white-space: nowrap; }
.pj-toast small {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    font-weight: 400;
    white-space: nowrap;
    color: rgba(255,255,255,0.68);
}


/* ================================================================
   TEMPS 5 — GMAIL, LE DEVIS, LE PAIEMENT
   ================================================================
   Point de craft central : la boite mail grandit DEPUIS le coin
   bas-droit, la ou etait le toast qu'on vient de cliquer. Un
   panneau qui surgirait du centre semblerait venir d'ailleurs et
   le lien de cause a effet se perdrait.
   ================================================================ */

.pj-gmail {
    position: absolute;
    z-index: 4;
    top: 46px; left: 50%;
    width: min(360px, 82%);
    margin-left: calc(min(360px, 82%) / -2);
    border-radius: 14px;
    background: #fff;
    box-shadow: var(--elev-4, 0 28px 72px rgba(17,17,17,0.14));
    overflow: hidden;
    transform-origin: 100% 100%;
    animation: pjGmail var(--pj) var(--ease-out) infinite both;
}

.pj-gmail-bar {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 13px;
    border-bottom: 1px solid rgba(17,17,17,0.07);
    background: #fafafa;
}
.pj-gmail-bar svg { width: 15px; height: 15px; color: #9a9aa0; }
.pj-gmail-bar b {
    margin-left: auto;
    font-size: 11px; font-weight: 700; letter-spacing: -0.01em;
    color: #EA4335;
}

.pj-mail { padding: 14px 16px 16px; }

.pj-mail-objet {
    font-size: 14px; font-weight: 700;
    letter-spacing: -0.015em; color: var(--c-noir);
    margin-bottom: 10px;
}
.pj-mail-de {
    display: flex; align-items: center; gap: 9px;
    padding-bottom: 11px; margin-bottom: 11px;
    border-bottom: 1px solid rgba(17,17,17,0.07);
}
.pj-avatar {
    flex: none; width: 28px; height: 28px;
    border-radius: 50%;
    background: var(--c-noir); color: var(--c-jaune);
    display: grid; place-items: center;
    font-size: 12px; font-weight: 800;
}
.pj-mail-de strong { display: block; font-size: 12px; font-weight: 700; }
.pj-mail-de small  { display: block; font-size: 11px; color: #8a8a90; font-weight: 400; }
.pj-mail-heure     { margin-left: auto; font-size: 10.5px; color: #a2a2a8; }

/* Les lignes du corps arrivent en cascade : on lit un mail ligne a
   ligne, pas d'un bloc. */
.pj-mail-corps p {
    font-size: 12px;
    line-height: 1.55;
    color: #4a4a52;
    margin: 0 0 7px;
    animation: pjLigne var(--pj) var(--ease-out) infinite both;
}
.pj-mail-corps p:nth-of-type(1) { animation-delay: calc(var(--pj) * 0.000); }
.pj-mail-corps p:nth-of-type(2) { animation-delay: calc(var(--pj) * 0.004); }
.pj-mail-corps p:nth-of-type(3) { animation-delay: calc(var(--pj) * 0.008); }
.pj-mail-corps p:nth-of-type(4) { animation-delay: calc(var(--pj) * 0.012); }
.pj-mail-corps p:nth-of-type(5) { animation-delay: calc(var(--pj) * 0.016); }

.pj-mail-corps b { color: var(--c-noir); font-weight: 700; }

/* « cliquer ici » : la formulation exacte du template CRM. */
.pj-lien {
    color: #1a56db;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.pj-piece {
    display: inline-flex; align-items: center; gap: 8px;
    margin-top: 4px;
    padding: 8px 12px;
    border: 1px solid rgba(17,17,17,0.12);
    border-radius: 9px;
    background: #fafafa;
    animation: pjPiece var(--pj) var(--ease-out) infinite both;
}
.pj-piece-ico {
    width: 22px; height: 26px;
    border-radius: 4px;
    background: var(--c-jaune);
    display: grid; place-items: center;
    font-size: 8px; font-weight: 800; color: var(--c-noir);
}
.pj-piece-txt > span  { display: block; font-size: 11.5px; font-weight: 600; color: var(--c-noir); }
.pj-piece-txt > small { display: block; font-size: 10.5px; color: #9a9aa0; }

.pj-paid {
    position: absolute;
    left: 16px; right: 16px; bottom: 14px;
    display: flex; align-items: center; justify-content: center; gap: 8px;
    padding: 11px;
    border-radius: 10px;
    background: rgba(52, 199, 89, 0.10);
    color: #1e8e3e;
    font-size: 12.5px; font-weight: 700;
    animation: pjPaid var(--pj) var(--ease-out) infinite both;
}
.pj-paid svg { width: 16px; height: 16px; flex: none; }
.pj-paid path {
    stroke-dasharray: 22; stroke-dashoffset: 22;
    animation: pjCheck var(--pj) var(--ease-out) infinite both;
}


/* ================================================================
   TEMPS 6 — LE MOTEUR ARRIVE
   ================================================================ */

.pj-engine {
    position: absolute;
    z-index: 5;
    left: 50%; top: 130px;
    width: min(300px, 74%);
    margin-left: calc(min(300px, 74%) / -2);
    padding: 18px 20px;
    border-radius: 16px;
    background: var(--c-noir);
    color: #fff;
    box-shadow: var(--elev-4, 0 28px 72px rgba(17,17,17,0.14));
    animation: pjEngine var(--pj) var(--ease-out) infinite both;
}
.pj-engine-top { display: flex; align-items: center; gap: 12px; margin-bottom: 13px; }
.pj-engine-ico {
    flex: none; width: 40px; height: 40px;
    border-radius: 11px; background: var(--c-jaune);
    display: grid; place-items: center;
}
.pj-engine-ico svg { width: 21px; height: 21px; color: var(--c-noir); }
.pj-engine strong { display: block; font-size: 14px; font-weight: 700; letter-spacing: -0.01em; }
.pj-engine small  { display: block; margin-top: 2px; font-size: 11.5px; color: rgba(255,255,255,0.62); }
.pj-engine-bar { height: 4px; border-radius: 2px; background: rgba(255,255,255,0.14); overflow: hidden; }
.pj-engine-bar i {
    display: block; height: 100%; width: 100%; border-radius: 2px;
    background: var(--c-jaune); transform-origin: 0 50%;
    animation: pjDeliver var(--pj) var(--ease-out) infinite both;
}
.pj-engine-etat {
    margin-top: 8px;
    font-size: 11px; font-weight: 700;
    letter-spacing: 0.05em; text-transform: uppercase;
    color: var(--c-jaune);
}


/* ================================================================
   TEMPS 7 — L'AVIS S'ECRIT, PUIS LES CINQ ETOILES
   ================================================================
   L'avis se tape sous les yeux du visiteur : c'est un geste, pas un
   resultat. Puis les etoiles s'allument une par une, 110ms d'ecart —
   deux fois plus lent que les grilles du site, parce qu'ici la
   cascade EST le contenu : c'est le geste de noter.
   ================================================================ */

.pj-review {
    position: absolute;
    z-index: 6;
    left: 50%; top: 120px;
    width: min(320px, 78%);
    margin-left: calc(min(320px, 78%) / -2);
    padding: 20px;
    border-radius: 16px;
    background: #fff;
    box-shadow: var(--elev-4, 0 28px 72px rgba(17,17,17,0.14));
    animation: pjReview var(--pj) var(--ease-out) infinite both;
}
.pj-review-titre {
    font-size: 12.5px; font-weight: 700;
    color: var(--c-noir); margin-bottom: 12px;
}
.pj-zone {
    min-height: 56px;
    padding: 10px 12px;
    border: 1.5px solid rgba(17,17,17,0.12);
    border-radius: 10px;
    background: #fbfbfc;
    margin-bottom: 14px;
    animation: pjZone var(--pj) var(--ease-out) infinite both;
}
.pj-avis-texte {
    display: inline-block;
    font-size: 12.5px; line-height: 1.5; color: var(--c-noir);
    /* Meme correctif que la plaque : revelation par la largeur pour que le
       curseur de saisie, element frere, suive le texte au lieu de rester fige
       a la fin de la zone. */
    overflow: hidden;
    white-space: nowrap;
    width: 0;
    animation: pjEcrit var(--pj) steps(34, end) infinite both;
}
.pj-avis-caret {
    display: inline-block;
    width: 1.5px; height: 15px;
    vertical-align: -2px;
    background: var(--c-noir);
    animation: pjCaretBlink 0.9s steps(1, end) infinite,
               pjAvisCaret var(--pj) linear infinite both;
}

.pj-stars { display: flex; justify-content: center; gap: 7px; }
.pj-stars i {
    font-style: normal; font-size: 26px; line-height: 1;
    color: var(--c-jaune);
    transform-origin: 50% 60%;
    animation: pjStar var(--pj) var(--ease-out) infinite both;
}
.pj-stars i:nth-child(1) { animation-delay: calc(var(--pj) * 0.000); }
.pj-stars i:nth-child(2) { animation-delay: calc(var(--pj) * 0.006); }
.pj-stars i:nth-child(3) { animation-delay: calc(var(--pj) * 0.012); }
.pj-stars i:nth-child(4) { animation-delay: calc(var(--pj) * 0.018); }
.pj-stars i:nth-child(5) { animation-delay: calc(var(--pj) * 0.024); }

.pj-merci {
    margin-top: 11px; text-align: center;
    font-size: 11.5px; font-weight: 600; color: #7c7c83;
    animation: pjMerci var(--pj) var(--ease-out) infinite both;
}


/* ================================================================
   LE CURSEUR, ET LE DOIGT
   ================================================================
   Il s'etale sur toute la scene (inset: 0) et porte le pictogramme
   dans son coin. C'est ce qui permet d'exprimer son trajet dans le
   repere de la SCENE : les % de translate() se calculent sur la
   taille de l'element, pas sur celle du parent — et l'element fait
   la taille de la scene.

   Sur telephone il n'y a pas de curseur : un doigt ne survole rien.
   On montre a la place l'impact du doigt (.pj-tap), au moment des
   trois touchers du hero : la plaque, le bouton, le toast.
   ================================================================ */

.pj-cursor {
    position: absolute;
    z-index: 9;
    inset: 0;
    pointer-events: none;
    animation: pjCursor var(--pj) var(--ease-in-out) infinite both;
}
.pj-cursor svg {
    position: absolute; left: 0; top: 0;
    width: 21px; height: 21px;
    filter: drop-shadow(0 2px 5px rgba(0,0,0,0.28));
}

.pj-tap {
    display: none;
    position: absolute;
    z-index: 9;
    inset: 0;
    pointer-events: none;
    animation: pjTap var(--pj) steps(1, end) infinite both;
}
.pj-tap::after {
    content: '';
    position: absolute;
    left: -16px; top: -16px;
    width: 32px; height: 32px;
    border-radius: 50%;
    background: rgba(17,17,17,0.16);
    box-shadow: 0 0 0 1.5px rgba(255,255,255,0.85);
    animation: pjTapRond var(--pj) var(--ease-out) infinite both;
}


/* ================================================================
   LA TIMELINE MAITRE — 20s
   ================================================================
   Regle de montage : deux plans ne se chevauchent jamais a demi.
   Un element est sorti AVANT que le suivant entre, sinon deux
   surfaces a 50% d'opacite se superposent et l'oeil ne lit plus
   ni l'une ni l'autre. Les fenetres ci-dessous sont donc
   disjointes, avec un souffle entre chaque.

      0-5      le hero de motro.fr apparait
      3-6.5    le curseur monte jusqu'a la plaque
      7        clic : le champ prend le focus (fond #FFD700, trait)
      8.5-15   la plaque se tape : A ... AB 123 CD
     15.6-18.4 le curseur descend sur le bouton jaune
     18.4-19.6 survol
     19.6-20.4 pression (le champ perd le focus), puis relachement
     21-22.4   le toast du site entre par le bas, a droite
     22.4-28.4 il se lit ; le curseur le rejoint
     28.4-29.4 clic sur le toast
     30-36     Gmail s'ouvre depuis le coin du toast
     36-48     le mail se lit, la piece jointe arrive
     48-52     clic sur "cliquer ici"
     52-58     paiement confirme (remplace la piece jointe)
     58-62     Gmail se referme
     62-72     le moteur est expedie puis pose
     72-88     l'avis s'ecrit
     86-93     les cinq etoiles s'allument
     93-100    remerciement, fondu, on reboucle

   Les animations en steps(1, end) TIENNENT la valeur de chaque
   palier jusqu'au suivant : etats discrets (focus, touches tapees).
   ================================================================ */

@keyframes pjSite {
    0%          { opacity: 0; transform: translateY(14px) scale(0.965); }
    5%, 30%     { opacity: 1; transform: translateY(0)    scale(1); }
    /* Recule quand Gmail passe devant : la profondeur dit ou est le
       focus, sans avoir a assombrir la scene. */
    36%, 92%    { opacity: 0.4; transform: translateY(0)  scale(0.975); }
    97%, 100%   { opacity: 0;   transform: translateY(0)  scale(0.975); }
}

@keyframes pjChamp {
    0%     { background-color: #FFCC00; outline-color: transparent;    border-radius: 0; }
    7%     { background-color: #FFD700; outline-color: var(--c-jaune); border-radius: var(--r-sm); }
    19.6%  { background-color: #FFCC00; outline-color: transparent;    border-radius: 0; }
    100%   { background-color: #FFCC00; outline-color: transparent;    border-radius: 0; }
}
@keyframes pjIndice {
    0%     { opacity: 1; }
    8.5%   { opacity: 0; }
    100%   { opacity: 0; }
}
/* Sept touches a un rythme humain, pas a la metronome : 220, 240,
   180, 200, 260, 200 ms. Les espaces arrivent avec la touche qui les
   provoque (1 et C), comme dans le vrai champ. */
@keyframes pjType {
    0%     { width: 0; }
    8.5%   { width: 1ch; }
    9.6%   { width: 2ch; }
    10.8%  { width: 4ch; }
    11.7%  { width: 5ch; }
    12.7%  { width: 6ch; }
    14%    { width: 8ch; }
    15%    { width: 9ch; }
    100%   { width: 9ch; }
}
@keyframes pjCaretShow {
    0%     { opacity: 0; }
    7%     { opacity: 1; }
    19.6%  { opacity: 0; }
    100%   { opacity: 0; }
}
@keyframes pjCaretBlink {
    0%, 49%   { opacity: 1; }
    50%, 100% { opacity: 0; }
}

/* Repos -> survol -> pression -> survol -> repos : les valeurs de
   .btn-cta-overlay, :hover et :active du site. */
@keyframes pjCta {
    0%, 18.4% {
        background-color: var(--c-jaune);
        transform: translateY(0) scale(1);
        box-shadow: 0 5px 20px rgba(255, 204, 0, 0.55), 0 2px 8px rgba(0, 0, 0, 0.20);
    }
    19.1%, 19.6% {
        background-color: var(--c-jaune-sombre);
        transform: translateY(-2px) scale(1);
        box-shadow: 0 8px 28px rgba(255, 204, 0, 0.65), 0 3px 10px rgba(0, 0, 0, 0.20);
    }
    20.1%, 20.4% {
        background-color: var(--c-jaune-sombre);
        transform: translateY(0) scale(0.97);
        box-shadow: 0 8px 28px rgba(255, 204, 0, 0.65), 0 3px 10px rgba(0, 0, 0, 0.20);
    }
    21.1%, 21.6% {
        background-color: var(--c-jaune-sombre);
        transform: translateY(-2px) scale(1);
        box-shadow: 0 8px 28px rgba(255, 204, 0, 0.65), 0 3px 10px rgba(0, 0, 0, 0.20);
    }
    22.3%, 100% {
        background-color: var(--c-jaune);
        transform: translateY(0) scale(1);
        box-shadow: 0 5px 20px rgba(255, 204, 0, 0.55), 0 2px 8px rgba(0, 0, 0, 0.20);
    }
}

@keyframes pjNotif {
    0%, 21%      { opacity: 0; transform: translateY(20px) scale(0.97); }
    22.4%, 28.4% { opacity: 1; transform: translateY(0)    scale(1); }
    28.8%        { opacity: 1; transform: translateY(0)    scale(0.97); }
    29.4%        { opacity: 1; transform: translateY(0)    scale(1); }
    32%, 100%    { opacity: 0; transform: translateY(0)    scale(1.02); }
}

@keyframes pjGmail {
    0%, 30%     { opacity: 0; transform: scale(0.90) translateY(8px); }
    36%, 58%    { opacity: 1; transform: scale(1)    translateY(0); }
    62%, 100%   { opacity: 0; transform: scale(0.97) translateY(-4px); }
}

@keyframes pjLigne {
    0%, 37%     { opacity: 0; transform: translateY(4px); }
    42%, 100%   { opacity: 1; transform: translateY(0); }
}

/* La piece jointe s'efface pour laisser la place a la confirmation :
   c'est le meme emplacement qui change d'etat, pas deux blocs qui
   s'empilent. */
@keyframes pjPiece {
    0%, 43%     { opacity: 0; transform: translateY(6px) scale(0.97); }
    47%, 51%    { opacity: 1; transform: translateY(0)   scale(1); }
    54%, 100%   { opacity: 0; transform: translateY(0)   scale(1); }
}

@keyframes pjPaid {
    0%, 53%     { opacity: 0; transform: translateY(6px); }
    56%, 58%    { opacity: 1; transform: translateY(0); }
    61%, 100%   { opacity: 0; transform: translateY(0); }
}
@keyframes pjCheck {
    0%, 54%     { stroke-dashoffset: 22; }
    58%, 100%   { stroke-dashoffset: 0; }
}

@keyframes pjEngine {
    0%, 63%     { opacity: 0; transform: translateY(18px) scale(0.96); }
    67%, 71%    { opacity: 1; transform: translateY(0)    scale(1); }
    75%, 100%   { opacity: 0; transform: translateY(-8px) scale(0.98); }
}
@keyframes pjDeliver {
    0%, 66%     { transform: scaleX(0.06); }
    71%, 100%   { transform: scaleX(1); }
}

@keyframes pjReview {
    0%, 74%     { opacity: 0; transform: translateY(16px) scale(0.96); }
    78%, 96%    { opacity: 1; transform: translateY(0)    scale(1); }
    100%        { opacity: 0; transform: translateY(0)    scale(0.99); }
}
@keyframes pjZone {
    0%, 78%     { border-color: rgba(17,17,17,0.12); }
    80%, 87%    { border-color: rgba(17,17,17,0.45); }
    89%, 100%   { border-color: rgba(17,17,17,0.12); }
}
@keyframes pjEcrit {
    0%, 79%     { width: 0; }
    87%, 100%   { width: 100%; }
}
@keyframes pjAvisCaret {
    0%, 78%     { opacity: 0; }
    79%, 87%    { opacity: 1; }
    88%, 100%   { opacity: 0; }
}

@keyframes pjStar {
    0%, 87%     { opacity: 0; transform: scale(0.4) rotate(-16deg); }
    /* Le seul rebond de tout le site. Il est ici parce que mettre
       cinq etoiles est un geste joyeux. */
    89.5%       { opacity: 1; transform: scale(1.16) rotate(3deg); }
    91%, 97%    { opacity: 1; transform: scale(1)    rotate(0deg); }
    100%        { opacity: 0; transform: scale(1)    rotate(0deg); }
}
@keyframes pjMerci {
    0%, 92%     { opacity: 0; transform: translateY(4px); }
    94%, 97%    { opacity: 1; transform: translateY(0); }
    100%        { opacity: 0; transform: translateY(0); }
}

/* Trajet du curseur. La pointe de la fleche est le coin haut gauche du
   SVG, et la couche .pj-cursor fait la taille de la scene : un
   translate(X, Y) place donc la pointe en (X, Y) de la scene.

   Partie hero : cotes en PX depuis le haut (geometrie fixe), X = 50 %
   pour la plaque et le bouton (centres), et depuis le coin bas-droit
   pour le toast (calc(100% - …)) — juste a toutes les largeurs.
   Partie Gmail : % de la scene, MESURES en figeant l'animation a
   l'instant de chaque clic (cible a sa place d'arrivee).
   Le banc verifie que la pointe est DANS sa cible a chaque clic. */
@keyframes pjCursor {
    0%, 2.5%     { opacity: 0; transform: translate(calc(50% + 40px), 445px); }
    3.5%         { opacity: 1; transform: translate(calc(50% + 40px), 445px); }
    6.5%, 7.6%   { opacity: 1; transform: translate(50%, 325px); }                 /* la plaque : clic a 7 */
    9%, 15.6%    { opacity: 1; transform: translate(calc(50% + 74px), 337px); }   /* on s'ecarte pour taper */
    18.4%, 21.6% { opacity: 1; transform: translate(50%, 368px); }                 /* le bouton : clic a 19,6 */
    /* le toast : clic a 28,4, dans sa marge basse, a 40 px de son bord droit — la
       fleche part vers le bas a droite et ne masque pas le texte qu'on vient de lire */
    26.4%, 29.2% { opacity: 1; transform: translate(calc(100% - 56px), calc(100% - 28px)); }
    34%, 46%     { opacity: 1; transform: translate(25%, 50%); }                   /* on lit le mail */
    49%, 52%     { opacity: 1; transform: translate(49.7%, 58.3%); }               /* "cliquer ici" */
    56%, 74%     { opacity: 0; transform: translate(49.7%, 64%); }
    80%, 86%     { opacity: 1; transform: translate(50%, 42.4%); }                 /* la zone d'avis */
    88.5%, 91%   { opacity: 1; transform: translate(50%, 57.6%); }                 /* les etoiles */
    96%, 100%    { opacity: 0; transform: translate(50%, 92%); }
}

/* Le doigt : il se pose (cercle qui s'elargit et s'efface) sur les
   memes cibles, aux memes instants que les clics du curseur. */
@keyframes pjTap {
    0%     { transform: translate(50%, 325px); }
    8.5%   { transform: translate(50%, 368px); }
    21%    { transform: translate(calc(100% - 128px), calc(100% - 44px)); }   /* centre du toast */
    100%   { transform: translate(calc(100% - 128px), calc(100% - 44px)); }
}
@keyframes pjTapRond {
    0%, 6.8%      { opacity: 0; transform: scale(0.6); }
    7%            { opacity: 1; transform: scale(0.7); }
    8.4%          { opacity: 0; transform: scale(1.25); }
    8.5%, 19.4%   { opacity: 0; transform: scale(0.6); }
    19.6%         { opacity: 1; transform: scale(0.7); }
    21%           { opacity: 0; transform: scale(1.25); }
    21.1%, 28.2%  { opacity: 0; transform: scale(0.6); }
    28.4%         { opacity: 1; transform: scale(0.7); }
    29.8%, 100%   { opacity: 0; transform: scale(1.25); }
}


/* ================================================================
   MOUVEMENT REDUIT
   ================================================================
   On ne joue rien. On montre UNE image qui dit le debut de
   l'histoire : la plaque saisie sur le vrai hero, et le toast du
   devis qui en resulte. La liste numerotee a cote raconte la suite
   en toutes lettres. Mouvement reduit veut dire moins et plus doux,
   pas "contenu retire".
   (Avant le hero a l'echelle, on montrait le mail et les etoiles :
   avec une carte de 420 px, le mail recouvrait la voiture et les
   etoiles, en position statique, passaient SOUS la carte.)
   ================================================================ */

@media (prefers-reduced-motion: reduce) {
    .pj-stage *,
    .pj-stage *::before,
    .pj-stage *::after { animation: none !important; }

    .pj-site   { opacity: 1; transform: none; }
    .pj-plaque-texte { width: 9ch; }
    /* Avec ou sans .is-playing : la regle « hors ecran » (0,3,0) masque le toast. */
    .pj-toast,
    .pj-stage:not(.is-playing) .pj-toast { opacity: 1; transform: none; }
    .pj-plaque-indice,
    .pj-caret,
    .pj-gmail,
    .pj-engine,
    .pj-review,
    .pj-cursor,
    .pj-tap    { display: none; }
}


/* ================================================================
   MOBILE
   ================================================================
   Meme scene, meme hauteur (470 px) : la geometrie du hero est fixe,
   c'est elle qui garde le doigt sur ses cibles. Le toast se cale
   comme celui du site sur telephone (#toastContainer : 16 / 12 px).
   ================================================================ */

@media (max-width: 720px) {
    .pj-site   { left: 3%; right: 3%; }
    .pj-notif  { right: 12px; bottom: 16px; }
    .pj-gmail  { top: 36px; width: 92%; margin-left: -46%; }
    .pj-cursor { display: none; }   /* il n'y a pas de curseur au doigt */
}
/* ⚠ Condition sur le mouvement : cette regle vient APRES le bloc « mouvement
   reduit » ; sans elle, elle y rallumerait le doigt — fige, animations
   coupees, son cercle resterait plante dans le coin de la scene. */
@media (max-width: 720px) and (prefers-reduced-motion: no-preference) {
    .pj-tap    { display: block; }
}
