  /* ─── View Transitions (cross-document) ─────────────────────────────────────
     Opt the whole site into the View Transitions API for cross-document
     navigation. Browsers without support (Firefox, Safari < 18) navigate
     normally; the JS fallback in main.js handles those with a cream fade. */
  @view-transition {
    navigation: auto;
  }

  /* Root cross-fade. The surrounding home content (everything except the
     shared image) fades out to cream while the destination page fades in.
     500ms with a smooth, decelerating ease so it reads as one continuous
     gesture rather than a hard cut. */
  ::view-transition-old(root),
  ::view-transition-new(root){
    animation-duration: 500ms;
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  }
  ::view-transition-old(root){ animation-name: okapi-fade-out-cream; }
  ::view-transition-new(root){ animation-name: okapi-fade-in-cream; }
  @keyframes okapi-fade-out-cream { to { opacity: 0; } }
  @keyframes okapi-fade-in-cream  { from { opacity: 0; } }

  /* The 5 entity card images each carry a view-transition-name on the home
     page; the matching destination hero image carries the same name. The
     browser handles the position / scale / border-radius interpolation
     automatically. We just stretch the timing to 600ms so the morph reads
     longer than the surrounding fade and feels like the lead element. */
  ::view-transition-old(entity-image-kp),
  ::view-transition-new(entity-image-kp),
  ::view-transition-old(entity-image-kamino),
  ::view-transition-new(entity-image-kamino),
  ::view-transition-old(entity-image-geneva-oil),
  ::view-transition-new(entity-image-geneva-oil),
  ::view-transition-old(entity-image-hummingbird),
  ::view-transition-new(entity-image-hummingbird),
  ::view-transition-old(entity-image-manta),
  ::view-transition-new(entity-image-manta){
    animation-duration: 600ms;
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  }

  /* ─── Tokens ─────────────────────────────────────────────────────────────── */
  :root{
    /* === OKAPI BRAND PALETTE (from official charte graphique) === */

    /* Couleurs principales */
    --color-brand: #5C2E20;          /* Primary maroon */
    --color-dark: #282828;           /* Near-black for dark sections */

    /* Couleurs corporate (neutrals from charte) */
    --color-brown-secondary: #7D5148;
    --color-gray-medium: #6D6B6C;
    --color-gray-light: #9B9C9D;

    /* Couleurs d'accentuation (charte accents) */
    --color-accent-orange: #F29100;  /* Primary accent : CTA, emphasis */
    --color-accent-yellow: #FCC930;  /* Reserved, not used yet */
    --color-accent-green: #91D400;   /* Reserved, not used yet */
    --color-accent-cyan: #0BC5DE;    /* Reserved, not used yet */

    /* Background */
    --color-cream: #F5F2EC;          /* Canvas : pending client confirmation */

    /* Brand at varying opacities (charte logic: one color, many opacities) */
    --color-brand-90: color-mix(in srgb, var(--color-brand) 90%, transparent);
    --color-brand-80: color-mix(in srgb, var(--color-brand) 80%, transparent);
    --color-brand-60: color-mix(in srgb, var(--color-brand) 60%, transparent);
    --color-brand-40: color-mix(in srgb, var(--color-brand) 40%, transparent);
    --color-brand-20: color-mix(in srgb, var(--color-brand) 20%, transparent);
    --color-brand-10: color-mix(in srgb, var(--color-brand) 10%, transparent);

    /* === Legacy tokens (now resolve to charte palette) ============== */

    /* Dark surfaces consolidated to --color-brand (brown).
       The previous --color-dark (#282828 near-black) is no longer used
       as a surface token, only as raw text/border ink where appropriate.
       Do not introduce a separate dark surface token without explicit
       design review. */
    --canvas-d:      var(--color-brand);
    --canvas-d-2:    var(--color-brand);
    --canvas-d-3:    var(--color-brand);
    --ink-d:         #f5f0ea;
    --ink-d-2:       #c8b8a8;
    --hairline-d:    rgba(245, 240, 234, 0.14);
    --hairline-d-strong: rgba(245, 240, 234, 0.22);

    /* Light surfaces (platform, ecosystem, expertise, influence, direction) */
    --canvas:        #ffffff;
    --canvas-warm:   #f5f0ea;
    --canvas-rust:   #f6ede8;
    --canvas-mint:   #e8f2f1;

    /* Body text family : editorial near-black at varying opacities (cream surfaces) */
    --ink:           var(--color-dark);
    --ink-2:         rgb(from var(--color-dark) r g b / 0.8);
    --ink-3:         rgb(from var(--color-dark) r g b / 0.6);
    --muted:         rgb(from var(--color-dark) r g b / 0.4);

    --hairline:      rgba(61, 18, 8, 0.14);
    --hairline-soft: rgba(61, 18, 8, 0.08);
    --hairline-rust: rgba(61, 18, 8, 0.16);
    --hairline-mint: rgba(10, 74, 94, 0.16);

    /* Partners surface : charte dark (was navy-tinted teal).
       Now consolidated with --color-brand per the dark-surface
       unification above. */
    --canvas-teal:   var(--color-brand);
    --ink-teal:      #f5f0ea;
    --ink-teal-muted: rgba(245, 240, 234, 0.70);
    --hairline-teal: rgba(245, 240, 234, 0.16);

    /* Accents : charte orange replaces amber */
    --amber:         var(--color-accent-orange);
    --amber-deep:    #C77600;
    --rust:          #3d1208;
    --rust-2:        #5a1d0e;
    --rust-3:        #7a2e10;

    --radius-sm:  8px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-xl: 18px;

    /* Shared mobile gutter applied to every page hero envelope at <=767px.
       Canonical value lifted from the entity sub-page hero (entites/kp.html
       et al). One source of truth so the home, entites landing, and every
       sub-page wrap their hero with identical breathing room on mobile. */
    --hero-gutter-mobile: 8px;

    --ease-out-expo:   cubic-bezier(0.16, 1, 0.3, 1);
    --ease-viscous:    cubic-bezier(0.22, 1, 0.36, 1);
    --ease-hairline:   cubic-bezier(0.77, 0, 0.175, 1);

    --maxw: 1440px;
    --margin: clamp(24px, 5vw, 80px);
    --section-pad-y: clamp(72px, 8vw, 112px);

    /* === FONT FAMILIES === */
    --font-sans: "Mulish", sans-serif;
    --font-mono: "Montserrat", sans-serif;

    /* Semantic aliases : selectors should reference these going forward.
       All three sans aliases currently resolve to Mulish; the split lets
       future font swaps target hero/heading/body independently. */
    --font-display: var(--font-sans);
    --font-heading: var(--font-sans);
    --font-body:    var(--font-sans);
    --font-label:   var(--font-mono);

    /* === FONT SIZE SCALE (multiples of 4) === */
    --text-xs:   12px;
    --text-sm:   14px;
    --text-md:   16px;
    --text-lg:   20px;
    --text-xl:   28px;
    --text-2xl:  40px;
    --text-3xl:  56px;
    --text-4xl:  80px;
    --text-5xl:  112px;

    /* === FONT WEIGHTS === */
    --weight-light:    400;
    --weight-regular:  400;
    --weight-medium:   500;
    --weight-semibold: 600;

    /* === LETTER-SPACING (tracking) === */
    --track-tight-xs: -0.005em;
    --track-tight-sm: -0.01em;
    --track-tight-md: -0.02em;
    --track-tight-lg: -0.025em;
    --track-normal:    0;
    --track-wide-sm:   0.04em;
    --track-mono:       0.18em;
    --track-mono-wide:  0.22em;
    --track-mono-xwide: 0.24em;

    /* === LINE-HEIGHT (leading) === */
    --leading-display: 1.05;
    --leading-heading: 1.15;
    --leading-tight:   1.2;
    --leading-snug:    1.3;
    --leading-normal:  1.5;
    --leading-relaxed: 1.65;
    --leading-loose:   1.75;
  }

  *,*::before,*::after{ box-sizing: border-box; }
  html,body{ margin:0; padding:0; background: var(--canvas-d); color: var(--ink-d); font-family: var(--font-body); font-weight: var(--weight-light); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
  body{ overflow-x: hidden; }

  a{ color: inherit; text-decoration: none; }
  button{ font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
  svg{ display: block; }

  /* ─── BUTTON SYSTEM (locked) ─────────────────────────────────────────────
     Three variants only: primary, secondary, tertiary. Every button on the
     site uses one of these. No one-off buttons. See CLAUDE.md +
     MOBILE_GUIDELINES.md for the discipline rules.

     Variants:
       .btn--primary          Amber fill, 56h, PARLONS (drawer), ENVOYER
       .btn--secondary        Outline, 48h, hero CTA, closing PARLONS
       .btn--tertiary         48×48 icon-only (drawer close, etc.)
       .btn--hero-flood       Modifier on .btn--secondary to layer the
                              signature viscous amber wash behind the button.
                              Used ONLY on the home hero DÉCOUVRIR CTA.
       .btn--tertiary-visual  Decorative amber arrow square used inside
                              a parent clickable (entity cards). Not a
                              standalone interactive element.
     Radii honour the universal system (10px buttons, 8px arrow squares). */

  .btn{
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-body);
    font-weight: var(--weight-medium);
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    border: 0;
    background: transparent;
    color: inherit;
    user-select: none;
    transition:
      background 420ms var(--ease-out-expo),
      border-color 420ms var(--ease-out-expo),
      color 420ms var(--ease-out-expo),
      transform 280ms var(--ease-out-expo),
      opacity 240ms ease-out,
      box-shadow 420ms var(--ease-out-expo);
  }
  .btn:focus-visible{ outline: 2px solid var(--amber); outline-offset: 3px; }
  .btn__text{ position: relative; z-index: 1; display: inline-block; }
  .btn__arrow-square{
    position: relative;
    z-index: 1;
    display: inline-grid;
    place-items: center;
    flex-shrink: 0;
    border-radius: var(--radius-sm);
    transition: transform 420ms var(--ease-out-expo), background 420ms var(--ease-out-expo);
  }

  /* PRIMARY : amber fill, dark arrow-square, 56h. Hover layers an
     amber-deep left-to-right wipe over the base amber, border fades
     transparent (2px transparent at rest for structural parity with
     the 1px outlined secondary in the same family), arrow square
     rotates +45° matching the outbound-signal pattern. Text + arrow
     square ride above the wipe on their own z-layer. */
  .btn--primary{
    position: relative;
    overflow: hidden;
    height: 56px;
    padding: 0 8px 0 28px;
    gap: 20px;
    background: var(--amber);
    color: var(--canvas-d);
    border: 2px solid transparent;
    border-radius: var(--radius-md);
    font-size: clamp(var(--text-xs), 1.1vw, var(--text-sm));
    letter-spacing: 0.12em;
    transition: border-color 910ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .btn--primary::before{
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: var(--amber-deep);
    transform: translateX(-101%);
    transition: transform 910ms cubic-bezier(0.22, 1, 0.36, 1);
    z-index: 1;
    pointer-events: none;
  }
  .btn--primary .btn__text,
  .btn--primary .btn__arrow-square{
    position: relative;
    z-index: 2;
  }
  .btn--primary .btn__arrow-square{
    width: 40px; height: 40px;
    background: var(--canvas-d);
    color: var(--amber);
    transition:
      background 910ms 260ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 910ms 260ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .btn--primary .btn__arrow-square svg{ width: 20px; height: 20px; }
  @media (hover: hover){
    .btn--primary:hover{
      border-color: transparent;
    }
    .btn--primary:hover::before{
      transform: translateX(0);
    }
    /* Unified arrow-square hover for the filled + outlined button family.
       .btn--hero-flood also carries .btn--secondary, so it inherits this
       treatment without a dedicated override. */
    .btn--primary:hover .btn__arrow-square,
    .btn--secondary:hover .btn__arrow-square{
      background: var(--canvas-d);
      transform: rotate(45deg);
    }
    /* Arrow icon stays amber on hover so the glyph reads clearly against
       the canvas-d rotated square. SVGs use stroke="currentColor" on the
       parent <svg>. Setting stroke directly on the path overrides that
       inheritance without affecting rest-state icon colors. */
    .btn--primary:hover .btn__arrow-square svg path,
    .btn--secondary:hover .btn__arrow-square svg path{
      stroke: var(--amber);
    }
  }
  /* Touch / no-hover : match the same amber-on-dark readability during
     :active so the press state mirrors desktop hover. */
  @media (hover: none){
    .btn--primary:active .btn__arrow-square svg path,
    .btn--secondary:active .btn__arrow-square svg path{
      stroke: var(--amber);
    }
  }
  .btn--primary:active::before{
    transform: translateX(0);
    transition-duration: 200ms;
  }
  .btn--primary:active{ transform: scale(0.98); opacity: 0.9; }

  /* SECONDARY : outline on dark (default) or on light, 56h. Chassis now
     matches .btn--primary (height / padding / gap / radius / arrow-square
     40×40 with 10px radius) so a filled primary and an outlined secondary
     read as the same component family, differing only in fill treatment. */
  .btn--secondary{
    height: 56px;
    padding: 0 8px 0 28px;
    gap: 20px;
    background: transparent;
    border: 1px solid rgba(245, 240, 234, 0.4);
    color: var(--ink-d);
    border-radius: var(--radius-md);
    font-size: clamp(var(--text-xs), 1vw, var(--text-sm));
    letter-spacing: 0.14em;
  }
  .btn--secondary .btn__arrow-square{
    width: 40px; height: 40px;
    background: var(--amber);
    color: var(--canvas-d);
    transition:
      background 910ms 260ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 910ms 260ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .btn--secondary .btn__arrow-square svg{ width: 20px; height: 20px; }
  .btn--secondary.btn--on-dark{ border-color: rgba(245, 240, 234, 0.4); color: var(--ink-d); }
  .btn--secondary.btn--on-light{ border-color: rgba(61, 18, 8, 0.4); color: var(--color-dark); }
  @media (hover: hover){
    .btn--secondary.btn--on-dark:hover{
      background: rgba(245, 240, 234, 0.06);
      border-color: rgba(245, 240, 234, 0.7);
    }
    .btn--secondary.btn--on-light:hover{
      background: rgba(61, 18, 8, 0.06);
      border-color: rgba(61, 18, 8, 0.7);
    }
    /* Arrow-square :hover treatment is defined in the unified primary +
       secondary rule above. No per-variant override here. */
  }
  .btn--secondary:active{ transform: scale(0.98); opacity: 0.85; }

  /* HERO-FLOOD MODIFIER : left-to-right amber wipe on the home hero
     DÉCOUVRIR CTA. Scoped to .cta.btn--hero-flood so it never collides
     with other secondary buttons. Text + arrow-square ride above the
     wipe on their own stacking layer. Staggered 200ms delays let the
     fill lead and the text/arrow color change catch up. */
  .cta.btn--hero-flood{
    /* .cta already carries position: absolute from its layout rule,
       which serves as the containing block for ::before. Don't override
       here or the button detaches from the hero's bottom-right anchor. */
    overflow: hidden;
    transition: border-color 910ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .cta.btn--hero-flood::before{
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: var(--amber);
    transform: translateX(-101%);
    transition: transform 910ms cubic-bezier(0.22, 1, 0.36, 1);
    z-index: 1;
    pointer-events: none;
  }
  .cta.btn--hero-flood .btn__text,
  .cta.btn--hero-flood .btn__arrow-square{
    position: relative;
    z-index: 2;
  }
  .cta.btn--hero-flood .btn__text{
    transition: color 910ms 260ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  /* Arrow-square transition + hover bg/rotation both come from the unified
     .btn--secondary .btn__arrow-square rule (hero also carries that class).
     Hero used to darken to amber-deep and skip rotation; that exception has
     been removed to unify the family. */
  @media (hover: hover){
    .cta.btn--hero-flood:hover{
      border-color: transparent;
    }
    .cta.btn--hero-flood:hover::before{
      transform: translateX(0);
    }
    .cta.btn--hero-flood:hover .btn__text{
      color: var(--canvas-d);
    }
  }
  /* Touch / no-hover : fill fires on :active with snappier 200ms timing
     and no staggered delays. */
  .cta.btn--hero-flood:active::before{
    transform: translateX(0);
    transition-duration: 200ms;
  }
  .cta.btn--hero-flood:active .btn__text{
    color: var(--canvas-d);
    transition-duration: 200ms;
  }
  .cta.btn--hero-flood:active{
    transform: scale(0.98);
  }
  .cta.btn--hero-flood:focus-visible{
    outline: 2px solid var(--amber);
    outline-offset: 3px;
  }
  @media (prefers-reduced-motion: reduce){
    .cta.btn--hero-flood::before,
    .cta.btn--hero-flood .btn__text,
    .cta.btn--hero-flood .btn__arrow-square{
      transition-duration: 0.01ms !important;
    }
  }

  /* TERTIARY : 48×48 icon-only, transparent + border. */
  .btn--tertiary{
    width: 48px; height: 48px;
    padding: 0;
    gap: 0;
    background: transparent;
    border: 1px solid rgba(245, 240, 234, 0.3);
    border-radius: var(--radius-md);
    color: var(--ink-d);
  }
  .btn--tertiary svg{
    width: 20px; height: 20px;
    transition: transform 420ms var(--ease-out-expo);
  }
  .btn--tertiary.btn--on-dark{ border-color: rgba(245, 240, 234, 0.3); color: var(--ink-d); }
  .btn--tertiary.btn--on-light{ border-color: rgba(61, 18, 8, 0.3); color: var(--color-dark); }
  @media (hover: hover){
    .btn--tertiary.btn--on-dark:hover{
      background: rgba(245, 240, 234, 0.08);
      border-color: rgba(245, 240, 234, 0.6);
    }
    .btn--tertiary.btn--on-light:hover{
      background: rgba(61, 18, 8, 0.08);
      border-color: rgba(61, 18, 8, 0.6);
    }
    .btn--tertiary:hover svg{ transform: rotate(45deg); }
  }
  .btn--tertiary:active{ transform: scale(0.9); opacity: 0.8; }

  /* TERTIARY-VISUAL : decorative amber arrow square inside a parent
     clickable element (e.g. entity cards). Not a button itself. Parent
     handles the hover/active interactions. */
  .btn--tertiary-visual{
    display: inline-grid;
    place-items: center;
    width: 48px; height: 48px;
    border-radius: var(--radius-md);
    background: var(--amber);
    color: var(--canvas-d);
    transition: transform 600ms var(--ease-viscous), background 420ms var(--ease-out-expo);
    will-change: transform;
  }
  .btn--tertiary-visual svg{ width: 18px; height: 18px; }

  /* MOBILE : primary spans full width ; secondary/tertiary natural width. */
  @media (max-width: 767px){
    .btn--primary{ width: 100%; }
  }

  /* ─── Hero section ───────────────────────────────────────────────────────── */
  /* Cinematic video bed. The cream background is the fallback that shows
     while the MP4 buffers ; once the <video> paints, it covers the bed
     edge to edge. The hero is 100vh, full-bleed, no rounded corners,
     overflow hidden so the watermark-clipping transform on the inner
     video never leaks. */
  .hero{
    position: relative;
    width: 100%;
    height: 100vh;
    height: 100dvh;
    min-height: 100vh;
    min-height: 100dvh;
    /* overflow:hidden so the watermark-clipping transform on the inner
       video never leaks past the hero box, and so the rounded bottom
       corners on .hero__video-clip clip cleanly against the section
       boundary. The cream background is the fallback that shows while
       the MP4 buffers ; once the <video> paints, it covers edge to edge. */
    overflow: hidden;
    background: #F5F2EC;
  }

  /* Video clip wrapper. Full-bleed video bed with rounded BOTTOM corners
     only (top corners flush). overflow:hidden + transform on the inner
     <video> crops the Veo watermark out of the bottom-right corner. The
     inset box-shadow paints a strong dark gradient at the bottom that
     fades upward, plus a softer ambient corner darkening for legibility.
     overflow:hidden + the rounded radius live on the SAME element so the
     inset shadow is clipped to the rounded shape and never leaks beyond
     the hero. No filter:drop-shadow is applied to this element or any
     ancestor in the hero. */
  .hero__video-clip{
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
    border-radius: 0 0 48px 48px;
    /* No box-shadow. Headline legibility is handled exclusively by
       .hero__scrim (separate element). The hero meets the cream
       section below cleanly via the rounded bottom corners alone. */
  }
  .hero__video{
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* scale + translate hides the Veo watermark anchored bottom-right.
       1.15 scale crops ~7.5% off each axis. The positive translate
       shifts the video down and to the right inside the clip, which
       pushes the bottom-right corner (and its watermark) off-screen
       while keeping the upper-left within frame. */
    transform: scale(1.15) translate(2%, 3%);
    transform-origin: 50% 50%;
    opacity: 0;        /* faded in by GSAP entrance timeline */
    pointer-events: none;
    user-select: none;
  }

  /* Legibility scrim over the video : faint top fade only (behind nav).
     Sits between the video (z 0) and the foreground (z 5+).
     The hero meets the cream section below cleanly, no bottom darkening. */
  .hero__scrim{
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    opacity: 0;        /* faded in by GSAP entrance timeline */
    background: linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.35) 0%,
      rgba(0, 0, 0, 0) 60%
    );
  }

  /* Legacy particle canvas (no longer rendered, retained for non-video heroes) */
  #flux-canvas{
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    z-index: 1;
    opacity: 0;              /* fades in via JS */
    mix-blend-mode: lighter;
    pointer-events: none;
  }

  /* Grid hairlines (12 cols desktop, 8 tablet, 4 mobile) */
  .grid-veils{
    position: absolute; inset: 0;
    z-index: 2;
    pointer-events: none;
    display: grid;
    padding: 0 var(--margin);
    grid-template-columns: repeat(12, 1fr);
    column-gap: 32px;
  }
  .grid-veils span{
    position: relative;
    height: 100%;
    opacity: 0; /* animated */
  }
  .grid-veils span::before{
    content: "";
    position: absolute; inset: 0 auto 0 -16px;
    width: 1px; height: 100%;
    background: linear-gradient(180deg, rgba(245,240,234,0) 0%, rgba(245,240,234,0.022) 22%, rgba(245,240,234,0.04) 50%, rgba(245,240,234,0.022) 78%, rgba(245,240,234,0) 100%);
    transform-origin: top center;
    transform: scaleY(0);
  }
  @media (max-width: 1023px){ .grid-veils{ grid-template-columns: repeat(8, 1fr); column-gap: 24px; } }
  @media (max-width: 767px){  .grid-veils{ grid-template-columns: repeat(4, 1fr); column-gap: 24px; } }

  /* Portal: inline SVG (uses actual filigree paths from icone filigramme.svg) */
  .portal{
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%) scale(0.88);
    width: min(62vw, 880px);
    aspect-ratio: 975 / 955;
    z-index: 2;
    opacity: 0;
    pointer-events: none;
    filter: drop-shadow(0 0 60px rgba(200, 146, 42, 0.06));
  }
  .portal svg{ width: 100%; height: 100%; overflow: visible; }
  .portal path{
    fill: var(--amber);
    fill-opacity: 0.065;   /* the 6-7% brand opacity */
  }
  .portal .ring{
    fill: none;
    stroke: var(--amber);
    stroke-width: 0.6;
    stroke-opacity: 0.32;
    vector-effect: non-scaling-stroke;
  }

  /* ─── Nav ────────────────────────────────────────────────────────────────── */
  /* Sticky across all pages. Three zones float independently above the
     hero (no continuous bar background): logo at left, links pill at
     center, FR|EN + Parlons CTA at right. The pill carries its own
     cream-glass chrome (subtle bg, hairline border, backdrop blur) and
     gains a soft rust shadow once the user scrolls past 100px. The CTA
     button has its own amber chrome.

     Visibility:
       Default (main pages) : visible on first paint (opacity 1, no
                              translate).
       body.page-entity-detail : hidden on first paint; revealed by JS
                              (.nav--visible) only on scroll-up.
       .nav-hidden          : direction-based hide on scroll-down past
                              ~100px; restored on scroll-up. Orthogonal
                              to the visibility gate above.
       .nav-shadowed        : toggled at scrollY > 100. Adds the soft
                              shadow under the pill and shifts the FR|EN
                              + pill link colours from cream to rust to
                              compensate for the cream surface scrolling
                              behind. Active states (link underline,
                              FR is-active) stay amber.

     Negative margin-bottom pulls the next section up under the sticky
     nav so the body's canvas-d background never shows as a horizontal
     strip above the hero (which starts at canvas-d-2, slightly lighter).
     Bumped to -90px to clear the 40px logo and the pill's vertical
     padding without leaking the body bg through. */
  .nav{
    position: sticky; top: 0; left: 0; right: 0;
    z-index: 100;
    padding: 24px var(--margin) 16px;
    margin-bottom: -90px;
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 40px;
    background: transparent;
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
    transition: transform 400ms cubic-bezier(0.16, 1, 0.3, 1),
                opacity 400ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  /* Entity detail pages : nav hidden on first paint. Revealed only when
     the user scrolls back up (JS adds .nav--visible). */
  body.page-entity-detail .nav{
    opacity: 0;
    transform: translateY(-100%);
    pointer-events: none;
  }
  body.page-entity-detail .nav.nav--visible{
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }
  /* Direction-based hide. !important defeats the .nav--visible transform
     so the nav slides back off-screen on scroll-down even after reveal. */
  .nav.nav-hidden{
    transform: translateY(-100%) !important;
    pointer-events: none;
  }
  /* Brand : bare logo SVG, no wordmark, no chrome. */
  .nav__brand{
    display: inline-flex; align-items: center;
    justify-self: start;
  }
  .nav__logo{
    height: 40px; width: auto;
    display: block;
    /* Logo is a raster (PNG embedded in SVG), so colour-swap relies on
       a filter pair. Default = cream over dark surfaces. .nav--on-light
       reverts to the natural brand colour over cream surfaces. */
    filter: brightness(0) invert(1);
    transition: filter 200ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .nav.nav--on-light .nav__logo{
    filter: none;
  }
  /* Center pill : cream-glass chrome, hairline border, backdrop blur,
     14px rounded rectangle (NOT a full pill). Soft shadow appears past
     100px via .nav-shadowed. Default tones suit a dark surface ; the
     .nav--on-light variant retones for cream surfaces. */
  .nav__pill{
    justify-self: center;
    display: inline-flex;
    align-items: center;
    background: rgba(245, 240, 234, 0.06);
    border: 1px solid rgba(245, 240, 234, 0.12);
    border-radius: 14px;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    padding: 12px 24px;
    transition: box-shadow 200ms cubic-bezier(0.16, 1, 0.3, 1),
                background 200ms cubic-bezier(0.16, 1, 0.3, 1),
                border-color 200ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .nav.nav--on-light .nav__pill{
    background: rgba(58, 30, 18, 0.04);
    border-color: rgba(58, 30, 18, 0.10);
  }
  .nav.nav-shadowed .nav__pill{
    box-shadow: 0 8px 24px rgba(61, 18, 8, 0.12);
  }
  .nav__links{
    display: flex; gap: 32px;
    list-style: none; margin: 0; padding: 0;
  }
  .nav__links a{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono-wide);
    text-transform: uppercase;
    color: var(--ink-d);
    text-decoration: none;
    position: relative;
    padding: 8px 0;
    transition: color 200ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .nav__links a::after{
    content: "";
    position: absolute; left: 0; bottom: 0;
    height: 1px; width: 0;
    background: var(--amber);
    transition: width 910ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .nav.nav--on-light .nav__pill .nav__links a{
    color: var(--color-dark);
  }
  .nav__links a:hover,
  .nav.nav--on-light .nav__pill .nav__links a:hover{
    color: var(--amber);
  }
  .nav__links a:hover::after{ width: 100%; }
  /* Right zone : FR|EN sits next to the Parlons CTA, free-floating. */
  .nav__actions{
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: 20px;
  }
  .nav__lang{
    display: flex; align-items: center; gap: 8px;
    font-family: var(--font-label);
    font-size: var(--text-xs); letter-spacing: var(--track-mono-wide);
  }
  .nav__lang button{
    color: var(--ink-d);
    padding: 8px 2px;
    background: transparent;
    border: 0;
    cursor: pointer;
    font: inherit;
    letter-spacing: inherit;
    transition: color 200ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .nav.nav--on-light .nav__lang button:not(.is-active){
    color: var(--color-dark);
  }
  .nav__lang button:hover,
  .nav.nav--on-light .nav__lang button:hover{ color: var(--amber); }
  .nav__lang button.is-active{ color: var(--amber); }
  .nav__lang .sep{ color: rgba(245,240,234,0.25); }
  .nav.nav--on-light .nav__lang .sep{ color: rgb(from var(--color-dark) r g b / 0.35); }
  /* Hamburger : desktop hides it, mobile reveals it (replaces .nav__pill
     and .nav__actions). 24x24 hit area, 3 horizontal lines, color matches
     the logo treatment (white over dark hero, brand rust once scrolled). */
  .nav__hamburger{
    display: none;
    width: 24px; height: 24px;
    padding: 0;
    background: transparent;
    border: 0;
    cursor: pointer;
    flex-direction: column;
    justify-content: space-between;
    align-items: stretch;
    color: #F5F0EA;
    transition: color 200ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .nav.nav--on-light .nav__hamburger{ color: var(--color-dark); }
  .nav__hamburger-line{
    display: block;
    width: 100%;
    height: 2px;
    background: currentColor;
    border-radius: 1px;
  }
  .nav__hamburger:focus-visible{ outline: 2px solid var(--amber); outline-offset: 4px; }

  /* Mobile : hide center pill + right actions, show hamburger flush right. */
  @media (max-width: 767px){
    .nav{
      grid-template-columns: 1fr auto;
      gap: 16px;
      padding: 20px var(--margin) 16px;
      margin-bottom: -76px;
    }
    .nav__pill{ display: none; }
    .nav__actions{ display: none; }
    .nav__hamburger{ display: flex; }
    .nav__logo{ height: 32px; }
  }

  /* ─── Mobile navigation drawer ─────────────────────────────────────────
     Full-viewport sheet that slides in from the right when .nav__hamburger
     is tapped. Hidden on desktop ; only mounted into the layout on widths
     below 768px. Closes on X tap, link tap, ESC, or backdrop tap. */
  .mobile-drawer{
    position: fixed;
    inset: 0;
    z-index: 200;
    pointer-events: none;
    visibility: hidden;
    transition: visibility 0s linear 320ms;
  }
  .mobile-drawer.is-open{
    pointer-events: auto;
    visibility: visible;
    transition: visibility 0s linear 0s;
  }
  .mobile-drawer__backdrop{
    position: absolute;
    inset: 0;
    background: rgba(245, 242, 236, 0);
    transition: background 300ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .mobile-drawer.is-open .mobile-drawer__backdrop{
    background: rgba(245, 242, 236, 1);
  }
  .mobile-drawer__panel{
    position: absolute;
    top: 0;
    right: -100%;
    bottom: 0;
    width: 100%;
    max-width: 100vw;
    background: #F5F2EC;
    transition: right 300ms cubic-bezier(0.16, 1, 0.3, 1);
    display: flex;
    flex-direction: column;
    padding: 24px 0 32px;
    overflow-y: auto;
  }
  .mobile-drawer.is-open .mobile-drawer__panel{
    right: 0;
  }
  .mobile-drawer__close{
    align-self: flex-end;
    width: 24px; height: 24px;
    margin: 0 24px 24px 0;
    padding: 0;
    background: transparent;
    border: 0;
    cursor: pointer;
    color: var(--color-dark);
    flex-shrink: 0;
  }
  .mobile-drawer__close svg{ width: 100%; height: 100%; display: block; }
  .mobile-drawer__close:focus-visible{ outline: 2px solid var(--amber); outline-offset: 4px; }
  .mobile-drawer__links{
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 1;
  }
  .mobile-drawer__links li + li{
    border-top: 1px solid rgba(58, 30, 18, 0.1);
  }
  .mobile-drawer__links a{
    display: block;
    font-family: var(--font-body);
    font-weight: var(--weight-regular);
    font-size: var(--text-xl);
    letter-spacing: 0.02em;
    color: var(--color-dark);
    text-align: left;
    padding: 20px 32px;
    min-height: 44px;
    text-decoration: none;
  }
  .mobile-drawer__links a:focus-visible{
    outline: 2px solid var(--amber);
    outline-offset: -2px;
  }
  .mobile-drawer__lang{
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 24px 32px 0;
    padding-top: 24px;
    border-top: 1px solid rgba(58, 30, 18, 0.1);
    font-family: var(--font-label);
    font-size: var(--text-sm);
    letter-spacing: var(--track-mono-wide);
  }
  .mobile-drawer__lang button{
    color: var(--color-dark);
    padding: 8px 8px;
    min-height: 44px;
    background: transparent;
    border: 0;
    cursor: pointer;
    font: inherit;
    letter-spacing: inherit;
  }
  .mobile-drawer__lang button.is-active{ color: var(--amber); }
  .mobile-drawer__lang button:focus-visible{ outline: 2px solid var(--amber); outline-offset: 4px; }
  .mobile-drawer__lang .sep{ color: rgb(from var(--color-dark) r g b / 0.35); }

  /* Hide drawer entirely on desktop : never paints, never traps focus. */
  @media (min-width: 768px){
    .mobile-drawer{ display: none; }
  }
  /* Lock body scroll while drawer is open (paired with lenis.stop() in JS) */
  body.mobile-menu-open{ overflow: hidden; }

  /* Section label: top-left, below nav, generous breathing room */
  .label{
    position: absolute;
    left: var(--margin);
    top: clamp(104px, 12vh, 148px);
    z-index: 5;
    display: flex; align-items: center; gap: 16px;
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono-xwide);
    text-transform: uppercase;
    color: var(--ink-d-2);
    opacity: 0;
  }
  .label__sep{ color: rgba(245,240,234,0.25); padding: 0 2px; }
  .label__bullet{
    width: 8px; height: 8px;
    background: var(--amber);
    flex-shrink: 0;
  }
  .label__num{ color: var(--ink-d); }
  .label__divider{
    width: 40px; height: 1px;
    background: var(--hairline-d-strong);
    flex-shrink: 0;
  }

  /* Headline + subline: single left column, stacked */
  .stage{
    position: absolute;
    left: var(--margin);
    bottom: clamp(88px, 12vh, 140px);
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    max-width: min(920px, calc(100vw - var(--margin) * 2));
  }

  .headline{
    font-family: var(--font-display);
    font-weight: var(--weight-light);
    font-size: clamp(var(--text-2xl), 7vw, var(--text-5xl));
    line-height: 1.02;
    letter-spacing: var(--track-tight-lg);
    color: var(--ink-d);
    margin: 0;
    max-width: 18ch;
  }
  .headline .line{
    display: block;
    overflow: hidden;
    padding-bottom: 0.04em;
  }
  .headline .line > span{
    display: inline-block;
    transform: translateY(104%);
    will-change: transform;
  }
  .headline em{
    font-family: var(--font-body);
    font-style: italic;
    color: var(--amber);
    font-weight: var(--weight-semibold);
  }

  .subline{
    font-family: var(--font-body);
    font-weight: var(--weight-light);
    font-size: clamp(var(--text-sm), 1.05vw, var(--text-md));
    line-height: var(--leading-relaxed);
    color: rgba(255, 255, 255, 0.92);
    max-width: 52ch;
    margin: 12px 0 0 0;
    padding-top: 0;
    opacity: 0;
    transform: translateY(18px);
  }
  .subline .locus{
    display: block;
    margin-top: 16px;
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono-xwide);
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.92);
  }
  .subline .dot{ color: var(--amber); padding: 0 8px; }

  /* CTA: fluid connected unit. Hover of either half activates the whole. */
  /* Hero CTA : only positions the button ; visuals come from .btn
     .btn--secondary.btn--on-dark.btn--hero-flood in the markup. Intro
     reveal target for GSAP (opacity/translateY pre-state). */
  .cta{
    position: absolute;
    right: var(--margin);
    bottom: clamp(88px, 12vh, 140px);
    z-index: 6;
    opacity: 0;
    transform: translateY(14px);
  }

  @media (max-width: 1023px){
    .cta{
      position: static;
      align-self: flex-start;
      margin-top: 24px;
    }
    .stage{
      bottom: auto;
      position: relative;
      padding-top: 44vh;
      padding-bottom: 32px;
    }
    .hero{ display: flex; flex-direction: column; justify-content: space-between; }
  }

  /* Home hero CTA : hidden on mobile so the hero reads with just the
     headline + subline + locus, matching the simplified mobile rhythm
     used on the rest of the site. The CTA's anchor target (#plateforme)
     is one swipe below, immediately reachable via the standard scroll
     indicator. Scoped to .cta.btn--hero-flood so only the home hero CTA
     is affected ; .btn--secondary buttons elsewhere are unchanged. */
  @media (max-width: 767px){
    .cta.btn--hero-flood{
      display: none;
    }
  }

  /* Home hero mobile envelope. Wraps the cinematic video bed in the same
     gutter as every other page hero (entites/*.html, page-hero, entity-hero
     --index) so the hero edge reads consistently across the site at <=767px.
     The cream .hero background paints the gutter on top, left, and right ;
     the video clip (which already carries the rounded radius via
     overflow:hidden) is the envelope, inset to the same gutter on those
     three sides. Bottom remains flush so the hero rhythm and meeting line
     with the cream section below are unchanged. The width/height auto
     overrides cancel the desktop 100%/100% sizing so the inset values
     determine the box dimensions. */
  @media (max-width: 767px){
    .hero__video-clip,
    .hero__scrim{
      top: var(--hero-gutter-mobile);
      left: var(--hero-gutter-mobile);
      right: var(--hero-gutter-mobile);
      bottom: 0;
      width: auto;
      height: auto;
    }
  }

  /* ─── Scroll indicator (bottom-center) ──────────────────────────────────── */
  .scroll{
    position: absolute;
    left: 50%;
    bottom: 28px;
    transform: translateX(-50%);
    z-index: 6;
    display: flex; flex-direction: column; align-items: center; gap: 16px;
    opacity: 0;
  }
  .scroll__label{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: 0.32em;
    text-transform: uppercase;
    color: var(--ink-d-2);
  }
  .scroll__drip{
    position: relative;
    width: 1px; height: 56px;
    background: var(--hairline-d);
    overflow: hidden;
  }
  .scroll__drip::after{
    content: "";
    position: absolute;
    left: 0; top: -56px;
    width: 1px; height: 28px;
    background: linear-gradient(180deg, rgba(200,146,42,0) 0%, var(--amber) 85%, var(--amber) 100%);
    animation: drip 2.2s cubic-bezier(0.55, 0, 0.45, 1) infinite;
  }
  @keyframes drip{
    0%   { transform: translateY(0);   opacity: 0; }
    10%  { opacity: 1; }
    80%  { opacity: 1; }
    100% { transform: translateY(112px); opacity: 0; }
  }

  /* ════════════════════════════════════════════════════════════════════════
     SECTION 02 : PLATEFORME
     First light section. Rust-tinted canvas. The seam at the top dissolves
     the dark hero into the rust tint across 120px so the boundary reads like
     a turning brochure page, not a harsh cut.
     ════════════════════════════════════════════════════════════════════════ */
  .plateforme{
    position: relative;
    background: var(--canvas-rust);
    color: var(--ink);
    padding: var(--section-pad-y) var(--margin);
    overflow: hidden;
    isolation: isolate;
  }

  /* Watermark portal : rust-tinted filigree, off-center right, 3.5% opacity */
  .plateforme__watermark{
    position: absolute;
    top: 50%;
    right: -10%;
    transform: translateY(-50%);
    width: min(58vw, 760px);
    aspect-ratio: 975 / 955;
    pointer-events: none;
    z-index: 0;
  }
  .plateforme__watermark svg{ width: 100%; height: auto; overflow: visible; }
  .plateforme__watermark path{
    fill: var(--rust);
    fill-opacity: 0.035;
  }
  .plateforme__watermark .ring{
    fill: none;
    stroke: var(--rust);
    stroke-width: 0.5;
    stroke-opacity: 0.10;
    vector-effect: non-scaling-stroke;
  }

  .plateforme__inner{
    position: relative;
    z-index: 2;
    max-width: var(--maxw);
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: clamp(64px, 9vh, 120px);
  }

  /* Label variant on light surface */
  .label--light{ color: var(--ink-3); opacity: 0; }
  .label--light .label__num{ color: var(--color-dark); }
  .label--light .label__sep{ color: rgb(from var(--color-dark) r g b / 0.3); }
  .label--light .label__divider{ background: var(--hairline); }
  /* Bullet stays amber on both surfaces */

  /* Headline on light surface */
  .plateforme__head{
    display: flex;
    flex-direction: column;
    gap: 48px;
  }
  .headline--light{
    font-family: var(--font-display);
    font-weight: var(--weight-light);
    font-size: clamp(var(--text-2xl), 5.5vw, var(--text-4xl));
    line-height: var(--leading-display);
    letter-spacing: var(--track-tight-md);
    color: var(--color-dark);
    margin: 0;
    max-width: 16ch;
  }
  .headline--light .line{
    display: block;
    overflow: hidden;
    padding-bottom: 0.04em;
  }
  .headline--light .line > span{
    display: inline-block;
    transform: translateY(104%);
    will-change: transform;
  }
  .headline--light em{
    font-family: var(--font-body);
    font-style: italic;
    color: var(--amber);
    font-weight: var(--weight-semibold);
  }

  /* Two-column body */
  .plateforme__body{
    display: grid;
    grid-template-columns: 1.2fr 1fr;
    gap: 80px;
    align-items: start;
  }
  @media (max-width: 1023px){
    .plateforme__body{ grid-template-columns: 1fr; gap: 48px; }
  }

  .plateforme__copy{
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 56ch;
    padding-top: 8px;
  }
  .plateforme__copy p{
    font-family: var(--font-body);
    font-weight: var(--weight-light);
    font-size: var(--text-md);
    line-height: var(--leading-loose);
    color: var(--ink);
    margin: 0;
    opacity: 0;
    transform: translateY(24px);
    will-change: transform, opacity;
  }

  .plateforme__media{
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 16px;
    /* Lift the right-column tanker image so its top edge aligns with the
       top of the headline "Une plateforme énergétique". The negative
       margin pulls the media up out of the body row into the empty right
       half of the section-head row above (the headline is constrained to
       16ch on the left). Value matches measured offset between
       .section-head top and .plateforme__body top + .plateforme__copy
       padding-top at 1440px. Reset to 0 below the desktop grid breakpoint
       (handled at 1023px below) where the columns stack. */
    margin-top: -420px;
  }
  @media (max-width: 1023px){
    .plateforme__media{ margin-top: 0; }
  }
  .plateforme__image{
    position: relative;
    aspect-ratio: 4 / 5;
    border-radius: var(--radius-xl);
    overflow: hidden;
    background: var(--ink-3);
    box-shadow: 0 30px 80px -30px rgba(61, 18, 8, 0.28);
    opacity: 0;
    transform: scale(0.97);
    will-change: transform, opacity;
  }
  .plateforme__image img{
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    filter: saturate(0.92) contrast(1.02);
  }
  .plateforme__caption{
    display: flex;
    align-items: center;
    gap: 16px;
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono-xwide);
    text-transform: uppercase;
    color: var(--muted);
    opacity: 0;
  }

  /* Stats strip */
  .plateforme__stats{
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 32px;
    padding-top: 56px;
    border-top: 1px solid var(--hairline);
  }
  @media (max-width: 1023px){
    .plateforme__stats{ grid-template-columns: repeat(2, 1fr); gap: 48px 24px; }
  }
  .stat{
    display: flex;
    flex-direction: column;
    gap: 16px;
  }
  .stat__num{
    font-family: var(--font-display);
    font-weight: var(--weight-light);
    font-size: var(--text-5xl);
    line-height: 1;
    letter-spacing: var(--track-tight-md);
    color: var(--color-dark);
    display: inline-flex;
    align-items: baseline;
  }
  @media (max-width: 1023px){ .stat__num{ font-size: var(--text-5xl); } }
  @media (max-width: 767px){  .stat__num{ font-size: var(--text-4xl); } }
  .stat__num sup{
    color: var(--amber);
    font-size: 0.6em;
    line-height: 1;
    vertical-align: baseline;
    margin-left: 0.04em;
    align-self: flex-start;
    padding-top: 0.08em;
  }
  .stat__label{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted);
  }

  /* ════════════════════════════════════════════════════════════════════════
     SHARED SECTION PRIMITIVES (sections 03-08)
     Generic section box. section-head holds label + counter. Seam variants
     soften every surface boundary to read like a brochure page-turn, never
     a hard cut. Counter system is "0X · 08" (right-aligned, never amber).
     ════════════════════════════════════════════════════════════════════════ */
  .section{
    position: relative;
    overflow: hidden;
    isolation: isolate;
    padding: var(--section-pad-y) var(--margin);
  }
  .section__inner{
    position: relative;
    z-index: 2;
    max-width: var(--maxw);
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: clamp(56px, 8vh, 104px);
  }

  /* Inter-section seam shadows removed. The previous .section::before
     painted a 16px top-edge gradient on every home section (and a stronger
     variant on .section.contact). Removed sitewide so transitions between
     sections read as a continuous cream canvas with no horizontal bands. */
  .section::before{ content: none; }
  .section.contact::before{ content: none; }

  /* Section watermark portals */
  .section__watermark{
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: min(58vw, 760px);
    aspect-ratio: 975 / 955;
    pointer-events: none;
    z-index: 0;
  }
  .section__watermark--right{ right: -10%; }
  .section__watermark--left{ left: -12%; }
  .section__watermark svg{ width: 100%; height: auto; overflow: visible; }
  .section__watermark--mint path{ fill: #0a4a5e; fill-opacity: 0.032; }
  .section__watermark--mint .ring{ fill: none; stroke: #0a4a5e; stroke-width: 0.5; stroke-opacity: 0.10; vector-effect: non-scaling-stroke; }
  .section__watermark--white path{ fill: var(--rust); fill-opacity: 0.026; }
  .section__watermark--white .ring{ fill: none; stroke: var(--rust); stroke-width: 0.5; stroke-opacity: 0.08; vector-effect: non-scaling-stroke; }
  .section__watermark--teal path{ fill: var(--ink-teal); fill-opacity: 0.045; }
  .section__watermark--teal .ring{ fill: none; stroke: var(--ink-teal); stroke-width: 0.5; stroke-opacity: 0.14; vector-effect: non-scaling-stroke; }
  .section__watermark--cream path{ fill: var(--rust); fill-opacity: 0.035; }
  .section__watermark--cream .ring{ fill: none; stroke: var(--rust); stroke-width: 0.5; stroke-opacity: 0.10; vector-effect: non-scaling-stroke; }
  .section__watermark--rust path{ fill: var(--rust); fill-opacity: 0.035; }
  .section__watermark--rust .ring{ fill: none; stroke: var(--rust); stroke-width: 0.5; stroke-opacity: 0.10; vector-effect: non-scaling-stroke; }
  .section__watermark--dark path{ fill: var(--amber); fill-opacity: 0.05; }
  .section__watermark--dark .ring{ fill: none; stroke: var(--amber); stroke-width: 0.5; stroke-opacity: 0.18; vector-effect: non-scaling-stroke; }

  /* Section header : label left, counter right, unified row for 02-08 */
  .section-head{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
  }
  .section-head .label{
    position: static;
    top: auto;
    left: auto;
  }
  .section-counter{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono-xwide);
    text-transform: uppercase;
    font-weight: var(--weight-regular);
    opacity: 0;
    white-space: nowrap;
  }
  .section-counter--light{ color: var(--muted); }
  .section-counter--dark{ color: var(--ink-d-2); }
  .section-counter--teal{ color: var(--ink-teal-muted); }

  /* Label variants for remaining surfaces */
  .label--teal{ color: var(--ink-teal-muted); opacity: 0; position: static; top: auto; left: auto; }
  .label--teal .label__num{ color: var(--ink-teal); }
  .label--teal .label__sep{ color: rgba(245,240,234,0.35); }
  .label--teal .label__divider{ background: var(--hairline-teal); }
  .label--dark-section{ color: var(--ink-d-2); opacity: 0; position: static; top: auto; left: auto; }
  .label--dark-section .label__num{ color: var(--ink-d); }
  .label--dark-section .label__sep{ color: rgba(245,240,234,0.28); }
  .label--dark-section .label__divider{ background: var(--hairline-d-strong); }

  /* ════════════════════════════════════════════════════════════════════════
     UNIFIED SECTION HEADER (home page sections 02, 04-10)
     Structural pattern : .section-head wraps a single-line kicker, the
     headline (.section-head__title), and a 1-2 line lede paragraph. Spacing
     is driven by three variables so every section breathes at the same
     rhythm. Detected via :has(.section-head__kicker) so the legacy flex
     row-layout (still used on a-propos, services, entites, actualites)
     stays untouched.
     ════════════════════════════════════════════════════════════════════════ */
  :root{
    --section-header-gap-1: 8px;    /* kicker → title */
    --section-header-gap-2: 8px;    /* title  → lede */
    --section-header-gap-3: 96px;   /* lede   → content */
  }
  @media (max-width: 767px){
    :root{
      --section-header-gap-1: 8px;
      --section-header-gap-2: 8px;
      --section-header-gap-3: 64px;
    }
  }

  .section-head:has(.section-head__kicker){
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    justify-content: flex-start;
    margin: 0;
  }

  .section-head__kicker{
    display: block;
    font-family: var(--font-label);
    font-weight: var(--weight-regular);
    font-size: var(--text-xs);
    line-height: 1;
    letter-spacing: var(--track-mono);
    text-transform: uppercase;
    color: rgb(from var(--color-dark) r g b / 0.6);
    white-space: nowrap;
    margin: 0 0 var(--section-header-gap-1) 0;
    opacity: 0;
  }
  .section-head__num{
    color: var(--color-accent-orange);
  }
  /* Higher specificity defends margin-bottom against `.headline { margin: 0 }`
     which appears later in this stylesheet (and is shared with non-home pages). */
  .section-head .section-head__title{
    margin: 0 0 var(--section-header-gap-2) 0;
    max-width: 16ch;
  }
  .section-head__lede{
    font-family: var(--font-body);
    font-weight: var(--weight-regular);
    font-size: var(--text-md);
    line-height: var(--leading-normal);
    color: rgb(from var(--color-dark) r g b / 0.8);
    max-width: 560px;
    margin: 0;
    opacity: 0;
  }

  /* Dark-surface variants (Section 07 partenaires, Section 10 contact). */
  .section-head--on-dark .section-head__kicker{
    color: color-mix(in srgb, var(--color-cream) 60%, transparent);
  }
  .section-head--on-dark .section-head__lede{
    color: color-mix(in srgb, var(--color-cream) 80%, transparent);
  }

  /* Replace the inherited section__inner / plateforme__inner gap with the
     spec gap-3 (96px / mobile 64px). Scoped via :has() so this only
     affects sections that adopted the unified header. */
  .section__inner:has(.section-head__kicker),
  .plateforme__inner:has(.section-head__kicker){
    gap: var(--section-header-gap-3);
  }

  /* Plateforme-only override: tighten lede -> first body paragraph to 16px.
     8px inner gap + 8px .plateforme__copy padding-top = 16px total. */
  .plateforme .plateforme__inner:has(.section-head__kicker){
    gap: 8px;
  }

  /* Headline variants */
  .headline{
    font-family: var(--font-display);
    font-weight: var(--weight-light);
    font-size: clamp(var(--text-2xl), 5.5vw, var(--text-4xl));
    line-height: var(--leading-display);
    letter-spacing: var(--track-tight-md);
    margin: 0;
    max-width: 16ch;
  }
  .headline .line{ display: block; overflow: hidden; padding-bottom: 0.04em; }
  .headline .line > span{ display: inline-block; transform: translateY(104%); will-change: transform; }
  .headline em{ font-family: var(--font-body); font-style: italic; color: var(--amber); font-weight: var(--weight-semibold); }
  .headline--rust{ color: var(--color-dark); }
  .headline--teal-text{ color: var(--ink-teal); }
  .headline--dark-text{ color: var(--ink-d); }

  /* Generic fade-up primitive used by body copy blocks in 03-08 */
  .fade-up{ opacity: 0; transform: translateY(24px); will-change: transform, opacity; }

  /* ════════════════════════════════════════════════════════════════════════
     SECTION 03 : L'ÉCOSYSTÈME (mint tint)
     Order : section-head . 2x2 stats block . headline . 5 stacked split
     cards. Each card carries its own themed metadata panel and an editorial
     image that drifts with a shallow scrub-parallax as it passes through.
     ════════════════════════════════════════════════════════════════════════ */
  .ecosysteme{ background: transparent; color: var(--ink); }
  /* Zero the section__inner gap so this section owns its own rhythm.
     Scoped to home only; the entites.html landing reuses .ecosysteme but
     needs the unified Pattern A header rhythm via :has(.section-head__kicker). */
  .ecosysteme:not(.en-landing-cards) > .section__inner{ gap: 0; }

  /* Headline sits tight against the section head. Line-height 1.0 so the
     two lines read as one connected statement. !important defends the
     margin values against any flex-gap or cascade leak. */
  /* Headline rhythm tightens to a single typographic block (kicker, title,
     lede then live inside .section-head and inherit the unified gap vars). */
  .ecosysteme .section-head{ margin: 0; }
  .ecosysteme .section-head__title{
    line-height: 1.0;
  }

  /* ── Org tree ────────────────────────────────────────────────────────────
     Centered SVG spine + 5 entity rows alternating L/R from the trunk.
     Spine draws via stroke-dashoffset (see main.js). Rows fade in as the
     line "reaches" each dot. The em dash before each country label is
     replaced by a 14px CSS hairline rule per the project content rule. */
  .ecosysteme{ background: transparent; }   /* Cream now painted by the
                                               shared .topography-wrapper
                                               that spans sections 03 + 04. */
  .ecosysteme .section__watermark{ display: none; }

  .org-tree{
    margin-top: 96px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    --ot-arm: 60px;
    --ot-dot: 14px;
    /* Icon-circle replaces the legacy dot as the per-entity marker.
       Arm + content position formulas reference --ot-icon so the
       horizontal hairline lands flush against the cream circle. */
    --ot-icon: 72px;
    --ot-gap: 16px;
    --ot-row-h: 160px;
    --ot-ease: cubic-bezier(0.22, 1, 0.36, 1);
    /* Mirrored enter/exit timing : both directions feel deliberate.
       Description leads with 120ms delay, image follows at 240ms. */
    --ot-dur: 600ms;
  }
  .org-tree__logo{
    display: flex;
    justify-content: center;
    margin-bottom: 56px;
  }
  .org-tree__logo img{
    height: 64px;
    width: auto;
    display: block;
  }

  .org-tree__diagram{
    position: relative;
    max-width: 880px;
    width: 100%;
    margin: 0 auto;
  }

  .org-tree__spine{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 2px;
    height: 100%;
    z-index: 0;
    overflow: visible;
    pointer-events: none;
  }
  .org-tree__spine-line{
    stroke: var(--color-brand-20);
    stroke-width: 2;
    fill: none;
    transition: stroke var(--ot-dur) var(--ot-ease);
  }
  .org-tree__diagram.is-hovering .org-tree__spine-line{
    stroke: var(--color-brand-10);
  }

  .org-tree__rows{
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
    z-index: 1;
  }
  /* Row uses min-height so the active (hovered) row can grow naturally
     when description + image expand. Idle rows keep their --ot-row-h
     baseline so the section reads as a calm grid until interaction. */
  .org-tree__row{
    position: relative;
    min-height: var(--ot-row-h);
  }
  .org-tree__entry{
    position: absolute;
    inset: 0;
    display: block;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
  }

  .org-tree__dot{
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--ot-dot);
    height: var(--ot-dot);
    margin-left: calc(var(--ot-dot) / -2);
    margin-top: calc(var(--ot-dot) / -2);
    border-radius: 50%;
    background: var(--color-brand-40);
    transition:
      background-color var(--ot-dur) var(--ot-ease),
      width var(--ot-dur) var(--ot-ease),
      height var(--ot-dur) var(--ot-ease),
      margin var(--ot-dur) var(--ot-ease);
    z-index: 2;
  }
  .org-tree__arm{
    position: absolute;
    top: 50%;
    height: 2px;
    width: var(--ot-arm);
    background: var(--color-brand-20);
    transition:
      background-color 700ms cubic-bezier(0.16, 1, 0.3, 1),
      width 700ms cubic-bezier(0.16, 1, 0.3, 1);
    z-index: 1;
  }
  .org-tree__row--left  .org-tree__arm{ right: calc(50% + (var(--ot-icon) / 2)); }
  .org-tree__row--right .org-tree__arm{ left:  calc(50% + (var(--ot-icon) / 2)); }

  /* Per-entity arm extension target for the hover/active state. The arm
     grows from --ot-arm out to --ot-arm-extended, sweeping under each
     entity name as an underline that ends just past the text. */
  .org-tree__row[data-entity="kamino"]{      --ot-arm-extended: 288px; }
  .org-tree__row[data-entity="hummingbird"]{ --ot-arm-extended: 270px; }
  .org-tree__row[data-entity="kp"]{          --ot-arm-extended: 145px; }
  .org-tree__row[data-entity="geneva"]{      --ot-arm-extended: 240px; }
  .org-tree__row[data-entity="manta"]{       --ot-arm-extended: 279px; }
  .org-tree__row[data-entity="supply"]{      --ot-arm-extended: 364px; }

  /* Anchor the name's BOTTOM edge to the row's 50% line (= arm Y position),
     so the extending arm acts as a true underline beneath the name rather
     than cutting through its vertical center. Name line-height box =
     var(--text-lg) × leading-tight = 20px × 1.2 = 24px ; full box offset
     above the 50% line = 24px. Description still expands downward only
     because the name itself does not move when the description reveals.
     z-index 2 puts name above the extending arm. */
  .org-tree__content{
    position: absolute;
    top: 50%;
    transform: translateY(-24px);
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-width: 320px;
    z-index: 2;
  }
  .org-tree__row--left .org-tree__content{
    right: calc(50% + (var(--ot-icon) / 2) + var(--ot-arm) + var(--ot-gap));
    text-align: right;
    align-items: flex-end;
  }
  .org-tree__row--right .org-tree__content{
    left: calc(50% + (var(--ot-icon) / 2) + var(--ot-arm) + var(--ot-gap));
    text-align: left;
    align-items: flex-start;
  }

  .org-tree__name{
    font-family: var(--font-heading);
    font-weight: var(--weight-semibold);
    font-size: var(--text-lg);
    line-height: var(--leading-tight);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--color-accent-orange);
    position: relative;
    display: inline-flex;
    align-items: center;
    transition:
      color var(--ot-dur) var(--ot-ease),
      font-weight 200ms ease;
  }

  /* Arrow icon (matches site CTA arrows). Renders AFTER the name,
     hidden in idle, slides in + rotates 45deg on hover to mirror the
     .btn__arrow-square wrapper rotation used elsewhere on the site. */
  .org-tree__arrow{
    display: inline-block;
    vertical-align: middle;
    width: 22px;
    height: 22px;
    margin-left: 12px;
    color: inherit;
    opacity: 0;
    transform: translateX(-6px);
    flex-shrink: 0;
    transition:
      opacity var(--ot-dur) var(--ot-ease),
      transform var(--ot-dur) var(--ot-ease);
  }

  .org-tree__tagline{
    font-family: var(--font-body);
    font-weight: var(--weight-regular);
    font-size: var(--text-md);
    line-height: var(--leading-normal);
    color: var(--color-brand-80);
    margin-top: 2px;
    white-space: nowrap;
    transition:
      color var(--ot-dur) var(--ot-ease),
      font-weight var(--ot-dur) var(--ot-ease);
  }

  /* Hover description : hidden by default (no layout impact), expands
     in on hover. max-height is animated so the row only grows when its
     entry is hovered. Only one row is ever hovered at a time. */
  .org-tree__description{
    font-family: var(--font-body);
    font-weight: var(--weight-regular);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: rgb(from var(--color-dark) r g b / 0.8);
    max-width: 320px;
    max-height: 0;
    margin-top: 0;
    opacity: 0;
    overflow: hidden;
    transform: translateY(8px);
    transition:
      max-height 700ms cubic-bezier(0.16, 1, 0.3, 1),
      margin-top 700ms cubic-bezier(0.16, 1, 0.3, 1),
      opacity 700ms cubic-bezier(0.16, 1, 0.3, 1),
      transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  /* ── Hover states ─────────────────────────────────────────────────────
     Driven by .org-tree__diagram.is-hovering (JS toggles per-entry on
     mouseenter, mouseleave, focus, blur). :focus-visible / :hover
     selectors below cover the active row. Sibling-recede selectors use
     .is-hovering plus :not(:hover) and a :has() fallback.

     Mobile : because :hover is unreliable on touch, an additional class
     pair drives the same active state: .org-tree__entry.is-active marks
     the row whose center sits closest to the viewport center, and
     .org-tree__diagram.has-active mirrors .is-hovering so the
     sibling-recede selectors fire identically. The class toggling
     happens in main.js (gsap.matchMedia (max-width: 767px) and
     (prefers-reduced-motion: no-preference) branch). */
  .org-tree__entry{
    transition: none;
  }

  /* Active (hovered or keyboard-focused or scroll-active) row */
  .org-tree__entry:hover,
  .org-tree__entry:focus-visible,
  .org-tree__entry.is-active{
    outline: none;
  }
  .org-tree__entry:hover .org-tree__dot,
  .org-tree__entry:focus-visible .org-tree__dot,
  .org-tree__entry.is-active .org-tree__dot{
    background: var(--color-accent-orange);
    width: 20px;
    height: 20px;
    margin-left: -10px;
    margin-top: -10px;
  }
  .org-tree__entry:hover .org-tree__arm,
  .org-tree__entry:focus-visible .org-tree__arm,
  .org-tree__entry.is-active .org-tree__arm{
    background: var(--color-accent-orange);
    width: var(--ot-arm-extended);
  }
  .org-tree__entry:hover .org-tree__name,
  .org-tree__entry:focus-visible .org-tree__name,
  .org-tree__entry.is-active .org-tree__name{
    color: var(--color-accent-orange);
    font-weight: 700;
  }
  /* Arrow rotation matches the site's .btn__arrow-square hover behaviour
     (rotate(45deg)). Slides in from the left as it appears. */
  .org-tree__entry:hover .org-tree__arrow,
  .org-tree__entry:focus-visible .org-tree__arrow,
  .org-tree__entry.is-active .org-tree__arrow{
    opacity: 1;
    transform: translateX(0) rotate(45deg);
  }
  .org-tree__entry:hover .org-tree__tagline,
  .org-tree__entry:focus-visible .org-tree__tagline,
  .org-tree__entry.is-active .org-tree__tagline{
    font-weight: var(--weight-semibold);
  }
  .org-tree__entry:hover .org-tree__description,
  .org-tree__entry:focus-visible .org-tree__description,
  .org-tree__entry.is-active .org-tree__description{
    max-height: 200px;
    margin-top: 12px;
    opacity: 1;
    transform: translateY(0);
    transition:
      max-height 700ms cubic-bezier(0.16, 1, 0.3, 1) 200ms,
      margin-top 700ms cubic-bezier(0.16, 1, 0.3, 1) 200ms,
      opacity 700ms cubic-bezier(0.16, 1, 0.3, 1) 200ms,
      transform 700ms cubic-bezier(0.16, 1, 0.3, 1) 200ms;
  }

  /* Sibling (non-hovered, non-active) rows recede when ANY entry is
     active. JS toggles .is-hovering (desktop hover) and .has-active
     (mobile scroll) on the diagram ; :has() mirrors the same intent
     for environments where JS has not yet attached. */
  .org-tree__diagram.is-hovering .org-tree__row:not(:hover):not(:focus-within) .org-tree__name,
  .org-tree__diagram:has(.org-tree__entry:hover) .org-tree__row:not(:hover):not(:focus-within) .org-tree__name,
  .org-tree__diagram:has(.org-tree__entry:focus-visible) .org-tree__row:not(:hover):not(:focus-within) .org-tree__name,
  .org-tree__diagram.has-active .org-tree__row:not(:has(.org-tree__entry.is-active)) .org-tree__name{
    color: var(--color-accent-orange);
  }
  .org-tree__diagram.is-hovering .org-tree__row:not(:hover):not(:focus-within) .org-tree__tagline,
  .org-tree__diagram:has(.org-tree__entry:hover) .org-tree__row:not(:hover):not(:focus-within) .org-tree__tagline,
  .org-tree__diagram:has(.org-tree__entry:focus-visible) .org-tree__row:not(:hover):not(:focus-within) .org-tree__tagline,
  .org-tree__diagram.has-active .org-tree__row:not(:has(.org-tree__entry.is-active)) .org-tree__tagline{
    color: var(--color-brand-40);
  }
  .org-tree__diagram.is-hovering .org-tree__row:not(:hover):not(:focus-within) .org-tree__dot,
  .org-tree__diagram:has(.org-tree__entry:hover) .org-tree__row:not(:hover):not(:focus-within) .org-tree__dot,
  .org-tree__diagram:has(.org-tree__entry:focus-visible) .org-tree__row:not(:hover):not(:focus-within) .org-tree__dot,
  .org-tree__diagram.has-active .org-tree__row:not(:has(.org-tree__entry.is-active)) .org-tree__dot{
    background: var(--color-brand-10);
  }
  .org-tree__diagram.is-hovering .org-tree__row:not(:hover):not(:focus-within) .org-tree__arm,
  .org-tree__diagram:has(.org-tree__entry:hover) .org-tree__row:not(:hover):not(:focus-within) .org-tree__arm,
  .org-tree__diagram:has(.org-tree__entry:focus-visible) .org-tree__row:not(:hover):not(:focus-within) .org-tree__arm,
  .org-tree__diagram.has-active .org-tree__row:not(:has(.org-tree__entry.is-active)) .org-tree__arm{
    background: var(--color-brand-10);
  }
  .org-tree__diagram:has(.org-tree__entry:hover) .org-tree__spine-line,
  .org-tree__diagram:has(.org-tree__entry:focus-visible) .org-tree__spine-line,
  .org-tree__diagram.has-active .org-tree__spine-line{
    stroke: var(--color-brand-10);
  }

  /* Reduced motion : keep contrast (font-size + color shifts) but
     remove the perception of motion. Description fades happen instantly. */
  @media (prefers-reduced-motion: reduce){
    .org-tree__spine-line,
    .org-tree__dot,
    .org-tree__arm,
    .org-tree__name,
    .org-tree__arrow,
    .org-tree__tagline,
    .org-tree__description{
      transition-duration: 0ms !important;
      transition-delay: 0ms !important;
    }
    .org-tree__description{ transform: none; }
  }

  @media (max-width: 767px){
    .org-tree{
      --ot-arm: 24px;
      --ot-row-h: 108px;
    }
    .org-tree__logo{ margin-bottom: 40px; }
    .org-tree__diagram{ max-width: none; }
    .org-tree__spine{
      /* SVG is 2px wide with the line at viewBox x=1 (svg-center). To land
         the actual stroke at 24px from the diagram edge, offset the SVG
         by 1px so its center column sits exactly at x=24. */
      left: 23px;
      transform: none;
    }
    .org-tree__dot{
      left: 24px;
      margin-left: calc(var(--ot-dot) / -2);
    }
    .org-tree__row--left  .org-tree__arm,
    .org-tree__row--right .org-tree__arm{
      left: calc(24px + (var(--ot-icon) / 2));
      right: auto;
    }
    .org-tree__row--left  .org-tree__content,
    .org-tree__row--right .org-tree__content{
      left: calc(24px + (var(--ot-icon) / 2) + var(--ot-arm) + var(--ot-gap));
      right: auto;
      text-align: left;
      align-items: flex-start;
      max-width: calc(100% - (24px + (var(--ot-icon) / 2) + var(--ot-arm) + var(--ot-gap) + 16px));
    }
    .org-tree__name{ font-size: var(--text-lg); }
    /* Mobile per-entity arm extension : proportionally shorter than desktop
       because --ot-arm baseline is 24px (vs 60px) and content sits closer
       to the circle. */
    .org-tree__row[data-entity="kamino"]{      --ot-arm-extended: 160px; }
    .org-tree__row[data-entity="hummingbird"]{ --ot-arm-extended: 140px; }
    .org-tree__row[data-entity="kp"]{          --ot-arm-extended: 65px;  }
    .org-tree__row[data-entity="geneva"]{      --ot-arm-extended: 130px; }
    .org-tree__row[data-entity="manta"]{       --ot-arm-extended: 155px; }
    .org-tree__row[data-entity="supply"]{      --ot-arm-extended: 130px; }
    /* Description max-height accommodates longer paragraphs on narrow viewports */
    .org-tree__entry:hover .org-tree__description,
    .org-tree__entry:focus-visible .org-tree__description,
    .org-tree__entry.is-active .org-tree__description{
      max-height: 240px;
    }
    /* Mobile: allow tagline to wrap if it overruns the narrow row width. */
    .org-tree__tagline{
      white-space: normal;
    }
    /* Reserve internal vertical room on the active row so the expanded
       description (max-height 120px) plus the larger name (22px) plus
       the 12px description margin fit within the row's box. The content
       block is position:absolute centered (top:50% + translateY(-50%))
       within the row, so without enough min-height it would overflow up
       and down into the rows above and below. The row's intrinsic height
       grows to 220px while active and returns to --ot-row-h (108px)
       when scroll moves on, pushing siblings naturally via normal flow. */
    .org-tree__row:has(.org-tree__entry.is-active){
      min-height: 320px;
    }
  }

  /* ── Per-entity icon marker (cream circle + 3 amber ripples) ───────
     Replaces the legacy .org-tree__dot. A zero-size positioning anchor
     (.org-tree__icon) sits at the row center; the cream circle and the
     three concentric amber ripples are absolutely centered on that
     point via transform: translate(-50%,-50%). The Phosphor glyph
     inside the cream circle inherits color from .org-tree__icon-circle
     so idle/active/recede transitions only target the circle and the
     icon, never the spine or arms. */
  .org-tree__icon{
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    z-index: 2;
    pointer-events: none;
  }
  .org-tree__icon-circle{
    position: absolute;
    top: 0;
    left: 0;
    width: var(--ot-icon);
    height: var(--ot-icon);
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: var(--color-cream);                /* Solid cream fill
                                                      masks the spine
                                                      where it would
                                                      otherwise bisect
                                                      the circle. */
    border: 2px solid var(--color-brand-20);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-brand);
    z-index: 3;
    transition:
      background-color var(--ot-dur) var(--ot-ease),
      border-color var(--ot-dur) var(--ot-ease),
      color var(--ot-dur) var(--ot-ease);
  }
  .org-tree__icon-circle i{
    font-size: 24px;
    line-height: 1;
    color: inherit;
    transition: color var(--ot-dur) var(--ot-ease);
  }
  /* Phosphor auto-replaces <i class="ph ph-*"> with an inline <svg>.
     The replaced SVG inherits color via currentColor, but its sizing
     comes from font-size on the parent. Ensure the SVG fills the
     glyph slot consistently. */
  .org-tree__icon-circle svg{
    width: 24px;
    height: 24px;
    color: inherit;
  }
  /* Per-entity sizing for optical balance. Hummingbird's glyph carries
     empty padding inside its viewBox so it gets bumped slightly larger ;
     Manta's landscape mark (175:120) needs the biggest bounding box to
     read at comparable weight to the near-square marks. */
  .org-tree__row[data-entity="kamino"] .org-tree__icon-circle svg{
    width: 41px;
    height: 41px;
  }
  .org-tree__row[data-entity="hummingbird"] .org-tree__icon-circle svg{
    width: 44px;
    height: 44px;
  }
  .org-tree__row[data-entity="kp"] .org-tree__icon-circle svg{
    width: 41px;
    height: 41px;
  }
  .org-tree__row[data-entity="geneva"] .org-tree__icon-circle svg{
    width: 41px;
    height: 41px;
  }
  .org-tree__row[data-entity="manta"] .org-tree__icon-circle svg{
    width: 36px;
    height: 36px;
  }
  .org-tree__row[data-entity="supply"] .org-tree__icon-circle svg{
    width: 40px;
    height: 40px;
  }
  .org-tree__icon-ripple{
    position: absolute;
    top: 0;
    left: 0;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: var(--color-accent-orange);
    pointer-events: none;
    transition:
      opacity var(--ot-dur) var(--ot-ease),
      transform var(--ot-dur) var(--ot-ease),
      background-color var(--ot-dur) var(--ot-ease);
  }
  /* Proportional ripple scale : +16px / +34px / +54px on the icon
     diameter. Ripples are INVISIBLE at idle (opacity 0) and bloom in
     on active. --1 is the tightest and most opaque ring at active ;
     --3 is the widest, faintest halo. */
  .org-tree__icon-ripple--1{
    width: calc(var(--ot-icon) + 16px);
    height: calc(var(--ot-icon) + 16px);
    opacity: 0;
    z-index: 2;
  }
  .org-tree__icon-ripple--2{
    width: calc(var(--ot-icon) + 34px);
    height: calc(var(--ot-icon) + 34px);
    opacity: 0;
    z-index: 1;
  }
  .org-tree__icon-ripple--3{
    width: calc(var(--ot-icon) + 54px);
    height: calc(var(--ot-icon) + 54px);
    opacity: 0;
    z-index: 0;
  }

  /* Active row : the ONLY visual changes are border-color and glyph
     color, both shifting from maroon to amber. The circle background
     stays transparent. Ripples remain hidden in every state (their
     DOM nodes are kept for legacy JS compatibility but never bloom). */
  .org-tree__entry:hover .org-tree__icon-circle,
  .org-tree__entry:focus-visible .org-tree__icon-circle,
  .org-tree__entry.is-active .org-tree__icon-circle{
    border-color: var(--color-accent-orange);
    color: var(--color-accent-orange);            /* Propagates to the
                                                     glyph via inherit
                                                     on i / svg. */
  }
  /* Ripples kept at opacity 0 in active states (no halo bloom). */
  .org-tree__entry:hover .org-tree__icon-ripple--1,
  .org-tree__entry:focus-visible .org-tree__icon-ripple--1,
  .org-tree__entry.is-active .org-tree__icon-ripple--1,
  .org-tree__entry:hover .org-tree__icon-ripple--2,
  .org-tree__entry:focus-visible .org-tree__icon-ripple--2,
  .org-tree__entry.is-active .org-tree__icon-ripple--2,
  .org-tree__entry:hover .org-tree__icon-ripple--3,
  .org-tree__entry:focus-visible .org-tree__icon-ripple--3,
  .org-tree__entry.is-active .org-tree__icon-ripple--3{
    opacity: 0;
  }

  /* Sibling recede REMOVED for icons : all 5 entity icons retain their
     full idle appearance regardless of which row is hovered/active.
     (The text-level sibling recede on .org-tree__name / __tagline /
     __arm above remains intact, per scope of this edit.) */

  /* Reduced motion : ripples and glyph snap between states. */
  @media (prefers-reduced-motion: reduce){
    .org-tree__icon-circle,
    .org-tree__icon-circle i,
    .org-tree__icon-circle svg,
    .org-tree__icon-ripple{
      transition-duration: 0ms !important;
      transition-delay: 0ms !important;
    }
  }

  /* Mobile : shrink the icon so the marker still fits inside the
     narrower 108px row baseline. Ripple offsets are absolute pixels
     so they scale with the icon naturally. */
  @media (max-width: 767px){
    .org-tree{
      --ot-icon: 44px;
    }
    .org-tree__icon{
      left: 24px;
    }
    .org-tree__icon-circle i,
    .org-tree__icon-circle svg{
      font-size: 18px;
      width: 18px;
      height: 18px;
    }
    /* Per-entity sizing : ~75% of desktop values. */
    .org-tree__row[data-entity="kamino"] .org-tree__icon-circle svg{
      width: 31px;
      height: 31px;
    }
    .org-tree__row[data-entity="hummingbird"] .org-tree__icon-circle svg{
      width: 33px;
      height: 33px;
    }
    .org-tree__row[data-entity="kp"] .org-tree__icon-circle svg{
      width: 31px;
      height: 31px;
    }
    .org-tree__row[data-entity="geneva"] .org-tree__icon-circle svg{
      width: 31px;
      height: 31px;
    }
    .org-tree__row[data-entity="manta"] .org-tree__icon-circle svg{
      width: 27px;
      height: 27px;
    }
    .org-tree__row[data-entity="supply"] .org-tree__icon-circle svg{
      width: 30px;
      height: 30px;
    }
  }

  /* Topography is now painted by the shared .topography-wrapper that
     spans sections 03 + 04 as a single continuous image with one mask
     gradient. The legacy .ecosysteme::before rule was removed to
     eliminate the seam between the two sections. */

  /* ── Entity silhouettes ───────────────────────────────────────────────
     Five faded silhouette images, one per entity, painted behind the
     org-tree as a quiet backdrop. Each silhouette has its OWN framing
     (anchor, size, mask) tuned to the composition baked into its PNG :
     no shared "side alternation" rule applies. The wrapper covers
     the full écosystème section so children can anchor against any
     edge.

     Default state : Kamino visible. Hover / focus-visible / .is-active
     on any .org-tree__entry cross-fades to the matching silhouette
     via parent :has() selectors. .is-active is set on mobile by
     main.js as rows enter the viewport center, so the same selectors
     drive the touch experience without any JS changes.
     ──────────────────────────────────────────────────────────────────── */
  .ecosysteme__silhouettes{
    position: absolute;
    inset: 0;                        /* Full section coverage so children
                                        can anchor against any edge. */
    pointer-events: none;            /* Decorative ; never intercepts
                                        clicks meant for the spine. */
    z-index: 0;                      /* Behind icons / text / spine. */
  }
  .ecosysteme__silhouette{
    position: absolute;
    opacity: 0;
    transition: opacity 600ms ease-out;
  }

  /* Kamino : tall vertical composition, right-anchored. Anchor matches
     KP so the 100vh-tall image bleeds past the section bottom (clipped
     by .ecosysteme overflow:hidden) and reads as full-viewport, rather
     than floating centered with symmetric gaps in a section that is
     taller than the viewport. */
  .ecosysteme__silhouette--kamino{
    right: 0;
    top: 65%;
    transform: translateY(-50%);
    height: 100vh;
    width: auto;
    -webkit-mask-image: linear-gradient(to bottom,
      transparent 0%, black 12%, black 88%, transparent 100%);
    mask-image: linear-gradient(to bottom,
      transparent 0%, black 12%, black 88%, transparent 100%);
  }

  /* Hummingbird : wide composition spanning the full section width,
     anchored to the section bottom. No mask : the bottom edge is
     intentional, and a top feather would clash with the horizon. */
  .ecosysteme__silhouette--hummingbird{
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: auto;
  }

  /* KP : tall vertical composition, right-anchored. The figure sits in
     the upper portion of the PNG canvas, so the anchor is dropped to
     65% of the section so the figure aligns with the KP row on the
     spine (rather than floating near the top). */
  .ecosysteme__silhouette--kp{
    right: 0;
    top: 65%;
    transform: translateY(-50%);
    height: 100vh;
    width: auto;
    -webkit-mask-image: linear-gradient(to bottom,
      transparent 0%, black 12%, black 88%, transparent 100%);
    mask-image: linear-gradient(to bottom,
      transparent 0%, black 12%, black 88%, transparent 100%);
  }

  /* Geneva : full-width, bottom-anchored, natural aspect ratio
     (matches Hummingbird pattern). The PNG was NOT exported with
     baked-in opacity, so it relies on a low CSS opacity (set in the
     hover rule below) to read as a faint texture rather than a
     dominant background. */
  .ecosysteme__silhouette--geneva{
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: auto;
    object-fit: contain;
    object-position: center bottom;
  }

  /* Manta : wide composition, right-anchored, bottom-anchored. Width
     bumped to 95vw (~27% larger) for more visual presence ; bottom
     pulled to -40px so the larger image still reads as grounded
     against the section floor rather than rising into the spine. */
  .ecosysteme__silhouette--manta{
    right: 0;
    bottom: -40px;
    width: 95vw;
    height: auto;
  }

  /* Okapi Supply Trading : hover-toggled backdrop (matches geneva pattern).
     Base opacity:0 inherited from shared .ecosysteme__silhouette rule; supply
     row hover fades it to 0.05 via the hover rule below (also matches geneva).
     Sized to 70% of section width, bottom-anchored, horizontally centred so
     the world-map sits low against the section floor rather than dominating
     the middle. Sepia filter warms the near-black ink into the maroon family. */
  .ecosysteme__silhouette--supply{
    left: 50%;
    bottom: 0;
    transform: translate(-50%, 25%);
    width: 70%;
    height: auto;
    filter: sepia(1) hue-rotate(-15deg) saturate(2.5);
  }

  /* Default idle state : Kamino visible. */
  .ecosysteme__silhouette--kamino{ opacity: 1; }

  /* On any active entry, hide the default Kamino so non-Kamino hover
     does not show two silhouettes at once. */
  .ecosysteme:has(.org-tree__entry:is(:hover, :focus-visible, .is-active))
    .ecosysteme__silhouette--kamino{
    opacity: 0;
  }
  /* Bring up the silhouette matching the active row. Geneva gets a
     low opacity because its PNG was not pre-faded. */
  .ecosysteme:has(.org-tree__row[data-entity="kamino"] .org-tree__entry:is(:hover, :focus-visible, .is-active))
    .ecosysteme__silhouette--kamino{
    opacity: 1;
  }
  .ecosysteme:has(.org-tree__row[data-entity="hummingbird"] .org-tree__entry:is(:hover, :focus-visible, .is-active))
    .ecosysteme__silhouette--hummingbird{
    opacity: 1;
  }
  .ecosysteme:has(.org-tree__row[data-entity="kp"] .org-tree__entry:is(:hover, :focus-visible, .is-active))
    .ecosysteme__silhouette--kp{
    opacity: 1;
  }
  .ecosysteme:has(.org-tree__row[data-entity="geneva"] .org-tree__entry:is(:hover, :focus-visible, .is-active))
    .ecosysteme__silhouette--geneva{
    opacity: 0.05;
  }
  .ecosysteme:has(.org-tree__row[data-entity="manta"] .org-tree__entry:is(:hover, :focus-visible, .is-active))
    .ecosysteme__silhouette--manta{
    opacity: 1;
  }
  .ecosysteme:has(.org-tree__row[data-entity="supply"] .org-tree__entry:is(:hover, :focus-visible, .is-active))
    .ecosysteme__silhouette--supply{
    opacity: 0.05;
  }
  /* Reduced motion : snap between silhouettes instead of cross-fading. */
  @media (prefers-reduced-motion: reduce){
    .ecosysteme__silhouette{ transition-duration: 0ms; }
  }

  /* Mobile : the three wide-aspect silhouettes (Hummingbird 1.74,
     Geneva 2.06, Manta 2.95) collapse to ~120-215px tall when sized
     by width on a 375px viewport, leaving them visibly undersized
     next to the height-driven Kamino / KP. Switch them to height-driven
     sizing so they fill the section vertically (matching Kamino / KP
     scale), anchor right so horizontal overflow falls off the left edge
     behind the spine column (clipped by .ecosysteme overflow:hidden).
     Object-position bottom keeps each composition's grounded baseline
     (horizon for Hummingbird, ground line for Geneva and Manta) visible
     while the wide top crops off-screen. */
  @media (max-width: 767px){
    .ecosysteme__silhouette--hummingbird,
    .ecosysteme__silhouette--geneva,
    .ecosysteme__silhouette--manta{
      width: auto;
      height: 100vh;
      left: auto;
      right: 0;
      bottom: 0;
      object-fit: cover;
      object-position: right bottom;
    }
  }

  /* ── Stacked split cards (legacy : superseded by .org-tree) ────────── */
  .entity-cards{
    margin-top: 80px;
    display: flex;
    flex-direction: column;
    gap: 40px;
  }
  @media (max-width: 767px){ .entity-cards{ margin-top: 56px; gap: 32px; } }

  /* Anchor wrapper that turns each entity card into one full-card click
     target. Block-level so the wrapped <article> fills it; inherits the
     visual from the article itself (no underline, no color change, no
     extra spacing). All existing .entity-card hover effects continue
     working untouched because the article inside is still the styled
     element. Focus ring routed through the article so keyboard users see
     the same outline as everywhere else. */
  .entity-card-link{
    display: block;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    border-radius: var(--radius-xl);
  }
  .entity-card-link:hover,
  .entity-card-link:focus,
  .entity-card-link:visited,
  .entity-card-link:active{
    color: inherit;
    text-decoration: none;
  }
  .entity-card-link:focus{ outline: none; }
  .entity-card-link:focus-visible{
    outline: 2px solid var(--amber);
    outline-offset: 4px;
  }

  .entity-card{
    display: grid;
    grid-template-columns: 42fr 58fr;
    height: 520px;
    border-radius: var(--radius-xl);
    overflow: hidden;
    background: var(--panel-bg, var(--canvas-d));
    color: var(--panel-ink, var(--ink-d));
    opacity: 0;
    transform: translateY(40px);
    will-change: transform, opacity;
    box-shadow: 0 40px 90px -40px rgba(26, 12, 6, 0.28);
  }
  @media (max-width: 1023px){ .entity-card{ height: 420px; } }
  @media (max-width: 767px){
    .entity-card{
      grid-template-columns: 1fr;
      grid-template-rows: 320px auto;
      height: auto;
    }
  }

  .entity-card__panel{
    position: relative;
    padding: 56px;
    display: flex;
    flex-direction: column;
    gap: 0;
    background: var(--panel-bg);
    color: var(--panel-ink);
  }
  @media (max-width: 767px){ .entity-card__panel{ padding: 40px 28px; order: 2; } }

  .entity-card__num{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--amber);
    display: block;
    margin-bottom: 24px;
  }
  .entity-card__name{
    font-family: var(--font-display);
    font-weight: var(--weight-light);
    font-size: var(--text-3xl);
    letter-spacing: -0.022em;
    line-height: 1.04;
    margin: 0;
    color: var(--panel-ink);
  }
  @media (max-width: 1023px){ .entity-card__name{ font-size: var(--text-2xl); } }
  @media (max-width: 767px){  .entity-card__name{ font-size: var(--text-2xl); } }

  .entity-card__desc{
    font-family: var(--font-body);
    font-weight: var(--weight-regular);
    font-size: var(--text-md);
    line-height: var(--leading-normal);
    max-width: 380px;
    margin: 24px 0 0;
    color: var(--panel-ink);
    opacity: 0.88;
  }
  .entity-card__meta{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono);
    text-transform: uppercase;
    color: var(--panel-ink);
    opacity: 0.7;
    margin-top: auto;
    padding-top: 32px;
  }
  .entity-card__cta{
    display: inline-flex;
    align-items: center;
    gap: 16px;
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono-wide);
    text-transform: uppercase;
    color: var(--panel-ink);
    margin-top: 16px;
    align-self: flex-start;
    cursor: pointer;
  }
  /* .entity-card__arrow : visual chrome now supplied by .btn--tertiary-visual
     in the markup (48×48, 10px radius, amber fill). This selector retained
     only as a JS/DOM hook and as the target of the card-level hover below. */

  .entity-card__media{
    position: relative;
    overflow: hidden;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-top-right-radius: var(--radius-xl);
    border-bottom-right-radius: var(--radius-xl);
  }
  @media (max-width: 767px){
    .entity-card__media{
      order: 1;
      border-top-left-radius: var(--radius-xl);
      border-top-right-radius: var(--radius-xl);
      border-bottom-left-radius: 0;
      border-bottom-right-radius: 0;
    }
  }
  .entity-card-img{
    width: 100%;
    /* Oversize vertically so pocket parallax (yPercent -8) has headroom. */
    height: 120%;
    margin-top: -10%;
    object-fit: cover;
    object-position: center;
    display: block;
    will-change: transform;
    transition: transform 700ms var(--ease-out-expo);
  }
  .entity-card:hover .entity-card-img{ transform: scale(1.03); }
  .entity-card:hover .entity-card__arrow{ transform: rotate(45deg) scale(1.08); }

  /* ════════════════════════════════════════════════════════════════════════
     SECTION 05 : RÉSEAU (cream, interactive globe iframe)
     ════════════════════════════════════════════════════════════════════════ */
  .reseau{ background: #F5F2EC; color: var(--ink); }
  .reseau__lede{
    max-width: 56ch;
    font-size: clamp(var(--text-md), 1.15vw, var(--text-lg));
    line-height: 1.6;
    color: var(--ink);
    margin: 0;
  }
  .reseau__globe{
    padding: 80px 0;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
  }
  .reseau__globe iframe{
    display: block;
    max-width: 100%;
    /* Desktop only : visually enlarge the globe by 20% without changing
       the iframe's layout box. transform-origin center keeps the globe
       centered horizontally and vertically inside the wrap, and the
       parent's 80px vertical padding absorbs the 72px of vertical visual
       overflow that the scale introduces. The mobile @media block below
       overrides this transform with its own transform-origin/scale rig
       so mobile sizing stays unchanged. */
    transform: scale(1.2);
    transform-origin: center center;
  }
  /* Subtle "spin me" hint overlaid on the globe. Same DM Mono kicker rhythm
     as section labels. Fades in once when the globe is visible, then out
     after a few seconds (driven from main.js). Pointer-events disabled so
     it never blocks the iframe drag interaction. */
  .reseau__hint{
    position: absolute;
    left: 50%;
    bottom: 64px;
    transform: translateX(-50%);
    font-family: var(--font-label);
    font-weight: var(--weight-regular);
    font-size: var(--text-xs);
    line-height: 1;
    letter-spacing: var(--track-mono);
    text-transform: uppercase;
    color: rgb(from var(--color-dark) r g b / 0.55);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    z-index: 2;
  }
  .reseau__hint::before{
    content: '';
    display: inline-block;
    width: 18px;
    height: 1px;
    background: currentColor;
    vertical-align: middle;
    margin-right: 12px;
    opacity: 0.6;
  }
  @media (max-width: 767px){
    /* The Three.js scene inside the iframe scales the globe in world units
       by (globeSize / window.innerHeight) * (visibleHeight / 2). With the
       default globeSize of 580px, the iframe height must be >= 720px for
       the globe + city labels + amber pulse halos to fit within the
       vertically-bound view frustum. The iframe's horizontal aspect must
       also be wide enough to keep Kinshasa (east edge) and its halo from
       running off the right. We render the iframe at 800 x 720 layout
       size (matching desktop's working height, with extra horizontal
       headroom for halos), then visually compress it with transform:scale
       so the visual rect fills the parent's content width on any mobile
       viewport. The parent's overflow:hidden clips the over-wide layout
       box. Desktop CSS at >767px is unchanged.

       Math: scale = parent_w / 800. parent_w = 100vw - 2 x section gutter
       (the section uses --margin = clamp(24px, 5vw, 80px)). visual_h =
       720 * scale ; reclaim the unused vertical layout space with a
       negative margin-bottom equal to 720 * (scale - 1) so the next
       cream area sits flush against the visible globe. */
    .reseau__globe{
      --reseau-scale: calc((100vw - 2 * clamp(24px, 5vw, 80px)) / 800px);
      padding: 40px 0;
      display: block;
      overflow: hidden;
    }
    .reseau__globe iframe{
      width: 800px !important;
      height: 720px !important;
      max-width: none;
      display: block;
      transform-origin: top left;
      transform: scale(var(--reseau-scale));
      margin-bottom: calc(720px * (var(--reseau-scale) - 1));
    }
    .reseau__hint{
      bottom: 32px;
      font-size: var(--text-xs);
      letter-spacing: 0.16em;
    }
  }

  /* ════════════════════════════════════════════════════════════════════════
     SECTION 06 : EXPERTISE (dark brown, entry to the dark zone)
     Brand primary maroon (#5C2E20) used as surface here, unifying 06+07
     into a single dark zone. The 48px top corners form the curved lip
     that visually separates the cream zone above from the dark zone
     below. Negative margin-top of -48px lets the rounded corners cut
     into the cream section above (Section 05 reseau), so the cut shows
     cream rather than the body's neutral dark background.
     ════════════════════════════════════════════════════════════════════════ */
  .expertise{
    background: var(--color-brand);
    color: var(--ink-d);
    border-top-left-radius: 48px;
    border-top-right-radius: 48px;
    margin-top: -48px;
    z-index: 2;
  }
  /* Header overrides for dark surface : kicker reads at 60% cream, the
     rust headline becomes plain cream, the lede reads at 80% cream. */
  .expertise .section-head__kicker{ color: color-mix(in srgb, var(--color-cream) 60%, transparent); }
  .expertise .section-head__lede{ color: color-mix(in srgb, var(--color-cream) 80%, transparent); }
  .expertise .headline--rust{ color: var(--ink-d); }
  /* Amber italic accents already pop on dark; left untouched. */
  .capabilities{
    display: grid;
    grid-template-columns: 1fr 1fr;
    border-top: 1px solid var(--hairline-d);
  }
  .capability{
    padding: 52px 40px 52px 0;
    border-bottom: 1px solid var(--hairline-d);
    position: relative;
    transition: transform 600ms var(--ease-viscous);
    opacity: 0;
    transform: translateY(20px);
  }
  .capability:nth-child(odd){ border-right: 1px solid var(--hairline-d); padding-right: 40px; }
  .capability:nth-child(even){ padding-left: 40px; padding-right: 0; }
  .capability__title{
    font-family: var(--font-heading);
    font-weight: var(--weight-regular);
    font-size: var(--text-xl);
    color: var(--ink-d);
    margin: 0 0 16px;
    line-height: 1.22;
  }
  .capability__desc{
    font-family: var(--font-body);
    font-weight: var(--weight-light);
    font-size: clamp(var(--text-sm), 1vw, var(--text-md));
    line-height: 1.7;
    color: color-mix(in srgb, var(--color-cream) 75%, transparent);
    margin: 0;
    max-width: 50ch;
  }
  .capability__rule{
    position: absolute;
    left: 0; bottom: -1px;
    width: 0;
    height: 1px;
    background: var(--amber);
    transition: width 720ms var(--ease-viscous);
  }
  .capability:nth-child(even) .capability__rule{ left: 40px; }
  .capability:hover .capability__rule{ width: 72px; }
  .capability:hover{ transform: translate(4px, 0); }
  @media (max-width: 767px){
    .capabilities{ grid-template-columns: 1fr; }
    .capability{ padding: 40px 0 !important; border-right: none !important; }
    .capability:nth-child(even) .capability__rule{ left: 0; }
  }

  /* ════════════════════════════════════════════════════════════════════════
     SECTION 05 : PARTENAIRES (deep teal)
     Logos are mixed PNG + JPEG. The cream-inverted filter alone would wash
     the opaque JPEGs to solid white, so we pair it with mix-blend-mode:
     screen so white JPEG backgrounds dissolve into the teal surface while
     dark logo strokes read as cream marks.
     ════════════════════════════════════════════════════════════════════════ */
  /* Section 07 unified into the dark-zone : same brand maroon as Section
     06 so the two sections read as one continuous dark surface. Existing
     .section-head--on-dark + .headline--teal-text overrides already paint
     text in cream, so no header changes are needed here. */
  .partenaires{ background: var(--color-brand); color: var(--ink-teal); }

  /* ── Two-row marquee ──────────────────────────────────────────────────
     Pure CSS keyframe scroll. Each row's track contains the logo set
     duplicated twice; the track translates by -50% over 60s, looping
     seamlessly. Top row scrolls right-to-left, bottom row scrolls
     left-to-right. Hovering any logo pauses ITS row only (via :has()).
     Edges fade via mask-image so the looping seam is hidden. */
  .marquee{
    /* Unified section-head gap-3 (96px) provides the spacing above the
       marquee. Internal padding stays for top/bottom breathing room
       between the two rows and the section bottom edge. */
    padding: 0 0 80px;
    display: flex;
    flex-direction: column;
    gap: 32px;
  }
  .marquee-row{
    width: 100%;
    overflow: hidden;
    mask-image: linear-gradient(to right, transparent 0%, #000 8%, #000 92%, transparent 100%);
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 8%, #000 92%, transparent 100%);
  }
  .marquee-row__track{
    display: flex;
    align-items: center;
    width: max-content;
    will-change: transform;
  }
  /* Top row : RTL (translates from 0 to -50%, content moves right-to-left). */
  .marquee-row--rtl .marquee-row__track{
    animation: marquee-rtl 60s linear infinite;
  }
  /* Bottom row : LTR (translates from -50% to 0, content moves left-to-right). */
  .marquee-row--ltr .marquee-row__track{
    animation: marquee-ltr 60s linear infinite;
  }
  @keyframes marquee-rtl{
    from{ transform: translateX(0); }
    to{ transform: translateX(-50%); }
  }
  @keyframes marquee-ltr{
    from{ transform: translateX(-50%); }
    to{ transform: translateX(0); }
  }
  /* Pause-on-hover : the entire row pauses when ANY logo in it is hovered.
     Other row keeps scrolling. */
  .marquee-row:hover .marquee-row__track,
  .marquee-row:focus-within .marquee-row__track{
    animation-play-state: paused;
  }

  /* Individual logo container : fixed height, white-treated SVGs by
     default, original brand color on hover. */
  .marquee-logo{
    flex: 0 0 auto;
    height: 48px;
    padding: 0 64px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .marquee-logo img{
    display: block;
    width: auto;
    height: 100%;
    max-height: 48px;
    object-fit: contain;
    filter: brightness(0) invert(1);
    opacity: 1;
    transition: filter 400ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .marquee-logo:hover img,
  .marquee-logo:focus-visible img{
    filter: none;
  }
  /* Text-only fallback for partners without a shipped SVG. Styled to read
     at the same visual weight as the logos around it. */
  .marquee-logo--text span{
    display: inline-block;
    font-family: var(--font-body);
    font-weight: var(--weight-semibold);
    font-size: var(--text-lg);
    letter-spacing: var(--track-wide-sm);
    text-transform: uppercase;
    color: #FFFFFF;
    white-space: nowrap;
    transition: color 400ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .marquee-logo--text:hover span,
  .marquee-logo--text:focus-visible span{
    color: var(--color-accent-orange);
  }
  /* Italco SVG ships with a tagline band : if it appears in the marquee
     later, crop the bottom 24%. Currently not in either row but the rule
     stays as a safety net. */
  .marquee-logo img[src*="italco"]{
    clip-path: inset(0 0 24% 0);
  }
  /* BP roundel + CBG emblem read smaller at the shared 48px height. Allow
     the bounding box to grow modestly so visual weight balances. */
  .marquee-logo img[src*="Bp_Logo"],
  .marquee-logo img[src*="CBG"]{
    height: 64px;
    max-height: 64px;
  }
  /* Lift the cell wrapper to match the img height so the row's
     overflow:hidden does not clip the BP/CBG emblems vertically. */
  .marquee-logo:has(img[src*="Bp_Logo"]),
  .marquee-logo:has(img[src*="CBG"]){
    height: 64px;
  }

  @media (max-width: 767px){
    .marquee{ padding: 0 0 56px; gap: 24px; }
    .marquee-row{
      mask-image: linear-gradient(to right, transparent 0%, #000 12%, #000 88%, transparent 100%);
      -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 12%, #000 88%, transparent 100%);
    }
    .marquee-row--rtl .marquee-row__track,
    .marquee-row--ltr .marquee-row__track{
      animation-duration: 45s;
    }
    .marquee-logo{
      height: 32px;
      padding: 0 40px;
    }
    .marquee-logo img{
      max-height: 32px;
    }
    .marquee-logo img[src*="Bp_Logo"],
    .marquee-logo img[src*="CBG"]{
      height: 44px;
      max-height: 44px;
    }
    .marquee-logo:has(img[src*="Bp_Logo"]),
    .marquee-logo:has(img[src*="CBG"]){
      height: 44px;
    }
    .marquee-logo--text span{
      font-size: var(--text-sm);
    }
  }

  /* Reduced motion : pause animations and lay logos out as a static grid. */
  @media (prefers-reduced-motion: reduce){
    .marquee{
      gap: 0;
    }
    .marquee-row{
      overflow: visible;
      mask-image: none;
      -webkit-mask-image: none;
    }
    .marquee-row__track{
      animation: none !important;
      transform: none !important;
      width: 100%;
      flex-wrap: wrap;
      justify-content: center;
      gap: 32px 48px;
    }
    /* Hide the duplicated set in the static layout to avoid double-listing. */
    .marquee-row__track > [aria-hidden="true"]{
      display: none;
    }
    .marquee-logo{
      padding: 0;
    }
  }

  /* ════════════════════════════════════════════════════════════════════════
     SECTION 06 : AU-DELÀ DE L'ÉNERGIE (warm cream)
     Two editorial stories. Visuals are placeholder panels (no polo / cinema
     photography shipped in the project). Kept editorial, never decorative.
     ════════════════════════════════════════════════════════════════════════ */
  .influence{ background: var(--canvas-warm); color: var(--ink); }
  .stories{
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 80px;
  }
  @media (max-width: 1023px){ .stories{ grid-template-columns: 1fr; gap: 64px; } }
  .story{
    opacity: 0;
    transform: translateY(24px);
    will-change: transform, opacity;
  }
  .story__visual{
    position: relative;
    aspect-ratio: 4 / 5;
    border-radius: var(--radius-xl);
    overflow: hidden;
    display: grid;
    place-items: center;
    padding: 32px;
    text-align: center;
    margin-bottom: 24px;
  }
  /* Section 08 Influence : two-up cards render in landscape (16:10) so
     the section reads horizontally instead of two tall portrait blocks.
     The 3-up Engagement grid on a-propos (.stories--triple) keeps the
     default 4:5 portrait crop. */
  .influence .stories .story__visual{ aspect-ratio: 16 / 10; }
  .story__visual--polo{
    background:
      radial-gradient(480px 320px at 30% 25%, rgba(200, 146, 42, 0.22) 0%, rgba(200,146,42,0) 60%),
      linear-gradient(135deg, #3d1208 0%, #5a1d0e 55%, #783214 100%);
  }
  .story__visual--cinema{
    background:
      radial-gradient(420px 300px at 70% 30%, rgba(245, 240, 234, 0.14) 0%, rgba(245,240,234,0) 60%),
      linear-gradient(135deg, #0a4a5e 0%, #123a48 60%, #061d26 100%);
  }
  .story__placeholder{
    position: relative;
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: rgba(245, 240, 234, 0.78);
    line-height: 2;
  }
  .story__placeholder small{
    display: block;
    color: rgba(245, 240, 234, 0.48);
    letter-spacing: var(--track-mono-wide);
    font-size: var(--text-xs);
    margin-top: 16px;
  }
  .story__title{
    font-family: var(--font-heading);
    font-weight: var(--weight-regular);
    font-size: clamp(var(--text-lg), 1.6vw, var(--text-xl));
    color: var(--color-dark);
    margin: 0 0 16px;
    line-height: var(--leading-snug);
  }
  .story__body{
    font-family: var(--font-body);
    font-weight: var(--weight-light);
    font-size: clamp(var(--text-sm), 1vw, var(--text-md));
    line-height: 1.7;
    color: var(--ink-2);
    margin: 0;
    max-width: 52ch;
  }

  /* ════════════════════════════════════════════════════════════════════════
     SECTION 07 : DIRECTION (rust tint)
     ════════════════════════════════════════════════════════════════════════ */
  .direction{ background: var(--canvas-rust); color: var(--ink); }
  .team-grid{
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 56px 40px;
  }
  @media (max-width: 1023px){ .team-grid{ grid-template-columns: repeat(2, 1fr); gap: 48px 24px; } }
  @media (max-width: 640px){  .team-grid{ grid-template-columns: 1fr; gap: 40px; } }
  .team-grid:hover .member{ opacity: 0.55; }
  .team-grid:hover .member:hover{ opacity: 1; }
  .team-grid:hover .member:hover .member__name{ transform: translateX(4px); }
  .member{
    transition: opacity 620ms var(--ease-viscous);
    opacity: 0;
    transform: translateY(20px);
    will-change: transform, opacity;
  }
  .member__portrait{
    position: relative;
    aspect-ratio: 4 / 5;
    border-radius: var(--radius-lg);
    overflow: hidden;
    margin-bottom: 24px;
    background: var(--ink-3);
    box-shadow: 0 26px 70px -30px rgba(61, 18, 8, 0.28);
  }
  .member__portrait img{
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
    filter: saturate(0.88) contrast(1.02);
  }
  .member__name{
    font-family: var(--font-heading);
    font-weight: var(--weight-light);
    /* +15% bump on Section 09 La Direction member names. */
    font-size: clamp(var(--text-xl), 2.3vw, var(--text-2xl));
    letter-spacing: var(--track-tight-sm);
    color: var(--color-dark);
    margin: 0 0 8px;
    line-height: var(--leading-tight);
    transition: transform 500ms var(--ease-viscous);
  }
  .member__role{
    font-family: var(--font-label);
    /* +15% bump on Section 09 La Direction member roles. */
    font-size: var(--text-sm);
    letter-spacing: var(--track-mono);
    text-transform: uppercase;
    color: var(--muted);
  }

  /* ─── DIRECTION : horizontal scroll-jack on desktop ─────────────────────
     Desktop (>= 900px) : vertical stack. The unified section header
     (.section-head__kicker / __title / __lede) sits at the top, then
     .direction__viewport occupies the full content width below. A pinned
     ScrollTrigger in main.js translates .direction__row from right to
     left across the pin distance, with three cards visible at any
     moment. Card width is sized in JS so exactly three fit within
     .direction__viewport (now ~1/3 viewport width minus gutters).

     Mobile (< 900px) : .direction__viewport stops clipping, and
     .direction__row reverts to the original .team-grid (2-up at
     640-900, 1-up below). The scroll-jack ScrollTrigger is gated to
     desktop via gsap.matchMedia.
     ──────────────────────────────────────────────────────────────────── */
  /* .direction__layout wraps the header and the portraits viewport so
     the section padding and inner max-width still apply uniformly. The
     wrapper is a flex column so the standard section-header rhythm
     (--section-header-gap-3 = 96px desktop, 64px mobile) is restored
     between the header and the portraits row. Without this gap the
     header's bottom would sit flush against the viewport (the parent
     .section__inner gap only applies between its direct children, and
     here the only direct child is .direction__layout itself). */
  .direction__layout{
    display: flex;
    flex-direction: column;
    gap: var(--section-header-gap-3);
  }
  .direction__viewport{ overflow: visible; }
  /* Mobile : restore the 2-up / 1-up grid that .team-grid provided. */
  @media (max-width: 899px){
    .direction__row.team-grid{
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 48px 24px;
    }
  }
  @media (max-width: 640px){
    .direction__row.team-grid{ grid-template-columns: 1fr; gap: 40px; }
  }

  @media (min-width: 900px){
    .direction .section__inner{ width: 100%; }

    /* Section 09 must fit each portrait card (portrait + name + role) as
       a bundled unit fully inside the pinned viewport. The default
       .section padding (clamp 140-220 top, 112-176 bottom) plus the 96
       px header-to-content gap consumes too much vertical budget at
       laptop heights (1140 px section on 900 px viewport, 240 px
       overshoot pushed names and roles below the fold). Trim padding
       and the layout gap on this one section, and cap the portrait
       height so portrait+name+role resolve inside any viewport >= 800.
       Math at 900vh: 99 padT + 169 header + 45 gap + 475 card + 99
       padB = 887. At 800vh: 88 + 169 + 40 + 375 + 88 = 760. */
    .direction{
      padding-top:    clamp(72px, 11vh, 120px);
      padding-bottom: clamp(72px, 11vh, 120px);
    }
    .direction .direction__layout{ gap: clamp(40px, 5vh, 64px); }

    /* Header sits above the viewport in the natural flow of
       .direction__layout. The .section-head:has(.section-head__kicker)
       rule already left-aligns the kicker / headline / lede with the
       standard typographic rhythm shared across home page sections. */
    .direction__copy{ width: 100%; }

    .direction__viewport{
      width: 100%;
      overflow: hidden;
      position: relative;
      /* Bleed the row into the right margin so the last card can exit
         cleanly past the viewport edge, matching the cinematic intent. */
      margin-right: calc(-1 * var(--margin));
    }
    /* Override the .team-grid CSS grid : the row is a single horizontal
       flex line on desktop. Each member sizes itself to its portrait
       (portrait width derives from clamped height x 4:5 aspect). */
    .direction__row.team-grid{
      display: flex;
      flex-direction: row;
      flex-wrap: nowrap;
      gap: 32px;
      width: max-content;
      will-change: transform;
    }
    /* Cards are visible from the start in horizontal mode (no per-member
       fade-in). The .member primitive's opacity/transform base is reset
       by gsap.set() in main.js so the row reads as a continuous strip. */
    .direction__row .member{
      margin: 0;
    }
    /* Cap portrait height so the full card (portrait + name + role)
       plus breathing room fits inside the user's actual usable
       viewport. Width derives from the 4:5 aspect ratio. The clamp
       subtrahend (460 px) reserves enough headroom for section padding
       + header + layout gap + the 15%-bumped text block below the
       portrait. Min 276 px / max 506 px is a 15% bump over the prior
       sizing to give the cards more presence. JS reads the resulting
       portrait width and sets .member flex-basis to keep the row
       continuous and the pin distance correct. */
    .direction__row .member__portrait{
      height: clamp(276px, calc(100vh - 460px), 506px);
      width: auto;
      margin-bottom: 16px;
    }
  }

  /* ════════════════════════════════════════════════════════════════════════
     SECTION 08 : CONTACT (dark warm brown)
     Closing portal scrubs from 1.0 to 0.88 as user scrolls out of the page.
     ════════════════════════════════════════════════════════════════════════ */
  /* Section 08 unified into the dark zone : brand maroon (#5C2E20)
     matches sections 06 expertise and 07 partenaires so the bottom
     third of the home page reads as one continuous dark brown surface.
     The previous --canvas-d (#282828 neutral near-black) registered as
     cool grey next to the warm brown above it. */
  .contact{
    background: var(--color-brand);
    color: var(--ink-d);
    position: relative;
    overflow: hidden;
    padding-bottom: clamp(48px, 6vh, 72px);
  }
  /* Filigree watermark : amber rings/paths at low opacity, reading as
     ambient warmth on the brown surface. Container opacity bumped from
     0.085 to 0.18 because the cool grey base used to suppress the
     amber; on the warmer brown a slightly higher value is needed for
     the filigree to register without competing with the form copy.
     Effective opacities (container * per-path) :
       paths  0.18 * 0.6 = 0.108  (10.8%)
       rings  0.18 * 0.7 = 0.126  (12.6%)
     Both within the user-specified 10-15% comfort band. */
  .contact__portal{
    position: absolute;
    left: 50%; top: 54%;
    transform: translate(-50%, -50%) scale(1);
    width: min(64vw, 820px);
    aspect-ratio: 975 / 955;
    pointer-events: none;
    z-index: 0;
    opacity: 0.18;
    transform-origin: center;
    will-change: transform, opacity;
  }
  .contact__portal svg{ width: 100%; height: 100%; overflow: visible; }
  .contact__portal path{ fill: var(--amber); fill-opacity: 0.6; }
  .contact__portal .ring{ fill: none; stroke: var(--amber); stroke-width: 0.6; stroke-opacity: 0.7; vector-effect: non-scaling-stroke; }

  .contact__grid{
    display: grid;
    grid-template-columns: 1.2fr 1fr;
    gap: 96px;
    align-items: start;
  }
  @media (max-width: 1023px){ .contact__grid{ grid-template-columns: 1fr; gap: 56px; } }

  .contact-form{
    display: flex;
    flex-direction: column;
    gap: 24px;
  }
  .contact-form__field{
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  .contact-form label{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono-wide);
    text-transform: uppercase;
    color: var(--ink-d-2);
  }
  .contact-form input,
  .contact-form textarea{
    width: 100%;
    padding: 16px 16px;
    background: rgba(245,240,234,0.04);
    border: 1px solid var(--hairline-d);
    border-radius: var(--radius-sm);
    color: var(--ink-d);
    font: 300 15px/1.5 var(--font-sans);
    transition: border-color 400ms var(--ease-viscous), background 400ms var(--ease-viscous);
  }
  .contact-form input:focus,
  .contact-form textarea:focus{
    outline: none;
    border-color: var(--amber);
    background: rgba(245,240,234,0.06);
  }
  .contact-form textarea{ min-height: 140px; resize: vertical; }
  /* Home Section 08 ENVOYER submit : layout-only override, visuals via
     .btn.btn--primary in markup. */
  .contact-form__submit{
    align-self: flex-start;
    margin-top: 12px;
  }

  .contact-coords{ font-family: var(--font-body); font-weight: var(--weight-light); }
  .contact-coords__title{
    font-family: var(--font-heading);
    font-weight: var(--weight-regular);
    font-size: clamp(var(--text-lg), 1.8vw, var(--text-xl));
    color: var(--ink-d);
    margin: 0 0 24px;
  }
  .contact-coords p{
    font-size: clamp(var(--text-sm), 1vw, var(--text-md));
    line-height: 1.95;
    color: var(--ink-d-2);
    margin: 0 0 20px;
  }
  .contact-coords a{
    color: var(--ink-d);
    border-bottom: 1px solid var(--hairline-d);
    padding-bottom: 1px;
    transition: border-color 400ms var(--ease-viscous);
  }
  .contact-coords a:hover{ border-color: var(--amber); }

  .contact__footer{
    margin-top: clamp(80px, 10vh, 120px);
    padding-top: 32px;
    border-top: 1px solid var(--hairline-d);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono-wide);
    text-transform: uppercase;
    color: var(--ink-d-2);
  }
  .contact__footer-links{ display: flex; gap: 28px; }
  .contact__footer-links a{ transition: color 400ms var(--ease-viscous); }
  .contact__footer-links a:hover{ color: var(--amber); }
  .contact__footer-lang button{ color: var(--ink-d-2); letter-spacing: var(--track-mono-wide); font-family: var(--font-label); font-size: var(--text-xs); }
  .contact__footer-lang button.is-active{ color: var(--amber); }
  .contact__footer-lang .sep{ color: rgba(245,240,234,0.28); padding: 0 8px; }

  /* ─── Reduced motion ─────────────────────────────────────────────────────── */
  @media (prefers-reduced-motion: reduce){
    *, *::before, *::after{
      animation-duration: 0.001ms !important;
      transition-duration: 0.001ms !important;
    }
    #flux-canvas{ display: none; }
    .hero{ background: radial-gradient(1200px 800px at 30% 30%, rgba(168,119,31,0.14), rgba(26,12,6,0) 60%), var(--canvas-d); }
    /* Reveal everything statically when reduce-motion is requested */
    .label, .label--light, .label--teal, .label--dark-section,
    .section-counter,
    .section-head__kicker, .section-head__lede,
    .plateforme__copy p, .plateforme__image, .plateforme__caption,
    .headline--light .line > span,
    .headline .line > span,
    .entity, .capability, .story, .member,
    .entity-card, .entity-card-img,
    .fade-up{
      opacity: 1 !important;
      transform: none !important;
    }
  }

  /* ════════════════════════════════════════════════════════════════════════
     SHARED NAV : active link state
     Added for the 5-page architecture. The 4 anchor items behave as links
     and use the shared underline. The Parlons CTA has its own amber chrome
     (defined further below).
     ════════════════════════════════════════════════════════════════════════ */
  .nav__brand{ color: inherit; text-decoration: none; }
  .nav__links li{ list-style: none; display: inline-flex; align-items: center; }
  .nav__links a.active{ color: var(--ink-d); opacity: 1; }
  .nav__links a.active::after{ width: 100%; height: 2px; background: var(--amber); }
  .nav.nav--on-light .nav__pill .nav__links a.active{ color: var(--color-dark); }

  /* ════════════════════════════════════════════════════════════════════════
     PAGE HERO : same framed-card envelope as the entity sub-pages.
     Outer .page-hero paints the cream gutter on all four sides; the brown
     card with rounded corners lives in the .page-hero__card child. The
     existing typography stack (label + headline + subheading) sits inside
     .page-hero__inner within the card.
     ════════════════════════════════════════════════════════════════════════ */
  .page-hero{
    position: relative;
    background: var(--canvas-warm);
    color: var(--ink-d);
    padding: 12px;
    display: flex;
    align-items: stretch;
    isolation: isolate;
  }
  .page-hero__card{
    position: relative;
    flex: 1;
    background: var(--canvas-d);
    color: var(--ink-d);
    border-radius: 18px;
    overflow: hidden;
    min-height: clamp(620px, 86vh, 860px);
    padding: clamp(80px, 12vh, 140px) clamp(40px, 5vw, 80px);
    isolation: isolate;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .page-hero__inner{
    position: relative;
    z-index: 2;
    max-width: var(--maxw);
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: clamp(56px, 8vh, 104px);
  }
  @media (max-width: 1023px){
    .page-hero__card{
      padding: clamp(120px, 14vh, 160px) clamp(32px, 5vw, 64px) clamp(64px, 10vh, 100px);
      min-height: 0;
      justify-content: flex-start;
    }
  }
  @media (max-width: 767px){
    .page-hero{ padding: var(--hero-gutter-mobile); }
    .page-hero__card{
      padding: 120px 24px 64px;
      border-radius: 14px;
    }
  }
  .page-hero .label{
    position: static;
    top: auto; left: auto;
    opacity: 1;
  }
  /* Hide the amber square bullet inside hero kickers. The .label__bullet
     primitive remains intact for other contexts on the site ; this scope
     suppresses it only inside .page-hero so the kicker reads as plain text
     starting with the section number. */
  .page-hero .label__bullet{ display: none; }
  /* Terminal period in hero headlines. Mulish renders the period as a
     near-square block at hero scale ; switching just the terminal glyph to
     a serif font yields a clean round dot. Color inherits from the
     headline so the period reads as punctuation, not as an amber accent.
     Applied to <span class="title-period"> markup wrapping the final
     period inside .headline / .entity-hero__headline. */
  .title-period{
    font-family: "Instrument Serif", serif;
    font-style: italic;
    color: inherit;
  }
  .page-hero .headline{
    color: var(--ink-d);
    max-width: 18ch;
    font-size: clamp(var(--text-2xl), 6vw, var(--text-4xl));
    line-height: 1.02;
    letter-spacing: var(--track-tight-lg);
  }
  .page-hero__subheading{
    font-family: var(--font-body);
    font-weight: var(--weight-light);
    font-size: clamp(var(--text-md), 1.2vw, var(--text-lg));
    line-height: var(--leading-relaxed);
    color: var(--ink-d-2);
    max-width: 56ch;
    margin: 0;
  }
  /* Hero silhouette : decorative photographic plate anchored to the
     bottom-right corner of the maroon hero card. max-width / max-height
     both 100% so the image scales proportionally to fit fully inside the
     card regardless of its native aspect ratio (panoramic images stay
     uncropped, taller images still fill the full card height). Sits
     BEHIND the kicker + headline + subtitle (z-index 0). */
  .page-hero__silhouette,
  .entity-hero__silhouette{
    position: absolute;
    bottom: 0;
    right: 0;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    opacity: 0.15;
    pointer-events: none;
    z-index: 0;
  }

  /* Services page only : scale the silhouette to 95% of the card (down 5%
     from full). Scoped via attribute selector on the image src so we don't
     need a body-level page class. Keeps the bottom-right anchor; both width
     and height caps drop proportionally so the panoramic still fits. */
  .page-hero__silhouette[src*="services-hero-image"]{
    max-width: 95%;
    max-height: 95%;
  }

  /* Page body : light cream surface between the dark page-hero and the
     dark closing moment. Gives non-home pages the same dark-light-dark
     brochure rhythm as the home. Placeholder copy sits on rust-brown at
     40% opacity until real content lands. */
  .page-placeholder{
    background: #f5f0ea;
    color: var(--color-dark);
    padding: 160px var(--margin);
    text-align: center;
  }
  @media (max-width: 767px){
    .page-placeholder{ padding: 96px var(--margin); }
  }
  .page-placeholder__inner{
    font-family: var(--font-body);
    font-weight: var(--weight-light);
    font-size: var(--text-xl);
    letter-spacing: var(--track-wide-sm);
    color: rgb(from var(--color-dark) r g b / 0.4);
  }

  /* ════════════════════════════════════════════════════════════════════════
     CLOSING MOMENT : dark bookend for non-home pages. Echoes the home
     Section 08 Parlons feel without duplicating the form. The CTA opens
     the shared drawer. A .closing__footer block sits at the bottom of this
     same section so the filigree watermark and the dark warm-brown surface
     run uninterrupted from the closing statement through the legal row.
     ════════════════════════════════════════════════════════════════════════ */
  .closing{
    position: relative;
    background: var(--canvas-d);
    color: var(--ink-d);
    min-height: 80vh;
    padding: 120px;
    overflow: hidden;
    isolation: isolate;
    display: grid;
    grid-template-rows: 1fr auto;
    row-gap: 48px;
  }
  @media (max-width: 1023px){ .closing{ padding: 96px 64px; } }
  @media (max-width: 640px){  .closing{ padding: 96px 40px; min-height: 70vh; } }

  /* Matches home Section 08 .contact__portal : centered filigree portal
     watermark, opacity 0.085, amber paths at 60% fill-opacity, amber rings
     at 70% stroke-opacity. The extra 55vh cap in the width formula keeps the
     portal fully inside this shorter closing section (60vh min-height) so it
     never clips at the viewport edges, matching home Section 08 containment. */
  .closing__portal{
    position: absolute;
    left: 50%; top: 54%;
    transform: translate(-50%, -50%) scale(1);
    width: min(64vw, 820px, 55vh);
    aspect-ratio: 975 / 955;
    pointer-events: none;
    z-index: 0;
    opacity: 0.085;
  }
  .closing__portal svg{ width: 100%; height: 100%; overflow: visible; }
  .closing__portal path{ fill: var(--amber); fill-opacity: 0.6; }
  .closing__portal .ring{ fill: none; stroke: var(--amber); stroke-width: 0.6; stroke-opacity: 0.7; vector-effect: non-scaling-stroke; }

  /* Left-anchored editorial layout matching home Section 08 .section__inner
     (max-width: var(--maxw), flush left). The closing label, statement, and
     CTA sit on the same left baseline as the headlines elsewhere on the site
     instead of being centered, keeping the interior pages in the same
     typographic family as the home page. */
  .closing__inner{
    position: relative;
    z-index: 1;
    max-width: var(--maxw);
    width: 100%;
    justify-self: center;
    align-self: center;
    text-align: left;
  }
  .closing__label{
    display: inline-flex;
    align-items: center;
    gap: 12px;
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono);
    text-transform: uppercase;
    color: var(--amber);
  }
  .closing__label .closing__label-bullet{
    display: inline-block;
    width: 8px; height: 8px;
    background: var(--amber);
  }
  .closing__statement{
    font-family: var(--font-display);
    font-weight: var(--weight-light);
    font-size: var(--text-4xl);
    line-height: var(--leading-display);
    letter-spacing: var(--track-tight-lg);
    color: var(--ink-d);
    /* Cap the headline to the left editorial column so the two stacked
       lines ("Une plateforme." / "Un partenaire.") stay flush left and
       the filigree portal on the right reads cleanly beside them instead
       of underneath the glyphs. */
    max-width: 780px;
    margin: 32px 0 0;
    opacity: 0;
    transform: translateY(40px);
    will-change: transform, opacity;
  }
  @media (max-width: 640px){ .closing__statement{ font-size: var(--text-3xl); } }
  .closing__statement em{
    font-style: italic;
    font-family: var(--font-body);
    font-weight: var(--weight-semibold);
    color: var(--amber);
  }
  /* Interior-page closing moment PARLONS : layout + intro-reveal hooks +
     hero-style wipe hover. Visuals come from .btn.btn--secondary.btn--on-dark
     in the markup; this block adds a left-to-right amber wipe, text inversion,
     arrow-square darkening + rotation, and border fade. Scoped to .closing__cta
     so other secondary-on-dark buttons keep their default hover. */
  .closing__cta{
    position: relative;
    overflow: hidden;
    margin-top: 60px;
    opacity: 0;
    transform: translateY(20px) scale(0.96);
    transition:
      border-color 910ms cubic-bezier(0.22, 1, 0.36, 1),
      opacity 600ms var(--ease-out-expo),
      transform 600ms var(--ease-out-expo);
  }
  .closing__cta::before{
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: var(--amber);
    transform: translateX(-101%);
    transition: transform 910ms cubic-bezier(0.22, 1, 0.36, 1);
    z-index: 1;
    pointer-events: none;
    border-radius: inherit;
  }
  .closing__cta .btn__text,
  .closing__cta .btn__arrow-square{
    position: relative;
    z-index: 2;
  }
  .closing__cta .btn__text{
    transition: color 910ms 260ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .closing__cta .btn__arrow-square{
    transition:
      background 910ms 260ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 910ms 260ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  @media (hover: hover){
    .closing__cta.btn--secondary.btn--on-dark:hover{
      /* Kill the default cream-wash + cream-border secondary hover. */
      background: transparent;
      border-color: transparent;
    }
    .closing__cta:hover::before{
      transform: translateX(0);
    }
    .closing__cta:hover .btn__text{
      color: var(--canvas-d);
    }
    /* Arrow-square hover treatment inherited from the unified
       .btn--primary:hover / .btn--secondary:hover rule. */
  }
  .closing__cta:active::before{
    transform: translateX(0);
    transition-duration: 200ms;
  }

  /* Integrated footer block sitting at the bottom of .closing on non-home
     pages. Mirrors the .site-footer layout the home page uses as a separate
     strip, but lives inside the dark closing section here so the filigree
     watermark and the canvas-d surface run uninterrupted from the Parlons
     CTA through the legal row. Home keeps its external .site-footer. */
  .closing__footer{
    position: relative;
    z-index: 1;
    max-width: var(--maxw);
    width: 100%;
    margin: 0 auto;
    padding-top: 40px;
    border-top: 1px solid rgba(245, 240, 234, 0.15);
  }
  .closing__footer-inner{
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: start;
    gap: 48px;
  }
  @media (max-width: 900px){
    .closing__footer-inner{ grid-template-columns: 1fr; gap: 32px; }
  }

  .closing__footer-col--brand{ display: flex; flex-direction: column; gap: 8px; }
  .closing__footer-wordmark{
    font-family: var(--font-heading);
    font-weight: var(--weight-regular);
    font-size: var(--text-sm);
    color: var(--ink-d);
  }
  .closing__footer-tag{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono);
    text-transform: uppercase;
    color: rgba(200, 146, 42, 0.8);
  }

  .closing__footer-col--links{
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    justify-self: center;
  }
  .closing__footer-col--links a{
    font-family: var(--font-body);
    font-weight: var(--weight-light);
    font-size: var(--text-sm);
    color: rgba(245, 240, 234, 0.65);
    transition: color 910ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .closing__footer-col--links a:hover{ color: var(--amber); }
  .closing__footer-dot{ color: rgba(245, 240, 234, 0.35); font-size: var(--text-sm); }

  .closing__footer-col--locus{
    justify-self: end;
    display: flex;
    flex-direction: column;
    gap: 8px;
    text-align: right;
    font-family: var(--font-label);
    font-size: var(--text-xs);
    color: rgba(245, 240, 234, 0.65);
  }
  @media (max-width: 900px){ .closing__footer-col--locus{ justify-self: start; text-align: left; } }
  .closing__footer-mail{
    color: rgba(245, 240, 234, 0.65);
    transition: color 910ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .closing__footer-mail:hover{ color: var(--amber); }

  .closing__footer-row{
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    margin-top: 40px;
    padding-top: 24px;
    border-top: 1px solid rgba(245, 240, 234, 0.06);
    font-family: var(--font-label);
    font-size: var(--text-xs);
    color: rgba(245, 240, 234, 0.45);
  }
  @media (max-width: 640px){
    .closing__footer-row{ flex-direction: column; align-items: flex-start; gap: 12px; }
  }
  .closing__footer-credit{
    color: rgba(245, 240, 234, 0.45);
    transition: color 240ms ease;
  }
  .closing__footer-credit:hover{ color: var(--ink-d); }

  /* ════════════════════════════════════════════════════════════════════════
     BOTTOM ROW FOOTER : thin essentials strip below every page.
     ════════════════════════════════════════════════════════════════════════ */
  /* Surface uses the same brand-brown as the section above (Contact /
     pinned dark surfaces) so the dark-surface system reads as one
     continuous tone. Distinction from the previous section is signalled
     structurally : generous top padding plus the existing cream hairline
     at the top edge. The earlier one-off near-black created an
     unintended seam where two browns met. */
  .site-footer{
    background: var(--color-brand);
    color: var(--ink-d);
    border-top: 1px solid rgba(245, 240, 234, 0.08);
    padding: 104px 120px 48px;
  }
  @media (max-width: 1023px){ .site-footer{ padding: 80px 40px 48px; } }
  @media (max-width: 640px){  .site-footer{ padding: 64px 32px 40px; } }

  .site-footer__inner{
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: start;
    gap: 48px;
    max-width: var(--maxw);
    margin: 0 auto;
  }
  @media (max-width: 900px){
    .site-footer__inner{ grid-template-columns: 1fr; gap: 32px; }
  }

  .site-footer__col--brand{ display: flex; flex-direction: column; gap: 8px; }
  .site-footer__wordmark{
    font-family: var(--font-heading);
    font-weight: var(--weight-regular);
    font-size: var(--text-sm);
    color: var(--ink-d);
  }
  .site-footer__tag{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono);
    text-transform: uppercase;
    color: rgba(200, 146, 42, 0.8);
  }

  .site-footer__col--links{
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    justify-self: center;
  }
  .site-footer__col--links a,
  .site-footer__contact{
    font-family: var(--font-body);
    font-weight: var(--weight-light);
    font-size: var(--text-sm);
    color: rgba(245, 240, 234, 0.65);
    background: transparent;
    border: 0;
    padding: 0;
    cursor: pointer;
    transition: color 910ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .site-footer__col--links a:hover,
  .site-footer__contact:hover{ color: var(--amber); }
  .site-footer__dot{ color: rgba(245, 240, 234, 0.35); font-size: var(--text-sm); }

  .site-footer__col--locus{
    justify-self: end;
    display: flex;
    flex-direction: column;
    gap: 8px;
    text-align: right;
    font-family: var(--font-label);
    font-size: var(--text-xs);
    color: rgba(245, 240, 234, 0.65);
  }
  @media (max-width: 900px){ .site-footer__col--locus{ justify-self: start; text-align: left; } }
  .site-footer__mail{
    color: rgba(245, 240, 234, 0.65);
    transition: color 910ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .site-footer__mail:hover{ color: var(--amber); }

  .site-footer__row{
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    max-width: var(--maxw);
    margin: 40px auto 0;
    padding-top: 24px;
    border-top: 1px solid rgba(245, 240, 234, 0.06);
    font-family: var(--font-label);
    font-size: var(--text-xs);
    color: rgba(245, 240, 234, 0.45);
  }
  @media (max-width: 640px){
    .site-footer__row{ flex-direction: column; align-items: flex-start; gap: 12px; }
  }
  .site-footer__credit{
    color: rgba(245, 240, 234, 0.45);
    transition: color 240ms ease;
  }
  .site-footer__credit:hover{ color: var(--ink-d); }

  /* ════════════════════════════════════════════════════════════════════════
     CONTACT DRAWER : right-side slide-in used on every page.
     ════════════════════════════════════════════════════════════════════════ */
  .drawer-backdrop{
    position: fixed;
    inset: 0;
    background: rgba(26, 12, 6, 0.7);
    opacity: 0;
    pointer-events: none;
    transition: opacity 400ms ease-out;
    z-index: 990;
  }
  .drawer-backdrop.is-open{ opacity: 1; pointer-events: auto; }

  .drawer{
    position: fixed;
    top: 0;
    right: 0;
    width: 45vw;
    height: 100vh;
    background: var(--canvas-d);
    color: var(--ink-d);
    border-radius: 18px 0 0 18px;
    padding: 96px 80px;
    transform: translateX(100%);
    transition: transform 600ms var(--ease-out-expo);
    z-index: 1000;
    overflow-y: auto;
    overscroll-behavior: contain;
    box-shadow: -40px 0 80px -40px rgba(0, 0, 0, 0.55);
  }
  @media (max-width: 900px){ .drawer{ width: 90vw; padding: 64px 48px; } }
  .drawer.is-open{ transform: translateX(0); }
  .drawer[aria-hidden="true"]{ visibility: hidden; }
  .drawer.is-open[aria-hidden="false"],
  .drawer.is-open{ visibility: visible; }

  /* Drawer close X : layout + hover override. Visuals via .btn.btn--tertiary
     .btn--on-dark in the markup, but the generic tertiary hover (cream wash +
     rotate svg) is replaced here with a simple color transition cream → amber,
     910ms. No chrome, no rotation, no fill per the rollout spec. */
  .drawer__close{
    position: absolute;
    top: 24px;
    right: 24px;
    transition: color 910ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .drawer__close svg{
    transition: color 910ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  @media (hover: hover){
    .drawer__close.btn--tertiary.btn--on-dark:hover{
      /* Neutralise the generic tertiary hover wash + border brighten. */
      background: transparent;
      border-color: rgba(245, 240, 234, 0.3);
      color: var(--amber);
    }
    .drawer__close.btn--tertiary:hover svg{
      /* Cancel the -45° SVG rotation inherited from .btn--tertiary:hover svg. */
      transform: none;
      color: var(--amber);
    }
  }

  .drawer__inner{ display: flex; flex-direction: column; gap: 32px; }

  .drawer__label{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--amber);
    opacity: 0;
    transform: translateY(12px);
  }
  .drawer__headline{
    font-family: var(--font-heading);
    font-weight: var(--weight-light);
    font-size: clamp(var(--text-3xl), 6vw, var(--text-4xl));
    line-height: 1.02;
    letter-spacing: var(--track-tight-lg);
    color: var(--ink-d);
    margin: 0;
    opacity: 0;
    transform: translateY(20px);
  }

  .drawer__form{ display: flex; flex-direction: column; gap: 20px; }
  .drawer__field{
    display: flex; flex-direction: column; gap: 8px;
    opacity: 0;
    transform: translateY(16px);
  }
  .drawer__field-label{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono-wide);
    text-transform: uppercase;
    color: rgba(245, 240, 234, 0.55);
  }
  .drawer__field input,
  .drawer__field textarea{
    font-family: var(--font-body);
    font-weight: var(--weight-light);
    font-size: var(--text-md);
    color: var(--ink-d);
    background: transparent;
    border: 0;
    border-bottom: 1px solid rgba(245, 240, 234, 0.18);
    padding: 12px 0;
    outline: none;
    transition: border-color 240ms ease;
    resize: vertical;
  }
  .drawer__field input:focus,
  .drawer__field textarea:focus{ border-color: var(--amber); }

  /* Drawer ENVOYER submit : layout + intro-reveal hooks only. Visuals come
     from .btn.btn--primary in the markup. */
  .drawer__submit{
    align-self: flex-start;
    margin-top: 16px;
    opacity: 0;
    transform: translateY(16px);
  }

  .drawer__coords{
    display: flex; flex-direction: column; gap: 8px;
    padding-top: 28px;
    border-top: 1px solid rgba(245, 240, 234, 0.08);
    opacity: 0;
    transform: translateY(12px);
  }
  .drawer__coords-name{
    font-family: var(--font-heading);
    font-weight: var(--weight-regular);
    font-size: var(--text-sm);
    color: var(--ink-d);
  }
  .drawer__coords-line,
  .drawer__coords-link{
    font-family: var(--font-label);
    font-size: var(--text-xs);
    color: rgba(245, 240, 234, 0.7);
    letter-spacing: var(--track-wide-sm);
  }
  .drawer__coords-link{ transition: color 240ms ease; }
  .drawer__coords-link:hover{ color: var(--amber); }

  body.drawer-open{ overflow: hidden; }

  @media (prefers-reduced-motion: reduce){
    .drawer,
    .drawer-backdrop,
    .closing__statement,
    .closing__cta,
    .drawer__label,
    .drawer__headline,
    .drawer__field,
    .drawer__submit,
    .drawer__coords{
      transition-duration: 0.001ms !important;
    }
    .closing__statement,
    .closing__cta,
    .drawer__label,
    .drawer__headline,
    .drawer__field,
    .drawer__submit,
    .drawer__coords{ opacity: 1 !important; transform: none !important; }
  }

/* ══════════════════════════════════════════════════════════════════════════
   À PROPOS · Sections 02-07 additions
   Scoped to interior page ids so home primitives remain untouched.
   ══════════════════════════════════════════════════════════════════════════ */

/* À PROPOS · valeurs 3-over-2 centred stagger layout.
   6-column base grid: every card spans 2 columns. Top row fills cols 1-6
   (three cards at 1-2, 3-4, 5-6). Bottom row stays two cards, staggered
   into cols 2-3 and 4-5 so they visually centre under the top row and sit
   between the top cards' boundaries. */
.values-grid{
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  border-top: 1px solid var(--hairline-soft);
}
.values-grid .capability{
  grid-column: span 2;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding: 52px 40px !important;
  border-right: 1px solid var(--hairline-soft);
  border-bottom: 1px solid var(--hairline-soft);
  border-radius: 10px;
  transition: background-color 700ms cubic-bezier(0.16, 1, 0.3, 1),
              border-radius 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
.values-grid .capability:nth-child(3){ border-right: none; }
.values-grid .capability:nth-child(4){ grid-column: 2 / span 2; }
.values-grid .capability:nth-child(5){ grid-column: 4 / span 2; border-right: none; }
.values-grid .capability__rule{ left: 40px; }

.values-grid .capability__icon,
.values-grid .capability__title,
.values-grid .capability__desc{
  transition: color 700ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* À PROPOS · valeurs default text colors on the cream surface. Overrides
   the global .capability rules (which target the home Expertise dark
   surface) so the title and descriptions read in ink, not cream-on-cream. */
.values-grid .capability__title{ color: var(--ink); }
.values-grid .capability__desc{ color: color-mix(in srgb, var(--ink) 75%, transparent); }

/* À PROPOS · valeurs expanded description.
   All card content is visible by default. The longer description sits
   12px below the short description and inherits the cream surface ink
   color. Hover only inverts the color for contrast on the brown fill. */
.values-grid .capability__desc--more{
  margin: 12px 0 0 0;
  transition: color 700ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* À PROPOS · valeurs hover treatment (pointer-capable devices only so
   mobile taps do not trigger a sticky hover state). Radius lifts from
   10px (locked default for medium cards) to 14px (locked featured-state
   value) to signal the card promoting itself on focus. */
@media (hover: hover){
  .values-grid .capability:hover{
    background-color: var(--color-brand);
    border-radius: 14px;
  }
  .values-grid .capability:hover .capability__icon{ color: var(--color-accent-orange); }
  .values-grid .capability:hover .capability__title{ color: var(--color-accent-orange); }
  .values-grid .capability:hover .capability__desc{ color: rgba(245, 240, 234, 0.85); }
  .values-grid .capability:hover .capability__desc--more{ color: rgba(245, 240, 234, 0.85); }
  .values-grid .capability:hover .capability__rule{
    background-color: rgba(245, 240, 234, 0.24);
  }
}
/* À PROPOS · valeurs touch feedback for non-pointer (mobile) devices. */
@media (hover: none){
  .values-grid .capability:active{ background-color: rgba(26, 12, 6, 0.05); }
}

@media (max-width: 1023px){
  .values-grid{ grid-template-columns: 1fr; border-top: none; }
  .values-grid .capability,
  .values-grid .capability:nth-child(4),
  .values-grid .capability:nth-child(5){
    grid-column: 1;
    padding: 40px 0 !important;
    border-right: none !important;
  }
  .values-grid .capability__rule{ left: 0; }
}

/* À PROPOS · new for Lucide icon slot on .capability */
.capability__icon{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(32px, 2.4vw, 40px);
  height: clamp(32px, 2.4vw, 40px);
  color: var(--color-dark);
  margin-bottom: 24px;
}
.capability__icon svg{ width: 100%; height: 100%; }

/* À PROPOS · new for stories 3-up layout on Engagement */
.stories--triple{ grid-template-columns: repeat(3, 1fr); gap: 48px; }
@media (max-width: 1023px){
  .stories--triple{ grid-template-columns: 1fr; gap: 56px; }
}

/* À PROPOS · reveal prestate resets (main.js reveal hooks are home-scoped,
   so interior-page elements that reuse home primitives would stay invisible
   without an explicit visible state). */
#origine .label--light, #origine .section-counter,
#vision .label--light, #vision .section-counter,
#valeurs .label--light, #valeurs .section-counter, #valeurs .capability,
#presence .label--light, #presence .section-counter, #presence .stat,
#leadership .label--light, #leadership .section-counter, #leadership .member,
#engagement .label--light, #engagement .section-counter, #engagement .story{
  opacity: 1;
  transform: none;
}

/* À PROPOS · Engagement story body width (cream surface, no colour override
   needed; .story__title and .story__body inherit default ink-on-cream). */
#engagement .story__body{ max-width: 42ch; }

/* À PROPOS · Leadership bio paragraph (short, quiet, editorial) */
#leadership .member p{
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-sm), 1vw, var(--text-md));
  line-height: 1.7;
  color: var(--ink-2);
  margin: 12px 0 0;
  max-width: 42ch;
}

/* À PROPOS · warm cream surface namespace.
   One continuous warm paper for all non-Vision content sections, so the
   page reads as a single editorial canvas with Vision as the only focal
   colour break. Cascade-wins over .direction/.expertise/.influence/
   .partenaires modifiers (same specificity, defined later). */
.ap-cream{
  background: #f5f0ea;
  color: var(--ink);
}

/* À PROPOS · Vision focal anchor.
   Full-bleed video hero on deep teal. Section breaks out of any container
   via 100vw + negative margin trick. The 12px section padding draws a
   thin deep-teal frame around the rounded media wrapper. Inside the
   wrapper, video sits behind a 45% deep-teal overlay for text contrast;
   content stacks above on z-index 2. */
.ap-vision{
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  min-height: 100vh;
  overflow: hidden;
  background: #f5f0ea;
  display: flex;
  align-items: stretch;
  padding: 12px;
  isolation: isolate;
}
/* À PROPOS · Vision media wrapper.
   Hero-tier 18px radius with overflow:hidden clips the video, the overlay
   and the centred content into a single rounded card sitting inside the
   12px teal gutter. Flex centring keeps the headline + body vertically
   aligned within the card. */
.ap-vision__media-wrapper{
  position: relative;
  flex: 1;
  border-radius: 18px;
  overflow: hidden;
  isolation: isolate;
  background: #0a4a5e;
  display: flex;
  align-items: center;
}
.ap-vision__video{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
  pointer-events: none;
}
/* À PROPOS · Vision overlay. Flat dark-teal wash at 45% opacity; uniform
   coverage protects readability across the full frame without competing
   with the ship for visual weight. */
.ap-vision__overlay{
  position: absolute;
  inset: 0;
  background: rgba(10, 74, 94, 0.45);
  z-index: 1;
  pointer-events: none;
}
.ap-vision__content{
  position: relative;
  z-index: 2;
  width: 100%;
}

/* Cream-on-deep-teal text treatment for Vision content. Scoped to
   .ap-vision so .label--light, .section-counter--light, and .headline
   primitives can be reused without page-wide impact. */
.ap-vision .label--light{ color: rgba(245, 240, 234, 0.85); }
.ap-vision .label__bullet{ background: var(--amber); }
.ap-vision .label__divider{ background: rgba(245, 240, 234, 0.3); }
.ap-vision .section-counter--light{ color: rgba(245, 240, 234, 0.85); }
.ap-vision .headline{ color: #f5f0ea; }
.ap-vision .headline em{ color: var(--color-accent-orange); }
.ap-vision__body{
  color: rgba(245, 240, 234, 0.8);
  max-width: 640px;
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-md), 1.3vw, var(--text-lg));
  line-height: 1.7;
  margin: 0;
}

@media (prefers-reduced-motion: reduce){
  .ap-vision__video{ display: none; }
}
@media (max-width: 767px){
  .ap-vision{ min-height: 80vh; }
}

/* ========================================
   === SERVICES PAGE ===
   All Services-only rules. Namespaced under .sv-* to keep the page
   isolated from home and À propos. Surface paint via .sv-cream so the
   page reads as one continuous warm paper from Intégration through
   Conseil. Cards use the .sv-service-card primitive (fresh, modeled on
   the home .entity-card vocabulary). All four cards use the same panel-
   left / image-right layout so the toggle bar above can anchor over the
   panel column at every state.
   ======================================== */

/* SERVICES · warm cream surface namespace.
   One continuous warm paper for all five content sections, identical
   paint to .ap-cream but Services-namespaced so cascade ownership is
   explicit. Cascade-wins over any later-defined surface modifier at
   equal specificity. */
.sv-cream{
  background: #f5f0ea;
  color: var(--ink);
}

/* SERVICES · Intégration positioning block.
   Two editorial paragraphs, left-aligned, max ~72 characters. Restraint
   over density. Quietly sets up the four service deep-dives that
   follow. */
.sv-integration-block{
  display: flex;
  flex-direction: column;
  gap: 24px;
  max-width: 72ch;
}
.sv-integration-para{
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-md), 1.2vw, var(--text-lg));
  line-height: var(--leading-loose);
  color: var(--ink);
  margin: 0;
}

/* SERVICES · Service split card.
   Stacked split card primitive. 42/58 panel/image grid, hero-tier 18px
   radius, dark warm brown panel against the warm cream surface, 700ms
   hover. All four service cards share this single layout so the toggle
   bar above always sits over the same panel column.

   Modeled on the home .entity-card vocabulary (520px desktop, 420px
   tablet, stacks at 767px) so the Services cards read as a sibling of
   the home Écosystème stack without overloading that primitive. */
.sv-service-card{
  display: grid;
  grid-template-columns: 42fr 58fr;
  column-gap: clamp(40px, 4vw, 64px);
  align-items: center;
  color: var(--ink);
}
@media (hover: hover){
  .sv-service-card:hover .sv-service-card__media img{
    transform: scale(1.018);
  }
}

@media (max-width: 767px){
  .sv-service-card{
    grid-template-columns: 1fr;
    grid-template-rows: 280px auto;
    column-gap: 0;
  }
  /* Mobile: image always on top, panel always below. Editorial rhythm
     gives way to vertical scan. */
  .sv-service-card__panel{ order: 2; }
  .sv-service-card__media{ order: 1; }
}

.sv-service-card__panel{
  position: relative;
  padding: 0;
  display: flex;
  flex-direction: column;
  color: var(--ink);
}
@media (max-width: 767px){
  .sv-service-card__panel{ padding: 28px 0 0; }
}

/* Kicker : reuses canonical .section-head__kicker rule (DM Mono xs,
   60% dark, amber num via .section-head__num). Per-card override forces
   opacity:1 since the main.js reveal hook only fires on .section-head
   ancestors. White-space allowed to wrap on narrow viewports as a
   safety net; site canon nowraps but service panels are narrower. */
.sv-service-card__panel .section-head__kicker{
  opacity: 1;
  white-space: normal;
  margin: 0 0 var(--section-header-gap-1) 0;
}

/* Vertical rhythm inside the panel (matches site canon):
     kicker → 8px → name → 8px → desc → 24px → meta. */
.sv-service-card__name{
  font-family: var(--font-heading);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-xl), 3vw, var(--text-2xl));
  letter-spacing: var(--track-tight-md);
  line-height: 1.08;
  margin: 0 0 var(--section-header-gap-2);
  color: var(--ink);
  max-width: 14ch;
}
.sv-service-card__desc{
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: var(--text-md);
  line-height: var(--leading-relaxed);
  color: var(--ink-2);
  margin: 0 0 24px;
  max-width: 44ch;
}
.sv-service-card__meta{
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0;
}

.sv-service-card__media{
  position: relative;
  overflow: hidden;
  background: var(--canvas-d-2);
  border-radius: var(--radius-xl);
  aspect-ratio: 16 / 10;
}
@media (max-width: 767px){
  .sv-service-card__media{ aspect-ratio: auto; }
}
.sv-service-card__media img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  transition: transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}

/* SERVICES · Conseil placeholder visual.
   Same editorial intent as À propos Engagement Gingembre Littéraire.
   Warm radial + linear gradient on dark warm brown, mono caption
   centered. Reads as restraint, never as a missing image. */
.sv-service-card__media--placeholder{
  display: grid;
  place-items: center;
  padding: 32px;
  text-align: center;
  background:
    radial-gradient(460px 320px at 40% 30%, rgba(200, 146, 42, 0.18) 0%, rgba(200, 146, 42, 0) 60%),
    linear-gradient(135deg, #5a1d0e 0%, #3d1208 55%, #1a0c06 100%);
}
.sv-service-card__placeholder{
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(245, 240, 234, 0.78);
  line-height: 2;
}
.sv-service-card__placeholder small{
  display: block;
  color: rgba(245, 240, 234, 0.48);
  letter-spacing: var(--track-mono-wide);
  font-size: var(--text-xs);
  margin-top: 16px;
}

/* SERVICES · reveal pre-state resets.
   main.js reveal hooks are home-scoped, so .label--light (opacity:0 by
   default) and .section-counter (opacity:0 by default) would stay
   invisible on Services without an explicit visible state. Mirrors the
   À propos pattern at #origine / #vision / etc. */
#integration .label--light, #integration .section-counter,
#metiers .label--light, #metiers .section-counter,
#difference .label--light, #difference .section-counter,
#partenaires .label--light, #partenaires .section-counter,
#faq .label--light, #faq .section-counter{
  opacity: 1;
  transform: none;
}

/* ────────────────────────────────────────────────────────────────────
   SERVICES · token additions (scoped to the Services block).
   --canvas-lifted is the warm cream lifted surface used for difference
   cards and partner cards (one notch above the page surface so cards
   read as cards without breaking the warm-paper continuity).
   ──────────────────────────────────────────────────────────────────── */
.sv-cream{
  --canvas-lifted: #faf6f1;
}

/* SERVICES · shared lede paragraph for the difference, partenaires
   sections. Same body weight as integration paragraphs so the page
   reads as one continuous editorial voice. */
.sv-lede{
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-md), 1.2vw, var(--text-lg));
  line-height: var(--leading-loose);
  color: var(--ink);
  max-width: 68ch;
  margin: 0;
}

/* ════════════════════════════════════════════════════════════════════
   SERVICES · MÉTIERS STACK
   Four .sv-service-card siblings stacked vertically with alternating
   panel/media orientation. Even cards take .sv-service-card--reverse
   to flip the grid orientation (media on the left at 58fr, panel on
   the right at 42fr). Mobile keeps the default image-on-top / panel-
   below rhythm from the base card rules.
   Row gap matches the .entity-cards precedent (40/32) for the cream-
   on-cream image+text rhythm without a card chassis.
   ════════════════════════════════════════════════════════════════════ */
.sv-services-stack{
  display: flex;
  flex-direction: column;
  gap: 40px;
}
@media (max-width: 767px){
  .sv-services-stack{ gap: 32px; }
}

/* Reverse variant : media-left, panel-right. Only flips above the
   mobile breakpoint; on mobile the base rule (image-on-top) is the
   editorial truth for both orientations. */
@media (min-width: 768px){
  .sv-service-card--reverse{
    grid-template-columns: 58fr 42fr;
  }
  .sv-service-card--reverse .sv-service-card__panel{ order: 2; }
  .sv-service-card--reverse .sv-service-card__media{ order: 1; }
}

/* ════════════════════════════════════════════════════════════════════
   SERVICES · L'OKAPI DIFFÉRENCE (framed asymmetric grid)
   Structural twin of À propos Vision: full-bleed via 100vw + negative
   margin, warm cream gutter painted on the section, 12px padding so the
   inner frame floats with even breathing room. Inner frame paints dark
   warm brown at 18px radius. Inside the frame: section head (label +
   counter), cream-on-dark headline, lede, and two grid rows with
   intentionally non-aligning column ratios (1/1.4/1 over 1.3/0.9) so
   the bottom row gridlines break from the top.
   ──────────────────────────────────────────────────────────────────── */
.sv-difference{
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  background: #f5f0ea;
  padding: 12px;
  display: flex;
  isolation: isolate;
  overflow: hidden;
}
/* Frame: warm gradient base + faint oil_rig.jpeg overlay (soft-light @ 0.12)
   so a sense of warm light reads from the top-right of the surface without
   the rig itself being recognizable. ::before paints the gradient as the
   base layer; ::after layers the photo via background-blend-mode soft-light. */
.sv-difference__frame{
  position: relative;
  flex: 1;
  border-radius: 18px;
  background:
    radial-gradient(ellipse at 78% 18%, rgba(200, 146, 42, 0.18), transparent 55%),
    linear-gradient(160deg, #2a140b 0%, #1a0c06 60%, #140906 100%);
  isolation: isolate;
  overflow: hidden;
}
.sv-difference__frame::after{
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("hero/oil_rig.jpeg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: 0.12;
  mix-blend-mode: soft-light;
  pointer-events: none;
  z-index: 0;
}
.sv-difference__content{
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 64px;
  padding: clamp(48px, 6vw, 96px) clamp(32px, 4vw, 80px);
}
/* Cream-on-dark text overrides scoped to .sv-difference. Mirrors the
   .ap-vision pattern so .label--light, .section-counter--light, and
   .headline primitives can be reused inside the dark frame. */
.sv-difference .label--light{ color: rgba(245, 240, 234, 0.85); }
.sv-difference .label__bullet{ background: var(--amber); }
.sv-difference .label__divider{ background: rgba(245, 240, 234, 0.3); }
.sv-difference .section-counter--light{ color: rgba(245, 240, 234, 0.85); }
.sv-difference .headline{ color: #f5f0ea; margin: 0; }
.sv-difference .headline em{ color: var(--color-accent-orange); }
.sv-difference__lede{
  margin: 0;
  max-width: 680px;
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-md), 1.2vw, var(--text-lg));
  line-height: var(--leading-loose);
  color: rgba(245, 240, 234, 0.85);
}

/* SERVICES · DIFFÉRENCE asymmetric grid.
   Two rows with deliberately different column counts and ratios. Each
   row is a self-contained grid (rather than one shared grid) so the
   gridlines do not align between rows: the visual offset is the ratio
   mismatch itself, not an explicit padding shift. */
.sv-difference-grid{
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.sv-difference-grid__row{
  display: grid;
  gap: 20px;
}
.sv-difference-grid__row--top{
  grid-template-columns: 1fr 1.4fr 1fr;
}
.sv-difference-grid__row--bottom{
  grid-template-columns: 1.3fr 0.9fr;
}

/* SERVICES · DIFFÉRENCE card.
   Dark warm brown surface by default with cream text. Hover lifts the card
   (translateY only, no background-color shift) and intensifies the shadow
   plus the amber title and decorative watermark. The decorative SVG sits
   behind .sv-difference-card__content via z-index stacking and is clipped
   to the card by overflow:hidden. */
.sv-difference-card{
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: 40px;
  background: var(--color-brand);
  border: 1px solid rgba(245, 240, 234, 0.06);
  border-radius: 10px;
  display: flex;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  transition: transform 700ms cubic-bezier(0.16, 1, 0.3, 1),
              box-shadow 700ms cubic-bezier(0.16, 1, 0.3, 1),
              border-color 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
.sv-difference-card__bg{
  position: absolute;
  bottom: -20px;
  right: -20px;
  width: 180px;
  height: 180px;
  color: #f5f0ea;
  opacity: 0.06;
  pointer-events: none;
  z-index: 0;
  transition: opacity 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
.sv-difference-card__bg svg{ width: 100%; height: 100%; display: block; overflow: visible; }
/* Numeral decoratives (cards 2 + 4) read as oversized watermark figures.
   Wider viewBox + xMidYMax keeps the baseline anchored to the card's
   bottom-right corner, then the numerals bleed out via overflow:visible
   on the SVG and overflow:hidden on the card. */
.sv-difference-card__bg--numeral{
  width: 220px;
  height: 200px;
  bottom: -32px;
  right: -16px;
}
.sv-difference-card__content{
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
}
.sv-difference-card__icon{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  color: var(--amber);
  margin-bottom: 24px;
}
.sv-difference-card__icon svg{ width: 100%; height: 100%; }
.sv-difference-card__title{
  margin: 0 0 12px;
  font-family: var(--font-heading);
  font-weight: var(--weight-light);
  font-size: var(--text-xl);
  letter-spacing: var(--track-tight-sm);
  color: #f5f0ea;
  transition: color 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
.sv-difference-card__body{
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: var(--text-md);
  line-height: 1.6;
  color: rgba(245, 240, 234, 0.7);
}

/* Hover: lift only. No background change. Shadow deepens, title turns
   amber, decorative watermark intensifies from 0.06 to 0.18. Body cream
   stays at 0.7 (does not shift) so the eye lands on the title accent. */
@media (hover: hover){
  .sv-difference-card:hover{
    transform: translateY(-4px);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
  }
  .sv-difference-card:hover .sv-difference-card__title{ color: var(--amber); }
  .sv-difference-card:hover .sv-difference-card__bg{ opacity: 0.18; }
}
/* Mobile fallback. No transform (avoids janky tap), shadow grows so the
   touch target still gives press feedback. */
.sv-difference-card:active{ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5); }

/* Tablet: top row collapses to 2-up with the third card spanning full
   width below the first two. Bottom row becomes a clean 1fr 1fr. */
@media (max-width: 1023px){
  .sv-difference__content{ gap: 48px; padding: clamp(40px, 5vw, 64px) clamp(24px, 4vw, 48px); }
  .sv-difference-grid__row--top{ grid-template-columns: 1fr 1fr; }
  .sv-difference-grid__row--top > :nth-child(3){ grid-column: 1 / -1; }
  .sv-difference-grid__row--bottom{ grid-template-columns: 1fr 1fr; }
}

/* Mobile: single column, decorative SVG scales down. */
@media (max-width: 767px){
  .sv-difference{ padding: 8px; }
  .sv-difference__content{ gap: 40px; padding: 40px 24px; }
  .sv-difference-grid,
  .sv-difference-grid__row{ gap: 16px; }
  .sv-difference-grid__row--top,
  .sv-difference-grid__row--bottom{ grid-template-columns: 1fr; }
  .sv-difference-grid__row--top > :nth-child(3){ grid-column: auto; }
  .sv-difference-card{ padding: 28px; }
  .sv-difference-card__bg{ width: 120px; height: 120px; bottom: -16px; right: -16px; }
  .sv-difference-card__bg--numeral{ width: 150px; height: 130px; bottom: -22px; right: -10px; }
}

/* ════════════════════════════════════════════════════════════════════
   SERVICES · PARTENAIRES MARQUEE
   Two-row reverse-direction marquee. Pure CSS keyframes. Card list is
   duplicated inline in the markup so the translate(-50%) loop is
   seamless. Edge mask fades cards into the warm-cream surface on both
   sides. Logos default grayscale + 70% opacity; hover restores both
   and lifts the card 2px while pausing the marquee.
   ════════════════════════════════════════════════════════════════════ */
.sv-marquee{
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: 100%;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 80px, #000 calc(100% - 80px), transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 80px, #000 calc(100% - 80px), transparent 100%);
}
.sv-marquee__row{
  overflow: hidden;
}
.sv-marquee__track{
  display: flex;
  align-items: stretch;
  gap: 16px;
  list-style: none;
  margin: 0;
  padding: 0;
  width: max-content;
  will-change: transform;
}
.sv-marquee__row--left .sv-marquee__track{
  animation: sv-marquee-left 60s linear infinite;
}
.sv-marquee__row--right .sv-marquee__track{
  animation: sv-marquee-right 75s linear infinite;
}

@keyframes sv-marquee-left{
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - 8px)); }
}
@keyframes sv-marquee-right{
  from { transform: translateX(calc(-50% - 8px)); }
  to   { transform: translateX(0); }
}

@media (hover: hover){
  .sv-marquee__row:hover .sv-marquee__track{
    animation-play-state: paused;
  }
}

@media (prefers-reduced-motion: reduce){
  .sv-marquee__row--left .sv-marquee__track,
  .sv-marquee__row--right .sv-marquee__track{
    animation: none;
    transform: none;
  }
  .sv-marquee__row{ overflow-x: auto; }
}

/* SERVICES · partner card primitive.
   Uniform 320×160, 18px radius, lifted cream surface by default.
   Variants paint dark warm brown (--dark) or deep teal (--teal). The
   --text variant renders the partner name in DM Mono caps when no
   logo file is available (fallback per brief). */
.sv-partner-card{
  flex: 0 0 auto;
  width: 320px;
  height: 160px;
  padding: 24px;
  border-radius: 18px;
  background: var(--canvas-lifted, #faf6f1);
  border: 1px solid rgba(61, 18, 8, 0.08);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  transition: transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
.sv-partner-card img{
  display: block;
  width: 100%;
  max-width: 70%;
  height: auto;
  max-height: 60px;
  object-fit: contain;
  object-position: left center;
  filter: grayscale(1);
  opacity: 0.7;
  transition: filter 700ms cubic-bezier(0.16, 1, 0.3, 1),
              opacity 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
/* Italco SVG carries an "AUTOMOTIVE REFINISHING" tagline below the
   logomark. Crop the bottom band so the marquee reads as logomark only. */
.sv-partner-card img[src*="italco"]{
  clip-path: inset(0 0 24% 0);
}
/* BP (icon roundel) and CBG (square emblem) lack a horizontal wordmark,
   so at the shared 60px cap they appear lighter than the wordmark logos.
   Allow them a taller box to balance visual weight in the marquee. */
.sv-partner-card img[src*="Bp_Logo"],
.sv-partner-card img[src*="CBG"]{
  max-height: 80px;
}
.sv-partner-card__name{
  display: block;
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: inherit;
  opacity: 0.85;
  max-width: 80%;
}
.sv-partner-card__desc{
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  color: var(--color-dark);
}
.sv-partner-card--dark{
  background: var(--ink);
  border-color: var(--ink);
  color: var(--canvas);
}
.sv-partner-card--dark .sv-partner-card__desc{ color: var(--canvas); opacity: 0.86; }
.sv-partner-card--dark img{ filter: grayscale(1) invert(1); opacity: 0.78; }
.sv-partner-card--teal{
  background: #0a4a5e;
  border-color: #0a4a5e;
  color: var(--canvas);
}
.sv-partner-card--teal .sv-partner-card__desc{ color: var(--canvas); opacity: 0.86; }
.sv-partner-card--teal img{ filter: grayscale(1) invert(1); opacity: 0.78; }

@media (hover: hover){
  .sv-partner-card:hover{ transform: translateY(-2px); }
  .sv-partner-card:hover img{ filter: none; opacity: 1; }
  .sv-partner-card--dark:hover img{ filter: invert(1); opacity: 1; }
  .sv-partner-card--teal:hover img{ filter: invert(1); opacity: 1; }
}
.sv-partner-card:active img{ filter: none; opacity: 1; }

@media (max-width: 767px){
  .sv-partner-card{ width: 280px; }
  .sv-marquee{
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 40px, #000 calc(100% - 40px), transparent 100%);
            mask-image: linear-gradient(to right, transparent 0, #000 40px, #000 calc(100% - 40px), transparent 100%);
  }
  /* Mobile collapses to single row, slower loop. Row 2 hidden. */
  .sv-marquee__row--right{ display: none; }
  .sv-marquee__row--left .sv-marquee__track{ animation-duration: 90s; }
}

/* ════════════════════════════════════════════════════════════════════
   SERVICES · FAQ
   Two-column grid, intro left + accordion right (50/50, 80px gap,
   collapses to single column under 1024px). Native <details> for
   mutually-exclusive behaviour via the name attribute. Plus icon
   rotates 45° on [open] for a quiet × glyph.
   ════════════════════════════════════════════════════════════════════ */
.sv-faq-grid{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  align-items: start;
}
.sv-faq-intro{
  display: flex;
  flex-direction: column;
  gap: 28px;
  max-width: 420px;
}
.sv-faq-body{
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: var(--text-md);
  line-height: 1.7;
  color: var(--ink);
  opacity: 0.84;
}
.sv-faq-pill{
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  padding: 12px 20px;
  font-family: var(--font-label);
  font-size: var(--text-sm);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--color-dark);
  text-decoration: none;
  border: 1px solid rgba(61, 18, 8, 0.15);
  border-radius: 8px;
  transition: color 700ms cubic-bezier(0.16, 1, 0.3, 1),
              border-color 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
@media (hover: hover){
  .sv-faq-pill:hover{ color: var(--amber); border-color: var(--amber); }
}
.sv-faq-pill:active{ color: var(--amber); border-color: var(--amber); }

.sv-faq-list{
  display: flex;
  flex-direction: column;
  border-top: 1px solid rgba(61, 18, 8, 0.12);
}
.sv-faq-item{
  border-bottom: 1px solid rgba(61, 18, 8, 0.12);
  padding: 24px 0;
}
/* Strip the default disclosure marker. Safari needs the prefix. */
.sv-faq-item summary{
  list-style: none;
  cursor: pointer;
}
.sv-faq-item summary::-webkit-details-marker{ display: none; }

.sv-faq-item__q{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: var(--text-md);
  line-height: 1.4;
  color: var(--color-dark);
}
.sv-faq-item__icon{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  color: var(--amber);
  flex: 0 0 auto;
  transform: rotate(0);
  transition: transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}
.sv-faq-item__icon svg{ width: 100%; height: 100%; }
.sv-faq-item[open] .sv-faq-item__icon{ transform: rotate(45deg); }

.sv-faq-item__a{
  margin: 16px 0 0;
  max-width: 540px;
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: var(--text-md);
  line-height: 1.7;
  color: var(--ink);
  opacity: 0.78;
}

@media (max-width: 1023px){
  .sv-faq-grid{ grid-template-columns: 1fr; gap: 56px; }
  .sv-faq-intro{ max-width: 100%; }
}

@media (prefers-reduced-motion: reduce){
  .sv-faq-item__icon{ transition: none; }
}

/* === END SERVICES === */


/* ════════════════════════════════════════════════════════════════════════
   SHARED NAV : Parlons CTA button (global, not Entités-specific)
   Lives inside .nav__actions next to FR|EN. Solid amber fill, cream text,
   inline arrow SVG, 10px radius, 44px height, amber-deep wipe on hover.
   Stays amber regardless of scroll state.
   ════════════════════════════════════════════════════════════════════════ */
.nav__cta{
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  padding: 0 16px;
  background: var(--amber);
  color: var(--canvas-warm);
  border: 0;
  border-radius: 10px;
  font-family: var(--font-label);
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  letter-spacing: var(--track-mono-wide);
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: color 910ms cubic-bezier(0.22, 1, 0.36, 1);
}
.nav__cta::before{
  content: "";
  position: absolute;
  inset: 0;
  background: var(--amber-deep);
  transform: translateX(-101%);
  transition: transform 910ms cubic-bezier(0.22, 1, 0.36, 1);
  z-index: 1;
  pointer-events: none;
}
.nav__cta > *{
  position: relative;
  z-index: 2;
}
.nav__cta-arrow{
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  transition: transform 400ms cubic-bezier(0.16, 1, 0.3, 1);
}
.nav__cta,
.nav__cta:hover{
  color: var(--canvas-warm);
}
@media (hover: hover){
  .nav__cta:hover::before{ transform: translateX(0); }
  .nav__cta:hover .nav__cta-arrow{ transform: translateX(3px); }
}
.nav__cta:active{ transform: scale(0.98); }
@media (max-width: 767px){
  .nav__cta{
    height: 40px;
    padding: 0 16px;
    gap: 8px;
    font-size: var(--text-xs);
    letter-spacing: var(--track-mono);
    border-radius: 10px;
  }
  .nav__cta-arrow{ width: 12px; height: 12px; }
}


/* ════════════════════════════════════════════════════════════════════════
   === ENTITÉS PAGES ===
   Styles for entites.html (landing) and /entites/*.html (sub-pages).
   Class prefix: .en-* for everything specific to the Entités universe.
   Reuses primitives: .page-hero, .section, .section-head, .label,
   .headline, .capabilities/.capability, .member, .stat, .closing.
   ════════════════════════════════════════════════════════════════════════ */

/* Sub-page seam suppression. The global .section::before paints a 16px
   top-edge gradient (intentional shadow seam between home-page sections).
   On sub-pages every section is a single continuous cream surface, so that
   gradient reads as an unwanted dark band above each section. Suppress it
   for every en-* section variant. Scoped: home, À propos, Services,
   Actualités, and the entites.html landing (.en-landing-cards) keep the
   seam. The closing dark section already has its own .section.contact
   variant which is untouched. */
.en-lede-section::before,
.en-mission::before,
.en-activities::before,
.en-leadership::before,
.en-stats::before,
.en-hsse::before,
.en-external::before{
  content: none;
  background: none;
}

/* Hero head row : label left, section counter right.
   Used on entites.html (01 · 03) and on every sub-page hero (01 · 07).
   Pairs with the existing .label and .section-counter primitives. */
.page-hero__head{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 28px;
}
.page-hero__head .label{ margin: 0; }
.section-counter--dark{
  color: rgba(245, 240, 234, 0.6);
}

/* ─── ENTITES.HTML LANDING ────────────────────────────────────────────── */

/* Section wrapper for the 5-card grid. Cream canvas, sits between the
   dark warm hero and the universal closing. */
.en-landing-cards{
  background: var(--canvas-warm);
  color: var(--ink);
}
.en-landing-lede{
  max-width: 720px;
  margin: 0 0 56px;
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-md), 1.3vw, var(--text-lg));
  line-height: 1.7;
  color: var(--ink);
  opacity: 0.78;
}
@media (max-width: 767px){
  .en-landing-lede{ margin-bottom: 40px; }
}

/* Grid for the 5 entity cards. Reuses .entity-cards from the home page,
   stacked vertically (one card per row) for editorial reading rhythm. */
.en-landing-cards__grid{
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}
@media (max-width: 767px){
  .en-landing-cards__grid{ gap: 16px; }
}

/* On entites.html the .entity-card reveal lives inside main.js IIFE #1,
   which is home-only (gated on #flux-canvas). Reset the pre-state here so
   the 5 landing cards render visible without depending on that IIFE. */
.en-landing-cards__grid .entity-card{
  opacity: 1;
  transform: none;
}

/* Each card is now an <a>. Remove default anchor styling, preserve the
   .entity-card chassis. The custom CTA span inside is a visual cue only. */
.en-card{
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
}
.en-card:focus-visible{
  outline: 2px solid var(--amber);
  outline-offset: 4px;
}
@media (hover: hover){
  .en-card:hover{ transform: translateY(-2px); }
  .en-card:hover .entity-card__arrow{
    transform: rotate(45deg);
  }
}
.entity-card__cta-text{
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--track-mono-wide);
  text-transform: uppercase;
  color: var(--panel-ink, var(--canvas-warm));
  opacity: 0.86;
}
.entity-card__arrow{
  transition: transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Entites landing : seam shadow on the image side of each entity card.
   Mirrors the .entity-hero__media pattern from the entity sub-pages so
   the photo reads as lifted off the brown panel. Desktop layout is panel
   left / image right, so the shadow casts from the image's left edge
   onto the panel. Mobile stacks image on top (via .entity-card__media
   order: 1) and panel below, so the shadow rotates 90deg and casts down
   from the image's bottom edge onto the panel beneath it. Scoped to
   .en-card to avoid affecting the home-page .entity-card grid. */
.en-card .entity-card__media{
  filter: drop-shadow(-24px 0 48px rgba(0, 0, 0, 0.25));
}
@media (max-width: 767px){
  .en-card .entity-card__media{
    filter: drop-shadow(0 24px 48px rgba(0, 0, 0, 0.25));
  }
}

/* ─── SUB-PAGES : COMMON HERO LAYOUT ──────────────────────────────────── */

/* Hero variant for /entites/*.html. Same chassis as .page-hero, with a
   tagline (em italic accent) and a small geographic location label. */
.en-sub-hero .page-hero__subheading{
  margin-top: 24px;
}
.en-sub-tagline{
  /* uses .page-hero__subheading base; this only adjusts max-width below */
  max-width: 640px;
}
.en-sub-location{
  display: inline-block;
  margin-top: 32px;
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--track-mono-wide);
  text-transform: uppercase;
  color: rgba(245, 240, 234, 0.62);
}

/* ─── SECTION 02 : MISSION ────────────────────────────────────────────── */

.en-mission{
  background: var(--canvas-warm);
  color: var(--ink);
}
.en-mission__body{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  max-width: 960px;
  margin-top: 8px;
}
/* Single-paragraph variant. Mission on KP runs one condensed body
   paragraph followed by a separate quote callout, so the 2-col grid
   collapses to a single editorial column with a 720px reading measure. */
.en-mission__body--single{
  grid-template-columns: 1fr;
  max-width: 720px;
}
.en-mission__para{
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: var(--text-md);
  line-height: var(--leading-loose);
  color: var(--ink);
  opacity: 0.82;
}
@media (max-width: 1023px){
  .en-mission__body{ grid-template-columns: 1fr; gap: 28px; }
}

/* Circular brand mark anchored on the right of the Mission section.
   Static visual only: no link, no hover, no shadow. The cream fill matches
   the section canvas so only the thin amber outline and the inner logo are
   visible, in keeping with the editorial restraint of the entity pages.
   Three amber ripple rings radiate outward from the main circle at
   decreasing opacity. The whole composition is shifted left so the right
   side of the outer ripples bleeds beyond the section's right edge.
   Pilot scope: entites/kp.html only. */
.en-mission__mark{
  position: absolute;
  top: 50%;
  right: clamp(24px, 5vw, 80px);
  transform: translate(-10vw, -50%) scale(0.7);
  width: clamp(280px, 26vw, 360px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--color-cream);
  border: 1px solid var(--color-accent-orange);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
  pointer-events: none;
}
.en-mission__mark img{
  width: 90%;
  height: 90%;
  object-fit: contain;
  display: block;
}
.en-mission__mark-ripple{
  position: absolute;
  top: 50%;
  left: 50%;
  border-radius: 50%;
  border: 1px solid var(--color-accent-orange);
  pointer-events: none;
  /* width/height set per ripple below; transform centers each ring on the
     main circle (which has its own border included in its 100%). */
  transform: translate(-50%, -50%);
}
.en-mission__mark-ripple--1{
  width: calc(100% + 100px);
  height: calc(100% + 100px);
  opacity: 0.50;
}
.en-mission__mark-ripple--2{
  width: calc(100% + 200px);
  height: calc(100% + 200px);
  opacity: 0.25;
}
.en-mission__mark-ripple--3{
  width: calc(100% + 300px);
  height: calc(100% + 300px);
  opacity: 0.12;
}
/* Per-page override: the Manta Marine logo PNG is near-square (524x544)
   with its wordmark trimmed almost edge-to-edge of the canvas. The other
   entity logos (KP, Geneva Oil, etc.) ship with substantial built-in
   whitespace, so at the shared 90% sizing they read as ~58% of the
   circle. Manta needs a tighter box to match that visual coverage. At
   55%, Manta's visible glyph + wordmark lands at ~53% of circle. */
.en-mission__mark--manta img{
  width: 55%;
  height: 55%;
}
@media (max-width: 1023px){
  .en-mission__mark{ display: none; }
}

/* ─── SECTION 03 : ACTIVITÉS ──────────────────────────────────────────── */

/* Reuses .expertise (white background) + .capabilities grid. The override
   here only handles the Entités-specific 3-column rhythm at desktop. */
.en-activities__grid{
  margin-top: 12px;
}

/* ─── SECTION 04 : DIRECTION ──────────────────────────────────────────── */

.en-leadership{
  background: var(--canvas-warm);
  color: var(--ink);
}
.en-leadership__grid{
  display: grid;
  grid-template-columns: 360px 1fr;
  gap: 64px;
  align-items: start;
  margin-top: 12px;
  max-width: 1100px;
}
.en-leadership__member{
  /* Reuses .member primitive. No grid-internal change needed. */
}
.en-leadership__bio{
  margin: 16px 0 0;
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-sm), 1.05vw, var(--text-md));
  line-height: var(--leading-loose);
  color: var(--ink);
  opacity: 0.78;
  max-width: 560px;
}
/* Placeholder portrait for entities without a director image (Hummingbird,
   Mantra Marines). Rust-tinted block fills the 4:5 frame, the .member__name
   below reads "Direction · à venir". Applied via .member__portrait--placeholder
   on the existing .member__portrait. */
.member__portrait--placeholder{
  background: var(--canvas-rust);
  position: relative;
}
.member__portrait--placeholder::after{
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(135deg, rgba(90, 29, 14, 0.04) 0%, rgba(245, 240, 234, 0) 60%);
  pointer-events: none;
}
@media (max-width: 1023px){
  .en-leadership__grid{
    grid-template-columns: 1fr;
    gap: 32px;
    max-width: 480px;
  }
}

/* ─── SECTION 05 : CHIFFRES ───────────────────────────────────────────── */

.en-stats{
  background: var(--canvas-warm);
  color: var(--ink);
}
.en-stats .label,
.en-stats .headline{
  color: var(--ink);
}
.en-stats__grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 48px;
  margin-top: 12px;
  padding-top: 56px;
}
.en-stat{
  /* Reuses .stat primitive. Cream canvas inherits ink color from .en-stats. */
}
.en-stat .stat__num{
  color: var(--ink);
  /* Sub-page chiffres mix numeric values (400+, 2010) with short words
     (Afrique, Genève, Boké). The home 140px size is too aggressive for
     words and starts breaking the grid. Scale down to a measured display
     size that reads cleanly for both forms. */
  font-size: clamp(var(--text-2xl), 5vw, var(--text-4xl));
  letter-spacing: -0.015em;
}
@media (max-width: 1023px){
  .en-stat .stat__num{ font-size: clamp(var(--text-2xl), 4.5vw, var(--text-3xl)); }
}
@media (max-width: 767px){
  .en-stat .stat__num{ font-size: var(--text-2xl); }
}
.en-stat .stat__label{
  color: rgb(from var(--color-dark) r g b / 0.62);
}
@media (max-width: 1023px){
  .en-stats__grid{ grid-template-columns: repeat(3, 1fr); gap: 32px; padding-top: 40px; }
}
@media (max-width: 640px){
  .en-stats__grid{ grid-template-columns: 1fr; gap: 32px; padding-top: 32px; }
}

/* ─── SECTION 06 : LIEN EXTERNE ───────────────────────────────────────── */

.en-external{
  background: var(--canvas-warm);
  color: var(--ink);
}
.en-external__lede{
  max-width: 560px;
  margin: 0 0 24px;
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: var(--text-md);
  line-height: 1.7;
  color: var(--ink);
  opacity: 0.78;
}
.en-external__cta{
  /* Inherits .btn .btn--secondary .btn--on-light chassis. No further
     overrides needed. */
}

/* ─── SUB-PAGES v2 : FRAMED HERO ──────────────────────────────────────── */

/* Replaces the legacy full-bleed dark .en-sub-hero with a framed
   light-tan panel inset by a 12px gutter. Pattern mirrors the À propos
   Vision frame: outer breaks out to viewport width, gutter painted in
   cream, inner rounded card painted in warm tan. The sticky nav above
   sits on its own dark-blurred chassis (.nav--page) so legibility is
   preserved against the cream gutter peek-through. */
.en-hero--framed{
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  background: var(--canvas-warm);
  color: var(--ink);
  padding: 12px;
  min-height: 92vh;
  display: flex;
  align-items: stretch;
  isolation: isolate;
  /* overflow: visible so the frame inner's drop shadow can render into
     the 12px cream gutter and softly into the page below. The frame
     inner keeps its own overflow:hidden to clip the image cleanly. */
  overflow: visible;
}
.en-hero-frame__inner{
  position: relative;
  flex: 1;
  border-radius: 18px;
  overflow: hidden;
  background: transparent;
  border: 1px solid #1a0c06;
  /* Soft, atmospheric lift off the cream surface. Two-layer composite
     using the brand dark warm brown at low opacity so the shadow joins
     the page colour story instead of reading as neutral grey. */
  box-shadow: 0 80px 200px 20px rgba(26, 12, 6, 0.07),
              0 40px 120px 0 rgba(26, 12, 6, 0.05),
              0 20px 60px -10px rgba(26, 12, 6, 0.04);
  isolation: isolate;
  display: flex;
  align-items: center;
  padding: clamp(140px, 16vh, 180px) clamp(40px, 6vw, 96px) clamp(80px, 12vh, 140px);
}
.en-hero--framed .page-hero__inner{
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: clamp(40px, 6vh, 72px);
}
/* Light-bg color overrides : dark warm brown text replaces cream. */
.en-hero--framed .headline{ color: var(--ink); max-width: 18ch; }
.en-hero--framed .headline em{ color: var(--amber); }
.en-hero--framed .page-hero__subheading,
.en-hero--framed .en-sub-tagline{ color: rgb(from var(--color-dark) r g b / 0.74); }
.en-hero--framed .en-sub-location{ color: rgb(from var(--color-dark) r g b / 0.5); }
.en-hero--framed .label--light{ color: rgb(from var(--color-dark) r g b / 0.62); }
.en-hero--framed .label--light .label__num{ color: var(--ink); }
.en-hero--framed .label--light .label__sep{ color: rgb(from var(--color-dark) r g b / 0.32); }
.en-hero--framed .label--light .label__bullet{ background: var(--amber); }
.en-hero--framed .label--light .label__divider{ background: rgba(26, 12, 6, 0.22); }
.en-hero--framed .section-counter--light{ color: rgb(from var(--color-dark) r g b / 0.5); }
/* Filigree on tan : amber rings ≈5% opacity so it whispers, not shouts. */
.en-hero--framed .page-hero__portal path{ fill: var(--amber); fill-opacity: 0.05; }
.en-hero--framed .page-hero__portal .ring{ stroke: var(--amber); stroke-opacity: 0.18; }
@media (max-width: 1023px){
  .en-hero--framed{ min-height: 85vh; }
  .en-hero-frame__inner{ padding: clamp(120px, 14vh, 160px) 40px clamp(64px, 10vh, 100px); }
}
@media (max-width: 767px){
  .en-hero--framed{ padding: 8px; min-height: 78vh; }
  .en-hero-frame__inner{ padding: 120px 24px 64px; border-radius: 14px; }
}

/* ─── SUB-PAGES v2 : RESTRAINED SECTION HEADER ───────────────────────── */

/* Single-line DM Mono tag. Replaces the big italic-amber H2 on every
   non-hero section so the page has one display moment instead of seven.
   The amber number is the only chromatic accent in the tag. */
.en-section-tag{
  display: block;
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  margin: 0 0 40px;
  color: rgb(from var(--color-dark) r g b / 0.55);
}
.en-section-tag__num{
  color: var(--amber);
  margin-right: 16px;
}
/* Modifier kept as a no-op hook for future dark variants. Cream surfaces
   inherit the base .en-section-tag color so the markup needs no churn. */
.en-section-tag--on-dark{
  color: rgb(from var(--color-dark) r g b / 0.55);
}
@media (max-width: 767px){
  .en-section-tag{ margin-bottom: 28px; font-size: var(--text-xs); letter-spacing: var(--track-mono-xwide); }
  .en-section-tag__num{ margin-right: 12px; }
}

/* ─── SUB-PAGES v2 : SECTION SURFACES ─────────────────────────────────── */
/* Rhythm : framed-tan hero → continuous cream surface for every section
   below → dark closing. The hero is the only "framed moment" on the page.
   The .en-activities--dark / .en-leadership--cream / .en-stats--rust
   modifier classes are kept on the markup as no-op hooks (the bases now
   resolve cream) so future variants remain easy without HTML churn. */

/* Sub-page Activités base. The shared .expertise class (line 1206) paints
   white on the home page; sub-pages need cream. Scoped to .en-activities
   so the home grid is untouched. */
.en-activities{
  background: var(--canvas-warm);
  color: var(--ink);
}

/* Capability reveal-stuck reset. Pre-state at line ~1217 (.capability
   opacity 0 / translateY 20px) is unconditional. The reveal that animates
   it to visible lives in main.js IIFE #1, which is home-only (gated on
   #flux-canvas). Same scoped reset pattern as .en-landing-cards__grid
   .entity-card above : target the entites wrapper class only, leaving
   the home .expertise .capability cards untouched. */
.en-activities .capability,
.en-activities--dark .capability{
  opacity: 1;
  transform: none;
}

/* Sub-page Activités : strip the .capabilities / .capability hairline grid
   inherited from the home Expertise primitive. Sub-pages run on a single
   continuous cream surface : the only visible frame on the page is the
   hero's hairline. Capability cells become editorial blocks separated
   by whitespace alone. */
.en-activities .capabilities{
  border-top: none;
}
.en-activities .capability{
  border-bottom: none;
}
.en-activities .capability:nth-child(odd){
  border-right: none;
}

/* ─── SUB-PAGES v2 : EDITORIAL LEAD (H2) ─────────────────────────────── */

/* One promoted description line per sub-page, lifted from the Entités
   landing card. Sits below the framed hero, above Section 02 (Mission),
   acts as the editorial bridge. No italic, no amber, no rust : plain
   warm brown. Reduced vertical padding so the cream surface flows from
   hero margin-bottom into this lede into the standard section padding
   below without a perceptible band. */
.en-lede-section{
  background: var(--canvas-warm);
  color: var(--ink);
  padding-top: clamp(40px, 6vh, 80px);
  padding-bottom: clamp(40px, 6vh, 80px);
}
.en-lede{
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: clamp(var(--text-xl), 2.6vw, var(--text-2xl));
  line-height: var(--leading-snug);
  letter-spacing: var(--track-tight-xs);
  color: var(--color-dark);
  max-width: 720px;
  margin: 0;
}
@media (max-width: 767px){
  .en-lede{ font-size: clamp(var(--text-lg), 5vw, var(--text-xl)); line-height: 1.32; }
}

/* Editorial narrative tagline that bridges the hero and the first
   inner section. Centered amber italic Mulish semibold, sized to match
   the Direction quote callout rhythm. Replaces the ink-coloured H2 lede
   on entity sub-pages where a softer narrative voice fits better. */
.en-page-narrative {
  font-family: var(--font-body);
  font-style: italic;
  font-weight: var(--weight-semibold);
  font-size: clamp(var(--text-xl), 3.2vw, var(--text-2xl));
  line-height: 1.25;
  color: var(--amber);
  text-align: center;
  max-width: 900px;
  margin: clamp(64px, 9vh, 120px) auto 0;
  padding: 0 clamp(24px, 4vw, 64px);
}

/* When a .en-flow diagram follows the narrative tagline (Kamino sub-page),
   tighten the flex row-gap so the narrative→diagram rhythm is 24px total
   (narrative margin-bottom 0 + this gap + .en-flow margin-top 0). */
.section__inner:has(> .en-page-narrative + .en-flow) { gap: 24px; }

/* ─── SUB-PAGES v2 : CONTACT BLOCK (Geneva Oil) ───────────────────────── */

/* Replacement for the external-link section on entities without a public
   website. Compact stacked coords in DM Mono, restrained underline on
   hover. Sits inside the standard .section + .section__inner chassis. */
.en-contact-block{
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 24px;
  font-family: var(--font-label);
  font-size: var(--text-sm);
  letter-spacing: var(--track-wide-sm);
  color: var(--ink);
}
.en-contact-block a{
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid rgba(26, 12, 6, 0.2);
  padding-bottom: 2px;
  transition: color 320ms ease, border-color 320ms ease;
  align-self: flex-start;
}
.en-contact-block a:hover{
  color: var(--amber-deep);
  border-color: var(--amber);
}

/* ─── SUB-PAGES v2 : SPLIT FRAMED HERO (KP) ──────────────────────────── */

/* Modifier on .en-hero--framed for sub-pages that pair the editorial text
   block with a real photograph inside the same hairline-bordered frame.
   Text sits left (~45%), image fills right (~55%). The frame's
   18px radius and overflow:hidden continue to clip the image cleanly.
   Stacks on narrow viewports : image above text, single column inside
   the frame. */
.en-hero--framed--split .en-hero-frame__inner{
  display: flex;
  align-items: stretch;
  gap: clamp(40px, 5vw, 80px);
  padding: clamp(80px, 12vh, 140px) clamp(40px, 6vw, 80px);
}
.en-hero--framed--split .page-hero__inner{
  flex: 0 0 45%;
  max-width: 45%;
  margin: 0;
  justify-content: center;
  /* Tighter rhythm than the base framed hero: drop the uniform flex gap
     and apply per-element margins so kicker/H1/subhead/location read as
     one deliberate composition. Per-gap scaling vs base clamp(40,6vh,72):
     kicker→H1 -35%, H1→sub -30%, sub→location -35%. */
  gap: 0;
}
.en-hero--framed--split .page-hero__head{
  margin-bottom: clamp(26px, 3.9vh, 47px);
}
.en-hero--framed--split .headline{
  margin-bottom: clamp(28px, 4.2vh, 50px);
}
.en-hero--framed--split .page-hero__subheading{
  margin-bottom: clamp(26px, 3.9vh, 47px);
}
/* Zero the base .en-sub-location margin-top so the subheading's own
   margin-bottom controls the sub→location gap (otherwise the 32px
   margin-top stacks on top, breaking the tightened rhythm). */
.en-hero--framed--split .en-sub-location{
  margin-top: 0;
}
.en-hero-frame__media{
  position: relative;
  z-index: 2;
  flex: 1;
  align-self: stretch;
  overflow: hidden;
  background: rgba(26, 12, 6, 0.04);
  /* Break out of the inner's top, right, and bottom padding so the image
     sits flush with the frame's hairline border. Parent has
     overflow:hidden + border-radius:18px, so the image's top-right and
     bottom-right corners are clipped by the frame itself, no gap. Match
     border-radius on the right side defensively in case the parent ever
     loses overflow:hidden. Left side stays flat: it adjoins the text
     column inside the frame, not a rounded corner. */
  margin-top: calc(-1 * clamp(80px, 12vh, 140px));
  margin-bottom: calc(-1 * clamp(80px, 12vh, 140px));
  margin-right: calc(-1 * clamp(40px, 6vw, 80px));
  border-radius: 0 18px 18px 0;
}
.en-hero-frame__media img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
@media (max-width: 1023px){
  .en-hero--framed--split .en-hero-frame__inner{
    padding: clamp(80px, 12vh, 120px) 40px clamp(56px, 8vh, 96px);
    gap: clamp(32px, 4vw, 56px);
  }
  .en-hero--framed--split .page-hero__inner{ flex-basis: 50%; max-width: 50%; }
  /* The @1023 inner override changes padding to clamp(80,12vh,120) 40px
     clamp(56,8vh,96). The base media's negative margins use different
     clamp envelopes that overshoot here. Track the @1023 padding values
     exactly so the image sits flush with the frame at 768-1023 widths. */
  .en-hero--framed--split .en-hero-frame__media{
    margin-top: calc(-1 * clamp(80px, 12vh, 120px));
    margin-bottom: calc(-1 * clamp(56px, 8vh, 96px));
    margin-right: -40px;
  }
}
@media (max-width: 767px){
  .en-hero--framed--split .en-hero-frame__inner{
    flex-direction: column;
    gap: clamp(24px, 4vh, 40px);
    padding: 24px 24px 64px;
    align-items: stretch;
  }
  .en-hero--framed--split .page-hero__inner{
    flex: 0 0 auto;
    max-width: 100%;
    order: 2;
  }
  .en-hero--framed--split .en-hero-frame__media{
    order: 1;
    flex: 0 0 auto;
    height: 45vh;
    width: 100%;
    /* Mobile: column stack. Image breaks out of inner's top + side
       padding (24px) so it sits flush with the frame's top + sides.
       Bottom stays inside the frame (text follows below). */
    margin-top: -24px;
    margin-right: -24px;
    margin-bottom: 0;
    margin-left: -24px;
    width: calc(100% + 48px);
    border-radius: 14px 14px 0 0;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   ENTITY DETAIL HERO (sub-pages: KP, Manta Marine, Kamino, Hummingbird,
   Geneva Oil). Reusable system. Adopt by adding the .entity-hero block to
   any entite/*.html sub-page. Inherits the canonical home-page
   typographic system from .boussole__* (the cleanest example) so every
   entity hero reads with the same institutional rhythm.
   Dark brown surface (#5C2E20, var(--color-brand)) matches sections
   06 expertise and 07 partenaires on the home page. Hero sits flush
   under the fixed .nav--page so no top corner radius is applied.
   ════════════════════════════════════════════════════════════════════════ */
/* Outer wrapper paints the cream gutters around the brown card.
   No border on the card itself per brand direction. */
.entity-hero{
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  background: var(--canvas-warm);
  color: var(--ink-d);
  padding: 12px;
  display: flex;
  align-items: stretch;
  isolation: isolate;
}
.entity-hero__inner{
  position: relative;
  z-index: 1;
  flex: 1;
  background: var(--color-brand);
  border-radius: 18px;
  overflow: hidden;
  margin: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 5vw, 64px);
  align-items: stretch;
  min-height: clamp(620px, 86vh, 860px);
  padding: 0;
}
.entity-hero__copy-col{
  display: block;
  align-self: center;
  padding: clamp(80px, 12vh, 140px) 0 clamp(80px, 12vh, 140px) clamp(40px, 5vw, 80px);
  position: relative;
  z-index: 1;
}
/* Tertiary back link sitting above the kicker. No fill, no border, just
   a left chevron + label. Amber on the brown hero surface, picking up the
   accent colour used by the headline italics. Slightly larger than a
   standard kicker label so it reads as navigation, but still a tertiary
   element (no border, no fill, no pill). */
.entity-back{
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-label);
  font-weight: var(--weight-regular);
  font-size: var(--text-sm);
  line-height: 1;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--amber);
  text-decoration: none;
  margin: 0 0 clamp(40px, 6vh, 64px) 0;
  transition: color 240ms var(--ease-out-expo);
}
.entity-back svg{
  width: 16px;
  height: 16px;
  transition: transform 240ms var(--ease-out-expo);
  flex-shrink: 0;
}
@media (hover: hover){
  .entity-back:hover{
    color: var(--amber);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 5px;
  }
  .entity-back:hover svg{ transform: translateX(-3px); }
}
.entity-back:focus-visible{
  outline: 1px solid var(--amber);
  outline-offset: 4px;
  color: var(--amber);
}
/* Kicker : DM Mono micro-label sitting directly above the headline.
   Mirrors .boussole__kicker exactly, with the dark-zone cream colour
   substituted for the on-cream rust. */
.entity-hero__kicker{
  display: block;
  font-family: var(--font-label);
  font-weight: var(--weight-regular);
  font-size: var(--text-xs);
  line-height: 1;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-cream) 60%, transparent);
  margin: 0 0 1.25em 0;
  white-space: nowrap;
}
/* Numeric prefix in the kicker (e.g. "01") receives the amber accent,
   matching the home-page .section-head__num convention. */
.entity-hero__kicker-num{ color: var(--color-accent-orange); }
/* Headline : same scale, weight, leading, tracking as .boussole__headline.
   Cream replaces brand maroon for the on-dark surface. */
.entity-hero__headline{
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  /* Hero headline size normalized to match .page-hero .headline so the
     entites landing + 5 entity sub-pages render at the same institutional
     scale as a-propos + services (max 80px @ desktop, not 112px). */
  font-size: clamp(var(--text-2xl), 6vw, var(--text-4xl));
  line-height: 0.95;
  letter-spacing: var(--track-tight-md);
  color: var(--ink-d);
  margin: 0 0 0.55em 0;
  max-width: 16ch;
}
.entity-hero__headline em{
  font-style: italic;
  font-family: var(--font-body);
  font-weight: var(--weight-semibold);
  color: var(--amber);
}
/* Body copy : matches .boussole__copy. Cream @ 80% on dark for the
   muted institutional read used across all dark-zone surfaces. */
.entity-hero__copy{
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: var(--text-md);
  line-height: 1.6;
  color: color-mix(in srgb, var(--color-cream) 80%, transparent);
  max-width: 42ch;
  margin: 0;
}
/* Right-column media. Bleeds to the top, right, and bottom edges of the
   brown card. Padded only on the left (gap with the typography column).
   Inner-left corners get a small 14px radius. The outer-right corners stay
   square here but get clipped by the card's 18px overflow:hidden mask, so
   visually the right side flows continuously with the card edge.
   A soft drop-shadow falls from the image's left edge onto the brown
   surface toward the typography column, lifting the image off the card. */
.entity-hero__media{
  position: relative;
  align-self: stretch;
  overflow: hidden;
  background: rgba(245, 240, 234, 0.04);
  border: none;
  border-radius: 14px 0 0 14px;
  aspect-ratio: auto;
  filter: drop-shadow(-24px 0 48px rgba(0, 0, 0, 0.25));
}
.entity-hero__media img{
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
/* Solid-color placeholder rectangle for entities without a hero image yet.
   Uses a subtly lighter brown wash on the brand surface so the slot reads
   intentional, not broken. */
.entity-hero__media--placeholder{
  background: color-mix(in srgb, var(--color-brand) 55%, black);
}
@media (max-width: 1023px){
  .entity-hero__inner{
    grid-template-columns: 1fr;
    grid-template-rows: 1fr auto;
    gap: clamp(40px, 5vh, 64px);
    min-height: max(100svh, 760px);
    padding: clamp(120px, 14vh, 160px) clamp(32px, 5vw, 64px) clamp(64px, 10vh, 100px);
  }
  .entity-hero__copy-col{
    padding: 0;
  }
  .entity-hero__media{
    aspect-ratio: 16 / 10;
    max-height: 60vh;
    border-radius: clamp(10px, 1.5vw, 14px);
    filter: none;
  }
}
@media (min-width: 600px) and (max-width: 1023px){
  .entity-hero__inner{
    min-height: max(100svh, 1000px);
  }
}
@media (max-width: 767px){
  .entity-hero{ padding: var(--hero-gutter-mobile); }
  /* 50/50 vertical split inside the brown card on mobile: text on top,
     image flush to the card's inner left, right, and bottom edges below.
     Single shared rule covers all five entity sub-pages. */
  .entity-hero__inner{
    /* minmax(0, 1fr) prevents long min-content children (e.g. the
       white-space:nowrap kicker on manta-marine) from forcing the
       column wider than the card and pushing the image past flush-right. */
    padding: 0;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: 1fr 1fr;
    gap: 0;
    border-radius: 14px;
    min-height: 92vh;
  }
  .entity-hero__kicker{
    /* Allow long kickers (e.g. "Manta Marine Technologies") to wrap
       gracefully at narrow widths instead of forcing column width. */
    white-space: normal;
  }
  .entity-hero__copy-col{
    /* Text region fills the full top-half cell so its rect equals the
       image rect (50/50 split). Inner content centers vertically via flex. */
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 32px 24px;
    align-self: stretch;
  }
  .entity-hero__media{
    /* Image region: bleeds flush to the card's left, right, and bottom
       edges. Square top corners (meets text), rounded bottom corners
       (matches card). object-fit: cover already declared on the inner img.
       Seam shadow: same drop-shadow as desktop (same color, blur, opacity,
       magnitude) but rotated 90deg so it casts upward from the photo's top
       edge into the bottom of the text region above. The square top edge
       is preserved ; only the projected shadow extends past it. The card's
       inner overflow:hidden + 18px radius clips any spill at the envelope. */
    aspect-ratio: auto;
    max-height: none;
    width: 100%;
    height: 100%;
    border-radius: 0 0 14px 14px;
    filter: drop-shadow(0 -24px 48px rgba(0, 0, 0, 0.25));
  }
  .entity-hero__headline{
    /* font-size intentionally not overridden on mobile : the desktop clamp
       (defined above) cascades down to match .page-hero .headline's mobile
       behavior exactly. Only line-height is tightened for narrow widths. */
    line-height: 0.98;
  }
  .entity-hero__copy{ font-size: var(--text-md); }
}

/* ─── HERO KICKER : MOBILE SUPPRESSION ──────────────────────────────────
   On mobile (≤767px), suppress the in-hero kicker line across all page
   heroes site-wide so the mobile typographic language stays consistent
   and the kicker no longer clashes with the "Retour aux entités" back
   button on entity sub-pages.

   Scope is strictly the in-hero kicker:
     · .entity-hero__kicker  : namespaced kicker on entites.html and the
       five entity sub-pages.
     · .page-hero .label--dark-section : in-hero label kicker on
       a-propos.html, services.html, actualites.html. Scoped under
       .page-hero so even if --dark-section is reused elsewhere later
       this rule cannot leak.

   Section-level kickers (.section-head__kicker) below the hero remain
   visible on mobile. Desktop CSS at >767px is unchanged.
   ─────────────────────────────────────────────────────────────────── */
@media (max-width: 767px){
  .entity-hero__kicker,
  .page-hero .label--dark-section{
    display: none;
  }
}

/* ─── ENTITY BACK BUTTON : MOBILE HIDE ──────────────────────────────────
   On mobile (≤767px), the sticky OKAPI logo and the in-hero "Retour aux
   entités" link share the same top-left zone and visually clash. The new
   universal hamburger drawer already exposes "Entités" as a top-level menu
   item, providing the same affordance without competing with the logo.
   Desktop CSS at >767px is unchanged.
   ─────────────────────────────────────────────────────────────────── */
@media (max-width: 767px){
  .entity-back{
    display: none;
  }
}

/* ─── ENTITY HERO : INDEX VARIANT ───────────────────────────────────────
   Single-column layout for /entites.html (the listing page that fronts
   the five entity sub-pages). Same brown surface, kicker, headline, and
   copy as the canonical .entity-hero, but :
     · no right-side photograph (the cards below ARE the visual)
     · adds a small head row : kicker on the left, "01 · 03" section
       counter on the right (mirrors the home section-counter pattern)
     · keeps the amber filigree portal as a quiet decorative watermark
       echoing the home hero portal, anchored to the right edge.
   ─────────────────────────────────────────────────────────────────── */
.entity-hero--index .entity-hero__inner{
  grid-template-columns: 1fr;
}
.entity-hero--index .entity-hero__copy-col{
  position: relative;
  z-index: 2;
  max-width: 70ch;
}
.entity-hero__head-row{
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: clamp(24px, 4vw, 48px);
  margin: 0 0 clamp(40px, 6vh, 72px) 0;
}
.entity-hero--index .entity-hero__kicker{
  margin: 0;                              /* head-row owns the spacing */
}
.entity-hero__counter{
  font-family: var(--font-label);
  font-weight: var(--weight-regular);
  font-size: var(--text-xs);
  line-height: 1;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-cream) 45%, transparent);
  white-space: nowrap;
}
/* Filigree watermark : the entites landing hero now reuses the shared
   .page-hero__portal class so its watermark is byte-for-byte identical
   to services.html and the other sub-page heroes. The previous
   .entity-hero__portal rules were removed to avoid drift. */
@media (max-width: 767px){
  .entity-hero__head-row{
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: clamp(28px, 4vh, 40px);
  }
}

/* ─── SUB-PAGES v2 : HSSE & ENGAGEMENTS (KP) ─────────────────────────── */

/* Replaces the placeholder Chiffres section with editorial prose plus a
   3-item commitments list. Reuses .en-mission__para for body paragraphs
   so the rhythm matches Mission. Commitments use a clean dl pattern :
   Poppins 400 label, Poppins 300 short description, no bullets, generous
   row spacing. Cream surface, no count-up, no fake numbers. */
.en-hsse{
  background: var(--canvas-warm);
  color: var(--ink);
}
.en-hsse__body{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  max-width: 980px;
  margin: 0 0 clamp(56px, 8vh, 96px);
}
.en-hsse__commitments{
  margin: 0;
  padding-top: clamp(40px, 6vh, 56px);
  border-top: 1px solid var(--hairline-soft);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 48px;
}
.en-hsse__item{ margin: 0; }
.en-hsse__label{
  font-family: var(--font-heading);
  font-weight: var(--weight-regular);
  font-size: clamp(var(--text-md), 1.2vw, var(--text-lg));
  line-height: var(--leading-snug);
  color: var(--ink);
  margin: 0 0 12px;
}
.en-hsse__desc{
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-sm), 1vw, var(--text-md));
  line-height: 1.7;
  color: var(--ink-2);
  margin: 0;
  max-width: 38ch;
}
@media (max-width: 1023px){
  .en-hsse__body{ grid-template-columns: 1fr; gap: 24px; }
  .en-hsse__commitments{ grid-template-columns: 1fr 1fr; gap: 32px; }
}
@media (max-width: 767px){
  .en-hsse__commitments{ grid-template-columns: 1fr; gap: 32px; padding-top: 32px; }
}

/* ─── SUB-PAGES v2 : EXTERNAL HEADLINE (KP) ──────────────────────────── */

/* Section 06 promoted headline above the lede. Plain warm brown,
   Poppins 400, no italic, no amber. Sits below the kicker tag, above
   the lede paragraph. Sized as a section H2 (smaller than hero). */
.en-external__headline{
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: clamp(var(--text-xl), 2.6vw, var(--text-2xl));
  line-height: var(--leading-tight);
  letter-spacing: var(--track-tight-xs);
  color: var(--ink);
  margin: 0 0 14px;
  max-width: 720px;
}
@media (max-width: 767px){
  .en-external__headline{ font-size: var(--text-xl); margin-bottom: 12px; }
}

/* ─── SUB-PAGES v2 : TIGHTER VERTICAL RHYTHM ──────────────────────────── */

/* Sub-page content sections lean editorial, not corporate. The global
   .section rule paints clamp(140px, 18vh, 220px) top + clamp(112px, 14vh,
   176px) bottom, and .section__inner stacks children with clamp(56px, 8vh,
   104px) flex gap. Combined with the .en-section-tag's own 40px bottom
   margin, kicker-to-body distance was reaching ~140px on tall viewports,
   which made each section feel like a discrete corporate slab. Tightening
   to ~70 percent of the home rhythm so the sub-page reads as one
   continuous editorial document. Scoped to en-* sub-page sections only,
   the home page and entites.html landing keep the original rhythm. */
.en-mission,
.en-activities,
.en-leadership,
.en-hsse,
.en-external{
  padding-top: clamp(96px, 12vh, 152px);
  padding-bottom: clamp(80px, 10vh, 128px);
}
.en-mission > .section__inner,
.en-activities > .section__inner,
.en-leadership > .section__inner,
.en-hsse > .section__inner,
.en-external > .section__inner{
  gap: 8px;
}

/* The .en-section-tag carries its own margin-bottom (40px) which stacks on
   top of the .section__inner flex gap. Zero it on these sub-page sections
   so the gap alone owns kicker-to-next-child rhythm. */
.en-mission .en-section-tag,
.en-activities .en-section-tag,
.en-leadership .en-section-tag,
.en-hsse .en-section-tag,
.en-external .en-section-tag{
  margin-bottom: 0;
}

/* En savoir plus is a denser sign-off block (headline + 1 short lede +
   CTA, kicker removed). Tighten further than the shared sub-page rhythm
   so it does not read as a full editorial section, just a compact closing
   card. The flex gap is dropped to exactly 10px so the headline sits
   tight to the lede; the CTA gets a compensating margin-top so its
   distance from the lede stays at the original clamp(16px, 2.5vh, 28px)
   gap value (calc subtracts the new 10px gap). The headline's own
   margin-bottom is zeroed so the visual gap is governed solely by the
   parent flex gap (= 10px). */
.en-external{
  padding-top: clamp(76px, 9.5vh, 120px);
  padding-bottom: clamp(64px, 8vh, 100px);
}
.en-external > .section__inner{
  gap: 12px;
}
.en-external .en-external__headline{
  margin-bottom: 0;
}
.en-external .en-external__cta{
  margin-top: calc(clamp(16px, 2.5vh, 28px) - 12px);
}

/* ─── SUB-PAGES v2 : SECTION-LEVEL EDITORIAL LEDE ──────────────────────── */

/* Optional H2 lede paragraph that can sit between the kicker tag and the
   section body on Mission, Activités, HSSE. Reuses the .en-lede typography
   primitive (Poppins 400, dark warm brown, clamp 22-32px, line-height 1.3,
   max-width 720px). The .en-section-lede modifier adds a small bottom
   margin so the visual gap to the body is medium (gap + this margin), not
   tight (gap alone). Top margin is zero so the kicker-to-lede gap is
   governed by the .section__inner flex gap alone, keeping it tight. */
.en-section-lede{
  margin-top: 0;
  margin-bottom: 8px;
}
@media (max-width: 767px){
  .en-section-lede{ margin-bottom: 8px; }
}

/* ─── SUB-PAGES v2 : SECTION H2 OPENER ────────────────────────────────── */

/* Short H2 title alternative to .en-lede. Used when a section opens with a
   crisp headline rather than an editorial paragraph (e.g., Activités on
   KP). Typographically distinct from .en-lede on purpose: larger, tighter
   line-height, denser letter-spacing. Pairs with .en-section-lede for
   margin rhythm so both H2 styles slot into the same DOM position with
   identical vertical spacing to neighbours. */
.en-section-h2{
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: clamp(var(--text-2xl), 5vw, var(--text-3xl));
  line-height: 1.1;
  letter-spacing: var(--track-tight-sm);
  color: var(--color-dark);
  max-width: 720px;
  margin: 0;
}
@media (max-width: 767px){
  .en-section-h2{ font-size: clamp(var(--text-xl), 7vw, var(--text-2xl)); line-height: var(--leading-heading); }
}

/* ─── SUB-PAGES v2 : ACTIVITÉS STICKY-IMAGE SCROLL (KP) ───────────────── */

/* Override base .section { overflow: hidden } so the right-column image
   frame can pin via position: sticky. The base rule (styles.css line 921)
   exists for home-page watermark clipping; .en-activities has no watermark
   and the clipping ancestor was killing sticky behaviour for the stack. */
section.en-activities {
  overflow: visible;
}

/* Decorative filigree behind the Activités sticky image. Peeks from the
   top with the right portion cropped beyond the viewport edge. Sits at
   z-index 0 so the section's content stack reads above it. */
.en-activities__filigree {
  position: sticky;
  top: clamp(60px, 8vh, 120px);
  right: -30%;
  margin-left: auto;
  margin-right: -30%;
  /* Absorb the img's flow height (SVG aspect ≈ 0.98) so .section__inner
     sits where it would without the filigree. Without this, sticky in a
     plain block parent pushes subsequent content down by the img height. */
  margin-bottom: calc(clamp(600px, 55vw, 900px) * -0.98);
  width: clamp(600px, 55vw, 900px);
  height: auto;
  opacity: 0.05;
  pointer-events: none;
  z-index: 0;
  user-select: none;
  align-self: start;
  display: block;
}

/* Mobile : hide the filigree at <=767px. The img is 600px wide minimum
   (clamp lower bound) which exceeds any phone viewport, and its parent
   .en-activities deliberately keeps overflow:visible to allow the sticky
   scroll choreography on desktop, so the filigree was the sole element
   driving document-level horizontal scroll on entites/kp.html. The asset
   is decorative (opacity 0.05) and visually negligible on a single-column
   mobile layout, so it is safely removed at this breakpoint. Containing
   it via overflow on the section would also break the sticky behavior. */
@media (max-width: 767px){
  .en-activities__filigree{ display: none; }
}


/* Two-column scroll choreography: panels stack on the left, a single
   sticky image holder on the right cross-fades between four images as
   each panel enters the viewport center. Mirrors Webflow-style sticky
   scroll patterns. position: sticky over GSAP pin to avoid pin-spacing
   layout shifts. Active/inactive opacity carries the focus shift; the
   image stack handles the visual cross-fade. */
.en-activities-sticky{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: start;
  margin-top: clamp(40px, 6vh, 72px);
}
.en-activities-panels{
  display: flex;
  flex-direction: column;
}
.en-activity-panel{
  min-height: 30vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  opacity: 0.4;
  transition: opacity 400ms ease;
  padding: 24px 0;
}
.en-activity-panel--active{ opacity: 1; }
.en-activity-panel__image{ display: none; }
.en-activity-panel__title{
  font-family: var(--font-heading);
  font-weight: var(--weight-medium);
  font-size: clamp(var(--text-xl), 3.4vw, var(--text-2xl));
  line-height: var(--leading-heading);
  letter-spacing: var(--track-tight-sm);
  color: var(--ink);
  margin: 0 0 20px;
  max-width: 28ch;
}
.en-activity-panel__desc{
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: var(--text-md);
  line-height: 1.6;
  color: rgb(from var(--color-dark) r g b / 0.74);
  margin: 0;
  max-width: 48ch;
}
.en-activities-images{
  position: sticky;
  top: 120px;
  align-self: start;
}
.en-activities-images__frame{
  position: relative;
  width: 100%;
  height: 70vh;
  max-height: 640px;
  border-radius: 14px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.2);
}
.en-activity-image{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 500ms ease;
}
.en-activity-image--active{ opacity: 1; }

/* Mobile: collapse to a single stacked column. Each panel shows its
   inline image at ~250px tall above the title and description. The
   sticky image stack is hidden so screen readers do not double-announce
   (decorative aria-hidden on the sticky stack already, but display:none
   removes it from the layout entirely). */
@media (max-width: 840px){
  .en-activities-sticky{
    grid-template-columns: 1fr;
    gap: 0;
  }
  .en-activities-images{ display: none; }
  .en-activity-panel{
    min-height: 0;
    opacity: 1;
    padding: 0 0 48px;
    gap: 18px;
  }
  .en-activity-panel + .en-activity-panel{
    padding-top: 32px;
    border-top: 1px solid rgba(245, 240, 234, 0.12);
  }
  .en-activity-panel__image{
    display: block;
    width: 100%;
    height: 250px;
    border-radius: 12px;
    overflow: hidden;
    margin-bottom: 4px;
  }
  .en-activity-panel__image img{
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  .en-activity-panel__title{ font-size: var(--text-xl); margin-bottom: 12px; }
}

/* Reduced motion: drop opacity dimming and cross-fade durations so
   panels read as a calm static list. Active/inactive states still apply
   instantly (no transition) for any JS that toggles them. */
@media (prefers-reduced-motion: reduce){
  .en-activity-panel{ opacity: 1; transition: none; }
  .en-activity-image{ transition: none; }
}

/* ─── SUB-PAGES v2 : ACTIVITÉS CENTERED HEADER (Geneva Oil only) ──────
   Scoped exclusively to the .en-activities--centered-head modifier added
   to entites/geneva-oil.html. The other four entity pages (kp,
   hummingbird, kamino, manta-marine) keep the base left-aligned header
   layout and are not affected by any of the rules below.
   Deltas vs. the base layout:
     1. The .en-activities__head wrapper (kicker + headline) is center-
        aligned horizontally and centered on the section's content axis.
     2. A full-bleed cream backdrop sits behind the header to extend the
        section's canvas color edge-to-edge above the two-column grid.
     3. Extra breathing room above the kicker (padding-top: 60px).
   No pinning. The header scrolls naturally with the section; the image
   column uses the same CSS sticky behavior as the base layout. */
.en-activities--centered-head .en-activities__head{
  position: relative;
  /* Flex column with align-items:center collapses each child to content
     width and centers them on the cross axis. text-align:center is also
     applied so wrapped lines inside the headline center on their own
     box. The 8px gap matches the site-wide section-head rhythm between
     kicker and headline. The __head wrapper isolates them from
     .section__inner's flex gap and .en-activities .en-section-tag has
     its margin zeroed at styles.css:5829-5835. */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
  z-index: 5;
  padding-top: 60px;
}
.en-activities--centered-head .en-activities__head::before{
  /* Full-viewport-width cream backdrop. The head sits inside
     .section__inner (constrained max-width + horizontal padding), so a
     same-width background would leave gutters showing through. The
     pseudo extends to ±50vw so the backdrop covers the full viewport
     horizontally regardless of the inner container's width. */
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100vw;
  background: var(--canvas-warm);
  z-index: -1;
  pointer-events: none;
}
/* Headline is a block element with max-width: 720px. text-align centers
   the glyphs inside; margin-inline:auto centers the block itself. */
.en-activities--centered-head .en-activities__head .en-section-h2{
  margin-inline: auto;
}
/* Lower the CSS-sticky image so it locks below the pinned centered head
   (see main.js centered-head pin). Base value is 120px; the centered
   head pins at the viewport top with ~222px of header height, so the
   image needs a larger sticky top to clear the pinned header band with
   breathing room. Scoped to the centered-head variant only; KP, Manta,
   Hummingbird, Kamino retain the base top:120px. */
.en-activities--centered-head .en-activities-images {
  top: 280px;
}
/* Each panel is sized to match the image container height (560px) and
   centers its text content vertically. With four panels stacked, the
   panels column is 4 × 560 = 2240px tall, which becomes the
   `.en-activities-sticky` grid container height (grid container takes
   max child height). The image (top:280, height:560) un-sticks the
   moment the container's bottom edge passes vp_top + 840, which is
   also where the centered-head pin ends (see main.js). Result:
   header and image release at the same scrollY, and at that moment
   the active panel's text is vertically centered against the image.
   Scoped to the centered-head variant only. */
.en-activities--centered-head .en-activity-panel {
  min-height: 560px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
/* Mobile fallback: revert to left-aligned + base rhythm so the layout
   matches the other entity pages below 841px. */
@media (max-width: 840px){
  .en-activities--centered-head .en-activities__head{
    align-items: flex-start;
    text-align: left;
    padding-top: 0;
  }
  .en-activities--centered-head .en-activities__head::before{
    display: none;
  }
  .en-activities--centered-head .en-activities__head .en-section-h2{
    margin-inline: 0;
  }
}

/* ─── SUB-PAGES v2 : DIRECTION QUOTE CALLOUT (KP) ─────────────────────── */

/* DEVIATION: Standard rule is one italic-amber em-word per page in hero only.
   KP relaxes this to add one italic-amber quote callout in the Direction section
   as Louis Camara's voice (sourced from KP's "Notre Histoire" page).
   Other entities should not duplicate this pattern unless explicitly approved. */
.en-quote-callout{
  font-family: var(--font-body);
  font-style: italic;
  font-weight: var(--weight-semibold);
  font-size: clamp(var(--text-xl), 3.5vw, var(--text-2xl));
  line-height: 1.25;
  letter-spacing: var(--track-tight-xs);
  color: var(--amber);
  max-width: 720px;
  margin: 32px 0 16px;
}
@media (max-width: 767px){
  .en-quote-callout{ font-size: var(--text-xl); margin: 24px 0 12px; }
}

/* ─── SUB-PAGES v2 : HSSE COMMITMENTS AS BORDERED CARDS (KP) ──────────── */

/* Cards modifier: when .en-hsse__commitments carries .en-hsse__commitments--cards,
   each item is a bordered editorial card on the cream surface. Drops the
   wrapper hairline + padding-top from the base treatment because cards
   carry their own visible enclosure. Used on KP after the body paragraphs
   were removed: the lede sits directly above three bordered commitments. */
.en-hsse__commitments--cards{
  border-top: none;
  padding-top: 0;
  gap: 24px;
}
.en-hsse__commitments--cards .en-hsse__item{
  border: 1px solid rgba(61, 18, 8, 0.4);
  border-radius: 14px;
  padding: 24px;
  background: transparent;
}
.en-hsse__commitments--cards .en-hsse__label{
  font-family: var(--font-heading);
  font-weight: var(--weight-medium);
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
  color: var(--color-dark);
  margin: 0 0 12px;
}
@media (max-width: 1023px){
  .en-hsse__commitments--cards{ grid-template-columns: 1fr 1fr; gap: 20px; }
}
@media (max-width: 840px){
  .en-hsse__commitments--cards{ grid-template-columns: 1fr; gap: 16px; }
  .en-hsse__commitments--cards .en-hsse__item{ padding: 20px; }
}

/* Editorial stagger: middle card sits 32px lower than the outer two,
   breaking the strict grid into a more deliberate composition. Subtle
   6px hover lift on all three with smooth ease. Stagger and hover only
   apply when the grid is in its 3-column layout. */
.en-hsse__commitments--cards{ align-items: start; }
.en-hsse__commitments--cards .en-hsse__item{
  transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}
.en-hsse__commitments--cards .en-hsse__item:nth-child(2){
  transform: translateY(32px);
}
.en-hsse__commitments--cards .en-hsse__item:hover{
  transform: translateY(-6px);
}
.en-hsse__commitments--cards .en-hsse__item:nth-child(2):hover{
  /* 32 - 6 = 26: middle card lifts 6px from its staggered base position. */
  transform: translateY(26px);
}
@media (max-width: 1023px){
  /* Two-column layout: drop the stagger so the second card sits flush
     with the first row again. Hover lift remains active. */
  .en-hsse__commitments--cards .en-hsse__item:nth-child(2){
    transform: none;
  }
  .en-hsse__commitments--cards .en-hsse__item:nth-child(2):hover{
    transform: translateY(-6px);
  }
}
@media (max-width: 840px){
  /* Single column: kill the stagger and hover lift entirely (touch device,
     no hover). Bumped specificity by chaining the modifier with its base
     class so this beats every desktop rule above regardless of source-order
     cascade quirks. */
  .en-hsse__commitments.en-hsse__commitments--cards .en-hsse__item,
  .en-hsse__commitments.en-hsse__commitments--cards .en-hsse__item:nth-child(2),
  .en-hsse__commitments.en-hsse__commitments--cards .en-hsse__item:hover,
  .en-hsse__commitments.en-hsse__commitments--cards .en-hsse__item:nth-child(2):hover{
    transform: none;
  }
}

/* ─── SUB-PAGES v2 : DIRECTION WITH QUOTE LAYOUT (KP) ─────────────────── */

/* Modifier: 2-col Direction layout when the section pairs portrait with the
   founder's quote callout (KP only). Portrait column fixed at 360px to
   match the original .en-leadership scale; voice column flexes. Grid is
   top-aligned so the portrait and the quote share a top edge. Name + role
   sit beneath the quote in the voice column, left-aligned to the quote.
   Compound selector raises specificity above the base
   .en-leadership__grid mobile @media at 1023px, so the 2-col layout holds
   down to its own 840px stack breakpoint. */
.en-leadership__grid.en-leadership__grid--with-quote{
  grid-template-columns: 360px 1fr;
  gap: 64px;
  align-items: start;
  max-width: 1100px;
}
/* Portrait-only article: the shared .member primitive paints a 22px
   bottom margin under .member__portrait to space the name beneath it.
   Here the name has moved to the voice column, so suppress that margin
   to keep the article flush. */
.en-leadership__grid--with-quote .en-leadership__member .member__portrait{
  margin-bottom: 0;
}
/* Inside the grid, the quote callout's standalone block margins are
   redundant: the voice column governs vertical rhythm. */
.en-leadership__grid--with-quote .en-quote-callout{
  margin: 0;
}
/* Attribution sits beneath the quote, left-aligned to the quote's left
   edge. Margin-top creates breathing room between the closing guillemet
   and the name. .member__name and .member__role inherit their base
   typography from the .member primitive. */
.en-leadership__voice{
  display: flex;
  flex-direction: column;
}
.en-leadership__attribution{
  margin-top: 36px;
}
.en-leadership__attribution .member__name{
  margin: 0 0 12px;
}
.en-leadership__attribution .member__role{
  margin: 0;
}
@media (max-width: 1023px){
  .en-leadership__grid.en-leadership__grid--with-quote{
    grid-template-columns: 280px 1fr;
    gap: 48px;
  }
  .en-leadership__attribution{ margin-top: 28px; }
}
@media (max-width: 840px){
  .en-leadership__grid.en-leadership__grid--with-quote{
    grid-template-columns: 1fr;
    gap: 32px;
    max-width: 480px;
    align-items: start;
  }
  .en-leadership__attribution{ margin-top: 24px; }
}

/* ============================================
   === ACTUALITÉS PAGE ===
   Hero embeds a featured article (image left 60% / text right 40%
   on desktop and tablet, stacks mobile) directly on the dark hero
   surface with cream type. Section 02 (Articles) is a 4-card editorial
   grid on warm cream; image inset 4px from card edges so the white
   card field reads as a hairline frame around the image. Section 03
   (Publications) is a 2-column layout (headline left, list right) of
   official communiqués and reports with hairline rust separators.
   All cards/rows are V1 non-interactive, swap-ready for Phase 2 CMS
   migration. Image area reuses the .story__placeholder text primitive
   (cross-namespace, defined under home Section 06).
   ============================================ */

/* ACTUALITÉS · warm cream surface namespace.
   Mirrors .ap-cream / .sv-cream pattern. Lets the .section primitive
   carry vertical rhythm and watermarks while the surface colour wins
   over any default background. */
.ac-cream{
  background: #f5f0ea;
  color: var(--ink);
}

/* ════════════════════════════════════════════
   FEATURED ARTICLE (in-hero)
   ════════════════════════════════════════════ */

/* ACTUALITÉS · featured article (in-hero).
   Sits below the hero headline. Transparent (no card chrome) on the
   dark hero surface so cream type reads directly off the dark bg.
   Image left 60% / text right 40% on desktop and tablet, stacks on
   mobile with image first. Cinematic stillness: no hover transforms,
   no transitions on children. V1 non-interactive (<article> root,
   link is a <span>). */
.ac-featured{
  display: grid;
  grid-template-columns: 6fr 4fr;
  gap: 32px;
  align-items: center;
  margin-top: clamp(32px, 4vw, 56px);
}
@media (max-width: 768px){
  .ac-featured{
    grid-template-columns: 1fr;
    gap: 24px;
    margin-top: 32px;
  }
}

/* ACTUALITÉS · featured media frame.
   Same dark-rust gradient + 18px hero-tier radius as grid card images
   so the featured reads as the same family. 16:9 ratio locked. */
.ac-featured__media{
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 18px;
  overflow: hidden;
  display: grid;
  place-items: center;
  padding: 24px;
  text-align: center;
  background:
    radial-gradient(420px 260px at 30% 30%, rgba(200, 146, 42, 0.20) 0%, rgba(200, 146, 42, 0) 60%),
    linear-gradient(135deg, #3d1208 0%, #5a1d0e 55%, #783214 100%);
}

/* ACTUALITÉS · featured body column.
   Cream-on-dark editorial column. Slightly larger title than the
   standard grid card (32px vs 22px) and excerpt (16px vs 15px) to
   honor the "featured" hierarchy. */
.ac-featured__body{
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.ac-featured__meta{
  display: inline-flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.ac-featured__category{
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--amber);
}

.ac-featured__date{
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: rgba(245, 240, 234, 0.6);
}

.ac-featured__title{
  font-family: var(--font-heading);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-xl), 2.4vw, var(--text-2xl));
  line-height: var(--leading-tight);
  color: #f5f0ea;
  margin: 0;
}

.ac-featured__excerpt{
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: var(--text-md);
  line-height: 1.6;
  color: rgba(245, 240, 234, 0.7);
  margin: 0;
  max-width: 56ch;
}

.ac-featured__link{
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--amber);
  margin-top: 4px;
}
.ac-featured__link svg{
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
}

/* ════════════════════════════════════════════
   SECTION 02 · ARTICLES GRID
   ════════════════════════════════════════════ */

/* ACTUALITÉS · Section 02 article grid.
   3-column desktop, 2-column tablet, 1-column mobile. With 4 cards,
   desktop renders 3 + 1 (last card hangs left on row 2); tablet
   renders a clean 2x2. */
.ac-articles-grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
}
@media (max-width: 1023px){
  .ac-articles-grid{
    grid-template-columns: repeat(2, 1fr);
    gap: 28px;
  }
}
@media (max-width: 640px){
  .ac-articles-grid{
    grid-template-columns: 1fr;
    gap: 24px;
  }
}

/* ACTUALITÉS · article card (Section 02).
   Editorial container, white field with hairline rust border at 12%
   opacity. 10px medium-card radius per locked system. Outer card
   padding is 4px so the image sits at a hairline inset from card
   edges; the inner .ac-article-card__body wraps the text content
   with its own 28px (desktop) / 20px (mobile) padding so net
   text-from-edge is 32px / 24px. Root is <article>; V1 cards are
   non-interactive editorial blocks. */
.ac-article-card{
  display: flex;
  flex-direction: column;
  background: #ffffff;
  border: 1px solid rgba(61, 18, 8, 0.12);
  border-radius: 10px;
  padding: 4px;
  transition: transform 700ms cubic-bezier(0.16, 1, 0.3, 1),
              border-color 700ms cubic-bezier(0.16, 1, 0.3, 1),
              opacity 200ms ease-out;
}

/* ACTUALITÉS · article card body wrapper.
   Holds the text block (category, date, title, excerpt, link) with
   the editorial padding tier. Kept as flex column so the link can
   anchor to the bottom via margin-top: auto on .ac-article-card__link. */
.ac-article-card__body{
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 28px;
}
@media (max-width: 640px){
  .ac-article-card__body{
    padding: 20px;
  }
}

/* ACTUALITÉS · article card image frame.
   16:9 aspect, 18px hero-tier radius. Dark rust gradient with a soft
   amber radial glow stands in for the eventual editorial photography.
   Sits at the top of the card with a 4px hairline inset from card
   edges (provided by .ac-article-card outer padding). overflow:hidden
   clips the inner placeholder/img scale on hover. */
.ac-article-card__image{
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 18px;
  overflow: hidden;
  display: grid;
  place-items: center;
  padding: 24px;
  text-align: center;
  background:
    radial-gradient(420px 260px at 30% 30%, rgba(200, 146, 42, 0.20) 0%, rgba(200, 146, 42, 0) 60%),
    linear-gradient(135deg, #3d1208 0%, #5a1d0e 55%, #783214 100%);
}
/* Direct child (placeholder div now, future <img>) carries the slow
   scale on hover. Both placeholder and a future image element inherit
   this transition cleanly. */
.ac-article-card__image > *{
  transition: transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}

/* ACTUALITÉS · category tag.
   Amber DM Mono caps, sits above the date in the meta row. */
.ac-article-card__category{
  display: block;
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--amber);
  margin-bottom: 8px;
}

/* ACTUALITÉS · date.
   Rust at 60% opacity, DM Mono caps. Sits between the category and
   the title. */
.ac-article-card__date{
  display: block;
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: rgb(from var(--color-dark) r g b / 0.6);
  margin-bottom: 16px;
}

/* ACTUALITÉS · article title.
   Poppins 300 in rust brown. Tight line-height for editorial weight. */
.ac-article-card__title{
  font-family: var(--font-heading);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-lg), 1.6vw, var(--text-xl));
  line-height: var(--leading-snug);
  color: var(--color-dark);
  margin: 0 0 16px;
}

/* ACTUALITÉS · article excerpt.
   Poppins 400 at 70% rust on light. Clamped to 2 lines so card
   heights stay editorially aligned across the grid. */
.ac-article-card__excerpt{
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: clamp(var(--text-sm), 1vw, var(--text-md));
  line-height: 1.6;
  color: rgb(from var(--color-dark) r g b / 0.7);
  margin: 0 0 20px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ACTUALITÉS · "LIRE LA SUITE" tertiary text link.
   Editorial signal only. V1 is non-interactive (rendered as a span)
   pending Phase 2 detail pages. Amber, DM Mono caps with arrow. */
.ac-article-card__link{
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--amber);
}
.ac-article-card__link svg{
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
}

/* ACTUALITÉS · card hover (pointer-capable devices only).
   Subtle lift, image scale, border deepens. 700ms cinematic ease.
   Mobile and other touch contexts skip this entirely. */
@media (hover: hover){
  .ac-article-card:hover{
    transform: translateY(-4px);
    border-color: rgba(61, 18, 8, 0.25);
  }
  .ac-article-card:hover .ac-article-card__image > *{
    transform: scale(1.02);
  }
}

/* ACTUALITÉS · touch feedback.
   Brief opacity dim on tap. No translate or scale on mobile to avoid
   jank. Pairs with the @media (hover: hover) block above so every
   hover state has a touch equivalent. */
.ac-article-card:active{
  opacity: 0.92;
  transition-duration: 200ms;
}

/* ════════════════════════════════════════════
   SECTION 03 · PUBLICATIONS LIST
   ════════════════════════════════════════════ */

/* ACTUALITÉS · publications layout.
   2-column desktop: headline left (~33% with a 280px floor), list
   right (~67%) with a 64px column gap. Stacks single-column at 768
   so the headline reads above the list on tablet portrait and mobile. */
.ac-publications{
  display: grid;
  grid-template-columns: minmax(280px, 1fr) 2fr;
  gap: 64px;
  align-items: start;
}
@media (max-width: 1023px){
  .ac-publications{
    gap: 48px;
  }
}
@media (max-width: 768px){
  .ac-publications{
    grid-template-columns: 1fr;
    gap: 32px;
  }
}
.ac-publications__headline{
  margin: 0;
}

/* ACTUALITÉS · publications list.
   Stack of 4 rows with hairline rust separators. Each row carries a
   border-top; the list itself carries a border-bottom for the cap so
   visually we get N+1 hairlines (top of each row + one closing the
   list). */
.ac-publications-list{
  display: flex;
  flex-direction: column;
  border-bottom: 1px solid rgba(61, 18, 8, 0.12);
}

/* ACTUALITÉS · publication row.
   Title takes available width, date sits to the right, arrow at the
   far right. 24px vertical padding on desktop with a slight horizontal
   negative margin so the hover bg fill extends just past the list
   column edges and reads as a full-row state. Mobile wraps date+arrow
   below the title (title takes 100% on row 1, date+arrow share row 2).
   V1 non-interactive (root <div>). */
.ac-publication-row{
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 24px 16px;
  margin: 0 -16px;
  border-top: 1px solid rgba(61, 18, 8, 0.12);
  transition: background-color 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
@media (max-width: 640px){
  .ac-publication-row{
    flex-wrap: wrap;
    gap: 8px 16px;
    padding: 20px 12px;
    margin: 0 -12px;
  }
}

/* ACTUALITÉS · publication row title.
   Poppins 400 in rust, 18px desktop / 16px mobile. Takes the available
   width on desktop; full-width on mobile so date+arrow drop below. */
.ac-publication-row__title{
  flex: 1 1 auto;
  font-family: var(--font-heading);
  font-weight: var(--weight-regular);
  font-size: clamp(var(--text-md), 1.2vw, var(--text-lg));
  line-height: 1.4;
  color: var(--color-dark);
  margin: 0;
  transition: color 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
@media (max-width: 640px){
  .ac-publication-row__title{
    flex: 1 1 100%;
  }
}

/* ACTUALITÉS · publication row date.
   DM Mono caps, rust at 60% opacity. Sits to the right of the title
   on desktop, below the title on mobile (paired with the arrow). */
.ac-publication-row__date{
  flex: 0 0 auto;
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: rgb(from var(--color-dark) r g b / 0.6);
  white-space: nowrap;
}

/* ACTUALITÉS · publication row arrow.
   Amber 16px arrow at the far right. Translates +4px on hover to
   signal directionality. On mobile, sits at the end of the date+arrow
   row (margin-left:auto pushes it to the right). */
.ac-publication-row__arrow{
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  color: var(--amber);
  transition: transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
.ac-publication-row__arrow svg{
  width: 16px;
  height: 16px;
}
@media (max-width: 640px){
  .ac-publication-row__arrow{
    margin-left: auto;
  }
}

/* ACTUALITÉS · publication row hover (pointer-capable devices only).
   Subtle rust 4% bg fill, arrow nudges right, title shifts to amber.
   700ms cinematic ease pairs with the rest of the page. */
@media (hover: hover){
  .ac-publication-row:hover{
    background-color: rgba(61, 18, 8, 0.04);
  }
  .ac-publication-row:hover .ac-publication-row__title{
    color: var(--amber);
  }
  .ac-publication-row:hover .ac-publication-row__arrow{
    transform: translateX(4px);
  }
}

/* ACTUALITÉS · publication row touch feedback.
   Mirrors the hover bg fill in 200ms for tap states. Title color and
   arrow translate are skipped on touch to avoid sticky highlights
   after the user lifts the finger. */
.ac-publication-row:active{
  background-color: rgba(61, 18, 8, 0.04);
  transition-duration: 200ms;
}

/* === END ACTUALITÉS === */

/* ══════════════════════════════════════════════════════════════════════════
   SECTION 03 : BOUSSOLE. Une direction claire
   Pinned cream stage. The tanker scrolls vertically through a fixed
   viewport while three text blocks fade in and out at scroll thresholds.
   The pinned wrapper itself never animates. Only its children move.
   Single master timeline, scrubbed (see main.js).
   ══════════════════════════════════════════════════════════════════════════ */
/* ──────────────────────────────────────────────────────────────────────
   Shared cream canvas for sections 03 (boussole) + 04 (écosystème).
   Paints ONE continuous topography image across both sections via a
   single ::before so the previous seam between two independent
   pseudo-elements is gone. Mask gradient fades the texture out just
   above the OKAPI wordmark at the top of the écosystème spine. The
   wrapper is transparent to ScrollTrigger pinning : the .pin-spacer
   that GSAP injects around .boussole still lives inside this wrapper,
   pinning works unchanged. .boussole and .ecosysteme themselves are
   declared with background: transparent so the wrapper cream + topo
   reads through them. Tunable mask stops if the fade lands too high
   or too low after browser verification. */
.topography-wrapper{
  position: relative;
  background-color: #F5F2EC;       /* Same cream tone that used to live
                                      on .boussole + .ecosysteme. */
  overflow: hidden;
}
.topography-wrapper::before{
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("hero/topography%20ship.png");
  background-position: center top;
  background-repeat: no-repeat;             /* DO NOT tile. */
  background-size: 100vw auto;              /* Image scales to the full
                                               viewport width edge-to-
                                               edge while preserving its
                                               natural aspect ratio.
                                               Pairs with background-
                                               attachment:fixed below
                                               (vw resolves against the
                                               viewport, matching the
                                               fixed attachment's frame
                                               of reference). No gutters
                                               on wide displays. */
  background-attachment: fixed;             /* Anchor the texture to
                                               the VIEWPORT so it does
                                               not crawl off-screen
                                               while the user scrolls
                                               through the boussole pin
                                               range. The pseudo itself
                                               still spans the full
                                               wrapper, but the painted
                                               image stays viewport-
                                               fixed. GSAP pins .boussole
                                               (an inner element, not an
                                               ancestor of this wrapper),
                                               so no transform is applied
                                               up the containing chain
                                               and position:fixed-style
                                               attachment behaves
                                               correctly. */
  opacity: 0.13;
  pointer-events: none;
  z-index: 0;
  /* Mask anchored to the wrapper bounds. With the real viewport
     height (~1080px) and GSAP's pin-spacer expanding boussole to
     400vh, the wrapper measures ~5800px tall and the OKAPI wordmark
     sits around 77% of that height. Stops below place the fully-
     transparent point AT the OKAPI position with a soft 16pp ramp. */
  -webkit-mask-image: linear-gradient(to bottom,
    rgba(0,0,0,1) 0%,
    rgba(0,0,0,1) 62%,
    rgba(0,0,0,0) 78%);
  mask-image: linear-gradient(to bottom,
    rgba(0,0,0,1) 0%,
    rgba(0,0,0,1) 62%,
    rgba(0,0,0,0) 78%);
}

.boussole{
  position: relative;
  width: 100%;
  height: 100vh;                   /* Visible viewport size. ScrollTrigger
                                      pinSpacing extends scroll length to
                                      300vh via end:"+=300%". */
  background-color: transparent;   /* Cream + topo now painted by the
                                      shared .topography-wrapper that
                                      spans sections 03 + 04. */
  overflow: hidden;
}

.boussole__stage{
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

/* Traveling tanker. Oversized on purpose so the hull crosses through
   the headline's letterforms when the timeline reaches its midpoint.
   X centering only: the GSAP fromTo owns yPercent. Mixing translateY
   in CSS with GSAP yPercent stacks the offsets and breaks the scrub. */
.boussole__tanker{
  position: absolute;
  top: 0;
  left: 50%;
  width: 775px;
  height: auto;
  transform: translateX(-50%);
  z-index: 3;                              /* Above the text blocks. */
  filter: drop-shadow(0 60px 120px rgba(58, 30, 18, 0.18));
  will-change: transform;
  pointer-events: none;
  user-select: none;
}

/* Left column wrapper : kicker + headline stacked as a single unit,
   vertically centered on the viewport, anchored 8vw from the left.
   The wrapper owns positioning so kicker and headline read as one
   typographic block instead of two unrelated absolutely-placed items. */
.boussole__left{
  position: absolute;
  top: 50%;
  left: 8vw;
  transform: translateY(-50%);
  z-index: 1;                              /* Behind the tanker. */
  max-width: 420px;
}

/* Kicker : DM Mono micro-label sitting directly above the headline. */
.boussole__kicker{
  display: block;
  font-family: var(--font-label);
  font-size: var(--text-xs);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgb(from var(--color-dark) r g b / 0.6);
  opacity: 0;
  margin: 0 0 1.25em 0;                    /* Tight gap to headline. */
  white-space: nowrap;
}

/* Headline : sits flush below the kicker inside the left wrapper. */
.boussole__headline{
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-3xl), 7vw, var(--text-5xl));
  line-height: 0.95;
  letter-spacing: var(--track-tight-md);
  color: var(--color-dark);
  text-align: left;
  margin: 0;
  opacity: 0;
}

/* Copy : right column, vertically centered, right-aligned. Mirrors
   the left wrapper's vertical anchor so both columns read at the
   same eye-line while the tanker travels through the middle. */
.boussole__copy{
  position: absolute;
  top: 50%;
  right: 8vw;
  transform: translateY(-50%);
  z-index: 1;                              /* Behind the tanker. */
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  font-size: var(--text-md);
  line-height: 1.6;
  color: rgb(from var(--color-dark) r g b / 0.8);
  text-align: right;
  max-width: 380px;
  margin: 0;
  opacity: 0;
}

/* Mobile (<=767px). The desktop pinned-scroll choreography is translated
   to a single-column layout: the text block (kicker + headline + copy)
   sits vertically centered in the viewport and is pinned for the section's
   scroll duration ; the tanker scrolls vertically over it, entering from
   above the section, passing through the centered text region (overlaying
   it via z-index), and exiting below. The pin and tanker translation are
   owned by a gsap.matchMedia branch in main.js gated to
   (max-width: 767px) and (prefers-reduced-motion: no-preference).
   The tanker carries a subtle drop-shadow so the layering reads clearly
   when it crosses through the headline. */
@media (max-width: 767px){
  .boussole{
    height: 100vh;
    padding: 0;
    overflow: hidden;
  }
  .boussole__stage{
    position: relative;
    height: 100vh;
    width: 100%;
    overflow: hidden;
    display: grid;
    align-content: center;
    justify-items: stretch;
    padding: 0 24px;
    gap: 16px;
  }
  .boussole__tanker{
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 76.8vw;
    max-width: 384px;
    height: auto;
    margin: 0;
    align-self: auto;
    z-index: 2;
    filter: drop-shadow(0 18px 36px rgba(58, 30, 18, 0.22));
    will-change: transform;
    pointer-events: none;
    user-select: none;
  }
  .boussole__left,
  .boussole__kicker,
  .boussole__headline,
  .boussole__copy{
    position: relative;
    top: auto;
    right: auto;
    left: auto;
    transform: none;
    text-align: left;
    max-width: 100%;
    opacity: 1;
    z-index: 1;
  }
  .boussole__kicker{
    display: block;
    margin: 0 0 8px 0;
  }
  .boussole__headline{
    font-size: clamp(var(--text-2xl), 9vw, var(--text-3xl));
    margin: 0;
  }
  .boussole__copy{
    margin: 0;
  }
}

/* Reduced motion : same stacked layout as mobile, applied at any width.
   The pin/scrub block in main.js is gated on the desktop matchMedia
   query and its prefers-reduced-motion:no-preference branch, so this
   rule on its own is enough to keep the section fully readable. */
@media (prefers-reduced-motion: reduce){
  .boussole{
    height: auto;
    padding: 18vh 8vw 14vh;
    overflow: visible;
  }
  .boussole__stage{
    height: auto;
    overflow: visible;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 5vh;
  }
  .boussole__tanker{
    position: relative;
    top: auto;
    left: auto;
    transform: none;
    align-self: center;
    max-width: 320px;
    width: 100%;
    filter: drop-shadow(0 28px 48px rgba(58, 30, 18, 0.16));
  }
  .boussole__left,
  .boussole__kicker,
  .boussole__headline,
  .boussole__copy{
    position: relative;
    top: auto;
    right: auto;
    left: auto;
    transform: none;
    text-align: left;
    max-width: 100%;
    opacity: 1;
  }
  .boussole__kicker{
    margin: 0;
  }
}
/* === END BOUSSOLE === */

/* ════════════════════════════════════════════════════════════════════════
   UNIVERSAL HEADER RHYTHM
   8px between kicker (eyebrow) and heading.
   16px between heading and description (subheading / lede).
   Applied to every header template on the site so the cadence is
   identical regardless of where the kicker / heading / description block
   lives. The .section-head template is already covered by the
   :has(.section-head__kicker) rules earlier in this stylesheet.
   ════════════════════════════════════════════════════════════════════════ */

/* Page hero (a-propos / services / actualites main heroes,
   plus entity sub-pages whose chassis reuses .page-hero__inner). */
.page-hero .page-hero__inner{ gap: 0; }
.page-hero .page-hero__inner > .label{ margin: 0 0 8px 0; }
.page-hero .page-hero__inner > .page-hero__head{ margin: 0 0 8px 0; }
.page-hero .page-hero__inner > .headline{ margin: 0 0 16px 0; }
.page-hero .page-hero__inner > .page-hero__subheading{ margin: 0; }
.page-hero .page-hero__inner > .en-sub-location{ margin-top: 32px; }

/* Entity hero (entites.html landing page uses .entity-hero--index with
   a head-row; entity sub-pages such as kp.html use .entity-hero with the
   simpler kicker span). Both share .entity-hero__headline and __copy. */
.entity-hero .entity-hero__head-row{ margin: 0 0 8px 0; }
.entity-hero .entity-hero__kicker{ margin: 0 0 8px 0; }
.entity-hero--index .entity-hero__kicker{ margin: 0; }
.entity-hero .entity-hero__headline{ margin: 0 0 16px 0; }
.entity-hero .entity-hero__copy{ margin: 0; }

/* Boussole (home page : kicker + headline live in the left column;
   the description lives in a separate right column so the 16px rule
   does not apply to that pair). */
.boussole__kicker{ margin: 0 0 8px 0; }

/* Home hero (.hero) carries no kicker, only heading + subline. */
.hero .stage > .headline{ margin-bottom: 16px; }
.hero .stage > .subline{ margin: 0; }

/* ─── PILOT : KAMINO FOUR-NODE FLOW DIAGRAM ──────────────────────────────
   Horizontal four-icon flow scoped to the Kamino entity sub-page.
   Each .en-flow__node carries a thin amber icon circle, an uppercase
   label, and a short descriptor. Connectors run a dotted amber line
   with a small filled dot between nodes; the row terminates with an
   amber arrow. Mobile (<=767px) stacks the row vertically with the
   dotted line and arrow rotating to run downward. All selectors are
   .en-flow* and used only on entites/kamino.html, so no other page
   inherits these rules. */
.en-flow{
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 0;
}
.en-flow__node{
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 0 16px;
}
.en-flow__icon{
  width: 72px;
  height: 72px;
  border-radius: 50%;
  border: 1px solid var(--color-accent-orange);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-accent-orange);
  margin-bottom: 24px;
  flex-shrink: 0;
}
.en-flow__icon svg{
  width: 28px;
  height: 28px;
  stroke-width: 2;
}
.en-flow__label{
  font-family: var(--font-heading);
  font-weight: var(--weight-medium);
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 8px;
  line-height: var(--leading-tight);
}
.en-flow__desc{
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  color: rgb(from var(--color-dark) r g b / 0.7);
  margin: 0;
  max-width: 24ch;
}
.en-flow__connector{
  flex: 0 0 64px;
  height: 72px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.en-flow__connector::before{
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  border-top: 1px dotted var(--color-accent-orange);
}
.en-flow__dot{
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-accent-orange);
  position: relative;
  z-index: 1;
}
.en-flow__arrow{
  flex: 0 0 48px;
  height: 72px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  color: var(--color-accent-orange);
  position: relative;
}
.en-flow__arrow::before{
  content: '';
  position: absolute;
  left: -16px;
  right: 16px;
  top: 50%;
  border-top: 1px dotted var(--color-accent-orange);
}
.en-flow__arrow svg{
  width: 20px;
  height: 20px;
  stroke-width: 2;
  position: relative;
  z-index: 1;
}

@media (max-width: 767px){
  .en-flow{
    flex-direction: column;
    align-items: center;
    gap: 0;
    margin-top: 40px;
  }
  .en-flow__node{
    flex: none;
    padding: 0;
    max-width: 32ch;
  }
  .en-flow__connector{
    flex: none;
    width: 72px;
    height: 48px;
  }
  .en-flow__connector::before{
    border-top: 0;
    border-left: 1px dotted var(--color-accent-orange);
    left: 50%;
    right: auto;
    top: 0;
    bottom: 0;
    width: 0;
    transform: translateX(-50%);
  }
  .en-flow__arrow{
    flex: none;
    width: 72px;
    height: 48px;
    justify-content: center;
    align-items: flex-end;
  }
  .en-flow__arrow::before{
    border-top: 0;
    border-left: 1px dotted var(--color-accent-orange);
    left: 50%;
    right: auto;
    top: 0;
    bottom: 16px;
    width: 0;
    transform: translateX(-50%);
  }
  .en-flow__arrow svg{
    transform: rotate(90deg);
  }
}

