/* =============================================================================
   SHADOW ACADEMY - Style des pages
   -----------------------------------------------------------------------------
   Le chassis (jetons, base, en-tete, pied, boutons, formulaires) est dans
   app.css. Cette feuille ne contient que ce qui est propre a une page.

   Le motif structurant du site est la GOUTTIERE : une colonne etroite a
   gauche du contenu, portant un marqueur (un numero, une coche, un cadenas,
   un etat de test). Elle vient de la gouttiere de numeros de ligne d'un
   editeur de code, qui est le vocabulaire du sujet.

   Elle n'est employee que la ou le contenu est REELLEMENT ordonne ou porte un
   etat : chapitres, lecons, exercices, resultats de tests. Ailleurs la
   structure est un tableau de specification (terme | definition), qui est le
   vocabulaire de la documentation. Aucune grille de cartes identiques.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   1. ACCUEIL
   -------------------------------------------------------------------------- */

.heros {
    padding: var(--v-6) 0 var(--v-5);
    border-bottom: 1px solid var(--sf-line-soft);
}

/* Asymetrique et aligne a gauche. Un heros centre est le reglage par defaut
   de n'importe quelle page : il ne dit rien de celle-ci. */
.heros__grille {
    display: grid;
    grid-template-columns: 1.15fr 1fr;
    gap: var(--v-5);
    align-items: center;
}

.heros__titre {
    font-size: var(--t-3xl);
    line-height: 1.04;
    letter-spacing: -0.005em;
    margin: 0 0 var(--v-3);
    max-width: 15ch;
}

.heros__texte {
    font-size: var(--t-base);
    line-height: 1.7;
    color: var(--sf-text-dim);
    max-width: 52ch;
    margin-bottom: var(--v-4);
}

.heros__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--v-2);
    margin-bottom: var(--v-3);
}

.heros__promesse {
    font-family: var(--sf-font-mono);
    font-size: var(--t-sm);
    color: var(--sf-ok);
    margin: 0;
}

/* --- La demonstration : le premier exercice du site, rendu tel quel ---------
   Le heros montre le produit au lieu de le decrire. Ce que le visiteur voit
   ici est exactement ce qu'il verra a l'ecran suivant. */

.demo {
    border: 1px solid var(--sf-line);
    background: var(--sf-void);
    box-shadow: var(--sf-shadow);
    font-size: var(--t-md);
    overflow: hidden;
}

.demo__barre {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--v-2);
    padding: 9px 14px;
    background: var(--sf-surface);
    border-bottom: 1px solid var(--sf-line);
}

.demo__fichier {
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-text-dim);
}

.demo__etat {
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-text-faint);
}

/* Les numeros de ligne viennent d'un compteur CSS : ils ne sont pas dans le
   HTML, donc ni selectionnables ni lus a voix haute. */
.demo__code {
    counter-reset: ligne;
    list-style: none;
    margin: 0;
    padding: var(--v-2) 0;
    font-family: var(--sf-font-mono);
    font-size: var(--t-sm);
    line-height: 1.85;
    color: var(--sf-text);
}

.demo__code li {
    counter-increment: ligne;
    padding-left: 52px;
    position: relative;
    min-height: 1.85em;
    white-space: pre;
}

.demo__code li::before {
    content: counter(ligne);
    position: absolute;
    left: 0;
    width: 34px;
    text-align: right;
    color: var(--sf-text-faint);
    opacity: .65;
}

.demo__fn     { color: var(--sf-cyan); }
.demo__chaine { color: var(--sf-ok); }
.demo__comm   { color: var(--sf-text-faint); }

/* Le curseur, a la fin de la derniere ligne. Immobile : une animation qui
   tourne en permanence dans le champ de vision finit par gener la lecture. */
.demo__curseur {
    display: inline-block;
    width: 8px;
    height: 1.05em;
    background: var(--sf-violet);
    vertical-align: -2px;
}

.demo__console {
    border-top: 1px solid var(--sf-line);
    background: var(--ink);
    padding: 12px 14px;
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    line-height: 1.8;
}

.demo__test {
    display: flex;
    align-items: center;
    gap: var(--v-1);
    margin: 0;
    color: var(--sf-text-dim);
}

.demo__test::before {
    content: "";
    width: 7px;
    height: 7px;
    flex: none;
    background: var(--sf-ok);
}

.demo__bilan {
    margin: 4px 0 0;
    color: var(--sf-ok);
}

/* --- Bande de chiffres ------------------------------------------------------
   Ce que contient reellement le site, lu dans la base. En monospace : ce sont
   des donnees, pas un argument commercial. */

.chiffres {
    display: flex;
    flex-wrap: wrap;
    border-top: 1px solid var(--sf-line-soft);
    border-bottom: 1px solid var(--sf-line-soft);
    margin: var(--v-5) 0;
}

/* Contenu centre dans sa colonne, et rembourrage symetrique. Avec un
   rembourrage a droite seulement, le chiffre des colonnes 2 et suivantes
   venait se coller au filet qui les precede : la bande paraissait desequilibree
   alors que les colonnes, elles, etaient bien egales. */
.chiffre {
    flex: 1 1 140px;
    padding: var(--v-3) var(--v-2);
    border-right: 1px solid var(--sf-line-soft);
    text-align: center;
}

.chiffre:last-child { border-right: 0; }

.chiffre__valeur {
    display: block;
    font-family: var(--sf-font);
    font-size: 2rem;
    font-weight: 700;
    line-height: 1;
    color: var(--sf-text);
    font-variant-numeric: tabular-nums;
}

.chiffre__quoi {
    display: block;
    margin-top: 5px;
    font-size: var(--t-sm);
    color: var(--sf-text-faint);
}

/* --- Les trois principes, en tableau de specification -----------------------
   Terme a gauche, definition a droite, un filet entre chaque ligne. C'est la
   forme d'une page de documentation : elle appartient au sujet, contrairement
   a trois cartes identiques cote a cote. */

.principes { padding-bottom: var(--v-5); }

.principes__titre {
    font-size: var(--t-xl);
    margin: 0 0 var(--v-3);
    color: var(--sf-text-dim);
    font-weight: 600;
}

.principe {
    display: grid;
    grid-template-columns: 15rem 1fr;
    gap: var(--v-4);
    padding: var(--v-3) 0;
    border-top: 1px solid var(--sf-line-soft);
}

.principe:last-child { border-bottom: 1px solid var(--sf-line-soft); }

.principe__terme {
    font-family: var(--sf-font);
    font-size: var(--t-lg);
    font-weight: 700;
    line-height: 1.2;
    color: var(--sf-text);
    margin: 0;
}

.principe__texte {
    color: var(--sf-text-dim);
    max-width: var(--mesure);
    margin: 0;
}

/* -----------------------------------------------------------------------------
   2. CATALOGUE DES LANGAGES
   Une liste de lignes pleine largeur, pas une grille de cartes : avec un seul
   langage publie, une grille d'un element parait cassee.
   -------------------------------------------------------------------------- */

.section-catalogue { padding: var(--v-5) 0; }

.section-catalogue__intro {
    color: var(--sf-text-dim);
    max-width: var(--mesure);
    margin: var(--v-2) 0 var(--v-4);
}

.liste-langues {
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--sf-line-soft);
}

/* L'echine coloree a gauche porte la couleur du langage, lue dans la base.
   Elle s'epaissit au survol : le mouvement designe la ligne visee. */
.carte-langue {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--v-2) var(--v-4);
    align-items: center;
    padding: var(--v-3);
    border-bottom: 1px solid var(--sf-line-soft);
    border-left: 3px solid var(--teinte, var(--sf-violet));
    text-decoration: none;
    color: inherit;
    transition: background var(--sf-fast) var(--sf-ease),
                border-left-width var(--sf-fast) var(--sf-ease),
                padding-left var(--sf-fast) var(--sf-ease);
}

.carte-langue:hover {
    background: var(--sf-surface);
    border-left-width: 6px;
    padding-left: 21px;
    color: inherit;
}

.carte-langue__titre {
    font-size: var(--t-xl);
    margin: 0 0 4px;
    color: var(--sf-text);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--v-1);
}

.carte-langue__description {
    color: var(--sf-text-dim);
    max-width: 62ch;
    margin: 0;
    font-size: var(--t-md);
}

/* Second groupe du catalogue (les parcours) : un filet le separe des
   langages, comme une nouvelle section d'un sommaire. */
.section-catalogue__groupe {
    margin-top: var(--v-5);
    padding-top: var(--v-4);
    border-top: 1px solid var(--sf-line);
}

/* Branche a suivre avant : indicatif, donc discret. */
.carte-langue__prerequis {
    display: flex;
    align-items: baseline;
    gap: var(--v-1);
    margin: var(--v-1) 0 0;
    font-size: var(--t-sm);
    color: var(--sf-text-faint);
}

.carte-langue__chiffres {
    grid-column: 2;
    grid-row: 1 / span 2;
    display: flex;
    gap: var(--v-3);
    margin: 0;
    text-align: right;
}

.carte-langue__chiffre strong {
    display: block;
    font-family: var(--sf-font);
    font-size: var(--t-lg);
    font-weight: 700;
    color: var(--sf-text);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.carte-langue__chiffre span {
    font-size: var(--t-xs);
    color: var(--sf-text-faint);
}

/* -----------------------------------------------------------------------------
   3. SOMMAIRE D'UN LANGAGE
   La page la plus structurelle du site : les chapitres sont numerotes dans la
   gouttiere parce qu'ils forment une SEQUENCE reelle, et les lecons pendent
   d'un filet vertical qui les relie a leur chapitre.
   -------------------------------------------------------------------------- */

.entete-langue { padding: var(--v-5) 0 var(--v-3); }

.entete-langue h1 {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--v-1);
    margin-bottom: var(--v-2);
}

.entete-langue__description {
    color: var(--sf-text-dim);
    max-width: var(--mesure);
    margin-bottom: var(--v-2);
}

.sommaire { padding-bottom: var(--v-5); }

.chapitre {
    display: grid;
    grid-template-columns: var(--gouttiere) 1fr;
    gap: 0 var(--v-3);
    padding-bottom: var(--v-4);
}

.chapitre__numero {
    grid-row: 1 / span 2;
    font-family: var(--sf-font-mono);
    font-size: var(--t-md);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    color: var(--sf-violet-bright);
    text-align: right;
    padding-top: 3px;
    position: relative;
}

/* Le filet qui descend du numero jusqu'au bas du chapitre : il rend la
   hierarchie visible sans un seul mot. */
.chapitre__numero::after {
    content: "";
    position: absolute;
    top: 30px;
    right: 6px;
    bottom: 8px;
    width: 1px;
    background: var(--sf-line);
}

.chapitre__titre {
    font-size: var(--t-xl);
    margin: 0 0 4px;
}

.chapitre__description {
    color: var(--sf-text-faint);
    font-size: var(--t-md);
    max-width: var(--mesure);
    margin: 0 0 var(--v-2);
}

.liste-lecons {
    grid-column: 2;
    list-style: none;
    margin: 0;
    padding: 0;
}

.lecon-item + .lecon-item { border-top: 1px solid var(--sf-line-soft); }

.lecon-item a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--v-3);
    padding: 11px 12px 11px 0;
    text-decoration: none;
    color: var(--sf-text-dim);
    transition: color var(--sf-fast) var(--sf-ease),
                padding-left var(--sf-fast) var(--sf-ease);
}

.lecon-item a:hover {
    color: var(--sf-text);
    padding-left: 6px;
}

.lecon-item__titre {
    font-size: var(--t-md);
    font-weight: 500;
}

.lecon-item__exercices {
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-text-faint);
    white-space: nowrap;
}

/* Lecon deja validee : un point vert en fin de titre. */
.lecon-item--lue .lecon-item__titre::after {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-left: var(--v-1);
    border-radius: 50%;
    background: var(--sf-ok);
    vertical-align: 2px;
}

/* -----------------------------------------------------------------------------
   4. LECON
   La surface de lecture. C'est la page la plus calme du site : une colonne,
   une mesure courte, beaucoup d'air. Elle ne doit surtout PAS ressembler a
   l'atelier.
   -------------------------------------------------------------------------- */

.page-lecon {
    max-width: 800px;
    padding: var(--v-5) var(--v-3);
}

.page-lecon > h1 {
    font-size: clamp(1.9rem, 4vw, 2.5rem);
    margin-bottom: var(--v-4);
    padding-bottom: var(--v-3);
    border-bottom: 1px solid var(--sf-line-soft);
}

.contenu-lecon {
    max-width: var(--mesure);
    font-size: var(--t-base);
    line-height: 1.75;
    color: #DFDAEE;
}

.contenu-lecon > * + * { margin-top: var(--v-2); }

.contenu-lecon h2 {
    font-size: var(--t-xl);
    margin-top: var(--v-5);
    margin-bottom: var(--v-2);
    color: var(--sf-text);
}

.contenu-lecon h3 {
    font-size: var(--t-lg);
    margin-top: var(--v-4);
    margin-bottom: var(--v-1);
    color: var(--sf-text);
}

.contenu-lecon ul,
.contenu-lecon ol {
    padding-left: 1.35em;
    margin-top: var(--v-2);
}

.contenu-lecon li { margin-bottom: 6px; }
.contenu-lecon li::marker { color: var(--sf-text-faint); }

.contenu-lecon strong { color: var(--sf-text); font-weight: 600; }

/* Bloc de code : sur le fond le plus sombre du site, avec un filet violet a
   gauche. Il deborde legerement de la mesure, parce qu'une ligne de code ne
   se coupe pas comme une phrase. */
.contenu-lecon pre {
    margin: var(--v-3) 0;
    padding: var(--v-2) var(--v-3);
    background: var(--sf-void);
    border: 1px solid var(--sf-line-soft);
    border-left: 3px solid var(--sf-violet);
    overflow-x: auto;
    font-size: var(--t-md);
    line-height: 1.7;
    color: #D8D3EC;
    max-width: calc(var(--mesure) + 6rem);
}

.contenu-lecon pre code {
    background: none;
    border: 0;
    padding: 0;
    color: inherit;
    font-size: inherit;
}

.contenu-lecon blockquote {
    margin: var(--v-3) 0;
    padding: var(--v-1) 0 var(--v-1) var(--v-3);
    border-left: 2px solid var(--sf-line);
    color: var(--sf-text-dim);
}

.contenu-lecon table {
    width: 100%;
    border-collapse: collapse;
    margin: var(--v-3) 0;
    font-size: var(--t-md);
}

.contenu-lecon th,
.contenu-lecon td {
    text-align: left;
    padding: 9px 12px 9px 0;
    border-bottom: 1px solid var(--sf-line-soft);
}

.contenu-lecon th {
    font-family: var(--sf-font);
    font-weight: 700;
    letter-spacing: var(--piste);
    color: var(--sf-text);
}

/* --- Le point de controle ---------------------------------------------------
   Une bande pleine largeur entre deux filets, pas une carte. C'est un
   passage, pas un objet. */

.validation {
    margin: var(--v-5) 0 var(--v-4);
    padding: var(--v-3) 0;
    border-top: 1px solid var(--sf-line);
    border-bottom: 1px solid var(--sf-line);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--v-2) var(--v-3);
}

.validation__message {
    flex: 1 1 22rem;
    margin: 0;
    font-family: var(--sf-font);
    font-size: var(--t-lg);
    font-weight: 600;
    color: var(--sf-text);
}

.validation__aide {
    flex-basis: 100%;
    margin: 0;
    font-size: var(--t-sm);
    color: var(--sf-text-faint);
    max-width: 62ch;
}

.validation--faite { border-color: rgba(45, 212, 167, .35); }

.validation--faite .validation__message {
    display: flex;
    align-items: center;
    gap: var(--v-1);
    color: var(--sf-ok);
}

/* --- Les exercices de la lecon --------------------------------------------- */

.bloc-exercices { margin-bottom: var(--v-5); }

.bloc-exercices h2 {
    font-size: var(--t-lg);
    margin-bottom: var(--v-2);
}

.liste-exercices {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--sf-line-soft);
}

.exercice-item { border-bottom: 1px solid var(--sf-line-soft); }

/* Une seule definition de grille pour la ligne d'exercice, qu'elle soit
   cliquable ou verrouillee : les deux etats s'alignent alors exactement. */
.exercice-item__lien {
    display: grid;
    grid-template-columns: var(--gouttiere) 1fr auto auto;
    align-items: center;
    gap: var(--v-2) var(--v-3);
    padding: 13px 0;
    text-decoration: none;
    color: var(--sf-text);
    transition: background var(--sf-fast) var(--sf-ease);
}

a.exercice-item__lien:hover {
    background: var(--sf-surface);
    color: var(--sf-text);
}

/* Le marqueur d'etat, dans la gouttiere. Dessine en CSS plutot qu'ecrit dans
   le HTML : un lecteur d'ecran n'a pas a epeler un cadenas, l'etat lui est
   donne par le texte de la ligne. */
.exercice-item__cadenas {
    justify-self: end;
    width: 15px;
    height: 15px;
    border: 1px solid var(--sf-line);
    position: relative;
    flex: none;
}

.exercice-item--reussi .exercice-item__cadenas {
    border-color: var(--sf-ok);
    background: rgba(45, 212, 167, .16);
}

/* La coche est tracee avec deux bords d'une boite pivotee : pas de police
   d'icones a charger, pas de SVG a inliner. */
.exercice-item--reussi .exercice-item__cadenas::after {
    content: "";
    position: absolute;
    left: 4px;
    top: 1px;
    width: 4px;
    height: 8px;
    border: solid var(--sf-ok);
    border-width: 0 2px 2px 0;
    transform: rotate(42deg);
}

.exercice-item--entame .exercice-item__cadenas { border-color: var(--sf-warn); }

.exercice-item--entame .exercice-item__cadenas::after {
    content: "";
    position: absolute;
    inset: 3px;
    background: var(--sf-warn);
}

.exercice-item--verrouille .exercice-item__cadenas {
    border-color: var(--sf-line-soft);
    background: repeating-linear-gradient(
        135deg,
        transparent 0 3px,
        var(--sf-line-soft) 3px 4px
    );
}

.exercice-item--verrouille .exercice-item__lien {
    color: var(--sf-text-faint);
    cursor: default;
}

.exercice-item__titre {
    font-family: var(--sf-font);
    font-size: var(--t-base);
    font-weight: 600;
    letter-spacing: var(--piste);
    text-decoration: none;
    color: inherit;
}

.exercice-item__xp {
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-text-faint);
    white-space: nowrap;
    text-align: right;
    min-width: 9rem;
}

.exercice-item--reussi .exercice-item__xp { color: var(--sf-ok); }

/* --- Navigation entre lecons ----------------------------------------------- */

.navigation-lecon {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--v-2);
    margin-top: var(--v-5);
    padding-top: var(--v-3);
    border-top: 1px solid var(--sf-line-soft);
}

.navigation-lecon__lien {
    display: block;
    padding: var(--v-2) var(--v-3);
    border: 1px solid var(--sf-line-soft);
    text-decoration: none;
    transition: border-color var(--sf-fast) var(--sf-ease),
                background var(--sf-fast) var(--sf-ease);
}

.navigation-lecon__lien:hover {
    border-color: var(--sf-violet);
    background: var(--sf-surface);
}

.navigation-lecon__lien--suivant {
    text-align: right;
    grid-column: 2;
}

.navigation-lecon__sens {
    display: block;
    font-family: var(--sf-font);
    font-size: var(--t-sm);
    font-weight: 600;
    letter-spacing: var(--piste);
    color: var(--sf-text-faint);
    margin-bottom: 3px;
}

.navigation-lecon__titre {
    display: block;
    font-family: var(--sf-font);
    font-size: var(--t-md);
    font-weight: 700;
    color: var(--sf-text);
}

/* -----------------------------------------------------------------------------
   5. ATELIER
   Ici on assume l'outil : plein ecran, fond le plus sombre, panneaux separes
   par un filet, aucune marge perdue. C'est le contraire exact de la lecon.
   -------------------------------------------------------------------------- */

.atelier {
    display: grid;
    grid-template-columns: minmax(320px, 27rem) 1fr;
    /* La ligne DOIT etre declaree. Sans elle, la ligne implicite prend la
       hauteur de son contenu : sur un ecran de portable, la console d'une
       reussite (badges, tests, solution) faisait 1500 px dans un cadre de
       600, et la solution sortait de l'ecran. minmax(0, 1fr) fixe la ligne a
       la hauteur du cadre : ce sont les panneaux qui defilent. */
    grid-template-rows: minmax(0, 1fr);
    /* L'atelier occupe toute la hauteur disponible sous l'en-tete : l'editeur
       doit etre le plus haut possible. */
    height: calc(100vh - var(--entete-h));
    background: var(--sf-void);
    border-top: 1px solid var(--sf-line-soft);
}

.atelier__enonce {
    /* Meme raison que pour .console : sans min-height: 0, un element de grille
       refuse de rétrécir sous la hauteur de son contenu, et un enonce long
       deborderait du cadre au lieu de defiler. */
    min-height: 0;

    overflow-y: auto;
    padding: var(--v-3) var(--v-3) var(--v-5);
    border-right: 1px solid var(--sf-line);
    background: var(--ink);
}

.atelier__enonce h1 {
    font-size: 1.6rem;
    margin-bottom: var(--v-2);
}

.atelier__enonce h2 {
    font-size: var(--t-md);
    letter-spacing: var(--piste);
    color: var(--sf-text-dim);
    margin: var(--v-4) 0 var(--v-2);
    padding-bottom: 6px;
    border-bottom: 1px solid var(--sf-line-soft);
}

.atelier__meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--v-2);
    margin-bottom: var(--v-3);
    padding-bottom: var(--v-3);
    border-bottom: 1px solid var(--sf-line-soft);
}

.atelier__xp {
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-pink);
}

.atelier__reussi {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--sf-font);
    font-size: var(--t-sm);
    font-weight: 600;
    letter-spacing: var(--piste);
    color: var(--sf-ok);
}

.atelier__description {
    color: var(--sf-text-dim);
    font-size: var(--t-md);
    line-height: 1.7;
}

.atelier__consignes {
    margin: 0;
    padding-left: 1.3em;
    font-size: var(--t-md);
    line-height: 1.7;
    color: var(--sf-text);
}

.atelier__consignes li { margin-bottom: var(--v-1); }
.atelier__consignes li::marker { color: var(--sf-violet-bright); font-weight: 600; }

/* Les tests annonces : des cases vides, que la console remplira. Cela cree
   une continuite visuelle entre la promesse et le resultat. */
.atelier__tests {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: var(--t-md);
}

.atelier__tests li {
    display: flex;
    align-items: baseline;
    gap: var(--v-2);
    padding: 5px 0;
    color: var(--sf-text-dim);
}

.atelier__tests li::before {
    content: "";
    width: 9px;
    height: 9px;
    flex: none;
    border: 1px solid var(--sf-line);
    transform: translateY(1px);
}

.atelier__note {
    margin-top: var(--v-2);
    font-size: var(--t-sm);
    color: var(--sf-text-faint);
    line-height: 1.6;
}

.atelier__retour {
    margin-top: var(--v-4);
    padding-top: var(--v-3);
    border-top: 1px solid var(--sf-line-soft);
    font-size: var(--t-md);
}

/* --- Colonne de droite : editeur et console -------------------------------- */

.atelier__travail {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) minmax(160px, 38%);
    min-width: 0;
    /* Meme regle que partout dans l'atelier : un element de grille refuse
       sinon de devenir plus petit que son contenu. */
    min-height: 0;
}

/* La barre d'outils, traitee comme la barre d'etat d'un editeur : dense,
   monospace pour les donnees, actions a droite. */
.atelier__barre {
    display: flex;
    align-items: center;
    gap: var(--v-2);
    padding: 8px var(--v-2);
    background: var(--sf-surface);
    border-bottom: 1px solid var(--sf-line);
}

.atelier__theme {
    display: inline-flex;
    align-items: center;
    gap: var(--v-1);
    font-family: var(--sf-font);
    font-size: var(--t-sm);
    font-weight: 600;
    letter-spacing: var(--piste);
    color: var(--sf-text-faint);
}

.atelier__theme select {
    padding: 5px 8px;
    background: var(--sf-void);
    border: 1px solid var(--sf-line);
    color: var(--sf-text);
    font-family: var(--sf-font-body);
    font-size: var(--t-sm);
    cursor: pointer;
}

.atelier__etat {
    margin-right: auto;
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-text-faint);
    /* Reserve sa place : sans cela, l'apparition du message deplace les
       boutons juste au moment ou l'on veut cliquer. */
    min-height: 1em;
}

.atelier__barre .bouton {
    padding: 7px 14px;
    font-size: var(--t-sm);
}

.atelier__editeur {
    min-height: 0;
    background: var(--sf-void);
}

/* La zone de travail : l'editeur seul, ou l'editeur et l'apercu cote a cote
   pour les exercices HTML et CSS. Meme regle min-height: 0 que partout dans
   l'atelier, pour que les panneaux se partagent la hauteur au lieu de
   deborder. */
.atelier__zone {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    min-height: 0;
}

.atelier__zone--apercu {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

/* --- L'apercu ---------------------------------------------------------------
   Une page web rendue : elle s'affiche comme une page web, sur fond blanc,
   sans habillage. Seule sa legende reprend le vocabulaire de l'atelier. */
.apercu {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    min-height: 0;
    margin: 0;
    border-left: 1px solid var(--sf-line);
}

.apercu__legende {
    display: flex;
    align-items: baseline;
    gap: var(--v-1);
    padding: 6px var(--v-2);
    background: var(--sf-surface);
    border-bottom: 1px solid var(--sf-line);
}

.apercu__detail {
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-text-faint);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.apercu__cadre {
    width: 100%;
    height: 100%;
    border: 0;
    /* Une iframe est transparente par defaut : sans ce fond, une page sans
       couleur de fond laisserait voir l'atelier sombre au travers. */
    background: #ffffff;
}

/* Apercu JavaScript : un bouton Lancer dans la legende, et sous la page, la
   console du script -- ce qu'affiche console.log dans un vrai navigateur. */
.apercu--script {
    grid-template-rows: auto minmax(0, 1fr) auto;
}

.apercu__legende .bouton {
    margin-left: auto;
    padding: 2px 12px;
    font-size: var(--t-xs);
}

.apercu__console {
    max-height: 9rem;
    min-height: 2.6rem;
    margin: 0;
    padding: 6px var(--v-2);
    overflow: auto;
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--sf-text-dim);
    background: var(--sf-void);
    border-top: 1px solid var(--sf-line);
}

/* Une erreur : la couleur ET un filet epais, jamais la couleur seule. */
.apercu__console--erreur {
    color: var(--sf-danger);
    border-top: 3px solid var(--sf-danger);
}

/* --- La console ------------------------------------------------------------
   Sortie de terminal : monospace, fond noir, un filet en haut. Les etats sont
   portes par la couleur ET par une forme, jamais par la couleur seule : un
   daltonien doit pouvoir lire ses resultats. */

.console {
    /* min-height: 0 est INDISPENSABLE, et son absence reste invisible tant
       que la console est courte.

       Un element de grille vaut par defaut min-height: auto, ce qui l empeche
       de devenir plus petit que son contenu. Un conteneur defilant place dans
       une grille ne defile alors pas : il grandit, deborde de sa piste et sort
       du cadre de l atelier.

       Le defaut ne se voyait qu apres une reussite, seul moment ou la console
       est haute -- bandeau, XP, badges, retour gradue, tests, puis la solution
       de reference. Et c est ce dernier bloc, le plus utile, qui passait hors
       de l ecran. L editeur juste au-dessus avait deja la propriete. */
    min-height: 0;

    overflow-y: auto;
    padding: var(--v-2);
    background: var(--sf-void);
    border-top: 1px solid var(--sf-line);
    font-size: var(--t-md);
}

.console__vide,
.console__attente {
    margin: 0;
    padding: var(--v-2);
    font-family: var(--sf-font-mono);
    font-size: var(--t-sm);
    line-height: 1.7;
    color: var(--sf-text-faint);
    max-width: 68ch;
}

.console__attente { color: var(--sf-cyan); }

.console__erreur {
    margin: 0;
    padding: var(--v-2);
    border-left: 3px solid var(--sf-danger);
    background: rgba(255, 77, 109, .08);
    color: var(--sf-text);
    font-size: var(--t-md);
}

.console__bandeau {
    padding: 11px 14px;
    margin-bottom: var(--v-2);
    border-left: 3px solid var(--sf-text-faint);
    background: var(--sf-surface);
    font-size: var(--t-md);
    line-height: 1.6;
}

.console__bandeau strong {
    font-family: var(--sf-font);
    font-size: var(--t-lg);
    font-weight: 700;
    letter-spacing: var(--piste);
    display: block;
    margin-bottom: 2px;
}

.console__bandeau--reussi {
    border-left-color: var(--sf-ok);
    background: rgba(45, 212, 167, .09);
}

.console__bandeau--reussi strong { color: var(--sf-ok); }

.console__bandeau--echec {
    border-left-color: var(--sf-warn);
    background: rgba(245, 165, 36, .08);
}

.console__bandeau--echec strong { color: var(--sf-warn); }

.console__xp {
    font-family: var(--sf-font-mono);
    font-weight: 500;
    color: var(--sf-pink);
    white-space: nowrap;
}

/* Badge tout juste obtenu. Le rose est reserve a la reussite : le voir
   apparaitre suffit a comprendre qu'il s'est passe quelque chose. */
.console__badges {
    display: flex;
    flex-wrap: wrap;
    gap: var(--v-1);
    margin-bottom: var(--v-2);
}

.console__badge {
    display: inline-flex;
    align-items: center;
    gap: var(--v-1);
    padding: 7px 12px;
    border: 1px solid rgba(255, 46, 136, .45);
    background: rgba(255, 46, 136, .1);
    color: var(--sf-text);
    font-size: var(--t-sm);
}

.console__badge strong { color: var(--sf-pink); }

.console__retour {
    list-style: none;
    margin: 0 0 var(--v-2);
    padding: 0;
}

.console__retour li {
    position: relative;
    padding: 5px 0 5px var(--v-3);
    color: var(--sf-text-dim);
    line-height: 1.65;
    font-size: var(--t-md);
    max-width: 78ch;
}

.console__retour li::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 13px;
    width: 6px;
    height: 6px;
    background: var(--sf-cyan);
}

.console__tests {
    list-style: none;
    margin: 0;
    padding: 0;
}

.console__test {
    display: grid;
    grid-template-columns: 22px 1fr auto;
    align-items: baseline;
    gap: 4px var(--v-2);
    padding: 9px 0;
    border-top: 1px solid var(--sf-line-soft);
    font-size: var(--t-md);
}

/* Marqueur dessine en CSS : un carre vert plein pour un test reussi, un carre
   rouge barre pour un echec. La forme differe autant que la couleur. */
.console__marque {
    width: 12px;
    height: 12px;
    justify-self: end;
    position: relative;
    transform: translateY(1px);
}

.est-reussi .console__marque { background: var(--sf-ok); }

.est-rate .console__marque { border: 2px solid var(--sf-danger); }

.est-rate .console__marque::after {
    content: "";
    position: absolute;
    left: -1px;
    top: 3px;
    width: 10px;
    height: 2px;
    background: var(--sf-danger);
    transform: rotate(-45deg);
}

.console__nom {
    font-family: var(--sf-font-mono);
    font-size: var(--t-sm);
    line-height: 1.5;
    color: var(--sf-text);
}

.est-reussi .console__nom { color: var(--sf-text-dim); }

.console__cache {
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-text-faint);
    border: 1px solid var(--sf-line-soft);
    padding: 2px 6px;
    white-space: nowrap;
}

/* Attendu contre obtenu, cote a cote. Vert et rouge, comme une difference
   dans un gestionnaire de versions : encore le vocabulaire du sujet. */
.console__diff {
    grid-column: 2 / -1;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--v-1);
    margin-top: var(--v-1);
}

.console__diff > div {
    border: 1px solid var(--sf-line-soft);
    background: var(--ink);
    min-width: 0;
}

.console__diff > div:first-child { border-left: 3px solid var(--sf-ok); }
.console__diff > div:last-child  { border-left: 3px solid var(--sf-danger); }

.console__diff span {
    display: block;
    padding: 4px 9px;
    border-bottom: 1px solid var(--sf-line-soft);
    font-family: var(--sf-font);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: var(--piste);
    color: var(--sf-text-faint);
}

.console__diff pre {
    margin: 0;
    padding: 8px 9px;
    font-size: var(--t-sm);
    line-height: 1.6;
    color: var(--sf-text);
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 12em;
    overflow: auto;
}

.console__message {
    grid-column: 2 / -1;
    margin: var(--v-1) 0 0;
    padding: 8px 11px;
    background: rgba(255, 77, 109, .08);
    border-left: 2px solid var(--sf-danger);
    font-family: var(--sf-font-mono);
    font-size: var(--t-sm);
    line-height: 1.6;
    color: #FFC2CD;
}

.console__solution {
    margin-top: var(--v-3);
    border: 1px solid var(--sf-line-soft);
    background: var(--ink);
}

.console__solution summary {
    padding: 10px 13px;
    cursor: pointer;
    font-family: var(--sf-font);
    font-size: var(--t-md);
    font-weight: 600;
    letter-spacing: var(--piste);
    color: var(--sf-violet-bright);
}

.console__solution summary:hover { color: var(--sf-text); }

.console__note {
    margin: 0;
    padding: 0 13px;
    font-size: var(--t-sm);
    color: var(--sf-text-faint);
    line-height: 1.6;
    max-width: 70ch;
}

.console__solution pre {
    margin: var(--v-1) 13px 13px;
    padding: var(--v-2);
    background: var(--sf-void);
    border: 1px solid var(--sf-line-soft);
    overflow-x: auto;
    font-size: var(--t-sm);
    line-height: 1.7;
    color: #D8D3EC;
}

/* --- L atelier comme outil plein ecran --------------------------------------
   Sur ordinateur, la page d exercice se comporte comme un editeur : elle ne
   defile pas, seuls ses panneaux defilent.

   Auparavant l atelier faisait un ecran de haut et le pied de page venait
   dessous. Il y avait donc deux defilements empiles, celui de la page et celui
   de la console, et la fin de la console -- la solution de reference --
   finissait coupee au ras du pied de page.

   La hauteur vient d une colonne flex et non plus d un calc(100vh - en-tete) :
   un message flash au-dessus de l atelier la reduit d autant, au lieu de
   pousser le bas de l atelier hors de l ecran. */
@media (min-width: 1021px) {
    body.page-atelier {
        height: 100vh;
        overflow: hidden;
    }

    .page-atelier main {
        flex: 1 1 0;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    .page-atelier .atelier {
        flex: 1 1 0;
        height: auto;
        min-height: 0;
    }

    /* Le pied de page reste accessible partout ailleurs sur le site. Dans un
       outil plein ecran, il ne servirait qu a voler de la hauteur. */
    .page-atelier .pied {
        display: none;
    }

    /* Des qu un resultat est affiche, la console prend plus de place : elle
       contient alors le bandeau, le detail des tests et la solution. Avant,
       l editeur garde l essentiel de la hauteur, c est la qu on travaille. */
    .atelier__travail:has(.console__bandeau) {
        grid-template-rows: auto minmax(0, 1fr) minmax(200px, 55%);
    }
}

/* -----------------------------------------------------------------------------
   6. PROFIL
   -------------------------------------------------------------------------- */

.page-profil { padding: var(--v-5) var(--v-3); }

.profil-entete {
    display: flex;
    align-items: center;
    gap: var(--v-3);
    padding-bottom: var(--v-4);
    margin-bottom: var(--v-4);
    border-bottom: 1px solid var(--sf-line-soft);
}

.profil-avatar {
    width: 84px;
    height: 84px;
    flex: none;
    display: grid;
    place-items: center;
    overflow: hidden;

    background: var(--sf-surface-2);
    border: 1px solid var(--sf-line);
    /* Le coin coupe reprend l'angle du caret de l'en-tete, a plus grande
       echelle : c'est la meme forme, donc la meme marque. */
    clip-path: polygon(0 0, 100% 0, 100% 78%, 78% 100%, 0 100%);

    font-family: var(--sf-font);
    font-size: 2.4rem;
    font-weight: 700;
    color: var(--sf-violet-bright);
    line-height: 1;
}

.profil-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.profil-entete h1 { margin-bottom: 6px; }

.profil-entete__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--v-2);
    margin: 0 0 var(--v-1);
    font-family: var(--sf-font-mono);
    font-size: var(--t-sm);
    color: var(--sf-text-dim);
}

.profil-entete__xp,
.profil-entete__serie { color: var(--sf-pink); }

.profil-entete__bio {
    color: var(--sf-text-dim);
    max-width: var(--mesure);
    margin: var(--v-1) 0 0;
    font-size: var(--t-md);
}

.profil-entete__actions {
    margin-left: auto;
    align-self: flex-start;
}

.profil-bloc { margin-bottom: var(--v-5); }

.profil-bloc > h2 {
    font-size: var(--t-lg);
    margin-bottom: var(--v-3);
    padding-bottom: var(--v-1);
    border-bottom: 1px solid var(--sf-line-soft);
}

/* Jauge segmentee plutot que barre continue : le decompte se lit d'un coup
   d'oeil, et la forme appartient au monde des interfaces de jeu, qui est
   celui du public de ce site. */
.jauge {
    display: flex;
    gap: 3px;
    height: 14px;
    margin-bottom: var(--v-1);
}

.jauge__segment {
    flex: 1;
    background: var(--sf-surface-2);
    border: 1px solid var(--sf-line-soft);
}

.jauge__segment--plein {
    background: var(--sf-pink);
    border-color: var(--sf-pink);
}

.jauge__legende {
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-text-faint);
    margin: 0 0 var(--v-3);
}

.profil-chiffres {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--sf-line-soft);
}

.profil-chiffres li {
    flex: 1 1 130px;
    /* Rembourrage symetrique et contenu centre, comme la bande de chiffres de
       l'accueil : les deux doivent se ressembler, ce sont les memes objets. */
    padding: var(--v-2);
    border-right: 1px solid var(--sf-line-soft);
    font-size: var(--t-sm);
    color: var(--sf-text-faint);
    text-align: center;
}

.profil-chiffres li:last-child { border-right: 0; }

.profil-chiffres strong {
    display: block;
    font-family: var(--sf-font);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--sf-text);
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.profil-vide {
    color: var(--sf-text-faint);
    font-size: var(--t-md);
    max-width: var(--mesure);
}

/* Les badges sont les seuls elements du site traites en tuiles : ce sont
   reellement des objets distincts que l'on collectionne. */
.grille-badges {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: var(--v-2);
}

.badge {
    display: grid;
    grid-template-columns: 34px 1fr;
    gap: 2px var(--v-2);
    padding: var(--v-2);
    border: 1px solid var(--sf-line);
    border-top-width: 2px;
    background: var(--sf-surface);
}

.badge__icone {
    grid-row: 1 / span 2;
    font-size: 1.7rem;
    line-height: 1;
    align-self: center;
}

.badge__nom {
    font-family: var(--sf-font);
    font-size: var(--t-md);
    font-weight: 700;
    letter-spacing: var(--piste);
    color: var(--sf-text);
}

.badge__description {
    font-size: var(--t-sm);
    color: var(--sf-text-faint);
    line-height: 1.5;
}

/* La rarete se lit sur le filet superieur. Une seule ligne coloree suffit :
   colorer la tuile entiere rendrait la grille illisible. */
.badge--commun     { border-top-color: var(--sf-text-faint); }
.badge--rare       { border-top-color: var(--sf-cyan); }
.badge--epique     { border-top-color: var(--sf-violet-bright); }
.badge--legendaire { border-top-color: var(--sf-pink); }

/* Une mesure suivie d'une jauge et d'une legende. Deux mesures cote a cote sur
   le profil : l'une bouge a chaque exercice, l'autre a l'echelle du parcours.
   Les melanger dans une seule barre reviendrait a n'en montrer aucune. */
.mesures {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--v-3) var(--v-4);
    margin-bottom: var(--v-3);
}

.mesure__titre {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--v-2);
    margin: 0 0 6px;
    font-family: var(--sf-font);
    font-size: var(--t-md);
    font-weight: 600;
    letter-spacing: var(--piste);
    color: var(--sf-text);
}

.mesure__valeur {
    font-family: var(--sf-font-mono);
    font-size: var(--t-sm);
    font-weight: 500;
    color: var(--sf-pink);
    font-variant-numeric: tabular-nums;
}

/* La jauge du parcours avance lentement par nature : sa valeur est en cyan,
   la couleur des donnees techniques, et non en rose, celle de la reussite. */
.mesure--parcours .mesure__valeur { color: var(--sf-cyan); }
.mesure--parcours .jauge__segment--plein {
    background: var(--sf-cyan);
    border-color: var(--sf-cyan);
}

/* -----------------------------------------------------------------------------
   6 bis. CLASSEMENT
   Une liste ordonnee : le rang va donc dans la gouttiere, comme les numeros de
   chapitre. C'est l'un des rares endroits ou numeroter est justifie.
   -------------------------------------------------------------------------- */

.page-classement { padding: var(--v-5) var(--v-3); }

.classement {
    list-style: none;
    margin: var(--v-3) 0 0;
    padding: 0;
    border-top: 1px solid var(--sf-line-soft);
}

.rang {
    display: grid;
    grid-template-columns: var(--gouttiere) auto 1fr auto auto;
    align-items: center;
    gap: var(--v-2) var(--v-3);
    padding: 11px 0;
    border-bottom: 1px solid var(--sf-line-soft);
    border-left: 2px solid transparent;
}

/* La ligne de l'eleve qui consulte. Le violet marque la position, exactement
   comme dans la navigation et dans la gouttiere d'un editeur. */
.rang--moi {
    border-left-color: var(--sf-violet);
    background: var(--sf-violet-soft);
    padding-left: var(--v-2);
}

.rang__place {
    justify-self: end;
    font-family: var(--sf-font-mono);
    font-size: var(--t-md);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    color: var(--sf-text-faint);
}

/* Les trois premiers en rose : c'est la couleur de la reussite, et elle sert
   ici a la meme chose qu'ailleurs. Pas de podium, pas de medailles. */
.rang--tete .rang__place { color: var(--sf-pink); }

.rang__avatar {
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    overflow: hidden;
    flex: none;

    background: var(--sf-surface-2);
    border: 1px solid var(--sf-line);
    clip-path: polygon(0 0, 100% 0, 100% 78%, 78% 100%, 0 100%);

    font-family: var(--sf-font);
    font-size: 1rem;
    font-weight: 700;
    color: var(--sf-violet-bright);
    line-height: 1;
}

.rang__avatar img { width: 100%; height: 100%; object-fit: cover; }

.rang__pseudo {
    font-family: var(--sf-font);
    font-size: var(--t-base);
    font-weight: 600;
    letter-spacing: var(--piste);
    color: var(--sf-text);
    min-width: 0;
    overflow-wrap: anywhere;
}

.rang__niveau {
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-text-faint);
    white-space: nowrap;
}

.rang__xp {
    font-family: var(--sf-font-mono);
    font-size: var(--t-sm);
    font-weight: 500;
    color: var(--sf-pink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    text-align: right;
    min-width: 6rem;
}

/* Rappel de sa propre place quand on ne figure pas dans la page affichee. */
.classement__moi {
    margin-top: var(--v-3);
    padding-top: var(--v-3);
    border-top: 1px solid var(--sf-line);
}

.classement__absent {
    margin-top: var(--v-3);
    font-size: var(--t-md);
    color: var(--sf-text-faint);
    max-width: var(--mesure);
}

/* -----------------------------------------------------------------------------
   7. PAGES DE COMPTE
   Une colonne etroite : un formulaire perdu au milieu d'un grand vide donne
   l'impression d'un site inacheve.
   -------------------------------------------------------------------------- */

.page-auth {
    max-width: 30rem;
    margin-inline: auto;
    padding: var(--v-6) var(--v-3);
}

.page-auth h1 {
    font-size: var(--t-2xl);
    margin-bottom: var(--v-2);
}

.page-auth__intro {
    color: var(--sf-text-dim);
    font-size: var(--t-md);
    margin-bottom: var(--v-4);
}

.page-auth__bascule {
    margin-top: var(--v-3);
    padding-top: var(--v-3);
    border-top: 1px solid var(--sf-line-soft);
    font-size: var(--t-md);
    color: var(--sf-text-faint);
}

/* -----------------------------------------------------------------------------
   8. PAGES LEGALES ET ERREURS
   -------------------------------------------------------------------------- */

.page-legale {
    max-width: 760px;
    padding: var(--v-5) var(--v-3);
}

.page-legale h1 { margin-bottom: var(--v-1); }

.page-legale__date {
    font-family: var(--sf-font-mono);
    font-size: var(--t-sm);
    color: var(--sf-text-faint);
    margin-bottom: var(--v-4);
    padding-bottom: var(--v-3);
    border-bottom: 1px solid var(--sf-line-soft);
}

.page-legale h2 {
    font-size: var(--t-lg);
    margin: var(--v-4) 0 var(--v-2);
}

.page-legale p,
.page-legale li {
    max-width: var(--mesure);
    color: var(--sf-text-dim);
    line-height: 1.75;
}

.page-legale ul { padding-left: 1.3em; }
.page-legale li { margin-bottom: 6px; }

.section-erreur {
    padding: var(--v-6) var(--v-3);
    max-width: 46rem;
}

/* Le code d'erreur en monospace tres grand : c'est un nombre technique, il
   est traite comme tel plutot qu'en titre decoratif. */
.section-erreur__code {
    font-family: var(--sf-font-mono);
    font-size: clamp(3.5rem, 12vw, 7rem);
    font-weight: 500;
    line-height: 1;
    color: var(--sf-line);
    margin: 0 0 var(--v-2);
    font-variant-numeric: tabular-nums;
}

.section-erreur h1 { margin-bottom: var(--v-2); }

.section-erreur__message {
    color: var(--sf-text-dim);
    max-width: var(--mesure);
    margin-bottom: var(--v-4);
}

/* -----------------------------------------------------------------------------
   9. SOUTENIR
   -------------------------------------------------------------------------- */

.page-don { padding: var(--v-5) var(--v-3); }

.don__grille {
    display: grid;
    grid-template-columns: 1.3fr 1fr;
    gap: var(--v-5);
    align-items: start;
    margin-top: var(--v-4);
}

.don__texte p {
    color: var(--sf-text-dim);
    max-width: var(--mesure);
    line-height: 1.75;
}

.don__texte h2 {
    font-size: var(--t-lg);
    margin: var(--v-4) 0 var(--v-2);
}

/* La destination des dons, en tableau de specification : c'est un engagement
   verifiable, il merite une forme de document, pas une carte. */
.don__postes { margin: 0; }

.don__poste {
    display: grid;
    grid-template-columns: 9rem 1fr;
    gap: var(--v-3);
    padding: 11px 0;
    border-top: 1px solid var(--sf-line-soft);
    font-size: var(--t-md);
}

.don__poste:last-child { border-bottom: 1px solid var(--sf-line-soft); }

.don__poste dt {
    font-family: var(--sf-font);
    font-weight: 700;
    letter-spacing: var(--piste);
    color: var(--sf-text);
}

.don__poste dd {
    margin: 0;
    color: var(--sf-text-dim);
}

.don__boite {
    border: 1px solid var(--sf-line);
    border-top: 2px solid var(--sf-pink);
    background: var(--sf-surface);
    padding: var(--v-3);
    position: sticky;
    top: calc(var(--entete-h) + var(--v-3));
}

.don__boite h2 {
    font-size: var(--t-lg);
    margin-bottom: var(--v-1);
}

.don__boite p {
    font-size: var(--t-md);
    color: var(--sf-text-dim);
    margin-bottom: var(--v-3);
}

/* Conteneur du bouton PayPal. PayPal injecte son propre balisage : on ne lui
   impose qu'une largeur, sans chercher a le restyler. */
#paypal-don-conteneur {
    min-height: 46px;
    margin-bottom: var(--v-2);
}

.don__repli {
    font-size: var(--t-sm);
    color: var(--sf-text-faint);
    line-height: 1.6;
}

.don__promesse {
    margin-top: var(--v-3);
    padding-top: var(--v-3);
    border-top: 1px solid var(--sf-line-soft);
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    line-height: 1.8;
    color: var(--sf-ok);
}

.don__derniers {
    list-style: none;
    margin: var(--v-2) 0 0;
    padding: 0;
}

.don__derniers li {
    display: flex;
    justify-content: space-between;
    gap: var(--v-2);
    padding: 7px 0;
    border-top: 1px solid var(--sf-line-soft);
    font-size: var(--t-sm);
    color: var(--sf-text-dim);
}

.don__montant {
    font-family: var(--sf-font-mono);
    color: var(--sf-pink);
    white-space: nowrap;
}

/* -----------------------------------------------------------------------------
   10. PARAMETRES
   -------------------------------------------------------------------------- */

.page-parametres { padding: var(--v-5) var(--v-3); }

.parametres__section {
    padding: var(--v-4) 0;
    border-top: 1px solid var(--sf-line-soft);
}

.parametres__section:first-of-type { border-top: 0; padding-top: var(--v-3); }

.parametres__section > h2 {
    font-size: var(--t-lg);
    margin-bottom: var(--v-1);
}

.parametres__intro {
    color: var(--sf-text-faint);
    font-size: var(--t-md);
    max-width: var(--mesure);
    margin-bottom: var(--v-3);
}

.parametres__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--v-2);
    align-items: center;
    margin-top: var(--v-2);
}

.parametres__formulaire { max-width: 34rem; }

/* Apercu de l'avatar a cote du champ : on voit ce que l'on remplace avant de
   le remplacer. */
.avatar-choix {
    display: flex;
    align-items: center;
    gap: var(--v-3);
    margin-bottom: var(--v-2);
}

.avatar-choix .profil-avatar {
    width: 64px;
    height: 64px;
    font-size: 1.7rem;
}

.avatar-choix > div { flex: 1; min-width: 0; }

/* Zone dangereuse : encadree en rouge, en bas de page, avec une confirmation
   ecrite. Supprimer un compte est irreversible. */
.zone-danger {
    margin-top: var(--v-5);
    padding: var(--v-3);
    border: 1px solid rgba(255, 77, 109, .35);
    border-left-width: 3px;
    background: rgba(255, 77, 109, .05);
}

.zone-danger h2 {
    font-size: var(--t-lg);
    color: var(--sf-danger);
    margin-bottom: var(--v-1);
}

.zone-danger p {
    color: var(--sf-text-dim);
    font-size: var(--t-md);
    max-width: var(--mesure);
}

/* -----------------------------------------------------------------------------
   11. ADMINISTRATION
   Interface d'outil : dense, tabulaire, sans fioriture. Personne ne consulte
   un panneau d'administration pour le plaisir des yeux.
   -------------------------------------------------------------------------- */

.page-admin { padding: var(--v-4) var(--v-3) var(--v-5); }

.admin__entete {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--v-2);
    padding-bottom: var(--v-2);
    margin-bottom: var(--v-3);
    border-bottom: 1px solid var(--sf-line);
}

.admin__nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--v-2);
    margin-bottom: var(--v-4);
}

.admin__nav a {
    padding: 6px 12px;
    border: 1px solid var(--sf-line-soft);
    color: var(--sf-text-dim);
    text-decoration: none;
    font-family: var(--sf-font);
    font-size: var(--t-sm);
    font-weight: 600;
    letter-spacing: var(--piste);
}

.admin__nav a:hover { border-color: var(--sf-violet); color: var(--sf-text); }

.admin__nav a[aria-current="page"] {
    border-color: var(--sf-violet);
    background: var(--sf-violet-soft);
    color: var(--sf-text);
}

.tableau {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--t-sm);
}

.tableau th,
.tableau td {
    text-align: left;
    padding: 9px 12px 9px 0;
    border-bottom: 1px solid var(--sf-line-soft);
    vertical-align: top;
}

.tableau th {
    font-family: var(--sf-font);
    font-weight: 700;
    letter-spacing: var(--piste);
    color: var(--sf-text-dim);
    border-bottom-color: var(--sf-line);
    white-space: nowrap;
}

.tableau td { color: var(--sf-text-dim); }
.tableau tbody tr:hover td { background: var(--sf-surface); color: var(--sf-text); }

.tableau__nombre {
    font-family: var(--sf-font-mono);
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

.tableau__defilant { overflow-x: auto; }

.admin__stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    border: 1px solid var(--sf-line-soft);
    margin-bottom: var(--v-4);
}

.admin__stat {
    padding: var(--v-2) var(--v-3);
    border-right: 1px solid var(--sf-line-soft);
    text-align: center;
}

.admin__stat:last-child { border-right: 0; }

.admin__stat strong {
    display: block;
    font-family: var(--sf-font);
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.15;
    color: var(--sf-text);
    font-variant-numeric: tabular-nums;
}

.admin__stat span {
    font-size: var(--t-xs);
    color: var(--sf-text-faint);
}

.etiquette {
    display: inline-block;
    padding: 2px 7px;
    border: 1px solid var(--sf-line);
    font-family: var(--sf-font-mono);
    font-size: var(--t-xs);
    color: var(--sf-text-dim);
    white-space: nowrap;
}

.etiquette--publie    { border-color: rgba(45, 212, 167, .5); color: var(--sf-ok); }
.etiquette--brouillon { border-color: rgba(245, 165, 36, .5); color: var(--sf-warn); }

/* -----------------------------------------------------------------------------
   12. RESPONSIVE
   -------------------------------------------------------------------------- */

@media (max-width: 1020px) {
    /* En dessous de cette largeur, l'enonce et l'editeur cote a cote
       deviennent tous deux trop etroits : on empile, l'enonce d'abord. */
    .atelier {
        grid-template-columns: 1fr;
        /* Empile : chaque panneau prend sa hauteur, la page defile. */
        grid-template-rows: auto;
        height: auto;
    }

    .atelier__enonce {
        border-right: 0;
        border-bottom: 1px solid var(--sf-line);
        overflow: visible;
    }

    .atelier__travail { grid-template-rows: auto 60vh auto; }

    /* Sur un ecran etroit, l'apercu passe sous l'editeur. */
    .atelier__travail:has(.atelier__zone--apercu) { grid-template-rows: auto auto auto; }
    .atelier__zone--apercu { grid-template-columns: minmax(0, 1fr); }
    .atelier__zone--apercu .atelier__editeur { height: 50vh; }
    .atelier__zone--apercu .apercu { height: 45vh; border-left: 0; border-top: 1px solid var(--sf-line); }

    .console { max-height: 60vh; }

    /* Ici c est la page qui defile : a l ouverture de la solution, l en-tete
       colle en haut ne doit pas la recouvrir. */
    .console__solution { scroll-margin-top: calc(var(--entete-h) + var(--v-4)); }
}

@media (max-width: 900px) {
    .heros__grille {
        grid-template-columns: 1fr;
        gap: var(--v-4);
    }

    .heros { padding: var(--v-5) 0 var(--v-4); }
    .heros__titre { max-width: 100%; }

    .don__grille { grid-template-columns: 1fr; }
    .don__boite { position: static; }
}

@media (max-width: 720px) {
    .principe {
        grid-template-columns: 1fr;
        gap: var(--v-1);
    }

    .carte-langue { grid-template-columns: 1fr; }

    .carte-langue__chiffres {
        grid-column: 1;
        grid-row: auto;
        text-align: left;
    }

    .chapitre {
        grid-template-columns: 30px 1fr;
        gap: 0 var(--v-2);
    }

    .chapitre__numero::after { display: none; }

    /* Sur 360px de large, quatre colonnes ne tiennent pas : le compteur d'XP
       passe sous le titre. */
    .exercice-item__lien { grid-template-columns: var(--gouttiere) 1fr auto; }

    .exercice-item__xp {
        grid-column: 2 / -1;
        text-align: left;
        min-width: 0;
    }

    .navigation-lecon { grid-template-columns: 1fr; }
    .navigation-lecon__lien--suivant { grid-column: 1; text-align: left; }

    .profil-entete { flex-wrap: wrap; }
    .profil-entete__actions { margin-left: 0; width: 100%; }

    /* Cinq colonnes ne tiennent pas sur un telephone : le niveau passe sous
       le pseudo, ou il reste lisible. */
    .rang { grid-template-columns: 34px auto 1fr auto; }
    .rang__niveau { grid-column: 3 / -1; }

    .console__test { grid-template-columns: 20px 1fr; }
    .console__cache { grid-column: 2; justify-self: start; }

    .atelier__barre { flex-wrap: wrap; }
    .atelier__etat { order: 3; flex-basis: 100%; margin-right: 0; }

    .don__poste { grid-template-columns: 1fr; gap: 2px; }
}
