/*
 * Base visuelle partagée de Parkour-Stagiaire.
 *
 * V2 (2026-09-24, `Plan design/UX` v1.0) : nouvelle direction visuelle —
 * marine #0E1B2B en ancrage, rouge framboise PROFORM en accent d'action
 * (dégradé localisé autorisé, §10), sarcelle #16C7B9 en accent secondaire
 * (progression, repères actifs), typographies Space Grotesk (titres) et
 * Manrope (texte), auto-hébergées (assets/fonts, licence OFL — aucun appel
 * à un service tiers, cohérent avec la politique RGPD du projet).
 *
 * Règle inchangée : une couleur de statut = une information. Le rouge de
 * marque (#D92D52, rosé) reste visuellement distinct du rouge sémantique
 * d'erreur (#B42318, orangé) — `Plan design/UX` §10 révisé.
 *
 * Historique : Phase Design D1 (2026-09-09) — marine #1c3f5f + rouge
 * #c8102e, surfaces claires, peu d'ombres.
 */

@font-face {
    font-family: "Manrope";
    font-style: normal;
    font-display: swap;
    font-weight: 200 800;
    src: url("../fonts/manrope-latin-wght-normal-aA_waSK.woff2") format("woff2-variations");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Manrope";
    font-style: normal;
    font-display: swap;
    font-weight: 200 800;
    src: url("../fonts/manrope-latin-ext-wght-normal-PPaTnwi.woff2") format("woff2-variations");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Space Grotesk";
    font-style: normal;
    font-display: swap;
    font-weight: 300 700;
    src: url("../fonts/space-grotesk-latin-wght-normal-Dr-cltI.woff2") format("woff2-variations");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Space Grotesk";
    font-style: normal;
    font-display: swap;
    font-weight: 300 700;
    src: url("../fonts/space-grotesk-latin-ext-wght-normal-NXGsJlG.woff2") format("woff2-variations");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    /* Typographie */
    --police-texte: "Manrope", -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --police-titre: "Space Grotesk", "Manrope", -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    /* Neutres */
    --couleur-texte: #101a26;
    --couleur-texte-attenue: #5b6b7c;
    --couleur-fond: #f3f6fa;
    --couleur-surface: #ffffff;
    --couleur-surface-secondaire: #eef2f7;
    --couleur-bordure: #e4e9f0;
    --couleur-bordure-forte: #cfd7e2;

    /* Marque */
    --couleur-marine: #0e1b2b;
    --couleur-primaire: #15304f;
    --couleur-primaire-fonce: #0e1b2b;
    --couleur-accent: #d92d52;
    --couleur-accent-hover: #b8203f;
    --couleur-accent-texte: #ffffff;
    --couleur-accent-vif: #e23b5c;
    --couleur-sarcelle: #16c7b9;
    --couleur-sarcelle-texte: #0b7f76;
    --couleur-sarcelle-fond: #e3f8f6;
    --degrade-accent: linear-gradient(135deg, #e23b5c 0%, #b8203f 100%);
    --degrade-accent-survol: linear-gradient(135deg, #d92d52 0%, #a31a37 100%);
    --degrade-marine: linear-gradient(160deg, #13263d 0%, #0e1b2b 55%, #0a1422 100%);
    --degrade-bandeau: linear-gradient(120deg, #0e1b2b 0%, #15304f 60%, #0f4f5a 100%);

    /* Statuts (sémantiques, jamais la couleur de marque) */
    --couleur-succes-fond: #ecfdf3;
    --couleur-succes-texte: #067647;
    --couleur-succes-bordure: #abefc6;
    --couleur-info-fond: #eaf2fd;
    --couleur-info-texte: #1d4f91;
    --couleur-info-bordure: #b9d3f7;
    --couleur-attention-fond: #fffaeb;
    --couleur-attention-texte: #b54708;
    --couleur-attention-bordure: #fedf89;
    /* Laurier de réussite (DEC-122) : or sourd, distinct de l'attention. */
    --couleur-laurier-fond: #fbf4dc;
    --couleur-laurier-texte: #8a6a12;
    --couleur-laurier-bordure: #e6cf86;
    --couleur-erreur-fond: #fef3f2;
    --couleur-erreur-texte: #b42318;
    --couleur-erreur-bordure: #fecdca;
    --couleur-violet-fond: #f1ecfb;
    --couleur-violet-texte: #6b3fd4;
    --couleur-violet-bordure: #d9c9f5;

    /* Navigation latérale */
    --couleur-sidebar-fond: #0e1b2b;
    --couleur-sidebar-fond-clair: #1a2e45;
    --couleur-sidebar-texte: #9fb0c3;
    --couleur-sidebar-texte-actif: #ffffff;

    /* Formes */
    --rayon: 10px;
    --rayon-petit: 6px;
    --rayon-grand: 16px;
    --ombre-carte: 0 1px 2px rgba(16, 26, 38, 0.04), 0 2px 6px rgba(16, 26, 38, 0.05);
    --ombre-survol: 0 8px 24px rgba(16, 26, 38, 0.10), 0 2px 6px rgba(16, 26, 38, 0.06);
    --ombre-flottante: 0 16px 40px rgba(16, 26, 38, 0.18);
    --anneau-focus: 0 0 0 3px rgba(22, 199, 185, 0.35);
    --largeur-sidebar: 256px;
    --hauteur-header: 64px;
}

* {
    box-sizing: border-box;
}

html {
    overflow-x: hidden;
}

body {
    margin: 0;
    background-color: var(--couleur-fond);
    color: var(--couleur-texte);
    font-family: var(--police-texte);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

main, .conteneur {
    max-width: 960px;
    margin: 0 auto;
    padding: 1.75rem 1.5rem 3rem;
}

.app-contenu {
    max-width: 1360px;
    margin: 0;
    padding: 1.5rem 2rem 3rem;
}

h1, h2, h3, .police-titre {
    font-family: var(--police-titre);
    letter-spacing: -0.01em;
}

h1 {
    font-size: 1.75rem;
    line-height: 1.2;
    margin: 0 0 1rem;
    color: var(--couleur-texte);
    font-weight: 700;
    letter-spacing: -0.02em;
}

h2 {
    font-size: 1.12rem;
    margin: 2rem 0 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--couleur-bordure);
    color: var(--couleur-texte);
    font-weight: 600;
}

h2:first-of-type {
    border-top: none;
    padding-top: 0;
}

a {
    color: var(--couleur-primaire);
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
    transition: color var(--duree-rapide, 0.15s) ease;
}

a:hover {
    color: var(--couleur-accent);
}

::selection {
    background: rgba(22, 199, 185, 0.25);
}

p {
    margin: 0.5rem 0;
}

.texte-attenue {
    color: var(--couleur-texte-attenue);
}

/* Texte réservé aux lecteurs d'écran (UX1.1) : complète une information
   portée visuellement autrement (ex. date affichée en pavé jour/mois). */
.visuellement-masque {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

ul {
    padding-left: 1.25rem;
}

/* Structure applicative : sidebar pleine hauteur + colonne (header + contenu) */

.app-shell {
    display: flex;
    align-items: stretch;
    min-height: 100vh;
}

.app-sidebar {
    display: flex;
    flex-direction: column;
    flex: 0 0 var(--largeur-sidebar);
    width: var(--largeur-sidebar);
    background: var(--degrade-marine);
    padding: 1.25rem 0.9rem 1rem;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
}

.app-sidebar-marque {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.35rem 0.7rem 1.4rem;
    text-decoration: none;
}

.app-sidebar-logo {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    font-family: var(--police-titre);
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: #ffffff;
}

/* Pastille de marque (V2) : petit carré en dégradé devant le nom — repère
   d'identité, jamais porteur d'une information. */
.app-sidebar-logo::before {
    content: "";
    width: 0.8rem;
    height: 0.8rem;
    border-radius: 4px;
    background: var(--degrade-accent);
    box-shadow: 0 0 0 3px rgba(226, 59, 92, 0.18);
}

.app-sidebar-souslogo {
    font-size: 0.72rem;
    color: var(--couleur-sidebar-texte);
    padding-left: 1.35rem;
}

.app-sidebar-version {
    font-size: 0.62rem;
    color: var(--couleur-sidebar-texte);
    opacity: 0.55;
    margin-top: 0.3rem;
    padding-left: 1.35rem;
}

.app-role-actif {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0 0.6rem 1rem;
    margin: 0 0 0.75rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}

.app-role-actif label {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--couleur-sidebar-texte);
    margin: 0;
}

.app-role-actif select {
    width: 100%;
    max-width: none;
    padding: 0.5rem 0.6rem;
    border-radius: var(--rayon-petit);
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: rgba(255, 255, 255, 0.06);
    color: var(--couleur-sidebar-texte-actif);
    font-size: 0.86rem;
    font-weight: 600;
    cursor: pointer;
}

.app-role-actif select option {
    color: var(--couleur-texte);
}

.app-sidebar-nav {
    flex: 1;
}

.app-nav-groupe {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    margin-bottom: 0.9rem;
    padding-bottom: 0.9rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.app-nav-groupe:last-child {
    border-bottom: none;
}

/* Intitulé d'un groupe de navigation (V2, UXP-2 — administrateur
   fonctionnel) : repère discret, jamais cliquable. */
.app-nav-titre {
    margin: 0.2rem 0 0.35rem;
    padding: 0 0.75rem;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: rgba(159, 176, 195, 0.7);
}

.app-nav-groupe a {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.58rem 0.75rem;
    border-radius: var(--rayon-petit);
    color: var(--couleur-sidebar-texte);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 500;
    transition: background-color var(--duree-rapide) ease, color var(--duree-rapide) ease, transform var(--duree-rapide) var(--courbe-sortie);
}

.app-nav-groupe a svg {
    flex-shrink: 0;
    opacity: 0.8;
    transition: opacity var(--duree-rapide) ease, color var(--duree-rapide) ease;
}

.app-nav-groupe a:hover {
    background: rgba(255, 255, 255, 0.06);
    color: #ffffff;
    transform: translateX(2px);
}

/* Entrée active : pastille claire + repère sarcelle à gauche (V2). */
.app-nav-groupe a.actif {
    background: linear-gradient(90deg, rgba(22, 199, 185, 0.16) 0%, rgba(255, 255, 255, 0.05) 100%);
    color: var(--couleur-sidebar-texte-actif);
    font-weight: 600;
}

.app-nav-groupe a.actif::before {
    content: "";
    position: absolute;
    left: -0.9rem;
    top: 0.45rem;
    bottom: 0.45rem;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--couleur-sarcelle);
    box-shadow: 0 0 12px rgba(22, 199, 185, 0.6);
}

.app-nav-groupe a.actif svg {
    opacity: 1;
    color: var(--couleur-sarcelle);
}

.app-nav-groupe a .badge {
    margin-left: auto;
}

.app-sidebar-pied {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding-top: 0.75rem;
}

.app-aide-carte {
    position: relative;
    overflow: hidden;
    background: linear-gradient(145deg, rgba(22, 199, 185, 0.18) 0%, rgba(255, 255, 255, 0.04) 70%);
    border: 1px solid rgba(22, 199, 185, 0.22);
    border-radius: var(--rayon);
    padding: 0.95rem 1rem;
}

.app-aide-titre {
    margin: 0 0 0.2rem;
    color: #ffffff;
    font-family: var(--police-titre);
    font-weight: 600;
    font-size: 0.92rem;
}

.app-aide-texte {
    margin: 0 0 0.75rem;
    color: var(--couleur-sidebar-texte);
    font-size: 0.8rem;
    line-height: 1.45;
}

.app-aide-carte .app-aide-bouton {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    width: 100%;
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.18);
    color: #ffffff;
    font-size: 0.82rem;
    padding: 0.5rem 0.6rem;
}

.app-aide-carte .app-aide-bouton:hover {
    background: rgba(255, 255, 255, 0.18);
    border-color: rgba(255, 255, 255, 0.28);
    color: #ffffff;
}

.app-colonne {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* Header translucide (V2) : reste lisible au-dessus du contenu qui défile. */
.app-header {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1rem;
    height: var(--hauteur-header);
    padding: 0 2rem;
    background: rgba(255, 255, 255, 0.82);
    -webkit-backdrop-filter: saturate(160%) blur(12px);
    backdrop-filter: saturate(160%) blur(12px);
    border-bottom: 1px solid var(--couleur-bordure);
    position: sticky;
    top: 0;
    z-index: 20;
}

.app-header-marque {
    display: none;
}

.app-header-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.app-notif {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 50%;
    color: var(--couleur-texte-attenue);
    background: var(--couleur-surface);
    border: 1px solid var(--couleur-bordure);
    text-decoration: none;
    transition: color var(--duree-rapide) ease, border-color var(--duree-rapide) ease, transform var(--duree-rapide) var(--courbe-rebond), box-shadow var(--duree-rapide) ease;
}

/* Pastille de la cloche (N1) : nombre d'éléments réellement à traiter ou à
   consulter (jamais un simple point de couleur — le chiffre porte
   lui-même l'information, la couleur rouge n'est jamais la seule). */
.app-notif-pastille {
    position: absolute;
    top: -0.25rem;
    right: -0.25rem;
    min-width: 1.2rem;
    height: 1.2rem;
    padding: 0 0.3rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--degrade-accent);
    color: #ffffff;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1;
    border: 2px solid var(--couleur-surface);
    animation: pastille-apparition var(--duree-lente) var(--courbe-rebond) both;
}

.app-notif:hover, .app-notif.actif {
    color: var(--couleur-primaire);
    border-color: var(--couleur-bordure-forte);
    box-shadow: var(--ombre-carte);
    transform: translateY(-1px);
}

.app-compte {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    text-decoration: none;
    padding: 0.3rem 0.75rem 0.3rem 0.3rem;
    border-radius: 999px;
    background: var(--couleur-surface);
    border: 1px solid var(--couleur-bordure);
    transition: border-color var(--duree-rapide) ease, box-shadow var(--duree-rapide) ease;
}

.app-compte:hover,
.app-compte-menu[open] .app-compte,
.app-compte.actif {
    border-color: var(--couleur-bordure-forte);
    box-shadow: var(--ombre-carte);
}

/* Menu du compte (V2) : <details> natif, fermé au clic extérieur et à
   Échap par menu_deroulant_controller.js. */
.app-compte-menu {
    position: relative;
}

.app-compte-menu > summary {
    cursor: pointer;
    list-style: none;
    user-select: none;
}

.app-compte-menu > summary::-webkit-details-marker {
    display: none;
}

.app-compte-menu > summary:focus-visible {
    outline: 2px solid var(--couleur-primaire);
    outline-offset: 2px;
}

.app-compte-chevron {
    display: flex;
    color: var(--couleur-texte-attenue);
    transition: transform var(--duree-rapide) ease;
}

.app-compte-menu[open] .app-compte-chevron {
    transform: rotate(180deg);
}

.app-compte-panneau {
    position: absolute;
    right: 0;
    top: calc(100% + 0.5rem);
    z-index: 60;
    width: 18.5rem;
    max-width: calc(100vw - 1.5rem);
    max-height: calc(100vh - 5rem);
    overflow-y: auto;
    padding: 0.45rem;
    background: var(--couleur-surface);
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon);
    box-shadow: 0 16px 40px rgba(16, 24, 40, 0.14);
    animation: app-compte-apparition var(--duree-rapide) ease both;
}

@keyframes app-compte-apparition {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}

.app-compte-identite {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 0.65rem 0.65rem 0.8rem;
}

.app-compte-identite .app-avatar {
    width: 2.5rem;
    height: 2.5rem;
    font-size: 0.9rem;
}

.app-compte-identite p {
    margin: 0;
    overflow-wrap: anywhere;
}

.app-compte-identite-nom {
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--couleur-texte);
}

.app-compte-identite-email {
    font-size: 0.8rem;
    color: var(--couleur-texte-attenue);
}

.app-compte-identite-role {
    margin-top: 0.35rem !important;
    font-size: 0.78rem;
    color: var(--couleur-texte-attenue);
    line-height: 1.4;
}

.app-compte-identite-role strong {
    color: var(--couleur-texte);
    font-weight: 600;
}

.app-compte-groupe {
    margin: 0;
    padding: 0.35rem 0;
    border-top: 1px solid var(--couleur-bordure);
}

.app-compte-titre {
    margin: 0.2rem 0.65rem 0.3rem;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--couleur-texte-attenue);
}

.app-compte-lien {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.65rem;
    width: 100%;
    padding: 0.55rem 0.65rem;
    border: none;
    border-radius: var(--rayon-petit);
    background: none;
    box-shadow: none;
    color: var(--couleur-texte);
    font: inherit;
    font-size: 0.88rem;
    font-weight: 500;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.app-compte-lien svg {
    flex-shrink: 0;
    color: var(--couleur-texte-attenue);
}

.app-compte-lien:hover {
    background: var(--couleur-fond);
    color: var(--couleur-texte);
    transform: none;
    box-shadow: none;
}

.app-compte-lien.actif {
    background: var(--couleur-fond);
    color: var(--couleur-primaire);
    font-weight: 600;
}

.app-compte-lien.actif svg,
.app-compte-lien:hover svg {
    color: var(--couleur-primaire);
}

.app-compte-sortie:hover,
.app-compte-sortie:hover svg {
    color: var(--couleur-erreur-texte);
}

.app-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: var(--degrade-bandeau);
    color: #ffffff;
    font-family: var(--police-titre);
    font-size: 0.78rem;
    font-weight: 700;
    flex-shrink: 0;
}

.app-compte-nom {
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--couleur-texte);
    white-space: nowrap;
}

/* Menu mobile (V2) : sous 900px, la sidebar devient un tiroir latéral
   complet (libellés visibles, contrairement à l'ancienne barre d'icônes
   défilante). Ouverture sans JavaScript par une case à cocher associée au
   bouton « Menu » du header ; `menu_mobile_controller.js` ajoute seulement
   la fermeture par Échap et au clic sur le voile. */
.app-menu-case {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}

.app-burger,
.app-voile {
    display: none;
}

@media (max-width: 900px) {
    .app-sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 60;
        width: min(86vw, 300px);
        height: 100%;
        transform: translateX(-102%);
        transition: transform var(--duree-moyenne) var(--courbe-sortie);
        box-shadow: none;
    }

    .app-menu-case:checked ~ .app-sidebar {
        transform: translateX(0);
        box-shadow: var(--ombre-flottante);
    }

    .app-voile {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 55;
        background: rgba(14, 27, 43, 0.45);
        -webkit-backdrop-filter: blur(2px);
        backdrop-filter: blur(2px);
        opacity: 0;
        pointer-events: none;
        transition: opacity var(--duree-moyenne) ease;
    }

    .app-menu-case:checked ~ .app-voile {
        opacity: 1;
        pointer-events: auto;
    }

    .app-menu-case:focus-visible ~ .app-colonne .app-burger {
        box-shadow: var(--anneau-focus);
    }

    .app-header {
        justify-content: space-between;
        padding: 0 1rem;
        height: 58px;
    }

    .app-burger {
        display: inline-flex;
        align-items: center;
        gap: 0.45rem;
        padding: 0.45rem 0.75rem;
        border-radius: 999px;
        border: 1px solid var(--couleur-bordure);
        background: var(--couleur-surface);
        color: var(--couleur-texte);
        font-size: 0.86rem;
        font-weight: 600;
        cursor: pointer;
        margin: 0;
        -webkit-tap-highlight-color: transparent;
    }

    .app-burger:active {
        transform: scale(0.96);
    }

    .app-header-marque {
        display: inline-flex;
        align-items: center;
        gap: 0.45rem;
        font-family: var(--police-titre);
        font-weight: 700;
        letter-spacing: 0.06em;
        color: var(--couleur-marine);
        text-decoration: none;
        font-size: 1rem;
    }

    .app-header-marque::before {
        content: "";
        width: 0.7rem;
        height: 0.7rem;
        border-radius: 3px;
        background: var(--degrade-accent);
    }

    .app-compte-nom {
        display: none;
    }

    .app-compte {
        padding: 0.2rem;
    }

    .app-contenu {
        padding: 1.25rem 1rem 2.5rem;
    }
}

/* Messages flash */

/* Messages (flash et encadrés) : le sélecteur exclut `.tache` et `.badge`,
   qui portent aussi une classe de sévérité (`tache attention`) pour leur
   icône, sans être des messages. */
.succes:not(.tache):not(.badge), .erreur:not(.tache):not(.badge), .info:not(.tache):not(.badge), .attention:not(.tache):not(.badge) {
    position: relative;
    padding: 0.75rem 1rem 0.75rem 1.15rem;
    border-radius: var(--rayon);
    border: 1px solid transparent;
    margin: 0 0 1rem;
    font-size: 0.92rem;
    font-weight: 500;
    box-shadow: var(--ombre-carte);
    overflow: hidden;
}

/* Liseré de couleur à gauche (V2) : repère visuel du type de message,
   toujours doublé par le texte lui-même — jamais la couleur seule. */
.succes:not(.tache):not(.badge)::before, .erreur:not(.tache):not(.badge)::before, .info:not(.tache):not(.badge)::before, .attention:not(.tache):not(.badge)::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: currentColor;
    opacity: 0.7;
}

.succes {
    background: var(--couleur-succes-fond);
    color: var(--couleur-succes-texte);
    border-color: var(--couleur-succes-bordure);
}

.erreur {
    background: var(--couleur-erreur-fond);
    color: var(--couleur-erreur-texte);
    border-color: var(--couleur-erreur-bordure);
}

.info {
    background: var(--couleur-info-fond);
    color: var(--couleur-info-texte);
    border-color: var(--couleur-info-bordure);
}

.attention {
    background: var(--couleur-attention-fond);
    color: var(--couleur-attention-texte);
    border-color: var(--couleur-attention-bordure);
}

/* Cartes */

.carte {
    background: var(--couleur-surface);
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon-grand);
    box-shadow: var(--ombre-carte);
    padding: 1.35rem 1.5rem;
    margin-bottom: 1.25rem;
}

/* Carte « file de travail » (V2, UXP-2) : liseré vertical en dégradé,
   distingue une liste à traiter d'une liste de consultation. */
.carte-priorite {
    position: relative;
    overflow: hidden;
    border-left: none;
    padding-left: 1.75rem;
}

.carte-priorite::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: linear-gradient(180deg, var(--couleur-accent-vif) 0%, var(--couleur-sarcelle) 100%);
}

.carte h2 .badge {
    vertical-align: 0.15em;
    margin-left: 0.35rem;
}

/* Formulaire de recherche d'une liste (§12) : champ et bouton alignés sur
   une ligne, quel que soit l'écran (structure `label > input[type=search]`
   déjà commune à toutes les listes). */
form:has(> label > input[type="search"]) {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.6rem 0.75rem;
}

form:has(> label > input[type="search"]) > label {
    flex: 1 1 260px;
    max-width: 460px;
    margin: 0;
}

form:has(> label > input[type="search"]) > label > input[type="search"] {
    margin-top: 0.3rem;
    max-width: none;
}

form:has(> label > input[type="search"]) > div {
    margin: 0;
}

/* V2 : une carte qui ne contient que la recherche d'une liste devient une
   barre d'outils compacte, comme les filtres de l'Espace Partenaire. */
.carte:has(> form:only-child > label > input[type="search"]) {
    padding: 0.8rem 1rem;
}

form:has(> label > input[type="search"]) > label:has(> select) {
    flex: 0 1 240px;
}

/* Carte cliquable (lien) : se soulève légèrement au survol (V2). */
a.carte {
    display: block;
    color: inherit;
    text-decoration: none;
    transition: transform var(--duree-moyenne) var(--courbe-sortie), box-shadow var(--duree-moyenne) ease, border-color var(--duree-moyenne) ease;
}

a.carte:hover {
    transform: translateY(-3px);
    box-shadow: var(--ombre-survol);
    border-color: var(--couleur-bordure-forte);
}

/* Carte mise en avant (§13 révisé) : bandeau marine en dégradé — réservée
   à la première information utile d'un écran, jamais à un indicateur. */
.carte-vedette {
    background: var(--degrade-bandeau);
    border-color: transparent;
    color: #ffffff;
    box-shadow: var(--ombre-survol);
}

.carte-vedette h2,
.carte-vedette h3,
.carte-vedette a {
    color: #ffffff;
}

.carte-vedette .texte-attenue {
    color: rgba(255, 255, 255, 0.72);
}

.carte-signature {
    border-left: 3px solid var(--couleur-accent);
}

.carte h2 {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

.cartes-grille {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
    margin-bottom: 1.25rem;
}

/* Catalogue de formations par thèmes (F11) : carte cliquable sobre,
   cohérente avec .carte existante — jamais un style "marketplace". */
.carte-theme {
    display: block;
    text-align: center;
    text-decoration: none;
    color: inherit;
}

.carte-theme-icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    margin: 0 auto 0.75rem;
    border-radius: 14px;
    color: var(--couleur-accent);
    background: linear-gradient(145deg, rgba(226, 59, 92, 0.12) 0%, rgba(22, 199, 185, 0.12) 100%);
    transition: transform var(--duree-moyenne) var(--courbe-rebond);
}

.carte-theme:hover .carte-theme-icone {
    transform: scale(1.08) rotate(-3deg);
}

.carte-theme h2 {
    margin-bottom: 0.25rem;
}

/* Onglets (fiches à sections multiples, `Plan design/UX` §6) : CSS pur,
   sans JavaScript — un input radio caché par onglet, ciblé par label,
   panneau révélé par sélecteur de frère général. Le contenu de chaque
   panneau reste présent dans le DOM (recette et tests fonctionnels
   inchangés), seul l'affichage change. */

.onglets {
    margin-bottom: 1.25rem;
}

.onglet-radio {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.onglets-nav {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.25rem;
    border-bottom: 1px solid var(--couleur-bordure);
    margin-bottom: 1.25rem;
    overflow-x: auto;
    scrollbar-width: none;
}

.onglets-nav::-webkit-scrollbar {
    display: none;
}

.onglets-nav label,
.onglets-nav a {
    position: relative;
    flex-shrink: 0;
    padding: 0.7rem 1rem;
    cursor: pointer;
    color: var(--couleur-texte-attenue);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.92rem;
    border-bottom: 2px solid transparent;
    margin: 0 0 -1px;
    white-space: nowrap;
    transition: color var(--duree-rapide) ease, border-color var(--duree-moyenne) var(--courbe-sortie);
}

.onglets-nav label:hover,
.onglets-nav a:hover {
    color: var(--couleur-texte);
    border-bottom-color: var(--couleur-bordure-forte);
}

.onglet-radio:focus-visible ~ .onglets-nav label {
    outline: none;
}

/* Variante navigation (routes serveur distinctes plutôt que panneaux
   CSS) : même langage visuel que les onglets, onglet actif marqué par
   `.actif` plutôt que par `:checked` — réutilisée pour le parcours du
   formateur à travers une même séance (préparer / animer / émarger...),
   jusqu'ici sans aucun repère de parcours (`Plan design/UX` §8). */
.onglets-nav a.actif {
    color: var(--couleur-texte);
    border-bottom-color: var(--couleur-accent);
}

.onglet-panneau {
    display: none;
}

/* Association radio -> onglet actif / panneau visible, par position plutôt
   que par identifiant (générique, valable pour toute fiche à onglets sans
   CSS dédié par écran). Jusqu'à 6 onglets (Ma formation, `Plan design/UX`
   §6), largement suffisant ici. */
.onglet-radio:nth-of-type(1):checked ~ .onglets-nav label:nth-of-type(1),
.onglet-radio:nth-of-type(2):checked ~ .onglets-nav label:nth-of-type(2),
.onglet-radio:nth-of-type(3):checked ~ .onglets-nav label:nth-of-type(3),
.onglet-radio:nth-of-type(4):checked ~ .onglets-nav label:nth-of-type(4),
.onglet-radio:nth-of-type(5):checked ~ .onglets-nav label:nth-of-type(5),
.onglet-radio:nth-of-type(6):checked ~ .onglets-nav label:nth-of-type(6) {
    color: var(--couleur-texte);
    border-bottom-color: var(--couleur-accent);
}

/* Focus clavier sur un onglet (radio masqué) : anneau visible sur son
   libellé, même association par position que ci-dessus. */
.onglet-radio:nth-of-type(1):focus-visible ~ .onglets-nav label:nth-of-type(1),
.onglet-radio:nth-of-type(2):focus-visible ~ .onglets-nav label:nth-of-type(2),
.onglet-radio:nth-of-type(3):focus-visible ~ .onglets-nav label:nth-of-type(3),
.onglet-radio:nth-of-type(4):focus-visible ~ .onglets-nav label:nth-of-type(4),
.onglet-radio:nth-of-type(5):focus-visible ~ .onglets-nav label:nth-of-type(5),
.onglet-radio:nth-of-type(6):focus-visible ~ .onglets-nav label:nth-of-type(6) {
    box-shadow: var(--anneau-focus);
    border-radius: var(--rayon-petit) var(--rayon-petit) 0 0;
}

.onglet-radio:nth-of-type(1):checked ~ .onglet-panneau:nth-of-type(1),
.onglet-radio:nth-of-type(2):checked ~ .onglet-panneau:nth-of-type(2),
.onglet-radio:nth-of-type(3):checked ~ .onglet-panneau:nth-of-type(3),
.onglet-radio:nth-of-type(4):checked ~ .onglet-panneau:nth-of-type(4),
.onglet-radio:nth-of-type(5):checked ~ .onglet-panneau:nth-of-type(5),
.onglet-radio:nth-of-type(6):checked ~ .onglet-panneau:nth-of-type(6) {
    display: block;
}

/* Badges de statut */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.22rem 0.65rem;
    border-radius: 999px;
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1.35;
    white-space: nowrap;
    background: var(--couleur-surface-secondaire);
    color: var(--couleur-primaire);
    border: 1px solid transparent;
}

.badge-succes {
    background: var(--couleur-succes-fond);
    color: var(--couleur-succes-texte);
    border-color: var(--couleur-succes-bordure);
}

.badge-info {
    background: var(--couleur-info-fond);
    color: var(--couleur-info-texte);
    border-color: var(--couleur-info-bordure);
}

.badge-attention {
    background: var(--couleur-attention-fond);
    color: var(--couleur-attention-texte);
    border-color: var(--couleur-attention-bordure);
}

.badge-erreur {
    background: var(--couleur-erreur-fond);
    color: var(--couleur-erreur-texte);
    border-color: var(--couleur-erreur-bordure);
}

.badge-neutre {
    background: var(--couleur-fond);
    color: var(--couleur-texte-attenue);
    border-color: var(--couleur-bordure);
}

/* Verrou administratif d'un rattachement (F1) : icône cliquable dans le
   tableau des stagiaires d'une session — déverrouillé reste neutre
   (fonctionnement normal, pas d'alerte), verrouillé reprend la palette
   erreur déjà utilisée pour tout ce qui nécessite l'attention de
   l'administratif ailleurs dans l'application. */

.verrou-etat {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    border: 1px solid var(--couleur-bordure);
    color: var(--couleur-texte-attenue);
    background: var(--couleur-surface);
}

.verrou-etat:hover {
    border-color: var(--couleur-primaire);
    color: var(--couleur-primaire);
}

.verrou-etat.verrouille {
    background: var(--couleur-erreur-fond);
    color: var(--couleur-erreur-texte);
    border-color: var(--couleur-erreur-bordure);
}

.verrou-etat.verrouille:hover {
    color: var(--couleur-erreur-texte);
    border-color: var(--couleur-erreur-texte);
}

/* Laurier de réussite (DEC-122) — même gabarit que le verrou. */
.laurier-etat {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    border: 1px dashed var(--couleur-bordure-forte);
    color: var(--couleur-texte-attenue);
    background: var(--couleur-surface);
}

.laurier-etat:hover {
    border-color: var(--couleur-primaire);
    color: var(--couleur-primaire);
}

.laurier-etat.acquis {
    border-style: solid;
    background: var(--couleur-laurier-fond);
    color: var(--couleur-laurier-texte);
    border-color: var(--couleur-laurier-bordure);
}

.laurier-etat.acquis:hover {
    border-color: var(--couleur-laurier-texte);
}

.badge-laurier {
    background: var(--couleur-laurier-fond);
    color: var(--couleur-laurier-texte);
    border: 1px solid var(--couleur-laurier-bordure);
}

/* Tableaux */

.tableau-scroll {
    overflow-x: auto;
}

table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    background: var(--couleur-surface);
    margin: 0.75rem 0 1.5rem;
    font-size: 0.92rem;
}

th, td {
    text-align: left;
    padding: 0.8rem 0.8rem;
    border-bottom: 1px solid var(--couleur-bordure);
    vertical-align: middle;
}

th {
    background: var(--couleur-surface-secondaire);
    color: var(--couleur-texte-attenue);
    font-weight: 700;
    font-size: 0.74rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    white-space: nowrap;
}

thead th:first-child {
    border-top-left-radius: var(--rayon-petit);
}

thead th:last-child {
    border-top-right-radius: var(--rayon-petit);
}

tbody tr {
    transition: background-color var(--duree-rapide) ease;
}

tbody tr:hover {
    background: rgba(22, 199, 185, 0.05);
}

tbody tr:last-child td {
    border-bottom: none;
}

/* Formulaires */

form {
    margin: 0.75rem 0;
}

/* Espacement entre champs : couvre à la fois les lignes de formulaire
   manuelles (.form-ligne, formulaires HTML sans FormType) et les lignes
   générées par Symfony Form (form_row), qui rend chaque champ dans un
   <div> sans classe — jusqu'ici totalement sans espacement (référentiel
   §11 : « les champs sont regroupés logiquement », pas collés). */
form > div {
    margin-bottom: 0.9rem;
}

label {
    display: block;
    font-weight: 600;
    font-size: 0.88rem;
    margin-bottom: 0.3rem;
    color: var(--couleur-texte-attenue);
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="date"],
input[type="number"],
input[type="file"],
select,
textarea,
input[type="search"],
input[type="tel"],
input[type="time"],
input[type="url"] {
    width: 100%;
    max-width: 420px;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--couleur-bordure-forte);
    border-radius: var(--rayon);
    background: var(--couleur-surface);
    color: var(--couleur-texte);
    font-size: 0.94rem;
    font-family: inherit;
    transition: border-color var(--duree-rapide) ease, box-shadow var(--duree-rapide) ease;
}

input[type="text"]:hover,
input[type="email"]:hover,
input[type="password"]:hover,
input[type="date"]:hover,
input[type="number"]:hover,
input[type="search"]:hover,
input[type="tel"]:hover,
input[type="time"]:hover,
select:hover,
textarea:hover {
    border-color: #b7c2d0;
}

input[type="checkbox"],
input[type="radio"] {
    accent-color: var(--couleur-accent);
}

input[type="text"]:focus-visible,
input[type="email"]:focus-visible,
input[type="password"]:focus-visible,
input[type="date"]:focus-visible,
input[type="number"]:focus-visible,
input[type="file"]:focus-visible,
input[type="search"]:focus-visible,
input[type="tel"]:focus-visible,
input[type="time"]:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: none;
    border-color: var(--couleur-sarcelle-texte);
    box-shadow: var(--anneau-focus);
}

a:focus-visible,
button:focus-visible,
input[type="submit"]:focus-visible,
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible,
summary:focus-visible {
    outline: 2px solid var(--couleur-sarcelle-texte);
    outline-offset: 2px;
}

textarea {
    max-width: 100%;
    min-height: 4.5rem;
}

.form-ligne {
    margin-bottom: 0.9rem;
}

/* Formulaires Symfony — rendu par défaut (`form_row`), jamais un Form
   Theme global (Phase Design D5.1) : additions ciblées sur des éléments
   jusqu'ici totalement non stylés, sans toucher `form`, `label`, `button`,
   `input[type=submit]` ni `form > div`. Tout ce qui n'est pas garanti
   exclusif au rendu par défaut de Symfony (`.help-text`) est scopé sous
   `.formulaire-page` — seuls les formulaires effectivement migrés au
   patron D5 sont concernés, jamais l'ensemble du projet par avance. */

/* Aide de champ (`help`, option FormType déjà existante) — Symfony rend
   toujours `<div class="help-text">`, jamais modifié ici : seule la classe
   déjà émise est stylée. Recherche effectuée avant d'élargir la portée :
   aucune occurrence manuelle de `help-text` dans templates/, uniquement
   produite par `form_div_layout.html.twig` (thème par défaut) — donc
   sans risque à rester globale. */
.help-text {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.82rem;
    color: var(--couleur-texte-attenue);
}

/* Conteneur de page formulaire (Phase Design D5.1) : largeur raisonnable,
   et portée de scope pour toutes les règles ci-dessous qui réinterprètent
   une structure HTML générique (pas une classe propre à Symfony) —
   jamais de sélecteur global qui toucherait aussi un écran non migré
   (ex. `planning/consulter.html.twig`, hors périmètre D5, traité en D6). */
.formulaire-page {
    max-width: 720px;
}

/* Étiquette requise — Symfony ajoute déjà `class="required"` au `<label>`
   selon l'option `required` du FormType (calculée, jamais dupliquée ici) ;
   seul le scope sous `.formulaire-page` est nouveau, la classe `required`
   elle-même reste la source de vérité Symfony. */
.formulaire-page label.required::after {
    content: " *";
    color: var(--couleur-accent);
}

/* Erreurs de validation par champ — rendu par défaut de `form_row`
   (`form_errors`) : un `<ul>` sans classe, soit direct enfant du `<div>`
   de ligne, soit direct enfant du `<form>` pour une erreur de niveau
   formulaire. `form > div > ul`/`form > ul` décrivent une structure HTML
   générique, pas une classe Symfony — scopés sous `.formulaire-page` pour
   ne concerner que les formulaires déjà migrés au patron D5. */
.formulaire-page form > div > ul,
.formulaire-page form > ul {
    margin: 0.3rem 0 0;
    padding: 0;
    list-style: none;
    color: var(--couleur-erreur-texte);
    font-size: 0.85rem;
}

.formulaire-page form > div > ul li,
.formulaire-page form > ul li {
    margin-top: 0.15rem;
}

.formulaire-page fieldset {
    border: none;
    border-top: 1px solid var(--couleur-bordure);
    margin: 2rem 0 0;
    padding: 1.1rem 0 0;
}

.formulaire-page legend {
    padding: 0;
    margin: 0 0 0.85rem;
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--couleur-texte);
}

/* `input[type="time"]` (Phase Design D5.1) : confirmé réellement utilisé
   par `SessionExamenType` (2 `TimeType` en `widget: single_text`), donc
   dans le périmètre D5.1 — mais la seule autre occurrence du projet est
   `planning/consulter.html.twig` (HTML brut, hors périmètre, traité en
   D6). Dupliqué ici plutôt qu'ajouté à la liste globale `input[type=date],
   select, textarea` (ligne ~738) pour ne pas modifier visuellement
   Planning avant sa propre refonte — même déclaration que cette liste,
   scopée sous `.formulaire-page`. */
.formulaire-page input[type="time"] {
    width: 100%;
    max-width: 420px;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon);
    background: var(--couleur-surface);
    color: var(--couleur-texte);
    font-size: 0.92rem;
    font-family: inherit;
}

.formulaire-page input[type="time"]:focus-visible {
    outline: 2px solid var(--couleur-primaire);
    outline-offset: 1px;
}

/* Variante large de `.formulaire-page` (Phase Design D5.4) : pour une
   grille de critères dense (ex. certification SST) dont les libellés
   longs ne tiennent pas confortablement dans les 720px standard.
   Modificateur, jamais une classe séparée (même patron que
   `.parcours`/`.parcours--vertical`) : l'élément garde `.formulaire-page`
   et hérite donc sans duplication de tout son traitement (fieldset/
   legend, erreurs, required, input[type=time]). */
.formulaire-page--large {
    max-width: 900px;
}

/* Grille de critères homogènes et répétitifs (Phase Design D5.4) : une
   série de cases à cocher avec un libellé long chacune (ex. indicateurs
   SST), bien plus dense qu'un formulaire courant — le rendu par défaut de
   `form_row` (libellé au-dessus, case en dessous) gaspille une ligne par
   critère. Ici la case reste avant son libellé visuellement (`order`),
   sans changer l'ordre du DOM ni le rendu Symfony sous-jacent (aucun JS,
   aucun Form Theme). Générique et réutilisable pour toute future grille
   métier comparable (jamais une classe par critère). */
.grille-criteres > div {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    padding: 0.45rem 0.5rem;
    border-radius: var(--rayon-petit);
}

.grille-criteres > div:hover {
    background: var(--couleur-surface-secondaire);
}

.grille-criteres label {
    order: 2;
    margin-bottom: 0;
    font-weight: 400;
    font-size: 0.9rem;
    color: var(--couleur-texte);
    cursor: pointer;
}

.grille-criteres input[type="checkbox"] {
    order: 1;
    flex-shrink: 0;
    margin-top: 0.2rem;
    cursor: pointer;
}

/* Deux champs de même nature affichés côte à côte (ex. dates ou heures
   liées) — jamais forcé, seulement quand les champs s'y prêtent
   naturellement. Les lignes `form_row` internes restent des `div` : elles
   deviennent simplement des cellules de grille, `.formulaire-grille`
   porte elle-même l'espacement vertical normalement dévolu à `form > div`. */
.formulaire-grille {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 1.25rem;
    margin-bottom: 0.9rem;
}

.formulaire-grille > div {
    margin-bottom: 0;
}

@media (max-width: 560px) {
    .formulaire-grille {
        grid-template-columns: 1fr;
        gap: 0;
    }

    .formulaire-grille > div {
        margin-bottom: 0.9rem;
    }

    .formulaire-grille > div:last-child {
        margin-bottom: 0;
    }
}

/* Zone d'actions finales — sépare visuellement le bouton de soumission
   des champs, jamais un second bouton « Annuler » (le lien de retour en
   haut de page reste le seul mécanisme d'abandon). */
.formulaire-actions {
    margin-top: 2rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--couleur-bordure);
}

/* Boutons */

/* Bouton d'action principale (V2, §10 révisé) : dégradé framboise
   localisé. Contraste du texte blanc ≥ 4,5:1 sur toute la largeur du
   dégradé. Les boutons porteurs d'une classe propre (bouton discret, de
   fermeture, cellule de matrice…) redéfinissent leur fond et ne reçoivent
   ni ombre ni soulèvement : seuls les boutons « nus » et `.bouton-primaire`
   s'animent au survol. */
button, input[type="submit"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    background: var(--degrade-accent);
    color: var(--couleur-accent-texte);
    border: 1px solid transparent;
    border-radius: var(--rayon);
    padding: 0.58rem 1.1rem;
    font-size: 0.9rem;
    font-weight: 700;
    font-family: inherit;
    line-height: 1.3;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

button:not([class]), input[type="submit"]:not([class]) {
    box-shadow: 0 1px 2px rgba(184, 32, 63, 0.25), 0 4px 12px rgba(217, 45, 82, 0.18);
    transition: transform var(--duree-rapide) var(--courbe-sortie), box-shadow var(--duree-moyenne) ease, opacity var(--duree-rapide) ease;
}

button:not([class]):hover, input[type="submit"]:not([class]):hover {
    background: var(--degrade-accent-survol);
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(184, 32, 63, 0.25), 0 10px 22px rgba(217, 45, 82, 0.26);
}

button:not([class]):active, input[type="submit"]:not([class]):active {
    transform: translateY(0) scale(0.98);
    box-shadow: 0 1px 2px rgba(184, 32, 63, 0.3);
}

button:disabled, input[type="submit"]:disabled,
button[aria-busy="true"] {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

/* `.bouton-primaire`/`.bouton-secondaire` : mêmes styles que les éléments
   `button`/`input[type=submit]` natifs ci-dessus, mais autonomes — pour un
   lien `<a>` stylé comme un bouton (`.bouton-secondaire` était déjà utilisé
   ainsi sur plusieurs écrans sans porter son propre gabarit de boîte,
   corrigé ici plutôt que dupliqué à chaque nouvel usage). */

.bouton-primaire, .bouton-secondaire {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    border: 1px solid transparent;
    border-radius: var(--rayon);
    padding: 0.58rem 1.1rem;
    font-size: 0.9rem;
    font-weight: 700;
    font-family: inherit;
    line-height: 1.3;
    text-decoration: none;
    cursor: pointer;
    transition: transform var(--duree-rapide) var(--courbe-sortie), box-shadow var(--duree-moyenne) ease, background var(--duree-moyenne) ease, border-color var(--duree-rapide) ease, color var(--duree-rapide) ease;
    -webkit-tap-highlight-color: transparent;
}

.bouton-primaire {
    background: var(--degrade-accent);
    color: var(--couleur-accent-texte);
    box-shadow: 0 1px 2px rgba(184, 32, 63, 0.25), 0 4px 12px rgba(217, 45, 82, 0.18);
}

.bouton-primaire:hover {
    background: var(--degrade-accent-survol);
    color: var(--couleur-accent-texte);
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(184, 32, 63, 0.25), 0 10px 22px rgba(217, 45, 82, 0.26);
}

.bouton-secondaire {
    background: var(--couleur-surface);
    color: var(--couleur-texte);
    border-color: var(--couleur-bordure-forte);
    box-shadow: 0 1px 2px rgba(16, 26, 38, 0.05);
}

.bouton-secondaire:hover {
    background: var(--couleur-surface);
    border-color: var(--couleur-primaire);
    color: var(--couleur-primaire);
    transform: translateY(-1px);
    box-shadow: var(--ombre-carte);
}

/* `.bouton-secondaire` porté par un `<button>` : l'aplat blanc prime sur
   le dégradé des boutons natifs. */
button.bouton-secondaire {
    background: var(--couleur-surface);
    color: var(--couleur-texte);
}

.bouton-primaire:active, .bouton-secondaire:active {
    transform: translateY(0) scale(0.98);
}

.bouton-petit {
    padding: 0.35rem 0.75rem;
    font-size: 0.82rem;
    border-radius: var(--rayon-petit);
}

/* Ligne d'état vide « calme » (`Plan design/UX` §16.4, généralisé en V2). */
.etat-vide-ligne {
    margin-top: 0.25rem;
    font-size: 0.88rem;
}

/* Pagination des listes principales (T3.2), même patron que
   `.planning-navigation` (prev/label/next) — un seul composant Twig/CSS
   réutilisé par tous les écrans paginés, jamais une variante par écran. */

.pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-top: 1rem;
}

.pagination-info {
    color: var(--couleur-texte-attenue);
    font-size: 0.9rem;
}

.pagination-inactif {
    opacity: 0.5;
    pointer-events: none;
}

/* En-tête des écrans de liste (Phase Design D3) : titre à gauche, action
   principale (`.bouton-primaire`) et liens secondaires à droite — plutôt
   qu'un lien texte perdu sous le `h1`, l'action la plus utile de l'écran
   (créer) devient immédiatement visible et cohérente avec la hiérarchie de
   boutons posée en D1. */

.liste-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.liste-entete h1 {
    margin-bottom: 0;
}

.liste-entete-actions {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}

/* En-tête de fiche détail (Phase Design D4.1) : distinct de `.liste-entete`
   (écrans de liste) — porte en plus les métadonnées et statuts d'une fiche
   métier (session, dossier, formation, formateur). Introduit sur Session ;
   à généraliser aux autres fiches (D4.2 à D4.4) si le patron convient tel
   quel, mutualisation Twig éventuelle décidée séparément en D4.5. */

.fiche-retour {
    display: inline-block;
    margin-bottom: 1rem;
    color: var(--couleur-texte-attenue);
    font-size: 0.88rem;
    text-decoration: none;
}

.fiche-retour:hover {
    color: var(--couleur-primaire);
}

/* V2 : l'icône « flèche » des liens de retour pointe vers l'arrière et
   recule légèrement au survol. */
.fiche-retour {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.fiche-retour svg {
    transform: rotate(180deg);
    transition: transform var(--duree-moyenne) var(--courbe-sortie);
}

.fiche-retour:hover svg {
    transform: rotate(180deg) translateX(3px);
}

.fiche-entete {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.5rem;
}

.fiche-entete-identite {
    flex: 1 1 320px;
    min-width: 0;
}

.fiche-entete-identite h1 {
    margin-bottom: 0.5rem;
}

.fiche-entete-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 1.2rem;
    margin: 0 0 0.65rem;
    color: var(--couleur-texte-attenue);
    font-size: 0.88rem;
}

.fiche-entete-meta span {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.fiche-entete-statuts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.fiche-entete-actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    flex-shrink: 0;
}

/* v1.118 : accès rapides d'une fiche Session Formateur (stagiaires, ordre
   de mission, évaluation qualité), rendus sous l'en-tête plutôt que dans
   `.fiche-entete-actions` elle-même (déjà réservée à l'action de
   construction de planning, admin uniquement) — même classe de boutons,
   simplement décalée du bloc titre. */
.planning-actions-rapides {
    margin-bottom: 1.25rem;
}

/* Sections principales d'une fiche détail : grandes zones séparées par un
   simple filet plutôt qu'empilées en cartes indépendantes (référentiel
   design §13 : « pas une carte autour de chaque information »). Le titre
   de section porte ses propres règles (`.fiche-section-titre`, spécificité
   supérieure à `h2`) plutôt que de dépendre de `h2:first-of-type`, qui ne
   fonctionnerait pas ici : chaque section est un conteneur `div` distinct,
   donc chaque `h2` y serait « premier de son type » et perdrait à tort son
   filet supérieur. */

.fiche-section {
    margin-top: 2rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--couleur-bordure);
}

.fiche-section:first-of-type {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

.fiche-section-titre {
    margin: 0 0 0.85rem;
    padding-top: 0;
    border-top: none;
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--couleur-texte);
}

.fiche-section-description {
    margin: -0.5rem 0 1rem;
    color: var(--couleur-texte-attenue);
    font-size: 0.88rem;
}

/* Volet « Sessions terminées » (Phase Design D3.1) : `<details>` natif,
   jamais de JavaScript pour un simple repli — replié par défaut sans
   attribut `open`, accessible au clavier nativement. */

.liste-repliable > summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--couleur-texte);
    list-style-position: outside;
}

.liste-repliable[open] > summary {
    margin-bottom: 0.9rem;
}

/* Écran de connexion — deux zones (identité PROFORM / formulaire), pleine
   hauteur, en dehors du conteneur centré `main` (échappement volontaire de
   son max-width/padding, seul écran de l'application à le faire). */

.ecran-connexion-split {
    position: relative;
    left: 50%;
    width: 100vw;
    margin-left: -50vw;
    margin-top: -1.75rem;
    margin-bottom: -3rem;
    min-height: 100vh;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.connexion-identite {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--degrade-bandeau);
    padding: 3rem 2rem;
}

/* Halos de couleur (V2) : profondeur visuelle du panneau d'identité,
   purement décoratifs, statiques. */
.connexion-identite::before,
.connexion-identite::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    filter: blur(60px);
    pointer-events: none;
}

.connexion-identite::before {
    width: 22rem;
    height: 22rem;
    top: -6rem;
    right: -6rem;
    background: rgba(226, 59, 92, 0.35);
}

.connexion-identite::after {
    width: 18rem;
    height: 18rem;
    bottom: -5rem;
    left: -4rem;
    background: rgba(22, 199, 185, 0.3);
}

.connexion-identite-corps {
    position: relative;
    z-index: 1;
    animation: apparition-montee var(--duree-lente) var(--courbe-sortie) both;
}

.connexion-identite-corps {
    max-width: 360px;
}

.connexion-marque {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    font-family: var(--police-titre);
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #ffffff;
}

.connexion-marque::before {
    content: "";
    width: 0.8rem;
    height: 0.8rem;
    border-radius: 4px;
    background: var(--degrade-accent);
    box-shadow: 0 0 0 4px rgba(226, 59, 92, 0.2);
}

.connexion-produit {
    margin: 1.1rem 0 0.75rem;
    color: #ffffff;
    font-size: 2.4rem;
    line-height: 1.1;
    letter-spacing: -0.03em;
}

.connexion-accroche {
    margin: 0;
    color: var(--couleur-sidebar-texte);
    font-size: 0.95rem;
    line-height: 1.6;
}

.connexion-formulaire {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--couleur-fond);
    padding: 3rem 2rem;
}

.connexion-formulaire-corps {
    width: 100%;
    max-width: 380px;
    background: var(--couleur-surface);
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon-grand);
    box-shadow: var(--ombre-survol);
    padding: 2rem 1.9rem 1.6rem;
    animation: apparition-montee var(--duree-lente) var(--courbe-sortie) 80ms both;
}

.connexion-formulaire-corps h2 {
    margin: 0 0 1.25rem;
    padding: 0;
    border: none;
    font-size: 1.5rem;
    letter-spacing: -0.02em;
}

.connexion-formulaire-corps input[type="email"],
.connexion-formulaire-corps input[type="password"] {
    max-width: none;
}

.connexion-formulaire-corps button {
    width: 100%;
    margin-top: 0.6rem;
    padding: 0.75rem 0.9rem;
    font-size: 0.95rem;
}

@media (max-width: 780px) {
    .ecran-connexion-split {
        grid-template-columns: 1fr;
        min-height: auto;
    }

    .connexion-identite {
        padding: 2.25rem 1.5rem;
    }

    .connexion-produit {
        font-size: 1.8rem;
    }

    .connexion-formulaire {
        padding: 1.5rem 1rem 3rem;
    }

    .connexion-formulaire-corps {
        padding: 1.5rem 1.25rem 1.25rem;
    }
}

/* Liens réglementaires (politique de confidentialité, mentions légales) —
   présentation discrète et secondaire, réutilisée sur la connexion et sur
   « Mon compte » (LOT CONFORMITÉ V1). Positionnement en flux naturel,
   jamais absolu ni calé sur une résolution précise, pour rester correct en
   desktop, petit écran et page à contenu variable. */

.liens-reglementaires {
    margin-top: 3rem;
    text-align: center;
    font-size: 0.8rem;
}

.liens-reglementaires a {
    color: var(--couleur-texte-attenue);
}

.liens-reglementaires a:hover {
    color: var(--couleur-primaire);
}

.liens-reglementaires span {
    margin: 0 0.5rem;
    color: var(--couleur-bordure);
}

/* Pages légales publiques (politique de confidentialité, mentions légales) */

.page-legale {
    max-width: 760px;
    margin: 0 auto;
}

/* Page d'accueil publique (hors périmètre AFI, sans sidebar) */

.ecran-accueil-public {
    max-width: 640px;
    margin: 4rem auto;
    padding: 0 1.5rem;
    text-align: center;
}

.accueil-public-marque {
    margin-bottom: 2.5rem;
}

.accueil-public-logo-image {
    display: block;
    max-width: 220px;
    height: auto;
    margin: 0 auto;
}

.accueil-public-signature {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 0.6rem;
}

.accueil-public-signature .texte-attenue {
    font-size: 0.85rem;
}

.accueil-public-logo-make {
    display: block;
    height: 38px;
    width: auto;
}

.ecran-accueil-public h1 {
    font-size: 2.1rem;
}

.accueil-public-choix {
    display: flex;
    gap: 1rem;
    margin-top: 2rem;
}

.accueil-public-carte {
    flex: 1;
    position: relative;
    overflow: hidden;
    background: var(--couleur-surface);
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon-grand);
    padding: 1.6rem 1.35rem;
    text-decoration: none;
    color: var(--couleur-texte);
    box-shadow: var(--ombre-carte);
    transition: transform var(--duree-moyenne) var(--courbe-sortie), box-shadow var(--duree-moyenne) ease, border-color var(--duree-moyenne) ease;
    animation: apparition-montee var(--duree-lente) var(--courbe-sortie) both;
}

.accueil-public-carte + .accueil-public-carte {
    animation-delay: 80ms;
}

.accueil-public-carte::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 4px;
    background: var(--couleur-bordure-forte);
}

.accueil-public-carte:hover {
    transform: translateY(-4px);
    box-shadow: var(--ombre-survol);
    border-color: var(--couleur-bordure-forte);
    color: var(--couleur-texte);
}

.accueil-public-carte-titre {
    display: block;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--couleur-primaire);
    margin-bottom: 0.35rem;
}

.accueil-public-carte-principale::before {
    background: var(--degrade-accent);
}

.accueil-public-carte-principale .accueil-public-carte-titre {
    color: var(--couleur-accent);
}

@media (max-width: 640px) {
    .accueil-public-choix {
        flex-direction: column;
    }
}

/* Écran d'attente « en construction » (espace entreprises) */

.ecran-chantier {
    max-width: 480px;
    margin: 4rem auto;
    padding: 0 1.5rem;
    text-align: center;
}

.chantier-bandeau {
    height: 10px;
    border-radius: var(--rayon-petit);
    margin-bottom: 1.75rem;
    background-image: repeating-linear-gradient(
        45deg,
        var(--couleur-attention-texte),
        var(--couleur-attention-texte) 12px,
        var(--couleur-attention-fond) 12px,
        var(--couleur-attention-fond) 24px
    );
}

.chantier-etiquette {
    display: inline-block;
    background: var(--couleur-attention-fond);
    color: var(--couleur-attention-texte);
    border: 1px solid var(--couleur-attention-bordure);
    border-radius: 999px;
    padding: 0.25rem 0.85rem;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 0.75rem;
}

/* Parcours (étapes) */

.parcours {
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    margin: 1rem 0 1.75rem;
}

.parcours-etape {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.9rem 0.5rem 0;
    font-size: 0.88rem;
    color: var(--couleur-texte-attenue);
}

.parcours-etape:not(:last-child)::after {
    content: "";
    display: inline-block;
    width: 1.75rem;
    height: 2px;
    border-radius: 2px;
    background: var(--couleur-bordure-forte);
    margin-left: 0.5rem;
}

/* Liaison vers l'étape suivante déjà franchie : trait sarcelle. */
.parcours-etape.faite:not(:last-child)::after {
    background: linear-gradient(90deg, var(--couleur-sarcelle) 0%, rgba(22, 199, 185, 0.45) 100%);
}

.parcours-etape .parcours-puce {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    background: var(--couleur-surface);
    border: 2px solid var(--couleur-bordure-forte);
    font-size: 0.78rem;
    font-weight: 700;
    flex-shrink: 0;
    transition: transform var(--duree-moyenne) var(--courbe-rebond);
}

.parcours-etape.faite {
    color: var(--couleur-texte);
}

.parcours-etape.faite .parcours-puce {
    background: var(--couleur-sarcelle);
    border-color: var(--couleur-sarcelle);
    color: var(--couleur-marine);
}

/* Étape franchie en parallèle d'une étape antérieure encore en cours
   (V2, UXP-3) : cochée, mais plus légère — jamais présentée comme l'étape
   courante. */
.parcours-etape.faite.parallele {
    color: var(--couleur-texte-attenue);
}

.parcours-etape.faite.parallele .parcours-puce {
    background: var(--couleur-sarcelle-fond);
    border-color: var(--couleur-sarcelle);
    border-style: dashed;
    color: var(--couleur-sarcelle-texte);
}

.parcours-etape.faite.parallele:not(:last-child)::after,
.parcours-etape.actuelle:not(:last-child)::after {
    background: var(--couleur-bordure-forte);
}

.parcours-etape.actuelle {
    color: var(--couleur-texte);
    font-weight: 700;
}

.parcours-etape.actuelle .parcours-puce {
    background: var(--degrade-accent);
    border-color: transparent;
    color: #fff;
    transform: scale(1.1);
}

/* Niveaux de hiérarchie visuelle des 5 accueils (introduits Phase Design D1
   pour l'accueil stagiaire, généralisés D2 aux 4 accueils de rôle
   Formateur/Équipe administrative/Responsable pédagogique/Administrateur
   fonctionnel — remplace l'ancienne grille `.tableau-bord`/`.tb-principal`/
   `.tb-aside`, retirée D2, plus aucun écran ne l'utilisant) — niveau 1
   urgent/prochaine action (pleine largeur, empilé, repère marine en tête
   de chaque carte), niveau 2 blocs opérationnels de poids équivalent
   (grille), niveau 3 accès secondaires (grille, cartes compactes, utilisé
   uniquement quand l'écran distingue réellement un troisième niveau). */

.tb-niveau-1 {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1.75rem;
}

/* En-tête des tableaux de bord (V2) : salutation à gauche, action
   principale de l'écran à droite (repliée sous le titre sur mobile). */
.tb-entete {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.tb-entete h1 {
    margin-bottom: 0.3rem;
}

.tb-entete-actions {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

/* Carte de niveau 1 : fin liseré en dégradé en tête (V2), repère de
   priorité sans alourdir la carte. */
.tb-niveau-1 > .carte {
    position: relative;
    overflow: hidden;
}

.tb-niveau-1 > .carte::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--couleur-accent-vif) 0%, var(--couleur-sarcelle) 100%);
}

.tb-niveau-2 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1rem;
    align-items: start;
    margin-bottom: 1.75rem;
}

.tb-niveau-3 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 1rem;
    align-items: start;
}

.carte-compacte {
    padding: 1rem 1.15rem;
    box-shadow: none;
}

.carte-compacte h2 {
    font-size: 1rem;
    margin-bottom: 0.6rem;
}

/* Carte formation principale */

.carte-formation-entete {
    display: flex;
    align-items: flex-start;
    gap: 0.9rem;
}

.carte-formation-icone {
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 50%;
    background: var(--couleur-violet-fond);
    color: var(--couleur-violet-texte);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.carte-formation-titre {
    flex: 1;
    min-width: 0;
}

.carte-formation-titre h2 {
    margin: 0;
    padding: 0;
    border: none;
    font-size: 1.15rem;
}

/* v1.119 : titre de Session cliquable (Mes sessions, Accueil Formateur) —
   discret au repos, une trace visuelle claire au survol et au clavier
   (accessibilité), jamais toute la carte transformée en lien. */
.lien-titre-session {
    color: inherit;
    text-decoration: none;
}

.lien-titre-session:hover {
    text-decoration: underline;
}

.lien-titre-session:focus-visible {
    outline: 2px solid var(--couleur-primaire, currentColor);
    outline-offset: 2px;
    border-radius: 2px;
}

.carte-formation-meta {
    margin: 0.3rem 0 0;
    color: var(--couleur-texte-attenue);
    font-size: 0.86rem;
    display: flex;
    gap: 1.1rem;
    flex-wrap: wrap;
}

.carte-formation-meta span {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.stats-rangee {
    display: flex;
    flex-wrap: wrap;
    margin: 1.1rem 0;
    border-top: 1px solid var(--couleur-bordure);
    border-bottom: 1px solid var(--couleur-bordure);
}

.stat-tuile {
    flex: 1 1 130px;
    padding: 0.85rem 1.1rem;
    border-right: 1px solid var(--couleur-bordure);
}

.stat-tuile:last-child {
    border-right: none;
}

.stat-tuile-legende {
    display: block;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--couleur-texte-attenue);
    margin-bottom: 0.35rem;
}

.stat-tuile-valeur {
    font-family: var(--police-titre);
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--couleur-texte);
}

.stat-tuile-progression {
    flex-basis: 170px;
}

.stat-tuile-barre {
    height: 6px;
    border-radius: 999px;
    background: var(--couleur-bordure);
    margin: 0.35rem 0 0.3rem;
    overflow: hidden;
}

.stat-tuile-barre-remplissage {
    height: 100%;
    background: linear-gradient(90deg, var(--couleur-sarcelle) 0%, #0fa598 100%);
    border-radius: inherit;
    transform-origin: left center;
    animation: remplissage-barre 0.9s var(--courbe-sortie) 0.2s both;
}

@media (max-width: 620px) {
    .stat-tuile {
        flex: 1 1 45%;
        border-right: none;
        border-bottom: 1px solid var(--couleur-bordure);
    }
}

/* Zone « À faire » : chaque action comme une tâche identifiable */

.taches {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.tache {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.8rem 0.95rem;
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon);
    background: var(--couleur-surface);
    text-decoration: none;
    color: inherit;
    transition: transform var(--duree-moyenne) var(--courbe-sortie), box-shadow var(--duree-moyenne) ease, border-color var(--duree-rapide) ease;
}

.tache:hover {
    border-color: var(--couleur-bordure-forte);
    box-shadow: var(--ombre-survol);
    transform: translateX(3px);
}

.tache:hover .tache-fleche {
    color: var(--couleur-accent);
    transform: translateX(3px);
}

.tache-icone {
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.tache.urgent .tache-icone {
    background: var(--couleur-erreur-fond);
    color: var(--couleur-erreur-texte);
}

.tache.attention .tache-icone {
    background: var(--couleur-attention-fond);
    color: var(--couleur-attention-texte);
}

.tache.normal .tache-icone {
    background: var(--couleur-info-fond);
    color: var(--couleur-info-texte);
}

.tache-corps {
    flex: 1;
    min-width: 0;
}

.tache-titre {
    display: block;
    font-weight: 700;
    font-size: 0.93rem;
    color: var(--couleur-texte);
}

.tache-sous-titre {
    display: block;
    margin-top: 0.1rem;
    font-size: 0.82rem;
    color: var(--couleur-texte-attenue);
}

.tache-etiquette {
    flex-shrink: 0;
}

.tache-fleche {
    color: var(--couleur-texte-attenue);
    flex-shrink: 0;
    transition: transform var(--duree-moyenne) var(--courbe-sortie), color var(--duree-rapide) ease;
}

/* État vide « rien à signaler » (§16.4) : une ligne calme, sans cadre
   lourd — plus un grand bandeau vert. */
.tache-etat-vide {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    color: var(--couleur-succes-texte);
    background: none;
    padding: 0.35rem 0;
    font-size: 0.92rem;
    font-weight: 600;
}

/* Accès rapides (Ma formation) */

.acces-rapides {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0.85rem;
}

.acces-rapide {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1rem;
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon);
    text-decoration: none;
    color: inherit;
}

.acces-rapide:hover {
    border-color: var(--couleur-primaire);
    box-shadow: var(--ombre-carte);
}

.acces-rapide-icone {
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 50%;
    background: var(--couleur-info-fond);
    color: var(--couleur-info-texte);
    display: flex;
    align-items: center;
    justify-content: center;
}

.acces-rapide-titre {
    font-weight: 600;
    font-size: 0.92rem;
}

.acces-rapide-info {
    font-size: 0.78rem;
    color: var(--couleur-texte-attenue);
}

/* M'entraîner : QCM libre vs. examen blanc (deux usages distincts) */

.entrainement-grille {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

@media (max-width: 620px) {
    .entrainement-grille {
        grid-template-columns: 1fr;
    }
}

.entrainement-carte {
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.entrainement-carte.mise-en-situation {
    background: var(--couleur-violet-fond);
    border-color: var(--couleur-violet-bordure);
}

.entrainement-entete {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.entrainement-titre {
    font-weight: 600;
    font-size: 0.92rem;
}

.jauge {
    width: 4.2rem;
    height: 4.2rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--couleur-primaire);
    background: conic-gradient(var(--couleur-primaire) calc(var(--valeur, 0) * 1%), var(--couleur-bordure) 0);
    margin: 0 auto;
}

.jauge span {
    background: var(--couleur-surface);
    width: 3.1rem;
    height: 3.1rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Documents (résumé sur le tableau de bord) */

.documents-resume {
    display: flex;
    flex-direction: column;
}

.document-ligne {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.6rem 0;
}

.document-ligne:not(:last-child) {
    border-bottom: 1px solid var(--couleur-bordure);
}

.document-icone {
    width: 2rem;
    height: 2rem;
    border-radius: var(--rayon-petit);
    background: var(--couleur-info-fond);
    color: var(--couleur-info-texte);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.document-corps {
    flex: 1;
    min-width: 0;
}

.document-titre {
    display: block;
    font-weight: 600;
    font-size: 0.9rem;
}

.document-etat {
    display: block;
    font-size: 0.8rem;
    color: var(--couleur-texte-attenue);
}

.document-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--couleur-texte-attenue);
    flex-shrink: 0;
    padding: 0.5rem;
    margin: -0.5rem;
    border-radius: 50%;
}

.document-action:hover {
    background: var(--couleur-fond);
    color: var(--couleur-texte);
}

/* Parcours vertical (colonne secondaire) : même composant `.parcours`
   (`Plan design/UX` §16.2), simplement réorienté. */

.parcours--vertical {
    flex-direction: column;
    gap: 0;
}

.parcours--vertical .parcours-etape {
    padding: 0.4rem 0;
}

.parcours--vertical .parcours-etape:not(:last-child)::after {
    display: none;
}

/* Prochaine session (carte colonne secondaire) */

.session-info {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    font-size: 0.9rem;
}

.session-info-ligne {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    color: var(--couleur-texte);
}

.session-info-ligne svg {
    color: var(--couleur-texte-attenue);
    flex-shrink: 0;
}

@media print {
    .app-header, .app-sidebar, .no-print {
        display: none !important;
    }

    .app-shell {
        display: block;
    }
}

/* Signature tactile (Sprint Consolidation Produit, Lot F1) */

.zone-signature {
    display: block;
    width: 100%;
    max-width: 32rem;
    aspect-ratio: 2 / 1;
    height: auto;
    touch-action: none;
    background: #fff;
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon);
    margin-bottom: 0.75rem;
}

.zone-signature-actions {
    margin-bottom: 0.9rem;
}

/*
 * Calendrier de planning (Sprint Planning, étape 3 ; cadre et navigation
 * refondus en Phase Design D6.1). Classes volontairement nommées par
 * fonction (`.planning-*`) et non par couleur — jamais renommées depuis :
 * partagées avec le calendrier des sessions (`session/liste.html.twig`,
 * Phase Design D3) et testées par les deux features. D6.1 ne fait évoluer
 * que les valeurs ci-dessous (densité, hiérarchie période/navigation/vues),
 * jamais la structure ni les noms de classes.
 */

.planning-barre {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
}

.planning-vues {
    display: flex;
    gap: 0.35rem;
}

.planning-vue-lien {
    padding: 0.4rem 0.9rem;
    border-radius: var(--rayon-petit);
    border: 1px solid var(--couleur-bordure);
    color: var(--couleur-texte-attenue);
    text-decoration: none;
    font-size: 0.88rem;
    font-weight: 600;
}

.planning-vue-lien:hover {
    border-color: var(--couleur-primaire);
    color: var(--couleur-texte);
}

.planning-vue-lien.actif {
    background: var(--couleur-primaire);
    border-color: var(--couleur-primaire);
    color: #fff;
}

.planning-navigation {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.planning-navigation .bouton-secondaire {
    padding: 0.42rem 0.8rem;
}

.planning-periode {
    font-weight: 600;
    font-size: 1.02rem;
    color: var(--couleur-texte);
    min-width: 13rem;
    text-align: center;
}

.planning-corps {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    align-items: start;
    gap: 1rem;
}

.planning-panneau {
    position: sticky;
    top: 1rem;
}

.planning-detail-vide {
    padding: 0.25rem 0;
}

.planning-detail-contenu h3 {
    margin: 0.6rem 0 0.9rem;
    font-size: 1rem;
}

.planning-detail-liste {
    margin: 0;
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.4rem 0.75rem;
    font-size: 0.88rem;
}

.planning-detail-liste dt {
    color: var(--couleur-texte-attenue);
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.planning-detail-liste dd {
    margin: 0;
}

.planning-detail-action {
    margin: 1.1rem 0 0;
    padding-top: 0.9rem;
    border-top: 1px solid var(--couleur-bordure);
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Légende des couleurs (Phase Design D6.4) : explique les 5 types déjà
   rendus par `.planning-evenement-*` (D6.0-D6.2), affichée une seule fois
   dans l'état vide du panneau plutôt que par événement — jamais une
   nouvelle donnée, seuls les libellés déjà utilisés ailleurs
   (`TypeEvenementPlanning::libelle()`) sont recopiés en Twig statique. */

.planning-legende {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0.9rem 0 0;
    border-top: 1px solid var(--couleur-bordure);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    font-size: 0.85rem;
    color: var(--couleur-texte-attenue);
}

.planning-legende-puce {
    display: inline-block;
    width: 0.65rem;
    height: 0.65rem;
    border-radius: 50%;
    margin-right: 0.55rem;
    vertical-align: middle;
}

/* Séparateur opérationnel/administratif (Phase Design D6.5) : uniquement
   inséré quand la légende mélange les deux natures (Mon planning) — jamais
   pour les calendriers de session, qui ne produisent jamais d'échéance. */
.planning-legende-separateur {
    border-top: 1px dashed var(--couleur-bordure);
    margin: 0.2rem 0;
}

/* Mode Mois (densité et lisibilité affinées en Phase Design D6.2 — mêmes
   classes, mêmes structures, aucune troncature/pagination introduite : le
   débordement d'une journée chargée reste géré par défilement interne,
   comme avant D6.2, jamais par un nouveau plafond de présentation). */

.planning-mois-entetes,
.planning-mois-semaine {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 0.4rem;
}

.planning-mois-entetes {
    margin-bottom: 0.5rem;
}

.planning-mois-entete {
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--couleur-texte-attenue);
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding-bottom: 0.2rem;
}

.planning-mois-semaine {
    margin-bottom: 0.4rem;
}

.planning-mois-jour {
    background: var(--couleur-surface);
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon-petit);
    min-height: 6rem;
    padding: 0.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.planning-mois-jour.hors-mois {
    background: var(--couleur-fond);
    opacity: 0.6;
}

.planning-mois-jour.aujourdhui {
    border-color: var(--couleur-primaire);
    box-shadow: inset 0 0 0 1px var(--couleur-primaire);
}

.planning-mois-jour-numero {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--couleur-texte-attenue);
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
}

.planning-mois-jour.aujourdhui .planning-mois-jour-numero {
    background: var(--couleur-primaire);
    color: #fff;
}

.planning-mois-jour-evenements {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    max-height: 6.5rem;
    overflow-y: auto;
}

/* Mode Semaine (Phase Design D6.3 — mêmes classes ; exclusivement Planning,
   jamais partagées avec `session/liste.html.twig`, D3). */

.planning-semaine {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 0.5rem;
}

.planning-semaine-jour {
    background: var(--couleur-surface);
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon-petit);
    padding: 0.5rem;
    min-height: 12rem;
    display: flex;
    flex-direction: column;
}

.planning-semaine-jour.aujourdhui {
    border-color: var(--couleur-primaire);
    box-shadow: inset 0 0 0 1px var(--couleur-primaire);
}

.planning-semaine-jour-entete {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 0.5rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px solid var(--couleur-bordure);
}

.planning-semaine-jour-nom {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--couleur-texte);
    text-transform: capitalize;
}

.planning-semaine-jour-numero {
    font-size: 0.78rem;
    color: var(--couleur-texte-attenue);
}

.planning-semaine-jour.aujourdhui .planning-semaine-jour-nom {
    color: var(--couleur-primaire);
}

.planning-semaine-jour-evenements {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    max-height: 9.5rem;
    overflow-y: auto;
}

.planning-semaine-jour-evenements .texte-attenue {
    font-size: 0.8rem;
    margin: 0;
}

/* Mode Liste (Phase Design D6.3) : structure `<table>` strictement
   conservée (une ligne par événement — `table tbody tr` reste compté et
   vérifié par les tests existants), seule une classe de regroupement par
   jour est ajoutée sur le `<tr>` du premier événement de chaque journée,
   posée en Twig à partir de la même liste `evenements` déjà triée
   chronologiquement — aucune nouvelle donnée, aucun service modifié.
   Exclusif à Planning, jamais partagé avec `session/liste.html.twig`
   (D3), qui n'a pas de vue Liste équivalente. */

.planning-liste-nouveau-jour:not(:first-child) td {
    border-top: 2px solid var(--couleur-bordure);
    padding-top: 0.85rem;
}

.planning-liste-jour-nom {
    display: block;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--couleur-texte-attenue);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* Puce d'événement, commune aux trois modes (et à `session/liste.html.twig`,
   Phase Design D3, pour `.planning-evenement`/`.planning-evenement-formation`
   uniquement) — cinq couleurs par type, inchangées depuis D6.0 : aucun
   niveau d'urgence n'est déduit ici pour les échéances (`evenement.statut`
   n'influence toujours que le texte, jamais la couleur), conformément à
   l'arbitrage « pas de nouvelle sémantique métier ». */

.planning-evenement {
    display: flex;
    align-items: baseline;
    gap: 0.35rem;
    width: 100%;
    border: none;
    border-radius: var(--rayon-petit);
    padding: 0.3rem 0.45rem;
    font-size: 0.8rem;
    line-height: 1.3;
    text-align: left;
    cursor: pointer;
    overflow: hidden;
}

.planning-evenement:hover {
    filter: brightness(0.96);
}

.planning-evenement-heure {
    font-weight: 600;
    flex-shrink: 0;
}

.planning-evenement-intitule {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.planning-evenement-formation {
    background: var(--couleur-info-fond);
    color: var(--couleur-info-texte);
}

.planning-evenement-visite {
    background: var(--couleur-attention-fond);
    color: var(--couleur-attention-texte);
}

.planning-evenement-examen {
    background: var(--couleur-violet-fond);
    color: var(--couleur-violet-texte);
}

/* Échéances documentaires/habilitation (Phase Design D6.5) : seuls types
   produits par `PlanningAgregationService::pourFormateur()`, jamais par
   `pourSession()` — de fait exclusifs à Mon planning, sans qu'aucune
   condition de route ne soit nécessaire ici. Bordure pointillée (au lieu
   d'une nouvelle couleur) pour les distinguer des événements opérationnels
   (Formation/Visite/Examen, toujours en bordure pleine) : nature
   administrative plutôt qu'une session réelle, seule différenciation
   demandée — aucune donnée, aucun niveau d'urgence supplémentaire. */

.planning-evenement-echeance_document {
    background: var(--couleur-erreur-fond);
    color: var(--couleur-erreur-texte);
    border: 1px dashed var(--couleur-erreur-texte);
}

.planning-evenement-echeance_habilitation {
    background: var(--couleur-surface-secondaire);
    color: var(--couleur-texte-attenue);
    border: 1px dashed var(--couleur-texte-attenue);
}

@media (max-width: 860px) {
    .planning-corps {
        /* `minmax(0, 1fr)`, pas `1fr` seul : `1fr` équivaut à
           `minmax(auto, 1fr)`, dont le minimum basé sur le contenu empêche
           la colonne de rétrécir sous la largeur de la grille Mois/Semaine
           et fait déborder toute la page (corrigé en D7.4, cassure réelle
           constatée sous 860px — la colonne desktop utilisait déjà
           `minmax(0, 1fr)`, jamais reproduit ici avant ce correctif). */
        grid-template-columns: minmax(0, 1fr);
    }

    .planning-panneau {
        position: static;
    }
}

/* Correction d'une cassure évidente (Phase Design D6.7) : sous 640px, la
   grille 7 colonnes du Mois/de la Semaine n'avait aucun repli — chaque
   colonne devenait illisible. Défilement horizontal local plutôt qu'une
   réorganisation en liste (qui relève de la refonte responsive complète,
   D7) : mêmes classes, même structure, la grille garde simplement une
   largeur minimale et déborde dans son propre conteneur. Bénéficie aussi à
   `session/liste.html.twig` (D3, `.planning-mois-*` partagées). */
@media (max-width: 640px) {
    .planning-mois {
        overflow-x: auto;
    }

    .planning-mois-entetes,
    .planning-mois-semaine {
        min-width: 560px;
    }

    .planning-semaine {
        overflow-x: auto;
        grid-template-columns: repeat(7, minmax(90px, 1fr));
    }
}

/* Évaluation qualité stagiaire (F2) : échelles visuelles de satisfaction.
   Les couleurs vert/orange/rouge introduites ici sont strictement
   sémantiques pour cette échelle (réutilisent les tokens succès/attention/
   erreur déjà existants), jamais une extension générale de la palette du
   reste de l'application. */

.evaluation-kicker {
    display: block;
    color: var(--couleur-accent);
    font-weight: 600;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 0.3rem;
}

.evaluation-progression {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    list-style: none;
    margin: 0.9rem 0 0;
    padding: 0;
}

.evaluation-progression a {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.65rem;
    border-radius: 999px;
    background: var(--couleur-surface-secondaire);
    color: var(--couleur-texte-attenue);
    font-size: 0.8rem;
    font-weight: 600;
    text-decoration: none;
}

.evaluation-progression a:hover {
    background: var(--couleur-bordure);
}

.evaluation-progression a span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.3rem;
    height: 1.3rem;
    border-radius: 50%;
    background: var(--couleur-primaire);
    color: #fff;
    font-size: 0.72rem;
}

/* En-tête de bloc (numéro + titre + courte indication) */

.bloc-evaluation-entete {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.bloc-evaluation-numero {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--rayon-petit);
    background: var(--couleur-primaire);
    color: #fff;
    font-weight: 700;
    font-size: 0.95rem;
}

.bloc-evaluation-titre h2 {
    margin: 0;
    padding: 0;
    border-top: none;
    font-size: 1.05rem;
}

.bloc-evaluation-soustitre {
    display: block;
    color: var(--couleur-texte-attenue);
    font-size: 0.85rem;
    margin-top: 0.15rem;
}

/* Question à échelle (question fermée + cartes de réponse) */

.question-echelle {
    padding: 1rem 0;
    border-top: 1px solid var(--couleur-bordure);
}

.question-echelle:first-of-type {
    border-top: none;
    padding-top: 0;
}

.question-echelle > label {
    color: var(--couleur-texte);
    font-weight: 600;
    font-size: 0.98rem;
    margin-bottom: 0.75rem;
}

.options-echelle {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0.6rem;
}

.option-echelle {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.35rem;
    padding: 0.75rem 0.5rem;
    border: 1.5px solid var(--couleur-bordure);
    border-radius: var(--rayon);
    background: var(--couleur-fond);
    cursor: pointer;
    font-weight: 500;
    font-size: 0.85rem;
    color: var(--couleur-texte);
}

.option-echelle input[type="radio"] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
}

.option-echelle:focus-within {
    outline: 2px solid var(--couleur-primaire);
    outline-offset: 2px;
}

.option-echelle__visage {
    display: inline-flex;
    color: var(--couleur-texte-attenue);
}

/* État sélectionné : piloté par l'état réel du radio HTML
   (`:has(input:checked)`), jamais par une classe rendue une fois pour
   toutes côté serveur — sinon un clic sans nouveau rendu de page ne
   changerait jamais l'apparence de la carte. Fonctionne donc aussi bien
   à l'affichage initial (réponse déjà cochée après une erreur de
   validation) qu'après un clic, sans JavaScript. */

.option-echelle--tres_positif:has(input:checked) { background: var(--couleur-succes-fond); border-color: var(--couleur-succes-texte); color: var(--couleur-succes-texte); }
.option-echelle--tres_positif:has(input:checked) .option-echelle__visage { color: var(--couleur-succes-texte); }

.option-echelle--positif:has(input:checked) { background: color-mix(in srgb, var(--couleur-succes-fond) 65%, white); border-color: var(--couleur-succes-texte); color: var(--couleur-succes-texte); }
.option-echelle--positif:has(input:checked) .option-echelle__visage { color: var(--couleur-succes-texte); }

.option-echelle--neutre:has(input:checked) { background: var(--couleur-surface-secondaire); border-color: var(--couleur-texte-attenue); color: var(--couleur-texte); }
.option-echelle--neutre:has(input:checked) .option-echelle__visage { color: var(--couleur-texte-attenue); }

.option-echelle--negatif:has(input:checked) { background: var(--couleur-attention-fond); border-color: var(--couleur-attention-texte); color: var(--couleur-attention-texte); }
.option-echelle--negatif:has(input:checked) .option-echelle__visage { color: var(--couleur-attention-texte); }

.option-echelle--tres_negatif:has(input:checked) { background: var(--couleur-erreur-fond); border-color: var(--couleur-erreur-texte); color: var(--couleur-erreur-texte); }
.option-echelle--tres_negatif:has(input:checked) .option-echelle__visage { color: var(--couleur-erreur-texte); }

.option-echelle:has(input:checked) {
    border-width: 2px;
    font-weight: 600;
}

.option-echelle:has(input:checked)::after {
    content: "✓";
    position: absolute;
    top: 0.35rem;
    right: 0.5rem;
    font-size: 0.75rem;
    font-weight: 700;
}

.option-echelle:not(:has(input:checked)):hover {
    border-color: var(--couleur-texte-attenue);
}

/* Question ouverte obligatoire, distincte du commentaire facultatif */

.question-ouverte {
    padding: 1rem 0;
    border-top: 1px solid var(--couleur-bordure);
}

.question-ouverte > label {
    color: var(--couleur-texte);
    font-weight: 600;
    font-size: 0.98rem;
    margin-bottom: 0.3rem;
}

.etiquette-requis {
    display: inline-block;
    color: var(--couleur-accent);
    font-size: 0.78rem;
    font-weight: 600;
    margin-bottom: 0.5rem;
}

.question-ouverte textarea {
    max-width: 100%;
}

/* Commentaire de fin de bloc, facultatif — zone secondaire volontairement
   moins proéminente qu'une question ouverte obligatoire. */

.champ-commentaire {
    margin-top: 1rem;
    padding: 0.9rem;
    background: var(--couleur-surface-secondaire);
    border-radius: var(--rayon);
}

.champ-commentaire > label {
    display: inline;
    margin-bottom: 0;
    font-weight: 600;
    color: var(--couleur-texte-attenue);
}

.etiquette-facultatif {
    display: inline-block;
    margin-left: 0.4rem;
    color: var(--couleur-texte-attenue);
    font-size: 0.78rem;
    font-style: italic;
}

.champ-commentaire textarea {
    max-width: 100%;
    margin-top: 0.5rem;
    background: var(--couleur-surface);
}

.evaluation-envoi {
    text-align: right;
}

.evaluation-envoi button,
.evaluation-envoi input[type="submit"] {
    font-size: 1rem;
    padding: 0.6rem 1.3rem;
}

@media (max-width: 620px) {
    .bloc-evaluation-entete {
        gap: 0.5rem;
    }

    .evaluation-envoi {
        text-align: center;
    }
}

/* Indicateurs qualité consolidés (F4) — pas de librairie de graphiques,
   uniquement une étiquette + une valeur + une barre de remplissage
   discrète. Réutilisé par `pilotage/_satisfaction.html.twig` et
   `qualite/retours_stagiaires.html.twig` via le même partiel Twig. */

.indicateurs-qualite-entete {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    margin-bottom: 1.25rem;
}

.indicateur-cle {
    display: flex;
    flex-direction: column;
}

.indicateur-cle-valeur {
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--couleur-primaire);
}

.indicateur-cle-valeur.donnee-absente {
    color: var(--couleur-texte-attenue);
    font-size: 1rem;
    font-weight: 500;
}

.indicateur-cle-legende {
    font-size: 0.82rem;
    color: var(--couleur-texte-attenue);
}

.indicateur-ligne {
    margin-bottom: 0.75rem;
}

.indicateur-ligne-entete {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 0.88rem;
    margin-bottom: 0.25rem;
}

.indicateur-ligne-valeur {
    font-weight: 600;
}

.indicateur-barre {
    height: 0.4rem;
    border-radius: 999px;
    background: var(--couleur-surface-secondaire);
    overflow: hidden;
}

.indicateur-barre-remplissage {
    height: 100%;
    background: var(--couleur-primaire);
    border-radius: 999px;
}

/* Option de tri simple (F7, liste des dossiers) : deux liens texte, pas
   de composant dédié pour un besoin aussi ponctuel. */

.tri-options {
    margin: 0.6rem 0 1rem;
    font-size: 0.88rem;
    color: var(--couleur-texte-attenue);
}

.tri-options a {
    color: var(--couleur-texte-attenue);
    text-decoration: none;
}

.tri-options a.actif {
    color: var(--couleur-primaire);
    font-weight: 600;
    text-decoration: underline;
}

/* Courbe d'évolution des résultats (P2.6, Ma progression) : SVG rendu
   côté serveur, aucune dépendance JS — le tableau d'historique juste en
   dessous sert d'alternative textuelle accessible (§10/§31). */

.courbe-progression {
    display: block;
    width: 100%;
    aspect-ratio: 8 / 3;
    max-height: 340px;
    min-height: 220px;
    margin: 0.75rem 0;
}

.courbe-axe {
    stroke: var(--couleur-texte-attenue);
    stroke-width: 1;
}

.courbe-repere {
    stroke: var(--couleur-bordure);
    stroke-width: 0.75;
}

.courbe-texte-axe {
    font-size: 6px;
    fill: var(--couleur-texte-attenue);
}

.courbe-ligne {
    stroke-width: 1.75px;
    vector-effect: non-scaling-stroke;
}

.courbe-ligne-entrainement_theme,
.courbe-pastille-entrainement_theme,
.courbe-point-entrainement_theme {
    stroke: var(--couleur-info-texte);
    fill: var(--couleur-info-texte);
}

.courbe-ligne-test_connaissances,
.courbe-pastille-test_connaissances,
.courbe-point-test_connaissances {
    stroke: var(--couleur-violet-texte);
    fill: var(--couleur-violet-texte);
}

.courbe-ligne-examen_blanc,
.courbe-pastille-examen_blanc,
.courbe-point-examen_blanc {
    stroke: var(--couleur-primaire);
    fill: var(--couleur-primaire);
}

.courbe-point {
    vector-effect: non-scaling-stroke;
}

.courbe-legende {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem;
    font-size: 0.85rem;
    color: var(--couleur-texte-attenue);
    margin: 0.5rem 0;
}

.courbe-legende-item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.courbe-pastille {
    display: inline-block;
    width: 0.65rem;
    height: 0.65rem;
    border-radius: 999px;
}

/* Messagerie (M1.2/M1.3) — composants scopés à la messagerie uniquement,
   jamais un mini-design-system : `.carte`/`.taches`/`.tache`/`.app-avatar`/
   `.badge` déjà existants sont réutilisés tels quels partout ailleurs sur
   ces écrans. */

/* Badge de non-lus dans le lien de navigation (M1.3 §6) : `.badge` existant,
   seul l'espacement par rapport au libellé est propre à ce contexte. */
.app-nav-groupe a .badge {
    margin-left: 0.4rem;
}

.messagerie-grille {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.25rem;
    align-items: start;
}

@media (max-width: 780px) {
    .messagerie-grille {
        grid-template-columns: 1fr;
    }
}

/* Un bouton (envoi du formulaire "nouvelle conversation") a besoin de la
   même mise en page que .tache (utilisé partout ailleurs sur un <a>), sans
   hériter du style natif d'un <button>. */
button.tache {
    all: unset;
    box-sizing: border-box;
    width: 100%;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon);
    cursor: pointer;
    font: inherit;
    text-align: left;
}

button.tache:hover {
    border-color: var(--couleur-primaire);
}

.messagerie-entete {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
}

.messagerie-fil {
    margin-bottom: 1rem;
}

.messagerie-fil-actions {
    display: flex;
    justify-content: center;
    margin-bottom: 0.75rem;
}

.messagerie-messages {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-top: 0.5rem;
}

.message-bulle {
    max-width: 75%;
    padding: 0.6rem 0.85rem;
    border-radius: var(--rayon);
    background: var(--couleur-surface-secondaire);
}

.message-bulle p {
    margin: 0 0 0.25rem;
    white-space: pre-wrap;
    overflow-wrap: break-word;
}

.message-date {
    font-size: 0.75rem;
    color: var(--couleur-texte-attenue);
}

/* Nom de l'auteur (supervision uniquement, M1.4 §11) : l'administrateur
   fonctionnel n'étant ni A ni B, l'alignement seul ne suffit pas à
   identifier l'auteur d'un message. */
.message-auteur {
    display: block;
    font-size: 0.75rem;
    font-weight: 600;
    margin-bottom: 0.15rem;
}

.message-moi, .message-a {
    align-self: flex-end;
    background: var(--couleur-primaire);
    color: #ffffff;
}

.message-moi .message-date, .message-a .message-date {
    color: rgba(255, 255, 255, 0.75);
}

.message-autre, .message-b {
    align-self: flex-start;
}

@media (max-width: 560px) {
    .message-bulle {
        max-width: 90%;
    }
}

/* Fenêtre de confirmation (V2, UXPP-2 — assets/confirmation.js) : une seule
   présentation pour toute action sensible, interne comme Partenaire. */
dialog.confirmation {
    width: min(92vw, 420px);
    padding: 0;
    border: none;
    border-radius: var(--rayon-grand);
    background: var(--couleur-surface);
    color: var(--couleur-texte);
    box-shadow: var(--ombre-flottante);
}

dialog.confirmation[open] {
    animation: apparition-glisse var(--duree-moyenne) var(--courbe-sortie) both;
}

dialog.confirmation::backdrop {
    background: rgba(14, 27, 43, 0.5);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
}

.confirmation-corps {
    margin: 0;
    padding: 1.5rem 1.5rem 1.25rem;
}

.confirmation-titre {
    margin: 0 0 1.25rem;
    font-family: var(--police-titre);
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1.45;
}

.confirmation-actions {
    display: flex;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.confirmation-corps > div {
    margin-bottom: 0;
}

/* En-têtes de fiche et de liste sur mobile (V2) : les actions passent sous
   le titre et se replient sur plusieurs lignes, jamais au-delà de l'écran. */
@media (max-width: 680px) {
    .fiche-entete-actions,
    .liste-entete-actions,
    .tb-entete-actions {
        flex-shrink: 1;
        width: 100%;
    }

    .fiche-entete-actions > a,
    .fiche-entete-actions > form,
    .tb-entete-actions > a {
        flex: 1 1 auto;
    }

    h1 {
        font-size: 1.5rem;
    }
}

/* V2 (audit de simplification Q3) : retour principal vers la session,
   raccourci discret vers le dossier du stagiaire. */
.fiche-retour-double {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 1.25rem;
    margin: 0 0 1rem;
}

.fiche-retour-double .fiche-retour {
    margin-bottom: 0;
}

.fiche-retour-secondaire {
    color: var(--couleur-texte-attenue);
    font-size: 0.85rem;
}

/* Page autonome sans navigation (erreurs, compte sans accès) —
   templates/_page_simple.html.twig. */
.page-simple {
    display: grid;
    place-items: center;
    min-height: 100vh;
    margin: 0;
    padding: 1.5rem 1rem;
    background: var(--couleur-fond);
}

.page-simple-carte {
    width: 100%;
    max-width: 32rem;
    padding: 2rem 1.75rem;
    background: var(--couleur-surface);
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon);
    box-shadow: var(--ombre-carte);
}

.page-simple-marque {
    margin: 0 0 1rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--couleur-texte-attenue);
}

.page-simple-carte h1 {
    margin: 0 0 0.6rem;
    font-size: 1.4rem;
}

.page-simple-actions {
    margin: 1.25rem 0 0;
}

/* DEC-119 : ajout de l'e-mail d'un salarié repris sans e-mail (fiche partenaire, interne) */

.fiche-email > summary {
    cursor: pointer;
    color: var(--couleur-attention-texte);
    font-weight: 500;
}

.fiche-email-form {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.4rem;
}

.fiche-email-form input[type="email"] {
    flex: 1 1 13rem;
    min-width: 0;
}

/* DEC-119 : « Nouveau stagiaire » — personne déjà connue sans e-mail */

.homonymes {
    flex-direction: column;
    align-items: stretch;
}

.homonymes-liste {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0.6rem 0 0;
    padding: 0;
    list-style: none;
}

.homonymes-liste li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* DEC-120 : écran « Comptes » — onglets par population, filtres, liste paginée */

.gc-onglets {
    margin-bottom: 1rem;
}

.gc-effectif {
    display: inline-block;
    min-width: 1.6rem;
    margin-left: 0.3rem;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    background: var(--couleur-fond-attenue, rgba(15, 23, 42, 0.06));
    color: var(--couleur-texte-attenue);
    font-size: 0.78rem;
    font-weight: 600;
    text-align: center;
}

.onglets-nav a.actif .gc-effectif {
    background: var(--couleur-accent);
    color: #fff;
}

.gc-filtres {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 1rem;
}

.gc-recherche {
    flex: 1 1 18rem;
}

.gc-recherche input {
    width: 100%;
}

.gc-reinitialiser {
    font-size: 0.9rem;
}

.gc-plus {
    flex-basis: 100%;
}

.gc-plus > summary {
    cursor: pointer;
    color: var(--couleur-texte-attenue);
    font-size: 0.9rem;
    font-weight: 600;
}

.gc-plus-champs {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    margin-top: 0.6rem;
}

.gc-plus-champs label {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.85rem;
}

.gc-personne {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    color: inherit;
    text-decoration: none;
}

.gc-personne:hover strong {
    text-decoration: underline;
}

.gc-email {
    color: var(--couleur-texte-attenue);
    word-break: break-all;
}

.gc-vide {
    margin: 0;
    padding: 1.5rem 0.5rem;
    text-align: center;
    color: var(--couleur-texte-attenue);
}

/* DEC-136 : fiche partenaire — ranger des stagiaires dans la société */

.effectif-recherche {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.effectif-recherche label {
    flex: 1 1 16rem;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.effectif-recherche select {
    width: 100%;
}

.effectif-candidats {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.effectif-candidat {
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon-petit);
    padding: 0.7rem 0.9rem;
}

.effectif-candidat-identite {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.7rem;
    cursor: pointer;
}

.effectif-candidat-identite > span:first-of-type {
    display: flex;
    flex-direction: column;
    flex: 1 1 12rem;
    min-width: 0;
    overflow-wrap: anywhere;
}

.effectif-formations {
    margin: 0.6rem 0 0 1.6rem;
    padding: 0.5rem 0.7rem;
    border: 1px dashed var(--couleur-bordure);
    border-radius: var(--rayon-petit);
}

.effectif-formations legend {
    float: left;
    width: 100%;
    font-size: 0.85rem;
    margin-bottom: 0.3rem;
}

.effectif-formations label {
    display: block;
    clear: left;
    padding: 0.15rem 0;
}

.effectif-retirer {
    display: inline;
}

.fiche-section-entete {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    margin-bottom: 0.85rem;
}

.fiche-section-entete .fiche-section-titre {
    margin-bottom: 0;
}

/* DEC-137 : avis des sociétés partenaires (onglet Qualité de la session) */

.avis-entreprises {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* DEC-138 : renvoi du lien d'activation depuis la liste des comptes */

.gc-renvoi {
    display: inline-block;
    margin: 0.25rem 0 0 0.4rem;
}

/* DEC-140 : couleur de domaine des sessions dans le calendrier (comme le catalogue) */

.planning-evenement-formation[class*="ff-teinte-"] {
    background: var(--ff-teinte-unie);
    color: var(--ff-texte);
}

.planning-evenement-formation[class*="ff-teinte-"]:hover {
    filter: brightness(1.08);
}

.planning-legende-domaines {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1rem;
    margin: 0 0 0.75rem;
    padding: 0;
    font-size: 0.85rem;
    color: var(--couleur-texte-attenue);
}

.planning-legende-domaines li {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.planning-legende-pastille {
    width: 0.8rem;
    height: 0.8rem;
    border-radius: 3px;
    background: var(--ff-teinte-unie);
}
