/* ============================================================
   SYSTÈME DE CONCEPTION — Apprenons Juntos !
   Créé le 09/10/2026, variables déplacées dans theme.css le 18/10/2026.

   Chargée APRÈS theme.css (qui porte la palette et la base) et AVANT
   pages.css (qui porte les styles propres à une page).
   Ici : UNIQUEMENT les composants du site — boutons, cartes, pilules,
   jauges, tableaux, page de leçon, parcours, cadenas de chapitre.
   Aucune couleur n'est écrite en dur : tout passe par les variables.

   PRINCIPES
     1. Une seule largeur de lecture pour tout le site (1040 px).
     2. Les boutons ont une « épaisseur » : une ombre pleine sous le
        bouton, qui s'écrase quand on clique. C'est la signature Duolingo.
     3. Beaucoup d'air, des angles très arrondis, des couleurs franches.
     4. Tout doit tenir sur un téléphone sans débordement.
   ============================================================ */

/* ---------- La largeur unique de tout le site ---------- */
.conteneur-page,
.conteneur-admin {
    width: 100%;
    max-width: var(--largeur);
    margin: 0 auto;
    padding: 1.5rem 1rem 3rem;
}
.conteneur-etroit { max-width: 760px; }

@media (min-width: 768px) {
    .conteneur-page, .conteneur-admin { padding-left: 1.5rem; padding-right: 1.5rem; }
}

/* ---------- Boutons « en relief » ---------- */
.bouton-principal,
.bouton-secondaire,
.bouton-danger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .8rem 1.6rem;
    border: 0;
    border-radius: var(--r-pilule);
    font-family: inherit;
    font-size: .95rem;
    font-weight: 800;
    letter-spacing: .02em;
    text-decoration: none;
    cursor: pointer;
    transition: transform .1s ease, box-shadow .1s ease, background .15s ease;
}
/* LE BOUTON PRINCIPAL EST UN SYSTÈME DE VARIABLES, PAS UNE COULEUR FIXE.
   Une variante (l'invitation bleue de la leçon) ne redéfinit QUE ses
   variables. Avant, `:hover` peignait `--vert-clair` en dur : le bouton
   bleu redevenait donc VERT au survol. */
.bouton-principal {
    --fond: var(--vert); --fond-survol: var(--vert-clair);
    --ombre-bouton: var(--vert-ombre); --texte-bouton: #fff;
    background: var(--fond); color: var(--texte-bouton); box-shadow: 0 4px 0 var(--ombre-bouton);
}
.bouton-principal:hover {
    background: var(--fond-survol); color: var(--texte-bouton);
    transform: translateY(-1px); box-shadow: 0 5px 0 var(--ombre-bouton);
}
.bouton-secondaire {
    --ombre-bouton: var(--bord); --texte-bouton: var(--bleu-fonce);
    background: var(--blanc); color: var(--bleu-fonce); box-shadow: 0 4px 0 var(--ombre-bouton); border: 2px solid var(--bord);
}
.bouton-secondaire:hover { background: #f4f9ff; color: var(--bleu-fonce); }
.bouton-danger {
    --ombre-bouton: var(--rouge-ombre); --texte-bouton: #fff;
    background: var(--rouge); color: #fff; box-shadow: 0 4px 0 var(--ombre-bouton);
}
.bouton-principal:active, .bouton-secondaire:active, .bouton-danger:active {
    transform: translateY(3px);
    box-shadow: 0 1px 0 var(--ombre-bouton, var(--vert-ombre));
}

/* ---------- Cartes ---------- */
.carte {
    background: var(--blanc);
    border: 2px solid var(--bord);
    border-radius: var(--r);
    padding: 1.25rem 1.4rem;
    margin-bottom: 1.2rem;
}
.carte-message {
    background: var(--blanc);
    border: 2px solid var(--bord);
    border-radius: var(--r);
    padding: 2rem 1.6rem;
    text-align: center;
    max-width: 560px;
    margin: 2rem auto;
}
.carte-message h1, .carte-message h2 { font-size: 1.25rem; margin: 0 0 .6rem; }
.carte-message p { color: var(--texte-doux); margin: 0 0 1.2rem; }

/* ---------- Barres de progression ---------- */
.jauge-bloc {
    width: 100%;
    height: 14px;
    border-radius: var(--r-pilule);
    background: var(--bord-doux);
    overflow: hidden;
}
.jauge-bloc > span {
    display: block;
    height: 100%;
    border-radius: var(--r-pilule);
    background: linear-gradient(90deg, var(--vert-clair), var(--vert));
    transition: width .4s ease;
}

/* ---------- En-tête de page (fil d'Ariane + titre) ---------- */
.entete-section {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.4rem;
}
.entete-section .titre { font-size: 1.4rem; font-weight: 800; color: var(--encre); margin: 0; }
.entete-section .sous-titre { font-size: .9rem; color: var(--texte-doux); margin: .2rem 0 0; }

.fil-ariane {
    font-size: .82rem;
    font-weight: 600;
    color: var(--texte-doux);
    margin-bottom: .5rem;
}
.fil-ariane a { color: var(--bleu-fonce); text-decoration: none; }
.fil-ariane a:hover { text-decoration: underline; }

/* ---------- Bandeau d'accueil ---------- */
.bandeau-accueil {
    display: flex;
    flex-wrap: wrap;
    gap: 1.2rem;
    align-items: center;
    justify-content: space-between;
    padding: 1.3rem 1.5rem;
    border-radius: var(--r);
    background: linear-gradient(135deg, var(--bleu), var(--bleu-fonce));
    color: #fff;
    margin-bottom: 1.8rem;
    box-shadow: 0 6px 18px rgba(28, 176, 246, .22);
}
.bandeau-accueil h1 { color: #fff; font-size: 1.35rem; margin: 0; }
.bandeau-accueil p { margin: .2rem 0 0; font-size: .88rem; opacity: .95; max-width: 46ch; }
.bandeau-accueil .serie-stats { display: flex; gap: 1.5rem; }
.bandeau-accueil .serie-stats > div { text-align: center; }
.bandeau-accueil .serie-stats .valeur { display: block; font-size: 1.4rem; font-weight: 800; line-height: 1.1; }
.bandeau-accueil .serie-stats .libelle { font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; opacity: .9; }

/* ---------- Messages vides ---------- */
.texte-secondaire { color: var(--texte-doux); }
.vide {
    text-align: center;
    padding: 2.5rem 1rem;
    color: var(--texte-doux);
}
.vide i { font-size: 2.2rem; display: block; margin-bottom: .6rem; opacity: .5; }

/* ============================================================
   LE CHEMIN DES COURS
   Des bulles rondes sur un tracé sinueux, comme Duolingo.
   Sous chaque bulle : un point par leçon, qui verdit quand la
   leçon est faite. C'est le repère de progression voulu.
   ============================================================ */

.bloc-chapitre { margin-bottom: 2.2rem; }

/* Le trait de séparation, avec le titre du chapitre au milieu */
.titre-chapitre {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin: 0 0 1.6rem;
}
.titre-chapitre::before,
.titre-chapitre::after {
    content: '';
    flex: 1;
    height: 2px;
    border-radius: 2px;
    background: var(--bord);
}
.titre-chapitre .etiquette { text-align: center; padding: 0 .3rem; }
.titre-chapitre .numero {
    display: block;
    font-size: .68rem;
    font-weight: 800;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--texte-doux);
}
.titre-chapitre .nom {
    display: block;
    font-size: 1.06rem;
    font-weight: 800;
    color: var(--encre);
    margin-top: .1rem;
}

.chemin { display: flex; flex-direction: column; align-items: center; gap: 1.5rem; }

.etape-lien {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .55rem;
    text-decoration: none;
    transform: translateX(var(--dx, 0px));
    transition: transform .2s ease;
}
.etape-lien:not(.etape-bloquee):hover { transform: translateX(var(--dx, 0px)) translateY(-3px); }

/* La bulle */
.bulle {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 78px;
    height: 78px;
    border-radius: 50%;
    font-size: 1.7rem;
    font-weight: 800;
    color: #fff;
    background: #dbe2ea;
    box-shadow: 0 5px 0 #c4ccd7;
}
.bulle-ouverte,
.bulle-ouvert {
    background: linear-gradient(160deg, var(--vert-clair), var(--vert-fonce));
    box-shadow: 0 5px 0 var(--vert-ombre);
    animation: bulle-respire 2.6s ease-in-out infinite;
}
.bulle-en_cours {
    background: linear-gradient(160deg, #3ec3ff, var(--bleu-fonce));
    box-shadow: 0 5px 0 var(--bleu-ombre);
    animation: bulle-respire-bleue 2.2s ease-in-out infinite;
}
.bulle-termine { background: linear-gradient(160deg, var(--jaune), #f0b400); box-shadow: 0 5px 0 var(--jaune-ombre); color: #fff; }
.bulle-ferme   { background: #e9edf3; box-shadow: 0 5px 0 #d4dae3; color: #6b7787; }

@keyframes bulle-respire {
    0%, 100% { box-shadow: 0 5px 0 var(--vert-ombre), 0 0 0 0 rgba(88, 204, 2, .40); }
    50%      { box-shadow: 0 5px 0 var(--vert-ombre), 0 0 0 14px rgba(88, 204, 2, 0); }
}
@keyframes bulle-respire-bleue {
    0%, 100% { box-shadow: 0 5px 0 var(--bleu-ombre), 0 0 0 0 rgba(28, 176, 246, .40); }
    50%      { box-shadow: 0 5px 0 var(--bleu-ombre), 0 0 0 14px rgba(28, 176, 246, 0); }
}

/* LES POINTS DE PROGRESSION — un par leçon */
.points-lecon {
    display: flex;
    gap: 6px;
    align-items: center;
    justify-content: center;
    min-height: 10px;
}
.points-lecon .point {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #d4dae3;
    transition: background .3s ease, transform .3s ease;
}
.points-lecon .point.fait {
    background: var(--vert);
    transform: scale(1.15);
}
.etape-bloquee .points-lecon .point { background: #e6eaf0; }

/* L'étiquette sous la bulle */
.etiquette-etape {
    max-width: 210px;
    text-align: center;
    font-size: .85rem;
    font-weight: 800;
    color: var(--encre);
    line-height: 1.25;
}
/* Gris lisible : #aab4c2 tenait 2,2:1 sur blanc — illisible sur un
   écran faible luminosité. #6b7787 passe 4,5:1 sans cesser d'être gris. */
.etape-bloquee .etiquette-etape { color: #6b7787; }
.sous-etiquette {
    display: block;
    margin-top: 2px;
    font-size: .72rem;
    font-weight: 600;
    color: var(--texte-doux);
}
.etape-bloquee .sous-etiquette { color: #6b7787; }

@media (max-width: 640px) {
    .bulle { width: 68px; height: 68px; font-size: 1.45rem; }
    .etape-lien { transform: translateX(calc(var(--dx, 0px) * .5)); }
    .etape-lien:not(.etape-bloquee):hover { transform: translateX(calc(var(--dx, 0px) * .5)); }
    .etiquette-etape { max-width: 150px; font-size: .8rem; }
    .points-lecon .point { width: 7px; height: 7px; }
}

/* ============================================================
   PIED DE PAGE
   ============================================================ */
.pied-de-page {
    margin-top: 3rem;
    background: var(--blanc);
    border-top: 2px solid var(--bord);
    padding: 2rem 1rem 1.4rem;
}
.conteneur-pied {
    max-width: var(--largeur);
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr;
    gap: 1.6rem;
    align-items: start;
}
.pied-colonne h3 {
    font-size: .72rem;
    font-weight: 800;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--texte-doux);
    margin: 0 0 .7rem;
}
.pied-marque { font-size: 1.05rem; font-weight: 800; color: var(--encre); }
.pied-marque span { color: var(--vert); }
.pied-presentation { font-size: .84rem; color: var(--texte-doux); margin: .4rem 0 0; max-width: 34ch; line-height: 1.5; }
.pied-liens { list-style: none; margin: 0; padding: 0; }
.pied-liens li { margin-bottom: .45rem; }
.pied-liens a, .pied-colonne a {
    font-size: .86rem;
    font-weight: 600;
    color: var(--texte);
    text-decoration: none;
}
.pied-liens a:hover, .pied-colonne a:hover { color: var(--vert-fonce); }
.pied-bas {
    max-width: var(--largeur);
    margin: 1.6rem auto 0;
    padding-top: 1rem;
    border-top: 1px solid var(--bord-doux);
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    justify-content: space-between;
    align-items: center;
    font-size: .78rem;
    color: var(--texte-doux);
}
.pied-bas .drapeaux { display: flex; gap: .35rem; align-items: center; }

@media (max-width: 720px) {
    .conteneur-pied { grid-template-columns: 1fr; gap: 1.2rem; }
    .pied-bas { flex-direction: column; text-align: center; }
}

/* ============================================================
   CADRE GÉNÉRAL — toutes les pages du site
   Les pages écrites avant la refonte utilisent les classes
   « container » de Bootstrap, qui s'étalent sur toute la largeur
   d'un grand écran. On leur impose la même largeur de lecture
   que le reste du site.
   ============================================================ */
.container,
.container-sm,
.container-md,
.container-lg,
.container-xl,
.container-xxl,
.container-fluid {
    width: 100%;
    max-width: var(--largeur);
    margin-left: auto;
    margin-right: auto;
    padding-left: 1rem;
    padding-right: 1rem;
}

/* Les bandeaux pleine largeur (en-tête, pied) restent intacts */
.app-header .container-fluid,
.app-header .container { max-width: var(--largeur); }

/* Titres de page homogènes */
.page-titre { font-size: 1.5rem; font-weight: 800; color: var(--encre); margin: 0 0 .3rem; }
.page-sous-titre { font-size: .92rem; color: var(--texte-doux); margin: 0 0 1.4rem; }

/* ============================================================
   LES BOUTONS — UN SEUL SYSTÈME POUR TOUT LE SITE
   Calqué sur le bouton « Flashcards » du header (.nav-link-cta de
   theme.css), la référence validée : couleur franche, tranche 3D en
   dessous, LE BOUTON SE LÈVE au survol et s'ENFONCE au clic.

   COMMENT C'EST ORGANISÉ — et pourquoi c'est fait ainsi.
   Les trois états (repos, survol, clic) sont écrits UNE SEULE FOIS, sur
   .btn. Une couleur ne fait que poser des VARIABLES (--fond, --fond-
   survol, --fond-clic, --ombre-couleur) : elle ne réécrit jamais un état.
   Ainsi aucune règle ne peut plus en écraser silencieusement une autre —
   c'est ce qui laissait le vert sombre au survol et rendait le jaune
   illisible (le texte passait en blanc).
   ============================================================ */
.btn {
    --fond:           var(--bleu);
    --fond-survol:    var(--bleu-clair);
    --fond-clic:      var(--bleu-ombre);
    --ombre-couleur:  var(--bleu-ombre);
    --texte-bouton:   var(--blanc);
    --ombre-hauteur:  4px;

    font-family: var(--police-titre);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .5px;
    font-size: .95rem;
    color: var(--texte-bouton);
    background: var(--fond);
    border: none;
    border-radius: var(--r-pilule);
    padding: .78rem 1.55rem;
    box-shadow: 0 var(--ombre-hauteur) 0 var(--ombre-couleur);
    transition: background-color .18s ease, box-shadow .18s ease, transform .12s ease;
}

/* LE SURVOL : le bouton se soulève, son ombre grandit.
   Les « :not(:disabled):not(.disabled) » ne sont pas du décoratif : ils
   donnent à la règle la spécificité nécessaire pour GAGNER contre celle
   de Bootstrap (« :not(.btn-check)+.btn:active », spécificité 3), qui
   ramenait ses couleurs par défaut au clic. */
.btn:hover:not(:disabled):not(.disabled) {
    color: var(--texte-bouton);
    background: var(--fond-survol);
    transform: translateY(-2px);
    box-shadow: 0 calc(var(--ombre-hauteur) + 2px) 0 var(--ombre-couleur);
}

/* LE CLIC : il s'enfonce, l'ombre se réduit. */
.btn:active:not(:disabled):not(.disabled),
.btn.show {
    color: var(--texte-bouton);
    background: var(--fond-clic);
    transform: translateY(1px);
    box-shadow: 0 max(2px, calc(var(--ombre-hauteur) - 2px)) 0 var(--ombre-couleur);
}

.btn:focus-visible {
    outline: 3px solid rgba(28, 176, 246, .35);
    outline-offset: 3px;
}

/* — les couleurs : RIEN d'autre que des variables — */
.btn-primary {
    --fond: var(--bleu); --fond-survol: var(--bleu-clair);
    --fond-clic: var(--bleu-ombre); --ombre-couleur: var(--bleu-ombre);
}
.btn-success {
    --fond: var(--vert); --fond-survol: var(--vert-clair);
    --fond-clic: var(--vert-ombre); --ombre-couleur: var(--vert-ombre);
}
.btn-danger {
    --fond: var(--rouge); --fond-survol: var(--rouge);
    --fond-clic: var(--rouge-ombre); --ombre-couleur: var(--rouge-ombre);
}
.btn-warning,
.btn-duolingo {
    /* Le texte reste SOMBRE sur ce jaune : du blanc y serait illisible. */
    --fond: var(--jaune); --fond-survol: var(--jaune);
    --fond-clic: var(--jaune-ombre); --ombre-couleur: var(--jaune-ombre);
    --texte-bouton: var(--encre);
}
.btn-secondary {
    --fond: var(--blanc); --fond-survol: var(--blanc);
    --fond-clic: var(--bord-doux); --ombre-couleur: var(--bord);
    --texte-bouton: var(--texte);
}
.btn-outline-success {
    --fond: transparent; --fond-survol: var(--vert);
    --fond-clic: var(--vert-ombre); --ombre-couleur: var(--vert-ombre);
    --texte-bouton: var(--vert-fonce);
}
.btn-outline-success:hover,
.btn-outline-success:active { --texte-bouton: var(--blanc); }
.btn-outline-secondary {
    --fond: transparent; --fond-survol: var(--blanc);
    --fond-clic: var(--bord-doux); --ombre-couleur: var(--bord-doux);
    --texte-bouton: var(--texte-doux);
}
.btn-outline-secondary:hover { --texte-bouton: var(--texte); }

/* — les tailles : la même mécanique, à une autre échelle — */
.btn-lg {
    --ombre-hauteur: 6px;
    font-size: 1.06rem;
    padding: .95rem 1.95rem;
}
.btn-sm {
    --ombre-hauteur: 3px;
    font-size: .82rem;
    padding: .45rem 1rem;
}

/* — l'état inactif — */
.btn:disabled,
.btn.disabled {
    --fond: var(--bord-doux); --fond-survol: var(--bord-doux);
    --fond-clic: var(--bord-doux); --ombre-couleur: var(--bord);
    --texte-bouton: var(--texte-doux);
    /* Propriétés réécrites ICI, et pas seulement par variables : la règle
       « .btn:disabled » de Bootstrap a la même spécificité, c'est la
       dernière déclaration qui gagne. */
    background: var(--bord-doux);
    color: var(--texte-doux);
    box-shadow: 0 var(--ombre-hauteur) 0 var(--bord);
    filter: grayscale(1);
    opacity: .8;
    transform: none;
    cursor: not-allowed;
}

/* Cartes Bootstrap */
.card { border: 2px solid var(--bord); border-radius: var(--r); box-shadow: none; }

/* Tableaux : lisibles sur téléphone */
.table-responsive { overflow-x: auto; }
@media (max-width: 640px) {
    .bandeau-accueil { padding: 1.1rem 1.2rem; }
    .bandeau-accueil .serie-stats { gap: 1rem; }
    .entete-section .titre { font-size: 1.2rem; }
}

/* ============================================================
   MENU DÉROULANT DU SITE (remplace l'ancienne version translucide)
   ============================================================ */
.dropdown-menu-site {
    min-width: 250px;
    padding: .45rem;
    margin-top: .5rem !important;
    background: var(--blanc);
    border: 2px solid var(--bord);
    border-radius: var(--r-sm);
    box-shadow: 0 10px 30px rgba(43, 58, 82, .16);
}
.dropdown-menu-site .dropdown-item {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .65rem .8rem;
    border-radius: 10px;
    font-weight: 700;
    font-size: .9rem;
    color: var(--texte);
    white-space: normal;
}
.dropdown-menu-site .dropdown-item:hover,
.dropdown-menu-site .dropdown-item:focus {
    background: #f1f7ff;
    color: var(--bleu-fonce);
}
.dropdown-menu-site .dropdown-item i { font-size: 1.05rem; color: var(--vert); }

/* ============================================================
   BARRE D'ACTION EN BAS DE LA LEÇON
   Pleine largeur, fond opaque, collée au pied de page : plus de
   bande grise visible entre les deux.
   ============================================================ */
.barre-fin {
    position: sticky;
    bottom: 0;
    z-index: 20;
    width: 100%;
    background: var(--blanc);
    border-top: 2px solid var(--bord);
    padding: .85rem 1rem;
    display: flex;
    justify-content: center;
    box-shadow: 0 -6px 18px rgba(43, 58, 82, .06);
}
.pied-de-page { margin-top: 0; }

/* ============================================================
   PAGE DE LEÇON — version « premium »
   Le français en avant ; le portugais accompagne, plus discret.
   `.langue-native` = tout ce qui est en portugais, et que le bouton
   « masquer le portugais » fait disparaître.
   ============================================================ */
.fil-ariane .separateur { margin: 0 .35rem; color: #c3cbd8; }

.entete-lecon {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem 1.5rem;
    align-items: flex-start;
    justify-content: space-between;
    padding-bottom: 1.3rem;
    border-bottom: 2px solid var(--bord);
    margin-bottom: 1.8rem;
}
.entete-lecon .etiquette-rang {
    font-size: .74rem;
    font-weight: 800;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--texte-doux);
}
.entete-lecon .point-sep { margin: 0 .4rem; }
.entete-lecon h1 {
    font-size: 1.85rem;
    font-weight: 800;
    line-height: 1.15;
    margin: .35rem 0 0;
    color: var(--encre);
}
.titre-native {
    font-size: 1rem;
    font-weight: 600;
    color: var(--texte-doux);
    margin: .3rem 0 0;
}

.bouton-bascule-portugais {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem 1.1rem;
    /* Teinté, pas blanc bordé de gris : dans un en-tête blanc, un bouton
       blanc bordé de gris passe pour un élément non stylé. Il suit
       maintenant la langue des pilules — teinte bleue au repos, bleu plein
       quand l'immersion est active. */
    border: 1px solid #d7e8f8;
    border-radius: var(--r-pilule);
    background: #f2f9ff;
    color: #1878b8;
    font-family: inherit;
    font-size: .84rem;
    font-weight: 700;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.bouton-bascule-portugais:hover { background: #e4f3ff; border-color: #b9dcf7; color: #0f5c91; }
.bouton-bascule-portugais[aria-pressed="true"] {
    background: var(--bleu);
    border-color: var(--bleu);
    color: #fff;
}

/* Les points d'une évaluation (« +15 XP »). Cette étiquette portait par
   erreur la classe du portugais : en immersion, elle disparaissait. */
.gain-xp { font-weight: 700; color: var(--bleu); }

/* ---- L'AIDE PORTUGAISE REPLIÉE PAR LE CHAPITRE ------------------------
   Le portugais ajouté par le site (la traduction sous un titre, la colonne
   portugaise du vocabulaire) se retire au fil des chapitres : c'est
   l'immersion progressive. Le serveur pose « pt-cache » sur ce qui doit
   être replié — il ne le SUPPRIME jamais de la page, pour que le bouton
   « Afficher le portugais » puisse le faire revenir. */
.pt-cache { display: none !important; }

/* L'élève a toujours le dernier mot. En rouvrant l'aide, chaque élément
   reprend sa mise en page d'origine : un titre reprend sa ligne, une
   traduction posée sous son original redevient une ligne de texte. */
html.pt-montre-tout .pt-cache { display: revert !important; }
html.pt-montre-tout .detail-lecon.pt-cache,
html.pt-montre-tout .sous-etiquette.pt-cache { display: block !important; }

/* À l'inverse, l'élève qui choisit l'immersion complète masque TOUT le
   portugais ajouté, y compris ce que le chapitre laissait affiché. */
html.pt-masque-tout .langue-native { display: none !important; }

/* Deux colonnes sur grand écran, une seule sur téléphone */
.grille-lecon {
    display: grid;
    /* Une seule colonne : la leçon occupe toute la largeur de lecture.
       La colonne latérale du vocabulaire a été retirée — ces cartes sont
       désormais montrées à l'élève sur la page de fin de leçon. */
    grid-template-columns: minmax(0, 1fr);
    gap: 1.6rem;
    align-items: start;
}
/* La feuille de cours occupe TOUTE la largeur de lecture, exactement comme
   la boîte d'en-tête posée au-dessus d'elle. Elle était bridée à 780 px :
   la boîte de la leçon paraissait donc plus étroite que la boîte du haut,
   avec un grand vide à droite — c'est ce qui donnait l'air « brouillon ». */
.lesson-content-lecon { max-width: 100%; }
@media (max-width: 940px) {
    .grille-lecon { grid-template-columns: 1fr; }
    .entete-lecon h1 { font-size: 1.5rem; }
}

.bloc-lecon {
    background: var(--blanc);
    border: 2px solid var(--bord);
    border-radius: var(--r);
    padding: 1.4rem 1.6rem;
    margin-bottom: 1.4rem;
}
.titre-bloc {
    display: flex;
    align-items: center;
    gap: .55rem;
    font-size: 1.02rem;
    font-weight: 800;
    color: var(--encre);
    margin: 0 0 .9rem;
}
.titre-bloc i { color: var(--bleu); font-size: 1.15rem; }
.aide-bloc { font-size: .82rem; color: var(--texte-doux); line-height: 1.5; margin: 0 0 .9rem; }

.cadre-video { position: relative; padding-bottom: 56.25%; height: 0; border-radius: var(--r-sm); overflow: hidden; }
.cadre-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* Le contenu du manuel, mis en lecture confortable */
.lesson-content-lecon { color: var(--texte); line-height: 1.75; font-size: .96rem; }
.lesson-content-lecon h2,
.lesson-content-lecon h3 { font-size: 1.05rem; color: var(--encre); margin: 1.5rem 0 .6rem; }
.lesson-content-lecon p { margin: 0 0 .9rem; }
.lesson-content-lecon table { width: 100%; border-collapse: collapse; margin: .6rem 0; }
.lesson-content-lecon td { padding: .4rem .5rem; vertical-align: middle; border-bottom: 1px solid var(--bord-doux); }
.lesson-content-lecon audio.audio-lecon { height: 34px; width: 220px; max-width: 100%; margin: 0 .3rem .3rem 0; }

/* Liste de vocabulaire : français en avant, portugais en retrait */
.liste-vocabulaire { list-style: none; margin: 0; padding: 0; }
.liste-vocabulaire .mot {
    padding: .75rem 0;
    border-bottom: 1px solid var(--bord-doux);
}
.liste-vocabulaire .mot:last-child { border-bottom: 0; }
.mot-fr {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: 1rem;
    font-weight: 700;
    color: var(--encre);
}
.mot-pt {
    font-size: .84rem;
    font-weight: 600;
    color: var(--texte-doux);
    padding-left: 2.6rem;
    margin-top: .1rem;
}
.bouton-son {
    flex: 0 0 30px;
    width: 30px; height: 30px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 0; border-radius: 50%;
    background: #eaf7fe; color: var(--bleu-fonce);
    font-size: .82rem; cursor: pointer;
    transition: transform .15s ease, background .15s ease;
}
.bouton-son { border-bottom: 3px solid rgba(0,0,0,.08); }
.bouton-son:hover {
    /* Le meme geste que partout ailleurs : le bouton s'enfonce. */
    transform: translateY(2px);
    border-bottom-width: 1px;
    background: #d5effc;
}
.compte-vocabulaire {
    margin-top: .9rem;
    padding-top: .7rem;
    border-top: 1px solid var(--bord-doux);
    font-size: .76rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--texte-doux);
}
.bloc-lateral-discret .aide-bloc { margin: .6rem 0 0; }
.pastille-faite {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    margin-top: .8rem;
    padding: .3rem .7rem;
    border-radius: var(--r-pilule);
    background: #f0fbe6;
    color: var(--vert-fonce);
    font-size: .78rem;
    font-weight: 800;
}

/* Fenêtre de réussite */
.voile-succes {
    position: fixed; inset: 0; z-index: 2900; display: none;
    align-items: center; justify-content: center; text-align: center;
    background: rgba(247, 249, 252, .82);
    backdrop-filter: blur(6px);
}
.voile-succes.visible { display: flex; }
.boite-succes {
    background: var(--blanc);
    border-radius: 22px;
    padding: 2.2rem 2.5rem;
    box-shadow: 0 22px 60px rgba(43, 58, 82, .20);
    max-width: 440px;
    width: calc(100% - 2rem);
}
.coche-succes {
    width: 74px; height: 74px; margin: 0 auto .9rem;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(160deg, var(--vert-clair), var(--vert-fonce));
    box-shadow: 0 5px 0 var(--vert-ombre);
    color: #fff; font-size: 2.2rem;
}
.boite-succes h1 { font-size: 1.7rem; margin: 0; }
.sous-succes { color: var(--texte-doux); margin: .2rem 0 0; font-size: .92rem; }
.contenu-xp { text-align: left; margin-top: 1.3rem; font-size: .9rem; }
.ligne-xp { display: flex; justify-content: space-between; padding: .35rem 0; border-bottom: 1px solid var(--bord-doux); }
.total-xp {
    margin-top: .7rem; text-align: center;
    font-size: 1.5rem; font-weight: 800; color: var(--vert-fonce);
}

/* ============================================================
   CONVENTION BILINGUE DU SITE
   Le français en libellé principal, le portugais en traduction
   discrète juste en dessous. Appliqué partout : menus, titres,
   boutons, cartes. L'élève brésilien comprend toujours où il va.
   ============================================================ */
.item-fr { display: block; font-weight: 700; }
.item-native {
    display: block;
    font-size: .74rem;
    font-weight: 600;
    font-style: italic;
    color: var(--texte-doux);
    margin-top: 1px;
}
.dropdown-menu-site .dropdown-item.item-admin { color: var(--bleu-fonce); }
.dropdown-menu-site .dropdown-item.item-admin i { color: var(--bleu); }
.dropdown-menu-site .dropdown-item.item-danger { color: var(--rouge); }
.dropdown-menu-site .dropdown-item.item-danger i { color: var(--rouge); }
.dropdown-menu-site .dropdown-divider { margin: .35rem 0; border-color: var(--bord-doux); }

/* Traduction discrète sous un libellé de statistique */
.serie-stats .libelle b {
    display: block;
    font-size: .62rem;
    font-weight: 600;
    font-style: italic;
    opacity: .85;
    text-transform: none;
    letter-spacing: 0;
}
/* Traduction discrète sous un titre de chapitre ou d'étape */
.nom-native,
.sous-etiquette b {
    display: block;
    font-size: .72rem;
    font-weight: 600;
    font-style: italic;
    color: var(--texte-doux);
    text-transform: none;
    letter-spacing: 0;
}
.nom-native { margin-top: 1px; font-size: .8rem; }

/* ============================================================
   PAGE D'UNE SÉANCE (étape)
   ============================================================ */
.entete-etape {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem 1.5rem;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: 1.1rem;
}
.entete-etape h1 { font-size: 1.6rem; font-weight: 800; margin: .3rem 0 0; color: var(--encre); }
.entete-etape .etiquette-rang {
    font-size: .74rem; font-weight: 800; letter-spacing: .12em;
    text-transform: uppercase; color: var(--texte-doux);
}
.compteur-etape { text-align: right; flex-shrink: 0; }
.compteur-etape .valeur { display: block; font-size: 1.8rem; font-weight: 800; color: var(--vert-fonce); line-height: 1; }
.compteur-etape .libelle {
    display: block; font-size: .68rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .08em; color: var(--texte-doux); margin-top: .2rem;
}
.compteur-etape .libelle b {
    display: block; font-size: .62rem; font-weight: 600; font-style: italic;
    text-transform: none; letter-spacing: 0; opacity: .85;
}

.liste-lecons { display: flex; flex-direction: column; gap: .7rem; }
.carte-lecon {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1rem 1.15rem;
    border-radius: var(--r-sm);
    background: var(--blanc);
    border: 2px solid var(--bord);
    text-decoration: none;
    color: inherit;
    transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.carte-lecon:hover { border-color: var(--bleu); transform: translateX(4px); }
.carte-lecon.termine { border-color: #cfeeb8; background: #fbfff7; }
.carte-lecon.en_cours { border-color: var(--bleu); box-shadow: 0 3px 0 rgba(28,176,246,.14); }

.puce {
    flex: 0 0 40px;
    width: 40px; height: 40px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-weight: 800; font-size: .95rem;
    background: #eef2f7; color: #7c8798;
}
.puce.termine { background: var(--vert); color: #fff; }
.puce.en_cours { background: var(--bleu); color: #fff; }
.corps-lecon { flex: 1; min-width: 0; }
.titre-lecon { display: block; font-weight: 700; color: var(--encre); font-size: 1rem; }
.detail-lecon { display: block; font-size: .8rem; color: var(--texte-doux); margin-top: 2px; }
.marque-media {
    flex: 0 0 30px; width: 30px; height: 30px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%; background: #eaf7fe; color: var(--bleu-fonce); font-size: .8rem;
}

/* Accueil : pastille du nombre de leçons dans une carte de chapitre */
.badge-chapitre {
    display: inline-block;
    align-self: center;
    padding: .25rem .7rem;
    border-radius: var(--r-pilule);
    background: #eaf7fe;
    color: var(--bleu-fonce);
    font-size: .74rem;
    font-weight: 800;
}

/* ============================================================
   BOUTON « J'AI TERMINÉ CETTE LEÇON »
   Rétabli le 09/10/2026 : le style vivait dans un bloc <style> propre
   à la page ; en réécrivant la leçon, je l'ai supprimé sans le déplacer
   ici. Le bouton avait perdu son vert.
   ============================================================ */
.bouton-terminer {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .55rem;
    padding: .85rem 2.2rem;
    border: 0;
    border-radius: var(--r-pilule);
    background: linear-gradient(160deg, var(--vert-clair), var(--vert-fonce));
    box-shadow: 0 4px 0 var(--vert-ombre);
    color: #fff;
    font-family: inherit;
    font-size: 1rem;
    font-weight: 800;
    letter-spacing: .01em;
    cursor: pointer;
    text-decoration: none;
    transition: transform .12s ease, box-shadow .12s ease, filter .15s ease;
}
.bouton-terminer:hover { filter: brightness(1.06); color: #fff; }
.bouton-terminer:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--vert-ombre); }
.bouton-terminer:disabled {
    background: #cfd6e0;
    box-shadow: 0 4px 0 #b3bcc9;
    cursor: default;
    transform: none;
    filter: none;
}

/* ============================================================
   RENVOIS DE LEÇON — la bulle d'explication
   Un renvoi « [1] » dans le texte devient une pastille. Au survol
   (ordinateur) ou au toucher (téléphone), l'explication s'affiche
   dans une bulle, sur place : plus besoin de descendre en bas de page.
   ============================================================ */
.note-renvoi {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: super;
    margin: 0 .15rem;
    cursor: pointer;
}
/* ⚠️ POURQUOI DEUX SÉLECTEURS À CHAQUE FOIS
   Dans le corps de la leçon, le bloc « aucun élément du contenu ne pose de
   fond opaque » écrit `.lesson-content-lecon div`, `.lesson-content-lecon
   span`, `.lesson-content-lecon p`… : une CLASSE + une BALISE, donc une
   spécificité (0,1,1) SUPÉRIEURE à celle d'une simple classe (0,1,0).
   Il remettait donc à transparent le fond de la pastille de renvoi, de son
   infobulle, des encadrés d'action et de leur étiquette — tout ce qui est
   décoratif, par opposition au TEXTE du cours. La forme préfixée
   (`.lesson-content-lecon .invitation-activite`, (0,2,0)) reprend le
   dessus. Toute nouvelle décoration posée dans la leçon doit faire pareil. */
.note-marque,
.lesson-content-lecon .note-marque {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 17px;
    height: 17px;
    border-radius: 50%;
    background-color: var(--bleu);
    color: #fff;
    font-size: .62rem;
    font-weight: 800;
    line-height: 1;
    /* Un liseré blanc : sans lui, la pastille bleue se noie dans les
       carreaux bleus du papier. */
    box-shadow: 0 0 0 2px #fff;
    transition: transform .15s ease, background .15s ease;
}
.note-renvoi:hover .note-marque,
.note-renvoi.ouverte .note-marque {
    background: var(--bleu-fonce);
    transform: scale(1.18);
}

.note-bulle,
.lesson-content-lecon .note-bulle {
    position: absolute;
    bottom: calc(100% + 10px);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    width: max-content;
    max-width: 290px;
    padding: .6rem .8rem;
    border-radius: 14px;
    /* Opaque : une bulle d'explication se lit par-dessus la page, elle ne
       doit pas laisser deviner les carreaux au travers. */
    background-color: #fff;
    border: 2px solid #dbe9f8;
    box-shadow: 0 8px 26px rgba(43, 58, 82, .18);
    color: var(--texte);
    font-size: .82rem;
    font-weight: 500;
    font-style: normal;
    line-height: 1.45;
    text-align: left;
    opacity: 0;
    visibility: hidden;
    transition: opacity .16s ease, transform .16s ease, visibility .16s;
    z-index: 60;
    pointer-events: none;
}
/* La petite pointe de la bulle, vers la pastille */
.note-bulle::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    margin-left: -7px;
    border: 7px solid transparent;
    border-top-color: var(--blanc);
    filter: drop-shadow(0 2px 1px rgba(43, 58, 82, .08));
}
.note-renvoi:hover .note-bulle,
.note-renvoi.ouverte .note-bulle {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) translateY(0);
}
/* Sur téléphone, la bulle reste dans l'écran */
@media (max-width: 640px) {
    .note-bulle { max-width: min(270px, 78vw); font-size: .8rem; }
}

/* ============================================================
   FIN DE LEÇON — le moment où l'élève voit ce qu'il a appris
   ============================================================ */
body.page-fin-lecon { min-height: 70vh; }
.centre-fin {
    display: flex;
    flex-direction: column;      /* la carte, PUIS le bouton — jamais côte à côte */
    align-items: center;
    justify-content: center;
    gap: 1rem;
    min-height: 62vh;
    padding: 1rem;
}

/* Barre de progression, en haut */
.barre-progression-fin {
    position: sticky;
    top: 78px;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: .9rem;
    max-width: var(--largeur);
    margin: 0 auto;
    padding: .8rem 1rem;
    /* PAS DE FOND : la barre flottait sur un bandeau blanc qui coupait le
       dégradé de la page. Décision de Jérémy : elle se pose sur le fond. */
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
.jauge-fin {
    flex: 1;
    height: 14px;
    border-radius: var(--r-pilule);
    background: var(--bord-doux);
    overflow: hidden;
}
.jauge-fin > span {
    display: block;
    height: 100%;
    width: 0;
    border-radius: var(--r-pilule);
    background: linear-gradient(90deg, var(--vert-clair), var(--vert));
    transition: width .45s cubic-bezier(.4, 0, .2, 1);
}
.compteur-fin {
    font-size: .82rem;
    font-weight: 800;
    color: var(--texte-doux);
    white-space: nowrap;
}

/* Les écrans de la page */
.intro-fin, .etape-fin { text-align: center; max-width: 520px; }
.intro-fin h1, .etape-fin h1 { font-size: 1.9rem; margin: .6rem 0 .3rem; }

/* LE TEXTE BLEU, PUIS LE BOUTON — l'un SOUS l'autre.
   `.pastille-compte` est en `inline-flex` et le bouton est un `<button>`
   (donc en ligne lui aussi) : les deux se posaient côte à côte, et
   « Continuar » se retrouvait à droite de « 6 cartões… ». */
.intro-fin .pastille-compte,
.etape-fin .pastille-compte {
    display: flex;
    width: fit-content;
    margin: 0 auto 1rem;
}
.intro-fin .bouton-large,
.etape-fin .bouton-large {
    display: block;
    margin-left: auto;
    margin-right: auto;
}
.sous-titre-fin { color: var(--texte-doux); font-size: 1rem; margin: 0 0 1.2rem; }
.bouton-large { padding: 1rem 2.6rem; font-size: 1.05rem; margin-top: .6rem; }
.pastille-compte {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .5rem 1rem;
    border-radius: var(--r-pilule);
    background: #eaf7fe;
    color: var(--bleu-fonce);
    font-size: .86rem;
    font-weight: 700;
    margin-bottom: 1rem;
}
.gain-xp {
    font-size: 2.4rem;
    font-weight: 800;
    color: var(--vert-fonce);
    margin: .4rem 0 1rem;
}

/* ------------------------------------------------------------
   LA CARTE REPREND LE DESSIN DE LA PAGE FLASHCARDS.

   Trois défauts vus à l'écran par Jérémy :
     1. la carte était une petite boîte de 430 × 290 px ;
     2. le bouton d'écoute sortait en OVALE — `.bouton-son` porte
        `flex: 0 0 30px`, donc sa HAUTEUR était forcée à 31 px alors que la
        variante « grand » lui donnait 44 px de large ;
     3. le bouton « J'ai appris » se posait À CÔTÉ de la carte : `.centre-fin`
        était une rangée (flex-direction: row par défaut).
   On reprend donc les mesures de la révision des cartes
   (references/decisions-29-10-2026.md, §3) : la page prend l'écran, la
   carte prend la hauteur qui reste, le texte suit la taille de la carte et
   la SEULE commande est posée dessous, sur toute la largeur. */

body.page-fin-lecon {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
}
body.page-fin-lecon .app-header { flex: 0 0 auto; }
/* Activité plein écran : le pied de page poussait la carte sous l'écran. */
body.page-fin-lecon .pied-de-page { display: none; }
body.page-fin-lecon main {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

#page-fin.page-fin-lecon {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}
#page-fin .centre-fin {
    flex: 1 1 auto;
    min-height: 0;
    justify-content: center;
    padding: 0 1rem 1rem;
}
/* La barre ne « colle » plus : la page ne défile plus. */
#page-fin .barre-progression-fin {
    position: relative;
    top: auto;
    flex: 0 0 auto;
    width: 100%;
}

/* --- La carte --- */
.scene-carte {
    perspective: 1500px;
    width: min(100%, 860px);
    flex: 1 1 auto;
    min-height: 220px;
    display: flex;
    align-items: stretch;
    justify-content: center;
}
.carte-apprendre {
    position: relative;
    /* La hauteur vient de la scène par étirement (`align-self: stretch`) :
       un `height: 100%` ici se résolvait à 0 px, et la carte disparaissait. */
    height: auto;
    flex: 1 1 auto;
    align-self: stretch;
    min-height: 0;
    cursor: pointer;
    transform-style: preserve-3d;
    transition: transform .5s cubic-bezier(.2, .8, .2, 1);
}
.carte-apprendre.retournee { transform: rotateY(180deg); }
.carte-face {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .9rem;
    padding: 2rem 2.2rem 1.6rem;
    border-radius: 1.5rem;
    background: #fff;
    border: 2px solid var(--duo-grey, var(--bord));
    border-bottom-width: 8px;      /* la même tranche que la révision */
    box-shadow: 0 22px 50px -30px rgba(43, 58, 82, .55);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}
.carte-avant { border-color: var(--duo-grey, var(--bord)); }
.carte-arriere {
    background: #f8f9fa;
    transform: rotateY(180deg);
}
.carte-etiquette {
    font-size: .72rem;
    font-weight: 800;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--texte-doux);
    position: absolute;
    top: 1rem;
    left: 1.3rem;
}
/* La taille en pixels est posée par ajusterTexte() dans fin-lecon.js :
   elle suit la carte, en largeur ET en hauteur. Ces valeurs ne servent
   qu'avant la mesure. */
.carte-mot {
    font-size: 2.4rem;
    font-weight: 800;
    color: var(--encre);
    text-align: center;
    line-height: 1.25;
    width: 100%;
    overflow-wrap: break-word;
}
.carte-mot-pt { color: var(--vert-fonce); }
.carte-invite { font-size: .82rem; color: var(--texte-doux); font-style: italic; }
.carte-apprise {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-size: .8rem;
    font-weight: 800;
    color: var(--vert-fonce);
    background: rgba(255,255,255,.8);
    padding: .3rem .8rem;
    border-radius: var(--r-pilule);
}

/* LE BOUTON D'ÉCOUTE — un rond, en haut à droite, comme sur la révision.
   `flex: 0 0 auto` annule le `flex-basis: 30px` qui écrasait la hauteur ;
   `aspect-ratio` garantit le cercle même si une règle change la largeur. */
.bouton-son-grand {
    position: absolute;
    top: 1rem;
    right: 1rem;
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    aspect-ratio: 1 / 1;
    font-size: 1.4rem;
    border-bottom-width: 4px;
    box-shadow: 0 2px 6px rgba(43, 58, 82, .12);
}

/* LA SEULE COMMANDE, SOUS LA CARTE, PLEINE LARGEUR.
   Sa zone réserve sa hauteur dès le départ : l'arrivée du bouton ne fait
   donc pas sauter la carte. Elle apparaît en fondu, après le retournement,
   le temps de lire la traduction. */
.zone-appris {
    flex: 0 0 auto;
    width: min(100%, 860px);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 4.6rem;
}
.zone-appris #btn-appris {
    width: 100%;
    opacity: 0;
    transform: translateY(10px);
    animation: apparition-appris .3s ease forwards;
}
/* Le bouton attend, invisible, AVANT le retournement : sa place reste
   prise, donc la carte ne rétrécit pas quand il apparaît. */
.zone-appris #btn-appris.est-attente {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    animation: none;
    transform: none;
}
@keyframes apparition-appris {
    to { opacity: 1; transform: translateY(0); }
}

/* Écran bas (portable 13 pouces, téléphone couché) : la carte se contente
   de la place qui reste, sans jamais disparaître. */
@media (max-height: 640px) {
    #page-fin .centre-fin { padding: 0 .6rem .6rem; }
    .scene-carte { min-height: 170px; }
    .zone-appris { min-height: 4rem; }
}

/* La copie qui s'envole vers l'en-tête */
.carte-en-vol {
    border-radius: 22px !important;
    background: var(--blanc) !important;
    border: 3px solid var(--vert) !important;
    box-shadow: 0 10px 30px rgba(43, 58, 82, .3) !important;
    overflow: hidden;
}

/* Le bouton de l'en-tête qui accuse réception */
.cible-touchee { animation: cible-recoit .7s ease; }
@keyframes cible-recoit {
    0%   { transform: scale(1); }
    35%  { transform: scale(1.22); }
    100% { transform: scale(1); }
}


/* ============================================================
   SUIVI EN DIRECT — calque, barre d'outils, fenêtre de saisie
   Écrit d'un seul tenant le 09/10/2026 : les versions précédentes
   s'empilaient et se contredisaient, ce qui sortait la barre de l'écran.
   ============================================================ */

/* ---------- Le calque d'annotations ---------- */
.calque-live {
    position: absolute;
    left: 0; top: 0;
    pointer-events: none;   /* laisse passer tous les clics de la page */
    /* SOUS l'en-tête (1071) : sans cela les annotations passaient
       par-dessus la barre du site au défilement, et l'on voyait bien
       qu'elles étaient posées sur un calque. */
    z-index: 900;
}
.calque-toile {
    position: absolute;
    left: 0; top: 0;
    pointer-events: none;
}

/* ---------- Une note : bulle colorée, déplaçable, supprimable ---------- */
.calque-note {
    position: absolute;
    transform: translate(-50%, -50%);
    pointer-events: auto;
    display: inline-block;
    max-width: 290px;
    min-width: 70px;
    padding: .5rem .8rem .5rem .75rem;
    /* UNE VRAIE PETITE BULLE : fond blanc, coins doux, ombre portée
       légère, et un trait de couleur sur le bord gauche qui suit l'arrondi.
       Elle se pose par-dessus n'importe quel texte sans le rendre illisible. */
    background: #fff;
    /* LE TRAIT DE COULEUR EST LA BORDURE GAUCHE ELLE-MEME.
       C'est la seule façon qu'il épouse parfaitement l'arrondi : posé en
       pseudo-élément, il gardait des extrémités carrées qui débordaient.
       Le navigateur, lui, arrondit les bordures avec la forme. */
    border: 1px solid #e8eef6;
    border-left: 5px solid var(--c-note, #1cb0f6);
    border-radius: 14px;
    color: #22304a;
    font-family: 'Lato', system-ui, sans-serif;
    font-size: .82rem;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: .1px;
    text-align: left;
    cursor: grab;
    /* Ombre plus discrète : elle était trop large et trop marquée. */
    box-shadow:
        0 1px 2px rgba(34,48,74,.05),
        0 5px 14px rgba(34,48,74,.09);
    user-select: none;
    white-space: pre-wrap;
    word-break: break-word;
    transition: box-shadow .16s ease, transform .12s ease;
}
.calque-note:hover {
    box-shadow:
        0 2px 5px rgba(34,48,74,.07),
        0 8px 20px rgba(34,48,74,.13);
}
.calque-note:active { cursor: grabbing; transform: translate(-50%, -50%) scale(.985); }
/* Le trait de couleur est désormais la BORDURE GAUCHE de la bulle :
   plus besoin de pseudo-élément, et l'arrondi est parfait. */
.calque-note.note-prof { --c-note: #e94560; }
.calque-note.note-eleve { --c-note: #1cb0f6; font-style: normal; }
.calque-note:active { cursor: grabbing; }
.calque-note-texte {
    display: block;
    padding-right: 1rem;
    word-break: break-word;
    outline: none;
}
.calque-note.note-eleve { font-style: italic; }
.calque-note-suppr {
    position: absolute; top: -8px; right: -8px;
    width: 19px; height: 19px; border-radius: 50%;
    border: 2px solid #fff; background: #22304a; color: #fff;
    font-size: 12px; line-height: 1; font-weight: 700;
    display: none; align-items: center; justify-content: center;
    cursor: pointer; padding: 0;
}
.calque-note:hover .calque-note-suppr { display: flex; }

/* ---------- Le repère temporaire du professeur ---------- */
.calque-pointeur {
    position: absolute;
    width: 46px; height: 46px;
    margin: -23px 0 0 -23px;
    border: 4px solid #e94560;
    border-radius: 50%;
    pointer-events: none;
    animation: pointeur-pulse 1.1s ease-out infinite;
}
@keyframes pointeur-pulse {
    0%   { transform: scale(.45); opacity: 1; }
    100% { transform: scale(1.5);  opacity: 0; }
}

/* ---------- La barre d'outils ----------
   VERTICALE et collée à gauche, chez le professeur COMME chez l'élève.
   Le fond est blanc, les boutons sont de petites pastilles rondes : c'est
   la présentation que Monsieur préfère. */
.boite-live {
    position: fixed;
    z-index: 3100;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .3rem;
    padding: .5rem .45rem;
    background: rgba(255,255,255,.97);
    border: 2px solid #e7ecf3;
    border-radius: 22px;
    box-shadow: 0 10px 30px rgba(43,58,82,.18);
    top: 66px;
    left: .7rem;
    max-height: calc(100vh - 96px);
    overflow-y: auto;
    overflow-x: hidden;
}
/* Chez l'élève, la barre descend un peu pour ne pas gêner le bandeau. */
body:not(.prof-live) .boite-live { top: 76px; }
.boite-groupe, .boite-couleurs, .boite-filtres {
    display: flex; flex-direction: column; align-items: center; gap: .3rem;
}
.boite-poignee {
    /* SIX POINTS, deux rangees de trois : l'icone du glisser-deposer.
       Dessines un par un (voir suivi-live.js) — nets, quelle que soit
       la taille, et sans trame CSS qui puisse etre ecrasee. */
    display: grid;
    grid-template-columns: repeat(3, 4px);
    grid-template-rows: repeat(2, 4px);
    gap: 2px;
    place-content: center;
    width: 24px; height: 16px; flex-shrink: 0;
    border-radius: 4px;
    cursor: grab; margin-bottom: .3rem;
    opacity: .9;
    transition: opacity .15s ease;
}
.poignee-point {
    width: 4px; height: 4px;
    border-radius: 50%;
    background: rgba(255,255,255,.55);
}
.boite-poignee:hover { opacity: 1; }
/* Chez l'élève, points plus foncés pour ressortir sur le fond clair. */
body:not(.prof-live) .poignee-point { background: #8a9bb2; }
body:not(.prof-live) .boite-poignee:hover .poignee-point { background: #5a6b80; }
.boite-poignee:active { cursor: grabbing; }
.boite-btn {
    width: 38px; height: 38px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border: 0; border-radius: 13px; background: #f2f5f9;
    color: #2b3a52; font-size: 1.05rem; cursor: pointer;
    transition: background .15s, color .15s, transform .1s;
}
.boite-btn:hover { background: #e3eaf3; }
.boite-btn.boite-actif { background: #1cb0f6; color: #fff; box-shadow: 0 4px 12px rgba(28,176,246,.35); }
.boite-btn:active { transform: scale(.92); }
.boite-danger:hover { background: #ffe3e3; color: #e03e3e; }
/* Les outils réservés au professeur : légèrement teintés */
.boite-btn.boite-pref { background: #eef4ff; color: #3a6ea5; }
.boite-btn.boite-pref:hover { background: #e0ebff; }
.boite-couleur {
    width: 24px; height: 24px; flex-shrink: 0;
    border-radius: 50%; border: 2px solid #fff;
    box-shadow: 0 0 0 1.5px rgba(43,58,82,.18);
    cursor: pointer; padding: 0; transition: transform .12s;
}
/* LE SURVOL ENFONCE LE BOUTON, COMME DUOLINGO.
   Pas de grossissement : le bouton S'ABAISSE de 2 px, et son relief du
   bas se reduit — exactement le geste des boutons du site. */
.boite-couleur:hover {
    transform: translateY(2px);
    box-shadow: inset 0 -1px 0 rgba(0,0,0,.12);
}
.boite-btn {
    /* Le relief qui donne le « clic » duolingo. */
    border-bottom: 3px solid rgba(0,0,0,.10);
    transition: background .15s, color .15s, transform .1s, border-bottom-width .1s;
}
.boite-btn:hover {
    transform: translateY(2px);
    border-bottom-width: 1px;
}
.boite-btn:active {
    transform: translateY(3px);
    border-bottom-width: 0;
}
.boite-couleur.boite-actif { box-shadow: 0 0 0 3px #2b3a52; }
.boite-sep { width: 24px; height: 1.5px; background: #e7ecf3; margin: .22rem 0; flex-shrink: 0; }
.boite-filtre {
    border: 0; border-radius: 999px; background: #f2f5f9; color: #5c6b82;
    font-family: inherit; font-size: .64rem; font-weight: 800;
    padding: .28rem .5rem; cursor: pointer; white-space: nowrap;
    width: 100%; text-align: center;
}
.boite-filtre.boite-actif { background: #2b3a52; color: #fff; }
body.outil-actif { cursor: crosshair; }
body.outil-actif a, body.outil-actif button { cursor: crosshair; }
/* Sur écran étroit, la barre se resserre */
@media (max-width: 620px) {
    .boite-live { top: auto; bottom: .6rem; max-height: 46vh; }
    .boite-btn { width: 34px; height: 34px; font-size: .95rem; }
}

/* ---------- La fenêtre de saisie d'une note ---------- */
/* ⚠️ L'ATTRITBUT hidden DOIT GAGNER SUR display: flex.
   Sans cette regle, la modale masquee restait « affichee » en flex :
   elle recouvrait TOUTE la page, invisible, et interceptait CHAQUE clic.
   C'est la cause des boutons inertes. */
.live-modale-fond[hidden] { display: none !important; }

.live-modale-fond {
    position: fixed; inset: 0; z-index: 4000;
    background: rgba(43,58,82,.45);
    backdrop-filter: blur(3px);
    display: flex; align-items: center; justify-content: center;
    padding: 1rem;
}
.live-modale {
    width: 100%; max-width: 380px;
    background: #fff; border-radius: 20px;
    padding: 1.1rem 1.1rem 1rem;
    box-shadow: 0 24px 60px rgba(43,58,82,.3);
    font-family: 'Lato', system-ui, sans-serif;
    animation: modale-entree .18s ease-out;
}
@keyframes modale-entree {
    from { transform: translateY(10px) scale(.97); opacity: 0; }
    to   { transform: none; opacity: 1; }
}
.live-modale-titre {
    font-family: 'Poppins', system-ui, sans-serif;
    font-size: 1rem; font-weight: 800; color: #2b3a52;
    margin: 0 0 .6rem;
}
.live-modale-champ {
    width: 100%; border: 2px solid #e7ecf3; border-radius: 12px;
    padding: .6rem .75rem; font-family: inherit; font-size: .92rem;
    color: #2b3a52; resize: vertical; outline: none;
}
.live-modale-champ:focus { border-color: #1cb0f6; }
.live-modale-pied { display: flex; gap: .5rem; justify-content: flex-end; margin-top: .8rem; }
.live-modale-ok, .live-modale-non {
    border: 0; border-radius: 999px; padding: .5rem 1rem;
    font-family: inherit; font-size: .82rem; font-weight: 800; cursor: pointer;
}
.live-modale-ok { background: #1cb0f6; color: #fff; }
.live-modale-ok:hover { background: #0f9fe0; }
.live-modale-non { background: #f2f5f9; color: #5c6b82; }
.live-modale-non:hover { background: #e7ecf3; }

/* ---------- Le bouton d'arrêt, dans le témoin de l'élève ---------- */
.temoin-fin {
    display: none;
    border: 0; border-radius: 999px;
    background: #fff; color: #e03e3e;
    font-family: inherit; font-size: .68rem; font-weight: 800;
    padding: .22rem .6rem; margin-left: .45rem;
    cursor: pointer; white-space: nowrap;
}
.temoin-live.ouvert .temoin-fin { display: inline-block; }

/* ---------- La fenêtre de demande d'accord ---------- */
.live-modale-demande { max-width: 420px; }
.live-modale-texte {
    font-size: .92rem; color: #2b3a52; line-height: 1.45; margin: 0 0 .5rem;
}
.live-modale-aide {
    font-size: .78rem; color: #5c6b82; line-height: 1.45;
    background: #f6f8fb; border-radius: 10px; padding: .55rem .7rem; margin: 0;
}
.live-modale-demande .live-modale-pied { justify-content: stretch; gap: .6rem; margin-top: 1rem; }
.live-modale-demande .live-modale-ok,
.live-modale-demande .live-modale-non { flex: 1; padding: .62rem 1rem; font-size: .86rem; }

/* Quand le suivi est actif, la page de l'élève respire un peu : le
   témoin et la barre ne doivent jamais recouvrir le bouton de validation. */
body.suivi-actif .boite-live { top: 76px; }

/* ============================================================
   LE TÉMOIN DU SUIVI, CHEZ L'ÉLÈVE
   RÉÉCRIT EN ENTIER le 09/10/2026 : ces règles avaient disparu lors de
   la réécriture du bloc précédent. Le témoin s'affichait donc sans forme
   — un simple texte perdu en bas de page — et l'élève croyait qu'il n'y
   avait rien. Ne jamais retirer ce bloc.
   ============================================================ */

/* Au repos : un point rouge seul, sans fond, discret. */
.temoin-live {
    position: fixed !important;
    top: 88px !important;
    right: 1rem !important;
    left: auto !important;
    bottom: auto !important;
    display: inline-flex !important;
    flex-direction: row !important;
    align-items: center !important;
    gap: 0 !important;
    width: auto !important;
    height: auto !important;
    padding: 7px !important;
    margin: 0 !important;
    border: 0 !important;
    border-radius: 999px !important;
    background: transparent !important;
    box-shadow: none !important;
    z-index: 3000 !important;
    cursor: pointer;
    font-family: 'Lato', system-ui, sans-serif;
}

.temoin-live .temoin-point {
    position: relative;
    display: inline-block;
    width: 15px;
    height: 15px;
    flex-shrink: 0;
}
.temoin-live .temoin-point::after {
    content: '';
    display: block;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: #ff4b4b;
    box-shadow: 0 2px 8px rgba(255,75,75,.5);
    animation: temoin-respire 2.4s ease-in-out infinite;
}
.temoin-live .temoin-halo {
    position: absolute;
    left: 0; top: 0;
    width: 15px; height: 15px;
    border-radius: 50%;
    background: #ff4b4b;
    animation: temoin-halo 2s ease-out infinite;
}
@keyframes temoin-halo {
    0%   { transform: scale(1);   opacity: .55; }
    100% { transform: scale(2.6); opacity: 0; }
}
@keyframes temoin-respire {
    0%, 100% { opacity: 1; }
    50%      { opacity: .65; }
}

/* Le texte : masqué au repos, il ne prend aucune place. */
.temoin-live .temoin-texte {
    display: inline-block;
    max-width: 0;
    opacity: 0;
    overflow: hidden;
    white-space: nowrap;
    font-size: .78rem;
    font-weight: 700;
    color: #fff;
    transition: max-width .32s ease, opacity .2s ease, padding .32s ease;
}

/* Ouvert : la bulle apparaît à côté du point, sur une seule ligne. */
.temoin-live.ouvert {
    background: rgba(43,58,82,.96) !important;
    padding: 7px 15px 7px 11px !important;
    box-shadow: 0 8px 24px rgba(43,58,82,.3) !important;
}
.temoin-live.ouvert .temoin-texte {
    max-width: 330px;
    opacity: 1;
    padding-left: .55rem;
}

/* Une note du professeur se distingue de celle de l'élève au premier
   regard : un liseré clair sur le bord gauche. L'élève garde une police
   et une couleur uniques, ce qui lui permet de retrouver ses propres
   annotations des mois plus tard. */
.calque-note.note-prof {
    border-left: 4px solid rgba(255,255,255,.85);
    font-style: normal;
}
.calque-note.note-eleve { cursor: grab; }

/* ---------- Les repères de bord ----------
   Quand un point d'intérêt sort du champ de vision, on l'annonce sur le
   bord de l'écran, dans sa direction — comme sur une carte. Rien ne
   défile tout seul : c'est un simple repère. */
.repere-bord {
    position: fixed;
    z-index: 3050;
    display: none;
    align-items: center;
    gap: .4rem;
    transform: translate(-50%, -50%);
    padding: .3rem .6rem;
    border-radius: 999px;
    background: #ff4b4b;
    color: #fff;
    font-family: 'Lato', system-ui, sans-serif;
    font-size: .72rem;
    font-weight: 800;
    white-space: nowrap;
    box-shadow: 0 6px 18px rgba(255,75,75,.45);
    animation: repere-pulse 1.6s ease-in-out infinite;
    pointer-events: none;
}
.repere-bord i { font-size: .85rem; }
/* LE REPÈRE GLISSE, IL NE SAUTE PAS.
   La durée colle au rythme du suivi vif (150 ms) : plus longue, le repère
   resterait deux relevés en arrière — il traînait derrière le curseur. */
.repere-bord { transition: left .12s linear, top .12s linear; }
@keyframes repere-pulse {
    0%, 100% { transform: translate(-50%, -50%) scale(1); }
    50%      { transform: translate(-50%, -50%) scale(1.08); }
}

/* ---------- Le curseur de l'élève, vu par le professeur ---------- */
.curseur-eleve {
    position: fixed;
    z-index: 3060;
    display: none;
    pointer-events: none;
    color: #ff4b4b;
    font-size: 20px;
    line-height: 1;
    filter: drop-shadow(0 2px 4px rgba(0,0,0,.35));
    /* Le curseur GLISSE entre deux relevés, au lieu de sauter : la durée
       colle au rythme de suivi vif (150 ms). */
    transition: left .12s linear, top .12s linear;
}

/* LE CLIC DE L'ÉLÈVE — une pulsation du curseur rouge et une onde qui
   s'échappe. Assez pour être vu du coin de l'œil, sans distraire de ce
   que le professeur explique. */
.curseur-eleve.clic i {
    animation: curseur-clic .45s cubic-bezier(.3, .7, .4, 1.4);
}

.curseur-eleve.clic::after {
    content: '';
    position: absolute;
    left: 6px;
    top: 6px;
    width: 14px;
    height: 14px;
    margin: -7px 0 0 -7px;
    border-radius: 50%;
    border: 2px solid #ff4b4b;
    animation: curseur-onde .5s ease-out forwards;
}

@keyframes curseur-clic {
    0%   { transform: scale(1); }
    35%  { transform: scale(.78); }
    100% { transform: scale(1); }
}

@keyframes curseur-onde {
    from { transform: scale(.4); opacity: .95; }
    to   { transform: scale(3.2); opacity: 0; }
}

/* La confirmation d'effacement : plus rouge, pour marquer le coup. */
.live-modale-danger { background: #ff4b4b; }
.live-modale-danger:hover { background: #e03e3e; }
.live-modale-confirme { max-width: 400px; }

/* ---------- Une note en cours d'écriture ---------- */
.calque-note.note-en-ecriture {
    min-width: 110px;
    box-shadow: 0 0 0 3px rgba(28,176,246,.45), 0 8px 22px rgba(0,0,0,.25);
}
.calque-note.note-en-ecriture .calque-note-texte {
    outline: none;
    cursor: text;
}
/* Une note modifiable : le curseur devient un trait d'écriture */
.calque-note .calque-note-texte[contenteditable="true"] {
    cursor: text;
    outline: none;
}

/* ---------- La croix de suppression, posée par le professeur ----------
   Les notes vivant dans la page de l'élève, elles ne peuvent pas etre
   survolees depuis le miroir : la croix est donc posee dans SA page, au
   coin de la note reperee. */
.croix-note {
    position: fixed;
    z-index: 3400;
    width: 22px; height: 22px;
    display: flex; align-items: center; justify-content: center;
    border: 2px solid #fff; border-radius: 50%;
    background: #2b3a52; color: #fff;
    font-size: 14px; line-height: 1; font-weight: 700;
    cursor: pointer; padding: 0;
    box-shadow: 0 3px 10px rgba(0,0,0,.3);
}
.croix-note:hover { background: #ff4b4b; }
/* La note survolee se signale, meme sans recevoir la souris elle-meme. */
.calque-note.survol {
    border-color: #1cb0f6;
    box-shadow: 0 8px 24px rgba(28,176,246,.28);
}

/* ---------- Le bouton du mode diagnostic ---------- */
.bouton-diagnostic {
    position: fixed;
    right: .8rem; bottom: .8rem;
    z-index: 3300;
    width: 34px; height: 34px;
    display: flex; align-items: center; justify-content: center;
    border: 0; border-radius: 50%;
    background: rgba(43,58,82,.85); color: #fff;
    font-size: .95rem; cursor: pointer;
    opacity: .45;
    transition: opacity .16s;
}
.bouton-diagnostic:hover { opacity: 1; }

/* ---------- La poignée de dimension, en bas à droite ---------- */
.calque-note-taille {
    position: absolute;
    right: 2px; bottom: 2px;
    width: 14px; height: 14px;
    cursor: nwse-resize;
    border-right: 3px solid rgba(34,48,74,.35);
    border-bottom: 3px solid rgba(34,48,74,.35);
    border-radius: 0 0 7px 0;
}
/* ZONE DE PRÉHENSION PLUS LARGE QUE LE DESSIN.
   Viser un carré de 14 px au pixel près est pénible, et un geste raté ne
   fait RIEN : on croit que la taille ne fonctionne pas. La prise s'étend
   donc à 30 px autour, sans changer l'aspect. */
.calque-note-taille::before {
    content: '';
    position: absolute;
    top: -8px; left: -8px; right: -8px; bottom: -8px;
    cursor: nwse-resize;
}
.calque-note-taille:hover {
    border-right-color: var(--c-note, #1cb0f6);
    border-bottom-color: var(--c-note, #1cb0f6);
}
/* La largeur devient modifiable : le texte ne se replie plus tout seul. */
.calque-note { max-width: none; }

/* ============================================================
   LES BARRES DU BAS PASSENT AU-DESSUS DU CALQUE
   Le calque d'annotations est à 900 (sous l'en-tête, qui est à 1071).
   La barre du bouton de validation était à 20, et le pied de page n'avait
   aucune altitude : au défilement, les notes passaient donc PAR-DESSUS
   eux. Elles doivent glisser DERRIÈRE, comme derrière l'en-tête.
   ============================================================ */
.barre-fin {
    z-index: 1000;   /* au-dessus du calque (900), sous l'en-tête (1071) */
}
.pied-de-page {
    position: relative;
    z-index: 1000;
}

/* ============================================================
   BARRES D'OUTILS — BLEU NUIT, comme au début
   ============================================================ */
.boite-live {
    background: #22304a;
    border: 1px solid rgba(255,255,255,.10);
    box-shadow: 0 10px 30px rgba(10,18,32,.35);
}
.boite-btn {
    background: rgba(255,255,255,.09);
    color: #e8eef7;
}
.boite-btn:hover { background: rgba(255,255,255,.20); }
.boite-btn.boite-actif {
    background: #1cb0f6;
    color: #fff;
    box-shadow: 0 4px 14px rgba(28,176,246,.45);
}
.boite-btn.boite-pref { background: rgba(120,170,255,.16); color: #a9c8ff; }
.boite-btn.boite-pref:hover { background: rgba(120,170,255,.28); }
.boite-danger:hover { background: rgba(255,90,90,.25); color: #ffb3b3; }
.boite-sep { background: rgba(255,255,255,.14); }
/* ATTENTION : ne JAMAIS ecrire « background » ici — la forme abregée
   EFFACE background-image et la trame de points disparait. On ne regle
   que la couleur des points. */
.boite-poignee {
    background-image: radial-gradient(circle, rgba(255,255,255,.55) 1.7px, transparent 1.8px);
}
.boite-couleur { box-shadow: 0 0 0 2px rgba(255,255,255,.35); }
.boite-couleur.boite-actif { box-shadow: 0 0 0 3px #fff; }

/* ============================================================
   LE FILTRE — MÊME DESIGN QUE LA BARRE D'OUTILS
   De petits boutons CARRÉS ARRONDIS, identiques à ceux de la barre
   d'outils : même taille, même rayon, même relief du bas, et le bouton
   actif se REMPLIT au lieu d'un rond qui glisse.
   ============================================================ */
.filtre-segmente {
    position: fixed;
    z-index: 3050;
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: .3rem;                     /* = la barre d'outils */
    padding: .4rem .45rem;          /* = la barre d'outils */
    border-radius: 22px;            /* = la barre d'outils */
    background: #22304a;
    border: 1px solid rgba(255,255,255,.10);
    box-shadow: 0 10px 30px rgba(10,18,32,.35);
    cursor: grab;
    bottom: 1rem; left: .9rem; top: auto;
    user-select: none;
}
.filtre-segmente:active { cursor: grabbing; }

/* Le rond qui glissait n'a plus lieu d'etre : on le retire. */
.filtre-curseur { display: none; }

/* LE BOUTON : exactement celui de la barre d'outils. */
.filtre-icone {
    position: relative;
    z-index: 1;
    width: 32px; height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-bottom: 3px solid rgba(0,0,0,.16);
    border-radius: 10px;
    background: rgba(255,255,255,.09);   /* = bouton de la barre, en bleu nuit */
    color: #e8eef7;
    font-size: .92rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
    transition: background .15s, color .15s,
                transform .1s, border-bottom-width .1s;
}
.filtre-icone i { line-height: 1; display: block; }
.filtre-icone:hover {
    background: rgba(255,255,255,.20);   /* = survol de la barre */
    transform: translateY(2px);
    border-bottom-width: 1px;
}
.filtre-icone:active {
    transform: translateY(3px);
    border-bottom-width: 0;
}
/* LE BOUTON ACTIF SE REMPLIT — comme celui de la barre d'outils. */
.filtre-icone.actif {
    background: #1cb0f6;
    color: #fff;
    box-shadow: 0 3px 10px rgba(28,176,246,.4);
}

/* Chez le professeur : EN HAUT A DROITE. A gauche se trouve la barre
   d'outils — les deux se croisaient et entraient dans le cadre. */
body.prof-live .filtre-segmente {
    top: 62px; bottom: auto;
    left: auto; right: .9rem;
}

/* ============================================================
   CHEZ L'ÉLÈVE SEULEMENT — gris clair et VERT Duolingo
   ============================================================ */
body:not(.prof-live) .boite-live {
    background: #fff;
    border: 2px solid #e7ecf3;
    box-shadow: 0 10px 30px rgba(43,58,82,.16);
}
body:not(.prof-live) .boite-btn {
    background: #f7f9fc;
    color: #5a6b80;
}
body:not(.prof-live) .boite-btn:hover { background: #eef3f9; }
body:not(.prof-live) .boite-btn.boite-actif {
    background: #58cc02;
    color: #fff;
    box-shadow: 0 3px 10px rgba(88,204,2,.35);
}
body:not(.prof-live) .boite-danger:hover { background: #ffe3e3; color: #e03e3e; }

body:not(.prof-live) .filtre-segmente {
    background: #fff;
    border: 2px solid #e7ecf3;
    box-shadow: 0 10px 30px rgba(43,58,82,.16);
}
body:not(.prof-live) .filtre-icone {
    background: #f7f9fc;
    color: #5a6b80;
    border-bottom-color: #e2e9f1;
}
body:not(.prof-live) .filtre-icone:hover { background: #eef3f9; color: #22304a; }
body:not(.prof-live) .filtre-icone.actif {
    background: #58cc02;
    color: #fff;
    box-shadow: 0 3px 10px rgba(88,204,2,.35);
}

/* ============================================================
   LEÇON VIVANTE — les activités montées DANS la page de leçon
   Créé le 10/10/2026.

   Le serveur pose un conteneur vide à l'endroit prévu par le manuel
   (« Foco em… » / « Teste seus conhecimentos »), ou en fin de cours en
   repli. assets/js/lecon-activites.js le remplit EN LIGNE : mini-
   exercice question par question, puis révision des cartes.

   Ces classes appartiennent à la page de leçon : toute classe employée
   par le HTML ou le JS doit exister ici, sinon l'élément reste
   invisible — sans le moindre message d'erreur.
   ============================================================ */

/* ============================================================
   LES INVITATIONS À S'EXERCER
   L'activité ne s'étale plus dans le flux de la leçon. À l'endroit de la
   partie concernée, une invitation DIT à quelle partie elle appartient
   (« Partie 2 ») et propose un bouton. L'exercice s'ouvre alors dans une
   modale ; la révision des cartes se fait sur la page de fin de leçon,
   en plein écran, avec l'animation vers le bouton Flashcards.
   ============================================================ */
.invitation-activite {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem 1.4rem;
    background: linear-gradient(135deg, #f2f8ff, #e7f3ff);
    border: 2px solid #cfe6ff;
    border-left: 6px solid #1cb0f6;
    border-radius: var(--r);
    padding: 1.1rem 1.3rem;
    margin: 1.6rem 0;
}
.invitation-cartes {
    background: linear-gradient(135deg, #f7fff0, #ecfbe0);
    border-color: #d4efbc;
    border-left-color: #58cc02;
}
.invitation-texte { flex: 1 1 300px; min-width: 0; }
.invitation-rang {
    display: inline-block;
    font-size: .7rem;
    font-weight: 800;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: #fff;
    background: #1cb0f6;
    border-radius: 999px;
    padding: .2rem .65rem;
    margin-bottom: .45rem;
}
.invitation-cartes .invitation-rang { background: #58cc02; }
.invitation-activite h3 { margin: 0 0 .25rem; font-size: 1.08rem; }
.invitation-activite p { margin: 0; font-size: .92rem; color: var(--texte-doux); }
.bouton-invitation { flex: 0 0 auto; }

/* Un BOUTON posé dans la leçon n'est pas un lien de contenu : son texte
   reste blanc. `.lesson-content-lecon a` (plus spécifique) repeignait en
   bleu le bouton vert, qui redevenait blanc au survol — le bouton semblait
   avoir deux couleurs. */
.lesson-content-lecon a.bouton-principal { color: var(--texte-bouton); }

/* ============================================================
   LA MODALE DE L'EXERCICE
   Fond flouté (backdrop-filter), boîte large et arrondie : l'exercice
   tient en grand sur une seule page, au lieu d'être écrasé dans la leçon.
   z-index 2500 : au-dessus de l'en-tête fixe, sous le calque d'annotations.
   ============================================================ */
.modale-fond {
    position: fixed;
    inset: 0;
    z-index: 2500;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 1.2rem;
    background: rgba(28, 38, 56, .42);
    backdrop-filter: blur(9px);
    -webkit-backdrop-filter: blur(9px);
}
.modale-fond.ouverte { display: flex; }
body.modale-ouverte { overflow: hidden; }
.modale-boite {
    position: relative;
    width: min(720px, 100%);
    max-height: 92vh;
    overflow-y: auto;
    background: var(--blanc);
    border-radius: 26px;
    padding: 1.5rem 1.6rem;
    box-shadow: 0 30px 70px rgba(20, 30, 50, .35);
    animation: arrivee-modale .28s cubic-bezier(.2, .8, .3, 1);
}
@keyframes arrivee-modale {
    from { opacity: 0; transform: translateY(18px) scale(.98); }
}
.modale-fermer {
    position: absolute;
    top: .8rem;
    right: .8rem;
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 2px solid var(--bord);
    background: var(--blanc);
    color: var(--texte-doux);
    cursor: pointer;
    z-index: 1;
}
.modale-fermer:hover { background: #f2f5fa; color: var(--encre); }

/* ============================================================
   LA LEÇON SURLIGNÉE COMME UN CAHIER D'ÉLÈVE
   Le manuel marquait ses points importants avec des balises strong et em.
   On leur rend leur rôle de stabilo : un TRAIT DE COULEUR SOUS LE MOT,
   jamais un aplat qui mangerait le texte.
   ============================================================ */
.lesson-content-lecon strong {
    font-weight: 800;
    background-image: linear-gradient(transparent 57%,
                                      rgba(255, 206, 0, .55) 57%,
                                      rgba(255, 206, 0, .55) 94%,
                                      transparent 94%);
    padding: 0 .12em;
    border-radius: 3px;
}
.lesson-content-lecon em {
    font-style: normal;
    color: #0f6b58;
    background-image: linear-gradient(transparent 64%, rgba(0, 200, 160, .32) 64%);
    padding: 0 .1em;
}
.lesson-content-lecon h2 { border-left: 5px solid #1cb0f6; padding-left: .6rem; }
.lesson-content-lecon h3 { color: #b65b1e; }
/* ... mais PAS les titres des invitations : ce sont nos blocs, pas le
   manuel. Sans cette règle, le titre de l'invitation héritait de l'orange
   du manuel — le style de la leçon débordait sur notre interface. */
.lesson-content-lecon .invitation-activite h3 { color: var(--encre); }
.lesson-content-lecon tbody tr:nth-child(odd) { background: #fbfcff; }
.lesson-content-lecon audio { max-width: 100%; }

/* La boîte commune */
.al-boite {
    background: var(--blanc);
    border: 2px solid var(--bord);
    border-radius: var(--r);
    padding: 1.1rem 1.2rem 1.2rem;
}
.al-titre-activite {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: 1.02rem;
    font-weight: 800;
    color: var(--encre);
    margin: 0 0 .9rem;
}
.al-titre-activite i { color: var(--bleu); font-size: 1.15rem; }

/* ---------- Barre du haut : jauge + vies ---------- */
.al-barre { display: flex; align-items: center; gap: .9rem; margin-bottom: 1rem; }
.al-jauge {
    flex: 1; height: 14px; border-radius: var(--r-pilule);
    background: var(--bord-doux); overflow: hidden;
}
.al-jauge > span {
    display: block; height: 100%; width: 0; border-radius: var(--r-pilule);
    background: linear-gradient(90deg, var(--vert-clair), var(--vert));
    transition: width .4s ease;
}
.al-vies {
    display: inline-flex; align-items: center; gap: .25rem;
    font-weight: 800; color: var(--rouge); white-space: nowrap;
}
.al-vies i { font-size: 1.05rem; }
.al-vies.al-secousse { animation: al-secousse .5s; }
@keyframes al-secousse {
    10%, 90% { transform: translateX(-1px); }
    20%, 80% { transform: translateX(2px); }
    30%, 50%, 70% { transform: translateX(-4px); }
    40%, 60% { transform: translateX(4px); }
}

/* ---------- La carte d'une question ---------- */
.al-carte {
    background: var(--fond);
    border: 2px solid var(--bord-doux);
    border-radius: var(--r-sm);
    padding: 1.2rem 1.2rem 1.3rem;
    min-height: 190px;
}
.al-titre { font-size: 1.2rem; font-weight: 800; color: var(--encre); margin: 0 0 .2rem; }
.al-consigne { font-size: .88rem; color: var(--texte-doux); margin: 0 0 1rem; }

/* ---------- Choix (CHOIX_UNIQUE / MULTIPLE …) ---------- */
.al-options { display: flex; flex-direction: column; gap: .55rem; }
.al-option {
    display: block; width: 100%; text-align: left;
    background: #fff; border: 2px solid var(--bord); border-bottom-width: 4px;
    border-radius: var(--r-sm); padding: .8rem 1rem;
    font: inherit; font-size: .96rem; font-weight: 600; color: var(--encre);
    cursor: pointer;
    transition: background .15s, border-color .15s, transform .1s;
}
.al-option:hover:not(.gele) { background: #f7f9fc; transform: translateY(-1px); }
.al-option.choisi { border-color: var(--bleu); background: #e8f7ff; }
.al-option.juste {
    border-color: var(--vert-fonce) !important; background: #d7ffb8 !important;
    color: var(--vert-fonce) !important;
}
.al-option.faux {
    border-color: var(--rouge-ombre) !important; background: #ffdfe0 !important;
    color: var(--rouge-ombre) !important;
}

/* ---------- Association ---------- */
.al-assoc { display: flex; gap: .7rem; }
.al-colonne { flex: 1; display: flex; flex-direction: column; gap: .5rem; }
.al-mot {
    background: #fff; border: 2px solid var(--bord); border-bottom-width: 4px;
    border-radius: var(--r-sm); padding: .7rem .8rem;
    font: inherit; font-size: .92rem; font-weight: 600; color: var(--encre);
    cursor: pointer; transition: background .15s, border-color .15s;
}
.al-mot:hover:not(.gele) { background: #f7f9fc; }
.al-mot.choisi { border-color: var(--bleu); background: #e8f7ff; }
.al-mot.juste {
    border-color: var(--vert-fonce) !important; background: #d7ffb8 !important;
    color: var(--vert-fonce) !important;
}
.al-mot.faux {
    border-color: var(--rouge-ombre) !important; background: #ffdfe0 !important;
    color: var(--rouge-ombre) !important; animation: al-secousse .5s;
}

/* ---------- Texte à trous / remise en ordre ---------- */
/* `.al-phrase` sert à DEUX choses : la boîte à jetons de la REMISE EN ORDRE
   et le fil du TEXTE À TROUS (`.al-phrase-trous`). Elles n'ont rien à voir :
   on ne dessine un cadre que pour la remise en ordre (voir plus bas). */
.al-phrase {
    display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
    min-height: 56px; padding: .7rem .8rem;
    border: 2px dashed var(--bord); border-radius: var(--r-sm);
    font-size: 1.05rem; font-weight: 600; color: var(--encre);
}

/* ================================================================
   LA REMISE EN ORDRE — deux zones nommées, chacune dans son cadre.
   Même dessin que la page d'exercice (pages.css, « REMISE EN ORDRE ») :
   sans cela, le MÊME exercice changeait d'allure d'une page à l'autre.
   ================================================================ */
.al-ordre { display: flex; flex-direction: column; gap: 1rem; }
.al-ordre-entete { display: flex; align-items: center; gap: .6rem; margin-bottom: .4rem; }
.al-ordre-titre {
    font-size: .7rem; font-weight: 800; letter-spacing: .09em;
    text-transform: uppercase; color: var(--texte-doux); white-space: nowrap;
}
.al-ordre-entete::after {
    content: ''; flex: 1 1 auto; height: 2px; border-radius: 2px; background: var(--bord);
}
/* L'aide n'apparaît que lorsqu'un mot est posé : elle décrit un geste
   qui existe à ce moment-là. */
.al-ordre-aide {
    display: none; font-size: .7rem; font-weight: 700;
    color: var(--bleu); white-space: nowrap;
}
.al-ordre:has(.al-phrase:not(.al-est-vide)) .al-ordre-aide { display: inline; }

.al-phrase:not(.al-phrase-trous) {
    min-height: 84px; padding: .8rem .9rem;
    background: #fff; border: 2px solid var(--bord); border-radius: var(--r-sm);
    transition: border-color .18s, background-color .18s, box-shadow .18s;
}
.al-phrase:not(.al-phrase-trous).al-est-vide {
    border-style: dashed; border-color: #cdd8e4; background: #f8fbfd;
}
.al-ordre-vide {
    display: none; align-items: center; justify-content: center; gap: .5rem;
    width: 100%; color: var(--texte-doux);
    font-size: .92rem; font-weight: 600; text-align: center;
}
.al-phrase.al-est-vide .al-ordre-vide { display: flex; }
/* Boîte pleine : trait plein et curseur qui bat au bout. */
.al-phrase:not(.al-est-vide):not(.juste):not(.faux)::after {
    content: ''; width: 2px; height: 1.6em; border-radius: 2px;
    background: var(--bleu); animation: al-ordre-curseur 1.05s steps(1) infinite;
}
@keyframes al-ordre-curseur { 50% { opacity: 0; } }

/* La correction : la boîte entière dit juste ou faux. */
.al-phrase.juste { border-color: var(--vert); background: #f3ffe6; }
.al-phrase.faux { border-color: var(--rouge); background: #fff5f5; }

/* Le plateau des mots restants — cadré seulement dans la remise en ordre. */
.al-ordre .al-banque {
    align-items: center; min-height: 56px; padding: .6rem .7rem; margin-top: 0;
    background: #f7fafc; border: 2px solid var(--bord-doux);
    border-radius: var(--r-sm);
}
/* Plateau vide : il dit ce qui se passe au lieu de rester un trou blanc. */
.al-ordre-banque-vide {
    display: none; width: 100%; text-align: center;
    color: var(--texte-doux); font-size: .82rem; font-weight: 600;
}
.al-ordre .al-banque:not(:has(.al-jeton)) .al-ordre-banque-vide { display: block; }

.al-phrase-trous { display: block; line-height: 2.2; }
.al-trou {
    display: inline-flex; align-items: center; justify-content: center;
    vertical-align: middle;
    min-width: 100px; min-height: 2em; margin: 0 .15rem; padding: 0 .4rem;
    background: var(--bord); border: 2px dashed var(--texte-doux);
    border-radius: var(--r-sm);
}
/* Trou rempli : il s'efface devant son mot. */
.al-trou:has(.al-jeton) {
    min-width: 0; padding: 0; margin: 0 .1rem;
    background: transparent; border-color: transparent;
}
.al-trou .al-jeton { margin: 0; padding: .25rem .7rem; font-size: .92em; }
.al-banque { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }
.al-jeton {
    background: #fff; border: 2px solid var(--bord); border-bottom-width: 4px;
    border-radius: var(--r-sm); padding: .55rem .9rem;
    font: inherit; font-size: .96rem; font-weight: 700; color: var(--encre);
    cursor: pointer; transition: background .15s, border-color .15s, transform .1s;
}
.al-jeton:hover:not(.gele) { background: #f7f9fc; transform: translateY(-1px); }
.al-jeton.juste {
    border-color: var(--vert-fonce) !important; background: #d7ffb8 !important;
    color: var(--vert-fonce) !important;
}
.al-jeton.faux {
    border-color: var(--rouge-ombre) !important; background: #ffdfe0 !important;
    color: var(--rouge-ombre) !important;
}
.al-champ {
    width: 100%; border: 2px solid var(--bord); border-radius: var(--r-sm);
    padding: .7rem .85rem; font: inherit; font-size: 1rem; color: var(--encre);
    resize: vertical;
}
.al-champ:focus { outline: none; border-color: var(--bleu); }

/* Les éléments figés après correction ne réagissent plus au survol. */
.al-option.gele, .al-mot.gele, .al-jeton.gele { cursor: default; }

/* ---------- Le retour (vert / rouge) ---------- */
.al-retour {
    margin-top: .9rem; padding: .7rem .9rem; border-radius: var(--r-sm);
    font-weight: 800; font-size: .95rem;
}
.al-retour.al-juste { background: #d7ffb8; color: var(--vert-fonce); }
.al-retour.al-faux { background: #ffdfe0; color: var(--rouge-ombre); }

/* ---------- Le bouton principal ---------- */
.al-pied { display: flex; justify-content: flex-end; margin-top: 1rem; }
.al-bouton {
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    padding: .8rem 1.8rem; border: 0; border-radius: var(--r-pilule);
    background: var(--bleu); color: #fff;
    font: inherit; font-size: .95rem; font-weight: 800;
    cursor: pointer;
    box-shadow: 0 4px 0 var(--bleu-ombre);
    transition: transform .1s, box-shadow .1s, filter .15s;
}
.al-bouton:hover:not(:disabled) { filter: brightness(1.05); }
.al-bouton:active:not(:disabled) { transform: translateY(3px); box-shadow: 0 1px 0 var(--bleu-ombre); }
.al-bouton:disabled { background: #cfd6e0; box-shadow: 0 4px 0 #b3bcc9; cursor: default; }
.al-bouton-vert { background: var(--vert); box-shadow: 0 4px 0 var(--vert-ombre); }
.al-bouton-rouge { background: var(--rouge); box-shadow: 0 4px 0 var(--rouge-ombre); }

/* ---------- L'écran de fin ---------- */
.al-fin { text-align: center; }
.al-fin-icone {
    width: 68px; height: 68px; margin: 0 auto .8rem; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 2rem; color: #fff;
}
.al-fin-ok {
    background: linear-gradient(160deg, var(--vert-clair), var(--vert-fonce));
    box-shadow: 0 5px 0 var(--vert-ombre);
}
.al-fin-ko {
    background: linear-gradient(160deg, #ff7c7c, var(--rouge-ombre));
    box-shadow: 0 5px 0 #c63c3c;
}
.al-fin-titre { font-size: 1.35rem; margin: 0 0 .3rem; }
.al-score { font-size: 1.05rem; color: var(--texte); margin: .2rem 0 .6rem; }
.al-xp { font-weight: 800; color: var(--vert-fonce); margin: 0 0 .8rem; }

/* ---------- La révision des cartes ---------- */
.al-rev { }
.al-rev-barre { display: flex; align-items: center; gap: .9rem; margin-bottom: 1.1rem; }
.al-rev-jauge {
    flex: 1; height: 14px; border-radius: var(--r-pilule);
    background: var(--bord-doux); overflow: hidden;
}
.al-rev-jauge > span {
    display: block; height: 100%; width: 0; border-radius: var(--r-pilule);
    background: linear-gradient(90deg, var(--vert-clair), var(--vert));
    transition: width .45s ease;
}
.al-rev-compteur {
    font-size: .82rem; font-weight: 800; color: var(--texte-doux);
    white-space: nowrap;
}
.al-rev-scene { display: flex; flex-direction: column; align-items: center; }
.al-rev-fin { text-align: center; margin: 0 auto; }

/* Le bouton « J'ai appris » de la page de leçon : la MÊME apparition que
   sur la page de fin de leçon (règle .zone-appris #btn-appris ci-dessus). */
.zone-appris #al-btn-appris {
    opacity: 0;
    transform: translateY(10px);
    animation: apparition-appris .3s ease forwards;
}

/* ============================================================
   LE CAHIER DE L'ÉLÈVE — refonte premium
   ------------------------------------------------------------
   Ce que Jérémy a refusé : un fond crème, un quadrillage qui s'arrête au
   milieu de la boîte, des encadrés sans relief, un en-tête plat.

   Règles tenues ici :
   1. le quadrillage couvre TOUTE la feuille — donc AUCUN élément interne
      ne pose de fond opaque (c'était le défaut : les cellules des tableaux
      étaient en #fbfdff et recouvraient tout le bas de la page) ;
   2. les encadrés d'action sont BLANCS et pleins — ils se détachent de la
      feuille par l'ombre et la couleur, jamais par la transparence ;
   3. l'en-tête est une carte colorée, pas une bande de texte espacée ;
   4. une seule définition par niveau typographique.
   ============================================================ */
/* Les variables du papier et du cahier vivent dans theme.css. */

/* ============================================================
   LA FEUILLE DE COURS — le quadrillage, partout
   ============================================================ */
.lesson-content-lecon {
    background-color: var(--papier);
    background-image:
        linear-gradient(to right, var(--carreau-trait) 1px, transparent 1px),
        linear-gradient(to bottom, var(--carreau-trait) 1px, transparent 1px);
    background-size: var(--carreau) var(--carreau);
    border: 1px solid var(--papier-bord);
    border-radius: 22px;
    padding: 1.9rem 2rem 2.1rem;
    /* La feuille se détache de la page : elle doit se lire comme une vraie
       feuille posée sur le bureau, pas comme un aplat collé. */
    box-shadow: 0 18px 40px -34px rgba(18, 76, 130, .6);
}
/* AUCUN élément du contenu ne pose de fond opaque : le quadrillage doit
   passer partout, jusqu'au bas de la feuille. */
.lesson-content-lecon table,
.lesson-content-lecon thead,
.lesson-content-lecon tbody,
.lesson-content-lecon tr,
.lesson-content-lecon td,
.lesson-content-lecon th,
.lesson-content-lecon div,
.lesson-content-lecon p,
.lesson-content-lecon span,
.lesson-content-lecon ul,
.lesson-content-lecon ol,
.lesson-content-lecon li {
    background-color: transparent;
}
/* Le zébruillage se fait en VOILE très léger, jamais en aplat : l'ancienne
   règle posait un #fbfcff OPAQUE sur les lignes impaires, et c'est elle qui
   recouvrait le quadrillage sur toute la partie basse de la feuille.
   (Même spécificité que l'ancienne règle, mais écrite après : elle gagne.) */
.lesson-content-lecon tbody tr,
.lesson-content-lecon tbody tr:nth-child(odd),
.lesson-content-lecon tbody tr:nth-child(odd) td { background-color: transparent; }
.lesson-content-lecon tbody tr:nth-child(even) td { background-color: rgba(28, 176, 246, .04); }
.lesson-content-lecon table thead th,
.lesson-content-lecon table tr:first-child th { background-color: rgba(28, 176, 246, .09); }

/* Le bloc qui porte la feuille : il ne double pas la carte. */
.bloc-lecon {
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0;
}

/* ============================================================
   L'EN-TÊTE DE LA LEÇON — une carte nette, moderne
   ------------------------------------------------------------
   Refonte du 10/10/2026. La version précédente portait un dégradé bleu→vert
   sur trois arrêts ET un filet de couleur bleu→vert→jaune collé en bas de
   la boîte : deux effets pour un seul rôle, ce qui faisait « brouillon ».
   On garde UNE seule idée : un fond blanc, un lavis bleu très doux dans le
   coin haut-droit, une bordure fine et une ombre légère. Le filet du bas
   est supprimé.
   ============================================================ */
.entete-lecon {
    position: relative;
    background-image:
        radial-gradient(130% 150% at 100% 0%, rgba(28, 176, 246, .10), rgba(28, 176, 246, 0) 62%),
        linear-gradient(180deg, #ffffff 0%, #f7fbff 100%);
    background-color: #fff;
    border: 1px solid #e2eefa;
    border-radius: 24px;
    padding: 1.35rem 1.5rem 1.45rem;
    margin-bottom: 1.4rem;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem 1.2rem;
    box-shadow: 0 16px 36px -30px rgba(18, 76, 130, .65);
}
/* Le bloc du texte prend la place disponible : sans cela il se réduisait à
   la largeur de ses mots et un titre long cassait trop tôt. */
.entete-lecon-texte { flex: 1 1 22rem; min-width: 0; }

/* ---- LES PILULES DE L'EN-TÊTE ------------------------------------------
   Elles doivent avoir EXACTEMENT la même géométrie. Deux défauts les
   séparaient :
     1. l'icône de l'horloge est plus haute que le texte : elle faisait
        grandir la pilule de la durée (32 px contre 28 px), donc les deux
        pilules n'avaient ni la même hauteur ni le même alignement ;
     2. `gap` écartait TOUS les enfants du bloc, y compris le « /4 » du
        compteur — le « 3 » et le « /4 » se détachaient l'un de l'autre.
   On fixe donc une hauteur commune et on porte l'écart icône/texte par
   l'icône elle-même. */
.jetons-lecon {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .45rem;
    margin-bottom: .75rem;
}
.jeton-lecon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    height: 30px;
    padding: 0 .85rem;
    font-size: .71rem;
    font-weight: 800;
    letter-spacing: .06em;
    line-height: 1;
    text-transform: uppercase;
    white-space: nowrap;
    color: #1878b8;
    background: rgba(28, 176, 246, .13);
    border: 0;
    border-radius: 999px;
}
.jeton-lecon i { font-size: .95rem; line-height: 1; margin-right: .42rem; }
.jeton-lecon .sur { color: #8fb6cf; margin: 0; letter-spacing: 0; }
.jeton-duree { color: #5b6b82; background: rgba(43, 58, 82, .08); }
.jeton-fait { color: var(--vert-fonce); background: rgba(88, 204, 2, .16); }

/* La pilule de CATÉGORIE — vocabulaire, grammaire, prononciation, culture.
   C'est la seule information neuve que portait le titre du manuel
   (« Vocabulaire: Les matières ») : le titre, lui, est déjà le grand titre
   de la page. Chaque catégorie a sa teinte pastel, pour qu'on sache d'un
   coup d'œil de quoi la leçon parle.

   Deux formes, une seule palette : la pilule de l'en-tête d'une leçon
   (.jeton-categorie) et la pastille discrète des listes de leçons
   (.puce-categorie) — même vocabulaire de couleurs, deux poids visuels. */
.jeton-categorie.categorie-vocabulaire,
.puce-categorie.categorie-vocabulaire   { color: #1878b8; background: #e3f2ff; }
.jeton-categorie.categorie-grammaire,
.puce-categorie.categorie-grammaire     { color: #7a4fd0; background: #f1eaff; }
.jeton-categorie.categorie-prononciation,
.puce-categorie.categorie-prononciation { color: #a76a00; background: #fff3d9; }
.jeton-categorie.categorie-coin-culture,
.puce-categorie.categorie-coin-culture  { color: #3d8a1f; background: #e9f9dc; }

/* La pastille de catégorie dans une liste de leçons : petite, elle ne doit
   pas peser plus que le titre de la leçon qu'elle accompagne. */
.puce-categorie {
    display: inline-block;
    font-size: .66rem;
    font-weight: 800;
    letter-spacing: .05em;
    text-transform: uppercase;
    padding: .12rem .5rem;
    border-radius: 999px;
    margin-right: .5rem;
    vertical-align: 1px;
}

/* Le titre : un trait de surligneur pastel SOUS les mots, jamais un aplat
   qui mange le texte — la même écriture que dans la feuille de cours. */
.entete-lecon h1.titre-lecon {
    display: inline;
    font-size: 2.3rem;
    font-weight: 800;
    line-height: 1.25;
    margin: 0;
    color: #14496e;
    background-image: linear-gradient(rgba(28, 176, 246, .24), rgba(28, 176, 246, .24));
    background-repeat: no-repeat;
    background-size: 100% .34em;
    background-position: 0 84%;
    padding: 0 .08em;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}
.entete-lecon .titre-lecon-pt {
    font-size: 1.05rem;
    font-weight: 700;
    color: #5b8fae;
    margin: .45rem 0 0;
}
/* Sur téléphone : le titre redescend, la carte se resserre. Ce bloc doit
   venir APRÈS la règle du titre, sinon la règle générale gagne (à
   spécificité égale, c'est la dernière écrite qui s'applique — une
   requête média ne change rien à cet ordre). */
@media (max-width: 640px) {
    .entete-lecon { padding: 1.1rem 1.15rem 1.2rem; border-radius: 20px; }
    .entete-lecon h1.titre-lecon { font-size: 1.7rem; }
    .entete-lecon .titre-lecon-pt { font-size: .98rem; }
}

/* Le fil d'Ariane : cliquable jusqu'à la page courante, qui ne l'est pas. */
.fil-ariane {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .1rem .45rem;
    font-size: .82rem;
    margin-bottom: .7rem;
    color: var(--texte-doux);
}
.fil-ariane a {
    color: #1878b8;
    text-decoration: none;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    gap: .3rem;
}
.fil-ariane a:hover { color: #0f5c91; text-decoration: underline; }
.fil-ariane .separateur { color: #c3cbd8; }
.fil-ariane .ici { color: var(--nuit); font-weight: 800; }

/* ---- LES ENCADRÉS D'ACTION (exercice, cartes) — opaques et pleins ----
   « Les deux jolies box ont un fond transparent, elles ne ressortent
   plus. » Elles doivent se lire comme des cartes POSÉES SUR la feuille
   quadrillée : fond opaque, ombre franche, liseré coloré à gauche.
   Le fond est un dégradé très doux du blanc vers la teinte de l'accent —
   assez pour que la boîte ressortie, assez discret pour rester un cahier.
   ⚠️ La forme `.lesson-content-lecon .invitation-activite` est
   indispensable : voir l'avertissement de spécificité plus haut. */
.invitation-activite,
.lesson-content-lecon .invitation-activite {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem 1.4rem;
    background-color: #fff;
    background-image: linear-gradient(152deg, #ffffff 0%, #eaf5ff 100%);
    border: 1px solid #dbe9f8;
    border-left: 6px solid var(--bleu);
    border-radius: 18px;
    padding: 1.2rem 1.35rem;
    margin: 1.6rem 0;
    box-shadow: 0 12px 26px -20px rgba(20, 72, 128, .6),
                0 1px 2px rgba(20, 72, 128, .07);
}
.invitation-activite.invitation-cartes,
.lesson-content-lecon .invitation-activite.invitation-cartes {
    background-image: linear-gradient(152deg, #ffffff 0%, #ebfbe0 100%);
    border-color: #d9eed0;
    border-left: 6px solid var(--vert);
    box-shadow: 0 12px 26px -20px rgba(70, 163, 2, .55),
                0 1px 2px rgba(70, 163, 2, .07);
}
.invitation-texte { flex: 1 1 16rem; min-width: 0; }
.invitation-rang,
.lesson-content-lecon .invitation-rang {
    display: inline-block;
    font-size: .68rem;
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #fff;
    background-color: var(--bleu);
    border-radius: 999px;
    padding: .2rem .65rem;
    margin-bottom: .5rem;
}
.invitation-cartes .invitation-rang { background-color: var(--vert); }
.invitation-activite h3 {
    font-family: var(--police-cahier);
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.1;
    margin: 0 0 .3rem;
    color: var(--nuit);
}
.invitation-activite p { margin: 0; font-size: .95rem; color: var(--texte); }
.invitation-quand { font-size: .82rem; color: var(--texte-doux); margin-top: .25rem; }
.bouton-invitation {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-size: 1rem;
    font-weight: 800;
    /* Une VARIANTE du bouton principal : elle ne pose que des variables,
       jamais un fond en dur — sinon le survol reprendrait le vert. */
    --fond: var(--bleu); --fond-survol: var(--bleu);
    --ombre-bouton: #1899d6; --texte-bouton: #fff;
    border: 0;
    /* Une pilule, comme tous les boutons principaux du site : un bouton
       « arrondi à 14 px » à côté d'un bouton pilule, ça se voit. */
    border-radius: 999px;
    padding: .85rem 1.6rem;
    text-decoration: none;
    cursor: pointer;
    transition: transform .08s ease, box-shadow .08s ease;
}
.bouton-invitation:hover {
    color: var(--texte-bouton);
    transform: translateY(1px);
    box-shadow: 0 3px 0 var(--ombre-bouton);
}
.invitation-cartes .bouton-invitation {
    --fond: var(--vert); --fond-survol: var(--vert);
    --ombre-bouton: var(--vert-fonce);
}

/* ============================================================
   LA MISE EN FORME DU CONTENU (contrat : docs/CONTRAT_CONTENU.md)
   ============================================================ */

/* Le titre de section du manuel : une étiquette douce, pas un gris
   minuscule. C'est la première chose qu'on lit dans la feuille. */
.lesson-content-lecon h1.lc-titre {
    display: inline-block;
    font-size: 1.02rem;
    font-weight: 800;
    letter-spacing: .02em;
    color: #1878b8;
    /* Opaque : une étiquette se pose sur la feuille, elle ne la laisse pas
       deviner au travers. */
    background-color: #e6f4ff;
    border-radius: 999px;
    padding: .4rem 1rem;
    margin: .3rem 0 1.5rem;
}
.lesson-content-lecon h1.lc-titre .lc-titre-pt {
    display: block;
    font-size: .82rem;
    font-weight: 700;
    color: #6fa4c4;
    margin-top: .15rem;
}

/* Le chapeau du manuel (« 1 – Bonjour et bienvenue ! ») : discret mais net. */
.lesson-content-lecon .lc-chapeau {
    font-size: .8rem;
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #8695a8;
    margin: 0 0 .6rem;
}

/* Une partie numérotée : le seul niveau qui porte un numéro. La barre
   bleue devient une pastille arrondie, posée dans la marge — plus nette
   qu'un trait de bordure, qui ne peut pas s'arrondir. */
.lesson-content-lecon h2.lc-partie {
    position: relative;
    font-family: var(--police-cahier);
    font-size: 2.05rem;
    font-weight: 700;
    line-height: 1.15;
    color: var(--nuit);
    margin: 2.3rem 0 1rem;
    padding-left: 1.05rem;
    border-left: 0;
}
.lesson-content-lecon h2.lc-partie::before {
    content: '';
    position: absolute;
    left: 0;
    top: .16em;
    bottom: .16em;
    width: 6px;
    border-radius: 999px;
    background: linear-gradient(180deg, #55c8ff 0%, var(--bleu) 100%);
}
.lesson-content-lecon h2.lc-partie:first-child { margin-top: 0; }
.lesson-content-lecon h3.lc-sous {
    font-family: var(--police-cahier);
    font-size: 1.5rem;
    font-weight: 700;
    color: #b65b1e;
    margin: 1.5rem 0 .6rem;
}
/* Un mot à apprendre : jamais un titre, donc jamais énorme. */
.lesson-content-lecon .lc-mot {
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--nuit);
    margin: 1rem 0 .35rem;
}
.lesson-content-lecon p { margin: 0 0 .85rem; }
.lesson-content-lecon ul, .lesson-content-lecon ol { margin: 0 0 .9rem; padding-left: 1.25rem; }
.lesson-content-lecon li { margin-bottom: .35rem; }
.lesson-content-lecon a { color: #1878b8; font-weight: 700; }

/* Les surlignages : un trait de couleur SOUS le mot, jamais un aplat. */
.lesson-content-lecon strong {
    font-weight: 800;
    background-image: linear-gradient(transparent 58%, var(--hl-jaune) 58%,
                                      var(--hl-jaune) 95%, transparent 95%);
    padding: 0 .1em;
}
.lesson-content-lecon em {
    font-style: normal;
    font-weight: 800;
    color: #1b6d92;
    background-image: linear-gradient(transparent 60%, var(--hl-bleu) 60%);
    padding: 0 .1em;
}
.lesson-content-lecon u {
    text-decoration: none;
    font-weight: 800;
    background-image: linear-gradient(transparent 60%, var(--hl-vert) 60%);
    padding: 0 .1em;
}

/* Les tableaux : pleine largeur, aérés, lisibles comme une liste. */
.lesson-content-lecon table.lc-tableau,
.lesson-content-lecon table {
    width: 100%;
    max-width: 100%;
    border-collapse: collapse;
    margin: 1.1rem 0 1.5rem;
    font-size: .96rem;
}
.lesson-content-lecon table td,
.lesson-content-lecon table th {
    padding: .7rem .75rem;
    border: 0;
    border-bottom: 1px solid rgba(28, 176, 246, .16);
    vertical-align: middle;
    text-align: left;
}
.lesson-content-lecon table thead th,
.lesson-content-lecon table tr:first-child th {
    font-size: .74rem;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #5b8fae;
    border-bottom: 2px solid rgba(28, 176, 246, .25);
}
.lesson-content-lecon table tr:last-child td { border-bottom: 0; }

/* Le lecteur du navigateur est remplacé par un bouton rond et coloré
   (voir assets/js/audio-lecon.js). Masqué SEULEMENT une fois remplacé :
   sans JavaScript, le lecteur natif reste utilisable. */
.lesson-content-lecon audio.audio-lecon.ameliore { display: none; }

/* ---------- Écouter : un vrai bouton plein, pas une puce ----------
   Aucune transparence : le bouton est BLEU PLEIN au repos, avec son ombre
   pleine de 3 px sous lui — la signature « en relief » du site. Un fond
   translucide faisait disparaître le bouton dans les carreaux du papier. */
.bouton-audio {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.85rem;
    height: 2.85rem;
    border: 0;
    border-radius: 999px;
    background-color: var(--bleu);
    color: #fff;
    font-size: 1.3rem;
    cursor: pointer;
    box-shadow: 0 3px 0 var(--bleu-ombre);
    transition: background .15s ease, color .15s ease,
                transform .08s ease, box-shadow .08s ease;
}
.bouton-audio:hover {
    background-color: #3cc0ff;
    color: #fff;
    transform: translateY(-1px);
    box-shadow: 0 4px 0 var(--bleu-ombre);
}
.bouton-audio:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--bleu-ombre); }
/* Pendant la lecture : un halo, pour voir d'un coup d'œil ce qui joue. */
.bouton-audio.joue {
    background-color: var(--bleu-fonce);
    color: #fff;
    box-shadow: 0 0 0 4px rgba(28, 176, 246, .3), 0 3px 0 var(--bleu-ombre);
}
.bouton-audio:disabled { opacity: .45; cursor: default; box-shadow: none; }

/* ---- LE TABLEAU DE VOCABULAIRE ----------------------------------------
   Il se lit comme une LISTE d'apprentissage, pas comme un tableau de
   grammaire : colonnes à largeur fixe (donc parfaitement alignées d'un
   bout à l'autre), un trait pointillé entre le français et le portugais
   — la marge d'un cahier —, et une ligne sur deux très légèrement voilée
   pour suivre son doigt. Le voile est un VOILE, jamais un aplat : le
   quadrillage de la feuille continue de passer au travers.

   ATTENTION AU SÉLECTEUR, ce n'est pas un détail. Il ne vise QUE les
   listes de vocabulaire : audio + français + portugais, donc EXACTEMENT
   trois colonnes. Une première version disait simplement `:has(audio)` :
   elle a attrapé 29 leçons dont les tableaux ont 4 à 8 colonnes (les
   conjugaisons, les pronoms, la prononciation) et les a écrasés —
   `table-layout: fixed` plus une deuxième colonne forcée à 46 % coupaient
   les cellules en lignes d'un mot. Il faut donc TROIS conditions :
       :has(td:nth-child(3))          au moins 3 colonnes
       :not(:has(td:nth-child(4)))    et pas une de plus
       :not(:has(ul)):not(:has(ol))   et AUCUNE liste à puces
   La troisième est celle qui distingue une LISTE DE VOCABULAIRE d'un
   TABLEAU D'EXPLICATION. Les deux ont trois colonnes et de l'audio, mais
   l'explication met un paragraphe — souvent une liste — dans la troisième
   cellule : la colonne du mot n'a alors aucune raison de faire 46 %. Sur
   171 leçons, ce cas ne concerne que la leçon 261 « Les pronoms sujets »,
   et c'est lui qui cassait la page. Les tableaux sans ces conditions
   gardent la mise en forme générale des tableaux, définie plus haut. */
.lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) {
    border-collapse: separate;
    border-spacing: 0;
    table-layout: fixed;
    margin: 1.2rem 0 1.6rem;
}
.lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td {
    padding: .78rem .6rem;
    border: 0;
    vertical-align: middle;
}
/* La colonne du bouton d'écoute : largeur fixe, le bouton ne bouge jamais. */
.lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td:first-child {
    width: 3.6rem;
    padding-right: .3rem;
}
/* Le français d'abord : encre foncée, un cran plus grand. Les deux colonnes
   sont alignées sur la MÊME ligne de base — sinon le portugais, plus petit,
   flotte un peu plus haut que le mot français en face de lui. */
.lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td:nth-child(2) {
    width: 46%;
    font-size: 1.02rem;
    font-weight: 700;
    color: var(--nuit);
    vertical-align: baseline;
}
/* Le portugais ensuite : plus petit, plus gris, derrière le trait pointillé. */
.lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td:nth-child(3) {
    padding-left: 1.15rem;
    border-left: 1px dashed rgba(28, 176, 246, .32);
    font-size: .95rem;
    color: #7d8c9f;
    vertical-align: baseline;
}
.lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) tbody tr:nth-child(even) td {
    background-color: rgba(28, 176, 246, .05);
}
.lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) tbody tr td:first-child { border-radius: .8rem 0 0 .8rem; }
.lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) tbody tr td:last-child { border-radius: 0 .8rem .8rem 0; }
/* Au survol, toute la ligne s'allume : on sait sur quel mot on se trouve. */
.lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) tbody tr:hover td { background-color: rgba(28, 176, 246, .11); }

/* Le chapitre passé en immersion replie aussi la colonne portugaise du
   vocabulaire : c'est le plus gros bloc de portugais de la page, il serait
   absurde qu'il reste affiché. Le français, lui, prend toute la largeur. */
.lesson-content-lecon.pt-sans-vocab table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td:nth-child(3) { display: none; }
.lesson-content-lecon.pt-sans-vocab table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td:nth-child(2) { width: auto; }
/* La colonne française devient la dernière de la ligne : c'est donc elle
   qui doit porter le coin arrondi droit, sinon sa bande finit à angle droit. */
.lesson-content-lecon.pt-sans-vocab table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) tbody tr td:nth-child(2) {
    border-radius: 0 .8rem .8rem 0;
}
/* L'élève peut rouvrir l'aide : la colonne revient, à sa place et à sa
   largeur. (table-cell est la valeur juste pour une cellule de tableau.) */
html.pt-montre-tout .lesson-content-lecon.pt-sans-vocab table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td:nth-child(3) { display: table-cell; }
html.pt-montre-tout .lesson-content-lecon.pt-sans-vocab table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td:nth-child(2) { width: 46%; }

/* Sur téléphone, la feuille est étroite : on rend de la place au portugais
   (sa colonne tombait à 100 px, ce qui cassait « ciência da computação »
   sur trois lignes) et on resserre le bouton d'écoute. */
@media (max-width: 560px) {
    .lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td { padding: .7rem .4rem; }
    .lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td:first-child { width: 3.1rem; padding-right: 0; }
    .lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td:nth-child(2) { width: 40%; font-size: .98rem; }
    .lesson-content-lecon table:has(audio):has(td:nth-child(3)):not(:has(td:nth-child(4))):not(:has(ul)):not(:has(ol)) td:nth-child(3) { padding-left: .7rem; font-size: .9rem; }
    .bouton-audio { width: 2.5rem; height: 2.5rem; font-size: 1.15rem; }
}

/* Un encadré (astuce, remarque). */
.lesson-content-lecon .lc-note {
    background-color: #f1f8ff;
    border-left: 4px solid var(--bleu);
    border-radius: 0 .7rem .7rem 0;
    padding: .85rem 1rem;
    margin: 1.1rem 0;
}
.lesson-content-lecon .lc-vocab {
    display: flex;
    align-items: center;
    gap: .8rem;
    padding: .55rem .2rem;
    border-bottom: 1px solid rgba(28, 176, 246, .16);
}
.lesson-content-lecon img { max-width: 100%; height: auto; border-radius: 12px; }

/* La correction montrée après une erreur : lisible, jamais accusatrice. */
.al-correction {
    display: block;
    margin-top: .35rem;
    font-weight: 800;
    color: var(--nuit);
    background: var(--hl-jaune);
    border-radius: .5rem;
    padding: .2rem .55rem;
}

/* ============================================================
   LA MODALE DE L'EXERCICE ET LA PAGE DE FIN
   ============================================================ */
.modale-boite, .al-boite {
    background-color: #fff;
    background-image: none;
    border: 1px solid var(--papier-bord);
}
.modale-boite { border-radius: 22px; box-shadow: 0 30px 80px rgba(20, 45, 80, .35); }
.titre-bloc, .al-fin-titre { font-family: var(--police-cahier); font-weight: 700; }
.titre-bloc { font-size: 1.95rem; }

.barre-fin-lecture { border-top: 2px solid var(--bord-doux); }
.coche-attente { background: linear-gradient(135deg, var(--jaune), var(--orange)); color: #fff; }
.note-fin { margin-top: .9rem; font-size: .88rem; }
.note-fin a { color: var(--texte-doux); text-decoration: underline; }

/* ============================================================
   LA PAGE D'UN CHAPITRE — sa couverture, ses objectifs, ses séances
   (refonte du 10/10/2026)

   Elle ne réinvente rien : mêmes variables, mêmes rayons, mêmes
   ombres pleines sous les boutons que le reste du site.
   ============================================================ */

/* ---- LA COUVERTURE DU CHAPITRE ---- */
.couverture-chapitre {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1.3rem;
    padding: 1.4rem 1.5rem;
    margin: .3rem 0 1.8rem;
    border: 1px solid var(--bord);
    border-radius: var(--r);
    background:
        radial-gradient(circle at 88% -30%, rgba(28, 176, 246, .14), transparent 55%),
        linear-gradient(180deg, var(--blanc), #f7fbff);
    box-shadow: var(--ombre-douce);
}

.couverture-pastille {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 68px;
    height: 68px;
    border-radius: 20px;
    color: #fff;
    background: linear-gradient(160deg, var(--bleu), var(--bleu-fonce));
    box-shadow: 0 4px 0 var(--bleu-ombre);
}
.couverture-numero { font-size: 1.7rem; font-weight: 800; line-height: 1; }
.couverture-mot {
    font-size: .54rem;
    font-weight: 800;
    letter-spacing: .12em;
    text-transform: uppercase;
    opacity: .92;
}

.couverture-texte { flex: 1 1 250px; min-width: 0; }
.couverture-texte h1 { margin: 0; font-size: 1.5rem; line-height: 1.2; color: var(--encre); }
.couverture-native {
    margin: .28rem 0 0;
    font-size: .95rem;
    font-style: italic;
    color: var(--texte-doux);
}
.couverture-meta { margin: .65rem 0 0; font-size: .82rem; color: var(--texte-doux); }
.couverture-meta i { color: var(--bleu); margin-right: .15rem; }

/* L'anneau d'avancement : le repère qui manquait à cette page */
.couverture-avancement { flex: 0 0 auto; display: flex; align-items: center; gap: .7rem; }
.anneau { position: relative; width: 66px; height: 66px; }
.anneau svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.anneau-fond { fill: none; stroke: var(--bord); stroke-width: 4; }
.anneau-valeur {
    fill: none;
    stroke: var(--vert);
    stroke-width: 4;
    stroke-linecap: round;
    transition: stroke-dashoffset .6s ease;
}
.anneau-chiffre {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--encre);
}
.anneau-chiffre small { font-size: .58rem; margin-left: 1px; }
.couverture-avancement-legende {
    font-size: .72rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--texte-doux);
}

/* ---- LES OBJECTIFS ----
   Le manuel donne ses objectifs en puces. On les rend comme on les lit :
   une liste de choses qu'on saura faire, une ligne à la fois, avec une
   coche. Aucune ligne n'est plus grosse que sa voisine — c'était le
   défaut : la moitié des objectifs étaient des titres, l'autre non. */
.encadre-objectifs {
    padding: 1.2rem 1.4rem 1.3rem;
    margin-bottom: 1.9rem;
    border: 1px solid #dcefff;
    border-radius: var(--r);
    background: linear-gradient(180deg, #f5fbff, var(--blanc));
}
.encadre-titre {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: 0 0 .95rem;
    font-size: 1.02rem;
    color: var(--encre);
}
.encadre-titre i { color: var(--jaune-ombre); font-size: 1.15rem; }

.liste-objectifs ul {
    display: grid;
    gap: .45rem;
    margin: 0;
    padding: 0;
    list-style: none;
}
.liste-objectifs li {
    position: relative;
    padding-left: 1.85rem;
    font-size: .95rem;
    line-height: 1.45;
    color: var(--texte);
}
/* La coche, dessinée en CSS : aucune police d'icônes à charger en plus. */
.liste-objectifs li::before {
    content: '';
    position: absolute;
    left: 0;
    top: .4rem;
    width: 1.05rem;
    height: 1.05rem;
    border: 1px solid #cfeeb8;
    border-radius: 50%;
    background: #eaf8de;
}
.liste-objectifs li::after {
    content: '';
    position: absolute;
    left: .31rem;
    top: .6rem;
    width: .4rem;
    height: .21rem;
    border-left: 2px solid var(--vert-fonce);
    border-bottom: 2px solid var(--vert-fonce);
    transform: rotate(-45deg);
}
/* Quelques objectifs restent des paragraphes : on ne les perd pas. */
.liste-objectifs p { margin: 0 0 .7rem; font-size: .95rem; color: var(--texte); }

/* Le chapeau du manuel — la phrase qui annonce le chapitre — et tout ce qu'il
   laisse hors liste. Il garde la plume du cahier, mais se fait plus discret
   qu'un titre de leçon : ici, c'est une note du professeur, pas un titre. */
.encadre-objectifs h3,
.encadre-objectifs h3.lc-sous {
    margin: 0 0 .95rem;
    font-family: var(--police-cahier);
    font-size: 1.22rem;
    font-weight: 700;
    line-height: 1.42;
    color: #b65b1e;
}
.encadre-objectifs em { font-style: italic; }
.encadre-objectifs p {
    margin: 0 0 .8rem;
    font-size: .95rem;
    line-height: 1.5;
    color: var(--texte);
}
.encadre-objectifs > div > section > *:last-child { margin-bottom: 0; }

/* ---- LE TITRE D'UNE SECTION ---- */
.titre-section {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: 2.2rem 0 1rem;
    font-size: 1.12rem;
    color: var(--encre);
}
.titre-section i { color: var(--bleu); font-size: 1.15rem; }

/* ---- UNE SÉANCE ---- */
.carte-seance {
    margin-bottom: 1rem;
    border: 1px solid var(--bord);
    border-radius: var(--r);
    background: var(--blanc);
    overflow: hidden;
    box-shadow: var(--ombre-carte);
}
.carte-seance.est-ouverte  { border-color: #cfe9fb; }
.carte-seance.est-fermee  { background: #fafbfd; }

.seance-entete {
    display: flex;
    align-items: center;
    gap: .85rem;
    padding: .9rem 1.1rem;
    border-bottom: 1px solid var(--bord-doux);
    background: linear-gradient(180deg, #fbfdff, #f5f9fd);
}
.est-ouverte .seance-entete {
    border-bottom-color: #d8eefc;
    background: linear-gradient(180deg, #f2faff, #eaf6ff);
}
.est-terminee .seance-entete {
    border-bottom-color: #dff0cf;
    background: linear-gradient(180deg, #f6fdf0, #eefae4);
}
.est-fermee .seance-entete { background: #f5f7fa; }

.seance-numero {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    font-size: .95rem;
    font-weight: 800;
    color: #7d8b9e;
    background: #e9eef5;
}
.est-ouverte .seance-numero {
    color: #fff;
    background: var(--bleu);
    box-shadow: 0 3px 0 var(--bleu-ombre);
}
.est-terminee .seance-numero {
    color: #fff;
    background: var(--vert);
    box-shadow: 0 3px 0 var(--vert-ombre);
}

.seance-titre { flex: 1; min-width: 0; }
.seance-nom { display: block; font-size: 1rem; font-weight: 800; color: var(--encre); }
.seance-meta { display: block; margin-top: .1rem; font-size: .78rem; color: var(--texte-doux); }
.est-fermee .seance-nom { color: #6b7787; }

.seance-etat {
    flex: 0 0 auto;
    padding: .22rem .62rem;
    border-radius: var(--r-pilule);
    font-size: .72rem;
    font-weight: 800;
}
.etat-ouverte  { color: #1878b8; background: #e3f2ff; }
.etat-terminee { color: #3d8a1f; background: #eaf8de; }
.etat-fermee   { color: #6b7787; background: #eef1f5; }

.seance-note {
    display: flex;
    align-items: flex-start;
    gap: .45rem;
    margin: 0;
    padding: .9rem 1.1rem;
    font-size: .87rem;
    color: var(--texte-doux);
}
.carte-seance .liste-lecons { padding: .9rem 1.1rem 1.1rem; }
.fleche-lecon { color: #c3cbd8; }

/* ---- L'ÉVALUATION ---- */
.carte-evaluation {
    padding: 1.2rem 1.4rem 1.3rem;
    border: 1px solid var(--bord);
    border-radius: var(--r);
    background: var(--blanc);
    box-shadow: var(--ombre-carte);
}
.evaluation-note { margin: 0 0 .85rem; font-size: .87rem; color: var(--texte-doux); }
.evaluation-titre { margin: 0 0 .5rem; font-weight: 800; color: var(--encre); }
.evaluation-etat {
    display: flex;
    align-items: center;
    gap: .45rem;
    margin: 0 0 .35rem;
    font-weight: 800;
}
.etat-verrou      { color: var(--texte-doux); }
.etat-reussie     { color: var(--vert-fonce); }
.etat-disponible  { color: var(--bleu-ombre); }
.evaluation-score { font-size: .85rem; font-weight: 600; color: var(--texte-doux); }
.evaluation-detail { margin: 0 0 .85rem; font-size: .87rem; color: var(--texte); }

/* ---- TÉLÉPHONE ---- */
@media (max-width: 640px) {
    .couverture-chapitre { align-items: flex-start; gap: 1rem; padding: 1.1rem 1.1rem 1.2rem; }
    .couverture-pastille { width: 56px; height: 56px; border-radius: 16px; }
    .couverture-numero { font-size: 1.4rem; }
    .couverture-texte h1 { font-size: 1.25rem; }
    .couverture-avancement { width: 100%; justify-content: flex-start; }
    .anneau { width: 56px; height: 56px; }
    .seance-entete { flex-wrap: wrap; gap: .6rem; }
    .seance-etat { order: 3; margin-left: 2.9rem; }
    .encadre-objectifs { padding: 1rem 1.1rem; }
}

/* ============================================================
   LA PAGE APPRENDRE — reprendre, avancer, et voir où l'on en est
   (refonte du 10/10/2026)

   Trois ajouts à l'ancien chemin :
     - la carte « Reprendre où j'en étais », en haut, qui évite à
       l'élève de chercher sa bulle à la main ;
     - une jauge d'avancement sous le nom de chaque chapitre ;
     - l'évaluation du chapitre, en bout de chemin, comme une
       récompense à décrocher.
   ============================================================ */

/* ---- REPRENDRE OÙ J'EN ÉTAIS ---- */
.carte-reprendre {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1rem 1.2rem;
    margin-bottom: 1.9rem;
    border-radius: var(--r);
    text-decoration: none;
    color: #fff;
    background: linear-gradient(135deg, var(--vert), var(--vert-fonce));
    box-shadow: 0 5px 0 var(--vert-ombre), 0 8px 22px rgba(88, 204, 2, .22);
    transition: transform .18s ease, box-shadow .18s ease;
}
.carte-reprendre:hover,
.carte-reprendre:focus-visible {
    color: #fff;
    transform: translateY(-2px);
    box-shadow: 0 7px 0 var(--vert-ombre), 0 10px 26px rgba(88, 204, 2, .28);
}
/* Le bouton s'écrase quand on clique : c'est la signature du site. */
.carte-reprendre:active {
    transform: translateY(1px);
    box-shadow: 0 3px 0 var(--vert-ombre);
}

.reprendre-icone {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border: 2px solid rgba(255, 255, 255, .45);
    border-radius: 50%;
    font-size: 1.35rem;
    background: rgba(255, 255, 255, .2);
}
.reprendre-texte { flex: 1; min-width: 0; }
.reprendre-mot {
    display: block;
    font-size: .68rem;
    font-weight: 800;
    letter-spacing: .12em;
    text-transform: uppercase;
    opacity: .92;
}
.reprendre-nom { display: block; margin-top: .15rem; font-size: 1.2rem; font-weight: 800; }
.reprendre-meta { display: block; margin-top: .1rem; font-size: .78rem; opacity: .9; }
.reprendre-action {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .55rem .95rem;
    border: 2px solid rgba(255, 255, 255, .5);
    border-radius: var(--r-pilule);
    font-size: .85rem;
    font-weight: 800;
    background: rgba(255, 255, 255, .18);
}
@media (max-width: 640px) {
    .carte-reprendre { flex-wrap: wrap; }
    .reprendre-action { width: 100%; justify-content: center; }
}

/* Rien à reprendre : tout ce qui est ouvert est terminé. La carte reste,
   mais elle se calme — elle informe au lieu d'appeler au clic. */
.carte-reprendre.est-repos {
    background: linear-gradient(135deg, #f2faff, #e8f5ff);
    border: 1px solid #cfe9fb;
    color: var(--encre);
    box-shadow: var(--ombre-carte);
    cursor: default;
}
.carte-reprendre.est-repos .reprendre-icone {
    color: var(--bleu);
    border-color: #bfe3fb;
    background: #e3f2ff;
}
.carte-reprendre.est-repos .reprendre-mot { color: var(--bleu-ombre); opacity: 1; }
.carte-reprendre.est-repos .reprendre-meta { color: var(--texte-doux); opacity: 1; }

/* ---- LA JAUGE D'AVANCEMENT D'UN CHAPITRE ---- */
.titre-chapitre:has(+ .avancement-chapitre) { margin-bottom: .5rem; }

.avancement-chapitre {
    display: flex;
    align-items: center;
    gap: .7rem;
    margin: 0 0 1.5rem;
}
.avancement-jauge {
    flex: 1;
    height: 9px;
    border-radius: var(--r-pilule);
    background: #e9edf3;
    overflow: hidden;
}
.avancement-remplie {
    display: block;
    height: 100%;
    border-radius: var(--r-pilule);
    background: linear-gradient(90deg, var(--vert-clair), var(--vert));
    transition: width .6s ease;
}
.avancement-texte {
    flex: 0 0 auto;
    font-size: .74rem;
    font-weight: 700;
    color: var(--texte-doux);
}

/* ---- LA BULLE DIT LA MATIÈRE ---- */
.bulle-matiere { font-size: 1.9rem; }

/* La coche d'une séance terminée, posée sur le coin de la bulle */
.bulle-coche {
    position: absolute;
    top: -4px;
    right: -4px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 27px;
    height: 27px;
    border: 2px solid var(--blanc);
    border-radius: 50%;
    font-size: .85rem;
    color: #fff;
    background: var(--vert);
    box-shadow: 0 2px 5px rgba(43, 58, 82, .2);
}

/* ---- LE BOUT DU CHEMIN : L'ÉVALUATION ---- */
.bulle-evaluation { font-size: 2rem; }

.bulle-evaluation.est-fermee {
    color: #6b7787;
    background: #e9edf3;
    box-shadow: 0 5px 0 #d4dae3;
}
.bulle-evaluation.est-prete {
    background: linear-gradient(160deg, var(--violet), #a259e0);
    box-shadow: 0 5px 0 #8f45cf;
    animation: bulle-respire-violette 2.4s ease-in-out infinite;
}
.bulle-evaluation.est-reussie {
    background: linear-gradient(160deg, var(--jaune), #f0b400);
    box-shadow: 0 5px 0 var(--jaune-ombre);
}
@keyframes bulle-respire-violette {
    0%, 100% { box-shadow: 0 5px 0 #8f45cf, 0 0 0 0 rgba(206, 130, 255, .42); }
    50%      { box-shadow: 0 5px 0 #8f45cf, 0 0 0 15px rgba(206, 130, 255, 0); }
}

.bulle-cadenas {
    position: absolute;
    bottom: -4px;
    right: -4px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 25px;
    height: 25px;
    border: 2px solid var(--blanc);
    border-radius: 50%;
    font-size: .72rem;
    color: #fff;
    background: #8a95a5;
    box-shadow: 0 2px 5px rgba(43, 58, 82, .18);
}

/* Le libellé de l'évaluation est plus long que celui d'une séance */
.etape-lien:has(.bulle-evaluation) .etiquette-etape { max-width: 190px; }

/* ============================================================
   L'EXERCICE DE FIN DE SÉANCE — la carte qui clôt une séance
   (ajouté le 10/10/2026)

   Elle se distingue des leçons par sa couleur : violette quand elle est
   ouverte, grise tant que les leçons de la séance ne sont pas faites.
   ============================================================ */
.carte-exo-seance {
    margin-top: 1.8rem;
    border: 1px solid var(--bord);
    border-radius: var(--r);
    background: var(--blanc);
    overflow: hidden;
    box-shadow: var(--ombre-carte);
}
.carte-exo-seance.est-ouverte {
    border-color: #e6d5ff;
    background: linear-gradient(180deg, #faf6ff, var(--blanc));
}
.exo-seance-tete { display: flex; align-items: flex-start; gap: .9rem; padding: 1.1rem 1.2rem; }
.exo-seance-icone {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 14px;
    font-size: 1.2rem;
    color: #fff;
    background: #8a95a5;
}
.est-ouverte .exo-seance-icone {
    background: linear-gradient(160deg, var(--violet), #a259e0);
    box-shadow: 0 3px 0 #8f45cf;
}
.exo-seance-texte { flex: 1; min-width: 0; }
.exo-seance-texte h2 { margin: 0 0 .3rem; font-size: 1.05rem; color: var(--encre); }
.exo-seance-texte p { margin: 0; font-size: .87rem; line-height: 1.5; color: var(--texte-doux); }
.exo-seance-pied {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    padding: .9rem 1.2rem;
    border-top: 1px solid var(--bord-doux);
    background: #fbfcfe;
}
.est-ouverte .exo-seance-pied { border-top-color: #eee2ff; background: #fdfaff; }
.exo-seance-compte { font-size: .8rem; font-weight: 700; color: var(--texte-doux); }

@media (max-width: 640px) {
    .exo-seance-pied { justify-content: center; }
    .exo-seance-pied .bouton-principal { width: 100%; justify-content: center; }
    .exo-seance-tete { padding: 1rem; }
}

/* ============================================================
   LE VERROU D'UN CHAPITRE — ajouté le 18/10/2026

   Trois pièces, toutes dessinées avec les mêmes variables que le
   reste du site (angles arrondis, ombre pleine sous l'objet qui
   s'écrase au clic) :
     1. la pilule « Objectifs du chapitre » — page leçon et page séance ;
     2. le gros CADENAS d'ouverture sur apprendre.php, avec le chemin
        gris qui l'attend en dessous ;
     3. le message de félicitations FR / PT, en modale puis en bandeau
        sur chapitre.php.
   ============================================================ */

/* On arrive sur un chapitre du chemin depuis la barre fixe du haut :
   sans marge, son titre passerait dessous. */
.bloc-chapitre { scroll-margin-top: 96px; }

/* ---------- 1. LA PILULE « OBJECTIFS DU CHAPITRE » ---------- */
.jeton-objectifs {
    text-decoration: none;
    border: 2px solid #cfe9fb;
    background: var(--blanc);
    color: var(--bleu-ombre);
    box-shadow: 0 2px 0 #d9edfb;
    cursor: pointer;
    transition: transform .1s ease, box-shadow .1s ease,
                background .15s ease, border-color .15s ease;
}
.jeton-objectifs:hover {
    background: #f2faff;
    border-color: var(--bleu);
    color: var(--bleu-ombre);
    transform: translateY(-1px);
    box-shadow: 0 3px 0 #bfe3fb;
}
.jeton-objectifs:active { transform: translateY(2px); box-shadow: 0 0 0 #bfe3fb; }

/* La pilule vit à côté du compteur de la page séance. */
.entete-etape-suite {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .6rem;
    flex-shrink: 0;
}

/* Le petit cadenas posé sur le nom d'un chapitre verrouillé. */
.verrou-mini { font-size: .78rem; color: #6b7787; margin-left: .35rem; }

/* ---------- 2. UN CHAPITRE FERMÉ : UNE SEULE BULLE ---------- */
/* Ces blocs sont des lignes d'attente, pas des chapitres de cours :
   on les resserre, sinon huit « à venir » occupent plus de place que
   le chapitre que l'élève est en train de faire. */
.chemin-ferme { gap: 1.2rem; }
.etape-avenir { cursor: default; }
.bloc-chapitre.etat-ferme { margin-bottom: 1.3rem; }
.etat-ferme .titre-chapitre { margin-bottom: .95rem; }

/* ---------- 3. LE CHEMIN GRIS DERRIÈRE LE CADENAS ---------- */
/* Les séances sont bien ouvertes par le professeur : on ne les cache
   pas, on les met en sourdine. pointer-events coupe le clic, et les
   liens portent déjà href="#" + tabindex=-1 (côté PHP). */
.chemin-verrouille {
    opacity: .5;
    filter: grayscale(.9);
    pointer-events: none;
    user-select: none;
}

/* ---------- 4. LE CADENAS D'OUVERTURE ---------- */
.verrou-chapitre {
    display: flex;
    align-items: center;
    gap: 1.3rem;
    padding: 1.2rem 1.4rem;
    margin: 0 0 1.6rem;
    border: 2px dashed #bfe3fb;
    border-radius: var(--r);
    background:
        radial-gradient(circle at 14% 50%, rgba(28, 176, 246, .12), transparent 46%),
        linear-gradient(180deg, #f7fbff, var(--blanc));
    transition: border-color .3s ease, background .3s ease;
}

.verrou-cadenas {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .55rem;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}

.cadenas-boite {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 92px;
    height: 92px;
    border-radius: 26px;
    font-size: 2.5rem;
    color: #fff;
    background: linear-gradient(160deg, #3ec3ff, var(--bleu-fonce));
    box-shadow: 0 6px 0 var(--bleu-ombre), 0 14px 26px rgba(28, 176, 246, .3);
    transition: transform .12s ease, box-shadow .12s ease, background .3s ease;
}
/* L'anneau qui appelle le geste — il ne touche pas à l'ombre du bouton,
   sinon l'effet « en relief » du site disparaît. */
.cadenas-boite::after {
    content: '';
    position: absolute;
    inset: -9px;
    border: 3px solid rgba(28, 176, 246, .4);
    border-radius: 33px;
    animation: verrou-anneau 2.4s ease-in-out infinite;
    pointer-events: none;
}
@keyframes verrou-anneau {
    0%, 100% { transform: scale(.95); opacity: .9; }
    50%      { transform: scale(1.07); opacity: .2; }
}

.verrou-cadenas:hover .cadenas-boite { transform: translateY(-2px); }
.verrou-cadenas:active .cadenas-boite {
    transform: translateY(4px);
    box-shadow: 0 2px 0 var(--bleu-ombre), 0 6px 14px rgba(28, 176, 246, .25);
}

/* Les deux cadenas, superposés : le fermé cède la place à l'ouvert. */
.cadenas-boite i {
    position: absolute;
    transition: opacity .35s ease, transform .35s cubic-bezier(.2, .8, .3, 1.3);
}
.cadenas-ferme { opacity: 1; transform: none; }
.cadenas-ouvert { opacity: 0; transform: rotate(-35deg) scale(.45); }

.cadenas-libelle {
    font-size: .7rem;
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--bleu-ombre);
}

.verrou-texte { flex: 1; min-width: 0; }
.verrou-titre { margin: 0; font-size: 1.08rem; font-weight: 800; color: var(--encre); }
.verrou-aide {
    margin: .32rem 0 0;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--texte-doux);
}

/* L'instant du clic : le cadenas s'ouvre, la carte passe au vert. */
.verrou-chapitre.est-ouverte {
    border-style: solid;
    border-color: #cfeeb8;
    background: linear-gradient(180deg, #f8fff1, var(--blanc));
}
.verrou-chapitre.est-ouverte .cadenas-boite {
    background: linear-gradient(160deg, var(--vert-clair), var(--vert-fonce));
    box-shadow: 0 6px 0 var(--vert-ombre), 0 14px 26px rgba(88, 204, 2, .3);
    animation: verrou-pop .45s cubic-bezier(.2, .9, .3, 1.4) both;
}
.verrou-chapitre.est-ouverte .cadenas-boite::after {
    border-color: rgba(88, 204, 2, .45);
    animation: none;
    opacity: 0;
}
.verrou-chapitre.est-ouverte .cadenas-ferme { opacity: 0; transform: rotate(30deg) scale(.45); }
.verrou-chapitre.est-ouverte .cadenas-ouvert { opacity: 1; transform: none; }
.verrou-chapitre.est-ouverte .cadenas-libelle { color: var(--vert-fonce); }
.verrou-chapitre.est-ouverte .verrou-titre { color: var(--vert-fonce); }

@keyframes verrou-pop {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.13); }
    100% { transform: scale(1); }
}

/* ---------- 5. LE MESSAGE DE FÉLICITATIONS ---------- */
.modale-deverrouillage {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 1.2rem;
    background: rgba(20, 45, 80, .55);
    backdrop-filter: blur(7px);
    -webkit-backdrop-filter: blur(7px);
}
.modale-deverrouillage.visible { display: flex; animation: verrou-fondu .28s ease both; }
@keyframes verrou-fondu { from { opacity: 0; } to { opacity: 1; } }

.deverrouillage-boite {
    width: 100%;
    max-width: 470px;
    padding: 2rem 1.6rem 1.7rem;
    border-radius: 26px;
    background: var(--blanc);
    text-align: center;
    box-shadow: 0 34px 70px rgba(20, 45, 80, .4);
    animation: verrou-boite .42s cubic-bezier(.2, .9, .3, 1.25) both;
}
@keyframes verrou-boite {
    from { transform: translateY(20px) scale(.94); opacity: 0; }
    to   { transform: none; opacity: 1; }
}
.deverrouillage-icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 84px;
    height: 84px;
    margin-bottom: 1rem;
    border-radius: 50%;
    font-size: 2.2rem;
    color: #fff;
    background: linear-gradient(160deg, var(--vert-clair), var(--vert-fonce));
    box-shadow: 0 5px 0 var(--vert-ombre);
    animation: verrou-icone .6s .12s ease both;
}
@keyframes verrou-icone {
    from { transform: rotate(-30deg) scale(.7); }
    to   { transform: none; }
}
.deverrouillage-titre { margin: 0; font-size: 1.32rem; font-weight: 800; color: var(--encre); }
.deverrouillage-secondaire {
    margin: .3rem 0 0;
    font-size: 1.04rem;
    font-weight: 700;
    color: var(--vert-fonce);
}
.deverrouillage-suite {
    margin: .95rem 0 1.25rem;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--texte-doux);
}

/* La même joie, en bandeau, en haut de chapitre.php — c'est elle qui
   accueille l'élève venu sans JavaScript, ou depuis une page refusée. */
.bandeau-deverrouillage {
    display: flex;
    align-items: center;
    gap: .95rem;
    padding: .95rem 1.15rem;
    margin: 0 0 1.4rem;
    border: 1px solid #d3efbe;
    border-radius: var(--r);
    background: linear-gradient(135deg, #f2fbe9, var(--blanc));
    box-shadow: var(--ombre-carte);
}
.bienvenue-icone {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    border-radius: 14px;
    font-size: 1.3rem;
    color: #fff;
    background: linear-gradient(160deg, var(--vert-clair), var(--vert-fonce));
    box-shadow: 0 3px 0 var(--vert-ombre);
}
.bienvenue-texte { min-width: 0; }
.bienvenue-fr { display: block; font-size: 1.04rem; font-weight: 800; color: var(--encre); }
.bienvenue-pt { display: block; margin-top: .12rem; font-size: .94rem; font-weight: 700; color: var(--vert-fonce); }
.bienvenue-suite { display: block; margin-top: .4rem; font-size: .86rem; line-height: 1.45; color: var(--texte-doux); }

/* ---------- 6. LA CARTE « UN CHAPITRE VOUS ATTEND » ---------- */
.carte-reprendre.est-cadenas {
    background: linear-gradient(135deg, var(--bleu), var(--bleu-fonce));
    box-shadow: 0 5px 0 var(--bleu-ombre), 0 8px 22px rgba(28, 176, 246, .25);
}
.carte-reprendre.est-cadenas:hover,
.carte-reprendre.est-cadenas:focus-visible {
    box-shadow: 0 7px 0 var(--bleu-ombre), 0 10px 26px rgba(28, 176, 246, .3);
}
.carte-reprendre.est-cadenas:active { box-shadow: 0 3px 0 var(--bleu-ombre); }
.carte-reprendre.est-cadenas .reprendre-mot { color: #eaf7ff; }

/* ---------- 7. TÉLÉPHONE ---------- */
@media (max-width: 640px) {
    .entete-etape-suite { align-items: flex-start; }
    .verrou-chapitre {
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 1rem;
        padding: 1.3rem 1.1rem;
    }
    .cadenas-boite { width: 84px; height: 84px; font-size: 2.2rem; }
    .bandeau-deverrouillage { align-items: flex-start; }
    .deverrouillage-boite { padding: 1.6rem 1.2rem 1.4rem; }
}


/* ============================================================
   LA BARRE D'APERÇU — « voir le site comme l'élève »
   (habillage sorti de includes/apercu_session.php le 18/10/2026 :
   une page ne porte pas de CSS, même quand c'est du PHP qui l'écrit)

   Elle occupe le haut de l'écran, et l'en-tête du site — qui est en
   position fixe — descend de sa hauteur au lieu d'être recouvert.
   ':has()' évite de toucher au <body> du site.
   ============================================================ */

#apercu-barre {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 1100;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 0 16px;
    box-sizing: border-box;
    background: #22304a;
    color: #e8eef7;
    font-family: var(--police-titre);
    font-size: .95rem;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .25);
}
body:has(#apercu-barre) { padding-top: calc(80px + 46px); }
body:has(#apercu-barre) .app-header { top: 46px; }
@media (max-width: 768px) {
    body:has(#apercu-barre) { padding-top: calc(70px + 46px); }
}

.apercu-titre { display: flex; align-items: center; gap: 9px; min-width: 0; }
.apercu-oeil { flex: 0 0 auto; }
.apercu-oeil path { stroke: #9db4d0; stroke-width: 2; }
.apercu-oeil circle { fill: #9db4d0; }
.apercu-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.apercu-nom strong { color: #fff; }
.apercu-quitter {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 15px;
    border-radius: 10px;
    background: var(--rouge, #e94560);
    color: #fff;
    font-weight: 700;
    text-decoration: none;
    box-shadow: 0 3px 0 #b3304a;
}
.apercu-quitter:hover { background: #f05670; color: #fff; }
.apercu-croix { font-weight: 800; }


/* ============================================================
   LA PHOTO DE PROFIL, EN GRAND
   Utilisée par l'accueil et par « Mon évolution » : c'est un
   composant PARTAGÉ, donc il vit ici et pas dans une page — les deux
   pages la définissaient séparément, avec les mêmes valeurs.
   ============================================================ */
.welcome-avatar-wrapper {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    border-style: solid;
    border-width: 4px;
    padding: 3px;
    flex-shrink: 0;
}
.welcome-avatar {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}

/* ============================================================
   WIDGETS D'ACCUEIL & LIQUID GLASS — ajouté le 18/10/2026
   ------------------------------------------------------------
   Système de composants « verre » pour la grille d'accueil.
   Les variables --verre*, --blur-*, --deg-* vivent dans theme.css.
   Aucun sélecteur existant n'est modifié : tout est ajouté ici.
   ============================================================ */

/* ---------- La grille 12 colonnes ---------- */
.accueil-grille {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 16px;
    width: 100%;
    max-width: var(--largeur);
    margin: 0 auto;
}

/* ---------- Apparition des widgets au chargement ---------- */
@keyframes widget-apparition {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ---------- La carte en verre ---------- */
.widget {
    position: relative;
    background: var(--verre);
    backdrop-filter: var(--blur-verre);
    -webkit-backdrop-filter: var(--blur-verre);
    border: 1px solid var(--verre-bord);
    border-radius: var(--r);
    box-shadow: var(--verre-ombre);
    overflow: hidden;
    transition: transform .25s ease, box-shadow .25s ease;
    animation: widget-apparition .5s ease both;
}

/* ---------- Les tailles (grid-column) ---------- */
.widget--large { grid-column: span 12; }
.widget--moyen  { grid-column: span 6; }
.widget--petit  { grid-column: span 4; }
.widget--liste  { grid-column: span 4; }

/* ---------- En-tête et corps du widget ---------- */
.widget-tete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--verre-bord);
}
.widget-titre {
    font-family: var(--police-titre);
    font-weight: 800;
    font-size: 1.05rem;
    color: var(--encre);
    margin: 0;
}
.widget-corps { padding: 1.25rem; }
/* Quand une tête est présente, le corps ne redouble pas le padding haut. */
.widget-tete + .widget-corps { padding-top: 0; }

/* ---------- Mode édition ----------
   .accueil--edition se pose sur le CONTENEUR de la grille quand on
   réorganise son accueil. C'est elle qui révèle poignées et actions :
   hors édition, elles restent masquées. */
.widget-poignee {
    display: none;
    cursor: grab;
    opacity: .5;
    color: var(--texte-doux);
    font-size: 1.1rem;
    line-height: 1;
    transition: opacity .15s ease;
}
.widget-poignee:active { cursor: grabbing; }
.widget-actions { display: none; align-items: center; gap: .5rem; }
.accueil--edition .widget-poignee { display: inline-flex; align-items: center; }
.accueil--edition .widget-actions { display: flex; }

.widget-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--verre-fort);
    border: 1px solid var(--verre-bord);
    color: var(--texte);
    font-size: .9rem;
    line-height: 1;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, transform .1s ease;
}
.widget-action:hover { background: var(--blanc); color: var(--encre); }
.widget-action:active { transform: translateY(1px); }

/* Un widget retiré de l'accueil : estompé et inerte. */
.widget.est-masque {
    opacity: .35;
    filter: saturate(.6);
    pointer-events: none;
}

/* La classe posée pendant le glisser-déposer. */
.widget-survol {
    outline: 2px dashed var(--bleu);
    outline-offset: 2px;
}

/* ---------- Commutateur « liquid glass » ---------- */
.verre-switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .55);
    border: 1px solid var(--verre-bord);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    cursor: pointer;
    transition: background .25s ease, border-color .25s ease;
}
.verre-switch::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--blanc);
    box-shadow: 0 1px 3px rgba(43, 58, 82, .28);
    transition: transform .25s ease;
}
.verre-switch.actif {
    background: var(--deg-vert);
    border-color: transparent;
}
.verre-switch.actif::after { transform: translateX(20px); }

/* ---------- Bouton « verre » ----------
   Même tranche 3D que le système .btn : il se soulève au survol et
   s'enfonce au clic. Combiné à .btn, les variables ci-dessous
   reprennent le dessus (même spécificité, déclarées après). */
.btn-verre {
    --fond: var(--verre-fort);
    --fond-survol: var(--blanc);
    --fond-clic: var(--verre-tres-fort);
    --ombre-couleur: rgba(43, 58, 82, .16);
    --texte-bouton: var(--encre);

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .78rem 1.55rem;
    background: var(--verre-fort);
    border: 1px solid var(--verre-bord);
    border-radius: var(--r-pilule);
    color: var(--encre);
    font-family: var(--police-titre);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .5px;
    font-size: .95rem;
    cursor: pointer;
    backdrop-filter: var(--blur-verre);
    -webkit-backdrop-filter: var(--blur-verre);
    box-shadow: 0 4px 0 rgba(43, 58, 82, .16);
    transition: background-color .18s ease, box-shadow .18s ease, transform .12s ease;
}
.btn-verre:hover {
    background: var(--blanc);
    color: var(--encre);
    transform: translateY(-2px);
    box-shadow: 0 6px 0 rgba(43, 58, 82, .16);
}
.btn-verre:active {
    transform: translateY(1px);
    box-shadow: 0 2px 0 rgba(43, 58, 82, .16);
}

/* ---------- Téléphone : une seule colonne ---------- */
@media (max-width: 768px) {
    .widget--large,
    .widget--moyen,
    .widget--petit,
    .widget--liste {
        grid-column: span 12;
    }
}

/* ============================================================
   LE LIEN SECONDAIRE DE LA BARRE DE FIN — 02/11/2026
   Une leçon sans carte ni exercice propose « J'ai terminé cette
   leçon » (bouton vert) ET la possibilité de lire la suivante
   sans valider. Ce lien doit rester discret : une seule action
   principale par écran.
   ============================================================ */
.note-fin-lien {
    font-size: .88rem;
    font-weight: 700;
    color: var(--texte-doux);
    text-decoration: underline;
    text-underline-offset: 3px;
}
.note-fin-lien:hover { color: var(--encre); }
