/* etabli.css v0.1.0 — copie, ne pas modifier ici.
   Toute correction remonte à ~/projects/perso/etabli. */
/* ==========================================================================
   ÉTABLI — design system des apps perso
   Copié dans chaque app, jamais modifié sur place : une correction remonte au
   dépôt ~/projects/perso/etabli puis redescend par `scripts/installer_css.py`.

   Établi ne définit AUCUNE teinte d'accent : c'est ce qui distingue une app des
   autres. Chaque app pose sa paire --accent / --accent-tx / --accent-soft /
   --accent-line / --ring, pour les DEUX thèmes, vérifiée au contraste :
   `python3 css/verifier_contrastes.py "#8c2f39" "#ffffff"`.

   Cette vérification n'est pas une formalité : l'ancien accent de recipes
   (#FEF991) tenait sur fond noir et tombait à 1,2:1 sur fond blanc.
   ========================================================================== */

/* --- Jetons : thème clair (défaut) --------------------------------------- */
:root {
  --bg: #f7f7f6;
  --surface: #ffffff;
  --surface-2: #f2f2f0;   /* zone en retrait, ligne survolée */
  --surface-hi: #ffffff;  /* élément surélevé : menu, popover */

  /* `--line` et `--line-strong` sont décoratifs (séparateurs, bord de carte).
     `--line-controle` est le seul qui identifie un contrôle : il tient 3:1
     comme l'exige WCAG 1.4.11, les deux autres n'y sont pas soumis. */
  --line: #e4e3df;
  --line-strong: #d3d2cd;
  --line-controle: #8a8880;

  --tx: #16150f;
  --tx-2: #5f5d55;
  --tx-3: #6f6d64;        /* gris de service : libellés, unités, inactifs */

  --ok-bg: #e7f4e7;   --ok-tx: #1e5320;   --ok-line: #bfe0c0;
  --warn-bg: #fdf1dd; --warn-tx: #6b4200; --warn-line: #f0dcb0;
  --err-bg: #fdecec;  --err-tx: #8c1d1d;  --err-line: #f3c9c9;
  --info-bg: #e8f0fd; --info-tx: #1a4a8c; --info-line: #c5d9f5;

  --shadow-1: 0 1px 2px rgba(20,18,10,.05), 0 1px 1px rgba(20,18,10,.04);
  --shadow-2: 0 6px 16px -6px rgba(20,18,10,.14), 0 2px 5px -2px rgba(20,18,10,.08);
  --shadow-3: 0 1px 2px rgba(20,18,10,.04), 0 12px 32px -12px rgba(20,18,10,.16);

  color-scheme: light;
}

/* --- Jetons : thème sombre ----------------------------------------------- */
/* Le sombre n'est pas une inversion : les surfaces s'ÉCLAIRCISSENT à mesure
   qu'elles s'élèvent, et l'accent se désature.
   `:root:not([data-theme="light"])` est ce qui permet à un choix « clair »
   explicite de gagner contre un système en sombre. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0d0d0e;
    --surface: #161618;
    --surface-2: #1d1d20;
    --surface-hi: #1f1f23;

    --line: #26262a;
    --line-strong: #35353b;
    --line-controle: #66666f;

    --tx: #f2f1ee;
    --tx-2: #a3a29c;
    --tx-3: #8a8982;

    --ok-bg: #16290f;   --ok-tx: #9bd79b;   --ok-line: #274a20;
    --warn-bg: #2a1e10; --warn-tx: #f0c07a; --warn-line: #4a3616;
    --err-bg: #2c1414;  --err-tx: #f5a9a9;  --err-line: #4d2222;
    --info-bg: #101f33; --info-tx: #9dc0f0; --info-line: #1e3a5c;

    --shadow-1: 0 1px 2px rgba(0,0,0,.5);
    --shadow-2: 0 10px 26px -10px rgba(0,0,0,.75), 0 2px 6px -2px rgba(0,0,0,.5);
    --shadow-3: 0 1px 2px rgba(0,0,0,.5), 0 14px 36px -14px rgba(0,0,0,.8);

    color-scheme: dark;
  }
}

/* Choix explicite. Duplique le bloc ci-dessus : c'est le prix à payer pour
   qu'une préférence stockée l'emporte sur le réglage du système. */
:root[data-theme="dark"] {
  --bg: #0d0d0e;
  --surface: #161618;
  --surface-2: #1d1d20;
  --surface-hi: #1f1f23;

  --line: #26262a;
  --line-strong: #35353b;
  --line-controle: #66666f;

  --tx: #f2f1ee;
  --tx-2: #a3a29c;
  --tx-3: #8a8982;

  --ok-bg: #16290f;   --ok-tx: #9bd79b;   --ok-line: #274a20;
  --warn-bg: #2a1e10; --warn-tx: #f0c07a; --warn-line: #4a3616;
  --err-bg: #2c1414;  --err-tx: #f5a9a9;  --err-line: #4d2222;
  --info-bg: #101f33; --info-tx: #9dc0f0; --info-line: #1e3a5c;

  --shadow-1: 0 1px 2px rgba(0,0,0,.5);
  --shadow-2: 0 10px 26px -10px rgba(0,0,0,.75), 0 2px 6px -2px rgba(0,0,0,.5);
  --shadow-3: 0 1px 2px rgba(0,0,0,.5), 0 14px 36px -14px rgba(0,0,0,.8);

  color-scheme: dark;
}
:root[data-theme="light"] { color-scheme: light; }

/* --- Formes, espacement, mouvement, typographie --------------------------- */
:root {
  --r-s: 6px; --r-m: 10px; --r-l: 14px; --r-xl: 18px;

  /* Base de 4. Une valeur d'espacement écrite en dur est un jeton manquant. */
  --e-1: 4px; --e-2: 8px; --e-3: 12px; --e-4: 16px;
  --e-5: 24px; --e-6: 32px; --e-7: 48px;

  --lg-lecture: 720px;  /* contenu linéaire */
  --lg-large: 1240px;   /* grilles et tableaux */

  --ease: cubic-bezier(.2,.7,.3,1);
  --t: 140ms var(--ease);

  --sans: ui-sans-serif, -apple-system, BlinkMacSystemFont, "SF Pro Text",
          "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --serif: Georgia, "Iowan Old Style", "Times New Roman", serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, "JetBrains Mono",
          "Cascadia Mono", Menlo, Consolas, monospace;
}

/* --- L'ACCENT est fourni par l'application ------------------------------- */
/* Socle ne définit aucune teinte : c'est ce qui distingue une app des autres.
   Chaque app pose, dans sa propre feuille et POUR LES DEUX THÈMES :

     --accent        la teinte
     --accent-tx     le texte qui se pose dessus  (≥ 4,5:1 sur --accent)
     --accent-soft   fond discret teinté
     --accent-line   filet teinté
     --ring          l'accent à ~30 % d'opacité, pour l'anneau de focus

   L'accent est une PAIRE, jamais une couleur seule. Un jaune pâle qui tient
   sur fond noir tombe à 1,2:1 dès qu'on pose un fond blanc — c'est la leçon
   qui a coûté le plus cher dans recipes. Vérifier avant de commiter :
   `python3 verifier_contrastes.py`. */

/* --- Réinitialisation ---------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

/* `hidden` doit l'emporter sur les `display:flex` posés plus bas, sinon un
   élément masqué par le serveur reste visible. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--tx);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  min-height: 100dvh;   /* jamais 100vh : sur iOS la barre d'adresse rétracte la hauteur */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
img, svg { max-width: 100%; }
img { display: block; }

:focus-visible {
  outline: 2px solid var(--accent, var(--tx));
  outline-offset: 2px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* --- Typographie --------------------------------------------------------- */
h1, h2, h3 { line-height: 1.25; letter-spacing: -.015em; font-weight: 640; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.1rem; }
h3 { font-size: 1rem; }

/* Le serif est réservé aux grands titres et écrans d'accueil. Toute
   l'interface courante reste en --sans. */
.titre-affiche {
  font-family: var(--serif);
  font-weight: 500;
  letter-spacing: -.01em;
}

/* Chiffres en chasse fixe tabulaire : durées, quantités, montants, compteurs.
   Sans elle, une colonne « 5 min / 45 min / 120 min » danse d'une ligne à
   l'autre. */
.num {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: .92em;
  letter-spacing: -.01em;
}

.doux { color: var(--tx-2); }
.service { color: var(--tx-3); font-size: .85rem; }

.contenu { max-width: var(--lg-lecture); margin: 0 auto; padding: var(--e-4); }
.contenu-large { max-width: var(--lg-large); margin: 0 auto; padding: var(--e-4); }

/* ==========================================================================
   COMPOSANTS
   ========================================================================== */

/* --- Bandeau collant ----------------------------------------------------- */
.bandeau {
  position: sticky; top: 0; z-index: 50;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  padding: var(--e-2) var(--e-4);
  padding-top: calc(var(--e-2) + env(safe-area-inset-top, 0px));
}
@supports (backdrop-filter: blur(1px)) {
  .bandeau {
    background: color-mix(in srgb, var(--bg) 88%, transparent);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
  }
}
.bandeau .dedans {
  display: flex; align-items: center; gap: var(--e-3);
  max-width: var(--lg-large); margin: 0 auto;
}
.bandeau .marque { font-weight: 640; letter-spacing: -.02em; margin-right: auto; }
.bandeau nav { display: flex; gap: var(--e-4); font-size: .9rem; }
.bandeau nav a { color: var(--tx-2); }
.bandeau nav a:hover, .bandeau nav a[aria-current] { color: var(--tx); }

/* --- Carte --------------------------------------------------------------- */
.carte {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-l);
  padding: var(--e-4);
  box-shadow: var(--shadow-1);
}
.carte-flottante {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: var(--e-6) var(--e-5) var(--e-5);
  box-shadow: var(--shadow-3);
}

/* --- Boutons ------------------------------------------------------------- */
/* 44px de haut : cible tactile minimale. Un bouton de 32px se rate au doigt. */
.bouton {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--e-2);
  min-height: 44px; padding: 0 var(--e-4);
  font: inherit; font-weight: 600;
  border: 1px solid var(--line-controle);
  border-radius: var(--r-m);
  background: var(--surface); color: var(--tx);
  cursor: pointer;
  transition: background var(--t), border-color var(--t), color var(--t);
}
.bouton:hover { background: var(--surface-2); }
.bouton:active { transform: translateY(1px); }
.bouton[disabled] { opacity: .5; cursor: not-allowed; }

.bouton.principal {
  background: var(--accent); color: var(--accent-tx);
  border-color: transparent;
}
.bouton.principal:hover { filter: brightness(.94); background: var(--accent); }

.bouton.discret {
  background: transparent; border-color: transparent; color: var(--tx-2);
  min-height: 36px; padding: 0 var(--e-2); font-weight: 500; font-size: .9rem;
}
.bouton.discret:hover { background: var(--surface-2); color: var(--tx); }

.bouton.pleine-largeur { width: 100%; }

/* --- Champs -------------------------------------------------------------- */
.champ { display: flex; flex-direction: column; gap: var(--e-1); }
.champ > span { font-size: .85rem; color: var(--tx-2); }

/* `input:not([type])` n'est pas une coquetterie : un <input name="x"> sans
   attribut type est un champ texte parfaitement valide, et c'est la forme la
   plus courante dans un gabarit. Sans cette ligne il ressort au style natif du
   navigateur au milieu de champs stylés — l'app a l'air cassée. */
.champ input, .champ select, .champ textarea,
input:not([type]), input[type=text], input[type=email], input[type=password],
input[type=search], input[type=number], input[type=date], input[type=url],
input[type=tel], select, textarea {
  width: 100%;
  padding: var(--e-2) var(--e-3);
  /* 16px, et pas moins : en dessous, Safari zoome la page au focus. */
  font: inherit; font-size: 16px;
  color: var(--tx);
  background: var(--surface);
  border: 1px solid var(--line-controle);
  border-radius: var(--r-m);
  transition: border-color var(--t), box-shadow var(--t);
}
.champ input:focus, .champ select:focus, .champ textarea:focus,
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--ring);
}
textarea { min-height: 5rem; resize: vertical; }

/* --- Badges d'état ------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: var(--e-1);
  padding: 2px var(--e-2);
  font-size: .8rem; font-weight: 600;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface-2); color: var(--tx-2);
}
.badge.ok   { background: var(--ok-bg);   color: var(--ok-tx);   border-color: var(--ok-line); }
.badge.warn { background: var(--warn-bg); color: var(--warn-tx); border-color: var(--warn-line); }
.badge.err  { background: var(--err-bg);  color: var(--err-tx);  border-color: var(--err-line); }
.badge.info { background: var(--info-bg); color: var(--info-tx); border-color: var(--info-line); }

/* --- Alertes ------------------------------------------------------------- */
.alerte {
  padding: var(--e-3);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  background: var(--surface-2); color: var(--tx-2);
  font-size: .9rem;
}
.alerte.ok   { background: var(--ok-bg);   color: var(--ok-tx);   border-color: var(--ok-line); }
.alerte.warn { background: var(--warn-bg); color: var(--warn-tx); border-color: var(--warn-line); }
.alerte.err  { background: var(--err-bg);  color: var(--err-tx);  border-color: var(--err-line); }
.alerte.info { background: var(--info-bg); color: var(--info-tx); border-color: var(--info-line); }

/* --- Listes -------------------------------------------------------------- */
.liste { list-style: none; }
.liste > li {
  padding: var(--e-3) 0;
  border-bottom: 1px solid var(--line);
}
.liste > li:last-child { border-bottom: 0; }
.liste .titre-ligne { font-weight: 600; }
.liste .meta { display: block; color: var(--tx-2); font-size: .85rem; }

/* --- Tableaux ------------------------------------------------------------ */
/* Le conteneur défile, pas la page : sur téléphone un tableau large ne doit
   jamais provoquer un défilement horizontal du document entier. */
.tableau-conteneur { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tableau { width: 100%; border-collapse: collapse; font-size: .9rem; }
.tableau th, .tableau td {
  padding: var(--e-2) var(--e-3);
  text-align: left;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.tableau th { color: var(--tx-3); font-weight: 600; font-size: .8rem; }
.tableau tbody tr:hover { background: var(--surface-2); }

/* --- Navigation basse (téléphone) ---------------------------------------- */
.nav-basse { display: none; }
@media (max-width: 640px) {
  .nav-basse {
    display: flex;
    position: fixed; inset: auto 0 0 0; z-index: 30;
    background: var(--surface);
    border-top: 1px solid var(--line);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .nav-basse a {
    flex: 1;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; min-height: 56px;
    color: var(--tx-3); font-size: .7rem; font-weight: 600;
  }
  .nav-basse a[aria-current] { color: var(--accent); }
  .nav-basse .ico { font-size: 1.15rem; line-height: 1; }
}
