/* ============================================================
   KLE — Site vitrine · Feuille de style
   ------------------------------------------------------------
   Site statique (zéro build, zéro SPA), fidèle au design system
   de l'app KLE. Un seul thème : Charbon. Tokens et composants
   repris de CODE_KLE/static/colors_and_type.css + kle.css.
   Le préfixe .lrv-* reprend la convention des maquettes.
   ============================================================ */

/* ── Thème Charbon (le seul utilisé sur le site) ── */
:root {
  --bg:            #0A0B0A;
  --surface:       #121212;
  --surface-2:     #1C1C1C;
  --surface-3:     #272727;
  --line:          rgba(220, 221, 178, 0.08);
  --line-strong:   rgba(220, 221, 178, 0.20);

  /* Échelle de beige — REMONTÉE le 05.08.2026 (arbitrage Val).
     Règle : on n'assombrit JAMAIS un texte beige sur fond sombre pour le mettre
     en retrait. Les niveaux se différencient par la police (mono vs sans) et le
     poids, pas par l'opacité. L'ancienne échelle descendait à #4d4e3a, soit
     2,3:1 sur le fond — la moitié du minimum WCAG AA (4,5:1), et illisible en
     vrai. Tous les niveaux sont désormais au-dessus de 7:1.
     Contrastes sur --bg : ink 14:1 · ink-2 11:1 · ink-3 9:1 · ink-4 7,6:1. */
  --ink:           #DCDDB2;
  --ink-2:         #c9caa3;
  --ink-3:         #b5b58c;
  --ink-4:         #a3a47e;

  --accent:        #C3453C;
  --accent-soft:   #3a1c1a;
  /* Blanc pur et non plus le rose pâle #f4dad6 (validé par Val le 06.08.2026) :
     sur le rouge de marque, l'ancien donnait 3,74:1, sous le minimum WCAG AA de
     4,5:1 — et c'était le texte du bouton principal, présent sur chaque page.
     Le blanc monte à 4,96:1. Profite aussi aux pastilles urgentes, au sticker de
     service et à la sélection de texte, qui utilisent la même variable. */
  --accent-ink:    #ffffff;

  --signature:     #E8B94E;
  --signature-ink: #2d1f06;
  --forest:        #0E2D2E;
  --forest-ink:    #DCDDB2;
  --ok:            #6B9A5A;

  --display: "Big Shoulders Display", "Franklin Gothic Heavy", Impact, sans-serif;
  --sans:    "Figtree", -apple-system, system-ui, sans-serif;
  --mono:    "JetBrains Mono", ui-monospace, monospace;

  --r-sm: 4px;
  --r-md: 6px;
  --r-lg: 10px;

  --page-max: 1280px;
  --page-pad: 56px;
}

/* ── Reset / base ── */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
}
img { max-width: 100%; display: block; }
a { color: var(--signature); text-decoration: none; cursor: pointer; transition: color .12s; }
a:hover { color: var(--ink); }
h1, h2, h3 { margin: 0; }
p { margin: 0; }
button { font-family: inherit; }

/* Navigation au clavier : sans ça, la tabulation avançait à l'aveugle. On ne
   pose l'anneau que sur :focus-visible, donc jamais après un clic souris. */
:focus-visible {
  outline: 2px solid var(--signature);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}
.lrv-btn:focus-visible, .nav-link:focus-visible, .lrv-input:focus-visible { outline-offset: 2px; }

::selection { background: var(--accent); color: var(--accent-ink); }
* { scrollbar-width: thin; scrollbar-color: var(--surface-3) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 4px; }
*::-webkit-scrollbar-thumb:hover { background: var(--line-strong); }
*::-webkit-scrollbar-track { background: transparent; }

/* ── Typographie ── */
.lrv-display {
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: 0.005em;
  line-height: 0.92;
  text-transform: uppercase;
}
.lrv-mono {
  font-family: var(--mono);
  font-feature-settings: "tnum", "ss01";
  letter-spacing: -0.01em;
}
.lrv-eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
}

/* ── Boutons ── */
.lrv-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.005em;
  padding: 10px 14px;
  border-radius: var(--r-md);
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.06s, background 0.12s, border 0.12s, color 0.12s, filter 0.12s;
  background: transparent;
  color: var(--ink);
  white-space: nowrap;
}
.lrv-btn:active { transform: translateY(1px); }
.lrv-btn.primary { background: var(--accent); color: var(--accent-ink); }
.lrv-btn.primary:hover { filter: brightness(1.08); color: var(--accent-ink); }
.lrv-btn.ghost { border-color: var(--line-strong); color: var(--ink-2); }
.lrv-btn.ghost:hover { background: var(--surface-2); color: var(--ink); }
.lrv-btn.subtle { color: var(--ink-2); font-weight: 500; }
.lrv-btn.subtle:hover { background: var(--surface-2); color: var(--ink); }

/* ── Pills / statuts ── */
.lrv-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 8px 3px;
  border-radius: 2px;
  white-space: nowrap;
  line-height: 1;
  border: 1px solid transparent;
}
.lrv-pill.en-test    { background: rgba(232, 185, 78, 0.16); color: var(--signature); }
.lrv-pill.validee    { background: rgba(143, 165, 107, 0.16); color: var(--ok); }
.lrv-pill.idee       { background: rgba(220, 221, 178, 0.10); color: var(--ink-2); }
.lrv-pill.urgent     { background: var(--accent); color: var(--accent-ink); }
.lrv-pill.signature  { background: rgba(232, 185, 78, 0.16); color: var(--signature); }
button.lrv-pill { cursor: pointer; }

/* ── Carte filet ── */
.lrv-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: background 0.12s, border 0.12s;
}
.lrv-card.hoverable:hover { border-color: var(--line-strong); background: var(--surface-2); }

/* ── Checkbox (décor) ── */
.lrv-check {
  width: 18px; height: 18px;
  border: 1.5px solid var(--line-strong);
  border-radius: 3px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  background: transparent;
}

/* ── Barre de progression ── */
.lrv-progress {
  width: 100%;
  height: 4px;
  background: var(--surface-3);
  border-radius: 999px;
  overflow: hidden;
}
.lrv-progress > span {
  display: block;
  height: 100%;
  background: var(--signature);
  border-radius: 999px;
  transition: width 0.6s cubic-bezier(.2,.7,.3,1);
}

/* ── Champs de formulaire ── */
.lrv-input {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  padding: 11px 13px;
  font-family: var(--sans);
  font-size: 14px;
  color: var(--ink);
  outline: none;
  transition: border-color 0.12s, background 0.12s;
}
.lrv-input:focus {
  border-color: var(--accent);
  background: color-mix(in oklab, var(--bg) 92%, var(--accent));
}
.lrv-input::placeholder { color: var(--ink-3); }

/* ── Sticker « Service aujourd'hui » ── */
.lrv-service-sticker {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  background: var(--accent); color: var(--accent-ink);
  border-radius: var(--r-md);
  transform: rotate(-1.4deg);
  font-family: var(--mono); font-size: 12px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; line-height: 1;
  box-shadow: 0 6px 18px rgba(195,69,60,0.28), 0 0 0 1px rgba(195,69,60,0.4);
}

/* ════════════════════════════════════════════════════════════
   NAV
   ════════════════════════════════════════════════════════════ */
.site-nav {
  position: sticky; top: 0; z-index: 20;
  background: var(--bg);
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px;
  padding: 16px var(--page-pad);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 12px; cursor: pointer; }
.brand__word { font-size: 32px; color: var(--ink); line-height: 1; }
.brand:hover .brand__word { color: var(--ink); }
.brand__tag {
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-3);
}
.site-nav__links { display: flex; align-items: center; gap: 2px; }
.nav-link {
  font-family: var(--sans); font-size: 13px; font-weight: 500;
  padding: 7px 14px; border-radius: 6px; color: var(--ink-2);
  transition: background .12s, color .12s;
}
/* nowrap : un libellé comprimé par le flex se repliait sur deux lignes et
   déformait la nav (« Histoire & Contact » entre 760 et 1000 px). */
.nav-link { white-space: nowrap; }
.nav-link:hover { color: var(--ink); }
.nav-link.active { background: var(--surface-2); color: var(--ink); font-weight: 600; }
/* Onglet secondaire (Patchlog) : présent, mais qui ne dispute pas la vedette aux
   cinq pages du parcours. On descend d'UN cran seulement, jusqu'à --ink-3 (9:1) :
   la règle du 05.08 interdit d'assombrir pour mettre en retrait, et l'esprit de
   cette règle est qu'aucun texte ne devienne pénible à lire. À l'état actif ou au
   survol, il reprend le traitement normal. */
.nav-link--soft { color: var(--ink-3); }
.nav-link--soft:hover, .nav-link--soft.active { color: var(--ink); }
.site-nav__cta { flex-shrink: 0; }

.nav-toggle { display: none; }

/* ════════════════════════════════════════════════════════════
   LAYOUT commun
   ════════════════════════════════════════════════════════════ */
.site-main { flex: 1; }
.wrap {
  max-width: var(--page-max);
  margin: 0 auto;
  padding-left: var(--page-pad);
  padding-right: var(--page-pad);
  box-sizing: border-box;
}
.section-head { display: flex; flex-direction: column; gap: 10px; }
.lead {
  font-family: var(--sans); font-size: 17px; line-height: 1.6;
  color: var(--ink-2); text-wrap: pretty;
}
.body-txt {
  font-family: var(--sans); font-size: 15px; line-height: 1.65;
  color: var(--ink-2); text-wrap: pretty;
}
.body-txt strong { color: var(--ink); }

/* ── Hero (Accueil) ── */
.hero {
  display: grid; grid-template-columns: 1fr minmax(360px, 600px);
  gap: 56px; align-items: center;
  padding: 72px var(--page-pad) 56px;
  max-width: var(--page-max); margin: 0 auto; box-sizing: border-box;
}
.hero__col { display: flex; flex-direction: column; gap: 24px; }
.hero h1 { font-size: clamp(44px, 5.5vw, 80px); color: var(--ink); text-wrap: balance; }
.hero__lead { max-width: 460px; }
.hero__actions { display: flex; gap: 12px; flex-wrap: wrap; }
.hero__pills { display: flex; gap: 8px; flex-wrap: wrap; }
.hero__actions .lrv-btn { font-size: 14px; padding: 12px 20px; }

/* ── Fausse fenêtre navigateur ── */
.browser {
  border: 1px solid var(--line-strong); border-radius: var(--r-lg);
  overflow: hidden; background: var(--surface); transform: rotate(.6deg);
}
.browser__bar {
  display: flex; align-items: center; gap: 6px;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
}
.browser__bar .b-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--surface-3); }
.browser__bar .b-title { margin-left: 12px; font-family: var(--mono); font-size: 12px; color: var(--ink-3); }
.browser__body { height: 380px; min-height: 300px; }

/* ── Zone image (placeholder screenshot) ── */
.shot {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 24px;
  background:
    repeating-linear-gradient(45deg, transparent 0 12px, rgba(220,221,178,0.02) 12px 24px),
    var(--surface-2);
  color: var(--ink-3);
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em;
  text-transform: uppercase; line-height: 1.6;
}
.shot img { width: 100%; height: 100%; object-fit: cover; }

/* Screenshots réels : remplissent leur cadre (comme les zones .shot) */
.spotlight__img img,
.import-block__img img,
.browser__body img,
.story-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── Bloc "section" générique ── */
.stack { display: flex; flex-direction: column; }
.pad-y { padding-top: 72px; padding-bottom: 72px; }
.stepper { display: inline-flex; align-items: center; gap: 2px; border: 1px solid var(--line-strong); border-radius: var(--r-md); overflow: hidden; }
.stepper__btn { width: 34px; height: 34px; border: none; background: var(--surface-2); color: var(--ink); font-size: 18px; line-height: 1; cursor: pointer; transition: background .12s; }
.stepper__btn:hover { background: var(--surface-3); }
.stepper__btn:active { transform: translateY(1px); }
.stepper__val { min-width: 48px; text-align: center; font-family: var(--mono); font-size: 17px; font-weight: 600; color: var(--ink); font-feature-settings: "tnum"; }

/* Coche générique (recettes cochées de l'atelier) */
.lrv-check.checked { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.lrv-check.checked::after { content: '✓'; font-size: 12px; line-height: 1; }

/* ── Cartes de pages / modules ── */
.card-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.card-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.page-card {
  padding: 24px; display: flex; flex-direction: column; gap: 12px;
  color: inherit;
}
.page-card .kicker { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; color: var(--signature); }
.page-card .title { font-family: var(--display); font-weight: 800; text-transform: uppercase; line-height: 0.92; letter-spacing: 0.005em; font-size: 22px; color: var(--ink); }
.page-card .desc { font-family: var(--sans); font-size: 13px; line-height: 1.55; color: var(--ink-2); }
.page-card .arrow { margin-top: auto; font-family: var(--mono); font-size: 13px; color: var(--ink-3); }
.module-card .title { font-size: 20px; }
.module-card { gap: 10px; }
/* Ce que le lecteur achète : module facturé (doré) ou compris dans le socle.
   C'est ce qui relie la page Produit à la page Tarifs. */
.module-card__in {
  margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--signature);
}
.module-card__in.is-socle { color: var(--ink-4); }

/* ── Bande CTA / sarcelle ── */
.cta-band { background: var(--forest); padding: 48px var(--page-pad); }
.cta-band__inner {
  max-width: 1168px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 32px; flex-wrap: wrap;
}
.cta-band h2 { font-size: 44px; color: var(--forest-ink); }

/* ── Produit : spotlights ── */
.spotlight { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.spotlight__txt { display: flex; flex-direction: column; gap: 16px; }
.spotlight__num { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; color: var(--signature); }
/* 400 px et non 340 : les captures d'interface sont denses, chaque pixel rendu
   compte pour que le texte reste lisible. Le ratio du cadre (~1,39) est celui
   des images recadrées, donc `cover` ne rogne quasiment rien. */
.spotlight__img { height: 400px; border: 1px solid var(--line-strong); border-radius: var(--r-lg); overflow: hidden; }
.spotlight h2 { font-size: 44px; color: var(--ink); }

/* ── Bloc import ── */
.import-block {
  /* 0,85 / 1,15 et non 1 / 1 : les trois onglets du scanner imposent une zone
     large, et l echelle de lecture depend directement de ce cadre. */
  display: grid; grid-template-columns: 0.85fr 1.15fr; gap: 56px; align-items: center;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 48px;
}
.import-block__img { height: 360px; border: 1px solid var(--line-strong); border-radius: var(--r-md); overflow: hidden; }

/* ── Ligne CTA bas de page ── */
.cta-line {
  display: flex; align-items: center; justify-content: space-between; gap: 32px; flex-wrap: wrap;
  border-top: 1px solid var(--line); padding-top: 40px;
}
.cta-line p {
  font-family: var(--mono); font-size: 13px; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--ink-2);
}

/* ── Méthode : bande + diagramme ── */
.method-hero { background: var(--forest); padding: 72px var(--page-pad); }
.method-hero__inner {
  max-width: 1168px; margin: 0 auto;
  display: grid; grid-template-columns: 1.1fr 1fr; gap: 64px; align-items: center;
}
.method-hero h1 { font-size: 60px; color: var(--forest-ink); text-wrap: balance; }
.method-hero .eyebrow-forest { color: rgba(220,221,178,.55); }
.method-hero p { color: rgba(220,221,178,.75); max-width: 480px; }
.flow { display: flex; flex-direction: column; gap: 10px; }
.flow__box {
  display: flex; align-items: center; gap: 14px;
  background: rgba(10,11,10,.4); border: 1px solid rgba(220,221,178,.15);
  border-radius: var(--r-md); padding: 16px 20px;
}
.flow__box .k { font-family: var(--mono); font-size: 12px; color: rgba(220,221,178,.5); width: 88px; flex-shrink: 0; }
.flow__box .v { font-family: var(--sans); font-size: 14px; color: var(--forest-ink); }
.flow__arrow { display: flex; justify-content: center; font-family: var(--mono); font-size: 14px; color: var(--signature); }

.method-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.method-3 .step { display: flex; flex-direction: column; gap: 8px; }
.method-3 .step .num { font-family: var(--mono); font-size: 22px; color: var(--signature); }
.method-3 .step .t { font-family: var(--sans); font-size: 15px; font-weight: 600; color: var(--ink); }
.method-3 .step .d { font-family: var(--sans); font-size: 13.5px; line-height: 1.55; color: var(--ink-2); }

.feature-card { padding: 26px; display: flex; flex-direction: column; gap: 12px; }
.feature-card .kicker { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; color: var(--signature); }
.feature-card .title { font-family: var(--display); font-weight: 800; text-transform: uppercase; line-height: 0.92; letter-spacing: 0.005em; font-size: 22px; color: var(--ink); }
.feature-card ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
/* Puce dessinée plutôt qu'un tiret cadratin écrit dans le texte : le tiret
   touchait le mot suivant et alourdissait la lecture. */
.feature-card li {
  font-family: var(--sans); font-size: 13.5px; line-height: 1.55; color: var(--ink-2);
  position: relative; padding-left: 16px;
}
.feature-card li::before {
  content: ''; position: absolute; left: 0; top: 0.55em;
  width: 5px; height: 5px; border-radius: 1px; background: var(--ink-4);
}

.stats-strip { border-top: 1px solid var(--line); padding-top: 32px; display: flex; justify-content: center; gap: 56px; flex-wrap: wrap; }
.stats-strip span { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }

/* ── Histoire & Contact ── */
.story-split { display: grid; grid-template-columns: 460px 1fr; gap: 64px; align-items: center; }
.story-photo { height: 480px; border-radius: var(--r-lg); overflow: hidden; }
.story-txt { display: flex; flex-direction: column; gap: 18px; }
/* Carte de marque : tient la place de la photo de Val, et renvoie chez LRV.
   Le logo EST le lien — aucune URL écrite, le nom est déjà dessus.
   Surcharge volontaire de `.story-photo img` (qui recadre en cover) — un logo
   ne se recadre pas, il se pose. */
.brand-card {
  display: flex; align-items: center; justify-content: center; padding: 40px;
  background: var(--surface); border: 1px solid var(--line);
  transition: background .12s, border-color .12s;
}
.brand-card img { width: 240px; max-width: 64%; height: auto; object-fit: contain; transition: transform .18s; }
.brand-card:hover { background: var(--surface-2); border-color: var(--line-strong); }
@media (prefers-reduced-motion: no-preference) {
.brand-card:hover img { transform: scale(1.03); }
}
.story-txt h1 { font-size: 64px; color: var(--ink); }
.contact-split { border-top: 1px solid var(--line); padding-top: 64px; display: grid; grid-template-columns: 1fr 440px; gap: 72px; align-items: start; }
.contact-txt { display: flex; flex-direction: column; gap: 18px; }
.contact-txt h2 { font-size: 64px; color: var(--ink); }
.contact-list { display: flex; flex-direction: column; gap: 11px; margin-top: 12px; }
.contact-list span { font-family: var(--sans); font-size: 14px; color: var(--ink-2); }
/* Les items de la liste (ceux sans classe) portent une puce dessinée ; le
   premier span est l'intitulé en mono et n'en veut pas. */
.contact-list span:not([class]) { position: relative; padding-left: 17px; display: block; }
.contact-list span:not([class])::before {
  content: ''; position: absolute; left: 0; top: 0.55em;
  width: 5px; height: 5px; border-radius: 1px; background: var(--signature);
}
.contact-form { padding: 32px; display: flex; flex-direction: column; gap: 14px; }
.contact-form h2 { font-size: 24px; color: var(--ink); }
.form-status { font-family: var(--sans); font-size: 13px; line-height: 1.5; }
.form-status.ok { color: var(--ok); }
.form-status.err { color: var(--accent); }

/* ── Patchlog ── */
.patch-head h1 { font-size: 64px; color: var(--ink); }
.patch-head .row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.patch-list { display: flex; flex-direction: column; }
.patch-row {
  display: grid; grid-template-columns: 120px 110px 1fr; gap: 20px;
  padding: 18px 0; border-bottom: 1px solid var(--line); align-items: baseline;
}
.patch-row .v { font-family: var(--mono); font-size: 13px; font-weight: 600; color: var(--signature); }
.patch-row .date { font-family: var(--mono); font-size: 12px; color: var(--ink-3); }
.patch-row .body { display: flex; flex-direction: column; gap: 4px; }
.patch-row .body .t { font-family: var(--sans); font-size: 14px; font-weight: 600; color: var(--ink); }
.patch-row .body .d { font-family: var(--sans); font-size: 13.5px; line-height: 1.55; color: var(--ink-2); }

/* ── Installer (page Installer) ──
   Les 6 fiches vivent en HTML : sans JavaScript, tout reste lisible et déplié.
   Le bloc « Sur cet appareil » n'apparaît que quand la détection a réussi. */
.inst-head h1 { font-size: 64px; color: var(--ink); }

.inst-warn {
  display: flex; align-items: flex-start; gap: 14px;
  background: rgba(232, 185, 78, 0.06);
  border: 1px solid rgba(232, 185, 78, 0.32);
  border-radius: var(--r-md); padding: 16px 18px;
}
.inst-warn .i {
  font-family: var(--display); font-weight: 800; font-size: 22px; line-height: 1;
  color: var(--signature); flex-shrink: 0; width: 14px; text-align: center;
}
.inst-warn p { font-family: var(--sans); font-size: 13.5px; line-height: 1.6; color: var(--ink-2); }
.inst-warn strong { color: var(--ink); }

.inst-here { flex-direction: column; gap: 14px; }
.inst-here__top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.inst-badge {
  align-items: center;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink); background: var(--surface-2);
  border: 1px solid var(--line-strong); border-radius: 999px; padding: 5px 11px;
}

.inst-case {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 24px;
  display: flex; flex-direction: column; gap: 13px;
}
.inst-slot .inst-case { border-color: var(--line-strong); }
.inst-case__k { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--signature); }
.inst-case.is-blocked .inst-case__k { color: var(--accent); }
.inst-case__t {
  font-family: var(--display); font-weight: 800; text-transform: uppercase;
  line-height: 0.92; letter-spacing: 0.005em; font-size: 24px; color: var(--ink);
}
.inst-steps { list-style: none; margin: 0; padding: 0; counter-reset: inst-st; display: flex; flex-direction: column; gap: 10px; }
/* Le <li> N'EST PAS une grille, et c'est délibéré (corrigé le 05.08.2026).
   En grid, chaque nœud texte anonyme devient un item : « Ouvre <a>my.kleapp.ch</a>
   et connecte-toi. » produisait 4 items (numéro, "Ouvre", le lien, la suite), si
   bien que le lien atterrissait dans la colonne de 24 px du numéro, écrasé et
   superposé au texte voisin. Le bug ne touchait que les étapes contenant une
   balise inline — les 6 chemins d'installation.
   Le numéro est donc sorti du flux ; le contenu reste du texte inline normal. */
.inst-steps li {
  counter-increment: inst-st;
  position: relative;
  padding-left: 36px;   /* 24 px de pastille + 12 px de gouttière */
  min-height: 22px;
  font-family: var(--sans); font-size: 14px; line-height: 1.55; color: var(--ink-2);
}
.inst-steps li::before {
  content: counter(inst-st);
  position: absolute; left: 0; top: 0;
  width: 24px; height: 22px;
  font-family: var(--mono); font-size: 12px; font-weight: 600; color: var(--ink-3);
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  display: grid; place-items: center;
}
.inst-steps li b { color: var(--ink); font-weight: 600; }
.inst-txt { font-family: var(--sans); font-size: 14px; line-height: 1.55; color: var(--ink-2); }
.inst-alt {
  font-family: var(--sans); font-size: 13px; line-height: 1.55; color: var(--ink-3);
  border-top: 1px solid var(--line); padding-top: 12px;
}
.inst-alt b { color: var(--ink-2); font-weight: 600; }
.inst-note { font-family: var(--mono); font-size: 12px; line-height: 1.6; letter-spacing: 0.03em; color: var(--ink-4); }

/* Le bouton « Installer KLE » amène la marche à suivre sous les yeux : sans ce
   clignement, un clic qui ne fait que défiler passe pour un clic sans effet. */
.inst-case.is-flash { border-color: var(--signature); background: color-mix(in oklab, var(--surface) 92%, var(--signature)); }
@media (prefers-reduced-motion: no-preference) {
.inst-case { transition: border-color .3s, background .3s; }
}

.inst-others { border-top: 1px solid var(--line); padding-top: 22px; }
.inst-others > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 12px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-2);
  transition: color .12s;
}
.inst-others > summary::-webkit-details-marker { display: none; }
.inst-others > summary::before { content: '\25B8'; color: var(--signature); }
.inst-others[open] > summary::before { content: '\25BE'; }
.inst-others > summary:hover { color: var(--ink); }
.inst-cases { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding-top: 20px; }
/* Sans cette règle, le repli du <details> ne marchait PAS (corrigé le 05.08.2026).
   Un <details> fermé masque ses enfants via un display implicite — que le
   `display: grid` ci-dessus écrase. Résultat : le bloc repliable mesurait 39 px
   (son seul summary) pendant que ses 1252 px de contenu s'affichaient par-dessus
   les sections suivantes. C'est ce qui superposait les six chemins au reste de la
   page. `install.js` retire `open` au chargement, donc l'état fermé est le cas
   NORMAL, pas un cas limite. */
.inst-others:not([open]) > .inst-cases { display: none; }

.inst-faq { display: flex; flex-direction: column; }
.inst-q { display: grid; grid-template-columns: 260px 1fr; gap: 28px; padding: 18px 0; border-bottom: 1px solid var(--line); }
.inst-q .q { font-family: var(--sans); font-size: 14.5px; font-weight: 600; color: var(--ink); }
.inst-q .a { font-family: var(--sans); font-size: 13.5px; line-height: 1.6; color: var(--ink-2); }
/* Un appel à l'action en fin de réponse se met sur sa propre ligne : noyé en fin
   de paragraphe, il se lit comme du texte et personne ne le clique.
   `width: fit-content` pour que la zone cliquable s'arrête au mot. */
.inst-q .a .faq-cta { display: block; width: fit-content; margin-top: 10px; font-weight: 600; }

/* ── Tarifs ──
   Le calculateur d'équipe réutilise .demo-seg et .stepper de la mini-démo :
   même geste, même rendu. Rien de neuf à apprendre pour l'œil. */
/* auto-fit : les cinq packs se repartissent seuls (cinq colonnes a 1280 px,
   quatre vers 1000, trois vers 760) sans une media query par palier. */
/* align-items: stretch (le défaut) et NON start : sans ça, chaque carte prenait
   la hauteur de son seul contenu (94 px d'écart entre la plus courte et la plus
   haute), et le `margin-top: auto` de .price-card__save n'avait aucun effet
   puisqu'il n'y avait pas d'espace libre à absorber. Les cartes d'une même rangée
   s'alignent maintenant, et la mention de bas se colle vraiment en bas. */
.price-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; align-items: stretch; }
.price-card {
  padding: 22px; display: flex; flex-direction: column; gap: 13px;
  /* Ce sont des <button> depuis qu'elles preremplissent le simulateur : on
     annule ce qu'un bouton impose et on rend le clic visible. */
  text-align: left; font-family: var(--sans); cursor: pointer; width: 100%;
}
.price-card:hover { border-color: var(--line-strong); }
.price-card:hover .price-card__p .n { color: var(--signature); }
.price-card__p .n { transition: color .12s; }
.price-card.is-reco { border-color: rgba(232, 185, 78, 0.45); background: color-mix(in oklab, var(--surface) 96%, var(--signature)); }
.price-card .kicker { font-family: var(--mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--signature); }
.price-card__p { display: flex; align-items: baseline; gap: 8px; }
.price-card__p .n {
  font-family: var(--display); font-weight: 800; font-size: 46px; line-height: 0.9;
  letter-spacing: 0.005em; color: var(--ink);
}
.price-card__p .u { font-family: var(--mono); font-size: 12px; color: var(--ink-3); }
.price-card__d { font-family: var(--sans); font-size: 13.5px; line-height: 1.55; color: var(--ink-2); }
.price-card ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; border-top: 1px solid var(--line); padding-top: 14px; }
/* Puce dessinée, pas un caractère : un tiret cadratin touchait le texte et
   passait pour une rature. En position ABSOLUE et non en grille : une grille
   fait de chaque enfant une cellule, donc un `<li>` contenant « <strong>+
   Projet</strong> : menus, matériel… » poussait la fin de la phrase dans la
   colonne de 5 px de la puce, un mot par ligne. */
.price-card li {
  font-family: var(--sans); font-size: 13.5px; line-height: 1.5; color: var(--ink-2);
  position: relative; padding-left: 16px;
}
.price-card li::before {
  content: ''; position: absolute; left: 0; top: 0.5em;
  width: 5px; height: 5px; border-radius: 1px; background: var(--ink-4);
}
.price-card.is-reco li::before { background: var(--signature); }
.price-card li strong { color: var(--ink); font-weight: 600; }
.price-card__save { margin-top: auto; font-family: var(--mono); font-size: 12px; letter-spacing: 0.03em; color: var(--ink-4); }

.addons { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.addon {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 20px; display: flex; flex-direction: column; gap: 8px;
}
.addon.is-base { border-color: var(--line-strong); }
.addon .k { font-family: var(--sans); font-size: 14px; font-weight: 600; color: var(--ink); }
.addon .p { font-family: var(--mono); font-size: 20px; font-weight: 600; color: var(--signature); font-feature-settings: "tnum"; }
.addon.is-base .p { color: var(--ink); }
.addon .d { font-family: var(--sans); font-size: 12.5px; line-height: 1.5; color: var(--ink-3); }

.tarif-calc { padding: 28px; display: flex; flex-direction: column; gap: 24px; }
.tarif-calc__ctl { display: flex; gap: 40px; flex-wrap: wrap; align-items: flex-end; }
.tarif-calc__out {
  display: flex; gap: 48px; flex-wrap: wrap;
  border-top: 1px solid var(--line-strong); padding-top: 20px;
}
.tarif-calc__note { font-family: var(--sans); font-size: 12.5px; line-height: 1.55; color: var(--ink-3); }

.tarif-bareme { display: flex; flex-direction: column; gap: 12px; }
.tarif-bareme__rows { display: flex; flex-wrap: wrap; gap: 10px; }
.tarif-bareme__rows span {
  font-family: var(--mono); font-size: 12px; color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px; padding: 7px 13px;
}
.tarif-bareme__rows b { color: var(--ink); font-weight: 600; }

/* ── Simulateur de tarif ──
   Deux étapes (composer, dimensionner) et une facture détaillée. Le barème est
   MARGINAL : le 1er siège plein tarif, chaque siège suivant au taux de sa
   tranche. Un taux unique appliqué à tous les sièges créerait une falaise (11
   sièges coûteraient moins que 10), voir le commentaire dans site.js. */
.sim-etape { display: grid; grid-template-columns: 34px 1fr; gap: 18px; align-items: start; }
.sim-etape__n {
  font-family: var(--mono); font-size: 13px; font-weight: 600;
  color: var(--signature); border: 1px solid var(--line-strong); border-radius: 50%;
  width: 34px; height: 34px; display: grid; place-items: center;
}
.sim-etape__corps { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

.mods { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.mod {
  text-align: left; font-family: var(--sans); cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 18px; display: flex; flex-direction: column; gap: 7px;
  transition: border-color .12s, background .12s;
}
.mod:hover { border-color: var(--line-strong); background: var(--surface-2); }
.mod__k { font-size: 14px; font-weight: 600; color: var(--ink); }
/* « Bientôt » : le module est vendu au prix affiché, il n'est pas encore livré.
   On marque le MODULE et pas le pack qui le contient — sinon 4 cartes sur 5
   portent le badge et l'offre paraît vide (arbitrage Val, 06.08.2026).
   Le simulateur, lui, reste pleinement opérationnel : le prix est arrêté. */
.mod__soon {
  display: inline-block; vertical-align: 1px; margin-left: 6px;
  font-family: var(--mono); font-size: 12px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--signature); background: rgba(232, 185, 78, .16);
  border-radius: 2px; padding: 1px 5px;
}
.mod__p { font-family: var(--mono); font-size: 19px; font-weight: 600; color: var(--ink-3); font-feature-settings: "tnum"; }
.mod__d { font-size: 12.5px; line-height: 1.5; color: var(--ink-3); }
.mod__etat {
  margin-top: auto; padding-top: 10px; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 12px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-4);
}
/* Coché : la bordure et le prix passent en doré, l'état dit « inclus ». */
.mod[aria-pressed="true"] {
  border-color: rgba(232, 185, 78, .5);
  background: color-mix(in oklab, var(--surface) 94%, var(--signature));
}
.mod[aria-pressed="true"] .mod__p { color: var(--signature); }
.mod[aria-pressed="true"] .mod__etat { color: var(--signature); }
/* Le socle est toujours pris : il porte donc la même marque dorée qu'un module
   coché, avec un cadre un peu plus épais pour dire qu'il ne se décoche pas. Le
   padding compense l'épaisseur, sinon sa boîte serait plus petite d'1 px. */
.mod.is-socle {
  cursor: default;
  border-width: 2px; padding: 17px;
  border-color: rgba(232, 185, 78, .55);
  background: color-mix(in oklab, var(--surface) 94%, var(--signature));
}
.mod.is-socle .mod__p, .mod.is-socle .mod__etat { color: var(--signature); }
.mod.is-socle:hover {
  border-color: rgba(232, 185, 78, .55);
  background: color-mix(in oklab, var(--surface) 94%, var(--signature));
}

.sim-hint { font-family: var(--sans); font-size: 13px; line-height: 1.55; color: var(--ink-2); min-height: 20px; }
.sim-hint b { color: var(--signature); font-weight: 600; }

.sim-sieges { display: flex; gap: 44px; flex-wrap: wrap; }
.sim-lbl { font-family: var(--sans); font-size: 13.5px; font-weight: 600; color: var(--ink); }
/* Le stepper est un inline-flex : dans une colonne flex il s etirait sur toute
   la largeur et laissait un rectangle vide a droite de ses boutons. */
.sim-sieges .stepper { align-self: flex-start; }
.sim-sub { font-family: var(--mono); font-size: 12px; line-height: 1.5; color: var(--ink-4); max-width: 210px; }
/* Sièges compta inertes tant que le module n'est pas pris. */
[data-sim-bloc-compta].is-off { opacity: .45; }
[data-sim-bloc-compta].is-off .stepper__btn { cursor: not-allowed; }

.sim-facture { padding: 26px 28px; display: flex; flex-direction: column; gap: 20px; }
/* Facture en TROIS colonnes alignées : libellé · détail · montant.
   La grille vit sur le CONTENEUR, pas sur chaque ligne : deux grilles sœurs ne
   partagent pas leurs colonnes, donc « 7.– par siège », « plein tarif » et
   « 90 % du tarif » ne s'alignaient pas entre eux. `subgrid` fait hériter les
   colonnes du parent tout en gardant un filet sous chaque ligne. */
.sim-facture__lignes { display: grid; grid-template-columns: auto 1fr auto; }
.sim-ligne {
  display: grid; grid-column: 1 / -1; grid-template-columns: subgrid;
  gap: 16px; align-items: baseline;
  padding: 9px 0; border-bottom: 1px solid var(--line);
}
.sim-ligne:last-child { border-bottom: none; }
.sim-ligne__l { font-family: var(--sans); font-size: 13.5px; color: var(--ink-2); }
.sim-ligne__d { font-family: var(--mono); font-size: 12px; color: var(--ink-4); }
.sim-ligne__v { font-family: var(--mono); font-size: 13.5px; color: var(--ink); font-feature-settings: "tnum"; white-space: nowrap; }
.sim-ligne.is-remise .sim-ligne__l,
.sim-ligne.is-remise .sim-ligne__d,
.sim-ligne.is-remise .sim-ligne__v { color: var(--ok); }
/* Sous 560 px, trois colonnes laissent 65 px au détail : « 3 accès × 19.–, hors
   dégressif d'équipe » s'y enroulait sur cinq lignes. Le détail passe donc SOUS
   son libellé, le montant reste à droite, centré sur les deux lignes. */
@media (max-width: 560px) {
  .sim-facture__lignes { display: block; }
  .sim-ligne { grid-template-columns: 1fr auto; gap: 2px 12px; }
  .sim-ligne__l { grid-column: 1; grid-row: 1; }
  .sim-ligne__d { grid-column: 1; grid-row: 2; }
  .sim-ligne__v { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
}

.sim-facture__totaux {
  display: flex; gap: 48px; flex-wrap: wrap;
  border-top: 1px solid var(--line-strong); padding-top: 20px;
}
.sim-total { display: flex; flex-direction: column; gap: 5px; }
.sim-total__v {
  font-family: var(--mono); font-size: 26px; font-weight: 600; color: var(--ink);
  font-feature-settings: "tnum";
}
.sim-total__v.accent { color: var(--accent); }
.sim-total__sub { font-family: var(--mono); font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-4); }

/* ── Mentions légales ── */
.legal { max-width: 760px; }
.legal-block { display: flex; flex-direction: column; gap: 12px; }
.legal-block .k { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--signature); }
.legal-block p { font-family: var(--sans); font-size: 14.5px; line-height: 1.7; color: var(--ink-2); }

/* ── Page 404 ── */
.notfound {
  min-height: 62vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 18px;
  padding: 72px var(--page-pad);
}
.notfound .code {
  font-family: var(--display); font-weight: 800; line-height: 0.88;
  font-size: clamp(96px, 18vw, 220px); color: var(--ink); letter-spacing: 0.01em;
}
.notfound .code em { color: var(--accent); font-style: normal; }
.notfound h1 { font-size: clamp(28px, 4.5vw, 48px); color: var(--ink); }
.notfound p { max-width: 460px; }
.notfound .actions { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }
.notfound .actions .lrv-btn { font-size: 14px; padding: 12px 20px; }

/* ── Footer ── */
.site-footer {
  border-top: 1px solid var(--line); padding: 28px var(--page-pad);
  display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap;
}
.site-footer__brand { display: flex; flex-direction: column; gap: 4px; }
.site-footer__brand .w { font-size: 20px; color: var(--ink); }
.site-footer__brand .t { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.site-footer__links { display: flex; gap: 20px; flex-wrap: wrap; }
.site-footer__links a { font-family: var(--sans); font-size: 12.5px; color: var(--ink-3); }
.site-footer__links a:hover { color: var(--ink); }
.site-footer__meta { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.site-footer__meta a { font-family: var(--mono); font-size: 12px; color: var(--ink-4); }
.site-footer__meta .c { font-family: var(--mono); font-size: 12px; color: var(--ink-4); }

/* ════════════════════════════════════════════════════════════
   RESPONSIVE
   ════════════════════════════════════════════════════════════ */
@media (max-width: 1000px) {
:root { --page-pad: 32px; }
  .hero { grid-template-columns: 1fr; gap: 40px; padding-top: 48px; }
  .spotlight, .import-block, .method-hero__inner, .story-split, .contact-split, .cta-band__inner { grid-template-columns: 1fr; gap: 32px; }
  .spotlight.reverse .spotlight__img { order: -1; }
  .story-photo { height: 360px; }
  .card-grid-4 { grid-template-columns: repeat(2, 1fr); }
  .method-3 { grid-template-columns: 1fr; }
  .method-hero h1 { font-size: 44px; }
  .story-txt h1, .contact-txt h1, .contact-txt h2, .patch-head h1, .inst-head h1 { font-size: 46px; }
  .hero h1 { font-size: clamp(38px, 8vw, 60px); }
  .inst-cases { grid-template-columns: 1fr; }
  .inst-q { grid-template-columns: 1fr; gap: 6px; }
  .mods { grid-template-columns: 1fr 1fr; }
  .sim-sieges { gap: 28px; }
  .addons { grid-template-columns: 1fr 1fr; }
  .tarif-calc__out { gap: 28px; }

  /* Captures d'écran : hauteur libre en dessous de 1000 px.
     Les quatre cadres ont une hauteur FIXE (400 / 360 / 380 px) et leurs images
     sont en `object-fit: cover`. Tant que le cadre garde le même rapport que la
     capture, rien ne se voit. Mais dès que la mise en page passe en une colonne,
     le cadre devient étroit et haut : `cover` zoome pour le remplir et il ne
     restait que 55 à 66 % de la largeur de la capture — une bande centrale, donc
     une capture d'app illisible et moche (constat Val, 06.08.2026 sur mobile).
     On rend la hauteur au contenu : l'image reprend son rapport naturel et
     s'affiche entière. */
  .browser__body,
  .spotlight__img,
  .import-block__img { height: auto; min-height: 0; }
  .browser__body img,
  .spotlight__img img,
  .import-block__img img { height: auto; object-fit: contain; }
}

/* Nav repliée sous le menu ☰ dès 1080 px : six liens + le CTA ne tiennent plus
   sur une ligne en dessous, et le flex comprimait les libellés. Le CTA, lui,
   reste visible jusqu'à 760 px (c'est le bouton de conversion). */
@media (max-width: 1080px) {
.site-nav { flex-wrap: wrap; }
  .site-nav__links {
    order: 3; width: 100%;
    display: none; flex-direction: column; align-items: stretch; gap: 2px;
    padding-top: 8px; border-top: 1px solid var(--line); margin-top: 8px;
  }
  .site-nav__links.open { display: flex; }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border-radius: var(--r-md);
    border: 1px solid var(--line-strong); background: transparent;
    color: var(--ink); cursor: pointer; font-size: 18px;
  }
}

@media (max-width: 760px) {
:root { --page-pad: 20px; }
  .site-nav__cta { display: none; }
  .card-grid-4, .card-grid-2 { grid-template-columns: 1fr; }
  .patch-row { grid-template-columns: 1fr; gap: 4px; }
  .import-block { padding: 28px; }
  .stats-strip { gap: 20px; }
  .story-txt h1, .contact-txt h1, .contact-txt h2, .patch-head h1, .inst-head h1, .spotlight h2, .cta-band h2 { font-size: 38px; }
  .inst-case { padding: 20px; }
  .addons { grid-template-columns: 1fr; }
  .price-grid { grid-template-columns: 1fr; }
  .mods { grid-template-columns: 1fr; }
  .sim-etape { grid-template-columns: 24px 1fr; gap: 12px; }
  .sim-etape__n { width: 24px; height: 24px; font-size: 12px; }
  .sim-sieges { gap: 24px; }
  .sim-facture { padding: 20px; }
  .sim-facture__totaux { gap: 24px; }
  .sim-total__v { font-size: 22px; }
  .tarif-calc { padding: 20px; }
  .tarif-calc__ctl { gap: 24px; }
  .price-card__p .n { font-size: 44px; }
}

/* ── Animations d'entrée douces ──
   État masqué gaté par .has-js : sans JavaScript (ou crawler), le contenu
   reste visible. L'animation n'est qu'une amélioration progressive. */
@media (prefers-reduced-motion: no-preference) {
.has-js .reveal { opacity: 0; transform: translateY(16px); }
  .has-js .reveal.in { opacity: 1; transform: translateY(0); transition: opacity .5s ease, transform .5s cubic-bezier(.16,.84,.3,1); }
}
