/* HyperPuck — la feuille de style du site.
 *
 * AUCUNE RESSOURCE EXTERNE, et ce n'est pas un choix esthétique : la page du
 * jeu est servie en isolation d'origine (COOP + COEP), sans quoi les fils
 * d'exécution de WebAssembly n'existent pas. Sous ce régime, tout ce qui vient
 * d'ailleurs — une police Google, une image de CDN — doit porter un en-tête
 * que ces hébergeurs n'envoient pas. On embarque donc tout, polices système
 * comprises.
 *
 * LE MOTIF : la page EST une table. Une ligne médiane la descend de bout en
 * bout, et les sections se posent alternativement d'un côté puis de l'autre,
 * comme les deux moitiés d'un terrain. Ce n'est pas une décoration : c'est la
 * seule forme qui dise de quoi parle le site avant qu'on ait lu une phrase.
 */

:root {
	/* Les couleurs viennent de l'habillage « Néon » du jeu, pas d'une palette
	 * choisie à côté : le site et la table doivent être le même objet. */
	--fond: #060a0f;
	--fond-haut: #0a1219;
	--feutre: #102a35;
	--rail: #2fd8f5;
	--rail-sourd: #176b80;
	--cage: #ff5546;
	--adverse: #ff3fa0;
	--hyperpuck: #ffd166;
	--texte: #e8f2f7;
	/* Un gris qui TIRE vers le cyan. Un gris neutre au milieu de ces néons
	 * passe pour une couleur oubliée. */
	--texte-doux: #8fa8b4;
	--trait: #14303c;

	--large: 1180px;
	--pad: clamp(18px, 4vw, 40px);
}

* { box-sizing: border-box; }

html {
	scroll-behavior: smooth;
}

body {
	margin: 0;
	background: var(--fond);
	color: var(--texte);
	font: 16px/1.65 "Segoe UI", Roboto, "Helvetica Neue", Arial, system-ui, sans-serif;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	* { animation: none !important; transition: none !important; }
}

a { color: var(--rail); }

/* --- La barre du haut : un tableau d'affichage ------------------------- */

.tableau {
	position: sticky;
	top: 0;
	z-index: 20;
	display: flex;
	align-items: center;
	gap: 10px 24px;
	flex-wrap: wrap;
	padding: 12px var(--pad);
	background: rgba(6, 10, 15, 0.86);
	backdrop-filter: blur(10px);
	border-bottom: 1px solid var(--trait);
}

.marque {
	display: flex;
	align-items: baseline;
	gap: 10px;
	text-decoration: none;
	color: var(--texte);
	font-weight: 800;
	font-size: 19px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	white-space: nowrap;
}

.marque b { color: var(--rail); font-weight: 800; }

.onglets {
	display: flex;
	gap: 4px;
	margin-left: auto;
	flex-wrap: wrap;
}

.onglets a {
	display: block;
	padding: 8px 15px;
	border-radius: 3px;
	color: var(--texte-doux);
	text-decoration: none;
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	border: 1px solid transparent;
}

.onglets a:hover { color: var(--texte); border-color: var(--trait); }

.onglets a[aria-current="page"] {
	color: var(--rail);
	border-color: var(--rail-sourd);
	background: rgba(47, 216, 245, 0.07);
}

/* --- La table : la ligne médiane et ses deux moitiés ------------------- */

main {
	position: relative;
	max-width: var(--large);
	margin: 0 auto;
	padding: 0 var(--pad) 90px;
}

/* La ligne médiane, tirée derrière tout le reste. Elle s'efface sur un
 * téléphone, où une colonne unique n'a pas deux moitiés à séparer. */
main::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 90px;
	left: 50%;
	width: 1px;
	background: linear-gradient(180deg,
		transparent, var(--trait) 8%, var(--trait) 92%, transparent);
	pointer-events: none;
}

@media (max-width: 860px) {
	main::before { display: none; }
}

/* PAS DE LIGNE DERRIÈRE UN CADRE. Sur les pages qui portent un grand
 * rectangle — le jeu, la chaîne — la médiane passe DERRIÈRE lui et ressort
 * au-dessus et en dessous : de loin, ça ne se lit plus comme la ligne d'une
 * table, mais comme un défaut d'affichage. Le motif n'a de sens que là où il
 * sépare deux moitiés de texte. */
body.cadre main::before { display: none; }

/* SUR UN TÉLÉPHONE, LA MARQUE PREND SA LIGNE.
 *
 * Trois onglets et un nom ne tiennent pas sur 420 points : « TV » repartait
 * seul à la ligne, sous les deux autres, avec la marque à sa gauche — une
 * barre en escalier. Elle s'empile proprement plutôt que de se casser. */
@media (max-width: 520px) {
	.tableau { justify-content: center; }
	.marque { width: 100%; text-align: center; justify-content: center; }
	.onglets { margin: 0 auto; }
	.onglets a { padding: 7px 12px; }
}

/* --- L'ouverture ------------------------------------------------------- */

.ouverture {
	position: relative;
	padding: clamp(52px, 9vw, 104px) 0 clamp(40px, 6vw, 72px);
	text-align: center;
}

.ouverture h1 {
	margin: 0;
	font-size: clamp(40px, 8.4vw, 88px);
	line-height: 0.92;
	font-weight: 800;
	letter-spacing: -0.02em;
	text-transform: uppercase;
	text-wrap: balance;
}

.ouverture h1 span {
	color: var(--rail);
	text-shadow: 0 0 34px rgba(47, 216, 245, 0.42);
}

.accroche {
	margin: 22px auto 0;
	max-width: 33em;
	font-size: clamp(17px, 2.2vw, 21px);
	color: var(--texte-doux);
	text-wrap: balance;
}

.boutons {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: 34px;
}

.bouton {
	display: inline-block;
	padding: 14px 30px;
	border-radius: 3px;
	font-weight: 700;
	font-size: 15px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	text-decoration: none;
	border: 1px solid var(--rail-sourd);
	color: var(--rail);
	background: rgba(47, 216, 245, 0.06);
	transition: background 0.16s, border-color 0.16s, color 0.16s;
}

.bouton:hover { background: rgba(47, 216, 245, 0.14); border-color: var(--rail); }

.bouton.plein {
	background: var(--rail);
	border-color: var(--rail);
	color: #04141a;
	box-shadow: 0 0 36px rgba(47, 216, 245, 0.26);
}

.bouton.plein:hover { background: #6ce6ff; border-color: #6ce6ff; }

/* --- La table dessinée sous l'ouverture -------------------------------- */

/* Une vraie table, en CSS : deux cages, une ligne, un rond central, un palet.
 * Dessinée plutôt qu'une capture d'écran, parce qu'elle reste nette à toutes
 * les tailles et ne pèse rien. */
.table {
	position: relative;
	width: min(300px, 58vw);
	aspect-ratio: 3 / 5;
	margin: clamp(30px, 5vw, 54px) auto 0;
	border: 2px solid var(--rail);
	border-radius: 10px;
	background:
		radial-gradient(120% 70% at 50% 50%, rgba(47, 216, 245, 0.10), transparent 70%),
		var(--feutre);
	box-shadow: 0 0 60px rgba(47, 216, 245, 0.18), inset 0 0 50px rgba(0, 0, 0, 0.45);
}

.table::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: 50%;
	height: 1px;
	background: rgba(47, 216, 245, 0.45);
}

.table::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: 33%;
	aspect-ratio: 1;
	transform: translate(-50%, -50%);
	border: 1px solid rgba(47, 216, 245, 0.45);
	border-radius: 50%;
}

.cage {
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	width: 34%;
	height: 7px;
	background: var(--cage);
	box-shadow: 0 0 22px var(--cage);
	border-radius: 2px;
}

.cage.haut { top: -4px; }
.cage.bas { bottom: -4px; }

.palet {
	position: absolute;
	left: 50%;
	top: 50%;
	width: 13%;
	aspect-ratio: 1;
	margin: -6.5% 0 0 -6.5%;
	border-radius: 50%;
	background: var(--adverse);
	box-shadow: 0 0 26px var(--adverse);
	animation: va-et-vient 4.6s ease-in-out infinite;
}

@keyframes va-et-vient {
	0%, 100% { transform: translate(-42%, -170%); }
	50% { transform: translate(46%, 168%); }
}

/* --- Les sections, posées d'un côté puis de l'autre -------------------- */

.moitie {
	position: relative;
	width: min(100%, 520px);
	padding: clamp(26px, 4vw, 40px) 0;
}

.moitie.gauche { margin-right: auto; }
.moitie.droite { margin-left: auto; }

.moitie h2 {
	margin: 0 0 14px;
	font-size: clamp(24px, 3.4vw, 34px);
	line-height: 1.12;
	font-weight: 800;
	letter-spacing: -0.01em;
	text-wrap: balance;
}

.moitie p {
	margin: 0 0 14px;
	color: var(--texte-doux);
}

.moitie p strong { color: var(--texte); font-weight: 600; }

.etiquette {
	display: block;
	margin-bottom: 10px;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--rail-sourd);
}

/* --- Les chiffres ------------------------------------------------------ */

.chiffres {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
	gap: 1px;
	margin: clamp(34px, 6vw, 60px) 0;
	background: var(--trait);
	border: 1px solid var(--trait);
}

.chiffre {
	padding: 22px 16px;
	background: var(--fond-haut);
	text-align: center;
}

.chiffre b {
	display: block;
	font-size: clamp(28px, 4vw, 40px);
	font-weight: 800;
	line-height: 1;
	color: var(--rail);
	font-variant-numeric: tabular-nums;
}

.chiffre span {
	display: block;
	margin-top: 8px;
	font-size: 12px;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--texte-doux);
}

/* --- Le pied ----------------------------------------------------------- */

footer {
	border-top: 1px solid var(--trait);
	padding: 28px var(--pad) 42px;
	text-align: center;
	color: var(--texte-doux);
	font-size: 13px;
}

footer a { color: var(--texte-doux); }
footer a:hover { color: var(--rail); }

/* --- La page TV -------------------------------------------------------- */

.antenne {
	margin: clamp(26px, 4vw, 44px) 0 0;
	border: 1px solid var(--trait);
	background: #000;
	aspect-ratio: 16 / 9;
	width: 100%;
	position: relative;
	overflow: hidden;
}

.antenne iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}

/* L'état HORS ANTENNE est l'état PAR DÉFAUT de cette page, et c'est voulu :
 * une chaîne qui n'a pas encore démarré doit dire ce qu'elle passera, pas
 * afficher un carré noir en attendant. */
.hors-antenne {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 14px;
	padding: 26px;
	text-align: center;
	background:
		radial-gradient(90% 70% at 50% 45%, rgba(47, 216, 245, 0.08), transparent 70%),
		var(--fond-haut);
}

.hors-antenne b {
	font-size: clamp(19px, 3vw, 26px);
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--texte);
}

.hors-antenne span {
	max-width: 34em;
	color: var(--texte-doux);
	font-size: 15px;
}

.voyant {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--texte-doux);
}

.voyant::before {
	content: "";
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: var(--texte-doux);
}

.voyant.direct { color: var(--cage); }
.voyant.direct::before {
	background: var(--cage);
	box-shadow: 0 0 12px var(--cage);
	animation: pulse 1.8s ease-in-out infinite;
}

@keyframes pulse {
	50% { opacity: 0.35; }
}

/* --- La grille des programmes ------------------------------------------ */

.grille {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
	gap: 18px;
	margin-top: clamp(28px, 5vw, 46px);
}

.programme {
	padding: 20px;
	border: 1px solid var(--trait);
	background: var(--fond-haut);
}

.programme h3 {
	margin: 0 0 8px;
	font-size: 16px;
	font-weight: 700;
	letter-spacing: 0.04em;
}

.programme p {
	margin: 0;
	font-size: 14px;
	color: var(--texte-doux);
}

/* --- La page « jouer » ------------------------------------------------- */

/* LE JEU PREND LA HAUTEUR QU'IL PEUT.
 *
 * Un 16/9 fixe donne un cadre écrasé sur un téléphone en portrait, où la table
 * est justement en portrait elle aussi. On prend donc ce qui reste de l'écran
 * une fois la barre d'onglets passée, avec un plancher pour que le cadre ne
 * devienne jamais une fente. */
.cadre-jeu {
	width: 100%;
	height: min(76vh, 900px);
	min-height: 420px;
	margin-top: clamp(20px, 3vw, 32px);
	border: 1px solid var(--trait);
	background: #000;
}

.cadre-jeu iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
}

/* LE DOIGT APPARTIENT AU JEU, PAS À LA PAGE.
 *
 * Sur Android, un appui qui bouge de deux pixels est interprété par la page
 * PARENTE comme un début de défilement : elle prend le geste, et le canevas du
 * jeu ne reçoit jamais rien. Sur PC le même geste est un clic, d'où un défaut
 * qui n'existait que sur téléphone. `touch-action: none` rend le geste au
 * cadre — c'est d'ailleurs ce que la page du jeu fait déjà pour elle-même,
 * sur son propre `body`. */
.cadre-jeu,
.cadre-jeu iframe {
	touch-action: none;
}

.avertissement {
	margin-top: 14px;
	font-size: 13px;
	color: var(--texte-doux);
	text-align: center;
}

/* Le bouton de plein écran, posé sur le coin du cadre : il ne doit pas voler
 * de place au jeu, et il doit rester trouvable sans mode d'emploi. */
.barre-jeu {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
	margin-top: 14px;
}

.barre-jeu .avertissement { margin: 0; text-align: left; }

.bouton.petit {
	padding: 10px 18px;
	font-size: 13px;
}

/* --- La porte de l'alpha ------------------------------------------------ */

.entree {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 12px;
	margin: 30px auto 0;
	max-width: 320px;
}

.entree .etiquette { margin: 0; }

.entree input {
	width: 100%;
	padding: 13px 16px;
	border-radius: 3px;
	border: 1px solid var(--trait);
	background: var(--fond-haut);
	color: var(--texte);
	font-size: 16px;
	font-family: inherit;
	letter-spacing: 0.08em;
}

.entree input:focus {
	outline: none;
	border-color: var(--rail);
	box-shadow: 0 0 0 3px rgba(47, 216, 245, 0.16);
}

.entree button { width: 100%; cursor: pointer; font-family: inherit; }

.refus {
	margin: 0;
	color: var(--cage);
	font-size: 14px;
}
