/* Le Bon Voisin — une seule feuille, mobile d'abord.
   
   Le parti pris : premium, mais goût village, et une palette d'ENFANCE. La
   facture est celle de lease — jetons de couleur, bandeau translucide,
   mot-marque en serif, bloc peint, ombres douces. La couleur, elle, est un bleu
   d'atelier posé sur un papier crème : le bleu pour la confiance et le calme
   (c'est aussi celui des friperies en ligne, donc un terrain familier), le
   crème pour la chaleur, l'ambre pour le grenier. Le rouge ne sert plus
   d'identité — il ne dit plus qu'une erreur.

   Et une déco qui parle de vêtements : le CINTRE, en marque du grenier, en
   filigrane du bloc peint, et devant le nom de l'app. Trois silhouettes — body,
   tee-shirt, sweat — disent l'âge d'un enfant plus vite qu'un nombre.

   Aucune police n'est chargée de l'extérieur : la CSP interdit tout ce qui vient
   d'ailleurs, et un empilement système fait le travail.

   Deux règles apprises à la dure et qu'il ne faut pas défaire :
   - aucun style EN LIGNE dans les gabarits : `style-src 'self'` les ignore
     SILENCIEUSEMENT, ce qui donne des pages presque justes ;
   - [hidden] doit gagner contre display, sinon un élément « caché » reste
     visible et avale les clics. */

:root {
	--bg: #f6f3ec;            /* papier chaud */
	--bg-elev: #fcfaf5;       /* le creux d'une carte : champs, cellules */
	--card: #ffffff;
	--ink: #1f2429;           /* une encre à peine bleutée, plus fraîche que le brun */
	--muted: #66707a;
	--line: #e3e0d7;
	--line-forte: #cfd0c9;
	/* Le liseré des logos de plateforme : assez pâle pour disparaître sur une
	   icône pleine, assez net pour tenir lieu de bord à celle du Bon Coin, qui
	   est blanche. */
	--logo-bord: rgba(0, 0, 0, 0.14);

	--accent: #1b6a86;        /* l'accent principal : le bleu de l'atelier */
	--accent-2: #2b8aa8;      /* le même, éclairci, pour les dégradés */
	--accent-ink: #ffffff;
	--accent-douce: #e3f0f5;
	--accent-puce: #0f4c62;   /* le texte sur accent-douce, contraste AA */

	--volet: #3d7d63;         /* le vert des volets : ce qu'on peut prendre */
	--volet-douce: #e4f1ea;
	--volet-ink: #2c5b48;
	--marine: #3f5f8a;        /* ce qu'on peut passer */
	--marine-douce: #e8eef7;
	--ocre: #b8761d;          /* le grenier, le troc, et les chiffres */
	--ocre-douce: #fbeeda;
	/* L'encre de l'ocre manquait, et ça s'est vu au premier nombre écrit en gros
	   sur fond pâle : 3,25 de contraste, sous le seuil lisible. Les autres
	   couleurs de cette palette ont les trois tons ; celle-ci n'en avait que
	   deux, et rien ne le signalait tant qu'on n'y écrivait que du petit. */
	--ocre-ink: #8a5712;
	--alerte: #a3342c;        /* et RIEN d'autre que les erreurs */
	--alerte-douce: #fbe9e7;

	/* Les quatre familles d'outils. Seize dessins gris étaient un mur
	   d'outillage, pas un village — et c'est la remarque qui a fait naître ces
	   jetons. Mais une couleur ne se pose pas ici pour égayer : elle DIT la
	   famille, donc on trouve la sienne avant d'avoir lu un seul mot, comme la
	   teinte d'une pastille d'enfant dit le genre. Le mot reste écrit dessous,
	   toujours : l'information n'est jamais portée par la seule couleur.

	   Aucune des quatre n'est le bleu de l'app, et c'est délibéré : c'est lui qui
	   dit « coché », et une famille qui porterait sa teinte ferait passer une case
	   vide pour une case cochée. L'ambre reprend la valeur de --ocre et le vert
	   celle de --volet — même teinte, autre sens, donc un autre nom. */
	--outil-bricoler: #b8761d;        /* l'établi : la sciure et le bois */
	--outil-bricoler-douce: #fbeeda;
	--outil-bricoler-ink: #8a5712;
	--outil-jardiner: #3d7d63;        /* le vert des volets, et du jardin */
	--outil-jardiner-douce: #e4f1ea;
	--outil-jardiner-ink: #2c5b48;
	--outil-chantier: #b0563a;        /* la brique et la terre cuite */
	--outil-chantier-douce: #fbe8e1;
	--outil-chantier-ink: #83402b;
	--outil-transporter: #4f63b8;     /* le bleu de travail, franchement plus
	                                     violet que l'accent pour qu'on ne les
	                                     confonde pas */
	--outil-transporter-douce: #e9ecfa;
	--outil-transporter-ink: #3a4a8d;
	--outil-recevoir: #8a5595;        /* la prune : une fête, et rien d'autre
	                                     dans la feuille ne la porte */
	--outil-recevoir-douce: #f5eaf7;
	--outil-recevoir-ink: #6b3f76;

	/* Fille, garçon, peu importe. Trois teintes franchement distinctes, dont
	   aucune n'est celle de l'app : une pastille ne doit pas se confondre avec
	   un bouton. Et la couleur ne porte JAMAIS l'information seule — chaque
	   pastille écrit aussi le mot. */
	--fille: #c2557a;
	--fille-douce: #fbe9ef;
	--fille-ink: #943c5a;
	--garcon: #4f63b8;
	--garcon-douce: #e9ecfa;
	--garcon-ink: #3a4a8d;
	--mixte: #77808a;
	--mixte-douce: #edeef1;
	--mixte-ink: #565e67;

	--radius: 18px;
	--radius-md: 14px;
	--radius-sm: 10px;
	--pilule: 999px;

	--ombre-sm: 0 1px 2px rgba(36, 29, 22, 0.05), 0 1px 3px rgba(36, 29, 22, 0.04);
	--ombre-md: 0 6px 20px rgba(36, 29, 22, 0.08);
	--ombre-lg: 0 16px 40px rgba(36, 29, 22, 0.14);

	/* Le bloc peint de l'accueil a ses propres jetons : un bleu profond sous un
	   texte presque blanc, et des chiffres AMBRE — c'est ce contraste chaud sur
	   froid qui fait la chaleur, un bleu seul serait un bandeau de banque. Le
	   dégradé reste dans la même famille : un dégradé bleu → vert vire au cyan
	   en route. */
	--peint-a: #1b6a86;
	--peint-b: #114a61;
	--peint-ink: #f0fafd;
	--peint-chiffre: #ffd79a;

	--font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	--font-titre: ui-serif, "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Noto Serif", serif;

	/* La barre du bas est mesurée ici : le contenu s'en écarte, elle ne le
	   recouvre jamais. */
	/* 5 + 52 + 5 : l'air repris autour des trois onglets compte dans ce que le
	   contenu doit laisser libre en bas de page. */
	--barre-h: calc(62px + env(safe-area-inset-bottom));

	color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
	:root {
		--bg: #0f1417;
		--bg-elev: #151b1f;
		--card: #1a2126;
		--ink: #e6ebee;
		--muted: #97a2ab;
		--line: #263036;
		--line-forte: #334049;
		--logo-bord: rgba(255, 255, 255, 0.22);

		--accent: #6ec1da;
		--accent-2: #8ed2e7;
		--accent-ink: #06232e;
		--accent-douce: #15303a;
		--accent-puce: #a5dced;

		--volet: #7fc3a3;
		--volet-douce: #16291f;
		--volet-ink: #a3dbc0;
		--marine: #93aede;
		--marine-douce: #1a2233;
		--ocre: #e0b062;
		--ocre-douce: #2e2413;
		--ocre-ink: #edc888;

		--fille: #e79ab5;
		--fille-douce: #33202a;
		--fille-ink: #f2bacd;
		--garcon: #97a6ea;
		--garcon-douce: #1f2340;
		--garcon-ink: #b9c3f4;
		--mixte: #9aa4ae;
		--mixte-douce: #232a30;
		--mixte-ink: #bcc5cd;
		--alerte: #e59a93;
		--alerte-douce: #331e1c;

		--outil-bricoler: #e0b062;
		--outil-bricoler-douce: #2e2413;
		--outil-bricoler-ink: #edc888;
		--outil-jardiner: #7fc3a3;
		--outil-jardiner-douce: #16291f;
		--outil-jardiner-ink: #a3dbc0;
		--outil-chantier: #e5a48c;
		--outil-chantier-douce: #2f1d16;
		--outil-chantier-ink: #f0bfae;
		--outil-transporter: #97a6ea;
		--outil-transporter-douce: #1f2340;
		--outil-transporter-ink: #b9c3f4;
		--outil-recevoir: #c99ad4;
		--outil-recevoir-douce: #2b1f2e;
		--outil-recevoir-ink: #e2c3ea;

		--peint-a: #16505f;
		--peint-b: #0b3341;
		--peint-ink: #eaf7fb;
		--peint-chiffre: #ffd193;

		--ombre-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
		--ombre-md: 0 6px 20px rgba(0, 0, 0, 0.45);
		--ombre-lg: 0 16px 40px rgba(0, 0, 0, 0.5);
	}
}

* {
	box-sizing: border-box;
}

body {
	margin: 0;
	background: var(--bg);
	color: var(--ink);
	font: 16px/1.55 var(--font);
	-webkit-text-size-adjust: 100%;
}

/* --- le bandeau ---------------------------------------------------------- */

.bandeau {
	position: sticky;
	top: 0;
	z-index: 30;
	background: color-mix(in srgb, var(--bg) 84%, transparent);
	backdrop-filter: saturate(1.5) blur(12px);
	border-bottom: 1px solid var(--line);
	padding-top: env(safe-area-inset-top);
}

.bandeau-dedans {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	max-width: 640px;
	margin: 0 auto;
	padding: 11px 16px;
}

/* Le nom du village en romain, encré du dégradé bleu → ocre : la seule
   fantaisie de la page, et elle tient en une ligne. La couleur pleine est posée
   d'abord, pour le navigateur qui ne clipperait pas le fond. */
.marque-lien {
	display: inline-flex;
	gap: 9px;
	align-items: center;
	min-width: 0;
	text-decoration: none;
}

.marque {
	font-family: var(--font-titre);
	font-size: 1.28rem;
	font-weight: 700;
	letter-spacing: 0.01em;
	color: var(--accent);
	background: linear-gradient(100deg, var(--accent) 40%, var(--ocre));
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	text-decoration: none;
}

.bouton-icone {
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid var(--line);
	border-radius: var(--pilule);
	background: var(--card);
	color: var(--muted);
	cursor: pointer;
}

.bouton-icone svg {
	width: 19px;
	height: 19px;
}

.bouton-icone:hover,
.bouton-icone:focus-visible {
	color: var(--alerte);
	border-color: var(--alerte);
}

/* --- la barre du bas ---------------------------------------------------- */

/* TOUTES CES RÈGLES SONT PRÉFIXÉES .barre, et ce n'est pas du zèle : le nom
   « onglet » est pris DEUX FOIS dans cette feuille — ici, et pour les onglets de
   la recherche (vêtements / chaussures / outils). Les seconds venant plus bas,
   ils gagnaient à égalité de spécificité : la barre du bas héritait donc du fond
   plein et du rayon des onglets de recherche, et le commentaire juste en dessous
   — « un point plutôt qu'un fond » — décrivait une intention que la feuille
   annulait en silence depuis le jour où le second .onglet est né. Mesuré au
   navigateur : fond rgb(27,106,134) et border-radius 999px sur un onglet censé
   n'avoir qu'un point de 5 px.

   Une classe déjà prise dans une feuille unique ne lève aucune erreur. */
.barre {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 50;
	display: flex;
	/* De l'air entre les trois, et sur les bords : sans lui, les zones
	   tactiles se touchent d'un bord à l'autre de l'écran et la pastille de
	   l'onglet actif colle à ses deux voisines. Trois boutons collés se lisent
	   comme un bandeau, pas comme une navigation. */
	gap: 6px;
	padding: 5px 10px calc(5px + env(safe-area-inset-bottom));
	background: color-mix(in srgb, var(--bg) 88%, transparent);
	backdrop-filter: saturate(1.4) blur(12px);
	border-top: 1px solid var(--line);
}

.barre .onglet {
	display: flex;
	flex: 1 1 0;
	min-width: 0;
	position: relative;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 3px;
	/* 52 et non 44 : c'est la hauteur de la zone tactile, et elle reste
	   confortablement au-dessus du minimum même une fois l'air repris. */
	height: 52px;
	padding: 4px 2px;
	border-radius: var(--pilule);
	color: var(--muted);
	font-size: 0.7rem;
	font-weight: 650;
	text-decoration: none;
}

.barre .onglet svg {
	width: 22px;
	height: 22px;
}

.barre .onglet.actif {
	background: var(--accent);
	color: var(--accent-ink);
}

@media (max-width: 330px) {
	.onglet-mot {
		display: none;
	}
}

/* --- le contenu ---------------------------------------------------------- */

.contenu {
	max-width: 640px;
	margin: 0 auto;
	/* La barre du bas ne recouvre jamais la fin d'une page — un formulaire dont
	   le dernier bouton passe dessous est un formulaire qu'on ne valide pas. */
	padding: 14px 16px calc(var(--barre-h) + 28px);
}

h1 {
	margin: 14px 0 4px;
	font-family: var(--font-titre);
	font-size: 1.55rem;
	font-weight: 700;
	letter-spacing: -0.01em;
}

h2 {
	margin: 0 0 8px;
	font-family: var(--font-titre);
	font-size: 1.16rem;
	font-weight: 700;
}

h2 em,
.carte-titre em {
	color: var(--muted);
	font-family: var(--font);
	font-size: 0.72em;
	font-style: normal;
	font-weight: 500;
}

/* Le titre d'une carte de réglage. Un h3 parce qu'il vit sous un intertitre —
   « Comment j'entre » et les trois cartes qui y répondent — mais il ouvre un
   paragraphe, là où les autres h3 de l'app tiennent dans une ligne d'en-tête
   (le nom d'un voisin, celui d'un village) : il lui faut donc l'air que le
   margin: 0 de h3 ne donne pas. */
.carte-titre {
	margin: 0 0 8px;
}

h3 {
	margin: 0;
	font-family: var(--font-titre);
	font-size: 1.1rem;
	font-weight: 700;
}

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

.titre-section {
	margin: 26px 0 2px;
	font-size: 0.78rem;
	font-weight: 700;
	font-family: var(--font);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--muted);
}

.baseline,
.sous-titre {
	margin: 2px 0 12px;
	color: var(--muted);
	font-size: 0.92rem;
}

/* Un sous-titre qui porte des raccourcis. Ils ont leur propre boîte : à la suite
   de la phrase, deux liens successifs se lisaient comme une suite de mots —
   « … d'abord. Changer l'ordre Chercher ». Un seul passait encore ; le second
   l'a montré. Ils se replient sous la phrase dès que l'écran ne suffit plus. */
.sous-titre.avec-liens {
	display: flex;
	flex-wrap: wrap;
	gap: 2px 14px;
	align-items: baseline;
}

.sous-titre-liens {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 14px;
}

.sous-titre .lien {
	font-weight: 600;
	white-space: nowrap;
}

/* --- le bloc peint ------------------------------------------------------- */

.resume {
	position: relative;
	overflow: hidden;
	margin: 4px 0 18px;
	padding: 16px 18px 18px;
	border-radius: var(--radius);
	background: linear-gradient(140deg, var(--peint-a), var(--peint-b));
	color: var(--peint-ink);
	box-shadow: var(--ombre-md);
}

.resume-titre {
	margin: 0 0 10px;
	font-size: 0.74rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	opacity: 0.82;
}

.resume-chiffres {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 7px;
	margin: 0;
	font-size: 0.92rem;
}

.resume-valeur {
	font-family: var(--font-titre);
	font-size: 1.85rem;
	font-weight: 700;
	line-height: 1;
	color: var(--peint-chiffre);
	font-variant-numeric: tabular-nums;
}

.resume-point {
	opacity: 0.5;
}

.resume-mot {
	margin: 12px 0 0;
	font-size: 0.92rem;
	opacity: 0.9;
}

/* --- les cartes ---------------------------------------------------------- */

.carte {
	margin: 12px 0;
	padding: 16px;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--card);
	box-shadow: var(--ombre-sm);
}

.carte-tete {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 8px;
}

.lieu {
	color: var(--muted);
	font-size: 0.85rem;
}

.mot {
	margin: 8px 0 0;
	color: var(--ink);
	font-family: var(--font-titre);
	font-size: 1rem;
	font-style: italic;
	opacity: 0.88;
}

.macaron {
	padding: 3px 9px;
	border-radius: var(--pilule);
	background: var(--volet-douce);
	color: var(--volet-ink);
	font-size: 0.66rem;
	font-weight: 800;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

.macaron.mienne {
	background: var(--marine-douce);
	color: var(--marine);
}

.carte.mienne {
	border-color: color-mix(in srgb, var(--marine) 45%, var(--line));
}

.invite {
	border-style: dashed;
	border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
	background: var(--bg-elev);
}

.invite h2 {
	color: var(--accent-puce);
}

.discret {
	background: transparent;
	border-style: dashed;
	box-shadow: none;
}

.enfants {
	display: flex;
	flex-direction: column;
	gap: 5px;
	margin: 10px 0 0;
	padding: 0;
	list-style: none;
}

.enfants li {
	padding: 5px 10px;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
	font-size: 0.86rem;
	font-variant-numeric: tabular-nums;
}


/* CE QUE PORTENT SES ENFANTS, ET CE QU'IL GARDE AU GRENIER. Une ligne par
   enfant, une par carton, et la même forme pour les deux : c'est la même
   question — « quelle taille ? ».

   LA VALEUR D'ABORD. Les deux listes étaient des phrases : « fille, 5 ans —
   taille 116, pointure 29 ». Le nombre qu'on traverse le village pour lire
   arrivait en quatrième position, et trois lignes empilées se lisaient comme un
   paragraphe. La section « Entre vous deux », douze lignes plus haut sur la même
   page, faisait déjà l'inverse sur la même donnée. Deux façons de présenter une
   même chose, à quinze pixels d'écart, font douter des deux.

   Sur un téléphone, le « qui » passe au-dessus des mesures ; dès qu'il y a la
   place, les deux se rangent côte à côte et les nombres s'alignent à droite. */
.portees {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: 10px 0 0;
	padding: 0;
	list-style: none;
}

.portee {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 14px;
	align-items: center;
	justify-content: space-between;
	padding: 9px 12px;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
}

/* Le « qui » : la silhouette du stade, et le mot. Le mot TOUJOURS — une
   information portée par la seule couleur n'en est pas une, et c'est déjà la
   règle des pastilles du marché, d'où viennent ce dessin et cette teinte. */
.portee-qui {
	display: inline-flex;
	gap: 7px;
	align-items: center;
	color: var(--muted);
	font-size: 0.84rem;
}

.portee-qui svg {
	width: 17px;
	height: 17px;
	flex: none;
}

.portee.fille {
	border-color: color-mix(in srgb, var(--fille) 30%, transparent);
	background: var(--fille-douce);
}

.portee.fille .portee-qui,
.portee.fille .mesure-nombre {
	color: var(--fille-ink);
}

.portee.garcon {
	border-color: color-mix(in srgb, var(--garcon) 30%, transparent);
	background: var(--garcon-douce);
}

.portee.garcon .portee-qui,
.portee.garcon .mesure-nombre {
	color: var(--garcon-ink);
}

/* Le carton garde l'ocre du grenier, qui est sa couleur partout ailleurs dans
   l'app — la pastille de la carte, et le cintre. */
.portee.carton {
	border-color: color-mix(in srgb, var(--ocre) 30%, transparent);
	background: var(--ocre-douce);
}

.portee.carton .mesure-nombre {
	color: var(--ocre-ink);
}

.portee-mesures {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 6px 16px;
	align-items: flex-start;
}

/* Une mesure lue : le dessin de la chose mesurée, le nombre, et le mot dessous.
   Le nombre est ce qu'on vient chercher, donc il est le seul en grand. */
.mesure-lue {
	display: grid;
	grid-template-columns: auto auto;
	gap: 0 6px;
	align-items: center;
}

.mesure-icone {
	width: 16px;
	height: 16px;
	grid-row: span 2;
	color: var(--muted);
}

.mesure-nombre {
	font-size: 1.02rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	line-height: 1.15;
	white-space: nowrap;
}

.mesure-quoi {
	color: var(--muted);
	font-size: 0.68rem;
	line-height: 1.15;
	white-space: nowrap;
}

/* --- les liens de plateforme --------------------------------------------- */

.pastilles {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 13px 0 0;
}

.pastille {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-height: 42px;
	padding: 0 14px;
	border: 1px solid var(--line-forte);
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
	color: var(--ink);
	font-weight: 650;
	font-size: 0.9rem;
	text-decoration: none;
	box-shadow: var(--ombre-sm);
}

.pastille:hover,
.pastille:focus-visible {
	border-color: var(--accent);
	background: var(--card);
}

/* Le logo officiel de la plateforme. Le liseré n'est pas une coquetterie :
   l'icône du Bon Coin est un coin orange sur fond BLANC, et sans lui elle
   flotte au milieu d'une pastille blanche au lieu d'être une vignette. Il est
   assez pâle pour ne pas se voir sur les trois autres, qui sont pleines. */
.logo-plateforme {
	flex: none;
	width: 22px;
	height: 22px;
	border: 1px solid var(--logo-bord);
	border-radius: 6px;
}

/* --- les correspondances -------------------------------------------------- */

.match {
	border-left: 4px solid var(--accent);
}

.pistes {
	display: grid;
	gap: 14px;
	margin: 13px 0 0;
	padding: 0;
	list-style: none;
}

.piste {
	padding: 2px 0 2px 12px;
	border-left: 3px solid var(--muted);
}

.piste.acheter {
	border-left-color: var(--volet);
}

.piste.reserve {
	border-left-color: var(--ocre);
}

.piste.vendre {
	border-left-color: var(--marine);
}

.piste.troquer {
	border-left-color: var(--line-forte);
}

/* Mon grenier prend l'ocre du grenier des autres : c'est le même objet, pris
   par l'autre bout. Les deux ne se croisent jamais — ils vivent dans deux
   sections distinctes de l'accueil — donc rien n'oblige à les distinguer, et le
   faire aurait donné deux couleurs à une seule idée.

   « mon-grenier » parce que « grenier » est DÉJÀ une classe, quinze lignes plus
   haut : un fond ocre et un display:flex, qui se seraient posés sur la piste
   sans que rien ne le signale. */
.piste.mon-grenier {
	border-left-color: var(--ocre);
}

.piste-titre {
	margin: 0;
	font-weight: 650;
}

.taille {
	display: flex;
	align-items: baseline;
	gap: 5px;
	margin: 3px 0 1px;
	color: var(--accent);
	font-family: var(--font-titre);
	font-size: 1.4rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

/* Le « ≈ » d'une taille estimée d'après l'âge. Discret, mais présent : deux
   enfants du même âge ne portent pas la même taille, et le dire évite un
   déplacement pour rien. */
.estime {
	color: var(--muted);
	font-family: var(--font);
	font-size: 0.8rem;
	font-weight: 600;
}

.piste-chaussures {
	margin: 0 0 2px;
	color: var(--ink);
	font-size: 0.86rem;
	font-variant-numeric: tabular-nums;
	opacity: 0.85;
}

.piste-detail {
	margin: 0;
	color: var(--muted);
	font-size: 0.85rem;
}

/* --- le filtre ------------------------------------------------------------ */

/* Il n'y a ni <select> ni bouton « Chercher » : chaque pastille est un lien, un
   tap est une recherche, et l'adresse obtenue se partage telle quelle. Sur un
   téléphone, c'est la différence entre trois gestes et un seul. */
.filtre {
	margin: 12px 0 18px;
	padding: 14px;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--card);
	box-shadow: var(--ombre-sm);
}

.filtre-titre {
	margin: 14px 0 7px;
	color: var(--muted);
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.09em;
	text-transform: uppercase;
}

/* Il y avait ici un `.filtre-titre:first-child { margin-top: 0 }`, et il faisait
   exactement le contraire de ce qu'on croyait. Dans l'onglet des tailles,
   « Pour qui » n'est jamais premier — les onglets le précèdent — donc la règle
   ne s'appliquait jamais. Dans celui des outils, « Quel outil » ouvre le bloc
   .outils-cherches, donc elle s'appliquait toujours : le titre collait aux
   onglets (0 px) là où son homologue respirait (14 px), et rien n'expliquait
   la différence à l'écran. Mesuré au navigateur ; la règle est partie. */

/* Les deux onglets : vêtements ou chaussures. Un interrupteur, pas une liste. */
.onglets {
	display: flex;
	gap: 4px;
	padding: 4px;
	border-radius: var(--pilule);
	background: var(--bg-elev);
	border: 1px solid var(--line);
}

/* Préfixées .onglets pour la même raison qu'au-dessus : sans le préfixe, elles
   repeignaient la barre de navigation du bas, qui porte le même nom de classe. */
.onglets .onglet {
	display: inline-flex;
	flex: 1 1 0;
	gap: 7px;
	align-items: center;
	justify-content: center;
	min-height: 40px;
	border-radius: var(--pilule);
	color: var(--muted);
	font-size: 0.88rem;
	font-weight: 600;
	text-decoration: none;
}

.onglets .onglet.actif {
	background: var(--accent);
	color: var(--accent-ink);
	box-shadow: var(--ombre-sm);
}

.onglet-icone {
	width: 17px;
	height: 17px;
}

/* Trois onglets depuis les outils, là où il y en avait deux. Sur un téléphone
   étroit, c'est le DESSIN qui s'efface et jamais le mot : « Vêtements » se lit,
   un pantalon de 17 px se devine. */
@media (max-width: 380px) {
	.onglets .onglet {
		gap: 0;
		font-size: 0.8rem;
	}

	.onglets .onglet-icone {
		display: none;
	}
}

.pastilles-filtre {
	display: flex;
	flex-wrap: wrap;
	gap: 7px;
}

.pastille-filtre {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 40px;
	padding: 0 14px;
	border: 1px solid var(--line-forte);
	border-radius: var(--pilule);
	background: var(--bg-elev);
	color: var(--ink);
	font-size: 0.9rem;
	text-decoration: none;
}

.pastille-filtre.actif {
	border-color: var(--accent);
	background: var(--accent-douce);
	color: var(--accent-puce);
	font-weight: 600;
}

/* Une mesure porte deux lignes : la taille, et l'âge qui va avec. Le village
   pense parfois en tailles et parfois en âges, et personne ne devrait avoir à
   convertir de tête. */
.pastille-filtre.mesure {
	flex-direction: column;
	gap: 0;
	min-width: 62px;
	padding: 5px 10px;
	line-height: 1.2;
}

.mesure-valeur {
	font-variant-numeric: tabular-nums;
	font-weight: 600;
}

.mesure-note {
	color: var(--muted);
	font-size: 0.68rem;
}

.pastille-filtre.mesure.actif .mesure-note {
	color: var(--accent-puce);
}

/* Le raccourci « pour Lina » : deux lignes comme une mesure, mais ici c'est le
   prénom qui porte et la taille qui commente — l'inverse d'une pastille de
   mesure, où le nombre est la réponse. Aligné à gauche parce qu'un prénom n'a
   pas de largeur prévisible, et qu'une colonne de prénoms centrés flotte.

   « mien » et non « enfant » : .enfant est déjà le cadre d'une ligne du
   formulaire de vitrine, avec sa bordure et son fond. À spécificité égale c'est
   le dernier écrit qui gagne, donc la pastille serait devenue un rectangle —
   sans une erreur, ni dans le navigateur ni dans les tests. */
.pastille-filtre.mien {
	flex-direction: column;
	gap: 0;
	align-items: flex-start;
	padding: 5px 13px;
	line-height: 1.25;
}

.mien-nom {
	font-weight: 600;
}

.mien-mesure {
	color: var(--muted);
	font-size: 0.68rem;
	font-variant-numeric: tabular-nums;
}

.pastille-filtre.mien.actif .mien-mesure {
	color: var(--accent-puce);
}

/* L'âge de ce qu'un voisin affirme, sur sa fiche. Le ton du « ≈ » d'une taille
   estimée, et pour la même raison : ce n'est pas un reproche, c'est une mise en
   garde discrète avant de traverser le village. Donc l'encre grise et la taille
   d'une aide — surtout pas le rouge d'une alerte, qui ferait de l'oubli une
   faute. */
.fraicheur {
	margin: 10px 0 0;
	color: var(--muted);
	font-size: 0.84rem;
	font-style: italic;
}

/* La première case à cocher de l'app. Elle emprunte la boîte de .champ mais pas
   sa disposition : une case se lit EN LIGNE avec son libellé, et le libellé tout
   entier doit être cliquable — sur un téléphone, viser une case de 16 px est un
   geste raté une fois sur trois. D'où le <label> qui enveloppe les deux. */
.champ-case {
	display: flex;
	gap: 10px;
	align-items: flex-start;
	margin: 12px 0 4px;
	cursor: pointer;
}

/* UNE CASE À COCHER N'EST PAS UN CHAMP DE TEXTE, et la règle générale ci-dessous
   la traitait comme tel : elle impose min-height 44px et un padding pour qu'on
   vise sans peine un champ sur un téléphone, et `height: 20px` ne les défait pas
   — min-height gagne sur height. La case se retrouvait donc dans une boîte de
   20 par 44 où le carré est dessiné au MILIEU, c'est-à-dire ONZE pixels sous le
   mot qu'elle accompagne.

   Ça ne se voyait pas sur la case des jeux, dont le libellé tient sur deux
   lignes et compense l'écart par hasard ; la première case à libellé court l'a
   montré d'un coup. La zone cliquable, elle, ne rétrécit pas : c'est le <label>
   entier qui la porte, et il fait toute la largeur.

   La marge du haut centre le carré sur la PREMIÈRE ligne du mot — (24,8 − 20)/2
   — et non sur le bloc entier, sinon un libellé de deux lignes la ferait
   descendre à mi-hauteur. */
.champ-case input {
	width: 20px;
	height: 20px;
	min-height: 0;
	padding: 0;
	flex: none;
	margin-top: 2px;
	accent-color: var(--accent);
}

/* Le carton de jeux sur la fiche d'un voisin. Son propre dessin depuis toujours —
   le cintre dit « des vêtements de cette taille », et l'emprunter ici serait un
   pictogramme qui ment.

   IL N'A PLUS LA BOÎTE OCRE DU GRENIER, et c'est le grenier qui l'a fait partir :
   depuis que les cartons sont des lignes ocres pleines juste au-dessus, une
   troisième boîte ocre se lisait comme un carton de plus — un carton sans
   taille, c'est-à-dire exactement ce que l'app passe son temps à dire qu'elle
   refuse de tenir. Le dé garde l'ocre, parce que c'en est bien un ; la boîte
   revient à ce qui porte une TAILLE, et lui n'en porte pas. */
.jeux {
	display: flex;
	gap: 8px;
	align-items: center;
	margin: 12px 0 0;
	color: var(--muted);
	font-size: 0.86rem;
}

.jeux svg {
	color: var(--ocre);
}

.jeux-icone {
	width: 17px;
	height: 17px;
	flex: none;
	align-self: center;
}

/* La phrase de secours d'une recherche vide : une proposition, pas une erreur —
   donc l'encre ordinaire et pas le rouge. */
.secours {
	margin: -4px 0 14px;
	color: var(--ink);
	font-size: 0.92rem;
}

.compte {
	margin: 14px 0 10px;
	color: var(--muted);
	font-size: 0.9rem;
}

/* --- les formulaires ------------------------------------------------------ */

input,
select,
textarea {
	width: 100%;
	min-height: 44px;
	padding: 10px 12px;
	border: 1px solid var(--line-forte);
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
	color: var(--ink);
	font: inherit;
}

/* Une liste grisée dit « pas encore », pas « cassé ». La taille et la pointure
   d'un enfant se choisissent par rapport à son âge, donc elles restent fermées
   tant que l'année de naissance manque — et sans cette règle un select
   désactivé garde l'allure exacte des autres : on cliquait dessus, rien ne
   s'ouvrait, et on croyait le formulaire bloqué. text-fill-color est là pour
   iOS, qui ignore color sur un champ désactivé. */
input:disabled,
select:disabled {
	border-color: var(--line);
	border-style: dashed;
	background: var(--bg);
	color: var(--muted);
	-webkit-text-fill-color: var(--muted);
	cursor: not-allowed;
}

input:focus,
select:focus {
	background: var(--card);
	border-color: var(--accent);
}

input:focus-visible,
select:focus-visible,
button:focus-visible,
a:focus-visible {
	outline: none;
	box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--accent);
}

.champ {
	display: block;
	margin: 14px 0;
}

.etiquette {
	display: block;
	margin-bottom: 5px;
	font-weight: 650;
	font-size: 0.9rem;
}

.etiquette em {
	color: var(--muted);
	font-weight: 400;
	font-size: 0.85em;
	font-style: normal;
}

/* L'étiquette d'un champ « lien » porte le logo de la plateforme ; il faut la
   passer en rangée pour que le logo tombe au milieu du mot et pas sur sa ligne
   de base. Elle vit ICI, après .etiquette : plus haut dans la feuille, le
   « display: block » de .etiquette l'emportait par simple ordre d'écriture et
   le gap ne s'appliquait jamais — le nom restait collé au logo. */
.etiquette-logo {
	display: flex;
	align-items: center;
	gap: 6px;
}

.aide {
	display: block;
	margin-top: 5px;
	color: var(--muted);
	font-size: 0.81rem;
}

.aide.centre {
	text-align: center;
}

.erreur {
	margin: 8px 0;
	padding: 9px 11px;
	border-left: 3px solid var(--alerte);
	border-radius: var(--radius-sm);
	background: var(--alerte-douce);
	color: var(--alerte);
	font-size: 0.88rem;
}

/* Le rappel d'adresse, en haut de sa vitrine : le ton de .invite (l'ocre qui
   appelle une action) dans la forme d'un bandeau. Il mène au compte, où le
   réglage se fait — donc il doit se voir sans peser autant qu'une carte. */
.bandeau-invite {
	margin: 12px 0;
	padding: 11px 13px;
	border-left: 3px solid var(--ocre);
	border-radius: var(--radius-sm);
	background: var(--ocre-douce);
	color: var(--ink);
}

.bandeau-invite .lien {
	display: inline-block;
	margin-left: 6px;
	font-weight: 600;
}

.bandeau-ok {
	margin: 12px 0;
	padding: 11px 13px;
	border-left: 3px solid var(--volet);
	border-radius: var(--radius-sm);
	background: var(--volet-douce);
	color: var(--volet-ink);
	font-weight: 600;
}

/* Le pendant du bandeau vert, pour ce qui a RATÉ. Il manquait, et les échecs
   s'affichaient donc en vert — la couleur qui dit « c'est fait ». Même forme,
   l'alerte à la place du volet : c'est l'ordre du dépôt, --alerte ne sert qu'aux
   erreurs et rien d'autre. */
.bandeau-erreur {
	margin: 12px 0;
	padding: 11px 13px;
	border-left: 3px solid var(--alerte);
	border-radius: var(--radius-sm);
	background: var(--alerte-douce);
	color: var(--alerte);
	font-weight: 600;
}

.enfant {
	margin: 12px 0;
	padding: 12px 13px 6px;
	border: 1px solid var(--line);
	border-radius: var(--radius-md);
	background: var(--bg-elev);
}

.enfant legend {
	padding: 0 7px;
	color: var(--muted);
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
}

.enfant-champs {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 10px;
}

.enfant .champ,
.enfant-champs .champ {
	margin: 4px 0;
}

/* Le repli natif : un <details>, pas un panneau en JavaScript. Il porte le cas
   rare — le carton qui n'est à aucun enfant — sans le mettre sous le nez de tout
   le monde.

   FERMÉ, IL EST UN BOUTON, et c'est tout l'objet de ce qui suit. C'était une
   ligne de texte dans un cadre en pointillés, et elle ne disait pas qu'elle
   ouvrait quelque chose : on la lisait comme une question posée en passant, donc
   le formulaire qu'elle cache restait introuvable. Elle emprunte maintenant
   l'apparence de « + Ajouter un enfant », deux sections plus haut dans le même
   formulaire — le geste est alors déjà appris plutôt qu'à deviner. Le signe passe
   de + à −, et le cadre n'apparaît qu'une fois ouvert : un bouton entouré de
   pointillés ne ressemble à rien. */
.repli {
	margin-top: 12px;
}

.repli[open] {
	padding: 10px 12px;
	border: 1px dashed var(--line-forte);
	border-radius: var(--radius-md);
	background: var(--bg-elev);
}

/* La flèche native est retirée des DEUX façons qu'il faut : ::marker pour les
   navigateurs récents, ::-webkit-details-marker pour Safari, qui ignore le
   premier. Sans les deux, le bouton porte à la fois la flèche du navigateur et
   le signe de l'app. */
/* summary.bouton et non summary tout court, et c'est la spécificité qui l'exige :
   le résumé porte « bouton second petit », donc `.bouton.petit` pèse deux classes
   là où `.repli > summary` n'en pèse qu'une. Sa `padding: 0 14px` — une
   propriété RACCOURCIE, qui remet donc le haut et le bas à zéro — écrasait en
   silence la marge verticale posée ici, et les deux lignes du libellé touchaient
   les bords sans que rien ne le signale. */
.repli > summary.bouton {
	list-style: none;
	cursor: pointer;
	/* Aligné à gauche, et non centré comme les autres boutons : le libellé passe
	   à deux lignes sur un téléphone, et un « + » centré avec son texte flotterait
	   au milieu au lieu de marquer le début d'une ligne qu'on déplie. */
	justify-content: flex-start;
	text-align: left;
	padding: 9px 14px;
}

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

/* Le signe est écrit par la feuille de style et non par le gabarit : c'est un
   ORNEMENT qui dit l'état du repli, donc il n'a rien à faire dans le HTML, où un
   lecteur d'écran le lirait — le mot « Ajouter » porte déjà le sens. */
.repli > summary::before {
	content: "+";
	font-size: 1.15rem;
	font-weight: 700;
	line-height: 1;
}

.repli[open] > summary::before {
	content: "−";
}

.repli[open] > summary {
	margin-bottom: 10px;
}

/* --- les boutons ---------------------------------------------------------- */

.bouton {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	min-height: 46px;
	padding: 0 20px;
	border: 1px solid transparent;
	border-radius: var(--radius-sm);
	background: linear-gradient(140deg, var(--accent-2), var(--accent));
	color: var(--accent-ink);
	font: inherit;
	font-weight: 700;
	text-decoration: none;
	cursor: pointer;
	box-shadow: var(--ombre-sm);
}

.bouton.second {
	background: var(--card);
	border-color: var(--line-forte);
	color: var(--accent-puce);
}

.bouton.petit {
	min-height: 38px;
	padding: 0 14px;
	font-size: 0.88rem;
}

.bouton.grand {
	width: 100%;
	margin-top: 10px;
	font-size: 1.02rem;
}

.bouton.danger {
	background: var(--alerte);
	border-color: transparent;
}

.bouton.petit.danger {
	background: var(--card);
	border-color: var(--line-forte);
	color: var(--alerte);
}

.carte.danger {
	border-color: var(--alerte);
}

.actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 12px;
	align-items: center;
}

.actions form {
	margin: 0;
}

/* --- divers -------------------------------------------------------------- */

.porte {
	max-width: 430px;
	margin: 0 auto;
	padding: 24px 16px calc(var(--barre-h) + 24px);
}

.porte h1 {
	font-size: 1.7rem;
}

.vide {
	color: var(--muted);
	font-style: italic;
}

.vide.grand {
	padding: 14px 0;
}

.lien-perso code {
	display: block;
	padding: 11px;
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
	border: 1px solid var(--line);
	font-size: 0.85rem;
	word-break: break-all;
}

input.code {
	max-width: 8ch;
	font-size: 1.5rem;
	letter-spacing: 0.35em;
	text-align: center;
	font-variant-numeric: tabular-nums;
}

.pied {
	padding: 8px 16px calc(var(--barre-h) + 12px);
	color: var(--muted);
	font-size: 0.76rem;
	text-align: center;
}

.ligne-admin .actions {
	margin-top: 12px;
}

/* L'attribut hidden perd contre n'importe quelle règle display : sans ceci, un
   élément « caché » resterait visible et avalerait les clics. */
[hidden] {
	display: none !important;
}

/* --- l'affiche à imprimer ------------------------------------------------- */

.page-affiche {
	max-width: 780px;
}

.affiche {
	padding: 30px 26px;
	border: 1px solid var(--line);
	border-radius: var(--radius-md);
	background: var(--card);
	text-align: center;
}

.affiche-nom {
	margin: 0;
	font-family: var(--font-titre);
	color: var(--accent);
	font-size: 2.2rem;
	letter-spacing: -0.02em;
}

.affiche-punch {
	margin: 5px 0 18px;
	font-size: 1.15rem;
	font-weight: 600;
}

.affiche-texte {
	max-width: 46ch;
	margin: 0 auto 18px;
	color: var(--muted);
}

.affiche-qr svg {
	width: 230px;
	height: 230px;
	max-width: 62vw;
}

.affiche-url {
	margin: 8px 0 0;
	font-family: var(--font-titre);
	font-size: 1.2rem;
	font-weight: 700;
}

.affiche-code {
	margin: 6px 0 18px;
	font-size: 1.05rem;
}

.affiche-etapes {
	display: inline-block;
	max-width: 44ch;
	margin: 0 auto;
	text-align: left;
}

.affiche-etapes li {
	margin: 7px 0;
}

.affiche-pied {
	margin: 18px 0 0;
	color: var(--muted);
	font-size: 0.8rem;
}

@media (min-width: 560px) {
	.enfant-champs {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media print {
	.bandeau,
	.barre,
	.pied,
	.non-imprimable {
		display: none !important;
	}

	body {
		background: #fff;
	}

	.contenu {
		padding: 0;
	}

	.affiche {
		border: none;
	}

	@page {
		size: A4;
		margin: 14mm;
	}
}

/* --- les pastilles d'enfant : la carte lue d'un coup d'œil ---------------- */

/* Une silhouette pour le stade, une teinte ET un mot pour le genre, l'âge en
   chiffres. C'est ce qui permet de parcourir vingt vitrines sans en lire une :
   la couleur ne porte jamais l'information seule. */
/* UNE CLASSE DÉJÀ PRISE, ET DIX PIXELS QUI N'AVAIENT AUCUNE RAISON D'ÊTRE LÀ.
   Sur une même vitrine, « 14 ans garçon » s'affichait 38 px de haut et « 5 ans
   fille » 28. La cause : la pastille du grenier porte `class="puce grenier"`, et
   il existait ailleurs une règle `.grenier` — pour un paragraphe de la fiche
   d'un voisin, page qui n'a rien à voir — qui posait `margin: 10px 0 0`. La
   marge d'un élément flex compte dans la hauteur de sa LIGNE : la ligne passait
   donc à 38, et la pastille voisine s'y étirait. Rien dans la console, rien dans
   les tests ; c'est une mesure au navigateur qui l'a dit. La règle fautive est
   partie avec le paragraphe qu'elle stylait.

   Les deux lignes ci-dessous sont la ceinture par-dessus les bretelles, et elles
   valent d'être gardées : une pastille est un JETON, pas un bloc de texte — sa
   hauteur ne doit dépendre ni de la ligne où elle tombe, ni de ce qu'un voisin
   écrit dedans, ni d'une classe qu'on lui ajoutera un jour. */
.puces {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: 6px;
	margin: 12px 0 0;
	padding: 0;
	list-style: none;
}

.puce {
	display: inline-flex;
	gap: 6px;
	align-items: center;
	box-sizing: border-box;
	min-height: 28px;
	padding: 5px 11px 5px 9px;
	border: 1px solid transparent;
	border-radius: var(--pilule);
	background: var(--mixte-douce);
	color: var(--mixte-ink);
	font-size: 0.82rem;
	line-height: 1.25;
}

.puce.fille {
	background: var(--fille-douce);
	color: var(--fille-ink);
}

.puce.garcon {
	background: var(--garcon-douce);
	color: var(--garcon-ink);
}

.puce.grenier {
	background: var(--ocre-douce);
	color: var(--ink);
	border-color: color-mix(in srgb, var(--ocre) 35%, transparent);
}

/* Le carton de jeux. Une teinte à lui — ni celle du grenier, ni celle d'un
   genre — parce qu'il ne parle ni de tailles ni d'enfants ; et le MOT « jeux »
   à côté du dé, comme partout ici : une information portée par la seule couleur
   n'est pas une information pour tout le monde. */
.puce.jeux {
	background: var(--volet-douce);
	color: var(--volet-ink);
	border-color: color-mix(in srgb, var(--volet) 35%, transparent);
}

/* Le grand tri. La teinte de l'accent, la plus forte de la feuille, et c'est
   voulu : c'est la seule pastille qui parle du PRÉSENT et la seule qui
   disparaîtra d'elle-même. Les autres disent un état durable ; celle-ci dit
   « cette semaine », et une nouvelle qui se lit comme un état ne se lit pas. */
.puce.tri {
	background: var(--accent-douce);
	color: var(--accent-puce);
	border-color: color-mix(in srgb, var(--accent) 40%, transparent);
	font-weight: 600;
}

.puce-icone {
	width: 16px;
	height: 16px;
	flex: 0 0 auto;
}

.puce-age {
	font-variant-numeric: tabular-nums;
	font-weight: 600;
	white-space: nowrap;
}

.puce-genre {
	opacity: 0.78;
}

/* --- le pied d'une carte : les liens, et le bouton qui ouvre la fiche ----- */

.carte-pied {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	align-items: center;
	justify-content: space-between;
	margin-top: 14px;
}

/* Les liens de plateforme y perdent leur marge du haut : c'est le pied qui la
   porte désormais. */
.carte-pied .pastilles {
	margin: 0;
	flex: 1 1 auto;
}

/* --- la fiche d'un voisin ------------------------------------------------- */

.fil {
	margin: 2px 0 12px;
	font-size: 0.9rem;
}

.fiche-voisin h1 {
	margin: 0;
	font-size: 1.35rem;
}

.titre-carte {
	margin: 18px 0 0;
	color: var(--muted);
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.09em;
	text-transform: uppercase;
}

.mot.grand {
	font-size: 1rem;
}

/* Le contact : la raison d'être de tout le reste. Il a sa propre carte, sous la
   fiche, parce qu'on y arrive après avoir décidé que ça valait le coup. */
.contact h2 {
	margin-top: 0;
}

.contact-tel {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 12px 0 16px;
}

.succes {
	margin: 12px 0 0;
	padding: 10px 12px;
	border-radius: var(--radius-sm);
	background: var(--volet-douce);
	color: var(--volet-ink);
	font-size: 0.9rem;
}

/* --- le cintre, en filigrane -------------------------------------------- */

/* Trois cintres dans le coin du bloc peint, très pâles : la seule décoration de
   l'app, et elle dit de quoi il s'agit sans un mot. En data: URI parce que la
   CSP autorise data: pour les images et rien d'autre — pas de fichier de plus à
   servir, pas de requête de plus. */
.resume::after {
	content: "";
	position: absolute;
	right: -14px;
	bottom: -22px;
	width: 168px;
	height: 118px;
	opacity: 0.16;
	background-repeat: no-repeat;
	background-size: contain;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 84' fill='none' stroke='%23ffffff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M30 30v-5a5 5 0 1 1 5-5'/%3E%3Cpath d='M30 30 8 52h44L30 30z'/%3E%3Cpath d='M66 46v-5a5 5 0 1 1 5-5'/%3E%3Cpath d='M66 46 44 68h44L66 46z'/%3E%3Cpath d='M96 24v-5a5 5 0 1 1 5-5'/%3E%3Cpath d='M96 24 74 46h44L96 24z'/%3E%3C/svg%3E");
	pointer-events: none;
}

/* Le cintre devant le nom de l'app, dans le bandeau. */
.marque-cintre {
	width: 20px;
	height: 20px;
	flex: 0 0 auto;
	color: var(--accent);
}

/* La carte d'invitation, quand elle ouvre la page : elle passe avant les
   chiffres du village, parce que c'est la seule chose à faire ici. */
.invite.premiere {
	margin-top: 4px;
}

.aide.centre {
	text-align: center;
}

.invite .actions {
	margin-bottom: 6px;
}

/* Les trois pastilles « pour qui » n'ont plus de texte : le dessin porte, et le
   mot vit dans title/aria-label. Elles sont donc plus hautes que larges — une
   cible qu'on touche du pouce, pas une case à cocher. */
.pastille-filtre.genre {
	min-width: 66px;
	min-height: 48px;
	padding: 0 14px;
}

/* Une recherche posée pour une fille répond dans SA teinte : le prénom, le
   genre et la taille s'allument en rose et non dans l'accent de l'app. C'est la
   même information à l'écran qu'une puce d'enfant de l'annuaire, elle garde
   donc la même couleur — et un fond qui répond dans la couleur de ce qu'on
   vient de demander confirme le choix mieux qu'un bleu commun à tout.

   La règle porte sur le CONTENEUR et pas sur chaque rangée, parce que c'est le
   filtre entier qui est « pour une fille » : c'est ce qui fait que le raccourci
   « Lina » teinte aussi la taille qu'il vient de poser, sans que la pastille de
   taille ait à savoir pour qui elle s'est allumée. Les onglets, eux, ne sont pas
   des pastilles et restent à l'accent : vêtements ou chaussures ne parle de
   personne.

   Les variables existent déjà (--fille-douce est un rose très pâle, presque
   blanc) : rien n'est ajouté à la palette, et le mode sombre suit tout seul
   puisqu'il en redéfinit les trois valeurs plus haut. */
.filtre.fille .pastille-filtre.actif {
	border-color: var(--fille);
	background: var(--fille-douce);
	color: var(--fille-ink);
}

/* La deuxième ligne d'une pastille — « 6 ans » sous 116, « taille 110 » sous un
   prénom — porte sa propre couleur d'accent. Sans ces deux-là elle resterait
   bleue au milieu d'un fond rose. */
.filtre.fille .pastille-filtre.actif .mesure-note,
.filtre.fille .pastille-filtre.actif .mien-mesure {
	color: var(--fille-ink);
}

.genre-icone {
	width: 24px;
	height: 24px;
}

.genre-icone.deux {
	width: 44px;
}

/* --- les villages ------------------------------------------------------- */

.bandeau-actions {
	display: flex;
	gap: 8px;
	align-items: center;
}

/* Le code d'un village se lit à voix haute et se recopie depuis un papier :
   chasse fixe, gros, et sélectionnable d'un geste. */
.code-village {
	margin: 10px 0;
	padding: 10px 14px;
	border: 1px dashed var(--line-forte);
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 1.15rem;
	letter-spacing: 0.02em;
	overflow-wrap: anywhere;
}

.carte.invitation {
	border-color: var(--accent);
	box-shadow: var(--ombre-md);
}

.carte.neuf {
	border-color: var(--volet);
}

.lien-brut {
	margin: 10px 0;
	padding: 10px 12px;
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 0.82rem;
	overflow-wrap: anywhere;
}

/* Les deux listes de taille prennent toute la largeur de la ligne enfant : leurs
   libellés portent le mot ET la taille de l'abaque (« sa taille d'âge (110) »),
   et une demi-largeur les rognait — un select natif coupe son texte sans le
   dire, donc le parent lisait « sa taille d'â… ». */
.enfant-champs .champ.large {
	grid-column: 1 / -1;
}

/* Le cartouche de marque : « Le Bon Voisin » au-dessus, le village dessous.
   Une seule ligne — « Le Bon Voisin de Renneville » — débordait sur deux dans un
   bandeau de téléphone qui porte aussi deux boutons, et mettait surtout la
   marque et le lieu sur le même plan. Dès qu'il y a de la place, le village
   passe à droite. */
.marque-mots {
	display: flex;
	flex-direction: column;
	min-width: 0;
	line-height: 1.05;
}

.marque-village {
	color: var(--muted);
	font-size: 0.68rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	overflow-wrap: anywhere;
}

@media (min-width: 560px) {
	.marque-mots {
		flex-direction: row;
		align-items: baseline;
		gap: 10px;
	}
	.marque-village {
		position: relative;
		padding-left: 12px;
	}
	/* Un point de séparation, dessiné : un « · » dans le balisage serait lu à
	   voix haute par un lecteur d'écran. */
	.marque-village::before {
		content: "";
		position: absolute;
		left: 0;
		top: 50%;
		width: 4px;
		height: 4px;
		border-radius: 50%;
		background: var(--line-forte);
		transform: translateY(-50%);
	}
}

/* Dire qu'un lien est mort. L'app ne peut pas le voir elle-même (voir
   lebonvoisin.Signalement), donc ces boutons sont sa seule source — ils doivent
   être trouvables sans détourner l'attention des pastilles, qui restent
   l'action principale. D'où un bouton qui ressemble à un lien, pas à un bouton.

   Les formulaires sont en ligne parce qu'il y en a un par plateforme : un
   bouton par formulaire, et le HTML interdit de les imbriquer. */
.signaler {
	display: block;
	margin-top: 10px;
}

/* En FLUX et non en flex : ce sont des phrases, et un conteneur flex mettait
   chaque morceau sur sa propre ligne dès que ça débordait — « Tu as signalé
   Vinted (annuler) » puis, à la ligne, « — il ne t'est plus proposé ». */
.signaler form {
	display: inline;
}

.lien-bouton {
	width: auto;
	min-height: 0;
	padding: 0;
	border: 0;
	background: none;
	color: var(--accent);
	font: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
	cursor: pointer;
}

.lien-bouton:hover {
	color: var(--accent-puce);
}

/* Ce que les voisins disent d'un de MES liens, sous le champ qui le porte : le
   seul endroit où le corriger. Le fond ambré plutôt que rouge — ce n'est pas une
   erreur de saisie, c'est une nouvelle du village. */
.signale {
	display: block;
	margin-top: 6px;
	padding: 8px 10px;
	border-radius: var(--radius-sm);
	background: var(--ocre-douce);
	color: var(--ink);
	font-size: 0.82rem;
	line-height: 1.45;
}

.signale .lien-bouton {
	margin-left: 4px;
	color: var(--ocre);
}

/* ---------------------------------------------------------------------------
   Ce qu'un voisin prête, et les villages jumelés.
   --------------------------------------------------------------------------- */

/* LES QUATRE TEINTES, et le seul endroit où elles se nomment. Chaque classe ne
   fait que POSER trois variables ; tout ce qui suit s'en sert sans jamais
   reparler d'ambre ni de brique, donc changer une couleur de famille est une
   ligne, et ajouter une cinquième famille en est quatre.

   La classe vient de lebonvoisin.Outil.Famille, qui est une clé exprès : les
   quatre mots sont donc à greper dans outil.go avant d'en changer ici. Une
   famille sans classe correspondante n'est pas un trou — le repli juste
   en dessous lui rend le gris d'avant. */
.outil-case,
.outil-lien,
.outil-vu {
	--teinte: var(--muted);
	--teinte-douce: var(--bg-elev);
	--teinte-ink: var(--ink);
}

.teinte-bricoler {
	--teinte: var(--outil-bricoler);
	--teinte-douce: var(--outil-bricoler-douce);
	--teinte-ink: var(--outil-bricoler-ink);
}

.teinte-jardiner {
	--teinte: var(--outil-jardiner);
	--teinte-douce: var(--outil-jardiner-douce);
	--teinte-ink: var(--outil-jardiner-ink);
}

.teinte-chantier {
	--teinte: var(--outil-chantier);
	--teinte-douce: var(--outil-chantier-douce);
	--teinte-ink: var(--outil-chantier-ink);
}

.teinte-transporter {
	--teinte: var(--outil-transporter);
	--teinte-douce: var(--outil-transporter-douce);
	--teinte-ink: var(--outil-transporter-ink);
}

.teinte-recevoir {
	--teinte: var(--outil-recevoir);
	--teinte-douce: var(--outil-recevoir-douce);
	--teinte-ink: var(--outil-recevoir-ink);
}

/* Le formulaire de prêt : vingt-deux cases, groupées par famille. Autant d'icônes en vrac
   sont un mur ; par famille, on trouve la sienne. */
.outils-famille {
	margin: 14px 0 0;
}

.outils-titre {
	margin: 0 0 8px;
	color: var(--muted);
	font-size: 0.82rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

/* auto-fill et un minimum en ch : la grille rend trois colonnes sur un téléphone
   et cinq sur un écran large, sans point de rupture à maintenir. */
.outils-grille {
	display: grid;
	gap: 8px;
	grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
}

/* LE PREMIER :checked DE CETTE FEUILLE, et c'est pour ça qu'il est expliqué ici.
   Les pastilles de la recherche s'allument par une classe « actif » que le
   SERVEUR pose, parce que ce sont des liens — chaque tap y est la recherche.
   Une case à cocher, elle, doit s'allumer SANS aller-retour et voyager avec le
   formulaire de la vitrine : c'est donc le navigateur qui la teint, par :checked.

   La case elle-même est cachée à l'œil mais PAS au clavier ni au lecteur
   d'écran : opacity 0 et pas display:none, sinon elle sort de l'ordre de
   tabulation et le champ devient inatteignable sans souris. */
.outil-case {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 6px;
	align-items: center;
	padding: 10px 6px 8px;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
	color: var(--muted);
	text-align: center;
	cursor: pointer;
}

.outil-case input {
	position: absolute;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	cursor: pointer;
}

/* LE DESSIN PORTE SA FAMILLE, EN TOUTES CIRCONSTANCES : c'est une couleur qui
   informe, pas un état. Elle ne doit donc pas bouger au clic, sans quoi elle
   voudrait dire deux choses à la fois. */
.outil-dessin {
	color: var(--teinte);
}

/* Éteinte → allumée, dans la teinte de la FAMILLE et non dans le bleu de l'app :
   quatre couleurs cohabitent ici, et un bleu unique aurait effacé la seule chose
   que ces couleurs disent. La couleur seule ne dit d'ailleurs rien à qui ne la
   voit pas — la bordure prend la teinte, le fond se remplit et le mot passe en
   gras, donc l'état se lit de trois façons. */
.outil-case:has(input:checked) {
	border-color: var(--teinte);
	background: var(--teinte-douce);
	color: var(--teinte-ink);
	font-weight: 600;
}

/* Le mot se teinte AUSSI par voisinage, sans :has(). Ce n'est pas de la
   redondance : :has() ne date que de 2023, et sur un navigateur plus vieux la
   case cochée n'aurait plus RIEN pour se distinguer — le dessin, lui, ne change
   pas d'une case à l'autre depuis qu'il porte sa famille. Le cadre ne s'allume
   pas dans ce cas ; le mot en gras et teinté suffit à trancher. */
.outil-case input:checked ~ .outil-nom {
	color: var(--teinte-ink);
	font-weight: 600;
}

/* Le focus doit rester visible alors que la case est transparente : sans ça, on
   navigue au clavier dans vingt-deux cases sans savoir où l'on est. */
.outil-case:has(input:focus-visible),
.outil-lien:focus-visible {
	outline: 2px solid var(--teinte);
	outline-offset: 2px;
}

.outil-icone {
	width: 26px;
	height: 26px;
	flex: none;
}

.outil-nom {
	font-size: 0.74rem;
	line-height: 1.2;
}

/* La grille de la RECHERCHE d'outils : les mêmes vingt-deux dessins, mais en liens.
   Une classe à elle et surtout pas .outil-case, pour la raison expliquée juste
   au-dessus — la case du formulaire s'allume par :checked dans le navigateur,
   celle-ci par la classe « actif » que pose le serveur. Deux mécaniques sous une
   seule classe, c'est le jour où l'une teint l'autre sans qu'on comprenne. */
.outil-lien {
	display: flex;
	flex-direction: column;
	gap: 4px;
	align-items: center;
	padding: 10px 6px 8px;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
	color: var(--muted);
	text-align: center;
	text-decoration: none;
}

.outil-lien.actif {
	border-color: var(--teinte);
	background: var(--teinte-douce);
	color: var(--teinte-ink);
	font-weight: 600;
}

/* Ce que personne ne prête reste LISIBLE et cliquable : c'est une réponse, pas
   une case morte — et le mot « personne » la donne pour qui ne voit pas la
   nuance de gris. */
.outil-lien.vide {
	opacity: 0.55;
}

/* La barre du haut est COLLANTE : sans cette marge, l'ancre #outils ferait
   atterrir le titre « Quel outil » DESSOUS, et la page aurait l'air d'avoir sauté
   au mauvais endroit. */
#outils,
.outils-famille {
	scroll-margin-top: 72px;
}

/* Le bouton d'enregistrement de la vitrine, collant au bas de l'écran.
   Le formulaire fait plusieurs écrans : corriger une année de naissance en haut
   demandait de tout faire défiler pour valider, et un changement qu'on oublie
   d'enregistrer est un changement perdu. Il s'arrête avec le formulaire — fixe,
   il aurait recouvert un coin de chaque page jusqu'au pied.

   pointer-events sur la boîte : sans lui, la bande collante s'étend sur toute
   la largeur et avale les clics de ce qui passe dessous. C'est le même défaut
   qu'un élément invisible qui reste cliquable. */
.fiche-garder {
	position: sticky;
	/* --barre-h PORTE DÉJÀ env(safe-area-inset-bottom) (voir sa définition) :
	   l'ajouter ici comptait deux fois l'encoche, et le bouton flottait 34 px
	   trop haut sur un iPhone. Invisible sur un écran d'ordinateur, où la valeur
	   vaut zéro — c'est exactement le genre de faute qu'on ne voit qu'en vrai. */
	bottom: calc(var(--barre-h) + 18px);
	z-index: 40;
	display: flex;
	justify-content: flex-end;
	/* Un peu en retrait de la colonne de texte, et pas aligné sur elle : un
	   bouton qui FLOTTE doit se voir flotter, sinon il se lit comme la fin du
	   formulaire et on continue de chercher le vrai en bas de page. */
	padding-right: 6px;
	margin-top: 18px;
	pointer-events: none;
}

.fiche-garder .bouton {
	pointer-events: auto;
	box-shadow: var(--ombre-md);
}

/* Inviter un voisin : le carré qu'on tend, grand et seul.
   On tend son téléphone à quelqu'un qui vise mal avec le sien ; tout ce qui
   n'est pas le carré noir est du bruit à ce moment-là. Fond BLANC en toutes
   circonstances, y compris en thème sombre : un QR code inversé n'est pas lu
   par la moitié des appareils photo, et celui qui ne scanne pas repart sans
   rien. C'est la même raison qui garde le code écrit en clair dessous. */
.inviter-qr {
	display: flex;
	justify-content: center;
	padding: 16px;
	border-radius: var(--radius-sm);
	background: #ffffff;
}

.inviter-qr svg {
	width: min(300px, 100%);
	height: auto;
}

.inviter-code {
	margin: 14px 0 0;
	text-align: center;
	font-size: 1.05rem;
	letter-spacing: 0.02em;
}

.inviter-pied {
	margin-top: 22px;
}

/* L'anniversaire qui arrive. La teinte de la famille « recevoir », et c'est le
   seul lien de couleur de l'app qui dise quelque chose : la carte pointe vers
   cette famille-là, et on retrouve la même prune en arrivant sur la grille. Le
   mot reste écrit, comme partout. */
.carte.fete {
	border-color: color-mix(in srgb, var(--outil-recevoir) 35%, var(--line));
	background: linear-gradient(
		180deg,
		color-mix(in srgb, var(--outil-recevoir-douce) 70%, var(--bg-elev)),
		var(--bg-elev) 70%
	);
}

.carte.fete h2 {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 8px;
	color: var(--outil-recevoir-ink);
}

/* L'âge en jeton, et pas au fil de la phrase : c'est le chiffre qu'on cherche
   des yeux, et il change chaque année. */
.fete-ans {
	padding: 2px 9px;
	border-radius: 999px;
	background: var(--outil-recevoir-douce);
	color: var(--outil-recevoir-ink);
	font-family: var(--font);
	font-size: 0.78rem;
	font-weight: 600;
	letter-spacing: 0.01em;
}

.outil-combien {
	color: var(--muted);
	font-size: 0.68rem;
	font-variant-numeric: tabular-nums;
}

.outil-lien.actif .outil-combien {
	color: var(--teinte-ink);
}

/* Le réglage du classement du marché, sur la page du compte. Deux blocs qui
   s'expliquent, et non un interrupteur : le second choix ne se devine pas. */
.reglages {
	display: grid;
	gap: 10px;
	margin: 12px 0 0;
	padding: 0;
	list-style: none;
}

.reglage {
	padding: 11px 13px;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
}

.reglage.actif {
	border-color: var(--accent);
	background: var(--accent-douce);
}

.reglage-titre {
	margin: 0;
	font-weight: 600;
}

.reglage-dit {
	margin: 8px 0 0;
	color: var(--accent-puce);
	font-size: 0.8rem;
	font-weight: 600;
}

/* La rangée d'outils d'une fiche : ce qu'il prête, en clair. Le mot est TOUJOURS
   à côté du dessin — une information portée par la seule image n'en est pas une,
   et c'est déjà la règle des pastilles d'enfants. */
.outils-vus {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 10px 0 0;
	padding: 0;
	list-style: none;
}

.outil-vu {
	display: inline-flex;
	gap: 6px;
	align-items: center;
	padding: 5px 10px;
	border-radius: var(--pilule);
	background: var(--teinte-douce);
	color: var(--teinte-ink);
	font-size: 0.8rem;
}

/* Le dessin garde sa teinte PLEINE sur le mot déjà teinté : sans ça, la pastille
   serait d'une seule couleur unie et l'icône s'y dissoudrait. */
.outil-vu svg {
	color: var(--teinte);
}

.outil-vu svg {
	width: 16px;
	height: 16px;
	flex: none;
}

/* Le village d'origine d'une vitrine, quand l'annuaire en mêle deux. Il ne
   s'affiche QUE pour une vitrine d'en face : c'est sa rareté qui lui donne son
   sens, et une étiquette sur chaque carte ne dirait plus rien. Le bleu de
   l'atelier, parce que ce n'est pas un avertissement — c'est une adresse. */
.village-origine {
	padding: 2px 8px;
	border-radius: var(--pilule);
	background: var(--accent-douce);
	color: var(--accent-puce);
	font-size: 0.74rem;
	font-weight: 600;
	white-space: nowrap;
}

/* Une ligne de l'écran de jumelage. L'état sert de classe, comme la valeur de
   lebonvoisin.Sens sur une piste : « possible », « attendu », « recu »,
   « accepte ». */
.ligne-jumelage {
	margin-bottom: 10px;
}

.jumelage-qui {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: baseline;
}

.jumelage-nom {
	font-size: 1.02rem;
	font-weight: 600;
}

.jumelage-loin,
.jumelage-compte {
	color: var(--muted);
	font-size: 0.84rem;
}

.jumelage-etat {
	margin: 6px 0 0;
	font-size: 0.86rem;
}

/* Une entente signée se voit d'un coup d'œil dans une liste : le vert des
   volets, celui de « ce qu'on peut prendre ». Une demande reçue attend une
   réponse, donc elle appelle l'œil par l'ocre. */
.ligne-jumelage.accepte {
	border-left: 3px solid var(--volet);
}

.ligne-jumelage.accepte .jumelage-etat {
	color: var(--volet-ink);
	font-weight: 600;
}

.ligne-jumelage.recu {
	border-left: 3px solid var(--ocre);
}

.ligne-jumelage.attendu .jumelage-etat {
	color: var(--muted);
}

/* Le code postal se saisit à côté de son bouton, dans la rangée d'actions d'un
   village : un champ seul sur sa ligne ferait croire à un formulaire à part. */
.situer {
	display: flex;
	gap: 6px;
	align-items: center;
}

.situer input {
	width: 9ch;
	min-height: 34px;
	padding: 0 8px;
	border: 1px solid var(--line-forte);
	border-radius: var(--radius-sm);
	background: var(--bg-elev);
	color: var(--ink);
	font-size: 0.86rem;
}
