/* IONSOFT Obras — hoja de estilos unica.
 *
 * Direccion de diseno: MESA DE OBRA. Un tablero de instrumentos, no un dashboard.
 * El fondo es papel de plano en tinta; el laton es el unico acento y se usa como se
 * usa el bronce en un instrumento de medicion: en los filos, no en las superficies.
 * Los titulos van en serif editorial porque esto es un documento financiero que
 * alguien firma, y toda la plata va en monoespaciada tabular para que las columnas
 * de guaranies caigan al digito.
 *
 * Jerarquia de lectura, en este orden y a proposito:
 *   1. el estado (color de la franja)  2. la cifra  3. el nombre  4. el resto.
 *
 * Tres reglas que no se pueden romper:
 *   1. Sin JavaScript. La CSP de la app es `script-src 'none'`.
 *   2. Sin `style` inline y sin recursos remotos: `style-src 'self'` y `default-src 'self'`.
 *      Las fuentes se sirven desde /static/fuentes y los graficos son SVG en linea, que
 *      pinta atributos de presentacion y no CSS, asi que la CSP los deja pasar.
 *   3. Todo estado tiene que leerse sin depender del color: texto, forma o ambos.
 */

@import url('/static/fuentes.css');

:root {
  /* --- Tinta y superficies ------------------------------------------------
     Cinco escalones y no dos: con dos, una tarjeta dentro de otra desaparece. */
  --tinta:        #070b14;
  --tinta-alta:   #0a1120;
  --superficie:   #0f172a;
  --superficie-2: #16203a;
  --superficie-3: #1e2c4b;

  --plano: rgba(150, 180, 220, .05);   /* lineas del papel de plano */

  --borde:        rgba(190, 214, 246, .10);
  --borde-medio:  rgba(190, 214, 246, .18);
  --borde-fuerte: rgba(190, 214, 246, .30);

  /* --- Texto --- */
  --texto:   #eef2f9;
  --texto-2: #b6c4da;
  --tenue:   #7f92b0;

  /* --- Laton: el unico acento de marca --- */
  --laton:       #cfa451;
  --laton-claro: #f0d69b;
  /* El laton cuando se usa de SUPERFICIE y no de texto. Vale lo mismo en los dos temas:
     un boton de metal es de metal de dia y de noche. El de arriba, en cambio, cambia con
     el tema porque tiene que leerse contra el fondo. */
  --laton-vivo:  #cfa451;
  --laton-hondo: #8a6a2b;
  --laton-tenue: rgba(207, 164, 81, .13);

  /* --- Semaforo. Tres tonos por color: solido, tinte de fondo, borde. --- */
  --verde:       #3ec48d;
  --verde-tinte: rgba(62, 196, 141, .12);
  --verde-borde: rgba(62, 196, 141, .34);

  --ambar:       #e5a53a;
  --ambar-tinte: rgba(229, 165, 58, .12);
  --ambar-borde: rgba(229, 165, 58, .36);

  --rojo:        #f0645c;
  /* Sobre su propio tinte y en 11px, el rojo del semaforo se queda en 4.39:1. Este es el
     mismo rojo con mas luz, solo para texto chico sobre fondo rojo. */
  --rojo-texto:  #f78d86;
  --rojo-tinte:  rgba(240, 100, 92, .13);
  --rojo-borde:  rgba(240, 100, 92, .38);

  --acento: var(--laton);

  /* --- Elevacion. La luz cae de arriba, siempre. --- */
  --sombra-1: 0 1px 2px rgba(0, 0, 0, .45);
  --sombra-2: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 26px -14px rgba(0, 0, 0, .75);
  --sombra-3: 0 2px 4px rgba(0, 0, 0, .4), 0 28px 64px -28px rgba(0, 0, 0, .9);
  --filo: inset 0 1px 0 rgba(255, 255, 255, .05);   /* el brillo del canto superior */

  /* --- Espaciado: escala de 4, sin numeros sueltos --- */
  --e1: 4px;  --e2: 8px;  --e3: 12px; --e4: 16px;
  --e5: 22px; --e6: 30px; --e7: 42px; --e8: 60px;

  /* --- Radios --- */
  --r1: 7px; --r2: 11px; --r3: 15px; --r4: 20px; --rp: 999px;

  /* --- Tipografia --- */
  --display: Newsreader, Constantia, Cambria, Georgia, serif;
  --sans: 'IBM Plex Sans', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --cifras: 'IBM Plex Mono', Consolas, 'Cascadia Mono', monospace;

  /* --- Curvas. Una sola familia para que todo se mueva igual. --- */
  --curva: cubic-bezier(.22, .68, .28, 1);
  --rapido: .14s var(--curva);
  --medio: .26s var(--curva);

  /* --- Velos y pozos ------------------------------------------------------
     Todo lo que en el tema oscuro era "un poco de blanco encima" o "un poco de
     negro adentro" vive aca. Es lo unico que NO se puede dejar literal: en el
     tema claro, un velo blanco sobre papel es invisible y un pozo negro es un
     agujero. Con estos tokens el tema claro se define arriba y no hay que tocar
     ninguna regla de las novecientas de abajo. */
  --velo-1: rgba(255, 255, 255, .035);   /* fila enfocada */
  --velo-2: rgba(255, 255, 255, .05);    /* hover de lista */
  --velo-3: rgba(255, 255, 255, .07);    /* pista de un grafico */
  --pozo:      rgba(0, 0, 0, .30);       /* fondo de un campo */
  --pozo-foco: rgba(0, 0, 0, .42);
  --pozo-hondo: rgba(0, 0, 0, .14);      /* caja de "no hay nada" */
  --hundido: inset 0 1px 2px rgba(0, 0, 0, .35);
  --marca-agua: rgba(127, 146, 176, .7); /* placeholder */
  --frio: #5b7fb9;                       /* el azul del aro interior */
  --seleccion: rgba(207, 164, 81, .3);
  --velo-subrayado: rgba(255, 255, 255, .35);

  /* Segundo escalon de los degradados. La luz cae de arriba: el fondo de una
     superficie es siempre mas oscuro que su tope en oscuro, y mas claro en claro. */
  --superficie-baja: rgba(15, 23, 42, .82);
  --barra-alta: rgba(10, 17, 32, .94);
  --barra-baja: rgba(10, 17, 32, .84);

  /* Sobre laton siempre va tinta, en los dos temas: el boton es del mismo color
     en claro y en oscuro, asi que su texto tambien. */
  --sobre-laton: #1a1204;
  --filo-boton: rgba(255, 255, 255, .45);

  /* Los halos de fondo de la pagina. */
  --halo-laton: rgba(207, 164, 81, .11);
  --halo-verde: rgba(62, 196, 141, .055);

  /* Arranque de los degradados del semaforo en las barras de consumo. */
  --verde-hondo: #2c9a6d;
  --ambar-hondo: #b8811f;
  --rojo-hondo:  #c04c45;
}

/* ======================================================================================
   TEMA CLARO
   ======================================================================================
   Lo elige el sistema operativo de cada persona, no un boton: `prefers-color-scheme` es
   CSS puro y la CSP prohibe el JavaScript que haria falta para un interruptor. El dueno
   mirando de dia en la oficina ve papel; el residente cargando de noche en la obra ve
   tinta. Nadie configura nada.

   Se redefinen SOLO los tokens. Ninguna regla de las de abajo sabe que existe este
   bloque, y esa es toda la razon por la que se pudo tokenizar antes cada velo y cada
   pozo: un `rgba(255,255,255,.06)` escrito a mano en una regla seria invisible sobre
   papel y no habria forma de arreglarlo desde aca.

   Tres decisiones que no son obvias:

   1. **El papel no es blanco puro y el texto no es negro puro.** `#eef1f7` contra
      `#121a2b`. Blanco puro sobre una pantalla brillante cansa en una jornada entera, y
      el gris tiene una pizca de azul para que sea el mismo mundo que el tema oscuro y no
      un gris de fabrica.
   2. **La luz sigue cayendo de arriba.** En oscuro el pie de una tarjeta se oscurece; en
      claro se aclara. Por eso `--superficie-baja` no es una inversion mecanica.
   3. **El laton se oscurece.** `#cfa451` sobre tinta tiene contraste de sobra; sobre
      papel queda en 2.1:1 y un enlace deja de leerse. El acento pasa a `#8a6a2b`, que es
      el mismo laton con menos luz, y conserva la identidad sin pedirle al ojo que
      adivine.
   ==================================================================================== */

@media (prefers-color-scheme: light) {
  :root {
    /* Papel y superficies. Al reves que en oscuro: el fondo es el escalon mas
       oscuro y las tarjetas se levantan hacia el blanco. */
    --tinta:        #e8ecf4;
    --tinta-alta:   #eef1f7;
    --superficie:   #ffffff;
    --superficie-2: #f1f4fa;
    --superficie-3: #d8e0ee;

    --plano: rgba(70, 100, 150, .07);

    --borde:        rgba(30, 52, 92, .13);
    --borde-medio:  rgba(30, 52, 92, .22);
    --borde-fuerte: rgba(30, 52, 92, .34);

    --texto:   #121a2b;
    --texto-2: #38465e;
    --tenue:   #515e73;

    /* El laton baja de luz para poder leerse sobre papel. */
    --laton:       #7a5c22;
    --laton-claro: #6d531f;
    --laton-hondo: #cfa451;
    --laton-vivo:  #cfa451;
    --laton-tenue: rgba(138, 106, 43, .12);

    /* El semaforo tambien: los tonos brillantes del tema oscuro sobre blanco
       quedan en 2:1 y el estado deja de leerse. */
    --verde:       #11633f;
    --verde-tinte: rgba(21, 122, 79, .10);
    --verde-borde: rgba(21, 122, 79, .32);

    --ambar:       #7d5206;
    --ambar-tinte: rgba(154, 101, 8, .11);
    --ambar-borde: rgba(154, 101, 8, .34);

    --rojo:        #a01f18;
    --rojo-texto:  #a01f18;
    --rojo-tinte:  rgba(179, 38, 30, .09);
    --rojo-borde:  rgba(179, 38, 30, .32);

    /* Sombras mucho mas suaves: sobre papel una sombra fuerte se ve sucia. */
    --sombra-1: 0 1px 2px rgba(20, 35, 65, .08);
    --sombra-2: 0 1px 2px rgba(20, 35, 65, .06), 0 8px 20px -12px rgba(20, 35, 65, .22);
    --sombra-3: 0 2px 4px rgba(20, 35, 65, .07), 0 22px 50px -26px rgba(20, 35, 65, .30);
    --filo: inset 0 1px 0 rgba(255, 255, 255, .9);

    /* Velos y pozos invertidos: encima va sombra, no luz. */
    --velo-1: rgba(20, 35, 65, .035);
    --velo-2: rgba(20, 35, 65, .055);
    --velo-3: rgba(20, 35, 65, .09);
    --pozo:      #ffffff;
    --pozo-foco: #ffffff;
    --pozo-hondo: rgba(20, 35, 65, .035);
    --hundido: inset 0 1px 2px rgba(20, 35, 65, .09);
    --marca-agua: #8b98ac;
    --frio: #3a5f96;
    --seleccion: rgba(207, 164, 81, .38);
    --velo-subrayado: rgba(30, 52, 92, .35);

    /* El pie de una superficie se ACLARA, porque la luz sigue viniendo de arriba. */
    --superficie-baja: #f6f8fc;
    --barra-alta: #ffffff;
    --barra-baja: #f4f7fb;

    /* El boton de laton sigue siendo de laton en los dos temas, asi que su texto
       tambien: tinta sobre metal. */
    --sobre-laton: #1a1204;
    --filo-boton: rgba(255, 255, 255, .55);

    --halo-laton: rgba(207, 164, 81, .13);
    --halo-verde: rgba(21, 122, 79, .05);

    --verde-hondo: #0f5c3b;
    --ambar-hondo: #7a5006;
    --rojo-hondo:  #8c1c16;
  }
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* Le avisa al navegador que el tema es oscuro: sin esto los controles nativos
     (barra de scroll, calendario del input date, desplegables en Windows) salen
     claros sobre fondo negro. */
  color-scheme: dark;
  scroll-behavior: smooth;
}

/* La barra superior es pegajosa: sin esto, un ancla deja el titulo tapado debajo. */
h1, h2, h3 { scroll-margin-top: 76px; }

/* Nada de retardo de 300 ms al tocar en un telefono, y el destello del toque a tono. */
a, button, .boton, summary, label, select, input[type=submit] {
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(207, 164, 81, .18);
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--sans);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--texto);
  background-color: var(--tinta);
  /* Papel de plano: cuadricula finisima, un halo de lampara arriba a la izquierda y
     un segundo halo frio a la derecha para que el fondo no sea plano. */
  background-image:
    radial-gradient(1100px 480px at 6% -10%, var(--halo-laton), transparent 62%),
    radial-gradient(900px 620px at 102% -4%, var(--halo-verde), transparent 58%),
    repeating-linear-gradient(0deg,  var(--plano) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg, var(--plano) 0 1px, transparent 1px 34px);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }
em { font-style: normal; }
code {
  font-family: var(--cifras); font-size: .92em;
  background: var(--superficie-2); padding: 1px 5px; border-radius: 5px;
  border: 1px solid var(--borde);
}

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -.012em;
  line-height: 1.18;
  /* Evita la palabra huerfana en la ultima linea de un titulo. */
  text-wrap: balance;
}

/* Foco visible y con el color de la casa. Sin esto, el sistema es inusable con
   teclado, que es como lo va a usar la administracion que carga cien gastos. */
:focus-visible {
  outline: 2px solid var(--laton-claro);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Salto al contenido: primer tabulador de la pagina, invisible hasta que se enfoca. */
.saltar {
  position: absolute; left: -9999px; top: var(--e2); z-index: 100;
  background: var(--laton-vivo); color: var(--sobre-laton); font-weight: 700;
  padding: var(--e2) var(--e4); border-radius: var(--r1);
}
.saltar:focus { left: var(--e4); }

::selection { background: var(--seleccion); color: var(--texto); }

/* Barras de scroll a tono: en una pantalla oscura, una barra clara es un tajo. */
* { scrollbar-width: thin; scrollbar-color: var(--superficie-3) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb {
  background: var(--superficie-3); border-radius: var(--rp);
  border: 3px solid transparent; background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background-color: var(--borde-fuerte); background-clip: content-box; }


/* =========================================================================
   BARRA SUPERIOR
   Siete secciones y un usuario. En el escritorio entra todo en una linea;
   en un telefono el menu se desliza de costado en vez de apretarse.
   ========================================================================= */
.barra {
  display: flex; align-items: center; gap: var(--e5);
  padding: 0 var(--e5);
  height: 58px;
  background: linear-gradient(180deg, var(--barra-alta), var(--barra-baja));
  border-bottom: 1px solid var(--borde);
  backdrop-filter: blur(16px) saturate(1.3);
  position: sticky; top: 0; z-index: 20;
}
/* Hilo de laton bajo la barra: el filo del instrumento. */
.barra::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(207, 164, 81, .5) 18%, rgba(207, 164, 81, .5) 82%, transparent);
}

.logo { display: flex; align-items: center; gap: var(--e3); flex: none; }
.logo-icon {
  display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 10px;
  background: linear-gradient(152deg, var(--laton-claro), var(--laton) 46%, var(--laton-hondo));
  color: var(--sobre-laton);
  font-family: var(--display); font-weight: 600; font-size: 14px; letter-spacing: -.02em;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 3px 10px rgba(207, 164, 81, .28);
}
.logo strong {
  display: block; font-size: 13.5px; font-weight: 600; letter-spacing: -.005em; line-height: 1.2;
}
.logo small {
  display: block; color: var(--tenue); font-size: 11px; line-height: 1.3;
  max-width: 24ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.nav { display: flex; gap: 1px; margin-left: auto; align-items: center; }
.nav a {
  position: relative;
  padding: 7px 11px; border-radius: var(--r1);
  color: var(--tenue); font-weight: 500; font-size: 12.5px; white-space: nowrap;
  transition: color var(--rapido), background-color var(--rapido);
}
.nav a:hover { background: var(--superficie-2); color: var(--texto); }
.nav a.activo { color: var(--texto); background: var(--superficie-2); }
/* Subrayado de laton en la seccion activa: mas sobrio que pintar el boton entero. */
.nav a.activo::after {
  content: ''; position: absolute; left: 11px; right: 11px; bottom: 3px;
  height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--laton-hondo), var(--laton-claro), var(--laton-hondo));
}

.usuario { display: flex; align-items: center; gap: var(--e3); flex: none; }
.usuario > a {
  display: flex; align-items: center; gap: var(--e2);
  padding: 5px 11px 5px 6px; border-radius: var(--rp);
  border: 1px solid var(--borde); background: var(--superficie);
  font-size: 12.5px; font-weight: 500;
  transition: border-color var(--rapido), background-color var(--rapido);
}
.usuario > a:hover { border-color: var(--borde-medio); background: var(--superficie-2); }
/* Inicial del usuario en un disco: identifica la sesion de un vistazo. */
.usuario .inicial {
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  background: var(--superficie-3); color: var(--laton-claro);
  font-size: 11px; font-weight: 700; flex: none;
}
.usuario em {
  color: var(--tenue); font-size: 9.5px; text-transform: uppercase; letter-spacing: .09em;
  font-weight: 600;
}

.contenido {
  padding: var(--e6) var(--e5) var(--e8);
  max-width: 1520px; margin: 0 auto;
}


/* =========================================================================
   ENCABEZADO DE PANTALLA
   Antetitulo en versalitas, titulo en serif, una linea de contexto. Siempre
   la misma forma, para que el ojo sepa donde esta parado sin leer.
   ========================================================================= */
.encabezado {
  display: flex; align-items: flex-end; gap: var(--e4); flex-wrap: wrap;
  margin-bottom: var(--e5);
  padding-bottom: var(--e4);
  border-bottom: 1px solid var(--borde);
}
.encabezado h1 { margin: 0; font-size: 29px; }
.encabezado p { margin: var(--e1) 0 0; color: var(--tenue); font-size: 12.5px; }
.antetitulo {
  display: block; margin-bottom: 5px;
  color: var(--laton); font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .16em;
}
.acciones { margin-left: auto; display: flex; gap: var(--e2); align-items: flex-end; flex-wrap: wrap; }


/* =========================================================================
   TARJETAS
   ========================================================================= */
.tarjeta {
  position: relative;
  background: linear-gradient(180deg, var(--superficie), var(--superficie-baja));
  border: 1px solid var(--borde);
  border-radius: var(--r3);
  padding: var(--e5);
  margin-bottom: var(--e4);
  box-shadow: var(--sombra-2), var(--filo);
}
.tarjeta h2 {
  margin: 0 0 var(--e4); font-size: 16px;
  display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap;
}
/* Marca de laton antes del titulo de cada tarjeta. */
.tarjeta h2::before {
  content: ''; width: 3px; height: 16px; border-radius: 2px; flex: none;
  background: linear-gradient(180deg, var(--laton-claro), var(--laton-hondo));
}

/* Dos tarjetas lado a lado; en pantalla angosta se apilan solas. */
.columnas { display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: var(--e4); }
.nota-criterio { margin-top: var(--e4); max-width: 72ch; }


/* =========================================================================
   KPIs
   La cifra manda. El rotulo es chico, la cifra es grande y monoespaciada, y
   abajo va el contexto que evita la pregunta de si es mucho o poco.
   ========================================================================= */
.kpis {
  display: grid; gap: var(--e3); margin-bottom: var(--e5);
  grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
}
.kpi {
  position: relative; overflow: hidden;
  background: linear-gradient(180deg, var(--superficie), var(--superficie-baja));
  border: 1px solid var(--borde);
  border-radius: var(--r3);
  padding: var(--e4) var(--e4) var(--e3);
  box-shadow: var(--sombra-2), var(--filo);
  animation: subir .42s var(--curva) both;
}
/* Hilo superior: la tarjeta se identifica por color sin gritar. */
.kpi::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: linear-gradient(90deg, var(--laton), transparent 72%);
}
.kpi:nth-child(2) { animation-delay: .05s; }
.kpi:nth-child(3) { animation-delay: .10s; }
.kpi:nth-child(4) { animation-delay: .15s; }
.kpi:nth-child(5) { animation-delay: .20s; }
.kpi:nth-child(6) { animation-delay: .25s; }

.kpi > span {
  display: block; color: var(--tenue);
  font-size: 9.5px; text-transform: uppercase; letter-spacing: .12em; font-weight: 700;
}
.kpi > strong {
  display: block; margin-top: var(--e2);
  font-family: var(--cifras); font-size: 23px; font-weight: 500;
  font-variant-numeric: tabular-nums; letter-spacing: -.035em;
  line-height: 1.15;
}
.kpi > em {
  display: block; margin-top: 5px;
  font-size: 11px; color: var(--tenue); line-height: 1.4;
}
/* El KPI que importa en la pantalla: mas alto y con filo de laton. Se usa UNA vez
   por pantalla; si se usa dos, deja de significar nada. */
.kpi.principal { border-color: var(--laton-tenue); grid-column: span 2; }
.kpi.principal::before {
  height: 3px;
  background: linear-gradient(90deg, var(--laton-claro), var(--laton), transparent 88%);
}
.kpi.principal > strong { font-size: 31px; letter-spacing: -.045em; }
.kpi.rojo::before  { background: linear-gradient(90deg, var(--rojo), transparent 72%); }
.kpi.verde::before { background: linear-gradient(90deg, var(--verde), transparent 72%); }
.kpi.ambar::before { background: linear-gradient(90deg, var(--ambar), transparent 72%); }

@keyframes subir {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}


/* =========================================================================
   TABLAS
   Es donde vive la plata. Cifras tabulares alineadas al
   digito, y la fila en problemas marcada con una franja lateral: el color solo
   no alcanza, y ademas hay gente que no lo distingue.
   ========================================================================= */
.tabla-scroll {
  overflow-x: auto;
  margin: 0 calc(var(--e5) * -1) calc(var(--e5) * -1);
  padding: 0 var(--e5) var(--e2);
}
table { width: 100%; border-collapse: collapse; }
th, td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--borde); }
th {
  background: var(--superficie);
  color: var(--tenue); font-size: 9.5px; text-transform: uppercase;
  font-weight: 700; letter-spacing: .11em; white-space: nowrap;
  border-bottom: 1px solid var(--borde-medio);
}
td { font-size: 13px; }
/* Toda la plata en cifras tabulares: las columnas caen alineadas al digito. */
td.num, th.num { text-align: right; white-space: nowrap; }
td.num {
  font-family: var(--cifras); font-variant-numeric: tabular-nums;
  font-size: 12.5px; letter-spacing: -.02em;
}
tbody tr { transition: background-color var(--rapido); }
tbody tr:hover { background: var(--superficie-2); }
tbody tr:last-child td { border-bottom: none; }
tfoot td {
  font-weight: 700; border-top: 1px solid var(--borde-medio); border-bottom: none;
  background: var(--laton-tenue);
}
tfoot td:first-child {
  font-size: 10px; text-transform: uppercase; letter-spacing: .11em; color: var(--texto-2);
}

/* Franja de estado de la fila. La celda del semaforo la dibuja con un ::before,
   asi no hace falta una columna extra ni un borde que descuadre la tabla. */
td.estado { width: 1px; padding-left: var(--e4); position: relative; }
td.estado::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: transparent;
}
/* Solo las filas con problema llevan franja. Si la llevan las doce, ninguna resalta. */
tr.fila-ambar td.estado::before { background: var(--ambar); }
tr.fila-rojo  td.estado::before { background: var(--rojo); }
/* La fila que pierde plata: tinte propio y se mantiene al pasar el mouse. Es la
   que se muestra en la reunion y tiene que encontrarse sin buscarla. */
tr.fila-rojo { background: var(--rojo-tinte); }
tr.fila-rojo:hover { background: rgba(240, 100, 92, .19); }
tr.fila-rojo td.num.negativo { font-weight: 600; }

.anulado td { opacity: .45; text-decoration: line-through; }
.es-anulacion td { color: var(--ambar); }
.es-anulacion td:first-child { position: relative; }

.negativo { color: var(--rojo); font-weight: 600; }
.positivo { color: var(--verde); }


/* =========================================================================
   SEMAFORO, CHIPS Y BARRAS
   ========================================================================= */
.punto {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%; flex: none;
}
.punto.verde { background: var(--verde); box-shadow: 0 0 0 3px var(--verde-tinte); }
.punto.ambar { background: var(--ambar); box-shadow: 0 0 0 3px var(--ambar-tinte); }
.punto.rojo  { background: var(--rojo);  box-shadow: 0 0 0 3px var(--rojo-tinte); }
.punto.gris  { background: var(--tenue); }
/* El punto rojo late despacio. Una sola cosa se mueve en la pantalla, y es la
   que hay que mirar. */
.punto.rojo { animation: latir 2.4s ease-in-out infinite; }
@keyframes latir {
  0%, 100% { box-shadow: 0 0 0 3px var(--rojo-tinte); }
  50%      { box-shadow: 0 0 0 6px rgba(240, 100, 92, .05); }
}

.chip {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  padding: 3px 10px 4px; border-radius: var(--rp);
  font-size: 11px; font-weight: 600; letter-spacing: .01em; white-space: nowrap;
  border: 1px solid transparent;
}
.chip.verde { background: var(--verde-tinte); color: var(--verde); border-color: var(--verde-borde); }
.chip.ambar { background: var(--ambar-tinte); color: var(--ambar); border-color: var(--ambar-borde); }
.chip.rojo  { background: var(--rojo-tinte);  color: var(--rojo-texto);  border-color: var(--rojo-borde); }
.chip.laton { background: var(--laton-tenue); color: var(--laton-claro); border-color: rgba(207, 164, 81, .3); }
.chip.neutro { background: var(--superficie-2); color: var(--texto-2); border-color: var(--borde); }
.chip-chico {
  display: inline-block; padding: 1px 8px 2px; border-radius: var(--rp);
  background: var(--superficie-2); border: 1px solid var(--borde);
  font-size: 9.5px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--tenue); font-weight: 700;
}

/* Celda de porcentaje: la cifra y la barra en una sola linea, pegadas a la
   derecha, para que la columna se lea de un vistazo y no en zigzag. */
.peso { display: flex; align-items: center; justify-content: flex-end; gap: var(--e3); }
.peso .cifra {
  font-family: var(--cifras); font-variant-numeric: tabular-nums;
  font-size: 11.5px; color: var(--texto-2); min-width: 38px; text-align: right;
}

.barra-consumo {
  position: relative; height: 6px; border-radius: 3px;
  background: var(--velo-3); overflow: hidden; min-width: 78px;
  box-shadow: var(--hundido);
}
.peso .barra-consumo { width: 104px; flex: none; }
.barra-consumo i {
  position: absolute; inset: 0 auto 0 0; border-radius: 3px;
  animation: crecer .55s var(--curva) both;
}
.barra-consumo i.verde  { background: linear-gradient(90deg, var(--verde-hondo), var(--verde)); }
.barra-consumo i.ambar  { background: linear-gradient(90deg, var(--ambar-hondo), var(--ambar)); }
.barra-consumo i.rojo   { background: linear-gradient(90deg, var(--rojo-hondo), var(--rojo)); }
.barra-consumo i.laton  { background: linear-gradient(90deg, var(--laton-hondo), var(--laton-claro)); }
.barra-consumo i.bronce { background: linear-gradient(90deg, var(--laton-hondo), var(--laton-claro)); }

@keyframes crecer { from { transform: scaleX(0); transform-origin: left; } }

/* El ancho va por clase y no por atributo `style`: la CSP es `style-src 'self'`, que
   tambien descarta los atributos style, y una barra sin ancho no se ve. */
.w0 { width: 0 }
.w5 { width: 5% }
.w10 { width: 10% }
.w15 { width: 15% }
.w20 { width: 20% }
.w25 { width: 25% }
.w30 { width: 30% }
.w35 { width: 35% }
.w40 { width: 40% }
.w45 { width: 45% }
.w50 { width: 50% }
.w55 { width: 55% }
.w60 { width: 60% }
.w65 { width: 65% }
.w70 { width: 70% }
.w75 { width: 75% }
.w80 { width: 80% }
.w85 { width: 85% }
.w90 { width: 90% }
.w95 { width: 95% }
.w100 { width: 100% }


/* =========================================================================
   GRAFICOS EN SVG
   La CSP prohibe JavaScript, asi que no hay libreria de graficos posible. El SVG
   se arma en la plantilla con atributos de presentacion (que la CSP no bloquea,
   porque no son CSS) y se pinta desde aca. De paso resuelve algo que las clases
   .w0-.w100 no pueden: anchos exactos y no redondeados al 5%.
   ========================================================================= */
.g-pista { fill: var(--velo-3); }
.g-relleno { transform-box: fill-box; transform-origin: left center; animation: crecer .6s var(--curva) both; }
.g-relleno.verde { fill: var(--verde); }
.g-relleno.ambar { fill: var(--ambar); }
.g-relleno.rojo  { fill: var(--rojo); }
.g-relleno.laton { fill: var(--laton); }
.g-relleno.tenue { fill: var(--superficie-3); }
.g-barra, .g-par { display: block; overflow: visible; }
/* Linea del 100% sobre las barras de consumo: lo que la cruza se paso del presupuesto. */
.g-marca { stroke: var(--borde-fuerte); stroke-width: 1; stroke-dasharray: 2 2; }

/* Dona de dos aros: plata gastada contra obra construida. La comparacion es el
   argumento de venta entero, asi que va en una sola figura y no en dos numeros. */
.dona { display: block; }
.dona .pista { fill: none; stroke: var(--velo-3); }
.dona .arco {
  fill: none; stroke-linecap: round;
  /* El arco arranca arriba y no a las 3 en punto. `view-box` es el valor por
     defecto en SVG, pero se deja escrito: si alguien lo cambia a fill-box, el
     centro de giro pasa a ser el del trazo y el arco se va de la figura. */
  transform: rotate(-90deg); transform-box: view-box; transform-origin: center;
  animation: girar 1s var(--curva) both;
}
.dona .arco.verde { stroke: var(--verde); }
.dona .arco.ambar { stroke: var(--ambar); }
.dona .arco.rojo  { stroke: var(--rojo); }
.dona .arco.laton { stroke: var(--laton); }
.dona .arco.frio  { stroke: var(--frio); }
.dona .cifra {
  fill: var(--texto); font-family: var(--cifras); font-size: 21px; font-weight: 500;
  text-anchor: middle; letter-spacing: -.04em;
}
.dona .rotulo {
  fill: var(--tenue); font-family: var(--sans); font-size: 8.5px; font-weight: 700;
  text-anchor: middle; letter-spacing: .12em; text-transform: uppercase;
}
/* El arco se dibuja al entrar. Se anima el offset y no el dasharray porque el
   dasharray lo pone la plantilla y es distinto en cada figura. */
@keyframes girar { from { stroke-dashoffset: 290; } to { stroke-dashoffset: 0; } }

/* Bloque de dos donas con su leyenda, para el detalle de obra. */
.medidores {
  display: flex; align-items: center; gap: var(--e6); flex-wrap: wrap;
  padding: var(--e2) 0;
}
.medidor { display: flex; align-items: center; gap: var(--e4); }
.medidor-texto span {
  display: block; color: var(--tenue); font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em;
}
.medidor-texto strong {
  display: block; margin-top: 3px; font-family: var(--cifras);
  font-size: 19px; font-weight: 500; letter-spacing: -.03em;
}
.medidor-texto em { display: block; color: var(--tenue); font-size: 11px; margin-top: 2px; }


/* =========================================================================
   FORMULARIOS
   La administracion carga cien gastos por semana. Cada milimetro de friccion
   aca se multiplica por cien.
   ========================================================================= */
.grilla { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--e3) var(--e4); }
label {
  display: block; font-size: 9.5px; color: var(--tenue); margin-bottom: 5px;
  text-transform: uppercase; letter-spacing: .11em; font-weight: 700;
}
input, select, textarea {
  width: 100%; padding: 9px 12px;
  background-color: var(--pozo); color: var(--texto);
  border: 1px solid var(--borde-medio); border-radius: var(--r1);
  font-family: inherit; font-size: 13px;
  transition: border-color var(--rapido), box-shadow var(--rapido), background-color var(--rapido);
}
input::placeholder, textarea::placeholder { color: var(--marca-agua); }
/* Los montos se tipean en cifras tabulares, igual que como se leen despues. */
input[name=monto], input[name*=monto], input[type=number], input[name*=porcentaje],
input[name*=cantidad], input[name*=precio] {
  font-family: var(--cifras); font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
input:hover, select:hover, textarea:hover { border-color: var(--borde-fuerte); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--laton);
  /* `background-color` y no el atajo `background`: el atajo resetea background-image,
     y con eso desaparecia la flecha del desplegable justo en el campo enfocado. */
  background-color: var(--pozo-foco);
  box-shadow: 0 0 0 3px rgba(207, 164, 81, .17);
}
select {
  /* La flecha del select nativo en Windows es gris sobre oscuro y se pierde.
     Va dibujada como SVG embebido: img-src permite data:, y no es un `style` inline. */
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%237f92b0' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  padding-right: 32px;
}
textarea { resize: vertical; min-height: 66px; line-height: 1.5; }
/* Las opciones del desplegable las pinta el sistema operativo, no la pagina: en
   Windows con tema claro salian blancas sobre blanco al abrirse. */
select option { background: var(--superficie-2); color: var(--texto); }

button, .boton {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 16px; border-radius: var(--r1); cursor: pointer;
  background: linear-gradient(180deg, var(--laton-claro), var(--laton) 55%, #b98f3f);
  color: var(--sobre-laton); border: 1px solid rgba(0, 0, 0, .28);
  font-family: inherit; font-size: 12.5px; font-weight: 600; letter-spacing: .005em;
  white-space: nowrap;
  box-shadow: inset 0 1px 0 var(--filo-boton), 0 2px 8px rgba(207, 164, 81, .18);
  transition: filter var(--rapido), transform .07s var(--curva), box-shadow var(--rapido);
}
button:hover, .boton:hover {
  filter: brightness(1.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 4px 14px rgba(207, 164, 81, .3);
}
button:active, .boton:active { transform: translateY(1px); box-shadow: inset 0 1px 3px rgba(0, 0, 0, .3); }
.boton.secundario, button.secundario {
  background: var(--superficie-2); color: var(--texto);
  border-color: var(--borde-medio); font-weight: 500;
  box-shadow: var(--filo);
}
.boton.secundario:hover, button.secundario:hover {
  background: var(--superficie-3); border-color: var(--borde-fuerte); filter: none;
  box-shadow: var(--filo);
}
button.link {
  background: none; border: none; color: var(--tenue); box-shadow: none;
  padding: 4px 2px; font-weight: 500; text-decoration: underline; text-underline-offset: 3px;
}
button.link:hover { color: var(--texto); filter: none; box-shadow: none; }
button.mini, .boton.mini { padding: 5px 10px; font-size: 11px; }

.filtros { display: flex; gap: var(--e2); align-items: flex-end; flex-wrap: wrap; }
.filtros > div { min-width: 148px; }
.filtros button { margin-bottom: 0; }


/* =========================================================================
   AVISOS
   Tres niveles y una sola forma: franja de color, titulo en negrita, frase.
   El texto dice que pasa; el color solo lo confirma.
   ========================================================================= */
.aviso {
  position: relative;
  padding: 12px 15px 12px 17px; border-radius: var(--r2); margin-bottom: var(--e4);
  font-size: 13px; line-height: 1.5;
  border: 1px solid var(--borde); background: var(--superficie);
  box-shadow: var(--sombra-1);
}
.aviso::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  border-radius: var(--r2) 0 0 var(--r2);
}
.aviso strong { font-weight: 600; }
.aviso.error  { background: var(--rojo-tinte);  border-color: var(--rojo-borde); }
.aviso.error::before  { background: var(--rojo); }
.aviso.ok     { background: var(--verde-tinte); border-color: var(--verde-borde); }
.aviso.ok::before     { background: var(--verde); }
.aviso.alerta { background: var(--ambar-tinte); border-color: var(--ambar-borde); }
.aviso.alerta::before { background: var(--ambar); }

/* Aviso grande: el titular de la pantalla cuando hay una obra perdiendo plata.
   Ocupa lugar a proposito. Es lo que el dueno tiene que ver desde la puerta. */
.aviso.grande {
  padding: var(--e4) var(--e5) var(--e4) calc(var(--e5) + 2px);
  border-radius: var(--r3);
  display: flex; align-items: center; gap: var(--e4); flex-wrap: wrap;
}
.aviso.grande::before { width: 4px; }
.aviso.grande .titular {
  font-family: var(--display); font-size: 20px; font-weight: 600; line-height: 1.25;
  display: block; margin-bottom: 3px;
}
.aviso.grande .detalle { color: var(--texto-2); font-size: 13px; }
.aviso.grande .cifra-alerta {
  margin-left: auto; text-align: right; flex: none;
  font-family: var(--cifras); font-size: 30px; font-weight: 500; letter-spacing: -.04em;
}
.aviso.grande .cifra-alerta small {
  display: block; font-family: var(--sans); font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em; color: var(--tenue);
}


/* =========================================================================
   LOGIN
   La primera pantalla que ve el cliente, y la unica sin barra. Va partida: a la
   izquierda el argumento, a la derecha la puerta. En un telefono se apila y el
   argumento queda arriba, que es donde igual se lee primero.
   ========================================================================= */
.login-pantalla {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(340px, 400px);
  gap: var(--e8);
  align-items: center;
  min-height: calc(100vh - var(--e6) - var(--e8));
  max-width: 1080px; margin: 0 auto;
}

.login-pitch { animation: subir .55s var(--curva) both; }
.marca-login { display: flex; align-items: flex-start; gap: var(--e3); margin-bottom: var(--e5); }
.marca-login .logo-icon { width: 44px; height: 44px; font-size: 17px; border-radius: 13px; flex: none; }
.login-pitch h1 { font-size: 27px; margin: 0 0 3px; }
.login-pitch p.sub { color: var(--tenue); font-size: 13px; margin: 0; }

/* La frase que resume el producto. Es lo unico grande de la pantalla a proposito. */
.login-frase {
  font-family: var(--display); font-size: 33px; font-weight: 400; line-height: 1.25;
  letter-spacing: -.015em; margin: 0 0 var(--e6); max-width: 19ch;
  color: var(--texto);
}
.login-frase::after {
  content: ''; display: block; width: 64px; height: 2px; margin-top: var(--e4);
  background: linear-gradient(90deg, var(--laton-claro), transparent);
}

.login-puntos { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e4); max-width: 52ch; }
.login-puntos li {
  position: relative; padding-left: var(--e5);
  color: var(--texto-2); font-size: 13px; line-height: 1.55;
}
/* Marca de cota, como en un plano. */
.login-puntos li::before {
  content: ''; position: absolute; left: 0; top: 8px;
  width: 9px; height: 9px; border-radius: 2px;
  border: 1.5px solid var(--laton); transform: rotate(45deg);
}
.login-puntos strong { color: var(--texto); font-weight: 600; display: block; }

.login-caja {
  background: linear-gradient(180deg, var(--superficie), var(--barra-alta));
  border: 1px solid var(--borde-medio);
  border-radius: var(--r4); padding: var(--e6);
  box-shadow: var(--sombra-3), var(--filo);
  animation: subir .55s var(--curva) .1s both;
  position: relative; overflow: hidden;
}
/* Filo de laton en el canto superior de la caja. */
.login-caja::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--laton), transparent);
}
.login-caja h2 {
  margin: 0 0 var(--e4); font-size: 19px;
  padding-bottom: var(--e3); border-bottom: 1px solid var(--borde);
}
.login-caja label { margin-top: var(--e4); }
.login-caja button { width: 100%; margin-top: var(--e5); padding: 12px; font-size: 13.5px; }
.login-pie {
  margin: var(--e5) 0 0; padding-top: var(--e4); border-top: 1px solid var(--borde);
  color: var(--tenue); font-size: 11px; line-height: 1.6; text-align: center;
}

@media (max-width: 900px) {
  .login-pantalla {
    grid-template-columns: 1fr; gap: var(--e6); min-height: 0;
    padding-top: var(--e4); max-width: 480px;
  }
  .login-frase { font-size: 26px; max-width: none; margin-bottom: var(--e5); }
  .login-puntos { gap: var(--e3); }
  .login-caja { padding: var(--e5); }
}


/* =========================================================================
   PANEL DEL JEFE
   La regla de esta pantalla: se entiende en cinco segundos, en un celular, sin
   tocar nada. Una tarjeta por obra, una franja de color y una frase.
   ========================================================================= */
.tarjetas-obra {
  display: grid; gap: var(--e4);
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
}
.obra-card {
  position: relative; overflow: hidden;
  background: linear-gradient(180deg, var(--superficie), var(--superficie-baja));
  border: 1px solid var(--borde);
  border-radius: var(--r3); padding: var(--e4) var(--e5);
  box-shadow: var(--sombra-2), var(--filo);
  display: flex; flex-direction: column; gap: var(--e3);
  animation: subir .42s var(--curva) both;
  transition: border-color var(--rapido), transform var(--medio), box-shadow var(--medio);
}
.obra-card:hover { transform: translateY(-2px); box-shadow: var(--sombra-3), var(--filo); }
/* Franja de estado a la izquierda: es lo primero que se ve, antes de leer una palabra. */
.obra-card::before { content: ''; position: absolute; inset: 0 auto 0 0; width: 4px; }
.obra-card.verde::before { background: var(--verde); }
.obra-card.ambar::before { background: var(--ambar); }
.obra-card.rojo::before  { background: var(--rojo); }
.obra-card.rojo { border-color: var(--rojo-borde); }
.obra-card.rojo:hover { border-color: rgba(240, 100, 92, .55); }

.obra-card-top { display: flex; align-items: flex-start; gap: var(--e3); }
.obra-card-top strong { font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
.obra-card-top > div:first-child { flex: 1; min-width: 0; }
.obra-card-top a:hover strong { color: var(--laton-claro); }

.obra-card-datos { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--e3) var(--e4); }
.obra-card-datos span {
  display: block; font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .11em; color: var(--tenue); font-weight: 700;
}
.obra-card-datos strong {
  display: block; margin-top: 3px;
  font-family: var(--cifras); font-size: 20px; font-weight: 500;
  font-variant-numeric: tabular-nums; letter-spacing: -.035em;
}
.obra-card-datos strong.texto {
  font-family: var(--sans); font-size: 13px; font-weight: 500; letter-spacing: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.obra-card-barra { display: flex; align-items: center; gap: var(--e3); }
.obra-card-barra .barra-consumo { flex: 1; }

.obra-card-nota {
  margin: 0; padding: 10px 12px; border-radius: var(--r1);
  background: var(--superficie-2); font-size: 12.5px;
  display: flex; align-items: flex-start; gap: var(--e2);
}
.obra-card-pie {
  display: flex; gap: var(--e4); padding-top: var(--e2); margin-top: auto;
  border-top: 1px solid var(--borde); font-size: 12.5px;
}
.obra-card-pie a { color: var(--laton); font-weight: 500; }
.obra-card-pie a:hover { color: var(--laton-claro); text-decoration: underline; text-underline-offset: 3px; }


/* =========================================================================
   NOVEDADES
   ========================================================================= */
.lista-novedades { display: grid; gap: var(--e3); }
.novedad {
  border: 1px solid var(--borde); border-left: 3px solid var(--tenue);
  border-radius: var(--r2); padding: var(--e3) var(--e4);
  background: var(--superficie);
  display: flex; flex-direction: column; gap: 7px;
}
.novedad.alta  { border-left-color: var(--rojo); }
.novedad.media { border-left-color: var(--ambar); }
.novedad.baja  { border-left-color: var(--verde); }
.novedad.resuelta { opacity: .62; }
.novedad-cabecera { display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap; }
.novedad-detalle { margin: 0; color: var(--texto-2); font-size: 12.5px; }
.novedad-resolucion {
  margin: 0; padding: 9px 12px; border-radius: var(--r1);
  background: var(--verde-tinte); border: 1px solid var(--verde-borde); font-size: 12.5px;
}


/* =========================================================================
   UTILITARIAS
   Existen porque la CSP bloquea el atributo `style`: cualquier ajuste puntual
   de layout tiene que tener nombre y vivir en esta hoja.
   ========================================================================= */
.mt { margin-top: var(--e3); }
.mb { margin-bottom: var(--e4); }
.fila-botones { margin-top: var(--e4); display: flex; gap: var(--e2); flex-wrap: wrap; }
.angosta { max-width: 940px; }
.angosta-media { max-width: 840px; }
.angosta-chica { max-width: 660px; }
.min-auto { min-width: auto; }
.casilla { width: auto; margin-right: 6px; vertical-align: -1px; accent-color: var(--laton); }
.derecha { text-align: right; }
.corta { width: 138px; }
.etiqueta-fila {
  margin: 0; font-size: 13px; color: var(--texto);
  text-transform: none; letter-spacing: 0; font-weight: 400;
}
.vacio {
  color: var(--tenue); text-align: center; padding: var(--e7) var(--e4); font-size: 13px;
  border: 1px dashed var(--borde-medio); border-radius: var(--r2);
  background: var(--pozo-hondo);
}
.chico { font-size: 11px; color: var(--tenue); }
.linea-acciones { display: flex; gap: 6px; align-items: center; }
.linea-acciones input[type=text] { width: 132px; padding: 5px 8px; font-size: 11px; }
/* Visible solo para lectores de pantalla: un encabezado de tabla que en pantalla
   seria ruido pero sin el cual la columna del semaforo no se anuncia. `display:none`
   no sirve, porque tambien se lo esconde al lector. */
.solo-lectura {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

.caja-error { max-width: 540px; margin: 13vh auto; text-align: center; }
.caja-error h1 {
  font-family: var(--cifras); font-size: 52px; margin: 0; color: var(--tenue);
  letter-spacing: -.05em; font-weight: 500;
}
.caja-error p { margin: var(--e3) 0 var(--e5); color: var(--texto-2); }


/* =========================================================================
   CELULAR
   La barra tiene siete secciones: en un telefono no entran en una linea. En vez
   de apretarlas hasta que se corten, la barra se apila y el menu se desliza.
   ========================================================================= */
@media (max-width: 1080px) {
  .barra { gap: var(--e3); padding: 0 var(--e4); }
  .nav a { padding: 7px 9px; font-size: 12px; }
}

@media (max-width: 860px) {
  .barra {
    height: auto; flex-wrap: wrap; gap: 10px var(--e4); padding: 10px var(--e4);
  }
  .nav {
    order: 3; width: 100%; margin-left: 0;
    overflow-x: auto; flex-wrap: nowrap;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    padding-bottom: 2px;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { white-space: nowrap; }
  .usuario { margin-left: auto; }
  .usuario em { display: none; }

  .contenido { padding: var(--e4) var(--e4) var(--e7); }
  .encabezado h1 { font-size: 23px; }
  .kpi > strong { font-size: 20px; }
  .kpi.principal > strong { font-size: 26px; }
  .kpi.principal { grid-column: auto; }
  .acciones { margin-left: 0; width: 100%; }
  .columnas { grid-template-columns: 1fr; }
  .tabla-scroll { margin: 0 calc(var(--e4) * -1) calc(var(--e4) * -1); padding: 0 var(--e4) var(--e2); }
  .tarjeta { padding: var(--e4); }
  .aviso.grande .cifra-alerta { margin-left: 0; text-align: left; }
}

@media (max-width: 540px) {
  .tarjetas-obra { grid-template-columns: 1fr; }
  .obra-card-datos { gap: 10px var(--e3); }
  .obra-card-datos strong { font-size: 18px; }
  .medidores { gap: var(--e4); }
}


/* =========================================================================
   IMPRESION
   El cierre se manda al contador. Si se imprime desde el navegador tiene que
   salir en papel blanco y legible, no en negativo gastando un cartucho.
   ========================================================================= */
/* Una tarjeta que se pliega. El resumen tiene que verse como el titulo de una tarjeta
   normal, no como un renglon de lista, porque ocupa el mismo lugar visual. */
details.tarjeta > summary {
  cursor: pointer; list-style: none; display: flex; align-items: baseline;
  gap: var(--e3); justify-content: space-between; flex-wrap: wrap;
}
details.tarjeta > summary::-webkit-details-marker { display: none; }
details.tarjeta > summary strong {
  font-family: var(--display); font-size: 17px; font-weight: 600; color: var(--texto);
}
details.tarjeta > summary::after {
  content: 'ver'; font: 600 10px var(--sans); letter-spacing: .12em;
  text-transform: uppercase; color: var(--laton); order: 3;
}
details.tarjeta[open] > summary::after { content: 'ocultar'; }
details.tarjeta > summary:focus-visible { outline: 2px solid var(--laton); outline-offset: 3px; }

/* --- Roles de un tercero ------------------------------------------------------------
   Tres casillas que se leen como una sola pregunta ("es..."), no como tres campos
   sueltos. `fieldset` con `legend` es lo que dice eso en HTML, y ademas es lo que hace
   que un lector de pantalla las anuncie juntas. */
fieldset.roles {
  border: 1px solid var(--borde-medio); border-radius: var(--r1);
  padding: var(--e2) var(--e3) var(--e3); margin: 0; min-width: 0;
  display: flex; gap: var(--e3); align-items: center; flex-wrap: wrap;
}
fieldset.roles legend {
  font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--tenue); padding: 0 var(--e2);
}
fieldset.roles label {
  display: inline-flex; align-items: center; gap: var(--e2); margin: 0;
  font-size: 13px; font-weight: 500; color: var(--texto-2); white-space: nowrap;
}
fieldset.roles input[type=checkbox] { width: auto; margin: 0; accent-color: var(--laton-vivo); }

/* --- Pendientes del panel -----------------------------------------------------------
   Una lista de decisiones, no una tabla: cada renglon es un enlace entero al lugar donde
   se resuelve, con el monto anclado a la derecha para que la columna de plata se lea
   sola de arriba a abajo. */
.lista-pendientes { list-style: none; margin: 0; padding: 0; }
.lista-pendientes li + li { border-top: 1px solid var(--borde); }
.lista-pendientes a {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: var(--e3); padding: var(--e3) var(--e2); text-decoration: none; color: inherit;
  border-radius: var(--radio-2);
}
.lista-pendientes a:hover { background: var(--velo-2); }
.lista-pendientes a:focus-visible { outline: 2px solid var(--laton); outline-offset: -2px; }
.lista-pendientes .que { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.lista-pendientes .que strong { font-weight: 600; }
.lista-pendientes .que em {
  font-style: normal; font-size: .84em; color: var(--texto-tenue);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lista-pendientes .cuanto {
  font-family: var(--cifras); font-variant-numeric: tabular-nums; white-space: nowrap;
}
@media (max-width: 640px) {
  .lista-pendientes a { grid-template-columns: auto 1fr; row-gap: var(--e2); }
  .lista-pendientes .cuanto { grid-column: 2; }
}

/* --- Cronograma en barras -----------------------------------------------------------
   El SVG se estira al ancho de su celda (`preserveAspectRatio="none"` + width 100%), asi
   que todas las filas comparten el mismo eje aunque la tabla cambie de tamano. */
.g-gantt, .g-eje { display: block; width: 100%; height: auto; overflow: visible; }
.g-plan { fill: var(--superficie-3); }
.g-real.verde { fill: var(--verde); }
.g-real.ambar { fill: var(--ambar); }
.g-real.rojo  { fill: var(--rojo); }
.g-real.laton { fill: var(--laton); }
.g-real.tenue { fill: var(--borde-fuerte); }
/* Hoy: la unica linea llena del grafico. El resto son punteadas o rellenos. */
.g-hoy { stroke: var(--laton-claro); stroke-width: 1.5; opacity: .85; }
.g-tic { stroke: var(--borde-fuerte); stroke-width: 1; }
.g-mes {
  fill: var(--texto-tenue); font-family: var(--cifras); font-size: 9px;
  letter-spacing: .06em; text-transform: uppercase;
}
table.gantt { table-layout: fixed; width: 100%; min-width: 44rem; }
table.gantt col.c-etapa { width: 27%; }
table.gantt col.c-barra { width: 51%; }
table.gantt col.c-monto { width: 22%; }
.gantt-fila td { vertical-align: middle; padding-block: var(--e2); }
/* La barra mide 22px de alto: una fila de 60 la deja flotando en el medio de la nada. */
.gantt-fila td.celda-barra { padding-block: var(--e1); }
.gantt th.celda-barra { padding-block: 0 var(--e1); vertical-align: bottom; }
/* La franja de la etapa en curso, para encontrarla sin leer los estados. */
tr.gantt-fila.en-curso td:first-child { box-shadow: inset 3px 0 0 var(--laton); }

/* El desglose que se abre desde el monto de la etapa. Va dentro de una celda numerica,
   asi que el `summary` tiene que seguir alineado a la derecha como si fuera el numero. */
.gantt details > summary {
  cursor: pointer; list-style: none; display: inline-flex; align-items: center;
  gap: var(--e2); justify-content: flex-end; width: 100%;
}
.gantt details > summary::-webkit-details-marker { display: none; }
.gantt details > summary::after {
  content: '+'; font-family: var(--cifras); font-size: .85em; line-height: 1;
  color: var(--texto-tenue); border: 1px solid var(--borde-fuerte);
  width: 1.15em; height: 1.15em; display: grid; place-items: center; border-radius: 3px;
}
.gantt details[open] > summary::after { content: '2'; color: var(--laton); border-color: var(--laton); }
.gantt details[open] > summary { color: var(--laton); }
table.desglose { margin-top: var(--e2); font-size: .86em; width: 100%; }
table.desglose td { border: none; padding: 1px 0; color: var(--texto-tenue); }
table.desglose td.num { color: var(--texto); }
.bloque { display: block; }

/* --- Computo del presupuesto --------------------------------------------------------
   Una grilla de carga, no una tabla de lectura: las celdas son campos, el alto de fila
   baja y el foco tiene que verse sin buscarlo. */
table.presupuesto th { white-space: nowrap; }
table.presupuesto td { padding: var(--e2) var(--e2); vertical-align: middle; }
table.presupuesto input,
table.presupuesto select { width: 100%; min-width: 5.5rem; margin: 0; }
table.presupuesto td.angosta { width: 6rem; }
table.presupuesto input.corta { min-width: 4.5rem; }
/* La fila entera se tine mientras se escribe en ella: con seis columnas iguales, perder
   de vista en cual se esta es el error mas facil de cometer. */
table.presupuesto tr:focus-within td { background: var(--velo-1); }

@media print {
  /* El papel es blanco siempre, tenga el que imprime el tema que tenga.
     Antes esto se resolvia listando componente por componente y quedaban cosas afuera:
     un usuario en tema oscuro imprimia los campos del presupuesto con fondo negro,
     porque `--pozo` seguia valiendo lo del tema oscuro. Ahora se pisan los TOKENS y todo
     lo de abajo se acomoda solo, igual que hace el tema claro. */
  :root {
    --tinta: #fff; --tinta-alta: #fff;
    --superficie: #fff; --superficie-2: #f4f4f4; --superficie-3: #d8d8d8;
    --superficie-baja: #fff; --barra-alta: #fff; --barra-baja: #fff;
    --plano: transparent;
    --borde: #ccc; --borde-medio: #bbb; --borde-fuerte: #999;
    --texto: #111; --texto-2: #333; --tenue: #555;
    --laton: #7a5c22; --laton-claro: #6d531f; --laton-tenue: #f5eeda;
    --verde: #1b6b46; --verde-tinte: #eaf4ef; --verde-borde: #9fc9b4;
    --ambar: #7d5206; --ambar-tinte: #fbf1de; --ambar-borde: #d8bd85;
    --rojo:  #b3261e; --rojo-texto: #b3261e; --rojo-tinte: #fdecea; --rojo-borde: #e3aaa5;
    --velo-1: transparent; --velo-2: transparent; --velo-3: #e4e4e4;
    --pozo: #fff; --pozo-foco: #fff; --pozo-hondo: #f7f7f7;
    --hundido: none; --marca-agua: #888; --frio: #33517d;
    --sombra-1: none; --sombra-2: none; --sombra-3: none; --filo: none;
    --halo-laton: transparent; --halo-verde: transparent;
  }

  body { background: #fff; color: var(--texto); font-size: 10.5pt; }
  .barra, .acciones, .filtros, .fila-botones, .saltar, form { display: none !important; }
  /* Salvo el presupuesto, que ES un formulario y a la vez el documento que se imprime.
     Los campos se muestran, sin marco, como si fueran texto. */
  form:has(table.presupuesto) { display: block !important; }
  table.presupuesto input, table.presupuesto select {
    border: none; background: none; color: var(--texto); padding: 0;
    -webkit-appearance: none; appearance: none;
  }
  .contenido { padding: 0; max-width: none; }
  .tarjeta, .kpi, .obra-card {
    background: #fff; border: 1px solid #bbb; box-shadow: none; break-inside: avoid;
  }
  th { background: #f2f2f2; }
  tr.fila-rojo { background: var(--rojo-tinte) !important; }
  .negativo { color: var(--rojo); }
  .positivo { color: var(--verde); }
  a { text-decoration: none; }
  .tabla-scroll { overflow: visible; margin: 0; padding: 0; }
  /* Los graficos SVG se dibujan con los tokens de arriba, asi que ya salen en tinta.
     Solo hay que asegurarse de que el navegador no descarte los rellenos. */
  .g-barra, .g-par, .g-gantt, .g-eje, .dona { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
}


/* Quien pidio que nada se mueva, que nada se mueva. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}

/* Los codigos de obra dentro de un aviso son enlaces: si no se subrayan, nadie
   descubre que se puede hacer click justo en el dato que importa. */
.aviso a {
  color: inherit; text-decoration: underline; text-underline-offset: 3px;
  text-decoration-thickness: 1px; text-decoration-color: var(--velo-subrayado);
}
.aviso a:hover { text-decoration-color: currentColor; }

/* Registro crudo de auditoria, plegado. `details` es HTML nativo: se abre y se cierra
   sin una linea de JavaScript, que es lo unico que la CSP permite. */
details.crudo { margin-top: 6px; }
details.crudo > summary {
  cursor: pointer; color: var(--tenue); font-size: 10.5px; width: fit-content;
  list-style: none; display: flex; align-items: center; gap: 5px;
}
details.crudo > summary::-webkit-details-marker { display: none; }
details.crudo > summary::before {
  content: '+'; font-family: var(--cifras); font-weight: 600;
  display: grid; place-items: center; width: 14px; height: 14px; border-radius: 4px;
  background: var(--superficie-2); border: 1px solid var(--borde);
}
details.crudo[open] > summary::before { content: '-'; }
details.crudo > summary:hover { color: var(--texto); }
details.crudo > div {
  margin-top: 6px; padding: 10px 12px; border-radius: var(--r1);
  background: var(--pozo); border: 1px solid var(--borde);
  max-width: 620px;
}
details.crudo pre {
  margin: 5px 0 10px; font-family: var(--cifras); font-size: 10.5px; line-height: 1.45;
  color: var(--texto-2); white-space: pre-wrap; word-break: break-word;
}
details.crudo pre:last-child { margin-bottom: 0; }

/* Llave de color de la leyenda: cuadradito que ata cada aro de la dona con su renglon. */
.llave {
  display: inline-block; width: 9px; height: 9px; border-radius: 3px;
  margin-right: 7px; vertical-align: 0;
}
.llave.verde { background: var(--verde); }
.llave.ambar { background: var(--ambar); }
.llave.rojo  { background: var(--rojo); }
.llave.frio  { background: var(--frio); }
.medidor-texto span { display: flex; align-items: center; }

/* El "Gs." de una cifra grande va mas chico y mas tenue: la plata es el numero, no
   el simbolo. Lo pone el filtro `gsx`. */
.kpi > strong small,
.cifra-alerta small.moneda {
  font-size: .52em; font-weight: 500; color: var(--tenue);
  margin-right: .32em; letter-spacing: 0;
}

/* Enlace de texto dentro de una tabla: sin subrayado no se descubre que es un enlace. */
a.enlace { color: var(--laton); text-decoration: underline; text-underline-offset: 3px; }
a.enlace:hover { color: var(--laton-claro); }

/* La fila a la que se llego desde un enlace con ancla. Sin esto el navegador scrollea
   hasta ella y el ojo tiene que encontrarla igual entre noventa filas iguales. */
tr:target { scroll-margin-top: 90px; }
tr:target td {
  background: var(--laton-tenue);
  box-shadow: inset 0 1px 0 var(--laton), inset 0 -1px 0 var(--laton);
  animation: destello 2.2s var(--curva) both;
}
tr:target td:first-child { box-shadow: inset 0 1px 0 var(--laton), inset 0 -1px 0 var(--laton), inset 3px 0 0 var(--laton); }
@keyframes destello {
  0%   { background: rgba(207, 164, 81, .42); }
  100% { background: var(--laton-tenue); }
}

/* --- Logo del cliente ---
   Se sirve desde /static/logos con ancho y alto calculados en el server: un <img> sin
   dimensiones reserva cero espacio y la barra pega un salto al cargar. */
.logo-img {
  display: block; height: auto; max-width: 100%;
  /* El logo esta hecho para papel blanco: el gris y el rojo sobre tinta quedan
     apagados. Se levanta el brillo lo justo para que se lea, sin cambiarle los
     colores a la marca. */
  filter: brightness(1.28) saturate(1.08);
}
.logo-sep { width: 1px; height: 26px; background: var(--borde-medio); flex: none; }
.logo-producto {
  color: var(--tenue); font-size: 10px; font-weight: 700; line-height: 1.25;
  text-transform: uppercase; letter-spacing: .1em; white-space: nowrap;
}
.marca-login .logo-img { margin-right: var(--e1); }

@media (max-width: 860px) {
  .logo-sep, .logo-producto { display: none; }
}


/* ======================================================================================
   TEMA CLARO — los pocos ajustes que no se resuelven con un token
   ======================================================================================
   Van al FINAL y no arriba con los tokens: una variable se resuelve donde se usa, asi
   que da igual donde se declare, pero una regla de componente que pisa a otra tiene que
   venir despues o pierde en la cascada. Costo un boton marron descubrirlo.
   ==================================================================================== */

@media (prefers-color-scheme: light) {
  /* El boton sigue siendo de metal en los dos temas. Los tokens `--laton` y
     `--laton-claro` se oscurecieron para que un enlace se lea sobre papel, y con esos
     valores el degradado daba un boton marron apagado. Aca vuelve el laton vivo. */
  button, .boton {
    background: linear-gradient(180deg, #e6c684, #cfa451 55%, #b98f3f);
    border-color: rgba(80, 58, 12, .30);
    box-shadow: inset 0 1px 0 var(--filo-boton), 0 2px 8px rgba(138, 106, 43, .22);
  }
  button:hover, .boton:hover {
    background: linear-gradient(180deg, #f2dba6, #d8ae5c 55%, #c2973f);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6), 0 4px 14px rgba(138, 106, 43, .28);
  }
  /* El boton secundario sobre papel necesita un borde de verdad: sin fondo propio y con
     el borde tenue del tema oscuro, se pierde. */
  button.secundario, .boton.secundario {
    background: var(--superficie); border-color: var(--borde-fuerte); color: var(--texto);
  }
  button.secundario:hover, .boton.secundario:hover { background: var(--superficie-2); }

  /* La barra superior en claro no lleva degradado: sobre papel una franja degradada se
     ve sucia. Una linea firme abajo alcanza para separarla. */
  .barra { background: var(--superficie); border-bottom: 1px solid var(--borde-medio); }

  /* El logo de CX es rojo sobre blanco. En oscuro el recuadro le da cuerpo; en claro
     compite con el papel y con el rojo de las alertas. Se deja el logo solo. */
  .logo-icon { box-shadow: none; }
}
