/* ==========================================================================
   Tashiro World — style2026
   Habillage inspiré des menus de NieR:Automata : deux tons (gris beige
   « papier » et boîtes brun-noir), tout en angles droits, texture de grain
   et de lignes de balayage, et des éléments de corruption de données dans
   le coin inférieur gauche des visuels.

   Cette feuille ne sert QUE la page d'accueil (index.php).
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Zen+Kaku+Gothic+New:wght@500;700;900&display=swap');

/* --------------------------------------------------------------------------
   1. Jetons
   -------------------------------------------------------------------------- */
:root {
	/* Les deux tons de base */
	--papier:      #cbc7b2;
	--papier-fonce:#c0bca6;
	--papier-clair:#d6d2bf;
	--encre:       #454138;
	--encre-douce: #56513f;
	--encre-pale:  #6d6754;

	/* Boîtes sombres */
	--boite:       #454138;
	--boite-haut:  #4e4a3f;
	--boite-bas:   #3a372e;
	--sur-boite:   #cfcbb7;
	--sur-boite-pale: #a5a08c;

	/* Le rouge de NieR, réservé aux avertissements et aux glitchs */
	--rouge:       #a8392b;
	--cyan:        #4e8f8f;

	--trait:       rgba(69, 65, 56, .34);
	--trait-fort:  rgba(69, 65, 56, .62);

	/* NieR:Automata utilise FOT-Rodin Pro (Fontworks), une police payante
	   qu'on ne peut pas servir ici. Zen Kaku Gothic New est la plus proche
	   parmi les gratuites : même famille de gothiques japonaises, un latin
	   géométrique, large, à trait régulier. Si un jour vous avez la licence
	   Rodin, il suffit de la mettre en tête de ces deux lignes.
	   Graisses disponibles : 500, 700, 900 — et rien d'autre. */
	--titre: 'Zen Kaku Gothic New', 'Hiragino Kaku Gothic ProN', 'Yu Gothic', Meiryo, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
	--texte: 'Zen Kaku Gothic New', 'Hiragino Kaku Gothic ProN', 'Yu Gothic', Meiryo, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;

	/* Ombre portée décalée, sans flou : la signature typographique de NieR.
	   Une version pour le texte sombre sur papier, une pour le clair sur boîte. */
	--ombre-papier: 2px 2px 0 rgba(69, 65, 56, .20);
	--ombre-boite:  2px 2px 0 rgba(16, 15, 12, .55);

	--transition: 180ms cubic-bezier(.2, .7, .3, 1);
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* Garde-fou contre le défilement horizontal.
   « clip » coupe le débordement SANS fabriquer de conteneur de défilement
   (contrairement à « hidden », qui force overflow-y à « auto » et peut créer
   un second ascenseur). On le pose sur <html> ET <body> : Safari iOS ignore
   régulièrement la version posée sur <body> seul dès qu'un enfant en
   position absolue déborde — c'était exactement le cas ici. */
html {
	-webkit-text-size-adjust: 100%;
	overflow-x: clip;
	/* Le corps passe en position fixe quand la fenêtre s'ouvre : sans fond ici,
	   certains navigateurs repeignent la toile en blanc l'espace d'une image. */
	background: var(--papier);
}

body {
	margin: 0;
	width: 100%;
	background: var(--papier);
	color: var(--encre);
	font-family: var(--texte);
	font-weight: 500;
	font-size: 16.5px;
	line-height: 1.7;
	overflow-x: clip;
}

img { max-width: 100%; border: 0; }

a { color: var(--encre); text-decoration: none; }

h1, h2, h3, h4, .titre-bloc { font-family: var(--titre); font-weight: 700; }

/* --- Graisses : Rodin dans les menus du jeu est franchement gras ---
   Seules 500 / 700 / 900 existent dans cette police : pas de 600, sinon
   le navigateur fabrique une fausse graisse. */
.menu a, .reseaux a, .barre-sceau, .actions a, .tag,
.plateformes a, .note strong, .barre a:hover {
	font-weight: 700;
}
.cadre b, .marque-sous, .menu a .indice, .entete-section .compte,
.categorie .num, .visuel .matricule, .barre a, .pied, .boot-inner {
	font-weight: 500;
}

/* --- L'ombre décalée, posée sur tout ce qui relève de l'interface --- */
.marque-sous, .menu a, .reseaux a,
.entete-section h2, .entete-section .compte,
.categorie h3, .categorie .num,
.note, .pied, .cadre b, .tag {
	text-shadow: var(--ombre-papier);
}

/* Sur les boîtes sombres, l'ombre passe au noir */
.fiche-corps h4, .fiche-corps p, .actions a, .visuel .matricule,
.barre-sceau, .barre a {
	text-shadow: var(--ombre-boite);
}
.fiche-corps p { text-shadow: 1px 1px 0 rgba(16, 15, 12, .45); }

/* Sous 12px, le décalage se réduit : sinon l'ombre mange la lettre */
.cadre b, .entete-section .compte, .categorie .num,
.menu a .indice, .reseaux a, .actions a,
.visuel .matricule, .barre a, .pied {
	text-shadow: 1px 1px 0 rgba(69, 65, 56, .22);
}
.visuel .matricule, .barre a, .actions a {
	text-shadow: 1px 1px 0 rgba(16, 15, 12, .5);
}

/* Un fond clair reprend l'ombre claire, sinon le décalage bave */
.menu a:hover, .menu a:focus-visible,
.reseaux a:hover, .reseaux a:focus-visible,
.barre a:hover, .barre a:focus-visible { text-shadow: var(--ombre-boite); }

.actions a:hover, .actions a:focus-visible { text-shadow: var(--ombre-papier); }

::selection { background: var(--encre); color: var(--papier-clair); }

/* Un mot marqué : petite étiquette carrée */
.tag {
	font-family: var(--titre);
	font-size: 10px; letter-spacing: .18em; text-transform: uppercase;
	padding: 2px 7px; margin-left: 8px;
	border: 1px solid currentColor; color: var(--rouge);
	vertical-align: middle; white-space: nowrap;
}

/* --------------------------------------------------------------------------
   3. Textures — grain, lignes de balayage, vignettage
   Tout est généré en CSS/SVG : aucune image à télécharger.
   -------------------------------------------------------------------------- */
.grain, .balayage {
	position: fixed; inset: 0;
	pointer-events: none;
	z-index: 60;
}

/* Le grain déborde du cadre : il se déplace de quelques pourcents,
   sans cet excédent une bande nue apparaîtrait sur un bord. */
.grain {
	inset: -6%;
	opacity: .24; mix-blend-mode: multiply;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
	animation: grain-derive 1.1s steps(3, end) infinite;
}

.balayage {
	background-image: repeating-linear-gradient(
		to bottom,
		rgba(69, 65, 56, .085) 0,
		rgba(69, 65, 56, .085) 1px,
		transparent 1px,
		transparent 3px
	);
	opacity: .8;
}

/* Le vignettage se pose sur le fond, pas par-dessus le contenu */
body::before {
	content: '';
	position: fixed; inset: 0; z-index: 0; pointer-events: none;
	background: radial-gradient(120% 90% at 50% 40%, transparent 40%, rgba(69, 65, 56, .16) 100%);
}

@keyframes grain-derive {
	0%   { transform: translate3d(0, 0, 0); }
	33%  { transform: translate3d(-2%, 1%, 0); }
	66%  { transform: translate3d(1%, -2%, 0); }
	100% { transform: translate3d(0, 0, 0); }
}

/* --------------------------------------------------------------------------
   4. Cadre ATH — équerres dans les coins et étiquettes de bord
   -------------------------------------------------------------------------- */
.cadre { position: fixed; inset: 0; pointer-events: none; z-index: 55; }

.cadre i {
	position: absolute; width: 26px; height: 26px;
	border: 0 solid var(--trait-fort);
}
.cadre i:nth-child(1) { top: 14px;    left: 14px;  border-top-width: 1px; border-left-width: 1px; }
.cadre i:nth-child(2) { top: 14px;    right: 14px; border-top-width: 1px; border-right-width: 1px; }
.cadre i:nth-child(3) { bottom: 14px; left: 14px;  border-bottom-width: 1px; border-left-width: 1px; }
.cadre i:nth-child(4) { bottom: 14px; right: 14px; border-bottom-width: 1px; border-right-width: 1px; }

.cadre b {
	position: absolute;
	font-family: var(--titre);
	font-size: 9.5px; letter-spacing: .3em; text-transform: uppercase;
	color: var(--encre-pale);
}
.cadre b.gauche {
	left: 20px; top: 50%;
	transform: rotate(180deg) translateY(50%);
	writing-mode: vertical-rl;
}
.cadre b.bas { bottom: 20px; left: 50%; transform: translateX(-50%); }

/* Petit carré clignotant collé à l'étiquette du bas */
.cadre b.bas::before {
	content: ''; display: inline-block;
	width: 5px; height: 5px; margin-right: 10px;
	background: var(--encre-pale);
	animation: pouls 2.4s steps(2, end) infinite;
}

@keyframes pouls { 0%, 60% { opacity: 1; } 61%, 100% { opacity: .15; } }

/* --------------------------------------------------------------------------
   5. Séquence de démarrage
   -------------------------------------------------------------------------- */
.is-booting, .is-booting body { overflow: hidden; }
.is-booting .page { opacity: 0; }
.page { transition: opacity 620ms ease; }

.boot {
	position: fixed; inset: 0; z-index: 200;
	display: none;
	background: #100f0d;
	color: #cfcbb7;
	font-family: var(--titre);
	cursor: pointer;
}
.is-booting .boot { display: block; }

.boot-inner {
	position: absolute; left: 50%; top: 50%;
	transform: translate(-50%, -50%);
	width: min(560px, 82vw);
	font-size: 13px; letter-spacing: .22em; text-transform: uppercase;
	line-height: 2.4;
}

.boot-inner p { margin: 0; opacity: 0; display: flex; gap: 14px; }
.boot-inner p.vu { opacity: 1; }
.boot-inner p span:first-child { color: #6d6858; }
.boot-inner p span:last-child { margin-left: auto; color: #8f8a76; }
.boot-inner p.vu span:last-child { color: #cfcbb7; }

.boot-barre {
	margin-top: 26px; height: 1px; background: #302d27; position: relative;
}
.boot-barre span {
	position: absolute; inset: 0 auto 0 0; width: 0;
	background: #cfcbb7;
	transition: width 240ms linear;
}
.boot-passer {
	position: absolute; right: 22px; bottom: 20px;
	font-size: 9.5px; letter-spacing: .3em; color: #575347;
}
.boot::after {
	content: ''; position: absolute; inset: 0; pointer-events: none;
	background-image: repeating-linear-gradient(to bottom,
		rgba(255, 255, 255, .045) 0, rgba(255, 255, 255, .045) 1px,
		transparent 1px, transparent 3px);
}

/* --------------------------------------------------------------------------
   6. Accueil
   -------------------------------------------------------------------------- */
.enveloppe { position: relative; z-index: 1; }

.accueil {
	min-height: 100vh;
	min-height: 100svh;
	display: flex; align-items: center; justify-content: center;
	padding: 80px 26px 60px;
	position: relative;
	/* Les tranches décalées du titre sortent de quelques pixels à droite */
	overflow-x: clip;
}

.accueil-boite { width: min(760px, 100%); text-align: center; }

/* Le logo passe en deux tons pour se fondre dans le menu ;
   il retrouve ses couleurs au survol, comme les visuels de projets. */
.logo-cadre { position: relative; display: inline-block; }
.logo-cadre img {
	width: min(330px, 68vw); display: block;
	filter: grayscale(1) contrast(1.08) brightness(.62) sepia(.22);
	mix-blend-mode: multiply;
	transition: filter 420ms ease;
}
.logo-cadre:hover img { filter: none; mix-blend-mode: normal; }

.marque {
	font-family: var(--titre);
	font-size: clamp(34px, 10.5vw, 92px);
	letter-spacing: .3em; text-transform: uppercase;
	margin: 6px 0 0; padding-left: .3em;
	line-height: 1;
	font-weight: 700;
	text-shadow: .07em .07em 0 rgba(69, 65, 56, .18);
}

.marque-sous {
	display: block;
	font-family: var(--titre);
	font-size: 10.5px; letter-spacing: .42em; text-transform: uppercase;
	color: var(--encre-pale);
	margin-top: 18px;
}

/* Filet double, comme les séparateurs du menu du jeu */
.filet {
	border: 0; height: 3px; margin: 26px auto;
	width: 100%; max-width: 520px;
	background:
		linear-gradient(var(--trait-fort), var(--trait-fort)) top / 100% 1px no-repeat,
		linear-gradient(var(--trait), var(--trait)) bottom / 100% 1px no-repeat;
}

/* --- le menu : chaque rangée s'inverse en boîte sombre au survol --- */
.menu { margin: 26px auto 0; width: min(430px, 100%); text-align: left; }

.menu a {
	position: relative; isolation: isolate;
	display: flex; align-items: center; gap: 14px;
	padding: 11px 16px;
	font-family: var(--titre);
	font-size: 14.5px; letter-spacing: .22em; text-transform: uppercase;
	border-bottom: 1px solid var(--trait);
	transition: color var(--transition), padding-left var(--transition);
	overflow: hidden;
}

/* La boîte sombre glisse depuis la gauche */
.menu a::before {
	content: ''; position: absolute; inset: 0;
	background: var(--boite);
	transform: scaleX(0); transform-origin: left center;
	transition: transform var(--transition);
	z-index: -1;
}
.menu a > * { position: relative; }

.menu a:hover, .menu a:focus-visible {
	color: var(--sur-boite); outline: none; padding-left: 26px;
}
.menu a:hover::before, .menu a:focus-visible::before { transform: scaleX(1); }

/* Le curseur carré de NieR */
.menu a .puce {
	width: 7px; height: 7px; flex: 0 0 7px;
	border: 1px solid currentColor;
	transition: background-color var(--transition), transform var(--transition);
}
.menu a:hover .puce, .menu a:focus-visible .puce {
	background: currentColor; transform: rotate(45deg);
}

.menu a .indice {
	margin-left: auto;
	font-size: 9.5px; letter-spacing: .26em; color: var(--encre-pale);
	transition: color var(--transition);
}
.menu a:hover .indice, .menu a:focus-visible .indice { color: var(--sur-boite-pale); }

/* --- les réseaux, en petites cases --- */
.reseaux {
	display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;
	margin: 30px 0 0;
}
.reseaux a {
	padding: 7px 13px;
	font-family: var(--titre);
	font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
	border: 1px solid var(--trait);
	transition: background-color var(--transition), color var(--transition), border-color var(--transition);
}
.reseaux a:hover, .reseaux a:focus-visible {
	background: var(--boite); color: var(--sur-boite);
	border-color: var(--boite); outline: none;
}

/* --------------------------------------------------------------------------
   7. Barre ATH collante
   -------------------------------------------------------------------------- */
.barre {
	position: fixed; top: 0; left: 0; right: 0; z-index: 50;
	background: var(--boite);
	border-bottom: 1px solid var(--boite-bas);
	transform: translateY(-100%);
	transition: transform 260ms cubic-bezier(.2, .7, .3, 1);
}
.barre.vue { transform: translateY(0); }

.barre-inner {
	max-width: 1280px; margin: 0 auto;
	display: flex; align-items: center; gap: 4px;
	padding: 0 22px;
	overflow-x: auto; scrollbar-width: none;
}
.barre-inner::-webkit-scrollbar { display: none; }

.barre-sceau {
	font-family: var(--titre);
	font-size: 11px; letter-spacing: .34em; text-transform: uppercase;
	color: var(--sur-boite); padding: 14px 22px 14px 0;
	margin-right: auto; white-space: nowrap;
}
.barre-sceau::before {
	content: ''; display: inline-block;
	width: 6px; height: 6px; margin-right: 12px;
	background: var(--sur-boite); transform: rotate(45deg);
}

.barre a {
	padding: 14px 16px;
	font-family: var(--titre);
	font-size: 10.5px; letter-spacing: .22em; text-transform: uppercase;
	color: var(--sur-boite-pale); white-space: nowrap;
	transition: color var(--transition), background-color var(--transition);
}
.barre a:hover, .barre a:focus-visible {
	color: var(--boite); background: var(--sur-boite); outline: none;
}

/* --------------------------------------------------------------------------
   8. Section des projets
   -------------------------------------------------------------------------- */
.projets {
	background: var(--papier-fonce);
	border-top: 1px solid var(--trait-fort);
	padding: 0 26px 90px;
	position: relative;
	/* La colonne claire de la §15.7 traverse « 100vw + 200px » : sans cette
	   coupe, elle allonge la page de 380 px vers la droite à chaque passage,
	   ce qui rendait le défilement horizontal intermittent sur mobile. */
	overflow-x: clip;
}

.contenu { max-width: 1280px; margin: 0 auto; position: relative; z-index: 1; }

.entete-section {
	padding: 84px 0 10px;
	display: flex; align-items: baseline; gap: 20px;
}
.entete-section h2 {
	font-size: clamp(30px, 5vw, 52px);
	letter-spacing: .22em; text-transform: uppercase;
	margin: 0;
}
.entete-section .compte {
	font-family: var(--titre);
	font-size: 10.5px; letter-spacing: .26em; color: var(--encre-pale);
	margin-left: auto; white-space: nowrap;
}

/* Titre de catégorie : carré + libellé + filet qui court jusqu'au bord */
.categorie {
	display: flex; align-items: center; gap: 16px;
	margin: 68px 0 26px;
}
.categorie:first-of-type { margin-top: 40px; }

.categorie .carre {
	width: 10px; height: 10px; flex: 0 0 10px;
	background: var(--encre);
}
.categorie h3 {
	margin: 0;
	font-size: 17px; letter-spacing: .3em; text-transform: uppercase;
	white-space: nowrap;
}
.categorie .rail {
	flex: 1 1 auto; height: 3px;
	background:
		linear-gradient(var(--trait-fort), var(--trait-fort)) top / 100% 1px no-repeat,
		linear-gradient(var(--trait), var(--trait)) bottom / 100% 1px no-repeat;
}
.categorie .num {
	font-family: var(--titre);
	font-size: 10px; letter-spacing: .24em; color: var(--encre-pale);
}

/* --- la grille --- */
.grille {
	display: grid; gap: 22px;
	/* min(330px, 100%) : sur un écran plus étroit que 330px, la piste suit la
	   largeur disponible au lieu de forcer la grille à déborder. */
	grid-template-columns: repeat(auto-fill, minmax(min(330px, 100%), 1fr));
}

/* --------------------------------------------------------------------------
   9. Fiche de projet — la boîte sombre
   -------------------------------------------------------------------------- */
.fiche {
	position: relative;
	min-width: 0;                      /* la fiche suit sa colonne, jamais l'inverse */
	overflow-wrap: anywhere;           /* un titre ou une URL sans espace ne l'élargit pas */
	display: flex; flex-direction: column;
	background: linear-gradient(var(--boite-haut), var(--boite-bas));
	color: var(--sur-boite);
	border: 1px solid var(--boite-bas);
	transition: transform var(--transition), box-shadow var(--transition);
}
.fiche:hover { transform: translateY(-3px); box-shadow: 0 14px 0 -8px rgba(69, 65, 56, .3); }

.fiche.eteinte { opacity: .55; }
.fiche.eteinte:hover { opacity: .8; }

/* Équerres claires dans les coins de la boîte */
.fiche > .equerres i {
	position: absolute; width: 13px; height: 13px; z-index: 3;
	border: 0 solid var(--sur-boite-pale); opacity: .5;
	transition: opacity var(--transition);
}
.fiche > .equerres i:nth-child(1) { top: 5px;    left: 5px;  border-top-width: 1px; border-left-width: 1px; }
.fiche > .equerres i:nth-child(2) { top: 5px;    right: 5px; border-top-width: 1px; border-right-width: 1px; }
.fiche > .equerres i:nth-child(3) { bottom: 5px; left: 5px;  border-bottom-width: 1px; border-left-width: 1px; }
.fiche > .equerres i:nth-child(4) { bottom: 5px; right: 5px; border-bottom-width: 1px; border-right-width: 1px; }
.fiche:hover > .equerres i { opacity: 1; }

/* --- le visuel : image de fond, deux couches --- */
.visuel {
	position: relative; display: block;
	isolation: isolate;                /* le mélange des glitchs reste dans le cadre */
	aspect-ratio: 16 / 11;
	overflow: hidden;
	border-bottom: 1px solid var(--boite-bas);
	background: var(--boite-bas);
}

.visuel .couche {
	position: absolute; inset: 0;
	background-image: var(--shot);
	background-size: cover;
	background-position: center;
	transition: opacity 420ms ease, transform 620ms cubic-bezier(.2, .7, .3, 1);
}

/* Couche du bas : deux tons, accordée au papier */
.visuel .couche-ton {
	filter: grayscale(1) sepia(.42) contrast(1.12) brightness(.82);
}
/* Couche du haut : les vraies couleurs, révélées au survol */
.visuel .couche-couleur { opacity: 0; }

.fiche:hover .visuel .couche-couleur { opacity: 1; }
.fiche:hover .visuel .couche { transform: scale(1.035); }

/* Voile pour que le texte et les glitchs restent lisibles */
.visuel::after {
	content: ''; position: absolute; inset: 0; z-index: 2;
	background:
		linear-gradient(to top, rgba(58, 55, 46, .82) 0%, rgba(58, 55, 46, .12) 52%, rgba(58, 55, 46, .3) 100%);
	transition: opacity var(--transition);
}
.fiche:hover .visuel::after { opacity: .72; }

/* Numéro de fiche, en haut à droite du visuel */
.visuel .matricule {
	position: absolute; top: 10px; right: 12px; z-index: 4;
	font-family: var(--titre);
	font-size: 10px; letter-spacing: .24em;
	color: var(--sur-boite); opacity: .72;
}

/* --------------------------------------------------------------------------
   10. Corruption de données — coin inférieur gauche du visuel
   -------------------------------------------------------------------------- */
.glitch {
	position: absolute; left: 0; bottom: 0; z-index: 5;
	width: 62%; height: 54%;
	pointer-events: none;
}

/* Blocs de données */
.glitch i {
	position: absolute; display: block;
	background: var(--sur-boite);
	mix-blend-mode: screen;
	opacity: .85;
}
.glitch i:nth-child(1) {
	left: 10px; bottom: 12px; width: 46px; height: 7px;
	animation: bloc-a 3.8s steps(1, end) infinite;
}
.glitch i:nth-child(2) {
	left: 10px; bottom: 23px; width: 22px; height: 4px;
	animation: bloc-b 5.2s steps(1, end) infinite;
}
.glitch i:nth-child(3) {
	left: 62px; bottom: 12px; width: 9px; height: 9px;
	animation: bloc-c 4.4s steps(1, end) infinite;
}
.glitch i:nth-child(4) {
	left: 10px; bottom: 34px; width: 13px; height: 3px;
	background: var(--rouge); mix-blend-mode: normal;
	animation: bloc-d 6.6s steps(1, end) infinite;
}

/* Damier de pixels qui se déchire */
.glitch::before {
	content: ''; position: absolute;
	left: 8px; bottom: 44px; width: 78px; height: 14px;
	background-image:
		linear-gradient(90deg, var(--sur-boite) 25%, transparent 25%, transparent 50%,
		                       var(--sur-boite) 50%, var(--sur-boite) 75%, transparent 75%);
	background-size: 8px 100%;
	opacity: .3; mix-blend-mode: screen;
	animation: damier 7s steps(1, end) infinite;
}

/* Ligne de balayage qui remonte le coin */
.glitch::after {
	content: ''; position: absolute;
	left: 0; bottom: 0; width: 100%; height: 1px;
	background: linear-gradient(90deg, var(--sur-boite), transparent);
	opacity: .4;
	animation: scan 5.6s ease-in-out infinite;
}

@keyframes bloc-a {
	0%, 42%      { transform: none; opacity: .8; }
	43%, 46%     { transform: translateX(16px) scaleX(1.5); opacity: 1; }
	47%, 88%     { transform: none; opacity: .8; }
	89%, 91%     { transform: translateX(-6px); opacity: .3; }
	92%, 100%    { transform: none; opacity: .8; }
}
@keyframes bloc-b {
	0%, 24%   { transform: none; opacity: .7; }
	25%, 28%  { transform: translateX(38px) scaleX(2.4); opacity: 1; }
	29%, 70%  { transform: none; opacity: .7; }
	71%, 73%  { opacity: 0; }
	74%, 100% { transform: none; opacity: .7; }
}
@keyframes bloc-c {
	0%, 60%   { transform: none; opacity: .9; }
	61%, 64%  { transform: translate(12px, -8px); opacity: .4; }
	65%, 100% { transform: none; opacity: .9; }
}
@keyframes bloc-d {
	0%, 80%   { opacity: 0; }
	81%, 85%  { opacity: .9; transform: scaleX(3); }
	86%, 100% { opacity: 0; }
}
@keyframes damier {
	0%, 55%   { opacity: .22; clip-path: inset(0 0 0 0); }
	56%, 60%  { opacity: .5;  clip-path: inset(0 32% 0 0); }
	61%, 100% { opacity: .22; clip-path: inset(0 0 0 0); }
}
@keyframes scan {
	0%, 100% { transform: translateY(0);    opacity: .12; }
	45%      { transform: translateY(-58px); opacity: .5; }
	55%      { transform: translateY(-62px); opacity: 0; }
}

/* --- au survol : la corruption part en vrille --- */
.fiche:hover .glitch i:nth-child(1) { animation-duration: .55s; }
.fiche:hover .glitch i:nth-child(2) { animation-duration: .42s; }
.fiche:hover .glitch i:nth-child(3) { animation-duration: .68s; }
.fiche:hover .glitch i:nth-child(4) { animation-duration: .8s; }
.fiche:hover .glitch::before        { animation-duration: .9s; opacity: .5; }
.fiche:hover .glitch::after         { animation-duration: 1.1s; }

/* Tranches décalées de l'image, en rouge et cyan : le vrai bruit de NieR.
   Deux couches de plus, invisibles au repos. */
.visuel .tranche {
	position: absolute; inset: 0; z-index: 3;
	background-image: var(--shot);
	background-size: cover; background-position: center;
	opacity: 0; mix-blend-mode: screen;
	pointer-events: none;
}
.visuel .tranche-r { filter: sepia(1) saturate(6) hue-rotate(-32deg) brightness(.9); }
.visuel .tranche-c { filter: sepia(1) saturate(5) hue-rotate(130deg) brightness(.9); }

.fiche:hover .visuel .tranche-r { animation: tranche-r 1.4s steps(1, end) infinite; }
.fiche:hover .visuel .tranche-c { animation: tranche-c 1.9s steps(1, end) infinite; }

@keyframes tranche-r {
	0%, 78%   { opacity: 0; clip-path: inset(64% 0 22% 0); transform: none; }
	79%, 84%  { opacity: .55; transform: translateX(-9px); }
	85%, 100% { opacity: 0; }
}
@keyframes tranche-c {
	0%, 61%   { opacity: 0; clip-path: inset(76% 0 8% 0); transform: none; }
	62%, 67%  { opacity: .45; transform: translateX(11px); }
	68%, 100% { opacity: 0; }
}

/* --------------------------------------------------------------------------
   11. Contenu de la fiche
   -------------------------------------------------------------------------- */
.fiche-corps {
	padding: 20px 22px 22px;
	display: flex; flex-direction: column; flex: 1 1 auto;
}

.fiche-corps h4 {
	margin: 0 0 12px;
	font-size: 19px; letter-spacing: .1em; text-transform: uppercase;
	line-height: 1.35;
}
.fiche-corps h4 a { color: inherit; }
.fiche-corps h4 a:hover { text-decoration: underline; text-underline-offset: 5px; }

.fiche-corps p {
	margin: 0 0 18px;
	font-size: 14.5px; line-height: 1.72; font-weight: 500;
	color: var(--sur-boite-pale);
}
.fiche-corps p:last-child { margin-bottom: 0; }

/* Boutons de la fiche : cases claires qui s'inversent */
.actions {
	margin-top: auto;
	display: flex; flex-wrap: wrap; gap: 8px;
	padding-top: 6px;
}
.actions a {
	display: inline-flex; align-items: center; gap: 9px;
	padding: 8px 14px;
	font-family: var(--titre);
	font-size: 10.5px; letter-spacing: .18em; text-transform: uppercase;
	color: var(--sur-boite);
	border: 1px solid rgba(207, 203, 183, .38);
	transition: background-color var(--transition), color var(--transition), border-color var(--transition);
}
.actions a::before {
	content: ''; width: 5px; height: 5px;
	border: 1px solid currentColor;
	transition: background-color var(--transition), transform var(--transition);
}
.actions a:hover, .actions a:focus-visible {
	background: var(--sur-boite); color: var(--boite);
	border-color: var(--sur-boite); outline: none;
}
.actions a:hover::before, .actions a:focus-visible::before {
	background: currentColor; transform: rotate(45deg);
}

/* Icônes de plateformes musicales : monochromes, comme le reste */
.plateformes { display: flex; gap: 6px; margin-top: auto; padding-top: 8px; }
.plateformes a {
	width: 38px; height: 34px;
	display: inline-flex; align-items: center; justify-content: center;
	border: 1px solid rgba(207, 203, 183, .38);
	color: var(--sur-boite);
	transition: background-color var(--transition), color var(--transition), border-color var(--transition);
}
.plateformes a:hover, .plateformes a:focus-visible {
	background: var(--sur-boite); color: var(--boite);
	border-color: var(--sur-boite); outline: none;
}
.plateformes svg, .plateformes i { font-size: 15px; }

/* --------------------------------------------------------------------------
   12. Note de bas de section et pied de page
   -------------------------------------------------------------------------- */
.note {
	margin: 30px 0 0; padding: 18px 22px;
	border: 1px solid var(--trait);
	border-left: 3px solid var(--encre);
	background: rgba(214, 210, 191, .5);
	font-size: 15px;
}
.note a {
	text-decoration: underline; text-underline-offset: 4px;
	text-decoration-thickness: 1px;
}
.note a:hover { background: var(--encre); color: var(--papier-clair); text-decoration: none; }

.pied {
	border-top: 1px solid var(--trait-fort);
	margin-top: 76px; padding: 30px 0 8px;
	display: flex; flex-wrap: wrap; gap: 14px; align-items: center;
	font-family: var(--titre);
	font-size: 10px; letter-spacing: .26em; text-transform: uppercase;
	color: var(--encre-pale);
}
.pied .haut { margin-left: auto; }
.pied .haut:hover { color: var(--encre); }

/* --------------------------------------------------------------------------
   13. Écrans étroits
   -------------------------------------------------------------------------- */
@media screen and (max-width: 760px) {
	.grille { grid-template-columns: minmax(0, 1fr); }
	.entete-section { flex-direction: column; gap: 6px; }
	.entete-section .compte { margin-left: 0; }
	.categorie { gap: 12px; margin: 52px 0 22px; }
	.categorie h3 { font-size: 14px; letter-spacing: .22em; }
	.cadre b.gauche { display: none; }
	.projets { padding-left: 18px; padding-right: 18px; }
	.marque { letter-spacing: .16em; padding-left: .16em; }
}

@media screen and (max-width: 420px) {
	.marque { letter-spacing: .1em; padding-left: .1em; }
	.marque-sous { letter-spacing: .28em; }
	.categorie .num { display: none; }
	.fiche-corps { padding: 16px 16px 18px; }
}

/* --------------------------------------------------------------------------
   14. Mouvement réduit
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	.grain,
	.cadre b.bas::before,
	.glitch i, .glitch::before, .glitch::after,
	.visuel .tranche {
		animation: none !important;
	}
	.fiche:hover { transform: none; }
	.fiche:hover .visuel .couche { transform: none; }
	* { transition-duration: 1ms !important; }
}

/* ==========================================================================
   15. Couche d'effets — texte corrompu, balayages, apparitions
   ========================================================================== */

/* --------------------------------------------------------------------------
   15.1 Texte corrompu
   Un élément portant data-texte reçoit deux copies de lui-même, décalées
   en rouge et en cyan, découpées en tranches. Au repos elles dorment ;
   elles se réveillent au survol, ou quand JS pose la classe .corrompu.
   -------------------------------------------------------------------------- */
.txt-glitch { position: relative; display: inline-block; }

.txt-glitch::before,
.txt-glitch::after {
	content: attr(data-texte);
	position: absolute; left: 0; top: 0;
	width: 100%;
	pointer-events: none;
	opacity: 0;
	text-shadow: none;
}
.txt-glitch::before { color: var(--rouge); }
.txt-glitch::after  { color: var(--cyan); }

.txt-glitch:hover::before,
.corrompu .txt-glitch::before,
.txt-glitch.corrompu::before {
	animation: txt-r 620ms steps(1, end) infinite;
}
.txt-glitch:hover::after,
.corrompu .txt-glitch::after,
.txt-glitch.corrompu::after {
	animation: txt-c 780ms steps(1, end) infinite;
}

@keyframes txt-r {
	0%,  100% { opacity: 0; transform: none; clip-path: inset(0 0 0 0); }
	10%       { opacity: .9; transform: translate(-3px, 1px); clip-path: inset(12% 0 62% 0); }
	22%       { opacity: .9; transform: translate(4px, -1px); clip-path: inset(58% 0 18% 0); }
	32%       { opacity: 0; }
	64%       { opacity: .8; transform: translate(-2px, 0);   clip-path: inset(34% 0 44% 0); }
	72%       { opacity: 0; }
}
@keyframes txt-c {
	0%,  100% { opacity: 0; transform: none; clip-path: inset(0 0 0 0); }
	16%       { opacity: .8; transform: translate(3px, -1px); clip-path: inset(4% 0 70% 0); }
	28%       { opacity: 0; }
	54%       { opacity: .85; transform: translate(-4px, 1px); clip-path: inset(66% 0 6% 0); }
	66%       { opacity: 0; }
}

/* Un titre entièrement corrompu tremble aussi */
.corrompu .txt-glitch,
.txt-glitch.corrompu { animation: tremble 340ms steps(1, end) infinite; }

@keyframes tremble {
	0%, 100% { transform: none; }
	25%      { transform: translateX(-1px) skewX(-.6deg); }
	50%      { transform: translateX(2px); }
	75%      { transform: translateX(-1px) skewX(.4deg); }
}

/* --------------------------------------------------------------------------
   15.2 Titre d'accueil : découpé en tranches en permanence, discrètement
   -------------------------------------------------------------------------- */
.marque { position: relative; isolation: isolate; }

.marque .tranche-txt {
	position: absolute; left: 0; top: 0; width: 100%;
	padding-left: inherit;             /* suit le lettrage du titre */
	text-shadow: none;
	color: var(--encre);
	pointer-events: none;
	opacity: 0;
}
.marque .tranche-txt:nth-of-type(1) { animation: marque-a 7.5s steps(1, end) infinite; }
.marque .tranche-txt:nth-of-type(2) { animation: marque-b 11s  steps(1, end) infinite; }

@keyframes marque-a {
	0%, 92%   { opacity: 0; }
	93%, 95%  { opacity: 1; transform: translateX(-8px); clip-path: inset(28% 0 52% 0); }
	96%, 100% { opacity: 0; }
}
@keyframes marque-b {
	0%, 74%   { opacity: 0; }
	75%, 77%  { opacity: 1; transform: translateX(11px); clip-path: inset(60% 0 14% 0); color: var(--rouge); }
	78%, 100% { opacity: 0; }
}

/* --------------------------------------------------------------------------
   15.3 Balayage plein écran — un « rafraîchissement » d'interface
   -------------------------------------------------------------------------- */
.sweep {
	position: fixed; left: 0; right: 0; top: 0; height: 34vh;
	z-index: 58; pointer-events: none; opacity: 0;
	background: linear-gradient(to bottom,
		transparent 0%,
		rgba(207, 203, 183, .05) 62%,
		rgba(69, 65, 56, .13) 92%,
		rgba(69, 65, 56, .3) 99%,
		transparent 100%);
}
.sweep.passe { animation: sweep 1.35s cubic-bezier(.35, 0, .25, 1) 1; }

@keyframes sweep {
	0%   { opacity: 0;  transform: translateY(-40vh); }
	12%  { opacity: 1; }
	88%  { opacity: 1; }
	100% { opacity: 0;  transform: translateY(115vh); }
}

/* Secousse de l'écran, très courte, sur les gros glitchs */
.secousse { animation: secousse 260ms steps(1, end) 1; }
@keyframes secousse {
	0%, 100% { transform: none; }
	20%      { transform: translate(-3px, 1px); }
	40%      { transform: translate(2px, -2px); }
	60%      { transform: translate(-2px, -1px); }
	80%      { transform: translate(1px, 2px); }
}

/* --------------------------------------------------------------------------
   15.4 Apparition des fiches au défilement
   La boîte se dévoile de gauche à droite, comme un élément d'interface
   qui se dessine, avec une barre claire qui court devant.
   -------------------------------------------------------------------------- */
/* Règle d'or : la fiche est visible par défaut. L'animation joue VERS cet
   état de repos, sans jamais le retenir — donc aucune fiche ne peut rester
   invisible, que JavaScript soit absent, en retard ou en panne.
   Pas de fill-mode : rien ne subsiste avant ni après l'animation. */
.fiche.entre {
	animation: fiche-entre 620ms cubic-bezier(.2, .75, .25, 1);
}
.fiche.entre::after {
	content: ''; position: absolute; inset: 0; z-index: 10;
	pointer-events: none;
	background: linear-gradient(90deg, transparent 0%, rgba(207, 203, 183, .5) 82%, var(--sur-boite) 100%);
	animation: fiche-barre 620ms cubic-bezier(.2, .75, .25, 1);
}

@keyframes fiche-entre {
	0%   { opacity: 0; clip-path: inset(0 100% 0 0); }
	30%  { opacity: 1; }
	100% { opacity: 1; clip-path: inset(0 0 0 0); }
}
@keyframes fiche-barre {
	0%   { clip-path: inset(0 100% 0 0); opacity: 1; }
	80%  { opacity: 1; }
	100% { clip-path: inset(0 0 0 0); opacity: 0; }
}

/* Les titres de catégorie se dessinent pareil, même principe */
.categorie .rail { transform-origin: left center; }
.categorie.entre .rail { animation: rail 700ms cubic-bezier(.2, .75, .25, 1); }
@keyframes rail { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.categorie.entre .carre { animation: carre 460ms steps(4, end); }
@keyframes carre {
	0%   { opacity: 0; transform: rotate(45deg) scale(.2); }
	100% { opacity: 1; transform: rotate(0) scale(1); }
}

/* --------------------------------------------------------------------------
   15.5 Fiche corrompue (posée au hasard par JS)
   -------------------------------------------------------------------------- */
.fiche.corrompu .visuel .couche-ton { animation: ton-saute 240ms steps(1, end) 3; }
.fiche.corrompu .glitch i           { animation-duration: .3s !important; }
.fiche.corrompu .glitch::before     { animation-duration: .4s !important; opacity: .6; }
.fiche.corrompu .visuel .tranche-r  { animation: tranche-r .5s steps(1, end) infinite; }
.fiche.corrompu .visuel .tranche-c  { animation: tranche-c .7s steps(1, end) infinite; }

@keyframes ton-saute {
	0%, 100% { transform: none; filter: grayscale(1) sepia(.42) contrast(1.12) brightness(.82); }
	35%      { transform: translateX(-7px); filter: grayscale(1) sepia(.42) contrast(2.4) brightness(1.3); }
	70%      { transform: translateX(5px);  filter: grayscale(1) sepia(.1) contrast(.7) brightness(.5); }
}

/* Bandeau d'erreur qui traverse la fiche corrompue */
.fiche .avarie {
	position: absolute; left: 0; right: 0; top: 46%;
	z-index: 12; pointer-events: none;
	height: 16px;
	display: flex; align-items: center;
	font-family: var(--titre);
	font-size: 9px; letter-spacing: .34em; text-transform: uppercase;
	color: var(--boite); background: var(--rouge);
	padding-left: 12px;
	opacity: 0; clip-path: inset(0 100% 0 0);
}
.fiche.corrompu .avarie { animation: avarie 900ms steps(1, end) 1; }

@keyframes avarie {
	0%       { opacity: 0; clip-path: inset(0 100% 0 0); }
	12%      { opacity: 1; clip-path: inset(0 0 0 0); }
	40%      { opacity: 1; transform: translateX(-4px); }
	52%      { opacity: 0; }
	62%      { opacity: 1; transform: translateX(3px); }
	100%     { opacity: 0; clip-path: inset(0 0 0 100%); }
}

/* --------------------------------------------------------------------------
   15.6 Curseur d'interface — deux traits qui suivent la souris
   -------------------------------------------------------------------------- */
.viseur {
	position: fixed; z-index: 57; pointer-events: none;
	opacity: 0; transition: opacity 400ms ease;
	mix-blend-mode: multiply;
}
.viseur.vu { opacity: .32; }
.viseur i {
	position: fixed; background: var(--encre);
}
.viseur i.h { left: 0; right: 0; height: 1px; }
.viseur i.v { top: 0; bottom: 0; width: 1px; }

/* --------------------------------------------------------------------------
   15.7 Bruit de fond animé dans la section des projets
   -------------------------------------------------------------------------- */
.projets::before {
	content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
	background-image:
		repeating-linear-gradient(90deg,
			rgba(69, 65, 56, .05) 0, rgba(69, 65, 56, .05) 1px,
			transparent 1px, transparent 64px);
	opacity: .7;
}

/* Une colonne claire qui glisse lentement derrière les fiches */
.projets::after {
	content: ''; position: absolute; top: 0; bottom: 0; width: 180px;
	z-index: 0; pointer-events: none;
	background: linear-gradient(90deg, transparent, rgba(214, 210, 191, .35), transparent);
	animation: colonne 26s linear infinite;
}
@keyframes colonne {
	0%   { transform: translateX(-200px); }
	100% { transform: translateX(calc(100vw + 200px)); }
}

/* --------------------------------------------------------------------------
   15.8 Compléments « mouvement réduit »
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	.txt-glitch::before, .txt-glitch::after,
	.marque .tranche-txt,
	.sweep, .secousse,
	.projets::after,
	.fiche .avarie,
	.fiche.corrompu .visuel .couche-ton {
		animation: none !important;
	}
	.fiche.entre, .fiche.entre::after,
	.categorie.entre .rail, .categorie.entre .carre { animation: none !important; }
	.viseur { display: none; }
}

/* ==========================================================================
   16. Fenêtre « Qui suis-je » — écran de données à la NieR
   Dimensionnée pour tenir d'un seul coup d'œil en 1080p comme en 1440p :
   largeur et hauteur plafonnées en pixels, puis en pourcentage de l'écran
   pour les affichages plus courts. Aucune barre de défilement en cible.
   ========================================================================== */
.modale {
	display: none;
	position: fixed; inset: 0;
	/* Sous le grain et les lignes de balayage (60) pour que la texture
	   passe aussi sur la fenêtre, au-dessus du cadre ATH (55). */
	z-index: 59;
	align-items: center; justify-content: center;
	padding: 24px;
}
.modale.est-ouverte { display: flex; }

/* Verrou de défilement. « overflow: hidden » sur <body> ne suffit pas sur
   Safari iOS : la page reste déplaçable au doigt, y compris latéralement.
   On fige donc réellement le corps, et le script remet le défilement là où
   il était à la fermeture (voir fenetre() dans index.php). */
.fenetre-ouverte, .fenetre-ouverte body { overflow: hidden; }
.fenetre-ouverte body {
	position: fixed;
	left: 0; right: 0;
	width: 100%;
}

/* Voile : la page derrière s'assombrit et se retire d'un cran */
.modale-fond {
	position: absolute; inset: 0;
	background: rgba(46, 43, 36, .72);
	animation: voile 280ms ease;
	cursor: pointer;
}
@keyframes voile { from { opacity: 0; } to { opacity: 1; } }

/* --- le panneau --- */
.modale-boite {
	position: relative;
	display: flex; flex-direction: column;
	width: min(1180px, 94vw);
	height: min(740px, 86vh);
	background: var(--papier-clair);
	border: 1px solid var(--encre);
	box-shadow: 14px 14px 0 -1px rgba(46, 43, 36, .35);
	overflow: hidden; isolation: isolate;
	animation: modale-entre 420ms cubic-bezier(.2, .75, .25, 1);
}

@keyframes modale-entre {
	0%   { opacity: 0; clip-path: inset(0 100% 0 0); transform: translateY(6px); }
	40%  { opacity: 1; }
	100% { opacity: 1; clip-path: inset(0 0 0 0); transform: translateY(0); }
}

/* La barre claire qui court devant le tracé, comme sur les fiches */
.modale-boite::after {
	content: ''; position: absolute; inset: 0; z-index: 12;
	pointer-events: none;
	opacity: 0;                        /* état de repos : effacée */
	background: linear-gradient(90deg, transparent 0%, rgba(69, 65, 56, .18) 84%, var(--encre) 100%);
	animation: fiche-barre 420ms cubic-bezier(.2, .75, .25, 1);
}

/* Équerres de la fenêtre */
.modale-boite > .equerres i {
	position: absolute; width: 16px; height: 16px; z-index: 10;
	border: 0 solid var(--encre); opacity: .75;
}
.modale-boite > .equerres i:nth-child(1) { top: 6px;    left: 6px;  border-top-width: 1px; border-left-width: 1px; }
.modale-boite > .equerres i:nth-child(2) { top: 6px;    right: 6px; border-top-width: 1px; border-right-width: 1px; }
.modale-boite > .equerres i:nth-child(3) { bottom: 6px; left: 6px;  border-bottom-width: 1px; border-left-width: 1px; }
.modale-boite > .equerres i:nth-child(4) { bottom: 6px; right: 6px; border-bottom-width: 1px; border-right-width: 1px; }

/* --------------------------------------------------------------------------
   16.1 En-tête : logo et nom en haut à gauche
   -------------------------------------------------------------------------- */
.modale-tete {
	display: flex; align-items: center; gap: 20px;
	padding: clamp(16px, 2.4vh, 26px) clamp(20px, 2.2vw, 32px) 0;
	flex: 0 0 auto;
}

.modale-logo {
	flex: 0 0 auto; display: block;
	width: clamp(56px, 7.6vh, 92px);
}
.modale-logo img {
	width: 100%; display: block;
	filter: grayscale(1) contrast(1.08) brightness(.6) sepia(.22);
	mix-blend-mode: multiply;
	transition: filter 420ms ease;
}
.modale-logo:hover img { filter: none; mix-blend-mode: normal; }

.modale-id { display: flex; flex-direction: column; gap: 4px; min-width: 0; }

.modale-nom {
	font-family: var(--titre); font-weight: 700;
	font-size: clamp(24px, 3.6vh, 40px);
	letter-spacing: .2em; text-transform: uppercase;
	line-height: 1;
	text-shadow: .05em .05em 0 rgba(69, 65, 56, .2);
}
.modale-role {
	font-family: var(--titre); font-weight: 500;
	font-size: clamp(9.5px, 1.25vh, 11.5px);
	letter-spacing: .26em; text-transform: uppercase;
	color: var(--encre-pale);
	text-shadow: 1px 1px 0 rgba(69, 65, 56, .22);
}

.modale-etiquette {
	margin-left: auto; align-self: flex-start;
	font-family: var(--titre); font-weight: 700;
	font-size: 9.5px; letter-spacing: .28em; text-transform: uppercase;
	color: var(--papier-clair); background: var(--encre);
	padding: 5px 12px; white-space: nowrap;
}

.modale-x {
	align-self: flex-start;
	font: inherit; font-size: 22px; line-height: 1;
	width: 34px; height: 34px; flex: 0 0 34px;
	display: flex; align-items: center; justify-content: center;
	background: none; color: var(--encre);
	border: 1px solid var(--trait); border-radius: 0;
	cursor: pointer;
	transition: background-color var(--transition), color var(--transition), border-color var(--transition);
}
.modale-x:hover, .modale-x:focus-visible {
	background: var(--encre); color: var(--papier-clair);
	border-color: var(--encre); outline: none;
}

.modale-boite .filet {
	margin: clamp(12px, 1.8vh, 20px) clamp(20px, 2.2vw, 32px);
	max-width: none; width: auto; flex: 0 0 auto;
}

/* --------------------------------------------------------------------------
   16.2 Corps : rail de données sombre à gauche, récit à droite
   -------------------------------------------------------------------------- */
.modale-corps {
	flex: 1 1 auto; min-height: 0;
	display: grid;
	grid-template-columns: clamp(210px, 21%, 280px) 1fr;
}

/* Le rail touche le bord gauche et le bas du panneau : c'est lui qui
   reçoit les blocs de corruption, comme les visuels des fiches. */
.modale-rail {
	background: linear-gradient(var(--boite-haut), var(--boite-bas));
	color: var(--sur-boite);
	padding: clamp(16px, 2.4vh, 26px) clamp(16px, 1.5vw, 24px) clamp(30px, 5vh, 56px);
	display: flex; flex-direction: column; gap: clamp(10px, 1.6vh, 18px);
	min-height: 0; overflow: hidden;
}

.rail-titre {
	display: flex; align-items: center; gap: 10px;
	font-family: var(--titre); font-weight: 700;
	font-size: 10px; letter-spacing: .28em; text-transform: uppercase;
	color: var(--sur-boite);
	text-shadow: 1px 1px 0 rgba(16, 15, 12, .5);
}
.rail-titre .carre { width: 8px; height: 8px; flex: 0 0 8px; background: var(--sur-boite); }

.modale-rail dl { margin: 0; display: flex; flex-direction: column; }
.modale-rail dt {
	font-family: var(--titre); font-weight: 500;
	font-size: 9px; letter-spacing: .24em; text-transform: uppercase;
	color: var(--sur-boite-pale);
	margin-bottom: 2px;
}
.modale-rail dd {
	margin: 0 0 clamp(7px, 1.1vh, 12px);
	padding-bottom: clamp(6px, 1vh, 10px);
	border-bottom: 1px solid rgba(207, 203, 183, .17);
	font-family: var(--titre); font-weight: 700;
	font-size: clamp(11.5px, 1.5vh, 13.5px);
	letter-spacing: .06em;
	text-shadow: 1px 1px 0 rgba(16, 15, 12, .5);
}
.modale-rail dd:last-of-type { border-bottom: 0; }

.rail-liens { margin-top: auto; display: flex; flex-wrap: wrap; gap: 6px; }
.rail-liens a {
	display: inline-flex; align-items: center; gap: 8px;
	padding: 6px 11px;
	font-family: var(--titre); font-weight: 700;
	font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase;
	color: var(--sur-boite);
	border: 1px solid rgba(207, 203, 183, .38);
	text-shadow: 1px 1px 0 rgba(16, 15, 12, .5);
	transition: background-color var(--transition), color var(--transition), border-color var(--transition);
}
.rail-liens a::before {
	content: ''; width: 5px; height: 5px; border: 1px solid currentColor;
	transition: background-color var(--transition), transform var(--transition);
}
.rail-liens a:hover, .rail-liens a:focus-visible {
	background: var(--sur-boite); color: var(--boite);
	border-color: var(--sur-boite); outline: none;
	text-shadow: 1px 1px 0 rgba(69, 65, 56, .22);
}
.rail-liens a:hover::before { background: currentColor; transform: rotate(45deg); }

/* --- le récit --- */
.modale-texte {
	padding: clamp(14px, 2.2vh, 24px) clamp(20px, 2.4vw, 36px) clamp(20px, 3vh, 32px);
	min-height: 0;
	/* En 1080p et 1440p tout tient : ce défilement n'est qu'un filet de
	   sécurité pour les écrans très courts, et sa barre reste discrète. */
	overflow-y: auto;
	scrollbar-width: thin;
	scrollbar-color: var(--trait) transparent;
}
.modale-texte::-webkit-scrollbar { width: 6px; }
.modale-texte::-webkit-scrollbar-thumb { background: var(--trait); }

.modale-texte h3 {
	margin: 0 0 clamp(8px, 1.4vh, 14px);
	font-size: clamp(12px, 1.5vh, 14px);
	font-weight: 700; letter-spacing: .26em; text-transform: uppercase;
	color: var(--encre-douce);
	text-shadow: 1px 1px 0 rgba(69, 65, 56, .22);
	display: flex; align-items: center; gap: 12px;
}
.modale-texte h3::after {
	content: ''; flex: 1 1 auto; height: 1px; background: var(--trait);
}

.modale-texte p {
	margin: 0 0 clamp(9px, 1.5vh, 15px);
	font-size: clamp(13px, .95vh + .28vw, 16px);
	line-height: 1.66;
	color: var(--encre-douce);
	text-shadow: 1px 1px 0 rgba(69, 65, 56, .14);
}
.modale-texte p:last-child { margin-bottom: 0; }
.modale-texte p strong { font-weight: 700; color: var(--encre); }

/* Exergue : la ligne de conclusion, encadrée à gauche */
.modale-texte .exergue {
	margin-top: clamp(12px, 2vh, 20px);
	padding: clamp(10px, 1.6vh, 15px) clamp(12px, 1.4vw, 18px);
	border: 1px solid var(--trait);
	border-left: 3px solid var(--encre);
	background: rgba(203, 199, 178, .5);
	font-weight: 700;
}

/* --------------------------------------------------------------------------
   16.3 Corruption dans le coin inférieur gauche du panneau
   Elle tombe sur le rail sombre : les blocs clairs y ressortent, exactement
   comme sur les visuels des fiches.
   -------------------------------------------------------------------------- */
.modale-boite > .glitch {
	width: clamp(160px, 20%, 260px);
	height: clamp(90px, 16vh, 130px);
	z-index: 11;
}

/* --------------------------------------------------------------------------
   16.4 Écrans étroits — hors cible, mais la fenêtre doit rester utilisable
   -------------------------------------------------------------------------- */
@media screen and (max-width: 860px) {
	.modale { padding: 12px; }
	.modale-boite { width: 100%; max-width: 100%; height: min(92vh, 900px); }
	.modale-corps {
		grid-template-columns: minmax(0, 1fr);   /* « 1fr » laissait le contenu élargir la colonne */
		overflow-y: auto; overflow-x: hidden;
	}
	.modale-rail, .modale-texte { min-width: 0; }
	.modale-rail { padding-bottom: 22px; }
	.modale-rail dd { overflow-wrap: anywhere; }
	.rail-liens { margin-top: 14px; }
	.modale-texte { overflow: visible; }
	.modale-texte p, .modale-texte .exergue { overflow-wrap: anywhere; }
	.modale-boite > .glitch { display: none; }
	.modale-etiquette { display: none; }

	/* En-tête. Le nom est un seul mot très espacé : il ne se coupe pas, donc
	   sans ces bornes il pousse le logo et la croix hors du panneau.
	   La croix : c'est l'étiquette « Qui suis-je » qui portait le
	   « margin-left: auto » — masquée ici, plus rien ne poussait la croix au
	   bout de la rangée. Elle reprend la consigne à son compte, sur une
	   rangée qui ne se coupe plus, et s'aligne sur le milieu du logo. */
	.modale-tete { flex-wrap: nowrap; gap: 12px; }
	.modale-logo { width: clamp(44px, 13vw, 64px); }
	.modale-id { flex: 1 1 auto; min-width: 0; }
	.modale-nom { font-size: clamp(19px, 6.4vw, 30px); letter-spacing: .12em; }
	.modale-role { letter-spacing: .18em; }
	.modale-x {
		margin-left: auto; align-self: center;
		flex: 0 0 36px; width: 36px; height: 36px;
	}

	/* La boîte « exergue » est le dernier élément du corps qui défile :
	   sans marge sous elle, elle colle au bord une fois descendu en bas. */
	.modale-texte .exergue { margin-bottom: 15px; }
}

@media (prefers-reduced-motion: reduce) {
	.modale-fond, .modale-boite, .modale-boite::after { animation: none !important; }
}
