/* ============================================================================
   DESIGN SYSTEM v1 — valide en aout 2026.

   LE SITE A DEUX SURFACES, ET UNE SEULE REGLE POUR EN CHANGER.

   NUIT   (#01192b) : ce qui vend. Accueil, pages de formation, bandes.
                      C'est la surface par defaut : elle est posee sur <body>.
   PAPIER (#fffef6) : ce qui se lit. Espace eleve, pages d'etape, conseils,
                      formulaires, pages legales. On la lit dehors, en plein
                      soleil, telephone a la main, un chien au bout de la
                      laisse : elle garde donc le fond clair et les contrastes
                      maximaux du site precedent.

   POUR CHANGER DE SURFACE, on ne repeint aucune couleur a la main : on pose
   la classe "papier" sur <main> (page entiere) ou sur une <section>. Tout le
   reste suit tout seul, parce que les composants ne connaissent pas les
   couleurs : ils ne connaissent que les six roles ci-dessous.

     --fond        le fond de la surface
     --texte       le texte courant
     --titre       les titres
     --secondaire  le texte attenue (surtitres, mentions)
     --bord        les filets et les contours de cartes
     --carte       le fond d'une carte posee sur la surface

   AJOUTER UNE COULEUR EN DUR DANS UN COMPOSANT, C'EST CASSER CE MECANISME :
   le composant serait juste sur une surface et faux sur l'autre.

   LE ROUGE (--signal) EST UN SIGNAL, PAS UNE COULEUR.
   Il ne sert qu'a : un mot par titre, le badge "Avance", le badge "On commence
   ici", les guillemets d'un avis, la fin du degrade de progression.
   JAMAIS UN BOUTON. JAMAIS UN PRIX. Un rouge qu'on voit partout n'attire plus
   l'attention nulle part.
   ============================================================================ */
:root {
  /* --- Surface NUIT (par defaut) ------------------------------------- */
  --fond: #01192b;
  --texte: #c3d3e0;
  --titre: #ffffff;
  --secondaire: #7fa8c9;
  --bord: rgba(127, 168, 201, 0.18);
  --carte: rgba(255, 255, 255, 0.04);

  /* Les declinaisons du bleu de nuit. */
  --nuit: #01192b;
  --nuit-bande: #012843;      /* la bande des chiffres sous le hero */
  --nuit-section: #011f36;    /* une section qui doit se detacher du fond */
  --nuit-pied: #01121f;       /* le pied de page, le point le plus sombre */
  --acier: #7fa8c9;
  --brume: #c3d3e0;
  /* Le filet de la Nuit, fige. L en-tete et le pied de page le gardent meme
     au-dessus d une page Papier, ou --bord vaut autre chose. */
  --trait-nuit: rgba(127, 168, 201, 0.18);
  --trait-pointille: rgba(127, 168, 201, 0.35);
  --trait-bouton: rgba(127, 168, 201, 0.5);

  --color-bg: #fffef6;
  --color-bg-alt: #f3efdd;
  --color-navy: #023f70;
  --color-navy-dark: #012c4e;
  --color-teal: #0c4237;
  /* Les deux couleurs viennent du logo (assets/logo.png), rien n'est invente.
     L'accent porte les boutons et les liens : c'est le bleu marine, calme, qu'on
     peut mettre partout sans fatiguer l'oeil (contraste 10,4 pour 1).
     Le rouge, lui, est EN RESERVE : il ne sert qu'au prix et au mot mis en avant
     dans le titre. Un rouge qu'on voit partout n'attire plus l'attention nulle
     part ; celui-ci reste un signal. */
  --color-accent: #023f70;
  --color-accent-dark: #012c4e;
  --color-signal: #d4000d;
  /* Le bleu marine d'Agility Click & Run, releve sur leur site. Il se trouve
     etre exactement celui du logo Speed Link Dog. Il ne sert QUE dans la bande
     qui presente l'application.
     Leur orange (#ffad61) a ete retire le 4 aout 2026 : Mickael n'en voulait
     plus. La bande est desormais en bleu marine et blanc, sans troisieme
     couleur. Ne pas le reintroduire sans le lui demander. */
  --color-acr: #023f70;
  --color-white: #ffffff;
  /* Kanit reprend l'inclinaison du logo : les titres sont en italique et en
     capitales, comme le mot-verbal "SPEED LINK DOG". Titillium Web est gardee
     pour le texte courant — le lecteur ne change pas d'habitude de lecture. */
  --font-heading: 'Kanit', sans-serif;
  --font-body: 'Titillium Web', sans-serif;
  --radius: 12px;         /* cartes et photos */
  --radius-ligne: 10px;   /* lignes d'etape */
  --radius-bouton: 6px;   /* boutons : presque droit, plus sportif */
  --shadow: 0 12px 30px -14px rgba(2, 63, 112, 0.25);
}

/* ---------------------------------------------------------------------------
   LA SURFACE PAPIER. Une seule classe, six roles redefinis, et toute la page
   bascule. A poser sur <main> pour une page entiere, ou sur une <section>
   pour un passage de lecture au milieu d'une page de vente (la methode et le
   materiel d'une page de formation, le formulaire de contact de l'accueil).
   --------------------------------------------------------------------------- */
.papier {
  --fond: var(--color-bg);
  --texte: var(--color-teal);
  --titre: var(--color-navy);
  --secondaire: var(--color-navy-dark);
  --bord: rgba(2, 63, 112, 0.15);
  --carte: #ffffff;
  background: var(--fond);
  color: var(--texte);
}

* { box-sizing: border-box; }

/* Les images portent des attributs width/height dans le HTML (utile : le navigateur
   reserve la place avant de les charger, la page ne saute pas). Sans "height: auto",
   cette hauteur brute l'emporte sur la mise en page et deforme la photo. */
img { max-width: 100%; height: auto; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font-family: var(--font-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Les titres portent l'inclinaison du logo : italique, capitales, tres serres
   verticalement (0.98) pour que deux lignes forment un bloc et non deux
   phrases. h3 reste droit : un titre de carte en italique capitales serait
   illisible a cette taille. */
h1, h2 {
  font-family: var(--font-heading);
  font-style: italic;
  text-transform: uppercase;
  color: var(--titre);
  line-height: 0.98;
  margin: 0 0 0.5em;
  letter-spacing: 0;
}
h3 {
  font-family: var(--font-heading);
  color: var(--titre);
  line-height: 1.2;
  margin: 0 0 0.5em;
}

h1 { font-size: clamp(2.4rem, 4.5vw, 3.8rem); font-weight: 800; }
h2 { font-size: clamp(1.7rem, 3vw, 2.4rem); font-weight: 700; line-height: 1.05; }
h3 { font-size: 1.25rem; font-weight: 600; }

p { margin: 0 0 1em; }

a { color: var(--titre); }

/* LA MISE AU POINT AU CLAVIER.
   Le site est passe sur fond sombre. L'anneau que le navigateur dessine tout
   seul est souvent noir : sur la Nuit, il devient invisible, et une personne qui
   navigue au clavier ne sait plus ou elle est. On en pose donc un explicite,
   dans la couleur des titres de la surface — blanc sur la Nuit, marine sur le
   Papier. Il se voit dans les deux cas, sans rien changer a la souris. */
:focus-visible {
  outline: 2px solid var(--titre);
  outline-offset: 2px;
}

/* Les chiffres qui se comparent d'une ligne a l'autre (etapes, prix, chronos,
   progression) sont a chasse fixe : sans ca, "11" est plus etroit que "88" et
   une colonne de nombres tremble. */
.stat-number,
.bio-stat-number,
.module-price,
.offer-price,
.step-counter,
.module-meta,
.app-number { font-variant-numeric: tabular-nums; }

.container {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 24px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--color-navy);
  color: #fff;
  padding: 10px 16px;
  z-index: 100;
}
.skip-link:focus { left: 12px; top: 12px; }

/* HEADER
   L'en-tete est TOUJOURS en Nuit, y compris au-dessus d'une page Papier : c'est
   le seul element qui ne change jamais d'une page a l'autre, et c'est ce qui
   tient le site ensemble quand l'eleve passe de la boutique a ses classes. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(1, 25, 43, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--trait-nuit);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 76px;
}

.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: #fff;
}
.logo-mark { height: 44px; width: auto; display: block; }

.main-nav {
  display: flex;
  align-items: center;
  gap: 24px;
}
.main-nav a {
  text-decoration: none;
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--brume);
}
.main-nav a:hover { color: #fff; }
/* La pilule d'Agility Click & Run garde son bleu marine : cette bande parle
   d'un autre produit, elle garde donc sa propre couleur. */
.main-nav .nav-external {
  background: var(--color-navy);
  color: #fff;
  padding: 8px 16px;
  border-radius: 999px;
}
.main-nav .nav-external:hover { background: var(--color-navy-dark); color: #fff; }
/* "Mon espace" est la porte de ce que l'eleve a paye : c'est le seul lien du
   menu qui prend la forme d'un bouton. */
.main-nav .nav-espace {
  font-family: var(--font-heading);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  border: 1px solid var(--trait-bouton);
  border-radius: var(--radius-bouton);
  color: #fff;
  padding: 8px 18px;
  transition: border-color 0.15s ease;
}
.main-nav .nav-espace:hover { border-color: #fff; }

/* L'EN-TETE DE L'ESPACE ELEVE.
   Un eleve au milieu de sa classe n'a rien a faire de "Qui suis-je" ni de la
   bande de l'application : il a paye, il travaille. Le menu se reduit donc a
   deux liens — revenir a ses classes, et son compte — et l'en-tete se tasse de
   76 a 68 pixels. Le logo, lui, reste : c'est le bouton "sortir de l'espace".
   Les deux liens n'existent que la, et nulle part ailleurs. */
.nav-espace-retour,
.nav-espace-compte { display: none; }

.espace .main-nav > a { display: none; }
.espace .main-nav > .nav-espace-retour,
.espace .main-nav > .nav-espace-compte { display: inline-block; }
.espace .header-inner { height: 68px; }
.espace .logo-mark { height: 38px; }
.espace .main-nav { gap: 22px; }
.espace .nav-espace-compte {
  font-family: var(--font-heading);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  border: 1px solid var(--trait-bouton);
  border-radius: var(--radius-bouton);
  color: #fff;
  padding: 7px 16px;
  transition: border-color 0.15s ease;
}
.espace .nav-espace-compte:hover { border-color: #fff; }
/* Le menu deroulant du telephone n'a plus lieu d'etre avec deux liens. */
/* LE MENU BASCULE EN HAMBURGER A 960 PIXELS, ET PAS PLUS TARD.
   Mesure du 21 aout 2026 : les neuf liens du menu francais occupent 745
   pixels, le logo 105, les marges du conteneur 48 — il faut donc 898 pixels
   pour que la barre tienne. Le seuil etait a 720 : dans une fenetre de 768
   (tablette en portrait, ou navigateur a moitie d ecran) le menu depassait de
   20 pixels et TOUTE la page se decalait horizontalement.
   960 et non 900 : a 900 pile il ne restait que deux pixels de marge, et un
   seul mot de menu ajoute un jour ferait revenir le defaut.
   Ce bloc est separe de celui des grilles, qui reste a 720 : replier les
   cartes sur une colonne des 960 pixels gacherait toutes les tablettes. */
@media (max-width: 960px) {
  .espace .nav-toggle { display: none; }
  .espace .main-nav {
    position: static;
    flex-direction: row;
    padding: 0;
    gap: 14px;
    background: none;
    border: 0;
    transform: none;
    opacity: 1;
    pointer-events: auto;
  }
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  background: none;
  border: none;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  height: 2px;
  background: #fff;
  border-radius: 2px;
}

/* HERO */
.hero { padding: 80px 0 0; overflow: hidden; }
.hero-inner {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 48px;
  align-items: center;
  padding-bottom: 64px;
}
.hero-copy { text-align: left; }
/* Sur la Nuit, une photo n'a pas besoin d'ombre : le fond sombre la detache
   deja. Le coin arrondi discret suffit a la poser. */
.hero-media img {
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  display: block;
  object-fit: cover;
  aspect-ratio: 3 / 2;
}
.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.22em;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--secondaire);
  margin-bottom: 16px;
}
.eyebrow.center { text-align: center; }
/* Le mot mis en avant dans le titre : c'est l'un des deux seuls endroits ou le
   rouge sort de sa reserve. Sans lui, le mot serait bleu sur un titre bleu. */
/* ⚠️ SURTOUT PAS « h1 span » TOUT COURT. L'animation du titre (js/script.js)
   decoupe CHAQUE MOT du h1 dans des <span class="mot"><span class="mot-in">.
   La regle nue attrapait ces enveloppes-la aussi : des que l'animation
   tournait, LE TITRE ENTIER passait au rouge. Vu en ligne le 21 aout 2026 —
   les controles automatiques mesuraient la page avant l'animation et ne
   voyaient rien. On ne vise donc que la span ecrite a la main dans le HTML
   (le mot mis en avant), jamais les enveloppes de l'animation. */
h1 span:not(.mot):not(.mot-in) { color: var(--color-signal); }
.hero-lead { font-size: 1.1rem; max-width: 56ch; }
.hero-actions { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 10px; }

/* LES DEUX PORTES D'ENTREE
   Le site parle a deux publics tres differents : celui qui debute en club et
   celui qui concourt deja. Sans ces deux portes, la page d'accueil ne s'adresse
   qu'au second, et le debutant repart sans savoir par ou commencer. */
/* 64px sous les cartes : la bande des chiffres arrive juste apres, et sans cet
   air les cartes tombaient directement sur son filet (vu le 21 aout 2026).
   Pas de marge au-dessus : le hero porte deja ses 64px de bas. */
.entry-grid { display: grid; gap: 20px; margin: 0 0 64px; }
@media (min-width: 760px) { .entry-grid { grid-template-columns: 1fr 1fr; } }
.entry-card {
  display: block;
  background: var(--carte);
  border-radius: var(--radius);
  padding: 26px 24px;
  border: 1px solid var(--bord);
  text-decoration: none;
  color: inherit;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
/* Vers la droite, pas vers le haut : tout ce qui bouge sur ce site part dans le
   sens de la course. */
.entry-card:hover { transform: translateX(4px); border-color: var(--acier); }
.entry-card h3 { margin: 0 0 8px; }
.entry-card p { margin: 0; font-size: 0.96rem; }
.entry-go {
  display: inline-block;
  margin-top: 14px;
  font-weight: 700;
  color: var(--titre);
}
/* Le rouge au survol d'un lien-fleche est la seule sortie de reserve autorisee
   en dehors des titres et des badges : il dure le temps du survol. */
.entry-card:hover .entry-go { color: var(--color-signal); }

/* LES BOUTONS
   Presque droits (6px), en Kanit capitales : ils ont la forme d'un dossard, pas
   d'une pilule. Au survol ils glissent de 3px VERS LA DROITE — le sens de la
   course. Aucun bouton n'est rouge, sur aucune surface : le rouge est un
   signal, et un signal qu'on peut cliquer n'en est plus un. */
.btn {
  display: inline-block;
  padding: 14px 32px;
  border-radius: var(--radius-bouton);
  font-family: var(--font-heading);
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  text-decoration: none;
  transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease;
  border: 1px solid transparent;
}
/* Le bouton principal. Sur Nuit il est blanc, sur Papier il est marine : dans
   les deux cas, c'est la valeur la plus eloignee du fond. */
.btn-accent {
  background: #fff;
  color: var(--color-navy);
  font-style: italic;
}
.btn-accent:hover { background: #dfe8f1; color: var(--color-navy); transform: translateX(3px); }
.papier .btn-accent { background: var(--color-navy); color: #fff; }
.papier .btn-accent:hover { background: var(--color-navy-dark); color: #fff; }

/* Le bouton secondaire : un contour, jamais un aplat. Il accompagne le
   principal sans lui disputer le regard. */
.btn-ghost {
  border-color: var(--trait-bouton);
  color: var(--titre);
  font-weight: 600;
  font-size: 0.95rem;
}
.btn-ghost:hover { border-color: #fff; color: #fff; }
.papier .btn-ghost { border-color: var(--color-navy); color: var(--color-navy); }
.papier .btn-ghost:hover { background: var(--color-navy); border-color: var(--color-navy); color: #fff; }

/* LA BANDE DES CHIFFRES. Un bleu a peine plus clair que le fond, tenu par deux
   filets : elle marque une respiration sans couper la page en deux. */
.hero-stats {
  background: var(--nuit-bande);
  border-top: 1px solid var(--bord);
  border-bottom: 1px solid var(--bord);
  padding: 30px 0;
}
.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  text-align: center;
}
.stat-number {
  display: block;
  font-family: var(--font-heading);
  font-style: italic;
  font-size: 2.3rem;
  font-weight: 800;
  line-height: 1.1;
  /* Blanc franc : la hierarchie avec l'intitule vient de la taille et de la
     graisse, pas de la couleur. */
  color: #fff;
}
.stat-label {
  display: block;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
  /* Acier plein plutot qu'un blanc transparent : une opacite sur fond sombre
     donne un gris sale, et le contraste devient impossible a verifier. */
  color: var(--acier);
}

/* SECTIONS */
.section { padding: 88px 0; }
.papier.section, .papier .section { padding: 80px 0; }
/* Une section qui doit se detacher du fond : sur Nuit elle s'eclaircit d'un
   ton, sur Papier elle prend le sable. */
.section-alt { background: var(--nuit-section); }
.papier .section-alt, .section-alt.papier { background: var(--color-bg-alt); }
.section-lead { max-width: 65ch; margin-left: auto; margin-right: auto; font-size: 1.02rem; }
.center { text-align: center; margin-left: auto; margin-right: auto; }

.split {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: 56px;
  align-items: center;
}
.split-media { display: flex; justify-content: center; }
.portrait-photo {
  width: 100%;
  max-width: 380px;
  border-radius: var(--radius);
  object-fit: cover;
}

.bio-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin: 24px 0;
}
.bio-stat {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--radius-ligne);
  padding: 16px 12px;
  text-align: center;
}
.bio-stat-number {
  display: block;
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 800;
  font-size: 1.5rem;
  line-height: 1.15;
  color: var(--titre);
}
.bio-stat-label {
  display: block;
  font-size: 0.78rem;
  color: var(--secondaire);
}
.bio-teaser {
  font-style: italic;
  opacity: 0.85;
}

.team-photo {
  margin: 24px 0 0;
}
.team-photo img {
  width: 100%;
  border-radius: var(--radius);
  display: block;
}
.team-photo figcaption {
  margin-top: 8px;
  font-size: 0.85rem;
  color: var(--secondaire);
}

/* LA GALERIE, BORD A BORD.
   Quatre photos collees, sans marge, sans coin arrondi, sans ombre : c'est le
   seul endroit du site ou l'image touche les deux bords de l'ecran. Elle coupe
   la page en deux comme une bande de pellicule, et c'est voulu — le reste du
   site est fait de cartes, il fallait une respiration qui n'en soit pas une. */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
}
.gallery-grid img {
  width: 100%;
  aspect-ratio: 3 / 2.4;
  object-fit: cover;
  display: block;
}
/* Les photos touchent le bas de leur section : sans cette ligne, une bande de
   fond de 88 pixels s'intercalerait entre la galerie et la section suivante, et
   le bord a bord n'aurait plus aucun sens. */
.gallery-section { padding-bottom: 0; }

/* FEATURE GRID */
.feature-grid {
  margin-top: 48px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}
.feature-card {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--radius);
  padding: 26px 22px;
}
.feature-card p { color: var(--texte); font-size: 0.94rem; }
.feature-card h3 { font-size: 1.1rem; }
/* Les numeros 01-04 sont ROUGES : c'est ecrit tel quel dans la maquette
   Accueil v2 validee par Mickael. C'est une des rares sorties de reserve du
   rouge — quatre petits chiffres, pas un pave. */
.feature-icon {
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 800;
  font-size: 1.2rem;
  color: var(--color-signal);
  line-height: 1;
  margin-bottom: 10px;
}

/* MODULES */
.modules-grid {
  margin-top: 48px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
}
.module-card {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--radius);
  padding: 28px;
  display: flex;
  flex-direction: column;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.module-card:hover { transform: translateX(4px); border-color: var(--acier); }
.module-card p { flex: 1; color: var(--texte); }
.module-link {
  font-weight: 700;
  text-decoration: none;
  color: var(--titre);
}
.module-link:hover { color: var(--color-signal); }

/* AVIS */
.avis-grid {
  margin-top: 44px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 22px;
  align-items: start;
}
.avis-card {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--radius);
  padding: 28px;
  margin: 0;
}
.avis-card blockquote {
  margin: 0 0 18px;
  font-size: 1rem;
  line-height: 1.65;
}
/* Les guillemets sont la seule decoration de la carte, et le seul rouge de la
   section. Ces avis sont repris mot pour mot de Facebook : rien d'autre ne
   vient les habiller. */
.avis-card blockquote::before,
.avis-card blockquote::after {
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 800;
  font-size: 1.4rem;
  color: var(--color-signal);
}
.avis-card blockquote::before { content: "« "; }
.avis-card blockquote::after { content: " »"; }
.avis-card figcaption { display: flex; flex-direction: column; gap: 2px; }
.avis-name { font-family: var(--font-heading); font-weight: 600; color: var(--titre); }
.avis-meta { font-size: 0.85rem; color: var(--secondaire); }

/* PROMO BANNER */
/* LE BLOC AGILITY CLICK & RUN
   Cette bande presente un autre produit : elle parle donc SA langue, pas celle
   de Speed Link Dog. Couleurs relevees le 3 aout 2026 sur agilityclickandrun.fr :
   fond bleu marine #023F70 (le meme que le logo Speed Link Dog, heureuse
   coincidence) et un ambre #FFAD61 pour les accents. Le vert #0C4237 qui etait
   ici n'existait nulle part chez eux. */
.promo-banner { background: var(--color-acr); color: #fff; padding: 64px 0; }
.promo-banner h2, .promo-banner p { color: #fff; }
.promo-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  flex-wrap: wrap;
}
.promo-inner > div { max-width: 620px; }
/* Le surtitre etait lui aussi en orange : c'etait le troisieme et dernier
   endroit. Blanc attenue, pour rester au-dessus du titre sans le concurrencer. */
.promo-banner .promo-eyebrow { color: #fff; opacity: 0.82; }

.promo-head { text-align: center; max-width: 760px; margin: 0 auto; }
.promo-head .section-lead { color: #fff; opacity: 0.9; }

.app-grid {
  margin-top: 48px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 22px;
}
.app-card {
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--radius);
  padding: 26px 22px;
}
.app-card h3 { color: #fff; font-size: 1.05rem; }
.app-card p { font-size: 0.93rem; opacity: 0.85; margin: 0; color: #fff; }
.app-number {
  display: block;
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 800;
  font-size: 1.9rem;
  /* Blanc, comme les chiffres de la bande sous le hero. La hierarchie vient de
     la taille et de la graisse, pas d'une couleur en plus. */
  color: #fff;
  line-height: 1;
  margin-bottom: 12px;
}
.promo-actions {
  margin-top: 40px;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
}
.promo-note {
  flex-basis: 100%;
  text-align: center;
  font-size: 0.9rem;
  opacity: 0.85;
  margin: 8px 0 0;
}
/* Souligne, comme au pied de page : sur un fond ou tout est blanc, c'est le
   trait qui dit "ceci se clique", plus la couleur. */
.promo-note a { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.promo-note a:hover { opacity: 0.75; }

/* Sur le fond bleu marine, un bouton bleu marine serait invisible. */
.promo-actions .btn-accent { background: #fff; color: var(--color-acr); box-shadow: none; }
/* Au survol, le bouton se teinte tres legerement de bleu au lieu de changer de
   couleur. Un bouton blanc qui vire a l'orange attire l'oeil plus fort que le
   titre juste au-dessus : le survol doit confirmer, pas crier. */
.promo-actions .btn-accent:hover { background: #dfe8f1; color: var(--color-acr); }

/* CONTACT
   La section reste en Nuit — c'est la maquette qui le dit : titre blanc, liens
   blancs qui rougissent au survol, et le FORMULAIRE seul est une carte Papier
   posee dessus (classe "papier" sur le <form> dans index.html). Un formulaire
   sombre-sur-sombre serait le seul endroit du site ou l'on ecrit, rendu
   illisible au moment precis ou le visiteur fait un effort. */
.contact-links { list-style: none; padding: 0; margin: 20px 0 0; }
.contact-links li { margin-bottom: 10px; }
.contact-links a { text-decoration: none; font-weight: 600; }
.contact-links a:hover { color: var(--color-signal); }

.contact-form {
  padding: 32px;
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
}
.contact-form label { font-weight: 600; margin: 12px 0 6px; font-size: 0.9rem; }
.contact-form input,
.contact-form textarea {
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 11px 14px;
  border-radius: 8px;
  border: 1px solid rgba(2, 63, 112, 0.2);
  background: #fff;
  color: var(--color-teal);
}
.contact-form button { margin-top: 18px; cursor: pointer; align-self: flex-start; }
/* Pendant l'envoi, le bouton est desactive : sans ca, un visiteur presse clique
   trois fois et recoit trois fois le meme message. */
.contact-form button[disabled] { opacity: 0.6; cursor: progress; }

/* Le piege a robots. On ne met pas "display: none" : beaucoup de robots savent
   ignorer un champ cache de cette facon. Sorti de l'ecran, il reste un champ
   normal a leurs yeux. aria-hidden et tabindex="-1" (dans le HTML) le retirent
   des lecteurs d'ecran et du parcours au clavier. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-consent { margin-top: 12px; font-size: 0.82rem; color: var(--color-teal); opacity: 0.85; }
.form-consent a { color: var(--color-accent-dark); }

.form-note { margin-top: 12px; font-size: 0.9rem; color: var(--secondaire); }
/* Le resultat de l'envoi. La couleur seule ne suffit pas a distinguer une
   reussite d'une erreur (daltonisme) : le texte le dit toujours explicitement. */
.form-note.is-ok { color: var(--color-teal); font-weight: 600; }
.form-note.is-error { color: var(--color-signal); font-weight: 600; }
.form-note a { color: inherit; }

/* FOOTER
   Le point le plus sombre de la page : il ferme le site sans concurrencer la
   derniere section. Toujours en Nuit, comme l'en-tete. */
.site-footer {
  background: var(--nuit-pied);
  color: var(--brume);
  padding: 26px 0;
  border-top: 1px solid var(--trait-nuit);
}
.footer-inner {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 0.9rem;
}
/* Les liens du pied de page sont blancs comme le reste. Le souligne est la pour
   qu'on voie que ce sont des liens : sans lui, "Mentions legales" et "CGV"
   ressembleraient a du texte normal, et ces deux-la sont obligatoires. */
.footer-inner a { color: var(--brume); text-decoration: underline; text-underline-offset: 3px; }
.footer-inner a:hover { color: #fff; }

/* MODULE CARDS — prix, etapes, badge "en preparation" */
.module-meta {
  list-style: none;
  padding: 0;
  margin: 0 0 18px;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 14px;
  font-size: 0.88rem;
  color: var(--secondaire);
}
/* LE PRIX EST BLANC, PAS ROUGE.
   Il etait rouge : c'etait la faute qui vidait le rouge de son sens. Un prix
   n'a pas besoin d'etre crie, il a besoin d'etre lu — la hierarchie vient de la
   taille et de la graisse. Le rouge reste au mot du titre et aux badges. */
.module-price {
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 800;
  font-size: 1.4rem;
  color: var(--titre);
  opacity: 1;
  margin-left: auto;
}

/* LE BADGE DE NIVEAU : un parallelogramme incline.
   C'est le seul element "dessine" du systeme, repris de la trainee de pixels du
   logo. L'inclinaison est portee par un calque en arriere-plan et NON par le
   badge lui-meme : incliner la boite inclinerait aussi le texte, qui devient
   illisible a 0.72rem. Le calque penche, le mot reste droit. */
.module-badge {
  position: relative;
  isolation: isolate;
  align-self: flex-start;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 5px 14px;
  margin-bottom: 16px;
}
.module-badge::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--color-navy);
  transform: skewX(-10deg);
}
/* Le niveau se lit a la couleur avant de se lire au mot : marine pour ce qui
   est ouvert a tous, acier pour l'intermediaire, rouge pour l'avance. Le rouge
   sert ici de mise en garde — cette classe-la demande des bases. */
.module-badge.is-intermediaire { color: var(--nuit); }
.module-badge.is-intermediaire::before { background: var(--acier); }
.module-badge.is-avance::before { background: var(--color-signal); }
/* Le titre traduit en francais courant, pour les debutants. */
.module-plain {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--secondaire);
  margin: -4px 0 12px;
  flex: none;
}
/* "En preparation" : ni fond, ni aplat, ni survol. Une classe qui n'existe pas
   encore ne doit pas se comporter comme une classe qu'on peut ouvrir. */
.module-badge.is-coming { color: var(--acier); }
.module-badge.is-coming::before {
  background: transparent;
  border: 1px dashed var(--trait-bouton);
}
.module-card.is-coming { background: transparent; border-style: dashed; border-color: var(--trait-pointille); }
.module-card.is-coming:hover { transform: none; border-color: var(--trait-pointille); }
.module-link.is-muted { color: var(--acier); font-weight: 600; }

/* PAGE FORMATION */
.container.narrow { max-width: 760px; }

/* LE HERO D'UNE FORMATION.
   Une photo de l'obstacle passe derriere le titre, tres attenuee : elle dit de
   quoi parle la page avant meme qu'on lise. Toutes les classes n'en ont pas —
   seules celles dont on possede vraiment la photo (voir "image" dans
   modules-data.json). Sans photo, le hero reste uni, et c'est tres bien. */
.module-hero {
  position: relative;
  overflow: hidden;
  background: var(--nuit);
  padding: 88px 0 72px;
}
.module-hero-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 0.18 et pas davantage : au-dela, le texte blanc passe encore mais l'acier
     des pilules tombe sous le contraste minimum sur les zones claires. */
  opacity: 0.18;
}
/* Le contenu repasse devant la photo. */
.module-hero > .container { position: relative; }
/* Le badge de niveau du hero. Le meme composant que sur la carte du catalogue,
   mais hors d'une carte en colonne : il lui faut donc son propre affichage. */
.module-hero .module-badge { display: inline-block; margin-bottom: 18px; }
.module-hero .eyebrow a { color: var(--acier); text-decoration: none; }
.module-hero .eyebrow a:hover { color: #fff; }
.module-hero h1 { max-width: 20ch; font-size: clamp(2.6rem, 5vw, 4.2rem); }
.module-hero .form-note { margin-top: 16px; max-width: 60ch; color: var(--acier); }
.module-authors { font-size: 0.92rem; font-style: italic; color: var(--secondaire); margin: 0 0 20px; }

/* Les faits de la classe : des pilules a contour, jamais des aplats. Elles se
   lisent en diagonale — nombre d'etapes, tutoriels, prix. */
.module-facts {
  list-style: none;
  padding: 0;
  margin: 24px 0 28px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.module-facts li {
  border: 1px solid var(--trait-pointille);
  border-radius: 999px;
  padding: 6px 16px;
  font-size: 0.88rem;
}
.module-facts strong { font-family: var(--font-body); font-weight: 700; color: #fff; }

.module-plain-lead {
  font-family: var(--font-heading);
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--acier);
  margin: -6px 0 16px;
  max-width: 34ch;
}

/* LE MATERIEL */
/* "Se commence a la maison" : une pilule, pas une phrase. C'est l'argument qui
   leve le plus d'objections chez un debutant sans materiel — il doit se voir
   d'un coup d'oeil dans la carte, au meme rang que le niveau. */
.module-home {
  align-self: flex-start;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--texte);
  border: 1px solid var(--trait-pointille);
  border-radius: 999px;
  padding: 5px 14px;
  margin: 0 0 14px;
  flex: none;
}
.module-home::before { content: "🏠 "; }

.equip-home {
  background: var(--color-bg-alt);
  border-left: 4px solid var(--color-accent);
  border-radius: 8px;
  padding: 14px 18px;
  font-weight: 600;
  margin-bottom: 24px;
}
.equip-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
  align-items: start;
  margin-bottom: 20px;
}
.equip-card {
  background: var(--color-bg-alt);
  border-radius: var(--radius);
  padding: 24px;
}
.equip-card.is-later { background: transparent; border: 1px dashed rgba(2, 63, 112, 0.25); }
.equip-card h3 { font-size: 1rem; margin-bottom: 12px; }
.equip-card ul { list-style: none; padding: 0; margin: 0; }
.equip-card li { position: relative; padding-left: 20px; margin-bottom: 10px; font-size: 0.94rem; }
.equip-card li::before {
  content: "•";
  position: absolute;
  left: 0;
  color: var(--color-accent);
  font-weight: 700;
}

/* POUR QUI C'EST / CE N'EST PAS ENCORE */
.audience-grid {
  margin-top: 40px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
  align-items: start;
}
/* "POUR QUI C'EST" / "POUR QUI CE N'EST PAS ENCORE".
   Les deux cartes sont identiques : c'est la coche ou le tiret qui separe, pas
   un habillage. La carte "pas encore" garde un contour pointille, comme les
   classes en preparation — meme grammaire pour "ce n'est pas pour maintenant". */
.audience-card {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--radius);
  padding: 28px;
}
.audience-card.is-no { background: transparent; border-style: dashed; border-color: var(--trait-pointille); }
.audience-card ul { list-style: none; padding: 0; margin: 0; }
.audience-card li { position: relative; padding-left: 28px; margin-bottom: 12px; }
.audience-card li::before {
  position: absolute;
  left: 0;
  top: 0;
  font-weight: 700;
}
.audience-card.is-yes li::before { content: "✓"; color: var(--titre); }
.audience-card.is-no li::before { content: "—"; color: var(--secondaire); }
.audience-note { margin-top: 32px; font-size: 0.98rem; }

.check-list { list-style: none; padding: 0; margin: 0 0 1em; }
.check-list li { position: relative; padding-left: 30px; margin-bottom: 12px; }
.check-list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  font-weight: 700;
  color: var(--titre);
}

/* NIVEAUX / OFFRES */
.offer-grid {
  margin-top: 40px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  align-items: start;
}
.offer-card {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--radius);
  padding: 28px;
}
/* Le pack complet : un contour franc, et c'est tout. Pas d'ombre, pas de fond
   different — sur la Nuit, un simple trait clair suffit a dire "celui-la". */
.offer-card.is-featured {
  border-color: rgba(255, 255, 255, 0.55);
  border-width: 2px;
}
.offer-flag {
  position: relative;
  isolation: isolate;
  display: inline-block;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 5px 14px;
  margin-bottom: 12px;
}
.offer-flag::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--color-signal);
  transform: skewX(-10deg);
}
/* "On commence ici" n'est pas une promotion, c'est un ordre de marche : marine,
   pas rouge. Le rouge reste pour "Les deux niveaux, moins cher". */
.offer-flag.is-start::before { background: var(--color-navy); }
.offer-price {
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 800;
  font-size: 2.1rem;
  line-height: 1.1;
  color: var(--titre);
  margin: 0 0 12px;
}
.offer-meta { font-size: 0.85rem; color: var(--secondaire); margin: 0; }

/* LE PARCOURS : deux niveaux qui se suivent, pas deux produits concurrents. */
.offer-path {
  max-width: 720px;
  margin: 40px auto 0;
}
.offer-card.is-step { position: relative; padding-left: 92px; }
.offer-step-number {
  position: absolute;
  left: 26px;
  top: 28px;
  isolation: isolate;
  width: 44px;
  height: 44px;
  color: #fff;
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 800;
  font-size: 1.3rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.offer-step-number::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--color-navy);
  transform: skewX(-10deg);
}
.offer-prereq {
  font-size: 0.88rem;
  color: var(--secondaire);
  border: 1px solid var(--bord);
  border-radius: 8px;
  padding: 10px 14px;
  margin: 0 0 12px;
}
/* La fleche entre les deux niveaux : elle dit qu'on les suit dans l'ordre, et
   qu'ils ne se concurrencent pas. */
.offer-arrow {
  text-align: center;
  font-size: 1.6rem;
  color: var(--acier);
  line-height: 1;
  padding: 14px 0;
}
.offer-card.is-bundle { max-width: 720px; margin: 32px auto 0; }

/* LES PETITS DESSINS DES ETAPES.
   Des reperes de lecture, pas des illustrations : ils coupent un long texte
   et rendent une idee saisissable d'un coup d'oeil. Ils suivent la couleur du
   texte, donc ils restent lisibles sur n'importe quel fond, y compris a
   l'impression. */
.step-schema {
  margin: 28px 0;
  padding: 20px 18px 14px;
  background: var(--color-bg-alt);
  border-radius: var(--radius);
  color: var(--color-navy);
}
.step-schema svg {
  display: block;
  width: 100%;
  max-width: 480px;
  height: auto;
  margin: 0 auto;
}
.step-schema figcaption {
  margin-top: 12px;
  text-align: center;
  font-size: 0.9rem;
  opacity: 0.75;
}

/* MES FACTURES, dans l'espace eleve.
   Une ligne par facture, lisible d'un coup d'oeil : le numero d'abord (c'est
   ce qu'un comptable demande), le montant aligne a droite pour que les
   chiffres se comparent verticalement. */
.factures-liste {
  list-style: none;
  margin: 24px 0 0;
  padding: 0;
  border-top: 1px solid rgba(2, 63, 112, 0.12);
}
.facture-ligne a {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 18px;
  padding: 16px 4px;
  border-bottom: 1px solid rgba(2, 63, 112, 0.12);
  text-decoration: none;
  color: inherit;
}
.facture-ligne a:hover { background: var(--color-bg-alt); }
.facture-numero {
  font-weight: 800;
  color: var(--color-navy);
  font-variant-numeric: tabular-nums;
}
.facture-objet { flex: 1 1 200px; }
.facture-date { font-size: 0.88rem; opacity: 0.7; }
.facture-montant {
  font-weight: 700;
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}

/* Le bouton d'achat au bas d'une carte de niveau.
   Il vient APRES le prix, les etapes et le prerequis : on ne demande de
   payer qu'une fois que tout ce qu'il fallait savoir a ete dit. */
.offer-acheter {
  margin-top: 18px;
}

/* Le dernier appel de la page de formation. Il se detache du fond comme les
   autres sections alternees — pas avec le sable, qui est une couleur de la
   surface Papier et qui rendrait le texte courant illisible ici. */
.cta-section { background: var(--nuit-section); }
.papier .cta-section, .cta-section.papier { background: var(--color-bg-alt); }
.center-actions { justify-content: center; }

/* ESPACE ELEVE */
.preview-banner {
  background: #fff2b8;
  color: #7a5b00;
  border-radius: var(--radius);
  padding: 14px 18px;
  margin-bottom: 28px;
  font-size: 0.92rem;
}

/* Progression : barre + compteur, remplis par le navigateur. */
.step-progress { margin-bottom: 28px; }
.step-progress-bar {
  height: 10px;
  border-radius: 999px;
  background: rgba(2, 63, 112, 0.1);
  overflow: hidden;
}
/* La barre part du marine et FINIT EN ROUGE. C'est la seule animation de
   l'espace eleve, et le seul degrade du site : le rouge n'arrive qu'a la fin,
   quand la classe est presque terminee. Il recompense, il n'alerte pas. */
.step-progress-bar span {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--color-navy), var(--color-signal));
  transition: width 0.4s ease;
}
.step-progress p {
  margin: 10px 0 0;
  font-weight: 600;
  font-size: 0.94rem;
  color: var(--color-navy);
}

.step-list { display: flex; flex-direction: column; gap: 10px; }
.step-group {
  font-family: var(--font-heading);
  font-style: italic;
  text-transform: uppercase;
  font-size: 1.1rem;
  margin: 26px 0 6px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--color-accent);
}
.step-group:first-child { margin-top: 0; }
.step-row {
  display: flex;
  align-items: center;
  gap: 16px;
  background: #fff;
  border: 1px solid rgba(2, 63, 112, 0.15);
  border-radius: var(--radius-ligne);
  padding: 14px 18px;
  text-decoration: none;
  color: var(--color-teal);
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.step-row:hover { border-color: var(--color-accent); transform: translateX(3px); }
/* Le numero d'etape reprend le parallelogramme du badge de niveau : meme
   inclinaison portee par un calque, meme chiffre droit par-dessus. C'est ce
   qui fait que l'espace eleve et la boutique sont visiblement le meme site. */
.step-num {
  position: relative;
  isolation: isolate;
  flex: none;
  width: 34px;
  height: 34px;
  color: var(--color-navy);
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
}
.step-num::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--color-bg-alt);
  transform: skewX(-10deg);
}
.step-label { flex: 1; font-weight: 600; }
.step-has-video,
.step-text-only {
  flex: none;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 4px 10px;
  border-radius: 999px;
}
.step-has-video { background: var(--color-bg-alt); color: var(--color-accent-dark); }
.step-text-only { background: rgba(2, 63, 112, 0.07); color: var(--color-navy); opacity: 0.75; }
.step-pending {
  flex: none;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 4px 10px;
  border-radius: 999px;
  background: #fff2b8;
  color: #7a5b00;
}

/* Etape validee : la coche n'apparait que si l'eleve a coche la case. */
.step-check {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--color-accent);
  color: #fff;
  font-weight: 700;
  display: none;
  align-items: center;
  justify-content: center;
}
.step-row.is-done { border-color: var(--color-accent); background: #fffaf7; }
.step-row.is-done .step-num { color: #fff; }
.step-row.is-done .step-num::before { background: var(--color-accent); }
.step-row.is-done .step-check { display: flex; }
.step-text-only-note {
  background: var(--color-bg-alt);
  border-radius: var(--radius);
  padding: 16px 20px;
  margin: 24px 0 28px;
  font-weight: 600;
}

.step-page { padding: 40px 0 84px; }
.step-counter {
  font-family: var(--font-heading);
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
  color: var(--color-accent-dark);
  margin-bottom: 6px;
}
/* Le tutoriel video.
   Chez Mickael (apercu local) c'est une balise <video> ; en ligne c'est le
   lecteur Bunny, glisse dans un <div class="step-video"> par le worker. Les
   deux cas sont couverts ici : meme cadre, meme arrondi, meme ombre.
   Le rapport 16/9 est impose au conteneur pour que la page ne sursaute pas
   pendant le chargement du lecteur. */
.step-video {
  width: 100%;
  border-radius: var(--radius);
  background: #000;
  display: block;
  margin: 24px 0 28px;
  box-shadow: var(--shadow);
  overflow: hidden;
}
div.step-video {
  aspect-ratio: 16 / 9;
}
.step-video iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.step-done {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--color-bg-alt);
  border-radius: var(--radius);
  padding: 14px 18px;
  margin: 28px 0;
  font-weight: 600;
  cursor: pointer;
}
.step-done input { width: 18px; height: 18px; cursor: pointer; }
.step-nav { display: flex; flex-wrap: wrap; gap: 12px; }

/* BLOCS D'UNE ETAPE D'ENTRAINEMENT
   Une classe ecrite a la main peut structurer son etape en blocs typés :
   objectif, dose, exercice, progression, erreurs, chien, critere. Le but est
   qu'on voie d'un coup d'oeil ce qu'il y a A FAIRE, pas seulement a lire. */
.step-objectif,
.step-critere {
  border-left: 4px solid var(--color-accent);
  background: var(--color-bg-alt);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 14px 20px;
  margin: 26px 0;
}
.step-critere { border-left-color: #2f9e5e; }
.step-objectif strong,
.step-critere strong {
  display: block;
  font-family: var(--font-heading);
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 4px;
  color: var(--color-accent-dark);
}
.step-critere strong { color: #23794a; }

.step-dose {
  list-style: none;
  padding: 0;
  margin: 22px 0;
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.step-dose li {
  background: var(--color-bg-alt);
  border-radius: var(--radius);
  padding: 12px 16px;
  font-size: 0.95rem;
}

.step-box {
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: var(--radius);
  padding: 20px 24px;
  margin: 28px 0;
}
.step-box h2 {
  font-size: 1.05rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0 0 14px;
}
.step-box ol,
.step-box ul { padding-left: 22px; margin: 0; }
.step-box li { margin-bottom: 12px; }
.step-box li:last-child { margin-bottom: 0; }

.step-box-exo { border-left: 4px solid var(--color-accent); }
.step-box-exo h2 { color: var(--color-accent-dark); }
.step-box-prog { background: var(--color-bg-alt); border-color: transparent; }
.step-box-err { border-left: 4px solid #d4a017; }
/* Assombri : a #9a7410 le contraste tombait a 4,25, sous le minimum de 4,5. */
.step-box-err h2 { color: #7a5c0a; }
.step-box-dog { border-left: 4px solid #3d7ea6; }
.step-box-dog h2 { color: #2c6485; }
.step-box-dog p { margin: 0; }

/* PAGES LEGALES */
.legal h2 { margin-top: 1.8em; font-size: 1.4rem; }
.legal h3 { margin-top: 1.4em; }
.legal ul { padding-left: 20px; }
.legal li { margin-bottom: 8px; }
/* Surligne les informations qu'il reste a completer avant la mise en ligne. */
.legal mark {
  background: #fff2b8;
  color: #7a5b00;
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: 600;
}
.legal-table-wrap { overflow-x: auto; margin: 20px 0; }
.legal-table { border-collapse: collapse; width: 100%; min-width: 620px; font-size: 0.92rem; }
.legal-table th,
.legal-table td {
  border: 1px solid rgba(2, 63, 112, 0.15);
  padding: 10px 12px;
  text-align: left;
  vertical-align: top;
}
.legal-table th {
  background: var(--color-bg-alt);
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--color-navy);
}

/* LE HERO DE L'ESPACE ELEVE.
   Meme ossature que celui d'une page de formation, mais sur Papier et sans
   photo : ici on ne vend plus, on travaille. L'en-tete du site reste en Nuit
   au-dessus — c'est la seule chose qui ne change jamais. */
.espace-hero { padding: 48px 0 8px; }
.espace-hero h1 { max-width: 20ch; }
.espace-hero .hero-lead { font-size: 1.05rem; max-width: 60ch; }

/* FOOTER LINKS */
.footer-links { display: flex; flex-wrap: wrap; gap: 18px; }

/* RESPONSIVE */
@media (max-width: 900px) {
  .offer-grid { grid-template-columns: 1fr; }
  .audience-grid { grid-template-columns: 1fr; }
  .equip-grid { grid-template-columns: 1fr; }
  .hero-inner { grid-template-columns: 1fr; }
  .hero-media { order: -1; }
  .split { grid-template-columns: 1fr; }
  .split-media { order: -1; max-width: 220px; margin: 0 auto; }
  .feature-grid { grid-template-columns: repeat(2, 1fr); }
  .modules-grid { grid-template-columns: repeat(2, 1fr); }
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
  .gallery-grid { grid-template-columns: repeat(2, 1fr); }
  .bio-stats { grid-template-columns: repeat(2, 1fr); }
  .app-grid { grid-template-columns: repeat(2, 1fr); }
  .avis-grid { grid-template-columns: 1fr; }
}

@media (max-width: 960px) {
  .main-nav {
    position: absolute;
    /* 100% et non 76px : le panneau suit la hauteur de l en-tete, qui se
       tasse a 68 pixels dans l espace eleve. */
    top: 100%;
    left: 0;
    right: 0;
    /* Opaque, et pas translucide : le menu deroule passe par-dessus le contenu
       de la page. Sur un fond clair, un menu Nuit a moitie transparent rendrait
       ses propres liens illisibles. */
    background: var(--nuit);
    flex-direction: column;
    align-items: flex-start;
    padding: 20px 24px 28px;
    gap: 16px;
    border-bottom: 1px solid var(--bord);
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
  }
  .main-nav.open {
    transform: translateY(0);
    opacity: 1;
    pointer-events: auto;
  }
  .nav-toggle { display: flex; }
}

/* Les grilles, elles, ne se replient qu a 720 : sur une tablette de 768 il y a
   largement la place pour deux colonnes de cartes. */
@media (max-width: 720px) {
  .feature-grid { grid-template-columns: 1fr; }
  .modules-grid { grid-template-columns: 1fr; }
  /* La galerie reste sur deux colonnes meme sur telephone : en une seule, les
     quatre photos deviennent un mur de 4 ecrans a faire defiler. */
  .gallery-grid { grid-template-columns: repeat(2, 1fr); }
  .app-grid { grid-template-columns: 1fr; }
  .promo-inner { flex-direction: column; align-items: flex-start; }
  .offer-card.is-step { padding-left: 26px; padding-top: 78px; }
}

/* ============================================================================
   ANIMATIONS  --  reglage "Apple", valide par Mickael le 4 aout 2026.
   ============================================================================
   Le principe, en une phrase : rien ne depasse jamais sa cible. Le mouvement
   ralentit longtemps, puis s'arrete. C'est cette deceleration qui donne
   l'impression de calme ; un rebond, meme leger, fait "site web".

   Huit effets, pas douze. Ont ete ECARTES volontairement : le fil de lecture,
   la ligne de course, les boutons magnetiques et la lueur qui suit la souris.
   Ce sont des effets d'agence : Apple n'en a aucun.

   REGLE DE SECURITE : tout est conditionne a la classe "js-anim", posee par
   une ligne de script dans le <head>. Si le JavaScript ne s'execute pas, rien
   ne se cache et la page reste entierement lisible.
   Pour tout ralentir ou accelerer, il suffit de changer les valeurs ci-dessous.
   ---------------------------------------------------------------------------- */
:root {
  --anim-courbe: cubic-bezier(.16, 1, .3, 1);   /* aucun depassement */
  --anim-duree: 1s;
  --anim-duree-volet: 1.15s;
  --anim-course: 34px;
  --anim-duree-mot: .85s;
  --anim-ecart-mot: 80ms;
  --anim-duree-entree: .9s;
  --anim-parallaxe: 46px;
}

/* --- 1. Apparition au defilement -------------------------------------------
   Deux traitements : une photo et une carte ne bougent pas pareil. */

/* Les photos et les titres : un volet remonte et decouvre. */
.js-anim .anim-volet {
  opacity: 0;
  clip-path: inset(0 0 100% 0);
  transition: opacity calc(var(--anim-duree-volet) * .55) ease,
              clip-path var(--anim-duree-volet) var(--anim-courbe);
}
.js-anim .anim-volet.is-in { opacity: 1; clip-path: inset(0 0 0 0); }

/* Les cartes : elles montent et se posent. */
.js-anim .anim-montee {
  opacity: 0;
  transform: translateY(var(--anim-course));
  transition: opacity calc(var(--anim-duree) * .85) ease,
              transform var(--anim-duree) var(--anim-courbe);
}
.js-anim .anim-montee.is-in { opacity: 1; transform: none; }

/* --- 2. Chiffres qui montent ------------------------------------------------
   Chasse fixe : chaque chiffre occupe la meme largeur, donc le nombre ne
   tremble pas pendant qu'il defile. */
.stat-number, .bio-stat-number, .app-number { font-variant-numeric: tabular-nums; }
@keyframes anim-claque { 0% { transform: scale(1); } 42% { transform: scale(1.07); } 100% { transform: scale(1); } }
.is-claque { display: inline-block; animation: anim-claque .42s var(--anim-courbe); }

/* --- 3. Reaction au survol --------------------------------------------------
   .module-card a deja le sien plus haut dans ce fichier : on ne le touche pas. */
/* Sur la Nuit, une ombre ne se voit pas : c'est la BORDURE qui s'eclaircit, et
   la carte qui glisse vers la droite. Meme geste que les cartes de classe —
   tout le site reagit de la meme facon au survol. */
.feature-card, .avis-card {
  transition: transform .28s var(--anim-courbe), border-color .28s ease;
}
.feature-card:hover, .avis-card:hover {
  transform: translateX(4px);
  border-color: var(--acier);
}
/* L'enveloppe decoupe le zoom de la photo : sans elle, l'agrandissement
   deborderait sur les photos voisines de la galerie. Ni ombre ni arrondi : la
   galerie est bord a bord. */
.zoom-wrap {
  display: block;
  overflow: hidden;
  line-height: 0;
}
.zoom-wrap img { box-shadow: none; transition: transform .7s var(--anim-courbe); }
.zoom-wrap:hover img { transform: scale(1.05); }

/* --- 4. Entree de la page ---------------------------------------------------
   Volontairement sobre : c'est la seconde ou le visiteur decide de rester. */
@keyframes anim-entree { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
/* "both" et non "forwards", et AUCUNE opacite de base : l'element est visible
   par defaut, et c'est l'animation qui le cache le temps de son entree. Ecrit
   dans l'autre sens (opacite 0 en base), une animation qui ne demarre pas
   laisserait le contenu invisible pour toujours. */
.js-anim .anim-entree { animation: anim-entree var(--anim-duree-entree) var(--anim-courbe) both; }

/* Le mot rouge du titre se souligne, une fois le titre pose. */
.mot-cle { position: relative; display: inline-block; }
.js-anim .mot-cle::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: .02em;
  height: .09em; border-radius: 2px;
  background: var(--color-signal); opacity: .55;
  transform-origin: left;
  animation: anim-trait .6s var(--anim-courbe) var(--anim-trait-delai, .9s) both;
}
@keyframes anim-trait { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* --- 5. En-tete qui se compacte ---------------------------------------------
   Le bandeau du haut se resserre des qu'on descend. C'est ce qui fait qu'un
   site a l'air fini. */
.site-header { transition: box-shadow .3s ease, background .3s ease; }
.site-header .logo-mark { transition: transform .3s var(--anim-courbe); transform-origin: left center; }
.site-header.is-compact { background: rgba(1, 25, 43, 0.98); box-shadow: 0 10px 28px -18px rgba(0, 0, 0, 0.8); }
.site-header.is-compact .logo-mark { transform: scale(0.84); }

/* --- 8. Titre mot par mot ---------------------------------------------------
   Chaque mot est enferme dans une fenetre qui deborde en "hidden". Le mot part
   sous cette fenetre et remonte : on ne voit jamais son point de depart, donc
   il semble surgir du papier au lieu d'apparaitre en fondu. */
.mot { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: .1em; margin-bottom: -.1em; }
.mot-in { display: inline-block; }
/* Meme regle que pour l'entree : pas de transform de base, et "both". Sinon un
   mot qui n'anime pas resterait pousse sous sa fenetre, donc illisible. */
@keyframes anim-mot { from { transform: translateY(115%); } to { transform: none; } }
.js-anim .mot-in { animation: anim-mot var(--anim-duree-mot) var(--anim-courbe) var(--d, 0ms) both; }
/* Le titre est cache tant que le decoupage en mots n'a pas eu lieu : sinon on
   verrait le titre entier une fraction de seconde, puis ses mots retomber. */
.js-anim .hero-copy h1 { visibility: hidden; }
.js-anim .hero-copy h1.est-decoupe { visibility: visible; }
/* Les mots s'animent : le titre entier n'a plus besoin de bouger en plus. */
.js-anim .hero-copy h1.anim-entree { opacity: 1; animation: none; }

/* --- 9. La photo du hero se pose -------------------------------------------- */
@keyframes anim-pose { from { transform: scale(1.06); } to { transform: scale(1); } }
.js-anim .hero-media img { animation: anim-pose 1.7s var(--anim-courbe) forwards; }

/* --- 10. Parallaxe douce ----------------------------------------------------
   Le decalage est calcule par le JavaScript et depose dans --py. */
.para-fenetre { display: block; overflow: hidden; border-radius: var(--radius); }
.para { display: block; }
.js-anim .para { transform: translate3d(0, var(--py, 0px), 0); }

/* --- Le reglage systeme "reduire les animations" ----------------------------
   Windows, macOS et l'iPhone proposent ce reglage. Il est souvent active par
   des personnes sujettes aux vertiges ou aux migraines. On lui obeit, toujours :
   sans ca, le site devient inconfortable pour une partie des visiteurs. */
@media (prefers-reduced-motion: reduce) {
  .js-anim .anim-volet, .js-anim .anim-montee {
    opacity: 1 !important; transform: none !important; clip-path: none !important; transition: none !important;
  }
  .js-anim .anim-entree { opacity: 1 !important; animation: none !important; }
  .js-anim .mot-in { transform: none !important; animation: none !important; }
  .js-anim .mot-cle::after { animation: none !important; transform: scaleX(1) !important; }
  .js-anim .hero-media img { animation: none !important; transform: none !important; }
  .js-anim .para { transform: none !important; }
  .is-claque { animation: none !important; }
  .zoom-wrap img, .feature-card, .avis-card, .site-header, .site-header .logo-mark { transition: none !important; }
}

/* ==========================================================================
   LES FORMATIONS REPLIEES SUR TELEPHONE
   ==========================================================================

   Le probleme, mesure le 6 aout 2026 sur speedlinkdog.com a 375 px de large :
   les 11 cartes de formation occupaient 4917 px, soit 6,1 ecrans de telephone
   a faire defiler - un tiers de toute la page d'accueil. Beaucoup de visiteurs
   abandonnaient avant d'avoir atteint "Qui suis-je", les avis et le formulaire
   de contact.

   La solution retenue par Mickael (option C, choisie sur maquette) : on montre
   les 4 premieres cartes, et un bouton deplie les 7 autres. On passe a 2290 px,
   soit 2,8 ecrans.

   REGLE DE SECURITE, la meme que pour les animations :
   par defaut les 11 cartes sont VISIBLES. C'est le javascript qui ajoute la
   classe "est-repliee" et qui pose le bouton, et il ne l'ajoute qu'apres avoir
   reussi a poser le bouton. S'il ne s'execute pas, le visiteur voit simplement
   les 11 formations, comme avant. Ecrite dans l'autre sens - cartes cachees par
   defaut, revelees par le javascript - une panne cacherait 7 formations, donc
   7 produits, sans que personne s'en apercoive.

   Sur ordinateur, les cartes se rangent sur trois colonnes : la longueur n'est
   pas un probleme, on n'y touche pas. Tout ce bloc est donc sous media query.
   ========================================================================== */

.modules-deplier { display: none; }

@media (max-width: 700px) {
  .modules-grid.est-repliee .module-card:nth-child(n + 5) { display: none; }

  .modules-deplier {
    display: block;
    width: 100%;
    margin-top: 24px;
    padding: 14px 22px;
    /* Un bouton de contour, comme partout ailleurs : le trait et le mot
       prennent la couleur de la surface, jamais un bleu marine fixe qui
       disparaitrait sur le fond de nuit. */
    border: 1px solid var(--trait-bouton);
    border-radius: var(--radius-bouton);
    background: transparent;
    color: var(--titre);
    font: inherit;
    font-family: var(--font-heading);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: border-color 0.15s ease;
  }
  .modules-deplier:hover,
  .modules-deplier:focus-visible { border-color: #fff; }
}

/* --- La page de commande -----------------------------------------------------

   Dernier ecran avant le paiement. Deux principes de fabrication :

   1. Les deux cases a cocher sont des cases HTML natives, marquees "required".
      Le navigateur bloque l'envoi tout seul, sans une ligne de JavaScript. On ne
      grise donc PAS le bouton par script : un bouton grise par du code qui n'a
      pas tourne, c'est une vente perdue sans que personne ne comprenne pourquoi.

   2. La case de retractation ne doit pas ressembler a une formalite : c'est elle
      qui fait perdre a l'acheteur un droit de quatorze jours. Elle est ecrite en
      pleine taille, jamais en petits caracteres.
   -------------------------------------------------------------------------- */

/* La carte de commande : le nom a gauche, le prix en gros a droite, puis ce que
   contient la formation. Choix de Mickael sur maquette, le 11 aout 2026.
   Blanche et detachee du fond, pour qu'elle se lise avant tout le reste. */
.commande-carte {
  margin: 28px 0;
  padding: 22px 24px;
  background: #fff;
  border: 1px solid rgba(2, 63, 112, 0.14);
  border-radius: 14px;
  box-shadow: 0 4px 14px rgba(2, 63, 112, 0.06);
}

.commande-tete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px solid rgba(2, 63, 112, 0.12);
}

.commande-nom {
  margin: 0;
  font-family: 'Urbanist', system-ui, sans-serif;
  font-weight: 800;
  font-size: 1.15rem;
  line-height: 1.25;
  color: var(--color-navy);
}

.commande-sous { margin: 3px 0 0; font-size: 0.87rem; opacity: 0.8; }

/* "white-space: nowrap" : le prix ne doit jamais se couper en deux lignes.
   "tabular-nums" : les chiffres gardent tous la meme largeur. */
.commande-prix {
  margin: 0;
  font-family: 'Urbanist', system-ui, sans-serif;
  font-weight: 900;
  font-size: 2.1rem;
  line-height: 1;
  color: var(--color-navy);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Encadre beige, garde pour la page "merci" qui s'en sert encore. */
.commande-recap {
  margin: 28px 0;
  padding: 24px 26px;
  background: var(--color-bg-alt);
  border-radius: 14px;
}

.commande-inclus { list-style: none; padding: 0; margin: 0 0 20px; }
.commande-inclus li {
  position: relative;
  padding-left: 26px;
  margin-bottom: 9px;
  line-height: 1.5;
}
.commande-inclus li::before {
  content: "\2713";
  position: absolute;
  left: 0;
  color: var(--color-navy);
  font-weight: 700;
}

.commande-tva { margin: 14px 0 0; font-size: 0.85rem; opacity: 0.8; }

.consent-list { list-style: none; padding: 0; margin: 0 0 26px; }

.consent-item {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  margin-bottom: 18px;
  line-height: 1.5;
}
/* 3px de decalage : aligne le carre de la case sur la premiere ligne de texte. */
.consent-item input[type="checkbox"] {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin: 3px 0 0;
  accent-color: var(--color-navy);
  cursor: pointer;
}
.consent-item label { cursor: pointer; }

.commande-payer { width: 100%; font-size: 1.05rem; }

.commande-retour { margin-top: 26px; font-size: 0.92rem; }

@media (max-width: 700px) {
  .commande-recap { padding: 20px 18px; }
  .commande-total > strong { font-size: 1.7rem; }
}

/* « Comment avez-vous connu Speed Link Dog ? »
   Elle est posee AVANT les deux cases obligatoires, et volontairement discrete :
   c'est la derniere page avant le paiement, rien ici ne doit ressembler a un
   obstacle de plus. Le mot "facultatif" est visible sans etre lu en premier. */
.commande-provenance { margin: 0 0 26px; }
.commande-provenance label {
  display: block;
  margin-bottom: 8px;
  font-weight: 600;
  color: var(--color-navy);
}
.commande-facultatif {
  margin-left: 6px;
  padding: 2px 8px;
  border-radius: 99px;
  background: var(--color-bg-alt);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--color-teal);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.commande-provenance select {
  width: 100%;
  padding: 12px 13px;
  border: 1px solid rgba(2, 63, 112, 0.25);
  border-radius: 8px;
  font: inherit;
  background: var(--color-white);
}

.commande-intro { margin: 0 0 18px; font-weight: 600; }

/* L'explication vit JUSTE SOUS la case, pas en bas de page : c'est la ou se pose
   la question. Plus petite que la case elle-meme, mais pas au point de devenir
   des petits caracteres — c'est elle qui rend la renonciation comprehensible,
   donc valable. */
.consent-explication {
  margin: -8px 0 24px;
  padding-left: 35px;
  font-size: 0.88rem;
  line-height: 1.55;
  opacity: 0.85;
}
.consent-explication a { color: var(--color-accent-dark); }

@media (max-width: 700px) {
  .consent-explication { padding-left: 0; }
}

/* --- LA PAGE DE CONNEXION -------------------------------------------------
   Une seule chose a faire sur cette page : taper son adresse. Tout le reste
   est ecarte. Le champ est volontairement grand : c'est souvent la premiere
   page qu'un eleve ouvre sur son telephone, au terrain, en plein soleil. */

.connexion { padding: 60px 0 80px; }

.connexion-intro { margin: 0 0 26px; max-width: 46ch; }

.connexion-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 420px;
  margin: 0 0 22px;
}

.connexion-form label {
  font-size: 0.9rem;
  font-weight: 600;
  opacity: 0.85;
}

.connexion-form input[type="email"] {
  padding: 14px 16px;
  font-size: 1.05rem;
  font-family: inherit;
  color: inherit;
  background: #fff;
  border: 1px solid rgba(2, 63, 112, 0.28);
  border-radius: 10px;
}

.connexion-form input[type="email"]:focus-visible {
  outline: 2px solid var(--color-accent-dark);
  outline-offset: 1px;
  border-color: transparent;
}

.connexion-form button { margin-top: 4px; }

/* Les messages d'etat. Ils sont TOUS presents dans la page et TOUS caches ;
   c'est le serveur qui ajoute "is-visible" a celui qui convient. Ainsi la page
   de connexion ne contient pas une ligne de JavaScript : elle s'ouvre meme
   quand les scripts sont bloques, ce qui est la moindre des choses pour une
   porte d'entree. */
.connexion-etat {
  display: none;
  max-width: 420px;
  margin: 0 0 22px;
  padding: 14px 16px;
  border-radius: 10px;
  border-left: 4px solid var(--color-accent-dark);
  background: rgba(2, 63, 112, 0.06);
  font-size: 0.95rem;
  line-height: 1.55;
}

.connexion-etat.is-visible { display: block; }

/* Les trois cas d'echec passent en rouge : l'eleve doit voir tout de suite
   qu'il a quelque chose a refaire, sans lire. */
.connexion-etat--adresse,
.connexion-etat--jeton,
.connexion-etat--consentement,
.connexion-etat--technique {
  background: #fff4f4;
  border-left-color: #d4000d;
}

.connexion-etat a { color: var(--color-accent-dark); }

/* --- LE TABLEAU DE BORD DE L'ELEVE ---------------------------------------
   Les cartes portent une pastille qui dit, sans lire, ce qui est a soi et ce
   qui ne l'est pas. Les classes verrouillees ne sont pas cachees : elles sont
   la, en retrait, et un clic mene a leur page de vente. C'est la vitrine la
   plus efficace du site, parce qu'elle s'adresse a quelqu'un qui a deja
   achete une fois. */

.module-etat {
  align-self: flex-start;
  margin-bottom: 10px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  line-height: 1.4;
}

.module-card--ouvert .module-etat,
.module-card--partiel .module-etat {
  background: rgba(2, 63, 112, 0.1);
  color: var(--color-accent-dark);
}

.module-card--gratuit .module-etat {
  background: rgba(2, 63, 112, 0.9);
  color: #fff;
}

.module-card--verrouille .module-etat {
  background: rgba(2, 63, 112, 0.07);
  color: var(--color-teal);
}

/* Le grise. Assez marque pour se distinguer d'un coup d'oeil, assez lisible
   pour donner envie : une carte qu'on ne peut pas lire ne vend rien. */
.module-card--verrouille {
  background: transparent;
  border-style: dashed;
}
.module-card--verrouille h3,
.module-card--verrouille p { opacity: 0.6; }
.module-card--verrouille:hover { transform: none; box-shadow: none; }
.module-card--verrouille:hover h3,
.module-card--verrouille:hover p { opacity: 0.95; }
.module-card--verrouille:hover .module-etat {
  background: var(--color-accent-dark);
  color: #fff;
}

.espace-compte {
  margin: 18px 0 0;
  font-size: 0.85rem;
  opacity: 0.75;
}
.espace-compte a { color: var(--color-accent-dark); }
.espace-compte:empty { display: none; }

/* Les deux rayons du tableau de bord. « Mes classes » d'abord, toujours :
   ce qu'on a paye ne doit pas se chercher. */
.espace-titre {
  margin: 0 0 4px;
  font-size: 1.55rem;
}
.espace-titre + .espace-sous {
  margin: 0 0 22px;
  opacity: 0.75;
}
.modules-grid + .espace-titre { margin-top: 56px; }

/* Le lien d'action, en bas de carte. Il dit ce qui va se passer au clic —
   entrer chez soi, ou aller voir une classe qu'on n'a pas. */
.module-aller {
  margin-top: 16px;
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--color-accent-dark);
}
.module-card--verrouille .module-aller { opacity: 0.75; }

/* --- LE BOUTON « MON ESPACE » DU MENU ------------------------------------- */
.main-nav a.nav-espace {
  padding: 7px 15px;
  border-radius: 999px;
  background: var(--color-accent-dark);
  color: #fff;
  font-weight: 700;
}
.main-nav a.nav-espace:hover { color: #fff; opacity: 0.88; }

.connexion-note {
  max-width: 46ch;
  margin: 0 0 12px;
  font-size: 0.9rem;
  line-height: 1.6;
  opacity: 0.82;
}

/* Sur telephone, le prix passe sous le nom : cote a cote, un titre long comme
   "Le parcours complet — Niveau 1 + Niveau 2" ecraserait le montant. */
@media (max-width: 560px) {
  .commande-tete { flex-direction: column; gap: 12px; }
  .commande-prix { font-size: 1.9rem; }
}

/* CONSEILS — les articles qui font venir les gens depuis Google.

   Le sommaire a d'abord ete fait de dix cartes identiques. Le defaut n'etait
   pas le dessin, c'etait le message : dix boites qui se ressemblent ne disent
   pas par ou commencer, et laissent au lecteur un travail de tri qui est
   justement celui qu'il vient nous demander de faire.
   On range donc par question posee, et on met un article en avant. */

/* Le grand bloc du haut. C'est le seul aplat de bleu plein de la rubrique :
   il n'y en a qu'un pour que ce soit lui qu'on voie en arrivant. */
.conseil-vedette {
  display: block;
  margin: 40px 0 56px;
  padding: 32px 36px;
  background: var(--color-navy);
  border-radius: var(--radius);
  color: var(--color-white);
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.conseil-vedette:hover { transform: translateX(4px); box-shadow: var(--shadow); }
.conseil-vedette-label {
  display: block;
  margin-bottom: 10px;
  font-family: var(--font-heading);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.75;
}
.conseil-vedette-titre {
  display: block;
  font-family: var(--font-heading);
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 800;
  line-height: 1.2;
  text-wrap: balance;
}
.conseil-vedette-desc {
  display: block;
  margin-top: 12px;
  font-size: 1rem;
  line-height: 1.6;
  opacity: 0.88;
}
.conseil-vedette-lire {
  display: block;
  margin-top: 18px;
  font-weight: 700;
}

/* Les groupes. Un titre = une question que se pose le lecteur. */
.conseil-groupe { margin-bottom: 48px; }
.conseil-groupe h2 { font-size: clamp(1.3rem, 2.4vw, 1.7rem); margin-bottom: 6px; }
.conseil-groupe-intro {
  margin: 0 0 18px;
  color: var(--color-teal);
  opacity: 0.75;
  font-size: 0.98rem;
}

/* La liste. Des filets, pas des boites : dix articles alignes se comparent d'un
   coup d'oeil, la ou dix cadres se comptent un par un. */
.conseil-liste { list-style: none; margin: 0; padding: 0; }
.conseil-liste li { border-top: 1px solid rgba(2, 63, 112, 0.14); }
.conseil-liste li:last-child { border-bottom: 1px solid rgba(2, 63, 112, 0.14); }
.conseil-liste a {
  display: block;
  padding: 18px 16px;
  /* La bordure est deja la, transparente : au survol elle ne fait que changer
     de couleur. Rien ne bouge, le texte ne se recompose pas. */
  border-left: 3px solid transparent;
  text-decoration: none;
  color: inherit;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.conseil-liste a:hover,
.conseil-liste a:focus-visible {
  background: var(--color-bg-alt);
  border-left-color: var(--color-navy);
}
.conseil-item-titre {
  display: block;
  font-family: var(--font-heading);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--color-navy);
  line-height: 1.3;
}
.conseil-item-desc {
  display: block;
  margin-top: 5px;
  color: var(--color-teal);
  opacity: 0.85;
  font-size: 0.94rem;
  line-height: 1.5;
}

/* Les numeros n'apparaissent que sur le groupe des exercices, parce que la
   seulement l'ordre veut dire quelque chose. */
.conseil-liste-num { counter-reset: conseil; }
.conseil-liste-num li { counter-increment: conseil; }
.conseil-liste-num a {
  display: grid;
  /* Largeur FIXE, pas "auto" : avec auto, la colonne se reglerait sur la
     largeur du chiffre, et comme un "1" est plus etroit qu'un "3", les trois
     titres ne commenceraient pas au meme endroit. */
  grid-template-columns: 1.75rem 1fr;
  column-gap: 18px;
}
.conseil-liste-num a::before {
  content: counter(conseil);
  grid-row: 1 / span 2;
  align-self: start;
  text-align: right;
  font-family: var(--font-heading);
  font-size: 1.6rem;
  font-weight: 800;
  line-height: 1.1;
  color: var(--color-navy);
  opacity: 0.3;
  font-variant-numeric: tabular-nums;
}

/* Le renvoi vers la classe gratuite, en bas du sommaire. */
.conseil-final {
  margin-top: 8px;
  padding-top: 32px;
  border-top: 2px solid rgba(2, 63, 112, 0.12);
  text-align: center;
}

@media (max-width: 600px) {
  .conseil-vedette { padding: 26px 22px; }
  .conseil-liste a { padding: 16px 12px; }
}

/* Le fil d'Ariane en haut d'un article. */
.conseil-retour { margin-bottom: 20px; }
.conseil-retour a { font-weight: 600; text-decoration: none; color: var(--color-accent-dark); }
.conseil-retour a:hover { color: var(--color-accent); }

/* Le renvoi vers la classe gratuite, en fin d'article. C'est le seul endroit
   de l'article ou l'on propose quelque chose : il doit se detacher du texte
   sans crier. */
.conseil-suite {
  margin-top: 48px;
  padding-top: 28px;
  border-top: 2px solid rgba(2, 63, 112, 0.12);
}
.conseil-suite h2 { margin-top: 0; }

/* ---- LA PAGE D'ARTICLE ----------------------------------------------------
   Elle empruntait l'habillage des pages legales. Ca se voyait : des CGV se
   consultent en diagonale, un conseil se lit d'un bout a l'autre. Il lui faut
   des lignes plus aerees et des respirations entre les parties. */
/* Les lignes faisaient 96 caracteres. Au-dela de 80, l'oeil retombe une ligne
   trop bas en revenant a la marge : on relit deux fois la meme phrase sans
   comprendre pourquoi. On resserre la colonne (le sommaire, lui, reste large :
   on le parcourt, on ne le lit pas). */
.conseil.narrow { max-width: 640px; }
.conseil p { line-height: 1.75; }
.conseil h2 { margin-top: 2em; font-size: clamp(1.3rem, 2.4vw, 1.6rem); }
.conseil h3 { margin-top: 1.5em; }
.conseil ul,
.conseil ol { padding-left: 22px; }
.conseil li { margin-bottom: 10px; line-height: 1.7; }

/* Le chapeau : la reponse courte, avant tout le reste. Beaucoup de lecteurs
   n'ont besoin que de ces trois lignes — autant qu'elles se voient. */
.conseil > .section-lead {
  margin: 0 0 44px;
  padding: 22px 26px;
  background: var(--color-bg-alt);
  border-left: 4px solid var(--color-navy);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 1.1rem;
  line-height: 1.65;
}

/* Le critere de reussite. C'est l'information la plus utile de la page : celle
   qui dit "c'est acquis" ou "il reste du travail", sans interpretation.
   Elle etait noyee dans le texte ; elle a maintenant son cadre. */
/* EXACTEMENT le meme objet que le critere d'une etape de classe (.step-critere) :
   meme filet vert a gauche, meme fond sable, meme coin carre du cote du filet.
   Un critere doit se reconnaitre au premier coup d'oeil, qu'on le rencontre
   dans un article gratuit ou au milieu d'une classe payante. */
.conseil-critere {
  margin: 44px 0;
  padding: 24px 28px;
  background: var(--color-bg-alt);
  border-left: 4px solid #2f9e5e;
  border-radius: 0 var(--radius) var(--radius) 0;
}
.conseil .conseil-critere h2 {
  margin-top: 0;
  margin-bottom: 0.4em;
  font-size: 1.15rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  /* Vert, comme le titre du critere d'une etape de classe. */
  color: #23794a;
}
.conseil-critere p:last-child { margin-bottom: 0; }

/* Les tableaux des articles reutilisent .legal-table. Une seule retouche : la
   largeur minimale de 620px est calibree pour les tableaux des CGV, a trois ou
   quatre colonnes. Ceux des articles en ont deux, et dans une colonne plus
   etroite ils se mettaient a defiler sur ordinateur pour rien. */
.conseil .legal-table { min-width: 420px; }

/* TRIBUNE INVITEE — un texte signe par quelqu'un d'autre que Mickael.
   Le nom de l'auteur doit se voir tout de suite : c'est ce qui rend le texte
   credible, et c'est ce qu'on doit a la personne qui l'a ecrit. */
.conseil-auteur {
  margin: -8px 0 28px;
  padding-bottom: 18px;
  border-bottom: 1px solid rgba(2, 63, 112, 0.12);
  color: var(--color-teal);
}
.conseil-signature {
  margin-top: 36px;
  padding-top: 18px;
  border-top: 1px solid rgba(2, 63, 112, 0.12);
  line-height: 1.5;
}

/* L'ENCADRE D'URGENCE.
   Il utilise --color-signal, le rouge tenu en reserve. C'est exactement l'usage
   pour lequel une couleur de signal existe : quelqu'un qui arrive ici en
   panique, le chien haletant a cote de lui, doit voir ce bloc AVANT le reste.
   Il est place tout en haut de la page pour la meme raison. */
.encadre-urgence {
  background: var(--color-white);
  border: 2px solid var(--color-signal);
  border-radius: var(--radius);
  padding: 24px 28px;
  margin: 0 0 40px;
}
.encadre-urgence h2 {
  margin-top: 0;
  color: var(--color-signal);
  font-size: 1.15rem;
}
.encadre-urgence p:last-child { margin-bottom: 0; }

@media (max-width: 560px) {
  .encadre-urgence { padding: 20px; }
}

/* --- LA PAGE "QU'EST-CE QUI VOUS BLOQUE ?" --------------------------------
   Une carte par probleme, en une seule colonne : on lit du haut vers le bas
   jusqu'a se reconnaitre dans une ligne, puis on clique. Une grille a
   plusieurs colonnes obligerait a balayer en zigzag, ce qui est exactement
   l'inverse de ce qu'on demande ici.

   Aucun style nouveau n'est invente : c'est la carte blanche du site
   (.module-card), avec le meme cadre, le meme rayon et la meme animation. */
.probleme-liste {
  margin-top: 36px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.probleme-carte {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--radius);
  padding: 28px;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.probleme-carte:hover { transform: translateX(4px); border-color: var(--acier); }

/* La promesse en francais clair. C'est le titre que le visiteur lit en
   premier — le nom de metier de la classe, lui, est en bas. */
.probleme-titre {
  margin: 0 0 14px;
  font-size: 1.18rem;
  line-height: 1.35;
  color: var(--titre);
}

.probleme-symptomes { list-style: none; padding: 0; margin: 0 0 18px; }
.probleme-symptomes li {
  position: relative;
  padding-left: 16px;
  margin-bottom: 9px;
  line-height: 1.55;
  color: var(--texte);
}
.probleme-symptomes li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--color-signal);
}

.probleme-pied {
  margin: 0;
  padding-top: 16px;
  border-top: 1px solid var(--bord);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}
.probleme-lien { font-weight: 700; color: var(--titre); }
.probleme-prix {
  flex: 0 0 auto;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--secondaire);
}

@media (max-width: 560px) {
  .probleme-carte { padding: 22px; }
  .probleme-pied { flex-direction: column; align-items: flex-start; gap: 6px; }
}

/* La ligne « vous voulez traiter ce point a fond ? » en bas d'un article.
   Discrete par choix : elle ne doit pas concurrencer la classe gratuite, qui
   reste l'appel principal. Un encadre leger, pas un bouton. */
.conseil-classe {
  margin: 26px 0 0;
  padding: 14px 18px;
  background: var(--color-bg-alt);
  border-radius: 10px;
  font-size: 0.95rem;
  line-height: 1.55;
}
.conseil-classe a { font-weight: 700; color: var(--color-accent-dark); }

/* --- Le selecteur de langue -------------------------------------------------
   Discret par construction : c'est un service, pas une rubrique. Il ne doit
   pas attirer l'oeil autant que "Modules" ou "Mon espace". */
.main-nav .nav-langue {
  font-size: .82rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  /* Une couleur pleine plutot qu'une opacite : sur le fond de nuit, un blanc
     transparent donne un gris dont on ne peut plus verifier le contraste. */
  color: var(--acier);
}
.main-nav .nav-langue:hover,
.main-nav .nav-langue:focus-visible { opacity: 1; }
