/* Mi | NU Space — regles propres a l'univers Space.
 *
 * Cette feuille se charge APRES roots-tokens.css et roots.css et ne fait que
 * les consommer : elle ne declare aucune valeur litterale, aucune couleur,
 * aucune taille. Toute valeur vient d'un jeton. Les deux seules proprietes
 * personnalisees qu'elle introduit sont des alias de ROLE — elles pointent
 * vers un echelon existant et n'en creent aucun.
 *
 * Ce qu'elle exige : les jetons de rampe d'air --air-i1, i2, i3, i6, i8 — un
 * cran hors de cette rampe casse le rythme vertical de l'interface — et les
 * trois roles du gris, qui ne se confondent pas : --gris-aplat pour une
 * surface, --gris-filet pour un separateur, --limite-controle pour ce qui
 * identifie un controle. Seul le troisieme releve du seuil de 3:1.
 *
 * Ce qu'elle refuse : l'or en encre et l'or en filet. Sur un fond clair, aucun
 * echelon de la famille jaune n'atteint 3:1 — un aplat jaune ne se detache pas
 * de la page. L'or ne porte donc que du texte a l'interieur d'un aplat, et cet
 * aplat porte un filet d'une famille qui, elle, se detache.
 *
 * Ce qui casserait si on le modifiait : sans son trait, l'aplat de la section
 * financiere ne se distingue plus du fond de page ; remplacer l'encre des aplats
 * noirs par autre chose que --blanc ferait tomber le contraste sous AA.
 */

/* ---- Univers -------------------------------------------------------------
 * --univers pilote deja, dans le tronc commun, les aplats de bouton, les
 * bordures de champ actives, le trait du chrome et l'element actif du menu.
 * L'univers Space le porte au noir ; l'encre du corps reste noire elle aussi,
 * et le fond de page reste clair.
 */
:where(body.p-space){
  --univers: var(--roots-noir);
  --univers-e1: var(--roots-noir);
  --univers-e3: var(--terre-e3);
  --univers-e5: var(--gris-ilot);
  --univers-e1-rgb: var(--noir-rgb);
  --univers-e3-rgb: var(--terre-e3-rgb);
  --univers-rgb: var(--noir-rgb);
  --encre: var(--roots-noir);
  --accent-plan: var(--terre-e3);
  /* L'ombre et les voiles suivent l'encre profonde de l'univers : une piece
     partagee ne garde jamais la teinte d'un autre univers. Les encres de la
     lecture longue suivent l'echelon 3 de l'univers pour la meme raison. */
  --ombre-teinte: var(--noir-rgb);
  --univers-e4: var(--terre-e4);
  --encre-ll-h1: var(--encre);
  --encre-ll-h3: var(--encre);
  --encre-ll-h5: var(--encre);
  --encre-ll-h2: var(--univers-e3);
  --encre-ll-h4: var(--univers-e3);
  --encre-ll-h6: var(--univers-e3);
  --encre-ll-chapo: var(--univers-e3);
  /* Les liens de la lecture longue portent l'ACCENT de l'univers, pas son
     noir : un lien noir sur encre noire ne se distingue plus. */
  --lien-lecture: var(--univers-e3);
}
:where(body.p-space) .lecture a{color:var(--univers-e3)}

/* ---- En-tete de l'ecran --------------------------------------------------
 * Aplat noir, encre blanche. Mesure sur les jetons : 17,40 — AAA.
 */
/* La page de module n'a pas de carte noire d'en-tete : le cadre de la
   semaine se dit sur une ligne discrete, et le titre appartient au chrome. */
/* La plage de dates est le titre de la page ; la note qui la suit tient sa
   ligne juste dessous, sans l'air d'un bloc separe — les deux se lisent d'un
   trait. */
:where(body.p-space) .titre-semaine{ margin: 0 0 var(--esp-1) }
:where(body.p-space) .cadre-semaine{
  margin: 0 0 var(--air-i3);
  color: var(--encre-discrete);
  font-size: var(--t-sm);
  line-height: var(--lh-14);
}
/* Une commande qui ne peut rien garder se montre eteinte et le dit : la
   mention vit sous la rangee qu'elle explique, a l'encre discrete. L'aplat
   eteint est celui du socle, repris a ses jetons — jamais redessine. */
:where(body.p-space) .mention-inerte{
  width: 100%; max-width: var(--col);
  margin: 0 0 var(--esp-2);
  font-size: var(--t-12);
  line-height: var(--lh-12);
  color: var(--encre-discrete);
}
:where(body.p-space) .jour:disabled{
  background: var(--eteint-fond);
  border-color: var(--eteint-fond);
  color: var(--eteint-encre);
  cursor: not-allowed;
}
:where(body.p-space) .entete-plan{
  background: var(--univers);
  border-radius: var(--rayon-carte);
  padding: var(--esp-6);
  margin: 0 0 var(--air-i4);
  text-align: left;
}
:where(body.p-space) .entete-plan h1{
  margin: 0 0 var(--air-i2);
  color: var(--blanc);
  font-size: var(--t-h2);
  line-height: var(--lh-28);
}
:where(body.p-space) .entete-plan .sous-titre{
  margin: 0;
  color: var(--blanc);
  font-size: var(--t-sm);
  line-height: var(--lh-14);
}

/* ---- Blocs --------------------------------------------------------------- */
:where(body.p-space) .bloc-plan{ margin: 0 0 var(--air-i6) }
:where(body.p-space) .bloc-plan > .etiquette{ display: block }

/* ---- Poseur d'engagement -------------------------------------------------
 * Trois gestes : ecrire, choisir un jour, ajouter. Le jour est facultatif —
 * un engagement sans jour appartient a la semaine, pas a un jour.
 */
:where(body.p-space) .jours{
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-2);
  margin: var(--air-i2) 0 var(--air-i3);
}
:where(body.p-space) .jour{
  min-width: var(--cible-min);
  min-height: var(--cible-min);
  padding: 0 var(--esp-3);
  background: var(--gris-aplat);
  /* L'aplat clair de la pastille ne se detache pas du papier : il rend 1,31
     contre lui, sous le plancher de 3 exige d'une frontiere de commande. Le
     lisere de controle porte donc la frontiere, et l'etat retenu ne fait que
     lui changer d'encre — la boite ne bouge d'aucun pixel entre les deux. */
  border: var(--limite-ep) solid var(--limite-controle);
  border-radius: var(--rayon-champ);
  font-family: var(--font-corps);
  font-size: var(--t-sm);
  line-height: var(--lh-14);
  font-weight: var(--w-bold);
  color: var(--encre);
  cursor: pointer;
}
:where(body.p-space) .jour[aria-pressed="true"]{
  background: var(--univers);
  border-color: var(--univers);
  color: var(--blanc);
}

/* ---- Liste de la semaine -------------------------------------------------
 * Un groupe par jour, plus un groupe pour ce qui n'a pas de jour. Un groupe
 * vide ne se rend pas : une case vide n'informe de rien.
 */
:where(body.p-space) .groupe-jour{ margin: 0 0 var(--air-i4) }
:where(body.p-space) .groupe-jour > .etiquette{ margin-bottom: var(--air-i2) }
/* Une liste de taches est UNE surface : les lignes s'y empilent, separees
   d'un filet, au lieu de porter chacune sa propre carte — une carte par
   ligne epaissit chaque ligne et pousse le module hors de l'ecran. Sur la
   page, la ligne tient le plancher tactile ; dans l'apercu du hall elle
   descend d'un cran d'air sous lui, et reste pleine largeur. */
:where(body.p-space) .taches{
  display: block; margin: 0; padding: 0; list-style: none;
  background: var(--blanc);
  border: var(--limite-ep) solid var(--gris-filet);
  border-radius: var(--rayon-module);
  overflow: hidden;
}
:where(body.p-space) .taches > li + li{
  border-top: var(--limite-ep) solid var(--gris-filet);
}
/* Une tache tient une ou deux lignes, jamais plus : le champ borne les
   signes a ce que deux lignes portent au plus etroit, et le clamp du texte
   est la barriere de rendu. La ligne s'aligne en tete pour que la case et la
   mention tiennent la PREMIERE ligne quand il y en a deux ; l'air vertical se
   derive de l'interligne pour que la ligne simple garde son plancher. */
:where(body.p-space) .tache{
  display: flex;
  align-items: flex-start;
  gap: var(--esp-3);
  width: 100%;
  min-height: var(--cible-min);
  padding: calc((var(--cible-min) - 1em * var(--lh-16)) / 2) var(--esp-4);
  text-align: left;
  background: none;
  border: 0;
  font-family: var(--font-corps);
  font-size: var(--t-body);
  line-height: var(--lh-16);
  color: var(--encre);
  cursor: pointer;
}
:where(body.p-space) .tache:focus-visible{
  box-shadow: inset 0 0 0 var(--limite-ep) var(--univers);
}

/* La case est un aplat, pas une icone du sprite commun : son bord porte
 * l'information, donc il se detache du blanc de la carte.
 */
:where(body.p-space) .tache .case{
  flex: 0 0 auto;
  width: var(--esp-6);
  height: var(--esp-6);
  margin-top: calc((1em * var(--lh-16) - var(--esp-6)) / 2);
  border: var(--limite-ep) solid var(--univers);
  border-radius: var(--rayon-champ);
  background: var(--blanc);
  display: flex;
  align-items: center;
  justify-content: center;
}
:where(body.p-space) .tache .case svg{ width: var(--esp-4); height: var(--esp-4); display: none }
:where(body.p-space) .tache[aria-pressed="true"] .case{ background: var(--univers) }
:where(body.p-space) .tache[aria-pressed="true"] .case svg{ display: block; color: var(--blanc) }
:where(body.p-space) .tache[aria-pressed="true"] .engagement{
  color: var(--encre-discrete); text-decoration: line-through;
}
:where(body.p-space) .engagement{
  flex: 1 1 auto;
  /* Un element flexible refuse par defaut de descendre sous la largeur de son
     mot le plus long : sans cette remise a zero, la ligne pousse la liste, la
     liste pousse son bloc, et la page defile en travers. La coupe et le
     rognage ci-dessous n'entrent en jeu qu'une fois cette remise faite. */
  min-width: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* L'echeance de la ligne : a droite, chiffres de tableau, encre discrete —
   la grammaire fil-heure du hall. Elle se centre sur la premiere ligne du
   texte, jamais sur la boite ; la cloche dit l'alarme tenue, a l'accent. */
:where(body.p-space) .tache .mention{
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: calc(var(--esp-1) / 2);
  font-size: var(--t-12);
  line-height: var(--lh-12);
  font-variant-numeric: tabular-nums;
  color: var(--encre-discrete);
  margin-top: calc((1rem * var(--lh-16) - var(--t-12) * var(--lh-12)) / 2);
}
:where(body.p-space) .tache .mention svg{
  width: var(--t-12); height: var(--t-12); color: var(--accent-plan);
}

/* Le repli des faites : une commande discrete entre les deux listes d'un
   jour — le compte dans le mot, l'etat dans le chevron qui suit, pointe en
   bas replie, en haut deplie. Le mot tient le rail des etiquettes ; la cible
   tient le plancher tactile. Le chevron se recale d'un demi-cran : sa pointe
   vit sous son centre de boite quand il pointe en bas, au-dessus quand il
   pointe en haut. */
:where(body.p-space) .repli-faites{
  display: inline-flex; align-items: center; gap: var(--esp-2);
  min-height: var(--cible-min);
  margin-top: var(--esp-1);
  border: 0; background: none; padding: 0;
  font-family: var(--font-corps); font-size: var(--t-14);
  color: var(--encre-discrete);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
:where(body.p-space) .repli-faites::after{
  content: '';
  width: var(--esp-2); height: var(--esp-2);
  margin-top: calc(var(--esp-1) / -2);
  border-right: var(--limite-ep) solid currentColor;
  border-bottom: var(--limite-ep) solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--mvt-etat) var(--courbe-etat);
}
:where(body.p-space) .repli-faites[aria-expanded="true"]::after{
  margin-top: calc(var(--esp-1) / 2);
  transform: rotate(225deg);
}
:where(body.p-space) .repli-faites + .taches{ margin-top: var(--esp-1) }

/* ---- Progression ---------------------------------------------------------
 * La jauge informe par sa longueur, donc son aplat se detache du fond de sa
 * gouttiere. Le nombre est ecrit a cote : la couleur ne dit jamais seule.
 */
:where(body.p-space) .jauge{
  height: var(--esp-3);
  background: var(--gris-aplat);
  border-radius: var(--rayon-pilule);
  overflow: hidden;
  margin: var(--air-i2) 0;
}
:where(body.p-space) .jauge .part{
  height: 100%;
  background: var(--univers);
  border-radius: var(--rayon-pilule);
}
:where(body.p-space) .compte{
  font-family: var(--font-chiffres);
  font-size: var(--t-h4);
  line-height: var(--lh-21);
  font-weight: var(--w-bold);
  color: var(--encre);
}
:where(body.p-space) .compte-dit{
  display: block;
  margin-top: var(--air-i1);
  font-size: var(--t-sm);
  line-height: var(--lh-14);
  color: var(--encre-discrete);
}

/* ---- Accent -------------------------------------------------------------
 * Le terracotta atteint 4,56 en encre sur fond clair : il porte un mot, une
 * mention, un geste. Il ne porte pas un paragraphe de lecture longue, qui
 * demande AAA.
 */
:where(body.p-space) .accent{ color: var(--accent-plan); font-weight: var(--w-bold) }

/* ---- Etat vide ----------------------------------------------------------- */
:where(body.p-space) .vide{
  padding: var(--esp-6);
  background: var(--gris-aplat);
  border-radius: var(--rayon-module);
  font-size: var(--t-sm);
  line-height: var(--lh-14);
  color: var(--encre-discrete);
}


/* ---- La place vide d'un montant -----------------------------------------
 * Une absence n'emprunte pas la voix d'un chiffre : elle se dit au corps et
 * a l'encre de la prose, sans la graisse ni la chasse des chiffres, qui
 * feraient crier une phrase de quatre mots.
 */
:where(body.p-space) .montant.sans{
  font-family: var(--font-corps);
  font-size: var(--t-body);
  line-height: var(--lh-16);
  font-weight: var(--w-medium);
}

/* ==========================================================================
   PAGE D'ENTREE — LA PREMIERE COCHE
   --------------------------------------------------------------------------
   Une scene, une seule tache : la cocher revele l'acte. La revelation tient a
   la relation de voisinage entre la case et le bloc qui suit — sortir l'un de
   la section la casse. L'air vertical vient de la rampe --air-i*, les tailles
   de la suite typographique, le mouvement des jetons de mouvement.
   ========================================================================== */

:where(body.p-space) .coche-scene{
  min-height: calc(100svh - var(--entete-h-rendue, 64px) - var(--chrome-bas-h, 80px));
  display: grid; align-content: center; justify-items: center;
  gap: var(--air-i4); text-align: center;
  padding-block: var(--air-i6);
}
:where(body.p-space) .coche-scene h1{
  font-family: var(--font-eclat); font-weight: var(--w-a-display);
  font-size: var(--t-h3);
}
:where(body.p-space) #premiereCoche{ position: absolute; opacity: 0 }
:where(body.p-space) .coche-tache{
  display: flex; align-items: center; gap: var(--esp-6); text-align: left;
  background: var(--blanc); border-radius: var(--rayon-carte);
  padding: var(--esp-6) var(--esp-8);
  box-shadow: 0 18px 44px rgba(var(--ombre-teinte), .14);
  cursor: pointer; max-width: 560px; width: 100%;
}
:where(body.p-space) .coche-case{
  width: var(--cible-min); height: var(--cible-min); flex: none;
  border-radius: var(--rayon-pilule); border: 3px solid var(--univers);
  display: grid; place-items: center; position: relative;
  transition: background-color var(--mvt-etat) var(--courbe-etat);
}
:where(body.p-space) .coche-case::after{
  content: ""; position: absolute; inset: calc(-1 * var(--esp-2));
  border-radius: var(--rayon-pilule); border: 2px solid var(--accent-plan);
  opacity: .6;
}
:where(body.p-space) .coche-case svg{
  width: var(--esp-6); height: var(--esp-6); color: var(--blanc); opacity: 0;
}
:where(body.p-space) .coche-mot{
  font-family: var(--font-eclat); font-weight: var(--w-bold);
  font-size: var(--t-h3);
}
/* La case est le MANDATAIRE visible d'une commande retiree de la vue : le
   foyer se poserait sur une boite d'un pixel que personne ne voit. La regle
   du socle est donc reportee ici telle quelle, sur le mandataire, et sans
   rien y ajouter — l'aplat de l'univers, et le lisere de son encre. Cochee,
   la case porte deja l'aplat : c'est le lisere qui parle. */
:where(body.p-space) #premiereCoche:focus-visible ~ .coche-tache .coche-case{
  background-color: var(--foyer-fond);
  box-shadow: inset 0 0 0 var(--foyer-lisere) var(--foyer-encre);
}
:where(body.p-space) #premiereCoche:checked ~ .coche-tache .coche-case{ background: var(--univers) }
:where(body.p-space) #premiereCoche:checked ~ .coche-tache .coche-case::after{ opacity: 0 }
:where(body.p-space) #premiereCoche:checked ~ .coche-tache .coche-case svg{ opacity: 1 }
:where(body.p-space) #premiereCoche:checked ~ .coche-tache .coche-mot{
  text-decoration: line-through; text-decoration-thickness: 3px;
  color: var(--encre-discrete);
}
:where(body.p-space) .coche-fait{ font-size: var(--t-14); font-weight: var(--w-bold) }
:where(body.p-space) .coche-apres{
  visibility: hidden; opacity: 0; transform: translateY(var(--esp-2));
  transition: opacity var(--mvt-apparition) var(--courbe-etat),
              transform var(--mvt-apparition) var(--courbe-etat),
              visibility 0s var(--mvt-apparition);
}
:where(body.p-space) #premiereCoche:checked ~ .coche-apres{
  visibility: visible; opacity: 1; transform: none; transition-delay: 0s;
}

:where(body.p-space) .entree-acte{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: var(--cible-min);
  box-sizing: border-box;
  padding: var(--esp-3) var(--esp-4);
  background: var(--univers);
  color: var(--blanc);
  border-radius: var(--rayon-pilule);
  font-family: var(--font-eclat);
  font-weight: var(--w-bold);
  font-size: var(--t-h4);
  text-decoration: none;
}

/* ---- L'inscription en taches ---------------------------------------------
 * La cascade suit la premiere coche : une etape par carte, la pastille se
 * remplit quand l'etape est faite. Le bouton en contour est le geste sur
 * place ; le seul bouton plein de l'ecran reste l'acte final.
 */
:where(body.p-space) [hidden]{ display: none !important }
:where(body.p-space) .coche-liste{
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--air-i3);
  width: 100%; max-width: 560px; text-align: left;
}
:where(body.p-space) .coche-etape{
  display: grid; grid-template-columns: auto 1fr; gap: var(--esp-4);
  align-items: start;
  background: var(--blanc); border-radius: var(--rayon-carte);
  padding: var(--esp-4) var(--esp-6);
  box-shadow: 0 18px 44px rgba(var(--ombre-teinte), .10);
}
:where(body.p-space) .coche-pastille{
  width: var(--esp-8); height: var(--esp-8); flex: none;
  border-radius: var(--rayon-pilule); border: var(--limite-ep) solid var(--univers);
  display: grid; place-items: center;
  transition: background-color var(--mvt-etat) var(--courbe-etat);
}
:where(body.p-space) .coche-pastille svg{ width: var(--esp-4); height: var(--esp-4); color: var(--blanc); opacity: 0 }
:where(body.p-space) .coche-etape.faite .coche-pastille{ background: var(--univers) }
:where(body.p-space) .coche-etape.faite .coche-pastille svg{ opacity: 1 }
:where(body.p-space) .coche-etape.faite .coche-titre{ color: var(--encre-discrete) }
:where(body.p-space) .coche-corps{ display: grid; gap: var(--air-i2); min-width: 0 }
:where(body.p-space) .coche-titre{ font-family: var(--font-eclat); font-weight: var(--w-bold); font-size: var(--t-h4) }
:where(body.p-space) .coche-champ{ display: flex; flex-wrap: wrap; gap: var(--esp-2) }
:where(body.p-space) .chercher{ margin-bottom: var(--air-i3) }
:where(body.p-space) .chercher input,
:where(body.p-space) .coche-champ input{
  flex: 1 1 12ch; min-width: 0; min-height: var(--cible-min);
  border: var(--limite-ep) solid var(--limite-controle); border-radius: var(--rayon-champ);
  background: var(--blanc); color: var(--encre);
  padding-inline: var(--esp-3); font: inherit; font-size: var(--t-body);
}
:where(body.p-space) .bouton-contour{
  min-height: var(--cible-min); padding-inline: var(--esp-4);
  border: var(--limite-ep) solid var(--univers); border-radius: var(--rayon-pilule);
  background: none; color: var(--univers);
  font-family: var(--font-eclat); font-weight: var(--w-bold); font-size: var(--t-16);
  cursor: pointer;
}
:where(body.p-space) .bouton-contour[disabled]{ opacity: .45; cursor: default }
:where(body.p-space) .coche-note{ font-size: var(--t-14); color: var(--encre-discrete) }
:where(body.p-space) .etat-semaine{ font-size: var(--t-14); color: var(--encre-discrete); margin-block: var(--air-i2) }

@media (prefers-reduced-motion: reduce){
  :where(body.p-space) .coche-case,
  :where(body.p-space) .coche-pastille,
  :where(body.p-space) .coche-apres{ transition: none }
}

@media (min-width: 1024px){
  :where(body.p-space) .coche-scene h1{ font-size: var(--t-h2) }
  :where(body.p-space) .coche-tache{ max-width: 680px; padding: var(--esp-8); gap: var(--esp-8) }
  :where(body.p-space) .coche-mot{ font-size: var(--t-h2) }
  :where(body.p-space) .coche-liste{ max-width: 680px }
}

/* ---- Le hall -------------------------------------------------------------
   L'accueil de l'univers : chaque module dans son propre bloc, la pile sur
   petit ecran, deux colonnes des que la place le permet. Les modules non
   ouverts se montrent muets, sans lien. */
:where(body.p-space) .hall{ display: grid; gap: var(--air-i4) }
:where(body.p-space) .hall-bloc{
  background: var(--blanc); border-radius: var(--rayon-carte);
  padding: var(--esp-6);
  box-shadow: 0 18px 44px rgba(var(--ombre-teinte), .14);
  display: grid; gap: var(--air-i3); align-content: start;
}
:where(body.p-space) .hall-tete{
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--esp-3);
}
/* Dans une tete de module, l'air vient de la carte, jamais de la marge du
   titre : sans cela le toit s'ecarte d'un cran de plus que les trois autres
   cotes, et le module qui porte un titre de rang 1 le fait differemment des
   autres. */
:where(body.p-space) .hall-tete :is(h1, h2, h3){ margin: 0 }
/* Ouvrir un module : le lien vit sur SON TITRE, et son extension couvre la
   carte entiere — la carte s'ouvre donc partout ou l'on tape, sans que le
   module devienne un seul nom verbeux pour qui l'ecoute. Ce qui est deja une
   commande a l'interieur repasse au-dessus par son propre plan. */
:where(body.p-space) .lien-module{
  color: inherit; text-decoration: none;
}
:where(body.p-space) .lien-module::after{
  content: ''; position: absolute; inset: 0;
}
/* Le signe a droite du nom : un chevron, qui dit que la carte mene quelque
   part. Il ne porte aucun geste — le titre le porte — sauf sur le module en
   vedette, ou cette place revient au geste d'ajout rapide. */
:where(body.p-space) .ouvre-module{
  flex: none; margin-left: auto;
  min-width: var(--cible-min); height: var(--cible-min);
  color: var(--accent-plan); text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center;
}
:where(body.p-space) .ouvre-module svg{ width: 22px; height: 22px }
:where(body.p-space) .ouvre-module.est-geste{
  position: relative;
  border-radius: 50%; border: 1.5px solid currentColor;
}
:where(body.p-space) .hall-bloc{ position: relative }
/* Ce qui est deja une commande dans la carte repasse au-dessus de
   l'extension. Le lien du module en est exclu : c'est LUI qui porte
   l'extension, et se poser lui-meme l'ancrerait sur son seul titre. */
:where(body.p-space) .hall-bloc :is(button, input, textarea, a:not(.ouvre-module, .lien-module)){
  position: relative;
}
/* La carte du module est un aplat, pas un aplat qui saute : le survol dit
   qu'elle mene quelque part, sans mouvement. */
@media (hover: hover){
  :where(body.p-space) .hall-bloc:has(.lien-module:hover) .ouvre-module{
    transform: translateX(2px);
  }
}

/* LE FIL A SOI, dans le hall. Une note par ligne, coupee net ; le jour se
   dit une fois, en tete de ses lignes ; l'heure se tient a droite, en
   chiffres de meme chasse pour que la colonne reste droite. C'est ce qui
   distingue un fil d'une liste : on y relit sa propre journee. */
:where(body.p-space) .hall-lignes{
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 0;
}
/* La ligne est une case de grille : sans plancher de largeur remis a zero,
   elle ne descend pas sous la largeur de son texte et pousse la carte hors de
   l'ecran. Le `min-width` du texte seul n'y suffit pas — il faut celui de la
   case qui le contient. */
:where(body.p-space) .hall-ligne{
  display: flex; align-items: baseline; gap: var(--esp-3); min-width: 0;
  padding-block: var(--esp-1);
  font-size: var(--t-sm); line-height: var(--lh-14); color: var(--encre);
}
:where(body.p-space) .hall-ligne + .hall-ligne{
  border-top: 1px solid var(--gris-service);
}
:where(body.p-space) .fil-dit{
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: inherit; text-decoration: none;
}
:where(body.p-space) .fil-compte{
  flex: none; color: var(--encre-discrete);
  font-size: var(--t-note); font-variant-numeric: tabular-nums;
}
:where(body.p-space) .fil-heure{
  flex: none; color: var(--encre-discrete);
  font-size: var(--t-note); font-variant-numeric: tabular-nums;
}
:where(body.p-space) .fil-jour{
  font-size: var(--t-note); font-weight: var(--w-bold);
  letter-spacing: var(--lettrage-capitales-petites); text-transform: uppercase;
  color: var(--encre-discrete);
  padding-top: var(--air-i2); padding-bottom: var(--air-i1);
}

/* Un module sans contenu porte sa carte et son nom, rien de plus : sa
   hauteur suit ce qu'il affiche, comme celle de tout autre module. */
:where(body.p-space) .hall-bloc.dort{
  box-shadow: 0 6px 18px rgba(var(--ombre-teinte), .10);
  padding-block: var(--esp-4);
}
:where(body.p-space) .hall-bloc.dort .hall-tete{
  flex-wrap: nowrap; align-items: center; gap: var(--esp-4);
}
:where(body.p-space) .hall-bloc.dort h2{
  min-width: 0; text-wrap: nowrap;
}
:where(body.p-space) .hall-bloc.dort h2{ color: var(--encre-discrete) }
:where(body.p-space) .bientot{
  font-size: var(--t-12); font-weight: var(--w-bold);
  letter-spacing: .08em; text-transform: uppercase; color: var(--encre-discrete);
  white-space: nowrap;
}

/* Des que la place le permet, les quatre premiers modules forment un carre
   sur deux colonnes — l'ordre du balisage suffit a les y poser — et le
   cinquieme prend la largeur entiere sous eux. Les hauteurs ne sont pas
   egalisees : chaque module tient la sienne, celle de ce qu'il a a dire. */
/* Chaque colonne coule pour elle seule : un module suit celui du dessus a
   la meme gouttiere que celle qui separe les deux colonnes. Sous le seuil,
   les colonnes s'effacent et les modules reprennent l'ordre de lecture. */
:where(body.p-space) .hall-col{ display: contents }
@media (max-width: 767.98px){
  :where(body.p-space) .hall-col:first-of-type > :first-child{ order: 1 }
  :where(body.p-space) .hall-col:last-of-type > :first-child{ order: 2 }
  :where(body.p-space) .hall-col:first-of-type > :last-child{ order: 3 }
  :where(body.p-space) .hall-col:last-of-type > :last-child{ order: 4 }
  :where(body.p-space) .hall-bloc.large{ order: 5 }
}
@media (min-width: 768px){
  :where(body.p-space) .hall{ grid-template-columns: 1fr 1fr }
  /* Les deux colonnes prennent la meme hauteur, et le module du bas occupe
     ce que celui du haut laisse : les quatre bords exterieurs se ferment,
     et la masse du bas est l'inverse de celle du haut. */
  :where(body.p-space) .hall-col{
    display: grid; grid-template-rows: auto 1fr; gap: var(--air-i4);
  }
  :where(body.p-space) .hall-bloc.large{ grid-column: 1 / -1 }
}

/* ---- Cartes de note ------------------------------------------------------
   La carte de note sert le fil, le mur et l'apercu du hall. Le contenu ne
   porte que trois formes : la note, la liste a cocher, le lien. */
:where(body.p-space) .note-carte{
  background: var(--blanc); border-radius: var(--rayon-module);
  padding: var(--esp-4);
  box-shadow: 0 6px 18px rgba(var(--ombre-teinte), .10);
  display: grid; gap: var(--air-i2);
}
/* Le rythme interne est celui de la grille : le paragraphe rend sa marge de
   navigateur, sans quoi le toit de la premiere ligne ne se mesure pas. */
:where(body.p-space) .note-carte p{ margin-block: 0; line-height: 1.5; overflow-wrap: anywhere }
:where(body.p-space) .note-carte .note-titre{ font-weight: var(--w-bold) }
:where(body.p-space) .hall-bloc .note-carte{
  box-shadow: none; border: 1px solid var(--terre-e5);
  padding: var(--esp-3); gap: 0;
}
/* Dans un apercu, une note se reconnait, elle ne se lit pas : deux lignes
   suffisent a la reconnaitre, et la carte garde une hauteur previsible. */
:where(body.p-space) .hall-bloc .note-carte p:not(.note-quand){
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
:where(body.p-space) .hall-bloc .note-rang{ margin-top: var(--air-i1) }
/* Dans le hall, une tache tient sur sa ligne et la ligne s'abaisse d'un
   demi-cran d'air : le module se lit d'un regard, la liste entiere vit sur
   son ecran. */
:where(body.p-space) .hall-bloc .tache{
  min-height: calc(var(--cible-min) - var(--esp-1));
  padding-block: calc((var(--cible-min) - var(--esp-1) - 1em * var(--lh-16)) / 2);
}
/* Dans un module d'accueil, une tache tient UNE ligne et se coupe au point de
   suspension : le module montre quatre lignes, et une tache qui en prend deux
   en retire une autre. L'etage-sujet d'une page de module est exclu : la page
   est la vue detaillee, ou la tache dispose de ses deux lignes. */
:where(body.p-space) .hall-bloc:not(.bande-journee) .tache .engagement{
  display: block; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
:where(body.p-space) .note-carte.tenue{ border: var(--limite-ep) solid var(--terre-e5) }
:where(body.p-space) .note-rang{
  display: flex; align-items: center; justify-content: flex-end;
  gap: var(--esp-3); flex-wrap: wrap;
}
:where(body.p-space) .note-rang .note-quand{ margin-right: auto }
:where(body.p-space) .note-quand{ font-size: var(--t-12); color: var(--encre-discrete) }
:where(body.p-space) .bouton-doux{
  border: var(--limite-ep) solid var(--limite-controle); color: var(--encre);
  background: none; border-radius: var(--rayon-pilule);
  min-height: calc(var(--cible-min) - var(--esp-2));
  padding-inline: var(--esp-4); font-size: var(--t-14); cursor: pointer;
}
:where(body.p-space) .bouton-doux.tenu{
  border-color: var(--accent-plan); color: var(--accent-plan);
  font-weight: var(--w-bold);
}
:where(body.p-space) .bouton-doux.arme{
  border-color: var(--accent-plan); color: var(--blanc);
  background: var(--accent-plan); font-weight: var(--w-bold);
}
:where(body.p-space) .note-item{
  display: flex; gap: var(--esp-3); align-items: center;
  min-height: calc(var(--cible-min) / 2 + var(--esp-1));
  border: 0; background: none; padding: 0; font: inherit; color: inherit;
  text-align: left; cursor: pointer;
}
:where(body.p-space) .note-case{
  width: 22px; height: 22px; flex: none;
  border: var(--limite-ep) solid var(--encre); border-radius: 6px;
  display: grid; place-items: center; color: var(--blanc);
}
:where(body.p-space) .note-case svg{ width: 14px; height: 14px; opacity: 0 }
:where(body.p-space) .note-item.fait .note-case{ background: var(--encre) }
:where(body.p-space) .note-item.fait .note-case svg{ opacity: 1 }
:where(body.p-space) .note-item.fait span:last-child{
  text-decoration: line-through; color: var(--encre-discrete);
}
:where(body.p-space) .coches{ display: grid; gap: var(--air-i1) }
:where(body.p-space) .note-lien{
  display: flex; gap: var(--esp-3); align-items: center;
  color: inherit; text-decoration: none;
}
:where(body.p-space) .note-lien-pic{
  width: var(--cible-min); height: var(--cible-min); flex: none;
  border-radius: var(--rayon-champ);
  background: var(--terre-e5); color: var(--terre-e2);
  display: grid; place-items: center; font-weight: var(--w-bold);
}
:where(body.p-space) .note-lien-quoi{ font-weight: var(--w-bold) }
:where(body.p-space) .note-lien-ou,
:where(body.p-space) .note-lien-mot{
  font-size: var(--t-12); color: var(--encre-discrete); overflow-wrap: anywhere;
}

/* ---- L'ecran des notes ---------------------------------------------------
   Le fil ecrit vers le bas, la saisie collee au bas de l'ecran ; le mur
   range en colonnes. Une seule vue se montre a la fois. */
/* La page d'un module ne porte plus de titre : son nom prend la place du mot
   d'univers dans la barre. Les vues ouvrent donc l'ecran, sur une seule ligne
   de la largeur de la page, comme la ligne de filtres du Savoir. */


:where(body.p-space) .fil-jour{
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: var(--esp-4); margin-top: var(--air-i3);
}
:where(body.p-space) .fil-jour::before,
:where(body.p-space) .fil-jour::after{
  content: ""; height: 1px; background: var(--terre-e5);
}
:where(body.p-space) .fil-jour span{
  font-size: var(--t-12); font-weight: var(--w-bold);
  letter-spacing: .08em; text-transform: uppercase; color: var(--encre-discrete);
}
/* Trois etats de la vue Mur et du composeur. La reprise se dit au-dessus du
   champ, avec de quoi en sortir. Le rattrapage prend la place exacte de la note
   retiree, le temps d'un delai. La note designee est celle qu'on vient
   d'ouvrir depuis le hall : elle s'eclaire un instant, sans rien deplacer. */
/* Les gestes d'une carte sont des pastilles a glyphe : le dessin recule
   d'un cran d'air sous le plancher tactile, la zone atteinte le tient par
   extension. Ce qui est tenu ou pose se remplit d'accent ; la pastille
   remplie et inerte reste pleinement lisible, elle dit un etat, pas une
   commande eteinte. */
:where(body.p-space) .geste-note{
  width: calc(var(--cible-min) - var(--esp-2));
  height: calc(var(--cible-min) - var(--esp-2)); flex: none;
  border: var(--limite-ep) solid var(--limite-controle); color: var(--encre);
  background: none; border-radius: var(--rayon-pilule);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; position: relative;
}
:where(body.p-space) .geste-note::after{
  content: ''; position: absolute; inset: calc(var(--esp-2) / -2);
}
:where(body.p-space) .geste-note svg{ width: 18px; height: 18px }
/* Le nom a gauche, le geste a droite — la grammaire du hall, portee a la
   carte : une colonne de texte, une colonne de gestes. Le texte revient a la
   ligne DANS sa colonne ; la rangee du bas et le composeur ouvert reprennent
   toute la largeur. Le rebord haut des pastilles s'aligne sur le TOIT DES
   LETTRES de la premiere ligne, pas sur sa boite : la demi-interligne et
   l'ecart entre ascendante et capitale de la fonte servie font 0,4 em. */
:where(body.p-space) .note-carte{
  position: relative; grid-template-columns: minmax(0, 1fr) auto;
}
:where(body.p-space) .note-carte > *{ grid-column: 1 }
:where(body.p-space) .note-gestes{
  grid-column: 2; grid-row: 1; align-self: start;
  display: flex; gap: var(--esp-2); margin-top: 0.4em;
}
:where(body.p-space) .note-carte > .note-rang,
:where(body.p-space) .note-carte > .ecrire-carte{ grid-column: 1 / -1 }
/* Au mur, le corps d'une note se borne a six lignes d'apercu — la meme mesure
   que le composeur deplie — et s'ouvre entier a l'ecriture. La borne est en
   LIGNES, jamais en caracteres : la note garde tout son texte. */
:where(body.p-space) .mur-notes .note-carte p{
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 6; overflow: hidden;
}
:where(body.p-space) .geste-note[aria-pressed="true"]{
  background: var(--accent-plan); border-color: var(--accent-plan);
  color: var(--blanc);
}
:where(body.p-space) .geste-note[disabled]{ cursor: default }

/* Le composeur ouvert DANS une carte : la meme piece que partout, bornee a la
   carte qui la porte. */
:where(body.p-space) .note-carte .ecrire-carte{ max-width: none }
:where(body.p-space) .note-carte .ecrire-carte textarea{ max-height: 144px }

/* Le mot cherche s'eclaire dans la note, a l'aplat clair de la famille terre. */
:where(body.p-space) mark.trouve{
  background: var(--terre-e5); color: inherit;
  border-radius: calc(var(--esp-1) / 2);
}

/* La recherche ouvre la page : pleine largeur de piste sur telephone, bornee
   a la COLONNE DE LECTURE et centree au-dela — la page s'ouvre sur ce qu'on
   cherche et se ferme sur ce qu'on ecrit, aux memes cotes ; les deux mesures
   se declarent au meme jeton et ne se separent pas. Chercher depuis le fil
   bascule sur le mur, qui est la vue des resultats. */
:where(body.p-space) .chercher{
  width: 100%; max-width: var(--col); margin-inline: auto;
}
:where(body.p-space) .chercher input{ width: 100% }


:where(body.p-space) .rattrapage{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--esp-3); margin-bottom: var(--esp-4);
  padding: var(--esp-3) var(--esp-4);
  border-radius: var(--rayon-carte); background: var(--gris-ilot);
  font-size: var(--t-sm); color: var(--encre);
}
:where(body.p-space) .note-carte.designee{
  box-shadow: 0 0 0 var(--limite-ep) var(--accent-plan),
              0 18px 44px rgba(var(--ombre-teinte), .14);
}
/* Dans la bande ancree, la rangee des jours tient UNE ligne et defile au
   doigt ; elle partage la mesure de la pilule qu'elle surplombe. */
:where(body.p-space) .ecrire-bas .jours{
  width: 100%; max-width: var(--col);
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  /* PLIEE AU REPOS. Le mecanisme d'echeance ne parait qu'au moment ou l'on est
     pret a ecrire : la rangee se deplie quand le composeur prend le foyer, et
     se replie quand il le rend sans que rien ait ete choisi ni ecrit. La bande
     etant ancree au bas de la fenetre, elle grandit vers le HAUT — le champ ne
     bouge pas d'un pixel sous le doigt, et c'est cela qui rend le mouvement
     lisible plutot que sautant.
     Le pli se lit sur le foyer de LA BANDE et non du champ : taper une
     pastille deplace le foyer du champ vers un bouton, et un pli suspendu au
     champ se refermerait sous le geste meme qui le sert.
     Repliee, la rangee est invisible : ses commandes sortent du parcours au
     clavier, ce qu'une simple opacite ne ferait pas. */
  max-height: 0; opacity: 0; visibility: hidden;
  overflow-y: hidden;
  margin: 0;
  transition: max-height var(--mvt-apparition) var(--courbe-etat),
              opacity var(--mvt-apparition) var(--courbe-etat),
              margin var(--mvt-apparition) var(--courbe-etat),
              visibility 0s linear var(--mvt-apparition);
}
/* DEPLIEE. Deux causes, jamais une seule : le foyer dans la bande, et le
   marqueur que l'ecran pose quand un choix est fait ou un texte commence —
   sans lui, rendre le foyer effacerait de vue ce qui vient d'etre decide.
   L'ouverture emprunte la courbe d'ENTREE, la fermeture la courbe standard. */
:where(body.p-space) .ecrire-bas:focus-within .jours,
:where(body.p-space) .ecrire-bas.retient .jours{
  max-height: calc(var(--cible-min) + var(--esp-2));
  opacity: 1; visibility: visible;
  margin: 0 0 var(--esp-2);
  transition: max-height var(--mvt-apparition) var(--courbe-entree),
              opacity var(--mvt-apparition) var(--courbe-entree),
              margin var(--mvt-apparition) var(--courbe-entree),
              visibility 0s;
}
:where(body.p-space) .ecrire-bas .jours::-webkit-scrollbar{ display: none }
:where(body.p-space) .ecrire-bas .jour{ flex: none }

/* La rangee des heures appartient aux jours : fermee elle n'occupe rien,
   ouverte elle prend sa ligne, au meme dessin que la rangee des jours. Elle
   ENTRE sur la courbe d'entree et se retire sur la courbe standard — rien ne
   parait ni ne disparait d'un coup. La hauteur vise un plafond connu : la
   cible tactile plus son air, jamais une mesure qui court. */
:where(body.p-space) .ecrire-bas .heures{
  width: 100%; max-width: var(--col);
  display: flex; gap: var(--esp-2);
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  max-height: 0; opacity: 0; visibility: hidden;
  overflow-y: hidden;
  margin: 0;
  transition: max-height var(--mvt-apparition) var(--courbe-etat),
              opacity var(--mvt-apparition) var(--courbe-etat),
              margin var(--mvt-apparition) var(--courbe-etat),
              visibility 0s linear var(--mvt-apparition);
}
:where(body.p-space) .ecrire-bas .heures::-webkit-scrollbar{ display: none }
:where(body.p-space) .ecrire-bas .heures.ouverte{
  max-height: calc(var(--cible-min) + var(--esp-2));
  opacity: 1; visibility: visible;
  margin: 0 0 var(--esp-2);
  transition: max-height var(--mvt-apparition) var(--courbe-entree),
              opacity var(--mvt-apparition) var(--courbe-entree),
              margin var(--mvt-apparition) var(--courbe-entree),
              visibility 0s;
}
:where(body.p-space) .heures .jour{ flex: none }
:where(body.p-space) .heures .heure{ font-variant-numeric: tabular-nums }
:where(body.p-space) .heures .alarme{
  display: inline-flex; align-items: center; gap: var(--esp-1);
}
:where(body.p-space) .heures .alarme svg{ width: var(--t-14); height: var(--t-14) }
:where(body.p-space) .heures .alarme[disabled]{ opacity: .45; cursor: default }
/* Le champ d'heure libre garde le dessin des pastilles : c'est le meme choix,
   saisi au lieu d'etre presse. */
:where(body.p-space) .heures .autre-heure{
  font: inherit; font-size: var(--t-sm); font-weight: var(--w-bold);
  color: var(--encre);
  width: auto; max-width: calc(var(--cible-min) * 2.5);
}

/* La feuille d'echeance de « Plus tard » : une mini-feuille au-dessus de la
   bande, sur le papier de la page, bornee a la mesure des feuilles etroites.
   Elle ENTRE sur la courbe d'entree, se retire en fondu sur la courbe
   standard ; l'etat avant-entree pose le depart hors transition. */
:where(body.p-space) .feuille-echeance{
  position: absolute;
  bottom: calc(100% - var(--air-i3) + var(--esp-2));
  left: var(--marge); right: var(--marge);
  margin-inline: auto;
  max-width: 400px;
  background: var(--blanc);
  border: var(--limite-ep) solid var(--gris-filet);
  border-radius: var(--rayon-carte);
  padding: var(--esp-4);
  box-shadow: 0 2px 6px rgba(var(--ombre-teinte), .10),
              0 18px 44px rgba(var(--ombre-teinte), .14);
  opacity: 1; transform: none;
  transition: opacity var(--mvt-apparition) var(--courbe-entree),
              transform var(--mvt-apparition) var(--courbe-entree);
}
:where(body.p-space) .feuille-echeance.avant-entree{
  opacity: 0; transform: translateY(var(--esp-2)); transition: none;
}
:where(body.p-space) .feuille-echeance.se-retire{
  opacity: 0; transform: translateY(var(--esp-2));
  transition-timing-function: var(--courbe-etat), var(--courbe-etat);
}
:where(body.p-space) .feuille-echeance > .etiquette{ margin-bottom: var(--esp-2) }
/* Deux pastilles par ligne, au dessin des jours : la feuille reste une main,
   pas une colonne. Le champ de date et le « Passer » prennent leur ligne
   entiere — le premier est une saisie, le second une sortie douce, pas un
   engagement. */
:where(body.p-space) .feuille-echeance .options{
  /* Les colonnes s'equilibrent sur le contenu : aucune pastille ne casse son
     mot — la colonne ne descend jamais sous son texte le plus large. */
  display: grid;
  grid-template-columns: minmax(max-content, 1fr) minmax(max-content, 1fr);
  gap: var(--esp-2);
}
:where(body.p-space) .feuille-echeance .choix,
:where(body.p-space) .feuille-echeance .champ-date{
  width: 100%; text-align: center; white-space: nowrap;
}
:where(body.p-space) .feuille-echeance .champ-date{
  grid-column: 1 / -1;
  font: inherit; font-size: var(--t-sm); font-weight: var(--w-bold);
  color: var(--encre);
}
:where(body.p-space) .feuille-echeance .passer{
  grid-column: 1 / -1; justify-self: start; margin-top: var(--esp-1);
}
:where(body.p-space) .ecrire-bas{
  /* La bande s'arrete au-dessus de la barre des verbes. La hauteur employee
     est celle que le chrome PUBLIE au rendu, non la hauteur ecrite : les deux
     different, et le jeton publie tombe a zero quand la barre passe en haut,
     ce qu'une valeur ecrite ne saurait pas faire. */
  position: sticky;
  bottom: calc(var(--chrome-bas-h, 80px) + var(--safe-bas, 0px));
  z-index: 5;
  /* La bande porte le papier de la page — le meme, jamais une teinte
     voisine — opaque sur toute sa matiere, fondue sur son seul cran d'air
     haut pour voiler ce qui defile dessous ; sa matiere tient la COLONNE DE
     LECTURE, la meme mesure que la recherche, a toute largeur. Une mesure
     ecrite plus large que la colonne sortirait du texte qu'elle sert. */
  padding: var(--air-i3) var(--marge) var(--air-i3);
  background: linear-gradient(to top, var(--blanc) calc(100% - var(--air-i3)), transparent);
  display: grid; justify-items: center;
}
:where(body.p-space) .ecrire{
  width: 100%; max-width: var(--col);
  display: flex; gap: var(--esp-2); align-items: flex-end;
  background: var(--blanc);
  /* Le trait de controle du dialecte rond ; le trait double appartient au
     dialecte franc et ne se porte pas ici. La limite est le seul moyen
     d'identifier un champ vide : elle tient 3:1 contre son fond. */
  border: var(--limite-ep) solid var(--limite-controle);
  border-radius: var(--rayon-carte);
  padding: 0 var(--esp-1) 0 var(--esp-6);
}
:where(body.p-space) .ecrire:focus-within{ border-color: var(--accent-plan) }
:where(body.p-space) .ecrire textarea{
  flex: 1; border: 0; background: none; resize: none;
  font: inherit; font-size: var(--t-16); line-height: 1.5;
  /* L'air vertical vit ICI et non sur le contenant : ce qui se touche est le
     champ, et sa boite doit atteindre le plancher a elle seule. */
  color: var(--encre); padding-block: calc((var(--cible-min) - 1.5em) / 2);
  outline: none; max-height: 144px;
}
:where(body.p-space) .envoi{
  /* Le dessin recule d'un cran d'air pour ne pas venir tangenter la limite du
     champ ; la zone atteinte reste au plancher par l'extension ci-dessous. */
  width: calc(var(--cible-min) - var(--esp-2));
  height: calc(var(--cible-min) - var(--esp-2)); flex: none;
  border: var(--limite-ep) solid var(--accent-plan); color: var(--accent-plan);
  background: none; border-radius: var(--rayon-pilule);
  display: grid; place-items: center; cursor: pointer;
  position: relative; margin-bottom: var(--esp-1);
}
:where(body.p-space) .envoi::after{
  /* La zone atteinte se DECLARE au jeton du plancher et se centre sur le
     dessin. Un retrait calcule en cran d'air ne suffit pas : le bloc contenant
     d'une position absolue est la boite de REMPLISSAGE, dont la limite est
     deja retranchee — la zone y perdait la valeur de deux limites et tombait
     sous le plancher sans que rien ne le dise. */
  content: ''; position: absolute;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: var(--cible-min); height: var(--cible-min);
}
/* A une ligne, la commande occupe le bout rond du cadre et sa proportion tient.
   Des la deuxieme ligne ce bout rond n'existe plus et elle se retrouve dans un
   angle : elle recule alors d'un cran d'air sur les deux axes, ce qui double
   l'air de ses trois cotes libres sans changer la hauteur de la boite. Le
   deplacement porte sur la commande seule, pas sur le cadre : la boite grandit
   deja d'une ligne au meme instant, et deux croissances simultanees se lisent
   comme un a-coup. La zone atteinte suit le dessin. */
:where(body.p-space) .envoi{
  transition: transform var(--mvt-etat) var(--courbe-etat);
}
:where(body.p-space) .ecrire-bas .ecrire.est-longue .envoi{
  transform: translate(calc(var(--esp-1) * -1), calc(var(--esp-1) * -1));
}
/* Le recul rapproche la commande du texte d'autant qu'il l'eloigne du bord :
   l'ecart de la rangee le compense, pour que les deux cotes verticaux gardent
   la meme valeur. */
:where(body.p-space) .ecrire-bas .ecrire.est-longue{
  gap: calc(var(--esp-2) + var(--esp-1));
}
:where(body.p-space) .envoi svg{ width: 18px; height: 18px }

/* Le champ court du hall : une note rapide s'y ecrit et s'y garde. Sa forme
   dit sa portee — deux lignes ici, la page pour ce qui s'etend. C'est le meme
   composant que celui des notes, borne en hauteur. Il se declare APRES lui :
   a specificite egale, c'est l'ordre qui tranche. */
:where(body.p-space) .ecrire-court{ margin-top: var(--air-i3) }
:where(body.p-space) .ecrire-court textarea{
  max-height: calc(var(--cible-min) * 2);
}

/* Dans une carte, le composeur perd son cadre : un contenant dans un contenant
   double la limite sans rien ajouter. Il devient la derniere ligne de la
   liste — celle qu'on ecrit — aligne sur la colonne de texte, et sa limite
   passe sous le seul champ, ou elle reste le moyen de l'identifier. */
:where(body.p-space) .hall-bloc .ecrire{
  border: 0; background: none; border-radius: 0;
  padding: 0; gap: var(--esp-3);
}
/* La limite se porte sur le contenant, pas sur le champ : le trait du foyer
   au clavier est declare sur les champs eux-memes et prime, ce qui donnerait
   deux couleurs pour un meme etat selon le geste. Elle s'arrete avant la
   pastille — largeur du dessin plus l'ecart qui l'en separe. */
:where(body.p-space) .hall-bloc .ecrire{ position: relative }
:where(body.p-space) .hall-bloc .ecrire::after{
  content: ''; position: absolute; left: 0; bottom: 0;
  right: calc(var(--cible-min) - var(--esp-2) + var(--esp-3));
  border-bottom: var(--limite-ep) solid var(--limite-controle);
}
:where(body.p-space) .hall-bloc .ecrire:focus-within::after{
  border-bottom-color: var(--accent-plan);
}

/* Trois etats, un seul recit. Au repos la limite est grise et la pastille
   attend, bordee. Le champ qui a la main porte la limite d'accent. Du texte
   entre remplit la pastille : il y a desormais de quoi envoyer, et la limite
   reste d'accent tant que rien n'est parti. `a-du-texte` est posee par le
   script sur le contenant : un champ qui ne porte que des espaces n'a rien a
   envoyer et ne doit donc pas s'allumer. Declaree APRES l'etat actif : meme
   specificite, c'est l'ordre qui tranche. */
:where(body.p-space) .ecrire.a-du-texte{
  border-color: var(--accent-plan);
}
:where(body.p-space) .ecrire.a-du-texte .envoi{
  background: var(--accent-plan); color: var(--blanc);
}
:where(body.p-space) .hall-bloc .ecrire.a-du-texte::after{
  border-bottom-color: var(--accent-plan);
}
:where(body.p-space) .filtres{
  display: flex; gap: var(--esp-2); flex-wrap: wrap; margin-bottom: var(--air-i3);
}
:where(body.p-space) .filtre{
  border: var(--limite-ep) solid var(--limite-controle); color: var(--encre);
  background: none; border-radius: var(--rayon-pilule);
  min-height: calc(var(--cible-min) - var(--esp-2));
  padding-inline: var(--esp-4); font-size: var(--t-14); cursor: pointer;
  position: relative;
}
/* Le dessin de la pilule recule d'un cran d'air sous le plancher pour que la
   rangee tienne sa ligne ; la zone atteinte, elle, reste AU plancher par une
   extension centree. Retirer cette regle ramene la cible a la hauteur du
   dessin, qui est sous la valeur declaree. */
:where(body.p-space) .filtre::after{
  content: ''; position: absolute;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 100%; height: var(--cible-min);
}
:where(body.p-space) .filtre[aria-pressed="true"]{
  border-color: var(--accent-plan); color: var(--accent-plan);
  font-weight: var(--w-bold);
}
/* Ce qui est ecrit se relit tel quel : les retours a la ligne d'une note se
   rendent. Le fil du hall reste sur une ligne — c'est un apercu, pas la note. */
:where(body.p-space) .note-carte p{ white-space: pre-wrap }
:where(body.p-space) .mur-notes{ columns: 1; column-gap: var(--esp-4) }
:where(body.p-space) .mur-notes .note-carte{
  break-inside: avoid; margin-bottom: var(--esp-4);
}
:where(body.p-space) .visuellement-cache{
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}
@media (min-width: 768px){
  :where(body.p-space) .mur-notes{ columns: 2 }
  /* Un seul axe vertical : la quete, les vues, le mur et le composeur se
     centrent sur la meme mesure — la page s'ouvre et se ferme au meme endroit. */
  :where(body.p-space) .filtres{ justify-content: center }
}
/* Pas de troisieme colonne : les gestes restent toujours visibles, et une
   carte plus etroite ne loge pas leur colonne a cote d'un titre. */

/* La vedette : la bande sombre de l'univers porte le module mis en avant, et
   ses cartes restent claires — elles s'y detachent d'elles-memes. Elle sert au
   hall pour son premier module, et sur une page de module pour l'etage qui en
   est le sujet ; hors du hall elle garde l'air des blocs de la page. */
:where(body.p-space) .hall-bloc.vedette{ background: var(--univers) }
/* L'air vertical seul : ecrire la marge en abrege effacerait la traversee de
   piste, qui vit sur la marge horizontale. */
:where(body.p-space) .corps > .hall-bloc{ margin-block: 0 var(--air-i4) }
/* La bande de l'etage-sujet traverse la page par le mecanisme commun des
   pleines largeurs, et REPREND en dedans exactement ce que la traversee a
   donne au dehors — la demi-difference entre la fenetre et la piste, la meme
   expression au signe pres. Ses lignes tombent alors sur le rail des etages
   qui la suivent, quelle que soit la largeur, sans qu'aucun cran soit ecrit.
   Bord a bord, un rayon n'a plus de coin ou vivre et l'ombre n'a plus de
   sol : les deux tombent. */
:where(body.p-space) .bande-journee{
  padding-inline: calc(50vw - 50%);
  border-radius: 0;
  box-shadow: none;
}
/* Les cinq modules sont freres : ils portent le meme rang de titre. Celui de
   la vedette ne redeclare de l'arbre que ce que la bande sombre impose — son
   encre. */
:where(body.p-space) .hall-bloc.vedette .hall-tete :is(h2, h3){
  margin: 0; color: var(--blanc);
}
:where(body.p-space) .hall-bloc.vedette .ouvre-module{ color: var(--terre-e4) }
:where(body.p-space) .hall-bloc.vedette .lien-module{ color: var(--blanc) }
/* Tout ce qui parle a l'encre discrete sur la bande sombre reprend le blanc
   voile : l'encre discrete est reglee pour le papier, et elle passe sous le
   plancher des qu'on la pose sur le noir. */
:where(body.p-space) .hall-bloc.vedette .vide,
:where(body.p-space) .hall-bloc.vedette .fil-compte,
:where(body.p-space) .hall-bloc.vedette .mot-boss,
:where(body.p-space) .hall-bloc.vedette .repli-faites,
:where(body.p-space) .hall-bloc.vedette .etat-semaine{
  color: rgba(var(--blanc-rgb), .75);
}
/* Le mot de la semaine accomplie : une note, pas un titre — il suit la liste
   sans la concurrencer. */
:where(body.p-space) .mot-boss{
  margin: 0; font-size: var(--t-sm); line-height: var(--lh-14);
  color: var(--encre-discrete);
}
/* Sur la bande sombre, l'aplat clair du vide garde son encre claire : la
   paire s'inverse ensemble, jamais a moitie. */
:where(body.p-space) .hall-bloc.vedette .vide{
  background: rgba(var(--blanc-rgb), .10);
  color: var(--blanc-casse);
}
:where(body.p-space) .hall-bloc.vedette .bouton-contour{
  border-color: var(--blanc); color: var(--blanc);
}

/* ---- Ce qui n'appartient qu'a l'ecran du Savoir ---- */
/* La tete de la salle des formats courts, puis la bande sombre qui les
   porte : elle traverse la piste par le mecanisme commun des pleines
   largeurs, et sa rangee defile au doigt — rien n'y avance seul. */
/* La salle des formats courts ferme la page : elle est une rupture de
   section, pas la suite de la liste. Elle prend le cran d'air que le tronc
   pose entre deux gabarits — sans lui, son titre se colle a la derniere
   fiche. */
:where(body.p-space) .intel-tube{ margin-top: var(--air-i6) }
:where(body.p-space) .intel-tube-tete{
  display: flex; align-items: baseline; gap: var(--esp-2);
  margin: 0 0 var(--air-i2);
}
:where(body.p-space) .intel-tube-tete h2{ margin: 0 }
:where(body.p-space) .intel-compte{ color: var(--encre-discrete); font-size: var(--t-sm) }
:where(body.p-space) .intel-bande{
  background: var(--univers);
  padding: var(--esp-4) 0;
  margin-bottom: var(--air-i3);
}
:where(body.p-space) .intel-rangee{
  display: flex; gap: var(--esp-3);
  overflow-x: auto;
  padding-inline: max(var(--esp-4), calc(50vw - 50%));
  scrollbar-width: none;
}
:where(body.p-space) .intel-rangee::-webkit-scrollbar{ display: none }
/* La vignette d'un format court garde le portrait des ecrans qui le
   produisent ; sa largeur derive du plancher tactile et cede sous les
   fenetres etroites. */
:where(body.p-space) .intel-vignette{
  flex: none;
  width: min(30vw, calc(var(--cible-min) * 3));
  aspect-ratio: 9 / 16;
  border: none; padding: 0;
  border-radius: var(--rayon-module);
  overflow: hidden; position: relative;
  background: var(--neutre-e1); color: var(--blanc);
  cursor: pointer;
}
:where(body.p-space) .intel-vignette img{
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
:where(body.p-space) .intel-vignette iframe{
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
}
:where(body.p-space) .intel-vignette.est-jouee{ cursor: default }
:where(body.p-space) .intel-vignette-hote{
  position: absolute; inset: auto var(--esp-2) var(--esp-2);
  font-size: var(--t-sm); font-weight: var(--w-bold);
  overflow-wrap: anywhere;
}
:where(body.p-space) .intel-joue{
  position: absolute; inset: 0; margin: auto;
  width: calc(var(--cible-min) * 0.75); height: calc(var(--cible-min) * 0.75);
  border-radius: 50%; background: rgba(var(--blanc-rgb), .92);
  display: flex; align-items: center; justify-content: center;
}
:where(body.p-space) .intel-joue::after{
  content: ''; margin-left: 2px;
  border-style: solid; border-width: 7px 0 7px 11px;
  border-color: transparent transparent transparent var(--univers);
}
:where(body.p-space) .intel-vignette.est-jouee .intel-joue{ display: none }

/* La ligne des salles introduit le module : une seule ligne, la largeur
   de la page, chaque pilule a part egale. */
:where(body.p-space) .intel-filtres{
  display: flex; gap: var(--esp-2);
  margin: 0 0 var(--air-i3);
}
/* Les commandes de la rangee. La feuille les tient hors des ecrans ou le
   balayage au doigt est le geste naturel ; elles paraissent au cran ou la
   piste arrete ses marges, et y restent visibles en permanence. */
:where(body.p-space) .intel-fleches{ display: none; gap: var(--esp-2); margin-left: auto }
:where(body.p-space) .intel-fleche{
  width: var(--cible-min); height: var(--cible-min);
  /* Le gris de service ne rend que 1,31 contre le papier : c'est une teinte de
     separation, pas une frontiere de commande. */
  border-radius: 50%; border: var(--limite-ep) solid var(--limite-controle);
  background: var(--blanc); color: var(--encre);
  font-size: var(--t-h4); line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}


:where(body.p-space) .intel-filtres .vue{
  flex: 1; white-space: nowrap;
  display: inline-flex; align-items: center; justify-content: center;
  padding-inline: var(--esp-3);
  position: relative;
}
/* La commande ne dessine que son mot : sa boite prend la hauteur d'une ligne,
   soit vingt et un pixels, tres loin du plancher tactile. La zone atteinte se
   pose donc AU plancher, centree sur le mot, sans que le dessin bouge. La
   rangee garde son cran d'air entre elle et ce qui suit : deux zones de
   rangees voisines ne se rencontrent pas. */
:where(body.p-space) .intel-filtres .vue::after{
  content: ''; position: absolute;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 100%; height: var(--cible-min);
}

/* Au cran ou la piste tient ses marges definitives, la bande perd son aplat :
   le carrousel seul, aligne a la piste. Retirer ces regles rendrait au tres
   large ecran une bande sombre d'un bord a l'autre de la fenetre. */
@media(min-width:1024px) and (min-height:600px){
  :where(body.p-space) .intel-bande{ margin-inline: 0; background: none; padding: 0 }
  :where(body.p-space) .intel-rangee{ padding-inline: 0 }
  /* La vignette ne grandit jamais avec la fenetre : la piste s'elargit, la
     rangee en montre davantage. Au portrait 9/16, une largeur qui suit la
     page rendrait une bande plus haute que le contenu qu'elle accompagne. */
  :where(body.p-space) .intel-vignette{ width: calc(var(--cible-min) * 2.5) }
  :where(body.p-space) .intel-tube-tete .intel-fleches{ display: flex }
  /* Le nom du site, qui remplace une vignette absente, descend d'un cran :
     a cette largeur il se couperait au milieu d'un mot. */
  :where(body.p-space) .intel-vignette-hote{ font-size: var(--t-note) }
  /* La ligne des salles cesse de s'etirer : chaque pilule reprend la largeur
     de son texte, et la ligne se range a gauche comme le reste de la page. */
  :where(body.p-space) .intel-filtres .vue{ flex: 0 0 auto }
}

/* La fiche d'un lien : deux rangs, et l'ombre en deux couches — une de
   contact qui pose, une ambiante qui detache — a la place de tout trait. */
:where(body.p-space) .intel-fiche{
  background: var(--blanc);
  border-radius: var(--rayon-module);
  padding: var(--esp-3) var(--esp-4);
  display: grid; gap: var(--esp-1);
  box-shadow: 0 1px 2px rgba(var(--ombre-teinte), .08),
              0 8px 24px rgba(var(--ombre-teinte), .12);
}
:where(body.p-space) .intel-fiche + .intel-fiche{ margin-top: var(--air-i2) }
:where(body.p-space) .intel-titre{
  font-weight: var(--w-bold); color: var(--encre);
  text-decoration: none; line-height: 1.35; overflow-wrap: anywhere;
  /* Le titre mene au contenu : c'est une commande, et elle tient le plancher
     tactile sur une ligne comme sur deux. */
  display: flex; align-items: center; min-height: var(--cible-min);
}
:where(body.p-space) .intel-meta{
  margin: 0; display: flex; align-items: center; gap: var(--esp-2);
  flex-wrap: wrap; color: var(--encre-discrete); font-size: var(--t-sm);
}
:where(body.p-space) .intel-pousse{
  margin-left: auto; display: inline-flex; gap: var(--esp-2);
}
/* Une action en lettres : la cible tactile s'etend sans pousser le rang. */
:where(body.p-space) .intel-lien-action{
  background: none; border: none; cursor: pointer;
  color: var(--terre-e3); font-family: var(--font-corps);
  font-weight: var(--w-bold); font-size: var(--t-sm);
  padding: 0 var(--esp-1); position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--cible-min);
}
:where(body.p-space) .intel-lien-action::after{
  content: ''; position: absolute; left: 0; right: 0;
  top: 50%; transform: translateY(-50%); height: var(--cible-min);
}
:where(body.p-space) .salle-chip{
  display: inline-flex; align-items: center;
  border-radius: var(--rayon-pilule);
  background: var(--terre-e5); color: var(--terre-e2);
  font-family: var(--font-eclat); font-weight: var(--w-bold);
  font-size: var(--t-sm); padding: .05em .6em; white-space: nowrap;
}
:where(body.p-space) .salle-chip.est-question{
  background: var(--jaune-e4); color: var(--terre-e1);
}
:where(body.p-space) .intel-choix{
  display: flex; gap: var(--esp-2); flex-wrap: wrap;
  margin-top: var(--air-i1);
}
:where(body.p-space) .intel-choix .vue{
  padding-inline: var(--esp-4); font-size: var(--t-sm); white-space: nowrap;
}
:where(body.p-space) .intel-toujours{
  margin: var(--air-i1) 0 0; display: flex; align-items: center;
  gap: var(--esp-3); flex-wrap: wrap;
  color: var(--encre); font-size: var(--t-sm);
}
