/* control-tower.css — Tablero ejecutivo Control Tower (PBI 735). Usa el sistema de diseno. */
/* El encabezado de VIRGILIO es fijo (116px); layout.css compensa 130px por seccion en una lista explicita. Esta seccion lo compensa aqui. */
#page-control-tower { background: var(--bg-secondary, #fafafa); min-height: 100vh; padding-top: 130px; }
/* max-width 1680 (era 1280): con 1280 tres tarjetas ocupaban ~1.130px de los
   ~1.770 disponibles y sobraba un tercio de pantalla a la derecha. A 1680 el
   contenido llega a 1.632px (~92% del ancho util) y deja un margen lateral que
   evita que el texto quede pegado al borde en monitores anchos. */
/* Tipografia de marca, acotada a ESTE modulo.
 *
 * Las tres variables se declaran en .ct-root y no en :root a proposito:
 * --font-sans es global y la usan todos los modulos, asi que redefinirla —aun
 * dentro de .ct-root— se filtraria a lo que cuelgue de aca. De hecho se
 * filtraria: .ctg-root, la pestana de Geografia, vive dentro de .ct-root y pide
 * var(--font-sans) por su cuenta. Con nombres nuevos, Geografia conserva la
 * fuente del sistema y solo cambia lo que este archivo toca a mano.
 *
 * Cada cadena tiene tres escalones. Primero el archivo local (fuentes-marca.css);
 * despues la misma familia servida por Google, que enterprise.css ya importa,
 * como red para el dia que fonts/ no este publicado —es carpeta nueva y todavia
 * no esta en el repo—; y al final la fuente del sistema. Asi el peor caso es
 * "se ve como antes", nunca "se ve roto".
 *
 * Reparto: DM Sans para TODO el modulo, numeros incluidos; Poppins 600 solo
 * para el nombre del indicador (.ct-nombre); Suti solo para el titulo del
 * modulo (.ct-titulo).
 *
 * El nombre del indicador fue Centory of Brush en mayuscula sostenida hasta el
 * 23/09/2026: el PBI 973 (decision de Miguel) lo paso a Poppins 600, sin
 * mayuscula sostenida y con letter-spacing 0. Cadena de --ct-fuente-nombre:
 * 'YaYa Poppins' (el .ttf 600 local de fonts/, mismo patron que 'YaYa DM Sans'
 * en --ct-fuente-texto) -> 'Poppins' de Google (enterprise.css la importa en
 * 400-700 y se carga siempre) -> DM Sans. El @font-face de Centory sigue en
 * fuentes-marca.css, anotado como sin consumidor.
 *
 * (Historia, antes del PBI 973: Centory NO esta en Google Fonts, asi que su
 * escalon del medio era Permanent Marker, otra display de pincel que index.html
 * carga desde Google.)
 *
 * COLOR DEL TEXTO. Los dos verdes que ofrecia el encargo no empatan: medido
 * contra la tarjeta #D8F4D7, Verde crecimiento #022D2B da 12,63:1 y Verde YaYa
 * #2AA048 da 2,87:1 — este ultimo no llega ni al 3:1 de texto grande, asi que no
 * puede llevar texto en este modulo. El reparto queda entonces entre el propio
 * Verde crecimiento y una version suya aclarada sobre la misma tarjeta
 * (--yaya-crecimiento-suave, 5,55:1): el pleno para lo que se lee, el suave para
 * lo que acompana. La jerarquia que antes daban los niveles de gris ahora la dan
 * el tamano y el peso, que el modulo ya tenia. */
.ct-root {
    --ct-fuente-texto: 'YaYa DM Sans', 'DM Sans', var(--font-sans);
    --ct-fuente-nombre: 'YaYa Poppins', 'Poppins', var(--ct-fuente-texto);
    --ct-fuente-titulo: 'YaYa Suti', 'Poppins', var(--ct-fuente-texto);
    --ct-texto: var(--yaya-verde-crecimiento, #022D2B);
    --ct-texto-suave: var(--yaya-crecimiento-suave, #3E655B);
    /* Alto de toda tarjeta de la rejilla desde 1025px (PBI 1001, tarea 1255):
       ver el bloque que sigue a .ct-tarjeta. */
    --ct-tarjeta-alto: 640px;
    max-width: 1680px; margin: 0 auto; padding: 32px 24px 48px; font-family: var(--ct-fuente-texto); color: var(--ct-texto);
}
.ct-root .ct-cabecera, .ct-root .ct-titulo, .ct-root .ct-subtitulo { display: block; position: static; }
.ct-root .ct-cabecera { display: flex; }
.ct-cabecera { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
/* El titulo del modulo, en Suti. Es un titulo suelto y no lleva mayuscula
   sostenida, asi que no sigue la regla de .ct-nombre.

   Peso 400 y no 700: Suti solo trae el peso 400, y un 700 se lo inventaria el
   navegador engrosando los trazos. A 26px el titulo
   ya se lee como titulo por tamano, no necesita negrita. Y el letter-spacing
   negativo se va: apretar una display de trazo suelto la emborrona.

   El escalon del medio de la cadena es Poppins y NO Permanent Marker a
   proposito, aunque las dos esten cargadas: .ct-nombre usa Poppins 600 desde
   el PBI 973 (23/09/2026; antes era Centory, con Permanent Marker de
   respaldo). El dia que fonts/ no este publicada, el titulo y los nombres de
   indicador caen los dos en la Poppins de Google —que el manual de marca ya
   asigna a titulos y que enterprise.css importa— y se distinguen por tamano
   (56px contra 19px) y peso (400 contra 600). */
/* 56px (era 26px), con el interlineado apretado a 1,05.
 *
 * El numero sale de emparejar los dos lados de .ct-cabecera, que es un flex con
 * align-items: flex-end. El lado derecho (.ct-derecha) mide 84px exactos: las
 * pestanas 37px (9+9 de padding, 17 de texto a 13px con el interlineado normal
 * de DM Sans, 2 de borde), el toggle de moneda otros 37px (3+3 de riel, 7+7 de
 * padding, 17 de texto) y 10px de gap. El lado izquierdo con titulo de 56px a
 * 1,05 da 58,8px, mas 6px de margen, mas 19,5px del subtitulo a 15px: 84,3px.
 * Los dos lados apoyan parejos abajo con un tercio de pixel de diferencia.
 *
 * El interlineado baja de 1,2 a 1,05 porque a este tamano el aire pesa. La caja
 * natural de Suti es 1,221em pero sus mayusculas solo llegan a 0,732em: a 26px
 * eso sobraban 12,7px de aire y no se notaba, a 56px serian 27,4px y el titulo
 * quedaria flotando lejos del subtitulo. Un line-height por debajo del natural
 * no recorta nada —el glifo desborda la caja de linea sin cortarse— y aca es
 * doblemente seguro porque "Control Tower" no tiene ni una letra con descendente
 * que pueda tocar el subtitulo.
 *
 * Ancho: "Control Tower" en Suti a 56px mide 282px de los ~1632 de la fila, y la
 * derecha ocupa unos 300. No hay riesgo de que la cabecera se parta. */
.ct-titulo { margin: 0; font-family: var(--ct-fuente-titulo); font-size: 56px; font-weight: 400; color: var(--ct-texto); line-height: 1.05; }
/* El subtitulo sube de 14 a 15px y su margen de 4 a 6px. A 14px al lado de un
   titulo de 56px se leia como una nota al pie y no como la bajada del titulo; y
   el margen de 4px era el que tenia cuando arriba habia 26px. */
.ct-subtitulo { margin: 6px 0 0; font-size: 15px; color: var(--ct-texto-suave); }
.ct-derecha { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
/* Interruptores: riel gris con la opcion activa como pastilla flotante encima,
   en vez de dos botones separados por un borde duro. El riel es el fondo gris,
   la pastilla es blanca con una sombra corta, y el estado activo se lee por
   elevacion y por el verde del texto en vez de por un bloque de color pleno.
   El padding del riel es lo que deja ver el carril a los costados de la
   pastilla; sin el, la pastilla lo tapa entero y vuelve a parecer un boton. */
/* El riel pasa del gris al verde tenue: --gray-100 sobre la tarjeta daba 1,08:1
   y el carril no existia, con lo que la pastilla activa flotaba sobre nada. Con
   --yaya-crecimiento-tenue da 2,14:1 contra la tarjeta, y la pastilla blanca
   encima da 2,51:1 contra el riel, que con su sombra corta alcanza para leerse
   como elevada. */
.ct-toggle { display: inline-flex; border: none; border-radius: 999px; overflow: hidden; background: var(--yaya-crecimiento-tenue, #95A7A6); padding: 3px; gap: 2px; }
.ct-toggle-btn { border: none; background: transparent; padding: 7px 15px; border-radius: 999px; font: inherit; font-size: 13px; font-weight: 600; color: var(--ct-texto); cursor: pointer; transition: background .18s, color .18s, box-shadow .18s; }
.ct-toggle-btn:hover { color: var(--ct-texto); }
/* La pastilla activa es blanca y su texto va en Verde crecimiento: 14,86:1 sobre
   blanco. Antes iba en --primary-700, que daba 5,00:1 y era de la familia verde
   anterior. */
.ct-toggle-btn.activo { background: var(--bg-primary); color: var(--ct-texto); box-shadow: 0 1px 1px rgba(16,24,40,.04), 0 2px 6px rgba(16,24,40,.12); }
.ct-toggle-btn:focus-visible { outline: 2px solid var(--primary-500); outline-offset: -2px; }
.ct-aviso { margin: 0 0 14px; font-size: 13px; color: var(--amber-600); background: var(--amber-50); border: 1px solid #fde68a; border-radius: 8px; padding: 8px 12px; }
/* Tres por fila FIJAS, no auto-fill: con nueve indicadores tienen que ser tres
   filas de tres y no una grilla que se reacomoda sola segun cuantos entren.
   Cada tarjeta mide (1632 - 32) / 3 = 533px. Bajo 1024px se cae a una columna,
   porque tres tarjetas de ~330px con un grafico adentro no se leen.

   align-items: start (el default de Grid es stretch), agregado cuando
   .ct-tarjeta-ancha empezo a quedar mas alta que sus vecinas de 1 columna:
   sin esto, Grid estira TODAS las tarjetas de una fila a la altura de la
   mas alta, y la vecina mas corta quedaba con su contenido arriba y un
   hueco verde vacio abajo. Ahora que TODA tarjeta tiene el mismo
   min-height (ver .ct-tarjeta) esta regla ya no tiene nada que corregir --
   ninguna fila deberia llegar a tener alturas distintas entre si -- pero se
   deja puesta: es inofensiva si algun dia una tarjeta vuelve a superar el
   min-height de las demas (una vuelta al problema que esto resolvio, sin
   volver a escribir la regla). */
/* grid-auto-flow: dense (encargo "Rejilla sin huecos, selector de tarjetas
   visibles, y volver conserva la posicion de scroll", pieza 1). Con 3
   columnas fijas y tarjetas de 1, 2 y 3 columnas (.ct-tarjeta-ancha y
   .ct-tarjeta-triple, mas abajo), el auto-placement SPARSE por default deja
   huecos: una tarjeta de span 3 solo entra arrancando en la columna 1, asi
   que si el cursor quedo en la 2 o la 3, el resto de esa fila queda vacio y
   ya no se vuelve a visitar.

   MEDIDO simulando el auto-placement con los anchos reales y el orden real
   de hoy (11 tarjetas = 15 celdas = 5 filas exactas si empaquetaran
   perfecto): sparse da 6 filas con 3 huecos -retencion_cohortes sola en una
   fila con dos celdas vacias al lado, mas una celda suelta al final-; dense
   da 5 filas y CERO huecos.

   El precio, medido y aceptado por Miguel: dense reordena visualmente para
   rellenar, asi que el orden en pantalla deja de coincidir con el del DOM.
   Con el orden de hoy mueve 2 tarjetas (escalera_mora_mensual pasa a
   dibujarse despues de activos_mensual_dual). Es aceptable porque el orden
   actual es incidental, no intencional -- si algun dia el orden pasa a
   significar algo, esta linea es lo primero a revisar.

   Bajo 1024px es inoperante y no hace falta apagarlo: ahi la rejilla es de 1
   columna y todas las tarjetas son span 1 (ver los @media de .ct-tarjeta-
   ancha y .ct-tarjeta-triple), o sea que no hay hueco posible que rellenar
   ni reordenamiento posible que hacer. */
/* PBI 973 T5: dense SE RETIRO (el comentario de arriba queda como historia).
   Con subtabs cada rejilla pinta pocas tarjetas y dense no alcanzaba: dejaba
   filas con celdas vacias y ademas reordenaba, subiendo la TRM -ultima en el
   HTML y en el selector- al hueco de una fila anterior. Ahora el JS cierra
   cada fila antes de pintar (ctColumnasRejilla estira la ultima tarjeta de una
   fila incompleta), asi que todas las filas suman 3 columnas exactas y el
   auto-placement normal (row, sparse) no deja huecos ni reordena: el orden en
   pantalla es el del HTML. Bajo 1024px sigue la regla de abajo (1 columna, y
   las clases de 2 y 3 columnas vuelven a span 1): ahi no hay filas que
   cerrar. */
.ct-rejilla { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-flow: row; gap: 16px; align-items: start; }
@media (max-width: 1024px) { .ct-rejilla { grid-template-columns: 1fr; } }
/* Grupos del subtab caja (CT_SUBTABS.grupos, PBI 1001, tarea 1247; ver
   ctDisposicionRejilla y ctHtmlRejilla): el dinero operativo y el de prestamo, cada
   uno con su encabezado. La banda (.ct-grupos) ocupa la fila entera y hereda las 3
   columnas de la rejilla con subgrid, y cada grupo hereda las suyas (span 1, 2 o 3):
   las tarjetas caen en las mismas columnas que el resto de la rejilla, con los
   mismos anchos de 1, 2 o 3 y el mismo gap. Desde la tarea 1258 (PBI 1004) los dos
   grupos son span 3: cada uno es una franja y la grilla pone el de prestamo debajo
   del operativo, con el row-gap de la banda entre los dos. Cada grupo es su propia
   grilla, con su encabezado arriba y sus tarjetas debajo; asi el HTML queda en el
   orden de la pantalla angosta (encabezado operativo, sus tarjetas, encabezado de
   prestamo, las suyas) y debajo de 1025px todo se apila en ese orden. El
   encabezado no es una tarjeta: no mide --ct-tarjeta-alto. La linea de acento es
   el color de la serie de cada grupo: el verde de la linea de la caja operativa y
   el morado de la serie 2 del 5.2 y el 5.7. */
.ct-grupos { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; row-gap: 16px; align-items: start; }
.ct-grupo { display: grid; grid-template-columns: subgrid; row-gap: 16px; align-items: start; align-content: start; }
.ct-grupo-span-1 { grid-column: span 1; }
.ct-grupo-span-2 { grid-column: span 2; }
.ct-grupo-span-3 { grid-column: span 3; }
.ct-grupo-titulo { grid-column: 1 / -1; margin: 0; padding: 0 0 6px; border-bottom: 3px solid var(--yaya-verde-crecimiento, #022D2B); font-family: var(--ct-fuente-nombre); font-size: 15px; font-weight: 600; letter-spacing: 0; color: var(--ct-texto); }
.ct-grupo-prestamo .ct-grupo-titulo { border-bottom-color: var(--yaya-morado-oscuro, #6660B0); }
/* La TRM en la fila de antes de la banda (ctDisposicionRejilla, trmArriba): en el
   HTML va al final, para la pantalla angosta; en la ancha la banda pasa despues de
   ella con order, y la TRM ocupa el lugar libre de la fila de rotacion y recaudo. */
@media (min-width: 1025px) {
    .ct-rejilla > .ct-grupos-trm-arriba { order: 1; }
}
@media (max-width: 1024px) {
    .ct-grupos, .ct-grupo { display: flex; flex-direction: column; gap: 16px; }
}
/* activos_mensual_dual (PBI 737/738): la unica tarjeta de la rejilla con DOS
   series a la vez,24 barras en vez de 12 -- ver ctTarjetaActivosDual. Medido
   (encargo "etiquetas y ancho de Clientes Activos 30D y 60D"): a 1 columna
   (480u de viewBox, ~493px de interior) cada barra mide ~13,1u (~13,5px) y el
   espacio entre las dos barras de un mismo mes es ~15,1u (~15,5px); el texto
   mas largo realista ("-45,9%", 6 caracteres a 9u de fuente) mide 28,1u --
   mas del DOBLE del espacio disponible, ni reduciendo la fuente a la mitad
   entra. A 2 columnas (grid-column: span 2, el viewBox pasa a compartir
   exactamente el de detalle, 864x202, ~1042px de interior) el espacio sube a
   ~26,4u y el mismo texto entra con la tolerancia de 2u que el resto del
   modulo ya usa para TPV (28,1 vs 26,4+2=28,4). De ahi el span 2: no hay
   forma de que las etiquetas entren legibles en 1 columna. */
.ct-tarjeta-ancha { grid-column: span 2; }
@media (max-width: 1024px) { .ct-tarjeta-ancha { grid-column: span 1; } }
/* escalera_mora_mensual (PBI 745, encargo "Escalera de mora a ancho de 3
   columnas con 4 barras agrupadas"): mismo patron que .ct-tarjeta-ancha,
   span 3 en vez de span 2 -- .ct-rejilla tiene EXACTAMENTE 3 columnas (ver
   arriba), asi que span 3 ocupa la fila COMPLETA, mas simple que span 2 (que
   deja una columna suelta sin llenar salvo que otra tarjeta angosta caiga
   ahi por auto-placement). Mismo fallback a 1 columna bajo 1024px.

   padding-left/right: 12px (encargo "Escalera de mora: gráfico más alto,
   barras más anchas con pocos meses, checkboxes pegados al borde", PASO 4),
   REEMPLAZA los 20px/lado que .ct-tarjeta declara para todas las tarjetas
   -- SOLO para esta clase, .ct-tarjeta-ancha (tpv_categoria_comercio) y la
   base .ct-tarjeta (el resto) siguen en 20px sin cambios. Miguel pidio la
   leyenda de checkboxes "más pegada al borde"; .ct-leyenda en si no declara
   margen lateral propio (ver esa regla, gap/margin son solo verticales), asi
   que el margen que Miguel ve es el padding lateral HEREDADO de .ct-tarjeta
   -- reducirlo ahi es lo unico que mueve la leyenda, y de paso le da mas
   ancho real al grafico (la misma medida que define el viewBox, ver abajo).
   top/bottom se quedan en los 18px de .ct-tarjeta: el pedido es de margen
   LATERAL, achicar el vertical movería el calculo del min-height (ver el
   comentario de .ct-tarjeta) sin que nadie lo pidiera.

   Interior real, RECALCULADO con el padding lateral nuevo (mismas reglas
   que ya midio .ct-tarjeta-ancha: .ct-root max-width 1680 + padding 24px/
   lado, gap 16px, y ahora 12px/lado de ESTA tarjeta en vez de los 20px
   genericos): 3 columnas de grid dan 3*533,333 + 2*16 - 2*12 = 1.608px
   exactos (subio de los 1.592px que daba con el padding viejo de 20px, ver
   el historial de este comentario para esa medicion). Usado para re-derivar
   CT_TARJETA_TRIPLE_VB_ALTO en control-tower.js -- ver el comentario de esa
   constante, que ahora tambien re-mide cuanto alto de tarjeta le sobra al
   grafico en vez de solo igualar la altura de una tarjeta de 1 columna
   (PASO 1 del mismo encargo).

   SELECTOR COMPUESTO para el padding (.ct-tarjeta.ct-tarjeta-triple, no
   .ct-tarjeta-triple sola): esta regla vive en la seccion de GRILLA/layout
   del archivo (junto a .ct-rejilla/.ct-tarjeta-ancha), que en el orden del
   archivo queda ANTES que la regla de apariencia de .ct-tarjeta (padding:
   18px 20px, mas abajo). Con la misma especificidad (una sola clase, 0-1-0)
   la regla que aparece DESPUES en la hoja gana -- .ct-tarjeta, mas abajo,
   le habria pisado el padding-left/right a esta silenciosamente. El
   selector compuesto (0-2-0, dos clases) le gana a .ct-tarjeta (0-1-0) SIN
   IMPORTAR el orden de origen -- no depende de que nadie reordene un
   comentario o una regla en el futuro. grid-column se queda en el selector
   simple: esa propiedad no la declara .ct-tarjeta en ningun lado, asi que
   no tiene con que competir. */
.ct-tarjeta-triple { grid-column: span 3; }
.ct-tarjeta.ct-tarjeta-triple { padding-left: 12px; padding-right: 12px; }
@media (max-width: 1024px) { .ct-tarjeta-triple { grid-column: span 1; } }
/* Sombra en tres capas en vez de una: un contacto de 1px que asienta la
   tarjeta, una difusa corta que le da grosor y una larga y muy tenue que la
   separa del fondo. Una sola sombra grande se ve como una mancha; tres cortas
   se leen como una pieza apoyada. El radio sube de 14 a 18 para acompanar el
   radio nuevo de las barras. */
/* Fondo Verde Emprendedor, solo en las tarjetas de la REJILLA: la vista abierta
   (.ct-detalle) sigue en blanco, porque ahi el grafico ocupa 1.200px y el verde
   sobre verde pesa mucho mas.

   Medido, y hay que decirlo: sobre #D8F4D7 el tope del degradado de la barra de
   compras (#66BB7B) queda en 1,99:1 contra el fondo, verde sobre verde; tres
   piezas claras se funden del todo —la linea base (1,04:1), el fondo de la trama
   del mes en curso (1,07:1) y el riel del interruptor (1,08:1)—; y tres textos
   de apoyo en --gray-500 caen de 4,74 a 4,03 y dejan de pasar el 4,5:1. Los
   ajustes minimos estan propuestos pero NO aplicados: la decision es de quien
   encargo esto. */
/* min-height: pedido explicito de simetria (Miguel, PBI 737/738) -- TODAS
   las tarjetas de la rejilla a la misma altura siempre, aceptando que crezcan
   un poco si hace falta. Antes de esto, activos_mensual_dual (2 columnas,
   con leyenda de colores SIEMPRE visible y un numero destacado mas chico,
   .ct-valor-dual) quedaba mas alta que sus vecinas de 1 columna aunque el
   GRAFICO ya rindiera a la misma altura (ver CT_TARJETA_ANCHA_VB_ALTO en
   control-tower.js): el resto del contenido (cabecera, periodo, el numero,
   el estado del mes, los interruptores, la leyenda) no tiene por que medir
   lo mismo entre una tarjeta y otra, y no hay forma de igualarlo ajustando
   el grafico solo.

   min-height (no height fijo) para no recortar nada si algun dia una
   tarjeta necesita mas espacio -- crece en vez de tapar contenido.

   El numero sale de sumar cada bloque de esta tarjeta con los valores que
   YA estan declarados en este archivo (padding 18+18, .ct-valor con
   line-height:1.1 explicito, el alto del grafico ya calculado con precision)
   y, donde el CSS NO declara line-height (cabecera, periodo, mes,
   controles, leyenda), un interlineado de 1,3x el tamano de fuente -- el
   mismo criterio que ya uso una vez este archivo para DM Sans ("17px de
   texto a 13px", 17/13=1,308).

   REVISADO (encargo "subtitulos explicativos y reubicar criterio de mora"):
   subiendo de 360 a 400px porque dos bloques nuevos entraron a la cuenta.
   .ct-tarjeta-subtitulo (las CINCO tarjetas) SI declara su line-height
   (1.35, ver esa regla), asi que su aporte es exacto, no estimado: 2 lineas
   a 12px x 1,35 = 32,4px, mas un gap de 8px. .ct-criterio-tarjeta (solo
   NPL/ICV) ocupa una fila de ~24px (el <select>, con su padding declarado
   de 4px+4px y ~13px x ~1,2 de interlineado no declarado) mas un gap de
   8px. Con esos dos bloques agregados a la base de ~344px, el caso mas alto
   pasa a ser TPV (subtitulo + controles reales + leyenda, sin el criterio
   que es exclusivo de NPL): ~384,5px. 400px deja ~15,5px de margen -- un
   colchon parecido al que ya tenia el numero anterior (360 sobre ~344),
   para lo que el interlineado de 1,3x no puede prometer sin un navegador
   real.

   Sigue en 400px con nuevos_activados_mensual (PBI 739): misma FORMA que
   tenia activos_mensual antes de retirarse (subtitulo + controles reales,
   SIN leyenda, sin criterio), asi que su alto natural es menor al de TPV,
   no mayor -- no hizo falta recalcular el numero.

   SUBE a 430px con tpv_categoria_comercio a 2 columnas (PBI 742, encargo
   "tarjeta de 2 columnas y separador entre segmentos"): esta es la primera
   tarjeta con una leyenda de MAS DE UNA fila (hasta 15 categorias, ver
   ctLeyendaCategoriaComercio), y esa leyenda mas alta no se resuelve
   igualando solo el alto del grafico (CT_TARJETA_ANCHA_VB_ALTO) -- hay que
   sumarla al calculo de la tarjeta ENTERA.
   Simulado el wrap de la leyenda contra el ancho real de 2 columnas
   (1042,667px, con el mismo criterio de ancho por caracter que ya usa
   ctAnchoTexto): a los 15 nombres de categoria en espanol, entran unas 8-9
   por fila, entonces son 2 filas (a 1 columna hubieran sido 5). Leyenda de
   2 filas = 2 x (12px x 1,3 de interlineado no declarado) + 1 gap de fila
   (14px, el mismo gap de .ct-leyenda) + su margin-top (6px) = ~51,2px,
   contra los ~21,6px de una leyenda de 1 fila que ya estaban en la cuenta
   de 384,5px de TPV. Restando esos 21,6px y sumando los 51,2px nuevos:
   384,5 - 21,6 + 51,2 = ~414,1px. 430px deja ~15,9px de margen, el mismo
   colchon proporcional que ya usaban 360 y 400.

   SUBE a 460px (encargo "filtro Todos y aclaracion Barras/Linea", PBI 742),
   y CORRIGE un error del calculo de arriba, no solo lo extiende: al
   resimular el wrap para sumar el nuevo item "Todos" (ver
   ctLeyendaCategoriaComercio) con el ancho REAL de cada entrada -- 15
   nombres de categoria, uno por uno, no un promedio de "8-9 por fila" --
   la leyenda da 3 filas, no 2, CON o SIN "Todos" agregado. El calculo de
   430px no sumaba el checkbox (12px + su gap de 5px = 17px por entrada) a
   la cuenta de ancho, solo swatch+gap+texto: sin el checkbox alcanzaban 2
   filas (7 y 8 items), pero el checkbox SI esta en el HTML desde el
   encargo que agrego el filtro (anterior a este), asi que la tarjeta YA
   estaba rindiendo 3 filas de leyenda antes de este encargo, con 430px
   dandole apenas ~-14px (una fila entera sin cubrir, no ~16px de margen)
   -- ver el detalle de la resimulacion, con las 15 entradas reales, en el
   historial de esta sesion.
   Leyenda de 3 filas = 3 x (12px x 1,3) + 2 gaps de fila (14px c/u) + su
   margin-top (6px) = 46,8 + 28 + 6 = ~80,8px, contra los ~21,6px de 1 fila
   que ya estaban en la base de 384,5px de TPV: 384,5 - 21,6 + 80,8 =
   ~443,7px. 460px deja ~16,3px de margen, el mismo colchon absoluto que ya
   usaron 360, 400 y 430.
   El nuevo item "Todos" (agregado en este mismo encargo) NO suma una
   cuarta fila: en la resimulacion completa (16 entradas, "Todos" primero)
   la fila 1 sigue cerrando en el mismo punto que sin el ("Todos" es corto,
   32px + 6,24px/caracter x 5 caracteres = ~63px, mas chico que la mayoria
   de las categorias), asi que 443,7px sigue siendo el numero correcto CON
   "Todos" incluido, no uno mas.
   El delta inline junto al monto (.ct-delta-inline, ver ese comentario) y
   el subtitulo nuevo de esta tarjeta (ctSubtituloTarjeta,
   subtituloCategoriaComercio) NO suman nada aparte a esta cuenta: el delta
   es un span DENTRO de la linea de .ct-valor, mas chico que su
   line-height heredado (14px x 1,1 = 15,4px, contra el strut de 30px x
   1,1 = 33px del bloque, asi que no crece la caja de linea); el subtitulo
   ya estaba presupuestado -- el calculo de 384,5px de TPV parte de una
   tarjeta que YA tiene su propio subtitulo, y tpv_categoria_comercio
   comparte esa misma base aunque hasta este encargo no pintara el suyo. */
.ct-tarjeta { background: var(--yaya-verde-emprendedor, #D8F4D7); border: 1px solid var(--yaya-crecimiento-tenue, #95A7A6); border-radius: 18px; padding: 18px 20px; box-shadow: 0 1px 1px rgba(16,24,40,.04), 0 2px 6px rgba(16,24,40,.05), 0 12px 24px -12px rgba(16,24,40,.10); display: flex; flex-direction: column; gap: 8px; cursor: pointer; transition: box-shadow .18s, border-color .18s, transform .18s; min-height: 460px; }
/* Alto fijo (PBI 1001, tarea 1255, regla de Miguel del 16/10/2026): desde
   1025px, donde la rejilla tiene 3 columnas, toda tarjeta de la rejilla mide
   --ct-tarjeta-alto; solo cambia el ancho. El min-height de 460px de arriba
   queda para la ventana angosta (1 columna, alto natural, como siempre) y
   para la franja y el detalle no cambia nada: no son .ct-rejilla .ct-tarjeta.
   El grafico es el hijo que crece (flex 1 1 0) y se lleva el alto libre; lo
   que va despues (leyendas, notas de TRM) queda al pie. 140px es el minimo
   (CT_GRAFICO_TARJETA_MIN_PX en control-tower.js): si una tarjeta no llega,
   su contenido sobresale, no se recorta. ctAjustarGraficosTarjetas mide la
   caja y lo redibuja con un viewBox de ese alto: el CSS solo reparte, nunca
   estira. ctGraficoLineaN trae su svg dentro de .ct-grafico-linea-wrap: ahi
   crece el envoltorio y el svg adentro. */
@media (min-width: 1025px) {
    .ct-rejilla .ct-tarjeta { height: var(--ct-tarjeta-alto); }
    .ct-rejilla .ct-tarjeta > svg.ct-grafico,
    .ct-rejilla .ct-tarjeta > svg.ct-grafico-linea { flex: 1 1 0; min-height: 140px; }
    .ct-rejilla .ct-tarjeta > .ct-grafico-linea-wrap { flex: 1 1 0; display: flex; flex-direction: column; }
    .ct-rejilla .ct-tarjeta > .ct-grafico-linea-wrap > svg { flex: 1 1 0; min-height: 140px; }
}
.ct-tarjeta:hover { border-color: var(--yaya-verde-crecimiento, #022D2B); box-shadow: 0 1px 1px rgba(16,24,40,.05), 0 4px 10px rgba(16,24,40,.07), 0 18px 32px -14px rgba(16,24,40,.16); transform: translateY(-1px); }
.ct-tarjeta-cabecera { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
/* Nombre del indicador: Poppins 600, sin mayuscula sostenida y letter-spacing 0
   (PBI 973, decision de Miguel, 23/09/2026; antes era Centory of Brush en
   mayuscula sostenida, peso 400 y letter-spacing .03em). Los nombres vienen del
   catalogo del backend y no se tocan: las siglas (TPV, NPL, ICV, TRM, 60D) ya
   llegan en mayuscula, y ningun nombre viene entero en mayusculas.

   Peso 600: es el unico que trae el .ttf local ('YaYa Poppins', ver
   fuentes-marca.css), asi que no hay peso sintetico; la 'Poppins' de Google
   tambien lo tiene (enterprise.css importa 400-700).

   Poppins NO trae el glifo "→" (medido sobre fonts/Poppins-SemiBold.ttf):
   en "Activación → primera compra → retención" la flecha cae al ultimo
   escalon, DM Sans (su archivo Bold, por el peso 600). Centory tampoco la traia.

   ALTO DE LINEA: .ct-nombre no declara line-height, asi que usa el de la
   fuente. Poppins mide 1,5 (hhea y typo, con USE_TYPO_METRICS) contra 1,2 de
   Centory: la fila de cabecera de cada tarjeta pasa de ~22,8px a 28,5px. */
/* 19px (era 15px). A 15px el nombre quedaba a dos puntos y medio del texto de
   apoyo que lo rodea —.ct-mes 12,5px, .ct-periodo 12px, .ct-unidad 11px— y no se
   leia como el titulo de la tarjeta. A 19px hay un escalon claro (1,5x sobre el
   texto de apoyo) y sigue por debajo de la cifra destacada (30px) y del titulo
   del modulo (26px), que es el orden correcto.

   ANCHO, re-medido con Poppins 600 a 19px (PBI 973) sobre las metricas de
   fonts/Poppins-SemiBold.ttf, sin kerning: sale entre 2% y 9% mas ancho que
   Centory en mayuscula (la medicion vieja, "TRM PROMEDIO MENSUAL" = 209px en
   Centory, da 214px con el mismo metodo; en Poppins "TRM promedio mensual" es
   229px). La fila es nombre + gap 8px + .ct-unidad, contra un interior de
   tarjeta de ancho 1 que es ~491px desde 1.820px de ventana y se achica por
   debajo (~365px a 1.440, ~311px a 1.280). Sigue en una linea a 1.920px todo
   menos "Transacciones por cliente activo 60D" (540px de fila con su unidad
   "TRANSACCIONES POR CLIENTE"), que ya partia en dos con Centory (529px). */
.ct-nombre { font-family: var(--ct-fuente-nombre); letter-spacing: 0; font-size: 19px; font-weight: 600; color: var(--ct-texto); }
.ct-unidad { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ct-texto-suave); }
/* Subtitulo explicativo de las CINCO tarjetas (encargo "subtitulos
   explicativos y reubicar criterio de mora"), debajo del nombre y antes del
   periodo -- ver ctSubtituloTarjeta. line-height EXPLICITO (a diferencia de
   .ct-periodo/.ct-mes, que no lo declaran) a proposito: es el bloque que
   mas le puede variar el alto a la tarjeta segun cuanto texto tenga cada
   indicador, y con un numero exacto (no heredado del navegador) se puede
   calcular su aporte al min-height de .ct-tarjeta con precision en vez de
   estimarlo.

   -webkit-line-clamp:2 (mas su version estandar sin prefijo) es un tope
   DURO: si algun texto resultara mas largo de lo medido -- distinto largo
   de fuente, una traduccion mas larga -- se corta con "..." en vez de
   agregar una tercera linea que rompa la altura pareja de la fila. Medido
   (0,52em por caracter, el mismo criterio que ya usa ctAnchoTexto en
   control-tower.js para las etiquetas de los graficos) contra el interior
   real de una tarjeta de 1 columna (493px) y de 2 columnas (1042px): a 12px
   de fuente entran ~79 caracteres por linea en 1 columna y ~167 en 2. Los
   textos (98, 50, 80, 139, 197 y 146 caracteres respectivamente, el ultimo
   agregado con nuevos_activados_mensual en el PBI 739) entran en 2 lineas o
   menos con ese presupuesto -- el mas ajustado es "Clientes Activos" (139
   de 158 disponibles; el de Nuevos Clientes Activados, 146, queda cerca
   pero por debajo), y en cualquier caso el line-clamp es la red de
   seguridad si la estimacion sin navegador se quedara corta. */
.ct-tarjeta-subtitulo { margin: 0; font-size: 12px; line-height: 1.35; color: var(--ct-texto-suave); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.ct-periodo { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--ct-texto-suave); margin-bottom: 2px; }
/* La cifra destacada vuelve a DM Sans: hereda de .ct-root, por eso no declara
   font-family. Suti salio del modulo; su @font-face sigue en fuentes-marca.css,
   anotada como sin consumidor.

   Lo que se midio de Suti mientras estuvo, por si vuelve: trae los diez digitos
   y cubre todo lo que .ct-valor imprime, y no es italica (su post.italicAngle es
   0). Sus digitos son proporcionales, pero eso no la distingue de las otras:
   ninguna de las cinco fuentes de fonts/ tiene la feature tnum, asi que no hay
   numerales tabulares que pedir por CSS en ninguna. */
.ct-valor { font-size: 30px; font-weight: 700; letter-spacing: -0.02em; color: var(--ct-texto); line-height: 1.1; }
/* rojoNegativo (CT_CIERRES_MES, el 5.2, PBI 1001, tarea 1245): la cifra de una foto
   menor que cero. Solo la cifra. Sobre #D8F4D7 da 4,1:1, que a 30px en negrita pasa
   el 3:1 de texto grande. Dos clases: le gana a .ct-valor sin depender del orden. */
.ct-valor.ct-valor-negativo { color: var(--red-600, #dc2626); }
.ct-mes { font-size: 12.5px; color: var(--ct-texto-suave); display: flex; gap: 10px; flex-wrap: wrap; }
.ct-trm { color: var(--ct-texto-suave); }
.ct-grafico { width: 100%; height: auto; display: block; margin-top: 4px; }
/* Relleno de las barras. Los cuatro estados (normal, apilada, mes en curso y
   periodo seleccionado) se siguen resolviendo por clase como antes; lo unico
   que cambio es QUE valor toma fill: donde habia un color plano ahora hay una
   referencia al degradado o a la trama que define ctDefsSvg.

   Los ids url(#...) no llevan respaldo posible, asi que si el svg de defs no
   estuviera en el documento la barra quedaria sin pintar. Lo pone ctRender al
   principio de la raiz, antes que cualquier grafico. */
.ct-barra { fill: url(#ct-grad-compras); }
/* Mes en curso: trama diagonal y borde punteado, en vez del relleno palido de
   antes. El palido decia "menos", que no es lo que pasa: el mes existe y esta
   completo hasta hoy, lo que le falta es cerrar. Una trama dice "en curso" sin
   sugerir que el dato valga menos, y el punteado es la convencion de "todavia
   no es definitivo". */
.ct-barra-abierta { fill: url(#ct-trama-compras); }
.ct-barra-parcial { fill: var(--yaya-crecimiento-tenue, #95A7A6); }
/* Brillo interno del canto de arriba. pointer-events:none es obligatorio: el
   trazo cruza justo por donde el mouse entra a la barra, y sin eso se comeria
   el hover del tooltip y el clic que abre el periodo. */
.ct-barra-brillo { fill: none; stroke: rgba(255,255,255,.55); stroke-width: 1; stroke-linecap: round; pointer-events: none; }
/* La linea base pasa del gris al verde claro de la familia: --gray-200 contra la
   tarjeta daba 1,04:1 y el eje del grafico directamente no se veia. Con
   --yaya-crecimiento-luz da 3,35:1, que para una linea de 1px es de sobra. */
.ct-base { stroke: var(--yaya-crecimiento-luz, #6C8584); stroke-width: 1; }
/* Texto DENTRO de los SVG. Pasa a DM Sans como el resto del texto del modulo:
   dejarlo en la fuente del sistema partia el tablero en dos tipografias segun se
   mirara adentro o afuera del grafico.

   El riesgo era ctAnchoTexto, que estima el ancho en 0,52em por caracter y
   decide con eso si las etiquetas se pisan. Medido contra los archivos, sobre
   las etiquetas que el codigo genera de verdad y no sobre promedios: la fecha
   mas ancha pasa de 28,1u estimados a 29,4u reales en la serie mensual (+4,7%) y
   a 30,1u en la diaria (+7,1%), y el valor mas ancho ("$ 200,0 M") de 46,8u a
   47,5u (+1,5%). Con esos numeros el "cada" de ctFechasEje da IGUAL en las seis
   combinaciones de ventana y tamano, asi que el 0,52 se queda como esta. */
/* El texto de los SVG usa los MISMOS dos verdes que el texto de HTML: es texto
   sobre la misma tarjeta y no habia razon para que siguiera en gris. Las fechas
   del eje se van al suave (5,55:1) y las etiquetas de valor al pleno (12,63:1);
   antes eran --gray-400, que sobre la tarjeta daba 2,14:1, y --gray-700. */
.ct-eje { font-size: 9px; fill: var(--ct-texto-suave); font-family: var(--ct-fuente-texto); }
/* Revision Ola 3 (rotulos): desde 1025px la tarjeta redibuja su grafico con
   9u = 11px (ctAjustarGraficosTarjetas); los meses van un punto abajo, a ~10px
   (8,2u x 11/9). ctFechasEje los sigue midiendo a 9u: quedan con aire de mas.
   Solo la rejilla: el detalle no cambia. */
.ct-rejilla .ct-tarjeta svg .ct-eje { font-size: 8.2px; }
.ct-valor-punto { font-size: 9px; font-weight: 600; fill: var(--ct-texto); font-family: var(--ct-fuente-texto); }
/* Descripcion del indicador en la VISTA ABIERTA. Va DENTRO del bloque de
   titulo de la cabecera, debajo del nombre, y por eso ya no lleva max-width:
   suelta en el cuerpo y recortada a 78ch se leia como un bloque de texto de
   500px pegado a la izquierda, desconectado de una vista de 1.600. Como
   subtitulo del nombre no necesita recorte —hereda el ancho del bloque de
   titulo— y se lee como lo que es: la aclaracion de que mide este indicador. */
.ct-detalle-descripcion { margin: 3px 0 0; font-size: 13px; line-height: 1.5; color: var(--ct-texto-suave); }
.ct-estado { padding: 40px 20px; text-align: center; color: var(--gray-500); background: var(--bg-primary); border: 1px dashed var(--gray-200); border-radius: 14px; }
.ct-estado-error { color: var(--red-600); border-color: #fecaca; }
.ct-boton { margin-left: 10px; border: 1px solid var(--gray-300); background: var(--bg-primary); border-radius: 8px; padding: 6px 12px; font: inherit; font-size: 13px; cursor: pointer; }
/**
 * Excepcion de .ct-boton SOLO dentro de .ct-periodo-detalle (encargo
 * "Contraste de deltas y boton Cerrar en .ct-periodo-detalle" -- cambio
 * INDEPENDIENTE del de .ct-delta-sube/baja de mas abajo, aunque los dos
 * vivan en el mismo bloque: no se combinan en una regla).
 *
 * .ct-boton es una clase COMPARTIDA: la usa el boton "Volver" de la
 * cabecera (.ct-detalle-cabecera, dentro de .ct-detalle -- el panel de
 * arriba, sin cambios) Y el boton "Cerrar" de ctBloquePeriodo/
 * ctBloquePeriodoActivos (dentro de .ct-periodo-detalle). Sin fondo propio,
 * "Cerrar" heredaria el D8F4D7 que .ct-periodo-detalle redefine en
 * --ct-texto (Miguel lo vio en el navegador: 1,18:1 contra el fondo blanco
 * del boton, casi invisible, calculado y confirmado). En vez de eso, Miguel
 * pidio invertir los roles DENTRO del boton mismo: fondo D8F4D7, texto
 * 022D2B -- 12,63:1, calculado y confirmado (el mismo par y el mismo numero
 * que ya da el texto del bloque contra su propio fondo, pero invertido).
 *
 * Override LOCAL por selector descendiente, no un cambio a .ct-boton a
 * secas: "Volver" (arriba, sobre el verde claro de .ct-detalle) sigue
 * necesitando su fondo blanco y su texto oscuro heredado de siempre, sin
 * tocar.
 */
.ct-periodo-detalle .ct-boton { background: var(--yaya-verde-emprendedor, #D8F4D7); color: var(--yaya-verde-crecimiento, #022D2B); }
.ct-pie { margin: 18px 0 0; font-size: 11.5px; color: var(--ct-texto-suave); text-align: right; }
/* En pantalla angosta la cabecera se parte igual (flex-wrap), pero 56px de
   titulo se comerian la pantalla: baja a 34px, que sigue siendo el doble del
   resto y entra en un telefono. */
@media (max-width: 720px) { .ct-root { padding: 18px 14px 36px; } .ct-valor { font-size: 26px; } .ct-titulo { font-size: 34px; } }

/* Detalle de indicador (clic en la tarjeta). Mismo lenguaje visual que .ct-tarjeta. */
/* La vista abierta lleva el mismo verde que la tarjeta.
   Tres razones. La tarjeta y el detalle son el MISMO objeto a dos tamanos: que
   la superficie cambie al hacer clic se lee como haber navegado a otro lado.
   Todo el trabajo de contraste de esta tanda —la rampa de las barras, la linea
   base, la trama, el riel, los dos verdes de texto— esta calibrado contra
   #D8F4D7, asi que dejar el detalle en blanco obligaria a mantener un segundo
   juego de colores para los mismos componentes. Y el radio y la sombra ya venian
   igualando las dos piezas.

   El reparo de que ahi el grafico ocupa 1.200px y el verde pesa mas es cierto, y
   por eso el bloque suplementario de periodo (.ct-periodo-detalle) se queda en
   su neutro claro: da un escalon de luminosidad adentro de la vista en vez de un
   unico pano verde de punta a punta. */
/* scroll-margin-top (encargo "Posicion de scroll al abrir el detalle y al
   seleccionar un periodo"): ctAbrirDetalle hace scrollIntoView sobre este
   elemento al abrir un indicador. Sin este margen, el titulo/boton Volver
   quedarian TAPADOS por el header fijo de VIRGILIO (.header, position:fixed,
   116px de alto, ver css/layout.css) -scrollIntoView alinea el borde
   superior de .ct-detalle contra el borde superior del contenedor con
   scroll, que es exactamente donde ese header se superpone. 130px es el
   mismo numero que ya usa #page-control-tower como padding-top por el
   MISMO motivo (compensar ese header) -reusado, no inventado. */
.ct-detalle { background: var(--yaya-verde-emprendedor, #D8F4D7); border: 1px solid var(--yaya-crecimiento-tenue, #95A7A6); border-radius: 18px; padding: 20px 24px; scroll-margin-top: 130px; }
/* align-items: flex-start (era center) para que el boton Volver quede alineado
   con el nombre y no se centre contra el bloque de dos lineas que ahora forman
   nombre + descripcion. */
.ct-detalle-cabecera { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 16px; }
.ct-detalle-titulo { flex: 1; min-width: 0; }
.ct-destacado { margin-bottom: 8px; }
.ct-grafico-linea { width: 100%; height: auto; display: block; margin: 8px 0 16px; }
.ct-linea-area { fill: url(#ct-grad-area); }
/* El grafico de linea sigue la misma regla que las barras: el trazo y los puntos
   pasan al Verde crecimiento. Contra la tarjeta el trazo pasa de 2,87:1 (que es
   lo que daba #2AA048) a 12,63:1, y el area de abajo es el mismo verde con la
   opacidad cayendo de .24 a .02, o sea el degradado de la barra al reves. */
.ct-linea-trazo { fill: none; stroke: var(--yaya-verde-crecimiento, #022D2B); stroke-width: 2; }
/* Trazo de ctGraficoLineaN (N series simultaneas, color propio de cada una):
   estructural nada mas, sin stroke fijo -- el color llega por inline style,
   igual que los segmentos de categoria en ctGrafico (N colores arbitrarios
   no entran en un numero fijo de clases CSS con proposito, ver ese
   comentario). Los puntos reusan .ct-linea-punto tal cual, con el mismo
   mecanismo de inline style pisando su fill. */
.ct-linea-trazo-n { fill: none; stroke-width: 2; }
.ct-linea-guia { stroke: var(--yaya-crecimiento-luz, #6C8584); stroke-width: 1; opacity: .45; }
.ct-linea-punto { fill: var(--yaya-verde-crecimiento, #022D2B); }
.ct-linea-punto-cierre { fill: var(--yaya-verde-crecimiento, #022D2B); stroke: var(--yaya-verde-emprendedor, #D8F4D7); stroke-width: 1.5; }
/* Punto provisional (opciones.puntoAbierto de ctGraficoLinea y
   ctGraficoTarjetaLinea, hoy la cohorte provisional del FPD): hueco, con el
   mismo borde punteado de la barra abierta (.ct-contorno-abierta). */
.ct-linea-punto-abierto { fill: var(--yaya-verde-emprendedor, #D8F4D7); stroke: var(--yaya-verde-crecimiento, #022D2B); stroke-width: 1.5; stroke-dasharray: 2 1.5; }
.ct-grafico-vacio { padding: 24px; text-align: center; color: var(--ct-texto-suave); font-size: 13px; }

/* Tooltip propio de los puntos de la linea (reemplaza <title> nativo): wrap con
   position:relative para anclar el tooltip absoluto a la posicion del mouse. */
/* Ancho de render del grafico del detalle. Es lo que fija la escala, porque el
   viewBox (CT_DETALLE_VB_ANCHO, hoy 864) se estira hasta aca: 1200/864 = 1,389.
   Ese 1,389 es deliberado y NO hay que "arreglarlo" igualandolo al viewBox como
   estaba antes. Con escala 1,00 el texto del grafico, que mide 9u, salia de 9px
   contra los 12,5-13px del resto de la pagina y se veia chico; a 1,389 sale de
   12,5px, que es el tamano del texto de la vista. Todo lo demas escala con el
   mismo factor, asi que la barra sigue midiendo los mismos 70,6px de siempre y
   el grafico los mismos ~280px de alto.

   Los 1.200px en si vienen de la medicion anterior: con el contenedor en
   1.584px, dejar que el SVG lo ocupe entero daba un grafico de 545px de alto
   que se comia media pantalla. */
.ct-grafico-linea-wrap { position: relative; max-width: 1200px; }
.ct-tooltip-linea { position: absolute; display: none; pointer-events: none; transform: translate(-50%, -100%); margin-top: -10px; background: var(--gray-900, #111827); color: #fff; font-size: 12px; line-height: 1.5; padding: 8px 10px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,.2); white-space: nowrap; z-index: 5; }
.ct-tooltip-fecha { font-weight: 700; margin-bottom: 2px; }

/* Linea de contexto bajo el valor destacado del detalle (con que parametros se
   calculo), especifica de npl_diario. */
.ct-contexto-npl { font-size: 12px; color: var(--ct-texto-suave); font-style: italic; margin-top: 2px; }

/* Anualizado (Revenue Run Rate) bajo el valor destacado del detalle, de los
   indicadores de CT_PAR_APILADO -- ver ctBloqueRunRate en control-tower.js
   para cuando se dibuja y cuando no existe en absoluto.

   Vive en el mismo renglon logico que .ct-contexto-npl (texto de apoyo bajo el
   numero grande) pero lleva un numero propio, asi que no puede ser una linea
   de 12px entera: la etiqueta y la nota se quedan en el peso de apoyo
   (.ct-run-rate-etiqueta copia el tamano/peso/tracking de .ct-periodo-medidas
   y .ct-run-rate-nota el de .ct-contexto-npl) y solo el valor sube a 18px --
   por debajo de los 30px de .ct-valor, que sigue siendo el titular de la
   vista, y por encima del texto de apoyo, para que se lea como una cifra.

   align-items:baseline alinea las tres piezas por la linea de texto y no por
   la caja, que es lo unico que hace que un numero de 18px conviva en la misma
   fila con dos textos de 11-12px sin verse flotando. flex-wrap para que en
   pantalla angosta la nota caiga abajo en vez de apretar el numero.

   Los colores son los dos que ya usa el modulo para esta jerarquia
   (--ct-texto para la cifra, --ct-texto-suave para etiqueta y nota): no hace
   falta ningun tono nuevo, este bloque es texto sobre la misma superficie
   verde de .ct-detalle contra la que los dos ya estan calibrados. */
.ct-run-rate { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.ct-run-rate-etiqueta { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ct-texto-suave); }
.ct-run-rate-valor { font-size: 18px; font-weight: 600; color: var(--ct-texto); }
.ct-run-rate-nota { font-size: 12px; color: var(--ct-texto-suave); font-style: italic; }

/* Criterio de calculo de npl_diario (Tope de castigo / Inicio de mora), DENTRO
   de la tarjeta/detalle de NPL-ICV (encargo "subtitulos explicativos y
   reubicar criterio de mora"): ya no es la franja de ancho completo que vivia
   arriba de la rejilla (esa version, con su filete izquierdo y su propio
   fondo/borde para distinguirse de una tarjeta, se retiro entera -- no hacia
   falta nada de eso estando ya adentro de una). Mismo lenguaje visual que
   .ct-controles-indicador (fila de controles secundarios, 12px, cursor
   default): las dos conviven en la misma tarjeta para otros indicadores, asi
   que tienen que leerse como la misma familia de fila.

   Sin etiqueta de grupo ("Criterio de mora"): las dos etiquetas de campo
   ("Tope de castigo", "Inicio de mora") ya dicen de que se trata, y estar
   dentro de la tarjeta de NPL/ICV ya da ese contexto -- ahorra una linea de
   alto en una tarjeta que ya creamos con el subtitulo nuevo. */
.ct-criterio-tarjeta { display: flex; flex-wrap: wrap; gap: 14px; margin: 2px 0 2px; font-size: 12px; color: var(--ct-texto-suave); cursor: default; }
.ct-criterio-tarjeta label { display: inline-flex; align-items: center; }
/* Toggle chico: mismo lenguaje que .ct-toggle pero en linea con una etiqueta,
   para los interruptores de grafico y de cashouts. */
.ct-toggle-mini { display: inline-flex; margin-left: 6px; vertical-align: middle; }
.ct-toggle-mini .ct-toggle-btn { padding: 4px 10px; font-size: 12px; }
.ct-control-linea { display: inline-flex; align-items: center; gap: 4px; }
.ct-control-etiqueta { font-size: 12px; color: var(--ct-texto-suave); }
/* Interruptores por indicador: dentro de la tarjeta y dentro de la vista
   abierta, entre el encabezado y el grafico. cursor:default para que se
   distingan de la tarjeta, que entera es clicable para abrir el detalle. */
.ct-controles-indicador { display: flex; flex-wrap: wrap; gap: 14px; margin: 2px 0 2px; cursor: default; }

/* Grafico clicable (solo en el detalle): el cursor avisa que cada barra o punto
   abre el detalle de ese periodo. */
.ct-grafico-interactivo .ct-barra,
.ct-grafico-interactivo .ct-barra-abierta,
.ct-grafico-interactivo .ct-barra-parcial,
.ct-grafico-interactivo .ct-linea-punto { cursor: pointer; }
.ct-barra-sel { fill: url(#ct-grad-compras-sel); }
.ct-linea-punto-sel { fill: var(--gray-900); stroke: var(--bg-primary); stroke-width: 2; }

/* Segmento de cashouts de la barra apilada del TPV: Coral Empuje, de la paleta
   de marca (ver el bloque "Paleta de marca YaYa" en design-system.css). Antes
   era --amber-500, que no es de marca y se habia elegido por descarte: --blue-*
   dice "blue" pero vale los verdes de --primary-600/700, asi que no servia de
   segundo tono. Con la paleta cargada el ambar ya no hace falta.

   Los hex de respaldo dentro de var() no son colores sueltos: son el valor de
   la misma variable, y estan porque design-system.css se sirve cacheado. Sin
   respaldo, un navegador con el CSS viejo no resolveria --yaya-coral-empuje, el
   fill quedaria invalido y el segmento se pintaria de negro. Es el mismo patron
   que ya usan .ct-tooltip-linea y .ct-periodo-detalle mas abajo.

   Va despues de .ct-barra y .ct-barra-abierta a proposito: contra ellas empata
   en especificidad (una clase) y gana por orden. Contra .ct-barra-sel no hace
   falta el orden porque los combinados de abajo llevan dos clases, pero quedan
   juntos para leerse de una.

   Los dos combinados existen porque .ct-barra-abierta y .ct-barra-sel pisan
   fill: sin ellos, el mes en curso y el periodo seleccionado perderian el color
   del segmento y la barra volveria a verse de un solo color justo en los dos
   estados donde mas se la mira. Cada uno conserva el borde que da su estado
   (el trazo de "abierta", el gris de "seleccionada") y solo cambia el relleno a
   la rama coral. */
.ct-barra-cashouts { fill: url(#ct-grad-cashouts); }
.ct-barra-cashouts.ct-barra-abierta { fill: url(#ct-trama-cashouts); }
.ct-barra-cashouts.ct-barra-sel { fill: url(#ct-grad-cashouts-sel); }
/* Las dos combinaciones de TRES estados. Sin ellas gana .ct-barra-sel por orden
   y seleccionar el mes en curso le borraba la trama, que es la unica senal de
   que ese mes no cerro. Aca la trama se conserva, y la seleccion la marca el
   contorno, que es una pieza aparte. */
.ct-barra-abierta.ct-barra-sel { fill: url(#ct-trama-compras); }
.ct-barra-cashouts.ct-barra-abierta.ct-barra-sel { fill: url(#ct-trama-cashouts); }
/* Barra HUECA de CT_PAR_APILADO: fila con el total y sin sus dos componentes
   (ctParSinDesglose, hoy los meses de Finanzas de ingresos_mensual). Relleno
   del color de la tarjeta para que no diga "fee de ciclo"; lo que la hace
   visible es el contorno solido (.ct-contorno-sin-desglose, mas abajo).
   Gana en los CUATRO estados, mes en curso incluido: la trama es la version
   abierta del relleno de la base y volveria a nombrar un componente (ver el
   comentario en ctGrafico). Va despues de todos los rellenos: contra .ct-barra
   empata en especificidad y gana por orden; contra .ct-barra-abierta,
   .ct-barra-sel y su combinada gana por llevar una clase mas. */
.ct-barra-sin-desglose,
.ct-barra-sin-desglose.ct-barra-abierta,
.ct-barra-sin-desglose.ct-barra-sel,
.ct-barra-sin-desglose.ct-barra-abierta.ct-barra-sel { fill: var(--yaya-verde-emprendedor, #D8F4D7); }

/* Contorno de la barra: el perfil de la silueta completa, sin relleno, dibujado
   por encima de todo. Existe solo en los estados con borde. Las piezas
   RELLENAS ya no llevan stroke, justamente para que el borde salga de aca y de
   ningun otro lado (ver el comentario del contorno en ctGrafico).

   pointer-events:none por lo mismo que el brillo: cubre toda la barra y sin eso
   se quedaria con el hover y el clic que pertenecen a los segmentos.

   Las clases de estado del contorno son propias (ct-contorno-*) y no las mismas
   de los rellenos: .ct-barra-abierta y .ct-barra-sel declaran fill, y su
   combinada le ganaria por especificidad al fill:none de aca, con lo que el
   contorno de un mes en curso seleccionado saldria relleno y taparia la barra.
   Con nombres aparte no hay empate que resolver. */
.ct-barra-contorno { fill: none; stroke: none; pointer-events: none; }
.ct-contorno-abierta { stroke: var(--yaya-verde-crecimiento, #022D2B); stroke-width: 1; stroke-dasharray: 3 2; }
.ct-contorno-sel { stroke: var(--gray-900); stroke-width: 1; }
.ct-contorno-abierta.ct-contorno-sel { stroke: var(--gray-900); stroke-dasharray: 3 2; }
/* Contorno de la barra hueca: SIEMPRE presente (sin el, la barra se funde con
   la tarjeta) y SOLIDO, que es lo que la separa del mes en curso (trama +
   punteado). #022D2B da 12,63:1 contra la tarjeta. En curso suma el punteado
   de .ct-contorno-abierta, que no toca el color. Seleccionada pasa al gris de
   siempre pero a 2u: --gray-900 y #022D2B son casi el mismo oscuro, y en una
   barra sin relleno que cambie no hay otra senal de seleccion. */
.ct-contorno-sin-desglose { stroke: var(--yaya-verde-crecimiento, #022D2B); stroke-width: 1; }
.ct-contorno-sin-desglose.ct-contorno-sel { stroke: var(--gray-900); stroke-width: 2; }
/* Barra corta HUECA: tpv_mensual con Excluidos en un mes de Finanzas, que no
   publica compras (ctTpvSinDesglose). Es el <rect> de .ct-barra-parcial, sin
   pieza de contorno aparte, asi que el borde va en el mismo rect. El relleno
   ya lo pone .ct-barra-sin-desglose de arriba, que va despues de
   .ct-barra-parcial (gana por orden) y su combinada con .ct-barra-sel lleva
   una clase mas que .ct-barra-sel. Mismo borde solido y mismo 2u gris
   seleccionada que la barra hueca: el gris de la parcial de siempre es el de
   la trama del mes en curso, y este mes esta cerrado. */
.ct-barra-parcial.ct-barra-sin-desglose { stroke: var(--yaya-verde-crecimiento, #022D2B); stroke-width: 1; }
.ct-barra-parcial.ct-barra-sin-desglose.ct-barra-sel { stroke: var(--gray-900); stroke-width: 2; }

/* Separador entre segmentos de categoria (tpv_categoria_comercio, PBI 742,
   encargo "tarjeta de 2 columnas y separador entre segmentos"). UNA linea
   por borde interno (ver ctGrafico), no un stroke por segmento -- asi no
   hay dos trazos pisandose donde una tapa se apoya sobre la de abajo, y
   tampoco se duplica ct-barra-contorno (que ya traza el perimetro entero
   de la barra para "mes en curso"/"seleccionado" y no debe repetirse aca).

   Blanco puro, MEDIDO contra los 15 colores de CT_CATEGORIAS_TPV_COMERCIO:
   entre si dan ~1,0-1,05:1 (se generaron para el MISMO contraste contra el
   fondo de la tarjeta, asi que quedan con luminancia casi identica entre
   ellos -- el problema que reporta el encargo, confirmado con numeros
   antes de elegir el color). Blanco da 3,8-4,0:1 parejo contra cualquiera
   de los 15, sin importar que par le toque al lado. --gray-900 y
   --yaya-verde-crecimiento (los colores de ct-contorno-sel/abierta) se
   descartan a proposito: usarlos aca confundiria el separador -- que esta
   SIEMPRE, en las 15 categorias, en cualquier estado -- con la senal
   intermitente de mes en curso o seleccion.

   Grosor 0.6u, mas fino que el 1u del contorno de estado: se lee como una
   costura fina entre colores, no como un borde con el mismo peso visual. */
.ct-barra-separador-categoria { stroke: var(--bg-primary, #ffffff); stroke-width: 0.6; pointer-events: none; }

/* Definiciones compartidas (ctDefsSvg). El svg se esconde por tamano y overflow
   y NO con display:none, que en varios navegadores apaga tambien los gradientes
   y patrones que contiene. */
.ct-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Extremos de cada degradado. Van por clase sobre el <stop> porque stop-color
   es una propiedad CSS: asi los tonos quedan aca, con las variables de marca y
   su hex de respaldo, y no escritos a mano dentro del JS que arma el svg.

   El recorrido normal de compras cruza el verde de marca por el medio, o sea
   que la barra sigue siendo #2AA048, sombreado. El del periodo seleccionado
   arranca justo en el verde de marca y baja un escalon mas: se ve mas asentado
   sin cambiar de familia. Misma construccion para el coral. */
/* Compras pasa del Verde YaYa al Verde crecimiento #022D2B. Los nombres de
   clase se mantienen porque ctDefsSvg los escribe en el SVG: lo que cambia es a
   donde apuntan, no como se llaman.

   El fondo de las dos rampas es el mismo #022D2B. El tope es lo que las separa:
     normal        -luz   #6C8584  3,35:1 contra la tarjeta, 3,77:1 contra el
                                   fondo del propio degradado
     seleccionada  -medio #3A5B5A  6,32:1 contra la tarjeta, 2,00:1 de volumen

   OJO con la rampa seleccionada: antes corria un escalon MAS HONDO que la
   normal, y eso aca no se puede. #022D2B tiene luminancia 0,021, o sea que por
   debajo no queda practicamente nada: un "mas hondo" seria invisible. La logica
   se invierte y la rampa seleccionada es mas CORTA — arranca mas oscura arriba,
   asi que la barra se ve mas plana y mas asentada, que es el efecto que se
   buscaba. La seleccion ademas la marca el contorno gris, que no cambio. */
.ct-stop-verde-luz { stop-color: var(--yaya-crecimiento-luz, #6C8584); }
.ct-stop-verde-hondo { stop-color: var(--yaya-verde-crecimiento, #022D2B); }
.ct-stop-verde-marca { stop-color: var(--yaya-crecimiento-medio, #3A5B5A); }
.ct-stop-verde-hondo-sel { stop-color: var(--yaya-verde-crecimiento, #022D2B); }
.ct-stop-coral-luz { stop-color: var(--yaya-coral-luz, #F4A18F); }
.ct-stop-coral-hondo { stop-color: var(--yaya-coral-oscuro, #B75F4C); }
.ct-stop-coral-marca { stop-color: var(--yaya-coral-empuje, #F07C63); }
.ct-stop-coral-hondo-sel { stop-color: var(--yaya-coral-profundo, #8C493A); }
/* El area del grafico de LINEA, con el mismo verde y el mismo sentido vertical
   que las barras: asi los dos tipos de grafico se leen de la misma familia
   aunque uno sea npl_diario en % y el otro un monto. Antes era un plano al 12%
   de opacidad; ahora se desvanece hacia abajo, que es lo que hace el degradado
   de la barra al reves y deja respirar la linea base. */
.ct-stop-area-alto { stop-color: var(--yaya-verde-crecimiento, #022D2B); stop-opacity: .24; }
.ct-stop-area-bajo { stop-color: var(--yaya-verde-crecimiento, #022D2B); stop-opacity: .02; }
/* Trama del mes en curso, una por familia para que el segmento apilado no
   pierda su color al no estar cerrado. La diagonal sale del patternTransform
   rotate(45) de ctDefsSvg; aca solo van los colores y el grosor. */
/* Trama del mes en curso, rehecha sobre el verde NUEVO. Antes el fondo era
   --primary-100 #dcfce7, que contra la tarjeta #D8F4D7 daba 1,07:1: el mes sin
   cerrar desaparecia, y ademas quedaba de la familia del verde anterior.

   Ahora el fondo es --yaya-crecimiento-tenue #95A7A6, que da 2,14:1, y la
   diagonal es #022D2B a opacidad plena, que da 9,53:1 contra ese fondo y 12,63:1
   contra la tarjeta. Hay que ser honesto con el numero: NINGUN relleno claro
   llega a 3:1 contra una tarjeta clara, asi que lo que hace visible el estado no
   es el fondo sino la raya oscura, mas el contorno punteado que tambien es
   #022D2B. El fondo solo tiene que dejar de confundirse con la tarjeta, y a
   2,14:1 —el doble que antes— ya no se confunde. */
.ct-trama-fondo-verde { fill: var(--yaya-crecimiento-tenue, #95A7A6); }
.ct-trama-linea-verde { stroke: var(--yaya-verde-crecimiento, #022D2B); stroke-width: 2.4; }
.ct-trama-fondo-coral { fill: var(--yaya-coral-claro, #FDEBE8); }
.ct-trama-linea-coral { stroke: var(--yaya-coral-empuje, #F07C63); stroke-width: 2.4; opacity: .55; }

/* Leyenda de la barra apilada. Mismo tamano y color que .ct-control-etiqueta,
   con la que comparte renglon visual: la leyenda queda debajo del grafico y los
   interruptores encima, y las dos son texto de apoyo, no contenido. */
.ct-leyenda { display: flex; flex-wrap: wrap; gap: 14px; margin: 6px 0 0; font-size: 12px; color: var(--ct-texto-suave); }
.ct-leyenda-item { display: inline-flex; align-items: center; gap: 5px; }
/* La muestra repite el degradado de su barra, no el color plano: si la barra
   esta sombreada y el cuadradito no, la leyenda deja de nombrar lo que se ve.
   Va en CSS y no como url(#...) porque un <span> no puede referenciar un
   gradiente de SVG. */
.ct-leyenda-color { width: 11px; height: 11px; border-radius: 3px; flex: none; box-shadow: inset 0 1px 0 rgba(255,255,255,.45); }
.ct-leyenda-compras { background: linear-gradient(180deg, var(--yaya-crecimiento-luz, #6C8584), var(--yaya-verde-crecimiento, #022D2B)); }
.ct-leyenda-cashouts { background: linear-gradient(180deg, var(--yaya-coral-luz, #F4A18F), var(--yaya-coral-oscuro, #B75F4C)); }
/* Muestra de la barra hueca: el color de la tarjeta con el borde solido de su
   contorno. El box-shadow inset reemplaza al brillo de .ct-leyenda-color, que
   la barra hueca tampoco lleva. */
.ct-leyenda-sin-desglose { background: var(--yaya-verde-emprendedor, #D8F4D7); box-shadow: inset 0 0 0 1px var(--yaya-verde-crecimiento, #022D2B); }

/* Linea sobre eje secundario (CT_LINEA_SECUNDARIA en control-tower.js, hoy el
   take rate por cohorte sobre Ingresos mensuales cobrados). Morado Financiero
   de la paleta: 2,94:1 contra la tarjeta y 4,30:1 contra el pie oscuro de la
   barra, pero 1,14:1 contra el tope claro de la barra (--yaya-crecimiento-luz);
   por eso el halo del color de la tarjeta debajo del trazo, mas ancho que el,
   y el mismo halo en el borde de los puntos y detras de las etiquetas, que
   pueden caer sobre el relleno de una barra. El trazo no toma clics: la barra
   que tiene debajo sigue abriendo su periodo. */
.ct-linea-sec-halo { fill: none; stroke: var(--yaya-verde-emprendedor); stroke-width: 5; stroke-linejoin: round; stroke-linecap: round; pointer-events: none; }
.ct-linea-sec-trazo { fill: none; stroke: var(--yaya-morado-financiero); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; pointer-events: none; }
.ct-linea-sec-punto { fill: var(--yaya-morado-financiero); stroke: var(--yaya-verde-emprendedor); stroke-width: 1.5; }
.ct-grafico-interactivo .ct-linea-sec-punto { cursor: pointer; }
.ct-valor-linea-sec { paint-order: stroke; stroke: var(--yaya-verde-emprendedor); stroke-width: 3; stroke-linejoin: round; pointer-events: none; }
/* La muestra es un trazo, no un cuadrado: nombra una linea, no una barra. */
.ct-leyenda-linea-sec { height: 3px; border-radius: 2px; box-shadow: none; background: var(--yaya-morado-financiero); }
.ct-nota-linea-sec { margin: 4px 0 0; font-size: 12px; line-height: 1.35; color: var(--ct-texto-suave); }
/* Recuperacion de capital vencido (ctTarjetaRecuperacionCapital): tarjeta sin
   grafico que conserva los 460px de .ct-tarjeta; la leyenda baja al pie.
   .ct-tarjeta ya es flex en columna, asi que alcanza con margin-top:auto. */
.ct-tarjeta-recuperacion .ct-nota-linea-sec { margin-top: auto; }

/* Filtro por checkbox de tpv_categoria_comercio (ctLeyendaCategoriaComercio,
   encargo "escala real, nombres legibles, filtro por categoria y orden
   descendente"): la leyenda que antes era de solo lectura ahora es
   tildable, .ct-leyenda-item de base (flex/align/gap) sigue sirviendo tal
   cual para el <label>. cursor:pointer marca que, a diferencia del resto
   de la leyenda, esta fila SI responde al clic.

   Ya NO lleva una regla :disabled (encargo "filtro Todos y aclaracion
   Barras/Linea", que REVIRTIO el bloqueo de "no se puede destildar la
   ultima categoria" -- antes ese checkbox se atenuaba con opacity:.5 para
   marcar que no respondia; ahora todos los checkboxes de esta leyenda,
   incluido "Todos", responden siempre, asi que la regla quedaba sin
   consumidor y se retiro en vez de dejarla muerta). */
.ct-leyenda-checkbox { cursor: pointer; }
.ct-leyenda-checkbox input[type="checkbox"] { margin: 0; width: 12px; height: 12px; accent-color: var(--yaya-verde-crecimiento, #022D2B); cursor: pointer; }
/* Checkbox maestro "Todos" (ctLeyendaCategoriaComercio, mismo encargo):
   primera entrada de la leyenda, separada visualmente de las 15 categorias
   con un borde -- el gap de 14px que ya declara .ct-leyenda de base cubre
   el espacio, el padding-right + border-right solo agregan la linea
   divisoria sobre ese mismo espacio, sin sumar un gap nuevo. font-weight
   600 (contra el 400 heredado del resto de la leyenda) para que se lea
   como un control aparte, no como una categoria 16. */
.ct-leyenda-todos { font-weight: 600; padding-right: 14px; border-right: 1px solid var(--yaya-crecimiento-tenue, #95A7A6); }

/* Selector de tarjetas visibles de la rejilla (ctSelectorTarjetas, encargo
   "Rejilla sin huecos, selector de tarjetas visibles, y volver conserva la
   posicion de scroll", pieza 2). REUSA .ct-leyenda/.ct-leyenda-item/
   .ct-leyenda-checkbox/.ct-leyenda-todos de aca arriba tal cual -- el unico
   estilo propio es este contenedor, porque la lista en si es visualmente la
   misma cosa que la leyenda con checkbox de una tarjeta, solo que aplicada a
   la rejilla.

   flex-basis:100% + width:100%: .ct-cabecera es flex con flex-wrap:wrap (ver
   esa regla), asi que este tercer hijo se lleva la fila entera y deja al
   titulo y a .ct-derecha exactamente como estaban. Hace falta el ancho
   completo: MEDIDO con el criterio de 0,52em/caracter a los 12px de
   .ct-leyenda, 11 tarjetas con titulos de ~20 caracteres promedio piden
   ~1.777px contra los 1.632px de interior de .ct-root -- no entra en una
   linea ni ocupando todo el ancho (envuelve a 2 filas, que es correcto), y
   mucho menos dentro de .ct-derecha, que ademas es una columna alineada a la
   derecha.

   align-items:baseline para que el rotulo "Tarjetas" y la primera fila de
   checkboxes se alineen por la linea de texto; margin-top:0 en la .ct-leyenda
   interna porque el separador de este bloque lo da el border-top, no el
   margen de 6px que esa clase trae para cuando vive dentro de una tarjeta. */
.ct-selector-tarjetas { flex-basis: 100%; width: 100%; display: flex; align-items: baseline; gap: 10px; padding-top: 12px; border-top: 1px solid var(--yaya-crecimiento-tenue, #95A7A6); }
.ct-selector-tarjetas .ct-leyenda { margin: 0; flex: 1; }
.ct-selector-etiqueta { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ct-texto-suave); flex: none; }
/* La ultima tarjeta tildada no se puede destildar (ver ctCambiarTarjetaVisible):
   el input va disabled y la etiqueta pierde el cursor de mano y baja de
   opacidad, para que se lea como "este no se puede tocar" y no como "este no
   anda". El texto NO se atenua hasta el punto de no leerse: sigue siendo el
   nombre de la unica tarjeta visible, la informacion mas util del selector en
   ese estado. */
.ct-leyenda-bloqueada { cursor: default; opacity: .62; }
.ct-leyenda-bloqueada input[type="checkbox"] { cursor: default; }
/* PBI 973: la guarda de "al menos una visible" se retiro, asi que
   ctSelectorTarjetas ya no emite .ct-leyenda-bloqueada; las dos reglas de
   arriba quedan sin uso. */

/* PBI 973 · subtabs por pregunta de negocio (ver ctSubtabsHtml).
   Los botones son .ct-toggle-btn tal cual (y su .activo): el estado elegido
   sigue el mismo criterio que la pastilla activa del modulo. El contenedor es
   propio porque .ct-toggle es inline-flex sin wrap y con overflow:hidden:
   MEDIDO, las cinco preguntas piden ~1.417px (es) y ~1.328px (en) contra
   1.092px utiles a 1.280px de ventana, y ahi .ct-toggle las cortaria. Aca pasan
   a otra fila. Mismo fondo y padding que .ct-toggle; el radio baja de 999px a
   22px: con una fila (~37px de alto: 3 + 7 + 13px x 1,302 + 7 + 3) casi no se
   distingue de la pildora, y con dos (~65px) se lee como una caja en vez de
   una pildora deformada. */
/* Colores del riel (correccion visual de T4, solo .ct-subtabs): fondo Verde
   Emprendedor en vez de --yaya-crecimiento-tenue, y como #D8F4D7 contra el
   fondo de pagina (#fafafa) da 1,13:1 y el relleno solo no dibuja el limite,
   un borde de 1px en --yaya-crecimiento-luz (3,78:1 contra la pagina y 3,35:1
   contra el riel), el mismo criterio que ya usa .ct-selector. Las pastillas
   inactivas siguen en --ct-texto: 12,63:1 sobre el riel. El hover general de
   .ct-toggle-btn solo fija color: var(--ct-texto), sin fondo, asi que sobre el
   riel nuevo sigue en esos mismos 12,63:1 y no hace falta ajustarlo. */
.ct-subtabs { display: flex; flex-wrap: wrap; gap: 2px; padding: 3px; margin: 0; width: fit-content; max-width: 100%; background: var(--yaya-verde-emprendedor, #D8F4D7); border: 1px solid var(--yaya-crecimiento-luz, #6C8584); border-radius: 22px; }
/* Pastilla activa SOLO dentro de .ct-subtabs: la blanca de .ct-toggle-btn.activo
   sobre el Verde Emprendedor da 1,18:1 y no se distingue. Verde crecimiento con
   texto Verde Emprendedor da 12,63:1 (texto contra pastilla y pastilla contra
   riel), la misma pareja que .ct-periodo-detalle. Sin sombra: la sombra de la
   regla general era para elevar una pastilla blanca. 0-3-0 de especificidad:
   le gana a .ct-toggle-btn.activo (0-2-0) y a .ct-toggle-btn:hover (0-2-0), asi
   que el hover no le devuelve el texto oscuro a la activa. */
.ct-subtabs .ct-toggle-btn.activo { background: var(--yaya-verde-crecimiento, #022D2B); color: var(--yaya-verde-emprendedor, #D8F4D7); box-shadow: none; }
/* Anillo de foco SOLO dentro de .ct-subtabs, mismo :focus-visible que la regla
   general (.ct-toggle-btn:focus-visible, que queda igual). La general usa
   --primary-500 hacia adentro (offset -2px): sobre el riel nuevo da 2,60:1,
   por debajo del 3:1 de un indicador de foco. Aca va en Verde crecimiento
   HACIA AFUERA (offset 2px), sobre el riel claro: 12,63:1, y se ve tambien en
   la pastilla activa, que es del mismo verde, porque entre el anillo y la
   pastilla quedan 2px de riel. */
.ct-subtabs .ct-toggle-btn:focus-visible { outline: 2px solid var(--yaya-verde-crecimiento, #022D2B); outline-offset: 2px; }
/* Los subtabs viven en .ct-cabecera, arriba del selector de tarjetas: la fila
   ocupa el ancho entero (mismo mecanismo que .ct-selector-tarjetas, que
   .ct-cabecera ya baja a su propio renglon con flex-wrap) y la separacion con
   el titulo y con el selector la da el gap:16px de .ct-cabecera, por eso
   .ct-subtabs va sin margin. */
.ct-subtabs-fila { flex-basis: 100%; width: 100%; }
/* La TRM (CT_EN_TODOS_LOS_SUBTABS) va al final del selector con su propio
   checkbox, separada de la lista con la misma linea que separa a "Todos". */
.ct-leyenda-aparte { padding-left: 14px; border-left: 1px solid var(--yaya-crecimiento-tenue, #95A7A6); }
/* Estado vacio de un subtab: con la TRM tildada, su tarjeta va debajo. */
.ct-estado-subtab { margin-bottom: 16px; }

/* Detalle de un periodo: bloque suplementario DEBAJO del grafico, no lo
   reemplaza (ver el comentario de ctBloquePeriodo). */
.ct-periodo-pista { margin: 0 0 8px; font-size: 12.5px; color: var(--ct-texto-suave); font-style: italic; }
/* Fondo #2AA048 / texto #D8F4D7 (encargo "Fondo verde de marca en las vistas
   de detalle", corregido en "Corregir: el fondo verde va en .ct-periodo-
   detalle, no en .ct-detalle" -- el primer intento aplico esto en .ct-detalle
   por error de lectura; ESTE es el bloque que Miguel pidio, "Detalle del
   periodo" + la tabla "Medidas del periodo". .ct-detalle -el contenedor
   grande, con el grafico, el numero destacado, el nombre y la descripcion-
   vuelve a su fondo claro de siempre y NO se toca).

   Los dos hex son los mismos 2 tonos de marca de siempre (--yaya-verde /
   --yaya-verde-emprendedor, ver design-system.css), reusados tal cual, sin
   variables nuevas -- mismo argumento que ya se escribio para el intento
   anterior. Redefine --ct-texto/--ct-texto-suave (no un color: propio en este
   selector) para que TODO lo que ya vive adentro y lee esas variables --
   .ct-periodo-titulo, .ct-periodo-contra, .ct-periodo-nota, .ct-tabla th Y
   .ct-tabla td (esta ultima agregada mas abajo para que la tenga: sin color
   propio no seguia a NINGUNA variable)-- tome el D8F4D7 nuevo sin tocarlas
   una por una.

   FONDO CORREGIDO (encargo "Ajuste de color: .ct-periodo-detalle a fondo
   oscuro de marca"): #2AA048 le parecio feo a Miguel viendolo en el
   navegador -el contraste bajo (2,87:1, aceptado en su momento para probarlo)
   no convencio en la practica, no solo en el numero. En vez de un tono
   nuevo, se invierten los roles DENTRO de la misma pareja de siempre: fondo
   --yaya-verde-crecimiento #022D2B (el mismo oscuro que --ct-texto ya usa
   como color de texto en el resto del tablero) y texto --yaya-verde-
   emprendedor #D8F4D7 (sin cambios, el de siempre). Confirmado contra
   design-system.css antes de escribir esto -no se repitio el nombre a
   ciegas- que --yaya-verde-crecimiento es efectivamente #022D2B.

   CONTRASTE: D8F4D7 sobre 022D2B = 12,63:1 -- muy por encima del 4,5:1 de
   texto normal, y el mejor resultado posible combinando dos tonos de la
   paleta existente (calculo hecho fuera del repo, confirmado por Miguel).
   Reemplaza al 2,87:1 de la version anterior.

   RECALCULADO, no asumido que mejora solo por ser un fondo mas oscuro (los 3
   colores comparten el problema de que ninguno esta calibrado contra ESTE
   fondo, calibrados contra otro): el borde inferior de la tabla (.ct-tabla
   th/td, --yaya-crecimiento-luz #6C8584) sube de 1,17:1 a 3,77:1 contra
   #022D2B (mismo numero que ya trae el comentario de design-system.css para
   este mismo par, confirmado con el mismo metodo) -- visible, aunque sigue
   por debajo del 4,5:1 de texto (no es texto, es un borde). .ct-delta-sube
   (--primary-700 #1E8038, la base SIN el inline) sube de 1,48:1 a 2,97:1;
   .ct-delta-baja (--yaya-coral-profundo #8C493A) sube de 1,99:1 a 2,21:1 --
   los dos mejoran, ninguno de los dos llega a pasar 4,5:1 (ni al 3:1 de
   texto grande). Sin ajuste: no fue lo que se pidio esta vuelta, se reporta
   para que Miguel decida si hace falta una tercera pasada.

   .ct-periodo-aviso (el banner "Periodo en curso") sigue sin verse afectado,
   mismo motivo que antes: tiene su propio color (--amber-600) y fondo
   (--amber-50) explicitos, ninguno de los dos lee --ct-texto/--ct-texto-
   suave, asi que no le importa que fondo tenga este bloque.

   .ct-selector (el desplegable de criterio de mora de npl_diario) sigue sin
   vivir aca -- ctCriterioNplTarjeta() esta dentro de .ct-destacado, parte de
   .ct-detalle (el panel de arriba, sin tocar), no de este bloque. */
.ct-periodo-detalle { margin-top: 8px; padding: 16px 18px; border: 1px solid var(--gray-200); border-radius: 12px; background: var(--yaya-verde-crecimiento, #022D2B); --ct-texto: var(--yaya-verde-emprendedor, #D8F4D7); --ct-texto-suave: var(--yaya-verde-emprendedor, #D8F4D7); }
.ct-periodo-cabecera { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.ct-periodo-titulo { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--ct-texto-suave); }
/* Recuadro de avisos: "periodo en curso" y TRM provisional, juntos cuando
   aplican los dos en el mismo lugar (ctRecuadroAviso: un <p> por mensaje).
   Vive en dos fondos: el claro de tarjeta y detalle (#D8F4D7) y el oscuro del
   panel del periodo (#022D2B). El recuadro trae su propio fondo, asi que el
   texto se mide contra ese fondo: #92400e sobre --amber-50 da 6,84:1 (antes
   --amber-600, 3,07:1, por debajo del 4,5:1 de texto normal). Contra el panel
   oscuro el recuadro se separa solo (fondo 14,33:1, borde #fde68a 11,94:1);
   contra la tarjeta clara no (fondo 1,14:1, borde 1,06:1), por eso el borde
   izquierdo de acento: #b45309 da 4,27:1 contra #D8F4D7. */
.ct-periodo-aviso { margin: 8px 0; font-size: 12.5px; line-height: 1.4; color: #92400e; background: var(--amber-50); border: 1px solid #fde68a; border-left: 3px solid #b45309; border-radius: 8px; padding: 8px 12px; }
.ct-periodo-aviso p { margin: 0; }
.ct-periodo-aviso p + p { margin-top: 6px; }
.ct-periodo-contra { font-size: 12.5px; color: var(--ct-texto-suave); margin-top: 6px; }
.ct-delta { font-size: 18px; font-weight: 700; color: var(--ct-texto); }
/* Los dos colores de la variacion. Viven dentro de .ct-periodo-detalle, que es
   el bloque claro (--bg-secondary #fafafa), no la superficie verde, asi que el
   contraste se mide contra ese fondo. Y .ct-delta es 18px en peso 700, o sea
   13,5pt: queda por DEBAJO de los 14pt que WCAG llama "texto grande", asi que el
   umbral que aplica es 4,5:1 y no 3:1.

   BAJA pasa del rojo al coral de marca, pero no al Coral Empuje: medido sobre
   #fafafa, #F07C63 da 2,59:1 y ni siquiera --yaya-coral-oscuro #B75F4C llega
   (4,23:1). El primero de la familia que pasa es --yaya-coral-profundo #8C493A,
   con 6,43:1. Antes, --red-600 daba 4,63:1.

   SUBE se queda en --primary-700 #1E8038 (4,79:1). Bajarlo a --primary-600
   #2AA048 lo dejaria en 3,23:1, o sea que romperia el mismo umbral que acabamos
   de hacer respetar del otro lado. --primary-700 ES el escalon oscuro de la
   familia del Verde YaYa, exactamente el mismo tratamiento que recibio el coral
   aca arriba. */
.ct-delta-sube { color: var(--primary-700, var(--primary-600)); }
.ct-delta-baja { color: var(--yaya-coral-profundo, #8C493A); }
/* .ct-delta-inline: modificador para reusar el patron de .ct-delta (mismos
   nombres de clase ct-delta-sube/baja, mismo criterio de flecha+color, ver
   ctDeltaDestacado) JUNTO al monto de .ct-valor en vez de en su
   bloque propio dentro de .ct-periodo-detalle -- encargo "filtro Todos y
   aclaracion Barras/Linea", PBI 742. font-size mas chico (14px, no 18px)
   porque es una anotacion secundaria en la MISMA linea que un numero de
   30px, no un bloque destacado propio; margin-left en vez de gap porque va
   pegado al texto de .ct-valor sin envolver en un contenedor flex nuevo.

   El color de SUBE NECESITA cambiar en este contexto, medido de nuevo
   (mismo metodo WCAG sRGB->luminancia->contraste que ya uso el comentario
   de arriba, pero contra el fondo real de ESTE lugar): .ct-valor esta
   sobre la superficie verde de la tarjeta (--yaya-verde-emprendedor
   #D8F4D7, ver .ct-tarjeta/.ct-detalle), no sobre el bloque claro #fafafa
   de .ct-periodo-detalle contra el que se midio --primary-700 arriba.
   Sobre #D8F4D7, --primary-700 #1E8038 da 4,25:1 -- por DEBAJO del 4,5:1
   que exige este tamano (14px/700, muy lejos del umbral de "texto grande")
   -- mientras que sobre #fafafa daba 4,79:1 y pasaba. --yaya-verde-profundo
   #17622B (ya en uso en otras partes del modulo) da 6,33:1 sobre la
   tarjeta, y sigue siendo visualmente un verde distinto de --ct-texto
   #022D2B (el color del numero grande), asi que la variacion no se
   confunde con el headline. BAJA no cambia: --yaya-coral-profundo #8C493A
   da 5,70:1 sobre #D8F4D7, sigue pasando sin ajuste. */
.ct-delta-inline { font-size: 14px; margin-left: 8px; }
.ct-delta-inline.ct-delta-sube { color: var(--yaya-verde-profundo, #17622B); }

/* Rotulo de QUE es el numero destacado, AL LADO del monto y dentro de la misma
   linea de .ct-valor (encargo "Escalera de mora: barras vacias en USD, y
   caption al lado del numero"). Hoy solo escalera_mora_mensual, ver
   ctNotaValor en control-tower.js.

   ANTES era .ct-periodo-nota, un <p> en su propio renglon DEBAJO del numero.
   Conserva de esa regla el tamano (12,5px) y el color (--ct-texto-suave): lo
   unico que cambia es que pasa a la misma linea, no como se ve. El
   margin-left de 8px y el font-weight normal son de .ct-delta-inline, el otro
   inline que ya convive con el monto en esta misma linea -- sin el
   font-weight propio heredaria el 700 de .ct-valor y competiria con el
   numero, que es justo lo que no tiene que hacer.

   SIN flex y SIN media query, a proposito. Un <span> inline lo baja de linea
   el navegador solo cuando no entra, a CUALQUIER ancho, que es mejor que un
   corte fijo en 1024px: MEDIDO con el criterio de 0,52em/caracter que usa
   ctAnchoTexto, el monto ("$ 79,7 M" a 30px, letter-spacing -0,02em) mide
   ~120px y la nota mas larga -54 caracteres en ingles a 12,5px- ~351px, o sea
   ~479px con el margen. Contra los 1.608px de interior a 3 columnas usa el
   29,8%, y en el fallback de 1 columna en el breakpoint de 1024px hay 952px
   de interior (1024 - 48 de .ct-root - 24 de .ct-tarjeta.ct-tarjeta-triple):
   entra en una linea en las dos. Un @media (max-width:1024px) que lo forzara
   a bajar estaria partiendo la linea con el DOBLE del ancho que hace falta.
   El ancho real donde deja de entrar es ~551px de viewport (o ~515px por
   debajo de 720px, donde .ct-valor ya baja a 26px y .ct-root a 14px/lado):
   telefono, y ahi envuelve sola sin ayuda. */
.ct-valor-nota { font-size: 12.5px; font-weight: 400; letter-spacing: normal; margin-left: 8px; color: var(--ct-texto-suave); }

/**
 * Excepcion de .ct-delta-sube/.ct-delta-baja SOLO dentro de .ct-periodo-
 * detalle (encargo "Contraste de deltas y boton Cerrar en .ct-periodo-
 * detalle"). .ct-delta-sube/.ct-delta-baja (arriba, sin scope) son clases
 * GLOBALES, no variables -- las usan ctBloquePeriodo/ctBloquePeriodoActivos
 * (bare, sin .ct-delta-inline, SOLO dentro de .ct-periodo-detalle) Y
 * ctDeltaDestacado (con .ct-delta-inline, dentro de .ct-destacado/.ct-detalle,
 * el panel de arriba, sin cambios). Por eso el override es un selector
 * descendiente de .ct-periodo-detalle, NO un cambio a la clase base: cambiar
 * .ct-delta-sube/.ct-delta-baja a secas habria corrido tambien el color del
 * delta junto al numero destacado, que sigue sobre el verde claro de
 * siempre y para el que --primary-700/--yaya-coral-profundo YA estan bien
 * (ver los dos comentarios de arriba).
 *
 * Colores nuevos, calculados y aprobados por Miguel contra el fondo #022D2B
 * de .ct-periodo-detalle:
 *   "bajo"   -> --yaya-coral-empuje #F07C63 (5,50:1) en vez de
 *               --yaya-coral-profundo #8C493A (2,21:1 medido en el encargo
 *               anterior, insuficiente).
 *   "subio"  -> --yaya-verde-claro #32C057 (6,24:1, declarada en
 *               design-system.css para este uso exacto) en vez de
 *               --primary-700 (2,97:1, insuficiente).
 *
 * Coral Empuje ya tiene significado en otras dos partes del modulo --el
 * segmento de cashouts en TPV/ingresos, y la serie "Con cashouts" de
 * transacciones_por_activo (un grafico de linea, en .ct-detalle, no en este
 * bloque)-- reportado, no resuelto: los dos usos previos estan en pantallas/
 * bloques distintos de este, y Miguel ya confirmo el color sabiendolo.
 */
.ct-periodo-detalle .ct-delta-sube { color: var(--yaya-verde-claro, #32C057); }
.ct-periodo-detalle .ct-delta-baja { color: var(--yaya-coral-empuje, #F07C63); }

/* Revenue Run Rate inline, en el MISMO renglon que .ct-valor y a continuacion
   de .ct-delta-inline -- ver ctRunRateDestacado en control-tower.js para
   cuando se dibuja, para la medicion de ancho por la que entra tambien en la
   tarjeta angosta, y para por que el dato aparece dos veces en el detalle.

   El problema de este renglon son TRES numeros seguidos ($ 2,4 M, el % de
   variacion y el RRR), que sin tratamiento se leen como una sola fila corrida
   de cifras. Lo que los separa:

   - JERARQUIA DE TAMANO: 30px el valor, 14px el delta y el RRR. El RRR no
     puede subir mas sin competir con el titular, y no puede bajar a 12px sin
     parecer texto de apoyo en vez de una cifra: 14px es exactamente el escalon
     que .ct-delta-inline ya fijo para este renglon.
   - COLOR: el delta lleva el verde o el coral del signo; el RRR va en
     --ct-texto pleno, sin color de signo, porque no es una variacion y
     pintarlo de verde lo haria leer como una segunda subida.
   - SEPARADOR CON AIRE: un punto medio en --ct-texto-suave con 10px a cada
     lado. El delta se pega al valor con 8px de margin-left (es una anotacion
     sobre ese numero); el RRR abre con 10+punto+10 porque es OTRA magnitud, no
     una anotacion sobre la anterior. aria-hidden en el punto: es decoracion.
   - ROTULO: la sigla en 11px versalita con letter-spacing, el mismo
     tratamiento de .ct-run-rate-etiqueta y .ct-periodo-medidas, para que se lea
     como etiqueta de la cifra que sigue y no como parte del numero anterior.

   Contraste, medido contra el fondo REAL de este renglon, que es la superficie
   verde --yaya-verde-emprendedor #D8F4D7 tanto en .ct-tarjeta como en
   .ct-detalle (no el #fafafa de .ct-periodo-detalle): --ct-texto-suave #3E655B
   da 5,55:1 sobre #D8F4D7, que pasa el 4,5:1 que exigen los 11px de la sigla;
   --ct-texto #022D2B para la cifra esta muy por encima. Son los dos mismos
   tonos que ya usa .ct-run-rate sobre esta misma superficie: no hace falta
   ningun color nuevo.

   letter-spacing:normal en el grupo porque .ct-valor declara -0.02em para el
   numero de 30px, y ese tracking negativo apretaria una sigla de 11px. La
   sigla vuelve a pedir el suyo (+.04em) sobre esa base. white-space:nowrap
   para que, si algun dia el renglon si tuviera que envolver, el corte caiga
   ANTES del grupo y no entre la sigla y su cifra. */
.ct-rrr-inline { margin-left: 10px; letter-spacing: normal; white-space: nowrap; }
.ct-rrr-sep { font-size: 14px; font-weight: 400; color: var(--ct-texto-suave); margin-right: 10px; }
.ct-rrr-etiqueta { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ct-texto-suave); margin-right: 5px; }
.ct-rrr-valor { font-size: 14px; font-weight: 600; color: var(--ct-texto); }

/* Indicadores con meta (CT_METAS, hoy cycle_rate). Contrastes medidos contra
   la tarjeta #D8F4D7:
     - "→ Meta 1,50x", la linea punteada y su rotulo: --ct-texto-suave
       (#3E655B), 5,55:1. La linea es un trazo fino: pasa holgado el 3:1 de
       elementos graficos, y el rotulo (9px) el 4,5:1 de texto.
     - Variacion que sube: --yaya-verde-profundo (#17622B), 6,33:1. NO
       --primary-700 (el .ct-delta-sube de la tabla), que da 4,25:1: con 12,5px
       queda por debajo del 4,5:1. Es el mismo tono que ya usa
       .ct-delta-inline.ct-delta-sube por el mismo motivo.
     - Variacion que baja: --yaya-coral-profundo (#8C493A), 5,70:1, el mismo
       de .ct-delta-baja.
   Verde YaYa (#2AA048, 2,87:1) no lleva texto. */
.ct-meta-inline { margin-left: 10px; font-size: 14px; font-weight: 600; letter-spacing: normal; color: var(--ct-texto-suave); white-space: nowrap; }
.ct-meta-flecha { font-weight: 400; }
.ct-meta-variacion { font-weight: 600; white-space: nowrap; }
.ct-meta-sube { color: var(--yaya-verde-profundo, #17622B); }
.ct-meta-baja { color: var(--yaya-coral-profundo, #8C493A); }
.ct-linea-meta { stroke: var(--ct-texto-suave); stroke-width: 1.2; stroke-dasharray: 4 3; fill: none; }
.ct-meta-rotulo { font-size: 9px; font-weight: 700; letter-spacing: .04em; fill: var(--ct-texto-suave); font-family: var(--ct-fuente-texto); }

/* Cifras clave de ingresos_mensual (ctCifrasClave): tres cifras en una fila,
   cada una con el rotulo (.ct-periodo), la cifra (.ct-valor) y la linea suave
   (.ct-mes) de la cifra destacada de siempre, asi que colores, tamanos y
   fuente salen de esas mismas reglas. Se apilan segun el ancho de la TARJETA,
   no de la ventana (container query): la misma tarjeta puede ocupar 1, 2 o 3
   columnas. Medido con ctAnchoTexto, la cifra 1 mas ancha realista ("US$ 36,6
   M" a 30px mas "↑ 162,0 %" a 14px) pide ~230px; tres mas dos huecos de 32px
   son ~754px, de ahi el corte en 760. */
.ct-cifras { container-type: inline-size; }
.ct-cifras-fila { display: flex; gap: 32px; }
.ct-cifra { flex: 1 1 0; min-width: 0; }
@container (max-width: 759px) {
    .ct-cifras-fila { flex-direction: column; gap: 12px; }
}
/* Los dos bloques de rotacion_libro (mes cerrado y MTD, ctBloqueCifraRotacion),
   con la misma separacion en la tarjeta y en el detalle. Sin esto la ponia el
   contenedor: 8px del gap de .ct-tarjeta, 0 en .ct-destacado. 12px, el mismo
   paso de .ct-cifras-fila apilada. */
.ct-rotacion-bloques { display: flex; flex-direction: column; gap: 12px; }
.ct-periodo-nota { margin: 6px 0 0; font-size: 12.5px; color: var(--ct-texto-suave); }
.ct-periodo-medidas { margin: 16px 0 6px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ct-texto-suave); }
/* Los selectores de la franja de criterio (unico lugar donde se usan). El borde
   sale del gris: sobre coral la caja blanca se separaba sola (2,70:1), pero
   sobre Verde Emprendedor da 1,18:1 y practicamente se funde, asi que ahora el
   limite lo dibuja el borde. --gray-300 daba 1,29:1 contra la franja y no se
   veia; --yaya-crecimiento-luz da 3,35:1 contra la franja y 3,94:1 contra su
   propio relleno blanco.

   El texto va en el tono PLENO y no en el suave que hereda de la etiqueta: lo
   que muestra el selector es el valor elegido, o sea dato, no rotulo. Sobre la
   caja blanca da 14,86:1. */
.ct-selector { margin-left: 6px; border: 1px solid var(--yaya-crecimiento-luz, #6C8584); border-radius: 8px; padding: 4px 8px; font: inherit; font-size: 13px; color: var(--ct-texto); background: var(--bg-primary); }
.ct-tabla { width: 100%; border-collapse: collapse; font-size: 12.5px; }
/* La tabla de tramos vive dentro de .ct-detalle, o sea sobre el verde: su borde
   sale del gris por lo mismo que la linea base del grafico (--gray-200 daba
   1,04:1 y no se veia). */
.ct-tabla th, .ct-tabla td { padding: 6px 10px; text-align: left; border-bottom: 1px solid var(--yaya-crecimiento-luz, #6C8584); }
.ct-tabla th { color: var(--ct-texto-suave); font-weight: 600; text-transform: uppercase; font-size: 11px; letter-spacing: .04em; }
/* .ct-tabla td no tenia color propio -- sin esto hereda color: de su ancestro
   mas cercano que lo declare, que hoy es .ct-detalle (verde claro, texto
   oscuro de --ct-root, sin cambios) y despues del encargo "Corregir: el fondo
   verde va en .ct-periodo-detalle" tambien puede ser .ct-periodo-detalle
   (fondo oscuro nuevo). SIN esta regla, dentro de .ct-periodo-detalle el
   cuerpo de la tabla "Medidas del periodo" se habria quedado en el mismo
   verde oscuro que ya trae desde mas arriba en la cascada -- un mismatch con
   su propio encabezado (th, que SI lee --ct-texto-suave y sigue el fondo de
   cada contenedor). Con esta regla los dos (th y td) leen la MISMA variable,
   asi que cada tabla -la de "Medidas del periodo" sobre el fondo oscuro
   nuevo, y la escalera de mora de npl_diario (.ct-npl, que sigue directo
   sobre el verde CLARO de .ct-detalle, sin cambios en este encargo) sobre el
   claro de siempre- resuelve el color correcto para SU propio fondo, sin
   tocarla clase por clase. */
.ct-tabla td { color: var(--ct-texto); }

/* ============================================================
   activos_mensual (una serie) Y activos_mensual_dual (dos tarjetas separadas
   desde el encargo "Separar Clientes activos en dos tarjetas", PBI 737/738).
   Ver ctEtiquetasDoblesActivos, ctGraficoDual, ctGraficoLineaDual,
   ctGraficoTarjetaLineaDual, ctTarjetaActivosDual y ctBloquePeriodoActivos en
   control-tower.js.
   ============================================================ */

/* La linea de % de las DOS lineas de etiqueta por barra (ver
   ctEtiquetasDoblesActivos): "sube" no necesita clase propia porque hereda el
   fill pleno de .ct-valor-punto (--ct-texto, el mismo verde-crecimiento de
   siempre); "baja" pasa a coral, mismo tono ya medido contra la tarjeta
   (--yaya-coral-profundo, 5,70:1 contra #D8F4D7) que antes usaba el headline
   retirado de este encargo. La cantidad (segunda linea) nunca lleva esta
   clase: solo la variacion tiene sentido de colorear. */
.ct-valor-pct-baja { fill: var(--yaya-coral-profundo, #8C493A); }

/* Cifra destacada de la tarjeta activos_mensual_dual: dos numeros con
   etiqueta ("30D 700 · 60D 1.050") en vez de uno solo, asi que a los 30px de
   .ct-valor no entraria sin arriesgar el ancho de la tarjeta (533px). Mismo
   peso/color, tamano reducido a como si fuera un paso intermedio entre
   .ct-valor (30px) y .ct-nombre (19px). */
.ct-valor-dual { font-size: 22px; }

/* Serie 60D del Nivel 2 (ctGraficoDual/ctGraficoLineaDual). 30D reusa las
   clases de compras TAL CUAL -- ctGraficoDual le da literalmente la clase
   "ct-barra" (no un alias "-30d"): un alias de una sola clase empataria en
   especificidad con .ct-barra-abierta/.ct-barra-sel y, por venir despues en
   esta hoja, les ganaria por orden -- la barra 30D perderia la trama de "mes
   en curso" o el resaltado de seleccion. Reusando "ct-barra" tal cual, esas
   dos reglas (ya definidas mas arriba) siguen ganando exactamente como ya
   ganan en las barras de TPV. Ver el comentario de --yaya-morado-* en
   design-system.css para la eleccion de color de 60D. */
.ct-barra-60d { fill: url(#ct-grad-60d); }
.ct-barra-60d.ct-barra-abierta { fill: url(#ct-trama-60d); }
.ct-barra-60d.ct-barra-sel { fill: url(#ct-grad-60d-sel); }
.ct-barra-60d.ct-barra-abierta.ct-barra-sel { fill: url(#ct-trama-60d); }
.ct-stop-60d-luz { stop-color: var(--yaya-morado-luz, #A7A1ED); }
.ct-stop-60d-hondo { stop-color: var(--yaya-morado-oscuro, #6660B0); }
.ct-stop-60d-marca { stop-color: var(--yaya-morado-marca, #857DE6); }
.ct-stop-60d-hondo-sel { stop-color: var(--yaya-morado-profundo, #4E4987); }
.ct-trama-fondo-60d { fill: var(--yaya-morado-claro, #EDECFB); }
.ct-trama-linea-60d { stroke: var(--yaya-morado-marca, #857DE6); stroke-width: 2.4; opacity: .55; }
/* Contorno propio del mes en curso para la serie 60D: un contorno verde
   (.ct-contorno-abierta, la clase generica de ctGrafico) sobre una barra
   morada se leeria como un error de color, no como "mes en curso". Mismo
   stroke-width y dasharray que la generica, solo cambia el color. */
.ct-contorno-abierta-60d { stroke: var(--yaya-morado-oscuro, #6660B0); stroke-width: 1; stroke-dasharray: 3 2; }
.ct-contorno-abierta-60d.ct-contorno-sel { stroke: var(--gray-900); stroke-dasharray: 3 2; }

.ct-linea-trazo-60d { stroke: var(--yaya-morado-oscuro, #6660B0); stroke-width: 2; }
.ct-linea-punto-60d { fill: var(--yaya-morado-oscuro, #6660B0); }
/* serie2 (CT_CIERRES_MES, el 5.2): el punto de cierre y el abierto de un grafico de
   un solo indicador en morado. Sin estos combinados, .ct-linea-punto-60d (despues en
   esta hoja) le pisaria el relleno a los dos y el abierto dejaria de verse hueco. Son
   los de .ct-linea-punto-cierre y .ct-linea-punto-abierto con el morado en lugar del
   verde, y van ANTES del combinado de seleccion de abajo para que este les siga
   ganando, como en la version verde. */
.ct-linea-punto-60d.ct-linea-punto-cierre { fill: var(--yaya-morado-oscuro, #6660B0); stroke: var(--yaya-verde-emprendedor, #D8F4D7); stroke-width: 1.5; }
.ct-linea-punto-60d.ct-linea-punto-abierto { fill: var(--yaya-verde-emprendedor, #D8F4D7); stroke: var(--yaya-morado-oscuro, #6660B0); stroke-width: 1.5; stroke-dasharray: 2 1.5; }
/* .ct-linea-punto-sel viene ANTES en este archivo (linea ~336): sin este
   combinado, .ct-linea-punto-60d le empataria en especificidad y le ganaria
   por orden, y un punto 60D seleccionado perderia el gris que marca la
   seleccion. Mismo problema que ya resolvieron los combinados de la barra
   apilada (ver el comentario de .ct-barra-abierta.ct-barra-sel), aplicado
   aca al punto de linea. */
.ct-linea-punto-60d.ct-linea-punto-sel { fill: var(--gray-900); stroke: var(--bg-primary); stroke-width: 2; }

/* Leyenda de las dos series, siempre visible en el Nivel 2 (a diferencia de
   .ct-leyenda-compras/.ct-leyenda-cashouts, que solo aparecen si el TPV esta
   apilado): ver ctLeyendaActivosSeries. */
.ct-leyenda-30d { background: linear-gradient(180deg, var(--yaya-crecimiento-luz, #6C8584), var(--yaya-verde-crecimiento, #022D2B)); }
.ct-leyenda-60d { background: linear-gradient(180deg, var(--yaya-morado-luz, #A7A1ED), var(--yaya-morado-oscuro, #6660B0)); }

/* Nivel 3 de activos_mensual (ctBloquePeriodoActivos): dos bloques de
   valor+variacion lado a lado, uno por serie, dentro de .ct-periodo-detalle. */
.ct-activos-series { display: flex; gap: 24px; flex-wrap: wrap; margin: 4px 0 8px; }
.ct-activos-serie { flex: 1; min-width: 160px; }
.ct-activos-serie-etiqueta { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--ct-texto-suave); margin-bottom: 2px; }

/* ============================================================
   Cosechas quincenales (ctMatrizCosecha, ctTarjetaCosecha, ctDetalleCosecha
   en control-tower.js). Encargo "Vista de matriz (heatmap) para los
   indicadores de granularidad quincenal", 23/09/2026.

   Tres estados de celda, distinguibles a simple vista sobre el fondo
   --yaya-verde-emprendedor:
   - .ct-cos-escala: medida en una columna con contra que comparar. Color por
     COLUMNA en TRES colores de marca (encargo "Escala de color de la matriz
     de cosechas", 23/09/2026): Verde luz (minimo) -> Amarillo Pasion (mitad)
     -> Coral Empuje (maximo). Antes eran dos, del Verde Emprendedor al coral,
     y el minimo tenia 1,0:1 contra el fondo: parecia una celda vacia con
     borde. El JS solo manda la posicion en --ct-cos-t y el color sale de las
     variables de design-system.css via color-mix (ver la regla, abajo).
   - .ct-cos-neutra: medida, pero su columna tiene un solo valor o todos
     iguales: blanco, sin pintarse como maximo ni como minimo.
   - .ct-cos-sin-dato: la clave no vino en valores. Solo la linea tenue de la
     cuadricula (--ct-cos-linea, la tienen TODAS las celdas), sin fondo y sin
     texto. Las medidas llevan SIEMPRE su borde mas fuerte (inset de
     --yaya-crecimiento-tenue) y numero, asi que un 0,00 minimo (verde sobre
     verde) sigue viendose como caja con numero.
   Encabezados y columnas fijos (encargo "Legibilidad de la matriz de
   cosechas"): un solo contenedor con scroll en los dos ejes (.ct-cos-scroll),
   los dos renglones de <thead> con sticky top, Cohorte y base con sticky left,
   y la esquina (las dos <th> de thead con rowspan) con las dos cosas y el
   z-index mas alto. border-collapse: separate con border-spacing: 0 a
   proposito: con collapse los bordes no viajan con la celda fija, y con
   spacing distinto de 0 los offsets de top/left dejan de ser exactos. Toda
   celda fija lleva fondo opaco (el mismo Verde Emprendedor de la vista) para
   que los numeros no se vean por debajo al desplazarse.
   --ct-cos-w1 es el ancho FIJO de la columna Cohorte: de el sale el left de la
   columna base. --ct-cos-h1 es el alto del primer renglon de encabezado: de el
   sale el top del segundo.
   Texto de celda siempre en --ct-texto: MEDIDO, sobre el coral pleno da
   5,50:1 con --ct-texto (#022D2B) y 2,41:1 con --ct-texto-suave (#3E655B), que
   no llega a 4,5. Sobre el verde da 12,63:1 y sobre el blanco 14,86:1.
   ============================================================ */
.ct-cos-scroll { --ct-cos-w1: 210px; --ct-cos-h1: 24px; --ct-cos-linea: color-mix(in srgb, var(--yaya-crecimiento-tenue, #95A7A6) 45%, var(--yaya-verde-emprendedor, #D8F4D7)); overflow: auto; max-height: 70vh; margin: 8px 0 4px; border: 1px solid var(--yaya-crecimiento-tenue, #95A7A6); border-radius: 8px; background: var(--yaya-verde-emprendedor, #D8F4D7); }
/* En la tarjeta de la rejilla, alto MAXIMO fijo (no relativo a la ventana): la
   tarjeta comparte fila con otras y no puede crecer segun la pantalla. Maximo
   y no alto fijo (encargo "Una sola tarjeta de Cosechas con selector"): con
   las 4 filas de colocacion un alto fijo dejaba la caja casi vacia; asi se
   encoge a la tabla. */
.ct-tarjeta-cosecha .ct-cos-scroll { max-height: 300px; }
.ct-cos-matriz { border-collapse: separate; border-spacing: 0; font-size: 11px; font-variant-numeric: tabular-nums; }
.ct-cos-matriz th, .ct-cos-matriz td { box-sizing: border-box; border-right: 1px solid var(--ct-cos-linea); border-bottom: 1px solid var(--ct-cos-linea); }
.ct-cos-matriz th { color: var(--ct-texto-suave); font-weight: 600; font-size: 10.5px; text-align: center; padding: 2px 4px; white-space: nowrap; background: var(--yaya-verde-emprendedor, #D8F4D7); }
.ct-cos-matriz thead th { position: sticky; top: 0; z-index: 2; }
.ct-cos-matriz thead tr:first-child th { height: var(--ct-cos-h1); }
.ct-cos-matriz thead tr + tr th { top: var(--ct-cos-h1); border-bottom-color: var(--yaya-crecimiento-tenue, #95A7A6); }
.ct-cos-matriz .ct-cos-grupo { text-transform: uppercase; letter-spacing: .04em; text-align: left; }
.ct-cos-matriz .ct-cos-cohorte { position: sticky; left: 0; z-index: 1; width: var(--ct-cos-w1); min-width: var(--ct-cos-w1); max-width: var(--ct-cos-w1); overflow: hidden; text-overflow: ellipsis; text-align: left; padding: 2px 8px; color: var(--ct-texto); font-weight: 600; background: var(--yaya-verde-emprendedor, #D8F4D7); }
.ct-cos-matriz .ct-cos-base { position: sticky; left: var(--ct-cos-w1); z-index: 1; text-align: right; padding: 2px 8px; color: var(--ct-texto); white-space: nowrap; background: var(--yaya-verde-emprendedor, #D8F4D7); border-right-color: var(--yaya-crecimiento-tenue, #95A7A6); }
/* La esquina: fija arriba Y a la izquierda, por encima de las dos. */
.ct-cos-matriz thead .ct-cos-cohorte, .ct-cos-matriz thead .ct-cos-base { top: 0; z-index: 3; color: var(--ct-texto-suave); vertical-align: bottom; border-bottom-color: var(--yaya-crecimiento-tenue, #95A7A6); }
.ct-cos-celda { min-width: 40px; height: 24px; padding: 0 4px; text-align: center; color: var(--ct-texto); white-space: nowrap; }
.ct-cos-medida { box-shadow: inset 0 0 0 1px var(--yaya-crecimiento-tenue, #95A7A6); }
.ct-cos-neutra { background: var(--bg-primary, #ffffff); }
/* Dos tramos con la MISMA posicion --ct-cos-t (0% = minimo de la columna,
   100% = maximo), resueltos solo en CSS con dos color-mix anidados:
   - el de adentro va de Verde luz a Amarillo Pasion con peso clamp(t x 2):
     llega al amarillo pleno en t = 50% y se queda ahi;
   - el de afuera le suma el Coral Empuje con peso clamp((t - 50%) x 2): vale
     0% en toda la mitad baja (queda solo el de adentro) y sube a 100% en
     t = 100%.
   Posiciones: 0% verde luz, 25% mitad verde-amarillo, 50% amarillo, 75% mitad
   amarillo-coral, 100% coral. Texto en --ct-texto sobre los tres: 6,34:1,
   13,12:1 y 5,50:1. */
.ct-cos-escala { background: color-mix(in srgb, var(--yaya-coral-empuje, #F07C63) clamp(0%, calc((var(--ct-cos-t, 0%) - 50%) * 2), 100%), color-mix(in srgb, var(--yaya-amarillo-pasion, #DBFE87) clamp(0%, calc(var(--ct-cos-t, 0%) * 2), 100%), var(--yaya-verde-luz, #66BB7B))); }
.ct-cos-marca { font-weight: 400; font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--ct-texto-suave); }
/* La tarjeta de cosecha no es clicable (el detalle se abre con "Ver completa",
   ver ctTarjetaCosecha): sin cursor de mano ni el hover de .ct-tarjeta que dice
   "esto se clickea". Los valores son los de reposo de .ct-tarjeta. */
.ct-tarjeta.ct-tarjeta-cosecha { cursor: default; }
.ct-tarjeta.ct-tarjeta-cosecha:hover { border-color: var(--yaya-crecimiento-tenue, #95A7A6); box-shadow: 0 1px 1px rgba(16,24,40,.04), 0 2px 6px rgba(16,24,40,.05), 0 12px 24px -12px rgba(16,24,40,.10); transform: none; }
/* Esquina superior derecha de la tarjeta y del detalle: unidad + selector de
   cosecha (ctCabeceraDerCosecha). */
.ct-cos-cabecera-der { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.ct-cos-cabecera-der .ct-toggle-mini { margin-left: 0; }
/* Titulo de la tarjeta de cosechas, mas grande que el .ct-nombre comun (19px)
   por ser de ancho triple. SOLO esta tarjeta: .ct-tarjeta-cosecha no existe en
   el detalle (.ct-detalle), asi que ahi queda en 19px.

   RE-CALIBRADO con Poppins (PBI 973), mismo criterio que con Centory: el
   titulo no puede agrandar la fila de cabecera, que la fija el toggle
   Onboarding/Colocacion. Toggle = 3px + 3px (.ct-toggle) + 4px + 4px
   (.ct-toggle-mini .ct-toggle-btn) + 12px x 1,302 (alto de linea de DM Sans,
   medido en fonts/DMSans-Regular.ttf) = 29,6px. Con Centory (alto de linea
   1,2) 22px daban 26,4px y entraban. Con Poppins (1,5) solo cambiando el
   tamano el techo es 29,6 / 1,5 = 19,7px: ya no queda lugar para ser mas
   grande que el .ct-nombre comun. Por eso el tamano se queda en 22px y lo que
   se ajusta es el alto de linea: 22px x 1,3 = 28,6px, dentro de los 29,6px.
   A 1,3 los trazos de Poppins (1,4em de ascendente + descendente) desbordan
   la caja ~1px por lado sin recortarse: es un titulo de una linea. */
.ct-tarjeta-cosecha .ct-nombre { font-size: 22px; line-height: 1.3; }
.ct-cos-fila-resumen { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
/* Panel "Descargar CSV" (ctPanelDescargaCosecha): es un .ct-periodo-detalle,
   fondo verde crecimiento. El accent-color de .ct-leyenda-checkbox es ese
   mismo verde y la casilla marcada no se veria: se aclara solo aca. */
.ct-cos-descarga .ct-leyenda-checkbox input { accent-color: var(--yaya-verde-emprendedor, #D8F4D7); }
.ct-cos-descarga .ct-leyenda + .ct-leyenda { margin-top: 10px; }
.ct-cos-descarga .ct-boton[disabled] { opacity: .6; cursor: default; }
.ct-cos-descarga > .ct-boton { margin-left: 0; }
.ct-cos-sw-max { background: var(--yaya-coral-empuje, #F07C63); }
.ct-cos-sw-min { background: var(--yaya-verde-luz, #66BB7B); }
/* El amarillo si lleva borde: 1,04:1 contra el fondo, sin borde no se ve. */
.ct-cos-sw-medio { background: var(--yaya-amarillo-pasion, #DBFE87); border: 1px solid var(--yaya-crecimiento-tenue, #95A7A6); }
.ct-cos-leyenda-escala { gap: 10px; }
.ct-cos-sw-neutra { background: var(--bg-primary, #ffffff); border: 1px solid var(--yaya-crecimiento-tenue, #95A7A6); }
.ct-cos-sw-sin-dato { background: transparent; border: 1px dashed var(--yaya-crecimiento-tenue, #95A7A6); box-shadow: none; }

/* FPD por cohorte de aprobacion (ctTablaCohortesFpd, PBI 1048): cada fila
   abre las cifras de su cohorte, igual que un punto del grafico; la elegida
   va sobre blanco, como la celda neutra de la cosecha. Las columnas de
   cifras, a la derecha y con numeros tabulares. */
.ct-fpd-tabla tbody tr { cursor: pointer; }
.ct-fpd-tabla .ct-fpd-num, .ct-ecuacion .ct-fpd-num { text-align: right; font-variant-numeric: tabular-nums; }
/* La ecuacion del 5.2 (ctEcuacionCierres, CT_CIERRES_MES.ecuacion): cada renglon es un
   .ct-mes con el texto a la izquierda y el monto a la derecha (.ct-fpd-num, arriba); el
   total, en el color del texto y no en el suave, y nunca en rojo. */
.ct-ecuacion .ct-mes { justify-content: space-between; flex-wrap: nowrap; }
.ct-ecuacion .ct-ecuacion-total { color: var(--ct-texto); font-weight: 600; }
/* En el detalle (revision de Miguel en Live Server, 16/10/2026) la ecuacion ocupaba todo el
   ancho y los montos quedaban a ~1.100px de su texto: no se leia como una cuenta. Ahi va
   angosta y a la izquierda, bajo la cifra. 360px dan aire al renglon mas largo (~265px:
   "− Minimum operating reserve" o "− Desplegado o comprometido" a 12,5px, mas "US$ 848.8 K*"
   y el gap de 10px de .ct-mes). La tarjeta no cambia: ahi el ancho ya es el de la columna. */
.ct-detalle .ct-destacado .ct-ecuacion { max-width: 360px; }
/* La cascada del 5.7 (ctCascadaCierres, CT_CIERRES_MES.cascada, PBI 1004, tarea 1257):
   barras horizontales desde cero. Rotulos y montos en --ct-texto, a 9u como el resto
   del texto de los graficos. El tono de cada barra lo declara su renglon: serie2 es el
   morado oscuro de la serie 2 (4,61:1 sobre la tarjeta) y neutro el --gray-500
   (#737373, 4,03:1 sobre #D8F4D7, medido): las dos pasan el 3:1 de un objeto grafico.
   En el detalle, angosta como la ecuacion (CT_CASCADA_DETALLE_VB_ANCHO, 1u = 1px). */
.ct-cascada-rotulo, .ct-cascada-monto { font-size: 9px; fill: var(--ct-texto); font-family: var(--ct-fuente-texto); }
.ct-cascada-monto { font-variant-numeric: tabular-nums; }
.ct-cascada-serie2 { fill: var(--yaya-morado-oscuro, #6660B0); }
.ct-cascada-neutro { fill: var(--gray-500, #737373); }
.ct-detalle .ct-destacado svg.ct-cascada { max-width: 360px; }
/* Cascada del margen de contribucion (PBI 997, ctCascadaMargen): nueve renglones
   flotantes, del ingreso al margen. NO es .ct-grafico: la pasada de alto fijo mide
   el primer svg.ct-grafico hijo de la tarjeta, que es la franja de 6 meses. Su alto
   es el de sus renglones (242u; 1u = 1px a ancho completo) y no crece ni se achica
   con la tarjeta. En el detalle, 864px de ancho maximo (viewBox de 864u). Su texto
   va a 12u, no a los 9u del resto de los SVG: a escala 1:1, 9u eran 9px reales
   (correccion de Miguel del 16/10/2026). ctCascadaMargen mide con la misma fuente.
   Colores (decision de Miguel del 16/10/2026), medidos sobre la tarjeta #D8F4D7:
   serie 1 --yaya-verde-crecimiento 12,63:1, costos --gray-500 4,03:1, margen
   negativo --red-600 4,10:1 (el rojo de .ct-valor-negativo), linea de cero
   --yaya-crecimiento-luz 3,35:1. Todos pasan el 3:1 de un objeto grafico. */
.ct-cascada-margen { display: block; width: 100%; height: auto; flex: 0 0 auto; margin-top: 4px; }
.ct-detalle svg.ct-cascada-margen { max-width: 864px; }
.ct-cascada-margen-nombre, .ct-cascada-margen-monto { font-size: 12px; fill: var(--ct-texto); font-family: var(--ct-fuente-texto); }
.ct-cascada-margen-origen { font-size: 12px; fill: var(--ct-texto-suave); font-family: var(--ct-fuente-texto); }
.ct-cascada-margen-monto { font-variant-numeric: tabular-nums; }
.ct-cascada-margen-serie1 { fill: var(--yaya-verde-crecimiento, #022D2B); }
.ct-cascada-margen-costo { fill: var(--gray-500, #737373); }
.ct-cascada-margen-negativo { fill: var(--red-600, #dc2626); }
.ct-cascada-margen-falta { fill: none; stroke: var(--ct-texto-suave); stroke-width: 1; stroke-dasharray: 3 2; }
.ct-cascada-margen-cero { stroke: var(--yaya-crecimiento-luz, #6C8584); stroke-width: 1; }
/* El panel del periodo tiene fondo --yaya-verde-crecimiento: ahi serie 1 daria
   1,00:1. Se invierte dentro de la misma pareja, como el texto del panel
   (--ct-texto pasa a --yaya-verde-emprendedor): 12,63:1. Sobre ese fondo, medido,
   los costos dan 3,13:1, el rojo 3,08:1 y la linea de cero 3,77:1. */
.ct-periodo-detalle .ct-cascada-margen-serie1 { fill: var(--yaya-verde-emprendedor, #D8F4D7); }
/* La barra negativa de la franja del margen (CT_ECONOMIA_UNITARIA.negativoRojo, en
   ctGrafico), en el rojo de .ct-valor-negativo: 4,10:1 sobre la tarjeta. Liso,
   tambien seleccionada o en curso: esos estados los marca su contorno. Dos y tres
   clases, despues de .ct-barra-abierta.ct-barra-sel: le gana a todas. */
.ct-barra.ct-barra-negativa-roja,
.ct-barra.ct-barra-negativa-roja.ct-barra-sel,
.ct-barra.ct-barra-negativa-roja.ct-barra-abierta { fill: var(--red-600, #dc2626); }
.ct-fpd-tabla tr.ct-fpd-fila-sel td { background: var(--bg-primary, #ffffff); font-weight: 600; }

/* Franja superior (PBI 998): tarjetas de lectura rapida entre el selector de
   tarjetas y la rejilla, en todos los subtabs; con un detalle abierto no se
   muestra (ver CT_FRANJA y ctFranjaHtml). Grilla de 3 columnas pensada para
   tres tarjetas; bajo 1024px, una por fila, igual que .ct-rejilla. Separada de
   la rejilla por el mismo gap de 16px que hay entre tarjetas. Una tarjeta con
   detalle en CT_FRANJA es clicable (.ct-franja-clicable, abajo). */
.ct-franja { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin-bottom: 16px; }
@media (max-width: 1024px) { .ct-franja { grid-template-columns: 1fr; } }
.ct-franja-tarjeta { background: var(--yaya-verde-emprendedor); border: 1px solid var(--yaya-crecimiento-tenue); border-radius: 18px; padding: 14px 18px; display: flex; flex-direction: column; gap: 4px; }
/* Con detalle en CT_FRANJA: clicable, con el MISMO cursor, transicion y hover
   que .ct-tarjeta (borde Verde crecimiento, sombra mas honda, sube 1px). */
.ct-franja-clicable { cursor: pointer; transition: box-shadow .18s, border-color .18s, transform .18s; }
.ct-franja-clicable:hover { border-color: var(--yaya-verde-crecimiento); box-shadow: 0 1px 1px rgba(16,24,40,.05), 0 4px 10px rgba(16,24,40,.07), 0 18px 32px -14px rgba(16,24,40,.16); transform: translateY(-1px); }
/* El chip de estado de las autonomias (5.6 y 5.8) va aca, a la derecha. */
.ct-franja-cabecera { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
/* Chip de estado (PBI 1003, ctFranjaChip): simbolo y palabra, el color solo
   acompana. La palabra en --ct-texto (12,63:1 contra #D8F4D7, texto de 12,5px:
   umbral 4,5:1) y solo el simbolo en color (umbral 3:1, grafico): Sano en
   --yaya-verde-profundo 6,33:1, Vigilancia en --yaya-coral-oscuro 3,75:1 y
   Critico en --yaya-coral-profundo 5,70:1. Sin tono nuevo: la paleta no tiene
   ambar y el derivado probado (Coral Empuje + Amarillo pasion, x0,764 dos
   veces) daba 4,12:1 pero se leia marron y casi igual al Critico (1,38:1 entre
   los dos). El borde, el de la tarjeta (--yaya-crecimiento-tenue): decorativo. */
.ct-franja-chip { display: inline-flex; align-items: baseline; gap: 5px; flex-shrink: 0; padding: 1px 9px; border: 1px solid var(--yaya-crecimiento-tenue); border-radius: 999px; font-size: 12.5px; font-weight: 600; color: var(--ct-texto); white-space: nowrap; }
.ct-franja-chip-sano .ct-franja-chip-simbolo { color: var(--yaya-verde-profundo); }
.ct-franja-chip-vigilancia .ct-franja-chip-simbolo { color: var(--yaya-coral-oscuro); }
.ct-franja-chip-critico .ct-franja-chip-simbolo { color: var(--yaya-coral-profundo); }
.ct-franja-etiqueta { font-family: var(--ct-fuente-nombre); font-size: 15px; font-weight: 600; color: var(--ct-texto); }
.ct-franja-ventana { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--ct-texto-suave); }
.ct-franja-valor { font-size: 30px; font-weight: 700; letter-spacing: -0.02em; color: var(--ct-texto); line-height: 1.1; }
.ct-franja-variacion { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.ct-franja-contra { font-size: 12.5px; color: var(--ct-texto-suave); }
/* La variacion usa .ct-delta (18px en 700: NO es texto grande, umbral 4,5:1),
   pero aca va sobre la tarjeta verde y no sobre #fafafa. --primary-700 da
   4,25:1 contra #D8F4D7 y no llega; --yaya-verde-profundo da 6,33:1. El coral
   de .ct-delta-baja (--yaya-coral-profundo) ya da 5,70:1 y se queda. */
.ct-franja .ct-delta-sube { color: var(--yaya-verde-profundo); }

/* Barra apilada de N segmentos fijos (CT_APILADO_N, el CAC).
   Mes N.A.: no hay barra, solo el texto sobre la base (ctGrafico). Va en el
   texto suave (5,55:1 contra la tarjeta); elegido, en el pleno.
   Con un mes elegido en el detalle, los demas se atenuan: barra, N.A. y el
   total de arriba. */
.ct-na-barra { font-size: 9px; font-weight: 700; fill: var(--ct-texto-suave); font-family: var(--ct-fuente-texto); }
.ct-na-barra-sel { fill: var(--ct-texto); }
.ct-grafico-interactivo .ct-na-barra { cursor: pointer; }
.ct-barra-atenuada { opacity: .35; }

/* Subtab con alturaPorContenido (CT_SUBTABS, hoy solo rentabilidad, con
   ingresos_mensual): cada tarjeta mide lo que su contenido. El min-height de
   460px de .ct-tarjeta existe para que las tarjetas que COMPARTEN una fila
   midan lo mismo; en un subtab de ancho completo cada una va sola en su fila,
   y ahi el minimo solo deja un hueco al pie de la que tiene menos contenido.
   Dos clases (0-2-0) le ganan a .ct-tarjeta sin depender del orden. Los demas
   subtabs no llevan la clase: no cambian. */
.ct-rejilla-altura-contenido .ct-tarjeta { min-height: 0; }

/* Vista Insumos (PBI 1238, tarea 1241; js/control-tower-insumos.js). Todo sale de lo que ya
   existe, segun las decisiones de Miguel del 15/10/2026: los montos con el borde y el radio de
   .ct-selector, alineados a la derecha y con cifras tabulares; el error de celda y el resumen con
   --red-600 y --red-50; Guardar con los colores de la pastilla activa de .ct-subtabs; las hojas
   en .ct-toggle; .ct-boton, .ct-selector y .ct-aviso tal cual. En el telefono la tabla se
   desplaza de costado (.cti-scroll), no se apila. Lo unico sin precedente, a aprobar en Live
   Server: la lista de reglas, el punto y el texto ambar de "cambios sin guardar" y el ancho de la
   columna Que incluye. */
.cti-cabecera { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin: 0 0 12px; }
.cti-cabecera .ct-toggle { max-width: 100%; overflow-x: auto; }
.cti-cabecera .ct-toggle-btn { white-space: nowrap; }
.cti-punto { color: var(--amber-600, #d97706); }
.cti-reglas { margin: 0 0 14px; padding-left: 20px; font-size: 12.5px; line-height: 1.5; color: var(--ct-texto-suave); }
.cti-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 0 12px; }
.cti-tabla td { vertical-align: top; }
.cti-tabla .cti-num { text-align: right; }
.cti-tabla .cti-fija { white-space: nowrap; }
.cti-tabla .cti-nota { min-width: 260px; font-size: 12px; color: var(--ct-texto-suave); }
.cti-tabla .ct-selector { margin-left: 0; }
.cti-monto { width: 100%; min-width: 140px; box-sizing: border-box; border: 1px solid var(--yaya-crecimiento-luz, #6C8584); border-radius: 8px; padding: 4px 8px; font: inherit; font-size: 13px; color: var(--ct-texto); background: var(--bg-primary); text-align: right; font-variant-numeric: tabular-nums; }
.cti-tabla .cti-error { border-color: var(--red-600, #dc2626); }
.cti-motivo { display: block; margin-top: 3px; font-size: 11.5px; line-height: 1.3; text-align: left; color: var(--red-600, #dc2626); }
.cti-resumen { margin: 0 0 12px; padding: 8px 12px; border-radius: 8px; font-size: 13px; background: var(--red-50, #fef2f2); color: var(--red-600, #dc2626); }
.cti-resumen ul { margin: 4px 0 0; padding-left: 18px; }
.ct-boton.cti-agregar, .ct-boton.cti-quitar { margin-left: 0; }
.cti-acciones { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 12px 0 4px; }
.cti-guardar { border: none; border-radius: 999px; padding: 7px 15px; font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; background: var(--yaya-verde-crecimiento, #022D2B); color: var(--yaya-verde-emprendedor, #D8F4D7); }
.cti-guardar:focus-visible { outline: 2px solid var(--yaya-verde-crecimiento, #022D2B); outline-offset: 2px; }
.cti-guardar[disabled] { opacity: .6; cursor: default; }
.cti-estado-guardado { font-size: 12.5px; color: var(--ct-texto-suave); }
.cti-sucio { color: var(--amber-600, #d97706); font-weight: 600; }
.cti-notas { margin-top: 18px; }
