/* Sistema visual de Informes PS.
   Tema unico y claro: el informe es una pieza de lectura, casi impresa, y por eso no tiene
   modo oscuro. Los colores no se eligieron a ojo: salen del sistema de Serenity, que ya los
   tiene medidos, y los dos que no estaban ahi -el de la meta- se midieron antes de usarlos.
   Los contrastes anotados estan medidos contra el fondo #f4f1e9. */

/* Inter y Cormorant Garamond, servidas por el propio sitio.
   No van por Google Fonts: la CSP de este Host declara `font-src 'self'`, asi que una fuente
   de otro dominio no cargaria y el navegador no avisa: se ve el respaldo y parece que el
   cambio no se aplico. Ademas un informe interno no tiene por que avisarle a un tercero cada
   vez que alguien lo abre.

   Son las mismas dos familias del sistema visual de Parque Serenidad. Inter lleva TODO el
   texto del informe, incluidos los datos: es la que tiene cifras tabulares, que es lo que
   alinea las columnas de guaranies. Cormorant lleva UNICAMENTE el titulo del informe y el de
   la portada de la hoja de lectura. Una serif de display en un rotulo, un boton o una cifra
   se lee peor y mas lento, que es lo contrario de lo que este documento necesita. */
@font-face {
  font-family: "Inter Variable";
  font-style: normal; font-display: swap; font-weight: 100 900;
  src: url("psinformes-assets/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter Variable";
  font-style: normal; font-display: swap; font-weight: 100 900;
  src: url("psinformes-assets/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal; font-display: swap; font-weight: 600;
  src: url("psinformes-assets/cormorant-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal; font-display: swap; font-weight: 600;
  src: url("psinformes-assets/cormorant-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* superficies: la crema del sistema de Serenity. El papel del informe. */
  --fondo: #f4f1e9;          /* crema-200 */
  --panel: #faf8f3;          /* crema-50, la tarjeta */
  --panel-hundido: #eae5da;  /* crema-200 */
  --panel-oscuro: #232c21;   /* tinta-800: barras y cabecera */

  /* lineas: recesivas a proposito, de la rampa de piedra */
  --linea-tenue: #f0ece4;    /* piedra-100 */
  --linea: #e3ded3;          /* piedra-200 */
  --linea-fuerte: #cfc9bb;   /* piedra-300, 1,46:1 */

  /* tinta. Medido contra el fondo #f4f1e9 */
  --tinta-1: #232c21;        /* 12,80:1 */
  --tinta-2: #4a5344;        /*  7,12:1 */
  --tinta-3: #6b6558;        /*  5,13:1 */
  --tinta-clara: #f4f1e9;    /* sobre superficies oscuras */

  /* SERIES. La paleta es de neutros calidos: ningun color salvo la meta llega al croma que
     haria falta para distinguir series por tono. Funciona igual porque cada grafico del
     informe tiene UN dato y a lo sumo UNA referencia, y esos dos se separan por tono.
     REGLA DURA: si alguna vez un grafico necesita tres series de verdad, esta paleta NO
     alcanza y hay que medir colores nuevos antes de inventarlos. Por eso la mezcla de
     servicios es una barra por servicio y no un anillo de ocho gajos. */
  --serie-dato: #45543c;       /* salvia-700, 7,19:1 contra el fondo */
  --serie-referencia: #cfc9bb; /* piedra-300: pistas y fondos, NUNCA un dato */
  --serie-contraste: #232c21;  /* un segundo dato, si alguna vez hace falta */

  /* LA SEGUNDA SERIE, y solo con codificacion secundaria.
     Medida contra --serie-dato: 22,4 de separacion perceptual en vision normal, 19,4 en
     protanopia y 20,2 en deuteranopia, contra un piso de 23. Queda JUSTO por debajo y se usa
     igual porque nunca va sola: donde aparece, la serie de comparacion se dibuja rayada y mas
     fina, la de dato va solida con marcador, la leyenda las nombra y el tooltip muestra las dos.
     La alternativa mas separada -#a8a293, 34,7- da 2,4:1 contra el panel: se separa del dato pero
     no se ve. REGLA: si alguna vez se dibuja esta serie solida y del mismo grosor que el dato,
     este color deja de ser legal. */
  --serie-comparacion: #857f70;  /* piedra-500, 3,76:1 contra el panel */

  /* LA META Y LAS REFERENCIAS. Terracota, y el tono no se eligio a ojo.
     Medido contra #45543c -el dato- con distancia perceptual en Lab y con simulacion de
     dicromatismo: 56,6 en vision normal, 26,6 en protanopia y 41,8 en deuteranopia. El piso
     usado es 23, que es 2,2 veces la separacion del par que el informe de la INC prohibe
     expresamente por indistinguible. Contra el panel da 5,45:1.
     Se descartaron por medicion, no por gusto: el rojo ladrillo #9d3b30 del sistema cae a 4,8
     en protanopia -por debajo del par prohibido: en esa vision se confunde con el verde- y
     #a8482a cae a 14,6.
     NO es el rojo ni el amarillo de alerta del sistema de Serenity, aunque se parezca: la meta
     es una referencia, no un juicio. Una barra que la cruza por encima esta bien y una que se
     queda corta esta mal, segun la metrica. Lo que califica es el signo y el peso visual.
     OJO: contra el relleno de la barra da 1,2:1, o sea nada. Por eso toda linea de meta y todo
     punto de referencia lleva un halo del color del panel debajo; sin el, la meta desaparece
     justo en los meses en que cruza la barra, que son los que mas importan. */
  --serie-meta: #a34d12;

  /* ESTADO. Tambien de la paleta: no hay verde ni rojo de semaforo.
     Lo que esta por debajo usa la tinta mas fuerte, para que pese mas en la mirada. */
  --bueno: #6b6558;            /* 5,13:1, deliberadamente mas tenue */
  --atencion: #4a5344;         /* 7,12:1 */
  --critico: #232c21;          /* 12,80:1, el que se lleva la mirada */

  /* Acento de la interfaz: el estado activo de un control. */
  --acento: #45543c;           /* salvia-700 */
  --acento-fuerte: #36422f;    /* salvia-800 */

  /* Verde Parque, el canonico de la marca. Se reserva para marcas de marca: NO es un color
     de dato, y el informe no lo usa en ningun grafico. */
  --marca: #2f8a43;

  /* forma: un solo sistema de esquinas. Paneles rectos con 2px, controles pildora. */
  --radio-panel: 2px;
  --radio-bloque: 8px;
  --radio-control: 999px;

  --sans: "Inter Variable", Inter, ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
  /* Solo para el titulo del informe y el de la portada. Ver la nota de las fuentes. */
  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --mono: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, "Liberation Mono", monospace;

  /* motion: estado, no decoracion */
  --curva: cubic-bezier(0.22, 1, 0.36, 1);
  --rapido: 160ms;
  --normal: 220ms;

  color-scheme: light;
}


* { box-sizing: border-box; }

/* Digitos tabulares en todo lo que sea un numero: con las cifras enteras, cada guarani
   ocupa lo mismo y las columnas de la tabla y de la franja quedan alineadas. Sin esto el
   1 es mas angosto que el 8 y una columna de montos se ve temblorosa. */
.cifra, .cota-valor, .franja-valor, .franja-desv, .ficha-valor, .comparacion-valor,
.brecha-valor, .tick, .monto-texto, .etiqueta-dato, .etiqueta-meta, .cifra-anillo,
table td, table th {
  font-variant-numeric: tabular-nums;
}

body {
  margin: 0;
  background: var(--fondo);
  color: var(--tinta-1);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

/* Aviso de version nueva. Abajo y a la derecha: tiene que verse sin tapar el informe
   ni pedir que se lo atienda antes de seguir leyendo. */

/* ============ barra de la plataforma ============ */
.barra {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 20px;
  height: 56px;
  padding: 0 20px;
  background: var(--panel-oscuro);
  color: var(--tinta-clara);
  border-bottom: 1px solid var(--panel-oscuro);
}

.marca-plataforma {
  display: flex;
  /* center y no baseline: con el logo adentro, alinear por la linea base del texto deja
     la imagen colgando. */
  align-items: center;
  gap: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.marca-plataforma .nombre { color: var(--tinta-clara); }
.marca-plataforma .cliente { color: #b9b4b0; font-weight: 500; font-size: 12px; }

.barra-informes { display: flex; gap: 4px; margin-left: 12px; }

.pestania {
  appearance: none;
  border: 1px solid transparent;
  background: transparent;
  color: #d5d1ce;
  font: inherit;
  font-size: 13px;
  padding: 6px 14px;
  border-radius: var(--radio-control);
  cursor: pointer;
  transition: background var(--rapido) var(--curva), color var(--rapido) var(--curva), border-color var(--rapido) var(--curva);
}
.pestania:hover { background: #464a51; color: #fff; }
.pestania:active { transform: scale(0.98); }
.pestania[aria-selected="true"] {
  background: #4a4f57;
  color: #fff;
  border-color: #9aa79a;
}
.pestania:focus-visible { outline: 2px solid #9aa79a; outline-offset: 2px; }
.pestania[disabled] { color: #6f747b; cursor: not-allowed; }

.barra-acciones { margin-left: auto; display: flex; align-items: center; gap: 10px; }

.usuario {
  display: flex; align-items: center; gap: 8px;
  color: #d5d1ce; font-size: 13px;
}
.usuario .inicial {
  width: 26px; height: 26px; border-radius: var(--radio-control);
  display: grid; place-items: center;
  background: #4a4f57; color: #fff;
  font-size: 12px; font-weight: 700;
}

.boton {
  appearance: none;
  border: 1px solid var(--linea-fuerte);
  background: var(--panel);
  color: var(--tinta-1);
  font: inherit; font-size: 13px;
  padding: 7px 14px;
  border-radius: var(--radio-control);
  cursor: pointer;
  transition: background var(--rapido) var(--curva), transform var(--rapido) var(--curva), border-color var(--rapido) var(--curva);
}
.boton:hover { background: var(--panel-hundido); border-color: var(--tinta-3); }
.boton:active { transform: scale(0.98); }
.boton:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
.boton.primario { background: var(--acento); border-color: var(--acento); color: #fff; font-weight: 600; }
.boton.primario:hover { background: var(--acento-fuerte); border-color: var(--acento-fuerte); }

/* Los botones de la barra oscura llevan su propio traje. */
.barra .boton {
  background: transparent;
  border-color: #5b6068;
  color: #e8e5e2;
}
.barra .boton:hover { background: #464a51; border-color: #7c828b; }

/* ============ fila de filtros: una sola, arriba de todo lo que alcanza ============ */
.filtros {
  position: sticky;
  top: 56px;
  z-index: 25;
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
  padding: 12px 20px;
  background: var(--panel);
  border-bottom: 1px solid var(--linea);
}

.filtro { display: flex; align-items: center; gap: 10px; }
.filtro-etiqueta {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tinta-3);
}

.segmentos {
  display: inline-flex;
  padding: 3px;
  background: var(--panel-hundido);
  border: 1px solid var(--linea);
  border-radius: var(--radio-control);
}
.segmento {
  appearance: none; border: 0; background: transparent;
  color: var(--tinta-2); font: inherit; font-size: 13px;
  padding: 5px 14px; border-radius: var(--radio-control); cursor: pointer;
  transition: background var(--rapido) var(--curva), color var(--rapido) var(--curva);
}
.segmento:hover { color: var(--tinta-1); }
.segmento[aria-pressed="true"] { background: var(--acento); color: #fff; font-weight: 600; }
.segmento:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }

.meses { display: flex; gap: 3px; flex-wrap: wrap; }
.mes {
  appearance: none;
  border: 1px solid var(--linea);
  background: var(--panel);
  color: var(--tinta-2);
  font: inherit; font-size: 12px;
  min-width: 44px;
  padding: 5px 8px;
  border-radius: var(--radio-panel);
  cursor: pointer;
  transition: background var(--rapido) var(--curva), color var(--rapido) var(--curva), border-color var(--rapido) var(--curva);
}
.mes:hover:not([disabled]) { border-color: var(--tinta-3); color: var(--tinta-1); }
.mes[aria-pressed="true"] { background: var(--acento); border-color: var(--acento); color: #fff; font-weight: 700; }
.mes[disabled] { color: #a9a19e; cursor: not-allowed; border-style: dashed; background: var(--panel-hundido); }
.mes:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }

.zoom { margin-left: auto; display: flex; align-items: center; gap: 8px; color: var(--tinta-3); font-size: 12px; }

/* ============ lienzo ============ */
.escenario {
  padding: 28px 20px 60px;
  display: flex;
  justify-content: center;
}

.lienzo {
  position: relative;
  width: 1400px;
  height: 1980px;
  flex: none;
  transform-origin: top center;
  background: var(--panel);
  border: 1px solid var(--linea);
  box-shadow: 0 18px 44px rgba(54, 57, 63, 0.14);
}

/* ---- el logo institucional, en sus lugares ---- */
.marca-texto { display: flex; flex-direction: column; line-height: 1.2; }
.marca-logo {
  width: auto;
  height: 38px;
  flex: none;
}
.portada-logo {
  width: auto;
  height: 64px;
  margin: 0 auto 12px;
  display: block;
}

/* marcas de esquina: la unica cita al plano tecnico que sobrevive */
.esquina {
  position: absolute;
  width: 26px; height: 26px;
  border: 2px solid var(--linea-fuerte);
}
.esquina.si { top: 14px; left: 14px; border-right: 0; border-bottom: 0; }
.esquina.sd { top: 14px; right: 14px; border-left: 0; border-bottom: 0; }
.esquina.ii { bottom: 14px; left: 14px; border-right: 0; border-top: 0; }
.esquina.id { bottom: 14px; right: 14px; border-left: 0; border-top: 0; }

/* cabecera del informe */
.cabecera {
  position: absolute;
  top: 60px; left: 70px; right: 70px;
  text-align: center;
}
.cabecera-texto { width: 100%; }
.cabecera .titulo {
  margin: 0;
  font-family: var(--serif);
  font-size: 64px;
  line-height: 1.05;
  font-weight: 600;
  letter-spacing: 0;
  text-wrap: balance;
  color: var(--tinta-1);
}
.cabecera .subtitulo {
  margin: 12px 0 0;
  font-size: 16px;
  color: var(--tinta-2);
  text-wrap: balance;
}
.cabecera .periodo {
  margin-top: 14px;
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--tinta-3);
  border: 1px solid var(--linea);
  border-radius: var(--radio-panel);
  padding: 5px 12px;
}
.cabecera .regla { height: 1px; background: var(--linea); margin: 22px 0 0; }

.sello {
  position: absolute;
  top: 46px; left: 70px;
  width: auto;
  height: 104px;
}

.folio {
  position: absolute;
  top: 52px; right: 70px;
  border: 1px solid var(--linea-fuerte);
  border-radius: var(--radio-panel);
  padding: 10px 14px;
  text-align: right;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--tinta-3);
}
.folio b { display: block; font-size: 20px; color: var(--tinta-1); letter-spacing: 0; }

/* columnas de objetos */
.columna {
  position: absolute;
  top: 452px;
  width: 380px;
  display: flex;
  flex-direction: column;
  gap: 26px;
}
.columna.izquierda { left: 70px; }
.columna.derecha { right: 70px; }

/* Anatomia de bloque, calcada de los paneles de BIS INC: radio de 8px, relleno de
   16px, borde superior de acento de 2px y rotulo de 11px en mayusculas con tracking
   de 0.14em. Misma estructura para que las dos plataformas se lean igual. */
.objeto {
  position: relative;
  background: var(--fondo);
  /* El relleno del objeto se separa del lienzo blanco por solo 1,16:1, que es poco.
     Quien hace la separacion de verdad es el borde, y por eso es el paso fuerte. */
  border: 1px solid var(--linea-fuerte);
  border-top: 2px solid var(--acento);
  border-radius: var(--radio-bloque);
  padding: 16px;
}

.objeto-cabecera {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 12px;
  min-height: 26px;
}

.objeto-titulo {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  line-height: 1.35;
  color: var(--tinta-3);
}

/* Donde antes decia de que planilla salia el dato, ahora va una lectura de como se
   comporta la metrica. Es prosa, no un pie de pagina: se le da cuerpo de texto y una
   linea superior que la separa del grafico. */
.objeto-lectura {
  margin: 10px 0 0;
  padding-top: 8px;
  border-top: 1px solid var(--linea-tenue);
  font-size: 11px;
  line-height: 1.45;
  color: var(--tinta-2);
  text-wrap: pretty;
}
/* Etiquetas de datos dentro de los graficos: van siempre y van abreviadas. Son mas
   chicas y mas tenues que el monto opcional, que muestra la cifra entera en capsula. */
.etiqueta-dato {
  fill: var(--tinta-1);
  font-weight: 600;
}
.etiqueta-meta {
  fill: var(--tinta-1);
  font-weight: 600;
}
/* El numero que va adentro de la barra. La barra es oscura, asi que la tinta se invierte:
   medido, #f0edee sobre #5c665a da 5,2:1, el mismo contraste que la tinta normal sobre el
   panel, nada mas que al reves. */
.etiqueta-en-barra {
  fill: var(--tinta-clara);
  font-weight: 600;
}
.etiqueta-serie { pointer-events: none; }

.cifra-linea { display: flex; align-items: baseline; gap: 7px; }
.cifra {
  /* 28px y no 34: la cifra va entera y un ingreso mensual son catorce caracteres.
     A 34px desbordaba el bloque y el navegador la partia en dos renglones. */
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--tinta-1);
  white-space: nowrap;
}
.cifra-unidad { font-size: 13px; color: var(--tinta-3); }

.comparacion { margin-top: 6px; display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; }
.comparacion-valor { font-weight: 700; }
.comparacion-detalle { color: var(--tinta-3); }
.comparacion.bueno .comparacion-valor { color: var(--bueno); }
.comparacion.malo .comparacion-valor { color: var(--critico); }
.comparacion.neutro .comparacion-valor { color: var(--tinta-3); }

.objeto-grafico { margin-top: 14px; }
.objeto-grafico svg { display: block; width: 100%; height: auto; }
/* El anillo conserva su tamano y se centra. Ver graficoAnillo() en motor.js. */
.objeto-grafico svg.grafico-cuadrado { width: auto; max-width: 100%; margin: 0 auto; }
.objeto-nota { margin: 10px 0 0; font-size: 11.5px; color: var(--tinta-3); }

.leyenda { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 14px; font-size: 11.5px; color: var(--tinta-2); }
.leyenda-item { display: inline-flex; align-items: center; gap: 6px; }
.punto { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.punto.raya { width: 14px; height: 2px; border-radius: 1px; }

.brecha-lista { margin-top: 4px; display: flex; flex-direction: column; gap: 8px; }
.brecha-fila { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.brecha-nombre { color: var(--tinta-2); font-size: 13px; }
.brecha-valor { font-size: 17px; font-weight: 700; font-variant-numeric: proportional-nums; }
.brecha-valor.bueno { color: var(--bueno); }
.brecha-valor.malo { color: var(--critico); }
.brecha-valor.neutro { color: var(--tinta-3); }

/* zona central: la pieza de marca y sus cotas */
.centro {
  position: absolute;
  top: 452px;
  left: 50%;
  transform: translateX(-50%);
  width: 420px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.pieza {
  /* El isotipo de Parque Serenidad, al que llegan los hilos de los bloques.
     En el informe de la INC esta pieza era la bolsa de cemento: el producto del que hablan
     los numeros. Aca no hay un producto unico que fotografiar -son servicios- asi que el
     centro lo ocupa la marca.
     220 y no 300: la imagen es cuadrada y la de la INC era apaisada y alta, asi que a igual
     ancho esta ocupa mucho menos alto de columna y mucho mas ancho de carril. A 300 los
     hilos de los bloques laterales llegaban pegados al borde. */
  width: 220px;
  /* La proporcion reserva el espacio antes de que la imagen baje. Sin esto el layout salta
     al cargar y los hilos se trazan contra un hueco de altura cero. */
  aspect-ratio: 1 / 1;
  height: auto;
  object-fit: contain;
}
/* Bloque colgado debajo de la pieza: ocupa todo el ancho de la columna del medio. */
.objeto-central {
  width: 100%;
  margin-top: 30px;
}

/* La zona se queda con el espacio que sobra y centra la pieza adentro. Con la columna
   estirada por alinearColumnas, esto es lo que deja la imagen en medio de los datos en
   lugar de pegada al borde de arriba. */
.zona-pieza {
  flex: 1;
  width: 100%;
  display: grid;
  place-items: center;
  min-height: 0;
}


/* Tira de totales del ejercicio. Vive arriba, cruzando el ancho del informe:
   abajo de la pieza robaba el espacio por donde tienen que pasar los hilos de
   los bloques laterales. */
.cotas {
  position: absolute;
  top: 320px;
  left: 70px;
  right: 70px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
.cota {
  border: 1px solid var(--linea-fuerte);
  border-radius: var(--radio-panel);
  background: var(--fondo);
  padding: 10px 14px;
  text-align: center;
}
.cota-titulo { font-size: 10.5px; letter-spacing: 0.09em; text-transform: uppercase; color: var(--tinta-3); }
.cota-valor { font-family: var(--mono); font-size: 21px; font-weight: 700; color: var(--tinta-1); margin-top: 2px; }
.cota-unidad { font-size: 11px; color: var(--tinta-3); }

/* capa de conectores: une cada objeto con el centro */
.conectores { position: absolute; inset: 0; pointer-events: none; }

/* Los colores van en CSS y no en atributos del SVG porque un atributo de
   presentacion pierde contra una regla de hoja de estilo: asi el estado activo
   puede sobreescribirlos sin tocar el trazado. */
.conector-linea {
  stroke: var(--linea-fuerte);
  stroke-width: 1.4;
  transition: stroke var(--rapido) var(--curva), stroke-width var(--rapido) var(--curva);
}
.conector-origen {
  fill: var(--linea-fuerte);
  transition: fill var(--rapido) var(--curva), r var(--rapido) var(--curva);
}
.conector-punta {
  fill: var(--panel);
  stroke: var(--linea-fuerte);
  stroke-width: 1.5;
  transition: stroke var(--rapido) var(--curva), r var(--rapido) var(--curva);
}

/* Hilo del bloque que el puntero o el teclado tienen encima. */
.conector.activo .conector-linea { stroke: var(--acento); stroke-width: 2; }
.conector.activo .conector-origen { fill: var(--acento); r: 5.5; }
.conector.activo .conector-punta { stroke: var(--acento); stroke-width: 2; r: 7.5; }

/* El bloque acompana al hilo: sin esto hay que adivinar cual de los dos extremos
   corresponde al bloque que se esta mirando. */
.objeto:hover, .objeto:focus-within { border-color: var(--acento); }
.objeto { transition: border-color var(--rapido) var(--curva); }

@media (prefers-reduced-motion: reduce) {
  .conector-linea, .conector-origen, .conector-punta { transition: none; }
}

/* franja de cierre del ejercicio */
/* La posicion vertical la calcula el shell al dibujar: ver apilarCierre en app.js.
   Un top escrito a mano se encima en cuanto un bloque de arriba crece. */
.franja {
  position: absolute;
  left: 70px; right: 70px;
  top: 0;
}
.franja-titulo {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tinta-3);
  margin-bottom: 10px;
}
.franja-grilla {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 1px;
  background: var(--linea-fuerte);
  border: 1px solid var(--linea-fuerte);
  border-radius: var(--radio-panel);
  overflow: hidden;
}
.franja-celda { background: var(--fondo); padding: 14px 14px 16px; }
.franja-etiqueta { font-size: 11px; color: var(--tinta-3); min-height: 28px; }
.franja-valor {
  margin-top: 4px;
  /* 15px y no 19: con la cifra entera, "342.820.968.360 Gs" son dieciocho caracteres y a
     19px el "Gs" caia a un segundo renglon en una celda de la franja. */
  font-size: 15px;
  font-weight: 700;
  color: var(--tinta-1);
  white-space: nowrap;
}
.franja-desv { margin-top: 4px; font-size: 11.5px; font-weight: 600; }
.franja-desv.bueno { color: var(--bueno); }
.franja-desv.malo { color: var(--critico); }
.franja-desv.neutro { color: var(--tinta-3); }

/* pie del informe */
.pie {
  position: absolute;
  left: 70px; right: 70px;
  top: 0;
}
.pie-regla { height: 1px; background: var(--linea); margin-bottom: 16px; }
.ficha {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--linea-fuerte);
  border: 1px solid var(--linea-fuerte);
  border-radius: var(--radio-panel);
  overflow: hidden;
}
.ficha-celda { background: var(--panel); padding: 12px 14px; }
.ficha-titulo { font-size: 10.5px; letter-spacing: 0.09em; text-transform: uppercase; color: var(--tinta-3); }
.ficha-valor { margin-top: 3px; font-size: 15px; font-weight: 600; color: var(--tinta-1); }

.aviso {
  margin-top: 16px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  border: 1px solid var(--linea-fuerte);
  border-radius: var(--radio-panel);
  padding: 11px 14px;
  font-size: 12px;
  color: var(--tinta-2);
  background: var(--fondo);
}
.aviso .icono { color: var(--atencion); font-weight: 700; flex: none; }
.aviso.discrepancia .icono { color: var(--acento); }

/* ============ tooltip ============ */
.tooltip {
  position: fixed;
  top: 0; left: 0;
  z-index: 60;
  pointer-events: none;
  min-width: 190px;
  background: var(--panel-oscuro);
  color: #e8e5e2;
  border: 1px solid #4a4f57;
  border-radius: var(--radio-panel);
  padding: 9px 11px;
  box-shadow: 0 10px 28px rgba(54, 57, 63, 0.3);
  font-size: 12px;
}
.tooltip .titulo { font-weight: 700; margin-bottom: 6px; color: #fff; }
.tooltip .fila { display: flex; align-items: center; gap: 7px; margin-top: 3px; color: #d5d1ce; }
.tooltip .fila b { margin-left: auto; color: #fff; font-variant-numeric: tabular-nums; }

/* ============ svg ============ */
.grafico .tick {
  font-family: var(--mono);
  font-size: 10px;
  fill: var(--tinta-3);
  font-variant-numeric: tabular-nums;
}
.grafico .cifra-anillo {
  font-family: var(--sans);
  font-size: 30px;
  font-weight: 700;
  fill: var(--tinta-1);
}
.zona-hover { cursor: crosshair; }

/* ============ tabla equivalente ============ */
.tabla-envoltorio { margin: 0 auto; max-width: 1400px; padding: 0 20px 60px; }
.tabla-titulo { font-size: 15px; font-weight: 700; margin: 0 0 10px; }
.tabla-scroll { overflow-x: auto; border: 1px solid var(--linea); border-radius: var(--radio-panel); background: var(--panel); }
table { border-collapse: collapse; width: 100%; font-size: 12.5px; }
th, td { padding: 8px 12px; text-align: right; white-space: nowrap; }
th:first-child, td:first-child { text-align: left; position: sticky; left: 0; background: var(--panel); }
thead th { background: var(--panel-hundido); color: var(--tinta-2); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; }
thead th:first-child { background: var(--panel-hundido); }
tbody tr { border-top: 1px solid var(--linea-tenue); }
tbody td { color: var(--tinta-1); font-variant-numeric: tabular-nums; }
tbody tr.sin-dato td, tbody tr.sin-dato th { color: var(--tinta-3); font-style: italic; }

/* ============ pantalla de ingreso ============ */
body.modo-ingreso { min-height: 100dvh; background: var(--panel-oscuro); }

body.modo-ingreso #raiz {
  min-height: 100dvh;
  display: grid;
  place-items: center end;
  padding: 24px clamp(24px, 7vw, 110px);
  /* La foto institucional ya es una composicion terminada: el logo arriba a la
     izquierda y la leyenda abajo. El velo es parejo y suave para no tapar nada de
     eso; la tarjeta se apoya a la derecha, sobre la zona de cielo, que es la unica
     parte vacia de la foto. La tarjeta es opaca, asi que el velo separa, no protege
     texto. */
  background-image:
    linear-gradient(rgba(28, 31, 36, 0.22), rgba(28, 31, 36, 0.22)),
    url("psinformes-assets/portada.jpg");
  background-size: auto, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
}

/* En pantallas angostas la foto ya no tiene zona vacia: la tarjeta se centra y el
   velo sube, porque ahi el fondo pasa a ser textura y no composicion. */
@media (max-width: 820px) {
  /* La foto es apaisada y la pantalla es vertical: `cover` deja ver solo una franja
     estrecha del centro, que siempre corta el logotipo por la mitad. En vez de buscar
     un encuadre que no existe, se muestra la foto entera arriba, como una cabecera,
     y la tarjeta se apoya sobre el color solido. */
  body.modo-ingreso #raiz {
    place-items: start center;
    padding: 0 20px 40px;
    /* La version de 1400 px y no la grande: aca la foto se muestra a lo ancho de la pantalla,
       asi que 1400 px cubren un telefono incluso con pantalla de triple densidad. Son 152 KB en
       vez de 338, y es justo el caso donde la conexion suele ser peor. */
    background-image: url("psinformes-assets/portada-1400.jpg");
    background-size: 100% auto;
    background-position: top center;
    background-color: var(--panel-oscuro);
  }
  .ingreso { margin-top: clamp(180px, 58vw, 300px); }
}

.ingreso {
  width: min(380px, 100%);
  background: var(--panel);
  border: 1px solid var(--linea);
  border-radius: var(--radio-panel);
  padding: 28px 26px 26px;
  box-shadow: 0 20px 50px rgba(20, 22, 25, 0.35);
}
.ingreso-marca { display: flex; flex-direction: column; gap: 2px; }
.ingreso-nombre { font-size: 20px; font-weight: 700; letter-spacing: -0.01em; color: var(--tinta-1); }
.ingreso-cliente { font-size: 12px; color: var(--tinta-3); }
.ingreso-ayuda { margin: 16px 0 20px; font-size: 13px; color: var(--tinta-2); }

.campo { display: block; margin-bottom: 14px; }
.campo-etiqueta { display: block; font-size: 12px; color: var(--tinta-2); margin-bottom: 6px; }
.campo input {
  width: 100%;
  font: inherit;
  font-size: 14px;
  color: var(--tinta-1);
  background: var(--panel);
  border: 1px solid var(--linea-fuerte);
  border-radius: var(--radio-panel);
  padding: 9px 11px;
  transition: border-color var(--rapido) var(--curva);
}
.campo input::placeholder { color: var(--tinta-3); }
.campo input:hover { border-color: var(--tinta-3); }
.campo input:focus { outline: 2px solid var(--acento); outline-offset: 1px; border-color: var(--acento); }
.campo-error { margin: 0 0 14px; font-size: 12.5px; color: var(--critico); }
.ingreso-boton { width: 100%; padding: 10px; font-size: 14px; }
.ingreso-boton[disabled] { opacity: 0.7; cursor: progress; }

/* ============ estados del lienzo ============ */
.cargando { padding: 70px; }
.cargando-columnas {
  display: grid;
  grid-template-columns: 380px 1fr 380px;
  gap: 40px;
}
.cargando-texto {
  margin-top: 40px;
  text-align: center;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tinta-3);
}

.esqueleto {
  background: linear-gradient(90deg, var(--panel-hundido) 25%, #efeaea 50%, var(--panel-hundido) 75%);
  background-size: 200% 100%;
  animation: brillo 1.4s linear infinite;
  border-radius: var(--radio-panel);
}
/* Las medidas del esqueleto viven aca y no en el marcado: la CSP de este Host declara
   `style-src 'self'` sin `'unsafe-inline'`, asi que un `style=` en el HTML queda bloqueado
   y el esqueleto colapsaba a altura cero. No da error: solo no se ve. */
.esq-titulo { height: 58px; width: 52%; margin: 0 auto; }
.esq-subtitulo { height: 16px; width: 34%; margin: 14px auto 40px; }
.esq-bloque-chico { height: 160px; }
.esq-bloque-medio { height: 250px; }
.esq-bloque-grande { height: 470px; }
.esq-bloque-alto { height: 560px; }
.esqueleto.separado { margin-top: 26px; }
@keyframes brillo { to { background-position: -200% 0; } }

/* Sin movimiento para quien lo pidió: el brillo del esqueleto no informa nada que el propio
   bloque gris no diga ya. */
@media (prefers-reduced-motion: reduce) {
  .esqueleto { animation: none; }
}

.error-lienzo {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  padding: 40px;
}
.error-titulo { margin: 0; font-size: 20px; font-weight: 700; }
.error-detalle { margin: 0; max-width: 46ch; color: var(--tinta-2); }

.origen { color: var(--tinta-3); font-size: 12px; margin-top: -40px; }

/* El redibujo ya ocurrio cuando esto se aplica: la marca solo avisa que cambio.
   El contenido nunca depende de esta transicion para existir. */
/* ============ disposicion apilada ============
   La otra disposicion posiciona TODO en absoluto, porque los hilos se trazan contra coordenadas.
   Esta no tiene hilos, asi que va en flujo normal: el contenido manda el alto y no hay nada que
   medir dos veces. Las reglas de abajo devuelven al flujo lo que la otra saca. */
.lienzo.apilado .cabecera { position: static; margin: 60px 70px 0; }
.apilado-cuerpo {
  padding: 34px 70px 0;
  display: flex;
  flex-direction: column;
  gap: 34px;
}
.lienzo.apilado .cotas,
.lienzo.apilado .franja,
.lienzo.apilado .pie { position: static; left: auto; right: auto; top: auto; }

/* El bloque principal se queda con el ancho entero: es el que justifica el informe, asi que se le
   da el espacio en vez de repartirlo parejo. */
.objeto-principal { width: 100%; }

/* El resto, en una grilla que se acomoda sola. `auto-fit` con un minimo evita declarar cuantas
   columnas hay: con cinco bloques entran tres y dos, y con dos entran dos. */
.apilado-grilla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
  gap: 26px;
  align-items: start;
}

.lienzo { transition: border-color var(--normal) var(--curva); }
.lienzo.recien-actualizado { border-color: var(--acento); }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

@media print {
  /* Una sola configuracion de pagina para los dos formatos de salida. El margen existe
     porque muchas impresoras no llegan al borde del papel. */
  @page { size: A4 portrait; margin: 12mm; }

  html, body {
    margin: 0;
    padding: 0;
    background: #fff;
  }

  .barra, .filtros, .tabla-envoltorio, .barra-foco, .objeto-controles { display: none !important; }

  main, .escenario {
    display: block;
    margin: 0;
    padding: 0;
    height: auto !important;
  }

  .lienzo {
    /* El factor lo calcula el codigo antes de abrir el dialogo: depende del alto real
       del lienzo, que crece si el contenido no entra en la proporcion A4. */
    zoom: var(--zoom-impresion, 0.567);
    transform: none !important;
    box-shadow: none;
    border: 0;
    margin: 0;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* Nada de lo que se dibuja debe empujar contenido a una segunda hoja. */
  .objeto, .cota, .franja, .pie, .centro { break-inside: avoid; page-break-inside: avoid; }
}

/* ============ enfoque ============
   El bloque elegido no se abre en una ventana aparte: el lienzo entero se acerca
   hacia el, como en una presentacion de Prezi. El informe no se pierde de vista,
   solo se mira mas de cerca, y por eso el resto se atenua en vez de taparse. */

/* El bloque enfocado sale del flujo y se centra en la pantalla. El hueco conserva
   su lugar en el informe para que nada de atras se reacomode. */
.hueco-foco { flex: none; }

.objeto.en-foco {
  position: fixed;
  /* left y top los pone el JavaScript, redondeados a pixel entero. Centrarlo aca con
     left:50% + translate(-50%,-50%) deja el bloque en medio pixel cuando su ancho o su
     alto son impares, y ahi el texto se rasteriza borroso. */
  z-index: 50;
  margin: 0;
  max-height: calc(100dvh - 130px);
  overflow: auto;
  will-change: transform;
  padding: 26px 30px;
}

/* Enfocar es para leer de cerca: adentro del foco todo sube de cuerpo. Los bloques que
   no tienen grafico crecen asi, porque estirarles el alto solo les agregaria vacio. */
.en-foco .objeto-titulo { font-size: 13px; letter-spacing: 0.16em; }
.en-foco .cifra { font-size: 52px; }
.en-foco .cifra-unidad { font-size: 20px; }
.en-foco .comparacion { font-size: 16px; margin-top: 10px; }
.en-foco .comparacion-detalle { font-size: 14px; }
.en-foco .objeto-nota { font-size: 14px; }
.en-foco .objeto-lectura { font-size: 15px; padding-top: 14px; margin-top: 18px; }
.en-foco .leyenda { font-size: 13px; }
.en-foco .brecha-nombre { font-size: 16px; }
.en-foco .brecha-valor { font-size: 22px; }
.en-foco .brecha-fila { padding: 12px 0; }

/* Lo que no esta enfocado retrocede. Se atenua y pierde nitidez, que es lo que
   hace que el ojo se quede en el bloque elegido. */
.lienzo.enfocado .objeto:not(.en-foco),
.lienzo.enfocado .cota,
.lienzo.enfocado .franja,
.lienzo.enfocado .pie,
.lienzo.enfocado .cabecera,
.lienzo.enfocado .sello,
.lienzo.enfocado .folio,
.lienzo.enfocado .centro,
.lienzo.enfocado .conectores {
  opacity: 0.25;
  filter: blur(1.5px);
  /* Sin esto, los controles de los bloques atenuados siguen respondiendo detras del
     velo: se puede pulsar "mostrar montos" de otro bloque sin verlo. */
  pointer-events: none;
  transition: opacity 420ms var(--curva), filter 420ms var(--curva);
}

.objeto.en-foco {
  box-shadow: 0 30px 70px rgba(20, 22, 25, 0.3);
  border-color: var(--acento);
  background: var(--panel);
}

/* Detras del bloque enfocado, el informe se atenua. No se tapa con un velo opaco:
   sigue siendo el mismo informe, mirado de mas cerca. */
.lienzo.enfocado::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 45;
  background: rgba(240, 237, 238, 0.72);
  pointer-events: none;
}

/* El control de enfoque aparece al pasar por encima del bloque, y siempre que el
   teclado lo alcance. Es un boton de verdad: se puede tabular. */
.objeto-controles {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  gap: 4px;
  opacity: 0;
  transition: opacity var(--rapido) var(--curva);
}
.objeto:hover .objeto-controles,
.objeto:focus-within .objeto-controles,
.objeto.en-foco .objeto-controles { opacity: 1; }

.control {
  appearance: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--linea-fuerte);
  background: var(--panel);
  color: var(--tinta-2);
  border-radius: var(--radio-panel);
  cursor: pointer;
  transition: background var(--rapido) var(--curva), color var(--rapido) var(--curva), border-color var(--rapido) var(--curva);
}
.control:hover { background: var(--acento); border-color: var(--acento); color: #fff; }
.control:active { transform: scale(0.96); }
.control:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
.control svg { width: 14px; height: 14px; display: block; }

/* Barra del modo enfoque: vive fuera del lienzo para no escalarse con el. */
.barra-foco {
  position: fixed;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 9px 14px;
  background: var(--panel-oscuro);
  color: #e8e5e2;
  border-radius: var(--radio-control);
  box-shadow: 0 14px 34px rgba(20, 22, 25, 0.35);
  font-size: 13px;
}
.barra-foco .titulo-foco { font-weight: 600; }
.barra-foco .atajo {
  font-family: var(--mono);
  font-size: 11px;
  color: #b9b4b0;
  border: 1px solid #5b6068;
  border-radius: 3px;
  padding: 1px 5px;
}
.barra-foco button {
  appearance: none;
  border: 1px solid #5b6068;
  background: transparent;
  color: #e8e5e2;
  font: inherit;
  font-size: 12px;
  padding: 4px 12px;
  border-radius: var(--radio-control);
  cursor: pointer;
}
.barra-foco button:hover { background: #464a51; }
.barra-foco button:focus-visible { outline: 2px solid #9aa79a; outline-offset: 2px; }

/* Con movimiento reducido, el acercamiento es instantaneo: el enfoque sigue
   funcionando, lo que desaparece es el viaje. */
@media (prefers-reduced-motion: reduce) {
  .lienzo.enfocado { transition: none; }
  .lienzo.enfocado .objeto:not(.en-foco) { filter: none; }
}

@media print {
  .barra-foco, .objeto-controles { display: none; }
}

/* Montos sobre el grafico. El tamano lo fija el control de la fila de filtros. */
.grafico .monto-texto {
  font-family: var(--sans);
  font-weight: 700;
  fill: var(--tinta-1);
  font-variant-numeric: tabular-nums;
}

/* ============ hoja de lectura ============
   El segundo formato de salida: los bloques uno debajo del otro, con los graficos
   grandes, en las hojas que hagan falta. Solo existe mientras dura la impresion, y en
   pantalla no se muestra nunca. */

#hoja-lectura { display: none; }

@media print {
  /* Con la hoja de lectura armada, el lienzo no se imprime y la hoja si. */
  body.imprimiendo-lectura .escenario,
  body.imprimiendo-lectura #lienzo { display: none !important; }

  body.imprimiendo-lectura #hoja-lectura {
    display: block;
    width: 100%;
    padding: 0;
    margin: 0;
    color: var(--tinta-1);
  }

  body.imprimiendo-lectura { width: auto; }

  /* Margenes de hoja: aca si hacen falta, porque el contenido llega hasta el borde. */
  .portada-lectura {
    padding: 0 0 18px;
    border-bottom: 2px solid var(--acento);
    margin-bottom: 22px;
    break-after: avoid;
    page-break-after: avoid;
  }
  .portada-cliente {
    margin: 0;
    font-size: 10px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--tinta-3);
  }
  .portada-titulo {
    margin: 6px 0 0;
    font-family: var(--serif);
    font-size: 34px;
    font-weight: 600;
    letter-spacing: 0;
    line-height: 1.08;
  }
  .portada-subtitulo { margin: 6px 0 0; font-size: 12px; color: var(--tinta-2); }
  .portada-periodo {
    margin: 10px 0 0;
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.06em;
    color: var(--tinta-3);
  }
  .portada-totales {
    margin-top: 16px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1px;
    background: var(--linea-fuerte);
    border: 1px solid var(--linea-fuerte);
  }
  .portada-totales > div { background: var(--fondo); padding: 10px 12px; text-align: center; }

  /* Un bloque por fila, con el grafico a todo el ancho util de la hoja. */
  .bloque-lectura {
    position: static;
    width: 100%;
    margin: 0 0 16px;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .bloque-lectura .cifra { font-size: 28px; }
  .bloque-lectura .objeto-grafico { margin-top: 12px; }

  .cierre-lectura { margin-top: 8px; break-inside: avoid; page-break-inside: avoid; }
  .cierre-lectura .franja,
  .cierre-lectura .pie {
    position: static;
    left: auto; right: auto; top: auto;
    margin-top: 18px;
  }
}
