/*
 * Charte graphique CIPBourse — fichier source unique.
 *
 * Bootstrap 5.3 n'hérite PAS ses classes de composants (.btn-primary, etc.)
 * des variables racine --bs-primary : chaque composant définit ses propres
 * variables locales avec des valeurs codées en dur au moment du build Sass
 * upstream. On ne peut donc pas se contenter de redéfinir --bs-primary au
 * :root — il faut cibler chaque composant utilisé par l'app. Toujours du
 * CSS pur, aucune étape de build ajoutée.
 */

@font-face {
    font-family: "InterVariable";
    src: url("../fonts/InterVariable-jznyFqg.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

:root {
    /* --- Marque --- */
    --app-navy: #0B2545;         /* fixe quel que soit le thème : texte sur fond doré (--app-accent),
                                    jamais utilisé comme couleur de texte "libre" sur le fond de page
                                    (cf. --app-heading pour ça) — sinon illisible en mode sombre */
    --app-navy-dark: #081B33;    /* fixe : dégradé du bandeau de connexion, toujours sombre */
    --app-heading: var(--app-navy); /* titres + survol de lien : sur le fond de page, donc adapté au thème */
    --app-accent: #C9A24B;       /* fonds (boutons, badges) — toujours avec texte navy dessus */
    --app-accent-ink: #8F6E28;   /* texte/liens sur fond clair */
    --app-accent-soft: #F5EEDD;  /* fond très clair pour états hover/selected discrets */

    /* --- Signaux financiers (réservés : jamais réutilisés ailleurs) --- */
    --app-gain: #1B7A4D;
    --app-gain-soft: #E7F4EE;
    --app-loss: #B3261E;
    --app-loss-soft: #FBEAE9;

    /* --- Info (même bleu que .badge-info de MobileKit, cf. assets/styles/mobilekit.css) --- */
    --app-info: #4A6FA0;

    /* --- Neutres --- */
    --app-bg: #F7F8FA;
    --app-surface: #FFFFFF;
    --app-text: #101828;
    --app-text-secondary: #5B6472;
    --app-text-muted: #8A93A3;
    --app-border: #E2E5EA;

    /* --- Formes --- */
    --app-radius-sm: 0.375rem;   /* 6px — boutons, inputs, badges */
    --app-radius-lg: 0.5rem;     /* 8px — cartes */
    --app-shadow-sm: 0 1px 2px rgba(11, 37, 69, 0.06);
    --app-shadow-md: 0 4px 16px rgba(11, 37, 69, 0.08);

    /* --- Typographie --- */
    --app-font-sans: "InterVariable", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* ==================== Mode sombre ====================
 * Ne redéfinit QUE les neutres/couleurs "libres" sur le fond de page — jamais --app-navy ni
 * --app-accent, qui servent de texte fixe sur fond doré (--app-accent) ou de dégradé de
 * connexion, censés rester sombres quel que soit le thème. Toutes les règles du fichier
 * utilisent déjà ces variables (jamais de couleur codée en dur), donc les redéfinir ici suffit
 * à adapter cartes/tableaux/formulaires/badges sans toucher au reste du fichier.
 * Valeurs de neutres alignées sur celles déjà utilisées par MobileKit pour ses propres
 * composants en mode sombre (cf. assets/styles/mobilekit.css, body.dark-mode-active) — pour
 * que .card/.table (surchargés ci-dessous par ce fichier) restent visuellement cohérents avec
 * le reste de l'appli. Voir aussi assets/mobilekit.js (active en plus [data-bs-theme=dark],
 * qui couvre les classes/composants Bootstrap natifs que ni MobileKit ni ce fichier ne
 * surchargent, ex. .text-secondary/.text-muted). */
body.dark-mode-active {
    --app-heading: #FFFFFF;
    --app-accent-ink: #D9B968;
    --app-accent-soft: #2A2410;

    --app-gain: #4CAF7D;
    --app-gain-soft: #123424;
    --app-loss: #E5615A;
    --app-loss-soft: #3A1613;
    --app-info: #7FA7D9;

    --app-bg: #081221;
    --app-surface: #081B33;
    --app-text: #E3E8EF;
    --app-text-secondary: #A9B4C4;
    --app-text-muted: #6C7A8C;
    --app-border: #1B2A3F;
}

/* ==================== Base ==================== */

body {
    background-color: var(--app-bg);
    color: var(--app-text);
    font-family: var(--app-font-sans);
}

h1, h2, h3, h4, h5, h6 {
    color: var(--app-heading);
    font-weight: 600;
}

a {
    color: var(--app-accent-ink);
}

a:hover {
    color: var(--app-heading);
}

/* Colonnes de valeurs financières : chiffres alignés */
.figures {
    font-variant-numeric: tabular-nums;
}

/* ==================== Signaux gain / perte ==================== */

.text-gain {
    color: var(--app-gain);
}

.text-loss {
    color: var(--app-loss);
}

.badge-gain {
    color: var(--app-gain);
    background-color: var(--app-gain-soft);
}

.badge-loss {
    color: var(--app-loss);
    background-color: var(--app-loss-soft);
}

/* Variante bordure de .badge-info (MobileKit ne fournit que des badges pleins) : fond blanc,
   bordure et texte dans la couleur info. */
.badge-outline-info {
    color: var(--app-info);
    background-color: var(--app-surface);
    border: 1px solid var(--app-info);
}

.badge-outline-secondary {
    color: var(--app-text-secondary);
    background-color: var(--app-surface);
    border: 1px solid var(--app-text-secondary);
}

/* ==================== MobileKit — ajustements layout ====================
 * theme-src/mobilekit/ fournit la structure (header/bottomMenu/sidebar) ;
 * ces quelques règles adaptent son comportement responsive au choix retenu
 * pour CIPBourse : bottom nav + burger + appHeader réservés au mobile,
 * sidebar toujours dépliée à partir de 992px (offcanvas-lg de Bootstrap),
 * avec la marque affichée en haut de la sidebar (à la place de l'appHeader,
 * masqué) plutôt que dans un bandeau horizontal séparé. */

/* #appCapsule prévoit 56px de padding-top pour dégager le .appHeader fixe —
   uniquement en mobile, où il reste affiché. On ajoute 1rem de plus qu'un
   simple raccord pile-poil : sans ça, le titre de page vient se coller
   directement sous la barre. */
@media (max-width: 991.98px) {
    #appCapsule {
        padding-top: calc(56px + 1rem);
    }
}

/* Bootstrap fixe la largeur du panneau replié (< 992px) via
   .offcanvas-lg.offcanvas-start { width: var(--bs-offcanvas-width) }, une
   règle à deux classes plus spécifique que le width: 300px ciblant juste
   .offcanvas-lg dans theme-src/mobilekit/framework/_offcanvas.scss — elle
   l'emportait donc avec la valeur par défaut de Bootstrap (400px), sans
   rapport avec les 300px de .profileBox/.sidebar-buttons. On passe par la
   variable plutôt que de dupliquer un sélecteur à deux classes. */
#sidebarPanel {
    --bs-offcanvas-width: 300px;
}

/* .appHeader et .appBottomMenu sont masquées à partir de 992px : la sidebar
   devient permanente (plus de barre à dégager en haut) et on lui laisse la
   place à gauche. */
@media (min-width: 992px) {
    #appCapsule {
        padding-top: 1.5rem;
        padding-bottom: 24px;
        margin-left: 300px;
    }

    #sidebarPanel.offcanvas-lg {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        visibility: visible;
        border-right: 1px solid var(--app-border);
    }

    #sidebarPanel .offcanvas-body {
        display: block;
    }

    /* .profileBox est positionné en fixed par rapport à la fenêtre (pas à
       #sidebarPanel) dans le SCSS d'origine — pas de décalage à prévoir ici
       puisque l'appHeader est masqué en desktop. */
    #sidebarPanel .profileBox,
    #sidebarPanel .profileBox:before {
        top: 0;
    }
}

/* Sous-menu du sidebar (.multi-level, ex. Administration) : le SCSS d'origine
   anime la hauteur via du JS qu'on n'a pas repris (mesure du contenu en
   pixels) — ouverture/fermeture immédiate ici, sans animation. */
.multi-level.active > ul {
    height: auto;
}

/* ==================== Boutons ==================== */

.btn {
    --bs-btn-border-radius: var(--app-radius-sm);
    font-weight: 500;
}

.btn-primary {
    --bs-btn-color: var(--app-navy);
    --bs-btn-bg: var(--app-accent);
    --bs-btn-border-color: var(--app-accent);
    --bs-btn-hover-color: var(--app-navy);
    --bs-btn-hover-bg: #b8923e;
    --bs-btn-hover-border-color: #b8923e;
    --bs-btn-active-color: var(--app-navy);
    --bs-btn-active-bg: #a9832f;
    --bs-btn-active-border-color: #a9832f;
    --bs-btn-disabled-color: var(--app-navy);
    --bs-btn-disabled-bg: var(--app-accent);
    --bs-btn-disabled-border-color: var(--app-accent);
}

.btn-outline-primary {
    --bs-btn-color: var(--app-accent-ink);
    --bs-btn-border-color: var(--app-accent-ink);
    --bs-btn-hover-color: var(--app-navy);
    --bs-btn-hover-bg: var(--app-accent);
    --bs-btn-hover-border-color: var(--app-accent);
    --bs-btn-active-color: var(--app-navy);
    --bs-btn-active-bg: var(--app-accent);
    --bs-btn-active-border-color: var(--app-accent);
}

.btn-outline-secondary {
    --bs-btn-color: var(--app-text-secondary);
    --bs-btn-border-color: var(--app-border);
    --bs-btn-hover-color: var(--app-text);
    --bs-btn-hover-bg: var(--app-bg);
    --bs-btn-hover-border-color: var(--app-border);
}

.btn-danger {
    --bs-btn-bg: var(--app-loss);
    --bs-btn-border-color: var(--app-loss);
    --bs-btn-hover-bg: #9c211a;
    --bs-btn-hover-border-color: #9c211a;
    --bs-btn-active-bg: #8a1d17;
    --bs-btn-active-border-color: #8a1d17;
}

/* ==================== Cartes ==================== */

.card {
    --bs-card-border-color: var(--app-border);
    --bs-card-border-radius: var(--app-radius-lg);
    box-shadow: var(--app-shadow-sm);
}

/* ==================== Tableaux ==================== */

.table {
    --bs-table-striped-bg: var(--app-bg);
    --bs-table-border-color: var(--app-border);
    color: var(--app-text);
}

.table > thead {
    --bs-table-color: var(--app-text-secondary);
    font-size: 0.8125rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.table > thead th.sortable {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.table > thead th.sortable:hover {
    color: var(--app-text);
}

.table > thead th.sortable .sort-icon {
    margin-left: 0.35rem;
    font-size: 0.75em;
    opacity: 0.35;
}

.table > thead th.sortable .sort-icon.bi-sort-up,
.table > thead th.sortable .sort-icon.bi-sort-down {
    opacity: 1;
    color: var(--app-accent-ink);
}

.api-log-json {
    max-width: 320px;
    max-height: 160px;
    overflow: auto;
    background-color: var(--app-bg);
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    padding: 0.375rem 0.5rem;
    white-space: pre-wrap;
    word-break: break-word;
}

.pre-wide {
    max-width: none;
    max-height: none;
    width: 100%;
}

.api-log-modal-dialog .modal-body {
    min-height: 55vh;
}

/* Sélecteur de liste de suivi (page Listes) : doit se lire comme un titre de page (h3), pas
   comme un champ de formulaire ordinaire — évite de dupliquer le nom de la liste sélectionnée
   avec un <h1> séparé (Bootstrap ne prévoit pas de style "titre" pour un <select>). */
.watchlist-name-select {
    color: var(--app-heading);
}

/* ==================== Formulaires ==================== */

.form-control,
.form-select {
    border-color: var(--app-border);
    border-radius: var(--app-radius-sm);
}

.form-control:focus,
.form-select:focus {
    border-color: var(--app-accent-ink);
    box-shadow: 0 0 0 0.2rem var(--app-accent-soft);
}

.form-label {
    color: var(--app-text-secondary);
    font-weight: 500;
    font-size: 0.875rem;
}

/* ==================== Page de connexion ==================== */

.login-shell {
    min-height: calc(100vh - 6rem);
}

.login-card {
    border: none;
    box-shadow: var(--app-shadow-md);
}

.login-card-header {
    background: linear-gradient(135deg, var(--app-navy), var(--app-navy-dark));
    color: var(--app-accent);
}

.login-card-header p {
    color: #ffffff;
    font-weight: 700;
    letter-spacing: 0.02em;
}

/* ==================== Mobile ==================== */

/* Bootstrap ne fait pas passer les .btn-group à la ligne par défaut : sur un
   téléphone étroit, un groupe de boutons trop large (ex. sélecteur d'indicateurs
   du graphique) déborderait silencieusement au lieu de s'adapter. */
@media (max-width: 575.98px) {
    .btn-group-sm {
        flex-wrap: wrap;
    }
}

/* Cible tactile minimale pour les boutons icône seule des colonnes d'actions,
   sans changer la densité de l'affichage desktop. */
@media (max-width: 767.98px) {
    .table > tbody > tr > td:last-child .btn {
        min-width: 2.25rem;
    }
}

/* Réduit tous les boutons à la densité "sm" sur mobile — la taille par défaut de
   mobilekit.css est pensée pour desktop et prend trop de place sur petit écran.
   On recopie ici les valeurs pixel de ses classes .btn-sm / .btn-icon.btn-sm (cf.
   mobilekit.css) plutôt que les variables --bs-btn-* de Bootstrap : mobilekit les
   surcharge déjà avec des valeurs codées en dur, donc jouer sur les variables
   Bootstrap seules n'aurait aucun effet visible. theme.css est chargé après
   mobilekit.css, donc ces règles gagnent à spécificité égale. */
@media (max-width: 767.98px) {
    .btn {
        height: 30px;
        padding: 0 12px;
        font-size: 12px;
    }

    .btn i.bi,
    .btn i.icon,
    .btn ion-icon {
        font-size: 20px;
        margin-right: 6px;
    }

    .btn-icon {
        width: 30px;
        height: 30px;
    }

    .btn-icon i.bi,
    .btn-icon i.icon,
    .btn-icon ion-icon {
        font-size: 18px;
    }
}

/* mobilekit.css redéfinit .input-group-text en style "underline" (border-bottom
   seul, sans fond) pour son propre design de formulaire. Nos .input-group
   utilisent le style Bootstrap classique (input encadré) : sans ce correctif,
   le suffixe de devise (ex. modales achat/vente, seuil d'alerte) se retrouve
   sans bordure alors que le champ à côté en a une. */
.input-group .input-group-text {
    background-color: var(--bs-tertiary-bg);
    border: var(--bs-border-width) solid var(--bs-border-color);
    border-radius: 0;
    color: var(--bs-body-color);
    font-size: inherit;
    font-weight: inherit;
    height: auto;
    padding: 0.375rem 0.75rem;
}

/* Aligne la hauteur des champs sur celle des boutons réduits ci-dessus (30px) —
   sans ça, un input ou un select à côté d'un bouton dans un .input-group (ex.
   recherche d'instruments, sélecteur de liste de suivi) garde la hauteur
   desktop de Bootstrap (~38px) et dépasse visiblement du bouton voisin. Doit
   être déclaré APRÈS la règle .input-group-text ci-dessus : à spécificité
   égale, l'ordre du fichier tranche, et cette règle doit gagner sur mobile
   pour que le suffixe (%, devise) ne redevienne pas plus haut que le champ.
   Bug rencontré et corrigé le 2026-08-20 sur le seuil d'une alerte. */
@media (max-width: 767.98px) {
    .input-group .form-control,
    .input-group .form-select,
    .input-group .input-group-text {
        height: 30px;
        padding-top: 0;
        padding-bottom: 0;
        font-size: 12px;
    }
}

/* ==================== Signaux divers ==================== */

/* Étoile "déjà dans une liste de suivi" — seul usage de --app-accent (doré) hors CTA. */
.text-gold {
    color: var(--app-accent);
}

/* ==================== Footer ==================== */

.app-footer {
    background-color: var(--app-surface);
    border-top: 1px solid var(--app-border);
    color: var(--app-text-muted);
    font-size: 0.8125rem;
}
