/* Tâches — taches.dujardin.me
 *
 * La palette est RECOPIÉE de sono.montreuillois.com, variable par variable et
 * dans le même ordre, pour que la comparaison reste possible d'un coup d'œil.
 * Trois sites de la même main doivent se reconnaître, et une retouche de teinte
 * doit se faire une fois plutôt que trois.
 *
 * Chaque teinte est déclarée en light-dark(clair, sombre) : c'est color-scheme
 * qui désigne laquelle s'applique. Sans réglage il vaut « light dark » — le
 * système tranche, et les éléments natifs (barres de défilement, cases à cocher,
 * champs) suivent sans une ligne de plus.
 */

:root {
	color-scheme: light dark;

	--fond: light-dark(#fff, #0b0b0d);
	--laterale: light-dark(#f4f4f7, #000);
	--surface: light-dark(#f1f1f5, #17181c);
	--surface-haute: light-dark(#e6e6ee, #212328);
	--bordure: light-dark(#e1e1e9, #2a2c33);
	--separateur: light-dark(#e4e4ec, #1d1f25);
	--survol: light-dark(#eaeaf1, #131418);
	--texte: light-dark(#16171a, #f2f3f5);
	--texte-doux: light-dark(#3b3f47, #c8ccd3);
	--discret: light-dark(#62687a, #9096a0);
	--efface: light-dark(#6b7180, #5f6672);

	/* Le mauve d'emphase. Le thème sombre en prend la déclinaison claire, qui
	   réclame un texte sombre quand elle sert de fond — d'où --accent-texte, et
	   l'inverse en thème clair. */
	--accent: light-dark(#7b2cbf, #c589f2);
	--accent-texte: light-dark(#fff, #17171b);
	--accent-voile: light-dark(rgba(123, 44, 191, .12), rgba(197, 137, 242, .16));
	--accent-halo: light-dark(rgba(123, 44, 191, .35), rgba(197, 137, 242, .45));

	/* L'échelle des priorités, du rouge au vert.

	   Aucune n'est une primaire absolue : sur du blanc, un jaune pur sort à
	   1,07:1 — il n'existe pas à l'écran —, et un vert pur à 1,37. Il faut les
	   assombrir pour qu'un anneau de 1,8 px se voie, ce qui les rend plus
	   sourdes que le nom de la couleur ne le laisse croire. Le thème sombre n'a
	   pas cette contrainte et rend les teintes franches : c'est là que
	   l'échelle se lit le mieux, et light-dark() sert exactement à ça.

	   **Leur CLARTÉ décroît de P1 à P4 en thème clair, et croît en sombre.** Ce
	   n'est pas une coquetterie : l'échelle va du rouge au vert, la paire même
	   que confond une deutéranopie. Privée de la teinte, il reste la clarté, et
	   P1 sort 1,79 fois plus sombre que P4 en clair, 2,13 fois plus claire en
	   sombre. L'ordre survit donc à la perte de la couleur.

	   Toutes tiennent au-dessus de 3:1 sur leur fond — le seuil d'un objet
	   graphique, un anneau n'étant pas du texte. C'est ce plancher qui a fixé
	   les valeurs, et non l'inverse : P3 a dû redescendre à #a8850c, un jaune
	   plus clair passant sous la barre. */
	--p1: light-dark(#c6191e, #fb575c);
	--p2: light-dark(#d2691e, #f4944f);
	--p3: light-dark(#a8850c, #e7be23);
	--p4: light-dark(#28a252, #9ee3b6);

	--erreur: light-dark(#c0272d, #ff6b6b);
	--succes: light-dark(#0f7a52, #5ddba0);

	--plein: light-dark(#16171a, #fff);
	--plein-texte: light-dark(#fff, #000);
	--plein-survol: light-dark(#33353c, #e6e6e6);

	/* Une ombre portée pèse plus lourd sur du blanc que sur du noir : elle
	   s'allège d'autant en thème clair. */
	--ombre: light-dark(rgba(0, 0, 0, .12), rgba(0, 0, 0, .35));
	--voile-fond: light-dark(rgba(0, 0, 0, .35), rgba(0, 0, 0, .6));

	--rayon: 6px;
	--largeur-laterale: 232px;

	/* Les clés reconnues dans la saisie. Un fond teinté, jamais une couleur de
	   texte : le texte visible est celui du champ, par-dessus le calque, et il
	   garde donc son contraste habituel quelle que soit la teinte.
	   L'alpha est plus fort en thème sombre — un voile clair sur du noir se voit
	   moins qu'un voile sombre sur du blanc, à opacité égale. */
	--cle-date: light-dark(rgba(15, 122, 82, .18), rgba(93, 219, 160, .22));
	--cle-repetition: light-dark(rgba(37, 99, 235, .16), rgba(125, 169, 255, .24));
	/* Mesuré sur la page en thème clair, écart au fond du champ : l'étiquette
	   sortait à 53 quand la date sortait à 93 — elle se lisait comme une teinte
	   plus faible, alors que rien ne la rend moins importante. Relevées à
	   parité, elles pèsent le même poids à l'œil. */
	--cle-priorite: light-dark(rgba(192, 39, 45, .18), rgba(255, 107, 107, .22));
	--cle-etiquette: light-dark(rgba(123, 44, 191, .20), rgba(197, 137, 242, .22));
	--cle-projet: light-dark(rgba(13, 148, 136, .18), rgba(94, 234, 212, .22));

	/* Le texte des pastilles, plus contrasté que le fond qu'elles reprennent. */
	--cle-date-texte: light-dark(#0f7a52, #5ddba0);
	--cle-repetition-texte: light-dark(#2563eb, #7da9ff);
	--cle-priorite-texte: light-dark(#c0272d, #ff6b6b);
	--cle-etiquette-texte: var(--accent);
	--cle-projet-texte: light-dark(#0d9488, #5eead4);
}

/* Le bouton fige color-scheme sur une seule valeur ; le témoin d'un an est relu
   par le serveur, qui rend l'attribut dans le HTML. */
:root[data-theme="clair"] { color-scheme: light; }
:root[data-theme="sombre"] { color-scheme: dark; }

* { box-sizing: border-box; }
html, body { height: 100%; }

body {
	margin: 0;
	background: var(--fond);
	color: var(--texte);
	font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	-webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

/* Ce qu'une synthèse vocale lit et que l'œil ne voit pas. `display: none` le
   retirerait des deux. */
.hors-ecran {
	position: absolute;
	width: 1px; height: 1px;
	margin: -1px; padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.icone {
	width: 20px; height: 20px;
	flex: none;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}

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

.cadre { display: flex; height: 100%; }

.colonne {
	flex: 1;
	min-width: 0;          /* sans quoi un contenu large pousse la latérale dehors */
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.vue {
	flex: 1;
	overflow-y: auto;
	padding: 24px clamp(16px, 4vw, 40px) 64px;
}

.vue--nue {
	display: grid;
	place-items: center;
	min-height: 100%;
	padding: 24px;
}

/* --- La barre latérale --------------------------------------------------- */

.laterale {
	width: var(--largeur-laterale);
	flex: none;
	display: flex;
	flex-direction: column;
	background: var(--laterale);
	border-right: 1px solid var(--separateur);
	padding: 14px 10px 10px;
	overflow-y: auto;
}

.marque {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 4px 8px 14px;
	font-weight: 600;
}

/* 28 px et non 26 : le viewBox porte une unité de marge de chaque côté pour que
   la pointe de la coche puisse sortir du carré sans être coupée. Le carré, lui,
   garde la taille qu'il avait. */
.logo { display: block; width: 28px; height: 28px; }
.logo svg { display: block; width: 100%; height: 100%; }
.logo-fond { fill: var(--accent); }
.logo-trace {
	fill: none;
	stroke: var(--accent-texte);
	stroke-width: 3.6;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.menu { flex: 1; display: flex; flex-direction: column; gap: 1px; }

.menu-titre {
	margin: 14px 0 4px;
	padding: 0 8px;
	font-size: 11px;
	font-weight: 600;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--efface);
}
.menu-titre:first-child { margin-top: 0; }

.menu-item {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 7px 8px;
	border: 0;
	border-radius: var(--rayon);
	background: none;
	color: var(--texte-doux);
	text-align: left;
	width: 100%;
	cursor: pointer;
}

.menu-item span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu-item small { display: block; font-size: 11px; color: var(--efface); }
.menu-item:hover { background: var(--survol); color: var(--texte); }

.menu-item[aria-current="page"] {
	background: var(--accent-voile);
	color: var(--accent);
	font-weight: 500;
}

/* Le compteur d'une entrée du menu.
   `margin-left: auto` le pousse au bout sans qu'il ait de largeur fixe à tenir,
   et `flex: none` l'empêche d'être rogné : c'est le libellé qui doit céder,
   avec ses points de suspension, pas le nombre. Sans `flex: none`, « Courses
   des vacances » réduisait le 12 à « 1… ».
   Le chiffre est plus discret que le libellé — il accompagne, il n'annonce pas
   — et passe à l'accent sur l'entrée courante, comme le reste de la ligne. */
.menu-compte {
	margin-left: auto;
	flex: none;
	padding-left: 6px;
	font-size: 12px;
	font-variant-numeric: tabular-nums;
	color: var(--efface);
}
.menu-item:hover .menu-compte { color: var(--discret); }
.menu-item[aria-current="page"] .menu-compte { color: var(--accent); }

.menu-projets:empty::after {
	content: attr(data-vide);
	display: block;
	padding: 4px 8px;
	font-size: 13px;
	color: var(--efface);
}

/* Le champ de création, à la place exacte du bouton « Nouveau projet ».
   Le retrait de 8 px et la taille de 14 px sont ceux de `.menu-item` : le champ
   doit tomber sur le même bord gauche que les libellés au-dessus, sinon la
   colonne se décale sous l'œil au moment où on écrit dedans. */
.projet-neuf { padding: 0 8px; }

.projet-neuf input {
	width: 100%;
	padding: 6px 8px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: var(--surface);
	color: var(--texte);
	font: inherit;
	font-size: 14px;
}

.projet-neuf input:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 1px;
	border-color: transparent;
}

/* --- Le panneau de partage ------------------------------------------------ */

/* Il reprend `.fiche` pour le cadre : même tiroir à droite, même bascule en
   pleine page sous 900 px. Seul son contenu lui appartient. */
.partage-membres { margin: 0; padding: 0; list-style: none; }

.partage-membre {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 8px 0;
	border-bottom: 1px solid var(--separateur);
}

.partage-qui { min-width: 0; flex: 1; }
.partage-nom { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.partage-qui small { color: var(--efface); font-size: 12px; }

.partage-retirer {
	flex: none;
	padding: 5px 10px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: none;
	color: var(--texte-doux);
	font: inherit;
	font-size: 13px;
	cursor: pointer;
}

.partage-retirer:hover { background: var(--survol); color: var(--texte); }
.partage-retirer:disabled { opacity: 0.5; cursor: default; }

.partage-inviter { display: flex; gap: 8px; margin-top: 16px; }

.partage-inviter input {
	flex: 1;
	min-width: 0;
	padding: 8px 10px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: var(--surface);
	color: var(--texte);
	font: inherit;
	font-size: 14px;
}

.partage-inviter input:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 1px;
	border-color: transparent;
}

.partage-inviter button {
	flex: none;
	padding: 8px 14px;
	border: 0;
	border-radius: var(--rayon);
	background: var(--accent);
	color: var(--accent-texte);
	font: inherit;
	font-size: 14px;
	cursor: pointer;
}

.partage-note, .partage-vide {
	margin: 10px 0 0;
	color: var(--efface);
	font-size: 12px;
	line-height: 1.5;
}

/* --- La recherche --------------------------------------------------------- */

/* Le champ prend la place qu'occupe ailleurs celui d'ajout : c'est le même
   geste au même endroit, et la vue ne se réorganise pas quand on y arrive. */
.recherche { margin: 0 0 16px; }

.recherche input {
	width: 100%;
	padding: 10px 12px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: var(--surface);
	color: var(--texte);
	font: inherit;
	font-size: 15px;
}

.recherche input:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 1px;
	border-color: transparent;
}

/* Le report, en bout de ligne.
   Estompé au repos et franc au survol : il est là pour un geste courant, mais
   c'est la tâche qu'on vient lire, pas ses commandes. Au clavier il reprend sa
   pleine teinte comme au survol — un bouton qu'on ne voit pas quand on l'atteint
   par tabulation est un bouton perdu. */
.tache-reporter {
	flex: none;
	align-self: flex-start;
	margin-left: auto;
	padding: 2px 8px;
	border: 0;
	border-radius: var(--rayon);
	background: none;
	color: var(--efface);
	font: inherit;
	font-size: 16px;
	line-height: 1.4;
	cursor: pointer;
	opacity: 0.55;
}

.tache:hover .tache-reporter { opacity: 1; }

.tache-reporter:hover {
	background: var(--survol);
	color: var(--texte);
	opacity: 1;
}

.tache-reporter:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 1px;
	opacity: 1;
}

/* Le lien de la note, en bout de ligne, juste avant le report.
   Un peu plus présent que lui au repos : dans la Watchlist, c'est LA commande
   qu'on vient chercher, et il n'y a pas de survol au doigt pour la révéler. */
.tache-lien {
	flex: none;
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 4px 6px;
	border-radius: var(--rayon);
	color: var(--discret);
	opacity: 0.75;
}

.tache-lien svg {
	width: 15px;
	height: 15px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.tache:hover .tache-lien { opacity: 1; }

.tache-lien:hover {
	background: var(--survol);
	color: var(--accent);
	opacity: 1;
}

.tache-lien:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 1px;
	opacity: 1;
}

/* Le pied de la latérale : l'application, puis la ligne du compte.
 *
 * La bascule de thème siège DANS la ligne du compte et non sur une rangée à
 * part : la latérale frôle la hauteur d'un écran de portable, et une ligne de
 * plus y ferait apparaître un ascenseur. */
.pied {
	border-top: 1px solid var(--separateur);
	padding-top: 8px;
	margin-top: 8px;
}

.ligne-compte { display: flex; align-items: center; gap: 4px; }

/* Un trait entre le bloc de l'application et celui du compte.
   `:not(:first-child)` plutôt qu'un trait posé sans condition : quand aucun APK
   n'est déposé, la ligne du compte est seule dans le pied, et son trait
   doublerait celui de `.pied` — deux filets à deux pixels d'écart, ce qui se
   voit et ne veut rien dire. */
.ligne-compte:not(:first-child) {
	margin-top: 8px;
	border-top: 1px solid var(--separateur);
	padding-top: 8px;
}

.compte {
	flex: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 7px 8px;
	border-radius: var(--rayon);
	color: var(--texte-doux);
}
.compte:hover { background: var(--survol); color: var(--texte); }
.compte span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.outil {
	display: grid;
	place-items: center;
	width: 34px; height: 34px;
	border: 0;
	border-radius: var(--rayon);
	background: none;
	color: var(--discret);
	cursor: pointer;
}
.outil:hover { background: var(--survol); color: var(--texte); }

/* Les deux pictogrammes de thème cohabitent dans le HTML : sans choix
   enregistré, le serveur ignore la préférence du système et ne peut pas savoir
   lequel rendre. C'est le CSS qui masque celui qui n'a pas lieu d'être. */
.bascule-theme .theme-clair,
.bascule-theme .theme-sombre { display: none; }
:root[data-theme="clair"] .theme-sombre { display: grid; }
:root[data-theme="sombre"] .theme-clair { display: grid; }

@media (prefers-color-scheme: light) {
	:root:not([data-theme="sombre"]) .theme-sombre { display: grid; }
	:root:not([data-theme="sombre"]) .theme-clair { display: none; }
}
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="clair"]) .theme-clair { display: grid; }
	:root:not([data-theme="clair"]) .theme-sombre { display: none; }
}

/* --- La barre du haut ---------------------------------------------------- */

.haut {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 12px clamp(16px, 4vw, 40px);
	border-bottom: 1px solid var(--separateur);
}

.haut-titre { margin: 0; font-size: 17px; font-weight: 600; }

/* Les outils de la vue, au bout de la barre. */
.haut-outils { display: flex; align-items: center; gap: 4px; margin-left: auto; }

/* Le tri en vigueur se voit : un bouton qui change ce qu'on lit doit dire
   qu'il est enfoncé, sinon une liste triée autrement passe pour un défaut. */
.outil[aria-pressed="true"] { background: var(--survol); color: var(--texte); }

.burger {
	display: none;
	place-items: center;
	width: 36px; height: 36px;
	border: 0;
	border-radius: var(--rayon);
	background: none;
	cursor: pointer;
}
.burger:hover { background: var(--survol); }

.voile {
	position: fixed;
	inset: 0;
	background: var(--voile-fond);
	z-index: 5;
}

/* --- Formulaires et boutons ---------------------------------------------- */

.carte {
	width: min(380px, 100%);
	background: var(--surface);
	border: 1px solid var(--bordure);
	border-radius: calc(var(--rayon) * 2);
	padding: 28px;
	box-shadow: 0 8px 30px var(--ombre);
}

.carte .marque { justify-content: center; padding: 0 0 18px; font-size: 18px; }
.carte h2 { margin: 0 0 4px; font-size: 18px; }
.carte .accroche { margin: 0 0 20px; color: var(--discret); font-size: 14px; }

.champ { display: block; margin-bottom: 14px; }
.champ span { display: block; margin-bottom: 5px; font-size: 13px; color: var(--texte-doux); }

.champ input,
.champ select {
	width: 100%;
	padding: 9px 11px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: var(--fond);
	color: var(--texte);
	font: inherit;
}

.champ input:focus-visible,
.champ select:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 1px;
	border-color: transparent;
}

.bouton {
	width: 100%;
	padding: 10px 14px;
	border: 0;
	border-radius: var(--rayon);
	background: var(--accent);
	color: var(--accent-texte);
	font-weight: 600;
	cursor: pointer;
}
.bouton:hover { filter: brightness(1.08); }

.message {
	margin: 0 0 16px;
	padding: 9px 12px;
	border-radius: var(--rayon);
	font-size: 14px;
}
.message--erreur { background: var(--accent-voile); color: var(--erreur); }
.message--succes { background: var(--accent-voile); color: var(--succes); }

.sous-carte { margin: 18px 0 0; text-align: center; font-size: 13px; color: var(--discret); }
.sous-carte a { color: var(--accent); }

.vide {
	margin: 48px auto;
	max-width: 380px;
	text-align: center;
	color: var(--discret);
}

/* --- Sous 900 px : la latérale devient un tiroir ------------------------- */
/*
 * À 1024×768 elle reste donc affichée, et laisse près de 800 px au contenu.
 * C'est la HAUTEUR qui contraint à cette taille, pas la largeur.
 */
@media (max-width: 900px) {
	.laterale {
		position: fixed;
		inset: 0 auto 0 0;
		z-index: 10;
		/* Le tiroir se gare au-delà de sa propre ombre.
		 *
		 * À translateX(-100%) son bord droit tombe exactement sur x = 0 : le
		 * panneau ne se voit plus, mais son ombre de 30 px, elle, continue de
		 * peindre sur la page — une bande sombre en dégradé sur tout le bord
		 * gauche, qu'on prend pour un défaut d'affichage. Mesuré avant
		 * correction : (9,9,10) au bord contre (11,11,13) au fond de la page.
		 *
		 * Reculer de la portée de l'ombre coûte 40 px d'animation et règle la
		 * chose sans conditionner l'ombre à l'état, ce qui la ferait apparaître
		 * d'un coup au milieu du glissement. */
		transform: translateX(calc(-100% - 40px));
		transition: transform .18s ease;
		box-shadow: 0 0 30px var(--ombre);

		/* L'ombre suffit à le détacher : la bordure ferait un second trait. */
		border-right: 0;
	}

	body.tiroir-ouvert .laterale { transform: none; }
	.burger { display: grid; }
}

@media (min-width: 901px) {
	.voile { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.laterale { transition: none; }
}

/* --- Le profil ----------------------------------------------------------- */

.carte--large { width: min(560px, 100%); box-shadow: none; }
/* Une section du profil se sépare de la précédente par un trait, et non par du
   vide : sous un bouton pleine largeur, 24 px de marge ne se lisent pas comme
   une séparation — le titre suivant a l'air de commenter le bouton. */
.carte h3 {
	margin: 28px 0 4px;
	padding-top: 24px;
	border-top: 1px solid var(--separateur);
	font-size: 15px;
}
.carte h3:first-of-type { margin-top: 0; padding-top: 0; border-top: 0; }

.liste-sobre { margin: 0; padding: 0; list-style: none; }

.etapes { margin: 0 0 14px; padding-left: 20px; }
.etapes li { margin: 4px 0; }
.routes { margin-bottom: 14px; }
.routes code { font-size: 12.5px; }
.lien-contrat { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.exemple {
	margin: 0 0 14px;
	padding: 10px 12px;
	overflow-x: auto;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: var(--fond);
	font: 12.5px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
	white-space: pre;
}
.liste-sobre li {
	padding: 8px 0;
	border-bottom: 1px solid var(--separateur);
}
.liste-sobre li:last-child { border-bottom: 0; }
.liste-sobre small { display: block; color: var(--efface); font-size: 12px; }

.pied-carte { margin-top: 24px; border-top: 1px solid var(--separateur); padding-top: 16px; }

.bouton--sobre {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	background: var(--surface-haute);
	color: var(--texte-doux);
}
.bouton--sobre:hover { background: var(--survol); filter: none; color: var(--texte); }

/* Un lien qui a l'air d'un bouton : la connexion par le nuage part d'un lien,
   parce que « form-action 'self' » couperait une redirection sortie d'un
   formulaire. Reste à lui donner la même assiette qu'un vrai bouton. */
a.bouton {
	display: block;
	box-sizing: border-box;
	text-align: center;
	text-decoration: none;
}

a.bouton--sobre { display: flex; }

/* « ou », entre le mot de passe et le nuage : un trait de chaque côté plutôt
   qu'un mot flottant, qui se lirait comme un titre. */
.ou {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 16px 0;
	color: var(--discret);
	font-size: 13px;
}

.ou::before,
.ou::after {
	content: '';
	flex: 1;
	height: 1px;
	background: var(--separateur);
}

/* --- La page d'épreuves -------------------------------------------------- */

.epreuves { margin: 0 0 8px; padding: 0; list-style: none; font-size: 13px; }
.epreuves li { padding: 2px 0; }
.epreuves .ok { color: var(--discret); }
.epreuves .raté { color: var(--erreur); }
.epreuves pre {
	margin: 4px 0 8px 16px;
	padding: 8px 10px;
	border-radius: var(--rayon);
	background: var(--surface-haute);
	color: var(--texte-doux);
	font-size: 12px;
	overflow-x: auto;
}

code {
	padding: 1px 4px;
	border-radius: 3px;
	background: var(--surface-haute);
	font-size: .92em;
}

/* --- Les vues de tâches -------------------------------------------------- */

.colonne-vue { max-width: 760px; }

.saisie { position: relative; margin-bottom: 18px; }

.saisie input::placeholder { color: var(--efface); }

/* Ce que la saisie a compris, montré et corrigeable : on ne devine jamais en
   silence. */
.pastilles { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

.pastille {
	padding: 2px 9px;
	border-radius: 999px;
	background: var(--accent-voile);
	color: var(--accent);
	font-size: 12px;
	font-weight: 500;
}

.etat-sync { margin: 0 0 12px; font-size: 13px; color: var(--discret); }
.etat-sync:empty { display: none; }
.etat-sync--attente { color: var(--discret); }
.etat-sync--refus { color: var(--erreur); }

/* L'emoji d'un projet, à la place de son picto dans la latérale : même boîte,
   pour que la colonne des noms ne se décale pas d'une entrée à l'autre. */
.menu-emoji {
	display: grid;
	place-items: center;
	width: 20px; height: 20px;
	font-size: 15px;
	line-height: 1;
}

/* Les réglages d'un projet. Le champ d'emoji est large comme deux caractères et
   centré : ce qu'on y met tient en un signe, et un champ pleine largeur pour un
   seul signe donnerait l'idée d'y écrire une phrase. */
.reglage-emoji {
	width: 3.5rem;
	padding: 6px 8px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: var(--surface);
	color: var(--texte);
	font: inherit;
	font-size: 20px;
	text-align: center;
}

.reglage-bascule {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 18px;
	cursor: pointer;
}

.reglage-bascule input { width: 16px; height: 16px; accent-color: var(--accent); }

/* La session expirée : rouge comme un refus — il faut agir —, mais d'une classe
   à elle, pour qu'une synchronisation revenue puisse l'effacer sans emporter le
   message d'une action refusée, qui, lui, reste vrai. */
.etat-sync--session { color: var(--erreur); }
.etat-sync--session a { color: inherit; }

/* Un conseil n'est ni une panne ni un refus : il ne prend pas le rouge. Il dit
   pourquoi un geste n'a rien donné, et porte le bouton qui le lève. */
.etat-sync--conseil { color: var(--discret); }

.bloc { margin-bottom: 22px; }

/* L'en-tête de « En retard » : le compte à gauche, l'action à droite.

   Le bouton est posé au-dessus de la première ligne et non dans chacune : il
   agit sur la liste entière, et un bouton par ligne aurait dit le contraire. */
/* Un jeton et son bouton de révocation, sur la même ligne. Le bouton à droite
   et non sous le nom : révoquer se vise, cela ne se rencontre pas en lisant. */
.ligne-jeton {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
}

.ligne-jeton form { margin: 0; }

/* --- Les statistiques du profil ------------------------------------------ */

/* Quatre tuiles qui se replient d'elles-mêmes : `auto-fit` passe de quatre
   colonnes à deux sur un téléphone sans qu'aucune requête média ne le dise. Le
   minimum de 96 px est la largeur sous laquelle « jours d'affilée » se coupe. */
.stat-chiffres {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
	gap: 8px;
	margin: 12px 0 16px;
	padding: 0;
	list-style: none;
}

/* `--surface-haute` et non `--surface` : la carte est déjà en `--surface`, et
   des tuiles de la même teinte ne se voyaient pas — quatre nombres flottant
   dans le vide, ce qui se lit, mais n'était pas le dessin. C'est la teinte que
   `.bouton--sobre` emploie déjà pour se détacher du même fond. */
.stat-chiffres li {
	padding: 10px 12px;
	border-radius: var(--rayon);
	background: var(--surface-haute);
}

.stat-chiffres strong {
	display: block;
	font-size: 22px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	line-height: 1.15;
	color: var(--texte);
}

.stat-chiffres span { font-size: 12px; color: var(--efface); }

/* La hauteur est ICI, et la largeur suit la carte : le SVG est tracé dans un
   repère de 60 unités de haut et s'étire, `preserveAspectRatio` étant à `none`.
   Ce sont des rectangles — les étirer ne les déforme pas. */
.stat-graphique {
	display: block;
	width: 100%;
	height: 72px;
	margin: 4px 0 8px;
}

/* Le halo d'accent, et non l'accent plein : trente barres pleines feraient un
   mur mauve où l'on ne distingue plus la hauteur, qui est pourtant la seule
   chose que ce dessin dit. Le jour même sort en plein — c'est le repère qui
   permet de lire les autres de droite à gauche.

   **Le halo (35 %) et non le voile (12 %).** Le voile est fait pour tenir
   DERRIÈRE du texte, où il ne doit surtout pas se voir ; ici il est la matière
   même du dessin, et sur le fond clair d'une carte il s'effaçait presque.

   Le halo reste en deçà des 3:1 que ce fichier tient pour les anneaux de
   priorité, et c'est assumé : ces barres-là ne portent aucune information
   qu'on ne trouve pas en toutes lettres juste dessous — la meilleure journée,
   son nombre, le total. Un anneau de priorité, lui, est la seule façon de
   connaître la priorité, d'où le seuil. */
.stat-barre { fill: var(--accent-halo); }
.stat-barre--jour { fill: var(--accent); }

.stat-legende { margin-bottom: 16px; }

/* Le nom à gauche, le nombre à droite. `.liste-sobre small` est en `block` pour
   les appareils connectés, où le nom passe au-dessus de sa date ; ici les deux
   tiennent sur une ligne, et le nombre s'aligne au bout. */
.stat-projets li {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
}

.stat-projets span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stat-projets small { display: inline; flex: none; font-variant-numeric: tabular-nums; }

.bloc-entete {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	margin: 0 0 6px;
}

.bloc-compte {
	margin: 0;
	color: var(--discret);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .05em;
	text-transform: uppercase;
}

/* Discret au repos, franc au survol. Il déplace des dates sur plusieurs tâches
   d'un seul clic : il ne doit pas se cliquer par accident en visant la première
   ligne, d'où le contour plein plutôt qu'un simple texte. */
.reporter-tout {
	flex: none;
	padding: 4px 12px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: none;
	color: var(--discret);
	font: inherit;
	font-size: 13px;
	cursor: pointer;
}

.reporter-tout:hover {
	border-color: var(--accent);
	background: var(--accent-voile);
	color: var(--accent);
}

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

.bloc-titre {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 0 0 6px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--discret);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .05em;
	text-transform: uppercase;
	cursor: pointer;
}

button.bloc-titre::before {
	content: '';
	width: 0; height: 0;
	border-left: 5px solid currentColor;
	border-top: 4px solid transparent;
	border-bottom: 4px solid transparent;
	transform: rotate(90deg);
	transition: transform .15s ease;
}
button.bloc-titre[aria-expanded="false"]::before { transform: none; }

/* Un titre repliable et sa commande, côte à côte — « En retard » dans
   « Aujourd'hui ». Le titre est lui-même un bouton : la commande ne peut pas
   vivre dedans. */
.bloc-entete--titre { align-items: center; }
.bloc-entete--titre > .bloc-titre { margin: 0; }

.taches, .sous-taches { margin: 0; padding: 0; list-style: none; }

.tache {
	display: flex;
	align-items: flex-start;
	gap: 11px;
	padding: 9px 0;
	border-bottom: 1px solid var(--separateur);
	flex-wrap: wrap;
}

.tache:last-child { border-bottom: 0; }

/* La coche : un cercle, teinté par la priorité.

   Seules P1 et P2 se coloraient, au motif que si tout est urgent, plus rien ne
   l'est. L'argument valait quand les quatre auraient porté la même alarme ; il
   tombe pour une ÉCHELLE. Le vert de P4 ne crie pas — il dit « peut attendre »,
   ce qu'aucune absence de couleur ne disait : une tâche sans priorité et une
   tâche explicitement basse se ressemblaient, alors qu'on a tranché pour l'une
   et pas pour l'autre. Le gris reste donc à qui n'a rien choisi, et lui seul. */
.coche {
	flex: none;
	width: 19px; height: 19px;
	margin-top: 2px;
	padding: 0;
	border: 1.8px solid var(--discret);
	border-radius: 50%;
	background: none;
	cursor: pointer;
}
.coche:hover { border-color: var(--accent); background: var(--accent-voile); }
.coche--p1 { border-color: var(--p1); }
.coche--p2 { border-color: var(--p2); }
.coche--p3 { border-color: var(--p3); }
.coche--p4 { border-color: var(--p4); }

.coche[aria-pressed="true"] {
	border-color: var(--accent);
	background: var(--accent);
	background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='6,12.5 10.2,16.5 18,8'/></svg>");
	background-size: 13px;
	background-position: center;
	background-repeat: no-repeat;
}

.tache-corps { flex: 1; min-width: 0; }
.tache-titre { display: block; overflow-wrap: anywhere; }
.tache--faite > .tache-corps .tache-titre { color: var(--efface); text-decoration: line-through; }

.etiquette { color: var(--accent); }

.tache-meta {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 2px;
	font-size: 12px;
	color: var(--discret);
}

.meta--retard { color: var(--erreur); font-weight: 500; }
.meta--discret { color: var(--efface); }
.meta--projet { margin-left: auto; color: var(--efface); }

/* Les sous-tâches, décalées sous leur mère. Un seul niveau : l'affichage n'a
   donc jamais à se demander jusqu'où descendre. */
.sous-taches {
	flex-basis: 100%;
	margin: 6px 0 0 30px;
	border-left: 1px solid var(--separateur);
	padding-left: 14px;
}
.sous-taches .tache { padding: 6px 0; border-bottom: 0; font-size: 14px; }
.sous-taches .coche { width: 16px; height: 16px; }

@media (max-width: 600px) {
	.meta--projet { margin-left: 0; }
}

/* Une pastille s'annule d'un clic : le mot retourne alors dans le titre. */
.pastille {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	border: 0;
	cursor: pointer;
	font: inherit;
	font-size: 12px;
	font-weight: 500;
	line-height: 1.5;
}

.pastille-croix { opacity: .5; font-size: 14px; line-height: 1; }
.pastille:hover .pastille-croix { opacity: 1; }

.pastille--annulee {
	background: var(--surface-haute);
	color: var(--efface);
	text-decoration: line-through;
}
.pastille--annulee:hover { color: var(--texte-doux); }

/* Le titre qui sera gardé — affiché seulement s'il diffère de ce qui est tapé. */
.apercu-titre {
	margin: 6px 0 0;
	font-size: 12px;
	color: var(--discret);
}
.apercu-titre[hidden] { display: none; }

/* --- Le surlignage des clés dans la saisie ------------------------------- */

/*
 * Un `<input>` ne peut pas porter de balises. On pose donc derrière lui un
 * miroir qui rejoue le même texte — même police, mêmes marges, même bordure —
 * dont le texte est transparent : seuls ses fonds colorés se voient.
 *
 * Les deux doivent partager EXACTEMENT la même boîte. Tout ce qui influe sur la
 * position d'un caractère est déclaré une seule fois, sur les deux à la fois :
 * un `padding` retouché d'un côté seulement décalerait tout le surlignage, et
 * c'est le genre d'écart qu'on met une heure à voir.
 */
.saisie-cadre { position: relative; }

.saisie-cadre input,
.miroir {
	width: 100%;
	padding: 11px 14px;
	border: 1px solid transparent;
	border-radius: var(--rayon);
	font: inherit;
	font-size: 15px;
	line-height: 1.5;
	letter-spacing: normal;
	white-space: pre;
	overflow-x: auto;
	overflow-y: hidden;
}

.miroir {
	position: absolute;
	inset: 0;
	color: transparent;
	background: var(--surface);
	scrollbar-width: none;
	pointer-events: none;
	user-select: none;
}
.miroir::-webkit-scrollbar { display: none; }

.saisie-cadre input {
	position: relative;
	border-color: var(--bordure);
	background: transparent;
	color: var(--texte);
}

.saisie-cadre input:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 1px;
	border-color: transparent;
}

/* Le champ en avant reste au-dessus du miroir, sinon le caret disparaît. */
.saisie-cadre input { z-index: 1; }

/* --- La carte des rappels, sur le profil ----------------------------------- */

.carte-push {
	margin: 0 0 8px;
	padding: 14px;
	background: var(--surface);
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
}

.carte-push .accroche { margin: 0 0 10px; }
.carte-push .accroche:last-child { margin: 10px 0 0; }

.push-boutons { display: flex; flex-wrap: wrap; gap: 8px; }
.push-boutons:empty { display: none; }

/* --- Les sections d'un projet, et le rangement ------------------------------
 *
 * La poignée ne paraît qu'au survol de la ligne : elle est un outil, pas une
 * décoration, et une liste qui porte trente poignées visibles se lit moins bien
 * qu'une liste de titres.
 */

.section-entete {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin: 0 0 6px;
	padding: 4px 0;
	border-bottom: 1px solid var(--separateur);
	cursor: grab;
}

/* La zone « hors section » ne paraît QUE pendant qu'on glisse. Repliée, elle
   laisserait un blanc que rien n'explique ; nommée en permanence, elle ferait un
   rangement de plus à comprendre là où le défaut est justement de ne pas ranger.
   Elle est ce qu'elle est : une cible de lâcher, et seulement quand on lâche. */
.section-entete--racine {
	margin: 0;
	padding: 0;
	border-bottom: 0;
	cursor: default;
}

.section-entete--racine .section-nom { display: none; }

#liste.en-rangement .section-entete--racine {
	margin: 0 0 6px;
	padding: 4px 0;
	border: 1px dashed var(--bordure);
	border-radius: var(--rayon);
}

#liste.en-rangement .section-entete--racine .section-nom {
	display: block;
	padding-left: 8px;
}

.section-nom {
	margin: 0;
	font-size: 13px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--discret);
}

/* **Les outils se voient, discrètement, tout le temps.**
   Ils étaient à `opacity: 0` et n'apparaissaient qu'au survol : sur un écran
   tactile, où il n'y a pas de survol, renommer une section n'existait tout
   simplement pas — et à la souris il fallait deviner qu'il y avait quelque
   chose à survoler. Une commande qu'on ne voit jamais vaut une commande
   absente. Ils restent en retrait, et se réveillent au survol. */
.section-outils {
	display: flex;
	gap: 10px;
	opacity: .55;
	transition: opacity .12s;
}

.section-entete:hover .section-outils,
.section-entete:focus-within .section-outils { opacity: 1; }

.section-entete:focus-visible {
	outline: 2px solid var(--accent-halo);
	outline-offset: 2px;
	border-radius: var(--rayon);
}

.section-neuve { flex: 1; }
.section-neuve input {
	width: 100%;
	padding: 6px 10px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: var(--fond);
	color: var(--texte);
	font: inherit;
	font-size: 14px;
}

.ajouter-section { display: block; margin: 6px 0 4px; }

/* Discret, et rouge seulement au survol : c'est une sortie, pas une action
   qu'on propose. */
.supprimer-projet { display: block; margin: 0 0 24px; color: var(--discret); }
.supprimer-projet:hover { color: var(--erreur); }

/* La poignée : DANS la ligne, et large de vingt-quatre pixels.
   Elle était dehors — `left: -16px` — et large de treize : il fallait viser la
   marge pour la prendre, et l'on croyait la ligne immobile. Elle occupe sa
   place même invisible, sinon les lignes se décaleraient au survol. */
.poignee {
	flex: none;
	display: grid;
	place-items: center;
	width: 24px;
	align-self: stretch;
	margin-left: -6px;
	color: var(--efface);
	font-size: 14px;
	line-height: 1;
	opacity: 0;
	cursor: grab;
	transition: opacity .12s ease;
}

/* La poignée de l'entête : la même marque que celle des lignes, parce que
   c'est le même geste. Elle ne se cache pas non plus — c'était précisément le
   défaut : l'entête était déplaçable et rien ne le disait. */
.poignee--section {
	/* `.poignee` est à `opacity: 0` — elle ne se montre qu'au survol d'une
	   ligne. Ici c'est l'inverse qu'il faut : c'est la seule marque qui annonce
	   qu'une section se déplace. */
	align-self: center;
	width: auto;
	margin: 0 6px 0 0;
	opacity: .55;
}

.section-entete:hover .poignee--section,
.section-entete:focus-within .poignee--section { opacity: 1; }

/* La poignée et le nom restent collés à gauche, les outils à droite : sans
   cela, `space-between` répartirait les trois et le nom flotterait au milieu. */
.section-entete .section-nom { margin-right: auto; }

.tache { position: relative; }
.tache:hover .poignee,
.tache:focus-within .poignee { opacity: 1; }
.poignee:active { cursor: grabbing; }

/* Pendant qu'on range, toutes les poignées se montrent : on voit d'un coup ce
   qui se déplace et ce qui ne se déplace pas. */
.en-rangement .poignee { opacity: .55; }
/* La ligne qu'on tient : elle se soulève au lieu de s'effacer. Elle suit le
   pointeur, il faut donc la voir — l'effacer, comme le faisait le glisser du
   navigateur qui en dessinait un fantôme à côté, la rendrait illisible. */
.tache.tenue {
	position: relative;
	z-index: 2;
	background: var(--surface);
	box-shadow: 0 6px 18px var(--ombre);
	cursor: grabbing;
}

/* Pendant qu'on range, les lignes glissent à leur nouvelle place au lieu d'y
   sauter. Celle qu'on tient, elle, suit le pointeur sans transition : elle est
   déjà où on la met. */
.en-rangement .tache { transition: transform .12s ease; }
.en-rangement .tache.tenue { transition: none; }

/* Le texte ne se surligne pas pendant qu'on range. */
.en-rangement { user-select: none; }

/* **Pendant un rangement, le doigt ne fait plus défiler.** Sans cela, le
   navigateur emporte le geste dès qu'il le croit vertical, annule le pointeur,
   et la ligne retombe au hasard. Hors rangement, `touch-action` reste intact :
   c'est le même doigt qui parcourt la liste, et l'appui long les départage. */
.en-rangement, .en-rangement .tache { touch-action: none; }

/* Le trait d'insertion : au-dessus de la ligne visée, parce qu'un lâcher pose
   la tâche AVANT elle. Un fond coloré dirait « dedans », ce qui est faux. */
.tache.survol-avant { box-shadow: 0 -2px 0 var(--accent); }
.section-entete.survol-dedans { background: var(--accent-voile); }

/* --- L'éditeur de règle de répétition -------------------------------------- */

.editeur-regle {
	margin: -6px 0 18px;
	padding: 14px;
	background: var(--surface);
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
}

.editeur-regle[hidden] { display: none; }

.editeur-corps .fiche-champ { margin-bottom: 10px; }

/* L'avertissement du repli se rattache au champ qu'il commente, pas au suivant :
   collé au libellé d'après, on le lit comme son introduction. */
.editeur-corps .fiche-aide { margin: -4px 0 12px; }

.editeur-jours { display: flex; flex-wrap: wrap; gap: 6px; }

.jour {
	min-width: 42px;
	padding: 6px 8px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: var(--fond);
	color: var(--texte-doux);
	font: inherit;
	font-size: 13px;
	cursor: pointer;
}

.jour--pris {
	background: var(--accent);
	border-color: var(--accent);
	color: var(--accent-texte);
	font-weight: 600;
}

.editeur-apercu {
	margin: 12px 0;
	padding: 10px 12px;
	background: var(--accent-voile);
	border-radius: var(--rayon);
	color: var(--texte-doux);
	font-size: 14px;
}

.editeur-apercu small { display: block; margin-top: 4px; color: var(--discret); }

.editeur-boutons { display: flex; gap: 8px; }

/* --- Les clés proposées pendant la frappe ---------------------------------
 *
 * Ancrée au cadre du champ, et au-dessus de lui (z-index 2 contre 1) : elle
 * recouvre le début de la liste des tâches, ce qui est le propre d'une liste de
 * complétion — la masquer sous la liste reviendrait à ne pas l'afficher.
 */

.suggestions {
	position: absolute;
	z-index: 2;
	top: calc(100% + 4px);
	left: 0;
	right: 0;
	max-height: 260px;
	overflow-y: auto;
	margin: 0;
	padding: 4px;
	list-style: none;
	background: var(--surface-haute);
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	box-shadow: 0 8px 30px var(--ombre);
}

.suggestions[hidden] { display: none; }

.suggestion {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	padding: 7px 10px;
	border-radius: var(--rayon);
	font-size: 14px;
	cursor: pointer;
}

/* La même teinte que la clé prendra dans le champ : la liste et le surlignage
   doivent parler de la même chose. */
.suggestion--etiquette { color: var(--cle-etiquette-texte); }
.suggestion--projet { color: var(--cle-projet-texte); }

.suggestion:hover,
.suggestion--choisie { background: var(--accent-voile); }

.suggestion-emplois { color: var(--discret); font-size: 12px; }

.cle {
	color: transparent;
	background: none;
	border-radius: 3px;
	box-decoration-break: clone;
}
.cle--echeance, .cle--heure { background: var(--cle-date); }
.cle--rrule { background: var(--cle-repetition); }
.cle--priorite { background: var(--cle-priorite); }
.cle--etiquette { background: var(--cle-etiquette); }
.cle--projet { background: var(--cle-projet); }

/* La pastille reprend la teinte de la clé qu'elle commande : sans cela, rien
   ne dit laquelle des cinq elle annulerait. */
.pastille--echeance, .pastille--heure { background: var(--cle-date); color: var(--cle-date-texte); }
.pastille--rrule { background: var(--cle-repetition); color: var(--cle-repetition-texte); }
.pastille--priorite { background: var(--cle-priorite); color: var(--cle-priorite-texte); }
.pastille--projet { background: var(--cle-projet); color: var(--cle-projet-texte); }

/* --- La fiche d'une tâche ------------------------------------------------ */

/*
 * Tiroir à droite au-dessus de 900 px, pleine page en dessous. C'est le même
 * seuil que la barre latérale : deux tiroirs qui basculeraient à des largeurs
 * différentes donneraient un entre-deux où l'un est ouvert et l'autre replié,
 * sans que rien ne l'explique.
 */
.fiche {
	position: fixed;
	inset: 0 0 0 auto;
	z-index: 20;
	width: min(420px, 100%);
	display: flex;
	flex-direction: column;
	background: var(--fond);
	border-left: 1px solid var(--separateur);
	box-shadow: -8px 0 30px var(--ombre);
	overflow-y: auto;
}

.fiche[hidden] { display: none; }

.fiche-haut {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 12px 16px;
	border-bottom: 1px solid var(--separateur);
	position: sticky;
	top: 0;
	background: var(--fond);
}

.fiche-haut h2 { margin: 0; font-size: 15px; font-weight: 600; }

.fiche-corps { padding: 16px; display: flex; flex-direction: column; gap: 16px; }

.fiche-champ { display: block; }
.fiche-champ > span {
	display: block;
	margin-bottom: 5px;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--efface);
}

/* Les liens d'une note. Ils suivent le champ de si près qu'ils lui
   appartiennent — d'où la marge négative, qui reprend le `gap` de la colonne :
   posés à 16 px, ils auraient l'air d'être une rubrique de plus. */
.fiche-liens {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-top: -10px;
}

.fiche-liens a {
	max-width: 100%;
	padding: 4px 9px;
	border: 1px solid var(--accent-halo);
	border-radius: 999px;
	background: var(--accent-voile);
	color: var(--accent);
	font-size: 12px;
	text-decoration: none;
	/* Une adresse ne se coupe pas en deux lignes : elle se tronque, et
	   l'infobulle porte l'entière. */
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.fiche-liens a:hover,
.fiche-liens a:focus-visible { text-decoration: underline; }

/* --- La vidéo de la note -------------------------------------------------

   Un encadré au format d'une vidéo, dessiné par nous. Tant qu'on n'a pas
   cliqué, rien n'est demandé à YouTube : ouvrir une fiche pour cocher une
   tâche ne doit rien apprendre à personne. Au clic, le lecteur prend la place
   du cadre, à la même taille — la fiche ne doit pas sauter sous les yeux. */
.fiche-video {
	margin-top: -4px;
}

.video-cadre,
.fiche-video iframe {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	border-radius: var(--rayon);
}

.video-cadre {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 8px;
	border: 1px solid var(--bordure);
	background: var(--surface-haute);
	color: var(--texte-doux);
	font: inherit;
	font-size: 13px;
	cursor: pointer;
}

.video-cadre:hover,
.video-cadre:focus-visible {
	border-color: var(--accent);
	background: var(--accent-voile);
	color: var(--accent);
}

.video-lire {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	border-radius: 50%;
	background: var(--accent);
	color: var(--accent-texte);
	/* La flèche d'un bouton de lecture n'est pas centrée optiquement : son
	   triangle pèse à gauche. Deux pixels suffisent à la poser droite. */
	padding-left: 3px;
	font-size: 17px;
}

.fiche-video iframe { border: 0; }

.fiche-champ input,
.fiche-champ textarea,
.fiche-champ select {
	width: 100%;
	padding: 8px 10px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: var(--surface);
	color: var(--texte);
	font: inherit;
	font-size: 14px;
}

.fiche-champ textarea { resize: vertical; }

.fiche-champ input:focus-visible,
.fiche-champ textarea:focus-visible,
.fiche-champ select:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 1px;
	border-color: transparent;
}

/* Deux champs par ligne quand ils vont ensemble — échéance et heure, priorité
   et projet. Ils se lisent comme une seule décision. */
.fiche-rangee { display: flex; gap: 12px; }
.fiche-rangee > * { flex: 1; min-width: 0; }

.fiche-repetition {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 8px;
	padding: 8px 10px;
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	background: var(--surface);
	font-size: 14px;
}
.fiche-repetition small { flex-basis: 100%; color: var(--efface); font-size: 12px; }

.lien-sobre {
	border: 0;
	background: none;
	padding: 0;
	color: var(--accent);
	font-size: 12px;
	cursor: pointer;
	text-decoration: underline;
}

.fiche-sous-taches, .fiche-commentaires { margin: 0 0 8px; padding: 0; list-style: none; }

.fiche-sous-taches li {
	display: flex;
	align-items: center;
	gap: 9px;
	padding: 5px 0;
	font-size: 14px;
}
.fiche-sous-taches .faite span { color: var(--efface); text-decoration: line-through; }
.fiche-sous-taches .coche { width: 16px; height: 16px; margin: 0; }

.fiche-commentaires li {
	padding: 8px 10px;
	margin-bottom: 6px;
	border-radius: var(--rayon);
	background: var(--surface);
	font-size: 14px;
}
.fiche-commentaires p { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.fiche-commentaires small { color: var(--efface); font-size: 11px; }

.fiche-aide { display: block; margin-top: 4px; color: var(--efface); font-size: 11px; }

.bouton--danger {
	background: none;
	border: 1px solid var(--bordure);
	color: var(--erreur);
}
.bouton--danger:hover { background: var(--survol); filter: none; }

/* La ligne devient un bouton : on ouvre la fiche en cliquant dessus. Elle garde
   l'apparence d'un texte — un bouton qui ressemble à un bouton, dans une liste
   de trente lignes, ferait une page de boutons. */
button.tache-corps {
	border: 0;
	background: none;
	padding: 0;
	text-align: left;
	font: inherit;
	cursor: pointer;
}
button.tache-corps:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
	border-radius: 3px;
}

/* --- La pastille d'annulation ---------------------------------------------
 *
 * Au-dessus de la fiche (z-index 20), parce qu'un geste fait depuis la fiche
 * doit pouvoir se reprendre sans la fermer d'abord. À gauche, en regard de la
 * liste plutôt qu'au centre : centrée, elle masquerait la ligne dont elle parle.
 *
 * **Elle ne paraît pas pour une création.** Le résultat d'une création est sous
 * les yeux — la ligne vient d'apparaître —, et la vue le dit déjà quand la tâche
 * tombe ailleurs : la pastille faisait alors doublon, sur le seul geste où elle
 * n'apprenait rien. Ctrl+Z, lui, annule toujours.
 */

.annulation {
	position: fixed;
	z-index: 30;
	bottom: 16px;
	left: calc(var(--largeur-laterale) + 20px);

	/* **Une pastille, pas une barre.** Elle occupait toute la largeur sous
	   900 px, sur deux lignes, pour dire ce qu'on venait de faire : plus
	   voyante que le geste qu'elle commentait. Elle prend maintenant la place
	   de son texte, et pas un pixel de plus. */
	width: max-content;
	max-width: min(360px, calc(100vw - var(--largeur-laterale) - 40px));
	display: flex;
	align-items: baseline;
	gap: 10px;
	padding: 7px 12px;
	background: var(--surface-haute);
	border: 1px solid var(--bordure);
	border-radius: 999px;
	box-shadow: 0 4px 16px var(--ombre);
	opacity: .96;
}

.annulation[hidden] { display: none; }

.annulation-texte {
	min-width: 0;
	margin: 0;
	font-size: 13px;
	color: var(--discret);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Un lien, et non un bouton plein : c'est une porte de sortie qu'on prend
   rarement, pas l'action principale de l'écran. */
.annulation-bouton {
	flex: none;
	border: 0;
	padding: 0;
	background: none;
	color: var(--accent);
	font: inherit;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
}
.annulation-bouton:hover { text-decoration: underline; }
.annulation-bouton:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 3px;
	border-radius: 2px;
}

@media (max-width: 900px) {
	.fiche {
		inset: 0;
		width: 100%;
		border-left: 0;
	}

	/* Sous 900 px la latérale est un tiroir : la pastille repart de la marge
	   gauche, sans s'étirer — elle garde la largeur de son texte. */
	.annulation {
		left: 12px;
		max-width: calc(100vw - 24px);
	}
}

/* --- Choisir plusieurs tâches --------------------------------------------- */

/* Le carré du choix, tout à gauche de la ligne.

   **Effacé par défaut, comme la flèche de report.** Il se montre au survol, au
   focus, et dès qu'un choix est commencé. Une case visible en permanence devant
   chaque tâche ferait ressembler la liste à un formulaire, alors que le geste
   ordinaire ici est de cocher la COCHE — qui est autre chose, et vit juste à
   côté. C'est aussi pourquoi il est carré : deux ronds l'un contre l'autre
   auraient demandé de lire avant d'agir. */
.tache-choix {
	flex: none;
	width: 15px; height: 15px;
	margin-top: 4px;
	padding: 0;
	border: 1.6px solid var(--discret);
	border-radius: 3px;
	background: none;
	cursor: pointer;
	opacity: 0;
	transition: opacity .12s ease;
}

.tache:hover .tache-choix,
.tache:focus-within .tache-choix,
body.en-choix .tache-choix { opacity: 1; }

.tache-choix:hover { border-color: var(--accent); background: var(--accent-voile); }

.tache-choix[aria-checked="true"] {
	opacity: 1;
	border-color: var(--accent);
	background: var(--accent);
	background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6,12.5 10.2,16.5 18,8'/></svg>");
	background-size: 11px;
	background-position: center;
	background-repeat: no-repeat;
}

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

/* La ligne choisie se teinte, elle ne s'encadre pas : un cadre par ligne sur six
   lignes contiguës donne cinq traits doubles au milieu, et l'ensemble se lit
   comme un tableau plutôt que comme une sélection. */
.tache--choisie {
	background: var(--accent-voile);
	box-shadow: -8px 0 0 var(--accent-voile), 8px 0 0 var(--accent-voile);
}

/* La barre du choix, au bas de l'écran.

   Elle prend la place de son contenu et se replie sur plusieurs lignes sur un
   écran étroit : une barre qui déborde cacherait ses derniers boutons, dont
   « Supprimer », qui est justement celui qu'il ne faut pas atteindre par
   hasard. */
.choix-barre {
	position: fixed;
	z-index: 31;
	bottom: 16px;
	left: calc(var(--largeur-laterale) + 20px);

	/* **La largeur de son contenu, et pas un pixel de plus** — comme la pastille
	   d'annulation juste à côté. Étirée d'un bord à l'autre, elle laissait un
	   grand vide entre « Supprimer » et la croix, et l'œil traversait l'écran
	   pour rien. */
	width: max-content;
	max-width: calc(100vw - var(--largeur-laterale) - 40px);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 12px;
	padding: 10px 14px;
	background: var(--surface-haute);
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	box-shadow: 0 6px 24px var(--ombre);
}

.choix-barre[hidden] { display: none; }

.choix-compte {
	margin: 0;
	font-size: 13px;
	font-weight: 600;
	color: var(--texte);
	white-space: nowrap;
}

.choix-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
	min-width: 0;
}

.choix-action {
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	padding: 5px 10px;
	background: var(--fond);
	color: var(--texte-doux);
	font: inherit;
	font-size: 13px;
	cursor: pointer;
}
.choix-action:hover { background: var(--survol); color: var(--texte); }
.choix-action:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 1px;
}
.choix-action[hidden] { display: none; }

/* Le seul geste du lot qui retire quelque chose porte la couleur qui le dit.
   Il reste discret tant qu'on ne le survole pas : il est dans la même rangée
   que cinq boutons ordinaires, et un rouge plein y attirerait la main. */
.choix-action--danger { color: var(--erreur); }
.choix-action--danger:hover {
	background: var(--erreur);
	border-color: var(--erreur);
	color: #fff;
}

.choix-vider {
	margin-left: 4px;
	border: 0;
	padding: 0 4px;
	background: none;
	color: var(--discret);
	font: inherit;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
}
.choix-vider:hover { color: var(--texte); }
.choix-vider:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
	border-radius: 2px;
}

/* Les deux barres du bas ne se recouvrent pas : le bandeau d'annulation remonte
   tant qu'un choix est en cours. Il reste lisible, et c'est lui qui porte le
   « Annuler » du lot qu'on vient d'appliquer. */
body.en-choix .annulation { bottom: 74px; }

/* À qui la tâche est confiée. La même teinte que le nom du projet : ce sont
   deux rangements, pas deux alarmes. */
.meta--assigne { color: var(--accent); }

/* --- La tâche qui arrive, la tâche qui s'en va ---------------------------- */

/* **Une tâche écrite doit se voir arriver.** Elle s'insère au milieu de trente
   autres, à sa place dans l'ordre des dates — c'est-à-dire rarement là où l'œil
   regarde. Le fond s'allume et s'éteint : on sait où elle est tombée sans avoir
   à la chercher, et une seconde plus tard la liste est redevenue elle-même. */
@keyframes tache-arrivee {
	from { background: var(--accent-voile); transform: translateY(-4px); opacity: .4; }
	60%  { background: var(--accent-voile); transform: none; opacity: 1; }
	to   { background: transparent; transform: none; opacity: 1; }
}

.tache--neuve { animation: tache-arrivee .7s ease-out; }

/* Et une tâche supprimée doit se voir partir, sinon la ligne d'à côté paraît
   avoir bougé toute seule. La hauteur n'est pas animée : une ligne qui se replie
   ferait sauter tout ce qui la suit, et le geste suivant tomberait à côté. */
@keyframes tache-depart {
	to { opacity: 0; transform: translateX(-14px); }
}

.tache--partante {
	animation: tache-depart .19s ease-in forwards;
	pointer-events: none;
}

/* Une préférence système qui demande moins de mouvement la demande ici aussi.
   Les tâches continuent de s'ajouter et de disparaître — c'est l'animation qui
   s'arrête, pas le geste. */
@media (prefers-reduced-motion: reduce) {
	.tache--neuve, .tache--partante { animation: none; }
	.tache-choix { transition: none; }
}

/* --- La palette de commandes ---------------------------------------------- */

/* Elle se pose par-dessus tout, y compris la fiche : c'est la couche la plus
   récente, et Échap la referme en premier. */
.palette {
	position: fixed;
	inset: 0;
	z-index: 40;
	display: flex;
	justify-content: center;

	/* **`flex-start`, sans quoi la boîte s'étire sur toute la hauteur.** Un
	   conteneur flexible aligne ses enfants sur `stretch` par défaut : la
	   palette faisait alors un rectangle de 70 % de l'écran pour un seul
	   résultat, avec du vide en dessous. Elle épouse maintenant sa liste. */
	align-items: flex-start;
	padding: 12vh 16px 16px;
	background: var(--voile-fond);
}

.palette[hidden] { display: none; }

.palette-boite {
	display: flex;
	flex-direction: column;
	width: min(560px, 100%);
	max-height: 70vh;
	background: var(--fond);
	border: 1px solid var(--bordure);
	border-radius: var(--rayon);
	box-shadow: 0 20px 60px var(--ombre);
	overflow: hidden;
}

.palette-champ {
	border: 0;
	border-bottom: 1px solid var(--separateur);
	padding: 14px 16px;
	background: none;
	color: var(--texte);
	font: inherit;
	font-size: 16px;
}
.palette-champ:focus { outline: none; }

.palette-liste {
	margin: 0;
	padding: 6px;
	list-style: none;
	overflow-y: auto;
}

.palette-item {
	display: flex;
	align-items: baseline;
	gap: 10px;
	padding: 8px 10px;
	border-radius: var(--rayon);
	cursor: pointer;
}

/* Le survol NE colore PAS : la ligne active est celle des flèches, et deux
   lignes marquées à la fois — l'une sous la souris, l'autre sous le clavier —
   feraient croire qu'Entrée vise la mauvaise. */
.palette-item--choisi { background: var(--accent-voile); }

.palette-genre {
	flex: none;
	width: 52px;
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--efface);
}

.palette-nom {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.palette-vide {
	padding: 14px 10px;
	color: var(--discret);
	font-size: 13px;
}

/* --- Le panneau des commandes au clavier ---------------------------------- */

.aide-famille + .aide-famille { margin-top: 4px; }

.aide-famille h3 {
	margin: 0 0 8px;
	font-size: 13px;
	font-weight: 600;
	color: var(--discret);
	text-transform: uppercase;
	letter-spacing: .04em;
}

/* Une grille de deux colonnes plutôt qu'une liste de définitions par défaut :
   les touches doivent s'aligner d'une famille à l'autre, sans quoi l'œil
   redescend chercher où commence chaque explication. */
/* La première colonne a un plancher : sans lui, chaque famille calait ses
   explications sur SA touche la plus large, et les quatre colonnes de texte
   commençaient à quatre abscisses différentes. */
.aide-liste {
	display: grid;
	grid-template-columns: minmax(112px, auto) 1fr;
	gap: 8px 14px;
	margin: 0;
	align-items: baseline;
}

.aide-liste dt { white-space: nowrap; }
.aide-liste dd { margin: 0; font-size: 14px; color: var(--texte-doux); }

kbd {
	display: inline-block;
	min-width: 20px;
	padding: 2px 6px;
	border: 1px solid var(--bordure);
	border-bottom-width: 2px;
	border-radius: 4px;
	background: var(--surface);
	color: var(--texte);
	font-family: inherit;
	font-size: 12px;
	text-align: center;
}

.aide-note {
	margin: 4px 0 0;
	font-size: 13px;
	color: var(--discret);
}

@media (max-width: 900px) {
	/* Sous 900 px la latérale est un tiroir : la barre du choix repart de la
	   marge, comme le bandeau d'annulation. */
	.choix-barre {
		left: 12px;
		right: 12px;
	}
}
