/* Novastra · la zona de usuario (acceso, "Mi Novastra" y las páginas públicas).
 *
 * Se apoya en `landing.css` y en los tokens: la zona privada es el MISMO producto que la
 * portada, y una segunda paleta se nota a los diez segundos. Aquí solo va lo que la landing no
 * tiene, que es lo propio de una aplicación: rejillas de tarjetas, tablas, formularios y la
 * barra de estado del guardado.
 *
 * Sin framework y sin build, igual que el resto del sitio.
 */

/* ------------------------------------------------------------------ estructura */

.zona {
  min-height: 100vh;
}

.zona__main {
  max-width: var(--ancho);
  margin: 0 auto;
  padding: calc(var(--space-2xl) + 40px) var(--gutter) var(--space-2xl);
}

.zona__vista > h1,
.zona__vista > section > h2 {
  font-family: var(--font-display);
}

.zona__vista h1 {
  font-size: var(--text-display-s);
  margin: 0 0 var(--space-2xs);
}

.zona__vista h2 {
  font-size: var(--text-xl);
  margin: var(--space-xl) 0 var(--space-sm);
}

.apagado {
  color: var(--color-dim);
}

.mini {
  font-size: var(--text-xs);
  color: var(--color-dim);
}

/* ------------------------------------------------------------------ tarjetas */

.tarjeta {
  background: var(--color-paper-2);
  border: var(--rule-thin) solid var(--color-rule);
  border-radius: var(--radius-card);
  padding: var(--space-md);
}

.rejilla {
  display: grid;
  gap: var(--space-sm);
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

/* Los números grandes del resumen. Mismo orden de lectura que en la app: etiqueta pequeña
   arriba y la cifra debajo, no al revés. */
.cifra {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cifra__eti {
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.cifra__val {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  line-height: 1.1;
}

/* ------------------------------------------------------------------ listas y tablas */

.lista {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  list-style: none;
  margin: 0;
  padding: 0;
}

.fila {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-2xs) var(--space-xs);
  border-radius: 12px;
  border: var(--rule-thin) solid transparent;
}

.fila:hover {
  border-color: var(--color-rule);
  background: var(--color-paper-3);
}

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

.fila__nom {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La miniatura del ejercicio: la misma foto que en la app, servida desde novastra-media. Si no
   hay, se pinta la inicial, que es exactamente lo que hace la app. */
.mini-foto {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  object-fit: cover;
  background: var(--color-paper-3);
  border: var(--rule-thin) solid var(--color-rule);
  flex: none;
}

.mini-foto--letra {
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  color: var(--color-accent-hi);
}

table.datos {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

table.datos th {
  text-align: left;
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
  font-weight: 500;
  padding: 6px 8px;
}

table.datos td {
  padding: 6px 8px;
  border-top: var(--rule-thin) solid var(--color-rule);
}

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

.eti {
  display: inline-block;
  font-size: var(--text-xs);
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  border: var(--rule-thin) solid var(--color-rule-hi);
  color: var(--color-muted);
}

.eti--acento {
  color: var(--color-accent-hi);
  border-color: var(--color-accent);
}

.eti--senal {
  color: var(--color-signal);
  border-color: var(--color-signal);
}

/* ------------------------------------------------------------------ formularios */

.campo {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: var(--space-sm);
}

.campo > label {
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-muted);
}

input[type="text"],
input[type="number"],
textarea,
select {
  font-family: var(--font-body);
  font-size: var(--text-md);
  color: var(--color-ink);
  background: var(--color-paper);
  border: var(--rule-thin) solid var(--color-rule-hi);
  border-radius: 12px;
  padding: 10px 12px;
  width: 100%;
}

input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

.num {
  width: 82px;
  text-align: center;
}

.boton {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  letter-spacing: 0.06em;
  color: var(--color-accent-ink);
  background: var(--color-accent-deep);
  border: 0;
  border-radius: var(--radius-pill);
  padding: 10px 20px;
  cursor: pointer;
}

.boton:hover { background: var(--color-accent); }

.boton--grande { font-size: var(--text-md); padding: 14px 28px; width: 100%; }

.boton--fantasma {
  background: transparent;
  color: var(--color-ink-2);
  border: var(--rule-thin) solid var(--color-rule-hi);
}

.boton--fantasma:hover { background: var(--color-paper-3); }

.boton--peligro { color: var(--color-ink); background: oklch(45% 0.15 25); }

.boton:disabled { opacity: 0.5; cursor: default; }

.botones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  align-items: center;
}

.enlace--boton {
  font: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  color: inherit;
}

/* ------------------------------------------------------------------ acceso */

.acceso {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--gutter);
}

.acceso__caja {
  max-width: 460px;
  text-align: center;
}

.acceso__caja h1 {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  margin: 0 0 var(--space-xs);
}

.acceso__estado {
  min-height: 1.5em;
  margin: var(--space-sm) 0 0;
  color: var(--color-signal);
  font-size: var(--text-sm);
}

.acceso__pie {
  font-size: var(--text-xs);
  margin-top: var(--space-md);
}

/* ------------------------------------------------------------------ guardado */

/* La barra que aparece abajo cuando hay cambios sin guardar. Fija y siempre visible: en una
   pantalla de edición larga, un botón de guardar que se va con el scroll es un botón que no se
   pulsa. */
.guardado {
  position: fixed;
  left: 50%;
  bottom: var(--space-md);
  transform: translateX(-50%);
  display: flex;
  gap: var(--space-sm);
  align-items: center;
  background: var(--color-paper-3);
  border: var(--rule-thin) solid var(--color-accent);
  border-radius: var(--radius-pill);
  padding: 10px 12px 10px 20px;
  box-shadow: 0 18px 40px oklch(0% 0 0 / 0.45);
  z-index: var(--z-nav);
}

.guardado[hidden] { display: none; }

/* ------------------------------------------------------------------ gráfica */

/* Barras dibujadas con divs: cuatro reglas de CSS frente a una librería de 90 KB para pintar
   doce rectángulos. */
.barras {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 160px;
  padding-top: var(--space-sm);
}

.barra {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 4px;
  height: 100%;
}

.barra__t {
  width: 100%;
  min-height: 2px;
  border-radius: 6px 6px 0 0;
  background: linear-gradient(180deg, var(--color-accent-hi), var(--color-accent));
}

.barra__e {
  font-size: 10px;
  color: var(--color-dim);
  white-space: nowrap;
}

/* ------------------------------------------------------------------ público */

.publica {
  max-width: 760px;
  margin: 0 auto;
  padding: calc(var(--space-2xl) + 40px) var(--gutter) var(--space-2xl);
}

.publica__cta {
  margin-top: var(--space-xl);
  text-align: center;
}

@media (max-width: 640px) {
  .zona__main { padding-top: calc(var(--space-xl) + 56px); }
  .pastilla .enlace { font-size: var(--text-xs); }
}

/* ------------------------------------------------------------------ utilidades
 *
 * Cuatro márgenes y tres retoques. Existen porque la política de seguridad del sitio prohíbe
 * los estilos en línea: sin `unsafe-inline`, un `style="margin-top:…"` no se aplica y el
 * navegador no dice nada. Antes que abrir la política, tres clases.
 */

.mt-2xs { margin-top: var(--space-2xs); }
.mt-sm { margin-top: var(--space-sm); }
.mt-md { margin-top: var(--space-md); }
.mt-lg { margin-top: var(--space-lg); }
.mb-sm { margin-bottom: var(--space-sm); }
.my-md { margin: var(--space-md) 0; }
.m-0 { margin: 0; }
.puntero { cursor: pointer; }
.p-fila { padding: var(--space-2xs) var(--space-xs); }
.centrado { max-width: 720px; margin: 0 auto; }

/* ------------------------------------------------------------------ el gesto
 *
 * Los dos fotogramas del ejercicio, uno encima del otro, alternando. Es la misma idea que en la
 * app (un GIF sin ser un GIF: dos WebP de 24 KB), pero aquí se hace **sin JavaScript**, para que
 * la ficha de un ejercicio siga funcionando en cualquier navegador y se pueda indexar.
 */

.gesto {
  position: relative;
  aspect-ratio: 1.55;
  margin-top: var(--space-md);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--color-paper-3);
  border: var(--rule-thin) solid var(--color-rule);
}

.gesto img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Las fotos son de un gimnasio real y en crudo cantan sobre el fondo oscuro; se apagan un
     poco, igual que en la app, pero solo un poco: lo que se viene a mirar es dónde van los
     codos. */
  filter: saturate(0.55);
}

.gesto img + img {
  animation: gesto 1.7s steps(1, end) infinite;
}

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

/* Quien pide menos movimiento ve el primer fotograma quieto, no un parpadeo más lento. */
@media (prefers-reduced-motion: reduce) {
  .gesto img + img { animation: none; opacity: 0; }
}

.gesto--sin {
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  color: var(--color-accent-hi);
}

/* ------------------------------------------------------------------ la imagen de un programa
 *
 * Si el usuario le puso foto, se ve su foto. Si viene del catálogo, la app lo dibuja con Canvas
 * y aquí no hay Canvas: se pinta una pastilla con el degradado de ESE dibujo (los colores salen
 * del mismo sitio, `datos/arte.json`) y la inicial. No es el dibujo, pero es su color, y dos
 * programas distintos no se confunden.
 */

.arte {
  width: 52px;
  height: 52px;
  border-radius: 16px;
  flex: none;
  object-fit: cover;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  border: var(--rule-thin) solid var(--color-rule);
}

/* ------------------------------------------------------------------ filtros del buscador */

.filtros {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: var(--space-2xs);
}

.chip {
  font-size: var(--text-xs);
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  border: var(--rule-thin) solid var(--color-rule-hi);
  background: transparent;
  color: var(--color-muted);
  cursor: pointer;
}

.chip:hover { border-color: var(--color-accent); }

.chip[aria-pressed="true"] {
  color: var(--color-ink);
  border-color: var(--color-signal);
  background: oklch(82.8% 0.147 183.3 / 0.14);
}

/* El buscador de ejercicios ocupa la pantalla entera: con 907 y dos filas de filtros, una
   ventanita flotante deja ver cuatro resultados. Sustituye a la posición fija de `.guardado`. */
.buscador {
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  transform: none;
  border-radius: 0;
  display: block;
  overflow: auto;
  padding: var(--space-lg);
  background: var(--color-paper);
}

/* La foto de un ejercicio dentro de una fila, cuando lleva a su ficha. */
.mini-enlace {
  display: block;
  flex: none;
  border-radius: 12px;
}

.mini-enlace:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

/* Un programa escrito a mano no tiene dibujo: se enseñan los días a la semana, igual que la app. */
.arte--dias {
  background: var(--color-paper-3);
  color: var(--color-muted);
  font-size: var(--text-lg);
}

/* La biblioteca: 907 nombres. En columnas porque una lista de 907 en una sola fila vertical son
   veinte pantallas de scroll, y aquí se viene a buscar uno concreto. */
.columnas {
  columns: 2 220px;
  column-gap: var(--space-lg);
  list-style: none;
  margin: 0 0 var(--space-lg);
  padding: 0;
  font-size: var(--text-sm);
}

.columnas li {
  break-inside: avoid;
  padding: 3px 0;
}
