@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');

/* Palette de marque Lifto :
     NAVY   #05172F  -> --ink
     CYAN   #2DBAB9  -> --blue
     ORANGE #FAAA2C  -> --orange
     LIGHT  #E2E7E9  -> --line
   Les variantes -deep / -soft / tint- en derivent.

   Les doublons -rgb ne sont pas decoratifs : var() fait une substitution de
   TEXTE, donc « rgba(var(--blue), .3) » produit « rgba(#2dbab9, .3) », qui est
   invalide. Sans composantes separees, chaque ombre, halo, voile et anneau de
   focus doit reecrire la couleur en dur — c'est ce qui avait produit 33 hex
   disperses dans le fichier. Toute couleur utilisee en rgba() a donc sa
   version -rgb, et c'est elle qu'il faut appeler : jamais un triplet litteral. */
:root {
  --ink: #05172f;
  --ink-rgb: 5, 23, 47;
  /* Navy profond du hero home. Il etait code en dur en rgba(5,24,40,...) dans
     le degrade alors que le fond utilisait --ink : la meme surface etait donc
     peinte avec deux bleus differents. */
  --ink-deep: #030f20;
  --ink-deep-rgb: 3, 15, 32;
  /* Navy eclairci, etat de survol du CTA du header. */
  --ink-light: #0e2c4c;
  --ink-soft: #44566b;
  /* --muted et --blue-deep sont volontairement plus fonces que la teinte de
     marque : le cyan #2DBAB9 ne donne que 2,3:1 sur blanc. --blue-deep est
     cale a 5,29:1, ce qui laisse la marge necessaire pour tenir le seuil WCAG
     AA de 4,5:1 sur les fonds teintes (--surface, --surface-blue). */
  --muted: #5c6e7f;
  --paper: #ffffff;
  --surface: #f5f7f8;
  --surface-blue: #e9f7f6;
  /* Teintes des blocs decoratifs alternes des lignes de fonctionnalites.
     Elles doivent rester tres claires mais se distinguer de --surface : d'ou
     un decalage de teinte (froid / chaud) plutot qu'un ecart de luminosite,
     que l'oeil percoit mieux a ce niveau de contraste. */
  --tint-cool: #ddf1ef;
  --tint-warm: #fdefd5;
  /* Distinct de --tint-warm, qui habille les blocs decoratifs alternes :
     celui-ci est le fond des pastilles et icones orange. Les deux valeurs sont
     proches (1,02:1) mais portent deux roles differents ; les fusionner est un
     arbitrage de design, pas un nettoyage. */
  --tint-orange: #fff2d8;
  --line: #e2e7e9;
  --line-rgb: 226, 231, 233;
  --blue: #2dbab9;
  --blue-rgb: 45, 186, 185;
  --blue-deep: #0e7876;
  --blue-deep-rgb: 14, 120, 118;
  /* Survol des liens et libelles portes par --blue-deep. Texte uniquement. */
  --blue-darker: #0b6b69;
  --orange: #faaa2c;
  --orange-rgb: 250, 170, 44;
  --orange-deep: #ee8b1f;
  --orange-ink: #a15e00;
  --green: #56c590;
  --shadow-sm: 0 10px 30px rgba(var(--ink-rgb), .07);
  --shadow-md: 0 24px 70px rgba(var(--ink-rgb), .12);
  --radius-sm: .75rem;
  --radius-md: 1.25rem;
  --radius-lg: 1.75rem;
  --radius-pill: 999px;
  --header-height: 78px;
  --container: 1180px;
  /* Débord du visuel du hero vers le bord droit de la fenêtre. Nul sous
     1180px ; plafonné à 300px pour que la carte reste dans la hauteur du
     hero (borné à 800px) et ne déborde pas sur la section suivante. */
  --hero-bleed: clamp(0px, calc((100vw - var(--container)) / 2 + 2.5rem), 300px);
  --ease: cubic-bezier(.2, .75, .25, 1);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  color: var(--ink);
  background: var(--paper);
  font-family: 'Plus Jakarta Sans', Arial, sans-serif;
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
body.nav-open { overflow: hidden; }
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; }
button { cursor: pointer; }
h1, h2, h3, h4, p { margin: 0; }
h1, h2, h3, h4 { color: var(--ink); line-height: 1.12; letter-spacing: -.04em; }
h1 { font-size: clamp(2.75rem, 6vw, 5.25rem); font-weight: 800; }
h2 { font-size: clamp(2.1rem, 4vw, 3.6rem); font-weight: 700; }
h3 { font-size: clamp(1.2rem, 2vw, 1.55rem); font-weight: 700; }
p { color: var(--ink-soft); }
main { overflow: clip; }
section, [id] { scroll-margin-top: calc(var(--header-height) + 24px); }

.skip-link {
  position: fixed; z-index: 100; top: -100px; left: 1rem; padding: .7rem 1rem;
  color: #fff; background: var(--ink); border-radius: var(--radius-sm);
}
.skip-link:focus { top: 1rem; }
.container { width: min(var(--container), calc(100% - 2.5rem)); margin-inline: auto; }
.narrow { width: min(760px, 100%); margin-inline: auto; }
.section { position: relative; padding: 7rem 0; }
.section--soft { background: var(--surface); }
.section--blue { background: var(--surface-blue); }
.section--dark { color: #fff; background: var(--ink); }
.section--dark h2, .section--dark h3 { color: #fff; }
.section--dark p { color: rgba(255,255,255,.72); }
.section--dark .eyebrow,
.estimator .eyebrow,
.article-callout .eyebrow,
.cta-panel .eyebrow { color: #fff; }
.section-heading { max-width: 760px; margin-bottom: 3.2rem; }
.section-heading--center { margin-inline: auto; text-align: center; }
.section-heading p { max-width: 650px; margin-top: 1.35rem; font-size: 1.08rem; }
.section-heading--center p { margin-inline: auto; }
/* align-items: flex-start (et non center) : le texte est un bloc anonyme a
   cote du tiret. Sur deux lignes, « center » recalait le tiret au milieu du
   bloc et la 2e ligne repassait SOUS le tiret, desalignee de la 1re. Le tiret
   est donc cale en haut puis descendu a la hauteur optique de la 1re ligne.
   flex: none l'empeche de se comprimer quand le texte est long. */
.eyebrow {
  display: inline-flex; align-items: flex-start; gap: .55rem; margin-bottom: 1rem;
  color: var(--blue-deep); font-size: .78rem; font-weight: 800; letter-spacing: .12em; line-height: 1.45; text-transform: uppercase;
}
.eyebrow::before { content: ''; flex: none; width: 1.55rem; height: 2px; margin-top: .7em; background: currentColor; }
.lead { font-size: clamp(1.08rem, 1.4vw, 1.3rem); line-height: 1.7; }
.text-center { text-align: center; }
.mt-1 { margin-top: 1rem; }
.mt-2 { margin-top: 2rem; }
.mt-3 { margin-top: 3rem; }

/* Compliance banner */
.compliance-banner { background: var(--surface-blue); border-bottom: 1px solid var(--line); }
.compliance-banner__inner { display: flex; align-items: center; justify-content: center; gap: .5rem; padding: .5rem 0; font-size: .82rem; font-weight: 600; color: var(--blue-deep); text-align: center; }
.compliance-banner__inner svg { flex: 0 0 auto; width: 16px; height: 16px; }
/* 760.98 et non 760 : les largeurs de viewport ne sont pas toujours entieres
   (zoom navigateur, mise a l'echelle Windows 125/150%, dpr fractionnaire). A
   760,5px « max-width: 760px » ET « min-width: 761px » etaient tous deux faux :
   la page tombait entre les deux jeux de regles, sans burger, sans CTA flottant
   et avec un header CTA prive de son fond (texte navy illisible sur la photo du
   hero). Le .98 ferme ce trou en conservant 761 comme debut du desktop. */
@media (max-width: 760.98px) {
  .compliance-banner__inner { padding: .5rem 1rem; font-size: .76rem; }
}

/* Header */
.site-header {
  position: sticky; z-index: 50; top: 0; min-height: var(--header-height);
  display: flex; align-items: center; background: rgba(255,255,255,.92);
  border-bottom: 1px solid rgba(var(--line-rgb), .85); backdrop-filter: blur(18px);
}
.site-header__inner { width: min(1280px, calc(100% - 2.5rem)); margin-inline: auto; display: flex; align-items: center; gap: 2rem; }
.brand { display: inline-flex; align-items: center; flex: 0 0 auto; }
.brand img { width: auto; height: 45px; object-fit: contain; }
.site-nav { display: flex; align-items: center; gap: 1.45rem; margin-left: auto; }
.site-nav > a {
  display: inline-flex; align-items: center; gap: .35rem; padding: .5rem .15rem;
  border: 0; color: var(--ink-soft); background: transparent; font-size: .86rem; font-weight: 700;
}
.site-nav > a:hover, .site-nav > a.is-active { color: var(--ink); }
.site-nav > a.is-active { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: .4em; }
.site-header__inner > .header-quick-cta { display: none; }
.nav-toggle { display: none; margin-left: auto; padding: .55rem; border: 1px solid var(--line); border-radius: .65rem; color: var(--ink); background: #fff; }
.nav-toggle svg { width: 1.35rem; height: 1.35rem; }
.header-cta { white-space: nowrap; }

/* Présentation desktop inspirée du header TellDesk. Le breakpoint isole les
   ajustements de densité nécessaires quand les liens sont tous visibles. */
@media (min-width: 761px) {
  :root { --header-height: 86px; }
  .site-header {
    min-height: var(--header-height);
    background: #fff;
    border-bottom: 0;
    backdrop-filter: none;
  }
  .site-header__inner {
    width: 100%;
    max-width: none;
    padding-inline: 4rem;
    gap: 2rem;
  }
  .brand img { height: 54px; }
  .site-nav { gap: 1.45rem; }
  .site-nav > a {
    padding: .75rem .15rem;
    color: var(--ink);
    font-size: .9rem;
    font-weight: 600;
  }
  .site-nav > a:hover { color: var(--blue-deep); }
  .site-nav > a {
    padding-inline: .1rem;
    white-space: nowrap;
    border-radius: .8rem;
    color: var(--ink);
    font-size: .83rem;
  }
  /* Regle unique pour les DEUX etats du header (transparent sur la photo du
     hero en haut de l'accueil, blanc partout ailleurs) : le bouton ne doit
     changer ni de couleur, ni de forme, ni de hauteur au defilement. Il y
     avait avant deux traitements distincts (navy pilule 54px / teal 44px en
     .65rem), ce qui donnait un bouton qui se transformait en cours de scroll.
     Le fond est en --blue-deep et non en --ink : le navy est invisible sur le
     navy profond du hero, alors que le teal tient sur les deux fonds (et
     c'est deja la couleur des boutons principaux du site).
     Le selecteur est en (0,3,1) pour battre « .site-header--home .site-nav > a »
     (0,2,1), qui imposerait sinon au bouton la couleur du texte de navigation. */
  .site-header .site-nav > a.header-cta {
    min-height: 54px;
    padding: .9rem 1.25rem;
    border-radius: var(--radius-pill);
    color: #fff;
    background: var(--blue-deep);
    font-size: .86rem;
    font-weight: 700;
  }
  .site-header .site-nav > a.header-cta:hover,
  .site-header .site-nav > a.header-cta:focus-visible {
    color: #fff;
    background: var(--blue-darker);
    box-shadow: 0 12px 24px rgba(var(--blue-rgb), .24);
  }
}

.site-header--home {
  background: rgba(255,255,255,.94);
  border-bottom-color: rgba(var(--line-rgb), .85);
}
.site-header--home .brand img { filter: none; }
.site-header--home .site-nav > a { color: var(--ink); }
.site-header--home .site-nav > a:hover,
.site-header--home .site-nav > a.is-active { color: var(--blue-deep); }
/* Le CTA n'a plus de traitement propre a l'accueil : il est entierement decrit
   par « .site-header .site-nav > a.header-cta » (media >= 761px), commun aux
   deux etats du header. */

/* Sur l'accueil uniquement, le header se pose sur le hero comme dans la
   composition de reference. La banniere de conformite reste dans le flux et
   les autres pages conservent leur header blanc et sticky. */
@media (min-width: 761px) {
  .site-header--home {
    position: sticky; top: 0; right: auto; left: auto;
    color: #fff;
    background: linear-gradient(90deg, rgba(var(--ink-deep-rgb), .96) 0%, rgba(var(--ink-deep-rgb), .76) 58%, rgba(var(--ink-deep-rgb), .28) 100%);
    border-bottom: 0; backdrop-filter: blur(8px);
  }
  .site-header--home .brand img { filter: none; }
  .site-header--home .site-nav > a { color: rgba(255,255,255,.82); }
  .site-header--home .site-nav > a:hover,
  .site-header--home .site-nav > a.is-active { color: #fff; }
  .hero--home { margin-top: calc(-1 * var(--header-height)); }
}

/* Buttons */
.button {
  display: inline-flex; align-items: center; justify-content: center; gap: .65rem; min-height: 48px; padding: .72rem 1.15rem;
  border: 1px solid transparent; border-radius: .75rem; color: #fff; background: var(--blue-deep);
  font-size: .86rem; font-weight: 800; line-height: 1.2; transition: transform .2s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease);
}
/* Sans largeur explicite, un <svg> inline garde sa taille intrinsèque (~46px) :
   l'icône écrase le texte et le fait passer à la ligne dès que le bouton
   rétrécit (ex. pop-up promo en largeur contrainte). */
.button svg { width: 1.05rem; height: 1.05rem; flex-shrink: 0; }
.button:hover, .button:focus-visible { color: #fff; background: var(--blue-darker); box-shadow: 0 12px 24px rgba(var(--blue-rgb), .24); transform: translateY(-2px); }
.button:focus-visible { outline: 3px solid rgba(var(--blue-rgb), .38); outline-offset: 3px; }
.button--blue { background: var(--blue-deep); }
.button--blue:hover, .button--blue:focus-visible { background: var(--blue-darker); box-shadow: 0 12px 24px rgba(var(--blue-rgb), .24); }
.button--ghost { color: var(--ink); background: transparent; border-color: var(--line); }
.button--ghost:hover, .button--ghost:focus-visible { color: var(--ink); background: #fff; border-color: var(--blue); box-shadow: var(--shadow-sm); }
.button--light { color: var(--ink); background: #fff; }
.button--light:hover, .button--light:focus-visible { color: var(--ink); background: var(--surface-blue); }
.button--small { min-height: 40px; padding: .55rem .9rem; font-size: .78rem; }

/* Hero */
/* min-height (et non height) : un titre long doit pouvoir faire grandir le
   hero au lieu de déborder de son propre padding. */
.hero {
  position: relative; display: flex; align-items: center; min-height: clamp(700px, calc(100svh - var(--header-height)), 800px); padding: 4.5rem 0;
  /* Le degrade se termine sur --surface-blue : c'est ce qui raccorde le hero a
     la section teintee qui le suit. L'arret intermediaire n'a pas de token,
     il n'existe que pour adoucir la course entre le blanc et cette fin. */
  background: linear-gradient(145deg, #fff 0%, #f6faf9 74%, var(--surface-blue) 100%);
}
/* Heroes sans visuel ni grille (pages légales, 404) : la hauteur suit le
   contenu, sinon un simple titre laisse plusieurs centaines de pixels vides.
   Spécificité doublée pour primer sur les min-height des media queries. */
.hero.hero--compact { min-height: 0; padding: 4rem 0 3.5rem; }
.hero--home {
  /* Hauteur relevee (560 -> 620) : la photo source est carree, et une bande
     trop plate obligeait a rogner soit le casque, soit la tablette. */
  min-height: clamp(620px, calc(100svh - 2.2rem), 700px);
  padding: calc(var(--header-height) + 2.4rem) 0 6rem;
  overflow: hidden;
  color: #fff;
  background: var(--ink-deep);
  isolation: isolate;
}
/* Le visuel est borne a la moitie droite au lieu de couvrir tout le hero.
   Avant : inset 0 + object-fit: contain sur une source carree 1024x1024 =
   l'image etait rendue a (hauteur x hauteur) calee a droite, ce qui laissait
   ~880px d'aplat a gauche ET une arete verticale franche a son bord gauche,
   la ou le degrade n'etait plus qu'a ~38% d'opacite. En bornant la boite, le
   degrade est cale sur les bords de l'image : la jonction devient invisible.
   max-width: none neutralise le « max-width: 700px » generique de
   .hero__visual (media queries tablette). */
.hero--home .hero__visual--home {
  position: absolute;
  z-index: -1;
  inset: 0 0 0 auto;
  width: min(58%, 980px);
  min-height: 0;
  max-width: none;
  background: var(--ink-deep);
}
/* .hero__visual::before dessine une carte degradee cyan/orange inclinee a 4°,
   pensee pour les heros a visuel encadre. Elle etait aussi peinte par-dessus
   la photo du hero home (les elements positionnes passent au-dessus du flux)
   et y ajoutait une bande diagonale trouble. */
.hero--home .hero__visual--home::before { display: none; }
.hero--home .hero__visual--home::after {
  position: absolute;
  inset: 0;
  content: '';
  /* Le tout premier arret est a 1 : c'est lui qui rend la jonction avec
     l'aplat invisible. La retombee est ensuite rapide, sinon la tablette et
     la cabine — situees dans le tiers gauche de la photo — restent noyees
     sous le voile. Le texte s'arrete vers 15% de la boite, ou l'opacite est
     encore a ~0,87. */
  background:
    linear-gradient(90deg,
      rgb(var(--ink-deep-rgb)) 0%,
      rgba(var(--ink-deep-rgb), .96) 9%,
      rgba(var(--ink-deep-rgb), .72) 26%,
      rgba(var(--ink-deep-rgb), .32) 52%,
      rgba(var(--ink-deep-rgb), .08) 80%,
      rgba(var(--ink-deep-rgb), 0) 100%),
    linear-gradient(0deg, rgba(var(--ink-deep-rgb), .55), transparent 48%);
}
/* cover (et non contain) : plus de letterbox, donc plus de couture. La boite
   etant bornee a 980px max pour une source de 1024px, l'image reste toujours
   en reduction — jamais d'agrandissement flou sur grand ecran. */
.hero--home .hero__visual--home img { width: 100%; height: 100%; object-fit: cover; object-position: center 42%; }
.hero--home .hero__grid { width: 100%; max-width: none; min-height: 100%; padding-inline: clamp(2.5rem, 5vw, 5.5rem); grid-template-columns: minmax(0, 1fr); }
/* Une seule mesure pour la colonne (avant : 575 sur .hero__copy, 520 sur le
   h1, 520 sur le lead et 630 sur les assurances — le bandeau depassait donc
   tout le reste sur la droite). Le h1 garde volontairement une mesure plus
   courte : un titre display se lit mieux sous ~30 caracteres par ligne. */
.hero--home .hero__copy { max-width: 600px; }
/* Accent unique, pris dans les tokens. Avant : #73d9e8 sur l'eyebrow et
   #20bfd5 sur le h1, deux hex en dur assez proches pour passer pour une
   erreur, en plus de --blue et --blue-deep deja presents. */
.hero--home .eyebrow { color: var(--blue); }
.hero--home .eyebrow::before { background: var(--blue); }
.hero--home h1 { max-width: 540px; color: #fff; font-size: clamp(3rem, 4.4vw, 4.2rem); line-height: 1.02; text-wrap: balance; }
.hero.hero--home h1 em { color: var(--blue); }
.hero--home .hero__copy > .lead { max-width: none; color: rgba(255,255,255,.8); text-wrap: pretty; }
.hero--home .hero__actions { margin-top: 1.5rem; }
/* Bordure adoucie et fond retire : le bouton secondaire avait un poids visuel
   quasi egal au principal alors qu'il est plus large (label plus long). */
.hero--home .button--hero-light { color: #fff; border-color: rgba(255,255,255,.38); background: transparent; }
.hero--home .button--hero-light:hover,
.hero--home .button--hero-light:focus-visible { color: #fff; border-color: rgba(255,255,255,.9); background: rgba(255,255,255,.1); }
/* Bandeau de reassurance : un aplat par bloc, un par couleur de marque
   (navy / cyan / orange). Une precedente version avec 3 teintes saturees hors
   palette (#68220f / #bd4e0a / #12659b) se lisait comme un bandeau d'alerte ;
   ici les 3 aplats sont les couleurs officielles de la charte, donc pas de
   confusion avec un code couleur d'alerte. Le cyan et l'orange n'offrent que
   ~2,3:1 de contraste au blanc (charte non pensee pour du texte clair dessus)
   : ces deux blocs passent donc en texte/icone --ink, qui y tient l'AA. */
.hero__assurances {
  display: grid; grid-template-columns: repeat(3, 1fr); max-width: 600px; margin-top: 1.5rem;
  overflow: hidden; border: 1px solid rgba(var(--blue-rgb), .28); border-radius: .75rem;
  background: var(--ink);
}
.hero__assurance {
  display: grid; grid-template-columns: auto 1fr; align-content: center; align-items: center;
  gap: .05rem .55rem; min-height: 64px; padding: .7rem .85rem; color: #fff;
}
.hero__assurance + .hero__assurance { border-left: 1px solid rgba(var(--blue-rgb), .22); }
.hero__assurance svg { grid-row: span 2; width: 1.15rem; height: 1.15rem; fill: none; stroke: var(--blue); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.hero__assurance strong { font-size: .875rem; line-height: 1.25; }
.hero__assurance small { color: var(--line); font-size: .75rem; line-height: 1.25; }
.hero__assurance:nth-child(2) { color: var(--ink); background: var(--blue); }
.hero__assurance:nth-child(2) svg { stroke: var(--ink); }
.hero__assurance:nth-child(2) small { color: rgba(var(--ink-rgb), .72); }
.hero__assurance:nth-child(3) { color: var(--ink); background: var(--orange); }
.hero__assurance:nth-child(3) svg { stroke: var(--ink); }
.hero__assurance:nth-child(3) small { color: rgba(var(--ink-rgb), .72); }
/* Raccord asymetrique entre le hero et les benefices. Le precedent
   border-radius formait un bombement regulier ; ce SVG dessine une vraie
   ondulation et conserve ses proportions relatives sur toute la largeur. */
.home-benefits { --home-wave-height: clamp(2.5rem, 5vw, 4.75rem); position: relative; z-index: 2; padding: 2.5rem 0 2.8rem; background: #fff; }
.home-benefits__wave { position: absolute; top: calc(-1 * var(--home-wave-height)); left: 0; display: block; width: 100%; height: var(--home-wave-height); pointer-events: none; }
.home-benefits__wave path { fill: #fff; }
.home-benefits__grid { position: relative; z-index: 1; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2.25rem; }
.home-benefit { display: grid; grid-template-columns: 42px minmax(0, 1fr); align-items: start; gap: 1rem; }
.home-benefit__icon { display: grid; width: 36px; height: 36px; place-items: center; color: var(--blue-deep); }
.home-benefit__icon svg { width: 32px; height: 32px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.7; }
.home-benefit h2 { margin-top: .05rem; color: var(--ink); font-size: 1rem; letter-spacing: -.015em; line-height: 1.3; }
.home-benefit p { margin-top: .35rem; color: var(--ink-soft); font-size: .875rem; line-height: 1.5; }
.hero::before, .hero::after { position: absolute; z-index: 0; content: ''; border-radius: 50%; filter: blur(2px); pointer-events: none; }
.hero::before { width: 330px; height: 330px; top: 80px; left: -170px; background: rgba(var(--orange-rgb), .2); }
.hero::after { width: 430px; height: 430px; right: -240px; bottom: -180px; background: rgba(var(--blue-rgb), .15); }
.hero--home::before, .hero--home::after { display: none; }
.hero__grid { position: relative; z-index: 1; display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(500px, .95fr); align-items: center; gap: 4rem; }
.hero__grid > * { min-width: 0; }
.hero h1 { max-width: 720px; }
.hero h1 em { color: var(--orange-deep); font-style: normal; }
.hero__copy > .lead { max-width: 610px; margin-top: 1.5rem; }
.hero__actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 2rem; }
.hero__note { display: flex; align-items: center; gap: .65rem; margin-top: 1rem; font-size: .8rem; }
.hero__note::before { content: '✓'; display: grid; place-items: center; width: 19px; height: 19px; border-radius: 50%; color: #fff; background: var(--green); font-size: .7rem; font-weight: 800; }
.error-mascot { display: flex; align-items: center; justify-content: center; gap: .75rem; margin: 2rem 0 .5rem; }
.error-mascot img { width: 108px; height: 108px; object-fit: contain; }
.error-mascot span { max-width: 220px; padding: .65rem .8rem; border: 1px solid var(--line); border-radius: .8rem .8rem .8rem 0; color: var(--ink-soft); background: #fff; font-size: .75rem; font-weight: 700; text-align: left; }
.hero__visual { position: relative; min-height: 620px; }
.hero__visual::before { position: absolute; inset: 4% 4% 8% 10%; content: ''; border-radius: 2rem; background: linear-gradient(145deg, rgba(var(--blue-rgb), .21), rgba(var(--orange-rgb), .22)); transform: rotate(4deg); }
.dashboard-card { position: absolute; z-index: 1; top: 5%; right: calc(-4% - var(--hero-bleed)); width: calc(108% + var(--hero-bleed)); overflow: hidden; border: 8px solid #fff; border-radius: 1.5rem; box-shadow: var(--shadow-md); transform: rotate(2deg); }
.dashboard-card img { width: 100%; aspect-ratio: 1.42; object-fit: cover; }
.floating-chip { position: absolute; z-index: 2; display: grid; gap: .1rem; padding: .85rem 1rem; border: 1px solid rgba(255,255,255,.7); border-radius: 1rem; background: rgba(255,255,255,.92); box-shadow: var(--shadow-sm); }
.floating-chip strong { color: var(--ink); font-size: .9rem; }
.floating-chip span { color: var(--muted); font-size: .7rem; }
.floating-chip--one { top: 8%; left: -3%; }
.floating-chip--two { right: -5%; bottom: 5%; }
.floating-chip--two strong { color: var(--blue-deep); }
/* min-height: 0 casse le plancher clamp(700px…800px) herite de .hero : ce
   plancher visait le hero home (photo pleine hauteur) mais forcait aussi ces
   heros texte+vignette a ~800px sur desktop quel que soit leur contenu,
   laissant des heros a titre court flotter dans un vide vertical. La hauteur
   suit maintenant le contenu (copy vs visuel, le plus grand des deux). */
.hero--page { padding: 4rem 0; min-height: 0; }
.hero--page h1 { font-size: clamp(2.6rem, 3.6vw, 4.1rem); }
.hero--page .hero__grid { grid-template-columns: 1.1fr .9fr; }
.hero--page .hero__visual { height: 350px; min-height: 350px; }
.hero--page .hero__visual img { width: 100%; height: 350px; object-fit: cover; border-radius: 1.6rem; box-shadow: var(--shadow-md); }
.hero--article { padding: 4rem 0; min-height: 0; }
.hero--article h1 { font-size: clamp(2.5rem, 3.4vw, 4rem); }
.hero--article .hero__grid { grid-template-columns: 1.15fr .85fr; }
.hero--article .hero__visual { height: 320px; min-height: 320px; }
.hero--article .hero__visual img { width: 100%; height: 320px; object-fit: cover; border-radius: 1.6rem; box-shadow: var(--shadow-md); }
/* Les visuels sources verticaux (4:5 et plus) recadres dans une boite de
   320px de haut perdent les tetes si le cadrage reste centre : le sujet de
   ces photos est dans le tiers haut. 18% = le point ou les visages tiennent
   dans la boite sans decoller le sujet du bas de cadre. */
.hero--article .hero__visual--portrait img { object-position: center 18%; }

/* Trust and cards */
.trust { padding: 2.7rem 0; border-bottom: 1px solid var(--line); }
.trust__inner { display: flex; align-items: center; justify-content: space-between; gap: 2rem; }
.trust__label { max-width: 230px; color: var(--muted); font-size: .82rem; font-weight: 700; }
.trust__logos { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .65rem; }
.trust__logo { display: inline-flex; align-items: center; justify-content: center; min-width: 94px; height: 38px; padding: .4rem .75rem; color: #8493a1; border: 1px solid var(--line); border-radius: .65rem; font-size: .75rem; font-weight: 800; letter-spacing: .06em; }
.card-grid { display: grid; gap: 1.2rem; }
.card-grid--3 { grid-template-columns: repeat(3, 1fr); }
.card-grid--4 { grid-template-columns: repeat(4, 1fr); }
.card {
  padding: 1.6rem; border: 1px solid var(--line); border-radius: var(--radius-md); background: #fff; box-shadow: 0 1px 0 rgba(var(--ink-rgb), .02);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease), border-color .25s var(--ease);
}
.card:hover { border-color: rgba(var(--blue-rgb), .35); box-shadow: var(--shadow-sm); transform: translateY(-5px); }
.card__icon { display: grid; place-items: center; width: 48px; height: 48px; margin-bottom: 1.25rem; border-radius: 1rem; color: var(--blue-deep); background: var(--surface-blue); font-size: 1.3rem; }
.card__icon--orange { color: var(--orange-ink); background: var(--tint-orange); }
#avantages .card__icon svg { display: block; width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.card p { margin-top: .75rem; font-size: .93rem; }
/* .8rem valait 12,8px pour la seule action de chaque ligne. Le survol passait
   du bleu a l'orange : un saut de teinte trop large pour un etat de lien, on
   assombrit le bleu a la place (meme valeur que le survol des boutons). */
.card__link { display: inline-flex; align-items: center; gap: .45rem; margin-top: 1rem; color: var(--blue-deep); font-size: .875rem; font-weight: 800; }
.card__link:hover, .card__link:focus-visible { color: var(--blue-darker); }

/* Product sections */
.feature-list { display: grid; gap: 5.5rem; }
.feature-row { display: grid; grid-template-columns: .85fr 1.15fr; align-items: center; gap: 5rem; }
.feature-row:nth-child(even) { grid-template-columns: 1.15fr .85fr; }
.feature-row:nth-child(even) .feature-row__media { order: -1; }
.feature-row__copy h3 { margin-top: .55rem; font-size: clamp(1.75rem, 3vw, 2.55rem); }
.feature-row__copy p { max-width: 500px; margin-top: 1.1rem; }
/* isolation: isolate est indispensable, pas cosmetique. Le bloc decoratif est
   un ::after en z-index: -1. Tant que la ligne porte le transform de
   [data-reveal] (translateY(18px)), ce transform cree un contexte d'empilement
   qui retient le pseudo-element : il s'affiche. Des que .is-visible remet
   transform: none, le contexte disparait, le z-index: -1 remonte jusqu'a la
   racine et le bloc passe DERRIERE le fond de la section, donc devient
   invisible. Resultat : le decor s'affichait pendant l'animation puis
   disparaissait a la fin. En isolant ici, le contexte ne depend plus du
   transform et le decor reste stable. */
.feature-row__media { position: relative; isolation: isolate; }
.feature-row__media::after { position: absolute; z-index: -1; inset: 12% -5% -8% 9%; content: ''; border-radius: 1.5rem; background: var(--tint-cool); }
/* Images posees directement dans .feature-row__media (sans passer par
   .feature-row__frame) restaient a angles droits, en rupture avec le reste
   du site : meme rayon que .feature-row__frame pour rester coherent. */
.feature-row__media > img { display: block; width: 100%; border-radius: 1.4rem; box-shadow: var(--shadow-md); }
/* Recadrage des captures produit.
   Le probleme : les sources sont des captures d'application entieres
   (1096 a 1539px de large) affichees dans une fente de 633px, soit 41 a 58%
   d'echelle — un texte d'interface de 14px tombait a 6px, et a 3px sur mobile.
   La section censee montrer le logiciel ne montrait qu'une tache grise.
   La solution : afficher une FENETRE dans la capture au lieu de la capture
   entiere. --fx/--fy designent le point d'interet (en % de l'image), --zoom
   le facteur d'agrandissement. object-position et transform-origin partagent
   le meme point, donc le pixel vise reste au meme endroit du cadre quand on
   change le zoom : les deux reglages sont independants.
   Les zooms sont calibres sous deux contraintes :
   1. l'echelle finale reste sous 100% — la capture est toujours reduite,
      jamais agrandie, donc jamais floue ;
   2. la fenetre se termine sur une frontiere naturelle (bord de l'image,
      separation entre colonnes, zone blanche) et jamais au milieu d'un
      element. Un titre coupe en plein mot se lit comme un bug d'affichage,
      pas comme un cadrage — mieux vaut une echelle plus faible qu'un bord
      sale. C'est pourquoi la ligne 01 reste en pleine largeur : son en-tete
      et sa rangee d'onglets occupent toute la largeur de la capture, toute
      fenetre partielle les tronquerait ;
   3. la fenetre demarre APRES la gouttiere de la capture. Les exports
      d'application en portent une, et elle varie : 12px a gauche pour le parc,
      25px pour les devis, 44px et 21px en haut pour le planning. Laissee dans
      le cadre, elle formait une bande morte le long du bord ;
   4. rien d'important ne doit tomber dans les coins : le cadre a un
      border-radius de 22px et un overflow: hidden, qui rognent un quart de
      disque a chaque angle. C'est ce qui amputait le libelle « 10:00 » du
      planning en « 0:00 ». La fenetre s'arrete donc avant lui. */
.feature-row__frame {
  position: relative;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  border: 7px solid #fff;
  border-radius: 1.4rem;
  background: #fff;
  box-shadow: var(--shadow-md);
}
.feature-row__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--fx, 50%) var(--fy, 50%);
  /* --zoom est pose en style inline sur chaque cadre (valeur propre a l'image).
     --zoom-boost reste donc pilotable depuis la feuille de style : une valeur
     inline primerait sur une regle de media query. */
  transform: scale(var(--zoom, 1));
  transform-origin: var(--fx, 50%) var(--fy, 50%);
}
/* La ligne « 04 · Vos rapports » ne passe plus par .feature-row : elle a sa
   propre vitrine pleine largeur (.report-showcase, dans report-showcase.css).
   Les regles de cadre document qui vivaient ici n'avaient donc plus de cible. */
/* Le bloc decoratif alternait --surface-blue (#e9f7f6) et un creme code en
   dur. Sur le fond de section (#f5f7f8), le bleu ne ressortait pas — meme
   famille de gris froid, 1,023:1 : une ligne sur deux semblait simplement ne
   pas avoir de bloc. Les deux teintes sont maintenant tokenisees et decalees
   en teinte (froid / chaud), ce qui rend l'alternance perceptible. */
.feature-row:nth-child(even) .feature-row__media::after { background: var(--tint-warm); inset: 12% 9% -8% -5%; }
.product-window { padding: 1.2rem; border: 1px solid var(--line); border-radius: 1.4rem; background: #fff; box-shadow: var(--shadow-md); }
.product-window__bar { display: flex; align-items: center; gap: .4rem; margin-bottom: 1rem; }
.product-window__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--orange); }
.product-window__dot:nth-child(2) { background: var(--blue); }
.product-window__dot:nth-child(3) { background: var(--green); }
.product-window img { width: 100%; border-radius: .8rem; }

.metric-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 1px; margin-top: 3rem; overflow: hidden; border: 1px solid rgba(255,255,255,.16); border-radius: var(--radius-md); background: rgba(255,255,255,.16); }
.metric { padding: 1.6rem; background: rgba(255,255,255,.04); }
.metric strong { display: block; color: var(--orange); font-size: clamp(1.8rem, 3vw, 2.75rem); line-height: 1; }
.metric span { display: block; margin-top: .65rem; color: rgba(255,255,255,.7); font-size: .8rem; }
.step-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 1.2rem; counter-reset: step; }
.step-card { position: relative; overflow: hidden; min-height: 260px; padding: 1.7rem; border-radius: var(--radius-md); color: #fff; background: var(--ink); counter-increment: step; }
.step-card::before { content: '0' counter(step); color: rgba(255,255,255,.42); font-size: 4rem; font-weight: 800; line-height: 1; }
.step-card h3 { margin-top: 1.9rem; color: #fff; }
.step-card p { margin-top: .6rem; color: rgba(255,255,255,.7); font-size: .9rem; }
.step-card .eyebrow { color: #fff; }
.step-card:nth-child(2) { background: var(--blue-deep); }
/* --blue-deep est bien plus clair que --ink : le blanc a 70% des deux autres
   cartes n'y donne que 3,4:1. On remonte l'opacite pour cette carte seule. */
.step-card:nth-child(2) p { color: rgba(255,255,255,.92); }
.step-card:nth-child(3) { color: var(--ink); background: var(--orange-deep); }
.step-card:nth-child(3)::before { color: rgba(var(--ink-rgb), .46); }
.step-card:nth-child(3) .eyebrow,
.step-card:nth-child(3) h3 { color: var(--ink); }
.step-card:nth-child(3) p { color: rgba(var(--ink-rgb), .82); }

/* Personas and guide */
.persona-card { padding: 2rem; border-radius: var(--radius-lg); background: var(--surface-blue); }
.persona-card--orange { background: var(--tint-orange); }
.persona-card__top { display: flex; align-items: start; justify-content: space-between; gap: 1rem; }
.persona-card__top span { color: var(--blue-deep); font-size: .76rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.persona-card--orange .persona-card__top span { color: var(--orange-ink); }
.persona-card p { margin-top: .9rem; font-size: .94rem; }
.persona-card__link { display: inline-flex; margin-top: 1.8rem; color: var(--ink); font-size: .82rem; font-weight: 800; }
.guide-card { overflow: hidden; padding: 0; }
.guide-card__image { position: relative; height: 190px; overflow: hidden; }
.guide-card__image img { width: 100%; height: 100%; object-fit: cover; transition: transform .4s var(--ease); }
.guide-card:hover .guide-card__image img { transform: scale(1.06); }
.guide-card__body { padding: 1.35rem 1.4rem 1.5rem; }
.guide-card__body .eyebrow { margin-bottom: .65rem; font-size: .68rem; }
.guide-card__body h3 { font-size: 1.25rem; }
.guide-card__body p { margin-top: .7rem; font-size: .86rem; }

/* Grille éditoriale des guides — six grands blocs inspirés de la référence. */
#guides .section-heading { max-width: none; margin-bottom: 1.8rem; }
#guides .container { width: calc(100% - 2.5rem); max-width: none; }
/* Titre du hub guides (guide.html). Le :not() evite de rétrécir le titre
   du bloc guides de la page d'accueil, qui utilise --center. */
#guides .section-heading:not(.section-heading--center) h2 { font-size: clamp(2rem, 3vw, 2.65rem); }
#guides .card-grid { gap: 0; }
#guides .guide-card { position: relative; display: block; min-height: 412px; padding: 0; overflow: hidden; border: 0; border-radius: 0; color: #fff; background: var(--ink); box-shadow: none; }
#guides .guide-card:hover { border-color: transparent; box-shadow: none; transform: none; }
#guides .guide-card__image { position: absolute; inset: 0; height: auto; }
#guides .guide-card__image::after { position: absolute; inset: 0; content: ''; background: rgba(var(--ink-rgb), .52); transition: background .25s var(--ease); }
#guides .guide-card:hover .guide-card__image::after { background: rgba(var(--ink-rgb), .38); }
/* Les six cartes sont alimentees par des photos verticales (~972x1619) alors
   que la carte, elle, est en paysage (~466x412 sur desktop). Au cadrage
   centre par defaut, cover ne garde que la bande mediane de l'image et coupe
   les tetes. object-position remonte le cadrage sur le tiers haut, ou se
   trouve l'action de chaque photo. */
#guides .guide-card__image img { width: 100%; height: 100%; object-fit: cover; object-position: center 18%; transition: transform .4s var(--ease); }
#guides .guide-card:hover .guide-card__image img { transform: scale(1.05); }
#guides .guide-card__body { position: absolute; z-index: 1; right: 0; bottom: 0; left: 0; display: flex; flex-direction: column; padding: 5.5rem 1.25rem 1.1rem; background: linear-gradient(180deg, transparent 0%, rgba(var(--ink-rgb), .76) 100%); }
#guides .guide-card__body .eyebrow { order: 2; width: max-content; max-width: 100%; margin: .55rem 0 0; padding: .42rem .65rem; border-radius: var(--radius-pill); color: #fff; background: rgba(var(--ink-rgb), .62); font-size: .68rem; letter-spacing: 0; line-height: 1.2; text-transform: none; }
#guides .guide-card__body .eyebrow::before { display: none; }
#guides .guide-card__body h3 { order: 1; color: #fff; font-size: clamp(1.45rem, 2.55vw, 2rem); line-height: 1.16; }
#guides .guide-card__body p { display: none; }

/* Pricing */
.pricing-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; margin-bottom: 2rem; padding: 1rem 1.2rem; border: 1px solid var(--line); border-radius: var(--radius-md); background: #fff; box-shadow: var(--shadow-sm); }
/* Une seule regle pour les deux groupes : ils avaient la meme mise en colonne
   ecrite deux fois, via un :not() et une classe, ce qui laissait croire a un
   traitement different. */
.pricing-toolbar__group { display: flex; align-items: stretch; flex-direction: column; gap: .5rem; min-width: 0; }
.pricing-toolbar__label { color: var(--muted); font-size: .76rem; font-weight: 800; text-transform: uppercase; letter-spacing: .08em; }
/* .7rem valait 11,2px : c'etait le plus petit texte de la barre alors qu'il
   porte la nuance la plus delicate (un equivalent mensuel n'est pas une
   mensualite). */
.pricing-toolbar__hint { color: var(--muted); font-size: .78rem; line-height: 1.45; text-wrap: pretty; }
.segmented { display: inline-flex; padding: .2rem; border: 1px solid var(--line); border-radius: .75rem; background: var(--surface); }
.segmented button { padding: .58rem .8rem; border: 0; border-radius: .55rem; color: var(--muted); background: transparent; font-size: .78rem; font-weight: 800; transition: color .22s var(--ease), background-color .22s var(--ease), box-shadow .22s var(--ease), transform .22s var(--ease); }
.segmented button.is-active { color: var(--ink); background: #fff; box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.period-toggle { display: grid; grid-template-columns: repeat(2, minmax(150px, 1fr)); gap: .35rem; width: min(100%, 430px); padding: .3rem; border: 1px solid var(--line); border-radius: .85rem; background: var(--surface); }
.period-toggle__option { display: grid; justify-items: center; gap: .15rem; min-height: 3.45rem; padding: .55rem .7rem; border: 1px solid transparent; border-radius: .62rem; color: var(--muted); background: transparent; cursor: pointer; font-size: .78rem; font-weight: 700; line-height: 1.25; text-align: center; transition: border-color .2s var(--ease), background .2s var(--ease), color .2s var(--ease), box-shadow .2s var(--ease); }
.period-toggle__option:hover { color: var(--ink); }
.period-toggle__option.is-active { color: var(--ink); border-color: rgba(var(--blue-rgb), .45); background: #fff; box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.period-toggle__title { font-size: .84rem; font-weight: 800; }
.period-toggle__option small { color: inherit; font-size: .68rem; font-weight: 600; }
.period-toggle__option.is-active small { color: var(--orange-deep); }
.period-toggle__option:focus-visible, .segmented button:focus-visible { outline: 3px solid rgba(var(--blue-rgb), .35); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .segmented button, .period-toggle__option { transition: none; }
}
.price-grid { display: grid; grid-template-columns: repeat(3,1fr); align-items: stretch; gap: 1rem; }
.price-card { position: relative; display: flex; flex-direction: column; padding: 1.7rem; border: 1px solid var(--line); border-radius: var(--radius-lg); background: #fff; box-shadow: var(--shadow-sm); }
.price-card--featured { border: 2px solid var(--blue); box-shadow: 0 24px 60px rgba(var(--blue-rgb), .16); }
.price-card--featured::before { position: absolute; top: -1px; right: 1.4rem; content: 'RECOMMANDÉE'; padding: .35rem .65rem; border-radius: 0 0 .55rem .55rem; color: #fff; background: var(--blue-deep); font-size: .62rem; font-weight: 800; letter-spacing: .08em; }
.price-card__tag { display: inline-flex; padding: .38rem .6rem; border-radius: var(--radius-pill); color: var(--blue-deep); background: var(--surface-blue); font-size: .68rem; font-weight: 800; }
.price-card__tag--orange { color: var(--orange-ink); background: var(--tint-orange); }
.price-card h3 { margin-top: 1.4rem; font-size: 1.65rem; }
.price-card__desc { min-height: 3.2em; margin-top: .55rem; font-size: .88rem; }
.price-card__amount { margin-top: 1.5rem; }
.price-card__amount strong { display: block; color: var(--ink); font-size: clamp(2.5rem, 5vw, 3.75rem); line-height: 1; letter-spacing: -.06em; }
.price-card__amount small { color: var(--muted); font-size: .74rem; font-weight: 700; }
.price-card__after { min-height: 2.8em; margin-top: .6rem; color: var(--muted); font-size: .72rem; }
.price-card__list { display: grid; gap: .6rem; margin: 1.4rem 0 1.5rem; padding: 1.2rem 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.price-card__list li { display: flex; gap: .55rem; color: var(--ink-soft); font-size: .8rem; }
.price-card__list li::before { content: '✓'; color: var(--green); font-weight: 800; }
.price-card .button { width: 100%; margin-top: auto; }
.pricing-note { margin-top: 1.1rem; text-align: center; color: var(--muted); font-size: .76rem; }
.estimator { padding: 2rem; border-radius: var(--radius-lg); background: var(--ink); box-shadow: var(--shadow-md); }
.estimator h2 { color: #fff; font-size: clamp(1.75rem, 3vw, 2.6rem); }
.estimator p { margin-top: .7rem; color: rgba(255,255,255,.7); }
.estimator__head { display: flex; align-items: end; justify-content: space-between; gap: 2rem; }
.estimator__fields { display: flex; gap: .75rem; }
.estimator__field { display: grid; gap: .4rem; color: rgba(255,255,255,.7); font-size: .72rem; font-weight: 800; }
.estimator__field input { width: 130px; padding: .75rem .8rem; border: 1px solid rgba(255,255,255,.25); border-radius: .65rem; color: #fff; background: rgba(255,255,255,.08); }
.estimator__result { display: flex; align-items: center; justify-content: space-between; gap: 2rem; margin-top: 2rem; padding: 1.2rem 1.35rem; border: 1px solid rgba(255,255,255,.16); border-radius: 1rem; background: rgba(255,255,255,.05); }
.estimator__result strong { display: block; color: #fff; }
.estimator__result span { color: rgba(255,255,255,.65); font-size: .76rem; }
.estimator__price { text-align: right; }
.estimator__price > span { display: block; margin-top: .35rem; }
.estimator.is-quote .estimator__price { max-width: 34rem; }
.estimator__price strong { color: var(--orange); font-size: 2rem; }
.estimator__details { display: grid; grid-template-columns: repeat(2, 1fr) auto; align-items: center; gap: .8rem; margin-top: 1rem; }
.estimator__detail { padding: .9rem; border-radius: .8rem; background: rgba(255,255,255,.06); }
.estimator__detail span { display: block; color: rgba(255,255,255,.6); font-size: .68rem; }
.estimator__detail strong { display: block; margin-top: .2rem; color: #fff; font-size: .93rem; }
.estimator__note { font-size: .72rem; }
.estimator.is-quote .estimator__price strong { color: var(--blue); }

/* Articles and legal */
.breadcrumb { display: flex; flex-wrap: wrap; gap: .45rem; margin-bottom: 1.2rem; color: var(--muted); font-size: .76rem; font-weight: 700; }
.breadcrumb a { color: var(--blue-deep); }
.article-layout { display: grid; grid-template-columns: minmax(190px, .27fr) minmax(0, .73fr); gap: 4.5rem; align-items: start; }
.article-toc { position: sticky; top: calc(var(--header-height) + 1.5rem); padding: 1.2rem; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface); }
.article-toc strong { display: block; margin-bottom: .75rem; color: var(--ink); font-size: .73rem; letter-spacing: .1em; text-transform: uppercase; }
.article-toc a { display: block; padding: .48rem .7rem; border-left: 3px solid transparent; border-radius: .45rem; color: var(--ink-soft); font-size: .78rem; line-height: 1.45; transition: color .2s var(--ease), background-color .2s var(--ease), border-color .2s var(--ease); }
.article-toc a.is-active { border-left-color: var(--blue); color: var(--blue-deep); background: var(--surface-blue); font-weight: 700; }
.article-toc a:hover, .article-toc a:focus { color: var(--blue-deep); }
.article-toc a:focus-visible { outline: 3px solid rgba(var(--blue-rgb), .3); outline-offset: 2px; }
.article-content { max-width: 770px; }
.article-content > p, .article-content > ul, .article-content > ol { max-width: 700px; margin-top: 1rem; }
.article-content h2 { margin-top: 4rem; font-size: clamp(1.7rem, 3vw, 2.65rem); }
.article-content h3 { margin-top: 2rem; }
.article-content ul, .article-content ol { padding-left: 1.2rem; color: var(--ink-soft); }
.article-content li { margin-top: .55rem; }
.article-meta { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 1.2rem; color: var(--muted); font-size: .76rem; }
.article-image { margin-top: 2rem; overflow: hidden; border-radius: var(--radius-lg); box-shadow: var(--shadow-md); }
.article-image img { width: 100%; max-height: 490px; object-fit: cover; }
.article-image figcaption { padding: .75rem 1rem; color: var(--muted); background: #fff; font-size: .75rem; }
.takeaway { margin-top: 2rem; padding: 1.35rem 1.5rem; border-left: 4px solid var(--orange); border-radius: 0 var(--radius-md) var(--radius-md) 0; background: #fff8e9; }
.takeaway strong { color: #8c5600; font-size: .75rem; letter-spacing: .1em; text-transform: uppercase; }
.takeaway ul { margin: .65rem 0 0; }
.article-callout { margin-top: 3rem; padding: 2rem; border-radius: var(--radius-lg); background: var(--ink); }
.article-callout h2 { margin: 0; color: #fff; font-size: 2rem; }
/* Un callout ouvre normalement sur un h2, deja passe en blanc. Celui du guide
   CTQ ouvre sur un <strong>, qui heritait donc de --ink : du navy sur le navy
   du bloc, soit 1:1 — la phrase etait litteralement invisible. */
.article-callout > strong { color: #fff; }
.article-callout p { margin-top: .8rem; color: rgba(255,255,255,.72); }
.article-callout .button { margin-top: 1.1rem; }
.article-source { margin-top: 3rem; padding-top: 1.2rem; border-top: 1px solid var(--line); color: var(--muted); font-size: .82rem; }
.article-source strong { display: block; margin-bottom: .4rem; color: var(--ink); font-size: .75rem; letter-spacing: .1em; text-transform: uppercase; }
.article-source p { margin-top: 0; }
.faq-list { display: grid; gap: .7rem; }
.faq-list details { border: 1px solid var(--line); border-radius: .9rem; background: #fff; }
.faq-list summary { position: relative; padding: 1.1rem 3rem 1.1rem 1.2rem; color: var(--ink); cursor: pointer; font-size: .9rem; font-weight: 700; list-style: none; }
.faq-list summary::-webkit-details-marker { display: none; }
/* Sans reperes verticaux, le marqueur se cale sur la ligne de base du texte :
   plus gros que lui, il descendait 6 px sous le centre, et restait sur la
   premiere ligne quand la question en occupait deux. */
.faq-list summary::after { position: absolute; top: 50%; right: 1.2rem; transform: translateY(-50%); content: '+'; color: var(--blue-deep); font-size: 1.3rem; font-weight: 400; line-height: 1; }
.faq-list details[open] summary::after { content: '−'; }
.faq-list .answer { padding: 0 1.2rem 1.1rem; font-size: .85rem; }
.legal { max-width: 850px; }
.legal h2 { margin-top: 3rem; font-size: 2rem; }
.legal p { margin-top: 1rem; }
.legal__updated { color: var(--muted); font-size: .8rem; }
.legal a { color: var(--blue-deep); text-decoration: underline; text-underline-offset: 2px; }

/* Forms / final CTA / footer */
.cta-panel { display: grid; grid-template-columns: 1fr .75fr; gap: 3rem; align-items: center; padding: 3.2rem; border-radius: var(--radius-lg); background: linear-gradient(135deg, var(--blue-deep), #0a5f5e); box-shadow: var(--shadow-md); }
.cta-panel h2 { color: #fff; }
.cta-panel p { margin-top: .9rem; color: rgba(255,255,255,.75); }
.cta-panel__copy { position: relative; min-height: 390px; padding-bottom: 11rem; }
.cta-panel__mascot { position: absolute; right: .5rem; bottom: -1.1rem; display: flex; align-items: end; gap: .6rem; margin: 0; }
.cta-panel__mascot img { width: 145px; height: 145px; object-fit: contain; filter: drop-shadow(0 14px 20px rgba(var(--ink-deep-rgb), .24)); }
.cta-panel__mascot figcaption { margin-bottom: 1.4rem; padding: .55rem .75rem; border-radius: .8rem .8rem .8rem 0; color: var(--ink); background: #fff; font-size: .7rem; font-weight: 800; white-space: nowrap; }
.cta-panel__aside { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: space-between; align-self: stretch; gap: 1.4rem; text-align: center; }
.cta-panel__aside::before { position: absolute; top: -.9rem; left: 50%; width: 250px; max-width: 100%; aspect-ratio: 1; border-radius: 50%; content: ''; background: rgba(255,255,255,.1); transform: translateX(-50%); }
.cta-panel__helper { position: relative; z-index: 1; width: 230px; height: 230px; object-fit: contain; filter: drop-shadow(0 18px 24px rgba(var(--ink-deep-rgb), .3)); }
.cta-panel__aside > .button { width: 100%; max-width: 100%; }
.demo-form { display: grid; gap: 1rem; padding: 1.3rem; border-radius: 1.1rem; background: #fff; }
[data-demo-fields] { display: grid; gap: 1rem; }
.demo-form p.demo-form__hint { margin: 0 0 -.1rem; color: var(--ink-soft); font-size: .68rem; font-weight: 700; }
.demo-form label { display: grid; gap: .4rem; color: var(--ink); font-size: .72rem; font-weight: 800; }
.demo-form__label { display: block; }
.demo-form input, .demo-form select, .demo-form textarea { width: 100%; padding: .72rem .8rem; border: 1px solid var(--line); border-radius: .55rem; color: var(--ink); background: var(--surface); font-size: .82rem; }
.demo-form input:focus-visible, .demo-form select:focus-visible, .demo-form textarea:focus-visible { outline: 3px solid rgba(var(--blue-rgb), .38); outline-offset: 2px; border-color: var(--blue-deep); }
.lifto-select { position: relative; display: block; }
.lifto-select__native { position: absolute; width: 1px !important; height: 1px; padding: 0 !important; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0 !important; }
.lifto-select__trigger { display: flex; align-items: center; justify-content: space-between; width: 100%; min-height: 43px; padding: .72rem .8rem; border: 1px solid var(--line); border-radius: .55rem; color: var(--ink); background: var(--surface); font-size: .82rem; line-height: 1.2; text-align: left; transition: border-color .2s var(--ease), background .2s var(--ease), box-shadow .2s var(--ease); }
.lifto-select__trigger:hover, .lifto-select.is-open .lifto-select__trigger { border-color: rgba(var(--blue-deep-rgb), .55); background: #fff; }
.lifto-select__trigger:focus-visible { outline: 3px solid rgba(var(--blue-rgb), .3); outline-offset: 3px; border-color: var(--blue-deep); }
.lifto-select__trigger svg { flex: 0 0 auto; width: 1rem; margin-left: .7rem; color: var(--blue-deep); transition: transform .2s var(--ease); }
.lifto-select.is-open .lifto-select__trigger svg { transform: rotate(180deg); }
.lifto-select__menu { position: absolute; z-index: 25; top: calc(100% + .4rem); right: 0; left: 0; display: grid; gap: .2rem; max-height: 220px; overflow-y: auto; padding: .35rem; border: 1px solid var(--line); border-radius: .75rem; background: #fff; box-shadow: var(--shadow-md); }
.lifto-select__menu[hidden] { display: none; }
.lifto-select__option { padding: .65rem .7rem; border-radius: .5rem; color: var(--ink-soft); font-size: .8rem; line-height: 1.3; cursor: pointer; }
.lifto-select__option:hover, .lifto-select__option:focus-visible { outline: 0; color: var(--ink); background: var(--surface-blue); }
.lifto-select__option.is-selected { color: var(--blue-deep); background: #e0f5f3; font-weight: 800; }
.lifto-select__option.is-selected::after { float: right; content: '✓'; color: var(--orange-deep); }
.demo-form__grid { display: grid; grid-template-columns: 1fr 1fr; column-gap: .75rem; row-gap: 1rem; }
.demo-form p.demo-form__intro { margin: 0; color: var(--ink); font-size: .82rem; font-weight: 800; }
.demo-form__block { display: grid; gap: 1rem; padding: .9rem; border-radius: .8rem; background: var(--surface); }
.demo-form__block-title { margin: 0; color: var(--blue-deep); font-size: .8rem; }
.demo-form__block input, .demo-form__block select, .demo-form__block textarea { background: #fff; }
.demo-form p.demo-form__note { margin: 0; color: var(--ink-soft); font-size: .7rem; font-weight: 500; line-height: 1.45; }
.demo-form p.demo-form__note strong { color: var(--ink); }
.demo-form__privacy { padding: .85rem; border-radius: .8rem; background: var(--surface-blue); }
.demo-form .demo-form__privacy p { margin: 0; color: var(--ink-soft); font-size: .7rem; line-height: 1.45; }
.demo-form .demo-form__privacy a { color: var(--blue-deep); font-weight: 700; text-decoration: underline; }
.demo-form .demo-form__privacy p strong { color: var(--ink); }
.demo-form label.demo-form__check { display: flex; align-items: start; gap: .55rem; color: var(--ink-soft); font-size: .7rem; font-weight: 600; line-height: 1.4; cursor: pointer; }
.demo-form label.demo-form__marketing { padding: .1rem .15rem 0; color: var(--ink); font-size: .76rem; line-height: 1.45; }
.demo-form__optional { color: var(--muted); font-weight: 500; }
.demo-form__check input { width: auto; min-width: 1.1rem; height: 1.1rem; margin-top: .08rem; padding: 0; accent-color: var(--blue-deep); }
.demo-form__check input:focus-visible { outline: 3px solid rgba(var(--blue-rgb), .38); outline-offset: 2px; }
.demo-form textarea { min-height: 78px; resize: vertical; }
.demo-form button { width: 100%; }
.form-status { min-height: 1.3em; color: var(--blue-deep); font-size: .75rem; }
.form-status[data-state="success"] { color: #146c43; }
.form-status[data-state="error"] { color: #b42318; }
.demo-form__honeypot { position: absolute !important; left: -10000px !important; width: 1px !important; height: 1px !important; overflow: hidden !important; }

/* Page contact : le formulaire devient une destination autonome, lisible et
   confortable sur mobile au lieu d'allonger le bas de la page d'accueil. */
.contact-page { background: linear-gradient(145deg, #fff 0%, var(--surface) 56%, var(--surface-blue) 100%); }
.contact-section { position: relative; padding: clamp(3.5rem, 7vw, 7rem) 0 clamp(4.5rem, 8vw, 8rem); overflow: hidden; }
.contact-section::before { position: absolute; top: -12rem; left: -11rem; width: 28rem; height: 28rem; border-radius: 50%; content: ''; background: rgba(var(--orange-rgb), .14); pointer-events: none; }
.contact-layout { position: relative; display: grid; grid-template-columns: minmax(0, .82fr) minmax(480px, 1.18fr); align-items: start; gap: clamp(2.5rem, 6vw, 6rem); }
.contact-intro { position: sticky; top: calc(var(--header-height) + 2rem); }
.contact-intro h1 { max-width: 12ch; margin-top: .8rem; font-size: clamp(2.6rem, 5vw, 4.8rem); line-height: .98; letter-spacing: -.055em; text-wrap: balance; }
.contact-intro .lead { max-width: 52ch; margin-top: 1.4rem; }
.contact-points { display: grid; gap: .65rem; margin-top: 2rem; }
.contact-point { display: grid; grid-template-columns: 2.9rem 1fr; align-items: center; gap: .85rem; padding: .85rem 1rem; border: 1px solid rgba(var(--line-rgb), .95); border-radius: .9rem; background: rgba(255,255,255,.7); backdrop-filter: blur(10px); }
.contact-point svg { width: 1.35rem; height: 1.35rem; margin-inline: auto; fill: none; stroke: var(--blue-deep); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.contact-point strong, .contact-point span { display: block; }
.contact-point strong { color: var(--ink); font-size: .86rem; }
.contact-point span { margin-top: .12rem; color: var(--ink-soft); font-size: .75rem; }
.contact-alternative { margin-top: 1.5rem; color: var(--ink-soft); font-size: .8rem; }
.contact-alternative a { color: var(--blue-deep); font-weight: 800; text-decoration: underline; text-underline-offset: 3px; }
.contact-card { padding: clamp(1.25rem, 3vw, 2.2rem); border: 1px solid var(--line); border-radius: var(--radius-lg); background: #fff; box-shadow: var(--shadow-md); }
.contact-card__head { margin-bottom: 1.5rem; padding-bottom: 1.35rem; border-bottom: 1px solid var(--line); }
.contact-card__head h2 { max-width: 19ch; margin-top: .45rem; font-size: clamp(1.55rem, 2.5vw, 2.25rem); line-height: 1.08; }
.contact-card__head p { max-width: 58ch; margin-top: .7rem; font-size: .84rem; }
.contact-card .demo-form { gap: 1.15rem; padding: 0; }
.contact-card [data-demo-fields], .contact-card .demo-form__block { gap: 1.15rem; }
.contact-card .demo-form label { gap: .48rem; font-size: .8rem; }
.contact-card .demo-form input, .contact-card .demo-form select, .contact-card .demo-form textarea,
.contact-card .lifto-select__trigger { min-height: 48px; font-size: 1rem; }
.contact-card .demo-form textarea { min-height: 112px; }
.contact-card .demo-form button { min-height: 52px; }
.site-footer { padding: 4.5rem 0 1.25rem; color: #fff; background: var(--ink); }
.site-footer__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 2.5rem; }
.site-footer .brand img { filter: none; }
.site-footer p { max-width: 260px; margin-top: 1rem; color: rgba(255,255,255,.6); font-size: .82rem; }
.site-footer h3 { margin-bottom: .9rem; color: var(--orange); font-size: .75rem; letter-spacing: .1em; text-transform: uppercase; }
.footer-links { display: grid; gap: .55rem; }
.footer-links a { color: rgba(255,255,255,.68); font-size: .8rem; }
.footer-links a:hover { color: #fff; }
.site-footer__bottom { display: flex; justify-content: space-between; gap: 1rem; margin-top: 3rem; padding-top: 1.1rem; border-top: 1px solid rgba(255,255,255,.14); color: rgba(255,255,255,.48); font-size: .72rem; }
.site-footer__bottom a { color: rgba(255,255,255,.7); }
.demo-estimate { padding: 1rem; border: 1px solid var(--line); border-radius: .8rem; background: var(--surface-blue); }
.demo-estimate h3 { font-size: 1rem; }
.demo-estimate p { margin: .6rem 0; white-space: pre-line; overflow-wrap: anywhere; font-size: .9rem; }
.demo-estimate a { display: inline-flex; align-items: center; min-height: 44px; color: var(--blue-deep); font-weight: 700; text-decoration: underline; text-underline-offset: .2em; }
.cookie-banner { position: fixed; z-index: 80; right: 1.25rem; bottom: 1.25rem; left: 1.25rem; display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; padding: 1rem 1.2rem; border: 1px solid var(--line); border-radius: var(--radius-md); background: rgba(255,255,255,.97); box-shadow: var(--shadow-md); }
.cookie-banner p { max-width: 720px; font-size: .8rem; }
.cookie-banner p a { color: var(--blue-deep); text-decoration: underline; text-underline-offset: 2px; }
.cookie-banner__actions { display: flex; flex: 0 0 auto; gap: .6rem; }

/* Promotion à l'arrivée */
.promo-modal { width: min(760px, calc(100% - 2rem)); max-width: 760px; max-height: calc(100dvh - 2rem); overflow: auto; padding: 0; border: 0; border-radius: var(--radius-lg); color: var(--ink); background: transparent; box-shadow: var(--shadow-md); }
.promo-modal::backdrop { background: rgba(var(--ink-rgb), .58); backdrop-filter: blur(4px); }
.promo-modal__surface { position: relative; display: grid; grid-template-columns: 42% 58%; overflow: hidden; min-height: 430px; border: 1px solid rgba(255,255,255,.75); border-radius: var(--radius-lg); background: #fff; }
.promo-modal__visual { position: relative; overflow: hidden; min-height: 430px; background: var(--blue-deep); }
.promo-modal__visual::after { position: absolute; inset: 0; content: ''; background: linear-gradient(180deg, rgba(var(--ink-rgb), .04) 20%, rgba(var(--ink-rgb), .76) 100%); }
.promo-modal__visual img { width: 100%; height: 100%; object-fit: cover; object-position: 60% center; }
@media (min-width: 761px) {
  .promo-modal__visual img { position: absolute; inset: 0; object-position: 32% center; }
}
.promo-modal__content { position: relative; z-index: 1; display: grid; align-content: center; gap: .15rem; padding: 3.2rem 2.6rem 2.5rem; background: linear-gradient(145deg, #fff 0%, #f3faf9 100%); }
.promo-modal .eyebrow { margin-bottom: .8rem; }
.promo-modal h2 { max-width: 400px; font-size: clamp(1.9rem, 4vw, 2.45rem); }
/* Le titre porte tabindex="-1" uniquement pour recevoir le focus a l'ouverture
   (au lieu de la croix de fermeture). Il n'est pas atteignable au Tab : son
   anneau de focus par defaut n'indiquerait rien et encadrerait le titre. */
.promo-modal h2:focus { outline: none; }
/* Remise ramenee de 128px a 72px max. A 128px elle ecrasait tout : le rapport
   avec la ligne qui qualifie l'offre atteignait 8:1 et la modale se lisait
   comme un coupon de reduction plutot que comme une offre logicielle.
   white-space: nowrap retire ici et sur __message : la piste de grille
   s'elargissait au-dela de la modale et le contenu etait rogne par le
   overflow: hidden de __surface (deborde de 15,2px a 320px). Le texte venant
   de l'objet `promotion` en JS, le nowrap cassait aussi a toute largeur des
   qu'on rallongeait le libelle. */
.promo-modal__discount { display: block; margin-bottom: .05em; color: var(--orange-ink); font-size: clamp(3.25rem, 8vw, 4.5rem); letter-spacing: -.03em; line-height: .95; }
.promo-modal__message { display: block; font-size: clamp(1.45rem, 3vw, 1.85rem); line-height: 1.15; text-wrap: balance; }
/* Ligne de qualification remontee : c'est elle qui dit a qui s'applique
   l'offre, elle ne peut pas rester le plus petit texte du bloc. */
.promo-modal p { max-width: 390px; margin-top: 1rem; }
.promo-modal #promo-modal-description { color: var(--ink); font-size: 1.02rem; }
.promo-modal__countdown { margin-top: 1.45rem; }
.promo-modal__countdown-label { margin: 0 0 .65rem !important; color: var(--ink); font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.promo-modal__countdown-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .55rem; max-width: 370px; }
.promo-modal__countdown-unit { display: grid; min-height: 74px; align-content: center; justify-items: center; gap: .2rem; padding: .55rem .35rem; border: 1px solid var(--line); border-radius: .75rem; background: rgba(255,255,255,.78); box-shadow: 0 6px 16px rgba(var(--ink-rgb), .04); }
.promo-modal__countdown-unit strong { color: var(--ink); font-size: clamp(1.45rem, 3vw, 1.9rem); font-variant-numeric: tabular-nums; letter-spacing: -.04em; line-height: 1; }
/* .6rem valait 9,6px : illisible, meme travers que l'ancien bandeau du hero. */
.promo-modal__countdown-unit span { color: var(--ink-soft); font-size: .75rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.sr-only { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; }
/* Hors de la derniere semaine, cette ligne remplace le compte a rebours et
   porte seule l'echeance : elle merite un cran de plus que la fine impression. */
.promo-modal__date { margin-top: 1.35rem !important; color: var(--blue-deep); font-size: .95rem; }
.promo-modal__close { position: absolute; z-index: 2; top: 1rem; right: 1rem; display: grid; width: 2.75rem; height: 2.75rem; place-items: center; padding: 0; border: 1px solid var(--line); border-radius: 50%; color: var(--ink-soft); background: rgba(255,255,255,.86); }
.promo-modal__close:hover, .promo-modal__close:focus-visible { color: var(--ink); border-color: var(--blue); background: var(--surface-blue); }
.promo-modal__close:focus-visible { outline: 3px solid rgba(var(--blue-rgb), .38); outline-offset: 3px; }
.promo-modal__close svg { width: 1.15rem; }
.promo-modal__actions { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; margin-top: 1.75rem; }
.promo-modal__actions .button { min-height: 44px; }
.promo-modal__actions > .button:first-child { min-width: 180px; }
.promo-modal__actions .button--ghost { background: rgba(255,255,255,.72); }

/* Motion */
.js-ready [data-reveal] { opacity: 0; transform: translateY(18px); transition: opacity .75s var(--ease), transform .75s var(--ease); }
.js-ready [data-reveal].is-visible { opacity: 1; transform: none; }
/* Les panneaux CTA restent toujours lisibles : leur contenu ne doit pas
   disparaître si l'observer de défilement se déclenche trop tard. */
.js-ready .cta-panel[data-reveal] { opacity: 1; transform: none; }
/* Le hero est au-dessus de la ligne de flottaison : le masquer jusqu'a
   l'execution du script differé retardait son image de toute la latence
   reseau, puis d'un fondu de 0,75 s. Il s'affiche donc sans attendre. */
.js-ready .hero [data-reveal] { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; animation-duration: .01ms !important; } .js-ready [data-reveal] { opacity: 1; transform: none; } }

@media (max-width: 1020px) {
  .site-nav { gap: .8rem; }
  .hero__grid, .hero--page .hero__grid, .hero--article .hero__grid { grid-template-columns: 1fr; gap: 3rem; }
  .hero__copy { max-width: 760px; }
  .hero__visual { min-height: 390px; max-width: 700px; }
  .dashboard-card { right: 0; width: 100%; }
  .floating-chip--two { right: -1%; }
  .hero { height: auto; min-height: 700px; }
  .hero--page .hero__visual, .hero--article .hero__visual { height: 310px; min-height: 310px; }
  .hero--page .hero__visual img, .hero--article .hero__visual img { height: 310px; }
  .feature-row, .feature-row:nth-child(even) { grid-template-columns: 1fr; gap: 2.2rem; }
  .feature-row:nth-child(even) .feature-row__media { order: 0; }
  .card-grid--4 { grid-template-columns: repeat(2,1fr); }
  .article-layout { gap: 2.5rem; }
  .site-footer__grid { grid-template-columns: 1.2fr repeat(3,1fr); gap: 1.2rem; }
  #guides .guide-card { min-height: 360px; }
  .contact-layout { grid-template-columns: 1fr; }
  .contact-intro { position: static; max-width: 720px; }
  .contact-intro h1 { max-width: 14ch; }
  .contact-points { grid-template-columns: repeat(3, 1fr); }
  .contact-point { grid-template-columns: 1fr; justify-items: start; }
  .contact-point svg { margin-inline: 0; }
}
@media (max-width: 1100px) and (min-width: 761px) {
  /* Zone tablette : la colonne de texte et la photo se rapprochent. On
     retrecit le visuel et la colonne pour que le texte reste sur la partie
     quasi opaque du degrade. */
  .hero--home .hero__visual--home { width: 52%; }
  /* Dans cette zone la boite devient plus haute que large : cover cadre alors
     sur la largeur, et c'est l'axe X d'object-position qui joue (plus l'axe Y).
     40% garde un peu de cabine a gauche au lieu d'un gros plan sur le casque. */
  .hero--home .hero__visual--home img { object-position: 40% center; }
  .hero--home .hero__copy { max-width: 520px; }
  /* En dessous de 1100px, 3 colonnes dans 520px ne laissent que ~120px de
     texte par bloc : les libelles passaient a la ligne (« Reponse sous 24 /
     h »). On empile comme sur mobile plutot que de rogner la typo. */
  .hero__assurances { grid-template-columns: 1fr; max-width: 340px; }
  .hero__assurance + .hero__assurance { border-left: 0; border-top: 1px solid rgba(var(--blue-rgb), .22); }
  .hero__assurance { min-height: 54px; padding: .55rem .8rem; }
  .hero__grid, .hero--page .hero__grid, .hero--article .hero__grid { grid-template-columns: 1fr; gap: 3rem; }
  .hero__copy { max-width: 760px; }
  .hero__visual { min-height: 390px; max-width: 700px; }
  .dashboard-card { right: 0; width: 100%; }
  .hero { height: auto; min-height: 700px; }
  .hero--page .hero__visual, .hero--article .hero__visual { height: 310px; min-height: 310px; }
  .hero--page .hero__visual img, .hero--article .hero__visual img { height: 310px; }
}
/* Zone étroite (tablette portrait, ~761–900px) : le nav desktop et le
   panneau CTA à 2 colonnes débordent avant que .hero passe en 1 colonne
   (1100px) ou que le menu repasse en burger (760px). */
@media (max-width: 900px) and (min-width: 761px) {
  .site-header__inner { padding-inline: 1.5rem; gap: 1rem; }
  .site-nav { gap: .45rem; }
  .site-nav > a { padding: .75rem .05rem; font-size: .72rem; }
  .site-nav > a.header-cta { display: none; }
  .cta-panel { grid-template-columns: 1fr; }
}
/* Voir la note sur le .98 au premier « max-width: 760.98px » de la feuille. */
@media (max-width: 760.98px) {
  :root { --header-height: 70px; }
  .container, .site-header__inner { width: min(100% - 2rem, var(--container)); }
  .section { padding: 5rem 0; }
  .site-header__inner { gap: .5rem; }
  .site-header__inner > .header-quick-cta { display: inline-flex; flex: 0 0 auto; min-height: 44px; margin-left: auto; padding: .55rem .75rem; font-size: .8rem; }
  .header-quick-cta + .nav-toggle { margin-left: 0; }
  .nav-toggle { min-width: 44px; min-height: 44px; }
  .site-header .brand img { height: 39px; }
  .nav-toggle { display: grid; place-items: center; }
  .site-header--home .nav-toggle { color: var(--ink); border-color: var(--line); background: #fff; }
  /* Le header porte un backdrop-filter : il devient le bloc conteneur des
     descendants en position fixed. On ne peut donc pas caler le menu avec
     bottom: 0 (ce serait le bas du header) — la hauteur est donnée en dvh. */
  .site-nav { position: fixed; inset: var(--header-height) 0 auto; height: calc(100vh - var(--header-height)); height: calc(100dvh - var(--header-height)); overflow-y: auto; overscroll-behavior: contain; display: none; align-content: start; gap: .3rem; padding: 1.5rem 1rem calc(2rem + env(safe-area-inset-bottom)); margin: 0; background: #fff; }
  .site-header--home .site-nav { background: #fff; }
  .site-header--home .site-nav > a { color: var(--ink); }
  body.nav-open .site-nav { display: grid; }
  .site-nav > a { justify-content: space-between; padding: .85rem .5rem; color: var(--ink); font-size: 1.25rem; font-weight: 700; letter-spacing: -.02em; }
  .site-nav > a + a { border-top: 1px solid var(--line); }
  .site-nav > a.header-cta { display: none; }
  .hero { height: auto; min-height: auto; padding: 5rem 0 3rem; }
  .hero--home { min-height: 760px; padding: 4.5rem 0 16rem; align-items: start; }
  /* La reserve basse du hero (padding-bottom: 16rem = 256px) doit rester
     superieure a la hauteur de l'image, sinon les reassurances empietent
     dessus. A 260px l'image remontait 22px au-dessus du bas du contenu.
     On reduit l'image plutot que d'augmenter la reserve : le hero mobile
     depasse deja la hauteur d'ecran, l'allonger aggraverait le probleme. */
  /* width: auto annule le « width: min(58%, 980px) » du desktop, sinon la
     bande basse ne ferait que 58% de la largeur malgre left/right a 0. */
  .hero--home .hero__visual--home { top: auto; right: 0; bottom: 0; left: 0; width: auto; height: 224px; min-height: 0; }
  .hero--home .hero__visual--home::after { background: linear-gradient(180deg, rgba(var(--ink-deep-rgb), .1) 0%, rgba(var(--ink-deep-rgb), .2) 42%, rgba(var(--ink-deep-rgb), .75) 100%); }
  .hero--home .hero__visual--home img { object-fit: cover; object-position: center; }
  .hero--home .hero__grid { min-height: 0; }
  .hero--home .hero__copy { max-width: none; }
  .hero.hero--home h1 { font-size: clamp(2.1rem, 9.2vw, 3.4rem); }
  .hero__assurances { grid-template-columns: 1fr; max-width: 340px; margin-top: 1.5rem; }
  /* En colonne, le filet de separation passe en haut et non a gauche. */
  .hero__assurance + .hero__assurance { border-left: 0; border-top: 1px solid rgba(var(--blue-rgb), .22); }
  .hero__assurance { min-height: 54px; padding: .55rem .8rem; }
  .home-benefits { padding: 4rem 0 2.5rem; }
  .home-benefits__grid { grid-template-columns: 1fr; gap: 1.5rem; }
  .home-benefit h2 { font-size: 1.05rem; }
  .home-benefit p { max-width: 320px; font-size: .9rem; }
  .hero--page, .hero--article { padding-top: 2.5rem; }
  .hero h1 { font-size: clamp(2rem, 9vw, 3rem); line-height: 1.08; }
  .hero__visual { min-height: 300px; }
  .dashboard-card { top: 6%; right: 0; width: 100%; border-width: 5px; }
  .dashboard-card img { aspect-ratio: 1.32; }
  .floating-chip--one { left: -1%; }
  .floating-chip--two { right: -1%; }
  .floating-chip { padding: .65rem .75rem; }
  .floating-chip--one { left: -1%; }
  .floating-chip--two { right: -1%; }
  .trust__inner, .pricing-toolbar, .estimator__head, .estimator__result { align-items: stretch; flex-direction: column; }
  .trust__inner { display: grid; }
  .trust__logos { justify-content: flex-start; }
  .card-grid--3, .card-grid--4, .price-grid, .step-grid, .metric-grid { grid-template-columns: 1fr; }
  #guides .guide-card { min-height: 340px; }
  .metric-grid { gap: 1px; }
  .metric { display: grid; grid-template-columns: 110px 1fr; align-items: center; gap: 1rem; }
  .metric strong { min-width: 0; overflow-wrap: break-word; font-size: clamp(1.35rem, 5.5vw, 1.8rem); }
  .feature-list { gap: 4rem; }
  /* Le cadrage mobile visait la lisibilite du texte des captures : ratio 3/2
     force et zoom de 2,15 a 2,72 selon l'image. Mesure sur un ecran de 390px
     (cadre reel 358x239), il n'en restait que 30 a 47% de l'image visible, et
     le bord du cadre tombait en plein milieu d'une carte ou d'une ligne de
     liste — jamais sur une limite naturelle. C'est precisement le defaut que
     le cadrage voulait eviter : un element tranche se lit comme un bug
     d'affichage, pas comme un cadrage.
     La capture est donc montree entiere sur mobile. Son texte n'y est pas
     lisible a cette echelle (~25 a 33%), mais elle joue le role d'une preuve
     visuelle — « voila l'outil » — et c'est le texte de la colonne a cote qui
     porte l'explication. Une vignette complete et nette vaut mieux qu'un
     fragment agrandi qui semble casse.
     Les variables --fx-m / --fy-m / --zoom-m posees en inline dans index.html
     ne sont plus lues ; elles restent inoffensives si on veut revenir a un
     cadrage serre. */
  .feature-row__frame { aspect-ratio: auto; }
  .feature-row__frame img {
    height: auto;
    object-fit: contain;
    object-position: center;
    transform: none;
  }
  .pricing-toolbar__group { align-items: start; flex-direction: column; }
  .period-toggle { width: 100%; }
  .estimator { padding: 1.3rem; }
  .estimator__fields { width: 100%; }
  .estimator__field { flex: 1; }
  .estimator__field input { width: 100%; }
  .estimator__details { grid-template-columns: 1fr; }
  .estimator__result { gap: 1rem; }
  .estimator__price { text-align: left; }
  .article-layout { grid-template-columns: 1fr; gap: 2rem; }
  .article-toc { position: static; }
  .article-toc strong { margin-bottom: .35rem; }
  .article-toc a { display: inline-block; width: 100%; padding: .6rem .7rem; border-bottom: 1px solid var(--line); }
  .article-toc a.is-active { border-bottom-color: var(--blue); }
  .article-content h2 { margin-top: 3rem; }
  .cta-panel { grid-template-columns: 1fr; padding: 1.3rem; }
  .demo-form__grid { grid-template-columns: 1fr; }
  .contact-section { padding: 3rem 0 4.5rem; }
  .contact-layout { gap: 2rem; }
  .contact-intro h1 { max-width: 16ch; font-size: clamp(2rem, 9vw, 3rem); line-height: 1.08; }
  .contact-intro .lead { margin-top: 1rem; font-size: 1rem; }
  .contact-points { grid-template-columns: 1fr; margin-top: 1.5rem; }
  .contact-point { grid-template-columns: 2.7rem 1fr; justify-items: stretch; padding: .75rem .85rem; }
  .contact-point svg { margin-inline: auto; }
  .contact-card { padding: 1rem; border-radius: 1rem; }
  .contact-card__head { margin-bottom: 1.2rem; padding: .2rem .15rem 1.1rem; }
  .contact-card__head h2 { max-width: none; }
  .contact-card .demo-form { gap: 1.05rem; }
  .cta-panel__copy { min-height: 0; padding-bottom: 9.5rem; }
  .cta-panel__mascot { right: 0; bottom: -1.2rem; }
  .cta-panel__mascot img { width: 120px; height: 120px; }
  .cta-panel__mascot figcaption { margin-bottom: 1rem; }
  .cta-panel__aside { margin-top: 1.6rem; gap: 1rem; }
  .cta-panel__aside::before { top: -.6rem; width: 205px; }
  .cta-panel__helper { width: 180px; height: 180px; }
  .site-footer__grid { grid-template-columns: 1fr 1fr; gap: 2rem 1rem; }
  .site-footer__grid > :first-child { grid-column: 1 / -1; }
  .site-footer__bottom { display: grid; }
  .cookie-banner { display: block; right: .75rem; bottom: .75rem; left: .75rem; padding: .9rem; }
  .cookie-banner__actions { margin-top: .8rem; }
  .promo-modal__surface { display: block; min-height: 0; }
  /* Visuel raccourci et paddings resserres : avec le compte a rebours affiche,
     « Plus tard » tombait sous la ligne de flottaison de la modale a 360px et
     le visiteur ne voyait plus qu'un seul bouton, celui de l'achat. */
  .promo-modal__visual { height: 150px; min-height: 150px; max-height: 170px; }
  .promo-modal__content { padding: 1.9rem 1.35rem 1.35rem; }
  .promo-modal__countdown-grid { max-width: none; }
  .promo-modal__countdown { margin-top: 1.15rem; }
  .promo-modal__countdown-unit { min-height: 62px; }
  .promo-modal h2 { max-width: none; font-size: clamp(1.8rem, 8vw, 2.35rem); }
  .promo-modal__discount { font-size: clamp(2.9rem, 15vw, 4rem); }
  .promo-modal__message { font-size: clamp(1.3rem, 6vw, 1.6rem); }
  .promo-modal #promo-modal-description { font-size: .98rem; }
  .promo-modal__actions { margin-top: 1.35rem; }
  .promo-modal p { max-width: none; }
  .promo-modal__actions { display: grid; }
  .promo-modal__actions .button, .promo-modal__actions > .button:first-child { width: 100%; min-width: 0; justify-content: center; }
}
/* Contact delivery: a miniature LiftO cabin, driven by the actual request state. */
.request-delivery[hidden] { display: none; }
.request-delivery { display: flex; align-items: center; gap: 1.15rem; max-height: 180px; overflow: hidden; padding: 1.1rem; border-radius: 16px; background: #eff5fb; animation: delivery-enter .4s ease-out both; transition: max-height 1.2s cubic-bezier(.4,0,.2,1), gap 1.2s cubic-bezier(.4,0,.2,1), padding 1.2s cubic-bezier(.4,0,.2,1), background-color .45s cubic-bezier(.4,0,.2,1); }
.request-delivery__copy { flex: 1; min-width: 0; }
.request-delivery__copy strong { display: block; color: var(--blue-deep); font-size: .95rem; line-height: 1.4; transition: color .45s cubic-bezier(.4,0,.2,1); }
.request-delivery .form-status { margin: .35rem 0 0; font-size: .8rem; line-height: 1.6; }
.request-delivery__lift { flex: 0 0 58px; }
.request-delivery__signal { display: block; width: 16px; height: 4px; margin: 0 auto 6px; border-radius: 2px; background: var(--blue-deep); transition: background-color .45s cubic-bezier(.4,0,.2,1); }
.request-delivery__shaft { position: relative; height: 72px; overflow: hidden; border: 1px solid #c0cfdf; border-radius: 8px 8px 3px 3px; background: #dce7f2; }
.request-delivery__cab { position: absolute; inset: 5px; overflow: hidden; display: grid; place-items: center; border-radius: 4px; background: #146c43; }
.request-delivery__cab i { position: absolute; top: 0; bottom: 0; width: 50%; background: var(--blue-deep); transition: transform 1.6s cubic-bezier(.4,0,.2,1) .2s; }
.request-delivery__cab i:first-of-type { left: 0; border-right: 1px solid #ffffff40; }
.request-delivery__cab i:last-of-type { right: 0; border-left: 1px solid #ffffff40; }
.request-delivery__cab svg { width: 30px; fill: none; stroke: white; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.request-delivery[data-state="sending"] .request-delivery__cab { animation: delivery-rise 1.8s cubic-bezier(.65,0,.35,1) infinite; }
.request-delivery[data-state="success"] { background: #edf7f1; }
.request-delivery[data-state="success"] strong { color: #146c43; }
.request-delivery[data-state="success"] .request-delivery__signal { background: #146c43; }
.request-delivery[data-state="success"] .request-delivery__cab i:first-of-type { transform: translateX(-100%); }
.request-delivery[data-state="success"] .request-delivery__cab i:last-of-type { transform: translateX(100%); }
.request-delivery[data-state="success"] .request-delivery__copy { animation: delivery-copy-in .65s cubic-bezier(.16,1,.3,1) .2s both; }
.request-delivery[data-state="dismissing"] { max-height: 0; pointer-events: none; gap: 0; padding-block: 0; animation: delivery-exit 1.2s cubic-bezier(.4,0,.2,1) forwards; }
.request-delivery[data-state="error"] { background: #fff3ef; }
.request-delivery[data-state="error"] strong { color: #b42318; }
.request-delivery[data-state="error"] .request-delivery__signal { background: #b42318; }
@keyframes delivery-rise { 0% { transform: translateY(70px); opacity: 0; } 25%, 65% { transform: translateY(0); opacity: 1; } 100% { transform: translateY(-70px); opacity: 0; } }
@keyframes delivery-enter { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes delivery-copy-in { from { opacity: .45; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes delivery-exit { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) {
  .request-delivery, .request-delivery[data-state="sending"] .request-delivery__cab, .request-delivery[data-state="success"] .request-delivery__copy, .request-delivery[data-state="dismissing"] { animation: none; }
  .request-delivery, .request-delivery__signal, .request-delivery__copy strong, .request-delivery__cab i { transition: none; }
}
