/* BARE CSS — Boring, Accessible, Restrained, Equitable. */
/* A minimal CSS framework. */

/* ============================================
   1. ROOT & CUSTOM PROPERTIES
   ============================================ */

:root {
  --bare-text: #1a1a1a;
  --bare-bg: #fff;
  --bare-link: #0000ee;
  --bare-border: #ddd;
  --bare-muted: #666;
  --bare-mark-bg: #fff3a0;
  --bare-mark-text: inherit;
  --bare-btn-bg: #efefef;
  --bare-card-header-bg: #f8f8f8;
  --bare-focus: #888;
  --bare-ok: #145214;
  --bare-warning: #5c4500;
  --bare-danger: #7a1010;
  --bare-ok-bg: #e6f4e6;
  --bare-warning-bg: #fff8e0;
  --bare-danger-bg: #fde8e8;
  --bare-gap-s: 0.3em;
  --bare-gap: 1em;
  --bare-gap-l: 2em;
  /* Hauteur approximative de la barre <nav> figée en haut (seule sticky) :
     décalage sous lequel un en-tête de tableau .sticky-head vient se fixer. */
  --bare-nav-h: 3em;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bare-text: #e0e0e0;
    --bare-bg: #1a1a1a;
    --bare-link: #7db3fa;
    --bare-border: #444;
    --bare-muted: #aaa;
    --bare-mark-bg: #ffdd00;
    --bare-mark-text: #1a1a1a;
    --bare-btn-bg: #333;
    --bare-card-header-bg: #222;
    --bare-ok: #50dc50;
    --bare-warning: #e4c000;
    --bare-danger: #f09898;
    --bare-ok-bg: #1a3a1a;
    --bare-warning-bg: #3a3000;
    --bare-danger-bg: #3a1a1a;
    --bare-focus: #888;
  }
}

:root[data-theme="dark"] {
  --bare-text: #e0e0e0;
  --bare-bg: #1a1a1a;
  --bare-link: #7db3fa;
  --bare-border: #444;
  --bare-muted: #aaa;
  --bare-mark-bg: #ffdd00;
  --bare-mark-text: #1a1a1a;
  --bare-btn-bg: #333;
  --bare-card-header-bg: #222;
  --bare-ok: #50dc50;
  --bare-warning: #e4c000;
  --bare-danger: #f09898;
  --bare-ok-bg: #1a3a1a;
  --bare-warning-bg: #3a3000;
  --bare-danger-bg: #3a1a1a;
  --bare-focus: #888;
}

/* ============================================
   1b. THÈMES TERMINAL
   ============================================
   Les palettes de terminaux/éditeurs les plus emblématiques (Solarized,
   Monokai, Dracula, Nord, Gruvbox, les thèmes Modus, etc.). Chaque thème ne fait
   que surcharger les mêmes variables `--bare-*` que `:root` ci-dessus : tout le
   reste de la feuille (corps, nav, tables, cartes, champs, alertes, badges…) se
   recolore automatiquement. Le catalogue (identité + libellé) est dans
   `conformite/themes.py` ; le slug ci-dessous DOIT y correspondre. Les boutons
   d'action sémantiques (`.ok`/`.danger`/`.special`, vert/rouge/bleu) restent
   volontairement constants d'un thème à l'autre — l'affordance ne change pas. */

/* ---- Clairs ---- */

/* Solarized est délibérément peu contrasté (surtout en clair) ; on garde les
   teintes mais on descend le texte/atténué et on renforce bordures + accents
   pour tenir le contraste AA (texte ≥ 4.5:1) au lieu du ~2.4:1 canonique. */
:root[data-theme="solarized-light"] {
  --bare-text: #3f5157; --bare-bg: #fdf6e3; --bare-link: #1a6cad; --bare-border: #d5cbae; --bare-muted: #5e7278;
  --bare-mark-bg: #f1de85; --bare-mark-text: #3f5157;
  --bare-btn-bg: #ebe4ce; --bare-card-header-bg: #efe8d2; --bare-focus: #657b83;
  --bare-ok: #536510; --bare-warning: #805900; --bare-danger: #b0201d;
  --bare-ok-bg: #e6ebc7; --bare-warning-bg: #f4e7bd; --bare-danger-bg: #f7d6cd;
}

:root[data-theme="gruvbox-light"] {
  --bare-text: #3c3836; --bare-bg: #fbf1c7; --bare-link: #076678; --bare-border: #e6d8ab; --bare-muted: #6d6055;
  --bare-mark-bg: #fbe5a0; --bare-mark-text: #3c3836;
  --bare-btn-bg: #ebdbb2; --bare-card-header-bg: #eeddb3; --bare-focus: #a89984;
  --bare-ok: #5c5809; --bare-warning: #7d5300; --bare-danger: #9d0006;
  --bare-ok-bg: #e9e6ba; --bare-warning-bg: #f3e4b8; --bare-danger-bg: #f2d9c9;
}

:root[data-theme="modus-operandi"] {
  --bare-text: #000000; --bare-bg: #ffffff; --bare-link: #0031a9; --bare-border: #d7d7d7; --bare-muted: #595959;
  --bare-mark-bg: #f5e6a0; --bare-mark-text: #000000;
  --bare-btn-bg: #eeeeee; --bare-card-header-bg: #f4f4f4; --bare-focus: #595959;
  --bare-ok: #005e00; --bare-warning: #6f5500; --bare-danger: #a60000;
  --bare-ok-bg: #dcf0dc; --bare-warning-bg: #f0e8c0; --bare-danger-bg: #f5d5d0;
}

/* Palette « GitHub clair » (GitHub Primer, thème par défaut du site GitHub). */
:root[data-theme="github-light"] {
  --bare-text: #1f2328; --bare-bg: #ffffff; --bare-link: #0969da; --bare-border: #d0d7de; --bare-muted: #59636e;
  --bare-mark-bg: #fff8c5; --bare-mark-text: #1f2328;
  --bare-btn-bg: #f6f8fa; --bare-card-header-bg: #f6f8fa; --bare-focus: #0969da;
  --bare-ok: #1a7f37; --bare-warning: #9a6700; --bare-danger: #cf222e;
  --bare-ok-bg: #dafbe1; --bare-warning-bg: #fff8c5; --bare-danger-bg: #ffebe9;
}

/* Catppuccin Latte — la variante claire de Catppuccin (pendant de « Mocha »).
   Vert/jaune/rouge sémantiques assombris et fonds d'alerte éclaircis pour tenir
   l'AA (texte ≥ 4.5:1) que la palette canonique ne garantit pas en clair. */
:root[data-theme="catppuccin-latte"] {
  --bare-text: #4c4f69; --bare-bg: #eff1f5; --bare-link: #1a56c9; --bare-border: #bcc0cc; --bare-muted: #5c5f77;
  --bare-mark-bg: #f2dfa3; --bare-mark-text: #4c4f69;
  --bare-btn-bg: #e6e9ef; --bare-card-header-bg: #e6e9ef; --bare-focus: #7c7f93;
  --bare-ok: #2c761d; --bare-warning: #855f00; --bare-danger: #c11d34;
  --bare-ok-bg: #e4f2dc; --bare-warning-bg: #f7edcf; --bare-danger-bg: #f9e1e4;
}

/* One Light (Atom / One) — pendant clair de « One Dark ». */
:root[data-theme="one-light"] {
  --bare-text: #383a42; --bare-bg: #fafafa; --bare-link: #2f5fd0; --bare-border: #d4d4d6; --bare-muted: #63666f;
  --bare-mark-bg: #f0e0a0; --bare-mark-text: #383a42;
  --bare-btn-bg: #eaeaeb; --bare-card-header-bg: #eaeaeb; --bare-focus: #7c7f88;
  --bare-ok: #367634; --bare-warning: #855e00; --bare-danger: #bf2f24;
  --bare-ok-bg: #e4f3df; --bare-warning-bg: #f6edd0; --bare-danger-bg: #f9e2df;
}

/* Tokyo Night Day — variante claire de « Tokyo Night ». */
:root[data-theme="tokyo-night-day"] {
  --bare-text: #343b58; --bare-bg: #e1e2e7; --bare-link: #1c5bc9; --bare-border: #c0c4d6; --bare-muted: #565f89;
  --bare-mark-bg: #d8c58a; --bare-mark-text: #343b58;
  --bare-btn-bg: #d6d8e0; --bare-card-header-bg: #d6d8e0; --bare-focus: #6a6f8e;
  --bare-ok: #4f6d1f; --bare-warning: #8a5a15; --bare-danger: #b21545;
  --bare-ok-bg: #e2ecd2; --bare-warning-bg: #f0e6cd; --bare-danger-bg: #f2dde2;
}

/* Tomorrow — la base claire de la famille « Tomorrow Night ». */
:root[data-theme="tomorrow"] {
  --bare-text: #4d4d4c; --bare-bg: #ffffff; --bare-link: #3b5ea8; --bare-border: #d6d6d6; --bare-muted: #6a6a68;
  --bare-mark-bg: #f0dfa0; --bare-mark-text: #4d4d4c;
  --bare-btn-bg: #efefef; --bare-card-header-bg: #efefef; --bare-focus: #8e908c;
  --bare-ok: #5c6f00; --bare-warning: #846700; --bare-danger: #c82829;
  --bare-ok-bg: #edf1d3; --bare-warning-bg: #f9f2da; --bare-danger-bg: #fae3e3;
}

/* Alucard — le thème clair officiel de la famille « Dracula ». */
:root[data-theme="alucard"] {
  --bare-text: #1f1f1f; --bare-bg: #fffbeb; --bare-link: #036a96; --bare-border: #ded8c2; --bare-muted: #6c664b;
  --bare-mark-bg: #f2e2a0; --bare-mark-text: #1f1f1f;
  --bare-btn-bg: #f3edd8; --bare-card-header-bg: #f3edd8; --bare-focus: #6c664b;
  --bare-ok: #14710a; --bare-warning: #a34d14; --bare-danger: #c23222;
  --bare-ok-bg: #e2f0d2; --bare-warning-bg: #f6e8cc; --bare-danger-bg: #fae6dd;
}

/* ---- Sombres ---- */

:root[data-theme="solarized-dark"] {
  --bare-text: #adbcbc; --bare-bg: #002b36; --bare-link: #56aae0; --bare-border: #14495a; --bare-muted: #8098a0;
  --bare-mark-bg: #cb9a00; --bare-mark-text: #002b36;
  --bare-btn-bg: #073e4b; --bare-card-header-bg: #0a4150; --bare-focus: #93a1a1;
  --bare-ok: #b6d100; --bare-warning: #e0ac00; --bare-danger: #fb544c;
  --bare-ok-bg: #0d3f27; --bare-warning-bg: #38340b; --bare-danger-bg: #3a1712;
}

:root[data-theme="monokai"] {
  --bare-text: #f8f8f2; --bare-bg: #272822; --bare-link: #66d9ef; --bare-border: #49483e; --bare-muted: #a6a28c;
  --bare-mark-bg: #e6db74; --bare-mark-text: #272822;
  --bare-btn-bg: #3e3d32; --bare-card-header-bg: #34352c; --bare-focus: #75715e;
  --bare-ok: #a6e22e; --bare-warning: #e6db74; --bare-danger: #ff6188;
  --bare-ok-bg: #33401a; --bare-warning-bg: #3d3a1e; --bare-danger-bg: #2b0f18;
}

:root[data-theme="dracula"] {
  --bare-text: #f8f8f2; --bare-bg: #282a36; --bare-link: #8be9fd; --bare-border: #44475a; --bare-muted: #8a92bf;
  --bare-mark-bg: #f1fa8c; --bare-mark-text: #282a36;
  --bare-btn-bg: #3b3d4f; --bare-card-header-bg: #343746; --bare-focus: #6272a4;
  --bare-ok: #50fa7b; --bare-warning: #f1fa8c; --bare-danger: #ff5555;
  --bare-ok-bg: #21372b; --bare-warning-bg: #3a3a1f; --bare-danger-bg: #3d2130;
}

:root[data-theme="nord"] {
  --bare-text: #d8dee9; --bare-bg: #2e3440; --bare-link: #88c0d0; --bare-border: #434c5e; --bare-muted: #9aa4b8;
  --bare-mark-bg: #ebcb8b; --bare-mark-text: #2e3440;
  --bare-btn-bg: #3b4252; --bare-card-header-bg: #39404e; --bare-focus: #4c566a;
  --bare-ok: #a3be8c; --bare-warning: #ebcb8b; --bare-danger: #e0868d;
  --bare-ok-bg: #333d34; --bare-warning-bg: #3c3a2c; --bare-danger-bg: #322528;
}

:root[data-theme="gruvbox-dark"] {
  --bare-text: #ebdbb2; --bare-bg: #282828; --bare-link: #83a598; --bare-border: #3c3836; --bare-muted: #a89984;
  --bare-mark-bg: #fabd2f; --bare-mark-text: #282828;
  --bare-btn-bg: #3c3836; --bare-card-header-bg: #32302f; --bare-focus: #665c54;
  --bare-ok: #b8bb26; --bare-warning: #fabd2f; --bare-danger: #fb6152;
  --bare-ok-bg: #33361c; --bare-warning-bg: #3b3520; --bare-danger-bg: #2c1712;
}

:root[data-theme="modus-vivendi"] {
  --bare-text: #ffffff; --bare-bg: #000000; --bare-link: #2fafff; --bare-border: #303030; --bare-muted: #989898;
  --bare-mark-bg: #b0d000; --bare-mark-text: #000000;
  --bare-btn-bg: #1e1e1e; --bare-card-header-bg: #191919; --bare-focus: #989898;
  --bare-ok: #44bc44; --bare-warning: #d0bc00; --bare-danger: #ff5f59;
  --bare-ok-bg: #00220a; --bare-warning-bg: #241f00; --bare-danger-bg: #2a1210;
}

:root[data-theme="tomorrow-night"] {
  --bare-text: #c5c8c6; --bare-bg: #1d1f21; --bare-link: #81a2be; --bare-border: #373b41; --bare-muted: #969896;
  --bare-mark-bg: #f0c674; --bare-mark-text: #1d1f21;
  --bare-btn-bg: #282a2e; --bare-card-header-bg: #25282c; --bare-focus: #4b5056;
  --bare-ok: #b5bd68; --bare-warning: #f0c674; --bare-danger: #db8383;
  --bare-ok-bg: #2b3120; --bare-warning-bg: #332f1e; --bare-danger-bg: #331f1f;
}

:root[data-theme="one-dark"] {
  --bare-text: #abb2bf; --bare-bg: #282c34; --bare-link: #61afef; --bare-border: #3b4048; --bare-muted: #969db0;
  --bare-mark-bg: #e5c07b; --bare-mark-text: #282c34;
  --bare-btn-bg: #333842; --bare-card-header-bg: #2d323b; --bare-focus: #5c6370;
  --bare-ok: #98c379; --bare-warning: #e5c07b; --bare-danger: #e88b91;
  --bare-ok-bg: #2c3626; --bare-warning-bg: #353120; --bare-danger-bg: #372428;
}

:root[data-theme="zenburn"] {
  --bare-text: #dcdccc; --bare-bg: #3f3f3f; --bare-link: #8cd0d3; --bare-border: #5f5f5f; --bare-muted: #b7b7a5;
  --bare-mark-bg: #f0dfaf; --bare-mark-text: #3f3f3f;
  --bare-btn-bg: #4f4f4f; --bare-card-header-bg: #4a4a4a; --bare-focus: #7f7f7f;
  --bare-ok: #a4c6a4; --bare-warning: #f0dfaf; --bare-danger: #dca3a3;
  --bare-ok-bg: #2e3a2e; --bare-warning-bg: #4f4a3a; --bare-danger-bg: #503f3f;
}

:root[data-theme="tokyo-night"] {
  --bare-text: #a9b1d6; --bare-bg: #1a1b26; --bare-link: #7aa2f7; --bare-border: #2a2e42; --bare-muted: #8b90b3;
  --bare-mark-bg: #e0af68; --bare-mark-text: #1a1b26;
  --bare-btn-bg: #24283b; --bare-card-header-bg: #1f2233; --bare-focus: #565f89;
  --bare-ok: #9ece6a; --bare-warning: #e0af68; --bare-danger: #f7768e;
  --bare-ok-bg: #22301e; --bare-warning-bg: #312a1c; --bare-danger-bg: #331f26;
}

:root[data-theme="catppuccin-mocha"] {
  --bare-text: #cdd6f4; --bare-bg: #1e1e2e; --bare-link: #89b4fa; --bare-border: #313244; --bare-muted: #a6adc8;
  --bare-mark-bg: #f9e2af; --bare-mark-text: #1e1e2e;
  --bare-btn-bg: #313244; --bare-card-header-bg: #282839; --bare-focus: #6c7086;
  --bare-ok: #a6e3a1; --bare-warning: #f9e2af; --bare-danger: #f38ba8;
  --bare-ok-bg: #26331f; --bare-warning-bg: #332f1f; --bare-danger-bg: #342029;
}

/* ============================================
   2. BASE
   ============================================ */

*, *::before, *::after {
  box-sizing: border-box;
}

body {
  margin: 0 auto;
  max-width: 60em;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  line-height: 1.5;
  padding: 0 1em;
  font-size: 16px;
  color: var(--bare-text);
  background: var(--bare-bg);
  /* Sticky footer : le contenu pousse le footer au bas de la fenêtre
     même quand la page est trop courte pour la remplir. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main {
  flex: 1 0 auto;
}

footer {
  flex-shrink: 0;
  /* Le body ne porte plus de padding bas : le footer touche le bas de la
     fenêtre (sticky footer). Un léger retrait décolle juste le texte du bord. */
  padding-bottom: var(--bare-gap);
  /* Discret : pas de filet, petit texte, une seule rangée (avis + thème) —
     mais un large dégagement au-dessus, pour ne pas coller au contenu. */
  margin-top: calc(4 * var(--bare-gap-l));
  font-size: .8rem;
}

/* Skip to content — accessibility */
a[href="#content"] {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: var(--bare-gap-s) var(--bare-gap);
  background: var(--bare-text);
  color: var(--bare-bg);
  z-index: 1000;
}

a[href="#content"]:focus {
  left: 0;
}

/* ============================================
   2b. GRID
   ============================================ */

.grid {
  display: grid;
  gap: var(--bare-gap);
  grid-template-columns: repeat(auto-fit, minmax(min(12em, 100%), 1fr));
}

.grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.grid.cols-4 { grid-template-columns: repeat(4, 1fr); }

.grid .span-2 { grid-column: span 2; }
.grid .span-3 { grid-column: span 3; }
.grid .span-4 { grid-column: span 4; }

@media (max-width: 40em) {
  .grid.cols-2,
  .grid.cols-3,
  .grid.cols-4 {
    grid-template-columns: 1fr;
  }
  .grid .span-2,
  .grid .span-3,
  .grid .span-4 {
    grid-column: span 1;
  }
}

/* ============================================
   2c. FLEX
   ============================================ */

.flex        { display: flex; gap: var(--bare-gap); }
.flex.inline { display: inline-flex; }
.flex.wrap   { flex-wrap: wrap; }
.flex.col    { flex-direction: column; }
/* Ordre visuel inversé sans toucher l'ordre DOM (soumission implicite, tabulation). */
.flex.reverse { flex-direction: row-reverse; }

/* Alignment */
.flex.center  { align-items: center; }
.flex.start   { align-items: flex-start; }
.flex.end     { align-items: flex-end; }
.flex.stretch { align-items: stretch; }

/* Justification */
.flex.between { justify-content: space-between; }
.flex.around  { justify-content: space-around; }
.flex.evenly  { justify-content: space-evenly; }
.flex.jc-center { justify-content: center; }
.flex.jc-end    { justify-content: flex-end; }

/* Children */
.flex .grow   { flex-grow: 1; }
.flex .shrink { flex-shrink: 1; }
.flex .noshrink { flex-shrink: 0; }

/* Gap overrides */
.flex.gap-0 { gap: 0; }
.flex.gap-s { gap: var(--bare-gap-s); }
.flex.gap-l { gap: var(--bare-gap-l); }

/* ============================================
   3. TYPOGRAPHY
   ============================================ */

h1, h2, h3, h4, h5, h6 {
  margin-top: var(--bare-gap-l);
  margin-bottom: var(--bare-gap);
  line-height: 1.25;
}

h1 { font-size: 2em; }

/* Rangée « titre + action » (ex. relevé du copropriétaire) : h1 à gauche, un
   bouton à droite, alignés au centre. Le h1 perd ses marges propres (portées par
   la rangée) — sinon ses marges verticales asymétriques décalent le bouton vers
   le haut par rapport au texte du titre. */
.titre-action { margin: var(--bare-gap-l) 0 var(--bare-gap); }
.titre-action h1, .titre-action h2 { margin: 0; }
/* Fil d'Ariane (sous-pages profondes : relevé, vérification, revue…) : le h1
   porte le CHEMIN, en liens — taille de texte normale et en maigre, des liens
   géants ou gras seraient criards. */
h1.fil {
  font-size: 1em;
  font-weight: normal;
}
h2 { font-size: 1.5em; }
h3 { font-size: 1.25em; }
h4 { font-size: 1em; }
h5 { font-size: 0.875em; }
h6 { font-size: 0.75em; }

p {
  margin: 0 0 var(--bare-gap);
}

small {
  font-size: 0.875em;
  color: var(--bare-muted);
}

blockquote {
  margin: var(--bare-gap) 0;
  padding: var(--bare-gap-s) var(--bare-gap);
  border-left: 3px solid var(--bare-border);
  color: var(--bare-muted);
}

blockquote > p:last-child {
  margin-bottom: 0;
}

mark {
  background: var(--bare-mark-bg);
  color: var(--bare-mark-text);
  padding: 0.1em 0.2em;
}

hr {
  border: none;
  border-top: 1px solid var(--bare-border);
  margin: var(--bare-gap-l) 0;
}

abbr[title] {
  text-decoration: underline dotted;
  cursor: help;
}

/* ============================================
   4. LINKS
   ============================================ */

a {
  color: var(--bare-link);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* ============================================
   5. LISTS
   ============================================ */

ul, ol {
  margin: 0 0 var(--bare-gap);
  padding-left: var(--bare-gap-l);
}

li {
  margin-bottom: var(--bare-gap-s);
}

dt {
  font-weight: bold;
}

dd {
  margin: 0 0 var(--bare-gap-s);
}

/* ============================================
   6. TABLES
   ============================================ */

table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  margin: var(--bare-gap) 0;
  border: 1px solid var(--bare-border);
  border-radius: 4px;
}

th, td {
  padding: var(--bare-gap-s) 0.75em;
  text-align: left;
  border-bottom: 1px solid var(--bare-border);
}

th {
  font-weight: bold;
}

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

/* Pied de tableau (totaux de contrôle) : un filet le sépare du corps, comme le
   trait qu'on tire au-dessus d'un total — pas d'aplat ni de pastille, la somme
   se lit dans la continuité de sa colonne. Seule la PREMIÈRE rangée du pied
   porte le filet (un récap peut en compter plusieurs : entrées, sorties, net). */
tfoot tr:first-child > * {
  border-top: 2px solid var(--bare-border);
}

caption {
  margin-bottom: var(--bare-gap-s);
  font-size: 0.875em;
  color: var(--bare-muted);
}

/* En-têtes de tableau qui restent visibles au défilement. Le <thead> se fige
   sous la barre de navigation (seule barre sticky du haut) ; fond opaque +
   z-index pour que les lignes défilent DESSOUS. Fonctionne grâce au
   border-collapse: separate ci-dessus (le sticky d'un th est ignoré avec
   border-collapse: collapse). À poser sur les grands tableaux qui débordent. */
table.sticky-head thead th {
  position: sticky;
  top: var(--bare-nav-h);
  background: var(--bare-bg);
  z-index: 10;
}

/* Récap « Par cotisation » : la cotisation du filtre ACTIF est surlignée au
   surligneur BLEU (info), sur le TEXTE du titre. Recliquer la désélectionne
   (toggle : le href bascule côté serveur, le script en JS). Le bleu reste
   constant d'un thème à l'autre — variante claire/sombre seulement, comme
   .badge.special. */
tr.filtre-actif > td:first-child a {
  background: #dbe8f4; color: #1a4890;
  padding: 0.1em 0.25em; border-radius: 3px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) tr.filtre-actif > td:first-child a {
    background: #1a2e44; color: #8ec0ff;
  }
}
:root[data-theme="dark"] tr.filtre-actif > td:first-child a {
  background: #1a2e44; color: #8ec0ff;
}

/* ============================================
   8. FORMS
   ============================================ */

/* L'attribut HTML `hidden` doit gagner : nos règles d'AUTEUR `select/input
   { display: block }` (origine auteur) l'emportent sinon sur le `[hidden]
   { display: none }` du navigateur (origine UA), et un `<select hidden>`
   resterait visible. `!important` le garantit partout (selects masqués par JS —
   rattachements de la ventilation, lignes/bouton « Ajouter une ligne »…). */
[hidden] { display: none !important; }

label {
  display: block;
  margin-bottom: var(--bare-gap-s);
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="url"],
input[type="tel"],
input[type="number"],
input[type="search"],
input[type="date"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
input[type="time"],
textarea,
select {
  display: block;
  width: 100%;
  padding: var(--bare-gap-s);
  margin-bottom: var(--bare-gap-l);
  font: inherit;
  color: var(--bare-text);
  background: var(--bare-bg);
  border: 1px solid var(--bare-border);
  border-radius: 4px;
}

textarea {
  resize: vertical;
  min-height: 6em;
}

select {
  appearance: auto;
}

/* Dans une rangée de formulaire (.flex : Date · Description · Montant, ou
   Sens · Fonds), chaque champ clôt sa colonne : la grande marge basse des
   champs pleine largeur (--bare-gap-l) se réduit, la rangée suivante reste
   dans le rythme du groupe. */
.flex label > input,
.flex label > select {
  margin-bottom: var(--bare-gap-s);
}

/* Messages en « pastilles » : petites, EN BAS À DROITE, empilées (la plus
   récente en bas), refermées par le script de base.html (4 s, 8 s pour une
   erreur ; clic = tout de suite — sans JS elles restent simplement affichées).
   La pastille est un ACCUSÉ DE RÉCEPTION, pas un lieu d'explication : un
   refus de formulaire s'explique AU-DESSUS du formulaire (.alert.danger) et
   la pastille se réduit alors à son ✕ (classe « bref »). */
.toasts {
  position: fixed;
  bottom: var(--bare-gap);
  right: var(--bare-gap);
  z-index: 2000;
  display: flex;
  flex-direction: column;
  align-items: flex-end;           /* pastilles à la largeur de leur texte */
  gap: var(--bare-gap-s);
  max-width: min(26em, 92vw);
}

/* `.toasts p.toast` (et non `.toast`) pour battre la spécificité des règles
   de paragraphe de la base. Le glyphe est posé en CSS (::before) : un seul
   endroit le décide, le gabarit ne porte que le texte. */
.toasts p.toast {
  margin: 0;
  padding: 0.3em 0.6em;
  font-size: 0.9em;
  line-height: 1.35;
  border-radius: 4px;
  cursor: pointer;
  border: 1px solid var(--bare-border);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  transition: opacity 0.4s;
  display: flex;
  align-items: baseline;
  gap: 0.4em;
}
.toasts p.toast::before { content: "✓"; font-weight: bold; }
.toasts p.toast.danger::before  { content: "✕"; }
.toasts p.toast.warning::before { content: "!"; }
.toasts p.toast.special::before { content: "i"; }

.toasts p.toast.ok      { background: var(--bare-ok-bg);      color: var(--bare-ok); }
.toasts p.toast.warning { background: var(--bare-warning-bg); color: var(--bare-warning); }
.toasts p.toast.danger  { background: var(--bare-danger-bg);  color: var(--bare-danger); }
.toasts p.toast.special { background: #dbe8f4;                color: #1a4890; }

.toast.toast-fin {
  opacity: 0;
}

/* Champ refusé : contour rouge et halo — le « rougeoiement » qui DÉSIGNE le
   champ dont le refus parle (le texte, lui, est au-dessus du formulaire).
   Posé par `aria-invalid` : forms.py le met sur les champs d'un formulaire
   Django refusé, et les écrans à formulaire écrit à la main le posent depuis
   `champs_fautifs`. Le repli `ul.errorlist + p` couvre les formulaires
   d'authentification de Django, qui n'ont pas notre mixin (cf. p.html : la
   liste d'erreurs précède le <p> du champ). */
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"],
ul.errorlist + p input,
ul.errorlist + p select,
ul.errorlist + p textarea {
  border-color: var(--bare-danger);
  box-shadow: 0 0 0 3px var(--bare-danger-bg);
}

/* Un GROUPE de champs refusé (les radios d'une catégorie : on n'encercle pas
   chaque bouton) prend le même contour + halo que le ferait un champ. */
.groupe[aria-invalid="true"] {
  border: 1px solid var(--bare-danger);
  border-radius: 4px;
  padding: var(--bare-gap-s);
  box-shadow: 0 0 0 3px var(--bare-danger-bg);
}

/* Les listes d'erreurs que Django colle au champ (as_p) sont MUETTES : le
   texte du refus se dit UNE fois, au-dessus du formulaire
   (`_erreurs_formulaire.html`) ; ici, le champ se contente de rougeoyer. */
ul.errorlist {
  display: none;
}

/* Dates en trois menus [02][janvier][2026] (forms.DateSelects et le champ
   Date de la vérification PDF) : les trois selects coulent côte à côte au
   lieu de s'empiler (le défaut classless leur donnerait 100 % de largeur). */
select[name$="_day"],
select[name$="_month"],
select[name$="_year"] {
  display: inline-block;
  width: auto;
  margin-bottom: var(--bare-gap-s);
}

/* Rangée de champs « label AU-DESSUS du champ » posés côte à côte (répartition
   par fonds d'une cotisation, ou début · fréquence · fin) : on serre le rythme
   vertical — les grandes marges basses des champs (faites pour l'empilement)
   sont de trop ici, et le label colle à son champ. `input[type]` bat la
   spécificité de `input[type="number"]` de la base (cf. la règle des cellules). */
.rangee-champs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bare-gap);
  align-items: flex-end;
  margin-bottom: var(--bare-gap);
}
.rangee-champs label { margin-bottom: var(--bare-gap-s); }
.rangee-champs input[type],
.rangee-champs select { margin-bottom: 0; }

/* Dans une cellule de tableau (ventilation, postes du budget), c'est la
   rangée qui donne le rythme : aucun champ n'y porte de marge basse, et tous
   partagent la même hauteur alignée au milieu (sinon l'input Montant et les
   selects voisins décrochent). `input[type]` et non `input` : il faut battre
   la spécificité du sélecteur d'attribut `input[type="number"]` de la base,
   sinon la grande marge basse survit sur les inputs (mais pas les selects). */
td > input[type],
td > select {
  margin-bottom: 0;
  height: 2.4em;
  vertical-align: middle;
}

/* Ventilation : tableau PLEINE LARGEUR à 3 colonnes (Montant · Fonds ·
   Catégorie). Chaque champ remplit sa cellule ; le rattachement de cotisation
   s'empile SOUS la catégorie (même cellule) avec un léger espace. Mise en page
   FIXE : les colonnes gardent leurs proportions quel que soit le texte des
   options (sinon un libellé de cotisation très long élargirait sa colonne).
   S'applique à la revue (#table-ventilation) ET à l'éditeur de règle
   (#table-ventilation-regle). */
#table-ventilation,
#table-ventilation-regle { width: 100%; table-layout: fixed; }
#table-ventilation td,
#table-ventilation-regle td { padding: var(--bare-gap-s); vertical-align: top; }
#table-ventilation th:nth-child(1), #table-ventilation td:nth-child(1),
#table-ventilation-regle th:nth-child(1),
#table-ventilation-regle td:nth-child(1) { width: 20%; }
#table-ventilation th:nth-child(2), #table-ventilation td:nth-child(2),
#table-ventilation-regle th:nth-child(2),
#table-ventilation-regle td:nth-child(2) { width: 28%; }
#table-ventilation input[type="number"], #table-ventilation select,
#table-ventilation-regle input[type="number"],
#table-ventilation-regle select { width: 100%; }
#table-ventilation td > select + select,
#table-ventilation-regle td > select + select { margin-top: var(--bare-gap-s); }

/* Champs pré-remplis par une règle d'association (revue / vérification) : le
   jaune de <mark> porté PAR LE CHAMP lui-même — la provenance se voit, à
   confirmer du regard. Uniforme label/select/input : chaque champ (y compris
   une ligne de ventilation) est marqué INDIVIDUELLEMENT, donc un champ laissé
   vide n'est jamais surligné. */
label.prerempli,
select.prerempli,
input.prerempli {
  background: var(--bare-mark-bg);
  color: var(--bare-mark-text);
}

/* Période en une phrase : « Du 1er [mois][année] au 31 [mois][année] ».
   Les menus se dimensionnent à leur contenu et coulent dans le texte au lieu de
   prendre 100 % de la largeur (le défaut classless ci-dessus). */
.periode {
  line-height: 2.2;
}

.periode select {
  display: inline-block;
  width: auto;
  margin-bottom: 0;
  vertical-align: baseline;
}

/* Cases à cocher de comptes (état partiel) : en ligne. */
.comptes label {
  display: inline-block;
  margin: 0 var(--bare-gap) var(--bare-gap-s) 0;
}

/* Barre de filtres (journal) : les champs coulent en une rangée compacte —
   menus et champs à leur taille de contenu, sans la grande marge de bloc du
   défaut classless (l'espacement vient du gap du conteneur .flex). */
.filtres label { margin-bottom: 0; }
.filtres input,
.filtres select,
.filtres button {
  display: inline-block;
  width: auto;
  margin-bottom: 0;
  /* Même hauteur pour TOUS les contrôles (date, menu, recherche, bouton) : les
     widgets natifs (date vs select) et les boutons (padding plus petit) diffèrent
     sinon de quelques pixels. box-sizing border-box (global) inclut padding + bordure. */
  height: 2.4em;
}
.filtres button {
  /* Texte du bouton centré verticalement dans sa hauteur fixe. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Le menu « exercice fiscal » : assez large pour afficher « Exercice 2025 »
   ou le titre « Exercice fiscal ? » sans troncature. */
.filtres .fy-select { min-width: 12em; }
/* Rangée de menus (2e ligne) ÉTIRÉE : chaque menu grandit également pour
   remplir toute la largeur (même base + même grow = largeurs égales). */
.filtres .menus-full select { flex: 1 1 12em; }

/* Bouton « Surligner » : jaune constant (même jaune que le stabilo), pour
   l'action de MISE EN ÉVIDENCE (montre toute la période, marque les
   correspondances). Constant d'un thème à l'autre, comme les boutons sémantiques. */
button.jaune {
  background: #fde047;
  color: #1a1a1a;
  border-color: #fde047;
}
/* Ligne du journal SURLIGNÉE (résultat du mode « Surligner ») : fond jaune doux,
   texte foncé lisible. */
tr.surlignee > td { background-color: #fef08a; color: #1a1a1a; }
/* La flèche « ← » (raccourci exercice) centrée verticalement sur la rangée,
   à la même hauteur que les champs voisins. */
.filtres .fy-arrow {
  display: inline-flex;
  align-items: center;
  height: 2.4em;
  line-height: 1;
}

/* Clignotement : signale au regard un champ qui vient d'être pré-rempli
   (journal — le menu « exercice fiscal » remplit les deux dates). Trois flashs
   brefs, puis retour à l'état normal. */
@keyframes clignote { 0%, 100% { opacity: 1; } 50% { opacity: 0.15; } }
.clignote { animation: clignote 0.4s ease-in-out 3; }

/* Sélecteur de thème (pied de page) : le menu et son bouton coulent dans la
   ligne au lieu de prendre 100 % de la largeur (défaut classless ci-dessus) ;
   le tout reste sur la rangée unique du footer. */
.theme-form label { display: inline; margin: 0; }
.theme-form select { display: inline-block; width: auto; margin-bottom: 0; }

fieldset {
  border: 1px solid var(--bare-border);
  padding: var(--bare-gap);
  margin: var(--bare-gap) 0;
  border-radius: 4px;
}

legend {
  font-weight: bold;
  padding: 0 0.25em;
}

/* Groupe de champs SANS bordure — alternative au <fieldset> à l'intérieur
   d'une carte (préférence projet : jamais de <fieldset> dans une .card, pour
   éviter le double encadré). */
.groupe {
  margin: var(--bare-gap) 0;
}

.groupe-titre {
  font-weight: bold;
  margin: 0 0 var(--bare-gap-s);
}

.help {
  font-size: 0.875em;
  color: var(--bare-muted);
  margin: var(--bare-gap-s) 0 var(--bare-gap);
}

input[type="checkbox"],
input[type="radio"] {
  margin-right: var(--bare-gap-s);
  vertical-align: middle;
  margin-top: -0.2em;
}

input[type="checkbox"] + label,
input[type="radio"] + label {
  display: inline;
  margin-right: var(--bare-gap);
}

.vertical {
  display: flex;
  flex-direction: column;
  gap: var(--bare-gap-s);
}

/* ============================================
   8b. FORM VALIDATION
   ============================================ */

input:user-valid,
textarea:user-valid,
select:user-valid {
  border-color: var(--bare-ok);
}

input:user-invalid,
textarea:user-invalid,
select:user-invalid {
  border-color: var(--bare-danger);
}

.help.ok     { color: var(--bare-ok); }
.help.danger { color: var(--bare-danger); }

/* ============================================
   8c. INPUT GROUPS
   ============================================ */

.input-group {
  display: flex;
  margin-bottom: var(--bare-gap-l);
}

.input-group input,
.input-group select {
  margin-bottom: 0;
  border-radius: 0;
  flex: 1;
  min-width: 0;
}

.input-group input:first-child,
.input-group select:first-child,
.input-group span:first-child {
  border-radius: 4px 0 0 3px;
}

.input-group input:last-child,
.input-group select:last-child,
.input-group span:last-child,
.input-group button:last-child {
  border-radius: 0 3px 3px 0;
}

.input-group span {
  display: flex;
  align-items: center;
  padding: var(--bare-gap-s) var(--bare-gap);
  background: var(--bare-btn-bg);
  border: 1px solid var(--bare-border);
  white-space: nowrap;
  font-size: 0.875em;
}

.input-group button {
  border-radius: 0;
  margin: 0;
}

.input-group > :not(:first-child) {
  margin-left: -1px;
}

/* ============================================
   9. BUTTONS
   ============================================ */

button,
input[type="submit"],
input[type="reset"],
input[type="button"],
a.btn {
  --btn-bg: var(--bare-btn-bg);
  --btn-fg: var(--bare-text);
  font: inherit;
  padding: 0.15em 0.5em;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-bg);
  border-radius: 4px;
  cursor: pointer;
}

/* Un lien présenté comme un bouton — pour NAVIGUER avec l'aspect d'un bouton
   sans imbriquer <button> dans <a> (HTML invalide). Mêmes couleurs que button. */
a.btn {
  display: inline-block;
  text-decoration: none;
}

button:hover,
input[type="submit"]:hover,
input[type="reset"]:hover,
input[type="button"]:hover,
a.btn:hover {
  background: var(--bare-bg);
  color: var(--bare-text);
}

button.ok:hover,
button.danger:hover,
button.special:hover,
a.btn.ok:hover,
a.btn.danger:hover,
a.btn.special:hover {
  background: var(--btn-fg);
  color: var(--btn-bg);
}

button.ok,
a.btn.ok {
  --btn-bg: #2a7d2a;
  --btn-fg: #fff;
}

button.danger,
a.btn.danger {
  --btn-bg: #c33;
  --btn-fg: #fff;
}

button.special,
a.btn.special {
  --btn-bg: #2a5da8;
  --btn-fg: #fff;
}

.boolean {
  display: inline-flex;
  gap: 0;
}

.boolean button {
  border-radius: 0;
}

.boolean button:first-child {
  border-radius: 4px 0 0 3px;
}

.boolean button:last-child {
  border-radius: 0 3px 3px 0;
}

.boolean button.ok,
.boolean button.danger {
  --btn-bg: var(--bare-btn-bg);
  --btn-fg: var(--bare-text);
}

.boolean button.ok.active {
  --btn-bg: #2a7d2a;
  --btn-fg: #fff;
}

.boolean button.danger.active {
  --btn-bg: #c33;
  --btn-fg: #fff;
}

.boolean button.ok:hover {
  --btn-bg: #2a7d2a;
  --btn-fg: #fff;
}

.boolean button.danger:hover {
  --btn-bg: #c33;
  --btn-fg: #fff;
}

button.small {
  font-size: 0.875em;
  padding: 0.15em 0.5em;
}

button[disabled],
input[disabled],
textarea[disabled],
select[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

:root[data-theme="dark"] button.ok { --btn-bg: #1e5c1e; }
:root[data-theme="dark"] button.danger { --btn-bg: #8f2424; }
:root[data-theme="dark"] button.special { --btn-bg: #234e8f; }
:root[data-theme="dark"] .boolean button.ok.active { --btn-bg: #1e5c1e; }
:root[data-theme="dark"] .boolean button.danger.active { --btn-bg: #8f2424; }
:root[data-theme="dark"] .boolean button.ok:hover { --btn-bg: #1e5c1e; }
:root[data-theme="dark"] .boolean button.danger:hover { --btn-bg: #8f2424; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) button.ok { --btn-bg: #1e5c1e; }
  :root:not([data-theme="light"]) button.danger { --btn-bg: #8f2424; }
  :root:not([data-theme="light"]) button.special { --btn-bg: #234e8f; }
  :root:not([data-theme="light"]) .boolean button.ok.active { --btn-bg: #1e5c1e; }
  :root:not([data-theme="light"]) .boolean button.danger.active { --btn-bg: #8f2424; }
  :root:not([data-theme="light"]) .boolean button.ok:hover { --btn-bg: #1e5c1e; }
  :root:not([data-theme="light"]) .boolean button.danger:hover { --btn-bg: #8f2424; }
}

/* Bouton « au trait » : la couleur sémantique (--btn-bg posé par .ok/.danger/
   .special, surcharges de thème comprises) portée en CONTOUR plutôt qu'en aplat
   — fond transparent, texte + bordure colorés. Pour une action présente mais qui
   ne doit pas crier (remplacer / supprimer un relevé). Se remplit au survol.
   Placé après les règles sémantiques : gagne à spécificité égale. */
button.outline,
a.btn.outline {
  background: transparent;
  color: var(--btn-bg);
}

button.outline:hover,
a.btn.outline:hover {
  background: var(--btn-bg);
  color: var(--btn-fg);
}

/* ============================================
   10. ALERTS
   ============================================ */

.alert {
  padding: var(--bare-gap);
  margin: var(--bare-gap) 0;
  border-radius: 4px;
}

.alert.ok {
  background: var(--bare-ok-bg);
  color: var(--bare-ok);
}

.alert.warning {
  background: var(--bare-warning-bg);
  color: var(--bare-warning);
}

.alert.danger {
  background: var(--bare-danger-bg);
  color: var(--bare-danger);
}

/* Info (bleu) — pendant « alerte » du badge special, pour un message multi-mots. */
.alert.special {
  background: #dbe8f4;
  color: #1a4890;
}

/* ============================================
   10b. BADGES
   ============================================ */

.badge {
  display: inline-block;
  padding: 0.35em 0.5em;
  font-size: 0.75em;
  font-weight: bold;
  line-height: 1;
  border-radius: 4px;
  background: var(--bare-btn-bg);
  color: var(--bare-text);
  vertical-align: middle;
}

.badge.ok      { background: var(--bare-ok-bg);      color: var(--bare-ok); }
.badge.warning { background: var(--bare-warning-bg);  color: var(--bare-warning); }
.badge.danger  { background: var(--bare-danger-bg);   color: var(--bare-danger); }
.badge.special { background: #dbe8f4; color: #1a4890; }

/* Solid, high-contrast variants (white text on a full green/red) — for figures
   whose sign must read at a glance, e.g. the monthly budget variance grid. Same
   greens/reds as the .ok/.danger buttons. */
.badge.solid-ok     { background: #2a7d2a; color: #fff; }
.badge.solid-danger { background: #c33;    color: #fff; }

/* Heat-map DATA CELL: the colour goes on the CELL, the figure stays plain text —
   a montant is never wrapped in a pastille (règle « aucun chiffre dans un tag »),
   but the variance grid keeps its at-a-glance green/red. Same greens/reds as the
   .solid-* badges above (still used for the legend swatch). */
td.heat-pos { background: #2a7d2a; color: #fff; }
td.heat-neg { background: #c33;    color: #fff; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .badge.special { background: #1a2e44; color: #8ec0ff; }
  :root:not([data-theme="light"]) .badge.solid-ok     { background: #1e5c1e; }
  :root:not([data-theme="light"]) .badge.solid-danger { background: #8f2424; }
  :root:not([data-theme="light"]) td.heat-pos { background: #1e5c1e; }
  :root:not([data-theme="light"]) td.heat-neg { background: #8f2424; }
}
:root[data-theme="dark"] .badge.special { background: #1a2e44; color: #8ec0ff; }
:root[data-theme="dark"] .badge.solid-ok     { background: #1e5c1e; }
:root[data-theme="dark"] .badge.solid-danger { background: #8f2424; }
:root[data-theme="dark"] td.heat-pos { background: #1e5c1e; }
:root[data-theme="dark"] td.heat-neg { background: #8f2424; }

/* ============================================
   10c. CARDS
   ============================================ */

.card {
  border: 1px solid var(--bare-border);
  border-radius: 4px;
  margin: var(--bare-gap) 0;
  min-width: 0;
  overflow: hidden;
}

.card > header {
  padding: var(--bare-gap-s) var(--bare-gap);
  font-weight: bold;
  background: var(--bare-card-header-bg);
  border-radius: 4px 4px 0 0;
}

.card > :not(header) {
  padding-left: var(--bare-gap);
  padding-right: var(--bare-gap);
}

.card > header + * {
  padding-top: var(--bare-gap);
}

.card > :first-child:not(header) {
  padding-top: var(--bare-gap);
}

.card fieldset {
  margin: var(--bare-gap-s);
}

.card details[open] summary {
  margin-bottom: var(--bare-gap-s);
}

.card > :last-child {
  padding-bottom: var(--bare-gap);
  margin-bottom: 0;
}

/* ============================================
   11. PROGRESS
   ============================================ */

progress {
  appearance: none;
  width: 100%;
  height: 1em;
  border: none;
  border-radius: 4px;
  background: var(--bare-btn-bg);
  margin: 0 0 var(--bare-gap);
}

label + progress {
  margin-top: 0;
}

progress::-webkit-progress-bar {
  background: var(--bare-btn-bg);
  border-radius: 4px;
}

progress::-webkit-progress-value {
  background: var(--bare-border);
  border-radius: 4px;
}

progress::-moz-progress-bar {
  background: var(--bare-border);
  border-radius: 4px;
}

/* ============================================
   11. NAVIGATION
   ============================================ */

nav {
  position: sticky;
  top: 0;
  background: var(--bare-bg);
  margin: 0 0 var(--bare-gap-l);
  padding: 0.6em 0;
  border-bottom: 1px solid var(--bare-border);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bare-gap);
}

/* Les DEUX rangées du bandeau (barre principale + sous-navigation Compta)
   partagent la MÊME hauteur : un min-height commun en rem (la base est fixe,
   16px), le contenu se centre dedans — plutôt que d'égaliser des paddings,
   fragile (la barre principale est tenue par son bouton Déconnexion, la
   sous-nav par ses liens en 0.95em). */
body > nav {
  min-height: 3.25rem;
}

nav img {
  height: 2em;
  width: auto;
}

nav > a {
  display: flex;
  align-items: center;
}

nav > a strong {
  font-size: 1.3em;
  line-height: 1;
}

:root[data-theme="dark"] nav img { filter: invert(1); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) nav img { filter: invert(1); }
}

nav ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--bare-gap);
}

nav li {
  margin: 0;
}

nav a {
  color: var(--bare-text);
}

nav a:hover {
  text-decoration: underline;
}

nav a[aria-current="page"] {
  font-weight: bold;
}

/* Sous-navigation de section (« Compta » : Budget / Clôtures / Rapports) :
   une DEUXIÈME LIGNE de la barre du haut — en CONTACT net avec elle (la barre
   principale perd sa marge basse quand une 2e ligne suit), même fond, refermée
   par son propre filet. Onglets centrés ; l'actif est en gras (pas de
   soulignement — l'état courant se marque au gras seul). */
nav:has(+ nav.subnav) {
  margin-bottom: 0;
}

nav.subnav {
  position: static;
  z-index: auto;
  justify-content: center;
  background: var(--bare-bg);
  border-bottom: 1px solid var(--bare-border);
  margin: 0 0 var(--bare-gap-l);
  /* Pas de padding de barre : les LI s'étirent sur TOUTE la hauteur (chaîne
     align-items: stretch nav → ul → li), donc un item surligné (.stabilo)
     couvre la rangée entière, sans liseré ; chaque libellé se centre dans
     son item (li flex). */
  padding: 0;
  font-size: 0.95em;
  align-items: stretch;
}

nav.subnav ul {
  align-items: stretch;
}

nav.subnav li {
  display: flex;
  align-items: center;
  padding: 0.3em 0;
}

nav.subnav a { color: var(--bare-muted); }
nav.subnav a:hover { color: var(--bare-text); }

nav.subnav a[aria-current="page"] {
  color: var(--bare-text);
  font-weight: bold;
}

/* Pages de tête : l'onglet actif est un vrai <h1> (repère de structure), mais
   à TAILLE NORMALE comme le reste du bandeau ; les autres onglets sont des
   liens estompés vers les sections voisines. */
nav.subnav.heading h1 {
  font-size: inherit;
  font-weight: bold;
  margin: 0;
}

/* Onglets d'un formulaire à variantes (revue : Une écriture / Ventiler /
   Virement entre comptes) : même mécanique que la sous-navigation, mais DANS
   le flux de la page, centrés et sans filet — seul l'onglet actif est en
   gras. */
nav.onglets {
  position: static;
  z-index: auto;
  justify-content: center;
  border-bottom: none;
  margin: var(--bare-gap-l) 0;
  padding: 0 0 0.35em;
}

nav.onglets a { color: var(--bare-muted); }
nav.onglets a:hover { color: var(--bare-text); }

nav.onglets a[aria-current="page"] {
  color: var(--bare-text);
  font-weight: bold;
}

/* « Stabilo » : surligneur jaune — état d'AVERTISSEMENT réutilisable qui signale
   un réglage manquant / incomplet (onglet Compta à configurer, fractions non
   toutes renseignées, …). Constant d'un thème à l'autre, comme les boutons
   sémantiques : fond jaune + texte foncé, lisible partout comme sur du papier. */
.stabilo {
  background-color: #fde047;
  color: #1a1a1a;
  padding: 0 0.25em;
  border-radius: 0.15em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* Dans un onglet Compta surligné, forcer le texte foncé du lien/titre (sinon le
   gris estompé du sélecteur passerait mal sur le jaune). */
nav.subnav li.stabilo a,
nav.subnav li.stabilo h1 {
  color: #1a1a1a;
}

/* L'onglet surligné : étiré sur la rangée (cf. align-items ci-dessus), contenu
   centré — le jaune couvre toute la ligne, bord à bord. */
nav.subnav li.stabilo {
  display: flex;
  align-items: center;
  padding: 0 0.5em;
  border-radius: 0;
}

/* `body` est un conteneur flex (colonne, cf. §2) : les marges verticales de
   nav/header ne se « collapsent » PAS entre elles. Le titre de page ajoutait
   donc sa marge supérieure (var(--bare-gap-l)) EN PLUS de la marge sous la nav
   → double espace nav ↔ h1. On annule la marge haute du 1er bloc de l'en-tête. */
body > header > :first-child {
  margin-top: 0;
}

/* Fil d'Ariane : TROISIÈME ligne du bandeau — remonté juste sous la
   sous-navigation (annule presque toute la marge basse de nav.subnav), et
   suivi d'un blanc franc : il appartient à l'en-tête, le contenu commence
   plus bas. Spécificité > `body > header > :first-child` ci-dessus. */
body > header > h1.fil {
  margin-top: calc(-1 * var(--bare-gap-l) + 0.4em);
  margin-bottom: var(--bare-gap-l);
}

/* Idem pour le 1er bloc du contenu : quand l'en-tête est vide (ex. Clôtures, où
   le titre est le bandeau d'onglets), le contenu ne doit pas ajouter sa grande
   marge haute sous le sous-menu. */
body > main > :first-child {
  margin-top: 0;
}

/* ============================================
   11b. MENU (vertical nav)
   ============================================ */

.menu {
  list-style: none;
  padding: 0;
  margin: 0;
}

.menu li {
  margin: 0;
}

.menu a {
  display: block;
  padding: var(--bare-gap-s) var(--bare-gap);
  color: var(--bare-text);
  border-radius: 4px;
}

.menu a:hover {
  text-decoration: underline;
}

/* ============================================
   12. MEDIA
   ============================================ */

img, video, svg, canvas {
  max-width: 100%;
  height: auto;
}

figure {
  margin: var(--bare-gap) 0;
}

figcaption {
  font-size: 0.875em;
  color: var(--bare-muted);
  margin-top: var(--bare-gap-s);
}

/* ============================================
   13. DETAILS & DIALOG
   ============================================ */

details {
  margin: var(--bare-gap-l) 0;
  border: 1px solid var(--bare-border);
  border-radius: 4px;
  padding: var(--bare-gap-s) var(--bare-gap);
}

summary {
  cursor: pointer;
  font-weight: bold;
}

details[open] summary {
  margin-bottom: var(--bare-gap-l);
}

dialog {
  border: 1px solid var(--bare-border);
  border-radius: 4px;
  padding: var(--bare-gap-l);
  max-width: 40em;
}

dialog::backdrop {
  background: rgba(0, 0, 0, 0.5);
}

/* ============================================
   14. FOCUS — ACCESSIBILITY
   ============================================ */

:focus-visible {
  outline: 2px solid var(--bare-focus);
}

/* ============================================
   15. PRINT
   ============================================ */

@media print {
  body {
    max-width: none;
    padding: 0;
    font-size: 12pt;
    color: #000;
    background: #fff;
  }

  a {
    color: #000;
    text-decoration: underline;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.8em;
    color: #555;
  }

  img, video, svg {
    max-width: 100% !important;
  }

  nav, .no-print {
    display: none;
  }
}

/* ============================================
   16. SPACING UTILITIES
   ============================================ */

/* Margin — all sides */
.m-0  { margin: 0; }
.m-s  { margin: var(--bare-gap-s); }
.m    { margin: var(--bare-gap); }
.m-l  { margin: var(--bare-gap-l); }

/* Un titre de tableau (ex. « Répartition » de la ventilation) collé à sa table :
   non gras et rapproché (la table porte margin-top: gap, trop loin sinon). */
p.titre-tableau { margin-bottom: 0; font-weight: normal; }
p.titre-tableau + table { margin-top: var(--bare-gap-s); }

/* Margin — top */
.mt-0 { margin-top: 0; }
.mt-s { margin-top: var(--bare-gap-s); }
.mt   { margin-top: var(--bare-gap); }
.mt-l { margin-top: var(--bare-gap-l); }

/* Margin — bottom */
.mb-0 { margin-bottom: 0; }
.mb-s { margin-bottom: var(--bare-gap-s); }
.mb   { margin-bottom: var(--bare-gap); }
.mb-l { margin-bottom: var(--bare-gap-l); }

/* Margin — left (start) */
.ms-0 { margin-left: 0; }
.ms-s { margin-left: var(--bare-gap-s); }
.ms   { margin-left: var(--bare-gap); }
.ms-l { margin-left: var(--bare-gap-l); }

/* Margin — right (end) */
.me-0 { margin-right: 0; }
.me-s { margin-right: var(--bare-gap-s); }
.me   { margin-right: var(--bare-gap); }
.me-l { margin-right: var(--bare-gap-l); }

/* Margin — horizontal */
.mx-0    { margin-left: 0; margin-right: 0; }
.mx-s    { margin-left: var(--bare-gap-s); margin-right: var(--bare-gap-s); }
.mx      { margin-left: var(--bare-gap); margin-right: var(--bare-gap); }
.mx-l    { margin-left: var(--bare-gap-l); margin-right: var(--bare-gap-l); }
.mx-auto { margin-left: auto; margin-right: auto; }

/* Margin — vertical */
.my-0 { margin-top: 0; margin-bottom: 0; }
.my-s { margin-top: var(--bare-gap-s); margin-bottom: var(--bare-gap-s); }
.my   { margin-top: var(--bare-gap); margin-bottom: var(--bare-gap); }
.my-l { margin-top: var(--bare-gap-l); margin-bottom: var(--bare-gap-l); }

/* Padding — all sides */
.p-0  { padding: 0; }
.p-s  { padding: var(--bare-gap-s); }
.p    { padding: var(--bare-gap); }
.p-l  { padding: var(--bare-gap-l); }

/* Padding — top */
.pt-0 { padding-top: 0; }
.pt-s { padding-top: var(--bare-gap-s); }
.pt   { padding-top: var(--bare-gap); }
.pt-l { padding-top: var(--bare-gap-l); }

/* Padding — bottom */
.pb-0 { padding-bottom: 0; }
.pb-s { padding-bottom: var(--bare-gap-s); }
.pb   { padding-bottom: var(--bare-gap); }
.pb-l { padding-bottom: var(--bare-gap-l); }

/* Padding — left (start) */
.ps-0 { padding-left: 0; }
.ps-s { padding-left: var(--bare-gap-s); }
.ps   { padding-left: var(--bare-gap); }
.ps-l { padding-left: var(--bare-gap-l); }

/* Padding — right (end) */
.pe-0 { padding-right: 0; }
.pe-s { padding-right: var(--bare-gap-s); }
.pe   { padding-right: var(--bare-gap); }
.pe-l { padding-right: var(--bare-gap-l); }

/* Padding — horizontal */
.px-0 { padding-left: 0; padding-right: 0; }
.px-s { padding-left: var(--bare-gap-s); padding-right: var(--bare-gap-s); }
.px   { padding-left: var(--bare-gap); padding-right: var(--bare-gap); }
.px-l { padding-left: var(--bare-gap-l); padding-right: var(--bare-gap-l); }

/* Padding — vertical */
.py-0 { padding-top: 0; padding-bottom: 0; }
.py-s { padding-top: var(--bare-gap-s); padding-bottom: var(--bare-gap-s); }
.py   { padding-top: var(--bare-gap); padding-bottom: var(--bare-gap); }
.py-l { padding-top: var(--bare-gap-l); padding-bottom: var(--bare-gap-l); }

/* Text & display helpers — replace the inline styles in the templates.
   `.num` (right-aligned figures) is by far the most used (numeric table cells). */
.num         { text-align: right; }
/* Un champ numérique DANS une cellule `.num` aligne son chiffre à droite comme
   la colonne (montant de part, poste de budget) — sinon le texte de l'input
   resterait calé à gauche. */
.num > input[type="number"] { text-align: right; }
.text-center { text-align: center; }
.block       { display: block; }
.inline      { display: inline; }
.full        { width: 100%; }
.scroll-x    { overflow-x: auto; }
.nowrap      { white-space: nowrap; }
/* Coupe un mot insécable (jeton, code, référence collée) plutôt que de laisser
   la cellule pousser le tableau au-delà de sa largeur — sinon un `.scroll-x`
   affiche un défilement horizontal parasite de quelques pixels. */
.break       { overflow-wrap: anywhere; word-break: break-word; }
.big         { font-size: 1.4em; }
.muted       { color: var(--bare-muted); }
/* Lu par les lecteurs d'écran, invisible à l'œil : le texte d'une pastille
   « brève » (réduite à son ✓ / ✕) reste ainsi énoncé, jamais perdu. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Fenêtre de conversation de l'assistant : elle DÉFILE (bornée en hauteur) pour
   qu'on voie toujours la dernière réponse ET le champ juste dessous (JS place le
   scroll en bas au chargement). La réponse de l'IA coule SANS cadre ; la phrase de
   l'utilisateur est mise en RETRAIT (padding gauche/droite) pour la distinguer. */
.chat {
  max-height: 60vh;
  overflow-y: auto;
  border: 1px solid var(--bare-border);
  border-radius: 4px;
  padding: var(--bare-gap);
  margin: var(--bare-gap) 0;
}
.chat > :first-child { margin-top: 0; }
.chat > :last-child  { margin-bottom: 0; }
/* La réponse de l'IA est décalée à GAUCHE (padding à droite) ; la question de
   l'utilisateur est décalée à DROITE et alignée à droite — lecture « chat ». */
.chat-ai { padding-right: 15%; }
.chat-ai > :first-child { margin-top: 0; }
.chat-ai > :last-child  { margin-bottom: 0; }
/* La question de l'utilisateur : une bulle bleue calée à DROITE (largeur au
   contenu, jusqu'à 85 %), même bleu « info » que .badge.special / .alert.special
   — recoloré par thème plus bas. */
.chat-user {
  margin-left: auto;
  width: fit-content;
  max-width: 85%;
  padding: 0.5em 0.75em;
  border-radius: 12px;
  background: #dbe8f4;
  color: #1a4890;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chat-user { background: #1a2e44; color: #8ec0ff; }
}
:root[data-theme="dark"] .chat-user { background: #1a2e44; color: #8ec0ff; }

/* Indicateur d'attente de l'assistant IA (le SEUL de l'app) : un anneau qui
   tourne, couleurs héritées du thème (piste = bordure, arc = muted). Respecte
   prefers-reduced-motion — manifeste « calme » : pas d'animation imposée. */
.spinner {
  display: inline-block;
  width: 1em; height: 1em;
  vertical-align: -0.15em;
  border: 0.15em solid var(--bare-border);
  border-top-color: var(--bare-muted);
  border-radius: 50%;
  animation: bare-spin 0.8s linear infinite;
}
@keyframes bare-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; } }

/* Page en CONSULTATION SEULEMENT (le compte n'a pas le droit d'écriture de
   cette page — cf. conformite/droits.py). On masque les formulaires qui
   MODIFIENT (method="post") : offrir un bouton menant à un 403 serait
   malhonnête. Les formulaires de filtre/recherche (method="get") restent,
   la lecture étant libre. Ceci n'est QU'UN MASQUE : la barrière est le
   middleware côté serveur, jamais le CSS. */
main.lecture-seule form[method="post"] { display: none; }
