/**
 * Clubia - Componentes UI
 * Librería de componentes reutilizables
 */

@import './tokens.css';

/* ========================================
   BOTONES
   ======================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  font-family: var(--font-headings);
  font-size: var(--text-base);
  font-weight: var(--font-semibold);
  letter-spacing: 0.01em;
  text-align: center;
  text-decoration: none;
  border: none;
  border-radius: var(--radius-button);
  cursor: pointer;
  transition: all var(--duration-base) var(--ease-out-quad);
  min-height: var(--touch-min);
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* Botón primario */
.btn-primary {
  background-color: var(--primary);
  color: var(--parchment);
  box-shadow: var(--shadow-primary);
}

@media (hover: hover) {
  .btn-primary:hover {
    background-color: var(--primary-hover);
    transform: translateY(-1px);
    box-shadow: 0 10px 24px rgba(110, 139, 94, 0.30);
  }
}

/* Botón acento (terracota) */
.btn-accent {
  background-color: var(--accent);
  color: var(--parchment);
  box-shadow: 0 8px 20px rgba(196, 124, 90, 0.22);
}
@media (hover: hover) {
  .btn-accent:hover {
    background-color: var(--accent-hover);
    transform: translateY(-1px);
  }
}
.btn-accent:active {
  background-color: var(--accent-pressed);
  transform: translateY(0);
}

.btn-primary:active {
  background-color: var(--primary-pressed);
  transform: translateY(0);
}

/* Botón secundario */
.btn-secondary {
  background-color: var(--primary-light);
  color: var(--primary);
}

@media (hover: hover) {
  .btn-secondary:hover {
    background-color: var(--primary-20);
  }
}

.btn-secondary:active {
  background-color: var(--primary-30);
}

/* Botón ghost */
.btn-ghost {
  background-color: transparent;
  color: var(--text-primary);
  box-shadow: none;
}

@media (hover: hover) {
  .btn-ghost:hover {
    background-color: var(--bg-tertiary);
  }
}

/* Botón outline */
.btn-outline {
  background-color: transparent;
  color: var(--primary);
  border: 2px solid var(--primary);
  box-shadow: none;
}

@media (hover: hover) {
  .btn-outline:hover {
    background-color: var(--primary-light);
  }
}

/* Tamaños de botones */
.btn-sm {
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  border-radius: var(--radius-md);
}

.btn-lg {
  padding: var(--space-4) var(--space-8);
  font-size: var(--text-lg);
}

.btn-full {
  width: 100%;
}

/* ========================================
   TARJETAS (CARDS)
   ======================================== */

/* Fondo avena sobre pergamino, sin sombra. Epílogo separa por color y filete,
   no por elevación: la única sombra del contenido es la de las portadas, que
   son objetos físicos. Esta decisión estaba repetida como `.card{box-shadow:none}`
   en cuatro páginas y olvidada en otras seis, así que las de clubs flotaban y
   las de Reflexiones no. Vive aquí. */
.card {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  box-shadow: none;
  transition: all var(--duration-base) var(--ease-out-quad);
}

/* Sin usar hoy. Se marca el hover con el filete, coherente con el resto. */
@media (hover: hover) {
  .card-hover:hover {
    border-color: var(--primary);
  }
}

.card-compact {
  padding: var(--space-3);
}

.card-spacious {
  padding: var(--space-6);
}

/* Tarjeta de libro */
.book-card {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-4);
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  transition: all var(--duration-base) var(--ease-out-quad);
}

.book-card__cover {
  flex-shrink: 0;
  width: 80px;
  height: 112px;
  border-radius: var(--radius-sm);
  background-size: cover;
  background-position: center;
  box-shadow: var(--shadow-md);
}

.book-card__content {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.book-card__title {
  font-size: var(--text-base);
  font-weight: var(--font-bold);
  color: var(--text-primary);
  line-height: var(--leading-tight);
}

.book-card__meta {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/* ========================================
   FORMULARIOS
   ======================================== */

.form-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.form-label {
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--text-primary);
}

/* El mensaje de error de un campo.
 *
 * Vive aquí y no copiada en el `<style>` de cada página, que es como estaba y
 * por eso hacía falta: SEIS pantallas la usaban desde su JS sin haberla
 * declarado —perfil, actividad, editoriales, bandejas, resumen y anticipadas—,
 * así que sus avisos de error salían en negro y a tamaño de párrafo, que es
 * justo no parecer un error.
 *
 * No rompe nada donde ya estaba copiada: la declaración es la misma y el
 * `<style>` de la página va después, así que gana el suyo y se ve igual. */
.campo-error {
  color: var(--error);
  font-size: 0.76rem;
  margin-top: 0.35rem;
}

.form-input,
.form-textarea,
.form-select {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-base);
  font-family: var(--font-sans);
  color: var(--text-primary);
  background-color: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  transition: all var(--duration-base) var(--ease-out-quad);
  min-height: var(--touch-min);
}

.form-input:focus,
.form-textarea:focus,
.form-select:focus,
input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--primary) !important;
  box-shadow: 0 0 0 3px var(--primary-light) !important;
  --tw-ring-color: var(--primary) !important;
}

.form-input::placeholder,
.form-textarea::placeholder {
  color: var(--text-secondary);
  opacity: 0.6;
}

.form-textarea {
  min-height: 120px;
  resize: vertical;
}

/* --- Campos que crecen con el texto (reflexiones, comentarios, respuestas) ---
   El alto lo calcula js/autogrow.js; aquí solo el marco. Pasado el máximo, el
   campo scrollea por dentro en vez de comerse la pantalla: en móvil manda el
   viewport (con el teclado abierto queda poco sitio) y en pantallas altas se
   corta en 22rem para que no se separe del botón de enviar.
   Se puede afinar por campo con --autogrow-max. */
textarea.autogrow {
  resize: none;          /* el alto lo lleva el JS; el tirador estorbaría */
  overflow-x: hidden;    /* el texto ajusta línea: nunca scroll horizontal */
  overflow-y: auto;
  max-height: var(--autogrow-max, min(40vh, 22rem));
}

.form-error {
  font-size: var(--text-sm);
  color: var(--error);
  margin-top: var(--space-1);
}

.form-hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin-top: var(--space-1);
}

/* Checkbox y Radio personalizados */
.form-checkbox,
.form-radio {
  appearance: none;
  width: 20px;
  height: 20px;
  border: 2px solid var(--border-color);
  border-radius: var(--radius-sm);
  background-color: var(--bg-tertiary);
  cursor: pointer;
  transition: all var(--duration-fast) var(--ease-out-quad);
  position: relative;
}

.form-radio {
  border-radius: var(--radius-full);
}

.form-checkbox:checked,
.form-radio:checked {
  background-color: var(--primary);
  border-color: var(--primary);
}

.form-checkbox:checked::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 5px;
  width: 6px;
  height: 10px;
  border: solid white;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.form-radio:checked::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: white;
  transform: translate(-50%, -50%);
}

/* ========================================
   BADGES Y TAGS
   ======================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  border-radius: var(--radius-full);
  white-space: nowrap;
}

.badge-primary {
  background-color: var(--primary-light);
  color: var(--primary);
}

.badge-success {
  background-color: rgba(59, 178, 115, 0.1);
  color: var(--success);
}

.badge-warning {
  background-color: rgba(245, 165, 36, 0.1);
  color: var(--warning);
}

.badge-error {
  background-color: rgba(229, 72, 77, 0.1);
  color: var(--error);
}

/* ========================================
   BARRA DE PROGRESO
   ======================================== */

.progress {
  width: 100%;
  height: 8px;
  background-color: var(--bg-tertiary);
  border-radius: var(--radius-full);
  overflow: hidden;
}

.progress__bar {
  height: 100%;
  background-color: var(--primary);
  border-radius: var(--radius-full);
  transition: width var(--duration-slow) var(--ease-out-quad);
}

.progress-sm {
  height: 4px;
}

.progress-lg {
  height: 12px;
}

/* ========================================
   AVATAR
   ======================================== */

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background-color: var(--bg-tertiary);
  background-size: cover;
  background-position: center;
  overflow: hidden;
}

.avatar-sm {
  width: 32px;
  height: 32px;
  font-size: var(--text-sm);
}

.avatar-md {
  width: 48px;
  height: 48px;
  font-size: var(--text-base);
}

.avatar-lg {
  width: 64px;
  height: 64px;
  font-size: var(--text-lg);
}

/* ========================================
   TOAST / NOTIFICACIONES
   ======================================== */

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  background-color: var(--bg-secondary);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  border-left: 4px solid var(--primary);
  animation: slideInRight var(--duration-slow) var(--ease-out-quad);
  /* La capa la lleva el componente, no la clase de turno. El JS pedía `z-60`,
     que NO existe en la escala de Tailwind, así que el toast se quedaba sin
     z-index y la cabecera —que sí tiene z-30— lo tapaba: salía, pero detrás.
     Un aviso tiene que estar por encima de todo menos de los tooltips. */
  z-index: var(--z-toast);
}

/* El icono va del mismo color que la franja lateral: los dos dicen lo mismo —de
   qué tipo es el aviso— y en negro el icono no decía nada. El selector directo
   deja fuera la aspa de cerrar, que está dentro del <button> y debe seguir
   siendo discreta. */
.toast > .material-symbols-outlined {
  color: var(--primary);
}

.toast-success {
  border-left-color: var(--success);
}

.toast-success > .material-symbols-outlined {
  color: var(--success);
}

.toast-warning {
  border-left-color: var(--warning);
}

.toast-warning > .material-symbols-outlined {
  color: var(--warning);
}

.toast-error {
  border-left-color: var(--error);
}

.toast-error > .material-symbols-outlined {
  color: var(--error);
}

@keyframes slideInRight {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

/* ========================================
   SKELETON LOADING
   ======================================== */

.skeleton {
  background: linear-gradient(
    90deg,
    var(--bg-tertiary) 0%,
    var(--bg-secondary) 50%,
    var(--bg-tertiary) 100%
  );
  background-size: 200% 100%;
  animation: skeleton-loading 1.5s ease-in-out infinite;
  border-radius: var(--radius-sm);
}

@keyframes skeleton-loading {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

.skeleton-text {
  height: 1em;
  margin-bottom: var(--space-2);
}

.skeleton-avatar {
  border-radius: var(--radius-full);
}

/* ========================================
   DIVIDER
   ======================================== */

.divider {
  height: 1px;
  background-color: var(--border-color);
  margin: var(--space-4) 0;
}

.divider-vertical {
  width: 1px;
  height: auto;
  margin: 0 var(--space-4);
}

/* ========================================
   TABS
   ======================================== */

.tabs {
  display: flex;
  gap: var(--space-4);
  border-bottom: 1px solid var(--border-color);
}

.tab {
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--text-secondary);
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: all var(--duration-base) var(--ease-out-quad);
  white-space: nowrap;
}

@media (hover: hover) {
  .tab:hover {
    color: var(--text-primary);
  }
}

.tab-active {
  color: var(--primary);
  border-bottom-color: var(--primary);
  font-weight: var(--font-bold);
}

/* ========================================
   MODAL
   ======================================== */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background-color: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(4px);
  z-index: var(--z-modal-backdrop);
  animation: fadeIn var(--duration-base) var(--ease-out-quad);
}

.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 90%;
  max-width: 500px;
  max-height: 90vh;
  overflow-y: auto;
  background-color: var(--bg-primary);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  z-index: var(--z-modal);
  animation: scaleIn var(--duration-slow) var(--ease-out-quad);
}

.modal__header {
  padding: var(--space-6);
  border-bottom: 1px solid var(--border-color);
}

.modal__body {
  padding: var(--space-6);
}

.modal__footer {
  padding: var(--space-6);
  border-top: 1px solid var(--border-color);
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.9);
  }
  to {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
}

/* ========================================
   UTILIDADES ESPECÍFICAS DE CLUBIA
   ======================================== */

/* Placeholder de IA */
.ai-placeholder {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background-color: var(--primary-light);
  border: 1px dashed var(--primary);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  color: var(--primary);
  font-weight: var(--font-medium);
}

.ai-placeholder::before {
  content: '✨';
}

/* Estado vacío */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-12) var(--space-6);
  gap: var(--space-4);
}

.empty-state__icon {
  font-size: 4rem;
  opacity: 0.3;
}

.empty-state__title {
  font-size: var(--text-2xl);
  font-weight: var(--font-bold);
  color: var(--text-primary);
}

.empty-state__message {
  font-size: var(--text-base);
  color: var(--text-secondary);
  max-width: 400px;
}

/* ========================================
   NOTIFICACIONES
   ======================================== */

.notification-group {
  margin-bottom: var(--space-6);
}

.notification-group__title {
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: var(--space-3);
  letter-spacing: 0.05em;
}

.notification-group__items {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.notification {
  display: flex;
  align-items: start;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  box-shadow: none;
  transition: all var(--duration-base) var(--ease-out-quad);
}

@media (hover: hover) {
  .notification:hover {
    box-shadow: var(--shadow-md);
  }
}

/* Notificación que lleva a algún sitio: se pinta como <a>, así que hay que
   neutralizar el color y el subrayado del enlace. Las que no tienen destino
   (por ejemplo avisos antiguos sin referencia) siguen siendo un <div>. */
.notification--link {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}
@media (hover: hover) {
  .notification--link:hover {
    border-color: var(--primary);
  }
}
.notification--link:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
/* Flecha de "esto se puede pulsar", alineada con el icono de la izquierda. */
.notification__go {
  display: flex;
  align-items: center;
  align-self: center;
  color: var(--text-tertiary);
  flex-shrink: 0;
}

/* Pendiente de consultar: se ha abierto la bandeja pero esto no se ha pulsado.
   El resalte NO caduca, así que tener media lista así es lo NORMAL — y por eso
   es deliberadamente discreto.

   Antes era fondo verde claro + borde + icono relleno en blanco sobre verde:
   con dos o tres notificaciones pasaba, pero con quince gritaba, y un resalte
   que grita en toda la pantalla deja de señalar nada.

   Ahora son tres señales pequeñas que suman: un filete a la izquierda, un fondo
   apenas distinto y el título algo más marcado. La barra vertical es la que de
   verdad se ve al recorrer la lista con la vista, y es la única que no depende
   de distinguir dos tonos casi iguales. */
.notification--pendiente {
  border-left: 3px solid var(--primary);
  padding-left: calc(var(--space-4) - 2px);
  background-color: var(--bg-primary);
}

.notification--pendiente .notification__title {
  font-weight: var(--font-semibold);
}

.notification__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-full);
  background-color: var(--primary-20);
  color: var(--primary);
  flex-shrink: 0;
}

/* Los avisos que pesan más: un cambio de fecha o una cancelación.
   Un recordatorio se lee y se olvida; que se caiga algo que tenías guardado
   cambia los planes de alguien que quizá ya había reservado la tarde.

   Se distingue por el COLOR del icono y no por el fondo de la fila, que es
   donde vive el resalte de «pendiente»: dos señales en el mismo sitio se
   pisarían, y una notificación puede ser las dos cosas a la vez.

   Y es el acento, no un rojo: sigue siendo una agenda, no una alarma. */
.notification__icon--peso {
  background-color: var(--accent-light);
  color: var(--accent);
}

.notification__content {
  flex: 1;
  min-width: 0;
}

.notification__title {
  font-size: var(--text-base);
  font-weight: var(--font-semibold);
  color: var(--text-primary);
  margin-bottom: var(--space-1);
}

.notification__text {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin-bottom: var(--space-2);
  line-height: var(--leading-normal);
}

.notification__time {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}

.notification__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* Notification badge para navbar */
.notification-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: var(--radius-full);
  background-color: var(--accent);
  color: var(--parchment);
  font-size: 10px;
  font-weight: var(--font-bold);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 4px rgba(44, 42, 37, 0.2);
}

/* ========================================
   EPÍLOGO v2 — COMPONENTES NUEVOS
   ======================================== */

/* Wordmark de marca */
.wordmark {
  font-family: var(--font-headings);
  font-weight: var(--font-semibold);
  color: var(--primary);
  letter-spacing: -0.01em;
}

/* --- Tab bar inferior (navegación principal) --- */
.tab-bar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  display: flex;
  background-color: var(--parchment);
  border-top: 1px solid var(--border-color);
  padding: var(--space-2) var(--space-2) calc(var(--space-2) + env(safe-area-inset-bottom));
  z-index: var(--z-fixed);
}
.tab-bar__item {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: var(--space-2) 0;
  color: var(--taupe);
  text-decoration: none;
  font-family: var(--font-sans);
  font-size: 10px; font-weight: var(--font-medium);
  position: relative;
  transition: color var(--duration-base) var(--ease-out-quad);
}
.tab-bar__item .material-symbols-outlined { font-size: 24px; }
.tab-bar__item.is-active { color: var(--primary); }
.tab-bar__item.is-active .material-symbols-outlined { font-variation-settings: 'FILL' 1; }
.tab-bar__item.is-active::after {
  content: ''; position: absolute; bottom: 2px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--primary);
}

/* Cuánto ocupa la barra de pestañas. Vive aquí y no repartido en cada
   pantalla porque lo necesitan las barras de acción fijas para apoyarse encima
   en vez de quedar debajo y no poder pulsarse. */
:root { --tab-bar-alto: 72px; }

/* Una barra de acción fija que se apoya SOBRE la de pestañas. Sustituye a la
   clase `bottom-0` en las pantallas que tienen las dos. */
.sobre-tab-bar {
  bottom: calc(var(--tab-bar-alto) + env(safe-area-inset-bottom));
}

/* --- FAB (acción flotante, terracota) --- */
/**
 * El botón flotante: la acción principal del sitio donde estás.
 *
 * Nace VERDE. Estaba en terracota y las pantallas que lo usaban lo repintaban
 * con un estilo en línea; con ocho pantallas eso serían ocho sitios que tocar
 * el día que cambie el verde. Los inline que quedan pintan exactamente esto
 * mismo, así que no se ven, pero ya no hacen falta.
 *
 * No lleva texto a propósito. Un botón con etiqueta visible mide el triple de
 * ancho y tapa contenido justo donde el pulgar ya está; el nombre de la acción
 * va en `aria-label`, que es lo que lee un lector de pantalla y lo que sale al
 * mantenerlo pulsado.
 */
.fab {
  position: fixed;
  right: var(--space-6);
  bottom: calc(88px + env(safe-area-inset-bottom));
  width: 60px; height: 60px;
  display: flex; align-items: center; justify-content: center;
  background-color: var(--primary);
  color: var(--parchment);
  border: none; border-radius: var(--radius-full);
  box-shadow: 0 10px 24px rgba(110, 139, 94, 0.35);
  cursor: pointer;
  z-index: var(--z-sticky);
  transition: transform var(--duration-base) var(--ease-out-quad);
}
@media (hover: hover) { .fab:hover { transform: scale(1.06); } }
.fab:active { transform: scale(0.98); }
.fab .material-symbols-outlined { font-size: 28px; }

/* --- Texto largo con "Mostrar más" ---
   Se recorta a cuatro líneas. El botón lo enseña el JS solo cuando de verdad
   sobra texto (comparando scrollHeight con clientHeight), así que un comentario
   corto nunca lo ve. */
.texto-largo__cuerpo {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Interlineado de lectura: la sinopsis es prosa, no interfaz. */
  line-height: 1.6;
}
.texto-largo.esta-abierto .texto-largo__cuerpo {
  -webkit-line-clamp: unset;
  display: block;
  overflow: visible;
}
.texto-largo__mas {
  margin-top: 2px;
  padding: 2px 0;
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  color: var(--primary);
  background: none; border: none; cursor: pointer;
}
@media (hover: hover) { .texto-largo__mas:hover { text-decoration: underline; } }
.texto-largo__mas:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* --- Invitación a instalar la app (login) ---
   Discreta: es una sugerencia, no la acción por la que se entra a la pantalla.
   Por eso va en avena con borde, y no en el oliva de las acciones del producto. */
.instalar-app {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  max-width: 22rem;
  margin: var(--space-6) auto 0;
  padding: var(--space-3) var(--space-4);
  background-color: var(--oat);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
}
.instalar-app__icono {
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex-shrink: 0;
  border-radius: var(--radius-full);
  background-color: var(--primary-20);
  color: var(--primary);
}
.instalar-app__icono .material-symbols-outlined { font-size: 1.2rem; }
.instalar-app__texto { flex: 1; min-width: 0; }
.instalar-app__titulo {
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--text-primary);
}
.instalar-app__nota {
  font-size: 11px;
  line-height: 1.35;
  color: var(--text-secondary);
}
.instalar-app__accion {
  flex-shrink: 0;
  height: 36px; padding: 0 var(--space-3);
  border: none; border-radius: var(--radius-md);
  background-color: var(--primary);
  color: var(--parchment);
  font-size: var(--text-sm); font-weight: var(--font-semibold);
  cursor: pointer;
}
.instalar-app__cerrar {
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; margin-right: calc(var(--space-2) * -1);
  border: none; background: none;
  color: var(--text-tertiary);
  border-radius: var(--radius-full);
  cursor: pointer;
}
.instalar-app__cerrar .material-symbols-outlined { font-size: 1.05rem; }

/* --- Portada ausente ---
   Antes era un emoji 📖, que cada sistema dibuja a su manera y desentonaba con
   el resto. Ahora es el icono de la tipografía de iconos, en el oliva de marca
   sobre el fondo de avena: se lee como parte de la app y no como un parche.
   El tamaño lo pone quien lo usa con --portada-icono, porque la miniatura de
   una lista y la portada de una rejilla no piden lo mismo. */
.portada-vacia {
  position: absolute;
  inset: 0;
  /* `display` NO se pone aquí: lo trae el atributo `style` de cada elemento,
     porque es lo que alterna entre `none` y `flex` cuando la imagen falla.
     Ojo: si se declarara aquí, ganaría el inline y daría igual; el problema
     real fue tener DOS atributos style, y el navegador ignora el segundo. */
  align-items: center;
  justify-content: center;
  color: var(--primary);
  opacity: 0.45;
}
.portada-vacia .material-symbols-outlined {
  font-size: var(--portada-icono, 2rem);
  /* Trazo algo más fino: a este tamaño el peso normal se ve tosco. */
  font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 48;
}

/* --- Tarjeta de libro en rejilla ---
   El contador vivía superpuesto sobre la portada y con cifras de cinco dígitos
   se comía la imagen. Ahora la portada queda limpia y todo lo demás va debajo,
   con ALTURAS RESERVADAS: dos líneas para el título y una para el autor, aunque
   sobren, para que las tarjetas de una misma fila queden alineadas por abajo
   pase lo que pase con la longitud de los títulos. */
.libro-card {
  display: flex;
  flex-direction: column;
}
.libro-card__portada {
  aspect-ratio: 2 / 3;                 /* misma proporción en todas */
  border-radius: var(--radius-md);
  background-color: var(--oat-deep);
  overflow: hidden;
  position: relative;
  box-shadow: var(--shadow-md);
  transition: box-shadow var(--duration-base) var(--ease-out-quad);
}
@media (hover: hover) { .group:hover .libro-card__portada { box-shadow: var(--shadow-lg); } }

.libro-card__titulo {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--text-primary);
  line-height: 1.25;
  /* Dos líneas exactas: se recorta lo que sobre y se reserva el hueco. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(2 * 1.25em);
}
.libro-card__autor {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-height: 1.3em;
}
/* Contador debajo de la portada, nunca encima. */
.libro-card__meta {
  margin-top: var(--space-1);
  display: flex; align-items: center; gap: 4px;
  font-size: 11px;
  font-weight: var(--font-semibold);
  color: var(--primary);
  white-space: nowrap;
}
.libro-card__meta .material-symbols-outlined { font-size: 13px; }
/* Sin reflexiones: invitación en terracota, no un hueco vacío. */
.libro-card__meta--vacio { color: var(--accent); font-weight: var(--font-medium); }

/* --- Volver arriba ---
   Discreto a propósito: es una ayuda, no una acción del producto, así que va en
   pergamino con borde en vez de en color de marca, para no competir con la
   pluma. Por defecto se sienta donde iría el FAB; si la página ya tiene uno,
   `--sobre-fab` lo apila encima. */
.volver-arriba {
  position: fixed;
  right: var(--space-6);
  bottom: calc(88px + env(safe-area-inset-bottom));
  width: 44px; height: 44px;          /* zona pulsable mínima */
  display: flex; align-items: center; justify-content: center;
  background-color: var(--parchment);
  color: var(--text-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-full);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.10);
  cursor: pointer;
  z-index: var(--z-sticky);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--duration-base) var(--ease-out-quad),
              transform var(--duration-base) var(--ease-out-quad);
}
.volver-arriba.is-visible { opacity: 1; transform: translateY(0); }
@media (hover: hover) { .volver-arriba:hover { color: var(--primary); border-color: var(--primary); } }
.volver-arriba:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.volver-arriba .material-symbols-outlined { font-size: 22px; }

/* El FAB mide 60px y arranca en 88px: 60 + 12 de aire = 160px. */
.volver-arriba--sobre-fab { bottom: calc(160px + env(safe-area-inset-bottom)); }

/* Sin animación para quien la haya desactivado en el sistema. */
@media (prefers-reduced-motion: reduce) {
  .volver-arriba { transition: none; transform: none; }
}

/* --- Tabs segmentadas (pill): Leídos / Leyendo / Deseados --- */
.segmented {
  display: inline-flex;
  gap: var(--space-1);
  padding: var(--space-1);
  background-color: var(--oat);
  border-radius: var(--radius-full);
}
.segment {
  padding: var(--space-2) var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--taupe);
  background: transparent;
  border: none; border-radius: var(--radius-full);
  cursor: pointer; white-space: nowrap;
  transition: all var(--duration-base) var(--ease-out-quad);
}
.segment.is-active {
  background-color: var(--primary);
  color: var(--parchment);
}
/* Las pestañas de la Biblioteca son ENLACES: cada área es su propia página.
   Sin esto se leerían subrayadas y desalineadas respecto a las de botón. */
a.segment {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  text-align: center;
  text-decoration: none;
}

/* Segmentos que se reparten el ancho de la pantalla.

   El control de arriba está pensado para dos o tres opciones cortas que se
   miden por su contenido. En cuanto las etiquetas crecen —las cuatro áreas de
   la Biblioteca, o «Con reflexión»— su relleno de 16px por lado se come el
   sitio: en un móvil de 375px se lleva 128 de los 343 disponibles, y la última
   opción se salía por la derecha.

   Las etiquetas en sí nunca fueron el problema. Medidas con Arial (más ancha
   que Golos Text, así que la cuenta va sobrada), las cuatro áreas necesitan 78
   de los 81px que les tocan. Lo que sobraba era el relleno.

   Aquí el ancho se reparte a partes iguales, el relleno baja al mínimo y la
   letra se ajusta al de la pantalla. La fórmula sale de esa medición: mantiene
   «Pendientes» entero desde 320px y llega a los 14px de siempre a partir de
   414. El recorte con puntos suspensivos es la red por si una fuente cae más
   ancha de lo previsto. */
.segmented--repartido {
  display: flex;
  width: 100%;
}
.segmented--repartido .segment {
  flex: 1 1 0;
  min-width: 0;   /* sin esto ninguna opción baja del ancho de su propio texto */
  display: block;
  padding: 0 var(--space-1);
  min-height: 44px;
  line-height: 44px;   /* centra sin relleno vertical y deja la zona pulsable */
  font-size: clamp(0.6875rem, 4.6vw - 4px, var(--text-sm));
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Los botones del pie de un modal.

   `.btn` está pensado para el cuerpo de una página: píldora, tipografía de
   titulares y sombra que levanta al pasar por encima. En un pie de modal eso
   desentonaba con el botón de los paneles inferiores —ancho, rectángulo
   redondeado y tipografía de cuerpo—, que es el patrón de la casa para
   confirmar dentro de una capa.

   Se reparten el ancho: con un solo botón sale ancho del todo, como en los
   paneles; con dos, a mitades. */
.modal-pie .btn {
  flex: 1 1 0;
  min-width: 0;
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  border-radius: var(--radius-sm);
  box-shadow: none;
}
@media (hover: hover) {
  .modal-pie .btn:hover {
    transform: none;
    box-shadow: none;
    filter: brightness(0.95);
  }
}
.modal-pie .btn:active {
  transform: scale(0.99);
}

/* El título de un paso numerado dentro de un formulario largo (crear club).
   Numerar convierte una pila de campos en una secuencia con final. */
.paso-titulo {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-sans);
  font-size: 0.92rem;
  font-weight: var(--font-semibold);
  color: var(--charcoal);
}

/* --- Tarjeta prompt (bloque de color: reflexión del día) --- */
.prompt-card {
  position: relative;
  overflow: hidden;
  background-color: var(--primary);
  color: var(--parchment);
  border-radius: var(--radius-card);
  padding: var(--space-6);
  box-shadow: var(--shadow-soft);
}
.prompt-card__label {
  font-family: var(--font-headings);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  opacity: 0.85;
  margin-bottom: var(--space-2);
}
.prompt-card__title {
  font-family: var(--font-headings);
  font-size: var(--text-xl);
  font-weight: var(--font-semibold);
  line-height: var(--leading-snug);
}

/* ==========================================================================
   Utilidad de estado: .hidden SIEMPRE gana
   ==========================================================================
   Este archivo se carga DESPUÉS de tailwind.css, así que con la misma
   especificidad (una clase) las reglas de componente que fijan `display`
   (.empty-state, .notification-badge, .fab, .badge, .toast…) ganaban a
   `.hidden{display:none}` y el elemento seguía visible aunque el JS le
   añadiera la clase. Con el Tailwind por CDN no pasaba: se inyectaba en
   runtime y quedaba el último en la cascada.
   Todo el código hace classList.add('hidden') para ocultar, así que esta
   utilidad debe imponerse siempre. */
.hidden {
  display: none !important;
}

/* ========================================
   UTILIDADES SUELTAS
   ======================================== */

/* Las tiras de pestañas que se desplazan a lo ancho la usan desde siempre,
   pero nunca estuvo definida: viene del plugin tailwind-scrollbar-hide, que
   no está instalado. La barra se veía en escritorio, cortando el diseño. */
.scrollbar-hide {
  -ms-overflow-style: none;   /* Edge antiguo */
  scrollbar-width: none;      /* Firefox */
}

.scrollbar-hide::-webkit-scrollbar {
  display: none;              /* Chrome, Safari */
}

/* --- Pestañas de orden/estado ---------------------------------------
   La tira de pestañas que ordena una lista (reflexiones por fecha, libros
   por estado). Vivía suelta en el <style> de book-reflections; al usarla una
   segunda pantalla se sube aquí, que es donde no se desincroniza. */
.sort-tab.is-active {
  color: var(--primary);
  border-color: var(--primary);
}

/* ========================================
   AUTOR VERIFICADO
   ======================================== */

/* El distintivo que acompaña al nombre del autor en sus intervenciones. Se
   trata como un estado más de la reflexión —igual que "editado"— pero con peso
   propio: quien lee tiene que distinguirlo sin buscarlo. */
.insignia-autor,
.insignia-rol {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 7px 1px 5px;
  border-radius: 100px;
  font-size: 0.68rem;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
}

/* Autor verificado: en verde, porque es una distinción de cara al lector. */
.insignia-autor {
  background-color: var(--primary-light);
  color: var(--primary);
}

/* El rol dentro de Epílogo. Va en neutro a propósito: ser administrador no es
   un mérito que mostrar junto a los demás distintivos, es saber con qué
   permisos estás entrando. */
.insignia-rol {
  background-color: var(--oat-deep);
  color: var(--taupe);
}

.insignia-autor .material-symbols-outlined,
.insignia-rol .material-symbols-outlined {
  font-size: 0.85rem;
  font-variation-settings: 'FILL' 1;
}

/* Controles nativos con el color de Epílogo.
 *
 * El calendario que abre un campo de fecha lo dibuja el navegador, no nosotros:
 * no se puede maquetar. Lo único que acepta es `accent-color`, que tiñe el día
 * seleccionado y los controles de sistema. Es lo más cerca del oliva que se
 * puede llegar sin construir un calendario propio.
 */
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="checkbox"],
input[type="radio"],
input[type="range"],
progress {
  accent-color: var(--primary);
}

/* El iconito del calendario, en el mismo tono que el resto de la interfaz. */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.55;
}
@media (hover: hover) {
  input[type="date"]:hover::-webkit-calendar-picker-indicator,
  input[type="time"]:hover::-webkit-calendar-picker-indicator,
  input[type="datetime-local"]:hover::-webkit-calendar-picker-indicator {
    opacity: 1;
  }
}

/* ==========================================================================
   SELECTOR DE FECHAS
   ==========================================================================
   El calendario propio de Epílogo, que sustituye al del sistema. Vive aquí y
   no en la pantalla que lo usa porque es de toda la aplicación: Biblioteca,
   Lecturas, Agenda y lo que venga.

   El `<input type="date">` original sigue en el DOM, oculto: si este CSS o su
   JS no llegaran a cargar, queda un campo de fecha nativo y usable. */

/* El campo visible: se lee como los demás inputs de la aplicación. */
.campo-fecha {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  min-height: 44px;
  padding: 0.625rem 1rem;
  border: 1px solid var(--oat-deep);
  border-radius: 0.75rem;
  background: #fff;
  color: var(--charcoal);
  font-family: var(--font-sans);
  font-size: 0.875rem;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s ease;
}
@media (hover: hover) { .campo-fecha:hover { border-color: color-mix(in srgb, var(--primary) 50%, transparent); } }
.campo-fecha:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 30%, transparent);
}
.campo-fecha__icono { font-size: 1.1rem; color: var(--taupe); flex-shrink: 0; }
.campo-fecha__texto { flex: 1; min-width: 0; }
/* Sin fecha se lee como un marcador de posición, no como un dato. */
.campo-fecha__texto--vacio { color: var(--taupe); }

/* El panel. En móvil sube desde abajo, como el resto de hojas; en pantallas
   grandes se queda centrado. */
.calendario-fondo {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: color-mix(in srgb, var(--charcoal) 40%, transparent);
  backdrop-filter: blur(2px);
}
@media (min-width: 640px) {
  .calendario-fondo { align-items: center; }
}

.calendario {
  width: 100%;
  max-width: 26rem;
  padding: 0.75rem;
  background: var(--parchment);
  border: 1px solid var(--oat-deep);
  border-radius: 1rem 1rem 0 0;
  box-shadow: 0 -8px 32px rgb(0 0 0 / 12%);
}
@media (min-width: 640px) {
  .calendario { border-radius: 1rem; box-shadow: 0 8px 32px rgb(0 0 0 / 16%); }
}

.calendario__cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}
.calendario__mes {
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 1rem;
  color: var(--charcoal);
  text-transform: capitalize;
}
.calendario__flecha {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: var(--taupe);
  transition: background-color 0.15s ease;
}
@media (hover: hover) { .calendario__flecha:hover { background: var(--oat-deep); } }

.calendario__semana,
.calendario__rejilla {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.125rem;
}
.calendario__semana span {
  text-align: center;
  font-size: 0.7rem;
  color: var(--taupe);
  padding-bottom: 0.25rem;
}

/* 44px de lado en todos los días, no solo en los pulsables: si cambiaran de
   tamaño según el estado, la rejilla bailaría al cambiar de mes. */
.calendario__dia {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border-radius: 50%;
  font-size: 0.875rem;
  color: var(--charcoal);
  transition: background-color 0.15s ease;
}
@media (hover: hover) { .calendario__dia:hover:not(:disabled) { background: var(--oat-deep); } }
.calendario__dia:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 40%, transparent);
}
/* Hoy se marca con un borde; el elegido, con relleno. Así se distinguen aunque
   sean el mismo día, y no dependen solo del color. */
.calendario__dia.es-hoy { box-shadow: inset 0 0 0 1.5px var(--primary); font-weight: 600; }
.calendario__dia.esta-elegido {
  background: var(--primary);
  color: var(--parchment);
  font-weight: 700;
}
.calendario__dia:disabled { color: var(--oat-deep); cursor: not-allowed; }

/* La rejilla de meses: cuatro columnas, doce celdas, tres filas. Píldoras y no
   círculos porque llevan tres letras dentro, no un número. Los estados son los
   mismos que los del día —borde para «este mes», relleno para el elegido— para
   que sea reconocible como el mismo componente. */
.calendario__meses {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.375rem;
}
.calendario__mes-celda {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border-radius: 0.75rem;
  font-size: 0.82rem;
  color: var(--charcoal);
  text-transform: capitalize;
  transition: background-color 0.15s ease;
}
@media (hover: hover) { .calendario__mes-celda:hover:not(:disabled) { background: var(--oat-deep); } }
.calendario__mes-celda:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 40%, transparent);
}
.calendario__mes-celda.es-hoy { box-shadow: inset 0 0 0 1.5px var(--primary); font-weight: 600; }
.calendario__mes-celda.esta-elegido {
  background: var(--primary);
  color: var(--parchment);
  font-weight: 700;
}
.calendario__mes-celda:disabled { color: var(--oat-deep); cursor: not-allowed; }

/* Una flecha apagada se ve apagada: sin esto, pulsar en el límite del rango no
   haría nada y parecería que el panel se ha quedado colgado. */
.calendario__flecha:disabled { color: var(--oat-deep); cursor: not-allowed; }

/* ── Campos de texto declarados como búsqueda ──────────────────────────────
   Son campos de texto normales —un título, un personaje, el nombre de una
   saga— escritos como `type="search"` por una razón concreta y comprobada en
   este proyecto: es lo ÚNICO que apaga la barra de autocompletado de Android,
   esa fila con la llave, la tarjeta y la ubicación.

   `autocomplete="off"` no la apaga; se probó y sigue saliendo. Lo que decide es
   el tipo de campo: un `<textarea>` no la muestra y un `type="search"` tampoco,
   pero un `type="text"` sí. Es una palanca del sistema operativo, no nuestra.

   El precio es la X de limpiar que el navegador añade a los campos de búsqueda,
   y aquí no viene a cuento: se quita. Los buscadores DE VERDAD no llevan
   `data-sin-limpiar` y la conservan, que ahí sí sirve. */
[data-sin-limpiar]::-webkit-search-cancel-button,
[data-sin-limpiar]::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}

/* ── Las citas del Diario ──────────────────────────────────────────────────
   Las comillas latinas son del DISEÑO, no del texto: nadie las escribe y no
   entran en lo que se guarda. Si se pidieran a mano, media ficha llevaría
   comillas rectas, otra media inglesas y alguna ninguna.

   `aria-hidden` no hace falta porque son pseudo-elementos: los lectores de
   pantalla no leen el contenido generado por CSS en la mayoría de motores, y
   donde sí lo hacen dicen la comilla, que es correcto. */
.cita-campo { position: relative; }
.cita-campo::before,
.cita-campo::after {
  position: absolute;
  top: 0.6rem;
  color: var(--primary);
  font-family: 'Literata', Georgia, serif;
  font-size: 1.1rem;
  line-height: 1;
  pointer-events: none;    /* la comilla no roba el clic al campo */
}
.cita-campo::before { content: '«'; left: 0.75rem; }
.cita-campo::after  { content: '»'; right: 0.75rem; }

.calendario__pie {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--oat-deep);
}
.calendario__accion {
  flex: 1;
  min-height: 44px;
  border-radius: 0.75rem;
  border: 1px solid var(--oat-deep);
  background: var(--oat);
  color: var(--charcoal);
  font-size: 0.8rem;
  font-weight: 500;
  transition: background-color 0.15s ease;
}
@media (hover: hover) { .calendario__accion:hover { background: var(--oat-deep); } }
.calendario__accion--principal {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--parchment);
  font-weight: 600;
}
@media (hover: hover) { .calendario__accion--principal:hover { filter: brightness(0.95); } }

/* ========================================
   MI BIBLIOTECA — las áreas de la portada
   ======================================== */

/* Las cuatro áreas de Mi Biblioteca, como tarjetas grandes pulsables.

   🔴 Los cuatro son TONOS DEL MISMO VERDE, el de Epílogo. Antes cada área
   tenía su color —avena, terracota, lila, verde— y la pantalla parecía cuatro
   productos distintos puestos en fila: la app se leía como una suma de
   aplicaciones, cada una con su marca.

   Lo que separa una de otra es su icono, su título y lo que dice; el color solo
   las agrupa. Cuatro tonos y no uno porque cuatro cajas idénticas seguidas
   dejan de leerse como cuatro cosas: la escalera va de más claro a más lleno
   siguiendo el orden en que se usan.

   El titular va SIEMPRE en `--charcoal`, que sobre estos fondos pasa de 10:1.
   Lo secundario NO va en taupe: ver `--area-texto` unas líneas más abajo. */
:root {
  --area-leidos: #e5e7e4;        --area-leidos-hondo: #d7ddd3;
  --area-pendientes: #dee4da;    --area-pendientes-hondo: #cfd9c8;
  --area-archivo: #d7e0d1;       --area-archivo-hondo: #c6d4bd;
  --area-diario: #d0dec7;        --area-diario-hondo: #bdd0b2;

  /**
   * El texto secundario SOBRE una de estas tarjetas.
   *
   * ⚠️ No es `--taupe`. El taupe está pensado para el papel de la app y sobre
   * estos fondos se queda en 2,6:1 — AA pide 4,5. Ya andaba justo antes de
   * pasar al verde (3,0:1), así que esto no es un daño nuevo: es una deuda que
   * se salda ahora que se tocaba el color de todas formas.
   *
   * Es del mismo tono verde y sigue leyéndose como secundario al lado del
   * charcoal. Sobre el más oscuro de los cuatro fondos: 4,6:1.
   */
  --area-texto: #5C5F55;
}

.area {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-4);
  border: none;
  border-radius: var(--radius-card);
  background-color: var(--area-fondo, var(--oat));
  color: var(--charcoal);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--duration-base) var(--ease-out-quad),
              filter var(--duration-base) var(--ease-out-quad);
}
@media (hover: hover) { .area:hover { filter: brightness(0.97); } }
.area:active { transform: scale(0.995); }

/* El icono, en su círculo. `flex-shrink-0` porque un título largo no debe
   comerse el círculo. */
.area__icono {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-full);
  background-color: var(--area-circulo, var(--oat-deep));
  color: var(--charcoal);
  flex-shrink: 0;
}
.area__icono .material-symbols-outlined { font-size: 1.6rem; }

.area__cuerpo { flex: 1 1 0; min-width: 0; }

.area__titulo {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-size: 1.02rem;
  font-weight: var(--font-semibold);
  color: var(--charcoal);
}

/* El candado de las dos áreas privadas. Va con `aria-label`, que el icono por
   sí solo no dice nada a quien no lo ve. */
.area__candado { font-size: 1rem; opacity: 0.55; }

.area__texto {
  display: block;
  margin-top: 2px;
  font-size: 0.82rem;
  line-height: 1.45;
  /* Ver `--area-texto`: el taupe no llega a AA sobre estos fondos. */
  color: var(--area-texto);
}

.area__flecha { color: var(--taupe); flex-shrink: 0; }

/* Mi Huella Lectora: con presencia, pero no un botón de compra. Filete y
   fondo de papel, no color de marca. */
.huella-acceso {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-4);
  border: 1px solid var(--oat-deep);
  border-radius: var(--radius-card);
  background-color: var(--oat);
  color: var(--charcoal);
  text-decoration: none;
  transition: border-color var(--duration-base) var(--ease-out-quad);
}
@media (hover: hover) { .huella-acceso:hover { border-color: var(--primary); } }

/* El bloque de Goodreads es secundario y tiene que parecerlo: sin fondo, solo
   un filete. Si compitiera con las áreas, lo primero que vería quien abre su
   biblioteca sería una importación. */
.bloque-secundario {
  border: 1px dashed var(--oat-deep);
  border-radius: var(--radius-card);
  padding: var(--space-4);
  text-align: center;
}

/* ========================================
   LIBROS LEÍDOS — el recorrido por meses
   ======================================== */

/* Un mes con lecturas: una tarjeta que se despliega. Los meses sin nada NO son
   tarjetas —ver `.mes-vacio`—, porque doce cajas vacías convertirían un año
   tranquilo en un cementerio. */
/* El interruptor de pastilla.
 *
 * Es un checkbox de verdad debajo: se llega con el tabulador, se activa con la
 * barra espaciadora y un lector de pantalla lo anuncia como lo que es. Lo único
 * que hace el CSS es taparlo y dibujar la pastilla encima, así que no hay que
 * inventar teclado ni estados.
 *
 * Va donde el interruptor ES la explicación —«Mostrar reflexiones» y poco más—.
 * Para lo que necesita una frase debajo sigue valiendo la casilla normal: una
 * pastilla con dos renglones al lado pesa demasiado en la fila. */
.pastilla {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  width: 52px;
  height: 30px;
  cursor: pointer;
}

.pastilla input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.pastilla__via {
  position: absolute;
  inset: 0;
  border-radius: var(--radius-full);
  background-color: var(--oat-deep);
  transition: background-color var(--duration-base) var(--ease-out-quad);
  pointer-events: none;
}

/* La bolita. Se mueve con `transform` y no con `left`, que es lo que hace que
   el movimiento sea suave sin recalcular la maquetación en cada fotograma. */
.pastilla__bola {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-full);
  background-color: #FFFFFF;
  box-shadow: 0 1px 3px rgba(44, 42, 37, 0.28);
  transition: transform var(--duration-base) var(--ease-out-quad);
  pointer-events: none;
}

.pastilla input:checked ~ .pastilla__via { background-color: var(--primary); }
.pastilla input:checked ~ .pastilla__bola { transform: translateX(22px); }

/* El foco se pinta sobre la pastilla, no sobre el checkbox invisible: si no,
   quien navega con el tabulador vería el anillo en un cuadrado transparente. */
.pastilla input:focus-visible ~ .pastilla__via {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* La fila entera: el nombre a la izquierda, el interruptor a la derecha. */
.ajuste {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) 0;
}
.ajuste + .ajuste { border-top: 1px solid var(--oat-deep); }

.ajuste__nombre {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  color: var(--charcoal);
  min-width: 0;
}

@media (prefers-reduced-motion: reduce) {
  .pastilla__via,
  .pastilla__bola { transition: none; }
}

/* ─────────────────────────────────────────────────────────────────────────
   LOS DOCE MESES

   Cada mes es un degradado sobre el papel, sin ilustración ninguna. Antes había
   doce escenas dibujadas en SVG; se retiraron enteras.

   🔴 Son doce tonos del MISMO verde, el de Epílogo. Antes eran un recorrido
   del oliva a la terracota, y eso significaba que dos meses del mismo año no
   compartían color de marca: agosto era naranja. Epílogo es verde, blanco y
   neutros, y la Huella de un año no es el sitio para estrenar una segunda
   familia de colores.

   Pero doce meses idénticos convierten el año en una pared. Así que lo que
   cambia no es el TONO —fijo en el verde de la marca— sino dos cosas:

     COLOR   cuánto verde tiene. Enero casi ninguno; agosto, lleno. Sube y
             vuelve a bajar: es el péndulo de las estaciones, el mismo de
             antes, pero dentro del verde.
     LUZ     cuánto papel se le ve debajo. Va al revés que el color, y es lo
             que hace que el invierno se lea frío en vez de «verde pálido».

   No es simétrico: el final del año pesa un poco más que el principio, y eso
   es lo único que separa marzo de noviembre.

   El extremo de abajo de cada banda se inclina hacia el mes que va debajo en la
   pantalla, para que el año fluya en vez de escalonarse.

   Van escritos y no calculados a propósito: la regla queda aquí explicada, pero
   una hoja de estilos con aritmética de color dentro no hay quien la mire. El
   generador que los produjo vive en el cuaderno de trabajo; si hay que
   rehacerlos, se rehacen los doce de golpe y se pegan aquí.

   El peor contraste del texto sobre estos fondos es 11,3:1 — AA pide 4,5.
   ───────────────────────────────────────────────────────────────────────── */
.mes--m0 { --alto: #e5e7e4; --bajo: #edeeec; }   /* Enero */
.mes--m1 { --alto: #e2e6e0; --bajo: #edeeec; }   /* Febrero */
.mes--m2 { --alto: #dee4da; --bajo: #eaede9; }   /* Marzo */
.mes--m3 { --alto: #dae2d4; --bajo: #e6eae4; }   /* Abril */
.mes--m4 { --alto: #d4e0cc; --bajo: #e1e6dd; }   /* Mayo */
.mes--m5 { --alto: #cfdfc3; --bajo: #dce3d7; }   /* Junio */
.mes--m6 { --alto: #c9ddbb; --bajo: #d6dfd0; }   /* Julio */
.mes--m7 { --alto: #c5dcb4; --bajo: #d2dccc; }   /* Agosto */
.mes--m8 { --alto: #cbddbd; --bajo: #d8dfd3; }   /* Septiembre */
.mes--m9 { --alto: #d0dec7; --bajo: #dde2da; }   /* Octubre */
.mes--m10 { --alto: #d6dfd0; --bajo: #e3e5e0; }   /* Noviembre */
.mes--m11 { --alto: #dce1d8; --bajo: #e8e9e7; }   /* Diciembre */

.mes {
  /* Un mes, un color, de arriba abajo. Antes solo se teñía la cabecera y el
     cuerpo se quedaba en avena: dos blancos rotos a cuatro unidades de
     distancia, demasiado cerca para leerse como una decisión y demasiado lejos
     para parecer el mismo color. Se veía como un fallo de pintado.
     Sin estación —la banda de «Sin fecha»— cae en el papel de siempre. */
  background-color: var(--bajo, var(--oat));
  /* Un negro translúcido y no un color fijo: así el borde vale sobre los cuatro
     tintes del año sin necesitar un token por estación. */
  border: 1px solid rgba(44, 42, 37, 0.10);
  border-radius: var(--radius-card);
  margin-bottom: var(--space-2);
  overflow: hidden;
}

.mes__cabecera {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  /* La portada del mes, no un renglón: alta para que el degradado tenga
     sitio donde recorrerse. */
  min-height: 56px;
  padding: var(--space-3) var(--space-4);
  /* El degradado del mes. Termina justo en el tono del cuerpo de la tarjeta,
     así que la costura entre cabecera y lista no se ve: es el mismo color
     donde se tocan. */
  background-image: linear-gradient(180deg, var(--alto, var(--oat)) 0%, var(--bajo, var(--oat)) 100%);
  background-color: transparent;
  border: none;
  color: var(--charcoal);
  text-align: left;
  cursor: pointer;
  overflow: hidden;
}
/* Oscurecer en vez de pintar de otro color: así vale igual sobre los doce
   degradados del año y sobre la banda sin teñir de «Sin fecha». */
@media (hover: hover) { .mes__cabecera:hover { filter: brightness(0.97); } }

/* Todo lo que se lee va por encima del fondo. */
.mes__nombre,
.mes__cuantos,
.mes__flecha { position: relative; z-index: 1; }

/* ─────────────────────────────────────────────────────────────────────────
   MES Y AÑO, ALINEADOS

   Los nombres de los meses miden cosas distintas —MAYO y SEPTIEMBRE— así que
   escritos seguidos el año bailaba de una tarjeta a otra y el año entero se
   leía torcido.

   🔴 Se arregla con REJILLA, nunca metiendo espacios en el texto. Un espacio
   escrito depende del tipo de letra, no sobrevive a un cambio de tamaño y se
   lo comen los lectores de pantalla, que dirían «septiembre    dos mil
   veintiséis» con una pausa que no significa nada.

   La primera columna es fija y la comparten las doce tarjetas: por eso está en
   `:root` y no aquí. Vale para cualquier tipo de letra siempre que quepa
   SEPTIEMBRE, que es el más largo; si algún día no cupiera, se sube ESE número
   y ya está — es lo único que hay que tocar. Sobra ancho a propósito: de más
   solo se gana separación, de menos se descuadra otra vez. */
.mes__nombre {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  grid-template-columns: var(--ancho-mes) auto;
  align-items: baseline;
  font-family: var(--font-sans);
  font-size: 0.86rem;
  font-weight: var(--font-semibold);
  letter-spacing: 0.06em;
}

/* Sin partirse nunca: un mes en dos líneas rompería la rejilla entera. */
.mes__mes,
.mes__ano { white-space: nowrap; }

/* El año, un punto más apagado: es el dato de contexto, no el titular. Y en la
   misma línea de base, para que no parezca pegado a otro sitio. */
.mes__ano { color: var(--taupe); font-weight: var(--font-normal); }

.mes__cuantos {
  font-size: 0.76rem;
  color: var(--taupe);
  white-space: nowrap;
}

.mes__flecha {
  color: var(--taupe);
  transition: transform var(--duration-base) var(--ease-out-quad);
}
.mes__cabecera[aria-expanded="true"] .mes__flecha { transform: rotate(180deg); }

.mes__cuerpo { padding: 0 var(--space-4) var(--space-2); }

/* Los separadores entre libros vienen puestos en avena desde la fila, que se
   comparte con otras pantallas. Sobre un mes teñido esa avena desafina, así que
   aquí —y solo aquí— se cambian por el mismo negro translúcido del borde: una
   raya que es siempre un pelo más oscura que el papel que tenga debajo, sea el
   que sea. */
.mes__cuerpo [data-libro] { border-bottom-color: rgba(44, 42, 37, 0.08); }

/* El icono del mes sin lecturas. Los meses CON libros llevan ya su color de
   fondo; aquí, que es una línea y no una tarjeta, no cabe más que esto. */
.marca-mes {
  color: var(--primary);
  opacity: 0.22;
  flex-shrink: 0;
}

/* Un mes sin lecturas. Lleva su color como los demás —el año se lee como un
   año, no como una lista con huecos— pero pesa menos y no promete nada: es un
   encabezado, no un botón, así que no lleva flecha ni reacciona al ratón. Una
   flecha que al pulsarla no abre nada molesta más que no tenerla.

   Y va más tenue, para que de un vistazo se vea dónde hay algo tuyo. No es otro
   color: es el suyo aguado con papel, así que un mes vacío y el mismo mes con
   libros se siguen reconociendo como el mismo mes. */
.mes--vacio .mes__cabecera {
  min-height: 36px;
  cursor: default;
  margin: 0;
  /* El relleno baja con la altura. Con el de un mes normal —12px arriba y
     abajo— el texto y sus márgenes ya suman más de 36, así que la altura no se
     alcanzaría nunca y los doce acabarían midiendo lo mismo. */
  padding: var(--space-1) var(--space-4);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--alto) 55%, var(--parchment)) 0%,
    color-mix(in srgb, var(--bajo) 55%, var(--parchment)) 100%);
}
@media (hover: hover) { .mes--vacio .mes__cabecera:hover { filter: none; } }

.mes--vacio { background-color: color-mix(in srgb, var(--bajo) 55%, var(--parchment)); }

.mes--vacio .mes__nombre { color: var(--taupe); font-weight: var(--font-medium); }

/* Los iconos del final de una fila de libro: reflexión, ficha y el menú.
   Cada uno con su propia zona de 44px, porque están pegados y un dedo no
   distingue tres cosas dentro del mismo cuadrado. */
.fila-icono {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border: none;
  background: none;
  border-radius: var(--radius-full);
  color: var(--primary);
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--duration-base) var(--ease-out-quad);
}
@media (hover: hover) { .fila-icono:hover { background-color: var(--oat-deep); } }

/* Un dato ya elegido de una lista corta: un género, una palabra descubierta.
   Se lee como algo puesto sobre la ficha, no como un botón que hace algo, así
   que va en el papel de la aplicación y no en el color de acción. La única
   parte pulsable es el aspa, y esa sí tiene sus 44px. */
.puesto {
  display: inline-flex;
  align-items: center;
  gap: 0.1rem;
  padding-left: 0.75rem;
  border: 1px solid var(--oat-deep);
  border-radius: var(--radius-full);
  background-color: var(--oat);
  font-family: var(--font-sans);
  font-size: 0.82rem;
  color: var(--charcoal);
  max-width: 100%;
  overflow-wrap: anywhere;
}

.puesto__quitar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  margin-right: -0.6rem;
  border: none;
  background: none;
  border-radius: var(--radius-full);
  color: var(--taupe);
  cursor: pointer;
  transition: color var(--duration-base) var(--ease-out-quad);
}
@media (hover: hover) { .puesto__quitar:hover { color: var(--charcoal); } }

/* El menú es del dueño y no es contenido: se distingue en gris. */
.fila-icono[data-menu] { color: var(--taupe); }

/* La acción de un aviso: «Deshacer». Se lee como un botón sin serlo del todo,
   porque compite con el mensaje y no debe ganarle. */
.toast__accion {
  flex-shrink: 0;
  padding: var(--space-1) var(--space-2);
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--primary);
  text-decoration: underline;
  cursor: pointer;
  min-height: var(--touch-min);
}
@media (hover: hover) { .toast__accion:hover { background-color: var(--primary-light); } }

/* ─────────────────────────────────────────────────────────────────────────
   LA TARJETA DE UNA LECTURA

   Una fila, no una celda de cuadrícula: el libro a la izquierda y lo que hace
   falta para decidir a la derecha. Nada de contadores de participantes — un
   número de gente al lado de un libro se lee como popularidad, y la pregunta
   de esta pantalla es «¿qué quiero leer acompañado?», no «¿qué lleva más
   apuntados?».
   ───────────────────────────────────────────────────────────────────────── */
.lectura {
  display: block;
  position: relative;
  background-color: var(--oat);
  border: 1px solid var(--oat-deep);
  border-radius: var(--radius-card, 14px);
  padding: var(--space-3);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--duration-base) var(--ease-out-quad);
}

@media (hover: hover) { .lectura:hover { border-color: var(--taupe-soft, var(--taupe)); } }

.lectura__fila { display: flex; gap: var(--space-3); align-items: flex-start; }

.lectura__datos { flex: 1; min-width: 0; }

.lectura__titulo {
  display: block;
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 0.98rem;
  line-height: 1.25;
  color: var(--charcoal);
}

.lectura__autor,
.lectura__quien {
  display: block;
  font-size: 0.78rem;
  color: var(--taupe);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lectura__autor { margin-top: 2px; }
.lectura__quien { margin-top: var(--space-2); }

/* El estado: lo que contesta «¿llego a tiempo?». Es el dato que más se mira,
   así que va en el color de acción y no en el gris de los secundarios. */
.lectura__estado {
  display: block;
  margin-top: 2px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--primary);
}

.lectura__estado--pasado { color: var(--taupe); font-weight: 500; }

/* Los sellos. Se leen SIEMPRE, no solo se ven: el filete de color es refuerzo
   y nunca la única señal, porque quien no distingue el oliva de la terracota
   se quedaría sin la información. */
.lectura__sellos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin-bottom: var(--space-2);
}

.lectura__sello {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px var(--space-2);
  border-radius: 999px;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.lectura__sello .material-symbols-outlined { font-size: 0.85rem; }

/* Organizada por el autor. Manda sobre el otro sello cuando coinciden: es un
   hecho sobre el libro, no una preferencia de quien mira. */
.lectura__sello--autor {
  background-color: color-mix(in srgb, var(--accent) 15%, transparent);
  color: var(--accent);
}

.lectura--autor { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }

/* Sigues sus próximas lecturas. Es una relación TUYA con quien organiza, así
   que se dice en segundo plano y sin ningún número detrás. */
.lectura__sello--seguido {
  background-color: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--primary);
}

.lectura--seguido { border-color: color-mix(in srgb, var(--primary) 40%, transparent); }

/* Cuando coinciden, el filete es el del autor y el seguimiento se queda solo
   en su sello. Dos bordes distintos en la misma tarjeta no se pueden pintar. */
.lectura--autor.lectura--seguido { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }

/* Ya estás dentro: no es un sello de la lectura, es tu situación en ella. */
.lectura__dentro {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: var(--space-2);
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--primary);
}

/* ── Los filtros ── */
.filtros {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  padding-bottom: var(--space-1);
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.filtros::-webkit-scrollbar { display: none; }

.filtro {
  flex-shrink: 0;
  min-height: 36px;
  padding: 0 var(--space-3);
  border: 1px solid var(--oat-deep);
  border-radius: 999px;
  background-color: var(--oat);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--taupe);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--duration-base) var(--ease-out-quad);
}

@media (hover: hover) { .filtro:hover { background-color: var(--oat-deep); } }

.filtro[aria-pressed="true"] {
  background-color: var(--primary);
  border-color: var(--primary);
  color: var(--parchment);
}

/* ─────────────────────────────────────────────────────────────────────────
   POR DÓNDE VA LA LECTURA

   Una línea partida en tantos trozos como partes tenga, con los abiertos en el
   color de la casa y los que faltan en gris. Contesta a UNA pregunta —«¿por
   dónde van?»— y a ninguna más.

   No es una barra de progreso: no dice cuánto ha leído nadie, ni un porcentaje,
   ni lleva número. Sirve para que quien todavía no participa calcule de un
   vistazo si le da tiempo a entrar. Y se actualiza sola, porque las fechas ya
   son la programación: no hay nada que pulsar ni que mantener al día.
   ───────────────────────────────────────────────────────────────────────── */
.tramos {
  display: flex;
  gap: 3px;
  margin-top: var(--space-2);
}

.tramos__parte {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background-color: var(--oat-deep);
}

.tramos__parte--abierta { background-color: var(--primary); }

/* La que está en marcha ahora mismo: la última abierta. Un punto más viva que
   las anteriores, para que se distinga «por aquí van» de «esto ya pasó». */
.tramos__parte--actual { background-color: var(--accent); }

/* ─────────────────────────────────────────────────────────────────────────
   LA AGENDA LITERARIA

   Una tarjeta de evento contesta a tres cosas y a ninguna más: qué ocurre,
   dónde y cuándo. No hay asistentes, ni «populares», ni contadores: el orden
   es siempre la proximidad, y todo lo que invite a ordenar de otra manera
   sobra en la tarjeta.

   El bloque de fecha va primero, a la izquierda, porque la pregunta con la que
   se entra en esta pantalla es «¿qué hay estos días?» y no «¿de qué va?».
   ───────────────────────────────────────────────────────────────────────── */
.evento {
  display: flex;
  gap: var(--space-3);
  align-items: stretch;
  background-color: var(--oat);
  border: 1px solid var(--oat-deep);
  border-radius: var(--radius-card, 14px);
  padding: var(--space-3);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--duration-base) var(--ease-out-quad);
}

@media (hover: hover) { .evento:hover { border-color: var(--taupe-soft, var(--taupe)); } }

/* Lo que publica el propio autor lleva filete de terracota, igual que en
   Lecturas: es el mismo hecho —«esto viene de quien lo escribió»— y merece la
   misma señal en toda la app. */
.evento--autor { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }

/* Cancelado. No se borra —quien lo tuviera apuntado merece enterarse— pero
   tiene que verse de lejos que ya no se va a celebrar. */
.evento--cancelado { opacity: 0.62; }

.evento__fecha {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 52px;
  border-radius: var(--radius-sm, 10px);
  background-color: var(--parchment);
  border: 1px solid var(--oat-deep);
  color: var(--primary);
  padding: var(--space-2) 0;
}

/* Hoy y mañana en sólido: son los dos únicos días en que la fecha cambia lo
   que haces al leerla. */
.evento__fecha--cerca {
  background-color: var(--primary);
  border-color: var(--primary);
  color: var(--parchment);
}

.evento__dia {
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 1.2rem;
  line-height: 1.05;
}

.evento__mes {
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.evento__hora {
  margin-top: 3px;
  font-size: 0.64rem;
  font-weight: 600;
  opacity: 0.85;
}

.evento__datos { flex: 1; min-width: 0; }

.evento__tipo {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--taupe);
  text-transform: uppercase;
}

.evento__titulo {
  display: block;
  margin-top: 2px;
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 0.98rem;
  line-height: 1.25;
  color: var(--charcoal);
}

.evento__donde {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: var(--space-2);
  font-size: 0.78rem;
  color: var(--taupe);
  min-width: 0;
}

.evento__donde span:last-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.evento__donde .material-symbols-outlined { font-size: 0.95rem; flex-shrink: 0; }

.evento__sello {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: var(--space-2);
  padding: 2px var(--space-2);
  border-radius: 999px;
  font-size: 0.66rem;
  font-weight: 700;
  background-color: color-mix(in srgb, var(--accent) 15%, transparent);
  color: var(--accent);
}

.evento__sello .material-symbols-outlined { font-size: 0.85rem; }

/* El título de cada grupo del listado —hoy, mañana, esta semana— es lo que
   convierte una lista larga en algo que se recorre sin leerlo entero. */
.agenda__grupo {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: var(--space-5) 0 var(--space-2);
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 1rem;
  color: var(--charcoal);
}

.agenda__grupo span { font-family: var(--font-sans); font-size: 0.76rem; font-weight: 600; color: var(--taupe); }

/* ── Botones-opción de los formularios (`grupo()` de diario-ficha y de la
   agenda) ──

   La marca de "esto es lo elegido". Faltaba: los botones llevaban `is-active`
   desde el principio, pero esa clase no tenía ninguna regla en ninguna hoja, y
   el resultado era un grupo de opciones donde solo un lector de pantalla —por
   el `aria-checked`— se enteraba de cuál estaba puesta. */
/* Elegida: oliva sobre oliva claro, como el icono de «Reflexiones de la
   comunidad» en la ficha del libro. Antes era oliva macizo con el texto en
   pergamino, y en una fila de tres o cuatro opciones pesaba demasiado — parecía
   un botón de acción y no una elección hecha. */
.opcion.is-active {
  background-color: color-mix(in srgb, var(--primary) 15%, transparent);
  border-color: var(--primary);
  color: var(--primary);
  font-weight: 600;
}

@media (hover: hover) { .opcion.is-active:hover { border-color: var(--primary); } }

/* ── Opciones compactas ────────────────────────────────────────────────────
   Para las que van en una columna estrecha —el formato, al lado de la portada
   de la ficha— donde las de tamaño normal se comen dos filas.

   El botón se ve más pequeño pero SE SIGUE PUDIENDO PULSAR IGUAL: el
   pseudo-elemento estira el área sensible hasta los 44 px de siempre, por
   arriba y por abajo. Encoger la zona táctil de verdad sería ganar un poco de
   hueco a costa de que la gente falle el toque, que es justo el cambio que no
   se ve al mirar la pantalla en un escritorio. */
/* Las medidas van calculadas, no a ojo. En un móvil de 375 px la columna de al
   lado de la portada mide 215 (375 − 32 de padding − 112 de portada − 16 de
   hueco), y «Físico · E-book · Audiolibro» con el tamaño anterior sumaba
   exactamente 215: cualquier redondeo del navegador los saltaba de línea. Con
   estos quedan en unos 182, con margen de sobra. */
.opciones-compactas .opcion {
  position: relative;
  min-height: 32px;
  padding: 0.25rem 0.45rem;
  font-size: 0.68rem;
  white-space: nowrap;   /* «E-book» partido por el guion queda ridículo */
}

.opciones-compactas .opcion::after {
  content: '';
  position: absolute;
  inset: -6px 0;      /* 32 + 6 + 6 = 44 */
}

/* ─────────────────────────────────────────────────────────────────────────
   AGENDA · LO PRÓXIMO, EN GRANDE

   La portada de la Agenda literaria tiene el mismo esqueleto que la de un
   libro en Reflexiones: primero una ficha grande —bloque visual a la
   izquierda, titular en Ovo, autor enlazado, el dato que importa en oliva—,
   debajo las pestañas subrayadas con su control aparte, y después una lista
   apretada que se recorre rápido.

   La razón de que lo primero sea UN evento y no la lista entera: la pregunta
   con la que se entra aquí es «¿qué hay ahora mismo?». Lo que viene después
   se consulta; lo inminente se decide.
   ───────────────────────────────────────────────────────────────────────── */

.ahora__etiqueta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}

.ahora__etiqueta .material-symbols-outlined { font-size: 0.95rem; }

.ahora {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  margin-top: var(--space-2);
  text-decoration: none;
  color: inherit;
}

/* El cartel: la portada del libro si el evento tiene uno, y si no la fecha en
   grande sobre el oliva. Nunca un hueco vacío — una firma sin libro asociado
   es lo más normal del mundo y no puede verse como un error. */
.cartel {
  flex-shrink: 0;
  width: 8rem;
  aspect-ratio: 2 / 3;
  border-radius: 6px;
  overflow: hidden;
  background-color: var(--oat-deep);
  box-shadow: 0 4px 6px -1px rgb(0 0 0 / 10%), 0 2px 4px -2px rgb(0 0 0 / 10%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--taupe-soft);
}

.cartel img { width: 100%; height: 100%; object-fit: cover; }

.cartel--fecha {
  background-image: linear-gradient(160deg, #6E8B5E 0%, #56704A 100%);
  color: var(--parchment);
}

.cartel__n { font-family: var(--font-headings); font-weight: 700; font-size: 2.75rem; line-height: 0.95; }
.cartel__mes { font-size: 0.8rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; }

.ahora__datos { flex: 1; min-width: 0; }

.ahora__tipo {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--taupe);
}

.ahora__tipo .material-symbols-outlined { font-size: 0.95rem; }

.ahora__titulo {
  margin: 4px 0 2px;
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 1.6rem;
  line-height: 1.05;
  color: var(--charcoal);
}

/* El autor, con el subrayado punteado de la ficha del libro: se lee como un
   enlace a una persona y no como un dato más. */
.ahora__autor {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--taupe);
  text-decoration: none;
  font-size: 0.92rem;
}

.ahora__autor span:first-child { text-decoration: underline dotted; text-underline-offset: 2px; }
.ahora__autor .material-symbols-outlined { font-size: 1rem; }

/* El dato en oliva: es lo que se mira y lo que decide si vas o no. */
.ahora__cuando {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: var(--space-2);
  color: var(--primary);
  font-size: 0.92rem;
  font-weight: 600;
}

.ahora__donde {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
  color: var(--taupe);
  font-size: 0.85rem;
}

.ahora__cuando .material-symbols-outlined { font-size: 1.05rem; }
.ahora__donde .material-symbols-outlined { font-size: 1rem; }

/* ── La lista de debajo ──
   Sin tarjetas: filas separadas por un filete. Lo importante ya está arriba;
   esto es para recorrer, y cincuenta bordes redondeados seguidos cansan. */
.fila-ev {
  display: flex;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-3) 2px;
  border-bottom: 1px solid var(--gray-200);
  text-decoration: none;
  color: inherit;
}

@media (hover: hover) {
  .fila-ev:hover { background-color: color-mix(in srgb, var(--oat) 55%, transparent); }
}

.fila-ev--cancelada { opacity: 0.62; }

.fila-ev__cuando {
  flex-shrink: 0;
  width: 4.25rem;
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}

.fila-ev__cuando small {
  display: block;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 0.72rem;
  color: var(--taupe);
}

.fila-ev__datos { flex: 1; min-width: 0; }

.fila-ev__titulo { font-weight: 600; font-size: 0.92rem; line-height: 1.25; color: var(--charcoal); }

.fila-ev__pie {
  margin-top: 2px;
  font-size: 0.78rem;
  color: var(--taupe);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* El sello va DENTRO del título y con su palabra: el color solo no lo lee
   quien no distingue la terracota del oliva. */
.fila-ev__sello {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: 6px;
  font-size: 0.64rem;
  font-weight: 700;
  color: var(--accent);
}

.fila-ev__sello .material-symbols-outlined { font-size: 0.8rem; }

.agenda__dia {
  margin: var(--space-5) 0 2px;
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--taupe-soft);
}

/* ── El espacio promocional (§6) ──
   Reservado desde el principio y en su sitio: por encima del listado y por
   debajo de lo inminente. Se identifica SIEMPRE como promocionado, y la marca
   va donde se lee antes de pulsar, no después. */
.promo-agenda {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding: var(--space-3);
  border: 1px solid var(--oat-deep);
  border-radius: var(--radius-card);
  background-color: var(--oat);
  text-decoration: none;
  color: inherit;
}

.promo-agenda__cartel {
  flex-shrink: 0;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 8px;
  overflow: hidden;
  background-image: linear-gradient(135deg, #C47C5A 0%, #8F5A40 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--parchment);
}

.promo-agenda__cartel img { width: 100%; height: 100%; object-fit: cover; }

.promo-agenda__titulo { font-family: var(--font-headings); font-weight: 700; font-size: 0.98rem; color: var(--charcoal); }
.promo-agenda__cuando { font-size: 0.78rem; color: var(--taupe); }

.promo-agenda__marca {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--taupe-soft);
}

/* ─────────────────────────────────────────────────────────────────────────
   AHORA EN EPÍLOGO

   Las tarjetas de la Home. Cada una dice de qué área viene, qué pasa y adónde
   lleva; entera pulsable, con un solo destino. Llenarlas de botones pequeños
   obligaría a apuntar, y esto se mira de pie y con una mano.

   No llevan contadores de nada. La Home no es una competición: si una tarjeta
   dijera «14 comentarios», el orden dejaría de importar y empezaría a
   importar el número.
   ───────────────────────────────────────────────────────────────────────── */
.ahora-card {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  background-color: #fff;
  border: 1px solid var(--oat-deep);
  border-radius: var(--radius-card);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--duration-base) var(--ease-out-quad);
}

@media (hover: hover) { .ahora-card:hover { border-color: var(--primary-30); } }

/* El mismo filete de terracota que en Lecturas y en la Agenda: «esto viene de
   quien lo escribió» es el mismo hecho en toda la app y merece la misma señal. */
.ahora-card--autor { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }

.ahora-card__portada {
  flex-shrink: 0;
  width: 3rem;
  aspect-ratio: 2 / 3;
  border-radius: 5px;
  overflow: hidden;
  background-color: var(--oat-deep);
  box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
}

.ahora-card__portada img { width: 100%; height: 100%; object-fit: cover; }

/* Sin portada, el icono del área. Un hueco del tamaño de una portada, vacío,
   se lee como que falta un dato: la agenda tiene muchos eventos sin libro
   asociado y es lo normal, no un error. */
.ahora-card__portada--vacia {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--taupe-soft);
}

.ahora-card__datos { flex: 1; min-width: 0; }

.ahora-card__area {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--taupe);
}

.ahora-card__area .material-symbols-outlined { font-size: 0.9rem; }

.ahora-card__titulo {
  display: block;
  margin-top: 2px;
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.2;
  color: var(--charcoal);
}

.ahora-card__linea {
  display: block;
  margin-top: 2px;
  font-size: 0.8rem;
  color: var(--taupe);
}

/* ── La etiqueta de una Muestra ──
   Discreta pero legible: la tarjeta es la misma que la de un contenido real
   —enseña cómo se verá la pantalla llena de verdad— y esta palabra es lo único
   que la distingue. Por eso no puede ser un color ni un icono a secas: tiene
   que poder LEERSE que es una muestra.

   En terracota y no en oliva porque el oliva es el color de la acción, y esto
   no es algo que hacer: es un aviso sobre lo que se está mirando. */
.sello-muestra {
  display: inline-flex;
  align-items: center;
  margin-left: var(--space-2);
  padding: 1px 6px;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: 999px;
  background-color: var(--accent-light);
  color: var(--accent);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: none;
}

/* Una muestra sin destino no es un enlace: se queda quieta. Un enlace que no
   lleva a ninguna parte es peor que un texto — se pulsa y no pasa nada. */
.ahora-card--quieta { cursor: default; }
@media (hover: hover) { .ahora-card--quieta:hover { border-color: var(--oat-deep); } }

/* ── Los apartados del buscador ──
   El buscador devuelve cuatro cosas distintas —libros, autores, lecturas y
   eventos— en una sola columna. Las filas son iguales a propósito, para que se
   lean como una lista; lo que las separa es este titulillo. Sin él, un evento
   y un libro parecen lo mismo y hay que leerlos enteros para saber qué son.

   Discreto y no en verde: aquí lo que se busca son los resultados, no los
   nombres de los apartados. */
.busca-grupo { margin-top: var(--space-5); }
.busca-grupo:first-child { margin-top: 0; }

.busca-grupo__titulo {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  font-weight: var(--font-semibold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--taupe);
  padding-bottom: var(--space-1);
  margin-bottom: var(--space-1);
  border-bottom: 1px solid var(--oat-deep);
}

/* ── El buzón ──
   Un mensaje sin leer se distingue por TRES cosas a la vez: el icono cerrado,
   el título en negrita y el punto. Con una sola —el punto— quien no lo vea
   bien no distingue lo nuevo de lo viejo; y el `sr-only` «(sin leer)» lo dice
   para quien no ve ninguna. */
.mensaje--nuevo { border-color: color-mix(in srgb, var(--primary) 40%, transparent); }

.punto-nuevo {
  flex-shrink: 0;
  align-self: center;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background-color: var(--primary);
}

/* ─────────────────────────────────────────────────────────────────────────
   LAS TRES MODALIDADES DE LECTURAS

   Los mismos tonos del verde de Epílogo que las áreas de Mi Biblioteca, y por
   la misma razón: son tres puertas de una sola casa, no tres aplicaciones. Lo
   que distingue una modalidad de otra es su icono y su nombre; el tono solo
   evita que tres cajas seguidas se lean como una sola.

   La escalera sigue el orden del producto —leer con otros, leer con quien lo
   escribió, leer antes que nadie—, así que se puede señalar «la tercera» sin
   mirar el texto.

   El texto va SIEMPRE en `--charcoal`: sobre estos fondos casi blancos el
   contraste sobra, y así el color no decide nunca la legibilidad. */
:root {
  --modo-conjuntas: #e2e6e0;     --modo-conjuntas-hondo: #d2dbcd;
  --modo-epilogo: #dae2d4;       --modo-epilogo-hondo: #c8d5c0;
  --modo-anticipadas: #d0dec7;   --modo-anticipadas-hondo: #bdd0b2;
}

/* ============================================================
   LAS TRES PUERTAS DE LECTURAS · compactas
   ============================================================
   Antes eran tres tarjetas grandes con su párrafo y su botón, y ocupaban la
   pantalla entera: quien abría Lecturas se encontraba un menú donde elegir
   por dónde entrar, no una portada.

   Ahora son tres puertas en una fila y el sitio es para lo que de verdad
   importa — lo que se está leyendo. Cada una conserva su color: sin él, tres
   cajas grises seguidas dejan de leerse como tres cosas distintas.

   La explicación de qué se hace dentro se ha ido a cada pantalla, que es
   donde hace falta: aquí sobraba el día dos. */
.puerta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-2);
  border-radius: var(--radius-card);
  background-color: var(--modo-fondo, var(--oat));
  color: var(--charcoal);
  text-align: center;
  text-decoration: none;
  transition: transform var(--duration-base) var(--ease-out-quad),
              filter var(--duration-base) var(--ease-out-quad);
  /* Zona pulsable: la regla de la casa son 44 px, y esto se toca con el
     pulgar en una fila de tres. */
  min-height: 44px;
}

@media (hover: hover) { .puerta:hover { filter: brightness(0.985); } }
.puerta:active { transform: scale(0.98); }

.puerta__icono {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-full);
  background-color: var(--modo-circulo, var(--oat-deep));
  flex-shrink: 0;
}

.puerta__nombre {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.78rem;
  line-height: 1.25;
  color: var(--charcoal);
}

/* ============================================================
   UNA FILA DE LECTURAS · el contenido de la portada
   ============================================================
   Se desplaza en horizontal a propósito: en vertical, cuatro secciones con
   seis tarjetas cada una convierten la portada en un scroll infinito donde
   las últimas no las ve nadie. Así cada fila se recorre con el pulgar y la
   siguiente se ve asomar debajo. */
.fila-lecturas {
  display: flex;
  gap: var(--space-3);
  overflow-x: auto;
  padding-bottom: var(--space-1);
  scroll-snap-type: x proximity;
  /* Sin barra visible en escritorio: la fila ya se entiende por el corte de
     la última tarjeta. */
  scrollbar-width: thin;
}

.lectura-tarjeta {
  flex-shrink: 0;
  width: 116px;
  scroll-snap-align: start;
  text-decoration: none;
  color: inherit;
}

.lectura-tarjeta__titulo {
  display: block;
  margin-top: var(--space-2);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8rem;
  line-height: 1.3;
  color: var(--charcoal);
}

.lectura-tarjeta__pie {
  display: block;
  margin-top: 2px;
  font-size: 0.72rem;
  line-height: 1.3;
  color: var(--taupe);
}

/* La tarjeta de una modalidad. Hereda de `.area` —la de Mi Biblioteca— pero
   en vertical: aquí cada puerta lleva una frase que explica qué se hace
   dentro y su propio botón, y en horizontal no cabrían sin apretarlo todo.

   ⚠️ Se conserva porque `.modo__pronto` la usa la pantalla de Lecturas
   anticipadas para su etiqueta de «Próximamente». */
.modo {
  display: block;
  width: 100%;
  padding: var(--space-4);
  border: none;
  border-radius: var(--radius-card);
  background-color: var(--modo-fondo, var(--oat));
  color: var(--charcoal);
  text-align: left;
  text-decoration: none;
  transition: transform var(--duration-base) var(--ease-out-quad),
              filter var(--duration-base) var(--ease-out-quad);
}

@media (hover: hover) { .modo:hover { filter: brightness(0.985); } }
.modo:active { transform: scale(0.995); }

.modo__cabeza { display: flex; align-items: center; gap: var(--space-3); }

.modo__icono {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-full);
  background-color: var(--modo-circulo, var(--oat-deep));
  color: var(--charcoal);
  flex-shrink: 0;
}

.modo__titulo {
  flex: 1;
  min-width: 0;
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 1.1rem;
  line-height: 1.2;
  color: var(--charcoal);
}

/* «Próximamente». No es un adorno: avisa de que dentro todavía no se puede
   leer nada, y va ARRIBA, antes de entrar, no escondido al final. */
.modo__pronto {
  flex-shrink: 0;
  padding: 2px var(--space-2);
  border-radius: 999px;
  background-color: color-mix(in srgb, var(--charcoal) 8%, transparent);
  color: var(--charcoal);
  font-family: var(--font-sans);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.modo__texto {
  display: block;
  margin-top: var(--space-3);
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--charcoal);
}

/* La acción, dicha con palabras. Es lo que convierte tres tarjetas bonitas en
   tres puertas: se lee qué pasa al pulsarlas antes de pulsarlas. */
.modo__accion {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: var(--space-3);
  font-family: var(--font-sans);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--charcoal);
}

.modo__accion .material-symbols-outlined { font-size: 1.05rem; }

/* ============================================================
   RETOMAR · lo que dejaste a medias, arriba de Inicio
   ============================================================
   Hermano de .ahora-card y no una copia: comparte medidas y portada para que
   Inicio se lea como una sola pantalla, pero lleva el acento oliva a la
   izquierda porque esto NO es lo que pasa en Epílogo, es lo que estabas
   haciendo tú. Esa diferencia tiene que verse sin leer. */

.retomar__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  background-color: #fff;
  border: 1px solid var(--oat-deep);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-card);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--duration-base) var(--ease-out-quad);
}

@media (hover: hover) { .retomar__item:hover { border-color: var(--primary-30); border-left-color: var(--primary); } }

.retomar__portada {
  flex-shrink: 0;
  width: 2.5rem;
  aspect-ratio: 2 / 3;
  border-radius: 5px;
  overflow: hidden;
  background-color: var(--oat-deep);
  box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
}

.retomar__portada img { width: 100%; height: 100%; object-fit: cover; }
.retomar__portada--vacia { box-shadow: none; }

.retomar__datos { flex: 1; min-width: 0; }

.retomar__titulo {
  display: block;
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--charcoal);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La acción, debajo y en oliva: es lo que va a pasar al pulsar, no un dato. */
.retomar__accion {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-top: 1px;
  font-size: 0.8rem;
  color: var(--primary);
}

.retomar__accion .material-symbols-outlined { font-size: 1rem; }

/* ══════════════════════════════════════════════════════════════════════════
   CENTRO DE AYUDA — el acordeón

   En components.css y no en Tailwind a propósito: aquí no hay purga, y el
   contenido de la ayuda lo pinta el JS desde la base de datos. Una clase que
   solo apareciera dentro de una plantilla de JS podría no llegar al bundle.

   La pregunta es un `button` de línea completa y no un `div` con `onclick`:
   así el teclado y el lector de pantalla la encuentran solos, y el
   `aria-expanded` dice si está abierta sin depender de ver la flecha.
   ══════════════════════════════════════════════════════════════════════════ */

.faq-apartado { margin-bottom: 1.5rem; }

.faq-apartado__titulo {
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--primary);
  margin-bottom: 0.5rem;
}

.faq-lista {
  border: 1px solid var(--oat-deep);
  border-radius: 12px;
  overflow: hidden;
  background-color: var(--bg-secondary);
}

.faq-item + .faq-item { border-top: 1px solid var(--oat-deep); }

.faq-pregunta {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  /* 44 px de alto mínimo con el texto en una sola línea. */
  min-height: 44px;
  padding: 0.75rem 1rem;
  text-align: left;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--charcoal);
  background: none;
  border: 0;
  cursor: pointer;
}

@media (hover: hover) { .faq-pregunta:hover { background-color: var(--oat); } }

.faq-pregunta__texto { flex: 1; min-width: 0; }

.faq-pregunta__flecha {
  flex-shrink: 0;
  color: var(--taupe);
  font-size: 1.25rem;
  transition: transform 0.18s ease;
}

.faq-pregunta[aria-expanded="true"] .faq-pregunta__flecha { transform: rotate(180deg); }

.faq-respuesta {
  padding: 0 1rem 1rem;
  font-family: var(--font-reading);
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--taupe);
  white-space: pre-line;   /* las respuestas se guardan en texto plano */
}

.faq-respuesta[hidden] { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   EL PERFIL DE OTRO LECTOR

   Su historia de lectura, no un escaparate. Todo lo de aquí es composición:
   ningún color nuevo y ninguna medida que no salga de los tokens.
   ══════════════════════════════════════════════════════════════════════════ */

/* La cabecera de una sección: un disco pálido con su icono y el título en
   titulares. Es lo que separa «Libros leídos» de «Fichas» sin una línea. */
.perfil-seccion {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.perfil-seccion__icono {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  background: var(--oat);
  color: var(--primary);
  flex-shrink: 0;
}

.perfil-seccion__titulo {
  font-family: var(--font-headings);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--charcoal);
}

/* El mes, con su filete hasta el borde.

   La raya sale del propio título y no es un <hr>: así se acaba donde acaba el
   texto, mida lo que mida el nombre del mes, y no hay que ajustar nada al
   traducir «AGOSTO» por «SEPTIEMBRE». */
.perfil-mes {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0 0.25rem;
}

.perfil-mes__nombre {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--taupe);
  flex-shrink: 0;
}

.perfil-mes::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--oat-deep);
}

.perfil-ano {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--primary);
  margin-top: 1.5rem;
}

.perfil-ano:first-child { margin-top: 0; }

/* ── El carrusel de fichas ──────────────────────────────────────────────────

   Se desplaza solo él, nunca la página: una tira horizontal que arrastra el
   cuerpo entero es la forma más rápida de que alguien no pueda hacer scroll
   vertical con el pulgar donde le apetezca. */
.fichas-tira {
  display: flex;
  gap: 0.75rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 0.5rem;
  /* Que la primera y la última no queden pegadas al borde de la pantalla. */
  margin: 0 -1rem;
  padding-left: 1rem;
  padding-right: 1rem;
}

.fichas-tira__ficha {
  scroll-snap-align: start;
  flex: 0 0 min(17rem, 78vw);
}

/* El papel de la ficha. La misma textura que la imagen que se comparte, para
   que una ficha se reconozca aquí y allí. Si la imagen no carga queda el color
   de debajo y la ficha se lee igual. */
.ficha-papel {
  background-color: var(--parchment);
  background-image: url('/imgs/ficha/papel.jpg');
  background-size: cover;
  background-position: center;
  border: 1px solid var(--oat-deep);
}

/* ══════════════════════════════════════════════════════════════════════════
   LA FILA DE UN LIBRO

   La misma en Mi Biblioteca → Libros leídos, Lecturas pendientes, la huella
   que se comparte y el perfil de otra persona. Está aquí y no en clases
   sueltas dentro del JavaScript porque son CUATRO pantallas: repartido por
   utilidades, cambiar el tamaño del autor obligaba a acordarse de todas.

   El aire es corto a propósito. Son tres líneas —título, autor, fecha— que se
   leen como un bloque; separadas parecían tres datos independientes, y una
   lista de veinte libros no cabía en pantalla.
   ══════════════════════════════════════════════════════════════════════════ */

.fila-libro {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--oat-deep);
}

.fila-libro:last-child { border-bottom: 0; }

/* El título en la tipografía de titulares, y a dos líneas si hace falta.

   ⚠️ SIN recortar con puntos suspensivos. Antes iba en una línea con `truncate`
   y «Memorias de Idhün: La Resistencia» acababa en «Memorias de Idhün: La…»,
   que es justo la parte que distingue un tomo de otro. */
.fila-libro__titulo {
  display: block;
  font-family: var(--font-headings);
  font-size: 0.88rem;
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: var(--charcoal);
}

/* El autor, en versalitas. Es la voz secundaria de la fila: se reconoce de un
   vistazo sin competir con el título. */
.fila-libro__autor {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.6rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fila-libro__fecha {
  display: block;
  margin-top: 0.05rem;
  font-size: 0.66rem;
  line-height: 1.3;
  color: var(--taupe);
}
