/* Le registre — la feuille unique de l'application.
 *
 * Les couleurs des trois echelles ne sont PAS ici : elles sortent de
 * `outils/jetons.py` dans `jetons.css`. Tout le reste tient dans un seul jeu
 * de variables — une seule DA, pierre et foret, pas de theme sombre.
 *
 * Le fond ne dit rien : c'est ce qui permet a la couleur de vouloir dire
 * quelque chose partout ailleurs.
 */

/* Nunito, hebergee localement (OFL) — quetes/static/quetes/fonts/ */
@font-face {
  font-family: "Nunito";
  src: url("fonts/nunito-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Nunito";
  src: url("fonts/nunito-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Nunito";
  src: url("fonts/nunito-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Nunito";
  src: url("fonts/nunito-800.woff2") format("woff2");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

/* ------------------------------------------------------------------ jetons */

:root {
  color-scheme: light;

  --fond: #ebe8e1;          /* pierre : gris chaud presque blanc, jamais sable */
  --carte: #ffffff;
  --tete: #ffffff;          /* bandeaux du haut et du bas */
  --creux: #f1eee8;
  --champ: #f1eee8;

  --encre: #1c1712;
  --encre-2: #58524a;
  --encre-3: #6f6960;       /* dates, compteurs, « a tenir » — un cran plus clair que --encre-2 */
  --encre-forte: #111111;   /* titre de quete/epic, plus noir que --encre */
  --encre-eteinte: #7a746b; /* titre d'une quete faite, barre */

  --trait: #d7d2c7;
  --trait-doux: #e6e2d9;
  --trait-fort: #c4beb1;    /* bouton menu, boutons secondaires */
  --trait-case: #8e877b;    /* contour de la case a cocher */

  --accent: #3f6b3a;        /* foret : coches, onglet ouvert, jauges, boutons forts */
  --accent-encre: #ffffff;
  --accent-sombre: #2f4f2a; /* sous-bois : le « + », le texte de l'onglet ouvert */
  --accent-pale: #dce9d6;   /* fond de l'onglet ouvert, du cadran « bon », du solde positif */
  --accent-semelle: #1b3018; /* ombre plate du « + » */
  --alerte: #8a3a22;        /* brique fonce : retard, prix manquant — texte seulement */
  --alerte-pale: #f1e3dd;   /* fond du cadran/solde "mauvais" */
  --epingle: #b8892f;       /* ambre : ne se confond ni avec l'accent (vert), ni l'or des gains (jaune) */
  --epingle-pale: #fbf2df;

  --ombre: none;            /* aucune ombre portee dans le registre */
  --arrondi: 12px;
  --arrondi-grand: 20px;    /* panneau de l'ile, feuille des filtres */
  /* Ce que le bandeau du bas occupe en bas de l'ecran, menton d'iPhone compris.
   * L'ile y ancre son panneau et sa boussole, la feuille y reserve sa place —
   * sans variable, changer le bandeau laissait un trou chez le voisin. */
  --quai: calc(74px + env(safe-area-inset-bottom));
  --colonne: 46rem;
  --paillasse: #d7dbe3;     /* le fond derriere le telephone dessine, hors DA */
  --appareil: 393px;   /* l'ecran du telephone dessine, cadre non compris */
  /* Centre horizontal du telephone quand le tableau de triche prend le
     reste de l'ecran (staff, >=1100px) : au premier tiers plutot qu'au
     centre, pour laisser au tableau plus que la moitie de l'ecran —
     demande de Loic le 16 septembre 2026, le panneau restait trop etroit
     pour la galerie. Source unique, lue par `.appareil` et `.tableau-triche`. */
  --triche-phone-x: 30vw;

  --corps: "Nunito", "Segoe UI", Roboto, system-ui, sans-serif;
  --titre: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Palatino, Georgia, serif;
}

/* ------------------------------------------------------------------- socle */

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--encre);
  font-family: var(--corps);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -.01em; }
h1 { font-family: var(--titre); font-size: 24px; font-weight: 700; }
h2 { font-size: 15px; }

/* Le sprite des jetons ne s'affiche pas : il n'est la que pour etre reference. */
.jetons-source { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ------------------------------------------------------------------- cadre */

.feuille { max-width: var(--colonne); margin: 0 auto; padding-bottom: calc(var(--quai) + 18px); }

/* L'interface est dessinee pour un telephone : c'est la ou l'application sert.
 * Sur un grand ecran, plutot que d'inventer une deuxieme mise en page a tenir
 * a jour, on montre la vraie dans un cadre d'appareil — ce qu'on regle ici est
 * exactement ce qu'on aura dans la main. Provisoire : l'ecran large aura sa
 * propre grammaire le jour ou il la merite.
 *
 * Sur telephone, `display: contents` efface le cadre : aucune regle a annuler,
 * aucune deuxieme mise en page. */
.appareil { display: contents; }

@media (min-width: 760px) {
  :root { --colonne: 100%; }

  body {
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 32px;
    background: var(--paillasse);
    overflow: auto;
  }

  .appareil {
    display: block;
    /* `transform` fait de l'appareil le repere des positions fixes : sans lui,
     * le bouton + se colle au coin du navigateur au lieu de l'ecran dessine.
     * Taille fixe (393x851, viewport d'un Redmi Note 10, ratio 20:9) : le
     * rendu doit etre identique quel que soit l'ecran ou la fenetre qui
     * l'affiche. Si la fenetre est plus petite, on la fait defiler (voir
     * `body { overflow: auto }`) plutot que de retrecir l'appareil. */
    transform: translateZ(0);
    position: relative;
    width: var(--appareil);
    height: 851px;
    flex-shrink: 0;
    background: var(--fond);
    border: 12px solid #0c0e12;
    border-radius: 46px;
    box-shadow: 0 24px 64px rgba(0, 0, 0, .35);
    overflow: hidden;
  }

  /* L'encoche, et la place qu'elle prend sur l'en-tete. */
  .appareil::before {
    content: "";
    position: absolute;
    z-index: 5;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 132px;
    height: 26px;
    background: #0c0e12;
    border-radius: 0 0 15px 15px;
  }
  .appareil .tete { padding-top: 32px; }

  /* Ca defile comme sur un telephone, mais un telephone ne montre pas de
   * barre de scroll : la cacher garde le cadre honnete avec l'appareil qu'il
   * mime. */
  .appareil > .feuille {
    height: 100%;
    overflow-y: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .appareil > .feuille::-webkit-scrollbar { display: none; }
  .appareil .quai { position: absolute; }
}

/* Le bandeau du haut. Le bouton de menu est partout ; la bourse (niveau, or,
 * rituels) ne s'y ajoute que sur l'Ile, seule page ou elle a un rapport
 * direct avec ce qu'on regarde. Doit rester au-dessus de `.ressources-ile`
 * (z-index 3, plus bas dans le DOM) : a egalite de z-index le menu deroulant
 * du bouton `...` (`.menu__volet`, imbrique ici) se retrouvait peint sous le
 * bandeau des ressources sur la page de l'Ile. */
.tete {
  position: sticky;
  top: 0;
  z-index: 4;
  background: var(--tete);
  border-bottom: 1px solid var(--trait);
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Le compte : un bouton, un volet. Le volet se pose par-dessus la liste, il ne
 * pousse pas l'en-tete. */
.menu { position: relative; flex: none; }
/* Les deux `details` du volet portent leur propre bouton : une seule regle
 * efface la puce des deux. */
.menu summary { list-style: none; }
.menu summary::-webkit-details-marker { display: none; }

.menu__bouton {
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 999px;
  border: 1.5px solid var(--trait-fort);
  color: var(--encre-2);
}
.menu[open] > .menu__bouton { color: var(--encre); border-color: var(--encre-2); }

.menu__volet {
  position: absolute;
  /* Le bouton est a gauche du bandeau : le volet tombe sous lui et s'ancre a
   * gauche pour ne pas sortir de l'ecran par la droite. */
  left: 0;
  top: calc(100% + 7px);
  z-index: 3;
  min-width: 200px;
  background: var(--carte);
  border: 1px solid var(--trait);
  border-radius: var(--arrondi);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .16);
  padding: 5px;
  display: flex;
  flex-direction: column;
}
.menu__item {
  font: inherit;
  font-size: 14px;
  text-align: left;
  color: var(--encre);
  text-decoration: none;
  background: transparent;
  border: 0;
  border-radius: 7px;
  padding: 9px 10px;
  cursor: pointer;
}
.menu__item:hover { background: var(--creux); }
.menu__item--danger { color: var(--alerte); }

/* La confirmation vit dans le volet : le clic ouvre la question, il ne ferme
 * pas la session. */
.menu__sortie[open] { background: var(--creux); border-radius: 7px; }
.menu__sortie form { display: flex; flex-direction: column; gap: 7px; padding: 0 10px 10px; }
.menu__question { margin: 0; font-size: 12.5px; color: var(--encre-2); }
.menu__sortie .bouton { justify-content: center; font-size: 13px; padding: 8px 12px; border-color: var(--trait); }


main { padding: 14px 16px 0; display: flex; flex-direction: column; gap: 18px; }

.pan { display: flex; flex-direction: column; gap: 9px; }
.pan > h2 {
  font-family: var(--titre);
  font-size: 16px;
  font-weight: 700;
  color: var(--encre-2);
}

.vide {
  color: var(--encre-2);
  font-size: 14px;
  background: var(--carte);
  border: 1px dashed var(--trait);
  border-radius: var(--arrondi);
  padding: 16px;
  text-align: center;
}

.renvoi { margin: 0; font-size: 13.5px; }
.renvoi a { text-decoration: none; }
.renvoi a:hover { text-decoration: underline; }

/* Les deux onglets de la creation (Quete / Rituel) — le choix de Loic pour le
 * bouton `+` du quai (13 septembre 2026) : un seul `+`, cette pilule pour
 * changer de cible sans repasser par le quai. */
.creation-onglets {
  display: flex;
  flex-shrink: 0;
  gap: 2px;
  padding: 3px;
  background: var(--creux);
  border-radius: 999px;
}
.creation-onglets__onglet {
  text-align: center;
  white-space: nowrap;
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--encre-2);
  text-decoration: none;
}
.creation-onglets__onglet--actif { background: var(--carte); color: var(--encre); box-shadow: var(--ombre); }

/* --------------------------------------------------------------- annonces */

.annonces { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.annonce {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  background: var(--carte);
  border: 1px solid var(--trait);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 10px 13px;
  font-size: 13.5px;
}
.annonce--error, .annonce--rappel { border-left-color: var(--alerte); }
.annonce form { margin-left: auto; }

/* ------------------------------------------------------------------ jetons */

/* Un embleme n'a pas de largeur propre : son cadre 56x48 la deduit de sa
 * hauteur. Une seule valeur a regler, jamais deux qui divergent.
 *
 * Attention : le cadre reserve de chaque cote la place des ailes du rang
 * maximal, donc la plaque ne fait que les deux tiers de la hauteur demandee.
 * 40 px de cadre donnent un embleme de 27 px — c'est cette taille-la qu'on
 * regle ici, pas celle de la boite. */
.jeton { display: block; flex: none; height: 40px; width: auto; }
/* Sur la ligne compacte d'un curseur, le jeton tient la hauteur de la barre,
 * pas la sienne : un rang 4 tout en ailes ne doit pas ecraser la ligne. */
.curseur__jeton .jeton { height: 36px; }
@media (max-width: 420px) { .jeton { height: 36px; } }

.icone { flex: none; width: 12px; height: 12px; }
.jeton__chiffre {
  font-family: "Segoe UI", Roboto, system-ui, sans-serif;
  font-weight: 700;
  font-size: 18px;
  text-anchor: middle;
  dominant-baseline: middle;
  paint-order: stroke;
  stroke: rgba(0, 0, 0, .35);
  stroke-width: 1.6px;
  stroke-linejoin: round;
}

/* ------------------------------------------------------------ la ligne */

.liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }

.ligne {
  display: flex;
  align-items: stretch;
  background: var(--carte);
  border: 1.5px solid var(--trait);
  border-radius: var(--arrondi);
  box-shadow: var(--ombre);
  overflow: hidden;
}

/* Le bandeau EST le jeton de priorite : sa couleur et son chiffre. Les trois
 * variables viennent de la classe `rang-N`, ecrite par outils/jetons.py. */
.ligne__rang {
  flex: none;
  width: 32px;
  display: grid;
  place-items: center;
  background: linear-gradient(180deg, var(--rang-haut), var(--rang-bas));
  color: var(--rang-encre);
  font-family: var(--titre);
  font-size: 17px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  box-shadow: inset -1px 0 0 rgba(0, 0, 0, .14), inset 0 1px 0 rgba(255, 255, 255, .35);
}
.ligne--faite .ligne__rang { filter: saturate(.18) opacity(.65); }

/* La coche se centre sur la hauteur reelle de la ligne, une ou deux lignes. */
.ligne__corps { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; padding: 10px 11px 10px 10px; }
.ligne__corps form { display: flex; }

.coche {
  width: 22px;
  height: 22px;
  flex: none;
  border-radius: 6px;
  border: 2px solid var(--trait-case);
  background: transparent;
  cursor: pointer;
  padding: 0;
  position: relative;
}
.coche:hover { border-color: var(--accent); }
.coche::after {
  content: "";
  position: absolute;
  left: 3px;
  top: 4px;
  width: 11px;
  height: 5px;
  border: solid var(--accent-encre);
  border-width: 0 0 2px 2px;
  transform: rotate(-45deg);
  opacity: 0;
}
.coche[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); }
.coche[aria-pressed="true"]::after { opacity: 1; }

/* Titre et marques vivent dans le meme conteneur souple. Les jetons montent
 * sur la ligne du titre quand il reste la place et basculent en dessous des
 * qu'il n'y en a plus : c'est le flex qui tranche, rien a mesurer cote
 * serveur. Une echeance, elle, prend toujours son propre etage. */
.ligne__texte { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }

.ligne__titre {
  flex: 0 1 auto;
  min-width: 0;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.3;
  color: var(--encre-forte);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.ligne__titre:hover { text-decoration: underline; text-underline-offset: 2px; }
.ligne__titre .icone-epingle { color: var(--epingle); vertical-align: -1px; margin-right: 1px; }
.ligne--datee .ligne__titre { flex-basis: 100%; }
.ligne--faite .ligne__titre { font-weight: 500; color: var(--encre-eteinte); text-decoration: line-through; }

/* En pause : grisee, mais lisible — ce n'est pas fait, c'est juste hors-jeu. */
.ligne--en-pause { opacity: .55; filter: saturate(.35); }

/* Meme forme que `.coche` (case, bordure, etats hover/presse) — seule la
 * taille du glyphe differe, donc `.coche.pause` en template plutot qu'une
 * seconde classe qui recopierait sa geometrie. Le glyphe est du texte, pas
 * le ::after en coche de `.coche` : celui-ci est donc neutralise. */
.pause { display: grid; place-items: center; font-size: 12px; line-height: 1; }
.pause::after { content: none; }

/* Meme geometrie que `.pause` — l'ambre distingue « epinglee » de
 * « accomplie »/« en pause », toutes deux vertes. */
.epingle { display: grid; place-items: center; color: var(--trait-case); }
.epingle::after { content: none; }
.epingle svg { width: 12px; height: 12px; }
.coche.epingle[aria-pressed="true"] {
  background: var(--epingle-pale);
  border-color: var(--epingle);
  color: var(--epingle);
}

.ligne__quand { display: flex; align-items: center; gap: 8px; flex: 0 1 auto; min-width: 0; }
.marques { display: flex; align-items: center; gap: 5px; flex: none; }
.ligne__marques { margin-left: auto; }

/* La galerie de triche (ile/_galerie_batiments.html) : une vignette par
 * azimut, sur fond sombre pour que les sprites (qui detourent en transparent)
 * restent lisibles quel que soit le theme de la page qui l'inclut. Sans
 * largeur fixee, `.ligne__images` (flex-shrink) retrecit en colonnes
 * plus etroites quand le conteneur manque de place — c'est ce qui la garde
 * lisible dans la page dediee et dans les colonnes de 260px des autres
 * onglets du tableau de triche. */
.ligne--batiment { align-items: flex-start; padding: 8px 0; }
.ligne__images { display: flex; flex-wrap: wrap; gap: 4px;
  background: #20262a; padding: 4px; border-radius: 6px; }
.ligne__images img { background: #384049; border-radius: 3px; }
/* `.ligne__corps` est pensee pour une ligne de todo (titre + meta en ligne,
 * `display:flex`) : ici elle porte trois paragraphes (palier, cout, effet)
 * qu'il faut empiler, pas aligner en trois colonnes etroites qui se
 * retrouvaient a couper chaque mot des que les vignettes prenaient de la
 * place. */
.ligne--batiment .ligne__corps { display: block; }

/* Le portrait du personnage qui tient ce batiment (§8) : rendu par le banc
 * (`bake/portraits.html`, buste neutre), un fichier par modele KayKit — cinq
 * portraits pour dix-huit batiments, plusieurs partagent le meme. */
.personnage-portrait { align-items: center; gap: 8px; background: none;
  border: none; box-shadow: none; margin-bottom: 8px; }
.personnage-portrait img { flex: none; border-radius: 999px; background: var(--creux); }

/* Les dialogues de triche (§8, previsualisation avant le chantier 8) : la
 * galerie et les scenes de dialogue cote a cote dans l'onglet Batiments,
 * ouvertes toutes les deux par le meme select (`#tt-bat-select`, base.html) —
 * "cliquer sur un perso" n'est pas un second geste. */
.tt-perso-layout { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; }
.tt-perso-galerie { flex: 1 1 260px; min-width: 220px; }
.tt-perso-dialogues { flex: 2 1 460px; min-width: 280px; }
.tt-dialogues-perso[data-cle] { display: none; }
.tt-dialogues-perso[data-cle].tt-bat-actif { display: block; }
.dialogues-pistes { display: flex; flex-wrap: wrap; gap: 14px; }

/* Une scene independante du theme de la page (comme .ligne__images ci-dessus) :
 * c'est une salle de projection sur fond sombre, pas un ecran de l'appli. */
.dialogue-scene { margin: 0; flex: 1 1 200px; max-width: 240px; }
.dialogue-scene__titre { display: block; font-size: 11px; color: var(--encre-3); margin: 0 0 4px; }
/* Colonne flexible, pas deux calques empiles : le buste occupe toute la
 * place laissee par le panneau (`flex: 1 1 auto`), jamais couvert par lui —
 * releve par Loic le 19 septembre 2026, un texte long mangeait le visage
 * quand les deux etaient positionnes en absolu l'un sur l'autre. Le panneau
 * (D compris) garde sa hauteur naturelle, donnee par son texte. */
.dialogue-scene__ecran {
  position: relative; overflow: hidden; border-radius: 12px; background: #0a1620;
  aspect-ratio: 9 / 16; box-shadow: 0 8px 22px -10px rgba(0, 0, 0, .6);
  display: flex; flex-direction: column;
}
.dialogue-scene__fond {
  position: absolute; inset: -8%; width: 116%; height: 116%; object-fit: cover;
  object-position: 50% 82%; filter: blur(5px) saturate(.92) brightness(.82);
}
.dialogue-scene__scene { position: relative; flex: 1 1 auto; min-height: 0; }
/* `max-width` cadre un buste carre (760x760) dans une zone plus etroite que
 * haute : sans object-position, `object-fit: contain` centre alors l'image
 * dans sa boite (trop haute pour son contenu retreci en largeur) et le buste
 * semble flotter au-dessus du panneau (releve par Loic le 19 septembre 2026).
 * Ancre en bas : le vide du letterboxing va en haut, jamais entre le
 * personnage et le texte. */
.dialogue-scene__acteur {
  position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);
  height: 100%; width: auto; max-width: 92%; object-fit: contain;
  object-position: 50% 100%;
  filter: drop-shadow(0 10px 18px rgba(0, 0, 0, .55));
}
.dialogue-scene--d .dialogue-scene__acteur--plein {
  position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);
  height: 46%; width: auto;
}

.dialogue-scene__panneau {
  position: relative; flex: 0 0 auto;
  background: linear-gradient(to bottom, rgba(9, 24, 33, .9), rgba(6, 17, 24, .97));
  border-top: 1px solid rgba(217, 164, 65, .4);
  padding: 18px 10px 10px; display: flex; flex-direction: column; gap: 6px;
}
.dialogue-scene__plaque {
  position: absolute; top: 0; left: 8px; transform: translateY(-50%);
  font-size: 11px; font-weight: 600; color: #f6ecd6;
  background: linear-gradient(to bottom, #23414f, #16303c);
  border: 1px solid rgba(217, 164, 65, .5); padding: 3px 10px; border-radius: 3px;
}
.dialogue-scene__texte { margin: 0; font-size: 12px; line-height: 1.42; color: #f1e7d4; }
.dialogue-scene__suite { align-self: flex-end; font-size: 10.5px; color: #9db3bd; }
.dialogue-scene__choix { display: flex; flex-wrap: wrap; gap: 5px; }
.dialogue-scene__bouton {
  font-size: 11px; font-weight: 600; padding: 5px 9px; border-radius: 999px;
  background: #c6da4e; color: #12261a;
}
.dialogue-scene__bouton:nth-child(2) { background: transparent; color: #cfe0e8; border: 1px solid rgba(207, 224, 232, .4); }
.dialogue-scene__bouton:nth-child(3) { background: transparent; color: #7f97a2; border: 1px solid rgba(127, 151, 162, .35); }

.dialogue-scene__rayons {
  position: absolute; left: 50%; bottom: 10%; width: 140%; padding-top: 140%;
  transform: translate(-50%, 50%);
  background: radial-gradient(closest-side, rgba(255, 224, 160, .28), rgba(255, 224, 160, .05) 55%, transparent 72%);
}
/* Le buste (72 % de la hauteur) occupe le bas de la carte : le texte se
 * cale donc en haut (pas de superposition sur le visage), et le bouton
 * seul redescend, sur les jambes plutot que sur la face. */
.dialogue-scene__ceremonie {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center;
  text-align: center; padding: 8% 8% 6%; gap: 5px;
}
.dialogue-scene__cta { margin-top: auto; }
.dialogue-scene__ceremonie h3 { margin: 0; font-size: 14px; color: #f7edd8; text-shadow: 0 2px 10px rgba(0, 0, 0, .7); }
.dialogue-scene__ceremonie p { margin: 0; font-size: 11.5px; color: #dbe6ec; text-shadow: 0 1px 6px rgba(0, 0, 0, .7); }
.dialogue-scene__gain { font-weight: 700; color: #f6dfa8 !important; }
.dialogue-scene__cta {
  margin-top: 4px; font-size: 11.5px; font-weight: 700; color: #12261a; background: #c6da4e;
  padding: 6px 16px; border-radius: 999px;
}

.quand {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--encre-3);
  font-variant-numeric: tabular-nums;
}
.quand--retard { color: var(--alerte); font-weight: 600; }
.quand svg { flex: none; }

.compte-etapes {
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--encre-3);
  border: 1px solid var(--trait);
  border-radius: 999px;
  padding: 0 7px;
  line-height: 17px;
}
.cadence, .serie { font-size: 11.5px; color: var(--encre-2); white-space: nowrap; }
.serie { font-weight: 600; }

/* -------------------------------------------------------------------- epic */

.epic {
  background: var(--carte);
  border: 1.5px solid var(--trait);
  border-radius: var(--arrondi);
  box-shadow: var(--ombre);
  overflow: hidden;
}
.epic > summary { list-style: none; cursor: pointer; }
.epic > summary::-webkit-details-marker { display: none; }

.epic__tete { display: flex; align-items: center; gap: 10px; padding: 11px 12px; }
.chevron {
  flex: none;
  width: 7px;
  height: 7px;
  border: solid var(--encre-2);
  border-width: 2px 2px 0 0;
  transform: rotate(45deg);
  margin-left: 3px;
}
.epic[open] .chevron { transform: rotate(135deg); margin-top: -3px; }

.sceau {
  width: 22px;
  height: 22px;
  flex: none;
  border-radius: 6px;
  background: linear-gradient(160deg, var(--teinte-claire), var(--teinte-sombre));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .4);
}

/* Les cinq memes couleurs servent au sceau d'un epic et a la pastille d'un
 * tag : une seule palette, sinon les deux divergent au premier ajustement. */
.sceau--rouge,    .tag--rouge    { --teinte-claire: #b5583f; --teinte-sombre: #6e2c18; }  /* brique */
.sceau--verte,    .tag--verte    { --teinte-claire: #6e9160; --teinte-sombre: #2f4f2a; }  /* foret */
.sceau--bleue,    .tag--bleue    { --teinte-claire: #7f919c; --teinte-sombre: #3e5160; }  /* ardoise */
.sceau--ambre,    .tag--ambre    { --teinte-claire: #cfa457; --teinte-sombre: #7f5a14; }  /* ambre */
.sceau--violette, .tag--violette { --teinte-claire: #8f7590; --teinte-sombre: #4c3550; }  /* prune */

.epic__titre { flex: 1; min-width: 0; font-weight: 700; font-size: 15px; color: var(--encre-forte); }
.epic__avancement { font-size: 12px; color: var(--encre-3); font-variant-numeric: tabular-nums; white-space: nowrap; }

.epic__dedans {
  border-top: 1px solid var(--trait-doux);
  background: var(--creux);
  padding: 8px 8px 10px 22px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.epic__dedans .ligne { box-shadow: var(--ombre); }
.epic__liens { display: flex; gap: 14px; padding: 2px 4px 0; font-size: 12.5px; margin: 0; }

.epic-range { list-style: none; }
.epic-range a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  background: var(--carte);
  border: 1px solid var(--trait);
  border-radius: var(--arrondi);
  text-decoration: none;
  color: var(--encre);
}

.accomplies > summary { font-size: 13px; color: var(--encre-2); cursor: pointer; padding: 4px 0; }

/* -------------------------------------------------------- le bandeau du bas */

/* Le bandeau du bas : Ile, Quetes, le `+`, Rituels — le meme sur toutes les
 * pages. Ce que la regle veut dire et pourquoi elle a ete prise :
 * `concept.md`, « le bandeau du bas ne change jamais ». Quatre onglets sont
 * des colonnes egales, le `+` ne se confond avec aucun d'eux — le Domaine
 * porte le bandeau a cinq cibles, ecart assume (spec du lot du Domaine).
 * Les signes viennent du sprite de `_jetons.html` et portent leur trait
 * eux-memes ; ici on ne pose que leur taille. */
.quai {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  height: var(--quai);
  background: var(--tete);
  border-top: 1.5px solid var(--trait);
  color: var(--encre-2);
  display: flex;
  gap: 2px;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
  /* L'ombre monte, elle ne descend pas : le bandeau flotte au-dessus de la
   * liste — et au-dessus de l'ile, qui n'a pas de bord a elle. */
  box-shadow: 0 -6px 18px -12px rgba(0, 0, 0, .55);
}

.quai__onglet {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  border-radius: 12px;
  color: var(--encre-2);
  text-decoration: none;
  font-size: 11px;
  letter-spacing: .02em;
  /* Le doigt ne survole pas : ce qui compte, c'est que le changement d'onglet
   * ne clignote pas. */
  transition: color .14s ease, background-color .14s ease;
}

.quai__signe { width: 23px; height: 23px; }

/* L'onglet ouvert s'allume : l'accent, le nom en gras, et un aplat tres pale
 * derriere. Le dessin ne change pas — un second jeu de signes pleins serait
 * deux fois le meme dessin a tenir. */
.quai__onglet--actif {
  color: var(--accent-sombre);
  font-weight: 700;
  background: var(--accent-pale);
}

/* Le bouton depasse du bandeau vers le haut : c'est ce qui le distingue d'une
 * quatrieme destination. Il ne porte pas de nom — un signe surleve et colore ne
 * se lit pas comme un onglet, l'ecrire n'ajouterait que du bruit.
 *
 * Un disque, pas un losange : une semelle portee en dessous (`box-shadow`
 * plat, pas un halo) plutot qu'une forme tournee — plus proche de la pierre
 * que d'Habitica. */
.plus {
  flex: none;
  align-self: center;
  margin: -20px 12px 0;
  width: 48px;
  height: 48px;
  border-radius: 999px;
  transform: none;
  border: 0;
  background: var(--accent-sombre);
  color: #ffffff;
  display: grid;
  place-items: center;
  text-decoration: none;
  box-shadow: 0 4px 0 var(--accent-semelle);
}

.plus__signe { transform: none; }

/* Le tableau de triche : a cote du telephone dessine, reserve au staff. Il ne
 * se montre que si la fenetre laisse la place a cote du cadre — sur un vrai
 * telephone `.appareil` disparait et il n'y a plus de « a cote ». `position:
 * fixed` le sort du flux (et donc du calcul de centrage du flex `body`) :
 * le telephone reste fixe quel que soit l'onglet ouvert, plutot que de
 * bouger avec la hauteur du panneau actif (demande de Loic, 16 septembre
 * 2026 — avant, changer d'onglet recentrait le duo telephone + tableau et
 * deplacait le telephone). Le tableau prend tout le reste de l'ecran a
 * droite du telephone (voir `--triche-phone-x` ci-dessous) : `left` calcule
 * le bord droit de l'appareil, sans marge ni carte flottante — juste un
 * trait pour le detacher du fond. Quatre onglets (Triche / Ajout bât /
 * Personnage / Reste) se partagent sa
 * largeur — avant eux, neuf blocs empiles dans une seule mise en colonnes
 * CSS forcaient plus de colonnes que la largeur ne pouvait en montrer, d'ou
 * une scrollbar horizontale. Chaque panneau garde ses propres colonnes
 * (`columns`), un bloc etant une carte independante (`break-inside: avoid`).
 * Titres repris de `.pan`. */
.tableau-triche { display: none; }
@media (min-width: 1100px) {
  /* Le telephone glisse au premier tiers (voir `--triche-phone-x`) pour que
     le tableau, qui prend tout le reste, ne soit pas coince a moitie
     d'ecran. `:has()` le limite au staff (seul a avoir ce panneau) : sans
     lui, tout le monde perdrait le centrage habituel des qu'il aurait la
     largeur pour voir apparaitre le tableau — qui n'existe meme pas dans
     leur DOM. */
  body:has(.tableau-triche) .appareil {
    position: fixed;
    top: 50%;
    left: var(--triche-phone-x);
    transform: translate(-50%, -50%) translateZ(0);
  }
  .tableau-triche {
    display: block;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: calc(var(--triche-phone-x) + (var(--appareil) / 2));
    overflow-y: auto;
    background: var(--carte);
    border-left: 1px solid var(--trait);
  }
  .tableau-triche .filtres input { width: 62px; }
}
.tableau-triche__titre {
  margin: 0;
  padding: 16px 16px 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--encre);
}

/* Quatre radios caches (etat) + labels (commande) : le tableau vit hors de
 * `#fond`, donc nav.js ne le remplace jamais — l'onglet ouvert survit tel
 * quel a chaque changement de page, sans une ligne de JS. La pilule reprend
 * `.creation-onglets`/`.creation-onglets__onglet` (labels au lieu de liens) ;
 * seul l'etat coche, propre au radio, s'ajoute ici. */
.tableau-triche__radio {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}
/* Colle en haut du panneau qui defile (le tableau occupe tout l'ecran en
 * hauteur desormais) : les onglets restent a portee quelle que soit la
 * longueur du contenu en dessous. `width: fit-content` garde la pilule
 * compacte (`.creation-onglets` est un flex bloc, donc pleine largeur par
 * defaut) : le tableau etant desormais tres large, quatre onglets etires
 * dessus laissaient des vides enormes entre les mots. */
.tableau-triche__onglets {
  position: sticky;
  top: 0;
  z-index: 1;
  width: fit-content;
  margin: 12px 16px 14px;
  background: var(--carte);
}
.tableau-triche__tab { cursor: pointer; }
/* Les radios sont soeurs de `.tableau-triche__onglets`, pas de leurs propres
 * labels (qui doivent rester groupes dans la pilule) : `~` rejoint le
 * conteneur, puis le descendant vise par `for`. */
#tt-triche:checked ~ .tableau-triche__onglets label[for="tt-triche"],
#tt-bat:checked ~ .tableau-triche__onglets label[for="tt-bat"],
#tt-perso:checked ~ .tableau-triche__onglets label[for="tt-perso"],
#tt-char:checked ~ .tableau-triche__onglets label[for="tt-char"],
#tt-decors:checked ~ .tableau-triche__onglets label[for="tt-decors"],
#tt-reste:checked ~ .tableau-triche__onglets label[for="tt-reste"] {
  background: var(--carte);
  color: var(--encre);
  box-shadow: var(--ombre);
}
#tt-triche:focus-visible ~ .tableau-triche__onglets label[for="tt-triche"],
#tt-bat:focus-visible ~ .tableau-triche__onglets label[for="tt-bat"],
#tt-perso:focus-visible ~ .tableau-triche__onglets label[for="tt-perso"],
#tt-char:focus-visible ~ .tableau-triche__onglets label[for="tt-char"],
#tt-decors:focus-visible ~ .tableau-triche__onglets label[for="tt-decors"],
#tt-reste:focus-visible ~ .tableau-triche__onglets label[for="tt-reste"] {
  outline: 2px solid var(--accent);
}

.tableau-triche__panneau { display: none; padding: 0 16px 16px; columns: 260px; column-gap: 20px; }
#tt-triche:checked ~ #tt-panneau-triche,
#tt-bat:checked ~ #tt-panneau-bat,
#tt-perso:checked ~ #tt-panneau-perso,
#tt-char:checked ~ #tt-panneau-char,
#tt-decors:checked ~ #tt-panneau-decors,
#tt-reste:checked ~ #tt-panneau-reste { display: block; }

/* L'onglet Personnage (exploration chantier 7) : une grille de vignettes,
 * une par personnage candidat — pas de select comme Batiments, quinze tiennent
 * cote a cote sans qu'il faille en choisir un a la fois. */
#tt-panneau-char { columns: initial; display: none; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 14px; }
#tt-char:checked ~ #tt-panneau-char { display: grid; }
.perso-extra { break-inside: avoid; padding: 10px; border: 1px solid var(--trait); border-radius: 10px; text-align: center; }
.perso-extra img { width: 100%; max-width: 180px; height: auto; }
.perso-extra h3 { margin: 6px 0 2px; font-size: 13px; }
.perso-extra .notes { font-size: 11px; }

/* L'onglet Decors (18 septembre 2026, demande de Loic) : meme grille que
 * Personnage, un paquet (pack CC0) a la fois, un badge de verdict par vignette
 * plutot que deux listes separees — plus facile a parcourir pack par pack. */
#tt-panneau-decors { columns: initial; display: none; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 12px; }
#tt-decors:checked ~ #tt-panneau-decors { display: grid; }
.decor-extra { break-inside: avoid; padding: 8px; border: 1px solid var(--trait); border-radius: 10px; text-align: center; position: relative; }
.decor-extra img { width: 100%; max-width: 140px; height: auto; }
.decor-extra h3 { margin: 4px 0 2px; font-size: 12px; }
.decor-extra .verdict { display: inline-block; margin-top: 2px; padding: 1px 6px; border-radius: 6px; font-size: 10px; }
.decor-extra .verdict--utilise { background: #2e5c3a; color: #d8ffe0; }
.decor-extra .verdict--exploitable, .decor-extra .verdict--exploitable_filler { background: #3a4a5c; color: #dcecff; }
.decor-extra .verdict--terrain_redondant { background: #5c4a2e; color: #ffe8c8; }
/* Titres de section dans la grille #tt-panneau-char : sur toute la largeur,
 * pas une case de plus parmi les vignettes. */
.perso-section-titre { grid-column: 1 / -1; margin: 18px 0 4px; font-size: 14px; }
.perso-section-titre:first-child { margin-top: 0; }
.perso-section-note { grid-column: 1 / -1; margin: 0 0 10px; font-size: 12px; color: var(--encre-2); }

/* L'onglet Personnage montre un seul batiment a la fois (`tt-bat-select`,
 * base.html) : en colonnes de 260px, l'image (3 vignettes) et le texte
 * (palier/cout/effet) de `_galerie_batiments.html` n'avaient pas la place de
 * tenir cote a cote, le texte se coupait (demande de Loic, 16 septembre
 * 2026). Pleine largeur ici, pas de colonnes ; `.pan[data-cle]` masque tout
 * sauf le batiment choisi. Depuis que le telephone glisse au premier tiers
 * (`--triche-phone-x`), ce panneau est bien plus large qu'avant — assez pour
 * que les six vignettes tiennent cote a cote agrandies, sans plus avoir
 * besoin de les figer a trois colonnes (l'ancien correctif, retire) ; sous
 * cette largeur, `flex-wrap` sur `.ligne__images` les replie de lui-meme.
 * Portrait et vignettes agrandis ici seulement — la page dediee et les
 * autres onglets restent a une largeur ou les tailles par defaut suffisent. */
#tt-panneau-perso { columns: initial; }
#tt-panneau-perso .pan[data-cle] { display: none; }
#tt-panneau-perso .pan[data-cle].tt-bat-actif { display: block; }
#tt-panneau-perso .ligne__images img { width: 176px; height: 176px; }
#tt-panneau-perso .personnage-portrait img { width: 200px; height: 200px; }
/* Sans plancher, `.ligne__corps` (flex-basis 0) perd tout l'arbitrage a
 * `.ligne__images` (qui replie une vignette de plus plutot que de retrecir)
 * pres de la largeur minimale du tableau (1100px) : le texte du cout/effet
 * se retrouvait coupe a un mot par ligne. */
#tt-panneau-perso .ligne__corps { min-width: 220px; }
.tableau-triche__choix {
  display: block;
  margin-bottom: 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--encre-2);
}
.tableau-triche__choix select { margin-left: 6px; }

.tableau-triche__bloc {
  break-inside: avoid;
  margin-bottom: 14px;
  padding: 12px;
  border: 1px solid var(--trait);
  border-radius: 10px;
}
.tableau-triche__note {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
  color: var(--encre-2);
  border: 1px solid var(--trait);
  border-radius: 999px;
  padding: 1px 7px;
  margin-left: 4px;
}
.tableau-triche__bloc--a-venir .bouton { opacity: .5; cursor: not-allowed; }

/* -------------------------------------------------------------- les champs */

.filtres { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.filtres label { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--encre-2); }

.saisie,
.filtres input, .filtres select,
.ajout-etape input,
.tag-ligne input, .tag-ligne select,
.formulaire input, .formulaire select, .formulaire textarea,
.chercher {
  background: var(--champ);
  border: 1.5px solid var(--trait);
  border-radius: 8px;
  padding: 8px 11px;
  font: inherit;
  font-size: 14px;
  color: var(--encre);
  width: 100%;
}
.filtres input, .filtres select { width: auto; font-size: 13px; padding: 6px 9px; }
/* `type="search"` porte son propre chrome (WebKit) par-dessus le fond/bordure
 * communs sans ce reset — le seul input du genre sur la page. */
.chercher { appearance: none; -webkit-appearance: none; }
textarea.saisie { resize: vertical; min-height: 62px; line-height: 1.5; }
.saisie--titre { font-size: 17px; font-weight: 600; padding: 11px 12px; }
::placeholder { color: var(--encre-2); opacity: .8; }

.bouton {
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  border-radius: 10px;
  padding: 9px 16px;
  border: 1.5px solid var(--trait-fort);
  background: transparent;
  color: var(--encre-2);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.bouton--fort { background: var(--accent); border-color: var(--accent); color: var(--accent-encre); }
.bouton--danger { color: var(--alerte); border-color: transparent; }
.bouton--pousse { margin-left: auto; }

/* --------------------------------------------------------------- la fiche */

.fiche { display: flex; flex-direction: column; gap: 12px; }

/* Le geste principal d'une page pose dans le bandeau du haut, a cote du
 * menu, plutot que sur sa propre ligne sous le bandeau. */
.tete-action { display: flex; align-items: center; gap: 9px; flex: 1; min-width: 0; font-size: 12.5px; }
.tete-action__retour { text-decoration: none; color: var(--accent); font-size: 15px; font-weight: 600; white-space: nowrap; }
.tete-action__bouton { margin-left: auto; padding: 6px 13px; font-size: 13px; }
.tete-action__titre { font-family: var(--titre); font-size: 17px; font-weight: 700; letter-spacing: -.01em; }
.tete-action__icone { margin-left: auto; }

.champ { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.champ__nom { font-size: 12.5px; color: var(--encre-2); margin: 0; }
/* Le placeholder du champ porte deja l'intitule : le label reste pour les
 * lecteurs d'ecran mais ne prend plus de place a l'ecran. */
.champ__nom--masque {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.champ__erreur { font-size: 12.5px; color: var(--alerte); margin: 0; }
/* La coche de la fiche est le meme geste que celle de la liste, au meme rang. */
.champ-titre { display: flex; align-items: center; gap: 10px; }

/* Titre + notes de la fiche de quete, en grille 2 colonnes x 2 rangees.
 * L'ordre des enfants dans le gabarit EST le placement : coche (col 1, ligne
 * 1), champ titre (col 2, ligne 1), epingle+pause (col 1, ligne 2), champ
 * notes (col 2, ligne 2) — l'ordre naturel du flux suffit, aucun
 * grid-column/row explicite a poser ni a desynchroniser du gabarit. */
.bloc-titre { display: grid; grid-template-columns: 22px 1fr; gap: 8px 10px; }
.colonne-coche { align-self: center; }
.colonne-actions { display: flex; flex-direction: column; justify-content: space-between; padding-block: 2px; }

.duo-champ { display: flex; gap: 10px; flex-wrap: wrap; }
.duo-champ .champ { flex: 1 1 150px; }
.duo-champ .champ--court { flex: 0 1 130px; }

/* La cloche est dans le champ, pas a cote : elle dit de quoi parle le menu. */
.champ-cloche { position: relative; display: flex; align-items: center; }
.champ-cloche svg { position: absolute; left: 11px; color: var(--encre-2); pointer-events: none; }
.champ-cloche .saisie { padding-left: 32px; }

.bloc {
  border: 1.5px solid var(--trait);
  border-radius: var(--arrondi);
  background: var(--carte);
  box-shadow: var(--ombre);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.bloc__tete { display: flex; align-items: center; gap: 10px; }
.bloc__nom { font-size: 13px; font-weight: 600; }
.bloc__compte { margin-left: auto; font-size: 12px; color: var(--encre-2); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------- la recompense */

/* L'or et l'experience se lisent comme un prix : l'embleme puis le nombre.
 * Bareme provisoire, il vit dans le modele (chantier 5). */
.gain { display: inline-flex; align-items: center; gap: 4px; }
.gain__embleme { width: 15px; height: 15px; flex: none; }
.gain__valeur { font-size: 13px; color: var(--encre-2); font-weight: 700; font-variant-numeric: tabular-nums; }
.gain__plafond { font-size: 11px; color: var(--encre-2); opacity: .6; font-variant-numeric: tabular-nums; }

/* Le bandeau du haut (niveau, or, rituels), reserve a l'Ile — spec du lot
 * Domaine §5. Agrandi (`.tete--reduite`) pour laisser au niveau sa propre
 * ligne. */
.tete--reduite { padding: 13px 16px; gap: 14px; }
.bourse-reduite { display: flex; align-items: center; gap: 16px; flex: 1; min-width: 0; }
.bandeau-progres { display: flex; flex-direction: column; gap: 4px; }
.bandeau-niveau { display: flex; align-items: center; gap: 7px; }
.bandeau-niveau__mot { font-size: 14px; font-weight: 700; white-space: nowrap; }
.bandeau-niveau__barre { width: 68px; }
.bandeau-or { display: flex; align-items: center; gap: 6px; }
/* La gemme suit l'or avec un peu plus de champ : deux monnaies cote a cote
 * sans separateur se liraient comme une seule valeur. */
.bandeau-or .gain:last-child { margin-left: 4px; }

/* Bois, pierre, nourriture : ligne compacte sous l'en-tete de l'Ile (demande
 * de Loic, 13 septembre 2026). Pas besoin de `position: sticky` — la scene
 * est `fixed` derriere (`ile.css`), la page ne defile jamais, l'en-tete et
 * cette ligne restent donc visibles par construction. */
.ressources-ile {
  position: relative;
  z-index: 3;
  display: flex;
  gap: 16px;
  padding: 7px 16px 8px;
  background: var(--tete);
  border-bottom: 1px solid var(--trait);
  font-size: 13px;
}

/* L'anneau est tout a droite, loin du cluster niveau/or : deux echelles de
 * progression cote a cote se liraient comme une seule sinon. Le signe
 * `#icone-rituels` (le meme que l'onglet du bas) dit ce qu'il compte, sans
 * texte a cote qui ferait doublon avec le titre de la page. */
.bandeau-rituels { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.bandeau-rituels__mot { font-size: 11px; font-weight: 600; color: var(--encre-2); text-transform: uppercase; letter-spacing: .03em; }
.anneau-rituels {
  --part: 0%;
  width: 38px;
  height: 38px;
  border-radius: 999px;
  flex: none;
  display: grid;
  place-items: center;
  background: conic-gradient(var(--accent) var(--part), var(--trait) 0);
}
.anneau-rituels__mot {
  width: 30px;
  height: 30px;
  border-radius: 999px;
  background: var(--tete);
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------------- les tags */

.tags { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.champ__nom--inline { margin-right: 2px; }

/* Une pastille est pleine ; celle qui porte une case a cocher se vide tant
 * qu'elle n'est pas cochee. Un seul etat a distinguer, il se voit sans lire. */
.tag {
  display: inline-flex;
  align-items: center;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: linear-gradient(160deg, var(--teinte-claire), var(--teinte-sombre));
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
}
.tag:has(input), .jour-pastille:has(input) { cursor: pointer; }
.tag input, .jour-pastille input { position: absolute; width: 0; height: 0; opacity: 0; }
.tag:has(input:not(:checked)) {
  background: none;
  border-color: var(--teinte-sombre);
  color: var(--teinte-sombre);
}
.tag:has(input:focus-visible), .jour-pastille:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

.tag--gerer { background: none; border-color: var(--trait); color: var(--encre-2); }

/* Les sept jours d'un rituel : meme case-a-cocher-deguisee-en-pastille que les
 * tags (mecanique partagee ci-dessus), coloree en accent plutot qu'en teinte
 * de tag puisqu'un jour n'a pas de famille de couleur a lui. */
.jours-choix { display: flex; flex-wrap: wrap; gap: 6px; }
.jour-pastille {
  display: grid;
  place-items: center;
  width: 38px;
  height: 34px;
  border-radius: 8px;
  border: 1px solid var(--trait);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--encre-2);
}
.jour-pastille:has(input:checked) { background: var(--accent); border-color: var(--accent); color: var(--accent-encre); }

/* La carte d'un tag porte sa couleur sur la tranche, comme une ligne porte
 * sa priorite : la couleur est le bord, elle ne s'ajoute pas au contenu.
 * Deux classes dans le selecteur, sinon le `border` raccourci de `.carte`,
 * declare plus bas, reprend la main. */
.carte.tag-carte { padding: 10px 12px; border-left: 5px solid var(--teinte-sombre); }
.tag-ligne { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
/* Les champs de l'application font toute la largeur ; sur une ligne de tag ils
 * partagent la leur. */
.tag-ligne input, .tag-ligne select { width: auto; }
.tag-ligne input[type="text"] { flex: 1 1 140px; }

.jauge { height: 5px; border-radius: 999px; background: var(--trait); overflow: hidden; }
.jauge > i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }

/* ------------------------------------------------------------ les curseurs */

/* Deux rangees : le nom et la piste sur la premiere, les crans juste dessous
 * sur la seconde — colles a la piste puisque plus rien d'autre n'y vit. Le
 * jeton, seul assez grand (36px) pour dicter la hauteur d'une rangee, s'etend
 * maintenant sur les deux et se centre sur leur hauteur cumulee plutot que
 * d'ecraser la premiere seule. La colonne du milieu garde sa largeur de
 * telephone meme sur grand ecran : quatre crans se pointent aussi bien en
 * 300 px, et une barre etiree lit mal. */
.curseur {
  display: grid;
  grid-template-columns: 72px 1fr auto;
  grid-template-rows: auto auto;
  column-gap: 8px;
  row-gap: 4px;
  width: 100%;
  max-width: 344px;
}
/* Largeur fixe : sans elle, "Priorite" / "Importance" / "Difficulte" n'ont pas
 * la meme longueur et la barre de chacun des trois curseurs ne demarre pas au
 * meme endroit — les trois doivent avoir la meme tete. */
.curseur__nom { grid-column: 1; grid-row: 1; align-self: center; font-size: 12px; font-weight: 600; white-space: nowrap; }
.curseur__piste { grid-column: 2; grid-row: 1; align-self: center; min-width: 0; }
.curseur__jeton { grid-column: 3; grid-row: 1 / span 2; align-self: center; display: flex; }
.curseur__crans {
  grid-column: 2;
  grid-row: 2;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  font-size: 10px;
  color: var(--encre-2);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

/* `--piste` porte les quatre aplats de la famille ; il vient de jetons.css.
 * Le bouton va d'un bord a l'autre de la piste (jamais du centre d'une bande
 * a l'autre — un `<input type=range>` natif ne sait pas faire ça sans
 * retrecir sa zone cliquable), donc a la valeur 1 il colle le bord gauche
 * plutot que le milieu de la premiere bande. Essaye et defait (chantier
 * quetes, sept. 2026) : la piste inseree a 75% centrait bien le bouton sur
 * chaque bande, mais la marge de 12.5% de chaque cote devenait un angle mort
 * — plus cliquable. Vivre avec le decalage plutot que perdre la zone. */
.curseur__piste { -webkit-appearance: none; appearance: none; width: 100%; height: 14px; background: transparent; margin: 0; cursor: pointer; }
.curseur__piste::-webkit-slider-runnable-track { height: 11px; border-radius: 999px; background: var(--piste); border: 1px solid rgba(0, 0, 0, .12); }
.curseur__piste::-moz-range-track { height: 11px; border-radius: 999px; background: var(--piste); border: 1px solid rgba(0, 0, 0, .12); }
.curseur__piste::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  /* Centre sur la piste : piste 11px + 2x1px de bordure = 13px (hauteur de
   * `.curseur__piste`), bouton 18px + 2x1px de bordure = 20px. (13-20)/2 = -3.5. */
  margin-top: -3.5px;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #ffffff, #d7dde5 62%, #aab3bf);
  border: 1px solid rgba(0, 0, 0, .28);
  box-shadow: 0 2px 5px rgba(0, 0, 0, .3);
}
.curseur__piste::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #ffffff, #d7dde5 62%, #aab3bf);
  border: 1px solid rgba(0, 0, 0, .28);
  box-shadow: 0 2px 5px rgba(0, 0, 0, .3);
}

/* ------------------------------------------------------------- les etapes */

.etapes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.etape {
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--champ);
  border: 1px solid var(--trait);
  border-radius: 8px;
  padding: 6px 9px;
}
.etape .coche { width: 19px; height: 19px; border-radius: 6px; }
.etape .coche::after { left: 2px; top: 3px; width: 9px; height: 4px; }
.etape__titre { flex: 1; min-width: 0; font-size: 14px; overflow-wrap: anywhere; }
.etape--faite .etape__titre { text-decoration: line-through; color: var(--encre-2); }
.etape form { display: flex; }
.etape__retirer {
  border: 0;
  background: none;
  color: var(--encre-2);
  font-size: 17px;
  line-height: 1;
  padding: 2px 4px;
  cursor: pointer;
}

.ajout-etape { display: flex; gap: 8px; }
.ajout-etape input { flex: 1; }

/* --------------------------------------------------------------- la barre */

.barre {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px 0 0;
  border-top: 1px solid var(--trait);
}

/* Un formulaire d'action n'a rien a montrer : il n'existe que pour qu'un
 * bouton pose ailleurs le vise par `form="..."`. Cache, il poste quand meme. */
.action-seule { display: none; }

/* ------------------------------------------------------------- les fiches simples */

/* Les formulaires qui n'ont pas encore leur ecran dedie (epic, rituel, compte)
 * partagent la meme colonne et les memes champs, sans mise en page propre. */
.formulaire { display: flex; flex-direction: column; gap: 14px; }
.formulaire p { margin: 0; display: flex; flex-direction: column; gap: 5px; }
.formulaire label { font-size: 11px; letter-spacing: .11em; text-transform: uppercase; color: var(--encre-2); font-weight: 600; }.formulaire input[type="checkbox"] { width: auto; }
.formulaire ul.errorlist { margin: 0; padding-left: 16px; color: var(--alerte); font-size: 12.5px; }
.formulaire .helptext { font-size: 12px; color: var(--encre-2); }

.seuil { max-width: 26rem; margin: 0 auto; display: flex; flex-direction: column; gap: 12px; }

.carte {
  background: var(--carte);
  border: 1.5px solid var(--trait);
  border-radius: var(--arrondi);
  box-shadow: var(--ombre);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.notes { margin: 0; color: var(--encre-2); font-size: 14px; }
.jours-dus { display: flex; gap: 5px; list-style: none; margin: 0; padding: 0; }
.jours-dus li {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 7px;
  border: 1px solid var(--trait);
  font-size: 11px;
  color: var(--encre-2);
}
.jours-dus li.du { background: var(--accent); border-color: var(--accent); color: var(--accent-encre); font-weight: 600; }

/* ---------------------------------------------------- la feuille des filtres */

/* Un `<details>` plutot qu'une boite modale maison : l'ouverture/fermeture au
 * clic existe deja nativement, il ne reste qu'a l'habiller en feuille qui
 * monte du bas. Zero JavaScript de plus. */
.feuille-filtres { position: relative; }
.feuille-filtres > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  color: var(--encre-2);
  background: var(--carte);
  border: 0;
  border-radius: 999px;
  box-shadow: 0 1px 0 var(--trait);
  padding: 8px 14px;
  position: relative;
}
.feuille-filtres > summary::-webkit-details-marker { display: none; }
.feuille-filtres[open] > summary { color: var(--encre); }

/* Variante icone seule, posee dans l'en-tete : le meme bouton rond que le
 * menu a gauche, la pastille de comptage en debordement plutot qu'en ligne
 * puisqu'il n'y a plus de texte pour l'accueillir. */
.feuille-filtres--icone > summary {
  width: 38px;
  height: 38px;
  padding: 0;
  justify-content: center;
  border-radius: 999px;
  background: transparent;
  border: 1.5px solid var(--trait-fort);
  box-shadow: none;
}
.feuille-filtres--icone[open] > summary { border-color: var(--encre-2); }
.feuille-filtres--icone .tete__pastille { position: absolute; top: -4px; right: -4px; }

.tete__pastille {
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-encre);
  font-size: 10px;
  font-weight: 700;
  display: grid;
  place-items: center;
}

.feuille-filtres__contenu {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 6;
  max-width: var(--colonne);
  margin: 0 auto;
  background: var(--carte);
  border: 1px solid var(--trait);
  border-bottom: 0;
  border-radius: var(--arrondi-grand) var(--arrondi-grand) 0 0;
  box-shadow: 0 -14px 40px -14px rgba(8, 12, 20, .45);
  padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: 80vh;
  overflow-y: auto;
}
.reglage { display: flex; flex-direction: column; gap: 7px; }
.reglage__nom {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--encre-2);
}
.pastilles { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
/* « Gerer les tags » vit dans la meme rangee que les pastilles de tag, en
 * dernier — un renvoi, pas un filtre de plus, donc pas le style pastille. */
.pastilles .renvoi { white-space: nowrap; }
.pastille {
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  color: var(--encre-2);
  background: var(--champ);
  border: 0;
  border-radius: 999px;
  padding: 6px 12px;
  cursor: pointer;
  line-height: 1.2;
}
.pastille[aria-pressed="true"] {
  color: var(--accent-encre);
  background: var(--accent);
}
.feuille-filtres__pied { display: flex; padding-top: 2px; }

/* Le tri, juste sous l'en-tete de la page : ca retombe a la ligne plutot que
 * de defiler — rien n'indique qu'une rangee est scrollable, et cinq criteres
 * tiennent rarement sur un ecran de telephone. */
.tri-rapide { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.tri-rapide .pastille { white-space: nowrap; }

/* La bande des filtres actifs : hauteur nulle des qu'il n'y en a aucun, c'est
 * ce qui permet de la garder toujours au meme endroit. */
.bande { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.bande__pastille {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 11%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  border-radius: 999px;
  padding: 3px 5px 3px 9px;
}
.bande__pastille::after { content: "\00d7"; font-size: 14px; line-height: 1; opacity: .75; }
.bande__tout {
  margin-left: auto;
  font-size: 11.5px;
  color: var(--encre-2);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ----------------------------------------------------- les etages (Quetes) */

.etage { display: flex; flex-direction: column; gap: 7px; }
/* La categorie est un <details> : replier/deplier lui appartient, sans script. */
.etage__tete { display: flex; align-items: center; gap: 9px; list-style: none; cursor: pointer; }
.etage__tete::-webkit-details-marker { display: none; }
.etage__nom {
  font-family: var(--titre);
  font-size: 16px;
  font-weight: 700;
  color: var(--encre-2);
}
.etage__compte {
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--encre-2);
}
.etage[open] .etage__chevron { transform: rotate(135deg); margin-top: -3px; }

/* ----------------------------------------------- le bandeau des trois cadrans */

.bandeau-trois { display: flex; gap: 4px; }
.cadran {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  border-radius: 10px;
  padding: 3px 2px 6px;
  text-decoration: none;
  color: var(--encre-2);
}
.cadran:hover { background: var(--creux); }
.cadran__nom { font-size: 9.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; }
.cadran__anneau {
  --part: 0%;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: conic-gradient(var(--accent) var(--part), var(--trait) 0);
}
.cadran__anneau > span {
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: var(--carte);
  display: grid;
  place-items: center;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--encre);
}
.cadran__anneau--tenu > span { color: var(--accent); }

/* Le solde des habitudes est une balance, pas une fraction : un disque plein
 * et un signe, jamais un anneau qui se remplit. */
.cadran__disque {
  width: 40px;
  height: 40px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  border: 1px solid transparent;
}
.cadran__disque--bon { background: var(--accent-pale); border: 0; color: var(--accent-sombre); }
.cadran__disque--mauvais { background: var(--alerte-pale); color: var(--alerte); }

/* ---------------------------------------------- la semaine d'un rituel */

/* Sept lettres, l'etat se voit sans lire — partagee par les rituels hebdo (la
 * coche marque le jour precis) et par la fiche d'un quotidien. */
.semaine { display: flex; gap: 3px; }
.semaine i {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  display: grid;
  place-items: center;
  font-size: 9.5px;
  font-style: normal;
  font-weight: 700;
  border: 0;
  color: var(--encre-2);
  background: var(--creux);
}
.semaine .j--tenu { background: var(--accent); color: var(--accent-encre); }
.semaine .j--du { border: 1.5px solid var(--accent); background: transparent; color: var(--accent); }

/* La semaine d'un hebdo passe sous le titre, comme une echeance de quete. */
.ligne--hebdo .ligne__titre { flex-basis: 100%; }

/* ---------------------------------------------------- la flamme (streak) */

.flamme { position: relative; width: 21px; height: 25px; flex: none; display: inline-grid; place-items: center; }
.flamme svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.flamme b {
  position: relative;
  font-size: 9.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.03em;
  color: #fff;
  padding-top: 7px;
  text-shadow: 0 1px 1px rgba(120, 40, 6, .55);
}
.flamme--longue b { font-size: 8px; }

/* --------------------------------------------------- le compteur libre */

.compteur { display: inline-flex; align-items: center; gap: 2px; flex: none; }
.compteur button {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  border: 0;
  background: var(--creux);
  color: var(--encre-2);
  font: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
.compteur output {
  min-width: 24px;
  text-align: center;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------- une habitude */

.sens { font-size: 11px; color: var(--encre-2); white-space: nowrap; }
.solde {
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  border-radius: 999px;
  padding: 1px 8px;
  border: 1px solid transparent;
}
.solde--bon { background: var(--accent-pale); border: 0; color: var(--accent-sombre); }
.solde--mauvais { background: var(--alerte-pale); color: var(--alerte); }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
