/* ==========================================================================
   GABARIT DES ENTRÉES LORE (maquette client « lore-duality »)

   FEUILLE PARTAGÉE PAR TOUTES LES SOUS-PAGES DE LA SECTION LORE & UNIVERS.
   La maquette était écrite pour être dupliquée : son bloc :root portait la
   consigne « pour dupliquer ce gabarit, changer ces trois valeurs ». Elle est
   donc intégrée UNE SEULE FOIS ici, et les sept entrées prévues (Duality,
   Duelliste Embrasement, Shattered, la Radianite, Kingdom, les Radiants, le
   First Light) partageront ce fichier sans y ajouter une seule règle.

   CE QUI CHANGE D'UNE PAGE À L'AUTRE, ce sont les TROIS JETONS D'ACCENT de la
   maquette, et rien d'autre :

     --entry       la couleur d'accent de l'entrée
     --entry-soft  la même en halo translucide, pour le dégradé du hero
     --entry-grad  le dégradé sombre de l'illustration du hero

   Ils sont posés PAR PAGE, en jetons locaux sur le conteneur .lore-entree-page
   (attribut style), jamais en :root : ColorPalette y repeindrait le méga menu
   et le pied de page, piège déjà consigné pour lore.css. Les valeurs
   ci-dessous ne sont qu'un REPLI, le violet de la rubrique Lore, servi si une
   page oublie ses jetons.

   TOUTES les règles sont scopées sous .lore-entree-page, sans exception. La
   feuille est chargée dans @section('head'), donc AVANT agent.css et
   mega-menu.css : un sélecteur nu (.content, .box, .key, .next…) y perdrait
   ses arbitrages de spécificité et déborderait sur le reste du site.

   CE QUI VIENT D'AGENT.CSS et n'est pas redéclaré ici : le reset, le body, la
   palette de marque (--dark, --text, --text-light, --bg, --white) et
   l'anatomie du fil d'Ariane. La maquette redéclarait tout cela dans un
   premier bloc de style, avec en prime le CSS complet d'un listing d'agents
   sans balisage correspondant : rien n'en a été repris.

   --hdr-h N'EST PAS REDÉCLARÉE : elle vient de mega-menu.css (72 px, 62 px
   sous 900 px), qui la tient en :root parce que c'est la hauteur réelle de la
   barre collante. La maquette la figeait à 70 px, ce qui décalait la colonne
   collante des deux côtés de la bascule.

   LE PIED DE PAGE N'EST PAS REPEINT. La maquette le passait en violet foncé
   (#0b0714) par une règle globale sur `footer`. La feuille étant scopée, le
   pied de page commun du site garde son apparence : la page sombre s'arrête à
   son propre contenu, comme sur le hub de la section.
   ========================================================================== */

  .lore-entree-page {
    /* Repli des trois jetons d'accent : chaque page pose les siens en style
       local, qui l'emportent sur ceux-ci. */
    --entry: #7c5cbf;
    --entry-soft: rgba(124,92,191,0.22);
    --entry-grad: linear-gradient(150deg, #150c22, #4a2f7a);

    /* Le violet de la rubrique Lore, commun à toutes les entrées : liens du
       texte, encadré des spéculations, bloc de retour au hub. */
    --lore: #7c5cbf;
    --lore-dark: #63489c;
    --lore-light: #efeafa;
  }

  /* ========== HERO ========== */

  .lore-entree-page .entry-hero {
    position: relative;
    overflow: hidden;
    background: #0b0714;
  }
  .lore-entree-page .entry-hero .eh-art {
    position: absolute;
    inset: 0;
    background: var(--entry-grad);
    opacity: 0.42;
  }
  /* LA VARIANTE À IMAGE, pour les entrées qui en ont une (First Light, 04/08) :
     l'illustration remplace le dégradé de --entry-grad derrière le hero. Elle
     est posée en style local par la page, comme le hero du hub, la feuille
     n'ayant pas à connaître le fichier de chaque entrée. Le cadrage (« center
     40 % ») et le voile (30 %) viennent de la maquette : le titre reste lisible
     par-dessus, le ::after ci-dessous assombrissant le reste. Une entrée sans
     image garde .eh-art, les deux ne se posent jamais ensemble. */
  .lore-entree-page .entry-hero .eh-img {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center 40%;
    opacity: 0.3;
  }
  .lore-entree-page .entry-hero::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
      linear-gradient(180deg, rgba(11,7,20,0.55) 0%, rgba(11,7,20,0.86) 60%, rgba(11,7,20,0.98) 100%),
      radial-gradient(ellipse at 26% 45%, var(--entry-soft) 0%, transparent 60%);
  }
  .lore-entree-page .entry-hero .grain {
    position: absolute;
    inset: 0;
    opacity: 0.45;
    pointer-events: none;
    background-image: radial-gradient(rgba(255,255,255,0.045) 1px, transparent 1px);
    background-size: 3px 3px;
  }
  .lore-entree-page .eh-inner {
    position: relative;
    z-index: 3;
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px 40px 48px;
  }

  /* Le fil d'Ariane vient d'agent.css (mêmes classes, même anatomie) : seules
     les teintes changent, la maquette le voulant plus effacé et son survol à
     l'accent de l'entrée. */
  .lore-entree-page .eh-inner .breadcrumb {
    margin-bottom: 30px;
  }
  .lore-entree-page .eh-inner .breadcrumb a { color: rgba(255,255,255,0.3); }
  .lore-entree-page .eh-inner .breadcrumb a:hover { color: var(--entry); }
  .lore-entree-page .eh-inner .breadcrumb .sep { color: rgba(255,255,255,0.14); }
  .lore-entree-page .eh-inner .breadcrumb .current { color: rgba(255,255,255,0.58); }

  .lore-entree-page .eh-tags {
    display: flex;
    gap: 9px;
    flex-wrap: wrap;
    margin-bottom: 14px;
  }
  .lore-entree-page .eh-tag {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 5px 13px;
    border-radius: 7px;
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
  }
  /* L'étiquette de branche prend l'accent de l'entrée : elle dit à quelle
     famille du récit la page appartient. Elle se contente des DEUX jetons de
     couleur déjà posés par la page, l'accent et son halo, plutôt que d'en
     réclamer un troisième pour son seul fond. */
  .lore-entree-page .eh-tag.branch {
    background: var(--entry-soft);
    color: var(--entry);
    border: 1px solid var(--entry-soft);
  }
  .lore-entree-page .eh-tag.fmt {
    background: rgba(255,255,255,0.08);
    color: rgba(255,255,255,0.62);
    border: 1px solid rgba(255,255,255,0.1);
  }
  .lore-entree-page .entry-hero h1 {
    font-family: 'Bebas Neue', sans-serif;
    font-size: 3.1rem;
    color: white;
    letter-spacing: 2.5px;
    line-height: 1;
    margin-bottom: 16px;
  }
  .lore-entree-page .eh-lede {
    font-size: 0.98rem;
    color: rgba(255,255,255,0.5);
    line-height: 1.8;
    max-width: 640px;
  }

  /* ========== MISE EN PAGE : TEXTE ET COLONNE LATÉRALE ========== */

  .lore-entree-page .layout {
    max-width: 1200px;
    margin: 0 auto;
    padding: 40px 40px 20px;
    display: grid;
    grid-template-columns: 1fr 300px;
    gap: 48px;
    align-items: start;
  }
  .lore-entree-page .content { max-width: 780px; }
  .lore-entree-page .content h2 {
    font-family: 'Bebas Neue', sans-serif;
    font-size: 1.55rem;
    color: var(--dark);
    letter-spacing: 1px;
    line-height: 1.12;
    margin: 36px 0 15px;
  }
  .lore-entree-page .content h2:first-child { margin-top: 0; }
  .lore-entree-page .content p {
    font-size: 0.93rem;
    color: var(--text-light);
    line-height: 1.92;
    margin-bottom: 16px;
  }
  .lore-entree-page .content p strong {
    color: var(--text);
    font-weight: 600;
  }
  .lore-entree-page .content a {
    color: var(--lore-dark);
    text-decoration: none;
    border-bottom: 1px solid rgba(124,92,191,0.34);
    transition: all 0.2s;
  }
  .lore-entree-page .content a:hover {
    border-bottom-color: var(--lore-dark);
    background: var(--lore-light);
  }
  /* Le chapô. Le sélecteur porte la balise (0,2,1) parce qu'il doit battre
     .lore-entree-page .content p, qui pèse autant : la maquette compensait par
     deux !important, retirés à l'intégration. */
  .lore-entree-page .content p.intro-p {
    font-size: 1rem;
    color: var(--text);
  }

  /* ========== ILLUSTRATION ==========
     La figure d'en-tête d'une entrée (Shattered, 04/08) et, plus largement,
     toute image posée dans le fil du texte. La LÉGENDE EST FACULTATIVE : une
     figure sans figcaption ne laisse aucun blanc sous l'image, la règle ne
     s'applique qu'à la légende quand il y en a une. Composant du gabarit, il
     sert donc toutes les entrées de la section. */

  .lore-entree-page figure {
    margin: 24px 0;
  }
  .lore-entree-page figure img {
    width: 100%;
    height: auto;
    display: block;
    border-radius: 16px;
    border: 1px solid #ececec;
  }
  .lore-entree-page figcaption {
    font-size: 0.73rem;
    color: #b0b0b0;
    font-style: italic;
    text-align: center;
    margin-top: 9px;
  }

  /* ========== FAÇADE VIDÉO ==========
     La vidéo ne se charge qu'au clic (lore-entree.js) : aucune iframe et
     aucun appel à YouTube tant que le lecteur ne l'a pas demandé. */

  .lore-entree-page .vf {
    position: relative;
    display: block;
    width: 100%;
    border: none;
    border-radius: 16px;
    overflow: hidden;
    /* La marge basse valait 8 px tant que la note « la vidéo ne se charge
       qu'au clic » suivait la façade et portait, elle, les 24 px de respiration.
       La note retirée (demande client), c'est la façade qui reprend cette marge
       basse : le titre suivant ne se colle pas à la vidéo. */
    margin: 24px 0;
    aspect-ratio: 16 / 9;
    background: var(--entry-grad);
    cursor: pointer;
    /* La façade est un <button> : il n'hérite pas de la police du body, son
       libellé retomberait sur celle du navigateur. Même déclaration que les
       contrôles d'agent.css et du catalogue. */
    font-family: 'DM Sans', sans-serif;
  }
  /* Vignette réelle de la vidéo, posée par la page au-dessus du dégradé de
     repli ; le voile ::after et les commandes .vf-play restent au-dessus
     (l'un est pseudo-élément du bouton, les autres portent leur z-index). */
  .lore-entree-page .vf-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .lore-entree-page .vf::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(0,0,0,0.34);
    transition: background 0.25s;
  }
  .lore-entree-page .vf:hover::after { background: rgba(0,0,0,0.2); }
  .lore-entree-page .vf-play {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
  }
  /* Le libellé sous la pastille. */
  .lore-entree-page .vf-play span {
    font-size: 0.74rem;
    color: rgba(255,255,255,0.75);
    text-transform: uppercase;
    letter-spacing: 1.5px;
    font-weight: 700;
  }
  /* Le triangle de lecture est un SVG en ligne, jamais le caractère ▶ :
     doctrine du site, aucun pictogramme de police dans le contenu. Il prend sa
     couleur du currentColor de la pastille, qui est elle aussi un span de
     .vf-play : le sélecteur porte donc la balise pour que le BLANC PLEIN
     l'emporte sur le blanc à 75 % du libellé (défaut hérité de la maquette). */
  .lore-entree-page .vf-play span.vf-btn {
    width: 68px;
    height: 68px;
    border-radius: 50%;
    background: rgba(255,255,255,0.15);
    border: 2px solid rgba(255,255,255,0.42);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    padding-left: 5px;
    transition: all 0.25s;
    backdrop-filter: blur(4px);
  }
  .lore-entree-page .vf-btn svg { display: block; }
  .lore-entree-page .vf:hover .vf-btn {
    transform: scale(1.09);
    background: rgba(255,255,255,0.26);
  }
  /* Le lecteur qui remplace la façade au clic : mêmes dimensions, même
     arrondi, pour que rien ne saute à l'écran. */
  .lore-entree-page .vf-frame {
    position: relative;
    border-radius: 16px;
    overflow: hidden;
    aspect-ratio: 16 / 9;
    /* Même marge basse que la façade qu'il remplace, pour la même raison :
       sans la note, rien d'autre ne sépare la vidéo du titre suivant. */
    margin: 24px 0;
  }
  .lore-entree-page .vf-frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
  }
  /* Aucune règle .vf-note ici : la note « la vidéo ne se charge qu'au clic »
     a été retirée des entrées de la section (demande client). Le chargement
     au clic n'a pas bougé, seule la phrase est partie. */

  /* ========== LES SCÈNES ==========
     Une frise verticale numérotée : chaque scène ajoute une pièce, les scènes
     marquées « key » portent la pastille d'accent de l'entrée. */

  .lore-entree-page .scenes {
    position: relative;
    padding-left: 46px;
    margin: 22px 0 0;
  }
  .lore-entree-page .scenes::before {
    content: '';
    position: absolute;
    left: 15px;
    top: 12px;
    bottom: 12px;
    width: 2px;
    background: linear-gradient(180deg, var(--entry), rgba(124,92,191,0.4));
  }
  .lore-entree-page .scene {
    position: relative;
    margin-bottom: 28px;
  }
  .lore-entree-page .scene:last-child { margin-bottom: 0; }
  .lore-entree-page .scene::before {
    content: attr(data-n);
    position: absolute;
    left: -46px;
    top: -2px;
    width: 32px;
    height: 32px;
    border-radius: 10px;
    background: #0b0714;
    color: white;
    font-family: 'Bebas Neue', sans-serif;
    font-size: 0.9rem;
    display: flex;
    align-items: center;
    justify-content: center;
    letter-spacing: 0.5px;
    box-shadow: 0 0 0 4px var(--bg);
    border: 1px solid rgba(255,255,255,0.12);
  }
  .lore-entree-page .scene.key::before { background: var(--entry); }
  .lore-entree-page .scene h3 {
    font-size: 1.02rem;
    font-weight: 700;
    color: var(--dark);
    margin: 3px 0 8px;
  }
  .lore-entree-page .scene p {
    margin-bottom: 0;
    font-size: 0.9rem;
  }
  .lore-entree-page .scene .sc-tag {
    display: inline-block;
    margin-left: 9px;
    font-size: 0.55rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    padding: 3px 8px;
    border-radius: 5px;
    background: var(--entry);
    color: white;
    vertical-align: 2px;
  }

  /* ========== LES PERSONNAGES FACE À FACE ==========
     Deux portraits côte à côte, chacun sous un bandeau de couleur (Retake
     Formation, 04/08 : Yoru et Phoenix). Composant GÉNÉRIQUE : la feuille ne
     connaît ni les personnages ni leurs teintes, la PAGE pose le dégradé du
     .char-art et la couleur du .c-role en style local, exactement comme les
     pastilles .nx-art des cartes de suite. Aucune classe de personnage n'entre
     donc ici, et l'entrée suivante s'en servira sans y toucher.

     Le bandeau porte le VISUEL DE LA FICHE de l'agent, posé par la page et
     résolu en base (demande client) ; le dégradé reste le fond et redevient le
     seul décor quand aucune image n'est servie. La maquette y posait un emoji
     (🌀, 🔥), retiré comme tous les autres (doctrine du site), et le centrage
     qui l'accompagnait n'a plus d'objet. La hauteur passe de 96 à 125 px
     (+ 30 %) pour que le portrait ait de quoi se voir.

     Le paragraphe porte le CHEMIN COMPLET (.content .char-body p) : à égalité
     de poids avec .content p, il perdrait sa taille et son interligne. La
     maquette compensait par trois !important, retirés comme ailleurs ici. */

  .lore-entree-page .chars {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin: 22px 0 0;
  }
  .lore-entree-page .char {
    border-radius: 16px;
    overflow: hidden;
    border: 1px solid #ececec;
    background: var(--white);
    transition: all 0.26s;
  }
  .lore-entree-page .char:hover {
    transform: translateY(-4px);
    box-shadow: 0 14px 34px rgba(0,0,0,0.07);
  }
  .lore-entree-page .char-art { height: 125px; }
  /* Le visuel couvre tout le bandeau sans jamais se déformer : il déborde et se
     recadre, le dégradé de la page ne se voyant plus que s'il n'y a pas
     d'image. Générique comme le reste du composant : la feuille ne connaît
     aucun agent. */
  .lore-entree-page .char-art img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Cadrage vers le haut : les portraits de fiche sont en pied, un cover
       centré sur une bande de 125 px montrait les bustes sans les visages
       (validé superviseur sur aperçus, 04/08). */
    object-position: top;
  }
  .lore-entree-page .char-body { padding: 18px 21px 21px; }
  .lore-entree-page .char-body .c-role {
    font-size: 0.63rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.7px;
    margin-bottom: 5px;
  }
  .lore-entree-page .char-body h3 {
    margin: 0 0 9px;
    font-size: 1.05rem;
    color: var(--dark);
  }
  .lore-entree-page .content .char-body p {
    margin: 0;
    font-size: 0.87rem;
    line-height: 1.78;
  }
  .lore-entree-page .content .char-body p + p { margin-top: 10px; }

  /* ========== CITATION EN BANDEAU ==========
     Le bandeau sombre qui isole une réplique de la cinématique (« Alma por un
     alma » dans Shattered). Son halo appartient au COMPOSANT et non à l'accent
     de l'entrée : il ne suit pas --entry, et une citation se présente de la
     même façon d'une page à l'autre.

     Il reste néanmoins RÉGLABLE par la page, depuis Retake Formation (04/08),
     qui teinte le sien à l'orangé de Phoenix : --quote-glow, posé en jeton
     local comme les trois jetons d'accent. Le REPLI est le rouge d'origine, si
     bien qu'une page qui ne dit rien garde exactement l'apparence de Shattered.

     Le paragraphe porte le CHEMIN COMPLET (.content .quote-line p) : à égalité
     de poids avec .content p, il perdrait sa taille et sa couleur claire. La
     maquette compensait par quatre !important, retirés comme ceux du chapô
     (même piège, même remède). */

  .lore-entree-page .quote-line {
    position: relative;
    margin: 22px 0;
    padding: 20px 26px;
    border-radius: 14px;
    background: #0b0714;
    overflow: hidden;
  }
  .lore-entree-page .quote-line::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse at 82% 50%, var(--quote-glow, rgba(180,60,90,0.3)) 0%, transparent 62%);
    pointer-events: none;
  }
  .lore-entree-page .content .quote-line p {
    position: relative;
    z-index: 2;
    margin: 0;
    font-family: 'Bebas Neue', sans-serif;
    font-size: 1.5rem;
    letter-spacing: 2px;
    color: rgba(255,255,255,0.9);
    line-height: 1.2;
  }
  .lore-entree-page .quote-line span {
    position: relative;
    z-index: 2;
    display: block;
    margin-top: 8px;
    font-size: 0.72rem;
    color: rgba(255,255,255,0.38);
  }

  /* ========== NOTE DE FIN ==========
     L'encadré italique qui ferme le texte d'une entrée (Retake Formation,
     04/08) : un aparté, typiquement un renvoi de lecture, distinct du fil du
     récit. Composant du gabarit, il sert donc les entrées suivantes. */

  .lore-entree-page .endnote {
    margin-top: 26px;
    padding: 16px 20px;
    background: var(--bg);
    border: 1px solid #ececec;
    border-radius: 12px;
    font-size: 0.84rem;
    color: var(--text-light);
    line-height: 1.72;
    font-style: italic;
  }

  /* ========== INFORMATIONS CLÉS ==========
     La maquette posait un pictogramme emoji devant chaque bloc. Ils sont
     retirés (doctrine du site) : le bloc devient un simple encadré, l'intitulé
     en gras portant déjà le sens. */

  .lore-entree-page .keys {
    display: grid;
    gap: 12px;
    margin-top: 20px;
  }
  .lore-entree-page .key {
    padding: 17px 20px;
    background: var(--white);
    border: 1px solid #ececec;
    border-radius: 13px;
    border-left: 3px solid var(--entry);
    transition: all 0.22s;
  }
  .lore-entree-page .key:hover {
    transform: translateX(3px);
    box-shadow: 0 8px 22px rgba(0,0,0,0.04);
  }
  .lore-entree-page .key strong {
    display: block;
    font-size: 0.88rem;
    color: var(--dark);
    margin-bottom: 4px;
  }
  .lore-entree-page .key span {
    display: block;
    font-size: 0.85rem;
    color: var(--text-light);
    line-height: 1.72;
  }

  /* ========== QUESTIONS ET SPÉCULATIONS ==========
     Encadré en pointillé, à la couleur de la rubrique Lore et non à celle de
     l'entrée : c'est le même encadré d'une page à l'autre, il dit « ici, on
     interprète ». */

  .lore-entree-page .interp {
    margin: 30px 0 0;
    border: 1px dashed #d8d2ea;
    border-radius: 16px;
    background: #fbfaff;
    overflow: hidden;
  }
  .lore-entree-page .interp-head {
    padding: 17px 22px 14px;
    border-bottom: 1px dashed #e4dff2;
    display: flex;
    align-items: center;
    gap: 11px;
  }
  .lore-entree-page .interp-head h2 {
    margin: 0;
    font-size: 1.15rem;
  }
  .lore-entree-page .interp-head .ih-note {
    font-size: 0.66rem;
    color: var(--lore-dark);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    margin-left: auto;
  }
  .lore-entree-page .interp-body { padding: 18px 22px 22px; }
  .lore-entree-page .q {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 15px 18px;
    background: var(--white);
    border: 1px solid #ececec;
    border-radius: 12px;
    margin-bottom: 11px;
    font-size: 0.9rem;
    color: var(--dark);
    font-weight: 600;
    line-height: 1.6;
  }
  .lore-entree-page .q:last-child { margin-bottom: 0; }
  .lore-entree-page .q::before {
    content: '?';
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    border-radius: 7px;
    background: var(--lore-light);
    color: var(--lore-dark);
    font-size: 0.82rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  /* LES HYPOTHÈSES TITRÉES, l'autre forme que prend l'encadré : là où Duality
     alignait des questions courtes (.q), Shattered et Duelists déroulent des
     hypothèses titrées (.hyp).

     STYLE OFFICIEL DU DESIGNER, posé le 04/08 par la maquette de First Light.
     La maquette de Shattered ne stylait PAS DU TOUT ces blocs (ils retombaient
     sur les réglages du navigateur) et l'anatomie des scènes leur avait été
     prêtée à titre provisoire ; celle de First Light livre enfin la vraie :
     une carte blanche à puce ronde, distincte des scènes. Elle REMPLACE la
     provisoire, et les deux entrées déjà en ligne l'adoptent, c'est voulu.

     Deux écarts d'écriture avec la maquette, les mêmes que partout ici :
     ses trois !important sur le paragraphe sont retirés au profit du CHEMIN
     COMPLET (.content .hyp p bat .content p, qui pèse moins), et l'intitulé
     redéclare sa graisse et sa couleur, que la maquette tenait d'un .content h3
     global dont la feuille partagée n'a pas l'équivalent. */
  .lore-entree-page .hyp {
    padding: 17px 19px;
    background: var(--white);
    border: 1px solid #ececec;
    border-radius: 12px;
    margin-bottom: 12px;
  }
  .lore-entree-page .hyp:last-child { margin-bottom: 0; }
  .lore-entree-page .hyp h3 {
    margin: 0 0 6px;
    font-size: 0.91rem;
    font-weight: 700;
    color: var(--dark);
    display: flex;
    align-items: center;
    gap: 9px;
  }
  .lore-entree-page .hyp h3::before {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--lore);
    flex-shrink: 0;
  }
  .lore-entree-page .content .hyp p {
    margin: 0;
    font-size: 0.86rem;
    line-height: 1.8;
  }

  /* ========== COLONNE LATÉRALE ========== */

  .lore-entree-page .aside {
    position: sticky;
    top: calc(var(--hdr-h) + 22px);
    display: grid;
    gap: 18px;
  }
  .lore-entree-page .box {
    background: var(--white);
    border: 1px solid #ececec;
    border-radius: 16px;
    overflow: hidden;
  }
  .lore-entree-page .box-head {
    padding: 15px 19px 12px;
    border-bottom: 1px solid #f2f2f2;
    font-family: 'Bebas Neue', sans-serif;
    font-size: 0.76rem;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--text-light);
  }
  .lore-entree-page .facts { padding: 6px 0; }
  .lore-entree-page .fact {
    display: grid;
    gap: 3px;
    padding: 11px 19px;
    border-bottom: 1px solid #f7f7f7;
  }
  .lore-entree-page .fact:last-child { border-bottom: none; }
  .lore-entree-page .fact dt {
    font-size: 0.64rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: #bbb;
  }
  .lore-entree-page .fact dd {
    margin: 0;
    font-size: 0.85rem;
    color: var(--dark);
    font-weight: 600;
    line-height: 1.5;
  }
  .lore-entree-page .fact dd a {
    color: var(--lore-dark);
    text-decoration: none;
    border-bottom: 1px solid rgba(124,92,191,0.3);
  }

  /* LES ENTRÉES LIÉES, l'autre encadré de la colonne (First Light, 04/08) :
     une liste de renvois vers les entrées voisines de la section, chacune
     portée par une PASTILLE DE COULEUR qui dit sa famille. La pastille est
     posée en style local par la page, comme les dégradés des cartes de suite.

     Une entrée est un LIEN quand sa page existe et un BLOC quand elle manque,
     jamais un lien mort : le survol est donc réservé aux entrées qui portent
     réellement une adresse, exactement comme les cartes de « Suivre le récit »
     et les puces du casting. */
  .lore-entree-page .links { padding: 8px 0; }
  .lore-entree-page .lk {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 19px;
    text-decoration: none;
    color: inherit;
    transition: background 0.18s;
  }
  .lore-entree-page a.lk:hover { background: var(--bg); }
  .lore-entree-page .lk .lk-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
  }
  .lore-entree-page .lk strong {
    display: block;
    font-size: 0.83rem;
    color: var(--dark);
  }
  .lore-entree-page .lk span {
    font-size: 0.68rem;
    color: #bbb;
  }

  /* LE CASTING. Une puce est un LIEN quand la fiche existe et un SPAN quand
     elle manque : le survol et le curseur sont donc réservés aux liens, comme
     les cartes de lieux du hub. Les doubles de la Terre Omega n'ont pas de
     fiche par nature : ils gardent le contour en pointillé de la maquette. */
  .lore-entree-page .cast {
    padding: 12px 19px 16px;
    display: flex;
    gap: 7px;
    flex-wrap: wrap;
  }
  .lore-entree-page .cast a,
  .lore-entree-page .cast span {
    display: inline-block;
    padding: 6px 12px;
    border-radius: 7px;
    background: var(--bg);
    border: 1px solid #ececec;
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--dark);
    text-decoration: none;
    transition: all 0.18s;
  }
  .lore-entree-page .cast a:hover {
    background: var(--white);
    border-color: var(--entry);
    color: var(--entry);
  }
  .lore-entree-page .cast .clone {
    border-style: dashed;
    color: var(--text-light);
  }

  .lore-entree-page .back {
    display: block;
    padding: 16px 19px;
    background: #0b0714;
    color: white;
    text-decoration: none;
    border-radius: 16px;
    transition: all 0.2s;
  }
  .lore-entree-page .back:hover {
    background: var(--lore-dark);
    transform: translateY(-2px);
  }
  .lore-entree-page .back strong {
    display: block;
    font-size: 0.82rem;
    margin-bottom: 3px;
  }
  .lore-entree-page .back span {
    font-size: 0.68rem;
    opacity: 0.5;
  }

  /* ========== SUIVRE LE RÉCIT ==========
     Les entrées voisines. Tant que leur page n'existe pas, ce sont des BLOCS
     et non des liens (doctrine du site) : le survol est donc réservé aux
     cartes qui portent réellement une adresse, et le jour où une entrée sort,
     sa carte redevient un lien sans qu'une règle change ici. */

  .lore-entree-page .next {
    max-width: 1200px;
    margin: 0 auto;
    padding: 10px 40px 60px;
  }
  .lore-entree-page .next-inner { max-width: 780px; }
  .lore-entree-page .next h2 {
    font-family: 'Bebas Neue', sans-serif;
    font-size: 1.3rem;
    color: var(--dark);
    letter-spacing: 1px;
    margin-bottom: 16px;
  }
  /* DEUX GRILLES, MÊME PAVAGE, DEUX ANATOMIES DE CARTE : .chrono sert les
     entrées qui situent leurs voisines dans le récit (chaque .nx y porte son
     étiquette de direction .nx-way, « Précédemment », « Ensuite »), .next-grid
     celles qui se contentent de renvoyer vers d'autres pages (First Light,
     04/08 : le .nx y est sans .nx-way). Les déclarations sont communes, les
     deux noms restent distincts pour que le balisage dise lequel des deux
     blocs il rend. */
  .lore-entree-page .chrono,
  .lore-entree-page .next-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 13px;
  }
  .lore-entree-page .nx {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 18px;
    background: var(--white);
    border: 1px solid #ececec;
    border-radius: 14px;
    text-decoration: none;
    color: inherit;
    transition: all 0.24s;
  }
  .lore-entree-page a.nx:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 28px rgba(0,0,0,0.06);
    border-color: transparent;
  }
  .lore-entree-page .nx .nx-art {
    width: 42px;
    height: 42px;
    border-radius: 11px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    color: rgba(255,255,255,0.82);
  }
  .lore-entree-page .nx .nx-way {
    display: block;
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: #bbb;
    margin-bottom: 2px;
  }
  .lore-entree-page .nx strong {
    display: block;
    font-size: 0.86rem;
    color: var(--dark);
    margin-bottom: 2px;
  }
  .lore-entree-page .nx span.d {
    font-size: 0.7rem;
    color: var(--text-light);
  }

  /* ========== ENCADRÉ DE REMARQUE ==========
     L'encadré à liseré latéral qui pose un aparté au fil du texte (les Radiants,
     04/08 : la composante héréditaire). C'est LE MÊME COMPOSANT QUE CELUI DU HUB
     (.note / .n-t de lore.css), repris ici en version gabarit d'entrée : la
     feuille du hub est scopée .lore-page, elle ne peut pas servir une sous-page.

     Il prend la couleur de la RUBRIQUE LORE et non celle de l'entrée, comme
     l'encadré des spéculations : c'est le même aparté d'une page à l'autre.
     La maquette y posait un emoji, retiré comme tous les autres.

     Le paragraphe porte le CHEMIN COMPLET (.content .note p) : à égalité de
     poids avec .content p, il perdrait sa taille et sa couleur. */

  .lore-entree-page .note {
    margin: 24px 0 0;
    padding: 20px 24px;
    border-radius: 14px;
    border-left: 4px solid var(--lore);
    background: var(--lore-light);
  }
  .lore-entree-page .note .n-t {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--lore-dark);
    margin-bottom: 8px;
  }
  .lore-entree-page .content .note p {
    margin: 0;
    font-size: 0.88rem;
    color: #4a3a7a;
    line-height: 1.78;
  }

  /* ========== FILTRES D'UNE GRILLE ==========
     La barre de boutons qui trie la grille qui la suit (les Radiants, 04/08).
     Composant GÉNÉRIQUE : la feuille ne connaît aucune catégorie, chaque bouton
     porte la sienne en data-f et lore-entree.js bascule .hide sur les éléments
     data-t correspondants. Le bouton actif porte .on, posé côté serveur sur
     « Tous » : sans JavaScript, la barre reste lisible et la grille entière
     s'affiche. */

  .lore-entree-page .filt {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin: 20px 0 4px;
  }
  .lore-entree-page .filt button {
    padding: 9px 17px;
    border: 1px solid #ececec;
    border-radius: 9px;
    background: var(--white);
    /* Un <button> n'hérite pas de la police du body : même déclaration que la
       façade vidéo et les contrôles du catalogue. */
    font-family: 'DM Sans', sans-serif;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-light);
    cursor: pointer;
    transition: all 0.2s;
    display: inline-flex;
    align-items: center;
    gap: 8px;
  }
  .lore-entree-page .filt button:hover {
    border-color: #ddd;
    color: var(--text);
  }
  .lore-entree-page .filt button.on {
    background: var(--dark);
    border-color: var(--dark);
    color: white;
  }
  .lore-entree-page .filt button .n {
    font-family: 'Bebas Neue', sans-serif;
    font-size: 0.85rem;
    opacity: 0.55;
    letter-spacing: 0.5px;
  }

  /* ========== GRILLE D'AGENTS ==========
     Les cartes d'agents d'un dossier (les Radiants, 04/08) : un portrait, un
     nom, une origine et deux lignes de texte. Composant générique lui aussi, la
     feuille ne connaissant aucun agent : c'est la PAGE qui pose le dégradé de
     chaque .r-art en style local, sur le précédent des pastilles .nx-art.

     Une carte est un LIEN quand la fiche existe et un BLOC quand elle manque
     (fiche dépubliée au back-office) : le survol est donc réservé aux cartes qui
     portent réellement une adresse, comme les puces du casting.

     .hide est l'état que pose le filtre. Il n'est JAMAIS rendu côté serveur :
     sans JavaScript, la grille entière reste lisible.

     Les BADGES disent un STATUT et non une nouveauté : « Ajouté depuis » pour
     les Radiants confirmés après la rédaction d'origine, « Non-Radiant » pour
     ceux qui n'en sont pas, dont le portrait est grisé.

     Le paragraphe porte le CHEMIN COMPLET (.content .rad p), et l'image du
     portrait reprend le cadrage des cartes de personnages : couverture et
     alignement haut, les portraits de fiche étant en pied. */

  .lore-entree-page .rads {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    margin: 18px 0 0;
  }
  .lore-entree-page .rad {
    display: flex;
    align-items: flex-start;
    gap: 15px;
    padding: 18px 20px;
    background: var(--white);
    border: 1px solid #ececec;
    border-radius: 15px;
    text-decoration: none;
    color: inherit;
    transition: all 0.26s;
    position: relative;
  }
  .lore-entree-page a.rad:hover {
    transform: translateY(-4px);
    box-shadow: 0 14px 34px rgba(0,0,0,0.07);
    border-color: transparent;
  }
  /* LA CARTE EST UN LIEN DANS LE FIL DU TEXTE, et doit donc battre .content a,
     qui pèse plus qu'elle et lui poserait le violet de la rubrique, un
     soulignement et un fond lilas au survol. Le CHEMIN COMPLET suffit, comme
     pour le bouton du bandeau de passerelle : ce sont les deux seuls liens de la
     feuille qui vivent à l'intérieur de .content. */
  .lore-entree-page .content a.rad {
    color: inherit;
    border: 1px solid #ececec;
  }
  .lore-entree-page .content a.rad:hover {
    background: var(--white);
    border-color: transparent;
  }
  .lore-entree-page .rad.hide { display: none; }
  .lore-entree-page .rad .r-art {
    width: 46px;
    height: 46px;
    border-radius: 13px;
    flex-shrink: 0;
    overflow: hidden;
  }
  .lore-entree-page .rad .r-art img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top;
  }
  .lore-entree-page .rad h3 {
    margin: 0 0 3px;
    font-size: 0.98rem;
    font-weight: 700;
    color: var(--dark);
  }
  .lore-entree-page .rad .r-from {
    font-size: 0.63rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #bbb;
  }
  .lore-entree-page .content .rad p {
    margin: 6px 0 0;
    font-size: 0.83rem;
    line-height: 1.65;
  }
  .lore-entree-page .rad .r-badge {
    position: absolute;
    top: 14px;
    right: 15px;
    font-size: 0.52rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    padding: 3px 8px;
    border-radius: 5px;
  }
  .lore-entree-page .rad.new .r-badge {
    background: #fce4e9;
    color: #c23a58;
  }
  .lore-entree-page .rad.non .r-badge {
    background: #f1f1f4;
    color: #999;
  }
  .lore-entree-page .rad.non .r-art { filter: grayscale(0.55); }

  /* ========== LISTE D'ARTEFACTS ==========
     Une liste d'objets commentés (les Radiants, 04/08 : ce qui leur sert à
     canaliser leurs pouvoirs). La maquette posait une pastille à emoji devant
     chaque ligne : elle est RETIRÉE et la boîte vide avec, comme sur les
     informations clés de Duality. L'intitulé en gras porte déjà le sens, la
     ligne redevient un simple encadré. */

  .lore-entree-page .arts {
    display: grid;
    gap: 11px;
    margin: 20px 0 0;
  }
  .lore-entree-page .art-i {
    padding: 15px 19px;
    background: var(--white);
    border: 1px solid #ececec;
    border-radius: 13px;
  }
  .lore-entree-page .art-i strong {
    display: block;
    font-size: 0.87rem;
    color: var(--dark);
    margin-bottom: 3px;
  }
  .lore-entree-page .art-i span {
    display: block;
    font-size: 0.84rem;
    color: var(--text-light);
    line-height: 1.68;
  }

  /* ========== NOTE DE SOURCE ==========
     La ligne en italique qui dit d'où vient une liste et comment elle évolue
     (les Radiants, 04/08, sous la grille d'agents). Le sélecteur porte la balise
     (.content p.src) pour battre .content p, qui pèse autant. */

  .lore-entree-page .content p.src {
    margin: 14px 0 0;
    font-size: 0.73rem;
    color: #b4b4b4;
    font-style: italic;
    line-height: 1.6;
  }

  /* ========== BANDEAU DE PASSERELLE ==========
     Le bandeau sombre qui ferme un dossier en renvoyant vers une autre partie du
     site (les Radiants, 04/08 : le listing des fiches agents). Même anatomie que
     la citation en bandeau, et mêmes arbitrages :

     - le FOND SOMBRE appartient au composant, comme le #0b0714 de .quote-line :
       un bandeau se présente de la même façon d'une page à l'autre ;
     - le HALO suit l'accent de l'entrée (--entry-soft), là où la maquette
       figeait un rgba doré ;
     - le BOUTON prend l'accent de l'entrée (--entry), là où la maquette figeait
       le #e6b44d de cette page. Son survol s'obtient par un assombrissement
       relatif, et non par une seconde couleur en dur, pour que le composant
       reste servable par n'importe quel accent.

     Le paragraphe porte le CHEMIN COMPLET (.content .bridge p), comme partout
     ici : la maquette compensait par des !important, retirés à l'intégration. */

  .lore-entree-page .bridge {
    position: relative;
    margin-top: 30px;
    padding: 26px 28px;
    border-radius: 16px;
    background: linear-gradient(135deg, #1a1408, #4a3a12);
    overflow: hidden;
  }
  .lore-entree-page .bridge::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse at 80% 45%, var(--entry-soft) 0%, transparent 62%);
    pointer-events: none;
  }
  .lore-entree-page .bridge > * {
    position: relative;
    z-index: 2;
  }
  .lore-entree-page .bridge h3 {
    margin: 0 0 8px;
    font-family: 'Bebas Neue', sans-serif;
    font-size: 1.35rem;
    color: white;
    letter-spacing: 1.2px;
  }
  .lore-entree-page .content .bridge p {
    margin: 0 0 17px;
    color: rgba(255,255,255,0.52);
    font-size: 0.88rem;
    line-height: 1.75;
  }
  /* Le bouton est un lien du fil du texte : il doit battre .content a, qui lui
     poserait le violet de la rubrique et un soulignement. */
  .lore-entree-page .content .bridge a.go {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 13px 26px;
    border-radius: 10px;
    background: var(--entry);
    color: #2a1f06;
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-decoration: none;
    border-bottom: none;
    transition: all 0.2s;
  }
  .lore-entree-page .content .bridge a.go:hover {
    filter: brightness(0.92);
    background: var(--entry);
    transform: translateY(-2px);
  }

  /* ========== RESPONSIVE ========== */

  @media (max-width: 1024px) {
    .lore-entree-page .layout {
      grid-template-columns: 1fr;
      gap: 32px;
      padding: 30px 20px 20px;
    }
    .lore-entree-page .aside { position: static; }
    .lore-entree-page .content { max-width: 100%; }
    .lore-entree-page .next { padding: 0 20px 46px; }
    .lore-entree-page .next-inner { max-width: 100%; }
  }

  @media (max-width: 768px) {
    .lore-entree-page .eh-inner { padding: 14px 20px 36px; }
    .lore-entree-page .entry-hero h1 { font-size: 2.1rem; }
    .lore-entree-page .content h2 { font-size: 1.32rem; }
    .lore-entree-page .scenes { padding-left: 38px; }
    .lore-entree-page .scenes::before { left: 11px; }
    .lore-entree-page .scene::before {
      left: -38px;
      width: 27px;
      height: 27px;
      font-size: 0.8rem;
    }
    .lore-entree-page .chars { grid-template-columns: 1fr; }
    .lore-entree-page .content .quote-line p { font-size: 1.2rem; }
    .lore-entree-page .interp-head { flex-wrap: wrap; }
    .lore-entree-page .interp-head .ih-note {
      margin-left: 0;
      width: 100%;
    }
    .lore-entree-page .chrono,
    .lore-entree-page .next-grid { grid-template-columns: 1fr; }
    .lore-entree-page .rads { grid-template-columns: 1fr; }
  }
