/* Lo que comparten todas las secciones de Cartas Astravellers.
 *
 * Aquí vive la base: los colores, la tipografía, los botones, las pestañas,
 * los campos de formulario y los diálogos. Cada sección (catálogo, notas y
 * reglas, Astravellers) añade encima solo lo suyo.
 *
 * Está fuera de las apps a propósito: no es de ninguna. Si estuviera copiado
 * en cada una, cambiar un color sería cambiarlo en tres sitios y que el
 * tercero se olvide. */

/* ------------------------------------------------------------- tipografía
 *
 * La fuente de los títulos va EMPAQUETADA con la app, no traída de Google
 * Fonts: la app funciona sin internet, tiene una Content-Security-Policy que
 * no deja cargar nada de fuera, y así seguirá viéndose igual dentro de dos
 * años. Todas son de licencia libre (OFL, ver `fuentes/OFL.txt`).
 *
 * Para cambiar de fuente, se cambia `--fuente-titulos` ahí abajo. */

@font-face {
  font-family: "Vollkorn";
  src: url("fuentes/Vollkorn.ttf") format("truetype-variations");
  font-weight: 400 900;
  font-display: swap;
}
@font-face {
  font-family: "Alegreya";
  src: url("fuentes/Alegreya.ttf") format("truetype-variations");
  font-weight: 400 900;
  font-display: swap;
}
@font-face {
  font-family: "Cinzel";
  src: url("fuentes/Cinzel.ttf") format("truetype-variations");
  font-weight: 400 900;
  font-display: swap;
}
@font-face {
  font-family: "Marcellus";
  src: url("fuentes/Marcellus.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}

:root {
  /* ↓ La fuente de los títulos. Cambiar aquí la cambia en toda la app. */
  --fuente-titulos: "Vollkorn", Georgia, "Liberation Serif", serif;

  --fondo: #14131a;
  --fondo-panel: #1e1c26;
  --fondo-hueco: #272433;
  --borde: #383345;
  --texto: #ece9f2;
  --texto-suave: #a49fb5;
  --acento: #c9a227;
  --acento-oscuro: #8a6f16;
  --peligro: #c05045;
  --ok: #5aa469;
}

* { box-sizing: border-box; }

/* Cualquier regla `display` propia gana al `hidden` del navegador, así que
   hay que reforzarlo: si no, los pasos ocultos del diálogo se ven igual. */
[hidden] { display: none !important; }

body {
  margin: 0;
  padding: 0 2rem 4rem;
  background: var(--fondo);
  color: var(--texto);
  font-family: "Iosevka", "Cantarell", "Segoe UI", system-ui, sans-serif;
  font-size: 15px;
  line-height: 1.5;
}

h1, h2, h3 { font-family: var(--fuente-titulos); font-weight: 600; }

/* --------------------------------------------- barra de secciones (arriba) */

.barra {
  display: flex;
  gap: .4rem;
  align-items: center;
  margin: 0 -2rem;
  padding: 0 2rem;
  background: var(--fondo-panel);
  border-bottom: 1px solid var(--borde);
}
/* El nombre del juego. Manda sobre las secciones que tiene al lado, así que
   va bastante más grande que ellas —no es un enlace más— y en mayúsculas.
   Aquí es donde iría un logo el día que lo haya. */
.barra .marca {
  font-family: var(--fuente-titulos);
  font-weight: 700;
  font-size: 1.45rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  line-height: 1;
  color: var(--acento);
  margin-right: 1.6rem;
  padding: .55rem 0;
  white-space: nowrap;
}
.barra a {
  padding: .75rem 1rem;
  color: var(--texto-suave);
  text-decoration: none;
  border-bottom: 3px solid transparent;
}
.barra a:hover { color: var(--texto); }
.barra a.activa {
  color: var(--acento);
  border-bottom-color: var(--acento);
  font-weight: 600;
}
/* La versión. `margin-left: auto` la empuja al extremo derecho sin necesidad
   de envolver nada. Va deliberadamente apagada: tiene que poder encontrarse
   cuando se busca, y no verse cuando no. Al pasar el ratón sube a la
   intensidad de un enlace normal, ni siquiera a la del texto. */
.barra .version {
  margin-left: auto;
  padding: .75rem 0;
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--texto-suave);
  opacity: .35;
  cursor: default;
  user-select: all;   /* para poder copiarla de un doble clic al reportar algo */
  transition: opacity .15s ease;
}
.barra .version:hover { opacity: .9; }

/* A la derecha de la versión (R-77): quién ha entrado, «Salir» y el engranaje
   de «Opciones». «Salir» y el engranaje miden lo mismo de alto, `--alto-barra`,
   y el engranaje es un cuadrado de ese lado: se leen como una pareja. */
.barra { --alto-barra: 2.2rem; }
.barra .usuario {
  margin-left: 1rem;
  color: var(--texto-suave);
  white-space: nowrap;
}
.barra .form-salir { margin: 0 0 0 .6rem; }
/* «Salir» con el borde dorado de la casa: el mismo fondo de `.secundario`,
   pero el borde en `--acento`. */
.barra button.salir {
  height: var(--alto-barra);
  padding: 0 .9rem;
  border-color: var(--acento);
}
.barra button.salir:hover:not(:disabled) { border-color: var(--acento); }
/* El engranaje. Pisa lo de `.barra a` (relleno y subrayado de las secciones):
   no es una sección, es un botón. Marcado (en Opciones y en sus claves) va
   dorado, como una sección activa. */
.barra .engranaje {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--alto-barra);
  height: var(--alto-barra);
  margin-left: .4rem;
  padding: 0;
  border: 1px solid var(--borde);
  border-radius: 6px;
  background: var(--fondo-hueco);
  color: var(--texto-suave);
}
.barra .engranaje:hover { color: var(--texto); border-color: var(--acento); }
.barra .engranaje.activa {
  color: var(--acento);
  border-color: var(--acento);
  font-weight: normal;
}

/* ------------------------------------------------- Opciones (/opciones/) */

.apartado-opciones { padding: 1.2rem 0; border-bottom: 1px solid var(--borde); }
.apartado-opciones h2 { margin: 0 0 .8rem; font-size: 1.2rem; color: var(--texto); }
.temas { display: flex; flex-direction: column; gap: .6rem; max-width: 34rem; }
/* La pastilla del tema: ancha, con su muestra de colores a la izquierda. La
   elegida lleva el borde dorado y la palabra «elegido»: no solo el color. */
.pastilla-tema {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .7rem 1rem;
  border: 1px solid var(--borde);
  border-radius: 999px;
  background: var(--fondo-hueco);
  color: var(--texto);
}
.pastilla-tema.elegida { border: 2px solid var(--acento); }
.pastilla-tema .nombre-tema { font-family: var(--fuente-titulos); font-weight: 600; font-size: 1.1rem; }
.pastilla-tema .marca-elegida { margin-left: auto; color: var(--acento); font-size: .85rem; }
/* La muestra pinta las variables de la casa, no copias de sus colores. */
.muestra { display: inline-flex; border: 1px solid var(--borde); border-radius: 999px; overflow: hidden; }
.muestra span { width: 1.3rem; height: 1.3rem; }
.muestra .fondo { background: var(--fondo); }
.muestra .panel { background: var(--fondo-panel); }
.muestra .acento { background: var(--acento); }
.muestra .texto { background: var(--texto); }
/* Un enlace con la cara de un botón básico (el `button` de abajo): sin dorado
   ni subrayado, porque lleva a otra pantalla y no hace nada aquí. */
.acceso-opcion {
  display: inline-block;
  padding: .45rem .9rem;
  border: 1px solid var(--borde);
  border-radius: 6px;
  background: var(--fondo-hueco);
  color: var(--texto);
  text-decoration: none;
}
.acceso-opcion:hover { border-color: var(--acento); }

/* La miga de las pantallas que viven dentro de Opciones. */
.miga { padding: 1rem 0 0; font-size: .9rem; color: var(--texto-suave); }
.miga a { color: var(--acento); }

/* -------------------------------------------------------------- cabecera */

.cabecera {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: 1rem;
  padding: 1.5rem 0 1rem;
  border-bottom: 1px solid var(--borde);
}
.cabecera h1 { margin: 0; font-size: 1.7rem; color: var(--acento); }
.subtitulo { margin: 0; color: var(--texto-suave); }
.acciones-cabecera { display: flex; gap: .6rem; }

/* -------------------------------------------------------------- botones */

button {
  font: inherit;
  padding: .45rem .9rem;
  border: 1px solid var(--borde);
  border-radius: 6px;
  background: var(--fondo-hueco);
  color: var(--texto);
  cursor: pointer;
}
button:hover:not(:disabled) { border-color: var(--acento); }
button:disabled { opacity: .45; cursor: not-allowed; }

/* El foco, en el dorado de la casa y no en el azul cian del navegador, que no
   aparece en ninguna otra parte de esta app y desentonaba en cuanto salía.
   Va aquí y no en el CSS de una sección porque el foco es de toda la app: es
   lo que dice dónde estás si te mueves con el tabulador.

   `:focus-visible` y no `:focus`: así lo dibuja al llegar con el teclado, que
   es cuando hace falta, y no cada vez que se pincha un botón con el ratón.
   3 px en vez de los 2 del navegador —Jovanius lo quería algo más gordo— y
   separado 1 px del borde, para que se lea como un halo alrededor y no como
   un engrosamiento del propio borde. */
:focus-visible {
  outline: 3px solid var(--acento);
  outline-offset: 1px;
}
button.primario { background: var(--acento); border-color: var(--acento); color: #241f05; font-weight: 600; }
button.primario:hover:not(:disabled) { background: #dcb437; }
button.peligro { border-color: var(--peligro); color: #f0b7b1; }
button.peligro:hover { background: var(--peligro); color: #fff; }

/* Interruptores: botones que se quedan pulsados. Sustituyen a las casillas de
   verificación donde lo que se enciende es un filtro o una marca.
   Su comportamiento está en `estatico/interruptor.js`.

   Apagado es el mismo dibujo que `.peligro` pero en el dorado de la casa: el
   borde y el texto teñidos, el fondo hueco. Encendido se rellena de dorado
   macizo, que es el mismo salto que hace `.peligro` al pasar el ratón. Así los
   dos estados se distinguen por RELLENO y no por un matiz de color, que es lo
   que hace que se lea de un vistazo y de lejos. */
/* El dibujo dorado: borde y texto teñidos sobre el fondo hueco. Lo comparten
   los interruptores apagados y el botón del segundo corte cuando hay cartas
   esperando decisión. Está escrito UNA vez porque son el mismo botón visual;
   estaba copiado en el CSS del catálogo, y por eso a aquél se le olvidó el
   hover y parecía que no se podía pulsar. */
button.dorado,
button.interruptor {
  border-color: var(--acento-oscuro);
  color: var(--acento);
}
button.dorado:hover:not(:disabled),
button.interruptor:hover:not(:disabled) {
  border-color: var(--acento);
  background: #2e2919;
}
/* Encendido NO se rellena de dorado macizo: ese es el dibujo de `.primario`,
   y un filtro encendido no puede pesar lo mismo que «Subir carta nueva», que
   es la acción principal de la pantalla. Se rellena de dorado apagado con el
   texto en dorado claro (7,9:1 de contraste), que se distingue del apagado a
   simple vista sin subir de rango. */
button.interruptor[aria-pressed="true"] {
  background: #3d3014;
  border-color: var(--acento);
  color: #e9c85c;
  font-weight: 600;
}
button.interruptor[aria-pressed="true"]:hover:not(:disabled) { background: #4a3a17; }

/* La tercera posición de algunos filtros: en vez de acotar, EXCLUYE. Va en el
   rojo de la casa (`--peligro`, el mismo de «Archivar»), relleno igual que el
   encendido para que los dos pesen lo mismo y solo se diferencien en el matiz:
   lo que separa «filtro puesto» de «filtro quitado» es el relleno, y lo que
   separa acotar de excluir es el color.

   El texto es el `#f0b7b1` que ya usa `.peligro`, no un rojo claro nuevo:
   8,3:1 sobre este fondo, al lado del 7,9:1 del dorado encendido.

   Aun así el color NO es lo único que lo dice: el botón cambia de rótulo
   («Seleccionadas» -> «Sin preselección»), porque un daltónico —o una pantalla
   mal calibrada— no puede distinguir este rojo de aquel dorado. */
button.interruptor[aria-pressed="mixed"] {
  background: #43201c;
  border-color: var(--peligro);
  color: #f0b7b1;
  font-weight: 600;
}
button.interruptor[aria-pressed="mixed"]:hover:not(:disabled) { background: #52281f; }

/* Acción secundaria: ni principal ni peligrosa ni un filtro. Se distingue por
   ser el único botón de la barra que NO es dorado, así se lee de un vistazo
   que hace otra cosa que los de al lado. */
button.secundario {
  background: #332f42;
  border-color: #5b5470;
}
button.secundario:hover:not(:disabled) { background: #3d3850; border-color: var(--texto-suave); }

/* -------------------------------------------------------------- pestañas */

.pestanas {
  display: flex;
  gap: .3rem;
  margin: 1.2rem 0 0;
  border-bottom: 1px solid var(--borde);
  flex-wrap: wrap;
}
.pestanas button {
  border-radius: 6px 6px 0 0;
  border-bottom: none;
  background: transparent;
  color: var(--texto-suave);
}
.pestanas button.activa {
  background: var(--fondo-panel);
  color: var(--acento);
  border-color: var(--borde);
  font-weight: 600;
}

/* --------------------------------------------------- filtros y formularios */

.filtros {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: flex-end;
  padding: 1rem;
  margin-top: -1px;
  background: var(--fondo-panel);
  border: 1px solid var(--borde);
  border-radius: 0 8px 8px 8px;
}
/* `display: contents` hace que los filtros que se generan solos sean hijos
   directos del flex de `.filtros`. Sin esto se apilan en vertical dentro de
   su div en vez de ponerse en línea con los demás. */
.filtros-propios { display: contents; }

.filtros label { display: flex; flex-direction: column; gap: .25rem; font-size: .85rem; color: var(--texto-suave); }
.filtros label.casilla { flex-direction: row; align-items: center; gap: .4rem; }

select, input[type="text"], input[type="number"], input[type="search"], textarea {
  font: inherit;
  padding: .35rem .5rem;
  background: var(--fondo-hueco);
  color: var(--texto);
  border: 1px solid var(--borde);
  border-radius: 5px;
  min-width: 8rem;
}
textarea { resize: vertical; width: 100%; }
input[type="file"] { font-size: .85rem; color: var(--texto-suave); }

.resumen { color: var(--texto-suave); margin: 1rem 0 .5rem; }
.vacio { color: var(--texto-suave); grid-column: 1 / -1; padding: 2rem; text-align: center; }

/* -------------------------------------------------------------- diálogos */

dialog {
  background: var(--fondo-panel);
  color: var(--texto);
  border: 1px solid var(--borde);
  border-radius: 12px;
  padding: 1.5rem;
  max-width: 760px;
  width: 90vw;
}
dialog::backdrop { background: rgba(0, 0, 0, .65); }

/* Un diálogo largo no cabe en pantalla: sin esto, los campos de abajo se
   salen y no hay forma de llegar a ellos. El `[open]` es imprescindible: sin
   él, `display:flex` mostraría también los diálogos cerrados. */
dialog[open] {
  display: flex;
  flex-direction: column;
  max-height: 88vh;
}
/* El formulario sigue siendo un bloque normal —convertirlo en flex le rompe
   el ancho a las rejillas de campos—; solo se le da scroll propio.

   El hueco va a los DOS lados, y no solo a la derecha como estaba. Dar scroll
   en un eje hace que el navegador recorte también el otro, así que el halo de
   foco de un campo pegado al borde izquierdo se cortaba por la mitad —se veía
   en las casillas del glosario—. El halo mide 4 px (3 de grosor y 1 de
   separación) y aquí hay 6,4, que le dejan sitio de sobra. */
dialog[open] > form {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding-inline: .4rem;
}
/* El pie con los botones se queda siempre a la vista. */
/* El pie se queda pegado abajo mientras el formulario hace scroll.

   El hueco de abajo NO es simetría: sin él, los botones llegan justo al borde
   del área con scroll, que casi nunca cae en un píxel entero. Ese último píxel
   se pinta a medias y deja asomar una raya entrecortada —el borde dorado de un
   botón, el rojo de «Borrar»— que parece que el pie es transparente. Con el
   hueco, ahí abajo solo hay fondo, y da igual dónde caiga el corte. */
dialog[open] > form > .pie-dialogo {
  position: sticky;
  bottom: 0;
  background: var(--fondo-panel);
  padding-top: .8rem;
  padding-bottom: .8rem;
  border-top: 1px solid var(--borde);
}
dialog h2 { margin-top: 0; color: var(--acento); }

.paso { display: flex; flex-direction: column; gap: .8rem; }
.paso + .paso { margin-top: 1.2rem; border-top: 1px solid var(--borde); padding-top: 1.2rem; }

.rejilla-campos {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: .7rem;
}
.rejilla-campos label, label.ancho {
  display: flex; flex-direction: column; gap: .25rem;
  font-size: .85rem; color: var(--texto-suave);
}
label.ancho { margin-top: .7rem; }
.rejilla-campos input { min-width: 0; }

.pie-dialogo { display: flex; gap: .6rem; margin-top: 1.2rem; align-items: center; }
.pie-dialogo .separador { flex: 1; }

/* -------------------------------------------------------------- mensajes */

.nota { color: var(--texto-suave); font-size: .85rem; margin: 0; }
.aviso {
  background: rgba(201, 162, 39, .12);
  border-left: 3px solid var(--acento);
  padding: .6rem .8rem;
  border-radius: 4px;
  margin: 0;
  font-size: .88rem;
}
.aviso.duplicado { border-left-color: var(--peligro); background: rgba(192, 80, 69, .14); }
.error {
  color: #f0b7b1;
  background: rgba(192, 80, 69, .14);
  border-left: 3px solid var(--peligro);
  padding: .6rem .8rem;
  border-radius: 4px;
  margin: .8rem 0 0;
}

/* -------------------------------------------------------------- etiquetas */

.etiquetas { margin: 0 0 .4rem; display: flex; gap: .3rem; flex-wrap: wrap; }
.etiqueta {
  font-size: .72rem;
  padding: .1rem .45rem;
  border-radius: 999px;
  background: rgba(201, 162, 39, .18);
  border: 1px solid var(--acento-oscuro);
  color: var(--acento);
}

/* ------------------------------------------- la galería de artes y el visor */
/* Lo usan las dos secciones, por eso vive aquí y no en el CSS de ninguna. */

.tira-artes {
  display: flex;
  align-items: center;
  gap: .4rem;
}
/* El hueco manda sobre la imagen, y no al revés.
   Sin alto fijo, el marco se ajustaba al alto de cada arte y pasar de uno a
   otro daba un salto que movía todo lo que hay debajo en la ficha. Con el alto
   fijo, cambiar de arte no mueve ni un píxel del resto.
   `clamp` lo hace responsive: crece con la ventana pero entre topes, para que
   ni desaparezca en una pantalla pequeña ni se coma la ficha en una grande. */
.hueco-arte {
  flex: 1;
  min-width: 0;
  height: clamp(7rem, 17vh, 11rem);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--fondo-hueco);
  border: 1px solid var(--borde);
  border-radius: 8px;
  padding: .3rem;
}
/* Pequeñas a propósito: la ficha es para leer los datos, y el arte se mira a
   lo grande en el visor. `contain` la encaja entera dentro del hueco sea cual
   sea su proporción, sin recortarla ni deformarla. */
.miniatura-arte {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 6px;
  cursor: zoom-in;
  display: block;
}
.flecha-arte {
  padding: .1rem .45rem;
  font-size: 1.1rem;
  line-height: 1;
  flex: none;
}
.pie-artes {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-top: .35rem;
  flex-wrap: wrap;
}
/* Pequeño como estaba, pero en los rojos de «Archivar carta»: es la única
   acción de esta columna que destruye algo, y quitar un arte SÍ borra el
   fichero. El color lo pone `.peligro`, compartido; aquí solo va el tamaño.
   `margin-left: auto` lo empuja al otro extremo del pie: la cuenta a la
   izquierda y lo que se puede pulsar a la derecha, lejos de las flechas. */
.quitar-arte {
  font-size: .78rem;
  padding: .15rem .5rem;
  margin-left: auto;
}
/* Sin artes todavía: centrado bajo su título, pegado a él —dicen lo mismo— y
   despegado del botón, que es lo único que ahí se puede pulsar.

   El margen de arriba es NEGATIVO porque este párrafo vive dentro del hueco de
   la galería, y su margen se junta con el que el rótulo deja debajo: sin
   restar, el de arriba manda y el texto no sube. Bajar el margen del rótulo no
   valdría, porque ese mismo hueco lo quiere la tira de artes cuando sí las
   hay. Lo de abajo se queda como está: la distancia al botón ya era la buena,
   y como el párrafo y el botón bajan juntos, subir esto no la toca. */
.sin-artes {
  text-align: center;
  margin: -.25rem 0 .9rem;
}

img.ampliable { cursor: zoom-in; }

/* El visor va por encima de TODO, diálogos incluidos: un <dialog> modal se
   pinta en la capa superior del navegador, así que sin esto la imagen grande
   se quedaría por debajo de la ficha desde la que se abre. */
dialog.visor-imagen {
  /* Anula el aspecto de diálogo normal: aquí manda la imagen. */
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 2rem;
  max-width: 100vw;
  width: 100vw;
  max-height: 100vh;
  height: 100vh;
  cursor: zoom-out;
}
dialog.visor-imagen[open] {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .8rem;
}
dialog.visor-imagen::backdrop { background: rgba(0, 0, 0, .88); }
.visor-lienzo {
  max-width: 92vw;
  max-height: 82vh;
  border-radius: 10px;
  cursor: default;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .6);
}
.visor-pie { color: var(--texto-suave); margin: 0; cursor: default; }
.visor-cerrar {
  position: absolute;
  top: 1rem;
  right: 1.2rem;
  font-size: 1.2rem;
  line-height: 1;
  padding: .25rem .6rem;
}
/* Mientras el visor está abierto, la página de detrás no hace scroll. */
body.con-visor { overflow: hidden; }
