/* ============================================================
   unky.app · portada y categorías

   Dos niveles con dos formas distintas a propósito: las categorías
   son fichas que fluyen en línea y las trivias son tarjetas rellenas
   con galón. Si las dos usaran la misma forma —y lo hicieron dos
   veces— no se distingue en qué nivel estás.
   ============================================================ */

/* --- Campo de código ------------------------------------------------
   Cinco casillas, una por carácter. Debajo hay un solo <input> real,
   invisible y del tamaño de toda la fila: así pegar el código funciona,
   el teclado del teléfono se comporta y el lector de pantalla oye un único
   campo. Las casillas solo pintan.
   -------------------------------------------------------------------- */

/* Lo único que la portada grita. Antes el campo era el único elemento sin
   etiqueta, y las categorías sí tenían la suya. */
.code__label {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 28px;
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--brand);
  margin-top: 22px;
}

.code {
  position: relative;
  margin-top: 12px;
}

.code__row {
  display: flex;
  gap: 10px;
}

.code__box {
  flex: 1;
  height: 68px;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 28px;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  transition: background 0.15s, border-color 0.15s;
}

/* Ya escrita */
.code__box.is-filled {
  border-color: var(--line-2);
}

/* La que recibe el próximo carácter. Solo mientras el campo tiene el
   foco: es también el indicador de foco, porque el <input> es invisible. */
.code.is-focus .code__box.is-next {
  background: #1E1436;
  border: 2px solid var(--brand);
  box-shadow: 0 0 0 4px rgba(255, 197, 61, 0.14);
}

.code.is-focus .code__box.is-next::after {
  content: "";
  width: 2px;
  height: 30px;
  background: var(--brand);
  border-radius: 2px;
  animation: caret 1.1s steps(1) infinite;
}

@keyframes caret {
  0%, 50%   { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}

/* Código completo y encontrado: se va a buscar el video */
.code.is-done .code__box {
  background: var(--surface-2);
  border-color: var(--line-2);
}

/* Código completo que no existe */
.code.is-error .code__box {
  background: #2C1733;
  border-color: var(--no);
}

.code__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: 16px; /* menos de 16px hace que iOS acerque la página */
  cursor: pointer;
}

/* El alto está reservado porque la nota cambia de una línea a dos al fallar
   el código. Sin esto, todo lo que hay debajo salta en el momento exacto en
   que la persona está mirando el campo. */
.code__note {
  color: var(--dim);
  font-size: 13px;
  line-height: 1.45;
  margin-top: 10px;
  padding: 0 2px;
  min-height: 38px;
}

.code__note.is-error {
  color: var(--no);
}

/* Encabezado de sección. Sustituye a .feed-label, que solo servía a una. */
.rail {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 26px;
  padding: 0 2px;
}

/* --- Nuevas -----------------------------------------------------------
   Misma anatomía que la tarjeta de dentro de una categoría —superficie,
   borde, galón— pero apretada, porque aquí convive con el campo de código
   y no puede pesar lo mismo: 20 px de relleno bajan a 13/16 y el título de
   24 a 19. Lleva encima el nombre de su categoría, que es lo único que la
   lista de la portada necesita y la de dentro no, porque aquí se mezclan.
   ---------------------------------------------------------------------- */

.news {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 8px;
}

.news__item {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 13px 16px 14px;
  color: var(--text);
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}

.news__item:hover {
  background: var(--surface-2);
  border-color: var(--line-2);
}

.news__item:active {
  transform: scale(0.99);
}

.news__item:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
}

.news__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* Era texto de color; ahora es icono + texto en --dim. Lo que identifica es
   la silueta, no el tono. */
.news__cat {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--dim);
}

.news__title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 19px;
  line-height: 1.08;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.news__meta {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}

/* Fichas, no casillas en rejilla.

   Hubo antes una rejilla de casillas y se quitó: tenía la misma superficie,
   el mismo borde y el mismo radio que la tarjeta de trivia —los mismos tres
   valores— así que la portada se leía como una sola lista larga de cosas
   tocables. Cambiar la orientación no bastaba: dos listas seguidas hechas del
   mismo material se funden. Hacía falta cambiar la silueta.

   La pastilla que fluye en línea no se puede confundir con una tarjeta, y de
   paso pesa mucho menos en vertical: a ocho categorías son tres renglones.
   Es coherente con lo que son: la trivia es la cosa que se juega, la
   categoría solo el camino para llegar. */
.cats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

/* --- Trivias: la lista ------------------------------------------------ */

/* Lista de verdad: el build la escribe como <ul>/<li>. Un lector de pantalla
   anuncia "lista de 25 elementos" y permite saltarla entera; con divs no
   dice nada, y a 25 trivias eso es la diferencia entre navegar y no. */
.trivias {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 20px;
}

/* Apretada respecto a lo que era (20 px de relleno y 24 de título): una
   categoría puede tener 25 trivias, y esos pocos píxeles por tarjeta son una
   pantalla entera de diferencia al final de la lista. */
.trivia {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 16px 17px 17px;
  color: var(--text);
  text-decoration: none;
  transition: 0.15s;
}

.trivia:hover {
  background: var(--surface-2);
  border-color: var(--line-2);
}

.trivia:active {
  transform: scale(0.99);
}

.trivia:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
}

.trivia__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* baseline y no center: con un título de dos líneas —"Capitales que no son
   la ciudad más grande"— centrado dejaba la etiqueta "Nueva" flotando en
   mitad del bloque en vez de junto a la primera línea. */
.trivia__head {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

/* min-width sin flex-grow: el título se encoge y parte en dos líneas cuando
   hace falta, pero no se estira. Con flex:1 la etiqueta salía disparada al
   borde derecho de la tarjeta y dejaba de leerse como parte del título. */
.trivia__title {
  min-width: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 20px;
  line-height: 1.06;
  letter-spacing: -0.03em;
  text-wrap: pretty;
}

/* "Nueva" sale de la fecha de publicación, no de nada guardado en el
   navegador: es un hecho del contenido, no un estado del usuario. Con 25
   trivias en una categoría es lo único que dice cuál corresponde al video
   que se acaba de ver. */
.tag {
  flex: 0 0 auto;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand);
  border: 1px solid color-mix(in srgb, var(--brand) 42%, transparent);
  border-radius: var(--r-pill);
  padding: 2px 8px 3px;
}

.trivia__meta {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}

/* El galón es la única señal de que la tarjeta se toca. En --line-2 daba
   1,97:1 contra la superficie de la tarjeta, por debajo del 3:1 que pide un
   elemento de interfaz; --line-2 además es un token de borde, no de figura.
   En --dim son 3,85:1. */
.chev {
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
  color: var(--dim);
}

/* --- Cabecera de categoría -------------------------------------------- */

.cat-head {
  margin-top: 22px;
}

/* El icono es el mismo con el que se eligió la categoría en la portada: es
   el hilo entre las dos pantallas. Antes ese papel lo hacía el color. */
.cat-head__top {
  display: flex;
  align-items: center;
  gap: 13px;
}

.cat-head__name {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 34px;
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

/* Ya existía en categories.json y solo viajaba en la meta description. Aquí
   dice de qué va la categoría justo antes de la lista. */
.cat-head__desc {
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.45;
  margin-top: 8px;
  max-width: 32ch;
}

/* "25 trivias · 3 nuevas": contesta sin scrollear la pregunta del que vuelve,
   ¿hay algo para mí aquí? El build no escribe el recuento de nuevas cuando es
   cero, ni la línea entera cuando la categoría está vacía. */
.cat-head__count {
  color: var(--dim);
  font-size: 12.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  margin-top: 10px;
}

.cat-head__count:empty {
  display: none;
}

.cat-head__count b {
  color: var(--brand);
  font-weight: 600;
}

/* --- Barra fija de categoría ------------------------------------------
   Misma forma que la barra del código de la portada —mismo vidrio, mismo
   alto, mismo interior de --shell-max— porque hacen el mismo trabajo:
   devolver, al scrollear, lo que la cabecera dejó de decir. Aquí eso es de
   qué categoría es la lista y cómo se sale.
   ---------------------------------------------------------------------- */

.cat-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  backdrop-filter: blur(16px) saturate(1.4);
  border-bottom: 1px solid var(--line);
  opacity: 0;
  transform: translateY(-10px);
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}

.cat-bar.is-on {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.cat-bar__inner {
  display: flex;
  align-items: center;
  height: 58px;
  padding: 0 var(--pad-x);
  max-width: var(--shell-max);
  margin-inline: auto;
}

.cat-bar__back {
  display: flex;
  align-items: center;
  gap: 9px;
  height: 44px;
  padding: 0 10px 0 6px;
  border-radius: var(--r-pill);
  text-decoration: none;
  color: var(--text);
}

.cat-bar__back:hover {
  background: color-mix(in srgb, var(--text) 8%, transparent);
}

.cat-bar__back:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.cat-bar__arrow {
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
  color: var(--muted);
}

.cat-bar__name {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -0.035em;
}

/* --- Barra del código -------------------------------------------------
   La portada tiene una sola acción real: escribir cinco caracteres. Con la
   sección de nuevas y ocho categorías, esa acción se va de pantalla al
   primer scroll. La barra la devuelve sin repetir la interfaz: cinco
   casillas mínimas que reflejan lo ya escrito y, al tocarlas, suben al campo
   de verdad y le dan el foco.

   Va fija al viewport y no pegajosa dentro de .screen, porque .screen ya es
   fixed inset:0 con su propio scroll. El interior repite --shell-max para
   que en pantalla ancha quede alineada con la columna.
   ---------------------------------------------------------------------- */

.code-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  backdrop-filter: blur(16px) saturate(1.4);
  border-bottom: 1px solid var(--line);
  opacity: 0;
  transform: translateY(-10px);
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}

.code-bar.is-on {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.code-bar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 58px;
  padding: 0 var(--pad-x);
  max-width: var(--shell-max);
  margin-inline: auto;
}

.code-bar__brand {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 17px;
  letter-spacing: -0.04em;
  color: var(--text);
}

.code-bar__brand span {
  color: var(--brand);
}

/* 44 px de alto aunque las casillas midan 30: es el objetivo mínimo. */
.code-bar__jump {
  display: flex;
  align-items: center;
  gap: 9px;
  height: 44px;
  padding: 0 4px 0 12px;
  border: 0;
  background: none;
  border-radius: var(--r-pill);
  cursor: pointer;
  font: inherit;
}

.code-bar__jump:hover {
  background: color-mix(in srgb, var(--brand) 10%, transparent);
}

.code-bar__jump:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.code-bar__label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--brand);
}

.code-bar__boxes {
  display: flex;
  gap: 4px;
}

.code-bar__box {
  width: 21px;
  height: 30px;
  border-radius: 6px;
  background: var(--surface);
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.code-bar__box.is-filled {
  border-color: var(--brand);
  color: var(--brand);
}

/* --- Vacío y pie ------------------------------------------------------- */

/* --- Categoría sin trivias ---------------------------------------------
   Antes era una línea gris centrada, ".feed-empty", que no decía de qué
   categoría hablaba, qué iba a pasar después ni cómo salir: un callejón.
   Ahora nombra la categoría, dice qué ocurre y deja una sola acción, que en
   esta pantalla es siempre la misma: volver. La cabecera se queda arriba —
   saber dónde estás importa más cuando no hay nada que mirar.
   ---------------------------------------------------------------------- */

.empty {
  margin-top: 30px;
  padding: 30px 22px 32px;
  border-radius: var(--r-lg);
  border: 1px dashed var(--line-2);
  background: color-mix(in srgb, var(--surface) 55%, transparent);
}

.empty__title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 21px;
  line-height: 1.1;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.empty__note {
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.45;
  margin-top: 9px;
  max-width: 30ch;
  text-wrap: pretty;
}

.empty + .btn {
  margin-top: 22px;
}

