/* ==========================================================================
   Konkret — direction artistique.

   Registre : peu de texte, beaucoup d'air, une idée par écran, et du mouvement
   qui sert la lecture plutôt que de la retarder. Rien ne dure plus de 600 ms.

   Le choix de la police d'affichage se fait par une classe posée sur <body>
   (voir POLICE dans la configuration) : cinq familles sont livrées, on garde
   celle qui va et on retire les autres.
   ========================================================================== */

@font-face { font-family: "Kk Grotesk";    src: url("/assets/polices/grotesk.woff2") format("woff2");    font-weight: 300 700; font-display: swap; }
@font-face { font-family: "Kk Sora";       src: url("/assets/polices/sora.woff2") format("woff2");       font-weight: 200 600; font-display: swap; }
@font-face { font-family: "Kk Instrument"; src: url("/assets/polices/instrument.woff2") format("woff2"); font-weight: 400 700; font-display: swap; }
@font-face { font-family: "Kk Outfit";     src: url("/assets/polices/outfit.woff2") format("woff2");     font-weight: 200 600; font-display: swap; }
@font-face { font-family: "Kk Fraunces";   src: url("/assets/polices/fraunces.woff2") format("woff2");   font-weight: 300 500; font-display: swap; }

:root {
  --display: "Kk Instrument", system-ui, sans-serif;
  --gr-titre: 500;                 /* graisse des titres, propre à la famille */
  --gr-inter: -.03em;              /* interlettrage des titres */

  --nuit:   #0B1420;
  --nuit-2: #122031;
  --creme:  #F7F8FA;

  --douce:  0 10px 34px -18px rgba(11,20,32,.20);
  --portee: 0 26px 60px -26px rgba(11,20,32,.30);
}

body.p-sora       { --display: "Kk Sora", system-ui, sans-serif;       --gr-titre: 300; --gr-inter: -.025em; }
body.p-grotesk    { --display: "Kk Grotesk", system-ui, sans-serif;    --gr-titre: 400; --gr-inter: -.02em; }
body.p-outfit     { --display: "Kk Outfit", system-ui, sans-serif;     --gr-titre: 300; --gr-inter: -.02em; }
body.p-fraunces   { --display: "Kk Fraunces", Georgia, serif;          --gr-titre: 300; --gr-inter: .01em; }

/* Une seule famille sur tout le site : titres, texte, boutons, libellés. Deux
   typographies sur une même page, c'est ce qui donne l'air « assemblé ». */
body { font-size: 16.5px; font-family: var(--display); }
.bouton, .sur-titre, .heros-oeil, .marque-texte strong, .marque-texte em,
input, textarea, select, button { font-family: var(--display); }

/* ------------------------------------------------------------ typographie -- */

h1, h2, h3, .prix {
  font-family: var(--display);
  font-weight: var(--gr-titre);
  letter-spacing: var(--gr-inter);
  /* Le navigateur équilibre lui-même les lignes : plus de mot esseulé en bas
     d'un titre, et deux lignes pleines valent mieux que quatre bancales. */
  text-wrap: balance;
}
h1 { font-size: clamp(2.3rem, 1.4rem + 3vw, 3.9rem); line-height: 1.08; }
h2 { font-size: clamp(1.8rem, 1.3rem + 1.8vw, 2.7rem); line-height: 1.14; }
h3 { font-size: 1.2rem; line-height: 1.35; letter-spacing: -.015em; }
p  { text-wrap: pretty; }

.chapeau .sur-titre, .sur-titre {
  display: inline-block; 
  font-size: .67rem; font-weight: 600; letter-spacing: .28em; text-transform: uppercase;
  color: var(--bleu); margin-bottom: 1rem;
}
.chapeau .sur-titre::before { display: none; }

.chapeau { max-width: 62ch; }
/* Le titre reste noir même dans un bloc mis en gris. `.mesure` grise tout ce
   qu'il contient pour les paragraphes ; sur /statut et /contact il emportait
   aussi le h1, qui devenait illisiblement pâle. */
.chapeau h1, .chapeau h2 { color: var(--texte); }
/* Le titre prend toute la largeur du chapeau ; seule la phrase qui suit est
   ramenée à une mesure de lecture confortable. */
.chapeau h1, .chapeau h2 { max-width: none; }
.chapeau p { font-size: 1.03rem; line-height: 1.75; color: var(--gris); max-width: 54ch; margin-inline: auto; }

/* Des sections respirées, pas des trous : au-delà de ~5,5 rem on ne lit
   plus une page aérée, on scrolle dans du vide. */
.section { padding: clamp(3rem, 2.2rem + 2.6vw, 5.4rem) 0; }
.section-claire { background: var(--creme); border-block: 0; }
.centre-page { text-align: center; }
.centre-page .chapeau { margin-inline: auto; }

/* ---------------------------------------------------------------- boutons -- */

.bouton {
  padding: .95rem 1.9rem; border-radius: 999px;
  font-size: .73rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
  transition: transform .28s var(--sortie), background-color .28s var(--sortie),
              border-color .28s var(--sortie), box-shadow .28s var(--sortie), color .28s var(--sortie);
}
.bouton:hover { transform: translateY(-2px); }
.bouton svg { display: none; }

.bouton-primaire { background: var(--nuit); color: #fff; box-shadow: var(--douce); }
.bouton-primaire:hover { background: #000; box-shadow: var(--portee); }
.bouton-secondaire { background: transparent; border-color: rgba(11,20,32,.2); color: var(--texte); }
.bouton-secondaire:hover { border-color: var(--nuit); }

/* ------------------------------------------------------------------ en-tête */
/*
   La barre garde une hauteur FIXE. La faire rétrécir au défilement décale le
   contenu, ce décalage change la position de défilement, ce qui repasse sous le
   seuil : la barre se remet à sa taille, et l'affichage se met à danser. Une
   boucle de rétroaction classique — on ne change jamais la hauteur d'un élément
   collant en fonction du défilement.
*/
.entete { background: rgba(255,255,255,.92); backdrop-filter: saturate(160%) blur(12px); }

/* La barre reprend la largeur du reste du site : le fond va d'un bord à
   l'autre, mais logo et onglets s'alignent exactement sur la colonne des
   pages. Une barre plus large que tout ce qu'elle surplombe se voit.
   C'est ce qui la fait tenir : les libellés restent courts, et le bouton
   secondaire est déjà une entrée de la liste. */
/* Les anciennes adresses /avis et /engagements arrivent maintenant sur une
   ancre. Sans cette réserve, le titre visé se range sous l'en-tête collant et
   le visiteur croit avoir atterri au mauvais endroit. */
html { scroll-padding-top: 84px; }

.entete-corps {
  display: flex; align-items: center; gap: 1.2rem;
  width: min(100% - 2.5rem, var(--large)); margin-inline: auto;
  padding-inline: 0;
  min-height: 66px; transition: none;
}
.entete.est-defile .entete-corps { min-height: 66px; }

.entete-nav { margin-left: auto; }
.entete-nav .nav {
  display: flex; flex-wrap: nowrap; align-items: center; gap: .05rem; margin: 0;
}
.entete-nav .nav-lien { padding: .5rem .5rem; font-size: 1rem; white-space: nowrap; }
.entete-nav .nav-lien::after { left: .5rem; right: .5rem; bottom: .2rem; }

/* Le bouton « Nous écrire » redisait l'onglet Contact placé juste à côté, et
   coûtait 207 px — précisément ce qui manquait pour que les onglets soient
   lisibles. La barre garde son point d'appui à droite : « Espace client »
   devient la pastille. */
.entete-actions { display: none; }
.nav-repli { display: block; }
/* Statut et Contact : même forme que l'espace client, mais creuses. Un seul
   aplat dans la barre, sinon plus rien ne ressort. */
.entete-nav .nav-cle {
  margin-left: .3rem; padding: .5rem .85rem; font-weight: 650;
  border: 1px solid var(--filet-fort); border-radius: 999px;
}
.entete-nav .nav-cle::after { display: none; }
.entete-nav .nav-cle:hover { border-color: var(--bleu); color: var(--bleu-lien); }
.entete-nav .nav-cle[aria-current="page"] { border-color: var(--bleu); color: var(--bleu); }

.entete-nav .nav-repli {
  margin-left: .6rem; padding: .52rem 1rem; font-size: .92rem;
  border: 1px solid var(--bleu); border-radius: 999px;
  /* Le seul aplat de la barre : c'est ce qui en fait le point d'appui à
     droite, là où le regard finit sa course. */
  background: var(--bleu); color: #fff; font-weight: 600;
}
.entete-nav .nav-repli::after { display: none; }
.entete-nav .nav-repli:hover { background: var(--bleu-profond); border-color: var(--bleu-profond); color: #fff; }

/* Dans la barre, un libellé va droit au but ; la moitié après « & » ne
   revient que dans le menu déplié, où la place ne manque pas. */
.nav-plus { display: none; }

/* On resserre par paliers plutôt que de replier trop tôt. */
@media (max-width: 1320px) {
  .entete-nav .nav-lien { padding: .5rem .42rem; font-size: .94rem; }
  .entete-nav .nav-cle,
  .entete-nav .nav-repli { padding: .5rem .85rem; font-size: .87rem; }
}
@media (max-width: 1140px) {
  .entete-nav .nav-lien { padding: .5rem .34rem; font-size: .87rem; letter-spacing: -.01em; }
  .entete-nav .nav-cle,
  .entete-nav .nav-repli { padding: .46rem .74rem; font-size: .81rem; }
  .marque-texte em { display: none; }
}
@media (max-width: 1060px) {
  .entete-nav .nav-lien { padding: .5rem .28rem; font-size: .82rem; }
  .entete-nav .nav-cle,
  .entete-nav .nav-repli { padding: .44rem .66rem; font-size: .77rem; }
}


/* ------------------------------------------------------------------ héros -- */

.heros {
  position: relative; isolation: isolate; overflow: hidden;
  padding: clamp(4.5rem, 3rem + 6vw, 8rem) 0 clamp(3.5rem, 2.5rem + 4vw, 6rem);
  background: var(--nuit); border-bottom: 0; text-align: center;
}
/* Plus de voile de lumière derrière le héros. Les deux dégradés éclaircissaient
   le fond sombre, et le titre blanc perdait d'autant son contraste : il
   paraissait délavé sans qu'on voie d'où ça venait. Un aplat franc tient
   mieux. */
.heros::after {
  content: ""; position: absolute; z-index: -1; right: -10%; top: 50%;
  width: min(720px, 76vw); aspect-ratio: 1; transform: translateY(-50%);
  /* --symbole est posée par la mise en page : c'est la même URL versionnée que
     le logo de l'en-tête, donc une seule image téléchargée. Le repli sert aux
     pages autonomes (attente, erreur) qui n'ont pas de version d'assets. */
  background: var(--symbole, url("/assets/img/symbole.png")) no-repeat center / contain;
  /* Le filigrane se voyait à peine ; à ce point-là autant ne pas le mettre. */
  opacity: .1;
}
.heros-grille { display: block; }

.heros-oeil {
  display: inline-block; margin-bottom: 2rem;
  padding: .58rem 1.25rem; border: 1px solid rgba(255,255,255,.26); border-radius: 999px;
   font-size: .65rem; font-weight: 600;
  letter-spacing: .28em; text-transform: uppercase; color: rgba(255,255,255,.88);
}
.heros-oeil::before { display: none; }

.heros h1 { color: #fff; max-width: 30ch; margin-inline: auto; margin-bottom: 1.5rem; }
.heros .accroche {
  color: rgba(255,255,255,.76); font-size: 1.05rem; line-height: 1.8;
  max-width: 52ch; margin-inline: auto; margin-bottom: 2.4rem;
}
.heros-actions { justify-content: center; gap: .8rem; }
.heros .bouton-primaire { background: #fff; color: var(--nuit); }
.heros .bouton-primaire:hover { background: var(--creme); }
.heros .bouton-secondaire { border-color: rgba(255,255,255,.36); color: #fff; }
.heros .bouton-secondaire:hover { border-color: #fff; background: rgba(255,255,255,.08); }

/* Chaque mot du titre se lève à son tour : ça donne le rythme d'une phrase
   qu'on prononce, et c'est fini en moins d'une seconde. */
.mot {
  display: inline-block; opacity: 0; transform: translateY(.5em);
  animation: mot-leve .62s var(--sortie) forwards;
}
/* Le décalage est porté par le CSS, pas par du JavaScript : si le script ne
   tourne pas, le titre s'affiche quand même. Un effet ne doit jamais pouvoir
   retenir le contenu. */
.mot:nth-child(1) { animation-delay: .05s } .mot:nth-child(2) { animation-delay: .11s }
.mot:nth-child(3) { animation-delay: .17s } .mot:nth-child(4) { animation-delay: .23s }
.mot:nth-child(5) { animation-delay: .29s } .mot:nth-child(6) { animation-delay: .35s }
.mot:nth-child(7) { animation-delay: .41s } .mot:nth-child(8) { animation-delay: .47s }
.mot:nth-child(9) { animation-delay: .53s } .mot:nth-child(10){ animation-delay: .59s }
.mot:nth-child(11){ animation-delay: .65s } .mot:nth-child(12){ animation-delay: .71s }
@keyframes mot-leve { to { opacity: 1; transform: none; } }

/* Le repère de défilement : la flèche reste là, en permanence et immobile.
   Ce qui bouge, c'est une bande de lumière qui la traverse de haut en bas —
   la flèche est le rail, pas le mobile. Angles vifs, bouts coupés net. */
.cue {
  position: absolute; left: 50%; bottom: 2rem; transform: translateX(-50%);
  width: 26px; height: 34px;
}
.cue svg { position: absolute; inset: 0; display: block; }

/* Le rail : toujours visible, discret. */
.cue-trait { color: rgba(255,255,255,.26); }

/* La lumière : la même flèche en blanc franc, révélée par une bande étroite
   qui descend. Rien n'apparaît ni ne disparaît — c'est l'éclairage qui passe. */
.cue-lueur {
  color: #fff;
  -webkit-mask-image: linear-gradient(180deg, transparent 34%, #000 50%, transparent 66%);
          mask-image: linear-gradient(180deg, transparent 34%, #000 50%, transparent 66%);
  -webkit-mask-size: 100% 280%;  mask-size: 100% 280%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  animation: cue-lumiere 2.4s var(--sortie) infinite;
}
@keyframes cue-lumiere {
  0%   { -webkit-mask-position: 0 -140%; mask-position: 0 -140%; }
  100% { -webkit-mask-position: 0  140%; mask-position: 0  140%; }
}

/* ------------------------------------------------------------------ cartes */

.carte {
  background: #fff; border: 1px solid rgba(11,20,32,.07); border-radius: 18px;
  padding: 2.1rem 1.9rem; box-shadow: var(--douce);
  transition: transform .35s var(--sortie), box-shadow .35s var(--sortie), border-color .35s var(--sortie);
}
.carte:hover { transform: translateY(-4px); box-shadow: var(--portee); border-color: rgba(11,20,32,.1); }
.carte h3 { margin-bottom: .55rem; }
.carte p { font-size: .95rem; line-height: 1.7; color: var(--gris); margin-bottom: 0; }

.carte-icone {
  width: 46px; height: 46px; border-radius: 15px; margin: 0 auto 1.3rem;
  background: var(--lavis); color: var(--bleu);
  transition: transform .4s var(--vif), background-color .3s var(--sortie);
}
.carte:hover .carte-icone { transform: translateY(-2px) rotate(-4deg); background: #DDEBFB; }
.centre-page .carte { text-align: center; }
.grille { gap: 1.4rem; }

/* ------------------------------------------------------------------ offres */

.offre {
  border: 1px solid rgba(11,20,32,.07); border-radius: 20px; padding: 2.3rem 2rem;
  box-shadow: var(--douce); text-align: center;
  transition: transform .35s var(--sortie), box-shadow .35s var(--sortie);
}
.offre:hover { transform: translateY(-4px); box-shadow: var(--portee); }
.offre h3 { font-size: 1.5rem; margin-bottom: .5rem; }
.offre .prix { font-size: 1.1rem; color: var(--texte); }
.offre .prix small {
   font-size: .66rem; letter-spacing: .15em;
  text-transform: uppercase; color: var(--gris-clair); margin-top: .5rem;
}
.offre ul { text-align: left; }
.offre-mise-en-avant { background: var(--nuit); border-color: var(--nuit); }
.offre-mise-en-avant::before { left: 50%; right: auto; transform: translateX(-50%); top: 1.4rem; }

.etape { border: 1px solid rgba(11,20,32,.07); border-radius: 18px; padding: 1.8rem; box-shadow: var(--douce); }
.etape::before { font-family: var(--display); font-size: 1.4rem; border: 0; background: var(--lavis); color: var(--bleu); }

/* ------------------------------------------------------------------ divers */

.bande, .grille-filet, .deux-colonnes, .schema { display: none; }

.bloc-sombre { background: var(--nuit); text-align: center; }
.bloc-sombre h2 { max-width: 26ch; margin-inline: auto; color: #fff; }
.bloc-sombre p { margin-inline: auto; }
.sombre-grille { grid-template-columns: 1fr; gap: 2.2rem; justify-items: center; }
.bloc-sombre .rangee { justify-content: center; }
.bloc-sombre .bouton-primaire { background: #fff; color: var(--nuit); }
.bloc-sombre .bouton-secondaire { border-color: rgba(255,255,255,.36); color: #fff; }

.pied { border-top: 1px solid rgba(11,20,32,.07); }
.billet-carte { box-shadow: var(--douce); }
.billet-carte h3 { font-size: 1.12rem; }

/* Les liens de contenu se soulignent d'un trait qui se déploie. */
.chapeau p a, .carte p a, .texte-long p a {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px; background-position: 0 100%; background-repeat: no-repeat;
  text-decoration: none; transition: background-size .32s var(--sortie);
}
.chapeau p a:hover, .carte p a:hover, .texte-long p a:hover { background-size: 100% 1px; }

/* Les cartes d'une même grille entrent en cascade — par la position seule,
   comme les blocs qui les portent. Le fondu a été retiré ici aussi : avec un
   remplissage « both » et un retard allant jusqu'à 160 ms, une carte restait
   à l'opacité zéro avant même le début de son animation, et toute la cascade
   redevenait illisible pendant une demi-seconde à chaque révélation. */
.rev.vu > .carte:nth-child(1), .rev.vu > .offre:nth-child(1) { animation: monte .5s var(--sortie) .00s both; }
.rev.vu > .carte:nth-child(2), .rev.vu > .offre:nth-child(2) { animation: monte .5s var(--sortie) .08s both; }
.rev.vu > .carte:nth-child(3), .rev.vu > .offre:nth-child(3) { animation: monte .5s var(--sortie) .16s both; }
@keyframes monte { from { transform: translateY(16px); } }

@media (max-width: 780px) {
  .heros { padding-top: 5rem; }
  .heros-actions { flex-direction: column; align-items: stretch; }
  .heros-actions .bouton { width: 100%; }
  .cue { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .heros::before, .cue::after { animation: none; }
  .mot { opacity: 1; transform: none; animation: none !important; }
  .rev.vu > .carte, .rev.vu > .offre { animation: none; }
}

/* ==========================================================================
   Séquence figée — la méthode, étape par étape.

   Le visuel reste collé pendant qu'on descend ; ce sont les étapes qui
   défilent à côté, et l'illustration qui change. On ne détourne pas le
   défilement : la molette fait ce qu'elle a toujours fait, c'est juste la
   colonne de gauche qui tient en place.
   ========================================================================== */

.sequence { background: var(--creme); padding: 0 0 clamp(3rem, 2rem + 4vw, 6rem); }
.sequence-grille {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 6rem); align-items: start;
}

.sequence-visuel { position: sticky; top: 0; height: 100vh; display: grid; place-items: center; }
.sequence-cadre {
  position: relative; width: min(100%, 460px); aspect-ratio: 4 / 3;
  background: #fff; border: 1px solid rgba(11,20,32,.07); border-radius: 22px;
  box-shadow: var(--douce); display: grid; place-items: center; overflow: hidden;
}
.sequence-cadre .illus {
  position: absolute; width: 68%; height: auto; color: var(--bleu);
  opacity: 0; transform: translateY(10px) scale(.98);
  transition: opacity .45s var(--sortie), transform .55s var(--sortie);
}
.sequence-cadre .illus.actif { opacity: 1; transform: none; }
.sequence-compteur {
  position: absolute; left: 1.3rem; bottom: 1.1rem;
  font-size: .72rem; letter-spacing: .18em; color: var(--gris-clair);
}
.sequence-compteur b { color: var(--bleu); font-weight: 600; font-variant-numeric: tabular-nums; }

.sequence-etapes { list-style: none; margin: 0; padding: 0; }
.etape-long {
  min-height: 62vh; display: flex; flex-direction: column; justify-content: center;
  padding: 2rem 0; max-width: 46ch;
}
.etape-num {
  display: block; font-size: .8rem; letter-spacing: .2em; color: var(--bleu);
  margin-bottom: .9rem; font-variant-numeric: tabular-nums;
}
.etape-long h2 { font-size: clamp(1.7rem, 1.2rem + 1.6vw, 2.4rem); margin-bottom: .7rem; }
.etape-long p { color: var(--gris); font-size: 1.02rem; line-height: 1.75; margin: 0; }

/* L'étape qui n'est pas la vôtre s'efface — sans disparaître, pour qu'on
   garde le fil de ce qui précède et de ce qui suit. */
@media (scripting: enabled) and (min-width: 981px) {
  .etape-long { opacity: .3; transition: opacity .45s var(--sortie); }
  .etape-long.actif { opacity: 1; }
}

@media (max-width: 980px) {
  .sequence-grille { grid-template-columns: 1fr; gap: 1.5rem; }
  .sequence-visuel { position: static; height: auto; margin-bottom: 1rem; }
  .sequence-cadre { width: min(100%, 380px); margin-inline: auto; }
  .sequence-cadre .illus { opacity: 0; }
  .sequence-cadre .illus.actif { opacity: 1; }
  .etape-long { min-height: 0; padding: 1.2rem 0; }
  .etape-long + .etape-long { border-top: 1px solid rgba(11,20,32,.08); }
}

/* ==========================================================================
   Étude de cas
   ========================================================================== */

.cas-tete { display: grid; grid-template-columns: 1.1fr .9fr; gap: clamp(2rem, 4vw, 4rem); align-items: end; }
.cas-tete h2 { font-size: clamp(2rem, 1.4rem + 2vw, 3rem); margin: .3rem 0 .8rem; }
.cas-phrase { color: var(--gris); font-size: 1.04rem; line-height: 1.75; max-width: 44ch; margin: 0; }
.cas-faits { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }
.cas-faits li {
  display: grid; grid-template-columns: 8.5rem 1fr; gap: 1rem;
  padding-bottom: .7rem; border-bottom: 1px solid rgba(11,20,32,.08);
  font-size: .93rem; color: var(--gris);
}
.cas-faits li:last-child { border-bottom: 0; }
.cas-faits b { color: var(--texte); font-weight: 600; }

.cas-grande, .cas-duo { margin: clamp(2rem, 3vw, 3.5rem) 0 0; }
.cas-grande img, .cas-duo img {
  width: 100%; border-radius: 16px; border: 1px solid rgba(11,20,32,.08);
  box-shadow: var(--portee);
}
.cas-duo { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1rem, 2vw, 2rem); }
.cas-duo figure { margin: 0; }
.cas-duo figcaption {
  margin-top: .7rem; font-size: .78rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gris-clair); text-align: center;
}
.cas-grande { margin-inline: 0; }
.cas-grande figure { margin: 0; }

.cas-mot {
  margin-top: clamp(2.5rem, 3vw, 4rem); padding: clamp(1.8rem, 3vw, 2.6rem);
  border-left: 2px solid var(--bleu); background: #fff; border-radius: 0 16px 16px 0;
}
.cas-mot p { font-size: clamp(1.1rem, .95rem + .6vw, 1.4rem); line-height: 1.6; margin: 0 0 .9rem; }
.cas-mot footer { font-size: .82rem; letter-spacing: .12em; text-transform: uppercase; color: var(--gris-clair); }

/* ==========================================================================
   Avis et récit
   ========================================================================== */

.temoignage {
  margin: 0; padding: clamp(2rem, 3vw, 3rem); max-width: 62ch; margin-inline: auto;
  background: #fff; border: 1px solid rgba(11,20,32,.07); border-radius: 20px;
  box-shadow: var(--douce); text-align: left;
}
.temoignage p { font-size: clamp(1.05rem, .95rem + .5vw, 1.3rem); line-height: 1.65; margin: 0 0 1.3rem; }
.temoignage footer { display: grid; gap: .15rem; }
.temoignage strong { font-size: .95rem; }
.temoignage span { font-size: .84rem; color: var(--gris-clair); }

.recit { max-width: 60ch; margin-inline: auto; text-align: left; }
.recit p { font-size: 1.05rem; line-height: 1.85; color: var(--gris); margin-bottom: 1.3rem; }
.recit strong { color: var(--texte); }

@media (max-width: 900px) {
  .cas-tete { grid-template-columns: 1fr; align-items: start; }
  .cas-duo { grid-template-columns: 1fr; }
  .cas-faits li { grid-template-columns: 1fr; gap: .2rem; }
}

/* ==========================================================================
   Entrée de page et apparition des blocs
   ========================================================================== */

/* À l'ouverture, le contenu monte d'un souffle. Court — 550 ms — et une seule
   fois : une transition qu'on remarque deux fois est une transition de trop.

   C'est une ANIMATION, pas une transition pilotée par le script. Une animation
   se termine toute seule ; une transition qui ne part jamais laisse la page
   invisible. Le contenu ne dépend donc de rien pour s'afficher. */
main { animation: page-entre .55s var(--sortie) both; }
@keyframes page-entre { from { opacity: 0; transform: translateY(10px); } }

/* Les blocs qui arrivent : un peu plus de course qu'avant, et un léger
   grandissement — ça donne du relief sans que rien ne saute. */
.rev.vu {
  transition: opacity .55s var(--sortie), transform .6s var(--sortie);
}
@media (scripting: enabled) {
  .rev { transform: translateY(22px) scale(.985); }
}

@media (prefers-reduced-motion: reduce) {
  main { animation: none; }
  .rev { opacity: 1 !important; transform: none !important; }
  .sequence-cadre .illus { transition: none; }
}

/* ==========================================================================
   Étude de cas : la diapositive qui alterne
   ========================================================================== */

.cas { padding: clamp(2rem, 1.5rem + 2vw, 3.5rem) 0 clamp(3rem, 2.2rem + 2.6vw, 5rem); }

.cas-diapo {
  position: relative; aspect-ratio: 1400 / 694;
  border-radius: 18px; overflow: hidden;
  border: 1px solid rgba(11,20,32,.08); box-shadow: var(--portee);
  background: var(--creme);
  margin-bottom: clamp(2rem, 3vw, 3.5rem);
}
.cas-diapo img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
/* Douze secondes de cycle : assez long pour lire la vue, assez court pour
   qu'on comprenne qu'il y en a une deuxième. L'accueil passe en premier. */
.cas-diapo .diapo-a { animation: diapo-a 12s ease-in-out infinite; }
.cas-diapo .diapo-b { animation: diapo-b 12s ease-in-out infinite; }
@keyframes diapo-a {
  0%, 40%   { opacity: 1; transform: scale(1); }
  50%, 90%  { opacity: 0; transform: scale(1.015); }
  100%      { opacity: 1; transform: scale(1); }
}
@keyframes diapo-b {
  0%, 40%   { opacity: 0; transform: scale(1.015); }
  50%, 90%  { opacity: 1; transform: scale(1); }
  100%      { opacity: 0; transform: scale(1.015); }
}

.diapo-legende {
  position: absolute; left: 1rem; bottom: 1rem; z-index: 2;
  display: grid; /* les deux libellés se superposent et se relaient */
}
.diapo-legende b {
  grid-area: 1 / 1;
  padding: .35rem .8rem; border-radius: 999px;
  background: rgba(11,20,32,.72); color: #fff;
  font-size: .66rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
}
.diapo-legende .leg-a { animation: diapo-a 12s ease-in-out infinite; }
.diapo-legende .leg-b { animation: diapo-b 12s ease-in-out infinite; }

.cas-grande figcaption, .cas-duo figcaption {
  margin-top: .7rem; font-size: .74rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gris-clair); text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  /* Sans mouvement, on montre l'accueil et on cache l'autre — pas de
     clignotement, et l'information principale reste visible. */
  .cas-diapo .diapo-a, .diapo-legende .leg-a { animation: none; opacity: 1; }
  .cas-diapo .diapo-b, .diapo-legende .leg-b { animation: none; opacity: 0; }
}

/* Une carte qui suit directement le titre de page porte un h2 : elle garde la
   taille d'un h3, mais l'ordre des niveaux reste correct pour un lecteur
   d'écran. La forme suit le sens, pas l'inverse. */
.carte h2, .offre h2, .entree-mise-en-avant h2 {
  font-size: 1.2rem; line-height: 1.35; letter-spacing: -.015em;
  font-weight: var(--gr-titre); margin-bottom: .55rem;
}
.offre h2 { font-size: 1.5rem; margin-bottom: .5rem; }

/* Sur un téléphone, 90 barres de 2 px avec 2 px d'écart font 358 px : la page
   d'état débordait de 34 px et le doigt partait en travers. On resserre. */
@media (max-width: 560px) {
  /* Trente barres tiennent sans se serrer, même sur un téléphone. */
  .statut-barres { gap: 2px; height: 26px; }
  .statut-jour { min-width: 4px; }
  .dispo-barres { gap: 1px; height: 30px; }
  .dispo-jour { min-width: 1px; }
}

/* ==========================================================================
   En-tête replié — il porte maintenant sur la SECONDE rangée.

   La règle du fichier de base visait `.nav`, qui n'est plus le panneau : c'est
   `.entete-nav` qui se replie. Sans cette reprise, le menu du téléphone
   s'ouvrait à moitié — la moitié qui n'existe plus.
   ========================================================================== */
@media (max-width: 1000px) {
  .entete-nav {
    position: absolute; top: 100%; left: 0; right: 0;
    background: #fff; border-top: 1px solid var(--filet);
    box-shadow: var(--ombre-forte);
    max-height: calc(100dvh - 66px); overflow-y: auto;
    visibility: hidden; opacity: 0; transform: translateY(-8px); pointer-events: none;
    transition: opacity .22s var(--sortie), transform .28s var(--sortie), visibility 0s .3s;
  }
  .menu-bascule:checked ~ .entete-nav {
    visibility: visible; opacity: 1; transform: none; pointer-events: auto;
    transition: opacity .22s var(--sortie), transform .28s var(--sortie), visibility 0s;
  }
  /* Le fichier de base repliait `.nav` : c'était le panneau, c'est désormais le
     conteneur intérieur. Sans cette remise à plat, le panneau extérieur
     s'affichait vide et le menu du téléphone ne s'ouvrait plus du tout. */
  .entete-nav .nav {
    position: static; visibility: inherit; opacity: 1; transform: none;
    background: transparent; box-shadow: none; border-top: 0;
    flex-direction: column; align-items: stretch; flex-wrap: wrap;
    padding: .5rem 1.25rem 1rem; min-height: 0; gap: 0;
    transition: none;
  }
  .entete-nav .nav-lien { padding: .74rem .2rem; font-size: 1rem; }
  .entete-nav .nav-cle,
  .entete-nav .nav-repli {
    margin-left: 0; padding: .74rem .2rem; font-size: 1rem; font-weight: 500;
    border: 0; border-radius: 0;
  }
  .entete-nav .nav-cle:hover,
  .entete-nav .nav-repli:hover { background: transparent; color: inherit; }
  .nav-plus { display: inline; }
  .entete-nav .nav-lien::after { left: .2rem; right: auto; width: 18px; bottom: .48rem; }

  /* Les deux actions ne tiendraient pas dans la rangée du haut à côté du logo :
     elles redeviennent des entrées de la liste dépliée. */
  .entete-actions { display: none; }
  .nav-repli { display: block; }
}

/* ==========================================================================
   --- accueil : ce qu'on promet ---

   Un site qu'on a fait, face à ce qui vient avec. La page d'accueil ne montrait
   aucune image : une liste d'engagements toute seule se lit comme des
   conditions générales, la même liste à côté d'un écran allumé se lit comme une
   démonstration. C'est la seule chose ajoutée — le reste de la page ne bouge
   pas.
   ========================================================================== */

.promesses {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 3.6rem); align-items: center;
  /* La section est centrée ; une liste de cinq lignes centrée serait illisible. */
  text-align: left;
  margin-top: clamp(2.8rem, 2.2rem + 2vw, 4.2rem);
  padding-top: clamp(2.4rem, 2rem + 1.6vw, 3.4rem);
  border-top: 1px solid var(--filet);
}

/* Le cadre coupe l'image plutôt que `object-fit`. La capture fait deux fois
   plus large que haute : dans un cadre moins large qu'elle, `cover` remplit par
   la hauteur et garde donc le bas de la page — un aplat blanc qui tire l'œil
   vers le vide. On l'agrandit, et le cadre fait le recadrage. */
.promesses-vue {
  margin: 0; aspect-ratio: 1.9 / 1; overflow: hidden;
  border: 1px solid var(--filet); border-radius: var(--rayon);
  box-shadow: var(--douce);
}
.promesses-vue img { width: 125%; max-width: none; height: auto; }

.promesses-liste h3 {
  margin-bottom: 1.4rem;
  font-size: .67rem; font-weight: 600; letter-spacing: .28em; text-transform: uppercase;
  color: var(--bleu);
}
.promesses-liste ul { list-style: none; margin: 0; padding: 0; }
.promesses-liste li {
  display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: .15rem 1rem;
  padding-block: .95rem; border-top: 1px solid var(--filet);
}
.promesses-liste li:first-child { padding-top: 0; border-top: 0; }
/* L'icône tient les deux lignes de sa promesse : sans ça elle se range au-dessus
   du texte et la colonne part en escalier. */
.promesse-ico { grid-row: span 2; display: flex; padding-top: .2rem; color: var(--bleu); }
.promesses-liste b { font-size: .97rem; font-weight: 650; color: var(--texte); }
.promesses-liste p { margin: 0; font-size: .89rem; line-height: 1.55; color: var(--gris); }

@media (max-width: 900px) {
  .promesses { grid-template-columns: 1fr; gap: 2rem; }
  .promesses-vue { aspect-ratio: 1.9 / 1; }
  .promesses-vue img { width: 125%; }
}
