/* ============================================================
   BUREAU DE BEAUFORT — LANDING (css/landing.css)
   ------------------------------------------------------------
   Styles SPÉCIFIQUES à web/index.html. Le reset / body / typo /
   boutons / champs génériques vivent dans css/theme.css (chargé
   avant celui-ci, et NO-TOUCH) — on ne les redéfinit qu'aux
   endroits où la landing doit s'en détacher, et c'est dit.
   Les couleurs passent par les jetons var(--...) : jamais un
   hex de la charte en dur (garde posée en session 102).
   ============================================================ */

/* ⚠️ PAS de `scroll-behavior:smooth` ici, et c'est un choix MESURÉ, pas un oubli.
   Le défilement doux était en place ; sur un téléphone, il RATAIT sa cible :
   appuyer sur « Demander un accès » s'arrêtait 765 px avant le formulaire, et
   ce qu'on voyait à l'arrivée, c'était la grille des TARIFS. Mesuré à 390 px,
   trouvé en cliquant, et reproduit à l'identique par deux mesures indépendantes
   (arrêt à la même position, 6061 px). Le lien « Nous en parler » et l'ouverture
   directe de …/#acces rataient de même.
   La cause n'est ni le contenu qui bouge (le document ne grandit pas d'un pixel
   pendant le défilement) ni l'en-tête collant : c'est l'animation de la
   navigation par ancre elle-même, qui abandonne sur une longue distance.
   Sans elle, l'atterrissage est EXACT : 92 px, c'est-à-dire pile le
   `scroll-margin-top` ci-dessous.
   Ce qu'on perd : le glissement doux. Sur 6 800 px il durait plusieurs secondes
   — et il était déjà désactivé pour qui règle son système sur « animations
   réduites », donc la page devait de toute façon rester juste sans lui.
   ⚠️ Si quelqu'un veut le remettre, il faut d'abord régler l'atterrissage :
   le vérifier avec `py outils/banc_responsive.py` NE SUFFIT PAS — le banc
   mesure la mise en page, pas la navigation. Il faut cliquer. */

/* L'en-tête est collant : sans cette marge, une ancre atterrit SOUS la barre. */
:target{scroll-margin-top:92px}

/* theme.css met body en flex (mise en page app avec sidebar) : la landing
   n'a pas de sidebar, on repasse en flux normal + retire la contrainte de
   taille/hauteur de ligne de l'app pour retrouver les proportions maquette. */
body.page-landing{display:block;min-height:0;font-size:16px;line-height:1.6}

/* ===== SOCLE FLUIDE — la page se replie TOUTE SEULE =========================
   Demande d'Hubert (03/08/2026) : « qu'on n'ait plus besoin de passer du temps
   à s'assurer que la version web passe pour l'un et pour l'autre ».

   Le principe tient en une phrase : on ne décrit plus des ÉCRANS, on décrit des
   CONTRAINTES. Une marge qui suit la largeur, une grille qui compte ses colonnes
   toute seule, une image qui ne peut pas dépasser son cadre. Un bloc ajouté
   demain se range sans qu'on écrive un seul palier de plus.

   ⚠️ Ce qu'on ne fait PAS, volontairement : `overflow-x:hidden` sur le body.
   C'est le raccourci classique, et c'est un piège — il MASQUE le débordement au
   lieu de le corriger (le contenu reste coupé, simplement on ne peut plus le
   voir), il casse `position:sticky` sur l'en-tête, et surtout il rendrait
   `web/banc_responsive.py` AVEUGLE : le banc mesure scrollWidth, qui ne
   dépasserait plus jamais. On corrige la cause, on ne cache pas le symptôme.

   Le contrôle se lance en une commande :  py web/banc_responsive.py
   (9 tailles réelles, de 320 px à 1920 px — voir l'en-tête du fichier). */

/* Rien ne peut être plus large que son cadre. theme.css ne pose PAS cette règle
   (son reset s'arrête à box-sizing) : sans elle, chaque image doit recevoir sa
   propre largeur en CSS, et la première qu'on oublie fait glisser la page. */
.page-landing img,
.page-landing svg,
.page-landing video{max-width:100%;height:auto}

/* Un mot insécable plus long que la colonne (adresse e-mail, URL, nom composé)
   est la deuxième cause de page qui glisse. Sur un téléphone de 320 px, la
   colonne de texte fait 288 px : « contact@bureaudebeaufort.fr » n'en est pas
   loin. On l'autorise à se couper plutôt qu'à déborder. */
.page-landing p,.page-landing h1,.page-landing h2,.page-landing h3,
.page-landing a,.page-landing li{overflow-wrap:break-word}

/* Colonne centrale commune à toutes les sections.
   Marge FLUIDE : 16 px sur un téléphone étroit, 28 px dès 700 px, et tout le
   dégradé entre les deux — sans aucun palier. Elle remplace les trois valeurs
   qui vivaient dans trois media queries différentes (28 / 18 / 14 px), dont la
   dernière était morte : déclarée avant celle de 430 px, elle était écrasée en
   silence à 320 px (mesuré : 18 px appliqués au lieu des 14 px voulus). */
.conteneur{max-width:1140px;margin:0 auto;padding:0 clamp(16px,4vw,28px)}

/* GRILLES DE CARTES — elles comptent leurs colonnes toutes seules.
   Avant : `repeat(3,1fr)` en dur, plus une media query à 880 px qui les passait
   TOUTES à une colonne d'un coup. Deux endroits à penser à chaque fois qu'on
   ajoute une carte, et un repli brutal (3 colonnes puis 1, rien entre les deux).
   Maintenant : on déclare la largeur de référence d'une carte (--carte-min) et
   la ligne en accueille autant que la place permet — 3, puis 2, puis 1. Aucun
   palier à écrire, aucune valeur à re-régler si une carte s'ajoute.

   ⚠️ FLEX et non `grid + auto-fit`, et c'est mesuré, pas une préférence : avec
   une grille auto-fit, un nombre IMPAIR de cartes laisse un trou. Vu à 768 px
   sur les tarifs — deux blocs côte à côte, « Format A4 » seul sur la ligne
   suivante et la moitié droite vide. En flex, la carte restée seule s'étire sur
   toute la largeur : jamais de trou, quel que soit le nombre de cartes.
   Sur une ligne complète, les deux techniques donnent des colonnes strictement
   égales — le rendu grand écran est donc inchangé.

   `min(100%,…)` n'est pas décoratif : sans lui, une carte de 380 px de base
   déborde un écran de 320 px au lieu de se réduire. C'est le piège classique,
   et c'est exactement ce qui casse une page sur téléphone. */
.etapes,.grille-tarifs,.grille-secteurs,.grille-preuve{display:flex;flex-wrap:wrap}
/* `> *` et non les classes : la grille des tarifs est REMPLIE PAR landing.js
   depuis le catalogue du backend. Une règle accrochée à `.bloc-tarif` cesserait
   de s'appliquer le jour où le JS change de nom de classe — sans rien casser de
   visible en local, et en cassant la page en ligne. */
.etapes>*,.grille-tarifs>*,.grille-secteurs>*,.grille-preuve>*{
  flex:1 1 min(100%,var(--carte-min));
}

/* ⚠️ Sans cette ligne, l'attribut `hidden` NE MASQUE RIEN sur nos boutons :
   theme.css donne `display:inline-flex` à .btn, et une règle de classe l'emporte
   sur le `display:none` que le navigateur attache à [hidden]. C'est exactement
   ce qui affichait « Réserver un appel » alors qu'aucune URL de rendez-vous
   n'est renseignée. */
.page-landing [hidden]{display:none !important}

/* ===== Accessibilité : anneau de focus visible ==============
   theme.css ne donne d'anneau qu'aux champs de formulaire. Sans cette
   règle, une personne qui navigue au clavier traverse toute la page sans
   savoir où elle est (relevé de l'audit). On le pose sur TOUT ce qui est
   focalisable, y compris le bouton d'envoi et les liens du pied. */
.page-landing a:focus-visible,
.page-landing button:focus-visible,
.page-landing input:focus-visible{
  outline:3px solid var(--accent);
  outline-offset:3px;
  border-radius:4px;
}

/* Lien d'évitement : caché jusqu'à ce qu'on le focalise au clavier. */
/* ⚠️ CENTRÉ, pas à gauche : posé à gauche, il recouvrait la marque pendant la
   navigation clavier (bouton 149,6 px + anneau de focus = jusqu'à x 165,6,
   alors que le logo commence à x 141). Centré, il se pose au-dessus de la zone
   vide de la barre, entre la marque et les liens — visible, et il ne cache
   rien. */
.lien-evitement{
  position:absolute;top:10px;left:50%;transform:translateX(-50%) translateY(-200%);
  z-index:100;background:var(--accent);color:#fff;padding:11px 18px;
  border-radius:var(--rayon-ctrl);font-weight:600;font-size:.9rem;
  box-shadow:0 8px 22px -10px rgba(38,48,63,.5);
  transition:transform .12s ease-out;
}
.lien-evitement:focus{transform:translateX(-50%) translateY(0)}
@media (prefers-reduced-motion:reduce){.lien-evitement{transition:none}}

/* ===== En-tête collant ===== */
.entete-landing{position:sticky;top:0;z-index:50;background:color-mix(in srgb, var(--papier) 96%, transparent);backdrop-filter:blur(10px);border-bottom:1px solid var(--ligne)}
.entete-landing nav{display:flex;align-items:center;justify-content:space-between;height:74px;gap:20px}
/* Le logo est une image du kit (session 102) : les tracés sont vectorisés,
   on n'utilise QUE le fichier fourni, jamais un nom recomposé.
   ⚠️ Les deux remises à zéro ci-dessous ne sont pas cosmétiques :
   theme.css:33 pose sur .logo un padding 24/22/20 (destiné à la sidebar de
   l'app) qui décalait la marque de 22 px vers la droite par rapport au reste
   de la page, ET un font-family:'Fraunces' qui, si le SVG ne se charge pas,
   affiche le texte de repli « Bureau de Beaufort » composé en serif — c'est
   le PREMIER interdit du kit (« recomposer le nom avec une police
   installée »). Le cas n'est pas théorique : Caddy renvoie la landing en 200
   pour un fichier absent, jamais un 404 franc, donc un SVG mal déployé
   produit exactement ça. */
/* min-height : le logo est un LIEN (retour en haut). Réduit au monogramme sur
   téléphone, sa surface tombait à 28,7 px de haut — sous le seuil où un doigt
   le vise sans toucher le voisin. La barre en fait 74 : on prend la place qui
   existe déjà, rien ne bouge à l'écran. */
/* ☢️ `flex-shrink:0` — LA MARQUE NE SE COMPRIME JAMAIS.
   Régression introduite le 14/08 par l'ajout du bouton de menu : la barre est un
   flex, le bouton y prend 44 px de plus, et le logo était le seul élément à
   pouvoir céder (les deux boutons portent `white-space:nowrap`). Il ne
   rétrécissait pas un peu — il s'effondrait, exactement sur les téléphones les
   plus répandus. Mesuré, balayage de 10 en 10 px :
       370 px : logo à 0 px    (la marque DISPARAÎT de l'en-tête)
       375 px : 34 -> 5 x 5 px (un point)
       390 px : 34 -> 20 x 17
       400 px : 34 -> 30       410 px et au-delà : intact
   Trouvé par le gate `controle`. Ni mon banc ni mes captures ne l'ont vu : le
   banc ne regardait pas le logo, et je l'avais pourtant à l'écran.
   Le kit interdit de rétrécir la marque sous son minimum — un monogramme de
   5 px n'est plus une marque, c'est une bavure. La place se reprend sur le
   libellé du bouton (voir le palier 480 px), jamais sur elle. */
.entete-landing .logo{display:flex;align-items:center;padding:0;font-family:inherit;font-size:0;min-height:44px;flex-shrink:0}
.entete-landing .logo img{display:block;height:auto;width:180px}   /* minimum EXACT du kit */
.entete-landing .nav-liens{display:flex;gap:22px;align-items:center;font-size:.92rem;font-weight:500}
/* ⚠️ `>` ET PAS UN SÉLECTEUR DESCENDANT — mesuré, pas théorique. Le menu de
   navigation (<details>, ci-dessous) est un ENFANT de .nav-liens, et son
   panneau contient les mêmes ancres. Avec `.nav-liens a:not(.btn)`, la règle
   de masquage du palier 1080 px les atteignait AUSSI : le bouton s'ouvrait
   sur un panneau vide de 14 px de haut, ses 6 liens en display:none. Aucune
   erreur, aucun débordement — juste un menu qui ne servait à rien.
   `>` dit ce qu'on veut vraiment dire : les liens POSÉS DANS LA BARRE. */
.entete-landing .nav-liens > a:not(.btn){color:var(--encre-doux);transition:.2s}
.entete-landing .nav-liens > a:not(.btn):hover{color:var(--encre)}
.entete-landing .btn{white-space:nowrap}
.etiq-courte{display:none}

/* ===== MENU DE NAVIGATION (sous 1081 px) ====================================
   Il n'existe QUE là où les liens d'ancre de la barre sont masqués — la règle
   qui le montre est dans le palier `max-width:1080px`, exactement le même
   seuil, pour qu'il ne puisse jamais y avoir de fenêtre sans navigation.

   Bâti sur <details>/<summary> : le panneau s'ouvre sans JavaScript, et
   `aria-expanded` est tenu par le navigateur. Rien à synchroniser à la main.

   ⚠️ `list-style:none` ET `::-webkit-details-marker` : sans les deux, le
   triangle natif du <summary> reste affiché à côté de l'icône (WebKit ignore
   le premier, Firefox/Chrome ignorent le second). */
/* `flex-shrink:0` : le bouton garde ses 44 px de cible tactile même dans une
   barre serrée — sans quoi on déplacerait simplement le problème du logo ici. */
.menu-nav{display:none;position:relative;flex-shrink:0}
.menu-bouton{
  display:flex;align-items:center;justify-content:center;
  width:44px;height:44px;                    /* cible tactile pleine (repère Apple) */
  border:1px solid var(--ligne);border-radius:var(--rayon-ctrl);
  color:var(--encre);background:var(--blanc-carte);
  cursor:pointer;list-style:none;-webkit-tap-highlight-color:transparent;
}
.menu-bouton::-webkit-details-marker{display:none}
.menu-bouton::marker{content:""}
.menu-nav[open] .menu-bouton{background:var(--accent-voile);border-color:var(--accent)}

/* Le panneau est ancré à DROITE du bouton et s'étend vers la gauche : posé à
   gauche, il sortirait de l'écran sur un téléphone étroit et ferait glisser
   la page. `min-width` plutôt qu'une largeur fixe pour que le plus long
   libellé (« Comment ça marche ») ne se replie pas. */
.menu-panneau{
  position:absolute;top:calc(100% + 10px);right:0;z-index:60;
  min-width:210px;max-width:min(78vw,280px);
  display:flex;flex-direction:column;
  background:var(--blanc-carte);border:1px solid var(--ligne);
  border-radius:var(--rayon);padding:6px;
  box-shadow:0 18px 40px -14px rgba(38,48,63,.34),0 2px 8px rgba(38,48,63,.10);
  /* Téléphone COUCHÉ : 320 px de haut pour une barre de 74 — sans ce plafond,
     les six entrées passaient sous le bas de l'écran, sans moyen d'y accéder. */
  max-height:calc(100vh - 92px);overflow-y:auto;overscroll-behavior:contain;
}
.menu-panneau a{
  display:flex;align-items:center;min-height:44px;   /* cible tactile */
  padding:6px 12px;border-radius:var(--rayon-ctrl);
  color:var(--encre);font-size:.95rem;font-weight:500;
}
.menu-panneau a:hover{background:var(--accent-voile);color:var(--accent-fonce)}
/* Le repère « où suis-je » : sur une page de ~10 écrans, la section lue est
   la seule information que le défilement ne donne pas. Posé par landing.js
   (IntersectionObserver) ; sans JS, aucun lien n'est marqué et le menu reste
   parfaitement utilisable. */
.menu-panneau a[aria-current]{background:var(--accent-voile);color:var(--accent-fonce);font-weight:600}
.menu-connexion{border-top:1px solid var(--ligne);margin-top:4px;padding-top:10px;border-radius:0}
/* Même repère dans la barre du grand écran, où les liens sont visibles.
   ⚠️ `>` : en sélecteur descendant, cette règle (0,4,1) l'emportait sur
   `.menu-panneau a[aria-current]` (0,2,1) et repeignait aussi le lien marqué
   DU PANNEAU — qui sortait en bleu d'accent au lieu de l'accent foncé prévu.
   Le commentaire disait « dans la barre », le sélecteur faisait plus. */
.entete-landing .nav-liens > a:not(.btn)[aria-current]{color:var(--accent);font-weight:600}

/* ===== Héros ===== */
/* `minmax(0,1fr)` et non `1fr` sur la colonne de droite : en grille CSS, `1fr`
   vaut `minmax(auto,1fr)` — une piste refuse donc de descendre sous la taille
   de son contenu, et un enfant trop large (une image, un tableau) fait déborder
   la PAGE au lieu de se réduire. Le zéro lève ce plancher. Filet pur : tant que
   rien ne déborde, le rendu est identique au pixel. */
.hero{padding:64px 0 84px;display:grid;grid-template-columns:1.05fr minmax(0,1fr);gap:56px;align-items:center}
/* Verrouillage vertical, version principale du kit (min. 90 px de large).
   110 px et non 170 : sur l'écran d'Hubert (1366 × 673), les 170 px
   repoussaient le premier bouton 71 px SOUS la ligne de flottaison —
   personne ne voyait l'appel à l'action sans faire défiler. */
.logo-hero{display:block;width:110px;height:auto;margin-bottom:20px}
.eyebrow{font-size:.76rem;letter-spacing:.14em;text-transform:uppercase;color:var(--accent-fonce);background:var(--accent-voile);display:inline-block;padding:5px 12px;border-radius:999px;font-weight:600;margin-bottom:18px;white-space:nowrap}
.hero h1{font-size:clamp(2.2rem,4.2vw,3.5rem);line-height:1.08;font-weight:600;margin-bottom:18px}
.hero h1 span{color:var(--accent)}
.hero .sous-texte-hero{color:var(--encre-doux);font-size:1.04rem;max-width:46ch;margin-bottom:28px}
.hero-actions{display:flex;gap:14px;align-items:center;flex-wrap:wrap}
.mention{font-size:.82rem;color:var(--encre-doux);margin-top:20px}

/* Écran bas (le portable d'Hubert fait 673 px de haut) : on resserre pour que
   les boutons restent au-dessus de la ligne de flottaison. */
@media (max-height:760px) and (min-width:881px){
  .hero{padding:36px 0 56px;gap:44px}
  /* ⚠️ 90 px et pas moins : c'est le minimum EXACT du verrouillage vertical
     (identite/LISEZ-MOI.md). Il était descendu à 84 px pour gagner de la place
     sur l'écran d'Hubert — sous le minimum du kit, le nom sous la marque
     devient une bavure illisible. On reprend les pixels sur les marges, pas
     sur la marque : le kit interdit de rétrécir, pas de resserrer autour. */
  .logo-hero{width:90px;margin-bottom:12px}
  .eyebrow{margin-bottom:14px}
  .hero h1{margin-bottom:14px}
  .hero .sous-texte-hero{margin-bottom:20px}
  .mention{margin-top:14px}
}

/* ===== Scène héros : carte + enveloppe, en ÉCRITURE RÉELLE =====
   Les deux images sont les tracés du moteur de police vivante (SVG de
   chemins, aucun <text>) : ce que le visiteur voit est ce que la machine
   trace. L'encre des SVG est en currentColor -> elle suit le jeton. */
/* La scène est en FLUX (colonne), pas en positionnement absolu : c'est ce qui
   garantit que l'enveloppe ne peut PAS recouvrir l'écriture, à n'importe
   quelle largeur. Le seul chevauchement est un retrait négatif de 38 px, qui
   ne mord que sur la marge basse vide de la carte. En absolu, le recouvrement
   variait avec la largeur (47 px de la signature mangés à 1366 px) et il
   fallait le re-régler à chaque palier. */
.scene{display:flex;flex-direction:column}
.carte{position:relative;background:var(--blanc-carte);border:1px solid var(--ligne);box-shadow:0 30px 60px -24px rgba(38,48,63,.4),0 2px 8px rgba(38,48,63,.08);padding:26px 28px 34px;aspect-ratio:148/105;border-radius:12px;transform:rotate(-1.1deg);color:var(--encre)}
.carte-ecriture{height:100%;display:flex;align-items:flex-start}
.carte-ecriture img{display:block;width:100%;height:auto}
/* Le monogramme du kit remplace l'ancien cachet de cire : la cire promettait
   un produit que le catalogue ne vend pas (aucune option « sceau »). */
.monogramme-carte{position:absolute;top:-13px;left:-13px;width:52px;height:auto;opacity:.9}
/* ⚠️ Le retrait négatif est CONTRAINT, pas décoratif : l'enveloppe doit rester
   sous le bas du bloc d'écriture, jamais devant. La mesure tranche, pas l'œil :
   .enveloppe ne doit avoir AUCUNE intersection avec .carte-ecriture img.
   ⚠️ Le contrôle annoncé ici n'existait dans AUCUN banc du dépôt (vérifié le
   10/08/2026) — la contrainte était donc écrite, jamais vérifiée.

   -5.5% et non -38px (10/08/2026) : la hauteur de l'écriture est PROPORTIONNELLE
   à la largeur de la scène (l'image est en width:100%, rapport figé), alors que
   -38px était fixe. La mise en page de lettre du 10/08 a rendu le bloc plus haut
   (rapport 1,650 -> 1,542, soit +24 px à 1366) et l'enveloppe est passée DEVANT
   l'écriture de 5,2 px. Un retrait fixe se serait dégradé encore en s'élargissant :
   mesuré 5,2 px à 1366 et 5,5 px à 1500, l'écart suit la largeur. En pourcentage,
   le retrait suit la même échelle que ce qu'il doit éviter.
   (Un % de margin-top se calcule sur la LARGEUR du conteneur — c'est justement
   la grandeur dont dépend la hauteur de l'image.) */
.enveloppe{align-self:flex-end;width:46%;margin:-5.5% -8px 0 0;background:var(--papier-2);border:1px solid var(--ligne);aspect-ratio:220/110;border-radius:10px;transform:rotate(2.2deg);box-shadow:0 18px 40px -18px rgba(38,48,63,.32);display:flex;align-items:center;justify-content:center;padding:10px 14px;color:var(--encre)}
.enveloppe img{display:block;width:78%;max-width:190px;height:auto}

/* ⚠️ L'animation « la plume écrit » et la couleur d'encre des spécimens ne
   sont PAS ici : un SVG chargé par <img> est un document isolé, le CSS de la
   page ne le traverse pas et `currentColor` n'y hérite de rien. Les deux
   vivent donc DANS les fichiers .svg, posés par
   web/outils/generer_specimens.py. Elles respectent prefers-reduced-motion,
   ne tournent qu'une fois, et ne coûtent aucune ligne de JavaScript. */

/* ===== Sections génériques (titres, filet, sous-titre) ===== */
section{padding:80px 0}
.titre-section{font-size:clamp(1.7rem,3vw,2.4rem);font-weight:600;margin-bottom:14px}
.sous-titre{color:var(--encre-doux);max-width:60ch;margin-bottom:40px}
.sous-titre.marge-basse{margin-bottom:22px}
.filet{width:44px;height:3px;background:var(--accent);border-radius:999px;margin-bottom:24px}
.accent-italique{font-style:italic;color:var(--accent)}

/* ===== Comment ça marche (3 étapes) ===== */
.etapes{--carte-min:240px;gap:40px}
.etape .num{font-family:'Fraunces',serif;font-size:2.4rem;color:var(--accent);line-height:1;margin-bottom:12px;font-weight:600}
.etape h3{font-size:1.14rem;margin-bottom:10px;font-weight:600}
.etape p{color:var(--encre-doux);font-size:.94rem}
/* ⚠️ padding HORIZONTAL nul, volontairement : avec 5 px, la virgule qui suit
   « {{prenom}} » était repoussée hors de la puce et se lisait « {{prenom}} , »
   — une espace avant la virgule, interdite en français — et la ligne suivante
   partait 5 px en retrait du paragraphe. Le fond seul suffit à distinguer. */
.etape p b.var{color:var(--accent-fonce);font-weight:600;font-size:.92em;background:var(--accent-voile);border-radius:4px;padding:1px 0;box-shadow:0 0 0 3px var(--accent-voile)}

/* ===== L'écriture (spécimen réel) ===== */
.signature-bloc{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:56px;align-items:center}
.echantillons{display:flex;flex-direction:column;gap:16px}
.echantillon{background:var(--blanc-carte);border:1px solid var(--ligne);padding:22px 26px 16px;border-radius:14px;box-shadow:var(--ombre);margin:0;color:var(--encre)}
.echantillon .txt img{display:block;width:100%;height:auto}
/* .75rem = 12 px, le plancher de lisibilité : à .72rem cette légende était
   mesurée à 11,5 px sur TOUS les écrans, téléphone compris. */
.echantillon .lib{font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;color:var(--encre-doux);margin-top:10px}
.preuve-ecriture{background:var(--accent-voile);border-radius:14px;padding:18px 22px;font-size:.9rem;color:var(--accent-fonce)}
.preuve-ecriture b{font-weight:600}

/* ===== Tarifs (fond sombre --encre) =====
   Sobre par décision d'Hubert : un « à partir de » par format, pas de grille
   de prestations. Les montants viennent du BACKEND (plancher_cents calculé
   par api/app/catalogue.py) — aucun prix n'est écrit ici, la landing ne
   devient pas une source de prix de plus (D-083). */
.tarifs{background:var(--encre);color:#fff}
.tarifs .titre-section{color:#fff}
/* .78 et non .62 : à .62 le texte de 16 px passait tout juste, et la mention
   de 12 px sous la grille tombait sous le seuil de 4,5:1. */
.tarifs .sous-titre{color:rgba(255,255,255,.78)}
/* 210 px : c'est la valeur qui fait tenir les TROIS formats côte à côte sur une
   tablette en portrait (768 px), au lieu de deux plus un orphelin étiré. */
.grille-tarifs{--carte-min:210px;gap:22px}
.bloc-tarif{border:1px solid rgba(255,255,255,.26);border-radius:16px;padding:26px 24px}
.bloc-tarif .dim{font-size:.76rem;letter-spacing:.1em;text-transform:uppercase;color:var(--dore);margin-bottom:8px}
.bloc-tarif h3{font-size:1.24rem;margin-bottom:14px;font-weight:600;color:#fff}
.bloc-tarif .a-partir{font-size:.78rem;letter-spacing:.04em;text-transform:uppercase;color:rgba(255,255,255,.72);display:block;margin-bottom:2px}
.bloc-tarif .montant{font-family:'Fraunces',serif;font-size:2rem;font-weight:600;line-height:1.1}
.bloc-tarif .par{font-size:.84rem;color:rgba(255,255,255,.72);margin-top:4px}
.note-tarifs{margin-top:28px;font-size:.86rem;color:rgba(255,255,255,.78)}

/* ===== Demander un accès ===== */
.acces{padding-top:88px}
.bloc-acces{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:56px;align-items:center}
.carte-formulaire{background:var(--blanc-carte);border:1px solid var(--ligne);border-radius:var(--rayon);padding:28px 30px 24px;box-shadow:var(--ombre)}
#form-acces{display:flex;flex-direction:column;gap:14px}
#form-acces .champ{margin:0}
#form-acces .lib{display:block;margin-bottom:8px;font-size:.86rem;font-weight:500}
/* theme.css:113 habille input[type=text|number|search], select et textarea —
   mais PAS input[type=email] ni input[type=tel]. C'est exactement le défaut qui
   rendait les champs de l'écran de connexion natifs (Arial, 173 × 19 px, coins
   carrés). theme.css est NO-TOUCH : on redéclare ici, à l'identique, avec les
   mêmes jetons. La correction propre est une ligne dans theme.css, à faire dans
   une session dédiée au thème.
   Les 4 types sont listés ENSEMBLE : le formulaire enrichi (prénom, nom,
   téléphone, message) mélange text, email, tel et textarea, et rien ne serait
   plus visible qu'un seul champ habillé autrement au milieu des autres. */
#form-acces input[type=email],
#form-acces input[type=text],
#form-acces input[type=tel],
#form-acces textarea{
  width:100%;background:var(--blanc-carte);border:1px solid var(--ligne);
  border-radius:var(--rayon-ctrl);padding:11px 13px;
  font-family:'Inter',sans-serif;font-size:.92rem;color:var(--encre);
}
#form-acces input[type=email]:focus,
#form-acces input[type=text]:focus,
#form-acces input[type=tel]:focus,
#form-acces textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-voile)}
#form-acces input[aria-invalid="true"],
#form-acces textarea[aria-invalid="true"]{border-color:var(--cire)}
/* Le message : redimensionnable en HAUTEUR seulement — une poignée libre
   laisserait le visiteur élargir le champ hors de la carte. */
#form-acces textarea{resize:vertical;min-height:74px;line-height:1.5}
/* Prénom + nom sur une ligne, empilés dès que la carte devient étroite. */
.duo-champs{display:grid;grid-template-columns:1fr 1fr;gap:14px}
/* « facultatif » : discret, à côté du libellé — le visiteur doit voir d'un coup
   d'œil les 2 champs qu'il peut sauter, sinon les deux ajouts font fuir. */
.facultatif{font-weight:400;font-size:.76rem;color:var(--encre-doux);
  text-transform:lowercase;letter-spacing:.02em}
.facultatif::before{content:"· "}
.aide-champ{margin:6px 0 0;font-size:.76rem;color:var(--encre-doux);line-height:1.45}
.btn-acces{width:100%;justify-content:center;margin-top:2px}
/* Deux états distincts : « en cours d'envoi » (le JS vient de le désactiver) et
   « JavaScript absent » (le bouton n'a jamais été armé). Sans cette distinction,
   une page sans JS affichait un bouton en pleine couleur d'accent, identique à
   l'état fonctionnel : il faisait SEMBLANT de marcher. */
.btn-acces[disabled]{opacity:.6;cursor:progress}
.btn-acces[data-arme="non"]{background:var(--papier-2);color:var(--encre-doux);cursor:not-allowed;opacity:1}
.message-acces{font-size:.88rem;border-radius:var(--rayon-ctrl);padding:10px 14px;margin:0}
.message-acces.ok{background:#E7F1EA;color:var(--vert)}
.message-acces.ko{background:#F7E4E1;color:var(--cire)}
.mention-rgpd{font-size:.78rem;color:var(--encre-doux);margin:0;line-height:1.5}
.mention-rgpd a{color:var(--accent-fonce);font-weight:600;text-decoration:underline}
.acces-alternatives{margin-top:18px;font-size:.86rem;color:var(--encre-doux);text-align:center}
.acces-alternatives a{color:var(--accent-fonce);font-weight:600;text-decoration:underline}

/* Piège à robots : invisible et hors du parcours clavier, sans display:none
   (certains lecteurs d'écran annoncent quand même un champ display:none
   masqué par un aria-hidden mal placé — ici le champ est sorti du flux).

   ⚠️ IL ÉTAIT MASQUÉ PAR `left:-9999px`, ET CE MOTIF EST BANNI DE CE FICHIER
   (24/08/2026). Pas parce qu'il débordait — mesuré, il ne débordait pas : un
   contenu poussé à GAUCHE ne rallonge jamais la barre de défilement. Mais
   c'est exactement la technique qui, appliquée 100 lignes plus haut à l'en-tête
   d'un tableau passé en display:block, élargissait la page de 195 px (voir
   `.doc-table thead`). Le même geste est inoffensif ici et destructeur là-bas,
   pour une raison — la position dans le flux — qu'on ne voit pas en lisant la
   règle. On garde donc UNE seule technique de masquage dans tout le fichier :
   le masquage par DÉCOUPE, qui ne déplace pas l'élément — il reste à sa place
   et n'y occupe qu'un pixel. ⚠️ Il n'est pas « sans effet » dans l'absolu : il
   impose `position:absolute`, donc il RETIRE l'élément du flux. Ici c'est
   vérifié sans conséquence (les 8 enfants de `#form-acces` ont exactement les
   mêmes rectangles avant et après) ; ailleurs, il faudra le revérifier.
   Ce que ça ne change pas, et qui est le but du champ : il reste invisible à
   l'œil, hors du parcours clavier (tabindex=-1 dans index.html), et un robot
   qui lit le HTML le remplit toujours.
   Effet mesurable : une sonde de débordement écrite naïvement — `left < -1` —
   rendait 3 éléments sur cette page (le champ, son étiquette, son conteneur).
   Elle en rend 0. banc_landing_mobile.py interdit désormais le motif. */
.pot-de-miel{position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}


/* ===== Preuve chiffree (Note de synthese d'Hubert) =====
   Les chiffres viennent tous de sa note, avec leurs sources. C'est le manque
   le plus criant releve par l'audit : la page n'avancait AUCUNE preuve. */
.preuve{background:var(--papier-2)}
/* 380 px et non 280 : au-dessus du tiers de la colonne (1084 px), ce qui PLAFONNE
   la grille à 2 colonnes sur grand écran — la mise en page validée — tout en la
   laissant descendre à 1 colonne toute seule sous 800 px. */
.grille-preuve{--carte-min:380px;gap:26px 40px}
/* ⚠️ `flex-wrap` + une base de 220 px sur le texte : sans ça, la ligne « 9 € pour
   1 € » écrasait sa propre explication. Son chiffre est le plus long des quatre
   (~150 px contre ~60 pour « 96 % ») et il est insécable : à 390 px il ne
   restait que 187 px de texte, contre 260 à 294 px pour les trois autres — la
   section qui porte l'argument commercial avait l'air de travers, et
   précisément sur les iPhone les plus répandus (375 à 430 px).
   Maintenant le texte passe SOUS son chiffre dès qu'il ne peut plus tenir
   220 px. Aucun palier à régler : c'est la longueur réelle du chiffre qui
   décide, donc un chiffre ajouté demain se placera tout seul. */
.chiffre{display:flex;flex-wrap:wrap;gap:18px;align-items:baseline;border-top:1px solid var(--ligne);padding-top:18px}
.chiffre>span{flex:1 1 220px}
.chiffre>b{font-family:'Fraunces',serif;font-size:clamp(1.7rem,3vw,2.3rem);font-weight:600;color:var(--accent);line-height:1;white-space:nowrap}
.chiffre>span{color:var(--encre-doux);font-size:.94rem}
.chiffre .contre{color:var(--encre);font-weight:600;font-family:inherit;font-size:1em}
/* Les appels de note ¹ ² ³ ⁴. Ils mesuraient 6 × 11 px : au doigt, on ne les
   vise pas — on tape à côté. On NE grossit PAS le chiffre (il doit rester
   discret dans la phrase) : on élargit sa zone de contact avec un rectangle
   transparent posé par-dessus, qui ne se voit pas et ne déplace rien.
   Le retrait vertical reste modeste (12 px) pour ne pas recouvrir la ligne de
   texte du dessus, qui porte d'autres liens. */
.chiffre sup a{color:var(--encre-doux);text-decoration:none;font-size:.72em;padding:0 1px;position:relative}
/* -11 px et non -8 : le chiffre « 1 » est plus étroit que les autres, sa zone
   tombait à 22 px quand les autres atteignaient 24. On cale sur le plus étroit,
   pas sur la moyenne. */
.chiffre sup a::after{content:"";position:absolute;top:-12px;right:-11px;bottom:-12px;left:-11px}
.chiffre sup a:hover{color:var(--accent)}
.preuve-note{margin-top:32px;font-size:1.02rem;color:var(--encre);max-width:62ch}
.sources{margin-top:18px;font-size:.78rem;color:var(--encre-doux);line-height:1.7;max-width:none;scroll-margin-top:110px}
.sources b{color:var(--encre)}

/* ===== Secteurs (les 4 notes sectorielles) ===== */
/* Même plafond à 2 colonnes que la grille de preuve (4 cartes : sans ce minimum,
   auto-fit en aligne 3 sur grand écran et change la mise en page validée). */
.grille-secteurs{--carte-min:380px;gap:22px}
.secteur{background:var(--blanc-carte);border:1px solid var(--ligne);border-radius:var(--rayon);padding:26px 28px;box-shadow:var(--ombre)}
.secteur h3{font-size:1.14rem;font-weight:600;margin-bottom:10px}
.secteur p{color:var(--encre-doux);font-size:.94rem}
.secteur .moments{margin-top:12px;font-size:.8rem;color:var(--accent-fonce);border-top:1px solid var(--ligne);padding-top:12px}
.secteurs-note{margin-top:26px;font-size:.86rem;color:var(--encre-doux)}

/* ===== Pied de page ===== */
footer{border-top:1px solid var(--ligne);padding:34px 0;font-size:.84rem;color:var(--encre-doux)}
/* Verrouillage -reserve : le bloc encre est DANS le fichier, donc pas de fond
   ni de padding ici — on lui donne seulement de l'air autour (rien ne doit
   entrer dans sa zone de protection). Pas de border-radius : arrondir les
   angles reviendrait à modifier le logo. */
.logo-pied{display:block;width:120px;height:auto;margin:0 0 26px}
.pied-footer{display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px}
.pied-liens{display:flex;gap:20px;flex-wrap:wrap}
.pied-liens a{text-decoration:underline;text-underline-offset:3px}
.pied-liens a:hover{color:var(--encre)}

/* ===== Pages de texte (confidentialité, et les suivantes) ===== */
.doc{max-width:760px;padding-top:56px;padding-bottom:72px}
.doc h1{font-size:clamp(1.9rem,3.4vw,2.6rem);font-weight:600;margin-bottom:8px}
.doc h2{font-size:1.22rem;font-weight:600;margin:38px 0 12px}
.doc p{margin-bottom:14px;color:var(--encre-doux)}
.doc p b,.doc li b{color:var(--encre);font-weight:600}
.doc a{color:var(--accent-fonce);font-weight:600;text-decoration:underline;text-underline-offset:3px}
.doc-date{font-size:.84rem;color:var(--encre-doux);margin-bottom:26px}
.doc-chapeau{font-size:1.04rem;color:var(--encre);background:var(--accent-voile);border-radius:var(--rayon);padding:18px 22px}
.doc-liste{margin:0 0 14px 20px;color:var(--encre-doux)}
.doc-liste li{margin-bottom:9px}
.doc-note{font-size:.88rem;background:var(--papier-2);border-radius:var(--rayon-ctrl);padding:12px 16px}
/* ⚠️ Surtout PAS de defilement horizontal ici : avec `display:block;
   overflow-x:auto`, seules 2 colonnes sur 4 etaient visibles (35 % du contenu a
   1366 px, 17 % a 390 px) — et les deux qui manquaient etaient la BASE LEGALE et
   la DUREE DE CONSERVATION, c'est-a-dire les mentions obligatoires. Un tableau
   qui cache la moitie de ce qu'il doit dire ne vaut rien.
   Ici : tableau normal jusqu'a 720 px, puis REPLI en blocs etiquetes (l'etiquette
   vient de data-lib sur chaque cellule) — tout reste lisible, sans glisser. */
/* ⚠️ `white-space:normal` n'est pas décoratif : theme.css:176 pose
   `white-space:nowrap` sur TOUS les <table> (c'est voulu pour les tableaux de
   données de l'atelier, où une ligne ne doit pas se replier). Une table de
   PROSE en héritait : le texte refusait d'aller à la ligne, la cellule faisait
   562 px de contenu dans 344 px de boîte, et la page débordait de 195 px à
   390 px. theme.css est NO-TOUCH -> on neutralise ici, pour cette table seule. */
.doc-table{width:100%;border-collapse:collapse;margin-bottom:16px;font-size:.88rem;table-layout:fixed;white-space:normal}
.doc-table th,.doc-table td{white-space:normal}
.doc-table th,.doc-table td{text-align:left;vertical-align:top;padding:11px 12px;border-bottom:1px solid var(--ligne);overflow-wrap:anywhere}
.doc-table th{font-size:.75rem;letter-spacing:.06em;text-transform:uppercase;color:var(--encre-doux);font-weight:600}
.doc-table td{color:var(--encre-doux)}
@media (max-width:720px){
  .doc-table,.doc-table tbody,.doc-table tr,.doc-table td{display:block;width:100%}
  /* ⚠️ Masquer la ligne d'en-tête par `left:-9999px` élargissait la PAGE de
     195 px à 390 px (mesuré) : dans un tableau passé en display:block, le
     déplacement est compté dans la largeur du document. On utilise le masquage
     par découpe : l'élément reste à sa place, occupe 1 px, et demeure lisible
     par un lecteur d'écran. */
  .doc-table thead{position:absolute;width:1px;height:1px;overflow:hidden;
    clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
  .doc-table tr{border:1px solid var(--ligne);border-radius:var(--rayon-ctrl);padding:6px 4px;margin-bottom:12px;background:var(--blanc-carte)}
  .doc-table td{border:none;padding:8px 12px}
  /* .75rem : à .68rem cette étiquette faisait 10,9 px — c'est elle qui porte
     « base légale » et « durée de conservation », les mentions obligatoires,
     sur la seule mise en page que voit un téléphone.
     ⚠️ Le banc ne l'avait PAS signalée : sa sonde parcourt les éléments réels,
     pas les pseudo-éléments ::before / ::after. Limite connue, écrite ici pour
     qu'on ne prenne pas son silence pour une preuve. */
  .doc-table td::before{
    content:attr(data-lib);display:block;margin-bottom:3px;
    font-size:.75rem;letter-spacing:.08em;text-transform:uppercase;
    color:var(--encre-doux);font-weight:600;
  }
}

.avis-sans-js{background:var(--accent-voile);color:var(--accent-fonce);border-radius:var(--rayon);padding:16px 20px;margin:0 auto 28px;font-size:.9rem}
.avis-sans-js a{text-decoration:underline;font-weight:600}

/* ===== Responsive =========================================================
   ⚠️ ORDRE : du plus large au plus ÉTROIT, et jamais l'inverse. Ces blocs ont
   tous la même spécificité — à égalité, c'est le DERNIER déclaré qui gagne. Un
   palier étroit écrit au-dessus d'un palier plus large est donc écrasé par lui
   sur les écrans où il devait justement s'appliquer.
   Ce n'était pas théorique : le bloc « 360 px » était déclaré AVANT celui de
   « 430 px », donc mort. Mesuré à 320 px avant correction — la page appliquait
   28 px de titre au lieu des 25,6 px voulus et 18 px de marge au lieu de 14, et
   le commentaire du code affirmait le contraire. Les deux blocs ont fusionné
   ci-dessous : il n'en reste qu'un, il ne peut plus être contredit. */

/* Palier intermédiaire : entre 881 et 1080 px, 5 éléments de navigation ne
   tiennent plus à côté d'un logo de 180 px — on retire les liens d'ancre et
   on garde les deux actions, qui sont le but de la page. */
@media (max-width:1080px){
  /* `>` : ne masque QUE les liens posés dans la barre, pas ceux du panneau du
     menu, qui est un enfant de .nav-liens (voir l'avertissement plus haut). */
  .entete-landing .nav-liens > a:not(.btn){display:none}
  /* ⚠️ MÊME SEUIL, dans le MÊME bloc, et volontairement : la ligne au-dessus
     retire les 4 liens d'ancre, celle-ci fait apparaître le menu qui les
     porte. Séparées dans deux media queries, une modification de l'une
     laisserait une plage de largeurs SANS aucune navigation — c'est
     exactement l'état mesuré avant ce correctif (0 lien sur 4, de 320 à
     1080 px), et il n'avait rien de visible : la page ne débordait pas, ne
     déclenchait aucune erreur, elle était juste sans issue. */
  .menu-nav{display:block}
  /* ⚠️ Il y avait ici une règle `:has(.menu-nav[open]){z-index:60}`, posée par
     précaution contre un recouvrement du panneau par la carte du hero. Elle a
     été RETIRÉE : le gate `controle` a mesuré qu'avec ou sans elle,
     `elementFromPoint` rend le panneau en tous les points testés — elle
     n'avait aucun effet, et son commentaire décrivait un débordement que
     personne n'a jamais reproduit. Une règle inerte dont le commentaire
     affirme un danger est pire qu'une règle absente : elle se transmet.
     L'en-tête (z-index:50) et le panneau (z-index:60) suffisent. */
  .hero{gap:40px}
}
@media (max-width:880px){
  /* Les grilles de CARTES ne sont plus ici : elles se replient seules
     (voir « GRILLES DE CARTES » en tête de fichier). Ne restent que les
     blocs texte + visuel, dont le repli est un choix de mise en page. */
  .hero,.signature-bloc,.bloc-acces{grid-template-columns:1fr}
  .hero{padding-top:44px;gap:76px}
  /* Le verrouillage horizontal ne descend PAS sous 180 px (minimum du kit) :
     sous 881 px, <picture> a déjà servi le MONOGRAMME (voir index.html), on
     lui donne juste sa taille. */
  .entete-landing .logo img{width:34px}
  .entete-landing .nav-liens{gap:12px}
  .logo-hero{width:96px;margin-bottom:18px}

  /* ===== BLANCS DE SECTION SUR TÉLÉPHONE : la MOITIÉ du grand écran ========
     80 px en haut de fichier, donc 40 ici. C'était 60 — une réduction, mais
     pas une moitié.
     ⚠️ CE N'EST PAS LA VRAIE CAUSE DE LA LONGUEUR, et il faut le dire pour que
     personne ne revienne gratter ici : la page mesurait 8 205 px à 390 px
     AVANT ce bloc, et il en rend 268 — soit 3,3 %. Le reste, ce sont SEPT
     sections de contenu.
     Ce qui règle « dix écrans sans repère », c'est le menu de navigation
     (palier 1080 px ci-dessus), pas le rabotage des blancs. Descendre plus bas
     que 40 px collerait les sections les unes aux autres sans rien gagner de
     mesurable. */
  section{padding:40px 0}
  /* `.acces` (0,1,0) l'emporte sur `section` (0,0,1) : sans cette ligne, la
     règle ci-dessus ne l'atteint PAS et la section garde ses 88 px de base —
     mesuré à 390 px avant correction. Une modification faite en oubliant la
     spécificité aurait été vraie partout sauf sur la dernière section, celle
     qui porte le formulaire. */
  .acces{padding-top:40px}
  /* En colonne étroite l'enveloppe se centre et ne chevauche plus du tout. */
  /* ===== PAS DE ROTATION SUR TÉLÉPHONE — C'EST ELLE QUI REND L'ÉCRITURE FLOUE
     (24/08/2026). Sa remarque, et elle était juste : « c'est un svg, y a pas de
     pixel normalement ». Exact — le fichier n'en a pas. Ils naissent de la
     ROTATION : un `transform` force le navigateur à peindre la carte dans une
     image, puis à tourner cette image. L'écriture n'est plus tracée, elle est
     RÉÉCHANTILLONNÉE, et à la taille d'un téléphone ça se voit.
     MESURÉ sur la page, à 390 px, à la densité d'un vrai iPhone — part du trait
     peint FRANC (le reste est de l'encre diluée, donc grise) :
         carte      pivotée 0,593  ->  droite 0,746   (+26 %)
         enveloppe  pivotée 0,637  ->  droite 0,761   (+19 %)
         le mot du bas, qui n'est PAS pivoté : 0,730 dans les deux cas
     Ce dernier chiffre est la contre-épreuve : l'élément non pivoté ne bouge
     pas. Et c'est pourquoi « sur l'ordinateur c'est net » — à 448 px de large
     au lieu de 211, la même rotation coûte beaucoup moins.
     ⚠️ On ne touche PAS au grand écran : le léger travers du cachet posé à la
     main y reste, il ne coûte rien à cette taille. Il ne disparaît que là où il
     se paie en lisibilité. */
  .carte{transform:none}
  .enveloppe{align-self:center;width:74%;margin:22px 0 0;transform:none}

  /* La scène est BRIDÉE sur téléphone. Sur grand écran la carte occupe sa
     colonne, soit un peu moins de la moitié de la page ; empilée sur un
     téléphone elle prenait 93 % de la largeur et 31 % de la hauteur d'écran —
     elle n'illustrait plus le propos, elle l'écrasait. Constat d'Hubert sur son
     iPhone, capture à l'appui : « je pense que la carte est trop grosse encore,
     faudrait la rétrécir ».
     On bride la SCÈNE et non la carte seule : l'enveloppe est dimensionnée en
     pourcentage de la scène, donc elle suit et le couple garde ses proportions. */
  /* ⚠️ 82 % -> 70 % le 24/08/2026, 2e demande d'Hubert sur cette carte
     (« la lettre déborde toujours, il faut que tu la réduise un peu encore,
     elle est trop large je pense »). Mesuré avant : la carte occupait 76,3 %
     de la largeur de l'écran à 390 px ; après : 65 %.
     ⚠️ ET LE PIÈGE, écrit ici parce qu'il n'est pas devinable : RÉTRÉCIR LA
     CARTE AMINCIT LE TRAIT DE L'ÉCRITURE. Le dessin est un SVG mis à
     l'échelle — sa largeur rendue divise l'épaisseur du trait. Sous 1 px, le
     navigateur ne peint plus un trait plein, il le DILUE : c'est exactement
     le « elle est floue » qu'il signale dans le même message. On compense
     donc en reprenant la place sur le REMBOURRAGE de la carte (ci-dessous)
     plutôt que sur le dessin. Le vrai remède au flou est le plancher
     d'épaisseur du trait, qui vit dans le générateur des specimens — pas
     ici. Ne pas descendre sous 70 % sans mesurer ce que devient le trait. */
  /* ⚠️ 70 % -> 92 %, ET C'EST UN RETOUR EN ARRIÈRE ASSUMÉ (24/08/2026, fin de
     journée). Il avait demandé de rétrécir la carte parce qu'elle « collait le
     bord droit » — c'était en réalité un DÉCENTRAGE, corrigé par le verrou
     ci-dessous. La largeur n'était donc pas le vrai sujet, et la rétrécir
     coûtait cher sur le seul sujet qui restait : la netteté.
     POURQUOI LA TAILLE CHANGE LA NETTETÉ — c'est le cœur de l'affaire, mesuré
     dans le fichier d'écriture lui-même. Il porte sa propre règle d'épaisseur :
         --plancher : max(0px, 1.20px - 0.3483vw)
     où `vw` vaut 1 % de la largeur À LAQUELLE L'IMAGE EST AFFICHÉE. Ce plancher
     est un CONTOUR ajouté autour de chaque trait. Donc :
         écriture à 209 px (carte à 70 %)  -> contour 0,47 px
         écriture à 295 px (carte à 92 %)  -> contour 0,17 px
         écriture à 448 px (son ordinateur) -> contour 0,00 px
     Sur son ordinateur le contour n'existe PAS : le trait est pur, et c'est
     exactement là qu'il dit « c'est parfaitement net ». Sur son téléphone le
     contour épaissit les lettres jusqu'à boucher leurs boucles — ce qui se lit
     comme du flou. Plus la carte est petite, PIRE c'est.
     À 92 % le contour tombe de 64 %. C'est le maximum atteignable depuis la
     feuille de style : le reste se règle dans le générateur des images
     (`exploitation/outils/generer_specimens.py`), qui n'appartient pas à cette
     session. Ne pas re-rétrécir cette carte sans avoir lu ce qui précède. */
  .scene{max-width:92%;margin-inline:auto;align-items:center}
  /* ⚠️ VERROU AJOUTÉ LE 24/08/2026 SUR SA CAPTURE D'IPHONE, ET IL FAUT DIRE
     POURQUOI : sur son écran, la carte sortait de la scène par la DROITE —
     bord gauche là où le calcul le prévoit, bord droit à ~2 % du bord de
     l'écran, donc une carte 25 % trop large et décentrée. Chrome ne le
     reproduit pas : mesuré, il rend 68 px de marge des deux côtés.
     La construction s'y prêtait : `.carte` est un enfant ÉTIRÉ d'une boîte
     flex, sans largeur propre, et sa hauteur vient d'un `aspect-ratio` que son
     contenu (`.carte-ecriture{height:100%}` + une image en `width:100%`)
     contraint en retour. C'est une boucle largeur -> hauteur -> contenu, et
     les navigateurs ne la dénouent pas tous pareil.
     On ne discute donc plus du mécanisme : on POSE la largeur. `width:100%`
     la fixe, `max-width:100%` interdit d'en sortir quoi qu'il arrive, et
     `align-self:center` la recentre même si un navigateur la rendait plus
     étroite. Aucun effet mesurable sur Chrome (vérifié : mêmes 68/68 px). */
  .carte{width:100%;max-width:100%;min-width:0;align-self:center}
  /* Le rembourrage est en PIXELS FIXES (26/28/34) : sur une carte rétrécie il
     mange une part croissante de la largeur, et c'est le dessin qui paie. On
     le resserre donc sur téléphone — la carte perd 15 % de large, l'écriture
     seulement 11 %.
     ⚠️ ON NE TOUCHE PAS AU HAUT (26 px), ET C'EST UNE CORRECTION : un premier
     jet resserrait aussi le haut (18 px) et la gauche à 16 px. Vu sur capture,
     pas dans le code — le MONOGRAMME, qui est ancré au coin haut-gauche de la
     carte et déborde vers l'extérieur, se retrouvait POSÉ SUR « Chère Madame
     Aubry ». Le texte remontait de 8 px et se décalait de 12 px vers lui.
     La place se prend donc sur les côtés seulement. */
  /* Rembourrage resserré à 16 px : chaque pixel repris ici part dans le dessin,
     donc dans la finesse du contour (voir le calcul ci-dessus). Le haut reste à
     26 px — sinon le monogramme, ancré au coin, se pose sur « Chère Madame ». */
  .carte{padding:26px 16px 26px}

  /* Le monogramme déborde la carte de 13 px vers la gauche. Sur grand écran il
     mord sur une marge large ; sur un téléphone la carte touche presque le bord,
     et le monogramme finissait à 1-2 px de l'écran — sur un appareil à coins
     arrondis, il a l'air de tomber dehors. On réduit le débord, on ne le
     supprime pas : c'est lui qui donne l'impression du cachet posé de travers. */
  .monogramme-carte{top:-7px;left:-6px;width:44px}

  /* 44 px : la cible que le doigt vise sans se tromper (repère Apple). Le bouton
     d'envoi mesurait 39 px de haut — c'est le geste qui conclut la demande de
     contact, il ne doit pas être le plus difficile à toucher de la page. */
  .btn-acces{min-height:44px}

}

/* ===== CHAMPS À 16 px — le zoom automatique de Safari ======================
   ⚠️ 16 px EXACTEMENT, et ce n'est pas un choix de goût : sous 16 px, Safari
   sur iPhone et iPad ZOOME la page tout seul dès qu'on touche un champ. La
   page grossit, se met à glisser latéralement, et le visiteur doit dézoomer à
   la main — au milieu du formulaire de demande de contact, c'est-à-dire le
   seul endroit de la page où on lui demande quelque chose.
   Les champs sont à .92rem, soit 14,72 px mesurés, par la règle de base.

   ⚠️ CETTE RÈGLE VIVAIT DANS LE PALIER `max-width:880px`, ET ELLE Y ÉTAIT
   TROP ÉTROITE. Mesuré, 5 champs à 14,72 px sur des appareils bien tactiles :
     932 x 430  iPhone Pro Max COUCHÉ   -> 14,72 px
    1024 x 768  iPad paysage            -> 14,72 px
   Le premier est le même téléphone que celui qu'on protégeait en portrait :
   il suffisait de le tourner pour retrouver le zoom. Un seuil de LARGEUR ne
   pouvait pas résoudre ça — un iPad Pro en paysage fait 1366 px CSS, autant
   qu'un ordinateur portable.

   D'où les deux media queries, qui ne font pas double emploi :
     - `pointer:coarse` vise ce qu'on veut vraiment dire — « on y touche avec
       un doigt » — quelle que soit la largeur. C'est elle qui couvre l'iPad
       Pro. Elle n'est PAS visible d'un banc qui se contente de redimensionner
       une fenêtre : il faut émuler la nature du pointeur (fait, voir le
       compte-rendu).
     - `max-width:1080px` est la ceinture, calée sur le palier de navigation :
       elle couvre les téléphones et tablettes même si le navigateur ment sur
       son pointeur, et elle est mesurable directement.

   `input[type]` : même spécificité que la règle de base `input[type=email]`,
   déclarée plus haut — c'est l'ordre qui tranche. Un sélecteur moins
   spécifique (`#form-acces input`) serait resté sans effet, en silence. Et ce
   bloc est APRÈS le palier 880 px pour la même raison.
   ⚠️ Non reproductible ici : le zoom lui-même est propre à WebKit, Chrome ne
   le fait pas. La taille est mesurée avec certitude, la disparition du zoom
   demande un vrai iPhone. */
@media (pointer:coarse){
  #form-acces input[type],#form-acces textarea{font-size:16px}
}
@media (max-width:1080px){
  #form-acces input[type],#form-acces textarea{font-size:16px}
}
/* Bloc de preuve : sur téléphone, les 4 lignes s'empilent TOUTES — chiffre au-
   dessus, explication en dessous. Le `flex-wrap` ci-dessus suffirait à éviter
   l'écrasement, mais il ne replie que la ligne qui déborde : on obtenait trois
   lignes en « chiffre | texte » et une quatrième en « chiffre / texte », ce qui
   se voit autant que le défaut d'origine. Quatre lignes bâties pareil valent
   mieux que trois bien et une à part. Le repli reste automatique au-delà. */
@media (max-width:520px){
  .chiffre{flex-direction:column;gap:6px}
  /* ⚠️ INDISPENSABLE : `flex-basis` porte sur l'AXE PRINCIPAL. En colonne, le
     220 px déclaré plus haut cesse d'être une largeur minimale et devient une
     HAUTEUR minimale — chaque explication réservait 220 px de haut, ce qui
     ouvrait un trou d'environ 200 px de vide sous chacun des quatre chiffres.
     Vu sur une capture, pas par la mesure : rien ne débordait, la page était
     simplement pleine de blanc. */
  .chiffre>span{flex:0 1 auto}
}
@media (max-width:480px){
  /* Prénom et nom côte à côte deviennent deux champs trop étroits pour leur
     texte d'exemple : on les empile. */
  .duo-champs{grid-template-columns:1fr}
  /* Le monogramme + deux boutons ne tiennent plus : la barre débordait de
     2 px (mesuré à 390 px). On ne garde que l'action principale ; « Se
     connecter » reste accessible dans la section « Demander un accès » et
     dans le pied de page, donc rien n'est perdu. */
  .entete-landing .lien-connexion{
    background:none;border:none;padding:6px 2px;color:var(--accent-fonce);
    text-decoration:underline;text-underline-offset:3px;font-size:.84rem;
  }
  .entete-landing .lien-connexion:hover{background:none;color:var(--accent)}
  .entete-landing .btn:not(.lien-connexion){padding:10px 15px;font-size:.84rem}
  /* ⚠️ LE LIBELLÉ COURT MONTE ICI (il était au palier 360 px), et c'est ce qui
     PAYE le `flex-shrink:0` posé sur la marque : la barre porte désormais un
     bouton de menu de 44 px en plus, et à 375 px le compte ne tombait plus
     (347 px de contenu + 32 de marges pour 375 disponibles). Sans place rendue,
     interdire au logo de se comprimer aurait simplement déplacé le défaut en
     débordement horizontal.
     Rien n'est perdu : « Demander un accès » reste écrit EN TOUTES LETTRES dans
     le panneau du menu, juste en dessous. C'est le menu qui rend ce
     raccourcissement gratuit — avant lui, le libellé court était la seule
     formulation disponible sur ces largeurs. */
  .etiq-longue{display:none}
  .etiq-courte{display:inline}
}
@media (max-width:430px){
  /* Le badge passait sur 2 lignes et occupait toute la largeur : on raccourcit
     l'interlettrage plutôt que de le laisser plier.
     ⚠️ La taille ne descend PAS sous 12 px (.75rem) : elle était à .68rem, soit
     10,9 px mesurés — sous ce seuil un téléphone force son propre zoom et toute
     la mise en page saute. On reprend la place sur l'interlettrage et le
     rembourrage, jamais sur la taille du texte. */
  .eyebrow{font-size:.75rem;letter-spacing:.08em;padding:5px 10px}
  .hero h1{font-size:2rem}
  .pied-footer{flex-direction:column;gap:14px}
}
/* ⚠️ APRÈS le bloc 430 px, et pas avant : à spécificité égale, c'est l'ordre de
   déclaration qui tranche. Écrit au-dessus (état d'avant le 03/08/2026), ce bloc
   était intégralement écrasé sur les écrans qu'il visait. */
@media (max-width:360px){
  /* Mesuré : à 320 px la page débordait de 27 px, le badge et le bouton étaient
     tranchés. Ici on laisse le badge se replier sur deux lignes plutôt que de
     rogner encore le texte — deux lignes lisibles valent mieux qu'une ligne
     illisible. */
  .eyebrow{white-space:normal;letter-spacing:.04em}
  .hero h1{font-size:1.8rem}
  .entete-landing .btn{padding:9px 12px;font-size:.8rem}
  .entete-landing nav{gap:10px}
  /* ⚠️ Le basculement vers le libellé court vivait ICI ; il est monté au palier
     480 px (pour payer le `flex-shrink:0` de la marque). Les deux lignes qui
     restaient à cet endroit étaient donc du CSS MORT — une redite exacte, sous
     un commentaire qui décrivait un état déjà obtenu 120 px plus haut. Retiré
     après relevé du gate `controle`. */
  /* .chiffre : l'empilement est monté au palier 520 px (voir plus haut) — il
     concernait tous les téléphones, pas seulement les plus étroits. */
}

/* ===== Écran bas × formulaire d'accès (03/08/2026) ==========================
   Le formulaire est passé de 1 champ à 5 (prénom, nom, e-mail, téléphone,
   message). MESURÉ à 1366 × 673 — l'écran du portable d'Hubert — avant ce
   bloc : le bouton d'envoi finissait 210 px SOUS la ligne de flottaison en
   arrivant par le lien de la barre, et pile dessus (marge 0) même avec
   l'ancrage idéal. Le visiteur voyait un formulaire sans bouton, et surtout
   ne voyait pas le « C'est noté » après l'envoi.

   ⚠️ PLACÉ ICI, EN FIN DE FICHIER, ET PAS dans le bloc `max-height:760px` du
   haut : ces règles ont la même spécificité que les règles de base de la
   section « Demander un accès » (déclarées plus bas). Écrites en haut du
   fichier, elles étaient écrasées EN SILENCE — vérifié, la carte restait à
   629 px. À spécificité égale, c'est l'ordre qui tranche.

   On reprend les pixels sur les espacements, jamais sur la taille du texte
   ni sur la surface cliquable des champs. */
@media (max-height:760px) and (min-width:881px){
  .acces{padding-top:40px;padding-bottom:48px}
  .bloc-acces{gap:40px}
  .carte-formulaire{padding:18px 24px 16px}
  #form-acces{gap:9px}
  #form-acces .lib{margin-bottom:4px}
  #form-acces input[type=email],
  #form-acces input[type=text],
  #form-acces input[type=tel],
  #form-acces textarea{padding:8px 12px}
  #form-acces textarea{min-height:52px}
  .duo-champs{gap:10px}
  .aide-champ{margin-top:3px}
  .mention-rgpd{line-height:1.4}
  .acces-alternatives{margin-top:12px}
}

/* ===== Téléphone TOURNÉ (paysage) ==========================================
   Un téléphone couché, c'est ~390 px de haut pour 850 de large. La scène du
   hero prend alors toute la largeur : avec son rapport 148/105, la carte
   manuscrite dépassait la HAUTEUR de l'écran — il fallait deux écrans pour la
   passer, et l'entrée en matière devenait illisible dans ce sens.
   On borne donc la scène par la hauteur disponible, pas par la largeur : la
   carte occupe au plus ~46 % de la hauteur d'écran, et se centre.
   `orientation:landscape` ET `max-height` : sans la hauteur, la règle
   toucherait aussi les écrans de bureau, qui sont tous en paysage. */
@media (orientation:landscape) and (max-height:520px){
  .scene{max-width:min(100%,62vh);margin-inline:auto;width:100%}
  .hero{gap:32px;padding-top:28px;padding-bottom:36px}

  /* ⚠️ AJOUT DU 24/08/2026 — LE DÉFAUT QU'IL VOYAIT, ET QU'AUCUNE MESURE EN
     PORTRAIT NE POUVAIT MONTRER. Un iPhone Pro Max COUCHÉ fait 932 px CSS, un
     XR/11 en fait 896 : au-dessus du palier de 880 px, la page reprenait la
     mise en page de BUREAU — DEUX colonnes, texte à gauche, scène à DROITE —
     et la carte partait se coller au bord droit.
     Mesuré à 932 px avant ce correctif : carte à 563 px du bord gauche, à
     98,8 px du bord droit, centre à 698 quand celui de l'écran est à 466 —
     232 px hors axe. Ses mots : « la carte déborde largement trop à droite,
     elle colle le bord de droite ».
     Le bloc `max-width:880px` ne pouvait PAS l'attraper : un téléphone couché
     est plus LARGE que 880. Ce qui trahit un téléphone, c'est la HAUTEUR — et
     ce bloc-ci la connaît déjà (max-height:520px). D'où la correction ici, et
     pas en montant le palier de 880, qui aurait emporté les vraies tablettes.
     ⚠️ Ne pas retirer `.enveloppe` de cette règle : en une seule colonne, son
     `align-self:flex-end` de base la renvoie contre le bord droit — le même
     défaut, sur l'autre élément de la scène. */
  .hero,.signature-bloc,.bloc-acces{grid-template-columns:1fr}
  /* Même raison qu'au palier téléphone : la rotation rasterise l'écriture et
     la rend molle. Voir la mesure là-bas. */
  .carte{transform:none}
  .enveloppe{align-self:center;width:74%;margin:18px 0 0;transform:none}
  /* Même verrou qu'au palier téléphone : la scène centre ses enfants et la
     carte ne peut pas déborder par la droite. Voir le commentaire là-bas. */
  .scene{align-items:center}
  .carte{width:100%;max-width:100%;min-width:0;align-self:center}

  /* ⚠️ LE PANNEAU DÉFILE ICI, ET C'EST UN CHOIX, PAS UN OUBLI.
     Arithmétique du cas : un téléphone couché offre ~320 px de haut ; moins
     la barre de 74 et les marges, il reste 228 px pour le panneau, quand six
     entrées à 44 px en réclament 264 plus le rembourrage. Aucune mise en page
     ne fait tenir les six sans rogner quelque chose.
     Deux sorties ont été essayées et écartées, mesure et capture à l'appui :
       - réduire la hauteur des entrées : refusé, 44 px est le minimum tactile,
         et c'est la doctrine déjà tenue partout dans ce fichier ;
       - passer le panneau sur DEUX COLONNES : écrit, capturé, REGARDÉ — le
         libellé « Comment ça marche » se repliait sur trois lignes et cassait
         l'alignement des deux colonnes. Le remède était pire que le mal.
     On garde donc une colonne qui défile : les six entrées sont là, chacune à
     44 px, et `overscroll-behavior:contain` empêche le défilement de filer
     dans la page derrière. */
}

/* Impression : on ne fait pas imprimer une page de vente, mais si ça arrive,
   qu'elle soit lisible et sans fond sombre gourmand en encre. */
@media print{
  .entete-landing,.hero-actions,.carte-formulaire,.lien-evitement{display:none}
  .tarifs{background:none;color:var(--encre)}
  .tarifs .titre-section,.bloc-tarif h3{color:var(--encre)}
  .tarifs .sous-titre,.note-tarifs,.bloc-tarif .par,.bloc-tarif .a-partir{color:var(--encre-doux)}
  .bloc-tarif{border-color:var(--ligne)}
}
