/* ══════════════════════════════════════════════════════════════════════════
   RESPONSIVE — téléphone et tablette.

   La maquette a été dessinée pour un écran d'ordinateur : maquette_base.css
   ne contient aucune media query et fixe ses colonnes en dur, jusqu'à sept.

   Le repli des grilles n'est PAS écrit ici : il est généré depuis la maquette
   par `outils/generer_responsive.py` dans `grilles_mobile.css`. Énumérer les
   grilles à la main avait laissé passer .b2b, .waitlist, .kidsband et
   .leveltest — dont la colonne de texte s'écrasait à une lettre de large,
   ce qui écrivait les phrases verticalement. On ne recommence pas.

   Ce fichier ne garde que ce qu'aucun script ne peut deviner : la barre du
   haut, les bandeaux, le défilement tactile, les cas à styles en ligne.

   Chargé APRÈS site.css : à spécificité égale, c'est lui qui gagne. Aucun
   !important, sauf face aux styles en ligne du HTML (signalés sur place).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1. Socle ─────────────────────────────────────────────────────────────
   Pas de `* { min-width: 0 }` global : cette règle, dans une grille à deux
   colonnes non repliée, laisse la colonne de texte tomber à un caractère de
   large. C'est ce qui écrivait les phrases une lettre par ligne. On répare
   la cause (les grilles se replient) au lieu du symptôme. */
img, svg, video, canvas, iframe { max-width: 100%; }

/* `[hidden]` est une règle du navigateur, sans spécificité : une simple classe
   qui déclare un `display` la neutralise. C'est ce qui faisait réapparaître le
   compteur de liste d'attente à zéro. */
[hidden] { display: none !important; }

.site h1, .site h2, .site h3, .site p, .site li,
.site td, .site th, .site .cap, .site .lb {
  overflow-wrap: break-word;
}

/* Un bouton ne se comprime jamais : sans cela, une rangée serrée empile ses
   lettres à la verticale (« G é r e r »). */
.site .btn, .site .hbtn, .site .tvbtn, .site .rndbtn,
.site button:not(.tiroirbtn):not(.tfermer) {
  flex-shrink: 0;
  white-space: nowrap;
}
.site .btn.alarge { white-space: normal; }

/* Le logo et le nom ramènent à l'accueil — le réflexe attendu sur tout site.
   Devenus un lien, ils héritaient du soulignement et de la couleur des liens :
   on les remet exactement comme avant. */
.topnav a.lg {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
.topnav a.lg b { color: var(--navy); }
body.dark .topnav a.lg b, .tv .topnav a.lg b { color: #fff; }
.topnav a.lg:hover b { color: var(--crimson); }
/* Sur téléphone le mot-symbole est masqué : il ne reste que l'emblème, soit
   26 × 19 px de zone cliquable. On élargit la cible sans déplacer l'emblème. */
@media (hover: none) {
  .topnav a.lg { min-height: 38px; padding: 4px 6px; margin: -4px -6px; }
}

/* Les deux liens de la barre sont enveloppés dans une pastille : c'est la
   pastille qui a la taille, pas le lien. On étend le lien à toute la
   pastille, sinon la zone réellement cliquable ne fait que 72 × 12 px. */
.authbtns .lgin, .authbtns .sgup { display: inline-flex; align-items: stretch; }
.authbtns .lgin a, .authbtns .sgup a {
  display: flex; align-items: center; justify-content: center; width: 100%;
}

/* Confort tactile : pas de cible en dessous de 40 px sur écran sans souris */
@media (hover: none) {
  .site a.btn, .site .hbtn, .site .tvbtn, .site button { min-height: 40px; }
  .site .tvchip, .site .ftab { min-height: 36px; display: inline-flex; align-items: center; }
  /* les liens discrets — mot de passe oublié, liens de pied de carte — sont
     hauts de 14 px : on les épaissit sans changer leur apparence */
  .site .aoubli a, .site .abas a, .site .go, .site .lk2,
  .site p a, .site li a {
    display: inline-block; padding: 6px 1px;
  }
  /* la hauteur se pose sur le LIEN, pas sur la pastille : c'est le lien qui
     reçoit le doigt, et il ne s'étire pas tout seul dans un conteneur centré */
  .authbtns .lgin a, .authbtns .sgup a { min-height: 34px; }
}

/* ── 2. Rangées souples ───────────────────────────────────────────────────
   Ces rangées mêlent un texte extensible et un élément de largeur fixe. Sur
   un écran étroit elles doivent passer à la ligne, jamais se comprimer. */
@media (max-width: 760px) {
  .site .wlform { flex-wrap: wrap; gap: 9px; }
  .site .wlform input { width: auto; flex: 1 1 190px; min-width: 0; }
  .site .accessbar .txt { min-width: 0; flex: 1 1 100%; }
  .site .book .ft,
  .site .exhd,
  .site .tvrow h3,
  .site .nat .top,
  .site .chathead .rt2 { flex-wrap: wrap; }
  .site .rline .rn2 { flex: 0 0 auto; width: auto; }

  /* les trois choix de série (10 / 20 / 40 questions) sont alignés en ligne :
     à 320 px la dernière pastille sort de l'écran. On les laisse passer à la
     ligne et occuper toute la largeur — plus lisible, et plus facile à viser. */
  .site .qbtns { flex-wrap: wrap; gap: 8px; }
  .site .qbtns .qsm, .site .qbtns .qbig { flex: 1 1 auto; text-align: center; }
}

/* ── 3. La barre du haut ──────────────────────────────────────────────────
   Le tiroir ☰ porte déjà toute la navigation : sur mobile la barre ne garde
   que l'essentiel, sur une seule ligne, sans jamais rien couper. */
@media (max-width: 980px) {
  .topnav             { padding: 9px 13px; gap: 10px; row-gap: 8px; }
  .topnav .lk         { display: none; }
  .audsw              { display: none; }
  .topnav .rt .btn.sm { display: none; }
  .topnav .rt         { gap: 8px; }
  section.blk         { padding: 34px 18px; }
  .hero               { padding: 40px 18px 44px; }
}

@media (max-width: 560px) {
  section.blk { padding: 26px 14px; }
  .hero       { padding: 32px 14px 36px; }

  .topnav             { padding: 8px 11px; gap: 8px; flex-wrap: nowrap; }
  .topnav .lg b       { display: none; }   /* l'emblème suffit, le nom est dans le tiroir */
  .topnav .lg .bulles { height: 19px; }
  .topnav .rt         { gap: 6px; }
  .btn.sm             { font-size: 11.5px; padding: 6px 11px; }
  .authbtns           { display: flex; gap: 7px; flex: 0 0 auto; }
  .lgin, .sgup        { font-size: 12px; }

  h2.sh    { font-size: 19px; }
  p.lead   { font-size: 14px; }
  .hero h1 { font-size: 27px; letter-spacing: -.6px; }
}

@media (max-width: 380px) {
  .topnav      { padding: 7px 9px; gap: 6px; }
  .lgin, .sgup { font-size: 11.5px; }
}

@media (max-width: 720px) {
  h2.sh  { font-size: 21px; }
  p.lead { font-size: 14px; }
  .cal   { gap: 4px; font-size: 11px; }
  .avatar     { width: 64px; height: 64px; font-size: 22px; }
  .acct .avatar { width: 30px; height: 30px; font-size: 12px; }
}

/* ── 4. Le bandeau d'accueil ──────────────────────────────────────────────
   Hauteur fixe de 470 px et contenu en position absolue : sur téléphone le
   texte dépasse le cadre et passe sous les cartes suivantes. On remet le
   contenu dans le flux.

   `relative` et non `static` : le z-index:3 de la maquette n'agit que sur un
   élément positionné. En static, le voile sombre se peint par-dessus le
   titre et le fait disparaître — vérifié, et corrigé. */
@media (max-width: 820px) {
  .hero2   { height: auto; min-height: 400px; }
  .heroctn { position: relative; inset: auto; padding: 52px 18px 42px; }
  .heroimg { inset: 0; }

  .heroctn h1     { font-size: clamp(26px, 8vw, 38px); letter-spacing: -.8px; }
  .heroctn p      { font-size: 14.5px; }
  .heroctn .kick2 { letter-spacing: 2.6px; font-size: 10px; }
  .heroctn .cta   { width: 100%; flex-direction: column; align-items: stretch; }
  .heroctn .cta .hbtn { width: 100%; text-align: center; padding: 13px 18px; }

  .fig.t { left: 4%;  width: 120px; height: 195px; }
  .fig.f { right: 5%; width: 108px; height: 176px; }
}
@media (max-width: 480px) {
  .hero2 { min-height: 360px; }
  .figs  { opacity: .55; }
}

/* ── 5. Le bandeau TFA TV ─────────────────────────────────────────────────
   L'emplacement image y est positionné en absolu par un STYLE EN LIGNE du
   HTML (right:30px; top:40px; width:300px). Un style en ligne bat toutes les
   feuilles : c'est l'un des deux seuls endroits du site où `!important` est
   justifié. Sans cela, l'encadré se pose sur le titre. */
@media (max-width: 820px) {
  .tvhero { height: auto; flex-direction: column; align-items: stretch;
            padding: 20px 16px 26px; }
  .tvhero .masc {
    position: relative !important;
    right: auto !important; top: auto !important; bottom: auto !important;
    width: 100% !important;
    height: 176px; margin: 0 0 18px;
    order: -1;                        /* l'image d'abord, le texte ensuite */
  }
  .tvhero .in2  { max-width: none; }
  .tvhero h1    { font-size: clamp(22px, 7vw, 30px); }
  .tvhero .mute { display: none; }    /* aucun son à couper tant qu'il n'y a pas de vidéo */
}

/* ── 6. LE CARROUSEL TFA TV — défilement au doigt ─────────────────────────
   La maquette fait défiler les rangées avec `transform: translateX()`, animé
   par deux flèches qui n'apparaissent qu'AU SURVOL. Sur un téléphone il n'y
   a pas de survol : les flèches n'existent pas, le transform ne bouge jamais,
   et les vidéos hors cadre sont simplement inaccessibles.

   On rend donc la rangée nativement défilable au doigt, avec inertie et
   accrochage par vignette, et on neutralise le transform hérité. */
@media (max-width: 900px), (hover: none) {
  .tvviewport {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
  }
  .tvviewport::-webkit-scrollbar { display: none; }

  .tvtrack {
    transform: none !important;       /* neutralise la pagination par flèches */
    padding: 14px 16px 18px;
    width: max-content;
  }
  .tvcard { scroll-snap-align: start; }

  .tvnav { display: none; }           /* inutile : on fait défiler au doigt */
  .tvcard .pop { display: none; }     /* l'aperçu au survol n'existe pas au doigt */
}

/* ── 7. Tableaux : ils défilent dans leur cadre, pas la page ─────────────── */
@media (max-width: 900px) {
  table.tb, table.inv, .inv table, .doc table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    width: 100%;
  }
  table.tb td, table.tb th { white-space: nowrap; }
}

/* ── 8. Les grilles écrites en ligne dans le HTML ─────────────────────────
   Second et dernier endroit où `!important` est nécessaire : plusieurs blocs
   portent leur nombre de colonnes en attribut style, ce qu'aucune feuille ne
   peut surcharger autrement. */
@media (max-width: 1000px) {
  .site [style*="grid-template-columns"] {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}
@media (max-width: 760px) {
  .site [style*="grid-template-columns"] {
    grid-template-columns: minmax(0, 1fr) !important;
  }
}

/* ── 9. Les tarifs : comparaison au doigt ─────────────────────────────────
   Empiler trois formules l'une sous l'autre oblige à mémoriser la première
   pour la comparer à la troisième. On les garde côte à côte, en laissant
   dépasser la suivante pour que le geste soit évident. */
@media (max-width: 760px) {
  .pricing .grid4[style] {
    grid-template-columns: none !important;
    display: flex;
    gap: 13px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    scroll-padding-left: 14px;
    padding: 4px 14px 14px;
    margin: 0 -14px;                 /* la rangée touche les bords de l'écran */
    scrollbar-width: none;
  }
  .pricing .grid4[style]::-webkit-scrollbar { display: none; }
  .pricing .grid4[style] > .card {
    flex: 0 0 82%;                   /* 18 % de la suivante restent visibles */
    scroll-snap-align: start;
    margin: 0;
  }
}

/* ── 10. Le tiroir et la pastille de compte sur petit écran ─────────────── */
@media (max-width: 340px) { .tiroir { width: 88vw; } }

@media (max-width: 480px) {
  .acctmenu       { width: min(242px, calc(100vw - 24px)); right: 0; }
  .acct .idn b,
  .acct .idn span { max-width: 96px; overflow: hidden; text-overflow: ellipsis; }
}

/* ══════════════════════════════════════════════════════════════════════════
   11. NOTES DE TRAVAIL — INVISIBLES POUR LE PUBLIC

   La maquette porte des encadrés « EMPLACEMENT IMAGE · OPENART 16:9 » qui
   décrivent l'illustration à produire. C'étaient des repères de conception ;
   sur un site en ligne, ce sont des chantiers apparents. On les masque, en
   gardant les cadres et les dégradés — qui, eux, ont l'air voulus.

   Rien n'est supprimé du HTML : le jour où les images arrivent, elles
   viennent remplir exactement ces cadres.
   ══════════════════════════════════════════════════════════════════════════ */
.heroimg .ph,
.masc .lbl,
.masc .wave,
.mascots,
.doc .illus { display: none !important; }

/* le cadre en pointillés devient un cadre net, comme une affiche en attente */
.masc { border-style: solid !important; border-color: rgba(255,255,255,.13) !important; }

/* ══════════════════════════════════════════════════════════════════════════
   12. TRULY ET FLUENT — les visages du site
   ══════════════════════════════════════════════════════════════════════════ */
/* Sélecteur volontairement long : la maquette contient `body.dark .site > *`
   qui impose `position:relative; z-index:1` à tout enfant direct de `.site`.
   Avec un simple `.mascotte-coin`, la vignette repassait dans le flux et
   tombait tout en bas de la page. */
.site > .mascotte-coin,
body.dark .site > .mascotte-coin {
  position: absolute; top: 62px; right: 18px; width: 132px; z-index: 4;
  opacity: .42; pointer-events: none; transition: opacity .4s ease;
  filter: drop-shadow(0 6px 18px rgba(0,0,0,.28));
}
.mascotte-coin .mc-img { display: block; width: 100%; height: auto; }
.site:hover > .mascotte-coin { opacity: .62; }
body.dark .site > .mascotte-coin { opacity: .34; }
body.dark .site:hover > .mascotte-coin { opacity: .52; }

.mascotte-grande {
  position: absolute; inset: 0; overflow: hidden;
  z-index: 1; pointer-events: none;
}
/* L'image porte TRULY à l'extrême gauche et FLUENT à l'extrême droite, le
   centre volontairement vide pour le titre. Elle doit donc occuper toute la
   largeur du bandeau : la contraindre à une largeur fixe ramènerait les deux
   personnages vers le milieu, sous le texte. Ancrée en bas, le haut vide est
   ce qui déborde. */
.mascotte-grande .mg-img {
  position: absolute; left: 0; top: 0; width: 100%; height: auto;
  filter: drop-shadow(0 18px 46px rgba(0,0,0,.45));
}
/* Ancrage EN HAUT, et non en bas : l'image est plus haute que le bandeau, il
   faut donc en couper une partie. Les têtes portent toute l'identité de la
   marque — on coupe les jambes, jamais les têtes. */

.mascotte-tv { position: absolute; inset: 0; overflow: hidden; border-radius: 13px; }
.mascotte-tv .mtv-img { width: 100%; height: 100%; object-fit: cover;
                        display: block; transform: scale(1.02); }
.mascotte-tv::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 42%, transparent 42%, rgba(4,10,22,.55) 100%),
    linear-gradient(180deg, transparent 62%, rgba(4,10,22,.72) 100%);
}

.acct .avatar { position: relative; overflow: hidden; }
.acct .avatar .av-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 22%; display: block;
}
.acct .avatar.a-photo { color: transparent; }

@media (max-width: 820px) {
  .site > .mascotte-coin { width: 84px; top: 56px; right: 10px; opacity: .3; }
  /* Pleine largeur, et rien d'autre. Agrandir l'image sur un écran étroit
     ramène mécaniquement les deux personnages vers le centre — donc derrière
     le titre, ce que toute la composition cherche justement à éviter. */
  .mascotte-grande .mg-img { width: 100%; left: 0; }
  .mascotte-grande { opacity: .85; }
}
@media (max-width: 480px) {
  .site > .mascotte-coin { width: 62px; top: 52px; right: 7px; opacity: .26; }
}


/* ══════════════════════════════════════════════════════════════════════════
   13. DÉTAILS DE LISIBILITÉ ET D'ÉTAT

   Deux défauts relevés par le contrôle de contraste automatique :
   · les liens des pages légales prenaient le bleu par défaut du navigateur
     (#0000EE), soit 1,64:1 sur fond sombre — illisible ;
   · un bouton désactivé gardait sa couleur de marque atténuée, ce qui donnait
     un texte à 3,28:1 et laissait croire qu'il était encore cliquable.
   ══════════════════════════════════════════════════════════════════════════ */
.site p a, .site li a, .site .attention a {
  color: var(--crimson);
  text-decoration: underline;
  text-underline-offset: 2px;
}
body.dark .site p a,
body.dark .site li a,
body.dark .site .attention a { color: #FF9DB6; }

/* un bouton indisponible doit le dire : gris franc, curseur neutre */
.site .btn:disabled, .site .btn[disabled],
.site button:disabled {
  opacity: 1;
  background: var(--brd);
  color: var(--soft);
  border-color: transparent;
  cursor: not-allowed;
}
body.dark .site .btn:disabled,
body.dark .site button:disabled { background: #2A3446; color: #93A6BF; }


/* ── le bandeau de réponse des fonctions à venir ──────────────────────────
   Il apparaît en bas, au-dessus de tout, se lit en une phrase et disparaît.
   Sur téléphone il occupe toute la largeur ; sur ordinateur il reste discret
   dans le coin. */
#tfa-avis {
  position: fixed; z-index: 400;
  left: 14px; right: 14px; bottom: 16px;
  display: flex; align-items: flex-start; gap: 12px;
  background: #14243D; color: #EAF1FA;
  border: 1px solid rgba(255,255,255,.14);
  border-left: 3px solid var(--crimson);
  border-radius: 11px; padding: 13px 14px;
  font-size: 13.5px; line-height: 1.55;
  box-shadow: 0 14px 40px rgba(0,0,0,.45);
  opacity: 0; visibility: hidden; transform: translateY(12px);
  transition: opacity .22s ease, transform .22s ease, visibility .22s;
}
#tfa-avis.vu { opacity: 1; visibility: visible; transform: none; }
#tfa-avis span { flex: 1; }
#tfa-avis button {
  flex: 0 0 auto; background: transparent; border: 0; color: #9FB4CE;
  font-size: 15px; line-height: 1; cursor: pointer; padding: 2px 4px;
}
#tfa-avis button:hover { color: #fff; }

@media (min-width: 760px) {
  #tfa-avis { left: auto; right: 22px; bottom: 22px; max-width: 420px; }
}
