/* ============================================================================
   tarifs.css — la page /tarifs.html (2026-09-08).

   La page HTML est GENEREE (`scripts/generer_tarifs.js`) : ses montants
   viennent du catalogue, ses formulations de la plaquette V2. Cette feuille,
   elle, s'ecrit a la main -- elle ne porte aucun chiffre metier.

   LES MEMES TROIS REGLES QUE `rendez-vous.css`, POUR LES MEMES RAISONS :

   1. Aucun `:hover` hors `@media (hover:hover) and (pointer:fine)` : sur
      tactile, le doigt qui defile declenche :hover et les elements clignotent.
   2. Rien ne boucle en animant autre chose que `transform` et `opacity`. Ce
      qui coute sur un telephone n'est pas l'animation, c'est le REPEINT
      (mesure du 27/08 : 696 Paint contre 0 pour le meme effet recompose).
   3. Le halo ne DERIVE que sur un ecran a souris : l'en-tete du site porte
      `backdrop-filter`, et un fond mobile l'oblige a se re-filtrer a chaque
      image.

   ET LA REGLE DE SURETE : rien n'est visible uniquement grace a une animation.
   Les entrees partent d'`opacity: 0` en `animation-fill-mode: backwards` --
   l'etat ECRIT dans la regle est « visible ». Sur une page de TARIFS, ca n'est
   pas un detail de confort : un bloc de prix reste invisible, et le visiteur
   croit que le prix est cache.
   ========================================================================== */

:root {
  --tf-on-accent: #0a0a14;
  --tf-ombre: 0 18px 50px rgba(10, 14, 40, .10);
  --tf-voile: rgba(255, 255, 255, .55);
}
:root[data-theme="clair"] { --tf-on-accent: #ffffff; }
:root[data-theme="cyan"],
:root[data-theme="violet"],
:root[data-theme="emeraude"],
:root[data-theme="ambre"],
:root[data-theme="rose"] {
  --tf-ombre: 0 18px 50px rgba(0, 0, 0, .45);
  --tf-voile: rgba(255, 255, 255, .05);
}

/* `[hidden] { display: none }` vient de la feuille du NAVIGATEUR et pese
   (0,1,0) : n'importe quelle classe posant un `display` la bat. Vecu EN
   PRODUCTION le 2026-08-24. On la pose UNE fois, en tete. */
[hidden] { display: none !important; }

* { box-sizing: border-box; }

body {
  margin: 0;
  padding-top: 62px;
  font-family: 'Poppins', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
  background: var(--bg, #f4f5fa);
  color: var(--text, #191b2e);
  line-height: 1.65;
  overflow-x: hidden;
}

/* Le texte reserve aux lecteurs d'ecran : une coche dessinee ne se lit pas a
   voix haute, et « — » non plus. */
.tf-lu {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Halo de fond ────────────────────────────────────────────────────── */
.tf-aura { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.tf-orb { position: absolute; display: block; border-radius: 50%; }
.tf-orb-1 {
  top: -24vh; left: -20vw; width: 78vw; height: 78vw; max-width: 940px; max-height: 940px;
  background: radial-gradient(circle closest-side, var(--accent, #0061cc) 0%, transparent 72%);
  opacity: .16;
}
.tf-orb-2 {
  bottom: -30vh; right: -22vw; width: 72vw; height: 72vw; max-width: 880px; max-height: 880px;
  background: radial-gradient(circle closest-side, var(--light-blue, #00d4ff) 0%, transparent 72%);
  opacity: .13;
}
:root[data-theme="cyan"] .tf-orb-1,
:root[data-theme="violet"] .tf-orb-1,
:root[data-theme="emeraude"] .tf-orb-1,
:root[data-theme="ambre"] .tf-orb-1,
:root[data-theme="rose"] .tf-orb-1 { opacity: .12; }
:root[data-theme="cyan"] .tf-orb-2,
:root[data-theme="violet"] .tf-orb-2,
:root[data-theme="emeraude"] .tf-orb-2,
:root[data-theme="ambre"] .tf-orb-2,
:root[data-theme="rose"] .tf-orb-2 { opacity: .10; }

/* LA LARGEUR DE LA PAGE, ET POURQUOI ELLE N'EST PLUS UN NOMBRE FIXE.
   ------------------------------------------------------------------------
   Koray, 09/09/2026 : « on n'utilise pas toute la largeur de l'ecran quand
   elle est disponible ». MESURE sur son ecran principal (2752 px) : le
   contenu tenait dans 1120 px, soit **41 % de la largeur, et 1632 px de
   vide**. Les cinq cartes de formules tombaient a 207 px chacune -- « 3
   modifications par mois » passait sur deux lignes -- pendant qu'un tiers de
   l'ecran ne servait a rien.

   La cause n'est pas une erreur : un `max-width` de ~1100 px est la valeur
   de LISIBILITE d'un paragraphe (au-dela, l'oeil perd la ligne suivante).
   Le defaut est de l'avoir applique a TOUTE la page. Une grille de cinq
   cartes et un tableau de six colonnes n'ont pas de largeur de lecture : ils
   ont besoin de place, et ils en manquaient.

   D'ou deux largeurs au lieu d'une :
     --tf-large    la page (grilles, tableaux, cartes) ;
     --tf-lecture  ce qui se LIT en lignes, borne separement.

   `min()` et non un nombre : a 1440 px la page prend 94 % de la fenetre,
   a 2752 px elle plafonne a 1680 -- une page de tarifs etalee sur 2,7 m
   d'ecran obligerait a balayer la tete de gauche a droite pour lire une
   ligne de tableau. */
.tf-wrap {
  position: relative;
  max-width: 1680px;
  margin: 0 auto;
  padding: clamp(2rem, 5vw, 3.6rem) 20px 4rem;
}

/* ── Entrees ─────────────────────────────────────────────────────────── */
@keyframes tf-monte {
  from { opacity: 0; transform: translate3d(0, 22px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
.tf-up { animation: tf-monte .74s cubic-bezier(.2, .75, .25, 1) backwards; }
.tf-d1 { animation-delay: .04s; }
.tf-d2 { animation-delay: .10s; }
.tf-d3 { animation-delay: .17s; }
.tf-d4 { animation-delay: .24s; }
.tf-d5 { animation-delay: .31s; }
.tf-d6 { animation-delay: .38s; }

/* ── En-tete ─────────────────────────────────────────────────────────── */
.tf-hero { text-align: center; max-width: 760px; margin: 0 auto clamp(2rem, 4vw, 2.6rem); }
.tf-eyebrow {
  display: inline-flex; align-items: center; gap: .55rem;
  margin: 0 0 1.1rem; padding: .4rem 1rem .4rem .75rem;
  border: 1px solid var(--accent-soft, rgba(0, 97, 204, .28));
  border-radius: 999px;
  background: var(--accent-soft, rgba(0, 97, 204, .10));
  color: var(--accent, #0061cc);
  font-size: .78rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
}
.tf-pastille {
  width: 8px; height: 8px; flex: none; border-radius: 50%;
  background: var(--accent, #0061cc);
  animation: tf-respire 2.4s ease-in-out infinite;
}
@keyframes tf-respire {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .45; transform: scale(.62); }
}
.tf-hero h1 {
  font-size: clamp(2.1rem, 6vw, 3.4rem); line-height: 1.08; margin: 0 0 1rem;
  font-weight: 700; letter-spacing: -.02em;
}
.tf-mot {
  background: linear-gradient(100deg, var(--accent, #0061cc), var(--light-blue, #00b4e6) 70%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.tf-lead { color: var(--text-muted, #5b5e77); font-size: clamp(1.02rem, 2vw, 1.16rem); margin: 0; }

.tf-gages {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem .6rem;
  list-style: none; margin: 1.6rem 0 0; padding: 0;
}
.tf-gages li {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .38rem .85rem;
  border: 1px solid var(--border, #dde0ec); border-radius: 999px;
  background: var(--tf-voile);
  color: var(--text-muted, #5b5e77); font-size: .84rem; font-weight: 600;
}
.tf-gages svg { width: 15px; height: 15px; flex: none; color: var(--accent, #0061cc); }

/* ── LE SOCLE : ce qu'on achete, avant ce que ca coute ────────────────── */
/* Koray, 09/09/2026 : « on voit combien ca coute, mais pas de precision de ce
   que c'est ». Les deux lignes de la facture sont donc posees en tete, avec
   leur rythme et leur fourchette -- et chacune est un LIEN vers sa section :
   le socle sert de sommaire, il ne se contente pas d'annoncer. */
.tf-deux {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: stretch;
  gap: .9rem;
  margin: 0 0 clamp(2.4rem, 5vw, 3.4rem);
}
@media (max-width: 860px) { .tf-deux { grid-template-columns: 1fr; } }
.tf-deux-signe {
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem; font-weight: 700; color: var(--text-muted, #5b5e77);
}
/* Le prix se met A COTE du texte, pas dessous : empile, il laissait 435 px
   de blanc a droite sur un grand ecran -- exactement le defaut qu'on repare
   par ailleurs. Sous 860 px la carte redevient une colonne. */
.tf-sd {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "num   prix"
    "titre prix"
    "quand prix"
    "txt   prix";
  align-items: start;
  column-gap: 1.6rem;
  padding: 1.5rem 1.6rem 1.5rem;
  border: 1px solid var(--border, #dde0ec); border-radius: 20px;
  background: var(--bg-card, #fff);
  box-shadow: var(--tf-ombre);
  color: inherit; text-decoration: none;
  transition: transform .2s ease, box-shadow .24s ease, border-color .2s ease;
}
.tf-sd-num   { grid-area: num; }
.tf-sd-titre { grid-area: titre; }
.tf-sd-quand { grid-area: quand; justify-self: start; }
.tf-sd-txt   { grid-area: txt; }
.tf-sd-prix  { grid-area: prix; align-self: center; justify-self: end; }
@media (max-width: 1400px) and (min-width: 861px), (max-width: 620px) {
  .tf-sd {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "num" "titre" "quand" "txt" "prix";
  }
  .tf-sd-prix { justify-self: start; margin-top: .9rem; }
}
.tf-sd-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; margin: 0 0 .7rem;
  border-radius: 9px;
  background: var(--accent, #0061cc); color: var(--tf-on-accent);
  font-size: .85rem; font-weight: 700;
}
.tf-sd-titre { font-size: 1.22rem; font-weight: 700; letter-spacing: -.01em; }
.tf-sd-quand {
  margin: .35rem 0 .75rem; padding: .12rem .55rem;
  border-radius: 999px; background: var(--tf-voile);
  border: 1px solid var(--border, #dde0ec);
  font-size: .74rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-muted, #5b5e77);
}
/* Le texte du socle se LIT : il garde une largeur de lecture meme quand la
   carte, elle, s'etale sur un grand ecran. */
.tf-sd-txt {
  margin: 0; max-width: 46ch;
  color: var(--text-muted, #5b5e77); font-size: .93rem;
}
.tf-sd-prix { display: flex; align-items: baseline; flex-wrap: wrap; gap: .3rem; white-space: nowrap; }

/* ── Les blocs numerotes ─────────────────────────────────────────────── */
.tf-bloc { position: relative; margin: 0 0 clamp(2.6rem, 6vw, 4rem); }
.tf-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; margin: 0 0 .7rem;
  border-radius: 10px;
  background: var(--accent, #0061cc); color: var(--tf-on-accent);
  font-size: .95rem; font-weight: 700;
}
.tf-bloc h2 {
  margin: 0 0 .5rem;
  font-size: clamp(1.45rem, 3.4vw, 2rem); font-weight: 700; letter-spacing: -.015em;
}
.tf-sous { margin: 0 0 1.6rem; color: var(--text-muted, #5b5e77); max-width: 62ch; }

/* ── 1. Les trois voies de creation ──────────────────────────────────── */
.tf-voies { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.1rem; }
@media (max-width: 860px) { .tf-voies { grid-template-columns: 1fr; } }
.tf-voie {
  position: relative;
  display: flex; flex-direction: column;
  padding: 1.5rem 1.4rem;
  border: 1px solid var(--border, #dde0ec); border-radius: 18px;
  background: var(--bg-card, #fff);
  box-shadow: var(--tf-ombre);
  transition: transform .2s ease, box-shadow .24s ease, border-color .2s ease;
}
/* L'ETIQUETTE EST HORS DU FLUX, ET C'EST TOUTE LA QUESTION.
   ------------------------------------------------------------------------
   Koray, 09/09/2026 : « site vitrine / site + fonctionnalites / projet sur
   mesure, c'est pas aligne ». MESURE avant correctif : le titre de la
   premiere carte etait 35 px plus bas que les deux autres (754 contre 719),
   et son icone autant.

   La cause : « LE PLUS COURANT » ne vit que sur la premiere carte et vivait
   DANS le flux (`align-self` + `margin-bottom`). Elle poussait donc l'icone,
   le titre, le texte et le prix vers le bas -- de la hauteur exacte d'une
   etiquette que les deux autres cartes n'ont pas.

   Deux facons de reparer, et la mauvaise est tentante : reserver la place
   dans les trois cartes (un pseudo-element vide de meme hauteur). Elle
   marche tant que l'etiquette tient sur une ligne, puis ment le jour ou un
   libelle plus long passe sur deux -- et le decalage revient sans que rien
   ne tombe. Sortir l'etiquette du flux, comme `.tf-ruban` le fait deja pour
   les formules, ne peut pas se decaler : il n'y a plus rien a pousser. */
.tf-etiquette {
  position: absolute; top: 1.1rem; right: 1.1rem;
  padding: .2rem .65rem; border-radius: 999px;
  background: var(--accent-soft, rgba(0, 97, 204, .12));
  color: var(--accent, #0061cc);
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
}
.tf-voie h3 { margin: 0 0 .5rem; font-size: 1.15rem; font-weight: 700; }
.tf-voie-txt { margin: 0 0 1.3rem; color: var(--text-muted, #5b5e77); font-size: .92rem; flex: 1; }
.tf-voie-prix {
  margin: 0; display: flex; align-items: baseline; flex-wrap: wrap; gap: .3rem;
  min-height: 2.3rem;
}
.tf-apd { font-size: .82rem; color: var(--text-muted, #5b5e77); font-weight: 500; }
.tf-montant { font-size: clamp(1.9rem, 4vw, 2.3rem); font-weight: 700; letter-spacing: -.02em; line-height: 1; }
.tf-devis { font-size: 1.4rem; color: var(--accent, #0061cc); }
.tf-unite { font-size: 1.1rem; font-weight: 600; }
.tf-par { font-size: .8em; font-weight: 500; color: var(--text-muted, #5b5e77); }

/* ── 2. Le rythme, et les cinq formules ──────────────────────────────── */
/* L'indicateur est un bloc SEPARE qui se deplace en `transform` : anime en
   `left` ou en `background-position`, il repeindrait la barre a chaque image. */
/* La bascule ET ce qu'on gagne a l'annee, cote a cote. Le gain etait ecrit en
   petit gris sous chaque prix : c'est exactement l'information que Koray
   voulait voir ressortir, elle ne pouvait pas rester en note de bas de carte. */
.tf-rythme {
  display: flex; flex-wrap: wrap; align-items: center; gap: .8rem 1.1rem;
  margin: 0 0 1.6rem;
}
.tf-rythme-gain {
  display: inline-flex; align-items: center; gap: .45rem;
  margin: 0; padding: .42rem .9rem;
  border: 1px solid rgba(22, 163, 74, .32); border-radius: 999px;
  background: rgba(22, 163, 74, .10);
  color: #15803d; font-size: .86rem; font-weight: 600;
}
.tf-rythme-gain svg { width: 15px; height: 15px; flex: none; }
/* Le texte est UN SEUL element de flex. Sans ce <span>, chaque morceau de
   texte en devient un a lui seul : a 390 px, « 16 » et « % » se retrouvaient
   dans deux colonnes, et la phrase se lisait en escalier. */
.tf-rythme-gain > span { min-width: 0; }
.tf-rythme-gain strong { white-space: nowrap; }
.tf-rythme-gain strong { font-weight: 700; }
:root[data-theme="cyan"] .tf-rythme-gain,
:root[data-theme="violet"] .tf-rythme-gain,
:root[data-theme="emeraude"] .tf-rythme-gain,
:root[data-theme="ambre"] .tf-rythme-gain,
:root[data-theme="rose"] .tf-rythme-gain { color: #5ee9a4; border-color: rgba(94, 233, 164, .3); background: rgba(94, 233, 164, .10); }

.tf-bascule {
  position: relative; display: inline-flex; margin: 0; padding: 4px;
  border: 1px solid var(--border, #dde0ec); border-radius: 999px;
  background: var(--bg-card, #fff);
}
.tf-bascule::before {
  content: ""; position: absolute; top: 4px; bottom: 4px; left: 4px;
  width: calc(50% - 4px);
  border-radius: 999px; background: var(--accent, #0061cc);
  transform: translate3d(0, 0, 0);
  transition: transform .28s cubic-bezier(.2, .75, .25, 1);
}
.tf-bascule.is-annuel::before { transform: translate3d(100%, 0, 0); }
.tf-bascule-btn {
  position: relative; z-index: 1;
  min-width: 8.5rem; padding: .55rem 1.1rem;
  border: 0; border-radius: 999px; background: none;
  font: inherit; font-size: .92rem; font-weight: 600;
  color: var(--text-muted, #5b5e77); cursor: pointer;
  transition: color .2s ease;
}
.tf-bascule-btn.is-actif { color: var(--tf-on-accent); }

.tf-formules { display: grid; grid-template-columns: repeat(5, 1fr); gap: .8rem; align-items: stretch; }
@media (max-width: 1080px) { .tf-formules { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 720px)  { .tf-formules { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px)  { .tf-formules { grid-template-columns: 1fr; } }

.tf-formule {
  position: relative;
  display: flex; flex-direction: column;
  padding: 1.4rem 1.1rem 1.2rem;
  border: 1px solid var(--border, #dde0ec); border-radius: 18px;
  background: var(--bg-card, #fff);
  box-shadow: var(--tf-ombre);
  transition: transform .2s ease, box-shadow .24s ease, border-color .2s ease;
}
.tf-vedette { border-color: var(--accent, #0061cc); box-shadow: 0 18px 46px var(--accent-glow, rgba(0, 97, 204, .26)); }
.tf-ruban {
  position: absolute; top: -11px; left: 50%;
  transform: translateX(-50%);
  padding: .18rem .7rem; border-radius: 999px; white-space: nowrap;
  background: var(--accent, #0061cc); color: var(--tf-on-accent);
  font-size: .69rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
}
.tf-formule h3 { margin: .2rem 0 .6rem; font-size: .95rem; font-weight: 700; letter-spacing: .04em; }
/* Le prix barre du cycle annuel. La ligne existe TOUJOURS (meme vide au mois)
   pour que les cinq cartes gardent la meme hauteur : sans ca, basculer fait
   sauter toute la rangee sous le doigt. */
.tf-barre { margin: 0; min-height: 1.5em; font-size: .82rem; color: var(--text-muted, #5b5e77); }
.tf-barre s { text-decoration-thickness: 1.5px; }
.tf-remise {
  display: inline-block; margin-left: .25rem; padding: .06rem .4rem;
  border-radius: 5px; background: rgba(22, 163, 74, .14); color: #15803d;
  font-size: .78rem; font-weight: 700;
}
:root[data-theme="cyan"] .tf-remise,
:root[data-theme="violet"] .tf-remise,
:root[data-theme="emeraude"] .tf-remise,
:root[data-theme="ambre"] .tf-remise,
:root[data-theme="rose"] .tf-remise { color: #5ee9a4; background: rgba(94, 233, 164, .14); }

.tf-prix { margin: 0; display: flex; align-items: baseline; gap: .12rem; }
.tf-prix .tf-montant { font-size: 2rem; }

/* Le gain annuel, en vert et en gras : au mois c'est une invitation, a l'annee
   c'est un acquis. `min-height` pour la meme raison que la ligne barree. */
.tf-gain { margin: .45rem 0 .9rem; min-height: 3.4em; font-size: .78rem; color: var(--text-muted, #5b5e77); }
/* La precision passe A LA LIGNE, entiere. Collee derriere la pastille, elle se
   coupait n'importe ou : « 2 » restait sur la ligne de la pastille et « mois
   offerts » tombait dessous, ce qui se lit comme deux informations. */
.tf-gain-mois { display: block; margin-top: .18rem; }
.tf-gain-pastille {
  display: inline-block; padding: .12rem .5rem; margin-bottom: .12rem;
  border-radius: 6px;
  background: rgba(22, 163, 74, .13); color: #15803d;
  font-weight: 700; font-size: .82rem;
}
:root[data-theme="cyan"] .tf-gain-pastille,
:root[data-theme="violet"] .tf-gain-pastille,
:root[data-theme="emeraude"] .tf-gain-pastille,
:root[data-theme="ambre"] .tf-gain-pastille,
:root[data-theme="rose"] .tf-gain-pastille { color: #5ee9a4; background: rgba(94, 233, 164, .13); }

.tf-quota { margin: 0 0 1.1rem; font-size: .86rem; font-weight: 600; flex: 1; }
.tf-choix {
  display: block; text-align: center;
  padding: .6rem .8rem; border-radius: 11px;
  border: 1px solid var(--border, #dde0ec);
  color: var(--text, #191b2e); text-decoration: none;
  font-size: .86rem; font-weight: 600;
  transition: border-color .2s ease, color .2s ease, background-color .2s ease;
}
.tf-vedette .tf-choix {
  background: var(--accent, #0061cc); border-color: var(--accent, #0061cc);
  color: var(--tf-on-accent);
}

/* L'echange de prix a la bascule. Le script pose `tf-anime` sur la rangee, la
   retire 500 ms plus tard : une animation CSS ne se rejoue pas toute seule
   quand un element passe de `hidden` a visible.
   `transform` et `opacity` uniquement -- un prix qui grossit en `font-size`
   relancerait la mise en page de la carte a chaque image. */
@keyframes tf-echange {
  from { opacity: 0; transform: translate3d(0, 9px, 0) scale(.96); }
  to   { opacity: 1; transform: none; }
}
.tf-formules.tf-anime .tf-prix .tf-cycle,
.tf-formules.tf-anime .tf-barre .tf-cycle { animation: tf-echange .34s cubic-bezier(.2, .8, .3, 1) backwards; }
.tf-formules.tf-anime .tf-gain .tf-cycle { animation: tf-echange .42s cubic-bezier(.2, .8, .3, 1) .06s backwards; }
.tf-formules.tf-anime .tf-formule:nth-child(2) .tf-cycle { animation-delay: .04s; }
.tf-formules.tf-anime .tf-formule:nth-child(3) .tf-cycle { animation-delay: .08s; }
.tf-formules.tf-anime .tf-formule:nth-child(4) .tf-cycle { animation-delay: .12s; }
.tf-formules.tf-anime .tf-formule:nth-child(5) .tf-cycle { animation-delay: .16s; }

/* L'icone de chaque voie de creation. Elle apparait par `transform` a
   l'ouverture, en meme temps que sa carte. */
.tf-voie-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; margin: 0 0 .9rem;
  border-radius: 12px;
  background: var(--accent-soft, rgba(0, 97, 204, .12));
  color: var(--accent, #0061cc);
}
.tf-voie-ico svg { width: 21px; height: 21px; }

/* ── Le socle commun ─────────────────────────────────────────────────── */
.tf-socle {
  margin: 1.4rem 0 0; padding: 1.3rem 1.4rem;
  border: 1px solid var(--border, #dde0ec); border-radius: 18px;
  background: var(--tf-voile);
}
.tf-socle h3 { margin: 0 0 .8rem; font-size: 1rem; font-weight: 700; }
.tf-socle ul {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem 1.2rem;
  list-style: none; margin: 0; padding: 0;
}
@media (max-width: 860px) { .tf-socle ul { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .tf-socle ul { grid-template-columns: 1fr; } }
.tf-socle li {
  position: relative; padding-left: 1.6rem;
  font-size: .89rem; color: var(--text-muted, #5b5e77);
}
.tf-socle li::before {
  content: ""; position: absolute; left: 0; top: .45em;
  width: 13px; height: 13px;
  background: var(--accent, #0061cc);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 13 4.5 4.5L19 7'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 13 4.5 4.5L19 7'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* ── Les tableaux ────────────────────────────────────────────────────── */
.tf-tableau-aide { margin: 2rem 0 .6rem; font-size: .88rem; font-weight: 600; color: var(--text-muted, #5b5e77); }
/* `overflow-x: auto` est assume : un tableau a six colonnes ne rentre pas dans
   390 px, et le comprimer le rendrait illisible. La sonde du balayage
   responsive ignore volontairement ce qui vit dans un conteneur qui defile. */
.tf-tableau-cadre {
  overflow-x: auto;
  /* `contain: paint` EN PLUS du defilement, et ce n'est pas de la ceinture et
     des bretelles. MESURE a 390 px : avec `overflow-x: auto` seul, le conteneur
     defilait bien (348 px visibles pour 756 px de contenu) et POURTANT le
     document entier sortait a 738 px -- la fenetre de mise en page s'elargit,
     et le telephone affiche la page dezoomee. Quatre autres pistes essayees et
     mesurees FAUSSES : retirer le `position: sticky` des en-tetes, retirer le
     `min-width`, poser `max-width: 100%`, passer `overflow` sur les deux axes.
     Seul `contain: paint` ramene le document a 390. */
  contain: paint;
  border: 1px solid var(--border, #dde0ec); border-radius: 16px;
  background: var(--bg-card, #fff);
  box-shadow: var(--tf-ombre);
}
.tf-tableau-cadre:focus-visible { outline: 2px solid var(--accent, #0061cc); outline-offset: 2px; }
.tf-comparatif, .tf-options { width: 100%; min-width: 640px; border-collapse: collapse; font-size: .88rem; }
.tf-comparatif th, .tf-comparatif td,
.tf-options th, .tf-options td { padding: .72rem .9rem; text-align: left; }
.tf-comparatif thead th, .tf-options thead th {
  position: sticky; top: 0;
  background: var(--bg-card-2, #f1f3f9);
  font-size: .78rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-muted, #5b5e77);
  white-space: nowrap;
}
.tf-comparatif tbody tr + tr, .tf-options tbody tr + tr { border-top: 1px solid var(--border, #dde0ec); }
.tf-comparatif tbody th, .tf-options tbody th { font-weight: 600; white-space: nowrap; }
.tf-comparatif td { text-align: center; }
.tf-comparatif thead th:not(:first-child) { text-align: center; }
.tf-non { color: var(--text-muted, #5b5e77); opacity: .55; }
.tf-coche {
  display: inline-block; width: 15px; height: 15px;
  background: var(--accent, #0061cc);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 13 4.5 4.5L19 7'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 13 4.5 4.5L19 7'/%3E%3C/svg%3E") center / contain no-repeat;
}
.tf-opt-prix { white-space: nowrap; font-weight: 700; }
.tf-opt-quand, .tf-opt-inclus { color: var(--text-muted, #5b5e77); }

/* ── 4. Plusieurs etablissements ─────────────────────────────────────── */
.tf-encadre {
  padding: 1.7rem 1.6rem;
  border: 1px solid var(--accent-soft, rgba(0, 97, 204, .3)); border-radius: 20px;
  background: var(--accent-soft, rgba(0, 97, 204, .07));
}
.tf-etab { display: grid; grid-template-columns: repeat(3, 1fr); gap: .8rem; list-style: none; margin: 0; padding: 0; }
@media (max-width: 720px) { .tf-etab { grid-template-columns: 1fr; } }
.tf-etab li {
  padding: .9rem 1rem; border-radius: 14px;
  background: var(--bg-card, #fff); border: 1px solid var(--border, #dde0ec);
  font-size: .9rem;
}
.tf-etab strong { display: block; font-size: 1.5rem; font-weight: 700; color: var(--accent, #0061cc); line-height: 1.2; }
.tf-etab-note { margin: 1rem 0 0; font-size: .85rem; color: var(--text-muted, #5b5e77); }

/* ── Un exemple complet : l'addition, posee ──────────────────────────── */
/* Trois lignes et deux signes, comme sur un ticket. C'est la reponse a « les
   tarifs arrivent petit a petit » : ici tout est additionne devant le
   visiteur, et le total est le plus gros chiffre de la page. */
.tf-addition {
  display: grid;
  grid-template-columns: 1fr auto 1fr auto 1fr;
  align-items: stretch;
  gap: .7rem;
}
@media (max-width: 900px) { .tf-addition { grid-template-columns: 1fr; } }
.tf-add-ligne {
  display: flex; flex-direction: column; justify-content: space-between; gap: .5rem;
  padding: 1.2rem 1.2rem;
  border: 1px solid var(--border, #dde0ec); border-radius: 16px;
  background: var(--bg-card, #fff);
  box-shadow: var(--tf-ombre);
}
.tf-add-quoi { font-size: .9rem; font-weight: 600; }
.tf-add-quoi em {
  display: block; margin-top: .15rem;
  font-style: normal; font-size: .78rem; font-weight: 500;
  color: var(--text-muted, #5b5e77);
}
.tf-add-combien { font-size: 1.7rem; font-weight: 700; letter-spacing: -.02em; }
.tf-add-signe {
  display: flex; align-items: center; justify-content: center;
  font-size: 1.4rem; font-weight: 700; color: var(--text-muted, #5b5e77);
}
@media (max-width: 900px) { .tf-add-signe { padding: .1rem 0; } }
.tf-add-total {
  border-color: var(--accent, #0061cc);
  background: var(--accent, #0061cc);
  color: var(--tf-on-accent);
  box-shadow: 0 16px 40px var(--accent-glow, rgba(0, 97, 204, .3));
}
.tf-add-total .tf-add-quoi em { color: inherit; opacity: .8; }
.tf-add-total .tf-add-combien { font-size: 2rem; }
.tf-add-suite { margin: 1.1rem 0 0; font-size: .9rem; color: var(--text-muted, #5b5e77); }

/* ── 5. Les questions ────────────────────────────────────────────────── */
/* Deux colonnes des que la place existe : en une seule, chaque reponse
   ferait des lignes de plus de 180 caracteres sur un grand ecran -- l'oeil
   perd la ligne suivante. `align-items: start` pour qu'une question ouverte
   n'etire pas sa voisine. */
.tf-questions { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 .8rem; align-items: start; }
@media (max-width: 860px) { .tf-questions { grid-template-columns: 1fr; } }
.tf-q {
  border: 1px solid var(--border, #dde0ec); border-radius: 14px;
  background: var(--bg-card, #fff);
  margin-bottom: .6rem;
  overflow: hidden;
}
.tf-q summary {
  position: relative;
  padding: .95rem 3rem .95rem 1.1rem;
  font-weight: 600; cursor: pointer; list-style: none;
}
.tf-q summary::-webkit-details-marker { display: none; }
.tf-q summary::after {
  content: ""; position: absolute; right: 1.1rem; top: 50%;
  width: 13px; height: 13px; margin-top: -6px;
  background: var(--text-muted, #5b5e77);
  transform: rotate(0deg);
  transition: transform .25s ease;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
}
.tf-q[open] summary::after { transform: rotate(180deg); }
.tf-q p { margin: 0; padding: 0 1.1rem 1.1rem; color: var(--text-muted, #5b5e77); font-size: .92rem; }
.tf-q[open] p { animation: tf-monte .3s ease backwards; }

/* ── L'appel a l'action ──────────────────────────────────────────────── */
.tf-final {
  text-align: center;
  padding: 2.4rem 1.6rem;
  border: 1px solid var(--border, #dde0ec); border-radius: 22px;
  background: var(--bg-card, #fff);
  box-shadow: var(--tf-ombre);
}
.tf-final h2 { margin: 0 0 .5rem; font-size: clamp(1.4rem, 3.2vw, 1.9rem); font-weight: 700; }
.tf-final > p { margin: 0 auto 1.6rem; max-width: 54ch; color: var(--text-muted, #5b5e77); }
.tf-final-btns { display: flex; flex-wrap: wrap; justify-content: center; gap: .7rem; }
.tf-cta {
  display: inline-flex; align-items: center; justify-content: center;
  padding: .85rem 1.6rem; border-radius: 12px;
  background: var(--accent, #0061cc); color: var(--tf-on-accent);
  text-decoration: none; font-weight: 600;
  box-shadow: 0 10px 26px var(--accent-glow, rgba(0, 97, 204, .28));
  transition: transform .16s ease, box-shadow .22s ease;
}
.tf-cta-2 {
  background: none; color: var(--text, #191b2e);
  border: 1px solid var(--border, #dde0ec); box-shadow: none;
}
.tf-cta:active { transform: scale(.99); }
.tf-tva { margin: 1.6rem 0 0; font-size: .8rem; color: var(--text-muted, #5b5e77); }

/* ── Pied de page ────────────────────────────────────────────────────── */
.tf-foot { text-align: center; color: var(--text-muted, #5b5e77); font-size: .85rem; margin-top: 2.6rem; }
.tf-foot a { color: var(--accent, #0061cc); }

/* ── Survol : UNIQUEMENT a la souris ─────────────────────────────────── */
@media (hover: hover) and (pointer: fine) {
  .tf-voie:hover, .tf-formule:hover { transform: translateY(-3px); box-shadow: 0 22px 54px rgba(10, 14, 40, .14); }
  .tf-sd:hover { transform: translateY(-3px); box-shadow: 0 22px 54px rgba(10, 14, 40, .14); border-color: var(--accent, #0061cc); }
  .tf-vedette:hover { box-shadow: 0 24px 60px var(--accent-glow, rgba(0, 97, 204, .34)); }
  .tf-choix:hover { border-color: var(--accent, #0061cc); color: var(--accent, #0061cc); }
  .tf-vedette .tf-choix:hover { color: var(--tf-on-accent); background: var(--accent, #0061cc); filter: brightness(1.08); }
  .tf-bascule-btn:hover { color: var(--accent, #0061cc); }
  .tf-bascule-btn.is-actif:hover { color: var(--tf-on-accent); }
  .tf-cta:hover { transform: translateY(-2px); box-shadow: 0 16px 34px var(--accent-glow, rgba(0, 97, 204, .38)); }
  .tf-cta-2:hover { border-color: var(--accent, #0061cc); color: var(--accent, #0061cc); box-shadow: none; }
  .tf-q summary:hover { color: var(--accent, #0061cc); }
  .tf-foot a:hover, .tf-final a:hover { text-decoration: none; }

  .tf-orb-1 { animation: tf-derive-1 28s ease-in-out infinite alternate; }
  .tf-orb-2 { animation: tf-derive-2 34s ease-in-out infinite alternate; }
}
@keyframes tf-derive-1 { to { transform: translate3d(70px, 60px, 0) scale(1.14); } }
@keyframes tf-derive-2 { to { transform: translate3d(-80px, -50px, 0) scale(.88); } }

/* ── Mouvement reduit ────────────────────────────────────────────────── */
/* `animation-delay` fait partie du lot : avec un retard conserve, un element
   en `fill-mode: backwards` tient sa premiere image -- donc `opacity: 0` --
   pendant tout le retard. Un retard NEGATIF le donne deja termine. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-delay: -1ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

