/* systeme.css — le système de design de dashlife : verre dépoli, vert émeraude, fond d'ambiance calme.
   Le texte qui l'explique est docs/design/guide.md (et docs/design-system.md pour la règle des données).
   Règles dures (vérifiées par tests/unit/design-system.test.js) :
   - les couleurs de base sont des jetons déclarés dans :root (OKLCH) ; les variantes translucides (verre, hachures, lueurs) sont écrites en oklch() à l'endroit où elles servent ; les feuilles d'écran (ecran-*.css) n'ont, elles, AUCUNE couleur littérale ;
   - tout verre a un repli opaque (@supports, prefers-reduced-transparency) ;
   - tout mouvement vit dans prefers-reduced-motion: no-preference ;
   - un chiffre ou une forme estimé(e) porte TOUJOURS la hachure (.est / .hachure) ; un inconnu a son style (.inconnu), jamais un zéro. */

@font-face { font-family: "Figtree"; font-weight: 300 900; font-style: normal; font-display: swap;
  src: url("/polices/figtree-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Figtree"; font-weight: 300 900; font-style: normal; font-display: swap;
  src: url("/polices/figtree-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }

/* ============ 1. JETONS ============ */
@property --rayon { syntax: "<percentage>"; inherits: false; initial-value: 0%; }
@property --derive-x { syntax: "<percentage>"; inherits: true; initial-value: 0%; }

:root {
  color-scheme: light dark;
  /* Texte : cinq tailles, deux graisses (400 et 600). */
  --t-1: 13px;   /* étiquette, légende, note */
  --t-2: 16px;   /* texte courant, cellule de tableau, bouton */
  --t-3: 20px;   /* valeur d'une tuile, titre de section */
  --t-4: clamp(26px, 4.2vw, 34px);   /* titre d'écran */
  --t-5: clamp(44px, 12vw, 64px);    /* LE chiffre qui domine l'écran (un seul par écran) */
  --police: "Figtree", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px; --s-7: 48px;

  /* Rayons */
  --r-1: 8px;        /* barres, pastilles, hachure */
  --r-2: 14px;       /* champs, boutons carrés, alertes */
  --r-carte: 24px;   /* cartes */
  --r-panneau: 30px;
  --r-pleine: 999px; /* pilules, jauges */
  --trait: 1px;

  /* Encres (texte). Contrastes mesurés sur le pire fond sous le verre : voir docs/design/contraste.md */
  --encre: oklch(.22 .02 165);
  --encre-2: oklch(.40 .025 165);
  --encre-3: oklch(.47 .025 165);
  --sur-vert: oklch(1 0 0);            /* texte sur la carte héros */

  /* Fond et surfaces */
  --fond: oklch(.965 .018 150);        /* page, champs, texte des boutons noirs */
  --fond-haut: oklch(.93 .035 160);    /* le plus sombre que l'ambiance puisse laisser sous le verre */
  --panneau: oklch(1 0 0 / .46);       /* une marche au-dessus d'une carte : survol, explication */
  --filet: oklch(.30 .03 165 / .14);   /* traits fins, séparateurs, pistes */
  --blanc-plein: oklch(1 0 0);
  --marque: var(--encre-2);            /* couleur de la hachure quand l'objet n'a pas de famille */

  /* Les trois familles de couleur. Le violet n'existe plus. */
  --vert: oklch(.45 .10 165);          /* texte et traits verts */
  --vert-vif: oklch(.62 .12 165);      /* remplissages, jamais du texte */
  --vert-clair: oklch(.80 .08 165);
  --vert-nuit: oklch(.17 .035 165);    /* fond de l'ouverture */
  --entree: var(--vert);               /* L'ARGENT QUI ENTRE ou que l'on garde */
  --sortie: oklch(.42 .05 250);        /* L'ARGENT QUI SORT : marchandise, douane, publicité, frais. Ardoise, calme */
  --action: oklch(.48 .14 45);         /* CE QUI DEMANDE UNE ACTION : alerte, décision, jour à perte */
  --action-fond: oklch(.96 .035 60 / .72);

  /* Verre */
  --verre: oklch(1 0 0 / .50);
  --verre-fort: oklch(1 0 0 / .70);
  --verre-bord: oklch(1 0 0 / .66);
  --flou: blur(22px) saturate(150%);
  /* Ombre en deux couches : un contact serré, puis une lueur large et douce. */
  --ombre: 0 1px 0 oklch(1 0 0 / .65) inset, 0 2px 4px -1px oklch(.30 .04 165 / .10), 0 16px 34px -16px oklch(.30 .04 165 / .30);
  --ombre-haute: 0 1px 0 oklch(1 0 0 / .8) inset, 0 4px 8px -2px oklch(.30 .04 165 / .12), 0 28px 48px -18px oklch(.30 .04 165 / .38);
  --lisere: linear-gradient(90deg, transparent, oklch(1 0 0 / .95) 30%, oklch(1 0 0 / .95) 70%, transparent);   /* le trait de lumière en haut d'une carte */

  /* Voiles, champs, ambiance (ils changent en mode sombre) */
  --hachure-inconnu: oklch(.30 .03 165 / .09);
  --voile: oklch(1 0 0 / .55);         /* survol sur verre */
  --voile-leger: oklch(1 0 0 / .28);
  --champ: oklch(1 0 0 / .8);          /* fond d'un champ de saisie */
  --vert-fort: var(--vert);            /* fond d'un bouton au survol (texte blanc dessus) */
  --amb-1: oklch(.92 .07 80); --amb-2: oklch(.87 .09 165); --amb-3: oklch(.90 .08 55); --amb-4: oklch(.89 .07 165);
  --amb-a: oklch(.955 .02 90); --amb-b: oklch(.94 .03 165);

  /* Mouvement */
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  --ease-vague: cubic-bezier(.7, 0, .15, 1);
}
/* MODE SOMBRE automatique (prefers-color-scheme). Contrastes mesurés : encres ≥ 6,2 sur le verre sombre ; blanc sur la carte héros inchangé (5,7). */
@media screen and (prefers-color-scheme: dark) {
  :root {
    --encre: oklch(.95 .01 150); --encre-2: oklch(.80 .015 150); --encre-3: oklch(.72 .02 150);
    --fond: oklch(.18 .015 165); --panneau: oklch(1 0 0 / .06); --filet: oklch(1 0 0 / .13); --blanc-plein: oklch(.36 .03 165);
    --vert: oklch(.78 .12 165); --vert-fort: oklch(.50 .10 165); --vert-clair: oklch(.45 .08 165); --sortie: oklch(.78 .06 250); --action: oklch(.76 .13 55);
    --action-fond: oklch(.30 .05 50 / .6);
    --verre: oklch(1 0 0 / .07); --verre-fort: oklch(.26 .02 165 / .86); --verre-bord: oklch(1 0 0 / .14);
    --ombre: 0 1px 0 oklch(1 0 0 / .16) inset, 0 28px 36px -28px oklch(1 0 0 / .07) inset, 0 2px 4px -1px oklch(0 0 0 / .4), 0 18px 36px -16px oklch(0 0 0 / .65);
    --ombre-haute: 0 1px 0 oklch(1 0 0 / .14) inset, 0 4px 8px -2px oklch(0 0 0 / .45), 0 30px 50px -18px oklch(0 0 0 / .75), 0 0 0 1px oklch(.62 .12 165 / .10);
    --lisere: linear-gradient(90deg, transparent, oklch(1 0 0 / .7) 30%, oklch(1 0 0 / .7) 70%, transparent);
    --hachure-inconnu: oklch(1 0 0 / .14);
    --voile: oklch(1 0 0 / .12); --voile-leger: oklch(1 0 0 / .06); --champ: oklch(1 0 0 / .08);
    --amb-1: oklch(.31 .08 185); --amb-2: oklch(.34 .10 165); --amb-3: oklch(.30 .08 150); --amb-4: oklch(.33 .09 175);
    --amb-a: oklch(.17 .02 165); --amb-b: oklch(.19 .03 165);
  }
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root { --verre: oklch(.985 .008 150 / .92); --verre-fort: oklch(.99 .005 150); --flou: none; }
}
@media (prefers-reduced-transparency: reduce) {
  :root { --verre: oklch(.985 .008 150); --verre-fort: oklch(.99 .005 150); --flou: none; }
}
@media screen and (prefers-color-scheme: dark) {
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { :root { --verre: oklch(.24 .02 165); --verre-fort: oklch(.26 .02 165); } }
  @media (prefers-reduced-transparency: reduce) { :root { --verre: oklch(.24 .02 165); --verre-fort: oklch(.26 .02 165); --flou: none; } }
}

/* ============ 2. BASE ET FOND D'AMBIANCE ============ */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html { background: var(--fond); }
body { margin: 0; min-height: 100vh; color: var(--encre);
  font: 400 var(--t-2)/1.45 var(--police);
  padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
  -webkit-font-smoothing: antialiased; position: relative; }
/* Le fond : trois lueurs douces (sable, menthe, pêche) sur un papier clair. Il ne bouge pas pour qui demande moins de mouvement. */
body::before { content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(56% 50% at calc(10% + var(--derive-x)) 8%, var(--amb-1), transparent 72%),
    radial-gradient(52% 58% at calc(94% - var(--derive-x)) 16%, var(--amb-2), transparent 72%),
    radial-gradient(60% 56% at 64% 100%, var(--amb-3), transparent 72%),
    radial-gradient(46% 46% at 4% 82%, var(--amb-4), transparent 72%),
    linear-gradient(160deg, var(--amb-a), var(--amb-b)); }
[hidden] { display: none !important; }
h1, h2, h3, p { margin: 0; }
b, strong, th { font-weight: 600; }

.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; white-space: nowrap; }
.t-1 { font-size: var(--t-1); line-height: 1.35; }
.t-3 { font-size: var(--t-3); line-height: 1.3; }
.t-4 { font-size: var(--t-4); line-height: 1.15; font-weight: 600; letter-spacing: -.02em; }
.discret { color: var(--encre-2); }
.faible { color: var(--encre-3); }
.etiquette { font-size: var(--t-1); line-height: 1.35; color: var(--encre-3); }

/* INCONNU : son propre style, jamais un zéro. Italique + hachure discrète + le mot écrit. */
.inconnu { display: inline-block; color: var(--encre-3); font-style: italic; font-weight: 400; padding: 0 var(--s-2); border-radius: var(--r-1);
  background: repeating-linear-gradient(135deg, var(--hachure-inconnu) 0 4px, transparent 4px 8px); }

/* Focus : un seul anneau vert foncé, partout, jamais supprimé. */
:focus-visible { outline: 2px solid var(--vert); outline-offset: 3px; border-radius: var(--r-1); }
button { font: inherit; color: inherit; }
button:disabled, [aria-disabled="true"] { opacity: .6; cursor: default; }
.bouton:disabled { background: var(--encre-2); border-color: var(--encre-2); color: var(--fond); opacity: 1; }
::selection { background: oklch(.80 .08 165 / .6); }

/* ============ 3. L'INCERTITUDE : LA HACHURE ============
   Estimé = « ≈ » devant + bande hachurée dessous ; forme estimée = remplie de hachure à 45°. */
.hachure, .est::after {
  -webkit-mask: url("/hachure.svg") repeat 0 0 / 6px 6px; mask: url("/hachure.svg") repeat 0 0 / 6px 6px;
}
.hachure { background: var(--marque); }
.est { position: relative; display: inline-block; padding-bottom: .2em; }
.est::before { content: "≈\00a0"; }
.est::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: max(.12em, 3px); background: currentColor; }

.cle { display: inline-flex; flex-wrap: wrap; gap: var(--s-4); align-items: center; font-size: var(--t-1); color: var(--encre-3); }
.cle > span { display: inline-flex; gap: var(--s-2); align-items: center; }
.cle i { width: 16px; height: 10px; border-radius: var(--r-1); display: inline-block; }
.cle i.plein { background: var(--vert); }
.cle i.hachure { background: var(--marque); }
.cle i.inconnu-cle { background: repeating-linear-gradient(135deg, var(--hachure-inconnu) 0 4px, transparent 4px 8px); border: 1px solid var(--hachure-inconnu); }
.cle i.creux { width: 10px; height: 10px; border-radius: 50%; background: none; border: 1.5px solid var(--encre-3); }

/* Un jour sans vente : un point creux, jamais une barre à zéro. */
.vide-jour { display: inline-block; width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid var(--encre-3); background: none; }

/* ============ 4. VERRE ============ */
.vitre, .case, .carte, .alerte, .explication, .vide, .entete, .dock, nav.onglets, .palette-boite {
  -webkit-backdrop-filter: var(--flou); backdrop-filter: var(--flou); }
.vitre, .case, .carte { background: var(--verre); border: var(--trait) solid var(--verre-bord); box-shadow: var(--ombre); position: relative; }
/* Le liseré lumineux : un trait de lumière sur le bord haut, comme du verre qui capte le jour. */
.vitre::before, .case::before, .carte::before { content: ""; position: absolute; left: 14px; right: 14px; top: -1px; height: 1px; background: var(--lisere); pointer-events: none; border-radius: var(--r-pleine); }
.c-hero::before { opacity: .8; }
/* Reflet de verre sur la carte héros : une lumière en diagonale qui laisse deviner la transparence. */
.c-hero::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; background: linear-gradient(135deg, oklch(1 0 0 / .18), oklch(1 0 0 / 0) 42%); }

/* ============ 5. COMPOSANTS ============ */

/* ---- 5.1 Tuile de chiffre ---- */
.tuile { display: grid; gap: var(--s-1); }
.tuile .etiquette { display: flex; align-items: center; gap: var(--s-2); }
.tuile .marque { width: 8px; height: 8px; border-radius: 50%; background: var(--marque); flex: none; }
.tuile.entree { --marque: var(--entree); }
.tuile.sortie { --marque: var(--sortie); }
.tuile.action { --marque: var(--action); }
.tuile .valeur { font-size: var(--t-3); font-weight: 600; line-height: 1.2; letter-spacing: -.01em; }
.tuile .delta { font-size: var(--t-1); color: var(--encre-2); }
.tuile.dominante { gap: var(--s-2); }
.tuile.dominante .valeur { font-size: var(--t-5); font-weight: 600; line-height: 1; letter-spacing: -.035em; color: var(--marque); }
.tuile.dominante .etiquette { font-size: var(--t-2); color: var(--encre-2); }
.tuile.dominante .delta { font-size: var(--t-2); }
.tuile.dominante .valeur.est { padding-bottom: .12em; }
.tuile .valeur.est { justify-self: start; }

/* Pastilles d'état : réel / estimé / inconnu (le mot est écrit, la forme change aussi). */
.etat-pastille { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-1); font-weight: 600; padding: 2px 10px; border-radius: var(--r-pleine);
  background: oklch(.62 .12 165 / .16); color: var(--vert); }
.etat-pastille.estime { background: oklch(.62 .12 165 / .12); color: var(--vert);
  background-image: repeating-linear-gradient(135deg, oklch(.45 .10 165 / .22) 0 3px, transparent 3px 6px); }
.etat-pastille.incertain { background: oklch(.70 .14 55 / .22); color: var(--action); }
.etat-pastille.inconnu-p { color: var(--encre-3); font-style: italic; background: repeating-linear-gradient(135deg, var(--hachure-inconnu) 0 4px, transparent 4px 8px); }

.jauge { display: flex; gap: 2px; height: 10px; }
.jauge > i { display: block; height: 100%; min-width: 0; }
.jauge > .reel { background: var(--marque); border-radius: var(--r-pleine) 0 0 var(--r-pleine); }
.jauge > .estime { background: var(--marque); border-radius: 0 var(--r-pleine) var(--r-pleine) 0; }
.jauge > i:only-child { border-radius: var(--r-pleine); }
.piste { height: 10px; border-radius: var(--r-pleine); background: var(--filet); overflow: hidden; }
.piste > i { display: block; height: 100%; background: var(--marque); border-radius: var(--r-pleine); }

/* ---- 5.2 Graphique en barres (SVG fait main) ---- */
.graphique { display: grid; gap: var(--s-3); }
.graphique .lecture { min-height: 2.8em; }
.graphique .lecture .t-3 { display: block; }
.graphique svg { display: block; width: 100%; height: auto; overflow: visible; touch-action: pan-y; }
.graphique .barre { cursor: pointer; }
.graphique .barre rect.zone { fill: transparent; }
.graphique .barre:hover .plein, .graphique .barre:hover .hach, .graphique .barre:focus-visible .plein, .graphique .barre:focus-visible .hach { opacity: .8; }
.graphique .barre:focus-visible { outline: none; }
.graphique .barre:focus-visible .zone { stroke: var(--vert); stroke-width: 2; fill: var(--voile-leger); }
.graphique .barre[aria-pressed="true"] .zone { fill: var(--voile); }   /* la barre lue : une bande claire derrière, jamais un cadre qui cache la hachure */
.graphique .creux { fill: none; stroke: var(--encre-3); stroke-width: 1.5; }
.graphique .zero { stroke: var(--filet); stroke-width: 1; }
.graphique .axe { display: flex; justify-content: space-between; font-size: var(--t-1); color: var(--encre-3); margin-top: calc(var(--s-2) * -1); }
.graphique .entree { fill: var(--entree); } .graphique .action { fill: var(--action); }
.graphique .hach { stroke-width: 1.5; }
.graphique .hach.entree { stroke: var(--entree); } .graphique .hach.action { stroke: var(--action); }
.graphique .fond-e { fill: var(--entree); fill-opacity: .24; } .graphique .fond-a { fill: var(--action); fill-opacity: .24; }   /* la part estimée d'une barre : hachure ET teinte, pour qu'on la voie de loin */
.graphique .motif-e { stroke: var(--entree); } .graphique .motif-a { stroke: var(--action); }

/* ---- 5.3 Alerte honnête : la seule chose du produit qui a le droit d'être orange ---- */
.alerte { display: grid; gap: var(--s-3); padding: var(--s-4); border-radius: var(--r-2);
  background: var(--action-fond); border: var(--trait) solid oklch(.60 .13 50 / .35); border-left: 4px solid var(--action); }
.alerte.info { background: var(--panneau); border-color: var(--verre-bord); border-left-color: var(--encre-3); }
.alerte .quand { font-size: var(--t-1); color: var(--encre-2); }
.alerte .titre { font-size: var(--t-2); font-weight: 600; }
.alerte .corps { color: var(--encre-2); }
.alerte .gestes { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.alerte .niveau { font-size: var(--t-1); font-weight: 600; color: var(--encre); }
.alerte.info .niveau { color: var(--encre-2); }
.liste-alertes { display: grid; gap: var(--s-3); }

/* ---- 5.4 Boutons : le principal est noir et rond ---- */
.bouton { min-height: 44px; padding: 0 var(--s-5); border-radius: var(--r-pleine); border: var(--trait) solid var(--encre);
  background: var(--encre); color: var(--fond); font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2); text-decoration: none; }
.bouton.second { background: var(--verre-fort); color: var(--encre); border-color: var(--verre-bord); }
.bouton:hover:not(:disabled) { background: var(--vert-fort); border-color: var(--vert-fort); color: var(--sur-vert); }
.bouton.second:hover:not(:disabled) { background: var(--blanc-plein); border-color: var(--blanc-plein); color: var(--encre); }

/* ---- 5.5 Tableau : des lignes arrondies sur verre ---- */
.tableau { width: 100%; border-collapse: collapse; }
.tableau th { font-size: var(--t-1); font-weight: 400; color: var(--encre-3); text-align: right; padding: var(--s-2); }
.tableau td { padding: var(--s-3) var(--s-2); border-top: var(--trait) solid var(--filet); text-align: right; vertical-align: top; }
.tableau th:first-child, .tableau td:first-child { text-align: left; padding-left: var(--s-2); }
.tableau th:last-child, .tableau td:last-child { padding-right: var(--s-2); }
.tableau tbody tr:hover { background: var(--panneau); }
.tableau tbody tr:hover td:first-child { border-radius: var(--r-2) 0 0 var(--r-2); }
.tableau tbody tr:hover td:last-child { border-radius: 0 var(--r-2) var(--r-2) 0; }
.tableau td .sous { display: block; font-size: var(--t-1); color: var(--encre-3); }
.tableau td .signe { margin-right: .1em; }
.defile { overflow-x: auto; margin: 0 calc(var(--s-4) * -1); padding: 0 var(--s-4); }

/* ---- 5.6 Segments (filtres / période) : une pilule de verre, le choix actif est noir ---- */
.filtres { display: inline-flex; padding: 4px; gap: 2px; border-radius: var(--r-pleine); background: var(--verre-fort); border: var(--trait) solid var(--verre-bord); }
.filtres button { min-height: 44px; padding: 0 var(--s-4); border: 0; border-radius: var(--r-pleine);
  background: transparent; color: var(--encre-2); cursor: pointer; font-size: var(--t-1); font-weight: 600; }
.filtres button:hover { color: var(--encre); }
.filtres button[aria-checked="true"], .filtres button[aria-pressed="true"] { background: var(--encre); color: var(--fond); }

/* ---- 5.7 État vide ---- */
.vide { display: grid; gap: var(--s-2); padding: var(--s-5) var(--s-4); border-radius: var(--r-2);
  border: var(--trait) dashed oklch(.30 .03 165 / .28); background: var(--voile-leger); text-align: left; }
.vide .titre { font-size: var(--t-2); font-weight: 600; }
.vide .texte { color: var(--encre-2); }
.vide.bon { border-style: solid; border-color: oklch(.62 .12 165 / .6); }
.vide.bon .titre::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: var(--s-2);
  border-radius: 50%; background: var(--entree); vertical-align: .1em; }

/* ---- 5.8 Squelette : la forme de l'écran avant ses chiffres. Un reflet lent, sauf mouvement réduit. ---- */
.sq { display: block; height: 14px; border-radius: var(--r-1); background: var(--filet); }
.sq.grand { height: 56px; width: 70%; } .sq.moyen { width: 55%; } .sq.plein { width: 100%; height: 88px; }

/* ============ 6. MISE EN PAGE ============ */
.page { max-width: 1240px; margin: 0 auto; padding: var(--s-4) var(--s-4) var(--s-7); }
/* Barre du haut : une pilule de verre. */
.entete { display: flex; align-items: center; gap: var(--s-3); margin-bottom: var(--s-4); min-height: 56px; padding: var(--s-2) var(--s-4);
  border-radius: var(--r-pleine); background: var(--verre); border: var(--trait) solid var(--verre-bord); box-shadow: var(--ombre); }
.entete .logo-texte { font-size: var(--t-3); font-weight: 600; letter-spacing: -.03em; color: var(--encre); margin-right: var(--s-3); padding-right: var(--s-4); border-right: var(--trait) solid var(--filet); line-height: 1.2; }
.logo-dashlife { font-family: var(--police); font-weight: 600; letter-spacing: -.03em; color: var(--encre); }
.entete .identite { display: flex; align-items: baseline; gap: var(--s-3); min-width: 0; flex: 0 1 auto; }
.entete .boutique { font-size: var(--t-2); font-weight: 600; color: var(--encre); letter-spacing: -.01em; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Fraîcheur : un point vert et l'heure de la dernière lecture de Shopify. Sans date réelle : « pas encore lu », point creux. */
.fraicheur { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--t-1); color: var(--encre-2); white-space: nowrap; }
.fraicheur:empty { display: none; }
.fraicheur .point { width: 8px; height: 8px; border-radius: 50%; background: var(--vert-vif); box-shadow: 0 0 0 3px oklch(.62 .12 165 / .2); flex: none; }
.fraicheur.jamais .point { background: none; box-shadow: none; border: 1.5px dashed var(--encre-3); }
.entete .jour { font-size: var(--t-1); color: var(--encre-2); }
.entete #jour { margin-left: auto; }
.entete .logo-marque { margin-right: var(--s-1); }
.etiquette-demo { display: inline-block; margin: 0 0 var(--s-3); padding: 2px var(--s-3); border-radius: var(--r-pleine);
  border: var(--trait) dashed var(--encre-3); color: var(--encre-2); font-size: var(--t-1); background: var(--panneau); }
.panneau:not(.actif) { display: none; }

/* La grille bento : des cases de tailles inégales, quatre colonnes ; une seule sur téléphone. */
.bento { display: grid; gap: var(--s-4); grid-template-columns: minmax(0, 1fr); }
.case { display: grid; align-content: start; gap: var(--s-3); min-width: 0; padding: var(--s-5); border-radius: var(--r-carte); position: relative; }
.case > h2, .case-tete h2 { font-size: var(--t-2); font-weight: 600; line-height: 1.3; color: var(--encre-2); margin: 0; }
.case-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.case.c-faire.urgente { border-color: var(--action); }

/* LA CARTE HÉROS : verte, texte blanc, le bénéfice qui compte. Orange profond si le jour est à perte. */
.c-hero { gap: var(--s-3); align-content: start; color: var(--sur-vert); border-color: oklch(1 0 0 / .28);
  background: linear-gradient(150deg, oklch(.50 .10 165) 0%, oklch(.43 .09 165) 55%, oklch(.36 .07 165) 100%); }
.c-hero:has(.verdict.action) { background: linear-gradient(150deg, oklch(.50 .14 45) 0%, oklch(.42 .12 42) 100%); }
.c-hero > h2, .c-hero .etiquette, .c-hero .phrase, .c-hero .delta, .c-hero .tuile .etiquette, .c-hero .vide .texte { color: var(--sur-vert); }
.c-hero .tuile.dominante .valeur, .c-hero .tuile .valeur { color: var(--sur-vert); }
.c-hero .tuile .marque { background: var(--sur-vert); }
.c-hero .inconnu { color: var(--sur-vert); background: repeating-linear-gradient(135deg, oklch(1 0 0 / .22) 0 4px, transparent 4px 8px); }
.c-hero .vide { background: oklch(1 0 0 / .12); border-color: oklch(1 0 0 / .45); }
.c-hero .vide .titre { color: var(--sur-vert); }
.c-hero .verdict { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-2); font-weight: 600; color: var(--sur-vert); }
.c-hero .verdict .marque { width: 8px; height: 8px; border-radius: 50%; background: var(--sur-vert); flex: none; }
.c-hero .phrase { font-size: var(--t-2); line-height: 1.45; max-width: 44ch; }
.c-hero .confiance { display: grid; gap: var(--s-2); margin-top: auto; padding-top: var(--s-3); }
.c-hero .confiance .etiquette { --marque: var(--sur-vert); }
.c-hero .jauge { --marque: var(--sur-vert); }
.c-hero .jauge > .reel, .c-hero .jauge > .estime { background: var(--sur-vert); }
.c-hero .explication { background: oklch(1 0 0 / .14); border-color: oklch(1 0 0 / .3); color: var(--sur-vert); }
.c-hero .explication code { color: var(--sur-vert); }
.c-hero button.pourquoi { color: var(--sur-vert); }
.c-hero :focus-visible { outline-color: var(--sur-vert); }

.c-faire .alerte { border-radius: var(--r-2); }

/* NAVIGATION. Téléphone : une barre d'onglets flottante en bas. Grand écran : le rail flottant à gauche. */
nav.onglets { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; scroll-snap-type: x proximity;
  background: var(--verre); border: var(--trait) solid var(--verre-bord); box-shadow: var(--ombre); border-radius: var(--r-pleine); padding: 6px; }
nav.onglets::-webkit-scrollbar { display: none; }
nav.onglets button { position: relative; flex: none; background: none; border: 0; border-radius: var(--r-pleine); min-height: 52px; min-width: 64px; padding: 6px var(--s-3);
  color: var(--encre-2); cursor: pointer; font-weight: 600; font-size: var(--t-1); white-space: nowrap; scroll-snap-align: center;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; }
nav.onglets .pictogramme { display: grid; place-items: center; width: 22px; height: 22px; }
nav.onglets .pictogramme svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
nav.onglets button:hover { color: var(--encre); background: var(--voile); }
nav.onglets button[aria-current="page"] { background: var(--blanc-plein); color: var(--encre); box-shadow: 0 4px 14px -6px oklch(.30 .04 165 / .4); }
nav.onglets button[aria-current="page"] .pictogramme { color: var(--vert); }

.dock { display: none !important; }   /* doublon de la carte « À faire », dont les boutons sont maintenant dans la carte à toutes les largeurs */
.dock-ancien { position: fixed; left: var(--s-3); right: var(--s-3); bottom: calc(88px + env(safe-area-inset-bottom)); z-index: 2;
  display: flex; align-items: center; gap: var(--s-3); padding: var(--s-3) var(--s-4); border-radius: var(--r-carte);
  background: var(--verre-fort); border: var(--trait) solid oklch(.60 .13 50 / .5); box-shadow: var(--ombre-haute); }
.dock .texte { flex: 1; min-width: 0; display: grid; }
.dock .titre { font-size: var(--t-2); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dock .gestes { display: flex; gap: var(--s-2); }
.dock .bouton { min-height: 48px; padding: 0 var(--s-4); }

@media (max-width: 759px) {
  /* Téléphone : une seule ligne. Le nom de la boutique se tronque (« … »), la loupe et le compte restent à droite, la date disparaît. */
  .entete { flex-wrap: nowrap; gap: var(--s-2); padding: var(--s-2) var(--s-3); border-radius: var(--r-carte); }
  .entete .logo-texte { display: none; }
  .entete .identite { flex: 1 1 0; flex-direction: column; align-items: flex-start; gap: 0; }
  .entete .identite .boutique { max-width: 100%; }
  .entete .ouvrir-palette { margin-left: auto; flex: none; }
  .entete #jour { display: none; }
  .entete .compte { margin-left: 0; flex: none; }
  .entete .compte #qui { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .entete .compte .sep { display: none; }
}
@media (max-width: 899px) {
  .page { padding-bottom: calc(96px + 76px + var(--s-5) + env(safe-area-inset-bottom)); }
  /* Barre d'onglets du bas : quatre écrans principaux + « Plus ». Icône et libellé court, jamais coupé, jamais de défilement. */
  nav.onglets { position: fixed; left: var(--s-3); right: var(--s-3); bottom: calc(var(--s-3) + env(safe-area-inset-bottom)); z-index: 3; box-shadow: var(--ombre-haute); background: var(--verre-fort);
    overflow: visible; justify-content: space-between; gap: 0; padding: 6px; }
  nav.onglets button[data-onglet]:not([data-principal]) { display: none; }
  nav.onglets button { flex: 1 1 auto; min-width: 0; padding: 6px 4px; }
  nav.onglets .libelle-nav { font-size: var(--t-1); }
}
@media (min-width: 900px) { nav.onglets button[data-plus], dialog.plus { display: none !important; } }
dialog.plus { margin: auto auto calc(96px + env(safe-area-inset-bottom)); }
dialog.plus ul { padding: var(--s-2); }
dialog.plus li button .pictogramme { display: grid; place-items: center; width: 22px; height: 22px; color: var(--vert); }
dialog.plus li button:hover .pictogramme, dialog.plus li button[aria-selected="true"] .pictogramme { color: inherit; }
dialog.plus li button .pictogramme svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
dialog.plus li button[aria-current="page"] { font-weight: 600; background: var(--voile); }
@media (min-width: 760px) {
  .bento { grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-template-areas: "hero hero faire faire" "hero hero mois mois" "casc casc jours jours" "prod prod prod prod" "estim estim estim estim"; }
  .c-hero { grid-area: hero; padding: var(--s-6); }
  .c-faire { grid-area: faire; }
  .c-jours { grid-area: jours; }
  .c-mois { grid-area: mois; }
  .c-casc { grid-area: casc; }
  .c-prod { grid-area: prod; }
  .c-estim { grid-area: estim; }
}
.case.c-estim:empty { display: none; }

/* Grand écran : le RAIL flottant, une pilule de verre verticale, icônes rondes ; l'actif est un rond blanc ; la bulle sombre au survol. */
@media (min-width: 900px) {
  .page { padding: var(--s-5) var(--s-6) var(--s-7) 112px; }
  #application > nav.onglets { position: fixed; left: var(--s-5); top: 50%; transform: translateY(-50%); z-index: 5; flex-direction: column; gap: 6px;
    overflow: visible; max-height: calc(100vh - 48px); padding: 8px; scroll-snap-type: none; }
  #application > nav.onglets button { width: 46px; height: 46px; min-width: 0; min-height: 46px; padding: 0; border-radius: 50%; }
  #application > nav.onglets button[data-debut-groupe]:not(:first-child) { margin-top: var(--s-3); }
  #application > nav.onglets button[data-debut-groupe]:not(:first-child)::before { content: ""; position: absolute; top: -9px; left: 12px; right: 12px; height: 1px; background: var(--filet); }
  #application > nav.onglets .libelle-nav { position: absolute; left: 58px; top: 50%; transform: translate(-6px, -50%); white-space: nowrap; font-size: var(--t-1);
    padding: 6px 12px; border-radius: var(--r-1); background: var(--encre); color: var(--fond); opacity: 0; pointer-events: none; z-index: 6; }
  #application > nav.onglets button:hover .libelle-nav, #application > nav.onglets button:focus-visible .libelle-nav { opacity: 1; transform: translate(0, -50%); }
  #application > .panneau { min-width: 0; }
  .c-hero { min-height: 340px; }
}

button.pourquoi { background: none; border: 0; padding: 0; min-height: 44px; display: inline-flex; align-items: center; color: var(--encre-2);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer; font-size: var(--t-1); }
.explication { display: none; padding: var(--s-3) var(--s-4); border-radius: var(--r-2);
  background: var(--panneau); border: var(--trait) solid var(--verre-bord); color: var(--encre-2); font-size: var(--t-1); line-height: 1.6; }
.explication.ouverte { display: block; }
.explication code { color: var(--encre); font-family: inherit; font-weight: 600; }

/* ---- La cascade : d'où vient le bénéfice, euro par euro ----
   Chaque ligne : le nom et le montant au-dessus, une barre sur toute la largeur dessous. Chaque coût part là où le précédent s'arrête.
   Réel = barre pleine ; estimé = hachuré cerclé ; inconnu = zone grise hachurée (0 jusqu'à ce qui reste) et le mot « inconnu ». */
.cascade { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-3); }
.cascade li { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "nom montant" "piste piste"; align-items: baseline; gap: var(--s-1) var(--s-3); }
.cascade .nom { grid-area: nom; font-size: var(--t-1); color: var(--encre-2); }
.cascade .piste-c { grid-area: piste; position: relative; height: 14px; border-radius: var(--r-pleine); background: var(--filet); }
.cascade .seg { position: absolute; top: 0; bottom: 0; min-width: 3px; border-radius: var(--r-pleine); background: var(--marque); }
.cascade .seg.hachure { -webkit-mask: none; mask: none; background: repeating-linear-gradient(135deg, var(--marque) 0 2px, transparent 2px 6px); box-shadow: inset 0 0 0 1.5px var(--marque); }
.cascade .seg.inc { --marque: var(--encre-3); background: repeating-linear-gradient(135deg, color-mix(in oklch, var(--encre-3) 55%, transparent) 0 2px, transparent 2px 7px); box-shadow: inset 0 0 0 1.5px var(--hachure-inconnu); }
.cascade .montant { grid-area: montant; font-size: var(--t-2); font-weight: 600; text-align: right; }
.cascade li.entree { --marque: var(--entree); } .cascade li.sortie { --marque: var(--sortie); } .cascade li.action { --marque: var(--action); }
.cascade li.total { border-top: var(--trait) solid var(--filet); padding-top: var(--s-3); margin-top: var(--s-1); }
.cascade li.total .nom { color: var(--encre); font-weight: 600; font-size: var(--t-2); }
.cascade li.total .piste-c { height: 18px; }

/* ---- Infobulle du graphique : survol et clavier ---- */
.graphique { position: relative; }
.infobulle { position: absolute; z-index: 4; display: grid; gap: 1px; padding: var(--s-2) var(--s-3); border-radius: var(--r-2); pointer-events: none; white-space: nowrap;
  background: var(--verre-fort); border: var(--trait) solid var(--verre-bord); box-shadow: var(--ombre-haute); -webkit-backdrop-filter: var(--flou); backdrop-filter: var(--flou); }
.infobulle b { font-size: var(--t-2); font-weight: 600; }
.infobulle.perte b { color: var(--action); }
.infobulle.inconnu b { font-style: italic; font-weight: 400; color: var(--encre-3); }

/* Connexion (écran historique) */
#connexion { max-width: 380px; margin: 12vh auto; }
#connexion form { display: grid; gap: var(--s-4); margin-top: var(--s-4); }
#connexion label { display: grid; gap: var(--s-1); color: var(--encre-2); font-size: var(--t-1); }
#connexion input { background: var(--blanc-plein); border: var(--trait) solid var(--encre-3); color: var(--encre);
  border-radius: var(--r-2); padding: var(--s-3); font: inherit; min-height: 44px; }
#connexion h1 { font-size: var(--t-4); font-weight: 600; }

/* ============ 7. ÉCRANS ANCIENS (compatibilité) ============ */
.carte { border-radius: var(--r-carte); padding: var(--s-5); margin: var(--s-3) 0; }
h1 { font-size: var(--t-4); font-weight: 600; letter-spacing: -.02em; line-height: 1.15; }
h2 { font-size: var(--t-3); font-weight: 600; margin: var(--s-5) 0 var(--s-2); }
table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
table th { text-align: right; color: var(--encre-3); font-size: var(--t-1); font-weight: 400; padding: var(--s-2); }
table th:first-child, table td:first-child { text-align: left; padding-left: var(--s-2); }
table td { padding: var(--s-3) var(--s-2); border-top: var(--trait) solid var(--filet); text-align: right; }
.sous { color: var(--encre-2); font-size: var(--t-1); }
.legende { color: var(--encre-3); font-size: var(--t-1); margin-top: var(--s-2); }
.pos { color: var(--entree); } .neg { color: var(--action); }
.pastille { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: var(--s-2); }
.pastille.inconnu { background: transparent; border: var(--trait) dashed var(--encre-2); box-sizing: border-box; }
.pastille.ok { background: var(--entree); } .pastille.attention, .pastille.danger { background: var(--action); }
#deconnexion { background: none; border: 0; color: var(--encre-2); text-decoration: underline; cursor: pointer; font-size: var(--t-1); min-height: 44px; padding: 0 var(--s-1); }

@media (max-width: 640px) {
  #stocks .carte { overflow-x: auto; padding: var(--s-2) var(--s-3); }
  #stocks table th, #stocks table td { padding-left: 2px; padding-right: 2px; }
  #stocks table td:first-child { min-width: 4.5em; overflow-wrap: anywhere; }
  #stocks table td:not(:first-child) { font-size: var(--t-1); }
}

.bloc-estimations { display: grid; gap: var(--s-2); margin-block: var(--s-4); }
.bloc-estimations-titre { margin: 0; font-size: var(--t-2); }
.bloc-estimations ul { margin: 0; padding-left: var(--s-4); display: grid; gap: var(--s-2); }
.bloc-estimations li { color: var(--encre-2); }

/* Bouton d'ouverture de la palette (tactile et souris) */
.entete .ouvrir-palette { margin-left: auto; width: 44px; height: 44px; border: 0; border-radius: 50%; background: var(--voile); color: var(--encre-2); cursor: pointer; display: grid; place-items: center; }
.entete .ouvrir-palette:hover { background: var(--blanc-plein); color: var(--encre); }
.entete .ouvrir-palette svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.entete .ouvrir-palette ~ #jour { margin-left: 0; }
.palette .vide-p { padding: var(--s-4) var(--s-3); color: var(--encre-3); font-size: var(--t-1); }

/* Lien d'évitement : invisible jusqu'au focus clavier */
.evitement { position: fixed; left: var(--s-3); top: -80px; z-index: 70; padding: var(--s-3) var(--s-4); border-radius: var(--r-pleine); background: var(--encre); color: var(--fond); font-weight: 600; text-decoration: none; }
.evitement:focus-visible { top: var(--s-3); }

/* ============ 8. PALETTE DE COMMANDES (Cmd/Ctrl + K) ============ */
.palette { border: 0; padding: 0; background: transparent; max-width: min(560px, calc(100vw - 24px)); width: 100%; margin: 14vh auto 0; color: var(--encre); overflow: visible; }
.palette::backdrop { background: oklch(.17 .035 165 / .35); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.palette-boite { background: var(--verre-fort); border: var(--trait) solid var(--verre-bord); border-radius: var(--r-carte); box-shadow: var(--ombre-haute); overflow: hidden; }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { .palette-boite { background: var(--fond); } }
.palette input { width: 100%; min-height: 56px; padding: 0 var(--s-5); border: 0; border-bottom: var(--trait) solid var(--filet); background: transparent; color: var(--encre); font: inherit; font-size: var(--t-2); }
.palette input:focus-visible { outline: none; box-shadow: inset 0 -2px 0 var(--vert); border-radius: 0; }
.palette ul { list-style: none; margin: 0; padding: var(--s-2); max-height: 50vh; overflow: auto; }
.palette li button { width: 100%; min-height: 44px; display: flex; align-items: center; gap: var(--s-3); padding: 0 var(--s-3); border: 0; border-radius: var(--r-2); background: none; text-align: left; cursor: pointer; font-size: var(--t-2); }
.palette li button[aria-selected="true"], .palette li button:hover { background: var(--encre); color: var(--fond); }
.palette .groupe-p { font-size: var(--t-1); color: var(--encre-3); padding: var(--s-3) var(--s-3) var(--s-1); }
.palette .aide { font-size: var(--t-1); color: var(--encre-3); padding: var(--s-2) var(--s-5) var(--s-3); }

/* ============ 9. OUVERTURE APRÈS LA CONNEXION : lueur verte, puis vague circulaire depuis le coin haut gauche (web/ouverture.js) ============ */
.ouverture { position: fixed; inset: 0; z-index: 50; background: var(--vert-nuit); display: grid; place-items: center; overflow: hidden; cursor: pointer; }
.ouverture::before { content: ""; position: absolute; width: 90vmax; height: 90vmax; border-radius: 50%;
  background: radial-gradient(circle, oklch(.62 .12 165 / .26) 0%, oklch(.45 .10 165 / .1) 35%, transparent 65%); }
.ouverture .marque-ouv { position: relative; display: grid; justify-items: center; gap: var(--s-3); color: oklch(.92 .06 165); }
.ouverture .marque-ouv svg { width: 48px; height: 48px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; filter: drop-shadow(0 0 14px oklch(.80 .14 165 / .6)); }
.ouverture .marque-ouv p { font-size: var(--t-1); letter-spacing: .04em; color: oklch(.92 .06 165 / .75); }
.anneau { position: fixed; left: 0; top: 0; z-index: 60; width: 0; height: 0; border-radius: 50%; pointer-events: none; transform: translate(-50%, -50%);
  box-shadow: 0 0 0 2px oklch(.82 .13 165 / .75), 0 0 60px 18px oklch(.62 .12 165 / .38); }
.page.vague { clip-path: circle(var(--rayon) at 0 0); }

/* ============ 10. MOUVEMENT : il explique, il ne décore pas ============
   Entrée des cartes en cascade au changement d'écran, survol qui soulève, fondu, graphique qui se dessine, ouverture en vague,
   transition entre écrans (View Transitions). Rien de tout cela si l'appareil demande moins d'animation. */
@media (prefers-reduced-motion: no-preference) {
  .fondu { animation: fondu 180ms ease-out both; }
  .dessin .corps { animation: monte 220ms ease-out both; }
  .panneau.actif .bento > *, .panneau.actif > .carte, .panneau.actif > .case { animation: entre 620ms var(--ease-out) both; animation-delay: calc(var(--i, 0) * 70ms); }
  .bento > :nth-child(2), .panneau.actif > :nth-child(2) { --i: 1; } .bento > :nth-child(3), .panneau.actif > :nth-child(3) { --i: 2; }
  .bento > :nth-child(4), .panneau.actif > :nth-child(4) { --i: 3; } .bento > :nth-child(5), .panneau.actif > :nth-child(5) { --i: 4; }
  .bento > :nth-child(6), .panneau.actif > :nth-child(6) { --i: 5; } .bento > :nth-child(n+7), .panneau.actif > :nth-child(n+7) { --i: 6; }
  .tableau tbody tr { transition: background 160ms; }
  .case, .carte { transition: transform 250ms var(--ease-out), box-shadow 250ms var(--ease-out); }
  .case:hover, .carte:hover { transform: translateY(-3px); box-shadow: var(--ombre-haute); }
  .bouton, .filtres button, nav.onglets button { transition: background 200ms var(--ease-out), color 200ms, transform 200ms var(--ease-out); }
  .bouton:active { transform: scale(.97); }
  .sq { animation: reflet 1.6s ease-in-out infinite alternate; }
  .page.vague { animation: vague 1.1s var(--ease-vague) forwards; }
  .anneau.part { animation: anneau 1.1s var(--ease-vague) forwards; }
  .ouverture::before { animation: respire 2.4s ease-in-out infinite; }
  .ouverture.part { transition: opacity .4s ease .7s; opacity: 0; }
  ::view-transition-old(root) { animation: sort-ecran 180ms ease-in both; }
  ::view-transition-new(root) { animation: entre-ecran 360ms var(--ease-out) both; }
  @supports (animation-timeline: view()) {
    .reveler { animation: entre linear both; animation-timeline: view(); animation-range: entry 0% entry 40%; }
  }
}
@keyframes fondu { from { opacity: 0; } to { opacity: 1; } }
@keyframes monte { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes entre { from { opacity: 0; transform: translateY(14px) scale(.985); filter: blur(8px); } }
@keyframes reflet { to { opacity: .55; } }
@keyframes vague { from { --rayon: 0%; } to { --rayon: 150%; } }
@keyframes anneau { to { width: 300vmax; height: 300vmax; opacity: 0; } }
@keyframes respire { 50% { transform: scale(1.08); opacity: .8; } }
@keyframes sort-ecran { to { opacity: 0; filter: blur(8px); } }
@keyframes entre-ecran { from { opacity: 0; filter: blur(8px); } }
@media (prefers-reduced-motion: reduce) {
  .ouverture, .anneau { display: none !important; }
  .page.vague { clip-path: none; }
}

/* ============ 11. IMPRESSION ============ */
@media print {
  body::before, nav.onglets, .dock, .entete .jour, .palette { display: none !important; }
  .case, .carte, .vitre, .entete { background: none; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; border-color: var(--filet); }
  .c-hero { background: none; color: var(--encre); border-color: var(--encre); }
  .c-hero, .c-hero * { color: var(--encre) !important; }
  .page { padding: 0; }
}

/* ============ 12. TITRE DE PAGE : un grand titre et une phrase, sans carte (écrans simples) ============ */
.titre-page { display: grid; gap: var(--s-1); margin: var(--s-2) 0 var(--s-5); }
.titre-page h1 { font-size: var(--t-4); font-weight: 600; letter-spacing: -.03em; line-height: 1.1; margin: 0; }
.titre-page .sous-titre { color: var(--encre-2); font-size: var(--t-2); max-width: 62ch; }

/* Téléphone : une rangée de filtres reste sur UNE ligne qui défile sur le côté ; le bord qui s'estompe dit qu'il y a une suite. */
@media (max-width: 759px) {
  .filtres.defile-x { display: flex; flex-wrap: nowrap; overflow-x: auto; max-width: 100%; scrollbar-width: none; overscroll-behavior-x: contain; scroll-snap-type: x proximity;
    -webkit-mask: linear-gradient(90deg, oklch(0 0 0) calc(100% - 28px), transparent); mask: linear-gradient(90deg, oklch(0 0 0) calc(100% - 28px), transparent); }
  .filtres.defile-x::-webkit-scrollbar { display: none; }
  .filtres.defile-x button { flex: none; white-space: nowrap; scroll-snap-align: start; }
}

/* Barre d'action flottante : une pilule de verre collée en bas de l'écran, qui n'apparaît (hidden retiré) que lorsqu'il y a quelque chose à valider. */
.barre-flottante { position: sticky; bottom: calc(var(--s-4) + env(safe-area-inset-bottom)); z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  padding: var(--s-3) var(--s-4); border-radius: var(--r-pleine); background: var(--verre-fort); border: var(--trait) solid var(--verre-bord); box-shadow: var(--ombre-haute);
  -webkit-backdrop-filter: var(--flou); backdrop-filter: var(--flou); }
@media (prefers-reduced-motion: no-preference) { .barre-flottante:not([hidden]) { animation: entre 360ms var(--ease-out) both; } }
@media (max-width: 899px) { .barre-flottante { bottom: calc(96px + env(safe-area-inset-bottom)); } }
@media (min-width: 760px) { .barre-flottante { width: fit-content; justify-self: end; } }
nav.onglets button[data-plus] .pictogramme svg { stroke-width: 3.2; }

/* design3 : un texte n'est jamais plus petit que 13 px, même quand le balisage (app.js) le fixe en ligne. */
#produits .sous[style], #produits [style*="font-size"] { font-size: var(--t-1) !important; }

/* ============ 13. CODES D'INVITATION (fenêtre « montré une seule fois » et listes) — design3 ============ */
.ci-fenetre { border: 0; padding: 0; background: transparent; max-width: min(520px, calc(100vw - 24px)); width: 100%; color: var(--encre); overflow: visible; margin: auto; }
.ci-fenetre::backdrop { background: oklch(.17 .035 165 / .45); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.ci-boite { display: grid; gap: var(--s-3); padding: var(--s-6) var(--s-5); border-radius: var(--r-panneau); background: var(--verre-fort); border: var(--trait) solid var(--verre-bord); box-shadow: var(--ombre-haute); -webkit-backdrop-filter: var(--flou); backdrop-filter: var(--flou); }
.ci-titre { font-size: var(--t-3); font-weight: 600; letter-spacing: -.02em; margin: 0; }
.ci-code { display: block; padding: var(--s-4); border-radius: var(--r-2); background: var(--champ); border: var(--trait) dashed var(--vert); font-size: var(--t-3); font-weight: 600; letter-spacing: .06em; text-align: center; user-select: all; overflow-wrap: anywhere; white-space: normal; }
.ci-phrase { color: var(--encre-2); }
.ci-gestes { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.ci-retour { min-height: 1.4em; font-size: var(--t-1); color: var(--vert); margin: 0; }
.ci-case { display: flex; align-items: center; gap: var(--s-3); min-height: 44px; cursor: pointer; font-weight: 600; }
.ci-case input { width: 24px; height: 24px; margin: 0; accent-color: var(--vert); flex: none; }
.ci-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.ci-ligne { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; padding: var(--s-3) var(--s-4); border-radius: var(--r-2); background: var(--voile-leger); border: var(--trait) solid var(--filet); }
.ci-ligne .ci-qui { display: grid; gap: 2px; min-width: 0; }
.ci-ligne .ci-qui b { overflow-wrap: anywhere; }
.ci-etat { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--t-1); font-weight: 600; padding: 2px var(--s-3); border-radius: var(--r-pleine); border: 1.5px solid var(--encre-3); color: var(--encre-2); }
.ci-etat::before { content: ""; width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid currentColor; }
.ci-etat.actif { background: oklch(.62 .12 165 / .16); border-color: transparent; color: var(--vert); } .ci-etat.actif::before { background: currentColor; border: 0; }
.ci-etat.expire, .ci-etat.revoque { border-style: dashed; }
.ci-etat.utilise::before { background: currentColor; border: 0; border-radius: 2px; }
.ci-droits { display: grid; gap: 0; border: 0; padding: 0; margin: 0; }
.ci-droits legend { font-weight: 600; padding: 0; margin-bottom: var(--s-2); }
.ci-droit { display: flex; align-items: flex-start; gap: var(--s-3); min-height: 44px; padding: var(--s-2) 0; cursor: pointer; }
.ci-droit input { width: 24px; height: 24px; margin: 0; accent-color: var(--vert); flex: none; }
.ci-droit .etiquette { display: block; }
.ci-champ { display: grid; gap: var(--s-1); }
.ci-champ label { font-weight: 600; }
.ci-champ input[type=email], .ci-champ input[type=text] { min-height: 44px; width: 100%; box-sizing: border-box; padding: 0 var(--s-3); font: inherit; color: var(--encre); background: var(--champ); border: var(--trait) solid var(--encre-3); border-radius: var(--r-2); }
.ci-champ input:focus-visible { outline: 2px solid var(--vert); outline-offset: 2px; }
.ci-erreur { margin: 0; font-size: var(--t-1); color: var(--action); } .ci-erreur:empty { display: none; }
.ci-ok { margin: 0; font-size: var(--t-1); color: var(--vert); } .ci-ok:empty { display: none; }

.ci-confirme { display: inline-flex; align-items: center; flex-wrap: wrap; gap: var(--s-2); font-weight: 600; }
.ci-confirme .bouton { min-height: 44px; padding: 0 var(--s-4); }
@media (max-width: 759px) { .ci-ligne { align-items: flex-start; } .ci-ligne .ci-action { width: 100%; } .ci-ligne .ci-action .bouton { width: 100%; } }
.ci-etat.inconnu { border-style: dashed; font-style: italic; }

/* ============ 14. design3 : en-tête sans trou, champs et cases visibles en sombre, états vides teintés ============ */
.entete { flex-wrap: nowrap; align-items: center; }
.entete .compte { white-space: nowrap; margin-left: auto; }
.entete #jour:not(:empty) + .compte { margin-left: 0; }
.entete #jour:empty, .entete #fraicheur:empty { display: none; }
/* Cases à cocher dessinées : un contour net (≥ 3:1) en clair comme en sombre. */
.ci-droit input, .ci-case input, .param-case input[type=checkbox] { appearance: none; -webkit-appearance: none; width: 24px; height: 24px; margin: 0; flex: none; border: 2px solid var(--encre-2); border-radius: 7px; background: var(--champ); display: inline-grid; place-content: center; cursor: pointer; }
.ci-droit input:checked, .ci-case input:checked, .param-case input[type=checkbox]:checked { background: var(--vert-fort); border-color: var(--vert-fort); }
.ci-droit input:checked::after, .ci-case input:checked::after, .param-case input[type=checkbox]:checked::after { content: ""; width: 12px; height: 7px; border-left: 2.5px solid var(--sur-vert); border-bottom: 2.5px solid var(--sur-vert); transform: translateY(-1px) rotate(-45deg); }
@media screen and (prefers-color-scheme: dark) {
  .vide { background: oklch(.30 .03 165 / .45); border-color: oklch(1 0 0 / .22); }
  .ci-champ input[type=email], .ci-champ input[type=text], .sec-champ input { border-color: var(--encre-2); }
}

/* design3 : règles déplacées des feuilles d'écran (elles n'ont droit à aucun dégradé) */
/* design3 : la carte héros de Système est verte comme celle des autres écrans (clair et sombre). */
#systeme .sys-hero { color: var(--sur-vert); border-color: oklch(1 0 0 / .28); background: linear-gradient(150deg, oklch(.50 .10 165) 0%, oklch(.43 .09 165) 55%, oklch(.36 .07 165) 100%); }
#systeme .sys-hero .etiquette, #systeme .sys-hero .sys-grand { color: var(--sur-vert); }

/* design3 : les groupes de choix ne poussent plus la carte (min-width) et défilent sur une ligne avec un bord qui s'estompe. */
.cmd-controles > div { min-width: 0; max-width: 100%; }
@media (max-width: 759px) { .cmd-controles .filtres { max-width: 100%; display: flex; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; -webkit-mask: linear-gradient(90deg, oklch(0 0 0) calc(100% - 28px), transparent); mask: linear-gradient(90deg, oklch(0 0 0) calc(100% - 28px), transparent); }
  .cmd-controles .filtres::-webkit-scrollbar { display: none; } .cmd-controles .filtres button { flex: none; white-space: nowrap; } }

/* design3 : sur téléphone, les catégories défilent sur une ligne et le bord qui s'estompe dit qu'il y a une suite. */
@media (max-width: 759px) { .param-nav { -webkit-mask: linear-gradient(90deg, oklch(0 0 0) calc(100% - 28px), transparent); mask: linear-gradient(90deg, oklch(0 0 0) calc(100% - 28px), transparent); } }
