/*
 * IHM (Phase 65) : charte graphique - palette de marque fournie par
 * l'utilisateur (jeu de jetons HSL complet, thème sombre), reprise telle
 * quelle en CSS plutôt que convertie à la main (hsl() natif, aucun
 * risque d'erreur d'arrondi). Appliquée par-dessus le thème sombre
 * natif de Bootstrap 5.3 (data-bs-theme="dark", voir fragments/layout.html)
 * plutôt qu'en réécrivant chaque composant : Bootstrap gère déjà
 * l'inversion des tableaux/formulaires/cartes en mode sombre, seules les
 * variables de marque (couleur primaire, fond, bordures) sont
 * surchargées ici.
 *
 * IHM (Phase 81, polish visuel) : la famille "JetBrains Mono" (jeton
 * --font-mono) a été retirée - chargée depuis la Phase 65 mais jamais
 * référencée par aucun sélecteur, poids mort au chargement de la page.
 *
 * Phase 113 (thèmes) : deux jeux de jetons, un par mode - sombre (par
 * défaut, celui d'origine) et clair - choisis par l'attribut data-bs-theme
 * que pose le fragment "head" de fragments/layout.html. Tout le reste de la
 * feuille ne lit que des jetons (hsl(var(--...))) : changer de mode, ou
 * appliquer le thème d'une organisation (/theme/organisation.css, qui ne
 * redéfinit que des jetons), ne demande aucune autre règle. Les valeurs de
 * --background et --secondary de chaque mode sont aussi des constantes de
 * ThemeCouleurs (contrôle de lisibilité des thèmes d'organisation) :
 * ThemeCouleursTest vérifie qu'elles n'ont pas dérivé.
 */
/*
 * Phase 119 (CSP, RGPD) : la police Syne (titres) est servie par l'application (static/fonts) et non plus par Google Fonts - la politique de
 * sécurité du contenu n'autorise que les ressources de l'application, et chaque chargement depuis Google lui transmettait l'adresse IP de
 * l'utilisateur. Fichiers du paquet npm @fontsource/syne 5.3.0 (licence SIL Open Font License 1.1) : les deux graisses utilisées (500 et
 * 700), jeux de caractères latin et latin étendu ; les plages unicode-range sont celles du paquet (le navigateur ne charge le latin étendu
 * que si la page en contient).
 */
@font-face {
    font-family: 'Syne';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/syne-latin-ext-500-normal.woff2') format('woff2');
    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: 'Syne';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/syne-latin-500-normal.woff2') format('woff2');
    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: 'Syne';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('../fonts/syne-latin-ext-700-normal.woff2') format('woff2');
    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: 'Syne';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('../fonts/syne-latin-700-normal.woff2') format('woff2');
    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;
}

:root {
    --radius: 0.5rem;
    --font-display: 'Syne', sans-serif;
    --sidebar-w: 240px;
}

:root,
[data-bs-theme="dark"] {
    --background: 220 16% 8%;
    --foreground: 210 20% 92%;
    --card: 220 14% 11%;
    --card-foreground: 210 20% 92%;
    --popover: 220 14% 11%;
    --popover-foreground: 210 20% 92%;
    --primary: 273.4 75% 70%;
    --primary-foreground: 220 16% 8%;
    --primary-hover: 273.4 55% 50%;
    --primary-active: 273.4 55% 44%;
    --primary-rgb: 185, 121, 236;
    --secondary: 220 12% 16%;
    --secondary-foreground: 210 20% 80%;
    --muted: 220 12% 14%;
    --muted-foreground: 210 20% 65%;
    --accent: 273.4 75.3% 84.1%;
    --accent-foreground: 220 16% 8%;
    --destructive: 0 72% 55%;
    --destructive-foreground: 0 0% 98%;
    --destructive-rgb: 223, 58, 58;
    --border: 220 12% 18%;
    --input: 220 12% 16%;
    --ring: 273.4 75.3% 84.1%;
    /* La ligne « Notifications » de la barre latérale quand il y a des notifications non lues : un ambre, qui ne se confond ni avec le violet de la marque ni avec
       le rouge des erreurs. ThemeCouleursTest vérifie sa lisibilité (texte ambre sur sa propre teinte, au repos et au survol). */
    --notification: 38 92% 58%;
    /* Copies des jetons ci-dessus que le thème d'une organisation ne redéfinit jamais : le sélecteur de thème de la barre latérale ne lit qu'eux (voir
       .app-theme-bouton), pour rester visible quelles que soient les couleurs de texte ou de lignes réglées - la porte de sortie d'un thème mal réglé.
       ThemeCouleursTest vérifie qu'ils restent égaux aux jetons d'origine. */
    --mode-foreground: 210 20% 92%;
    --mode-muted-foreground: 210 20% 65%;
    --mode-border: 220 12% 18%;
    --mode-secondary: 220 12% 16%;
}

/* Phase 113 : thème clair. Les couleurs de marque y sont assombries pour rester
   lisibles sur fond clair (principale 6,2:1 sur le fond, 5,5:1 sur la surface
   de survol ; accent 5,5:1 ; texte atténué 6,2:1). */
[data-bs-theme="light"] {
    --background: 210 20% 98%;
    --foreground: 220 16% 12%;
    --card: 0 0% 100%;
    --card-foreground: 220 16% 12%;
    --popover: 0 0% 100%;
    --popover-foreground: 220 16% 12%;
    --primary: 273.4 55% 48%;
    --primary-foreground: 0 0% 100%;
    --primary-hover: 273.4 55% 40%;
    --primary-active: 273.4 55% 34%;
    --primary-rgb: 130, 55, 190;
    --secondary: 210 20% 93%;
    --secondary-foreground: 220 16% 25%;
    --muted: 210 20% 95%;
    --muted-foreground: 215 14% 38%;
    --accent: 273.4 60% 52%;
    --accent-foreground: 0 0% 100%;
    --destructive: 0 70% 45%;
    --destructive-foreground: 0 0% 98%;
    --destructive-rgb: 195, 34, 34;
    --border: 214 16% 85%;
    --input: 214 16% 90%;
    --ring: 273.4 60% 52%;
    --notification: 30 90% 28%;
    --mode-foreground: 220 16% 12%;
    --mode-muted-foreground: 215 14% 38%;
    --mode-border: 214 16% 85%;
    --mode-secondary: 210 20% 93%;
}

/* Variables Bootstrap dérivées des jetons - déclarées pour chaque élément qui
   porte data-bs-theme (la racine), de sorte qu'elles se recalculent avec les
   jetons du mode, et avec ceux d'un thème d'organisation. */
:root,
[data-bs-theme] {
    --bs-body-bg: hsl(var(--background));
    /* Texte à luminosité réduite (87 %) plutôt que le blanc quasi plein
       (92 % L) du jeton --foreground brut : trop tranchant sur un fond
       aussi sombre - retour direct de l'utilisateur ("le blanc est un
       peu agressif"). --foreground reste disponible tel quel pour les
       éléments qui ont besoin du blanc plein (nom de marque, icônes). */
    --bs-body-color: hsl(var(--foreground) / 0.87);
    --bs-emphasis-color: hsl(var(--foreground));
    --bs-secondary-color: hsl(var(--muted-foreground));
    --bs-tertiary-bg: hsl(var(--muted));
    --bs-secondary-bg: hsl(var(--secondary));
    --bs-border-color: hsl(var(--border));
    --bs-primary: hsl(var(--primary));
    --bs-primary-rgb: var(--primary-rgb);
    --bs-primary-text-emphasis: hsl(var(--primary));
    /* Liens au repos = texte atténué (pas un bleu vif qui détonne dans
       la page, retour direct de l'utilisateur), primaire teal au survol
       - garde un signal interactif sans crier. L'accent bleu reste
       disponible pour un usage ponctuel volontaire (pas les liens de
       navigation courants). */
    --bs-link-color: hsl(var(--muted-foreground));
    --bs-link-hover-color: hsl(var(--primary));
    --bs-danger: hsl(var(--destructive));
    --bs-danger-rgb: var(--destructive-rgb);
}

h1, h2, h3, h4, .app-sidebar-brand-name {
    font-family: var(--font-display);
}

.btn-primary {
    --bs-btn-bg: hsl(var(--primary));
    --bs-btn-border-color: hsl(var(--primary));
    --bs-btn-color: hsl(var(--primary-foreground));
    --bs-btn-hover-bg: hsl(var(--primary-hover));
    --bs-btn-hover-border-color: hsl(var(--primary-hover));
    --bs-btn-hover-color: hsl(var(--primary-foreground));
    --bs-btn-active-bg: hsl(var(--primary-active));
    --bs-btn-active-border-color: hsl(var(--primary-active));
    --bs-btn-active-color: hsl(var(--primary-foreground));
    --bs-btn-disabled-bg: hsl(var(--primary));
    --bs-btn-disabled-border-color: hsl(var(--primary));
    --bs-btn-disabled-color: hsl(var(--primary-foreground));
    --bs-btn-focus-shadow-rgb: var(--primary-rgb);
}

.btn-outline-primary {
    --bs-btn-color: hsl(var(--primary));
    --bs-btn-border-color: hsl(var(--primary));
    --bs-btn-hover-bg: hsl(var(--primary));
    --bs-btn-hover-border-color: hsl(var(--primary));
    --bs-btn-hover-color: hsl(var(--primary-foreground));
    --bs-btn-active-bg: hsl(var(--primary));
    --bs-btn-active-border-color: hsl(var(--primary));
    --bs-btn-active-color: hsl(var(--primary-foreground));
    --bs-btn-focus-shadow-rgb: var(--primary-rgb);
}

/* Champ qui a le focus : le contour et le halo suivent --ring (l'accent du thème, vert par défaut) au lieu du bleu codé en dur dans Bootstrap (#86b7fe,
   rgba(13, 110, 253, .25)). Même halo pour le focus au clavier des onglets et pour les cases à cocher. Un thème d'organisation règle cette couleur par son
   champ « Couleur d'accent » (voir ThemeCssGenerateur). */
.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    border-color: hsl(var(--ring));
    box-shadow: 0 0 0 0.25rem hsl(var(--ring) / 0.25);
}

.nav-link:focus-visible,
.page-link:focus,
.accordion-button:focus,
.btn-close:focus {
    box-shadow: 0 0 0 0.25rem hsl(var(--ring) / 0.25);
}

/* Barre de navigation latérale (fragments/layout :: sidebar) - remplace
   la barre horizontale du premier jet (retour utilisateur : "pas très
   joli", sidebar préférée) et les trois idiomes ad hoc d'avant Phase 65. */
.app-sidebar {
    width: var(--sidebar-w);
    background-color: hsl(var(--background));
    border-right: 1px solid hsl(var(--border));
    min-height: 100vh;
}

.app-sidebar-brand-name {
    font-weight: 700;
    font-size: 0.95rem;
    color: hsl(var(--foreground));
}

.app-sidebar-brand-sub {
    color: hsl(var(--muted-foreground));
}

/* --brand / --brand-foreground : redéfinis par le thème d'une organisation qui
   colore sa barre latérale (où --primary devient la couleur du texte) pour que
   la marque garde la couleur principale de l'organisation. */
.app-sidebar-icon {
    width: 34px;
    height: 34px;
    border-radius: var(--radius);
    background-color: hsl(var(--brand, var(--primary)));
    color: hsl(var(--brand-foreground, var(--primary-foreground)));
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    flex-shrink: 0;
}

/* Phase 113 : logo téléversé par l'organisation, à la place du carré « SM ». */
.app-sidebar-logo {
    max-width: 64px;
    max-height: 34px;
    object-fit: contain;
    flex-shrink: 0;
}

/* Logo par défaut de l'application (static/img/logo-theme-sombre.png et logo-theme-clair.png) : les deux versions sont dans la page, seule celle du thème en
   vigueur est affichée. Le nom du fichier dit le thème sur lequel il se lit (le « sombre » est la version claire du logo). */
[data-bs-theme="dark"] .logo-theme-clair,
[data-bs-theme="light"] .logo-theme-sombre {
    display: none;
}

.login-logo {
    display: block;
    max-width: 180px;
    max-height: 120px;
    margin: 0 auto 1rem;
    object-fit: contain;
}

.app-sidebar-link {
    display: block;
    padding: 0.55rem 0.75rem;
    border-radius: var(--radius);
    color: hsl(var(--muted-foreground));
    font-size: 0.9rem;
    text-decoration: none;
    /* IHM (Phase 81, polish visuel) : transition douce au survol - les
       boutons/nav-links Bootstrap l'ont nativement, ce lien maison ne
       l'avait pas (changement de couleur instantané). */
    transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out;
}

.app-sidebar-link:hover {
    background-color: hsl(var(--secondary));
    color: hsl(var(--foreground));
}

/* L'entrée du module où l'on se trouve (fragments/layout, ModuleCourant) : teinte et liseré de la couleur principale, texte en gras (le texte reste celui du thème :
   la couleur principale d'une organisation n'a pas à se lire sur sa propre teinte), icône dans la couleur principale. */
.app-sidebar-link.active {
    background-color: hsl(var(--primary) / 0.14);
    color: hsl(var(--foreground));
    font-weight: 600;
    border-left: 2px solid hsl(var(--primary));
    padding-left: calc(0.75rem - 2px);
}

.app-sidebar-link.active i {
    color: hsl(var(--primary));
}

/* Notifications non lues : toute la ligne change de couleur (fond teinté, texte et icône ambre, liseré à gauche comme l'entrée active). Le nombre reste écrit
   dans le libellé : la couleur n'est jamais seule à porter l'information. */
.app-sidebar-link.app-sidebar-link-notifications {
    background-color: hsl(var(--notification) / 0.14);
    color: hsl(var(--notification));
    font-weight: 600;
    border-left: 2px solid hsl(var(--notification));
    padding-left: calc(0.75rem - 2px);
}

.app-sidebar-link.app-sidebar-link-notifications:hover {
    background-color: hsl(var(--notification) / 0.22);
    color: hsl(var(--notification));
}

/* Notifications non lues ET page des notifications ouverte : la teinte ambre se renforce (le liseré ambre est déjà là), pour qu'on voie aussi où l'on est. */
.app-sidebar-link.app-sidebar-link-notifications.active {
    background-color: hsl(var(--notification) / 0.22);
}

.app-sidebar-link.app-sidebar-link-notifications.active i {
    color: hsl(var(--notification));
}

/* Liste « Mes notifications » : même langage que la ligne du menu ci-dessus. Une non lue a un liseré et une teinte ambre légers (8 %), un point devant et son message
   en gras ; une lue est atténuée. Le texte, le lien et l'atténué se lisent sur la teinte (ThemeCouleursTest). */
.list-group-item.app-notification-non-lue {
    background-color: hsl(var(--notification) / 0.08);
    color: hsl(var(--foreground));
    border-left: 3px solid hsl(var(--notification));
}

.app-notification-non-lue .app-notification-message {
    font-weight: 600;
}

.app-notification-point {
    color: hsl(var(--notification));
    font-size: 0.7rem;
    margin-right: 0.25rem;
}

.list-group-item.app-notification-lue {
    color: hsl(var(--muted-foreground));
}

.app-notification-lue .badge {
    opacity: 0.7;
}

.app-sidebar-avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background-color: hsl(var(--secondary));
    color: hsl(var(--foreground));
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    flex-shrink: 0;
}

/* Phase 113 : sélecteur de thème de la barre latérale - trois petits boutons
   (sombre, clair, organisation), celui en vigueur est marqué. Ils ne lisent que les
   jetons --mode-* (jamais redéfinis par le thème d'une organisation, sauf sur sa barre
   latérale colorée où ils prennent les couleurs de la barre) : quelles que soient les
   couleurs de texte et de lignes réglées, on peut toujours revenir au thème sombre ou clair. */
.app-theme-bouton {
    background-color: transparent;
    border: 1px solid hsl(var(--mode-border));
    border-radius: var(--radius);
    color: hsl(var(--mode-muted-foreground));
    padding: 0.15rem 0.45rem;
    line-height: 1.2;
    cursor: pointer;
    transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out;
}

.app-theme-bouton:hover {
    background-color: hsl(var(--mode-secondary));
    color: hsl(var(--mode-foreground));
}

.app-theme-bouton[aria-pressed="true"] {
    background-color: hsl(var(--mode-secondary));
    color: hsl(var(--mode-foreground));
    border-color: hsl(var(--primary));
}

.app-theme-bouton:focus-visible {
    outline: 2px solid hsl(var(--mode-foreground));
    outline-offset: 1px;
}

/* IHM (Phase 81, polish visuel) : largeurs de formulaire standardisées -
   remplace les max-width ad hoc (12 valeurs différentes, de 300 à 960px,
   réparties sur une centaine de formulaires) par 3 paliers fixes. */
.form-width-sm {
    max-width: 480px;
}

.form-width-md {
    max-width: 640px;
}

.form-width-lg {
    max-width: 800px;
}
.nav-pills {
    --bs-nav-pills-link-active-bg: hsl(var(--primary));
    --bs-nav-pills-link-active-color: hsl(var(--primary-foreground));
}

/* Libellés des onglets inactifs : --nav-foreground si le thème d'une organisation le règle, sinon le texte atténué (comme les liens au repos). */
.nav-pills,
.nav-tabs {
    --bs-nav-link-color: hsl(var(--nav-foreground, var(--muted-foreground)));
}

/* Texte sur la couleur principale : le même jeton que les boutons (.btn-primary), pour les onglets actifs ci-dessus, les pastilles et l'entrée active d'un
   menu - Bootstrap les écrit en blanc fixe, ce qui donnait deux couleurs de texte sur le même vert (et 3,05:1 seulement sur le vert d'origine). */
.text-bg-primary {
    color: hsl(var(--primary-foreground)) !important;
}

.dropdown-menu {
    --bs-dropdown-link-active-bg: hsl(var(--primary));
    --bs-dropdown-link-active-color: hsl(var(--primary-foreground));
}
a {
    color: hsl(var(--primary));
}

/* Phase 93 : tri de colonne (tableau-interactif.js) - en-tête cliquable. */
.tableau-tri-colonne {
    cursor: pointer;
    user-select: none;
}

a:hover {
    color: hsl(var(--foreground));
}

.nav-pills .nav-link {      /* "pills" : les coins arrondis */
    border-radius: var(--bs-nav-pills-border-radius);   /* = --bs-border-radius */
}

