/* ═══════════════════════════════════════════════════════════════════════════
   Sistema visual de LIDXI

   Fuente: «Refactoring UI» (Wathan & Schoger). Cada bloque cita el capítulo del
   que sale su regla. El porqué de cada decisión vive en
   lidxi/docs/ESTANDAR_INTERFAZ.md; aquí solo están los valores.

   REGLA DE ORO: ninguna plantilla define colores, espaciados ni tamaños propios.
   Todo sale de estas variables. La prueba `lidxi/gobierno/test_sistema_visual.py`
   falla si alguna plantilla introduce un valor fuera de estas escalas.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Espaciado ── «Establish a spacing and sizing system», p. 70-75 ────────
     Ocho pasos, con saltos SIEMPRE ≥25%: el libro advierte que por debajo de
     eso los valores dejan de distinguirse y uno pierde el tiempo eligiendo
     entre dos cosas que se ven igual. Antes teníamos 23 valores, de los que 19
     saltos eran indistinguibles a ojo. */
  --e-1: 0.25rem;   /*  4px */
  --e-2: 0.5rem;    /*  8px */
  --e-3: 0.75rem;   /* 12px */
  --e-4: 1rem;      /* 16px */
  --e-5: 1.5rem;    /* 24px */
  --e-6: 2rem;      /* 32px */
  --e-7: 3rem;      /* 48px */
  --e-8: 4rem;      /* 64px */

  /* ── Tipografía ── «Establish a type scale», p. 102-107 ───────────────────
     Seis tamaños con escala modular (~1.25). El libro señala que sin sistema
     acaban usándose todos los valores entre 10 y 24 px: teníamos 26.
     La base es 17px y no 16px por decisión propia de accesibilidad — el padrón
     de Dainzú incluye personas mayores, y bajo 16px iOS además hace zoom al
     enfocar un campo. */
  --t-xs:   0.75rem;    /* 12px · metadatos, notas al pie */
  --t-sm:   0.875rem;   /* 14px · texto secundario */
  --t-base: 1.0625rem;  /* 17px · cuerpo */
  --t-lg:   1.3125rem;  /* 21px · subtítulos, importes */
  --t-xl:   1.625rem;   /* 26px · títulos de pantalla */
  --t-2xl:  2.0625rem;  /* 33px · portada, cifras grandes */

  /* Interlineado proporcional al tamaño («Line-height is proportional», p.122):
     el texto pequeño necesita más aire relativo que un título. */
  --i-apretado: 1.25;
  --i-normal:   1.6;

  /* ── Grises ── «You need more colors than you think», p. 142-147 ──────────
     Nueve tonos. El libro insiste en que tres o cuatro nunca alcanzan: «casi
     todo en una interfaz es gris». Y «Greys don't have to be grey» (p.158):
     estos llevan una pizca de azul de la marca, para que el conjunto se sienta
     de una pieza en vez de gris de sistema operativo. */
  --g-50:  #f7f9fa;
  --g-100: #eef2f5;
  --g-200: #dde4e9;
  --g-300: #c3ced6;
  --g-400: #9aa9b4;
  --g-500: #74858f;
  --g-600: #5a6b78;
  --g-700: #40525e;
  --g-800: #26363f;
  --g-900: #16242e;

  /* ── Marca ── rampa completa, no un color suelto ──────────────────────────
     PROVISIONAL: construida sobre el azul elegido durante el desarrollo. En
     cuanto el Consejo entregue su color institucional (definición 5-C), se
     regenera esta rampa y el resto del sistema no se entera. */
  --m-50:  #eef4f8;
  --m-100: #d6e5ee;
  --m-200: #a9c7db;
  --m-300: #77a5c3;
  --m-400: #4885a8;
  --m-500: #1f6b8f;   /* acento: acciones */
  --m-600: #1a5a78;
  --m-700: #164961;
  --m-800: #12303f;   /* marca: barras y titulares */
  --m-900: #0c212c;

  /* ── Semánticos ── uno claro y uno oscuro por significado ─────────────────
     «Don't rely on color alone» (p.166): el color acompaña al texto, nunca lo
     sustituye. Ningún estado se comunica solo con color en LIDXI. */
  --ok-fondo:  #eaf5ef;  --ok-borde:  #bfe0cd;  --ok-texto:  #1f6b45;
  --av-fondo:  #fdf6ec;  --av-borde:  #d9a520;  --av-texto:  #7a4a12;
  --er-fondo:  #fdecec;  --er-borde:  #9a3412;  --er-texto:  #7a2020;

  /* ── Profundidad ── «Use shadows to convey elevation», p. 180-189 ─────────
     Tres niveles. Sustituyen al borde de 1px que antes llevaba cada tarjeta:
     «Use fewer borders» (p.238) advierte que el exceso de bordes hace que el
     diseño se sienta recargado. */
  --sombra-1: 0 1px 2px rgba(22, 36, 46, .06), 0 1px 3px rgba(22, 36, 46, .08);
  --sombra-2: 0 2px 4px rgba(22, 36, 46, .06), 0 4px 10px rgba(22, 36, 46, .08);
  --sombra-3: 0 8px 24px rgba(22, 36, 46, .12);

  --radio:    10px;
  --radio-sm: 7px;

  /* Área táctil mínima. Ley de Fitts: es el tamaño con el que un dedo acierta
     sin precisión. Se respeta en TODO control interactivo. */
  --tactil: 44px;
}

/* ═══ Base ════════════════════════════════════════════════════════════════ */

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--g-100);
  color: var(--g-900);
  font-size: var(--t-base);
  line-height: var(--i-normal);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}

h1, h2, h3 { line-height: var(--i-apretado); color: var(--m-800); margin: 0 0 var(--e-2); }
h1 { font-size: var(--t-xl); }
h2 { font-size: var(--t-lg); }
h3 { font-size: var(--t-base); }
p  { margin: 0 0 var(--e-3); }
p:last-child { margin-bottom: 0; }

a { color: var(--m-500); }
:focus-visible { outline: 3px solid var(--av-borde); outline-offset: 2px; }

/* ═══ Texto ═══════════════════════════════════════════════════════════════
   «Emphasize by de-emphasizing» (p.46): cuando algo no destaca lo suficiente,
   la solución suele ser bajarle el tono a lo que compite, no subírselo a ello. */

.tenue     { color: var(--g-600); font-size: var(--t-sm); }
.muy-tenue { color: var(--g-500); font-size: var(--t-xs); }
.dato      { font-weight: 600; color: var(--g-900); }
.cifra     { font-size: var(--t-lg); font-weight: 700; color: var(--m-800); }
.mono      { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
             font-size: var(--t-xs); word-break: break-all; color: var(--g-600); }

/* ═══ Estructura ══════════════════════════════════════════════════════════ */

.envoltura { max-width: 60rem; margin: 0 auto; padding: 0 var(--e-4) var(--e-7); }
.envoltura-angosta { max-width: 30rem; margin: var(--e-6) auto; padding: 0 var(--e-4); }

/* «Start with too much white space» (p.66): es más fácil quitar aire que añadirlo. */
.tarjeta {
  background: #fff;
  border-radius: var(--radio);
  padding: var(--e-5);
  margin-bottom: var(--e-4);
  box-shadow: var(--sombra-1);
}
.tarjeta:last-child { margin-bottom: 0; }
.tarjeta-plana { box-shadow: none; background: var(--g-50); }

.rejilla { display: grid; gap: var(--e-4); }
.rejilla-tarjetas { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.rejilla-campos   { grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }

/* Los campos de una fila se alinean por su BASE, no por su etiqueta. Una etiqueta que se
   parte en dos renglones —«Manzana, edificio o condominio»— empujaba su campo hacia abajo
   y dejaba los vecinos a distinta altura; el ojo lee ese desnivel como desorden y hace
   dudar de si son el mismo grupo de datos.
   Cada etiqueta se vuelve una columna que empuja su campo al fondo, así que todos los
   campos de la fila quedan a la misma altura sin importar cuánto ocupe el texto. */
.rejilla-campos > label {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--e-1);
}

.fila { display: flex; gap: var(--e-4); flex-wrap: wrap; }
.fila-entre { justify-content: space-between; align-items: baseline; }

/* Fila de campos corregibles dentro de una tabla (equipo del condominio). Los campos se
   apilan en pantalla angosta en vez de desbordar: la tabla ya es ancha por sí sola. */
.fila-datos { display: flex; gap: var(--e-2); align-items: center; flex-wrap: wrap; }
.fila-datos input { flex: 1 1 11rem; min-width: 0; }

/* ═══ Barra superior ══════════════════════════════════════════════════════ */

.barra {
  background: var(--m-800); color: #fff;
  padding: var(--e-3) var(--e-4);
  display: flex; flex-wrap: wrap; gap: var(--e-2) var(--e-4);
  align-items: center; justify-content: space-between;
}
/* Símbolo + nombre + condominio en una línea. El símbolo se alinea con el NOMBRE y no con
   el bloque entero: el condominio va debajo y centrarlo todo dejaría el logo flotando. */
/* El símbolo en la pantalla de entrada. Es la única vez que el producto se presenta a
   alguien que no lo conoce, así que va a 64 px —donde las nueve casas se leen— y con aire
   por debajo antes del nombre. */
.marca-entrada { display: block; width: 64px; height: 64px; margin-bottom: var(--e-3); }

.barra .identidad { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }

/* El símbolo de la marca, a la izquierda del nombre del producto. `flex-shrink: 0` porque
   la barra envuelve en móvil y sin eso el logo se aplasta antes que el texto — un logo
   deformado se lee como sistema descuidado. */
.barra .marca { width: 26px; height: 26px; flex-shrink: 0; display: block; }

.barra .producto {
  font-size: var(--t-xs); letter-spacing: 1.2px; text-transform: uppercase;
  opacity: .75; display: block;
}
.barra .cond { font-weight: 600; font-size: var(--t-base); }
.barra .quien { font-size: var(--t-sm); opacity: .9; text-align: right; }

/* ═══ Controles ═══════════════════════════════════════════════════════════ */

.boton, .boton-2, .boton-riesgo {
  display: inline-block; text-align: center; text-decoration: none;
  border-radius: var(--radio-sm); font-weight: 600; font-size: var(--t-base);
  padding: var(--e-3) var(--e-5); min-height: var(--tactil);
  cursor: pointer; font-family: inherit; border: 0; line-height: var(--i-apretado);
}
.boton { background: var(--m-500); color: #fff; box-shadow: var(--sombra-1); }
.boton:hover { background: var(--m-600); }
.boton:disabled { background: var(--g-400); cursor: progress; box-shadow: none; }

.boton-2 { background: #fff; color: var(--m-500); box-shadow: inset 0 0 0 1.5px var(--m-500); }
.boton-2:hover { background: var(--m-50); }

.boton-riesgo { background: #fff; color: var(--er-borde);
  box-shadow: inset 0 0 0 1.5px var(--er-borde); font-size: var(--t-sm);
  padding: var(--e-2) var(--e-3); min-height: 0; }

.boton-ancho { display: block; width: 100%; }
.boton-chico { font-size: var(--t-sm); padding: var(--e-2) var(--e-3); min-height: 0; }
.boton-enlace { background: none; border: 0; color: var(--m-500); cursor: pointer;
  font: inherit; text-decoration: underline; padding: 0; }

label.campo { display: block; font-weight: 600; margin-bottom: var(--e-1); }
input[type="text"], input[type="email"], input[type="password"],
input[type="date"], input[type="search"], select, textarea {
  width: 100%; font-family: inherit; font-size: var(--t-base);
  padding: var(--e-3); border: 1.5px solid var(--g-400);
  border-radius: var(--radio-sm); min-height: var(--tactil);
  background: #fff; color: var(--g-900);
  -webkit-appearance: none; appearance: none;
}
select { background-image: none; }
textarea { min-height: calc(var(--tactil) * 2); }
input:focus, select:focus, textarea:focus { border-color: var(--m-500); }

/* Casilla con área táctil generosa: se toca el texto, no el cuadrito. */
.casilla {
  display: flex; gap: var(--e-3); align-items: flex-start;
  padding: var(--e-3); background: var(--g-50);
  border-radius: var(--radio-sm); cursor: pointer; min-height: var(--tactil);
}
.casilla input { width: 26px; height: 26px; margin: 0; flex: 0 0 26px;
  accent-color: var(--m-500); }
.casilla span { font-size: var(--t-sm); line-height: var(--i-normal); }

/* ═══ Avisos ══════════════════════════════════════════════════════════════
   «Add color with accent borders» (p.224): una franja de color a la izquierda
   distingue el bloque sin encajonarlo. */

.aviso, .exito, .error {
  padding: var(--e-3) var(--e-4);
  border-radius: 0 var(--radio-sm) var(--radio-sm) 0;
  margin-bottom: var(--e-4); font-size: var(--t-sm);
}
.aviso { background: var(--av-fondo); border-left: 4px solid var(--av-borde); color: var(--av-texto); }
.exito { background: var(--ok-fondo); border-left: 4px solid var(--ok-borde); color: var(--ok-texto); }
.error { background: var(--er-fondo); border-left: 4px solid var(--er-borde); color: var(--er-texto);
  font-weight: 500; }

.exito-caja {
  background: var(--ok-fondo); border-radius: var(--radio);
  padding: var(--e-5); text-align: center; box-shadow: var(--sombra-1);
}
.exito-caja .marca-ok { font-size: var(--t-2xl); line-height: 1; color: var(--ok-texto);
  display: block; margin-bottom: var(--e-2); }

/* ═══ Estado vacío ════════════════════════════════════════════════════════
   «Don't overlook empty states» (p.234): cuando el sistema depende de datos
   que alguien captura, la pantalla en blanco es la PRIMERA impresión, no un
   caso raro. Lleva su acción siguiente bien visible. */

.vacio {
  text-align: center; padding: var(--e-7) var(--e-5);
  background: #fff; border-radius: var(--radio); box-shadow: var(--sombra-1);
}
.vacio .icono { font-size: var(--t-2xl); color: var(--g-300); display: block;
  margin-bottom: var(--e-3); }
.vacio h3 { color: var(--g-800); margin-bottom: var(--e-2); }
.vacio p { color: var(--g-600); font-size: var(--t-sm); margin-bottom: var(--e-4);
  max-width: 26rem; margin-left: auto; margin-right: auto; }

/* ═══ Listas de datos ═════════════════════════════════════════════════════ */

.datos { margin: 0; }
.datos .renglon {
  display: flex; justify-content: space-between; gap: var(--e-4);
  padding: var(--e-3) 0; border-bottom: 1px solid var(--g-200);
}
.datos .renglon:last-child { border-bottom: 0; }
.datos dt { color: var(--g-600); font-size: var(--t-sm); }
.datos dd { margin: 0; text-align: right; font-weight: 600; }

table.tabla { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
table.tabla th { text-align: left; padding: var(--e-2) 0;
  border-bottom: 2px solid var(--g-200); color: var(--g-600); font-weight: 600; }
table.tabla td { padding: var(--e-3) 0; border-bottom: 1px solid var(--g-200);
  vertical-align: top; }

/* Lo inactivo se atenúa pero NO se oculta: quién tuvo acceso, o quién fue
   dueño, es información de auditoría. */
.inactivo { opacity: .55; }

.separado { margin-top: var(--e-5); }
.apretado { margin-bottom: var(--e-2); }

@media screen and (min-width: 40rem) {
  .envoltura { padding-top: var(--e-5); }
}

/* ═══ Documento embebido ══════════════════════════════════════════════════
   El convenio se muestra dentro de un iframe para que sus estilos queden
   aislados y se vea TAL CUAL se guardó. La altura la ajusta el JS al contenido:
   dos barras de desplazamiento anidadas en un teléfono hacen creer que se llegó
   al final sin haber leído. */

.doc-marco { background: #fff; border-radius: var(--radio); overflow: hidden;
  margin: var(--e-4) 0; box-shadow: var(--sombra-1); }
.doc-marco iframe { display: block; width: 100%; border: 0; height: 2400px; }
.doc-etiqueta { background: var(--g-100); padding: var(--e-2) var(--e-3);
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .6px;
  color: var(--g-600); }

/* ═══ Estado de un documento del expediente ═══════════════════════════════
   Tres estados que se leen de un vistazo en una lista larga. Llevan también su
   PALABRA, nunca solo el color: uno de cada doce hombres no distingue rojo de verde,
   y aquí la diferencia es si un documento acredita algo o hay que volver a pedirlo. */

.estado-pendiente, .estado-validado, .estado-rechazado {
  display: inline-block; padding: var(--e-1) var(--e-2); border-radius: var(--radio);
  font-size: var(--t-xs); font-weight: 600; white-space: nowrap;
}
.estado-pendiente { background: var(--av-fondo); color: var(--av-texto); }
.estado-validado  { background: var(--ok-fondo); color: var(--ok-texto); }
.estado-rechazado { background: var(--er-fondo); color: var(--er-texto); }

/* ═══ Pasos numerados ═════════════════════════════════════════════════════ */

.pasos { list-style: none; margin: var(--e-2) 0 0; padding: 0; }
.pasos li { display: flex; gap: var(--e-3); margin-bottom: var(--e-2);
  align-items: flex-start; }
.pasos .num { flex: 0 0 1.5rem; height: 1.5rem; border-radius: 50%;
  background: var(--m-500); color: #fff; font-size: var(--t-xs); font-weight: 700;
  display: flex; align-items: center; justify-content: center; }

/* ═══ Tarjeta seleccionable (selector de condominio) ══════════════════════ */

.opcion { display: block; width: 100%; text-align: left; background: #fff;
  border: 0; border-radius: var(--radio); padding: var(--e-4);
  margin-bottom: var(--e-3); cursor: pointer; font-family: inherit;
  font-size: var(--t-base); min-height: var(--tactil); box-shadow: var(--sombra-1); }
.opcion:hover { box-shadow: var(--sombra-2); }

/* ═══ Precio ══════════════════════════════════════════════════════════════
   «Not all elements are equal» (p.36): el importe es lo que la Tesorería viene
   a ver, así que se lleva el mayor peso visual de la tarjeta. */

.precio { font-size: var(--t-lg); font-weight: 700; color: var(--m-800);
  line-height: var(--i-apretado); }
.precio-nota { font-size: var(--t-xs); color: var(--g-600); }

/* Saludo personal de las pantallas públicas: lo primero que lee el vecino. */
.saludo { font-size: var(--t-lg); font-weight: 600; color: var(--m-800);
  margin-bottom: var(--e-1); line-height: var(--i-apretado); }

/* Tarjeta-módulo del panel. von Restorff: lo que se puede usar se distingue de lo que
   solo se anuncia, y por eso los pendientes NO son tarjetas. */
.modulo { display: block; text-decoration: none; color: inherit; margin-bottom: 0; }
.modulo strong { color: var(--m-500); display: block; }
.modulo:hover { box-shadow: var(--sombra-2); }

/* Cerrar sesión vive en la barra oscura, donde un botón claro se convierte en el
   elemento más llamativo de la página. von Restorff al revés: lo que resalta debe ser lo
   que la pantalla existe para hacer, no la salida. Se degrada a enlace. */
.salir {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: inherit; opacity: .75; text-decoration: underline;
}
.salir:hover { opacity: 1; }

/* Estado logrado, dicho sin celebrarlo: un convenio firmado es lo normal, no un premio.
   Verde del sistema, tamaño del texto que lo rodea. */
.exito-tenue { color: var(--ok-texto); font-size: var(--t-sm); }

/* Dato que exige atención antes de continuar, sin ser todavía un error: nadie ha enviado
   nada. Tono de aviso, no de fallo. */
.dato-alerta { color: var(--av-texto); }

/* ═══ Menú lateral ════════════════════════════════════════════════════════ */

/* Dos columnas: navegación y contenido. El menú tiene ancho fijo para que el contenido
   no se mueva al cambiar de módulo —un texto que salta de sitio hace perder el renglón
   que se estaba leyendo. */
.con-menu {
  display: grid;
  /* 11rem alcanza para «Padrón de unidades y asociados» en dos renglones. Antes eran
     15rem: 4rem de más multiplicadas por cada pantalla del día. */
  grid-template-columns: 11rem 1fr;
  align-items: start;
}

/* Con menú al lado, el escritorio central puede ensancharse: el tope de 60rem existe para
   que un texto largo no se lea de pared a pared, pero aquí el contenido son tablas y
   formularios, que agradecen el ancho. Sin esto, el menú recortaba el área de trabajo sin
   que el contenido ganara nada a cambio. */
.con-menu .envoltura {
  max-width: 78rem;
  /* `width` y márgenes explícitos, no heredados. `.envoltura` trae `margin: 0 auto`, y al
     volverse elemento de grid eso la hacía encogerse al tamaño de su contenido en vez de
     estirarse: el escritorio quedaba en 775px de 1264 disponibles, sin usar ni su propio
     tope. Se pega al menú y crece hacia la derecha. */
  width: 100%;
  margin-inline: 0;
  justify-self: start;
}

.menu {
  position: sticky;
  top: var(--e-3);
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* Sin relleno a la derecha: la separación con el contenido la da el propio relleno de
     `.envoltura`, y sumarlas dejaba un canal vacío entre el menú y el trabajo. */
  padding: var(--e-3) 0 var(--e-4) var(--e-3);
}

.menu-opcion {
  display: block;
  /* Menos relleno horizontal que vertical: lo que se gana a los lados es ancho del
     escritorio; el alto táctil de 44px se conserva, que es lo que sí se toca. */
  padding: var(--e-2) var(--e-3);
  min-height: var(--tactil);
  display: flex;
  align-items: center;
  border-radius: var(--radio-sm);
  color: var(--g-700);
  text-decoration: none;
  font-size: var(--t-sm);
  line-height: 1.35;
  border-left: 3px solid transparent;
}

.menu-opcion:hover { background: var(--g-100); color: var(--g-900); }

/* El módulo en curso se distingue por color Y por la barra lateral, no solo por color:
   quien no distingue tonos necesita otra señal (ESTANDAR_INTERFAZ.md §5). */
.menu-opcion.activo {
  background: var(--m-50);
  color: var(--m-800);
  font-weight: 600;
  border-left-color: var(--m-500);
}

/* En pantalla angosta el menú pasa arriba, en fila. No se esconde tras una hamburguesa:
   ocultar la navegación cuesta un toque y hace olvidar que existe (Krug, cap. 6), y con
   tres o cuatro opciones cortas no hace falta. */
@media (max-width: 48rem) {
  .con-menu { grid-template-columns: 1fr; }
  .menu {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    padding: var(--e-3) var(--e-4) 0;
  }
  .menu-opcion {
    border-left: 0;
    border-bottom: 3px solid transparent;
    flex: 1 1 auto;
    text-align: center;
  }
  .menu-opcion.activo { border-left: 0; border-bottom-color: var(--m-500); }
}
