/* =====================================================================
   LJ TECHNOLOGIE — Design system
   ---------------------------------------------------------------------
   Charte graphique construite à partir du logo officiel :
     · Graphite  #202020  — couleur du lettrage « LJ TECHNOLOGIE »
     · Bleu      #5271FF  — crochet d'angle bas-droit
     · Menthe    #4CE8B8  — crochet d'angle bas-gauche
     · Ambre     #FFE471  — crochet d'angle haut-gauche
     · Corail    #FF565B  — crochet d'angle haut-droit
   Le motif de crochets d'angle du logo est repris comme signature
   graphique du site (sections, cartes, encadrés).
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. Tokens
   --------------------------------------------------------------------- */
:root {
    /* Couleurs issues du logo */
    --ink:            #202020;
    --blue:           #5271FF;
    --mint:           #4CE8B8;
    --amber:          #FFE471;
    --coral:          #FF565B;

    /* Déclinaisons nécessaires à la lisibilité */
    --blue-700:       #2E4CE0;
    --blue-800:       #223AAF;
    --blue-100:       #E7EBFF;
    --blue-050:       #F2F5FF;
    --mint-700:       #0E9B72;
    --mint-100:       #DEFAF0;
    --amber-800:      #8A6A00;
    --amber-100:      #FFF6D6;
    --coral-700:      #D93B40;
    --coral-100:      #FFE7E7;

    /* Neutres */
    --ink-900:        #121316;
    --ink-800:        #1A1C20;
    --ink-700:        #24262B;
    --ink-600:        #3A3D44;
    --ink-500:        #5A5E67;
    --ink-400:        #8A8F99;
    --ink-300:        #C3C7CE;
    --ink-200:        #E2E5EA;
    --ink-100:        #EFF1F4;
    --ink-050:        #F7F8FA;
    --white:          #FFFFFF;

    /* Rôles */
    --bg:             var(--white);
    --bg-soft:        var(--ink-050);
    --text:           var(--ink);
    --text-soft:      var(--ink-500);
    --text-invert:    #F4F6F8;
    --border:         rgba(32, 32, 32, .10);
    --border-strong:  rgba(32, 32, 32, .18);
    --accent:         var(--blue);
    --accent-contrast:#FFFFFF;

    /* Typographie */
    --font-title: 'Space Grotesk', 'Segoe UI', system-ui, sans-serif;
    --font-body:  'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --font-mono:  ui-monospace, 'SFMono-Regular', 'Cascadia Mono', Consolas, monospace;

    --step--1: clamp(.8125rem, .79rem + .11vw, .875rem);
    --step-0:  clamp(1rem, .97rem + .15vw, 1.0625rem);
    --step-1:  clamp(1.125rem, 1.07rem + .27vw, 1.3125rem);
    --step-2:  clamp(1.375rem, 1.27rem + .5vw, 1.75rem);
    --step-3:  clamp(1.75rem, 1.55rem + .95vw, 2.5rem);
    --step-4:  clamp(2.125rem, 1.75rem + 1.85vw, 3.5rem);
    --step-5:  clamp(2.5rem, 1.9rem + 3vw, 4.5rem);

    /* Espacements et formes */
    --space-section: clamp(4.5rem, 3rem + 6vw, 8rem);
    --radius-sm: 8px;
    --radius:    14px;
    --radius-lg: 22px;
    --radius-xl: 30px;

    --shadow-sm: 0 1px 2px rgba(18, 19, 22, .05), 0 2px 8px rgba(18, 19, 22, .04);
    --shadow:    0 2px 6px rgba(18, 19, 22, .05), 0 12px 32px rgba(18, 19, 22, .07);
    --shadow-lg: 0 8px 20px rgba(18, 19, 22, .07), 0 30px 60px rgba(18, 19, 22, .12);
    --shadow-blue: 0 10px 30px rgba(82, 113, 255, .28);

    --ease: cubic-bezier(.22, .68, .34, 1);
    --header-h: 76px;
}

/* Variantes d'accent, dérivées des quatre couleurs du logo */
[data-accent="blue"]  { --accent: var(--blue);  --accent-soft: var(--blue-100);  --accent-ink: var(--blue-800); }
[data-accent="mint"]  { --accent: var(--mint);  --accent-soft: var(--mint-100);  --accent-ink: var(--mint-700); }
[data-accent="amber"] { --accent: var(--amber); --accent-soft: var(--amber-100); --accent-ink: var(--amber-800); }
[data-accent="coral"] { --accent: var(--coral); --accent-soft: var(--coral-100); --accent-ink: var(--coral-700); }

/* ---------------------------------------------------------------------
   2. Base
   --------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--header-h) + 16px);
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-body);
    font-size: var(--step-0);
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
}

h1, h2, h3, h4, h5 {
    font-family: var(--font-title);
    font-weight: 600;
    line-height: 1.12;
    letter-spacing: -.02em;
    margin: 0 0 .6em;
    color: var(--ink);
    text-wrap: balance;
}

h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }

p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

a {
    color: var(--blue-700);
    text-decoration: none;
    transition: color .2s var(--ease);
}
a:hover { color: var(--blue-800); }

img, svg, video { max-width: 100%; height: auto; display: block; }
strong { font-weight: 600; }
ul, ol { margin: 0 0 1.15em; padding-left: 1.25em; }
li { margin-bottom: .4em; }
hr { border: 0; border-top: 1px solid var(--border); margin: 2.5rem 0; }

::selection { background: var(--blue); color: #fff; }

:focus-visible {
    outline: 3px solid var(--blue);
    outline-offset: 3px;
    border-radius: 4px;
}

/* Accessibilité : accès rapide au contenu */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    background: var(--ink);
    color: #fff;
    padding: .85rem 1.25rem;
    border-radius: 0 0 var(--radius-sm) 0;
    font-weight: 600;
}
.skip-link:focus { left: 0; color: #fff; }

.visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap; border: 0;
}

/* L'attribut `hidden` doit l'emporter sur nos `display: flex` et `grid`.
   La règle du navigateur, elle, a la priorité la plus faible : sans ce
   rappel, masquer un élément en JavaScript n'a aucun effet visible. */
[hidden] { display: none !important; }

/* Champ piège anti-spam */
.hp { position: absolute; left: -9999px; opacity: 0; height: 0; overflow: hidden; }

/* ---------------------------------------------------------------------
   3. Mise en page
   --------------------------------------------------------------------- */
.container {
    width: min(100% - 2.5rem, 1220px);
    margin-inline: auto;
}
.container--narrow { width: min(100% - 2.5rem, 820px); }
.container--mid    { width: min(100% - 2.5rem, 1000px); }

.section { padding-block: var(--space-section); position: relative; }
.section--tight { padding-block: clamp(3rem, 2rem + 4vw, 5rem); }
.section--soft  { background: var(--bg-soft); }
.section--dark {
    background: var(--ink-900);
    color: var(--text-invert);
}
.section--dark h1, .section--dark h2, .section--dark h3, .section--dark h4 { color: #fff; }
.section--dark p { color: rgba(244, 246, 248, .78); }
.section--dark a { color: #fff; }

.grid { display: grid; gap: clamp(1rem, .6rem + 1.4vw, 1.75rem); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }
/* Grille des cartes de services et de réalisations : trois colonnes larges
   sur grand écran. `auto-fill` et non `auto-fit`, car `auto-fit` ramasse les
   pistes vides — un filtre ne laissant qu'un projet lui ferait alors occuper
   toute la largeur. */
.grid--cartes { grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); }

.stack > * + * { margin-top: var(--stack-gap, 1.25rem); }
.center { text-align: center; }
.mt-0 { margin-top: 0; }
.mt-2 { margin-top: 2rem; }
.mb-0 { margin-bottom: 0; }

/* ---------------------------------------------------------------------
   4. Signature graphique : crochets d'angle (motif du logo)
   --------------------------------------------------------------------- */
.brackets {
    position: relative;
}
.brackets::before,
.brackets::after {
    content: '';
    position: absolute;
    width: 26px; height: 26px;
    pointer-events: none;
    transition: all .35s var(--ease);
}
.brackets::before {
    top: 0; left: 0;
    border-top: 2px solid var(--amber);
    border-left: 2px solid var(--amber);
}
.brackets::after {
    bottom: 0; right: 0;
    border-bottom: 2px solid var(--blue);
    border-right: 2px solid var(--blue);
}

/* Cadre complet aux 4 couleurs du logo */
.logo-frame {
    position: relative;
    display: inline-block;
    padding: clamp(1.25rem, 1rem + 1.5vw, 2.25rem);
}
.logo-frame span.corner {
    position: absolute;
    width: 34px; height: 34px;
}
.logo-frame .c-tl { top: 0; left: 0;  border-top: 3px solid var(--amber); border-left: 3px solid var(--amber); }
.logo-frame .c-tr { top: 0; right: 0; border-top: 3px solid var(--coral); border-right: 3px solid var(--coral); }
.logo-frame .c-bl { bottom: 0; left: 0;  border-bottom: 3px solid var(--mint); border-left: 3px solid var(--mint); }
.logo-frame .c-br { bottom: 0; right: 0; border-bottom: 3px solid var(--blue); border-right: 3px solid var(--blue); }

/* Filet coloré repris du logo */
.rule-4c {
    height: 3px;
    width: 100%;
    background: linear-gradient(90deg,
        var(--amber) 0 25%, var(--coral) 25% 50%, var(--mint) 50% 75%, var(--blue) 75% 100%);
    border-radius: 3px;
}

/* ---------------------------------------------------------------------
   5. Titres de section
   --------------------------------------------------------------------- */
.kicker {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    font-family: var(--font-title);
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--blue-700);
    margin-bottom: 1rem;
}
.kicker::before {
    content: '';
    width: 22px; height: 10px;
    border-left: 2px solid var(--accent, var(--blue));
    border-bottom: 2px solid var(--accent, var(--blue));
}
.section--dark .kicker { color: var(--mint); }
.section--dark .kicker::before { border-color: var(--mint); }

.section-head { max-width: 720px; margin-bottom: clamp(2.5rem, 2rem + 2vw, 4rem); }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head--center .kicker { justify-content: center; }
.section-head p { color: var(--text-soft); font-size: var(--step-1); margin-bottom: 0; }
.section--dark .section-head p { color: rgba(244, 246, 248, .72); }

.section-head--split {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 2rem;
    max-width: none;
    flex-wrap: wrap;
}
.section-head--split > div { max-width: 680px; }

/* ---------------------------------------------------------------------
   6. Boutons
   --------------------------------------------------------------------- */
.btn {
    --btn-bg: var(--ink);
    --btn-fg: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    padding: .95rem 1.6rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: var(--btn-bg);
    color: var(--btn-fg);
    font-family: var(--font-title);
    font-size: .9375rem;
    font-weight: 600;
    letter-spacing: .01em;
    line-height: 1.2;
    cursor: pointer;
    text-align: center;
    transition: transform .2s var(--ease), box-shadow .25s var(--ease), background-color .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.btn:hover { color: var(--btn-fg); transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn svg { width: 18px; height: 18px; flex: none; }
.btn .arrow { transition: transform .25s var(--ease); }
.btn:hover .arrow { transform: translateX(4px); }

.btn--primary { --btn-bg: var(--blue); box-shadow: var(--shadow-blue); }
.btn--primary:hover { --btn-bg: var(--blue-700); box-shadow: 0 14px 34px rgba(82, 113, 255, .38); }

.btn--dark { --btn-bg: var(--ink); }
.btn--dark:hover { --btn-bg: var(--ink-700); box-shadow: 0 12px 28px rgba(18, 19, 22, .22); }

.btn--light { --btn-bg: #fff; --btn-fg: var(--ink); box-shadow: var(--shadow-sm); }
.btn--light:hover { --btn-bg: #fff; box-shadow: var(--shadow); }

.btn--outline {
    --btn-bg: transparent;
    --btn-fg: var(--ink);
    border-color: var(--border-strong);
}
.btn--outline:hover { --btn-bg: var(--ink); --btn-fg: #fff; border-color: var(--ink); }

.btn--outline-light {
    --btn-bg: transparent;
    --btn-fg: #fff;
    border-color: rgba(255, 255, 255, .35);
}
.btn--outline-light:hover { --btn-bg: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .6); }

.btn--sm { padding: .65rem 1.1rem; font-size: .875rem; }
.btn--lg { padding: 1.1rem 2rem; font-size: 1rem; }
.btn--block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: .875rem; }
.btn-row--center { justify-content: center; }

/* Lien fléché */
.link-arrow {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    font-family: var(--font-title);
    font-weight: 600;
    font-size: .9375rem;
    color: var(--blue-700);
}
.link-arrow svg { width: 16px; height: 16px; transition: transform .25s var(--ease); }
.link-arrow:hover svg { transform: translateX(4px); }
.section--dark .link-arrow { color: var(--mint); }

/* ---------------------------------------------------------------------
   7. En-tête et navigation
   --------------------------------------------------------------------- */
/* Fond opaque par défaut : c'est le cas sûr, celui d'une page qui ouvre sur
   du blanc (la page de remerciement, par exemple). La transparence est
   accordée plus bas, uniquement aux pages qui commencent par un bandeau
   sombre — sans quoi un libellé clair se poserait sur du blanc. */
.header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: rgba(255, 255, 255, .88);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid transparent;
    transition: border-color .3s var(--ease), box-shadow .3s var(--ease),
                background-color .3s var(--ease), backdrop-filter .3s var(--ease);
}

/* Le bandeau d'ouverture remonte sous la barre, qui se pose alors dessus
   au lieu de laisser voir le fond blanc de la page. */
main > .hero:first-child,
main > .page-header:first-child {
    margin-top: calc(-1 * var(--header-h));
}
main > .hero:first-child { padding-top: calc(var(--header-h) + clamp(4rem, 2.5rem + 8vw, 8rem)); }
/* Le diaporama porte lui-même sa hauteur et son dégagement : ce padding
   s'ajouterait au sien et ferait dépasser le premier écran. */
main > .hero--slider:first-child { padding-top: 0; }
main > .page-header:first-child { padding-top: calc(var(--header-h) + clamp(3.5rem, 2.5rem + 5vw, 6rem)); }

/* Une seule variable porte l'encre de la barre : logo et bouton la suivent,
   sans avoir à répéter ces sélecteurs pour chacun.
   Un navigateur sans :has() garde la barre opaque et l'encre sombre :
   lisible partout, seul l'effet de transparence lui échappe. */
.header { --header-encre: var(--ink); }

body:has(main > .hero:first-child) .header:not(.is-scrolled),
body:has(main > .page-header:first-child) .header:not(.is-scrolled) {
    --header-encre: #fff;
    /* Le bandeau est sombre : c'est la déclinaison à lettrage blanc qui passe
       devant. Partout ailleurs, la barre est claire et c'est l'inverse. */
    --logo-clair: 1;
    --logo-sombre: 0;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
.header.is-scrolled {
    background: rgba(255, 255, 255, .88);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom-color: var(--border);
    box-shadow: 0 6px 24px rgba(18, 19, 22, .06);
}
.header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    min-height: var(--header-h);
}

.brand { display: inline-flex; align-items: center; gap: .75rem; flex: none; }
.brand img { height: 44px; width: auto; }

/* Les deux déclinaisons du logo sont superposées et l'on fait passer l'une
   devant l'autre selon le fond de la barre : le lettrage graphite se perdrait
   sur le bandeau sombre, le lettrage blanc sur le fond clair. La bascule suit
   les mêmes règles que l'encre, plus bas. */
.brand__logo { position: relative; display: block; height: 44px; width: 44px; flex: none; }
.brand__logo img {
    position: absolute;
    inset: 0;
    height: 100%;
    width: auto;
    transition: opacity .3s var(--ease);
}
.brand__logo--clair { opacity: var(--logo-clair, 0); }
.brand__logo--sombre { opacity: var(--logo-sombre, 1); }
.brand__name {
    font-family: var(--font-title);
    font-weight: 700;
    font-size: 1.0625rem;
    letter-spacing: .04em;
    color: var(--header-encre);
    transition: color .3s var(--ease);
}

/* --- Bouton d'ouverture ---------------------------------------------- */

.menu-btn {
    display: inline-flex;
    align-items: center;
    gap: .7rem;
    flex: none;
    padding: .55rem .3rem .55rem .9rem;
    font-family: var(--font-title);
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--header-encre);
    text-decoration: none;
    border-radius: 999px;
    transition: color .3s var(--ease);
}
.menu-btn:hover { color: var(--blue); }
.header.is-scrolled .menu-btn:hover { color: var(--blue-700); }
.menu-btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }

.menu-btn__lignes {
    display: grid;
    gap: 5px;
    width: 26px;
    padding: .5rem .3rem;
}
.menu-btn__lignes span {
    display: block;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
    transition: transform .25s var(--ease), width .25s var(--ease);
}
/* La seconde barre est plus courte : le bouton se reconnaît au premier
   coup d'œil sans avoir à lire le mot. */
.menu-btn__lignes span:last-child { width: 60%; justify-self: end; }
.menu-btn:hover .menu-btn__lignes span:last-child { width: 100%; }

.header__actions { display: flex; align-items: center; gap: 1rem; flex: none; }

@media (max-width: 640px) {
    /* Sur un téléphone, le bouton devis se retrouve dans le panneau : deux
       appels à l'action côte à côte n'y tiendraient pas lisiblement. */
    .header__actions .btn--nav { display: none; }
}

/* --- Panneau latéral -------------------------------------------------- */

.panneau {
    position: fixed;
    inset: 0;
    z-index: 200;
    /* Fermé : sorti du parcours clavier et du rendu, mais l'ouverture reste
       animable — « display: none » couperait toute transition. */
    visibility: hidden;
    transition: visibility 0s linear .4s;
}
.panneau:target,
.panneau.is-open { visibility: visible; transition: visibility 0s; }

/* Le voile assombrit la page sans la masquer : on garde le repère de l'endroit
   d'où l'on vient, ce qu'un panneau plein écran fait perdre. */
.panneau__voile {
    position: absolute;
    inset: 0;
    display: block;
    background: rgba(18, 19, 22, .5);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    opacity: 0;
    transition: opacity .4s var(--ease);
}
.panneau:target .panneau__voile,
.panneau.is-open .panneau__voile { opacity: 1; }

.panneau__corps {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: min(26rem, 88vw);
    background: var(--ink-900);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    overscroll-behavior: contain;
    box-shadow: -24px 0 60px rgba(18, 19, 22, .35);
    transform: translateX(100%);
    transition: transform .4s var(--ease);
}
.panneau:target .panneau__corps,
.panneau.is-open .panneau__corps { transform: none; }

.panneau__tete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.5rem 1.75rem 1.25rem;
    border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.panneau__titre {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .38);
}

.panneau__fermer {
    width: 2.5rem;
    height: 2.5rem;
    display: grid;
    place-items: center;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, .18);
    color: #fff;
    flex: none;
    transition: background-color .2s var(--ease), transform .2s var(--ease), border-color .2s var(--ease);
}
.panneau__fermer:hover {
    background: rgba(255, 255, 255, .1);
    border-color: rgba(255, 255, 255, .4);
    transform: rotate(90deg);
}
.panneau__fermer svg { width: 18px; height: 18px; }

.panneau__nav { padding: 1.25rem 1.75rem; flex: 1; }

.panneau__lien {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .85rem 0;
    font-family: var(--font-title);
    font-size: 1.125rem;
    font-weight: 600;
    letter-spacing: -.01em;
    color: rgba(255, 255, 255, .78);
    text-decoration: none;
    border-bottom: 1px solid rgba(255, 255, 255, .06);
    /* Entrée en cascade : chaque lien suit le précédent d'un souffle. */
    opacity: 0;
    transform: translateX(16px);
    transition: opacity .4s var(--ease), transform .4s var(--ease), color .2s var(--ease), padding-left .2s var(--ease);
    transition-delay: calc(var(--rang) * 45ms + 120ms);
}
.panneau:target .panneau__lien,
.panneau.is-open .panneau__lien { opacity: 1; transform: none; }

.panneau__lien svg { width: 16px; height: 16px; opacity: .35; transition: opacity .2s var(--ease), transform .2s var(--ease); }
.panneau__lien:hover { color: #fff; padding-left: .35rem; }
.panneau__lien:hover svg { opacity: .9; transform: translateX(3px); }
.panneau__lien:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.panneau__lien.is-active { color: #fff; }
.panneau__lien.is-active svg { opacity: .9; color: var(--blue); }

/* Rubrique à tiroir. Le marqueur natif du <summary> est retiré : le chevron
   de la charte en tient lieu, et pivote une fois le tiroir ouvert. */
.panneau__groupe > summary { cursor: pointer; list-style: none; }
.panneau__groupe > summary::-webkit-details-marker { display: none; }
.panneau__groupe[open] > summary svg { opacity: .9; transform: rotate(90deg); }
.panneau__groupe[open] > summary:hover svg { transform: rotate(90deg) translateX(3px); }

.panneau__sous {
    display: grid;
    gap: .1rem;
    padding: .6rem 0 .9rem;
    opacity: 0;
    transition: opacity .4s var(--ease) .32s;
}
.panneau:target .panneau__sous,
.panneau.is-open .panneau__sous { opacity: 1; }

.panneau__sous a {
    padding: .4rem 0 .4rem .9rem;
    border-left: 2px solid rgba(255, 255, 255, .12);
    color: rgba(255, 255, 255, .55);
    font-size: .875rem;
    text-decoration: none;
    transition: color .2s var(--ease), border-color .2s var(--ease);
}
.panneau__sous a:hover { color: #fff; border-left-color: var(--blue); }

.panneau__pied {
    padding: 1.5rem 1.75rem 2rem;
    border-top: 1px solid rgba(255, 255, 255, .08);
    display: flex;
    flex-direction: column;
    gap: .7rem;
    opacity: 0;
    transition: opacity .4s var(--ease) .38s;
}
.panneau:target .panneau__pied,
.panneau.is-open .panneau__pied { opacity: 1; }

.panneau__contact {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    color: rgba(255, 255, 255, .68);
    font-size: .875rem;
    text-decoration: none;
    transition: color .2s var(--ease);
}
.panneau__contact:hover { color: #fff; }
.panneau__contact svg { width: 16px; height: 16px; opacity: .6; }

body.nav-open { overflow: hidden; }

/* ---------------------------------------------------------------------
   8. Hero
   --------------------------------------------------------------------- */
.hero {
    position: relative;
    background: var(--ink-900);
    color: var(--text-invert);
    overflow: hidden;
    padding-block: clamp(4rem, 2.5rem + 8vw, 8rem) clamp(4rem, 3rem + 5vw, 7rem);
}
.hero::before {
    /* Trame technique discrète */
    content: '';
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(rgba(255, 255, 255, .035) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, .035) 1px, transparent 1px);
    background-size: 64px 64px;
    mask-image: radial-gradient(ellipse 90% 70% at 60% 35%, #000 30%, transparent 78%);
    -webkit-mask-image: radial-gradient(ellipse 90% 70% at 60% 35%, #000 30%, transparent 78%);
}
.hero__glow {
    position: absolute;
    width: 46rem; height: 46rem;
    border-radius: 50%;
    filter: blur(90px);
    opacity: .28;
    pointer-events: none;
}
.hero__glow--blue { background: var(--blue); top: -18rem; right: -14rem; }
.hero__glow--mint { background: var(--mint); bottom: -24rem; left: -18rem; opacity: .16; }

.hero__inner {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    gap: clamp(2rem, 1rem + 4vw, 4.5rem);
    align-items: center;
}
.hero__content { max-width: 660px; }
.hero h1, .hero-slide__title {
    font-size: var(--step-5);
    color: #fff;
    margin-bottom: 1.25rem;
}
.hero h1 em, .hero-slide__title em {
    font-style: normal;
    background: linear-gradient(100deg, var(--mint), var(--blue) 65%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.hero__lead {
    font-size: var(--step-1);
    color: rgba(244, 246, 248, .78);
    max-width: 56ch;
    margin-bottom: 2rem;
}
.hero .kicker { color: var(--mint); }
.hero .kicker::before { border-color: var(--mint); }

.hero__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 1.75rem;
    margin-top: 3rem;
    padding-top: 2rem;
    border-top: 1px solid rgba(255, 255, 255, .12);
}
.hero__meta-item { display: flex; align-items: center; gap: .6rem; font-size: .875rem; color: rgba(244, 246, 248, .72); }
.hero__meta-item svg { width: 18px; height: 18px; color: var(--mint); flex: none; }

@keyframes float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-10px); }
}

/* ---------------------------------------------------------------------
   8 bis. Hero — diaporama
   Les volets sont superposés en grille : le plus haut impose la hauteur,
   il n'y a donc aucun saut d'affichage au changement de volet.
   Sans JavaScript, seul le premier volet reste visible et lisible.
   --------------------------------------------------------------------- */
.hero--slider {
    --slide-duration: 7000ms;
    padding-block: 0;
    isolation: isolate;
}
.hero-slides {
    position: relative;
    display: grid;
}
.hero-slide {
    grid-area: 1 / 1;
    position: relative;
    display: flex;
    align-items: center;
    /* Le volet occupe la hauteur de l'écran : la barre transparente flotte
       par-dessus l'image, et rien d'autre ne partage le premier écran.
       « dvh » suit la barre d'adresse mobile, « vh » sert de repli aux
       navigateurs qui l'ignorent. C'est bien une hauteur *minimale* : un
       texte long allonge le volet plutôt que d'en déborder. */
    min-height: 100vh;
    min-height: 100dvh;
    /* En haut, la hauteur de la barre ; en bas, la place des pastilles et du
       bouton de pause, qui flottent en position absolue. */
    padding-top: calc(var(--header-h) + 2rem);
    padding-bottom: clamp(7rem, 5rem + 6vw, 10rem);
}

/* Écrans peu hauts — un portable de 900 px, par exemple : le dégagement se
   resserre pour que le volet tienne encore dans l'écran, faute de quoi la
   section suivante déborderait de quelques dizaines de pixels. */
@media (min-width: 641px) and (max-height: 920px) {
    .hero--slider .hero-slide {
        padding-top: calc(var(--header-h) + 1.25rem);
        padding-bottom: 6.5rem;
    }
    opacity: 0;
    visibility: hidden;
    transition: opacity .9s ease, visibility 0s linear .9s;
}
.hero-slide.is-active {
    opacity: 1;
    visibility: visible;
    z-index: 2;
    transition: opacity .9s ease, visibility 0s;
}

/* Image de fond : cadrage plein, zoom lent pendant l'affichage.
   Le point de cadrage est fixé volet par volet dans la vue (--slide-cadrage) :
   sur un écran étroit, « cover » rogne la photo sur les côtés et le sujet
   sortirait du champ s'il n'était pas centré au bon endroit. */
.hero-slide__media {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: var(--slide-cadrage, 50% 50%);
    background-repeat: no-repeat;
    transform: scale(1.08);
    transition: transform 1.2s ease;
    will-change: transform;
}
.hero-slide.is-active .hero-slide__media {
    animation: hero-zoom calc(var(--slide-duration) + 1200ms) ease-out forwards;
}
@keyframes hero-zoom {
    from { transform: scale(1.02) translate3d(0, 0, 0); }
    to   { transform: scale(1.16) translate3d(-1.2%, -1%, 0); }
}

/* Voile de lisibilité : dégradé horizontal + fondu vers le bandeau suivant.
   Calibré pour de vraies photographies, plus claires et plus chargées que des
   visuels abstraits : la moitié droite reste assez couverte pour que les
   flèches et les pastilles blanches gardent leur contraste. */
.hero-slide__veil {
    position: absolute;
    inset: 0;
    background:
        linear-gradient(90deg, rgba(18, 19, 22, .94) 0%, rgba(18, 19, 22, .84) 34%, rgba(18, 19, 22, .48) 66%, rgba(18, 19, 22, .30) 100%),
        linear-gradient(0deg, var(--ink-900) 0%, rgba(18, 19, 22, 0) 26%);
}

.hero-slide__inner {
    position: relative;
    z-index: 1;
    max-width: 100%;
}
.hero-slide__inner > * { max-width: 46rem; }
.hero-slide__title { margin-bottom: 1.25rem; }
.hero-slide__lead { margin-bottom: 2rem; }
.hero-slide__points {
    list-style: none;
    padding: 0;
    margin-top: 2.5rem;
}

/* Entrée en cascade du contenu du volet actif */
.hero-slide__kicker,
.hero-slide__title,
.hero-slide__lead,
.hero-slide__actions,
.hero-slide__points {
    opacity: 0;
    transform: translateY(22px);
}
.hero-slide.is-active .hero-slide__kicker,
.hero-slide.is-active .hero-slide__title,
.hero-slide.is-active .hero-slide__lead,
.hero-slide.is-active .hero-slide__actions,
.hero-slide.is-active .hero-slide__points {
    animation: hero-enter .8s cubic-bezier(.22, .8, .3, 1) forwards;
}
.hero-slide.is-active .hero-slide__kicker  { animation-delay: .10s; }
.hero-slide.is-active .hero-slide__title   { animation-delay: .20s; }
.hero-slide.is-active .hero-slide__lead    { animation-delay: .32s; }
.hero-slide.is-active .hero-slide__actions { animation-delay: .44s; }
.hero-slide.is-active .hero-slide__points  { animation-delay: .56s; }

@keyframes hero-enter {
    to { opacity: 1; transform: translateY(0); }
}

/* Sans JavaScript : le contenu doit rester visible et immobile */
.hero--slider:not([data-slider-ready]) .hero-slide:not(.is-active) { display: none; }
.hero--slider:not([data-slider-ready]) .hero-slide__kicker,
.hero--slider:not([data-slider-ready]) .hero-slide__title,
.hero--slider:not([data-slider-ready]) .hero-slide__lead,
.hero--slider:not([data-slider-ready]) .hero-slide__actions,
.hero--slider:not([data-slider-ready]) .hero-slide__points {
    opacity: 1;
    transform: none;
}

/* --- Commandes --- */
.hero-slider__arrow {
    position: absolute;
    top: 50%;
    z-index: 4;
    display: grid;
    place-items: center;
    width: 3.25rem;
    height: 3.25rem;
    margin-top: -1.625rem;
    /* Opacité soutenue : la flèche suivante tombe sur le bord droit de la
       photo, le seul endroit que le voile ne couvre presque pas. */
    border: 1px solid rgba(255, 255, 255, .3);
    border-radius: 50%;
    background: rgba(18, 19, 22, .62);
    color: #fff;
    cursor: pointer;
    backdrop-filter: blur(8px);
    transition: background .25s var(--ease), border-color .25s var(--ease), transform .25s var(--ease);
}
.hero-slider__arrow:hover {
    background: var(--blue);
    border-color: var(--blue);
    transform: scale(1.08);
}
.hero-slider__arrow svg { width: 22px; height: 22px; }
.hero-slider__arrow--prev { left: clamp(.75rem, .25rem + 1.5vw, 2rem); }
.hero-slider__arrow--next { right: clamp(.75rem, .25rem + 1.5vw, 2rem); }

.hero-slider__bar {
    position: absolute;
    left: 50%;
    bottom: clamp(1.25rem, .5rem + 2.5vw, 2.75rem);
    z-index: 4;
    transform: translateX(-50%);
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1.5rem;
}
.hero-slider__dots {
    display: flex;
    flex-wrap: wrap;
    gap: clamp(.75rem, .25rem + 1.5vw, 2rem);
}
.hero-dot {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: .35rem;
    padding: 0 0 .75rem;
    border: 0;
    background: none;
    color: rgba(244, 246, 248, .55);
    text-align: left;
    cursor: pointer;
    transition: color .25s var(--ease);
}
.hero-dot:hover { color: rgba(244, 246, 248, .9); }
.hero-dot.is-active { color: #fff; }
.hero-dot__index {
    font-family: var(--font-mono);
    font-size: .6875rem;
    letter-spacing: .1em;
    color: var(--mint);
}
.hero-dot__label {
    font-family: var(--font-title);
    font-size: .875rem;
    font-weight: 600;
    white-space: nowrap;
}
.hero-dot__track {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 2px;
    background: rgba(255, 255, 255, .18);
    overflow: hidden;
}
.hero-dot__fill {
    display: block;
    height: 100%;
    width: 100%;
    background: linear-gradient(90deg, var(--mint), var(--blue));
    transform: scaleX(0);
    transform-origin: left;
}
.hero-dot.is-active .hero-dot__fill {
    animation: hero-progress var(--slide-duration) linear forwards;
}
/* is-paused : arrêt demandé par l'utilisateur (le bouton change d'icône).
   is-held   : pause temporaire (survol, focus, onglet inactif, hors écran)
               — les animations se figent, mais le bouton reste inchangé. */
.hero--slider.is-paused .hero-dot__fill,
.hero--slider.is-held .hero-dot__fill,
.hero--slider.is-paused .hero-slide__media,
.hero--slider.is-held .hero-slide__media { animation-play-state: paused; }

@keyframes hero-progress {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}

.hero-slider__toggle {
    flex: none;
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border: 1px solid rgba(255, 255, 255, .22);
    border-radius: 50%;
    background: rgba(18, 19, 22, .35);
    cursor: pointer;
    transition: background .25s var(--ease), border-color .25s var(--ease);
}
.hero-slider__toggle:hover { background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .4); }
/* Pause (deux barres) → lecture (triangle) quand le diaporama est arrêté */
.hero-slider__toggle-icon {
    width: 10px;
    height: 12px;
    border-left: 3px solid #fff;
    border-right: 3px solid #fff;
}
.hero--slider.is-paused .hero-slider__toggle-icon {
    width: 0;
    height: 0;
    border: 6px solid transparent;
    border-left: 10px solid #fff;
    margin-left: 3px;
}

@media (max-width: 860px) {
    /* Sur un écran étroit le texte occupe toute la largeur : un voile
       horizontal ne protège plus que son bord gauche et le titre devient
       illisible dès que la photo est claire. On l'assombrit du haut vers
       le bas, dans le sens de lecture. */
    .hero-slide__veil {
        background:
            linear-gradient(180deg, rgba(18, 19, 22, .42) 0%, rgba(18, 19, 22, .74) 46%, rgba(18, 19, 22, .88) 100%),
            linear-gradient(0deg, var(--ink-900) 0%, rgba(18, 19, 22, 0) 18%);
    }

    .hero-slider__arrow { display: none; }
    .hero-dot__label { display: none; }
    .hero-dot { padding-bottom: .6rem; }
    .hero-slider__bar { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
    .hero-slide,
    .hero-slide__media,
    .hero-slide__kicker,
    .hero-slide__title,
    .hero-slide__lead,
    .hero-slide__actions,
    .hero-slide__points,
    .hero-dot__fill {
        animation: none !important;
        transition: none !important;
        transform: none;
        opacity: 1;
    }
    .hero-slide:not(.is-active) { opacity: 0; }
}

@media print {
    .hero-slider__controls { display: none; }
}

/* Bandeau de confiance sous le hero */
.trust-bar {
    background: var(--ink-800);
    border-top: 1px solid rgba(255, 255, 255, .07);
    padding-block: 1.5rem;
}
.trust-bar__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: clamp(1rem, .5rem + 2.5vw, 3rem);
}
.trust-bar span {
    display: inline-flex;
    align-items: center;
    gap: .55rem;
    font-family: var(--font-title);
    font-size: .8125rem;
    font-weight: 500;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: rgba(244, 246, 248, .6);
}
.trust-bar span::before {
    content: '';
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--mint);
}

/* ---------------------------------------------------------------------
   9. Cartes
   --------------------------------------------------------------------- */
.card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: clamp(1.5rem, 1.2rem + 1vw, 2rem);
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
    overflow: hidden;
}
.card::after {
    /* crochet d'angle révélé au survol — rappel du logo */
    content: '';
    position: absolute;
    top: 0; right: 0;
    width: 0; height: 0;
    border-top: 2px solid var(--accent, var(--blue));
    border-right: 2px solid var(--accent, var(--blue));
    transition: width .35s var(--ease), height .35s var(--ease);
}
.card:hover {
    transform: translateY(-6px);
    box-shadow: var(--shadow-lg);
    border-color: transparent;
}
.card:hover::after { width: 34px; height: 34px; }

.card__icon {
    display: grid;
    place-items: center;
    width: 54px; height: 54px;
    border-radius: 14px;
    background: var(--accent-soft, var(--blue-100));
    color: var(--accent-ink, var(--blue-800));
    margin-bottom: 1.25rem;
    transition: transform .35s var(--ease);
}
.card__icon svg { width: 26px; height: 26px; }
.card:hover .card__icon { transform: scale(1.06) rotate(-3deg); }

.card h3 { font-size: var(--step-1); margin-bottom: .5rem; }
.card p { color: var(--text-soft); font-size: .9375rem; margin-bottom: 1.25rem; }
.card .link-arrow { margin-top: auto; }

.card--flat { border-radius: var(--radius); box-shadow: none; }
.card--flat:hover { transform: none; box-shadow: var(--shadow-sm); }

/* Carte sur fond sombre */
.section--dark .card {
    background: rgba(255, 255, 255, .04);
    border-color: rgba(255, 255, 255, .1);
}
.section--dark .card h3 { color: #fff; }
.section--dark .card p { color: rgba(244, 246, 248, .68); }
.section--dark .card__icon { background: rgba(255, 255, 255, .08); color: var(--accent, var(--mint)); }
.section--dark .card:hover { background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .16); }

/* ---------------------------------------------------------------------
   10. Accueil — composants « montrer plutôt que décrire »
   Ces blocs remplacent des sections rédigées : engagements (ex-« neuf
   raisons »), domaines d'expertise et frise de processus n'affichent plus
   que des intitulés, le texte argumenté vivant sur les pages internes.
   --------------------------------------------------------------------- */

/* Engagements : pictogramme + intitulé, sans paragraphe */
.pledges {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: clamp(1.25rem, .75rem + 2vw, 2.5rem);
}
.pledge {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .6rem;
}
.pledge__icon {
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, .07);
    border: 1px solid rgba(255, 255, 255, .12);
    color: var(--accent, var(--mint));
}
.pledge__icon svg { width: 22px; height: 22px; }
.pledge h3 { font-size: 1.0625rem; margin: 0; color: #fff; }
.pledge__note { font-size: .875rem; color: rgba(244, 246, 248, .6); }

/* Domaines d'expertise : bandeau de pastilles, intitulés seuls */
.domains {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
}
.domain {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    padding: .7rem 1.1rem;
    border: 1px solid var(--ink-200);
    border-radius: 999px;
    background: var(--bg);
    font-family: var(--font-title);
    font-size: .9375rem;
    font-weight: 600;
    transition: border-color .25s var(--ease), transform .25s var(--ease), box-shadow .25s var(--ease);
}
.domain:hover {
    border-color: var(--accent, var(--blue));
    transform: translateY(-2px);
    box-shadow: var(--shadow-sm);
}
.domain__icon { display: grid; place-items: center; color: var(--accent, var(--blue)); }
.domain__icon svg { width: 18px; height: 18px; }

/* Frise de processus : la numérotation est un vrai déroulé chronologique */
.timeline {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: 1.5rem 1rem;
    counter-reset: none;
}
.timeline__step {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    padding-top: 2.25rem;
}
/* Filet reliant les étapes, interrompu après la dernière */
.timeline__step::before {
    content: '';
    position: absolute;
    top: .8rem;
    left: 0;
    right: -1rem;
    height: 1px;
    background: rgba(255, 255, 255, .14);
}
.timeline__step:last-child::before { right: 0; }
/* Pastilles numérotées en dégradé aux couleurs du logo. Chaque étape passe
   d'une couleur à la suivante, si bien que la frise parcourt la palette
   entière. Le cycle se répète tous les quatre rangs : les étapes viennent
   de l'administration, leur nombre n'est pas connu à l'avance. */
.timeline__num {
    position: absolute;
    top: 0;
    left: 0;
    display: grid;
    place-items: center;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--blue), var(--mint));
    color: var(--ink-900);
    font-family: var(--font-mono);
    font-size: .75rem;
    font-weight: 700;
}
.timeline__step:nth-child(4n+2) .timeline__num { background: linear-gradient(135deg, var(--mint), var(--amber)); }
.timeline__step:nth-child(4n+3) .timeline__num { background: linear-gradient(135deg, var(--amber), var(--coral)); }
.timeline__step:nth-child(4n+4) .timeline__num { background: linear-gradient(135deg, var(--coral), var(--blue)); }
.timeline__label {
    font-family: var(--font-title);
    font-size: .9375rem;
    font-weight: 600;
    color: #fff;
    text-wrap: balance;
}

/* Carte de service cliquable dans son ensemble */
.card--tile { display: flex; flex-direction: column; text-decoration: none; color: inherit; }
/* Le résumé complet reste dans le HTML ; seul l'affichage est limité à
   deux lignes, pour des cartes de hauteur régulière sans phrase coupée.
   Surtout pas de `flex: 1` ici : le paragraphe encaisserait la hauteur
   restante de la carte la plus haute du rang et se retrouverait tranché au
   milieu d'une ligne. C'est la flèche, en dessous, qui absorbe l'écart. */
.card--tile p {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}
.card--tile .card__go {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    /* `auto` plutôt qu'une marge fixe : la flèche se cale en bas de carte,
       ce qui aligne les flèches d'un même rang quelle que soit la longueur
       des résumés. L'espace au-dessus vient de la marge du paragraphe. */
    margin-top: auto;
    border-radius: 50%;
    background: var(--accent-soft, var(--blue-100));
    color: var(--accent-ink, var(--blue-800));
    transition: transform .25s var(--ease);
}
.card--tile .card__go svg { width: 16px; height: 16px; }
.card--tile:hover .card__go { transform: translateX(4px); }

/* --- Visuel d'un service (partials/visuel.php) ---
   Un seul gabarit, deux contenus possibles : l'image téléversée en
   administration, ou l'icône du service sur un aplat de son accent. Les
   deux occupent exactement la même place, ce qui permet d'illustrer les
   services un par un sans jamais donner une page à moitié terminée. */
.visuel {
    position: relative;
    display: block;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: linear-gradient(140deg, var(--accent-soft, var(--blue-100)), #fff);
}
.visuel img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .6s var(--ease);
}
.visuel__icone {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: var(--accent-ink, var(--blue-800));
    transition: transform .35s var(--ease);
}
.visuel__icone svg { width: 46px; height: 46px; }

/* Hors carte cliquable : le visuel est une illustration à part entière */
.visuel--large {
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
}
.visuel--large .visuel__icone svg { width: 76px; height: 76px; }

/* --- Carte de service illustrée ---
   Le visuel occupe toute la largeur : la carte perd donc son remplissage,
   qui passe au corps de texte. */
.card--illustree { padding: 0; }
.card--illustree:hover .visuel img { transform: scale(1.05); }
.card--illustree:hover .visuel__icone { transform: scale(1.06) rotate(-3deg); }
.card__corps {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: clamp(1.25rem, 1rem + .8vw, 1.75rem);
}

/* Étiquette de catégorie posée sur le visuel d'une carte */
.visuel__badge {
    position: absolute;
    top: .9rem; left: .9rem;
    z-index: 1;
    padding: .35rem .75rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, .95);
    color: var(--ink);
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .04em;
}
/* Ligne discrète sous le titre : client, année, catégorie.
   Elle échappe au `flex: 1` et au tronquage à deux lignes que `.card--tile`
   applique à ses paragraphes : ces règles visent le résumé, pas cette ligne,
   et les deux se disputaient sinon la hauteur restante. */
.card__meta {
    flex: none;
    display: block;
    -webkit-line-clamp: none;
    line-clamp: none;
    font-size: .8125rem;
    color: var(--text-soft);
    margin-bottom: .6rem;
}

@media (prefers-reduced-motion: reduce) {
    .card--illustree:hover .visuel img,
    .card--illustree:hover .visuel__icone { transform: none; }
}

/* ---------------------------------------------------------------------
   10 bis. Mot du dirigeant
   Mise en page éditoriale : le portrait est le sujet, la citation est posée
   par-dessus dans une carte blanche qui mord sur son bord droit. Le
   chevauchement est décalé vers le bas pour ne jamais recouvrir le visage.
   --------------------------------------------------------------------- */
.word { position: relative; overflow: hidden; }
/* Halo aux couleurs du logo, très diffus : détache la section sans la
   surcharger d'un aplat de couleur. */
.word::before {
    content: '';
    position: absolute;
    top: 10%;
    left: -12rem;
    width: 34rem;
    height: 34rem;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(82, 113, 255, .16), transparent 68%);
    pointer-events: none;
}

.word__inner {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 26rem) minmax(0, 1fr);
    align-items: center;
    margin: 0;
}

/* --- Portrait --- */
.word__portrait {
    position: relative;
    grid-column: 1;
    grid-row: 1;
    border-radius: var(--radius-lg);
}
/* Second halo, resserré derrière le portrait : c'est lui qui le met en
   exergue. Posé sur un pseudo-élément en retrait négatif, donc le portrait
   ne peut plus rogner son contenu — l'arrondi passe sur l'image. */
.word__portrait::before {
    content: '';
    position: absolute;
    inset: -1.25rem;
    z-index: -1;
    border-radius: inherit;
    background: linear-gradient(150deg, var(--blue), var(--mint));
    opacity: .22;
    filter: blur(34px);
}
.word__portrait img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}
/* Rappel du motif des crochets d'angle du logo */
.word__portrait::after {
    content: '';
    position: absolute;
    left: 1rem;
    bottom: 1rem;
    width: 2.25rem;
    height: 2.25rem;
    border-left: 3px solid var(--mint);
    border-bottom: 3px solid var(--mint);
}

/* --- Carte de citation, en chevauchement --- */
.word__body {
    position: relative;
    z-index: 2;
    grid-column: 2;
    grid-row: 1;
    margin-left: -5rem;
    margin-top: 4rem;
    padding: clamp(1.75rem, 1.2rem + 2vw, 3rem);
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}
/* Guillemet ouvrant en grand, en filigrane derrière le texte. L'encre d'un
   « “ » occupe le haut de son cadratin : posé à `top: 0`, le glyphe tombe
   dans le coin de la carte au lieu de flotter au-dessus. */
.word__body::before {
    content: '“';
    position: absolute;
    top: 0;
    right: 1.25rem;
    font-family: var(--font-title);
    font-size: 8rem;
    line-height: 1;
    color: var(--mint);
    opacity: .18;
    pointer-events: none;
}

.word__quote {
    position: relative;
    font-size: var(--step-0);
    font-family: var(--font-title);
    font-weight: 500;
    line-height: 1.65;
    /* `balance` est fait pour les titres de quelques mots : sur un
       paragraphe de huit lignes, il égalise les longueurs et laisse une
       colonne inutilement étroite. `pretty` se contente d'éviter les
       lignes orphelines. */
    text-wrap: pretty;
    /* Longueur de ligne plafonnée : sur un écran très large, la colonne de
       texte atteignait 130 caractères, illisible en lecture suivie. */
    max-width: 62ch;
    margin: .75rem 0 0;
    padding: 0;
    border: 0;
}
/* Repli du message sur petit écran. La troncature est posée par app.js et
   non par défaut : sans JavaScript, rien ne doit masquer le texte. */
.word__quote.est-tronque {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 7;
    line-clamp: 7;
    overflow: hidden;
}
.word__plus {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    margin-top: .85rem;
    padding: 0;
    border: 0;
    background: none;
    color: var(--blue);
    font-family: var(--font-title);
    font-size: .9375rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.word__plus:hover { color: var(--ink); }
.word--sombre .word__plus { color: var(--mint); }
.word--sombre .word__plus:hover { color: #fff; }

.word__sign {
    margin-top: 1.75rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--ink-200);
    font-size: 1rem;
}
.word__sign strong { display: block; font-family: var(--font-title); font-size: 1.0625rem; }
.word__sign span { color: var(--text-soft); font-size: .9375rem; }
.word__signature { display: block; height: 3.75rem; width: auto; margin-bottom: .75rem; }

/* --- Sans portrait : la carte occupe seule la largeur --- */
.word__inner--solo { grid-template-columns: minmax(0, 1fr); }
.word__inner--solo .word__body {
    grid-column: 1;
    margin: 0 auto;
    max-width: 52rem;
}

@media (max-width: 900px) {
    /* Le chevauchement passe à la verticale : la carte remonte sur le bas
       de la photo au lieu d'en mordre le côté. */
    .word__inner { grid-template-columns: minmax(0, 1fr); }
    .word__portrait { grid-column: 1; max-width: 20rem; }
    .word__body {
        grid-column: 1;
        grid-row: 2;
        margin-left: 1.5rem;
        margin-top: -3.5rem;
    }
    .word__body::before { font-size: 6rem; }
}

@media (max-width: 520px) {
    .word__body { margin-left: 0; }
}

/* --- Variante sombre : portrait pleine hauteur en bord de page ---
   Le portrait sort du gabarit et touche le bord de l'écran ; un fondu le
   dissout dans le fond sombre, et le texte se pose directement dessus sans
   carte intermédiaire. Il suffit d'ajouter ou de retirer `word--sombre` sur
   la section pour passer d'une variante à l'autre. */
.word--sombre {
    padding: 0;
    background: var(--ink-900);
    color: var(--text-invert);
}
.word--sombre::before { display: none; }             /* halo clair, inutile ici */
/* Le fond sombre occupe toute la largeur, mais la composition reste centrée.
   Gabarit élargi à 1500 px pour cette section seulement : à 1220 px, une fois
   la photo et l'écart retirés, il ne restait pas assez de place au texte. */
.word--sombre > .container { width: min(100% - 2.5rem, 1500px); }

/* Portrait à gauche, texte à droite. Largeur du portrait plafonnée : sur un
   très grand écran, un pourcentage seul en ferait une colonne de 800 px qui
   entraînerait toute la section à près de 1000 px de haut. */
.word--sombre .word__inner {
    grid-template-columns: minmax(0, min(30%, 26rem)) minmax(0, 1fr);
    /* Deux colonnes franchement séparées : le texte ne passe plus sur la
       photo, il lui répond. */
    column-gap: clamp(1.75rem, 1rem + 3vw, 4rem);
    align-items: stretch;
    /* Hauteur volontairement contenue : une bande pleine largeur trop haute
       coupe la page en deux. */
    min-height: clamp(20rem, 16rem + 10vw, 27rem);
}

.word--sombre .word__portrait {
    grid-column: 1;
    grid-row: 1;
    height: 100%;
    /* Arrondi du seul côté extérieur : le côté droit se dissout dans le
       fond, l'y arrondir ne se verrait pas et couperait le fondu. */
    border-radius: var(--radius-lg) 0 0 var(--radius-lg);
    overflow: hidden;
}
.word--sombre .word__portrait::before { display: none; }
/* L'image est sortie du flux : sinon sa hauteur naturelle dicte celle de la
   rangée, et la section entière suit. C'est le texte qui commande, la photo
   remplit ce qui reste. */
.word--sombre .word__portrait img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    border-radius: 0;
    box-shadow: none;
    object-position: center 18%;
}
/* Le crochet d'angle laisse la place au fondu vers le fond de section : le
   bord droit de la photo se dissout au lieu de s'arrêter net, ce qui la relie
   au texte malgré l'écart qui les sépare. */
.word--sombre .word__portrait::after {
    top: 0;
    bottom: 0;
    left: auto;
    right: 0;
    width: 42%;
    height: auto;
    border: 0;
    background: linear-gradient(90deg, rgba(18, 19, 22, 0), var(--ink-900) 96%);
}

.word--sombre .word__body {
    grid-column: 2;
    grid-row: 1;
    align-self: center;
    margin: 0;
    padding: clamp(1.75rem, 1rem + 2.5vw, 3rem) 0;
    background: transparent;
    border: 0;
    box-shadow: none;
}
/* Colonne de texte plus large que la valeur commune : la section pleine
   largeur a la place, et deux lignes de moins allègent nettement le bloc. */
.word--sombre .word__quote { max-width: 82ch; }
/* Sans `z-index`, la carte ne crée plus de contexte d'empilement : le
   `mix-blend-mode` de la signature peut alors se mélanger au fond de la
   section. L'ordre du DOM suffit à la placer au-dessus du portrait. */
.word--sombre .word__body { z-index: auto; }
/* Guillemet aux quatre couleurs du logo plutôt qu'en vert uni : le dégradé
   habille le glyphe lui-même, comme la numérotation des étapes. */
.word--sombre .word__body::before {
    right: 0;
    opacity: .3;
    background-image: linear-gradient(135deg,
        var(--blue) 0%, var(--mint) 34%, var(--amber) 67%, var(--coral) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.word--sombre .word__quote { color: rgba(244, 246, 248, .92); }
.word--sombre .word__sign { border-top-color: rgba(255, 255, 255, .16); }
.word--sombre .word__sign strong { color: #fff; }
.word--sombre .word__sign span { color: rgba(244, 246, 248, .62); }
/* La signature est un tracé sombre sur fond blanc : l'inverser la rend
   visible, mais son fond devient un rectangle noir. `lighten` ne conserve
   alors que ce qui est plus clair que la section — le tracé seul. */
.word--sombre .word__signature {
    filter: invert(1);
    mix-blend-mode: lighten;
}

/* --- Entrée à l'écran ---
   Les deux éléments se rejoignent : le portrait glisse depuis le bord gauche
   en se resserrant, le texte arrive depuis la droite, légèrement en retard.
   Seule la transformation est animée ici — l'opacité reste gérée par
   `.reveal` sur le conteneur, pour ne pas ajouter un second voile. */
.word--sombre .word__portrait,
.word--sombre .word__body {
    transition: transform 1.1s cubic-bezier(.16, .84, .32, 1);
}
.word--sombre .word__portrait { transform: translateX(-4rem) scale(1.06); }
.word--sombre .word__body { transform: translateX(2.5rem); transition-delay: .12s; }

.word--sombre .reveal.is-visible .word__portrait,
.word--sombre .reveal.is-visible .word__body,
.word--sombre .word__inner.is-visible .word__portrait,
.word--sombre .word__inner.is-visible .word__body {
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    .word--sombre .word__portrait,
    .word--sombre .word__body { transform: none; }
}

@media (max-width: 900px) {
    .word--sombre .word__inner { grid-template-columns: minmax(0, 1fr); min-height: 0; }
    /* La grille repasse à une colonne : sans ce rappel, le `grid-column: 2`
       du grand écran créerait une seconde colonne implicite. */
    /* L'image étant hors du flux, c'est au portrait de porter la hauteur :
       sans cela sa rangée reste à zéro et la photo déborde sur le texte. */
    .word--sombre .word__portrait {
        grid-column: 1;
        max-width: none;
        height: clamp(16rem, 55vw, 22rem);
    }
    /* Le glissement latéral n'a plus de sens une fois les blocs empilés */
    .word--sombre .word__portrait,
    .word--sombre .word__body { transform: none; }
    /* Le fondu bascule à la verticale, sous la photo. Il doit être opaque
       assez tôt : le libellé « Le mot du dirigeant » se pose dessus, et sur
       une photo encore visible il devient illisible. */
    .word--sombre .word__portrait::after {
        left: 0;
        right: 0;
        top: auto;
        bottom: 0;
        width: auto;
        height: 65%;
        background: linear-gradient(180deg, rgba(18, 19, 22, 0), var(--ink-900) 72%);
    }
    /* Rappel indispensable : hors media query le texte est en colonne 2.
       Sans ce retour en colonne 1, il créerait une colonne implicite et
       réduirait celle de la photo à néant — photo invisible sur mobile. */
    .word--sombre .word__body {
        grid-column: 1;
        grid-row: 2;
        margin: -3rem 0 0;
        padding-top: 1.25rem;
    }
    /* Le guillemet géant n'a plus la place de respirer sans chevaucher le
       libellé : il disparaît plutôt que de gêner. */
    .word--sombre .word__body::before { display: none; }
}

/* ---------------------------------------------------------------------
   11. Expertise
   --------------------------------------------------------------------- */
.expertise {
    position: relative;
    padding: 1.6rem;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: #fff;
    transition: border-color .3s var(--ease), box-shadow .3s var(--ease), transform .3s var(--ease);
}
.expertise:hover { transform: translateY(-4px); box-shadow: var(--shadow); border-color: transparent; }
.expertise__head { display: flex; align-items: center; gap: .8rem; margin-bottom: .85rem; }
.expertise__icon {
    display: grid; place-items: center;
    width: 40px; height: 40px;
    border-radius: 11px;
    background: var(--accent-soft, var(--blue-100));
    color: var(--accent-ink, var(--blue-800));
    flex: none;
}
.expertise__icon svg { width: 20px; height: 20px; }
.expertise h3 { font-size: 1.0625rem; margin: 0; }
.expertise p { font-size: .9375rem; color: var(--text-soft); margin-bottom: 1rem; }
.expertise ul { list-style: none; padding: 0; margin: 0; display: grid; gap: .45rem; }
.expertise li {
    position: relative;
    padding-left: 1.15rem;
    font-size: .875rem;
    color: var(--ink-600);
    margin: 0;
}
.expertise li::before {
    content: '';
    position: absolute;
    left: 0; top: .5em;
    width: 7px; height: 7px;
    border-left: 2px solid var(--accent, var(--blue));
    border-bottom: 2px solid var(--accent, var(--blue));
}

/* ---------------------------------------------------------------------
   12. Processus
   --------------------------------------------------------------------- */
.process { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr)); }

/* Toute la méthode sur une seule ligne à partir du grand écran : une colonne
   par étape, quel que soit leur nombre. Les cartes se resserrent en
   conséquence — chiffre plus petit, texte plus compact — sans quoi six
   colonnes de 185 px empileraient les descriptions sur douze lignes.
   En dessous de 1100 px la grille reprend son enroulement naturel. */
@media (min-width: 1100px) {
    .process {
        grid-template-columns: none;
        grid-auto-flow: column;
        grid-auto-columns: 1fr;
        gap: .85rem;
    }
    .process .step { padding: 1.35rem 1.15rem; }
    .process .step__num { font-size: 1.85rem; margin-bottom: .4rem; }
    .process .step h3 { font-size: 1rem; }
    .process .step p { font-size: .8125rem; }
}
.step {
    position: relative;
    padding: 1.75rem 1.5rem;
    border-radius: var(--radius);
    background: rgba(255, 255, 255, .04);
    border: 1px solid rgba(255, 255, 255, .09);
    overflow: hidden;
    transition: background-color .3s var(--ease), transform .3s var(--ease);
}
.step:hover { background: rgba(255, 255, 255, .07); transform: translateY(-4px); }
.step__num {
    font-family: var(--font-title);
    font-size: 2.75rem;
    font-weight: 700;
    line-height: 1;
    /* Repli des navigateurs sans découpe du fond sur le texte : le chiffre
       reste le filigrane discret d'origine plutôt que de disparaître. */
    color: rgba(255, 255, 255, .1);
    margin-bottom: .75rem;
    display: block;
}

/* Chiffres en dégradé aux couleurs du logo, comme la frise de l'accueil :
   chaque étape passe d'une couleur à la suivante et le cycle se répète tous
   les quatre rangs, quel que soit le nombre d'étapes défini en administration.
   Ici le dégradé habille le texte lui-même — ce sont de grands chiffres, pas
   des pastilles. */
@supports (background-clip: text) or (-webkit-background-clip: text) {
    .step__num {
        background-image: linear-gradient(135deg, var(--blue), var(--mint));
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
    }
    .step:nth-child(4n+2) .step__num { background-image: linear-gradient(135deg, var(--mint), var(--amber)); }
    .step:nth-child(4n+3) .step__num { background-image: linear-gradient(135deg, var(--amber), var(--coral)); }
    .step:nth-child(4n+4) .step__num { background-image: linear-gradient(135deg, var(--coral), var(--blue)); }
}
.step h3 { font-size: 1.125rem; margin-bottom: .5rem; }
.step p { font-size: .9375rem; margin: 0; }
.step::before {
    content: '';
    position: absolute;
    top: 0; left: 0;
    width: 3px; height: 0;
    background: linear-gradient(var(--mint), var(--blue));
    transition: height .4s var(--ease);
}
.step:hover::before { height: 100%; }

/* ---------------------------------------------------------------------
   13. Chiffres clés
   --------------------------------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); gap: 1.5rem; }
.stat { text-align: center; padding: 1.5rem 1rem; }
.stat__value {
    font-family: var(--font-title);
    font-size: clamp(2.5rem, 2rem + 2.5vw, 3.75rem);
    font-weight: 700;
    line-height: 1;
    letter-spacing: -.03em;
    background: linear-gradient(140deg, var(--mint), var(--blue));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.stat__label {
    display: block;
    margin-top: .6rem;
    font-size: .875rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-soft);
}
.section--dark .stat__label { color: rgba(244, 246, 248, .6); }

/* ---------------------------------------------------------------------
   14. Réalisations
   --------------------------------------------------------------------- */
.project-card {
    position: relative;
    display: flex;
    flex-direction: column;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: #fff;
    border: 1px solid var(--border);
    transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.project-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }
.project-card__media {
    position: relative;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: linear-gradient(140deg, var(--ink-800), var(--ink-600));
}
.project-card__media img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform .6s var(--ease);
}
.project-card:hover .project-card__media img { transform: scale(1.05); }
.project-card__placeholder {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: rgba(255, 255, 255, .5);
}
.project-card__placeholder svg { width: 46px; height: 46px; }
.project-card__cat {
    position: absolute;
    top: 1rem; left: 1rem;
    padding: .35rem .75rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, .95);
    color: var(--ink);
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .04em;
}
.project-card__body { padding: 1.5rem; display: flex; flex-direction: column; flex: 1; }
.project-card h3 { font-size: var(--step-1); margin-bottom: .5rem; }
.project-card p { font-size: .9375rem; color: var(--text-soft); margin-bottom: 1.1rem; }
.project-card__foot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: 1rem; }

/* ---------------------------------------------------------------------
   14 ter. Réalisations — carrousel en perspective
   L'affiche active occupe le centre, les voisines s'échelonnent derrière
   elle en se réduisant. Sans JavaScript, la piste reste une rangée
   défilante ordinaire : c'est le mode par défaut ci-dessous, la scène 3D
   n'est activée que par `data-coverflow-ready`, posé par app.js.
   --------------------------------------------------------------------- */
.coverflow {
    --affiche-largeur: clamp(15rem, 8rem + 18vw, 21rem);
    /* Hauteur dérivée de la largeur, et non un `aspect-ratio` : la scène 3D
       n'a que des enfants absolus, elle doit connaître cette hauteur pour se
       dimensionner. Une seule valeur à changer pour allonger les affiches. */
    --affiche-hauteur: calc(var(--affiche-largeur) * 1.62);
    position: relative;
}

/* --- Mode par défaut, sans JavaScript --- */
.coverflow__piste {
    display: flex;
    gap: clamp(1rem, .6rem + 1.4vw, 1.75rem);
    list-style: none;
    margin: 0;
    padding: 1rem 1.25rem 2rem;
    margin-inline: -1.25rem;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.coverflow__piste::-webkit-scrollbar { display: none; }
.coverflow__piste:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.coverflow__item {
    flex: 0 0 var(--affiche-largeur);
    scroll-snap-align: center;
}

/* --- Scène 3D, une fois app.js passé --- */
.coverflow[data-coverflow-ready] .coverflow__piste {
    display: block;
    position: relative;
    /* `clip` et non `hidden` : les affiches de second plan qui dépassent sur
       un écran étroit sont rognées sans créer de zone défilante — un simple
       `hidden` aurait ajouté une barre horizontale sur mobile. */
    overflow-x: clip;
    overflow-y: visible;
    margin-inline: 0;
    padding: 0;
    height: var(--affiche-hauteur);
    perspective: 1400px;
}
.coverflow[data-coverflow-ready] .coverflow__item {
    position: absolute;
    top: 0;
    left: 50%;
    width: var(--affiche-largeur);
    margin-left: calc(var(--affiche-largeur) / -2);
    transition: transform .55s var(--ease), opacity .55s var(--ease), filter .55s var(--ease);
    will-change: transform;
}
/* Les affiches de second plan reculent visuellement */
.coverflow[data-coverflow-ready] .coverflow__item:not(.is-active) .poster {
    filter: brightness(.78) saturate(.9);
}
.coverflow[data-coverflow-ready] .coverflow__item:not(.is-active) .poster__texte { opacity: 0; }
.coverflow[data-coverflow-ready] .coverflow__item:not(.is-active) .poster:hover {
    filter: brightness(.95) saturate(1);
}

/* --- Affiche --- */
.poster {
    position: relative;
    display: block;
    height: var(--affiche-hauteur);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--ink-800);
    box-shadow: var(--shadow-lg);
    text-decoration: none;
    color: #fff;
    transition: filter .45s var(--ease);
}
.poster__cadre { position: absolute; inset: 0; display: block; }
/* Copie floutée en fond : un visuel paysage garde ainsi ses proportions
   sans laisser de bandes vides sur les côtés. */
.poster__fond {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: blur(22px) brightness(.55);
    transform: scale(1.15);
}
.poster__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
}
.poster__vide {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: rgba(255, 255, 255, .45);
}
.poster__vide svg { width: 46px; height: 46px; }
.poster__voile {
    position: absolute;
    inset: 0;
    background: linear-gradient(0deg, rgba(18, 19, 22, .94) 4%, rgba(18, 19, 22, .55) 34%, rgba(18, 19, 22, .05) 62%);
}

.poster__texte {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .45rem;
    padding: 1.5rem 1.4rem 1.6rem;
    transition: opacity .45s var(--ease);
}
.poster__cat {
    padding: .3rem .7rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, .16);
    backdrop-filter: blur(6px);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .04em;
}
.poster__titre {
    font-family: var(--font-title);
    font-size: 1.15rem;
    font-weight: 600;
    line-height: 1.25;
}
.poster__lien {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    margin-top: .35rem;
    font-size: .875rem;
    color: var(--mint);
}
.poster__lien svg { width: 16px; height: 16px; transition: transform .25s var(--ease); }
.poster:hover .poster__lien svg { transform: translateX(4px); }

/* --- Commandes --- */
.coverflow__commandes {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    margin-top: 2rem;
}
.coverflow__fleche {
    flex: none;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: #fff;
    color: var(--ink);
    cursor: pointer;
    transition: background .25s var(--ease), color .25s var(--ease),
                border-color .25s var(--ease), transform .25s var(--ease);
}
.coverflow__fleche svg { width: 20px; height: 20px; }
.coverflow__fleche:hover:not(:disabled) {
    background: var(--blue);
    border-color: var(--blue);
    color: #fff;
    transform: translateY(-2px);
}
.coverflow__fleche:disabled { opacity: .3; cursor: default; }

.coverflow__pastilles { display: flex; align-items: center; gap: .6rem; }
.coverflow__pastille {
    width: 10px;
    height: 10px;
    padding: 0;
    border: 1px solid var(--ink-300);
    border-radius: 50%;
    background: transparent;
    cursor: pointer;
    transition: background .25s var(--ease), border-color .25s var(--ease), transform .25s var(--ease);
}
.coverflow__pastille.is-active {
    background: var(--blue);
    border-color: var(--blue);
    transform: scale(1.25);
}

@media (prefers-reduced-motion: reduce) {
    .coverflow[data-coverflow-ready] .coverflow__item { transition: none; }
    .coverflow__fleche:hover:not(:disabled) { transform: none; }
    .poster:hover .poster__lien svg { transform: none; }
}

/* ---------------------------------------------------------------------
   14 bis. Carrousel de cartes
   Le défilement est celui du navigateur : la piste est une simple zone
   en dépassement horizontal avec accroche (scroll-snap). Tout fonctionne
   donc sans JavaScript — doigt, trackpad, clavier — et les commandes ne
   sont affichées que si les cartes débordent vraiment.
   --------------------------------------------------------------------- */
.carrousel {
    /* Nombre de cartes visibles : la valeur décimale du format mobile
       laisse dépasser la suivante, seul indice fiable qu'il y a la suite. */
    --carrousel-cartes: 3;
    --carrousel-gap: clamp(1rem, .6rem + 1.4vw, 1.75rem);
    position: relative;
}
@media (max-width: 1080px) { .carrousel { --carrousel-cartes: 2; } }
@media (max-width: 700px)  { .carrousel { --carrousel-cartes: 1.15; } }

.carrousel__piste {
    display: flex;
    gap: var(--carrousel-gap);
    list-style: none;
    margin: 0;
    /* Le survol soulève les cartes de 6px et projette une ombre large :
       sans cette marge intérieure, le dépassement les tronquerait. */
    padding: .75rem 1.25rem 2rem;
    margin-inline: -1.25rem;
    overflow-x: auto;
    /* Explicite : `overflow-x: auto` seul force déjà l'axe vertical en `auto`,
       et l'animation d'apparition des cartes (22px vers le bas) suffirait à
       faire surgir une barre de défilement verticale parasite. */
    overflow-y: hidden;
    overscroll-behavior-x: contain;   /* ne pas déclencher le retour arrière du navigateur */
    scroll-snap-type: x mandatory;
    scroll-padding-left: 1.25rem;
    scroll-behavior: smooth;
    scrollbar-width: none;            /* la jauge sous la piste joue ce rôle */
    -ms-overflow-style: none;
}
.carrousel__piste::-webkit-scrollbar { display: none; }
.carrousel__piste:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
    border-radius: var(--radius-lg);
}

/* `flex-grow: 1` sur une base calculée : tant qu'il y a moins de cartes que
   de places, elles s'étalent et la section reste une grille pleine — dès
   qu'il y en a plus, la ligne déborde, la croissance ne s'applique plus et
   le carrousel prend le relais. Aucune bascule à gérer en JavaScript. */
.carrousel__item {
    flex: 1 0 calc(
        (100% - (var(--carrousel-cartes) - 1) * var(--carrousel-gap)) / var(--carrousel-cartes)
    );
    display: flex;
    scroll-snap-align: start;
}
.carrousel__item > * { width: 100%; }

/* --- Commandes : jauge de progression + flèches --- */
.carrousel__commandes {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    margin-top: .5rem;
}
.carrousel__jauge {
    position: relative;
    flex: 1;
    height: 3px;
    border-radius: 999px;
    background: var(--border);
    overflow: hidden;
}
.carrousel__curseur {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 30%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--blue), var(--mint));
    /* Pas de transition sur `left` : la position est recalculée à chaque
       événement de défilement, une animation la ferait traîner derrière. */
    transition: width .25s var(--ease);
}
.carrousel__fleches { display: flex; gap: .5rem; }
.carrousel__fleche {
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: #fff;
    color: var(--ink);
    cursor: pointer;
    transition: background .25s var(--ease), color .25s var(--ease),
                border-color .25s var(--ease), transform .25s var(--ease);
}
.carrousel__fleche svg { width: 20px; height: 20px; }
.carrousel__fleche:hover:not(:disabled) {
    background: var(--blue);
    border-color: var(--blue);
    color: #fff;
    transform: translateY(-2px);
}
.carrousel__fleche:disabled { opacity: .35; cursor: default; }

.section--dark .carrousel__fleche {
    background: rgba(255, 255, 255, .06);
    border-color: rgba(255, 255, 255, .18);
    color: #fff;
}
.section--dark .carrousel__jauge { background: rgba(255, 255, 255, .14); }

@media (prefers-reduced-motion: reduce) {
    .carrousel__piste { scroll-behavior: auto; }
    .carrousel__curseur { transition: none; }
    .carrousel__fleche:hover:not(:disabled) { transform: none; }
}

.chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.chip {
    display: inline-block;
    padding: .3rem .65rem;
    border-radius: 6px;
    background: var(--ink-100);
    color: var(--ink-600);
    font-size: .75rem;
    font-weight: 500;
    font-family: var(--font-mono);
}
.section--dark .chip { background: rgba(255, 255, 255, .08); color: rgba(244, 246, 248, .8); }

/* Filtres */
.filters { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 2.5rem; }
.filter {
    padding: .55rem 1.1rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: #fff;
    color: var(--ink-600);
    font-size: .875rem;
    font-weight: 500;
    font-family: var(--font-body);
    cursor: pointer;
    transition: all .2s var(--ease);
}
.filter:hover { border-color: var(--ink-300); color: var(--ink); }
.filter.is-active { background: var(--ink); border-color: var(--ink); color: #fff; }

.search-field { position: relative; max-width: 320px; width: 100%; }
.search-field svg {
    position: absolute;
    left: .9rem; top: 50%;
    transform: translateY(-50%);
    width: 18px; height: 18px;
    color: var(--ink-400);
    pointer-events: none;
}
.search-field input { padding-left: 2.6rem; }

/* ---------------------------------------------------------------------
   15. Témoignages
   --------------------------------------------------------------------- */
.testimonial {
    display: flex;
    flex-direction: column;
    padding: 2rem;
    border-radius: var(--radius-lg);
    background: #fff;
    border: 1px solid var(--border);
}
.testimonial__quote { font-size: 1.0625rem; line-height: 1.7; color: var(--ink-700); margin-bottom: 1.5rem; }
.testimonial__quote::before {
    content: '';
    display: block;
    width: 28px; height: 14px;
    margin-bottom: 1rem;
    border-top: 3px solid var(--blue);
    border-left: 3px solid var(--blue);
}
.testimonial__author { display: flex; align-items: center; gap: .9rem; margin-top: auto; }
.testimonial__photo {
    width: 48px; height: 48px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--ink-100);
    flex: none;
}
.testimonial__initials {
    display: grid; place-items: center;
    width: 48px; height: 48px;
    border-radius: 50%;
    background: var(--blue-100);
    color: var(--blue-800);
    font-family: var(--font-title);
    font-weight: 700;
    flex: none;
}
.testimonial__name { font-weight: 600; font-size: .9375rem; }
.testimonial__role { font-size: .8125rem; color: var(--text-soft); }
.rating { display: flex; gap: .15rem; margin-bottom: .9rem; color: var(--amber); }
.rating svg { width: 16px; height: 16px; }

/* ---------------------------------------------------------------------
   16. Appel à l'action
   --------------------------------------------------------------------- */
.cta {
    position: relative;
    overflow: hidden;
    background: var(--ink-900);
    color: #fff;
}
.cta::before {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(60rem 30rem at 15% 0%, rgba(82, 113, 255, .35), transparent 60%),
        radial-gradient(50rem 26rem at 85% 100%, rgba(76, 232, 184, .22), transparent 60%);
}
.cta__inner { position: relative; text-align: center; max-width: 780px; margin-inline: auto; }
.cta h2 { font-size: var(--step-4); color: #fff; }
.cta p { color: rgba(244, 246, 248, .78); font-size: var(--step-1); margin-bottom: 2rem; }

/* ---------------------------------------------------------------------
   17. Pages internes : bandeau de titre
   --------------------------------------------------------------------- */
.page-header {
    position: relative;
    background: var(--ink-900);
    color: #fff;
    padding-block: clamp(3.5rem, 2.5rem + 5vw, 6rem) clamp(3rem, 2rem + 4vw, 5rem);
    overflow: hidden;
}
.page-header::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    background:
        radial-gradient(46rem 22rem at 80% -10%, rgba(82, 113, 255, .3), transparent 60%),
        radial-gradient(40rem 20rem at 0% 120%, rgba(76, 232, 184, .16), transparent 60%);
}

/* Visuel de rubrique : une image parlante derrière le titre — des interfaces
   livrées pour les réalisations, un cadenas pour la confidentialité… Elle est
   posée sous les halos, qui restent la couche colorée du bandeau, et cadrée
   à 72 % : le dessin occupe la droite du fichier, le titre la gauche. */
.page-header__fond {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 72% center;
}
/* Par-dessus le visuel, la même couche porte deux choses : les halos, allégés
   car à pleine intensité ils noieraient le dessin, et surtout le voile de
   lisibilité. Ce voile est ici, en CSS, et non incrusté dans le fichier : il
   doit couvrir la colonne de texte, qui s'arrête aux 780 px du conteneur —
   soit une proportion de la largeur qui change avec l'écran, là où un voile
   gravé dans l'image se déformerait au recadrage. */
.page-header--visuel::before {
    background:
        linear-gradient(95deg,
            rgba(18, 19, 22, .96) 10%,
            rgba(18, 19, 22, .82) 40%,
            rgba(18, 19, 22, .34) 64%,
            rgba(18, 19, 22, 0) 80%),
        radial-gradient(46rem 22rem at 80% -10%, rgba(82, 113, 255, .2), transparent 60%),
        radial-gradient(40rem 20rem at 0% 120%, rgba(76, 232, 184, .12), transparent 60%);
}

/* En dessous de 900 px le titre traverse toute la largeur : le dessin passerait
   derrière le texte. On le laisse deviner plutôt que le montrer. */
@media (max-width: 900px) {
    .page-header__fond { opacity: .5; object-position: 84% center; }
    .page-header--visuel::before {
        background:
            linear-gradient(100deg,
                rgba(18, 19, 22, .96) 20%,
                rgba(18, 19, 22, .86) 70%,
                rgba(18, 19, 22, .62) 100%),
            radial-gradient(46rem 22rem at 80% -10%, rgba(82, 113, 255, .2), transparent 60%);
    }
}

.page-header__inner { position: relative; z-index: 2; max-width: 780px; }
.page-header h1 { color: #fff; margin-bottom: 1rem; }
.page-header p { color: rgba(244, 246, 248, .78); font-size: var(--step-1); margin-bottom: 0; }

.breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    font-size: .8125rem;
    margin-bottom: 1.25rem;
    color: rgba(244, 246, 248, .55);
}
.breadcrumb a { color: rgba(244, 246, 248, .8); }
.breadcrumb a:hover { color: #fff; }
.breadcrumb li { margin: 0; }
.breadcrumb ol { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; list-style: none; padding: 0; margin: 0; }
.breadcrumb li + li::before { content: '/'; margin-right: .5rem; opacity: .5; }

/* ---------------------------------------------------------------------
   18. Contenu éditorial (articles, pages légales)
   --------------------------------------------------------------------- */
.prose { font-size: 1.0625rem; line-height: 1.8; color: var(--ink-700); }
.prose > * + * { margin-top: 1.25em; }
.prose h2 { font-size: var(--step-2); margin-top: 2.5em; margin-bottom: .6em; }
.prose h3 { font-size: var(--step-1); margin-top: 2em; margin-bottom: .5em; }
.prose h2:first-child, .prose h3:first-child { margin-top: 0; }
.prose img { border-radius: var(--radius); margin-block: 2rem; }
.prose blockquote {
    margin: 2rem 0;
    padding: 1.25rem 1.5rem;
    border-left: 3px solid var(--blue);
    background: var(--blue-050);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    font-size: 1.0625rem;
    color: var(--ink-700);
}
.prose blockquote p:last-child { margin-bottom: 0; }
.prose code {
    font-family: var(--font-mono);
    font-size: .9em;
    background: var(--ink-100);
    padding: .15em .4em;
    border-radius: 4px;
}
.prose pre {
    background: var(--ink-900);
    color: #f4f6f8;
    padding: 1.25rem;
    border-radius: var(--radius);
    overflow-x: auto;
}
.prose pre code { background: none; padding: 0; color: inherit; }
.prose ul, .prose ol { padding-left: 1.4em; }
.prose table { width: 100%; border-collapse: collapse; font-size: .9375rem; }
.prose th, .prose td { padding: .75rem 1rem; border: 1px solid var(--border); text-align: left; }
.prose th { background: var(--ink-050); font-weight: 600; }

/* Liste à coches */
.check-list { list-style: none; padding: 0; display: grid; gap: .75rem; }
.check-list li { position: relative; padding-left: 2rem; margin: 0; color: var(--ink-600); }
.check-list li::before {
    content: '';
    position: absolute;
    left: 0; top: .3em;
    width: 18px; height: 18px;
    border-radius: 50%;
    background: var(--accent-soft, var(--blue-100));
}
.check-list li::after {
    content: '';
    position: absolute;
    left: 6px; top: .55em;
    width: 5px; height: 9px;
    border-right: 2px solid var(--accent-ink, var(--blue-800));
    border-bottom: 2px solid var(--accent-ink, var(--blue-800));
    transform: rotate(45deg);
}
.section--dark .check-list li { color: rgba(244, 246, 248, .78); }
.section--dark .check-list li::before { background: rgba(255, 255, 255, .1); }
.section--dark .check-list li::after { border-color: var(--mint); }

/* --- Accordéon --------------------------------------------------------
   Sections repliables d'une fiche : un `<details>` natif, qui s'ouvre sans
   JavaScript, se pilote au clavier et s'imprime déplié (section 26).
   Le titre vit à l'intérieur du `<summary>` : le plan du document reste
   entier, pour le lecteur d'écran comme pour l'indexation. */
.accordeons { margin-top: 2rem; border-bottom: 1px solid var(--border); }

.accordeon { border-top: 1px solid var(--border); }
.accordeon > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.15rem 0;
    cursor: pointer;
    list-style: none;
}
.accordeon > summary::-webkit-details-marker { display: none; }
.accordeon > summary:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
.accordeon__titre { margin: 0; font-size: var(--step-1); }
.accordeon > summary svg {
    width: 20px;
    height: 20px;
    flex: none;
    color: var(--text-soft);
    transition: transform .2s var(--ease), color .2s var(--ease);
}
.accordeon > summary:hover svg { color: var(--accent, var(--blue)); }
.accordeon[open] > summary svg { color: var(--accent, var(--blue)); transform: rotate(90deg); }
.accordeon__corps { padding-bottom: 1.7rem; }

/* ---------------------------------------------------------------------
   19. Formulaires
   --------------------------------------------------------------------- */
.form { display: grid; gap: 1.25rem; }
.form-grid { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
.field { display: flex; flex-direction: column; gap: .45rem; }
.field--full { grid-column: 1 / -1; }

.label {
    font-size: .875rem;
    font-weight: 600;
    color: var(--ink-700);
}
.label .req { color: var(--coral-700); }
.hint { font-size: .8125rem; color: var(--text-soft); }

.input, .select, .textarea, .file {
    width: 100%;
    padding: .85rem 1rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--ink);
    font-family: inherit;
    font-size: .9375rem;
    line-height: 1.5;
    transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-400); }
.input:focus, .select:focus, .textarea:focus, .file:focus {
    outline: none;
    border-color: var(--blue);
    box-shadow: 0 0 0 4px rgba(82, 113, 255, .15);
}
.textarea { min-height: 150px; resize: vertical; }
.select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235A5E67' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 18px;
    padding-right: 2.75rem;
}
.file { padding: .7rem; font-size: .875rem; }
.file::file-selector-button {
    margin-right: .9rem;
    padding: .5rem .9rem;
    border: 0;
    border-radius: 6px;
    background: var(--ink-100);
    color: var(--ink);
    font-family: inherit;
    font-weight: 600;
    font-size: .8125rem;
    cursor: pointer;
}

.is-invalid { border-color: var(--coral-700) !important; }
.field-error { font-size: .8125rem; color: var(--coral-700); font-weight: 500; }

.checkbox { display: flex; align-items: flex-start; gap: .7rem; font-size: .875rem; color: var(--ink-600); cursor: pointer; }
.checkbox input { width: 20px; height: 20px; margin: .1rem 0 0; accent-color: var(--blue); flex: none; cursor: pointer; }

.radio-cards { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr)); }
.radio-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .85rem 1rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    font-size: .875rem;
    cursor: pointer;
    transition: all .2s var(--ease);
}
.radio-card input { accent-color: var(--blue); }
.radio-card:hover { border-color: var(--ink-300); }
.radio-card:has(input:checked) { border-color: var(--blue); background: var(--blue-050); font-weight: 500; }

/* Messages */
.alert {
    display: flex;
    gap: .85rem;
    padding: 1rem 1.25rem;
    border-radius: var(--radius-sm);
    font-size: .9375rem;
    border: 1px solid transparent;
}
.alert svg { width: 20px; height: 20px; flex: none; margin-top: .1rem; }
.alert--success { background: var(--mint-100); border-color: rgba(14, 155, 114, .3); color: #0b6b50; }
.alert--error   { background: var(--coral-100); border-color: rgba(217, 59, 64, .3); color: #a52a2f; }
.alert--info    { background: var(--blue-050); border-color: rgba(82, 113, 255, .25); color: var(--blue-800); }
.alert--warning { background: var(--amber-100); border-color: rgba(138, 106, 0, .3); color: var(--amber-800); }
.alert ul { margin: .4rem 0 0; padding-left: 1.1rem; }

/* ---------------------------------------------------------------------
   20. Contact
   --------------------------------------------------------------------- */
.contact-grid { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: clamp(2rem, 1rem + 3vw, 3.5rem); align-items: start; }
.contact-panel {
    padding: clamp(1.5rem, 1.2rem + 1vw, 2.25rem);
    border-radius: var(--radius-lg);
    background: var(--ink-900);
    color: #fff;
}
.contact-panel h2, .contact-panel h3 { color: #fff; }
.contact-item { display: flex; gap: .9rem; padding-block: 1rem; border-bottom: 1px solid rgba(255, 255, 255, .1); }
.contact-item:last-of-type { border-bottom: 0; }
.contact-item__icon {
    flex: none;
    display: grid; place-items: center;
    width: 42px; height: 42px;
    border-radius: 11px;
    background: rgba(255, 255, 255, .08);
    color: var(--mint);
}
.contact-item__icon svg { width: 20px; height: 20px; }
.contact-item__label { font-size: .75rem; text-transform: uppercase; letter-spacing: .1em; color: rgba(244, 246, 248, .5); }
.contact-item__value { font-weight: 500; color: #fff; word-break: break-word; }
.contact-item__value a { color: #fff; }
.contact-item__value a:hover { color: var(--mint); }

.socials { display: flex; flex-wrap: wrap; gap: .6rem; }
.social {
    display: grid; place-items: center;
    width: 42px; height: 42px;
    border-radius: 11px;
    background: rgba(255, 255, 255, .08);
    color: #fff;
    transition: background-color .2s var(--ease), transform .2s var(--ease);
}
.social:hover { background: var(--blue); color: #fff; transform: translateY(-2px); }
.social svg { width: 19px; height: 19px; }
.footer .social { background: rgba(255, 255, 255, .07); }

.map-embed {
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--border);
    line-height: 0;
}
.map-embed iframe { width: 100%; height: 420px; border: 0; }

/* ---------------------------------------------------------------------
   21. État vide
   --------------------------------------------------------------------- */
.empty-state {
    text-align: center;
    padding: clamp(2.5rem, 2rem + 3vw, 4.5rem) 1.5rem;
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-lg);
    background: var(--bg-soft);
}
.empty-state__icon {
    display: grid; place-items: center;
    width: 64px; height: 64px;
    margin: 0 auto 1.25rem;
    border-radius: 18px;
    background: #fff;
    border: 1px solid var(--border);
    color: var(--ink-400);
}
.empty-state__icon svg { width: 28px; height: 28px; }
.empty-state h3 { font-size: var(--step-1); margin-bottom: .5rem; }
.empty-state p { color: var(--text-soft); max-width: 460px; margin-inline: auto; }
.section--dark .empty-state { background: rgba(255, 255, 255, .03); border-color: rgba(255, 255, 255, .16); }
.section--dark .empty-state__icon { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .12); }

/* ---------------------------------------------------------------------
   22. Pagination
   --------------------------------------------------------------------- */
.pagination { display: flex; flex-wrap: wrap; justify-content: center; gap: .4rem; margin-top: 3rem; }
.pagination a, .pagination span {
    display: grid;
    place-items: center;
    min-width: 42px; height: 42px;
    padding-inline: .75rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: .9375rem;
    font-weight: 500;
    color: var(--ink-600);
    background: #fff;
    transition: all .2s var(--ease);
}
.pagination a:hover { border-color: var(--ink-300); color: var(--ink); }
.pagination .is-current { background: var(--ink); border-color: var(--ink); color: #fff; }
.pagination .is-disabled { opacity: .4; pointer-events: none; }

/* ---------------------------------------------------------------------
   23. Pied de page
   --------------------------------------------------------------------- */
.footer {
    background: var(--ink-900);
    color: rgba(244, 246, 248, .7);
    padding-top: clamp(3.5rem, 2.5rem + 4vw, 5.5rem);
    font-size: .9375rem;
}
.footer__top { display: grid; grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr)); gap: clamp(1.75rem, 1rem + 3vw, 3rem); padding-bottom: 3rem; }
.footer__brand img { height: 52px; margin-bottom: 1.1rem; }
.footer__brand p { max-width: 38ch; margin-bottom: 1.5rem; }
.footer h3 {
    font-size: .8125rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: #fff;
    margin-bottom: 1.1rem;
}
.footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: .6rem; }
.footer li { margin: 0; }
.footer a { color: rgba(244, 246, 248, .7); }
.footer a:hover { color: #fff; }
.footer__contact-line { display: flex; gap: .6rem; align-items: flex-start; }
.footer__contact-line svg { width: 17px; height: 17px; color: var(--mint); flex: none; margin-top: .2rem; }

.newsletter { display: flex; gap: .5rem; margin-top: 1rem; }
.newsletter input {
    flex: 1;
    min-width: 0;
    padding: .75rem .9rem;
    border: 1px solid rgba(255, 255, 255, .16);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, .06);
    color: #fff;
    font-family: inherit;
    font-size: .875rem;
}
.newsletter input::placeholder { color: rgba(244, 246, 248, .45); }
.newsletter input:focus { outline: none; border-color: var(--mint); }
.newsletter button {
    padding: .75rem 1rem;
    border: 0;
    border-radius: var(--radius-sm);
    background: var(--blue);
    color: #fff;
    font-family: var(--font-title);
    font-weight: 600;
    font-size: .875rem;
    cursor: pointer;
    transition: background-color .2s var(--ease);
}
.newsletter button:hover { background: var(--blue-700); }

.footer__bottom {
    border-top: 1px solid rgba(255, 255, 255, .09);
    padding-block: 1.5rem 2rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    font-size: .8125rem;
}
.footer__legal { display: flex; flex-wrap: wrap; gap: 1.25rem; }

/* Bouton WhatsApp flottant */
.whatsapp-fab {
    position: fixed;
    right: 1.25rem; bottom: 1.25rem;
    z-index: 90;
    display: grid; place-items: center;
    width: 56px; height: 56px;
    border-radius: 50%;
    background: #25D366;
    color: #fff;
    box-shadow: 0 10px 30px rgba(37, 211, 102, .4);
    transition: transform .25s var(--ease);
}
.whatsapp-fab:hover { transform: scale(1.08); color: #fff; }
.whatsapp-fab svg { width: 28px; height: 28px; }

/* Retour en haut de page.
   Masqué par `visibility` et non par `display` : la transition reste
   possible, et le bouton sort quand même du parcours clavier tant qu'il
   n'est pas visible. */
.haut-fab {
    position: fixed;
    right: 1.25rem; bottom: 1.25rem;
    z-index: 89;
    display: grid; place-items: center;
    width: 48px; height: 48px;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: #fff;
    color: var(--ink);
    cursor: pointer;
    box-shadow: var(--shadow);
    opacity: 0;
    visibility: hidden;
    transform: translateY(12px);
    transition: opacity .3s var(--ease), visibility .3s var(--ease),
                transform .3s var(--ease), background .25s var(--ease),
                color .25s var(--ease), border-color .25s var(--ease);
}
/* Empilé au-dessus du bouton WhatsApp quand celui-ci est actif */
.haut-fab--empile { bottom: calc(1.25rem + 56px + .75rem); }
.haut-fab.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
.haut-fab:hover {
    background: var(--blue);
    border-color: var(--blue);
    color: #fff;
}
.haut-fab svg { width: 20px; height: 20px; }

/* ---------------------------------------------------------------------
   24. Animations au défilement
   --------------------------------------------------------------------- */
.reveal {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity .7s var(--ease), transform .7s var(--ease);
    will-change: opacity, transform;
}
.reveal.is-visible { opacity: 1; transform: none; }
.reveal-delay-1 { transition-delay: .08s; }
.reveal-delay-2 { transition-delay: .16s; }
.reveal-delay-3 { transition-delay: .24s; }
.reveal-delay-4 { transition-delay: .32s; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    .reveal { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------
   25. Adaptatif
   --------------------------------------------------------------------- */
@media (max-width: 1080px) {
    .hero__inner { grid-template-columns: 1fr; }
    .hero__visual { order: -1; max-width: 460px; }
    .footer__top { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .footer__brand { grid-column: 1 / -1; }
}

@media (max-width: 960px) {
    /* Le menu plein écran sert les deux tailles : plus rien à masquer ici. */
    .contact-grid { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
    :root { --header-h: 68px; }
    .brand img { height: 38px; }
    /* Marges resserrées : sur un téléphone, chaque centimètre repris au
       dégagement est un centimètre rendu au titre et aux boutons. */
    .hero--slider .hero-slide {
        padding-top: calc(var(--header-h) + 1rem);
        padding-bottom: 6rem;
    }
    .btn { width: 100%; }
    .btn-row .btn { width: auto; flex: 1 1 auto; min-width: 200px; }
    .hero__meta { gap: 1rem 1.5rem; }
    .footer__top { grid-template-columns: 1fr; }
    .footer__bottom { flex-direction: column; align-items: flex-start; }
    .section-head--split { flex-direction: column; align-items: flex-start; }
    .whatsapp-fab { width: 50px; height: 50px; right: 1rem; bottom: 1rem; }
    .whatsapp-fab svg { width: 25px; height: 25px; }
    .haut-fab { width: 42px; height: 42px; right: 1rem; bottom: 1rem; }
    .haut-fab--empile { bottom: calc(1rem + 50px + .6rem); }
}

@media (max-width: 420px) {
    .btn-row .btn { width: 100%; min-width: 0; }
}

/* ---------------------------------------------------------------------
   26. Impression
   --------------------------------------------------------------------- */
@media print {
    .header, .footer, .whatsapp-fab, .haut-fab, .panneau, .cta { display: none !important; }
    body { color: #000; background: #fff; }
    .section { padding-block: 1rem; }
    /* Un accordéon replié ne s'imprimerait pas : sur papier, tout est déplié. */
    details > :not(summary) { display: block !important; }
    .accordeon > summary svg { display: none; }
    a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .8em; }
}
