/* Fichier généré — modifier les sources dans assets/css/, puis regrouper */

/* ---- fonts.css ---- */
/* =============================================================
   MTS — Polices auto-hébergées
   General Sans (Fontshare, ITF Free Font License) et IBM Plex
   Sans / Mono (SIL Open Font License 1.1) : les deux licences
   autorisent l'hébergement local.

   Servies depuis le domaine du site, elles ne coûtent plus deux
   résolutions DNS, deux poignées de main TLS et deux feuilles de
   style bloquantes avant le premier rendu. Seuls les sous-ensembles
   latin et latin-ext sont embarqués : le site est en français et en
   anglais, le cyrillique et le grec ne servaient jamais.
   ============================================================= */

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'General Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/general-sans-500.woff2') format('woff2');
}

@font-face {
  font-family: 'General Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/general-sans-600.woff2') format('woff2');
}

@font-face {
  font-family: 'General Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/general-sans-700.woff2') format('woff2');
}

/* ---- tokens.css ---- */
/* =============================================================
   MTS — Manufacturing Technology System
   Design tokens

   Univers : le schéma d'implantation d'îlot — le document que MTS
   produit et que ses clients lisent tous les jours. Trait fin,
   violet de marque sur papier porcelaine, orange en signalétique.
   Mode clair exclusivement, aucune variante sombre.
   ============================================================= */

:root {
  /* ---------- Couleur : primitives ----------
     Violet et orange sont relevés au pixel sur le logo MTS.        */
  --color-porcelain: #F7F7F4;   /* fond principal — blanc cassé froid */
  --color-paper:     #FFFFFF;   /* surfaces, cards */
  --color-ink:       #15181C;   /* texte principal — 18.5:1 */
  --color-slate:     #5B6470;   /* texte secondaire — 5.6:1 */
  --color-mist:      #DADFE3;   /* hairlines, séparateurs */

  /* Violet de marque — 10.5:1 sur porcelaine : il porte le texte. */
  --color-violet:      #472583;
  --color-violet-deep: #341A61;

  /* Orange de marque — 3.3:1 seulement. Interdit en texte courant :
     réservé aux aplats, aux traits et aux titres de grande taille. */
  --color-orange:      #E0610E;
  /* Orange assombri — 5.5:1 sur porcelaine, 5.9:1 en fond sous du blanc.
     C'est celui-ci, et lui seul, qui a le droit de porter du texte.  */
  --color-orange-deep: #A8460A;
  /* Survol du bouton signal : plus sombre encore, 7,4:1 sous du porcelaine. */
  --color-orange-darkest: #8A3808;

  /* Dérivés de travail */
  --color-violet-wash: #F1EEF7;
  --color-orange-wash: #FBF0E8;
  --color-ink-06:    rgba(21, 24, 28, 0.06);
  --color-ink-12:    rgba(21, 24, 28, 0.12);
  --color-violet-08: rgba(71, 37, 131, 0.08);
  --color-violet-16: rgba(71, 37, 131, 0.16);
  --color-violet-32: rgba(71, 37, 131, 0.32);

  /* ---------- Couleur : sémantique ---------- */
  --bg-page:        var(--color-porcelain);
  --bg-surface:     var(--color-paper);
  --bg-wash:        var(--color-violet-wash);
  --text-primary:   var(--color-ink);
  --text-secondary: var(--color-slate);
  --text-accent:    var(--color-violet);
  --border-hair:    var(--color-mist);
  --border-strong:  var(--color-ink-12);
  --focus-ring:     var(--color-violet);

  /* ---------- Typographie ----------
     General Sans (géométrique, resserré) pour les titres,
     IBM Plex Sans pour la lecture, IBM Plex Mono pour les repères
     de poste, les cotes et les références.                         */
  --font-display: "General Sans", "Helvetica Neue", Arial, sans-serif;
  --font-body:    "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --text-display-1: clamp(2.75rem, 6.4vw, 5.5rem);
  --text-display-2: clamp(2rem, 4vw, 3.25rem);
  --text-h3:        clamp(1.375rem, 2.2vw, 1.75rem);
  --text-h4:        clamp(1.125rem, 1.6vw, 1.3125rem);
  --text-body-lg:   1.125rem;
  --text-body:      1rem;
  --text-small:     0.9375rem;
  --text-mono:      0.8125rem;
  --text-mono-sm:   0.6875rem;

  --leading-tight:   1.06;
  --leading-snug:    1.22;
  --leading-normal:  1.6;
  --leading-relaxed: 1.72;

  --tracking-display:   -0.022em;
  --tracking-heading:   -0.012em;
  --tracking-body:       0;
  --tracking-mono:       0.08em;
  --tracking-mono-wide:  0.16em;

  /* ---------- Espacement (échelle 8) ---------- */
  --space-1:  0.25rem;
  --space-2:  0.5rem;
  --space-3:  0.75rem;
  --space-4:  1rem;
  --space-5:  1.5rem;
  --space-6:  2rem;
  --space-7:  2.5rem;
  --space-8:  3rem;
  --space-10: 4rem;
  --space-12: 5rem;
  --space-14: 6rem;
  --space-16: 7.5rem;
  --space-20: 10rem;

  --section-y:       clamp(var(--space-12), 11vw, var(--space-20));
  --section-y-tight: clamp(var(--space-10), 8vw, var(--space-14));

  /* ---------- Grille & gouttières ---------- */
  --shell-max: 1440px;
  --shell-pad: clamp(1.25rem, 5vw, 5rem);
  --gutter:    clamp(1rem, 2.2vw, 2rem);
  --measure:   62ch;
  --measure-narrow: 46ch;

  /* ---------- Rayon ----------
     Quasi nul : un plan d'implantation n'a pas de coins arrondis.  */
  --radius-none: 0;
  --radius-sm:   2px;

  /* ---------- Élévation ----------
     Ombres dures, décalées : un calque posé sur la planche,
     jamais le flou diffus des cards SaaS.                          */
  --shadow-lift:        2px 2px 0 var(--color-ink-12);
  --shadow-lift-violet: 3px 3px 0 var(--color-violet-16);
  --shadow-inset-hair:  inset 0 0 0 1px var(--border-hair);

  /* ---------- Traits ---------- */
  --hair:        1px solid var(--border-hair);
  --hair-ink:    1px solid var(--border-strong);
  --rule-violet: 1px solid var(--color-violet-32);

  /* ---------- Mouvement ---------- */
  --ease-precise:  cubic-bezier(0.65, 0, 0.35, 1);   /* mécanique */
  --ease-settle:   cubic-bezier(0.16, 1, 0.3, 1);    /* amorti */
  --ease-out-soft: cubic-bezier(0.33, 1, 0.68, 1);

  --dur-fast:   180ms;
  --dur-base:   320ms;
  --dur-slow:   620ms;
  --dur-reveal: 900ms;

  /* ---------- Couches ---------- */
  --z-grid:    0;
  --z-content: 1;
  --z-header:  60;
  --z-menu:    70;
  --z-cursor:  90;
  --z-loader:  100;
}

/* ---- base.css ---- */
/* =============================================================
   MTS — Reset & socle typographique
   ============================================================= */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Aucun overflow global ici : sur la racine, `hidden` déplace le conteneur
     de défilement sur <body> et `clip` empêche purement et simplement de
     faire défiler la page. Les débordements horizontaux sont contenus là où
     ils naissent — .hero, .page-head, .rail et .notfound clippent déjà. */
}
/* Lenis pilote le scroll ; on neutralise le smooth natif quand il est actif */
html.lenis { scroll-behavior: auto; }
html.lenis body { min-height: 100%; }
html.lenis-stopped { overflow: hidden; }

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  letter-spacing: var(--tracking-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "kern" 1, "liga" 1;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--text-primary);
  text-wrap: balance;
}

h1 {
  font-size: var(--text-display-1);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
}
h2 {
  font-size: var(--text-display-2);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-display);
}
h3 {
  font-size: var(--text-h3);
  line-height: 1.28;
  letter-spacing: var(--tracking-heading);
}
h4 {
  font-size: var(--text-h4);
  line-height: 1.34;
  letter-spacing: var(--tracking-heading);
}

p { margin: 0; text-wrap: pretty; }

a {
  color: inherit;
  text-decoration: none;
}

ul, ol { margin: 0; padding: 0; list-style: none; }

img, video, svg {
  display: block;
  max-width: 100%;
  height: auto;
}

button, input, textarea, select {
  font: inherit;
  color: inherit;
  margin: 0;
}

button {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

strong { font-weight: 600; }

::selection {
  background: var(--color-violet);
  color: var(--color-porcelain);
}

/* ---------- Focus : jamais supprimé, toujours remplacé ---------- */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* ---------- Utilitaires d'accessibilité ---------- */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  z-index: calc(var(--z-loader) + 1);
  padding: var(--space-3) var(--space-5);
  background: var(--color-violet);
  color: var(--color-porcelain);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  transform: translateY(calc(-100% - var(--space-5)));
  transition: transform var(--dur-fast) var(--ease-precise);
}
.skip-link:focus-visible { transform: translateY(0); }

/* ---------- Typographie de service ---------- */
.lede {
  font-size: var(--text-body-lg);
  line-height: var(--leading-relaxed);
  color: var(--text-secondary);
  max-width: var(--measure);
}

.prose p + p { margin-top: var(--space-5); }
.prose {
  color: var(--text-secondary);
  max-width: var(--measure);
}
.prose strong { color: var(--text-primary); }

/* Le label mono : réservé aux vraies légendes et séquences */
.mono-label {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  font-weight: 500;
  letter-spacing: var(--tracking-mono-wide);
  text-transform: uppercase;
  color: var(--color-violet);
}
.mono-label--slate { color: var(--text-secondary); }
.mono-label--sm { font-size: var(--text-mono-sm); }

/* Un repère vide ne laisse pas de trou : toutes les réalisations n'ont pas
   un nom de client publiable, et la ligne de méta doit rester propre. */
.mono-label:empty { display: none; }

/* ---- layout.css ---- */
/* =============================================================
   MTS — Structure : coquille, grille d'implantation, repères de calage
   ============================================================= */

.shell {
  width: 100%;
  max-width: var(--shell-max);
  margin-inline: auto;
  padding-inline: var(--shell-pad);
}
.shell--narrow { max-width: 1080px; }

/* ---------- Sections ---------- */
.section {
  position: relative;
  padding-block: var(--section-y);
}
.section--tight { padding-block: var(--section-y-tight); }
.section--wash { background: var(--bg-wash); }
.section--paper { background: var(--bg-surface); }
.section--ruled { border-top: var(--hair); }

/* ---------- En-tête de section : le cartouche ----------
   Numéro mono + titre + intro, aligné sur la grille du plan.        */
.section-head {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr;
  margin-bottom: var(--space-12);
}
.section-head__meta {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: var(--rule-violet);
}
.section-head__title { max-width: 20ch; }
.section-head__intro { max-width: var(--measure); }

@media (min-width: 900px) {
  .section-head {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: end;
    column-gap: var(--space-10);
  }
  .section-head__meta { grid-column: 1 / -1; }
}

/* ---------- Grille d'implantation ----------
   Filigrane de papier à plan. Confinée aux sections qui la méritent :
   hero et charnières. Jamais sous les cards ou les formulaires.      */
.layout-grid {
  position: absolute;
  inset: 0;
  z-index: var(--z-grid);
  pointer-events: none;
  background-image:
    linear-gradient(to right,  var(--color-violet-08) 1px, transparent 1px),
    linear-gradient(to bottom, var(--color-violet-08) 1px, transparent 1px);
  background-size: 88px 88px;
  -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 45%, #000 20%, transparent 78%);
          mask-image: radial-gradient(ellipse 90% 70% at 50% 45%, #000 20%, transparent 78%);
}
.layout-grid--fine { background-size: 22px 22px; opacity: 0.55; }

/* ---------- Repères de calage ----------
   Marques d'angle façon registration marks d'une planche imprimée.   */
.reg-marks {
  position: absolute;
  inset: clamp(0.75rem, 2vw, 1.75rem);
  z-index: var(--z-grid);
  pointer-events: none;
}
.reg-marks::before,
.reg-marks::after {
  content: "";
  position: absolute;
  width: 26px;
  height: 26px;
  border-color: var(--color-violet-32);
  border-style: solid;
}
.reg-marks::before {
  top: 0; left: 0;
  border-width: 1px 0 0 1px;
}
.reg-marks::after {
  bottom: 0; right: 0;
  border-width: 0 1px 1px 0;
}
/* Second jeu pour les deux angles restants */
.reg-marks span::before,
.reg-marks span::after {
  content: "";
  position: absolute;
  width: 26px;
  height: 26px;
  border-color: var(--color-violet-32);
  border-style: solid;
}
.reg-marks span::before {
  top: 0; right: 0;
  border-width: 1px 1px 0 0;
}
.reg-marks span::after {
  bottom: 0; left: 0;
  border-width: 0 0 1px 1px;
}

/* ---------- En-tête de page intérieure ----------
   Partagé par Services, Réalisations, L'entreprise, Contact et 404.  */
.page-head {
  position: relative;
  padding-block: calc(var(--space-20) + var(--space-6)) var(--section-y-tight);
  border-bottom: var(--hair);
  overflow: hidden;
}
.page-head__inner {
  position: relative;
  z-index: var(--z-content);
  display: grid;
  gap: var(--space-6);
}
@media (min-width: 900px) {
  .page-head__inner {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    align-items: end;
    column-gap: var(--space-12);
  }
}
.page-head__eyebrow {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding-bottom: var(--space-5);
  border-bottom: var(--rule-violet);
  margin-bottom: var(--space-4);
}
/* Seule l'accueil porte le display-1 : les pages intérieures se tiennent
   un cran en dessous, ce qui installe une vraie hiérarchie entre elles. */
.page-head__title {
  font-size: var(--text-display-2);
  max-width: 18ch;
}
.page-head__lede { max-width: var(--measure); }

/* ---------- Colonnes réutilisables ---------- */
.split {
  display: grid;
  gap: var(--space-10);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-12); }
  .split--aside  { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
  .split--offset { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); }
}

/* ---------- Bandeau de métriques ---------- */
.metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: var(--hair);
  border-left: var(--hair);
}
@media (min-width: 800px) {
  .metrics { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.metric {
  padding: var(--space-7) var(--space-5);
  border-right: var(--hair);
  border-bottom: var(--hair);
}
.metric__value {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2rem, 3.6vw, 3rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: var(--tracking-display);
  color: var(--color-violet);
  font-variant-numeric: tabular-nums;
}
.metric__unit {
  font-size: 0.5em;
  font-weight: 500;
  color: var(--text-secondary);
  margin-left: 0.2em;
  letter-spacing: 0;
}
.metric__label {
  display: block;
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  letter-spacing: var(--tracking-mono-wide);
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* La légende de figure, ancrée sur l'image comme sur une planche */
.fig-tag {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 2;
  padding: var(--space-2) var(--space-4);
  background: var(--color-porcelain);
  border-top: var(--rule-violet);
  border-right: var(--rule-violet);
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  letter-spacing: var(--tracking-mono-wide);
  text-transform: uppercase;
  color: var(--color-violet);
}

/* =============================================================
   Process — séquence réelle, donc numérotée
   ============================================================= */
.process { display: grid; gap: 0; }
.process__step {
  position: relative;
  display: grid;
  gap: var(--space-4);
  padding-block: var(--space-8);
  padding-left: var(--space-7);
  border-top: var(--hair);
  align-items: start;
}
.process__step:last-child { border-bottom: var(--hair); }
@media (min-width: 860px) {
  .process__step {
    grid-template-columns: 6rem minmax(0, 22ch) minmax(0, 1fr);
    gap: var(--space-8);
    align-items: baseline;
  }
}
.process__index {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono-wide);
  color: var(--color-violet);
  font-variant-numeric: tabular-nums;
}

/* ---------- Déroulé animé étape par étape ----------
   Un rail vertical relie les étapes et un repère se remplit à mesure que
   la lecture avance. Le texte, lui, reste toujours à pleine lisibilité :
   on n'atténue jamais du contenu pour faire joli.                       */
.process--sequenced .process__step::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--color-violet-16);
}
.process--sequenced .process__step:first-child::before { top: 50%; }
.process--sequenced .process__step:last-child::before  { bottom: 50%; }

/* Le repère : carré creux, rempli quand l'étape est atteinte */
.process--sequenced .process__step::after {
  content: "";
  position: absolute;
  left: 0;
  top: calc(var(--space-8) + 0.32em);
  width: 11px;
  height: 11px;
  background: var(--bg-page);
  border: 1px solid var(--color-violet-32);
  transition:
    background-color var(--dur-base) var(--ease-precise),
    border-color var(--dur-base) var(--ease-precise),
    transform var(--dur-base) var(--ease-settle);
}
.process--sequenced .process__step.is-active::after {
  background: var(--color-orange);
  border-color: var(--color-orange-deep);
  transform: scale(1.25);
}
.process--sequenced .process__step.is-active .process__index { color: var(--color-orange-deep); }
.process--sequenced .process__index { transition: color var(--dur-base) var(--ease-precise); }

@media (min-width: 860px) {
  .process--sequenced .process__step { padding-left: var(--space-8); }
}
.process__text {
  color: var(--text-secondary);
  font-size: var(--text-small);
  line-height: var(--leading-relaxed);
  max-width: var(--measure);
}

/* ---------- Cartouche de specs ----------
   Le tableau technique en marge : vraies données, pas de décor.      */
.spec-table {
  border-top: var(--hair-ink);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
}
.spec-table__row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-3) 0;
  border-bottom: var(--hair);
}
.spec-table__key {
  color: var(--text-secondary);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  font-size: var(--text-mono-sm);
}
.spec-table__val {
  color: var(--text-primary);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ---------- Pied de page ---------- */
.footer {
  position: relative;
  background: var(--color-ink);
  color: var(--color-porcelain);
  padding-block: var(--space-14) var(--space-7);
}
.footer h2, .footer h3 { color: var(--color-porcelain); }
.footer__grid {
  display: grid;
  gap: var(--space-10);
  grid-template-columns: 1fr;
}
@media (min-width: 780px) {
  .footer__grid { grid-template-columns: 1.6fr 1fr 1fr; gap: var(--space-12); }
}
.footer__mark {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.08em;
}
.footer__tagline {
  margin-top: var(--space-4);
  max-width: 34ch;
  color: rgba(247, 247, 244, 0.62);
  font-size: var(--text-small);
}
.footer__heading {
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  letter-spacing: var(--tracking-mono-wide);
  text-transform: uppercase;
  color: rgba(247, 247, 244, 0.45);
  margin-bottom: var(--space-5);
}
.footer__list li + li { margin-top: var(--space-3); }
.footer__list a {
  color: rgba(247, 247, 244, 0.82);
  transition: color var(--dur-fast) var(--ease-precise);
}
.footer__list a:hover { color: var(--color-orange); }
.footer__list address {
  font-style: normal;
  color: rgba(247, 247, 244, 0.82);
  line-height: var(--leading-relaxed);
}
.footer__base {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: var(--space-4) var(--space-8);
  align-items: center;
  margin-top: var(--space-14);
  padding-top: var(--space-5);
  border-top: 1px solid rgba(247, 247, 244, 0.14);
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: rgba(247, 247, 244, 0.45);
}

.footer__base > :nth-child(2) { justify-self: center; text-align: center; }
.footer__base > :nth-child(3) { justify-self: end; text-align: right; }

/* Signature du réalisateur — en casse normale : une URL en capitales se lit
   mal et ne correspond plus à l'adresse réelle. */
.footer__credit {
  justify-self: start;
  text-transform: none;
  letter-spacing: 0.02em;
  color: rgba(247, 247, 244, 0.46);
}
.footer__credit a {
  color: rgba(247, 247, 244, 0.82);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-precise);
}
.footer__credit a:hover,
.footer__credit a:focus-visible { color: var(--color-porcelain); }
.footer__credit-url {
  color: rgba(247, 247, 244, 0.5);
  border-bottom: 1px solid rgba(247, 247, 244, 0.22);
  transition:
    color var(--dur-fast) var(--ease-precise),
    border-color var(--dur-fast) var(--ease-precise);
}
.footer__credit-sep { padding: 0 0.45em; border: 0; }
.footer__credit a:hover .footer__credit-url,
.footer__credit a:focus-visible .footer__credit-url {
  color: var(--color-porcelain);
  border-bottom-color: var(--color-porcelain);
}

/* Sous 900 px les trois blocs ne tiennent plus sur une ligne : on empile,
   centré, plutôt que de laisser la grille les écraser. */
@media (max-width: 900px) {
  .footer__base {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
  }
  .footer__base > :nth-child(2),
  .footer__base > :nth-child(3),
  .footer__credit {
    justify-self: center;
    text-align: center;
  }
}

/* ---- components.css ---- */
/* =============================================================
   MTS — Composants : nav, boutons, cards, formulaire, curseur
   ============================================================= */

/* =============================================================
   1. En-tête
   ============================================================= */
.header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-header);
  padding-block: var(--space-5);
  transition:
    background-color var(--dur-base) var(--ease-precise),
    padding var(--dur-base) var(--ease-precise),
    border-color var(--dur-base) var(--ease-precise);
  border-bottom: 1px solid transparent;
}
.header.is-stuck {
  background: rgba(247, 247, 244, 0.88);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
          backdrop-filter: blur(14px) saturate(1.4);
  border-bottom-color: var(--border-hair);
  padding-block: var(--space-3);
}
.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
}

/* Le logotype MTS, suivi du nom développé en mono ----------------
   Le logo est l'actif de marque existant : on ne le redessine pas. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  min-width: 0;
}
.brand__logo {
  flex: none;
  height: 38px;
  width: auto;
  transition: height var(--dur-base) var(--ease-precise);
}
.header.is-stuck .brand__logo { height: 32px; }

.brand__suffix {
  display: none;
  padding-left: var(--space-4);
  border-left: var(--hair);
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  letter-spacing: var(--tracking-mono);
  line-height: 1.35;
  color: var(--text-secondary);
  max-width: 17ch;
}
@media (min-width: 1240px) { .brand__suffix { display: block; } }

/* ---------- Navigation principale ---------- */
.nav { display: none; }
@media (min-width: 940px) {
  .nav {
    display: flex;
    align-items: center;
    gap: var(--space-7);
  }
}
.nav__link {
  position: relative;
  padding-block: var(--space-2);
  font-size: var(--text-small);
  font-weight: 500;
  color: var(--text-secondary);
  transition: color var(--dur-fast) var(--ease-precise);
}
.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--color-violet);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-precise);
}
.nav__link:hover { color: var(--text-primary); }
.nav__link:hover::after { transform: scaleX(1); }
.nav__link[aria-current="page"] { color: var(--text-primary); }
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

.header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

/* ---------- Badge d'origine ----------
   Carte tracée à partir de données de frontières, pas dessinée à main
   levée. Le texte reste du HTML : traduisible, sélectionnable, lisible
   par les moteurs, et masquable seul quand la largeur manque. */
.made-in {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
}
@media (min-width: 600px) {
  .made-in {
    padding-right: var(--space-4);
    border-right: var(--hair);
  }
}
.made-in__map {
  flex: none;
  width: auto;
  height: 26px;
  display: block;
}
.made-in__text {
  display: none;
  font-family: var(--font-body);
  font-size: 0.625rem;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-primary);
  white-space: nowrap;
}
@media (min-width: 600px) { .made-in__text { display: block; } }

/* ---------- Sélecteur de langue ---------- */
.lang {
  display: inline-flex;
  align-items: stretch;
  border: var(--hair-ink);
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  letter-spacing: var(--tracking-mono);
}
.lang__btn {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: var(--space-2) var(--space-3);
  color: var(--text-secondary);
  text-transform: uppercase;
  transition:
    background-color var(--dur-fast) var(--ease-precise),
    color var(--dur-fast) var(--ease-precise);
}
/* Au doigt, la cible passe à 44 px : deux libellés de deux lettres
   côte à côte sont sinon trop faciles à confondre au toucher. */
@media (pointer: coarse) {
  .lang__btn {
    min-height: 44px;
    padding-inline: var(--space-4);
  }
}
.lang__btn + .lang__btn { border-left: var(--hair-ink); }
.lang__btn:hover { color: var(--text-primary); }
.lang__btn[aria-pressed="true"] {
  background: var(--color-ink);
  color: var(--color-porcelain);
}

/* ---------- Bouton menu mobile ---------- */
.menu-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0 9px;
  border: var(--hair-ink);
}
@media (min-width: 940px) { .menu-toggle { display: none; } }
.menu-toggle__bar {
  display: block;
  height: 1.5px;
  background: var(--color-ink);
  transition: transform var(--dur-base) var(--ease-precise),
              opacity var(--dur-fast) var(--ease-precise);
}
.menu-toggle[aria-expanded="true"] .menu-toggle__bar:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] .menu-toggle__bar:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] .menu-toggle__bar:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* ---------- Panneau mobile ---------- */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-14) var(--shell-pad) var(--space-10);
  background: var(--color-porcelain);
  transform: translateY(-100%);
  visibility: hidden;
  transition: transform var(--dur-slow) var(--ease-precise),
              visibility 0s linear var(--dur-slow);
}
.mobile-menu.is-open {
  transform: translateY(0);
  visibility: visible;
  transition: transform var(--dur-slow) var(--ease-precise), visibility 0s;
}
@media (min-width: 940px) { .mobile-menu { display: none; } }

/* Le panneau passe AU-DESSUS de l'en-tête (z-index 70 contre 60) : le bouton
   hamburger est donc recouvert et ne peut pas servir à refermer. Le panneau
   porte sa propre croix, première cible au clavier une fois ouvert. */
.mobile-menu__close {
  position: absolute;
  top: var(--space-5);
  right: var(--shell-pad);
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: var(--hair-ink);
  color: var(--color-ink);
  background: var(--bg-page);
  transition:
    border-color var(--dur-fast) var(--ease-precise),
    color var(--dur-fast) var(--ease-precise);
}
.mobile-menu__close:hover {
  border-color: var(--color-violet);
  color: var(--color-violet);
}
.mobile-menu__list li + li { margin-top: var(--space-2); }
.mobile-menu__link {
  display: flex;
  align-items: baseline;
  gap: var(--space-5);
  padding-block: var(--space-4);
  border-bottom: var(--hair);
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 8vw, 2.5rem);
  font-weight: 600;
  letter-spacing: var(--tracking-display);
}
.mobile-menu__index {
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  font-weight: 400;
  letter-spacing: var(--tracking-mono);
  color: var(--color-violet);
}
.mobile-menu__foot {
  margin-top: var(--space-10);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  color: var(--text-secondary);
  line-height: var(--leading-relaxed);
}

/* =============================================================
   2. Boutons
   ============================================================= */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: 48px;
  padding: var(--space-3) var(--space-6);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: 500;
  letter-spacing: 0.01em;
  text-align: center;
  transition:
    background-color var(--dur-base) var(--ease-precise),
    border-color var(--dur-base) var(--ease-precise),
    color var(--dur-base) var(--ease-precise),
    box-shadow var(--dur-base) var(--ease-precise);
}
.btn__label { position: relative; z-index: 1; }
.btn__arrow {
  position: relative;
  z-index: 1;
  flex: none;
  transition: transform var(--dur-base) var(--ease-settle);
}
.btn:hover .btn__arrow { transform: translateX(4px); }

/* Primaire — le violet de marque porte du texte porcelaine (10,5:1) */
.btn--primary {
  background: var(--color-violet);
  color: var(--color-porcelain);
}
.btn--primary:hover {
  background: var(--color-violet-deep);
  box-shadow: var(--shadow-lift);
}

/* Signal — fond plein obligatoire, et c'est l'orange assombri qui le tient :
   l'orange de marque sous du texte porcelaine ne donne que 3,3:1, sous le
   seuil AA. À 5,5:1, celui-ci passe.                                      */
.btn--signal {
  background: var(--color-orange-deep);
  color: var(--color-porcelain);
}
.btn--signal:hover {
  background: var(--color-orange-darkest);
  box-shadow: var(--shadow-lift);
}

.btn--ghost {
  background: transparent;
  color: var(--text-primary);
  border-color: var(--border-strong);
}
.btn--ghost:hover {
  border-color: var(--color-violet);
  color: var(--color-violet);
  box-shadow: var(--shadow-lift-violet);
}

.btn--on-ink {
  background: transparent;
  color: var(--color-porcelain);
  border-color: rgba(247, 247, 244, 0.32);
}
.btn--on-ink:hover {
  background: var(--color-porcelain);
  color: var(--color-ink);
  border-color: var(--color-porcelain);
}

.btn--wide { width: 100%; }
@media (min-width: 560px) { .btn--wide { width: auto; } }

/* Lien fléché inline */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--color-violet);
  border-bottom: 1px solid var(--color-violet-32);
  transition: border-color var(--dur-fast) var(--ease-precise),
              color var(--dur-fast) var(--ease-precise);
}
.link-arrow svg { transition: transform var(--dur-base) var(--ease-settle); }
.link-arrow:hover { border-bottom-color: var(--color-violet); }
.link-arrow:hover svg { transform: translateX(4px); }

/* Sur fond encre, l'orange de marque passe à 5,15:1 — il peut porter
   ce libellé court, et le trait doit passer en clair pour rester vu. */
.link-arrow--on-ink {
  color: var(--color-orange);
  border-bottom-color: rgba(224, 97, 14, 0.45);
}
.link-arrow--on-ink:hover { border-bottom-color: var(--color-orange); }

/* =============================================================
   3. Cards & modules de planche
   ============================================================= */
.plate {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--bg-surface);
  border: var(--hair);
  transition: border-color var(--dur-base) var(--ease-precise),
              box-shadow var(--dur-base) var(--ease-precise),
              transform var(--dur-base) var(--ease-settle);
}
.plate:hover {
  border-color: var(--color-violet-32);
  box-shadow: var(--shadow-lift-violet);
}
.plate__media {
  position: relative;
  overflow: hidden;
  background: var(--bg-wash);
}
.plate__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-settle);
}
.plate:hover .plate__media img { transform: scale(1.035); }
.plate__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: var(--space-4);
  padding: var(--space-6);
}
.plate__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: var(--hair);
}
.plate__text {
  color: var(--text-secondary);
  font-size: var(--text-small);
  line-height: var(--leading-relaxed);
}
.plate__foot { margin-top: auto; padding-top: var(--space-3); }

/* Lien étiré : le titre est le seul lien de la card, mais la surface
   cliquable couvre toute la card. On évite ainsi le lien-image
   redondant, invisible aux lecteurs d'écran et sans nom accessible. */
.plate__body h3 a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.plate__body h3 a {
  transition: color var(--dur-fast) var(--ease-precise);
}
.plate:hover .plate__body h3 a { color: var(--color-violet); }
/* Le reste du contenu reste sélectionnable au-dessus de la zone étirée. */
.plate__text,
.plate__meta,
.plate__foot { position: relative; z-index: 2; }

/* Module texte seul : la case de la planche qui porte les specs */
.plate--specs { background: var(--color-ink); border-color: var(--color-ink); }
.plate--specs .plate__body { gap: var(--space-5); }
.plate--specs h3 { color: var(--color-porcelain); }
.plate--specs .plate__meta { border-bottom-color: rgba(247, 247, 244, 0.2); }
.plate--specs .mono-label { color: var(--color-orange); }
.plate--specs .plate__text { color: rgba(247, 247, 244, 0.66); }
.plate--specs .spec-table { border-top-color: rgba(247, 247, 244, 0.3); }
.plate--specs .spec-table__row { border-bottom-color: rgba(247, 247, 244, 0.14); }
.plate--specs .spec-table__key { color: rgba(247, 247, 244, 0.5); }
.plate--specs .spec-table__val { color: var(--color-porcelain); }
.plate--specs:hover { border-color: var(--color-ink); box-shadow: var(--shadow-lift-violet); }

/* =============================================================
   4. Formulaire
   ============================================================= */
.form { display: grid; gap: var(--space-6); }
.field { display: grid; gap: var(--space-2); }
.field__label {
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  letter-spacing: var(--tracking-mono-wide);
  text-transform: uppercase;
  color: var(--text-secondary);
}
.field__req { color: var(--color-orange-deep); }

.field__input,
.field__select,
.field__textarea {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  min-height: 48px;
  background: var(--bg-surface);
  border: 1px solid var(--border-hair);
  border-radius: var(--radius-sm);
  font-size: var(--text-body);
  color: var(--text-primary);
  transition: border-color var(--dur-fast) var(--ease-precise),
              box-shadow var(--dur-fast) var(--ease-precise);
}
.field__textarea { min-height: 148px; resize: vertical; line-height: var(--leading-normal); }
.field__select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='%235B6470' stroke-width='1.4' fill='none'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-4) center;
  padding-right: var(--space-8);
}
.field__input::placeholder,
.field__textarea::placeholder { color: #98A0AA; }

.field__input:hover,
.field__select:hover,
.field__textarea:hover { border-color: #BFC7CE; }

.field__input:focus-visible,
.field__select:focus-visible,
.field__textarea:focus-visible {
  outline: none;
  border-color: var(--color-violet);
  box-shadow: 0 0 0 3px var(--color-violet-16);
}

/* États de validation — le trait change, jamais uniquement la couleur */
.field.is-valid .field__input,
.field.is-valid .field__select,
.field.is-valid .field__textarea { border-color: var(--color-violet); }

.field.is-invalid .field__input,
.field.is-invalid .field__select,
.field.is-invalid .field__textarea {
  border-color: var(--color-orange-deep);
  border-width: 1.5px;
}

.field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-small);
  color: var(--color-orange-deep);
  min-height: 0;
}
.field__error:empty { display: none; }

.field__hint {
  font-size: var(--text-small);
  color: var(--text-secondary);
}

.form__status {
  padding: var(--space-4) var(--space-5);
  border-left: 3px solid var(--color-violet);
  background: var(--bg-wash);
  font-size: var(--text-small);
  color: var(--text-primary);
}
.form__status:empty { display: none; }
.form__status[data-state="error"] {
  border-left-color: var(--color-orange-deep);
  background: #FAF2EB;
}

/* =============================================================
   6. Préchargement
   ============================================================= */
.loader {
  position: fixed;
  inset: 0;
  z-index: var(--z-loader);
  display: grid;
  place-items: center;
  gap: var(--space-8);
  background: var(--color-porcelain);
  grid-auto-rows: min-content;
  align-content: center;
}
.loader[hidden] { display: none; }
.loader__mark { width: clamp(120px, 24vw, 180px); }
.loader__mark path,
.loader__mark circle,
.loader__mark line {
  stroke: var(--color-violet);
  fill: none;
  stroke-width: 1.25;
}
.loader__bar {
  width: clamp(120px, 24vw, 180px);
  height: 1px;
  background: var(--color-mist);
  overflow: hidden;
}
.loader__fill {
  display: block;
  height: 100%;
  width: 0;
  background: var(--color-violet);
  transform-origin: left;
}
.loader__pct {
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  letter-spacing: var(--tracking-mono-wide);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* =============================================================
   7. Bandeau clients & témoignage
   ============================================================= */
/* =============================================================
   Bandeau clients — carrousel infini

   Deux calques strictement identiques défilent ensemble : celui du
   dessous en niveaux de gris, celui du dessus en couleur mais masqué
   hors d'une fenêtre centrale. Le logo qui traverse le centre se colore
   donc de lui-même, et la couleur monte et redescend en fondu.

   Le défilement est une animation CSS, pas une boucle JavaScript : il
   continue même si le fil principal est occupé, et il s'arrête tout seul
   sous `prefers-reduced-motion`.
   ============================================================= */
/* =============================================================
   Bandeau de preuve — l'engagement, puis ceux qui l'ont éprouvé.
   Ces classes existaient dans le balisage sans aucun style : la phrase
   tombait en texte courant et la signature se recollait sur une ligne.
   ============================================================= */
.proof__inner { display: grid; }

.quote {
  max-width: 44rem;
  margin: 0 0 var(--space-12);
  padding-left: var(--space-8);
  border-left: 2px solid var(--color-violet);
}
.quote__text {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.3vw, 1.9rem);
  font-weight: 500;
  line-height: 1.34;
  letter-spacing: var(--tracking-heading);
  color: var(--color-ink);
  text-wrap: balance;
}
/* La signature se lit sur deux lignes : le nom porte, la raison sociale suit. */
.quote__by {
  display: grid;
  gap: var(--space-1, 4px);
  margin-top: var(--space-6);
}
.quote__name {
  font-size: var(--text-small);
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-primary);
}
.quote__role {
  font-family: var(--font-mono);
  font-size: var(--text-mono-sm);
  line-height: 1.5;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
}

/* Le libellé annonce la bande : il lui faut de l'air, sinon il se colle
   au filet supérieur du carrousel. */
.clients__label {
  margin-bottom: var(--space-6);
  color: var(--color-violet);
}

.clients {
  position: relative;
  overflow: hidden;
  padding-block: var(--space-8);
  border-block: var(--hair);
  /* Les logos s'effacent aux deux bords : le défilement paraît sans fin. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
}

/* Repère central : deux courts filets qui donnent son sens au logo coloré. */
.clients::before,
.clients::after {
  content: "";
  position: absolute;
  left: 50%;
  z-index: 2;
  width: 1px;
  height: 9px;
  background: var(--color-violet-32);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-precise);
}
.clients::before { top: var(--space-3); }
.clients::after  { bottom: var(--space-3); }
.clients.is-running::before,
.clients.is-running::after { opacity: 1; }

.clients__layer { display: block; }
.clients__layer--color {
  position: absolute;
  inset: var(--space-8) 0;
  pointer-events: none;
  /* La fenêtre de couleur : calibrée sur la largeur d'un logo, avec un
     fondu de part et d'autre — la couleur monte quand le logo entre au
     centre et redescend quand il en sort, sans jamais allumer son voisin. */
  -webkit-mask-image: linear-gradient(to right, transparent 42%, #000 46.5%, #000 53.5%, transparent 58%);
          mask-image: linear-gradient(to right, transparent 42%, #000 46.5%, #000 53.5%, transparent 58%);
}
/* Tant que le carrousel ne tourne pas, la fenêtre de couleur n'a pas de
   sens : on masque le calque et tout reste lisible en une seule rangée. */
.clients:not(.is-running) .clients__layer--color { display: none; }

.clients__track {
  display: flex;
  align-items: center;
  gap: var(--space-10);
  width: max-content;
  list-style: none;
  margin: 0;
  padding: 0;
}

.clients.is-running .clients__track {
  animation: clients-scroll var(--marquee-duration, 40s) linear infinite;
  will-change: transform;
}
/* On s'arrête dès que quelqu'un veut regarder. */
.clients:hover .clients__track,
.clients:focus-within .clients__track { animation-play-state: paused; }

@keyframes clients-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(calc(-1 * var(--marquee-set, 0px)), 0, 0); }
}

/* Sans JS ou sans mouvement : rangée centrée qui se replie normalement. */
.clients:not(.is-running) .clients__track {
  flex-wrap: wrap;
  width: auto;
  justify-content: center;
  gap: var(--space-6) var(--space-7);
}

/* Logos réels. `--logo-scale` corrige la taille optique de chacun : une
   hauteur de boîte identique ne donne pas une présence identique, un logo
   étalé (icône + baseline) paraît plus petit qu'un logo compact. Les
   valeurs sont mesurées sur la répartition de l'encre, pas devinées.     */
.client {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.client img {
  height: calc(30px * var(--logo-scale, 1));
  width: auto;
  object-fit: contain;
}
@media (min-width: 900px) { .client img { height: calc(34px * var(--logo-scale, 1)); } }

.clients__layer--grey .client img {
  filter: grayscale(1) contrast(1.15) brightness(0.82);
  opacity: 0.78;
  transition: filter var(--dur-base) var(--ease-precise),
              opacity var(--dur-base) var(--ease-precise);
}
/* Hors carrousel, le survol suffit à révéler la couleur d'un logo. */
.clients:not(.is-running) .client img:hover { filter: none; opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .clients.is-running .clients__track { animation: none; }
  .clients__layer--color { display: none; }
  .clients__layer--grey .client img { filter: none; opacity: 0.92; }
}

/* =============================================================
   8. Appel final
   ============================================================= */
.cta-band {
  position: relative;
  background: var(--color-ink);
  color: var(--color-porcelain);
  padding-block: var(--section-y);
  overflow: hidden;
}
.cta-band h2 { color: var(--color-porcelain); max-width: 18ch; }
.cta-band__inner {
  position: relative;
  z-index: var(--z-content);
  display: grid;
  gap: var(--space-8);
  align-items: end;
}
@media (min-width: 900px) {
  .cta-band__inner { grid-template-columns: 1.4fr 1fr; gap: var(--space-12); }
}
.cta-band__text { color: rgba(247, 247, 244, 0.66); max-width: 42ch; }
.cta-band__actions { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.cta-band .layout-grid {
  background-image:
    linear-gradient(to right,  rgba(247,247,244,0.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(247,247,244,0.07) 1px, transparent 1px);
}

/* ---- motion.css ---- */
/* =============================================================
   MTS — Mouvement
   Une séquence forte (le plan qui se dessine), le reste sobre.
   Tout se dégrade proprement sous prefers-reduced-motion.
   ============================================================= */

/* ---------- États de départ posés par JS (jamais avant) ----------
   .js-motion sur <html> évite le flash de contenu masqué si JS échoue. */

.js-motion [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  will-change: opacity, transform;
}
.js-motion [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--dur-reveal) var(--ease-out-soft),
    transform var(--dur-reveal) var(--ease-out-soft);
}

/* Reveal en développement de plan : l'image apparaît par le bas,
   comme un tirage qui se révèle — pas un fondu générique. */
/* La découpe porte sur l'IMAGE, jamais sur le conteneur observé.
   Un clip-path sur le conteneur écrasait son rectangle visible à zéro :
   IntersectionObserver le jugeait alors invisible (ratio 0, sous le seuil
   de 0,15), ne posait jamais .is-revealed, et la découpe ne se levait
   jamais. Les images se téléchargeaient sans jamais s'afficher — sur
   toutes les pages sauf l'accueil, seule à ne pas utiliser ce mécanisme. */
.js-motion [data-reveal-clip] img {
  clip-path: inset(0 0 100% 0);
  transform: scale(1.08);
  will-change: clip-path, transform;
  transition:
    clip-path 1100ms var(--ease-precise),
    transform 1400ms var(--ease-settle);
}
.js-motion [data-reveal-clip].is-revealed img {
  clip-path: inset(0 0 0 0);
  transform: scale(1);
}

/* Split-text : mot par mot, décalé */
.split-line { display: block; overflow: hidden; }
.split-word {
  display: inline-block;
  will-change: transform;
}
.js-motion .split-word {
  transform: translateY(105%);
}
.js-motion .is-revealed .split-word,
.js-motion .split-word.is-revealed {
  transform: translateY(0);
  transition: transform 820ms var(--ease-settle);
}

/* Traits qui se tirent : les hairlines de section se dessinent */
.js-motion [data-rule] {
  transform: scaleX(0);
  transform-origin: left;
}
.js-motion [data-rule].is-revealed {
  transform: scaleX(1);
  transition: transform 900ms var(--ease-precise);
}

/* ---------- Dessin du tracé (loader + écho de section) ---------- */
@keyframes draw-stroke {
  from { stroke-dashoffset: var(--dash, 1000); }
  to   { stroke-dashoffset: 0; }
}
.draw-path {
  stroke-dasharray: var(--dash, 1000);
  stroke-dashoffset: var(--dash, 1000);
  animation: draw-stroke 1500ms var(--ease-precise) forwards;
}

/* ---------- Hero : le schéma éclaté ---------- */
.schematic__part {
  will-change: transform, opacity;
  transform-box: fill-box;
  transform-origin: center;
}

@keyframes pulse-tick {
  0%, 100% { opacity: 0.25; }
  50%      { opacity: 1; }
}
.tick-pulse { animation: pulse-tick 2400ms var(--ease-out-soft) infinite; }

/* ---------- Tilt 3D des cards projets (pointeur fin uniquement) ---------- */
@media (hover: hover) and (pointer: fine) {
  .tilt {
    transform-style: preserve-3d;
    transition: transform var(--dur-base) var(--ease-settle);
  }
  .tilt__inner { transform: translateZ(28px); transform-style: preserve-3d; }
}

/* ---------- Cross-fade du switch de langue ---------- */
[data-i18n] { transition: opacity 200ms var(--ease-precise); }
html.is-switching-lang [data-i18n] { opacity: 0; }

/* ---------- Transitions de page (View Transitions API) ---------- */
@view-transition { navigation: auto; }

::view-transition-old(root) {
  animation: vt-out 260ms var(--ease-precise) forwards;
}
::view-transition-new(root) {
  animation: vt-in 420ms var(--ease-settle) forwards;
}
@keyframes vt-out {
  to { opacity: 0; transform: translateY(-10px); }
}
@keyframes vt-in {
  from { opacity: 0; transform: translateY(14px); }
}

/* Fallback fondu pour les navigateurs sans View Transitions */
.page-fade {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-loader) - 1);
  background: var(--color-porcelain);
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms var(--ease-precise);
}
.page-fade.is-active { opacity: 1; }

/* =============================================================
   Réduction de mouvement — version statique, parfaitement utilisable
   ============================================================= */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .js-motion [data-reveal],
  .js-motion [data-reveal-clip],
  .js-motion [data-rule] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }
  .js-motion [data-reveal-clip] img { transform: none !important; }
  .js-motion .split-word { transform: none !important; }
  .draw-path { stroke-dashoffset: 0 !important; }

  .tilt { transform: none !important; }
  .hero__video { display: none; }
  .hero__poster { display: block; }

  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}
