/* Design System Variables */
:root {
    --color-bg: #f4f8fa;
    --color-bg-card: #ffffff;
    --color-text-primary: #04142d;
    --color-text-secondary: #4b616b;
    --color-teal: #07295c;
    --color-teal-light: #0f8ca0;
    --color-teal-glow: rgba(15, 140, 160, 0.2);
    --color-teal-dark: #031735;
    --color-orange: #fcb506;
    --color-orange-light: #ffd54f;
    --color-orange-hover: #e5a405;
    --color-orange-dark: #b8860b;
    --color-grid: #e2ebf0;
    --color-border: rgba(7, 41, 92, 0.12);
    --color-blueprint-bg: #061830;
    --color-blueprint-line: #00e5ff;
    --color-blueprint-border: rgba(15, 140, 160, 0.25);
    
    /* Dark Theme Variables for alternating sections */
    --color-bg-dark: #031735;
    --color-bg-card-dark: #061e40;
    --color-text-primary-dark: #ffffff;
    --color-text-secondary-dark: #a5bccc;
    --color-border-dark: rgba(255, 255, 255, 0.08);
    --color-grid-dark: rgba(15, 140, 160, 0.08);
    
    --font-sans: 'Inter', sans-serif;
    --font-title: 'Outfit', sans-serif;
    
    --border-radius-sm: 8px;
    --border-radius-md: 16px;
    --border-radius-lg: 24px;
    
    --shadow-sm: 0 4px 6px -1px rgba(7, 41, 92, 0.05), 0 2px 4px -1px rgba(7, 41, 92, 0.03);
    --shadow-md: 0 10px 15px -3px rgba(7, 41, 92, 0.08), 0 4px 6px -2px rgba(7, 41, 92, 0.04);
    --shadow-lg: 0 20px 25px -5px rgba(7, 41, 92, 0.12), 0 10px 10px -5px rgba(7, 41, 92, 0.06);
    --shadow-glow: 0 0 25px -5px var(--color-teal-light);
    
    /* ----------------------------------------------------------------
       Motion — vocabulaire commun à tout le site
       ----------------------------------------------------------------
       Trois durées et trois courbes, pas davantage : c'est ce qui fait
       qu'une carte, un bouton et un panneau semblent appartenir à la
       même interface. Toute nouvelle animation pioche ici.

       « --transition-base » ne cible plus « all ». Animer « all »
       laisse le navigateur surveiller des propriétés qui déclenchent un
       recalcul de mise en page (width, margin, padding…) : c'était la
       cause des saccades au survol. On ne transitionne que ce qui est
       réellement composé par le GPU, plus les couleurs.
       ---------------------------------------------------------------- */
    --dur-fast: 150ms;    /* réponse tactile : appui, focus */
    --dur-base: 300ms;    /* survol, bascule d'état */
    --dur-slow: 600ms;    /* révélation, tracé, parcours */

    /* Sortie franche : rapide au départ, longue à l'arrivée. C'est la
       courbe « objet qui se pose », celle des révélations et panneaux. */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    /* Symétrique, pour ce qui part ET revient (survol réversible). */
    --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
    /* Léger dépassement, réservé aux confirmations. */
    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

    /* Décalage entre deux éléments frères dans une cascade. */
    --stagger: 70ms;

    --transition-base:
        transform var(--dur-base) var(--ease-in-out),
        opacity var(--dur-base) var(--ease-in-out),
        box-shadow var(--dur-base) var(--ease-in-out),
        background-color var(--dur-base) var(--ease-in-out),
        background-image var(--dur-base) var(--ease-in-out),
        border-color var(--dur-base) var(--ease-in-out),
        color var(--dur-base) var(--ease-in-out),
        filter var(--dur-base) var(--ease-in-out);

    /* Service Step Colors for Hero Graphic */
    --color-step-audit: #0f8ca0;
    --color-step-audit-dark: #0a5864;
    --color-step-conseil: #07295c;
    --color-step-conseil-dark: #031126;
    --color-step-formation: #4f46e5;
    --color-step-formation-dark: #312e81;
    --color-step-dev: #fcb506;
    --color-step-dev-dark: #b88300;
}

/* Reset */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;
    font-size: 16px;
}

/* ====================================================================
   SYSTÈME DE MOTION
   ====================================================================
   Tout ce qui bouge sur le site passe par ce bloc. Deux règles tenues
   partout en dessous :

   1. On n'anime que « transform » et « opacity ». Ce sont les deux
      seules propriétés que le navigateur peut composer sans refaire la
      mise en page ni repeindre : elles tiennent 60 images par seconde
      même sur un téléphone d'entrée de gamme. Animer une hauteur, une
      largeur ou une marge coûte un recalcul complet à chaque image.

   2. Rien ne bouge avant que le JavaScript ait pris la main. La classe
      « js-motion » est posée sur <html> par script.js. Sans elle, tout
      le contenu est visible et immobile : si le script échoue, ne se
      charge pas, ou si le visiteur a désactivé JavaScript, la page
      reste parfaitement lisible. Une animation d'apparition qui laisse
      la page blanche en cas d'erreur est un défaut, pas un effet.
   ==================================================================== */

/* --- Transitions entre pages -----------------------------------------
   Fondu croisé au lieu du flash blanc à chaque navigation. Syntaxe CSS
   native : les navigateurs qui ne la connaissent pas ignorent le bloc
   et naviguent comme avant. Aucun JavaScript, aucune dépendance. */
@view-transition {
    navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 260ms;
    animation-timing-function: var(--ease-in-out);
}

/* --- Révélation au scroll --------------------------------------------
   Posée via l'attribut « data-reveal » dans le HTML, déclenchée par un
   IntersectionObserver dans script.js.

   Le déplacement est volontairement court (14px) et la durée courte
   (500ms) : une révélation qu'on remarque est une révélation ratée. Le
   but est que le contenu semble se poser, pas qu'il fasse un numéro.
   On ne l'applique pas à tout — seulement aux blocs qui gagnent à être
   lus dans l'ordre. */
.js-motion [data-reveal] {
    opacity: 0;
    transform: translate3d(0, 14px, 0);
    transition:
        opacity var(--dur-slow) var(--ease-out),
        transform var(--dur-slow) var(--ease-out);
}

/* Variantes directionnelles, pour les mises en page en deux colonnes où
   le mouvement vertical n'a pas de sens. */
.js-motion [data-reveal="left"]  { transform: translate3d(-20px, 0, 0); }
.js-motion [data-reveal="right"] { transform: translate3d(20px, 0, 0); }
.js-motion [data-reveal="scale"] { transform: scale(0.97); }

.js-motion [data-reveal].is-revealed {
    opacity: 1;
    transform: none;
}

/* Cascade : chaque enfant direct d'un « data-reveal-group » part un cran
   après le précédent. L'index est posé par script.js en variable CSS,
   ce qui évite d'écrire une règle par position. Le décalage est plafonné
   côté script pour qu'une liste de douze éléments ne se termine pas une
   seconde après avoir commencé. */
.js-motion [data-reveal][style*="--reveal-i"] {
    transition-delay: calc(var(--reveal-i) * var(--stagger));
}

/* --- Entrée du héros -------------------------------------------------
   Le seul moment orchestré non déclenché par le visiteur, et il n'a lieu
   qu'une fois, au chargement. Le regard suit l'ordre de lecture :
   badge, titre, sous-titre, boutons. */
.js-motion .hero-content > * {
    opacity: 0;
    transform: translate3d(0, 18px, 0);
    animation: heroEnter 700ms var(--ease-out) forwards;
}

.js-motion .hero-badge    { animation-delay: 80ms; }
.js-motion .hero-title    { animation-delay: 180ms; }
.js-motion .hero-subtitle { animation-delay: 280ms; }
.js-motion .hero-actions  { animation-delay: 380ms; }

@keyframes heroEnter {
    to {
        opacity: 1;
        transform: none;
    }
}

/* Parallaxe du fond de héros : la variable est alimentée par script.js
   au fil du scroll. L'image descend plus lentement que la page, ce qui
   suffit à créer la profondeur — sans canvas ni boucle d'animation
   permanente, donc sans coût sur la batterie. */
body {
    font-family: var(--font-sans);
    background-color: var(--color-bg);
    color: var(--color-text-secondary);
    line-height: 1.6;
    overflow-x: hidden;
    position: relative;
    min-height: 100vh;
}

/* Grid Background Pattern */
.grid-background {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image: 
        linear-gradient(to right, var(--color-grid) 1px, transparent 1px),
        linear-gradient(to bottom, var(--color-grid) 1px, transparent 1px);
    background-size: 40px 40px;
    pointer-events: none;
    z-index: -1;
    opacity: 0.75;
}

/* Reusable Alternating Sections */
.section-light {
    position: relative;
    background-color: var(--color-bg);
    background-image: 
        linear-gradient(to right, var(--color-grid) 1px, transparent 1px),
        linear-gradient(to bottom, var(--color-grid) 1px, transparent 1px);
    background-size: 40px 40px;
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
}

.section-dark {
    position: relative;
    background-color: var(--color-bg-dark);
    background-image: 
        linear-gradient(to right, var(--color-grid-dark) 1px, transparent 1px),
        linear-gradient(to bottom, var(--color-grid-dark) 1px, transparent 1px);
    background-size: 40px 40px;
    border-top: 1px solid var(--color-border-dark);
    border-bottom: 1px solid var(--color-border-dark);
}

/* Layout Utilities */
.container {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 24px;
}

/* Typography */
h1, h2, h3, h4 {
    font-family: var(--font-title);
    color: var(--color-text-primary);
    font-weight: 700;
}

h1 {
    font-size: clamp(2rem, 5vw, 3.25rem);
    line-height: 1.15;
}

h2 {
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    text-align: center;
    margin-bottom: 12px;
}

.section-title {
    position: relative;
    padding-bottom: 16px;
    margin-bottom: 48px;
}

.section-title::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 60px;
    height: 3px;
    background: var(--color-teal-light);
    border-radius: 2px;
}

.section-title.text-left::after {
    left: 0;
    transform: none;
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 14px 28px;
    font-family: var(--font-title);
    font-size: 1rem;
    font-weight: 600;
    border-radius: var(--border-radius-sm);
    text-decoration: none;
    cursor: pointer;
    transition: var(--transition-base);
    border: none;
}

/* Relief façon touche physique : un dégradé glacé en haut du bouton, une
   arête plus sombre en dessous qui lui donne une épaisseur, et un liseré
   clair en haut (inset) qui simule la lumière accrochant le bord supérieur.
   L'arête disparaît sur .btn:active (ligne ~349) : le bouton s'aplatit
   contre la page au lieu de simplement s'assombrir. */
.btn-primary {
    background: linear-gradient(180deg, var(--color-teal-light) 0%, var(--color-teal) 70%);
    color: #ffffff;
    box-shadow:
        var(--shadow-sm),
        0 3px 0 var(--color-teal-dark),
        inset 0 1px 0 rgba(255, 255, 255, 0.25);
}

.btn-primary:hover {
    background: linear-gradient(180deg, var(--color-teal-light) 0%, var(--color-teal) 85%);
    transform: translateY(-2px);
    box-shadow:
        0 6px 20px rgba(15, 140, 160, 0.3),
        0 5px 0 var(--color-teal-dark),
        inset 0 1px 0 rgba(255, 255, 255, 0.3);
}

.btn-secondary {
    background: linear-gradient(180deg, var(--color-orange-light) 0%, var(--color-orange) 70%);
    color: var(--color-text-primary);
    box-shadow:
        var(--shadow-sm),
        0 3px 0 var(--color-orange-dark),
        inset 0 1px 0 rgba(255, 255, 255, 0.4);
}

.btn-secondary:hover {
    background: linear-gradient(180deg, var(--color-orange-light) 0%, var(--color-orange-hover) 85%);
    color: #ffffff;
    transform: translateY(-2px);
    box-shadow:
        0 6px 20px rgba(252, 181, 6, 0.35),
        0 5px 0 var(--color-orange-dark),
        inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

/* --- Réponse à l'appui ------------------------------------------------
   Le survol seul ne suffit pas : il indique qu'un élément est cliquable,
   pas que le clic a été reçu. C'est l'enfoncement qui donne la sensation
   de solidité, et c'est presque toujours ce qui manque à une interface
   qui « fait site web » plutôt que « fait application ».

   Le bouton redescend sous sa position de repos et perd son ombre — il
   s'enfonce dans la page au lieu de flotter au-dessus. La durée est
   volontairement la plus courte du système (--dur-fast, 150ms) : un
   retour à l'appui qui se fait attendre n'est plus un retour.

   Sur mobile, où il n'existe pas de survol, c'est le seul retour visuel
   disponible avant le chargement de la page suivante. */
.btn:active {
    transform: translateY(1px) scale(0.98);
    box-shadow: var(--shadow-sm);
    transition-duration: var(--dur-fast);
}

/* Le focus clavier reprend l'apparence du survol, et y ajoute un contour
   net. Le contour seul ne suffit pas — il signale où l'on se trouve, pas
   que l'élément est la cible d'une action. */
.btn:focus-visible {
    outline: 3px solid var(--color-teal-light);
    outline-offset: 3px;
}

.btn-primary:focus-visible {
    background-color: var(--color-teal-light);
    transform: translateY(-2px);
}

.btn-secondary:focus-visible {
    background-color: var(--color-orange-hover);
    color: #ffffff;
    transform: translateY(-2px);
}

/* Header & Navigation */
.main-header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    background-color: #ffffff;
    border-bottom: 1px solid var(--color-border);
    z-index: 100;
    transition: var(--transition-base);
}

.header-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 80px;
    transition: height var(--dur-base) var(--ease-out);
}

/* En-tête compacté, posé par script.js au-delà de 80px de défilement.
   La barre perd 12 pixels et gagne une ombre : elle cesse d'être une bande
   dans le flux de la page pour devenir une surface qui flotte au-dessus.
   C'est le signal qui dit au visiteur qu'il a quitté le haut de page.
   La hauteur fait exception à la règle « transform et opacity seulement » :
   elle est ici franchie une seule fois, dans un sens puis dans l'autre, et
   non pas à chaque image comme le serait une animation continue. */
.main-header.is-scrolled {
    box-shadow: var(--shadow-md);
    border-bottom-color: transparent;
}

.main-header.is-scrolled .header-container {
    height: 68px;
}

/* Le logo suit la compaction, sans quoi il flotterait dans une barre
   devenue trop basse pour lui. (.logo-img porte déjà --transition-base,
   qui inclut transform.) */
.main-header.is-scrolled .logo-img {
    transform: scale(0.9);
}

.logo {
    display: flex;
    align-items: center;
    text-decoration: none;
}

.logo-img {
    height: 54px;
    width: auto;
    display: block;
    transition: var(--transition-base);
}

.logo:hover .logo-img {
    transform: scale(1.04);
}

.main-nav {
    display: flex;
    align-items: center;
}

.nav-links {
    display: flex;
    align-items: center;
    gap: 32px;
    list-style: none;
}

.nav-link {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    color: var(--color-text-secondary);
    font-weight: 500;
    font-size: 0.95rem;
    padding: 8px 0;
    position: relative;
    transition: var(--transition-base);
}

.nav-link:hover, .nav-link.active {
    color: var(--color-teal);
}

/* Soulignement du lien de navigation.
   Il occupe toute la largeur en permanence et c'est son échelle
   horizontale qui varie, au lieu de sa largeur. Deux raisons : « width »
   force le navigateur à refaire la mise en page à chaque image, là où
   « transform » est composé par le GPU ; et l'origine de l'échelle rend
   le geste lisible — le trait naît du bord gauche et s'y retire. */
.nav-link::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 2px;
    background-color: var(--color-teal-light);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--dur-base) var(--ease-out);
}

.nav-link:hover::after,
.nav-link:focus-visible::after,
.nav-link.active::after {
    transform: scaleX(1);
}

/* Dropdown Menu Styles */
.dropdown {
    position: relative;
}

.dropdown-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
}

.arrow-icon-mini {
    font-size: 0.65rem;
    transition: transform 0.3s ease;
    display: inline-block;
    vertical-align: middle;
}

.dropdown:hover .arrow-icon-mini {
    transform: rotate(180deg);
}

/* Dropdown Menu Box */
.dropdown-menu {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%) translateY(10px);
    width: 280px;
    background: rgba(255, 255, 255, 0.98);
    backdrop-filter: blur(10px);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-sm);
    padding: 10px 0;
    box-shadow: var(--shadow-lg);
    opacity: 0;
    visibility: hidden;
    list-style: none;
    z-index: 1000;
    transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), 
                transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), 
                visibility 0.3s;
}

.dropdown:hover .dropdown-menu {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) translateY(0);
}

/* Dropdown Items styling */
.dropdown-item {
    display: block;
    padding: 10px 20px;
    color: var(--color-text-secondary);
    text-decoration: none;
    font-family: var(--font-sans);
    font-size: 0.9rem;
    font-weight: 500;
    text-align: left;
    transition: var(--transition-base);
}

/* Le décalage vers la droite au survol se fait par « transform » et non
   par « padding-left » : la marge interne déplace le texte en refaisant
   la mise en page de tout l'élément, le transform ne fait que le glisser. */
.dropdown-item:hover {
    color: var(--color-teal-light);
    background-color: rgba(7, 41, 92, 0.03);
    transform: translateX(6px);
}

.dropdown-item.active {
    color: var(--color-teal);
    font-weight: 600;
    background-color: rgba(7, 41, 92, 0.05);
}

.menu-toggle {
    display: none;
    background: none;
    border: none;
    cursor: pointer;
    padding: 10px;
    z-index: 110;
}

.hamburger {
    display: block;
    width: 24px;
    height: 2px;
    background-color: var(--color-text-primary);
    position: relative;
    transition: var(--transition-base);
}

.hamburger::before, .hamburger::after {
    content: '';
    position: absolute;
    width: 24px;
    height: 2px;
    background-color: var(--color-text-primary);
    transition: var(--transition-base);
}

.hamburger::before { top: -6px; }
.hamburger::after { bottom: -6px; }

/* Hero Section */
.hero-section {
    padding: 160px 0 100px;
    min-height: 90vh;
    display: flex;
    align-items: center;
    position: relative;
    overflow: hidden;
    z-index: 1; /* Create stacking context for canvas and background image */
}

.hero-bg-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    /* §16 — Repli PNG d'abord, puis WebP pour les navigateurs qui le gèrent.
       Le second bloc écrase le premier là où image-set() est reconnu. */
    background-image: url('assets/bg-bandeau-heros.png');
    background-image: image-set(url('assets/bg-bandeau-heros.webp') type('image/webp'),
                                url('assets/bg-bandeau-heros.png') type('image/png'));
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    z-index: -3;
    pointer-events: none;
}

/* Calque de particules en incrustation sur la photo (assets/hero-particles.js).
   Le conteneur naît transparent et ne devient visible qu'une fois la
   première image effectivement dessinée — même contrat que .hero-3d
   ci-dessous, pour la même raison : sans JavaScript ou sur une machine trop
   lente, la photo reste seule et intacte, sans état intermédiaire vide.

   Empilement : au-dessus de la photo (-3), sous le voile de lisibilité (-1)
   et le contenu du bandeau (2) — le calque ne doit jamais passer devant le
   texte. */
.hero-particles {
    position: absolute;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    overflow: hidden;
    opacity: 0;
    /* Le fond du canvas, presque noir une fois les traînées estompées,
       devient neutre en mode « écran » : seules les particules lumineuses
       remontent sur la photo. Voir assets/hero-particles.js. */
    mix-blend-mode: screen;
    transition: opacity calc(var(--dur-slow) * 2) var(--ease-out);
    contain: layout paint;
}

.hero-particles canvas {
    display: block;
    width: 100%;
    height: 100%;
    -webkit-mask-image: linear-gradient(to bottom,
        transparent 0%, #000 15%, #000 85%, transparent 100%);
    mask-image: linear-gradient(to bottom,
        transparent 0%, #000 15%, #000 85%, transparent 100%);
}

/* Incrustation légère : la photo doit rester lisible au travers. */
.hero-particles--actif {
    opacity: 0.6;
}

/* ====================================================================
   FONDS 3D DES BANDEAUX HÉROS
   ====================================================================
   Le conteneur du canvas piloté par assets/hero3d/core.js. Il est posé
   sur six pages : accueil, conseil, formation, applications web,
   rendez-vous et questionnaire d'audit.

   Le point important est l'opacité de départ. Le conteneur naît
   transparent et ne devient visible que lorsque le script ajoute
   « .hero-3d--actif », ce qu'il ne fait qu'après avoir effectivement
   rendu sa première image. Tant que rien n'est rendu — WebGL absent,
   script non chargé, machine trop faible, contexte graphique perdu —
   c'est le fond d'origine (quadrillage, halo, image) qui reste visible,
   seul et intact. Il n'y a donc jamais d'état intermédiaire vide, et le
   repli ne demande aucune règle supplémentaire : il est l'état par
   défaut.

   La durée du fondu est dérivée du vocabulaire de mouvement défini en
   tête de ce fichier plutôt que posée en dur. Deux fois --dur-slow :
   l'apparition d'un fond doit être plus lente que celle d'un élément
   d'interface, sans quoi elle attire l'œil au lieu de s'installer.
   ==================================================================== */
.hero-3d {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
    opacity: 0;
    transition: opacity calc(var(--dur-slow) * 2) var(--ease-out);
    /* Le canvas se redessine en continu tant que le bandeau est à
       l'écran. Sans confinement, le navigateur réévalue à chaque image
       si ce repaint peut affecter la mise en page du reste de la page. */
    contain: layout paint;
}

/* Le masque est posé sur le canvas et non sur le conteneur, parce que le
   conteneur porte aussi le fond opaque de l'accueil et du questionnaire : le
   masquer laisserait réapparaître l'image ou le dégradé d'origine en haut et
   en bas. Ici, seule la scène s'estompe.

   Sans ce dégradé, la géométrie est tranchée net par le bord du bandeau —
   des colonnes coupées à mi-hauteur, qui se lisent comme une erreur de
   cadrage plutôt que comme une profondeur. La scène doit sortir du champ, pas
   s'y arrêter. */
.hero-3d canvas {
    display: block;
    width: 100%;
    height: 100%;
    /* Les bornes sont en pourcentage, donc proportionnelles à la hauteur du
       bandeau — et c'est là qu'il faut être prudent. Réglées pour l'accueil,
       qui fait plus de huit cents pixels, elles mangeaient près de la moitié
       du bandeau de la page rendez-vous, qui en fait cinq cents : la partie
       basse du cadran y disparaissait purement et simplement. Les valeurs
       ci-dessous sont les plus serrées qui laissent encore l'estompe faire son
       travail sur le plus haut des six. */
    -webkit-mask-image: linear-gradient(to bottom,
        transparent 0%, #000 9%, #000 87%, transparent 100%);
    mask-image: linear-gradient(to bottom,
        transparent 0%, #000 9%, #000 87%, transparent 100%);
}

/* Le voile. Un fond animé qui passe derrière un titre finit toujours par
   entrer en concurrence avec lui : c'est le défaut le plus courant du genre,
   et il ne se corrige pas en composant mieux la scène, parce qu'elle bouge.
   On assombrit donc la zone du texte, en dégradé pour que la limite ne se
   voie pas. Le fond reste entièrement lisible sur les bords, là où il n'a
   rien à gêner. */
.hero-3d::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(ellipse 62% 78% at 50% 47%,
        rgba(3, 23, 53, 0.74) 0%,
        rgba(3, 23, 53, 0.40) 46%,
        rgba(3, 23, 53, 0) 78%);
}

.hero-3d--actif {
    opacity: 1;
}

/* Deux bandeaux ne plaçaient pas leur contenu au-dessus du fond. Sans
   « position », le texte reste dans le flux normal, et un conteneur positionné
   à z-index 0 — ce qu'est .hero-3d — se peint par-dessus lui : sur le
   questionnaire, le titre disparaissait purement et simplement derrière le
   canvas. Les trois autres pages de service portaient déjà la règle dans leur
   feuille dédiée. */
.rdv-hero .container,
.questionnaire-hero .container {
    position: relative;
    z-index: 1;
}

/* Voile de lisibilité sur la photo de l'accueil. L'accueil est le seul
   bandeau dont le texte n'est pas centré : il occupe la colonne de gauche, et
   le voile la suit plutôt que le centre du cadre, ce qui laisse la moitié
   droite de la photo entièrement dégagée. */
.hero-section::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(ellipse 56% 86% at 27% 50%,
        rgba(2, 14, 36, 0.80) 0%,
        rgba(2, 14, 36, 0.42) 44%,
        rgba(2, 14, 36, 0) 76%);
}

/* Le bandeau du questionnaire d'audit demande deux corrections que les cinq
   autres ne demandent pas.

   D'abord, il n'était pas positionné. Un conteneur en « inset: 0 » se
   rattache alors au bloc englobant initial et s'étale sur la hauteur du
   document entier : le fond couvrait toute la page, et l'observateur qui
   arrête la boucle au défilement ne la voyait jamais sortir de l'écran. Le
   bandeau n'est donc pas seulement mal cadré dans ce cas — il ne s'arrête
   jamais de tourner. Deux propriétés règlent les deux symptômes.

   Ensuite, ce bandeau est le seul dont le fond d'origine soit un dégradé
   turquoise clair, hérité d'une autre charte. Le brouillard des scènes fond
   vers le bleu nuit des cinq autres pages : superposé au turquoise, il ferait
   une tache sombre au milieu du dégradé. La scène pose donc son propre fond,
   comme sur l'accueil, et le dégradé d'origine reste le repli. */
.questionnaire-hero {
    position: relative;
    overflow: hidden;
}

.questionnaire-hero .hero-3d.hero-3d--actif {
    background: linear-gradient(135deg, #06284a 0%, #041c3c 55%, #02122b 100%);
}

.hero-container {
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    gap: 48px;
    align-items: center;
    position: relative;
    z-index: 2;
}

.hero-content {
    display: flex;
    flex-col: column;
    flex-direction: column;
    align-items: flex-start;
}

.hero-badge {
    background-color: rgba(15, 140, 160, 0.1);
    color: var(--color-teal-light);
    padding: 6px 16px;
    border-radius: 50px;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 1.5px;
    margin-bottom: 24px;
    border: 1px solid rgba(0, 229, 255, 0.35);
    box-shadow: 0 0 15px rgba(0, 229, 255, 0.2);
}

.hero-title {
    margin-bottom: 24px;
    letter-spacing: -0.5px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: flex-start;
}

.hero-title-small {
    font-size: clamp(1.75rem, 4.5vw, 2.5rem);
    font-weight: 700;
    color: var(--color-text-primary-dark);
    letter-spacing: -0.5px;
}

.hero-title-large {
    font-size: clamp(2.2rem, 5vw, 3.5rem);
    font-weight: 800;
    color: rgba(255, 255, 255, 0.92);
    line-height: 1.1;
    letter-spacing: -1px;
}

.hero-subtitle {
    font-size: 1.15rem;
    color: var(--color-text-secondary);
    margin-bottom: 40px;
    max-width: 540px;
}

.hero-actions {
    display: flex;
    gap: 16px;
    align-items: flex-end;
}

.hero-visual {
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
}

/* Le visuel SVG du héros (.hero-svg) et ses quatre calques flottants
   (.layer-1 à .layer-4, animations floatUp/floatDown) ont été retirés :
   aucune de ces classes n'existait plus dans le HTML depuis que le héros
   est passé sur une image de fond (.hero-bg-image, plus haut dans ce
   fichier), fixe et sans effet de profondeur ajouté. */

/* Intro Teaser Section */
.intro-teaser-section {
    padding: 140px 0;
    background-color: #e3f2fd;
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
    position: relative;
    z-index: 10;
}

.intro-teaser-grid {
    display: grid;
    grid-template-columns: 1fr 1.2fr;
    gap: 60px;
    align-items: center;
}

.intro-tagline-badge {
    display: inline-block;
    color: var(--color-teal-light);
    font-family: var(--font-title);
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 2px;
    margin-bottom: 16px;
    position: relative;
    padding-left: 28px;
    text-transform: uppercase;
}

.intro-tagline-badge::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 2px;
    background-color: var(--color-teal-light);
}

.intro-teaser-title {
    font-size: clamp(1.8rem, 3.5vw, 2.3rem);
    line-height: 1.3;
    color: var(--color-text-primary);
    margin-bottom: 0;
    font-weight: 800;
}

.intro-teaser-right {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
}

.intro-teaser-desc {
    font-size: 1.125rem;
    line-height: 1.8;
    color: var(--color-text-secondary);
    max-width: 450px;
}

.intro-teaser-desc strong {
    color: var(--color-text-primary);
    font-weight: 700;
}

.intro-teaser-illustration {
    width: 100%;
    max-width: 420px;
    margin-top: 40px;
}

.intro-teaser-illustration svg {
    display: block;
    width: 100%;
    height: auto;
}

.diag-center-glow {
    animation: diagPulse 3.5s ease-in-out infinite;
    transform-origin: 236px 130px;
}

@keyframes diagPulse {
    0%, 100% {
        opacity: 0.22;
        transform: scale(1);
    }
    50% {
        opacity: 0.4;
        transform: scale(1.12);
    }
}

.diag-label {
    font-family: var(--font-title);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    fill: var(--color-teal);
}

.diag-label-accent {
    fill: var(--color-orange);
}

@media (max-width: 992px) {
    .intro-teaser-grid {
        grid-template-columns: 1fr;
        gap: 32px;
    }
    .intro-teaser-section {
        padding: 80px 0;
    }
    .intro-teaser-illustration {
        max-width: 380px;
        margin-left: auto;
        margin-right: auto;
    }
}

@media (prefers-reduced-motion: reduce) {
    .diag-center-glow {
        animation: none;
    }
}

/* Services Section */
.services-section {
    padding: 100px 0;
    position: relative;
}

.services-diagram-container {
    position: relative;
    margin-top: 60px;
    width: 100%;
    min-height: 600px;
}

.services-circuit-svg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 1;
}

.services-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 80px 40px;
    position: relative;
    z-index: 2;
}

/* Chronological Tree Layout for Cards */
#card-audit {
    grid-column: 2;
    grid-row: 1;
    max-width: 360px;
    justify-self: center;
}

#card-conseil {
    grid-column: 2;
    grid-row: 2;
    max-width: 360px;
    justify-self: center;
}

#card-formation {
    grid-column: 1;
    grid-row: 3;
}

#card-logiciel-ia {
    grid-column: 2;
    grid-row: 3;
}

#card-automatisation {
    grid-column: 3;
    grid-row: 3;
}

/* Service Step Badge styling */
.service-step-badge {
    position: absolute;
    top: 14px;
    right: 14px;
    z-index: 10;
    background-color: #eaeaea;
    color: var(--color-teal);
    font-size: 0.7rem;
    font-weight: 700;
    padding: 3px 10px;
    border-radius: 50px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border: 1px solid rgba(7, 41, 92, 0.1);
    transition: var(--transition-base);
}

.service-card:hover .service-step-badge,
.service-card:focus-within .service-step-badge {
    background-color: var(--color-teal-light);
    color: #ffffff;
    border-color: var(--color-teal-light);
}

/* Les trois modalités de mise en œuvre sont des branches parallèles, pas une
   quatrième, cinquième et sixième étape : leur pastille se distingue donc de
   celles d'« Étape 1 » et « Étape 2 », qui, elles, se suivent. */
.service-step-badge.is-branch {
    background-color: transparent;
    color: var(--color-text-secondary);
    border-style: dashed;
}

.service-card:hover .service-step-badge.is-branch,
.service-card:focus-within .service-step-badge.is-branch {
    background-color: transparent;
    color: var(--color-teal-light);
    border-color: var(--color-teal-light);
}

.service-badge-free {
    position: absolute;
    top: 14px;
    left: 14px;
    z-index: 10;
    background-color: var(--color-orange);
    color: var(--color-text-primary);
    font-size: 0.7rem;
    font-weight: 800;
    padding: 3px 10px;
    border-radius: 50px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border: 1px solid rgba(252, 181, 6, 0.3);
    box-shadow: 0 2px 8px rgba(252, 181, 6, 0.2);
    transition: var(--transition-base);
}

.service-card:hover .service-badge-free,
.service-card:focus-within .service-badge-free {
    background-color: var(--color-orange-hover);
    color: #ffffff;
    border-color: rgba(252, 181, 6, 0.5);
    box-shadow: 0 4px 12px rgba(252, 181, 6, 0.35);
}


/* Service Card Styles */
.service-card {
    position: relative;
    background-color: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-md);
    padding: 36px 24px 28px 24px;
    text-align: center;
    box-shadow: var(--shadow-sm);
    transition: var(--transition-base);
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
}

/* Le survol combine deux mouvements de durées différentes : la carte se
   soulève vite (300ms, via --transition-base) pendant que l'image zoome
   lentement (600ms). Quand les deux durent le même temps, la carte et son
   image forment un bloc qui saute d'un coup ; en les désynchronisant, la
   carte réagit immédiatement au geste et l'image donne la profondeur
   derrière elle.
   Le soulèvement est ramené de 8 à 6 pixels : avec l'ombre portée plus
   marquée, 8 pixels faisaient décoller la carte au lieu de la désigner. */
.service-card:hover,
.service-card:focus-within {
    transform: translateY(-6px);
    border-color: var(--color-teal-light);
    box-shadow: var(--shadow-lg), 0 0 15px rgba(2, 128, 144, 0.15);
}

.service-image-wrapper {
    width: 100%;
    height: 160px;
    border-radius: var(--border-radius-sm);
    overflow: hidden;
    margin-bottom: 24px;
    border: 1px solid var(--color-border);
    position: relative;
}

.service-card-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}

.service-card:hover .service-card-img,
.service-card:focus-within .service-card-img {
    transform: scale(1.06);
}

.service-icon-wrapper {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    background-color: rgba(7, 41, 92, 0.05);
    color: var(--color-teal);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 20px;
    transition: var(--transition-base);
}

.service-card:hover .service-icon-wrapper {
    background-color: var(--color-teal-light);
    color: #ffffff;
    transform: scale(1.1);
}

.service-icon {
    width: 28px;
    height: 28px;
}

.service-card .service-title {
    font-size: 1.15rem;
    margin-bottom: 12px;
    letter-spacing: 0.5px;
    transition: var(--transition-base);
}

.service-card:hover .service-title {
    color: var(--color-teal-light);
}

.service-card .service-description {
    font-size: 0.9rem;
    color: var(--color-text-secondary);
}

/* Service Card Action Link Button */
.btn-card-link {
    margin-top: 20px;
    display: inline-block;
    padding: 8px 20px;
    font-family: var(--font-title);
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--color-teal-light);
    background-color: transparent;
    border: 1px solid var(--color-teal-light);
    border-radius: var(--border-radius-sm);
    text-decoration: none;
    transition: var(--transition-base);
    z-index: 5;
}

.service-card:hover .btn-card-link {
    background-color: var(--color-teal-light);
    color: #ffffff;
    box-shadow: 0 4px 12px rgba(15, 140, 160, 0.25);
}

/* CTA mis en avant de la carte Audit : mêmes effets que le bouton du hero, en bleu clair */
.btn-card-cta {
    margin-top: 20px;
    padding: 12px 24px;
    font-size: 0.9375rem;
    background-color: var(--color-teal-light);
    color: #ffffff;
    position: relative;
    overflow: hidden;
    z-index: 5;
    animation: pulse-glow-teal 2.5s ease-in-out infinite;
}

.btn-card-cta::before {
    content: "";
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.3), transparent);
    transform: rotate(45deg);
    animation: shimmer-sweep 3s infinite;
}

.btn-card-cta:hover,
.service-card:hover .btn-card-cta {
    background-color: var(--color-teal);
}

@keyframes pulse-glow-teal {
    0%, 100% {
        box-shadow:
            0 6px 20px rgba(15, 140, 160, 0.35),
            0 0 15px rgba(15, 140, 160, 0.3),
            0 3px 0 var(--color-teal),
            inset 0 1px 0 rgba(255, 255, 255, 0.3);
        transform: translateY(-2px);
    }
    50% {
        box-shadow:
            0 6px 30px rgba(15, 140, 160, 0.5),
            0 0 25px rgba(15, 140, 160, 0.4),
            0 3px 0 var(--color-teal),
            inset 0 1px 0 rgba(255, 255, 255, 0.3);
        transform: translateY(-4px);
    }
}

@keyframes shimmer-sweep {
    0% {
        left: -200%;
    }
    100% {
        left: 200%;
    }
}

/* CTA principal du bandeau d'accueil : même reflet animé que le CTA de la
   carte Audit, décliné en orange pour rester cohérent avec .btn-secondary. */
.btn-hero-cta,
.btn-hero-cta:hover,
.btn-hero-cta:focus-visible {
    color: #ffffff;
    text-shadow: 0 0 6px rgba(140, 90, 0, 0.45);
}

.btn-hero-cta,
.btn-hero-cta:hover {
    box-shadow: none;
}

.btn-hero-cta {
    position: relative;
    overflow: hidden;
    z-index: 5;
}

/* CTA secondaire du bandeau d'accueil ("Découvrir nos services") : sans
   ombre portée, contrairement au .btn-primary standard. */
.btn-hero-discover,
.btn-hero-discover:hover {
    box-shadow: none;
}

.btn-hero-cta::before {
    content: "";
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.35), transparent);
    transform: rotate(45deg);
    animation: shimmer-sweep 3s infinite;
}

@keyframes pulse-glow-orange {
    0%, 100% {
        box-shadow:
            var(--shadow-sm),
            0 0 15px rgba(252, 181, 6, 0.3),
            0 3px 0 var(--color-orange-dark),
            inset 0 1px 0 rgba(255, 255, 255, 0.4);
    }
    50% {
        box-shadow:
            0 6px 20px rgba(252, 181, 6, 0.4),
            0 0 25px rgba(252, 181, 6, 0.45),
            0 3px 0 var(--color-orange-dark),
            inset 0 1px 0 rgba(255, 255, 255, 0.4);
    }
}


/* --- Tracé progressif du parcours de services -------------------------
   C'est le moment signature de la page d'accueil. Les connecteurs ne sont
   pas simplement affichés : ils se dessinent dans l'ordre du parcours
   qu'ils décrivent — d'abord le tronc « audit vers conseil », puis les
   trois branches vers les réalisations. Le schéma se raconte au lieu de
   s'afficher, et le visiteur comprend qu'il y a un ordre avant même
   d'avoir lu les intitulés.

   La mécanique : chaque tracé porte « pathLength="1" » dans le HTML, ce
   qui normalise sa longueur à 1 quelle que soit sa géométrie. Un tiret de
   longueur 1 décalé de 1 laisse le tracé entièrement hors champ ; ramener
   le décalage à 0 le fait apparaître de son début vers sa fin. Aucune
   mesure JavaScript n'est nécessaire, et la règle vaut pour une ligne
   droite comme pour une courbe de Bézier. */
.js-motion .services-circuit-svg path:not(.active-flow-path) {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    transition: stroke-dashoffset 900ms var(--ease-out);
}

.js-motion .services-diagram-container.is-revealed .services-circuit-svg path:not(.active-flow-path) {
    stroke-dashoffset: 0;
}

/* Le tronc part immédiatement, les branches 400ms plus tard : elles ne
   peuvent pousser que depuis un tronc déjà tracé. Le décalage n'est pas
   décoratif, il respecte la logique du schéma. */
.js-motion .services-diagram-container.is-revealed #path-conseil-formation,
.js-motion .services-diagram-container.is-revealed #path-conseil-logiciel-ia,
.js-motion .services-diagram-container.is-revealed #path-conseil-automatisation {
    transition-delay: 400ms;
}

/* Variante « déclencheur seul » : l'élément ne se révèle pas lui-même, il
   sert uniquement de repère à l'observateur pour animer ce qu'il contient.
   Sans cela, le conteneur du schéma serait à la fois en train d'apparaître
   en fondu et de dessiner ses tracés — deux mouvements concurrents sur le
   même objet, qui se brouillent l'un l'autre. */
.js-motion [data-reveal="trigger"] {
    opacity: 1;
    transform: none;
}

/* Animated SVG Elements inside Services */
.active-flow-path {
    stroke-dasharray: 12 50;
    stroke-dashoffset: 0;
    animation: flowCircuit 4s linear infinite;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.service-card-active + .services-circuit-svg .active-flow-path,
.active-flow-path.illuminated {
    opacity: 1;
}

@keyframes flowCircuit {
    to {
        stroke-dashoffset: -62;
    }
}

.pulse-circle {
    animation: pulseGlow 2s infinite;
}

@keyframes pulseGlow {
    0%, 100% { transform: scale(1); opacity: 0.8; }
    50% { transform: scale(1.2); opacity: 1; filter: drop-shadow(0 0 8px var(--color-teal-light)); }
}

.rotate-circle {
    transform-origin: 500px 300px;
    animation: rotateHub 20s linear infinite;
}

@keyframes rotateHub {
    to { transform: rotate(360deg); }
}



/* Contact Section */
/* CTA de fin de page d'accueil, à la place de l'ancien formulaire de
   contact intégré : elle renvoie vers l'audit gratuit (l'action à plus
   forte valeur) et vers la page Contact dédiée. */
.home-audit-cta {
    padding: 100px 0;
    background-color: #e3f2fd;
    border-top: 1px solid var(--color-border);
    text-align: center;
}

.home-audit-cta .cta-box {
    max-width: 700px;
    margin: 0 auto;
}

.home-audit-cta .cta-box p {
    font-size: 1.1rem;
    color: var(--color-text-secondary);
    margin: 16px 0 30px;
    line-height: 1.6;
}

.home-audit-cta .cta-buttons {
    display: flex;
    justify-content: center;
    gap: 20px;
    flex-wrap: wrap;
}

.contact-section {
    padding: 100px 0;
    border-top: 1px solid var(--color-border);
}

.contact-container {
    display: grid;
    grid-template-columns: 0.95fr 1.05fr;
    gap: 60px;
}

.contact-info-column {
    display: flex;
    flex-direction: column;
}

.contact-text {
    font-size: 1.1rem;
    margin-bottom: 32px;
}

.contact-details {
    display: flex;
    flex-direction: column;
    gap: 24px;
    margin-bottom: 40px;
}

.contact-detail-item {
    display: flex;
    gap: 16px;
    align-items: flex-start;
}

.detail-icon {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background-color: rgba(7, 41, 92, 0.05);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
}

.contact-map {
    border-radius: var(--border-radius-md);
    overflow: hidden;
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-md);
}

.contact-map iframe {
    display: block;
    width: 100%;
    height: 320px;
    border: 0;
}

.contact-form-column {
    position: relative;
}

.contact-form {
    background-color: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-md);
    padding: 40px;
    box-shadow: var(--shadow-md);
    transition: var(--transition-base);
}

/* Honeypot anti-spam field - completely hidden from human view */
.form-group-hp {
    position: absolute !important;
    left: -9999px !important;
    top: -9999px !important;
    width: 1px !important;
    height: 1px !important;
    overflow: hidden !important;
    opacity: 0 !important;
    pointer-events: none !important;
}

.form-group {
    display: flex;
    flex-direction: column;
    margin-bottom: 24px;
    position: relative;
}

.form-group label {
    font-family: var(--font-title);
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--color-text-primary);
    margin-bottom: 8px;
}

.form-group input, .form-group textarea {
    font-family: var(--font-sans);
    font-size: 0.95rem;
    padding: 12px 16px;
    border: 1.5px solid var(--color-border);
    border-radius: var(--border-radius-sm);
    outline: none;
    transition: var(--transition-base);
    background-color: var(--color-bg);
}

.form-group input:focus, .form-group textarea:focus {
    border-color: var(--color-teal-light);
    background-color: #ffffff;
    box-shadow: 0 0 0 3px rgba(15, 140, 160, 0.1);
}

/* Validation styling */
.form-group.invalid input, .form-group.invalid textarea {
    border-color: #e76f51;
    box-shadow: 0 0 0 3px rgba(231, 111, 81, 0.1);
}

.error-message {
    font-size: 0.75rem;
    color: #e76f51;
    margin-top: 4px;
    display: none;
}

.form-group.invalid .error-message {
    display: block;
}

.btn-submit {
    width: 100%;
    gap: 8px;
}

/* --- Envoi en cours ---------------------------------------------------
   Un disque qui tourne, ajouté devant le texte du bouton pendant la
   requête. C'est le seul endroit du site où une animation en boucle est
   justifiée : elle dure exactement le temps de l'attente et répond à la
   question que le visiteur se pose à cet instant — « est-ce que c'est
   parti ? ». Elle s'arrête d'elle-même quand la classe est retirée.

   Le disque est dessiné en CSS plutôt qu'importé : une image de plus à
   télécharger au moment précis où le réseau est occupé par l'envoi du
   formulaire serait un mauvais calcul. */
.btn-submit.is-sending {
    cursor: progress;
}

.btn-submit.is-sending::before {
    content: '';
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #ffffff;
    animation: btnSpin 700ms linear infinite;
    flex: none;
}

@keyframes btnSpin {
    to { transform: rotate(360deg); }
}

/* Avec la réduction des animations, le disque ne tourne pas — mais il
   doit rester visible : c'est le seul signe que l'envoi est en cours.
   On le remplace par un repère statique plutôt que de le supprimer. */
@media (prefers-reduced-motion: reduce) {
    .btn-submit.is-sending::before {
        animation: none;
        border-color: rgba(255, 255, 255, 0.6);
        border-top-color: #ffffff;
    }
}

.arrow-icon {
    width: 18px;
    height: 18px;
    transition: var(--transition-base);
}

.btn-submit:hover .arrow-icon {
    transform: translateX(4px);
}

/* Success & Error Cards */
.form-success-message,
.form-error-message {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-md);
    padding: 40px;
    box-shadow: var(--shadow-md);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    opacity: 0;
    pointer-events: none;
    transform: scale(0.95);
    transition: var(--transition-base);
    z-index: 5;
}

.form-success-message.visible,
.form-error-message.visible {
    opacity: 1;
    pointer-events: auto;
    transform: scale(1);
}

.success-icon,
.error-icon {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 24px;
}

.success-icon {
    background-color: rgba(15, 140, 160, 0.1);
    color: var(--color-teal-light);
    font-size: 2rem;
    font-weight: 700;
    animation: pulseSuccess 420ms var(--ease-spring) both;
}

.error-icon {
    background-color: rgba(231, 111, 81, 0.1);
    color: #e76f51;
    font-size: 2rem;
    font-weight: 700;
    animation: pulseError 320ms var(--ease-out) both;
}

/* Les deux icônes battaient en boucle (« 2s infinite ») tant que le
   message restait affiché. Une pulsation qui ne s'arrête jamais cesse
   très vite d'attirer l'attention pour devenir une gêne : l'œil y revient
   sans cesse alors que l'information a déjà été lue, et le mouvement
   continue de consommer des ressources pendant que la personne lit le
   texte à côté.

   Une seule impulsion suffit. Elle marque l'arrivée du message — c'est
   son seul travail — puis s'efface. La courbe à léger dépassement donne
   à la confirmation le ressort qui lui convient ; l'erreur, elle, reste
   sur une courbe neutre : on ne met pas d'entrain dans l'annonce d'un
   échec. */
@keyframes pulseSuccess {
    from { transform: scale(0.8); opacity: 0; }
    to   { transform: scale(1);   opacity: 1; }
}

@keyframes pulseError {
    from { transform: scale(0.92); opacity: 0; }
    to   { transform: scale(1);    opacity: 1; }
}

.form-success-message h3 {
    font-size: 1.5rem;
    margin-bottom: 12px;
}

.form-error-message h3 {
    font-size: 1.5rem;
    margin-bottom: 12px;
    color: #e76f51;
}

.form-error-message p {
    margin-bottom: 24px;
}

.form-error-message .btn-retry {
    padding: 10px 24px;
    font-size: 0.9rem;
}

/* Footer Section */
.main-footer {
    background-color: var(--color-teal-dark);
    color: rgba(255, 255, 255, 0.7);
    padding: 80px 0 30px;
    border-top: 1px solid rgba(255, 255, 255, 0.05);
}

.footer-container {
    display: grid;
    grid-template-columns: 1.2fr 0.8fr;
    gap: 60px;
    margin-bottom: 60px;
}

.footer-brand .logo-text {
    color: #ffffff;
    display: inline-block;
    margin-bottom: 20px;
    font-family: var(--font-title);
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.5px;
    line-height: 1;
}

.footer-brand .logo-text .logo-i {
    color: var(--color-orange);
}

.footer-brand .logo-text .logo-a {
    color: var(--color-teal-light);
}

.footer-brand p {
    max-width: 360px;
    font-size: 0.95rem;
}

/* Liens réseaux sociaux : styles prêts pour le bloc .footer-social du pied de
   page, actuellement commenté dans les pages tant que les comptes n'existent pas. */
.footer-social {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 10px 20px;
    margin-top: 24px;
}

.footer-social a {
    color: rgba(255, 255, 255, 0.6);
    text-decoration: none;
    font-size: 0.9rem;
    transition: var(--transition-base);
}

.footer-social a:hover {
    color: var(--color-orange);
}

.footer-links-container {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 40px;
}

.footer-col h4 {
    color: #ffffff;
    font-size: 1rem;
    margin-bottom: 24px;
}

.footer-col ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.footer-col ul a {
    color: rgba(255, 255, 255, 0.6);
    text-decoration: none;
    font-size: 0.9rem;
    transition: var(--transition-base);
}

.footer-col ul a:hover {
    color: var(--color-orange);
    transform: translateX(4px);
}

.footer-bottom {
    border-top: 1px solid rgba(255, 255, 255, 0.05);
    padding-top: 30px;
    text-align: center;
    font-size: 0.85rem;
    color: rgba(255, 255, 255, 0.45);
}



/* ==========================================================================
   Dark Section Styling Overrides (Alternating Theme)
   ========================================================================== */

/* Dark Sections Typography & Titles */
.section-dark h1,
.section-dark h2,
.section-dark h3,
.section-dark h4,
.section-dark .section-title {
    color: var(--color-text-primary-dark);
}
.section-dark .section-subtitle-text,
.section-dark p {
    color: var(--color-text-secondary-dark);
}

/* Services Section in Dark Theme */
.section-dark .service-card {
    background-color: var(--color-bg-card-dark);
    border: 1px solid var(--color-border-dark);
}
.section-dark .service-card:hover {
    border-color: var(--color-teal-light);
    box-shadow: var(--shadow-lg), 0 0 20px rgba(15, 140, 160, 0.35);
}
.section-dark .service-image-wrapper {
    border-color: var(--color-border-dark);
}
.section-dark .service-title {
    color: var(--color-text-primary-dark);
}
.section-dark .service-card:hover .service-title {
    color: var(--color-teal-light);
}
.section-dark .service-description {
    color: var(--color-text-secondary-dark);
}
.section-dark .service-icon-wrapper {
    background-color: rgba(255, 255, 255, 0.04);
    color: var(--color-teal-light);
}
.section-dark .service-card:hover .service-icon-wrapper {
    background-color: var(--color-teal-light);
    color: #ffffff;
}
.section-dark .service-step-badge {
    background-color: #eaeaea;
    color: var(--color-teal);
    border: 1px solid rgba(7, 41, 92, 0.1);
}
.section-dark .service-card:hover .service-step-badge {
    background-color: rgba(255, 255, 255, 0.25);
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.35);
}
/* Services Circuit Connectors for Dark Theme */
.section-dark .services-circuit-svg path {
    stroke: rgba(255, 255, 255, 0.08) !important;
}
.section-dark .services-circuit-svg path.active-flow-path {
    stroke: var(--color-teal-light) !important;
}

/* Hero Section in Dark Theme */
.section-dark .hero-subtitle {
    color: var(--color-text-secondary-dark);
}

/* Contact Section in Dark Theme */
.section-dark .contact-text {
    color: var(--color-text-secondary-dark);
}
.section-dark .contact-detail-item strong {
    color: var(--color-text-primary-dark);
}
.section-dark .contact-detail-item p {
    color: var(--color-text-secondary-dark);
}
.section-dark .detail-icon {
    background-color: rgba(255, 255, 255, 0.05);
    color: var(--color-teal-light);
}

.section-dark .contact-form {
    background-color: var(--color-bg-card-dark);
    border: 1px solid var(--color-border-dark);
}
.section-dark .form-group label {
    color: var(--color-text-primary-dark);
}
.section-dark .form-group input, 
.section-dark .form-group textarea {
    background-color: rgba(3, 23, 53, 0.5);
    border: 1.5px solid var(--color-border-dark);
    color: #ffffff;
}
.section-dark .form-group input:focus, 
.section-dark .form-group textarea:focus {
    border-color: var(--color-teal-light);
    background-color: rgba(3, 23, 53, 0.8);
    box-shadow: 0 0 0 3px rgba(15, 140, 160, 0.25);
}
.section-dark .form-group.invalid input,
.section-dark .form-group.invalid textarea {
    border-color: #e76f51;
    box-shadow: 0 0 0 3px rgba(231, 111, 81, 0.25);
}
.section-dark .form-success-message {
    background-color: var(--color-bg-card-dark);
    border: 1px solid var(--color-border-dark);
}
.section-dark .form-success-message h3 {
    color: var(--color-text-primary-dark);
}
.section-dark .form-success-message p {
    color: var(--color-text-secondary-dark);
}

/* ==========================================================================
   Avantages & Infographics Section Styles
   ========================================================================== */
#avantages {
    padding: 100px 0;
}

.avantages-container {
    display: grid;
    grid-template-columns: 1.15fr 0.85fr;
    gap: 48px;
    align-items: stretch;
    margin-top: 60px;
}

/* Blueprint Column */
.avantages-blueprint {
    background-color: var(--color-blueprint-bg);
    border: 2px dashed var(--color-blueprint-border);
    border-radius: var(--border-radius-md);
    padding: 36px;
    display: flex;
    flex-direction: column;
    position: relative;
    box-shadow: inset 0 0 30px rgba(0, 229, 255, 0.03);
}

.blueprint-header {
    display: flex;
    justify-content: space-between;
    font-family: var(--font-title);
    font-size: 0.8rem;
    font-weight: 700;
    color: rgba(0, 229, 255, 0.7);
    letter-spacing: 1.5px;
    border-bottom: 1px solid var(--color-blueprint-border);
    padding-bottom: 12px;
    margin-bottom: 30px;
}

.blueprint-code {
    opacity: 0.5;
}

.blueprint-content {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    justify-content: space-between;
}

.blueprint-step {
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 20px;
    border-radius: var(--border-radius-sm);
    background-color: rgba(255, 255, 255, 0.015);
    border: 1px solid rgba(255, 255, 255, 0.03);
    transition: var(--transition-base);
}

.blueprint-step:hover {
    background-color: rgba(0, 229, 255, 0.04);
    border-color: rgba(0, 229, 255, 0.2);
    transform: translateX(6px);
}

.blueprint-node {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.node-icon {
    width: 54px;
    height: 54px;
    border-radius: 50%;
    background-color: rgba(0, 229, 255, 0.08);
    color: var(--color-blueprint-line);
    border: 1.5px solid var(--color-blueprint-line);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 0 10px rgba(0, 229, 255, 0.15);
    transition: var(--transition-base);
}

.node-icon svg {
    width: 26px;
    height: 26px;
}

.blueprint-step:hover .node-icon {
    box-shadow: 0 0 20px var(--color-blueprint-line);
    transform: scale(1.05);
}

.node-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    background-color: var(--color-orange);
    color: var(--color-text-primary);
    font-size: 0.65rem;
    font-weight: 800;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}

.blueprint-info h4 {
    color: #ffffff;
    font-size: 1.15rem;
    margin-bottom: 6px;
    font-family: var(--font-title);
    letter-spacing: 0.5px;
}

.blueprint-info p {
    color: var(--color-text-secondary-dark);
    font-size: 0.9rem;
    line-height: 1.55;
}

.blueprint-divider {
    height: 48px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 4px 0;
}

.blueprint-line-svg {
    height: 100%;
    width: 20px;
}

.blueprint-flow-dot {
    animation: flowDot 2.2s infinite linear;
}

@keyframes flowDot {
    0% {
        cy: 0;
        opacity: 0;
    }
    15% {
        opacity: 1;
    }
    85% {
        opacity: 1;
    }
    100% {
        cy: 80;
        opacity: 0;
    }
}

/* Stats Column */
.avantages-stats-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
}

.stat-card {
    background-color: var(--color-bg-card-dark);
    border: 1px solid var(--color-border-dark);
    border-radius: var(--border-radius-md);
    padding: 32px 24px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    transition: var(--transition-base);
    position: relative;
    overflow: hidden;
}

.stat-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 3px;
    background: linear-gradient(to right, var(--color-teal-light), var(--color-orange));
    opacity: 0;
    transition: var(--transition-base);
}

.stat-card:hover {
    transform: translateY(-6px);
    border-color: rgba(15, 140, 160, 0.4);
    box-shadow: 0 10px 25px rgba(0, 229, 255, 0.08);
}

.stat-card:hover::before {
    opacity: 1;
}

.stat-icon-box {
    font-size: 1.75rem;
    margin-bottom: 20px;
    width: 46px;
    height: 46px;
    background-color: rgba(255, 255, 255, 0.03);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: var(--transition-base);
}

/* Le survol soulève l'icône et la teinte, sans la faire pivoter : la
   rotation de 10° donnait un mouvement de pastille décorative, alors que
   la carte désigne un bénéfice. Monter de trois pixels dit « ceci
   répond », tourner ne dit rien.
   La règle « .stat-card:hover .stat-value » qui suivait a été retirée
   avec le bloc « .stat-value » : ni l'une ni l'autre n'avaient encore de
   support dans le HTML depuis que les cartes ont perdu leurs chiffres. */
.stat-card:hover .stat-icon-box {
    background-color: rgba(15, 140, 160, 0.1);
    color: var(--color-blueprint-line);
    transform: translateY(-3px) scale(1.06);
}

.stat-title {
    font-size: 1.25rem;
    color: #ffffff;
    margin-bottom: 12px;
    letter-spacing: 0.5px;
    font-weight: 600;
    transition: var(--transition-base);
}

.stat-card:hover .stat-title {
    color: var(--color-blueprint-line);
}

.stat-desc {
    font-size: 0.925rem;
    color: var(--color-text-secondary-dark);
    line-height: 1.6;
}

/* Responsive Breakpoints */

/* Tablet (Large) */
@media (max-width: 1024px) {
    .hero-container {
        grid-template-columns: 1fr;
        gap: 60px;
        text-align: center;
    }
    
    .hero-content {
        align-items: center;
    }
    
    .hero-title {
        align-items: center;
    }
    
    .hero-actions {
        justify-content: center;
    }
    
    .hero-visual {
        order: -1;
    }
    
    .services-circuit-svg {
        display: none; /* Hide connecting paths on tablet/mobile */
    }
    
    .services-diagram-container {
        min-height: auto;
    }
    
    .services-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 32px;
    }

    #card-audit, #card-conseil, #card-formation, #card-logiciel-ia, #card-automatisation {
        grid-column: auto !important;
        grid-row: auto !important;
        max-width: none !important;
        justify-self: stretch !important;
    }
    
    .contact-container {
        grid-template-columns: 1fr;
        gap: 60px;
    }
    

    
    .avantages-container {
        grid-template-columns: 1fr;
        gap: 40px;
    }
}

/* Tablet (Small) */
@media (max-width: 768px) {
    .menu-toggle {
        display: block;
    }
    
    .main-nav {
        position: fixed;
        top: 80px;
        left: 0;
        width: 100%;
        height: calc(100vh - 80px);
        background-color: var(--color-bg);
        z-index: 105;
        transform: translateX(100%);
        transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        padding: 40px 24px;
        border-top: 1px solid var(--color-border);
    }
    
    .main-nav.open {
        transform: translateX(0);
    }

    /* La compaction de l'en-tête est neutralisée sur mobile : le panneau de
       navigation est positionné à « top: 80px » avec une hauteur calculée
       sur cette même valeur. Laisser la barre passer à 68px en cours de
       défilement ouvrirait une bande vide de 12 pixels au-dessus du menu. */
    .main-header.is-scrolled .header-container {
        height: 80px;
    }

    .main-header.is-scrolled .logo-img {
        transform: none;
    }

    .nav-links {
        flex-direction: column;
        gap: 24px;
        align-items: center;
    }

    .nav-link {
        font-size: 1.25rem;
    }

    /* Cascade à l'ouverture du menu. Les entrées arrivent l'une après
       l'autre au lieu d'apparaître en bloc avec le panneau : le regard a
       le temps de les parcourir pendant qu'elles se posent.
       Le délai est court (40ms) — il s'agit de donner un sens de lecture,
       pas de faire attendre devant un menu de navigation. */
    .js-motion .main-nav .nav-links > li {
        opacity: 0;
        transform: translateX(16px);
        transition:
            opacity var(--dur-base) var(--ease-out),
            transform var(--dur-base) var(--ease-out);
    }

    .js-motion .main-nav.open .nav-links > li {
        opacity: 1;
        transform: none;
    }

    .js-motion .main-nav.open .nav-links > li:nth-child(1) { transition-delay: 120ms; }
    .js-motion .main-nav.open .nav-links > li:nth-child(2) { transition-delay: 160ms; }
    .js-motion .main-nav.open .nav-links > li:nth-child(3) { transition-delay: 200ms; }
    .js-motion .main-nav.open .nav-links > li:nth-child(4) { transition-delay: 240ms; }
    .js-motion .main-nav.open .nav-links > li:nth-child(5) { transition-delay: 280ms; }
    .js-motion .main-nav.open .nav-links > li:nth-child(6) { transition-delay: 320ms; }

    /* Mobile Dropdown styles.
       La hauteur d'ouverture n'est plus une constante devinée (250px pour
       un menu qui en fait bien moins) : elle est mesurée par script.js et
       déposée dans « --menu-h ». Un max-height trop généreux fait passer
       la transition à animer du vide — c'est exactement ce qui donnait
       l'impression que le menu s'ouvrait mollement. Avec la hauteur
       réelle, la durée annoncée est la durée perçue, et le menu reste
       juste si on lui ajoute une entrée.
       La valeur de repli (0px) n'est utilisée qu'entre le chargement du
       CSS et celui du script ; le menu est de toute façon fermé à cet
       instant. */
    .main-nav .dropdown-menu {
        position: static;
        transform: none;
        opacity: 1;
        visibility: visible;
        width: 100%;
        background: transparent;
        backdrop-filter: none;
        border: none;
        box-shadow: none;
        /* L'espacement autour des entrées est porté par la marge interne
           du menu et non par une marge externe posée à l'ouverture : il
           est ainsi compris dans la hauteur mesurée, et il disparaît avec
           le reste quand le menu est replié (max-height: 0 + overflow). */
        padding: 10px 0 5px;
        max-height: 0;
        overflow: hidden;
        transition: max-height var(--dur-base) var(--ease-out);
    }

    .main-nav .dropdown.open .dropdown-menu {
        max-height: var(--menu-h, 320px);
    }

    .main-nav .dropdown.open .arrow-icon-mini {
        transform: rotate(180deg);
    }
    
    .main-nav .dropdown-item {
        padding: 10px 0;
        font-size: 1.1rem;
        color: var(--color-text-secondary);
        text-align: center;
        width: 100%;
    }
    
    .main-nav .dropdown-item:hover {
        color: var(--color-teal-light);
        transform: none;
        background-color: transparent;
    }
    
    .footer-container {
        grid-template-columns: 1fr;
        gap: 40px;
    }
}

/* Mobile */
@media (max-width: 480px) {
    .services-grid {
        grid-template-columns: 1fr;
    }
    
    .hero-actions {
        flex-direction: column;
        width: 100%;
    }
    
    .btn {
        width: 100%;
    }
    
    .contact-form {
        padding: 24px;
    }
    
    .avantages-stats-grid {
        grid-template-columns: 1fr;
        gap: 20px;
    }
    .avantages-blueprint {
        padding: 24px 16px;
    }
    .blueprint-step {
        gap: 16px;
        padding: 14px;
    }
}

/* ==========================================================================
   Legal Page Custom Styles
   ========================================================================== */
.legal-page-hero {
    padding: 140px 0 60px;
    background-color: var(--color-bg-dark);
    color: #ffffff;
    text-align: center;
    position: relative;
}

.legal-page-hero h1 {
    color: #ffffff;
    font-size: clamp(2rem, 4vw, 3rem);
    margin-bottom: 12px;
}

.legal-page-hero .subtitle {
    color: var(--color-text-secondary-dark);
    font-size: 1.1rem;
    max-width: 600px;
    margin: 0 auto;
}

.legal-container {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 60px;
    padding: 80px 0;
}

.legal-sidebar {
    position: sticky;
    top: 120px;
    height: fit-content;
}

.legal-nav {
    display: flex;
    flex-direction: column;
    gap: 8px;
    list-style: none;
    border-left: 2px solid var(--color-border);
    padding-left: 16px;
}

.legal-nav-link {
    text-decoration: none;
    color: var(--color-text-secondary);
    font-family: var(--font-title);
    font-weight: 500;
    font-size: 0.95rem;
    transition: var(--transition-base);
    display: block;
    padding: 4px 0;
}

.legal-nav-link:hover {
    color: var(--color-teal-light);
    transform: translateX(4px);
}

.legal-nav-item.active .legal-nav-link {
    color: var(--color-teal);
    font-weight: 600;
}

.legal-content {
    background-color: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-md);
    padding: 48px;
    box-shadow: var(--shadow-sm);
}

.legal-section {
    margin-bottom: 48px;
    scroll-margin-top: 120px;
}

.legal-section:last-child {
    margin-bottom: 0;
}

.legal-section h2 {
    text-align: left;
    font-size: 1.5rem;
    color: var(--color-teal);
    margin-bottom: 20px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--color-border);
}

.legal-section h2::after {
    display: none; /* remove center line decoration */
}

.legal-section p {
    margin-bottom: 16px;
    line-height: 1.7;
    color: var(--color-text-secondary);
}

.legal-section ul {
    margin-bottom: 16px;
    padding-left: 24px;
    color: var(--color-text-secondary);
}

.legal-section li {
    margin-bottom: 8px;
}

.legal-section strong {
    color: var(--color-text-primary);
}

.legal-meta-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 24px;
    margin-top: 24px;
    margin-bottom: 24px;
}

.legal-meta-card {
    background-color: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-sm);
    padding: 20px;
    transition: var(--transition-base);
}

.legal-meta-card:hover {
    border-color: var(--color-teal-light);
    box-shadow: var(--shadow-sm);
}

.legal-meta-card h3 {
    font-size: 1.05rem;
    color: var(--color-teal);
    margin-bottom: 8px;
}

.legal-meta-card p {
    margin-bottom: 0;
    font-size: 0.92rem;
}

@media (max-width: 1024px) {
    .legal-container {
        grid-template-columns: 1fr;
        gap: 40px;
        padding: 60px 0;
    }
    
    .legal-sidebar {
        display: none; /* Hide sticky sidebar on tablets/mobiles */
    }
    
    .legal-content {
        padding: 32px 24px;
    }
}

/* ==========================================================================
   Système d'icônes
   --------------------------------------------------------------------------
   Jeu Lucide (licence ISC), tracé unique, même grille 24 et même épaisseur.
   Les icônes remplacent les emojis Unicode, dont le dessin variait d'un
   système à l'autre et que les lecteurs d'écran annonçaient littéralement
   (« sablier » pour un gain de temps). Chaque SVG porte aria-hidden : le sens
   est déjà porté par le texte qui l'accompagne.
   ========================================================================== */
.icon {
    width: 24px;
    height: 24px;
    flex: 0 0 auto;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    vertical-align: -0.15em;
}

.icon-sm {
    width: 20px;
    height: 20px;
}

.icon-lg {
    width: 32px;
    height: 32px;
    stroke-width: 1.75;
}

/* Pastilles de la section « Des atouts pour votre activité » (fond sombre). */
.stat-icon-box {
    color: var(--color-teal-light);
}

/* Coordonnées de la section contact (fond clair). */
.detail-icon {
    color: var(--color-teal);
}

/* Coche et croix des retours de formulaire : dessinées, plus typographiées. */
.success-icon .icon,
.error-icon .icon {
    width: 28px;
    height: 28px;
    stroke-width: 2.5;
}

/* Mention d'information RGPD, placée au point de collecte de chaque
   formulaire : le RGPD impose que l'information soit donnée au moment où la
   donnée est saisie, pas seulement dans une page annexe. */
.form-legal {
    font-size: 0.78rem;
    line-height: 1.55;
    color: var(--color-text-secondary);
    margin-bottom: 20px;
}

.form-legal a {
    color: var(--color-teal-light);
    text-decoration: underline;
}

.section-dark .form-legal {
    color: var(--color-text-secondary-dark);
}

/* Portrait en tête de la page « Qui suis-je ». */
.portrait-lead {
    width: 180px;
    height: 180px;
    border-radius: 50%;
    object-fit: cover;
    float: right;
    margin: 0 0 20px 28px;
    border: 4px solid var(--color-bg);
    box-shadow: var(--shadow-md);
}

@media (max-width: 600px) {
    .portrait-lead {
        float: none;
        margin: 0 auto 24px auto;
        display: block;
    }
}

/* Pages de remerciement : pas de sommaire latéral, le contenu occupe
   toute la largeur disponible. */
.merci-container {
    grid-template-columns: 1fr;
    max-width: 760px;
}

/* ====================================================================
   ACCESSIBILITÉ DU MOUVEMENT — dernier bloc du fichier, à garder en
   dernier pour qu'il l'emporte sur toute règle écrite au-dessus.
   ====================================================================
   « prefers-reduced-motion » est un réglage système (Windows, macOS,
   iOS, Android, GNOME) par lequel une personne demande à ce que les
   interfaces cessent de bouger. Ce n'est pas une préférence esthétique :
   les animations de défilement et de parallaxe déclenchent des nausées
   et des vertiges chez les personnes sujettes au mal des transports ou
   à des troubles vestibulaires, et peuvent provoquer des crises chez
   les personnes photosensibles. C'est une exigence du RGAA et des WCAG
   (critère 2.3.3).

   La règle ici ne supprime pas les animations, elle les ramène à une
   durée imperceptible. La différence compte : un élément révélé au
   scroll doit rester visible, un panneau ouvert doit rester ouvert, un
   message de confirmation doit rester affiché. Couper « animation:
   none » les laisserait bloqués dans leur état de départ — donc
   invisibles. En les réduisant à 0,01ms, l'état final est atteint
   immédiatement et la page se comporte comme si rien n'avait jamais
   été animé.
   ==================================================================== */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        animation-delay: 0ms !important;
        transition-duration: 0.01ms !important;
        transition-delay: 0ms !important;
        scroll-behavior: auto !important;
    }

    html {
        scroll-behavior: auto;
    }

    /* Le contenu révélé au scroll est affiché d'emblée, sans décalage. */
    .js-motion [data-reveal] {
        opacity: 1;
        transform: none;
    }

    /* Les boucles infinies purement décoratives (halo, balayage, rotation
       du moyeu, points qui circulent) n'ont pas d'état final utile : on
       les arrête franchement au lieu de les accélérer. */
    .active-flow-path,
    .flow-dot,
    .circuit-hub,
    .glow-pulse,
    [class*="shimmer"],
    [class*="pulse-glow"] {
        animation: none !important;
    }

    /* Le schéma des services est affiché entièrement tracé : sans cette
       règle, les connecteurs resteraient à « dashoffset: 1 », c'est-à-dire
       invisibles, et le parcours audit / conseil / réalisation perdrait
       les liens qui lui donnent son sens. C'est l'illustration du principe
       général de ce bloc : on retire le mouvement, jamais l'information. */
    .js-motion .services-circuit-svg path:not(.active-flow-path) {
        stroke-dasharray: none !important;
        stroke-dashoffset: 0 !important;
    }

    /* Les transitions de page rejoignent la même logique. */
    ::view-transition-old(root),
    ::view-transition-new(root) {
        animation: none !important;
    }
}

/* ====================================================================
   PAGES DE REMERCIEMENT — la coche qui se trace
   ====================================================================
   Ces trois pages (audit, contact, rendez-vous) closent un parcours : le
   visiteur vient de remplir un formulaire et attend une confirmation.
   Une coche déjà dessinée dit « voici une page de confirmation » ; une
   coche qui se trace sous les yeux dit « c'est en train d'être validé,
   maintenant, pour vous ». C'est la même information, reçue autrement.

   Le tracé repose sur « pathLength="1" » : la longueur de chaque trait
   est normalisée, le pointillé et son décalage travaillent donc en
   proportions. Le cercle se ferme d'abord, la coche s'inscrit ensuite —
   l'ordre compte, une coche qui précéderait son cercle n'aurait aucun
   sens de lecture.
   ==================================================================== */
.merci-check {
    display: block;
    width: 72px;
    height: 72px;
    margin: 0 auto 24px;
}

.merci-check circle,
.merci-check path {
    fill: none;
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
}

.merci-check circle {
    stroke: var(--color-teal-light);
}

.merci-check path {
    stroke: var(--color-orange);
    stroke-width: 3;
}

/* Sans JavaScript, la coche est simplement dessinée : l'état final est
   l'état par défaut, l'animation n'est qu'une manière d'y arriver. */
.js-motion .merci-check circle,
.js-motion .merci-check path {
    animation: drawStroke 600ms var(--ease-out) forwards;
}

.js-motion .merci-check circle {
    animation-delay: 120ms;
}

.js-motion .merci-check path {
    /* La coche part quand le cercle est tracé aux trois quarts : attendre
       la fin exacte produit une pause qui casse le geste. */
    animation-delay: 560ms;
}

@keyframes drawStroke {
    to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .js-motion .merci-check circle,
    .js-motion .merci-check path {
        stroke-dashoffset: 0;
    }
}
