/* Feed noir — mobile-first, scroll snap vertical full-screen.
   --feed-accent/--feed-cyan quedan como alias monocromáticos de compat:
   la UI no lleva color de marca fijo (spec noir 3), el acento es por historia. */
:root {
  --feed-bg: var(--ink-950, #050505);
  --feed-text: #fff;
  --feed-muted: rgba(255, 255, 255, 0.72);
  --feed-accent: rgba(255, 255, 255, 0.92);
  --feed-cyan: rgba(255, 255, 255, 0.92);
  --feed-chip: rgba(0, 0, 0, 0.55);
  --accent-ink: #ff1a1a; /* mismo rojo fijo que la home para el modo "punto de tinta" */
}

/* Modo "punto de tinta" — MISMO efecto que la home (css/home.css): el acento
   mono pasa a rojo tinta. Sin esto el toggle del header no tenía ningún
   efecto visible en la vista de artículo (solo recoloreaba el botón). */
html[data-accent="color"] {
  --feed-accent: var(--accent-ink);
  --feed-cyan: var(--accent-ink);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overscroll-behavior: none;
}

.feed-body {
  background: var(--feed-bg);
  color: var(--feed-text);
  font-family: "Inter", system-ui, -apple-system, sans-serif;
}

/* ---------- Barra superior ---------- */
.feed-top {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(env(safe-area-inset-top, 0px) + 10px) 14px 10px;
  background: linear-gradient(rgba(0, 0, 0, 0.65), rgba(0, 0, 0, 0));
  pointer-events: none;
}
.feed-top > * { pointer-events: auto; }

.feed-back {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 0;
  border: 1px solid rgba(255, 255, 255, 0.4);
  color: #fff;
  background: rgba(0, 0, 0, 0.45);
  text-decoration: none;
  backdrop-filter: blur(8px);
}

.feed-tabs {
  display: flex;
  gap: 0;
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 0;
  padding: 0;
  backdrop-filter: blur(8px);
}
.feed-tab + .feed-tab { border-left: 1px solid rgba(255, 255, 255, 0.25); }
.feed-tab {
  border: 0;
  background: transparent;
  color: var(--feed-muted);
  font: 500 0.66rem "DM Mono", monospace;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  white-space: nowrap;
  padding: 8px 12px;
  border-radius: 0;
  cursor: pointer;
}
.feed-tab.active {
  background: #fff;
  color: #000;
}

.feed-top-spacer { width: 38px; }

/* ---------- Scroller ---------- */
.feed-scroller {
  height: 100dvh;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  scrollbar-width: none;
}
.feed-scroller::-webkit-scrollbar { display: none; }

.feed-loading {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  color: var(--feed-muted);
}
.feed-spinner {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.25);
  border-top-color: #fff;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Slide ---------- */
.slide {
  position: relative;
  height: 100dvh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  touch-action: pan-y; /* el scroll vertical lo maneja el navegador; el horizontal llega como pointer events para el swipe */
}

.slide-media,
.slide-media img,
.slide-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.slide-media img { background: #111; }

.slide-shade {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 22%),
    linear-gradient(0deg, rgba(0, 0, 0, 0.88) 0%, rgba(0, 0, 0, 0.35) 38%, rgba(0, 0, 0, 0) 62%);
}

/* ---------- Rail derecho ---------- */
.slide-rail {
  position: absolute;
  right: 10px;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 110px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  z-index: 10;
}
.rail-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  color: #fff;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font: 600 12px "Inter", sans-serif;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}
.rail-item svg {
  width: 34px;
  height: 34px;
  filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.6));
  transition: transform 0.15s ease;
}
.rail-item:active svg { transform: scale(1.25); }
.rail-item.liked { color: var(--feed-accent); }
.rail-score {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.rail-score .num {
  font: 700 15px "DM Mono", monospace;
  background: linear-gradient(135deg, var(--feed-cyan), var(--feed-accent));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ---------- Contenido inferior ---------- */
.slide-content {
  position: relative;
  z-index: 5;
  width: min(100%, calc(100% - 64px));
  padding: 0 14px calc(env(safe-area-inset-bottom, 0px) + 92px);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.slide-badges {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: 500 0.62rem "DM Mono", monospace;
  letter-spacing: 0.1em;
  filter: grayscale(1); /* el ⭐ del score es un emoji: sin esto queda dorado */
  text-transform: uppercase;
  padding: 5px 9px;
  border-radius: 0;
  border: 1px solid rgba(255, 255, 255, 0.45);
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  backdrop-filter: blur(8px);
}

.slide-title {
  margin: 0;
  font: 400 clamp(1.85rem, 8vw, 2.5rem)/1.04 "Libre Caslon Display", Georgia, serif;
  -webkit-text-stroke: 0.5px currentColor;
  letter-spacing: -0.025em;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.55);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.slide-meta {
  font: 500 0.64rem "DM Mono", monospace;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--feed-muted);
}
.slide-summary {
  margin: 0;
  font: 400 0.95rem/1.5 Georgia, "Iowan Old Style", serif;
  color: rgba(255, 255, 255, 0.86);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.slide-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 4px;
}
.btn-feed {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 0;
  border-radius: 0;
  padding: 11px 16px;
  font: 500 0.68rem "DM Mono", monospace;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}
.btn-feed-ghost.truncate {
  max-width: 52%;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-block;
  line-height: 1.2;
}
.btn-feed svg { width: 16px; height: 16px; }
.btn-feed-primary { background: #fff; color: #000; }
.btn-feed-ghost {
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.4);
  color: #fff;
  backdrop-filter: blur(8px);
}

/* ---------- Hint ---------- */
.feed-hint {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 26px);
  transform: translateX(-50%);
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  color: var(--feed-muted);
  font: 600 11px "Inter", sans-serif;
  animation: bounce 1.6s ease-in-out infinite;
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.feed-hint.hidden { opacity: 0; }
@keyframes bounce {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50% { transform: translateX(-50%) translateY(6px); }
}

/* ---------- Toggle Lectura / Video ---------- */
.hidden { display: none !important; }

.view-toggle {
  display: flex;
  border: 1px solid rgba(255, 255, 255, 0.3);
}
.vt-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 0;
  background: transparent;
  color: var(--feed-muted);
  font: 500 0.68rem "DM Mono", monospace;
  text-transform: uppercase; letter-spacing: 0.06em;
  padding: 8px 12px;
  border-radius: 0;
  cursor: pointer;
  white-space: nowrap;
}
.vt-btn.active { background: #fff; color: #000; }

/* ---------- Vista video (letra estilo Spotify, full-screen) ---------- */
.lyx-view {
  position: fixed;
  inset: 0;
  z-index: 25; /* debajo del header para que el toggle siga accesible */
  background: var(--lyx-bg);
  color: var(--lyx-text);
  display: flex;
  flex-direction: column;
}

/* ── Tokens de la vista narrada ──────────────────────────────────────────────
   Respeta el tema activo: papel/tinta en light noir, tinta/papel en dark.
   Dos tamaños (modelo SMALL/LARGE, ver docs/ejemplo-subtitulos):
     SMALL → la narración corrida, una línea, nunca se quiebra.
     LARGE → el énfasis, pocas palabras, cuerpo grande. */
/* ── Tokens de la vista narrada ──────────────────────────────────────────────
   Respeta el tema activo: papel/tinta en light noir, tinta/papel en dark.
   Dos niveles (modelo SMALL/LARGE, ver docs/ejemplo-subtitulos):
     SMALL → la narración corrida. Una línea que nunca se quiebra.
     LARGE → el énfasis, pocas palabras, cuerpo grande.

   UNA SOLA FAMILIA: los dos niveles usan Prumo (la variable font del diseño
   de referencia); lo que cambia es el PESO y el CUERPO, no la familia. Antes
   el SMALL iba en Inter y el LARGE en Libre Caslon (un serif): eso hacía que
   la vista pareciera tener dos tipografías distintas. */
@font-face {
  font-family: "Prumo VF";
  src: url("../fonts/Prumo-LNVF.woff2") format("woff2-variations"),
       url("../fonts/Prumo-LNVF.woff2") format("woff2");
  font-weight: 10 190;  /* rango real del eje wght (10..190) */
  font-style: normal;
  font-display: swap;
}

.lyx-view {
  --lyx-bg: var(--bg, #f0eee7);
  --lyx-text: var(--text, #14120f);
  --lyx-muted: var(--muted, rgba(20, 18, 15, 0.62));
  --lyx-line: var(--line, rgba(20, 18, 15, 0.18));
  --lyx-invert-bg: var(--invert-bg, #14120f);
  --lyx-invert-text: var(--invert-text, #f0eee7);
  /* Estado de las palabras: sin leer → leída → sonando. */
  --lyx-idle: var(--muted, rgba(20, 18, 15, 0.34));
  --lyx-sung: var(--text, rgba(20, 18, 15, 0.72));
  --lyx-now: var(--text, #14120f);
  /* Cuerpo de la narración (SMALL) y del énfasis (LARGE). */
  --lyx-small: clamp(20px, 5.2vw, 27px);
  --lyx-large: clamp(34px, 9.5vw, 52px);
  /* Una familia para los dos niveles (ver @font-face arriba). El fallback es
     la misma sans de sistema, así nunca aparece un serif suelto. */
  --lyx-font-body: "Prumo VF", "Inter", system-ui, -apple-system, sans-serif;
  --lyx-font-editorial: "Prumo VF", "Inter", system-ui, -apple-system, sans-serif;
  --lyx-font-mono: "DM Mono", ui-monospace, monospace;
}

/* Fondo: solo en pantalla completa (desktop). En mobile la vista queda como estaba. */
.lyx-bg {
  display: none;
}
.lyx-bg-shade {
  display: none;
}

@media (min-width: 900px) {
  .lyx-view {
    flex-direction: row;
    max-width: 1280px;
    margin: 0 auto;
    left: 0;
    right: 0;
  }
  .lyx-bg {
    display: block;
    position: relative;
    width: 46%;
    height: 100%;
    flex-shrink: 0;
  }
  .lyx-bg video,
  .lyx-bg img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .lyx-bg-shade {
    display: block;
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0) 40%);
  }
}

.lyx-player {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.lyx-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: calc(env(safe-area-inset-top, 0px) + 64px) 22px 6px;
}
.lyx-label {
  font: 500 12px var(--lyx-font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lyx-muted);
}
.lyx-eq {
  display: inline-flex;
  align-items: flex-end;
  gap: 2.5px;
  height: 14px;
}
.lyx-eq i {
  width: 3px;
  background: var(--lyx-text);
  border-radius: 2px;
  height: 30%;
}
.lyx-eq.on i { animation: eq 0.7s ease-in-out infinite; }
.lyx-eq.on i:nth-child(1) { animation-delay: 0s; }
.lyx-eq.on i:nth-child(2) { animation-delay: 0.18s; }
.lyx-eq.on i:nth-child(3) { animation-delay: 0.36s; }
.lyx-eq.on i:nth-child(4) { animation-delay: 0.09s; }
@keyframes eq {
  0%, 100% { height: 25%; }
  50% { height: 100%; }
}

/* ── El escenario de la narración ────────────────────────────────────────────
   Muestra UNA SOLA pantalla, siempre a la MISMA altura (ver docs/
   ejemplo-subtitulos, CaptionPage.tsx::TOP_ANCHOR_RATIO).

   El bloque se ancla por ARRIBA a una posición fija y crece hacia abajo: una
   pantalla con SMALL solo, o con SMALL + LARGE, arranca siempre en el mismo
   lugar. Antes el track tenía las 40 pantallas apiladas y se traducía en Y,
   así que se veían líneas arriba y abajo desplazándose.

   `position: relative` + `top` fijo (y NO un flex centrado) es lo que da la
   altura constante: centrar haría que una pantalla con LARGE —más alta— se
   moviera respecto de una pantalla solo SMALL. */
.lyx-stage {
  flex: 1;
  overflow: hidden;
  min-height: 0;
  padding: 0 20px;
  position: relative;
}
/* Ancla del texto: mismo `top` para toda pantalla.
   El 66% de la pieza de referencia (CaptionPage.tsx) es para un lienzo vertical
   1080x1920 de video, donde deja la franja baja libre para la interfaz de la
   plataforma. Acá el escenario es más corto y ese 66% dejaba el texto pegado a
   los controles, así que se ancla un poco más arriba — pero SIEMPRE al mismo
   `top`, que es lo que garantiza que la pantalla no se mueva entre una de una
   línea y una con LARGE. */
.lyx-track {
  position: absolute;
  left: 20px;
  right: 20px;
  top: 52%;
}
/* La pantalla activa se funde al entrar, en el mismo lugar. */
.lyx-screen.is-active {
  animation: lyx-line-in 0.34s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes lyx-line-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .lyx-screen.is-active { animation: none; }
}
/* Solo se pinta la pantalla activa. */
.lyx-screen { display: none; }
.lyx-screen.is-active { display: block; }
.lyx-line {
  /* SMALL: la narración. Una línea, nunca se quiebra.
     El peso tiene que estar DENTRO del eje wght de Prumo (10..190): un valor
     mayor hace que el navegador descarte la variable font y caiga al fallback
     sans, que es justo lo que hacía que se vieran dos tipografías distintas. */
  font-family: var(--lyx-font-body);
  font-weight: 160;
  font-size: var(--lyx-small);
  line-height: 1.35;
  letter-spacing: -0.01em;
  padding: 0;
  cursor: pointer;
  white-space: nowrap;
}
/* LARGE: el énfasis. MISMA familia que el SMALL (Prumo), pero más cuerpo y
   peso; nunca un serif suelto. Va debajo del SMALL, en la misma pantalla.
   Se quiebra en líneas de máx 14 caracteres (regla 15 del requerimiento), así
   que nunca se desborda del ancho.

   INTERLINEADO: el bloque SMALL+LARGE se lee como una unidad, así que el LARGE
   tiene que venir PEGADO al SMALL, no flotando aparte. Antes tenía
   `margin-top: 0.5em` —y el `em` es el del LARGE, o sea ~18.5px a 37px de
   cuerpo— más un `line-height: 1.08` que entre sus propias líneas dejaba 40px
   a 37px de letra. El resultado era un bloque aireado y desconectado.
   Ahora: aire mínimo contra el SMALL y líneas del LARGE más juntas entre sí. */
.lyx-line.is-large {
  font-family: var(--lyx-font-editorial);
  font-weight: 150;
  font-size: var(--lyx-large);
  line-height: 0.94;
  letter-spacing: -0.02em;
  padding: 0;
  margin-top: 0.22em;
  white-space: normal;
  overflow-wrap: break-word;
}
.lyx-word {
  color: var(--lyx-idle);
  transition: color 0.18s ease;
}
.lyx-word.sung { color: var(--lyx-sung); }
.lyx-word.now {
  color: var(--lyx-now);
  /* El "encendido" es del color del tema, sin neón ni cyan. */
  text-shadow: none;
}
/* Reveal por palabra: la palabra ocupa su lugar desde el arranque y solo
   cambia de opacidad, así el layout nunca salta (misma lógica que el
   CaptionPage de referencia). */
.lyx-line.is-active .lyx-word {
  animation: lyx-reveal 0.34s ease-out both;
}
@keyframes lyx-reveal {
  from { opacity: 0.15; transform: translateY(3px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .lyx-line.is-active .lyx-word { animation: none; }
}

.lyx-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px calc(env(safe-area-inset-bottom, 0px) + 20px);
  border-top: 1px solid var(--lyx-line);
}
.lyx-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border: 0;
  border-radius: 50%;
  background: var(--lyx-invert-bg);
  color: var(--lyx-invert-text);
  cursor: pointer;
  flex-shrink: 0;
}
.lyx-btn.lyx-speed {
  width: auto;
  background: transparent;
  border: 1px solid var(--lyx-line);
  color: var(--lyx-text);
  font: 700 12px "DM Mono", monospace;
  padding: 0 12px;
  height: 30px;
  border-radius: 0;
}
.lyx-time {
  font: 600 11px "DM Mono", monospace;
  color: var(--lyx-muted);
  flex-shrink: 0;
}
.lyx-bar {
  flex: 1;
  height: 5px;
  border-radius: 3px;
  background: var(--lyx-line);
  cursor: pointer;
}
.lyx-fill {
  height: 100%;
  border-radius: 3px;
  /* Sin gradiente de color: la barra es tinta del tema. */
  background: var(--lyx-text);
  width: 0%;
}

/* ---------- Review en formato artículo (slots video/podcast) ---------- */
.review-why {
  border-left: 3px solid var(--feed-cyan);
  padding: 4px 0 4px 14px;
  font: 500 17px/1.6 "Libre Caslon Display", Georgia, serif;
  color: rgba(255, 255, 255, 0.95);
}
.review-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px;
}
.review-fact {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 0;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.review-fact strong {
  font: 700 10px "DM Mono", monospace;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--feed-muted);
}
.review-fact span { font: 400 13.5px/1.45 "Inter", sans-serif; }

.review-slot {
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.review-slot-title {
  margin: 0;
  font: 800 16px "Inter", sans-serif;
}
.review-slot-note {
  margin: 0;
  font: 400 14px/1.5 "Inter", sans-serif;
  color: var(--feed-muted);
}
.review-slot-soon {
  border-style: dashed;
  align-items: flex-start;
}
.review-video {
  width: 100%;
  border-radius: 0;
  background: #000;
  aspect-ratio: 9 / 16;
  max-height: 70vh;
  object-fit: contain;
}
.review-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 0;
  overflow: hidden;
  background: #000;
}
.review-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.review-where {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.review-where strong {
  font: 700 10px "DM Mono", monospace;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--feed-muted);
}
.review-where-list { display: flex; gap: 6px; flex-wrap: wrap; }

/* ---------- Vista por artículo ---------- */
.article-body {
  background: var(--feed-bg);
  color: var(--feed-text);
  font-family: "Inter", system-ui, sans-serif;
}

/* Toggle de vista (Lectura/Audio) — ya NO está en el menú superior:
   vive en el cuerpo de la nota, como una decisión de lectura editorial. */
.article-view-toggle {
  display: flex;
  justify-content: center;
  margin-bottom: 22px;
}
.article-view-toggle .vt-btn {
  display: inline-flex;
  align-items: center;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: transparent;
  color: var(--feed-muted);
  font: 500 0.68rem "DM Mono", monospace;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 8px 12px;
  border-radius: 0;
  cursor: pointer;
  white-space: nowrap;
}
.article-view-toggle .vt-btn.active {
  background: #fff;
  color: #000;
}
.article-view-toggle .vt-btn + .vt-btn { border-left: 0; }
/* En la vista audio, el toggle flota sobre el video, esquina inferior */
.article-view-toggle-audio {
  position: absolute;
  margin: 0;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 76px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 8;
}
.article-view-toggle-audio .vt-btn {
  border-color: rgba(255, 255, 255, 0.4);
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(8px);
}
.article-view-toggle-audio .vt-btn.active {
  background: #fff;
  color: #000;
}

/* Toolbar de la nota: toggle de vista + tamaño de letra, debajo del título */
.article-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin: 16px 0 6px;
}
.article-toolbar .article-view-toggle { justify-content: flex-start; margin: 0; }
.article-font { display: inline-flex; }
.article-font .af-btn {
  font: 500 0.7rem "DM Mono", monospace;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: transparent;
  color: var(--feed-muted);
  padding: 8px 11px;
  cursor: pointer;
  border-radius: 0;
}
.article-font .af-btn + .af-btn { border-left: 0; }
.article-font .af-btn:hover { background: #fff; color: #000; }
body.article-body.mode-read .article-font .af-btn {
  border-color: var(--a-line-strong);
  color: var(--a-text-soft);
}
body.article-body.mode-read .article-font .af-btn:hover {
  background: var(--a-text); color: var(--a-bg);
}
/* Grupo derecho del toolbar: tamaño de letra + compartir */
.article-toolbar-right { display: inline-flex; align-items: center; gap: 8px; }
.article-share {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font: 500 0.68rem "DM Mono", monospace;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: transparent;
  color: var(--feed-muted);
  padding: 8px 12px;
  cursor: pointer;
  border-radius: 0;
}
.article-share svg { width: 15px; height: 15px; }
.article-share:hover { background: #fff; color: #000; }
body.article-body.mode-read .article-share {
  border-color: var(--a-line-strong);
  color: var(--a-text-soft);
}
body.article-body.mode-read .article-share:hover {
  background: var(--a-text); color: var(--a-bg);
}

/* Aviso "enlace copiado" */
.share-toast {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 24px);
  transform: translateX(-50%) translateY(10px);
  z-index: 400;
  background: #fff;
  color: #000;
  font: 500 0.68rem "DM Mono", monospace;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 10px 14px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.share-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
html[data-theme="dark"] .share-toast { background: #f0eee7; color: #050505; }

/* (El menú superior es el compartido del sitio: .site-top en pages.css.
   El logo central .article-logo y el toggle fijo .article-top se retiraron:
   una sola barra en todas las páginas, el toggle vive en la nota.) */

/* Vista lectura: sigue el TEMA GLOBAL (mismo switch que la home).
   Claro (default) = MISMO papel que la home; oscuro = MISMA tinta.
   La vista audio se queda noir siempre (spec 4.1). */
body.article-body.mode-read {
  --a-bg: var(--paper-100, #f0eee7);
  --a-text: #14120f;
  --a-text-soft: rgba(20, 18, 15, 0.62);
  --a-line: rgba(20, 18, 15, 0.3);
  --a-line-strong: rgba(20, 18, 15, 0.5);
  background: var(--a-bg);
  color: var(--a-text);
}
html[data-theme="dark"] body.article-body.mode-read {
  --a-bg: var(--ink-950, #050505);
  --a-text: #e9e2cf;
  --a-text-soft: rgba(233, 226, 207, 0.62);
  --a-line: rgba(233, 226, 207, 0.24);
  --a-line-strong: rgba(233, 226, 207, 0.45);
}
/* Punto de tinta: MISMO criterio que .d-home en la home (css/home.css) —
   el fondo pasa a papel/blanco con texto oscuro aunque el tema esté en
   oscuro, porque la tinta se escribe sobre papel, no sobre un fondo negro.
   Va después de la regla [data-theme="dark"] para ganarle cuando ambos
   están activos (misma especificidad, gana el orden). */
html[data-accent="color"] body.article-body.mode-read {
  --a-bg: #fff;
  --a-text: #14120f;
  --a-text-soft: rgba(20, 18, 15, 0.62);
  --a-line: rgba(20, 18, 15, 0.3);
  --a-line-strong: rgba(20, 18, 15, 0.5);
  background: var(--a-bg);
  color: var(--a-text);
}
body.article-body.mode-read::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 25;
  opacity: 0.16;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.66' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.4'/%3E%3C/svg%3E");
  mix-blend-mode: multiply;
}
html[data-theme="dark"] body.article-body.mode-read::before {
  opacity: 0.06;
  mix-blend-mode: overlay;
}
html[data-accent="color"] body.article-body.mode-read::before {
  opacity: 0.16;
  mix-blend-mode: multiply;
}
/* Toggle de vista en modo lectura: sigue el tema de la nota */
body.article-body.mode-read .article-view-toggle .vt-btn {
  border-color: var(--a-line-strong);
  color: var(--a-text-soft);
}
body.article-body.mode-read .article-view-toggle .vt-btn.active {
  background: var(--a-text);
  color: var(--a-bg);
}

.article-page {
  max-width: 1280px;
  margin: 0 auto;
  padding: 30px 24px calc(env(safe-area-inset-bottom, 0px) + 40px);
}

.article-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 720px;
  margin: 0 auto;
}
.article-meta-top { display: flex; gap: 6px; }
.article-title {
  margin: 0;
  font: 400 clamp(1.75rem, 3.8vw, 2.8rem)/1.06 "Libre Caslon Display", Georgia, serif;
  -webkit-text-stroke: 0.5px currentColor;
  letter-spacing: -0.02em;
}
/* Título de diario impreso en la vista papel: escala display grande como
   el mockup .read h1, no el tamaño reducido de la vista noir. */
/* Titular de la nota: MISMA tipografía que los títulos de la home
   (Libre Caslon Display 400), para que ambas portadas se lean iguales. */
.mode-read .article-title {
  font-family: "Libre Caslon Display", Georgia, serif;
  font-size: clamp(1.7rem, 3.6vw, 2.9rem);
  font-weight: 400;
  -webkit-text-stroke: 0.5px currentColor;
  line-height: 1.06;
  letter-spacing: -0.02em;
}
.article-meta {
  font: 600 12.5px "DM Mono", monospace;
  color: var(--feed-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
/* Folio: regla doble arriba, simple abajo — como el encabezado de una
   sección de diario impreso (mockup .folio). */
.mode-read .article-meta {
  color: var(--a-text-soft);
  border-top: 3px double var(--a-line-strong);
  border-bottom: 1px solid var(--a-line);
  padding: 8px 0;
  order: -1; /* el folio va antes del título, como una fecha de edición */
}
.mode-read .article-title { color: var(--a-text); }
/* Deck/bajada: primer párrafo promovido a apertura de nota de diario —
   serif grande, doble filete debajo (mockup .deck). */
.article-deck {
  margin: 14px 0 0;
  font: 400 clamp(1.05rem, 2.2vw, 1.35rem)/1.45 Georgia, "Iowan Old Style", serif;
  color: var(--feed-muted);
  max-width: 640px;
}
/* Bajada/standfirst estilo NYT: ocupa todo el ancho del artículo, serif
   grande y oscuro (un escalón entre el titular y el cuerpo). */
.mode-read .article-deck {
  color: var(--a-text);
  font-family: Georgia, "Iowan Old Style", serif;
  font-size: calc(clamp(1.2rem, 2.6vw, 1.55rem) * var(--a-scale, 1));
  line-height: 1.38;
  font-weight: 400;
  max-width: none;
  margin: 12px 0 0;
  border-bottom: 1px solid var(--a-line);
  padding-bottom: 18px;
}
.article-figure {
  margin: 6px 0 0;
}
.article-figure img {
  width: 100%;
  border-radius: 0;
  display: block;
  /* La imagen og puede ser un avatar o thumb minúsculo estirado: no
     dejar que una imagen de baja resolución ocupe el ancho de la nota. */
  image-rendering: auto;
  max-height: 70vh;
  object-fit: cover;
}
.mode-read .article-figure img { filter: grayscale(1) contrast(1.1); }
/* Punto de tinta: las fotos que ya tienen color lo muestran también en la
   vista lectura, igual que la home apaga su grayscale global en este modo. */
html[data-accent="color"] .mode-read .article-figure img { filter: contrast(1.1); }
.article-figure figcaption {
  font: 400 11.5px "Inter", sans-serif;
  color: var(--feed-muted);
  margin-top: 6px;
}
.mode-read .article-figure figcaption { color: var(--a-text-soft); }
.article-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  font-size: 16px;
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.92);
}
.article-body p { margin: 0; }
.article-body a { color: var(--feed-cyan); }
.article-body code {
  font-family: "DM Mono", monospace;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  padding: 1px 5px;
  font-size: 0.9em;
}
/* Cuerpo de lectura: serif de texto (Georgia, spec 5 — distinto de la
   display Libre Caslon Display de los títulos), columnas en pantallas
   anchas como una nota de diario impresa. */
.mode-read .article-body {
  font-family: Georgia, "Iowan Old Style", serif;
  font-size: calc(1.18rem * var(--a-scale, 1));
  line-height: 1.72;
  color: var(--a-text);
  /* El fondo negro de la vista audio no debe arrastrarse al papel:
     el cuerpo hereda el fondo de la nota en modo lectura. */
  background: transparent;
}
.mode-read .article-body p { orphans: 2; widows: 2; }
.mode-read .article-body a { color: var(--a-text); text-decoration: underline; text-underline-offset: 3px; }
.mode-read .article-body code {
  font-family: "DM Mono", monospace;
  background: var(--a-line);
}
@media (min-width: 720px) {
  .mode-read .article-card { max-width: 900px; }
  .mode-read .article-body {
    columns: 2 320px;
    column-gap: 44px;
    column-rule: 1px solid var(--a-line);
  }
  .mode-read .article-body p { margin-bottom: 1em; break-inside: avoid-column; }
}
/* Drop cap en la vista papel: letra inicial enorme como apertura de nota
   de diario (mockup .body p:first-child:first-letter). */
.mode-read .article-body > p:first-child::first-letter {
  float: left;
  font: 400 4.6rem/0.72 "Libre Caslon Display", Georgia, serif;
  margin: 8px 10px 0 0;
}
.article-context {
  border-left: 3px solid var(--feed-accent);
  padding-left: 12px;
  color: var(--feed-muted);
  font-family: Georgia, "Iowan Old Style", serif;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.75;
}
.article-context strong {
  font-family: Georgia, "Iowan Old Style", serif;
  font-style: italic;
  font-weight: 700;
}
.mode-read .article-context {
  border-left-color: var(--a-line-strong);
  color: var(--a-text-soft);
}
.a-tags { display: flex; gap: 8px; flex-wrap: wrap; }
.a-tags span {
  font: 600 12px "DM Mono", monospace;
  color: var(--feed-cyan);
}
.mode-read .a-tags span { color: var(--a-text-soft); }
.article-source { align-self: flex-start; }
.mode-read .article-source.btn-feed-primary { background: var(--a-text); color: var(--a-bg); }
/* Badges y nav: invertidos según el extremo activo del tema */
.mode-read .article-meta-top .badge {
  background: transparent;
  border: 1px solid var(--a-line-strong);
  color: var(--a-text-soft);
}
.mode-read .article-nav { border-top: 1px solid var(--a-line); }
.mode-read .article-nav .btn-feed-ghost {
  color: var(--a-text);
  border-color: var(--a-line-strong);
  background: transparent;
}
/* Review unificada en modo lectura: ficha y slots siguen el papel/tinta
   (--a-*), no el noir de la vista audio. */
.mode-read .review-fact {
  background: transparent;
  border: 1px solid var(--a-line);
}
.mode-read .review-fact strong { color: var(--a-text-soft); }
.mode-read .review-fact span { color: var(--a-text); }
.mode-read .review-slot { border-color: var(--a-line); }
.mode-read .review-slot-title { color: var(--a-text); }
.mode-read .review-slot-note { color: var(--a-text-soft); }
.mode-read .review-where strong { color: var(--a-text-soft); }
.mode-read .review-slot .badge,
.mode-read .review-where .badge {
  background: transparent;
  border: 1px solid var(--a-line-strong);
  color: var(--a-text-soft);
}
.article-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 10px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

/* ---------- Desktop: centrar el "teléfono" ---------- */
@media (min-width: 700px) {
  body.feed-body {
    display: flex;
    align-items: center;
    justify-content: center;
    background: #0a0a0a radial-gradient(circle at 50% 30%, #1c1c24, #0a0a0a);
  }
  .feed-scroller {
    width: min(430px, 100vw);
    height: min(100dvh, 932px);
    border-radius: 0;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.8);
    overflow-y: auto;
    overflow-x: hidden;
  }
  .feed-top {
    max-width: 430px;
    left: 50%;
    transform: translateX(-50%);
  }
  .feed-hint { display: none; }
  .slide { height: 100%; }
  .feed-loading { height: 100%; }
}

/* En desktop la letra vive en el panel derecho (~54% del ancho), no en toda la ventana.
   OJO: acá NO se redeclara la familia. Prumo es una variable font con eje
   `wght` de 10 a 190: un `font-weight: 800` (como el Inter que había antes)
   queda FUERA del rango declarado y el navegador descarta la fuente y cae al
   fallback — en desktop el SMALL salía en Inter y el LARGE en Prumo, o sea otra
   vez las "dos tipografías" que se querían evitar. Solo se ajusta el cuerpo y
   el aire vertical; la familia y el peso los fija la regla base. */
@media (min-width: 900px) {
  .lyx-line {
    font-size: clamp(24px, 2.3vw, 34px);
    padding: 13px 0;
  }
  /* El padding de arriba es para dar aire ENTRE pantallas. El LARGE no lo lleva:
     heredaba los 13px y, sumados a su margin-top, abrían un hueco de ~26px
     contra el SMALL que lo dejaba flotando en vez de leído como una unidad. */
  .lyx-line.is-large {
    font-size: clamp(38px, 4vw, 58px);
    padding: 0;
  }
  .lyx-stage { padding: 0 34px; }
  .lyx-track { left: 34px; right: 34px; }
}
.lyx-word { overflow-wrap: break-word; }

/* Palabras del guion que el audio narra pero que NO se muestran (aclaraciones
   entre parentesis tipo "(canvas, WebRTC, fuentes, plugins)"). Ocupan lugar
   cero: siguen existiendo en el DOM —y con su índice— para que el resaltado no
   se corra, pero no dejan hueco entre las palabras visibles. */
.lyx-word.is-hidden { display: none; }

/* ── Podcast del resumen del día ── */
.podcast-card {
  display: flex; flex-direction: column; gap: 20px;
  max-width: 720px; margin: 0 auto;
}
.podcast-head { display: flex; flex-direction: column; gap: 10px; }
.podcast-title {
  margin: 0;
  font: 400 clamp(2.15rem, 5.5vw, 3.3rem)/1 "Libre Caslon Display", Georgia, serif;
  -webkit-text-stroke: 0.5px currentColor;
  letter-spacing: -0.03em;
}
.podcast-meta {
  margin: 0;
  font: 500 0.66rem "DM Mono", monospace;
  text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--feed-muted);
}
.podcast-player {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 20px;
}
.podcast-player audio { width: 100%; }
.podcast-ctas { display: flex; gap: 10px; flex-wrap: wrap; }

/* ── Botón volver arriba (vista de artículo) ──────────────────────────────────
   El modo lectura scrollea sobre el viewport y en mobile el navegador no
   dibuja barra de scroll: al bajar, no hay forma de volver salvo el gesto.
   Aparece pasados los 400px (lo togglea article.js con .is-visible).

   VA CON !important A PROPÓSITO: medido en producción, el botón quedaba
   tapado por los <p> del artículo (document.elementFromPoint devolvía <P>
   donde está el botón) y el click nunca llegaba. El z-index alto solo no
   alcanzaba porque las reglas del cuerpo del artículo ganaban en especificidad
   sobre el posicionamiento. */
.btn-top {
  position: fixed !important;
  right: 16px !important;
  bottom: 92px !important;      /* arriba de la barra de audio, que va abajo */
  z-index: 2147483000 !important;
  display: grid !important;
  place-items: center !important;
  width: 44px !important; height: 44px !important;
  padding: 0 !important;
  margin: 0 !important;
  border: 1px solid rgba(255, 255, 255, 0.18) !important;
  border-radius: 50% !important;
  background: rgba(5, 5, 5, 0.72) !important;
  color: #f0eee7 !important;
  cursor: pointer !important;
  pointer-events: auto !important;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35) !important;
  opacity: 0;
  transform: translateY(8px) scale(0.92);
  pointer-events: none !important;
  transition: opacity 220ms ease, transform 220ms ease;
}
.btn-top.is-visible {
  opacity: 1 !important;
  transform: translateY(0) scale(1) !important;
  pointer-events: auto !important;
}
.btn-top:hover { background: rgba(5, 5, 5, 0.88) !important; }
.btn-top svg { width: 20px !important; height: 20px !important; pointer-events: none !important; }
/* En modo lectura el fondo es papel claro: el botón va en tinta oscura. */
.mode-read .btn-top {
  border-color: rgba(0, 0, 0, 0.16) !important;
  background: rgba(240, 238, 231, 0.86) !important;
  color: #14141a !important;
}
.mode-read .btn-top:hover { background: rgba(240, 238, 231, 0.98) !important; }
@media (prefers-reduced-motion: reduce) {
  .btn-top { transition: none; }
}
