/* CF2M Campus — charte CF2M : marine #1F4E8E, cyan #009DE0 */
:root {
    color-scheme: light;
    --marine: #1F4E8E;
    --cyan: #009DE0;
    --fond: #f4f6fa;
    --carte: #ffffff;
    --texte: #1a202c;
    --muted: #64748b;
    --bordure: #e2e8f0;
    --ok: #16a34a;
    --ok-fond: #ecfdf3;
    --rouge: #dc2626;
    --rouge-fond: #fef2f2;
    --ambre: #d97706;
    --degrade: linear-gradient(135deg, #1F4E8E 0%, #009DE0 100%);
    --ombre: 0 1px 2px rgba(16, 24, 40, 0.04), 0 4px 12px rgba(16, 24, 40, 0.06);
    --ombre-survol: 0 4px 8px rgba(16, 24, 40, 0.06), 0 12px 28px rgba(16, 24, 40, 0.12);
    /* Couleurs sémantiques : fond doux + texte fort, contraste garanti */
    --ok-soft: #d9f2e5;    --ok-fort: #0c6b4a;
    /* Texte pose SUR une pastille --ok-fort (pastille foncee -> texte blanc) */
    --sur-ok: #ffffff;
    --warn-soft: #fdf0d5;  --warn-fort: #8a5a00;
    --danger-soft: #fde3e3; --danger-fort: #a32d2d;
    --info-soft: #e1f2fb;  --info-fort: #0b6e9e;
}

:root[data-theme="dark"] {
    color-scheme: dark;
    --fond: #0f172a;
    --carte: #1e293b;
    --texte: #e2e8f0;
    --muted: #94a3b8;
    --bordure: #334155;
    --ok-fond: #052e16;
    --rouge-fond: #450a0a;
    --marine: #6ba3e8;
}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;
        --fond: #0f172a;
        --carte: #1e293b;
        --texte: #e2e8f0;
        --muted: #94a3b8;
        --bordure: #334155;
        --ok-fond: #052e16;
        --rouge-fond: #450a0a;
        --marine: #6ba3e8;
        --ombre: 0 1px 2px rgba(0, 0, 0, 0.30), 0 4px 14px rgba(0, 0, 0, 0.35);
        --ombre-survol: 0 6px 16px rgba(0, 0, 0, 0.40), 0 14px 32px rgba(0, 0, 0, 0.50);
    }
}
:root[data-theme="dark"] {
    --ombre: 0 1px 2px rgba(0, 0, 0, 0.30), 0 4px 14px rgba(0, 0, 0, 0.35);
    --ombre-survol: 0 6px 16px rgba(0, 0, 0, 0.40), 0 14px 32px rgba(0, 0, 0, 0.50);
}
:root[data-theme="dark"], .dark-semantique {
    --ok-soft: rgba(34, 197, 94, 0.16);    --ok-fort: #6ee7a8;
    --warn-soft: rgba(217, 119, 6, 0.20);  --warn-fort: #fbbf24;
    --danger-soft: rgba(220, 38, 38, 0.22); --danger-fort: #f87171;
    --info-soft: rgba(0, 157, 224, 0.20);  --info-fort: #5fc8f5;
    /* La pastille --ok-fort est claire ici : le texte dessus doit etre fonce */
    --sur-ok: #06281c;
    /* --ok et --ambre n'etaient definis que pour le theme clair : trop sombres
       sur fond sombre (contraste 4.1 et 4.3, sous le seuil AA de 4.5). */
    --ok: #4ade80;
    --ambre: #fbbf24;
}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --ok-soft: rgba(34, 197, 94, 0.16);    --ok-fort: #6ee7a8;
        --warn-soft: rgba(217, 119, 6, 0.20);  --warn-fort: #fbbf24;
        --danger-soft: rgba(220, 38, 38, 0.22); --danger-fort: #f87171;
        --info-soft: rgba(0, 157, 224, 0.20);  --info-fort: #5fc8f5;
        --sur-ok: #06281c;
        --ok: #4ade80;
        --ambre: #fbbf24;
    }
}

* { box-sizing: border-box; }
body {
    margin: 0;
    font-family: "Inter", "Segoe UI", system-ui, sans-serif;
    background: var(--fond);
    color: var(--texte);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}
body, .carte, .topbar, .kpi, .btn-principal, .btn-secondaire,
input, textarea, .seance-carte, .exo-ligne {
    transition: background-color .25s ease, color .25s ease,
                border-color .25s ease, box-shadow .2s ease, transform .2s ease;
}

/* ── Barre du haut ── */
.topbar {
    display: flex; justify-content: space-between; align-items: center;
    padding: 6px 24px;
    background: var(--carte);
    border-bottom: none;
    box-shadow: 0 1px 0 var(--bordure), 0 2px 8px rgba(16, 24, 40, 0.05);
    position: relative;
}
.topbar::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0;
    height: 3px; background: var(--degrade);
}
.topbar-brand { display: flex; align-items: center; gap: 14px; }
.brand-user { font-size: 13px; }
.logo { height: 64px; display: block; }
.logo-lien { display: inline-flex; line-height: 0; }
@media (prefers-color-scheme: dark) {
}
.topbar-actions { display: flex; align-items: center; gap: 12px; }
.topbar-nav { display: flex; align-items: center; gap: 3px; }
/* Onglet = symbole + libellé. Le symbole donne le repère visuel, le libellé
   évite de faire deviner : les deux, jamais l'un sans l'autre sur ordinateur. */
.onglet {
    display: inline-flex; align-items: center; gap: 7px;
    color: var(--marine); text-decoration: none; font-weight: 600;
    font-size: 14px; padding: 8px 12px; border-radius: 10px;
    white-space: nowrap;
    transition: background .18s ease, color .18s ease;
}
.onglet .symb { width: 17px; height: 17px; flex: none; }
.onglet:hover { background: var(--info-soft); color: var(--info-fort); }
.onglet.actif { background: var(--marine); color: #fff; }
.onglet:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.onglet-sortie { color: var(--muted); }
.onglet-sortie:hover { background: var(--danger-soft); color: var(--danger-fort); }

/* Barre du bas : uniquement sur téléphone (voir la requête média plus bas) */
.barre-basse { display: none; }
.onglet-bas {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 8px 2px 7px; text-decoration: none; color: var(--muted);
    font-size: 10.5px; font-weight: 600; text-align: center;
    border-top: 2px solid transparent; min-width: 0;
}
.onglet-bas .symb { width: 21px; height: 21px; }
.onglet-bas span { overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.onglet-bas.actif { color: var(--marine); border-top-color: var(--marine); }
.onglet-bas:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }

.contenu { max-width: 980px; margin: 0 auto; padding: 24px 16px 48px; }


.pied { text-align: center; color: var(--muted); font-size: 12px; padding: 16px; }

h1 { color: var(--marine); font-size: 25px; font-weight: 700; letter-spacing: -0.02em; margin: 0 0 4px; }
h2 { color: var(--marine); font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 0 0 12px; }
.muted { color: var(--muted); }
.ok { color: var(--ok-fort); font-weight: 600; }
.rouge { color: var(--rouge); font-weight: 600; }
.etoiles { color: var(--warn-fort); letter-spacing: 2px; }
.cache { display: none; }

/* ── Icônes maison (remplacent les emojis) ── */
.icone { height: 1em; width: auto; vertical-align: -0.15em; display: inline-block; }
.icone-lg { height: 1.4em; }
.icone-blanc { filter: brightness(0) invert(1); }
:root[data-theme="dark"] .icone { filter: brightness(0) invert(1); }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .icone { filter: brightness(0) invert(1); }
}

/* ── Bouton clair/sombre ── */
.bouton-theme {
    background: none; border: 1px solid var(--bordure); border-radius: 50%;
    width: 36px; height: 36px; cursor: pointer; display: inline-flex;
    align-items: center; justify-content: center;
    color: var(--marine); flex-shrink: 0;
}
.bouton-theme:hover { background: var(--fond); border-color: var(--cyan); color: var(--cyan); }

.entete-page { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; }

/* ── Cartes ── */
.carte {
    background: var(--carte);
    border: 1px solid var(--bordure);
    border-radius: 14px;
    padding: 20px;
    margin: 14px 0;
    box-shadow: var(--ombre);
}

/* ── Boutons ── */
.btn-principal {
    background: var(--degrade); color: #fff; border: none;
    padding: 10px 22px; border-radius: 9px; font-size: 14px; font-weight: 600;
    cursor: pointer; text-decoration: none; display: inline-block;
    box-shadow: 0 2px 8px rgba(0, 157, 224, 0.30);
}
.btn-principal:hover { filter: brightness(1.07); transform: translateY(-1px); box-shadow: 0 4px 14px rgba(0, 157, 224, 0.40); }
.btn-principal:active { transform: translateY(0); }
.btn-principal:disabled { opacity: 0.6; cursor: wait; transform: none; }
.btn-large { width: 100%; padding: 12px; margin-top: 12px; }
.btn-secondaire {
    background: transparent; color: var(--marine);
    border: 1px solid var(--bordure); padding: 7px 14px; border-radius: 8px;
    font-size: 13px; cursor: pointer; text-decoration: none; display: inline-block;
}
.btn-secondaire:hover { border-color: var(--cyan); color: var(--cyan); background: var(--fond); }
.btn-secondaire.actif { background: var(--marine); color: #fff; border-color: var(--marine); }
.btn-secondaire.actif:hover { color: #fff; }
.btn-desactive { opacity: 0.45; pointer-events: none; cursor: not-allowed; }

/* ── Navigation entre exercices ── */
.nav-exercices {
    display: flex; justify-content: space-between; align-items: center;
    margin: 16px 0;
}

/* ── Progression admin : cellules heatmap ── */
.cellule {
    display: inline-block; padding: 3px 8px; border-radius: 6px;
    font-size: 12px; font-weight: 600; white-space: nowrap;
}
.cellule-ok    { background: var(--ok-soft); color: var(--ok-fort); }
.cellule-cours { background: var(--warn-soft); color: var(--warn-fort); }
.cellule-ko    { background: var(--danger-soft); color: var(--danger-fort); }
.cellule-vide  { background: transparent; color: var(--muted); }
.soum-cell { display: block; font-size: 10px; color: var(--muted); margin-top: 2px; }
.soum-lien { color: var(--cyan); text-decoration: none; }
.soum-lien:hover { text-decoration: underline; }
.code-soumis {
    background: var(--fond); border: 1px solid var(--bordure); border-radius: 6px;
    padding: 8px 10px; margin: 6px 0 0; font-size: 12.5px; white-space: pre-wrap;
    font-family: var(--mono, monospace); overflow-x: auto;
}

.ligne-bloque-resume { cursor: pointer; }
.ligne-bloque-resume:hover td { background: rgba(0, 157, 224, 0.08); }

.comparatif-bloque { display: flex; gap: 16px; padding: 12px 4px; flex-wrap: wrap; }
.comparatif-carte {
    flex: 1; min-width: 280px; border-radius: 8px; overflow: hidden;
    border: 1px solid var(--bordure); background: var(--carte);
}
.comparatif-entete {
    padding: 8px 14px; font-weight: 600; font-size: 13px; color: #fff;
}
.comparatif-eleve .comparatif-entete { background: var(--marine); }
.comparatif-formateur .comparatif-entete { background: var(--cyan); }
.comparatif-corps { padding: 12px 14px; font-size: 13px; }
.comparatif-carte .code-soumis { margin-top: 0; }
.comparatif-liste { margin: 0; }
.comparatif-liste dt {
    font-weight: 600; color: var(--muted); font-size: 11.5px;
    text-transform: uppercase; letter-spacing: .03em; margin-top: 12px;
}
.comparatif-liste dt:first-child { margin-top: 0; }
.comparatif-liste dd { margin: 4px 0 0; }
.lien-code { color: var(--cyan); cursor: pointer; font-size: 13px; }

/* ── Carte admin (corrigé + notes, invisible pour les élèves) ── */
.carte-admin { border: 2px solid var(--marine); border-style: dashed; }
.carte-admin h2 { color: var(--marine); }
.carte-admin #solution { font-family: var(--mono, monospace); font-size: 13px; }
.legende { font-size: 12px; margin-top: 8px; }

/* ── Classement ── */
.tableau tr.ligne-moi td { background: #eaf5fc; font-weight: 600; color: #14224a; }
.tableau tr:not(.ligne-moi):hover td { background: rgba(0, 157, 224, 0.12); }
.rang {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 50%;
    font-weight: 700; font-size: 13px; box-shadow: var(--ombre);
}
.rang-1 { background: linear-gradient(135deg, #f6d365, #e0a219); color: #4a3600; }
.rang-2 { background: linear-gradient(135deg, #dfe4ec, #b3bcca); color: #3a4250; }
.rang-3 { background: linear-gradient(135deg, #e0a06a, #b9712f); color: #ffffff; }
.rang-num { display: inline-flex; justify-content: center; width: 26px; color: var(--muted); }
.icone-titre { vertical-align: -4px; margin-right: 4px; }

/* ── Login ── */
.carte-login { max-width: 380px; margin: 8vh auto; text-align: center; }
.logo-login { height: 60px; margin-bottom: 8px; }
.carte-login form { text-align: left; }

/* ── Formulaires ── */
label { display: block; font-size: 13px; color: var(--muted); margin: 12px 0 4px; }
input[type=text], input[type=password], input[type=date], textarea {
    width: 100%; padding: 9px 12px;
    border: 1px solid var(--bordure); border-radius: 8px;
    font-size: 14px; background: var(--fond); color: var(--texte);
}
textarea { font-family: Consolas, "Courier New", monospace; font-size: 13.5px; resize: vertical; }
input:focus, textarea:focus { outline: 2px solid var(--cyan); border-color: var(--cyan); }

/* ── Alertes / feedback ── */
.alerte { padding: 10px 14px; border-radius: 8px; font-size: 14px; margin: 12px 0; }
.alerte-ok { background: var(--ok-fond); color: var(--ok); border: 1px solid var(--ok); }
.alerte-erreur { background: var(--rouge-fond); color: var(--rouge); border: 1px solid var(--rouge); }

/* ── Le Mémo (bibliothèque de référence) ── */
.memo-recherche { display: flex; align-items: center; gap: 14px; }
.memo-recherche input { flex: 1; }

/* Deux colonnes : navigation par thème à gauche, fiches à droite */
.memo-page { display: grid; grid-template-columns: 232px minmax(0, 1fr); gap: 20px; align-items: start; }
.memo-nav {
    position: sticky; top: 16px; background: var(--carte);
    border: 1px solid var(--bordure); border-radius: 14px;
    padding: 14px 12px; box-shadow: var(--ombre);
    max-height: calc(100vh - 40px); overflow: auto;
}
.memo-nav-titre {
    margin: 0 0 8px 6px; font-size: 11px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--muted);
}
.memo-theme {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    width: 100%; text-align: left; font-family: inherit; font-size: 14px; font-weight: 600;
    color: var(--texte); background: none; border: none; border-radius: 9px;
    padding: 9px 11px; cursor: pointer; transition: all .15s ease;
}
.memo-theme:hover { background: var(--fond); }
/* Chevron : indique qu'un clic sur le thème actif replie ou déplie sa liste */
.memo-theme::before {
    content: "\25B8"; font-size: 11px; line-height: 1; opacity: .55;
    transition: transform .15s ease; transform-origin: 50% 50%;
}
.memo-theme.ouvert::before { transform: rotate(90deg); opacity: .9; }
.memo-theme-nom { flex: 1 1 auto; }
.memo-theme.actif { background: var(--degrade); color: #fff; }
.memo-nav-nb {
    font-size: 11px; font-weight: 700; background: var(--fond); color: var(--muted);
    border-radius: 999px; padding: 1px 8px;
}
.memo-theme.actif .memo-nav-nb { background: rgba(255,255,255,.22); color: #fff; }
.memo-nav-fonctions { padding: 4px 0 10px 6px; }
.memo-nav-groupe {
    margin: 10px 0 4px; font-size: 10.5px; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: var(--muted);
}
.memo-nav-fonctions a {
    display: block; padding: 4px 8px; border-radius: 6px;
    font-family: var(--mono, Consolas, monospace); font-size: 12.5px;
    color: var(--marine); text-decoration: none;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.memo-nav-fonctions a:hover { background: var(--info-soft); color: var(--info-fort); }

@media (max-width: 820px) {
    .memo-page { grid-template-columns: 1fr; }
    .memo-nav { position: static; max-height: none; }
}

.memo-categorie {
    margin: 22px 0 10px; padding-bottom: 7px;
    border-bottom: 2px solid var(--cyan); font-size: 15px;
}
.memo-bloc-theme > .memo-categorie:first-child { margin-top: 4px; }
.memo-fiche { border-left: 4px solid var(--marine); }
.memo-fiche.memo-cible { border-color: var(--cyan); box-shadow: 0 0 0 2px rgba(0,157,224,.30); }
.memo-tete { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.memo-tete h3 {
    margin: 0; font-size: 17px; color: var(--marine);
    font-family: var(--mono, Consolas, monospace);
}
.memo-badges { display: flex; gap: 7px; flex-wrap: wrap; }
.memo-role { margin: 8px 0 12px; font-size: 14.5px; }
.memo-lignes { display: flex; flex-direction: column; gap: 6px; font-size: 13.5px; }
.memo-lignes > div { display: flex; gap: 12px; align-items: baseline; }
.memo-cle {
    flex: 0 0 74px; font-size: 11px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .04em; color: var(--muted); padding-top: 2px;
}
/* Syntaxe principale : une seule forme, bien visible sous le titre */
.memo-syntaxe {
    margin: 10px 0 10px; padding: 0;
}
.memo-syntaxe code {
    display: inline-block; padding: 5px 11px; font-size: 14px;
    background: var(--info-soft); color: var(--info-fort);
    border-radius: 7px; border: 1px solid rgba(0,157,224,.30);
}
/* Paramètres et variantes : chaque ligne est EXPLIQUÉE, jamais un nom seul */
.memo-parametres, .memo-variantes { margin: 14px 0 0; }
.memo-sous-titre {
    margin: 0 0 7px; font-size: 11px; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; color: var(--muted);
}
.memo-param {
    display: grid; grid-template-columns: minmax(120px, max-content) 1fr;
    gap: 4px 14px; align-items: baseline;
    padding: 6px 0; font-size: 13.5px;
    border-top: 1px solid var(--bordure);
}
.memo-param code { white-space: nowrap; }
@media (max-width: 620px) {
    .memo-param { grid-template-columns: 1fr; }
}
.memo-piege {
    margin: 12px 0 0; padding: 10px 14px; font-size: 13.5px;
    background: var(--warn-soft); color: var(--warn-fort);
    border-radius: 8px; border-left: 3px solid var(--warn-fort);
}
.memo-essai { margin-top: 14px; }
.memo-essai-tete {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 6px; font-size: 12.5px;
}
.memo-code {
    width: 100%; font-family: var(--mono, Consolas, monospace); font-size: 13px;
    line-height: 1.5; padding: 10px 12px; resize: vertical;
    border: 1px solid var(--bordure); border-radius: 8px;
    background: var(--fond); color: var(--texte);
}
.memo-sortie {
    margin: 8px 0 0; padding: 10px 14px; border-radius: 8px;
    background: #0F2137; color: #E6EDF6;
    font-family: var(--mono, Consolas, monospace); font-size: 13px;
    white-space: pre-wrap; max-height: 220px; overflow: auto;
}
.memo-sortie.muted { color: #8FA3BC; font-style: italic; }
.memo-sortie.erreur { color: #FF9B95; }
.memo-reconstruire { margin-top: 12px; }
.memo-reconstruire summary {
    cursor: pointer; font-size: 13.5px; font-weight: 600; color: var(--cyan);
}
/* Table ASCII : repliée par défaut, elle ne prend qu'une ligne fermée */
.ascii-convertisseur {
    display: flex; gap: 18px; align-items: flex-end; flex-wrap: wrap;
    margin: 10px 0 12px;
}
.ascii-convertisseur label { display: flex; flex-direction: column; gap: 4px; margin: 0; }
.ascii-convertisseur input {
    width: 110px; padding: 6px 10px; font-size: 14px;
    font-family: var(--mono, Consolas, monospace);
}
.ascii-resultat {
    padding: 7px 12px; border-radius: 8px; font-size: 13px; font-weight: 600;
    font-family: var(--mono, Consolas, monospace);
    background: var(--info-soft); color: var(--info-fort);
}
.ascii-legende { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.ascii-legende .ascii-case { padding: 3px 10px; font-size: 11px; font-weight: 600; }
.ascii-grille {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
    gap: 4px; max-height: 320px; overflow: auto;
}
.ascii-case {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: 5px 2px; border-radius: 6px; line-height: 1.15;
    font-family: var(--mono, Consolas, monospace); border: 1px solid transparent;
}
.ascii-case b { font-size: 14px; }
.ascii-case small { font-size: 10.5px; opacity: .75; }
.ascii-case.chiffre    { background: var(--ok-soft);     color: var(--ok-fort); }
.ascii-case.majuscule  { background: var(--info-soft);   color: var(--info-fort); }
.ascii-case.minuscule  { background: var(--warn-soft);   color: var(--warn-fort); }
.ascii-case.symbole    { background: var(--fond); color: var(--muted); border-color: var(--bordure); }

.memo-reconstruire pre {
    margin: 8px 0 0; padding: 10px 14px; font-size: 13px;
    background: var(--fond); border: 1px solid var(--bordure); border-radius: 8px;
    font-family: var(--mono, Consolas, monospace); white-space: pre-wrap;
}

/* ── Console « Exécuter » (Python dans le navigateur) ── */
.actions-boutons { display: flex; gap: 10px; align-items: center; }
.bloc-console {
    border: 1px solid var(--bordure); border-radius: 10px;
    margin: 12px 0; overflow: hidden; background: #0F2137;
}
.console-entete {
    display: flex; align-items: center; justify-content: space-between;
    padding: 8px 14px; font-size: 12.5px; font-weight: 600;
    color: #C7D6E6; background: rgba(255,255,255,.06);
}
.console-entete .muted { color: #8FA3BC; font-weight: 400; }
.console-fermer {
    background: none; border: none; color: #8FA3BC; cursor: pointer; font-size: 13px;
}
.console-fermer:hover { color: #fff; }
#console-sortie {
    margin: 0; padding: 12px 16px; color: #E6EDF6;
    font-family: var(--mono, Consolas, monospace); font-size: 13px; line-height: 1.55;
    white-space: pre-wrap; max-height: 260px; overflow: auto;
}
#console-sortie.muted { color: #8FA3BC; font-style: italic; }
#console-sortie.console-erreur { color: #FF9B95; }

/* ── Tableau de résultat SQL (aperçu façon client MySQL) ── */
.bloc-table-sql {
    border: 1px solid var(--bordure); border-radius: 8px;
    padding: 10px 14px 12px; margin: 12px 0; background: var(--fond);
}
.table-sql-titre { margin: 0 0 6px; font-size: 12.5px; font-weight: 600; }
.table-sql-defilement { overflow-x: auto; }
.table-sql { font-size: 12.5px; font-family: var(--mono, Consolas, monospace); }
.table-sql th {
    background: var(--carte); border-bottom: 2px solid var(--cyan);
    white-space: nowrap; padding: 5px 10px;
}
.table-sql td { padding: 4px 10px; white-space: nowrap; border-top: 1px solid var(--bordure); }
.table-sql .cellule-null { color: var(--muted); font-style: italic; }

.bloc-qualite { border: 1px solid var(--bordure); border-radius: 8px; padding: 12px 14px; margin: 12px 0; }
.qualite-entete { display: flex; justify-content: space-between; align-items: center; }
.bloc-qualite p { margin: 6px 0 0; font-size: 13.5px; }

/* ── Badges ── */
.badges { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0 4px; }
.badge { font-size: 12px; padding: 3px 10px; border-radius: 12px; }
.badge-rouge { background: var(--danger-soft); color: var(--danger-fort); }
.badge-bleu { background: var(--info-soft); color: var(--info-fort); }
.badge-gris { background: var(--fond); color: var(--muted); border: 1px solid var(--bordure); }
.badge-vert { background: var(--ok-soft); color: var(--ok-fort); }
.badge-lien { text-decoration: none; transition: all .15s ease; }
.badge-lien:hover { filter: brightness(.92); transform: translateY(-1px); }
.pastille-apercu { background: var(--info-soft); color: var(--info-fort); }
.enonce { font-size: 15px; margin: 0; }

/* ── Boîte Astuce (dépliable au clic) ── */
.astuce-bloc { margin: 12px 0; }
.astuce-toggle {
    display: inline-flex; align-items: center; gap: 8px;
    background: rgba(0, 157, 224, 0.08);
    border: 1px solid rgba(0, 157, 224, 0.3);
    color: var(--cyan); font-size: 13.5px; font-weight: 600;
    padding: 7px 14px; border-radius: 8px; cursor: pointer;
}
.astuce-toggle:hover { background: rgba(0, 157, 224, 0.16); }
.astuce-icone { width: 18px; height: 18px; }
.astuce-chevron { font-size: 11px; }
.astuce-contenu {
    background: rgba(0, 157, 224, 0.06);
    border-left: 3px solid var(--cyan);
    border-radius: 0 8px 8px 0;
    padding: 10px 14px; margin-top: 6px; font-size: 13.5px;
    color: var(--texte);
}
.astuce-contenu code { background: var(--fond); padding: 1px 5px; border-radius: 4px; font-size: 12.5px; }
.astuce-ref {
    display: block; margin-top: 8px; padding-top: 8px;
    border-top: 1px dashed rgba(0, 157, 224, 0.35);
    font-size: 12.5px; color: var(--muted);
}
:root[data-theme="dark"] .astuce-icone { filter: invert(1) brightness(1.4); }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .astuce-icone { filter: invert(1) brightness(1.4); }
}

.actions { display: flex; justify-content: space-between; align-items: center; margin-top: 14px; gap: 12px; }
.actions-slides { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* ── Sommaire des cours web ── */
.grille-cours { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; margin-top: 14px; }
.carte-cours {
    display: flex; align-items: center; gap: 14px;
    text-decoration: none; color: var(--texte);
    padding: 16px 18px; margin: 0; text-align: left;
}
a.carte-cours:hover { border-color: var(--cyan); box-shadow: var(--ombre-survol); transform: translateY(-2px); }
.carte-cours .cours-num {
    flex: 0 0 auto; width: 40px; height: 40px; border-radius: 11px;
    background: var(--degrade); color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-size: 16px; font-weight: 700;
}
.carte-cours .cours-texte { flex: 1; min-width: 0; display: block; }
.carte-cours .cours-titre { display: block; font-weight: 600; font-size: 15px; line-height: 1.3; }
.carte-cours .cours-meta {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    font-size: 12.5px; margin-top: 3px;
}
.carte-cours .cours-fleche { flex: 0 0 auto; color: var(--cyan); font-size: 13px; }
.carte-cours-verrouillee { opacity: .55; }
.carte-cours-verrouillee .cours-num { background: var(--bordure); color: var(--muted); }

/* ── Liste des séances ── */
.liste-seances { display: flex; flex-direction: column; gap: 4px; }
.seance-carte {
    display: flex; justify-content: space-between; align-items: center; gap: 16px;
    text-decoration: none; color: var(--texte); margin: 6px 0;
}
a.seance-carte:hover { border-color: var(--cyan); box-shadow: var(--ombre-survol); transform: translateY(-2px); }
.seance-verrouillee { opacity: 0.55; }
.seance-titre { font-weight: 600; display: flex; align-items: center; gap: 10px; }
.seance-meta {
    display: flex; align-items: center; gap: 16px; flex: none;
}

/* Anneau de progression : l'arc est tracé par stroke-dasharray, calculé côté
   gabarit (circonférence d'un rayon 26 = 163.4). */
.anneau { position: relative; width: 62px; height: 62px; flex: none; }
.anneau svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.anneau circle { fill: none; stroke-width: 7; }
.anneau-fond { stroke: var(--bordure); }
.anneau-arc {
    stroke: var(--cyan); stroke-linecap: round;
    transition: stroke-dasharray .6s ease;
}
.anneau-arc.complet { stroke: var(--ok-fort); }
.anneau-valeur {
    position: absolute; inset: 0; display: flex;
    align-items: center; justify-content: center;
    font-size: 16px; font-weight: 700; color: var(--texte);
    font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.anneau-valeur i { font-style: normal; font-size: 10px; color: var(--muted); margin-left: 1px; }

.seance-chiffres {
    display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
    min-width: 106px;
}
.chiffre-fort {
    font-size: 19px; font-weight: 700; color: var(--marine);
    font-variant-numeric: tabular-nums; letter-spacing: -.02em; line-height: 1.1;
}
.chiffre-fort i { font-style: normal; font-size: 13px; color: var(--muted); font-weight: 600; }
.chiffre-quoi { font-size: 11.5px; color: var(--muted); letter-spacing: .02em; }
.chiffre-etoiles {
    display: inline-flex; align-items: center; gap: 4px; margin-top: 3px;
    font-size: 13px; font-weight: 600; color: var(--warn-fort);
    font-variant-numeric: tabular-nums;
}
.chiffre-etoiles i { font-style: normal; color: var(--muted); font-weight: 500; }
.symb-etoile { width: 13px; height: 13px; flex: none; }
.pastille { width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 13px; flex-shrink: 0; }
.pastille-ok { background: var(--ok-soft); color: var(--ok-fort); }
.pastille-ouverte { background: var(--info-soft); color: var(--info-fort); }
.pastille-verrou { background: var(--fond); }
.barre { height: 6px; background: var(--bordure); border-radius: 3px; margin-top: 6px; }
.barre-remplie { height: 6px; background: var(--degrade); border-radius: 3px; }

/* ── Liste des exercices ── */
.barre-progression { display: flex; gap: 4px; margin: 14px 0; }
.segment { flex: 1; height: 7px; border-radius: 4px; background: var(--bordure); transition: background .3s ease; }
.segment-ok { background: var(--ok); }
.segment-actif { background: var(--cyan); animation: pulse-segment 1.6s ease-in-out infinite; }

@keyframes pulse-segment {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.45; }
}

/* Barre de progression en tête de la page exercice */
.progression-exo { margin: 4px 0 18px; }
.progression-exo .barre-progression { margin: 0 0 6px; }
.progression-legende { font-size: 12.5px; }

.liste-exos { display: flex; flex-direction: column; gap: 6px; }
.exo-ligne {
    display: flex; align-items: center; gap: 14px;
    padding: 12px 16px; margin: 0;
    text-decoration: none; color: var(--texte);
    border-left: 4px solid transparent;
}
a.exo-ligne:hover { border-color: var(--cyan); box-shadow: var(--ombre-survol); transform: translateY(-1px); }
.exo-verrouille { opacity: 0.55; }
.exo-num {
    width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0;
    background: var(--degrade); color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-size: 13px; font-weight: 600;
}
.exo-titre { flex: 1; font-weight: 500; }
.exo-etat { font-size: 13px; display: flex; align-items: center; gap: 10px; }

/* Progression visible au niveau exercice */
.exo-reussi { background: var(--ok-soft); border-left-color: var(--ok-fort); }
.exo-reussi .exo-num { background: var(--ok-fort); color: var(--sur-ok); }
.exo-courant { border-left-color: var(--cyan); box-shadow: var(--ombre), inset 0 0 0 1px var(--cyan); }
.badge-courant {
    background: var(--info-soft); color: var(--info-fort);
    font-weight: 600; padding: 3px 10px; border-radius: 12px;
    display: inline-flex; align-items: center; gap: 6px;
}

/* ── Admin ── */
.grille-kpi { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; margin: 16px 0; }
.kpi { background: var(--carte); border: 1px solid var(--bordure); border-radius: 12px; padding: 14px 16px; box-shadow: var(--ombre); }
.kpi-cliquable { display: block; text-decoration: none; color: inherit; cursor: pointer; transition: box-shadow .2s ease, transform .2s ease, border-color .25s ease; }
.kpi-cliquable:hover { border-color: var(--cyan); box-shadow: var(--ombre-survol); transform: translateY(-2px); }
.kpi-label { display: block; font-size: 12px; color: var(--muted); }
.kpi-valeur { font-size: 24px; font-weight: 600; }
.kpi-valeur small { font-size: 13px; color: var(--muted); font-weight: 400; }

.grille-deux { display: grid; grid-template-columns: 1.1fr 1fr; gap: 12px; align-items: start; }
/* Le tableau de deblocage (5 colonnes, dont deux interrupteurs) reclame ~840 px.
   Tant que la colonne de gauche ne peut pas les offrir, on empile : sinon la
   derniere colonne (WEB2) se retrouve coupee derriere une barre de defilement.
   Le seuil de 1750 px correspond au moment ou `.contenu` passe a 1560 px et
   ou la colonne de gauche atteint ~880 px. */
@media (max-width: 1749px) { .grille-deux { grid-template-columns: 1fr; } }
@media (min-width: 1750px) { .grille-deux { grid-template-columns: 1.45fr 1fr; } }

.tableau { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.tableau th { text-align: left; color: var(--muted); font-weight: 500; font-size: 12px; padding: 6px 8px; }
.tableau td { padding: 8px; border-top: 1px solid var(--bordure); color: var(--texte); }

.form-inline { display: inline; }
.lien-upload { display: inline; color: var(--cyan); cursor: pointer; font-size: 12px; margin: 0 0 0 6px; }

.interrupteur {
    width: 38px; height: 21px; border-radius: 11px; border: none; cursor: pointer;
    background: var(--bordure); position: relative; vertical-align: middle;
}
.interrupteur::after {
    content: ""; position: absolute; top: 2px; left: 2px;
    width: 17px; height: 17px; border-radius: 50%; background: #fff;
    transition: left 0.15s;
}
.interrupteur.on { background: var(--ok); }
.interrupteur.on::after { left: 19px; }

.flux { display: flex; flex-direction: column; gap: 8px; font-size: 13.5px; }
.flux-ligne { border-radius: 6px; }
.flux-cliquable:hover { background: rgba(0, 157, 224, 0.08); }
.flux-resume { display: flex; align-items: center; gap: 10px; cursor: pointer; list-style: none; padding: 2px 4px; }
.flux-resume::-webkit-details-marker { display: none; }
.flux-texte { flex: 1; }
.flux-ligne .code-soumis { margin: 4px 0 6px 4px; }

.onglets-cours {
    display: inline-flex; gap: 4px; padding: 4px;
    background: var(--fond); border: 1px solid var(--bordure); border-radius: 11px;
}
.onglets-cours .btn-secondaire {
    border: none; background: transparent; border-radius: 8px;
    padding: 6px 16px; color: var(--muted); font-weight: 500;
}
.onglets-cours .btn-secondaire:hover { color: var(--texte); background: var(--carte); }
.onglets-cours .btn-secondaire.actif {
    background: var(--degrade); color: #fff; box-shadow: 0 1px 5px rgba(0, 157, 224, 0.35);
}
.form-export { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.form-export label { display: flex; align-items: center; gap: 6px; margin: 0; }
.form-export input[type=date] { width: auto; }

/* ---- Champ mot de passe avec bouton « afficher » -------------------------
   Les stagiaires saisissent un code genere : pouvoir le relire evite les
   blocages a la connexion. */
.champ-mdp { position: relative; display: block; }
.champ-mdp input { width: 100%; padding-right: 44px; }
.oeil-mdp {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    display: flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; padding: 0;
    background: none; border: none; border-radius: 8px;
    color: var(--muted); cursor: pointer;
    transition: color .15s ease, background .15s ease;
}
.oeil-mdp:hover { color: var(--marine); background: var(--info-soft); }
.oeil-mdp:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
.oeil-mdp[aria-pressed="true"] { color: var(--cyan); }


/* ── Téléphone ───────────────────────────────────────────────────────────────
   Les onglets du haut demandaient 484 px de large : sur un écran de 375 px, ils
   poussaient la page à 768 px et créaient un défilement horizontal. En dessous
   de 720 px ils passent donc dans une barre fixe en bas, à portée de pouce. */
@media (max-width: 720px) {
    .topbar-nav { display: none; }
    .topbar { padding: 10px 14px; }
    .brand-user { display: none; }
    .contenu { padding: 18px 13px 92px; }   /* place pour la barre du bas */

    .barre-basse {
        display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
        background: var(--carte); border-top: 1px solid var(--bordure);
        padding-bottom: env(safe-area-inset-bottom);
        box-shadow: 0 -2px 12px rgba(16, 24, 40, .10);
    }
    .seance-carte { flex-direction: column; align-items: stretch; gap: 12px; }
    .seance-meta { justify-content: flex-start; }
    .entete-page { flex-direction: column; align-items: flex-start; gap: 12px; }
    table { font-size: 13px; }
}
/* Un tableau trop large doit défiler DANS sa carte, jamais pousser la page.
   `overflow-x` posé sur le <table> lui-même n'a aucun effet : c'est le
   conteneur qui doit défiler, et il lui faut `min-width: 0` pour accepter
   d'être plus étroit que son contenu à l'intérieur d'une grille ou d'un flex. */
.carte { min-width: 0; }
.carte:has(> .tableau), .carte:has(> table) { overflow-x: auto; }
/* Repli pour les navigateurs sans :has() — le défilement reste possible. */
@supports not selector(:has(*)) {
    .carte { overflow-x: auto; }
}
/* Pas de min-width ici : forcer max-content faisait deborder le tableau des
   qu'il etait dans une colonne etroite, coupant sa premiere colonne. Le
   defilement de la carte reste le filet de securite sur telephone. */
.tableau { width: 100%; }
.tableau td, .tableau th { overflow-wrap: anywhere; }

/* ── Vidéoprojection ─────────────────────────────────────────────────────────
   Projeté en 1080p ou plus, le contenu bloqué à 980 px se tasse au centre et
   le texte devient illisible depuis le fond de la salle. On élargit ET on
   agrandit : agrandir seul déborderait, élargir seul garderait un texte minuscule. */
@media (min-width: 1400px) {
    html { font-size: 17.5px; }
    .contenu { max-width: 1240px; padding: 30px 24px 60px; }
    .onglet { font-size: 15px; padding: 9px 14px; }
    .onglet .symb { width: 19px; height: 19px; }
    /* Tableau de bord : les chiffres cles sont ce qu'on lit de loin. */
    .kpi-valeur { font-size: 30px; }
    .kpi-label { font-size: 13px; }
}
@media (min-width: 1800px) {
    html { font-size: 19.5px; }
    .contenu { max-width: 1560px; padding: 36px 32px 72px; }
    .anneau { width: 78px; height: 78px; }
    .anneau-valeur { font-size: 20px; }
    .chiffre-fort { font-size: 23px; }
    .liste-seances { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
    .liste-seances .seance-carte { margin: 0; }
    .kpi-valeur { font-size: 38px; }
    .kpi { padding: 18px 22px; }
    /* Les tableaux de suivi sont lus de loin pendant le cours. */
    .tableau { font-size: 15.5px; }
    .tableau td, .tableau th { padding: 11px 14px; }
}

/* L'espace formateur porte 8 onglets : en dessous de 1450 px ils ne tiennent
   plus en toutes lettres (1038 px de large sur un ecran de 1265). Les libelles
   cedent alors la place aux seuls symboles — sauf celui de l'onglet actif, pour
   qu'on sache toujours ou l'on est. Le title prend le relais au survol. */
@media (max-width: 1450px) {
    .topbar-nav.dense .onglet { padding: 8px 10px; }
    .topbar-nav.dense .onglet span { display: none; }
    .topbar-nav.dense .onglet.actif span { display: inline; }
}
/* Filet de securite : la barre du haut ne pousse jamais la page en largeur. */
.topbar { flex-wrap: wrap; row-gap: 8px; }
.topbar-nav { flex-wrap: wrap; }

/* ── Page d'exercice : consigne et editeur cote a cote ───────────────────────
   Une seule colonne jusqu'a 1100 px (telephone, petit portable). Au-dela, la
   consigne reste sous les yeux pendant qu'on ecrit — utile en autonomie, et
   indispensable en videoprojection ou toute la classe doit voir les deux. */
.exo-grille { display: grid; gap: 20px; }
.exo-consigne, .exo-atelier { min-width: 0; }
@media (min-width: 1100px) {
    .exo-grille { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 26px; }
    .exo-consigne {
        border-right: 1px solid var(--bordure); padding-right: 24px;
        align-self: start; position: sticky; top: 16px;
    }
}
/* Le champ de code grandit avec l'ecran : c'est la zone qu'on lit le plus. */
@media (min-width: 1400px) {
    #code { font-size: 15px; line-height: 1.65; }
    .enonce { font-size: 17px; }
}
@media (min-width: 1800px) {
    #code { font-size: 17px; }
    .enonce { font-size: 19px; }
    .exo-grille { gap: 34px; }
}

/* ── Marque : logo compact + nom ─────────────────────────────────────────────
   L'ancien logo embarquait une ligne de texte (« Code de formation 2 mille
   asbl ») illisible a la taille d'une barre de navigation. Le logo compact est
   lisible, et le nom est ecrit en vrai texte a cote. */
.logo-lien { display: inline-flex; align-items: center; gap: 9px; text-decoration: none; }
.logo { height: 34px; width: auto; display: block; }
.logo-nom {
    font-weight: 700; font-size: 16px; letter-spacing: -.02em; color: var(--marine);
}
/* Deux vraies variantes du logo, toutes deux a fond transparent : la bleue de
   la charte en clair, et une version blanche en sombre — ou seul le « 2 »
   garde sa couleur d'origine. Aucun filtre, aucune plaque derriere. */
.logo-nuit, .logo-login.logo-nuit { display: none; }
:root[data-theme="dark"] .logo-jour { display: none; }
:root[data-theme="dark"] .logo-nuit { display: block; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .logo-jour { display: none; }
    :root:not([data-theme="light"]) .logo-nuit { display: block; }
}
@media (max-width: 720px) { .logo-nom { display: none; } }

/* ── Decor de la page de connexion ───────────────────────────────────────────
   Du code du cours en filigrane, de part et d'autre du formulaire. Il ne
   s'affiche que la ou il y a de la place (>= 1200 px), reste tres en retrait,
   et disparait si l'utilisateur demande moins d'animations ou plus de
   contraste. Il n'apparait QUE sur la connexion : ailleurs l'ecran contient du
   vrai code, et un faux code derriere preterait a confusion. */
.decor-code { display: none; }
@media (min-width: 1200px) {
    .decor-code { display: block; position: fixed; inset: 0; z-index: 0;
                  pointer-events: none; user-select: none; overflow: hidden; }
    .decor-code pre {
        position: absolute; top: 50%; margin: 0;
        font-family: var(--mono, Consolas, monospace);
        font-size: 12.5px; line-height: 2.1; white-space: pre;
        color: var(--marine); opacity: .06;
    }
    .decor-code pre:first-child  { left: 3vw;  transform: translateY(-50%) rotate(-2deg); }
    .decor-code pre:last-child   { right: 3vw; transform: translateY(-50%) rotate(2deg);
                                   text-align: right; }
    .carte-login { position: relative; z-index: 1; }
}
/* En sombre, le bleu de la charte est plus clair : on baisse encore. */
:root[data-theme="dark"] .decor-code pre { opacity: .045; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .decor-code pre { opacity: .045; }
}
@media (prefers-reduced-motion: reduce), (prefers-contrast: more) {
    .decor-code { display: none; }
}

/* Logo de la carte de connexion : meme logo compact, en plus grand. */
.logo-login { height: 62px; width: auto; margin: 0 auto 14px; }
.logo-login.logo-jour { display: block; }
:root[data-theme="dark"] .logo-login.logo-jour { display: none; }
:root[data-theme="dark"] .logo-login.logo-nuit { display: block; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .logo-login.logo-jour { display: none; }
    :root:not([data-theme="light"]) .logo-login.logo-nuit { display: block; }
}

/* ── Fiches SQL ──────────────────────────────────────────────────────────────
   « Ou ca s'ecrit » porte l'information la plus utile des fiches SQL : l'ordre
   d'ecriture n'est pas l'ordre d'execution. On le distingue du reste. */
.memo-place {
    margin: 10px 0 0; padding: 10px 14px; font-size: 13.5px;
    background: var(--info-soft); color: var(--info-fort);
    border-radius: 8px; border-left: 3px solid var(--info-fort);
}
.memo-requete { margin-top: 14px; }
.memo-sql {
    margin: 0 0 10px; padding: 12px 14px; border-radius: 8px;
    background: #0F2137; color: #E6EDF6; overflow-x: auto;
    font-family: var(--mono, Consolas, monospace); font-size: 13px;
    line-height: 1.5; white-space: pre;
}
.memo-sql code { background: none; border: none; color: inherit; padding: 0; }
/* Le resultat est un vrai tableau : il defile dans son cadre, jamais la page. */
.memo-resultat { overflow-x: auto; border: 1px solid var(--bordure); border-radius: 8px; }
.memo-resultat .tableau { margin: 0; font-size: 13px; }
.memo-resultat .tableau th {
    background: var(--surface-2, var(--fond)); color: var(--muted);
    font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase;
}
