/* ============================================================
   Panel de administración.

   Mismo idioma visual que el resto del sitio —noche, oro y relieve— pero sin
   fieltro: acá no se juega.

   IMPORTA css/tema.css en vez de repetir la paleta. Antes definía su propio
   `--oro: #fbbf24`, que NO es el `#d4a843` del sitio: eran dos dorados
   distintos conviviendo, y esa clase de diferencia se nota aunque nadie sepa
   señalar por qué. Ahora hay uno solo, y las piezas (--filo-oro, --relieve-oro,
   --halo-oro) salen de ahí.
   ============================================================ */

@import url("../css/tema.css");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  min-height: 100dvh;
  padding: 16px;
  font-family: "Inter", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  color: var(--texto);
  background:
    radial-gradient(ellipse 80% 50% at 50% 0%, rgba(212, 168, 67, 0.08), transparent 70%),
    var(--negro);
}

/* --------------------------------------------------------- cabecera */

.barra {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: 1100px;
  margin: 0 auto 22px;
  padding: 14px 18px;
  border-radius: 16px;
  background: var(--panel);
  border: 1px solid var(--borde);
  box-shadow: var(--sombra-negra);
}

.barra .marca {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  object-fit: cover;
  flex: 0 0 auto;
}

.barra h1 {
  font-family: "Playfair Display", Georgia, serif;
  font-size: 1.15rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--oro);
}

.barra .lema {
  font-size: 0.76rem;
  color: var(--texto-tenue);
}

.barra > button {
  margin-left: auto;
}

/* El `hidden` tiene que esconder, pase lo que pase.

   El atributo `hidden` no es más que un `display: none` de la hoja del
   navegador, así que CUALQUIER regla de autor con `display` lo anula. Hoy
   `main` no tiene ninguna y el panel se esconde bien —está comprobado—, pero
   basta con que alguien le ponga `display: grid` a `main` un martes para que
   el panel entero quede a la vista de cualquiera que abra esta URL.

   No filtraría datos: las ocho funciones comprueban el correo en el servidor y
   rechazan a todo el mundo. Pero mostraría el mapa de lo que hay del otro
   lado, y eso no hace falta regalarlo. Dos líneas para que no dependa de que
   nadie se equivoque. */
#panel[hidden],
#entrar[hidden] {
  display: none !important;
}

/* ------------------------------------------------------------ cajas */

main {
  max-width: 1100px;
  margin: 0 auto;
}

.tarjeta,
.dato {
  position: relative;
}

/* El filo dorado, como el canto de una carta cara.

   Va en un pseudoelemento con `mask` y no con `border-image` porque
   border-image no respeta el `border-radius`: con esquinas redondeadas deja
   los cantos cuadrados. Esto pinta el degradado y recorta el centro, así que
   queda un anillo de un píxel que sí sigue la curva. */
.tarjeta::before,
.dato::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: var(--filo-oro);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0.5;
  pointer-events: none;
}

.tarjeta {
  padding: 24px;
  border-radius: 16px;
  background: var(--panel);
  border: 1px solid var(--borde-suave);
  box-shadow: var(--sombra-negra);
}

.angosta {
  max-width: 400px;
  margin: 8vh auto 0;
}

h2 {
  font-family: "Playfair Display", Georgia, serif;
  font-size: 0.82rem;
  letter-spacing: 2.4px;
  text-transform: uppercase;
  color: var(--oro);
  margin: 28px 0 12px;
}

.angosta h2 {
  margin-top: 0;
}

.nota {
  margin: 0 0 14px;
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--texto-tenue);
}

/* ----------------------------------------------------------- entrar */

form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 16px;
}

label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.78rem;
  color: var(--texto-tenue);
}

/* El estilo base de input y select vive en tema.css, con selector de elemento:
   cualquier campo que aparezca mañana nace oscuro. Sin `color-scheme: dark`,
   el navegador dibuja el desplegable con el tema del SISTEMA, y en Windows eso
   es un panel blanco con texto claro encima. */
input,
select {
  width: 100%;
}

/* ---------------------------------------------------------- botones */

.btn {
  padding: 12px 20px;
  border: none;
  border-radius: 11px;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  font-family: inherit;
  cursor: pointer;
  color: #1a1206;
  background: linear-gradient(180deg, var(--oro-claro), var(--oro) 55%, var(--oro-hondo));
  /* El relieve es lo que lo hace parecer una gema y no un rectángulo pintado. */
  box-shadow: var(--relieve-oro), 0 5px 16px rgba(0, 0, 0, 0.45);
  transition: filter 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}

.btn:hover:not(:disabled) {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

/* Al presionar se hunde: el relieve se invierte. */
.btn:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: var(--relieve-hueco);
}

.btn:disabled {
  opacity: 0.45;
  cursor: progress;
  transform: none;
  filter: grayscale(0.5);
}

.btn.sobrio {
  color: #16110a;
  background: linear-gradient(180deg, var(--plata-clara), var(--plata) 60%, var(--plata-honda));
}

.btn.peligro {
  color: #fff;
  background: linear-gradient(180deg, #e05a4a, var(--rojo) 55%, #8e2a1e);
}

.btn.chico {
  padding: 8px 13px;
  font-size: 0.68rem;
}

/* ---------------------------------------------------------- totales */

.totales {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px;
}

.dato {
  padding: 18px 20px;
  border-radius: 14px;
  background: var(--panel);
  border: 1px solid var(--borde-suave);
  box-shadow: var(--sombra-negra);
}

.dato b {
  display: block;
  font-family: "Playfair Display", Georgia, serif;
  font-size: 1.9rem;
  font-variant-numeric: tabular-nums;
}

.dato span {
  font-size: 0.68rem;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--texto-tenue);
}

.dato.acento b {
  color: var(--oro);
  text-shadow: 0 2px 16px rgba(212, 168, 67, 0.35);
}

.acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 16px;
}

/* ------------------------------------------------------------ lista */

.lista {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  padding: 14px 16px;
  border-radius: 13px;
  background: var(--panel);
  border: 1px solid var(--borde-suave);
  transition: background 0.18s ease, border-color 0.18s ease;
}

.fila:hover {
  background: var(--panel-alto);
  border-color: var(--borde);
}

.fila .codigo {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  color: var(--oro-claro);
  min-width: 84px;
}

.fila .campo {
  font-size: 0.82rem;
  color: var(--texto-tenue);
  /* Sin esto, un nombre largo empuja al botón fuera de la fila: un hijo de
     flex no baja de su contenido salvo que se le diga. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fila .campo b {
  color: var(--texto);
  font-weight: 600;
}

/* Un artículo apagado sigue en la lista —es el que se va a querer volver a
   encender— pero se ve que no está a la venta sin tener que leer la etiqueta. */
.fila.apagada {
  opacity: 0.55;
  border-style: dashed;
}

/* ------------------------------------------- el formulario del catálogo */

.campos-item {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px 16px;
  margin: 16px 0;
}

.campos-item label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.78rem;
  color: var(--texto-tenue);
}

/* La descripción y la imagen ocupan la fila entera: son las dos que llevan
   texto largo, y en una columna angosta no se ve lo que uno escribió. */
.campos-item label.ancho {
  grid-column: 1 / -1;
}

.campos-item label.casilla {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  align-self: end;
  padding-bottom: 10px;
}

/* La casilla no es un campo de texto: no tiene que estirarse a lo ancho de su
   columna ni empujar su etiqueta a dos renglones. */
.campos-item label.casilla input {
  width: 18px;
  height: 18px;
  min-height: 0;
  flex: none;
  accent-color: var(--oro);
}

.campos-item label.casilla span {
  white-space: nowrap;
}

.campos-item input[type="text"],
.campos-item input[type="number"],
.campos-item select {
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--borde-suave);
  background: var(--panel);
  color: var(--texto);
  font-size: 0.9rem;
  /* Alto de dedo: el panel también se abre desde el teléfono. */
  min-height: 42px;
}

.campos-item input:focus-visible,
.campos-item select:focus-visible {
  outline: 2px solid var(--oro);
  outline-offset: 1px;
}

/* Al editar, el id se bloquea: cambiarlo no sería editar sino crear otro
   artículo y dejar huérfana a la gente que compró el viejo. */
.campos-item input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.campos-item code {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 0.74rem;
  color: var(--oro-claro);
}

/* Un nombre sospechoso se muestra como texto dentro de un `code`: se lee que
   es un dato y no parte de la interfaz. El escapado lo hace el JS. */
.fila .campo code {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 0.8rem;
  padding: 2px 6px;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.45);
  color: var(--plata-clara);
  word-break: break-all;
}

.fila > :last-child {
  margin-left: auto;
}

.etiqueta {
  padding: 3px 11px;
  border-radius: 999px;
  font-size: 0.64rem;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  border: 1px solid currentColor;
  white-space: nowrap;
}

.etiqueta.esperando { color: var(--oro); }
.etiqueta.jugando { color: var(--verde); }
.etiqueta.alerta { color: #ff8a7a; }

.vacio {
  padding: 22px;
  text-align: center;
  color: var(--texto-tenue);
  font-size: 0.88rem;
}

/* ------------------------------------------------------------ aviso */

.aviso {
  min-height: 1.4em;
  margin-top: 14px;
  font-size: 0.86rem;
  color: var(--texto-tenue);
}

.aviso.mal { color: #fca5a5; }
.aviso.bien { color: #86efac; }

/* ------------------------------------------------------------ móvil

   Medido antes de escribir esto: el botón "Salir" se salía 8 px a 360 px y
   24 px a 344, con scroll horizontal en toda la página. A 375 px todavía
   entraba, que es el ancho con el que uno prueba por reflejo. Por eso el corte
   va holgado en 560 y no justo en el borde donde se rompe. */

@media (max-width: 560px) {
  .barra {
    flex-wrap: wrap;
    height: auto;
    gap: 10px;
    padding: 12px 14px;
  }

  /* Sin `margin-left: auto` deja de empujarse contra el borde derecho, y con
     `width: 100%` se lleva su propia línea entera. */
  .barra > button {
    margin-left: 0;
    width: 100%;
    text-align: center;
  }

  /* El correo puede ser largo y es lo que empujaba al botón. Que se corte con
     puntos suspensivos en vez de estirar la cabecera. */
  .barra > div {
    min-width: 0;
    flex: 1 1 auto;
  }

  .barra .lema {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .fila > :last-child {
    margin-left: 0;
    width: 100%;
  }

  .fila .codigo {
    min-width: 0;
  }

  .acciones .btn {
    flex: 1 1 auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .btn,
  .fila {
    transition: none;
  }

  .btn:hover:not(:disabled) {
    transform: none;
  }
}

/* ------------------------------------------------------------- reportes

   La fila de un reporte lleva más cosas que las demás —dos personas, motivo,
   fecha, sala y un comentario libre— así que se deja envolver en vez de
   forzarla en una línea. En una pantalla angosta, una fila que no envuelve
   es una fila que se sale. */

#listaReportes .fila {
  flex-wrap: wrap;
}

/* El comentario lo escribió alguien enojado en medio de una partida. Puede
   ser largo y puede venir en una sola palabra kilométrica, así que se le
   permite partirse por donde sea antes que romper la caja. */
.campo.comentario {
  flex-basis: 100%;
  color: var(--texto-tenue);
  font-style: italic;
  overflow-wrap: anywhere;
}

/* El uid: hace falta para buscar la cuenta, pero no es lo que se lee. */
.campo.tenue {
  color: var(--texto-tenue);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78rem;
  opacity: 0.7;
}

.filtro-reportes select {
  padding: 8px 12px;
  border-radius: 8px;
}

/* Visible para un lector de pantalla, invisible para el resto. No usa
   `display: none` porque eso también lo esconde del lector. */
.oculto-visual {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* El separador entre los dos modos de entrar. Dos rayas y una palabra: deja
   claro que son alternativas y no pasos de un mismo formulario. */
.separador {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 16px 0;
  color: var(--texto-tenue);
  font-size: 0.8rem;
}

.separador::before,
.separador::after {
  content: "";
  flex: 1;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

/* El botón de Google ocupa el ancho: es el camino recomendado y tiene que
   verse como tal al lado de un formulario de dos campos. */
#btnGoogle {
  width: 100%;
}


/* El campo del correo del nuevo administrador. Se lleva el espacio que sobra
   en la fila: un correo entero no entra en un campo del ancho de un botón. */
.campo-admin {
  flex: 1 1 240px;
  min-width: 0;
}

.campo-admin input {
  width: 100%;
  padding: 9px 12px;
  border-radius: 8px;
}

/* La fila de un administrador lleva correo, fechas y quién lo agregó: se deja
   envolver antes que salirse en una pantalla angosta. */
#listaAdmins .fila {
  flex-wrap: wrap;
}

/* Un botón apagado tiene que verse apagado. Los dos casos son legítimos —el
   raíz y uno mismo— y el motivo está en el `title`. */
#listaAdmins .btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ============================================================
   Quién tiene un artículo
   ============================================================

   Se despliega DEBAJO de la fila del artículo, no en una ventana: lo que se
   decide acá es si sacárselo a alguien, y esa decisión se toma mirando el
   artículo. Una ventana modal taparía justamente eso.

   El borde de la izquierda es lo que dice de quién cuelga la lista: sin él,
   con varios artículos abiertos a la vez, no se sabe cuál es de cuál. */
.poseedores {
  margin: -4px 0 10px 26px;
  padding: 12px 14px;
  border-radius: 0 13px 13px 0;
  border-left: 3px solid var(--borde);
  background: var(--panel);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.poseedores .nota { margin: 0; }
.poseedores .nota.mal { color: #fca5a5; }

/* Una fila de persona pesa menos que una de artículo: es una lista de
   consulta dentro de otra lista, y con el mismo peso las dos se confunden. */
.fila.chica {
  padding: 8px 12px;
  gap: 8px 14px;
  font-size: 0.92rem;
}

.fila.chica .campo { font-size: 0.92rem; }

/* ------------------------------------- el catálogo, en dos grupos

   Lo que se vende y lo que se gana, separados. Mezclados, una insignia se
   leía como un producto apagado: la fila decía «apagado» y ofrecía
   «Encender», que en un artículo de venta significa ponerlo a la venta. Un
   administrador nuevo la enciende creyendo que la arregla. */
.grupo-catalogo {
  margin-bottom: 26px;
}

.grupo-catalogo h3 {
  margin: 0 0 4px;
  font-size: 1rem;
  letter-spacing: 0.5px;
}

/* El grupo que no se vende va marcado con una guía al costado. No es un
   aviso rojo: no hay nada que arreglar, es otra clase de cosa. */
.grupo-catalogo.no-vendible {
  padding-left: 14px;
  border-left: 2px solid rgba(212, 168, 67, 0.35);
}

.grupo-catalogo .titulo-tipo {
  margin: 16px 0 6px;
  font-size: 0.76rem;
  text-transform: uppercase;
  letter-spacing: 1.4px;
  color: var(--oro, #d4a843);
}

.grupo-catalogo .cuenta {
  color: var(--texto-tenue, #9aa0aa);
  font-weight: 400;
}

/* El aviso de debajo del precio, cuando el tipo no se vende. */
/* El `display` va con su excepción: una regla de autor con `display`
   anula el `[hidden]` de la hoja del navegador, y el aviso quedaba visible
   con el atributo puesto. Es el mismo tropiezo que ya documenta
   `admin-puerta.spec.js`. */
.nota-campo[hidden] {
  display: none;
}

.nota-campo {
  display: block;
  margin-top: 6px;
  font-size: 0.75rem;
  color: var(--oro-claro, #fcf0c4);
}
