:root {
    --primary: #3BBDEB;
    --primary-dark: #1E5FA8;
    --primary-gradient: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    --ease-premium: cubic-bezier(0.4, 0, 0.2, 1);
}
html { scroll-behavior: smooth; scrollbar-width: thin; scrollbar-color: var(--primary-dark) #f1f5f9; }
body { font-family: 'Inter', sans-serif; }
::selection { background: var(--primary); color: #ffffff; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: #f1f5f9; }
::-webkit-scrollbar-thumb { background: linear-gradient(180deg, var(--primary) 0%, var(--primary-dark) 100%); border-radius: 9999px; }
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}
.gradient-bg {
    background-color: var(--primary-dark);
    background-image: linear-gradient(120deg, #1e40af, var(--primary), var(--primary-dark), #1e40af);
    background-size: 200% 200%;
    animation: gradientShift 18s ease-in-out infinite;
}
.hero-subtitle {
    color: rgba(255, 255, 255, 0.9);
}
@keyframes gradientShift {
    0% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}
.tech-pattern { background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23f1f5f9' fill-opacity='0.05'%3E%3Ccircle cx='30' cy='30' r='2'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); }
.card-hover { transition: transform 0.3s ease, box-shadow 0.3s ease; }
.card-hover:hover { transform: translateY(-5px); box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); }
.animate-fade-in { animation: fadeIn 0.6s ease-in-out; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
.text-logo-blue-light { color: var(--primary); }
.text-logo-blue-dark { color: var(--primary-dark); }
.logo-gradient-text {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}
.gray-to-blue-gradient {
    background: linear-gradient(135deg, #6b7280 0%, #3b82f6 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}
.value-button {
    cursor: pointer;
    transition: all 0.3s ease;
    border-radius: 12px;
    position: relative;
    overflow: hidden;
    min-height: 280px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    width: 100%;
}
.value-button:hover {
    transform: translateY(-8px) scale(1.02);
    box-shadow: 0 25px 50px -12px rgba(59, 130, 246, 0.25);
    background: linear-gradient(135deg, #ffffff 0%, #eff6ff 100%);
}
.value-text {
    line-height: 1.6;
    text-align: center;
    padding: 0 8px;
}
.service-card {
    width: 100%;
    max-width: 100%;
}
.hero-title-spacing {
    margin-top: 3rem;
}
.hero-logo {
    width: 150px;
    height: auto;
    margin: 2rem auto 2rem auto;
    display: block;
    filter: drop-shadow(0 10px 20px rgba(59, 130, 246, 0.3)) drop-shadow(0 6px 10px rgba(59, 130, 246, 0.2)) drop-shadow(0 0 30px rgba(255, 255, 255, 0.35));
    animation: heroLogoIn 0.9s var(--ease-premium) both;
}
@keyframes heroLogoIn {
    from { opacity: 0; transform: scale(0.8); }
    to { opacity: 1; transform: scale(1); }
}
@media (min-width: 768px) {
    .hero-logo {
        width: 220px;
        margin: 3rem auto 2rem auto;
    }
}
.language-selector {
    display: flex;
    align-items: center;
    gap: 8px;
}
.flag-btn {
    /* Two-letter language codes rather than country flags: a flag says nothing
       about a language, and a British one excludes other English speakers.
       Sizing is the only change - padding, radius and border stay as they were,
       so the active outline is untouched. */
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    color: var(--primary-dark);
    user-select: none;
    cursor: pointer;
    transition: all 0.3s ease;
    padding: 4px 8px;
    border-radius: 6px;
    border: 2px solid transparent;
}
.flag-btn:hover {
    background-color: rgba(59, 130, 246, 0.1);
    transform: scale(1.1);
}
.flag-btn.active {
    border-color: #3b82f6;
    background-color: rgba(59, 130, 246, 0.1);
}
.section-spacing {
    margin-bottom: 4rem;
}

/* Harmonized section header pattern: eyebrow label + h2 + gradient underline */
.section-eyebrow {
    display: inline-block;
    color: var(--primary-dark);
    font-weight: 700;
    font-size: 0.8rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    margin-bottom: 0.75rem;
}
.section-eyebrow-light { color: var(--primary); }
.section-title-bar {
    display: block;
    width: 60px;
    height: 4px;
    background: var(--primary-gradient);
    border-radius: 9999px;
    margin: 1rem auto 0 auto;
}

/* Animated heading underline (draws in on scroll) */
.heading-underline {
    display: block;
    width: 60px;
    height: 3px;
    margin-top: 0.6rem;
    background: var(--primary-gradient);
    border-radius: 9999px;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.6s var(--ease-premium);
}
.heading-underline.active {
    transform: scaleX(1);
}
.founders-card {
    /* Fond teinté : la carte se détache du blanc de la page. 4 % de
       --primary, très en deçà du plafond de 8 % au-delà duquel le texte
       le plus clair du site passerait sous le seuil AA. */
    background: linear-gradient(
        135deg,
        white 0%,
        color-mix(in srgb, var(--primary) 4%, white) 100%
    );
    border: 1px solid color-mix(in srgb, var(--primary-dark) 12%, transparent);
    transition: all 0.3s ease;
}
.founders-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}
.quote-style {
    font-style: italic;
    position: relative;
    padding: 1rem 2rem;
    background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
    border-left: 4px solid #3b82f6;
    margin: 1rem 0;
}

/* "La révélation" premium card */
.revelation-card {
    position: relative;
    border-radius: 1.25rem;
    padding: 2.5rem;
    border: 1.5px solid transparent;
    background-image: linear-gradient(135deg, #eff6ff 0%, #ffffff 100%), linear-gradient(135deg, var(--primary), var(--primary-dark));
    background-origin: border-box;
    background-clip: padding-box, border-box;
    box-shadow: 0 20px 40px -22px rgba(30, 95, 168, 0.25);
    will-change: transform;
}
.revelation-item {
    border-radius: 1rem;
    padding: 1.5rem 1rem;
    transition: transform 0.4s var(--ease-premium), box-shadow 0.4s var(--ease-premium);
}
.revelation-item:hover {
    transform: translateY(-5px);
    box-shadow: 0 15px 30px -14px rgba(30, 95, 168, 0.3);
}
.revelation-icon {
    position: relative;
    width: 64px;
    height: 64px;
    border-radius: 9999px;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1rem auto;
    box-shadow: 0 8px 20px -8px rgba(30, 95, 168, 0.45);
}
.revelation-icon::before {
    content: '';
    position: absolute;
    inset: -25%;
    background: conic-gradient(from 0deg, var(--primary), var(--primary-dark), var(--primary));
    animation: revelationSpin 4s linear infinite;
    animation-play-state: paused;
}
.revelation-icon i {
    position: relative;
    z-index: 1;
    color: #ffffff;
    font-size: 1.25rem;
    transition: transform 0.4s var(--ease-premium);
}
.revelation-item:hover .revelation-icon::before {
    animation-play-state: running;
}
.revelation-item:hover .revelation-icon i {
    transform: scale(1.1);
}
@keyframes revelationSpin {
    to { transform: rotate(360deg); }
}

/* Premium closing quote */
.premium-quote {
    position: relative;
    display: flex;
    align-items: center;
    gap: 1.5rem;
    text-align: left;
    background: linear-gradient(90deg, #eff6ff 0%, rgba(239, 246, 255, 0) 100%);
    border-radius: 0 1rem 1rem 0;
    padding: 2rem 2rem 2rem 2.5rem;
    overflow: hidden;
    transition: box-shadow 0.4s var(--ease-premium);
}
.premium-quote::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    width: 4px;
    height: 100%;
    background: var(--primary-gradient);
    transform: scaleY(0);
    transform-origin: top;
    transition: transform 0.7s var(--ease-premium);
}
.premium-quote.active::before {
    transform: scaleY(1);
}
.premium-quote:hover {
    box-shadow: 0 15px 35px -18px rgba(30, 95, 168, 0.4);
}
.premium-quote-icon {
    flex-shrink: 0;
    font-size: 2.25rem;
    background: var(--primary-gradient);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    opacity: 0;
    transition: opacity 0.6s var(--ease-premium) 0.2s;
}
.premium-quote p {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.6s var(--ease-premium) 0.35s, transform 0.6s var(--ease-premium) 0.35s;
}
.premium-quote.active .premium-quote-icon,
.premium-quote.active p {
    opacity: 1;
    transform: translateY(0);
}
@media (max-width: 640px) {
    .premium-quote { flex-direction: column; text-align: center; gap: 1rem; }
}
.challenge-item {
    border-radius: 12px;
    padding: 2rem;
    margin-bottom: 2rem;
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
    transition: all 0.4s var(--ease-premium);
    border: 2px solid transparent;
    background-image: linear-gradient(white, white), linear-gradient(135deg, var(--primary), var(--primary-dark));
    background-origin: border-box;
    background-clip: padding-box, border-box;
}
.challenge-item:hover {
    transform: translateY(-6px);
    box-shadow: 0 20px 30px -10px rgba(30, 95, 168, 0.3);
}
.challenge-icon { transition: transform 0.45s var(--ease-premium); }
.challenge-item:hover .challenge-icon { animation: iconWiggle 0.5s var(--ease-premium); }
@keyframes iconWiggle {
    0%, 100% { transform: rotate(0deg) scale(1.15); }
    25% { transform: rotate(-5deg) scale(1.15); }
    75% { transform: rotate(5deg) scale(1.15); }
}

/* Hero background: animated tech-pattern layer (diagonal drift, own DOM layer so it
   never collides with .gradient-bg's background-image on the section itself) */
.hero-pattern-layer {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: 0.5;
    background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.08'%3E%3Ccircle cx='30' cy='30' r='2'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
    background-size: 60px 60px;
    animation: heroPatternDrift 60s linear infinite;
}
@keyframes heroPatternDrift {
    from { background-position: 0 0; }
    to { background-position: 600px 600px; }
}

/* Hero decorative floating blob shapes */
.hero-shapes {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}
.hero-shape {
    position: absolute;
    filter: blur(70px);
    will-change: transform;
}
.hero-shape-1 { width: 240px; height: 240px; top: 6%; left: 6%; border-radius: 60% 40% 70% 30% / 50% 60% 40% 50%; background: rgba(255, 255, 255, 0.13); animation: heroFloatA 12s ease-in-out infinite; }
.hero-shape-2 { width: 220px; height: 220px; bottom: 6%; right: 8%; border-radius: 40% 60% 30% 70% / 60% 40% 60% 40%; background: rgba(59, 189, 235, 0.15); animation: heroFloatB 15s ease-in-out infinite; }
.hero-shape-3 { width: 160px; height: 160px; top: 42%; right: 22%; border-radius: 50% 50% 70% 30% / 40% 60% 40% 60%; background: rgba(96, 165, 250, 0.13); animation: heroFloatC 8s ease-in-out infinite; }
.hero-shape-4 { width: 190px; height: 190px; top: 14%; left: 74%; border-radius: 70% 30% 50% 50% / 50% 50% 60% 40%; background: rgba(255, 255, 255, 0.1); animation: heroFloatA 10s ease-in-out infinite reverse; }
@keyframes heroFloatA {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50% { transform: translate(22px, -26px) scale(1.15); }
}
@keyframes heroFloatB {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50% { transform: translate(-26px, 20px) scale(1.1); }
}
@keyframes heroFloatC {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50% { transform: translate(16px, 18px) scale(0.9); }
}

/* Rising particle "bubbles" (generated in JS) */
.hero-particles {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}
.hero-particle {
    position: absolute;
    bottom: -10px;
    border-radius: 9999px;
    will-change: transform, opacity;
    animation-name: heroParticleRise;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}
@keyframes heroParticleRise {
    0% { transform: translateY(0); opacity: 0; }
    10% { opacity: 1; }
    85% { opacity: 1; }
    100% { transform: translateY(-110vh); opacity: 0; }
}

/* Radar-style concentric rings from a corner */
.hero-rings {
    position: absolute;
    top: 12%;
    right: 6%;
    width: 200px;
    height: 200px;
    pointer-events: none;
    z-index: 0;
}
.hero-ring {
    position: absolute;
    inset: 0;
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: 9999px;
    animation: heroRingPulse 4.5s ease-out infinite;
}
.hero-ring:nth-child(2) { animation-delay: 1.5s; }
.hero-ring:nth-child(3) { animation-delay: 3s; }
@keyframes heroRingPulse {
    0% { transform: scale(0.3); opacity: 0.6; }
    100% { transform: scale(1.4); opacity: 0; }
}

/* Mouse-follow spotlight glow */
.hero-spotlight {
    position: absolute;
    top: 0;
    left: 0;
    width: 380px;
    height: 380px;
    border-radius: 9999px;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.18) 0%, rgba(255, 255, 255, 0) 70%);
    pointer-events: none;
    z-index: 1;
    opacity: 0;
    will-change: transform, opacity;
    transition: opacity 0.6s ease;
}
.hero-spotlight.active { opacity: 1; }

section#accueil { position: relative; overflow: hidden; }
#accueil .container { position: relative; z-index: 5; }

.hero-wave {
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    line-height: 0;
    z-index: 6;
}
.hero-wave svg {
    width: 100%;
    height: 60px;
    display: block;
}

.btn-cta-primary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    transition: all 0.3s ease;
}
.btn-cta-primary:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.25);
}
.btn-cta-outline {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    background: transparent;
    border: 2px solid #ffffff;
    color: #ffffff;
    transition: all 0.3s ease;
}
.btn-cta-outline:hover {
    background: #ffffff;
    color: var(--primary-dark);
    border-color: #ffffff;
    transform: translateY(-3px);
    box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.25);
}

.scroll-indicator {
    position: absolute;
    bottom: 5rem;
    left: 50%;
    transform: translateX(-50%);
    color: #ffffff;
    font-size: 1.5rem;
    opacity: 0.7;
    animation: scrollBounce 2s ease-in-out infinite;
    z-index: 6;
}
@keyframes scrollBounce {
    0%, 100% { transform: translateX(-50%) translateY(0); opacity: 0.6; }
    50% { transform: translateX(-50%) translateY(10px); opacity: 1; }
}

/* Scroll reveal animations */
.reveal {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.7s var(--ease-premium), transform 0.7s var(--ease-premium);
}
.reveal.active {
    opacity: 1;
    transform: translateY(0);
}

/* Navbar: glassmorphism + shrink on scroll */
#site-header {
    background: rgba(255, 255, 255, 0.97);
    transition: background 0.4s var(--ease-premium), box-shadow 0.4s var(--ease-premium);
}
#site-header.scrolled {
    background: rgba(255, 255, 255, 0.75);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow: 0 8px 30px rgba(30, 95, 168, 0.1);
}
#site-header .nav-inner { position: relative; transition: padding 0.4s var(--ease-premium); }
#site-header.scrolled .nav-inner { padding-top: 0.5rem; padding-bottom: 0.5rem; }
.nav-logo { transition: height 0.4s var(--ease-premium); }
#site-header.scrolled .nav-logo { height: 2.75rem; }

/* Le menu compte cinq entrées, dont trois portent un chevron. Sur une tablette
   à 768 px la rangée logo + menu + sélecteur de langue devenait trop juste pour
   être garantie : le menu déroulant bascule donc en burger sous 1024 px plutôt
   que sous 768 px. C'est le seul réglage à reprendre pour revenir en arrière :
   remettre lg:flex / lg:hidden en md:flex / md:hidden dans l'en-tête de
   index.html, et ce palier à 1024 px.

   Au-dessus de 1024 px les cinq entrées tiennent avec 1,5 rem d'écart, et
   respirent à 2 rem dès 1280 px. */
.nav-entries { gap: 1.5rem; }
@media (min-width: 1280px) { .nav-entries { gap: 2rem; } }

.nav-link { position: relative; padding-bottom: 4px; }
.nav-link::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 2px;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.3s var(--ease-premium);
}
.nav-link:hover::after { transform: scaleX(1); }

/* Nav dropdown "Notre histoire" (desktop) */
.nav-dropdown { position: relative; }
.nav-dropdown-trigger { display: inline-flex; align-items: center; gap: 0.35rem; }
.nav-chevron { flex-shrink: 0; transition: transform 0.25s var(--ease-premium); }
.nav-dropdown.open > .nav-dropdown-trigger .nav-chevron { transform: rotate(180deg); }
.nav-dropdown-panel {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 60;
    min-width: 15rem;
    /* transparent bridge: keeps the pointer inside .nav-dropdown across the visual gap */
    padding-top: 12px;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(-6px);
    transition: opacity 0.25s var(--ease-premium), transform 0.25s var(--ease-premium), visibility 0.25s var(--ease-premium);
}
.nav-dropdown.open .nav-dropdown-panel {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
}
.nav-dropdown-inner {
    background: rgba(255, 255, 255, 0.98);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-radius: 0.75rem;
    box-shadow: 0 12px 30px rgba(30, 95, 168, 0.14);
    overflow: hidden;
}
.nav-dropdown-item {
    display: block;
    padding: 0.7rem 1.25rem;
    font-weight: 500;
    white-space: nowrap;
    transition: background 0.25s var(--ease-premium), color 0.25s var(--ease-premium);
}
.nav-dropdown-item + .nav-dropdown-item { border-top: 1px solid rgba(30, 95, 168, 0.1); }
.nav-dropdown-item:hover,
.nav-dropdown-item:focus-visible {
    background: rgba(59, 189, 235, 0.08);
    color: var(--primary-dark);
}
.nav-dropdown-item:focus-visible,
.mobile-menu .mobile-sub-link:focus-visible,
.mobile-accordion-trigger:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: -2px;
}

/* Scroll-spy active state (the parent entry stays active for its three sub-sections) */
.nav-link.active { color: var(--primary-dark); }
.nav-link.active::after { transform: scaleX(1); }
.nav-dropdown-item.active,
.mobile-menu .mobile-sub-link.active {
    color: var(--primary-dark);
    background: rgba(59, 189, 235, 0.08);
}
.mobile-accordion-trigger.active { color: var(--primary-dark); }

/* Nav dropdown as an inline accordion inside the burger menu */
.mobile-accordion-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 0.5rem 0;
    background: none;
    border: 0;
    /* font-family/size only: color and weight stay owned by the Tailwind classes on the
       button, so it matches the sibling top-level links exactly */
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
    text-align: left;
    cursor: pointer;
}
.mobile-accordion.open .nav-chevron { transform: rotate(180deg); }
.mobile-accordion-panel {
    max-height: 0;
    overflow: hidden;
    margin-left: 0.25rem;
    border-left: 2px solid rgba(30, 95, 168, 0.1);
    /* visibility keeps the folded sub-links out of the keyboard tab order */
    visibility: hidden;
    transition: max-height 0.35s var(--ease-premium), visibility 0.35s var(--ease-premium);
}
.mobile-accordion.open .mobile-accordion-panel {
    max-height: 320px;
    visibility: visible;
}
.mobile-menu .mobile-sub-link {
    display: block;
    padding: 0.45rem 0 0.45rem 0.85rem;
    font-size: 0.95rem;
    transition: background 0.25s var(--ease-premium), color 0.25s var(--ease-premium);
}
.mobile-menu .mobile-sub-link + .mobile-sub-link { border-top: 1px solid rgba(30, 95, 168, 0.1); }
.mobile-menu .mobile-sub-link:hover { color: var(--primary-dark); }

.hamburger {
    position: relative;
    width: 26px;
    height: 20px;
    cursor: pointer;
}
.hamburger span {
    position: absolute;
    left: 0;
    width: 100%;
    height: 2px;
    background: var(--primary-dark);
    border-radius: 2px;
    transition: all 0.35s var(--ease-premium);
}
.hamburger span:nth-child(1) { top: 0; }
.hamburger span:nth-child(2) { top: 9px; }
.hamburger span:nth-child(3) { top: 18px; }
.hamburger.open span:nth-child(1) { top: 9px; transform: rotate(45deg); }
.hamburger.open span:nth-child(2) { opacity: 0; }
.hamburger.open span:nth-child(3) { top: 9px; transform: rotate(-45deg); }

.mobile-menu {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    background: rgba(255, 255, 255, 0.98);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    padding: 0 1.5rem;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.45s var(--ease-premium), padding 0.45s var(--ease-premium);
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.08);
}
.mobile-menu.open {
    /* Cinq entrées dont trois dépliables. js/main.js n'en ouvre qu'une à la fois,
       la hauteur à prévoir est donc celle de la plus fournie (À propos, quatre
       sous-liens), pas celle des trois cumulées. overflow-y garde les écrans
       courts lisibles, overflow-x reste masqué par la règle de base. */
    max-height: min(85vh, 640px);
    padding: 1.5rem;
    overflow-y: auto;
}
.mobile-menu a { display: block; padding: 0.5rem 0; }

/* Hero word-cascade title */
.word-reveal {
    display: inline-block;
    opacity: 0;
    transform: translateY(20px);
    animation: wordIn 0.6s var(--ease-premium) forwards;
}
@keyframes wordIn {
    to { opacity: 1; transform: translateY(0); }
}

/* Magnetic CTA icon slide */
.btn-cta-primary i, .btn-cta-outline i, .btn-cta-shine i {
    transition: transform 0.35s var(--ease-premium);
}
.btn-cta-primary:hover, .btn-cta-outline:hover {
    transform: translateY(-4px) scale(1.05);
}
.btn-cta-primary:hover i, .btn-cta-outline:hover i {
    transform: translateX(5px);
}

/* Stagger grid children */
.stagger-grid > * { opacity: 0; transform: translateY(30px); transition: opacity 0.6s var(--ease-premium), transform 0.6s var(--ease-premium); }
.stagger-grid > *.active { opacity: 1; transform: translateY(0); }

/* Animated counters */
.counter { font-variant-numeric: tabular-nums; }

/* Founder avatar subtle zoom */
.founder-avatar { transition: transform 0.4s var(--ease-premium); }
.founders-card:hover .founder-avatar { transform: scale(1.1); }

/* Missions cards: gradient icon circle + hover fill invert */
.service-icon-wrap {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    transition: transform 0.4s var(--ease-premium), background 0.4s var(--ease-premium);
}
/* Survol de la pastille : le dégradé s'enfonce au lieu de s'effacer.
   L'ancien rgba(255, 255, 255, 0.2) supposait une carte qui fonce au
   survol ; la carte reste blanche, la pastille devenait donc blanche
   sous une icône blanche. Ici l'icône gagne en lisibilité au survol
   au lieu de disparaître : 2,17:1 au repos sur le point le plus clair
   du dégradé, 6,45:1 au survol. L'agrandissement, lui, était déjà bon. */
.service-card:hover .service-icon-wrap {
    background: linear-gradient(135deg, var(--primary-dark) 0%, color-mix(in srgb, var(--primary-dark) 75%, black) 100%);
    transform: scale(1.1);
}
.service-card {
    transition: transform 0.35s var(--ease-premium), box-shadow 0.35s var(--ease-premium), background 0.45s var(--ease-premium);
}
.service-card:hover {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
}
.service-card:hover h3,
.service-card:hover p,
.service-card:hover li,
.service-card:hover span,
.service-card:hover li i {
    color: #ffffff !important;
}
.service-card:hover::before { background: rgba(255, 255, 255, 0.6); }

/* Valeurs: icon animation */
.value-icon i { transition: transform 0.4s var(--ease-premium); }
.value-button:hover .value-icon i { transform: rotate(15deg) scale(1.2); }

/* Clickable contact values (mailto: / tel:) - inherits its colour from the
   Tailwind class on the element, so no new colour is introduced. */
.contact-value-link { transition: opacity 0.25s var(--ease-premium); }
.contact-value-link:hover { text-decoration: underline; opacity: 0.85; }

/* Contact cards */
.contact-card {
    border-radius: 1rem;
    padding: 1.25rem;
    transition: transform 0.35s var(--ease-premium), background 0.35s ease;
}
.contact-card:hover {
    transform: translateY(-6px);
    background: rgba(255, 255, 255, 0.06);
}
.contact-icon-circle {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    transition: transform 0.4s var(--ease-premium);
}
.contact-card:hover .contact-icon-circle {
    transform: scale(1.12) rotate(8deg);
}

/* Shine CTA button */
.btn-cta-shine {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    color: #ffffff;
    padding: 1rem 2.5rem;
    border-radius: 9999px;
    font-weight: 600;
    font-size: 1.125rem;
    box-shadow: 0 15px 30px -10px rgba(30, 95, 168, 0.5);
    transition: transform 0.35s var(--ease-premium), box-shadow 0.35s var(--ease-premium);
    position: relative;
    overflow: hidden;
    isolation: isolate;
}
.btn-cta-shine:hover {
    transform: translateY(-4px) scale(1.03);
    box-shadow: 0 20px 40px -10px rgba(30, 95, 168, 0.6);
}
.btn-cta-shine:hover i { transform: translateX(5px); }
.btn-cta-shine::after {
    content: '';
    position: absolute;
    top: 0;
    left: -75%;
    width: 50%;
    height: 100%;
    background: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.6), transparent);
    transform: skewX(-20deg);
    animation: shineMove 3.5s ease-in-out infinite;
}
@keyframes shineMove {
    0% { left: -75%; }
    50%, 100% { left: 125%; }
}

/* Footer */
.contact-bg { background-color: #1a3a6b; }
.footer-bg { background-color: #0d1f3c; }
.footer-top-bar {
    height: 3px;
    background: linear-gradient(90deg, var(--primary) 0%, var(--primary-dark) 55%, transparent 100%);
    box-shadow: 0 0 15px rgba(59, 189, 235, 0.5);
}
.footer-logo {
    filter: brightness(0) invert(1) drop-shadow(0 4px 10px rgba(59, 189, 235, 0.35));
}
.footer-social-icon {
    width: 40px;
    height: 40px;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.1);
    color: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s var(--ease-premium);
}
.footer-social-icon:hover {
    background: var(--primary-gradient);
    transform: scale(1.12) translateY(-2px);
}
.footer-heading {
    position: relative;
    padding-bottom: 0.75rem;
}
.footer-heading::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 30px;
    height: 2px;
    background: var(--primary-gradient);
}
.footer-link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    transition: color 0.3s var(--ease-premium), transform 0.3s var(--ease-premium);
}
.footer-link i {
    color: var(--primary);
    font-size: 0.65rem;
}
.footer-link:hover {
    color: var(--primary);
    transform: translateX(5px);
}
.footer-contact-icon {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.1);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-right: 0.65rem;
    flex-shrink: 0;
    color: #ffffff;
    transition: all 0.3s var(--ease-premium);
}
.footer-contact-item:hover .footer-contact-icon {
    background: var(--primary-gradient);
}
.footer-divider {
    border-top: 1px solid rgba(255, 255, 255, 0.1);
}

/* Back to top */
.back-to-top {
    position: fixed;
    bottom: 2rem;
    right: 2rem;
    width: 48px;
    height: 48px;
    border: none;
    border-radius: 9999px;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    color: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 10px 25px -5px rgba(30, 95, 168, 0.45);
    opacity: 0;
    visibility: hidden;
    transform: translateY(20px);
    transition: opacity 0.35s var(--ease-premium), transform 0.35s var(--ease-premium), visibility 0.35s;
    z-index: 60;
    cursor: pointer;
}
.back-to-top.visible { opacity: 1; visibility: visible; transform: translateY(0); }
.back-to-top:hover { transform: translateY(-4px) scale(1.08); }

/* Enhanced card hover: elevation + blue gradient bar */
.founders-card,
.service-card,
.value-button,
.team-card {
    position: relative;
    overflow: hidden;
}
.founders-card::before,
.service-card::before,
.value-button::before,
.team-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 4px;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.35s ease;
    border-radius: 4px 4px 0 0;
}
.founders-card:hover::before,
.service-card:hover::before,
.value-button:hover::before,
.team-card:hover::before {
    transform: scaleX(1);
}
.founders-card:hover,
.service-card:hover,
.team-card:hover {
    transform: translateY(-10px);
    box-shadow: 0 25px 40px -10px rgba(30, 95, 168, 0.35);
}
.team-card {
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

/* Expertise badges */
.expertise-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.35rem 0.85rem;
    border-radius: 9999px;
    background: rgba(59, 130, 246, 0.1);
    color: var(--primary-dark);
    font-size: 0.8rem;
    font-weight: 600;
    margin: 0.25rem;
    border: 1px solid rgba(59, 130, 246, 0.2);
    transition: all 0.3s ease;
    cursor: default;
}
.expertise-badge:hover {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    color: #ffffff;
    border-color: transparent;
    transform: translateY(-2px);
}

/* Testimonials carousel */
.testimonial-card {
    background: #ffffff;
    border-radius: 1.5rem;
    padding: 2.5rem;
    box-shadow: 0 20px 40px -15px rgba(30, 95, 168, 0.2);
    text-align: center;
}
.testimonial-quote-icon {
    width: 56px;
    height: 56px;
    border-radius: 9999px;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1.5rem auto;
    color: #ffffff;
    font-size: 1.25rem;
}
.testimonial-avatar {
    width: 56px;
    height: 56px;
    border-radius: 9999px;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #ffffff;
    font-weight: 700;
    margin: 0 auto 0.75rem auto;
}
/* Widths derive from --slide-count, which tools/build-pillars.js writes on the track
   from the number of slides it finds in the partial. The fallback of 3 keeps the
   carousel correct if the attribute is ever missing. */
#testimonial-track {
    display: flex;
    width: calc(var(--slide-count, 3) * 100%);
    transition: transform 0.6s var(--ease-premium);
}
.testimonial-slide {
    width: calc(100% / var(--slide-count, 3));
    flex-shrink: 0;
    padding: 0 0.5rem;
    box-sizing: border-box;
}
.testimonial-stars {
    color: #f59e0b;
}
.testimonial-arrow {
    width: 44px;
    height: 44px;
    border-radius: 9999px;
    background: #ffffff;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--primary-dark);
    transition: all 0.3s ease;
    cursor: pointer;
}
.testimonial-arrow:hover {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    color: #ffffff;
    transform: scale(1.1);
}
.testimonial-dot {
    width: 10px;
    height: 10px;
    border-radius: 9999px;
    background: #cbd5e1;
    cursor: pointer;
    transition: all 0.3s ease;
}
.testimonial-dot.active {
    background: var(--primary-dark);
    width: 28px;
    border-radius: 9999px;
}

/* "Notre promesse d'excellence" block */
.promise-block {
    position: relative;
    overflow: hidden;
    border-radius: 1.5rem;
    padding: 3rem 2rem;
    /* Était linear-gradient(120deg, #3b82f6, #8b5cf6, #3b82f6) : un bleu et
       un violet Tailwind hérités du gabarit initial, seul violet du site.
       background-size et l'animation suivent, donc le raccourci background
       ne les écrase pas. */
    background: var(--primary-gradient);
    background-size: 200% 200%;
    animation: promiseGradientShift 13s ease infinite;
    box-shadow: 0 30px 60px -20px rgba(59, 130, 246, 0.5);
    color: #ffffff;
}
@keyframes promiseGradientShift {
    0% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}
.promise-shapes {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}
.promise-shape {
    position: absolute;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.1);
    filter: blur(35px);
}
.promise-shape-1 { width: 160px; height: 160px; top: -30px; left: 6%; animation: promiseFloat1 9s ease-in-out infinite; }
.promise-shape-2 { width: 200px; height: 200px; bottom: -50px; right: 8%; animation: promiseFloat2 12s ease-in-out infinite; }
.promise-shape-3 { width: 120px; height: 120px; top: 45%; right: 32%; animation: promiseFloat3 7.5s ease-in-out infinite; }
@keyframes promiseFloat1 { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(22px) scale(1.15); } }
@keyframes promiseFloat2 { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-25px) scale(1.1); } }
@keyframes promiseFloat3 { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(15px) scale(0.9); } }
.promise-pattern-overlay {
    position: absolute;
    inset: 0;
    background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.06'%3E%3Ccircle cx='30' cy='30' r='2'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
    opacity: 0.6;
    pointer-events: none;
    z-index: 0;
}
.promise-tilt-target {
    position: relative;
    z-index: 1;
    transform-style: preserve-3d;
}
.promise-tilt-reset {
    transition: transform 0.5s var(--ease-premium);
}
.promise-title-bar {
    display: block;
    width: 60px;
    height: 3px;
    margin: 0.75rem auto 0 auto;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.25));
    border-radius: 9999px;
    transform: scaleX(0);
    transition: transform 0.7s var(--ease-premium);
}
.promise-title-bar.active {
    transform: scaleX(1);
}

/* Pillar cards */
.promise-grid.stagger-grid > * {
    transform: translateY(30px) scale(0.9);
}
.promise-grid.stagger-grid > *.active {
    transform: translateY(0) scale(1);
}
.promise-card {
    position: relative;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 1rem;
    padding: 1.75rem 1.25rem;
    text-align: center;
    transition: transform 0.4s var(--ease-premium), background 0.4s var(--ease-premium), box-shadow 0.4s var(--ease-premium);
}
.promise-card:hover {
    transform: translateY(-8px);
    background: rgba(255, 255, 255, 0.2);
    box-shadow: 0 20px 40px -18px rgba(0, 0, 0, 0.35);
}
@media (min-width: 768px) {
    .promise-grid > *:not(:first-child) {
        position: relative;
    }
    .promise-grid > *:not(:first-child)::before {
        content: '';
        position: absolute;
        left: -0.75rem;
        top: 15%;
        bottom: 15%;
        width: 1px;
        background: rgba(255, 255, 255, 0.15);
    }
}
.promise-icon-wrap {
    width: 56px;
    height: 56px;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.2);
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 0.9rem auto;
    transition: box-shadow 0.4s var(--ease-premium), background 0.4s var(--ease-premium);
}
.promise-icon-wrap i {
    font-size: 1.5rem;
    color: #ffffff;
}
.promise-card:hover .promise-icon-wrap {
    background: rgba(255, 255, 255, 0.3);
    box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.12), 0 0 25px rgba(255, 255, 255, 0.55);
}
.promise-card:hover .promise-icon-bolt { animation: promiseBoltPulse 0.7s ease-in-out infinite; }
.promise-card:hover .promise-icon-medal { animation: promiseMedalShine 1s ease-in-out infinite; }
.promise-card:hover .promise-icon-rotate { animation: promiseIconRotate 1.2s linear infinite; }
.promise-card:hover .promise-icon-trophy { animation: promiseIconBounce 0.8s ease-in-out infinite; }
@keyframes promiseBoltPulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.3); }
}
@keyframes promiseMedalShine {
    0%, 100% { filter: brightness(1) drop-shadow(0 0 0 rgba(255, 255, 255, 0)); }
    50% { filter: brightness(1.8) drop-shadow(0 0 8px rgba(255, 255, 255, 0.85)); }
}
@keyframes promiseIconRotate {
    to { transform: rotate(360deg); }
}
@keyframes promiseIconBounce {
    0%, 100% { transform: translateY(0); }
    30% { transform: translateY(-7px); }
    50% { transform: translateY(0); }
    70% { transform: translateY(-3px); }
    85% { transform: translateY(0); }
}
.promise-stat {
    font-size: 1.875rem;
    font-weight: 800;
    line-height: 1;
}
.promise-rocket {
    display: inline-block;
    animation: promiseRocketPulse 2s ease-in-out infinite;
}
@keyframes promiseRocketPulse {
    0%, 100% { transform: scale(1) translateX(0); }
    50% { transform: scale(1.15) translateX(3px); }
}
.promise-cta.reveal {
    transition-delay: 0.6s;
}
@media (prefers-reduced-motion: reduce) {
    .promise-block { animation: none; }
    .promise-shape { animation: none; }
}

/* "Ensemble, une force complémentaire" block */
.force-block {
    position: relative;
    overflow: hidden;
    border-radius: 1.5rem;
    border: 1px solid transparent;
    background-image: linear-gradient(135deg, #eff6ff 0%, #ffffff 50%, #eff6ff 100%), linear-gradient(135deg, var(--primary), var(--primary-dark));
    background-origin: border-box;
    background-clip: padding-box, border-box;
    box-shadow: 0 20px 45px -25px rgba(30, 95, 168, 0.25);
}
.force-shapes {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}
.force-shape {
    position: absolute;
    border-radius: 9999px;
    filter: blur(45px);
    background: rgba(59, 189, 235, 0.07);
}
.force-shape-1 { width: 220px; height: 220px; top: -60px; left: -60px; }
.force-shape-2 { width: 260px; height: 260px; bottom: -80px; right: -60px; background: rgba(30, 95, 168, 0.06); }
.force-content {
    position: relative;
    z-index: 1;
}
.force-subtitle.reveal {
    transition-delay: 0.2s;
}

/* Pillars */
.force-grid.stagger-grid > * {
    transform: translateY(30px);
}
.force-grid.stagger-grid > *.active {
    transform: translateY(0);
}
.force-card {
    position: relative;
    background: #ffffff;
    border-radius: 1rem;
    padding: 1.75rem 1.25rem;
    text-align: center;
    box-shadow: 0 8px 20px -12px rgba(30, 95, 168, 0.18);
    transition: transform 0.4s var(--ease-premium), box-shadow 0.4s var(--ease-premium), opacity 0.3s var(--ease-premium);
}
.force-card:hover {
    transform: translateY(-6px);
    box-shadow: 0 20px 35px -15px rgba(30, 95, 168, 0.3);
}
.force-grid:hover .force-card {
    opacity: 0.6;
}
.force-grid:hover .force-card:hover {
    opacity: 1;
}
@media (min-width: 768px) {
    .force-grid > *:not(:first-child) {
        position: relative;
    }
    .force-grid > *:not(:first-child)::before {
        content: '';
        position: absolute;
        left: -0.75rem;
        top: 15%;
        bottom: 15%;
        width: 1px;
        background: rgba(30, 95, 168, 0.12);
    }
}
.force-icon-wrap {
    width: 64px;
    height: 64px;
    border-radius: 9999px;
    background: var(--primary-gradient);
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 0.9rem auto;
    transform: scale(0);
    transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 0.15s, box-shadow 0.4s var(--ease-premium);
}
.force-grid.stagger-grid > *.active .force-icon-wrap {
    transform: scale(1);
}
.force-icon-wrap i {
    color: #ffffff;
    font-size: 1.35rem;
}
.force-card:hover .force-icon-wrap {
    animation: forceIconPulse 0.7s var(--ease-premium);
    box-shadow: 0 0 30px rgba(59, 189, 235, 0.45);
}
@keyframes forceIconPulse {
    0%, 100% { transform: scale(1) rotate(0deg); }
    30% { transform: scale(1.15) rotate(-6deg); }
    60% { transform: scale(1.1) rotate(6deg); }
}
.force-title-underline {
    display: block;
    width: 0;
    height: 2px;
    margin: 0.5rem auto 0 auto;
    background: var(--primary-gradient);
    border-radius: 9999px;
    transition: width 0.35s var(--ease-premium);
}
.force-card:hover .force-title-underline {
    width: 36px;
}

/* Contact form */
.contact-form-card {
    position: relative;
    background: #ffffff;
    border-radius: 1.25rem;
    padding: 2rem;
    box-shadow: 0 25px 50px -20px rgba(0, 0, 0, 0.4);
}
@media (min-width: 640px) {
    .contact-form-card { padding: 2.5rem; }
}
.form-grid.stagger-grid > * {
    transform: translateY(20px);
}
.form-grid.stagger-grid > *.active {
    transform: translateY(0);
}
.form-field {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    margin-bottom: 1.1rem;
}
.form-field label {
    font-size: 0.85rem;
    font-weight: 600;
    color: #374151;
    transition: color 0.3s var(--ease-premium), transform 0.3s var(--ease-premium);
}
.form-field.field-focused label {
    color: var(--primary-dark);
    transform: translateY(-2px);
}
.form-field.field-invalid input,
.form-field.field-invalid select,
.form-field.field-invalid textarea {
    border-color: #ef4444;
    box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.15);
}
.form-checkbox-row.field-invalid label {
    color: #dc2626;
}
.required-mark {
    color: #ef4444;
    margin-left: 2px;
}
.input-icon-wrap {
    position: relative;
    /* Single source of truth for the gutter: the icon sits at --icon-inset and
       occupies --icon-size, the text starts one --icon-gap further. Moving the
       icon moves the text with it, so the two can never overlap again. */
    --icon-inset: 0.9rem;
    --icon-size: 0.95rem;
    --icon-gap: 0.65rem;
    --icon-gutter: calc(var(--icon-inset) + var(--icon-size) + var(--icon-gap));
}
.input-icon-wrap i {
    position: absolute;
    left: var(--icon-inset);
    top: 50%;
    /* Fixed box + centred glyph: fa-user, fa-envelope and fa-phone have
       different intrinsic widths and would otherwise not line up. */
    width: var(--icon-size);
    text-align: center;
    transform: translateY(-50%);
    color: #9ca3af;
    font-size: 0.85rem;
    pointer-events: none;
    transition: color 0.3s var(--ease-premium);
}
.form-field.field-focused .input-icon-wrap i {
    color: var(--primary);
}
.form-field input[type="text"],
.form-field input[type="email"],
.form-field input[type="tel"],
.form-field select,
.form-field textarea {
    width: 100%;
    border: 1px solid #d1d5db;
    border-radius: 0.5rem;
    padding: 0.65rem 0.9rem;
    font-size: 0.95rem;
    font-family: inherit;
    color: #111827;
    background: #ffffff;
    transition: border-color 0.3s var(--ease-premium), box-shadow 0.3s var(--ease-premium);
}
.form-field textarea {
    resize: vertical;
    min-height: 7.5rem;
}
.form-field .input-icon-wrap input[type="text"],
.form-field .input-icon-wrap input[type="email"],
.form-field .input-icon-wrap input[type="tel"] {
    padding-left: var(--icon-gutter);
}
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 4px rgba(59, 189, 235, 0.15);
}
.form-checkbox-row {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    margin-bottom: 1.5rem;
}
.form-checkbox-row input[type="checkbox"] {
    margin-top: 0.2rem;
    width: 16px;
    height: 16px;
    accent-color: var(--primary-dark);
    flex-shrink: 0;
    cursor: pointer;
}
.form-checkbox-row label {
    font-size: 0.78rem;
    color: #4b5563;
    line-height: 1.5;
    cursor: pointer;
}
.form-checkbox-row a {
    color: var(--primary-dark);
    text-decoration: underline;
}
.btn-form-submit {
    width: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    background: var(--primary-gradient);
    color: #ffffff;
    font-weight: 600;
    font-size: 1rem;
    padding: 0.85rem 1.5rem;
    border-radius: 0.75rem;
    border: none;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    isolation: isolate;
    box-shadow: 0 10px 25px -10px rgba(30, 95, 168, 0.5);
    transition: transform 0.35s var(--ease-premium), box-shadow 0.35s var(--ease-premium), opacity 0.3s ease;
}
.btn-form-submit:hover:not(:disabled) {
    transform: translateY(-3px);
    box-shadow: 0 15px 30px -10px rgba(30, 95, 168, 0.6);
}
.btn-form-submit:disabled {
    opacity: 0.7;
    cursor: not-allowed;
}
.btn-form-submit::after {
    content: '';
    position: absolute;
    top: 0;
    left: -75%;
    width: 50%;
    height: 100%;
    background: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.55), transparent);
    transform: skewX(-20deg);
    animation: shineMove 3.5s ease-in-out infinite;
}
/* An author-level display beats the UA stylesheet's [hidden] rule, so the three
   status boxes stayed visible despite their hidden attribute. This restores it. */
.form-alert[hidden] { display: none; }
.form-alert {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.9rem 1.1rem;
    border-radius: 0.75rem;
    font-size: 0.88rem;
    margin-top: 1.25rem;
    animation: formAlertIn 0.4s var(--ease-premium);
}
.form-alert i {
    font-size: 1.15rem;
    flex-shrink: 0;
}
.form-alert-success {
    background: #ecfdf5;
    color: #065f46;
    border: 1px solid #a7f3d0;
}
.form-alert-error {
    background: #fef2f2;
    color: #991b1b;
    border: 1px solid #fecaca;
}
@keyframes formAlertIn {
    from { opacity: 0; transform: translateY(-8px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Actualités: card metadata, article body typography.
   Every colour comes from the existing tokens or from shades already used
   elsewhere in the sheet - nothing new is introduced here. */
.news-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}
.news-category {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.7rem;
    border-radius: 9999px;
    background: rgba(59, 189, 235, 0.12);
    color: var(--primary-dark);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}
.news-date {
    color: #6b7280;
    font-size: 0.8rem;
}
.news-empty {
    max-width: 36rem;
    margin: 3rem auto;
    padding: 2.5rem;
    border-radius: 1rem;
    background: #f8fafc;
    border: 1px dashed rgba(30, 95, 168, 0.25);
    color: #6b7280;
    text-align: center;
    font-size: 1.05rem;
}
/* ── mention de langue sur un article ─────────────────────────────────────
   Le corps des articles n'est pas traduit : seuls le titre, le chapô et
   l'appel à l'action le sont. Un lecteur en anglais clique donc une carte
   entièrement anglaise et tombe sur un texte français. Cette ligne le
   prévient avant qu'il entame la lecture.

   Solution d'attente, voir HANDOFF.md : traduire ou non le corps des
   articles est une décision cliente, non arbitrée à ce jour.

   Pilotée par l'attribut lang de <html>, que switchLanguage() tient à jour,
   et non par data-fr/data-en. La boucle de traduction de js/lang.js teste
   `if (text)` : un data-fr vide y est ignoré, et la phrase anglaise
   resterait affichée en français. Rien à modifier dans le JS par cette voie,
   et rien qui dépende d'une règle :empty — laquelle, posée globalement,
   masquerait les 590 icônes FontAwesome du site, toutes des balises vides. */
.news-lang-note {
    display: none;
    font-size: 0.85rem;
    color: #6b7280;
    margin-top: -0.5rem;
    margin-bottom: 2rem;
}
:root[lang="en"] .news-lang-note {
    display: block;
}

.news-lead {
    font-size: 1.2rem;
    line-height: 1.65;
    color: #374151;
    font-weight: 500;
    padding-bottom: 1.75rem;
    margin-bottom: 2rem;
    border-bottom: 1px solid rgba(30, 95, 168, 0.12);
}

/* Body copy: the elements a writer actually needs, styled once so that plain
   HTML in pages-src/actualites/ renders consistently with the rest of the site. */
.news-body {
    color: #374151;
    font-size: 1.0625rem;
    line-height: 1.75;
}
.news-body > * + * { margin-top: 1.25rem; }
.news-body h2 {
    margin-top: 2.75rem;
    font-size: 1.6rem;
    font-weight: 700;
    color: #111827;
}
.news-body h3 {
    margin-top: 2rem;
    font-size: 1.25rem;
    font-weight: 700;
    color: #111827;
}
.news-body h2 + *, .news-body h3 + * { margin-top: 0.75rem; }
.news-body strong { font-weight: 700; color: #111827; }
.news-body a {
    color: var(--primary-dark);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
    transition: opacity 0.25s var(--ease-premium);
}
.news-body a:hover { opacity: 0.75; }
.news-body ul, .news-body ol { padding-left: 1.5rem; }
.news-body ul { list-style: disc; }
.news-body ol { list-style: decimal; }
.news-body li { margin-top: 0.5rem; }
.news-body li::marker { color: var(--primary-dark); }
.news-body blockquote {
    /* Same treatment as .quote-style used elsewhere on the site */
    font-style: italic;
    padding: 1rem 2rem;
    background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
    border-left: 4px solid var(--primary);
    border-radius: 0 0.5rem 0.5rem 0;
}
.news-body blockquote > * + * { margin-top: 0.75rem; }

/* Tables scroll inside their own container rather than widening the page. */
.news-body .table-wrap { overflow-x: auto; }
.news-body table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95rem;
}
.news-body th, .news-body td {
    padding: 0.7rem 0.9rem;
    border: 1px solid rgba(30, 95, 168, 0.15);
    text-align: left;
    vertical-align: top;
}
.news-body th {
    background: rgba(59, 189, 235, 0.08);
    color: var(--primary-dark);
    font-weight: 700;
}
@media (max-width: 640px) {
    .news-body blockquote { padding: 1rem 1.25rem; }
    .news-lead { font-size: 1.08rem; }
}

/* ════════════════════════════════════════════════════════════════════════
   ALIGNEMENT HOMOGÈNE DES TEXTES
   Trois mécanismes, aucun contenu touché, aucune valeur calée sur la
   longueur d'un texte (donc rien à recaler en FR/EN ni à la retouche) :
     1. les cartes d'une même rangée partagent les pistes de leur grille,
        via subgrid, donc leurs bandes internes démarrent au même niveau ;
     2. le corps de texte de l'accueil lit à la largeur des sous-pages ;
     3. les listes ont un retrait unique et un texte enroulé qui s'aligne.
   ════════════════════════════════════════════════════════════════════════ */

:root {
    /* Largeur de lecture commune. 48rem = la max-w-3xl des sous-pages. */
    /* Visuels : aucune variable de rayon ni d'ombre n'existait jusqu'ici,
       ces valeurs passaient par les utilitaires Tailwind ou en dur. */
    --radius-media: 1rem;
    --shadow-media: 0 10px 24px -14px color-mix(in srgb, var(--primary-dark) 45%, transparent);
    --media-ratio: 16 / 10;

    --reading-width: 48rem;
    /* Retrait unique des listes, toutes familles confondues. */
    --list-indent: 1.5rem;
}

/* ── 1. Bandes internes des cartes en grille ─────────────────────────────
   Chaque carte reprend les pistes de sa grille parente : icône, titre,
   paragraphe et pied se calent au même niveau d'une carte à l'autre, quel
   que soit le nombre de lignes du titre, la langue ou la largeur d'écran.
   Les pistes sont implicites : le nombre de rangées suit les colonnes du
   point de rupture, sans rien à déclarer par media query.
   Hors subgrid, ces règles ne s'appliquent pas et le rendu actuel (flex)
   reste en place. */
@supports (grid-template-rows: subgrid) {
    .service-card,
    .team-card,
    .founders-card {
        display: grid;
        grid-template-rows: subgrid;
        /* Le row-gap de la grille parente sépare les rangées de cartes,
           pas les bandes internes : l'espacement interne reste celui des
           marges déjà portées par chaque bloc. */
        row-gap: 0;
    }

    /* Icône, titre, paragraphe, pied. */
    .service-card { grid-row: span 4; }
    /* Une piste de plus que les autres cartes : le visuel de tête. */
    .team-card { grid-row: span 5; }

    /* « Pourquoi choisir ABYLYS » : pas de pied de carte. */
    #pourquoi-abylys .service-card { grid-row: span 3; }

    /* Identité, accroche, parcours, intitulé, liste, intitulé, citation. */
    .founders-card { grid-row: span 7; }

    /* Les pistes partagées calent déjà le pied de carte : la poussée en
       bas ferait au contraire flotter l'intitulé « Sa conviction ». */
    .founders-card > .mt-auto { margin-top: 0; }
}

/* ── 2. Largeur de colonne de lecture ────────────────────────────────────
   Le corps de texte de l'accueil lisait sur 1152 px (~100 caractères par
   ligne). Les grilles de cartes gardent leur pleine largeur : seuls les
   paragraphes et la liste qui les suit sont contraints.

   Une largeur max ne recentre rien par elle-même : le bloc rétréci reste
   collé au bord gauche de son conteneur, donc hors de l'axe du titre. Il
   faut donc, selon le cas, contraindre un conteneur déjà centré ou rendre
   les marges horizontales automatiques. */

/* #histoire ne contient que du texte : on contraint le conteneur lui-même,
   déjà centré par mx-auto. Paragraphes et bloc de citation partagent ainsi
   la même colonne et le même axe que le titre. */
#histoire .max-w-4xl {
    max-width: var(--reading-width);
}

/* Ailleurs le conteneur porte aussi les grilles de cartes, qui gardent leur
   pleine largeur : on contraint les seuls blocs de texte, en les recentrant. */
#fondateurs .max-w-6xl > p,
#equipes .max-w-6xl > p,
#equipes .max-w-6xl > ul {
    max-width: var(--reading-width);
    margin-inline: auto;
}

/* Paragraphe de corps centré ramené à gauche, comme partout ailleurs.
   Les sur-titres, titres et sous-titres de section gardent leur pattern. */
#fondateurs .max-w-6xl > p.text-center {
    text-align: left;
}

/* ── 3. Listes ───────────────────────────────────────────────────────────
   Les listes à coche étaient en list-item sans retrait : le texte enroulé
   repassait sous l'icône. L'icône occupe désormais une colonne fixe, donc
   la deuxième ligne s'aligne sous la première. */
ul:has(> li > i.fa-check) > li {
    display: flex;
    align-items: flex-start;
}
ul:has(> li > i.fa-check) > li > i.fa-check {
    flex: 0 0 var(--list-indent);
    margin-right: 0;
    line-height: inherit;
}

/* Mêmes retrait et comportement pour les liens du footer. */
.footer-link {
    align-items: flex-start;
    gap: 0;
}
.footer-link i {
    flex: 0 0 var(--list-indent);
    line-height: inherit;
}

/* Listes des articles : même retrait que les deux familles ci-dessus. */
.news-body ul,
.news-body ol {
    padding-left: var(--list-indent);
}

/* Le logo du header ramène à l'accueil. Le parent est déjà un conteneur
   flex, donc l'ancre y est blockifiée ; inline-flex garde malgré tout la
   boîte du lien collée à celle de l'image si ce parent changeait un jour,
   ce qui évite l'espace de descente d'un <a> inline sous l'image. */
.nav-logo-link {
    display: inline-flex;
    cursor: pointer;
}

/* ════════════════════════════════════════════════════════════════════════
   VISUELS DE LA PAGE NOS ÉQUIPES
   Les conteneurs portent le ratio et l'aplat d'attente. Déposer le SVG et
   décommenter le <img> ne déplace donc rien : la boîte a déjà sa hauteur.
   ════════════════════════════════════════════════════════════════════════ */

/* Aplat d'attente, aux bleus de la marque. color-mix évite la couleur en
   dur là où la palette n'expose que --primary et --primary-dark. */
.media-placeholder {
    background-color: color-mix(in srgb, var(--primary) 8%, white);
    background-image: repeating-linear-gradient(
        135deg,
        color-mix(in srgb, var(--primary) 14%, transparent) 0 10px,
        transparent 10px 22px
    );
}

/* Visuel de tête des cartes du triptyque. Les marges négatives annulent le
   p-8 de la carte pour un rendu bord à bord ; la carte porte déjà
   overflow:hidden et son rayon, le rognage est donc net. */
.team-card-media {
    margin: -2rem -2rem 1.5rem;
    aspect-ratio: var(--media-ratio);
    overflow: hidden;
}
.team-card-media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Visuel du bloc « La force de la diversité », centré au-dessus des deux
   colonnes de texte. */
.diversity-media {
    max-width: 30rem;
    margin: 0 auto 2rem;
    aspect-ratio: var(--media-ratio);
    border-radius: var(--radius-media);
    box-shadow: var(--shadow-media);
    overflow: hidden;
}
.diversity-media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ════════════════════════════════════════════════════════════════════════
   FICHES FONDATEURS — ENRICHISSEMENT VISUEL
   Traitement d'attente, en place tant que les portraits ne sont pas
   fournis. Le conteneur de portrait porte déjà sa taille finale et son
   dégradé : déposer la photo et décommenter le <picture> la fait
   recouvrir l'aplat, sans rien déplacer ni redimensionner.
   Aucune couleur en dur : tout dérive de --primary et --primary-dark.
   ════════════════════════════════════════════════════════════════════════ */

/* Aplat organique d'angle, même langage que .force-shape du bloc « La
   force du trio » : un cercle flou, jamais lisible comme une forme.
   Posé en ::after pour n'ajouter aucun enfant de grille — les cartes
   restent à sept pistes de subgrid. */
.founders-card::after {
    content: '';
    position: absolute;
    width: 200px;
    height: 200px;
    right: -70px;
    bottom: -70px;
    border-radius: 9999px;
    filter: blur(45px);
    background: color-mix(in srgb, var(--primary) 14%, transparent);
    pointer-events: none;
    z-index: 0;
}

/* Le contenu repasse au-dessus de l'aplat. */
.founders-card > * {
    position: relative;
    z-index: 1;
}

/* Bandeau d'identité : pastille à gauche, nom et rôle à droite. Empilée,
   la pastille poussait le contenu utile très bas — elle occupait à elle
   seule 144 px des 236 px du bloc. Ce conteneur reste UN enfant de la
   carte : le subgrid garde ses sept pistes, rien à recompter.

   align-items: flex-start et non center — les intitulés de fonction font
   trois à quatre lignes en colonne étroite, et une pastille centrée sur
   un bloc aussi haut se retrouve en regard du rôle plutôt que du nom.
   Calée en haut, elle reste l'amorce de lecture de la fiche quelle que
   soit la longueur de l'intitulé. Le décalage de 2 px rattrape le
   jambage supérieur du nom, dont la boîte de ligne dépasse la capitale. */
.founder-identity {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
}
.founder-identity > .founder-portrait {
    margin-top: 2px;
}

/* Conteneur de portrait. Porte le dégradé de marque tant qu'il est vide,
   et sert de cadre de rognage dès qu'une image y entre.

   Deux tailles, une seule variable. Tout le reste — anneau, ombre,
   rognage, taille de l'icône — en dérive, donc le passage de l'une à
   l'autre ne demande aucun autre réglage. */
.founder-portrait {
    /* Taille compacte, pour l'icône d'attente. */
    --portrait-size: 4.5rem;

    width: var(--portrait-size);
    height: var(--portrait-size);
    /* En contexte flex, empêche la pastille de se comprimer quand le nom
       ou le rôle est long. */
    flex: 0 0 var(--portrait-size);
    border-radius: 9999px;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--primary-gradient);
    box-shadow: 0 10px 24px -14px color-mix(in srgb, var(--primary-dark) 55%, transparent);
    /* Anneau clair : détache le portrait du fond teinté de la carte. */
    outline: 4px solid white;
    outline-offset: -1px;
}

/* Taille généreuse, à poser le jour où une vraie photo remplace l'icône.
   Un visage a besoin de plus de place qu'un pictogramme pour rester
   reconnaissable : 96 px contre 72. Voir le commentaire posé au-dessus
   de chaque <picture> dans pages-src/a-propos/les-fondateurs.html. */
.founder-portrait--photo {
    --portrait-size: 6rem;
}

/* L'icône d'attente. Proportionnelle au conteneur, donc juste dans les
   deux tailles sans réglage séparé. Disparaît d'elle-même sous l'image
   le jour où le <picture> est décommenté, celle-ci couvrant tout. */
.founder-portrait i {
    font-size: calc(var(--portrait-size) * 0.42);
    color: white;
}

/* Le portrait, une fois fourni : couvre le conteneur, rognage centré. */
.founder-portrait img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Sous 380 px, la pastille rend un demi-rem au bloc nom + rôle, qui
   devient sinon trop étroit pour un intitulé de fonction complet.
   Au-dessus, la disposition horizontale tient sans réglage. */
@media (max-width: 380px) {
    .founder-portrait { --portrait-size: 4rem; }
    .founder-portrait--photo { --portrait-size: 5rem; }
    .founder-identity { gap: 0.75rem; }
}

/* ════════════════════════════════════════════════════════════════════════
   FOND DE PAGE — HALOS ORGANIQUES + FILET DE MARQUE
   Posé sur le <main> des pages intérieures : Notre histoire et les trois
   pages d'expertise. C'est la signature de ce type de page.

   Même effet perçu que .force-shape du bloc « La force du trio » : une
   lumière bleutée diffuse, jamais lisible comme une forme.

   Deux différences de mise en œuvre, toutes deux dictées par le bord :

   1. Des radial-gradient plutôt que des cercles floutés. Un cercle en
      filter: blur() doit être rogné par overflow: hidden, et ce rognage
      laisse une arête au bord du conteneur — invisible sur une carte, où
      l'arête coïncide avec le bord de la carte, mais pas ici, où le bord
      du conteneur est la jonction avec la section suivante. Un dégradé
      radial tombe à zéro par construction : aucune arête possible.

   2. Un masque éteint le champ sur les 200 derniers pixels du <main>,
      quelle que soit la hauteur de la page. Le halo bas ne peut donc pas
      atteindre la jonction, même si le contenu raccourcit.

   Les centres sont hors-cadre et bas : le fil d'Ariane en text-gray-500,
   qui n'a que 4,83:1 sur blanc pur, reste en dehors du cœur des halos.

   Aucune couleur en dur : tout dérive de --primary et --primary-dark.
   ════════════════════════════════════════════════════════════════════════ */

.page-aura {
    position: relative;
    /* Crée le contexte d'empilement qui contient le calque à z-index
       négatif. Sans lui, le halo passerait derrière le fond blanc du
       <main> et deviendrait invisible. */
    isolation: isolate;

    /* Géométrie. Sortie en variables pour qu'une section plus courte
       puisse la reprendre sans redéclarer les dégradés. Les valeurs par
       défaut sont calibrées pour un <main> de page, 780 px au minimum. */
    --aura-a-y: 420px;
    --aura-a-r: 560px;
    --aura-b-y: 560px;
    --aura-b-r: 520px;
    --aura-fade: 200px;

    /* Intensités des deux halos, sorties dans des variables pour que la
       version étroite n'ait à redéfinir que ces quatre valeurs. */
    --aura-a-core: color-mix(in srgb, var(--primary) 15%, transparent);
    --aura-a-mid: color-mix(in srgb, var(--primary) 6%, transparent);
    --aura-b-core: color-mix(in srgb, var(--primary-dark) 12%, transparent);
    --aura-b-mid: color-mix(in srgb, var(--primary-dark) 4.8%, transparent);
}

/* Sous 640 px, la colonne de texte occupe toute la largeur : elle passe
   donc sur le cœur des halos, et non plus seulement sur leur frange.
   Les intensités descendent d'un cran pour garder le fil d'Ariane
   au-dessus du seuil AA. */
@media (max-width: 640px) {
    .page-aura {
        --aura-a-core: color-mix(in srgb, var(--primary) 11%, transparent);
        --aura-a-mid: color-mix(in srgb, var(--primary) 4.4%, transparent);
        --aura-b-core: color-mix(in srgb, var(--primary-dark) 9%, transparent);
        --aura-b-mid: color-mix(in srgb, var(--primary-dark) 3.6%, transparent);
    }
}

/* Le calque de lumière. En z-index négatif : peint après le fond du
   <main>, avant tout le contenu. Aucun enfant n'a besoin d'être
   repositionné. */
.page-aura::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-repeat: no-repeat;
    background-image:
        /* Halo gauche, centre hors-cadre et sous le fil d'Ariane. */
        radial-gradient(circle var(--aura-a-r) at -80px var(--aura-a-y),
            var(--aura-a-core) 0%, var(--aura-a-mid) 45%, transparent 100%),
        /* Halo droit, centre hors-cadre et plus bas. Il porte la majeure
           partie de la présence du champ : c'est le seul des deux qui
           puisse être poussé, le fil d'Ariane étant loin de lui. */
        radial-gradient(circle var(--aura-b-r) at calc(100% + 80px) var(--aura-b-y),
            var(--aura-b-core) 0%, var(--aura-b-mid) 45%, transparent 100%);
    /* Garde-fou de jonction : quelle que soit la hauteur de la page, la
       lumière est éteinte 200 px avant le bas du <main>. */
    -webkit-mask-image: linear-gradient(to bottom, black calc(100% - var(--aura-fade)), transparent 100%);
    mask-image: linear-gradient(to bottom, black calc(100% - var(--aura-fade)), transparent 100%);
}

/* Variante pour une section prise dans une page, et non pour un <main>.
   La section « Notre histoire » de l'accueil fait environ 600 px : la
   géométrie longue y tasse tout en haut à gauche, et le fondu de 200 px
   mange un tiers de la hauteur en effaçant le halo droit. Les centres
   remontent, les rayons se resserrent, le fondu passe à 120 px.
   À combiner avec .page-aura, qui porte le calque. */
.page-aura-band {
    --aura-a-y: 200px;
    --aura-a-r: 420px;
    --aura-b-y: 330px;
    --aura-b-r: 400px;
    --aura-fade: 120px;
}

/* ── TEXTURE D'AMBIANCE — PROVISOIRE ──────────────────────────────────────
   Visuel d'attente sur Notre histoire, à remplacer après la séance photo.
   Voir HANDOFF.md.

   Trois décisions techniques, toutes dictées par le coût ou le contraste :

   1. Le flou est cuit dans le fichier, pas appliqué en CSS. Un filter:
      blur() sur une surface de cette taille est recalculé à chaque
      repaint ; ici le navigateur ne fait que peindre une image.

   2. L'image est servie en 400 px de large pour 3,3 Ko. Le flou ayant
      détruit toutes les hautes fréquences, une définition supérieure ne
      porterait aucune information : le réagrandissement est invisible.

   3. Le voile blanc tient lieu d'opacité ET fait les deux fondus. Son
      profil vertical dégage le haut de page, où le fil d'Ariane en
      text-gray-500 est le texte le plus juste du site, et retombe au
      blanc pur avant la jonction, pour la même raison que le masque des
      halos : aucune bande possible quelle que soit la hauteur de page. */
.page-texture {
    /* Part de la texture dans le mélange. Le reste est du blanc.
       0.92 avait été calibré par prudence : la texture était imperceptible.
       Mesuré : le fil d'Ariane reste à 4,83 quel que soit ce niveau, la
       bande dégagée du haut le mettant hors d'atteinte. Ce qui limite
       vraiment, c'est le corps de texte, encore à 6,60 ici. */
    --texture-veil: 0.80;
    /* Hauteur dégagée en haut. Le fil d'Ariane occupe y = 129 à 146 :
       200 px le dégagent avec 54 px de marge. C'est le vrai levier de
       présence — la texture couvre le titre et tout le corps, là où les
       textes sont foncés et le budget de contraste large. */
    --texture-top: 200px;
    --texture-in: 360px;
    /* Même garde-fou de jonction que --aura-fade. */
    --texture-fade: 200px;
}

/* Repli pour les navigateurs sans image-set : le JPEG, directement. */
.page-texture {
    background-image:
        linear-gradient(to bottom,
            #ffffff 0,
            #ffffff var(--texture-top),
            rgba(255, 255, 255, var(--texture-veil)) var(--texture-in),
            rgba(255, 255, 255, var(--texture-veil)) calc(100% - var(--texture-fade)),
            #ffffff 100%),
        url("../images/histoire-ambiance.jpg");
    background-size: cover, cover;
    background-position: center, center;
    background-repeat: no-repeat, no-repeat;
}
.page-texture {
    background-image:
        linear-gradient(to bottom,
            #ffffff 0,
            #ffffff var(--texture-top),
            rgba(255, 255, 255, var(--texture-veil)) var(--texture-in),
            rgba(255, 255, 255, var(--texture-veil)) calc(100% - var(--texture-fade)),
            #ffffff 100%),
        image-set(url("../images/histoire-ambiance.webp") type("image/webp"),
                  url("../images/histoire-ambiance.jpg") type("image/jpeg"));
}

/* Variante pour une page dont le bloc d'en-tête est plus haut. Les fiches
   fondateurs empilent fil d'Ariane, sur-titre, titre, deux sous-titres et
   un paragraphe d'introduction avant les cartes : la bande de 200 px
   calibrée pour Notre histoire y laisserait la texture monter jusque sous
   le sur-titre.

   300 px dégagent le fil d'Ariane (y = 129), le sur-titre (192) et le
   titre (223), et le fondu s'ouvre juste sur les deux sous-titres en
   text-gray-600 — la couleur la plus juste de la page après le fil
   d'Ariane. Mesuré à 7,17 et 6,80, très au-dessus de AA.

   AUCUNE PAGE NE PORTE CETTE CLASSE AUJOURD'HUI. Les fiches fondateurs,
   seule page pour laquelle elle avait été calibrée, sont passées aux halos
   comme les douze autres pages du site : sur une page dont les trois cartes
   sont opaques, la texture n'était plus visible que dans les deux marges et
   les deux gouttières — mesurée entre rgb(222,220,218) et rgb(235,233,230),
   soit 8 à 13 % plus sombre que le blanc. Elle ne se lisait plus comme une
   ambiance mais comme un cadre gris autour des cartes.

   La règle est conservée, pas supprimée : le calibrage est juste et vaut
   pour toute page dont le bloc d'en-tête empile plus de 200 px avant le
   premier contenu. Elle se réactive en posant `page-texture
   page-texture-deep` sur le <main> concerné. */
.page-texture-deep {
    --texture-top: 300px;
    --texture-in: 460px;
}

/* Là où la texture est posée, c'est elle qui porte l'ambiance : mesurée,
   elle pèse 2,5 fois les halos (écart moyen au blanc 4,00 contre 1,63,
   couverture 40,9 % contre 19,4 %). Les laisser à pleine intensité
   ferait se disputer deux traitements sur le même fond, pour un budget
   de contraste consommé deux fois.

   Ils ne disparaissent pas : ils restent la teinte de marque aux deux
   bords, que la texture — neutre et chaude — n'apporte pas.

   Réduction volontairement portée par .page-texture.page-aura et non par
   .page-aura : les trois pages d'expertise n'ont pas de texture, rien n'y
   remplacerait ce qu'on leur retirerait. */
.page-texture.page-aura {
    --aura-a-core: color-mix(in srgb, var(--primary) 9%, transparent);
    --aura-a-mid: color-mix(in srgb, var(--primary) 3.5%, transparent);
    --aura-b-core: color-mix(in srgb, var(--primary-dark) 7%, transparent);
    --aura-b-mid: color-mix(in srgb, var(--primary-dark) 2.8%, transparent);
}

/* Le filet, classe séparée. Il se pose sur la jonction avec la section
   suivante : le haut du <main> passe sous l'en-tête fixe, un filet y
   serait invisible au repos et hors écran une fois la page défilée.
   Même dégradé et même épaisseur que .heading-underline.

   Séparé des halos parce qu'il ne se justifie pas partout. Il marque la
   fin du contenu principal devant une section claire. Devant le bandeau
   de contact, qui porte déjà le dégradé de marque en grand, il ferait
   doublon : là, on met .page-aura sans .page-filet. De même en milieu de
   page d'accueil, où il se lirait comme une coupure. */
.page-filet {
    position: relative;
}
.page-filet::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3px;
    background: var(--primary-gradient);
    pointer-events: none;
}

/* ════════════════════════════════════════════════════════════════════════
   PLAN DU SITE
   Une liste, pas des cartes : la page sert à trouver une adresse vite, et
   une grille de pastilles ferait passer un sommaire pour une rubrique.
   Le filet vertical reprend le dégradé de marque, comme .mobile-accordion-panel.
   ════════════════════════════════════════════════════════════════════════ */
.sitemap-list { list-style: none; padding: 0; margin: 0; }
.sitemap-branch + .sitemap-branch { margin-top: 1.5rem; }
.sitemap-sublist {
    list-style: none;
    margin: 0.5rem 0 0 0.25rem;
    padding: 0 0 0 1rem;
    border-left: 2px solid rgba(30, 95, 168, 0.12);
}
.sitemap-sublist li + li { margin-top: 0.15rem; }
.sitemap-link {
    display: inline-block;
    padding: 0.35rem 0;
    color: #374151;
    transition: color 0.25s var(--ease-premium);
}
.sitemap-link:hover { color: var(--primary-dark); }
.sitemap-link-top { font-weight: 600; color: #111827; font-size: 1.125rem; }

/* ════════════════════════════════════════════════════════════════════════
   PAGES LÉGALES
   Squelettes en attente du texte. Les emplacements vides sont volontairement
   visibles et distincts d'un vrai paragraphe : personne ne doit pouvoir les
   confondre avec du contenu rédigé, ni en ligne ni sur une relecture papier.
   ════════════════════════════════════════════════════════════════════════ */
.legal-notice {
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
    margin-bottom: 2.5rem;
    padding: 1rem 1.25rem;
    border-left: 3px solid var(--primary-dark);
    border-radius: 0 0.5rem 0.5rem 0;
    background: rgba(59, 189, 235, 0.08);
    color: #1f2937;
    font-size: 0.95rem;
    line-height: 1.6;
}
.legal-notice-icon { margin-top: 0.2rem; color: var(--primary-dark); flex-shrink: 0; }

.legal-block { margin-bottom: 2rem; }
.legal-heading {
    font-size: 1.25rem;
    font-weight: 700;
    color: #111827;
    margin-bottom: 0.625rem;
}
/* Tiretés, en gris, en italique : trois signaux qui disent « ce n'est pas
   un texte ». Le contraste reste au-dessus de AA pour que la relecture
   client se fasse sans effort. */
.legal-placeholder {
    padding: 0.875rem 1rem;
    border: 1px dashed rgba(30, 95, 168, 0.35);
    border-radius: 0.5rem;
    background: rgba(30, 95, 168, 0.03);
    color: #4b5563;
    font-style: italic;
    font-size: 0.95rem;
}
.legal-updated {
    margin-top: 2.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid rgba(30, 95, 168, 0.12);
    color: #6b7280;
    font-size: 0.875rem;
}
