/* ============================================================================
   responsive.css — Adaptation aux petits écrans

   ────────────────────────────────────────────────────────────────────────────
   POURQUOI CE FICHIER, ET POURQUOI IL EST CHARGÉ EN DERNIER
   ────────────────────────────────────────────────────────────────────────────
   L'application comptait cinq `@media` sur l'ensemble des onze pages, et aucune
   sur bourse.html (1 875 lignes), comptes, categories ou parametres. Sur
   téléphone : padding latéral de 48 px sur un écran de 360, tableaux coupés par
   un `overflow: hidden`, modales plus larges que la fenêtre, formulaires en deux
   colonnes illisibles. Or le téléphone est précisément l'endroit où l'on saisit
   une dépense — au moment où on la fait.

   Chaque page porte son CSS dans un `<style>` en ligne, placé APRÈS le
   `<link theme.css>`. Écrire ces règles dans theme.css n'aurait donc servi à
   rien : à spécificité égale, la dernière déclaration l'emporte, et les styles
   en ligne des pages auraient repris le dessus.

   D'où un fichier séparé, référencé JUSTE APRÈS le bloc `<style>` de chaque
   page. Il gagne par l'ordre de cascade, sans `!important` et sans qu'on ait à
   toucher aux 1 000 règles existantes. Le retirer suffit à revenir en arrière.

   Trois paliers :
     ≤ 1100 px  tablette / fenêtre étroite — on desserre, on passe en 1 colonne
     ≤  760 px  téléphone paysage / petite tablette — pleine largeur
     ≤  460 px  téléphone portrait — compaction et cibles tactiles
   ========================================================================== */

/* ──────────────────────────────────────────────────────────────────────────
   Palier tablette
   ────────────────────────────────────────────────────────────────────────── */
@media (max-width: 1100px) {
  main {
    padding-left: 22px;
    padding-right: 22px;
    max-width: 100%;
  }

  /* Les grilles fixées à un nombre de colonnes en dur dans les pages. */
  .kpi-grid, .cards, .cards-grid, .stats-grid, .grid-cards {
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  }
}

/* ──────────────────────────────────────────────────────────────────────────
   Palier téléphone
   ────────────────────────────────────────────────────────────────────────── */
@media (max-width: 760px) {

  /* ── Mise en page générale ───────────────────────────────────────────── */
  main {
    padding: 68px 12px 40px;
    max-width: 100%;
    margin: 0;
  }

  .page-title { font-size: 1.35rem; }
  .page-title span { display: block; margin-top: 2px; }

  /* Tout ce qui est disposé en ligne se replie plutôt que de déborder. */
  .controls-bar, .filters, .filter-bar, .toolbar, .card-header, .card-head,
  .actions, .page-header, .header-actions, .alloc-top, .alloc-kpis {
    flex-wrap: wrap;
    gap: 9px;
  }
  .ctrl-spacer { display: none; }          /* le « pousse à droite » n'a plus de sens */
  .ctrl-sep    { display: none; }

  /* ── Tableaux ────────────────────────────────────────────────────────── */
  /* `overflow: hidden` (utilisé par plusieurs pages pour arrondir les coins)
     COUPE le tableau au lieu de le laisser défiler : les colonnes de droite —
     montant, actions — devenaient inatteignables. Le défilement horizontal est
     le bon compromis : la donnée reste intégralement accessible. */
  .table-wrapper, .budget-scroll, .tableau-wrapper {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .table-wrapper table, .tableau-wrapper table { min-width: 560px; }

  table th, table td {
    padding: 8px 7px;
    font-size: .78rem;
  }
  /* Les colonnes purement décoratives sont sacrifiées avant les chiffres. */
  .col-optionnelle, .th-optionnelle { display: none; }

  /* ── Grilles ─────────────────────────────────────────────────────────── */
  .grid-2, .grid-3, .grid-4, .grid-21, .grid-12,
  .kpi-grid, .cards, .cards-grid, .stats-grid, .grid-cards,
  .charts-row, .row-2, .two-col {
    grid-template-columns: 1fr;
  }

  .kpi-value, .kpi-val { font-size: 1.25rem; }

  /* ── Formulaires ─────────────────────────────────────────────────────── */
  .form-row, .form-grid, .form-2col {
    grid-template-columns: 1fr;
    display: grid;
  }
  .form-group.half, .form-group.full { grid-column: 1 / -1; }

  /* 16 px minimum sur les champs : en dessous, iOS zoome automatiquement à la
     mise au point et la page part de travers. */
  input, select, textarea { font-size: 16px; }

  /* ── Modales ─────────────────────────────────────────────────────────── */
  /* Elles étaient dimensionnées en pixels et sortaient de l'écran. En bas de
     fenêtre plutôt qu'au centre : c'est là que le pouce arrive. */
  .modal {
    width: calc(100vw - 20px);
    max-width: none;
    max-height: 88vh;
    overflow-y: auto;
    margin: 0;
  }
  .modal-overlay { align-items: flex-end; padding: 0 10px 10px; }
  .form-actions { flex-direction: column-reverse; }
  .form-actions .btn { width: 100%; justify-content: center; }

  /* ── Boutons ─────────────────────────────────────────────────────────── */
  /* 40 px : le minimum confortable pour une cible tactile. */
  .btn, .mini-btn, .icon-btn { min-height: 40px; }
  .mini-btn, .icon-btn { min-width: 40px; }

  /* ── Menu latéral ────────────────────────────────────────────────────── */
  /* 260 px fixes sur un écran de 360 laissaient une bande de contenu inerte
     à droite, sans repère pour comprendre qu'on peut fermer en la touchant. */
  #menu-panel, .app-nav { width: min(84vw, 300px); }
  #menu-btn { top: 12px; left: 12px; }

  /* ── Graphiques ──────────────────────────────────────────────────────── */
  .chart-box, .chart-container, .chart-wrap { height: 240px; }

  /* Le diagramme Sankey et la carte du monde n'ont aucun sens en dessous de
     600 px : les libellés se chevauchent au point d'être illisibles. Un message
     vaut mieux qu'un graphique faux. */
  .sankey-wrap, #sankey-container, .map-wrap, #carte-monde { display: none; }
  .masque-mobile-msg { display: block; }

  /* ════════════════════════════════════════════════════════════════════════
     Audit du 14/11/2026 sur le site complet à 375 px — 14 pages sur 17
     débordaient en largeur (jusqu'à 917 px sur Comptes). Trois causes :
     ════════════════════════════════════════════════════════════════════════ */

  /* 1. Grilles propres aux pages, absentes des listes ci-dessus. `1fr` seul
        vaut `minmax(auto, 1fr)` : une colonne ne descend jamais sous la largeur
        de son contenu le plus large (un tableau, un graphique, un libellé en
        nowrap) et entraîne toute la page. `minmax(0, 1fr)` l'autorise. */
  .main-grid, .sim-grid, .grille, .bilan, .liq, .info-grid,
  .grid-2, .grid-3, .grid-21, .grid-12, .charts-row, .row-2, .two-col {
    grid-template-columns: minmax(0, 1fr);
  }
  .total-bar  { padding: 16px; gap: 14px; }
  .stats-row  { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .stat-card  { padding: 12px 6px; }
  .stat-value { font-size: 1.1rem; }
  .net-ligne  { grid-template-columns: minmax(0, 1fr); }
  .net-ligne .mt { font-size: 1.35rem; }
  .card, .main-grid > *, .grille > *, .bilan > * { min-width: 0; }

  /* 2. Rangées flex en nowrap : barres d'onglets, lignes de réglages. Elles
        passent à la ligne au lieu de pousser l'écran. */
  .segmented { display: flex; flex-wrap: wrap; max-width: 100%; }
  .segmented a, .segmented button { flex: 1 1 auto; text-align: center; }
  .param-row, .danger-row, .card-header, .obj-head, .bn-head, .cr-head,
  .periode, .montants { flex-wrap: wrap; }
  .param-row, .danger-row { padding: 16px; gap: 12px; }
  .param-info { flex-basis: 100%; }
  .info-item  { flex-wrap: wrap; min-width: 0; }
  .danger-btn, .save-param-btn { white-space: normal; }

  /* 3. Tableaux dans des cartes sans conteneur défilant : ils défilent
        eux-mêmes. `display:block` fait du <table> une boîte qui peut défiler ;
        ses lignes restent mises en page comme un tableau. */
  .rep-table, .bareme, #encaisses-contenu table, .card table:not(.rav) {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* Sans nowrap, un tableau rendu défilant se comprime quand même à la largeur
     de l'écran (dates sur trois lignes, nom de produit coupé à chaque tiret). */
  .rep-table th, .rep-table td, .bareme th, .bareme td,
  #encaisses-contenu th, #encaisses-contenu td { white-space: nowrap; }

  /* « Réellement disponible » : le montant final, en police de titre, ne
     tenait pas à côté de son libellé. Le libellé passe à la ligne, le montant
     garde sa colonne. */
  .rav tr.total td { font-size: 1.15rem; }
  .rav tr.total td:first-child, .rav tr.note td { white-space: normal; }

  /* Lignes « libellé … valeur » : la valeur passe sous le libellé plutôt que
     de sortir de l'écran (Analyse : « baissière (plus hauts et plus bas
     décroissants) » ; Crédits : paliers de charge en trois colonnes fixes). */
  .analyse-row { flex-wrap: wrap; gap: 6px 12px; }
  .analyse-row > * { min-width: 0; max-width: 100%; }
  .legende { flex-direction: column; gap: 6px; }
  /* Budget : titre, phrase et bouton sur une ligne → la phrase n'avait
     plus que 90 px. Elle passe sous le titre. */
  .section-titre { flex-wrap: wrap; }
  .section-titre p { flex-basis: 100%; order: 3; }
  /* Récurrentes : le tableau défile déjà ; sans nowrap il se comprimait
     quand même (« − 295,66 € » coupé après le signe). */
  .rec-table td, .rec-table th { white-space: nowrap; }
  /* Catégories : cinq boutons de 40 px (cible tactile) laissaient ~70 px au
     nom de la catégorie. Les boutons passent sur leur propre ligne. */
  .tete-cat { flex-wrap: wrap; }
  .tete-cat .item-actions { flex-basis: 100%; display: flex; justify-content: flex-end; gap: 4px; }
  .palier { grid-template-columns: minmax(0, 1fr) auto; gap: 6px 12px; }
  .palier .quoi { grid-column: 1 / -1; grid-row: 2; }

  /* ── Montants en police de titre dans des tuiles étroites ────────────────
     La police de titre est large : « 105 389,62 € » occupe ~200 px en 1,4 rem.
     Dans une tuile de 150 px, le chiffre débordait sur la tuile voisine
     (Comptes), ou était coupé au milieu par `word-break: break-all`. */
  .total-bar   { grid-template-columns: minmax(0, 1fr); }
  .total-value { font-size: 1.25rem; }
  .solde-block { flex-basis: 100%; }
  .solde-block-value { word-break: normal; white-space: nowrap; }
  .chiffres    { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .chiffre .val { font-size: 1.05rem; }
  .ch .val     { font-size: .92rem; }
  .kpi .val, .montants .val { font-size: 1.3rem; }
  .tag-indicateur { white-space: normal; }

  /* KPI du portefeuille : cinq tuiles sur une rangée → deux colonnes. */
  .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .kpi-row > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  .kpi-card { padding: 14px; }
  .kpi-row .kpi-value { font-size: 1.1rem; }

  /* ── Bourse : lignes de position ─────────────────────────────────────────
     Six blocs côte à côte (ticker, nom, cours, plus-value, valeur, bouton)
     sur 350 px : le nom tombait à un mot par ligne. Deux rangées : identité
     en haut, chiffres en dessous. */
  .position-item {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 8px 10px;
  }
  .position-item > :first-child { grid-column: span 2; }
  .position-item > .position-info { grid-column: span 3; }
  .position-item > .action-btn { grid-column: 6; grid-row: 1; justify-self: end; align-self: start; }
  .position-item > .position-cours,
  .position-item > .position-pv,
  .position-item > .position-valeur { grid-column: span 2; min-width: 0; text-align: left; }
  .position-ticker { min-width: 0; }

  /* ── Bourse : classement par signaux long terme ──────────────────────────
     La colonne des notes (`flex-shrink:0`, verdict sur une ligne) prenait
     toute la largeur ; le nom et les signaux tombaient à un mot par ligne et
     chevauchaient le verdict (signalé le 14/11/2026). Sur téléphone : rang à
     gauche, puis nom, note, signaux, empilés dans une seule colonne. */
  .cl-ligne {
    display: grid;
    grid-template-columns: 26px minmax(0, 1fr);
    column-gap: 12px;
    row-gap: 6px;
    padding: 14px 14px;
  }
  .cl-rang   { grid-column: 1; grid-row: 1 / span 3; }
  .cl-corps  { display: contents; }
  .cl-nom    { grid-column: 2; grid-row: 1; }
  .cl-notes  { grid-column: 2; grid-row: 2; min-width: 0; text-align: left;
               display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 10px; }
  .cl-notes > * { margin-top: 0; }
  .cl-detail { grid-column: 2; grid-row: 3; margin-top: 0; }
  .cl-groupe, .cl-avert { padding-left: 14px; padding-right: 14px; }
  .classement-tete { padding-left: 14px; padding-right: 14px; }
}

/* ──────────────────────────────────────────────────────────────────────────
   Palier téléphone portrait
   ────────────────────────────────────────────────────────────────────────── */
@media (max-width: 460px) {
  main { padding: 64px 8px 32px; }

  .page-title { font-size: 1.18rem; }
  .card, .panel, .box { padding: 13px 12px; }
  table th, table td { padding: 7px 5px; font-size: .75rem; }

  /* Les onglets de période se réorganisent en grille plutôt que de déborder. */
  .periode-tabs, .tabs, .onglets {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 5px;
  }
  .periode-tab, .tab, .onglet { text-align: center; padding: 9px 4px; }

  /* Rail des douze mois de la page Budget : sur deux lignes de six. */
  .mois-rail { display: grid; grid-template-columns: repeat(6, 1fr); gap: 3px; }

  .toast { left: 8px; right: 8px; bottom: 8px; width: auto; max-width: none; }

  /* Tuiles de chiffres : une par ligne, libellé à gauche et montant à droite.
     En deux colonnes, la police de titre (large) ne laisse que ~130 px par
     montant : « 16 829,27 € » tient tout juste, un montant à six chiffres
     déborde. Une tuile par ligne tient n'importe quel montant, et la
     disposition en ligne garde la liste deux fois moins haute qu'un
     empilement libellé / montant. */
  .kpi-row, .chiffres, .pv-reperes { grid-template-columns: minmax(0, 1fr); }
  .kpi-row > :last-child:nth-child(odd) { grid-column: auto; }
  .kpi-card, .chiffre, .ch, .pv-repere {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 12px;
    align-items: baseline;
  }
  .kpi-card > :nth-child(2), .chiffre > :nth-child(2),
  .ch > :nth-child(2), .pv-repere > :nth-child(2) {
    grid-column: 2; grid-row: 1; text-align: right; margin-top: 0;
  }
  .kpi-card > :nth-child(n+3), .chiffre > :nth-child(n+3),
  .ch > :nth-child(n+3), .pv-repere > :nth-child(n+3) { grid-column: 1 / -1; }
  .kpi-card > .kpi-label { margin-bottom: 0; }
  .rav tr.total td { font-size: 1rem; }
}

/* ──────────────────────────────────────────────────────────────────────────
   Accessibilité — indépendant de la largeur
   ────────────────────────────────────────────────────────────────────────── */

/* Anneau de focus visible au clavier UNIQUEMENT (`:focus-visible`, pas
   `:focus`) : il n'apparaît donc pas au clic à la souris, où il fait
   « sale » et pousse justement à le désactiver. Sans lui, naviguer au clavier
   se fait à l'aveugle. */
:focus-visible {
  outline: 2px solid var(--accent, #6ea8fe);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Lien d'évitement : premier élément focusable de la page, invisible tant
   qu'il n'a pas le focus. Il évite de traverser les huit entrées du menu à
   chaque page pour atteindre le contenu. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100000;
  padding: 10px 16px;
  background: var(--accent, #6ea8fe);
  color: #0b0f19;
  font-weight: 600;
  border-radius: 0 0 8px 0;
}
.skip-link:focus {
  left: 0;
}

@media (prefers-contrast: more) {
  :root { --border: #6b7280; --muted: #d1d5db; }
}
