/* refonte.css */
/* ===========================================================
   CyNoLux — Refonte (v5)
   Chargée APRÈS finitions.css. Dernière couche du système.

   Rôle : élever la finition sans toucher à l'identité. Le navy,
   l'or, le verre et les polices ne changent pas. Ce fichier
   corrige la hiérarchie, le contraste et le rythme, et donne au
   bandeau de chiffres le poids qu'il mérite.

   Ce fichier est additif : le supprimer rend le site à son
   état précédent, sans casse.
   =========================================================== */

/* -----------------------------------------------------------
   1. JETONS COMPLÉMENTAIRES
   Deux manques dans le système existant :
   — aucune encre secondaire qui passe AA sur --bg (--ink-faint
     tombe à 3,1:1, insuffisant pour du texte courant) ;
   — aucun réglage de chiffres tabulaires, si bien que les
     compteurs animés font danser la mise en page à chaque tick.
   ----------------------------------------------------------- */
:root {
  --ink-soft: #3c4a6b;          /* 7,4:1 sur --bg — texte courant */
  --ink-quiet: #5a678a;         /* 4,9:1 — métadonnées */
  --plaque: #ffffff;
  --plaque-rule: rgba(11, 42, 107, 0.1);
  --figure-ink: var(--navy-700);
  --lift: 0 24px 60px -32px rgba(11, 42, 107, 0.5);
  --lift-soft: 0 12px 34px -22px rgba(11, 42, 107, 0.4);
}
[data-theme="dark"] {
  --ink-soft: #c2cfe8;
  --ink-quiet: #94a6c8;
  --plaque: #08132b;
  --plaque-rule: rgba(255, 255, 255, 0.11);
  --figure-ink: #f2f6ff;
  --lift: 0 24px 60px -30px rgba(0, 0, 0, 0.8);
  --lift-soft: 0 12px 34px -20px rgba(0, 0, 0, 0.65);
}

/* Les chiffres ne changent plus de largeur pendant qu'ils défilent. */
.counter,
.stat-chip strong,
.pack-price,
.kpi-value,
.hs-count,
.breadcrumb,
time {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* -----------------------------------------------------------
   2. LA PLAQUE DE CHIFFRES
   C'est le seul endroit où ce fichier hausse la voix.

   Avant : quatre nombres de 1,7 rem dans un bandeau de 110 px,
   à peine plus gros que leur propre légende. Un chiffre clé
   qui ne se voit pas ne prouve rien.

   Après : le chiffre devient l'objet graphique. Space Grotesk,
   chasse tabulaire, filets de séparation à un pixel, et un
   unique trait d'or sur l'arête haute — la seule fioriture.
   ----------------------------------------------------------- */
.proof-band {
  padding: 0;
  margin-top: -46px;              /* chevauche le bas du hero */
  position: relative;
  z-index: 6;
}
@media (max-width: 900px) {
  .proof-band { margin-top: -30px; }
}
/* Le chevauchement reste sous les 64 px de marge basse du hero :
   la pagination « 01 / 05 » et les flèches gardent leur place. */

.proof-band .proof-panel,
[data-theme="dark"] .proof-band .proof-panel {
  background: var(--plaque);
  border: 1px solid var(--plaque-rule);
  border-radius: var(--r-lg);
  box-shadow: var(--lift);
  overflow: hidden;
  position: relative;
}

/* Le trait d'or : court, ancré à gauche, il signe la plaque
   sans la souligner sur toute sa longueur. */
.proof-band .proof-panel::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 0;
  width: 96px;
  height: 3px;
  background: linear-gradient(90deg, var(--gold-500), var(--gold-400));
  border-start-start-radius: var(--r-lg);
}

.proof-band .proof-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}
.proof-band .proof-stats .stat-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 34px 32px 32px;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
.proof-band .proof-stats .stat-chip + .stat-chip {
  border-inline-start: 1px solid var(--plaque-rule);
}

.proof-band .proof-stats .stat-chip strong .counter {
  font-size: inherit;
  font-weight: inherit;
  letter-spacing: inherit;
  color: inherit;
}
.proof-band .proof-stats .stat-chip strong {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(2.5rem, 4.4vw, 3.9rem);
  line-height: 0.92;
  letter-spacing: -0.035em;
  color: var(--figure-ink);
  display: block;
}
/* Le suffixe (+ ou %) passe en or et redescend d'un cran :
   il qualifie le nombre, il ne le concurrence pas. */
.proof-band .proof-stats .stat-chip strong .counter-suffix {
  color: var(--gold-600);
  font-size: 0.52em;
  letter-spacing: 0;
  vertical-align: 0.42em;
  margin-inline-start: 0.06em;
}
[data-theme="dark"] .proof-band .proof-stats .stat-chip strong .counter-suffix {
  color: var(--gold-400);
}

.proof-band .proof-stats .stat-chip span:not(.counter):not(.counter-suffix) {
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
  max-width: 15ch;
}

@media (max-width: 900px) {
  .proof-band .proof-stats .stat-chip { padding: 26px 22px 24px; }
}
@media (max-width: 760px) {
  .proof-band .proof-stats { grid-template-columns: repeat(2, 1fr); }
  .proof-band .proof-stats .stat-chip:nth-child(3) { border-inline-start: 0; }
  .proof-band .proof-stats .stat-chip:nth-child(n + 3) {
    border-top: 1px solid var(--plaque-rule);
  }
}

/* -----------------------------------------------------------
   3. HEROS DES PAGES INTÉRIEURES
   Les titres couraient sur 1 100 px : l'œil perd la ligne
   suivante bien avant de l'atteindre. On plafonne la mesure
   autour de 18 caractères par ligne pour un affichage de cette
   taille, et on resserre la hauteur, qui laissait 400 px de
   vide sous le fil d'Ariane.
   ----------------------------------------------------------- */
.page-hero {
  min-height: 520px;
  padding-top: 96px;
  padding-bottom: 72px;
}
@media (max-width: 900px) {
  .page-hero { min-height: 440px; padding-bottom: 56px; }
}
.page-hero h1 {
  max-width: 18ch;
  margin-inline: auto;
  font-size: clamp(2.3rem, 4.6vw, 3.7rem);
  line-height: 1.06;
  text-wrap: balance;
}
.page-hero .lead,
.page-hero > .container > p {
  max-width: 58ch;
  margin-inline: auto;
  text-wrap: pretty;
}
.page-hero .breadcrumb { margin-top: 28px; }

/* Le titre d'accueil, lui, garde toute sa largeur : c'est la
   seule page où il doit occuper le terrain. */
.hero-slider .hs-slide h1,
.hero-slider .hs-slide h2 {
  max-width: 17ch;
  text-wrap: balance;
}
.hero-slider .hs-slide .lead { max-width: 52ch; }

@media (max-width: 760px) {
  .hero-slider .hs-slide h1,
  .hero-slider .hs-slide h2 {
    font-size: clamp(2rem, 8.2vw, 2.6rem);
    max-width: none;
  }
  .hero-slider .hs-slide .lead { font-size: 0.95rem; }
}

/* -----------------------------------------------------------
   4. CONTRASTE DU TEXTE COURANT
   --ink-faint servait à la fois de couleur décorative et de
   couleur de lecture. On le laisse aux ornements et on bascule
   tout ce qui se lit vraiment sur --ink-soft / --ink-quiet.
   ----------------------------------------------------------- */
.why-mini p,
.why-card p,
.feature-card p,
.mini-card p,
.cnx-articles__excerpt,
.timeline-step p,
.svc-card p,
.card p {
  color: var(--ink-soft);
}
.cnx-articles__meta,
.testi-role,
.proj-kind,
.breadcrumb {
  color: var(--ink-quiet);
}

/* Les commandes de navigation du bloc « pourquoi nous » étaient
   grises sur blanc : on ne voyait pas qu'elles étaient cliquables. */
.cnx-why-us .stack-prev,
.cnx-why-us .stack-next,
.cnx-why-us [class*="prev"],
.cnx-why-us [class*="next"] {
  color: var(--navy-700);
  font-weight: 700;
}
[data-theme="dark"] .cnx-why-us .stack-prev,
[data-theme="dark"] .cnx-why-us .stack-next,
[data-theme="dark"] .cnx-why-us [class*="prev"],
[data-theme="dark"] .cnx-why-us [class*="next"] {
  color: var(--gold-300);
}

/* -----------------------------------------------------------
   5. BOUTON FANTÔME SUR FOND SOMBRE
   « Explorer nos services » et « Estimer mon budget » posaient
   du bleu-gris translucide sur du navy : le libellé disparaît.
   Sur fond sombre, le fantôme devient un contour net.
   ----------------------------------------------------------- */
.hero-slider .btn-ghost,
.cta-dark .btn-ghost,
.cta-panel .btn-ghost,
[class*="cta"] .btn-ghost,
.page-hero.has-media .btn-ghost,
section[style*="navy"] .btn-ghost {
  background: rgba(255, 255, 255, 0.07);
  border: 1.5px solid rgba(255, 255, 255, 0.46);
  color: #fff;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.hero-slider .btn-ghost:hover,
.cta-dark .btn-ghost:hover,
.cta-panel .btn-ghost:hover,
[class*="cta"] .btn-ghost:hover,
.page-hero.has-media .btn-ghost:hover,
section[style*="navy"] .btn-ghost:hover {
  background: rgba(255, 255, 255, 0.15);
  border-color: #fff;
  color: #fff;
}

/* Le texte d'accompagnement du dernier appel à l'action tombait à
   3,2:1 sur le navy. */
.cta-band p { color: rgba(255, 255, 255, 0.84); }
.cta-band h2 { color: #fff; }

/* -----------------------------------------------------------
   6. BANDEAU TECHNOLOGIQUE
   Les dégradés de bord ne masquaient pas vraiment : les libellés
   se coupaient net à gauche. Un masque alpha règle le problème
   quel que soit le fond, et le défilement s'arrête au survol
   pour qu'on puisse lire.
   ----------------------------------------------------------- */
.stack-marquee-wrap {
  padding: 30px 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
.stack-marquee-wrap::before,
.stack-marquee-wrap::after { content: none; }
.stack-marquee-wrap:hover .stack-track,
.stack-marquee-wrap:focus-within .stack-track {
  animation-play-state: paused;
}
.stack-item {
  color: rgba(255, 255, 255, 0.66);
  letter-spacing: 0.01em;
}
@media (prefers-reduced-motion: reduce) {
  .stack-track { animation: none; }
  .stack-marquee-wrap {
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .stack-marquee-wrap::-webkit-scrollbar { display: none; }
}

/* -----------------------------------------------------------
   7. BOUTONS FLOTTANTS
   Sur mobile, finitions.css range volontairement WhatsApp et la
   palette de commandes en ligne, tout en bas — la hauteur d'écran
   y est la ressource rare. Mais « retour en haut » restait, lui,
   à 26 px du bord : il retombait pile sur cette ligne. Les trois
   boutons forment désormais une seule rangée.
   ----------------------------------------------------------- */
.lab-fab {
  right: 22px;
  bottom: 88px;
  gap: 12px;
  align-items: center;
}
.lab-fab button,
.lab-fab a {
  width: 50px;
  height: 50px;
  box-shadow: var(--lift-soft);
}
.back-to-top {
  right: 22px;
  bottom: 26px;
  width: 50px;
  height: 50px;
}
@media (max-width: 760px) {
  .lab-fab button,
  .lab-fab a { width: 44px; height: 44px; }
  /* 14 (marge) + 44 + 8 + 44 + 8 : la troisième place de la rangée. */
  .back-to-top {
    right: 118px;
    bottom: 14px;
    width: 44px;
    height: 44px;
  }
  /* Il s'efface avec les deux autres au défilement vers le bas. */
  body.scrolling-down .back-to-top {
    transform: translateY(140%);
    opacity: 0;
    pointer-events: none;
  }
}

/* -----------------------------------------------------------
   8. CARTES D'ARTICLES
   La date et l'auteur se cassaient sur deux lignes, et une
   catégorie longue (« Intelligence Artificielle ») venait
   percuter le badge « À la une ».
   ----------------------------------------------------------- */
.cnx-articles__badges {
  align-items: flex-start;
  gap: 10px;
}
.cnx-articles__badge {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 60%;
  line-height: 1.4;
}
.cnx-articles__badge--accent { max-width: none; flex: none; }

.cnx-articles__meta {
  flex-wrap: wrap;
  row-gap: 4px;
  column-gap: 14px;
  font-size: 0.7rem;
}
.cnx-articles__meta span { white-space: nowrap; }

.cnx-articles__title {
  font-size: 1.08rem;
  text-wrap: balance;
  min-height: 2.7em;   /* aligne les résumés d'une carte à l'autre */
}
.cnx-articles__excerpt { font-size: 0.87rem; line-height: 1.6; }

/* La superposition au survol recouvrait la carte entière, titre
   compris, et rejouait la même information. Elle s'efface. */
.cnx-articles__overlay { display: none; }

/* -----------------------------------------------------------
   9. TÉMOIGNAGES
   Le nom et la fonction se serraient sur deux lignes collées.
   ----------------------------------------------------------- */
.testi-meta,
.testi-author {
  gap: 14px;
  align-items: center;
}
.testi-author strong,
.testi-name {
  display: block;
  line-height: 1.3;
  margin-bottom: 3px;
}
.testi-role,
.testi-author span {
  display: block;
  font-size: 0.76rem;
  line-height: 1.45;
  color: var(--ink-quiet);
}

/* -----------------------------------------------------------
   10. LE SCEAU CIRCULAIRE
   Le même médaillon « CYNOLUX · CYBER · NOVATION · LUXURY »
   revenait dans six sections de la page d'accueil. Un motif
   qu'on croise six fois n'est plus une signature, c'est un
   fond d'écran. On le garde une section sur deux.
   ----------------------------------------------------------- */
.wm-seal-wrap { opacity: 0.55; }
section[data-seal] ~ section[data-seal] .wm-seal-wrap { display: none; }
section[data-seal] ~ section[data-seal] ~ section[data-seal] .wm-seal-wrap {
  display: block;
}
section[data-seal] ~ section[data-seal] ~ section[data-seal] ~ section[data-seal] .wm-seal-wrap {
  display: none;
}

/* -----------------------------------------------------------
   10 bis. CORRECTIFS DE THÈME SOMBRE
   ----------------------------------------------------------- */

/* La FAQ de la page contact n'avait jamais reçu sa variante sombre :
   `.faq-q` restait en --navy-800, c'est-à-dire du bleu nuit posé sur
   du bleu nuit. Les quatre questions étaient invisibles. */
[data-theme="dark"] .faq-q { color: var(--ink); }
[data-theme="dark"] .faq-q i { color: var(--gold-400); }
[data-theme="dark"] .faq-item { border-bottom-color: rgba(255, 255, 255, 0.12); }
[data-theme="dark"] .faq-a p { color: var(--ink-soft); }

/* L'or foncé sur fond clair tombe à 3,6:1 : sous le seuil pour du
   texte de 11 px. On le fonce, et la note repasse en encre lisible. */
.est-label { color: #8d5c05; }
.est-note { color: var(--ink-soft); }
[data-theme="dark"] .est-label { color: var(--gold-300); }

/* -----------------------------------------------------------
   11. RYTHME DES SECTIONS
   120 px partout donnait le même silence entre deux idées liées
   et entre deux chapitres. On resserre légèrement et on laisse
   respirer les bascules de fond.
   ----------------------------------------------------------- */
section { padding: 104px 0; }
section[style*="background"] + section[style*="background"] { padding-top: 104px; }
@media (max-width: 900px) { section { padding: 72px 0; } }

.section-head { margin-bottom: 56px; }
.section-head h2 {
  max-width: 20ch;
  text-wrap: balance;
}
.section-head.center h2 { margin-inline: auto; }
.section-head p {
  max-width: 62ch;
  text-wrap: pretty;
  color: var(--ink-soft);
}
.section-head.center p { margin-inline: auto; }

/* -----------------------------------------------------------
   12. CARTES : UNE SEULE GRAMMAIRE
   Toutes les cartes montaient de 6 px au survol, avec la même
   ombre. Le mouvement est réservé à ce qui mène ailleurs — les
   projets, les articles, les liens. Les cartes de contenu se
   contentent d'un filet qui s'affirme.
   ----------------------------------------------------------- */
.card:not(a):hover,
.svc-card:not(a):hover,
.why-mini:hover,
.feature-card:not(a):hover {
  transform: none;
  border-color: rgba(11, 42, 107, 0.22);
  box-shadow: var(--lift-soft);
}
[data-theme="dark"] .card:not(a):hover,
[data-theme="dark"] .svc-card:not(a):hover,
[data-theme="dark"] .why-mini:hover,
[data-theme="dark"] .feature-card:not(a):hover {
  border-color: rgba(255, 255, 255, 0.24);
}
a.card:hover,
.cnx-articles__card:hover,
.proj-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--lift);
}

/* -----------------------------------------------------------
   13. EN-TÊTE
   Le « Lux » doré tombait à 2,6:1 sur le verre clair du hero.
   On le remonte et on épaissit très légèrement la barre.
   ----------------------------------------------------------- */
.brand-word span { color: var(--gold-500); }
.site-header .brand-word span { text-shadow: 0 1px 2px rgba(7, 25, 56, 0.35); }
[data-theme="dark"] .brand-word span,
.page-hero.has-media ~ * .brand-word span { color: var(--gold-400); }

.header-inner { box-shadow: var(--lift-soft); }
.nav-menu a { font-weight: 600; }
.nav-menu a.active { font-weight: 700; }

/* -----------------------------------------------------------
   14. SOCLE DE QUALITÉ
   ----------------------------------------------------------- */
/* Le focus clavier doit rester visible même sur fond or. */
:focus-visible {
  outline: 3px solid var(--gold-500);
  outline-offset: 3px;
}
.btn-primary:focus-visible {
  outline-color: var(--navy-800);
  outline-offset: 4px;
}
[data-theme="dark"] .btn-primary:focus-visible { outline-color: #fff; }

/* Le lien d'évitement est stylé dans lab.css ; on n'ajoute que
   l'adoucissement de son apparition. */
.skip-link { transition: left 0.18s var(--ease); }

/* Césure propre du français dans les colonnes étroites. */
p, li { hyphens: auto; -webkit-hyphens: auto; }
h1, h2, h3, h4, .btn { hyphens: none; -webkit-hyphens: none; }

/* Les images sans dimensions déclarées réservent leur place. */
.cnx-articles__image,
.proj-media,
.svc-media { background: var(--bg-deep); }

@media (prefers-reduced-motion: reduce) {
  a.card:hover,
  .cnx-articles__card:hover,
  .proj-card:hover { transform: none; }
}

/* epure.css */
/* ===========================================================
   CyNoLux — Épuration (v6)
   Chargée APRÈS refonte.css. Dernière couche du système.

   Contexte : le v5 (refonte.css) corrigeait la hiérarchie et le
   contraste sans toucher au verre ni aux ombres. Cette demande-ci
   va plus loin — un design "encore plus épuré, moins chargé",
   une typographie qui tient à toutes les tailles d'écran, et une
   chronologie de lecture plus nette sur la page d'accueil.

   Trois leviers, dans l'ordre où ils comptent :
   1. Alléger le verre et les ombres (c'est la source la plus
      visible de "surcharge" — 22px de flou et 160% de saturation,
      répétés sur une dizaine de blocs, ça fatigue l'œil).
   2. Étendre la fluidité typographique et le rythme des sections
      aux extrêmes (petits téléphones, très grands écrans).
   3. Donner à la page d'accueil une numérotation de chapitres
      discrète, pour qu'on sente qu'on avance dans un récit plutôt
      que dans une pile de blocs.

   Additif : le supprimer rend le site à son état v5, sans casse.
   =========================================================== */

/* -----------------------------------------------------------
   1. VERRE ET OMBRES — allègement
   Avant : remplissage à 55-58% d'opacité + flou 18-22px +
   saturation 160% + ombres portées jusqu'à 70px. Empilé sur
   bento, why-us, features, partenaires, témoignages, le résultat
   scintille plus qu'il n'apaise.
   Après : un panneau plus mat, presque opaque, avec un flou
   résiduel pour la profondeur — pas pour l'effet. Même teinte,
   même identité (navy/or), poids visuel divisé par deux.
   ----------------------------------------------------------- */
:root {
  --glass-fill: rgba(255, 255, 255, 0.86);
  --glass-fill-strong: rgba(255, 255, 255, 0.94);
  --glass-border: rgba(11, 42, 107, 0.08);

  --glass-shadow: 0 20px 46px -28px rgba(11, 42, 107, 0.22);
  --glass-shadow-sm: 0 10px 24px -16px rgba(11, 42, 107, 0.16);
  --lift: 0 26px 60px -36px rgba(11, 42, 107, 0.34);
  --lift-soft: 0 14px 34px -24px rgba(11, 42, 107, 0.26);
}
[data-theme="dark"] {
  --glass-fill: rgba(19, 38, 76, 0.72);
  --glass-fill-strong: rgba(24, 48, 94, 0.86);
  --glass-border: rgba(255, 255, 255, 0.09);

  --glass-shadow: 0 22px 52px -26px rgba(0, 0, 0, 0.6);
  --glass-shadow-sm: 0 12px 28px -18px rgba(0, 0, 0, 0.48);
  --lift: 0 26px 60px -32px rgba(0, 0, 0, 0.68);
  --lift-soft: 0 14px 34px -22px rgba(0, 0, 0, 0.54);
}

/* Le flou et la saturation restent codés en dur (pas de jeton) sur
   les cartes vitrées les plus visibles : on les corrige ici,
   sélecteur par sélecteur, plutôt que de toucher aux fichiers
   sources. */
.glass,
.glass-dark,
.cnx-why-us__card,
.cnx-features__card,
.cnx-partners__card,
.cnx-testimonials__body {
  backdrop-filter: blur(12px) saturate(118%);
  -webkit-backdrop-filter: blur(12px) saturate(118%);
}

/* -----------------------------------------------------------
   2. RYTHME DES SECTIONS
   Avant : 120px fixes en haut et en bas de chaque section, sur
   mobile comme sur desktop — beaucoup de vide à défiler sur un
   téléphone, pas plus de souffle sur un écran 27". Les en-têtes
   de section (eyebrow + h2 + p) gardaient la même marge partout.
   Après : le rythme respire avec l'écran, dans une fourchette
   sobre (64 à 120px) qui ne s'emballe jamais sur les très grands
   moniteurs.
   ----------------------------------------------------------- */
section {
  padding: clamp(64px, 9vw, 120px) 0;
}
.section-head {
  margin-bottom: clamp(36px, 6vw, 56px);
}

/* -----------------------------------------------------------
   3. TYPOGRAPHIE — les extrêmes
   Les titres (h1-h3) étaient déjà fluides. Ce qui ne l'était pas :
   le conteneur (fixe à 1240px, un peu étroit sur un écran 4K, où
   le texte se retrouve en colonne étroite au milieu du vide) et
   le corps de texte des chapeaux/citations, qui restait figé au
   même rem du téléphone au grand écran.
   ----------------------------------------------------------- */
.container {
  max-width: min(1240px, 92vw);
}
@media (min-width: 1600px) {
  .container {
    max-width: 1320px;
  }
}
.hero p.lead,
.section-head p,
.cta-band p {
  font-size: clamp(0.98rem, 0.85rem + 0.4vw, 1.15rem);
}

/* Garde-fou sur les très petits écrans (dès 340px) : on resserre
   l'interligne des titres pour éviter qu'un h1 sur quatre lignes
   ne pousse le hero hors de l'écran. */
@media (max-width: 380px) {
  h1 {
    line-height: 1.06;
  }
  .container {
    padding-inline: 18px;
  }
}

/* -----------------------------------------------------------
   4. CHRONOLOGIE — repères de chapitre
   La page d'accueil enchaîne une dizaine de sections sans qu'on
   sache jamais où on en est dans la visite. On ajoute un numéro
   discret devant chaque chapeau de section (même esprit graphique
   que la pagination "01 / 05" du hero et les chiffres tabulaires
   du bandeau de preuve) : un repère de lecture, pas une décoration.
   Le HTML porte désormais un <span class="chapter-mark">01</span>
   juste avant chaque .eyebrow / .section-index de chapitre.
   ----------------------------------------------------------- */
.chapter-mark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--f-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  color: var(--gold-700, var(--gold-600));
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  margin-bottom: 8px;
}
[data-theme="dark"] .chapter-mark {
  color: var(--gold-400);
}
.chapter-mark::after {
  content: "";
  width: 14px;
  height: 1px;
  background: currentColor;
  opacity: 0.5;
}

/* Unifie les deux variantes de chapeau existantes (.eyebrow et
   .section-index) sur une seule couleur, pour que la page ne
   passe plus du navy au gris selon la section. */
.section-index {
  color: var(--gold-700, var(--gold-600));
}
[data-theme="dark"] .section-index {
  color: var(--gold-400);
}

/* -----------------------------------------------------------
   5. CONTENU ALLÉGÉ — ajustements liés à la simplification
   La section « Notes de terrain » est passée de 4 cartes (avec
   dates et auteurs fictifs — le site n'a pas de blog) à 3 cartes
   honnêtes, chacune reliée à une vraie page de service.
   ----------------------------------------------------------- */
.cnx-articles__grid {
  grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 900px) {
  .cnx-articles__grid {
    grid-template-columns: 1fr;
  }
}

/* -----------------------------------------------------------
   7. RAIL DE CHAPITRES
   Injecté par js/chapter-rail.js à partir des .chapter-mark déjà
   posés dans le HTML — rien à modifier côté markup. Reprend le
   "page-spine" du projet TDSI (features/shared/components/
   page-spine) : un trait fin qui se remplit avec la progression
   globale du scroll, et un point minimal par chapitre qui ne
   s'anime qu'au survol/à l'actif — pas d'icône, pas de capsule.
   Seule adaptation à CyNoLux : la halo autour des points est en
   verre translucide plutôt qu'une bordure unie, pour rester
   lisible aussi bien sur les sections claires que sur le hero
   sombre (TDSI n'a qu'un seul thème sombre). Cache sur petit
   écran : pas la place, et le pouce n'en a pas besoin sur mobile.
   ----------------------------------------------------------- */
.chapter-rail {
  position: fixed;
  top: 50%;
  right: 22px;
  transform: translateY(-50%);
  z-index: 60;
  height: min(70vh, 600px);
  display: flex;
  align-items: center;
  padding: 18px 8px;
  opacity: 1;
  transition: opacity 0.4s var(--ease, ease), transform 0.4s var(--ease, ease);
}
.chapter-rail.is-hidden {
  opacity: 0;
  transform: translateY(-50%) translateX(8px);
  pointer-events: none;
}

.chapter-rail__list {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  height: 100%;
  min-height: 100%;
}

.chapter-rail__track {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 3px;
  transform: translateX(-50%);
  background: linear-gradient(
    to bottom,
    transparent,
    rgba(11, 42, 107, 0.16) 8%,
    rgba(11, 42, 107, 0.16) 92%,
    transparent
  );
  border-radius: var(--r-pill, 999px);
  z-index: -1;
}
[data-theme="dark"] .chapter-rail__track {
  background: linear-gradient(
    to bottom,
    transparent,
    rgba(255, 255, 255, 0.18) 8%,
    rgba(255, 255, 255, 0.18) 92%,
    transparent
  );
}
.chapter-rail__fill {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--rail-progress, 0%);
  background: linear-gradient(180deg, var(--navy-400), var(--gold-500));
  box-shadow: 0 0 10px rgba(253, 185, 19, 0.45);
  border-radius: var(--r-pill, 999px);
  transition: height 0.15s linear;
}

.chapter-rail__dot {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: transparent;
  border: 0;
  padding: 0;
  flex-shrink: 0;
  cursor: pointer;
}
.chapter-rail__dot::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(11, 42, 107, 0.4);
  box-shadow: 0 0 0 3px var(--glass-fill, rgba(255, 255, 255, 0.4));
  transition: background 0.3s var(--ease, ease), transform 0.3s var(--ease, ease),
    box-shadow 0.3s var(--ease, ease);
}
[data-theme="dark"] .chapter-rail__dot::before {
  background: rgba(255, 255, 255, 0.4);
  box-shadow: 0 0 0 3px var(--glass-fill-dark, rgba(11, 25, 56, 0.4));
}
.chapter-rail__dot:hover::before {
  background: var(--navy-500);
  transform: scale(1.3);
}
.chapter-rail__dot.is-active::before {
  background: var(--gold-500);
  transform: scale(1.5);
  box-shadow: 0 0 10px rgba(253, 185, 19, 0.7), 0 0 0 3px var(--glass-fill, rgba(255, 255, 255, 0.4));
}
[data-theme="dark"] .chapter-rail__dot.is-active::before {
  box-shadow: 0 0 10px rgba(253, 185, 19, 0.7), 0 0 0 3px var(--glass-fill-dark, rgba(11, 25, 56, 0.4));
}

.chapter-rail__tip {
  position: absolute;
  right: 100%;
  top: 50%;
  margin-right: 14px;
  transform: translateY(-50%) translateX(6px);
  white-space: nowrap;
  background: var(--navy-800);
  color: #fff;
  font-family: var(--f-mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 6px 13px;
  border-radius: var(--r-pill, 999px);
  box-shadow: var(--glass-shadow-sm);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s var(--ease, ease), transform 0.25s var(--ease, ease);
}
.chapter-rail__dot:hover .chapter-rail__tip,
.chapter-rail__dot:focus-visible .chapter-rail__tip {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

@media (max-width: 960px) {
  .chapter-rail {
    display: none;
  }
}
@media print {
  .chapter-rail {
    display: none !important;
  }
}

/* -----------------------------------------------------------
   8. FINITIONS
   ----------------------------------------------------------- */
/* Un focus plus net, cohérent avec la seule fioriture dorée que
   ce système s'autorise déjà ailleurs (proof-band, chapter-mark). */
:focus-visible {
  outline-offset: 3px;
  border-radius: 6px;
}

/* Les liens de texte courant (notes, mentions légales, articles)
   gagnent un soulignement discret et espacé plutôt que le contact
   direct avec les descendantes de lettres. */
.section-head p a,
.cnx-articles__card p a {
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

/* Cartes : la même ombre partout, plus légère, au lieu de sauter
   de --glass-shadow-sm à --glass-shadow selon les blocs. */
.card,
.glass,
.cnx-why-us__card,
.cnx-features__card,
.cnx-testimonials__body,
.cnx-articles__card {
  transition: transform 0.4s var(--ease, ease), box-shadow 0.4s var(--ease, ease), background 0.4s var(--ease, ease);
}

/* contours.css */
/* ===========================================================
   CyNoLux — courbes de niveau (filigrane)
   -----------------------------------------------------------
   UN fichier (contours.webp, 48 Ko, tuile 900×600 sans couture) sert de
   masque ; la COULEUR et l'INTENSITÉ viennent du CSS. Aucune animation.

     <section class="ct-host">
       <div class="ct c-blanc ct--centre" aria-hidden="true"></div>
       …contenu (reste au-dessus tout seul)…
     </section>

   COULEURS  (choisissez-en UNE par calque)
     Fond sombre :  c-blanc  c-gris-clair  c-bleu-clair  c-or
     Fond blanc  :  c-noir   c-gris        c-bleu-nuit    c-or-fonce
     Auto (suit le thème du site) :  c-auto  (bleu-nuit en clair, blanc en sombre)
   INTENSITÉ    k-faible (×0,6)  ·  [défaut]  ·  k-fort (×1,7)  ·  k-max (×2,6)
   ESTOMPE      ct--centre (s'efface derrière le texte) · ct--gauche · ct--droite
                (sans estompe : motif plein sur toute la surface)
   ÉCHELLE      ct--fin (600 px) · [défaut 900 px] · ct--large (1300 px)
   =========================================================== */
.ct-host { position: relative; isolation: isolate; overflow: clip; }
.ct-host > :not(.ct) { position: relative; z-index: 1; }

.ct {
  --ct-c: #fff; --ct-o: .075; --ct-k: 1; --ct-s: 900px; --ct-fade: linear-gradient(#000, #000);
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--ct-c); opacity: calc(var(--ct-o) * var(--ct-k));
  -webkit-mask-image: url(../img/contours/contours.webp), var(--ct-fade); mask-image: url(../img/contours/contours.webp), var(--ct-fade);
  -webkit-mask-size: var(--ct-s) auto, 100% 100%; mask-size: var(--ct-s) auto, 100% 100%;
  -webkit-mask-repeat: repeat, no-repeat; mask-repeat: repeat, no-repeat;
  -webkit-mask-composite: source-in; mask-composite: intersect;
}
@media (max-width: 700px) { .ct { --ct-s: 600px; } .ct.ct--large { --ct-s: 800px; } }

/* ---- couleurs : fond sombre ---- */
.ct.c-blanc      { --ct-c: #FFFFFF; --ct-o: .075; }
.ct.c-gris-clair { --ct-c: #B8C2D9; --ct-o: .10; }
.ct.c-bleu-clair { --ct-c: #9FB4E6; --ct-o: .085; }
.ct.c-or         { --ct-c: #FDB913; --ct-o: .14; }
/* ---- couleurs : fond blanc ---- */
.ct.c-noir       { --ct-c: #000000; --ct-o: .055; }
.ct.c-gris       { --ct-c: #5B6785; --ct-o: .10; }
.ct.c-bleu-nuit  { --ct-c: #0B2A6B; --ct-o: .07; }
.ct.c-or-fonce   { --ct-c: #C98F0A; --ct-o: .17; }
/* ---- auto : suit le thème (la section blanche devient sombre en thème sombre) ---- */
.ct.c-auto { --ct-c: #0B2A6B; --ct-o: .07; }
[data-theme="dark"] .ct.c-auto { --ct-c: #FFFFFF; --ct-o: .075; }

/* ---- intensité ---- */
.ct.k-faible { --ct-k: .6; }
.ct.k-fort   { --ct-k: 1.7; }
.ct.k-max    { --ct-k: 2.6; }

/* ---- estompes ---- */
.ct.ct--centre { --ct-fade: radial-gradient(ellipse 62% 64% at 50% 54%, rgba(0,0,0,.12) 18%, #000 82%); }
.ct.ct--gauche { --ct-fade: linear-gradient(100deg, transparent 18%, #000 80%); }
.ct.ct--droite { --ct-fade: linear-gradient(260deg, transparent 18%, #000 80%); }

/* ---- échelle ---- */
.ct.ct--fin   { --ct-s: 600px; }
.ct.ct--large { --ct-s: 1300px; }

/* ---- fond de page (posé par lab.js) ----
   Le même filigrane que la bande « Travaillons ensemble », fixe derrière toute la page
   (il remplace la trame d'arcs concentriques `.wm-canvas`). z-index explicite : sur les
   pages qui ne chargent pas glass3d.css, `.ct` vaut 0 et passerait devant le contenu. */
.wm-contours { position: fixed; inset: 0; z-index: -1; --ct-s: 1100px; }
/* Jaune de la marque, très transparent : l'or paraît plus fort que le bleu nuit à
   opacité égale, donc on descend sous les ~4 % de la version bleue. La spécificité
   `.ct.wm-contours` passe devant `.ct.c-or` / `.k-faible`. */
.ct.wm-contours { --ct-c: #E5A20D; --ct-o: .05; --ct-k: .6; }
[data-theme="dark"] .ct.wm-contours { --ct-c: #FDB913; --ct-o: .04; --ct-k: .6; }
@media (max-width: 700px) { .wm-contours { --ct-s: 700px; } }

/* header-dock.css */
/* ==========================================================================
   Header « ancré au scroll » — 2 variantes
   Activation : <body data-header="dock"> ou <body data-header="triptych">
   (ou ?header=dock / ?header=triptych dans l'URL, voir header-dock.js)
   La classe .is-docked est posée sur .site-header par header-dock.js
   À charger EN DERNIER (après services-bento.css).
   ========================================================================== */

body[data-header] .site-header{
  /* une seule durée et une seule courbe pour TOUT : quand fond, rayon et taille
     n'arrivent pas en même temps, l'œil voit des étapes au lieu d'un mouvement */
  --dk-t:.6s;
  --dk-rb:28px;            /* rayon des coins bas une fois ancré */
  /* ⚠️ POURQUOI deux chorégraphies : une transition CSS prend ses durées dans
     l'état d'ARRIVÉE. Les valeurs ci-dessous servent donc au retour en haut
     (séparation), celles de .is-docked à l'ancrage. Avec les mêmes durées dans
     les deux sens, la séparation ouvrait les interstices en 60 ms alors que la
     bande était encore là : bandes grises entre des capsules délavées, puis saut.
     Séparation : les capsules reprennent leur fond, la bande s'efface, PUIS elles
     s'écartent, sur une courbe lente au départ. */
  --dk-ease:cubic-bezier(.45,0,.2,1);
  --dk-fill:.18s;          /* fond des capsules */
  --dk-blur:.18s;          /* flou propre à chaque capsule */
  --dk-band:.22s;          /* la bande commune */
  --dk-edge:.4s; --dk-edge-delay:.1s;   /* bordures et ombres des capsules */
  --dk-gap:.55s; --dk-gap-delay:.12s;   /* écart entre capsules */
  transition:padding var(--dk-t) var(--dk-ease);
}
body[data-header] .site-header.is-docked{
  padding-top:0; padding-inline:0;
  /* ancrage : la bande arrive en douceur, les jointures disparaissent vite
     (à mi-course, bordures, bords de flou et interstices dessinaient encore
     les coupures dans la bande) */
  --dk-ease:cubic-bezier(.22,1,.36,1);
  --dk-fill:var(--dk-t);
  --dk-blur:.25s;
  --dk-band:var(--dk-t);
  --dk-edge:.25s; --dk-edge-delay:0s;
  --dk-gap:.3s; --dk-gap-delay:0s;
}
body[data-header] .site-header .header-inner{
  /* ⚠️ POURQUOI relative : le filet de lecture (.sg-progress, focus.js) est en
     absolu. En triptyque la pilule n'a plus de backdrop-filter, donc plus de bloc
     conteneur : le filet se calait sur tout le <header> (padding compris) et
     flottait 20 px sous la bande au lieu de la suivre. */
  position:relative; isolation:isolate;
  max-width:1440px; width:100%;
  transition:max-width var(--dk-t) var(--dk-ease), min-height var(--dk-t) var(--dk-ease),
             border-radius var(--dk-t) var(--dk-ease), padding var(--dk-t) var(--dk-ease),
             gap var(--dk-gap) var(--dk-ease) var(--dk-gap-delay),
             background-color var(--dk-t) var(--dk-ease), box-shadow var(--dk-t) var(--dk-ease);
}
body[data-header] .site-header.is-docked .header-inner{ max-width:100%; }

/* Filet de lecture : il épouse la forme de la bande, quelle qu'elle soit */
body[data-header] .site-header .sg-progress{ inset:0; border-radius:inherit; }
/* ancré, on ne garde que le bas (coins compris) : sinon les flancs de l'anneau
   dessinent un petit trait vertical aux bords de l'écran */
body[data-header] .site-header.is-docked .sg-progress{
  clip-path:inset(calc(100% - var(--dk-rb) - 2px) calc((1 - var(--sp, 0)) * 100%) 0 0);
}

/* ---------- 1 · DOCK — la pilule se rattache au bord haut ---------- */
body[data-header="dock"] .site-header .header-inner{
  min-height:64px;
  /* ⚠️ POURQUOI pas var(--r-pill) (999px) : de 999px vers 30px, le coin reste
     visuellement rond jusqu'aux derniers instants puis casse d'un coup. */
  border-radius:32px;
}
body[data-header="dock"] .site-header.is-docked .header-inner{
  --dk-rb:30px;
  min-height:84px;
  padding-inline:max(32px, calc((100vw - 1440px) / 2 + 32px));
  border-radius:0 0 var(--dk-rb) var(--dk-rb);
  border-top-color:transparent;
  background-color:var(--glass-fill-strong);
  box-shadow:
    inset 0 -1px 0 rgba(229,162,13,.28),
    0 18px 40px -20px rgba(7,25,56,.55);
}
[data-theme="dark"] body[data-header="dock"] .site-header.is-docked .header-inner,
body[data-theme="dark"][data-header="dock"] .site-header.is-docked .header-inner{
  background-color:rgba(9,20,46,.92);
}

/* ---------- 2 · TRIPTYQUE — 3 capsules qui fusionnent en une bande ----------
   ⚠️ POURQUOI la bande est peinte par la pilule (::before) et pas par les
   capsules : trois fonds flous côte à côte laissent voir leurs jointures (bords
   du flou, demi-pixels, filets de séparation, trait or en trois morceaux). Une
   fois ancrées, les capsules deviennent transparentes et se fondent dans UNE
   surface. Un pseudo-élément et pas la pilule elle-même : un backdrop-filter sur
   un parent coupe celui des capsules dès le début de la transition (saut). */
body[data-header="triptych"] .site-header .header-inner{
  gap:10px; padding:0; min-height:0;
  background:none; border:0; border-radius:29px;
  -webkit-backdrop-filter:none; backdrop-filter:none; box-shadow:none;
  justify-content:space-between;
}
body[data-header="triptych"] .site-header .header-inner::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  border-radius:inherit;
  background:rgba(255,255,255,.72);
  -webkit-backdrop-filter:blur(34px) saturate(2.2); backdrop-filter:blur(34px) saturate(2.2);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.7), inset 0 -1px 0 rgba(229,162,13,.28);
  opacity:0;
  transition:opacity var(--dk-band) var(--dk-ease);
}
body[data-header="triptych"] .site-header .header-inner > :is(.brand,.nav-menu,.header-cta){
  min-height:58px; padding:0 20px;
  display:flex; align-items:center;
  background-color:var(--glass-fill);
  -webkit-backdrop-filter:blur(30px) saturate(2); backdrop-filter:blur(30px) saturate(2);
  border:1px solid var(--glass-border); border-radius:29px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.95), 0 12px 28px -14px rgba(7,25,56,.55);
  transition:min-height var(--dk-t) var(--dk-ease), border-radius var(--dk-t) var(--dk-ease),
             padding var(--dk-t) var(--dk-ease), background-color var(--dk-fill) var(--dk-ease),
             box-shadow var(--dk-edge) var(--dk-ease) var(--dk-edge-delay),
             border-color var(--dk-edge) var(--dk-ease) var(--dk-edge-delay),
             -webkit-backdrop-filter var(--dk-blur) var(--dk-ease), backdrop-filter var(--dk-blur) var(--dk-ease);
}
body[data-header="triptych"] .site-header .header-inner > .nav-menu{
  flex:1 1 auto; justify-content:center; padding:0 8px;
}
body[data-header="triptych"] .site-header .header-inner > .header-cta{ padding:0 12px 0 16px; }
[data-theme="dark"] body[data-header="triptych"] .site-header .header-inner > :is(.brand,.nav-menu,.header-cta){
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16), 0 12px 28px -14px rgba(0,0,0,.7);
}
[data-theme="dark"] body[data-header="triptych"] .site-header .header-inner::before{
  background:rgba(9,20,46,.72);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), inset 0 -1px 0 rgba(253,185,19,.22);
}

/* état ancré : les capsules se touchent, s'effacent, la bande apparaît dessous */
body[data-header="triptych"] .site-header.is-docked .header-inner{
  gap:0; border-radius:0 0 var(--dk-rb) var(--dk-rb);
  box-shadow:0 18px 40px -20px rgba(7,25,56,.6);
}
body[data-header="triptych"] .site-header.is-docked .header-inner::before{ opacity:1; }
body[data-header="triptych"] .site-header.is-docked .header-inner > :is(.brand,.nav-menu,.header-cta){
  min-height:80px; border-radius:0;
  background-color:transparent; border-color:transparent;
  -webkit-backdrop-filter:none; backdrop-filter:none;
  box-shadow:none;
}
body[data-header="triptych"] .site-header.is-docked .header-inner > .brand{
  border-radius:0 0 0 var(--dk-rb); padding-left:max(28px, calc((100vw - 1440px) / 2 + 28px));
}
body[data-header="triptych"] .site-header.is-docked .header-inner > .header-cta{
  border-radius:0 0 var(--dk-rb) 0; padding-right:max(20px, calc((100vw - 1440px) / 2 + 20px));
}

/* mobile : on garde la pilule simple, l'ancrage reste actif */
@media (max-width:980px){
  body[data-header="dock"] .site-header.is-docked .header-inner{ padding-inline:20px; min-height:72px; }
  /* le display:flex des capsules l'emportait sur le .nav-menu{display:none} de style.css */
  body[data-header="triptych"] .site-header .header-inner > .nav-menu{ display:none; }
  body[data-header="triptych"] .site-header .header-inner{ border-radius:27px; }
  body[data-header="triptych"] .site-header .header-inner > :is(.brand,.header-cta){ min-height:54px; border-radius:27px; }
  body[data-header="triptych"] .site-header.is-docked .header-inner > :is(.brand,.header-cta){ min-height:68px; }
  body[data-header="triptych"] .site-header.is-docked .header-inner > .brand{ border-radius:0 0 0 var(--dk-rb); }
  body[data-header="triptych"] .site-header.is-docked .header-inner > .header-cta{ border-radius:0 0 var(--dk-rb) 0; }
}
/* premier affichage : l'état est réglé d'un coup (voir header-dock.js) */
body[data-header] .site-header.dk-boot,
body[data-header] .site-header.dk-boot .header-inner,
body[data-header] .site-header.dk-boot .header-inner::before,
body[data-header] .site-header.dk-boot .header-inner > *{ transition:none !important; }

@media (prefers-reduced-motion:reduce){
  body[data-header] .site-header,
  body[data-header] .site-header .header-inner,
  body[data-header] .site-header .header-inner::before,
  body[data-header] .site-header .header-inner > *{ transition:none !important; }
}
