/* ==========================================
   ANIMATIONS — Batista Couverture
   Easing palette:
   --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1)   — primary reveal
   --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1)  — secondary
   --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1)    — symmetric
   ========================================== */

:root {
    --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
}

/* Respect user preferences */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    .reveal-mask .reveal-word,
    .word-reveal .word {
        opacity: 1 !important;
        transform: none !important;
    }
}

/* ==========================================
   WORD REVEAL — used for big titles
   Each word is wrapped in a span; the inner span
   slides up from below a mask line.
   ========================================== */

.word-reveal .word {
    display: inline-block;
    overflow: hidden;
    vertical-align: top;
    line-height: inherit;
    /* Slight extra padding so descenders aren't clipped */
    padding-bottom: 0.15em;
    margin-bottom: -0.15em;
}

/* If JS hasn't run or splitting failed, keep titles visible */
.section-title:not(.word-reveal),
.hero-title:not(.word-reveal) {
    opacity: 1;
}

.word-reveal .word-inner {
    display: inline-block;
    transform: translateY(115%);
    opacity: 0;
    transition:
        transform 1s var(--ease-out-expo),
        opacity 0.8s var(--ease-out-expo);
}

.word-reveal.is-visible .word-inner {
    transform: translateY(0);
    opacity: 1;
}

/* Stagger each word using --i (set inline by JS) */
.word-reveal.is-visible .word:nth-child(1) .word-inner { transition-delay: 0ms; }
.word-reveal.is-visible .word:nth-child(2) .word-inner { transition-delay: 60ms; }
.word-reveal.is-visible .word:nth-child(3) .word-inner { transition-delay: 120ms; }
.word-reveal.is-visible .word:nth-child(4) .word-inner { transition-delay: 180ms; }
.word-reveal.is-visible .word:nth-child(5) .word-inner { transition-delay: 240ms; }
.word-reveal.is-visible .word:nth-child(6) .word-inner { transition-delay: 300ms; }
.word-reveal.is-visible .word:nth-child(7) .word-inner { transition-delay: 360ms; }
.word-reveal.is-visible .word:nth-child(8) .word-inner { transition-delay: 420ms; }
.word-reveal.is-visible .word:nth-child(9) .word-inner { transition-delay: 480ms; }
.word-reveal.is-visible .word:nth-child(10) .word-inner { transition-delay: 540ms; }
.word-reveal.is-visible .word:nth-child(11) .word-inner { transition-delay: 600ms; }
.word-reveal.is-visible .word:nth-child(12) .word-inner { transition-delay: 660ms; }
.word-reveal.is-visible .word:nth-child(13) .word-inner { transition-delay: 720ms; }
.word-reveal.is-visible .word:nth-child(14) .word-inner { transition-delay: 780ms; }
.word-reveal.is-visible .word:nth-child(15) .word-inner { transition-delay: 840ms; }
.word-reveal.is-visible .word:nth-child(16) .word-inner { transition-delay: 900ms; }
.word-reveal.is-visible .word:nth-child(17) .word-inner { transition-delay: 960ms; }
.word-reveal.is-visible .word:nth-child(18) .word-inner { transition-delay: 1020ms; }

/* ==========================================
   FADE UP — generic, replaces old .fade-in
   ========================================== */
.anim-fade-up {
    opacity: 0;
    transform: translateY(40px);
    transition:
        opacity 1s var(--ease-out-expo),
        transform 1s var(--ease-out-expo);
}

.anim-fade-up.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* Stagger delays — applied via class */
.anim-delay-1 { transition-delay: 100ms; }
.anim-delay-2 { transition-delay: 200ms; }
.anim-delay-3 { transition-delay: 300ms; }
.anim-delay-4 { transition-delay: 400ms; }
.anim-delay-5 { transition-delay: 500ms; }

/* Slide from left — for badges */
.anim-slide-left {
    opacity: 0;
    transform: translateX(-24px);
    transition:
        opacity 0.8s var(--ease-out-expo),
        transform 0.8s var(--ease-out-expo);
}

.anim-slide-left.is-visible {
    opacity: 1;
    transform: translateX(0);
}

/* Scale fade — for cards */
.anim-scale-fade {
    opacity: 0;
    transform: translateY(30px) scale(0.97);
    transition:
        opacity 1.1s var(--ease-out-expo),
        transform 1.1s var(--ease-out-expo);
}

.anim-scale-fade.is-visible {
    opacity: 1;
    transform: translateY(0) scale(1);
}

/* ==========================================
   HERO ENTRANCE (on page load)
   ========================================== */

/* Background image: scales from 1.08 to 1, slight saturate boost */
.hero-bg-img {
    transform: scale(1.08);
    filter: saturate(0.7) brightness(0.9);
    transition:
        transform 1.8s var(--ease-out-expo),
        filter 1.8s var(--ease-out-expo);
}

body.hero-loaded .hero-bg-img {
    transform: scale(1);
    filter: saturate(1) brightness(1);
}

/* Hero overlay slides in from bottom */
.hero-overlay {
    opacity: 0;
    transition: opacity 1.4s var(--ease-out-expo) 0.2s;
}

body.hero-loaded .hero-overlay {
    opacity: 1;
}

/* Social icons fade up */
.hero-social {
    opacity: 0;
    transform: translateY(20px);
    transition:
        opacity 0.9s var(--ease-out-expo),
        transform 0.9s var(--ease-out-expo);
    transition-delay: 0.4s;
}

body.hero-loaded .hero-social {
    opacity: 1;
    transform: translateY(0);
}

/* Hero description fades up after title */
.hero-description {
    opacity: 0;
    transform: translateY(20px);
    transition:
        opacity 1s var(--ease-out-expo),
        transform 1s var(--ease-out-expo);
    transition-delay: 1.2s;
}

body.hero-loaded .hero-description {
    opacity: 1;
    transform: translateY(0);
}

/* Hero buttons fade up last */
.hero-buttons {
    opacity: 0;
    transform: translateY(20px);
    transition:
        opacity 1s var(--ease-out-expo),
        transform 1s var(--ease-out-expo);
    transition-delay: 1.4s;
}

body.hero-loaded .hero-buttons {
    opacity: 1;
    transform: translateY(0);
}

/* Stagger the two hero buttons individually */
.hero-buttons .btn {
    opacity: 0;
    transform: translateY(12px);
    transition:
        opacity 0.7s var(--ease-out-expo),
        transform 0.7s var(--ease-out-expo);
}

body.hero-loaded .hero-buttons .btn:nth-child(1) {
    opacity: 1;
    transform: translateY(0);
    transition-delay: 1.5s;
}

body.hero-loaded .hero-buttons .btn:nth-child(2) {
    opacity: 1;
    transform: translateY(0);
    transition-delay: 1.6s;
}

/* Navbar fades down */
.navbar {
    opacity: 0;
    transform: translateY(-12px);
    transition:
        opacity 0.8s var(--ease-out-expo),
        transform 0.8s var(--ease-out-expo);
    transition-delay: 0.1s;
}

body.hero-loaded .navbar {
    opacity: 1;
    transform: translateY(0);
}

/* Hero title baseline state — handled by .word-reveal but make sure visible after load */
body.hero-loaded .hero-title.word-reveal {
    /* Class gets is-visible added by JS */
}

/* ==========================================
   PULSING BADGE DOT
   The orange dot in section badges pulses subtly
   ========================================== */
.badge-dot {
    position: relative;
}

.badge-dot::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: var(--primary);
    opacity: 0.4;
    animation: dot-pulse 2.4s var(--ease-out-expo) infinite;
}

@keyframes dot-pulse {
    0% {
        transform: scale(1);
        opacity: 0.4;
    }
    70% {
        transform: scale(2.4);
        opacity: 0;
    }
    100% {
        transform: scale(2.4);
        opacity: 0;
    }
}

/* ==========================================
   STAT NUMBER COUNTUP
   The number element gets opacity transition;
   the actual count is done in JS.
   ========================================== */
.stat-card {
    opacity: 0;
    transform: translateY(24px);
    transition:
        opacity 0.9s var(--ease-out-expo),
        transform 0.9s var(--ease-out-expo);
}

.stat-card.is-visible {
    opacity: 1;
    transform: translateY(0);
}

.stat-card:nth-child(1).is-visible { transition-delay: 0ms; }
.stat-card:nth-child(2).is-visible { transition-delay: 100ms; }
.stat-card:nth-child(3).is-visible { transition-delay: 200ms; }
.stat-card:nth-child(4).is-visible { transition-delay: 300ms; }

/* ==========================================
   ABOUT FEATURES — staggered reveal
   ========================================== */
.about-feature {
    opacity: 0;
    transform: translateY(30px);
    transition:
        opacity 1s var(--ease-out-expo),
        transform 1s var(--ease-out-expo);
}

.about-feature.is-visible {
    opacity: 1;
    transform: translateY(0);
}

.about-feature:nth-child(1).is-visible { transition-delay: 0ms; }
.about-feature:nth-child(2).is-visible { transition-delay: 120ms; }
.about-feature:nth-child(3).is-visible { transition-delay: 240ms; }

/* ==========================================
   SERVICE ROWS — alternating slide
   ========================================== */
.service-row > * {
    opacity: 0;
    transform: translateY(40px);
    transition:
        opacity 1.1s var(--ease-out-expo),
        transform 1.1s var(--ease-out-expo);
}

.service-row.is-visible > *:nth-child(1) {
    opacity: 1;
    transform: translateY(0);
    transition-delay: 0ms;
}

.service-row.is-visible > *:nth-child(2) {
    opacity: 1;
    transform: translateY(0);
    transition-delay: 150ms;
}

/* ==========================================
   AVANT / APRÈS CARDS — pair narrative reveal
   The before fades in first, the after follows
   ========================================== */
.ba-card {
    opacity: 0;
    transform: translateY(30px) scale(0.97);
    transition:
        opacity 1.1s var(--ease-out-expo),
        transform 1.1s var(--ease-out-expo);
}

.ba-card.is-visible {
    opacity: 1;
    transform: translateY(0) scale(1);
}

/* ==========================================
   AVIS CARDS — fade up
   ========================================== */
.avis-item {
    opacity: 0;
    transform: translateY(30px);
    transition:
        opacity 1s var(--ease-out-expo),
        transform 1s var(--ease-out-expo);
}

.avis-track.is-visible .avis-item {
    opacity: 1;
    transform: translateY(0);
}

.avis-track.is-visible .avis-item:nth-child(1) { transition-delay: 0ms; }
.avis-track.is-visible .avis-item:nth-child(2) { transition-delay: 120ms; }
.avis-track.is-visible .avis-item:nth-child(3) { transition-delay: 240ms; }

/* ==========================================
   TRAVAUX CARDS — same pattern
   ========================================== */
.travaux-carousel-track > .travaux-card {
    opacity: 0;
    transform: translateY(30px);
    transition:
        opacity 1s var(--ease-out-expo),
        transform 1s var(--ease-out-expo);
}

.travaux-carousel-track.is-visible > .travaux-card {
    opacity: 1;
    transform: translateY(0);
}

.travaux-carousel-track.is-visible .travaux-card:nth-child(1) { transition-delay: 0ms; }
.travaux-carousel-track.is-visible .travaux-card:nth-child(2) { transition-delay: 120ms; }
.travaux-carousel-track.is-visible .travaux-card:nth-child(3) { transition-delay: 240ms; }
.travaux-carousel-track.is-visible .travaux-card:nth-child(4) { transition-delay: 360ms; }

/* ==========================================
   SECTION HEADERS
   ========================================== */
.section-badge {
    opacity: 0;
    transform: translateX(-20px);
    transition:
        opacity 0.8s var(--ease-out-expo),
        transform 0.8s var(--ease-out-expo);
}

.section-badge.is-visible {
    opacity: 1;
    transform: translateX(0);
}

/* ==========================================
   CARD HOVER LIFT (gentle)
   ========================================== */
.service-card-alt,
.avis-item,
.ba-card,
.travaux-card {
    transition:
        transform 0.5s var(--ease-out-expo),
        box-shadow 0.5s var(--ease-out-expo),
        opacity 1s var(--ease-out-expo);
}

.service-card-alt:hover {
    transform: translateY(-4px);
    box-shadow: 0 20px 40px -20px rgba(43, 29, 14, 0.15);
}

/* ==========================================
   PARALLAX-READY hero bg (handled by JS)
   ========================================== */
.hero-image-wrapper {
    will-change: transform;
}

/* ==========================================
   PRE-LOAD STATE
   Hide elements that will animate so there's
   no flash of un-animated content (FOUC)
   ========================================== */
body:not(.hero-loaded) .hero-bg-img,
body:not(.hero-loaded) .hero-overlay,
body:not(.hero-loaded) .hero-social,
body:not(.hero-loaded) .hero-description,
body:not(.hero-loaded) .hero-buttons,
body:not(.hero-loaded) .navbar {
    /* Already at their initial transform/opacity from above */
}

/* ==========================================
   CONTACT PAGE — entrance animations
   Mirrors hero animations but for the split layout
   ========================================== */

/* Dark panel image: scales down */
.ct-panel-img {
    transform: scale(1.08);
    filter: brightness(0.18) saturate(0.5);
    transition:
        transform 1.8s var(--ease-out-expo),
        filter 1.8s var(--ease-out-expo);
}

body.hero-loaded .ct-panel-img {
    transform: scale(1);
    filter: brightness(0.22) saturate(0.6);
}

/* Kicker slides from left */
.ct-anim-kicker {
    opacity: 0;
    transform: translateX(-20px);
    transition:
        opacity 0.8s var(--ease-out-expo),
        transform 0.8s var(--ease-out-expo);
    transition-delay: 0.3s;
}

body.hero-loaded .ct-anim-kicker {
    opacity: 1;
    transform: translateX(0);
}

/* Phone block fades up */
.ct-phone-block {
    opacity: 0;
    transform: translateY(20px);
    transition:
        opacity 1s var(--ease-out-expo),
        transform 1s var(--ease-out-expo);
    transition-delay: 1.0s;
}

body.hero-loaded .ct-phone-block {
    opacity: 1;
    transform: translateY(0);
}

/* Meta row fades up */
.ct-meta-row {
    opacity: 0;
    transform: translateY(20px);
    transition:
        opacity 1s var(--ease-out-expo),
        transform 1s var(--ease-out-expo);
    transition-delay: 1.2s;
}

body.hero-loaded .ct-meta-row {
    opacity: 1;
    transform: translateY(0);
}

/* Assurances line fades up */
.ct-assurances {
    opacity: 0;
    transform: translateY(20px);
    transition:
        opacity 1s var(--ease-out-expo),
        transform 1s var(--ease-out-expo);
    transition-delay: 1.4s;
}

body.hero-loaded .ct-assurances {
    opacity: 1;
    transform: translateY(0);
}

/* Form panel slides in from right */
.ct-form-inner {
    opacity: 0;
    transform: translateY(30px);
    transition:
        opacity 1.2s var(--ease-out-expo),
        transform 1.2s var(--ease-out-expo);
    transition-delay: 0.5s;
}

body.hero-loaded .ct-form-inner {
    opacity: 1;
    transform: translateY(0);
}

/* Form fields stagger in (direct children only) */
.ct-form > .ct-row,
.ct-form > .ct-field,
.ct-form > .ct-submit {
    opacity: 0;
    transform: translateY(16px);
    transition:
        opacity 0.8s var(--ease-out-expo),
        transform 0.8s var(--ease-out-expo);
}

body.hero-loaded .ct-form > .ct-row,
body.hero-loaded .ct-form > .ct-field,
body.hero-loaded .ct-form > .ct-submit {
    opacity: 1;
    transform: translateY(0);
}

body.hero-loaded .ct-form > .ct-row { transition-delay: 0.9s; }
body.hero-loaded .ct-form > .ct-field:nth-of-type(1) { transition-delay: 1.0s; }
body.hero-loaded .ct-form > .ct-field:nth-of-type(2) { transition-delay: 1.1s; }
body.hero-loaded .ct-form > .ct-field:nth-of-type(3) { transition-delay: 1.2s; }
body.hero-loaded .ct-form > .ct-submit { transition-delay: 1.3s; }

/* Form head (title + intro) fades up */
.ct-form-head {
    opacity: 0;
    transform: translateY(20px);
    transition:
        opacity 1s var(--ease-out-expo),
        transform 1s var(--ease-out-expo);
    transition-delay: 0.7s;
}

body.hero-loaded .ct-form-head {
    opacity: 1;
    transform: translateY(0);
}

/* Map section reveals on scroll */
.ct-map-section {
    opacity: 0;
    transform: translateY(40px);
    transition:
        opacity 1.1s var(--ease-out-expo),
        transform 1.1s var(--ease-out-expo);
}

.ct-map-section.is-visible {
    opacity: 1;
    transform: translateY(0);
}
