/*
Theme Name: Notelab
Theme URI: https://notelab.ch
Author: Anlo
Description: Custom theme for notelab.ch — a phone-first school companion. Standalone, no parent.
Version: 0.1
Requires at least: 6.4
Requires PHP: 8.1
Text Domain: notelab
*/

/* ============================================================
   1. Fonts — self-hosted, dropped in assets/fonts/
============================================================ */

@font-face {
	font-family: "Geist";
	src: url("assets/fonts/Geist-Variable.woff2") format("woff2-variations");
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Geist Mono";
	src: url("assets/fonts/GeistMono-Variable.woff2") format("woff2-variations");
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}

/* ============================================================
   2. Tokens

   Light is the bare :root. Dark is redefined twice — once behind
   prefers-color-scheme for the system default, once behind
   [data-theme] so an explicit choice wins either way.
============================================================ */

:root {
	--paper: #EDEFF5;
	--card: #F7F8FB;
	--ink: #17204E;
	--ink-soft: #4C5686;

	/* Subject ramp — one hue, four values.
	   ⚠️ Deux corrections successives, et la seconde annule une partie de la
	   première. Les écarts allaient de 9 à 36 : régularisés à ~22, la rampe
	   est devenue cohérente mais toujours trop contrastée — le premier ton,
	   un marine presque noir, écrasait le planning à lui seul.
	   Elle part du pâle et monte, mais l'étendue de 61 à 90 était trop courte
	   pour quatre marches : à dix points d'écart, les deux premières se
	   confondaient encore. Ouverte à 48 · 63 · 77 · 90 — des pas de quatorze,
	   et une encre claire sur la plus foncée, qui ne peut plus porter le
	   marine. Une branche se distingue sans que la grille devienne un damier.
	   Le marine, lui, garde ce qui lui revient : la barre d'onglets, les
	   compteurs, les titres, l'encre. */
	--l1-bg: #5F6EB0;  --l1-fg: #FFFFFF;
	--l2-bg: #8B97C9;  --l2-fg: #17204E;
	--l3-bg: #B4BCDE;  --l3-fg: #17204E;
	--l4-bg: #DDE2F0;  --l4-fg: #17204E;

	/* The one accent: free periods, alerts, the active tab */
	--free-bg: #FF5C45; --free-fg: #3E0C03; --free-on: #FF5C45;

	/* ⚠️ Le corail des aplats ne peut pas servir d'encre. `--free-on` tenait
	   les deux rôles : en clair il plafonnait à 2.88:1 sur le papier, et en
	   sombre — où il vaut un rouge presque noir, fait pour un filet — il
	   tombait à 1.19:1. La moyenne insuffisante, le seul chiffre qu'il faut
	   voir sur cet écran, était donc illisible dans le thème sombre.
	   `--free-on` reste la teinte des filets ; `--free-ink` est celle des mots
	   et des chiffres : 5.10:1 en clair, 7.45:1 en sombre. */
	--free-ink: #C2381F;

	/* Une échéance n'est pas une alerte. Le corail plein dit « ici il y a un
	   trou » ou « cette note ne passe pas » ; un test qui approche dit
	   seulement « prépare-toi ». Même famille, une octave plus bas — et du
	   coup une carte de test ne se confond plus avec une heure libre */
	--soon-bg: #FFC4B7; --soon-fg: #17204E;

	/* Brand only — logo, sign-in, splash. Never inside a data screen:
	   in there every colour carries a meaning and this one has none.
	   --brand-ink is the same hue made readable as text: the bright one
	   only reaches 2.3:1 on the paper, which fails at any size */
	--brand: #0FAFC0;
	--brand-ink: #07666F;

	--field: #DFE3EE;
	--pause: #D2D7E6;

	/* La barre d'onglets garde son fond sombre dans les deux thèmes, comme
	   toute barre d'application. C'est ce qui permet à l'onglet actif d'être
	   turquoise partout, et rend le corail à sa seule fonction : l'alerte */
	--bar-bg: #1B2557;
	--bar-fg: #EDEFF5;

	/* Le mono qui porte une valeur — notes, heures, salles — mérite plus de
	   présence que la prose autour de lui. Plus foncé que --ink-soft, sans
	   aller jusqu'à l'encre pleine des titres */
	--data: #1B2557;

	/* Ce sur quoi on agit. Le corail est pris par l'alerte, la rampe de bleus
	   par les branches, le marine par la structure : le turquoise est la seule
	   couleur libre, et « ici » et « agis ici » ne se posent jamais sur le
	   même élément */
	--act-bg: #0FAFC0;
	--act-fg: #04222A;

	/* Les deux petits gestes — corriger, supprimer — ont leur propre surface.
	   ⚠️ Elle était translucide, et une surface translucide n'a pas de couleur
	   à elle : elle prend celle du fond. Les mêmes deux boutons changeaient
	   donc de teinte de carte en carte, alors qu'ils font partout la même
	   chose. Pleines, ces quatre valeurs sont les mêmes sur les quatre bleus,
	   sur le corail et sur le papier — c'est ce qui les rend reconnaissables
	   avant d'être lus. L'encre est portée par la puce, pas par la carte. */
	--act-soft: #B1E2E9;  --act-soft-fg: #0A3F47;
	--free-soft: #F9CFCC; --free-soft-fg: #7A1A0C;

	/* ⚠️ Le bord d'un champ. Dans un panneau, le gris du champ suffit à le
	   détacher du papier de la feuille. Sur la porte d'entrée il n'y a pas de
	   feuille : le champ était posé à même la page, à 1.12:1, et disparaissait.
	   Un fond ne fait pas un contour. 3.65:1 sur la carte, ce que demande la
	   règle pour un élément qu'on doit voir sans le lire. */
	--edge: #7480AB;

	--radius: 4px;
	--gap: 9px;
	--pad: 15px;
	--shell: 620px;
}

@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		--paper: #0E1330;
		--card: #151B3C;
		--ink: #DEE3F5;
		--ink-soft: #8C97C4;
		--l1-bg: #7C88C8;  --l1-fg: #0E1330;
		--l2-bg: #5A65A6;  --l2-fg: #FFFFFF;
		--l3-bg: #3D4682;  --l3-fg: #DEE3F5;
		--l4-bg: #252B58;  --l4-fg: #DEE3F5;
		--free-bg: #FF6A54; --free-fg: #3E0C03; --free-on: #5A0C00;
		--free-ink: #FF8D7A;
		--soon-bg: #57271D; --soon-fg: #DEE3F5;
		--brand: #0FAFC0;  --brand-ink: #2FD3E3;
		--data: #DEE3F5;
		--act-bg: #0FAFC0;
		--act-fg: #04222A;
		--act-soft: #194E58;  --act-soft-fg: #A9E7EF;
		--free-soft: #55251C; --free-soft-fg: #FFC0B3;
		--edge: #646EB0;
		--field: #232C5C;
		--pause: #191F42;
		--bar-bg: #161C40;
		--bar-fg: #DEE3F5;
	}
}

:root[data-theme="dark"] {
	--paper: #0E1330;
	--card: #151B3C;
	--ink: #DEE3F5;
	--ink-soft: #8C97C4;
	--l1-bg: #7C88C8;  --l1-fg: #0E1330;
	--l2-bg: #5A65A6;  --l2-fg: #FFFFFF;
	--l3-bg: #3D4682;  --l3-fg: #DEE3F5;
	--l4-bg: #252B58;  --l4-fg: #DEE3F5;
	--free-bg: #FF6A54; --free-fg: #3E0C03; --free-on: #5A0C00;
	--free-ink: #FF8D7A;
	--soon-bg: #57271D; --soon-fg: #DEE3F5;
	--brand: #0FAFC0;  --brand-ink: #2FD3E3;
	--data: #DEE3F5;
	--act-bg: #0FAFC0;
	--act-fg: #04222A;
	--act-soft: #194E58;  --act-soft-fg: #A9E7EF;
	--free-soft: #55251C; --free-soft-fg: #FFC0B3;
	--edge: #646EB0;
	--field: #232C5C;
	--pause: #191F42;
	--bar-bg: #161C40;
	--bar-fg: #DEE3F5;
}

/* ============================================================
   3. Base
============================================================ */

*, *::before, *::after { box-sizing: border-box; }

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

body {
	margin: 0;
	background: var(--paper);
	color: var(--ink);
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 16px;
	line-height: 1.45;
	-webkit-font-smoothing: antialiased;
	overscroll-behavior-y: none;
}

/* Layout is done with flex gaps throughout, so the browser's default
   margins on headings and paragraphs only ever fight it */
h1, h2, h3, h4, p { margin: 0; }

a { color: inherit; }

img, svg { max-width: 100%; height: auto; }

:focus-visible {
	outline: 3px solid var(--free-bg);
	outline-offset: 2px;
}

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

/* ============================================================
   4. App shell

   The tab bar is fixed; the scroll area pads itself so the last
   card is never hidden behind it, home indicator included.
============================================================ */

.app {
	max-width: var(--shell);
	margin: 0 auto;
	padding: 22px var(--pad) calc(96px + env(safe-area-inset-bottom));
	min-height: 100svh;
}

.screen-head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 16px;
	margin-bottom: 18px;
}

.screen-head__text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }

/* Le gros bouton reste en bas de l'écran, pour qui a fait défiler. Celui-ci
   est pour qui vient d'arriver : ajouter ne devrait jamais demander de
   traverser dix lignes d'abord */
.add {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: var(--radius);
	background: var(--act-bg);
	color: var(--act-fg);
	font-size: 21px;
	font-weight: 500;
	line-height: 1;
	text-decoration: none;
}

/* Le `//` du bandeau revient ici, avec le même couple : le double slash, puis
   des capitales espacées. C'est la seule marque typographique que l'appli
   possède en propre, et elle ne servait qu'une fois, sur un écran.

   ⚠️ Elle s'arrête au sur-titre. Les intitulés de section — « lundi »,
   « tests à venir », « déjà passés » — restent nus : une marque posée partout
   ne distingue plus rien. Elle dit « voici de quel écran il s'agit », pas
   « voici un petit texte gris ». */
.eyebrow {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 11.5px;
	font-weight: 700;
	letter-spacing: .07em;
	text-transform: uppercase;
	line-height: 1.35;
	color: var(--ink-soft);
}

/* Le séparateur n'est pas un mot : ni le poids des capitales, ni leur
   espacement, et une encre en retrait — exactement son rôle dans le bandeau */
.eyebrow::before {
	content: "//";
	margin-right: 7px;
	font-weight: 500;
	letter-spacing: 0;
	opacity: .55;
}

.screen-title {
	font-size: 30px;
	font-weight: 700;
	letter-spacing: -.03em;
	line-height: 1.02;
	margin: 0;
	text-wrap: balance;
}

.stack {
	display: flex;
	flex-direction: column;
	gap: var(--gap);
}

/* Même taille que les instructions des formulaires : deux familles de petit
   texte suffisent, l'appli n'a pas besoin de trois */
.label {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 13.5px;
	color: var(--ink-soft);
	margin-top: 6px;
}

/* ============================================================
   5. Cards, buttons, fields
============================================================ */

/* Position posée ici et non au cas par cas : c'est ce qui permet à l'ancre
   de modification de recouvrir la carte, où qu'elle soit affichée */
.card {
	position: relative;
	border-radius: var(--radius);
	padding: 13px 14px;
	background: var(--l4-bg);
	color: var(--l4-fg);
	display: flex;
	flex-direction: column;
	gap: 4px;
	text-decoration: none;
}

.card--sci   { background: var(--l1-bg); color: var(--l1-fg); }
.card--lang  { background: var(--l2-bg); color: var(--l2-fg); }
.card--hum   { background: var(--l3-bg); color: var(--l3-fg); }
.card--alert { background: var(--free-bg); color: var(--free-fg); }
.card--soon  { background: var(--soon-bg); color: var(--soon-fg); }

/* ⚠️ Sur le corail, le texte ne se dilue pas. Ailleurs, une méta à
   `opacity: .8` reste lisible parce que le fond est calme ; sur cet
   aplat-là elle tombe à 3.98:1, et « supprimer » à .55 à 2.52:1 — sous
   la barre de l'AA, sur le seul écran qu'on lit en marchant.
   L'encre foncée est le bon choix et le blanc serait pire : 3.06:1
   contre 5.46:1. C'est l'opacité qu'il fallait retirer, pas la teinte */
.card--alert .card__meta,
.card--alert .card__note,
.card--soon .card__meta,
.card--soon .card__note { opacity: 1; }

.card__title {
	display: flex;
	align-items: baseline;
	gap: 7px;
	font-weight: 700;
	font-size: 16px;
	letter-spacing: -.015em;
	line-height: 1.15;
}

.card__meta {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 12.5px;
	line-height: 1.5;
	font-variant-numeric: tabular-nums;
	opacity: .8;
}

.emo { font-size: .92em; line-height: 1; flex: none; }

.btn {
	display: block;
	width: 100%;
	border: 0;
	border-radius: var(--radius);
	padding: 15px;
	background: var(--act-bg);
	color: var(--act-fg);
	font-family: inherit;
	font-weight: 700;
	font-size: 16px;
	letter-spacing: -.01em;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
}

/* Le corail ne sert plus qu'à l'alerte : un bouton d'enregistrement n'est
   pas une alarme, c'est l'action principale, donc turquoise comme les autres */
.btn--accent { background: var(--act-bg); color: var(--act-fg); }

/* Le secondaire d'une paire : présent, jamais concurrent */
.btn--ghost { background: var(--field); color: var(--ink); }

/* ============================================================
   Aller ailleurs n'est pas enregistrer

   Les deux étaient le même bouton : pleine largeur, turquoise, du
   poids d'un « Enregistrer ». Or « Voir la semaine » ne valide
   rien et ne mérite pas de crier aussi fort.

   Il garde le turquoise — aller quelque part est bien une action,
   et la règle des couleurs ne bouge pas — mais il se règle sur
   son texte et se range à droite, là où le pouce arrive. La
   flèche dit ce que le mot ne dit pas : ça part d'ici.

   Pas d'emoji dessus. Un emoji qui nomme la chose gagne son
   billet — 🇩🇪 pour l'allemand, 📸 pour l'appareil. Un emoji qui
   décore un verbe n'ajoute rien et fait le bruit que la barre
   d'onglets s'était déjà refusé.
============================================================ */

.go {
	align-self: flex-end;
	display: inline-flex;
	align-items: center;
	gap: 9px;
	width: auto;
	border: 0;
	border-radius: var(--radius);
	padding: 13px 17px;
	background: var(--act-bg);
	color: var(--act-fg);
	font-family: inherit;
	font-weight: 700;
	font-size: 15px;
	letter-spacing: -.01em;
	text-align: left;
	text-decoration: none;
	cursor: pointer;
}

/* Le même chevron que « voir les notes » : la flèche de Geist a une barre
   plus épaisse que sa pointe, et l'appli avait déjà son signe pour « ça
   continue par là » */
.go::after {
	content: "\203A";
	font-size: 20px;
	line-height: 0;
	transition: transform .15s ease;
}

.go:hover::after,
.go:focus-visible::after { transform: translateX(3px); }

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

.acts { display: flex; gap: 8px; }
.acts .btn { flex: 1; }
.acts .btn--ghost { flex: 0 1 38%; }

.field {
	width: 100%;
	border: 0;
	border-radius: var(--radius);
	padding: 13px;
	background: var(--field);
	color: var(--ink);
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 15px;
}

.empty {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 13.5px;
	line-height: 1.7;
	color: var(--ink-soft);
	background: var(--card);
	border-radius: var(--radius);
	padding: 20px 16px;
}

/* ============================================================
   Ce qui dit qu'il se passe quelque chose

   Un filet de 3 px, pas de 1 px : à 1 px il ressemble à une bordure
   oubliée. Turquoise parce que c'est la couleur de ce qui agit,
   et parce qu'il ne porte aucune donnée.
============================================================ */

/* ⚠️ Il ne suffit pas qu'il soit turquoise : posé sur le marine d'un cours ou
   sur un bouton de la même famille, il disparaissait. D'où l'épaisseur, et
   surtout le socle sombre qui court sous toute la largeur — c'est lui qui
   garantit que le filet se détache de ce qu'il y a derrière, quel qu'il soit */
.wait {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 100;
	height: 6px;
	background: var(--bar-bg);
	opacity: 0;
	transition: opacity .2s ease;
	pointer-events: none;
}

.wait::after {
	content: "";
	position: absolute;
	inset: 0 auto 0 0;
	width: var(--avance, 0%);
	background: var(--brand);
	box-shadow: 0 0 10px var(--brand);
	transition: width .45s ease-out;
}

.wait.is-on { opacity: 1; }

/* Inerte plutôt que désactivé : un bouton `disabled` peut être retiré de ce
   qui part au serveur, alors qu'on veut seulement éviter la deuxième tape */
.btn.is-busy {
	pointer-events: none;
	opacity: .75;
}

/* Ce qui apparaît après une action apparaît, au lieu de surgir */
.nl-flash,
.panel {
	animation: nl-arrive .22s ease-out both;
}

@keyframes nl-arrive {
	from { opacity: 0; transform: translateY(-4px); }
	to   { opacity: 1; transform: none; }
}

/* Rien de tout cela n'est nécessaire à qui préfère l'immobilité */
@media (prefers-reduced-motion: reduce) {
	.wait { transition: none; }
	.nl-flash,
	.panel { animation: none; }
	.lb { animation: none; }
}

/* ============================================================
   6. Tab bar
============================================================ */

/* ⚠️ z-index au-dessus du 1001 que `.select2-container.-acf` se donne : sans
   ça un champ fermé passait par-dessus la barre. La liste ouverte, elle,
   repasse au-dessus de tout — c'est le comportement attendu d'une liste */
.tabs {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1002;
	display: flex;
	background: var(--bar-bg);
	color: var(--bar-fg);
	padding: 0 4px calc(6px + env(safe-area-inset-bottom));
}

.tabs__item {
	position: relative;
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	/* 14 px au-dessus pour égaler l'air du dessous : 8 ici plus les 6 de la
	   barre elle-même. Des capitales à cette taille ont besoin d'interlettrage,
	   sinon elles se compactent en un bloc illisible */
	padding: 14px 2px 8px;
	font-size: 11.5px;
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: .07em;
	text-align: center;
	text-decoration: none;
	/* .5 donnait 4.26:1 sur le marine de la barre — sous l'AA pour du 10 px
	   en capitales, c'est-à-dire précisément là où il en faudrait plus */
	opacity: .72;
}

.tabs__item[aria-current="page"] { opacity: 1; color: var(--brand); }

/* A solid rule rather than a colour alone: on a bar this small, weight
   reads before hue, and it survives being looked at sideways */
.tabs__item[aria-current="page"]::before {
	content: "";
	position: absolute;
	inset: 0 14% auto;
	height: 3px;
	border-radius: 0 0 2px 2px;
	background: var(--brand);
}

/* ============================================================
   8. The week grid

   Periods down both sides, days across. Each day column is a
   subgrid, so a two-period lesson simply spans two rows and the
   whole week stays on one set of horizontal lines.
============================================================ */

.grid {
	display: grid;
	grid-template-columns: 66px repeat(5, minmax(0, 1fr)) 66px;
	gap: 5px;
}

.grid__col {
	grid-row: 1 / -1;
	display: grid;
	grid-template-rows: subgrid;
	gap: 5px;
}

.grid__head {
	display: flex;
	align-items: flex-end;
	padding: 0 0 8px 2px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: -.02em;
	color: var(--ink-soft);
	margin: 0;
}

/* Le turquoise seul ne se voyait pas assez. Le chevron de l'appli, celui qui
   dit « c'est par là », le dit mieux qu'une nuance */
.grid__day.is-today .grid__head { color: var(--brand-ink); }

/* ⚠️ `line-height: 0` dans un conteneur flex aligné sur `flex-end` fait
   tomber le signe sous le mot : sa boîte n'a pas de hauteur, donc rien à
   aligner. Ailleurs dans l'appli le même 0 marche, parce que les conteneurs
   y sont centrés */
.grid__day.is-today .grid__head::before {
	content: "\203A";
	align-self: center;
	margin-right: 6px;
	font-size: 1.15em;
	line-height: 1;
}

.grid__slot {
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding-right: 7px;
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 11.5px;
	font-variant-numeric: tabular-nums;
	line-height: 1.45;
	color: var(--ink-soft);
	text-align: right;
}

.grid__slot b { display: block; font-weight: 500; color: var(--ink); }

.grid__times--right { text-align: left; }
.grid__times--right .grid__slot { text-align: left; padding: 0 0 0 7px; }

/* A thin band the width of the week, painted before the day columns
   so a lesson running through a break covers it in its own column */
.grid__break {
	grid-column: 1 / -1;
	background: var(--pause);
	border-radius: 2px;
}

/* ============================================================
   Un cours sur une ligne

   Les mêmes règles que les cases dépliées de la grille, mais hors
   d'elle : l'accueil s'en sert pour la journée, et le panneau de
   modification pour rappeler ce qu'on touche. Sur grand écran la
   grille reprend la main avec sa propre disposition.
============================================================ */

.card--line {
	flex-direction: row;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 10px;
	padding: 11px 12px;
}

.card--line .card__when {
	display: block;
	min-width: 112px;
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 13px;
	font-variant-numeric: tabular-nums;
	opacity: .7;
}

.card--line .card__title { font-size: 15px; flex: 1; }
.card--line .card__meta--room { order: 1; margin: 0 0 0 auto; font-size: 12.5px; }
.card--line .card__note { order: 2; flex-basis: 100%; font-size: 12px; }

/* Inside the grid a card is tighter, and fills its rows */
.grid .card {
	height: 100%;
	padding: 8px 9px;
	gap: 2px;
}

/* Dans la grille sur grand écran, la ligne redevient un bloc */
@media (min-width: 860px) {
	.grid .card--line { flex-direction: column; align-items: stretch; gap: 2px; }
	.grid .card--line .card__when { display: none; }
	.grid .card--line .card__title { font-size: 13px; flex: none; }
}

.grid .card__title { font-size: 13px; gap: 5px; }
.grid .card__title--free { font-size: 13px; font-weight: 600; opacity: .85; }
.grid .card__when { display: none; }

.card__note {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 11px;
	line-height: 1.45;
	opacity: .72;
}

.card__meta--room {
	margin-top: auto;
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 11.5px;
	font-weight: 500;
	opacity: .78;
}

/* Modifier et ajouter encadrent la grille au lieu de s'ouvrir dedans : la
   grille place ses cartes sur des lignes calculées, et un panneau qui s'y
   déplierait décalerait toute la semaine sous lui */
/* ⚠️ Le panneau se confondait avec la page : fond identique, rien pour dire
   qu'on était entré quelque part. Un voile turquoise — la couleur de ce sur
   quoi on agit — et il se lit comme une pièce à part. `color-mix` le tient
   dans les deux thèmes, puisque --card bascule avec eux */
/* ⚠️ Un voile turquoise sur toute la surface agressait l'œil et jurait avec
   le gris de la page : le turquoise est un signal, pas un fond. Ce qui
   sépare ici, c'est l'élévation — une feuille posée sur le papier — et le
   signal se réduit à un filet sur la tranche.

   `.adder[open]` prend le même habit : ajouter et modifier sont le même
   moment, et rien ne justifiait qu'ils ne se ressemblent pas. */
.panel,
.adder[open] {
	margin-bottom: 22px;
	padding: 14px;
	border-left: 3px solid var(--act-bg);
	border-radius: var(--radius);
	background: var(--card);
	box-shadow: 0 1px 3px rgba(27, 37, 87, .09), 0 8px 24px rgba(27, 37, 87, .07);
	/* L'ancre amène ici : de l'air au-dessus, sinon on arrive collé au bord */
	scroll-margin-top: 14px;
}

/* Le sommaire d'un dépliant ouvert est son titre, pas un bouton de plus */
.adder[open] > summary {
	background: none;
	color: var(--ink);
	padding: 0 0 4px;
	text-align: left;
	font-size: 15px;
}
.page-template-template-week .panel { margin-bottom: 26px; }
.week-add { margin-top: 26px; }

@media (min-width: 860px) {
	/* Once the five days sit side by side, the reading width of the rest
	   of the app is the wrong constraint — a grid wants room. Capped all
	   the same: past this, columns get wider without getting clearer.
	   The class is WordPress's own, from the page template file name. */
	.page-template-template-week .app { max-width: 1240px; }
}

/* On a phone the grid is unreadable: the days unfold, the time columns
   step aside, and each block carries its own hours instead */
@media (max-width: 859px) {
	.grid { display: flex; flex-direction: column; gap: 24px; }
	.grid__col { display: flex; flex-direction: column; gap: 5px; }
	.grid__times, .grid__break { display: none; }

	.grid__head { font-size: 19px; padding-bottom: 4px; }

	.grid .card {
		height: auto;
		flex-direction: row;
		align-items: baseline;
		flex-wrap: wrap;
		gap: 10px;
		padding: 11px 12px;
	}
	.grid .card__when {
		display: block;
		min-width: 112px;
		font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
		font-size: 12.5px;
		font-variant-numeric: tabular-nums;
		opacity: .7;
	}
	.grid .card__title { font-size: 15px; flex: 1; }
	/* La salle passe avant la précision dans l'ordre visuel : sans ça, un
	   cours qui porte une note repousse sa salle en troisième ligne et le
	   rythme heure / matière / salle se casse sur cette seule ligne */
	.grid .card__meta--room { order: 1; margin: 0 0 0 auto; font-size: 12.5px; }
	/* Toute la largeur : décalée sous l'heure, une précision de deux mots
	   passait à la ligne pour rien */
	.grid .card__note { order: 2; flex-basis: 100%; padding-left: 0; font-size: 12px; }

	/* Dépliée, la carte range sa salle en haut à droite — là où le crayon se
	   tenait. La carte lui fait sa place au lieu de le laisser mordre sur le
	   code de salle */
	.grid .card { padding-right: 38px; }

	/* ⚠️ Centré verticalement, il flottait au milieu des blocs hauts — deux
	   périodes, ou un cours qui porte une précision. Il se cale sur la
	   première ligne, celle où se tient la salle, et n'en bouge plus */
	.grid .edit__mark {
		top: 11px;
		right: 8px;
		font-size: 17px;
	}

	/* Un rappel de durée, pas une proportion : doubler vraiment la hauteur
	   coûterait un tiers de défilement en plus pour redire ce que l'heure
	   affichée dit déjà */
	.grid .card.is-long-2 { min-height: 70px; }
	.grid .card.is-long-3 { min-height: 100px; }
}

/* ============================================================
   9. The report card

   Where the mono stops: it is for what aligns or is read digit by
   digit — hours, grades, room codes, counters. A sentence set in
   mono reads slower and says nothing extra.
============================================================ */

.counters {
	display: flex;
	gap: 5px;
}

/* ⚠️ Les compteurs prenaient le premier ton de la rampe des branches, ce qui
   n'a jamais eu de sens : ce ne sont pas des branches. Ça tenait tant que ce
   ton était marine ; la rampe éclaircie, ils perdaient tout leur poids.
   Le marine des barres est le bon jeton — il ne bouge pas avec le thème,
   pour la même raison qu'eux : ce sont des chiffres qu'on lit de loin */
.counter {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 2px;
	background: var(--bar-bg);
	color: var(--bar-fg);
	border-radius: var(--radius);
	padding: 12px 11px;
}

.counter.is-alert { background: var(--free-bg); color: var(--free-fg); }

.counter__value {
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 22px;
	font-weight: 500;
	line-height: 1;
	font-variant-numeric: tabular-nums;
}

.counter__unit { font-size: 13px; font-weight: 600; line-height: 1.2; }

.counter__note {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 11px;
	line-height: 1.35;
	opacity: .72;
}

.counters__caveat {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 12.5px;
	line-height: 1.6;
	color: var(--ink-soft);
}

/* --- one line of the bulletin --- */

.lines { display: flex; flex-direction: column; gap: 8px; }

/* Le titre, les notes et ce qui manque se touchaient : trois informations
   de nature différente méritent de ne pas se lire comme un bloc */
.line {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: baseline;
	column-gap: 12px;
	row-gap: 5px;
	/* ⚠️ Une teinte une ligne sur deux séparait les lignes sans les délimiter :
	   la moitié d'entre elles n'avait aucun fond, et le rayon de 2 px ne
	   ressemblait à rien d'autre dans l'appli. Chaque ligne prend sa propre
	   feuille, comme une fiche — même papier, même rayon, même ombre d'un
	   pixel — et l'espace entre elles fait le reste.
	   Le fond étant maintenant à la ligne, ce sont ses bords qui portent la
	   marge : les quatre `padding-left: 9px` posés au cas par cas ont disparu */
	padding: 13px 12px;
	background: var(--card);
	border-radius: var(--radius);
	box-shadow: 0 1px 2px rgba(27, 37, 87, .07);
}

.line__name {
	display: flex;
	align-items: baseline;
	gap: 7px;
	flex-wrap: wrap;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: -.015em;
}

.line__off,
.line__missing {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 11px;
	font-weight: 400;
	letter-spacing: 0;
	color: var(--ink-soft);
}

.line__detail {
	grid-column: 1;
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 12px;
	line-height: 1.5;
	color: var(--data);
}

.line__value {
	grid-column: 2;
	grid-row: 1 / span 2;
	align-self: center;
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 19px;
	font-weight: 500;
	font-variant-numeric: tabular-nums;
}

.line.is-low .line__value { color: var(--free-ink); }

.line__missing { grid-column: 1; }

/* --- adding a grade --- */

.adder { margin-top: 4px; }

.adder > summary {
	list-style: none;
	cursor: pointer;
}

.adder > summary::-webkit-details-marker { display: none; }

/* L'habillage du sommaire ouvert est plus bas, avec celui du panneau :
   ajouter et modifier sont le même moment */
.adder__body { padding-top: var(--gap); }

.nl-flash:empty { display: none; }

.nl-flash {
	background: var(--l3-bg);
	color: var(--l3-fg);
	border-radius: var(--radius);
	padding: 12px 14px;
	font-size: 14px;
	font-weight: 600;
	margin-bottom: var(--gap);
}

/* ACF renders its own markup: only the few things worth aligning
   with the rest of the app are touched here */
.nl-form .acf-field { margin-bottom: 12px; }

.nl-form .acf-label label {
	font-size: 13.5px;
	font-weight: 600;
	color: var(--ink-soft);
}

.nl-form .acf-input input[type="text"],
.nl-form .acf-input input[type="number"],
.nl-form .acf-input input[type="file"],
.nl-form .acf-input textarea,
.nl-form .acf-input select,
.nl-form .acf-input .acf-input-wrap input {
	width: 100%;
	border: 0;
	border-radius: var(--radius);
	padding: 12px;
	background: var(--field);
	color: var(--ink);
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 16px; /* under 16px, iOS zooms the page on focus */
}

/* Ce qui se lit chiffre par chiffre garde le mono : une note, une date, un
   nombre de périodes. Ce qu'on écrit en mots ne le garde pas — le mono
   ralentit la lecture d'une phrase sans rien lui apprendre */
.nl-form .acf-input input[type="number"],
.nl-form .acf-field-date-picker .acf-input input[type="text"] {
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-variant-numeric: tabular-nums;
}

.nl-form .acf-input textarea {
	min-height: 110px;
	resize: vertical;
	line-height: 1.55;
}

/* La règle groupée ci-dessus donne déjà le Geist, les 16 px et le fond : seul
   le rembourrage change, parce que le bouton natif que ce champ contient est
   plus haut qu'une ligne de texte.
   (Le commentaire qui était ici parlait de la dictée et de la hauteur d'une
   zone de texte — il avait suivi le mauvais bloc lors d'un déplacement.) */
.nl-form .acf-input input[type="file"] { padding: 11px 12px; }

/* Le bouton du navigateur, seul élément natif que l'appli montre encore. En
   thème sombre il sortait blanc à filets, et rien ne disait que c'était là
   qu'on appuie. Turquoise, comme tout ce sur quoi on agit */
.nl-form .acf-input input[type="file"]::file-selector-button {
	margin-right: 12px;
	border: 0;
	border-radius: var(--radius);
	padding: 9px 14px;
	background: var(--act-bg);
	color: var(--act-fg);
	font-family: inherit;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: -.01em;
	cursor: pointer;
}

.nl-form .acf-notice { border-radius: var(--radius); }

/* ACF prints its instructions in body size above the input; here they are
   a caption under the label, like everywhere else in the app */
.nl-form .acf-field .description {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 12px;
	line-height: 1.5;
	color: var(--ink-soft);
	margin: 5px 0 0;
}

/* The field group sets 33% widths inline, which is right in the admin and
   unusable on a phone. Inline styles need !important to be undone */
@media (max-width: 620px) {
	.nl-form .acf-field { width: 100% !important; }
}

/* ⚠️ ACF pose ses filets et ses fonds en gris clair codés en dur — #eaecf0
   entre deux champs, #ccd0d4 et #f9f9f9 dans le répéteur. En thème clair ils
   passent pour la nuance discrète qu'on voit partout ailleurs ; en thème
   sombre ce sont des traits blancs sur du marine, et c'était vrai de tous les
   formulaires, pas seulement du dernier. Tout revient sur les jetons */
.nl-form .acf-fields > .acf-field { border-top-color: var(--pause); }

/* ⚠️ Le !important n'est pas de l'entêtement : acfe-input.css pose ces
   filets en !important lui-même, et rien d'autre ne les défait */
.nl-form .acf-repeater .acf-row > td,
.nl-form .acf-repeater .acf-row-handle,
.nl-form .acf-repeater .acf-row .acf-field {
	border: 0 !important;
	background: none !important;
}

/* Le filet de droite de la poignée est visé plus précisément encore : il
   faut aller le chercher au même niveau, sinon il survit à tout le reste */
.nl-form .acf-repeater.-block > table > tbody > tr > td.acf-row-handle {
	border: 0 !important;
	background: none !important;
}

/* ============================================================
   Le répéteur — « ce qu'il y a à réviser »

   Le seul champ d'ACF qui n'est pas une simple boîte, et le seul
   endroit où l'admin transparaissait : un tableau à filets, des
   numéros de ligne, une bascule bleue, un lien souligné. Rien à
   réparer dans le HTML — ACF le produit et il est correct —, tout
   à réapprendre en CSS.

   Une ligne à réviser est une ligne à cocher : c'est la même chose
   que .todo sur la carte du test, et elle finit par lui ressembler.
============================================================ */

.nl-form .acf-repeater,
.nl-form .acf-repeater .acf-table,
.nl-form .acf-repeater tbody,
.nl-form .acf-repeater tr,
.nl-form .acf-repeater td {
	display: block;
	border: 0;
	padding: 0;
	background: none;
}

/* ACF colle son tableau à son cadre par des marges négatives. Le cadre
   retiré, elles font grimper la première ligne sur le libellé du champ */
.nl-form .acf-repeater .acf-table { margin: 0; }

/* Les filets du tableau, plus spécifiques que la règle groupée ci-dessus,
   et posés en dur en gris clair : illisibles dans le thème sombre */
.nl-form .acf-repeater .acf-table > tbody > tr > td { border: 0; }

.nl-form .acf-repeater tbody {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.nl-form .acf-repeater .acf-row {
	display: flex;
	align-items: center;
	gap: 10px;
	background: var(--field);
	border-radius: var(--radius);
	padding: 7px 9px;
}

/* Le numéro de ligne ne dit rien qu'on ne voie : l'ordre est l'ordre */
.nl-form .acf-repeater .acf-row-handle.order { display: none; }

.nl-form .acf-repeater .acf-row > .acf-fields {
	flex: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	gap: 10px;
}

.nl-form .acf-repeater .acf-row .acf-field {
	width: auto !important;
	float: none;
	margin: 0;
	padding: 0;
}

.nl-form .acf-repeater .acf-field-nl-todo-label { flex: 1; min-width: 0; }
.nl-form .acf-repeater .acf-field-nl-todo-done  { flex: none; }

/* Les libellés se répètent à chaque ligne et n'apprennent rien après la
   première : retirés de l'œil, gardés pour qui écoute la page */
.nl-form .acf-repeater .acf-row .acf-label {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.nl-form .acf-repeater .acf-row input[type="text"] {
	padding: 8px 10px;
	background: var(--card);
	font-size: 16px;
}

/* La bascule Oui/Non d'ACF redevient la case qu'elle est, et la même
   que sur la carte du test : vide, ou pleine et cochée */
.nl-form .acf-repeater .acf-true-false label { display: block; margin: 0; }

.nl-form .acf-repeater .acf-switch {
	position: relative;
	display: block;
	width: 26px;
	height: 26px;
	min-width: 0;
	border: 0;
	border-radius: 3px;
	background: var(--card);
	overflow: hidden;
}

.nl-form .acf-repeater .acf-switch.-on { background: var(--act-bg); }

.nl-form .acf-repeater .acf-switch-on,
.nl-form .acf-repeater .acf-switch-off,
.nl-form .acf-repeater .acf-switch-slider { display: none; }

.nl-form .acf-repeater .acf-switch.-on::after {
	content: "✓";
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--act-fg);
	font-size: 14px;
	font-weight: 700;
}

/* Ajouter une ligne se fait par le bouton du bas ; le + de la ligne
   ferait deux façons de faire la même chose, et le dupliqueur une
   troisième que personne n'a demandée */
.nl-form .acf-repeater .acf-row-handle.remove {
	flex: none;
	display: flex;
	align-items: center;
	width: 26px;
}

.nl-form .acf-repeater .acf-row-handle.remove .acf-icon.-plus,
.nl-form .acf-repeater .acf-row-handle.remove .acf-icon.-duplicate { display: none; }

/* ⚠️ ACF ne dévoile le retrait d'une ligne qu'au survol de la ligne, et le
   sort du flux pour le poser sur le coin. Sur le téléphone de Gab il n'y a
   pas de survol : la ligne était tout simplement indéracinable. Remis dans
   le flux et visible en permanence — discret comme « supprimer » ailleurs
   dans l'appli, mais atteignable au doigt */
.nl-form .acf-repeater .acf-row-handle.remove .acf-icon.-minus {
	display: flex !important;
	position: static;
	margin: 0;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	border: 0;
	border-radius: 3px;
	/* ACF le peint en blanc pur, ce qui éclate dans le thème sombre */
	background-color: var(--card);
	color: var(--ink-soft);
	opacity: .5;
	box-shadow: none;
}

.nl-form .acf-repeater .acf-row-handle.remove .acf-icon.-minus:hover,
.nl-form .acf-repeater .acf-row-handle.remove .acf-icon.-minus:focus-visible {
	opacity: 1;
}

/* ACF fait flotter son bouton à droite, ce qui vide la hauteur du bloc et
   fait retomber « Ajouter une ligne » sur l'instruction */
.nl-form .acf-repeater .acf-actions {
	display: flex;
	padding: 0;
	margin-top: 10px;
}

.nl-form .acf-repeater .acf-actions .clear { display: none; }
.nl-form .acf-repeater .acf-button { float: none; }

/* Le secondaire d'un formulaire, comme Annuler : présent, jamais
   concurrent du bouton qui enregistre */
.nl-form .acf-repeater .acf-button {
	display: inline-block;
	width: auto;
	height: auto;
	border: 0;
	border-radius: var(--radius);
	padding: 11px 15px;
	background: var(--field);
	color: var(--ink);
	font-family: inherit;
	font-size: 14px;
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: -.01em;
	text-decoration: none;
	text-shadow: none;
	box-shadow: none;
	cursor: pointer;
}

.nl-form .acf-repeater .acf-button:hover { background: var(--pause); color: var(--ink); }

/* ============================================================
   10. Tests and sheets
============================================================ */

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

.todo__row { display: flex; align-items: baseline; gap: 8px; font-size: 13.5px; line-height: 1.35; }

/* ⚠️ Deux corrections successives. D'abord : pas d'opacité pour dire « fait ».
   Sur le corail elle tombait à 2.30:1, et aucun réglage ne la sauvait — d'où
   la barre qui traversait le mot.
   Puis la liste a quitté la carte colorée pour son propre papier clair, et le
   raisonnement avec elle : sur --card, une encre plus claire est une couleur
   qui se mesure, pas un voile. --ink-soft donne 6.63:1 en clair et 5.85:1 en
   sombre, et la ligne se relit encore.
   La barre, elle, traversait aussi la coche : dire deux fois « fait », c'est
   une fois de trop, et la case cochée le disait déjà. */
.todo__row.is-done .todo__text { color: var(--ink-soft); }

.todo__box {
	flex: none;
	width: 17px; height: 17px;
	border-radius: 2px;
	background: var(--field);
	display: inline-flex; align-items: center; justify-content: center;
	font-size: 11.5px;
	transform: translateY(2px);
}

.card.is-past { opacity: .62; }

/* --- filters --- */

.filters { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 16px; }

.filters__item {
	display: inline-flex; align-items: baseline; gap: 6px;
	background: var(--l4-bg); color: var(--l4-fg);
	border-radius: var(--radius);
	padding: 7px 11px;
	font-size: 13.5px; font-weight: 600;
	text-decoration: none;
}

.filters__item.is-on { background: var(--bar-bg); color: var(--bar-fg); }

.filters__count {
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 11.5px; opacity: .7;
}

/* ============================================================
   La journée est finie

   Le titre annonce « Aujourd'hui » en grand ; le soir, il n'y a
   plus d'aujourd'hui à montrer. Ce bloc dit ce que l'écran répond
   à ce moment-là, et enchaîne sur la seule question qui reste :
   quand ça reprend.
============================================================ */

.done {
	display: flex;
	flex-direction: column;
	gap: 3px;
	background: var(--card);
	border-radius: var(--radius);
	padding: 15px 14px;
	box-shadow: 0 1px 2px rgba(27, 37, 87, .07);
}

.done__word {
	font-size: 19px;
	font-weight: 700;
	letter-spacing: -.02em;
	line-height: 1.15;
}

/* L'heure se lit chiffre par chiffre, comme partout ailleurs */
.done__next {
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 13px;
	color: var(--data);
	font-variant-numeric: tabular-nums;
}

/* --- the wall --- */

.wall {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
	gap: 10px;
}

/* Photo, titre, date et gestes se posaient à même le papier de la page : rien
   ne disait où finissait une fiche et où commençait la suivante, sinon la
   gouttière. Chacune prend sa propre feuille, et la grille redevient lisible */
.sheet {
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
	background: var(--card);
	border-radius: var(--radius);
	padding: 6px 6px 8px;
	box-shadow: 0 1px 2px rgba(27, 37, 87, .07);
}

.sheet__shot {
	display: block;
	aspect-ratio: 3 / 4;
	border-radius: var(--radius);
	overflow: hidden;
	background: var(--field);
}

.sheet__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Une fiche dont le titre tient sur deux lignes ne doit pas descendre ses
   deux boutons plus bas que sa voisine : la grille étire déjà les feuilles à
   la même hauteur, les gestes se posent au fond de la leur */
.sheet__meta {
	flex: 1;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 1px;
	padding: 0 2px;
}

/* Redevenue un titre après avoir été un lien que personne ne trouvait :
   c'est un bouton nommé qui mène à la correction */
.sheet__label {
	display: inline-flex;
	align-items: baseline;
	gap: 6px;
	min-width: 0;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: -.01em;
	line-height: 1.2;
}

.sheet__date {
	display: flex;
	align-items: baseline;
	gap: 10px;
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 11.5px;
	color: var(--ink-soft);
}

/* ============================================================
   11. The view-as bar
============================================================ */

.viewas {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 6px 14px;
	background: var(--l4-bg);
	color: var(--l4-fg);
	padding: calc(8px + env(safe-area-inset-top))
	         max(var(--pad), calc((100% - var(--shell)) / 2 + var(--pad)))
	         8px;
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 12.5px;
}

/* Borrowed, not owned: the bar turns turquoise the whole time you are
   reading somebody else's carnet, so it can never be forgotten */
.viewas.is-on {
	background: var(--brand);
	color: #04222A;
}

.viewas__links { display: flex; flex-wrap: wrap; gap: 12px; margin-left: auto; }
.viewas__links a { text-decoration: none; border-bottom: 2px solid currentColor; }

/* ============================================================
   12. Deleting
============================================================ */

.line__more { grid-column: 1 / -1; padding-top: 4px; }

/* Un chevron plutôt qu'un soulignement : souligner annonce un lien vers
   ailleurs, alors que ceci ouvre sur place. Le chevron pivote en s'ouvrant
   et dit donc aussi dans quel état on se trouve.
   La puce est celle de « ajouter une ligne » : toutes les actions de l'appli
   ont la même forme, et celle-ci en est une — c'est ici, et nulle part
   ailleurs, qu'une note se corrige ou se supprime */
.line__more > summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	list-style: none;
	cursor: pointer;
}

.line__more > summary::-webkit-details-marker { display: none; }

/* Le compte est une donnée, pas une action : il garde sa voix basse */
.line__count {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 11.5px;
	color: var(--ink-soft);
}

.marks {
	list-style: none;
	margin: 8px 0 2px;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 3px;
}

/* Le rayon de l'appli, comme la ligne qui la contient. Le 2 px restant sur
   la case à cocher, les vignettes et la bande de pause est voulu : sur un
   carré de dix-sept pixels, quatre pixels de rayon en font un galet */
.mark {
	position: relative;
	display: flex;
	align-items: baseline;
	gap: 10px;
	background: var(--field);
	border-radius: var(--radius);
	padding: 6px 9px;
}

.mark__value {
	min-width: 30px;
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 14px;
	font-weight: 500;
	font-variant-numeric: tabular-nums;
}

.mark__subject {
	font-size: 13px;
	font-weight: 600;
	letter-spacing: -.01em;
}

.mark__date {
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 12px;
	color: var(--data);
}

/* Toute la carte, toute la ligne, mène à sa correction. L'ancre la recouvre
   et ne se voit pas : un lien « modifier » écrit dans une case de la grille,
   ou sous une note haute de six millimètres, coûterait une ligne dans les
   endroits les plus serrés de l'appli pour nommer ce qu'on vient de toucher */
.edit {
	position: absolute;
	inset: 0;
	border-radius: inherit;
}

/* Le crayon dit que la case se touche. Discret — il y en a vingt-quatre —
   mais présent, parce qu'un geste qu'il faut deviner n'est pas un geste */
.pencil {
	width: 1em;
	height: 1em;
	vertical-align: -.14em;
	flex: none;
}

.edit__mark {
	position: absolute;
	top: 7px;
	right: 8px;
	font-size: 15px;
	line-height: 0;
	opacity: .5;
}

.edit:hover .edit__mark,
.edit:focus-visible .edit__mark { opacity: 1; }

.edit:focus-visible {
	outline: 2px solid var(--act-bg);
	outline-offset: 2px;
}

/* Discret, mais plus invisible. Il l'était par prudence, du temps où une tape
   suffisait à détruire ; c'est la question « sûr ? » qui protège maintenant,
   et un contrôle qu'on ne trouve pas n'est pas prudent, il est raté.
   Un fond rosé et un coin arrondi — le rayon de l'appli, pas une pilule.
   Il passe au-dessus de l'ancre de modification, et c'est le partage voulu :
   la grande cible facile est réversible, la petite est définitive */
.kill { position: relative; z-index: 1; display: inline-flex; margin-left: auto; }

/* ⚠️ Le fond était un color-mix vers `transparent` — donc pas un fond, un
   voile. Sur les quatre bleus, sur le corail et sur le papier, la même puce
   prenait six teintes, et il fallait six exceptions pour la rattraper.
   Pleine, elle n'en demande aucune : elle porte sa surface et son encre, et
   ne dépend plus de ce qu'il y a dessous. */
.kill__btn {
	display: inline-flex;
	align-items: center;
	border: 0;
	border-radius: var(--radius);
	padding: 5px 9px;
	background: var(--free-soft);
	color: var(--free-soft-fg);
	cursor: pointer;
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 13px;
	line-height: 1;
}

/* La croix dit ce que fait le mot avant qu'on l'ait lu */
.kill__btn .pencil { margin-right: 6px; color: currentColor; }

.kill__btn:hover,
.kill__btn:focus-visible {
	background: var(--free-bg);
	color: var(--free-fg);
}

/* ⚠️ Supprimer ne demandait rien : une tape et le contenu partait. Sur un
   téléphone le pouce se pose vite, et une note perdue fausse les trois
   compteurs. Deux temps plutôt qu'une fenêtre modale : le mot devient une
   question, et il faut y répondre. Sans JavaScript, le formulaire part
   directement — c'est le comportement d'avant, pas une régression */
/* Le jumeau turquoise : même forme, même taille, sens opposé — et pleine
   pour la même raison que sa jumelle */
.fix {
	position: relative;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	border-radius: var(--radius);
	padding: 5px 9px;
	background: var(--act-soft);
	color: var(--act-soft-fg);
	text-decoration: none;
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 13px;
	line-height: 1;
}

.fix .pencil { margin-right: 6px; color: currentColor; }

.fix:hover,
.fix:focus-visible { background: var(--act-bg); color: var(--act-fg); }

/* Les deux gestes vont ensemble et se tiennent à droite */
.acts-row {
	display: flex;
	align-items: center;
	gap: 6px;
	margin-left: auto;
}

.acts-row .kill { margin-left: 0; }

/* Sur une fiche, ils occupent leur propre ligne et se partagent la largeur :
   une tuile fait 170 px, deux mots complets côte à côte n'y tiennent pas si
   on les laisse à leur taille */
.sheet__acts { display: flex; align-items: stretch; gap: 5px; margin-top: 5px; }
.sheet__acts .kill { margin-left: 0; flex: 1; }
.sheet__acts .fix { flex: 1; }

.sheet__acts .fix,
.sheet__acts .kill__btn {
	justify-content: center;
	width: 100%;
	padding: 6px 4px;
	font-size: 11.5px;
}

.sheet__acts .fix .pencil,
.sheet__acts .kill__btn .pencil { margin-right: 5px; }

.sheet__top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }

/* La sortie, en tête du panneau */
.label--panel { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }

.quit {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 12px;
	color: var(--ink-soft);
	text-decoration: none;
	border-bottom: 1px solid currentColor;
}

.quit:hover { color: var(--free-ink); }

/* La question, elle, ne se rate pas : le fond se remplit */
.kill.is-asking .kill__btn {
	opacity: 1;
	font-weight: 700;
	background: var(--free-bg);
	color: var(--free-fg);
}

.kill.is-asking .kill__btn .pencil { color: inherit; }

/* ============================================================
   Consulter une fiche

   Le seul endroit de l'appli où l'on lit au lieu d'écrire. Sur un
   fond sombre dans les deux thèmes, comme la barre d'onglets et
   pour la même raison : une photo de feuille blanche se lit contre
   du sombre, et un voile clair par-dessus un écran clair ne dit
   plus qu'on a quitté la liste.
============================================================ */

.lb {
	width: 100%;
	max-width: 100%;
	height: 100%;
	max-height: 100%;
	margin: 0;
	padding: 0;
	border: 0;
	/* Le voile est porté par la boîte elle-même et non par ::backdrop :
	   le rendu de ::backdrop dépend du navigateur, celui-ci ne dépend de
	   rien. Fermer en appuyant à côté marche pareil, le gestionnaire vise
	   la boîte et son cadre */
	background: rgba(8, 11, 28, .96);
	color: var(--bar-fg);
	overflow: hidden;
}

.lb::backdrop { background: rgba(8, 11, 28, .96); }

.lb__frame {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 100%;
	padding: 52px 14px 128px;
}

.lb__img {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
	border-radius: var(--radius);
}

.lb__close {
	position: absolute;
	z-index: 1;
	top: 10px;
	right: 12px;
	width: 40px;
	height: 40px;
	border: 0;
	border-radius: var(--radius);
	background: var(--bar-bg);
	color: var(--bar-fg);
	font-size: 24px;
	line-height: 1;
	cursor: pointer;
}

.lb__bar {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 16px;
	padding: 14px var(--pad) calc(14px + env(safe-area-inset-bottom));
	background: var(--bar-bg);
}

.lb__said { min-width: 0; }

.lb__label {
	font-size: 16px;
	font-weight: 700;
	letter-spacing: -.015em;
	margin: 0;
}

.lb__sub {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 12.5px;
	opacity: .75;
	margin: 3px 0 0;
}

/* Dicté au moment de la photo, et jamais relu jusqu'ici. Les retours à la
   ligne de la dictée sont tout ce qui reste de sa mise en forme */
.lb__note {
	white-space: pre-line;
	font-size: 13px;
	line-height: 1.5;
	opacity: .9;
	margin: 8px 0 0;
	max-height: 5.2em;
	overflow-y: auto;
}

.lb__note[hidden] { display: none; }

.lb__nav {
	flex: none;
	display: flex;
	align-items: center;
	gap: 4px;
}

.lb__nav[hidden] { display: none; }

.lb__step {
	width: 40px;
	height: 40px;
	border: 0;
	border-radius: var(--radius);
	background: rgba(255, 255, 255, .12);
	color: var(--bar-fg);
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
}

.lb__step:hover { background: rgba(255, 255, 255, .22); }

.lb__count {
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 12px;
	opacity: .7;
	padding: 0 6px;
	font-variant-numeric: tabular-nums;
}

/* La vignette annonce qu'elle s'ouvre */
.sheet__shot,
.revise__shot { cursor: zoom-in; }

/* Les fiches d'un test, sur sa carte. Au-dessus de l'ancre qui recouvre la
   carte, sans quoi ouvrir une photo mènerait à modifier le test.
   Le bloc empile : la rangée de vignettes, puis le bouton qui en ajoute une —
   il appartient à ce qu'il nourrit, comme « ajouter une ligne » à sa liste */
.revise {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 9px;
	margin-top: 2px;
}

.revise__shots { display: flex; flex-wrap: wrap; gap: 10px; padding-top: 6px; }

/* ⚠️ La pastille déborde du coin : posée dessus, elle mangeait un cinquième
   d'une vignette de 54 px et volait des tapes destinées à la photo. Dehors,
   les deux cibles ne se chevauchent plus — c'est ce qui permet à la vignette
   de rester entièrement ouvrable. La gouttière et le retrait du haut lui font
   la place qu'elle prend en débordant */
.revise__one { position: relative; flex: none; }

.untie { position: absolute; top: -6px; right: -6px; z-index: 2; }

.untie__btn {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	border: 2px solid var(--card);
	border-radius: 50%;
	padding: 0;
	background: var(--free-soft);
	color: var(--free-soft-fg);
	cursor: pointer;
	line-height: 0;
}

.untie__btn .pencil { width: .78em; height: .78em; }

.untie__btn:hover,
.untie__btn:focus-visible { background: var(--free-bg); color: var(--free-fg); }

.untie__btn:focus-visible { outline: 2px solid var(--act-bg); outline-offset: 2px; }

.revise__shot {
	display: block;
	width: 54px;
	height: 54px;
	border-radius: 3px;
	overflow: hidden;
	background: var(--card);
}

.revise__shot img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.revise__shot:focus-visible {
	outline: 2px solid var(--act-bg);
	outline-offset: 2px;
}

/* ============================================================
   13. The front door

   The first thing seen every morning, so it gets air rather than
   a form crammed at the top. WordPress prints its own markup here;
   only what matters is restyled.
============================================================ */

.gate {
	max-width: 340px;
	margin: 0 auto;
	padding: 8vh 4px 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 20px;
}

.gate__logo { width: 108px; height: auto; }

.gate__head { display: flex; flex-direction: column; align-items: center; gap: 7px; }

/* L'enseigne du bandeau, sur du clair. Deux mots, deux encres — c'est ce qui
   fait qu'on reconnaît l'appli avant même de l'avoir ouverte */
.gate__name {
	font-size: 34px;
	font-weight: 700;
	letter-spacing: -.03em;
	line-height: 1;
}

.gate__one { color: var(--ink); }

/* ⚠️ J'avais mis `--brand-ink` en appliquant la règle de contraste du texte —
   2.31:1 sur le papier, ça échoue. Mauvaise règle : **un logotype n'est pas du
   texte.** La norme l'exempte explicitement, et pour une raison qui se vérifie
   à l'œil — un mot de 34 px en graisse 800, isolé, qu'on ne lit pas mais qu'on
   reconnaît. Le turquoise vif est la marque ; le foncer, c'était l'affadir pour
   satisfaire une règle qui ne s'appliquait pas. */
.gate__two { color: var(--brand); }

/* Le `//` du bandeau et des sur-titres, une troisième fois : c'est ce qui en
   fait la marque de l'appli plutôt qu'un ornement de page */
.gate__line {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 11.5px;
	font-weight: 700;
	letter-spacing: .07em;
	text-transform: uppercase;
	color: var(--ink-soft);
}

.gate__line::before {
	content: "//";
	margin-right: 7px;
	font-weight: 500;
	letter-spacing: 0;
	opacity: .55;
}

.gate__error {
	width: 100%;
	background: var(--free-bg);
	color: var(--free-fg);
	border-radius: var(--radius);
	padding: 11px 13px;
	font-size: 13.5px;
	font-weight: 600;
}

/* Le formulaire est une feuille posée sur la page, comme un panneau ou une
   fiche : c'est ce qui rassemble les deux champs en un seul objet, et ce qui
   donne au gris des champs un fond sur lequel se détacher */
#nl-login {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: 12px;
	background: var(--card);
	border-radius: var(--radius);
	padding: 18px 16px;
	box-shadow: 0 1px 3px rgba(27, 37, 87, .09), 0 8px 24px rgba(27, 37, 87, .07);
}

#nl-login p { display: flex; flex-direction: column; gap: 5px; margin: 0; }

#nl-login label {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 12px;
	color: var(--ink-soft);
}

#nl-login input[type="text"],
#nl-login input[type="password"] {
	width: 100%;
	border: 1px solid var(--edge);
	border-radius: var(--radius);
	padding: 12px;
	background: var(--field);
	color: var(--ink);
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 16px; /* under 16px, iOS zooms the page on focus */
}

/* Où l'on écrit se voit : le turquoise de l'action, et un halo de sa version
   pâle — le même couple que les puces d'action */
#nl-login input[type="text"]:focus,
#nl-login input[type="password"]:focus {
	outline: 0;
	border-color: var(--act-bg);
	box-shadow: 0 0 0 3px var(--act-soft);
}

/* Remember me sits inline: it is a choice, not a field */
#nl-login .login-remember {
	flex-direction: row;
	align-items: center;
	gap: 8px;
}

/* La seule case native que l'appli montre encore. Le bleu du système n'est
   dans aucune de ses deux palettes : `accent-color` la met au ton sans
   remplacer la case, donc sans rien coûter au clavier ni aux lecteurs d'écran */
#nl-login .login-remember input[type="checkbox"] {
	accent-color: var(--act-bg);
	width: 17px;
	height: 17px;
	margin: 0;
}

#nl-login .login-remember label {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 13px;
	color: var(--ink);
}

#nl-login input[type="submit"] {
	width: 100%;
	border: 0;
	border-radius: var(--radius);
	padding: 15px;
	background: var(--act-bg);
	color: var(--act-fg);
	font-family: inherit;
	font-weight: 700;
	font-size: 16px;
	letter-spacing: -.01em;
	cursor: pointer;
}

.gate__lost {
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 12px;
	color: var(--ink-soft);
	text-decoration: none;
	border-bottom: 2px solid currentColor;
}

/* « Aujourd'hui » est le mot le plus long de la barre : sur un iPhone SE
   les quatre onglets tombent à 78 px et il n'y aurait plus de marge */
@media (max-width: 360px) {
	.tabs__item { font-size: 10.5px; letter-spacing: .05em; }
}

/* ACF remplace les menus déroulants par Select2 : le <select> natif reste dans
   la page à 1 px de haut, et tout mon habillage tombait dessus sans rien faire.
   C'est la boîte rendue par Select2 qu'il faut viser. Le texte y reste en Geist,
   parce qu'un nom de branche est un mot et non une valeur qui s'aligne. */

.nl-form .select2-container { width: 100% !important; }

/* Le rembourrage à droite fait la place aux deux contrôles : le chevron au
   bord, le bouton de déliaison juste avant */
.nl-form .select2-container--default .select2-selection--single {
	height: auto;
	border: 0;
	border-radius: var(--radius);
	background: var(--field);
	padding: 12px;
	padding-right: 104px;
}

.nl-form .select2-container--default .select2-selection--single .select2-selection__rendered {
	padding: 0;
	line-height: 1.35;
	font-size: 16px;
	color: var(--ink);
}

.nl-form .select2-container--default .select2-selection--single .select2-selection__placeholder {
	color: var(--ink-soft);
}

.nl-form .select2-container--default .select2-selection--single .select2-selection__arrow {
	height: 100%;
	right: 12px;
}

/* ⚠️ Select2 fait flotter sa croix à droite pendant que le chevron y est posé
   en absolu : les deux se superposaient, et le résultat ne ressemblait à aucun
   des deux. Elle mesurait 8 px de large — sous le pouce, ce n'était pas un
   bouton raté, ce n'était pas un bouton.
   Et personne ne devinait ce qu'elle faisait. Un « ✕ » seul dit « ferme » ou
   « supprime » aussi bien que « détache » ; ici il détache une fiche de son
   test, et rien d'autre. Le mot le dit, la puce rosée dit que ça retire.
   La croix d'origine reste dans le document pour le clavier et les lecteurs
   d'écran — elle est seulement rendue à zéro. */
.nl-form .select2-container--default .select2-selection--single .select2-selection__clear {
	position: absolute;
	top: 50%;
	right: 38px;
	transform: translateY(-50%);
	float: none;
	margin: 0;
	display: inline-flex;
	align-items: center;
	height: 28px;
	padding: 0 9px;
	border-radius: var(--radius);
	background: var(--free-soft);
	color: var(--free-soft-fg);
	font-family: "Geist", "Helvetica Neue", Arial, sans-serif;
	font-size: 0;
	font-weight: 600;
	line-height: 1;
	cursor: pointer;
}

.nl-form .select2-container--default .select2-selection--single .select2-selection__clear::before {
	content: "\2715\00a0 d\00e9lier";
	font-size: 12px;
}

.nl-form .select2-container--default .select2-selection--single .select2-selection__clear:hover {
	background: var(--free-bg);
	color: var(--free-fg);
}

.nl-form .select2-container--default.select2-container--focus .select2-selection--single,
.nl-form .select2-container--default.select2-container--open .select2-selection--single {
	outline: 3px solid var(--act-bg);
	outline-offset: 2px;
}

/* ⚠️ La liste déroulante n'est pas dans le formulaire : Select2 l'accroche
   au <body>. Tous les habillages écrits en `.nl-form …` la manquaient, et
   elle sortait en blanc à filets — au-dessus de la barre d'onglets, ce qui
   la faisait passer pour cassée. Elle se vise donc sans préfixe */
.select2-container--default .select2-dropdown {
	border: 0;
	border-radius: var(--radius);
	background: var(--card);
	box-shadow: 0 10px 30px rgba(8, 11, 28, .28);
	overflow: hidden;
}

.select2-container--open { z-index: 1003; }

.select2-container--default .select2-search--dropdown { padding: 8px; }

.select2-container--default .select2-search--dropdown .select2-search__field {
	border: 0;
	border-radius: var(--radius);
	padding: 11px;
	background: var(--field);
	color: var(--ink);
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	/* Le zoom d'iOS guette aussi ce champ-là */
	font-size: 16px;
}

.select2-container--default .select2-results__option {
	padding: 12px 14px;
	font-size: 15px;
	color: var(--ink);
	background: transparent;
}

/* `body` en tête pour l'emporter : la feuille de Select2 est chargée après
   celle du thème et la règle serait sinon à égalité — d'où le bleu vif qui
   restait sur l'option visée */
body .select2-container--default .select2-results__option--highlighted[aria-selected],
body .select2-container--default .select2-results__option--highlighted,
body .select2-container--default .select2-results__option--selected {
	background: var(--field);
	color: var(--ink);
}

.select2-container--default .select2-results__message {
	padding: 12px 14px;
	font-size: 13px;
	color: var(--ink-soft);
}

/* Assez de place pour que la liste tienne sans recouvrir la barre : au pire
   elle bascule au-dessus du champ, ce que Select2 sait faire tout seul */
.select2-container--default .select2-results > .select2-results__options {
	max-height: 46vh;
}

/* Dans le panneau, la fiche se montre en grand : c'est la seule chose qui
   dise laquelle on corrige, puisque la photo n'est pas dans le formulaire */
/* Le panneau est déjà une feuille : une feuille sur une feuille ne sépare
   plus rien */
.sheet--panel { margin: 0; max-width: 220px; background: none; padding: 0; box-shadow: none; }

/* ============================================================
   Une fiche écrite

   Pas de photo, donc pas de vignette : la tuile montre le texte
   lui-même. Le papier de l'appli plutôt que le blanc d'une photo,
   pour qu'on voie du premier coup d'œil laquelle est laquelle.
============================================================ */

/* ⚠️ Un filet, ici, n'est pas un ornement : la tuile écrite a le papier du
   bloc qui la porte, donc sans lui le texte flotte sans bord. C'est la
   nuance de pause, celle qui sépare déjà les périodes */
.sheet__shot--texte,
.revise__shot--texte {
	display: block;
	/* Le papier de la page, pas celui de la feuille qui la porte : la tuile
	   écrite est posée sur une fiche, elle ne peut pas avoir son fond */
	background: var(--paper);
	border: 1px solid var(--pause);
	border-radius: var(--radius);
	overflow: hidden;
	/* C'est une ancre : sans ça, tout le vocabulaire arrive souligné */
	text-decoration: none;
}

.sheet__shot--texte { padding: 14px; min-height: 150px; cursor: pointer; }
.revise__shot--texte { padding: 7px; }

.ecrite {
	display: -webkit-box;
	-webkit-line-clamp: 8;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: 13px;
	line-height: 1.5;
	color: var(--ink);
	white-space: pre-line;
}

.revise__shot--texte .ecrite {
	-webkit-line-clamp: 4;
	font-size: 8.5px;
	line-height: 1.35;
}

/* ⚠️ Une fiche écrite montrait son texte dans la barre du bas, marine sur
   marine et légendée en haut — soit l'inverse d'une photo. Elle occupe
   maintenant la place de la photo, sur du papier clair, et la légende reste
   où elle est pour tout le monde */
.lb__page {
	width: 100%;
	max-width: 560px;
	max-height: 100%;
	overflow-y: auto;
	padding: 22px 20px;
	border-radius: var(--radius);
	background: var(--card);
	color: var(--ink);
	font-size: 16px;
	line-height: 1.6;
	white-space: pre-line;
}

.lb__page[hidden] { display: none; }

/* ============================================================
   L'enseigne, sur le seul écran qui en porte une

   Les autres écrans sont des pages de l'appli ; celui-ci en est
   la porte. Plus grand qu'un titre d'écran pour se distinguer,
   pas au point de voler la vedette à la journée qui suit.
============================================================ */

/* ============================================================
   L'enseigne, en bandeau

   Marine plein, comme la barre d'onglets — et pour la même raison :
   une barre d'application ne change pas avec le thème. Les encres
   s'inversent, le turquoise reste sur « Lab ».

   ⚠️ Le logo est dessiné pour un fond clair : son trait est le
   marine du bandeau, il y disparaîtrait. Il garde donc son papier,
   une petite tuile claire — ce qui le fait lire comme une marque
   plutôt que comme un ornement. Un logo en version claire ferait
   mieux le jour où il existe.
============================================================ */

/* Le bandeau est un frère de `.app`, pas son premier enfant : il va donc d'un
   bord à l'autre tout seul, comme la barre d'onglets, sans une seule unité
   `vw` — celles-ci comptent la barre de défilement et débordent la page
   d'autant.

   ⚠️ Son rembourrage réaligne son contenu sur celui de la colonne :
   `(100% - shell) / 2` place le bord de la colonne, `+ var(--pad)` son
   contenu. Sans ce dernier terme le logo se retrouve quinze pixels à gauche
   du titre juste en dessous — c'est le décalage qu'avait la barre « voir en
   tant que », corrigé du même coup.

   `env(safe-area-inset-top)` va dedans et non au-dessus : sur l'iPhone en mode
   plein écran, c'est le marine qui doit passer sous l'horloge, pas du papier. */
.brand {
	display: flex;
	align-items: flex-end;
	flex-wrap: wrap;
	gap: 4px 10px;
	padding: calc(20px + env(safe-area-inset-top))
	         max(var(--pad), calc((100% - var(--shell)) / 2 + var(--pad)))
	         18px;
	background: var(--bar-bg);
	color: var(--bar-fg);
}

/* Quand la barre « tu regardes le carnet de… » est là, c'est elle qui touche
   le haut : le bandeau n'a plus d'encoche à absorber */
.viewas ~ .brand { padding-top: 20px; }

.brand__mark {
	flex: none;
	width: 34px;
	height: 34px;
	padding: 3px;
	border-radius: var(--radius);
	background: var(--paper);
}

.brand__name {
	margin: 0;
	font-size: 22px;
	font-weight: 700;
	letter-spacing: -.025em;
	line-height: 1;
}

/* Tout en gras : « Note » prend l'encre du bandeau, « Lab » la marque */
.brand__one { color: var(--bar-fg); }
.brand__two { color: var(--brand); }

/* Le séparateur n'est pas un mot : il ne prend ni le poids ni l'encre */
.brand__slash {
	font-size: 16px;
	font-weight: 500;
	opacity: .45;
}

/* ⚠️ Ni turquoise — pris par la marque et par l'action — ni corail, qui est
   l'alerte. Il reste l'encre du bandeau, à qui les capitales et le gras
   donnent la présence que la couleur ne lui donne pas */
.brand__line {
	margin: 0;
	font-size: 12.5px;
	font-weight: 700;
	letter-spacing: .07em;
	text-transform: uppercase;
	opacity: .78;
}

/* La sortie : présente, jamais sous le pouce */
.bye {
	margin-top: 26px;
	text-align: center;
	font-size: 13px;
}

.bye a {
	color: var(--ink-soft);
	text-decoration: none;
	border-bottom: 1px solid currentColor;
}

.bye a:hover { color: var(--free-ink); }

/* Deux sorties, une ligne : le point médian les sépare sans les hiérarchiser */
.bye__dot { color: var(--ink-soft); margin: 0 9px; opacity: .6; }

/* ============================================================
   L'aide

   Le mode d'emploi, dans l'appli. Il emprunte la grammaire de ce
   qu'il explique — la feuille des panneaux, la rampe des branches
   pour les quatre onglets, les puces d'action pour montrer les
   boutons dont il parle. Un mode d'emploi qui ne ressemble pas à
   l'appli demande un effort de traduction à chaque paragraphe.
============================================================ */

.aide {
	display: flex;
	flex-direction: column;
	gap: 9px;
	background: var(--card);
	color: var(--ink);
	border-left: 3px solid var(--act-bg);
	border-radius: var(--radius);
	padding: 15px 16px;
	box-shadow: 0 1px 2px rgba(27, 37, 87, .07);
	font-size: 15px;
	line-height: 1.55;
}

.aide__title { font-size: 17px; font-weight: 700; letter-spacing: -.015em; }

/* Les quatre onglets prennent les quatre marches de la rampe : la même
   couleur qui distingue une branche d'une autre distingue ici une section */
.aide--tab { border-left: 0; padding: 0; gap: 0; overflow: hidden; }

.aide__head {
	display: flex;
	align-items: baseline;
	gap: 10px;
	padding: 12px 16px;
	font-size: 18px;
	font-weight: 700;
	letter-spacing: -.02em;
}

.aide__body {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 14px 16px 16px;
}

.aide--l1 .aide__head { background: var(--l1-bg); color: var(--l1-fg); }
.aide--l2 .aide__head { background: var(--l2-bg); color: var(--l2-fg); }
.aide--l3 .aide__head { background: var(--l3-bg); color: var(--l3-fg); }
.aide--l4 .aide__head { background: var(--l4-bg); color: var(--l4-fg); }

/* Ce sur quoi il faut faire attention prend le filet de l'alerte, comme
   partout ailleurs */
.aide--warn { border-left-color: var(--free-bg); }
.aide--warn b { color: var(--free-ink); }
.aide--warn p { font-size: 14.5px; }

.aide--fix { border-left-color: var(--free-bg); }

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

.points li { position: relative; padding-left: 17px; }

.points li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .62em;
	width: 6px;
	height: 6px;
	border-radius: 1px;
	background: var(--act-bg);
}

/* Les trois chiffres de la promotion se lisent chiffre par chiffre */
.regles {
	list-style: none;
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
	background: var(--field);
	border-radius: var(--radius);
	padding: 12px 13px;
}

.regles li { display: flex; align-items: baseline; gap: 10px; font-size: 14.5px; }

.regles b {
	flex: none;
	min-width: 3.4em;
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 15px;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	color: var(--data);
}

/* Montrer le bouton dont on parle, à sa taille et dans sa couleur : décrire
   « la petite croix rosée » demande de la chercher, la montrer non */
.montre {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	border-radius: var(--radius);
	padding: 1px 6px;
	font-size: .87em;
	font-weight: 600;
	white-space: nowrap;
}

.montre--act { background: var(--act-soft); color: var(--act-soft-fg); }
.montre--free { background: var(--free-soft); color: var(--free-soft-fg); }

.depanne { margin: 0; display: flex; flex-direction: column; }

.depanne__row {
	display: grid;
	gap: 2px;
	padding: 10px 0;
	border-bottom: 1px solid var(--pause);
}

.depanne__row:first-child { padding-top: 0; }
.depanne__row:last-child { padding-bottom: 0; border-bottom: 0; }

.depanne dt {
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 12.5px;
	color: var(--free-ink);
}

.depanne dd { margin: 0; font-size: 14.5px; }

@media (min-width: 560px) {
	.depanne__row { grid-template-columns: 15em 1fr; gap: 18px; align-items: baseline; }
}

.signe {
	margin-top: 8px;
	text-align: center;
	font-size: 14px;
	line-height: 1.7;
	color: var(--ink-soft);
}

.signe__menace {
	display: inline-block;
	margin-top: 6px;
	color: var(--free-ink);
	font-weight: 600;
}

/* ============================================================
   Un test

   La même grammaire qu'un cours : ce qui situe dans le temps à
   gauche, ce qui nomme au milieu, la branche à droite. Le compte
   à rebours passe sous la date, en gras — c'est lui qu'on vient
   chercher, et il était noyé entre deux points médians.

   Ce qui suit — à réviser, fiches, gestes — descend sur toute la
   largeur.
============================================================ */

/* Deux colonnes, deux lignes. Deux tailles de texte et pas six : le thème
   porte le poids, tout le reste se lit au même corps */
.card--test { gap: 10px; padding: 14px; }

/* ⚠️ Deux colonnes flex côte à côte, chacune empilant ses deux lignes : la
   première rangée s'alignait, la seconde partait en biais. Deux colonnes,
   ce sont deux suites de hauteurs de ligne indépendantes, et rien ne les
   raccorde.
   Une seule grille, et l'alignement sur la ligne de base redevient une
   propriété de la rangée : la date tient la branche, le décompte tient le
   thème. La colonne 2 ne porte que l'emoji — c'est elle qui fait que le
   thème se ferre au nom de la branche, pas à l'emoji. */
.card--test .card__head {
	display: grid;
	/* ⚠️ 92 px fixes coupaient « dans 3 jours » en deux, et la seconde rangée
	   se retrouvait à cheval sur deux lignes — l'alignement était juste, ce
	   qui l'occupait ne l'était pas. La colonne prend la largeur du plus long
	   des deux, et le mono tabulaire l'empêche de danser d'une carte à l'autre */
	grid-template-columns: auto auto 1fr;
	row-gap: 3px;
	align-items: baseline;
}

.card--test .card__date,
.card--test .card__left {
	grid-column: 1;
	padding-right: 12px;
	font-family: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
	font-size: 13px;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.card--test .card__date { grid-row: 1; font-weight: 500; opacity: .8; }
.card--test .card__left { grid-row: 2; font-weight: 700; }

.card--test .card__head > .emo { grid-area: 1 / 2; padding-right: 7px; }
.card--test .card__title { grid-area: 1 / 3; display: block; min-width: 0; }

/* Le thème sous la branche, plus petit mais gras : c'est ce qui tombe au
   test, pas une légende. Plus petit dit le rang, gras dit qu'on le lit */
.card--test .card__theme {
	grid-area: 2 / 3;
	margin: 0;
	font-size: 13px;
	font-weight: 700;
	line-height: 1.25;
}

/* ⚠️ L'urgence ne change plus le fond : une branche garde sa teinte partout,
   c'est la règle. Elle prend la tranche, comme le panneau prend la sienne */
.card--test.is-soon { border-left: 3px solid var(--free-on); }

/* Ce qu'il y a à revoir et les fiches se posent sur du papier clair, comme
   une fiche écrite. Ça les sépare de l'en-tête au lieu de tout empiler */
.card--test .todo,
.card--test .revise {
	background: var(--card);
	color: var(--ink);
	border-radius: var(--radius);
	padding: 11px 12px;
	margin: 0;
}

.card--test .revise { gap: 8px; }

.card--test .todo__row { font-size: 14px; }

/* ============================================================
   Réviser depuis la liste

   Cocher est le geste le plus fréquent de l'appli. Il se fait à
   même la carte, dans le même bloc de papier clair que ce qu'il
   y a à revoir — pas dans un formulaire qu'il faut ouvrir.
============================================================ */

.revision {
	background: var(--card);
	color: var(--ink);
	border-radius: var(--radius);
	padding: 11px 12px;
}

/* Le bloc porte déjà le papier : la liste qu'il contient n'en remet pas */
.revision .todo { background: none; padding: 0; }

.todo__pick {
	display: flex;
	align-items: baseline;
	gap: 9px;
	cursor: pointer;
}

/* La vraie case reste là pour le clavier et les lecteurs d'écran ; c'est le
   carré dessiné qui se voit, parce qu'une case native ne se met pas au ton */
.todo__pick input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

.todo__pick .todo__box { color: transparent; transition: none; }
.todo__pick input:checked + .todo__box { color: var(--act-fg); background: var(--act-bg); }
.todo__pick input:focus-visible + .todo__box { outline: 2px solid var(--act-bg); outline-offset: 2px; }

/* ⚠️ Le champ tenait toute la largeur en permanence, pour un geste qui vient
   après la lecture : il pesait plus que la liste qu'il sert. Il se replie
   derrière la même petite puce que « ajouter une fiche » — deux ajouts
   voisins, une seule forme — et le chevron dit que ça s'ouvre */
.todo__more { margin-top: 9px; }
.todo__more > summary { list-style: none; cursor: pointer; }
.todo__more > summary::-webkit-details-marker { display: none; }

.fix--more .chev {
	display: inline-block;
	width: 0; height: 0;
	margin-right: 8px;
	border-left: 5px solid currentColor;
	border-top: 4px solid transparent;
	border-bottom: 4px solid transparent;
	transition: transform .15s ease;
}

details[open] > summary .chev { transform: rotate(90deg); }

/* Ajouter une ligne se fait en révisant, pas en remplissant un formulaire */
.todo__add {
	display: flex;
	align-items: stretch;
	gap: 6px;
	margin-top: 9px;
}

.todo__add input[type="text"] {
	flex: 1;
	min-width: 0;
	border: 0;
	border-radius: var(--radius);
	padding: 9px 10px;
	background: var(--field);
	color: var(--ink);
	font-family: inherit;
	/* 16 px, sinon iOS grossit la page à la mise au point */
	font-size: 16px;
}

.todo__go {
	flex: none;
	border: 0;
	border-radius: var(--radius);
	padding: 0 14px;
	background: var(--act-bg);
	color: var(--act-fg);
	font-family: inherit;
	font-size: 13px;
	font-weight: 700;
	cursor: pointer;
}

/* Rattacher une fiche part d'ici mais se fait là-bas : le bouton emmène à la
   capture, le test déjà choisi. Le « + » des boutons d'ajout de l'appli, à la
   taille d'une puce — son voisin garde le chevron, parce qu'il déplie au lieu
   d'emmener */
.fix--sheet .plus {
	margin-right: 7px;
	font-size: 15px;
	font-weight: 600;
	line-height: 0;
}
