/* Componentes de página (UI-003).

   Se carga entre layout.css y site.css. Es el vocabulario que comparten las vistas: encabezado,
   secciones, tablas, estados vacíos, métricas y el shell de las pantallas de sesión.

   Por qué existe este archivo y no se resuelve con utilidades de Bootstrap en cada .cshtml: hasta
   UI-002 cada vista armaba lo mismo de forma distinta (tres variantes de encabezado, dos tamaños de
   valor para la misma métrica, "table table-striped align-middle" copiado en cinco tablas). Con las
   reglas acá, UI-004 toca los breakpoints en un solo lugar.

   Misma regla que layout.css: ni un color literal. Todo sale de los tokens --zw-* de UI-001.

   Estructura:
     1. Encabezado de página y títulos
     2. Toolbar
     3. Tablas
     4. Números
     5. Estados vacíos
     6. Métricas (stat cards)
     7. Formularios
     8. Paginación
     9. Badges
    10. Bloques monoespaciados y QR
    11. Listas de detalle
    12. Shell de las pantallas de sesión
    13. Área táctil en pantallas chicas

   Los breakpoints de UI-004 están junto al componente que modifican y no agrupados al final: la
   excepción es la §13, que es una sola regla transversal a los controles de Bootstrap. */

/* ============================================================================
   1. ENCABEZADO DE PÁGINA Y TÍTULOS
   ============================================================================
   El <h1> de Bootstrap mide 2.5rem, pensado para una landing. Acá compite con el contenido: la
   aplicación es un tablero operativo y el título es una referencia, no el protagonista. */

.zw-page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.zw-page-title {
  margin: 0;
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.3;
}

/* Las acciones de la página (exportar, ir al historial) van a la derecha del título y bajan solas
   cuando no entran. */
.zw-page-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

/* Título de una sección suelta sobre la página. El margen superior es parte del componente: sin él
   cada vista lo resolvía con un mt-4 propio. */
.zw-section-title {
  margin: 1.75rem 0 0.75rem;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.4;
}

/* Título de un bloque dentro de una card (filtros, formulario de alta). Va en label chico y no en
   heading grande: la card ya delimita el bloque, el texto solo lo nombra. */
.zw-panel-title {
  margin: 0 0 1rem;
  color: var(--zw-text-muted);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.4;
  text-transform: uppercase;
}

/* ============================================================================
   2. TOOLBAR
   ============================================================================
   Fila de controles arriba de una tabla: a la izquierda lo que filtra o cambia la vista (el selector
   de moneda de Assets/List), a la derecha lo que actúa sobre el resultado (exportar). */

.zw-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

/* Empuja el bloque a la derecha aunque sea el único hijo del toolbar. */
.zw-toolbar-end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
}

/* Cuando el toolbar se parte en dos líneas ya no hay nada a la izquierda de este bloque, y el
   margin-left:auto lo deja solo contra el borde derecho, desalineado del selector de moneda que le
   quedó arriba. Apilado, alinea a la izquierda como el resto de la página (UI-004). */
@media (max-width: 575.98px) {
  .zw-toolbar-end {
    margin-left: 0;
  }
}

.zw-toolbar-label {
  display: block;
  margin: 0 0 0.375rem;
  color: var(--zw-text-muted);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ============================================================================
   3. TABLAS
   ============================================================================
   .zw-table se usa junto a .table de Bootstrap: hereda de ahí el striping y el hover (cuyos colores
   ya define theme.css) y agrega la densidad y el encabezado. */

/* El wrapper y no .table-responsive de Bootstrap: aquel fuerza overflow siempre, lo que recorta el
   foco de los controles dentro de la tabla incluso cuando entra entera. Acá el scroll aparece solo
   si hace falta.

   Sombra de scroll (UI-004): cuatro gradientes con background-attachment mixto. Los dos primeros son
   "tapas" del color de la superficie ancladas al contenido (local), los dos últimos son la sombra
   anclada al recuadro visible (scroll). Mientras hay contenido por ver de un lado, la tapa de ese
   lado está fuera de cuadro y la sombra queda expuesta; al llegar al extremo, la tapa la cubre. Es
   decir: la sombra aparece exactamente del lado hacia el que todavía se puede desplazar, sin JS y
   sin elementos extra. --zw-bg hace de sombra por ser la superficie más oscura de la paleta.

   El anillo de foco cuando el contenedor es enfocable (ver site.js) lo aporta la regla global
   :focus-visible de theme.css; no hace falta repetirlo acá. */
.zw-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--zw-border);
  border-radius: var(--bs-border-radius);
  background-color: var(--zw-surface);
  background-image:
    linear-gradient(to right, var(--zw-surface), transparent),
    linear-gradient(to left, var(--zw-surface), transparent),
    linear-gradient(to right, var(--zw-bg), transparent),
    linear-gradient(to left, var(--zw-bg), transparent);
  background-position: left center, right center, left center, right center;
  background-repeat: no-repeat;
  background-size: 20px 100%, 20px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}

.zw-table {
  margin-bottom: 0;
  font-size: 0.8125rem;
  vertical-align: middle;
}

/* Los encabezados como label y no como texto: en una tabla densa el nombre de la columna es
   metadato, y en mayúsculas chicas deja de competir con los datos. */
.zw-table > thead > tr > th {
  padding: 0.625rem 0.75rem;
  border-bottom: 1px solid var(--zw-border-md);
  color: var(--zw-text-muted);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.zw-table > tbody > tr > td {
  padding: 0.5625rem 0.75rem;
}

/* La última fila no dibuja su borde: ya lo aporta el borde del wrapper. */
.zw-table > tbody > tr:last-child > td {
  border-bottom: 0;
}

/* En pantalla chica cada píxel de ancho es una columna menos que hay que ir a buscar con scroll: el
   historial de movimientos tiene ocho, y recortando el padding lateral entran casi dos más antes de
   necesitar desplazarse (UI-004). El padding vertical no baja tanto porque define el alto de fila,
   que es lo que se toca con el dedo. */
@media (max-width: 767.98px) {
  .zw-table > thead > tr > th,
  .zw-table > tbody > tr > td {
    padding-right: 0.5rem;
    padding-left: 0.5rem;
  }
}

/* ============================================================================
   4. NÚMEROS
   ============================================================================
   Los dígitos de DM Sans son proporcionales: en una columna de montos el "1" ocupa menos que el "8"
   y las cifras no alinean por posición decimal. tabular-nums las lleva a ancho fijo. */

.zw-num {
  font-variant-numeric: tabular-nums;
}

/* ============================================================================
   5. ESTADOS VACÍOS
   ============================================================================
   El borde punteado marca "acá va a haber algo" sin fingir un contenedor con contenido. */

.zw-empty {
  padding: 1.75rem 1.25rem;
  border: 1px dashed var(--zw-border-md);
  border-radius: var(--bs-border-radius);
  color: var(--zw-text-muted);
  font-size: 0.8125rem;
  text-align: center;
}

.zw-empty p {
  margin-bottom: 0;
}

.zw-empty p + p,
.zw-empty p + a {
  margin-top: 0.5rem;
}

/* Un estado vacío ofrece a lo sumo una acción, y como es lo único accionable del bloque se muestra
   como botón y no como link suelto. */
.zw-empty-action {
  display: inline-block;
  margin-top: 0.75rem;
}

/* ============================================================================
   6. MÉTRICAS
   ============================================================================
   .zw-stat se usa sobre .card: aporta el ritmo interno (label chico, valor grande, nota) que antes
   cada bloque resolvía por su cuenta —de ahí que el dashboard tuviera un h3 en la fila de valores y
   un h4 en la de actividad para métricas del mismo rango. */

.zw-stat {
  height: 100%;
  padding: 1rem 1.125rem;
}

.zw-stat-label {
  margin: 0 0 0.5rem;
  color: var(--zw-text-muted);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.zw-stat-value {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

/* Cuando no hay dato el hueco se llena con texto en el tono secundario, no con el tamaño de un
   valor: "todavía no hay" no es una cifra. */
.zw-stat-value--empty {
  color: var(--zw-text-muted);
  font-size: 0.8125rem;
  font-weight: 400;
  line-height: 1.5;
}

.zw-stat-note {
  margin: 0.625rem 0 0;
  font-size: 0.75rem;
  line-height: 1.4;
}

/* ============================================================================
   7. FORMULARIOS
   ============================================================================ */

/* Pie del formulario. El borde separa los campos de la acción que los envía, que si no queda como
   un control más de la grilla. */
.zw-form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--zw-border);
}

/* En teléfono los campos ocupan el ancho completo y un submit de 90px al pie se lee como un control
   secundario más. Repartido, cierra el formulario con el mismo peso que tiene (UI-004).

   Selector de hijo directo y no descendiente: en ConnectDrive los hijos del bloque son dos <form>
   (reconectar / desconectar) y sus botones no son flex items, así que la regla no los alcanzaría
   igual. Son acciones secundarias y quedan bien con su ancho natural. */
@media (max-width: 575.98px) {
  .zw-form-actions > .btn {
    flex: 1 1 auto;
  }
}

/* Enmascara un textarea multilínea para campos sensibles de tipo LongText (ITEM-007): un
   input[type=password] no admite saltos de línea, así que esto es el equivalente para algo como
   "Recovery codes". vault-item-form.js la agrega/quita al togglear la visibilidad. Degrada a texto
   visible en navegadores sin soporte para -webkit-text-security (Firefox); el botón de
   mostrar/ocultar sigue funcionando igual. */
.zw-masked {
  -webkit-text-security: disc;
}

/* Panel de opciones del generador de contraseñas (PWDGEN-002): sin min-width el dropdown de
   Bootstrap se angosta al ancho del botón trigger y las tres opciones + el input de longitud
   quedan amontonados. */
.zw-generate-password-menu {
  min-width: 220px;
}

/* ============================================================================
   8. PAGINACIÓN
   ============================================================================ */

.zw-pager {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1rem;
}

.zw-pager-status {
  color: var(--zw-text-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

/* ============================================================================
   9. BADGES
   ============================================================================
   Variante suave en vez del .badge sólido de Bootstrap: sobre fondo oscuro un rectángulo esmeralda
   o rojo pleno pesa más que el dato de la fila que está calificando. */

.zw-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.1875rem 0.5rem;
  border: 1px solid transparent;
  border-radius: var(--bs-border-radius-sm);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.4;
  white-space: nowrap;
}

.zw-badge-success {
  border-color: var(--zw-success-border);
  background-color: var(--zw-success-bg);
  color: var(--zw-accent-hover);
}

.zw-badge-danger {
  border-color: var(--zw-danger-border);
  background-color: var(--zw-danger-bg);
  color: var(--zw-danger);
}

/* ============================================================================
   10. BLOQUES MONOESPACIADOS Y QR
   ============================================================================ */

/* Texto que el usuario tiene que leer carácter por carácter o copiar tal cual: la clave manual del
   TOTP, los recovery codes, el Request ID de la página de error. Monoespaciado para que 0/O y 1/l se
   distingan, y white-space: pre-wrap para respetar los saltos de línea de una lista de códigos. */
.zw-key {
  margin: 0;
  padding: 0.75rem 0.875rem;
  overflow-x: auto;
  border: 1px solid var(--zw-border);
  border-radius: var(--bs-border-radius);
  background-color: var(--zw-elevated);
  color: var(--zw-accent-hover);
  font-family: var(--bs-font-monospace);
  font-size: 0.8125rem;
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-all;
}

/* El QR se genera en negro sobre transparente: sobre el fondo del tema queda negro sobre negro y no
   lo lee ninguna cámara. Es el único blanco de la aplicación, y es funcional. */
.zw-qr {
  display: inline-block;
  padding: 0.75rem;
  border-radius: var(--bs-border-radius);
  background-color: #ffffff;
}

.zw-qr img {
  display: block;
  width: 220px;
  max-width: 100%;
  height: auto;
}

/* ============================================================================
   11. LISTAS DE DETALLE
   ============================================================================
   Pares etiqueta/valor (el estado de la conexión con Drive). El <dl class="row"> de Bootstrap deja
   ambos lados con el mismo peso y hay que leer cuál es cuál. */

.zw-detail-list {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.5rem 1.25rem;
  margin: 0;
}

.zw-detail-list dt {
  margin: 0;
  color: var(--zw-text-muted);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.6;
  text-transform: uppercase;
}

.zw-detail-list dd {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.6;
}

/* En teléfono la columna "auto" de la etiqueta se lleva media pantalla y al valor —una cuenta de
   Google, que es largo— le queda un canal angosto donde parte cada dos palabras. Apilado se lee
   mejor, con la etiqueta arriba en tono secundario (UI-004). */
@media (max-width: 575.98px) {
  .zw-detail-list {
    grid-template-columns: 1fr;
    gap: 0.125rem;
  }

  .zw-detail-list dd + dt {
    margin-top: 0.75rem;
  }
}

/* ============================================================================
   12. SHELL DE LAS PANTALLAS DE SESIÓN
   ============================================================================
   Login, activación, recuperación de contraseña y 2FA del login. Lo usa _AuthLayout.cshtml.

   Estas páginas no tienen sidebar (no hay a dónde navegar sin sesión), así que el contenido quedaba
   suelto en la esquina superior izquierda de una pantalla vacía. */

.zw-auth {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* El alto disponible es la ventana menos el topbar (56px), su padding y el del contenido; con
     min-height la card queda centrada en pantallas altas y el bloque crece si el formulario es más
     largo que el viewport. */
  min-height: calc(100vh - 12rem);
  /* dvh es el alto real de la ventana, descontando la barra de URL del navegador móvil; con 100vh
     el bloque se reserva el alto de la ventana SIN esa barra y aparece scroll en una pantalla que
     entraba. La declaración anterior queda como fallback para navegadores sin dvh (UI-004). */
  min-height: calc(100dvh - 12rem);
  padding: 1rem 0;
}

.zw-auth-card {
  width: 100%;
  max-width: 420px;
  padding: 1.75rem;
  border: 1px solid var(--zw-border);
  border-radius: var(--bs-border-radius-lg);
  background-color: var(--zw-surface);
}

/* A 320px el padding de la card más el del contenido dejan el campo en 240px (UI-004). */
@media (max-width: 575.98px) {
  .zw-auth-card {
    padding: 1.25rem;
  }
}

.zw-auth-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
  color: var(--zw-text);
  font-size: 1.0625rem;
  font-weight: 600;
}

.zw-auth-brand .zw-icon {
  width: 1.375rem;
  height: 1.375rem;
  color: var(--zw-accent);
}

.zw-auth-title {
  margin: 0 0 1.25rem;
  font-size: 1.0625rem;
  font-weight: 600;
  text-align: center;
}

/* Texto explicativo entre el título y el formulario (las instrucciones del código 2FA). */
.zw-auth-intro {
  margin: -0.75rem 0 1.25rem;
  color: var(--zw-text-muted);
  font-size: 0.8125rem;
  line-height: 1.5;
  text-align: center;
}

/* Links de pie de la card (recuperar contraseña, volver al login). */
.zw-auth-footer {
  margin: 1.25rem 0 0;
  font-size: 0.8125rem;
  text-align: center;
}

/* ============================================================================
   13. ÁREA TÁCTIL EN PANTALLAS CHICAS
   ============================================================================
   Por debajo de 768px site.css baja el root a 14px, y como todo el dimensionado de Bootstrap es
   relativo, los controles se achican con él: un .btn-sm queda en 26px de alto y un .form-control en
   31px. Con el mouse eso es densidad; con el dedo es fallar el objetivo. Los 44px son el mínimo
   recomendado por las guías de iOS y Android y el criterio 2.5.5 de WCAG.

   Se ajusta el alto y no la tipografía: agrandar la letra reflotaría todas las tablas.

   El equivalente para Select2 vive en theme.css §5, junto a la definición del alto base del control:
   son el mismo ajuste y separarlos dejaría dos lugares donde tocar lo mismo. */

@media (max-width: 767.98px) {
  /* inline-flex además del min-height: .btn es inline-block y con un alto mínimo mayor al natural
     el texto se apoyaría arriba en vez de quedar centrado. */
  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
  }

  .form-control,
  .form-select {
    min-height: 44px;
  }

  /* El casillero de Bootstrap mide 1em: a 14px es un objetivo de 14px. El margen compensa el alto
     extra para que siga alineado con la primera línea de su etiqueta. */
  .form-check-input {
    width: 1.25em;
    height: 1.25em;
    margin-top: 0.15em;
  }

  .form-check {
    padding-left: 1.85em;
  }

  .form-check .form-check-input {
    margin-left: -1.85em;
  }
}

/* ============================================================================
   14. ÁRBOL DE CARPETAS (VAULT)
   ============================================================================
   Barra lateral de Vault/Items/Index y tabla de Vault/Folders (ORG-009). Reusa .zw-nav-link tal
   cual para el link de cada nodo — el único agregado es la sangría por profundidad, que no puede
   ser una clase fija porque el árbol admite subcarpetas de cualquier nivel: cada nodo declara su
   propio --zw-folder-depth inline y esta regla lo traduce a padding. Sin ícono de expandir/
   colapsar ni JS: un vault personal no tiene volumen para justificarlo (mismo criterio "no
   realtime" del proyecto). */
.zw-folder-tree-list {
  list-style: none;
  margin: 0.125rem 0 0;
  padding: 0;
}

.zw-folder-tree .zw-nav-link {
  padding-left: calc(0.625rem + var(--zw-folder-depth, 0) * 1rem);
}

.zw-folder-tree-cell {
  display: inline-block;
  padding-left: calc(var(--zw-folder-depth, 0) * 1.25rem);
}
