/* ═══════════════════════════════════════════════════════════════════════════
   LA POLICE EST SERVIE PAR CE SITE — 12/10/2026. Elle venait du CDN de Google.

   POURQUOI ELLE A DÉMÉNAGÉ. Charger une police depuis `fonts.gstatic.com`
   envoie à Google, à chaque visite et sans que le visiteur en sache rien, son
   adresse IP, sa page et son navigateur. C'est un transfert de données
   personnelles vers un tiers hors de l'Union — et un site qui publie une
   politique de confidentialité doit le déclarer. On préfère n'avoir rien à
   déclarer.

   CE QUE ÇA COÛTE : 52 Ko, une fois. Plus Jakarta Sans est une police
   VARIABLE : un seul fichier porte toutes les graisses de 400 à 800, et la
   déclaration `font-weight: 400 800` les lui demande. Le CDN servait cinq
   déclarations pointant quatre fois sur le même fichier.

   CE QUE ÇA RAPPORTE, en plus : deux connexions externes en moins avant le
   premier texte affiché (DNS, TLS, puis seulement la police), deux exceptions
   en moins dans la politique de sécurité, et un site qui s'affiche pareil le
   jour où Google change une adresse.

   Les sous-ensembles vietnamien et cyrillique ne sont pas repris. `latin` suffit
   au français — les accents, l'œ et l'euro y sont ; `latin-ext` est gardé pour
   les noms propres étrangers.

   ⚠ LICENCE. Plus Jakarta Sans est sous SIL Open Font License 1.1, qui
   AUTORISE cet hébergement et EXIGE que la licence accompagne les fichiers :
   elle est dans `polices/LICENCE-OFL.txt`, et citée dans les mentions légales.
   ═══════════════════════════════════════════════════════════════════════════ */

@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('polices/plus-jakarta-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('polices/plus-jakarta-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ═══════════════════════════════════════════════════════════════════════════
   KLIRA — feuille de style du site de présentation.  Version 2.

   ═══ D'OÙ VIENNENT CES COULEURS ═══

   Aucune n'est inventée : toutes sortent de `prototype/src/theme/tokens.ts`.

   Klira, ce sont LES BLEUS DE LA MÉDITERRANÉE — ceux de Sormiou et de Morgiou :
   le vert d'eau des bords (`teal.base`), le turquoise de la marque, la mer en
   surface (`sea`), et le bleu profond du large (`blue.base`). Rien d'autre.

   ⚠ UNE PREMIÈRE VERSION AVAIT PRIS LE CORAIL DU PRODUIT — `coral.base`, la
   couleur des tuiles — comme second accent, au motif qu'il figurait dans la
   palette de carte. C'était une erreur de lecture : ce corail sert à
   DIFFÉRENCIER des prestataires sur une carte, il n'est pas la marque. Corrigé
   le 18/09/2026. La leçon vaut d'être écrite : une couleur présente dans un
   fichier de thème n'est pas pour autant une couleur de marque.

   ═══ POURQUOI UN FOND SOMBRE ═══

   L'application vit sur du clair, et c'est juste : c'est un outil qu'on ouvre
   vingt fois par jour au comptoir. Un site de lancement se regarde une fois. Le
   turquoise ne devient LUMINEUX que posé sur du sombre, et la Méditerranée de
   nuit est le seul décor où une eau turquoise et des toits de terre cuite
   tiennent ensemble sans se battre.

   Le fond n'est jamais un gris neutre : il porte la teinte de la marque. L'œil
   ne la nomme pas, il la reconnaît.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── La marque ────────────────────────────────────────────────────────── */
  --primary: #0a7985;
  --primary-press: #075e68;
  --accent: #12bec9;
  --accent-graphic: #0e939c;
  --accent-deep: #0d5c6d;

  /* ── LA MER, ET RIEN D'AUTRE ─────────────────────────────────────────────
     ⚠ CORRIGÉ LE 18/09/2026. Une première version prenait le corail du produit
     (`coral.base`, la couleur des tuiles) comme second accent, au motif qu'il
     figurait dans la palette de carte. Benjamin a tranché, et il a raison : ce
     corail sert à DIFFÉRENCIER des prestataires sur une carte, il n'est pas la
     marque. Klira, ce sont les bleus de la Méditerranée — ceux de Sormiou et de
     Morgiou, du turquoise des bords au bleu profond du large.
     Les quatre valeurs ci-dessous sortent toutes de `theme/tokens.ts`. */
  --large: #2f6cb3;        /* `blue.base` — le bleu du large */
  --lagon: #3dcbb2;        /* `teal.base` en thème sombre — le vert d'eau des bords */
  --mer: #bcddee;          /* `sea` — la mer en surface */
  --ecume: #7ee8ef;        /* éclaircissement de l'accent : l'écume sur la roche */

  /* ── Les fonds ────────────────────────────────────────────────────────── */
  --ground: #03141a;
  --ground-2: #061f27;
  --ground-3: #0a2a33;

  --ink: #eaf7f8;
  --ink-soft: #9fc0c5;
  --ink-faint: #5f848b;
  --line: rgba(146, 204, 211, 0.15);
  --line-fort: rgba(146, 204, 211, 0.3);

  --radius: 18px;
  --radius-lg: 28px;

  --glow: 0 0 80px rgba(18, 190, 201, 0.22);
  --glow-fort: 0 0 120px rgba(18, 190, 201, 0.4);
  --glow-large: 0 0 90px rgba(47, 108, 179, 0.3);

  --mesure: 1180px;
  --sortie: cubic-bezier(0.16, 1, 0.3, 1);
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }

/* ⚠ LE MOUVEMENT RÉDUIT N'EST PAS UNE OPTION DE CONFORT. Pour qui souffre de
   troubles vestibulaires, une page qui glisse donne la nausée. Tout s'arrête. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ══════════════════ Typographie ══════════════════ */

h1, h2, h3 {
  margin: 0;
  line-height: 1.04;
  letter-spacing: -0.035em;
  text-wrap: balance;
  font-weight: 800;
}
h1 { font-size: clamp(2rem, 5vw, 3.7rem); }
.heros h1 { font-size: clamp(2.9rem, 8.5vw, 6.6rem); }
h2 { font-size: clamp(2rem, 5vw, 3.7rem); }
h3 { font-size: clamp(1.18rem, 2.2vw, 1.55rem); letter-spacing: -0.02em; }
p { margin: 0; }

.etiquette {
  display: inline-flex; align-items: center; gap: 14px;
  font-size: 0.73rem; font-weight: 700;
  letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 26px;
}
.etiquette::before {
  content: ''; width: 0; height: 1px; background: currentColor;
  transition: width 0.9s var(--sortie) 0.15s;
}
.revele .etiquette::before, .etiquette.revele::before { width: 48px; }
.etiquette.mer { color: var(--mer); }

.plomb {
  font-size: clamp(1.05rem, 1.7vw, 1.3rem);
  color: var(--ink-soft);
  max-width: 62ch;
}

.enveloppe { width: min(100% - 48px, var(--mesure)); margin-inline: auto; }
section { padding: clamp(96px, 13vh, 180px) 0; position: relative; }

/* ══════════════════ Révélation ══════════════════ */

.apparait {
  opacity: 0; transform: translateY(26px);
  transition: opacity 0.85s var(--sortie), transform 0.85s var(--sortie);
  transition-delay: var(--retard, 0s);
}
.apparait.revele { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .apparait { opacity: 1; transform: none; } }

/* ══════════════════ Jauge de lecture ══════════════════ */

/* Une barre fine qui dit où l'on en est. Sur une page longue, c'est la seule
   chose qui remplace la hauteur d'une barre de défilement qu'aucun navigateur
   moderne n'affiche plus vraiment. */
#jauge {
  position: fixed; top: 0; left: 0; height: 2px; width: 100%;
  transform: scaleX(0); transform-origin: left;
  background: linear-gradient(90deg, var(--lagon), var(--accent), var(--large));
  z-index: 60;
}

/* ══════════════════ En-tête ══════════════════ */

header {
  position: fixed; inset: 2px 0 auto 0; z-index: 50;
  padding: 16px 0;
  backdrop-filter: blur(20px);
  background: rgba(3, 20, 26, 0);
  border-bottom: 1px solid transparent;
  transition: background 0.4s ease, border-color 0.4s ease, padding 0.4s ease;
}
header.pose { background: rgba(3, 20, 26, 0.84); border-bottom-color: var(--line); padding: 11px 0; }
header .enveloppe { display: flex; align-items: center; justify-content: space-between; gap: 20px; }

.logotype {
  font-size: 1.45rem; font-weight: 800; letter-spacing: -0.04em;
  color: var(--ink); text-decoration: none;
}
.logotype span { color: var(--accent); text-shadow: 0 0 22px rgba(18, 190, 201, 0.9); }

nav { display: flex; align-items: center; gap: 28px; }
nav a {
  color: var(--ink-soft); text-decoration: none;
  font-size: 0.9rem; font-weight: 600;
  transition: color 0.25s ease;
}
nav a:hover, nav a:focus-visible { color: var(--ink); }
@media (max-width: 900px) { nav .masquable { display: none; } }

/* ══════════════════ Évitement, menu mobile, section active ══════════════════ */

/* Invisible tant qu'il n'a pas le focus — mais JAMAIS `display:none`, qui le
   retirerait aussi de l'ordre de tabulation et le rendrait inatteignable. */
.evitement {
  position: fixed; top: 10px; left: 10px; z-index: 100;
  padding: 12px 20px; border-radius: 12px;
  background: var(--accent); color: #03191d;
  font-weight: 700; text-decoration: none;
  transform: translateY(-160%);
  transition: transform 0.25s var(--sortie);
}
.evitement:focus { transform: none; }

/* Le bouton de menu n'existe QUE sur petit écran, et seulement si le script a
   tourné : `.js` est posé sur <html> par motion.js. Sans script, le panneau
   reste `hidden` et le bouton ne s'affiche pas — on ne montre pas une commande
   qui n'ouvrirait rien. */
.bascule { display: none; }
html.js .bascule {
  width: 42px; height: 42px; border-radius: 12px;
  border: 1px solid var(--line-fort);
  background: rgba(255, 255, 255, 0.03);
  cursor: pointer;
  flex-direction: column; align-items: center; justify-content: center; gap: 5px;
}
@media (max-width: 900px) { html.js .bascule { display: flex; } }
.bascule span {
  display: block; width: 17px; height: 1.5px; border-radius: 2px;
  background: var(--ink);
  transition: transform 0.3s var(--sortie), opacity 0.2s ease;
}
.bascule[aria-expanded='true'] span:first-child { transform: translateY(3.2px) rotate(45deg); }
.bascule[aria-expanded='true'] span:last-child { transform: translateY(-3.2px) rotate(-45deg); }

.menu-mobile {
  position: fixed; inset: 68px 12px auto 12px; z-index: 49;
  padding: 14px; border-radius: 22px;
  background: rgba(4, 22, 28, 0.97);
  backdrop-filter: blur(24px);
  border: 1px solid var(--line-fort);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  display: grid; gap: 2px;
  transform-origin: top right;
  animation: ouvre-menu 0.32s var(--sortie);
}
@keyframes ouvre-menu {
  from { opacity: 0; transform: translateY(-10px) scale(0.97); }
}
.menu-mobile a {
  padding: 14px 16px; border-radius: 13px;
  color: var(--ink); text-decoration: none; font-weight: 600;
  transition: background 0.2s ease;
}
.menu-mobile a:hover, .menu-mobile a:focus-visible { background: rgba(18, 190, 201, 0.1); }
/* ⚠ CETTE LIGNE N'EST PAS UNE PRÉCAUTION, C'EST UN CORRECTIF. L'attribut
   `hidden` pose `display:none` depuis la feuille du NAVIGATEUR, que n'importe
   quelle règle d'auteur écrase — et `.menu-mobile { display: grid }` l'écrasait.
   Résultat : sur petit écran, le menu s'affichait ouvert au chargement, par-
   dessus la page, sans que personne ne l'ait demandé. Constaté à la capture. */
.menu-mobile[hidden] { display: none; }
@media (min-width: 901px) { .menu-mobile { display: none; } }

/* La section où l'on se trouve, marquée dans le menu. Un repère discret : un
   point, pas un surlignage — on dit où l'on est, on ne décore pas. */
nav a.ici { color: var(--ink); position: relative; }
nav a.ici::after {
  content: ''; position: absolute;
  left: 50%; translate: -50% 0; bottom: -7px;
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent);
}

/* ══════════════════ Boutons ══════════════════ */

.bouton {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 14px 27px; border-radius: 999px;
  font-weight: 700; font-size: 0.95rem;
  text-decoration: none; border: 1px solid transparent;
  cursor: pointer; position: relative;
  transition: transform 0.3s var(--sortie), box-shadow 0.35s ease,
    background 0.25s ease, border-color 0.25s ease;
}
/* ⚠ LA FIN DU DÉGRADÉ A ÉTÉ ÉCLAIRCIE — 12/10/2026, et ce n'est pas une
   question de goût. Le texte de ce bouton est sombre (#03191d) sur un dégradé :
   il faut donc mesurer le contraste AUX DEUX BOUTS, pas au milieu. Mesuré :
   7,96:1 sur `--accent` au départ, mais 3,52:1 sur `--primary` à l'arrivée —
   sous le seuil AA de 4,5 exigé pour 15 px. La moitié droite de l'appel à
   l'action le plus important du site était illisible pour une partie des gens.
   `--accent-graphic` monte l'arrivée à 4,89:1. La couleur n'est pas inventée :
   elle est déjà dans la palette du produit. */
.bouton-plein {
  background: linear-gradient(120deg, var(--accent), var(--accent-graphic));
  color: #03191d; box-shadow: var(--glow);
}
.bouton-plein:hover { box-shadow: var(--glow-fort); }
.bouton-fil {
  border-color: var(--line-fort); color: var(--ink);
  background: rgba(255, 255, 255, 0.02);
}
.bouton-fil:hover { border-color: var(--accent); background: rgba(18, 190, 201, 0.07); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }

/* ══════════════════ Héros ══════════════════ */

.heros {
  min-height: 100svh; display: flex; align-items: center;
  padding-top: 96px; position: relative; overflow: hidden;
}

/* LES TROIS COUCHES DU FOND, de l'arrière vers l'avant.
   Chacune fait un travail différent ; empilées, elles donnent une profondeur
   qu'aucune ne produit seule. */

/* 1. Les caustiques : la lumière du soleil réfractée par la surface de l'eau.
      C'est LE motif méditerranéen — celui qu'on voit au fond d'une calanque à
      midi. Dessiné en canvas, il ondule lentement. */
#eau { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; opacity: 0.42; }

/* 2. La constellation : des points qui ne se relient qu'en deçà d'une certaine
      distance. C'est littéralement ce que fait Klira — relier des gens à des
      commerces DANS un quartier. Le motif est le sujet. */
#champ { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; opacity: 0.5; }

/* 3. La ligne d'horizon : une lueur basse, comme la mer sous la nuit. */
.horizon {
  position: absolute; left: -10%; right: -10%; bottom: -30%;
  height: 60%; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse at 50% 100%, rgba(18, 190, 201, 0.2), transparent 62%);
}

.heros::before, .heros::after {
  content: ''; position: absolute; border-radius: 50%;
  filter: blur(130px); z-index: 0; pointer-events: none;
}
/* Deux lueurs, toutes deux marines : le vert d'eau des bords en haut, le bleu du
   large en bas. C'est le dégradé qu'on voit en entrant dans une calanque. */
.heros::before {
  width: 660px; height: 660px;
  background: rgba(10, 121, 133, 0.32);
  top: -200px; left: -170px;
}
.heros::after {
  width: 540px; height: 540px;
  background: rgba(47, 108, 179, 0.26);
  bottom: -190px; right: -130px;
}

.heros .enveloppe {
  position: relative; z-index: 3;
  display: grid; grid-template-columns: 1.12fr 0.88fr;
  gap: 64px; align-items: center;
}
@media (max-width: 980px) { .heros .enveloppe { grid-template-columns: 1fr; gap: 56px; } }

.ligne-masque {
  overflow: hidden; display: block;
  padding-bottom: 0.14em; margin-bottom: -0.14em;
}
.ligne-masque > span {
  display: block; transform: translateY(105%);
  animation: monte 1.05s var(--sortie) forwards;
  animation-delay: var(--retard, 0s);
}
@keyframes monte { to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .ligne-masque > span { transform: none; animation: none; } }

.titre-accent {
  background: linear-gradient(105deg, var(--lagon) 0%, var(--ecume) 38%, var(--accent) 68%, var(--large) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

.heros .plomb { margin-top: 30px; }
.heros-actions { margin-top: 40px; display: flex; flex-wrap: wrap; gap: 14px; }

.mention-beta {
  margin-top: 26px; display: inline-flex; align-items: center; gap: 10px;
  font-size: 0.86rem; color: var(--ink-faint);
}
.pastille {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 rgba(18, 190, 201, 0.7);
  animation: pulse 2.6s ease-out infinite;
}
@keyframes pulse {
  70% { box-shadow: 0 0 0 11px rgba(18, 190, 201, 0); }
  100% { box-shadow: 0 0 0 0 rgba(18, 190, 201, 0); }
}

/* ── Les rayons : la lumière du soleil qui traverse l'eau ─────────────────
   Ce qu'on voit en levant la tête sous l'eau, à quelques mètres de fond. Ils
   balaient très lentement — un rayon qui bougerait vite ferait « projecteur de
   discothèque » au lieu de « surface qui ondule ». */
.rayons {
  position: absolute; inset: -20% -10% auto -10%; height: 110%;
  z-index: 0; pointer-events: none; overflow: hidden;
  mask-image: linear-gradient(to bottom, #000 0%, #000 42%, transparent 78%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 42%, transparent 78%);
}
.rayons i {
  position: absolute; top: -30%; height: 160%;
  width: var(--l, 120px);
  background: linear-gradient(to bottom, rgba(126, 232, 239, 0.1), transparent 72%);
  filter: blur(22px);
  transform-origin: top center;
  animation: oscille var(--d, 17s) ease-in-out infinite alternate;
  animation-delay: var(--retard, 0s);
}
@keyframes oscille {
  from { transform: rotate(var(--a1, -10deg)) translateX(-2%); opacity: 0.5; }
  to   { transform: rotate(var(--a2, 6deg)) translateX(2%); opacity: 1; }
}

/* ── Les particules : ce qui flotte entre deux eaux ───────────────────────
   Très peu, très lentes, très petites. Elles ne se remarquent pas une par une :
   c'est leur dérive d'ensemble qui donne au fond sa profondeur, et qui fait que
   l'œil croit voir un volume plutôt qu'une image. */
.plancton { position: absolute; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.plancton i {
  position: absolute; bottom: -8%;
  width: var(--t, 3px); height: var(--t, 3px);
  border-radius: 50%;
  background: rgba(126, 232, 239, 0.5);
  box-shadow: 0 0 8px rgba(18, 190, 201, 0.5);
  animation: monte-eau var(--d, 26s) linear infinite;
  animation-delay: var(--retard, 0s);
  left: var(--x, 50%);
  opacity: 0;
}
@keyframes monte-eau {
  0%   { transform: translateY(0) translateX(0); opacity: 0; }
  12%  { opacity: 0.85; }
  88%  { opacity: 0.7; }
  100% { transform: translateY(-112vh) translateX(var(--derive, 30px)); opacity: 0; }
}

/* ── La profondeur : sombre en bas, clair en haut ─────────────────────────
   Un seul dégradé, et c'est lui qui décide qu'on regarde de l'eau et non un
   fond noir avec des choses dessus. */
.profondeur {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(to bottom,
      rgba(18, 190, 201, 0.09) 0%,
      rgba(10, 121, 133, 0.04) 34%,
      transparent 58%,
      rgba(2, 12, 18, 0.55) 100%);
}

@media (prefers-reduced-motion: reduce) {
  .rayons i, .plancton i { animation: none; }
  .plancton i { opacity: 0.5; }
}

/* ══════════════════ Le pass ══════════════════ */

.scene-pass { perspective: 1400px; display: flex; justify-content: center; }

.pass {
  width: min(330px, 84vw); border-radius: var(--radius-lg); padding: 28px;
  background: linear-gradient(160deg, rgba(18, 190, 201, 0.17), rgba(10, 121, 133, 0.05));
  border: 1px solid var(--line);
  backdrop-filter: blur(22px);
  box-shadow: 0 34px 96px rgba(0, 0, 0, 0.6), var(--glow);
  transform-style: preserve-3d;
  transition: transform 0.5s var(--sortie);
  position: relative; overflow: hidden;
  animation: flotte 7s ease-in-out infinite;
}
@keyframes flotte { 0%, 100% { translate: 0 0; } 50% { translate: 0 -13px; } }

.pass::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(18, 190, 201, 0.18) 50%, transparent 62%);
  transform: translateX(-120%);
  animation: balaye 4.6s ease-in-out infinite;
}
@keyframes balaye { 0%, 62% { transform: translateX(-120%); } 100% { transform: translateX(120%); } }

.pass-entete { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 26px; }
.pass-commerce { font-weight: 800; font-size: 1.1rem; letter-spacing: -0.02em; }
.pass-activite { font-size: 0.8rem; color: var(--ink-faint); margin-top: 2px; }
.pass-etat {
  font-size: 0.65rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--accent); border: 1px solid rgba(18, 190, 201, 0.35);
  border-radius: 999px; padding: 5px 11px;
}
.code {
  display: grid; grid-template-columns: repeat(9, 1fr); gap: 4px;
  padding: 16px; background: rgba(2, 16, 20, 0.6);
  border-radius: 14px; border: 1px solid var(--line);
}
.code i {
  aspect-ratio: 1; border-radius: 2px;
  background: rgba(18, 190, 201, 0.1);
  animation: allume 3.4s ease-in-out infinite;
  animation-delay: var(--retard);
}
.code i.pleine { background: rgba(18, 190, 201, 0.74); }
@keyframes allume { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }
.pass-pied {
  margin-top: 22px; display: flex; justify-content: space-between; align-items: center;
  font-size: 0.78rem; color: var(--ink-faint);
}
.pass-pied strong { color: var(--ink); font-size: 0.92rem; }

/* ══════════════════ Grilles et cartes ══════════════════ */

.duo {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  gap: 24px; margin-top: 56px;
}

.carte {
  padding: 34px; border-radius: var(--radius-lg);
  background: linear-gradient(165deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012));
  border: 1px solid var(--line);
  position: relative; overflow: hidden;
  transition: transform 0.4s var(--sortie), border-color 0.4s ease;
}
.carte:hover { transform: translateY(-5px); border-color: var(--line-fort); }
.carte::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  transform: scaleX(0); transition: transform 0.6s var(--sortie);
}
.carte:hover::before { transform: scaleX(1); }

/* La lueur qui suit le pointeur. Elle ne sert à rien d'autre qu'à donner à la
   carte l'air d'être éclairée par la main qui s'en approche — mais c'est
   exactement ce qui fait la différence entre « une carte » et « une surface ». */
.carte::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 0%),
    rgba(18, 190, 201, 0.09), transparent 65%);
  opacity: 0; transition: opacity 0.4s ease;
}
.carte:hover::after { opacity: 1; }

.carte h3 { margin-bottom: 14px; }
.carte p { color: var(--ink-soft); font-size: 0.99rem; }

.icone {
  width: 46px; height: 46px; border-radius: 13px;
  display: grid; place-items: center;
  background: rgba(18, 190, 201, 0.12);
  border: 1px solid rgba(18, 190, 201, 0.22);
  margin-bottom: 22px;
}
.icone svg { width: 22px; height: 22px; stroke: var(--accent); fill: none; stroke-width: 1.7; }
.icone.mer { background: rgba(47, 108, 179, 0.16); border-color: rgba(188, 221, 238, 0.26); }
.icone.mer svg { stroke: var(--mer); }

/* ══════════════════ Le parcours ══════════════════ */

.parcours { margin-top: 64px; position: relative; }
.parcours::before {
  content: ''; position: absolute; top: 27px; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, var(--lagon), var(--accent), var(--large));
  transform-origin: left; transform: scaleX(0);
  transition: transform 1.6s var(--sortie);
}
.parcours.revele::before { transform: scaleX(1); }
@media (max-width: 880px) { .parcours::before { display: none; } }

.temps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 30px; }
@media (max-width: 880px) { .temps { grid-template-columns: 1fr; gap: 40px; } }
.temps > div { position: relative; }
.temps p { color: var(--ink-soft); margin-top: 10px; }
.numero {
  width: 54px; height: 54px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--ground); border: 1px solid rgba(18, 190, 201, 0.36);
  color: var(--accent); font-weight: 800; font-size: 1.05rem;
  margin-bottom: 22px; position: relative; z-index: 2;
  transition: box-shadow 0.5s ease;
}
.revele .numero { box-shadow: 0 0 34px rgba(18, 190, 201, 0.3); }

/* ══════════════════ Chiffres ══════════════════ */

.chiffres {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 18px; margin-top: 56px;
}
.chiffre {
  padding: 32px 26px; border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.025); border: 1px solid var(--line);
  text-align: center;
}
.chiffre b {
  display: block; font-size: clamp(2.2rem, 4.4vw, 3.1rem);
  font-weight: 800; letter-spacing: -0.04em;
  background: linear-gradient(120deg, var(--accent), #7ee8ef);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  font-variant-numeric: tabular-nums;
}
.chiffre span { color: var(--ink-soft); font-size: 0.92rem; }

/* ══════════════════ Marseille ══════════════════ */

.marseille { position: relative; overflow: hidden; }

/* Le littoral se DESSINE au défilement. Ce n'est pas une carte : c'est une
   silhouette de côte, qui dit « ici » sans prétendre situer quoi que ce soit.
   Une vraie carte demanderait d'être exacte ; une silhouette, non. */
.littoral {
  position: absolute; inset: auto 0 0 0; height: 62%;
  z-index: 0; pointer-events: none; opacity: 0.5;
}
.littoral svg { width: 100%; height: 100%; }
.littoral path {
  fill: none; stroke-width: 1;
  stroke-dasharray: var(--longueur); stroke-dashoffset: var(--longueur);
  transition: stroke-dashoffset 2.6s var(--sortie);
}
.marseille.revele .littoral path { stroke-dashoffset: 0; }

.marseille .enveloppe { position: relative; z-index: 2; }

/* Le titre se révèle LETTRE PAR LETTRE. Réservé à cette section, et à elle
   seule : c'est le nom de la ville, le seul mot de la page qui mérite qu'on le
   regarde arriver. Partout ailleurs, ce serait de l'esbroufe. */
.lettres span {
  display: inline-block;
  opacity: 0; transform: translateY(0.4em) rotate(4deg);
  transition: opacity 0.6s var(--sortie), transform 0.6s var(--sortie);
  transition-delay: calc(var(--i) * 0.035s);
}
.revele .lettres span { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .lettres span { opacity: 1; transform: none; } }

/* ══════════════════ L'histoire ══════════════════ */

.histoire { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; margin-top: 52px; }
.portrait {
  padding: 34px; border-radius: var(--radius-lg);
  background: linear-gradient(165deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.012));
  border: 1px solid var(--line);
}
.initiales {
  width: 62px; height: 62px; border-radius: 50%;
  display: grid; place-items: center;
  font-weight: 800; font-size: 1.3rem; letter-spacing: -0.02em;
  margin-bottom: 22px;
}
.initiales.a { background: rgba(18, 190, 201, 0.14); border: 1px solid rgba(18, 190, 201, 0.3); color: var(--accent); }
.initiales.b { background: rgba(47, 108, 179, 0.18); border: 1px solid rgba(188, 221, 238, 0.3); color: var(--mer); }
.portrait .role {
  font-size: 0.73rem; font-weight: 700; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--ink-faint); margin-top: 6px;
}
.portrait p { color: var(--ink-soft); margin-top: 16px; font-size: 0.99rem; }

.portrait-entete { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.portrait .initiales { margin-bottom: 0; }

/* L'étiquette de côté : c'est elle qui porte l'idée de la section — les deux
   faces de la place de marché sont les deux fondateurs. Deux teintes, mais
   toutes deux marines : le vert d'eau des bords pour le commerce (celui qu'on
   touche), le bleu du large pour le client (celui qui vient). */
.cote {
  font-size: 0.68rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  padding: 6px 13px; border-radius: 999px;
}
.cote-pro { background: rgba(61, 203, 178, 0.13); border: 1px solid rgba(61, 203, 178, 0.3); color: var(--lagon); }
.cote-client { background: rgba(47, 108, 179, 0.16); border: 1px solid rgba(155, 185, 221, 0.3); color: var(--mer); }

/* La bande qui referme la section : le trait vertical dit « ceci conclut ce qui
   précède » sans qu'on ait à l'écrire. */
.rencontre {
  margin-top: 30px; padding: 30px 34px;
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: linear-gradient(90deg, rgba(18, 190, 201, 0.07), transparent 70%);
}
.rencontre p { color: var(--ink-soft); font-size: 1.02rem; max-width: 74ch; }
.rencontre strong { color: var(--ink); }

/* ══════════════════ La démonstration de l'application ══════════════════ */

/* ⚠ CE BLOC EST LE SEUL DE LA FEUILLE À S'ÉCARTER DE LA PALETTE DU SITE, et
   c'est délibéré : l'écran du téléphone doit montrer l'APPLICATION, pas le site.
   Les valeurs ci-dessous sortent telles quelles de `prototype/src/theme/tokens.ts`.
   Si la marque bouge un jour, elles bougent avec elle — pas avant. */
.demo-app { --app-fond: #061c22; --app-carte: #0d2b33; --app-trait: rgba(146, 204, 211, 0.16); }

.scene-app {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: clamp(32px, 6vw, 80px);
  align-items: center;
  margin-top: 56px;
}
@media (max-width: 860px) { .scene-app { grid-template-columns: 1fr; justify-items: center; } }

.telephone { position: relative; width: 100%; max-width: 300px; }

.chassis {
  position: relative; z-index: 1;
  border-radius: 42px;
  padding: 11px;
  background: linear-gradient(160deg, #1b3e47, #061c22 60%);
  border: 1px solid var(--line-fort);
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.encoche {
  position: absolute; top: 20px; left: 50%; translate: -50% 0; z-index: 3;
  width: 78px; height: 20px; border-radius: 999px;
  background: #04141a;
}
.ecran {
  position: relative;
  aspect-ratio: 9 / 18.5;
  border-radius: 32px;
  overflow: hidden;
  background: var(--app-fond);
}

/* Les trois écrans sont EMPILÉS, pas remplacés : le téléphone garde une hauteur
   constante, sinon la page sautillerait à chaque changement de vue. */
.vue {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  opacity: 0; visibility: hidden;
  transform: translateY(10px) scale(0.985);
  transition: opacity 0.5s var(--sortie), transform 0.6s var(--sortie), visibility 0s 0.5s;
}
.vue-active { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }

.barre-etat {
  display: flex; justify-content: space-between; align-items: center;
  padding: 26px 22px 6px;
  font-size: 0.62rem; font-weight: 700; color: var(--ink);
}
.barre-etat .signal {
  width: 26px; height: 8px; border-radius: 3px;
  background: linear-gradient(90deg, var(--ink) 65%, var(--ink-faint) 65%);
}
.vue-corps { flex: 1; padding: 10px 18px 16px; display: flex; flex-direction: column; gap: 11px; overflow: hidden; }
.vue-corps.centre { justify-content: center; }

.titre-app { font-size: 1.12rem; font-weight: 800; letter-spacing: -0.02em; }

.filtres-app { display: flex; gap: 6px; }
.puce-app {
  font-size: 0.6rem; font-weight: 700; padding: 6px 11px; border-radius: 999px;
  border: 1px solid var(--app-trait); color: var(--ink-soft); white-space: nowrap;
}
.puce-app.active { background: var(--accent); border-color: var(--accent); color: #03191d; }

.carte-app {
  display: flex; align-items: center; gap: 11px;
  padding: 11px; border-radius: 15px;
  background: var(--app-carte); border: 1px solid var(--app-trait);
}
.carte-app.estompe { opacity: 0.5; }
.vignette {
  width: 40px; height: 40px; flex: none; border-radius: 12px;
  display: grid; place-items: center;
  font-size: 0.65rem; font-weight: 800; color: #03191d;
}
.vignette.v1 { background: linear-gradient(140deg, var(--ecume), var(--accent)); }
.vignette.v2 { background: linear-gradient(140deg, var(--lagon), var(--primary)); }
.vignette.v3 { background: linear-gradient(140deg, var(--mer), var(--large)); }
.carte-texte { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.carte-texte strong { font-size: 0.78rem; font-weight: 700; }
.carte-texte span { font-size: 0.62rem; color: var(--ink-soft); }
.prix-app { color: var(--ecume) !important; font-weight: 700; }

.pass-app {
  border-radius: 20px; padding: 16px;
  background: linear-gradient(150deg, rgba(18, 190, 201, 0.16), rgba(47, 108, 179, 0.12));
  border: 1px solid rgba(18, 190, 201, 0.35);
  display: grid; gap: 13px;
}
.pass-app .pass-entete, .pass-app .pass-pied {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 0.68rem; margin-bottom: 0;
}
.pass-app .pass-entete { font-weight: 800; }
.pass-app .pass-pied { color: var(--ink-soft); font-size: 0.6rem; }
.etat-app {
  font-size: 0.55rem; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 999px;
  background: rgba(61, 203, 178, 0.18); color: var(--lagon);
}
/* Le code est SUGGÉRÉ par une trame, jamais dessiné pour de vrai : un faux QR
   scannable serait un piège, et un vrai n'aurait rien à faire sur une vitrine. */
.code-app {
  aspect-ratio: 1; border-radius: 12px; background: var(--ink);
  background-image:
    repeating-linear-gradient(90deg, #04141a 0 8px, transparent 8px 16px),
    repeating-linear-gradient(0deg, #04141a 0 8px, transparent 8px 16px);
  background-size: 16px 16px;
  mask-image: radial-gradient(circle at 50% 50%, #000 72%, transparent 73%);
}
.note-app { font-size: 0.62rem; color: var(--ink-soft); text-align: center; margin-top: 12px; line-height: 1.5; }

.semaine-app { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.jour-app {
  display: grid; gap: 5px; justify-items: center;
  padding: 8px 0; border-radius: 10px;
  font-size: 0.58rem; font-weight: 700; color: var(--ink-soft);
  border: 1px solid transparent;
}
.jour-app i { width: 4px; height: 4px; border-radius: 50%; background: transparent; }
.jour-app.pris i { background: var(--lagon); }
.jour-app.aujourdhui { background: rgba(18, 190, 201, 0.14); border-color: rgba(18, 190, 201, 0.4); color: var(--ink); }

.rdv-app {
  display: flex; align-items: center; gap: 11px;
  padding: 11px; border-radius: 15px;
  background: var(--app-carte); border: 1px solid var(--app-trait);
  border-left: 3px solid var(--accent);
}
.rdv-app.pale { opacity: 0.55; border-left-color: var(--ink-faint); }
.heure-app { font-size: 0.68rem; font-weight: 800; color: var(--ecume); font-variant-numeric: tabular-nums; }

.onglets { display: flex; justify-content: center; gap: 26px; padding: 12px 0 4px; }
.onglet { width: 22px; height: 3px; border-radius: 2px; background: var(--ink-faint); opacity: 0.4; }
.onglet.actif { background: var(--accent); opacity: 1; }

.halo-tel {
  position: absolute; inset: -14% -22%; z-index: 0;
  background: radial-gradient(ellipse at 50% 45%, rgba(18, 190, 201, 0.3), transparent 68%);
  filter: blur(46px);
  animation: respire-halo 7s ease-in-out infinite;
}
@keyframes respire-halo { 50% { opacity: 0.55; } }

.legende-app { display: grid; gap: 10px; align-content: center; }
.pas-app {
  display: grid; gap: 5px; text-align: left;
  padding: 18px 22px; border-radius: var(--radius);
  background: transparent; cursor: pointer;
  border: 1px solid transparent;
  border-left: 2px solid var(--line);
  color: inherit; font: inherit;
  transition: background 0.35s ease, border-color 0.35s ease, transform 0.35s var(--sortie);
}
.pas-app strong { font-size: 1.04rem; font-weight: 700; color: var(--ink-soft); transition: color 0.35s ease; }
.pas-app span { font-size: 0.88rem; color: var(--ink-faint); line-height: 1.6; max-width: 52ch; }
.pas-app:hover { border-left-color: var(--line-fort); }
.pas-app.actif {
  background: linear-gradient(90deg, rgba(18, 190, 201, 0.08), transparent 75%);
  border-left-color: var(--accent);
  transform: translateX(4px);
}
.pas-app.actif strong { color: var(--ink); }

/* ══════════════════ Contact ══════════════════ */

.contact {
  border-radius: 34px;
  padding: clamp(44px, 6vw, 76px);
  background:
    radial-gradient(900px 340px at 50% 0%, rgba(18, 190, 201, 0.14), transparent 70%),
    linear-gradient(160deg, var(--ground-3), var(--ground-2));
  border: 1px solid var(--line);
  position: relative; overflow: hidden;
}
.contact-grille { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 48px; align-items: start; }
@media (max-width: 880px) { .contact-grille { grid-template-columns: 1fr; gap: 36px; } }

.voie {
  display: flex; gap: 16px; align-items: flex-start;
  padding: 18px 0; border-bottom: 1px solid var(--line);
}
.voie:last-child { border-bottom: 0; }
.voie svg { width: 20px; height: 20px; stroke: var(--accent); fill: none; stroke-width: 1.7; flex: none; margin-top: 3px; }
.voie b { display: block; font-size: 0.97rem; }
.voie a { color: var(--accent); text-decoration: none; }
.voie a:hover { text-decoration: underline; }
.voie small { color: var(--ink-faint); font-size: 0.85rem; }

.champ { margin-bottom: 18px; }
.champ label {
  display: block; font-size: 0.83rem; font-weight: 700;
  letter-spacing: 0.06em; color: var(--ink-soft); margin-bottom: 8px;
}
.champ input, .champ textarea, .champ select {
  width: 100%; padding: 13px 16px;
  background: rgba(2, 16, 20, 0.5);
  border: 1px solid var(--line); border-radius: 13px;
  color: var(--ink); font: inherit; font-size: 0.97rem;
  transition: border-color 0.25s ease, background 0.25s ease;
}
.champ textarea { min-height: 128px; resize: vertical; }
.champ input:focus, .champ textarea:focus, .champ select:focus {
  outline: none; border-color: var(--accent);
  background: rgba(18, 190, 201, 0.05);
}
.champ input::placeholder, .champ textarea::placeholder { color: var(--ink-faint); }

.note-formulaire {
  margin-top: 16px; font-size: 0.83rem; color: var(--ink-faint); line-height: 1.55;
}

/* ══════════════════ Magasins ══════════════════ */

.magasins { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 32px; }
/* ⚠ INERTES, ET ILS LE DISENT. L'application n'est sur aucun magasin. Un bouton
   qui ressemble à un lien sans en être un est un mensonge d'interface. */
.magasin {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 13px 22px; border-radius: 14px;
  border: 1px solid var(--line); background: rgba(255, 255, 255, 0.03);
  color: var(--ink-faint); cursor: not-allowed; font-size: 0.9rem;
}
.magasin svg { width: 21px; height: 21px; fill: currentColor; }
.magasin b { display: block; color: var(--ink-soft); font-size: 0.95rem; font-weight: 700; }
.magasin small { font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase; }

/* ══════════════════ Pied ══════════════════ */

footer {
  border-top: 1px solid var(--line);
  padding: 54px 0 44px; color: var(--ink-faint); font-size: 0.88rem;
}
footer .enveloppe { display: flex; flex-wrap: wrap; gap: 26px; justify-content: space-between; align-items: center; }
footer a { color: var(--ink-soft); text-decoration: none; }
footer a:hover { color: var(--accent); }
.liens-pied { display: flex; flex-wrap: wrap; gap: 24px; }

/* ═══════════════════════════════════════════════════════════════════════════
   LE SITE EN PLUSIEURS PAGES — ajouté le 18/09/2026.

   Le site tenait sur une seule page. Il fallait faire défiler six sections pour
   arriver au contact, et rien ne permettait d'envoyer quelqu'un directement à
   « pour le commerçant ». Sept pages, un squelette commun (`gabarit.html`),
   et ce bloc porte ce que la nouvelle structure a introduit.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Le pied, en colonnes ────────────────────────────────────────────────── */
.pied-colonnes {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr));
  gap: 36px;
  align-items: start;
}
@media (max-width: 820px) { .pied-colonnes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 30px; } }
@media (max-width: 480px) { .pied-colonnes { grid-template-columns: 1fr; } }
.colonne-pied { display: grid; gap: 9px; align-content: start; }
.colonne-pied strong {
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-faint);
  margin-bottom: 3px;
}
.note-pied { color: var(--ink-faint); font-size: 0.86rem; }

/* ── Le chapeau d'une page intérieure ────────────────────────────────────────
   Pas un héros : un héros ouvre un site, un chapeau ouvre un chapitre. D'où la
   hauteur retenue et l'absence de scène animée — on est déjà entré. */
.chapeau-page {
  position: relative; overflow: hidden;
  padding: clamp(112px, 15vw, 168px) 0 clamp(48px, 7vw, 76px);
}
.chapeau-page .rayons { opacity: 0.5; }
/* Le plancton du chapeau est plus discret que celui du héros : on ouvre un
   chapitre, on ne rouvre pas le site. */
.chapeau-page .plancton { opacity: 0.55; }
.chapeau-page .enveloppe { position: relative; z-index: 2; }
.chapeau-page h1 {
  font-size: clamp(2.1rem, 5.6vw, 3.9rem);
  line-height: 1.04; letter-spacing: -0.035em;
  margin-top: 18px; text-wrap: balance;
}
.chapeau-page .plomb { margin-top: 26px; }
.chapeau-page .mention-beta { margin-top: 30px; }

/* ── Les quatre portes de l'accueil ──────────────────────────────────────── */
.portes {
  display: grid; gap: 18px; margin-top: 50px;
  grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
}
.porte {
  display: grid; gap: 10px; align-content: start;
  padding: 30px 28px 26px; border-radius: var(--radius-lg);
  background: linear-gradient(165deg, rgba(255, 255, 255, 0.035), transparent 62%);
  border: 1px solid var(--line);
  text-decoration: none; color: inherit;
  position: relative; overflow: hidden;
  transition: transform 0.45s var(--sortie), border-color 0.45s ease, background 0.45s ease;
}
.porte::after {
  /* Une lueur qui monte au survol : elle vient du bas, comme si la page
     s'éclairait par-dessous. Sur `::after` pour ne pas toucher au fond. */
  content: ''; position: absolute; inset: auto 0 0 0; height: 0;
  background: radial-gradient(ellipse at 50% 100%, rgba(18, 190, 201, 0.2), transparent 70%);
  transition: height 0.55s var(--sortie);
}
.porte:hover, .porte:focus-visible {
  transform: translateY(-5px);
  border-color: var(--line-fort);
  background: linear-gradient(165deg, rgba(18, 190, 201, 0.08), transparent 62%);
}
.porte:hover::after, .porte:focus-visible::after { height: 100%; }
.numero-porte {
  /* ⚠ NUMÉROTÉ PARCE QUE C'EST UN ORDRE, pas pour décorer : on lit ces quatre
     portes dans cet ordre-là — ce que c'est, puis de quel côté on est, puis qui
     le fait. Si l'ordre cessait de compter, les numéros devraient disparaître. */
  font-size: 0.72rem; font-weight: 800; letter-spacing: 0.18em;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.porte h3 { font-size: 1.28rem; font-weight: 700; letter-spacing: -0.02em; }
.porte p { color: var(--ink-soft); font-size: 0.95rem; line-height: 1.66; }
.mene, .lien-fleche {
  font-weight: 700; color: var(--accent); font-size: 0.92rem;
  display: inline-flex; align-items: center; gap: 7px;
}
.mene { margin-top: 6px; }
.mene::after, .lien-fleche::after {
  content: '→'; transition: transform 0.35s var(--sortie);
}
.porte:hover .mene::after, .lien-fleche:hover::after { transform: translateX(5px); }
.lien-fleche { text-decoration: none; }

/* ── La bande d'appel qui referme chaque page ────────────────────────────── */
.bande-appel {
  padding: clamp(70px, 10vw, 118px) 0;
  border-top: 1px solid var(--line);
  background: radial-gradient(ellipse at 50% 0%, rgba(18, 190, 201, 0.09), transparent 62%);
}
.bande-appel h2 { text-wrap: balance; }
.trio-promesses {
  display: grid; gap: 20px; margin-top: 44px;
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
}
.promesse {
  padding: 26px 24px; border-radius: var(--radius);
  border: 1px solid var(--line); border-top: 2px solid var(--accent);
  background: rgba(255, 255, 255, 0.022);
  display: grid; gap: 9px; align-content: start;
}
.promesse strong { font-size: 1.04rem; font-weight: 700; }
.promesse p { color: var(--ink-soft); font-size: 0.93rem; line-height: 1.64; }

/* ═══════════════════════════════════════════════════════════════════════════
   LA GALERIE D'ÉCRANS.

   Douze écrans de l'application, DESSINÉS en HTML et non photographiés. Ce
   choix n'est pas une coquetterie : une capture se périme au premier changement
   d'interface, pèse lourd, floute au zoom, ne se traduit pas et ne dit rien à un
   lecteur d'écran. Dessinés, ils restent nets, se corrigent en une ligne, et le
   texte qu'ils portent est du vrai texte.

   ⚠ CE QU'ILS NE DOIVENT JAMAIS DEVENIR : une interface qui a l'air utilisable.
   Les boutons ne sont pas des boutons, le code du pass n'est pas scannable, et
   les chiffres sont des exemples. Tout ce bloc est `pointer-events: none` à
   l'intérieur de la vignette, et les valeurs affichées sont rondes exprès.
   ═══════════════════════════════════════════════════════════════════════════ */

.galerie { padding: clamp(56px, 8vw, 96px) 0; }
.entete-galerie { margin: 0 0 38px; }
.entete-galerie:not(:first-child) { margin-top: clamp(64px, 9vw, 110px); }
.entete-galerie h2 { font-size: clamp(1.7rem, 3.6vw, 2.5rem); }
.entete-galerie p { color: var(--ink-soft); margin-top: 12px; max-width: 62ch; }

.grille-ecrans {
  display: grid; gap: clamp(18px, 2.6vw, 30px);
  grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
}

.carte-ecran {
  display: grid; gap: 16px; justify-items: center;
  padding: 22px 16px 20px; border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.022);
  border: 1px solid var(--line);
  color: inherit; font: inherit; text-align: center; cursor: pointer;
  transition: transform 0.45s var(--sortie), border-color 0.4s ease, background 0.4s ease;
}
.carte-ecran:hover, .carte-ecran:focus-visible {
  transform: translateY(-6px);
  border-color: rgba(18, 190, 201, 0.42);
  background: rgba(18, 190, 201, 0.05);
}
.nom-ecran { display: grid; gap: 3px; font-weight: 700; font-size: 0.97rem; }
.nom-ecran em {
  font-style: normal; font-weight: 500;
  /* Même mesure que `.agrandir` : 4,39:1 sur le fond des cartes. C'est du texte
     de lecture — la phrase qui explique ce que fait l'écran. */
  font-size: 0.8rem; color: var(--ink-soft);
}

/* La vignette : un téléphone, en plus sobre que celui de l'accueil — douze
   châssis brillants côte à côte feraient une vitrine de magasin. */
.mini-tel {
  width: 100%; max-width: 186px;
  border-radius: 26px; padding: 7px;
  background: linear-gradient(160deg, #17373f, #061c22 62%);
  border: 1px solid var(--line-fort);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
  transition: box-shadow 0.45s ease;
}
.carte-ecran:hover .mini-tel { box-shadow: 0 24px 54px rgba(0, 0, 0, 0.55), 0 0 40px rgba(18, 190, 201, 0.16); }
.mini-ecran {
  aspect-ratio: 9 / 18;
  border-radius: 20px; overflow: hidden;
  background: var(--app-fond);
  display: flex; flex-direction: column;
  /* Rien là-dedans n'est cliquable : c'est une image faite de texte. */
  pointer-events: none;
  font-size: 0.86em;
}
.mini-ecran.sombre { background: #020c10; }
.mini-ecran .vue-corps { padding: 6px 10px 10px; gap: 6px; }
.mini-ecran .barre-etat { padding: 14px 12px 3px; font-size: 0.5rem; }
.mini-ecran .titre-app { font-size: 0.85rem; }
.mini-ecran .carte-app, .mini-ecran .formule-app, .mini-ecran .rdv-app { padding: 8px 9px; gap: 8px; }
.mini-ecran .vignette { width: 32px; height: 32px; border-radius: 10px; font-size: 0.56rem; }
.mini-ecran .carte-texte strong { font-size: 0.7rem; }
.mini-ecran .carte-texte span { font-size: 0.56rem; }
.mini-ecran .puce-app { font-size: 0.53rem; padding: 5px 9px; }
.mini-ecran .bouton-app { padding: 8px; font-size: 0.6rem; }
.mini-ecran .ligne-contrat { font-size: 0.56rem; padding-bottom: 5px; }
.mini-ecran .pass-app { padding: 12px; gap: 9px; }
/* Le code du pass prenait un carré plein — près de la moitié de l'écran. Il
   reste reconnaissable en étant nettement plus petit. */
.mini-ecran .code-app { width: 74%; margin: 0 auto; }
.mini-ecran .note-app { font-size: 0.55rem; margin-top: 8px; }
.mini-ecran .banniere-fiche { height: 38px; }
.mini-ecran .carte-geo { height: 74px; }
.mini-ecran .viseur { width: 66%; }
/* À 150 px de large, une rangée « heure + nom + état » se replie en colonne et
   l'écran cesse de ressembler à un écran. On force la rangée à tenir : l'état
   rétrécit, et un nom trop long s'abrège plutôt que de pousser le reste. */
.mini-ecran .etat-app { font-size: 0.46rem; padding: 3px 6px; letter-spacing: 0.06em; flex: none; }
.mini-ecran .heure-app { font-size: 0.6rem; flex: none; }
.mini-ecran .carte-texte { flex: 1 1 auto; min-width: 0; }
.mini-ecran .carte-texte strong,
.mini-ecran .carte-texte span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mini-ecran .alerte-app { font-size: 0.52rem; padding: 6px 9px; }
.mini-ecran .prix-app { font-size: 0.62rem; flex: none; }
.mini-ecran .chiffre-app span { font-size: 0.48rem; }
.mini-ecran .chiffre-app strong { font-size: 0.74rem; }
.mini-ecran .sous-titre-app { font-size: 0.54rem; }
.mini-ecran .case-app { font-size: 0.5rem; }
/* L'état d'une ligne (« Confirmé », « À jour ») coûte trop de largeur dans une
   vignette : il abrégeait les noms à « Ato… ». On le retire de la VIGNETTE et on
   le rend dans la LOUPE — la vignette donne l'allure, la loupe donne le détail.
   C'est la même hiérarchie que sur l'application : la liste, puis la fiche. */
.mini-ecran .rdv-app .etat-app,
.mini-ecran .carte-app .etat-app { display: none; }
.loupe-tel .mini-ecran .rdv-app .etat-app,
.loupe-tel .mini-ecran .carte-app .etat-app { display: inline-block; font-size: 0.55rem; padding: 4px 8px; }
.loupe-tel .mini-ecran .carte-texte strong,
.loupe-tel .mini-ecran .carte-texte span { white-space: normal; }

/* Dans la loupe, on redonne à l'écran ses vraies proportions : c'est le seul
   endroit où l'on a la place de le montrer tel qu'il est. */
.loupe-tel .mini-ecran .vue-corps { padding: 10px 14px 14px; gap: 9px; }
.loupe-tel .mini-ecran .titre-app { font-size: 1.05rem; }

/* ── Les pièces d'interface que les écrans réutilisent ───────────────────── */
.sous-titre-app { font-size: 0.6rem; color: var(--ink-soft); margin-top: -4px; }
.note-etoile { color: var(--ecume); font-weight: 700; }

.champ-faux {
  font-size: 0.6rem; color: var(--ink-faint);
  padding: 8px 11px; border-radius: 10px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--app-trait);
}
.champ-faux.saisie-code { text-align: center; letter-spacing: 0.14em; font-weight: 700; color: var(--ink-soft); }

.bouton-app {
  padding: 10px; border-radius: 12px; text-align: center;
  font-size: 0.66rem; font-weight: 800;
  background: var(--accent); color: #03191d;
}
.bouton-app.fil { background: transparent; border: 1px solid var(--line-fort); color: var(--ink-soft); }

.formule-app {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 11px; border-radius: 13px;
  background: var(--app-carte); border: 1px solid var(--app-trait);
}
.formule-app.active { border-color: rgba(18, 190, 201, 0.45); background: rgba(18, 190, 201, 0.09); }
.formule-app.estompe { opacity: 0.45; }

.ligne-contrat {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  font-size: 0.62rem; color: var(--ink-soft);
  padding-bottom: 7px; border-bottom: 1px solid var(--app-trait);
}
.ligne-contrat strong { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }
.ligne-contrat.fort { color: var(--ink); }
.ligne-contrat.fort strong { color: var(--ecume); font-size: 0.78rem; }

.case-app { display: flex; align-items: center; gap: 8px; font-size: 0.58rem; color: var(--ink-soft); }
.case-app i {
  width: 14px; height: 14px; flex: none; border-radius: 4px;
  background: var(--accent);
  /* Le crochet, dessiné plutôt que posé en caractère : un caractère hériterait
     de la police et changerait de dessin d'un appareil à l'autre. */
  clip-path: polygon(14% 46%, 8% 54%, 38% 84%, 92% 28%, 84% 20%, 38% 68%);
}

.duo-chiffres { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.chiffre-app {
  display: grid; gap: 3px; padding: 11px 12px; border-radius: 13px;
  background: var(--app-carte); border: 1px solid var(--app-trait);
}
/* Le libellé d'un chiffre dans une maquette d'écran. Sa TAILLE est volontaire —
   c'est un téléphone dessiné à l'échelle, l'agrandir casserait la maquette — mais
   sa couleur donnait 3,66:1 sur le fond de carte de l'application. `--ink-soft`
   monte à 7,67:1 sans toucher à l'échelle. */
.chiffre-app span { font-size: 0.53rem; color: var(--ink-soft); }
.chiffre-app strong { font-size: 0.86rem; font-weight: 800; font-variant-numeric: tabular-nums; }

.alerte-app {
  font-size: 0.58rem; font-weight: 700; padding: 8px 11px; border-radius: 10px;
  background: rgba(255, 176, 92, 0.12); border: 1px solid rgba(255, 176, 92, 0.32);
  color: #ffc888;
}
.etat-app.attente { background: rgba(255, 176, 92, 0.16); color: #ffc888; }

.banniere-fiche {
  height: 52px; border-radius: 13px; flex: none;
  background: linear-gradient(120deg, var(--accent-deep), var(--large) 60%, var(--lagon));
  opacity: 0.55;
}

/* La carte de Marseille : un aplat et cinq pastilles. Elle évoque, elle ne
   cartographie pas — une vraie carte serait fausse à cette taille. */
.carte-geo {
  position: relative; height: 92px; border-radius: 13px; flex: none;
  background: linear-gradient(160deg, #0b2f3a, #061c22);
  border: 1px solid var(--app-trait); overflow: hidden;
}
.carte-geo .trait-cote {
  position: absolute; inset: auto -10% -22% -10%; height: 56%;
  border-radius: 50% 50% 0 0;
  background: linear-gradient(180deg, rgba(47, 108, 179, 0.34), rgba(18, 190, 201, 0.12));
}
.lieu {
  position: absolute; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 0 3px rgba(18, 190, 201, 0.18);
  animation: pulse-lieu 3.4s ease-in-out infinite;
}
.lieu.l1 { top: 22%; left: 26%; }
.lieu.l2 { top: 44%; left: 58%; animation-delay: 0.6s; background: var(--lagon); box-shadow: 0 0 0 3px rgba(61, 203, 178, 0.18); }
.lieu.l3 { top: 30%; left: 76%; animation-delay: 1.2s; }
.lieu.l4 { top: 62%; left: 34%; animation-delay: 1.8s; background: var(--mer); box-shadow: 0 0 0 3px rgba(188, 221, 238, 0.16); }
.lieu.l5 { top: 16%; left: 52%; animation-delay: 2.4s; }
@keyframes pulse-lieu { 50% { transform: scale(1.35); } }
@media (prefers-reduced-motion: reduce) { .lieu { animation: none; } }

/* Le viseur du scanner : quatre coins et un rayon qui balaie. C'est l'image que
   tout le monde reconnaît, et elle dit « on est en train de scanner » sans mot. */
.viseur {
  position: relative; width: 78%; aspect-ratio: 1; margin: 6px auto;
  border-radius: 14px;
}
.viseur i {
  position: absolute; width: 20px; height: 20px;
  border: 2px solid var(--accent); border-radius: 4px;
}
.viseur i:nth-child(1) { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.viseur i:nth-child(2) { top: 0; right: 0; border-left: 0; border-bottom: 0; }
.viseur i:nth-child(3) { bottom: 0; left: 0; border-right: 0; border-top: 0; }
.viseur i:nth-child(4) { bottom: 0; right: 0; border-left: 0; border-top: 0; }
.viseur .rayon {
  position: absolute; left: 8%; right: 8%; top: 12%; height: 2px;
  background: linear-gradient(90deg, transparent, var(--ecume), transparent);
  box-shadow: 0 0 14px var(--accent);
  animation: balaye 2.6s ease-in-out infinite;
}
@keyframes balaye { 50% { top: 84%; } }
@media (prefers-reduced-motion: reduce) { .viseur .rayon { animation: none; } }

.note-galerie {
  margin-top: clamp(44px, 6vw, 72px);
  padding: 26px 30px; border-radius: var(--radius);
  border-left: 2px solid var(--line-fort);
  color: var(--ink-faint); font-size: 0.95rem; line-height: 1.7; max-width: 74ch;
}

/* ── La loupe ─────────────────────────────────────────────────────────────
   `<dialog>` plutôt qu'un `div` : le navigateur enferme le focus, Échap ferme,
   et le reste de la page devient inerte. Trois comportements qu'on réécrirait
   mal à la main, et qu'on oublierait de tester. */
.loupe {
  width: min(880px, 92vw); max-height: 88vh;
  padding: 0; border: 1px solid var(--line-fort); border-radius: var(--radius-lg);
  background: var(--ground-2); color: var(--ink);
  box-shadow: 0 50px 120px rgba(0, 0, 0, 0.7);
  overflow: visible;
}
.loupe::backdrop { background: rgba(2, 10, 14, 0.8); backdrop-filter: blur(6px); }
.loupe[open] { animation: ouvre-loupe 0.34s var(--sortie); }
@keyframes ouvre-loupe { from { opacity: 0; transform: translateY(14px) scale(0.97); } }
@media (prefers-reduced-motion: reduce) { .loupe[open] { animation: none; } }

.loupe-corps {
  display: grid; grid-template-columns: minmax(0, 250px) minmax(0, 1fr);
  gap: clamp(22px, 4vw, 44px);
  padding: clamp(26px, 4vw, 42px);
  max-height: 88vh; overflow-y: auto;
}
@media (max-width: 700px) { .loupe-corps { grid-template-columns: 1fr; justify-items: center; text-align: center; } }
.loupe-tel { width: 100%; max-width: 222px; justify-self: center; }
.loupe-tel .mini-tel { max-width: none; }
.loupe-tel .mini-ecran { font-size: 1em; }
.loupe-texte { align-self: center; display: grid; gap: 16px; }
.loupe-texte h3 { font-size: clamp(1.4rem, 3vw, 2rem); letter-spacing: -0.025em; text-wrap: balance; }
.loupe-texte p { color: var(--ink-soft); line-height: 1.76; font-size: 1.01rem; }

.ferme-loupe {
  position: absolute; top: -14px; right: -14px; z-index: 2;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--ground-3); border: 1px solid var(--line-fort);
  color: var(--ink); font-size: 1.4rem; line-height: 1; cursor: pointer;
  transition: background 0.25s ease, transform 0.25s var(--sortie);
}
.ferme-loupe:hover { background: var(--accent); color: #03191d; transform: rotate(90deg); }

/* ═══════════════════════════════════════════════════════════════════════════
   « VOUS ÊTES DE QUEL CÔTÉ ? » ET L'AIGUILLAGE DU CONTACT — 18/09/2026.

   Deux ajouts qui répondent au même reproche : le site faisait lire avant de
   servir. Sur l'accueil, on demande maintenant tout de suite de quel côté on
   est ; sur la page contact, on nomme trois portes au lieu d'une adresse
   fourre-tout.
   ═══════════════════════════════════════════════════════════════════════════ */

.entree-choix { max-width: 62ch; }

.deux-cotes {
  display: grid; gap: clamp(18px, 2.4vw, 26px); margin-top: 46px;
  grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
}

.cote-carte {
  display: grid; gap: 16px; align-content: start;
  padding: clamp(28px, 3.4vw, 40px); border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  text-decoration: none; color: inherit;
  position: relative; overflow: hidden;
  transition: transform 0.45s var(--sortie), border-color 0.45s ease;
}
/* Les deux côtés ne portent PAS la même teinte, et c'est le seul endroit du
   site où deux couleurs s'opposent : le vert d'eau des bords pour le commerce
   (celui qu'on touche), le bleu du large pour le client (celui qui vient).
   Toutes deux marines — la marque n'a pas d'autre famille. */
.cote-carte.pro { background: linear-gradient(165deg, rgba(61, 203, 178, 0.09), transparent 58%); }
.cote-carte.client { background: linear-gradient(165deg, rgba(47, 108, 179, 0.12), transparent 58%); }
.cote-carte::before {
  content: ''; position: absolute; inset: 0 auto 0 0; width: 3px;
  transition: opacity 0.4s ease; opacity: 0.55;
}
.cote-carte.pro::before { background: linear-gradient(180deg, var(--lagon), transparent); }
.cote-carte.client::before { background: linear-gradient(180deg, var(--large), transparent); }
.cote-carte:hover, .cote-carte:focus-visible { transform: translateY(-5px); border-color: var(--line-fort); }
.cote-carte:hover::before, .cote-carte:focus-visible::before { opacity: 1; }

.cote-marque {
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.15em; text-transform: uppercase;
}
.cote-carte.pro .cote-marque { color: var(--lagon); }
.cote-carte.client .cote-marque { color: var(--mer); }
.cote-carte h3 { font-size: clamp(1.3rem, 2.4vw, 1.75rem); letter-spacing: -0.025em; text-wrap: balance; }

/* ⚠ UNE LISTE NUMÉROTÉE PARCE QUE C'EST UN ORDRE, pas pour décorer : on crée sa
   formule AVANT que quelqu'un s'abonne, et on scanne APRÈS. Si l'ordre cessait
   de compter, les numéros devraient disparaître. */
.etapes-simples { display: grid; gap: 14px; counter-reset: pas; list-style: none; margin-top: 4px; }
.etapes-simples li {
  display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 13px; align-items: start;
  color: var(--ink-soft); font-size: 0.95rem; line-height: 1.6;
}
/* Le contenu est DANS un `span` : sans lui, le texte qui suit le `<strong>`
   devient un second élément de grille et retombe dans la colonne du numéro. */
.etapes-simples li > span { min-width: 0; padding-top: 2px; }
.etapes-simples li::before {
  counter-increment: pas; content: counter(pas);
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 0.72rem; font-weight: 800; font-variant-numeric: tabular-nums;
  border: 1px solid var(--line-fort); color: var(--ink);
}
.cote-carte.pro .etapes-simples li::before { border-color: rgba(61, 203, 178, 0.45); color: var(--lagon); }
.cote-carte.client .etapes-simples li::before { border-color: rgba(155, 185, 221, 0.45); color: var(--mer); }
.etapes-simples strong { color: var(--ink); font-weight: 700; }

#en-trois-etapes .cote-carte { max-width: 760px; }
#en-trois-etapes .cote-carte:hover { transform: none; border-color: var(--line); }

.cote-prix {
  font-size: 0.88rem; line-height: 1.6; color: var(--ink-faint);
  padding-top: 16px; border-top: 1px solid var(--line);
}

/* ── L'aiguillage du contact ─────────────────────────────────────────────── */
.aiguillage {
  display: grid; gap: 16px; margin-top: 44px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 720px) { .aiguillage { grid-template-columns: 1fr; } }
.voie-contact {
  display: flex; gap: 18px; align-items: flex-start;
  padding: 28px 26px; border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--line);
  text-decoration: none; color: inherit;
  transition: transform 0.4s var(--sortie), border-color 0.4s ease, background 0.4s ease;
}
.voie-contact:hover, .voie-contact:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(18, 190, 201, 0.45);
  background: rgba(18, 190, 201, 0.055);
}
/* La troisième carte tient toute la largeur : c'est le repli, et un repli doit
   se voir plus qu'une option parmi trois. */
.voie-contact.large { grid-column: 1 / -1; }

.qui {
  width: 48px; height: 48px; flex: none; border-radius: 15px;
  display: grid; place-items: center;
  font-size: 0.86rem; font-weight: 800; color: #03191d;
  background: linear-gradient(140deg, var(--ecume), var(--accent));
}
.qui.lagon { background: linear-gradient(140deg, var(--lagon), var(--primary)); }
.qui.mer { background: linear-gradient(140deg, var(--mer), var(--large)); }

.voie-corps { display: grid; gap: 7px; min-width: 0; }
.voie-sujet {
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--accent);
}
.voie-contact h3 { font-size: 1.2rem; font-weight: 700; letter-spacing: -0.02em; }
.voie-contact p { color: var(--ink-soft); font-size: 0.94rem; line-height: 1.62; }
.voie-contact strong { color: var(--ink); }
.adresse {
  margin-top: 5px; font-weight: 700; color: var(--ecume);
  font-size: 0.94rem; word-break: break-word;
}

.delai-reponse {
  margin-top: 34px; padding: 22px 26px; border-radius: var(--radius);
  border-left: 2px solid var(--line-fort);
  color: var(--ink-faint); font-size: 0.96rem; line-height: 1.7; max-width: 74ch;
}
.delai-reponse strong { color: var(--ink); }

/* ── Le formulaire, en second ────────────────────────────────────────────── */
.formulaire-contact { max-width: 660px; margin-top: 40px; display: grid; gap: 18px; }
.deux-champs { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 560px) { .deux-champs { grid-template-columns: 1fr; } }
.destinataire {
  margin-top: 9px; font-size: 0.88rem; color: var(--accent); font-weight: 600;
}
.note-formulaire { color: var(--ink-faint); font-size: 0.86rem; line-height: 1.6; }
/* Le lien de cette note est dans un `<p>` hors de `main p` ? Non — il y est.
   Mais `--ink-faint` l'entoure, et l'accent seul ne suffirait pas à le
   distinguer pour qui ne voit pas la couleur : le soulignement est hérité de la
   règle générale, on ne redéfinit ici que la couleur du texte autour. */
.note-formulaire a { color: var(--accent); }

/* Le repère de clic sur une vignette. Il est là AU REPOS, discrètement, et se
   révèle au survol : un repère qui n'apparaît qu'au survol ne sert à rien sur
   un écran tactile, où il n'y a pas de survol. */
.agrandir {
  order: 3;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  /* `--ink-faint` donnait 4,39:1 sur le fond des cartes — sous le seuil AA, de
     peu, mais sur un libellé qui annonce une action. */
  color: var(--ink-soft);
  display: inline-flex; align-items: center; gap: 6px;
  transition: color 0.3s ease;
}
.agrandir::before {
  content: ''; width: 13px; height: 13px;
  border: 1.5px solid currentColor; border-radius: 3px;
  box-shadow: 4px 4px 0 -1.5px var(--ground), 4px 4px 0 0 currentColor;
}
.carte-ecran { grid-template-rows: auto auto auto; }
.carte-ecran .nom-ecran { order: 2; }
.carte-ecran .mini-tel { order: 1; }
.carte-ecran:hover .agrandir, .carte-ecran:focus-visible .agrandir { color: var(--accent); }

/* Le geste porté par une notification, tel qu'il apparaît dans l'application.
   Encadré et non plein : c'est un recours, pas l'action principale de l'écran —
   un bouton plein ici donnerait envie d'appuyer, ce qui est exactement ce qu'on
   ne veut pas d'un geste qui renouvelle un code. */
.geste-app {
  align-self: flex-start;
  font-size: 0.58rem; font-weight: 800;
  padding: 7px 12px; border-radius: 11px;
  border: 1px solid rgba(18, 190, 201, 0.5);
  color: var(--accent);
}

/* ═══════════════════════════════════════════════════════════════════════════
   CE QUE LA POLITIQUE DE SÉCURITÉ NOUS OBLIGE À ÉCRIRE ICI — 12/10/2026.

   Ces règles n'ont aucune ambition esthétique : elles remplacent, une à une,
   les soixante-six déclarations qui vivaient dans des attributs `style="…"`.

   POURQUOI ELLES ONT DÛ DÉMÉNAGER. `netlify.toml` pose
   `style-src 'self' https://fonts.googleapis.com`, sans `'unsafe-inline'`.
   Or un attribut `style=""` EST du style inline au sens de la CSP : le
   navigateur l'ignore purement et simplement. Rien ne le signale — pas
   d'erreur visible, pas de page cassée, juste des marges qui sautent et un
   `display:none` qui ne cache plus rien.

   ET ÇA NE SE VOYAIT PAS EN LOCAL. `python3 -m http.server` ne pose aucun
   en-tête : le site était donc juste sur la machine et faux une fois en ligne.
   Vérifié le 12/10 en rejouant les en-têtes exacts de `netlify.toml` devant un
   navigateur — le `--retard` revenait vide, le logotype du pied passait de
   18,4 à 23,2 px, et le pot de miel du formulaire de contact s'affichait.

   L'AUTRE SOLUTION ÉTAIT D'AJOUTER `'unsafe-inline'`. Elle tenait en un mot et
   rouvrait précisément ce que la CSP ferme. Le site n'a aucune raison d'en
   avoir besoin : il n'engendre pas une ligne de HTML à l'exécution.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Les retards de la cascade d'apparition ──────────────────────────────────
   `--retard` est lu par `.apparait` (transition-delay) et par `.ligne-masque`
   (animation-delay). Les valeurs ne sont pas rondes parce qu'elles ont été
   réglées à l'œil, élément par élément : les reprendre telles quelles garantit
   que le mouvement est le même qu'avant ce déménagement. Le nom porte les
   centièmes de seconde. */
.retard-5  { --retard: .05s; }
.retard-6  { --retard: .06s; }
.retard-8  { --retard: .08s; }
.retard-12 { --retard: .12s; }
.retard-13 { --retard: .13s; }
.retard-14 { --retard: .14s; }
.retard-16 { --retard: .16s; }
.retard-17 { --retard: .17s; }
.retard-18 { --retard: .18s; }
.retard-20 { --retard: .20s; }
.retard-21 { --retard: .21s; }
.retard-24 { --retard: .24s; }
.retard-29 { --retard: .29s; }
.retard-30 { --retard: .30s; }
.retard-36 { --retard: .36s; }

/* ── Les écarts verticaux posés à la main ───────────────────────────────────
   Ce sont des réglages typographiques ponctuels, décidés à l'œil sur un
   paragraphe précis. Les valeurs sont celles d'avant, au pixel. */
.marge-10 { margin-top: 10px; }
.marge-14 { margin-top: 14px; }
.marge-18 { margin-top: 18px; }
.marge-20 { margin-top: 20px; }
.marge-24 { margin-top: 24px; }
.marge-26 { margin-top: 26px; }
.marge-32 { margin-top: 32px; }
.marge-36 { margin-top: 36px; }
.marge-38 { margin-top: 38px; }
.marge-40 { margin-top: 40px; }
.marge-44 { margin-top: 44px; }

/* ── LE POT DE MIEL. La règle la plus importante de ce bloc ──────────────────
   Un champ que seul un robot remplit, et que personne ne doit voir. Tant qu'il
   était caché par `style="display:none"`, la CSP le rendait VISIBLE en ligne :
   le formulaire de contact aurait affiché « Ne remplissez pas ceci : » suivi
   d'un champ vide, à tous les visiteurs. `netlify-honeypot` continue, lui, de
   fonctionner — c'est bien l'affichage qui était cassé, pas le piège. */
.pot-de-miel { display: none; }

/* ── Trois cas uniques ───────────────────────────────────────────────────────
   Un bouton d'envoi qui occupe toute la largeur de son formulaire ; un bloc de
   texte qu'on empêche de s'étaler sur toute la largeur de la page ; et la
   seconde colonne du pied du pass, alignée à droite face à la première. */
.bouton-large { width: 100%; justify-content: center; }
.bloc-etroit { max-width: 760px; }
.pass-pied > div:last-child { text-align: right; }

/* Le logotype du pied est plus petit que celui de l'en-tête : il signe la page,
   il ne la titre pas. */
footer .logotype { font-size: 1.15rem; }

/* ── Les liens à l'intérieur d'un paragraphe — 12/10/2026 ───────────────────
   Le site n'en avait aucun jusqu'ici : tous ses liens étaient des boutons, des
   entrées de menu ou des liens de pied, tous stylés à part. Les pages 404 et
   « merci » en ont introduit, et ils se sont affichés dans le bleu souligné par
   défaut du navigateur — la seule couleur de toute la page à n'appartenir pas
   à la palette.

   Le soulignement est CONSERVÉ, et décalé pour ne pas couper les jambages. Il
   n'est pas décoratif : sans lui, un lien dans un paragraphe ne se signale plus
   que par sa couleur, et ne se voit donc plus du tout pour qui ne distingue pas
   le turquoise du blanc cassé. */
main p a:not(.bouton) {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: rgba(18, 190, 201, 0.45);
  text-underline-offset: 3px;
  transition: color 0.25s ease, text-decoration-color 0.25s ease;
}
main p a:not(.bouton):hover,
main p a:not(.bouton):focus-visible {
  color: var(--ecume);
  text-decoration-color: var(--ecume);
}

/* ═══════════════════════════════════════════════════════════════════════════
   LES PAGES DE TEXTE LÉGAL — 12/10/2026.

   Mentions légales et politique de confidentialité. Ce sont les deux seules
   pages du site faites pour être LUES d'un bout à l'autre, et non parcourues :
   pas de carte, pas de colonne, pas d'effet. Une seule colonne, étroite.

   ⚠ LA LARGEUR EST LE RÉGLAGE QUI COMPTE. Au-delà d'environ 70 signes par
   ligne, l'œil perd le début de la ligne suivante et relit la même. Une page
   de conditions est déjà pénible à lire ; une page de conditions sur 1 200 px
   de large ne se lit pas du tout.
   ═══════════════════════════════════════════════════════════════════════════ */

.texte-legal { padding: clamp(28px, 5vw, 56px) 0 clamp(72px, 10vw, 120px); }
/* ⚠ LA COLONNE EST BRIDÉE, PAS RECENTRÉE. `.enveloppe` porte `margin-inline:
   auto` : lui donner simplement un `max-width` la centrait dans la page, et le
   texte se décalait alors de 166 px vers la droite par rapport au titre de la
   même page, posé dans une enveloppe pleine. On garde donc l'enveloppe telle
   qu'elle est, et c'est son CONTENU qu'on limite — la marge de gauche reste
   celle de tout le site. */
/* ⚠ EN `rem`, ET NON EN `ch`. Avec `ch`, chaque élément se mesurait dans SA
   propre taille de police : la colonne de texte s'arrêtait à 807 px et le trait
   de séparation des titres continuait jusqu'à 1 140 px, 300 px plus loin. Une
   largeur absolue les aligne tous — c'est la seule façon qu'un filet finisse où
   finit le texte qu'il sépare. 42 rem valent environ 72 signes dans cette
   police, ce qui est la cible. */
.texte-legal .enveloppe > * { max-width: 42rem; }

.texte-legal h2 {
  font-size: clamp(1.18rem, 2.4vw, 1.5rem);
  letter-spacing: -0.02em;
  margin: 52px 0 0;
  padding-top: 30px;
  border-top: 1px solid var(--line);
}
.texte-legal h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

.texte-legal p { margin: 16px 0 0; color: var(--ink-soft); line-height: 1.72; }
.texte-legal strong { color: var(--ink); font-weight: 700; }

.texte-legal ul { margin: 16px 0 0; padding-left: 0; list-style: none; }
.texte-legal li {
  position: relative;
  margin-top: 14px; padding-left: 26px;
  color: var(--ink-soft); line-height: 1.72;
}
/* Une puce dessinée plutôt qu'une puce de liste : elle se pose à la hauteur de
   la première ligne quelle que soit la taille du texte, ce que `list-style` ne
   garantit pas d'un navigateur à l'autre. */
.texte-legal li::before {
  content: ''; position: absolute; left: 6px; top: 0.72em;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
}

/* `code` sert ici à citer un nom technique exact — une adresse de courriel en
   gabarit, une clé de stockage. Il doit se distinguer sans crier. */
.texte-legal code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.88em;
  color: var(--ink);
  background: var(--ground-2);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 1px 6px;
}

.texte-legal .note-maj {
  margin-top: 56px; padding-top: 22px;
  border-top: 1px solid var(--line);
  font-size: 0.85rem; color: var(--ink-faint);
}

/* Les liens de ces pages suivent la règle générale des liens de paragraphe ;
   ceux des listes n'y étaient pas, et se seraient affichés en bleu système. */
.texte-legal li a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: rgba(18, 190, 201, 0.45);
  text-underline-offset: 3px;
  transition: color 0.25s ease, text-decoration-color 0.25s ease;
}
.texte-legal li a:hover, .texte-legal li a:focus-visible {
  color: var(--ecume); text-decoration-color: var(--ecume);
}
