@font-face {
  font-family: 'Inter';
  src: url('/static/fonts/InterVariable.woff2') format('woff2-variations'),
       url('/static/fonts/InterVariable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light;
  --bg: #f7f7fb;
  --bg-elevated: #ffffff;
  --bg-subtle: #f1f1f6;
  --text: #16161f;
  --text-muted: #6b6b7b;
  --border: #e4e4ec;
  --accent: #4f46e5;
  --accent-hover: #4338ca;
  --accent-soft: #eeedfd;
  --accent-contrast: #ffffff;
  --success-bg: #eafaf1; --success-text: #0f7a4a; --success-border: #34c076;
  --error-bg: #fdecec; --error-text: #b3261e; --error-border: #f26a63;
  --warning-bg: #fff6e0; --warning-text: #8a5a00; --warning-border: #f0ad2e;
  --highlight-bg: #fff2da; --highlight-bg-hover: #ffe9c2; --highlight-text: #7a4a00;
  --highlight-border: #f0ad2e; --highlight-strong: #d98c00;
  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 20px;
  --shadow: 0 1px 2px rgba(20, 20, 40, 0.04), 0 1px 4px rgba(20, 20, 40, 0.04);
  --shadow-lg: 0 8px 24px rgba(20, 20, 40, 0.10), 0 2px 6px rgba(20, 20, 40, 0.06);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0d0d13;
  --bg-elevated: #16161f;
  --bg-subtle: #1c1c28;
  --text: #f2f2f7;
  --text-muted: #9a9aad;
  --border: #2a2a38;
  --accent: #818cf8;
  --accent-hover: #a5b4fc;
  --accent-soft: #23234a;
  --accent-contrast: #0d0d13;
  --success-bg: #103322; --success-text: #4ade95; --success-border: #1f7a4d;
  --error-bg: #331515; --error-text: #ff8a82; --error-border: #7a2620;
  --warning-bg: #332708; --warning-text: #f5c76a; --warning-border: #8a6300;
  --highlight-bg: #3a2a0a; --highlight-bg-hover: #4a3610; --highlight-text: #ffcd70;
  --highlight-border: #a06b0f; --highlight-strong: #f0ad2e;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 12px 28px rgba(0, 0, 0, 0.45), 0 4px 10px rgba(0, 0, 0, 0.3);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0d0d13;
    --bg-elevated: #16161f;
    --bg-subtle: #1c1c28;
    --text: #f2f2f7;
    --text-muted: #9a9aad;
    --border: #2a2a38;
    --accent: #818cf8;
    --accent-hover: #a5b4fc;
    --accent-soft: #23234a;
    --accent-contrast: #0d0d13;
    --success-bg: #103322; --success-text: #4ade95; --success-border: #1f7a4d;
    --error-bg: #331515; --error-text: #ff8a82; --error-border: #7a2620;
    --warning-bg: #332708; --warning-text: #f5c76a; --warning-border: #8a6300;
    --highlight-bg: #3a2a0a; --highlight-bg-hover: #4a3610; --highlight-text: #ffcd70;
    --highlight-border: #a06b0f; --highlight-strong: #f0ad2e;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 12px 28px rgba(0, 0, 0, 0.45), 0 4px 10px rgba(0, 0, 0, 0.3);
  }
}

* { box-sizing: border-box; }

/* El background tambien en html (no solo body): el rebote elastico de iOS al final del
   scroll muestra el fondo del elemento raiz -- sin esto se veia una franja BLANCA bajo la
   ultima pagina del PDF (reporte real de Alvaro), en vez del fondo del tema. */
html { -webkit-text-size-adjust: 100%; background: var(--bg); }

body {
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text);
  margin: 0;
  line-height: 1.55;
  font-size: 16px;
  transition: background-color .2s ease, color .2s ease;
}

h1, h2, h3 { font-weight: 650; letter-spacing: -0.01em; line-height: 1.25; }
h1 { font-size: 1.7rem; margin: 0 0 1.1rem; }
h2 { font-size: 1.15rem; margin: 1.75rem 0 0.6rem; }
p { margin: 0 0 0.75rem; }
a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); text-decoration: underline; }
.muted { color: var(--text-muted); }

/* ---------- topbar ---------- */
.topbar {
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap;
  padding: 0.55rem 1.1rem; border-bottom: 1px solid var(--border);
  background: var(--bg-elevated);
  position: sticky; top: 0; z-index: 20;
  gap: 0.5rem;
}
.topbar-right { display: flex; align-items: center; gap: 0.5rem; }
.brand { display: inline-flex; align-items: center; gap: 0.55rem; color: var(--text); font-weight: 700;
  font-size: 1.05rem; letter-spacing: -0.01em; }
.brand:hover { color: var(--text); text-decoration: none; }
.brand-mark { display: block; transition: transform .25s ease; }
.brand:hover .brand-mark { transform: rotate(-8deg) scale(1.05); }
/* ---------- menu del header (dropdown unico: nav + ajustes de lectura + salir) ---------- */
.header-menu { position: relative; }
.header-menu-panel {
  display: none; position: absolute; top: calc(100% + 0.6rem); right: 0;
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 0.6rem; min-width: 15.5rem; max-width: calc(100vw - 2rem);
  z-index: 30;
}
.header-menu-panel.is-open { display: block; }
.header-menu-link {
  display: flex; align-items: center; gap: 0.6rem; width: 100%; text-align: left;
  padding: 0.6rem 0.7rem; border-radius: var(--radius-sm); border: none; background: transparent;
  color: var(--text); font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer;
  box-sizing: border-box;
}
.header-menu-link:hover { background: var(--bg-subtle); text-decoration: none; }
.header-menu-link svg { width: 1.05rem; height: 1.05rem; flex-shrink: 0; color: var(--text-muted); }
.header-menu-logout { color: var(--error-text); }
.header-menu-logout svg { color: var(--error-text); }
.header-menu-divider { height: 1px; background: var(--border); margin: 0.5rem 0.2rem; }
.header-settings-title { margin: 0.4rem 0.2rem 0.5rem; font-weight: 700; font-size: 0.82rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.header-menu-theme-row { display: flex; align-items: center; justify-content: space-between; padding: 0.4rem 0.2rem; }
.header-settings-title-inline { margin: 0; font-weight: 700; font-size: 0.82rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }

/* ---------- ajustes de lectura (panel propio, junto al reproductor de audio) ---------- */
.reading-settings-menu { position: relative; flex-shrink: 0; }
.reading-settings-toggle span { font-size: 0.78rem; font-weight: 700; line-height: 1; }
.reading-settings-panel { min-width: 13.5rem; }

.icon-button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.1rem; height: 2.1rem; border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg-subtle); color: var(--text); cursor: pointer; flex-shrink: 0;
  transition: background-color .15s ease, transform .1s ease, border-color .15s ease;
}
/* @media(hover:hover) evita que el borde morado quede "pegado" en touch: en mobile,
   :hover se activa con el primer tap y no se limpia hasta tocar otro lado, dando la
   impresion de un boton morado permanente (reportado por Alvaro, boton de ajustes de
   lectura, 2026-07-22). */
@media (hover: hover) {
  .icon-button:hover { border-color: var(--accent); transform: translateY(-1px); }
}
.icon-button:active { transform: translateY(0) scale(0.94); }
.icon-button svg { width: 1.05rem; height: 1.05rem; flex-shrink: 0; }

/* ---------- circulos de tema (dentro de ajustes de lectura) ---------- */
.theme-circles { display: flex; gap: 0.6rem; }
.theme-circle {
  width: 1.7rem; height: 1.7rem; border-radius: 50%; cursor: pointer; padding: 0;
  transition: transform .1s ease, box-shadow .15s ease;
}
.theme-circle-light { background: #ffffff; border: 1px solid #d4d4dc; }
.theme-circle-dark { background: #16161f; border: 1px solid #16161f; }
.theme-circle:hover { transform: scale(1.08); }
.theme-circle.is-active { box-shadow: 0 0 0 2px var(--bg-elevated), 0 0 0 4px var(--accent); }

/* ---------- layout ---------- */
.container {
  max-width: 760px; margin: 0 auto; padding: 2rem 1.25rem 4rem;
  /* Sin fill-mode "both": con "both" el transform final (translateY(0)) queda pegado
     para siempre despues de terminar la animacion, y cualquier transform != none en un
     ancestro rompe position:fixed en los descendientes (crea un containing block nuevo)
     -- eso era lo que hacia que .chat-dock-wrap no quedara fijo abajo (bug real, no cache,
     reportado por Alvaro incluso en PC, 2026-07-22). */
  animation: fade-in-up .45s cubic-bezier(.2,.8,.2,1);
}
@keyframes fade-in-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
  .container, .brand-mark, * { animation: none !important; transition: none !important; }
}

.page-center { display: flex; justify-content: center; padding: 3rem 1rem; min-height: calc(100vh - 4.2rem); align-items: center; }
/* Sin header (login/registro): recupera el alto que el topbar hubiera ocupado. */
.container--no-header { padding-top: 0; }
@media (min-width: 481px) {
  .container--no-header .page-center { min-height: 100vh; }
}

/* ---------- cards ---------- */
.card {
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); padding: 2rem; width: 100%; max-width: 380px;
}
.card-header { text-align: center; margin-bottom: 1.5rem; }
.card-header .brand-mark { margin: 0 auto 0.85rem; }
.card-header h1 { margin-bottom: 0.25rem; }
.card-header p { margin: 0; }
.card-section { background: var(--bg-subtle); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 1.25rem 1.4rem; margin: 1.25rem 0; }

.divider { display: flex; align-items: center; gap: 0.75rem; margin: 1.35rem 0; color: var(--text-muted); font-size: 0.85rem; }
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* ---------- forms ---------- */
.form { display: flex; flex-direction: column; gap: 1rem; }
.form label { display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.88rem; font-weight: 550; }
input[type="email"], input[type="password"], input[type="text"], input[type="search"],
input[type="file"], select {
  font: inherit; padding: 0.65rem 0.8rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg-elevated); color: var(--text);
  transition: border-color .15s ease, box-shadow .15s ease;
}
input:focus, select:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ---------- toolbar (biblioteca: buscar + ordenar) ---------- */
.toolbar { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.toolbar-search { flex: 1; min-width: 160px; border-radius: 999px; padding-left: 1.1rem; }

/* ---------- titulo editable ---------- */
.title-edit-form { display: flex; gap: 0.6rem; align-items: center; margin-bottom: 1.1rem; flex-wrap: wrap; }
.title-input {
  flex: 1; min-width: 200px; font-size: 1.6rem; font-weight: 650; letter-spacing: -0.01em;
  border: 1px solid transparent; background: transparent; padding: 0.25rem 0.5rem;
  border-radius: var(--radius-sm); font-family: inherit;
}
.title-input:hover { border-color: var(--border); }
.title-input:focus { background: var(--bg-elevated); border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

button, .button {
  display: inline-flex; align-items: center; justify-content: center;
  font: inherit; font-weight: 600; padding: 0.7rem 1.1rem; border-radius: var(--radius-sm);
  border: 1px solid transparent; background: var(--accent); color: var(--accent-contrast);
  cursor: pointer; transition: background-color .15s ease, transform .08s ease, box-shadow .15s ease;
}
button:hover, .button:hover { background: var(--accent-hover); text-decoration: none; color: var(--accent-contrast); }
button:active, .button:active { transform: scale(0.98); }
button.secondary, .button.secondary { background: var(--bg-subtle); color: var(--text); border-color: var(--border); }
button.secondary:hover, .button.secondary:hover { background: var(--bg-elevated); border-color: var(--accent); color: var(--text); }
button.danger, .button.danger { background: var(--error-bg); color: var(--error-text); border-color: var(--error-border); }
button.danger:hover, .button.danger:hover { background: var(--error-border); color: #fff; }
.danger-zone { margin-top: 2.5rem; padding-top: 1.25rem; border-top: 1px solid var(--border); }

.link-button { background: none; border: none; color: var(--text-muted); text-decoration: underline;
  cursor: pointer; padding: 0; font: inherit; }
.link-button:hover { color: var(--accent); }

.form-footer { text-align: center; margin-top: 1.25rem; font-size: 0.9rem; color: var(--text-muted); }

/* ---------- flashes / callouts ---------- */
.flash { padding: 0.65rem 0.9rem; border-radius: var(--radius-sm); margin-bottom: 1.1rem;
  border: 1px solid transparent; font-size: 0.92rem; }
.flash-error { background: var(--error-bg); color: var(--error-text); border-color: var(--error-border); }
.flash-success { background: var(--success-bg); color: var(--success-text); border-color: var(--success-border); }
.callout-warning { background: var(--warning-bg); color: var(--warning-text); padding: 0.7rem 1rem;
  border-radius: var(--radius-sm); border: 1px solid var(--warning-border); }

/* ---------- confetti (bienvenida) ---------- */
.confetti-burst { position: fixed; inset: 0; pointer-events: none; z-index: 999; overflow: hidden; }
.confetti-piece { position: absolute; top: -12px; width: 8px; height: 14px; opacity: 0.9;
  border-radius: 2px; animation-name: confetti-fall; animation-timing-function: ease-in;
  animation-fill-mode: forwards; }
@keyframes confetti-fall {
  0% { transform: translateY(0) rotate(0deg); opacity: 0.95; }
  100% { transform: translateY(100vh) rotate(540deg); opacity: 0.4; }
}

/* ---------- status badges ---------- */
.badge { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.78rem; font-weight: 650;
  padding: 0.2rem 0.6rem; border-radius: 999px; letter-spacing: 0.01em; text-transform: uppercase; }
.badge-uploaded, .badge-pending { background: var(--warning-bg); color: var(--warning-text); }
.badge-extracting, .badge-processing { background: var(--accent-soft); color: var(--accent); }
.badge-extracted, .badge-done { background: var(--success-bg); color: var(--success-text); }
.badge-error { background: var(--error-bg); color: var(--error-text); }

/* El atributo [hidden] es un contrato semantico -- nada deberia poder pisarlo con
   display. Bug real: .spinner de abajo tenia display:inline-block con la misma
   especificidad que la regla del navegador para [hidden], y por origen de cascada
   (autor > user-agent) siempre ganaba .spinner aunque JS pusiera hidden=true
   correctamente (spinner del boton "Escuchar" quedaba girando siempre, reportado por
   Alvaro 2026-07-22). */
[hidden] { display: none !important; }

/* ---------- spinner ---------- */
.spinner {
  display: inline-block; width: 1.3rem; height: 1.3rem; border-radius: 50%; flex-shrink: 0;
  border: 2.5px solid var(--border); border-top-color: var(--accent);
  animation: spin .8s linear infinite;
  box-sizing: border-box;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- panel generico (disclosure) ---------- */
.panel { margin: 1.4rem 0; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-elevated); overflow: hidden; }
.panel > summary {
  cursor: pointer; font-weight: 600; padding: 0.85rem 1.1rem; list-style: none;
  display: flex; align-items: center; gap: 0.5rem; user-select: none;
}
.panel > summary::-webkit-details-marker { display: none; }
.panel > summary::before {
  content: "›"; display: inline-block; font-size: 1.2rem; color: var(--text-muted);
  transition: transform .2s ease; transform: rotate(0deg);
}
.panel[open] > summary::before { transform: rotate(90deg); }
.panel-body { padding: 0 1.1rem 1.1rem; }

/* ---------- citas ---------- */
.citations-list { list-style: none; padding: 0 1.1rem 1.1rem; margin: 0; display: flex; flex-direction: column; gap: 1rem; }
.citations-list li { padding-top: 1rem; border-top: 1px solid var(--border); }
.citations-list li:first-child { padding-top: 0; border-top: none; }
.citation-badge { display: inline-block; font-size: 0.76rem; font-weight: 650; padding: 0.15rem 0.55rem;
  border-radius: 999px; margin-bottom: 0.4rem; }
.citation-verified .citation-badge { background: var(--success-bg); color: var(--success-text); }
.citation-unverified .citation-badge { background: var(--error-bg); color: var(--error-text); }
.citation-claim { margin: 0.2rem 0; font-weight: 550; }
.citation-quote { margin: 0.4rem 0 0; padding-left: 0.85rem; border-left: 3px solid var(--border); font-style: italic; color: var(--text-muted); }

/* ---------- figuras y tablas ---------- */
.figures-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1.1rem; }
.figure-card { margin: 0; }
.figure-card img { display: block; width: 100%; height: auto; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg-elevated); }
.figure-card figcaption { margin-top: 0.4rem; font-size: 0.82rem; }
.figure-card-trigger { display: block; width: 100%; padding: 0; border: none; background: none;
  cursor: zoom-in; border-radius: var(--radius-sm); }
.figure-card-trigger:hover img { border-color: var(--accent); }
.figure-ref { display: inline; padding: 0.05rem 0.4rem; margin: 0 0.05rem; border: none;
  border-radius: 999px; background: var(--accent-soft); color: var(--accent); font: inherit;
  font-size: 0.88em; cursor: zoom-in; }
.figure-ref:hover { background: var(--accent); color: var(--accent-contrast); }

.figure-lightbox { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center;
  justify-content: center; padding: 1.5rem; }
.figure-lightbox-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.72); }
.figure-lightbox-content { position: relative; z-index: 1; max-width: min(90vw, 900px);
  max-height: 90vh; overflow: auto; background: var(--bg-elevated); border-radius: var(--radius);
  padding: 1.1rem; display: flex; flex-direction: column; gap: 0.6rem; }
.figure-lightbox-content img { display: block; max-width: 100%; height: auto; border-radius: var(--radius-sm); }
.figure-lightbox-close { position: absolute; top: 0.6rem; right: 0.6rem; width: 2.2rem; height: 2.2rem;
  border-radius: 999px; border: 1px solid var(--border); background: var(--bg-subtle); color: var(--text);
  display: flex; align-items: center; justify-content: center; cursor: pointer; }
.figure-lightbox-close:hover { background: var(--error-bg); color: var(--error-text); border-color: var(--error-border); }

.citation-quote cite { display: block; font-style: normal; font-size: 0.82rem; opacity: 0.75; margin-top: 0.25rem; }

/* ---------- clasificacion de calidad (CEBM / GRADE) -- badge con tooltip CSS puro ---------- */
.quality-badges { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.1rem; }
.info-badge {
  position: relative; display: inline-flex; align-items: center;
  padding: 0.3rem 0.7rem; border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg-subtle); color: var(--text-muted); font-size: 0.78rem; font-weight: 650;
  cursor: help;
}
.info-badge:hover, .info-badge:focus { border-color: var(--accent); color: var(--text); outline: none; }
.info-badge-tooltip {
  display: none; position: absolute; bottom: calc(100% + 0.5rem); left: 50%;
  transform: translateX(-50%); box-sizing: border-box;
  width: max-content; max-width: min(18rem, calc(100vw - 2rem)); background: var(--text); color: var(--bg);
  padding: 0.55rem 0.75rem; border-radius: var(--radius-sm); font-size: 0.78rem; font-weight: 400;
  line-height: 1.45; box-shadow: var(--shadow-lg); z-index: 15;
}
.info-badge:hover .info-badge-tooltip, .info-badge:focus .info-badge-tooltip { display: block; }

/* ---------- ajustes de lectura ---------- */
.reading-settings-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 0.85rem;
}
.reading-settings-grid label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.82rem; font-weight: 550; color: var(--text-muted); }
.reading-settings-grid select { padding: 0.45rem 0.6rem; }

.reading-content { text-align: justify; -webkit-hyphens: auto; hyphens: auto; }
.reading-content[data-align="left"] { text-align: left; -webkit-hyphens: none; hyphens: none; }
.reading-content[data-align="justify"] { text-align: justify; -webkit-hyphens: auto; hyphens: auto; }

.reading-content[data-font="serif"] { font-family: Georgia, 'Times New Roman', serif; }
.reading-content[data-font="sans"] { font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif; }

.reading-content[data-size="sm"] { font-size: 0.92rem; }
.reading-content[data-size="md"] { font-size: 1rem; }
.reading-content[data-size="lg"] { font-size: 1.15rem; }
.reading-content[data-size="xl"] { font-size: 1.3rem; }

.reading-content[data-spacing="compact"] { line-height: 1.4; }
.reading-content[data-spacing="normal"] { line-height: 1.7; }
.reading-content[data-spacing="relaxed"] { line-height: 2; }
.reading-content h2 { text-align: left; }

/* ---------- chat del resumen ---------- */
.chat-thread { display: flex; flex-direction: column; gap: 0.85rem; margin-bottom: 1.1rem; max-height: 32rem; overflow-y: auto; }
.chat-bubble { max-width: 85%; padding: 0.65rem 0.9rem; border-radius: var(--radius); line-height: 1.5; font-size: 0.94rem; }
.chat-bubble p { margin: 0; }
.chat-bubble p + p { margin-top: 0.5rem; }
.chat-bubble-user { align-self: flex-end; background: var(--accent); color: var(--accent-contrast); border-bottom-right-radius: 4px; }
.chat-bubble-assistant { align-self: flex-start; background: var(--bg-subtle); border: 1px solid var(--border); border-bottom-left-radius: 4px; }
.chat-bubble-error { align-self: flex-start; background: var(--error-bg); color: var(--error-text); border: 1px solid var(--error-border); }

/* ---------- composer unificado fijo abajo (biblioteca + resumen) ---------- */
@keyframes chat-dock-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.chat-dock-wrap {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 500;
  display: flex; flex-direction: column; align-items: center; pointer-events: none;
}
/* El hilo NO se muestra en el estado normal del dock (tapaba el contenido) -- solo en
   el modo chat expandido a pantalla completa (.is-expanded), estilo Claude. */
.chat-dock-thread {
  display: none; pointer-events: auto; width: 100%; max-width: 720px; box-sizing: border-box;
  overflow-y: auto;
  margin-bottom: 0.5rem; padding: 0 0.6rem; flex-direction: column; gap: 0.6rem;
}
/* ---------- modo chat expandido: cubre la pagina entera ---------- */
.chat-dock-wrap.is-expanded {
  top: 0; background: var(--bg); pointer-events: auto;
  padding-top: max(env(safe-area-inset-top), 0.3rem);
}
.chat-dock-wrap.is-expanded .chat-dock-thread {
  display: flex; flex: 1 1 auto; min-height: 0; max-height: none; padding-top: 0.4rem;
}
.chat-dock-header {
  display: none; pointer-events: auto; width: 100%; max-width: 720px; box-sizing: border-box;
  align-items: center; justify-content: space-between; padding: 0.5rem 0.6rem;
}
.chat-dock-wrap.is-expanded .chat-dock-header { display: flex; }
.chat-dock-header-title { font-weight: 700; font-size: 0.95rem; }
.chat-dock-wrap.is-expanded .chat-dock-reopen { display: none; }
.chat-dock-reopen {
  pointer-events: auto; margin-bottom: 0.4rem; border: 1px solid var(--border);
  background: var(--bg-elevated); color: var(--text-muted); border-radius: 999px;
  padding: 0.3rem 0.9rem; font-size: 0.85rem; font-weight: 600; cursor: pointer;
  box-shadow: var(--shadow);
}
.chat-dock-reopen:hover { color: var(--accent); border-color: var(--accent); }
/* Bloquear el scroll de la pagina de fondo mientras el chat cubre la pantalla. */
html.chat-dock-open, html.chat-dock-open body { overflow: hidden; }
.chat-dock-indicator { pointer-events: auto; margin-bottom: 0.4rem; }
.chat-dock-status {
  pointer-events: auto; font-size: 0.82rem; margin-bottom: 0.35rem; min-height: 1.1rem;
}
.chat-dock-bar {
  pointer-events: auto; width: 100%; max-width: 720px; box-sizing: border-box;
  margin-bottom: 1.1rem; padding: 0 0.6rem;
  display: flex; flex-wrap: nowrap; align-items: flex-end; gap: 0.5rem;
}
/* Toda la pildora (+, texto, mic, enviar) es AHORA un solo elemento: antes el + y el
   mic eran circulos sueltos afuera de .chat-composer-box, lo que Alvaro reporto como
   "no es una sola barra como la de Claude" (2026-07-22) -- se fusiono el form externo
   viejo (.chat-composer) y el div interno (.chat-composer-box) en un unico form, asi
   que .chat-composer ya no existe como clase separada. */
.chat-dock-bar .chat-composer-box { flex: 1 1 auto; min-width: 0; margin: 0; }
/* Los botones +/mic viven DENTRO de la pildora ahora -- ya no necesitan borde/sombra/
   fondo propio (el borde de la pildora ya los contiene), quedan como iconos planos. */
.chat-dock-icon-button {
  flex: 0 0 auto; width: 2.3rem; height: 2.3rem; border-radius: 50%; padding: 0;
  border: none; background: transparent; color: var(--text-muted); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background-color .15s ease, color .15s ease;
}
/* Un SVG con solo viewBox (sin width/height) colapsa a 0x0 como flex item -- el boton
   "estaba" (area clickeable de 2.3rem, hover incluido) pero el icono adentro media cero.
   Todos los demas iconos del sitio ya tienen su regla de tamano equivalente. */
.chat-dock-icon-button svg { width: 1.2rem; height: 1.2rem; flex-shrink: 0; }
.chat-dock-mic svg { width: 1.35rem; height: 1.35rem; }
.chat-dock-icon-button:hover { background: var(--accent-soft); color: var(--accent); }
.chat-dock-icon-button:disabled { opacity: 0.45; cursor: not-allowed; }
.chat-dock-icon-button:disabled:hover { background: transparent; color: var(--text-muted); }
/* Mas grande que el + -- pedido explicito de Alvaro ("ese icono debe ser mas grande"). */
.chat-dock-mic { width: 2.4rem; height: 2.4rem; }
.chat-dock-mic.is-listening {
  background: var(--error-bg); color: var(--error-text);
  animation: chat-dock-pulse 1.4s ease-in-out infinite;
}
/* Alto por defecto antes de que chat-dock.js lo ajuste al alto real del dock (que crece
   con los mensajes) -- sin esto, o queda espacio muerto de scroll (dock vacio, spacer
   grande) o el dock tapa el final del contenido (dock con mensajes, spacer chico). */
.chat-dock-spacer { height: 7rem; }
/* ---------- composer estilo ChatGPT: +, texto, mic y enviar en una sola pildora ---------- */
/* align-items: center (no flex-end) para que con UNA sola linea el texto quede centrado
   en la pildora. Con flex-end el textarea (24px) se pegaba al piso de una fila que los
   botones redondos estiran a ~38px, dejando 24px de aire ARRIBA del placeholder y 10px
   abajo -- medido, era el reporte de Alvaro 2026-07-28. Los botones se bajan por su
   cuenta con align-self, asi que cuando el textarea crece a varias lineas siguen pegados
   al piso junto a la ultima linea, como en Claude. */
.chat-composer-box {
  display: flex; align-items: center; gap: 0.4rem;
  border: 1px solid var(--border); border-radius: 1.6rem; background: var(--bg-elevated);
  /* Izquierda mas chica que la derecha a proposito: lo primero en la pildora ya no es
     texto sino el boton +, que debe quedar cerca del borde (como en Claude). */
  padding: 0.45rem 0.6rem 0.45rem 0.3rem;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.chat-composer-box:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.chat-composer-box > button { align-self: flex-end; }
/* Padding vertical minimo: sumado al de la pildora dejaba ~16px sobre la primera linea
   y recortaba la segunda del placeholder envuelto (reporte de Alvaro en celular real,
   2026-07-22 -- "hay mucho padding sobre la primera linea"). */
.chat-composer-box textarea {
  flex: 1; min-width: 0; border: none; background: transparent; resize: none; padding: 0.1rem 0;
  min-height: 1.5rem; max-height: 45vh; font-family: inherit; font-size: 0.95rem;
  line-height: 1.35; color: var(--text); outline: none;
}
/* iOS pinta los placeholders casi transparentes por defecto -- Alvaro reporto que el
   texto del cuadro de chat "no se alcanza a leer bien" en su iPhone (2026-07-22). */
.chat-composer-box textarea::placeholder { color: var(--text-muted); opacity: 1; }
/* En pantalla angosta el placeholder completo no cabe en una linea del textarea de
   rows=1 (la segunda linea envuelta queda recortada) -- se achica solo el placeholder,
   no el texto que el usuario escribe. */
@media (max-width: 480px) {
  .chat-composer-box textarea::placeholder { font-size: 0.85rem; }
  /* Dos lineas completas visibles: si el placeholder igual se envuelve en una pantalla
     muy angosta, que la segunda linea se vea entera en vez de quedar cortada. */
  .chat-composer-box textarea { min-height: 2.4rem; }
}
.chat-send-button {
  flex-shrink: 0;
  width: 2.15rem; height: 2.15rem; border-radius: 50%; border: none; padding: 0;
  background: var(--text); color: var(--bg); display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background-color .15s ease, transform .1s ease, opacity .15s ease;
}
.chat-send-button:hover { background: var(--accent); color: var(--accent-contrast); }
.chat-send-button:active { transform: scale(0.92); }
.chat-send-button svg { width: 1.1rem; height: 1.1rem; }
.chat-indicator { display: none; align-items: center; gap: 0.5rem; margin-top: 0.6rem; color: var(--text-muted); font-size: 0.85rem; }
.htmx-request .chat-indicator { display: flex; }
.htmx-request.chat-indicator { display: flex; }

/* ---------- resumen ya hecho: lo mas valioso del sitio, tiene que resaltar ---------- */
.plain-link { color: var(--text); }
.plain-link:hover { color: var(--text); }
.summary-highlight {
  display: flex; align-items: center; gap: 0.5rem;
  background: var(--highlight-bg); border: 1.5px solid var(--highlight-border);
  border-radius: var(--radius-sm); padding: 0.55rem 0.85rem; margin: 0.4rem 0;
  transition: transform .1s ease, box-shadow .15s ease, background-color .15s ease;
}
.summary-highlight:hover { background: var(--highlight-bg-hover); transform: translateY(-1px); box-shadow: var(--shadow); text-decoration: none; }
.summary-highlight-main { display: flex; align-items: center; gap: 0.5rem; min-width: 0; }
.summary-highlight-icon { color: var(--highlight-strong); flex-shrink: 0; width: 18px; height: 18px; }
.summary-highlight-title { font-weight: 700; color: var(--highlight-text); font-size: 0.92rem; }
.summary-highlight-lang { background: rgba(0,0,0,0.08); color: var(--highlight-text); }
.summary-highlight-date { margin-left: auto; font-size: 0.72rem; color: var(--highlight-text); opacity: 0.75; flex-shrink: 0; }

/* ---------- hub del paper: recursos ---------- */
.paper-meta { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0.2rem 0 1rem; font-size: 0.85rem; }
.hub-resources h2 { margin: 0 0 0.4rem; }
.hub-summary { margin: 0 0 1.2rem; }
.form-actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.hub-summary-links { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; margin: 0.35rem 0 0.5rem; }
.hub-pending { margin: 0.4rem 0 0.8rem; padding-left: 1.2rem; }
.resource-card {
  display: flex; align-items: center; gap: 0.7rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-elevated);
  padding: 0.65rem 0.85rem; margin: 0.5rem 0; color: var(--text); text-decoration: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.resource-card:hover { border-color: var(--accent); box-shadow: var(--shadow); text-decoration: none; color: var(--text); }
.resource-card > svg { width: 1.4rem; height: 1.4rem; flex-shrink: 0; color: var(--text-muted); }
.resource-card-text { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.resource-card-title { font-weight: 600; font-size: 0.95rem; }
.resource-card-sub { font-size: 0.8rem; color: var(--text-muted); }

/* ---------- badge neutral (largo del resumen, encabezados) ---------- */
.badge-neutral { background: var(--bg-subtle); color: var(--text-muted); }

/* ---------- breadcrumb / contexto de ubicacion ---------- */
.breadcrumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem;
  font-size: 0.85rem; color: var(--text-muted); margin: 0 0 0.6rem;
}
.breadcrumb a { color: var(--text-muted); }
.breadcrumb a:hover { color: var(--accent); }
.breadcrumb span[aria-hidden] { opacity: 0.6; }

/* ---------- exportar: fila de artefactos (PDF, Anki, PPTX, visual abstract) ---------- */
.export-buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; }

/* ---------- tarjetas de estudio en el navegador (sin Anki) ---------- */
.flashcard {
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 1.5rem; margin-top: 1rem; min-height: 15rem;
  display: flex; flex-direction: column; gap: 0.8rem; cursor: pointer;
}
.flashcard:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@keyframes flashcard-in { from { opacity: 0.35; transform: translateX(var(--slide-from, 24px)); } to { opacity: 1; transform: none; } }
.flashcard.is-entering { animation: flashcard-in 0.18s ease; }
.flashcard-counter { font-size: 0.85rem; margin: 0; }
.flashcard-front { font-weight: 700; font-size: 1.15rem; margin: 0; }
.flashcard-back { white-space: pre-line; border-top: 1px dashed var(--border); padding-top: 0.8rem; }
.flashcard-hint { margin-top: auto; font-size: 0.85rem; }

/* ---------- compartir: link + copiar + revocar ---------- */
.share-list { list-style: none; padding: 0; margin: 1rem 0 0; display: flex; flex-direction: column; gap: 0.7rem; }
.share-item { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.share-link { flex: 1; min-width: 12rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem; word-break: break-all; }
.share-copy { padding: 0.4rem 0.8rem; font-size: 0.85rem; }

/* En modo oscuro, la pastilla del largo dentro de la tarjeta ambar no puede ser negra fija
   (la regla base usa rgba(0,0,0,0.08), que en fondo oscuro no aporta contraste). */
:root[data-theme="dark"] .summary-highlight-lang { background: rgba(255,255,255,0.12); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .summary-highlight-lang { background: rgba(255,255,255,0.12); }
}

/* ---------- pagina de error amigable ---------- */
.error-page { text-align: center; padding: 2.5rem 0; }
.error-code { font-size: 3rem; font-weight: 700; letter-spacing: -0.02em; color: var(--text-muted); margin: 0; line-height: 1; }
.error-page h1 { margin: 0.6rem 0 0.4rem; }
.error-actions { margin-top: 1.5rem; }

/* ---------- barra flotante de acciones masivas (biblioteca) ---------- */
/* bottom por encima del chat-dock fijo (spacer de 7rem) para no tapar el composer. */
.bulk-bar {
  display: none; position: fixed; left: 50%; bottom: 8rem; transform: translateX(-50%);
  align-items: center; gap: 0.9rem; padding: 0.55rem 1rem;
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 999px;
  box-shadow: var(--shadow-lg); z-index: 600; flex-wrap: wrap; max-width: 94vw; justify-content: center;
}
.bulk-bar.show { display: flex; }
/* Todas las opciones de la barra al mismo tamaño de letra (pedido explicito de Alvaro). */
.bulk-bar-option { font-size: 0.85rem; font-weight: 600; }
.bulk-bar-count { color: var(--text-muted); font-weight: 500; }
.bulk-bar-danger { color: var(--error-text); }
.bulk-bar-select {
  padding: 0.3rem 0.5rem; border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg-subtle); color: var(--text); cursor: pointer;
}

/* ---------- favoritos (estrella inline en la fila) ---------- */
.favorite-star {
  background: none; border: none; cursor: pointer; font-size: 1.3rem; line-height: 1;
  color: var(--text-muted); padding: 0.1rem 0.2rem;
}
.favorite-star.is-favorite { color: var(--highlight-strong); }
.favorite-star:hover { color: var(--highlight-strong); }

/* ---------- selector de orden compacto (toolbar de biblioteca) ---------- */
.library-sort-form { display: inline-flex; flex-shrink: 0; }
.library-sort-select {
  border: none; background: transparent; color: var(--text-muted);
  font: inherit; font-size: 0.85rem; font-weight: 600; cursor: pointer;
  padding: 0.3rem 0; max-width: 10rem;
}
.library-sort-select:hover { color: var(--text); }
.library-sort-select:focus { outline: none; border: none; box-shadow: none; color: var(--text); }

/* ---------- biblioteca estilo Gmail: sidebar de carpetas + filas + densidad ----------
   OJO: nada de transform/animation persistente en .library-shell ni sus hijos --
   romperia el position:fixed del chat-dock (ver nota en .container mas arriba). */
.container--library { max-width: 1200px; }
.library-shell { display: flex; gap: 1.5rem; align-items: flex-start; }
.library-main { flex: 1; min-width: 0; }

.library-sidebar {
  width: 230px; flex-shrink: 0; position: sticky; top: 4.5rem;
  display: flex; flex-direction: column; gap: 0.15rem; padding: 0.25rem 0;
}
.library-shell.is-collapsed .library-sidebar { display: none; }
.library-nav-link {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.45rem 0.95rem; border-radius: 999px; border: none; background: transparent;
  color: var(--text); font: inherit; font-size: 0.9rem; font-weight: 600;
  text-decoration: none; cursor: pointer; text-align: left; width: 100%; box-sizing: border-box;
  overflow-wrap: anywhere;
}
.library-nav-link:hover { background: var(--bg-subtle); text-decoration: none; }
.library-nav-link.is-active { background: var(--accent-soft); color: var(--accent); }
.library-nav-count { font-size: 0.78rem; font-weight: 600; color: var(--text-muted); flex-shrink: 0; }
.library-nav-link.is-active .library-nav-count { color: inherit; }
.library-nav-divider { border-top: 1px solid var(--border); margin: 0.5rem 0.95rem; }
.library-nav-add { color: var(--accent); justify-content: flex-start; }

.library-toolbar {
  display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
  padding: 0.2rem 0.25rem 0.7rem;
}
.paper-checkbox, .paper-checkbox-master {
  width: 1.15rem; height: 1.15rem; flex-shrink: 0; cursor: pointer; accent-color: var(--accent);
}
.library-nav-btn {
  display: inline-flex; align-items: center; gap: 0.45rem; flex-shrink: 0;
  border: none; background: transparent; color: var(--text-muted);
  font: inherit; font-size: 0.88rem; font-weight: 600; cursor: pointer;
  padding: 0.4rem 0.5rem; border-radius: var(--radius-sm);
}
.library-nav-btn:hover { background: var(--bg-subtle); color: var(--text); }
.library-nav-btn svg { width: 1.1rem; height: 1.1rem; flex-shrink: 0; }
.library-search-form { flex: 1; min-width: 9rem; display: flex; }
.library-search-input {
  flex: 1; min-width: 0; border-radius: 999px; padding: 0.5rem 1.1rem; font-size: 0.9rem;
}
.library-filter-note { margin: 0 0 0.6rem; font-size: 0.85rem; }

.paper-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.paper-row {
  display: flex; align-items: center; gap: 0.6rem; padding: 0.7rem 0.5rem;
  border-bottom: 1px solid var(--border); cursor: pointer;
  transition: background-color .1s ease, box-shadow .1s ease;
}
.paper-row:hover { background: var(--bg-subtle); box-shadow: var(--shadow); }
.paper-row .favorite-star { font-size: 1.15rem; flex-shrink: 0; }
.favorite-form { display: inline-flex; flex-shrink: 0; }

.paper-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.paper-row-titlebar { display: flex; align-items: center; gap: 0.5rem; min-width: 0; }
/* El titulo SIEMPRE se ve completo (pedido de Alvaro 2026-07-23) -- nada de ellipsis
   ni line-clamp; la fila crece lo que haga falta. */
.paper-row-title {
  display: block; min-width: 0; color: var(--text); font-weight: 500; font-size: 0.95rem;
  overflow-wrap: anywhere;
}
.paper-row-title:hover { color: var(--text); text-decoration: none; }
/* Analogo Gmail de "no leido": paper sin ningun resumen listo = trabajo pendiente. */
.paper-row.is-unworked .paper-row-title { font-weight: 700; }
/* Fecha deliberadamente discreta -- "la fecha no nos aporta nada como para ponerla tan
   visible" (Alvaro 2026-07-23). */
.paper-row-date {
  flex-shrink: 0; font-size: 0.72rem; color: var(--text-muted); font-weight: 400;
  align-self: flex-start; padding-top: 0.2rem; opacity: 0.8;
}

/* Tira de iconos de la fila (eleccion de Alvaro 2026-07-28: "solo iconos en una linea").
   Reemplaza a la vez la fila de indicadores (.paper-ind-row) y la de chips con texto
   (.paper-row-resources), que juntas ocupaban dos lineas -- y con ellas se fue el boton
   "Recursos" que las colapsaba en celular: una tira de ~6 iconos entra sin envolver
   incluso a 320px, no hay nada que colapsar. */
.paper-row-icons { display: flex; align-items: center; gap: 0.15rem; margin-top: 0.15rem; }
.res-icon {
  display: inline-flex; align-items: center; gap: 0.15rem; flex-shrink: 0;
  padding: 0.28rem; border-radius: 8px; color: var(--text-muted); text-decoration: none;
  font-size: 0.72rem; font-weight: 700; line-height: 1;
  transition: background-color .12s ease, color .12s ease;
}
.res-icon:hover { background: var(--bg-subtle); color: var(--accent); text-decoration: none; }
.res-icon svg { width: 1.05rem; height: 1.05rem; flex-shrink: 0; }
.res-icon .spinner { width: 0.95rem; height: 0.95rem; }
.res-icon-count { padding-right: 0.1rem; }
/* El resumen listo es la pieza de valor: unico icono con color propio (mismo ambar de
   .summary-highlight, no el gris del resto de la tira). */
.res-icon-summary { color: var(--highlight-strong); }
.res-icon-summary:hover { background: var(--highlight-bg); color: var(--highlight-strong); }
.res-icon-generate { color: var(--accent); }
.res-icon-generate:hover { background: var(--accent-soft); }
.res-icon-pending { cursor: default; }
.res-icon-pending:hover { background: transparent; }

.resource-chip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-size: 0.78rem; font-weight: 600; padding: 0.22rem 0.65rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--bg-elevated); color: var(--text);
  text-decoration: none;
}
.resource-chip:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.resource-chip svg { width: 0.85rem; height: 0.85rem; flex-shrink: 0; }

/* Miniatura de la pagina 1 (solo vista comoda; el <img> lazy cae al icono si 404). */
.paper-thumb {
  position: relative; width: 3.2rem; height: 4.2rem; flex-shrink: 0;
  border: 1px solid var(--border); border-radius: 6px; background: var(--bg-subtle);
  overflow: hidden; display: flex; align-items: center; justify-content: center;
  color: var(--text-muted);
}
.paper-thumb svg { width: 1.3rem; height: 1.3rem; }
.paper-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; }

/* Densidad: compacta = sin miniatura y todo en 1 linea; comoda = miniatura + iconos.
   La tira de iconos ya NO se esconde en compacta -- es el unico acceso a los recursos
   desde la biblioteca, esconderla dejaba la vista compacta sin ninguna via. */
.paper-list.density-compact .paper-thumb { display: none; }
.paper-list.density-compact .paper-row { padding: 0.45rem 0.5rem; }

/* Escritorio compacto: los iconos en la MISMA linea del titulo (1 fila real). */
@media (min-width: 900px) {
  .paper-list.density-compact .paper-row-body { flex-direction: row; align-items: center; gap: 0.6rem; }
  .paper-list.density-compact .paper-row-titlebar { flex: 1; }
  .paper-list.density-compact .paper-row-icons { flex-shrink: 0; margin-top: 0; }
  .paper-list.density-compact .paper-row-date { align-self: center; padding-top: 0; }
}

/* Movil: el sidebar se vuelve drawer fijo (sin animacion de transform, ver nota arriba). */
@media (max-width: 899px) {
  .library-sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; width: min(80vw, 300px);
    background: var(--bg-elevated); border-right: 1px solid var(--border);
    box-shadow: var(--shadow-lg); z-index: 710; padding: 1.1rem 0.7rem; overflow-y: auto;
    display: none;
  }
  .library-sidebar.is-open { display: flex; }
  /* El colapso persistente es solo de escritorio: si quedo guardado, no debe impedir
     abrir el drawer en el telefono. */
  .library-shell.is-collapsed .library-sidebar.is-open { display: flex; }
  .library-drawer-backdrop { position: fixed; inset: 0; background: rgba(15, 20, 30, 0.45); z-index: 705; }
  .paper-row { padding: 0.75rem 0.3rem; }
}

/* ---------- calificacion (solo estrellas, auto-envia por htmx al click) ---------- */
.rating-prompt { margin-bottom: 0.5rem; }
.rating-optional { opacity: 0.7; }
.rating-form { display: flex; align-items: center; gap: 0.8rem; }
.star-rating { display: inline-flex; flex-direction: row-reverse; justify-content: flex-end; gap: 0.15rem; font-size: 1.7rem; width: fit-content; }
.star-rating input {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.star-rating label { color: var(--border); cursor: pointer; transition: color .1s ease; }
.star-rating input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.star-rating input:checked ~ label { color: var(--highlight-strong); }
.star-rating label:hover, .star-rating label:hover ~ label { color: var(--highlight-strong); }
.rating-saved { font-size: 0.85rem; }

/* ---------- voz leida del resumen: boton play junto al titulo ---------- */
.upload-cta { gap: 0.5rem; flex-shrink: 0; }
.upload-cta svg { width: 1.05rem; height: 1.05rem; }

.summary-paper-title { font-size: 1.1rem; font-weight: 650; color: var(--text); margin: 0 0 0.35rem; }
.summary-heading { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; }
.summary-heading h1 { margin: 0; }
/* Antes contenia el widget de audio completo (width 100%/max-width 22.5rem); ahora son
   dos botones pastilla (Recursos + Aa), ancho natural. */
.summary-heading-controls { display: flex; align-items: flex-start; gap: 0.5rem; flex-shrink: 0; }
.summary-heading-controls .reading-settings-menu { margin-top: 0.05rem; }
/* ---------- menu Recursos (audio + tarjetas + presentacion + visual abstract) ---------- */
/* El panel NO se ancla al boton (que no es el elemento mas a la derecha: tiene Aa y el
   hamburguesa al lado, y sus 20rem se salian de pantalla por la izquierda -- mismo bug
   que tuvo el panel del hamburguesa, reporte de Alvaro 2026-07-22): el wrapper queda
   static y el panel se ancla al contenedor de la fila (.topbar-right o
   .summary-heading-controls), cuyo borde derecho SI es el borde real. */
.artifacts-menu { position: static; }
.topbar-right { position: relative; }
.summary-heading-controls { position: relative; }
.artifacts-menu-panel { min-width: min(20rem, calc(100vw - 2rem)); }
.artifacts-menu-panel .audio-play-wrap { width: 100%; max-width: none; margin: 0.3rem 0 0.5rem; }
.artifacts-menu-panel .header-menu-link { padding: 0.55rem 0.7rem; }
.audio-play-wrap { display: flex; flex-direction: column; align-items: flex-start; gap: 0.4rem; flex-shrink: 0; width: 100%; max-width: 20rem; }
.audio-play-row { display: flex; }
/* Oculto hasta el primer play -- antes se mostraba siempre, ocupando espacio sin dar
   ninguna informacion util (reportado por Alvaro 2026-07-22). Una vez que aparece (JS
   agrega .is-visible en el primer click) no se vuelve a ocultar ni siquiera al pausar. */
.audio-controls-row { display: none; align-items: center; gap: 0.4rem; width: 100%; }
.audio-controls-row.is-visible { display: flex; }
.audio-play-button {
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.5rem 1rem; border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg-elevated); color: var(--text); cursor: pointer; flex-shrink: 0;
  font-size: 0.85rem; font-weight: 600;
  transition: background-color .15s ease, transform .1s ease, border-color .15s ease;
}
.audio-play-button:hover { border-color: var(--accent); transform: translateY(-1px); }
.audio-play-button:active { transform: translateY(0) scale(0.96); }
.audio-play-button svg { width: 1rem; height: 1rem; flex-shrink: 0; }
.audio-play-button .icon-play { margin-left: 1px; }
.audio-play-button.is-playing { border-color: var(--accent); color: var(--accent); }
.audio-play-button .spinner { width: 1rem; height: 1rem; }
.audio-skip-button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.9rem; height: 1.9rem; border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg-elevated); color: var(--text-muted); cursor: pointer; flex-shrink: 0;
  padding: 0; transition: border-color .15s ease, color .15s ease;
}
.audio-skip-button svg { width: 0.95rem; height: 0.95rem; }
.audio-skip-button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.audio-skip-button:disabled { opacity: 0.4; cursor: default; }
.audio-progress-wrap { display: flex; align-items: center; gap: 0.5rem; flex: 1; min-width: 0; }
.audio-progress { flex: 1; min-width: 3rem; accent-color: var(--accent); cursor: pointer; }
.audio-progress:disabled { opacity: 0.4; cursor: default; }
.audio-time { font-size: 0.75rem; color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; flex-shrink: 0; }
.audio-play-error { font-size: 0.8rem; color: var(--error-text); }

/* ---------- resaltados del PDF (lista dentro del menu Recursos) ---------- */
:root {
  --hl-yellow-solid: #ffd43b; --hl-yellow: rgba(255, 212, 59, 0.55);
  --hl-green-solid: #69db7c; --hl-green: rgba(105, 219, 124, 0.5);
  --hl-blue-solid: #66d9e8; --hl-blue: rgba(102, 217, 232, 0.5);
  --hl-pink-solid: #f783ac; --hl-pink: rgba(247, 131, 172, 0.5);
}
.highlight-list { width: 100%; display: flex; flex-direction: column; gap: 0.5rem; max-height: 16rem; overflow-y: auto; }
.highlight-item { display: flex; align-items: flex-start; gap: 0.5rem; }
.highlight-dot { width: 0.7rem; height: 0.7rem; border-radius: 50%; flex-shrink: 0; margin-top: 0.35rem; }
/* Vista "Resaltados" (papers/highlights.html): todos los resaltados juntos como texto
   continuo, un parrafo por resaltado con su circulo de color. */
.highlight-flow { display: flex; flex-direction: column; gap: 0.9rem; margin-top: 1rem; }
.highlight-flow-item { margin: 0; display: flex; align-items: flex-start; gap: 0.6rem; }
.highlight-dot.hl-dot-yellow { background: var(--hl-yellow-solid); }
.highlight-dot.hl-dot-green { background: var(--hl-green-solid); }
.highlight-dot.hl-dot-blue { background: var(--hl-blue-solid); }
.highlight-dot.hl-dot-pink { background: var(--hl-pink-solid); }
.highlight-item-body { flex: 1; min-width: 0; }
.highlight-item-text {
  font-size: 0.82rem; color: var(--text); margin: 0 0 0.15rem;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.highlight-item-meta { font-size: 0.72rem; margin: 0; }
.highlight-item-actions { display: flex; align-items: center; gap: 0.35rem; margin-top: 0.3rem; }
.highlight-copy {
  font: inherit; font-size: 0.76rem; font-weight: 600; padding: 0.3rem 0.6rem;
  border-radius: 999px; border: 1px solid var(--border); background: var(--bg-elevated);
  color: var(--text); cursor: pointer;
}
.highlight-copy:hover { border-color: var(--accent); }
.highlight-delete-form { margin: 0; }
.highlight-delete-btn {
  font: inherit; line-height: 1; padding: 0.3rem 0.55rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--bg-elevated); color: var(--text-muted); cursor: pointer;
}
.highlight-delete-btn:hover { border-color: var(--error-text); color: var(--error-text); }

/* ---------- visor de PDF con marcador de colores (reemplaza el PDF nativo del navegador) ---------- */
/* Margen superior para dejar lugar a la barra del marcador, que flota fija sobre el
   viewport (ver .pdf-highlight-toolbar) sin ocupar espacio en el flujo. */
.pdf-viewer-wrap { display: flex; flex-direction: column; align-items: center; gap: 0.9rem; margin-top: 3.6rem; }
/* El scroll del visor termina EXACTO en la ultima hoja del PDF (pedido de Alvaro: "al
   hacer scroll solo debe llegar hasta la ultima pagina, no seguir mas adelante") -- se
   anula el padding inferior estandar del contenedor (4rem, 3rem en movil) solo cuando
   adentro vive el visor. Mayor especificidad que las reglas de .container, no depende
   del orden. */
main.container:has(.pdf-viewer-wrap) { padding-bottom: 0; }
.pdf-viewer-status { font-size: 0.85rem; color: var(--text-muted); text-align: center; }
/* Cada palabra del PDF es un <span class="pdf-word"> hijo del span de linea de pdf.js
   (ver splitSpansIntoWords en pdf-viewer.js): es la unidad que se resalta y se borra.
   El override de position es OBLIGATORIO -- la hoja de pdf.js declara
   `.textLayer :is(span, br) { position: absolute }`, que aplica tambien a estos hijos y
   los apilaria a todos en el origen del span padre. El padre sigue siendo el absoluto
   con el transform/scaleX; las palabras son inline dentro de esa caja. */
.textLayer span.pdf-word { position: static; display: inline; }
/* position:fixed + reposicionado continuo en JS con la Visual Viewport API (pedido de
   Alvaro: la barra debe mantenerse SIEMPRE en la misma posicion de pantalla y del mismo
   tamano, con o sin zoom, hasta el final del documento). transform-origin 0 0 es CLAVE:
   el contrapeso del zoom es `scale(1/s) translateX(-50%)` -- primero el translate (en px
   sin escalar), despues el scale sobre el origen; con ese orden el punto anclado en
   `left` queda siempre en el centro visual sin importar el zoom. El orden inverso (que
   estaba antes) corria la barra de lugar al zoomear porque el -50% se resolvia sobre el
   ancho sin escalar. El left/top/transform de aca son solo el estado inicial pre-JS. */
.pdf-highlight-toolbar {
  position: fixed; top: 4.5rem; left: 50%; transform: translateX(-50%); transform-origin: 0 0;
  z-index: 25; display: flex; gap: 0.6rem; align-items: center;
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 999px;
  padding: 0.5rem 0.7rem; box-shadow: var(--shadow-lg);
}
.pdf-info-btn {
  width: 1.7rem; height: 1.7rem; border-radius: 50%; border: 2px solid transparent;
  cursor: pointer; padding: 0; box-shadow: inset 0 0 0 1px var(--border);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-subtle); color: var(--text-muted);
}
.pdf-info-wrap { position: relative; display: inline-flex; }
.pdf-info-pop {
  position: absolute; top: calc(100% + 0.7rem); right: -0.5rem; width: min(76vw, 19rem);
  background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
  padding: 0.8rem 0.95rem; z-index: 26;
  font-size: 0.82rem; color: var(--text-muted); text-align: left; line-height: 1.45;
}
.pdf-info-pop p { margin: 0 0 0.55rem; }
.pdf-info-pop p:last-child { margin-bottom: 0; }
.pdf-color-swatch {
  width: 1.7rem; height: 1.7rem; border-radius: 50%; border: 2px solid transparent;
  cursor: pointer; padding: 0; box-shadow: inset 0 0 0 1px var(--border);
}
.pdf-color-swatch[data-color="yellow"] { background: var(--hl-yellow-solid); }
.pdf-color-swatch[data-color="green"] { background: var(--hl-green-solid); }
.pdf-color-swatch[data-color="blue"] { background: var(--hl-blue-solid); }
.pdf-color-swatch[data-color="pink"] { background: var(--hl-pink-solid); }
.pdf-color-swatch.is-active { border-color: var(--text); transform: scale(1.15); }
.pdf-eraser-btn {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-subtle); color: var(--text-muted);
}
.pdf-eraser-btn.is-active { color: var(--error-text); border-color: var(--error-text); }
.pdf-viewer-pages { display: flex; flex-direction: column; align-items: center; gap: 1rem; width: 100%; }
.pdf-page {
  position: relative; background: #fff; border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg); overflow: hidden;
}
.pdf-page canvas { display: block; }
.pdf-highlight-layer { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.pdf-highlight-mark { position: absolute; pointer-events: none; mix-blend-mode: multiply; border-radius: 2px; }
.pdf-highlight-mark.pdf-highlight-yellow { background: var(--hl-yellow); }
.pdf-highlight-mark.pdf-highlight-green { background: var(--hl-green); }
.pdf-highlight-mark.pdf-highlight-blue { background: var(--hl-blue); }
.pdf-highlight-mark.pdf-highlight-pink { background: var(--hl-pink); }
/* La capa de texto de pdf.js ya no sirve para seleccionar (reemplazada por el marcador de
   tocar-para-resaltar) -- se desactiva la seleccion nativa para que no compita con el tap
   (lupa/menu contextual de iOS al mantener presionado). */
.textLayer { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
/* Con un color armado, el pan de 1 dedo sobre el texto es "pintar" (arrastre de
   seleccion en bloque, ancla->foco -- ver pdf-viewer.js) -- se bloquea solo ese gesto;
   el zoom nativo de 2 dedos sigue vivo. Sin color armado no se toca touch-action
   (scroll normal). */
.textLayer.highlight-armed { touch-action: pinch-zoom; }

/* ---------- misc ---------- */
ul { padding-left: 1.3rem; }
li { margin-bottom: 0.3rem; }
section + section { margin-top: 1.75rem; padding-top: 1.75rem; border-top: 1px solid var(--border); }

@media (max-width: 480px) {
  .container { padding: 1.25rem 1rem 3rem; }
  h1 { font-size: 1.4rem; }
  .card { padding: 1.5rem; }
  .topbar { padding: 0.5rem 0.85rem; }

  .summary-highlight { padding: 0.45rem 0.7rem; gap: 0.4rem; }
  .summary-highlight-title { font-size: 0.85rem; }
  .summary-highlight-icon { width: 16px; height: 16px; }
  .summary-highlight-lang { font-size: 0.72rem; padding: 0.1rem 0.45rem; }

  /* Pagina de login/registro: que entre en pantalla sin scroll en celulares chicos. */
  .container--no-header { padding-top: 0; padding-bottom: 0.75rem; }
  .page-center { padding: 0.6rem 0.75rem; min-height: 0; }
  .card { padding: 1.15rem; }
  .card-header { margin-bottom: 0.85rem; }
  .card-header .brand-mark { margin-bottom: 0.5rem; }
  .card-header h1 { font-size: 1.25rem; }
  .divider { margin: 0.85rem 0; }
  .form { gap: 0.65rem; }
  .form-footer { margin-top: 0.7rem; }
}
