/*
 * Styléo Design System
 * Charte graphique unifiée (couleurs, typo, ombres, gradients)
 * Inspirée par https://www.styleo.fr
 *
 * PALIERS RESPONSIVE — quatre, et pas un de plus. Les mêmes dans `mailpilot.css` et dans
 * `app.js` (`matchMedia`), sinon une règle CSS et le code qui la double basculent à deux
 * largeurs différentes et l'interface se contredit pendant quelques pixels.
 *
 *   1150px  bascule large / étroit : au-dessus, les volets tiennent côte à côte
 *    900px  intermédiaire : les colonnes latérales passent en tiroir (agendas)
 *    760px  téléphone : un seul volet à la fois, en-tête sur une ligne
 *    560px  petit téléphone : les lignes de champs s'empilent
 *
 * S'y ajoute un palier de HAUTEUR, et un seul : `max-height: 500px` en paysage, le téléphone
 * couché. Il ne redispose rien, il comprime le chrome. Il vit en fin de `mailpilot.css`.
 *
 * `min-width: 761px` apparaît une fois, pour le menu réduit : c'est le miroir exact du palier
 * 760, la façon d'écrire « au-dessus du téléphone », et non un cinquième seuil.
 *
 * Une valeur ne peut pas venir d'une variable ici : `@media` n'évalue pas `var()`.
 * Les seuils sont donc écrits en clair, et cette liste est leur inventaire.
 */

:root {
    /* Palette neutre (encre & papier) */
    --ink: #0b0b0c;
    --ink-2: #242429;
    --muted: #6b6b72;      /* 4,6:1 au pire (voile d'accent, gris des séparateurs de date) — passe AA ([MAIL 107]) */
    --paper: #f3f2ee;
    --white: #fff;

    /*
     * Teinte des bordures, séparateurs et survols : la composante RVB seule, pour qu'une même
     * déclaration serve les deux thèmes en ne changeant que l'opacité au point d'usage
     * (`rgba(var(--teinte-rgb), .12)`). C'est de l'encre sur du papier, et du blanc sur du noir —
     * l'inverse donnerait des traits invisibles.
     */
    --teinte-rgb: 11, 11, 12;

    /* Lignes & bordures */
    /* Surfaces translucides (en-tête, cartes, modales) : le fond transparaît derrière, il faut
       donc une teinte qui appartienne au thème — un blanc en dur y ferait un voile laiteux. */
    /* État « or » (survol d'un bouton, onglet actif, pastille allumée) : aplat en clair, voile
       en sombre. Le trio fond/texte/trait va ensemble — le changer d'un côté seulement casse
       la lisibilité de l'autre. */
    --or-fond: var(--yellow);
    --or-texte: #0b0b0c;
    --or-trait: var(--yellow);

    /*
     * Texte posé sur un VOILE de couleur (alerte, badge, bandeau) — à ne pas confondre avec
     * `--or-texte`, qui va sur un aplat plein.
     *
     * Ces trois-là existent parce qu'un voile change de nature avec le thème : `rgba(255,196,61,.12)`
     * donne un jaune très pâle sur du papier et un brun sombre sur du noir. Une couleur de texte
     * écrite en dur pour le premier cas disparaît dans le second — c'est ce qui rendait illisibles,
     * de nuit, le bandeau « message douteux » et toutes les alertes de l'application.
     */
    --avert-texte: #7d6208;   /* sur un voile ambre  : avertissement, « à faire », coût — 4,8:1 au pire (papier) */
    --succes-texte: #1e6d4a;  /* sur un voile vert   : confirmation */
    --danger-texte: #8c2b33;  /* sur un voile rouge  : erreur, message frauduleux */

    /* Pictogrammes colorés des actions du message : une couleur par famille d'action, assez
       dense pour un trait de 14 px sur la surface du thème (l'or de la palette, par exemple,
       est trop pâle en trait fin sur du blanc). */
    --ico-or: #c9930a;        /* devis */
    --ico-bleu: #2f6fd6;      /* lu / non lu */
    --ico-mauve: #7c4fd6;     /* agenda : rendez-vous, disponibilités */
    --ico-vert: #2a9d63;      /* répondre */
    --ico-rouge-pale: #e0717b; /* indésirable */

    --verre: rgba(255, 255, 255, .92);
    --verre-header: rgba(255, 255, 255, .84);

    --line: rgba(11, 11, 12, .13);
    --line-strong: rgba(11, 11, 12, .24);

    /* Palette d'accent (couleurs primaires & états) */
    --coral: #ff2f63;      /* Corail — RÉSERVÉ au dégradé & lueurs de fond (jamais en aplat d'UI) */
    --orange: #f8784d;     /* Orange chaud — accent d'UI (index, liens, focus, états) */
    --yellow: #ffc43d;     /* Or — hover boutons, alertes */
    --green: #2da56f;      /* Vert — succès, positif */
    --success: var(--green);  /* alias sémantique (badges « ✓ configurée », etc.) */
    --danger: #c53b45;     /* Rouge — erreurs, danger */

    /* Accent de travail (UI). Le corail ne sert QUE dans le dégradé/lueurs (charte Styléo). */
    --accent: var(--orange);
    --accent-soft: rgba(248, 120, 77, .10);
    --accent-line: rgba(248, 120, 77, .30);
    --accent-text: #a74c1d;   /* orange foncé lisible pour texte sur fond clair : 4,6:1 au pire (voile d'accent sur papier) */
    /* Texte ou pictogramme posé SUR l'aplat d'accent (pastille, onglet actif, numéro d'étape).
       Le blanc sur l'orange de la charte ne tient que 2,7:1 : l'encre sombre en tient plus de 7. */
    --sur-accent: #0b0b0c;

    /* Gradient signature (corail → orange → or) : moments expressifs uniquement */
    --gradient: linear-gradient(120deg, var(--coral), var(--orange) 55%, var(--yellow));

    /* Ombre standard */
    --shadow: 0 24px 70px rgba(11, 11, 12, .12);
    --shadow-sm: 0 8px 24px rgba(11, 11, 12, .08);

    /* Échelle de rayons (cohérence visuelle) */
    --radius-sm: 10px;     /* inputs, petits boutons, stepper */
    --radius: 14px;        /* cartes internes, alertes, tables, propositions */
    --radius-lg: 18px;     /* cartes principales, modale */
    --radius-pill: 999px;  /* boutons pilule, tags */

    /* Courbe de transition partagée */
    --ease: .18s ease;

    /* Typographie */
    --font-display: "New Amsterdam", Haettenschweiler, "Arial Narrow", sans-serif;
    /* « Twemoji Country Flags » en tête : elle ne couvre que les drapeaux (fonts.css), tout le
       reste du texte passe à Open Sans. */
    --font-body: "Twemoji Country Flags", "Open Sans", sans-serif;

    /* Spacing */
    --gap: 1rem;
    --gap-lg: 2rem;
    --gap-xl: 3rem;
}

/* ===================================================================================
 * THÈME SOMBRE
 *
 * Seuls les JETONS changent : aucune règle de mise en page n'est dupliquée, et une
 * couleur oubliée quelque part se voit immédiatement au lieu de se cacher.
 *
 * Ce n'est pas une inversion mécanique du thème clair. Les surfaces sombres montent
 * en clarté à mesure qu'elles s'élèvent (fond de page < carte < champ), là où en clair
 * c'est l'inverse — c'est ainsi qu'on lit la profondeur sans ombres portées, qui ne se
 * voient pas sur du noir. Les accents sont éclaircis : l'orange de la charte, posé sur
 * du sombre, perd le contraste qu'il a sur du papier.
 *
 * Deux sélecteurs pour un seul jeu : le choix explicite de l'utilisateur, et le mode
 * « auto » qui suit le système. La duplication est assumée — une media query ne peut
 * pas être factorisée avec un attribut.
 * ================================================================================= */

/* Les contrôles natifs (cases, listes déroulantes, ascenseurs, calendriers) suivent le thème :
   sans cette déclaration, le navigateur les dessine en clair sur le fond sombre. */
:root[data-theme="dark"] { color-scheme: dark; }
@media (prefers-color-scheme: dark) { :root[data-theme="auto"] { color-scheme: dark; } }

:root[data-theme="dark"] {
    --ink: #f0ebe3;          /* l'encre devient claire : c'est le TEXTE, pas la couleur sombre.
                                Blanc-CRÈME et non blanc pur : moins dur, et fidèle au papier. */
    --ink-2: #d3ccc1;
    --muted: #a2988f;        /* 4,6:1 sur une ligne choisie (voile d'accent sur sombre) */
    --paper: #15120f;        /* fond de page : la surface la plus basse, brun très sombre */
    --white: #1f1b17;        /* surface élevée (cartes, champs, menus) */
    --or-fond: rgba(255, 209, 102, .16);
    --or-texte: #ffd9a0;
    --or-trait: rgba(255, 209, 102, .45);

    /* Sur un voile de couleur, le texte s'éclaircit comme le reste de l'encre : le voile est
       sombre ici, alors qu'il est très pâle en thème clair. */
    --avert-texte: #ffd9a0;
    --succes-texte: #7fe0ae;
    --danger-texte: #ff9aa2;
    --ico-or: #ffd166;
    --ico-bleu: #8ab8ff;
    --ico-mauve: #c4a8ff;
    --ico-vert: #5fd39a;
    --ico-rouge-pale: #ff9aa2;

    --verre: rgba(33, 29, 24, .92);
    --verre-header: rgba(21, 18, 15, .82);

    --teinte-rgb: 240, 235, 227;
    --line: rgba(240, 235, 227, .14);
    --line-strong: rgba(240, 235, 227, .26);

    /* Accents éclaircis pour tenir le contraste sur fond sombre. */
    --orange: #ff8f66;
    --yellow: #ffd166;
    --green: #4fc48c;
    --danger: #ff7b85;
    --accent-soft: rgba(255, 143, 102, .14);
    --accent-line: rgba(255, 143, 102, .38);
    --accent-text: #ffb694;  /* le texte d'accent doit rester lisible SUR du sombre */
    --sur-accent: #1f1b17;

    /* Les ombres restent noires, et plus franches : sur fond sombre, une ombre légère
       ne détache rien du tout. */
    --shadow: 0 24px 70px rgba(0, 0, 0, .55);
    --shadow-sm: 0 8px 24px rgba(0, 0, 0, .40);
}

@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] {
        --ink: #f0ebe3;
        --ink-2: #d3ccc1;
        --muted: #a2988f;
        --paper: #15120f;
        --white: #1f1b17;
        --or-fond: rgba(255, 209, 102, .16);
        --or-texte: #ffd9a0;
        --or-trait: rgba(255, 209, 102, .45);

        --avert-texte: #ffd9a0;
        --succes-texte: #7fe0ae;
        --danger-texte: #ff9aa2;
        --ico-or: #ffd166;
        --ico-bleu: #8ab8ff;
        --ico-mauve: #c4a8ff;
        --ico-vert: #5fd39a;
        --ico-rouge-pale: #ff9aa2;

        --verre: rgba(33, 29, 24, .92);
        --verre-header: rgba(21, 18, 15, .82);

        --teinte-rgb: 240, 235, 227;
        --line: rgba(240, 235, 227, .14);
        --line-strong: rgba(240, 235, 227, .26);

        --orange: #ff8f66;
        --yellow: #ffd166;
        --green: #4fc48c;
        --danger: #ff7b85;
        --accent-soft: rgba(255, 143, 102, .14);
        --accent-line: rgba(255, 143, 102, .38);
        --accent-text: #ffb694;
        --sur-accent: #1f1b17;

        --shadow: 0 24px 70px rgba(0, 0, 0, .55);
        --shadow-sm: 0 8px 24px rgba(0, 0, 0, .40);
    }
}

/*
 * Sélecteur d'apparence — discret, collé au pied de la barre.
 *
 * Ce n'est pas un réglage de travail : on le touche une fois, peut-être deux. Il se tient donc
 * en retrait, sous forme de trois pictogrammes sans libellé (le titre au survol suffit), et
 * `margin-top: auto` le pousse en bas quelle que soit la longueur du menu.
 */
.theme-switch {
    display: flex;
    gap: 2px;
    /* Centré dans son pied, qui porte désormais le collage en bas et le fond. */
    margin: 0 auto;
    padding: 2px;
    background: rgba(var(--teinte-rgb), .05);
    border-radius: var(--radius-pill);
    width: fit-content;
}

/*
 * Pied de barre : fond PLEIN sur toute la largeur, et collé en bas.
 *
 * Le sélecteur d'apparence portait seul le `sticky`, avec un halo de 6 px pour tout fond. Sur un
 * écran court — un téléphone couché — le menu passe dessous et se lisait de part et d'autre des
 * trois pictogrammes : « INTELLIGE ☀ CIELLE ». Un fond qui ne couvre pas toute la largeur ne
 * sépare rien.
 */
.sidebar-pied {
    /*
     * PAS `sticky`. Il l'a été, pour rester joignable quand le menu dépasse l'écran — mais un
     * élément collé ne réserve pas sa place : il flottait au-dessus de la fin du menu et
     * recouvrait « Ajouter une boîte mail… », qu'on ne pouvait plus ni lire ni atteindre.
     * En fin de flux, `margin-top: auto` le pose en bas quand il y a de la place, et le laisse
     * après le contenu quand il faut dérouler. C'est un réglage d'ambiance : le dérouler pour
     * l'atteindre coûte moins cher que de perdre une commande derrière lui.
     */
    z-index: 2;
    /* Marges négatives : le fond rejoint les bords de la barre malgré son retrait — d'où le
       jeton, qui garantit que les deux valeurs restent la même. */
    margin: auto calc(var(--sidebar-retrait) * -1) calc(var(--sidebar-retrait-y) * -1);
    padding: 10px var(--sidebar-retrait);
    background: var(--white);
    border-top: 1px solid var(--line);
}
.theme-opt {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 26px;
    border: 0;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    transition: background var(--ease), color var(--ease);
}
.theme-opt span { display: none; }   /* le libellé vit dans l'infobulle : la place est comptée */
.theme-opt .lc { width: 14px; height: 14px; }
.theme-opt:hover { color: var(--ink); }
.theme-opt.active { background: var(--white); color: var(--ink); box-shadow: 0 1px 2px rgba(0, 0, 0, .14); }

/* Au doigt, 30 px de large se ratent une fois sur trois : le sélecteur s'élargit sur mobile,
   où la place ne manque pas — le tiroir fait 280 px et le pied est vide. */
@media (max-width: 760px) {
    /*
     * Au doigt, la cible doit être atteignable — pas monumentale. Les trois pictogrammes
     * s'étiraient sur toute la largeur du tiroir en 74 x 42 px chacun : un réglage qu'on
     * touche une fois par an occupait le pied du menu comme s'il en était le sujet.
     * Largeur naturelle, centrée, et une cible qui reste confortable.
     */
    .theme-switch { padding: 3px; }
    .theme-opt { width: 46px; height: 34px; }
    .theme-opt .lc { width: 16px; height: 16px; }
}

/* Réinitialisation & normes */
* { box-sizing: border-box; }
[hidden] { display: none !important; }

html {
    min-width: 320px;
    background: var(--paper);
}

body {
    margin: 0;
    color: var(--ink);
    background:
        radial-gradient(circle at 5% 8%, rgba(255, 196, 61, .12), transparent 20rem),
        radial-gradient(circle at 95% 18%, rgba(255, 47, 99, .08), transparent 23rem),
        var(--paper);
    font: 15px/1.55 var(--font-body);
}

button, input, select, textarea { font: inherit; }
button { color: inherit; }
button, select { cursor: pointer; }

/* Focus visible (accessibilité) */
button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
    outline: 3px solid rgba(248, 120, 77, .35);
    outline-offset: 2px;
}

/* Noise pattern (texture subtile) */
.noise {
    position: fixed;
    inset: 0;
    z-index: -1;
    opacity: .07;
    pointer-events: none;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.45'/%3E%3C/svg%3E");
}

/* ============================================================ */
/* LAYOUT PRINCIPAL                                             */
/* ============================================================ */

.app-container {
    display: grid;
    grid-template-columns: 280px 1fr;
    min-height: 100vh;
    gap: 0;
}

.app-sidebar {
    background: var(--white);
    border-right: 1px solid var(--line);
    overflow-y: auto;
    /*
     * Le retrait latéral est un JETON, parce que le pied s'en sert en négatif pour aller
     * chercher les bords. Deux valeurs écrites séparément, c'est un pied plus large que sa
     * barre dès qu'un mode change le retrait — et une barre de défilement horizontale.
     */
    --sidebar-retrait: var(--gap);
    --sidebar-retrait-y: var(--gap-lg);
    padding: var(--sidebar-retrait-y) var(--sidebar-retrait);
    /* Colonne : c'est ce qui permet au sélecteur d'apparence de tomber en PIED de barre
       (margin-top: auto) plutôt que de flotter sous la dernière entrée du menu. */
    display: flex;
    flex-direction: column;
    /*
     * Collée à la fenêtre, avec son propre défilement.
     *
     * C'est la PAGE qui défile dans cette application, barre comprise : sur un écran long comme
     * « IA & confidentialité », la barre s'étirait sur toute la hauteur du contenu et son pied
     * partait à 2 500 px — il fallait dérouler la page entière pour retrouver le sélecteur
     * d'apparence, et le menu lui-même disparaissait dès qu'on lisait le bas d'une page.
     */
    position: sticky;
    top: 0;
    height: 100vh;
    align-self: start;
}

.app-main {
    display: flex;
    flex-direction: column;
    /* min-width: 0 est INDISPENSABLE, pas une précaution : .app-main est un élément de
       grille, sa largeur minimale automatique vaut donc « min-content ». Sans cette
       ligne, un seul contenu large enfoui n'importe où (un tableau, un graphique)
       élargit toute la colonne, et la page entière part en travers — les conteneurs
       à défilement placés autour du contenu large n'y peuvent alors plus rien,
       puisque c'est leur ANCÊTRE qui s'élargit. */
    min-width: 0;
}

.app-header {
    position: sticky;
    top: 0;
    z-index: 30;
    background: var(--verre-header);
    backdrop-filter: blur(18px);
    border-bottom: 1px solid var(--line);
    min-height: 72px;
    padding: var(--gap) var(--gap-lg);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.app-header h2 { font-family: var(--font-display); text-transform: uppercase; letter-spacing: .03em; margin: 0; font-size: 20px; }

/* Bouton hamburger (mobile) + conteneur du titre + contrôles de droite */
.header-title { display: flex; align-items: center; gap: 10px; min-width: 0; }
.header-controls { display: flex; align-items: center; gap: 1rem; }

.nav-burger {
    display: none;
    align-items: center; justify-content: center;
    width: 38px; height: 38px; flex-shrink: 0;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--white); cursor: pointer;
}
.nav-burger .lc { width: 20px; height: 20px; }
.sidebar-backdrop { display: none; }

.app-content {
    flex: 1;
    overflow-y: auto;
    padding: var(--gap-lg);
    min-width: 0; /* même raison que .app-main : ne jamais se laisser élargir par son contenu */
}

/* Fondu d'apparition au changement de vue / d'étape (re-déclenché par display none→block) */
@keyframes viewIn {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

#view-new, #view-drafts, #view-calendar, #view-history,
#step1, #step2, #step3, #step4 {
    animation: viewIn .25s ease;
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
    }
}

/* ============================================================ */
/* NAVIGATION                                                   */
/* ============================================================ */

.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    color: var(--ink);
}

/*
 * MENU RÉDUIT — la barre tombe à la largeur d'un pictogramme.
 *
 * Sur un portable, et plus encore sur une tablette en paysage, 280 px de menu permanent prennent
 * un tiers de la largeur pour une navigation qu'on utilise quelques secondes par heure. Replié,
 * il ne reste que les pictogrammes ; le libellé passe dans `title`, il n'est pas supprimé.
 *
 * Rien de tout cela ne joue sous 760 px : là, le menu est déjà un tiroir ouvert au burger, et il
 * n'occupe la largeur que le temps qu'on s'en serve.
 */
.sidebar-tete {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: var(--gap-xl);
}
.brand { flex: 1 1 auto; min-width: 0; }
.nav-repli {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--white);
    color: var(--muted);
    cursor: pointer;
}
.nav-repli:hover { background: var(--or-fond); border-color: var(--or-trait); color: var(--or-texte); }
.nav-repli .lc { width: 16px; height: 16px; }

/*
 * Le mode réduit ne vaut qu'AU-DESSUS du palier téléphone. `min-width: 761px` est le miroir
 * exact de `max-width: 760px`, pas un cinquième palier : sous cette largeur le menu est un
 * tiroir, il ne prend de la place que le temps qu'on s'en sert, et le réduire n'aurait aucun
 * effet — sauf à écraser la grille du tiroir, ce que ces règles feraient sans cette borne.
 */
@media (min-width: 761px) {
    /* La colonne suit : sans elle, la barre rétrécirait dans une piste restée à 280 px. */
    .nav-reduit.app-container { grid-template-columns: 64px 1fr; }
    .nav-reduit .app-sidebar { --sidebar-retrait: 10px; }
    .nav-reduit .brand,
    .nav-reduit .nav-label,
    .nav-reduit .nav-section-title,
    .nav-reduit .sidebar-boites { display: none; }
    .nav-reduit .sidebar-tete { justify-content: center; margin-bottom: var(--gap-lg); }
    .nav-reduit .nav-link {
        justify-content: center;
        padding: 10px 0;
        gap: 0;
    }
    /*
     * Replié, les titres de rubrique disparaissent — et avec eux la marge qui portait le rythme.
     * Il repasse donc au `gap`, et se resserre : sans libellé à séparer, huit pixels suffisent à
     * lire trois groupes de pictogrammes, là où seize creusaient des trous.
     */
    .nav-reduit .nav-menu { gap: 8px; }

    /* En colonne : trois pictogrammes côte à côte dans 64 px seraient trop serrés pour être
       visés, et débordaient de la barre. Empilés, ils gardent une cible confortable. */
    .nav-reduit .theme-switch { flex-direction: column; }
    .nav-reduit .theme-opt { width: 30px; height: 26px; }
    /* Le bouton de repli n'a plus qu'à se centrer : la marque a disparu à côté de lui. */
    .nav-reduit .nav-repli { margin: 0 auto; }
}

.brand strong {
    font-family: var(--font-display);
    text-transform: uppercase;
    font-size: 26px;
    font-weight: 400;
    letter-spacing: .04em;
}

.brand img {
    height: 38px;
    width: auto;
    object-fit: contain;
    /* Le logo est un JPEG sur fond blanc : `multiply` fait disparaître ce fond dans le papier. */
    mix-blend-mode: multiply;
}

/*
 * En sombre, `multiply` noircirait le logo au point de l'effacer. On lui rend donc son fond
 * blanc, sur une pastille discrète. Inverser l'image aurait été plus simple, mais retournerait
 * aussi les couleurs de la marque — un logo Styléo bleu ne serait plus le logo Styléo.
 */
:root[data-theme="dark"] .brand img {
    mix-blend-mode: screen;
    filter: invert(1) hue-rotate(180deg);
}
@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] .brand img {
        mix-blend-mode: screen;
        filter: invert(1) hue-rotate(180deg);
    }
}

.brand-divider {
    width: 1px;
    height: 24px;
    background: var(--line-strong);
}

/* Marque dans l'en-tête, téléphone seulement : logo réduit, séparateur et nom en police
   d'affichage, la même que la barre latérale en plus petit. Même traitement du logo JPEG en
   thème sombre que `.brand img`. */
.header-brand { display: none; }
@media (max-width: 760px) {
    .header-brand {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        min-width: 0;
    }
    .header-brand img { height: 22px; width: auto; object-fit: contain; mix-blend-mode: multiply; }
    .header-brand-nom {
        font-family: var(--font-display);
        text-transform: uppercase;
        font-size: 17px;
        letter-spacing: .04em;
        color: var(--ink);
        white-space: nowrap;
        padding-left: 8px;
        border-left: 1px solid var(--line-strong);
        line-height: 22px;
    }
    :root[data-theme="dark"] .header-brand img { mix-blend-mode: screen; filter: invert(1) hue-rotate(180deg); }
}
@media (max-width: 760px) and (prefers-color-scheme: dark) {
    :root[data-theme="auto"] .header-brand img { mix-blend-mode: screen; filter: invert(1) hue-rotate(180deg); }
}

/*
 * RYTHME VERTICAL DU MENU — une seule valeur, portée par les titres de rubrique.
 *
 * L'espace qui précède un groupe appartient à SON titre, jamais à un `gap` de conteneur. C'est
 * ce qui rend « Boîtes ouvertes » — qui vit hors de `.nav-menu`, en frère dans la barre —
 * exactement aussi espacé que « Configuration » : les deux portent le même titre, donc la même
 * marge. Avec un `gap` sur le menu, le premier groupe hors menu retombait à zéro et l'œil
 * voyait aussitôt que le rythme se cassait.
 */
.nav-menu {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0;
}

/* Espacements resserrés : la barre porte maintenant huit entrées, et l'aération d'origine
   faisait déborder la dernière section sous la ligne de flottaison sur un portable. */
/*
 * Aucune marge ici : le rythme appartient au titre, et à lui seul. Cette marge s'ajoutait à
 * celle du titre pour donner 36 px entre rubriques, quand « Boîtes ouvertes » — qui n'est pas
 * une `.nav-section` — n'en recevait que 20. Deux sources d'espacement pour un même rythme, et
 * l'œil voyait immédiatement lequel des groupes n'était pas à sa place.
 */
.nav-section {
    margin: 0;
}

.nav-section-title {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--muted);
    font-weight: 600;
    /* Le premier nombre EST le rythme entre groupes (cf. .nav-menu). */
    margin: 20px 0 4px;
}
/* Le premier groupe suit la marque, qui pose déjà son propre écart. */
.nav-menu > .nav-section:first-child > .nav-section-title { margin-top: 0; }

.nav-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    /* 32 px de retrait mangeaient la largeur utile : « Comment ça marche » revenait à la ligne
       et cette entrée devenait deux fois plus haute que ses voisines. Le retrait s'aligne aussi
       sur celui des titres de rubrique, qui n'en avaient pas. */
    padding: 10px var(--gap);
    background: transparent;
    border: none;
    border-radius: 10px;
    color: var(--muted);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--ease), color var(--ease);
    font-weight: 600;
    font-size: 14px;
}

.nav-link:hover { background: rgba(var(--teinte-rgb), .045); color: var(--ink); }

.nav-link.active { background: rgba(var(--teinte-rgb), .05); color: var(--ink); }

/* Marqueur dégradé (au lieu d'un aplat rose) */
.nav-link.active::before {
    content: "";
    position: absolute;
    left: 6px;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 18px;
    border-radius: 3px;
    background: var(--gradient);
}

/* Une entrée de menu tient sur UNE ligne, à toute largeur : un libellé qui passe à la ligne
   double la hauteur de sa case et désaligne toute la colonne. Il se coupe plutôt. */
.nav-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.nav-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ============================================================ */
/* FORMULAIRES                                                  */
/* ============================================================ */

.form-group {
    margin-bottom: var(--gap-lg);
}

.form-group label {
    display: block;
    margin-bottom: 8px;
    color: var(--ink-2);
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.form-group .help-text {
    font-size: 12px;
    color: var(--muted);
    margin-top: 6px;
}

.form-input, .form-textarea {
    width: 100%;
    min-height: 48px;
    padding: 11px 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--white);
    color: var(--ink);
    font-size: 15px;
    transition: border-color .2s, box-shadow .2s;
}

.form-input:hover, .form-textarea:hover { border-color: var(--line-strong); }

.form-input:focus, .form-textarea:focus {
    outline: none;
    border-color: var(--orange);
    box-shadow: 0 0 0 4px rgba(248, 120, 77, .09);
}

.form-textarea {
    resize: vertical;
    min-height: 120px;
}

/* Étape 2 : sélection des réseaux (configurés vs à configurer) */

.net-badge {
    font-size: 11px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(45, 165, 111, .12);
    color: var(--green);
    white-space: nowrap;
}

.net-badge.todo {
    background: rgba(255, 196, 61, .16);
    color: var(--avert-texte);
}

/* Picto « coût » cliquable (réseaux payants) + table de tarifs de la modale */
.cost-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    font-weight: 700;
    padding: 2px 9px 2px 7px;
    border-radius: 999px;
    background: rgba(255, 196, 61, .16);
    color: var(--avert-texte);
    border: 1px solid rgba(255, 196, 61, .5);
    cursor: pointer;
    white-space: nowrap;
    transition: filter var(--ease);
}
.cost-badge:hover { filter: brightness(.96); }
.cost-badge .lc { width: 13px; height: 13px; }

/* Indicateur budget/dépense IA dans l'en-tête (à côté du fournisseur) */
.budget-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11.5px;
    font-weight: 700;
    padding: 3px 10px;
    border-radius: 999px;
    white-space: nowrap;
    border: 1px solid transparent;
    transition: filter var(--ease);
}
.budget-chip[hidden] { display: none; }
.budget-chip:hover { filter: brightness(.97); }

/* Icônes de marque des réseaux (sprite SVG) */
.ni {
    width: 1.05em;
    height: 1.05em;
    display: inline-block;
    vertical-align: -0.16em;
    fill: currentColor;
    flex-shrink: 0;
}
/* Icônes UI (Lucide, sprite SVG) — héritent la couleur du texte */
.lc {
    width: 1.05em;
    height: 1.05em;
    display: inline-block;
    vertical-align: -0.16em;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex-shrink: 0;
}

/* ============================================================ */
/* BOUTONS                                                      */
/* ============================================================ */

/* Bouton Styléo : pilule encre → hover jaune */
.btn {
    /* Couleur du TEXTE portée par une variable, que chaque variante redéfinit. Elle sert deux
       fois : ici, et dans la règle de rattrapage `a.btn:link` plus bas. Sans elle, ce rattrapage
       devrait répéter la couleur de chaque variante, et une variante ajoutée plus tard serait
       oubliée — c'est-à-dire retomberait au bleu souligné du navigateur. */
    --btn-fg: var(--white);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 46px;
    padding: 0 22px;
    background: var(--ink);
    color: var(--btn-fg);
    border: 1px solid var(--ink);
    border-radius: var(--radius-pill);
    font-weight: 800;
    font-size: 12px;
    cursor: pointer;
    transition: transform .2s, background .2s, box-shadow .2s, color .2s, border-color .2s;
    text-decoration: none;
    box-shadow: 0 10px 22px rgba(11, 11, 12, .16);
}

.btn:hover {
    /* L'or de la charte reste CLAIR dans les deux thèmes : le texte posé dessus doit rester
       sombre. « var(--ink) » s'éclaircit avec le thème et s'effacerait sur son propre fond —
       c'est le piège de tout fond qui ne suit pas le thème. */
    color: var(--or-texte);
    background: var(--or-fond);
    border-color: var(--or-trait);
    transform: translateY(-1px);
}

.btn:active { transform: translateY(0); }
.btn:disabled { opacity: .4; cursor: not-allowed; transform: none; }

/*
 * Bouton porté par un LIEN (`<a class="btn">`), et non par un `<button>`.
 *
 * Un lien a des styles de navigateur que `.btn` ne bat pas toujours : dès qu'une feuille place
 * une règle un peu plus spécifique sur les liens d'un conteneur (`.un-panneau a { … }`), ou que
 * le navigateur impose ses couleurs (contraste élevé de Windows, styles utilisateur), le texte
 * repasse en bleu souligné À L'INTÉRIEUR de la pilule. Vu sur la fenêtre « Devis créé », où
 * « Ouvrir le devis » s'affichait en bleu souligné sur fond noir, donc illisible.
 *
 * `a.btn` et rien de plus : une feuille d'auteur bat toujours celle du navigateur, y compris sur
 * `:link` et `:visited`, donc viser ces états ne sert à rien. Ce serait même nuisible : à
 * spécificité (0,2,1), `a.btn:link` passerait devant `.btn:hover` (0,2,0) et figerait la couleur
 * du texte au survol.
 */
a.btn {
    color: var(--btn-fg);
    text-decoration: none;
}

/* Bouton principal : c'est l'apparence par défaut de `.btn`. La classe existe pour que le HTML
   dise son intention, et parce que le JS l'écrivait déjà sans qu'elle soit définie nulle part. */
.btn-primary {
    background: var(--ink);
    border-color: var(--ink);
}

.btn-secondary {
    --btn-fg: var(--ink);
    background: var(--white);
    color: var(--btn-fg);
    border: 1px solid var(--line-strong);
    box-shadow: none;
}

.btn-secondary:hover {
    background: var(--white);
    color: var(--ink);
    border-color: var(--ink);
}

.btn-danger {
    background: var(--danger);
    border-color: var(--danger);
    box-shadow: none;
}

.btn-danger:hover {
    background: #b03239;
    border-color: #b03239;
    color: var(--white);
}

.btn-sm {
    min-height: 38px;
    padding: 0 14px;
    font-size: 11px;
    box-shadow: none;
}

.btn-block {
    width: 100%;
    justify-content: center;
}

/* Bouton icône carré (édition, suppression…) — homogène et discret */
.btn-icon {
    min-height: 38px;
    width: 38px;
    padding: 0;
    flex-shrink: 0;
    border-radius: var(--radius-sm);
    background: var(--white);
    color: var(--ink);
    border: 1px solid var(--line-strong);
    box-shadow: none;
    font-size: 14px;
}

.btn-icon:hover {
    background: var(--white);
    color: var(--ink);
    border-color: var(--ink);
    transform: translateY(-1px);
}

.btn-icon.danger { color: var(--danger); }

.btn-icon.danger:hover {
    background: rgba(197, 59, 69, .08);
    border-color: var(--danger);
    color: var(--danger);
}

/* ============================================================ */
/* CARTES & PANNEAUX                                            */
/* ============================================================ */

.card {
    background: var(--verre);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: var(--gap-lg);
    box-shadow: var(--shadow-sm);
}

.card-header {
    margin-bottom: 1.25rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--line);
}

.card-header h3 {
    margin: 0;
    font-size: 32px;
    line-height: .98;
    letter-spacing: .02em;
    color: var(--ink);
}

/* Sous-titre optionnel sous un titre de carte */
.card-header > p {
    margin: 8px 0 0;
    font-size: 13px;
}

/* Eyebrow / kicker — petit sur-titre orange + barre dégradé (charte Styléo) */
.kicker {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 10px;
    color: var(--accent-text);
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .16em;
    text-transform: uppercase;
}
.kicker::before {
    content: "";
    width: 28px;
    height: 4px;
    border-radius: 9px;
    background: var(--gradient);
}

.card-body {
    margin-bottom: var(--gap-lg);
}

.card-body:last-child { margin-bottom: 0; }

.panel {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: var(--gap-lg);
}

/* ============================================================ */
/* TABLEAU DE DONNÉES                                           */
/* ============================================================ */

table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

thead {
    background: var(--paper);
    border-bottom: 1px solid var(--line-strong);
}

th {
    padding: var(--gap-lg) var(--gap);
    text-align: left;
    font-weight: 600;
    color: var(--ink);
}

td {
    padding: var(--gap) var(--gap-lg);
    border-bottom: 1px solid var(--line);
}

tbody tr:hover {
    background: rgba(var(--teinte-rgb), .025);
}

tbody tr:last-child {
    background: rgba(255, 196, 61, .05);
    font-weight: 600;
}

/* ============================================================ */
/* CHIFFRES CLÉS                                                */
/* ============================================================ */

.stat-value {
    font-size: 18px;
    font-weight: 700;
    color: var(--ink);
}

.stat-label {
    font-size: 12px;
    color: var(--muted);
    margin-top: 2px;
}

/* ============================================================ */
/* BADGES & TAGS                                                */
/* ============================================================ */

.badge {
    display: inline-block;
    padding: 5px 11px;
    background: var(--paper);
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 9px;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.badge.primary {
    background: var(--accent-soft);
    border-color: var(--accent-line);
    color: var(--accent-text);
}

.badge.success {
    background: rgba(45, 165, 111, .07);
    border-color: rgba(45, 165, 111, .25);
    color: var(--green);
}

.badge.warning {
    background: rgba(255, 196, 61, .14);
    border-color: rgba(255, 196, 61, .5);
    color: var(--avert-texte);
}

.tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    transition: border-color .2s, transform .2s;
}

.tag:hover { border-color: var(--line-strong); transform: translateY(-1px); }

.tag.selected {
    background: var(--ink);
    color: var(--white);
    border-color: var(--ink);
}

/* ============================================================ */
/* ALERTES & MESSAGES                                           */
/* ============================================================ */

/*
 * Alerte : une teinte de fond, un cadre discret, une encre. Rien d'autre.
 *
 * Ni barre verticale colorée à gauche, ni filet coloré en haut : ces liserés sont la signature
 * visuelle des interfaces générées (charte Styléo). L'état se lit à la teinte du fond et à la
 * couleur du texte. Le filet supérieur de 3 px a été retiré le 2026-09-23.
 */
.alert {
    display: flex;
    gap: var(--gap);
    align-items: flex-start;
    margin-bottom: var(--gap-lg);
    padding: 14px 18px 16px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    --voile: transparent;
    background: linear-gradient(var(--voile), var(--voile)), var(--white);
}

.alert-icon {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: bold;
}

.alert-content {
    flex: 1;
}

/* Info : neutre. La teinte d'accent (orangée) se confondait avec l'erreur une fois les filets
   retirés ; une information n'a pas à alarmer. */
.alert.info {
    --voile: rgba(var(--teinte-rgb), .05);
    border-color: var(--line);
    color: var(--ink-2);
}

.alert.success {
    --voile: rgba(45, 165, 111, .14);
    border-color: rgba(45, 165, 111, .24);
    color: var(--succes-texte);
}

.alert.warning {
    --voile: rgba(255, 196, 61, .20);
    border-color: rgba(255, 196, 61, .38);
    color: var(--avert-texte);
}

.alert.error {
    --voile: rgba(197, 59, 69, .14);
    border-color: rgba(197, 59, 69, .26);
    color: var(--danger-texte);
}

/* ============================================================ */
/* TYPOGRAPHIE                                                  */
/* ============================================================ */

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    /* New Amsterdam n'a que des capitales : ses minuscules accentuées portent un
       accent illisible (« à » se lit « ä »). En majuscules, le glyphe est le bon,
       et rien d'autre ne change. Toute règle en --font-display le fait. */
    text-transform: uppercase;
    font-weight: 400;
    margin: 0 0 var(--gap-lg) 0;
    letter-spacing: .04em;
}

h1 {
    font-size: 32px;
    background: var(--gradient);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

h2 {
    font-size: 26px;
    color: var(--ink);
}

h3 {
    font-size: 20px;
    color: var(--ink);
}

p {
    margin: 0 0 var(--gap-lg) 0;
    line-height: 1.6;
}

strong {
    font-weight: 600;
    color: var(--ink);
}

/* ============================================================ */
/* UTILITAIRES                                                  */
/* ============================================================ */

/* État vide cohérent (listes sans contenu) */

.text-muted { color: var(--muted); }

.mt { margin-top: var(--gap); }

.flex { display: flex; }

.grid { display: grid; }

.hidden { display: none; }

/* ============================================================ */
/* TOASTS (empilés)                                             */
/* ============================================================ */

#toast-container {
    position: fixed;
    bottom: calc(25px + env(safe-area-inset-bottom, 0px));
    right: 25px;
    z-index: 99999;
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: 420px;
}

/*
 * Toast Styléo : fond encre, rayon et ombre de l'échelle commune, et une PASTILLE
 * d'icône pour dire le type — là où une barre latérale de 4px ne disait rien à qui ne
 * connaît pas le code couleur. Les teintes viennent toutes des tokens de la charte.
 */
.toast {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 12px 11px 13px;
    color: var(--white);
    background: var(--ink);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    animation: toastIn .22s cubic-bezier(.2, .8, .3, 1);
}
.toast.out { animation: toastOut .18s ease forwards; }

.toast-ico {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--sur-accent);
}
.toast-ico .lc { width: 15px; height: 15px; }
.toast.success .toast-ico { background: var(--green); }
.toast.error   .toast-ico { background: var(--danger); color: #fff; }
/* L'or est clair : le picto y passe en encre, comme sur les boutons jaunes de la charte. */
.toast.warning .toast-ico { background: var(--yellow); color: #0b0b0c; }

.toast-text {
    flex: 1;
    min-width: 0;
    font-size: 13.5px;
    line-height: 1.45;
}

/* Bandeau d'envoi différé : l'objet sur la première ligne, le détail déplié au clic. */
.toast-cliquable { cursor: pointer; border-radius: 6px; }
.toast-cliquable:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.toast-principal { display: block; overflow-wrap: anywhere; }
.toast-detail { display: block; margin-top: 5px; font-size: 12.5px; opacity: .8; white-space: pre-line; overflow-wrap: anywhere; }

/* Action de rattrapage (« Annuler ») : une pilule, comme tous les boutons de la charte. */
.toast-action {
    flex: 0 0 auto;
    padding: 6px 14px;
    font: inherit;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--white);
    background: none;
    border: 1px solid rgba(255, 255, 255, .3);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background var(--ease), border-color var(--ease), color var(--ease);
}
.toast-action:hover { background: var(--white); border-color: var(--white); color: var(--ink); }

.toast-close {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    color: rgba(255, 255, 255, .55);
    background: none;
    border: 0;
    border-radius: 50%;
    cursor: pointer;
    transition: background var(--ease), color var(--ease);
}
.toast-close:hover { background: rgba(255, 255, 255, .14); color: var(--white); }
.toast-close .lc { width: 13px; height: 13px; }

/* Sur téléphone, le toast tient toute la largeur : viser une pilule de 390px au pouce
   n'a pas de sens, et un message tronqué ne rattrape rien. */
@media (max-width: 560px) {
    #toast-container {
        left: 12px;
        right: 12px;
        bottom: calc(12px + env(safe-area-inset-bottom, 0px));
        max-width: none;
    }
}

/*
 * Témoin d'activité réseau : filet en haut de la fenêtre, allumé tant qu'un appel dure.
 * Posé au-dessus de tout, jamais cliquable, et volontairement fin — il informe sans
 * s'imposer, et sans figer l'interface derrière un voile.
 */
#net-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: 100000;
    overflow: hidden;
    pointer-events: none;
}
#net-progress::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 40%;
    /* Le dégradé signature de la charte : un des rares moments où il a sa place. */
    background: var(--gradient);
    border-radius: 0 3px 3px 0;
    animation: netProgress 1.1s ease-in-out infinite;
}
@keyframes netProgress {
    from { transform: translateX(-100%); }
    to   { transform: translateX(350%); }
}
/* Mouvement réduit : le filet reste, immobile — la présence suffit à dire « ça travaille ». */
@media (prefers-reduced-motion: reduce) {
    #net-progress::before { animation: none; width: 100%; opacity: .55; }
}

/* Bouton dont l'action est en cours : verrouillé, et qui le dit. */
.is-busy {
    opacity: .6;
    cursor: progress;
}

/*
 * Étiquette d'adresse du lien survolé — la barre d'état que le navigateur n'affiche plus
 * quand l'application tourne en fenêtre installée (PWA). Posée en bas à GAUCHE, là où on
 * l'attend, et hors de portée des toasts qui vivent à droite.
 */
#link-status {
    position: fixed;
    left: 0;
    bottom: 0;
    z-index: 99998;
    max-width: min(70vw, 640px);
    padding: 4px 12px 4px 10px;
    font: 12px/1.5 var(--font-body);
    color: rgba(255, 255, 255, .62);
    background: var(--ink);
    border-radius: 0 var(--radius-sm) 0 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none; /* jamais entre le pointeur et ce qu'il vise */
}
/* Le domaine ressort : c'est lui qui dit où l'on va, le chemin est du détail. */
#link-status strong { color: var(--white); font-weight: 700; }

@keyframes toastIn {
    from { opacity: 0; transform: translateY(10px) scale(.98); }
    to   { opacity: 1; transform: none; }
}
@keyframes toastOut {
    to { opacity: 0; transform: translateY(6px) scale(.98); }
}
@media (prefers-reduced-motion: reduce) {
    .toast, .toast.out { animation: none; }
}

/* ============================================================ */
/* GRILLE DE CALENDRIER                                         */
/* ============================================================ */

.cal-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 6px;
}
.cal-dow {
    text-align: center;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted);
    padding: 4px 0;
}

/* ============================================================ */
/* EN-TÊTE D’APERÇU                                             */
/* ============================================================ */

.preview-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px;
    border-bottom: 1px solid var(--line);
}

/* ============================================================ */
/* MODALES                                                      */
/* ============================================================ */

/* Indicateur de chargement : anneau tournant au dégradé de marque + libellé.
   Bloc (.loader-box) pour les zones de contenu ; .loader-ring.sm pour l'intérieur d'un bouton. */

@keyframes loader-spin { to { transform: rotate(1turn); } }

.modal-body { padding: var(--gap-lg); overflow-y: auto; }

/* Aperçu plein écran (lightbox) — clic sur une vignette d'image.
   Au-dessus des modales (.modal-overlay à 9999) : une vignette peut être ouverte depuis une modale. */

/* Page « Comment ça marche » : cartes de principes empilées */
/* Sans max-width : l'aide occupe la largeur de la vue, comme toutes les autres. Bornée à 860 px
   elle était la seule à se resserrer, ce qui la faisait paraître mal réglée plutôt qu'aérée. */
.help-page { display: flex; flex-direction: column; gap: var(--gap); }
.help-page h3 { margin: 0 0 10px; }
.help-page p { margin: 0 0 10px; line-height: 1.65; }
.help-page p:last-child { margin-bottom: 0; }

/* ============================================================ */
/* ÉCRAN DE CONNEXION (gate Odoo) + chip utilisateur           */
/* ============================================================ */

.login-screen {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--gap-lg);
}
.login-card {
    width: 100%;
    max-width: 440px;
    animation: viewIn .3s ease;
}
.login-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: var(--gap-lg);
}
.login-brand img { height: 40px; width: auto; object-fit: contain; mix-blend-mode: multiply; }
.login-brand strong {
    font-family: var(--font-display);
    text-transform: uppercase;
    font-size: 24px;
    font-weight: 400;
    letter-spacing: .04em;
}

.login-remember {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 18px;
    font-size: 13px;
    color: var(--ink-2);
    cursor: pointer;
    user-select: none;
}
.login-remember input {
    width: 16px;
    height: 16px;
    accent-color: var(--accent);
    cursor: pointer;
}
/* Aide sous la case « rester connecté » : elle reprend la marge basse de la case. */
.login-remember:has(+ .login-remember-help) { margin-bottom: 6px; }
.login-remember-help {
    font-size: 12px;
    color: var(--muted);
    margin: 0 0 18px;
}

/* Réglages du serveur d'un compte IMAP : repliés par défaut, parce que la reconnaissance
   automatique suffit dans la plupart des cas et que les afficher d'emblée ferait renoncer. */
.login-avance {
    margin: 0 0 18px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
}
.login-avance > summary {
    cursor: pointer;
    font-size: 13px;
    font-weight: 700;
    color: var(--ink-2);
    list-style: none;
}
/* Le marqueur par défaut du navigateur diffère d'un moteur à l'autre : on pose le nôtre. */
.login-avance > summary::-webkit-details-marker { display: none; }
/* Une FORME tracée, pas un glyphe : le dessin d'un « ▸ » dépend de la police installée, il se lit
   à voix haute comme « triangle noir pointant vers la droite », et il ne suit pas toujours la
   couleur du texte. Un triangle en bordures suit `currentColor` et pivote au lieu de changer de
   caractère — l'état du <details> étant déjà annoncé par le navigateur. */
.login-avance > summary::before {
    content: "";
    display: inline-block;
    width: 0;
    height: 0;
    margin-right: 6px;
    vertical-align: middle;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    transition: transform .15s;
}
.login-avance[open] > summary::before { transform: rotate(90deg); }
.login-avance .form-group { margin: 12px 0 0; }

/* Accès sur invitation ([MAIL 35]) : la carte de demande remplace celle de connexion, et le lien
   vers la présentation reste sous l'une comme sous l'autre. */
.login-screen { flex-direction: column; gap: var(--gap); }
.login-demander, .login-retour { margin-bottom: 10px; }
.login-card h3 { margin: 0 0 6px; }
.login-card > .text-muted { font-size: 13px; margin: 0 0 20px; }
.login-card textarea.form-input { resize: vertical; min-height: 72px; }
.login-piege { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.login-decouvrir { margin: 0; font-size: 13px; }
.login-decouvrir a { color: var(--ink-2); }

.user-chip {
    max-width: 180px;
    padding: 4px 10px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--white);
    color: var(--ink);
    font-size: 12px;
    font-weight: 700;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* La puce est devenue un bouton (sélecteur de boîte) : elle doit rester identique à l'œil,
       d'où la neutralisation de ce qu'un bouton apporte de son côté. */
    font-family: inherit;
    line-height: 1.4;
    cursor: pointer;
}

/* ---- Boîtes ouvertes : bascule depuis l'en-tête ---- */

.boites { position: relative; }
/* Chevron discret, seulement quand il y a réellement de quoi choisir. */
.boites.multi > .user-chip::after {
    content: "";
    display: inline-block;
    width: 0;
    height: 0;
    margin-left: 6px;
    vertical-align: middle;
    border-top: 5px solid currentColor;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
}
.boites-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 1000;
    min-width: 260px;
    padding: 6px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--white);
    box-shadow: var(--shadow);
}
.boites-menu[hidden] { display: none; }
.boite-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--ink);
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}
.boite-item:hover { background: var(--paper); }
.boite-item.active { font-weight: 700; }
/* L'adresse est un bouton (elle bascule vers sa boîte), mais elle doit se LIRE comme une ligne de
   liste : sans les bordures ni le fond que les boutons du projet portent par défaut, qui la
   feraient passer pour un champ de saisie. */
.boite-mail {
    flex: 1;
    min-width: 0;
    border: 0;
    background: none;
    padding: 0;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.boite-mail:hover { text-decoration: underline; }
/* Boîte active : marquée par un mot, pas par un pictogramme seul. */
.boite-actuelle { font-size: 11px; color: var(--muted); }
.boite-fermer {
    flex: 0 0 auto;
    border: 0;
    background: none;
    padding: 2px 6px;
    color: var(--muted);
    font: inherit;
    font-size: 11px;
    text-decoration: underline;
    cursor: pointer;
}
.boite-fermer:hover { color: var(--danger); }
.boites-sep {
    height: 1px;
    margin: 6px 4px;
    background: var(--line);
}
.boite-ajouter {
    display: block;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--ink);
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
}
.boite-ajouter:hover { background: var(--paper); }

/*
 * Les mêmes boîtes, dans le tiroir de navigation. Masqué tant que l'en-tête a la place de
 * porter le sélecteur : deux commandes pour une seule action, visibles en même temps, se
 * concurrenceraient. Le palier est celui où l'en-tête passe sur une ligne.
 */
.sidebar-boites { display: none; }
.sidebar-boites .boite-item { padding: 6px 10px; }
.sidebar-boites .boite-ajouter { padding: 6px 10px; font-size: 12.5px; }

/* ============================================================ */
/* RESPONSIVE                                                   */
/* ============================================================ */

@media (max-width: 760px) {
    .app-container {
        grid-template-columns: 1fr;
    }

    /* Sidebar en TIROIR : ouverte par le bouton hamburger, fermée au clic sur le fond ou à la navigation */
    .app-sidebar {
        position: fixed;
        top: 0; bottom: 0; left: 0;
        /* Hauteur EXPLICITE : `auto` ne s'étirait pas jusqu'en bas (le tiroir se calait sur la
           hauteur de son contenu), laissant une bande vide sous le menu.
           `dvh` et non `vh` : sur mobile, la barre d'adresse se rétracte au défilement et `vh`
           reste figé sur la hauteur d'origine — le tiroir dépasserait alors sous l'écran. */
        height: 100vh;
        height: 100dvh;
        width: 280px;
        z-index: 6000;
        transform: translateX(-100%);
        transition: transform .22s ease;
        box-shadow: none;
    }
    body.sidebar-open .app-sidebar {
        transform: none;
        box-shadow: 0 0 40px rgba(11, 11, 12, .25);
    }
    .sidebar-backdrop {
        position: fixed; inset: 0;
        z-index: 5999;
        background: rgba(var(--teinte-rgb), .45);
    }
    body.sidebar-open .sidebar-backdrop { display: block; }

    .nav-burger { display: inline-flex; }
    /* Le repli laisse la main au burger : deux commandes pour ouvrir le même menu, dont une
       sans effet, se disputeraient l'en-tête d'un écran qui n'a déjà plus de place. */
    .nav-repli { display: none; }

    /*
     * TIROIR : une seule métrique verticale, pour que le menu tienne sans défiler.
     *
     * Il était bâti pour un grand écran — 32 px entre rubriques, 32 px de retrait dans chaque
     * entrée, une marque à 32 px du menu — et sur un téléphone la dernière rubrique passait
     * sous le pli. Pire, « Comment ça marche » revenait à la ligne et cette entrée-là devenait
     * deux fois plus haute que ses voisines : c'est ce qui donnait l'impression d'un menu mal
     * réglé, plus encore que la hauteur totale.
     *
     * Ces règles doivent venir APRÈS les déclarations qu'elles remplacent : à spécificité
     * égale, c'est l'ordre du fichier qui tranche, et le premier bloc mobile les précède.
     */
    /* Le jeton, et non `padding-top`/`padding-bottom` : le pied s'en sert en négatif pour
       aller chercher le bas de la barre. Deux valeurs séparées, c'est un pied qui déborde. */
    .app-sidebar { --sidebar-retrait-y: 14px; }
    /* La marque a besoin de respirer un peu plus que deux rubriques entre elles : collée au
       menu, elle en devenait la première entrée. Un cran au-dessus du rythme des groupes. */
    .sidebar-tete { margin-bottom: 22px; }
    .brand img { width: 84px; height: auto; }
    /* Le rythme reste porté par le titre, il se resserre seulement. Un `gap` sur le menu
       rendrait « Boîtes ouvertes », qui vit hors de lui, différent de tous les autres. */
    .nav-section-title { margin: 14px 0 2px; }
    /* Les entrées gardent 40 px : c'est LA cible que le pouce vise, et la rogner pour gagner
       quelques pixels ferait manquer le menu plutôt qu'il ne rentrerait. Tout le reste cède. */
    .nav-link { padding: 9px var(--gap); }
    .sidebar-boites .boite-item,
    .sidebar-boites .boite-ajouter { padding: 4px var(--gap); }
    .sidebar-pied { padding-top: 6px; padding-bottom: 6px; }

    /* En-tête sur DEUX lignes : titre (+ burger) puis contrôles essentiels.
       Le fournisseur, les logos réseaux et l'email passent à la trappe (accessibles ailleurs). */
    .app-header {
        flex-wrap: wrap;
        row-gap: 8px;
        padding: 10px var(--gap);
        min-height: 0;
    }
    .header-title { flex: 1 1 100%; }
    .app-header h2 { font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .header-controls { flex: 1 1 100%; gap: 8px; }

    /* La bascule de boîte quitte l'en-tête, faute de place, et reparaît dans le tiroir.
       C'est le conteneur entier qui part : n'en masquer que la puce laissait un élément
       vide dans la barre, et le menu déroulant restait accroché à un bouton invisible. */
    .boites { display: none; }
    .sidebar-boites { display: block; }

    .panel {
        grid-template-columns: 1fr;
    }

    h1 {
        font-size: 24px;
    }

    .app-content {
        padding: var(--gap-lg) var(--gap);
    }
}

/* Barres verticales */

.bar-fill { width: 100%; min-height: 2px; background: var(--accent, #f06a25); border-radius: 4px 4px 0 0; transition: height var(--ease); }

