/* Châssis archive, habillage néon : finition portée de l'archive Bret Easton Ellis. Les couleurs sont des rôles de la palette (archive-palette.js). */
/* =====================================================================
   FINISH : BRET EASTON ELLIS ARCHIVE
   ---------------------------------------------------------------------
   Couche de FINITION, chargée EN DERNIER (après archive.css +
   neon-noir.css). Relief, profondeur, rythme éditorial, micro-
   interactions, traitement d'image : dans la direction « LA noir 80s ».

   PRINCIPES
   · Additive et pilotée par les classes .ej-* existantes : aucune
     réécriture de structure, aucun texte modifié.
   · Entièrement réversible : retirer ce <link> (et js/finish.js)
     restaure exactement l'état précédent.
   · Direction : surface polie, nuit, néon diffus. On AJOUTE du relief
     et de la tension, jamais d'aplat, jamais de gadget.
   ===================================================================== */



:root {
  /* Relief de luminance (surfaces légèrement relevées vs le bitume) */
  --rz-hairline:    rgb(var(--hairline-rgb, 232 232 238) / 0.13);
  --rz-hairline-lit:rgb(var(--gold-rgb, 232 85 122) / 0.48);   /* filet accentué (néon) */
  --rz-glow:        rgb(var(--gold-rgb, 232 85 122) / 0.36);   /* halo d'enseigne localisé */
  --rz-ink-deep:    var(--deep, #050507);   /* encre la plus profonde (ombres) */
  --rz-ease-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --rz-shadow-soft: 0 2px 14px rgba(2, 2, 4, 0.5);
  --rz-shadow-card: 0 18px 48px rgba(2, 2, 4, 0.62), 0 2px 6px rgba(2, 2, 4, 0.45);
}

/* =====================================================================
   1. PROFONDEUR DE FOND : relief atmosphérique (sans assombrir)
   ===================================================================== */
/* Une seconde nappe de lumière froide très haute + grain optique discret,
   superposée au voile de glacial-noir, pour casser l'aplat du navy. */
body::after {
  content: "";
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(60% 32% at 50% 0%, rgb(var(--gold-rgb, 232 85 122) / 0.10), transparent 70%),
    radial-gradient(40% 24% at 88% 8%, rgb(var(--accent-2-rgb, 79 216 232) / 0.06), transparent 70%);
  mix-blend-mode: screen;
}

/* =====================================================================
   2. RYTHME ÉDITORIAL DES SECTIONS : strates, filets qui se tracent
   ===================================================================== */
/* Alternance de ton très subtile : une section sur deux reçoit un voile
   plus clair → les blocs se lisent comme composés, pas uniformes. */
main > .ej-section:nth-of-type(even):not(.ej-quote) {
  background:
    linear-gradient(180deg, rgb(var(--veil-rgb, 143 193 219) / 0.022) 0%, transparent 22%, transparent 78%, rgba(3, 3, 5, 0.28) 100%);
}

/* Filet de section anobli : dégradé lumineux au centre plutôt qu'un trait plat */
.ej-section[style*="border-top"] {
  border-top: 0 !important;
  position: relative;
}
.ej-section[style*="border-top"]::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--rz-hairline-lit) 50%, transparent);
  opacity: 0.7;
}

/* Sur-titre (kicker) : trait qui se trace à l'entrée (piloté par JS .is-drawn) */
.ej-kicker::before {
  transform: scaleX(0.55); transform-origin: left center;
  transition: transform 0.9s var(--rz-ease-out), opacity 0.6s ease;
}
/* le kicker porte lui-même .ej-reveal → reçoit .is-in ; ou son en-tête est tracé */
.ej-section-head.is-drawn .ej-kicker::before,
.ej-kicker.is-in::before { transform: scaleX(1); }

/* En-tête de section : filet horizontal fin qui se trace sous le titre */
.ej-section-head { position: relative; }
.ej-section-head::after {
  content: ""; display: block; height: 1px; margin-top: clamp(1.4rem, 3vw, 2.2rem);
  max-width: 8.5rem;
  background: linear-gradient(90deg, var(--rz-hairline-lit), transparent);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 1s var(--rz-ease-out) 0.15s;
}
.ej-section-head.is-center::after { margin-left: auto; margin-right: auto;
  background: linear-gradient(90deg, transparent, var(--rz-hairline-lit), transparent); }
.ej-section-head.is-drawn::after { transform: scaleX(1); }

/* =====================================================================
   3. HERO : présence éditoriale, profondeur, indice de défilement
   ===================================================================== */
.ej-hero-inner { max-width: var(--container); margin: 0 auto; }
/* Le kicker du hero respire davantage */
.ej-hero .ej-kicker { letter-spacing: 0.26em; opacity: 0.95; }
/* Titre : contraste et tenue typographique */
.ej-hero-title { letter-spacing: -0.025em; line-height: 1.04; text-wrap: balance; }
/* Indice de défilement : trait vertical lumineux qui pulse, bas du hero */
.ej-hero::after {
  content: ""; position: absolute; left: 50%; bottom: 1.6rem; width: 1px; height: 46px;
  background: linear-gradient(180deg, transparent, var(--rz-hairline-lit));
  transform: translateX(-50%); transform-origin: bottom; z-index: 2;
  animation: rzScrollCue 2.6s var(--ease) infinite;
}
@keyframes rzScrollCue {
  0%, 100% { opacity: 0.15; transform: translateX(-50%) scaleY(0.55); }
  50%      { opacity: 0.9;  transform: translateX(-50%) scaleY(1); }
}

/* =====================================================================
   4. CARTES : papier muséal froid : relief, rim lumineux, hover noble
   ===================================================================== */
/* Liseré HUD supérieur : plus présent, lumière d’enseigne */
.ej-card::before { background: var(--rz-hairline-lit); opacity: 0.6; height: 2px; box-shadow: 0 0 10px var(--rz-glow); }
.ej-card:hover::before { width: 72px; opacity: 1; }
/* Numéro d'index : capitale froide, présence d'archive */
.ej-card-index { color: var(--ln-rose, #E8557A); opacity: 0.85; }
.ej-access-card .ej-card-arrow { transition: gap 0.4s var(--ease), color 0.4s var(--ease); }
.ej-access-card:hover .ej-card-arrow { color: var(--ln-cyan-soft, #93E9F3); }

/* Cartes œuvres : cadre intérieur + lévitation */
.ej-work-cover { box-shadow: inset 0 0 0 1px rgb(var(--hairline-rgb, 232 232 238) / 0.08), inset 0 -40px 60px -40px rgba(2, 2, 4, 0.8); }

/* =====================================================================
   5. BOUTONS : remplissage balayé, focus premium
   ===================================================================== */
.ej-btn { position: relative; overflow: hidden; isolation: isolate; }
/* Balayage lumineux au survol (primary) */
.ej-btn--primary::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(120deg, transparent 20%, rgba(255, 255, 255, 0.55) 50%, transparent 80%);
  transform: translateX(-120%); transition: transform 0.7s var(--rz-ease-out);
}
.ej-btn--primary:hover::after { transform: translateX(120%); }
/* Focus clavier visible et raffiné */
.ej-btn:focus-visible,
.ej-nav-link:focus-visible,
.ej-source-link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--ln-asphalt, #0B0B0D), 0 0 0 4px var(--rz-hairline-lit);
  border-radius: 4px;
}

/* =====================================================================
   6. SECTIONS IMAGE + TEXTE : direction artistique éditoriale
   ===================================================================== */
/* ombre portée sur le CONTENEUR (sinon overflow:hidden la rognerait sur l'img) */
.ej-split-media { position: relative; overflow: hidden; border-radius: var(--radius, 14px); box-shadow: 0 24px 60px rgba(2, 2, 4, 0.5); }
.ej-split-media img { border: 0; border-radius: inherit; }
/* Voile d'étalonnage froid + liseré intérieur (cadre muséal) */
.ej-split-media::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(180deg, rgb(var(--bg-rgb, 11 11 13) / 0) 55%, rgba(3, 3, 5, 0.45) 100%);
  box-shadow: inset 0 0 0 1px var(--rz-hairline);
}
.ej-figure-cap { color: var(--ln-smoke, #9A9AA2); }

/* =====================================================================
   7. FOOTER : finition : titres laiton froid, liens soulignés animés
   ===================================================================== */
.ej-footer { position: relative; }
.ej-footer::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--rz-hairline-lit), transparent);
  opacity: 0.6;
}
.ej-footer-col a { position: relative; display: inline-block; }
.ej-footer-col a::after {
  content: ""; position: absolute; left: 0; bottom: -2px; width: 100%; height: 1px;
  background: var(--ln-rose, #E8557A);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 0.4s var(--ease);
}
.ej-footer-col a:hover::after { transform: scaleX(1); }

/* =====================================================================
   8. RÉVÉLATIONS : courbe raffinée + cascade échelonnée (piloté par JS)
   ===================================================================== */
.ej-reveal {
  transform: translateY(30px) scale(0.992);
  transition:
    opacity 0.9s var(--rz-ease-out), transform 0.9s var(--rz-ease-out);
}
/* will-change seulement tant que non révélé → la couche compositeur est libérée après .is-in */
.ej-reveal:not(.is-in) { will-change: opacity, transform; }
.ej-reveal.is-in { transform: none; }
/* La cascade (transition-delay par index) est appliquée en inline par le JS. */

/* Images à parallaxe / zoom au scroll : préparées par le JS (.ej-parallax) */
.ej-parallax { will-change: transform; }

/* =====================================================================
   9. ACCESSIBILITÉ MOUVEMENT : tout repli proprement
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  .ej-hero::after { animation: none; opacity: 0.4; }
  .ej-section-head::after,
  .ej-kicker::before { transform: none !important; transition: none; }
  .ej-btn--primary::after { display: none; }
  .ej-parallax { transform: none !important; }
}

/* =====================================================================
   10. ATELIER : finition « tirage argentique »
   Grain de pellicule, typographie de revue, micro-détails pour l'œil
   aguerri. Tout additif, tout réversible.
   ===================================================================== */

/* Patine : grain de pellicule très fin, voile uniforme (derrière nav/boutons) */
main::after {
  content: ""; position: fixed; inset: 0; z-index: 1; pointer-events: none;
  /* Texture retirée : dans la feuille d'origine, cette déclaration était
     mal formée (des restes de balisage SVG suivaient l'URL) et les
     navigateurs l'ignoraient. Elle n'a jamais été visible sur le site publié. */
  opacity: 0.025; mix-blend-mode: soft-light;
}

/* Typographie de revue : équilibrage optique + gravure soignée */
.ej-section-title, .ej-page-hero .ej-section-title {
  text-wrap: balance;
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
  letter-spacing: -0.016em;
}
.ej-hero-title { font-feature-settings: "kern" 1, "liga" 1, "calt" 1; }

/* Lettrine éditoriale : initiale Bodoni sur le chapô de l'accueil */
.ej-prose p.ej-lead::first-letter {
  font-family: var(--font-display); font-style: normal;
  font-size: 3.1em; line-height: 0.72; float: left;
  margin: 0.05em 0.16em -0.06em 0;
  color: var(--ln-rose, var(--gold));
}

/* Respiration : air entre le titre et le corps de texte (prose) */
.ej-prose .ej-section-title { margin-bottom: clamp(1.5rem, 3.2vw, 2.2rem); }
.ej-prose .ej-section-title + .ej-lead,
.ej-prose .ej-section-title + p { margin-top: 0; }

/* Citations : ponctuation suspendue + équilibre des lignes */
.ej-quote-text { text-wrap: balance; hanging-punctuation: first last; }
.ej-quote-author { font-size: 0.72rem; }

/* Micro-détail, le point net en fin de kicker (« épingle de spécimen ») */
.ej-kicker::after {
  content: ""; width: 3px; height: 3px; border-radius: 50%; flex: 0 0 auto;
  background: var(--rz-hairline-lit); opacity: 0;
  transition: opacity 0.6s var(--rz-ease-out) 0.25s;
}
.ej-kicker.is-in::after, .ej-reveal.is-in .ej-kicker::after { opacity: 0.6; }

/* Finesse des soulignés de liens */
.ej-prose a:not(.ej-btn), .ej-source-link, .ej-contact-mail { text-underline-offset: 4px; }

@media (prefers-reduced-motion: reduce) {
  main::after { opacity: 0.018; }
  .ej-kicker::after { transition: none; }
}

/* =====================================================================
   10. CARTES : PANNEAU INCLINABLE
   ---------------------------------------------------------------------
   Au repos : une surface sombre grainée, deux halos d'angle aux couleurs
   de l'archive, un liseré à 7 % de blanc, angles à 20 px.
   Au survol : la carte s'incline vers le curseur, un anneau conique
   s'allume du côté où se trouve la souris, un projecteur la suit, et un
   reflet diagonal traverse le panneau.

   L'inclinaison et les trois positions (projecteur, angle de l'anneau)
   viennent de js/card-tilt.js, posées en style en ligne. Tout le reste
   est en CSS : sans JavaScript, la carte reste entière, seulement fixe.
   ===================================================================== */
.ej-card,
.ej-work,
.ej-video,
.ej-edition {
  /* les deux halos d'angle, repris dans l'état de survol pour couvrir les
     règles de fond des couches inférieures */
  --ej-mesh:
    radial-gradient(600px circle at 0% 0%, rgb(var(--gold-rgb, 232 85 122) / 0.12), transparent 60%),
    radial-gradient(700px circle at 100% 100%, rgb(var(--accent-2-rgb, 79 216 232) / 0.07), transparent 60%);

  position: relative;
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, 0.07);
  background-color: #111116;
  background-image: var(--ej-mesh);
  box-shadow: none;
  transition:
    transform 0.6s cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow 0.3s ease,
    border-color 0.3s ease;
}

.ej-card:hover,
.ej-work:hover,
.ej-video:hover,
.ej-edition:hover {
  background-color: #111116;
  background-image: var(--ej-mesh);
  border-color: rgb(var(--gold-rgb, 232 85 122) / 0.24);
  box-shadow: 0 30px 80px rgb(var(--gold-rgb, 232 85 122) / 0.2);
  /* l'inclinaison arrive en style en ligne : ici on neutralise seulement
     les anciens soulèvements */
  transform: none;
}

/* La carte vidéo n'était pas un panneau : elle le devient. */
.ej-video { padding: 1rem; }

/* Le contenu passe au-dessus des couches d'effet. */
.ej-card > :not(.ej-card-fx),
.ej-work > :not(.ej-card-fx),
.ej-video > :not(.ej-card-fx),
.ej-edition > :not(.ej-card-fx) { position: relative; z-index: 1; }

/* Le grain, sur toute la surface, en fondu de superposition. */
.ej-card::after,
.ej-work::after,
.ej-video::after,
.ej-edition::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  /* Texture retirée : dans la feuille d'origine, cette déclaration était
     mal formée (des restes de balisage SVG suivaient l'URL) et les
     navigateurs l'ignoraient. Elle n'a jamais été visible sur le site publié. */
  background-size: 160px 160px;
  opacity: 0.04;
  mix-blend-mode: overlay;
}

/* Projecteur (suit le curseur) et reflet diagonal, allumés au survol. */
.ej-card-fx {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s ease;
  background-image:
    radial-gradient(200px circle at var(--ej-mx, 50%) var(--ej-my, 50%),
      rgba(255, 255, 255, 0.07) 0%, transparent 65%),
    linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, transparent 55%);
}

/* L'anneau conique : un arc de 60 degrés dont l'origine suit la souris. */
.ej-card-fx::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--ej-ring, 0deg) at 50% 50%,
    rgb(var(--gold-rgb, 232 85 122) / 0.85) 0deg,
    transparent 60deg,
    transparent 300deg,
    rgb(var(--gold-rgb, 232 85 122) / 0.85) 360deg);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

.ej-card:hover .ej-card-fx,
.ej-card:focus-within .ej-card-fx,
.ej-work:hover .ej-card-fx,
.ej-work:focus-within .ej-card-fx,
.ej-video:hover .ej-card-fx,
.ej-video:focus-within .ej-card-fx,
.ej-edition:hover .ej-card-fx,
.ej-edition:focus-within .ej-card-fx { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .ej-card,
  .ej-work,
  .ej-video,
  .ej-edition { transition: box-shadow 0.3s ease, border-color 0.3s ease; }
}

/* =====================================================================
   11. LUSTRE : reflets spéculaires & spectre néon (œil aguerri)
   Laque noire, chrome, verre, halo d'enseigne. Très subtil, réversible.
   ===================================================================== */
:root {
  /* Spectre d'enseigne au néon : rose → violet → cyan */
  --rz-iris: linear-gradient(90deg, transparent,
     rgb(var(--gold-rgb, 232 85 122) / 0.6) 26%, rgb(var(--iris-rgb, 184 120 224) / 0.40) 44%,
     rgb(var(--accent-2-rgb, 79 216 232) / 0.42) 60%, rgb(var(--gold-rgb, 232 85 122) / 0.6) 80%, transparent);
}

/* Filets spectraux : l'arête captée par l'enseigne */
.ej-section-head::after {
  background: linear-gradient(90deg, rgb(var(--gold-rgb, 232 85 122) / 0.66),
     rgb(var(--iris-rgb, 184 120 224) / 0.42) 42%, rgb(var(--accent-2-rgb, 79 216 232) / 0.38) 68%, transparent);
}
.ej-section-head.is-center::after { background: var(--rz-iris); }
.ej-footer::before { background: var(--rz-iris); opacity: 0.85; }

/* Bouton primaire, effet perle : reflet haut posé, ombre interne basse */
.ej-btn--primary {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.6),
    inset 0 -9px 15px -11px rgb(var(--bg-rgb, 11 11 13) / 0.3);
}

/* Lien actif & wordmark : halo néon d’une extrême finesse */
.ej-nav-link.is-active::after { box-shadow: 0 0 8px rgb(var(--gold-rgb, 232 85 122) / 0.55); }
.ej-logo { transition: filter 0.45s var(--ease); }
.ej-logo:hover { filter: drop-shadow(0 0 5px rgb(var(--gold-rgb, 232 85 122) / 0.4)); }

/* Couvertures d'œuvres : lustre de vitrine (sous verre) */
.ej-work-cover { position: relative; }
.ej-work-cover::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background: linear-gradient(122deg, rgba(255,255,255,0.07) 0%, transparent 26%, transparent 74%, rgba(255,255,255,0.035) 100%);
  mix-blend-mode: overlay; opacity: 0.55;
  transition: opacity 0.6s var(--ease);
}
.ej-work:hover .ej-work-cover::after { opacity: 0.85; }

@media (prefers-reduced-motion: reduce) { .ej-logo { transition: none; } }

/* =====================================================================
   12. VHS : lignes de balayage & dérive chromatique (très léger)
   La bande usée, la copie de la copie. Aucun mouvement agressif :
   une trame fixe à 0.5 % d'opacité et un souffle lent sur les titres.
   ===================================================================== */
body::after {
  background-image:
    radial-gradient(60% 32% at 50% 0%, rgb(var(--gold-rgb, 232 85 122) / 0.10), transparent 70%),
    radial-gradient(40% 24% at 88% 8%, rgb(var(--accent-2-rgb, 79 216 232) / 0.06), transparent 70%),
    repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.016) 0 1px, transparent 1px 4px);
  background-blend-mode: normal;
}

/* Dérive chromatique d'enseigne sur le titre du hero : un seul pixel d'écart */
.ej-hero-title {
  text-shadow:
    0 2px 44px rgba(0, 0, 0, 0.7),
    -1px 0 0 rgb(var(--gold-rgb, 232 85 122) / 0.16),
     1px 0 0 rgb(var(--accent-2-rgb, 79 216 232) / 0.14);
}

/* Le kicker : une enseigne qui vient de s'allumer */
.ej-page-hero .ej-kicker { color: var(--ln-rose, #E8557A); }

@media (prefers-reduced-motion: reduce) {
  .ej-hero-title { text-shadow: 0 2px 44px rgba(0, 0, 0, 0.7); }
}

/* =====================================================================
   TRACEUR DE SOURIS
   Le canevas est créé par js/cursor-trail.js, jamais présent sans lui.
   Posé sous la barre de navigation (100) et sous la lightbox (200), il
   glisse donc derrière l'en-tête comme le fait le contenu.
   ===================================================================== */
.ej-trail {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
  mix-blend-mode: screen;
}

@media (prefers-reduced-motion: reduce) {
  .ej-trail { display: none; }
}

/* =====================================================================
   BOUTON À PIXELS (second appel du hero)
   Cinq couches empilées : le fond noir, un faisceau conique qui tourne
   sur la bordure, la grille de pixels (js/pixel-button.js), un halo bas
   qui monte au survol, et le libellé détaché par un anneau d'ombres.
   Sans le JS, il reste un bouton noir à liseré tournant : rien ne casse.
   ===================================================================== */
@property --ej-beam {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
@property --ej-beam-w {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 5%;
}

.ej-btn--pixel {
  --ej-beam-1: var(--ln-rose, #E8557A);
  --ej-beam-2: var(--ln-cyan, #4FD8E8);
  --ej-btn-bg: var(--ln-asphalt, #0B0B0D);
  /* lues par le JS pour colorer la grille */
  --ej-px-1: var(--gold, #E8557A);
  --ej-px-2: var(--gold-soft, #F58CA7);
  --ej-px-3: var(--accent-2, #4FD8E8);

  color: var(--ln-bone, #E7E7E9);
  border: 1px solid transparent;
  box-shadow: inset 0 0 0 1px rgb(var(--hairline-rgb, 232 232 238) / 0.14);
  background:
    linear-gradient(var(--ej-btn-bg), var(--ej-btn-bg)) padding-box,
    conic-gradient(from var(--ej-beam),
      transparent,
      var(--ej-beam-1) var(--ej-beam-w),
      var(--ej-beam-2) calc(var(--ej-beam-w) * 2),
      var(--ej-beam-1) calc(var(--ej-beam-w) * 3),
      transparent calc(var(--ej-beam-w) * 4)) border-box;
  animation: ej-beam-spin 3s linear infinite;
  transition: color 220ms var(--ease), box-shadow 220ms var(--ease),
              --ej-beam-w 500ms var(--ease);
}

@keyframes ej-beam-spin { to { --ej-beam: 360deg; } }

.ej-btn--pixel:hover,
.ej-btn--pixel:focus-visible {
  --ej-beam-w: 20%;
  color: var(--ln-bone-bright, #FAFAFB);
  box-shadow: inset 0 0 0 1px rgb(var(--gold-rgb, 232 85 122) / 0.35);
}

/* La grille, posée à l'intérieur du liseré */
.ej-btn-pixels {
  position: absolute;
  inset: 1px;
  z-index: 0;
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
  transition: filter 0.1s linear;
}
.ej-btn-pixels canvas { display: block; width: 100%; height: 100%; }
.ej-btn--pixel:hover .ej-btn-pixels { filter: brightness(1.15) contrast(1.05); }
.ej-btn--pixel:active .ej-btn-pixels { filter: brightness(1.5) contrast(1.2); }

/* Le halo, qui monte du bas au survol */
.ej-btn-glow {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: calc(100% + 1rem);
  height: calc(100% + 1rem);
  box-shadow: inset 0 -1ex 2rem 4px var(--ln-rose, #E8557A);
  border-radius: inherit;
  pointer-events: none;
  z-index: 3;
  opacity: 0;
  transition: opacity 0.8s var(--ease);
}
.ej-btn--pixel:hover .ej-btn-glow,
.ej-btn--pixel:focus-visible .ej-btn-glow { opacity: 1; }

/* Le libellé, au-dessus de tout, cerné d'ombres pour rester lisible */
.ej-btn-label {
  position: relative;
  z-index: 10;
  text-shadow:
    -3px 0px 20px rgb(var(--bg-rgb, 11 11 13) / 0.2), -2px -2px 20px rgb(var(--bg-rgb, 11 11 13) / 0.2),
    -2px -1px 20px rgb(var(--bg-rgb, 11 11 13) / 0.204), -2px 0px 20px rgb(var(--bg-rgb, 11 11 13) / 0.267),
    -2px 1px 20px rgb(var(--bg-rgb, 11 11 13) / 0.204), -2px 2px 20px rgb(var(--bg-rgb, 11 11 13) / 0.2),
    -1px -2px 20px rgb(var(--bg-rgb, 11 11 13) / 0.204), -1px -1px 20px rgb(var(--bg-rgb, 11 11 13) / 0.423),
    -1px 0px 20px rgb(var(--bg-rgb, 11 11 13) / 0.533), -1px 1px 20px rgb(var(--bg-rgb, 11 11 13) / 0.423),
    -1px 2px 20px rgb(var(--bg-rgb, 11 11 13) / 0.204), 0px -3px 20px rgb(var(--bg-rgb, 11 11 13) / 0.2),
    0px -2px 20px rgb(var(--bg-rgb, 11 11 13) / 0.267), 0px -1px 20px rgb(var(--bg-rgb, 11 11 13) / 0.533),
    0px 1px 20px rgb(var(--bg-rgb, 11 11 13) / 0.533), 0px 2px 20px rgb(var(--bg-rgb, 11 11 13) / 0.267),
    0px 3px 20px rgb(var(--bg-rgb, 11 11 13) / 0.2), 1px -2px 20px rgb(var(--bg-rgb, 11 11 13) / 0.204),
    1px -1px 20px rgb(var(--bg-rgb, 11 11 13) / 0.423), 1px 0px 20px rgb(var(--bg-rgb, 11 11 13) / 0.533),
    1px 1px 20px rgb(var(--bg-rgb, 11 11 13) / 0.423), 1px 2px 20px rgb(var(--bg-rgb, 11 11 13) / 0.204),
    2px -2px 20px rgb(var(--bg-rgb, 11 11 13) / 0.2), 2px -1px 20px rgb(var(--bg-rgb, 11 11 13) / 0.204),
    2px 0px 20px rgb(var(--bg-rgb, 11 11 13) / 0.267), 2px 1px 20px rgb(var(--bg-rgb, 11 11 13) / 0.204),
    2px 2px 20px rgb(var(--bg-rgb, 11 11 13) / 0.2), 3px 0px 20px rgb(var(--bg-rgb, 11 11 13) / 0.2),
    0px 0px 10px var(--bg, #0B0B0D);
}

@media (prefers-reduced-motion: reduce) {
  .ej-btn--pixel { animation: none; }
  .ej-btn-glow { transition: none; }
}


/* =====================================================================
   LA SCÈNE DES CARTES (dossier American Psycho)
   ---------------------------------------------------------------------
   Trois spécimens de papier sur le noir de l'archive. Aucune adresse,
   aucun logo : le roman n'en donne pas. Ce qu'il donne, c'est la teinte
   du papier et le nom du caractère, et c'est tout ce qui est montré.
   Les trois blancs sont presque identiques, et c'est le sujet de la
   scène. Les cartes s'inclinent avec js/card-tilt.js, comme le reste
   du site ; l'anneau néon des panneaux est retiré ici : sur du papier,
   c'est un reflet blanc qui balaie, pas une enseigne.
   ===================================================================== */
.ej-visitcards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: clamp(1.6rem, 4vw, 3rem);
  margin: clamp(2.4rem, 6vw, 4rem) 0 2.4rem;
}

.ej-visitcard { margin: 0; position: relative; }

.ej-visitcard-face {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 7 / 4;
  padding: 1.4rem;
  border-radius: 3px;
  background: var(--ej-paper, #EDE8DE);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.5) inset,
    6px 14px 34px -6px rgba(0, 0, 0, 0.7),
    0 2px 6px rgba(0, 0, 0, 0.5);
}

/* Le grain du papier, très bas, pour que le blanc ne soit pas un aplat. */
.ej-visitcard-face::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  /* Texture retirée : dans la feuille d'origine, cette déclaration était
     mal formée (des restes de balisage SVG suivaient l'URL) et les
     navigateurs l'ignoraient. Elle n'a jamais été visible sur le site publié. */
  background-size: 160px 160px;
  opacity: 0.055;
  mix-blend-mode: multiply;
}

.ej-visitcard-name {
  position: relative;
  z-index: 1;
  color: var(--ink, #171512);
  text-align: center;
  line-height: 1.2;
}

/* Les trois papiers, et les trois façons d'imprimer dessus. */
.ej-visitcard--silian { --ej-paper: #EDE8DE; }
.ej-visitcard--silian .ej-visitcard-name {
  font-family: var(--font-display, Georgia, serif);
  font-size: clamp(1.05rem, 2.1vw, 1.35rem);
  letter-spacing: 0.06em;
}

.ej-visitcard--romalian { --ej-paper: #F0EAD6; }
.ej-visitcard--romalian .ej-visitcard-name {
  font-family: var(--font-display, Georgia, serif);
  font-size: clamp(0.95rem, 1.9vw, 1.2rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

/* « Raised lettering » : l'encre est en relief, donc elle porte une ombre
   en dessous et une lumière au-dessus. */
.ej-visitcard--nimbus { --ej-paper: #E9EBEC; }
.ej-visitcard--nimbus .ej-visitcard-name {
  font-family: var(--font-display, Georgia, serif);
  font-size: clamp(1.05rem, 2.1vw, 1.35rem);
  letter-spacing: 0.08em;
  color: #1B1E22;
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.85),
    0 -1px 0 rgba(0, 0, 0, 0.35);
}

.ej-visitcard figcaption {
  margin-top: 1.1rem;
  text-align: center;
}

.ej-visitcard-quote {
  display: block;
  quotes: none;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  line-height: 1.7;
  color: var(--ln-smoke, #9A9AA2);
}
.ej-visitcard-quote::before { content: "\201C"; }
.ej-visitcard-quote::after { content: "\201D"; }

.ej-visitcard-src {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--ln-smoke, #9A9AA2);
  opacity: 0.8;
  margin-bottom: 1.4rem;
}

/* Sur du papier, pas d'anneau néon : un reflet blanc qui suit le curseur. */
.ej-visitcard .ej-card-fx {
  border-radius: 3px;
  mix-blend-mode: overlay;
  background-image:
    radial-gradient(240px circle at var(--ej-mx, 50%) var(--ej-my, 50%),
      rgba(255, 255, 255, 0.6) 0%, transparent 62%);
}
.ej-visitcard .ej-card-fx::before { content: none; }
.ej-visitcard:hover .ej-card-fx,
.ej-visitcard:focus-within .ej-card-fx { opacity: 1; }


/* =====================================================================
   LES SURFACES DE LECTURE PASSENT AU PAPIER
   ---------------------------------------------------------------------
   La ville reste noire : fond de page, navigation, hero, pied. Ce qui se
   lit devient du papier os, comme la carte de la scène des cartes.

   Le basculement se fait par jetons, en portée locale. Les cinquante
   classes internes des panneaux (titres, années, catégories, liens
   croisés, drapeaux d'édition) ne sont pas reprises une à une : elles
   lisent déjà --text, --muted, --gold, --border. On redéfinit ces
   jetons à l'intérieur du panneau, et tout suit.

   Le cyan ne survit pas au passage : il est illisible sur clair. Il est
   remappé sur le rose assombri, qui tient le contraste sur le papier.
   ===================================================================== */
.ej-card,
.ej-work,
.ej-video,
.ej-edition,
.ej-era,
.ej-prose {
  /* Papier, encre, accent et encre tertiaire : rôles de la palette, émis par
     le pont en :root. Les redéclarer ici sous leur propre nom créait une
     référence circulaire, que le navigateur invalide. */
  --ink-soft:     var(--ink-muted, #55504A);
  --paper-rule:   rgb(var(--ink-line-rgb, 23 21 18) / 0.16);
  --paper-rule-2: rgb(var(--ink-line-rgb, 23 21 18) / 0.34);

  /* jetons sémantiques d'archive.css */
  --text: var(--ink);
  --muted: var(--ink-soft);
  --gold: var(--paper-accent);
  --gold-soft: var(--paper-accent);
  --border: var(--paper-rule);
  --border-strong: var(--paper-rule-2);
  --surface: var(--paper);
  --surface-2: var(--paper-2);
  --color-cool-gray: var(--ink-soft);
  --color-smoke: var(--ink-soft);
  --color-bone: var(--ink);

  /* jetons du thème neon-noir */
  --ln-bone: var(--ink);
  --ln-bone-bright: var(--ink-strong, #0E0C0A);
  --ln-smoke: var(--ink-soft);
  --ln-rose: var(--paper-accent);
  --ln-rose-soft: var(--paper-accent);
  --ln-cyan: var(--paper-accent);
  --ln-cyan-soft: var(--paper-accent);
  --ln-border: var(--paper-rule);
  --ln-border-strong: var(--paper-rule-2);
  --ln-panel: var(--paper);
  --ln-panel-2: var(--paper-2);

  /* jetons de finition */
  --rz-hairline: var(--paper-rule);
  --rz-hairline-lit: var(--paper-accent);
  --rz-glow: rgb(var(--paper-accent-rgb, 168 44 76) / 0.3);

  color: var(--ink);
}

/* La feuille elle-même : angles coupés court, ombre portée d'objet posé. */
.ej-card,
.ej-work,
.ej-video,
.ej-edition,
.ej-era,
.ej-prose {
  position: relative;
  border-radius: 4px;
  background-color: var(--paper);
  background-image: none;
  border: 1px solid rgb(var(--ink-line-rgb, 23 21 18) / 0.22);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 2px 6px rgba(0, 0, 0, 0.45),
    6px 16px 38px -8px rgba(0, 0, 0, 0.7);
}

/* Les deux longues feuilles n'avaient pas de marge intérieure. */
.ej-era,
.ej-prose { padding: clamp(1.5rem, 3.4vw, 2.6rem); }
.ej-prose { max-width: 46rem; }
.ej-era .ej-timeline { border-left-color: var(--paper-rule-2); }

/* opacity remise dans la liste : les panneaux portent aussi .ej-reveal,
   et sans elle leur apparition au défilement sautait au lieu de fondre. */
.ej-card,
.ej-work,
.ej-video,
.ej-edition {
  transition:
    opacity 0.9s var(--rz-ease-out),
    transform 0.6s cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow 0.3s ease,
    border-color 0.3s ease;
}

.ej-card:hover,
.ej-work:hover,
.ej-video:hover,
.ej-edition:hover {
  background-color: var(--paper);
  background-image: none;
  border-color: rgb(var(--ink-line-rgb, 23 21 18) / 0.3);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 3px 10px rgba(0, 0, 0, 0.5),
    10px 26px 60px -10px rgba(0, 0, 0, 0.78);
  transform: none;
}

/* Le grain : de la fibre, donc en multiplication, pas en superposition. */
.ej-card::after,
.ej-work::after,
.ej-video::after,
.ej-edition::after,
.ej-era::after,
.ej-prose::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  /* Texture retirée : dans la feuille d'origine, cette déclaration était
     mal formée (des restes de balisage SVG suivaient l'URL) et les
     navigateurs l'ignoraient. Elle n'a jamais été visible sur le site publié. */
  background-size: 160px 160px;
  opacity: 0.06;
  mix-blend-mode: multiply;
}
.ej-era > *,
.ej-prose > * { position: relative; z-index: 1; }

/* Au survol : plus d'anneau néon sur du papier, un reflet blanc qui balaie. */
.ej-card .ej-card-fx,
.ej-work .ej-card-fx,
.ej-video .ej-card-fx,
.ej-edition .ej-card-fx {
  border-radius: inherit;
  mix-blend-mode: overlay;
  background-image:
    radial-gradient(300px circle at var(--ej-mx, 50%) var(--ej-my, 50%),
      rgba(255, 255, 255, 0.55) 0%, transparent 62%);
}
.ej-card .ej-card-fx::before,
.ej-work .ej-card-fx::before,
.ej-video .ej-card-fx::before,
.ej-edition .ej-card-fx::before { content: none; }

/* Deux fonds translucides pensés pour le noir, réaccordés au papier. */
.ej-xref a { background: rgb(var(--paper-accent-rgb, 168 44 76) / 0.07); }
.ej-edition-flag { background: rgb(var(--ink-line-rgb, 23 21 18) / 0.05); }

/* Trois libellés tertiaires prenaient leur couleur dans un jeton de filet.
   Sur le noir, ce gris translucide passait ; sur le papier, il tombait à
   2,13:1. Ils reçoivent une encre pâle, mesurée au-dessus de 4,5:1. */
.ej-work-cat,
.ej-tl-src,
.ej-edition-poche { color: var(--ink-faint); }
