/* CSS compartido de las páginas React migradas -- extraído del bloque
   <style> que hasta ahora vivía duplicado, casi carácter por carácter, en
   static/app/dashboard/index.html Y static/app/investigacion/index.html
   (reporte_diseno_header_compartido_react_2026-09-07.txt sección 2.1,
   punto 5 del alcance: ~100 líneas de duplicación real confirmada). Cubre
   los tokens base + el layout compartido de sidebar/topbar/card/tabla que
   AMBAS páginas usaban idéntico -- no solo el header en sentido estricto,
   mismo criterio del diseño ("el CSS de tokens compartido a un archivo
   único enlazado por <link>, nunca duplicado en un <style> por página").

   Lo que NO entra acá: reglas que solo una de las 2 páginas usaba (ej.
   .cardgrid/.mini/dialog#dlg-bots de Dashboard, .subtabs/.chat-box/.field
   de Investigación) -- esas siguen en el <style> propio de cada index.html,
   junto a las reglas NUEVAS del header (chip--env, chip--fresh, bell/badge,
   popover de noticias, .status del reloj/mercado), agregadas acá porque SÍ
   son compartidas por diseño desde el día 1 (nunca existieron duplicadas
   para empezar). */
:root {
  --omnia-bg: #0d0d0d; --omnia-bg-elevated: #1a1a1a; --omnia-border: #2c2c2c;
  --omnia-text: #fafafa; --omnia-text-muted: #a3a8b4;
  --omnia-gold: #d4af37; --omnia-gold-bright: #f2c94c;
  --omnia-gold-muted: rgba(212,175,55,0.14); --omnia-gold-border: rgba(212,175,55,0.4);
  --color-success: #2ecc71; --color-success-bg: rgba(46,204,113,0.12);
  --color-danger: #ef4444; --color-danger-bg: rgba(239,68,68,0.12);
  --color-warning: #f59e0b; --color-warning-bg: rgba(245,158,11,0.12);
  --radius-card: 16px; --radius-pill: 999px; --transition-base: 180ms cubic-bezier(0.23,1,0.32,1);
  --omnia-glass-bg: rgba(26,26,26,0.6); --omnia-glass-bg-hover: rgba(34,34,34,0.68); --omnia-glass-bg-solid: rgba(22,22,22,0.96);
  --omnia-glass-border: rgba(255,255,255,0.08); --omnia-glass-border-hover: rgba(255,255,255,0.16);
  --omnia-glass-shadow: 0 8px 32px rgba(0,0,0,0.45); --omnia-glass-blur: 16px;
  --marcador-entrada: #5aa9e6; --marcador-salida: #f472b6;
  --font-ui: "Source Sans 3", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", Consolas, "SFMono-Regular", Menlo, monospace;
  --sidebar-w: 240px; --topbar-h: 56px;
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--omnia-bg); color: var(--omnia-text); font-family: var(--font-ui); font-size: 15px; line-height: 1.45; }
.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.glass { background: var(--omnia-glass-bg); backdrop-filter: blur(var(--omnia-glass-blur)) saturate(140%); -webkit-backdrop-filter: blur(var(--omnia-glass-blur)) saturate(140%);
  border: 1px solid var(--omnia-glass-border); border-radius: var(--radius-card); box-shadow: var(--omnia-glass-shadow); }
.up { color: var(--color-success); } .down { color: var(--color-danger); } .muted { color: var(--omnia-text-muted); } .gold { color: var(--omnia-gold-bright); }
.spacer { flex: 1; }
[hidden] { display: none !important; }
.app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; transition: grid-template-columns var(--transition-base); }
.sidebar { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; overflow: hidden auto;
  background: var(--omnia-glass-bg); backdrop-filter: blur(var(--omnia-glass-blur)) saturate(140%); -webkit-backdrop-filter: blur(var(--omnia-glass-blur)) saturate(140%);
  border-right: 1px solid var(--omnia-glass-border); box-shadow: var(--omnia-glass-shadow); padding: 1rem 0.75rem; }

/* Colapso de sidebar (#btn-collapse en el topbar) -- pieza NUEVA compartida
   agregada en la reconstrucción de Kelly (2026-09-13, ver reporte de esa
   tarea): los 8 mockups aprobados (dashboard/investigacion/contabilidad/
   deposito-retiro/pionex/kelly/capital/sistema) traen este botón y este
   mecanismo idénticos, pero ninguna página React ya migrada lo había
   implementado todavía -- vacío silencioso confirmado por auditoría, no una
   decisión explícita. Se agrega acá (una sola vez, compartido) en vez de
   duplicarlo por página, mismo criterio que el resto de este archivo.
   Toggle real: header_module.js::montar() (ignora el botón si la página no
   lo tiene, mismo criterio defensivo que el resto del módulo). Sin
   persistencia entre reloads -- el boceto tampoco la tiene. */
.app.collapsed { --sidebar-w: 64px; }
.collapsed .sidebar { padding: 1rem 0.5rem; }
.collapsed .brand .name, .collapsed .status, .collapsed .nav .lbl, .collapsed .signature { display: none; }
.brand { text-align: center; padding: 0.5rem 0 0.25rem; }
.brand .logo { width: 62px; height: 62px; border-radius: 12px; margin: 0 auto 0.4rem; display: block; object-fit: contain; } /* logo real (assets/logoapp_ui.png en Streamlit, static/app/img/logoapp_ui.png acá) -- antes un <div> con "OT" de placeholder genérico, nunca el emblema real. 62px (Pepe, 2026-09-15): mismo tamaño que ya usa app.py:624 en el sidebar real de Streamlit -- 44px lo dejaba chico. El "cuadrado amarillo aplastado" que reportó era un .brand .logo LOCAL duplicado en el <style> propio de cada página (mismo bug de especificidad que .chip--env) que le ganaba por orden de cascada a este reset -- eliminado de las 5 páginas que lo tenían. */
.brand .name { font-weight: 800; font-size: 1.15rem; letter-spacing: 0.05em; white-space: nowrap; }
.nav { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.nav a { display: flex; align-items: center; gap: 0.7rem; padding: 0.6rem 0.85rem; border-radius: var(--radius-card); color: var(--omnia-text); text-decoration: none; font-size: 1rem; border: 1px solid transparent; white-space: nowrap; }
.nav a:hover { background: var(--omnia-glass-bg-hover); }
.nav a[aria-current="page"] { background: var(--omnia-gold-muted); border-color: var(--omnia-gold-border); }
.nav svg { width: 18px; height: 18px; flex-shrink: 0; }
.signature { margin-top: auto; text-align: center; font-size: 0.7rem; color: var(--omnia-text-muted); opacity: 0.55; padding: 0.5rem 0; }
.main { display: flex; flex-direction: column; min-width: 0; }
.topbar { position: sticky; top: 0; z-index: 5; height: var(--topbar-h); display: flex; align-items: center; gap: 0.75rem; padding: 0 1.5rem;
  background: var(--omnia-glass-bg); backdrop-filter: blur(var(--omnia-glass-blur)) saturate(140%); -webkit-backdrop-filter: blur(var(--omnia-glass-blur)) saturate(140%); border-bottom: 1px solid var(--omnia-glass-border); }
.topbar h1 { margin: 0; font-size: 1.35rem; font-weight: 800; display: inline-flex; align-items: center; gap: 0.5rem; }
.topbar h1 svg { width: 22px; height: 22px; color: var(--omnia-gold-bright); }
.iconbtn { width: 36px; height: 36px; border-radius: var(--radius-pill); display: grid; place-items: center; border: 1px solid var(--omnia-glass-border); background: var(--omnia-glass-bg); color: var(--omnia-text-muted); cursor: pointer; padding: 0; position: relative; }
.iconbtn svg { width: 18px; height: 18px; }
.chip { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em; padding: 0.2rem 0.6rem; border-radius: var(--radius-pill); border: 1px solid var(--omnia-glass-border-hover); color: var(--omnia-text-muted); white-space: nowrap; }
.chip--ok { color: var(--color-success); border-color: rgba(46,204,113,0.4); background: var(--color-success-bg); }
.chip--crit { color: var(--color-danger); border-color: rgba(239,68,68,0.4); background: var(--color-danger-bg); }
/* Bug real "franja negra al colapsar sidebar" (Pepe, 2026-09-14, confirmado con
   getBoundingClientRect() en Kelly): `.content` (acá y en la copia literal de
   Kelly, mockup_kelly_frontend_react_2026-09-05.html línea 54) fija un
   max-width sin `margin: auto` -- con sidebar expandida el hueco sobrante a la
   derecha de `.main` es chico y pasa inadvertido, pero al colapsar (`--sidebar-w`
   240px -> 64px, header.css línea 60) `.main` gana ~176px extra que `.content`
   nunca ocupa (tope de max-width) ni centra -- queda pegado a la izquierda y el
   hueco a la derecha (fondo de `.main`, transparente, deja ver `--omnia-bg`
   #0d0d0d de `body`) se ve como una franja negra sólida de un solo lado. No es
   la transición de `grid-template-columns` (esa recalcula bien, medido) ni la
   sidebar -- `margin: 0 auto` centra `.content` dentro de `.main` en cualquier
   ancho, mismo fix para las 2 páginas que ya usan esta regla compartida
   (Dashboard/Investigación) y para Kelly y Sistema vía cascada (sus
   <style> propios redeclaran max-width/width pero nunca `margin`, así que
   heredan este fix sin tocar su archivo). */
.content { padding: 1rem 1.5rem 2rem; display: flex; flex-direction: column; gap: 0.85rem; max-width: 1400px; width: 100%; margin: 0 auto; }
.card { padding: 0.85rem 1rem; display: flex; flex-direction: column; gap: 0.5rem; min-width: 0; }
h3.rotulo { margin: 0; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--omnia-text-muted); }
.pre-json { font-family: var(--font-mono); font-size: 0.72rem; white-space: pre-wrap; word-break: break-word; color: var(--omnia-text-muted); max-height: 240px; overflow-y: auto; margin: 0; }
.sec { display: flex; align-items: center; gap: 0.5rem; margin: 0.3rem 0 0; }
.sec h2 { margin: 0; font-size: 1.1rem; font-weight: 800; }
.table-wrap { overflow-x: auto; border: 1px solid var(--omnia-glass-border); border-radius: 10px; }
table { width: 100%; border-collapse: collapse; font-size: 0.84rem; }
thead th { position: sticky; top: 0; background: var(--omnia-glass-bg-solid); text-align: left; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--omnia-text-muted); padding: 0.5rem 0.7rem; border-bottom: 1px solid var(--omnia-glass-border-hover); white-space: nowrap; }
tbody td { padding: 0.35rem 0.7rem; border-bottom: 1px solid var(--omnia-glass-border); white-space: nowrap; max-width: 320px; overflow: hidden; text-overflow: ellipsis; }
tbody tr:last-child td { border-bottom: 0; }
.btn { font: inherit; font-size: 0.8rem; font-weight: 600; padding: 0.3rem 0.9rem; border-radius: var(--radius-pill); border: 1px solid var(--omnia-glass-border); background: var(--omnia-glass-bg); color: var(--omnia-text); cursor: pointer; }
.btn:hover { border-color: var(--omnia-glass-border-hover); background: var(--omnia-glass-bg-hover); }
.btn--primary { border-color: var(--omnia-gold-border); background: var(--omnia-gold-muted); color: var(--omnia-gold-bright); }
.btn--sm { font-size: 0.74rem; padding: 0.2rem 0.7rem; }
.tabs { display: flex; gap: 0.2rem; border-bottom: 1px solid var(--omnia-glass-border); overflow-x: auto; min-height: 2.3rem; }
.tabs button { font: inherit; font-size: 0.86rem; font-weight: 600; padding: 0.55rem 0.9rem; background: transparent; border: 0; border-bottom: 2px solid transparent; color: var(--omnia-text-muted); cursor: pointer; white-space: nowrap; margin-bottom: -1px; }
.tabs button[aria-selected="true"] { color: var(--omnia-gold-bright); border-bottom-color: var(--omnia-gold); }
.tabs button.oos { opacity: 0.5; cursor: not-allowed; }
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.75rem; }
.metric { padding: 0.55rem 0.8rem; border-radius: 10px; border: 1px solid var(--omnia-glass-border); background: var(--omnia-glass-bg); }
.metric .label { font-size: 0.7rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--omnia-text-muted); }
.metric .value { font-size: 1.25rem; font-weight: 800; color: var(--omnia-gold-bright); font-variant-numeric: tabular-nums; }
.kv { display: grid; grid-template-columns: 1fr auto; gap: 0.3rem 1rem; font-size: 0.86rem; margin: 0; }
.kv dt { color: var(--omnia-text-muted); } .kv dd { margin: 0; text-align: right; font-family: var(--font-mono); }
.toast { position: fixed; bottom: 1rem; left: 50%; transform: translateX(-50%); z-index: 60; padding: 0.5rem 1rem; border-radius: 4px; font-size: 0.82rem; opacity: 0; transition: opacity var(--transition-base); pointer-events: none; background: var(--omnia-glass-bg-solid); border: 1px solid var(--omnia-border); border-left: 3px solid var(--omnia-text-muted); max-width: min(560px, 92vw); }
.toast.show { opacity: 1; }
/* BUG REAL compartido: las páginas migradas ya llaman toast(msg, "ok"/"warn"/
   "crit") pero esta regla nunca existió en ningún lado (ni acá ni en el
   <style> propio de cada página) -- CONFIRMADO EN VIVO (2026-09-13,
   encontrado independientemente por Depósito/Retiro, Contabilidad, Kelly,
   Capital.com, Investigación, Pionex, Sistema y Dashboard): todo toast, sin importar
   el tipo, salía con el mismo borde gris neutro de `.toast` base. Copiado
   LITERAL del mockup (mismo valor en los ~8 mockups que definen
   `.toast.ok/.warn/.crit` idéntico). Puesto ACÁ (compartido) en vez de en
   cada index.html -- es el mismo bug en todas las páginas, corregirlo una
   sola vez. */
.toast.ok { border-left-color: var(--color-success); }
.toast.warn { border-left-color: var(--color-warning); }
.toast.crit { border-left-color: var(--color-danger); }

/* ---------- NUEVO en esta tarea: reloj/mercado (sidebar), chips de
   entorno/frescura y campana de noticias (topbar) -- reporte_diseno_
   header_compartido_react_2026-09-07.txt secciones 3-7. Copiado del
   patrón ya aprobado en mockup_dashboard_frontend_react_2026-09-05.html,
   nunca redisañado acá. ---------- */
.status { text-align: center; font-size: 0.78rem; line-height: 1.7; color: var(--omnia-text-muted); padding-bottom: 0.9rem; white-space: nowrap; }
.status .mkt { color: var(--color-success); }
.status .mkt.cerrado { color: var(--color-warning); }
/* Rediseño "más limpio" (Pepe, 2026-09-14): el chip único fusionando los 2
   brókers con un separador "·" quedaba amontonado (2 puntos de color + 2
   textos + separador en una sola píldora chica, difícil de leer). Ahora
   #chip-env es un contenedor SIN estilo propio (background/border/padding
   en cero) que agrupa 2 píldoras .seg reales, cada una con su propio
   fondo/borde tenue según demo/real -- sigue siendo "un segmento por
   bróker, nunca un chip único fusionado" (la regla de fondo no cambia,
   solo la forma en que se ve). Especificidad `.chip.chip--nodot`/
   `.chip.chip--env` (Pepe, 2026-09-15): un `.chip` local duplicado en el
   <style> propio de cada página cargaba después en el cascade y le ganaba
   a este reset por empate de especificidad, mostrando un óvalo gris detrás
   del chip celeste/ámbar real -- subir a especificidad (0,2,0) lo gana
   siempre, sin tocar el .chip local de cada página. */
.chip.chip--nodot::before { display: none; }
.chip.chip--env { background: none; border: none; padding: 0; gap: 0.45rem; }
.chip--env .seg { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em; padding: 0.2rem 0.6rem; border-radius: var(--radius-pill); border: 1px solid var(--omnia-glass-border-hover); white-space: nowrap; }
.chip--env .seg::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.chip--env .seg--demo { color: var(--marcador-entrada); border-color: rgba(90,169,230,0.35); background: rgba(90,169,230,0.08); }
.chip--env .seg--real { color: var(--omnia-gold-bright); border-color: var(--omnia-gold-border); background: var(--omnia-gold-muted); }
.chip--fresh { font-family: var(--font-mono); font-weight: 500; letter-spacing: 0; min-width: 74px; justify-content: center; font-variant-numeric: tabular-nums; }
.chip--fresh.stale { color: var(--color-warning); border-color: rgba(245,158,11,0.4); background: var(--color-warning-bg); }
.bell .badge { position: absolute; top: -6px; right: -6px; background: var(--color-warning); color: #0e1117; border-radius: var(--radius-pill); font-size: 0.68rem; font-weight: 700; padding: 0 0.4rem; }
.bell .badge:empty { display: none; }
.pop { position: fixed; top: calc(var(--topbar-h) + 6px); right: 1.5rem; width: min(400px, 92vw); z-index: 30; padding: 0; overflow: hidden; }
.pop .ph { padding: 0.7rem 1rem; border-bottom: 1px solid var(--omnia-glass-border); display: flex; align-items: center; gap: 0.5rem; font-weight: 700; font-size: 0.9rem; }
.pop .pl { max-height: 50vh; overflow-y: auto; padding: 0.4rem; display: flex; flex-direction: column; gap: 0.2rem; }
.pop .pf { padding: 0.6rem 1rem; border-top: 1px solid var(--omnia-glass-border); font-size: 0.72rem; color: var(--omnia-text-muted); }
.news-item { display: block; width: 100%; text-align: left; font: inherit; background: transparent; border: 1px solid transparent; border-radius: 10px; padding: 0.35rem 0.5rem; color: var(--omnia-text); cursor: pointer; transition: background var(--transition-base), border-color var(--transition-base); }
.news-item:hover { background: var(--omnia-glass-bg-hover); }
.news-item b { display: block; font-size: 0.86rem; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.news-item small { font-size: 0.72rem; color: var(--omnia-text-muted); }
.news-item.unseen b::before { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--color-warning); margin-right: 0.4rem; vertical-align: 2px; }
dialog#dlg-noticia { border: 1px solid var(--omnia-glass-border); border-radius: var(--radius-card); background: var(--omnia-glass-bg-solid); color: var(--omnia-text); padding: 0; width: min(560px, 96vw); max-height: 90vh; box-shadow: var(--omnia-glass-shadow); overflow: hidden; display: none; flex-direction: column; }
dialog#dlg-noticia[open] { display: flex; }
dialog#dlg-noticia::backdrop { background: rgba(13,13,13,0.6); backdrop-filter: blur(4px); }
.dlg-head { display: flex; align-items: center; gap: 0.75rem; padding: 0.9rem 1.2rem; border-bottom: 1px solid var(--omnia-glass-border); }
.dlg-head h2 { margin: 0; font-size: 1.1rem; font-weight: 800; }
.dlg-body { padding: 1rem 1.2rem 1.2rem; overflow-y: auto; display: flex; flex-direction: column; gap: 0.9rem; }

@media (max-width: 767px) { .app { grid-template-columns: 1fr; } .sidebar, #btn-collapse { display: none; } .content { padding: 0.8rem; } }
@media (prefers-reduced-motion: reduce) { .app { transition: none; } }
