:root {
  --bg: #fafaf7;
  --navy: #101d3d;
  --blue: #5b4fea;
  --watermark: #e3e8f8;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
  background: var(--bg);
  color: var(--navy);
  -webkit-font-smoothing: antialiased;
}

/* ---------- Curseur personnalisé ---------- */

@media (hover: hover) and (pointer: fine) {
  body,
  body *,
  a,
  button,
  .btn {
    cursor: none;
  }

  .cursor-dot {
    position: fixed;
    top: 0;
    left: 0;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #ffffff;
    mix-blend-mode: difference;
    pointer-events: none;
    z-index: 9999;
    transform: translate(-50%, -50%) scale(1);
    transition: transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .cursor-dot--active {
    transform: translate(-50%, -50%) scale(0.7);
  }

  .cursor-trail {
    position: fixed;
    top: 0;
    left: 0;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--blue);
    pointer-events: none;
    z-index: 9998;
    transform: translate(-50%, -50%) scale(1);
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease;
  }

  .cursor-trail--active {
    transform: translate(-50%, -50%) scale(2.4);
    opacity: 0.35;
  }

  .hero__card,
  .hero__card * {
    user-select: none;
    -webkit-user-select: none;
  }

  .cursor-dot--click {
    transform: translate(-50%, -50%) scale(0.6);
  }
}

html {
  scroll-padding-top: 120px;
}

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

/* ---------- Hero ---------- */

.hero {
  position: relative;
  overflow-x: clip;
}

.hero__inner {
  position: relative;
  max-width: 1360px;
  margin: 0 auto;
  padding: 142px 48px 80px;
  display: flex;
  flex-direction: column;
}

.hero__visual {
  position: relative;
  display: flex;
  flex-direction: column;
}

.hero__watermark {
  position: absolute;
  right: -60px;
  top: 60px;
  width: 980px;
  height: 1150px;
  object-fit: fill;
  opacity: 0.18;
  z-index: -1;
  pointer-events: none;
}

/* ---------- Header ---------- */

.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 900;
  padding: 26px 0;
  /* Au repos, la barre est transparente et se pose sur le hero. */
  background: transparent;
  transition: padding 0.3s cubic-bezier(0.16, 1, 0.3, 1),
              background-color 0.3s ease;
}

.header__inner {
  max-width: 1360px;
  margin: 0 auto;
  padding: 0 48px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  transition: max-width 0.4s cubic-bezier(0.16, 1, 0.3, 1),
              padding 0.4s cubic-bezier(0.16, 1, 0.3, 1),
              background-color 0.3s ease,
              border-radius 0.4s cubic-bezier(0.16, 1, 0.3, 1),
              box-shadow 0.3s ease;
}

/* Au défilement la barre se contracte en pilule flottante : le bandeau
   pleine largeur laisse place à un bloc blanc arrondi, plus étroit. */
.header--scrolled {
  padding: 14px 0;
}

.header--scrolled .header__inner {
  max-width: 1120px;
  padding: 10px 14px 10px 44px;
  background: #ffffff;
  border-radius: 100px;
  box-shadow: 0 18px 40px -22px rgba(16, 29, 61, 0.45),
              0 2px 8px -4px rgba(16, 29, 61, 0.14);
}

.brand__logo,
.header .nav__cta {
  transition: height 0.3s cubic-bezier(0.16, 1, 0.3, 1),
              padding 0.3s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.2s ease, box-shadow 0.2s ease;
}

.header--scrolled .brand__logo { height: 36px; }
.header--scrolled .nav__cta { padding: 11px 22px; }

@media (prefers-reduced-motion: reduce) {
  .header, .header__inner, .brand__logo, .header .nav__cta { transition: none; }
}

.brand {
  display: flex;
  align-items: center;
  /* Le PNG contient le monogramme ET le mot "Altura Studio" ; au défilement
     on rogne le conteneur sur la largeur du seul monogramme (≈23 % du
     fichier) plutôt que de charger une seconde image. */
  overflow: hidden;
  max-width: 170px;
}

.header--scrolled .brand {
  max-width: 26px;
}

/* Dans la pilule, les liens se détachent du bloc de droite pour occuper le
   centre : le logo réduit et le CTA tiennent chacun leur extrémité. Réservé
   au grand écran : en dessous, les liens sont dans le panneau du menu. */
@media (min-width: 901px) {
  .header--scrolled .nav__links {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    margin-right: 0;
  }
}

.brand__logo {
  height: 52px;
  width: auto;
  max-width: none;
  display: block;
  flex: none;
}

.nav {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Des liens espacés plutôt qu'une barre en pilule : le conteneur blanc
   bordé est le réflexe des gabarits, pas d'une nav de studio. */
.nav__links {
  display: flex;
  align-items: center;
  gap: 32px;
  margin-right: 36px;
}

.nav__link {
  position: relative;
  font-size: 14px;
  font-weight: 500;
  color: #4b5573;
  padding: 4px 0;
  transition: color 0.2s ease;
}

.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--navy);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.nav__link:hover {
  color: var(--navy);
}

.nav__link:hover::after {
  transform: scaleX(1);
}

.nav__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: #ffffff;
  padding: 13px 24px;
  border-radius: 100px;
  box-shadow: 0 8px 18px -8px rgba(61, 91, 234, 0.6);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.nav__cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 22px -8px rgba(61, 91, 234, 0.7);
}

.nav__cta .arrow {
  display: inline-flex;
  transition: transform 0.2s ease;
}

.arrow svg {
  width: 16px;
  height: 16px;
  display: block;
}

.nav__cta:hover .arrow {
  transform: translateX(3px);
}

/* ---------- Menu mobile ---------- */

.nav__burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid #e0e3ef;
  border-radius: 12px;
  background: #ffffff;
  cursor: pointer;
}

.nav__burger-trait {
  display: block;
  width: 18px;
  height: 1.8px;
  margin: 0 auto;
  border-radius: 2px;
  background: var(--navy);
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.2s ease;
}

/* Ouvert, les deux traits se croisent : pas de troisième barre à animer. */
.nav__burger[aria-expanded="true"] .nav__burger-trait:first-child {
  transform: translateY(4px) rotate(45deg);
}

.nav__burger[aria-expanded="true"] .nav__burger-trait:last-child {
  transform: translateY(-4px) rotate(-45deg);
}

/* ---------- Content ---------- */

.hero__content {
  font-family: "IBM Plex Sans", sans-serif;
  text-align: center;
  margin-top: 60px;
  padding-bottom: 24px;
}

/* Une ligne posée sur le fond : encadrer trois mots dans une pilule
   ombrée est un tic de gabarit. */
.hero__rating {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-family: "DM Sans", sans-serif;
  font-size: 13.5px;
  color: #6b7593;
  margin-bottom: 20px;
}

.hero__stars {
  display: inline-flex;
  gap: 2px;
}

.hero__stars svg {
  width: 16px;
  height: 16px;
  display: block;
  fill: #f5b301;
}

.hero__rating-score {
  font-weight: 700;
  color: var(--navy);
}

.hero__rating-sep {
  width: 1px;
  height: 15px;
  background: #e0e3ec;
}

.hero__rating-src {
  font-weight: 500;
}

.hero__g b {
  font-weight: 700;
}

.hero__g b:nth-child(1) { color: #4285f4; }
.hero__g b:nth-child(2) { color: #ea4335; }
.hero__g b:nth-child(3) { color: #fbbc05; }
.hero__g b:nth-child(4) { color: #4285f4; }
.hero__g b:nth-child(5) { color: #34a853; }
.hero__g b:nth-child(6) { color: #ea4335; }

.hero__title {
  font-size: 72px;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.03em;
  max-width: 1080px;
  margin: 0 auto;
}

:root {
  --shine-gradient: linear-gradient(105deg,
    #4a3fd6 0%,
    #5b4fea 40%,
    #7a6eee 50%,
    #5b4fea 60%,
    #4a3fd6 100%);
}

.shine-text {
  background-image: var(--shine-gradient);
  background-size: 200% 100%;
  background-position: 100% 0;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: shine 3.2s linear infinite;
}

.shine-surface {
  background-image: var(--shine-gradient);
  background-size: 200% 100%;
  background-position: 100% 0;
  animation: shine 3.2s linear infinite;
}

.shine-text .arrow {
  color: var(--blue);
}

@keyframes shine {
  0%   { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

.hero__title .dot {
  display: inline-block;
  width: 0.17em;
  height: 0.17em;
  background: var(--blue);
  border-radius: 50%;
  margin-left: 0.07em;
}

.hero__tagline {
  font-family: "IBM Plex Sans", sans-serif;
  font-weight: 500;
  font-size: 19px;
  margin-top: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #3c4863;
}

.hero__tagline-line {
  width: 48px;
  height: 2px;
  background: var(--blue);
  margin-right: 22px;
  flex-shrink: 0;
}

.hero__services {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  flex-wrap: wrap;
  gap: 30px 44px;
  margin-top: 32px;
}

.hero__service {
  display: flex;
  align-items: center;
  gap: 12px;
}

.hero__service-icon {
  width: 40px;
  height: 46px;
  flex-shrink: 0;
  object-fit: contain;
}

.hero__service span {
  font-family: "Montserrat", sans-serif;
  font-weight: 500;
  font-size: 13px;
  line-height: 1.35;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--navy);
  text-align: left;
}

.hero__actions {
  display: flex;
  justify-content: center;
  gap: 18px;
  margin-top: 48px;
}

.btn {
  display: inline-flex;
  align-items: center;
  font-size: 16px;
  font-weight: 600;
  border-radius: 100px;
  padding: 16px 30px;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
  /* Sans ça, un <button class="btn"> hérite du `2px outset` du navigateur et
     ne ressemble plus à un <a class="btn">. .btn--ghost repose sa bordure. */
  border: none;
}

.btn .arrow {
  margin-left: 10px;
  display: inline-block;
  transition: transform 0.2s ease;
}

.btn:hover .arrow {
  transform: translateX(4px);
}

.btn--primary {
  color: #ffffff;
  box-shadow: 0 10px 24px -10px rgba(61, 91, 234, 0.65);
}

.btn--primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 28px -10px rgba(61, 91, 234, 0.75);
}

.btn--ghost {
  background-color: #ffffff;
  border: 1.5px solid #d7dae4;
}

.btn--ghost:hover {
  border-color: #9db4ff;
  transform: translateY(-2px);
}

/* ---------- Card (bordures uniquement pour l'instant) ---------- */

/* ---------- Bandeau logos clients ---------- */

.marquee {
  width: 100%;
  max-width: 1100px;
  margin: 44px auto 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.marquee__track {
  display: flex;
  width: max-content;
  gap: 0;
  animation: marquee-scroll 52s linear infinite;
}

.marquee__item {
  flex-shrink: 0;
  width: 232px;
  height: 125px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 13px;
}

.marquee__item img {
  width: auto;
  max-width: 190px;
  display: block;
  object-fit: contain;
  filter: brightness(0) invert(0.22);
}

/* single-line wordmarks — normalised to the same cap height */
.marquee__item--wordmark img {
  height: 34px;
}

.marquee__item--blackstone img {
  height: 46px;
}

.marquee__item--blackstone {
  transform: translateY(8px);
  margin-left: 12px;
}

/* stacked / multi-line logo — needs more height for equal presence */
.marquee__item--stacked img {
  height: 78px;
}

/* TE4M UP — tall lockup, needs extra height for the wordmark to read */
.marquee__item--te4mup img {
  height: 108px;
}

.marquee__item--te4mup {
  transform: translateY(-8px);
}

/* NVM Finance — icon + text lockup, keeps its own greens */
.marquee__item--nvm {
  flex-direction: column;
  gap: 4px;
  transform: translateY(-8px);
}

.marquee__item--nvm img {
  height: 66px;
  filter: none;
}

.marquee__name {
  font-family: "Nunito Sans", sans-serif;
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #383838;
}

.marquee__name span {
  color: #9a9a9a;
}

@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
}

.hero__card {
  flex-shrink: 0;
  margin-top: 8px;
  margin-left: 12px;
  margin-right: 12px;
  background: #f5f5f5;
  border: 1.5px solid var(--navy);
  border-radius: 24px 24px 0 0;
  box-shadow: 0 30px 60px -30px rgba(16, 29, 61, 0.18);
  overflow: hidden;
}

/* ---------- Simulation "vos 12 prochains mois" ---------- */

.sim {
  /* Helvetica Now Pro Display n'est pas une Google Font : la pile retombe
     sur Helvetica Neue / Arial tant que les .woff2 ne sont pas ajoutés au
     projet (elle prendra le dessus si la police est installée). Medium =
     graisse 500. */
  font-family: "Helvetica Now Display", "Helvetica Now Pro Display",
               "Helvetica Neue", "Instrument Sans", Helvetica, Arial, sans-serif;
  font-weight: 500;
}

/* window bar */
.sim__bar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 15px 26px;
  border-bottom: 1px solid #e7e9f0;
  background: #fbfbfc;
}

/* Réservés au format téléphone : barre d'état de l'appareil et nom de
   l'application sur les bannières de notification. */
.sim__statut,
.sim__event-app {
  display: none;
}

.sim__dots {
  display: inline-flex;
  gap: 6px;
}

.sim__dots i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.sim__dots i:nth-child(1) { background: #f0b9b0; }
.sim__dots i:nth-child(2) { background: #f2d9a8; }
.sim__dots i:nth-child(3) { background: #b8e0c2; }

.sim__bar-title {
  font-size: 12.5px;
  font-weight: 500;
  color: #8890ab;
}

.sim__body {
  padding: 30px 36px 34px;
}

/* header */
.sim__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
}

.sim__title {
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--navy);
}

/* year scrubber: the 12 months play out on this bar */
.sim__scrub {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 24px;
}

.sim__scrub-date {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 600;
  color: #8890ab;
}

.sim__scrub-track {
  position: relative;
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: #ecedf2;
}

.sim__scrub-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 0%;
  border-radius: 2px;
  background: var(--navy);
  animation: sim-scrub 12s linear 0.4s forwards;
}

.sim__scrub-fill::after {
  content: "";
  position: absolute;
  right: -7px;
  top: 50%;
  transform: translateY(-50%);
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #fff;
  border: 3px solid #4a3fd6;
  box-shadow: 0 2px 8px rgba(74, 63, 214, 0.35);
}

@keyframes sim-scrub {
  from { width: 0%; }
  to   { width: 100%; }
}

/* two-panel layout: event feed + live widgets */
.sim__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 16px;
  margin-top: 22px;
}

/* event feed */
/* Colonne en flex : les étapes se répartissent sur toute la hauteur de la
   grille plutôt que de s'empiler en haut en laissant un vide sous la dernière. */
.sim__feed {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Même traitement carte que .sim__result à droite (fond blanc, coins
   arrondis, pas de filet) pour que la timeline et les widgets partagent
   un seul et même vocabulaire visuel. */
.sim__event {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 18px;
  padding: 14px 16px;
  background: #ffffff;
  border-radius: 14px;
  opacity: 0;
  transform: translateY(8px);
  animation: sim-in 0.55s cubic-bezier(0.16, 1, 0.3, 1) var(--d) forwards;
}

@keyframes sim-in {
  to { opacity: 1; transform: none; }
}

/* Bannière de notification. L'entrée glisse depuis au-dessus de l'écran et
   dépasse légèrement sa place avant de s'y poser, comme le ressort d'iOS ;
   la sortie remonte, plus courte, en s'effaçant. */
@keyframes sim-notif {
  0%   { opacity: 0; transform: translate3d(0, -130%, 0) scale(0.94); }
  13%  { opacity: 1; transform: translate3d(0, 5px, 0) scale(1.008); }
  22%  { opacity: 1; transform: none; }
  74%  { opacity: 1; transform: none; }
  100% { opacity: 0; transform: translate3d(0, -60%, 0) scale(0.97); }
}

@keyframes sim-notif-fin {
  0%   { opacity: 0; transform: translate3d(0, -130%, 0) scale(0.94); }
  62%  { opacity: 1; transform: translate3d(0, 5px, 0) scale(1.008); }
  100% { opacity: 1; transform: none; }
}

.sim__event-icon {
  flex-shrink: 0;
  width: 22px;
  font-size: 15px;
  line-height: 1;
  color: var(--navy);
  display: flex;
  align-items: center;
  justify-content: center;
}

.sim__event-icon img {
  width: 100%;
  height: auto;
  display: block;
  /* Icônes ramenées à la même teinte navy que le reste du panneau, plutôt
     que leurs couleurs d'origine (rouge/orange/bleu...) qui juraient avec
     la palette violet/navy des cartes stats. */
  filter: brightness(0) saturate(100%) invert(13%) sepia(24%) saturate(1553%) hue-rotate(190deg) brightness(94%) contrast(94%);
}

.sim__event-body {
  display: flex;
  flex: 1;
  align-items: baseline;
  gap: 18px;
}

/* Colonne de dates de largeur fixe : les titres s'alignent, ce qui fait
   lire la liste comme un calendrier et non comme six blocs isolés. */
.sim__event-date {
  flex: 0 0 156px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: #4a3fd6;
}

.sim__event-title {
  flex: 1;
  font-size: 15.5px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--navy);
}

/* Le jalon final : un accent sur la date, pas un fond teinté. */
.sim__event--win .sim__event-date {
  color: #1a7f4f;
}

/* side widgets */
/* ---------- Panneau résultats (thème "Project Analytics", en bleu) ------
   3 cartes stats en haut (la première sur dégradé sombre), un graphique
   hebdomadaire large + une carte "prochaine étape" en dessous. Police :
   Space Grotesk, comme la référence. -------------------------------------- */

.sim__results {
  display: grid;
  /* minmax(0, 1fr) : sans quoi le contenu le plus large imposerait sa
     largeur minimale à sa colonne et déséquilibrerait les trois cartes. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  align-content: start;
  padding-left: 24px;
  border-left: 1px solid #ecedf2;
}

.sim__result {
  display: flex;
  flex-direction: column;
  background: #ffffff;
  border-radius: 18px;
  padding: 16px;
  opacity: 0;
  transform: translateY(8px);
  animation: sim-result 0.6s cubic-bezier(0.16, 1, 0.3, 1) var(--d) forwards;
}

@keyframes sim-result {
  to { opacity: 1; transform: none; }
}

/* Le graphique s'étale sur deux colonnes, la carte "prochaine étape" prend
   la troisième - mêmes proportions que la référence (≈ 2:1). */
.sim__panel--chart { grid-column: span 2; }

/* ----- Cartes stats (ligne du haut) ----- */

.sim__stat {
  justify-content: space-between;
  gap: 10px;
}

/* Les trois lignes partagent la même hauteur, calée sur les proportions
   des cartes de la référence (largeur/hauteur ≈ 240/158). */
.sim__results > .sim__result {
  min-height: 142px;
}

/* Fond scintillant de la carte mise en avant : même dégradé animé
   (--shine-gradient) que le texte/bouton de la hero section, posé via
   .shine-surface sur l'élément. */
.sim__stat--dark {
  border: 0;
  color: #ffffff;
}

.sim__result.sim__stat--dark {
  /* .sim__result pose un `background` en raccourci (donc background-image
     compris) et un `animation` de même spécificité que .shine-surface,
     déclaré plus tôt dans le fichier : sim__result gagnait et effaçait le
     dégradé. On les recombine ici pour que le scintillement s'affiche. */
  background-image: var(--shine-gradient);
  background-size: 200% 100%;
  background-position: 100% 0;
  /* En longhands, surtout pas le raccourci `animation` : il remettrait
     animation-play-state à `running`, et comme cette règle est plus
     spécifique (0,2,0) que la mise en pause plus bas (0,1,0), la carte
     s'animait avant l'heure : elle était déjà visible sur un dashboard
     censé être vide. */
  animation-name: sim-result, shine;
  animation-duration: 0.6s, 3.2s;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1), linear;
  animation-delay: var(--d), 0s;
  animation-iteration-count: 1, infinite;
  animation-fill-mode: forwards, none;
}

.sim__stat-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.sim__stat-title {
  /* Même police que les h2 du site (.section-title) : Inter, héritée du
     body par ces derniers. */
  font-size: 15.5px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--navy);
}

.sim__stat--dark .sim__stat-title { color: #ffffff; }

.sim__stat-value {
  font-size: 42px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  color: #0c1220;
}

.sim__stat--dark .sim__stat-value { color: #ffffff; }

.sim__stat-value em {
  font-style: normal;
  font-size: 20px;
  font-weight: 500;
  margin-left: 2px;
  color: #8a93ad;
}

.sim__approx {
  width: 26px;
  height: 32px;
  margin-right: 3px;
  vertical-align: -3px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Pied : petite puce carrée bordée (flèche montante) + texte en bleu,
   comme le "Increased from last month" vert de la référence. */
.sim__stat-foot {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 500;
  color: #4a3fd6;
}

.sim__stat--dark .sim__stat-foot { color: #c3c9ff; }

.sim__stat-chip {
  flex-shrink: 0;
  width: 17px;
  height: 17px;
  border: 1px solid currentColor;
  border-radius: 5px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 8px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234a3fd6' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l7-7 7 7M12 19V6'/%3E%3C/svg%3E");
}

.sim__stat--dark .sim__stat-chip {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23c3c9ff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l7-7 7 7M12 19V6'/%3E%3C/svg%3E");
}

/* ----- Graphique hebdomadaire (pilules) ----- */

.sim__panel {
  justify-content: space-between;
}

.sim__panel .sim__stat-title {
  font-size: 16.5px;
}

/* ----- Demi-jauge « Sources de trafic » (carte large) ----- */

.sim__half {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 34px;
  margin-top: 2px;
}

.sim__half-figure {
  position: relative;
  width: 178px;
  flex-shrink: 0;
}

.sim__half-figure svg {
  display: block;
  width: 100%;
  height: auto;
}

.sim__half-seg {
  fill: none;
  stroke-width: 24;
  stroke-linecap: round;
}

/* Ordre de dessin = empilement : le SEO recouvre le début du Direct, qui
   recouvre le début du segment hachuré - comme la référence. */
.sim__half-seg--seo    { stroke: var(--blue); }
.sim__half-seg--direct { stroke: var(--navy); }
.sim__half-seg--ads    { stroke: #9aa1e2; }

/* bottom suit la base de l'arc (remontée à y=95 dans le viewBox) pour que le
   « 64 % » reste centré dans la jauge. */
.sim__half-center {
  position: absolute;
  left: 50%;
  bottom: 6px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
}

.sim__half-center b {
  font-size: 23px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: #0c1220;
}

.sim__half-center small {
  margin-top: 4px;
  font-size: 11px;
  font-weight: 500;
  color: #4a3fd6;
}

.sim__legend {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 14px;
  font-weight: 500;
  color: #6b7593;
}

.sim__legend span {
  display: flex;
  align-items: center;
  gap: 8px;
}

.sim__legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}

.sim__legend-dot--seo    { background: var(--blue); }
.sim__legend-dot--direct { background: var(--navy); }
.sim__legend-dot--ads    { background: #9aa1e2; }

/* ----- SERP « Référencement » (carte de droite) ----- */

/* Un résultat de recherche qui remonte à la première place : la ligne
   accentuée monte dans un emplacement laissé vide, sans recouvrir les
   autres. */
/* Les lignes sont posées en absolu sur une grille de 4 emplacements espacés
   de 21px (14px de ligne + 7px de gouttière). Seuls les 3 premiers sont dans
   le cadre : le 4e est sous le bord bas, et c'est ce débord, clippé, qui
   fait entrer le résultat bleu et sortir le dernier gris. */
.sim__serp {
  position: relative;
  flex: 1;
  min-height: 56px;
  margin-top: 8px;
  margin-bottom: 8px;
  overflow: hidden;
}

.sim__serp-row {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  animation-duration: 6s;
  animation-iteration-count: infinite;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
  /* `backwards` : pendant le délai d'attente, chaque ligne tient déjà sa
     première keyframe (le classement de départ) au lieu d'afficher sa
     position de repos puis de sauter au démarrage. */
  animation-fill-mode: backwards;
  animation-delay: calc(var(--d) + 0.4s);
}

.sim__serp-row b,
.sim__serp-row em {
  display: block;
  border-radius: 3px;
  background: #e4e7f2;
}

.sim__serp-row b { height: 6px; width: 58%; }
.sim__serp-row em { height: 4px; width: 82%; background: #eef0f6; }

/* La position de repos de chaque ligne est son état d'ARRIVÉE : c'est ce qui
   s'affiche quand les animations sont coupées (prefers-reduced-motion), sans
   avoir à redéclarer le classement final là-bas. */
.sim__serp-row--you         { transform: translateY(-42px); animation-name: sim-serp-you; }
.sim__serp-row:nth-child(2) { transform: translateY(-21px); animation-name: sim-serp-r1; }
.sim__serp-row:nth-child(3) { transform: translateY(0);     animation-name: sim-serp-r2; }
.sim__serp-row:nth-child(4) { transform: translateY(21px);  animation-name: sim-serp-r3; }

.sim__serp-row--you b { width: 46%; background: var(--blue); }
.sim__serp-row--you em { width: 74%; background: #c3c9ff; }

/* Trois bascules successives, une par concurrent doublé. À chaque temps le
   bleu gagne un cran et LE SEUL gris qu'il dépasse descend d'un cran, d'où
   quatre pistes distinctes plutôt qu'un décalage en bloc :
     départ   gris1 gris2 gris3 · bleu hors cadre
     12-24 %  le bleu entre, gris3 sort par le bas
     24-36 %  le bleu double gris2
     36-48 %  le bleu double gris1, il est premier
     88-96 %  le bleu redevient gris (voir sim-serp-fade-*)

   Le reste du reset est GRATUIT : chaque ligne finit sa boucle un cran plus
   bas qu'elle ne l'a commencée, donc au raccord 100 %/0 % les quatre lignes
   remontent d'un cran d'un coup. Comme le bleu vient de repasser au gris,
   les trois lignes visibles sont alors interchangeables : la permutation ne
   se voit pas, et le cycle repart sur trois gris sans rien effacer. */
@keyframes sim-serp-you {
  0%, 12%   { transform: translateY(21px); }
  24%       { transform: translateY(0); }
  36%       { transform: translateY(-21px); }
  48%, 100% { transform: translateY(-42px); }
}

@keyframes sim-serp-r1 {
  0%, 36%   { transform: translateY(-42px); }
  48%, 100% { transform: translateY(-21px); }
}

@keyframes sim-serp-r2 {
  0%, 24%   { transform: translateY(-21px); }
  36%, 100% { transform: translateY(0); }
}

@keyframes sim-serp-r3 {
  0%, 12%   { transform: translateY(0); }
  24%, 100% { transform: translateY(21px); }
}

/* La bascule de teinte du résultat mis en avant : arrivé premier, il repasse
   au gris pour rendre le raccord invisible. Les largeurs suivent aussi,
   sinon la ligne resterait plus courte que les autres et trahirait la
   permutation. Au raccord, elle retrouve son bleu, hors cadre, donc jamais
   à vue. */
.sim__serp-row--you b,
.sim__serp-row--you em {
  animation-duration: 6s;
  animation-iteration-count: infinite;
  animation-timing-function: ease-in-out;
  animation-fill-mode: backwards;
  animation-delay: calc(var(--d) + 0.4s);
}

.sim__serp-row--you b  { animation-name: sim-serp-fade-b; }
.sim__serp-row--you em { animation-name: sim-serp-fade-em; }

@keyframes sim-serp-fade-b {
  0%, 88%   { background-color: var(--blue); width: 46%; }
  96%, 100% { background-color: #e4e7f2;     width: 58%; }
}

@keyframes sim-serp-fade-em {
  0%, 88%   { background-color: #c3c9ff; width: 74%; }
  96%, 100% { background-color: #eef0f6; width: 82%; }
}

/* closing CTA */
.sim__cta {
  display: flex;
  align-items: center;
  gap: 32px;
  margin-top: 30px;
}

.sim__cta-text {
  flex: 1;
  font-size: 13.5px;
  color: #6b7593;
}

.sim__cta-text b {
  color: var(--navy);
  font-weight: 700;
}

.sim__cta-action {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}

.sim__cta-note {
  font-size: 10.5px;
  font-weight: 600;
  color: #8890ab;
}

/* Le CTA pulse une fois la simulation terminée (12,8 s), pour relancer l'œil.
   Une `animation` de même spécificité que celle de .shine-surface l'écraserait
   au lieu de s'y ajouter : on redéclare donc le dégradé et les deux animations
   ensemble, comme pour .sim__result.sim__stat--dark plus haut. */
.sim__cta-btn {
  background-image: var(--shine-gradient);
  background-size: 200% 100%;
  background-position: 100% 0;
  animation: shine 3.2s linear infinite, sim-glow 2.4s ease 12.8s 3;
}

@keyframes sim-glow {
  0%, 100% { box-shadow: none; }
  50%      { box-shadow: 0 0 0 7px rgba(74, 63, 214, 0.18); }
}

/* The sequence is paused from the very first frame — a default, not something
   JS switches on, so no animation can slip through during page load. It runs
   once the configurator is done (.is-playing); the <noscript> block in <head>
   releases it for visitors without JS. */
/* `animation-play-state` ne s'hérite pas : les b/em du résultat mis en avant
   portent leur propre animation de teinte, il faut donc les citer aussi. */
.sim__scrub-fill,
.sim__event,
.sim__result,
.sim__serp-row,
.sim__serp-row--you > *,
.sim__cta-btn {
  animation-play-state: paused;
}

.sim.is-playing .sim__scrub-fill,
.sim.is-playing .sim__event,
.sim.is-playing .sim__result,
.sim.is-playing .sim__serp-row,
.sim.is-playing .sim__serp-row--you > *,
.sim.is-playing .sim__cta-btn {
  animation-play-state: running;
}

@media (prefers-reduced-motion: reduce) {
  .sim__scrub-fill,
  .sim__event,
  .sim__result,
  .sim__result *,
  .sim__cta-btn {
    animation: none;
  }
  .sim__scrub-fill { width: 100%; }
  .sim__event,
  .sim__result { opacity: 1; transform: none; }
  /* Pas de repli à écrire ici : la position de repos de chaque .sim__serp-row
     est déjà son classement d'arrivée. */
}

/* ---------- Shared layout ---------- */

.container {
  max-width: 1360px;
  margin: 0 auto;
  padding: 0 48px;
}

.section-head {
  max-width: 900px;
  margin: 0 auto 56px;
  text-align: center;
}

/* Les titres de section tiennent sur une ligne tant que la place le
   permet ; en dessous ils passent à la ligne au lieu de déborder. */
.section-title {
  white-space: nowrap;
}

@media (max-width: 1080px) {
  .section-title {
    white-space: normal;
    text-wrap: balance;
  }
}

.section-kicker {
  display: inline-block;
  font-family: "DM Sans", sans-serif;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 14px;
}
.section-subtitle {
  font-family: "DM Sans", sans-serif;
  font-size: 19px;
  color: #6b7593;
  margin-top: 16px;
}

.section-title {
  font-size: 48px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.25;
}

/* ---------- Preuve sociale ---------- */

.proof {
  padding: 60px 0;
  border-top: 1px solid #eceef4;
  border-bottom: 1px solid #eceef4;
}

.proof__label {
  text-align: center;
  font-family: "DM Sans", sans-serif;
  font-size: 13px;
  font-weight: 500;
  color: #8890ab;
  margin-bottom: 30px;
}

.proof__logos {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 48px;
}

.proof__logo {
  font-size: 19px;
  font-weight: 700;
  color: #b7bccb;
  letter-spacing: -0.01em;
}

.proof__logo em {
  font-style: normal;
  font-weight: 500;
}

/* ---------- Services ---------- */

.features {
  min-height: 100vh;
  padding: 72px 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.features .container {
  max-width: 1720px;
  width: 100%;
}

.features__title {
  font-size: 48px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.25;
  text-align: center;
  max-width: 860px;
  margin: 0 auto 44px;
}

.features__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: start;
}

.features__visual {
  position: relative;
  height: 640px;
  border-radius: 20px;
  overflow: hidden;
  background: linear-gradient(160deg, #cfe0ff 0%, #eef3ff 45%, #dbe6ff 100%);
}

.features__stat-card {
  position: absolute;
  left: 24px;
  bottom: 24px;
  width: calc(100% - 48px);
  max-width: 320px;
  background: #ffffff;
  border-radius: 14px;
  padding: 20px 22px;
  box-shadow: 0 24px 48px -20px rgba(16, 29, 61, 0.3);
}

.features__stat-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #8890ab;
}

.features__stat-label {
  font-family: "DM Sans", sans-serif;
  font-size: 13px;
  font-weight: 500;
}

.features__stat-top svg {
  width: 18px;
  height: 18px;
}

.features__stat-bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-top: 22px;
}

.features__stat-value {
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--navy);
}

.features__stat-value span {
  font-family: "DM Sans", sans-serif;
  font-size: 13px;
  font-weight: 500;
  color: #8890ab;
  margin-left: 4px;
}

.features__stat-badge {
  font-family: "DM Sans", sans-serif;
  font-size: 13px;
  font-weight: 700;
  color: var(--blue);
}

/* ---------- Panneaux de services (visuel de gauche) ---------- */

/* Les panneaux sont empilés : celui qui sort se fond dans celui qui entre
   plutôt que de disparaître d'un coup. Le léger recul donne un sens au
   remplacement sans déplacer la composition. */
.features__panel {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px) scale(0.985);
  transition: opacity 0.6s ease,
              transform 0.6s cubic-bezier(0.16, 1, 0.3, 1),
              visibility 0s linear 0.6s;
}

.features__panel.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.6s ease,
              transform 0.6s cubic-bezier(0.16, 1, 0.3, 1),
              visibility 0s;
}

/* Repli sans JS : le script retire l'attribut au démarrage, donc seul un
   visiteur sans JavaScript voit encore les panneaux masqués en dur. */
.features__panel[hidden] {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .features__panel,
  .features__panel.is-active {
    transition: opacity 0.2s ease, visibility 0s;
    transform: none;
  }
}

/* Trois rangées de hero sections qui défilent en continu. Le sens alterné de
   la rangée du milieu casse l'effet de bloc qu'on aurait avec trois défilés
   parallèles. */
.hero-wall {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 18px;
}

.hero-wall__row {
  overflow: hidden;
  /* Les extrémités s'effacent : sans ça, les vignettes seraient tranchées net
     sur les bords du panneau. */
  mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
}

.hero-wall__track {
  display: flex;
  gap: 18px;
  width: max-content;
  animation: hero-wall-scroll 46s linear infinite;
}

.hero-wall__track img {
  height: 178px;
  width: auto;
  display: block;
  border-radius: 10px;
  box-shadow: 0 14px 30px -16px rgba(16, 29, 61, 0.45);
}

/* Le contenu est dupliqué : la boucle rejoue à -50 %, soit exactement une
   copie plus loin, donc le raccord est invisible. */
@keyframes hero-wall-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - 9px)); }
}

/* Défilement vers la droite : la même rampe, jouée à l'envers. */
.hero-wall__row--droite .hero-wall__track {
  animation-direction: reverse;
}

.hero-wall__row--gauche .hero-wall__track {
  animation-duration: 38s;
}

@media (prefers-reduced-motion: reduce) {
  .hero-wall__track { animation: none; }
}

/* ---------- Panneau "Logiciels et SaaS" : une application qui tourne ------
   Le mur de hero sections du panneau Sites web argumente par le nombre ; ici
   c'est l'inverse, un seul objet mais qui a un état et qui avance. D'où un
   mouvement interne plutôt que latéral.

   Tout est en texte réel : mélanger des barres grises de gabarit et de vraies
   étiquettes donnait deux registres qui juraient, et des chiffres qui
   semblaient sortis de nulle part. Les trois compteurs s'additionnent
   maintenant au total affiché en pied de tableau. ------------------------ */

.app {
  position: absolute;
  inset: 34px;
  display: flex;
  background: #ffffff;
  border-radius: 14px;
  overflow: hidden;
  font-family: "DM Sans", sans-serif;
  box-shadow: 0 30px 60px -28px rgba(16, 29, 61, 0.42);
}

/* ----- Barre latérale ----- */

.app__side {
  flex-shrink: 0;
  width: 168px;
  padding: 20px 12px;
  background: #f6f7fc;
  border-right: 1px solid #eceef6;
  display: flex;
  flex-direction: column;
}

.app__marque {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--navy);
  padding: 0 8px;
  margin-bottom: 22px;
}

.app__marque-signe {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  background: var(--blue);
}

.app__nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.app__nav-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 500;
  color: #6b7593;
}

.app__nav-ico {
  flex-shrink: 0;
  width: 13px;
  height: 13px;
  border-radius: 4px;
  background: #cdd3e3;
}

.app__nav-item--actif {
  background: #e6e3ff;
  color: var(--blue);
  font-weight: 700;
}

.app__nav-item--actif .app__nav-ico { background: var(--blue); }

.app__nav-sep {
  height: 1px;
  background: #e4e7f2;
  margin: 10px 8px;
}

/* Poussé en bas : la place du compte utilisateur dans toutes les
   applications, et ça remplit la colonne sans meubler. */
.app__user {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 8px 2px;
  border-top: 1px solid #e4e7f2;
  font-size: 12px;
  font-weight: 500;
  color: #6b7593;
}

.app__user-ava {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #d5d9e8;
}

/* ----- Zone principale ----- */

.app__main {
  flex: 1;
  min-width: 0;
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
}

.app__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.app__titre {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--navy);
}

.app__outils {
  display: flex;
  align-items: center;
  gap: 9px;
}

.app__recherche {
  display: flex;
  align-items: center;
  height: 26px;
  padding: 0 14px;
  border-radius: 13px;
  background: #f1f3fa;
  font-size: 11.5px;
  color: #9aa1b8;
}

.app__rond {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: #e6e9f4;
}

.app__kpis {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin: 18px 0 16px;
}

.app__kpi {
  position: relative;
  padding: 12px 14px;
  border: 1px solid #eceef6;
  border-radius: 10px;
}

.app__kpi-label {
  display: block;
  font-size: 10.5px;
  font-weight: 500;
  color: #8890ab;
  margin-bottom: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app__kpi-valeur {
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--navy);
}

/* Le "+1" accompagne l'incrément réel du compteur : il le rend lisible sans
   le remplacer. */
.app__kpi-plus {
  position: absolute;
  top: 26px;
  left: 52px;
  font-size: 11px;
  font-weight: 700;
  color: #1a7f4f;
  opacity: 0;
}

.app__kpi-plus.est-visible {
  animation: app-plus 1.6s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes app-plus {
  0%   { opacity: 0; transform: translateY(4px); }
  25%  { opacity: 1; transform: translateY(-2px); }
  100% { opacity: 0; transform: translateY(-14px); }
}

/* ----- Filtres, en-tête et pied de tableau -----
   Ce trio est ce qui distingue un outil métier d'un tableau de bord : on y
   trie, on y pagine. Le hero porte déjà un dashboard analytique, ce panneau
   doit raconter autre chose. */
.app__filtres {
  display: flex;
  gap: 7px;
  margin-bottom: 14px;
}

.app__filtre {
  font-size: 10.5px;
  font-weight: 600;
  color: #8890ab;
  background: #f3f5fb;
  border-radius: 11px;
  padding: 5px 12px;
}

.app__filtre--actif {
  color: #ffffff;
  background: var(--navy);
}

.app__thead,
.app__row-inner {
  display: flex;
  align-items: center;
  gap: 12px;
}

.app__thead {
  padding-bottom: 8px;
  border-bottom: 1px solid #e4e7f2;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #a7aec4;
}

.app__th--ref   { flex: 1; margin-left: 34px; }
.app__th--heure { width: 44px; flex-shrink: 0; }
.app__th--etat  { width: 74px; flex-shrink: 0; }

.app__pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 12px;
  border-top: 1px solid #f0f2f8;
  font-size: 11px;
  color: #8890ab;
}

.app__pages {
  display: flex;
  gap: 6px;
}

.app__page {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  border: 1px solid #e4e7f2;
  font-size: 13px;
  line-height: 1;
  color: #b0b5c6;
}

.app__page--actif {
  background: #f3f5fb;
  color: var(--navy);
}

/* ----- Les lignes -----
   La hauteur est animée sur le conteneur et tout le visuel vit dans
   .app__row-inner : à hauteur nulle, la bordure disparaît avec le reste. */
.app__table {
  flex: 1;
  min-height: 0;
  /* La file compte toujours une ligne de plus que la place disponible (celle
     qui se replie avant de quitter le DOM) : sans ce clip elle chevaucherait
     le pied de tableau. Une ligne coupée en bas se lit comme une liste qui
     continue, ce que la pagination dit déjà. */
  overflow: hidden;
}

.app__row {
  height: 48px;
  overflow: hidden;
  transition: height 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}

.app__row--ferme {
  height: 0;
}

.app__row-inner {
  height: 48px;
  border-bottom: 1px solid #f0f2f8;
  transition: background 0.7s ease;
}

/* Surlignage d'arrivée, éteint dès la validation. */
.app__row--neuf .app__row-inner {
  background: #f4f2ff;
}

.app__ico {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 6px;
}

.app__ico--devis   { background: #dfe3ff; }
.app__ico--contrat { background: #e2dcff; }
.app__ico--facture { background: #fdeed6; }

.app__cell {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.app__ref {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--navy);
}

.app__type {
  font-size: 10.5px;
  color: #8890ab;
}

.app__heure {
  width: 44px;
  flex-shrink: 0;
  font-size: 11px;
  color: #8890ab;
}

.app__badge {
  position: relative;
  flex-shrink: 0;
  width: 74px;
  height: 21px;
}

.app__badge-etat {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  border-radius: 11px;
  transition: opacity 0.4s ease;
}

.app__badge-etat--valide {
  color: #1a7f4f;
  background: #dff2e7;
}

.app__badge-etat--attente {
  color: #9a6a12;
  background: #fbeed3;
  opacity: 0;
}

/* Une demande en attente masque son badge "Validé" tant qu'elle n'est pas
   traitée : les deux états se croisent en fondu. */
.app__row--attente .app__badge-etat--attente { opacity: 1; }
.app__row--attente .app__badge-etat--valide  { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .app__row,
  .app__row-inner,
  .app__badge-etat { transition: none; }
  .app__kpi-plus.est-visible { animation: none; }
}

/* ---------- Panneau "Identité visuelle" : la déclinaison ------------------
   Sites web argumente par le nombre, Logiciels par la profondeur ; ici c'est
   la cohérence. Un seul signe, repris à l'identique sur chaque support, et
   une gamme colorée qui bascule d'un bloc : c'est la simultanéité qui prouve
   qu'il s'agit d'un système et non d'une collection.

   @property rend --accent interpolable : sans lui la couleur sauterait d'une
   gamme à l'autre au lieu de fondre. Les navigateurs qui l'ignorent gardent
   la bascule, en moins doux. ---------------------------------------------- */

@property --accent {
  syntax: "<color>";
  inherits: true;
  initial-value: #5b4fea;
}

@property --accent-doux {
  syntax: "<color>";
  inherits: true;
  initial-value: #ece9ff;
}

.bp {
  position: absolute;
  inset: 30px;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  /* La dernière rangée prend ce qui reste : la maquette s'y loge en entier
     au lieu de déborder sous la planche. */
  grid-template-rows: auto auto minmax(0, 1fr);
  gap: 14px;
  font-family: "DM Sans", sans-serif;
  --accent: #231001;
  --accent-doux: #f9efe6;
  --encre: #4a2a16;
  --sable: #e4d5c7;
}

/* Logotype Pure : le fichier livré au client, repris à l'identique du
   bandeau à l'étiquette du flacon. Le PNG ne porte que la découpe du
   lettrage (blanc sur fond transparent) et sert de masque : `background`
   fournit la couleur, donc la même source se pose aussi bien en crème sur
   le brun qu'en brun sur le crème. */
.bp__signe {
  display: block;
  aspect-ratio: 1267 / 575;
  background: currentColor;
  -webkit-mask-image: url("assets/cases/pure-logo.png");
  mask-image: url("assets/cases/pure-logo.png");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* ----- Bandeau logo ----- */

.bp__logo {
  position: relative;
  overflow: hidden;
  grid-column: span 6;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 18px 28px;
  border-radius: 14px;
  background: var(--accent);
  color: #ffffff;
}

/* Logotype réel posé sur ses lignes de construction, comme dans la charte :
   hauteur d'ascendante, hauteur de capitale, ligne de base. */
.bp__marque {
  position: relative;
  display: block;
}

.bp__logo .bp__signe {
  flex-shrink: 0;
  width: 176px;
  color: var(--accent-doux);
}

.bp__ligne {
  position: absolute;
  left: -600px;
  right: -600px;
  border-top: 1px dashed rgba(247, 237, 230, 0.42);
}

/* Filets relevés au pixel dans le fichier du logotype : sommet du "P",
   hauteur d'x au sommet du "u", ligne de base au pied du "e", puis le
   point le plus bas du tracé. */
.bp__ligne--haut        { top: 10.8%; }
.bp__ligne--capitale    { top: 19%; }
.bp__ligne--base        { top: 77.2%; }
.bp__ligne--descendante { top: 77.5%; }

.bp__poignee {
  position: absolute;
  width: 5px;
  height: 5px;
  background: rgba(247, 237, 230, 0.55);
}

.bp__poignee--hg { top: 19%;   left: 14.3%;  transform: translate(-50%, -50%); }
.bp__poignee--hd { top: 19%;   right: 11.2%; transform: translate(50%, -50%); }
.bp__poignee--bg { top: 77.2%; left: 14.3%;  transform: translate(-50%, -50%); }
.bp__poignee--bd { top: 77.2%; right: 11.2%; transform: translate(50%, -50%); }

.bp__mot {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.bp__nom {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  line-height: 1;
}

.bp__base {
  font-size: 11px;
  letter-spacing: 0.06em;
  opacity: 0.72;
}

/* ----- Tuiles ----- */

.bp__tuile {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 14px 16px;
  border-radius: 14px;
  background: #ffffff;
  border: 1px solid #ece3da;
}

.bp__palette { grid-column: span 3; }
.bp__typo    { grid-column: span 3; }
.bp__carte   { grid-column: span 4; }

.bp__titre {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #b0a294;
  margin-bottom: 10px;
}

/* ----- Palette ----- */

.bp__chips {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.bp__chip b {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.bp__chip i {
  font-size: 9px;
  font-style: normal;
  opacity: 0.72;
}

.bp__chip {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 2px;
  min-height: 38px;
  padding: 7px 9px;
  border-radius: 8px;
  font-size: 9.5px;
  font-weight: 600;
  color: #ffffff;
}

.bp__chip--primaire { background: var(--accent); color: var(--accent-doux); }
.bp__chip--second   { background: var(--accent-doux); color: var(--accent); }
.bp__chip--encre    { background: var(--encre); }
.bp__chip--sable    { background: var(--sable); color: #7a6350; }

/* ----- Typographie ----- */

/* La police de la charte, chargée depuis le projet : Dorlan n'est pas une
   Google Font, et montrer un échantillon composé dans une autre fonte
   n'aurait aucun sens sur une planche d'identité. Jost reste le repli le
   temps du chargement. */
@font-face {
  font-family: "Dorlan";
  src: url("assets/fonts/Dorlan-Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

.bp__aa {
  font-family: "Dorlan", "Jost", "DM Sans", sans-serif;
  font-size: 27px;
  font-weight: 400;
  letter-spacing: 0.02em;
  line-height: 1;
  color: var(--accent);
}

.bp__fontes {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 10px;
  font-family: "Dorlan", "Jost", "DM Sans", sans-serif;
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.01em;
  color: var(--encre);
}

/* ----- Carte de visite ----- */

/* Une tuile comme les autres, titrée, où la maquette du site tient lieu
   d'échantillon. */
.bp__carte {
  overflow: hidden;
  align-self: stretch;
}

.bp__marque-logo .bp__titre {
  align-self: flex-start;
}

/* La maquette occupe la hauteur laissée par la rangée sous le titre de
   tuile, et l'image s'y inscrit entière : pas de recadrage, pas de
   dépassement. */
.bp__hero {
  display: block;
  flex: 1;
  min-height: 0;
  width: 100%;
  border-radius: 6px;
  overflow: hidden;
  /* La barre de navigation de la maquette est blanche, comme la tuile :
     sans ce filet, on ne voit pas où commence la capture. */
  border: 1px solid #ece3da;
}

.bp__hero img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Le cadrage se fait par le bas : la barre de navigation du site doit
     rester entière, le plan de travail peut être rogné. */
  object-position: top center;
}

.bp__carton {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 14px;
  border-radius: 9px;
  background: var(--sable);
}

.bp__carton .bp__signe {
  flex-shrink: 0;
  font-size: 22px;
  color: var(--accent);
}

.bp__carton-txt {
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1.2;
}

.bp__carton-txt b {
  font-size: 11px;
  font-weight: 700;
  color: var(--encre);
}

.bp__carton-txt i {
  font-size: 9px;
  font-style: normal;
  color: #7a6350;
}

/* ----- Logo ----- */

/* Tuile étroite à côté du hero : la marque réduite à son signe. */
.bp__marque-logo {
  grid-column: span 2;
  align-self: stretch;
  align-items: center;
}

.bp__pastille {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

/* La marque réduite à son signe. Retourné verticalement, le monogramme
   présente sa boucle en haut et sa hampe en bas : il se lit comme le P de
   Pure. */
.bp__pastille img {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  transform: scaleY(-1);
}

.bp__post {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 11px;
}

.bp__avatar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: var(--accent);
  color: var(--accent-doux);
}

.bp__avatar {
  padding: 0;
  overflow: hidden;
}

.bp__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.bp__post-txt {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  align-self: center;
  line-height: 1.25;
}

.bp__post-txt b {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--accent);
}

.bp__post-txt i {
  font-size: 10px;
  font-style: normal;
  color: #8a7a6a;
}



/* ---------- Panneau "IA & Automatisation" : l'autonomie -------------------
   Registre volontairement différent des trois autres : un canevas de workflow,
   pas une interface de site. Et surtout de vrais types de nœuds plutôt qu'une
   grille de carrés identiques : c'est l'hétérogénéité qui fait reconnaître un
   n8n. Le déclencheur est une pilule sans entrée, l'agent IA porte son modèle,
   sa mémoire et son outil accrochés sous lui par des liaisons pointillées, le
   branchement a deux sorties à des hauteurs différentes et la fusion deux
   entrées.

   Pas de libellés : à cette échelle un canevas dézoomé n'en montre pas, et
   c'est la structure qu'on lit. L'exécution rejoue en boucle, ce qui est ici
   la vérité du sujet : une automatisation se redéclenche à chaque évènement,
   sans personne.

   La scène a une taille fixe en pixels, partagée avec le viewBox du SVG : les
   courbes tombent ainsi exactement sur les prises. ------------------------ */

.wf {
  position: absolute;
  inset: 26px;
  display: flex;
  flex-direction: column;
  background: #ffffff;
  border-radius: 14px;
  overflow: hidden;
  font-family: "DM Sans", sans-serif;
  box-shadow: 0 30px 60px -28px rgba(16, 29, 61, 0.42);
}

.wf__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 13px 16px;
  border-bottom: 1px solid #eceef6;
}

.wf__nom { font-size: 12.5px; font-weight: 700; color: var(--navy); }

.wf__etat {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10.5px;
  font-weight: 700;
  color: #1a7f4f;
  background: #dff2e7;
  border-radius: 11px;
  padding: 4px 10px;
}

.wf__etat::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #1a7f4f;
}

.wf__canvas {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background-color: #f8f9fd;
  background-image: radial-gradient(#dce0ec 1px, transparent 1px);
  background-size: 17px 17px;
}

.wf__scene {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 660px;
  height: 430px;
  transform: translate(-50%, -50%);
}

/* Le pense-bête : un objet du canevas n8n, pas un nœud. Posé derrière, il
   donne l'échelle et l'impression d'un plan de travail habité. */
.wf__note {
  position: absolute;
  left: 96px;
  top: 8px;
  width: 158px;
  height: 74px;
  padding: 13px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  background: #fdf6d8;
  border: 1px solid #f0e4a9;
  border-radius: 8px;
}

.wf__note i {
  height: 4px;
  border-radius: 2px;
  background: #e6d798;
}

.wf__note i:nth-child(2) { width: 78%; }
.wf__note i:nth-child(3) { width: 52%; }

.wf__liens {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.wf__l {
  fill: none;
  stroke: #d3d8e6;
  stroke-width: 1.8;
}

/* Les liaisons vers le modèle, la mémoire et l'outil sont pointillées : dans
   n8n ce ne sont pas des passages de données mais des rattachements. */
.wf__l--sous {
  stroke-dasharray: 4 4;
  stroke-width: 1.5;
}

/* pathLength ramène chaque courbe à une longueur de 100 : les onze liaisons,
   de longueurs très différentes, partagent alors la même vitesse apparente. */
.wf__f {
  fill: none;
  stroke: var(--blue);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-dasharray: 14 100;
  stroke-dashoffset: 114;
  opacity: 0;
}

.wf__f--e1 { animation: wf-e1 9s linear infinite; }
.wf__f--e2 { animation: wf-e2 9s linear infinite; }
.wf__f--e3 { animation: wf-e3 9s linear infinite; }
.wf__f--e4 { animation: wf-e4 9s linear infinite; }
.wf__f--e5 { animation: wf-e5 9s linear infinite; }
.wf__f--e6 { animation: wf-e6 9s linear infinite; }
.wf__f--a { animation: wf-a 9s linear infinite; }
.wf__f--b { animation: wf-b 9s linear infinite; }
.wf__f--c { animation: wf-c 9s linear infinite; }

@keyframes wf-e1 {
  0%, 9%   { stroke-dashoffset: 114; opacity: 0; }
  11%     { opacity: 1; }
  16%       { stroke-dashoffset: 0; opacity: 1; }
  19%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes wf-e2 {
  0%, 22%   { stroke-dashoffset: 114; opacity: 0; }
  24%     { opacity: 1; }
  28%       { stroke-dashoffset: 0; opacity: 1; }
  31%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes wf-e3 {
  0%, 45%   { stroke-dashoffset: 114; opacity: 0; }
  47%     { opacity: 1; }
  52%       { stroke-dashoffset: 0; opacity: 1; }
  55%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes wf-e4 {
  0%, 58%   { stroke-dashoffset: 114; opacity: 0; }
  60%     { opacity: 1; }
  64%       { stroke-dashoffset: 0; opacity: 1; }
  67%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes wf-e5 {
  0%, 70%   { stroke-dashoffset: 114; opacity: 0; }
  72%     { opacity: 1; }
  76%       { stroke-dashoffset: 0; opacity: 1; }
  79%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes wf-e6 {
  0%, 82%   { stroke-dashoffset: 114; opacity: 0; }
  84%     { opacity: 1; }
  88%       { stroke-dashoffset: 0; opacity: 1; }
  91%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes wf-a {
  0%, 32%   { stroke-dashoffset: 114; opacity: 0; }
  34%     { opacity: 1; }
  37%       { stroke-dashoffset: 0; opacity: 1; }
  40%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes wf-b {
  0%, 35%   { stroke-dashoffset: 114; opacity: 0; }
  37%     { opacity: 1; }
  40%       { stroke-dashoffset: 0; opacity: 1; }
  43%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes wf-c {
  0%, 38%   { stroke-dashoffset: 114; opacity: 0; }
  40%     { opacity: 1; }
  43%       { stroke-dashoffset: 0; opacity: 1; }
  46%, 100% { stroke-dashoffset: 0; opacity: 0; }
}

/* ----- Les nœuds ----- */

.wf__n {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  border: 1.5px solid #e0e4f0;
  border-radius: 11px;
  color: #aab1c6;
  box-shadow: 0 5px 14px -9px rgba(16, 29, 61, 0.35);
}

.wf__ico { width: 20px; height: 20px; display: block; }

/* Le déclencheur : bord gauche en demi-cercle et aucune entrée, exactement
   comme n8n le dessine. */
.wf__n--trigger {
  width: 46px;
  height: 46px;
  border-radius: 23px 11px 11px 23px;
}

/* L'agent : plus large, c'est la pièce maîtresse du graphe. */
.wf__n--agent {
  width: 104px;
  height: 56px;
  border-radius: 13px;
}

.wf__n--agent .wf__ico { width: 26px; height: 26px; }

/* Modèle, mémoire, outil : plus petits, ce sont des dépendances de l'agent
   et non des étapes du flux. */
.wf__n--sub {
  width: 36px;
  height: 36px;
  border-radius: 10px;
}

.wf__n--sub .wf__ico { width: 16px; height: 16px; }

.wf__p {
  position: absolute;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #ffffff;
  border: 1.5px solid #ccd2e2;
}

.wf__p--in    { left: -4px;  top: 50%; margin-top: -3.5px; }
.wf__p--out   { right: -4px; top: 50%; margin-top: -3.5px; }
.wf__p--in2a  { left: -4px;  top: 25%; margin-top: -3.5px; }
.wf__p--in2b  { left: -4px;  top: 75%; margin-top: -3.5px; }
.wf__p--out2a { right: -4px; top: 25%; margin-top: -3.5px; }
.wf__p--out2b { right: -4px; top: 75%; margin-top: -3.5px; }

/* Les trois prises sous l'agent : carrées, comme n8n distingue ses
   connexions IA de ses connexions de données. */
.wf__p--bas {
  left: var(--bx);
  bottom: -4px;
  margin-left: -3.5px;
  border-radius: 2px;
}

.wf__n--s1 { animation: wf-s1 9s linear infinite; }
.wf__n--s2 { animation: wf-s2 9s linear infinite; }
.wf__n--s3 { animation: wf-s3 9s linear infinite; }
.wf__n--s4 { animation: wf-s4 9s linear infinite; }
.wf__n--s5 { animation: wf-s5 9s linear infinite; }
.wf__n--s6 { animation: wf-s6 9s linear infinite; }
.wf__n--s7 { animation: wf-s7 9s linear infinite; }
.wf__n--sa { animation: wf-sa 9s linear infinite; }
.wf__n--sb { animation: wf-sb 9s linear infinite; }
.wf__n--sc { animation: wf-sc 9s linear infinite; }

@keyframes wf-s1 {
  0%, 4%  { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
  7%    { transform: scale(1.16); border-color: var(--blue); background: #f2f0ff; color: var(--blue); }
  8%, 92% { transform: scale(1);    border-color: #c9c3ff; background: #f7f6ff; color: var(--blue); }
  97%, 100% { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
}
@keyframes wf-s2 {
  0%, 17%  { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
  20%    { transform: scale(1.16); border-color: var(--blue); background: #f2f0ff; color: var(--blue); }
  21%, 92% { transform: scale(1);    border-color: #c9c3ff; background: #f7f6ff; color: var(--blue); }
  97%, 100% { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
}
@keyframes wf-s3 {
  0%, 29%  { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
  32%    { transform: scale(1.16); border-color: var(--blue); background: #f2f0ff; color: var(--blue); }
  33%, 92% { transform: scale(1);    border-color: #c9c3ff; background: #f7f6ff; color: var(--blue); }
  97%, 100% { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
}
@keyframes wf-s4 {
  0%, 53%  { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
  56%    { transform: scale(1.16); border-color: var(--blue); background: #f2f0ff; color: var(--blue); }
  57%, 92% { transform: scale(1);    border-color: #c9c3ff; background: #f7f6ff; color: var(--blue); }
  97%, 100% { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
}
@keyframes wf-s5 {
  0%, 65%  { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
  68%    { transform: scale(1.16); border-color: var(--blue); background: #f2f0ff; color: var(--blue); }
  69%, 92% { transform: scale(1);    border-color: #c9c3ff; background: #f7f6ff; color: var(--blue); }
  97%, 100% { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
}
@keyframes wf-s6 {
  0%, 77%  { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
  80%    { transform: scale(1.16); border-color: var(--blue); background: #f2f0ff; color: var(--blue); }
  81%, 92% { transform: scale(1);    border-color: #c9c3ff; background: #f7f6ff; color: var(--blue); }
  97%, 100% { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
}
@keyframes wf-s7 {
  0%, 89%  { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
  92%    { transform: scale(1.16); border-color: var(--blue); background: #f2f0ff; color: var(--blue); }
  93%, 92% { transform: scale(1);    border-color: #c9c3ff; background: #f7f6ff; color: var(--blue); }
  97%, 100% { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
}
@keyframes wf-sa {
  0%, 34%  { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
  37%    { transform: scale(1.16); border-color: var(--blue); background: #f2f0ff; color: var(--blue); }
  38%, 92% { transform: scale(1);    border-color: #c9c3ff; background: #f7f6ff; color: var(--blue); }
  97%, 100% { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
}
@keyframes wf-sb {
  0%, 37%  { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
  40%    { transform: scale(1.16); border-color: var(--blue); background: #f2f0ff; color: var(--blue); }
  41%, 92% { transform: scale(1);    border-color: #c9c3ff; background: #f7f6ff; color: var(--blue); }
  97%, 100% { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
}
@keyframes wf-sc {
  0%, 40%  { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
  43%    { transform: scale(1.16); border-color: var(--blue); background: #f2f0ff; color: var(--blue); }
  44%, 92% { transform: scale(1);    border-color: #c9c3ff; background: #f7f6ff; color: var(--blue); }
  97%, 100% { transform: scale(1);    border-color: #e0e4f0; background: #fff; color: #aab1c6; }
}

.wf__zoom {
  position: absolute;
  right: 12px;
  bottom: 12px;
  display: flex;
  gap: 5px;
}

.wf__zoom span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: #ffffff;
  border: 1px solid #e4e7f2;
  font-size: 13px;
  line-height: 1;
  color: #8890ab;
}

/* La scène est en pixels fixes : on la réduit plutôt que de la laisser
   déborder quand la colonne se resserre. */
@media (max-width: 1600px) {
  .wf__scene { transform: translate(-50%, -50%) scale(0.84); }
}

@media (max-width: 1200px) {
  .wf__scene { transform: translate(-50%, -50%) scale(0.7); }
}

@media (prefers-reduced-motion: reduce) {
  .wf__n,
  .wf__f { animation: none; }
}

.features__list {
  display: flex;
  flex-direction: column;
  height: 640px;
}

.feature-row {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 20px 0;
  border-top: 1px solid #e7e9f0;
  transition: padding 0.6s cubic-bezier(0.16, 1, 0.3, 1);
  width: 100%;
}

/* Le service affiché à gauche ne change que de taille : aucune couleur ne
   bouge d'une ligne à l'autre, le grossissement suffit à la désigner. */
.feature-row.is-active {
  padding: 24px 0;
}

.feature-row.is-active .feature-row__title {
  font-size: 23.5px;
}

.feature-row.is-active .feature-row__text {
  font-size: 17.5px;
}

.feature-row:last-of-type {
  border-bottom: 1px solid #e7e9f0;
}

.feature-row__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.feature-row__title {
  font-size: 22px;
  font-weight: 700;
  color: var(--navy);
  transition: font-size 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}



.feature-row__num {
  font-family: "DM Sans", sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: #b0b5c6;
  flex-shrink: 0;
}
.feature-row__text {
  font-family: "DM Sans", sans-serif;
  font-size: 17px;
  line-height: 1.6;
  color: #6b7593;
  margin-top: 8px;
  transition: font-size 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- Méthode ---------- */

.process {
  padding: 120px 0 40px;
}

.process .container {
  max-width: 1600px;
  width: 100%;
}

.process__timeline {
  position: relative;
  margin-top: 60px;
}

.process__progress {
  position: absolute;
  left: 50%;
  top: 0;
  width: 8px;
  height: 320px;
  transform: translateX(-50%);
  background: linear-gradient(180deg,
    rgba(61, 91, 234, 0) 0%,
    rgba(61, 91, 234, 0) 8%,
    var(--blue) 42%,
    var(--blue) 58%,
    rgba(61, 91, 234, 0) 92%,
    rgba(61, 91, 234, 0) 100%);
  will-change: top;
}

.process-step {
  position: relative;
  width: calc(50% - 240px);
  min-height: 38vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0;
}

.process-step--right {
  margin-left: calc(50% + 240px);
}

.process-step--left {
  margin-right: calc(50% + 240px);
  text-align: right;
}
.process-step--left .process-step__text {
  margin-left: auto;
}

.process-step__dot {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 0 5px #eef1fc;
}

.process-step--right .process-step__dot {
  left: -240px;
}

.process-step--left .process-step__dot {
  right: -240px;
}

.process-step__icon {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 84px;
  height: 84px;
  flex-shrink: 0;
  border-radius: 22px;
  background: linear-gradient(160deg, #ffffff 0%, #eef1fc 100%);
  box-shadow: 0 16px 30px -14px rgba(16, 29, 61, 0.22), inset 0 1px 0 rgba(255, 255, 255, 0.6);
  color: var(--blue);
}

.process-step--right .process-step__icon {
  left: -150px;
}

.process-step--left .process-step__icon {
  right: -150px;
}

.process-step__icon svg {
  width: 34px;
  height: 34px;
}

.process-step__body {
  min-width: 0;
}

.process-step__num {
  color: var(--blue);
  font-weight: 800;
  margin-right: 4px;
}

.process-step__title {
  font-size: 26px;
  font-weight: 400;
  color: var(--navy);
  margin-bottom: 8px;
}
.process-step__text {
  font-family: "DM Sans", sans-serif;
  font-size: 16px;
  line-height: 1.6;
  color: #6b7593;
  max-width: 380px;
}

/* ---------- FAQ ---------- */

.faq {
  padding: 110px 0 90px;
}

/* Liste centrée sous l'en-tête de section, comme le reste de la page. */
.faq__list {
  max-width: 880px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

/* Des filets plutôt que sept cartes : la liste respire et le regard suit une
   seule colonne. */
.faq__item {
  border-bottom: 1px solid #e7e9f0;
}

.faq__item:first-child {
  border-top: 1px solid #e7e9f0;
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  font-size: 17.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--navy);
  padding: 26px 4px;
  transition: color 0.25s ease;
  /* Sans ces deux lignes, le triangle natif du <summary> reste affiché
     (list-style pour Firefox, le pseudo pour Safari/Chrome). */
  list-style: none;
}

.faq__q::-webkit-details-marker {
  display: none;
}

.faq__q:hover,
.faq__item[open] .faq__q {
  color: var(--blue);
}

.faq__q:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 4px;
  border-radius: 6px;
}

/* Un + tracé en deux dégradés dans une pastille : la barre verticale se
   rétracte à l'ouverture, ce qui le transforme en −. */
.faq__signe {
  position: relative;
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid #e7e9f0;
  background: #ffffff;
  transition: background-color 0.25s ease, border-color 0.25s ease;
}

.faq__signe::before,
.faq__signe::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--blue);
  transform: translate(-50%, -50%);
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1),
              background-color 0.25s ease;
}

.faq__signe::before {
  width: 12px;
  height: 1.6px;
}

.faq__signe::after {
  width: 1.6px;
  height: 12px;
}

.faq__item[open] .faq__signe {
  background: var(--blue);
  border-color: var(--blue);
}

.faq__item[open] .faq__signe::before,
.faq__item[open] .faq__signe::after {
  background: #ffffff;
}

.faq__item[open] .faq__signe::after {
  transform: translate(-50%, -50%) scaleY(0);
}

.faq__q:hover .faq__signe {
  border-color: #c9cdf0;
}

/* <details> n'anime pas son ouverture : le panneau est une piste de grille
   qui passe de 0fr à 1fr, ce qui anime la hauteur réelle sans la connaître.
   Sans JS la piste vaut 1fr d'emblée, donc l'accordéon natif reste bon. */
.faq__panneau {
  display: grid;
  grid-template-rows: 1fr;
}

/* La piste de grille se comprime jusqu'à 0, mais le rembourrage d'un
   enfant, lui, ne se comprime pas : c'est ce reliquat qui sautait d'un coup
   en fin de repli. La zone intermédiaire absorbe la compression, la réponse
   garde son rembourrage à l'intérieur. */
.faq__zone {
  min-height: 0;
  overflow: hidden;
}

.faq__list--js .faq__panneau {
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.faq__list--js .faq__item.is-ouvert .faq__panneau {
  grid-template-rows: 1fr;
}

.faq__a {
  font-family: "DM Sans", sans-serif;
  font-size: 15.5px;
  line-height: 1.7;
  color: #6b7593;
  max-width: 62ch;
  padding: 0 4px 28px;
  opacity: 0;
  transition: opacity 0.35s ease;
}

.faq__item[open] .faq__a,
.faq__item.is-ouvert .faq__a {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .faq__list--js .faq__panneau,
  .faq__a,
  .faq__q {
    transition: none;
  }
}

/* ---------- CTA final ---------- */

/* ---------- Contact ----------
   Posé à même la page : un filet en haut, un grand titre, et des champs
   réduits à leur trait de soulignement. */

.contact {
  padding: 40px 0 140px;
}

.contact__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 96px;
  padding-top: 64px;
  border-top: 1px solid #e3e6ef;
}

.contact__title {
  font-size: 64px;
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--navy);
}

.contact__text {
  max-width: 420px;
  margin-top: 24px;
  font-family: "DM Sans", sans-serif;
  font-size: 18px;
  line-height: 1.6;
  color: #6b7593;
}

.contact__mail {
  display: inline-block;
  margin-top: 48px;
  padding-bottom: 4px;
  font-size: 22px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--navy);
  border-bottom: 1.5px solid var(--navy);
  transition: color 0.2s ease, border-color 0.2s ease;
}

.contact__mail:hover {
  color: var(--blue);
  border-color: var(--blue);
}

/* ----- Formulaire ----- */

.contact-form {
  display: flex;
  flex-direction: column;
  gap: 36px;
  font-family: "DM Sans", sans-serif;
}

.contact-form__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
}

.contact-form__field {
  display: flex;
  flex-direction: column;
}

.contact-form__field label {
  font-size: 14px;
  font-weight: 500;
  color: #6b7593;
  transition: color 0.2s ease;
}

.contact-form__field:focus-within label {
  color: var(--navy);
}

.contact-form__field input,
.contact-form__field textarea {
  width: 100%;
  padding: 10px 0 12px;
  font-family: inherit;
  font-size: 18px;
  color: var(--navy);
  background: transparent;
  border: 0;
  border-bottom: 1.5px solid #d7dae4;
  border-radius: 0;
  transition: border-color 0.2s ease;
}

.contact-form__field textarea {
  min-height: 112px;
  line-height: 1.5;
  resize: none;
}

.contact-form__field input:hover,
.contact-form__field textarea:hover {
  border-color: #b0b5c6;
}

.contact-form__field input:focus,
.contact-form__field textarea:focus {
  outline: none;
  border-color: var(--navy);
}

.contact-form__foot {
  display: flex;
  align-items: center;
  gap: 20px;
}

.contact-form__submit {
  justify-content: center;
  height: 56px;
  padding: 0 44px;
}

.contact-form .btn:disabled {
  opacity: 0.65;
  cursor: progress;
}

/* Piège à robots : hors flux et hors lecteurs d'écran, jamais atteignable
   au clavier, donc seul un script de spam le coche. */
.contact-form__botcheck {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.contact-form__status {
  font-size: 14.5px;
  font-weight: 500;
}

.contact-form__status:empty {
  display: none;
}

.contact-form__status--ok { color: #1f9d5b; }
.contact-form__status--erreur { color: #d4483b; }

@media (max-width: 1000px) {
  .contact__grid {
    grid-template-columns: 1fr;
    gap: 56px;
  }

  .contact__title {
    font-size: 52px;
  }
}

@media (max-width: 768px) {
  .contact {
    padding: 8px 0 72px;
  }

  .contact__grid {
    gap: 44px;
    padding-top: 44px;
  }

  .contact__title {
    font-size: 40px;
  }

  .contact__text {
    font-size: 16px;
    margin-top: 18px;
  }

  .contact__mail {
    margin-top: 28px;
    font-size: 18px;
  }

  .contact-form {
    gap: 30px;
  }

  .contact-form__row {
    grid-template-columns: 1fr;
    gap: 30px;
  }

  /* 16 px minimum : en dessous, iOS zoome sur le champ au premier toucher. */
  .contact-form__field input,
  .contact-form__field textarea {
    font-size: 16px;
  }

  .contact-form__foot {
    flex-direction: column;
    align-items: stretch;
  }

  .contact-form__submit {
    height: 54px;
  }
}

/* ---------- Footer ---------- */
.footer {
  padding: 64px 0 28px;
  background: #080f22;
  color: #ffffff;
}

.footer__top {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1.1fr;
  gap: 40px;
  padding-bottom: 48px;
}

.footer__brand {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 320px;
}

.footer__kicker {
  font-size: 16px;
  font-weight: 700;
  color: #ffffff;
}

.footer__pitch {
  font-size: 14px;
  line-height: 1.65;
  color: #9aa6c4;
  margin-top: 12px;
}

.footer__socials {
  display: flex;
  gap: 16px;
  margin-top: 20px;
}

.footer__social {
  color: #9aa6c4;
  transition: color 0.2s ease;
}

.footer__social svg {
  width: 18px;
  height: 18px;
}

.footer__social:hover {
  color: #ffffff;
}

.footer__col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.footer__col-title {
  font-size: 14px;
  font-weight: 700;
  color: #ffffff;
  margin-bottom: 14px;
}

.footer__link {
  font-size: 14px;
  color: #9aa6c4;
  padding: 6px 0;
  transition: color 0.2s ease;
}

.footer__link:hover {
  color: #ffffff;
}

.footer__link--static {
  color: #6f7ca0;
}

.footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-top: 24px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.footer__copy,
.footer__legal-link {
  font-size: 13px;
  color: #6f7ca0;
}

.footer__legal {
  display: flex;
  gap: 24px;
}

.footer__legal-link {
  transition: color 0.2s ease;
}

.footer__legal-link:hover {
  color: #ffffff;
}


/* ---------- Responsive ---------- */

@media (max-width: 1080px) {
  .hero__title {
    font-size: 56px;
  }

}

@media (max-width: 900px) {
  .sim__grid {
    grid-template-columns: 1fr;
  }

  .sim__results {
    padding-left: 0;
    border-left: 0;
  }

  .sim__panel--chart {
    grid-column: span 2;
  }

  .hero__inner {
    padding: 118px 24px 60px;
  }

  .header__inner {
    padding: 0 24px;
  }

  .container {
    padding: 0 24px;
  }

  .nav__burger {
    display: flex;
  }

  /* Le panneau se déploie sous la barre, sur toute la largeur. Fermé, il
     est replié à zéro et retiré du parcours clavier. */
  .nav__links {
    position: absolute;
    top: calc(100% + 10px);
    /* Aligné sur les gouttières de la page, comme le reste du contenu. */
    left: 24px;
    right: 24px;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-right: 0;
    padding: 0 6px;
    border-radius: 18px;
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    box-shadow: 0 24px 48px -28px rgba(16, 29, 61, 0.55);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: opacity 0.25s ease, transform 0.3s cubic-bezier(0.16, 1, 0.3, 1),
                visibility 0s linear 0.3s;
  }

  .nav__links.is-ouvert {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity 0.25s ease, transform 0.3s cubic-bezier(0.16, 1, 0.3, 1),
                visibility 0s;
  }

  .nav__link {
    padding: 16px 14px;
    font-size: 16px;
    border-bottom: 1px solid #eef0f6;
  }

  .nav__link:last-child {
    border-bottom: 0;
  }

  .nav__link::after {
    display: none;
  }

  .header__inner {
    position: relative;
  }

  .hero__content {
    margin-top: 80px;
  }
}

@media (max-width: 768px) {
  .header {
    padding: 16px 0;
  }

  .header--scrolled {
    padding: 10px 0;
  }

  /* La pilule se détache des bords de l'écran : collée aux deux côtés, elle
     se lisait comme un bandeau, pas comme une barre flottante. */
  .header--scrolled .header__inner {
    margin: 0 12px;
    padding: 6px 6px 6px 18px;
  }

  .nav {
    gap: 8px;
  }

  /* Bouton rond, à la hauteur du CTA : le carré bordé jurait avec les deux
     pilules qui l'entourent. */
  .nav__burger {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 0;
    background: #ffffff;
    box-shadow: 0 0 0 1px #e3e6ef;
  }

  .nav__burger {
    transition: width 0.3s cubic-bezier(0.16, 1, 0.3, 1),
                height 0.3s cubic-bezier(0.16, 1, 0.3, 1),
                background-color 0.3s ease;
  }

  .header--scrolled .nav__burger {
    width: 36px;
    height: 36px;
    background: #f2f3f8;
    box-shadow: none;
  }

  /* Écart entre les traits (6 px + 1,8 px d'épaisseur) : ils se croisent
     exactement au centre. */
  .nav__burger[aria-expanded="true"] .nav__burger-trait:first-child {
    transform: translateY(3.9px) rotate(45deg);
  }

  .nav__burger[aria-expanded="true"] .nav__burger-trait:last-child {
    transform: translateY(-3.9px) rotate(-45deg);
  }

  .brand__logo {
    height: 44px;
  }

  /* Dans la pilule, le logo reste entier : réduit au seul monogramme, la
     marque disparaissait de l'écran dès le premier scroll. */
  .header--scrolled .brand {
    max-width: 170px;
  }

  .header--scrolled .brand__logo {
    height: 32px;
  }

  .nav__cta {
    height: 42px;
    font-size: 14px;
    padding: 0 20px;
  }

  /* Au scroll, CTA et bouton menu rapetissent avec le logo. */
  .header--scrolled .nav__cta {
    height: 36px;
    font-size: 13px;
    padding: 0 16px;
  }

  .nav__links {
    top: calc(100% + 12px);
    padding: 8px;
    border-radius: 22px;
    background: #ffffff;
  }

  /* Menu ouvert : un voile assombrit la page pour que les liens ne se lisent
     plus par-dessus le hero. Il vit sous la barre (z-index -1 dans le
     contexte du header), qui reste donc nette, pilule comprise. Un clic
     dessus referme le menu : le script écoute les clics hors de la nav. */
  .header::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background: rgba(16, 29, 61, 0.3);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
  }

  .header:has(.nav__links.is-ouvert)::before {
    opacity: 1;
    pointer-events: auto;
  }

  /* Dans la pilule, le panneau en reprend exactement la largeur. */
  .header--scrolled .nav__links {
    left: 0;
    right: 0;
  }

  .nav__link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 17px 16px;
    font-size: 18px;
    font-weight: 600;
    color: var(--navy);
    border-bottom: 0;
    border-radius: 14px;
  }

  .nav__link + .nav__link {
    box-shadow: inset 0 1px 0 #eef0f6;
  }

  .nav__link:active {
    background: #f4f5fa;
  }

  .nav__link::after {
    display: block;
    position: static;
    width: 8px;
    height: 8px;
    border-top: 2px solid #b0b5c6;
    border-right: 2px solid #b0b5c6;
    background: none;
    transform: translateY(-1px) rotate(45deg);
    margin-right: 4px;
  }

  .hero__content {
    margin-top: 8px;
    padding-bottom: 0;
  }

  .hero__title {
    font-size: 38px;
    letter-spacing: -0.02em;
  }

  /* Grille 2 × 2 centrée : calée à gauche, elle rompait l'axe du titre. */
  .hero__services {
    display: grid;
    grid-template-columns: repeat(2, auto);
    justify-content: center;
    gap: 18px 32px;
    margin-top: 28px;
  }

  /* Pleine largeur : les logos défilent d'un bord à l'autre de l'écran. */
  .marquee {
    width: auto;
    margin: 36px -24px 0;
  }

  /* Les logos clients étaient dimensionnés pour une bande large : sur un
     écran étroit, deux d'entre eux remplissaient l'écran. */
  .marquee__item {
    width: 150px;
    height: 88px;
    gap: 9px;
  }

  .marquee__item img {
    max-width: 122px;
  }

  .marquee__item--stacked img {
    height: 54px;
  }

  .marquee__item--te4mup img {
    height: 74px;
  }

  .marquee__item--nvm img {
    height: 46px;
  }

  .marquee__name {
    font-size: 10px;
  }

  /* Sur écran étroit le filigrane ne se lit plus comme un logo, seulement
     comme un pavé gris derrière les logos clients. */
  .hero__watermark {
    display: none;
  }

  .hero__service-icon {
    width: 32px;
    height: 32px;
  }

  .hero__service span {
    font-size: 11.5px;
  }

  .hero__actions {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    margin-top: 32px;
  }

  .btn {
    justify-content: center;
    font-size: 15px;
    padding: 14px 24px;
  }

  .hero__card {
    margin-top: 56px;
    margin-left: 0;
    margin-right: 0;
    border-radius: 20px 20px 0 0;
  }

  /* ----- Le dashboard en format téléphone ----- */

  /* Le châssis : encadrement sombre, coins très arrondis, largeur d'un
     appareil. Il continue de déborder sous le pli, comme en grand écran. */
  /* L'appareil est fermé en bas : coupé net, il avait l'air tronqué plutôt
     que posé dans la page. */
  .hero__card {
    width: min(100%, 360px);
    margin: 28px auto 0;
    padding: 9px;
    background: #101d3d;
    border: 0;
    border-radius: 46px;
    box-shadow: 0 30px 60px -28px rgba(16, 29, 61, 0.45);
  }

  /* L'écran se partage en hauteur : barre d'état, puis la scène qui prend
     tout le reste. Sans ça, le corps recevait 100 % de l'écran *sous* la
     barre d'état et débordait d'autant. */
  .sim {
    position: relative;
    display: flex;
    flex-direction: column;
    border-radius: 38px;
    overflow: hidden;
    /* Le gris que portait la fenêtre de bureau passe ici : sans lui, les
       cartes blanches de la timeline se fondraient dans l'écran. */
    background: #f5f5f5;
  }

  /* La barre d'accueil, en bas de l'écran comme sur l'appareil. */
  .sim::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 8px;
    width: 116px;
    height: 5px;
    border-radius: 100px;
    background: rgba(16, 29, 61, 0.55);
    transform: translateX(-50%);
    z-index: 4;
  }

  /* Les pastilles et l'URL cèdent la place à l'heure, l'îlot et les
     indicateurs : le chrome d'un navigateur de bureau n'a rien à faire
     sur un écran de téléphone. */
  .sim__dots,
  .sim__bar-title {
    display: none;
  }

  .sim__bar {
    justify-content: space-between;
    gap: 0;
    padding: 0;
    border-bottom: 0;
    background: transparent;
  }

  .sim__statut {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 11px 26px 6px;
    font-family: "Inter", "DM Sans", sans-serif;
    color: var(--navy);
  }

  .sim__statut-heure {
    flex: 1;
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: -0.01em;
  }

  /* L'îlot : une pastille noire, pas une encoche découpée — le châssis est
     dessiné à plat, inutile de simuler une découpe d'écran. */
  .sim__ile {
    flex-shrink: 0;
    width: 78px;
    height: 24px;
    border-radius: 100px;
    background: #101d3d;
  }

  .sim__statut-icones {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 5px;
  }

  .sim__ico-reseau {
    width: 16px;
    height: 11px;
  }

  .sim__ico-wifi {
    width: 15px;
    height: 11px;
  }

  .sim__batterie {
    position: relative;
    width: 23px;
    height: 11.5px;
    border: 1px solid rgba(16, 29, 61, 0.4);
    border-radius: 3.5px;
    padding: 1.5px;
  }

  /* Le téton du symbole de batterie. */
  .sim__batterie::after {
    content: "";
    position: absolute;
    top: 50%;
    right: -3px;
    width: 1.5px;
    height: 4px;
    border-radius: 0 2px 2px 0;
    background: rgba(16, 29, 61, 0.4);
    transform: translateY(-50%);
  }

  .sim__batterie i {
    display: block;
    width: 72%;
    height: 100%;
    border-radius: 1.5px;
    background: var(--navy);
  }

  .sim__body {
    padding: 24px 18px 26px;
  }

  .sim__head {
    flex-wrap: wrap;
  }

  .sim__event {
    gap: 12px;
    padding: 12px 14px;
  }

  /* La colonne de dates fixe étranglait le titre : sur un écran étroit, la
     date passe au-dessus et le texte prend la largeur. */
  .sim__event-body {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }

  .sim__event-date {
    flex: none;
    font-size: 11px;
  }

  .sim__event-title {
    font-size: 14.5px;
    line-height: 1.35;
  }

  /* ----- Écran du téléphone : les données, et le planning en notifications ----- */

  /* Format d'un iPhone. L'écran ne défile pas : ce qu'il montre doit donc
     tenir dedans, d'où les données seules et le planning renvoyé en
     notifications par-dessus. */
  .sim {
    position: relative;
    aspect-ratio: 9 / 18.5;
  }

  .sim__bar {
    flex: none;
  }

  .sim__stage {
    flex: 1;
    min-height: 0;
  }

  .sim__body {
    height: 100%;
  }

  .sim__body {
    display: flex;
    flex-direction: column;
    /* Le bas laisse la place à la barre d'accueil. */
    padding: 24px 14px 26px;
  }

  .sim__title {
    font-size: 19px;
    margin-bottom: 0;
  }

  .sim__scrub {
    margin-top: 10px;
  }

  .sim__grid {
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 1;
    min-height: 0;
    margin-top: 12px;
  }

  /* Les données prennent tout l'écran, en deux colonnes comme un tableau de
     bord d'application. */
  .sim__results {
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* Les trois rangées se partagent la hauteur de l'écran : sans ça, les
       cartes gardaient leur hauteur naturelle et laissaient un creux de
       100 px au-dessus de la barre d'accueil. */
    grid-auto-rows: minmax(0, 1fr);
    gap: 8px;
    flex: 1;
    min-height: 0;
    /* Ce qui ne tient pas dans l'écran est coupé net, comme sur un vrai
       appareil : rien ne fait grandir le châssis. */
    overflow: hidden;
  }

  .sim__result {
    display: flex;
    flex-direction: column;
    padding: 8px 10px 9px;
    border-radius: 16px;
    /* Sans cette permission de se comprimer, la hauteur du contenu passait
       devant le partage en trois rangées et la dernière carte débordait
       sous la barre d'accueil. */
    min-height: 0;
    overflow: hidden;
  }

  /* Une seule échelle pour toutes les cartes : titre, valeur, pied. Les
     panneaux larges utilisaient un titre plus gros que les statistiques,
     ce qui déséquilibrait la grille une fois les cartes réduites. */
  .sim__stat-title,
  .sim__panel .sim__stat-title {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: #6b7593;
  }

  .sim__stat--dark .sim__stat-title {
    color: rgba(255, 255, 255, 0.78);
  }

  /* Le chiffre occupe le centre de la carte : poussé en bas, il laissait un
     grand vide sous le titre. */
  .sim__stat-value {
    font-size: 40px;
    margin: auto 0;
  }

  .sim__stat-value em {
    font-size: 17px;
  }

  .sim__approx {
    width: 20px;
  }

  /* Le pied tient sur une ligne. La pastille, qui lui volait 20 px, passe à
     la trappe : à cette largeur c'est le texte qui compte. */
  .sim__stat-foot {
    margin-top: 8px;
    font-size: 10px;
    white-space: nowrap;
  }

  .sim__stat-chip {
    display: none;
  }

  /* Seul le graphe prend la pleine largeur : à moitié d'écran il ne se lit
     plus, alors que les barres de positions s'accommodent d'une colonne. */
  .sim__panel--chart {
    grid-column: 1 / -1;
  }

  /* C'est la figure qu'on réduit, pas le SVG : réduire le second laissait
     le label centré sur l'ancienne largeur, d'où le « 64 % » décalé. */
  .sim__half-figure {
    width: 138px;
    /* transform ne touche pas au flux : la légende reste en place. */
    transform: translateX(-10px);
  }

  .sim__half-center {
    bottom: 5px;
  }

  .sim__half-center b {
    font-size: 18px;
  }

  .sim__half-center small {
    margin-top: 3px;
    font-size: 9.5px;
  }

  /* Jauge et légende forment un seul bloc centré : écartées, la légende se
     lisait comme un élément séparé. */
  .sim__half {
    justify-content: center;
    gap: 36px;
    margin-top: 0;
  }

  .sim__legend {
    gap: 6px;
    font-size: 12px;
  }

  .sim__legend-dot {
    width: 7px;
    height: 7px;
  }

  /* Les barres de positions étaient presque invisibles une fois la carte
     réduite de moitié, et tassées en bas d'un grand vide. */
  /* Les lignes sont posées en absolu depuis le bas : c'est la hauteur du
     cadre qui les place. On la fixe et on centre le cadre dans la carte,
     plutôt que de l'étirer, sinon la pile reste collée en bas. */
  .sim__serp {
    flex: none;
    /* 62 px : la hauteur qu'il faut pour que les trois emplacements visibles
       le soient entièrement. Plus court, la dernière ligne était tranchée. */
    height: 62px;
    min-height: 0;
    margin: auto 0;
  }

  .sim__serp-row b { height: 7px; }
  .sim__serp-row em { height: 5px; }

  /* Le récapitulatif et son bouton sortent de l'écran : le hero a déjà ses
     propres boutons juste au-dessus, et l'appareil doit garder ses
     proportions. */
  .sim__cta {
    display: none;
  }

  /* ----- Le planning en notifications ----- */

  /* Les bannières se posent par-dessus l'écran, sous la barre d'état, comme
     une vraie notification : elles recouvrent le titre le temps de se lire,
     et celui-ci réapparaît entre deux. Rien n'est réservé dans le flux, donc
     les données gardent toute la hauteur de l'appareil. */
  .sim__feed {
    position: absolute;
    top: 46px;
    left: 11px;
    right: 11px;
    height: 0;
    z-index: 5;
    margin: 0;
    padding: 0;
    pointer-events: none;
  }

  /* Bannière iOS : matériau translucide très flouté, coins largement
     arrondis, icône d'application à gauche, en-tête nom + horodatage, puis
     le message sur deux lignes au plus. */
  .sim__event {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    align-items: flex-start;
    gap: 10px;
    padding: 11px 13px 12px;
    border-radius: 26px;
    background: rgba(255, 255, 255, 0.74);
    backdrop-filter: saturate(180%) blur(30px);
    -webkit-backdrop-filter: saturate(180%) blur(30px);
    border: 0.5px solid rgba(255, 255, 255, 0.6);
    box-shadow: 0 10px 30px -8px rgba(16, 29, 61, 0.22),
                0 2px 8px -4px rgba(16, 29, 61, 0.14);
    opacity: 0;
    transform: translate3d(0, -130%, 0) scale(0.94);
    /* Chaque bannière arrive avec la carte qu'elle accompagne (délais --d
       des cartes : 2,4 s puis toutes les 1,6 s) et dure 1,6 s, donc elles
       s'enchaînent sans se chevaucher. Arrivées avant, elles annonçaient
       des étapes sur un écran encore vide. */
    animation: sim-notif 1.6s cubic-bezier(0.32, 0.72, 0, 1) both;
    /* Le raccourci ci-dessus remet la lecture à `running` : sans cette
       ligne, les bannières partaient au chargement de la page, bien avant
       le dashboard qui attend le scroll (.sim.is-playing les relance). */
    animation-play-state: paused;
  }

  .sim__event:nth-child(1) { animation-delay: 2.4s; }
  .sim__event:nth-child(2) { animation-delay: 4s; }
  .sim__event:nth-child(3) { animation-delay: 5.6s; }
  .sim__event:nth-child(4) { animation-delay: 7.2s; }
  .sim__event:nth-child(5) { animation-delay: 8.8s; }
  /* La mise en ligne tombe à la fin de la timeline (12,4 s), une fois le
     dashboard complet laissé à l'écran deux secondes. */
  .sim__event:nth-child(6) { animation-delay: 12.4s; }

  /* La mise en ligne est le jalon d'arrivée : sa bannière s'attarde un peu
     plus que les autres, puis se retire comme elles. */
  .sim__event--win {
    animation-duration: 3.4s;
  }

  /* Icône d'application : le carré arrondi d'iOS, aux couleurs de la marque
     plutôt qu'en navy comme dans la timeline de bureau. */
  .sim__event-icon {
    width: 38px;
    height: 38px;
    padding: 8px;
    border-radius: 10px;
    background: #eef1fb;
    box-shadow: inset 0 0 0 0.5px rgba(61, 91, 234, 0.12);
  }

  .sim__event-icon img {
    filter: brightness(0) saturate(100%) invert(31%) sepia(72%) saturate(3661%)
            hue-rotate(228deg) brightness(97%) contrast(94%);
  }

  .sim__event-body {
    flex-direction: column;
    align-items: stretch;
    gap: 1px;
    min-width: 0;
  }

  /* En-tête : nom de l'application à gauche, date à droite, dans le gris
     translucide d'iOS. */
  .sim__event-app {
    display: block;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.045em;
    text-transform: uppercase;
    color: rgba(60, 60, 67, 0.6);
  }

  .sim__event-date {
    position: absolute;
    top: 11px;
    right: 15px;
    flex: none;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: rgba(60, 60, 67, 0.6);
  }

  /* Le « J+12 » appartient au planning, pas à une notification. */
  .sim__event-jalon {
    display: none;
  }

  .sim__event--win .sim__event-date {
    color: rgba(26, 127, 79, 0.85);
  }

  /* Deux lignes au maximum, puis les points de suspension : au-delà, iOS
     tronque aussi. */
  .sim__event-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 14.5px;
    font-weight: 600;
    line-height: 1.28;
    letter-spacing: -0.01em;
  }


  .sim__cta {
    flex-direction: column;
    align-items: stretch;
    text-align: center;
    padding: 16px;
  }

  .sim__cta-action {
    align-items: stretch;
  }

  .section-head {
    margin: 0 auto 40px;
  }

  .section-title {
    font-size: 26px;
    white-space: normal;
  }

  .faq {
    padding: 70px 0 50px;
  }

  .faq__q {
    font-size: 15.5px;
    padding: 18px 2px;
    gap: 14px;
  }

  .faq__signe {
    width: 30px;
    height: 30px;
  }

  .faq__a {
    font-size: 14.5px;
    padding: 0 2px 20px;
  }

  /* ----- Services : un bloc visuel + texte par service -----
     Le visuel unique qui tournait au-dessus de la liste ne se lisait pas sur
     un écran étroit : on ne voyait jamais en même temps l'image et la ligne
     qu'elle illustrait. Ici les deux conteneurs s'effacent (display:
     contents) et `order` intercale chaque panneau avec sa ligne, sans
     toucher au HTML du bureau. */
  .features {
    min-height: 0;
    padding: 64px 0 24px;
  }

  .features__title {
    font-size: 27px;
    line-height: 1.3;
    margin-bottom: 36px;
  }

  .features__title br {
    display: none;
  }

  .features__grid {
    display: flex;
    flex-direction: column;
    gap: 0;
  }

  .features__visual,
  .features__list {
    display: contents;
  }

  /* Tous les panneaux restent affichés : la rotation du bureau ne décide plus
     de rien ici. */
  .features__panel,
  .features__panel.is-active {
    position: relative;
    inset: auto;
    width: 100%;
    aspect-ratio: 640 / 520;
    border-radius: 20px;
    overflow: hidden;
    background: linear-gradient(160deg, #cfe0ff 0%, #eef3ff 45%, #dbe6ff 100%);
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: none;
  }

  /* Les maquettes sont composées pour un panneau de bureau : comprimées à la
     largeur d'un téléphone, elles se coupaient. Chacune est rendue dans un
     cadre de référence de 640 × 520, puis réduite d'un bloc par --k
     (largeur réelle / 640, posé par le script). */
  .features__panel .hero-wall,
  .features__panel .app,
  .features__panel .bp,
  .features__panel .wf {
    inset: auto;
    left: 0;
    top: 0;
    transform-origin: 0 0;
    transform: scale(var(--k, 0.55)) translate(var(--m), var(--m));
    width: calc(640px - 2 * var(--m));
    height: calc(520px - 2 * var(--m));
  }

  .features__panel .hero-wall { --m: 0px; }
  .features__panel .app { --m: 34px; }
  .features__panel .bp  { --m: 30px; }
  .features__panel .wf  { --m: 26px; }

  /* Le cadre de référence laisse plus de place au graphe qu'en bureau
     (réduit à 0,7) : il peut occuper le canevas. */
  .features__panel .wf__scene {
    transform: translate(-50%, -50%) scale(0.86);
  }

  #feature-panel-web   { order: 1; }
  #feature-tab-web     { order: 2; }
  #feature-panel-soft  { order: 3; }
  #feature-tab-soft    { order: 4; }
  #feature-panel-brand { order: 5; }
  #feature-tab-brand   { order: 6; }
  #feature-panel-ia    { order: 7; }
  #feature-tab-ia      { order: 8; }

  /* Plus de ligne active : chaque texte est à côté de son image, rien n'a
     besoin d'être désigné. */
  .feature-row,
  .feature-row.is-active,
  .feature-row:last-of-type {
    padding: 18px 4px 48px;
    border: 0;
  }

  #feature-tab-ia {
    padding-bottom: 0;
  }

  .feature-row__title,
  .feature-row.is-active .feature-row__title {
    font-size: 22px;
  }

  .feature-row__text,
  .feature-row.is-active .feature-row__text {
    font-size: 16px;
    line-height: 1.55;
    margin-top: 6px;
  }

  .process {
    min-height: 0;
    padding: 0 0 72px;
  }

  .process__timeline {
    margin-top: 48px;
  }

  .process__timeline::before {
    left: 5px;
  }

  .process-step,
  .process-step--right,
  .process-step--left {
    width: 100%;
    min-height: 0;
    margin: 0;
    padding: 24px 0 24px 96px;
    text-align: left;
  }

  .process-step--right .process-step__dot,
  .process-step--left .process-step__dot {
    left: 0;
    right: auto;
    top: 28px;
    transform: none;
  }

  .process-step__icon,
  .process-step--right .process-step__icon,
  .process-step--left .process-step__icon {
    left: 24px;
    right: auto;
    width: 56px;
    height: 56px;
    border-radius: 16px;
  }

  .process-step__icon svg {
    width: 24px;
    height: 24px;
  }

  .process__progress {
    left: 5px;
  }


  .footer {
    padding: 64px 0 24px;
  }

  .footer__top {
    grid-template-columns: 1fr 1fr;
    gap: 40px 24px;
    padding-bottom: 40px;
  }



  .footer__brand {
    grid-column: 1 / -1;
  }

  .footer__bottom {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
  }

  .footer__legal {
    flex-wrap: wrap;
    gap: 4px 20px;
  }

  /* Cibles tactiles : ces liens faisaient 17 px de haut, soit moins que la
     moitié de ce qu'un doigt vise correctement. */
  .footer__legal-link,
  .footer__link {
    display: inline-block;
    padding: 9px 0;
  }
}

@media (max-width: 420px) {
  .hero__title {
    font-size: 32px;
  }
}


/* ---------- Réalisations : mur de sites dans leur navigateur ---------- */
.showcase {
  padding: 72px 0 88px;
  overflow: hidden;
}

.showcase__wall {
  display: flex;
  flex-direction: column;
  gap: 36px;
  /* Légère inclinaison : l'œil lit une galerie, pas un tableau. */
  transform: rotate(-2deg) scale(1.04);
}

.showcase__track {
  display: flex;
  gap: 36px;
  width: max-content;
  animation: showcase-scroll 80s linear infinite;
}

/* Rangée du bas décalée d'une demi-fenêtre, comme sur un mur d'écrans. */
.showcase__row--droite .showcase__track {
  margin-left: -220px;
  animation-direction: reverse;
  animation-duration: 70s;
}

@keyframes showcase-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - 18px)); }
}

.browser {
  margin: 0;
  flex: none;
  width: 520px;
  border-radius: 14px;
  overflow: hidden;
  background: #fff;
  border: 1px solid rgba(16, 29, 61, 0.08);
  box-shadow: 0 30px 60px -30px rgba(16, 29, 61, 0.45);
}

.browser__bar {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  background: #f1f2f6;
  border-bottom: 1px solid rgba(16, 29, 61, 0.06);
}

.browser__bar span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ff5f57;
}
.browser__bar span:nth-child(2) { background: #febc2e; }
.browser__bar span:nth-child(3) { background: #28c840; }

/* Barre d'adresse centrée, décalée pour compenser les pastilles. */
.browser__bar i {
  margin: 0 auto;
  transform: translateX(-24px);
  width: 46%;
  padding: 3px 0;
  border-radius: 6px;
  background: #fff;
  font: 500 10px/1 Inter, sans-serif;
  font-style: normal;
  color: #8a91a8;
  text-align: center;
}

/* Toutes les fenêtres au même format, quelle que soit la capture : sinon
   une vraie capture plus panoramique décalerait la rangée. On rogne à
   droite, là où il n'y a que les icônes de la nav. */
.browser img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  object-position: left top;
}

/* Les captures déjà cadrées (maquettes non publiées) restent centrées. */
.browser img.browser__img--centre {
  object-position: center;
}

@media (max-width: 720px) {
  .showcase { padding: 40px 0 56px; }
  .showcase__wall, .showcase__track { gap: 18px; }
  .browser { width: 280px; border-radius: 10px; }
  .browser__bar { height: 20px; gap: 4px; padding: 0 8px; }
  .browser__bar span { width: 6px; height: 6px; }
  .browser__bar i { font-size: 7px; transform: translateX(-14px); }
  .showcase__row--droite .showcase__track { margin-left: -120px; }
  @keyframes showcase-scroll {
    to { transform: translateX(calc(-50% - 9px)); }
  }
}

@media (prefers-reduced-motion: reduce) {
  .showcase__track { animation: none; }
}
