/**
 * Page d'accueil — roue chronologique + globe 3D.
 *
 * Feuille de style autonome (aucune dépendance à Tailwind) chargée directement
 * par AssetsServiceProvider : elle ne nécessite donc pas de build Vite.
 */

.tl {
	--tl-bg: #06070a;
	--tl-line: rgba(255, 255, 255, 0.08);
	--tl-line-strong: rgba(255, 255, 255, 0.17);
	--tl-text: #eceff5;
	--tl-muted: #8a91a3;
	--tl-dim: #565d6e;
	--tl-accent: #f5c451;
	--tl-accent-soft: rgba(245, 196, 81, 0.13);
	--tl-geo: #93d6c2;
	--tl-radius: 16px;

	/* Géométrie de la roue.
	   --tl-focus  : hauteur de la ligne de mire dans l'arc. Le JS la relit pour
	                 caler le défilement, le moyeu et la fiche : elle n'est
	                 déclarée qu'ici.
	   --tl-bulge  : débord horizontal de l'arc, écrit par le JS d'après le rayon
	                 calculé pour la fenêtre. La valeur ci-dessous n'est que le
	                 repli avant le premier rendu. */
	--tl-focus: 44%;
	--tl-bulge: 120px;
	--tl-hub-w: 132px;
	--tl-strip-w: 196px;
	/* Hauteur unique : la bande doit rester régulière comme une pellicule. Le
	   rang d'une entrée se lit sur son bord intérieur, pas sur sa taille. */
	--tl-strip-h: 110px;
	/* Évasement de la vignette : elle est plus haute au bord extérieur qu'au bord
	   intérieur, comme un secteur de roue. Le JS écrit la valeur exacte
	   (h × l / R) d'après le rayon courant ; celle-ci n'est que le repli avant le
	   premier rendu — et le rendu sans JS. */
	--tl-strip-slant: 26px;
	--tl-gap: clamp(28px, 3.2vw, 58px);

	position: fixed;
	inset: 0;
	z-index: 1;
	display: grid;
	grid-template-columns: minmax(520px, 46vw) minmax(0, 1fr);
	background: var(--tl-bg);
	color: var(--tl-text);
	font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
	letter-spacing: 0;
}

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

/* Étiquette réservée aux lecteurs d'écran. */
.tl-u-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* ------------------------------------------------------------------ *
 * Colonne gauche — panneau chronologique
 * ------------------------------------------------------------------ */

.tl__panel {
	position: relative;
	display: flex;
	flex-direction: column;
	min-height: 0;
	border-right: 1px solid var(--tl-line);
	background: linear-gradient(180deg, #0a0c12 0%, #06070a 55%);
}

.tl__head {
	flex: none;
	padding: clamp(16px, 2.4vw, 30px) clamp(18px, 2.4vw, 32px) 14px;
	border-bottom: 1px solid var(--tl-line);
}

.tl__eyebrow {
	margin: 0 0 8px;
	color: var(--tl-accent);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
}

.tl__title {
	margin: 0 0 12px;
	font-size: clamp(21px, 2.4vw, 32px);
	font-weight: 800;
	line-height: 1.04;
	text-transform: uppercase;
}

.tl__stats {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 18px;
	margin: 0;
	padding: 0;
	list-style: none;
	color: var(--tl-muted);
	font-size: 11px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.tl__stats strong {
	color: var(--tl-text);
	font-size: 13px;
	font-weight: 700;
}

/* ------------------------------------------------------------------ *
 * Roue — moyeu, arc, fiche
 * ------------------------------------------------------------------ */

.tl-wheel {
	position: relative;
	display: grid;
	grid-template-columns:
		var(--tl-hub-w)
		calc(var(--tl-strip-w) + var(--tl-bulge))
		minmax(0, 1fr);
	grid-template-rows: minmax(0, 1fr);
	/* Écarte la fiche de l'arc : au contact, le titre se lisait comme la légende
	   de la vignette voisine et non comme celle de l'entrée visée. */
	column-gap: var(--tl-gap);
	flex: 1 1 auto;
	min-height: 0;
}

/* -- Couloir 1 : cadran de dates --
 *
 * La ligne de mire n'est pas tracée : le centre du cadran, la vignette au
 * sommet de l'arc et le liseré de la fiche sont à la même hauteur et la donnent
 * déjà. Un trait de plus barrerait la vignette visée.
 *
 * Un tour de cadran vaut une année : douze graduations, une par mois, celles
 * des trimestres plus longues. Tout est dimensionné en fraction de --tl-dial,
 * si bien qu'un seul nombre suffit à redimensionner l'ensemble d'un palier
 * d'affichage à l'autre. */

.tl-wheel__hub {
	position: relative;
}

/* Cadran calé à droite du couloir, centré sur la mire : contre l'arc, il en
   désigne le sommet. */
.tl-dial {
	--tl-dial: var(--tl-hub-w);

	position: absolute;
	top: var(--tl-focus);
	right: 0;
	width: var(--tl-dial);
	height: var(--tl-dial);
	border-radius: 50%;
	background:
		radial-gradient(
			120% 120% at 50% 3%,
			rgba(255, 255, 255, 0.075),
			rgba(255, 255, 255, 0.014) 52%,
			rgba(255, 255, 255, 0) 78%
		),
		#0a0c12;
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.06),
		0 22px 44px -28px #000;
	transform: translateY(-50%);
}

/* Le débord reste permis : le repère et sa lueur mordent sur la lunette. */
.tl-dial__rings {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	overflow: visible;
	fill: none;
}

.tl-dial__rim {
	stroke: rgba(255, 255, 255, 0.1);
	stroke-width: 1;
}

/* Chemin parcouru : le filet d'accent croît du sommet dans le sens horaire à
   mesure que la roue avance dans la chronologie. Avec pathLength="1", la
   fraction écrite par le JS est directement la longueur du premier tiret. */
.tl-dial__travel {
	stroke: var(--tl-accent);
	stroke-width: 1.6;
	stroke-dasharray: var(--tl-p, 0) 1;
	stroke-linecap: round;
	/* Un fil, non un repère : la bille de l'aiguille doit rester la seule marque
	   franche de la lunette. */
	opacity: 0.55;
}

/* Graduations et repère : chacun est un calque de la taille du cadran, pivoté
   autour de son centre. La marque est posée en haut, au milieu — la rotation
   l'amène sur son mois sans avoir à calculer de sinus. */
.tl-dial__ticks,
.tl-dial__index {
	position: absolute;
	inset: 0;
}

.tl-dial__tick {
	position: absolute;
	inset: 0;
	transform: rotate(calc(var(--tl-i) * 30deg));
}

/* Les graduations occupent la couronne intérieure, le repère la lunette : chacun
   a sa bande, si bien que le repère ne masque jamais le mois qu'il désigne et
   que la graduation la plus longue s'arrête avant les chiffres du centre. */
.tl-dial__tick::before {
	content: "";
	position: absolute;
	top: 13%;
	left: 50%;
	width: 1px;
	height: 5%;
	background: var(--tl-line-strong);
	transform: translateX(-50%);
}

.tl-dial__tick.is-quarter::before {
	height: 7.5%;
	background: rgba(255, 255, 255, 0.32);
}

.tl-dial__index {
	transform: rotate(calc(var(--tl-a, 0) * 1deg));
}

/* Aiguille courte, tournée vers l'extérieur : elle s'éteint vers le moyeu et
   porte à sa pointe une bille posée sur le filet du cadran. */
.tl-dial__needle {
	position: absolute;
	top: 4%;
	left: 50%;
	width: 2.5px;
	height: 8.5%;
	border-radius: 2px;
	background: linear-gradient(180deg, var(--tl-accent), rgba(245, 196, 81, 0.1));
	transform: translateX(-50%);
}

.tl-dial__needle::after {
	content: "";
	position: absolute;
	top: -2.5px;
	left: 50%;
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--tl-accent);
	box-shadow: 0 0 9px rgba(245, 196, 81, 0.6);
	transform: translateX(-50%);
}

/* Jour et mois au centre, un peu au-dessus de l'axe : le guichet de l'année
   occupe le bas du cadran, comme sur une montre. */
.tl-dial__core {
	position: absolute;
	top: 43%;
	left: 50%;
	display: flex;
	flex-direction: column;
	align-items: center;
	transform: translate(-50%, -50%);
}

.tl-dial__window {
	position: absolute;
	bottom: 13%;
	left: 50%;
	padding: 2px 7px 3px;
	border: 1px solid rgba(255, 255, 255, 0.13);
	border-radius: 5px;
	background: rgba(0, 0, 0, 0.3);
	transform: translateX(-50%);
}

/* Fenêtre du rouleau : une cellule. Les valeurs voisines défilent au travers,
   dissoutes aux deux bords. La largeur est figée — le rouleau ne pouvant se
   mesurer sur son ruban, qui est positionné en absolu.

   Le fondu reste cantonné aux derniers pixels : plus large, il délavait le haut
   et le bas des chiffres eux-mêmes, la cellule faisant exactement la hauteur de
   la fenêtre. */
.tl-dial__reel {
	position: relative;
	flex: none;
	height: var(--tl-cell);
	overflow: hidden;
	mask-image: linear-gradient(180deg, transparent, #000 15%, #000 85%, transparent);
	-webkit-mask-image: linear-gradient(180deg, transparent, #000 15%, #000 85%, transparent);
}

.tl-dial__strip {
	position: absolute;
	top: 0;
	right: 0;
	left: 0;
	transform: translate3d(0, calc(var(--tl-f, 0) * var(--tl-cell) * -1), 0);
}

.tl-dial__cell {
	display: flex;
	height: var(--tl-cell);
	align-items: center;
	justify-content: center;
	font-variant-numeric: tabular-nums;
	line-height: 1;
	white-space: nowrap;
}

.tl-dial__reel--day {
	--tl-cell: calc(var(--tl-dial) * 0.25);

	width: 2.3ch;
	font-size: calc(var(--tl-dial) * 0.2);
	font-weight: 800;
	letter-spacing: -0.02em;
}

/* Assez large pour « SEPT. », l'abréviation la plus longue que rende wp_date. */
.tl-dial__reel--month {
	--tl-cell: calc(var(--tl-dial) * 0.15);

	width: calc(var(--tl-dial) * 0.66);
	color: var(--tl-accent);
	font-size: max(8.5px, calc(var(--tl-dial) * 0.092));
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.tl-dial__reel--year {
	--tl-cell: calc(var(--tl-dial) * 0.125);

	width: 4.9ch;
	color: var(--tl-muted);
	font-size: max(8.5px, calc(var(--tl-dial) * 0.086));
	font-weight: 700;
	letter-spacing: 0.06em;
}

/* -- Couloir 2 : arc des entrées -- */

.tl-arc {
	position: relative;
	min-height: 0;
	/* `clip` évite d'ouvrir un second port de défilement ; la marge laisse
	   respirer les vignettes inclinées, dont les angles sortent de leur boîte. */
	overflow-x: hidden;
	overflow-x: clip;
	overflow-y: auto;
	overflow-clip-margin: 26px;
	overscroll-behavior: contain;
	padding-left: var(--tl-bulge);
	scrollbar-width: none;
}

.tl-arc::-webkit-scrollbar {
	width: 0;
	height: 0;
}

.tl-arc:focus-visible {
	outline: none;
}

/* Cales : laissent la première et la dernière entrée atteindre la mire. */
.tl-arc__lead {
	height: var(--tl-focus);
}

.tl-arc__tail {
	height: calc(100% - var(--tl-focus));
}

.tl-arc__empty {
	margin: 0;
	color: var(--tl-muted);
	font-size: 13px;
	line-height: 1.5;
}

/* Placement sur le cercle. Le JS écrit quatre variables par entrée :
     --tl-x   retrait horizontal (0 sur la mire, négatif en s'en éloignant)
     --tl-y   recalage vertical sur le cercle
     --tl-rot inclinaison radiale
     --tl-t   distance normalisée à la mire, de 0 à 1
   Le pivot est au bord côté moyeu : les entrées s'enroulent autour du centre de
   la roue. Aucune réduction d'échelle — les vignettes se touchent, et rétrécir
   l'une ouvrirait une brèche dans la bande.

   Les valeurs par défaut sont celles de la mire, pas celles du lointain : sans
   JS — un CDN injoignable suffit — l'arc se déplie en simple liste verticale
   lisible, au lieu de vignettes fantômes effacées. */
.tl-arc > * {
	--tl-x: 0px;
	--tl-y: 0px;
	--tl-rot: 0deg;
	--tl-t: 0;

	position: relative;
	margin: 0;
	transform-origin: 0 50%;
	transform: translate3d(var(--tl-x), var(--tl-y), 0) rotate(var(--tl-rot));
	opacity: calc(1 - var(--tl-t) * 0.55);
}

.tl-arc > [data-tl-spacer] {
	transform: none;
	opacity: 1;
}

/* Pas de gouttière entre les vignettes : elles sont bord à bord et forment une
   seule pellicule, la couture étant marquée dans la couverture elle-même. Seuls
   les repères ménagent une respiration — la coupure y est le signal. */
.tl-arc > .tl-marker {
	margin: 10px 0;
}

/* ------------------------------------------------------------------ *
 * Vignettes de l'arc
 * ------------------------------------------------------------------ */

/* La boîte de l'entrée garde la hauteur nominale : c'est elle que la mise en
   page empile et que le JS mesure. La couverture, elle, déborde en haut et en
   bas — le débord est repris par le découpage en trapèze. */
.tl-strip {
	position: relative;
	display: block;
	width: var(--tl-strip-w);
	height: var(--tl-strip-h);
	cursor: pointer;
}

.tl-strip:focus-visible {
	outline: 2px solid var(--tl-accent);
	outline-offset: 2px;
}

/* Ni cadre ni coin arrondi : la couverture est un photogramme de la pellicule.

   Le trapèze n'est pas un ornement : les vignettes pivotent autour de leur bord
   intérieur, jointives à cette hauteur-là, et le tour de roue est plus long au
   bord extérieur — un rectangle y laissait un coin de vide entre chaque
   vignette. La couverture est donc plus haute côté extérieur d'exactement ce
   qui manquait, et la bande redevient pleine. Le débord est symétrique pour que
   le centre optique reste sur la ligne de mire. */
.tl-strip__cover {
	position: absolute;
	inset: calc(var(--tl-strip-slant) / -2) 0;
	display: block;
	overflow: hidden;
	padding: 0;
	border: 0;
	background: #12151d;
	clip-path: polygon(
		0 calc(var(--tl-strip-slant) / 2),
		100% 0,
		100% 100%,
		0 calc(100% - var(--tl-strip-slant) / 2)
	);
	color: inherit;
	/* Une entrée hors mire s'y amène d'un clic ; visée, elle s'ouvre. */
	cursor: pointer;
	/* La couture avec la vignette suivante et l'ombre portée suivent le trapèze :
	   une box-shadow serait rognée par le découpage, qui s'applique aussi à
	   elle. */
	filter:
		drop-shadow(0 1px 0 rgba(6, 7, 10, 0.72))
		drop-shadow(-14px 0 22px rgba(0, 0, 0, 0.5));
	font: inherit;
	transition: filter 0.35s;
}

.tl-strip__cover img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0.88;
	transition: opacity 0.4s, transform 0.6s;
}

.tl-strip:hover .tl-strip__cover img {
	opacity: 1;
	transform: scale(1.04);
}

/* L'entrée visée ne sort pas du rang — la décaler ouvrirait une brèche dans la
   bande. Elle se signale par un liseré sur son bord extérieur, à hauteur de la
   fiche qui la décrit, et par un halo. */
.tl-strip.is-active {
	z-index: 2;
}

/* Le halo est une ombre projetée et non une box-shadow : elle épouse le trapèze
   au lieu d'en dessiner le rectangle englobant. */
.tl-strip.is-active .tl-strip__cover {
	filter:
		drop-shadow(0 1px 0 rgba(6, 7, 10, 0.72))
		drop-shadow(0 0 20px rgba(245, 196, 81, 0.38));
	cursor: zoom-in;
}

.tl-strip.is-active .tl-strip__cover::after {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	width: 3px;
	background: var(--tl-accent);
}

.tl-strip.is-active .tl-strip__cover img {
	opacity: 1;
}

.tl-strip__void {
	display: grid;
	place-items: center;
	height: 100%;
	color: var(--tl-dim);
	font-size: 24px;
	font-weight: 800;
}

/* Calé côté extérieur : c'est le seul bord que le biseau laisse entier. */
.tl-strip__count {
	position: absolute;
	right: 6px;
	bottom: 6px;
	padding: 2px 7px;
	border-radius: 6px;
	background: rgba(6, 7, 10, 0.78);
	color: var(--tl-text);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.04em;
}

/* Nomme l'entrée survolée. La fiche ne décrit que l'entrée visée : sans ce
   voile, les autres vignettes seraient des images sans légende. */
.tl-strip__hint {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	gap: 2px;
	/* Le coin bas-gauche est emporté par le biseau : le texte est remonté
	   d'autant pour ne pas y être coupé. */
	padding: 8px 10px calc(9px + var(--tl-strip-slant) / 2);
	background: linear-gradient(180deg, rgba(6, 7, 10, 0.1), rgba(6, 7, 10, 0.92));
	text-align: left;
	opacity: 0;
	transition: opacity 0.3s;
}

.tl-strip__cover:hover .tl-strip__hint,
.tl-strip__cover:focus-visible .tl-strip__hint,
.tl-strip:focus-visible .tl-strip__hint {
	opacity: 1;
}

.tl-strip__hint-kind {
	color: var(--tl-accent);
	font-size: 9px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.tl-strip__hint-title {
	display: -webkit-box;
	overflow: hidden;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	color: #fff;
	font-size: 12.5px;
	font-weight: 700;
	line-height: 1.24;
}

/* Le rang se lit sur le bord intérieur, côté moyeu : un album ouvre une
   séquence, une collection appartient à l'album qui la précède, une photo isolée
   ne porte rien. Un liseré posé dans la couverture, et non une bordure : la
   hauteur des vignettes doit rester identique pour que la bande reste jointive. */
.tl-strip--album .tl-strip__cover::before,
.tl-strip--collection .tl-strip__cover::before {
	content: "";
	position: absolute;
	z-index: 1;
	top: 0;
	bottom: 0;
	left: 0;
	width: 3px;
	background: rgba(245, 196, 81, 0.6);
}

.tl-strip--collection .tl-strip__cover::before {
	background: rgba(255, 255, 255, 0.16);
}

/* ------------------------------------------------------------------ *
 * Repères de l'arc — date charnière et déplacement
 * ------------------------------------------------------------------ */

.tl-marker {
	width: var(--tl-strip-w);
}

.tl-marker--date {
	display: flex;
	align-items: center;
	gap: 9px;
	min-height: 30px;
}

.tl-marker__spoke {
	flex: none;
	width: 16px;
	height: 1px;
	background: var(--tl-accent);
}

.tl-marker__date {
	min-width: 0;
	color: var(--tl-text);
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 0.14em;
	line-height: 1.3;
	text-transform: uppercase;
}

.tl-marker--transit {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 44px;
}

.tl-marker__medallion {
	position: relative;
	display: flex;
	flex: none;
	width: 38px;
	height: 38px;
	align-items: center;
	justify-content: center;
	border: 1px dashed var(--tl-line-strong);
	border-radius: 50%;
	background: #10131b;
	color: var(--tl-geo);
}

.tl-marker__medallion svg {
	width: 20px;
	height: 20px;
	fill: none;
	stroke: currentColor;
	stroke-linecap: round;
	stroke-linejoin: round;
	stroke-width: 1.4;
}

.tl-marker__body {
	display: flex;
	min-width: 0;
	flex-direction: column;
	gap: 2px;
}

.tl-marker__kind {
	color: var(--tl-dim);
	font-size: 9px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.tl-marker__route,
.tl-marker__file {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.tl-marker__route {
	color: var(--tl-text);
	font-size: 12px;
	font-weight: 700;
}

.tl-marker__file {
	color: var(--tl-accent);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-decoration: none;
}

.tl-marker__file:hover {
	text-decoration: underline;
}

/* ------------------------------------------------------------------ *
 * Couloir 3 : fiche de l'entrée visée
 * ------------------------------------------------------------------ */

.tl-wheel__side {
	position: relative;
	overflow: hidden;
}

.tl-info {
	position: absolute;
	top: var(--tl-focus);
	right: clamp(16px, 2vw, 30px);
	left: 0;
	padding-left: clamp(16px, 1.8vw, 26px);
	transform: translateY(-50%);
}

/* Prolonge la mire jusqu'à la fiche. */
.tl-info::before {
	content: "";
	position: absolute;
	top: 4px;
	bottom: 4px;
	left: 0;
	width: 2px;
	border-radius: 2px;
	background: linear-gradient(180deg, transparent, rgba(245, 196, 81, 0.75), transparent);
}

.tl-info__eyebrow {
	margin: 0;
	overflow: hidden;
	color: var(--tl-accent);
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: 0.2em;
	text-overflow: ellipsis;
	text-transform: uppercase;
	white-space: nowrap;
}

.tl-info__eyebrow:empty {
	display: none;
}

.tl-info__title {
	display: -webkit-box;
	overflow: hidden;
	margin: 8px 0 10px;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	font-size: clamp(19px, 2.1vw, 30px);
	font-weight: 800;
	line-height: 1.08;
	text-transform: uppercase;
}

.tl-info__date {
	margin: 0;
	color: var(--tl-text);
	font-size: 12.5px;
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.tl-info__place {
	display: -webkit-box;
	overflow: hidden;
	margin: 7px 0 0;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	color: var(--tl-muted);
	font-size: 12.5px;
	line-height: 1.45;
}

.tl-info__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 14px 0 0;
	padding: 0;
	list-style: none;
}

.tl-chip {
	max-width: 100%;
	overflow: hidden;
	padding: 3px 8px;
	border: 1px solid var(--tl-line);
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.03);
	color: var(--tl-muted);
	font-size: 10.5px;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.tl-chip--strong {
	border-color: var(--tl-line-strong);
	color: var(--tl-text);
}

.tl-chip--geo {
	border-color: rgba(147, 214, 194, 0.26);
	color: var(--tl-geo);
	font-variant-numeric: tabular-nums;
}

.tl-chip--muted {
	opacity: 0.5;
}

.tl-info__open {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-top: 16px;
	padding: 9px 16px;
	border: 1px solid rgba(245, 196, 81, 0.4);
	border-radius: 999px;
	background: rgba(245, 196, 81, 0.08);
	color: var(--tl-text);
	cursor: pointer;
	font: inherit;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	transition: border-color 0.3s, background 0.3s;
}

/* `display` posé sur la classe l'emporterait sur la feuille du navigateur : le
   bouton doit disparaître quand le JS le masque, faute de photos à ouvrir. */
.tl-info__open[hidden] {
	display: none;
}

.tl-info__open:hover,
.tl-info__open:focus-visible {
	border-color: var(--tl-accent);
	background: rgba(245, 196, 81, 0.16);
}

.tl-info__open svg {
	width: 14px;
	height: 14px;
	fill: none;
	stroke: var(--tl-accent);
	stroke-linecap: round;
	stroke-linejoin: round;
	stroke-width: 2.4;
}

/* ------------------------------------------------------------------ *
 * Colonne droite — scène du globe
 * ------------------------------------------------------------------ */

.tl__stage {
	position: relative;
	overflow: hidden;
	background: radial-gradient(125% 100% at 68% 18%, #111a2b 0%, #070911 45%, #04050a 100%);
}

.tl__canvas {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
}

.tl__stage-noise {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: radial-gradient(78% 68% at 50% 46%, transparent 38%, rgba(0, 0, 0, 0.62) 100%);
}

.tl-readout {
	position: absolute;
	top: clamp(16px, 2.4vw, 30px);
	right: clamp(16px, 2.4vw, 30px);
	display: flex;
	align-items: center;
	gap: 9px;
	padding: 8px 14px;
	border: 1px solid var(--tl-line);
	border-radius: 999px;
	background: rgba(6, 7, 10, 0.55);
	backdrop-filter: blur(8px);
	color: var(--tl-muted);
	font-size: 11.5px;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.09em;
}

.tl-readout__dot {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--tl-accent);
	animation: tl-pulse 2.4s infinite;
}

@keyframes tl-pulse {
	0% {
		box-shadow: 0 0 0 0 rgba(245, 196, 81, 0.45);
	}
	70% {
		box-shadow: 0 0 0 9px rgba(245, 196, 81, 0);
	}
	100% {
		box-shadow: 0 0 0 0 rgba(245, 196, 81, 0);
	}
}

.tl-stage__fallback {
	position: absolute;
	top: 50%;
	left: 50%;
	max-width: 280px;
	transform: translate(-50%, -50%);
	color: var(--tl-dim);
	font-size: 13px;
	line-height: 1.5;
	text-align: center;
}

/* ------------------------------------------------------------------ *
 * Mosaïque plein écran
 * ------------------------------------------------------------------ */

.tl-mosaic {
	position: fixed;
	inset: 0;
	z-index: 100;
	display: flex;
	flex-direction: column;
	padding: clamp(18px, 3vw, 40px);
	background: rgba(4, 5, 8, 0.97);
	color: #eceff5;
	font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.4s;
}

.tl-mosaic.is-open {
	opacity: 1;
	pointer-events: auto;
}

.tl-mosaic__head {
	display: flex;
	flex: none;
	align-items: flex-end;
	justify-content: space-between;
	gap: 20px;
	margin-bottom: 22px;
}

.tl-mosaic__eyebrow {
	margin: 0;
	color: #f5c451;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.2em;
	text-transform: uppercase;
}

.tl-mosaic__title {
	margin: 8px 0 6px;
	font-size: clamp(22px, 3vw, 36px);
	font-weight: 800;
	line-height: 1.05;
	text-transform: uppercase;
}

.tl-mosaic__sub {
	margin: 0;
	color: #8a91a3;
	font-size: 12px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.tl-mosaic__sub span + span::before {
	content: " · ";
}

.tl-mosaic__actions {
	display: flex;
	flex: none;
	gap: 12px;
}

.tl-icon-btn {
	display: flex;
	width: 44px;
	height: 44px;
	align-items: center;
	justify-content: center;
	border: 1px solid rgba(255, 255, 255, 0.22);
	border-radius: 50%;
	background: none;
	color: #fff;
	cursor: pointer;
	transition: border-color 0.3s, color 0.3s, background 0.3s;
}

.tl-icon-btn:hover {
	border-color: #f5c451;
	background: rgba(245, 196, 81, 0.1);
	color: #f5c451;
}

.tl-icon-btn svg {
	width: 19px;
	height: 19px;
	fill: currentColor;
}

.tl-mosaic__grid {
	display: flex;
	flex: 1 1 auto;
	flex-wrap: wrap;
	align-content: flex-start;
	gap: 10px;
	min-height: 0;
	overflow-y: auto;
	padding-right: 8px;
	scrollbar-width: thin;
	scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}

/* Dernière rangée justifiée sans étirer les vignettes. */
.tl-mosaic__grid::after {
	content: "";
	flex-grow: 999999;
	min-width: 150px;
}

.tl-mosaic__grid::-webkit-scrollbar {
	width: 8px;
}

.tl-mosaic__grid::-webkit-scrollbar-thumb {
	background: rgba(255, 255, 255, 0.16);
	border-radius: 4px;
}

.tl-thumb {
	position: relative;
	flex: 1 1 auto;
	min-width: 150px;
	height: 180px;
	overflow: hidden;
	border-radius: 8px;
	background: #14171f;
	cursor: zoom-in;
}

.tl-thumb img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0.9;
	transition: transform 0.5s, opacity 0.4s;
}

.tl-thumb:hover img {
	opacity: 1;
	transform: scale(1.05);
}

.tl-thumb__dl {
	position: absolute;
	top: 9px;
	right: 9px;
	z-index: 5;
	display: flex;
	width: 34px;
	height: 34px;
	align-items: center;
	justify-content: center;
	border: 1px solid rgba(255, 255, 255, 0.35);
	border-radius: 8px;
	background: rgba(0, 0, 0, 0.6);
	color: #fff;
	cursor: pointer;
	opacity: 0;
	transition: opacity 0.3s, background 0.3s, color 0.3s;
}

.tl-thumb__dl svg {
	width: 16px;
	height: 16px;
	fill: currentColor;
}

.tl-thumb:hover .tl-thumb__dl,
.tl-thumb__dl:focus-visible {
	opacity: 1;
}

.tl-thumb__dl:hover {
	border-color: #f5c451;
	background: #f5c451;
	color: #000;
}

/* ------------------------------------------------------------------ *
 * Adaptatif
 * ------------------------------------------------------------------ */

@media (max-width: 1180px) {
	.tl {
		--tl-hub-w: 118px;
		--tl-strip-w: 164px;
		--tl-strip-h: 94px;
		--tl-strip-slant: 22px;
		--tl-gap: 26px;
	}

	.tl-info__title {
		-webkit-line-clamp: 2;
	}
}

@media (max-width: 1080px) {
	.tl {
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: 36vh minmax(0, 1fr);
	}

	.tl__stage {
		order: -1;
		border-bottom: 1px solid var(--tl-line);
	}

	.tl__panel {
		border-right: 0;
	}
}

@media (max-width: 620px) {
	.tl {
		/* Trois couloirs et deux gouttières sur 360 px : le cadran est rogné au
		   plus juste — en deçà, la date n'y tiendrait plus — et la gouttière rend
		   à la fiche l'essentiel de ce qu'il prend. */
		--tl-hub-w: 92px;
		--tl-strip-w: 118px;
		--tl-strip-h: 72px;
		--tl-strip-slant: 16px;
		--tl-gap: 12px;

		grid-template-rows: 30vh minmax(0, 1fr);
	}

	.tl__head {
		padding-bottom: 12px;
	}

	.tl__title {
		margin-bottom: 8px;
	}

	/* Les libellés sont déjà au plancher de leur `max()` : seul l'espacement des
	   lettres se resserre encore, faute de largeur. */
	.tl-dial__reel--month {
		letter-spacing: 0.06em;
	}

	.tl-dial__reel--year {
		letter-spacing: 0.03em;
	}

	.tl-dial__window {
		padding: 1px 5px 2px;
	}

	.tl-strip__hint-title {
		-webkit-line-clamp: 3;
		font-size: 10.5px;
	}

	.tl-info {
		right: 12px;
		padding-left: 12px;
	}

	.tl-info__title {
		font-size: 17px;
	}

	.tl-info__open {
		margin-top: 12px;
		padding: 8px 13px;
	}

	.tl-thumb {
		height: 120px;
		min-width: 120px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.tl-readout__dot {
		animation: none;
	}

	.tl-strip__cover,
	.tl-strip.is-active .tl-strip__cover,
	.tl-strip__cover img,
	.tl-strip__hint,
	.tl-info__open {
		transition: none;
	}
}
