/*
 * Habillage de l'application. Bootstrap 5.3 est chargé avant ce fichier et fournit la grille,
 * les composants et les variables de thème (--bs-*). On s'appuie sur ces variables partout pour
 * que le mode sombre fonctionne sans dupliquer les règles.
 */

/*
 * Inter, auto-hébergée (SIL Open Font License). Une seule fonte variable couvre 400 à 700.
 * Choisie pour ses chiffres tabulaires : les montants s'alignent en colonne, ce que la pile
 * système ne garantit pas d'un appareil à l'autre.
 */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("../fonts/inter-latin-variable-1b3ec095194194abe1625b02c945e2f1.woff2") format('woff2');
}

:root {
    --bs-font-sans-serif: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

    /*
     * Échelle typographique. Application dense en chiffres : on part de 15px plutôt que des
     * 16px de Bootstrap, et on garde peu de paliers pour que la hiérarchie reste lisible.
     */
    --bs-body-font-size: 0.9375rem;   /* 15px — texte courant, libellés de transaction */
    --fs-micro: 0.75rem;              /* 12px — intitulés de section en capitales, badges */
    --fs-meta: 0.8125rem;             /* 13px — dates, texte secondaire */
    --fs-title: 1.0625rem;            /* 17px — titres de carte */
    --fs-value: 1.25rem;              /* 20px — valeurs de tuile de premier niveau */
    --fs-value-sm: 1rem;              /* 16px — valeurs de tuile imbriquée */
    --fs-hero: 2.25rem;               /* 36px — solde */

    --telire-accent: #0c5460;
    --telire-accent-soft: #e6f1f3;
    --telire-in: #198754;
    --telire-out: #b02a37;
    --telire-radius: 16px;
    --telire-topbar-h: 3.5rem;
    --telire-bottomnav-h: 4.25rem;
}

[data-bs-theme="dark"] {
    --telire-accent: #4dd4e8;
    --telire-accent-soft: #14313a;
    --telire-in: #4ade80;
    --telire-out: #f87171;
}

body {
    background-color: var(--bs-tertiary-bg);
    -webkit-font-smoothing: antialiased;
}

/* ------------------------------------------------- États d'interaction */

/*
 * Retour au toucher.
 *
 * Tout l'habillage interactif de ce fichier était en `:hover`, qui n'existe pas sur un téléphone :
 * appuyer sur une ligne ne produisait rien jusqu'au changement de page, et sur une connexion lente
 * on appuie deux fois. `:active` marche partout, y compris au doigt.
 *
 * Le halo gris d'Android se déclenche en plus du nôtre et déborde des coins arrondis : on le coupe
 * là où on fournit notre propre retour.
 */
.txn__link,
.app-bottomnav__item,
.app-topbar__icon-btn,
.btn,
.segmented .nav-link,
.details-block > summary {
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.12s ease, opacity 0.12s ease, transform 0.12s ease;
}

.txn__link:active { background: var(--bs-secondary-bg); }
.app-bottomnav__item:active { background: var(--bs-tertiary-bg); }
.app-topbar__icon-btn:active { background: rgba(255, 255, 255, 0.2); }
[data-bs-theme="dark"] .app-topbar__icon-btn:active { background: var(--bs-tertiary-bg); }
.btn:active { transform: scale(0.985); }

/*
 * Focus clavier.
 *
 * Plusieurs éléments posent `border: 0` pour l'esthétique — les boutons de la barre du haut, les
 * pastilles d'onglet — et perdaient du même coup l'anneau par défaut du navigateur. `:focus-visible`
 * et non `:focus` : au clic à la souris ou au doigt, l'anneau ne se justifie pas.
 */
:focus-visible {
    outline: 2px solid var(--telire-accent);
    outline-offset: 2px;
}

.app-topbar :focus-visible {
    outline-color: #fff;
}

[data-bs-theme="dark"] .app-topbar :focus-visible {
    outline-color: var(--telire-accent);
}

/* Barre de progression de Turbo : c'était la seule couleur de l'application qui n'était pas
   l'accent — elle héritait du bleu par défaut de la bibliothèque. */
.turbo-progress-bar {
    height: 3px;
    background-color: var(--telire-accent);
}

/* ---------------------------------------------------------------- Coquille */

.app-topbar {
    position: sticky;
    top: 0;
    z-index: 1030;
    min-height: var(--telire-topbar-h);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    /* La zone sûre s'ajoute au padding : avec une hauteur fixe elle écraserait le contenu. */
    padding: env(safe-area-inset-top) 0 0;
    background: var(--telire-accent);
    color: #fff;
}

/* Aligne le contenu du bandeau sur la même colonne que la page, sinon il se colle
   aux bords de la fenêtre sur grand écran alors que le contenu reste centré. */
.app-topbar__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
    max-width: 720px;
    margin: 0 auto;
    padding: 0 1rem;
    min-height: var(--telire-topbar-h);
}

[data-bs-theme="dark"] .app-topbar {
    background: var(--bs-secondary-bg);
    color: var(--bs-body-color);
    border-bottom: 1px solid var(--bs-border-color);
}

/*
 * Le titre de l'écran, et le seul `<h1>` de la page.
 *
 * Il porte désormais un nom de membre sur `/membres/{id}` : sans troncature, « Boubacar Bailo BA »
 * pousserait le sélecteur de thème et la déconnexion hors de l'écran. `min-width: 0` est
 * indispensable — un enfant de conteneur flex refuse de descendre sous sa largeur de contenu sans
 * lui, et `text-overflow` ne se déclenche jamais.
 */
.app-topbar__title {
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--fs-title);
    font-weight: 600;
    letter-spacing: 0.02em;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app-topbar__actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: none;
}

/*
 * Pastille d'initiales, lien vers « Mon compte ».
 *
 * `color` est **obligatoire** ici : c'est un `<a>`, et sans règle il prend le bleu de lien de
 * Bootstrap — illisible sur le bandeau teal en thème clair. Le bouton d'icône voisin s'en sortait
 * parce qu'il pose `color: inherit`, celui-ci ne le faisait pas.
 *
 * Fond plein plutôt que blanc translucide : à 18 % d'opacité la pastille se confondait avec le
 * bandeau et ne se lisait pas comme une cible.
 */
.app-topbar__user {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: #fff;
    color: var(--telire-accent);
    font-size: 0.75rem;
    font-weight: 600;
    text-decoration: none;
}

.app-topbar__user:hover,
.app-topbar__user:focus { color: var(--telire-accent); opacity: 0.85; }
.app-topbar__user:active { opacity: 0.7; }

/* En sombre le bandeau n'est plus l'accent : une pastille blanche y serait le point le plus
   lumineux de l'écran. Fond sourd, initiales à l'accent — qui est clair de ce côté-là. */
[data-bs-theme="dark"] .app-topbar__user {
    background: var(--bs-tertiary-bg);
    color: var(--telire-accent);
    border: 1px solid var(--bs-border-color);
}

[data-bs-theme="dark"] .app-topbar__user:hover,
[data-bs-theme="dark"] .app-topbar__user:focus { color: var(--telire-accent); }

.app-topbar__icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border: 0;
    padding: 0;
    background: transparent;
    border-radius: 50%;
    color: inherit;
    opacity: 0.85;
}

.app-topbar__icon-btn:hover { opacity: 1; background: rgba(255, 255, 255, 0.12); }
[data-bs-theme="dark"] .app-topbar__icon-btn:hover { background: var(--bs-tertiary-bg); }

.app-topbar__icon-btn .icon { width: 20px; height: 20px; }

/* Une seule des deux icônes du sélecteur de thème est visible à la fois. */
[data-bs-theme="dark"] .icon-when-light { display: none; }
:root:not([data-bs-theme="dark"]) .icon-when-dark { display: none; }

#main-content {
    max-width: 720px;
    margin: 0 auto;
    padding: 1rem 1rem calc(var(--telire-bottomnav-h) + 1.5rem);
}

/* Écrans sans coquille (connexion) : pas de navigation basse à compenser. */
#main-content.is-bare {
    max-width: none;
    padding: 0;
}

/* ------------------------------------------------------- Navigation basse */

.app-bottomnav {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1030;
    display: flex;
    justify-content: center;
    background: var(--bs-body-bg);
    border-top: 1px solid var(--bs-border-color);
    padding-bottom: env(safe-area-inset-bottom);
}

.app-bottomnav__inner {
    display: flex;
    width: 100%;
    max-width: 720px;
}

.app-bottomnav__item {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    min-height: var(--telire-bottomnav-h);
    padding: 0.5rem 0.25rem;
    color: var(--bs-secondary-color);
    text-decoration: none;
    font-size: var(--fs-micro);
    line-height: 1.1;
    text-align: center;
}

.app-bottomnav__item:hover { color: var(--bs-body-color); }

.app-bottomnav__item.is-active {
    color: var(--telire-accent);
    font-weight: 600;
}

.app-bottomnav__item .icon { width: 22px; height: 22px; }

/*
 * Bouton central de saisie (D-UX-2). Il occupe une case comme les autres pour que la barre reste
 * une grille régulière, mais son contenu est une pastille : c'est une action, pas une destination,
 * et rien ne doit laisser croire qu'on y « est ».
 */
.app-bottomnav__item--action {
    padding: 0;
}

.app-bottomnav__fab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--telire-accent);
    color: #fff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.12s ease;
}

/* En sombre l'accent devient clair : du blanc dessus serait illisible. */
[data-bs-theme="dark"] .app-bottomnav__fab { color: #06232a; }

.app-bottomnav__fab:active { transform: scale(0.94); }
.app-bottomnav__fab .icon { width: 24px; height: 24px; }

/* Tuiles de la feuille de choix du « + » */
.choice-tile {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.9rem 0.75rem;
    border-radius: 12px;
    color: inherit;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}

.choice-tile + .choice-tile { margin-top: 0.25rem; }
.choice-tile:hover, .choice-tile:active { background: var(--bs-tertiary-bg); color: inherit; }
.choice-tile > span { flex: 1 1 auto; display: flex; flex-direction: column; }
.choice-tile small { font-size: var(--fs-meta); color: var(--bs-secondary-color); }
.choice-tile > .icon:first-child { width: 22px; height: 22px; }

/* Une action et non une destination : mêmes repères visuels, remise à plat du bouton natif. */
.choice-tile--button {
    width: 100%;
    border: 0;
    background: none;
    text-align: left;
    font: inherit;
}

.choice-tile--button > span { align-items: flex-start; }

/* ------------------------------------------------------------- Composants */

.card {
    border: 1px solid var(--bs-border-color);
    border-radius: var(--telire-radius);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

/*
 * Intitulé de section. C'est un `<h2>` depuis le lot C — il l'était déjà à l'œil, il ne l'était pas
 * pour un lecteur d'écran, et aucune page ne portait de titre du tout.
 *
 * La remise à plat est explicite : les styles de titre de Bootstrap ne doivent pas transparaître,
 * l'échelle typographique du fichier fait foi.
 */
.section-title {
    font-size: var(--fs-micro);
    font-weight: 600;
    line-height: 1.3;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--bs-secondary-color);
    margin: 0 0 0.5rem;
}

/* Bandeau de solde */
.balance {
    border-radius: var(--telire-radius);
    padding: 1.25rem;
    color: #fff;
    background: linear-gradient(135deg, var(--telire-in), #0f5132);
}

.balance--negative {
    background: linear-gradient(135deg, var(--telire-out), #6f1620);
}

.balance__label {
    font-size: var(--fs-micro);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    opacity: 0.85;
    margin-bottom: 0.25rem;
}

.balance__amount {
    font-size: var(--fs-hero);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.balance__hint {
    font-size: var(--fs-meta);
    opacity: 0.85;
    margin: 0.35rem 0 0;
}

/*
 * Lien logé dans le bandeau. Séparé par un filet plutôt que posé dessous : le bandeau est déjà la
 * zone que l'œil regarde, sortir le lien l'aurait renvoyé dans le gris de la page.
 */
.balance__link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin: 0.9rem -0.35rem -0.35rem;
    padding: 0.55rem 0.35rem 0.1rem;
    border-top: 1px solid rgba(255, 255, 255, 0.25);
    color: #fff;
    font-size: var(--fs-meta);
    font-weight: 600;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}

.balance__link:hover, .balance__link:active { color: #fff; opacity: 0.85; }
.balance__link .icon { width: 15px; height: 15px; }

/* Tuiles de totaux */
.stat-tile {
    height: 100%;
    padding: 0.875rem 1rem;
    border-radius: var(--telire-radius);
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
}

/* Ces libellés nomment la valeur qu'ils surmontent : ils ne doivent pas être plus discrets
   que les dates. Ils sont donc au corps du texte secondaire, pas au corps « micro ». */
.stat-tile__label {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: var(--fs-meta);
    font-weight: 500;
    color: var(--bs-secondary-color);
    margin-bottom: 0.2rem;
}

.stat-tile__label .icon { width: 14px; height: 14px; }

.stat-tile__value {
    font-size: var(--fs-value);
    font-weight: 600;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

/* Tuiles imbriquées dans une carte de période : un cran en dessous des totaux du haut,
   sinon les deux niveaux de hiérarchie se disputent l'attention. */
.stat-tile--compact {
    padding: 0.625rem 0.75rem;
    background: var(--bs-tertiary-bg);
    border-color: transparent;
}

.stat-tile--compact .stat-tile__value { font-size: var(--fs-value-sm); }

.stat-tile__value--in { color: var(--telire-in); }
.stat-tile__value--out { color: var(--telire-out); }

.icon { width: 16px; height: 16px; flex: none; }
.icon--in { color: var(--telire-in); }
.icon--out { color: var(--telire-out); }

/* Dans un bouton, l'icône doit s'aligner sur la ligne de base du texte. */
.btn .icon { vertical-align: -0.15em; margin-right: 0.15rem; }

/* Onglets en pastilles */
.segmented {
    display: inline-flex;
    flex: none;
    flex-wrap: nowrap;
    padding: 0.25rem;
    gap: 0.25rem;
    background: var(--bs-tertiary-bg);
    border-radius: 999px;
    border: 0;
}

.segmented .nav-link {
    border: 0;
    border-radius: 999px;
    padding: 0.35rem 0.9rem;
    font-size: var(--fs-meta);
    font-weight: 500;
    color: var(--bs-secondary-color);
}

.segmented .nav-link.active {
    background: var(--bs-body-bg);
    color: var(--bs-body-color);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

/* Liste de transactions — remplace les tableaux, illisibles sur mobile */
.txn-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.txn {
    border-bottom: 1px solid var(--bs-border-color-translucent);
}

.txn:last-child { border-bottom: 0; }

/* Toute la ligne est cliquable : cible tactile confortable, pas de petit bouton à viser. */
.txn__link {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.7rem 0.5rem;
    margin: 0 -0.5rem;
    border-radius: 10px;
    color: inherit;
    text-decoration: none;
}

.txn__link:hover { background: var(--bs-tertiary-bg); color: inherit; }

/* Ligne en lecture seule : rien ne doit laisser croire qu'elle mène quelque part. */
.txn__link--static, .txn__link--static:hover, .txn__link--static:active { background: none; }

/* Indique que la ligne mène quelque part, faute de survol sur mobile. */
.txn__chevron {
    align-self: center;
    width: 14px;
    height: 14px;
    color: var(--bs-secondary-color);
    opacity: 0.6;
}

/* Le libellé absorbe l'espace restant : sans cela, space-between répartissait les trois
   blocs et le montant flottait à une position différente selon la longueur du libellé. */
.txn__main {
    flex: 1 1 auto;
    min-width: 0;
}

.txn__label {
    overflow-wrap: anywhere;
}

.txn__meta {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    font-size: var(--fs-meta);
    color: var(--bs-secondary-color);
    margin-top: 0.1rem;
}

.txn__tag {
    display: inline-block;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    background: var(--telire-accent-soft);
    color: var(--bs-body-color);
    font-size: var(--fs-micro);
}

/* Même corps que le libellé : plus gros, le montant écrase la lecture de la ligne. */
.txn__amount {
    flex: none;
    font-size: 1em;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    text-align: right;
}

.txn__amount--in { color: var(--telire-in); }
.txn__amount--out { color: var(--telire-out); }

.empty-state {
    padding: 1.5rem 0;
    text-align: center;
    color: var(--bs-secondary-color);
    font-size: var(--fs-meta);
}

/* ------------------------------------------------------------ Formulaires */

.form-card { position: relative; }

.form-card__index {
    position: absolute;
    top: -0.6rem;
    left: 1rem;
    padding: 0.1rem 0.6rem;
    border-radius: 999px;
    background: var(--telire-accent);
    color: #fff;
    font-size: 0.6875rem;
    font-weight: 600;
}

[data-bs-theme="dark"] .form-card__index { color: #06232a; }

/*
 * Barre d'actions collée au-dessus de la navigation basse.
 *
 * Réservée aux écrans à **formulaire unique** — la saisie de dépenses et de revenus. Deux barres
 * collantes sur la même page collent toutes les deux : elles se superposent au défilement et
 * s'empilent avec la navigation basse. Les pages qui portent deux formulaires (`/mon-compte`,
 * `/membres/{id}`) utilisent la variante `--inline`, qui reste dans le flux.
 */
.form-actions {
    position: sticky;
    bottom: calc(var(--telire-bottomnav-h) + 0.5rem);
    display: flex;
    gap: 0.5rem;
    padding: 0.75rem;
    border-radius: var(--telire-radius);
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.08);
}

.form-actions--inline {
    position: static;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
}

.form-actions .btn { flex: 1 1 0; }

/*
 * Champ de code : le bouton de révélation est greffé par app.js, jamais écrit dans un gabarit.
 * Le rembourrage à droite réserve sa place, sinon les derniers chiffres passent dessous.
 */
.code-field { position: relative; }

.code-field .form-control { padding-right: 2.75rem; }

.code-field__reveal {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    padding: 0;
    border: 0;
    background: none;
    color: var(--bs-secondary-color);
    border-radius: 0 10px 10px 0;
}

.code-field__reveal:hover { color: var(--bs-body-color); }
.code-field__reveal .icon { width: 19px; height: 19px; }

.form-label { font-size: var(--fs-meta); font-weight: 500; }
.form-control, .form-select { border-radius: 10px; }
.btn { border-radius: 10px; font-weight: 500; }

.btn-accent {
    background: var(--telire-accent);
    border-color: var(--telire-accent);
    color: #fff;
}

.btn-accent:hover, .btn-accent:focus {
    background: #0a4650;
    border-color: #0a4650;
    color: #fff;
}

[data-bs-theme="dark"] .btn-accent { color: #06232a; }
[data-bs-theme="dark"] .btn-accent:hover { color: #06232a; }

/* ------------------------------------------------- Code réinitialisé */

/*
 * Le code engendré par une réinitialisation, montré une seule fois (D-UX-5).
 *
 * Il partait dans un message d'alerte, au corps du texte courant, noyé dans une phrase de trois
 * lignes — l'information la moins reproductible de l'application présentée comme la plus banale.
 * Il est ici au corps du solde, en chiffres tabulaires, avec de quoi le copier.
 */
.code-reveal {
    padding: 1rem;
    border-radius: var(--telire-radius);
    border: 1px solid var(--telire-accent);
    background: var(--telire-accent-soft);
}

.code-reveal__label {
    font-size: var(--fs-micro);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--bs-secondary-color);
    margin: 0 0 0.35rem;
}

.code-reveal__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.code-reveal__code {
    font-size: var(--fs-hero);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: 0.12em;
    font-variant-numeric: tabular-nums;
    /* Sélectionnable au doigt : le bouton « Copier » exige un contexte sécurisé, la sélection non. */
    user-select: all;
}

.code-reveal__hint {
    font-size: var(--fs-meta);
    color: var(--bs-secondary-color);
    margin: 0.6rem 0 0;
}

/* -------------------------------------------------- Navigation par mois */

.month-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.month-nav__arrow {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    padding: 0.35rem 0;
}

.month-nav__arrow .icon { width: 18px; height: 18px; margin: 0; }

.month-nav__label {
    flex: 1 1 auto;
    text-align: center;
    font-size: var(--fs-title);
    font-weight: 600;
    text-transform: capitalize;
}

/* --------------------------------------------------------------- Connexion */

.login-shell {
    min-height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
}

.login-card { width: 100%; max-width: 24rem; }

.login-logo {
    width: 3.25rem;
    height: 3.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 18px;
    background: var(--telire-accent);
    color: #fff;
    font-weight: 700;
    margin-bottom: 0.75rem;
}

/* En sombre l'accent devient clair : du blanc dessus serait illisible. */
[data-bs-theme="dark"] .login-logo { color: #06232a; }

/* ------------------------------------------- Retrait de ligne et navigation */

.form-card__remove {
    position: absolute;
    top: -0.6rem;
    right: 0.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    padding: 0;
    border: 1px solid var(--bs-border-color);
    border-radius: 50%;
    background: var(--bs-body-bg);
    color: var(--telire-out);
}

.form-card__remove:hover {
    background: var(--telire-out);
    border-color: var(--telire-out);
    color: #fff;
}

.form-card__remove .icon { width: 15px; height: 15px; }

.back-link {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin-bottom: 0.75rem;
    font-size: var(--fs-meta);
    color: var(--bs-secondary-color);
    text-decoration: none;
}

.back-link:hover { color: var(--bs-body-color); }
.back-link .icon { width: 15px; height: 15px; }

.modal-content { border-radius: var(--telire-radius); }
.modal-footer form { margin: 0; }

/* ---------------------------------------------------------------- Membres */

/* .txn__link aligne sur la ligne de base ; l'avatar et le bouton doivent être recentrés. */
.member-avatar {
    flex: none;
    align-self: center;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background: var(--telire-accent-soft);
    color: var(--telire-accent);
    font-size: var(--fs-meta);
    font-weight: 600;
}

.txn__link > .btn { flex: none; align-self: center; }
.txn__link > .btn .icon { width: 15px; height: 15px; }

.txn__tag--warn {
    background: var(--telire-out);
    color: #fff;
}

/* Le détail mensuel court sur plusieurs années : replié par défaut. */
.details-block > summary {
    cursor: pointer;
    padding: 0.6rem 0;
    font-size: var(--fs-meta);
    font-weight: 600;
    color: var(--bs-secondary-color);
}

.details-block > summary:hover { color: var(--bs-body-color); }

/* ------------------------------------------------- Barres du détail mensuel */

/*
 * Barres proportionnelles en CSS pur : Chart.js ou équivalent casserait le « zéro Node »
 * d'AssetMapper pour une trentaine de points de données. La largeur est posée en style inline par
 * le gabarit, c'est la seule information qu'il ait à transmettre.
 */
.month-bar {
    height: 4px;
    margin-top: 0.35rem;
    border-radius: 2px;
    background: var(--bs-tertiary-bg);
    overflow: hidden;
}

.month-bar__fill {
    display: block;
    height: 100%;
    border-radius: 2px;
    background: var(--telire-accent);
}

/*
 * Écart d'un mois sur l'autre. Le montant du mois seul ne dit pas s'il est bon : il faut un point
 * de comparaison, et le mois précédent est le seul que tout le monde a en tête.
 *
 * La flèche double la couleur plutôt que de la remplacer : le sens ne doit pas reposer sur le vert
 * et le rouge seuls.
 */
.trend {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    white-space: nowrap;
}

.trend .icon { width: 14px; height: 14px; }
.trend--up { color: var(--telire-in); }
.trend--down { color: var(--telire-out); }

/*
 * Groupe d'année dans le détail replié. Sans en-tête, l'historique complet est une colonne de
 * trente lignes où l'on ne sait plus quelle année on lit ; le sous-total évite d'avoir à
 * additionner de tête.
 *
 * L'en-tête était au corps « meta », en couleur secondaire, sous un simple filet : plus petit et
 * plus pâle que les mois qu'il contenait. La hiérarchie était à l'envers et, en dépliant, on ne
 * voyait plus où une année finissait et où la suivante commençait. Il est maintenant au corps des
 * titres de carte, sur une bande pleine, et les mois lui sont rattachés par un filet latéral.
 */
.year-group + .year-group { margin-top: 1.5rem; }

.year-group__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.35rem;
    padding: 0.4rem 0.7rem;
    border-radius: 8px;
    background: var(--bs-tertiary-bg);
}

.year-group__year {
    margin: 0;
    font-size: var(--fs-title);
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--bs-body-color);
    font-variant-numeric: tabular-nums;
}

/* Le sous-total est nommé : un second nombre à côté d'une année se lit sinon comme une donnée
   de plus, sans qu'on sache de quoi elle est la somme. */
.year-group__total {
    font-size: var(--fs-meta);
    font-weight: 500;
    color: var(--bs-secondary-color);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.year-group__months {
    margin-left: 0.7rem;
    padding-left: 0.85rem;
    border-left: 2px solid var(--bs-border-color);
}

/* ------------------------------------------------- Mouvement réduit */

/*
 * Respecte le réglage système. Les transitions ajoutées plus haut sont un confort, pas une
 * information : aucune ne porte de sens qui serait perdu en les coupant.
 */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    .btn:active { transform: none; }
}

/* ------------------------------------------------------- Relevé imprimable */

/*
 * « Ma part » doit pouvoir se poser sur une table. Pas de génération de PDF : une feuille print
 * suffit, et le navigateur sait déjà exporter en PDF.
 */
@media print {
    .app-topbar,
    .app-bottomnav,
    .btn,
    .form-actions,
    .modal,
    .back-link,
    .balance__link,
    .no-print { display: none !important; }

    body { background: #fff; }

    /*
     * Le bandeau de solde est en blanc sur dégradé. Les navigateurs n'impriment pas les fonds sans
     * réglage explicite : laissé tel quel, le montant le plus important de la page sortirait en
     * blanc sur blanc — c'est-à-dire pas du tout.
     */
    .balance {
        background: none !important;
        color: #000;
        border: 1px solid #ddd;
    }

    .balance__label,
    .balance__hint { opacity: 1; }

    #main-content { padding: 0; max-width: none; }

    .card {
        border: 1px solid #ddd;
        break-inside: avoid;
    }

    /* Le détail mensuel est replié à l'écran ; sur papier, tout doit être là. */
    .details-block > summary { display: none; }
    .details-block[open],
    .details-block { display: block; }
    .details-block > *:not(summary) { display: block !important; }

    /* Les barres ne survivent pas à l'impression en noir et blanc, et le chiffre suffit. */
    .month-bar { display: none; }

    a[href]::after { content: ""; }
}
