/* ===========================================================================
   Bublee — « Édition »
   Une première page de journal : filets, aplats, angles droits, aucune ombre.
   Tout ce qui n'est pas éditorial est en mono capitales.
   =========================================================================== */

:root {
  /* Des noirs chauds, jamais purs : l'encre d'un journal n'est pas du #000,
     et un aplat trop sombre à côté du papier fatigue à la lecture longue. */
  --ink:      #24231f;   /* encre : texte, filets forts, aplats pleins */
  --ink-deep: #1b1a17;   /* fond des blocs photo, derrière les voiles */
  --index-bg: #302e2a;   /* l'index : un cran au-dessus de l'encre */
  --ink-2:    #403d37;   /* séparateurs internes de l'index */
  --voile:    27, 26, 22;/* base des voiles posés sur les images */
  --bone:     #e9e7e0;   /* fond de page */
  --bone-2:   #dedbd2;   /* aplats clairs, survol de ligne */
  --paper:    #f6f5f1;   /* encre claire : texte posé sur un fond sombre */
  --mute:     #7d7a71;   /* méta, libellés secondaires */

  /* Accent — réglable dans les préférences. Vert forêt par défaut. */
  --accent: #10604a;

  /* Filets et gris intermédiaires */
  --rule-col:  #c9c6bc;
  --rule-list: #cfccc2;
  --rule-fil:  #d6d3c9;
  --dark-rule: #4c4941;
  --dark-hov:  #3b3833;
  /* Sur un fond d'index éclairci, les gris doivent monter d'autant pour que
     la méta garde le même rapport de lisibilité. */
  --on-ink-1:  #cbc7bd;
  --on-ink-2:  #b5b1a7;
  --on-ink-3:  #a29e94;
  --on-ink-4:  #8c887e;

  --display: 'Instrument Serif', 'Iowan Old Style', Georgia, serif;
  --body:    'Newsreader', Georgia, 'Times New Roman', serif;
  --mono:    'IBM Plex Mono', ui-monospace, 'SF Mono', Consolas, monospace;

  --index-w: 266px;
  --gut:     30px;
  --ease:    cubic-bezier(.16, .84, .24, 1);
}

/* Le thème sombre inverse le papier et l'encre. L'index reste un cran plus
   sombre que la page pour s'en détacher — sans jamais tomber sur du noir pur. */
:root[data-theme='dark'] {
  --ink:      #e4e1d9;
  --ink-deep: #0f0e0d;
  --index-bg: #100f0e;
  --ink-2:    rgba(228, 225, 217, .12);
  --bone:     #161513;
  --bone-2:   #211f1c;
  --mute:     #8d8a82;

  --rule-col:  rgba(233, 231, 224, .16);
  --rule-list: rgba(233, 231, 224, .14);
  --rule-fil:  rgba(233, 231, 224, .12);
  --dark-rule: rgba(233, 231, 224, .16);
  --dark-hov:  #141312;
  --on-ink-1:  #b9b6ad;
  --on-ink-2:  #9d9a92;
  --on-ink-3:  #8d8a82;
  --on-ink-4:  #6f6d66;
}

@media (prefers-color-scheme: dark) {
  :root[data-theme='auto'] {
    --ink:      #e4e1d9;
    --ink-deep: #0f0e0d;
    --index-bg: #100f0e;
    --ink-2:    rgba(228, 225, 217, .12);
    --bone:     #161513;
    --bone-2:   #211f1c;
    --mute:     #8d8a82;

    --rule-col:  rgba(233, 231, 224, .16);
    --rule-list: rgba(233, 231, 224, .14);
    --rule-fil:  rgba(233, 231, 224, .12);
    --dark-rule: rgba(233, 231, 224, .16);
    --dark-hov:  #141312;
  }
}

/* L'index garde son propre fond dans les deux thèmes : en clair il est plus
   sombre que la page, en sombre légèrement plus sombre encore — jamais noir. */

/* ------------------------------------------------------------------ socle */

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body { height: 100%; margin: 0; }

body {
  background: var(--bone);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16px;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; border-radius: 0; }
a { color: inherit; text-decoration: none; }
img { border-radius: 0; }

svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* Le fond posé sous une illustration le temps qu'elle arrive : deux teintes
   moyennes de l'image elle-même, haut et bas, ce qui donne un dégradé qui en
   est une version très floue. Tant qu'on ne les connaît pas, la teinte de la
   source prend le relais — jamais de trou blanc dans la grille.

   Le dégradé est écrit en toutes lettres dans chaque règle, et non rangé dans
   une variable commune : un `var()` imbriqué dans une propriété personnalisée
   est substitué là où celle-ci est *déclarée*, pas là où elle est utilisée. En
   la posant sur :root, --f1 n'y existait pas et c'est la valeur de repli qui
   descendait partout — le dégradé ne voyait jamais les couleurs de l'image. */

/* L'image se pose en fondu sur ce fond au lieu d'apparaître d'un bloc. */
img.fondu { opacity: 0; transition: opacity .45s var(--ease); }
img.fondu.chargee { opacity: 1; }
@media (prefers-reduced-motion: reduce) { img.fondu { transition: none; } }

::selection { background: var(--accent); color: #fff; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* La mono en capitales tient tout l'habillage : méta, boutons, compteurs. */
.m { font-family: var(--mono); text-transform: uppercase; }

h1, h2, h3, p, dl, dd, figure { margin: 0; }

.skip-link {
  position: fixed; top: -60px; left: 12px; z-index: 999;
  background: var(--ink-deep); color: var(--paper);
  padding: 10px 16px; text-decoration: none;
  font-family: var(--mono); font-size: 10px; letter-spacing: .18em; text-transform: uppercase;
}
.skip-link:focus { top: 12px; }

@keyframes ed-rise { from { opacity: 0; transform: translateY(14px); } }
@keyframes ed-up   { from { opacity: 0; transform: translateY(26px); } }
@keyframes ed-fade { from { opacity: 0; } }

/* --------------------------------------------------------------- squelette */

.app {
  display: grid;
  grid-template-columns: var(--index-w) minmax(0, 1fr);
  height: 100%;
}

/* Index replié : la colonne tombe à zéro et la scène prend toute la largeur.
   Replier plutôt que réduire à une barre d'icônes — un nom de source ne se
   résume pas à un pictogramme, une demi-mesure ne rendrait pas de surface.

   Borné au-delà de 860 px : en dessous, l'index est déjà un tiroir et la grille
   n'a qu'une colonne — y appliquer le repli la casserait. */
@media (min-width: 861px) {
  .app.plie { grid-template-columns: 0 minmax(0, 1fr); }
  .app.plie .index { overflow: hidden; border-right: 0; }
  .app.plie .index-poignee { display: none; }
  .app.plie .index-open { display: flex; align-items: center; padding: 0 14px; height: 100%; border-right: 1px solid var(--bone-2); }
}

/* Pas de transition sur grid-template-columns : mesuree, elle empeche purement
   et simplement la colonne de tomber a zero — la valeur reste bloquee a sa
   largeur de depart. Le repli est donc instantane, ce qui va tres bien a une
   bascule de mise en page. */

/* ====================================================== l'index (kiosque) */

.index {
  position: relative;
  display: flex; flex-direction: column; min-height: 0;
  background: var(--index-bg);
  color: var(--bone);
}

/* La poignée de largeur : invisible au repos, un filet d'accent quand la main
   passe. La zone de saisie déborde de 3 px sur la scène — sinon on vise un
   trait de 1 px à la souris. */
.index-poignee {
  position: absolute; top: 0; bottom: 0; right: -3px; width: 7px; z-index: 5;
  cursor: col-resize;
}
.index-poignee::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: 3px; width: 1px;
  background: var(--accent); opacity: 0;
  transition: opacity .18s var(--ease);
}
.index-poignee:hover::after, .index-poignee:focus-visible::after,
.app.redim .index-poignee::after { opacity: 1; }
.index-poignee:focus-visible { outline: none; }
/* Pendant le glissé, plus rien ne surligne ni ne sélectionne sous le curseur. */
.app.redim { cursor: col-resize; user-select: none; }
.app.redim .feed-row:hover, .app.redim .view-row:hover { background: none; }

.index-head {
  padding: 20px 18px 16px;
  border-bottom: 1px solid var(--dark-rule);
}

.wordmark {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}

/* Le logo : deux bulles qui se recouvrent, l'intersection en accent.
   Deux filets, comme les règles de toute la maquette, mais courbés — ce sont les
   seules courbes de l'interface, d'où la reconnaissance immédiate. Et le dessin
   dit ce que fait l'app : deux sources qui se croisent, le recoupement mis en
   valeur plutôt que subi. */
.logo {
  display: flex; align-items: center; gap: 12px;
  color: #f6f5f1; text-decoration: none;
}
.logo-mark { width: 34px; height: 22.7px; flex: none; }
.logo-mark .lentille { fill: var(--accent); }
.logo-mark .anneaux { fill: none; stroke: currentColor; stroke-width: 1.5; }
.logo-mot {
  font-family: var(--display); font-size: 33px; line-height: .86; letter-spacing: -.025em;
}
.logo:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.index-date {
  margin-top: 12px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--on-ink-4);
}

.index-close { display: none; }

/* Le chevron de repli : discret au repos, il ne prend la lumière qu'au survol
   de l'en-tête — sinon il concurrencerait le logo juste à côté. */
.index-plier {
  flex: none; width: 24px; height: 24px;
  display: grid; place-items: center;
  color: var(--on-ink-4);
  opacity: 0; transition: opacity .18s var(--ease), color .18s var(--ease);
}
.index-plier svg { width: 15px; height: 15px; stroke-width: 1.8; }
.index-head:hover .index-plier, .index-plier:focus-visible { opacity: 1; }
.index-plier:hover { color: var(--accent); }

/* recherche */
.index-search { position: relative; border-bottom: 1px solid var(--ink-2); }
.index-search input {
  width: 100%; padding: 11px 14px 11px 34px;
  background: none; border: 0;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  color: #f6f5f1;
}
.index-search input::placeholder { color: var(--on-ink-4); }
.index-search input:focus { outline: none; background: var(--dark-hov); }
.index-search input::-webkit-search-cancel-button,
.index-search input::-webkit-search-decoration { display: none; -webkit-appearance: none; }
.search-glyph {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 13px; height: 13px; color: var(--on-ink-4); pointer-events: none;
}

/* vues */
.index-views { border-bottom: 1px solid var(--dark-rule); }

.view-row {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 11px 18px;
  border-bottom: 1px solid var(--ink-2);
  text-align: left;
}
.view-row:last-child { border-bottom: 0; }
.view-row:hover { background: var(--dark-hov); }
.view-mark { width: 5px; height: 5px; flex: none; background: var(--accent); opacity: 0; }
.view-row.active .view-mark { opacity: 1; }
.view-label {
  flex: 1;
  font-family: var(--mono); font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--on-ink-1);
}
.view-row.active .view-label { color: #f6f5f1; }
.view-count {
  font-family: var(--mono); font-size: 11px; font-variant-numeric: tabular-nums;
  color: var(--on-ink-4);
}

/* titres de section dans l'index */
.index-section {
  display: flex; align-items: center; gap: 10px;
  padding: 18px 18px 8px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .22em; text-transform: uppercase;
  color: var(--on-ink-4);
}
.index-section .count { color: #6b675e; font-variant-numeric: tabular-nums; }
.index-section .grow { flex: 1; }
.index-section button { color: var(--on-ink-4); }
.index-section button:hover { color: #f6f5f1; }
.index-section .pencil { width: 13px; height: 13px; }

/* étiquettes */
.index-tags { padding: 0 18px 4px; }

.tag-row {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 4px 0; text-align: left;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .04em;
  color: var(--on-ink-1);
  transition: color .2s ease;
}
.tag-row:hover, .tag-row.active { color: #f6f5f1; }
.tag-square { width: 9px; height: 9px; flex: none; background: var(--teinte, var(--accent)); }
.tag-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag-count { font-family: var(--mono); font-size: 10.5px; font-variant-numeric: tabular-nums; color: var(--on-ink-4); }

/* le kiosque */
.index-feeds {
  flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  scrollbar-width: thin; scrollbar-color: #35342f transparent;
}
.index-feeds::-webkit-scrollbar { width: 8px; }
.index-feeds::-webkit-scrollbar-thumb { background: #56534b; }
.index-feeds::-webkit-scrollbar-track { background: transparent; }

.folder-head {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 8px 18px 6px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--on-ink-3);
  text-align: left;
}
.folder-head:hover { color: #f6f5f1; }
.folder-head .chev { width: 9px; height: 9px; flex: none; transition: transform .22s var(--ease); }
.folder.collapsed .chev { transform: rotate(-90deg); }
.folder.collapsed .folder-body { display: none; }
.folder-name { flex: none; max-width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.folder-rule { flex: 1; height: 0; border-top: 1px solid var(--dark-rule); }
.folder-count { font-variant-numeric: tabular-nums; color: var(--on-ink-4); }
.folder-head.active { color: var(--accent); }

/* ligne de source : barre de teinte · marque · nom · compteur */
.feed-row {
  display: flex; align-items: center; width: 100%; text-align: left;
  transition: background .18s var(--ease);
}
.feed-row:hover { background: var(--dark-hov); }
.feed-row.active { background: var(--dark-hov); }

.feed-bar { width: 3px; height: 24px; flex: none; background: var(--teinte, var(--on-ink-4)); }
.feed-row.active .feed-bar { height: 28px; }

.feed-mark { position: relative; width: 15px; height: 15px; flex: none; margin-left: 12px; }
.feed-icon { width: 15px; height: 15px; object-fit: cover; display: block; }
.feed-icon.mono-mark {
  display: grid; place-items: center;
  background: var(--teinte, var(--on-ink-4));
  color: var(--teinte-texte, #f6f5f1);
  font-family: var(--display); font-size: 11px; line-height: 1;
}
/* La pastille de type détache la vidéo et le podcast de l'article simple. */
.feed-badge {
  position: absolute; right: -4px; bottom: -4px;
  width: 11px; height: 11px;
  display: grid; place-items: center;
  background: var(--index-bg);
}
.feed-badge svg { width: 9px; height: 9px; stroke: none; }

.feed-name {
  flex: 1; min-width: 0; padding: 5px 8px 5px 10px;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .02em;
  color: var(--on-ink-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Une source qui ne remonte plus d'elle-même se lit comme telle : le compteur
   passe en gris de fond pour le survol, et la ligne entière s'efface pour une
   source muette — elle est là, elle n'appelle plus. */
.feed-row.p-survol .feed-count { color: var(--on-ink-4); }
.feed-row.p-muet { opacity: .5; }
.feed-row.p-muet .feed-count { color: var(--on-ink-4); }
.feed-row.p-muet:hover, .feed-row.p-muet.active { opacity: 1; }

.feed-row:hover .feed-name, .feed-row.active .feed-name { color: #f6f5f1; }
.feed-row.error .feed-name { color: var(--on-ink-4); }
.feed-warn { flex: none; font-family: var(--mono); font-size: 9px; letter-spacing: .1em; color: #d63a2a; }

.feed-count {
  flex: none; padding-right: 14px;
  font-family: var(--mono); font-size: 10.5px; font-variant-numeric: tabular-nums;
  color: var(--on-ink-4);
}
.feed-edit { display: none; }

/* pied de l'index */
.index-foot {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 18px;
  border-top: 1px solid var(--dark-rule);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--on-ink-4);
}
.index-foot button { color: var(--on-ink-4); font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; }
.index-foot button:hover { color: #f6f5f1; }
.index-foot .grow { flex: 1; }
.index-foot .keys { width: 14px; height: 14px; }

/* ======================================================== barre d'outils */

.stage { display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.toolbar {
  height: 52px; flex: none;
  display: flex; align-items: center; gap: 18px;
  padding: 0 var(--gut) 0 0;
  background: var(--bone);
  border-bottom: 1px solid var(--ink);
}

.tabs { display: flex; height: 100%; }
.tab {
  display: flex; align-items: center; padding: 0 14px; height: 100%;
  border-right: 1px solid var(--bone-2);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--mute);
  transition: color .2s ease;
}
.tab:hover { color: var(--ink); }
.tab.active { background: var(--ink); color: var(--bone); }

.toolbar .grow { flex: 1; }

.toolbar-count {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--mute); white-space: nowrap;
}

.btn {
  padding: 6px 12px;
  border: 1px solid var(--ink);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink);
  transition: background .2s ease, color .2s ease, border-color .2s ease;
  white-space: nowrap;
}
.btn.solid { background: var(--ink); color: var(--bone); }
.btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }

.index-open { display: none; }

/* ========================================================== la manchette */

/* `relative` : le bouton d'étiquetage se pose en absolu là-dedans, donc il
   suit le défilement sans qu'on ait à le recalculer. */
.scroller { position: relative; flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; scroll-behavior: smooth; }
.scroller::-webkit-scrollbar { width: 10px; }
.scroller::-webkit-scrollbar-thumb { background: #c6c3b9; }
.scroller::-webkit-scrollbar-track { background: transparent; }

.masthead {
  display: flex; align-items: flex-end; gap: 24px; flex-wrap: wrap;
  padding: 26px var(--gut) 18px;
  border-bottom: 1px solid var(--ink);
}
.masthead h1 {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(46px, 6vw, 92px); line-height: .84; letter-spacing: -.035em;
  text-wrap: pretty;
}
.masthead-side { flex: 1; min-width: 180px; }
.masthead-rule { border-top: 1px solid var(--ink); }
.masthead-meta {
  display: flex; justify-content: space-between; gap: 12px; padding-top: 8px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--mute);
}

/* ================================================ mise en page « la une » */

/* La mise en page porte un préfixe : sans lui,  hériterait de la
   règle du bloc de une — hauteur figée et débordement masqué. */
.flux { display: block; }

/* Sans `both` : si l'animation ne joue pas (capture, moteur d'impression),
   l'état de repos du bloc est visible plutôt que transparent. */
.bloc { animation: ed-rise .5s var(--ease); }

/* --- la une plein cadre --- */
.une {
  position: relative;
  height: min(60vh, 540px);
  background: linear-gradient(168deg, var(--f1, var(--bone-2)), var(--f2, var(--bone-2)));
  overflow: hidden;
}
.une img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .9s var(--ease); }
.une:hover img { transform: scale(1.05); }
.une-voile {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(var(--voile), .9) 0%, rgba(var(--voile), .52) 34%, rgba(var(--voile), 0) 72%);
}
.une-tampon {
  position: absolute; left: 0; top: 0;
  padding: 7px 12px; background: var(--accent); color: #fff;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase;
}
.une-corps {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 20px var(--gut) 34px;
  text-align: left; width: 100%;
}
.une-sur {
  font-family: var(--mono); font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
  color: #c9c6bc;
}
.une-sur b { color: #f6f5f1; font-weight: 400; }
.une-titre {
  margin-top: 10px;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(38px, 5.4vw, 86px); line-height: .94; letter-spacing: -.03em;
  color: #f6f5f1; max-width: 20ch; text-wrap: pretty;
  transition: color .2s ease;
  /* Le titre doit rester dans la partie sombre du voile : au-delà de trois
     lignes il remonte sur l'image claire et devient illisible. */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.une-corps:hover .une-titre { color: var(--accent); }
.une-chapo {
  margin-top: 18px;
  font-family: var(--body); font-size: 17px; line-height: 1.5; font-weight: 300;
  color: #d5d2c9; max-width: 56ch;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* --- rangée de colonnes --- */
.cols {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  border-bottom: 3px solid var(--ink);
}
.col {
  display: flex; flex-direction: column;
  padding: 22px 22px 26px;
  border-left: 1px solid var(--rule-col);
  text-align: left;
}
.col:first-child { border-left: 0; }
.sur {
  font-family: var(--mono); font-size: 9px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--accent);
}
.sur .quand { color: var(--mute); }
.col-titre {
  margin-top: 10px;
  font-family: var(--display); font-weight: 400;
  font-size: 26px; line-height: 1.02; letter-spacing: -.02em;
  text-wrap: pretty; transition: color .2s ease;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.col:hover .col-titre, .une-corps:hover .une-titre { color: var(--accent); }
.wipe {
  margin: 12px 0; height: 0; border-top: 1px solid var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform .42s var(--ease);
}
.col:hover .wipe, .plaque:hover .wipe { transform: scaleX(1); }
.chapo {
  font-family: var(--body); font-size: 14.5px; line-height: 1.5; font-weight: 300;
  color: #4a4841;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
:root[data-theme='dark'] .chapo, :root[data-theme='auto'] .chapo { color: #b3b0a8; }
.col-pied {
  margin-top: auto; padding-top: 16px;
  font-family: var(--mono); font-size: 9px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--mute);
}

/* --- mur d'images --- */
.wall { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tuile {
  position: relative; height: 340px; overflow: hidden;
  background: linear-gradient(168deg, var(--f1, var(--bone-2)), var(--f2, var(--bone-2)));
  border-left: 1px solid var(--ink);
  text-align: left;
}
.tuile:first-child { border-left: 0; }
.tuile img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .9s var(--ease); }
.tuile:hover img { transform: scale(1.05); }
.tuile-voile {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(var(--voile), .88), rgba(var(--voile), .1) 62%);
}
.tuile-corps { position: absolute; left: 0; right: 0; bottom: 0; padding: 16px 20px 22px; }
.tuile-sur {
  font-family: var(--mono); font-size: 9px; letter-spacing: .2em; text-transform: uppercase;
  color: #c9c6bc;
}
.tuile-titre {
  margin-top: 8px;
  font-family: var(--display); font-weight: 400; font-size: 29px; line-height: 1.02; letter-spacing: -.02em;
  color: #f6f5f1; text-wrap: pretty;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.badge {
  position: absolute; right: 14px; top: 14px;
  padding: 4px 8px;
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .2em; text-transform: uppercase;
  background: rgba(246,245,241,.92); color: var(--ink);
}
.badge.video { background: var(--accent); color: #fff; }
.badge.audio { background: #f0a91d; color: var(--ink-deep); }

/* --- aplats et plaques typographiques --- */
.aplats {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  border-bottom: 3px solid var(--ink);
}

.aplat {
  position: relative; overflow: hidden;
  grid-column: span 2; min-height: 380px;
  padding: 26px 26px 24px;
  background: var(--teinte, var(--accent)); color: #f6f5f1;
  display: flex; flex-direction: column;
  text-align: left;
}
.aplat-initiale {
  position: absolute; right: -4%; bottom: -30%;
  font-family: var(--display); font-size: 400px; line-height: 1;
  color: rgba(246,245,241,.13); pointer-events: none; user-select: none;
}
.aplat .sur { color: rgba(246,245,241,.8); position: relative; }
.aplat-badge {
  display: inline-block; margin-left: 8px; padding: 2px 7px;
  background: #f6f5f1; color: var(--teinte, var(--accent));
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .16em;
}
.aplat-titre {
  position: relative; margin-top: 14px;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(34px, 3.4vw, 52px); line-height: .98; letter-spacing: -.025em;
  max-width: 22ch; text-wrap: pretty;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.aplat-pied {
  position: relative; margin-top: auto; padding-top: 20px;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 20px;
}
.aplat-chapo {
  font-family: var(--body); font-size: 16px; line-height: 1.5; font-weight: 300;
  color: rgba(246,245,241,.86); max-width: 46ch;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.aplat-duree { flex: none; font-family: var(--mono); font-size: 9px; letter-spacing: .18em; text-transform: uppercase; color: rgba(246,245,241,.8); }

.plaque {
  position: relative; overflow: hidden;
  min-height: 380px; padding: 22px;
  border-left: 1px solid var(--rule-col);
  display: flex; flex-direction: column;
  text-align: left;
}
.plaque.claire { background: var(--bone-2); }
.plaque.sombre { background: var(--ink-deep); }
.plaque-initiale {
  position: absolute; left: -2%; bottom: -24%;
  font-family: var(--display); font-size: 300px; line-height: 1;
  pointer-events: none; user-select: none;
}
.plaque.claire .plaque-initiale { color: rgba(36, 35, 31, .13); }
.plaque.sombre .plaque-initiale { color: var(--teinte-douce, rgba(246,245,241,.2)); }

.plaque-source {
  position: absolute; right: 12px; top: 26px;
  writing-mode: vertical-rl;
  font-family: var(--mono); font-size: 9px; letter-spacing: .24em; text-transform: uppercase;
}
.plaque.claire .plaque-source { color: var(--mute); }
.plaque.sombre .plaque-source { color: var(--on-ink-3); }

.plaque-corps { position: relative; padding-right: 24px; display: flex; flex-direction: column; height: 100%; }
.plaque .sur { color: var(--mute); }
.plaque.sombre .sur { color: var(--on-ink-3); }
.plaque-titre {
  margin-top: 10px;
  font-family: var(--display); font-weight: 400; font-size: 27px; line-height: 1.02; letter-spacing: -.02em;
  text-wrap: pretty; transition: color .2s ease;
  display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden;
}
.plaque.sombre .plaque-titre { color: var(--paper); }
.plaque:hover .plaque-titre { color: var(--accent); }
.plaque .wipe { border-top-color: var(--ink); margin-top: auto; }
.plaque.sombre .wipe { border-top-color: var(--on-ink-4); }
.plaque-pied {
  font-family: var(--mono); font-size: 9px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--mute);
}
.plaque.sombre .plaque-pied { color: var(--on-ink-3); }

/* --- dépêches en fin de page --- */
.fils-titre {
  display: flex; align-items: center; gap: 14px;
  padding: 26px var(--gut) 10px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .22em; text-transform: uppercase;
  color: var(--ink);
}
.fils-titre .rule { flex: 1; height: 0; border-top: 1px solid var(--ink); }
.fils-titre .reste { color: var(--mute); }

.fils {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 34px;
  padding: 0 var(--gut);
}

.fil {
  display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; gap: 14px;
  align-items: baseline; padding: 10px 0;
  border-bottom: 1px solid var(--rule-list);
  text-align: left;
}
.fil:hover { background: var(--bone-2); }
.fil-heure { font-family: var(--mono); font-size: 10px; font-variant-numeric: tabular-nums; color: var(--accent); }
.fil-titre {
  font-family: var(--body); font-size: 16px; line-height: 1.3; font-weight: 400;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fil-source { font-family: var(--mono); font-size: 9px; letter-spacing: .16em; text-transform: uppercase; color: var(--mute); }

.end-note {
  padding: 34px var(--gut) 60px; text-align: center;
  font-family: var(--display); font-style: italic; font-size: 19px; color: var(--mute);
}

/* =================================================== mise en page sommaire */

.flux.l-sommaire { padding: 16px var(--gut) 60px; }

.som {
  display: grid; grid-template-columns: 34px minmax(0, 1fr) 150px; gap: 24px;
  align-items: start; padding: 22px 0;
  border-bottom: 1px solid var(--rule-list);
  text-align: left; width: 100%;
}
.som-num {
  padding-top: 6px;
  font-family: var(--mono); font-size: 10px; font-variant-numeric: tabular-nums; color: var(--mute);
}
.som-titre {
  margin-top: 8px;
  font-family: var(--display); font-weight: 400; font-size: 30px; line-height: 1.04; letter-spacing: -.022em;
  text-wrap: pretty; transition: color .2s ease;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.som:hover .som-titre { color: var(--accent); }
.som-chapo {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  margin-top: 10px; font-family: var(--body); font-size: 15px; line-height: 1.5; font-weight: 300; color: #4a4841; max-width: 70ch;
}
:root[data-theme='dark'] .som-chapo, :root[data-theme='auto'] .som-chapo { color: #b3b0a8; }
.som-thumb { width: 150px; height: 104px; overflow: hidden; background: linear-gradient(168deg, var(--f1, var(--bone-2)), var(--f2, var(--bone-2))); }
.som-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .9s var(--ease); }
.som:hover .som-thumb img { transform: scale(1.05); }

/* =================================================== mise en page dépêches */

.flux.l-depeches { padding: 16px var(--gut) 60px; max-width: 1100px; }

.dep {
  display: grid; grid-template-columns: 9px 58px minmax(0, 1fr) 170px 46px; gap: 14px;
  align-items: baseline; padding: 9px 8px;
  border-bottom: 1px solid var(--rule-fil);
  text-align: left; width: 100%;
}
/* La seule inversion de la page : elle sert de curseur. */
.dep:hover, .dep.cursor { background: var(--ink); color: var(--bone); }
.dep:hover .dep-heure, .dep:hover .dep-source, .dep:hover .dep-duree,
.dep.cursor .dep-heure, .dep.cursor .dep-source, .dep.cursor .dep-duree { color: var(--bone); }

.dep-puce { width: 6px; height: 6px; align-self: center; background: var(--accent); }
.dep.read .dep-puce { background: transparent; }
.dep-heure { font-family: var(--mono); font-size: 10px; font-variant-numeric: tabular-nums; color: var(--mute); }
.dep-titre {
  font-family: var(--body); font-size: 16.5px; line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dep-source { font-family: var(--mono); font-size: 9px; letter-spacing: .16em; text-transform: uppercase; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dep-duree { font-family: var(--mono); font-size: 9px; text-align: right; color: var(--mute); }

/* ------------------------------------------------------- états de lecture */

.read .col-titre, .read .som-titre, .read .plaque-titre, .read .fil-titre, .read .dep-titre { color: var(--mute); }
.read img { filter: saturate(.35); opacity: .6; }
.bloc:hover.read img, .som:hover.read img { filter: none; opacity: 1; }

/* curseur clavier : un filet plein sur le bord gauche, pas de contour */
.cursor { position: relative; }
.col.cursor, .plaque.cursor, .som.cursor, .fil.cursor, .aplat.cursor, .tuile.cursor {
  box-shadow: inset 3px 0 0 0 var(--accent);
}
.une.cursor { box-shadow: inset 0 0 0 3px var(--accent); }

/* ---------------------------------------------------------- chargement */

.sk {
  background: linear-gradient(90deg, var(--bone-2) 25%, var(--rule-fil) 50%, var(--bone-2) 75%);
  background-size: 300% 100%;
  animation: shimmer 1.4s linear infinite;
}
@keyframes shimmer { to { background-position: -300% 0; } }
.sk.une { height: min(60vh, 540px); }
.sk.col { height: 260px; border-left: 1px solid var(--rule-col); background-image: none; background: var(--bone-2); }

.sentinel { height: 1px; }

/* ------------------------------------------------------------ état vide */

.empty { max-width: 620px; margin: 8vh auto; padding: 0 var(--gut); text-align: center; }
.empty h2 { font-family: var(--display); font-weight: 400; font-size: 46px; line-height: .96; letter-spacing: -.03em; }
.empty p { margin: 16px auto 26px; font-family: var(--body); font-size: 16px; line-height: 1.5; font-weight: 300; color: var(--mute); max-width: 44ch; }
.empty-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

.suggestions { margin-top: 40px; padding-top: 24px; border-top: 1px solid var(--ink); text-align: left; }
.suggestions h3 {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .22em; text-transform: uppercase;
  color: var(--mute); text-align: center; margin-bottom: 16px;
}
.suggestion-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 1px; background: var(--rule-col); border: 1px solid var(--rule-col); }
.suggestion {
  display: flex; align-items: center; gap: 8px; padding: 11px 13px;
  background: var(--bone);
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  text-align: left;
}
.suggestion:hover { background: var(--ink); color: var(--bone); }
.suggestion .plus { margin-left: auto; color: var(--accent); }
.suggestion:hover .plus { color: var(--bone); }
.suggestion.done { opacity: .45; pointer-events: none; }

/* ============================================================== lecteur */

/* Le lecteur est un panneau, pas un plein écran : il laisse voir la liste sur
   sa gauche, et cliquer cette lisière referme. La mesure de lecture reste à
   66ch, donc l'espace utile ne perd rien à ce compromis. */
.reader-shade {
  position: fixed; inset: 0; z-index: 59;
  background: rgba(var(--voile), .5);
  animation: ed-fade .24s var(--ease);
}

.reader {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 60;
  width: min(1080px, calc(100vw - 180px));
  display: flex; flex-direction: column;
  background: var(--bone);
  border-left: 1px solid var(--ink);
  animation: ed-slide .34s var(--ease);
}

@keyframes ed-slide { from { opacity: 0; transform: translateX(30px); } }

.reader-progress {
  position: absolute; left: 0; top: 0; height: 3px; z-index: 3;
  width: 0; background: var(--accent);
  transition: width .1s linear;
}

.reader-bar {
  flex: none; height: 52px;
  display: flex; align-items: center; gap: 16px;
  padding: 0 22px;
  background: var(--ink-deep); color: var(--paper);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase;
}
.reader-bar button, .reader-bar a {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase;
  color: #f6f5f1; white-space: nowrap;
  transition: color .2s ease;
}
.reader-bar button:hover, .reader-bar a:hover { color: var(--accent); }
#readerClose { display: inline-flex; align-items: baseline; gap: 7px; }
.reader-bar .sep { width: 1px; height: 20px; background: var(--dark-rule); flex: none; }
.reader-bar .infos { min-width: 0; color: var(--on-ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reader-bar .grow { flex: 1; }
.reader-bar .original {
  padding: 6px 12px; background: var(--paper); color: var(--ink-deep);
}
.reader-bar .original:hover { background: var(--accent); color: #fff; }
.reader-bar button.on { color: var(--accent); }

/* pan-y : le défilement vertical reste au navigateur, la direction horizontale
   est réservée au glissé (glisse.js). Sans ça, le navigateur dispute le geste
   au doigt et le glissé se fige à mi-course. */
/* overflow-x explicite, et surtout pas laissé implicite : déclarer le seul
   overflow-y fait calculer l'autre axe en « auto » (la règle CSS : un axe non
   « visible » force l'autre à sortir de « visible »). Le panneau passait donc
   pour une zone à défilement horizontal dès qu'un article débordait de deux
   pixels — une image large, une URL insécable —, et le glissé, qui cède la
   priorité à ces zones-là, mourait sur cet article. Le lecteur défile
   verticalement, point ; ce qui dépasse est rogné plutôt que de faire dériver
   la page de côté. */
.reader-scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; scroll-behavior: smooth; touch-action: pan-y; }
.reader-scroll::-webkit-scrollbar { width: 10px; }
.reader-scroll::-webkit-scrollbar-thumb { background: #c6c3b9; }

/* bandeau d'ouverture */
.reader-hero { position: relative; height: min(52vh, 460px); background: linear-gradient(168deg, var(--f1, var(--bone-2)), var(--f2, var(--bone-2))); overflow: hidden; }
.reader-hero img { width: 100%; height: 100%; object-fit: cover; display: block; }
.reader-hero .voile {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(var(--voile), .92) 0%, rgba(var(--voile), .4) 42%, rgba(var(--voile), 0) 80%);
}
.reader-hero-corps {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 0 40px 36px;
}
.reader-hero-inner { max-width: 900px; margin: 0 auto; }
.reader-badge {
  display: inline-block; padding: 4px 9px; background: var(--accent); color: #fff;
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .2em; text-transform: uppercase;
}
.reader-meta {
  margin-top: 12px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .18em; text-transform: uppercase;
  color: #c9c6bc;
}
.reader-titre {
  margin-top: 12px;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(38px, 4.6vw, 72px); line-height: .96; letter-spacing: -.03em;
  color: #f6f5f1; max-width: 26ch; text-wrap: pretty;
}

/* Le bandeau devient une plaque quand l'article n'a pas d'illustration. Il n'a
   alors pas de voile pour assombrir le fond : le texte se pose directement sur
   la teinte de la source. Or deux des huit teintes sont des neutres clairs —
   Libération tombe sur #f6f5f1 — et un titre blanc y devenait invisible. La
   couleur du texte est donc calculée d'après la luminance de la plaque, comme
   pour les aplats de la une. */
.reader-hero.plaque-hero { background: var(--teinte, var(--ink-deep)); color: var(--sur-plaque, #f6f5f1); }
.reader-hero.plaque-hero .reader-titre,
.reader-hero.plaque-hero .reader-meta { color: inherit; }
.reader-hero.plaque-hero .reader-meta { opacity: .72; }
.reader-hero.plaque-hero .plaque-initiale {
  font-size: 420px; left: -1%; bottom: -34%; color: currentColor; opacity: .14;
}
/* Une vidéo n'a pas besoin d'une ouverture pleine hauteur : le lecteur doit
   arriver tout de suite, sinon on scrolle pour rien. */
.reader-hero.hero-video { height: min(30vh, 230px); }
.reader-hero.hero-video .plaque-initiale { font-size: 230px; bottom: -30%; }

.reader-inner { max-width: var(--colonne, 66ch); margin: 0 auto; padding: 0 20px 90px; }

/* étiquettes du lecteur */
.tag-editor {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 18px 0; border-bottom: 1px solid var(--rule-list);
}
/* Les actions ferment la ligne, à droite : les étiquettes posées se lisent en
   premier, ce sont elles qui portent l'information. */
.tag-editor .actions-icones { margin-left: auto; }
.tag-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 4px 9px;
  background: var(--teinte, var(--accent)); color: #fff;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
}
.tag-jump { color: inherit; font: inherit; letter-spacing: inherit; }
.tag-off { color: #fff; opacity: .7; font-size: 11px; line-height: 1; }
.tag-off:hover { opacity: 1; }
.tag-input {
  padding: 4px 9px; width: 130px;
  border: 1px dashed #b6b3a9; background: none; color: var(--mute);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
}
.tag-input::placeholder { color: var(--mute); }
.tag-input:focus { outline: none; border-style: solid; border-color: var(--accent); color: var(--ink); width: 190px; }

.reader-sources {
  padding-top: 18px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--mute);
}

/* ------------------------------------ étiquettes posées dans les cartes --- */

.art-etiqs { display: inline-flex; flex-wrap: wrap; gap: 4px; vertical-align: middle; }
.art-etiqs:empty { display: none; }
/* Dans un pied qui porte déjà du texte, les pastilles s'en écartent. */
.col-pied .art-etiqs, .plaque-pied .art-etiqs, .dep .art-etiqs, .fil .art-etiqs { margin-left: 8px; }
.aplat-duree .art-etiqs { margin-right: 8px; }
.une-corps .art-etiqs, .tuile-corps .art-etiqs, .som .art-etiqs { margin-top: 10px; }

.art-etiq {
  padding: 2px 6px 1px;
  color: #fff;
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .14em; text-transform: uppercase;
  white-space: nowrap;
}

/* Le bouton qui suit la carte survolée. Plutôt que de se poser par-dessus la
   méta de droite, il prend sa place : elle s'efface le temps du survol. Rien ne
   se superpose, et aucune ligne ne bouge. */
.dep-source, .fil-source, .aplat-duree { transition: opacity .16s var(--ease); }
.art.survol .dep-source, .art.survol .fil-source, .art.survol .aplat-duree { opacity: 0; }
/* La dépêche reste inversée tant que la souris est sur le bouton, sinon la
   ligne clignoterait au moment précis où on va cliquer. */
.dep.survol { background: var(--ink); color: var(--bone); }
.dep.survol .dep-heure, .dep.survol .dep-source, .dep.survol .dep-duree { color: var(--bone); }
.fil.survol { background: var(--bone-2); }

/* La paire de pictogrammes : deux carrés d'encre séparés d'un filet, comme
   partout ailleurs dans la page. Le libellé écrit prenait la largeur d'un titre
   de dépêche. Même paire au coin des cartes et sous le titre dans le lecteur —
   c'est la même action, elle doit se présenter pareil. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.actions-icones { display: flex; flex: none; }
.actions-icones button {
  display: grid; place-items: center; width: 28px; height: 26px;
  background: var(--ink-deep); color: #f6f5f1;
  transition: background .18s var(--ease);
}
.actions-icones button + button { box-shadow: -1px 0 0 rgba(246, 245, 241, .22); }
.actions-icones svg { width: 14px; height: 14px; stroke-width: 1.6; }
.actions-icones button:hover { background: var(--accent); }

.art-actions { position: absolute; z-index: 6; }
/* Une dépêche survolée s'inverse en encre : les boutons s'inversent à leur tour,
   sinon ils disparaîtraient dans la ligne. */
.art-actions.sur-depeche button { background: var(--paper); color: var(--ink-deep); }
.art-actions.sur-depeche button + button { box-shadow: -1px 0 0 rgba(27, 26, 23, .22); }
.art-actions.sur-depeche button:hover { background: var(--accent); color: #fff; }

/* Le popover d'étiquetage. */
.tagpop {
  position: fixed; z-index: 70; width: 264px;
  display: flex; flex-direction: column;
  background: var(--bone); border: 1px solid var(--ink);
  animation: ed-fade .16s var(--ease);
}
.tagpop-titre {
  margin: 0; padding: 11px 13px 9px; border-bottom: 1px solid var(--rule-list);
  font-family: var(--mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--mute);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.tagpop-list { max-height: 260px; overflow-y: auto; }
.tagpop-row {
  display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 13px;
  text-align: left;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em;
  color: var(--mute);
  transition: background .14s var(--ease);
}
.tagpop-row:hover { background: var(--bone-2); }
.tagpop-row.on { color: var(--ink); }
/* Un pictogramme devant chaque destination : à la lecture rapide, c'est lui
   qu'on vise, pas le mot. */
.tagpop-glyphe { width: 13px; height: 13px; flex: none; stroke-width: 1.6; color: var(--mute); }
.tagpop-row:hover .tagpop-glyphe { color: var(--accent); }
.tagpop-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tagpop-coche { flex: none; color: var(--accent); }
.tagpop-vide { margin: 0; padding: 14px 13px; font-family: var(--body); font-size: 13px; color: var(--mute); }
.tagpop-input {
  border: 0; border-top: 1px solid var(--rule-list); padding: 10px 13px;
  background: none; color: var(--ink);
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
}
.tagpop-input::placeholder { color: var(--mute); }
.tagpop-input:focus { outline: none; background: var(--bone-2); }

/* corps de l'article */
.reader-body {
  margin-top: 40px;
  /* Trois réglages de lecture, posés sur :root par l'amorce avant le premier
     rendu. Un lecteur qu'on utilise une heure par jour doit se régler à l'œil
     de chacun — et c'est un réglage d'écran, pas de compte, comme le thème. */
  font-family: var(--body); font-size: var(--corps, 19.5px); line-height: var(--interligne, 1.68);
  font-weight: 400;
  color: #1a1917;
  overflow-wrap: break-word;
}
:root[data-theme='dark'] .reader-body, :root[data-theme='auto'] .reader-body { color: #ddd9d0; }

.reader-body p.lettrine::first-letter {
  float: left; font-family: var(--display); font-size: 5.2em; line-height: .76;
  padding: .02em .1em 0 0; color: var(--accent);
}
.reader-body p { margin: 0 0 1.15em; }
.reader-body h1, .reader-body h2, .reader-body h3, .reader-body h4 {
  margin: 1.8em 0 .5em; font-family: var(--display); font-weight: 400; line-height: 1.06; letter-spacing: -.02em;
}
.reader-body h1 { font-size: 1.7em; }
.reader-body h2 { font-size: 1.45em; }
.reader-body h3 { font-size: 1.2em; }
.reader-body a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.reader-body img, .reader-body video, .reader-body iframe, .reader-body audio {
  max-width: 100%; display: block; margin: 1.8em auto;
}
.reader-body iframe { width: 100%; aspect-ratio: 16/9; height: auto; border: 0; }
.reader-body audio { width: 100%; margin: 0 0 1.8em; }
.reader-body figure { margin: 2em 0; }
.reader-body figcaption {
  margin-top: 10px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--mute); text-align: center;
}
.reader-body blockquote {
  margin: 1.8em 0; padding-left: 22px; border-left: 2px solid var(--accent);
  font-style: italic; color: #4a4841;
}
:root[data-theme='dark'] .reader-body blockquote, :root[data-theme='auto'] .reader-body blockquote { color: #b3b0a8; }
.reader-body ul, .reader-body ol { margin: 0 0 1.15em; padding-left: 1.3em; }
.reader-body li { margin-bottom: .4em; }
.reader-body pre {
  margin: 1.6em 0; padding: 16px 18px;
  background: var(--bone-2); border: 1px solid var(--ink);
  overflow-x: auto; font-family: var(--mono); font-size: 12.5px; line-height: 1.6;
  /* Un bloc de code garde son propre défilement horizontal, que le pan-y du
     lecteur lui retirerait sinon ; le glissé du doigt lui cède déjà la
     priorité (dansUnDefilementHorizontal). */
  touch-action: pan-x;
}
.reader-body code { font-family: var(--mono); font-size: .8em; background: var(--bone-2); padding: 1px 5px; }
.reader-body pre code { background: none; padding: 0; }
.reader-body hr { margin: 2.2em 0; border: 0; border-top: 1px solid var(--rule-list); }
.reader-body table { width: 100%; border-collapse: collapse; margin: 1.6em 0; font-family: var(--mono); font-size: 12px; }
.reader-body th, .reader-body td { padding: 8px 10px; border: 1px solid var(--rule-list); text-align: left; }

/* bandeau du texte complet en cours */
.full-state {
  display: flex; align-items: center; gap: 10px;
  margin: 24px 0 0; padding: 10px 14px;
  background: var(--bone-2);
  border: 1px solid var(--ink); border-left: 3px solid var(--accent);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink);
}
.link-btn { color: var(--accent); font: inherit; letter-spacing: inherit; text-decoration: underline; }

.reader-end {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 46px; padding-top: 22px; border-top: 1px solid var(--ink);
}
.reader-end .next-hint {
  margin-left: auto;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--mute);
}

/* =========================================================== fenêtres */

/* Les fenêtres sont des <dialog> : le voile est son ::backdrop, le piège à
   focus et le retour du focus sont donnés par le navigateur. */
.modal::backdrop { background: rgba(27, 26, 22, .52); animation: ed-fade .2s var(--ease); }

.modal {
  position: fixed; z-index: 71; top: 50%; left: 50%; transform: translate(-50%, -50%);
  /* Le navigateur applique aux <dialog> ses propres `inset: 0` et `margin: auto`.
     Quand le contenu depasse la hauteur disponible, ce `margin: auto` repartit
     l'excedent en marges NEGATIVES, qui remontaient la fenetre au-dessus du bord
     de l'ecran : le haut des reglages etait alors inatteignable, tandis qu'il
     restait du vide en dessous. On rend donc la main a top/left et au decalage. */
  margin: 0; bottom: auto; right: auto;
  width: min(500px, calc(100vw - 32px));
  max-height: min(86vh, 820px); overflow-y: auto;
  padding: 28px 30px;
  background: var(--bone); color: var(--ink); border: 1px solid var(--ink);
  animation: ed-up .3s var(--ease);
}
/* Un <dialog> fermé ne s'affiche pas, et ouvert il redevient un bloc :
   sans ça, `display: none` du navigateur l'emporterait sur la mise en page. */
.modal:not([open]) { display: none; }
.modal.wide { width: min(660px, calc(100vw - 32px)); }
.modal h2 {
  font-family: var(--display); font-weight: 400; font-size: 34px; line-height: 1; letter-spacing: -.025em;
}
.modal-hint {
  margin: 12px 0 22px;
  font-family: var(--body); font-size: 14.5px; line-height: 1.5; font-weight: 300; color: var(--mute);
}

.field { display: block; margin-bottom: 18px; }
.field > span {
  display: block; margin-bottom: 7px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink);
}
.field > span small { text-transform: none; letter-spacing: .04em; color: var(--mute); }
.field input, .field select {
  width: 100%; padding: 10px 12px;
  background: var(--paper); border: 1px solid var(--ink);
  font-family: var(--mono); font-size: 11.5px; color: var(--ink);
}
:root[data-theme='dark'] .field input, :root[data-theme='dark'] .field select,
:root[data-theme='auto'] .field input, :root[data-theme='auto'] .field select { background: var(--bone-2); }
.field input:focus, .field select:focus { outline: none; border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.field-note { margin-top: 7px; font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; color: var(--mute); overflow-wrap: anywhere; }

.modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 24px; }
.modal-actions.spread { justify-content: flex-start; }
.modal-actions .grow { flex: 1; }

.modal-sep {
  display: flex; align-items: center; gap: 12px; margin: 24px 0 16px;
  font-family: var(--mono); font-size: 9px; letter-spacing: .22em; text-transform: uppercase; color: var(--mute);
}
.modal-sep::before, .modal-sep::after { content: ''; flex: 1; border-top: 1px solid var(--rule-list); }

.modal-io { display: flex; gap: 10px; flex-wrap: wrap; }

/* choix de l'accent */
.accent-choices { display: flex; gap: 10px; }
.accent-swatch {
  width: 34px; height: 34px; flex: none;
  background: var(--teinte);
  border: 1px solid var(--ink);
  transition: transform .18s var(--ease);
}
.accent-swatch:hover { transform: translateY(-2px); }
.accent-swatch.on { box-shadow: inset 0 0 0 3px var(--bone); }

/* raccourcis */
.keys { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 26px 30px; }
.keys h3 {
  margin-bottom: 12px; padding-bottom: 7px; border-bottom: 1px solid var(--ink);
  font-family: var(--mono); font-size: 9px; letter-spacing: .22em; text-transform: uppercase; color: var(--accent);
}
.keys dl { display: grid; grid-template-columns: auto 1fr; gap: 9px 12px; align-items: baseline; }
.keys dt { display: flex; gap: 4px; justify-content: flex-end; }
.keys dd { font-family: var(--mono); font-size: 10px; letter-spacing: .06em; color: var(--mute); }

kbd {
  display: inline-block; min-width: 20px; padding: 2px 6px;
  background: var(--bone-2); border: 1px solid var(--ink);
  font-family: var(--mono); font-size: 9.5px; text-align: center; color: var(--ink);
}

/* gestionnaire d'étiquettes */
.tag-create { display: flex; gap: 8px; margin-bottom: 20px; }
.tag-create input {
  flex: 1; padding: 10px 12px; background: var(--paper); border: 1px solid var(--ink);
  font-family: var(--mono); font-size: 11.5px;
}
:root[data-theme='dark'] .tag-create input, :root[data-theme='auto'] .tag-create input { background: var(--bone-2); }
.tag-create input:focus { outline: none; border-color: var(--accent); }

.tag-manager { display: flex; flex-direction: column; }
.tag-manage { padding: 14px 0; border-bottom: 1px solid var(--rule-list); }
.tag-manage:last-child { border-bottom: 0; }
.tag-manage-head { display: flex; align-items: center; gap: 10px; }
.tag-rename {
  flex: 1; min-width: 0; padding: 5px 8px;
  background: none; border: 1px solid transparent;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em; color: var(--ink);
}
.tag-rename:hover { border-color: var(--rule-list); }
.tag-rename:focus { outline: none; background: var(--paper); border-color: var(--accent); }
:root[data-theme='dark'] .tag-rename:focus, :root[data-theme='auto'] .tag-rename:focus { background: var(--bone-2); }
.tag-usage { flex: none; font-family: var(--mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--mute); }
.tag-delete { flex: none; width: 22px; height: 22px; font-size: 14px; line-height: 1; color: var(--mute); }
.tag-delete:hover { background: var(--ink); color: var(--bone); }
.tag-palette { display: flex; gap: 6px; margin: 10px 0 0 8px; }
.tag-swatch { width: 16px; height: 16px; background: var(--teinte); border: 1px solid var(--ink); }
.tag-swatch.on { box-shadow: inset 0 0 0 2px var(--bone); }

/* rapport de réparation */
.repair-list { display: flex; flex-direction: column; }
.repair-row {
  display: grid; grid-template-columns: 1fr auto; gap: 12px; align-items: start;
  padding: 14px 0; border-bottom: 1px solid var(--rule-list);
}
.repair-row:last-child { border-bottom: 0; }
.repair-name { font-family: var(--mono); font-size: 11px; letter-spacing: .08em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.repair-detail { margin-top: 5px; font-family: var(--body); font-size: 14px; line-height: 1.45; font-weight: 300; color: var(--mute); }
.repair-detail b { color: var(--ink); font-weight: 400; }
.repair-url { font-family: var(--mono); font-size: 9.5px; color: var(--mute); overflow-wrap: anywhere; }
.repair-cand { display: flex; align-items: flex-start; gap: 10px; margin-top: 8px; }
.repair-tag {
  flex: none; padding: 3px 8px;
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .16em; text-transform: uppercase;
}
.repair-tag.ok { background: var(--accent); color: #fff; }
.repair-tag.nok { background: var(--bone-2); color: var(--mute); }

/* ============================================================== toasts */

.toasts {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 80;
  display: flex; flex-direction: column-reverse; gap: 8px; align-items: center; pointer-events: none;
}
.toast {
  padding: 10px 18px; background: var(--ink-deep); color: var(--paper);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
  animation: ed-up .28s var(--ease); pointer-events: auto;
}
.toast.bad { background: #d63a2a; color: #fff; }
.toast.out { animation: ed-fade .28s var(--ease) reverse forwards; }

/* « Annuler », après un marquage en masse : un filet posé dans le message
   lui-même, séparé du texte par un filet et souligné comme un lien. */
.toast-action {
  font: inherit; letter-spacing: inherit; text-transform: inherit;
  color: inherit; margin-left: 14px; padding-left: 14px;
  border-left: 1px solid rgba(246, 245, 241, .3);
  text-decoration: underline; text-underline-offset: 3px;
}
.toast-action:hover { color: var(--accent); }

/* L'édition du jour ouvre l'index : c'est la pile qu'on peut finir. Sa marque
   est pleine, là où les autres vues n'ont qu'un contour. */
.view-row.edition .view-mark { background: var(--accent); border-color: var(--accent); }
.view-row.edition .view-label { font-family: var(--display); font-size: 17px; letter-spacing: 0; text-transform: none; }
/* Édition du jour terminée : la coche dit « à jour », pas un zéro éteint. */
.view-row.edition.finie .view-count { color: var(--accent); font-size: 13px; }

/* Ce qui est arrivé pendant qu'on lisait. Un filet à l'accent, pas une
   fenêtre : c'est une nouvelle, pas une interruption. */
.nouveautes {
  display: block; width: 100%;
  margin: 0 0 2px; padding: 11px var(--gut);
  background: var(--accent); color: #f6f5f1;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase;
  text-align: left;
  animation: ed-rise .3s var(--ease);
}
.nouveautes:hover { filter: brightness(1.12); }

/* ---------------------------------------------------------- les cartes */

/* Une carte est un <article>, plus un <button> : c'est le titre qui porte le
   lien. Elle reste cliquable en entier, et le curseur le dit. */
.art { position: relative; cursor: pointer; }
.art-lien {
  color: inherit; text-decoration: none;
  /* Le titre reste le titre : le lien ne doit rien changer à sa composition. */
  font: inherit; letter-spacing: inherit; display: inline;
}
.art-lien:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Le curseur clavier ne se signalait que par une teinte. Un filet à l'accent
   le dit aussi à qui ne distingue pas les couleurs. */
.art.cursor { box-shadow: inset 3px 0 0 var(--accent); }
.dep.cursor, .fil.cursor { box-shadow: none; }

/* La source qu'on déplace s'efface le temps du geste : ce qu'on suit des yeux,
   c'est la place qu'elle va prendre, pas elle. */
.feed-row.emportee { opacity: .35; }
.feed-row[draggable="true"] { -webkit-user-drag: element; }

/* ------------------------------------------------ réglages de lecture */

.curseurs { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }
.curseurs label { display: grid; grid-template-columns: 78px minmax(0, 1fr) 74px; gap: 10px; align-items: center; }
.curseurs label > span, .curseurs output {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--mute);
}
.curseurs output { text-align: right; font-variant-numeric: tabular-nums; }
.curseurs input[type="range"] { -webkit-appearance: none; appearance: none; background: none; height: 14px; }
.curseurs input[type="range"]::-webkit-slider-runnable-track { height: 1px; background: var(--rule-col); }
.curseurs input[type="range"]::-moz-range-track { height: 1px; background: var(--rule-col); }
.curseurs input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 10px; height: 10px; margin-top: -4.5px; background: var(--ink); border: 0;
}
.curseurs input[type="range"]::-moz-range-thumb { width: 10px; height: 10px; background: var(--ink); border: 0; border-radius: 0; }

.lien-sobre { font: inherit; color: var(--mute); text-decoration: underline; text-underline-offset: 3px; }
.lien-sobre:hover { color: var(--accent); }

/* ------------------------------------------------------------ baladeur */

/* Un seul lecteur, en pied de page : fermer l'article ne coupe pas l'écoute. */
.baladeur {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
  display: grid; grid-template-columns: 34px minmax(0, 1fr) minmax(220px, 340px) auto auto;
  gap: 14px; align-items: center;
  padding: 9px 16px;
  background: var(--ink-deep); color: var(--paper);
  border-top: 1px solid var(--dark-rule);
}
.baladeur button { color: var(--paper); font-family: var(--mono); font-size: 11px; }
.baladeur button:hover { color: var(--accent); }
#baladeurJouer { font-size: 14px; text-align: left; }
.baladeur-quoi { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.baladeur-titre {
  font-family: var(--body); font-size: 15px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.baladeur-source, .baladeur-temps {
  font-family: var(--mono); font-size: 9px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--on-ink-3);
}
.baladeur-temps { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* La ligne de temps : l'écoulé, la jauge, et ce qu'il reste. Les deux nombres
   encadrent la jauge plutôt que de la suivre — on lit d'un coup d'œil où l'on
   en est et combien il reste, sans avoir à soustraire. */
.baladeur-piste { display: flex; align-items: center; gap: 10px; min-width: 0; }
.baladeur-piste .baladeur-barre { flex: 1; min-width: 0; }
.baladeur-reste { color: var(--on-ink-2); }

/* La jauge : un filet, un curseur carré — pas de pilule. */
.baladeur-barre { -webkit-appearance: none; appearance: none; background: none; height: 14px; }
.baladeur-barre::-webkit-slider-runnable-track { height: 2px; background: var(--dark-rule); }
.baladeur-barre::-moz-range-track { height: 2px; background: var(--dark-rule); }
.baladeur-barre::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 9px; height: 9px; margin-top: -3.5px; background: var(--accent); border: 0;
}
.baladeur-barre::-moz-range-thumb { width: 9px; height: 9px; background: var(--accent); border: 0; border-radius: 0; }

/* La scène rend la hauteur du baladeur, pour que rien ne passe dessous. */
.app.avec-baladeur .scroller { padding-bottom: 58px; }

/* Dans le lecteur, l'épisode s'écoute par un bouton : c'est le baladeur qui joue. */
.btn.ecouter { margin: 4px 0 18px; }

@media (max-width: 720px) {
  /* Au doigt, la ligne de temps passe en dessous plutôt que de disparaître.
     Elle était masquée faute de place sur une seule rangée — mais un épisode de
     deux heures sans jauge ni décompte, c'est écouter à l'aveugle : on ne sait
     ni où l'on en est, ni combien il reste, et on ne peut pas se déplacer.
     Le baladeur gagne donc une seconde rangée, pleine largeur. */
  .baladeur { grid-template-columns: 30px minmax(0, 1fr) auto auto; gap: 6px 10px; padding: 8px 12px 10px; }
  /* Chaque élément à sa place, sans quoi la ligne de temps — qui prend toute la
     largeur — repousse la vitesse et la fermeture sur une troisième rangée.
     Les commandes tiennent sur la première, la ligne de temps occupe la seconde. */
  #baladeurJouer { grid-area: 1 / 1; }
  .baladeur-quoi { grid-area: 1 / 2; }
  #baladeurVitesse { grid-area: 1 / 3; }
  #baladeurFermer { grid-area: 1 / 4; }
  .baladeur-piste { grid-area: 2 / 1 / 3 / -1; gap: 12px; }
  /* Le baladeur a grandi d'une rangée : la scène lui rend cette hauteur, sinon
     la fin de la liste passerait dessous. */
  .app.avec-baladeur .scroller { padding-bottom: 78px; }
}

/* ---------------------------------------------------------------- débit */

.debit { display: flex; flex-direction: column; margin: 10px 0 12px; max-height: 320px; overflow-y: auto; }
.debit-ligne {
  display: grid; grid-template-columns: minmax(0, 1fr) 64px auto 64px;
  gap: 10px; align-items: center;
  padding: 7px 0; border-top: 1px solid var(--rule-list);
}
.debit-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; }
.debit-etat, .debit-chiffres {
  font-family: var(--mono); font-size: 9px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--mute);
}
/* La part lue, en clair : une barre courte est une source qu'on ne lit pas. */
.debit-barre { display: block; height: 3px; background: var(--rule-col); }
.debit-barre span { display: block; height: 100%; background: var(--accent); }
.debit-ligne.propose .debit-nom { font-weight: 600; }
.debit-ligne button {
  font-family: var(--mono); font-size: 9px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent); text-align: right;
}
.debit-ligne button:hover { text-decoration: underline; text-underline-offset: 3px; }

/* --------------------------------------------------------------- règles */

.regles-liste { display: flex; flex-direction: column; margin-bottom: 12px; }
.regle {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto;
  gap: 10px; align-items: center;
  padding: 9px 0; border-top: 1px solid var(--rule-list);
}
.regle.eteinte { opacity: .45; }
.regle-quoi { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.regle-quoi b { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.regle-ou, .regle-compte {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--mute);
}
.regle button {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--mute);
}
.regle button:hover { color: var(--ink); }
.regle .lien-danger:hover { color: #d63a2a; }

.regle-neuve { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.regle-neuve input[type="text"] { flex: 1 1 190px; min-width: 0; }
/* Bornés : sans ça, « de toutes les sources » et les noms de sources longs
   poussaient le menu sur toute la largeur et cassaient la ligne. */
.regle-neuve select { flex: 0 1 auto; max-width: 170px; }
.regle-neuve .btn { flex: 0 0 auto; }

/* Le classement des résultats : deux mots, celui qui tient étant souligné.
   Pas de boutons dessinés — c'est une nuance de lecture, pas une commande. */
.tri { display: inline-flex; gap: 12px; }
.tri button {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--mute);
}
.tri button.on { color: var(--ink); text-decoration: underline; text-underline-offset: 4px; }
.tri button:hover { color: var(--accent); }

/* Le mot cherché, dans l'extrait d'un résultat. */
mark {
  background: none; color: inherit; font-weight: 600;
  box-shadow: inset 0 -.45em 0 color-mix(in srgb, var(--accent) 22%, transparent);
}

/* ============================================================ responsive */

@media (max-width: 1280px) {
  .cols, .aplats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .aplat { grid-column: span 2; }
  .col:nth-child(3) { border-left: 0; }
  .wall { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fils { grid-template-columns: 1fr; }
}

@media (max-width: 1100px) {
  .reader { width: calc(100vw - 72px); }
}

@media (max-width: 720px) {
  /* Sur un téléphone, une lisière de 72 px se toucherait par accident :
     le panneau prend tout, on referme par ✕ ou Échap. */
  .reader { width: 100vw; border-left: 0; }

  /* Le panneau couvre tout l'écran : le voile derrière lui n'a plus à laisser
     deviner la liste, il devient un fond plein. Sans ça, le glissé découvre la
     liste par en dessous et le passage perd sa netteté — on voit deux choses à
     la fois au lieu d'une carte qui s'en va. */
  .reader-shade { background: var(--ink-deep); }

  /* Le bandeau tient sur une ligne en se délestant. Partent : la méta, que le
     titre juste en dessous répète ; « Texte complet », qui se récupère de toute
     façon tout seul à l'ouverture ; et « Non lu », qui ne sert qu'à revenir en
     arrière. Restent fermer, étiqueter, mettre en favori et ouvrir l'original. */
  .reader-bar { padding: 0 10px 0 4px; gap: 12px; }

  /* Au doigt, une croix de 9,5 px ne se vise pas. Elle grossit et prend une
     cible carrée d'environ 44 px — la taille sous laquelle on rate. Le mot
     « Fermer » part : la croix seule se comprend, et la place profite au reste. */
  #readerClose {
    width: 44px; height: 44px; flex: none;
    display: grid; place-items: center; gap: 0;
  }
  #readerClose .croix { font-size: 19px; line-height: 1; }
  #readerClose .mot { display: none; }
  .reader-bar .sep,
  .reader-bar .infos,
  #readerFull,
  #readerUnread { display: none; }
}

@media (max-width: 860px) {
  :root { --gut: 18px; }

  /* `1fr` vaut `minmax(auto, 1fr)`, et ce minimum automatique est la largeur
     minimale du contenu : la barre d'outils en réclamait 656, la colonne
     s'élargissait d'autant et toute la page se mettait à défiler latéralement.
     `minmax(0, 1fr)` autorise la colonne à descendre sous son contenu. */
  .app { grid-template-columns: minmax(0, 1fr); }
  .stage { min-width: 0; }

  /* La barre garde toutes ses commandes, mais serrées — et si l'écran est
     vraiment étroit, c'est elle qui défile, plus la page entière. */
  .toolbar {
    gap: 7px; padding-right: 10px;
    overflow-x: auto; scrollbar-width: none;
  }
  .toolbar::-webkit-scrollbar { display: none; }
  .toolbar .tab { padding: 0 7px; letter-spacing: .04em; font-size: 9px; }
  .toolbar .btn { padding: 6px 8px; letter-spacing: .06em; font-size: 8.5px; }
  /* « ＋ Source » quitte la barre : l'ajout reste à portée par le « + » du
     kiosque, dans l'index. Deux chemins pour la même chose ne valent pas
     d'expulser « Tout lire » hors de l'écran. */
  #addFeedBtn { display: none; }
  /* L'index passe en tiroir plein écran : plus rien à redimensionner ni à
     replier, le tiroir se ferme déjà par sa croix. */
  .index-poignee, .index-plier { display: none; }

  .index {
    position: fixed; inset: 0; z-index: 50;
    transform: translateX(-102%);
    transition: transform .32s var(--ease);
  }
  .app.rail-on .index { transform: none; }
  .index-open { display: flex; align-items: center; padding: 0 11px; height: 100%; border-right: 1px solid var(--bone-2); }
  .index-head .index-close { display: block; color: var(--on-ink-1); font-family: var(--mono); font-size: 12px; }

  .cols, .aplats, .wall { grid-template-columns: 1fr; }
  .col, .plaque { border-left: 0; border-top: 1px solid var(--rule-col); }
  .tuile { border-left: 0; border-top: 1px solid var(--ink); height: 260px; }
  .aplat { grid-column: span 1; min-height: 300px; }
  .plaque { min-height: 300px; }
  .une-titre { font-size: 40px; }
  .toolbar-count { display: none; }
  .som { grid-template-columns: 26px minmax(0, 1fr); }
  .som-thumb { display: none; }
  .dep { grid-template-columns: 9px 52px minmax(0, 1fr); }
  .dep-source, .dep-duree { display: none; }
  .reader-inner { padding: 0 20px 80px; }
  .reader-hero-corps { padding: 0 20px 26px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================== la porte */

/* L'ecran de connexion. Meme vocabulaire que le reste : filets, angles droits,
   mono en capitales pour tout ce qui n'est pas editorial. */
.porte {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center;
  background: var(--index-bg);
  animation: ed-fade .2s var(--ease);
}
.porte-carte {
  width: min(420px, calc(100vw - 40px));
  padding: 34px 32px 28px;
  background: var(--bone);
  border: 1px solid var(--ink);
}
.porte-marque { display: flex; align-items: center; gap: 12px; color: var(--ink); }
.porte-marque .logo-mark { width: 34px; height: 22.7px; flex: none; }
.porte-marque .logo-mot { font-family: var(--display); font-size: 33px; line-height: .86; letter-spacing: -.025em; }
.porte-intro {
  margin: 16px 0 22px;
  font-family: var(--body); font-size: 14.5px; line-height: 1.5; color: var(--mute);
}
.porte-erreur { color: #d63a2a; }
.porte .modal-actions { margin-top: 22px; }
.porte .btn.solid { width: 100%; justify-content: center; }

/* --------------------------------------------------------- les comptes */

.comptes-liste { display: flex; flex-direction: column; }
.compte-ligne {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 0; border-bottom: 1px solid var(--rule-list);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em;
}
.compte-ligne.suspendu { opacity: .5; }
.compte-qui { flex: 1; min-width: 0; }
.compte-qui b { display: block; font-weight: 500; color: var(--ink); }
.compte-qui span { color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
.compte-chiffres { flex: none; color: var(--mute); text-align: right; }
.compte-ligne select { padding: 3px 6px; font-size: 9.5px; }
.compte-ligne .lien-danger { flex: none; color: #d63a2a; font-family: var(--mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase; }
.compte-moi { color: var(--accent); }

.compte-neuf { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 14px; }
.compte-neuf input, .compte-neuf select {
  padding: 8px 10px; border: 1px solid var(--rule-list); background: none; color: var(--ink);
  font-family: var(--mono); font-size: 10px;
}
.compte-neuf input:first-child { grid-column: 1 / -1; }
.compte-neuf .btn { grid-column: 1 / -1; }

/* La pastille de dossier, sur les vues d'ensemble. Un contour plutôt qu'un
   aplat : les étiquettes posées à la main sont pleines, et ces deux marques ne
   doivent pas se confondre — l'une dit d'où vient l'article, l'autre ce qu'on
   en a décidé. */
.art-dossier {
  display: inline-block; margin-right: 7px; padding: 1px 5px;
  border: 1px solid currentColor; border-radius: 0;
  font-family: var(--mono); font-size: 8px; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 400; opacity: .72; vertical-align: 1px;
  white-space: nowrap;
}
.une-sur .art-dossier, .tuile-sur .art-dossier { opacity: .85; }

/* La photographie de l'article qu'on quitte pendant un glissé. Elle se pose
   par-dessus le suivant, déjà rendu en dessous : c'est ce qui supprime le vide
   entre les deux. Fond plein, sinon on verrait au travers. */
.reader-fantome {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: var(--bone);
  z-index: 2;
  pointer-events: none;
  overscroll-behavior: none;
  scrollbar-width: none;
  will-change: transform;
}
.reader-fantome::-webkit-scrollbar { width: 0; }
