:root {
    --bg-dark: #0f1117;
    --bg-card: #1a1d27;
    --bg-card-hover: #21252f;
    --accent: #5b8def;
    --accent-glow: rgba(91, 141, 239, 0.35);
    --text-primary: #eef1f8;
    --text-secondary: #8b91a7;
    --border: #2a2e3c;
    --danger: #e0545a;
    --success: #4caf7d;
    --warning: #e0a13d;
}

/* ---------- Thème clair (Mon compte > Interface, voir assets/theme.js) ----------
   Sombre par défaut (:root ci-dessus) ; data-theme="light" posé sur <html>
   par assets/theme.js avant le premier rendu (préférence enregistrée par
   compte, appliquée aussi hors connexion via localStorage) — jamais piloté
   par prefers-color-scheme seul, le mode "Automatique" de l'app suit
   l'heure locale (clair le jour, sombre la nuit), pas le thème système. */
:root[data-theme="light"] {
    --bg-dark: #f3f5fa;
    --bg-card: #ffffff;
    --bg-card-hover: #eef1f7;
    --accent: #3568d4;
    --accent-glow: rgba(53, 104, 212, 0.25);
    --text-primary: #1b2030;
    --text-secondary: #5b6172;
    --border: #dde1ea;
    --danger: #c23c42;
    --success: #2f9d68;
    --warning: #b9791f;
}
:root[data-theme="light"] body {
    background: radial-gradient(circle at 20% 20%, #ffffff 0%, var(--bg-dark) 55%);
}

/* Le logo (assets/logo.png) a un fond bleu nuit intégré à l'image (pas de
   transparence) : invisible sur le fond sombre par défaut, mais illisible
   posé tel quel sur un fond clair. En thème clair uniquement, on lui
   redonne un cartouche arrondi de la même couleur que son propre fond,
   pour qu'il se détache proprement plutôt que de flotter en rectangle nu. */
:root[data-theme="light"] .brand img {
    background: #0a1130;
    border-radius: 10px;
    padding: 6px 12px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* Fond posé aussi sur <html> (pas seulement <body>) : sur mobile, le
   rebond d'overscroll ou le repli de la barre d'adresse peut révéler une
   zone sous <body> — sans ce fond elle apparaît blanche par défaut
   (bandeau blanc constaté en bas de page sur mobile). */
html {
    background: var(--bg-dark);
}

body {
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    background: radial-gradient(circle at 20% 20%, #161a24 0%, var(--bg-dark) 55%);
    color: var(--text-primary);
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 40px 20px;
}

/* Page de connexion / installation : logo, texte et formulaire centrés
   verticalement dans la fenêtre, espacés régulièrement. */
body.auth-page {
    justify-content: center;
}

@media (max-width: 600px) {
    body { padding: 20px 12px; }
}

.hidden { display: none !important; }

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

.brand {
    width: 100%;
    text-align: left;
    margin-bottom: 8px;
}

.brand h1 {
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: 0.3px;
}

.brand h1 span { color: var(--accent); }

.brand p.subtitle {
    color: var(--text-secondary);
    margin-top: 6px;
}

.brand img { height: 140px; width: auto; }

.top-bar .brand { width: auto; margin-bottom: 0; flex-shrink: 0; }
.top-bar .brand img { height: 84px; }

.brand.center {
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    margin-bottom: 32px;
}

.brand.center p.subtitle { margin-top: 0; }

.brand.center img { height: 90px; }

@media (max-width: 500px) {
    .brand img { height: 90px; }
    .top-bar .brand img { height: 56px; }
    .brand.center img { height: 64px; }
}

.page {
    width: 100%;
    min-width: 0;
    max-width: 480px;
    margin: 0 auto;
    text-align: center;
    animation: fadeUp 0.6s ease;
}

.page.wide { max-width: 1400px; }


.panel {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 32px;
    display: flex;
    flex-direction: column;
    gap: 16px;
    text-align: left;
}

@media (max-width: 600px) {
    .panel { padding: 20px; }
    .card { padding: 20px; }
    .modal { padding: 20px; }
}

input[type="text"], input[type="password"], input[type="number"], input[type="email"], input[type="file"], input[type="date"], input[type="datetime-local"],
select, textarea {
    background: var(--bg-dark);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 14px;
    color: var(--text-primary);
    font-size: 1rem;
    font-family: inherit;
    outline: none;
    transition: border-color 0.2s ease;
    width: 100%;
}

input[type="date"], input[type="datetime-local"] { color-scheme: dark; }

input:focus, select:focus, textarea:focus { border-color: var(--accent); }

input:disabled, select:disabled, textarea:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

input[type="checkbox"] {
    width: 18px;
    height: 18px;
    accent-color: var(--accent);
    cursor: pointer;
    flex-shrink: 0;
}

label { color: var(--text-secondary); font-size: 0.85rem; display: block; margin-bottom: 6px; }

.field { display: flex; flex-direction: column; gap: 4px; }
.field-row { display: flex; gap: 12px; flex-wrap: wrap; }
.field-row .field { flex: 1; min-width: 140px; }

button, .btn {
    background: var(--accent);
    border: none;
    border-radius: 10px;
    padding: 12px 18px;
    color: white;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
    transition: opacity 0.2s ease, transform 0.15s ease;
}

button:hover, .btn:hover { opacity: 0.9; }
button:active, .btn:active { transform: scale(0.98); }
button:disabled { opacity: 0.6; cursor: wait; }

button.secondary, .btn.secondary {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-secondary);
}
button.secondary:hover { border-color: var(--accent); color: var(--accent); }

button.danger { background: var(--danger); }

.msg { font-size: 0.9rem; min-height: 20px; }
.msg.error { color: var(--danger); }
.msg.success { color: var(--success); }

/* ---------- Header / nav fixes ---------- */
:root {
    --header-h: 96px;
    --breadcrumb-h: 38px;
}

@media (max-width: 600px) {
    :root {
        --header-h: 112px;
        --breadcrumb-h: 34px;
    }
}

body.has-fixed-header { padding-top: 0; }

.site-header {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 200;
    background: var(--bg-dark);
    border-bottom: 1px solid var(--border);
    transition: transform 0.25s ease;
}

.site-header-row {
    max-width: 1400px;
    margin: 0 auto;
    padding: 12px 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    min-height: calc(var(--header-h) - 24px);
}

.site-header .brand { width: auto; flex-shrink: 0; margin-bottom: 0; }
.site-header .brand img { height: 76px; }

@media (max-width: 600px) {
    .site-header .brand img { height: 56px; }
}

.breadcrumb {
    position: fixed;
    top: var(--header-h);
    left: 0; right: 0;
    z-index: 190;
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    transition: transform 0.25s ease;
}

/* Mobile uniquement : en descendant la page, le bandeau (logo + nom
   d'utilisateur) glisse hors écran et seul le fil d'ariane reste visible,
   remonté en haut (translateY, pas de changement de "top" — le
   header-spacer garde sa hauteur, donc pas de saut de mise en page tant
   qu'on n'a pas dépassé cette hauteur). En remontant la page (ou près du
   haut), le bandeau réapparaît. Classe posée par header-fix.js, qui pose
   aussi --qa-header-h-actual (hauteur réelle du bandeau, mesurée : elle
   varie d'une page à l'autre selon le nombre de lignes du bandeau, --header-h
   ne suffit pas — remonter le fil d'ariane d'une valeur fixe le laissait
   décalé de plusieurs dizaines de px sur les pages à bandeau plus haut). */
@media (max-width: 600px) {
    body.qa-header-collapsed .site-header { transform: translateY(-100%); }
    body.qa-header-collapsed .breadcrumb { transform: translateY(calc(-1 * var(--qa-header-h-actual, var(--header-h)))); }
}

.breadcrumb-row {
    max-width: 1400px;
    margin: 0 auto;
    padding: 9px 20px;
    font-size: 0.82rem;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow-x: auto;
    text-align: left;
}

.breadcrumb a { color: var(--text-secondary); text-decoration: none; }
.breadcrumb a:hover { color: var(--accent); }
.breadcrumb .sep { margin: 0 6px; opacity: 0.45; }
.breadcrumb .current { color: var(--text-primary); font-weight: 600; }

.header-spacer {
    height: calc(var(--header-h) + var(--breadcrumb-h));
    width: 100%;
    flex-shrink: 0;
    margin-bottom: 24px;
}

/* ---------- Admin : menu latéral ---------- */
.admin-layout {
    display: flex;
    align-items: flex-start;
    gap: 24px;
    width: 100%;
}

.admin-sidebar {
    width: 220px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 10px;
    position: sticky;
    top: 20px;
}

.sidebar-link, .sidebar-group-toggle {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    color: var(--text-secondary);
    padding: 10px 14px;
    border-radius: 10px;
    font-weight: 600;
    font-size: 0.9rem;
}

.sidebar-link:hover, .sidebar-group-toggle:hover { background: var(--bg-card-hover); color: var(--text-primary); }
.sidebar-link.active { background: var(--accent); color: white; }

.sidebar-group-toggle { display: flex; justify-content: space-between; align-items: center; }
.sidebar-group-toggle::after { content: '▾'; font-size: 0.75rem; transition: transform 0.2s ease; }
.sidebar-group:not(.open) .sidebar-group-toggle::after { transform: rotate(-90deg); }

.sidebar-submenu {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-left: 10px;
    overflow: hidden;
}
.sidebar-group:not(.open) .sidebar-submenu { display: none; }
.sidebar-submenu .sidebar-link { font-weight: 500; font-size: 0.85rem; padding: 8px 14px; }

.admin-content { flex: 1; min-width: 0; }

@media (max-width: 800px) {
    .admin-layout { flex-direction: column; }
    .admin-sidebar { width: 100%; position: static; flex-direction: row; flex-wrap: wrap; }
    .sidebar-group { flex: 1 1 auto; }
    .sidebar-submenu { padding-left: 0; }
    .admin-content { width: 100%; }
}

/* ---------- Cards / grid ---------- */
.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 24px;
    width: 100%;
    animation: fadeUp 0.8s ease;
}

/* Rangée de tuiles-indicateurs (ex. mandats-admin.php) : minmax plus
   étroit que .grid pour que 5 tuiles tiennent sur une seule ligne sur
   un écran de bureau (reste de l'auto-fit normal, donc se replie
   proprement sur mobile/tablette, en dessous de ~900px). */
.grid-tiles {
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
}

/* Portail public (public.php) : 3 tuiles maximum par ligne, quel que soit
   le nombre configuré — flex (pas grid) pour que les rangées incomplètes
   (1 ou 2 tuiles) restent centrées au lieu d'être étirées sur toute la
   largeur. Se replie naturellement en dessous de ~860px. */
.grid-3 { display: flex; flex-wrap: wrap; justify-content: center; }
.grid-3 > * { flex: 0 0 calc(33.333% - 16px); max-width: calc(33.333% - 16px); }
@media (max-width: 860px) { .grid-3 > * { flex-basis: calc(50% - 12px); max-width: calc(50% - 12px); } }
@media (max-width: 560px) { .grid-3 > * { flex-basis: 100%; max-width: 420px; } }

.card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 28px;
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 10px;
    transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease, background 0.25s ease;
}

.card:hover { border-color: var(--accent); background: var(--bg-card-hover); box-shadow: 0 12px 30px rgba(91, 141, 239, 0.15); }

.card h2 { font-size: 1.15rem; font-weight: 600; }
.card p { font-size: 0.9rem; color: var(--text-secondary); line-height: 1.4; }

.card .meta {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

/* ---------- Rôles : grille des cartes (2 colonnes fixes) ---------- */
.roles-grid { grid-template-columns: repeat(2, minmax(280px, 1fr)); }
@media (max-width: 850px) {
    /* Le seuil est plus haut que .admin-layout (800px) : entre les deux, la
       barre latérale (220px + espacement) est encore côte à côte avec le
       contenu, qui n'a alors plus assez de place pour 2 colonnes de 280px. */
    .roles-grid { grid-template-columns: 1fr; }
}

/* Permissions d'un rôle : le libellé occupe toujours la même hauteur
   (jusqu'à 2 lignes), pour que tous les menus déroulants d'une même
   rangée restent alignés quel que soit le nombre de lignes du libellé
   voisin. */
.role-perm-field label {
    min-height: 2.3em;
    display: flex;
    align-items: flex-end;
}

.role-perm-group {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    margin-top: 4px;
}

.role-perm-group summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--text-primary);
    list-style: none;
}

.role-perm-group summary::-webkit-details-marker { display: none; }

.role-perm-group summary::before {
    content: '▸';
    display: inline-block;
    margin-right: 6px;
    color: var(--accent);
    transition: transform 0.15s ease;
}

.role-perm-group[open] summary::before { transform: rotate(90deg); }

.role-perm-group-body { margin-top: 10px; }

.pill {
    background: rgba(91, 141, 239, 0.12);
    color: var(--accent);
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.75rem;
}

.pill.warn { background: rgba(224, 84, 90, 0.12); color: var(--danger); }
.pill.ok { background: rgba(76, 175, 125, 0.12); color: var(--success); }
.pill.orange { background: rgba(224, 161, 61, 0.14); color: var(--warning); }
.pill.purple { background: rgba(155, 123, 222, 0.14); color: #9b7bde; }
.pill.pink { background: rgba(224, 91, 176, 0.14); color: #e05bb0; }

/* Fil de progression (ex. suivi public d'un mandat, mandats.php) : étapes
   reliées par un trait qui touche vraiment le bord de chaque cercle.
   Grille à colonnes fixes (34px cercle / 1fr trait en alternance) pour
   garantir un raccord pixel-parfait quelle que soit la largeur des
   étiquettes en dessous — les libellés vivent dans une ligne de grille
   séparée et se centrent indépendamment de la largeur de leur colonne. */
.stepper {
    display: grid;
    grid-template-columns: 34px 1fr 34px 1fr 34px 1fr 34px;
    margin: 16px 0 0;
    padding: 0 65px;
}
.stepper-connector {
    grid-row: 1;
    align-self: center;
    height: 3px;
    border-radius: 2px;
    background: var(--border);
    position: relative;
    overflow: hidden;
}
/* Le fond de base reste neutre même une fois "done" : c'est uniquement
   le calque ::after ci-dessous qui se colore, en se déployant de gauche
   à droite à l'ouverture — sinon le trait passerait bleu instantanément
   et l'animation, jouée par-dessus une couleur déjà identique, resterait
   invisible. Chaque segment attend que le précédent ait fini de se
   remplir (délai posé en JS = index * durée) pour un vrai enchaînement
   du début jusqu'à l'étape en cours, pas un remplissage simultané. */
.stepper-connector.done::after {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    /* Le délai par segment ne peut pas être posé en style inline sur
       ::after (un attribut style ne cible jamais un pseudo-élément) : il
       passe par une variable CSS, posée en inline sur l'élément réel
       (.stepper-connector), qui hérite bien dans son ::after. */
    animation: qaStepperFill 0.4s ease-out forwards;
    animation-delay: var(--reveal-delay, 0ms);
}
@keyframes qaStepperFill {
    to { transform: scaleX(1); }
}
.stepper-step {
    grid-row: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    background: none;
    border: none;
    padding: 0;
    position: relative;
}
.stepper-circle {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    font-weight: 600;
    border: 2px solid var(--border);
    background: var(--bg-card);
    color: var(--text-secondary);
    transition: border-color 0.15s, background 0.15s, color 0.15s, transform 0.15s;
}
.stepper-step.done .stepper-circle { background: var(--accent); border-color: var(--accent); color: #fff; }
/* Étape "en cours" : remplissage clair/translucide (pas plein comme une
   étape terminée) pour bien la distinguer visuellement des deux états,
   avec une légère pulsation pour attirer l'œil sur l'avancement. */
.stepper-step.current .stepper-circle { border-color: var(--accent); color: var(--accent); background: var(--accent-glow); animation: qaStepperPulse 1.8s ease-in-out infinite; }
.stepper-step.error .stepper-circle { border-color: var(--danger); color: var(--danger); background: rgba(224, 84, 90, 0.16); }
/* Rose plutôt qu'orange : aligné sur .pill.pink, la couleur du badge
   "Complément requis" utilisée à la fois côté admin et côté club. */
.stepper-step.attention .stepper-circle { border-color: #e05bb0; color: #e05bb0; background: rgba(224, 91, 176, 0.16); }
.stepper-step.selected .stepper-circle { box-shadow: 0 0 0 3px var(--accent-glow); }
@keyframes qaStepperPulse {
    0%, 100% { box-shadow: 0 0 0 0 var(--accent-glow); }
    50% { box-shadow: 0 0 0 6px transparent; }
}
.stepper-labels {
    display: grid;
    grid-template-columns: 34px 1fr 34px 1fr 34px 1fr 34px;
    padding: 0 65px;
    margin-top: 8px;
}
.stepper-labels > div {
    text-align: center;
    overflow: visible;
}
/* Libellé + date regroupés dans un même bloc centré (au lieu de deux
   éléments séparés centrés indépendamment) pour rester alignés entre eux
   quelle que soit la longueur du texte. */
.stepper-label-wrap {
    display: block;
    width: 130px;
    margin: 0 auto;
    transform: translateX(-48px);
}
.stepper-label {
    display: block;
    font-size: 0.78rem;
    color: var(--text-secondary);
}
.stepper-labels > div.done .stepper-label,
.stepper-labels > div.current .stepper-label,
.stepper-labels > div.attention .stepper-label,
.stepper-labels > div.error .stepper-label { color: var(--text-primary); }
.stepper-date { display: block; font-size: 0.72rem; color: var(--text-secondary); margin-top: 2px; }

/* Mobile : la grille horizontale ci-dessus (4 étapes côte à côte, padding
   0 65px + libellés de 130px) suppose une largeur d'écran confortable —
   sur mobile les étiquettes voisines se chevauchent et deviennent
   illisibles (constaté sur l'avancement de validation d'un mandat, admin
   comme club, y compris après un premier essai de simple réduction des
   tailles/largeurs, insuffisant). En dessous de 600px on bascule sur une
   disposition verticale : un rond par ligne, étiquette + date à droite —
   voir .stepper-wrap (wrapper commun posé en JS autour de .stepper et
   .stepper-labels, mandats.php/mandats-admin.php) mis en display:contents
   pour que les ronds et les étiquettes deviennent des enfants directs
   d'une seule grille à 2 colonnes (34px pour le rond, le reste pour le
   texte) et se retrouvent ainsi alignés ligne par ligne malgré leur
   origine dans deux blocs HTML distincts. Les connecteurs horizontaux
   n'ont pas d'équivalent vertical simple ici : masqués sur mobile, l'état
   (couleur/coche) du rond suffit à indiquer la progression. */
@media (max-width: 600px) {
    .stepper-wrap {
        display: grid;
        grid-template-columns: 34px 1fr;
        column-gap: 14px;
        row-gap: 20px;
        align-items: start;
    }
    .stepper-wrap .stepper,
    .stepper-wrap .stepper-labels {
        display: contents;
    }
    .stepper-wrap .stepper-connector { display: none; }
    /* L'index de colonne posé en JS (style="grid-column:...") vise la
       grille horizontale d'origine : neutralisé ici en priorité (!important)
       pour laisser la grille verticale ci-dessus placer les ronds en
       colonne 1. */
    .stepper-wrap .stepper-step {
        grid-column: 1 !important;
        justify-content: flex-start;
    }
    .stepper-wrap .stepper-step:nth-of-type(1) { grid-row: 1; }
    .stepper-wrap .stepper-step:nth-of-type(2) { grid-row: 2; }
    .stepper-wrap .stepper-step:nth-of-type(3) { grid-row: 3; }
    .stepper-wrap .stepper-step:nth-of-type(4) { grid-row: 4; }
    .stepper-wrap .stepper-labels > div {
        grid-column: 2 !important;
        text-align: left;
    }
    .stepper-wrap .stepper-labels > div:nth-of-type(1) { grid-row: 1; }
    .stepper-wrap .stepper-labels > div:nth-of-type(2) { grid-row: 2; }
    .stepper-wrap .stepper-labels > div:nth-of-type(3) { grid-row: 3; }
    .stepper-wrap .stepper-labels > div:nth-of-type(4) { grid-row: 4; }
    .stepper-wrap .stepper-label-wrap {
        width: auto;
        transform: none;
        margin: 0;
        padding-top: 4px;
    }
    .stepper-wrap .stepper-label { font-size: 0.82rem; }
    .stepper-wrap .stepper-date { font-size: 0.72rem; }
}

/* Bloc "Envoyer le mandat" du panneau de détail : bouton intégré à la
   même carte que le message d'état, plutôt que posé en dessous. */
.mandat-action-panel {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    text-align: left;
}

.competition-detail-row td { background: var(--bg-card); padding: 20px; }
.competition-detail-panel { display: flex; flex-direction: column; gap: 8px; }

/* Encadré de visibilité pour une opération en attente sur une tuile
   (ex. corrections à faire) : plus visible qu'un simple texte, aux mêmes
   codes couleur que .pill.warn/.pill.ok. */
.tile-alert {
    margin-top: 8px;
    padding: 6px 12px;
    border-radius: 8px;
    font-size: 0.85rem;
    font-weight: 600;
    border: 1px solid rgba(224, 84, 90, 0.35);
    background: rgba(224, 84, 90, 0.12);
    color: var(--danger);
}

.tile-alert.ok {
    border-color: rgba(76, 175, 125, 0.35);
    background: rgba(76, 175, 125, 0.12);
    color: var(--success);
}

.tile-alert.neutral {
    border-color: var(--border);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-secondary);
}

/* Tuile "à venir" (module pas encore développé) : atténuée pour ne pas
   se confondre avec une tuile pleinement fonctionnelle — évite de faire
   croire à une fonctionnalité disponible avant de cliquer dessus. */
.card-soon { opacity: 0.65; }
.card-soon:hover { border-color: var(--border); background: var(--bg-card); box-shadow: none; }

/* ---------- Table (admin) ---------- */
table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; white-space: nowrap; }
th { color: var(--text-secondary); font-weight: 600; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.03em; }
.th-sort-btn {
    background: none; border: none; padding: 0; margin: 0; cursor: pointer;
    color: inherit; font: inherit; text-transform: inherit; letter-spacing: inherit;
    display: inline-flex; align-items: center; gap: 4px;
}
.th-sort-btn:hover { color: var(--text-primary); }
.th-sort-btn::after { content: ''; width: 0; height: 0; opacity: 0.5; }
.th-sort-btn.sort-asc::after { content: '▲'; font-size: 0.6rem; opacity: 1; }
.th-sort-btn.sort-desc::after { content: '▼'; font-size: 0.6rem; opacity: 1; }
tr:hover td { background: var(--bg-card-hover); }
tr.row-selected td { background: rgba(91, 141, 239, 0.12); border-color: rgba(91, 141, 239, 0.3); }
/* Ombres de défilement : signalent qu'il y a du contenu caché à gauche/
   droite d'un tableau qui déborde (colonnes hors écran sur mobile, ex.
   le bouton "Voir la fiche" en bout de ligne) — invisibles tant qu'il n'y
   a rien à faire défiler grâce à background-attachment: local sur les
   deux dégradés "masque". Technique CSS classique, sans JS. */
.table-wrap {
    overflow-x: auto;
    background:
        linear-gradient(to right, var(--bg-card) 30%, rgba(0, 0, 0, 0)),
        linear-gradient(to right, rgba(0, 0, 0, 0), var(--bg-card) 70%) 100% 0,
        radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0)),
        radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0)) 100% 0;
    background-repeat: no-repeat;
    background-color: var(--bg-card);
    background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
    background-position: 0 0, 100% 0, 0 0, 100% 0;
    background-attachment: local, local, scroll, scroll;
}

.row-actions { display: flex; gap: 8px; }
.row-actions button { padding: 6px 12px; font-size: 0.8rem; }

/* Panneau détail en accordéon (mandats-admin.php) : la ligne <tr> qui le
   contient vit dans un tableau à défilement horizontal (.table-wrap), donc
   plus large que l'écran sur mobile. position:sticky recale le panneau sur
   le bord gauche visible du tableau quel que soit le défilement horizontal
   en cours, pour ne jamais avoir à faire défiler la fiche/le formulaire de
   décision sur le côté en plus du défilement vertical de la page. */
.accordion-panel {
    position: sticky;
    left: 0;
    width: 100%;
    max-width: calc(100vw - 64px);
    border-left: 3px solid var(--accent);
    border-radius: 0 10px 10px 0;
    padding-left: 16px;
    /* "th, td { white-space: nowrap }" (tableaux) est hérité par tout le
       contenu de ce panneau puisqu'il vit dans une <td> — sans ce reset,
       les textes (titres, hints...) refusent de passer à la ligne et
       débordent silencieusement au lieu de s'adapter à la largeur. */
    white-space: normal;
}
/* Un flex-item garde par défaut min-width:auto (taille intrinsèque de son
   contenu) — filet de sécurité complémentaire pour les champs imbriqués
   (soumissions, saisie manuelle, field-row...) une fois le retour à la
   ligne du texte rétabli ci-dessus. Ne prime pas sur les min-width
   explicites plus spécifiques comme .field-row .field. */
.accordion-panel, .accordion-panel * { min-width: 0; }
@media (max-width: 600px) {
    .accordion-panel { max-width: calc(100vw - 40px); }
    .accordion-actions { flex-direction: column; align-items: stretch; }
    .accordion-actions button { width: 100%; }
    .mandats-filter-select { max-width: 100% !important; width: 100%; }
}

/* ---------- Modal ---------- */
.modal-overlay {
    position: fixed; inset: 0;
    background: rgba(10, 11, 16, 0.7);
    display: flex; align-items: flex-start; justify-content: center;
    padding: 20px; z-index: 300;
    overflow-y: auto;
}

.modal {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 28px;
    max-width: 560px;
    width: 100%;
    max-height: 88vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.modal h2 { font-size: 1.2rem; }
.modal-hint { font-size: 0.85rem; color: var(--text-secondary); line-height: 1.5; }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 6px; }

/* ---------- Minuteur ---------- */
.timer-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 12px 18px;
    margin-bottom: 16px;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.timer-bar #timer-value {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

.timer-bar.urgent #timer-value { color: var(--danger); }
.timer-bar.urgent { border-color: var(--danger); }

.question-image {
    max-width: 100%;
    max-height: 320px;
    border-radius: 10px;
    margin-bottom: 14px;
    display: block;
}

.open-answer { resize: vertical; }

/* ---------- Quiz taking ---------- */
.question-block {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 24px;
    text-align: left;
    margin-bottom: 20px;
}

.question-block h3 { font-size: 1rem; margin-bottom: 14px; line-height: 1.4; }

.option-label {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    margin-bottom: 8px;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease;
}

.option-label:hover { border-color: var(--accent); }
.option-label input { width: auto; }
.option-label.selected { border-color: var(--accent); background: rgba(91, 141, 239, 0.08); }

/* Relecture (avant envoi côté candidat) et correction (formateur) : la
   réponse saisie reste en surbrillance accent ; en correction, la bonne
   réponse est en plus signalée en vert, et une réponse saisie mais fausse
   en rouge. */
.option-label.correct { border-color: var(--success); background: rgba(76, 175, 125, 0.1); }
.option-label.selected.incorrect { border-color: var(--danger); background: rgba(224, 84, 90, 0.1); }

.progress-bar {
    width: 100%;
    height: 6px;
    background: var(--border);
    border-radius: 999px;
    overflow: hidden;
    margin-bottom: 24px;
}
.progress-bar .fill { height: 100%; background: var(--accent); transition: width 0.3s ease; }

/* Reste visible en descendant la page pendant le passage d'un QCM Examen :
   le minuteur et l'avancement doivent rester consultables sans remonter.
   Le décalage top est calculé en JS (voir quiz.php) car la hauteur du
   bandeau fixe varie avec la largeur d'écran / longueur du nom d'utilisateur. */
.quiz-progress-sticky {
    position: sticky;
    z-index: 150;
    background: var(--bg-dark);
    padding-top: 10px;
}
.quiz-progress-sticky .timer-bar { margin-bottom: 10px; }
.quiz-progress-sticky .progress-bar { margin-bottom: 14px; }

.result-score {
    font-size: 3rem;
    font-weight: 700;
    margin: 10px 0;
}
.result-score.ok { color: var(--success); }
.result-score.ko { color: var(--danger); }

@media (max-width: 500px) {
    .result-score { font-size: 2.2rem; }
    .timer-bar { flex-wrap: wrap; gap: 6px; }
}

footer {
    margin-top: 60px;
    color: var(--text-secondary);
    font-size: 0.85rem;
    text-align: center;
}

@keyframes fadeUp {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ---------- Interrupteur "Mode config" (sous le bouton déconnexion) ---------- */
.switch-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
}
.switch-toggle-label { color: var(--text-secondary); font-size: 0.8rem; font-weight: 600; }

.switch {
    position: relative;
    display: inline-block;
    width: 40px;
    height: 22px;
    flex-shrink: 0;
}
.switch input { opacity: 0; width: 0; height: 0; }
.switch-slider {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background: var(--bg-card-hover);
    border: 1px solid var(--border);
    border-radius: 999px;
    transition: 0.15s;
}
.switch-slider::before {
    content: "";
    position: absolute;
    width: 14px;
    height: 14px;
    left: 3px;
    top: 3px;
    background: var(--text-secondary);
    border-radius: 50%;
    transition: 0.15s;
}
.switch input:checked + .switch-slider { background: var(--accent); border-color: var(--accent); }
.switch input:checked + .switch-slider::before { transform: translateX(17px); background: #fff; }

/* ---------- Glisser-déposer (tuiles / stats en mode config) ---------- */
.draggable-card { cursor: grab; }
.draggable-card:active { cursor: grabbing; }
.draggable-card.dragging { opacity: 0.4; }
.draggable-card.drag-over { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-glow); }
.drag-handle {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-secondary);
    cursor: grab;
}

/* ---------- Tuiles du dashboard en mode paramétrage ---------- */
.tile-manage-card { position: relative; }
.tile-manage-actions {
    display: flex;
    justify-content: center;
    gap: 6px;
    margin-top: 10px;
}
.tile-manage-actions button {
    padding: 4px 8px;
    font-size: 0.78rem;
    width: auto;
}
.tile-add-card {
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px dashed var(--border);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    min-height: 120px;
    font-size: 0.95rem;
}
.tile-add-card:hover { color: var(--accent); border-color: var(--accent); }

/* ---------- Glisser-déposer pour un input[type="file"] (voir assets/dropzone.js) ----------
   L'icône est un ::before en CSS pur (jamais touché par
   dropzoneEl.textContent = ... dans dropzone.js, qui ne remplace que le
   texte) : pas besoin de toucher au balisage de chaque zone existante
   dans l'appli pour la faire apparaître partout. */
.dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    border: 2px dashed var(--border);
    border-radius: 10px;
    padding: 22px 16px;
    text-align: center;
    cursor: pointer;
    color: var(--text-secondary);
    transition: border-color .15s, background .15s;
}
.dropzone::before {
    content: '';
    flex-shrink: 0;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background-color: rgba(91, 141, 239, 0.14);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235b8def' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 15V3'/%3E%3Cpath d='M8 7l4-4 4 4'/%3E%3Cpath d='M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 22px;
    transition: background-color .15s;
}
.dropzone:hover, .dropzone.dragover {
    border-color: var(--accent);
    background: rgba(91, 141, 239, 0.06);
}
.dropzone:hover::before, .dropzone.dragover::before {
    background-color: rgba(91, 141, 239, 0.24);
}
/* Menu horizontal à onglets (rapport-arbitrage-admin.php : Calendrier /
   Statistiques) — générique, réutilisable ailleurs si besoin. */
.tab-bar { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 20px; }
.tab-btn {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--text-secondary);
    font-size: 0.95rem;
    font-family: inherit;
    padding: 10px 16px;
    cursor: pointer;
}
.tab-btn:hover { color: var(--text-primary); }
.tab-btn.active { color: var(--text-primary); border-bottom-color: var(--accent); font-weight: 600; }

/* Tableau des arbitres (rapport-arbitrage-admin.php) : la colonne
   demi-journées est trop étroite pour les flèches natives d'un
   input[type=number], qui s'affichent alors tassées en un bloc grisé. */
.rapport-arbitre-row-demi::-webkit-outer-spin-button,
.rapport-arbitre-row-demi::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.dropzone-files { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.dropzone-file { display: flex; align-items: center; gap: 8px; padding: 6px 10px; background: rgba(255,255,255,0.03); border-radius: 8px; }
.dropzone-file .remove-btn { margin-left: auto; background: none; border: none; color: var(--text-secondary); cursor: pointer; font-size: 1rem; padding: 0 4px; }

/* L'ancien export PDF du calendrier s'appuyait sur window.print() (voir
   historique Git) : remplacé par une génération 100% côté client avec
   jsPDF + jspdf-autotable (calendrier.php, exportAvenirPdf) qui télécharge
   directement le fichier, sans passer par la boîte de dialogue
   d'impression du navigateur ni dépendre de son moteur de pagination —
   plus besoin de feuille @media print dédiée ici. */
