﻿/* ============================================================
   BUDGET APP - Styles principaux (version en em)
   Direction esthétique : papier de comptable moderne

   Notes sur la conversion px → em :
   - Base racine : html font-size = 15px (browser 16px × 0.9375)
   - font-size : converti relativement au parent (= 15 par défaut)
   - padding/margin/gap/width/etc. : converti relativement à la
     PROPRE font-size de l'élément (la cascade fait scaler tout
     ensemble si tu changes la font-size d'un parent)
   - Borders 1-2px et box-shadows fins : gardés en px (sub-pixel
     en em donne du flou)
   - Breakpoints @media : gardés en px (1em en media query = 16px
     toujours, donc pas comparable à notre base 15)
   ============================================================ */

:root {
  --bg: #f5f3ee;
  --bg-card: #ffffff;
  --bg-soft: #ebe8e0;
  --bg-softer: #f0ede5;
  --ink: #1a1714;
  --ink-soft: #3d3832;
  --ink-muted: #5d574e;
  --line: #8e8881;
  --line-soft: #b8b3ab;
  --accent: #1a1714;
  --pos: #2d6a4f;
  --neg: #a23b3b;
  --warn: #c8842b;
  --shared: #4a5d8c;
  --personal: #8b6f47;
  --project: #6b4a7a;
  /* Famille violet — boutons actifs, accents, submit */
  --primary: #6b4a7a;
  --primary-soft: #8c6a9d;
  --primary-light: #e7dce9;
  --primary-lighter: #f3ecf5;
}

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

html, body {
  color: var(--ink);
  font-family: 'Google Sans Flex', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
  font-size: 0.9375em; /* 15px (base browser 16px) */
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

html {
  background-color: var(--bg);
}

/* Carte ancienne en fond, fixée au viewport, à 20 % d'opacité.
   Sur ::before de html pour garantir une couverture pleine fenêtre
   peu importe la hauteur du body. */
html::before {
  content: '';
  position: fixed;
  inset: 0;
  background-image: url('../img/bg-map.jpg');
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
  opacity: 0.2;
  z-index: -1;
  pointer-events: none;
  /* Légère sur-échelle pour rogner les bords blancs du scan. */
  transform: scale(1.05);
  transform-origin: center center;
}

body {
  min-height: 100vh;
  background-color: transparent; /* laisse html (carte) traverser */
  background-image: radial-gradient(circle at 1px 1px, rgba(26,23,20,0.09) 1px, transparent 0);
  background-size: 1.6em 1.6em; /* 24px / 15 */
  overflow-x: hidden; /* garde-fou contre tout débordement horizontal */
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }

.serif { font-family: 'Google Sans Flex', system-ui, sans-serif; }
.mono { font-family: 'Roboto Mono', 'SF Mono', Menlo, monospace; font-feature-settings: "tnum"; }
.tabular { font-variant-numeric: tabular-nums; }
.muted { color: var(--ink-muted); }
.soft { color: var(--ink-soft); }

/* ===== Layout principal ===== */
.shell {
  max-width: 85.333em;
  margin: 0 auto;
  /* env(safe-area-inset-*) : 0 sur les écrans plats, hauteur réelle sur les
     iPhones avec encoche/Dynamic Island. Évite que le contenu soit caché par
     la caméra (haut) ou la home indicator (bas). Nécessite viewport-fit=cover
     dans <meta viewport> (déjà en place dans header.php). */
  padding:
    calc(1.6em + env(safe-area-inset-top))
    calc(1.6em + env(safe-area-inset-right))
    calc(1.6em + env(safe-area-inset-bottom))
    calc(1.6em + env(safe-area-inset-left));
}

@media (max-width: 768px) {
  .shell {
    padding:
      calc(0.933em + env(safe-area-inset-top))
      calc(0.933em + env(safe-area-inset-right))
      calc(6.667em + env(safe-area-inset-bottom))
      calc(0.933em + env(safe-area-inset-left));
  }
}

/* Si la bannière offline est visible, .shell n'a plus besoin de réserver le
   safe-area-inset-top (la bannière le fait via son propre padding). Évite le
   double-espace au-dessus de la première card en mode offline. */
body:has(#bpOfflineBanner:not([hidden])) .shell {
  padding-top: 1.6em;
}
@media (max-width: 768px) {
  body:has(#bpOfflineBanner:not([hidden])) .shell {
    padding-top: 0.933em;
  }
}

/* ===== Topbar ===== */
.topbar {
  display: flex;
  flex-direction: column;
  gap: 10em;
  margin-bottom: 1.867em;
  padding-bottom: 1.333em;
  border-bottom: 1px solid var(--line);
}

.topbar-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8em; /* 12 / 15 */
  flex-wrap: wrap;
  margin-left: 7em;
  /* Réserve l'espace au-dessus pour le voilier en filigrane (desktop). */
  padding-top: 1.5em;
}

.brand {
  display: flex;
  align-items: baseline;
  gap: 0.667em; /* 10 / 15 */
  flex-wrap: wrap;
  min-width: 0;
}

.brand-mark {
  font-family: 'Tangerine', cursive;
  font-size: 5em; /* Tangerine est très étroite, on compense */
  font-weight: 700;
  font-style: normal;
  letter-spacing: 0;
  line-height: 1;
  position: relative;
  isolation: isolate; /* contient le z-index négatif du ::before */
}
/* Voilier en filigrane à gauche du titre (desktop seulement, masqué en mobile). */
.brand-mark::before {
  content: '';
  position: absolute;
  left: -2.5em;
  top: 50%;
  width: 3em;
  height: 3em;
  margin-top: -1em;
  background: url(../icons/logo-appareillage.svg?v=4) no-repeat left center / contain;
  z-index: -1;
  pointer-events: none;
}

.brand-sub {
  font-size: 0.733em; /* 11 / 15 */
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.15em;
  font-weight: 500;
}

.brand-tagline {
  font-family: 'Google Sans Flex', system-ui, sans-serif;
  font-size: 0.867em; /* 13 / 15 */
  font-style: italic;
  color: var(--ink-soft);
  font-weight: 400;
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 0.4em; /* 6 / 15 */
  flex-wrap: wrap;
  row-gap: 0.533em; /* 8 / 15 */
}

/* .user-pill : font-size 13, props internes / 13 */
.user-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.769em; /* 10 / 13 */
  padding: 0.462em 0.923em 0.462em 0.462em; /* 6 12 6 6 / 13 */
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-card);
  font-size: 0.867em; /* 13 / 15 */
  flex-shrink: 0;
}

/* .avatar : font-size 11, props / 11 */
.avatar {
  width: 2.364em; /* 26 / 11 */
  height: 2.364em;
  border-radius: 50%;
  background: var(--ink);
  color: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.733em; /* 11 / 15 */
  font-weight: 600;
  flex-shrink: 0;
}

/* .nav-link : font-size 13, props / 13 */
.nav-link {
  padding: 0.538em 0.923em;
  border-radius: 0.615em;
  color: var(--ink-soft);
  font-size: 1.2em;
  font-weight: 500;
  white-space: nowrap;
}
.nav-link:hover { background: var(--bg-soft); color: var(--ink); }
.nav-link.active { background: var(--ink); color: var(--bg); }
/* .nav-link-icon : font-size 16, props / 16 */
.nav-link-icon { font-size: 1.067em; line-height: 1; padding: 0.375em 0.625em; } /* 16/15 ; 6/16 10/16 */
.nav-link-icon .emoji { width: 1em; height: 1em; vertical-align: -0.188em; } /* 16/16 ; -3/16 */

/* Banner offline / sync pending : sticky en haut, pleine largeur.
   Élément placé HORS de .shell (cf. _topbar.php) → pas de margin négative
   à compenser, le banner couvre naturellement toute la largeur viewport.
   Le padding-top intègre safe-area-inset-top pour passer SOUS l'encoche
   des iPhones (sinon le texte serait caché par la caméra/Dynamic Island). */
.bp-offline-banner {
  position: sticky;
  top: 0;
  z-index: 100;
  padding:
    calc(0.533em + env(safe-area-inset-top))
    calc(1em + env(safe-area-inset-right))
    0.533em
    calc(1em + env(safe-area-inset-left));
  text-align: center;
  font-size: 0.867em;
  font-weight: 500;
  border-bottom: 1px solid var(--line-soft);
}
.bp-offline-banner.is-offline { background: #fbe4ca; color: #8a5a14; }
.bp-offline-banner.is-pending { background: #dde2ee; color: #4a5d8c; }

/* Caméra in-page : viewfinder plein écran + 3 boutons en bas (cancel, capture, switch).
   Évite le handoff vers Samsung Camera qui ne renvoie pas le fichier en PWA. */
.bp-camera-modal {
  position: fixed;
  inset: 0;
  background: #000;
  z-index: 9999;
  display: flex;
  flex-direction: column;
}
.bp-camera-modal[hidden] { display: none; }
.bp-camera-modal video {
  flex: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
}
.bp-camera-controls {
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 1.333em 1.6em calc(1.333em + env(safe-area-inset-bottom, 0));
  background: rgba(0, 0, 0, 0.85);
}
.bp-camera-btn {
  border: none;
  cursor: pointer;
  font-family: inherit;
}
.bp-camera-btn-side {
  width: 3em;
  height: 3em;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  font-size: 1.333em;
  display: flex;
  align-items: center;
  justify-content: center;
}
.bp-camera-btn-side:active { background: rgba(255, 255, 255, 0.3); }
.bp-camera-btn-capture {
  width: 4.667em;
  height: 4.667em;
  border-radius: 50%;
  background: #fff;
  border: 0.267em solid rgba(255, 255, 255, 0.4);
  box-shadow: 0 0 0 0.133em #fff inset;
}
.bp-camera-btn-capture:active { background: #ddd; }

/* Modal "Réessayer la photo" — affiché quand on détecte que la capture a foiré
   (bug Samsung intent return : photo prise mais jamais transmise au PWA). */
.bp-retry-modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.333em;
}
.bp-retry-card {
  background: var(--bg);
  border-radius: 1em;
  padding: 1.6em 1.333em 1.333em;
  max-width: 24em;
  width: 100%;
  text-align: center;
  box-shadow: 0 1.333em 3.2em rgba(0, 0, 0, 0.3);
}
.bp-retry-icon {
  font-size: 2.667em;
  line-height: 1;
  margin-bottom: 0.2em;
}
.bp-retry-card h3 {
  margin: 0 0 0.533em;
  font-size: 1.2em;
  font-family: 'Newsreader', serif;
}
.bp-retry-card p {
  margin: 0 0 0.667em;
  font-size: 0.933em;
  color: var(--ink-soft);
  line-height: 1.4;
}
.bp-retry-tip {
  font-style: italic;
  font-size: 0.867em !important;
  color: var(--ink-muted) !important;
}
.bp-retry-actions {
  display: flex;
  gap: 0.667em;
  justify-content: center;
  margin-top: 1em;
}
.bp-retry-actions button {
  flex: 1;
  padding: 0.667em 1em;
  border-radius: 0.667em;
  font-size: 0.933em;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid var(--line);
  font-family: inherit;
}
.bp-retry-actions .btn {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}
.bp-retry-actions .btn-secondary {
  background: transparent;
  color: var(--ink);
}

/* ============================================================
   Éditeur d'items (modal après OCR) : layout responsive,
   card par item, hide taxes/déductible en devise étrangère.
   ============================================================ */
.items-editor-intro {
  font-size: 0.867em;
  margin-bottom: 1em;
  color: var(--ink-soft);
  line-height: 1.45;
}
.items-editor-list {
  display: flex;
  flex-direction: column;
  gap: 0.667em;
  margin-bottom: 1.067em;
}
/* Items : liste plate, séparée par lignes (pas de card / padding L-R individuel
   pour gagner de l'espace dans le modal). */
.items-editor-list { gap: 0; }
.items-row {
  display: flex;
  flex-direction: column;
  gap: 0.6em;
  padding: 0.867em 0;
  background: transparent;
  border: none;
  border-radius: 0;
  border-bottom: 1px solid var(--line-soft);
}
.items-row:last-child { border-bottom: none; padding-bottom: 0; }
.items-row:first-child { padding-top: 0.4em; }

/* Inputs item : nom + montant à la MÊME taille visuelle. On garde la même
   font-family (sans-serif) sur les deux — Roboto Mono sur le montant
   donnait une apparence visuellement plus petite à cause de sa x-height
   réduite. tabular-nums sur le montant suffit pour l'alignement chiffré. */
.items-row .item-label,
.items-row .item-amount {
  font-size: 0.867em;
  padding: 0.467em 0.667em;
  border: 1px solid var(--line-soft);
  border-radius: 0.533em;
  background: var(--bg-card);
  font-family: inherit;
  color: var(--ink);
  line-height: 1.3;
}
.items-row .item-label { width: 100%; }
.items-row .item-amount {
  width: 6em;
  flex-shrink: 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Ligne 2 : montant à gauche, traduction (label original) alignée à droite. */
.items-row-amt-line {
  display: flex;
  gap: 0.8em;
  align-items: center;
}
.items-row-amt-line .item-label-original {
  flex: 1;
  min-width: 0;
  text-align: right;
  font-size: 0.8em;
  color: var(--ink-muted);
  font-style: italic;
  line-height: 1.3;
  margin: 0;
  padding: 0;
}
.items-row-amt-line .item-label-native {
  display: block;
  font-style: normal;
  opacity: 0.7;
  font-size: 0.933em;
}

/* Toggle attribution : pill pleine largeur, fond doux, sélection colorée
   sémantiquement (partagé bleu / moi brun / partenaire violet) plutôt que
   noir massif. Les boutons remplissent la pilule sans gap visible. */
.items-row-attr { display: flex; }
.items-row-attr .attr-toggle {
  display: flex;
  gap: 0;
  width: 100%;
  background: var(--bg-soft);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  padding: 0;
  overflow: hidden;
}
.items-row-attr .attr-btn {
  flex: 1;
  padding: 0.467em 0.6em;
  font-size: 0.8em;
  font-weight: 500;
  border: none;
  background: transparent;
  cursor: pointer;
  font-family: inherit;
  color: var(--ink-muted);
  border-radius: 999px;
  transition: background 0.15s ease, color 0.15s ease;
}
.items-row-attr .attr-btn:hover { color: var(--ink); }
.items-row-attr .attr-btn.active {
  background: var(--shared);
  color: #fff;
}
.items-row-attr .attr-btn[data-attr-set="me"].active {
  background: var(--personal);
}
.items-row-attr .attr-btn[data-attr-set="partner"].active {
  background: var(--project);
}
.items-row-meta {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: 0.4em;
  align-items: center;
}
.items-row-meta select {
  padding: 0.4em 0.4em;
  font-size: 0.8em;
  border-radius: 0.4em;
  border: 1px solid var(--line);
  background: var(--bg);
  min-width: 0;
  font-family: inherit;
}
.items-row-meta .item-deduct-label {
  display: flex;
  align-items: center;
  gap: 0.333em;
  font-size: 0.8em;
  white-space: nowrap;
  cursor: pointer;
  padding: 0.267em 0.4em;
}
.items-row-meta .item-deduct-label input[type=checkbox] {
  width: 1.067em;
  height: 1.067em;
  cursor: pointer;
  margin: 0;
}

/* Devise étrangère : cache les contrôles taxes/déductible (non applicables) */
.items-row[data-foreign="1"] .item-taxcls,
.items-row[data-foreign="1"] .item-deduct-label {
  display: none;
}
.items-row[data-foreign="1"] .items-row-meta {
  grid-template-columns: 1fr;
}

/* Restaurant : la catégorisation par item n'a pas de sens (tout = Restaurant).
   On garde l'attribution + tip + taxes (au QC), on cache juste le select catégorie. */
.items-row[data-restaurant="1"] .item-cat {
  display: none;
}
.items-row[data-restaurant="1"] .items-row-meta {
  grid-template-columns: 1fr auto;
}
/* Restaurant à l'étranger : aucun contrôle de meta utile → on cache la rangée */
.items-row[data-restaurant="1"][data-foreign="1"] .items-row-meta {
  display: none;
}

/* Bloc pourboire */
.items-editor-tip {
  background: var(--bg-soft);
  padding: 0.8em;
  border-radius: 0.667em;
  margin-bottom: 0.8em;
}
.items-editor-tip-row {
  display: flex;
  gap: 0.667em;
  margin-bottom: 0.533em;
}
.items-editor-tip-row .form-field {
  flex: 1;
  min-width: 0;
}
.items-editor-tip-row label {
  display: block;
  font-size: 0.8em;
  margin-bottom: 0.267em;
  color: var(--ink-soft);
}
.items-editor-tip-row input {
  width: 100%;
  padding: 0.4em 0.533em;
  font-family: 'Roboto Mono', monospace;
}
.items-editor-tip-checkbox {
  display: flex;
  align-items: center;
  gap: 0.4em;
  font-size: 0.867em;
  cursor: pointer;
  padding: 0.267em 0;
  color: var(--ink-soft);
}

/* Recap (HT / Taxes / TTC / Tip) */
.items-editor-recap {
  padding: 0.8em;
  background: var(--bg-soft);
  border-radius: 0.667em;
  font-size: 0.867em;
  margin-bottom: 1em;
}
.items-editor-recap-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8em;
  font-family: 'Roboto Mono', monospace;
}
.items-editor-recap-row > span {
  flex: 1 1 auto;
}
.items-editor-recap-ocr {
  font-size: 0.733em;
  color: var(--ink-muted);
  margin-top: 0.4em;
}

/* Actions en bas */
.items-editor-actions {
  display: flex;
  gap: 0.667em;
  justify-content: flex-end;
}
.items-editor-actions .btn,
.items-editor-actions .btn-secondary {
  min-width: 7em;
}

/* Desktop : on garde le layout column. La structure verticale (label /
   montant+traduction / attribution / meta) tient mieux la cohérence
   visuelle qu'un grid 2 colonnes maintenant que chaque item est une rangée. */

/* ============================================================
   Info-modal trigger : label cliquable avec petite ⓘ pour ouvrir
   une explication dans un modal. Tout élément avec data-info-body.
   ============================================================ */
[data-info-body] {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* Bouton ⓘ : placé en absolute top-right de la card associée (le parent doit
   être position:relative). Couleur orange chaud cohérente avec la palette.
   TEMPORAIREMENT MASQUÉ via display:none — on y reviendra. */
.info-icon {
  display: none !important;
  position: absolute;
  top: 0.667em;
  right: 0.667em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.467em;
  height: 1.467em;
  border-radius: 50%;
  background: #c8842b;
  color: #fff;
  font-size: 0.733em;
  font-style: italic;
  font-weight: 700;
  font-family: 'Newsreader', 'Google Sans Flex', system-ui, sans-serif;
  border: none;
  cursor: pointer;
  box-shadow: 0 0.133em 0.4em rgba(200, 132, 43, 0.25);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  z-index: 2;
  padding: 0;
}
.info-icon:hover {
  transform: scale(1.1);
  box-shadow: 0 0.2em 0.533em rgba(200, 132, 43, 0.35);
}
.info-icon:active { transform: scale(0.95); }

/* ============================================================
   Contrôle de partage % avancé : chips (⅓, ⅔, 25, 75) + curseur snap
   par 5 (avec 33 et 67 inclus) + champ manuel. Caché par défaut, dévoilé
   par bouton "… autre" sur transaction.php et dans la saisie rapide.
   ============================================================ */
.share-advanced[hidden],
.qe-share-advanced[hidden] { display: none; }
.share-advanced,
.qe-share-advanced {
  display: flex;
  flex-direction: column;
  gap: 0.533em;
  margin-top: 0.533em;
  padding: 0.667em 0.8em;
  background: var(--bg-soft);
  border-radius: 0.533em;
}
.share-presets {
  display: flex;
  gap: 0.4em;
  flex-wrap: wrap;
}
.share-chip {
  padding: 0.333em 0.667em;
  border: 1px solid var(--line);
  background: var(--bg-card);
  border-radius: 0.4em;
  cursor: pointer;
  font-family: inherit;
  font-size: 0.8em;
  color: var(--ink-soft);
  white-space: nowrap;
}
.share-chip:hover { background: var(--bg); }
.share-chip.active {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}
.share-slider-row {
  display: flex;
  align-items: center;
  gap: 0.667em;
}
.share-slider {
  flex: 1;
  min-width: 0;
  accent-color: var(--ink);
}
.share-number-wrap {
  display: inline-flex;
  align-items: center;
  gap: 0.267em;
  flex-shrink: 0;
}
.share-number {
  width: 3.733em;
  padding: 0.267em 0.4em;
  font-family: 'Roboto Mono', monospace;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.share-number-suffix {
  color: var(--ink-muted);
  font-size: 0.867em;
}

/* Anneau jaune éphémère affiché à l'endroit du tap-to-focus (700ms). */
.bp-camera-focus-ring {
  position: fixed;
  width: 60px;
  height: 60px;
  border: 2px solid #ffcc00;
  border-radius: 50%;
  pointer-events: none;
  z-index: 10000;
  animation: bp-focus-ring 700ms ease-out forwards;
}
@keyframes bp-focus-ring {
  0%   { transform: scale(1.4); opacity: 0; }
  20%  { transform: scale(1);   opacity: 1; }
  100% { transform: scale(0.9); opacity: 0; }
}

/* Utilities pour basculer texte/icône et liens menu desktop/mobile.
   Par défaut (desktop) : on cache l'icône mobile et le lien "Autre". */
.nav-label-mobile-icon { display: none; }
.menu-only-mobile { display: none; }

/* Sélecteur de mois (‹, label, ›) : flex normal à l'intérieur de sa card. */
.bp-section-month {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8em;
}

/* Wrapper du sélecteur de mois (et ancre pour le todo-pad).
   Le wrapper est juste un `position: relative` sans flex : la card prend
   toute la largeur, et le `aside.todo-pad` se positionne en absolute
   à GAUCHE du wrapper via `right: calc(100% + ...)`. En dessous de 1400px,
   le todo-pad est caché ; la card prend toujours toute la largeur naturellement. */
.bp-todo-month-row {
  position: relative;
  margin-bottom: 1.067em; /* 16 / 15 */
}
.bp-todo-month-row > .bp-section-month-card {
  margin-bottom: 0; /* la marge est sur le wrapper */
  padding: 0.667em 1.067em;
}

/* Bascule Accueil vs Budget en mobile (≤540px) :
   - data-view="dashboard" (Accueil) : garde comptes + solde + à venir + outils.
     Cache : sélecteur d'instance, sélecteur de mois, "Ce mois-ci", tx passées.
   - data-view="budget"    (Budget)  : garde sélecteur + mois + Ce mois-ci + solde + à venir + passées.
     Cache : comptes, outils.
   Desktop reste inchangé : toutes les sections visibles. */
@media (max-width: 540px) {
  .shell[data-view="dashboard"] .bp-section-instance,
  .shell[data-view="dashboard"] .bp-section-month-card,
  .shell[data-view="dashboard"] .bp-section-month-stats,
  .shell[data-view="dashboard"] .bp-section-past { display: none; }
  .shell[data-view="budget"] .bp-section-accounts,
  .shell[data-view="budget"] .bp-section-tools { display: none; }

  /* Sélecteur d'instance compact : icônes au lieu de texte pour Personnel/Couple,
     label projet tronqué à 10 chars + …, bouton « + Projet » réduit à « + ».
     Sticky en haut pour que la personne ne perde pas son contexte au scroll.
     Pleine largeur : on déborde du padding-X du .shell (0.933em en mobile). */
  .bp-section-instance {
    position: sticky;
    top: 0;
    z-index: 10;
    margin: 0 -0.933em 1em -0.933em;
    padding: 0.4em 0.933em;
    background: var(--bg);
    border-bottom: 1px solid var(--line-soft);
  }
  /* Quand la bannière offline/sync est visible, décale l'instance pour qu'elle
     sticky juste en-dessous (hauteur calculée : padding 2×0.533em + line-height
     1.4 × font-size 0.867em ≈ 2.14em). */
  html.bp-has-offline-banner .bp-section-instance {
    top: 2.2em;
  }
  .bp-section-instance .context-tabs {
    margin-bottom: 0;
    gap: 0.267em;
    justify-content: space-evenly;
  }
  /* Séparateur invisible inséré par JS pour forcer un wrap au milieu et
     équilibrer les deux lignes (cf. _context_tabs.php). Hauteur 0 + base 100 %
     = on consomme toute la ligne sans rien afficher. */
  .bp-section-instance .context-tabs .tab-break {
    flex-basis: 100%;
    height: 0;
    margin: 0;
    padding: 0;
  }
  /* Chaque tab garde sa largeur naturelle. Le space-evenly du conteneur
     répartit l'espace restant uniformément (item-item ET item-bord) pour
     couvrir toute la largeur. Quand ça wrappe, chaque ligne reste balancée
     — pas de cas où 2 items collés aux extrémités avec un trou au milieu. */
  .bp-section-instance .tab {
    flex: 0 0 auto;
    padding: 0.5em 0.667em;
  }
  /* Bascule : on cache le texte long, on montre l'icône (Personnel/Couple)
     ou le label court (projets). */
  .bp-section-instance .tab-personal .tab-text,
  .bp-section-instance .tab-couple .tab-text,
  .bp-section-instance .tab-project .tab-text,
  .bp-section-instance .tab-add .tab-text { display: none; }
  .bp-section-instance .tab-personal .tab-icon,
  .bp-section-instance .tab-couple .tab-icon,
  .bp-section-instance .tab-add .tab-icon,
  .bp-section-instance .tab-project .tab-text-short { display: inline; }
  /* On retire le point coloré à gauche en mobile : l'icône / le label court
     suffit à identifier l'onglet. */
  .bp-section-instance .tab-dot { display: none; }
  /* Sur projet : on garde le dot coloré + le label court. */
  .bp-section-instance .tab-project { flex: 0 1 auto; }
  /* Bouton « + » plus compact que les tabs principales. */
  .bp-section-instance .tab-add { flex: 0 0 auto; font-weight: 600; }

  /* Solde du couple : montant principal divisé par 2 en mobile (gain de place). */
  .bp-section-couple-balance .balance-amount { font-size: 1.4em; }
}

@media (max-width: 540px) {
  /* En-tête plus compact sur mobile : titre réduit, tagline masquée
     (gain d'une ligne), nav plus serrée. Le voilier en filigrane est masqué
     car il gardait trop d'espace gauche. */
  .topbar { margin-bottom: 1em; padding-bottom: 0.667em; gap: 1em; }
  .topbar-top { gap: 0.533em; margin-left: 0; padding-top: 0; }
  /* Bascule mobile : Accueil devient une icône 🏠, on cache son texte.
     Liens secondaires (.menu-hide-mobile) cachés, lien "Autre" exposé. */
  .nav-label-desktop-text { display: none; }
  .nav-label-mobile-icon { display: inline; font-size: 1.2em; line-height: 1; }
  .menu-hide-mobile { display: none; }
  .menu-only-mobile { display: revert; }
  .brand { gap: 0.4em; }
  /* Inline-flex pour aligner le voilier ::after au centre vertical du glyphe
     (Tangerine a une x-height minuscule, vertical-align:middle aligne trop bas). */
  .brand-mark { font-size: 3.744em; display: inline-flex; align-items: center; gap: 0.15em; } /* 2.4 × 1.2 × 1.3 */
  .brand-mark::before { display: none; }
  /* Voilier à droite du titre, hauteur 1em = même hauteur que le texte.
     translateY -10% pour compenser le centre optique de Tangerine. */
  .brand-mark::after {
    content: '';
    width: 1em;
    height: 1em;
    background: url(../icons/logo-appareillage.svg?v=4) no-repeat center / contain;
    transform: translateY(-10%);
  }
  .brand-sub { font-size: 0.667em; letter-spacing: 0.12em; } /* 10/15 */
  .brand-tagline { display: none; }
  .nav-link { padding: 0.4em 0.667em; font-size: 1.12em; } /* 0.8 × 1.4 */
  /* Cog ⚙ : même métrique que le hamburger ☰ et 🏠 pour l'alignement vertical. */
  .nav-link-icon { font-size: 1.2em; padding: 0.4em 0.667em; line-height: 1; }
  /* Indicateur de page active : blanc avec border subtil sur mobile,
     plutôt que l'inversion foncée du desktop. box-shadow inset au lieu de
     border pour ne pas décaler le layout au switch. */
  .nav-link.active {
    background: var(--bg-card);
    color: var(--ink);
    box-shadow: inset 0 0 0 1px var(--line-soft);
    font-weight: 600;
  }
  /* Mobile : la nav prend toute la largeur dispo, items répartis également. */
  .topbar-actions {
    gap: 0.267em;
    row-gap: 0.333em;
    justify-content: space-between;
    width: 100%;
  }
  .user-pill { padding: 0.333em 0.833em 0.333em 0.333em; font-size: 0.8em; }
  .avatar { width: 2.2em; height: 2.2em; font-size: 0.667em; }
}

@media (max-width: 380px) {
  .user-pill span { display: none; }
  .user-pill { padding: 0.231em; } /* 3 / 13 */
}

/* ===== Tabs de contexte ===== */
.context-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.267em; /* 4 / 15 */
  margin-bottom: 1.6em; /* 24 / 15 */
  padding: 0.267em; /* 4 / 15 */
  /*background: var(--bg-soft);*/
  border-radius: 0.8em; /* 12 / 15 */
}

/* .tab : font-size 14, props / 14 */
.tab {
  display: flex;
  align-items: center;
  gap: 0.571em; /* 8 / 14 */
  padding: 0.714em 1.143em; /* 10 16 / 14 */
  border: none;
  background: transparent;
  border-radius: 0.571em; /* 8 / 14 */
  font-size: 0.933em; /* 14 / 15 */
  font-weight: 500;
  color: var(--ink-soft);
  white-space: nowrap;
  transition: all 0.15s ease;
}
.tab:hover { color: var(--ink); }
.tab.active {
  background: var(--bg-card);
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 0 0 1px var(--line);
}

.tab-dot { width: 0.533em; height: 0.533em; border-radius: 50%; } /* 8/15 */
.tab-personal .tab-dot { background: var(--personal); }
.tab-couple .tab-dot { background: var(--shared); }
.tab-project .tab-dot { background: var(--project); }

.tab-add { color: var(--ink-muted); font-weight: 400; }
.tab-add:hover { color: var(--ink); background: rgba(0,0,0,0.04); }

/* Bascule label / icône / short en desktop : on garde le label long, icônes
   et label court sont cachés. */
.tab .tab-icon,
.tab .tab-text-short { display: none; }

/* ===== Grid ===== */
.grid {
  display: grid;
  grid-template-columns: 1fr 25.333em; /* 380 / 15 */
  gap: 1.6em; /* 24 / 15 */
}
@media (max-width: 980px) {
  .grid { grid-template-columns: 1fr; }
}

/* ===== Saisie rapide ===== */
.quick-entry {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 1.067em; /* 16 / 15 */
  padding: 1.333em; /* 20 / 15 */
  margin-bottom: 1.333em; /* 20 / 15 */
  position: relative;
}

/* .qe-close : font-size 22, props / 22 */
.qe-close {
  display: none;
  position: absolute;
  top: 0.455em; /* 10 / 22 */
  right: 0.545em; /* 12 / 22 */
  width: 1.636em; /* 36 / 22 */
  height: 1.636em;
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--ink);
  border: none;
  font-size: 1.467em; /* 22 / 15 */
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}
.qe-close:hover { background: var(--line); }

/* ============================================================
   SAISIE RAPIDE — Refonte design (purement visuelle, JS inchangé)
   ============================================================ */

/* Visibilité progressive par État */
#qeBox[data-qe-step="1"] .qe-step-2-only,
#qeBox[data-qe-step="1"] .qe-step-3-only,
#qeBox[data-qe-step="1"] .qe-step-23-only { display: none !important; }
#qeBox[data-qe-step="2"] .qe-step-1-only,
#qeBox[data-qe-step="2"] .qe-step-3-only { display: none !important; }
#qeBox[data-qe-step="3"] .qe-step-1-only,
#qeBox[data-qe-step="3"] .qe-step-2-only { display: none !important; }

/* Filtrage Dépense / Revenu : on cache la grille du type non actif */
#qeBox[data-qe-type="expense"] .qe-cats-grid[data-cats-type="income"],
#qeBox[data-qe-type="income"]  .qe-cats-grid[data-cats-type="expense"] { display: none !important; }

/* Mode Retrait : on cache toute la machinerie cat (grilles + step 3 régulier)
   et on montre uniquement le panneau Retrait. Hors retrait : panneau caché. */
#qeBox[data-qe-type="withdrawal"] .qe-cats-grid,
#qeBox[data-qe-type="withdrawal"] .qe-cat-parent,
#qeBox[data-qe-type="withdrawal"] #qeStep3 { display: none !important; }
#qeBox:not([data-qe-type="withdrawal"]) #qeStep3Withdrawal { display: none !important; }
#qeBox[data-qe-type="withdrawal"] #qeStep3Withdrawal {
  display: flex;
  flex-direction: column;
  gap: 0.8em;
  animation: qeFadeIn 0.2s ease-out;
}

/* Fade-in léger sur les blocs qui apparaissent */
#qeBox[data-qe-step] .qe-cats-grid,
#qeBox[data-qe-step] .qe-cat-parent,
#qeBox[data-qe-step] #qeStep3 {
  animation: qeFadeIn 0.2s ease-out;
}
@keyframes qeFadeIn {
  from { opacity: 0; transform: translateY(-2px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Header : toggle Dépense/Revenu (à gauche) + actions photo/galerie/micro (à droite) */
.qe-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.875em;
  padding: 0 0.125em;
  gap: 0.75em;
}

.qe-top-toggle {
  display: inline-flex;
  background: var(--bg-softer);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  padding: 0.1875em;
  flex-shrink: 0;
}
.qe-top-toggle-btn {
  padding: 0.3125em 0.875em;
  background: transparent;
  border: none;
  border-radius: 999px;
  font-size: 0.6875em;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  cursor: pointer;
  transition: all 0.15s ease;
  text-transform: uppercase;
  font-family: inherit;
}
.qe-top-toggle-btn:hover { color: var(--ink-soft); }
.qe-top-toggle-btn.active {
  background: var(--primary);
  color: var(--bg);
  box-shadow: 0 1px 2px rgba(107,74,122,0.2);
}
.qe-top-toggle-btn.active[data-type="income"] { background: var(--primary); }

.qe-actions {
  display: flex;
  gap: 0.25em;
  flex-shrink: 0;
}
.qe-icon-btn {
  width: 2em;
  height: 2em;
  border-radius: 0.4em;
  background: var(--bg-softer);
  border: 1px solid var(--line-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--ink-soft);
  transition: all 0.15s ease;
  font-family: inherit;
}
.qe-icon-btn:hover {
  background: var(--bg-soft);
  color: var(--ink);
  border-color: var(--line);
}
.qe-icon-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.qe-icon-btn svg { width: 1em; height: 1em; }
.qe-icon-btn.recording { background: var(--neg); color: #fff; border-color: var(--neg); }

/* Grille de catégories — compacte, auto-fill */
.qe-cats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(4.5em, 1fr));
  gap: 0.375em;
}

.cat-tile {
  background: var(--bg-softer);
  border: 1px solid transparent;
  border-radius: 0.5em;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 0.25em 0.375em 0.25em; /* mini espace haut/bas autour icône+label */
  transition: all 0.12s ease;
  min-height: 0;
  font-family: inherit;
}
.cat-tile:hover {
  background: var(--bg-soft);
  border-color: var(--line);
}
.cat-tile:active { transform: scale(0.97); }
.cat-tile.active {
  background: var(--primary);
  border-color: var(--primary);
}
.cat-tile.active .cat-tile-label { color: var(--bg); }

.cat-tile-icon {
  font-size: 1.25em;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cat-tile-icon img {
  width: 1.25em;
  height: 1.25em;
  display: block;
}
.cat-tile-label {
  font-size: 0.625em;
  font-weight: 500;
  color: var(--ink-soft);
  text-align: center;
  line-height: 1.2;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cat-tile-more {
  background: transparent;
  border: 1px dashed var(--line);
}
.cat-tile-more:hover { background: var(--bg-softer); }
.cat-tile-more .cat-tile-icon { color: var(--ink-muted); }

/* Bouton « Aucune sous-cat » : occupe sa propre ligne dans la grille,
   aligné à gauche, à la largeur de son contenu (pas une tuile pleine).
   Visuellement discret pour signaler que c'est une action différente. */
.cat-tile-skip {
  grid-column: 1 / -1;
  justify-self: start;
  flex-direction: row;
  width: auto;
  gap: 0.4em;
  padding: 0.4em 0.75em;
  background: transparent;
  border: 1px dashed var(--line-soft);
  color: var(--ink-muted);
}
.cat-tile-skip:hover { background: var(--bg-softer); border-color: var(--line); }
.cat-tile-skip .cat-tile-icon { font-size: 1em; }
.cat-tile-skip .cat-tile-label { font-size: 0.75em; }

/* Raccourcis vers les autres pages de création (récurrence, transfert, etc.)
   Visibles uniquement en step 1 et hors mode Retrait. */
.qe-shortcuts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em;
  margin-top: 0.8em;
  padding-top: 0.8em;
  border-top: 1px dashed var(--line-soft);
  font-size: 0.9em;
}
.qe-shortcut-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.4em 0.8em;
  background: var(--bg-softer);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  color: var(--ink-soft);
  font-size: 0.867em;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.qe-shortcut-link:hover {
  background: var(--bg-soft);
  color: var(--ink);
}
.qe-shortcut-icon { font-size: 1.1em; }
#qeBox:not([data-qe-step="1"]) .qe-shortcuts,
#qeBox[data-qe-type="withdrawal"] .qe-shortcuts { display: none; }

/* Breadcrumb catégorie parent (États 2 et 3) */
.qe-cat-parent {
  display: flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.5em 0.75em;
  background: var(--bg-softer);
  border: 1px solid var(--line-soft);
  border-radius: 0.5em;
  cursor: pointer;
  margin-bottom: 0.625em;
  width: 100%;
  text-align: left;
  transition: all 0.12s ease;
  font-family: inherit;
}
.qe-cat-parent:hover { background: var(--bg-soft); }
.qe-cat-parent-back {
  color: var(--ink-muted);
  font-size: 0.875em;
}
.qe-cat-parent-icon {
  font-size: 1em;
  display: flex;
  align-items: center;
  line-height: 1;
}
.qe-cat-parent-icon img {
  width: 1em;
  height: 1em;
}
.qe-cat-parent-label {
  font-weight: 600;
  font-size: 0.8125em;
  color: var(--ink);
}
.qe-cat-parent-sub {
  margin-left: auto;
  font-size: 0.6875em;
  color: var(--ink-muted);
  font-style: italic;
}
.qe-cat-parent-sub:not(:empty)::before { content: '· '; }

/* ===== État 3 : formulaire complet =====
   Pas de flex parent + gap. Chaque section est wrappée dans .qe-section
   avec son propre margin-bottom — plus prévisible, plus modifiable, et
   compatible avec les vieux navigateurs. Cf. memory `feedback-section-wrapper-pattern`. */
#qeStep3 { display: block; }
/* Section wrapper : 1em de margin sous chaque section pour un espacement
   prévisible. Sélecteur dédoublé pour battre .form-field qui a sa propre
   margin-bottom — quand un élément est .form-field ET .qe-section, on garde
   1em (et pas le 1.067em de .form-field). */
.qe-section,
.form-field.qe-section { margin-bottom: 1em; }
/* Form-field nested dans une section : pas de margin propre, la section
   parent gère l'espacement. */
.qe-section > .form-field { margin-bottom: 0; }

/* Montant en hero */
.qe-amount-row {
  display: flex;
  align-items: baseline;
  gap: 0.5em;
  padding: 0.375em 0 0.625em 0;
  border-bottom: 1px solid var(--line-soft);
}
.qe-amount-currency {
  font-family: 'JetBrains Mono', monospace;
  font-size: 1.5em;
  color: var(--ink-muted);
  font-weight: 400;
}
.qe-amount-input {
  flex: 1;
  border: none;
  background: transparent;
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 2em;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.025em;
  outline: none;
  padding: 0;
}
.qe-amount-input::placeholder {
  color: var(--ink-muted);
  font-weight: 400;
}

/* Labels meta uppercase.
   Le sélecteur dédoublé `.form-field label.qe-meta-label` est là pour gagner
   la guerre de spécificité contre `.form-field label` (sinon les labels Marchand
   /Description/Notes héritent du style générique et ne sont pas identiques aux
   labels Montant/Date/Contexte/Compte/Déjà passée). */
.qe-meta-label,
.form-field label.qe-meta-label {
  font-size: 0.625em;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  display: block;
  margin-bottom: 0.4375em;
  /* margin-top retiré : l'air entre sections vient maintenant du
     margin-bottom de .qe-section parent, pas du label. */
}

/* Chips unifiés (contexte, comptes, sec merchant). Pill arrondi.
   Une seule classe .qe-chip — utilisée pour tous les items « cliquables »
   en pastille horizontale (contexte, méthodes de paiement, intermédiaires).
   inline-flex + gap pour permettre des spans internes (ex : name + balance
   sur les chips méthode). */
.qe-chips,
.qe-ctx-chips,
.qe-method-chips {
  display: flex;
  gap: 0.3125em;
  flex-wrap: wrap;
}
.qe-chip {
  padding: 0.375em 0.75em;
  background: var(--bg-softer);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  font-size: 0.75em;
  font-weight: 500;
  color: var(--ink-soft);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.3125em;
  transition: all 0.15s ease;
  font-family: inherit;
}
.qe-chip:hover {
  border-color: var(--ink-muted);
  color: var(--ink);
}
.qe-chip.active {
  background: var(--primary);
  color: var(--bg);
  border-color: var(--primary);
}

/* Toggle générique (payeur, split ratio) */
.qe-toggle {
  display: inline-flex;
  background: var(--bg-softer);
  border: 1px solid var(--line-soft);
  border-radius: 0.4em;
  padding: 0.1875em;
}
.qe-toggle-btn {
  padding: 0.375em 0.75em;
  background: transparent;
  border: none;
  border-radius: 0.25em;
  font-size: 0.6875em;
  font-weight: 500;
  color: var(--ink-soft);
  cursor: pointer;
  transition: all 0.15s ease;
  font-family: inherit;
}
.qe-toggle-btn.active {
  background: var(--bg-card);
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(26,23,20,0.06);
  font-weight: 600;
}

/* Payeur (label au-dessus du toggle) */
.qe-payer-row {
  display: flex;
  flex-direction: column;
  gap: 0.25em;
}

/* Dépense partagée (switch) */
.qe-shared-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  padding: 0.625em 0.875em;
  background: var(--bg-softer);
  border: 1px solid var(--line-soft);
  border-radius: 0.5em;
  flex-wrap: wrap;
}
.qe-shared-toggle,
.form-field label.qe-shared-toggle { /* override .form-field label display:block */
  display: flex;
  align-items: center;
  gap: 0.5em;
  cursor: pointer;
  font-size: 0.75em;
  font-weight: 500;
  color: var(--ink);
}
/* Le texte du label (1er span, pas le qe-switch) à 0.8× pour ne pas
   prendre trop de place. Le qe-switch garde sa taille via son propre em
   relatif au label parent.
   text-box-trim + text-box-edge = recadre la box au cap-height (haut) et
   alphabetic baseline (bas), donc le centrage flex match exactement le
   visuel — fix le décalage causé par l'uppercase. line-height:1 reste là
   en fallback pour les navigateurs sans text-box-trim. */
.qe-shared-toggle > span:not(.qe-switch) {
  font-size: 0.8em;
  line-height: 1;
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
  font-weight: 300;
  text-transform: none;
  letter-spacing: 0;
}
.qe-switch {
  position: relative;
  display: inline-block;
  width: 2em;
  height: 1.125em;
  flex-shrink: 0;
}
.qe-switch input { display: none; }
.qe-switch-slider {
  position: absolute;
  cursor: pointer;
  top: 0; left: 0; right: 0; bottom: 0;
  background: var(--line);
  border-radius: 999px;
  transition: 0.2s;
}
.qe-switch-slider::before {
  content: '';
  position: absolute;
  height: 0.875em;
  width: 0.875em;
  left: 0.125em;
  top: 0.125em;
  background: var(--bg-card);
  border-radius: 50%;
  transition: 0.2s;
}
.qe-switch input:checked + .qe-switch-slider { background: var(--primary); }
.qe-switch input:checked + .qe-switch-slider::before { transform: translateX(0.875em); }

/* Variante large : pour les toggles "critiques" (skip_couple_balance par ex.). */
.qe-switch.qe-switch-lg {
  width: 3.2em;
  height: 1.8em;
}
.qe-switch.qe-switch-lg .qe-switch-slider::before {
  height: 1.45em;
  width: 1.45em;
  left: 0.175em;
  top: 0.175em;
}
.qe-switch.qe-switch-lg input:checked + .qe-switch-slider::before { transform: translateX(1.4em); }

/* Toggle proéminent (label gras + sous-texte explicatif + switch large) — utilisé
   pour les overrides critiques que l'user doit voir clairement (ex: "Ne pas
   affecter le solde couple"). */
.bp-skip-couple-section {
  margin-top: 0.5em;
  padding: 0.8em 1em;
  background: var(--bg-soft);
  border: 1px solid var(--line-soft);
  border-radius: 0.5em;
}
.bp-prominent-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  cursor: pointer;
  margin: 0;
}
.bp-prominent-toggle-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.2em;
}
.bp-prominent-toggle-text strong {
  font-size: 1em;
  color: var(--ink);
  font-weight: 600;
}
.bp-prominent-toggle-help {
  font-size: 0.8em;
  color: var(--ink-muted);
  line-height: 1.4;
  font-weight: 400;
}

.qe-share-ratio-toggle { display: inline-flex; }
/* Les boutons du share-ratio et de Déductible ne sont PAS uppercase
   (le top-toggle générique l'est pour Dépense/Retrait/Revenu, mais ici
   on veut « 50 / 50 », « Pas déductible », « Santé », etc. lisibles tels quels).
   Letter-spacing aussi enlevé pour s'aligner avec les voisins (chips, switches)
   qui n'ont pas de letter-spacing. */
.qe-share-ratio-toggle .qe-top-toggle-btn,
#qeDeductionToggle .qe-top-toggle-btn { text-transform: none; }
#qeStep3 .qe-top-toggle-btn { letter-spacing: 0; }
#qeBox[data-qe-shared="0"] .qe-share-ratio-toggle { display: none; }

/* Ligne « Personne qui paie » : flex obligatoire en CSS (pas inline) parce
   que qeApplyContextVisibility set `style.display = ''` pour afficher →
   efface l'inline → fallback CSS. Wrap autorisé pour permettre l'éclatement
   sur écran étroit. */
[data-qe-shared-row] {
  display: flex;
  /* row-gap (vertical quand ça wrap) plus serré que column-gap (horizontal). */
  gap: 0.3125em 1.7em;
  align-items: center;
  flex-wrap: wrap;
}

/* Inner spans des chips (name + solde sur la même ligne, sur les chips méthode).
   Le chip lui-même utilise .qe-chip — ces styles ne concernent que le contenu interne. */
.qe-chip-name { font-weight: 500; }
.qe-chip-bal {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  opacity: 0.65;
}
.qe-method-empty {
  padding: 0.625em 0;
  font-size: 0.75em;
  color: var(--ink-muted);
  font-style: italic;
}
.qe-method-empty a { text-decoration: underline; color: var(--ink); }

/* Inputs texte */
.qe-text-input {
  width: 100%;
  padding: 0.5em 0.75em;
  background: var(--bg-softer);
  border: 1px solid var(--line-soft);
  border-radius: 0.4em;
  font-family: inherit;
  font-size: 0.8125em;
  color: var(--ink);
  outline: none;
  transition: all 0.15s ease;
}
.qe-text-input:focus {
  border-color: var(--ink-muted);
  background: var(--bg-card);
}
.qe-text-input::placeholder { color: var(--ink-muted); }
textarea.qe-text-input {
  min-height: 2.5em;
  resize: vertical;
}

/* Submit row */
.qe-submit-row {
  display: flex;
  align-items: center;
  gap: 0.625em;
  padding-top: 0.25em;
}
.qe-date {
  flex: 0 0 auto;
  padding: 0.5em 0.625em;
  background: var(--bg-softer);
  border: 1px solid var(--line-soft);
  border-radius: 0.4em;
  font-family: inherit;
  font-size: 0.75em;
  color: var(--ink);
  outline: none;
}
.qe-submit-btn {
  flex: 1;
  padding: 0.625em 1em;
  background: var(--primary);
  color: var(--bg);
  border: none;
  border-radius: 0.4em;
  font-family: inherit;
  font-size: 0.875em;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
}
.qe-submit-btn:hover { background: var(--primary-soft); }
.qe-submit-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* Sur petit écran, date + submit empilés */
@media (max-width: 480px) {
  .qe-submit-row { flex-direction: column; align-items: stretch; }
  .qe-submit-row .qe-submit-btn { width: 100%; }
}

/* ===== Sections ===== */
.section-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 1.6em;
  margin-bottom: 0.933em; /* 14 / 15 */
  padding: 0 0.267em; /* 0 4 / 15 */
}
/* .section-title h2 : font-size 20, props / 20 */
.section-title h2 {
  font-family: 'Google Sans Flex', system-ui, sans-serif;
  font-weight: 500;
  font-size: 1.333em; /* 20 / 15 */
  letter-spacing: -0.01em;
}
/* .section-title .meta : font-size 12 */
.section-title .meta {
  font-size: 0.8em; /* 12 / 15 */
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* ===== Stats du mois ===== */
.month-stats {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 1.067em; /* 16 / 15 */
  padding: 1.333em; /* 20 / 15 */
  margin-bottom: 1.333em; /* 20 / 15 */
}

.month-totals {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 1.067em; /* 16 / 15 */
  margin-bottom: 1.333em; /* 20 / 15 */
}
@media (max-width: 540px) {
  .month-totals { grid-template-columns: 1fr 1fr; }
  /* Pas de span 2 sur le dernier — sinon avec 4 items, les 2 derniers
     finissent chacun sur leur ligne au lieu d'être côte-à-côte. */
}

/* Projets actifs du mois — ligne typographique inline.
   « Voyage 245 $ · Réno 1 200 $ (+12 prév) · … »
   Compact (~1.5em haut), wrap si overflow, chaque item cliquable.
   L'underline pointillé est permanent (affordance de lien) ;
   sur hover on bascule en solide + intensifie la couleur. */
.month-projects-line {
  margin-top: -0.267em; /* -4 / 15, recolle au bloc Bilan au-dessus */
  margin-bottom: 1.867em; /* 28 / 15 */
  font-size: 0.867em; /* 13 / 15 */
  line-height: 1.5;
  color: var(--ink-muted);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.308em 0.462em; /* 4 / 13, 6 / 13 */
}
.month-projects-line .mpl-sep {
  color: var(--ink-muted);
  opacity: 0.5;
  user-select: none;
}
.month-projects-line .mpl-item {
  color: var(--ink);
  text-decoration: none;
  display: inline-flex;
  align-items: baseline;
  gap: 0.308em; /* 4 / 13 */
  border-bottom: 0.077em dotted var(--ink-muted); /* 1 / 13 */
  transition: border-bottom-style 0.12s, border-bottom-color 0.12s;
}
.month-projects-line .mpl-item:hover {
  border-bottom-style: solid;
  border-bottom-color: var(--ink);
}
.month-projects-line .mpl-label {
  font-weight: 500;
}
.month-projects-line .mpl-amount {
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.month-projects-line .mpl-projected {
  font-style: italic;
  color: var(--ink-muted);
  font-size: 0.846em; /* 11 / 13 */
}

/* Force le contenu à se coller en haut (les <button> centrent verticalement
   par défaut, ce qui débalance les blocs sans .delta vs ceux avec .delta) */
.total-block {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
}
/* .total-block .label : font-size 9, props / 9 */
.total-block .label {
  font-size: 0.8em;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin-bottom: 0.2em;
  font-weight: 500;
}
/* .total-block .amount : font-size 22, props / 22 */
.total-block .amount {
  font-family: 'Google Sans Flex', system-ui, sans-serif;
  font-size: 1.467em; /* 22 / 15 */
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
/* .total-block .amount .cents : font-size 16, herité parent 22 → 16/22 */
.total-block .amount .cents { font-size: 0.727em; color: var(--ink-muted); }
.total-block .amount.pos { color: var(--pos); }
/* .total-block .delta : font-size 11, props / 11 */
.total-block .delta {
  font-family: 'Roboto Mono', monospace;
  font-size: 0.733em; /* 11 / 15 */
  margin-top: 0.182em; /* 2 / 11 — collé au montant */
}
.delta.up { color: var(--neg); }
.delta.down { color: var(--pos); }

/* ===== Onglets Catégories / Marchands (au-dessus de .cat-list) ===== */
.cat-merchant-tabs {
  display: flex;
  gap: 0.4em;
  margin-bottom: 0.8em;
  flex-wrap: wrap;
}
.cm-tab {
  padding: 0.4em 0.9em;
  background: transparent;
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  color: var(--ink-muted);
  font-size: 0.867em;
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
}
.cm-tab.active {
  background: var(--primary);
  color: var(--bg);
  border-color: var(--primary);
}

/* ===== Liste catégories : 2 colonnes desktop, 1 colonne mobile ===== */
.cat-list {
  column-count: 2;
  column-gap: 2.667em; /* 40 / 15 */
}

@media (max-width: 720px) {
  .cat-list {
    column-count: 1;
  }
}

/* Un groupe = catégorie parent + ses enfants, ne se sépare jamais. */
.cat-group {
  break-inside: avoid;
  page-break-inside: avoid;
  -webkit-column-break-inside: avoid;
  display: block;
  margin-bottom: 0.4em; /* 6 / 15 */
}

.cat-row {
  display: grid;
  grid-template-columns: 1.6em 1fr auto; /* 24 / 15 */
  gap: 0.667em; /* 10 / 15 */
  align-items: baseline;
  padding: 0.3em 0;
  border-bottom: 1px solid #dedede;
}
.cat-row[data-cat-id] { cursor: pointer; }
.cat-row[data-cat-id]:hover .cat-name { text-decoration: underline; }

.cat-row--child {
  padding-left: 1.867em; /* 28 / 15 */
  padding-top: 0;
  padding-bottom: 0;
  border-bottom: none;
}

/* Première sous-cat d'un groupe : un peu d'air en haut pour la séparer du parent. */
.cat-row:not(.cat-row--child) + .cat-row--child {
  padding-top: 0.4em;
}

/* La dernière sous-catégorie d'un groupe reprend la border bottom. */
.cat-group .cat-row--child:last-child {
  padding-bottom: 0.667em; /* 10 / 15 */
  border-bottom: 1px solid #dedede;
}

/* .cat-icon : font-size 16, props / 16 */
.cat-icon {
  font-size: 1.067em; /* 16 / 15 */
  line-height: 1;
}

/* .cat-row--child .cat-icon : font-size 13 */
.cat-row--child .cat-icon {
  font-size: 0.867em; /* 13 / 15 */
  opacity: 0.6;
}

.cat-name-wrap {
  display: flex;
  align-items: baseline;
  gap: 0.533em; /* 8 / 15 */
  min-width: 0;
}

/* .cat-name : font-size 14 */
.cat-name {
  font-size: 0.933em; /* 14 / 15 */
  font-weight: 500;
}

/* .cat-row--child .cat-name : font-size 13 */
.cat-row--child .cat-name {
  font-weight: 400;
  font-size: 0.867em; /* 13 / 15 */
  color: var(--ink-soft);
}

/* .cat-meta : font-size 11 */
.cat-meta {
  font-size: 0.733em; /* 11 / 15 */
  color: var(--ink-muted);
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
}

/* .cat-amount : font-size 14 */
.cat-amount {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  font-size: 0.933em; /* 14 / 15 */
}

/* .cat-row--child .cat-amount : font-size 13 */
.cat-row--child .cat-amount {
  font-weight: 400;
  font-size: 0.867em; /* 13 / 15 */
  color: var(--ink-soft);
}

/* ===== Transactions ===== */
.tx-list {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 1.067em; /* 16 / 15 */
  overflow: hidden;
}

/* --- Bloc "À venir" --- */
.tx-upcoming {
  background: linear-gradient(to bottom, rgba(200,132,43,0.04) 0%, transparent 100%);
  padding-bottom: 0.533em; /* 8 / 15 */
}
.tx-upcoming-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.8em; /* 12 / 15 */
  padding: 0.933em 1.333em 0.667em 1.333em; /* 14 20 10 20 / 15 */
}
/* .tx-upcoming-title : font-size 14, props / 14 */
.tx-upcoming-title {
  font-family: 'Google Sans Flex', system-ui, sans-serif;
  font-style: italic;
  font-weight: 500;
  font-size: 0.933em; /* 14 / 15 */
}
.tx-upcoming-title::before {
  content: '↻';
  font-style: normal;
  margin-right: 0.429em; /* 6 / 14 */
}
/* .tx-upcoming-meta : font-size 12 */
.tx-upcoming-meta {
  font-family: 'Roboto Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.8em; /* 12 / 15 */
  color: var(--ink-muted);
}
.tx-upcoming .tx-row {
  opacity: 0.95;
  border-bottom: 1px dashed var(--line-soft);
}
.tx-upcoming .tx-row:last-child { border-bottom: none; }
.tx-upcoming .tx-amount.is-overdue { color: var(--neg); }
/* Message « rien dans 7 jours » : caché quand l'utilisateur expand à 1 mois */
.tx-upcoming[data-upcoming-expanded="1"] .tx-upcoming-empty-default { display: none; }

/* --- Séparateur de mois dans la liste des tx --- */
/* Bandeau pleine largeur : label centré encadré de deux lignes horizontales.
   Affiché au début et à chaque franchissement de frontière mensuelle quand
   on scroll dans le passé. */
.tx-month-sep {
  display: flex;
  align-items: center;
  gap: 1em; /* 15 / 15 */
  padding: 1.6em 1.333em 1em 1.333em; /* 24 20 15 20 / 15 */
  background: var(--bg);
}
.tx-month-sep::before,
.tx-month-sep::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--line);
}
.tx-month-sep-label {
  font-family: 'Newsreader', Georgia, serif;
  font-style: italic;
  font-size: 1.2em; /* 18 / 15 */
  font-weight: 500;
  color: var(--ink);
  letter-spacing: 0.02em;
  text-transform: lowercase;
  white-space: nowrap;
}

/* --- En-têtes de jour --- */
.tx-day-header {
  padding: 1.2em 1.333em 0.667em 1.333em; /* 18 20 10 20 / 15 */
  background: var(--bg-softer);
  border-bottom: 1px solid var(--line-soft);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
/* .tx-day-label : font-size 15 */
.tx-day-label {
  font-family: 'Google Sans Flex', system-ui, sans-serif;
  font-size: 1em; /* 15 / 15 */
  font-weight: 500;
  font-style: italic;
  color: var(--ink);
}
/* .tx-day-date : font-size 10, props / 10 */
.tx-day-date {
  margin-left: 1em; /* 10 / 10 */
  font-style: normal;
  font-weight: 500;
  font-size: 0.667em; /* 10 / 15 */
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-muted);
}
/* .tx-day-total : font-size 12 */
.tx-day-total {
  font-family: 'Roboto Mono', monospace;
  font-size: 0.8em; /* 12 / 15 */
  font-weight: 500;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* --- Lignes --- */
.tx-row {
  display: grid;
  grid-template-columns: 2.667em 1fr auto; /* 40 / 15 */
  gap: 0.933em; /* 14 / 15 */
  align-items: center;
  padding: 0.8em 1.333em; /* 12 20 / 15 */
  border-bottom: 1px solid var(--line-soft);
  transition: background 0.1s ease;
  color: inherit;
}
.tx-row:hover { background: var(--bg-soft); }
.tx-row:last-child { border-bottom: none; }

/* .tx-icon : font-size 16, props / 16 */
.tx-icon {
  width: 2.5em; /* 40 / 16 */
  height: 2.5em;
  border-radius: 0.625em; /* 10 / 16 */
  display: flex; align-items: center; justify-content: center;
  font-size: 1.067em; /* 16 / 15 */
  background: var(--bg-soft);
  flex-shrink: 0;
}
.tx-info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.267em; /* 4 / 15 */
}
/* .tx-title : font-size 14, props / 14 */
.tx-title {
  font-size: 0.933em; /* 14 / 15 */
  font-weight: 500;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* .tx-subtitle : description en sous-ligne quand marchand + description coexistent */
.tx-subtitle {
  font-size: 0.8em; /* 12 / 15 */
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* tx-title-line : marchand + description sur la même ligne (desktop),
   séparés par "·". Sur mobile (<48em), passe sur deux lignes : marchand
   en haut (proéminent), description en dessous (plus petite). */
.tx-title-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4em; /* 6 / 15 */
  line-height: 1.3;
  overflow: hidden;
}
.tx-title-line .tx-merchant {
  font-size: 0.933em; /* 14 / 15 */
  font-weight: 500;
  color: var(--ink);
}
.tx-title-line .tx-desc {
  font-size: 0.933em;
  font-weight: 400;
  color: var(--ink-soft);
}
.tx-title-line .tx-sep { color: var(--ink-muted); }
@media (max-width: 48em) {
  .tx-title-line { flex-direction: column; gap: 0.067em; }
  .tx-title-line .tx-sep { display: none; }
  .tx-title-line .tx-desc { font-size: 0.8em; }
}
/* .tx-meta : font-size 11, props / 11 */
.tx-meta {
  display: flex; gap: 0.727em; align-items: center; /* 8/11 */
  font-size: 0.733em; color: var(--ink-muted); /* 11/15 */
  flex-wrap: wrap;
}

/* .tx-tag : base commune à tous les tags dans .tx-meta (font-size = 1em) */
.tx-tag {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.1em 0.6em;
  border-radius: 0.4em;
  background: var(--bg-soft);
  font-weight: 500;
  font-size: 1em;
}
.tx-tag-shared { background: rgba(74,93,140,0.10); color: var(--shared); }
.tx-tag-personal { background: rgba(139,111,71,0.10); color: var(--personal); }
.tx-tag-project { background: rgba(107,74,122,0.10); color: var(--project); }
.tx-tag-deduct { background: rgba(45,106,79,0.12); color: var(--pos); }
.tx-tag-method { background: var(--bg-soft); color: var(--ink-muted); }
.tx-tag-method::before { content: '💳'; }
.tx-tag-matched { background: rgba(45,106,79,0.10); color: var(--pos); font-weight: 600; }

/* Items editor — nouveau bloc full chips (Contexte/Payeur/Partage/Déduction par item) */
.items-row-block {
    display: flex;
    flex-direction: column;
    gap: 0.4em;
    padding: 0.533em 0;
    border-top: 1px dashed var(--line-soft);
    margin-top: 0.4em;
}
.item-block-label {
    font-size: 0.667em;
    text-transform: uppercase;
    letter-spacing: 0.067em;
    color: var(--ink-muted);
    margin-bottom: 0.133em;
}
.items-row-block .qe-chips {
    flex-wrap: wrap;
    gap: 0.267em;
}
.items-row-block .qe-chip,
.items-row-block .qe-top-toggle-btn {
    font-size: 0.733em;
    padding: 0.267em 0.6em;
}
.item-payer-share-wrap {
    display: flex;
    flex-direction: column;
    gap: 0.267em;
    padding-left: 0.667em;
    border-left: 2px solid var(--line-soft);
}

/* Lock visuel quand le contexte/share parent est verrouillé par les items
   (contextes mixtes dans l'itémisation). */
[data-qe-disabled="1"] {
    pointer-events: none;
    opacity: 0.55;
    filter: grayscale(0.5);
}
[data-qe-locked="1"] .qe-meta-label { color: var(--ink-muted); }

/* Modal de picker générique (cat picker import, conversion tx en transfert, etc.) */
.stmt-cat-overlay {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.5);
    display: flex; align-items: center; justify-content: center;
    z-index: 10000; padding: 1em;
}
.stmt-cat-modal {
    background: var(--bg-card);
    border-radius: 0.667em;
    max-width: 32em; width: 100%; max-height: 80vh;
    display: flex; flex-direction: column;
    box-shadow: 0 0.667em 2em rgba(0,0,0,0.25);
}
.stmt-cat-modal-head {
    display: flex; align-items: center; gap: 0.667em;
    padding: 0.8em 1em; border-bottom: 1px solid var(--line-soft);
}
.stmt-cat-title { flex: 1; font-family: 'Google Sans Flex', sans-serif; font-weight: 500; font-size: 1.067em; }
.stmt-cat-back, .stmt-cat-close {
    background: transparent; border: none; cursor: pointer;
    font-family: inherit; color: var(--ink-muted);
    padding: 0.267em 0.533em; border-radius: 0.4em;
}
.stmt-cat-back { font-size: 0.933em; }
.stmt-cat-close { font-size: 1.467em; line-height: 1; }
.stmt-cat-back:hover, .stmt-cat-close:hover { background: var(--bg-soft); color: var(--ink); }
.stmt-cat-grid-wrap { overflow-y: auto; padding: 0.8em 1em; }
.stmt-cat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(6em, 1fr));
    gap: 0.533em;
}

.tx-tag-recurring,
.tx-tag-scheduled,
.tx-tag-planned {
  background: transparent;
  color: var(--ink-muted);
  padding: 0.091em 0.364em;
  font-weight: 400;
}
.tx-tag-recurring::before {
  content: '↻';
  margin-right: 0.182em;
}

/* .tx-paid : couleur uniquement, font-size hérité de .tx-tag */
.tx-paid {
  color: var(--ink-soft);
}
.tx-meta > .tx-paid:first-child::before { display: none; }

/* .tx-amount : font-size 15, props / 15 */
.tx-amount {
  font-family: 'Roboto Mono', monospace;
  font-size: 1em; /* 15 / 15 */
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.133em; /* 2 / 15 */
}
.tx-amount.income { color: var(--pos); }

/* --- Règlements --- */
.tx-row.tx-settlement { background: rgba(74,93,140,0.04); }
.tx-row.tx-settlement:hover { background: rgba(74,93,140,0.08); }
/* tx-settlement .tx-icon : font-size 20 override, on garde la taille de .tx-icon mais font-size change */
.tx-row.tx-settlement .tx-icon {
  background: rgba(74,93,140,0.12);
  color: var(--shared);
  font-size: 1.333em; /* 20 / 15 */
}
.tx-row.tx-settlement .tx-amount { color: var(--shared); }

/* --- Charger plus (sentinel) --- */
/* .tx-load-more : font-size 12 */
.tx-load-more {
  padding: 1.667em; /* 20 / 12 */
  text-align: center;
  font-size: 0.8em; /* 12 / 15 */
  color: var(--ink-muted);
  border-top: 1px solid var(--line-soft);
  font-style: italic;
}

/* ===== Sidebar ===== */
.sidebar > * + * { margin-top: 1.333em; } /* 20 / 15 */

/* Sidebar sticky en desktop (>= 980px). align-self: start évite que la grid
   étire la sidebar à la hauteur du main, ce qui casserait le sticky. */
@media (min-width: 980px) {
  .grid > .sidebar {
    position: sticky;
    top: 1em;
    align-self: start;
    max-height: calc(100vh - 2em);
    overflow-y: auto;
  }
}

.card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 1.067em; /* 16 / 15 */
  padding: 1.333em; /* 20 / 15 */
}

/* .card-title : font-size 16, props / 16 */
.card-title {
  font-family: 'Google Sans Flex', system-ui, sans-serif;
  font-size: 1.067em; /* 16 / 15 */
  font-weight: 500;
  margin-bottom: 0.875em; /* 14 / 16 */
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
/* .card-title .label : font-size 10, props / 10 */
.card-title .label {
  font-size: 0.625em; /* 10 / 16 (parent .card-title est 16) */
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-family: 'Google Sans Flex', sans-serif;
  font-weight: 500;
}
/* Variante inline du label (mois collé au titre, plutôt que pushed right). */
.card-title-inline-label {
  font-size: 0.625em;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-family: 'Google Sans Flex', sans-serif;
  font-weight: 500;
  margin-left: 0.4em;
  vertical-align: 0.2em;
}

.balance-display { text-align: center; padding: 0.933em 0; } /* 14/15 */
/* .balance-amount : font-size 42, props / 42 */
.balance-amount {
  font-family: 'Google Sans Flex', system-ui, sans-serif;
  font-size: 2.8em; /* 42 / 15 */
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.025em;
  line-height: 1;
}
.balance-amount.neg { color: var(--neg); }
.balance-amount.pos { color: var(--pos); }
.balance-amount.zero { color: var(--ink-muted); }
/* .balance-subtitle : font-size 13, props / 13 */
.balance-subtitle {
  font-size: 0.867em; /* 13 / 15 */
  color: var(--ink-soft);
  margin-top: 0.615em; /* 8 / 13 */
  font-style: italic;
  font-family: 'Google Sans Flex', sans-serif;
}
/* .balance-action : font-size 13, props / 13 */
.balance-action {
  display: block;
  width: 100%;
  margin-top: 1.231em; /* 16 / 13 */
  padding: 0.769em; /* 10 / 13 */
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 0.769em; /* 10 / 13 */
  font-size: 0.867em; /* 13 / 15 */
  font-weight: 500;
  color: var(--ink);
  text-align: center;
}
.balance-action:hover { background: var(--ink); color: var(--bg); border-color: var(--ink); }

.method-list { display: flex; flex-direction: column; gap: 0.667em; } /* 10/15 */
/* .method-row : font-size 13. Le :not(tr) est crucial : sur la vue Comptes
   desktop, on a aussi des <tr class="method-row"> dans le tableau ; appliquer
   display:flex là-bas casse le layout (chaque ligne dimensionne ses td
   indépendamment, plus de colonnes alignées entre comptes). */
.method-row:not(tr) {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.769em 0.923em; /* 10 12 / 13 */
  background: var(--bg-soft);
  border-radius: 0.769em; /* 10 / 13 */
  font-size: 0.867em; /* 13 / 15 */
}
.method-info { display: flex; align-items: center; gap: 0.769em; } /* 10/13 (méthod-row context 13) */
.method-icon { width: 1.846em; height: 1.231em; border-radius: 3px; flex-shrink: 0; } /* 24/13 16/13 ; border-radius hairline */
.method-icon.account { background: linear-gradient(135deg, #2d6a4f, #5a7a3e); }
.method-icon.credit { background: linear-gradient(135deg, #1a4178, #2d6dbe); }
.method-icon.line_of_credit { background: linear-gradient(135deg, #6b4a7a, #8c6a9d); }
.method-icon.cash { background: linear-gradient(135deg, #c8842b, #a23b3b); }
.method-icon.investment { background: linear-gradient(135deg, #1a7a5d, #3a8c7a); }
/* .method-name : font-size 13 */
.method-name { font-weight: 500; font-size: 0.867em; } /* 13/15 */
/* Badge "Conjoint" : pastille discrète à côté du nom du compte. Cohérent avec
   le style des tags secondaires (CELI/REER) mais avec une teinte couple. */
.method-joint-badge {
  display: inline-block;
  font-size: 0.667em;
  font-weight: 500;
  padding: 0.1em 0.5em;
  border-radius: 0.267em;
  background: rgba(74,93,140,0.12);
  color: var(--shared);
  letter-spacing: 0.04em;
  vertical-align: 0.15em;
  margin-left: 0.267em;
}
/* .method-balance : font-size 13 */
.method-balance {
  font-family: 'Roboto Mono', monospace;
  font-size: 0.867em; /* 13 / 15 */
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}
.method-balance.neg { color: var(--neg); }
.method-balance.pos { color: var(--pos); }

.upcoming-list { display: flex; flex-direction: column; gap: 0.8em; } /* 12/15 */
/* .upcoming-row : font-size 13, props / 13 */
.upcoming-row {
  display: grid;
  grid-template-columns: 2.462em 1fr auto; /* 32 / 13 */
  gap: 0.769em; /* 10 / 13 */
  align-items: center;
  font-size: 0.867em; /* 13 / 15 */
}
/* .upcoming-date : font-size 10, props / 10 */
.upcoming-date {
  font-family: 'Roboto Mono', monospace;
  font-size: 0.667em; /* 10 / 15 */
  color: var(--ink-muted);
  text-align: center;
  line-height: 1.2;
  text-transform: uppercase;
}
/* .upcoming-date strong : font-size 16, props / 16 */
.upcoming-date strong {
  display: block;
  font-size: 1.6em; /* 16 / 10 (parent .upcoming-date est 10) */
  color: var(--ink);
  font-family: 'Google Sans Flex', sans-serif;
  font-weight: 500;
}
.upcoming-name { font-weight: 500; }
/* .upcoming-meta : font-size 11, props / 11 */
.upcoming-meta { font-size: 0.733em; color: var(--ink-muted); margin-top: 0.182em; } /* 11/15 ; 2/11 */
/* .upcoming-amount : font-size 13 */
.upcoming-amount {
  font-family: 'Roboto Mono', monospace;
  font-size: 0.867em; /* 13 / 15 */
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}

/* ===== FAB Mobile ===== */
.mobile-fab {
  display: none;
  position: fixed;
  bottom: 1.333em; /* 20 / 15 */
  right: 1.333em; /* 20 / 15 */
  width: 3.733em; /* 56 / 15 */
  height: 3.733em;
  background: var(--ink);
  color: var(--bg);
  border: none;
  border-radius: 50%;
  box-shadow: 0 8px 24px rgba(0,0,0,0.18); /* shadow gardé en px (hairline-ish) */
  align-items: center;
  justify-content: center;
  z-index: 100;
}
.mobile-fab svg { width: 1.467em; height: 1.467em; } /* 22/15 */

/* ===== Back-to-top : bouton flottant bas-gauche, visible dès scrollY > 200 ===== */
.back-to-top {
  position: fixed;
  bottom: 1.333em; /* 20 / 15 — aligné verticalement avec le FAB */
  left: 1.333em;
  width: 2.933em; /* 44 / 15 — plus petit que le FAB pour rester discret */
  height: 2.933em;
  background: var(--ink);
  color: var(--bg);
  border: none;
  border-radius: 50%;
  box-shadow: 0 6px 18px rgba(0,0,0,0.16);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 100;
  opacity: 0.85;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.back-to-top:hover { opacity: 1; transform: translateY(-0.133em); } /* 2 / 15 */
.back-to-top[hidden] { display: none; }
.back-to-top svg { width: 1.2em; height: 1.2em; } /* 18 / 15 */
@media (max-width: 768px) {
  .mobile-fab { display: flex; }
  .quick-entry.collapsible { display: none; }
  .quick-entry.collapsible.open {
    display: block;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 101;
    border-radius: 1.067em 1.067em 0 0; /* 16 / 15 */
    box-shadow: 0 -10px 30px rgba(0,0,0,0.2);
    margin-bottom: 0;
    /* Hauteur stable entre step 1 (cat tiles) et step 2 (sub tiles) :
       le modal garde la même hauteur, le contenu plus petit a juste de
       l'espace en bas. Step 3 plus grand → scroll via overflow-y. */
    min-height: 60vh;
    max-height: 90vh;
    overflow-y: auto;
    /* Empêche tout débordement latéral d'un enfant mal contenu. */
    overflow-x: hidden;
    padding-top: 3.733em; /* 56 / 15 */
  }
  .quick-entry.collapsible.open .qe-close { display: flex; align-items: center; justify-content: center; }
  /* Defensive : tous les flex items (rows, toggles, chips) doivent pouvoir
     se rétrécir au lieu de pousser le parent. */
  .quick-entry.collapsible.open .qe-amount-row,
  .quick-entry.collapsible.open .qe-submit-row,
  .quick-entry.collapsible.open .qe-payer-row,
  .quick-entry.collapsible.open .qe-shared-row,
  .quick-entry.collapsible.open .qe-toggle { min-width: 0; max-width: 100%; }
  .quick-entry.collapsible.open .qe-text-input,
  .quick-entry.collapsible.open .qe-amount-input,
  .quick-entry.collapsible.open .qe-date { max-width: 100%; min-width: 0; }
  /* Toggles inline-flex (payeur, share 50/100) wrappent au besoin */
  .quick-entry.collapsible.open .qe-toggle { flex-wrap: wrap; }
}

/* ===== Forms génériques ===== */
.form-field { margin-bottom: 1.067em; } /* 16 / 15 */
/* .form-field label : font-size 12, props / 12 */
.form-field label {
  display: block;
  font-size: 0.8em; /* 12 / 15 */
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  margin-bottom: 0.5em; /* 6 / 12 */
  font-weight: 500;
}
/* inputs : font-size 14, props / 14 */
.form-field input[type=text],
.form-field input[type=number],
.form-field input[type=date],
.form-field input[type=password],
.form-field input[type=email],
.form-field input[type=tel],
.form-field input[type=url],
.form-field input[type=search],
.form-field select,
.form-field textarea {
  width: 100%;
  padding: 0.714em 0.857em; /* 10 12 / 14 */
  border: 1px solid var(--line);
  background: var(--bg-card);
  border-radius: 0.571em; /* 8 / 14 */
  font-family: inherit;
  font-size: 0.933em; /* 14 / 15 */
  color: var(--ink);
}
.form-field input:focus, .form-field select:focus, .form-field textarea:focus {
  outline: none;
  border-color: var(--ink);
}
.form-field textarea { resize: vertical; min-height: 5.714em; } /* 80 / 14 */

.form-row { display: flex; gap: 0.8em; } /* 12 / 15 */
.form-row > .form-field { flex: 1; }

/* .btn : font-size 14, props / 14 */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.429em; /* 6 / 14 */
  padding: 0.714em 1.286em; /* 10 18 / 14 */
  background: var(--ink);
  color: var(--bg);
  border: none;
  border-radius: 0.714em; /* 10 / 14 */
  font-size: 0.933em; /* 14 / 15 */
  font-weight: 600;
}
.btn:hover { background: #2d2925; }
.btn-secondary { background: var(--bg-soft); color: var(--ink); border: 1px solid var(--line); }
.btn-secondary:hover { background: var(--line-soft); }
.btn-danger { background: var(--neg); }
/* .btn-small : font-size 12, props / 12 */
.btn-small { padding: 0.5em 0.833em; font-size: 0.8em; } /* 6 10 / 12 ; 12/15 */

/* ===== Toast/notifs ===== */
/* .toast : font-size 14, props / 14 */
.toast {
  position: fixed;
  bottom: 6.429em; /* 90 / 14 */
  left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--bg);
  padding: 0.857em 1.429em; /* 12 20 / 14 */
  border-radius: 999px;
  font-size: 0.933em; /* 14 / 15 */
  font-weight: 500;
  z-index: 200;
  box-shadow: 0 8px 24px rgba(0,0,0,0.2);
  animation: toastFade 3s ease forwards;
}

/* ===== Toggle d'attribution Moi/Conjoint ===== */
/* .attr-toggle : font-size 12, props / 12 */
.attr-toggle {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-card);
  padding: 0.167em; /* 2 / 12 */
  font-size: 0.8em; /* 12 / 15 */
  font-weight: 500;
}
/* .attr-btn : font-size inherit du parent .attr-toggle = 12 */
.attr-btn {
  background: transparent;
  border: none;
  padding: 0.333em 1em; /* 4 12 / 12 */
  border-radius: 999px;
  color: var(--ink-muted);
  font-size: inherit;
  font-weight: inherit;
  font-family: inherit;
  transition: all 0.15s ease;
  cursor: pointer;
  white-space: nowrap;
}
.attr-btn:hover { color: var(--ink); }
.attr-btn.active {
  background: var(--ink);
  color: var(--bg);
}

/* ===== Affichage dual CAD + devise originale ===== */
.amt-main { display: inline; font-weight: inherit; }
/* .amt-orig : font-size 11, props / 11 */
.amt-orig {
  display: block;
  font-size: 0.733em; /* 11 / 15 */
  color: var(--ink-muted);
  font-style: italic;
  margin-top: 0.091em; /* 1 / 11 */
}
.tx-row .amt-orig { text-align: right; }

.toast.error { background: var(--neg); }
.toast.success { background: var(--pos); }
@keyframes toastFade {
  0% { opacity: 0; transform: translate(-50%, 20px); }
  10%, 80% { opacity: 1; transform: translate(-50%, 0); }
  100% { opacity: 0; transform: translate(-50%, -10px); }
}

/* ===== Modal ===== */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(26,23,20,0.5);
  z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: 1.333em; /* 20 / 15 */
}
.modal {
  background: var(--bg-card);
  border-radius: 1.067em; /* 16 / 15 */
  padding: 1.6em; /* 24 / 15 */
  max-width: 33.333em; /* 500 / 15 */
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
}
/* .modal-title : font-size 22, props / 22 */
.modal-title {
  font-family: 'Google Sans Flex', sans-serif;
  font-size: 1.467em; /* 22 / 15 */
  font-weight: 500;
  margin-bottom: 0.727em; /* 16 / 22 */
}
/* .modal-close : font-size 24 */
.modal-close {
  float: right;
  background: transparent;
  border: none;
  color: var(--ink-muted);
  font-size: 1.6em; /* 24 / 15 */
  line-height: 1;
}

/* Empty states */
.empty {
  text-align: center;
  padding: 2.667em 1.333em; /* 40 20 / 15 */
  color: var(--ink-muted);
}
.empty-icon { font-size: 2.133em; margin-bottom: 0.25em; } /* 32/15 ; 8/32 */
.empty-text { font-size: 0.933em; } /* 14 / 15 */

/* ===== Utility ===== */
.flex { display: flex; }
.flex-between { display: flex; justify-content: space-between; align-items: center; }
.gap-8 { gap: 0.533em; } /* 8 / 15 */
.gap-12 { gap: 0.8em; } /* 12 / 15 */
.mt-8 { margin-top: 0.533em; } /* 8 / 15 */
.mt-16 { margin-top: 1.067em; } /* 16 / 15 */
.mt-24 { margin-top: 1.6em; } /* 24 / 15 */
.mb-16 { margin-bottom: 1.067em; } /* 16 / 15 */
.text-center { text-align: center; }
.text-right { text-align: right; }
.hidden { display: none !important; }

/* ============================================================
   PROJECT CARD
   ============================================================ */
.project-card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 0.875em;
  padding: 1.25em;
}

/* Header */
.pc-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  margin-bottom: 1.125em;
}

.pc-titleblock {
  display: flex;
  align-items: center;
  gap: 0.625em;
}

.pc-title {
  font-size: 1.0625em;
  font-weight: 600;
  color: var(--ink);
}

.pc-tag {
  font-size: 0.625em;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--project);
  padding: 0.2em 0.8em;
  background: rgba(107,74,122,0.12);
  border-radius: 0.4em;
}

.pc-manage {
  font-size: 0.75em;
  color: var(--ink-soft);
  text-decoration: none;
  font-weight: 500;
  padding: 0.4167em 1em;
  border-radius: 0.5em;
  border: 1px solid var(--line);
  transition: all 0.12s;
}
.pc-manage:hover {
  border-color: var(--ink-muted);
  color: var(--ink);
}

/* Total + rate */
.pc-total-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75em;
  margin-bottom: 0.5em;
}

.pc-total-num {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 1.875em;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.pc-total-rate {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.8125em;
  color: var(--ink-soft);
  font-weight: 500;
}
.pc-total-rate .unit {
  color: var(--ink-muted);
  font-weight: 400;
}

/* ============================================================
   "À faire" — bloc temporaire ancré à gauche du sélecteur de mois
   ============================================================ */
/* Wrapper invisible des 2 pads "À faire". Inclus DANS .bp-todo-month-row
   (sur le dashboard) — qui est position:relative — pour que les pads en
   absolute s'ancrent à top:0 du sélecteur de mois. C'est le "tour de
   passe-passe" : pads en sibling du sélecteur dans le HTML, mais ancrés
   visuellement à la même hauteur grâce à top:0 du parent. */
.bp-todo-pads-row {
  display: contents;
}

/* Desktop (>= 1400px) : sticky les todo-pads. En JS, on déplace .bp-todo-pads-row
   dans un container fixed (#bpTodoPadsHoldFixed) ancré au viewport ; en mobile,
   il revient à sa position d'origine dans .bp-todo-month-row. */
@media (min-width: 1400px) {
  #bpTodoPadsHoldFixed {
    position: fixed;
    top: 1em;
    left: 50%;
    transform: translateX(-50%);
    width: 85.333em; /* même max-width que .shell */
    max-width: calc(100vw - 3.2em);
    height: 0;
    pointer-events: none;
    z-index: 5;
  }
  #bpTodoPadsHoldFixed .bp-todo-pads-row {
    display: block;
    position: relative;
    height: 0;
  }
  #bpTodoPadsHoldFixed .todo-pad {
    pointer-events: auto;
  }
}

/* Style commun aux 2 pads — repris à l'identique de l'original. */
.todo-pad {
  position: absolute;
  top: 0;
  width: 18.75em; /* 300 / 16 */
  padding: 0.9em 1em 0.8em 1em;
  background: linear-gradient(180deg, #fffdf6 0%, #fbf6e8 100%);
  border: 1px solid var(--line-soft);
  border-radius: 0.5em;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04), 0 8px 18px rgba(60, 50, 30, 0.06);
  transition: transform 0.2s ease;
}
/* Pad perso → sort à gauche du wrapper */
.bp-todo-pads-row > .todo-pad:first-child {
  right: calc(100% + 1em + 50px);
  transform: rotate(-1.2deg);
}
/* Pad partagé → sort à droite du wrapper (miroir) */
.bp-todo-pads-row > .todo-pad-shared {
  left: calc(100% + 1em + 50px);
  transform: rotate(1.2deg);
}
.todo-pad::before {
  /* punaise décorative */
  content: '';
  position: absolute;
  top: -0.45em;
  left: 50%;
  width: 0.7em;
  height: 0.7em;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #c97a5e, #8c3a25);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transform: translateX(-50%);
}
.todo-pad:hover {
  transform: rotate(0deg);
}
.todo-pad-title {
  font-family: 'Tangerine', cursive;
  font-size: 2em;
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
  text-align: center;
  margin-bottom: 0.2em;
}
.todo-pad-scope {
  font-family: 'Google Sans Flex', -apple-system, sans-serif;
  font-size: 0.4em;
  font-weight: 400;
  color: var(--ink-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  vertical-align: middle;
  margin-left: 0.3em;
}
.todo-pad-textarea {
  width: 100%;
  min-height: 650px; /* clampé par le JS dans _todo_pads.php si la page est plus courte */
  padding: 0.5em 0.6em;
  border: none;
  outline: none;
  background: transparent;
  resize: vertical;
  font-family: 'Google Sans Flex', -apple-system, sans-serif;
  font-size: 0.933em;
  line-height: 1.55;
  color: var(--ink-soft);
  /* lignes ruled */
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 1.42em,
    rgba(140, 110, 70, 0.22) 1.42em,
    rgba(140, 110, 70, 0.22) calc(1.42em + 1px)
  );
  background-position: 0 1.2em;
}
.todo-pad-textarea::placeholder {
  color: var(--ink-muted);
  font-style: italic;
}
.todo-pad-status {
  margin-top: 0.3em;
  font-size: 0.75em;
  color: var(--ink-muted);
  text-align: right;
  min-height: 1em;
  font-family: 'JetBrains Mono', monospace;
}

/* ---------- Transaction : rangée de 4 drapeaux (cases à cocher) ---------- */
/* Cellules : sur écran large 4 colonnes ; sur étroit, wrap en 2 colonnes.   */
.tx-flags-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.533em; /* 8 / 15 */
}
.form-field label.tx-flag,
.tx-flag {
  flex: 1 1 9em; /* 135 / 15 — wrap quand < ~36em dispo */
  display: flex;
  flex-direction: column;
  gap: 0.267em; /* 4 / 15 */
  padding: 0.6em 0.733em; /* 9 11 / 15 */
  margin: 0; /* écrase .form-field label margin-bottom */
  background: var(--bg-soft);
  border: 1px solid transparent;
  border-radius: 0.4em; /* 6 / 15 */
  cursor: pointer;
  font-size: 1em; /* écrase .form-field label font-size 0.8em */
  text-transform: none; /* écrase .form-field label uppercase */
  letter-spacing: 0;
  color: var(--ink);
  transition: background 0.15s, border-color 0.15s;
}
.tx-flag:hover { background: var(--bg-softer); border-color: var(--line-soft); }
.tx-flag-head {
  display: flex;
  align-items: center;
  gap: 0.4em; /* 6 / 15 */
  font-weight: 500;
  font-size: 0.933em; /* 14 / 15 */
  color: var(--ink);
  text-transform: none;
  letter-spacing: 0;
}
.tx-flag-head input[type=checkbox] {
  flex: 0 0 auto;
  margin: 0;
  width: 1.067em; /* 16 / 15 */
  height: 1.067em;
  cursor: pointer;
}
.tx-flag-hint {
  font-size: 0.733em; /* 11 / 15 */
  color: var(--ink-muted);
  line-height: 1.35;
  margin: 0;
  /* aligné sous le label, pas sous la checkbox */
  padding-left: 1.467em; /* 16 + 6 = 22 / 15 */
}
.tx-flag input[type=checkbox]:checked ~ .tx-flag-hint,
.tx-flag:has(input[type=checkbox]:checked) {
  /* léger état actif : fond plus marqué quand cochée */
}
.tx-flag:has(input[type=checkbox]:checked) {
  background: var(--bg-softer);
  border-color: var(--line-soft);
}

/* ---------- Transaction : champ « Via (intermédiaire) » repliable ------- */
/* Visible déplié sur cat. de type Restaurant/Café/Épicerie, sinon bouton. */
.tx-sec-merchant-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.533em 0.8em; /* 8 12 / 15 */
  background: transparent;
  border: 1px dashed var(--line-soft);
  border-radius: 0.4em;
  color: var(--ink-muted);
  font-size: 0.8em; /* 12 / 15 */
  cursor: pointer;
  transition: all 0.15s ease;
}
.tx-sec-merchant-toggle:hover {
  background: var(--bg-soft);
  color: var(--ink);
  border-style: solid;
  border-color: var(--ink-muted);
}
.tx-sec-merchant-wrap[hidden] { display: none; }

/* ---------- Dashboard : Solde + Comptes côte à côte sous la saisie ------ */
/* 2 colonnes égales sous le bloc de saisie rapide. Wrap en 1 col sur écran  */
/* très étroit (sub-28em) pour rester lisible.                              */
.qe-balance-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.667em; /* 10 / 15 */
  margin-top: 1.067em; /* 16 / 15 */
}
.qe-balance-row > .card {
  margin: 0; /* annule la marge inférieure standard du .card */
  min-width: 0; /* permet aux enfants longs de wrap au lieu de déborder */
}
@media (max-width: 28em) {
  .qe-balance-row { grid-template-columns: 1fr; }
}
/* Desktop : le bloc est déplacé en sidebar via JS → on l'empile verticalement
   pour matcher le reste des cards sidebar, et on enlève le margin-top spécifique
   (le sibling-margin de .sidebar gère l'espacement vertical). */
.sidebar > .qe-balance-row {
  grid-template-columns: 1fr;
  gap: 1.333em;
  margin-top: 0;
}

/* ---------- Saisie rapide : toggle payeur en step 1 ----------------------- */
.qe-step1-payer {
  display: flex;
  align-items: center;
  gap: 0.667em; /* 10 / 15 */
  margin-bottom: 0.667em;
  padding: 0.4em 0.533em; /* 6 8 / 15 */
  background: var(--bg-soft);
  border-radius: 0.4em;
}
.qe-step1-payer .qe-meta-label {
  margin: 0;
  flex: 0 0 auto;
}
.qe-step1-payer .qe-toggle { flex: 1 1 auto; }

/* Sépare visuellement la grille « quick » de la grille « top non-quick ».
   On garde la même grille/colonnage ; juste une ligne pointillée subtile. */
.qe-cats-grid-quick + .qe-cats-grid {
  margin-top: 0.4em;
  padding-top: 0.533em;
  border-top: 1px dashed var(--line-soft);
}

/* ---------- Edit transaction : bouton compact « cat actuelle » ----------- */
/* L'utilisateur clique dessus pour ouvrir le picker (tile grids).          */
.tx-cat-display {
  display: flex;
  align-items: center;
  gap: 0.667em;
  width: 100%;
  padding: 0.714em 0.857em; /* match .form-field input padding */
  border: 1px solid var(--line);
  background: var(--bg-card);
  border-radius: 0.571em;
  font-family: inherit;
  font-size: 0.933em;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.tx-cat-display:hover { border-color: var(--ink-muted); background: var(--bg-softer); }
.tx-cat-display-icon { font-size: 1.4em; line-height: 1; }
.tx-cat-display-label { flex: 1 1 auto; font-weight: 500; }
.tx-cat-display-edit {
  font-size: 0.733em;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  flex: 0 0 auto;
}

/* Le picker ouvert ; tile actif dans step 2 = même style qu'un chip activé. */
#txCatPicker { margin-top: 0.4em; position: relative; }
#txCatPicker .qe-cats-grid + .qe-cats-grid { margin-top: 0.4em; }
#txCatSubs .cat-tile.active {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}
.tx-cat-close {
  position: absolute;
  top: -0.267em;
  right: 0;
  width: 1.867em;
  height: 1.867em;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--bg-card);
  color: var(--ink-muted);
  font-size: 1.2em;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
}
.tx-cat-close:hover { background: var(--bg-softer); color: var(--ink); }

/* Caché en-dessous d'un viewport assez large pour avoir de l'espace à gauche
   de la shell centrée (max-width ~85em + marges). */
/* Sous 1400px, les pads ne tiennent plus dans les marges → on les cache
   (même comportement que le pad d'origine). */
@media (max-width: 1399px) {
  .todo-pad { display: none; }
}

/* Préf user "Cacher les icônes" — séparé en 2 portées :
   - .bp-hide-icons-summary : tuiles, listes par catégorie (Ce mois-ci,
     page Année), sélecteur de catégorie à la saisie rapide.
   - .bp-hide-icons-tx      : pastille colorée à gauche de chaque ligne
     de transaction, et icône dans le détail d'une tx.
   Les icônes restent dans le HTML — on masque juste en CSS.
   Pour les conteneurs grid, on recompose le layout pour éviter une colonne
   fantôme. */

/* === Portée bilans (catégories, tuiles, sélecteur saisie) === */
.bp-hide-icons-summary .cat-icon,
.bp-hide-icons-summary .cat-tile-icon,
.bp-hide-icons-summary .cat-chip-icon,
.bp-hide-icons-summary .cat-mini-icon,
.bp-hide-icons-summary .qe-cat-parent-icon {
  display: none !important;
}
.bp-hide-icons-summary .cat-row {
  grid-template-columns: 1fr auto;
}
.bp-hide-icons-summary .cat-tile {
  gap: 0;
  padding-top: 0.9em;
  padding-bottom: 0.9em;
}

/* === Portée transactions (pastille + icône détail tx) === */
.bp-hide-icons-tx .tx-cat-display-icon,
.bp-hide-icons-tx .tx-row:not(.tx-settlement) .tx-icon {
  display: none !important;
}
.bp-hide-icons-tx .tx-row:not(.tx-settlement) {
  grid-template-columns: 1fr auto;
}

/* Breadcrumb "Parent / Sous-cat" sur les lignes de tx. Toujours rendu dans
   le HTML mais masqué par défaut ; visible quand on cache les icônes côté
   transactions, pour ne pas perdre l'info qu'apportait la pastille. */
.tx-cat-breadcrumb { display: none; }
.bp-hide-icons-tx .tx-cat-breadcrumb { display: inline-flex; }

/* ========================================================================== */
/* Mode SOLO : pas de partenaire dans le ménage.                              */
/* On masque les éléments couple-only en CSS pour garder le PHP en place      */
/* (l'expérience couple revient toute seule si un partenaire est invité).    */
/* ========================================================================== */
/* Widget solde du couple sur dashboard */
.bp-solo .bp-section-couple-balance { display: none !important; }
/* Tags "Partagé" / "Perso" / "L'autre 100 %" sur les lignes de tx — en solo
   tout est implicitement perso, donc les tags ne portent aucune info. */
.bp-solo .tx-tag-shared,
.bp-solo .tx-tag-personal { display: none !important; }
/* Tag "Règlement" : on garde la classe pour les anciennes données mais y'a
   pas de règlement possible en solo. */
.bp-solo .tx-row.tx-settlement { display: none !important; }
.bp-hide-icons-tx .tx-tag.tx-cat-breadcrumb {
  background: transparent;
  color: var(--ink-soft);
  font-style: italic;
  font-weight: 400;
  padding-left: 0;
  padding-right: 0.4em;
}

.pc-total-sub {
  font-size: 0.75em;
  color: var(--ink-muted);
  font-style: italic;
  margin-bottom: 1em;
}

/* Barre composite */
.pc-bar {
  position: relative;
  height: 1.125em;
  border-radius: 0.25em;
  background: var(--bg-soft);
  overflow: hidden;
  display: flex;
}

.pc-bar-paid-user1 { background: var(--project); }
.pc-bar-paid-user2 { background: #8c6a9d; }
.pc-bar-future-user1 {
  background: repeating-linear-gradient(45deg, rgba(107,74,122,0.35) 0 4px, rgba(107,74,122,0.18) 4px 8px);
}
.pc-bar-future-user2 {
  background: repeating-linear-gradient(45deg, rgba(140,106,157,0.35) 0 4px, rgba(140,106,157,0.18) 4px 8px);
}

.pc-bar-labels {
  display: flex;
  justify-content: space-between;
  margin-top: 0.5em;
  font-size: 0.625em;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Personnes */
.pc-people {
  display: grid;
  grid-template-columns: 1fr 1px 1fr;
  gap: 3.5em;
  margin-top: 1.5em;
  padding-top: 1.25em;
  border-top: 1px solid var(--line-soft);
  align-items: start;
}

.pc-people-divider {
  width: 1px;
  align-self: stretch;
  background: var(--line-soft);
  margin: 0.5em 0;
}

.pc-person {
  display: grid;
  grid-template-columns: 0.75em 1fr;
  gap: 0.75em;
  align-items: start;
}

.pc-person-dot {
  width: 0.75em;
  height: 0.75em;
  border-radius: 0.1875em;
  margin-top: 0.3125em;
}

.pc-person-name {
  font-size: 0.8125em;
  font-weight: 600;
}

.pc-person-total {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 1.25em;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0.125em 0;
}

.pc-person-rate {
  font-size: 0.6875em;
  color: var(--ink-muted);
  font-style: italic;
  margin-bottom: 0.5em;
}

.pc-person-row {
  display: flex;
  justify-content: space-between;
  font-size: 0.75em;
  padding: 0.125em 0;
}

.pc-person-row-label { color: var(--ink-muted); }

.pc-person-row-val {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  color: var(--ink-soft);
}

.pc-person-versements {
  font-size: 0.625em;
  color: var(--ink-muted);
  margin-left: 0.25em;
  font-style: italic;
}

/* Responsive : sur mobile, pas de divider, blocs empilés */
@media (max-width: 37.5em) {
  .pc-people {
    grid-template-columns: 1fr;
    gap: 1.5em;
    padding-top: 1em;
  }
  .pc-people-divider {
    display: none;
  }
}

/* ===== Voyage couple : cards par personne empilées + balance projet =====
   Utilisé seulement pour kind=voyage avec voyage_scope=couple (2 personnes).
   Donne le détail Individuel / Sa moitié couple / Total avec la portion
   future annotée sur chaque ligne. */
.pc-person-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5em;
  margin-top: 1.125em;
  padding-top: 1em;
  border-top: 0.0625em solid var(--line-soft);
}
@media (max-width: 37.5em) {
  .pc-person-cards {
    grid-template-columns: 1fr;
  }
}
.pc-person-card {
  background: var(--bg-soft);
  border-radius: 0.5em;
  padding: 0.625em 0.75em;
}
.pc-person-card-head {
  display: flex;
  align-items: center;
  gap: 0.4em;
  margin-bottom: 0.5em;
}
.pc-person-card-dot {
  width: 0.625em;
  height: 0.625em;
  border-radius: 0.1875em;
}
.pc-person-card-name {
  font-size: 0.875em;
  font-weight: 600;
}
.pc-person-card-grid {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.2em 0.667em;
  align-items: baseline;
  font-size: 0.8125em;
}
.pcpc-label {
  color: var(--ink-muted);
}
.pcpc-amount {
  font-weight: 500;
  text-align: right;
}
.pcpc-future {
  font-size: 0.846em; /* 11 / 13 — relatif au grid */
  color: var(--ink-muted);
  font-style: italic;
  white-space: nowrap;
}
.pcpc-total-label,
.pcpc-total-amount {
  font-weight: 700;
  padding-top: 0.333em;
  margin-top: 0.2em;
  border-top: 0.0625em dashed var(--line-soft);
}
.pcpc-total-amount {
  font-size: 1.077em; /* 14 / 13 */
}
.pcpc-total-future {
  padding-top: 0.333em;
  margin-top: 0.2em;
  border-top: 0.0625em dashed var(--line-soft);
}
.pc-person-card-rates {
  margin-top: 0.5em;
  padding-top: 0.4em;
  border-top: 0.0625em solid var(--line-soft);
  font-size: 0.75em;
  color: var(--ink-muted);
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em;
  align-items: baseline;
}
.pcpc-sep {
  opacity: 0.5;
}
.pc-balance {
  margin-top: 0.875em;
  padding: 0.625em 0.75em;
  background: var(--bg-soft);
  border-left: 0.1875em solid var(--shared);
  border-radius: 0.25em;
  font-size: 0.875em;
  line-height: 1.5;
}
.pc-balance .mono {
  font-weight: 600;
  margin: 0 0.125em;
}
.pc-balance-note {
  display: block;
  font-size: 0.786em; /* 11 / 14 */
  color: var(--ink-muted);
  font-style: italic;
  margin-top: 0.125em;
}
.pc-balance-zero {
  border-left-color: var(--pos);
  color: var(--ink-muted);
}

/* ===== Autocomplétion marchand (dropdown au-dessus de l'input) ===== */
.bp-mac-wrap {
  position: relative;
  display: block;
}
.bp-mac-box {
  position: absolute;
  bottom: calc(100% + 0.267em); /* 4 / 15, juste au-dessus */
  left: 0;
  right: 0;
  z-index: 50;
  background: var(--bg-card);
  border: 1px solid var(--line-soft);
  border-radius: 0.667em; /* 10 / 15 */
  box-shadow: 0 0.533em 1.333em rgba(0, 0, 0, 0.12); /* 8 / 15 ; 20 / 15 */
  max-height: 16em;
  overflow-y: auto;
  padding: 0.267em; /* 4 / 15 */
}
.bp-mac-opt {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  padding: 0.5em 0.667em; /* 7.5 / 15 ; 10 / 15 */
  font: inherit;
  color: var(--ink);
  border-radius: 0.4em; /* 6 / 15 */
  cursor: pointer;
}
.bp-mac-opt:hover,
.bp-mac-opt.hover {
  background: var(--bg-soft);
}

/* ============================================================
   CALENDRIER (views/calendar.php)
   ============================================================ */
.cal-shell { /* container vide pour scopage */ }

/* --- Onglets mode (Mois/Semaine/Jour) --- */
.cal-mode-tab {
  display: inline-block;
  padding: 0.4em 0.867em;
  border: 0.067em solid var(--line);
  border-radius: 0.4em;
  font-size: 0.933em;
  text-decoration: none;
  color: var(--ink);
  background: var(--bg-card);
  transition: background 0.15s ease;
}
.cal-mode-tab:hover { background: var(--bg-soft); }
.cal-mode-tab.is-active {
  background: var(--primary);
  color: #fff;
  border-color: var(--primary);
}

/* --- Chips filtre contextes --- */
.cal-ctx-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.333em;
  padding: 0.267em 0.667em;
  border: 0.067em solid var(--line-soft);
  border-radius: 1em;
  font-size: 0.867em;
  text-decoration: none;
  color: var(--ink-muted);
  background: var(--bg-card);
  opacity: 0.5;
  transition: opacity 0.15s ease, background 0.15s ease;
}
.cal-ctx-chip.is-active {
  opacity: 1;
  color: var(--ink);
  background: var(--bg-soft);
  border-color: var(--ink-soft);
}
.cal-ctx-chip:hover { opacity: 1; }
.cal-ctx-icon { font-size: 1.067em; }

/* --- Vue mois : grille 7 colonnes --- */
.cal-month-head {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.067em;
  margin-bottom: 0.067em;
}
.cal-month-head-cell {
  text-align: center;
  padding: 0.333em 0;
  font-size: 0.8em;
  font-weight: 500;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.cal-month-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.067em;
  background: var(--line-soft);
  border: 0.067em solid var(--line-soft);
  border-radius: 0.4em;
  overflow: hidden;
}
.cal-day {
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  padding: 0.4em 0.333em;
  min-height: 6em;
  text-decoration: none;
  color: var(--ink);
  transition: background 0.1s ease;
}
.cal-day:hover { background: var(--bg-softer); }
.cal-day--out { background: var(--bg); color: var(--ink-muted); }
.cal-day--out .cal-day-num { opacity: 0.55; }
.cal-day--today { background: var(--primary-lighter); }
.cal-day--today .cal-day-num {
  background: var(--primary);
  color: #fff;
  border-radius: 50%;
  width: 1.6em;
  height: 1.6em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.cal-day-num {
  font-size: 0.867em;
  font-weight: 500;
  margin-bottom: 0.267em;
}
.cal-day { min-width: 0; }
.cal-day-events {
  display: flex;
  flex-direction: column;
  gap: 0.133em;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}
.cal-event-chip {
  font-size: 0.733em;
  padding: 0.133em 0.4em;
  border-radius: 0.267em;
  display: flex;
  gap: 0.267em;
  align-items: baseline;
  white-space: nowrap;
  overflow: hidden;
  min-width: 0;
}
.cal-event-time {
  font-family: 'Roboto Mono', monospace;
  font-size: 0.85em;
  opacity: 0.85;
  flex: 0 0 auto;
}
.cal-event-title,
.cal-event-desc {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cal-event-desc { opacity: 0.8; flex: 1 1 auto; }
.cal-event-more {
  font-size: 0.733em;
  color: var(--ink-muted);
  padding-left: 0.267em;
}

/* --- Vue semaine --- */
.cal-week {
  display: flex;
  flex-direction: column;
  gap: 0.4em;
}
.cal-week-day {
  background: var(--bg-card);
  border-radius: 0.4em;
  padding: 0.667em 0.8em;
  border-left: 0.267em solid var(--line-soft);
}
.cal-week-day--today {
  border-left-color: var(--primary);
  background: var(--primary-lighter);
}
.cal-week-day-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.933em;
  font-weight: 500;
  margin-bottom: 0.4em;
}
.cal-week-day-name { text-transform: capitalize; }
.cal-week-day-date {
  color: var(--ink-muted);
  font-size: 0.867em;
}
.cal-week-day-events {
  display: flex;
  flex-direction: column;
  gap: 0.333em;
}
.cal-empty-day {
  color: var(--ink-muted);
  font-size: 0.867em;
  font-style: italic;
}

/* --- Vue jour --- */
.cal-day-view {
  display: flex;
  flex-direction: column;
  gap: 0.4em;
}

/* --- Ligne d'event (semaine/jour) --- */
.cal-event-row {
  display: flex;
  gap: 0.667em;
  padding: 0.533em 0.667em;
  background: var(--bg-card);
  border-radius: 0.333em;
  text-decoration: none;
  color: var(--ink);
  border-left: 0.267em solid var(--line);
  transition: background 0.15s ease;
}
.cal-event-row:hover { background: var(--bg-soft); }
.cal-event-row-time {
  flex: 0 0 5em;
  font-family: 'Roboto Mono', monospace;
  font-size: 0.867em;
  color: var(--ink-muted);
  padding-top: 0.067em;
}
.cal-event-row-body { flex: 1; min-width: 0; }
.cal-event-row-title {
  font-weight: 500;
  font-size: 0.967em;
  display: flex;
  gap: 0.333em;
  align-items: center;
  flex-wrap: wrap;
}
.cal-event-row-icon { font-size: 1.1em; }
.cal-event-tx-tag {
  font-size: 0.733em;
  opacity: 0.7;
  margin-left: 0.267em;
}
.cal-event-row-project,
.cal-event-row-loc {
  font-size: 0.8em;
  color: var(--ink-muted);
  margin-top: 0.2em;
}
.cal-event-row-desc {
  font-size: 0.867em;
  color: var(--ink-soft);
  margin-top: 0.333em;
  line-height: 1.4;
}

/* --- Modale form event --- */
.cal-form-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(20, 18, 14, 0.55);
  z-index: 100;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 1.333em 0.667em;
  overflow-y: auto;
}
.cal-form-backdrop[hidden] { display: none; }
.cal-form-modal {
  background: var(--bg-card);
  border-radius: 0.667em;
  padding: 1.333em;
  width: 100%;
  max-width: 32em;
  box-shadow: 0 0.667em 2em rgba(0,0,0,0.18);
}
.cal-form-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1em;
}
.cal-form-close {
  background: transparent;
  border: 0;
  font-size: 1.6em;
  line-height: 1;
  cursor: pointer;
  color: var(--ink-muted);
  padding: 0 0.267em;
}
.cal-form-close:hover { color: var(--ink); }
.cal-form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.4em;
  margin-top: 1em;
}
.cal-form-actions > button:first-child { margin-right: auto; }

/* --- Mobile (≤540px) --- */
@media (max-width: 540px) {
  .cal-day { min-height: 4em; padding: 0.267em 0.2em; }
  .cal-day-num { font-size: 0.733em; }
  .cal-event-chip { font-size: 0.667em; padding: 0.067em 0.267em; }
  .cal-event-time { display: none; }
  .cal-month-head-cell { font-size: 0.733em; }
  .cal-event-row-time { flex: 0 0 3.5em; font-size: 0.8em; }
  .cal-ctx-label { display: none; }
  .cal-ctx-chip { padding: 0.333em 0.533em; }
  .cal-ctx-icon { font-size: 1.2em; }
}
