/* ============================================================
   Coupe de chantier animée — partagée
   ------------------------------------------------------------
   « Le chantier se construit sous la caméra » : terrassement,
   cotes, lit de pose, canalisation, remblai et grillage, enrobés,
   petit drone, puis mise au point et déclenchement (≈ 6 s).
   Utilisée par le hero de travaux-publics/ et par le bandeau
   « Sur les chantiers aussi » de la page entreprises.
   Le dessin fini est l'état de base (fill-mode both) : la classe
   « is-run » sur <svg class="tp-plan"> joue la construction, et le
   mouvement réduit montre directement le dessin fini.
   Script : coupe-chantier.js (compteur REC, relance au survol,
   départ à l'arrivée à l'écran avec data-tp-plan="scroll").
   ============================================================ */

.tp-plan__line,
.tp-plan__frame,
.tp-plan__cote,
.tp-plan__dash {
    fill: none;
    stroke: #c7b8ff;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.tp-plan__line {
    stroke-width: 1.6;
}

.tp-plan__line--soft {
    stroke-width: 1;
    opacity: 0.45;
}

.tp-plan__pipe {
    fill: rgba(16, 0, 63, 0.85);
}

.tp-plan__frame {
    stroke: #fff;
    stroke-width: 2;
    opacity: 0.85;
}

.tp-plan__cote {
    stroke-width: 0.9;
    opacity: 0.7;
}

.tp-plan__dash {
    stroke: #ffc94d;
    stroke-width: 1.4;
    stroke-dasharray: 6 5;
}

.tp-plan__fill {
    fill: rgba(199, 184, 255, 0.1);
}

.tp-plan__fill--bed {
    fill: rgba(255, 201, 77, 0.22);
}

.tp-plan__fill--asphalt {
    fill: #2a1d6b;
    stroke: #c7b8ff;
    stroke-width: 0.8;
}

.tp-plan__flash {
    fill: #fff;
    opacity: 0;
    pointer-events: none;
}

/* Petit drone (vue de face) et son cône de visée. */
.tp-plan__drone-line {
    fill: none;
    stroke: #fff;
    stroke-width: 1.6;
    stroke-linecap: round;
}

.tp-plan__drone-body {
    fill: #fff;
}

.tp-plan__drone-cam {
    fill: #10003f;
    stroke: #fff;
    stroke-width: 1.2;
}

.tp-plan__drone-led {
    fill: #ff5a6e;
}

.tp-plan__rotor {
    fill: rgba(199, 184, 255, 0.55);
    transform-box: fill-box;
    transform-origin: 50% 50%;
}

.tp-plan__beam {
    fill: rgba(199, 184, 255, 0.14);
    stroke: rgba(199, 184, 255, 0.5);
    stroke-width: 0.8;
    stroke-dasharray: 3 3;
    opacity: 0;
}

.tp-plan__rec {
    fill: #ff5a6e;
    animation: tp-rec 1.6s ease-in-out infinite;
}

.tp-plan__label {
    fill: #fff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    font-variant-numeric: tabular-nums;
}

.tp-plan__label--muted {
    fill: rgba(199, 184, 255, 0.78);
    font-weight: 600;
}

/* Entre la conduite et la paroi : il faut tenir dans 38 px. */
.tp-a--label-pipe {
    font-size: 9px;
    letter-spacing: 0;
}

/* ---------- La coupe se construit (≈ 6 s) ----------
   L'état de base est le dessin fini : chaque étape part de son état
   « avant » (fill-mode both) et s'y arrête. Ordre réel d'un chantier
   de réseau : terrassement, cotes, lit de pose, canalisation, remblai
   et grillage, enrobés ; puis la caméra fait sa mise au point. */
.tp-plan [pathLength] {
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
}

.tp-a--bed,
.tp-a--backfill {
    transform-box: fill-box;
    transform-origin: 50% 100%;
}

.tp-a--mesh,
.tp-a--asphalt {
    transform-box: fill-box;
    transform-origin: 0 50%;
}

.tp-a--camera {
    transform-origin: 210px 165px;
}

/* 1. terrassement */
.tp-plan.is-run .tp-a--ground { animation: tp-draw 0.5s ease-out 0.1s both; }
.tp-plan.is-run .tp-a--ground-soft { animation: tp-fade 0.4s ease-out 0.4s both; }
.tp-plan.is-run .tp-a--wall { animation: tp-draw 0.7s cubic-bezier(0.45, 0, 0.2, 1) 0.6s both; }
.tp-plan.is-run .tp-a--bottom { animation: tp-draw 0.3s ease-out 1.25s both; }
.tp-plan.is-run .tp-a--cote-v { animation: tp-draw 0.5s ease-out 1.3s both; }
.tp-plan.is-run .tp-a--ticks-v,
.tp-plan.is-run .tp-a--label-depth { animation: tp-fade 0.35s ease-out 1.6s both; }
.tp-plan.is-run .tp-a--cote-h { animation: tp-draw 0.4s ease-out 1.6s both; }
.tp-plan.is-run .tp-a--ticks-h,
.tp-plan.is-run .tp-a--label-width { animation: tp-fade 0.35s ease-out 1.9s both; }

/* 2. lit de pose, puis la canalisation descend et se pose */
.tp-plan.is-run .tp-a--bed { animation: tp-grow-y 0.3s ease-out 2s both; }
.tp-plan.is-run .tp-a--pipe { animation: tp-drop 0.8s ease-out 2.2s both; }
.tp-plan.is-run .tp-a--label-pipe { animation: tp-fade 0.35s ease-out 2.9s both; }

/* 3. remblai par couches, grillage avertisseur déroulé au-dessus de la conduite */
.tp-plan.is-run .tp-a--backfill { animation: tp-grow-y 1s cubic-bezier(0.3, 0, 0.3, 1) 3.1s both; }
.tp-plan.is-run .tp-a--layer-1 { animation: tp-fade 0.3s ease-out 3.3s both; }
.tp-plan.is-run .tp-a--mesh { animation: tp-grow-x 0.45s ease-out 3.55s both; }
.tp-plan.is-run .tp-a--label-mesh { animation: tp-fade 0.3s ease-out 3.8s both; }
.tp-plan.is-run .tp-a--layer-2 { animation: tp-fade 0.3s ease-out 3.65s both; }
.tp-plan.is-run .tp-a--layer-3 { animation: tp-fade 0.3s ease-out 4s both; }
.tp-plan.is-run .tp-a--label-fill { animation: tp-fade 0.3s ease-out 4.05s both; }

/* 4. enrobés : le finisseur passe de gauche à droite */
.tp-plan.is-run .tp-a--asphalt { animation: tp-grow-x 0.6s cubic-bezier(0.45, 0, 0.2, 1) 4.3s both; }
.tp-plan.is-run .tp-a--asphalt-line { animation: tp-draw 0.6s cubic-bezier(0.45, 0, 0.2, 1) 4.3s both; }
.tp-plan.is-run .tp-a--label-asphalt { animation: tp-fade 0.3s ease-out 4.7s both; }

/* 4 bis. le drone entre par la gauche en s'inclinant, se stabilise au-dessus
   de la tranchée, vise la chaussée pendant la prise de vue, puis reste posé
   en vol stationnaire (les hélices s'arrêtent de tourner après quelques secondes). */
.tp-a--drone {
    transform-box: fill-box;
    transform-origin: 50% 50%;
}

.tp-plan.is-run .tp-a--drone { animation: tp-fly 1.2s cubic-bezier(0.25, 0.8, 0.3, 1) 4.4s both; }
.tp-plan.is-run .tp-plan__rotor { animation: tp-spin 0.12s linear 4.4s 45; }
.tp-plan.is-run .tp-a--beam { animation: tp-beam 1.3s ease-in-out 5.2s both; }

/* 5. caméra : le cadre se resserre (mise au point), puis le déclenchement */
.tp-plan.is-run .tp-a--camera { animation: tp-focus 0.7s cubic-bezier(0.3, 0, 0.2, 1) 4.95s both; }
.tp-plan.is-run .tp-a--flash { animation: tp-flash 0.45s ease-out 5.7s both; }

@keyframes tp-draw {
    from { stroke-dashoffset: 1; }
    to { stroke-dashoffset: 0; }
}

@keyframes tp-fade {
    from { opacity: 0; }
}

@keyframes tp-grow-y {
    from { transform: scaleY(0); }
    to { transform: none; }
}

@keyframes tp-grow-x {
    from { transform: scaleX(0); }
    to { transform: none; }
}

@keyframes tp-drop {
    0% { transform: translateY(-150px); opacity: 0; }
    20% { opacity: 1; }
    65% { transform: translateY(3px); }
    82% { transform: translateY(-2px); }
    100% { transform: none; opacity: 1; }
}

@keyframes tp-focus {
    0% { transform: scale(1.08); opacity: 0.5; }
    60% { transform: scale(0.98); opacity: 1; }
    100% { transform: none; opacity: 1; }
}

@keyframes tp-flash {
    0% { opacity: 0; }
    25% { opacity: 0.3; }
    100% { opacity: 0; }
}

@keyframes tp-fly {
    0% { transform: translate(-260px, -34px) rotate(10deg); opacity: 0; }
    15% { opacity: 1; }
    70% { transform: translate(6px, 2px) rotate(-5deg); }
    100% { transform: none; opacity: 1; }
}

@keyframes tp-spin {
    50% { transform: scaleX(0.25); }
}

@keyframes tp-beam {
    0% { opacity: 0; }
    35%, 70% { opacity: 1; }
    100% { opacity: 0; }
}

@keyframes tp-rec {
    50% { opacity: 0.25; }
}

@media (prefers-reduced-motion: reduce) {
    .tp-plan *,
    .tp-plan.is-run * {
        animation: none !important;
    }
}
