/* DANIEL — l'interface.

   ── Les quatre détails qui font « une app » plutôt qu'« un site en plein
   écran » sur iPhone : l'encoche respectée, pas de sélection au maintien du
   doigt, un défilement à inertie sans rebond parasite, et des champs à 16 px
   qui n'entraînent pas de zoom au focus. Ils sont tous en haut du fichier.

   ── Le parti pris de forme : des LISTES GROUPÉES en VERRE. Le bloc reste un
   bloc — des filets fins entre les lignes, de l'air autour, c'est ce qui fait
   « app » plutôt que « site », et c'est plus dense. Mais le bloc est
   translucide : il laisse passer la nappe colorée du fond, floue et saturée.
   C'est ce qui fait le « liquid ».

   ── Le flou se pose sur le BLOC, jamais sur la ligne. Un `backdrop-filter`
   par bloc, c'est trois ou quatre par écran ; un par ligne, c'est quarante, et
   ça fait ramer un iPhone pour un rendu identique. Les lignes à l'intérieur
   sont donc TRANSPARENTES — c'est le bloc qui porte la matière.
*/

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

/* La nappe. Elle vit sur `html` et pas dans un pseudo-élément : un `::before`
   fixé en z-index négatif passerait DERRIÈRE le fond de son parent, et il
   faudrait alors jouer des contextes d'empilement pour le faire ressortir —
   exactement le piège qui a déjà coûté un écran noir sur le prototype.
   `fixed` : la nappe ne défile pas, seul le contenu glisse dessus. */
html {
  height: 100%;
  /* `--defile` (0→1) et `--glisse` (px) sont écrits par le moteur de
     défilement dans app.js. Les valeurs par défaut sont ici pour que la page
     soit juste AVANT que le script tourne. */
  --defile: 0;
  --glisse: 0;
  /* ── LE SOL DE LA FOLIE ─────────────────────────────────────────────────
     Deux nappes et un dégradé, repris tels quels de son `#bgfx`. Peint sur
     `html` plutôt que dans un div dédié : un `::before` en z-index négatif
     passerait DERRIÈRE le fond de son parent, et il faudrait alors jouer des
     contextes d'empilement — exactement le piège qui a déjà coûté un écran
     noir sur le prototype.

     Ce sol varie très peu, et c'est tout l'intérêt : il n'y a plus rien à
     compresser, donc le verre redevient une seule couleur translucide et les
     encres redeviennent translucides elles aussi. Tout l'échafaudage de §30 et
     §33 tombe avec lui. */
  background:
    radial-gradient(120% 90% at 12% -8%,   var(--sol-haut), transparent 52%),
    radial-gradient(150% 110% at 88% 112%, var(--sol-bas),  transparent 58%),
    linear-gradient(168deg, var(--sol-1) 0%, var(--sol-2) 46%, var(--sol-3) 100%);
  /* La dérive : deux nappes qui glissent à contre-sens, très peu. C'est
     l'ÉCART entre elles qui se lit comme de la profondeur. */
  background-position:
    0 calc(var(--glisse) * -1px),
    0 calc(var(--glisse) * 0.7px),
    0 0;
  background-attachment: fixed;
  background-repeat: no-repeat;
}

body {
  margin: 0; padding: 0;
  min-height: 100%;
  background: transparent;
  color: var(--encre);
  /* 15 px, pas 16 : c'est le texte courant de LA FOLIE. Plus dense — c'est ce
     qui fait qu'une liste se lit comme un catalogue et pas comme un
     formulaire. Les CHAMPS restent à 16 px, deux lignes plus bas. */
  font: 400 var(--t-l)/20px var(--sans);
  -webkit-font-smoothing: antialiased;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
  overscroll-behavior-y: none;
}
input, textarea { -webkit-user-select: text; user-select: text; }
input, textarea, select, button { font-size: 16px; font-family: inherit; }

button { border: 0; background: none; color: inherit; cursor: pointer; padding: 0; }
a { color: var(--accent); text-decoration: none; }
ul { list-style: none; margin: 0; padding: 0; }
::selection { background: var(--prim-fond); color: var(--prim-encre); }

/* ── Structure ─────────────────────────────────────────────────────────── */
#app { min-height: 100%; }
.cadre { display: flex; min-height: 100vh; min-height: 100dvh; }

.ecran {
  flex: 1; min-width: 0;
  padding: 0 var(--s-4);
  /* 18 px (le dock flotte) + 58 px (sa hauteur) + de l'air. Le contenu passe
     DESSOUS la pilule quand on défile : c'est ce qui lui donne sa matière —
     un verre qui ne couvre rien ne réfracte rien. */
  padding-top: calc(env(safe-area-inset-top) + 92px);
  padding-bottom: calc(env(safe-area-inset-bottom) + var(--s-10));
  max-width: 640px; margin: 0 auto;
}
/* Sur téléphone la barre est en bas : le dégagement change de côté. */
@media (max-width: 767px) {
  .ecran {
    padding-top: calc(env(safe-area-inset-top) + var(--s-5));
    /* 12 px (elle flotte) + 58 px (sa hauteur) + de l'air. */
    padding-bottom: calc(env(safe-area-inset-bottom) + 94px);
  }
}
/* L'entrée ne se joue qu'au CHANGEMENT D'ÉCRAN. Sans ce garde-fou, archiver
   une ligne refait fondre toute la page — le geste a l'air de rater alors
   qu'il a réussi. */
.ecran.nouveau { animation: entree var(--base) var(--ressort) both; }
@keyframes entree { from { opacity: 0; transform: translateY(8px); } }

/* ── L'en-tête d'accueil ───────────────────────────────────────────────────
   Trois niveaux, et rien d'autre : la date, la phrase, le reste à faire.
   La réponse à la question de l'app tient dans les deux premiers ; le
   troisième dit ce qui attendra. */
.entete { margin: var(--s-2) 0 var(--s-6); }

.entete .haut {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); margin-bottom: var(--s-3);
}
.entete .date { color: var(--encre-mute); }
.entete .date::first-letter { text-transform: uppercase; }
/* La marque, discrète, en haut à droite. Elle signe l'écran sans le décorer. */
.entete .signature { width: 22px; height: 22px; color: var(--encre-fant); flex: none; }

.entete h1 { margin: 0; max-width: 17ch; text-wrap: balance; }
.entete .resume {
  margin: var(--s-3) 0 0;
  color: var(--encre-mute);
}
.entete .resume b { font-weight: 600; color: var(--encre-dim); }

.section { margin: 0 0 var(--s-6); }
.section > h2 { margin: 0 0 var(--s-2) var(--s-1); color: var(--encre-mute); }

/* ── Le débit de la semaine ────────────────────────────────────────────────
   Une jauge de deux pixels et une phrase. C'est le seul endroit de l'app qui
   parle d'avancement plutôt que de retard — donc le seul qui a le droit de
   prendre l'accent, et seulement quand l'objectif est tenu. */
.debit { margin: var(--s-4) 0 0; }
.debit .jauge {
  height: 3px; border-radius: var(--rd-pill);
  background: color-mix(in srgb, var(--encre) 10%, transparent);
  overflow: hidden;
}
.debit .jauge span {
  display: block; height: 100%; border-radius: inherit;
  background: var(--accent);
  transition: width var(--base) var(--ressort);
}
.debit p { margin: 7px 0 0; color: var(--encre-mute); }
.debit p b { color: var(--encre); font-weight: 600; }
.debit .atteint { color: var(--accent); font-weight: 600; }

/* ── Une pile de l'accueil ─────────────────────────────────────────────────
   L'en-tête est CLIQUABLE et mène à l'écran complet : c'est le seul renvoi
   dont on a besoin, et il tient dans le titre qu'on lisait de toute façon.
   Le compte est à droite, en chiffres tabulaires, pour que les trois piles
   alignent leurs nombres. */
.pile-tete {
  display: flex; align-items: center; gap: var(--s-2);
  width: 100%; padding: 0 var(--s-1) var(--s-2);
  color: var(--encre-dim);
  transition: color var(--rapide) linear;
}
@media (hover: hover) { .pile-tete:hover { color: var(--encre); } }
.pile-tete .ic { width: 14px; height: 14px; flex: none; }
.pile-tete .t-oeilleton { flex: 1; text-align: left; }
.pile-tete .n { font-size: 13px; }

/* Une pile vide ne disparaît pas : elle se replie sur une phrase. L'ordre des
   trois piles doit rester le même d'une ouverture à l'autre, sinon on relit
   l'écran au lieu de le reconnaître. */
.pile[data-vide] { margin-bottom: var(--s-5); }
.pile[data-vide] .pile-tete { color: var(--encre-fant); }
.pile-vide { margin: 0 0 0 var(--s-1); color: var(--encre-fant); }

/* « 3 de plus » : le pied d'une pile tronquée. Sans lui, la liste ment. */
.renvoi.suite { justify-content: center; padding: 11px var(--s-4); }
.renvoi.suite .libelle {
  flex: none; color: var(--encre-mute);
  font: 500 13px/18px var(--sans);
}

/* ── L'en-tête compact au défilement : retiré le 2026-08-18 ────────────────
   Il posait une barre de verre en haut de l'écran quand le grand titre sortait.
   Le dock y est maintenant, et deux barres au même endroit c'est une de trop.
   Sur LA FOLIE il n'y en a jamais eu qu'une : c'est la pastille d'accent sous
   l'icône active qui dit où l'on est.

   Le fondu du grand titre (`--defile`) part avec lui : il n'avait de sens que
   parce qu'une autre barre prenait le relais. Sans relais, un titre qui
   s'efface est juste un titre qu'on ne lit plus. Le moteur `--defile` reste,
   il sert encore au repli du dock et aux mesures. */

/* ── Le groupe : une liste, un bloc, UNE dalle de verre ────────────────────
   QUATRE couches, et c'est ce qui sépare le verre DÉPOLI (2013) du verre
   LIQUIDE (2026) :

     le bloc      floute, sature ET ÉCLAIRCIT ce qu'il y a derrière → la matière
     le bloc      un balayage doux sur son tiers haut                → la lumière
                  qui entre
     ::before     une bande à l'arête où le flou se resserre,
                  sature plus et s'éclaircit beaucoup                → la lentille
     ::after      un liseré dégradé, vif en haut à gauche,
                  éteint au milieu, qui revient en bas à droite      → l'épaisseur

   ── Ce qui manquait, et pourquoi ça ne ressemblait à rien ─────────────────
   Le `brightness`. Une vitre n'assombrit pas ce qu'elle couvre : elle récolte
   la lumière et la renvoie. Sans lui, du blanc à 8 % sur un fond sombre donne
   un gris plat, et aucune quantité de flou ne rattrape ça. C'est LE delta de
   luminance entre l'intérieur et l'extérieur du bloc que l'œil lit comme du
   verre — avant même la forme, avant même le liseré.

   Et sous l'arête claire, un filet SOMBRE. C'est le détail qu'on oublie : une
   arête brillante sans dessous flotte comme un trait de crayon ; avec son
   ombre, elle devient la tranche d'un objet qui a une épaisseur. */
.groupe {
  position: relative;
  /* Une seule couleur translucide, et l'arête d'un pixel tout autour. Le
     balayage du haut reste, à peine perceptible : c'est la lumière qui entre
     par l'arête haute. Tout le reste — voile + relève, liseré en dégradé,
     lentille de tranche — a disparu avec le sol qui le justifiait. */
  background-color: var(--verre);
  background-image: linear-gradient(to bottom, var(--spec-nappe), transparent 26px);
  backdrop-filter: var(--flou-moyen);
  -webkit-backdrop-filter: var(--flou-moyen);
  border: 0;
  border-radius: var(--rd-4);
  box-shadow: var(--reflet), var(--ombre-verre);
  overflow: hidden;
  /* `isolation` fige le contexte d'empilement du bloc : sans ça, le
     `backdrop-filter` en crée un implicitement et les actions de balayage
     posées en `absolute` sous les lignes remontent au-dessus du texte. */
  isolation: isolate;
}

/* ── La lentille de tranche : retirée le 2026-08-18 ────────────────────────
   Elle existait pour comprimer la lumière sur les 26 px du pourtour — l'idée
   était juste, et c'est ce qui distingue le verre ÉPAIS du verre dépoli.

   Elle n'a plus de sujet. Depuis que le voile monte à .82 (nuit) et .80
   (jour), la box est une surface presque égale : il n'y a plus de fond qui
   traverse, donc plus rien à comprimer. Elle ne peignait plus qu'un halo de
   pourtour — c'est-à-dire un dégradé de plus, exactement ce qu'on venait de
   retirer.

   On ne la garde donc pas « au cas où » : un `backdrop-filter` invisible coûte
   quand même une passe de flou PAR BLOC, et la règle du fichier est « un flou
   par bloc, pas quarante ». L'arête est désormais portée entièrement par le
   liseré (`::after`) et par les ombres `inset`, qui ne coûtent rien. */


/* ── Le liseré en dégradé : retiré le 2026-08-18 ───────────────────────────
   Il dessinait une arête vive en haut à gauche qui s'éteignait puis revenait en
   bas à droite. C'était juste sur un sol qui portait de la lumière ; sur le
   quasi-noir de LA FOLIE il ne se voit plus, et LA FOLIE elle-même n'en a pas :
   son `--glass-edge` est un anneau uni d'un pixel. C'est ce que `--reflet`
   fait maintenant. Un pseudo-élément de moins par bloc. */

/* Sans verre (Firefox sans la préférence, vieux WebView), on retombe sur une
   surface opaque : une translucidité non floutée laisserait lire la nappe au
   travers du texte. La lentille n'a alors plus rien à réfracter. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .groupe {
    background-color: var(--surface); background-image: none;
    border: 1px solid var(--trait); box-shadow: var(--ombre-verre);
  }
}
/* Le filet traverse toute la largeur. On l'avait d'abord voulu indenté sur le
   texte, à la manière d'iOS — mais une ligne qui se balaie translate, et un
   filet indenté laisse alors un moignon visible à gauche pendant le geste. */
.groupe > * + * { border-top: 1px solid var(--trait); }

.piste {
  position: relative;
  /* Le doigt glisse à l'horizontale, la page défile à la verticale. Sans ça,
     un balayage entraîne le défilement et rien ne se déclenche. */
  touch-action: pan-y;
  overflow: hidden;
  background: transparent;   /* c'est la dalle du groupe qui porte la matière */
}

/* Les actions révélées sous la ligne pendant le balayage. */
.piste::before, .piste::after {
  content: ''; position: absolute; inset: 0;
  opacity: 0; transition: opacity var(--rapide) linear;
}
.piste::before { background: var(--ok); }
.piste::after  { background: var(--tiede); }
.piste[data-geste="archiver"]::before { opacity: 1; }
.piste[data-geste="reporter"]::after  { opacity: 1; }

.piste .action {
  position: absolute; top: 0; bottom: 0;
  display: flex; align-items: center; gap: 7px;
  color: #fff; font: 600 14px/19px var(--sans);
  padding: 0 var(--s-5); opacity: 0;
  transition: opacity var(--rapide) linear;
}
.piste .action svg { width: 17px; height: 17px; }
.piste .action.g { left: 0; }
.piste .action.d { right: 0; }
.piste[data-geste="archiver"] .action.g { opacity: 1; }
.piste[data-geste="reporter"] .action.d { opacity: 1; }

/* ── La ligne ──────────────────────────────────────────────────────────── */
.rang {
  position: relative;
  background: transparent;
  padding: 13px var(--s-4);
  display: grid;
  grid-template-columns: 20px 1fr auto;
  column-gap: var(--s-3);
  align-items: start;
  /* Le fond n'est PAS dans la transition, et c'est délibéré : il doit basculer
     d'un coup quand le geste commence. Un fondu de 180 ms laisserait justement
     voir la couleur de l'action au travers du texte pendant qu'il se joue —
     exactement ce que l'opacité est censée empêcher. (Et une transition sur
     `background` restait accrochée au blanc après le geste : ligne opaque à
     vie au milieu du bloc de verre. Vu en vrai le 2026-08-16.) */
  transition: transform var(--base) var(--ressort);
  will-change: transform;
  text-align: left; width: 100%;
}
.rang.tire { transition: none; }
/* Pendant le geste ET pendant le retour : la carte redevient opaque, sinon la
   couleur de l'action se lit à travers son propre texte. */
.rang.tire, .rang.rend { background: var(--surface); }
@media (hover: hover) { .rang:hover { background: color-mix(in srgb, var(--encre) 4%, transparent); } }

/* Le canal est un glyphe MONOCHROME, pas une pastille de couleur : à l'écran,
   une couleur doit vouloir dire un état, jamais une catégorie. Les formes
   suffisent — enveloppe, bulle, objectif. */
.rang .canal { grid-column: 1; grid-row: 1 / span 2; color: var(--encre-fant); padding-top: 2px; }
.rang .canal svg { width: 16px; height: 16px; display: block; }

.rang .qui { grid-column: 2; grid-row: 1; display: flex; align-items: baseline; gap: 7px; min-width: 0; }
.rang .nom {
  font: 600 16px/21px var(--sans); letter-spacing: -.2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rang .societe {
  color: var(--encre-mute); font: 400 14px/21px var(--sans);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rang .sujet {
  grid-column: 2; grid-row: 2;
  color: var(--encre-dim); font: 400 14px/19px var(--sans);
  margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rang .extrait {
  grid-column: 2; grid-row: 3;
  color: var(--encre-mute); font: 400 13px/18px var(--sans);
  margin-top: 3px;
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;
}

/* ── L'élément signature : le compteur de silence ──────────────────────────
   Le seul endroit de l'app où une couleur apparaît sans qu'on l'ait demandée.
   Elle veut dire : ça traîne. */
.compteur {
  grid-column: 3; grid-row: 1 / span 2; align-self: start;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 17px; font-weight: 500; line-height: 21px;
  color: var(--encre-fant);
  transition: color 400ms linear;   /* changement de palier en fondu, jamais en clignotement */
  white-space: nowrap; padding-top: 1px;
}
.compteur .u { font-size: 11px; margin-left: 1px; opacity: .7; }
.compteur.bientot { color: var(--tiede); }
.compteur.tard    { color: var(--chaud); font-weight: 600; }

.rang .epingle { position: absolute; top: 6px; right: 6px; font-size: 9px; opacity: .6; }

.piste.part { animation: sort 240ms var(--ressort) both; }
@keyframes sort { to { opacity: 0; max-height: 0; padding: 0; border-width: 0; } }

/* ── Lignes de renvoi ──────────────────────────────────────────────────── */
.renvoi {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%; padding: 15px var(--s-4);
  background: transparent; text-align: left;
  transition: background var(--rapide) linear;
}
.renvoi:active { background: color-mix(in srgb, var(--encre) 6%, transparent); }
.renvoi .ic { width: 18px; height: 18px; color: var(--encre-fant); flex: none; }
.renvoi .libelle { flex: 1; }
.renvoi .n { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--encre-mute); }
.renvoi .chevron { color: var(--encre-fant); width: 15px; height: 15px; flex: none; }

/* ══════════════════════ LES COMMANDES : le verre descend jusqu'en bas ══════
   Un champ de recherche et un contrôle segmenté posés en gris plat À CÔTÉ d'un
   bloc de verre, ça se voit immédiatement : ils datent de l'écran d'avant.
   C'était le décrochage le plus visible de l'app — trois blocs de verre
   magnifiques, et au-dessus d'eux quatre rectangles opaques.

   Dans le système d'Apple, TOUT ce qui flotte au-dessus du fond est la même
   matière ; seule l'ÉPAISSEUR change. Les commandes prennent donc le même
   verre que les blocs, avec un flou plus court : elles font 34 px de haut, et
   flouter sur 26 px ce qui tient sur 34 ne floute rien de plus qu'un flou de
   14 — c'est du calcul jeté par la fenêtre, sur la seule machine (un iPhone)
   où il coûte quelque chose. */

/* ── Contrôle segmenté ─────────────────────────────────────────────────── */
.segment {
  display: flex; gap: 2px; padding: 3px;
  background-color: var(--verre);
  backdrop-filter: var(--flou-fin);
  -webkit-backdrop-filter: var(--flou-fin);
  border-radius: var(--rd-3);
  /* Le rail est CREUX : son ombre est portée vers l'intérieur, à l'inverse
     d'un bloc. C'est ce qui fait qu'une lamelle a l'air posée DEDANS. */
  box-shadow: inset 0 1px 3px -1px var(--tranche);
  margin: 0 0 var(--s-4);
}
.segment button {
  flex: 1; padding: 8px 6px;
  border-radius: var(--rd-1);
  font: 500 14px/18px var(--sans); color: var(--encre-dim);
  transition: background var(--rapide) linear, color var(--rapide) linear;
  white-space: nowrap;
  /* Sans dimension explicite, un SVG en flex prend toute la place qu'il peut
     et écrase le libellé à côté de lui. */
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.segment button svg { width: 15px; height: 15px; flex: none; }
.segment button[aria-selected="true"] {
  /* Pas une autre couleur : le MÊME verre, plus épais et mieux éclairé. */
  background: var(--verre-actif);
  color: var(--encre);
  box-shadow: var(--reflet), var(--ombre-posee);
  font-weight: 600;
}
.segment .badge { font-family: var(--mono); font-size: 12px; color: var(--encre-mute); margin-left: 5px; }

/* ── Recherche ─────────────────────────────────────────────────────────── */
.recherche {
  display: flex; align-items: center; gap: var(--s-2);
  padding: 10px var(--s-3); margin-bottom: var(--s-3);
  background-color: var(--verre);
  backdrop-filter: var(--flou-fin);
  -webkit-backdrop-filter: var(--flou-fin);
  border-radius: var(--rd-pill);
  /* Creux, comme le rail du segment : un champ est une chose dans laquelle on
     écrit, pas une chose posée dessus. */
  box-shadow: inset 0 1px 3px -1px var(--tranche);
  transition: box-shadow var(--rapide) linear;
}
.recherche:focus-within {
  box-shadow: inset 0 1px 3px -1px var(--tranche), 0 0 0 3px var(--accent-voile);
}
.recherche svg { width: 16px; height: 16px; color: var(--encre-mute); flex: none; }
.recherche input {
  flex: 1; border: 0; outline: none; background: none; color: var(--encre);
  font: 400 16px/21px var(--sans);
}
.recherche input::placeholder { color: var(--encre-fant); }

/* ── Tâches ────────────────────────────────────────────────────────────── */
.ajout {
  display: flex; align-items: center; gap: var(--s-2);
  background: var(--verre);
  backdrop-filter: blur(var(--verre-flou)) saturate(var(--verre-sat));
  -webkit-backdrop-filter: blur(var(--verre-flou)) saturate(var(--verre-sat));
  border: 1px solid var(--verre-bord);
  border-radius: var(--rd-3);
  box-shadow: var(--reflet), var(--ombre-verre);
  padding: 4px 5px 4px var(--s-4);
  margin-bottom: var(--s-2);
}
.ajout input {
  flex: 1; border: 0; outline: none; background: none; color: var(--encre);
  padding: 12px 0; font: 400 16px/21px var(--sans);
}
.ajout input::placeholder { color: var(--encre-fant); }
.ajout .rond {
  width: 32px; height: 32px; flex: none; border-radius: var(--rd-pill);
  display: grid; place-items: center;
  transition: transform var(--rapide) var(--ressort), opacity var(--rapide) linear;
}
.ajout .rond svg { width: 16px; height: 16px; }
.ajout .rond.plein { background: var(--prim-fond); color: var(--prim-encre); }
.ajout .rond.creux { color: var(--encre-mute); }
.ajout .rond:disabled { opacity: .3; }
.ajout .rond:active:not(:disabled) { transform: scale(.9); }

.indice { color: var(--encre-mute); font: 400 13px/18px var(--sans); margin: 0 0 var(--s-5) var(--s-1); min-height: 18px; }
.indice b { color: var(--encre); font-weight: 600; }

.tache { display: flex; align-items: flex-start; gap: var(--s-3); padding: 13px var(--s-4); background: transparent; }
.tache .case {
  width: 21px; height: 21px; flex: none; margin-top: 1px;
  border-radius: 50%; border: 1.5px solid var(--encre-fant);
  display: grid; place-items: center; color: transparent;
  transition: background var(--rapide) var(--ressort), border-color var(--rapide) linear, transform var(--rapide) var(--ressort);
}
.tache .case:active { transform: scale(.88); }
.tache .case svg { width: 12px; height: 12px; }
.tache.faite .case { background: var(--ok); border-color: var(--ok); color: #fff; }
.tache .corps { flex: 1; min-width: 0; text-align: left; }
.tache .titre { font: 400 16px/21px var(--sans); }
.tache.faite .titre { color: var(--encre-mute); text-decoration: line-through; }
.tache .meta { color: var(--encre-mute); font: 400 13px/18px var(--sans); margin-top: 2px; display: flex; gap: var(--s-2); flex-wrap: wrap; align-items: center; }
.tache .meta .retard { color: var(--chaud); font-weight: 600; }
.tache .meta .projet { color: var(--encre-dim); }
.tache .meta svg { width: 12px; height: 12px; }

/* La ligne sous le composeur : l'analyse de la phrase à gauche, le classement
   à droite. Le `select` reste discret — c'est une correction, pas une étape :
   on ne doit pas croire qu'il faut le remplir avant d'écrire. */
.ajout-bas {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3); margin: var(--s-2) var(--s-1) var(--s-4);
}
.ajout-bas .indice { margin: 0; min-width: 0; flex: 1; }
.classer {
  flex: none; max-width: 45%;
  padding: 6px 10px; border: 0; border-radius: var(--rd-pill);
  background: var(--verre);
  backdrop-filter: var(--flou-fin); -webkit-backdrop-filter: var(--flou-fin);
  box-shadow: var(--reflet);
  color: var(--encre-dim);
  font: 400 var(--t-s)/1.4 var(--sans);
  /* 16 px sur mobile, sinon iOS zoome de force au focus et ne dézoome jamais.
     On garde donc la petite taille au-dessus du seuil tactile seulement. */
  -webkit-appearance: none; appearance: none;
  text-align: right;
}
@media (max-width: 767px) { .classer { font-size: 16px; } }
.classer:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Lignes de réglages ────────────────────────────────────────────────── */
.ligne {
  display: flex; align-items: center; gap: var(--s-3);
  padding: 13px var(--s-4);
  background: transparent;
  text-align: left; width: 100%;
}
.ligne .libelle { flex: 1; min-width: 0; }
.ligne .libelle small { display: block; color: var(--encre-mute); font: 400 13px/18px var(--sans); margin-top: 2px; }
.ligne .valeur { color: var(--encre-mute); font-family: var(--mono); }
.ligne input[type="text"], .ligne input[type="time"], .ligne input[type="number"], .ligne input[type="tel"] {
  border: 1px solid var(--trait); outline: none; background: var(--surface-2);
  border-radius: var(--rd-1); padding: 7px 10px; color: var(--encre);
  font: 400 14px/19px var(--mono); text-align: right; max-width: 132px;
}
.ligne.danger .libelle { color: var(--chaud); }
.ligne.action .libelle { color: var(--accent); font-weight: 500; }

.pastille-etat { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--encre-fant); }
.pastille-etat.on  { background: var(--ok); }
.pastille-etat.off { background: var(--chaud); }
/* Quelqu'un attend qu'on lui rouvre son accès. Ambre et pas rouge : ce n'est
   pas une panne, c'est une chose à faire. */
.pastille-etat.alerte { background: var(--tiede); }

.bouton {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: 14px var(--s-5); border-radius: var(--rd-3);
  background: var(--prim-fond); color: var(--prim-encre);
  font: 600 16px/21px var(--sans); width: 100%;
  transition: transform var(--rapide) var(--ressort), opacity var(--rapide) linear;
}
.bouton:active { transform: scale(.985); }
.bouton:disabled { opacity: .4; }
.bouton.creux { background: var(--trait); color: var(--encre); }

.apercu {
  white-space: pre-wrap; margin: 0;
  font: 400 13px/19px var(--mono); color: var(--encre-dim);
  background: var(--surface); border: 1px solid var(--trait);
  border-radius: var(--rd-3); padding: var(--s-4);
  -webkit-user-select: text; user-select: text;
}

/* ── Écran vide : une récompense, pas une erreur ───────────────────────── */
.vide { padding: 52px var(--s-2); text-align: center; }
.vide .marque { width: 40px; height: 40px; margin: 0 auto var(--s-4); color: var(--encre-fant); }
.vide h3 { margin: 0 0 6px; font: 600 19px/24px var(--sans); letter-spacing: -.25px; }
.vide p { margin: 0 auto; max-width: 32ch; color: var(--encre-mute); font: 400 14px/20px var(--sans); }

/* ── L'œil : la marque ─────────────────────────────────────────────────────
   Le logo est un SVG monochrome. On le pose en MASQUE plutôt qu'en image : la
   couleur vient alors de `background`, donc de `currentColor` — ce qui le rend
   juste au jour comme à la nuit, avec un seul fichier. */
.oeil {
  display: block;
  background: currentColor;
  -webkit-mask: url(/assets/logo-icon.svg) center / contain no-repeat;
  mask: url(/assets/logo-icon.svg) center / contain no-repeat;
}

/* ══════════════════════════ LE DOCK ══════════════════════════════════════
   Repris de LA FOLIE (DA.md §8, « exigence ferme ») : une pilule de verre EN
   HAUT, repliée au repos sur le seul logo, déployée au survol. La tab bar en
   bas y a été essayée et refusée — c'est ce que DANIEL avait.

   `width: max-content` + `left:50%` + `translateX(-50%)` : la pilule grandit
   en restant centrée. C'est ce qui fait que le déploiement a l'air de
   s'ouvrir depuis le logo, et pas de pousser vers la droite. */
.appbar {
  position: fixed; top: 18px; left: 50%; transform: translateX(-50%); z-index: 55;
  width: max-content; max-width: calc(100vw - 24px); height: 58px; padding: 0 10px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--rd-pill);
  /* Même motif que `.groupe` : `background-color` + `background-image`, et la
     couleur du milieu écrite en dégradé plat. Le raccourci `background` avec
     une couleur ailleurs qu'en dernière couche est INVALIDE, et le navigateur
     jette la déclaration entière — le dock se serait affiché sans aucun fond.
     Attrapé par `scripts/verifier-contraste.js` avant d'atteindre l'écran. */
  background-color: var(--verre-chrome);
  background-image: linear-gradient(to bottom, var(--spec-nappe), transparent 26px);
  backdrop-filter: var(--flou-moyen);
  -webkit-backdrop-filter: var(--flou-moyen);
  box-shadow:
    var(--reflet),
    inset 0 8px 16px -10px var(--tranche),
    var(--ombre-flot);
}
.appdock { display: flex; align-items: center; gap: 2px; }

/* ── Le dock reste DÉPLOYÉ, toujours ──────────────────────────────────────
   Il se repliait sur le seul logo au repos et s'ouvrait au survol — c'est le
   geste de LA FOLIE (DA.md §8). Retiré sur demande d'Isma, et il avait un vrai
   défaut : la pilule change de largeur, donc elle se RE-CENTRE, donc toutes
   les icônes glissent sous le curseur pendant l'ouverture. En passant d'un
   onglet à l'autre on voyait la barre se réorganiser à chaque fois.

   Une chrome qui bouge quand on la vise n'est pas une animation, c'est une
   cible mouvante. */
.nav-dock {
  display: flex; align-items: center; gap: 2px;
  margin: 0 10px;
}

.nav-item {
  position: relative; width: 46px; height: 46px; flex: none;
  display: grid; place-items: center; border-radius: 50%;
  color: var(--encre-mute);
  transition: color var(--rapide) linear, background var(--rapide) linear;
}
.nav-item:hover { color: var(--encre); background: var(--verre-actif); }
.nav-item.active { color: var(--encre); }
/* La pastille d'accent sous l'icône active. C'est elle qui dit où l'on est —
   c'est pour ça que l'en-tête compact au défilement a pu disparaître. */
.nav-item.active::after {
  content: ''; position: absolute; bottom: 5px; left: 50%; transform: translateX(-50%);
  width: 4px; height: 4px; border-radius: 50%; background: var(--accent);
}
.nav-item svg { width: 21px; height: 21px; }

.logo-btn {
  height: 46px; padding: 0 10px; border-radius: var(--rd-pill);
  display: grid; place-items: center; color: var(--encre);
  transition: background var(--rapide) linear;
}
.logo-btn:hover { background: var(--verre-actif); }
.logo-btn .oeil, .logo-btn svg { width: 26px; height: 26px; }

/* Le compteur, posé sur l'icône. */
.appbar .pt { position: relative; display: grid; place-items: center; }
.appbar .pt[data-n]::after {
  content: attr(data-n);
  position: absolute; top: -6px; right: -10px;
  min-width: 15px; height: 15px; padding: 0 4px;
  border-radius: var(--rd-pill);
  background: var(--chaud); color: var(--toile);
  font: 700 9px/15px var(--mono); text-align: center;
}

/* ── 768 → 920 px : tablette ───────────────────────────────────────────────
   Le dock reste en haut, mais DÉPLOYÉ : il n'y a pas de survol au doigt, et
   une pilule qui ne s'ouvre jamais est une pilule qui ne sert à rien. */
@media (min-width: 768px) and (max-width: 920px) {
  .nav-dock { margin: 0 6px; }
  .nav-item { width: 42px; height: 42px; }
}

/* ══════════════════ ≤ 767 px : LA BARRE PASSE EN BAS ══════════════════════
   Demande d'Isma : sur téléphone, une barre d'onglets en bas, en icônes, à la
   manière d'Instagram.

   ⚠️ C'est un écart ASSUMÉ à la charte de LA FOLIE, qui dit (DA.md §8, en
   « exigence ferme ») que la barre reste en haut quoi qu'il arrive, et que la
   tab bar en bas a été essayée puis refusée. L'écart ne vaut que pour le
   téléphone : au-dessus de 767 px, le dock de LA FOLIE reprend sa place en
   haut, replié au repos. La raison est le pouce — sur un écran tenu à une
   main, le haut de l'écran ne s'atteint pas.

   Pleine largeur et pas une pilule flottante : c'est ce qui distingue une tab
   bar d'iOS (qui flotte) d'une tab bar d'Instagram (qui est un socle). */
@media (max-width: 767px) {
  .appbar {
    /* Elle FLOTTE, comme le dock du web — même objet, autre bord de l'écran.
       Collée en socle, elle appartenait au téléphone ; détachée, elle
       appartient à l'app. Et le contenu passe DESSOUS, ce qui lui donne enfin
       quelque chose à réfracter. */
    top: auto; bottom: calc(env(safe-area-inset-bottom) + 12px);
    left: var(--s-3); right: var(--s-3);
    transform: none;
    width: auto; max-width: none;
    height: 58px; padding: 0 var(--s-2);
    border-radius: var(--rd-pill);
    box-shadow: var(--reflet), var(--ombre-flot);
  }
  .appdock { flex: 1; }
  .nav-dock { flex: 1; margin: 0; justify-content: space-around; }
  /* Le logo s'efface : il ne fait que ramener à l'accueil, ce que la première
     icône fait déjà, et il volerait la place d'un onglet. */
  .logo-btn { display: none; }
  .nav-item { width: 44px; height: 44px; }
  .nav-item svg { width: 24px; height: 24px; }
  /* La pastille remonte : en bas elle sortirait du socle. */
  .nav-item.active::after { bottom: 2px; }
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .appbar { background: var(--surface); }
}

/* ── Feuilles modales ──────────────────────────────────────────────────── */
.voile {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(0, 0, 0, .38);
  display: flex; align-items: flex-end; justify-content: center;
  animation: fondu var(--rapide) linear both;
}
@keyframes fondu { from { opacity: 0; } }
@media (min-width: 768px) { .voile { align-items: center; } }

/* La feuille est le seul verre DENSE de l'interface : on y lit des champs et
   des libellés. À 70 % d'opacité, le texte de la page remonte au travers. */
.feuille {
  width: 100%; max-width: 440px;
  max-height: 88vh; overflow-y: auto;
  border-radius: var(--rd-5) var(--rd-5) 0 0;
  padding: var(--s-2) var(--s-3) calc(env(safe-area-inset-bottom) + var(--s-3));
  position: relative;
  background:
    linear-gradient(to bottom, var(--spec-nappe), transparent 26px),
    var(--verre-opaque);
  backdrop-filter: var(--flou-epais);
  -webkit-backdrop-filter: var(--flou-epais);
  border: 0;
  box-shadow:
    var(--reflet),
    inset 0 9px 18px -12px var(--tranche),
    var(--ombre-flot);
  animation: monteFeuille var(--base) var(--ressort) both;
  -webkit-overflow-scrolling: touch;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .feuille { background: var(--surface); }
}
@media (min-width: 768px) { .feuille { border-radius: var(--rd-5); margin: 0 var(--s-4); } }
@keyframes monteFeuille { from { transform: translateY(26px); opacity: 0; } }

.feuille .poignee { width: 34px; height: 4px; border-radius: 3px; background: var(--encre-fant); margin: 4px auto 10px; }
.feuille h3 { margin: 2px 0 var(--s-3); text-align: center; font: 600 16px/21px var(--sans); }
.feuille .choix { display: flex; flex-direction: column; gap: 1px; }
.feuille .choix button {
  padding: 14px var(--s-4); border-radius: var(--rd-2);
  text-align: left; font: 400 16px/21px var(--sans);
  display: flex; justify-content: space-between; align-items: center; gap: var(--s-3);
  transition: background var(--rapide) linear;
}
.feuille .choix button:active { background: var(--trait); }
.feuille .choix button.danger { color: var(--chaud); }
.feuille .choix button .quand { color: var(--encre-mute); font-family: var(--mono); font-size: 14px; }
.feuille .choix button .ic { width: 19px; height: 19px; flex: none; color: var(--encre-mute); }
.feuille .choix button .g { display: flex; align-items: center; gap: var(--s-3); min-width: 0; }
.feuille .annuler {
  margin-top: var(--s-2); width: 100%; padding: 14px; border-radius: var(--rd-3);
  background: var(--trait); font: 600 16px/21px var(--sans);
}

.champ { display: flex; flex-direction: column; gap: 5px; padding: var(--s-2) var(--s-2) var(--s-1); }
.champ label { font: 600 11px/14px var(--sans); letter-spacing: .09em; text-transform: uppercase; color: var(--encre-mute); padding-left: var(--s-2); }
.champ input, .champ select {
  border: 0; outline: none;
  background-color: var(--verre);
  backdrop-filter: var(--flou-fin);
  -webkit-backdrop-filter: var(--flou-fin);
  box-shadow: inset 0 1px 3px -1px var(--tranche);
  border-radius: var(--rd-2); padding: 12px var(--s-4);
  color: var(--encre); font: 400 16px/21px var(--sans);
  width: 100%; -webkit-appearance: none; appearance: none;
}
.champ input:focus, .champ select:focus {
  box-shadow: inset 0 1px 3px -1px var(--tranche), 0 0 0 3px var(--accent-voile);
}
.duo { display: flex; gap: var(--s-2); }
.duo > * { flex: 1; min-width: 0; }

/* ── Bandeau ───────────────────────────────────────────────────────────── */
/* Le bandeau dit une info de service — Gmail pas branché, une synchro en
   cours. Il ne doit jamais peser autant qu'une ligne de la liste : pas de
   carte, pas de fond, juste un filet vertical et du texte en retrait. */
.bandeau {
  margin: 0 0 var(--s-4); padding: 2px 0 2px 11px;
  border-left: 2px solid var(--trait-fort);
  font: 400 13px/18px var(--sans); color: var(--encre-mute);
  display: flex; align-items: center; gap: var(--s-3);
}
.bandeau.alerte { border-left-color: var(--chaud); color: var(--encre-dim); }
.bandeau button { font-size: 13px; }
.bandeau button { color: var(--accent); font-weight: 600; white-space: nowrap; }

/* ── Fiche contact ─────────────────────────────────────────────────────── */
.fiche-tete { text-align: center; padding: var(--s-1) 0 var(--s-5); }
.fiche-tete .rond {
  width: 66px; height: 66px; margin: 0 auto var(--s-3);
  border-radius: 50%;
  background: var(--prim-fond); color: var(--prim-encre);
  display: grid; place-items: center;
  font: 600 24px/1 var(--sans);
}
.fiche-tete h1 { margin: 0 0 3px; font: 700 23px/28px var(--sans); letter-spacing: -.4px; }
.fiche-tete p { margin: 0; color: var(--encre-mute); font: 400 14px/19px var(--sans); }
.fiche-actions { display: flex; gap: var(--s-2); margin: var(--s-4) 0 var(--s-6); }
.fiche-actions button, .fiche-actions a {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 11px 5px; border-radius: var(--rd-3);
  background: var(--verre);
  backdrop-filter: blur(var(--verre-flou)) saturate(var(--verre-sat));
  -webkit-backdrop-filter: blur(var(--verre-flou)) saturate(var(--verre-sat));
  border: 1px solid var(--verre-bord);
  box-shadow: var(--reflet), var(--ombre-verre);
  font: 500 11px/15px var(--sans); color: var(--encre-dim);
}
.fiche-actions svg { width: 18px; height: 18px; color: var(--encre); }

/* Le fil, littéralement : une ligne verticale qui relie tout ce qui s'est
   passé avec cette personne. */
.frise { position: relative; padding-left: var(--s-5); }
.frise::before {
  content: ''; position: absolute; left: 5px; top: 8px; bottom: 8px;
  width: 1px; background: var(--trait-fort);
}
.frise .item { position: relative; margin-bottom: var(--s-3); }
.frise .item::before {
  content: ''; position: absolute; left: -19px; top: 15px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--encre-fant); box-shadow: 0 0 0 3px var(--toile);
}
.frise .item.tache::before { background: var(--ok); }
.frise .item.envoi::before { background: var(--tiede); }
.frise .quand-item { color: var(--encre-fant); margin: 0 0 5px 2px; }

/* ── Connexion ─────────────────────────────────────────────────────────── */
.porte { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: var(--s-6); }
.porte .boite { width: 100%; max-width: 320px; text-align: center; }
.porte .oeil {
  width: 84px; height: 84px; margin: 0 auto var(--s-5);
  color: var(--encre);
  animation: ouvrir 800ms var(--ressort) both;
}
@keyframes ouvrir { from { opacity: 0; transform: scale(.85); } }
.porte h1 { margin: 0 0 5px; font: 700 28px/32px var(--sans); letter-spacing: -.5px; }
.porte p { margin: 0 0 var(--s-6); color: var(--encre-mute); font: 400 14px/20px var(--sans); }
.porte input {
  width: 100%; padding: 14px var(--s-4); margin-bottom: var(--s-2);
  border: 1px solid var(--trait-fort); border-radius: var(--rd-3);
  background: var(--surface); color: var(--encre);
  font: 400 16px/21px var(--sans); outline: none; text-align: center;
}
.porte input:focus { border-color: var(--encre-dim); }
.porte .erreur { color: var(--chaud); font: 400 13px/18px var(--sans); margin: var(--s-3) 0 0; min-height: 18px; }
.porte code {
  display: block; margin-top: var(--s-4); padding: 12px;
  background: var(--surface); border: 1px solid var(--trait); border-radius: var(--rd-2);
  font: 400 13px/18px var(--mono); color: var(--encre-dim);
  -webkit-user-select: text; user-select: text;
}

/* ── Chargement ────────────────────────────────────────────────────────── */
.chargement { display: grid; place-items: center; min-height: 60vh; }
.chargement .oeil { width: 34px; height: 34px; color: var(--encre-fant); animation: battement 1.6s ease-in-out infinite; }

/* ══════════════════════ DANIEL, LA MASCOTTE ══════════════════════════════
   Un vieux monsieur un peu enveloppé qui somnole, en 16 bits. C'est
   l'assistant de la maison : il a l'air de ne rien faire, et c'est le but.

   ── Au lancement : il tourne en rond ─────────────────────────────────────
   La ronde se fait en DEUX rotations imbriquées, et c'est le seul moyen de la
   faire proprement : le parent tourne et emmène l'enfant sur un cercle, et
   l'enfant tourne EN SENS INVERSE d'autant, ce qui annule sa propre rotation.
   Résultat : il fait le tour du cercle en restant debout. Une seule rotation
   le mettrait la tête en bas à mi-parcours — ce qui, pour quelqu'un qui dort,
   serait un autre sujet. */
.chargement--lancement { min-height: 100vh; min-height: 100dvh; }
.ronde {
  width: 96px; height: 96px;
  display: grid; place-items: center;
  animation: ronde 2.8s linear infinite;
}
.ronde-daniel {
  width: 72px; height: auto;
  image-rendering: pixelated;          /* du 16 bits ne s'interpole pas */
  animation: ronde-inverse 2.8s linear infinite, sommeil 2.8s ease-in-out infinite;
  filter: drop-shadow(0 10px 18px rgba(0, 0, 0, .45));
}
@keyframes ronde         { to { transform: rotate(360deg); } }
@keyframes ronde-inverse { to { transform: rotate(-360deg); } }
/* Il respire en dormant. L'amplitude est minuscule — au-delà, ce n'est plus
   quelqu'un qui dort, c'est quelqu'un qui rebondit.

   ⚠️ Sur `scale` et PAS sur `transform`. Deux animations qui visent `transform`
   sur le même élément ne se composent pas : la dernière déclarée écrase
   l'autre. Écrite en `transform`, la respiration annulait la contre-rotation
   et Daniel faisait le tour la tête penchée. `scale` est une propriété à part
   entière depuis 2022 : les deux cohabitent. */
@keyframes sommeil { 50% { scale: 1.06; } }

/* ── La route, en bas de l'écran (web seulement) ──────────────────────────
   Daniel traverse endormi au volant d'un taxi, de DROITE à GAUCHE. Le sens
   compte : une voiture qui entre par la droite et sort par la gauche traverse
   le regard ; dans l'autre sens elle l'accompagne, et on la suit au lieu de
   travailler.

   `aria-hidden` et `pointer-events: none` : c'est un décor. Il ne doit ni être
   annoncé aux lecteurs d'écran, ni intercepter un clic.

   `overflow: hidden` sur la bande : sans lui, le taxi qui sort par la gauche
   élargit le document et fabrique une barre de défilement horizontale. */
.daniel-route {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: -1;
  /* Assez haut pour la voiture ET les « z » qui montent au-dessus d'elle. À
     92 px, le toit du taxi était coupé net par l'`overflow: hidden`. */
  height: 150px; overflow: hidden;
  pointer-events: none;
  /* Il passe DERRIÈRE les blocs de verre, qui le floutent au passage, et se
     montre franchement dans les intervalles. C'est ce qui le rend vivant sans
     qu'il ait à être opaque. */
  opacity: .7;
}
/* Le bitume : un filet, et des pointillés qui défilent en sens inverse du
   taxi. C'est le décalage entre les deux qui donne la vitesse — le taxi seul
   sur un fond immobile a l'air de glisser. */
.daniel-route::after {
  content: ''; position: absolute; left: -40px; right: -40px; bottom: 20px; height: 2px;
  background: repeating-linear-gradient(to right,
    var(--encre-fant) 0 14px, transparent 14px 34px);
  opacity: .30;
  animation: bitume 1.6s linear infinite;
}
@keyframes bitume { to { transform: translateX(-34px); } }

.daniel-voiture {
  /* Les roues doivent poser SUR le filet de bitume (à 20 px), pas flotter
     au-dessus ni sortir de l'écran par le bas. */
  position: absolute; bottom: 14px; left: 0;
  width: clamp(150px, 15vw, 230px);
  animation: traversee 34s linear infinite;
}
.daniel-voiture img {
  display: block; width: 100%; height: auto;
  image-rendering: pixelated;
  /* Les suspensions. Deux pixels, pas plus : au-delà ce n'est plus une route,
     c'est un nid-de-poule. */
  animation: suspension .5s steps(2, end) infinite;
}
/* De 110 % à -110 % : il entre entièrement hors champ et en ressort de même,
   donc on ne le voit jamais apparaître ni disparaître d'un coup. */
@keyframes traversee {
  from { transform: translateX(110vw); }
  to   { transform: translateX(-110%); }
}
@keyframes suspension { 50% { transform: translateY(1px); } }

/* Il ronfle en roulant. Les trois « z » montent en décalé et s'effacent. */
.ronfle {
  position: absolute; left: 46%; bottom: 62%;
  font: 700 13px/1 var(--mono); color: var(--encre-mute);
  opacity: 0;
  animation: ronfle 2.4s ease-out infinite;
}
.ronfle.r2 { animation-delay: .8s;  font-size: 16px; }
.ronfle.r3 { animation-delay: 1.6s; font-size: 19px; }
@keyframes ronfle {
  0%   { opacity: 0;   transform: translate(0, 0) rotate(-8deg); }
  25%  { opacity: .55; }
  100% { opacity: 0;   transform: translate(-14px, -34px) rotate(10deg); }
}

/* Pas sur téléphone : la barre y flotte précisément à cet endroit, et l'écran
   est déjà plein. */
@media (max-width: 767px) { .daniel-route { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .ronde, .ronde-daniel { animation: none; }
  /* La route entière disparaît : ce n'est pas une animation qu'on peut
     ralentir, c'est un objet qui n'existe QUE parce qu'il bouge. */
  .daniel-route { display: none; }
}
@keyframes battement { 0%, 100% { opacity: .3; } 50% { opacity: .8; } }

/* ── Le passage d'un écran à l'autre ───────────────────────────────────────
   `startViewTransition` (app.js) photographie l'ancien écran et le fond vers
   le nouveau. Sans les `view-transition-name` ci-dessous, TOUTE la page est
   photographiée d'un bloc : le dock se fondrait avec le contenu, alors qu'il
   ne bouge pas. En les nommant, on les sort de
   l'animation — ils restent plantés pendant que le contenu, lui, glisse.

   C'est la règle du mouvement iOS : ce qui reste ne bouge pas. */
.appbar { view-transition-name: dock; }

::view-transition-old(root),
::view-transition-new(root) {
  /* Le fondu par défaut fait se chevaucher les deux écrans en semi-opacité :
     sur du verre, ça donne deux listes qui se traversent. On les enchaîne. */
  animation: none;
  mix-blend-mode: normal;
}
::view-transition-old(root) { animation: ecranSort 180ms var(--ressort) both; }
::view-transition-new(root) { animation: ecranEntre 300ms var(--ressort) 60ms both; }

@keyframes ecranSort  { to   { opacity: 0; transform: translateY(-10px) scale(.985); } }
@keyframes ecranEntre { from { opacity: 0; transform: translateY(14px)  scale(.99);  } }

/* ── Mouvement réduit ──────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  /* La dérive du fond est branchée sur `--glisse`, pas sur une transition :
     la règle ci-dessus ne l'atteint pas. On la fige à la main. */
  html { background-position: 0 0, 0 0, 0 0, 0 0, 0 0; }

}

/* ══════════════════════════════════════════════ À DEUX SUR UN TABLEAU ═════
   Tout ce qui suit n'existe que parce que Daniel est passé de « moi » à
   « nous » : dire à qui appartient une ligne, qui s'en occupe, et pourquoi
   elle est remontée toute seule. */

/* Une puce devant un nom : épingle ou cadenas. Discrète — c'est une précision,
   pas une décoration. */
.puce { display: inline-grid; place-items: center; flex: none; }
.puce svg { width: 12px; height: 12px; display: block; }
.puce.epingle { color: var(--tiede); }
.puce.prive   { color: var(--encre-fant); }

/* L'intitulé d'une section épinglée porte la même épingle que les lignes. */
.pastille-epingle { display: inline-grid; place-items: center; vertical-align: -2px; margin-right: 5px; color: var(--tiede); }
.pastille-epingle svg { width: 11px; height: 11px; display: block; }

/* La raison de l'épinglage, en clair. C'est ce qui empêche l'épingle
   automatique de passer pour de la magie — et donc d'être défaite à l'aveugle. */
.tache .meta .raison {
  color: var(--tiede); font-weight: 500;
  background: color-mix(in srgb, var(--tiede) 12%, transparent);
  padding: 1px 7px; border-radius: var(--rd-pill);
}
.tache .meta .assigne {
  color: var(--encre-dim);
  background: var(--trait); padding: 1px 7px; border-radius: var(--rd-pill);
}
/* Ce qui m'est assigné se voit d'un coup d'œil : c'est la question qu'on se
   pose en ouvrant la liste. */
.tache .meta .assigne.moi { background: var(--accent-voile); color: var(--accent); font-weight: 600; }
.tache .meta .famille { color: var(--encre-fant); }
.tache .titre { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tache .ic-envoi { width: 21px; display: grid; place-items: center; color: var(--encre-fant); flex: none; margin-top: 1px; }
.tache .ic-envoi svg { width: 15px; height: 15px; }

/* Le filtre de portée : plus discret que le contrôle segmenté principal, parce
   qu'on le règle une fois et qu'on l'oublie. */
/* ⚠️ Remettre le fond à `transparent` NE SUFFIT PAS : le `backdrop-filter`
   hérité de `.segment` dessine une dalle de verre pleine largeur derrière les
   puces, même sans aucun fond. Un filtre de fond est visible par lui-même —
   c'est ce qui le distingue d'une couleur. Il faut donc l'éteindre, lui ET les
   ombres du rail. */
.segment.discret {
  background: transparent; padding: 0 0 var(--s-3); gap: var(--s-1);
  backdrop-filter: none; -webkit-backdrop-filter: none;
  box-shadow: none;
}
.segment.discret button {
  flex: 0 0 auto; padding: 5px 12px; border-radius: var(--rd-pill);
  font: 500 13px/17px var(--sans); color: var(--encre-mute);
  border: 0;
  background-color: var(--verre);
  backdrop-filter: var(--flou-fin);
  -webkit-backdrop-filter: var(--flou-fin);
  box-shadow: var(--reflet);
  transition: background var(--rapide) linear, color var(--rapide) linear;
}
/* Celle qui est choisie reste PLEINE, en encre. C'est le seul endroit où on
   sort du verre, et volontairement : trois puces de verre côte à côte, dont
   une « un peu plus claire », ne se distinguent pas au premier coup d'œil —
   or c'est un filtre, il doit se lire sans hésitation. */
.segment.discret button[aria-selected="true"] {
  background: var(--prim-fond); color: var(--prim-encre);
  backdrop-filter: none; -webkit-backdrop-filter: none;
  box-shadow: var(--ombre-posee);
}

/* Le jeton d'initiales — l'équipe, les contacts. */
.jeton {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  font: 600 11px/1 var(--sans);
  background: var(--trait); color: var(--encre-dim);
}

.rond-plus {
  width: 34px; height: 34px; flex: none; border-radius: var(--rd-pill);
  background: var(--prim-fond); color: var(--prim-encre);
  display: grid; place-items: center;
  transition: transform var(--rapide) var(--ressort);
}
.rond-plus:active { transform: scale(.92); }
.rond-plus svg { width: 17px; height: 17px; }

.bascule {
  width: 48px; height: 29px; border-radius: var(--rd-pill); position: relative; flex: none;
  background: var(--trait-fort); transition: background var(--rapide) linear;
}
.bascule.on { background: var(--ok); }
.bascule span {
  position: absolute; top: 2px; left: 2px; width: 25px; height: 25px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.25);
  transition: left var(--rapide) var(--ressort);
}
.bascule.on span { left: 21px; }

.retour { color: var(--accent); font: 400 16px/21px var(--sans); margin: 2px 0 10px; }
.lien-discret { margin-top: var(--s-3); color: var(--encre-mute); font: 400 13px/18px var(--sans); }

/* ── Le mode micro ─────────────────────────────────────────────────────────
   Un bouton, un halo qui respire pendant l'écoute, et le texte qui se pose au
   fur et à mesure. Rien d'autre : on dicte les mains prises, on ne vient pas
   regarder une animation. */
.micro { display: flex; flex-direction: column; align-items: center; gap: var(--s-4); padding: var(--s-5) 0 var(--s-3); }

.micro-bulle {
  width: 88px; height: 88px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--trait); color: var(--encre-dim);
  transition: background var(--rapide) linear, color var(--rapide) linear, transform var(--rapide) var(--ressort);
  cursor: pointer;
}
.micro-bulle svg { width: 34px; height: 34px; }
.micro-bulle:active { transform: scale(.95); }
.micro-bulle.ecoute {
  background: var(--accent); color: var(--accent-encre);
  animation: respire 1.9s ease-in-out infinite;
}
/* Le halo est une ombre, pas un élément : rien à positionner, rien qui
   déborde, et ça n'entre jamais en conflit avec le défilement de la feuille. */
@keyframes respire {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 40%, transparent); }
  50%      { box-shadow: 0 0 0 18px color-mix(in srgb, var(--accent) 0%, transparent); }
}

.micro-texte {
  margin: 0; text-align: center; min-height: 46px;
  font: 400 17px/23px var(--sans); color: var(--encre);
  max-width: 30ch;
}

/* ── Le titre de section avec pastille ─────────────────────────────────── */
.section > h2 { display: flex; align-items: center; }

/* ══════════════════════════════════════════════════════════════ JURIDIQUE ══
   Aucune nouvelle matière, aucune nouvelle couleur : les listes restent
   groupées, les surfaces restent opaques, et les seuls tons employés sont les
   trois couleurs fonctionnelles déjà mesurées (--chaud, --tiede, --ok).
   L'accent n'apparaît nulle part ici — il est réservé au signal (onglet actif,
   lien), et une catégorie qui le prendrait le viderait de son sens. */

/* Un textarea se règle comme un input : sans ça, il tombe sur la police du
   navigateur et jure au milieu d'une feuille. */
.champ textarea {
  border: 1px solid var(--trait-fort); outline: none;
  background: var(--surface);
  border-radius: var(--rd-2); padding: 12px var(--s-4);
  color: var(--encre); font: 400 16px/22px var(--sans);
  width: 100%; resize: vertical; -webkit-appearance: none; appearance: none;
}
.champ textarea:focus { border-color: var(--encre-dim); }

/* ── Ce qui attend, en trois chiffres ──────────────────────────────────── */
.k-compteurs { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-bottom: var(--s-4); }
.k-compteurs button {
  padding: 7px var(--s-3);
  border: 0; border-radius: var(--rd-pill);
  background-color: var(--verre);
  backdrop-filter: var(--flou-fin);
  -webkit-backdrop-filter: var(--flou-fin);
  box-shadow: var(--reflet);
  font: 400 13px/17px var(--sans); color: var(--encre-dim);
  transition: background var(--rapide) linear;
}
.k-compteurs button:hover { background: var(--verre-actif); }
.k-compteurs button b { font: 600 13px/17px var(--mono); color: var(--encre); }
.k-compteurs button.tiede b { color: var(--tiede); }

/* ── Une ligne de contrat ──────────────────────────────────────────────── */
/* Même densité qu'une tâche : un bloc, des filets, pas de carte flottante. */
.k-ligne {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  cursor: pointer; text-align: left; width: 100%;
}
.k-ligne + .k-ligne { border-top: 1px solid var(--trait); }
.k-ligne .corps { flex: 1; min-width: 0; }
.k-ligne .titre {
  font: 500 16px/21px var(--sans); color: var(--encre);
  display: flex; align-items: center; gap: 6px;
}
.k-ligne .meta {
  display: flex; flex-wrap: wrap; gap: var(--s-2);
  margin-top: 3px;
  font: 400 13px/17px var(--sans); color: var(--encre-mute);
}
.k-ligne .meta .tiede { color: var(--tiede); }
.k-ligne .meta .chaud { color: var(--chaud); }
.k-ligne .chev { width: 16px; height: 16px; flex: none; color: var(--encre-fant); }

/* ── Le feu de l'état ──────────────────────────────────────────────────── */
/* Trois valeurs seulement, comme la pastille de disponibilité du catalogue :
   rouge ça attend, ambre ça avance, vert c'est fait. Sept nuances d'ambre ne
   se distinguent pas d'un coup d'œil, donc elles ne servent à rien. */
.k-etat {
  width: 9px; height: 9px; flex: none;
  border-radius: var(--rd-pill);
  background: var(--encre-fant);
}
.k-etat[data-etat="recu"] { background: var(--chaud); }
.k-etat[data-etat="lu"],
.k-etat[data-etat="negociation"],
.k-etat[data-etat="signature"] { background: var(--tiede); }
.k-etat[data-etat="signe"] { background: var(--ok); }
.k-etat-ligne { display: flex; align-items: center; gap: var(--s-2); margin-top: var(--s-2); }

/* ── Ce qu'il faut faire ensuite ───────────────────────────────────────── */
/* Un filet vertical et du texte en retrait, comme le bandeau : ça informe,
   ça ne pèse pas autant qu'une ligne de contenu. */
.k-note {
  margin: var(--s-4) 0;
  padding: var(--s-2) 0 var(--s-2) var(--s-4);
  border-left: 2px solid var(--tiede);
  font: 400 14px/20px var(--sans); color: var(--encre-dim);
}

.k-resume { font: 400 16px/24px var(--sans); color: var(--encre-dim); padding: 0 var(--s-2); }

/* ── Les sept valeurs qui décident de tout ─────────────────────────────── */
.k-chiffres {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px; background: var(--trait);
  border-radius: var(--rd-3); overflow: hidden;
  backdrop-filter: blur(var(--verre-flou)) saturate(var(--verre-sat));
  -webkit-backdrop-filter: blur(var(--verre-flou)) saturate(var(--verre-sat));
  border: 1px solid var(--verre-bord);
  box-shadow: var(--reflet), var(--ombre-verre);
}
.k-chiffres > div {
  background: var(--verre);
  padding: var(--s-3) var(--s-4);
  /* Sans min-width, un élément de grille vaut minmax(auto, 1fr) : sa largeur
     minimale est celle de son contenu le moins compressible, et une valeur
     longue fait déborder toute la grille. Piège déjà rencontré sur les cartes
     de folders du catalogue. */
  min-width: 0;
}
.k-cle {
  display: block;
  font: 600 11px/14px var(--sans); letter-spacing: .09em; text-transform: uppercase;
  color: var(--encre-mute);
}
.k-val { display: block; margin-top: 3px; font: 400 15px/20px var(--sans); color: var(--encre); }

/* ── Un point relevé ───────────────────────────────────────────────────── */
.k-point { padding: var(--s-3) var(--s-4); border-left: 3px solid var(--encre-fant); }
.k-point + .k-point { border-top: 1px solid var(--trait); }
.k-point[data-grav="bloquant"] { border-left-color: var(--chaud); }
.k-point[data-grav="a_discuter"] { border-left-color: var(--tiede); }
.k-point .titre {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-2);
  font: 500 15px/20px var(--sans); color: var(--encre);
}
.k-grav {
  flex: none;
  font: 600 11px/14px var(--sans); letter-spacing: .06em; text-transform: uppercase;
  color: var(--encre-mute);
}
.k-point[data-grav="bloquant"] .k-grav { color: var(--chaud); }
.k-point[data-grav="a_discuter"] .k-grav { color: var(--tiede); }
.k-point .dit { margin-top: var(--s-2); font: 400 14px/20px var(--sans); color: var(--encre-dim); }
.k-point .pourquoi { margin-top: 4px; font: 400 14px/20px var(--sans); color: var(--encre); }
.k-point .fond { margin-top: 4px; font: 400 12px/16px var(--mono); color: var(--encre-mute); }

/* ── Le brouillon, et la réponse à une question ────────────────────────── */
.k-brouillon {
  width: 100%; margin-bottom: var(--s-3);
  border: 1px solid var(--trait-fort); border-radius: var(--rd-2);
  background: var(--surface); color: var(--encre);
  padding: var(--s-3) var(--s-4);
  font: 400 15px/22px var(--sans); resize: vertical; outline: none;
}
.k-reponse:not(:empty) {
  margin-top: var(--s-3);
  padding: var(--s-3) 0 0;
  border-top: 1px solid var(--trait);
}

/* ═════════════════════════════════════════ BROUILLONS & SUGGESTIONS ══════
   Deux ajouts de la phase 2 du brief. Règle tenue : le brouillon et la
   suggestion sont des PROPOSITIONS, pas des alertes — ils ne prennent ni
   l'accent, ni la couleur d'urgence. Seul le brouillon périmé passe à l'ambre,
   parce que l'ouvrir sans le savoir ferait envoyer une réponse à côté. */

.brouillon {
  display: flex; align-items: stretch; gap: 1px;
  border-top: 1px solid var(--trait);
  background: var(--surface-2);
}
.brouillon .ouvrir {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: var(--s-2);
  padding: 9px var(--s-4);
  font: 500 14px/18px var(--sans); color: var(--encre-dim);
  text-align: left;
}
.brouillon .ouvrir svg { width: 16px; height: 16px; flex: none; }
.brouillon .ouvrir small {
  margin-left: auto; flex: none;
  font: 400 12px/16px var(--sans); color: var(--encre-mute);
}
.brouillon .refaire {
  flex: none; width: 40px;
  display: grid; place-items: center;
  color: var(--encre-mute); background: var(--surface-2);
}
.brouillon .refaire svg { width: 15px; height: 15px; }
.brouillon.perime .ouvrir { color: var(--tiede); }
.brouillon.perime .ouvrir small { color: var(--tiede); }

/* ── Une suggestion ──────────────────────────────────────────────────────── */
.suggestion { display: flex; align-items: flex-start; gap: var(--s-3); padding: var(--s-3) var(--s-4); }
.suggestion + .suggestion { border-top: 1px solid var(--trait); }
.suggestion .corps { flex: 1; min-width: 0; }
.suggestion .titre { font: 500 16px/21px var(--sans); color: var(--encre); }
.suggestion .meta {
  display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: 3px;
  font: 400 13px/17px var(--sans); color: var(--encre-mute);
}
.suggestion .meta .source { font-style: italic; }
/* La raison, en retrait derrière un filet : c'est une citation du mail, pas
   une phrase de Daniel. La distinction compte quand on décide. */
.suggestion .raison {
  margin-top: 5px; padding-left: var(--s-3);
  border-left: 2px solid var(--trait-fort);
  font: 400 13px/18px var(--sans); color: var(--encre-mute);
}
.suggestion .gestes { display: flex; gap: var(--s-2); flex: none; padding-top: 2px; }
.suggestion .gestes button {
  width: 34px; height: 34px; border-radius: var(--rd-pill);
  display: grid; place-items: center;
  border: 1px solid var(--trait-fort);
  transition: border-color var(--rapide) linear, background var(--rapide) linear;
}
.suggestion .gestes .non { color: var(--encre-mute); font: 400 16px/1 var(--sans); }
.suggestion .gestes .oui { color: var(--ok); }
.suggestion .gestes .oui svg { width: 17px; height: 17px; }
.suggestion .gestes button:hover { border-color: var(--encre-dim); }

/* Une tâche commencée le dit, sinon « en cours » ne vit que dans l'éditeur. */
.tache .meta .encours {
  font: 600 11px/14px var(--sans); letter-spacing: .06em; text-transform: uppercase;
  color: var(--tiede);
}

/* Le montant d'une pièce : en chiffres tabulaires, pour que la colonne
   s'aligne d'une ligne à l'autre. Sans ça, une liste de montants danse. */
.k-ligne .k-somme {
  flex: none; font: 500 15px/20px var(--mono); font-variant-numeric: tabular-nums;
  color: var(--encre);
}

/* Le chevron d'une ligne cliquable, quand elle n'est pas dans une liste de
   contrats. Même dimension que partout ailleurs : un SVG sans taille explicite
   dans un conteneur flex prend toute la place qu'il peut. */
.ligne .chev { width: 16px; height: 16px; flex: none; color: var(--encre-fant); }

/* ══════════════════════════════════════════ LE BUREAU : CE QUI DOIT SORTIR ══
   La compta n'est pas un tableau de bord : c'est une liste de choses à régler.
   Un seul élément a le droit d'être gros — la somme en retard, parce que c'est
   la seule qui change ce qu'on fait de sa matinée. */

/* Les trois sommes de tête. Pas des cartes qui lévitent : une bande de verre
   divisée par des filets, comme une frise de chiffres. */
/* Une GRILLE et non un flex : à 375 px, trois colonnes forcées coupaient le
   troisième montant en deux. `auto-fit` + `minmax` fait passer le bloc de trop
   à la ligne suivante tout seul — 2 + 1 sur téléphone, 3 de front dès qu'il y
   a la place. Vu en vrai le 2026-08-17, « 3 000,00 € » tronqué au bord. */
.sous-total {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1px;
  margin-bottom: var(--s-5);
  border-radius: var(--rd-4); overflow: hidden;
  background: var(--trait);
  border: 1px solid var(--verre-bord);
  backdrop-filter: blur(var(--verre-flou)) saturate(var(--verre-sat));
  -webkit-backdrop-filter: blur(var(--verre-flou)) saturate(var(--verre-sat));
  box-shadow: var(--reflet), var(--ombre-verre);
}
.sous-total .bloc {
  min-width: 0;
  background: var(--verre);
  padding: var(--s-4) var(--s-3);
}
/* Sur téléphone : deux colonnes, et le troisième bloc prend toute la ligne.
   Sans ça, `auto-fit` laisse une case vide grise à côté de lui — un trou dans
   une bande de chiffres se lit comme une donnée manquante, pas comme un vide
   de mise en page. */
@media (max-width: 520px) {
  .sous-total { grid-template-columns: 1fr 1fr; }
  .sous-total .bloc:last-child:nth-child(3) { grid-column: 1 / -1; }
}
.sous-total b {
  display: block;
  font: 700 20px/24px var(--sans); letter-spacing: -.4px;
  font-variant-numeric: tabular-nums;
  color: var(--encre);
  /* Le montant ne se coupe pas ; s'il ne tient vraiment pas, il rétrécit
     plutôt que de déborder de sa case. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sous-total span {
  display: block; margin-top: 2px;
  color: var(--encre-mute); font: 400 12px/16px var(--sans);
}
/* Le retard est la seule chose colorée de l'écran, et seulement quand il y en
   a. À zéro, le bloc redevient de l'encre — un « 0,00 € » en rouge dit le
   contraire de ce qu'il devrait. */
.sous-total .bloc.chaud b { color: var(--chaud); }
.sous-total .bloc.ok b { color: var(--ok); }

/* Le compte ou la somme au bout d'un intitulé de section. */
.k-compte {
  margin-left: auto;
  font: 500 12px/16px var(--mono); font-variant-numeric: tabular-nums;
  color: var(--encre-mute); letter-spacing: 0; text-transform: none;
}
.t-oeilleton.chaud { color: var(--chaud); }
.t-oeilleton.chaud .k-compte { color: var(--chaud); }
.section > h2 { display: flex; align-items: baseline; }

/* Une ligne d'échéance réutilise `.tache` (même densité, même case à cocher).
   Ce qui s'ajoute : le montant à droite, et les deux mots qui disent si le
   chiffre est sûr. */
.tache .k-somme {
  flex: none; align-self: center;
  font: 600 16px/21px var(--mono); font-variant-numeric: tabular-nums;
  color: var(--encre); padding-left: var(--s-2);
}
.tache .k-somme.ok { color: var(--ok); }
.tache.faite .k-somme { color: var(--encre-fant); font-weight: 400; }

/* « facture jointe » vs « estimation » : la distinction la plus coûteuse de
   l'écran si on la rate. Discrètes toutes les deux — c'est une précision, pas
   une alerte — mais typées différemment pour se lire sans être relues. */
.tache .meta .appui {
  color: var(--encre-dim);
  background: var(--trait); padding: 1px 7px; border-radius: var(--rd-pill);
}
.tache .meta .estime {
  color: var(--encre-mute); font-style: italic;
}
.puce-entrant {
  font: 600 10px/14px var(--sans); letter-spacing: .06em; text-transform: uppercase;
  color: var(--ok);
  background: color-mix(in srgb, var(--ok) 12%, transparent);
  padding: 1px 7px; border-radius: var(--rd-pill);
}
.tache .titre .puce { color: var(--encre-fant); }

/* Le corps d'une échéance est un bouton (il ouvre l'éditeur) : sans ça, la
   ligne n'a pas de zone de clic et il faut viser le texte. */
.tache > button.corps {
  background: none; text-align: left;
  font: inherit; color: inherit;
}


/* ── Le fil de discussion d'un dossier ───────────────────────────────────── */
/* Pas de bulles arrondies façon messagerie : on lit ici des paragraphes de
   droit, pas des « ok ». Un filet à gauche suffit à distinguer qui parle, et
   le texte garde toute la largeur. */
.fil-ia {
  max-height: 46vh; overflow-y: auto;
  margin-bottom: var(--s-3);
  display: flex; flex-direction: column; gap: var(--s-3);
}
.fil-ia .bulle { padding-left: var(--s-3); border-left: 2px solid var(--trait-fort); }
.fil-ia .bulle.daniel { border-left-color: var(--encre-dim); }
.fil-ia .qui {
  font: 600 11px/14px var(--sans); letter-spacing: .09em; text-transform: uppercase;
  color: var(--encre-mute); margin-bottom: 3px;
}
.fil-ia .dit { font: 400 15px/22px var(--sans); color: var(--encre); white-space: pre-wrap; }
.fil-ia .bulle.moi .dit { color: var(--encre-dim); }
.fil-ia .attente { margin: 0; }
