/* Pantallas nuevas: acceso, onboarding, tienda de temas, ajustes,
   asistente del plan. Todos los colores salen de tokens.css. */

/* ── PANTALLAS A PANTALLA COMPLETA ───────────────────────────── */
.fullscreen {
  position: fixed; inset: 0; z-index: 500;
  display: none; align-items: center; justify-content: center;
  padding: 24px; overflow-y: auto;
  background: var(--void);
}
.fullscreen.visible { display: flex; }

/* ── ACCESO ──────────────────────────────────────────────────── */
.auth-card { width: 100%; max-width: 380px; margin: auto; }

/* ── LA PORTADA  ·  una tapa, no un encabezado ────────────────
   «Vamos a rediseñar la portada para que no se vea tan simplona.
    Debería coincidir con el tema, tener a la mascota que seleccione
    afuera, y Mi Biblioteca en letras más lindas o mágicas, más de
    cuento de hadas. La portada, algo más como un libro.»

   Lo que había era texto centrado sobre el fondo de la app: un título,
   un filete y una frase. Todo correcto y nada que mirar — «simplona»
   es la palabra exacta, porque no había ningún OBJETO, solo tipografía
   flotando.

   Ahora es una TAPA, y está hecha con lo que el sistema de temas ya
   tenía y no se estaba usando aquí:

     · la tela   `--tela-5`, una de las ocho telas de encuadernar que
                 cada tema define; cambia sola con el tema y no hay que
                 elegir un color para once temas.
     · la tinta  `--tela-5-tinta`, que el tema calcula por CONTRASTE
                 contra esa tela (oro en las oscuras, tinta en las
                 claras). Por eso el título se lee en los once sin
                 comprobar ninguno a mano.
     · el grano  `--texture`, el mismo papel del resto de la app.
     · el adorno el florón del tema, el mismo que remata las listas.

   EL LOMO ES LO QUE LA CONVIERTE EN LIBRO. Sin la banda de la
   izquierda con sus dos filetes esto sería una tarjeta de color; con
   ella se lee como una tapa vista de frente. Es el detalle más barato
   y el que más trabaja.

   Y LA MASCOTA VA FUERA, sentada sobre el canto inferior y pisando la
   tapa. Dentro del marco sería un dibujo más de la portada; delante y
   asomada, es alguien que te está esperando con el libro detrás. */
/* ── QUE NO PAREZCA UNA APP DE NIÑOS ─────────────────────────
   «Queda un poco infantil. ¿Podrías dibujarla más mágica, más estándar
    para todos, sin perder lo acogedor y lo lindo de la app y el mundo
    de la lectura?»

   Lo que la hacía infantil eran dos cosas concretas, no el conjunto:
   un ANIMAL DE DIBUJOS GRANDE presidiendo el centro, y una TELA PLANA
   —un rectángulo de color liso se lee como cartulina.

   Y la magia que pide no es purpurina: es la de un libro bueno de
   verdad. Un libro caro no brilla, PESA. Lo que hace que una tapa
   parezca valiosa es materia y luz:

     la trama    el hilo cruzado de la tela, no un color liso
     el oro      el título ESTAMPADO, que coge la luz de arriba abajo
     los nervios los resaltes del lomo de un libro cosido
     el canto    el filo dorado de las hojas, a la derecha
     la lámpara  luz cálida cayendo desde arriba y sombra abajo

   Ninguna de las cinco es un dibujo nuevo: son gradientes sobre lo que
   el tema ya define. Cambian el material, no el estilo, así que lo
   acogedor se queda y lo de guardería se va. */
.portada {
  position: relative;
  border-radius: var(--card-radius);
  /* La tinta va TAMBIÉN en su propia variable, y no solo en `color`:
     el degradado del título se pinta sobre una letra transparente, y
     ahí `currentColor` ya vale `transparent`. Se veía al mirarlo — el
     título salió fantasma en los once temas. */
  --tinta: var(--tela-5-tinta, var(--text));
  --tinta-alto: var(--tela-5-alto, var(--tinta));
  --tinta-bajo: var(--tela-5-bajo, var(--tinta));
  color: var(--tinta);
  background:
    /* la lámpara: luz arriba, penumbra abajo */
    radial-gradient(ellipse 120% 70% at 50% -12%, rgb(255 255 255 / .13), transparent 62%),
    radial-gradient(ellipse 130% 60% at 50% 112%, rgb(0 0 0 / .22), transparent 60%),
    /* la trama de la tela: dos hilos cruzados, muy tenues */
    repeating-linear-gradient(90deg, rgb(255 255 255 / .022) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(0deg, rgb(0 0 0 / .028) 0 1px, transparent 1px 5px),
    var(--tela-5, var(--deep));
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .10),
    inset 0 -1px 0 rgb(0 0 0 / .18),
    0 18px 40px rgb(0 0 0 / .45);
  margin-bottom: 52px;
  isolation: isolate;
}
/* El grano del papel, encima de la tela. */
.portada::before {
  content: ''; position: absolute; inset: 0;
  border-radius: inherit;
  background-image: var(--texture);
  opacity: var(--texture-opacity, .05);
  mix-blend-mode: var(--texture-blend, soft-light);
  pointer-events: none;
}
/* EL LOMO CON SUS NERVIOS, y el canto dorado de las hojas a la
   derecha. Los nervios son los resaltes que deja el cosido de un libro
   encuadernado a mano: cuatro rayas horizontales bastan para que la
   banda deje de ser una franja de color y se lea como un lomo. */
.portada::after {
  content: ''; position: absolute; inset: 0;
  border-radius: inherit;
  color: var(--tela-5-tinta, var(--gold));
  background:
    /* el canto de las hojas, a la derecha */
    linear-gradient(270deg, rgb(255 255 255 / .12) 0 2px, transparent 2px 5px),
    linear-gradient(270deg, currentColor 0 1px, transparent 1px 100%),
    /* la sombra del lomo y sus dos filetes */
    linear-gradient(90deg, rgb(0 0 0 / .32) 0 14px, rgb(0 0 0 / .10) 14px 26px, transparent 26px),
    linear-gradient(90deg, transparent 21px, currentColor 21px 21.7px, transparent 21.7px),
    linear-gradient(90deg, transparent 23.4px, currentColor 23.4px 24.1px, transparent 24.1px),
    /* los nervios: solo dentro de los 26 px del lomo */
    repeating-linear-gradient(0deg,
      transparent 0 44px,
      rgb(255 255 255 / .10) 44px 46px,
      rgb(0 0 0 / .16) 46px 49px,
      transparent 49px 52px);
  background-repeat: no-repeat;
  background-size: 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 26px 100%;
  opacity: .62;
  pointer-events: none;
}

/* El marco de la tapa: doble filete, como un grabado. */
/* El doble filete se saca de la MISMA tinta del tema rebajada, y no de
   un color nuevo: así el marco acompaña al título en los once temas
   sin declarar nada por tema. */
.portada-marco {
  position: relative; z-index: 1;
  margin: 12px 12px 12px 34px;
  /* El hueco de abajo no es aire: es el sitio donde se sienta la
     mascota. Con 28 px se comía la última línea de la frase — se veía
     al mirarlo, no al leerlo. */
  padding: 26px 20px 34px;
  text-align: center;
  color: var(--tela-5-tinta, var(--text));
  border: 1px solid color-mix(in srgb, currentColor 38%, transparent);
  border-radius: calc(var(--card-radius) - 2px);
  box-shadow: inset 0 0 0 3.5px color-mix(in srgb, currentColor 15%, transparent);
}

.portada-vineta { display: flex; justify-content: center; margin-bottom: 10px; opacity: .7; }
.portada-vineta svg {
  width: 74px; height: 40px;
  fill: none; stroke: currentColor; stroke-width: 1.15;
  stroke-linecap: round; stroke-linejoin: round; overflow: visible;
}
.portada-vineta use { display: none; }

.auth-exlibris {
  font-size: 9px; letter-spacing: 4px; text-transform: uppercase;
  opacity: .72; margin-bottom: 8px;
}
/* La letra del título es SUYA, no la del cuerpo de la app: es lo único
   de toda la interfaz que puede permitirse ser bonito antes que
   práctico, porque se lee una vez y no se usa para nada. Por defecto
   es la del tema; `--font-portada` deja que un tema pida otra. */
/* EL TÍTULO NO ESTÁ ESCRITO, ESTÁ ESTAMPADO. Es lo que más separa una
   tapa de verdad de un rótulo: las letras de un libro bueno son metal
   prensado en la tela, y el metal COGE LA LUZ — más claro arriba, más
   oscuro abajo, con el filo hundido donde muerde el papel.

   Se hace con el propio color del tema, no con un oro fijo: el degradado
   sale de `currentColor` mezclado con blanco y con negro, así que
   funciona igual sobre la tela clara de Manta que sobre la oscura de
   Grimorio. Sin `background-clip: text` —navegadores viejos— se queda
   el color plano de antes, que ya se leía bien. */
.auth-brand {
  font-family: var(--font-portada, var(--font-display));
  /* 56 y no 34: una caligráfica tiene la altura de x mucho menor que
     una serif, así que al mismo cuerpo se lee la mitad. Y el nombre
     pasó de trece letras a siete: a 46 px la tapa se quedaba vacía
     alrededor del título. Comprobado a 46, 56 y 64 sobre la tapa —
     a 56 el título sostiene la portada y sigue entrando en una línea
     en un móvil de 390. */
  font-size: 56px;
  font-weight: var(--portada-weight, var(--display-weight));
  line-height: 1.08;
  letter-spacing: var(--portada-spacing, var(--display-spacing));
  /* El hundido del troquel, debajo del metal. */
  text-shadow: 0 1px 0 rgb(0 0 0 / .28), 0 -1px 0 rgb(255 255 255 / .10);
}
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .auth-brand {
    /* Los dos bordes los calcula el TEMA, no esta hoja: sobre tela
       oscura el oro está en relieve y la luz le da arriba; sobre tela
       clara la letra está hundida y arriba lleva su sombra. Aclarar
       siempre arriba dejaba el título en 1,0:1 en Pergamino. */
    background-image: linear-gradient(
      180deg,
      var(--tinta-alto) 0%,
      var(--tinta) 48%,
      var(--tinta-bajo) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    /* Con las letras transparentes, la sombra de arriba se vería A
       TRAVÉS de ellas y ensuciaría el metal. */
    text-shadow: none;
    filter: drop-shadow(0 1px 0 rgb(0 0 0 / .30));
  }
}
.auth-filete {
  width: 64px; height: 1px; margin: 14px auto;
  background: currentColor; opacity: .45;
}
.auth-lede {
  font-family: var(--font-body);
  font-size: 13px; font-style: italic; line-height: 1.55;
  opacity: .78; max-width: 28ch; margin: 0 auto;
}

/* La mascota, sentada en el canto de abajo y pisando la tapa. */
/* ── LA MASCOTA SE ASOMA, NO PRESIDE ─────────────────────────
   Un animal de dibujos de 104 px en el CENTRO de la portada es lo que
   más hacía que la app pareciera de niños: en el eje del título, del
   mismo tamaño que él, compitiendo por ser lo primero que miras.

   Sigue estando —es el alma de la app y se pidió que estuviera— pero
   en la esquina y más pequeña: 76 px, apoyada en el canto de abajo a
   la derecha. Ahí hace lo que tiene que hacer, que es que la sonrisa
   te pille DESPUÉS de haber visto un libro; no antes.

   Y en la esquina no puede pisar el texto, que va centrado: por eso el
   hueco de abajo del marco baja de 62 px a 34. */
.portada-companera {
  position: absolute; z-index: 2;
  right: 14px; bottom: -30px;
  width: 76px; height: 76px;
  display: flex; align-items: flex-end; justify-content: center;
  pointer-events: none;
  filter: drop-shadow(0 8px 14px rgb(0 0 0 / .45));
}
.portada-companera .pet-img,
.portada-companera svg { width: 100%; height: 100%; }
/* El rincón de la mascota no viene a esta pantalla: aquí el escenario
   es la tapa, y dos escenarios superpuestos es uno de más. */
.portada-companera .pet-rincon { display: none; }

.auth-card > .auth-tabs { margin-top: 4px; }
.auth-tabs { display: flex; gap: 6px; margin-bottom: 20px; }
.auth-tab {
  flex: 1; padding: 10px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--card); color: var(--muted); font-family: var(--font-body);
  font-size: 13px; cursor: pointer; transition: all .2s;
}
.auth-tab.active { background: transparent; border-color: rgb(var(--gold-rgb) / .55); color: var(--gold); }
.auth-error { color: var(--danger); font-size: 12px; min-height: 18px; margin: 4px 0 8px; }
.auth-divider {
  display: flex; align-items: center; gap: 10px; margin: 20px 0 14px;
  color: var(--muted-soft); font-size: 11px;
}
.auth-divider::before, .auth-divider::after {
  content: ''; flex: 1; height: 1px; background: var(--border);
}
.btn-provider {
  width: 100%; padding: 12px; margin-bottom: 8px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--card); color: var(--text);
  font-family: var(--font-body); font-size: 14px; cursor: pointer; transition: all .2s;
}
.btn-provider:hover { border-color: var(--border-strong); background: var(--fog); }
.auth-fineprint { margin-top: 20px; text-align: center; color: var(--muted-soft); font-size: 11px; line-height: 1.6; }
.link-btn {
  display: block; width: 100%; margin-top: 10px; padding: 6px;
  background: none; border: 0; color: var(--lilac);
  font-family: var(--font-body); font-size: 12px; cursor: pointer; text-decoration: underline;
}

/* ── ONBOARDING ──────────────────────────────────────────────── */
.onb-card { width: 100%; max-width: 400px; margin: auto; }
.onb-step {
  font-size: 10px; letter-spacing: 2px; text-transform: uppercase;
  color: var(--muted); margin-bottom: 8px;
}
.onb-title { font-family: var(--font-display); font-size: 26px; color: var(--gold); margin-bottom: 8px; font-weight: 600; }
.onb-lede { color: var(--muted); font-size: 14px; line-height: 1.6; margin-bottom: 22px; }
.onb-legacy {
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--fog); padding: 16px; margin-bottom: 22px;
}
.onb-legacy-title { font-family: var(--font-display); color: var(--gold); font-size: 15px; margin-bottom: 6px; }
.onb-legacy p { color: var(--muted); font-size: 13px; line-height: 1.6; margin-bottom: 14px; }
.onb-actions { display: flex; flex-direction: column; gap: 8px; }

/* ── BOTONES COMPARTIDOS ─────────────────────────────────────── */
/* Un botón secundario es papel con un filete, no una cápsula de
   cristal: sin desenfoque, sin relleno translúcido, sin brillo. */
.btn-ghost {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 16px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: transparent; color: var(--text);
  font-family: var(--font-body); font-size: 13px; cursor: pointer;
  transition: border-color .2s, color .2s;
}
.btn-ghost:hover, .btn-ghost:active { border-color: rgb(var(--gold-rgb) / .5); color: var(--gold); }
.btn-ghost .ico { width: 16px; height: 16px; }
.btn-magic.full, .btn-delete.full { width: 100%; display: block; margin-bottom: 8px; }
/* `full` era `display:block`, y eso tiraba abajo el flex que centra el
   icono junto al texto: el icono se quedaba pegado al margen izquierdo
   y la etiqueta en medio de la nada. */
.btn-ghost.full { width: 100%; display: flex; margin-bottom: 8px; }
.btn-danger {
  padding: 11px 16px; border: 1px solid rgb(var(--danger-rgb) / .4); border-radius: var(--radius-sm);
  background: var(--danger-wash); color: var(--danger);
  font-family: var(--font-body); font-size: 13px; cursor: pointer;
}
.btn-mini {
  padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: transparent; color: var(--muted);
  font-family: var(--font-body); font-size: 11px; cursor: pointer; white-space: nowrap;
}
.btn-mini:hover { color: var(--text); border-color: var(--border-strong); }

/* ── TOAST ───────────────────────────────────────────────────── */
.toast {
  position: fixed; left: 50%; bottom: 90px; transform: translate(-50%, 20px);
  z-index: 900; max-width: 90vw;
  padding: 11px 18px; border-radius: var(--radius);
  background: var(--card-solid); border: 1px solid var(--border-strong);
  color: var(--text); font-size: 13px; text-align: center;
  opacity: 0; pointer-events: none; transition: opacity .25s, transform .25s;
  backdrop-filter: blur(20px);
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast[data-kind="error"] { border-color: rgb(var(--danger-rgb) / .5); color: var(--danger); }

/* ── CONFIRMACIÓN ────────────────────────────────────────────── */
.confirm-overlay { z-index: 950; }
.confirm-sheet { max-width: 380px; margin: auto; padding: 24px; border-radius: var(--radius-lg); }
.confirm-body { color: var(--muted); font-size: 13px; line-height: 1.7; margin: 10px 0 20px; }
.confirm-body strong { color: var(--text); }
.confirm-actions { display: flex; gap: 8px; justify-content: flex-end; }

/* ── TIENDA DE TEMAS ─────────────────────────────────────────── */
.store-shelf-label {
  font-family: var(--font-display); font-size: 12px; letter-spacing: 2px;
  text-transform: uppercase; color: var(--lilac); margin: 18px 0 12px;
}
.theme-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.theme-tile {
  display: flex; flex-direction: column; gap: 6px; text-align: left;
  padding: 12px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--card); cursor: pointer; transition: all .2s;
  font-family: var(--font-body); color: var(--text);
}
.theme-tile:hover:not(.locked) { border-color: var(--border-strong); transform: translateY(-2px); }
.theme-tile.active { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold); }
.theme-tile.locked { opacity: .55; cursor: not-allowed; }
/* Miniatura: una tarjeta de libro en pequeño, pintada con los tokens
   del propio tema. Así la ficha muestra su forma y su material, no un
   cuadro de color que todos comparten. */
.mini {
  position: relative;
  display: block;
  height: 58px;
  padding: 9px;
  overflow: hidden;
  background: var(--m-bg);
  border-radius: calc(var(--m-radius) * .6);
  border: 1px solid rgb(255 255 255 / .06);
}
.mini::after {
  content: '';
  position: absolute;
  left: 9px; right: 9px; top: 24px; bottom: 9px;
  background: var(--m-surface);
  border: var(--m-border);
  border-radius: var(--m-radius);
  opacity: .95;
}
.mini-rune {
  position: absolute;
  left: 9px; top: 9px;
  width: 11px; height: 11px;
  background: var(--m-accent);
  border-radius: var(--m-rune);
}
.mini-lines { position: absolute; left: 25px; top: 10px; right: 9px; }
.mini-lines i {
  display: block;
  height: 3px;
  border-radius: 1px;
  background: var(--m-gold);
  opacity: .8;
}
.mini-lines i + i {
  margin-top: 3px;
  width: 55%;
  background: var(--m-ink);
  opacity: .35;
}
.store-lede {
  color: var(--muted); font-size: 12.5px; line-height: 1.6; margin-bottom: 4px;
}
.theme-name { font-size: 13px; font-weight: 500; }
.theme-blurb { font-size: 11px; color: var(--muted); line-height: 1.5; }
.theme-lock { font-size: 10px; color: var(--amber); }
.theme-current { font-size: 10px; color: var(--gold); letter-spacing: 1px; text-transform: uppercase; }
.store-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 16px; }
.store-soon {
  padding: 16px; border: 1px dashed var(--border); border-radius: var(--radius);
  color: var(--muted); font-size: 12px; line-height: 1.6;
}

/* ── AJUSTES ─────────────────────────────────────────────────── */
.set-account { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.set-avatar {
  width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center;
  background: var(--accent-wash); border: 1px solid var(--border-strong);
  font-family: var(--font-display); font-size: 18px; color: var(--gold);
}
.set-name { font-size: 15px; color: var(--text); }
.set-email { font-size: 12px; color: var(--muted); }
.set-warn { font-size: 11px; color: var(--amber); margin-top: 2px; }
.set-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 0; border-bottom: 1px solid var(--border-soft); cursor: pointer;
}
.set-row:last-of-type { border-bottom: 0; }
.set-row-title { font-size: 14px; color: var(--text); }
.set-row-sub { font-size: 12px; color: var(--muted); margin-top: 2px; line-height: 1.5; }
.set-chev { color: var(--muted-soft); font-size: 18px; }
.set-fineprint { color: var(--muted-soft); font-size: 11px; line-height: 1.6; margin-top: 10px; }

/* ── LOS BLOQUES DE AJUSTES ──────────────────────────────────
   Diecisiete filas seguidas, todas del mismo peso, separadas solo por
   un filete casi invisible: eso no es un menú, es un muro. Darle
   superficie a cada grupo es lo que permite que el ojo lo trocee sin
   leerlo — y entonces el encabezado deja de ser una etiqueta suelta y
   pasa a nombrar algo que se ve.

   Es opcional a propósito (`.set-card` envuelve, no reemplaza): las
   mismas filas se usan en el perfil, en explorar y en los comentarios,
   y ninguna de esas pantallas cambia por esto. */
.set-card {
  background: var(--card);
  border: var(--hairline);
  border-radius: var(--card-radius);
  overflow: hidden;
  margin-bottom: 2px;
}
.set-card .set-row {
  padding: 13px 14px;
  border-bottom: 0;
}
/* El filete va entre HIJOS DIRECTOS de la tarjeta, no entre filas. Es
   lo mismo mientras las filas sean hermanas, y sigue siendo correcto
   cuando una viene envuelta —el @usuario vive dentro de su propio
   `div` para poder repintarse solo—, que es justo donde un selector
   de hermanos deja un hueco sin línea. */
.set-card > * + * { border-top: 1px solid var(--border-soft); }
.set-card .set-row:active { background: var(--fog-soft); }
/* Los logros traen su propio ritmo —un hueco entre filas y el sangrado
   a cero— porque nacieron sueltos sobre la hoja. Dentro de la tarjeta
   el hueco parte la lista y el sangrado los pega al borde. */
.set-card .ach-list { gap: 0; }
.set-card .ach { padding-left: 14px; padding-right: 14px; }

/* UN DATO NO ES UN MENÚ. «Tu ritmo real» y «Avance del año» no llevan
   a ninguna parte: se leen. Pintados como fila parecían un menú roto
   —se tocan y no pasa nada—, así que van con la etiqueta a la
   izquierda y el número a la derecha, que es como se lee un dato. */
.set-fact {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 12px 14px;
}
.set-fact-label { font-size: 13px; color: var(--muted); flex-shrink: 0; }
.set-fact-value { font-size: 13px; color: var(--text); text-align: right; line-height: 1.45; }

/* ── ASISTENTE DEL PLAN ──────────────────────────────────────── */
.planner-lede { color: var(--muted); font-size: 13px; line-height: 1.6; margin-bottom: 8px; }
.planner-lede strong { color: var(--text); }
.planner-hint { font-size: 12px; color: var(--muted); line-height: 1.6; margin: -4px 0 12px; }
.planner-hint strong { color: var(--text); }
.planner-hint.ok { color: var(--success); }
.planner-hint.warn { color: var(--amber); }
.stalled-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.stalled-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--card);
}
.stalled-title { font-size: 13px; color: var(--text); }
.stalled-sub { font-size: 11px; color: var(--muted); margin-top: 2px; }
.stalled-more { font-size: 11px; color: var(--muted-soft); text-align: center; padding: 4px; }

.proposal { display: flex; flex-direction: column; gap: 12px; margin: 14px 0; }
.prop-month { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.prop-month-head {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 9px 12px; background: var(--fog);
}
.prop-month-name { font-family: var(--font-display); font-size: 13px; color: var(--lilac); }
.prop-month-cap { font-size: 10px; color: var(--muted-soft); }
.prop-book {
  display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: start;
  padding: 10px 12px; border-top: 1px solid var(--border-soft);
}
.prop-role { font-size: 14px; }
.prop-title { font-size: 13px; color: var(--text); line-height: 1.4; }
.prop-title em { color: var(--muted); font-style: normal; font-size: 11px; }
.prop-reason { font-size: 11px; color: var(--muted); margin-top: 3px; line-height: 1.5; }
.prop-pages { font-size: 11px; color: var(--muted-soft); white-space: nowrap; }
.prop-empty { padding: 12px; font-size: 12px; color: var(--muted-soft); }

/* ── PROGRESO POR PÁGINA ─────────────────────────────────────── */
.progress-row { display: flex; align-items: center; gap: 8px; margin: 10px 0 4px; }
.page-input {
  width: 68px; padding: 6px 8px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--fog-soft); color: var(--text); font-family: var(--font-body); font-size: 12px;
}
.progress-of { font-size: 11px; color: var(--muted-soft); white-space: nowrap; }
.progress-pct { font-size: 11px; color: var(--lilac); white-space: nowrap; min-width: 32px; text-align: right; }
.mini-bar {
  height: 3px; border-radius: 2px; background: var(--fog); overflow: hidden; margin-top: 6px;
}
.mini-bar.grow { flex: 1; margin-top: 0; }
.mini-bar-fill { height: 100%; background: linear-gradient(90deg, var(--violet), var(--gold)); }

/* ── ESTADOS EXTRA ───────────────────────────────────────────── */
.status-abandoned-dot { background: var(--muted); }
.status-wished-dot { background: var(--amber); }
.status-btn.s-wished { border-color: var(--amber); color: var(--amber); }
.status-btn.s-abandoned { border-color: var(--muted); color: var(--muted); }

/* ── CABECERA: ACCIONES ──────────────────────────────────────── */
.header-actions { display: flex; align-items: center; gap: 8px; }
/* Sin caja: cuatro cajas seguidas en la cabecera pesaban más que el
   nombre de la app. El icono solo, y el latón al tocarlo. */
.icon-btn {
  position: relative;
  width: 30px; height: 30px; border-radius: var(--radius-sm);
  border: none; background: transparent;
  color: var(--lilac); cursor: pointer;
  display: grid; place-items: center; transition: color .2s;
}
.icon-btn:hover, .icon-btn:active { color: var(--gold); }
#save-state {
  font-size: 10px; color: var(--muted-soft); min-height: 12px;
  text-align: right; padding: 0 18px 4px;
}

/* La app solo se ve con sesión iniciada */
body:not(.signed-in) .app-wrapper,
/* Sin sesión no hay ni «+» ni atajos para salir de casa: los dos
   necesitan tu biblioteca y tu ciudad. Los botones del margen se
   quedaron fuera de esta regla al añadirlos y se veían en la pantalla
   de entrada, encima del formulario. */
body:not(.signed-in) .fab,
body:not(.signed-in) .atajos { display: none; }

/* Foco visible: quien navega con teclado tiene que ver dónde está */
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 4px; }

/* ── PANTALLA DE CARGA ───────────────────────────────────────── */
#loading-screen {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  background: var(--void);
}
.load-rune { font-family: var(--font-display); font-size: 28px; color: var(--gold); }
.load-text {
  font-family: var(--font-display); font-size: 14px;
  color: rgb(var(--lilac-rgb) / .7); letter-spacing: 2px;
}
.load-bar { width: 40px; height: 2px; background: rgb(var(--lilac-rgb) / .2); border-radius: 1px; overflow: hidden; }
.load-bar-fill { width: 100%; height: 100%; background: var(--violet); animation: slide 1.2s ease-in-out infinite; }
@keyframes slide { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }

/* ── LOGROS ──────────────────────────────────────────────────
   Los bloqueados se ven, con su condición: saber qué falta es
   parte del incentivo (historia #70). */
.ach-list { display: flex; flex-direction: column; gap: 2px; }
.ach {
  display: grid; grid-template-columns: auto 1fr auto;
  gap: 12px; align-items: center;
  padding: 11px 0; border-bottom: 1px solid var(--border-soft);
}
.ach:last-child { border-bottom: 0; }
/* La columna del medio de `.ach`: sin esto un nombre largo empuja el
   contador fuera de la fila en vez de partirse. */
.ach-body { min-width: 0; }
.ach-icon { font-size: 19px; width: 24px; text-align: center; opacity: .5; }
.ach.got .ach-icon { opacity: 1; }
.ach-name { font-size: 13.5px; color: var(--muted); }
.ach.got .ach-name { color: var(--text); }
.ach-hint { font-size: 11.5px; color: var(--muted-soft); margin-top: 2px; line-height: 1.5; }
.ach.got .ach-hint { color: var(--gold); }
.ach-count {
  font-size: 11px; color: var(--muted-soft);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}


/* ── CERRAR UNA HOJA ──────────────────────────────────────────
   Antes solo se cerraban tocando el fondo, que nadie adivina. */
.sheet-close {
  position: absolute;
  top: 12px; right: 14px;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: 15px;
  cursor: pointer;
  z-index: 2;
  transition: color .18s;
}
.sheet-close:hover, .sheet-close:active { color: var(--gold); }
.sheet { position: relative; }


/* ── AÑADIR UN LIBRO ──────────────────────────────────────────
   Los tres caminos —título, cámara, a mano— comparten hoja, así
   que comparten también el aire: una lista de candidatos que se
   lee de un vistazo y una ficha que se puede corregir. */

#add-results { display: flex; flex-direction: column; gap: 6px; }

.cand {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 9px 11px; text-align: left; cursor: pointer;
  border: var(--card-border); border-radius: var(--radius-sm);
  background: var(--card); color: var(--text);
  font-family: var(--font-body);
  transition: border-color .18s, transform .18s, background .18s;
}
.cand:hover { border-color: var(--border-strong); background: var(--fog-soft); transform: translateX(2px); }
.cand img, .cand-ph {
  width: 38px; height: 56px; flex-shrink: 0;
  object-fit: cover;
  border-radius: calc(var(--radius-sm) * .6);
  border: var(--card-border); box-shadow: var(--cover-frame);
}
.cand-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cand-title {
  font-size: 13.5px; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.cand-sub { font-size: 11.5px; color: var(--muted); }

/* ── LA CÁMARA ────────────────────────────────────────────────
   El marco no recorta nada: solo dice dónde poner el libro, que
   es la mitad de que el escáner acierte a la primera. */
.scan-stage {
  position: relative; overflow: hidden;
  aspect-ratio: 3 / 4; max-height: 46vh; margin-bottom: 12px;
  border: var(--card-border); border-radius: var(--radius);
  background: var(--void);
}
.scan-stage video { width: 100%; height: 100%; object-fit: cover; display: block; }
.scan-frame {
  position: absolute; inset: 12% 10%;
  border-radius: var(--radius-sm);
  pointer-events: none;
  box-shadow: 0 0 0 100vmax var(--shade);
  border: 1px solid rgb(var(--gold-rgb) / .55);
}
.scan-frame::before, .scan-frame::after {
  content: ''; position: absolute; width: 22px; height: 22px;
  border: 2px solid var(--gold);
}
.scan-frame::before { top: -1px; left: -1px; border-right: 0; border-bottom: 0; }
.scan-frame::after { bottom: -1px; right: -1px; border-left: 0; border-top: 0; }

/* EL LATIDO DICE QUE ESTÁ MIRANDO.
   «No se sabe si está viendo, tomando una foto o qué.» El marco era
   idéntico mirando y sin mirar, y la cámara encendida no significa
   nada: cualquier app enseña la cámara. Lo que hacía falta era una
   señal de que ESTÁ BUSCANDO ahora mismo, y que se vea sin leer.

   Es el borde el que late, no todo el marco: las cuatro esquinas se
   quedan quietas para que siga sirviendo de guía de encuadre
   mientras. */
@keyframes scan-latido {
  0%, 100% { border-color: rgb(var(--gold-rgb) / .35); }
  50%      { border-color: rgb(var(--gold-rgb) / .95); }
}
.scan-frame.buscando { animation: scan-latido 1.6s ease-in-out infinite; }

/* Y CUANDO YA LO TIENE, DEJA DE LATIR.
   El latido significa «estoy buscando». Si sigue latiendo con el código
   ya leído, sigue diciendo que busca — y entonces no significa nada. */
.scan-frame.leido {
  animation: none;
  border-color: rgb(var(--gold-rgb) / .95);
  border-width: 2px;
}

/* LA INSTRUCCIÓN NO ES EL ESTADO.
     «¿Por qué no dice "toma la foto del código de barras"? ¿Cuánto
      tiempo debo tener la cámara en el código de barras?»
   Estaban en el mismo hueco, así que la instrucción vivía medio segundo
   y luego la pisaba «Buscando el código…» para siempre. Esta va encima
   del vídeo y no la toca nadie. */
.scan-guia {
  margin: 0 0 10px;
  font-size: 13px; line-height: 1.5;
  color: var(--muted);
}
.scan-guia b { color: var(--text); }

/* LOS DÍGITOS QUE LEYÓ, para poder compararlos con el libro.
   Tabulares y espaciados: se leen de uno en uno, que es como se
   comparan con los de debajo de las barras. */
.scan-codigo {
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
  color: var(--text);
}

/* La portada es OTRO camino, no el segundo paso de este.
   Pegada al escáner se leía como parte de lo mismo. */
.scan-otro {
  margin-top: 18px; padding-top: 14px;
  border-top: var(--card-border);
}
.scan-otro .set-fineprint { margin: 0 0 8px; }

/* ── «ESTÁ HACIENDO ALGO» ────────────────────────────────────
   «No hay alguna barra o círculo de carga para ver que el código está
    haciendo algo.»

   Y no lo había. Un texto quieto durante treinta segundos —lo que
   tarda en bajar el diccionario del lector de texto— no parece que
   trabaje: parece que no pasó nada. El círculo gira siempre, aunque no
   se sepa cuánto queda, porque su trabajo no es medir sino demostrar
   que la app sigue viva. */
.trabajo { display: flex; align-items: center; gap: 9px; margin: 12px 0 6px; }
.trabajo-giro {
  width: 15px; height: 15px; flex-shrink: 0; border-radius: 50%;
  border: 2px solid rgb(var(--lilac-rgb) / .25);
  border-top-color: var(--gold);
  animation: girar .8s linear infinite;
}
.trabajo-txt { font-size: 12.5px; color: var(--muted); line-height: 1.45; }
@keyframes girar { to { transform: rotate(360deg); } }

.trabajo-bar {
  height: 3px; border-radius: 2px; overflow: hidden;
  background: rgb(var(--lilac-rgb) / .18);
}
.trabajo-bar i { display: block; height: 100%; background: var(--gold); transition: width .25s ease; }
/* Sin porcentaje que enseñar, la barra recorre en vez de llenarse: no
   promete un final que no se puede calcular. */
.trabajo-bar.sin-fin i { width: 40% !important; animation: slide 1.2s ease-in-out infinite; transition: none; }

/* ── DÓNDE QUEDAR  ·  historia #157 ──────────────────────────
   Cada sitio es una fila que se toca entera para proponerlo, con el
   mapa aparte a la derecha. Separados a propósito: abrir el mapa y
   proponer el sitio son cosas distintas y una no debe llevar a la
   otra por error. */
/* Aire entre la explicación y el primer grupo: sin él, «no se manda
   hasta que le des a Enviar» y «BIBLIOTECAS» se leen como un mismo
   bloque. */
.lugares-intro { margin: 0 0 20px; }
.lugares-tabs { margin-bottom: 14px; }

/* HASTA DÓNDE MIRAR. Debajo de las pestañas y con la misma forma,
   porque son la misma clase de decisión —qué lista estoy viendo— y
   inventarles otro aspecto sería hacerlas parecer un ajuste.

   Los metros van en una línea aparte y más pequeños: se leen al elegir
   y estorban al volver a mirar. */
/* DECIR DÓNDE BUSCAR. La caja y su botón en una línea: escribir el
   barrio y buscarlo son un solo gesto, y partirlos en dos filas hace
   que el botón parezca de otra cosa. */
/* LO QUE LE PASÓ A UN CÓDIGO, que se queda hasta que haya otro.
   Separado del estado de la cámara —que se reescribe cada vez que
   vuelve a mirar— porque si no, el aviso y su botón duran los dos
   segundos y medio que tarda el escáner en volver a empezar. */
#scan-fallo:not(:empty) { margin-top: 10px; }
.scan-fallo-txt { margin: 0 0 10px; font-size: .9rem; color: var(--muted); }

.lugares-donde { margin-bottom: 14px; }
.lugares-donde-caja { display: flex; gap: 8px; align-items: stretch; }
.lugares-donde-caja .finput { flex: 1; min-width: 0; }
.lugares-donde-caja .btn-mini { flex: 0 0 auto; padding-inline: 14px; }
.lugares-donde-pie { margin: 6px 0 0; }
/* «Quitar» es texto y no botón a propósito: deshacer no puede pesar
   más que hacer. */
.lugares-quitar {
  padding: 0; border: 0; background: none; font: inherit; cursor: pointer;
  color: var(--gold); text-decoration: underline;
}

.lugares-lejos { margin-bottom: 14px; }
.lugares-lejos .auth-tab { flex-direction: column; gap: 1px; line-height: 1.25; }
.lugares-lejos-km { display: block; font-size: .74rem; opacity: .7; font-weight: 400; }

/* La estantería se toca ENTERA para abrirla; renombrar y borrar van a
   un lado y en pequeño, que es el peso que les toca. */
.shelf-abrir {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px;
  padding: 0; border: 0; background: transparent; cursor: pointer;
  text-align: left; font: inherit; color: inherit;
}
.shelf-abrir .shelf-row-info { display: flex; flex-direction: column; gap: 2px; }
/* El icono de cada grupo, alineado con su nombre. */
.prof-sec-title .ico { display: inline-block; vertical-align: -2px; margin-right: 5px; }

/* Lo que dijo el servicio al fallar, en pequeño. No es para leerlo: es
   para poder copiarlo y contarlo, que es lo que convierte un «no
   funciona» en algo que se puede arreglar. */
.lugares-detalle { margin-top: 14px; opacity: .75; word-break: break-word; }

.sitio {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0; border-bottom: 1px solid var(--border-soft);
}
.sitio:last-child { border-bottom: 0; }
.sitio-elegir {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  padding: 0; border: 0; background: transparent; cursor: pointer;
  text-align: left; font: inherit; color: inherit;
}
.sitio-nombre { font-size: 14px; color: var(--text); line-height: 1.35; }
.sitio-datos { font-size: 11.5px; color: var(--muted); }
.sitio-horario { font-size: 11px; color: var(--lilac); font-style: italic; }
.sitio .btn-mini { flex-shrink: 0; text-decoration: none; }

/* La foto recién tomada, que es la prueba de que salió. */
.foto-tomada {
  border-radius: var(--radius-sm); overflow: hidden;
  border: var(--card-border); background: var(--fog);
  max-height: 260px; display: grid; place-items: center;
}
.foto-tomada img { width: 100%; max-height: 260px; object-fit: contain; display: block; }

@media (prefers-reduced-motion: reduce) {
  .trabajo-giro { animation: none; border-top-color: var(--gold); }
  .trabajo-bar.sin-fin i { animation: none; width: 100% !important; }
}

/* Quien tiene el movimiento reducido no necesita un latido para saber
   que pasa algo: el texto de debajo ya lo dice. */
@media (prefers-reduced-motion: reduce) {
  .scan-frame.buscando { animation: none; border-color: rgb(var(--gold-rgb) / .95); }
}

/* ── LA FICHA ENCONTRADA ──────────────────────────────────────
   La portada al lado de los campos: se ve de inmediato si el
   catálogo trajo el libro correcto o uno parecido. */
.draft-head { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 16px; }
.draft-head > div { flex: 1; min-width: 0; }
.draft-cover {
  width: 78px; height: 116px; flex-shrink: 0; object-fit: cover;
  border-radius: var(--radius-sm);
  border: var(--card-border); box-shadow: var(--cover-frame);
}
.draft-source {
  font-size: 10px; letter-spacing: var(--label-spacing); text-transform: uppercase;
  color: var(--lilac); margin-bottom: 7px;
}
.draft-meta { font-size: 11.5px; color: var(--muted); margin-top: 7px; }


/* ── ¿ME LO LEO?  ·  QUÉ LEER DESPUÉS ─────────────────────────
   Lo que dice el agente va enmarcado y con su propia voz, para que
   nunca se confunda con lo que escribiste tú. */

.brief {
  padding: 14px 16px; margin-bottom: 18px;
  border: var(--card-border); border-left: 3px solid var(--lilac);
  border-radius: var(--radius-sm);
  background: var(--fog-soft);
}
.brief-text { font-size: 13.5px; line-height: 1.65; color: var(--text); }
.brief-row {
  display: flex; gap: 9px; align-items: baseline;
  margin-top: 9px; font-size: 12.5px; line-height: 1.55; color: var(--muted);
}
.brief-tag {
  flex-shrink: 0; padding: 2px 8px;
  border: var(--hairline); border-radius: var(--pill-radius);
  font-size: 10px; letter-spacing: var(--label-spacing); text-transform: uppercase;
  color: var(--muted-soft);
}
.brief-tag.ok { color: var(--success); border-color: rgb(var(--success-rgb) / .35); }
.brief-tag.no { color: var(--amber); border-color: rgb(var(--amber-rgb) / .35); }

.recs { display: flex; flex-direction: column; gap: 10px; margin: 14px 0 4px; }
.rec {
  padding: 13px 15px;
  border: var(--card-border); border-radius: var(--radius);
  background: var(--card);
}
.rec-title { font-family: var(--font-display); font-size: 15px; color: var(--gold); line-height: 1.3; }
.rec-author { font-size: 12px; color: var(--muted); margin-top: 3px; }
.rec-why { font-size: 12.5px; line-height: 1.6; color: var(--muted); margin-top: 9px; }

/* Una sugerencia comprobada: portada y datos del catálogo, y el
   porqué del agente debajo, separado — para que se vea de un vistazo
   qué es dato y qué es opinión. */
.rec-head { display: flex; gap: 12px; align-items: flex-start; }
.rec-cover {
  width: 46px; height: 68px; flex-shrink: 0; object-fit: cover;
  border-radius: calc(var(--radius-sm) * .7);
  border: var(--card-border); box-shadow: var(--cover-frame);
}
.rec-info { min-width: 0; }
.rec-add { width: 100%; margin-top: 11px; font-size: 12.5px; }
.rec-add:disabled { color: var(--success); border-color: rgb(var(--success-rgb) / .4); cursor: default; }

/* ── QUÉ SE ENVÍA ─────────────────────────────────────────────
   El aviso del agente. Cada fila dice una cosa que sale de la app,
   en una tabla y no en un párrafo, porque un párrafo largo sobre
   privacidad no lo lee nadie. */
.notice-sheet { max-width: 420px; }
.notice-list {
  display: flex; flex-direction: column; gap: 1px;
  margin: 14px 0 16px; overflow: hidden;
  border: var(--card-border); border-radius: var(--radius-sm);
  background: var(--border-soft);
}
.notice-row { padding: 11px 13px; background: var(--card-solid); }
.notice-what {
  font-size: 10px; letter-spacing: var(--label-spacing); text-transform: uppercase;
  color: var(--lilac); margin-bottom: 4px;
}
.notice-sends { font-size: 12.5px; line-height: 1.6; color: var(--text); }
/* «No, gracias» partía en dos líneas y quedaba como un botón dudoso. */
.confirm-actions button { white-space: nowrap; }

/* ── ESTANTERÍAS  ·  historia #22 ─────────────────────────────
   Cada una tiene su color, pero el color sale de un token del tema
   (`--shelf-rgb`), no de un hex suelto: así una estantería se ve bien
   en los nueve mundos sin revisar el contraste por cada una. */

/* Una estantería no es un filtro excluyente: se marcan varias a la vez
   y cada una tiene su color, así que aquí sí hace falta una etiqueta
   con forma. `.chip` ya no la da —es una pestaña de texto— y estas se
   la ponen entera. */
.chip-shelf, .chip-new {
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-bottom-width: 1px;
  border-radius: var(--pill-radius);
}
.chip-shelf { border-color: rgb(var(--shelf-rgb) / .35); color: rgb(var(--shelf-rgb) / .95); }
.chip-shelf.active {
  background: rgb(var(--shelf-rgb) / .18);
  border-color: rgb(var(--shelf-rgb) / .7);
  color: rgb(var(--shelf-rgb));
}
.chip-count {
  margin-left: 5px; opacity: .6;
  font-variant-numeric: tabular-nums;
}
.chip-new { border-style: dashed; color: var(--muted); }

/* En la ficha del libro, donde se meten y se sacan. */
.shelf-picker {
  display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 18px;
}
.shelf-picker .chip { font-family: var(--font-body); }

/* Elegir símbolo y color al crear una. */
.shelf-emojis { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.shelf-emoji {
  width: 38px; height: 38px; font-size: 17px; cursor: pointer;
  border: var(--hairline); border-radius: var(--radius-sm);
  background: var(--card); transition: all .18s;
}
.shelf-emoji.on { border-color: var(--gold); background: var(--gold-wash); }

.shelf-colors { display: flex; gap: 8px; margin-bottom: 10px; }
.shelf-color {
  width: 32px; height: 32px; cursor: pointer;
  border-radius: 50%; border: 2px solid transparent;
  background: rgb(var(--shelf-rgb) / .85);
  transition: all .18s;
}
.shelf-color.on { border-color: var(--text); transform: scale(1.12); }

/* Gestionarlas, en Ajustes. */
.shelf-manage { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.shelf-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border: 1px solid rgb(var(--shelf-rgb) / .3);
  border-left: 3px solid rgb(var(--shelf-rgb) / .8);
  border-radius: var(--radius-sm);
  background: var(--card);
}
.shelf-row-emoji { font-size: 17px; }
.shelf-row-info { flex: 1; min-width: 0; }
.shelf-row-name { font-size: 13.5px; color: var(--text); }
.shelf-row-count { font-size: 11px; color: var(--muted); margin-top: 2px; }

/* ── CITAS  ·  historia #29 ───────────────────────────────────
   Una cita tiene que parecer una cita: con su comilla, su sangría y
   su tipografía de lectura. Si se ve como un campo de formulario más,
   guardar frases deja de apetecer. */

.quote {
  position: relative;
  margin: 0 0 12px;
  padding: 14px 16px 12px 34px;
  border: var(--card-border);
  border-left: 2px solid rgb(var(--gold-rgb) / .5);
  border-radius: var(--radius-sm);
  background: var(--fog-soft);
}
.quote::before {
  content: '❞';
  position: absolute; left: 11px; top: 10px;
  font-family: var(--font-display);
  font-size: 19px; line-height: 1;
  color: rgb(var(--gold-rgb) / .55);
}
.quote-text {
  margin: 0;
  font-family: var(--font-display);
  font-size: 14.5px; line-height: 1.7;
  color: var(--text);
  white-space: pre-wrap;
}
/* Una reseña en el perfil de alguien: papel citado, con su filete al
   margen izquierdo como una cita larga en un libro. */
.quote-card {
  margin: 0 0 14px;
  padding: 2px 0 0 14px;
  border-left: 2px solid rgb(var(--gold-rgb) / .45);
}
.quote-card blockquote {
  margin: 0;
  font-size: 14px;
  font-style: italic;
  line-height: 1.55;
  color: var(--text);
}
.quote-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 11px;
}
.quote-page {
  font-size: 11px; color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.quote-nopage { color: var(--muted-soft); }
.quote-note {
  flex: 1; min-width: 120px;
  font-size: 11.5px; color: var(--muted); font-style: italic;
}
.quote-book {
  flex: 1; min-width: 140px; text-align: left; padding: 0;
  background: none; border: 0; cursor: pointer;
  font-family: var(--font-body); font-size: 11.5px; color: var(--lilac);
}
.quote-book:hover { text-decoration: underline; }
.quote-standalone { background: var(--card); }

/* El marco de la cámara, al capturar una cita: apaisado, porque una
   frase ocupa lo ancho de la página y no un cuadrado. */
.quote-frame { inset: 26% 6%; }

/* ── HOJAS QUE SE ABREN SOBRE OTRA HOJA ───────────────────────
   Todas las hojas comparten z-index (300), así que entre dos abiertas
   gana la que esté DESPUÉS en el marcado. Una hoja que se abre desde
   la ficha de un libro y está antes en el HTML queda debajo: se ve,
   y no se puede tocar.

   Ya pasó dos veces —guardar una cita, y celebrar un libro
   terminado—, así que van juntas y con su motivo. Si añades otra
   hoja que se abra desde una ficha, súmala aquí. */
#qcap-overlay,
#done-overlay { z-index: 320; }

/* ── AL TERMINAR UN LIBRO  ·  historia #64 ────────────────────
   Una sugerencia que no se explica se ignora, y peor: no se puede
   corregir. Por eso el porqué va en la tarjeta y no escondido. */

.done-lede { font-size: 15px; color: var(--text); line-height: 1.6; margin-bottom: 6px; }
.done-lede strong { color: var(--gold); font-family: var(--font-display); }
.done-stars { justify-content: center; margin: 18px 0 6px; }
.done-stars .star { font-size: 34px; padding: 0 5px; }

.sug {
  padding: 13px 14px; margin-bottom: 9px;
  border: var(--card-border); border-radius: var(--radius);
  background: var(--card);
}
.sug-head { display: flex; gap: 11px; align-items: flex-start; }
.sug-cover {
  width: 40px; height: 60px; flex-shrink: 0; object-fit: cover;
  border-radius: calc(var(--radius-sm) * .7);
  border: var(--card-border); box-shadow: var(--cover-frame);
}
.sug-info { min-width: 0; }
.sug-title { font-family: var(--font-display); font-size: 14.5px; color: var(--gold); line-height: 1.35; }
.sug-author { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.sug-why {
  font-size: 12px; line-height: 1.55; color: var(--lilac);
  margin: 9px 0 0; font-style: italic;
}
.sug-actions { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; margin-top: 11px; }
.btn-sug { flex: 1; min-width: 96px; padding: 8px 12px; font-size: 12.5px; }

/* ── EL PERFIL PÚBLICO  ·  historia #45 ──────────────────────── */
.prof-head { display: flex; align-items: center; gap: 13px; margin-bottom: 12px; }
.prof-avatar {
  width: 58px; height: 58px; flex-shrink: 0; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent-wash); border: 1px solid var(--border-strong);
  font-family: var(--font-display); font-size: 26px; color: var(--gold);
}
.prof-id { min-width: 0; flex: 1; }
.prof-name { font-family: var(--font-display); font-size: 19px; color: var(--text); line-height: 1.25; }
.prof-handle { font-size: 12.5px; color: var(--gold); margin-top: 2px; }
.prof-city { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.prof-pet { width: 62px; height: 62px; flex-shrink: 0; }
.prof-pet svg { width: 100%; height: 100%; }
/* Las especies ilustradas llegan como IMAGEN, no como SVG, y traen
   puestas dos cosas del inicio que aquí estorban:

   · el margen negativo que las apoya en la balda —aquí no hay balda—;
   · y la respiración, que en 62 px al lado de un nombre es un tic.
     Además la escala llegaba a 1.022, así que el oso medía 63 en un
     hueco de 62: medido, no supuesto.

   Aquí es un retrato de la mascota de otra persona, quieto. */
.prof-pet .pet-escena { display: block; width: 100%; height: 100%; }
.prof-pet .pet-img {
  width: 100%; height: 100%;
  margin-bottom: 0;
  animation: none;
}
/* Y sin su rincón: en 62 px, una escena detrás del bicho es ruido. */
.prof-pet .pet-rincon { display: none; }
.prof-bio {
  font-size: 13px; line-height: 1.65; color: var(--text);
  margin: 0 0 8px; font-style: italic;
}
.prof-resumen { font-size: 11.5px; color: var(--muted); margin: 0 0 16px; }

.prof-nums { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.prof-num {
  flex: 1; min-width: 74px; text-align: center; padding: 11px 6px;
  border: var(--card-border); border-radius: var(--radius-sm); background: var(--card);
}
.prof-num b { display: block; font-family: var(--font-display); font-size: 21px; color: var(--gold); }
.prof-num span { display: block; font-size: 10.5px; color: var(--muted); margin-top: 3px; }

.prof-sec { margin-bottom: 18px; }
.prof-sec-title {
  font-family: var(--font-display); font-size: 13px; color: var(--lilac);
  margin: 0 0 9px; letter-spacing: .04em; text-transform: uppercase;
}
.prof-book { display: flex; gap: 11px; align-items: center; margin-bottom: 9px; }
.prof-cover {
  width: 42px; height: 63px; flex-shrink: 0; object-fit: cover;
  border-radius: calc(var(--radius-sm) * .7);
  border: var(--card-border); box-shadow: var(--cover-frame);
}
.prof-cover-none {
  display: grid; place-items: center; background: var(--fog);
  font-family: var(--font-display); font-size: 18px; color: var(--gold);
}
.prof-book-txt { min-width: 0; flex: 1; }
.prof-book-title { font-family: var(--font-display); font-size: 14px; color: var(--text); line-height: 1.35; }
.prof-book-author { font-size: 11.5px; color: var(--muted); margin-top: 3px; }

.prof-mine { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border-soft); }

/* «Se ve» / «Oculto»: el estado se lee sin tener que interpretar un
   interruptor, que en una pantalla de privacidad importa más de lo
   normal. Quien mira tiene que saber qué está publicando de un vistazo. */
.prof-flag {
  flex-shrink: 0; font-size: 11px; padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--muted-soft); background: var(--fog);
}
.prof-flag.on {
  color: var(--success); background: var(--success-wash);
  border-color: rgb(var(--success-rgb) / .4);
}

/* ── SEGUIR Y ENCONTRAR  ·  historias #46 y #47 ──────────────── */
.rel-counts { display: flex; gap: 8px; margin: 0 0 12px; }
.rel-count {
  flex: 1; padding: 9px 6px; text-align: center; cursor: pointer;
  border: var(--card-border); border-radius: var(--radius-sm);
  background: var(--card); color: inherit; font: inherit;
}
.rel-count b { display: block; font-family: var(--font-display); font-size: 17px; color: var(--gold); }
.rel-count span { display: block; font-size: 10.5px; color: var(--muted); margin-top: 2px; }
.rel-actions { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
/* Siguiendo se ve distinto de Seguir: si los dos estados se parecen,
   nadie sabe si el toque funcionó. */
.btn-magic.is-following {
  background: transparent; color: var(--muted);
  border: 1px solid var(--border-strong); box-shadow: none;
}
.rel-badge {
  flex-shrink: 0; font-size: 11px; padding: 5px 10px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--lilac); background: var(--fog);
}

.pers-row {
  display: flex; align-items: center; gap: 11px; cursor: pointer;
  padding: 10px 0; border-bottom: 1px solid var(--border-soft);
}
.pers-row:last-child { border-bottom: 0; }
.pers-row.nuevo { background: var(--accent-wash); margin: 0 -6px; padding-inline: 6px; }
.pers-avatar {
  width: 42px; height: 42px; flex-shrink: 0; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent-wash); border: 1px solid var(--border-strong);
  font-family: var(--font-display); font-size: 18px; color: var(--gold);
}
.pers-txt { min-width: 0; flex: 1; }
.pers-name { font-size: 14px; color: var(--text); line-height: 1.35; }
.pers-handle { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.pers-why { font-size: 11.5px; color: var(--lilac); margin-top: 3px; font-style: italic; }
/* Los números de quien sigues. Van en su propia línea y NO en cursiva:
   «Leyendo tal libro» es una frase y «12 libros en 2026» es un dato, y
   si los dos se ven igual hay que leerlos para distinguirlos. */
.pers-datos { font-size: 11px; color: var(--muted); margin-top: 2px; }

/* «A quién sigues» dentro del feed. El feed es la noticia y esto la
   referencia, así que se separa con la misma raya que el resto de la
   app usa para decir «esto ya es otra cosa». Sin ella, el título se
   pegaba al texto de arriba y parecían el mismo bloque. */
.feed-sigues { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--border-soft); }

/* El punto de avisos sin leer */
.notice-dot {
  position: absolute; top: -4px; right: -6px; min-width: 17px; height: 17px;
  padding: 0 4px; border-radius: 999px; display: grid; place-items: center;
  background: var(--danger); color: var(--void); font-size: 10px; font-weight: 700;
}

/* ── INVITAR: LINK Y QR  ·  historia #48 ─────────────────────── */
/* El QR va sobre blanco SIEMPRE, pase lo que pase con el tema: un
   código con poco contraste no lo lee ninguna cámara, y este se enseña
   justo cuando peor va la conexión y menos ganas hay de reintentar. */
.qr-card {
  background: #fff; border-radius: var(--radius); padding: 16px 16px 12px;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  margin: 12px auto 14px; width: fit-content;
  box-shadow: 0 6px 26px rgb(0 0 0 / .35);
}
.qr-card svg { display: block; }
.qr-handle { color: #1a1526; font-size: 14px; font-weight: 600; letter-spacing: .01em; }
.qr-link {
  font-size: 11.5px; color: var(--muted); word-break: break-all;
  text-align: center; margin-bottom: 12px;
}
.qr-cam { position: relative; margin: 10px 0; border-radius: var(--radius); overflow: hidden; }
.qr-cam video { width: 100%; display: block; background: #000; }
.qr-frame {
  position: absolute; inset: 18% 12%; pointer-events: none;
  border: 2px solid var(--gold); border-radius: var(--radius-sm);
  box-shadow: 0 0 0 100vmax rgb(0 0 0 / .35);
}

/* ── EL FEED  ·  historia #49 ────────────────────────────────── */
.feed-card {
  border: var(--card-border); border-radius: var(--radius);
  background: var(--card); padding: 13px 14px; margin-bottom: 10px;
}
.feed-head { display: flex; align-items: center; gap: 10px; cursor: pointer; margin-bottom: 11px; }
.feed-avatar { width: 34px; height: 34px; font-size: 15px; }
.feed-who { min-width: 0; }
.feed-line { font-size: 13px; color: var(--text); line-height: 1.35; }
.feed-when { font-size: 11px; color: var(--muted-soft); margin-top: 2px; }
.feed-book { display: flex; gap: 11px; align-items: center; }
.feed-book-txt { min-width: 0; flex: 1; }
.feed-stars { color: var(--gold); font-size: 12px; margin-top: 4px; letter-spacing: .06em; }
.feed-review {
  font-size: 12.5px; line-height: 1.6; color: var(--lilac);
  margin: 10px 0 0; font-style: italic;
}
.feed-logro {
  font-family: var(--font-display); font-size: 15px; color: var(--gold);
  padding: 10px 12px; border-radius: var(--radius-sm); background: var(--accent-wash);
}
.feed-add { width: 100%; margin-top: 11px; }
.feed-add.tengo { color: var(--success); border-color: rgb(var(--success-rgb) / .35); opacity: 1; }

/* El punto de avisos usa `display:grid`, y una clase gana a `[hidden]`
   por especificidad: sin esto, el punto se quedaba puesto enseñando un
   0 rojo permanente. */
.notice-dot[hidden] { display: none; }

/* Con cuatro botones en la cabecera la marca se partía en dos líneas.
   Las gemas son un resumen que el Tracker ya da entero, así que en
   pantallas estrechas ceden el sitio antes que el nombre de la app. */
.brand-title { white-space: nowrap; }
@media (max-width: 460px) {
  .header-gems { display: none; }
}

/* ── COMENTARIOS Y MODERACIÓN  ·  #50 y #51 ──────────────────── */
.feed-pie { display: flex; gap: 8px; margin-top: 10px; }
.feed-pie .btn-mini { flex: 1; }

.react-row { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 12px; }
.react {
  display: flex; align-items: center; gap: 5px; cursor: pointer;
  padding: 6px 11px; border-radius: 999px; font-size: 15px;
  border: 1px solid var(--border); background: var(--fog); color: inherit;
}
.react.mia { border-color: var(--gold); background: var(--accent-wash); }
.react span { font-size: 11px; color: var(--muted); }

.cmt { display: flex; gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--border-soft); }
.cmt.respuesta { padding-left: 26px; }
.cmt-avatar { width: 32px; height: 32px; font-size: 14px; }
.cmt-cuerpo { min-width: 0; flex: 1; }
.cmt-cab { display: flex; align-items: baseline; gap: 8px; }
.cmt-quien { font-size: 12.5px; color: var(--gold); cursor: pointer; }
.cmt-cuando { font-size: 11px; color: var(--muted-soft); }
.cmt-texto { font-size: 13.5px; line-height: 1.6; color: var(--text); margin: 5px 0 0; }
.cmt-acciones { display: flex; gap: 6px; margin-top: 7px; }
.cmt-acciones .btn-mini { padding: 4px 9px; font-size: 11px; }

/* El spoiler NO se tapa con un desenfoque: un desenfoque se lee de
   reojo y se quita con el inspector. El texto no está en la página
   hasta que se toca. */
.cmt-spoiler-tapa {
  display: block; width: 100%; text-align: left; cursor: pointer;
  margin-top: 5px; padding: 10px 12px; border-radius: var(--radius-sm);
  border: 1px dashed var(--border-strong); background: var(--fog);
  color: var(--muted); font-size: 12.5px; font-style: italic;
}
.cmt-write { margin-top: 16px; }
.cmt-row {
  display: flex; align-items: center; justify-content: space-between;
  margin: 8px 0 10px;
}
.cmt-spoiler { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.cmt-count { font-size: 11px; color: var(--muted-soft); }

.prof-mod { display: flex; gap: 8px; margin-top: 6px; }
.prof-mod .btn-mini { flex: 1; }

/* ── INTERCAMBIO  ·  #81, #82, #89 ───────────────────────────── */
.opt { color: var(--muted-soft); font-weight: 400; }

/* Los requisitos que faltan, con lo que ya cumples marcado: ver que
   llevas tres de cuatro anima a hacer la cuarta. */
.req { display: flex; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border-soft); }
.req:last-of-type { border-bottom: 0; }
.req-marca { color: var(--muted-soft); font-size: 15px; line-height: 1.3; }
.req.ok .req-marca { color: var(--success); }
.req-texto { font-size: 13.5px; color: var(--text); }
.req.ok .req-texto { color: var(--muted); }
.req-como { font-size: 11.5px; color: var(--muted); margin-top: 3px; line-height: 1.5; }

.estados { display: flex; flex-direction: column; gap: 7px; }
.estado { display: flex; align-items: flex-start; gap: 9px; cursor: pointer; }
.estado span { display: block; font-size: 13px; color: var(--text); }
.estado small { display: block; font-size: 11px; color: var(--muted); margin-top: 2px; }

.swap-card {
  border: var(--card-border); border-radius: var(--radius);
  background: var(--card); padding: 12px 13px; margin-bottom: 10px;
}
.swap-title { font-family: var(--font-display); font-size: 15px; color: var(--gold); }
.swap-sub { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.swap-nota { font-size: 12.5px; color: var(--lilac); font-style: italic; margin: 8px 0 0; }
.swap-foto { width: 100%; border-radius: var(--radius-sm); margin-top: 9px; display: block; }
.swap-lugar { font-size: 11.5px; color: var(--muted); margin-top: 8px; }
.swap-acciones { display: flex; gap: 7px; margin-top: 10px; }
.swap-acciones .btn-mini { flex: 1; }

/* ── TRUEQUE · explorar y solicitar  ·  #83 y #84 ───────────────
   La marca de «lo tienes pendiente» es lo único de esta pantalla que
   se pinta con color de acento. Es deliberado: la nota de la historia
   dice que resaltar lo que ya querías leer es lo que separa esto de un
   tablón de anuncios, así que se resalta de verdad y no con un matiz
   que nadie ve. */
.swap-card.marca-quiero {
  border-color: rgb(var(--gold-rgb) / .45);
  box-shadow: 0 0 0 1px rgb(var(--gold-rgb) / .12);
}
.swap-marca {
  font-family: var(--font-display);
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 7px;
}
.swap-card.marca-leyendo .swap-marca { color: var(--lilac); }
.swap-card.marca-leido { opacity: .72; }
.swap-card.marca-leido .swap-marca { color: var(--muted); }

/* Portada y texto, uno al lado del otro: en una lista de libros
   ajenos la portada es lo que se reconoce antes que el título. */
.swap-cab { display: flex; gap: 11px; align-items: flex-start; }
.swap-cab > div { min-width: 0; flex: 1; }
.swap-portada {
  width: 52px;
  flex: 0 0 52px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  display: block;
}

.swap-estado {
  font-family: var(--font-display);
  font-size: 11.5px;
  color: var(--lilac);
  margin-top: 5px;
}
.swap-card.cerrada { opacity: .6; }
.swap-contra {
  font-size: 12.5px;
  color: var(--lilac);
  background: rgb(var(--lilac-rgb) / .08);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  margin-top: 9px;
}

/* Los libros que se ofrecen: se envuelven en vez de desplazarse, para
   poder ver de un vistazo cuáles llevas marcados. */
.ask-libros {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-height: 168px;
  overflow-y: auto;
  margin-top: 6px;
}
.ask-libros .chip { max-width: 100%; }

/* Con cinco pestañas el texto se aprieta. Se encoge la letra en vez de
   quitar la etiqueta: un icono solo no dice qué es «⇄». */
@media (max-width: 420px) {
  .nav-label { font-size: 9.5px; letter-spacing: 0; }
}

/* ── EL CHAT DEL INTERCAMBIO  ·  #85, #86 y #88 ─────────────────
   El aviso de seguridad NO se puede cerrar. Se encoge a una línea
   después de la primera vez, pero se queda: un aviso que se cierra
   para siempre es un aviso que nadie lee la segunda vez, que es justo
   cuando ya te has confiado. */
.chat-aviso {
  background: rgb(var(--gold-rgb) / .12);
  border: 1px solid rgb(var(--gold-rgb) / .3);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  font-size: 12px;
  color: var(--gold);
  cursor: pointer;
  margin-bottom: 10px;
}
.chat-aviso-mas { text-decoration: underline; opacity: .8; margin-left: 4px; }

.chat-libro { margin-bottom: 10px; font-size: 13px; }

.chat-mensajes {
  min-height: 180px;
  max-height: 46vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 4px 0;
}
.burbuja {
  max-width: 82%;
  padding: 8px 11px;
  border-radius: 13px;
  font-size: 13.5px;
  line-height: 1.4;
  word-break: break-word;
}
.burbuja.mia {
  align-self: flex-end;
  background: rgb(var(--lilac-rgb) / .2);
  border-bottom-right-radius: 4px;
}
.burbuja.suya {
  align-self: flex-start;
  background: var(--fog);
  border-bottom-left-radius: 4px;
}
.burbuja-hora { display: block; font-size: 9.5px; color: var(--muted); margin-top: 3px; }

/* Quién lo dice, encima de lo que dice. Solo para ella: en un chat de
   dos, poner tu propio nombre sobre tus mensajes es ruido. */
.burbuja-dice { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; max-width: 82%; }
.burbuja-dice .burbuja { max-width: 100%; }
.burbuja-quien {
  font-size: 9.5px;
  letter-spacing: var(--label-spacing);
  text-transform: uppercase;
  color: var(--gold);
  padding-left: 2px;
}

/* El aviso de «esto parece un teléfono». Se ve, y se puede mandar
   igual: eso es lo que lo hace un aviso y no un filtro. */
.chat-cuidado {
  background: rgb(var(--gold-rgb) / .1);
  border-left: 2px solid var(--gold);
  padding: 7px 10px;
  font-size: 12px;
  color: var(--gold);
  margin: 8px 0;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.chat-escribir { display: flex; gap: 7px; align-items: flex-end; margin-top: 8px; }
.chat-escribir .finput { flex: 1; min-width: 0; }
/* `flex-basis: auto` significa «usa el width», y `.btn-magic` trae
   `width: 100%`: el botón pedía la fila entera y el campo se quedaba
   en un cuadradito. Le pasaba también al chat del trueque. */
.chat-escribir .btn-magic { flex: 0 0 auto; width: auto; padding: 10px 16px; }
.chat-acciones { display: flex; gap: 7px; margin-top: 12px; flex-wrap: wrap; }
.chat-acciones .btn-mini { flex: 1; min-width: 120px; }

/* ── HABLAR CON LA MASCOTA · #44 ──────────────────────────────
   Reusa las burbujas del trueque a propósito: en esta app una
   conversación se ve de UNA manera, la tengas con una amiga o con
   ella. Lo propio de aquí es solo quién habla. */
.petchat-cabeza {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 12px;
}
.petchat-retrato {
  flex: 0 0 auto;
  width: 64px; height: 64px;
  display: grid; place-items: center;
}
.petchat-retrato .pet-svg { width: 64px; height: 56px; }
.petchat-retrato .pet-img { width: 64px; height: 64px; margin-bottom: 0; }
/* A 64 px un rincón de 19 no cuenta nada: solo ensucia el retrato. */
.petchat-retrato .pet-rincon { display: none; }
.petchat-nombre { font-family: var(--font-display); font-size: 16px; color: var(--text); }
.petchat-sub { font-size: 12px; color: var(--muted); line-height: 1.5; margin-top: 2px; }
.petchat-sub strong { color: var(--text); }

/* Un cuadro vacío no dice de qué se puede hablar. Estas sí.
   NO reusan `.chip`: ese es la pestaña de un filtro —transparente y
   con filete abajo—, y aquí hace falta algo que se vea tocable. */
.petchat-sugerencias { display: flex; flex-direction: column; gap: 7px; margin: 4px 0 2px; }
.petchat-sug {
  width: 100%;
  text-align: left;
  padding: 10px 13px;
  border: var(--hairline);
  border-radius: var(--ctl-radius);
  background: var(--fog-soft);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.4;
  cursor: pointer;
  transition: border-color .18s, color .18s;
}
.petchat-sug:hover, .petchat-sug:active { border-color: var(--gold); color: var(--gold); }

/* Los tres puntos. Es la única forma de decir «te estoy oyendo»
   mientras se espera al servidor. */
.petchat-pensando { display: flex; gap: 4px; align-items: center; padding: 11px 13px; }
.petchat-pensando span {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--muted);
  animation: petchat-late 1.25s ease-in-out infinite;
}
.petchat-pensando span:nth-child(2) { animation-delay: .18s; }
.petchat-pensando span:nth-child(3) { animation-delay: .36s; }
@keyframes petchat-late {
  0%, 60%, 100% { opacity: .3; transform: translateY(0); }
  30%           { opacity: 1;  transform: translateY(-3px); }
}
@media (prefers-reduced-motion: reduce) {
  .petchat-pensando span { animation: none; opacity: .55; }
}

/* Un «no pude» no se pinta como si ella lo hubiera dicho. */
.burbuja-fallo { background: rgb(var(--amber-rgb) / .14); color: var(--amber); }

.sheet-alta { max-height: 92vh; }

/* Recomendaciones de seguridad */
.seg-item { margin-bottom: 13px; }
.seg-titulo { font-family: var(--font-display); font-size: 13.5px; color: var(--gold); }
.seg-texto { font-size: 12.5px; color: var(--muted); margin-top: 3px; line-height: 1.45; }
.puntos { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.punto {
  font-size: 12.5px;
  background: var(--fog-soft);
  border-radius: var(--radius-sm);
  padding: 7px 10px;
}

/* Valorar */
.estrellas { display: flex; gap: 6px; font-size: 26px; line-height: 1; margin-top: 4px; }
.estrella { cursor: pointer; color: var(--gold); user-select: none; }

/* La reputación. El número de intercambios va SIEMPRE; el promedio,
   solo cuando hay suficientes para que signifique algo (ver
   trust-core.js). */
.rep { margin-top: 10px; }
.rep-cifra { font-family: var(--font-display); font-size: 15px; color: var(--gold); }
.rep-nota { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.rep-ejes { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.rep-eje { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); }
.rep-eje b { color: var(--lilac); }

.trueque-atajos { display: flex; gap: 7px; margin-bottom: 12px; }
.trueque-atajos .btn-ghost { flex: 1; font-size: 11.5px; padding: 9px 6px; }

/* ── ESCRIBIR  ·  #72 y #73 ─────────────────────────────────────
   La visibilidad se ve en la lista SIN abrir la entrada. Tener que
   abrirla para saber quién la lee es lo que hace que alguien publique
   algo sin querer. */
.post-card {
  background: var(--fog-soft);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  padding: 11px 13px;
  margin-bottom: 9px;
  cursor: pointer;
}
.post-cab { display: flex; align-items: center; gap: 7px; margin-bottom: 5px; }
.post-vis { font-size: 14px; }
.post-tipo {
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
.post-titulo { font-family: var(--font-display); font-size: 14.5px; color: var(--gold); }
.post-adelanto { font-size: 12.5px; color: var(--muted); margin-top: 3px; line-height: 1.45; }
.post-libros { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
.post-libro {
  font-size: 10.5px;
  background: var(--fog);
  border-radius: 4px;
  padding: 2px 6px;
  color: var(--lilac);
}

.post-cuerpo { min-height: 200px; font-family: var(--font-body); line-height: 1.55; resize: vertical; }
.editor-atajos { display: flex; gap: 6px; margin-top: 7px; flex-wrap: wrap; }
.editor-estado { font-size: 11.5px; color: var(--muted); margin-top: 10px; min-height: 16px; }
.editor-agente { color: var(--lilac); }

/* Los tres niveles, con su explicación a la vista: elegir quién te lee
   no es una casilla, es una decisión. */
.vis-opciones { display: flex; flex-direction: column; gap: 7px; margin-top: 6px; }
.vis-op {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 9px 11px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.vis-op.active { border-color: rgb(var(--gold-rgb) / .5); background: var(--gold-wash); }
.vis-icono { font-size: 16px; }
.vis-label { font-size: 13px; }
.vis-sub { font-size: 11px; color: var(--muted); margin-top: 2px; }

/* Los enlaces legales al crear la cuenta. Se leen antes de aceptar,
   así que van a la vista y no escondidos tras un «ver más». */
.legal-acepta { line-height: 1.5; margin-top: 10px; }
.legal-acepta a { color: var(--lilac); }
.legal-acepta b { color: var(--gold); }
/* Las filas de ajustes que son enlaces de verdad se ven igual que las
   que abren una hoja: para quien las toca son la misma cosa. */
a.set-row { text-decoration: none; color: inherit; display: flex; }

/* ── DE QUÉ LIBRO SE HABLA  ·  cuando llevas varios a la vez ──
   Con un libro abierto la app afirma; con tres supone, y una
   suposición tiene que verse y poder corregirse. Solo aparece cuando
   hay más de uno: con uno sería una fila de un solo botón que no
   decide nada. */
.petchat-cuales {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 14px;
}
.petchat-cuales-que {
  font-size: 11px;
  color: var(--muted);
  margin-right: 2px;
}
.petchat-cual {
  padding: 5px 11px;
  border: var(--hairline);
  border-radius: var(--pill-radius);
  background: var(--card-bg);
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 12px;
  cursor: pointer;
  transition: color .18s, border-color .18s;
  /* Un título largo no puede empujar la fila fuera de la pantalla. */
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.petchat-cual:hover { border-color: var(--border-strong); }
/* El elegido, con el oro del tema: es el que se está mandando. */
.petchat-cual.on { border-color: var(--gold); color: var(--gold); }


/* ── EL RECORDATORIO DE LECTURA  ·  historia #69 ──────────────
   Tres formas de elegir en la misma hoja —una opción ancha, una
   cuadrícula de horas y una fila de días— y las tres tienen que
   distinguirse de un vistazo sin leer nada. Lo elegido lleva el mismo
   realce dorado en las tres, que es lo que hace que se lean como una
   familia y no como tres controles distintos. */

.hab-opcion {
  display: block; width: 100%; text-align: left;
  padding: 12px 14px; margin-bottom: 10px;
  border: var(--card-border); border-radius: var(--radius);
  background: var(--surface); color: var(--text);
  font: inherit; cursor: pointer;
}
.hab-opcion.elegida {
  border-color: rgb(var(--gold-rgb) / .75);
  background: var(--gold-wash);
}
.hab-opcion-nombre { display: block; font-weight: 600; }
.hab-opcion-sub {
  display: block; margin-top: 3px;
  font-size: 12px; line-height: 1.45; color: var(--muted);
}

/* Las horas: una cuadrícula que se adapta, no una lista de 21 filas. */
.hab-horas {
  display: grid; gap: 6px;
  grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
}
.hab-hora, .hab-dia {
  padding: 9px 0; text-align: center;
  border: var(--card-border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--muted);
  font: inherit; font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.hab-hora.elegida, .hab-dia.elegida {
  border-color: rgb(var(--gold-rgb) / .75);
  background: var(--gold-wash);
  color: var(--text); font-weight: 600;
}

/* «Prefiero otra hora»: un enlace, no un botón. Es la salida del caso
   raro y no puede pesar lo mismo que la opción de fábrica. */
.hab-otra {
  display: block; width: 100%; padding: 4px 0;
  border: 0; background: none; color: var(--muted);
  font: inherit; font-size: 13px; text-align: left;
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer;
}

/* Los días: siete, siempre en una fila, de lunes a domingo. */
.hab-dias { display: grid; gap: 6px; grid-template-columns: repeat(7, 1fr); }

/* Lo que pasaría ahora mismo. En cursiva y apagado: es una observación
   sobre el estado, no una instrucción ni un error. */
.hab-ahora { margin-top: 14px; font-style: italic; }


/* ── EL INTERRUPTOR DE CADA AVISO  ·  historia #95 ────────────
   «Sí» y «No» con el mismo peso obligan a LEER los seis para saber qué
   está encendido, y una lista de ajustes se mira, no se lee. El
   encendido lleva el realce dorado —el mismo de todo lo elegido en esta
   app— y el apagado se queda apagado de verdad. */
.btn-mini.activo {
  border-color: rgb(var(--gold-rgb) / .75);
  background: var(--gold-wash);
  color: var(--text);
  font-weight: 600;
}
