/* web/monitor/estilos.css */
:root {
  --fondo: radial-gradient(130% 100% at 12% -10%, #201a32 0%, #14111d 42%, #0b0a10 100%);
  --tarjeta: rgba(9, 8, 14, .55);
  --borde: rgba(167, 139, 250, .14);
  --texto: #e9e9ee;
  --tenue: #8f84b4;
  /* Paleta 26-09-2026: verde/rojo/ambar -> cyan/magenta/dorado (pedido
     del dueño). Los tres pasan contraste AAA sobre el fondo (10.9 / 7.5
     / 12.5) y quedan a 67°, 76° y 147° de tono del violeta del chrome
     (#a78bfa), que es lo que los mantiene distinguibles entre si. El
     magenta se eligio en 331° -- no en 290° (fucsia) -- justamente para
     no confundirse con ese violeta. */
  --sube: #22d3ee;
  --baja: #ff6bb2;
  --precio: #ffc53d;
}
* { box-sizing: border-box; }
body {
  margin: 0; padding: 16px; min-height: 100vh;
  background: var(--fondo); color: var(--texto);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.barra { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; flex-wrap: wrap; gap: 6px 12px; }
.barra h1 { font-size: 17px; font-weight: 650; margin: 0; letter-spacing: -.01em; }
.frescura { font-size: 12px; color: var(--tenue); }
/* Selector de idioma: al lado de la frescura, arriba a la derecha (pedido
   del dueño). barra-derecha agrupa ambos para que compartan una linea y,
   si el ancho no alcanza, bajen juntos en vez de que el selector quede
   pegado al titulo. */
.barra-derecha { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.idioma {
  font-size: 11px; color: var(--texto); background: var(--tarjeta);
  border: 1px solid var(--borde); border-radius: 6px; padding: 3px 5px;
  font-family: inherit; cursor: pointer;
}
.idioma:focus-visible { outline: 2px solid var(--precio); outline-offset: 1px; }
/* Salir: mismo aspecto que el selector de idioma, al lado. */
.salir {
  font-size: 11px; color: var(--tenue); background: var(--tarjeta);
  border: 1px solid var(--borde); border-radius: 6px; padding: 4px 7px;
  text-decoration: none;
}
.salir:hover { color: var(--texto); }
.salir:focus-visible { outline: 2px solid var(--precio); outline-offset: 1px; }
/* Sin glow en bordes: decidido en el diseño, menos efecto para mirar largo rato. */
.tarjeta, .grilla, .lateral { background: var(--tarjeta); border: 1px solid var(--borde); border-radius: 12px; }
.grilla, .lateral { padding: 12px 14px; }
/* Lateral ensanchado otra vez (260px -> 390px, mockup del dueño): ya no es
   solo la columna de noticias, ahora vive ahi la grilla de KPIs completa
   (ver .kpis mas abajo) que antes era una franja horizontal propia arriba
   de toda la pagina. Esa franja (el viejo #pulso) desaparece del todo. */
.cuerpo { display: grid; grid-template-columns: 1fr 390px; gap: 10px; }
/* Bug real de esta ronda (P16, verificado por render a 390px con un
   titulo de noticia largo -- ForexFactory no garantiza titulos cortos, ver
   badgeNoticia/pintarLateral en app.js): un item de grid tiene
   `min-width: auto` por default, que se resuelve al min-content de TODO
   su contenido -- y el min-content de un contenedor flex (.evento, mas
   abajo) NO hereda el `min-width:0` de su propio hijo (ese `min-width:0`
   solo lo deja encogerse una vez que el contenedor YA tiene un ancho
   resuelto, no cambia cuanto aporta el contenedor a un ANCESTRO que
   todavia esta calculando su propio tamaño por contenido). Con dos
   eventos ★★★ simultaneos (el destacado + uno en la lista secundaria) el
   titulo largo del segundo evento empujaba la columna entera de #grilla
   y #lateral -- las dos comparten la misma pista de grid en movil -- unos
   45px mas alla del viewport. `min-width: 0` en los dos items del grid es
   el arreglo estandar: nada cambia visualmente (las dos columnas siguen
   ocupando el mismo ancho que ya tenian) salvo que ahora SI pueden
   encogerse por debajo de su contenido cuando algo intenta forzarlas. */
.grilla, .lateral { min-width: 0; }
/* Bug 29-sep-2026 (medido a 768px): las ocho columnas fijas de .fila
   suman ~760px minimos, y entre 761px (fin del layout movil) y ~1215px de
   ventana la columna 1fr de .cuerpo le da menos que eso a #grilla. Las
   filas se salian de la tarjeta, se pintaban encima del lateral y a 768
   empujaban la pagina 8px de scroll horizontal. El arreglo de fondo es
   el layout de tablet (media 761-1279px, mas abajo); esto queda como red:
   si un texto largo (otro idioma) vuelve a no entrar, el sobrante queda
   adentro de la tarjeta con scroll propio y no rompe la pagina. */
.grilla { overflow-x: auto; }
.vacio { color: var(--tenue); font-size: 12px; }
/* Los seis KPIs (antes una franja horizontal propia, #pulso, arriba de
   toda la pagina) ahora viven adentro de la columna lateral, en un grid
   de dos columnas -- mockup del dueño. "Con actividad" ocupa las dos
   columnas (.kpi-full, mas abajo) porque es el dato mas relevante de la
   Capa 1 y porque su subtitulo ahora es una frase completa, no un
   fragmento, y necesita el ancho entero para no partirse feo. Los otros
   cuatro (indices/dolar/metal-energia/cripto) llenan el 2x2 debajo. */
.kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 10px; }
/* Estados de frescura: atenuar comunica "esto no es de ahora" sin texto. */
body[data-frescura="demorado"] .grilla { opacity: .6; }
body[data-frescura="caido"] .grilla { opacity: .35; }
body[data-frescura="caido"] .frescura { color: var(--baja); }

.kpi { background: var(--tarjeta); border: 1px solid var(--borde); border-radius: 12px; padding: 10px 12px; }
/* "Con actividad" ocupa las dos columnas del grid de KPIs (ver .kpis mas
   arriba): es el dato mas relevante de la Capa 1, y desde este cambio su
   subtitulo es la explicacion completa (ver actividad_explicacion en
   TEXTOS, app.js) en vez de un fragmento corto -- necesita el ancho
   entero. Numero mas grande (30px) para que se note la jerarquia contra
   los otros cuatro KPIs (23px). */
.kpi-full { grid-column: 1 / -1; }
.kpi-full .kv { font-size: 30px; }
.kl { font-size: 9px; letter-spacing: .1em; text-transform: uppercase; color: var(--tenue); }
.kv { font-size: 23px; font-weight: 650; letter-spacing: -.02em; margin-top: 2px; }
.kd { font-size: 12px; color: var(--tenue); }
.kn { font-size: 10px; color: var(--tenue); margin-top: 1px; }
/* Sesion y noticias: la tarjeta fusiona el KPI (el destacado, arriba) con
   la lista completa (lo secundario, abajo) que antes vivian en dos
   bloques separados -- dos tarjetas, no cuatro bloques (spec del dueño).
   Reusa .kl/.kv/.kn (mismo tratamiento tipografico que un KPI) y .evento
   (mismo que la lista de noticias/sesiones de siempre) en vez de
   inventar clases nuevas para lo mismo. */
.tarjeta-mini { background: var(--tarjeta); border: 1px solid var(--borde); border-radius: 12px; padding: 12px 14px; margin-top: 10px; }
.destacado { margin: 6px 0 10px; }
.lista-secundaria { border-top: 1px solid rgba(167,139,250,.09); padding-top: 4px; }
/* Tipografia mas grande en toda la fila (12.5px -> 14px, "es una fila
   densa de datos, no un pie de foto" -- pedido del dueño) y simbolo/precio
   un escalon por encima del resto (15px, ver .sym/.px mas abajo): son los
   dos datos que el ojo busca primero al recorrer la grilla. El panel de
   detalle (acordeon, P7) no se toca en esta ronda -- ver spec. */
/* Columnas: banda vs VWAP fija en 150px, un cuarto de lo que media antes
   (~590px con el viejo 1fr) -- el dueño la queria bien mas chica, no la
   columna dominante de la fila. Tendencia (H4/H1/M15/M5) pasa de cuatro
   puntos de 6px a una columna de 140px con las cuatro barras rotuladas
   (ver .tfs-marcos), asi que necesita mucho mas que los 72px de antes. El
   ancho que las dos se llevan de mas sale de "actividad" (unica columna
   sin ancho fijo, 1fr): crece o se achica con la ventana, y a partir de
   1280px de ancho de pagina (el minimo de este escritorio) le sobra lugar
   de sobra para el medidor y las dos lineas de texto que ya tenia. */
.fila { display: grid; grid-template-columns: 74px 96px 60px 56px 1fr 150px 54px 140px;
        gap: 8px; align-items: center; padding: 7px 8px; border-radius: 7px; font-size: 14px; }
.fila + .fila { border-top: 1px solid rgba(167,139,250,.09); }
.fila.cab { font-size: 8.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--tenue); }
/* P16 (revision movil, ver el media query de 760px mas abajo): oculto en
   escritorio -- ahi el orden ya se alcanza tocando los encabezados de
   `.fila.cab`. Vive siempre en el DOM (controlOrdenMovil, app.js) para no
   duplicar el armado de opciones entre anchos. */
.orden-movil { display: none; }
/* P15 (auditoria ronda 2, 25-sep-2026): encabezados ordenables -- clic o
   Enter/Espacio ordenan por esa columna (alternarOrden, delegado en
   #grilla igual que el clic de fila). El estado actual se anuncia con
   aria-sort (no solo la flechita ▲/▼, que un lector de pantalla no ve). */
.col-ordenable { cursor: pointer; user-select: none; }
.col-ordenable:hover, .col-ordenable:focus-visible { color: var(--precio); }
.col-ordenable:focus-visible { outline: 2px solid var(--precio); outline-offset: -2px; border-radius: 3px; }
.col-ordenada { color: var(--precio); }
.fila.error { grid-template-columns: 74px 1fr; color: var(--tenue); font-style: italic; }
/* Las filas sin datos no abren el detalle (alternarFila las rechaza,
   ver app.js): sin hover ni cursor de mano, para no invitar un clic que
   no hace nada. */
.fila:not(.cab):not(.error):hover { background: rgba(167,139,250,.07); cursor: pointer; }
/* Filas con tabindex="0" (app.js): foco de teclado visible, mismo trato
   que el hover de mouse mas un contorno -- sin esto un usuario de
   teclado no tiene forma de saber donde esta parado. */
.fila:not(.cab):not(.error):focus-visible { background: rgba(167,139,250,.07); outline: 2px solid var(--precio); outline-offset: -2px; }
/* P7: fila abierta (acordeon). Fondo sutil, el mismo tono que el hover --
   no un color nuevo -- para marcar "esta es la fila expandida" sin gritar. */
.fila.fila-abierta { background: rgba(167,139,250,.07); }
.sym { font-weight: 650; font-size: 15px; }
.px { font-size: 15px; }
/* Chevron: unico affordance visual de que la fila abre/cierra un panel.
   Vive junto al simbolo, nunca sobre el precio (P8a: el boton de cerrar
   del popup viejo tapaba el precio -- este no tapa nada, es parte del
   texto del simbolo). Gira con aria-expanded, no con :hover, para que
   el estado sea el mismo por mouse, teclado o repintado. */
.caret { display: inline-block; margin-left: 4px; font-size: 9px; color: var(--tenue);
         transform: rotate(0deg); transition: transform .18s ease; }
.fila[aria-expanded="true"] .caret { transform: rotate(180deg); }
/* P10/P13 (auditoria ronda 2, 25-sep-2026): badges compactos de la fila
   (compresion NR7, noticia proxima) -- el dueño ya pidio dos veces menos
   peso visual en la grilla, asi que van en su PROPIA linea chica debajo
   del simbolo (nunca ensanchan la columna: font-size 8px, padding
   minimo) en vez de una columna nueva que corriera el resto de la fila.
   Neutros a proposito (ni --sube ni --baja): son mediciones, no
   direcciones -- ver la regla del proyecto contra insinuar una ruptura
   o un lado a operar. */
.fila-badges { display: flex; gap: 3px; margin-top: 2px; flex-wrap: wrap; }
.badge-mini {
  display: inline-block; font-size: 8px; line-height: 1.5; padding: 1px 4px;
  border-radius: 3px; background: rgba(167,139,250,.14); color: var(--tenue);
  white-space: nowrap; letter-spacing: .02em; font-weight: 600;
}
/* En el encabezado del detalle (dt-cab) el badge va inline junto al
   simbolo, no en su propia linea -- ahi si hay lugar de sobra. */
.dt-sym .badge-mini, .dt-cab .badge-mini { margin-left: 2px; vertical-align: middle; }
/* P13: el badge de noticia usa el mismo acento violeta que el resto del
   panel reserva para "contexto informativo" (zonas FVG/OB, VAH/POC/VAL) --
   NO el ambar (reservado para el marcador de precio) ni verde/rojo
   (reservados para direccion). Es una alerta de tiempo, no de sentido. */
.badge-noticia { background: rgba(167,139,250,.22); color: #c4b5fd; }
.sube { color: var(--sube); } .baja { color: var(--baja); }
/* Neutro: variacion_dia sin dato (P11, ronda 2). Verde y rojo afirman una
   direccion; sin dato no se afirma ninguna. Reusa --tenue, no un color nuevo. */
.nt { color: var(--tenue); }
/* P7 (auditoria ronda 2, 25-sep-2026): el tachado era invisible sin
   pasar el mouse y no existe en el celular -- reemplazado por un badge
   visible (.badge-viejo-slot/.badge-viejo mas abajo). El numero conserva
   solo la opacidad reducida como pista secundaria; el badge es el que
   explica que pasa. */
.px.congelado { opacity: .55; }
/* Precio sin verificar (stale ni True ni False -- ver `stale` tri-estado
   en app.js): misma opacidad que congelado -- el numero solo no puede
   distinguir "confirmado viejo" de "no lo sabemos todavia". La
   diferencia la hace el badge, que SOLO aparece para "congelado". */
.px.incierto { opacity: .55; }
/* P7: badge de "dato viejo" -- mismo slot en la grilla (bajo el precio)
   y en la cabecera del detalle (dt-px-wrap). Siempre presente en el DOM
   (aunque vacio) para que aplicarPrecios() lo encuentre por
   [data-px-badge] cada 8s sin crear/destruir el nodo. */
.badge-viejo-slot:empty { display: none; }
.badge-viejo-slot { margin-top: 2px; }
.badge-viejo { background: rgba(167,139,250,.20); color: #c4b5fd; }
/* Mercado cerrado (03-oct-2026): neutro, no alarma -- es el horario, no una falla.
   En dos renglones para entrar en la columna HOY. */
.var-cerrado { display: block; font-size: 10.5px; line-height: 1.2; color: var(--tenue); }
.spark { height: 14px; width: 100%; }
/* Nombrada .medidor a proposito: .barra ya es la cabecera de la pagina
   (linea 18). Reusar el mismo nombre para esta mini-barra de metrica
   hacia que la cascada resolviera la cabecera con height:5px/overflow:
   hidden y le clipeara el titulo y #frescura a una tira invisible. */
.medidor { height: 5px; border-radius: 3px; background: rgba(167,139,250,.13); overflow: hidden; }
.medidor i { display: block; height: 100%; border-radius: 3px; background: #6d6d80; }
.micro { font-size: 9px; color: var(--tenue); margin-top: 2px; }
.banda { height: 15px; border-radius: 4px; position: relative;
         background: linear-gradient(90deg, rgba(167,139,250,.07), rgba(167,139,250,.17), rgba(167,139,250,.07)); }
.banda s { position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; background: rgba(255,255,255,.3); }
/* Unico glow permitido: el marcador del precio. Es el dato que se busca
   rapido al recorrer filas, y ahi el brillo trabaja a favor. */
.banda b { position: absolute; top: -2px; width: 2px; height: 19px; border-radius: 1px;
           background: var(--precio); box-shadow: 0 0 7px rgba(251,191,36,.75); }
/* Tendencia por marco: cuatro puntos de 6px no pesaban nada en la fila
   (pedido del dueño). Cada marco pasa a ser una unidad rotulada -- el
   nombre del timeframe arriba, la barra de color abajo -- en vez de un
   punto mudo que solo se explicaba al pasar el mouse (el title= se
   mantiene igual, como refuerzo). Con el rotulo en cada fila, el
   encabezado "H4·H1·M15·M5" de la cabecera de la grilla ya no hace
   falta (ver la celda vacia en pintarGrilla, app.js). En movil el rotulo
   se esconde (ver media query abajo): los 48px de esa columna ahi no
   alcanzan para texto + barra. */
.tfs-marcos { display: flex; gap: 5px; }
.tfs-marcos .tfs-item { flex: 1 1 0; min-width: 0; text-align: center; }
.tfs-lbl { display: block; font-size: 8.5px; letter-spacing: .04em; color: var(--tenue); margin-bottom: 3px; }
.tfs-marcos i { display: block; width: 100%; height: 8px; border-radius: 2px; }
.lt { font-size: 8.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--tenue); margin-bottom: 7px; }
/* El filtro de impacto (solo ★★★) se declara una vez en el titulo de la
   seccion, asi que cada fila solo necesita titulo + cuenta regresiva.
   min-width:0 + flex:1 en el primer span es lo que deja que text-overflow
   corte con "…" en vez de desbordar la tarjeta -- un span dentro de un
   flex container no se encoge por debajo de su contenido sin esto. */
.evento { display: flex; justify-content: space-between; gap: 8px; font-size: 10.5px; line-height: 1.9; }
.evento span:first-child { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.evento span:last-child { flex: 0 0 auto; }
/* L4: rango/sparkline dependen del ciclo lento (D1/M15/perfil de volumen,
   300s de cadencia). edad_lento > 900s -- tres ciclos perdidos -- marca
   la celda afectada, sutil (opacidad) y NO con el estilo de fila .error:
   el precio de esa fila sigue vivo, solo esas columnas estan viejas. */
.rezago { opacity: .6; }
.ico-lento { font-size: 8px; }

/* P7: el detalle dejo de ser un popup (dialog fixed) y paso a ser un
   acordeon dentro de la fila -- ver spec del dueño. El panel es un
   hermano de .fila en el DOM (no una celda de su grid), asi que crece
   en flujo normal y empuja las filas siguientes hacia abajo solo.
   .fila-panel-inner es el truco de altura desconocida sin salto: un
   grid de una sola celda que anima grid-template-rows de 0fr a 1fr.
   Animar max-height a un valor adivinado, la alternativa obvia, o
   recorta contenido real o se pasa de largo -- poner overflow:hidden
   en el item interno lo resuelve sin medir nada en JS. */
.fila-panel { overflow: hidden; }
.fila-panel-inner {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .22s ease;
}
.fila-panel-inner.fila-panel-abierta { grid-template-rows: 1fr; }
.fila-panel-content {
  overflow: hidden;
  min-height: 0;
  padding: 12px 10px 16px;
  border-top: 1px solid rgba(167,139,250,.09);
}
/* prefers-reduced-motion: sin transicion, ni en el panel ni en el
   chevron -- el estado cambia igual, solo que de golpe. El scroll al
   abrir (abrirPanelUI en app.js) tambien respeta esto por su lado. */
@media (prefers-reduced-motion: reduce) {
  .fila-panel-inner, .caret { transition: none; }
}
/* Cabecera del detalle: a la izquierda el simbolo CON el precio al lado
   (pedido del dueño -- antes el precio estaba del otro lado del panel y
   habia que cruzar la vista para leer de que instrumento era) y los
   badges; a la derecha la antiguedad del dato. */
.dt-cab { display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.dt-cab-izq { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; min-width: 0; }
.dt-sym { font-size: 17px; font-weight: 650; }
.dt-px { font-size: 19px; font-weight: 650; }
/* P7 (ronda 2): envuelve el precio + el badge de "dato viejo" para que
   se apilen a la derecha (columna, no fila) sin romper el
   space-between/baseline de .dt-cab -- sigue siendo el mismo segundo
   hijo de siempre, solo que ahora con dos lineas posibles. */
.dt-px-wrap { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; text-align: right; }
.dt-ejes { display: flex; justify-content: space-between; font-size: 9px; color: var(--tenue); margin-top: 3px; }

/* Rediseno del panel de detalle (24-sep-2026, maqueta OPCION 2 del
   dueño): dos tarjetas lado a lado -- "Del dia" y "Actividad y
   ubicacion" -- cada una con su propia barra de progreso por metrica en
   vez de la vieja lista `.dt-par` (par etiqueta/valor sin barra). Fondo
   apenas mas claro que el panel para separarlas sin un borde fuerte;
   SIN glow (regla del proyecto: nada de resplandor en bordes de tarjeta). */
/* El panel de detalle es una grilla de 2x2 de cajas parejas (pedido del
   dueño, 26-09-2026): arriba "La sesion de hoy" -- las dos tarjetas de
   antes unificadas -- y el velocimetro; abajo "Valor y zonas" y los
   pivots. Reemplaza a .dt-cards + .dt-perfil-pivots, que eran dos grillas
   distintas con bordes distintos (las de arriba con caja, las de abajo
   sin). Ahora las cuatro son .dt-box, con el mismo radio de 12px que
   .tarjeta/.grilla/.lateral en el resto de la pagina.
   min-width: 0 en las cajas por la misma razon que en .grilla/.lateral
   (P16): un item de grid arranca en min-width:auto y un contenido ancho
   empuja la columna entera mas alla del viewport. */
.dt-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 4px; }
/* "La sesion de hoy" como franja de una linea arriba del 2x2 (29-sep-2026).
   Segunda vuelta, pedido del dueño: cada indicador en una columna con
   titulo / valor / barra / nota, y las CUATRO filas compartidas entre
   columnas (subgrid): las barras quedan todas a la misma altura y del
   mismo largo aunque un titulo ocupe dos renglones. El titulo de la caja
   va en su propia columna y nunca pasa de dos renglones (ancho medido en
   ES/EN/PT). */
.dt-franja {
  display: grid; grid-template-columns: 112px repeat(6, minmax(0, 1fr));
  column-gap: 14px; row-gap: 3px; align-items: end;
  margin-top: 4px; margin-bottom: 12px;
}
.dt-franja .fr-titulo {
  grid-row: 1 / span 4; align-self: center; margin: 0;
  font-size: 15px; line-height: 1.2; text-align: left;
}
/* overflow-x: clip es el tope: un valor que no entra nunca estira su celda
   (y con ella su barra) mas alla de la columna. Solo horizontal, para no
   cortar los marcadores que sobresalen de la barra hacia arriba. */
.fr-item { display: grid; grid-row: span 4; grid-template-rows: subgrid; min-width: 0; overflow-x: clip; }
.fr-etq { font-size: 10.5px; color: var(--tenue); line-height: 1.25; align-self: end; }
/* 11px: con 12 el minimo-maximo de BTC (6 cifras + 2 decimales, dos
   veces) no entraba a 1440 px (medido: 121 px en una columna de 115). */
.fr-val { font-size: 11px; white-space: nowrap; color: var(--texto); font-weight: 600; font-variant-numeric: tabular-nums; }
/* Todas las barras: mismo alto, mismo largo (el de la columna). */
.fr-barra { height: 8px; margin-top: 3px; }
.fr-barra > .medidor, .fr-barra > .banda { height: 8px !important; }
.fr-barra .banda b { top: -3px; height: 14px; }
.fr-nota { align-self: start; margin-top: 3px; }
/* Minimo / Maximo: el minimo (etiqueta y valor) a la izquierda y el maximo a
   la derecha, como los extremos de la barra que tienen debajo, donde el
   marcador dorado es el precio actual dentro del rango del dia. */
.fr-extremos .fr-etq, .fr-extremos .fr-val { display: flex; justify-content: space-between; gap: 6px; }
/* ZigZag (29-sep-2026). Sin colores nuevos: velas con --sube/--baja, la
   linea con --texto, el precio vivo con --precio (la paleta queda como
   esta, decision del dueño). */
/* El titulo es un .lt directo de la caja, igual que en las otras tres
   (centrado, mismo tamaño); el selector va centrado debajo. */
.zz-tfs { display: flex; justify-content: center; gap: 4px; }
.zz-tf {
  font: inherit; font-size: 11px; color: var(--tenue); background: var(--tarjeta);
  border: 1px solid var(--borde); border-radius: 6px; padding: 2px 7px; cursor: pointer;
}
.zz-tf.activo { color: var(--texto); border-color: var(--tenue); }
.zz-tf:focus-visible { outline: 2px solid var(--precio); outline-offset: 1px; }
.dt-box > div > svg.zz-svg { display: block; width: 100%; height: auto; margin-top: 6px; }
.zz-tramo { stroke: var(--texto); stroke-width: 1.4; opacity: .85; }
.zz-tramo.zz-prov { opacity: .6; }
.zz-viejo { opacity: .45; }
.zz-pie { margin-top: 4px; }
.zz-nota { opacity: .75; }
.dt-box {
  background: rgba(255,255,255,.025); border: 1px solid var(--borde);
  border-radius: 12px; padding: 12px 14px; min-width: 0;
}
/* Los SVG estan topeados a proposito (ver el comentario del viewBox en
   construirValorZonas): sin tope escalan con el panel y la MISMA fuente
   se ve a 18px en una pantalla de 1512 y a 6px en un celular. La caja SI
   ocupa el ancho completo; el grafico se centra adentro.
   En pantallas anchas el tope sube -- ahi sobra lugar y el aire a los
   costados se notaba (51px por lado) -- pero solo hasta donde el texto
   sigue comodo. Medido en una pantalla de 1512: 420px llena el 87% de la
   caja y deja la tipografia en 10,1-14,3px. Soltar el tope del todo daria
   15-20px, que es de donde veniamos y lo que el dueño rechazo. El celular
   no se toca: ahi la caja mide ~305px y el tope nunca entra en juego. */
/* El tope vive ACA y no en un style inline del SVG: inline le gana en
   especificidad a cualquier media query, asi que con el tope inline la
   regla de abajo no hacia nada (visto al medir: el SVG seguia en 380
   con la pantalla en 1512). */
.dt-box > svg {
  display: block; margin-left: auto; margin-right: auto; max-width: 380px;
}
.dt-box > svg[viewBox="0 0 236 236"] { max-width: 300px; }
@media (min-width: 1200px) {
  .dt-box > svg { max-width: 420px; }
  .dt-box > svg[viewBox="0 0 236 236"] { max-width: 320px; }
}
/* Subtitulo de las dos mitades adentro de "La sesion de hoy". Mas chico y
   mas apagado que .lt, que es el titulo de la caja. */
.dt-sub {
  font-size: 9px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--tenue); opacity: .75; font-weight: 600; margin: 14px 0 7px;
}
.dt-box .lt + .dt-sub { margin-top: 10px; }
/* Titulo de cada caja del desplegable: al doble de cuerpo (8,5 -> 17px) y
   centrado, pedido del dueño. El tracking BAJA de .1em a .05em: el
   espaciado que hace legible una versalita de 8px la desarma a 17, donde
   las letras ya se separan solas. Solo aplica a las cajas del detalle --
   las etiquetas de la columna lateral (sesiones, proximas ★★★) siguen en
   8,5px, que es el tamaño que les corresponde ahi. */
.dt-box > .lt {
  font-size: 17px; letter-spacing: .05em; text-align: center;
  margin-bottom: 14px; font-weight: 600; color: var(--texto); opacity: .82;
}
/* "Ver mas info": las notas al pie de los graficos, plegadas. */
.dt-notas { margin-top: 8px; }
.dt-notas > summary {
  font-size: 10px; color: var(--tenue); cursor: pointer; list-style: none;
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 0;
  user-select: none;
}
.dt-notas > summary::-webkit-details-marker { display: none; }
.dt-notas > summary::before { content: "+"; font-size: 12px; line-height: 1; opacity: .8; }
.dt-notas[open] > summary::before { content: "−"; }
.dt-notas > summary:hover { color: var(--texto); }
.dt-notas > summary:focus-visible { outline: 2px solid var(--precio); outline-offset: 2px; border-radius: 4px; }
.dt-notas .micro { margin-top: 4px; }
.dt-minmax { display: flex; justify-content: space-between; font-size: 12px; color: var(--tenue); margin-bottom: 10px; }
.dt-minmax b { color: var(--texto); font-weight: 650; font-variant-numeric: tabular-nums; }
.dt-medidor-fila { margin-bottom: 9px; }
.dt-medidor-fila:last-child { margin-bottom: 0; }
.dt-medidor-etq { display: flex; justify-content: space-between; font-size: 10.5px; color: var(--tenue); margin-bottom: 3px; }
.dt-medidor-etq span:last-child { color: var(--texto); }
/* Marcador de "esperado a esta hora" sobre la barra de "rango consumido"
   (ver barraConMarcador en app.js): una linea neutra (no ambar -- ese
   color queda reservado para el precio en el resto del panel), asi que
   se lee como una referencia, no como una segunda medicion en pugna con
   el relleno de la barra. */
.medidor { position: relative; }
.medidor-marca {
  position: absolute; top: -3px; width: 2px; height: 13px;
  background: var(--texto); opacity: .85; border-radius: 1px;
}

/* El sesgo por marco ya no son cuatro chips planos (P14) sino UN
   velocimetro de anillos concentricos -- H4 afuera, M5 adentro. Es SVG
   entero (construirTendenciaPorMarco en app.js), asi que no necesita
   reglas propias aca: las clases .tf-chips/.tf-chip/.tf-chip-tf/
   .tf-chip-etq que vivian en este lugar se borraron con el markup que
   las usaba. */

/* "Valor y zonas" + "Pivots Fibonacci": las dos piezas graficas van lado
   a lado, mismo criterio que la maqueta aprobada ("para que las dos
   piezas rimen"). En escritorio nada mas -- ver la regla de 760px mas
   abajo para que no genere scroll horizontal en movil. */

/* P8d: leyenda de los cuatro puntos de tendencia (H4/H1/M15/M5). Vive
   fuera de .cuerpo (ver index.html) asi que es una tarjeta propia, mismo
   estilo que .grilla/.lateral pero mas baja -- es una sola linea de
   texto chico, no un panel de datos. */
.leyenda-tendencia {
  margin-top: 10px; padding: 8px 14px; font-size: 10px; color: var(--tenue);
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px;
}
.leyenda-item { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.leyenda-item i { width: 7px; height: 7px; border-radius: 2px; display: inline-block; flex: none; }

/* P9b: aviso legal, al pie de todo. Deliberadamente sin tarjeta/borde ni
   color de alarma (nada de --baja aca) -- es informativo, no una
   advertencia de la pagina sobre si misma, y no puede competir en peso
   visual con la grilla de datos de arriba. */
.aviso-legal {
  margin: 6px 0 0; padding: 0 14px 10px; font-size: 9.5px; color: var(--tenue);
  text-align: center;
}

/* Movil: dos lineas por simbolo. La cabecera se esconde porque las
   columnas dejan de estar alineadas y su texto solo confundiria.
   Cada celda tiene su propia clase c-* para que el grid-area la
   encuentre: dejar una celda sin clase es lo que rompio esto la
   primera vez (auto-placement silencioso en vez del layout con nombre). */
/* Entre celular y escritorio ancho, siete celdas en una fila no entran:
   tres por fila y el titulo arriba. Corte en 1440 y no en 1100: medido a
   1200 px, en una fila cada barra quedaba de 75 px y los valores largos
   ("66% del ADR (14d)") se partian; a 1280, el minimo-maximo de BTC no
   entraba. Una sola linea desde 1440 px. */
@media (max-width: 1439px) {
  .dt-franja { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .dt-franja .fr-titulo { grid-column: 1 / -1; grid-row: auto; margin-bottom: 6px; }
}
/* Tablet (761-1279px, 29-sep-2026): la fila de escritorio necesita ~760px
   y al lado del lateral de 390px no entraba (ver .grilla overflow-x). En
   este rango la grilla pasa a ocupar todo el ancho y el lateral baja
   abajo, en dos columnas: KPIs a la izquierda, sesiones y noticias a la
   derecha -- las mismas piezas y proporciones que en escritorio, solo
   reacomodadas. Desde 1280px (el minimo del escritorio) vuelven las dos
   columnas de siempre. */
@media (min-width: 761px) and (max-width: 1279px) {
  .cuerpo { grid-template-columns: 1fr; }
  .lateral { display: grid; grid-template-columns: 1fr 1fr; column-gap: 10px; align-items: start; }
  .lateral > .kpis { grid-column: 1; grid-row: 1 / span 2; margin-bottom: 0; }
  .lateral > .tarjeta-mini { grid-column: 2; }
  .lateral > .kpis + .tarjeta-mini { margin-top: 0; }
}
/* Tablet angosta: a todo el ancho igual faltan ~50px para las ocho
   columnas. Se saca el mini-grafico de 8h (y su encabezado, la 4ta celda
   de .fila.cab) -- mismo sacrificio que en movil; variacion, banda y
   tendencia quedan. */
@media (min-width: 761px) and (max-width: 899px) {
  .fila { grid-template-columns: 74px 96px 60px 1fr 150px 54px 140px; }
  .c-spark, .fila.cab > :nth-child(4) { display: none; }
}
@media (max-width: 760px) {
  .cuerpo { grid-template-columns: 1fr; }
  /* Los KPIs ya no son la franja horizontal deslizable de antes (esa
     ronda de movil quedo afuera del alcance de este cambio, ver spec del
     dueño) -- ahora son parte de la columna lateral, que en movil ya cae
     debajo de la grilla por el .cuerpo de arriba. El grid de 2 columnas
     de .kpis entra sin ajuste: no hace falta una regla especial aca. */
  body { padding: 10px; }
  .fila.cab { display: none; }
  /* P16: unica afordancia de orden en este ancho (ver controlOrdenMovil,
     app.js) -- reemplaza a los cinco encabezados tocables de arriba, que
     siguen ocultos. Estilo alineado con `.idioma` (mismo tratamiento de
     tarjeta chica) pero a todo el ancho: es la unica pieza de UI nueva de
     esta fila y no compite por espacio con nada mas. */
  .orden-movil { display: block; margin-bottom: 8px; }
  .orden-movil select {
    width: 100%; font-size: 12px; color: var(--texto); background: var(--tarjeta);
    border: 1px solid var(--borde); border-radius: 8px; padding: 7px 8px;
    font-family: inherit;
  }
  .orden-movil select:focus-visible { outline: 2px solid var(--precio); outline-offset: 1px; }
  /* Los 48px de la columna de tendencia no alcanzan para rotulo + barra
     (ver .tfs-marcos mas arriba) -- se esconde el rotulo y queda solo la
     barra, mismo tamaño que el punto que reemplaza en este ancho. El
     title= de cada barra sigue ahi para quien la toque. */
  .tfs-lbl { display: none; }
  .fila {
    grid-template-columns: 1fr 1.1fr 54px 48px;
    grid-template-areas:
      "sym  sym   px  px"
      "act  banda rng tfs";
    row-gap: 6px;
    padding: 9px 10px;
  }
  .c-sym   { grid-area: sym; font-size: 13px; }
  .c-px    { grid-area: px; text-align: right; }
  /* P7 (ronda 2): `.c-px` paso a ser el WRAPPER (precio + badge de "dato
     viejo", ver .badge-viejo-slot) -- el tamaño/peso que antes vivia en
     este mismo selector (cuando .px y .c-px eran el mismo elemento) hay
     que aplicarselo ahora al `.px` de adentro a proposito, porque su
     propia regla de escritorio (`.px{font-size:15px}`, mas arriba)
     gana por especificidad si no se la reescribe aca. */
  .c-px .px { font-size: 13px; font-weight: 650; }
  .c-act   { grid-area: act; }
  .c-banda { grid-area: banda; }
  .c-rango { grid-area: rng; }
  /* Bug real de esta ronda (P16, verificado por render a 390px): con
     `justify-self: end` el contenedor NO se estira a los 48px de la
     columna -- se dimensiona por contenido, y los cuatro `.tfs-item`
     (flex:1 1 0, sin ancho propio) colapsan a ~1px cada uno (quedaban
     15px total para las cuatro barras, invisibles). Sin `justify-self`
     (default: stretch) el contenedor ocupa los 48px completos de la
     columna, que es donde ya vivia (ultima columna, alineada a la
     derecha por si sola) -- `justify-self:end` no aportaba nada aca y
     rompia el ancho. */
  .c-tfs   { grid-area: tfs; }
  /* En 375px no entran ocho columnas. Se sacrifican variacion y
     mini-grafico: el precio y las cuatro barras son lo que orienta. */
  .c-var, .c-spark { display: none; }
  .fila.error { grid-template-columns: 1fr; grid-template-areas: "sym" "px"; }
  .fila.error .c-px { text-align: left; font-weight: 400; }
  .lateral { margin-top: 10px; }
  /* Panel de detalle: "no debe romper" es el requisito de esta ronda para
     movil (no tiene que ser lindo todavia, ver spec) -- las dos tarjetas
     y las dos piezas graficas, que en escritorio van lado a lado, se
     apilan a una columna para que nada empuje el ancho de la pagina a
     mas de 375px. */
  .dt-grid { grid-template-columns: 1fr; }
  .dt-franja { grid-template-columns: 1fr 1fr; }
  .dt-franja .fr-titulo { grid-column: 1 / -1; grid-row: auto; margin-bottom: 6px; }
  /* En el celular el padding lateral de la caja le sale directo al ancho
     del grafico: con 14px por lado el SVG bajaba de 305 a 275 y el texto
     de 7,3 a 6,6px -- medido, no estimado. Aca el ancho es el recurso
     escaso, no el aire. */
  .dt-box { padding: 12px 8px; }
}

/* ── Analisis del Equipo Legendario (02-oct-2026) ─────────────────────
   Box a lo ancho, debajo del 2x2. Tipo chat: avatar redondo y globo al
   lado. Colores solo de las variables de la paleta (no se toca). */
.dt-equipo { margin-top: 12px; }
.dt-equipo.eq-atenuado { opacity: .55; }
.eq-cab { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.eq-edad { font-size: 11px; color: var(--tenue); white-space: nowrap; }
.eq-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.eq-chip { font-size: 11px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--borde); color: var(--texto); }
.eq-sesgo-alcista { color: var(--sube); border-color: currentColor; }
.eq-sesgo-bajista { color: var(--baja); border-color: currentColor; }
.eq-sesgo-sin_definir { color: var(--precio); border-color: currentColor; }
.eq-chat { display: flex; flex-direction: column; gap: 10px; }
.eq-msg { display: flex; gap: 10px; align-items: flex-start; }
/* 50px = alto de un globo de una linea (nombre + una linea de texto,
   medido 49,8px el 03-oct-2026): pedido del dueño, la foto acompaña al
   mensaje mas corto sin quedar mas chica que el. */
.eq-av {
  flex: 0 0 50px; width: 50px; height: 50px; border-radius: 50%;
  display: grid; place-items: center; object-fit: cover;
  font-size: 15px; font-weight: 700; letter-spacing: .02em;
  color: var(--eq-color, var(--tenue)); background: rgba(255,255,255,.05);
  border: 1.5px solid var(--eq-color, var(--borde));
}
.eq-av-equipo { --eq-color: var(--precio); font-size: 20px; }
.eq-globo {
  background: rgba(255,255,255,.045); border: 1px solid var(--borde);
  border-radius: 4px 12px 12px 12px; padding: 7px 11px; min-width: 0; max-width: 100%;
}
.eq-msg-general .eq-globo { background: rgba(255,197,61,.06); }
.eq-nombre { font-size: 11px; font-weight: 650; color: var(--tenue); margin-bottom: 2px; }
.eq-globo p { margin: 0; font-size: 13px; line-height: 1.45; color: var(--texto); overflow-wrap: anywhere; }
.eq-mirar { margin-top: 12px; }
.eq-mirar ul { margin: 0; padding-left: 18px; font-size: 12.5px; line-height: 1.5; color: var(--texto); }
.eq-aviso { margin: 10px 0 0; font-size: 10.5px; color: var(--tenue); }
