/* ==========================================================================
   Loforge — socle du site vitrine
   --------------------------------------------------------------------------
   Ce qui est commun aux onze pages : remise à zéro, typographie, en-tête,
   pied de page, boutons, sections, formulaires, menu mobile.

   Avant le 20/09/2026, chaque page redéfinissait tout cela dans son propre
   bloc <style>. Huit copies, donc huit dérives : un bouton corrigé sur
   l'accueil restait faux sur la page contact. Ce fichier remplace les huit.

   Il ne contient RIEN de propre à une page. Une règle qui ne sert qu'à un
   seul écran reste dans le bloc <style> de cet écran.

   Ordre de chargement, dans chaque page :
       jetons.css  →  fonts.css  →  socle.css  →  bloc <style> de la page

   Les couleurs, polices, rayons et la courbe viennent de jetons.css et de
   nulle part ailleurs. Aucune valeur en dur ici.
   ========================================================================== */

:root{
  --w:1140px;

  /* Échelle fluide, bornée par la largeur ET la hauteur d'écran : le site
     doit tenir sur un portable 1366x768 comme sur un 1920x1080 mis à
     l'échelle à 150 %, sans perdre ses mesures sur grand écran. */
  --pad-x:clamp(18px,2.2vw,24px);
  --sec-pad:clamp(58px,calc(7vh + 2.2vw),110px);
  --head-gap:clamp(34px,calc(4vh + 1.4vw),64px);
  --grid-gap:clamp(16px,1.8vw,22px);
}

/* ---------- Remise à zéro ---------- */
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  background:var(--fond);
  color:var(--encre);
  font-family:var(--texte);
  font-size:16px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}
::selection{background:var(--braise);color:var(--braise-nuit)}

/* Jamais supprimé, sur aucun élément. Le rappel de spécificité est plus
   bas, avec les champs de formulaire. */
:focus-visible{outline:2px solid var(--braise);outline-offset:3px;border-radius:4px}

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

.wrap{max-width:var(--w);margin:0 auto;padding:0 var(--pad-x)}
section{scroll-margin-top:92px}

/* ---------- Titres ----------
   Orbitron porte les titres, Oxanium le reste. Deux familles, mais deux
   registres du même monde : c'est le contraste de dessin qui sépare un titre
   d'un paragraphe, pas une différence de graisse.

   AUCUN interlettrage négatif ici. Orbitron est large et dessinée avec son
   propre espacement ; `--serre` la faisait se toucher. Les tailles sont d'un
   cran sous celles de Geist : une police large mange une ligne de plus à
   chaque palier, et un titre de trois lignes doit tenir sur un téléphone. */
h1,h2,h3{font-family:var(--titre);letter-spacing:0;text-wrap:balance}
h2{
  font-weight:600;
  font-size:clamp(23px,min(3.5vw,4.6vh),38px);line-height:1.16;
  margin:clamp(12px,1.8vh,20px) 0 clamp(12px,1.7vh,18px);
}
h3{font-weight:600;font-size:17px;line-height:1.36}
/* Les accents des grands titres etaient portes par un italique Instrument
   Serif, retire le 20/09/2026 avec le passage a une seule famille. Sans
   cette regle, <em> retomberait sur l'italique par defaut du navigateur —
   une voix que plus rien dans le site ne justifie. */
h1 em,h2 em,h3 em{font-style:normal}

/* ---------- Sur-titre ----------
   Purement décoratif : il informe, il n'agit pas. Donc jamais de braise
   dessus, et aria-hidden côté HTML. */
.eyebrow{
  display:inline-flex;align-items:center;gap:14px;
  font-family:var(--mono);font-size:12.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--braise);font-weight:600;
}
.eyebrow.center{justify-content:center}

/* ---------- En-tête ----------
   Le verre dépoli est conservé : la barre est posée SUR la page qui défile
   dessous. Un aplat opaque mangerait une bande de l'écran. Le fond est
   neutre, pas bleuté : c'était le dernier reste du système « la forge ». */
header{
  position:fixed;top:0;left:0;right:0;z-index:50;
  border-bottom:1px solid transparent;
  transition:background .2s var(--sortie),border-color .2s var(--sortie);
}
header.scrolled{
  background:rgba(8,9,10,.82);
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  border-bottom-color:var(--filet);
}
.nav{
  max-width:var(--w);width:100%;margin:0 auto;
  padding:clamp(12px,1.6vh,18px) var(--pad-x);
  display:flex;align-items:center;justify-content:space-between;gap:clamp(14px,2vw,24px);
}
.brand{
  display:flex;align-items:center;gap:11px;
  font-family:var(--titre);font-weight:600;font-size:18px;letter-spacing:0;
}
.brand .spark{width:26px;height:26px;flex:none}
.brand em{font-style:normal;color:var(--braise)}
.nav-links{display:flex;align-items:center;gap:30px;font-size:14.5px;font-weight:500;color:var(--brume)}
.nav-links a{transition:color .2s var(--sortie)}
@media (hover:hover) and (pointer:fine){
  .nav-links a:hover{color:var(--encre)}
}

/* En-tête des pages de fond (à propos, contact, mentions, CGV, merci, 404).
   Elle est posée dans le flux et non au-dessus : ces pages n'ont pas de hero
   à recouvrir, et une barre flottante y mangerait la première ligne du texte. */
header.simple{
  position:sticky;background:var(--fond);
  border-bottom-color:var(--filet);
}
.back{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brume);
  transition:color .16s var(--sortie);
}
@media (hover:hover) and (pointer:fine){
  .back:hover{color:var(--encre)}
}

/* ---------- Boutons ----------
   Aplat, rayon court, aucune ombre, aucun halo. Un bouton qui décolle de la
   page se regarde lui-même au lieu de désigner ce qu'il déclenche.
   Un seul bouton plein (.btn-ember) par écran. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  min-height:48px;padding:12px 20px;
  font-family:var(--texte);font-weight:600;font-size:14.5px;
  border-radius:var(--r-bouton);border:1px solid transparent;
  cursor:pointer;white-space:nowrap;
  transition:background .16s var(--sortie),border-color .16s var(--sortie),
             color .16s var(--sortie),transform .12s var(--sortie);
}
/* Le seul retour dont on dispose avant que le réseau réponde. */
.btn:active{transform:scale(.97)}
.btn[disabled]{opacity:.35;cursor:default;transform:none}
.btn .arrow{transition:transform .16s var(--sortie)}
@media (hover:hover) and (pointer:fine){
  .btn:hover .arrow{transform:translateX(4px)}
}

.btn-ember{background:var(--braise);color:var(--braise-nuit)}
.btn-ghost{background:var(--surface-2);color:var(--encre);border-color:var(--filet-fort)}
.btn-text{background:transparent;color:var(--brume);border:0;padding:13px 12px}
@media (hover:hover) and (pointer:fine){
  .btn-ember:hover{background:#f39d52}
  .btn-ghost:hover{background:var(--surface-3)}
  .btn-text:hover{color:var(--encre)}
}
/* Barre de navigation seulement : la cible garde ses 44 px de haut. */
.btn-sm{min-height:44px;padding:11px 20px;font-size:13.5px}

/* ---------- Coquille de section ---------- */
.section{padding:var(--sec-pad) 0}
.section-head{max-width:640px;margin-bottom:var(--head-gap)}
.section-head.center{margin-left:auto;margin-right:auto;text-align:center}
.section-head p{color:var(--brume);font-size:17px}

/* ---------- Chiffres en colonne ----------
   Oxanium n'est pas à chasse fixe : sans cette règle, un « 1 » est plus
   étroit qu'un « 8 » et une colonne de prix ou d'heures ondule. C'est ce qui
   remplace la police à chasse fixe que le système portait avant. */
.chiffres,.price,.stat-num,.cal-day,.slot,.tarif-bloc .v,.doc td{
  font-variant-numeric:tabular-nums;
}

/* ---------- Carte ---------- */
.carte{
  background:var(--surface-1);
  border:1px solid var(--filet);border-radius:var(--r-carte);
  padding:24px;
}

/* ---------- Formulaires ---------- */
form{display:grid;gap:16px}
.field{display:grid;gap:8px}
.field label{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--brume);
}
.field input,.field select,.field textarea{
  width:100%;padding:14px 16px;
  font-family:var(--texte);font-size:15.5px;color:var(--encre);
  background:var(--surface-2);border:1px solid var(--filet);
  border-radius:var(--r-champ);
  transition:border-color .16s var(--sortie),background .16s var(--sortie);
}
.field textarea{resize:vertical;min-height:110px}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--braise);background:var(--surface-3);
}
/* PIÈGE DE SPÉCIFICITÉ, déjà tombé deux fois — ne pas croire que cette
   règle fait doublon avec :focus-visible plus haut. `input:focus{outline:none}`
   pèse 0,1,1 et l'emporte sur `:focus-visible` seul, qui ne pèse que 0,1,0.
   D'où ce rappel à poids égal, placé après. */
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:2px solid var(--braise);outline-offset:2px;
}
.field select{
  appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%238a8f98' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 16px center;
}
.form-row{display:grid;grid-template-columns:1fr 1fr;gap:16px}

/* Confirmation : jade, et un mot qui double la couleur. Un filet vertical
   plutôt qu'un aplat — le message informe, il n'agit pas. */
.form-sent{
  display:none;align-items:center;gap:12px;
  background:var(--surface-2);border:1px solid var(--filet);
  border-left:3px solid var(--jade);
  color:var(--encre);border-radius:var(--r-champ);
  padding:14px 18px;font-size:14.5px;
}
.form-sent.show{display:flex}

/* ---------- Erreurs de formulaire ----------
   La braise est la couleur de la marque : elle ne peut pas dire aussi
   « erreur ». L'alerte en est assez éloignée en teinte pour ne jamais se
   confondre avec un bouton d'action. Le mot porte le sens, jamais la
   couleur seule. */
.err-msg{
  display:none;color:var(--alerte);font-size:13.5px;line-height:1.5;
  margin-top:7px;padding-left:13px;position:relative;
}
.err-msg.on{display:block}
/* Un trait vertical plutôt qu'une icône : le signal se pose sur le bord du
   champ, là où l'œil revient pour corriger. */
.err-msg::before{
  content:"";position:absolute;left:0;top:.42em;bottom:.42em;
  width:2px;background:var(--alerte);border-radius:2px;
}
.field.en-erreur label{color:var(--alerte)}
.field.en-erreur input,.field.en-erreur textarea,.field.en-erreur select,
input[aria-invalid="true"],textarea[aria-invalid="true"],select[aria-invalid="true"]{
  border-color:var(--alerte);
}

/* ---------- Bouton pendant l'envoi ----------
   La largeur est figée en JS avant le changement de texte : sans ça le
   bouton se redimensionne sous le doigt qui vient d'appuyer. */
.lf-rouet{
  display:inline-block;width:14px;height:14px;flex:none;
  border-radius:var(--r-rond);border:2px solid currentColor;
  border-top-color:transparent;
  animation:lf-tourne .7s linear infinite;
}
@keyframes lf-tourne{to{transform:rotate(1turn)}}
button.en-cours{cursor:progress;opacity:.85}

/* ---------- Consentement et liens discrets ---------- */
.consent{font-size:12.5px;line-height:1.5;color:var(--brume-2);margin-top:2px}
.consent a,.lien-sobre,.doc a.lien{
  color:var(--brume);border-bottom:1px solid var(--filet-fort);
  transition:color .16s var(--sortie),border-color .16s var(--sortie);
}
@media (hover:hover) and (pointer:fine){
  .consent a:hover,.lien-sobre:hover,.doc a.lien:hover{color:var(--encre);border-bottom-color:var(--braise)}
}

/* ---------- Pages de texte ----------
   Mentions légales, confidentialité, CGV : trois pages dont la seule tâche
   est d'être lues. Elles partagent la même mise en page, donc les mêmes
   règles — les tripler dans trois blocs <style> était la cause exacte de la
   dérive que ce fichier corrige. */
/* La classe se pose sur <body>. La colonne de lecture est plus étroite que
   le reste du site : au-delà de 65 caractères par ligne, l'œil perd le début
   de la ligne suivante. */
.doc .wrap{max-width:760px}
.doc main{padding:clamp(44px,calc(4.5vh + 2vw),80px) 0 clamp(56px,calc(6vh + 2.4vw),100px)}
.doc h1{font-weight:600;font-size:clamp(32px,4.6vw,48px);line-height:1.08;margin-bottom:10px}
/* Date de mise à jour : elle informe, donc elle reste en brume. */
.doc .maj{font-family:var(--mono);font-size:12px;letter-spacing:.1em;color:var(--brume-2);margin-bottom:52px}
.doc h2{
  font-size:21px;margin:46px 0 14px;padding-top:26px;
  border-top:1px solid var(--filet);
}
.doc p,.doc li,.doc dd{color:var(--brume);margin-bottom:14px;max-width:65ch}
.doc p b,.doc p strong,.doc li b{color:var(--encre);font-weight:600}
.doc table{width:100%;border-collapse:collapse;margin:6px 0 18px;font-size:14px;min-width:520px}
.doc th,.doc td{text-align:left;padding:10px 13px;border:1px solid var(--filet);color:var(--brume);vertical-align:top}
.doc th{color:var(--encre);font-weight:600;background:var(--surface-2);font-size:13px}
/* Un tableau large ne se réduit pas : on le fait défiler seul plutôt que de
   laisser la page déborder. Le conteneur est focalisable au clavier, sans
   quoi son contenu serait inatteignable sans souris. */
.doc .table-defile{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:6px 0 18px;border-radius:var(--r-champ);scrollbar-width:thin}
.doc .table-defile table{margin:0}
.doc .todo,.todo{
  display:inline-block;background:var(--surface-2);border:1px solid var(--filet);
  color:var(--brume);border-radius:var(--r-champ);padding:1px 9px;
  font-family:var(--mono);font-size:13px;
}
.doc .note{
  background:var(--surface-1);border:1px solid var(--filet);
  border-left:3px solid var(--braise);border-radius:var(--r-champ);
  padding:16px 20px;margin:8px 0 20px;color:var(--brume);font-size:14.5px;
}
/* Sous 560 px, lire est la seule tâche de la page : on resserre le rythme
   vertical, et on force la césure des adresses longues — seuls éléments qui
   débordent réellement de la colonne. */
@media (max-width:560px){
  .doc{font-size:15.5px}
  .doc main{padding-top:clamp(28px,5vh,40px)}
  .doc .maj{margin-bottom:34px}
  .doc h2{font-size:19px;margin:34px 0 12px;padding-top:20px}
  .doc p,.doc li,.doc dd{overflow-wrap:anywhere}
  .doc table{font-size:13px}
  .doc th,.doc td{padding:8px 10px}
}

/* ---------- Pied de page ---------- */
footer{border-top:1px solid var(--filet);padding:clamp(30px,4vh,44px) 0;margin-top:var(--sec-pad)}
.foot{
  max-width:var(--w);margin:0 auto;padding:0 var(--pad-x);
  display:flex;flex-wrap:wrap;gap:24px;align-items:center;justify-content:space-between;
  color:var(--brume-2);font-size:14px;
}
.foot .brand{font-size:15px}
.foot-links{display:flex;flex-wrap:wrap;gap:16px 26px}
.foot-links a{transition:color .16s var(--sortie)}
@media (hover:hover) and (pointer:fine){
  .foot-links a:hover{color:var(--encre)}
}

/* ---------- Menu mobile ---------- */
.menu-btn{
  display:none;background:none;border:0;color:var(--encre);
  cursor:pointer;padding:8px;margin-left:-4px;
  min-width:44px;min-height:44px;align-items:center;justify-content:center;
}
.mobile-menu{
  position:fixed;inset:0;z-index:70;
  background:var(--fond);
  display:flex;flex-direction:column;justify-content:center;align-items:center;gap:8px;
  opacity:0;pointer-events:none;transition:opacity .2s var(--sortie);
}
.mobile-menu.open{opacity:1;pointer-events:auto}
.mobile-menu a{
  font-family:var(--titre);font-weight:600;font-size:22px;
  padding:14px 24px;color:var(--encre);letter-spacing:0;
}
.mobile-menu .btn{margin-top:22px;font-size:16px}
.mobile-close{
  position:absolute;top:20px;right:20px;
  background:none;border:1px solid var(--filet-fort);border-radius:var(--r-bouton);
  color:var(--encre);cursor:pointer;padding:9px;display:flex;
  min-width:44px;min-height:44px;align-items:center;justify-content:center;
}

/* ---------- Apparition au défilement ----------
   Un fondu court et une translation de 18 px. Au-delà, le contenu semble
   arriver en retard sur le doigt qui a fait défiler. */
.reveal{
  opacity:0;transform:translateY(18px);
  transition:opacity .26s var(--sortie),transform .26s var(--sortie);
}
.reveal.in{opacity:1;transform:none}
.reveal.d1{transition-delay:.06s}
.reveal.d2{transition-delay:.12s}
.reveal.d3{transition-delay:.18s}

/* ---------- Barre d'action flottante (téléphone) ----------
   Sous 680 px, le bouton du bandeau passe en display:none et se retrouve
   enfermé dans le menu. Cette barre rend une action atteignable au pouce
   sur toute la longueur de la page. Elle disparaît sur les sections qui
   portent déjà l'action (data-cta-masque). */
#cta-flottant{
  position:fixed;left:0;right:0;bottom:0;z-index:45;
  display:none;align-items:center;gap:14px;
  padding:11px clamp(14px,4vw,20px);
  padding-bottom:calc(11px + env(safe-area-inset-bottom,0px));
  background:var(--surface-1);
  border-top:1px solid var(--filet-fort);
  transform:translateY(102%);opacity:0;pointer-events:none;
  transition:transform .26s var(--sortie),opacity .2s var(--sortie);
}
#cta-flottant.on{transform:none;opacity:1;pointer-events:auto}
.cta-f-txt{flex:1;min-width:0;line-height:1.22}
.cta-f-txt b{display:block;font-weight:600;font-size:14px;color:var(--encre);font-family:var(--titre)}
.cta-f-txt span{display:block;font-size:12px;color:var(--brume)}
#cta-flottant .btn{flex:none;padding:12px 20px;font-size:14px}

/* ---------- Adaptation ---------- */
@media (max-width:1400px){
  .nav-links{gap:clamp(18px,2.1vw,30px)}
}
/* Les six entrees de menu plus le bouton ne tiennent plus des 860 px : elles
   debordaient de la barre sur une tablette en portrait. Le menu passe donc au
   bouton d'ouverture bien avant le telephone. Le bouton d'action, lui, reste
   visible jusqu'a 680 px : c'est l'action de la page, elle ne se range pas
   dans un menu tant qu'il y a la place. */
@media (max-width:860px){
  .nav-links{display:none}
  .menu-btn{display:flex}
}
@media (max-width:680px){
  .nav .btn-sm{display:none}
  .section{padding:clamp(52px,7vh,80px) 0}
  .form-row{grid-template-columns:1fr}
  #cta-flottant{display:flex}
  /* La barre ne doit jamais recouvrir la dernière ligne du pied de page :
     on lui réserve sa hauteur. */
  body{padding-bottom:calc(76px + env(safe-area-inset-bottom,0px))}
}

/* ---------- Mouvement réduit ----------
   Les déplacements tombent, les fondus restent. Rien ne doit rester
   invisible : c'est le point de contrôle numéro 9 du DESIGN.md. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .reveal{opacity:1;transform:none;transition:none}
  #cta-flottant{transform:none;transition:opacity .2s var(--sortie)}
  /* Sans mouvement, l'anneau reste plein et respire : le retour doit
     exister, seul le tournis disparaît. */
  .lf-rouet{animation:lf-respire 1.2s ease-in-out infinite;border-top-color:currentColor}
  @keyframes lf-respire{50%{opacity:.32}}
  *{transition-duration:.01ms!important}
}
