/* ==========================================================================
   FDS Pro — feuille de styles unique
   Portage du prototype design_handoff/design/Site.dc.html.

   Principes repris du handoff :
   - mobile-first, aucune media query de mise en page : tout repose sur clamp()
     et repeat(auto-fill|auto-fit, minmax(...)) ;
   - une seule rupture structurelle, à 900 px, pour basculer l'en-tête et les
     filtres entre leur forme « desktop » et leur forme « mobile » ;
   - cibles tactiles jamais inférieures à 44 px ;
   - prefers-reduced-motion neutralise toutes les animations (dernière section).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Couleurs — cf. handoff § Design Tokens. Contrastes vérifiés :
     --accent sur --bg ≈ 6,3:1 · --on-accent sur --accent ≈ 8:1
     --muted sur --bg ≈ 7,3:1 · --faint sur --surface-1 ≈ 5,1:1
     Toute nouvelle teinte doit être revérifiée à ≥ 4,5:1 (texte) / ≥ 3:1 (UI). */
  --bg: #14171a;
  --bg-footer: #101315;
  --surface-1: #1b1f22;
  --surface-2: #202427;
  --surface-3: #232830;
  --surface-dark: #15181a;
  --surface-menu: #181b1e;
  --visual: #0f1214;
  /* Halo derrière les détourages produit. 4,06:1 contre une carrosserie noire :
     au-dessus du seuil UI de 3:1 rappelé en tête de fichier. */
  --photo-halo: #707c82;

  --line: #33383d;
  --line-soft: #2c3134;
  --line-row: #2a2e31;
  --line-field: #4a5054;
  --line-btn: #5a6165;
  --line-chip: #3e4448;
  --line-footer: #1f2427;

  --fg: #f2f4f5;
  --fg-strong: #ffffff;
  --fg-2: #d3d9dc;
  --fg-3: #c3cace;
  --muted: #a8b0b5;
  --faint: #8d969b;
  --dim: #7b8388;
  --dimmer: #6e767b;

  --accent: #4fb86c;
  --accent-light: #7fd9a0;
  --accent-dark: #3d6b4f;
  --on-accent: #0e1416;

  --error-bg: #33191b;
  --error-line: #e4707a;
  --error-fg: #ff9ba4;
  --error-fg-strong: #ffd9dc;
  --success-bg: #1b2a20;

  /* Avertissement — bandeau des pages légales, rubriques « à compléter ».
     Distinct de --error-* : signaler un dossier incomplet n'est pas signaler une faute.
     Contrastes : --warn-fg sur --warn-bg ≈ 10,7:1 · --warn-line sur --warn-bg ≈ 7,9:1 */
  --warn-bg: #2b2418;
  --warn-line: #e0b464;
  --warn-fg: #f0d9a8;

  /* Typographie */
  --font-display: Archivo, system-ui, sans-serif;
  --font-sans: "IBM Plex Sans", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;

  /* Rayons */
  --r-badge: 2px;
  --r-ctl: 3px;
  --r-card: 4px;
  --r-sheet: 8px;

  /* Ombres */
  --shadow-fam: 0 14px 30px -18px #000000;
  --shadow-card: 0 18px 36px -22px #000000;
  --shadow-accent: 0 10px 22px -12px #4fb86c99;

  /* Rythme */
  --container: 1220px;
  --gutter: 20px;
  --section-y: clamp(48px, 7vw, 86px);
  --block-y: clamp(40px, 6vw, 68px);

  /* Animation */
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --lm-delay: 0s;
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--fg);
  font: 400 16px/1.55 var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

img {
  display: block;
  max-width: 100%;
}

a {
  color: var(--accent);
  text-underline-offset: 3px;
}

a:hover {
  color: var(--accent-light);
}

button,
input,
select,
textarea {
  font-family: inherit;
}

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

.lm-main {
  flex: 1;
}

/* --------------------------------------------------------------------------
   3. Utilitaires
   -------------------------------------------------------------------------- */

/* Texte réservé aux technologies d'assistance (nomme les boutons icône). */
.lm-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.lm-skip {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 99;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding: 0 18px;
  background: var(--accent);
  color: var(--on-accent);
  font: 700 14px/1 var(--font-sans);
  border-radius: var(--r-ctl);
  text-decoration: none;
}

.lm-skip:focus {
  top: 12px;
  color: var(--on-accent);
}

.lm-mono-label {
  margin: 0;
  font: 600 11px/1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
}

/* Révélation au défilement.
   La classe `lm-reveal-ready` est posée par le script en ligne de l'en-tête : sans
   JavaScript, sans IntersectionObserver ou avec prefers-reduced-motion, rien n'est
   jamais masqué — le contenu reste intégralement visible.

   On anime la propriété indépendante `translate`, et non `transform` : celui-ci reste
   ainsi libre pour les effets de survol, qui se composent par-dessus. (Une animation
   en `fill-mode: both` sur `transform` aurait au contraire neutralisé tout `:hover`,
   car la couche « animation » de la cascade prime sur les déclarations normales.) */
.lm-reveal-ready [data-reveal] {
  opacity: 0;
  translate: 0 24px;
  transition: opacity 0.6s var(--ease) var(--lm-delay),
    translate 0.6s var(--ease) var(--lm-delay);
}

.lm-reveal-ready [data-reveal].is-in {
  opacity: 1;
  translate: none;
}

/* Champ pot-de-miel : hors écran, hors ordre de tabulation, aria-hidden. */
.lm-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   4. Boutons
   -------------------------------------------------------------------------- */

.lm-btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 18px;
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  font: 600 15px/1.2 var(--font-sans);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease,
    transform 0.18s ease, box-shadow 0.18s ease;
}

.lm-btn--primary {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
}

.lm-btn--primary:hover {
  background: var(--accent-light);
  color: var(--on-accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-accent);
}

.lm-btn--ghost {
  background: transparent;
  color: var(--fg);
  border-color: var(--line-btn);
}

.lm-btn--ghost:hover {
  color: var(--fg);
  border-color: var(--fg);
}

.lm-btn--outline {
  background: var(--surface-2);
  color: var(--fg);
  border-color: var(--line-chip);
}

.lm-btn--outline:hover {
  color: var(--fg);
  border-color: var(--accent);
}

.lm-btn--lg {
  min-height: 52px;
  padding: 0 24px;
  font-size: 16px;
}

.lm-btn--block {
  width: 100%;
}

.lm-btn--submit {
  width: 100%;
  min-height: 54px;
  font: 700 16px/1.2 var(--font-sans);
}

/* --------------------------------------------------------------------------
   5. En-tête
   -------------------------------------------------------------------------- */

.lm-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: #14171af2;
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line-soft);
  transition: box-shadow 0.25s ease, background 0.25s ease;
}

/* Dès que la page défile, l'en-tête se décolle visuellement du contenu. */
.lm-header.is-scrolled {
  background: #14171afa;
  box-shadow: 0 10px 30px -24px #000000;
}

/* Jauge de progression de lecture : reprend le filet vert de 3 px du hero comme motif.
   Purement indicative, donc aria-hidden. */
.lm-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  pointer-events: none;
}

.lm-progress span {
  display: block;
  height: 100%;
  background: var(--accent);
  transform: scaleX(var(--lm-progress, 0));
  transform-origin: left;
}

.lm-header__row {
  max-width: var(--container);
  margin-inline: auto;
  padding: 14px var(--gutter);
  display: flex;
  align-items: center;
  gap: 24px;
}

.lm-logo {
  min-height: 44px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 4px;
  flex-shrink: 0;
  margin-right: auto;
  text-decoration: none;
}

.lm-logo__mark {
  flex-shrink: 0;
  height: 54px;
  width: auto;
}

.lm-logo__baseline {
  font: 500 9px/1.2 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
}

/* Navigation desktop — masquée sous 900 px (donc hors arbre d'accessibilité). */
.lm-nav {
  display: none;
  align-items: center;
  gap: 6px;
}

.lm-nav__link {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  border-bottom: 2px solid transparent;
  color: var(--fg-2);
  font: 600 15px/1 var(--font-sans);
  text-decoration: none;
}

.lm-nav__link:hover {
  color: var(--accent-light);
}

.lm-nav__link.is-active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* Entrée « Produits » : un lien + un bouton de dépliage, réunis sous un même
   soulignement d'état. Le soulignement marque la section, aria-current la page exacte. */
.lm-nav__group {
  position: relative;
  display: inline-flex;
  align-items: center;
  border-bottom: 2px solid transparent;
}

.lm-nav__group.is-active {
  border-bottom-color: var(--accent);
}

.lm-nav__group .lm-nav__link {
  border-bottom: 0;
  padding-right: 4px;
}

.lm-nav__group.is-active .lm-nav__link {
  color: var(--accent);
}

.lm-nav__toggle {
  min-height: 44px;
  width: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 0;
  color: var(--fg-2);
  cursor: pointer;
}

.lm-nav__group.is-active .lm-nav__toggle {
  color: var(--accent);
}

.lm-nav__toggle:hover {
  color: var(--accent-light);
}

.lm-nav__toggle svg,
.lm-menu__toggle svg {
  transition: transform 0.2s var(--ease);
}

.lm-nav__toggle[aria-expanded="true"] svg,
.lm-menu__toggle[aria-expanded="true"] svg {
  transform: rotate(180deg);
}

/* Panneau des familles, en surcouche sous l'en-tête. */
.lm-submenu {
  position: absolute;
  top: calc(100% + 12px);
  left: 0;
  z-index: 50;
  min-width: 268px;
  display: flex;
  flex-direction: column;
  padding: 14px;
  background: var(--surface-menu);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  box-shadow: 0 24px 48px -28px #000000;
  animation: lm-up 0.18s ease-out;
}

.lm-submenu[hidden] {
  display: none;
}

.lm-submenu__label {
  margin: 0 0 8px;
  padding-inline: 10px;
}

.lm-submenu ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.lm-submenu__link {
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 10px;
  border-radius: var(--r-ctl);
  color: var(--fg-2);
  font: 600 15px/1.2 var(--font-sans);
  text-decoration: none;
  transition: background 0.18s ease, color 0.18s ease;
}

.lm-submenu__link:hover {
  background: var(--surface-2);
  color: var(--accent-light);
}

.lm-submenu__link[aria-current="page"] {
  background: var(--surface-2);
  color: var(--accent);
}

.lm-submenu__count {
  font: 500 12px/1 var(--font-mono);
  color: var(--faint);
  white-space: nowrap;
}

.lm-submenu__all {
  min-height: 44px;
  display: flex;
  align-items: center;
  margin-top: 8px;
  padding: 0 10px;
  border-top: 1px solid var(--line-soft);
  color: var(--accent);
  font: 600 13px/1.3 var(--font-sans);
  text-decoration: none;
}

.lm-submenu__all:hover {
  color: var(--accent-light);
}

/* Variante mobile : dans le flux du menu, pas en surcouche. */
.lm-submenu--inline {
  position: static;
  width: 100%;
  min-width: 0;
  margin: 2px 0 6px;
  padding: 8px;
  background: var(--bg);
  box-shadow: none;
}

.lm-nav__phone {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: 10px;
  padding: 0 14px;
  border: 1px solid var(--line-chip);
  border-radius: var(--r-ctl);
  color: var(--fg);
  font: 600 15px/1 var(--font-sans);
  text-decoration: none;
}

.lm-nav__phone:hover {
  color: var(--fg);
  border-color: var(--fg);
}

.lm-header__compact {
  display: flex;
  align-items: center;
  gap: 10px;
}

.lm-iconbtn {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--line-chip);
  border-radius: var(--r-ctl);
  color: var(--fg);
  text-decoration: none;
  cursor: pointer;
}

.lm-iconbtn:hover {
  color: var(--fg);
  border-color: var(--fg);
}

.lm-burger {
  position: relative;
  width: 44px;
  height: 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  background: var(--surface-2);
  border: 1px solid var(--line-chip);
  border-radius: var(--r-ctl);
  cursor: pointer;
}

.lm-burger__bar {
  width: 20px;
  height: 2px;
  background: var(--fg);
}

/* Panneau de navigation mobile : replié par défaut, déplié par le burger.
   Sans JavaScript, il reste déplié en permanence et le burger disparaît. */
.lm-menu {
  display: none;
  flex-direction: column;
  gap: 4px;
  padding: 10px var(--gutter) 20px;
  background: var(--surface-menu);
  border-top: 1px solid var(--line-soft);
  animation: lm-up 0.18s ease-out;
}

.lm-menu.is-open {
  display: flex;
}

.no-js .lm-menu {
  display: flex;
  animation: none;
}

/* Sans JavaScript, le dépliage est impossible : on retire les chevrons plutôt que de
   laisser des boutons inertes. Le lien « Produits » mène de toute façon à l'index,
   qui liste les six familles. */
.no-js .lm-burger,
.no-js .lm-nav__toggle,
.no-js .lm-menu__toggle {
  display: none;
}

.lm-menu__link {
  flex: 1;
  min-height: 52px;
  display: flex;
  align-items: center;
  padding: 0 4px;
  border-bottom: 1px solid var(--line-soft);
  color: var(--fg-2);
  font: 600 17px/1 var(--font-sans);
  text-decoration: none;
}

/* Le lien et son chevron tiennent sur une ligne, le panneau passe à la suivante. */
.lm-menu__group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.lm-menu__toggle {
  width: 52px;
  min-height: 52px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line-soft);
  color: var(--fg-2);
  cursor: pointer;
}

.lm-menu__toggle[aria-expanded="true"] {
  color: var(--accent);
}

.lm-menu__link.is-active {
  color: var(--accent);
}

.lm-menu__cta {
  min-height: 52px;
  margin-top: 12px;
}

@media (min-width: 900px) {
  .lm-nav {
    display: flex;
  }

  .lm-header__compact,
  .lm-menu,
  .no-js .lm-menu {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   6. Titres et conteneurs de page
   -------------------------------------------------------------------------- */

.lm-page {
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(24px, 4vw, 40px) var(--gutter) clamp(48px, 7vw, 80px);
  animation: lm-in 0.45s var(--ease) both;
}

.lm-page--product {
  padding-top: clamp(20px, 3vw, 36px);
}

.lm-section {
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--section-y) var(--gutter);
}

.lm-section--flush-bottom {
  padding-bottom: 0;
}

.lm-subsection {
  margin-top: var(--block-y);
}

.lm-h1 {
  margin: 0;
  font: 800 clamp(28px, 4.6vw, 46px) / 1.05 var(--font-display);
  letter-spacing: -0.03em;
}

.lm-h1--product {
  margin: 14px 0 0;
  font-size: clamp(28px, 4.4vw, 44px);
  line-height: 1.03;
}

.lm-h2 {
  margin: 0;
  font: 700 clamp(24px, 3.4vw, 36px) / 1.1 var(--font-display);
  letter-spacing: -0.02em;
}

.lm-h2--sm {
  font-size: clamp(22px, 3vw, 30px);
  line-height: 1.15;
}

.lm-page__lead {
  margin: 12px 0 0;
  max-width: 64ch;
  color: var(--muted);
}

/* Chapô de section, sur toute la largeur du conteneur : bridé à 62ch, il laissait la
   moitié droite de l'écran vide et tassait le texte à gauche.
   La justification n'est tenable qu'avec la césure automatique — sans elle, les espaces
   s'étirent et creusent des « rivières » blanches. html[lang="fr"] donne au navigateur
   le dictionnaire de césure français. */
.lm-section__lead {
  margin: 14px 0 0;
  max-width: none;
  color: var(--muted);
  text-align: justify;
  hyphens: auto;
}

/* Deux chapôs qui se suivent (section « Six familles ») restent des paragraphes
   distincts, simplement espacés. */
.lm-leads .lm-section__lead + .lm-section__lead {
  margin-top: 14px;
}

/* --------------------------------------------------------------------------
   7. Hero
   -------------------------------------------------------------------------- */

.lm-hero {
  position: relative;
  min-height: clamp(460px, 72vh, 660px);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  border-bottom: 1px solid var(--line-soft);
}

/* Débord de 30 % en bas : c'est la réserve dans laquelle la parallaxe fait glisser
   l'image sans jamais découvrir le fond. */
.lm-hero__bg {
  position: absolute;
  inset: 0 0 -30% 0;
  overflow: hidden;
  background: var(--visual);
  will-change: transform;
}

.lm-hero__zoom {
  position: absolute;
  inset: 0;
  animation: lm-zoom 14s cubic-bezier(0.2, 0.6, 0.2, 1) both;
}

.lm-hero__zoom img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Scène de nuit composée : ciel dégradé, lueur d'horizon, sol sombre. Elle tient
   lieu de photographie tant qu'aucun plan large de chantier éclairé n'est
   disponible — cf. le commentaire dans home.php. */
.lm-hero__scene {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 80% at 72% 6%, #24313b 0%, transparent 58%),
    radial-gradient(90% 55% at 50% 100%, #1a2228 0%, transparent 70%),
    linear-gradient(180deg, #0d1113 0%, #121a1f 46%, #0b0e10 100%);
}

/* Ligne d'horizon : une bande claire très basse suffit à asseoir la tour au sol. */
.lm-hero__scene::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 5%;
  height: 1px;
  background: linear-gradient(90deg, transparent, #4a5c6633 30%, #6d838f4d 80%, transparent);
}

/* La tour est un détourage portrait : « contain » et calage à droite, pour qu'elle
   reste entière et laisse la colonne de texte respirer à gauche. */
/* Sélecteur renforcé : `.lm-hero__zoom img` impose « cover » juste au-dessus, à
   spécificité supérieure. Sans cela, le détourage portrait serait recadré. */
/* Le fond du hero déborde de 30 % sous la section — un effet de profondeur hérité de
   la photo, qu'on pouvait rogner sans dommage. Une tour entière, non : calée sur le bas
   de ce cadre, sa remorque passait sous la ligne de flottaison. Ce calque s'arrête donc
   au bas visible du hero. 30 % de la hauteur de section valent 23 % de celle du fond,
   qui en fait 130 % ; on garde deux points de marge. */
.lm-hero__zoom--tour {
  bottom: 26%;
  /* L'effet de zoom lent (× 1,08) était pensé pour une photo, qu'il pouvait déborder
     sans dommage. Appliqué à un détourage, il pousse la tour hors du cadre, que le
     hero rogne. */
  animation: none;
}

.lm-hero__zoom img.lm-hero__tower {
  object-fit: contain;
  object-position: 94% bottom;
}

/* Halo derrière la tête de projecteurs, à l'aplomb du mât déployé. */
.lm-hero__halo {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(34% 24% at 86% 16%, #cfe4f533 0%, transparent 66%);
}

/* Trois couches purement décoratives : aria-hidden côté HTML, inertes ici. */
.lm-hero__glow,
.lm-hero__sweep,
.lm-hero__veil {
  position: absolute;
  pointer-events: none;
}

.lm-hero__glow {
  inset: 0;
  background: radial-gradient(circle at 68% 12%, #9bc4e033 0%, transparent 42%);
  animation: lm-glow 6s ease-in-out infinite;
}

.lm-hero__sweep {
  top: 0;
  bottom: 0;
  left: 0;
  width: 34%;
  background: linear-gradient(90deg, transparent, #cfe4f51f, transparent);
  animation: lm-sweep 7s ease-in-out 1.2s infinite;
}

.lm-hero__veil {
  inset: 0;
  background: linear-gradient(
    90deg,
    #0f1214f7 0%,
    #0f1214e0 34%,
    #0f121459 62%,
    #0f12141a 100%
  );
}

/* Sous 760 px, le détourage occupe toute la largeur du hero et passerait sous le
   texte. Le voile, horizontal sur grand écran, bascule à la verticale ; la tour
   recule au second plan et ne sert plus que d'ambiance. */
@media (max-width: 760px) {
  .lm-hero__zoom img.lm-hero__tower {
    object-position: 92% bottom;
    opacity: 0.34;
  }

  .lm-hero__veil {
    background: linear-gradient(180deg, #0f1214f2 0%, #0f1214e6 48%, #0f121499 100%);
  }

  .lm-hero__halo {
    background: radial-gradient(46% 20% at 78% 62%, #cfe4f524 0%, transparent 70%);
  }
}

.lm-hero__content {
  position: relative;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(40px, 7vw, 80px) var(--gutter) clamp(36px, 6vw, 70px);
}

.lm-hero__eyebrow {
  margin: 0 0 18px;
  font: 600 12px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  animation: lm-in 0.6s var(--ease) 0.05s both;
}

.lm-hero__title {
  margin: 0;
  max-width: 15em;
  font: 800 clamp(32px, 6.4vw, 62px) / 1.02 var(--font-display);
  letter-spacing: -0.03em;
  color: var(--fg-strong);
  text-wrap: balance;
  animation: lm-in 0.7s var(--ease) 0.16s both;
}

.lm-hero__rule {
  width: 96px;
  height: 3px;
  margin: 22px 0 0;
  background: var(--accent);
  transform-origin: left;
  animation: lm-rule 0.7s var(--ease) 0.5s both;
}

.lm-hero__lead {
  margin: 20px 0 0;
  max-width: 48ch;
  font: 400 clamp(16px, 2.1vw, 19px) / 1.55 var(--font-sans);
  color: var(--fg-2);
  text-wrap: pretty;
  animation: lm-in 0.7s var(--ease) 0.3s both;
}

.lm-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 32px;
  animation: lm-in 0.7s var(--ease) 0.44s both;
}

/* Fond semi-opaque sous le CTA secondaire, pour rester lisible sur l'image. */
.lm-hero .lm-btn--ghost {
  background: #1a1d1fcc;
}

/* --------------------------------------------------------------------------
   8. Familles (accueil)
   -------------------------------------------------------------------------- */

.lm-famgrid {
  list-style: none;
  margin: 30px 0 0;
  padding: 0;
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(255px, 1fr));
  grid-auto-rows: 1fr;
  align-items: stretch;
}

.lm-famcard {
  position: relative;
  overflow: hidden;
  height: 100%;
  min-height: 150px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 20px;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-card);
  color: inherit;
  text-decoration: none;
  transition: transform 0.2s var(--ease), background 0.2s ease,
    border-color 0.2s ease, border-left-width 0.2s ease, box-shadow 0.2s ease;
}

.lm-famcard:hover {
  background: var(--surface-3);
  border-color: var(--accent);
  border-left-width: 6px;
  transform: translateY(-4px);
  box-shadow: var(--shadow-fam);
  color: inherit;
}

/* Balayage lumineux au survol : même vocabulaire que le hero (lm-sweep).
   La transition n'est déclarée que sur :hover, donc pas de balayage inverse au retour. */
.lm-famcard::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 45%;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, #ffffff14, transparent);
  transform: translateX(-180%) skewX(-14deg);
}

.lm-famcard:hover::after {
  transform: translateX(360%) skewX(-14deg);
  transition: transform 0.8s var(--ease);
}

.lm-famcard__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.lm-famcard__name {
  font: 700 21px/1.1 var(--font-display);
  letter-spacing: -0.01em;
  color: var(--fg);
}

.lm-famcard__count {
  font: 500 12px/1 var(--font-mono);
  color: var(--faint);
  white-space: nowrap;
}

.lm-famcard__desc {
  flex: 1;
  font: 400 14px/1.5 var(--font-sans);
  color: var(--muted);
}

.lm-famcard__more {
  font: 600 13px/1 var(--font-sans);
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   8 bis. Tuiles de famille (index /tours-eclairage)

   Six tuiles : la grille tombe sur 3, 2 ou 1 colonne, toutes diviseurs de 6 —
   aucune rangée incomplète, donc aucune règle de troncature à prévoir ici.
   -------------------------------------------------------------------------- */

.lm-famtiles {
  list-style: none;
  margin: 34px 0 0;
  padding: 0;
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  grid-auto-rows: 1fr;
  align-items: stretch;
}

.lm-famtile {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-card);
  color: inherit;
  text-decoration: none;
  transition: transform 0.22s var(--ease), background 0.2s ease,
    border-color 0.2s ease, box-shadow 0.22s ease;
}

.lm-famtile:hover {
  background: var(--surface-3);
  border-color: var(--accent);
  transform: translateY(-5px);
  box-shadow: var(--shadow-card);
  color: inherit;
}

/* Les tuiles de famille montrent désormais une machine représentative, détourée sur
   fond transparent : même halo et même cadrage portrait que les cartes produit. */
.lm-famtile__media {
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background:
    radial-gradient(ellipse 58% 52% at 50% 48%, var(--photo-halo) 0%, transparent 72%),
    linear-gradient(170deg, var(--surface-2) 0%, var(--surface-dark) 100%);
  border-bottom: 1px solid var(--line-soft);
}

.lm-famtile__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 12px 0;
  transition: transform 0.55s var(--ease);
}

.lm-famtile:hover .lm-famtile__media img {
  transform: scale(1.06);
}

.lm-famtile__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 20px;
}

.lm-famtile__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.lm-famtile__name {
  font: 700 22px/1.1 var(--font-display);
  letter-spacing: -0.01em;
  color: var(--fg);
}

.lm-famtile__count {
  font: 500 12px/1 var(--font-mono);
  color: var(--faint);
  white-space: nowrap;
}

.lm-famtile__desc {
  flex: 1;
  font: 400 14px/1.5 var(--font-sans);
  color: var(--muted);
}

.lm-famtile__more {
  font: 600 13px/1 var(--font-sans);
  color: var(--accent);
}

/* Passerelle vers le catalogue complet, pour qui sait déjà ce qu'il cherche. */
.lm-allcatalog {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 28px;
  padding: 20px;
  border: 1px dashed var(--line);
  border-radius: var(--r-card);
}

.lm-allcatalog__text {
  margin: 0;
  color: var(--muted);
}

.lm-cta--page {
  margin-top: var(--block-y);
}

/* --------------------------------------------------------------------------
   9. Grilles de cartes produit
   -------------------------------------------------------------------------- */

.lm-grid {
  display: grid;
  gap: 16px;
  margin-top: 18px;
  grid-template-columns: repeat(auto-fill, minmax(255px, 1fr));
  grid-auto-rows: 1fr;
  align-items: stretch;
}

.lm-section .lm-grid,
.lm-subsection .lm-grid {
  margin-top: 26px;
}

/* Rangées « vitrine » (accueil, modèles associés) : on ne montre jamais plus de
   cartes qu'il n'y a de colonnes, pour éviter une carte orpheline en fin de rangée.
   Les paliers reprennent exactement la grille ci-dessus — minmax(255px,1fr),
   gap 16px, conteneur plafonné à 1180 px : 2 colonnes dès 566 px, 3 dès 837 px,
   4 dès 1108 px. En colonne unique on affiche 4 cartes (accueil) ou 3 (associés). */
@media (max-width: 565px) {
  .lm-grid--related > *:nth-child(n + 4) {
    display: none;
  }
}

@media (min-width: 566px) and (max-width: 836px) {
  .lm-grid--showcase > *:nth-child(n + 3),
  .lm-grid--related > *:nth-child(n + 3) {
    display: none;
  }
}

@media (min-width: 837px) and (max-width: 1107px) {
  .lm-grid--showcase > *:nth-child(n + 4),
  .lm-grid--related > *:nth-child(n + 4) {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   10. Carte produit
   -------------------------------------------------------------------------- */

.lm-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
  transition: transform 0.22s var(--ease), border-color 0.22s ease,
    box-shadow 0.22s ease;
}

.lm-card:hover {
  transform: translateY(-5px);
  border-color: var(--accent);
  box-shadow: var(--shadow-card);
}

.lm-card__media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--surface-dark);
}

.lm-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.55s var(--ease);
}

.lm-card:hover .lm-card__media img {
  transform: scale(1.06);
}

/*
 * Photos produit : des détourages Trime sur fond transparent, en portrait 565x1000.
 * Les machines sont noires — sur le fond sombre du site elles disparaîtraient. On leur
 * donne donc un fond « studio » clair, et « contain » plutôt que « cover » : recadrer
 * une tour d'éclairage dans un cadre paysage la couperait en pleine hauteur de mât.
 */
.lm-photo {
  /* Halo centré plutôt qu'un aplat clair : 43 % des pixels d'un détourage Trime sont
     quasi noirs et se confondraient avec --surface-dark, mais un fond blanc trancherait
     avec la palette sombre du site. Seule la zone située derrière la machine s'éclaircit. */
  background:
    radial-gradient(ellipse 58% 52% at 50% 48%, var(--photo-halo) 0%, transparent 72%),
    linear-gradient(170deg, var(--surface-2) 0%, var(--surface-dark) 100%);
}

/* Les détourages Trime sont en portrait (565 x 1000). Dans le cadre 4/3 hérité des
   visuels d'ambiance, la machine n'occupait que 38 % de la surface, perdue au milieu
   du vide. Seuls les cadres qui portent une photo produit basculent en portrait ; les
   vignettes de détail, elles, restent en paysage. */
.lm-card__media.lm-photo,
.lm-gallery__main.lm-photo {
  aspect-ratio: 4 / 5;
}

/* Sélecteurs doublement classés à dessein : `.lm-gallery__main img` impose « cover »
   plus bas dans ce fichier, à spécificité égale. Sans ce renfort, la fiche produit
   recadrait la tour en pleine hauteur de mât. */
.lm-card__media.lm-photo img,
.lm-gallery__main.lm-photo img {
  /* « contain » et non « cover » : une tour d'éclairage tient dans la hauteur du
     cadre, jamais dans sa largeur. */
  object-fit: contain;
  padding: 12px 0;
}

.lm-badge {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 6px 9px;
  background: var(--accent);
  color: var(--on-accent);
  font: 600 11px/1 var(--font-mono);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  border-radius: var(--r-badge);
  pointer-events: none;
}

.lm-badge--static {
  position: static;
  display: inline-block;
  padding: 7px 10px;
}

.lm-card__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px 18px 20px;
}

.lm-card__heading {
  display: grid;
  gap: 6px;
}

.lm-card__title {
  margin: 0;
  font: 700 19px/1.15 var(--font-display);
  letter-spacing: -0.01em;
  color: var(--fg);
}

.lm-card__reference,
.lm-product__reference {
  margin: 0;
  font: 600 12px/1.35 var(--font-mono);
  letter-spacing: 0.04em;
  color: var(--faint);
}

.lm-card__specs {
  flex: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.lm-card__specs li {
  display: grid;
  grid-template-columns: 74px 1fr;
  gap: 10px;
  font: 400 13px/1.35 var(--font-sans);
  color: var(--fg-3);
}

.lm-card__key {
  font: 500 11px/1.5 var(--font-mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--faint);
}

/* Libellé explicite (« Voir la fiche · <modèle> ») : il doit pouvoir passer
   sur deux lignes sans casser la hauteur minimale de la cible tactile. */
.lm-card__cta {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 16px;
  background: transparent;
  border: 1px solid var(--accent-dark);
  border-radius: var(--r-ctl);
  color: var(--accent);
  font: 600 14px/1.3 var(--font-sans);
  text-align: center;
  text-decoration: none;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

.lm-card__cta:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

/* --------------------------------------------------------------------------
   11. Fil d'Ariane
   -------------------------------------------------------------------------- */

.lm-breadcrumb {
  margin-bottom: 18px;
}

.lm-breadcrumb ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  font: 400 13px/1.4 var(--font-sans);
  color: var(--faint);
}

/* Le fil d'Ariane garde sa hauteur de ligne discrète (13 px) : le padding vertical
   agrandit la zone cliquable sans rien changer à la mise en page. */
.lm-breadcrumb a {
  padding-block: 10px;
}

.lm-breadcrumb__current {
  color: var(--fg-2);
}

/* --------------------------------------------------------------------------
   12. Filtres du catalogue
   -------------------------------------------------------------------------- */

.lm-filterbar {
  position: sticky;
  top: 76px;
  z-index: 30;
  margin-top: 16px;
  padding: 12px 0;
  background: #14171af5;
}

.lm-filterbar__btn {
  width: 100%;
  min-height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: var(--surface-2);
  color: var(--fg);
  border: 1px solid var(--accent);
  border-radius: var(--r-ctl);
  font: 600 16px/1 var(--font-sans);
  cursor: pointer;
}

.lm-filters {
  display: none;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
  margin-top: 28px;
  padding: 18px 0;
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
}

.lm-filters__power {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
}

/* Sans JavaScript, le tiroir mobile ne peut pas s'ouvrir : on montre la rangée
   de filtres complète à toutes les largeurs. */
@media (min-width: 900px) {
  .lm-filterbar {
    display: none;
  }

  .lm-filters {
    display: flex;
  }
}

.no-js .lm-filterbar {
  display: none;
}

.no-js .lm-filters {
  display: flex;
}

/* Le select s'envoie tout seul en JS ; ce bouton ne sert que sans JavaScript. */
html:not(.no-js) .lm-apply {
  display: none;
}

/* Les puces de famille sont des liens : la famille est une page, pas un état. */
.lm-chips {
  flex: 1;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.lm-chips__legend {
  padding-right: 2px;
  line-height: 44px;
}

.lm-chip {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 15px;
  background: var(--surface-2);
  color: var(--fg-2);
  border: 1px solid var(--line-chip);
  border-radius: var(--r-ctl);
  font: 600 14px/1 var(--font-sans);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.lm-chip:hover {
  color: var(--accent-light);
  border-color: var(--accent);
}

.lm-chip.is-active,
.lm-chip.is-active:hover {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}

.lm-chip__count {
  font: 500 12px/1 var(--font-mono);
  opacity: 0.75;
}

.lm-select {
  min-height: 44px;
  padding: 0 12px;
  background: var(--surface-2);
  color: var(--fg);
  border: 1px solid var(--line-chip);
  border-radius: var(--r-ctl);
  font: 500 14px/1 var(--font-sans);
}

/* Variante empilée du tiroir mobile. */
.lm-chips--stacked {
  display: block;
  margin-top: 22px;
}

.lm-chips--stacked .lm-chips__legend {
  display: block;
  margin-bottom: 12px;
  padding-right: 0;
  line-height: 1;
}

.lm-chips--stacked .lm-chip {
  width: 100%;
  min-height: 52px;
  margin-bottom: 8px;
  padding: 0 16px;
  justify-content: space-between;
  font-size: 16px;
}

.lm-chips--stacked .lm-chip__count {
  font-size: 13px;
}

.lm-filters__power--stacked {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  margin-top: 24px;
}

.lm-filters__power--stacked .lm-select {
  min-height: 52px;
  border-color: var(--line-field);
  font: 400 16px/1 var(--font-sans);
}

.lm-filters__power--stacked .lm-btn {
  min-height: 54px;
  margin-top: 18px;
}

/* --------------------------------------------------------------------------
   13. Résultats, état vide, pagination
   -------------------------------------------------------------------------- */

.lm-results {
  margin: 22px 0 0;
  font: 500 14px/1.4 var(--font-mono);
  color: var(--muted);
}

.lm-empty {
  margin-top: 24px;
  padding: clamp(24px, 4vw, 40px);
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.lm-empty__title {
  margin: 0;
  font: 700 19px/1.3 var(--font-display);
}

.lm-empty__body {
  margin: 10px 0 0;
  max-width: 60ch;
  color: var(--muted);
}

.lm-empty__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 22px;
}

.lm-empty__actions--standalone {
  margin-top: 28px;
}

.lm-pagination {
  margin-top: 34px;
}

.lm-pagination form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.lm-page-btn {
  min-height: 44px;
  padding: 0 16px;
  background: var(--surface-2);
  color: var(--fg);
  border: 1px solid var(--line-chip);
  border-radius: var(--r-ctl);
  font: 600 14px/1 var(--font-sans);
  cursor: pointer;
}

.lm-page-btn:hover:not([disabled]) {
  border-color: var(--accent);
}

.lm-page-btn[disabled] {
  opacity: 0.4;
  cursor: default;
}

.lm-page-btn--num {
  min-width: 44px;
  padding: 0 8px;
  font-family: var(--font-mono);
}

.lm-page-btn--num.is-current {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}

/* --------------------------------------------------------------------------
   14. Tiroir de filtres (élément <dialog> natif)
   Le piège de focus, la fermeture par Échap et l'inertage de l'arrière-plan
   sont assurés par showModal() — rien à réimplémenter.
   -------------------------------------------------------------------------- */

.lm-drawer {
  position: fixed;
  inset: 0;
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: hidden;
}

.lm-drawer[open] {
  display: flex;
  align-items: flex-end;
}

.lm-drawer::backdrop {
  background: #0a0c0dcc;
}

.lm-drawer__panel {
  width: 100%;
  max-height: 86vh;
  overflow-y: auto;
  padding: 20px 20px 28px;
  background: var(--surface-menu);
  border-top: 2px solid var(--accent);
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  color: var(--fg);
  animation: lm-up 0.2s ease-out;
}

.lm-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.lm-drawer__title {
  margin: 0;
  font: 700 20px/1.2 var(--font-display);
}

@media (min-width: 900px) {
  .lm-drawer[open] {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   15. Fiche produit
   -------------------------------------------------------------------------- */

.lm-product {
  display: grid;
  gap: clamp(24px, 4vw, 48px);
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  align-items: start;
}

.lm-gallery {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.lm-gallery__main {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--surface-dark);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  overflow: hidden;
}

.lm-gallery__main img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.lm-product__reference {
  margin-top: 8px;
}

.lm-product__blurb {
  margin: 16px 0 0;
  max-width: 54ch;
  font: 400 clamp(15px, 2vw, 17px) / 1.6 var(--font-sans);
  color: var(--fg-3);
  text-wrap: pretty;
}

.lm-variants {
  margin: 26px 0 0;
}

.lm-variants__set {
  margin: 0;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.lm-variants__set legend {
  padding: 0 6px;
}

.lm-variants__row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.lm-variant {
  min-height: 48px;
  padding: 0 16px;
  background: var(--surface-2);
  color: var(--fg-2);
  border: 1px solid var(--line-field);
  border-radius: var(--r-ctl);
  font: 600 14px/1 var(--font-mono);
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.lm-variant:hover {
  border-color: var(--accent);
}

.lm-variant.is-active {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}

.lm-keypoints {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.lm-keypoints li {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: 12px;
  font: 400 15px/1.5 var(--font-sans);
  color: var(--fg-2);
}

.lm-keypoints__chevron {
  color: var(--accent);
  font-weight: 700;
}

.lm-product__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 30px;
}

.lm-product__quote {
  flex: 1;
  min-width: 220px;
}

.lm-product__notice {
  margin: 12px 0 0;
  min-height: 20px;
  font: 500 13px/1.4 var(--font-mono);
  color: var(--accent-light);
}

/* Le téléchargement de fiche technique est piloté en JS : sans JS, on ne
   propose pas un bouton qui ne ferait rien. */
.no-js .lm-pdf,
.no-js .lm-product__notice {
  display: none;
}

/* --------------------------------------------------------------------------
   16. Tableau de spécifications
   -------------------------------------------------------------------------- */

.lm-specs {
  margin-top: var(--block-y);
}

.lm-specs__current {
  margin: 8px 0 20px;
  font: 400 14px/1.5 var(--font-sans);
  color: var(--faint);
}

.lm-specs__scroll {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.lm-specs__table {
  width: 100%;
  min-width: 420px;
  border-collapse: collapse;
}

.lm-specs__table caption {
  text-align: left;
  padding: 14px 18px;
  font: 500 13px/1.4 var(--font-sans);
  color: var(--faint);
  border-bottom: 1px solid var(--line);
}

.lm-specs__table tr {
  border-bottom: 1px solid var(--line-row);
}

.lm-specs__table th {
  width: 42%;
  text-align: left;
  vertical-align: top;
  padding: 13px 18px;
  background: var(--surface-1);
  color: var(--muted);
  font: 600 13px/1.4 var(--font-mono);
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.lm-specs__table td {
  padding: 13px 18px;
  font: 400 15px/1.45 var(--font-sans);
  color: var(--fg);
}

.lm-specs__disclaimer {
  margin: 14px 0 0;
  font: 400 13px/1.5 var(--font-sans);
  color: var(--dim);
}

/* --------------------------------------------------------------------------
   17. Corps rédactionnel de fiche produit
   -------------------------------------------------------------------------- */

/* Le champ `body` de models.json contient du HTML volontairement dépourvu de classes :
   les prompts de `prompts/prompt-seo-fiche-produit.md` interdisent tout attribut, et
   c'est ce conteneur qui porte l'intégralité de la mise en forme. Conséquence à tenir :
   toute balise qu'on autoriserait dans le prompt doit d'abord trouver sa règle ici,
   sinon elle sortira au style par défaut du navigateur, en rupture avec le reste. */
.lm-prose {
  margin-top: var(--section-y);
  padding-top: clamp(32px, 4vw, 52px);
  border-top: 1px solid var(--line-soft);
}

.lm-prose > :first-child {
  margin-top: 0;
}

.lm-prose h2 {
  margin: clamp(34px, 4vw, 52px) 0 0;
  font: 700 clamp(22px, 3vw, 30px) / 1.15 var(--font-display);
  letter-spacing: -0.02em;
  color: var(--fg);
}

.lm-prose h3 {
  margin: clamp(24px, 3vw, 34px) 0 0;
  font: 600 clamp(17px, 2.2vw, 20px) / 1.25 var(--font-sans);
  letter-spacing: -0.01em;
  color: var(--fg);
}

/* Même parti pris que les chapôs de l'accueil : justification + césure automatique,
   sur toute la largeur du conteneur. */
.lm-prose p {
  margin: 14px 0 0;
  color: var(--muted);
  text-align: justify;
  hyphens: auto;
}

.lm-prose ul {
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}

.lm-prose li {
  position: relative;
  margin-top: 9px;
  padding-left: 22px;
  color: var(--muted);
}

.lm-prose li::before {
  content: "▸";
  position: absolute;
  left: 0;
  color: var(--accent);
}

.lm-prose strong {
  color: var(--fg);
  font-weight: 600;
}

/* Le tableau de spécifications est rendu par PHP, pas par le texte : celui-ci ne sert
   qu'aux comparaisons ponctuelles. Faute de conteneur pour porter le défilement — le
   prompt interdit <div> —, c'est le <table> lui-même qui passe en display: block. */
.lm-prose table {
  display: block;
  width: 100%;
  overflow-x: auto;
  margin: 22px 0 0;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  font: 400 15px/1.45 var(--font-sans);
}

.lm-prose th,
.lm-prose td {
  padding: 12px 16px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--line-row);
}

.lm-prose th {
  background: var(--surface-1);
  color: var(--muted);
  font: 600 13px/1.4 var(--font-mono);
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.lm-prose td {
  color: var(--fg);
}

.lm-prose tr:last-child th,
.lm-prose tr:last-child td {
  border-bottom: 0;
}

/* --------------------------------------------------------------------------
   18. Réassurance et encart CTA (accueil)
   -------------------------------------------------------------------------- */

.lm-trust {
  margin-top: var(--section-y);
  background: var(--surface-1);
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
}

.lm-trust__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(44px, 6vw, 74px) var(--gutter);
}

.lm-trust__grid {
  list-style: none;
  margin: 30px 0 0;
  padding: 0;
  display: grid;
  gap: 28px 34px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

/* Le filet vert de 2 px est un pseudo-élément et non une bordure, pour qu'il puisse
   se tracer de gauche à droite à la révélation — même geste que le filet du hero. */
.lm-trust__item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 18px;
}

.lm-trust__item::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--accent);
  transform-origin: left;
}

.lm-reveal-ready .lm-trust__item[data-reveal]::before {
  transform: scaleX(0);
  transition: transform 0.6s var(--ease) calc(var(--lm-delay) + 0.12s);
}

.lm-reveal-ready .lm-trust__item[data-reveal].is-in::before {
  transform: scaleX(1);
}

.lm-trust__title {
  margin: 0;
  font: 700 18px/1.2 var(--font-display);
  color: var(--fg);
}

.lm-trust__body {
  margin: 0;
  font: 400 15px/1.55 var(--font-sans);
  color: var(--muted);
  text-align: justify;
  hyphens: auto;
}

.lm-trust__sectors {
  margin: 34px 0 0;
  font: 500 13px/1.6 var(--font-mono);
  color: var(--faint);
}

.lm-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: clamp(24px, 4vw, 40px);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.lm-cta__text {
  flex: 1;
  min-width: min(100%, 320px);
}

.lm-cta__text p {
  margin: 10px 0 0;
  color: var(--muted);
}

.lm-cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* --------------------------------------------------------------------------
   17 bis. Blocs éditoriaux de l'accueil
   Chapô, parcours en trois étapes, bande illustrée et questions fréquentes.
   Ces blocs servent de respiration entre les grilles. Le texte y est justifié avec
   césure automatique et occupe toute la largeur disponible ; les paragraphes restent
   courts (deux à quatre lignes) pour qu'aucun ne se lise comme un mur.
   -------------------------------------------------------------------------- */

/* Chapô d'ouverture : les deux paragraphes de présentation et une photo de chantier
   éclairé, côte à côte. La photo donne au bloc une accroche visuelle sans réintroduire
   le hero, et raccourcit la ligne de ce paragraphe-là.
   `auto-fit` empile le tout en une seule colonne sur mobile, texte d'abord : c'est lui
   qui prend la suite du hero. */
.lm-intro {
  display: grid;
  gap: clamp(20px, 3vw, 40px);
  align-items: center;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

.lm-intro__text p {
  margin: 0 0 14px;
  font: 400 clamp(16px, 1.5vw, 18px) / 1.65 var(--font-sans);
  color: var(--fg-2);
  text-align: justify;
  hyphens: auto;
}

.lm-intro__text p:last-child {
  margin-bottom: 0;
}

.lm-intro__media {
  margin: 0;
  overflow: hidden;
  background: var(--visual);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
}

.lm-intro__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

/* Passerelle de fin de section : plus discrète qu'un lead, pour ne pas concurrencer
   le titre de la section suivante. */
.lm-section__note {
  margin: 26px 0 0;
  font: 400 14px/1.6 var(--font-sans);
  color: var(--faint);
  text-align: justify;
  hyphens: auto;
}

.lm-steps {
  list-style: none;
  margin: 30px 0 0;
  padding: 0;
  display: grid;
  gap: 28px 34px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.lm-step {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 22px 22px 24px;
  background: var(--surface-1);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
}

.lm-step__num {
  font: 600 13px/1 var(--font-mono);
  letter-spacing: 0.08em;
  color: var(--accent);
}

.lm-step__title {
  margin: 0;
  font: 700 19px/1.25 var(--font-display);
  color: var(--fg);
}

.lm-step__body {
  margin: 0;
  font: 400 15px/1.6 var(--font-sans);
  color: var(--muted);
  text-align: justify;
  hyphens: auto;
}

.lm-steps__cta {
  margin-top: 30px;
}

/* Bande illustrée : une image et son texte côte à côte. auto-fit fait passer la
   paire en colonne unique sur mobile, image d'abord. */
.lm-shots {
  display: grid;
  gap: clamp(28px, 4vw, 48px);
  margin-top: 30px;
}

.lm-shot {
  display: grid;
  gap: clamp(18px, 3vw, 34px);
  align-items: center;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

.lm-shot__media {
  margin: 0;
  overflow: hidden;
  background: var(--visual);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
}

.lm-shot__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  transition: transform 0.5s var(--ease);
}

.lm-shot:hover .lm-shot__media img {
  transform: scale(1.03);
}

/* Vues de détail bâties sur les mêmes détourages que les fiches produit. Le fond
   reprend le halo de `.lm-photo` : sans lui, une carrosserie noire disparaîtrait sur
   --visual. Le cadrage, lui, change selon ce que le texte commente. */
.lm-shot__media--tour {
  background:
    radial-gradient(ellipse 62% 68% at 50% 46%, var(--photo-halo) 0%, transparent 70%),
    linear-gradient(170deg, var(--surface-2) 0%, var(--surface-dark) 100%);
}

.lm-shot__media--haut img {
  object-position: 50% 6%;
}

.lm-shot__media--bas img {
  object-position: 50% 96%;
}

/* Machine entière : « contain », le seul cadrage qui ne coupe pas un mât déployé, et
   un cadre portrait — en 3/2 paysage la tour n'occupait qu'un tiers de la surface.
   Ces deux blocs sont des rangées côte à côte avec leur texte, pas une grille à
   colonnes : les hauteurs peuvent différer sans rien désaligner. */
.lm-shot__media--entier img {
  aspect-ratio: 4 / 5;
  object-fit: contain;
  padding: 10px 0;
}

.lm-shot__title {
  margin: 0;
  font: 700 clamp(19px, 2.2vw, 23px) / 1.2 var(--font-display);
  color: var(--fg);
}

.lm-shot__body p {
  margin: 10px 0 0;
  font: 400 15px/1.65 var(--font-sans);
  color: var(--muted);
  text-align: justify;
  hyphens: auto;
}

/* Zigzag : une rangée sur deux inverse image et texte. Le palier reprend celui de
   la grille de cartes (837 px) plutôt que d'en introduire un nouveau ; en dessous,
   tout est empilé et l'image reste toujours en premier. */
@media (min-width: 837px) {
  /* Chapô : le texte mène, la photo accompagne — d'où 7 parts contre 5. */
  .lm-intro {
    grid-template-columns: 7fr 5fr;
  }

  /* Colonne image un peu plus étroite que la colonne texte : les deux blocs finissent
     à des hauteurs comparables, ce qui évite l'effet « image posée à côté d'un
     paragraphe orphelin ». */
  .lm-shot {
    grid-template-columns: 5fr 6fr;
  }

  .lm-shot:nth-child(even) {
    grid-template-columns: 6fr 5fr;
  }

  .lm-shot:nth-child(even) .lm-shot__media {
    order: 2;
  }
}

/* Quatre questions : le seuil est volontairement haut (420 px) pour que la grille
   passe de 1 à 2 colonnes et jamais à 3, qui laisserait une question orpheline sur
   la dernière rangée. */
.lm-faq {
  display: grid;
  gap: 26px 34px;
  margin-top: 30px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
}

.lm-faq__item {
  padding-top: 18px;
  border-top: 1px solid var(--line-soft);
}

.lm-faq__q {
  margin: 0;
  font: 700 17px/1.3 var(--font-display);
  color: var(--fg);
}

.lm-faq__a {
  margin: 8px 0 0;
  font: 400 15px/1.6 var(--font-sans);
  color: var(--muted);
  text-align: justify;
  hyphens: auto;
}

/* --------------------------------------------------------------------------
   19. Contact
   -------------------------------------------------------------------------- */

.lm-contact {
  display: grid;
  gap: clamp(24px, 4vw, 44px);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  margin-top: 34px;
  align-items: start;
}

.lm-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.lm-form__summary {
  padding: 14px 16px;
  background: var(--error-bg);
  border: 1px solid var(--error-line);
  border-radius: var(--r-ctl);
  font: 500 15px/1.5 var(--font-sans);
  color: var(--error-fg-strong);
}

.lm-form__summary[hidden] {
  display: none;
}

.lm-field {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.lm-field label {
  font: 600 14px/1.3 var(--font-sans);
  color: var(--fg);
}

.lm-field__required {
  color: var(--accent-light);
}

.lm-field input,
.lm-field select,
.lm-field textarea {
  width: 100%;
  min-height: 48px;
  padding: 0 14px;
  background: var(--surface-1);
  border: 1px solid var(--line-field);
  border-radius: var(--r-ctl);
  color: var(--fg);
  font: 400 16px/1 var(--font-sans);
}

.lm-field textarea {
  padding: 12px 14px;
  line-height: 1.5;
  resize: vertical;
}

.lm-field input[aria-invalid="true"],
.lm-field textarea[aria-invalid="true"] {
  border-color: var(--error-line);
}

.lm-field__hint {
  margin: 0;
  font: 400 13px/1.4 var(--font-sans);
  color: var(--faint);
}

.lm-field__error {
  margin: 0;
  font: 500 13px/1.4 var(--font-sans);
  color: var(--error-fg);
}

.lm-field__error:empty {
  display: none;
}

.lm-field__pair {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.lm-form__legal {
  margin: 0;
  font: 400 13px/1.5 var(--font-sans);
  color: var(--dim);
}

.lm-confirm {
  padding: clamp(22px, 4vw, 34px);
  background: var(--success-bg);
  border: 1px solid var(--accent);
  border-radius: var(--r-card);
}

.lm-confirm__eyebrow {
  font-size: 12px;
  letter-spacing: 0.12em;
  color: var(--accent-light);
}

.lm-confirm__title {
  margin: 14px 0 0;
  font: 700 clamp(21px, 3vw, 28px) / 1.15 var(--font-display);
}

.lm-confirm__body {
  margin: 12px 0 0;
  font: 400 16px/1.6 var(--font-sans);
  color: var(--fg-2);
}

.lm-confirm__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 24px;
}

.lm-contactcard {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: clamp(22px, 3.5vw, 32px);
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.lm-contactcard__title {
  margin: 0;
  font: 700 20px/1.2 var(--font-display);
}

.lm-contactcard__hours {
  margin: 10px 0 0;
  font: 400 15px/1.55 var(--font-sans);
  color: var(--muted);
}

.lm-contactcard__list {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.lm-contactcard__list dd {
  margin: 6px 0 0;
}

.lm-contactcard__phone {
  font: 700 20px/1.2 var(--font-display);
  color: var(--accent);
  text-decoration: none;
}

.lm-contactcard__mail {
  font: 600 16px/1.3 var(--font-sans);
  color: var(--accent);
}

.lm-contactcard__address {
  font: 400 15px/1.55 var(--font-sans);
  color: var(--fg-2);
}

.lm-contactcard__status {
  margin: 0;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  font: 500 13px/1.6 var(--font-mono);
  color: var(--faint);
}

/* --------------------------------------------------------------------------
   20. Pied de page
   -------------------------------------------------------------------------- */

.lm-footer {
  margin-top: auto;
  background: var(--bg-footer);
  border-top: 1px solid var(--line-soft);
}

.lm-footer__grid {
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(34px, 5vw, 54px) var(--gutter);
  display: grid;
  gap: 30px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.lm-footer__logo {
  display: block;
  height: 64px;
  width: auto;
}

.lm-footer__pitch {
  margin: 12px 0 0;
  max-width: 34ch;
  font: 400 14px/1.6 var(--font-sans);
  color: var(--faint);
}

.lm-footer .lm-mono-label {
  margin: 0 0 12px;
  letter-spacing: 0.12em;
}

.lm-footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* 44 px et non les 36 px du prototype : la règle « cibles ≥ 44 px partout » de la
   section accessibilité du handoff prime sur la valeur d'origine. */
.lm-footer__link {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--fg-2);
  font: 400 15px/1.3 var(--font-sans);
  text-decoration: none;
}

.lm-footer__link:hover {
  color: var(--accent);
}

.lm-footer__bottom {
  border-top: 1px solid var(--line-footer);
}

.lm-footer__bottom p {
  max-width: var(--container);
  margin-inline: auto;
  padding: 18px var(--gutter);
  font: 400 12px/1.6 var(--font-sans);
  color: var(--dimmer);
}

/* --------------------------------------------------------------------------
   20 bis. Pages légales
   -------------------------------------------------------------------------- */

/* Même famille typographique que .lm-prose (section 17), mais conteneur autonome :
   pas de filet de séparation en tête, puisque ces pages n'ont rien au-dessus d'elles.
   Les liens y sont soulignés — dans un texte réglementaire, la couleur seule ne suffit
   pas à distinguer un lien (WCAG 1.4.1, « l'information n'est pas véhiculée par la
   seule couleur »). */
.lm-legal {
  margin-top: clamp(28px, 4vw, 44px);
}

.lm-legal h2 {
  margin: clamp(34px, 4vw, 52px) 0 0;
  font: 700 clamp(21px, 2.8vw, 28px) / 1.15 var(--font-display);
  letter-spacing: -0.02em;
  color: var(--fg);
}

.lm-legal > :first-child {
  margin-top: 0;
}

.lm-legal p {
  margin: 14px 0 0;
  max-width: 78ch;
  color: var(--muted);
}

.lm-legal ul {
  margin: 14px 0 0;
  padding: 0;
  max-width: 78ch;
  list-style: none;
}

.lm-legal li {
  position: relative;
  margin-top: 8px;
  padding-left: 20px;
  color: var(--muted);
}

.lm-legal li::before {
  content: "";
  position: absolute;
  top: 0.62em;
  left: 2px;
  width: 6px;
  height: 1px;
  background: var(--accent);
}

.lm-legal strong {
  color: var(--fg-2);
  font-weight: 600;
}

.lm-legal a {
  color: var(--accent-light);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.lm-legal a:hover {
  color: var(--fg-strong);
}

.lm-legal code {
  padding: 1px 5px;
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-badge);
  font: 400 0.9em/1 var(--font-mono);
  color: var(--fg-3);
}

/* Identité légale : libellé et valeur. En dessous de 560 px la valeur passe sous son
   libellé plutôt que de comprimer les deux colonnes — une adresse de siège social ne
   tient pas dans 40 % d'un écran de téléphone. */
.lm-legal__dl {
  margin: 18px 0 0;
  border-top: 1px solid var(--line-row);
}

.lm-legal__row {
  display: grid;
  grid-template-columns: minmax(180px, 260px) 1fr;
  gap: 4px 24px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line-row);
}

@media (max-width: 559px) {
  .lm-legal__row {
    grid-template-columns: 1fr;
  }
}

.lm-legal__row dd {
  margin: 0;
  color: var(--fg-2);
}

/* Rubrique obligatoire non renseignée. En italique et en teinte d'alerte : elle doit
   se repérer d'un coup d'œil dans la liste, sans être lisible comme une vraie valeur. */
.lm-legal__todo {
  font-style: italic;
  color: var(--warn-fg) !important;
}

.lm-legal__contact {
  margin-top: 18px;
}

/* Bandeau « informations manquantes ». Filet épais à gauche plutôt qu'un cadre complet :
   il signale sans imiter un message d'erreur de formulaire. */
.lm-notice {
  margin-top: clamp(24px, 3.5vw, 36px);
  padding: clamp(18px, 3vw, 26px) clamp(18px, 3vw, 28px);
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  border-left-width: 4px;
  border-radius: var(--r-card);
}

.lm-notice__eyebrow {
  font-size: 12px;
  letter-spacing: 0.12em;
  color: var(--warn-line);
}

.lm-notice__body {
  margin: 12px 0 0;
  max-width: 78ch;
  font: 400 15px/1.6 var(--font-sans);
  color: var(--warn-fg);
}

.lm-notice__body strong {
  color: var(--fg-strong);
  font-weight: 600;
}

.lm-notice code {
  padding: 1px 5px;
  background: #00000038;
  border-radius: var(--r-badge);
  font: 400 0.9em/1 var(--font-mono);
}

/* Liens légaux du bas de page. Hauteur portée à 44 px comme le reste du pied de page —
   c'est la cible tactile minimale retenue par le handoff, marquée « non négociable ». */
.lm-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 24px;
  max-width: var(--container);
  margin-inline: auto;
  padding: 4px var(--gutter) 0;
}

.lm-footer__legal-link {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--fg-3);
  font: 400 14px/1.3 var(--font-sans);
  text-decoration: none;
}

.lm-footer__legal-link:hover {
  color: var(--accent);
}

.lm-footer__legal + p {
  padding-top: 0;
}

/* --------------------------------------------------------------------------
   21. Animations
   -------------------------------------------------------------------------- */

@keyframes lm-up {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes lm-in {
  from {
    opacity: 0;
    transform: translateY(22px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes lm-zoom {
  from {
    transform: scale(1.08) translateX(1.5%);
  }
  to {
    transform: scale(1) translateX(0);
  }
}

@keyframes lm-sweep {
  0% {
    opacity: 0;
    transform: translateX(-18%) skewX(-12deg);
  }
  45% {
    opacity: 0.55;
  }
  100% {
    opacity: 0;
    transform: translateX(120%) skewX(-12deg);
  }
}

@keyframes lm-glow {
  0%,
  100% {
    opacity: 0.35;
  }
  50% {
    opacity: 0.75;
  }
}

@keyframes lm-rule {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

/* Non négociable : aucune animation pour qui la refuse.
   Le JS complète cette règle en n'activant ni la révélation au défilement, ni la
   parallaxe du hero, ni les compteurs — le contenu est alors rendu dans son état final. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .lm-famcard::after {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   22. Configurateur
   -------------------------------------------------------------------------- */

.lm-quiz {
  display: flex;
  flex-direction: column;
  gap: 22px;
  margin: 30px 0 0;
  max-width: 640px;
}

.lm-quiz__set {
  margin: 0;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.lm-quiz__set legend {
  padding: 0 6px;
}

.lm-quiz__row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}

.lm-quiz__option {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 12px 16px;
  background: var(--surface-2);
  color: var(--fg-2);
  border: 1px solid var(--line-field);
  border-radius: var(--r-ctl);
  font: 400 15px/1.4 var(--font-sans);
  cursor: pointer;
  transition: border-color 0.18s ease, color 0.18s ease;
}

.lm-quiz__option:hover {
  border-color: var(--accent);
}

.lm-quiz__option:has(input:checked),
.lm-quiz__option.is-active {
  color: var(--fg-strong);
  border-color: var(--accent);
}

.lm-quiz__option input {
  accent-color: var(--accent);
  width: 18px;
  height: 18px;
  flex: none;
}

.lm-quiz__result {
  margin: 34px 0 0;
  padding: 24px;
  max-width: 640px;
  background: var(--surface-1);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
}

.lm-quiz__result[hidden] {
  display: none;
}

.lm-quiz__result h2 {
  margin: 10px 0 0;
}

/* Justification de la recommandation — commune aux deux variantes du configurateur
   (page dépliée et bandeau d'accueil), qui partagent partials/configurator.php. */
.lm-config__reason {
  margin: 10px 0 0;
  max-width: 60ch;
  font: 400 15px/1.6 var(--font-sans);
  color: var(--fg-3);
}

.lm-quiz__optional {
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
}

.lm-quiz__count {
  margin: 14px 0 0;
  font: 500 13px/1.4 var(--font-mono);
  color: var(--accent-light);
}

.lm-quiz__count[hidden] {
  display: none;
}

.lm-quiz__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 20px;
}

.lm-quiz__result .lm-specs__disclaimer {
  margin-top: 18px;
}

/* La recommandation apparaît déjà sans rechargement dès la 3e réponse cochée : ce
   bouton ne sert qu'en repli sans JavaScript, comme .lm-apply pour les filtres. */
html:not(.no-js) .lm-quiz__submit {
  display: none;
}

/* --------------------------------------------------------------------------
   23. Bandeau configurateur (accueil)

   Même formulaire que la page /tours-eclairage/configurateur, mais replié : les
   quatre questions tiennent sur une rangée de volets, et seule la réponse choisie
   reste visible une fois le volet refermé. Au-dessus de 900 px, le panneau d'options
   s'ouvre en survol du contenu (position: absolute) plutôt que de pousser la page ;
   en dessous, il se déplie normalement dans le flux, comme un <details> ordinaire.
   -------------------------------------------------------------------------- */

/* Le bandeau ne s'encadre pas, il s'éclaircit : un fond plus clair que le reste de la
   page, fermé en haut et en bas par deux filets d'accent. Une carte à marges latérales
   aurait mieux ressorti sur grand écran, mais elle perd ses marges sous 900 px et
   redevient une bande de toute façon — la valeur inversée, elle, se comporte à
   l'identique partout. */
.lm-band {
  position: relative;
  background: var(--surface-3);
  border-top: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
}

.lm-band__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(26px, 4vw, 40px) var(--gutter) clamp(30px, 4.5vw, 46px);
}

.lm-band__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 10px 24px;
}

.lm-band__title {
  margin: 8px 0 0;
  font: 700 clamp(21px, 2.8vw, 30px) / 1.12 var(--font-display);
  letter-spacing: -0.02em;
  color: var(--fg-strong);
  text-wrap: balance;
}

.lm-band__hint {
  margin: 0;
  font: 500 13px/1.5 var(--font-mono);
  color: var(--faint);
}

.lm-band__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px;
  margin-top: clamp(18px, 2.6vw, 26px);
}

.lm-band__q {
  min-width: 0;
}

/* list-style + ::-webkit-details-marker : les deux écritures du triangle natif,
   remplacé ici par .lm-band__chev, qui suit l'état ouvert/fermé. */
/* Le fond du bandeau étant plus clair que le reste du site, les volets prennent le
   chemin inverse des autres contrôles : plus sombres que ce qui les entoure, ils se
   lisent comme des champs creusés dans la bande.
   D'où une bordure nettement plus claire que le --line-field habituel : ailleurs sur
   le site, c'est le remplissage du contrôle qui tranche sur le fond de page et signale
   qu'on peut cliquer. Ici les deux valeurs sont voisines (1,12:1) et la bordure porte
   seule cette indication — elle doit donc tenir les 3:1 exigés d'un élément
   d'interface. --dimmer sur --surface-1 : 3,6:1. */
.lm-band__summary {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 62px;
  padding: 10px 14px;
  background: var(--surface-1);
  border: 1px solid var(--dimmer);
  border-radius: var(--r-ctl);
  cursor: pointer;
  list-style: none;
  transition: border-color 0.18s ease, background 0.18s ease;
}

.lm-band__summary::-webkit-details-marker {
  display: none;
}

.lm-band__summary:hover {
  border-color: var(--accent);
}

.lm-band__q[open] > .lm-band__summary {
  background: var(--surface-2);
  border-color: var(--accent);
}

.lm-band__num {
  font: 600 12px/1 var(--font-mono);
  letter-spacing: 0.08em;
  color: var(--faint);
  flex: none;
}

.lm-band__q.is-set .lm-band__num {
  color: var(--accent);
}

.lm-band__labels {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  flex: 1 1 auto;
}

.lm-band__qlabel {
  font: 600 11px/1.2 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
}

/* Hérite du --faint de .lm-band__qlabel : --dimmer serait sous le seuil de 4,5:1
   sur le fond du volet. La mise en minuscules suffit à distinguer la mention. */
.lm-band__opt {
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
}

/* La réponse cochée remplace le « À choisir » : c'est elle qui doit rester lisible
   une fois le volet refermé, donc la seule ligne en pleine couleur du résumé. */
.lm-band__answer {
  font: 400 15px/1.25 var(--font-sans);
  color: var(--faint);
  overflow-wrap: anywhere;
}

.lm-band__q.is-set .lm-band__answer {
  color: var(--fg-strong);
  font-weight: 600;
}

/* Chevron dessiné en CSS : deux côtés d'un carré, tournés de 45 degrés. */
.lm-band__chev {
  width: 8px;
  height: 8px;
  flex: none;
  border-right: 2px solid var(--faint);
  border-bottom: 2px solid var(--faint);
  rotate: 45deg;
  translate: 0 -2px;
  transition: rotate 0.2s var(--ease), translate 0.2s var(--ease);
}

.lm-band__q[open] > .lm-band__summary .lm-band__chev {
  rotate: 225deg;
  translate: 0 2px;
}

.lm-band__panel {
  margin: 8px 0 0;
  padding: 14px;
  background: var(--surface-menu);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}

/* `float` sort la légende de l'encoche que le navigateur lui creuse d'office dans la
   bordure du <fieldset> : ici la question doit être la première ligne du panneau, pas
   un titre à cheval sur le cadre. `display: block` ne suffit pas — l'encoche est un
   comportement de rendu propre à <legend>, que seul le flottement neutralise. */
.lm-band__legend {
  float: left;
  width: 100%;
  margin: 0 0 10px;
  padding: 0;
  color: var(--fg-3);
  font: 600 13px/1.4 var(--font-sans);
}

/* Contrepartie du `float` ci-dessus : la liste d'options est un conteneur flex, donc
   un contexte de formatage de bloc — sans `clear`, elle se rangerait *à côté* du
   flottant large de 100 %, réduite à quelques dizaines de pixels. */
.lm-band__panel .lm-quiz__row {
  clear: both;
}

@media (min-width: 900px) {
  .lm-band__q {
    position: relative;
  }

  /* Le panneau flotte au-dessus du contenu suivant : la rangée de questions garde
     la même hauteur, ouverte ou fermée. */
  .lm-band__panel {
    position: absolute;
    z-index: 30;
    top: calc(100% + 8px);
    left: 0;
    width: max-content;
    min-width: 100%;
    max-width: min(400px, 42vw);
    margin: 0;
  }

  /* Dernier volet de la rangée : ancré à droite, sinon le panneau déborde du
     conteneur et provoque un défilement horizontal. */
  .lm-band__q:last-child .lm-band__panel {
    left: auto;
    right: 0;
  }
}

.lm-band__submit {
  margin-top: 18px;
}

.lm-band__pending {
  margin: 18px 0 0;
  font: 400 14px/1.5 var(--font-sans);
  color: var(--faint);
}

.lm-band__pending[hidden] {
  display: none;
}

/* Résultat : bord gauche accentué, comme les encarts de réassurance, pour qu'il se
   détache du bandeau dès l'apparition sans changer la couleur de fond du bloc. */
.lm-band__result {
  display: grid;
  gap: 18px;
  margin-top: clamp(18px, 2.6vw, 24px);
  padding: clamp(18px, 2.6vw, 26px);
  background: var(--surface-1);
  border: 1px solid var(--accent-dark);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  animation: lm-in 0.4s var(--ease) both;
}

.lm-band__result[hidden] {
  display: none;
}

.lm-band__result h2 {
  margin: 8px 0 0;
}

.lm-band__result .lm-quiz__actions {
  margin-top: 0;
}

.lm-band__result .lm-specs__disclaimer {
  margin: 0;
}

@media (min-width: 900px) {
  .lm-band__result {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 28px;
  }

  .lm-band__result .lm-specs__disclaimer {
    grid-column: 1 / -1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .lm-band__result {
    animation: none;
  }
}
