/* ════════════════════════════════════════════════════════════════════════
   LECTEUR AUDIO — habillage PARTAGÉ (extrait de journal.html le 2026-08-03)
   ════════════════════════════════════════════════════════════════════════
   Le widget vivait dans le fragment de la page Journal : son habillage
   mourait donc avec lui, et la page Décryptages ne pouvait pas l'afficher.
   Ces règles sont désormais servies par le shell (dashboard.html), donc
   valables sur TOUTE page qui pose un [data-w="audioplayer"].

   UNE SEULE COPIE : ne pas réintroduire ces règles dans un fragment de page
   (§1b-bis, l'écran doit être le même partout). Le comportement est dans
   /static/js/audio_widget.js, le moteur dans /static/js/audio_player.js.
   ════════════════════════════════════════════════════════════════════════ */

/* ══ Widget LECTEUR AUDIO (2026-08-02) ═══════════════════════════════
   Hauteur CHOISIE par l'admin (3 à 6 unités, --jn-h posé par le serveur) :
   c'est elle qui décide du nombre d'articles visibles dans la file. La
   carte s'y tient, seule la file défile — les commandes restent toujours
   à l'écran, quelle que soit la longueur de la file. */
.jn-w[data-h] { height:calc(var(--jn-unit) * var(--jn-h));
                display:flex; flex-direction:column; overflow:hidden; }
/* Une seule courbe d'accélération pour tout le lecteur : les mouvements
   ont ainsi le même « grain » (skill ui-ux-pro-max, motion-consistency). */
.jn-w[data-w="audioplayer"] { --jap-ease:cubic-bezier(.16,1,.3,1);
                              padding-bottom:10px; }
.jap-h { align-items:center; gap:8px; }
.jap-h .jn-card-t { display:flex; align-items:center; gap:7px; }
/* Médaillon d'identité du lecteur : même famille que les médaillons de
   rubrique du journal (dégradé d'accent, liseré, ombre portée) et même
   icône que l'onglet « Écoute audio » du menu. */
.jap-badge { display:flex; align-items:center; justify-content:center;
             width:30px; height:30px; flex:0 0 auto; border-radius:9px;
             color:#a78bfa;
             background:linear-gradient(145deg, rgba(167,139,250,.18),
                                        rgba(167,139,250,.05));
             border:1px solid rgba(167,139,250,.35);
             box-shadow:0 4px 10px rgba(0,0,0,.28);
             transition:transform .2s var(--jap-ease,ease); }
/* Pendant l'écoute, le médaillon respire doucement : l'état se voit même
   quand le témoin à barres n'est pas dans le champ. */
.jn-w[data-w="audioplayer"].jap-live .jap-badge { color:#c4b5fd;
             border-color:#a78bfa; transform:scale(1.04); }
.jap-count { font-family:var(--font-mono,monospace); font-size:0.6rem;
             font-weight:600; color:var(--text-muted);
             font-variant-numeric:tabular-nums; }
/* Témoin d'écoute : trois barres qui vivent seulement pendant la lecture.
   Au repos elles restent visibles, basses et grises — l'état se lit d'un
   coup d'œil sans dépendre de la seule couleur. */
.jap-eq { display:inline-flex; align-items:flex-end; gap:2px; height:12px;
          width:13px; flex:0 0 auto; }
.jap-eq b { display:block; width:3px; height:3px; border-radius:1px;
            background:var(--text-muted); transition:background .2s ease; }
.jn-w[data-w="audioplayer"].jap-live .jap-eq b { background:#a78bfa;
            animation:japEq .9s ease-in-out infinite; }
.jn-w[data-w="audioplayer"].jap-live .jap-eq b:nth-child(2) { animation-delay:.18s }
.jn-w[data-w="audioplayer"].jap-live .jap-eq b:nth-child(3) { animation-delay:.36s }
@keyframes japEq { 0%,100% { height:3px } 50% { height:12px } }
@media (prefers-reduced-motion:reduce) {
    .jn-w[data-w="audioplayer"].jap-live .jap-eq b { animation:none; height:8px } }

.jap-now { margin:4px 0 7px; min-height:36px; }
.jap-title { font-size:0.84rem; font-weight:700; color:var(--text-primary);
             line-height:1.28; display:-webkit-box; -webkit-line-clamp:2;
             -webkit-box-orient:vertical; overflow:hidden;
             font-family:Georgia,'Times New Roman',serif; }
.jap-sub { font-size:0.64rem; color:var(--text-muted); margin-top:4px;
           line-height:1.35; }
.jap-chap { font-size:0.64rem; font-weight:600; min-height:15px;
            color:color-mix(in srgb, #7c3aed 68%, var(--text-primary));
            white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
            margin-bottom:5px; letter-spacing:.01em; }

/* ── Barre de lecture : graduée en MOTS (échelle connue dès l'ouverture),
   les chapitres y sont matérialisés par des repères cliquables. Zone
   sensible de 18 px, bien au-delà du trait, pour rester facile à viser. */
.jap-bar { position:relative; height:18px; cursor:pointer; margin:0 0 1px;
           display:flex; align-items:center; touch-action:none; }
.jap-bar:focus-visible { outline:2px solid #a78bfa; outline-offset:3px;
                         border-radius:4px; }
/* Les teintes du lecteur sont MIXÉES au texte du thème, jamais posées en
   dur : le journal se lit en thème clair comme en sombre, et un
   rgba(255,255,255,…) disparaîtrait sur fond blanc. */
.jap-track { position:absolute; left:0; right:0; height:6px; border-radius:4px;
             background:color-mix(in srgb, var(--text-primary) 14%, transparent);
             box-shadow:inset 0 1px 2px rgba(0,0,0,.18); }
.jap-fill { position:absolute; left:0; height:6px; width:0; border-radius:4px;
            background:linear-gradient(90deg, #8b5cf6, #a78bfa);
            transition:width .2s var(--jap-ease); }
.jap-knob { position:absolute; right:-5px; top:50%; width:10px; height:10px;
            margin-top:-5px; border-radius:50%; background:#ede9fe;
            box-shadow:0 0 0 3px rgba(167,139,250,.35);
            opacity:0; transition:opacity .15s ease; }
.jap-bar:hover .jap-knob, .jap-bar:focus-visible .jap-knob { opacity:1; }
.jap-ticks { position:absolute; left:0; right:0; height:18px; }
/* Repère de chapitre : une CÉSURE dans la barre, pas un trait posé dessus —
   la barre paraît segmentée en chapitres (convention des lecteurs vidéo),
   au lieu d'être hachée par des marques qui la salissent. La césure fait
   exactement la hauteur de la piste et prend la couleur de la carte. */
.jap-tick { position:absolute; top:50%; width:2px; height:6px; margin:-3px 0 0 -1px;
            background:var(--bg-card); cursor:pointer;
            transition:height .15s var(--jap-ease), background .15s ease; }
/* Cible tactile élargie sans épaissir la césure */
.jap-tick::after { content:''; position:absolute; inset:-7px -6px; }
.jap-tick:hover { height:12px; margin-top:-6px;
                  background:color-mix(in srgb, var(--text-primary) 70%, transparent); }
/* Chapitre en cours : un repère plein sous la piste, qui ne coupe rien. */
.jap-tick.on { height:12px; margin-top:-6px; background:#7c3aed; width:2px; }
.jap-time { display:flex; justify-content:space-between; font-size:0.58rem;
            color:var(--text-muted); font-family:var(--font-mono,monospace);
            font-variant-numeric:tabular-nums; margin-bottom:9px; }

/* ── Transport : le bouton d'écoute est la SEULE action dominante ──
   (skill ui-ux-pro-max : un primaire par écran, le reste subordonné). */
.jap-ctl { display:flex; align-items:center; justify-content:center;
           gap:6px; margin-bottom:9px; }
.jap-b { background:transparent; border:1px solid transparent;
         color:var(--text-secondary); border-radius:9px; height:34px;
         min-width:34px; flex:0 0 auto; display:flex; align-items:center;
         justify-content:center; cursor:pointer; padding:0;
         transition:color .15s ease, background .15s ease,
                    border-color .15s ease, transform .12s var(--jap-ease); }
.jap-b:hover { color:var(--text-primary); background:rgba(167,139,250,.12); }
.jap-b:active { transform:scale(.94); }
.jap-b:focus-visible { outline:2px solid #a78bfa; outline-offset:2px; }
.jap-b[disabled] { opacity:.3; cursor:default; background:transparent;
                   transform:none; }
/* Action primaire : pastille pleine, halo d'accent, 44 px. */
.jap-b.jap-play { width:44px; height:44px; border-radius:50%;
                  background:#a78bfa; color:#1a1233; margin:0 4px;
                  box-shadow:0 4px 14px rgba(167,139,250,.32); }
.jap-b.jap-play:hover { background:#b9a3fc; color:#1a1233; }
.jap-b.jap-play[disabled] { background:var(--bg-deep); color:var(--text-muted);
                            box-shadow:none; }
.jap-b.jap-busy { animation:jnPulse 1.3s ease-out infinite; }
@media (prefers-reduced-motion:reduce) {
    .jap-b.jap-busy { animation:none }
    .jap-b, .jap-fill { transition:none } }

.jap-set { display:flex; align-items:center; gap:7px; margin-bottom:9px; }
.jap-b.jap-mini-act { height:26px; min-width:26px; border-color:var(--border);
                      color:var(--text-muted); }
.jap-b.jap-mini-act:hover { color:#ef4444; border-color:#ef4444;
                            background:rgba(239,68,68,.1); }
.jap-b.jap-mini-act svg { width:11px; height:11px; }
.jap-rate { display:flex; align-items:center; flex:0 0 auto; }
.jap-rate select { background:var(--bg-deep); border:1px solid var(--border);
                   color:var(--text-secondary); border-radius:7px;
                   font-size:0.64rem; font-weight:600; padding:4px 3px;
                   cursor:pointer; font-variant-numeric:tabular-nums; }
.jap-rate select:hover { color:var(--text-primary); border-color:#a78bfa; }
.jap-vol { display:flex; align-items:center; gap:5px; flex:1 1 auto;
           min-width:0; color:var(--text-muted); }
.jap-vol input { flex:1 1 auto; min-width:0; accent-color:#a78bfa; height:16px;
                 cursor:pointer; }

.jap-qh { display:flex; align-items:center; justify-content:space-between;
          font-size:0.58rem; font-weight:700; text-transform:uppercase;
          letter-spacing:.09em; color:var(--text-muted);
          border-bottom:1px solid var(--border); padding-bottom:4px;
          margin-bottom:2px; }
.jap-clear { background:transparent; border:none; color:var(--text-muted);
             font-size:0.58rem; font-weight:700; text-transform:uppercase;
             letter-spacing:.06em; cursor:pointer; padding:2px 4px;
             border-radius:5px; }
.jap-clear:hover { color:#ef4444; background:rgba(239,68,68,.1); }
.jap-clear[disabled] { opacity:.3; cursor:default; background:transparent; }
/* Réglage de hauteur du lecteur (− / +, en haut à droite) : n'a de sens
   qu'en présentation large, où la hauteur est contrainte. */
.jap-hbtns { display:none; align-items:center; gap:2px; margin-left:8px; }
.jn-w-lg .jap-hbtns { display:inline-flex; }
.jap-hb { background:transparent; border:1px solid var(--border);
          color:var(--text-muted); border-radius:5px; width:18px; height:18px;
          line-height:1; font-size:0.72rem; font-weight:700; cursor:pointer;
          padding:0; display:flex; align-items:center; justify-content:center; }
.jap-hb:hover { color:var(--accent); border-color:var(--accent); }
.jap-hb[disabled] { opacity:.3; cursor:default; }
/* La file est la SEULE partie qui défile : les commandes restent visibles.
   Barre de défilement discrète, dans la teinte du thème. */
.jap-q { list-style:none; margin:0; padding:0; overflow-y:auto;
         flex:1 1 auto; min-height:0; scrollbar-width:thin;
         scrollbar-color:rgba(167,139,250,.45) transparent; }
.jap-q::-webkit-scrollbar { width:5px; }
.jap-q::-webkit-scrollbar-thumb { background:rgba(167,139,250,.4);
                                  border-radius:3px; }
.jap-q li { display:flex; align-items:flex-start; gap:7px; padding:7px 6px;
            border-radius:8px; font-size:0.7rem; line-height:1.32;
            color:var(--text-secondary); cursor:pointer;
            transition:background .15s ease, color .15s ease; }
.jap-q li + li { margin-top:1px; }
.jap-q li:hover { color:var(--text-primary);
                  background:color-mix(in srgb, var(--text-primary) 7%, transparent); }
.jap-q li .n { font-family:var(--font-mono,monospace); font-size:0.58rem;
               color:var(--text-muted); flex:0 0 auto; width:13px;
               text-align:right; padding-top:2px;
               font-variant-numeric:tabular-nums; }
.jap-q li .t { flex:1 1 auto; min-width:0; }
/* Article EN COURS : fond teinté, filet d'accent, numéro allumé — trois
   marqueurs, dont deux non colorés (règle « pas la couleur seule »). */
.jap-q li.on { color:var(--text-primary); font-weight:700;
               background:rgba(167,139,250,.13);
               box-shadow:inset 3px 0 0 0 #a78bfa; }
.jap-q li.on .n { color:#c4b5fd; }
.jap-q li.done { color:var(--text-muted); }
.jap-q li .pc { display:block; font-size:0.56rem; color:var(--text-muted);
                font-family:var(--font-mono,monospace); font-weight:400;
                margin-top:2px; font-variant-numeric:tabular-nums; }
.jap-q li .x { flex:0 0 auto; background:transparent; border:none;
               color:var(--text-muted); cursor:pointer; font-size:0.9rem;
               line-height:1; padding:2px 3px; border-radius:5px;
               opacity:0; transition:opacity .15s ease, color .15s ease; }
.jap-q li:hover .x, .jap-q li .x:focus-visible { opacity:1; }
.jap-q li .x:hover { color:#ef4444; background:rgba(239,68,68,.12); }
/* Écran vide : on explique le geste à faire plutôt que d'afficher un trou.
   display:block indispensable — la règle générale des items de file est en
   flex, qui réduirait ce texte à une colonne d'un mot. */
.jap-q li.jap-empty { display:block; font-size:0.66rem; color:var(--text-muted);
             padding:14px 8px; line-height:1.5; text-align:center;
             cursor:default; background:transparent; }
.jap-q li.jap-empty:hover { background:transparent; color:var(--text-muted); }
.jap-empty b { display:block; color:var(--text-secondary); font-weight:700;
               margin-bottom:3px; }

/* ══ LECTEUR EN MODE LARGE — au-dessus de la barre des thèmes ══════
   Demande admin 2026-08-02. Deux parties nettes : le LECTEUR à gauche, la
   FILE à droite, séparées par un filet. Hauteur plafonnée à deux fois la
   barre des thèmes (mesurée à 44 px → 88 px).

   Composition, de gauche à droite — l'ordre de lecture d'une barre de
   lecture professionnelle : commandes de transport, puis ce qu'on écoute,
   puis où l'on en est, puis les réglages, enfin la file.

     ┌────────┬──────────────────────────┬────────┬────────────┐
     │ ⏮◀◀▶▶▶⏭ │ Titre de l'article       │ 1×  🔊 │ FILE   (3) │
     │        │ Chapitre 2/7 · Le paradoxe│        │ ▸1 Titre…  │
     │        │ 0:41 ▬▬▬●────────── 8:35  │        │  2 Titre…  │
     └────────┴──────────────────────────┴────────┴────────────┘

   La bascule est portée par la classe `jn-w-lg`, posée par le serveur dès
   6 colonnes et maintenue par l'éditeur admin au redimensionnement. (Une
   requête de conteneur ne conviendrait pas : un élément ne peut pas
   répondre à SA PROPRE container query — seuls ses descendants le
   peuvent.) En dessous de 900 px la grille du journal passe à une colonne :
   le lecteur reprend alors sa présentation verticale. */
@media (min-width:901px) {
.jn-w-lg[data-w="audioplayer"] {
    /* Hauteur d'un onglet de thème : le plafond du lecteur lui est
       RELATIF (2× à 3×), il suit donc l'agrandissement des pastilles. */
    --jap-thbar:52px;
    /* Hauteur réglée par l'AUDITEUR (boutons − / + en haut à droite) :
       deux à trois fois la barre des thèmes. Le multiplicateur est
       mémorisé dans son navigateur — c'est un confort de lecture, pas une
       décision de mise en page (demande admin 2026-08-02). */
    height:calc(var(--jap-thbar) * var(--jap-mult,2));
    max-height:calc(var(--jap-thbar) * var(--jap-mult,2));
    padding:9px 14px; overflow:hidden;
    display:grid; align-content:center;
    /* Répartition (demande admin 2026-08-02) : transport et zone de lecture
       resserrés d'un cinquième, tout l'espace gagné allant à la file. */
    grid-template-columns:auto auto minmax(0,.8fr) auto minmax(255px,.62fr);
    /* La DERNIÈRE rangée absorbe la hauteur disponible : à 2× elle ne
       change rien, à 3× elle donne à la file toute la place gagnée plutôt
       que de laisser deux bandes vides en haut et en bas (demande admin
       2026-08-02). */
    grid-template-rows:auto auto 1fr;
    column-gap:14px; row-gap:2px;
    grid-template-areas:
        "ico ctl now  now  qh"
        "ico ctl chap set  q"
        "ico ctl bar  bar  q"; }
/* Pleine largeur : la file, sur deux colonnes, reçoit davantage de place ;
   la zone de lecture reste confortable. */
.jn-w-lg[data-size="12"] {
    grid-template-columns:auto auto minmax(0,.72fr) auto minmax(360px,.9fr); }
/* Placement des blocs déjà présents — aucun HTML dupliqué. */
.jn-w-lg .jap-a-ctl  { grid-area:ctl; }
.jn-w-lg .jap-a-now  { grid-area:now; }
.jn-w-lg .jap-a-chap { grid-area:chap; }
.jn-w-lg .jap-a-bar  { grid-area:bar; }
.jn-w-lg .jap-a-set  { grid-area:set; }
.jn-w-lg .jap-a-qh   { grid-area:qh; }
.jn-w-lg .jap-a-q    { grid-area:q; }
/* De l'en-tête, seul le MÉDAILLON subsiste en présentation large : il dit
   ce qu'est ce bloc sans coûter une ligne. Le temps, lui, est réinjecté
   aux deux bouts de la barre — seule place qui ne coûte aucune hauteur. */
.jn-w-lg .jap-a-head { grid-area:ico; align-self:center; margin:0;
                       padding-right:12px; border-right:1px solid var(--border);
                       height:100%; align-items:center; }
.jn-w-lg .jap-a-head .jn-card-t,
.jn-w-lg .jap-a-head .jap-count { display:none; }
.jn-w-lg .jap-badge { width:34px; height:34px; border-radius:11px; }
.jn-w-lg .jap-a-time { display:none; }

/* ── Transport, colonne de gauche, centré sur les trois lignes ──
   Resserré d'un cinquième (demande admin 2026-08-02) : boutons 28→23 px,
   pastille de lecture 36→29 px, gouttières réduites. */
.jn-w-lg .jap-ctl { margin:0; gap:1px; align-self:center;
                    padding-right:11px; border-right:1px solid var(--border); }
.jn-w-lg .jap-b { height:23px; min-width:23px; border-radius:6px; }
.jn-w-lg .jap-b svg { width:11px; height:11px; }
.jn-w-lg .jap-b.jap-play { width:29px; height:29px; margin:0 2px; }
.jn-w-lg .jap-b.jap-play svg { width:13px; height:13px; }

/* ── Ce qu'on écoute ── */
.jn-w-lg .jap-now { margin:0; min-height:0; align-self:end; }
.jn-w-lg .jap-title { font-size:0.88rem; -webkit-line-clamp:1; line-height:1.3;
                      white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
                      display:block; letter-spacing:.005em; }
.jn-w-lg .jap-sub { display:none; }       /* l'aide vit dans la file vide */
.jn-w-lg .jap-chap { margin:0; font-size:0.62rem; min-height:0;
                     align-self:center; }

/* ── Où l'on en est : barre pleine largeur, temps à ses deux bouts ── */
.jn-w-lg .jap-bar { height:16px; margin:0; align-self:center;
                    padding:0 46px; box-sizing:border-box; }
.jn-w-lg .jap-bar .jap-track,
.jn-w-lg .jap-bar .jap-ticks { left:46px; right:46px; }
.jn-w-lg .jap-bar .jap-fill { left:46px; }
/* Les deux temps sont écrits par le moteur dans ces attributs : aucune
   ligne de plus, donc aucune hauteur de plus. */
.jn-w-lg .jap-bar::before, .jn-w-lg .jap-bar::after {
    position:absolute; top:50%; transform:translateY(-50%);
    font-family:var(--font-mono,monospace); font-size:0.58rem;
    font-variant-numeric:tabular-nums; color:var(--text-muted);
    pointer-events:none; }
.jn-w-lg .jap-bar::before { content:attr(data-t0); left:0; }
.jn-w-lg .jap-bar::after  { content:attr(data-t1); right:0; text-align:right; }

/* ── Réglages : arrêt, vitesse, volume ── */
.jn-w-lg .jap-set { margin:0; gap:6px; align-self:center; justify-self:end; }
.jn-w-lg .jap-b.jap-mini-act { height:24px; min-width:24px; }
.jn-w-lg .jap-b.jap-mini-act svg { width:10px; height:10px; }
.jn-w-lg .jap-rate select { font-size:0.6rem; padding:3px 2px; }
.jn-w-lg .jap-vol { width:74px; flex:0 0 auto; }
.jn-w-lg .jap-vol input { height:12px; }

/* ── File d'attente : panneau de droite, séparé par un filet ── */
.jn-w-lg .jap-qh { margin:0; padding:0 0 3px 14px; font-size:0.54rem;
                   align-self:center; border-bottom:none;
                   border-left:1px solid var(--border); }
.jn-w-lg .jap-q { max-height:none; padding-left:14px;
                  border-left:1px solid var(--border); }
/* PLEINE LARGEUR : la file passe à DEUX COLONNES (demande admin
   2026-08-02) — deux fois plus d'articles visibles à hauteur égale, et la
   largeur gagnée sert enfin à quelque chose. */
.jn-w-lg[data-size="12"] .jap-q { display:grid; align-content:start;
                  grid-template-columns:repeat(2,minmax(0,1fr));
                  gap:0 12px; }
.jn-w-lg[data-size="12"] .jap-q li.jap-empty { grid-column:1 / -1; }
.jn-w-lg .jap-q li { padding:2px 5px; font-size:0.63rem; gap:6px;
                     align-items:center; border-radius:6px; }
.jn-w-lg .jap-q li + li { margin-top:0; }
.jn-w-lg .jap-q li .t { white-space:nowrap; overflow:hidden;
                        text-overflow:ellipsis; }
.jn-w-lg .jap-q li .pc { display:inline; margin:0 0 0 5px; }
.jn-w-lg .jap-q li.on { box-shadow:inset 2px 0 0 0 #a78bfa; }
.jn-w-lg .jap-q li .x { opacity:0; }
.jn-w-lg .jap-q li:hover .x { opacity:1; }
.jn-w-lg .jap-q li.jap-empty { padding:4px 2px; font-size:0.58rem;
                               text-align:left; line-height:1.4; }
.jn-w-lg .jap-q li.jap-empty b { margin-bottom:0; }

/* ── HAUTEUR 3× : la place gagnée va au CONFORT DE LECTURE ──────────
   (demande admin 2026-08-02). Le titre peut s'écrire sur deux lignes, les
   lignes de commande respirent, et la file — qui est l'objet du réglage —
   affiche deux fois plus d'articles. */
.jn-w-lg[data-hmult="3"] { row-gap:4px; padding:10px 14px; }
/* Le titre reste sur UNE ligne : l'écrire sur deux reprendrait à la file
   la place que ce réglage vient précisément de lui donner (arbitrage
   explicite, demande admin 2026-08-02). */
.jn-w-lg[data-hmult="3"] .jap-now { align-self:center; }
.jn-w-lg[data-hmult="3"] .jap-b { height:26px; min-width:26px; }
.jn-w-lg[data-hmult="3"] .jap-b.jap-play { width:33px; height:33px; }
.jn-w-lg[data-hmult="3"] .jap-badge { width:40px; height:40px; border-radius:13px; }
.jn-w-lg[data-hmult="3"] .jap-badge svg { width:20px; height:20px; }
/* L'en-tête de file se réduit au strict nécessaire : chaque pixel repris
   ici est un pixel de plus pour les articles, qui sont l'objet du réglage. */
.jn-w-lg[data-hmult="3"] .jap-qh { padding-bottom:1px; font-size:0.52rem; }
.jn-w-lg[data-hmult="3"] .jap-q li { padding:3px 5px; font-size:0.65rem;
                                     line-height:1.25; }
.jn-w-lg[data-hmult="3"] .jap-bar { height:18px; }
}

/* ══ Menu contextuel (clic droit sur un article) ═════════════════════ */
#jn-ctx { position:fixed; z-index:980; min-width:212px; padding:4px;
          background:var(--bg-card); border:1px solid var(--border);
          border-left:3px solid #a78bfa; border-right:3px solid #a78bfa;
          border-radius:10px; box-shadow:0 12px 30px rgba(0,0,0,.5);
          display:none; }
#jn-ctx.open { display:block; }
#jn-ctx .h { font-size:0.62rem; color:var(--text-muted); padding:4px 8px 5px;
             border-bottom:1px solid var(--border); margin-bottom:3px;
             white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
             max-width:260px; }
#jn-ctx button { display:flex; align-items:center; gap:8px; width:100%;
                 text-align:left; background:transparent; border:none;
                 color:var(--text-primary); font-size:0.74rem; font-weight:600;
                 padding:6px 8px; border-radius:6px; cursor:pointer; }
#jn-ctx button:hover { background:rgba(167,139,250,.16); color:var(--accent); }
#jn-ctx button svg { flex:0 0 auto; opacity:.8; }

/* ══ HÔTE HORS JOURNAL (page Décryptages) ═══════════════════════════════
   Dans le journal, la carte du lecteur hérite des styles de la grille de
   widgets (.jn-card, .jn-rail, .jn-card-h…). Hors journal, ces classes
   n'existent pas : elles sont redonnées ici, SCOPÉES à .jap-host pour ne
   jamais interférer avec la grille du journal. */
/* --jn-unit : unité de la grille du journal (88 px), dont dépend la hauteur
   des widgets à hauteur réglable. Redonnée ici pour que le calcul reste
   valide en présentation étroite, où la bascule large ne s'applique pas. */
.jap-host { margin:0 0 20px; --jn-unit:88px; }
.jap-host .jn-card { background:var(--bg-card); border:1px solid var(--border);
                     border-radius:10px; padding:12px 14px; }
.jap-host .jn-w.jn-rail { border-left:3px solid #a78bfa;
                          border-right:3px solid #a78bfa; }
.jap-host .jn-card-h { display:flex; align-items:baseline;
                       justify-content:space-between; gap:8px; margin-bottom:6px; }
.jap-host .jn-card-t { font-size:0.76rem; font-weight:700;
                       color:var(--text-primary); letter-spacing:.02em; }
.jap-host .jn-card-v { font-size:0.78rem; font-weight:700;
                       font-family:var(--font-mono,monospace); }
.jap-host .jn-card-s { font-size:0.68rem; color:var(--text-muted); }
/* Halo de préparation du bouton d'écoute : l'animation est définie dans le
   fragment du journal, elle doit exister aussi hors de lui (déclaration
   identique, sans effet là où elle est déjà connue). */
@keyframes jnPulse { 0%{box-shadow:0 0 0 0 rgba(167,139,250,.5)}
                     70%{box-shadow:0 0 0 9px rgba(167,139,250,0)}
                     100%{box-shadow:0 0 0 0 rgba(167,139,250,0)} }

/* ══ PETIT ÉCRAN ════════════════════════════════════════════════════════
   Sous 900 px, le lecteur reprend sa présentation verticale (la bascule
   large est déjà bornée par @media (min-width:901px) plus haut) et ses
   commandes passent aux cibles tactiles du standard, 44 px : au doigt, les
   34 px du bureau ne suffisent pas (skill ui-ux-pro-max, touch-target-size).
   Ces règles étaient dans le fragment du journal, elles valent partout. */
@media (max-width:900px) {
    .jap-q { max-height:260px; }
    .jap-b { height:44px; min-width:44px; }
    .jap-b.jap-play { width:52px; height:52px; }
    .jap-b.jap-mini-act { height:36px; min-width:36px; }
    .jap-ctl { gap:8px; }
    .jap-q li { padding:10px 6px; }
    .jap-q li .x { opacity:1; }        /* pas de survol au doigt */
    /* Hôte hors journal : la hauteur choisie n'a plus de sens à une colonne. */
    .jap-host .jn-w[data-h] { height:auto; max-height:none; }
}

/* ══ BOUTON « AJOUTER À LA LISTE DE LECTURE » (cartes Décryptages) ═══════
   Demande admin 2026-08-03. Le bouton vit DANS le lien-carte (la carte
   entière est un <a>) : son clic est intercepté en capture par
   audio_widget.js, qui l'empêche d'ouvrir l'article. L'état .on (déjà en
   file) suit la file du moteur, pas le dernier clic. */
.blog-addq { display:inline-flex; align-items:center; gap:7px; margin-top:10px;
             align-self:flex-start; background:transparent;
             border:1px solid var(--border); border-radius:8px;
             color:var(--text-secondary); font:600 0.78rem/1 inherit;
             font-family:inherit; padding:7px 11px; cursor:pointer;
             transition:color .15s ease, border-color .15s ease,
                        background .15s ease; }
.blog-addq:hover { color:#a78bfa; border-color:#a78bfa;
                   background:rgba(167,139,250,.08); }
.blog-addq.on { color:#a78bfa; border-color:rgba(167,139,250,.5);
                background:rgba(167,139,250,.10); cursor:default; }
.blog-addq svg { flex:none; }

/* ══ ATTENTE DU PREMIER GESTE (lecture automatique, page article) ════════
   La lecture sonore est refusée par le navigateur tant que la page n'a pas
   reçu un geste : le bouton d'écoute du widget pulse pour signaler qu'il
   attend ce geste. Classe posée/retirée par la glue de la page article. */
.jap-b.jap-play.jap-wait { animation:jnPulse 1.6s ease-out infinite; }
