/* ═══════════════════════════════════════════════════════════════════════════
   style.v4.css — la porte d'entrée de d4xw.com (index.php).

   Même identité visuelle que /public.php : fond noir, phosphore vert,
   Fira Code, scanlines.

   v3 (17/10/2026) : le titre n'est plus un texte glitché mais un grand « D4 »
   écrit en 0 et en 1 (canvas, /assets/d4-binaire.v1.js).
   v4 (17/10/2026, demande du user) : la planète est retirée de l'accueil. Il
   ne reste que le D4, agrandi et centré, et la porte. Partis avec elle : le
   canvas #d4-cloud et la zone élastique .stage qui lui faisait de la place.

   ⚠️ Le nom du fichier porte sa version. Le site est derrière Cloudflare : un
   statique qui change de CONTENU sans changer de NOM continue d'être servi
   périmé pendant des heures. Modifier ce fichier = le renommer (style.v4.css)
   et répercuter le <link> dans index.php.
   style.v2.css (titre glitché) et style.css (fond gris d'origine) sont laissés
   en place volontairement : ce sont les retours arrière (rien ici n'est suivi
   par git).
   ═══════════════════════════════════════════════════════════════════════════ */

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

html { height: 100%; }

body {
	min-height: 100%;
	background-color: #0a0a0a;
	color: #fff;
	font-family: "Fira Code", ui-monospace, monospace;
	/* Obligatoire depuis le passage à la police auto-hébergée : le lien Google
	   d'avant ne servait QUE la graisse 500, la variable va de 400 à 600 et
	   retomberait sur 400 — tout le texte maigrissait. */
	font-weight: 500;
	-webkit-text-size-adjust: 100%;
	overflow-x: hidden;
}

/* Halo central : un contre-jour très doux derrière le D4, qui le détache du
   noir pur sans éclaircir la page. */
.glow {
	position: fixed;
	left: 50%;
	top: 50%;
	width: min(78vw, 78vh);
	height: min(78vw, 78vh);
	transform: translate(-50%, -50%);
	background: radial-gradient(circle, rgba(119, 255, 136, .055), transparent 62%);
	pointer-events: none;
	z-index: 0;
}

/* Scanlines : la signature D4, gardée très discrète pour ne pas manger les
   chiffres du titre. */
body::before {
	content: "";
	position: fixed;
	inset: 0;
	background: repeating-linear-gradient(
		0deg, transparent, transparent 2px,
		rgba(0, 0, 0, .10) 2px, rgba(0, 0, 0, .10) 4px
	);
	pointer-events: none;
	z-index: 2;
}

/* ── Colonne d'accueil ──────────────────────────────────────────────────────
   Un seul écran, jamais de défilement : le D4, puis la porte, centrés.
   `min-height` et pas `height` : si un cas déborde un jour, la page défile au
   lieu de couper la porte. `100dvh` ensuite : sur iPhone, `100vh` compte la
   zone SOUS la barre d'adresse. */
.landing {
	position: relative;
	z-index: 1;
	min-height: 100vh;
	min-height: 100dvh;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: clamp(.6rem, 3vh, 2.2rem);
	padding: 2rem 1.2rem 3.2rem;
}

/* ── Le titre : un grand « D4 » écrit en 0 et en 1 ────────────────────────
   Dessiné dans le canvas par /assets/d4-binaire.v1.js. Le texte « D4 » reste
   dans la page — lecteurs d'écran, moteurs de recherche, navigateur sans JS —
   mais s'efface dès que le canvas a pris le relais (classe `is-live`).
   `d4-js`, posée par le <head>, le cache dès le départ : sans elle, on verrait
   le D4 en lettres pleines une fraction de seconde avant l'animation. Si le
   moteur n'a pas démarré au bout de 3 s, le <head> retire la classe et le
   texte revient — le titre ne peut pas disparaître. */
.d4bin {
	position: relative;
	flex: 0 0 auto;
	width: 100%;
	max-width: 1400px;
	/* Sans la planète, le D4 prend la place : 58 % de la hauteur. Les lettres
	   se calent ensuite sur ce que permettent la hauteur ET la largeur (le
	   moteur les mesure) — sur un téléphone en portrait c'est la largeur qui
	   commande, et le surplus de hauteur devient de la place pour la pluie
	   au-dessus et en dessous du D4, au lieu d'un vide. */
	height: clamp(170px, 58vh, 640px);
	font-size: inherit;
	font-weight: inherit;
	-webkit-user-select: none;
	user-select: none;
	/* L'appui long sur le titre ouvre la porte privée (mobile) : pas de bulle
	   « copier / rechercher » d'iOS par-dessus. */
	-webkit-touch-callout: none;
}
.d4bin-cv {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	/* Jamais entre le doigt et le titre : c'est le <h1> qui reçoit l'appui long. */
	pointer-events: none;
}
.d4bin-txt {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #fff;
	line-height: 1;
	letter-spacing: -.06em;
	/* ≈ 1,16 × la hauteur du bloc (les capitales en occupent ~80 %), sans
	   dépasser la largeur : « D4 » fait ~1,2 em de large. */
	font-size: clamp(150px, min(67vh, 75vw), 742px);
	text-shadow: 0 2px 34px rgba(0, 0, 0, .95);
	transition: opacity .3s;
}
.d4-js .d4bin-txt,
.d4bin.is-live .d4bin-txt { opacity: 0; }

/* ── La porte ───────────────────────────────────────────────────────────── */
.enter-btn {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: .55em;
	padding: 1em 2.8em;
	border: 1px solid rgba(119, 255, 136, .22);
	/* Fond franc : sur téléphone le bouton touche la pluie du D4, le texte doit
	   toujours gagner contre les chiffres qui bougent derrière. */
	background: rgba(9, 9, 9, .78);
	-webkit-backdrop-filter: blur(7px);
	backdrop-filter: blur(7px);
	color: rgba(119, 255, 136, .7);
	font-family: inherit;
	text-decoration: none;
	cursor: pointer;
	overflow: hidden;
	/* Deux animations qui ne se marchent pas dessus : l'une l'opacité et la
	   propriété `translate`, l'autre l'ombre. Le survol garde `transform` pour
	   lui — une animation en `forwards` écrase toujours un `transform` déclaré
	   normalement, c'est ce qui rendait l'ancien effet de survol inopérant. */
	animation: enter-in .8s ease .7s backwards,
	           enter-pulse 3.8s ease-in-out 1.6s infinite;
	transition: border-color .25s, color .25s, background .25s, transform .25s;
}
/* Barre d'accent à gauche, comme les cartes de /public.php. */
.enter-btn::after {
	content: "";
	position: absolute;
	left: 0; top: 15%;
	height: 70%; width: 2px;
	background: rgba(119, 255, 136, .55);
	transform: scaleY(0);
	transform-origin: top;
	transition: transform .25s;
}
.enter-btn:hover,
.enter-btn:focus-visible {
	border-color: rgba(119, 255, 136, .6);
	background: rgba(12, 12, 12, .88);
	color: rgba(119, 255, 136, 1);
	transform: translateY(-3px);
	outline: none;
}
.enter-btn:hover::after,
.enter-btn:focus-visible::after { transform: scaleY(1); }
.enter-btn:hover .enter-txt,
.enter-btn:focus-visible .enter-txt { animation: card-glitch .2s steps(1) 3; }

.enter-txt {
	font-size: clamp(.85rem, 2.2vw, 1rem);
	letter-spacing: .3em;
	text-indent: .3em;
	text-transform: uppercase;
}
.enter-sub {
	font-size: .6rem;
	letter-spacing: .2em;
	text-indent: .2em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, .28);
	transition: color .25s;
}
.enter-btn:hover .enter-sub,
.enter-btn:focus-visible .enter-sub { color: rgba(255, 255, 255, .5); }

@keyframes enter-in {
	from { opacity: 0; translate: 0 8px; }
	to   { opacity: 1; translate: 0 0; }
}
@keyframes enter-pulse {
	0%, 100% { box-shadow: 0 0 0 0 rgba(119, 255, 136, 0); }
	50%      { box-shadow: 0 0 34px -6px rgba(119, 255, 136, .18); }
}
@keyframes card-glitch {
	0%   { transform: translate(0); color: #fff; }
	33%  { transform: translate(-2px, 1px); color: #77f8; clip-path: inset(20% 0 40% 0); }
	66%  { transform: translate(2px, -1px); color: #ff68; clip-path: inset(55% 0 10% 0); }
	100% { transform: translate(0); color: inherit; clip-path: none; }
}

/* ── Signature ──────────────────────────────────────────────────────────────
   Invisible par défaut : c'est la porte privée (Ctrl+A la révèle, Ctrl+clic
   ouvre le mot de passe). Elle doit rester CLIQUABLE, donc au-dessus des
   scanlines (z-index 2) — pas de pointer-events: none ici. */
.signature {
	position: fixed;
	bottom: 8px;
	left: 0;
	width: 100%;
	z-index: 5;
	text-align: center;
	font-family: inherit;
	font-size: 11px;
	letter-spacing: .12em;
	color: transparent;
	user-select: none;
	cursor: default;
}
.signature.revealed {
	color: rgba(255, 255, 255, .22);
	cursor: pointer;
	animation: sig-glitch .6s ease forwards;
}
@keyframes sig-glitch {
	0%   { color: rgba(255,255,255,0);    transform: translate(0);       text-shadow: none; }
	10%  { color: rgba(119,255,136,.6);   transform: translate(-2px, 0); text-shadow: 2px 0 #ff6688, -2px 0 #77ffff; }
	20%  { color: rgba(255,255,255,.22);  transform: translate(2px, 0);  text-shadow: none; }
	35%  { color: rgba(255,100,200,.5);   transform: translate(-1px, 0); text-shadow: 3px 0 #77f8; }
	50%  { color: rgba(255,255,255,.22);  transform: translate(0);       text-shadow: none; }
	70%  { color: rgba(119,255,255,.4);   transform: translate(1px, 0);  text-shadow: -2px 0 #ff68; }
	100% { color: rgba(255,255,255,.22);  transform: translate(0);       text-shadow: none; }
}

/* ── Modal mot de passe ─────────────────────────────────────────────────── */
.pw-modal {
	display: none;
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, .8);
	align-items: center;
	justify-content: center;
	z-index: 9999;
}
.pw-modal.active {
	display: flex;
}
.pw-box {
	background: #0d0d0d;
	border: 1px solid rgba(119, 255, 136, .25);
	box-shadow: 0 0 30px rgba(119, 255, 136, .08), inset 0 0 20px rgba(0,0,0,.5);
	padding: 2.5em 3.5em;
	display: flex;
	flex-direction: column;
	gap: 1.2em;
	min-width: 300px;
	font-family: inherit;
}
.pw-label {
	font-size: .95em;
	letter-spacing: .15em;
	color: rgba(119, 255, 136, .7);
}
.pw-input {
	background: transparent;
	border: none;
	border-bottom: 1px solid rgba(119, 255, 136, .3);
	color: #fff;
	font-family: inherit;
	font-size: 1.4em;
	letter-spacing: .5em;
	text-align: center;
	outline: none;
	padding: .3em 0;
	transition: border-color .2s;
}
.pw-input:focus {
	border-bottom-color: rgba(119, 255, 136, .8);
}
.pw-error {
	font-size: .8em;
	letter-spacing: .1em;
	color: rgba(255, 100, 100, .8);
	min-height: 1em;
}
.pw-input.shake {
	animation: pw-shake .35s ease;
}
@keyframes pw-shake {
	0%, 100% { transform: translateX(0); }
	20%, 60% { transform: translateX(-7px); }
	40%, 80% { transform: translateX(7px); }
}
.pw-submit {
	background: transparent;
	border: 1px solid rgba(119, 255, 136, .25);
	color: rgba(119, 255, 136, .6);
	font-family: inherit;
	font-size: .8em;
	letter-spacing: .25em;
	padding: .6em 1.2em;
	cursor: pointer;
	align-self: center;
	transition: border-color .2s, color .2s;
}
.pw-submit:hover, .pw-submit:active {
	border-color: rgba(119, 255, 136, .7);
	color: rgba(119, 255, 136, 1);
}

/* ── Animations réduites : on garde la page, on enlève le mouvement ─────── */
@media (prefers-reduced-motion: reduce) {
	.enter-btn { animation: none; }
	.enter-btn:hover .enter-txt,
	.enter-btn:focus-visible .enter-txt { animation: none; }
}

/* ── Mobile : ce bloc doit RESTER en dernier, sinon la cascade l'annule
      (régression déjà vécue sur ARIsMAP). ─────────────────────────────────── */
@media (max-width: 640px) {
	.landing { padding: 1.6rem 1.1rem 3rem; }
	.enter-btn { padding: 1em 2.2em; width: 100%; max-width: 320px; }
}

/* Téléphone couché (mesuré jusqu'à 303 px de haut : un iPhone SE couché,
   barres du navigateur déduites). Tout ce qui est en hauteur se resserre ; le
   D4 garde un peu plus de la moitié de l'écran, la porte reste au-dessus de la
   ligne de flottaison. */
@media (max-height: 520px) {
	.landing { padding: .8rem 1.1rem 1.4rem; }
	.d4bin { height: clamp(100px, 56vh, 290px); }
	.d4bin-txt { font-size: clamp(116px, 65vh, 336px); }
	.enter-btn { padding: .7em 2.4em; }
}
