/* ════════════════════════════════════════════════════════════════════
   LE JOURNAL DES CURIOSITÉS NUMÉRIQUES — Design system
   Thème : journal ancien (papier ivoire, encre, filets, blackletter)
   dans un écrin sombre (cohérent avec l'univers Ogmyos).
   ════════════════════════════════════════════════════════════════════ */

:root {
  /* Palette papier / encre */
  --paper:        #efe5cf;
  --paper-deep:   #e6d9bd;
  --paper-edge:   #d8c8a4;
  --ink:          #241d14;
  --ink-soft:     #4a4032;
  --ink-faint:    #7d7159;
  --rule:         #35291b;
  --accent:       #8a2f1f;          /* rouge sceau, usage parcimonieux */

  /* Écrin (la "table" sur laquelle repose le journal) */
  --room:         #16120e;
  --room-2:       #0e0b08;
  --chrome-fg:    #cdbfa4;
  --chrome-fg-dim:#8d816a;
  --chrome-line:  rgba(205, 191, 164, .16);

  /* Typographie */
  --f-black:  "UnifrakturCook", "Old English Text MT", serif;   /* masthead */
  --f-disp:   "Playfair Display", "Georgia", serif;              /* titres   */
  --f-body:   "EB Garamond", "Garamond", serif;                  /* corps    */
  --f-fell:   "IM Fell English", "Georgia", serif;               /* datelines, mentions */

  /* Feuille : dimensions logiques (le stage est mis à l'échelle en JS) */
  --sheet-w: 1140px;
  --sheet-h: 1560px;

  --ease-page: cubic-bezier(.22, .8, .28, 1);
}

/* ── Reset minimal ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  font-family: var(--f-body);
  background:
    radial-gradient(120% 90% at 50% 0%, var(--room) 0%, var(--room-2) 78%);
  color: var(--chrome-fg);
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  /* Ici plutôt que sur .jr-viewport seul : la barre d'outils, les rubriques,
     le lecteur et la modale d'abonnement sont des frères de .jr-viewport,
     pas des descendants — sans ça leurs boutons garderaient le flash de
     surbrillance au toucher.
     ⚠️ -webkit-touch-callout, lui, N'EST PAS posé ici : la propriété est
     héritée, et sur iOS elle supprime aussi l'appui long DANS le lecteur —
     plus de sélection de citation, plus d'ouverture de lien dans un nouvel
     onglet. Elle est donc portée par le seul .jr-viewport (le papier), là
     où l'appui long parasitait vraiment le déplacement. */
  -webkit-tap-highlight-color: transparent;
}
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}
.skip-to-content {
  position: fixed; top: -48px; left: 12px; z-index: 200;
  padding: 8px 14px; background: var(--paper); color: var(--ink);
  font-family: var(--f-fell); border-radius: 0 0 4px 4px;
  transition: top .2s;
}
.skip-to-content:focus { top: 0; }

/* ════════════════════════════════════════════════════════════════════
   BARRE D'OUTILS
   ════════════════════════════════════════════════════════════════════ */
.jr-toolbar {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  /* Les marges intègrent les zones sûres iOS (encoche, coins arrondis,
     barre latérale en paysage). Le moteur mesure ensuite cette barre au
     lieu de supposer sa hauteur, donc la feuille n'est jamais recouverte. */
  padding: calc(10px + env(safe-area-inset-top)) calc(16px + env(safe-area-inset-right))
           10px calc(16px + env(safe-area-inset-left));
  font-family: var(--f-fell); font-size: 13px; letter-spacing: .04em;
  background: linear-gradient(to bottom, rgba(14,11,8,.92), rgba(14,11,8,.55) 70%, transparent);
  pointer-events: none;              /* la barre laisse passer, ses enfants captent */
}
.jr-toolbar > * { pointer-events: auto; }

.jr-back {
  display: inline-flex; align-items: center; gap: 7px;
  color: var(--chrome-fg-dim); text-decoration: none;
  padding: 6px 10px; border: 1px solid transparent; border-radius: 3px;
  transition: color .2s, border-color .2s;
}
.jr-back:hover, .jr-back:focus-visible { color: var(--chrome-fg); border-color: var(--chrome-line); }

.jr-pagenav, .jr-tools, .jr-zoomgrp { display: inline-flex; align-items: center; gap: 6px; }
.jr-tools { gap: 14px; }

.jr-navbtn {
  display: inline-grid; place-items: center;
  min-width: 30px; height: 30px; padding: 0 8px;
  color: var(--chrome-fg-dim);
  border: 1px solid var(--chrome-line); border-radius: 3px;
  font-family: var(--f-fell); font-size: 14px; line-height: 1;
  transition: color .2s, border-color .2s, background .2s;
}
.jr-navbtn:hover:not(:disabled), .jr-navbtn:focus-visible {
  color: var(--paper); border-color: rgba(205,191,164,.45); background: rgba(205,191,164,.06);
}
.jr-navbtn:disabled { opacity: .35; cursor: default; }
.jr-zoomreset { font-size: 11.5px; letter-spacing: .03em; }

/* Bascule simple / double page (desktop) */
.jr-spread-btn[aria-pressed="true"] {
  color: var(--paper); border-color: rgba(205,191,164,.5);
  background: rgba(205,191,164,.1);
}
@media (max-width: 1023px) { .jr-spread-btn { display: none; } }

.jr-pageindic {
  min-width: 92px; text-align: center;
  color: var(--chrome-fg); font-variant: small-caps; letter-spacing: .12em;
}

.jr-subscribe-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 14px;
  color: var(--room-2); background: var(--chrome-fg);
  border-radius: 3px; letter-spacing: .06em; font-variant: small-caps;
  transition: background .2s, transform .2s;
}
.jr-subscribe-btn:hover, .jr-subscribe-btn:focus-visible { background: #e8dcc0; transform: translateY(-1px); }

/* ════════════════════════════════════════════════════════════════════
   RUBRIQUES (filtre discret sous la barre d'outils)
   ════════════════════════════════════════════════════════════════════ */
.jr-rubriques {
  position: fixed; left: 12px; top: 50%; transform: translateY(-50%);
  z-index: 55;
  display: flex; flex-direction: column; align-items: stretch; gap: 3px;
  width: 156px; max-height: 72vh;
  overflow-y: auto; scrollbar-width: none;
  padding: 2px 4px;
}
.jr-rubriques::-webkit-scrollbar { display: none; }
.jr-rub-head {
  font-family: var(--f-fell); font-variant: small-caps;
  font-size: 11px; letter-spacing: .24em;
  color: var(--chrome-fg-dim);
  padding: 0 11px 7px; margin-bottom: 4px;
  border-bottom: 1px solid var(--chrome-line);
}
.jr-rub {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 11px; white-space: nowrap;
  font-family: var(--f-fell); font-size: 12.5px;
  font-variant: small-caps; letter-spacing: .14em;
  color: var(--chrome-fg-dim); border-radius: 3px;
  border: 1px solid transparent;
  text-align: left;
  transition: color .25s, background .25s, border-color .25s;
}
.jr-rub:hover, .jr-rub:focus-visible { color: var(--chrome-fg); }
.jr-rub.is-active {
  color: var(--paper);
  background: rgba(205,191,164,.08);
  border-color: var(--chrome-line);
}
.jr-rub-dot {
  width: 5px; height: 5px; border-radius: 50%; flex: none;
  background: var(--chrome-fg-dim);
  filter: saturate(.8);
}

/* ════════════════════════════════════════════════════════════════════
   VIEWPORT + STAGE (pan / zoom)
   ════════════════════════════════════════════════════════════════════ */
.jr-viewport {
  position: fixed; inset: 0;
  overflow: hidden;
  cursor: grab;
  touch-action: none;                /* pinch/drag gérés en JS Pointer Events */
  /* Pas de sélection sur le papier : un drag de pan surlignerait le texte
     et casserait l'illusion. La sélection reste possible dans le lecteur. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;       /* portée limitée au papier, cf. body */
}
.jr-viewport.is-panning { cursor: grabbing; }

.jr-stage {
  position: absolute; top: 0; left: 0;
  width: var(--sheet-w); height: var(--sheet-h);
  transform-origin: 0 0;
  will-change: transform;
}

.jr-loading {
  position: absolute; inset: 0;
  display: grid; place-items: center; align-content: center; gap: 10px;
  color: var(--chrome-fg-dim); font-family: var(--f-fell);
  font-size: 15px; letter-spacing: .18em; text-transform: uppercase;
}
.jr-loading-orn { font-size: 22px; animation: jr-spin 2.4s linear infinite; }
.jr-loading-orn--still { animation: none; color: var(--accent); }
@keyframes jr-spin { to { transform: rotate(360deg); } }
/* Édition indisponible : message honnête plutôt qu'un chargement perpétuel */
.jr-loading-sub {
  max-width: 34ch; text-align: center;
  font-family: var(--f-fell); font-style: italic; font-size: 14px;
  letter-spacing: normal; text-transform: none; line-height: 1.5;
  color: var(--chrome-fg-dim);
}
.jr-retry { margin-top: 6px; padding: 8px 18px; font-variant: small-caps; letter-spacing: .12em; }

/* ════════════════════════════════════════════════════════════════════
   LA FEUILLE
   ════════════════════════════════════════════════════════════════════ */
.jr-sheet {
  position: absolute; top: 0; left: 0;   /* left posé en JS (vue double page) */
  width: var(--sheet-w); height: var(--sheet-h);
  padding: 44px 52px 58px;
  color: var(--ink);
  background:
    /* grain de papier (bruit SVG inline, aucun asset externe) */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.35 0 0 0 0 0.28 0 0 0 0 0.18 0 0 0 0.05 0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E"),
    /* taches d'âge + vignettage */
    radial-gradient(52% 40% at 82% 6%,  rgba(148,110,55,.14), transparent 60%),
    radial-gradient(40% 34% at 8% 88%,  rgba(148,110,55,.12), transparent 60%),
    radial-gradient(140% 120% at 50% 45%, var(--paper) 55%, var(--paper-deep) 82%, var(--paper-edge) 100%);
  box-shadow:
    0 2px 4px rgba(0,0,0,.5),
    0 24px 60px rgba(0,0,0,.55),
    inset 0 0 90px rgba(120, 90, 40, .12);
  display: flex; flex-direction: column;
  transform-origin: 50% 42%;
  opacity: 0; transition: opacity .45s var(--ease-page), transform .6s var(--ease-page);
}
.jr-sheet.is-visible { opacity: 1; transform: none; }
/* entrée "magique" après un filtrage : la feuille se pose sur la table */
.jr-sheet.is-settling { transform: scale(.984) rotate(-.35deg); }

/* ── Chorégraphie du filtrage par rubrique ──
   Sortie : les articles hors-sujet se dissolvent en s'envolant (cascade).
   Entrée : les articles retenus se matérialisent, légère rotation de
   coupure de presse. --d (délai) et --r (rotation) posés en JS. */
@keyframes jrArtOut {
  30% { opacity: .9; }
  to  { opacity: 0; transform: translateY(-22px) rotate(var(--r, 0deg)) scale(.94); filter: blur(5px) sepia(.4); }
}
/* le sélecteur long garantit que la dissolution prime toujours sur une
   matérialisation résiduelle (.anim-in.play, plus spécifique sinon) */
.jr-art.anim-out,
.jr-art.anim-in.play.anim-out {
  animation: jrArtOut .5s var(--ease-page) forwards;
  animation-delay: var(--d, 0s);
  pointer-events: none;
  /* Prévient le navigateur qu'un compositing layer dédié vaut le coût ici :
     évite de repeindre la feuille de papier entière à chaque frame de la
     cascade. Porté par la classe (présente seulement le temps de l'anim),
     donc jamais de layer promu en permanence sur des éléments statiques. */
  will-change: transform, opacity, filter;
}
.jr-art.anim-in { opacity: 0; }
@keyframes jrArtIn {
  from { opacity: 0; transform: translateY(26px) rotate(var(--r, 0deg)) scale(.96); filter: blur(6px) sepia(.5); }
  60%  { filter: blur(0) sepia(.15); }
  to   { opacity: 1; transform: none; filter: none; }
}
.jr-art.anim-in.play {
  animation: jrArtIn .7s var(--ease-page) forwards;
  animation-delay: var(--d, 0s);
  will-change: transform, opacity, filter;
}
/* fondu de l'en-tête quand le morphing change de page (manchette ↔ cartouche) */
@keyframes jrFade { from { opacity: 0; } to { opacity: 1; } }
.jr-headfade { animation: jrFade .55s var(--ease-page) both; animation-delay: .08s; }

/* filets utilitaires */
.jr-rule-double {
  border: 0; border-top: 1px solid var(--rule); border-bottom: 3px solid var(--rule);
  height: 6px; background: transparent;
}
.jr-rule-thin { border: 0; border-top: 1px solid var(--rule); }

/* ── Manchette (page 1) ── */
.jr-masthead { text-align: center; margin-bottom: 10px; }
.jr-masthead-topline {
  display: flex; justify-content: space-between; align-items: baseline;
  font-family: var(--f-fell); font-size: 13px; letter-spacing: .08em;
  color: var(--ink-soft); border-bottom: 1px solid var(--rule);
  padding-bottom: 5px; margin-bottom: 12px;
}
.jr-masthead-title {
  font-family: var(--f-black); font-weight: 700;
  font-size: 92px; line-height: .95; letter-spacing: .01em;
  margin: 2px 0 6px;
  text-shadow: 0 1px 0 rgba(255,255,255,.35);
}
.jr-masthead-sub {
  font-family: var(--f-fell); font-style: italic; font-size: 16px;
  color: var(--ink-soft); letter-spacing: .05em;
}
.jr-masthead-band {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 12px; padding: 6px 2px;
  border-top: 3px solid var(--rule); border-bottom: 1px solid var(--rule);
  font-family: var(--f-fell); font-size: 13.5px; letter-spacing: .1em;
  font-variant: small-caps; color: var(--ink-soft);
}

/* ── Cartouche de page intérieure ── */
.jr-innerhead {
  display: flex; justify-content: space-between; align-items: baseline;
  border-bottom: 3px double var(--rule);
  padding-bottom: 8px; margin-bottom: 18px;
  font-family: var(--f-fell); letter-spacing: .1em; color: var(--ink-soft);
}
.jr-innerhead .jr-ih-title { font-family: var(--f-black); font-size: 30px; color: var(--ink); letter-spacing: .02em; }
.jr-innerhead span { font-size: 13px; font-variant: small-caps; }

/* ── Grille de la page ── */
.jr-grid {
  flex: 1; min-height: 0;
  display: grid; gap: 22px;
  padding-top: 18px;
}
/* Une : article majeur + colonne droite + bande basse */
.jr-grid--front {
  grid-template-columns: 1.9fr 1fr;
  grid-template-rows: 1.35fr 1fr;
  grid-template-areas:
    "lead   side"
    "second third";
}
/* Intérieure A : deux colonnes hautes + pleine largeur basse */
.jr-grid--inner-a {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1.1fr 1fr;
  grid-template-areas:
    "lead   side"
    "second second";
}
/* Intérieure B : article majeur à droite */
.jr-grid--inner-b {
  grid-template-columns: 1fr 1.6fr;
  grid-template-rows: 1fr 1.1fr;
  grid-template-areas:
    "side   lead"
    "second third";
}
.slot-lead   { grid-area: lead; }
.slot-side   { grid-area: side; }
.slot-second { grid-area: second; }
.slot-third  { grid-area: third; }

/* ════════════════════════════════════════════════════════════════════
   ARTICLES (slots)
   ════════════════════════════════════════════════════════════════════ */
.jr-art {
  position: relative;
  display: flex; flex-direction: column;
  min-height: 0; overflow: hidden;
  cursor: pointer;
  outline-offset: 4px;
}
/* séparations verticales façon colonnes de presse */
.jr-grid--front .slot-side,
.jr-grid--front .slot-third,
.jr-grid--inner-a .slot-side,
.jr-grid--inner-b .slot-lead,
.jr-grid--inner-b .slot-third {
  border-left: 1px solid var(--rule);
  padding-left: 22px;
}
.jr-grid--front .slot-second,
.jr-grid--front .slot-third,
.jr-grid--inner-a .slot-second,
.jr-grid--inner-b .slot-second,
.jr-grid--inner-b .slot-third {
  border-top: 1px solid var(--rule);
  padding-top: 16px;
}

.jr-art-rubrique {
  font-family: var(--f-fell); font-size: 12.5px;
  font-variant: small-caps; letter-spacing: .22em;
  color: var(--accent);
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 7px;
}
.jr-art-rubrique::after { content: ""; flex: 1; border-top: 1px solid var(--rule); opacity: .4; }

.jr-art-title {
  font-family: var(--f-disp); font-weight: 800; line-height: 1.04;
  letter-spacing: -.01em; text-wrap: balance;
  margin-bottom: 9px;
}
.slot-lead   .jr-art-title { font-size: 46px; }
.slot-side   .jr-art-title { font-size: 25px; }
.slot-second .jr-art-title { font-size: 28px; }
.slot-third  .jr-art-title { font-size: 24px; }
/* Titres longs : le JS pose .is-long / .is-verylong.
   ⚠️ Ces tailles sont ABSOLUES par emplacement, et non relatives (.82em).
   En em, deux pièges se cumulaient : la règle relative, à spécificité égale
   avec `.slot-x .jr-art-title` mais écrite plus bas, l'emportait ; et son em
   se résolvait sur la taille HÉRITÉE du parent (16 px par défaut), pas sur
   celle de l'emplacement. Un titre long en colonne tombait donc à 13 px
   logiques au lieu de 20 — soit moins de 6 px à l'écran une fois la feuille
   mise à l'échelle (mesuré sur 1024×768). */
.slot-lead   .jr-art-title.is-long     { font-size: 38px; }
.slot-lead   .jr-art-title.is-verylong { font-size: 31px; }
.slot-side   .jr-art-title.is-long     { font-size: 21px; }
.slot-side   .jr-art-title.is-verylong { font-size: 18px; }
.slot-second .jr-art-title.is-long     { font-size: 23px; }
.slot-second .jr-art-title.is-verylong { font-size: 20px; }
.slot-third  .jr-art-title.is-long     { font-size: 20px; }
.slot-third  .jr-art-title.is-verylong { font-size: 17px; }

.jr-art-excerpt {
  font-family: var(--f-disp); font-style: italic; font-weight: 500;
  font-size: 16.5px; line-height: 1.35; color: var(--ink-soft);
  margin-bottom: 10px;
}
.slot-lead .jr-art-excerpt { font-size: 19px; }

.jr-art-meta {
  font-family: var(--f-fell); font-size: 12px; letter-spacing: .06em;
  color: var(--ink-faint); margin-bottom: 8px;
}

.jr-art-body {
  flex: 1; min-height: 0;
  position: relative; overflow: hidden;
  font-size: 15.5px; line-height: 1.42;
  text-align: justify; hyphens: auto;
  column-gap: 20px;
  column-rule: 1px solid rgba(53,41,27,.35);
}
.slot-lead .jr-art-body   { column-count: 3; font-size: 15.5px; }
.slot-second .jr-art-body { column-count: 3; }
.slot-third .jr-art-body  { column-count: 2; }
.slot-side .jr-art-body   { column-count: 1; }
.jr-art-body p { margin-bottom: .55em; }
/* lettrine sur l'article majeur */
.slot-lead .jr-art-body > p:first-child::first-letter {
  font-family: var(--f-disp); font-weight: 800;
  font-size: 3.05em; line-height: .8;
  float: left; padding: 4px 8px 0 0; color: var(--ink);
}
/* fondu bas de colonne : le texte "continue" dans la lecture zoomée */
.jr-art-body::after {
  content: "";
  position: absolute; inset: auto 0 0 0; height: 46px;
  background: linear-gradient(to bottom, transparent, var(--paper) 88%);
  pointer-events: none;
}

.jr-art-readmore {
  margin-top: 8px;
  font-family: var(--f-fell); font-size: 12.5px; font-style: italic;
  letter-spacing: .05em; color: var(--ink-faint);
  transition: color .2s;
}
.jr-art:hover .jr-art-readmore, .jr-art:focus-visible .jr-art-readmore { color: var(--accent); }
.jr-art:hover .jr-art-title { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }

/* ── Emplacements image ──
   Le cadre et sa légende forment un bloc solidaire (.jr-media) : quand une
   illustration ne peut pas être chargée, le moteur retire ce bloc entier,
   d'un seul geste, sans jamais laisser une légende orpheline ni un blanc.
   L'article se recompose alors autour — le corps de texte dispose d'une
   réserve prévue pour ça (voir BODY_CHARS côté moteur). */
.jr-media { flex: 0 0 auto; margin-bottom: 12px; }

.jr-figure {
  position: relative;
  border: 1px solid var(--rule);
  box-shadow: inset 0 0 0 3px var(--paper), inset 0 0 0 4px var(--rule);
  background:
    repeating-linear-gradient(45deg, rgba(53,41,27,.07) 0 2px, transparent 2px 9px),
    var(--paper-deep);
  display: grid; place-items: center;
}
.jr-figure-inner {
  text-align: center; padding: 10px;
  font-family: var(--f-fell); font-size: 12px; font-style: italic;
  letter-spacing: .08em; color: var(--ink-faint);
}
.jr-figure-inner b { display: block; font-size: 20px; margin-bottom: 4px; font-style: normal; }
.jr-figure--landscape { aspect-ratio: 16 / 9; width: 100%; }
.jr-figure--portrait  { aspect-ratio: 3 / 4;  width: 100%; }
.jr-figure--square    { aspect-ratio: 1;      width: 62%;  margin-inline: auto; }

/* Média réel (image, WebP animé, SVG animé, vidéo muette en boucle) :
   cadre gravure conservé, le média remplit l'intérieur du double filet.
   Il n'apparaît qu'une fois réellement décodé : tant qu'il charge, c'est la
   trame de gravure du cadre qu'on voit, jamais un rectangle noir. */
.jr-figure--media { position: relative; }
.jr-figure--media img,
.jr-figure--media video {
  position: absolute; inset: 7px;
  width: calc(100% - 14px); height: calc(100% - 14px);
  object-fit: cover; display: block;
  filter: sepia(.10) contrast(.98);   /* patine légère : intégration au papier */
  opacity: 0; transition: opacity .45s var(--ease-page);
}
.jr-media.is-loaded .jr-figure--media img,
.jr-media.is-loaded .jr-figure--media video { opacity: 1; }
/* portrait en colonne étroite : hauteur bornée, sinon la figure mange le slot */
.slot-side .jr-figure--portrait { max-height: 300px; aspect-ratio: auto; height: 300px; }

/* média dans le lecteur */
.jr-reader-media { margin-bottom: 24px; }
.jr-reader-media .jr-media { margin-bottom: 0; }
.jr-figure-caption {
  font-family: var(--f-fell); font-size: 12px; font-style: italic;
  color: var(--ink-faint); text-align: center; margin: 6px 0 0;
}

/* ── Encart abonnement imprimé dans la une ── */
.jr-annonce {
  margin-top: auto;
  border: 3px double var(--rule); padding: 12px 16px;
  text-align: center; font-family: var(--f-fell);
}
.jr-annonce b { font-variant: small-caps; letter-spacing: .14em; font-size: 15px; display: block; margin-bottom: 3px; }
.jr-annonce span { font-style: italic; font-size: 13.5px; color: var(--ink-soft); }

/* ── Pied de feuille ── */
.jr-sheet-foot {
  margin-top: 20px; padding-top: 8px;
  border-top: 3px double var(--rule);
  display: flex; justify-content: space-between;
  font-family: var(--f-fell); font-size: 12.5px;
  font-variant: small-caps; letter-spacing: .14em; color: var(--ink-faint);
}

/* ════════════════════════════════════════════════════════════════════
   LECTEUR (article déplié)
   ════════════════════════════════════════════════════════════════════ */
.jr-reader-backdrop {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(10, 8, 5, .62);
  backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none;
  transition: opacity .35s var(--ease-page);
}
.jr-reader-backdrop.is-open { opacity: 1; pointer-events: auto; }

.jr-reader {
  position: fixed; z-index: 90;
  inset: 4vh max(4vw, calc(50vw - 430px));
  color: var(--ink);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.35 0 0 0 0 0.28 0 0 0 0 0.18 0 0 0 0.05 0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(130% 110% at 50% 40%, var(--paper) 60%, var(--paper-deep) 100%);
  box-shadow: 0 30px 90px rgba(0,0,0,.65), inset 0 0 70px rgba(120,90,40,.10);
  opacity: 0; transform: scale(.92); transform-origin: center;
  pointer-events: none;
  transition: opacity .38s var(--ease-page), transform .38s var(--ease-page);
}
.jr-reader.is-open { opacity: 1; transform: scale(1); pointer-events: auto; }

.jr-reader-close, .jr-modal .jr-reader-close {
  position: absolute; top: 14px; right: 14px; z-index: 2;
  /* 44px : cible tactile minimale recommandée sur iOS comme sur Android.
     38px passait sous le seuil et se ratait au pouce. */
  width: 44px; height: 44px; display: grid; place-items: center;
  color: var(--ink-soft); border: 1px solid var(--rule); border-radius: 50%;
  background: var(--paper);
  transition: color .2s, transform .2s;
}
.jr-reader-close:hover, .jr-reader-close:focus-visible { color: var(--accent); transform: rotate(90deg); }

.jr-reader-scroll { position: absolute; inset: 0; overflow-y: auto; padding: 52px clamp(26px, 6vw, 76px) 46px; scrollbar-width: thin; }

.jr-reader-head { text-align: center; margin-bottom: 26px; }
.jr-reader-rubrique {
  font-family: var(--f-fell); font-variant: small-caps;
  letter-spacing: .3em; font-size: 14px; color: var(--accent); margin-bottom: 12px;
}
.jr-reader-title {
  font-family: var(--f-disp); font-weight: 800; line-height: 1.05;
  font-size: clamp(30px, 4.6vw, 46px); letter-spacing: -.01em;
  text-wrap: balance; margin-bottom: 14px;
}
.jr-reader-meta { font-family: var(--f-fell); font-style: italic; font-size: 14px; color: var(--ink-faint); margin-bottom: 16px; }

.jr-reader-body {
  font-size: 18px; line-height: 1.58; text-align: justify; hyphens: auto;
}
.jr-reader-body > p:first-of-type::first-letter {
  font-family: var(--f-disp); font-weight: 800;
  font-size: 3.2em; line-height: .78; float: left;
  padding: 6px 10px 0 0; color: var(--ink);
}
.jr-reader-body p { margin-bottom: 1em; }
.jr-reader-body h2, .jr-reader-body h3 {
  font-family: var(--f-disp); font-weight: 700; line-height: 1.15;
  margin: 1.5em 0 .55em; text-align: left;
}
.jr-reader-body h2 { font-size: 26px; }
.jr-reader-body h3 { font-size: 21px; }
.jr-reader-body h2::after { content: ""; display: block; width: 64px; border-top: 2px solid var(--rule); margin-top: 8px; }
.jr-reader-body ul, .jr-reader-body ol { margin: 0 0 1em 1.3em; }
.jr-reader-body li { margin-bottom: .35em; }
.jr-reader-body a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
.jr-reader-body blockquote {
  margin: 1.4em 0; padding: .2em 0 .2em 1.2em;
  border-left: 3px solid var(--accent);
  font-family: var(--f-disp); font-style: italic; font-size: 1.06em; color: var(--ink-soft);
}
.jr-reader-body img { max-width: 100%; height: auto; border: 1px solid var(--rule); }
.jr-reader-body code {
  font-family: ui-monospace, monospace; font-size: .85em;
  background: rgba(53,41,27,.09); padding: .1em .35em; border-radius: 2px;
}
.jr-reader-body pre { overflow-x: auto; background: rgba(53,41,27,.08); padding: 14px; margin-bottom: 1em; border: 1px solid rgba(53,41,27,.25); }
.jr-reader-body pre code { background: none; padding: 0; }

.jr-reader-foot { margin-top: 34px; }
.jr-reader-colophon {
  text-align: center; font-family: var(--f-fell); font-style: italic;
  font-size: 13.5px; color: var(--ink-faint); margin-top: 12px;
}

/* ════════════════════════════════════════════════════════════════════
   HINT + MODALE ABONNEMENT
   ════════════════════════════════════════════════════════════════════ */
.jr-hint {
  position: fixed; left: 50%; bottom: 18px; transform: translate(-50%, 6px);
  z-index: 70; display: flex; align-items: center; gap: 12px;
  padding: 9px 10px 9px 16px;
  font-family: var(--f-fell); font-size: 13px; font-style: italic; letter-spacing: .04em;
  color: var(--chrome-fg); background: rgba(22, 18, 14, .88);
  border: 1px solid var(--chrome-line); border-radius: 4px;
  opacity: 0; pointer-events: none;
  transition: opacity .4s, transform .4s;
}
.jr-hint.is-visible { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.jr-hint-close { color: var(--chrome-fg-dim); padding: 4px 6px; }
.jr-hint-close:hover { color: var(--paper); }

.jr-modal-backdrop {
  position: fixed; inset: 0; z-index: 95;
  background: rgba(10, 8, 5, .62); backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none; transition: opacity .3s;
}
.jr-modal-backdrop.is-open { opacity: 1; pointer-events: auto; }
.jr-modal {
  position: fixed; z-index: 96; left: 50%; top: 50%;
  width: min(480px, calc(100vw - 32px));
  transform: translate(-50%, -50%) scale(.94);
  padding: 44px 40px 36px; text-align: center; color: var(--ink);
  background: radial-gradient(120% 100% at 50% 30%, var(--paper) 60%, var(--paper-deep) 100%);
  box-shadow: 0 30px 80px rgba(0,0,0,.6);
  border: 3px double var(--rule);
  opacity: 0; pointer-events: none;
  transition: opacity .3s var(--ease-page), transform .3s var(--ease-page);
}
.jr-modal.is-open { opacity: 1; transform: translate(-50%, -50%) scale(1); pointer-events: auto; }
.jr-modal-orn { font-size: 26px; color: var(--accent); margin-bottom: 8px; }
.jr-modal-title { font-family: var(--f-disp); font-weight: 800; font-size: 27px; line-height: 1.1; margin-bottom: 12px; }
.jr-modal-text { font-size: 16px; line-height: 1.5; color: var(--ink-soft); margin-bottom: 20px; }
.jr-sub-form { display: flex; gap: 8px; }
.jr-sub-form input {
  flex: 1; min-width: 0; padding: 11px 14px;
  font-family: var(--f-body); font-size: 16px; color: var(--ink);
  background: rgba(255,255,255,.5); border: 1px solid var(--rule); border-radius: 2px;
}
.jr-sub-form input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.jr-sub-submit {
  padding: 11px 18px; background: var(--ink); color: var(--paper);
  font-family: var(--f-fell); font-variant: small-caps; letter-spacing: .1em;
  border-radius: 2px; transition: background .2s;
}
.jr-sub-submit:hover, .jr-sub-submit:focus-visible { background: var(--accent); }
.jr-modal-note { min-height: 1.4em; margin-top: 12px; font-family: var(--f-fell); font-style: italic; font-size: 13.5px; color: var(--accent); }

/* ════════════════════════════════════════════════════════════════════
   RESPONSIVE — le chrome s'adapte ; la feuille, elle, est mise à
   l'échelle par le moteur (fit-to-viewport), donc conserve son dessin.
   ════════════════════════════════════════════════════════════════════ */
/* Chrome des deux formats téléphone : écran étroit OU écran court.
   La seconde condition couvre l'appareil couché, qui a de la largeur mais
   pas de hauteur — il a exactement les mêmes besoins tactiles et les mêmes
   zones sûres, sans pour autant vouloir le bandeau bas des rubriques
   (traité plus loin, dans une requête réservée au portrait). */
@media (max-width: 720px),
       (max-height: 520px) and (max-width: 1024px),
       (max-width: 900px) and (orientation: portrait) {
  .jr-toolbar {
    flex-wrap: wrap;
    padding: calc(8px + env(safe-area-inset-top)) calc(10px + env(safe-area-inset-right))
             8px calc(10px + env(safe-area-inset-left));
  }
  .jr-back span { display: none; }
  .jr-back { padding: 8px 10px; }             /* cible tactile confortable */
  .jr-pageindic { min-width: 68px; font-size: 12px; }
  .jr-zoomgrp { display: none; }              /* pinch natif au doigt */
  .jr-subscribe-btn { padding: 8px 12px; font-size: 12.5px; }

  .jr-reader { inset: 0; }
  .jr-reader-close {
    top: calc(10px + env(safe-area-inset-top));
    right: calc(10px + env(safe-area-inset-right));
  }
  .jr-reader-scroll {
    padding: calc(64px + env(safe-area-inset-top)) calc(20px + env(safe-area-inset-right))
             calc(40px + env(safe-area-inset-bottom)) calc(20px + env(safe-area-inset-left));
  }
  .jr-reader-body { font-size: 16.5px; text-align: left; }

  .jr-hint {
    left: 12px; right: 12px; transform: translateY(6px);
    justify-content: space-between;
    bottom: calc(58px + env(safe-area-inset-bottom));
  }
  .jr-hint.is-visible { transform: translateY(0); }

  .jr-rub { padding: 7px 12px; }

  /* Allègement GPU : le flou d'arrière-plan est recalculé plein écran à
     chaque frame d'ouverture. Sur un Android d'entrée de gamme il coûte
     plus cher que tout le reste de l'animation réunie ; un voile plus dense
     produit la même séparation visuelle pour rien. */
  .jr-reader-backdrop, .jr-modal-backdrop {
    backdrop-filter: none; -webkit-backdrop-filter: none;
    background: rgba(10, 8, 5, .82);
  }
  /* Même logique pour la chorégraphie de filtrage : le flou animé par
     article est le poste le plus lourd. Le mouvement et le fondu suffisent
     à raconter la même chose. */
  @keyframes jrArtOut { to { opacity: 0; transform: translateY(-18px) scale(.95); } }
  @keyframes jrArtIn  { from { opacity: 0; transform: translateY(20px) scale(.97); } to { opacity: 1; transform: none; } }
}

/* Rubriques : en PORTRAIT seulement, le rail latéral devient un bandeau bas
   défilable. Couché, le rail reste à gauche — il y consomme de la largeur,
   dont on dispose, au lieu de la hauteur, qui est la ressource rare.
   left/right plutôt que width:100vw : 100vw ignore la barre de défilement
   et débordait horizontalement sur certains Android.

   ⚠️ Cette condition doit rester le calque exact de MOBILE_MQ dans
   journal.js (au « min-height » près, qui écarte le cas couché déjà pris
   par LANDSCAPE_MQ). Le moteur mesure ce bandeau pour cadrer la feuille :
   s'ils divergeaient, il mesurerait la mauvaise dimension. */
@media (max-width: 720px) and (min-height: 521px),
       (max-width: 900px) and (orientation: portrait) and (min-height: 521px) {
  .jr-rubriques {
    top: auto; bottom: 0; left: 0; right: 0; transform: none;
    flex-direction: row; align-items: center; gap: 2px;
    width: auto; max-width: none; max-height: none;
    overflow-x: auto; overflow-y: hidden;
    overscroll-behavior-x: contain;           /* pas de navigation arrière par rebond */
    padding: 8px 12px calc(10px + env(safe-area-inset-bottom));
    background: linear-gradient(to top, rgba(14,11,8,.94) 60%, transparent);
  }
  .jr-rub-head { display: none; }
}

/* Couché : le rail garde sa forme verticale mais se resserre, la hauteur
   utile étant très courte. */
@media (max-height: 520px) and (max-width: 1024px) {
  .jr-rubriques { width: 132px; max-height: 62vh; left: calc(8px + env(safe-area-inset-left)); }
  .jr-rub { padding: 4px 9px; font-size: 11.5px; }
  .jr-rub-head { padding-bottom: 5px; margin-bottom: 3px; }
}

/* ════════════════════════════════════════════════════════════════════
   FORMAT MOBILE DE LA FEUILLE

   La feuille bureau (1140×1560) réduite à un écran de téléphone tombait à
   28 % : 4 px de corps de texte, 7 px de titre de colonne — un journal
   qu'on ne pouvait plus lire, même pour choisir un article.
   Le format mobile est plus étroit, proche du ratio d'un téléphone, et ne
   porte que deux articles par page. Il est donc mis à l'échelle autour de
   45 %, et la typographie logique est redimensionnée en conséquence : les
   titres retrouvent une trentaine de pixels réels à l'écran.
   Les valeurs sont posées en « logique » (repère de la feuille) ; l'échelle
   effective est appliquée par le moteur.
   ════════════════════════════════════════════════════════════════════ */
[data-compact] .jr-sheet { padding: 30px 34px 34px; }

/* Manchette */
[data-compact] .jr-masthead-title { font-size: 50px; line-height: .98; }
[data-compact] .jr-masthead-sub { font-size: 19px; }
[data-compact] .jr-masthead-topline { font-size: 14px; letter-spacing: .02em; padding-bottom: 4px; margin-bottom: 9px; }
[data-compact] .jr-masthead-band { font-size: 14px; letter-spacing: .04em; }
/* La ligne de bandeau tient mal sur une feuille étroite : on garde
   l'essentiel, la mention centrale disparaît plutôt que de se casser. */
[data-compact] .jr-masthead-band > :nth-child(2) { display: none; }

/* Cartouche de page intérieure */
[data-compact] .jr-innerhead .jr-ih-title { font-size: 32px; }
[data-compact] .jr-innerhead span { font-size: 16px; }

/* Grilles : une colonne, deux articles. Les deux gabarits intérieurs
   n'échangent que la place de l'article majeur, pour garder un rythme
   d'édition sans jamais reléguer le plus récent au petit format. */
.jr-grid--m-front, .jr-grid--m-a, .jr-grid--m-b {
  grid-template-columns: 1fr;
  gap: 18px;
}
.jr-grid--m-front { grid-template-rows: 1fr;         grid-template-areas: "lead"; }
.jr-grid--m-a     { grid-template-rows: 1.35fr 1fr;  grid-template-areas: "lead" "second"; }
.jr-grid--m-b     { grid-template-rows: 1fr 1.35fr;  grid-template-areas: "second" "lead"; }
/* Le filet de séparation devient horizontal : on est en colonne unique. */
[data-layout="mobile"] .jr-grid .slot-second {
  border-left: 0; padding-left: 0;
  border-top: 1px solid var(--rule); padding-top: 16px;
}
[data-layout="mobile"] .jr-grid--m-b .slot-lead {
  border-top: 1px solid var(--rule); padding-top: 16px;
}
[data-layout="mobile"] .jr-grid--m-b .slot-second { border-top: 0; padding-top: 0; }

/* Typographie d'article. Repère : l'échelle effective va de 0,43 (iPhone SE)
   à 0,55 (iPhone 14). Les valeurs ci-dessous visent donc, à l'écran, une
   manchette d'une trentaine de pixels, un titre de une à 27-32, un titre
   secondaire à 19-23 et un corps à 11-14 — un aperçu lisible, la lecture
   réelle se faisant dans le lecteur plein écran. */
[data-compact] .jr-art-rubrique { font-size: 17px; letter-spacing: .18em; margin-bottom: 9px; }
[data-compact] .slot-lead   .jr-art-title { font-size: 58px; }
[data-compact] .slot-second .jr-art-title { font-size: 42px; }
[data-compact] .slot-lead   .jr-art-title.is-long     { font-size: 47px; }
[data-compact] .slot-lead   .jr-art-title.is-verylong { font-size: 39px; }
/* Chaque emplacement déclare ses propres tailles de titre long, en absolu :
   voir la note du format bureau sur le piège des tailles relatives. */
[data-compact] .slot-second .jr-art-title.is-long     { font-size: 34px; }
[data-compact] .slot-second .jr-art-title.is-verylong { font-size: 29px; }
[data-compact] .jr-art-excerpt { font-size: 26px; line-height: 1.3; margin-bottom: 11px; }
/* Le second article dispose d'un bloc court : titre et amorce de texte
   racontent mieux que titre + chapô + trois lignes hachées. */
[data-compact] .slot-second .jr-art-excerpt { display: none; }
/* Le corps ne peut jamais être réduit à néant : c'est lui qui absorbe la
   disparition d'une illustration, il doit garder de quoi le montrer. */
[data-compact] .jr-art-body { min-height: 4.2em; }
[data-compact] .jr-art-meta { font-size: 18px; margin-bottom: 9px; }
[data-compact] .jr-art-body { font-size: 24px; line-height: 1.4; column-gap: 20px; }
[data-compact] .slot-lead .jr-art-body,
[data-compact] .slot-second .jr-art-body { column-count: 2; }
[data-compact] .jr-art-body::after { height: 56px; }
[data-compact] .jr-art-readmore { font-size: 19px; margin-top: 9px; }

/* Encart abonnement et pied de feuille */
[data-compact] .jr-annonce { padding: 12px 14px; }
[data-compact] .jr-annonce b { font-size: 20px; margin-bottom: 2px; }
[data-compact] .jr-annonce span { font-size: 17px; }
[data-compact] .jr-sheet-foot { font-size: 16px; letter-spacing: .08em; margin-top: 14px; }
/* L'adresse du site ne tient pas entre les deux autres mentions sur une
   feuille étroite : elle est déjà dans la barre d'adresse du navigateur. */
[data-compact] .jr-sheet-foot > :nth-child(2) { display: none; }

/* Illustration : hauteur bornée EN PROPORTION de l'emplacement.
   Sans borne, un cadre 16/9 pleine largeur mesure 322 px de haut sur une
   feuille de 1280 : il avalait l'emplacement entier et réduisait le corps de
   texte à zéro (mesuré). Une borne en pixels ne suffisait pas non plus — le
   même chiffre est confortable dans l'emplacement de la une et étouffant
   dans celui d'une page intérieure, deux fois plus court.
   `display: contents` retire la boîte du conteneur sans retirer l'élément :
   le cadre devient enfant direct de l'article, donc son max-height en % se
   résout sur une hauteur définie (la rangée de grille). Le groupe reste
   sélectionnable et supprimable d'un bloc côté moteur.
   `flex: 0 1 auto` laisse enfin le cadre céder du terrain avant le texte. */
[data-compact] .jr-media { display: contents; }
[data-compact] .jr-figure {
  max-height: 24%; flex: 0 1 auto; min-height: 0; margin-bottom: 12px;
}
[data-compact] .jr-figure-caption { flex: 0 0 auto; }

/* Le chapô n'est conservé qu'en une, seul emplacement assez haut pour le
   porter sans rogner le corps de texte. Ailleurs, titre puis amorce de
   texte forment une accroche plus nette sur un écran étroit. */
[data-compact] .jr-grid--m-a .jr-art-excerpt,
[data-compact] .jr-grid--m-b .jr-art-excerpt { display: none; }

/* ════════════════════════════════════════════════════════════════════
   FORMAT TÉLÉPHONE COUCHÉ

   375 px de haut ne peuvent pas accueillir une feuille portrait : le
   format bureau y tombait à 0,187 d'échelle, soit un corps de texte de
   2,9 px et une feuille occupant 26 % de la largeur disponible (mesuré).
   La feuille se couche donc à son tour, et les deux articles se rangent
   côte à côte — la largeur est ici la ressource abondante. La typographie
   est celle du format portrait (attribut data-compact), l'échelle
   effective étant du même ordre (~0,50).
   ════════════════════════════════════════════════════════════════════ */
[data-layout="landscape"] .jr-sheet { padding: 22px 26px 24px; }
.jr-grid--l-front, .jr-grid--l-a, .jr-grid--l-b {
  grid-template-rows: 1fr;
  grid-template-areas: "lead second";
  gap: 20px;
  padding-top: 12px;
}
.jr-grid--l-front { grid-template-columns: 1.35fr 1fr; }
.jr-grid--l-a     { grid-template-columns: 1.3fr 1fr; }
/* Colonne large à droite : même alternance que sur les autres formats. */
.jr-grid--l-b     { grid-template-columns: 1fr 1.3fr; grid-template-areas: "second lead"; }
/* Deux colonnes côte à côte : le filet redevient vertical. */
[data-layout="landscape"] .jr-grid .slot-second,
[data-layout="landscape"] .jr-grid--l-b .slot-lead {
  border-left: 1px solid var(--rule); padding-left: 20px;
  border-top: 0; padding-top: 0;
}
[data-layout="landscape"] .jr-grid--l-b .slot-second { border-left: 0; padding-left: 0; }

/* Manchette ramassée : elle ne peut pas prendre le tiers d'une feuille
   de 620 px de haut. Le sous-titre et l'encart d'abonnement cèdent la
   place au contenu — le bouton « S'abonner » reste dans la barre d'outils. */
[data-layout="landscape"] .jr-masthead { margin-bottom: 4px; }
[data-layout="landscape"] .jr-masthead-title { font-size: 40px; }
[data-layout="landscape"] .jr-masthead-sub,
[data-layout="landscape"] .jr-annonce { display: none; }
[data-layout="landscape"] .jr-masthead-topline { margin-bottom: 6px; }
[data-layout="landscape"] .jr-masthead-band { margin-top: 8px; padding: 4px 2px; }
[data-layout="landscape"] .jr-sheet-foot { margin-top: 10px; padding-top: 6px; }

/* Emplacements moins hauts : le chapô cède partout, et le cadre
   d'illustration se contente d'une part plus modeste. */
[data-layout="landscape"] .jr-art-excerpt { display: none; }
[data-layout="landscape"] .jr-figure { max-height: 34%; }
[data-layout="landscape"] .jr-art-body { column-count: 1; }
[data-layout="landscape"] .slot-lead .jr-art-body,
[data-layout="landscape"] .slot-second .jr-art-body { column-count: 1; }

/* ── Accessibilité : mouvement réduit ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
