/* Una Cartera — panel financiero, tres pieles.
 *
 * CAMBIO DE IDENTIDAD DELIBERADO (2026-09-22). La app dejó la estética de
 * banca privada de 1950 por un lenguaje de dashboard fintech moderno, a
 * pedido explícito del usuario y a sabiendas de que reemplaza la decisión
 * anterior (la de "tinta sobre papel", con paleta contenida y sin color
 * saturado) — no es una variación de aquélla, es otra.
 *
 * Tres temas seleccionables por `data-theme`, cada uno con su propia
 * personalidad de color, pero los MISMOS nombres de variable: todo lo que
 * pinta con `var(--algo)` — las tarjetas, las tortas (`CAT` en app.js), los
 * KPI de ganancia/pérdida — cambia solo al cambiar de tema, sin tocar una
 * sola regla fuera de este bloque.
 *
 *   Dark Fintech   fondo casi negro con tinte azulado, tarjetas de vidrio
 *                  (semitransparentes + blur), acentos verde neón y púrpura.
 *   Soft UI        fondo claro y cálido, tarjetas blancas con radios grandes
 *                  y una sombra apenas perceptible, paleta pastel.
 *   Trading Pro    azul profundo casi negro, alto contraste, sin blur ni
 *                  sombra — la estética de una terminal, no de una app de
 *                  consumo. Acá el color SÍ es el canal principal de
 *                  ganancia/pérdida, a propósito: es el género que se pidió.
 *
 * `--card-bg/-radius/-shadow/-blur/-border` son la indirección que separa
 * "qué dice cada tema" (este bloque) de "cómo se pinta una tarjeta" (más
 * abajo, una sola regla `.card` para los tres). Soft UI no necesita blur;
 * Trading Pro no necesita sombra; ninguno de los dos toca `.card` para
 * decirlo, sólo deja esa variable en `none`.
 *
 * Tipografía dual: serif para lo que se lee de un vistazo (títulos, cifras
 * grandes), sans para lo que se lee de cerca (tablas, menús, formularios).
 * Las dos se cargan de Google Fonts; si no hay internet, las alternativas
 * locales (Georgia y la del sistema) sostienen el mismo contraste.
 */

:root, :root[data-theme="soft-ui"] {
  color-scheme: light;

  --font-serif: "Playfair Display", Georgia, "Iowan Old Style", "Times New Roman", serif;
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --page: #f2f0fb;
  --surface-1: #ffffff;
  --surface-2: #f6f4fd;

  --text-primary: #302e48;
  --text-secondary: #6f6c93;
  --muted: #a29fc4;

  --grid: #ece9f8;
  --axis: #ddd9f1;
  --border: rgba(48, 46, 72, 0.10);

  /* Escala ordinal: de un violeta claro a uno intenso. Mide magnitud, no
     identidad — por eso un solo matiz alcanza para ella. */
  --ramp-1: #4b3f8f;
  --ramp-2: #6a5cc2;
  --ramp-3: #8c80d6;
  --ramp-4: #aea5e5;
  --ramp-5: #cdc6ef;
  --ramp-6: #e8e4f8;

  --accent: #6c5ce7;
  --accent-strong: #5b48d6;
  --accent-soft: #eae6fb;
  --on-accent: #ffffff;

  /* Categórica pastel: seis matices distintos, no un degradé de uno solo —
     la torta pregunta "¿cuál es?", y eso lo tiene que decir el color, con la
     etiqueta al lado como red de seguridad. */
  --cat-1: #7c6ff0;
  --cat-2: #58c9b9;
  --cat-3: #f2a65a;
  --cat-4: #ef7ea8;
  --cat-5: #6fb1e8;
  --cat-6: #e0c95e;

  --acct-0: #8b85c9;
  --acct-1: #5b48d6;
  --acct-2: #58c9b9;
  --acct-3: #f2a65a;
  --acct-4: #ef7ea8;
  --acct-5: #6fb1e8;
  --acct-6: #e0c95e;
  --acct-7: #a684e8;
  --acct-8: #4fb88a;
  --on-acct: #ffffff;

  --good: #2fae72;
  --critical: #e6567a;
  --good-wash: #2fae72;
  --critical-wash: #e6567a;

  /* Tarjeta blanca, radio grande, sombra apenas ahí — nada de vidrio. */
  --card-bg: var(--surface-1);
  --card-radius: 18px;
  --card-shadow: 0 12px 32px -20px rgba(76, 68, 148, 0.28);
  --card-blur: none;
  --card-border: 1px solid var(--border);
}

:root[data-theme="fintech-dark"] {
  color-scheme: dark;

  --font-serif: "Playfair Display", Georgia, "Iowan Old Style", "Times New Roman", serif;
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --page: #060714;
  --surface-1: #0d0f22;
  --surface-2: #12142a;

  --text-primary: #eef1fb;
  --text-secondary: #9aa0c6;
  --muted: #5c6086;

  --grid: rgba(238, 241, 251, 0.06);
  --axis: rgba(238, 241, 251, 0.12);
  --border: rgba(238, 241, 251, 0.12);

  /* De un violeta profundo a un cian casi blanco: la escala ordinal de este
     tema, pensada para leerse sobre vidrio oscuro. */
  --ramp-1: #6f5cff;
  --ramp-2: #8f7bff;
  --ramp-3: #a99dff;
  --ramp-4: #b9e3ff;
  --ramp-5: #cdeeff;
  --ramp-6: #e6f8ff;

  --accent: #39ffb0;
  --accent-strong: #22e6a0;
  --accent-soft: rgba(57, 255, 176, 0.14);
  --on-accent: #04140f;

  /* Vibrante a propósito — es lo que pide el género: verde neón, púrpura,
     cian, rosa, ámbar, azul eléctrico. */
  --cat-1: #39ffb0;
  --cat-2: #b072ff;
  --cat-3: #38c6ff;
  --cat-4: #ff5d9e;
  --cat-5: #ffcc4d;
  --cat-6: #5b8dff;

  --acct-0: #7a80b8;
  --acct-1: #39ffb0;
  --acct-2: #b072ff;
  --acct-3: #38c6ff;
  --acct-4: #ff5d9e;
  --acct-5: #ffcc4d;
  --acct-6: #5b8dff;
  --acct-7: #ff9d5c;
  --acct-8: #6dffe0;
  --on-acct: #04140f;

  --good: #39ffb0;
  --critical: #ff5d7a;
  --good-wash: #39ffb0;
  --critical-wash: #ff5d7a;

  /* Vidrio: fondo semitransparente + blur + un borde que apenas brilla.
     `--card-bg` lleva alfa, así que el blur SE VE — una tarjeta opaca con
     blur detrás no es glassmorphism, es una tarjeta común. */
  --card-bg: rgba(18, 21, 42, 0.58);
  --card-radius: 14px;
  --card-shadow: 0 18px 44px -22px rgba(57, 255, 176, 0.16);
  --card-blur: blur(18px) saturate(140%);
  --card-border: 1px solid rgba(180, 190, 255, 0.16);
}

:root[data-theme="trading-pro"] {
  color-scheme: dark;

  --font-serif: "Playfair Display", Georgia, "Iowan Old Style", "Times New Roman", serif;
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --page: #050912;
  --surface-1: #0a0f1c;
  --surface-2: #0e1526;

  --text-primary: #e9edf7;
  --text-secondary: #7c88ab;
  --muted: #48516d;

  --grid: rgba(233, 237, 247, 0.05);
  --axis: rgba(233, 237, 247, 0.10);
  --border: rgba(233, 237, 247, 0.10);

  --ramp-1: #2f8bff;
  --ramp-2: #5aa3ff;
  --ramp-3: #7fbaff;
  --ramp-4: #a3d0ff;
  --ramp-5: #c6e3ff;
  --ramp-6: #e6f2ff;

  --accent: #2f8bff;
  --accent-strong: #1c74e6;
  --accent-soft: rgba(47, 139, 255, 0.14);
  --on-accent: #04101f;

  /* Alto contraste, frío: azules y verdes de terminal, sin los pasteles de
     Soft UI ni el arcoíris de Dark Fintech. */
  --cat-1: #00e6a0;
  --cat-2: #2f8bff;
  --cat-3: #ffb020;
  --cat-4: #ff3b5c;
  --cat-5: #7fd4ff;
  --cat-6: #8f9bff;

  --acct-0: #6b7699;
  --acct-1: #00e6a0;
  --acct-2: #2f8bff;
  --acct-3: #ffb020;
  --acct-4: #ff3b5c;
  --acct-5: #7fd4ff;
  --acct-6: #8f9bff;
  --acct-7: #ff8f4d;
  --acct-8: #4de0c8;
  --on-acct: #04101f;

  /* ACÁ el color es el canal principal de ganancia/pérdida — el signo sigue
     estando (nunca es el ÚNICO canal), pero la intención de este tema es
     precisamente el semáforo de una terminal de trading. */
  --good: #00e6a0;
  --critical: #ff3b5c;
  --good-wash: #00e6a0;
  --critical-wash: #ff3b5c;

  /* Sin blur, sin sombra: filo y densidad de terminal, no de vidrio. */
  --card-bg: var(--surface-1);
  --card-radius: 4px;
  --card-shadow: none;
  --card-blur: none;
  --card-border: 1px solid var(--border);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--page);
  color: var(--text-primary);
  font: 14px/1.6 var(--font-sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* La serif es para lo que se lee de un vistazo: títulos y cifras grandes.
   Peso 500 y no 700 — Playfair ya trae el contraste en el trazo, y el bold
   sólo la empasta. */
h1, h2, h3,
.hero, .kpi .value, .cash-amount, .mep-rate {
  font-family: var(--font-serif);
  font-weight: 500;
  letter-spacing: 0;
}

/* --- estructura: barra lateral + contenido --- */

.shell { display: flex; min-height: 100vh; align-items: stretch; }

.sidebar {
  width: 248px; flex: none;
  background: var(--surface-1);
  border-right: 1px solid var(--border);
  padding: 36px 22px 26px;
  display: flex; flex-direction: column; gap: 36px;
  position: sticky; top: 0; height: 100vh;
}

/* El logo es lo primero que se ve, así que se le da aire por los cuatro lados
   y una línea finísima debajo que lo separa del menú sin encajonarlo. */
.brand {
  padding: 2px 4px 26px;
  border-bottom: 1px solid var(--border);
}
.brand img {
  display: block; width: 100%; height: auto;
  /* El archivo es tinta negra sobre transparencia; en oscuro se invierte. */
}
/* El logo es tinta negra sobre transparencia; se invierte en los dos temas
   oscuros (Dark Fintech, Trading Pro), no en Soft UI. */
:root[data-theme="fintech-dark"] .brand img,
:root[data-theme="trading-pro"] .brand img { filter: invert(1); }

#nav { display: flex; flex-direction: column; gap: 1px; }
.nav-item {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: 13.5px; text-align: left;
  padding: 10px 12px; border-radius: 3px;
  color: var(--text-secondary); min-height: 38px;
  transition: background .14s ease, color .14s ease;
}
.nav-item:hover { background: var(--accent-soft); color: var(--text-primary); }
.nav-item[aria-current="true"] {
  background: var(--accent-soft); color: var(--text-primary); font-weight: 500;
}
.sidebar-foot {
  margin-top: auto; display: flex; flex-direction: column; gap: 10px;
}
.sidebar-foot .toggle { width: 100%; }
.sidebar-foot .toggle button { flex: 1; }

/* El tope de ancho es alto a propósito: esto muestra tablas de doce columnas
   y recortarlas a 1220 px dejaba "%" y "TNA" fuera de pantalla mientras
   sobraba margen vacío a la derecha. La prosa no se estira igual — las notas
   tienen su propio tope en 78ch. */
.main { flex: 1; min-width: 0; padding: 40px 44px 88px; max-width: 1640px; }
.topline {
  color: var(--muted); font-size: 12px; margin-bottom: 26px;
  letter-spacing: .02em;
}

/* --- controles --- */

.toggle {
  display: inline-flex; border: 1px solid var(--border);
  border-radius: 3px; overflow: hidden; background: var(--surface-1);
}
.toggle button {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  padding: 8px 18px; font: inherit; font-size: 12.5px; font-weight: 500;
  letter-spacing: .04em;
  color: var(--text-secondary); min-height: 36px;
  transition: background .14s ease, color .14s ease;
}
.toggle button:hover { background: var(--accent-soft); color: var(--text-primary); }
/* Lo seleccionado se invierte: tinta de fondo, papel de letra. Ése es el
   único "color de acento" que tiene la app. */
.toggle button[aria-pressed="true"] {
  background: var(--accent-strong); color: var(--on-accent);
}
.ghost {
  appearance: none; background: transparent; cursor: pointer;
  border: 1px solid var(--border); border-radius: 3px;
  padding: 8px 14px; font: inherit; font-size: 12.5px;
  color: var(--text-secondary);
  min-height: 36px; min-width: 40px;
  transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.ghost:hover {
  background: var(--accent-soft); color: var(--text-primary);
  border-color: var(--axis);
}

/* La acción principal. No lleva clase en el marcado: dentro de .actions, el
   botón que NO es .ghost es el que hace la cosa. Y su acento es la inversión
   — tinta de fondo, papel de letra — que es el único énfasis fuerte que se
   permite la app. */
.actions button:not(.ghost) {
  appearance: none; cursor: pointer;
  background: var(--accent-strong); color: var(--on-accent);
  border: 1px solid var(--accent-strong); border-radius: 3px;
  padding: 10px 24px; min-height: 40px;
  font: inherit; font-size: 12.5px; font-weight: 500; letter-spacing: .04em;
  transition: opacity .14s ease;
}
.actions button:not(.ghost):hover { opacity: .82; }
.actions button:not(.ghost):disabled { opacity: .38; cursor: default; }

/* Un foco visible y sobrio, igual en todos lados. */
.nav-item:focus-visible, .toggle button:focus-visible, .ghost:focus-visible,
.actions button:focus-visible, .dropzone:focus-visible {
  outline: 1px solid var(--accent); outline-offset: 2px;
}

/* --- tarjetas --- */

.grid { display: grid; gap: 22px; }
.cols-2 { grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); }

/* Sin sombra: el papel de la tarjeta ya se despega del fondo por ser más
   claro. Una sombra acá sólo agregaría ruido. */
.card {
  background: var(--card-bg, var(--surface-1));
  border: var(--card-border, 1px solid var(--border));
  border-radius: var(--card-radius, 3px);
  box-shadow: var(--card-shadow, none);
  backdrop-filter: var(--card-blur, none);
  -webkit-backdrop-filter: var(--card-blur, none);
  padding: 30px 32px;
  margin-bottom: 22px;
}
/* El título de tarjeta va en SANS y en versalitas: es una etiqueta, no un
   titular. La serif se guarda para las cifras, que es donde luce. */
.card h2 {
  font-family: var(--font-sans);
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .14em;
  color: var(--muted); margin: 0 0 22px; font-weight: 500;
}
.note {
  color: var(--muted); font-size: 12px; margin-top: 18px; line-height: 1.65;
  max-width: 78ch;
}

/* --- hero y KPIs --- */

.hero {
  font-size: 52px; line-height: 1.05;
  letter-spacing: -0.015em; color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.hero-sub {
  color: var(--text-secondary); margin-top: 12px; font-size: 13px;
}

/* La fila de cinco tarjetas del Resumen. `auto-fit`, no un número fijo de
   columnas: en un monitor angosto se apilan de a dos o una sin que nadie
   tenga que decidir un breakpoint. */
.kpi-row {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  margin-bottom: 22px;
}
.kpi-row .card { margin-bottom: 0; }
/* Dentro de una tarjeta angosta, el hero de 52px se pisa con el título en
   dos líneas — un tamaño intermedio sigue leyéndose de un vistazo sin
   forzar el ancho mínimo de la tarjeta. */
.kpi-card .hero { font-size: 34px; }
.hero-chico { font-size: 26px; }
.kpis-compact { grid-template-columns: repeat(2, 1fr); gap: 20px; }

.chart-row { margin-bottom: 22px; }

/* Las pestañas del retorno por período. Mismo trato que `.rangos .mini` del
   gráfico de una posición, pero como texto (Semanal/Mensual/Anual) en vez de
   sigla — la tarjeta tiene lugar de sobra y una sigla ahí sería una economía
   que nadie pidió. */
.periodo-tabs {
  display: flex; gap: 4px; margin: 4px 0 14px;
}
.periodo-tabs button {
  appearance: none; cursor: pointer; background: transparent;
  border: 1px solid var(--border); border-radius: 3px;
  padding: 5px 11px; font: inherit; font-size: 11.5px; color: var(--text-secondary);
}
.periodo-tabs button[aria-selected="true"] {
  background: var(--accent); color: var(--on-accent); border-color: var(--accent);
}

.kpis {
  display: grid; gap: 30px 34px;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
}
.kpi .label {
  color: var(--muted); font-size: 10.5px; margin-bottom: 8px;
  text-transform: uppercase; letter-spacing: .12em; font-weight: 500;
}
.kpi .value { font-size: 25px; font-variant-numeric: tabular-nums; }
.kpi .sub2 { color: var(--muted); font-size: 11.5px; margin-top: 4px; }

/* --- tablas --- */

.scroll { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-variant-numeric: tabular-nums; }
th, td { padding: 12px 9px; text-align: right; white-space: nowrap; }
th:first-child, td:first-child { padding-left: 2px; }
th:last-child, td:last-child { padding-right: 2px; }
th {
  color: var(--muted); font-weight: 500; font-size: 10px;
  border-bottom: 1px solid var(--axis); text-transform: uppercase;
  letter-spacing: .12em;
}
td { border-bottom: 1px solid var(--grid); font-size: 13.5px; }
th:first-child, td:first-child { text-align: left; }
tbody tr:hover { background: var(--accent-soft); }
tfoot td {
  font-weight: 500; border-top: 1px solid var(--axis); border-bottom: 0;
  padding-top: 14px;
}
.ticker { font-weight: 500; letter-spacing: .02em; }

/* El nombre de la empresa se recorta con puntos suspensivos. Sin esto, uno
   solo largo — "Taiwan Semiconductor Manufacturing Company Limited" — estira
   la fila y empuja las columnas de la derecha fuera de la tarjeta. El nombre
   completo sigue estando en el title. */
.asset .dim {
  display: inline-block; max-width: 20ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  vertical-align: bottom;
}
.dim { color: var(--muted); font-weight: 400; }

.pos { color: var(--good); }
.neg { color: var(--critical); }

/* --- logo del ticker --- */

.asset { display: flex; align-items: center; gap: 9px; }
.logo {
  width: 22px; height: 22px; border-radius: 3px; flex: none;
  object-fit: contain; background: var(--surface-1);
  border: 1px solid var(--border);
}
.logo-fallback {
  width: 22px; height: 22px; border-radius: 3px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 9.5px; font-weight: 500; letter-spacing: -0.02em;
  background: var(--accent-soft); color: var(--accent-strong);
  border: 1px solid var(--border);
}
/* Letras, bonos y fondos: no existe logo que buscar, va el icono de la clase. */
.logo-icon svg { width: 13px; height: 13px; stroke-linecap: round;
                 stroke-linejoin: round; }

/* Selector de broker, arriba de la zona de carga. */
.broker-pick {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 20px;
}
.broker-pick label {
  font-size: 10px; text-transform: uppercase; letter-spacing: .12em;
  color: var(--muted); font-weight: 500;
}
.broker-pick select {
  font: inherit; font-size: 13px; padding: 8px 11px; min-height: 38px;
  border: 1px solid var(--border); border-radius: 3px;
  background: var(--surface-1); color: var(--text-primary);
}
.broker-pick .dim { font-size: 11.5px; }

/* --- encabezado del resumen, con el MEP a la derecha --- */

.card-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.card-head h2 { margin: 0; }

.mep-box { text-align: right; flex: none; }
.mep-label { font-size: 11px; color: var(--muted); letter-spacing: 0.02em; }
.mep-rate {
  font-size: 17px; font-weight: 500; color: var(--text-primary);
  font-variant-numeric: tabular-nums; line-height: 1.25;
}
.mep-date { font-size: 11px; color: var(--muted); }

/* --- efectivo: un renglón por moneda, con su bandera --- */

.cash-lines { display: flex; flex-direction: column; gap: 3px; }
.cash-line { display: flex; align-items: center; gap: 7px; }
/* Ojo: no llamarla .flag. Ya existe una .flag para las insignias de
   cuarentena en Movimientos, y como está más abajo en el archivo ganaba
   ella: las banderas salían dibujadas como pastillas. */
.cur-flag {
  width: 18px; height: 12px; flex: none; border-radius: 2px;
  border: 1px solid var(--border);
}
.cash-amount {
  font-size: 19px; font-weight: 500; font-variant-numeric: tabular-nums;
}
.cash-cur { font-size: 11px; color: var(--muted); }

/* Renta cobrada dentro de la tabla de cerradas: es resultado realizado igual,
   pero de otra naturaleza, y se lee distinto sin depender sólo del color. */
tr.renta td { font-style: italic; }
tfoot tr.sub-total td {
  font-weight: 400; color: var(--text-secondary);
  border-top: 0; padding-top: 2px; padding-bottom: 2px;
}

/* --- detalle de un activo --- */

h3.sub {
  font-size: 13px; font-weight: 500; color: var(--text-secondary);
  margin: 22px 0 8px; text-transform: uppercase; letter-spacing: 0.04em;
}

/* Una fila que abre algo tiene que parecerlo, y tiene que poder recibir foco:
   el drill-down se dispara con clic y también con Enter o Espacio. */
tr.clickable { cursor: pointer; }
tr.clickable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

#d-back { margin-bottom: 12px; }
#d-movements { margin-top: 16px; }

/* Desglose del efectivo cuando hay pesos y dólares a la vez. */
.kpi-detail { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

/* "est." al lado de un precio que es el último conocido, no una cotización. */
abbr.est {
  font-size: 10px; font-weight: 500; letter-spacing: 0.02em;
  color: var(--muted); border: 0; text-decoration: none; cursor: help;
}

/* --- gráfico de precio --- */

.chart-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.rangos { display: flex; gap: 4px; }
.rangos .mini[aria-pressed="true"] {
  background: var(--accent); color: var(--on-accent); border-color: var(--accent);
}
#d-chart {
  width: 100%; height: 260px; display: block; margin-top: 4px;
  /* Sin esto el trazo se estira con el viewBox y una línea de 1px termina
     midiendo 3 en una pantalla ancha y 0,4 en el celular. */
  vector-effect: non-scaling-stroke;
}
#d-chart .linea {
  fill: none; stroke: var(--accent); stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}
#d-chart .area { fill: var(--accent-soft); stroke: none; }
#d-chart .grilla {
  stroke: var(--grid); stroke-width: 1; vector-effect: non-scaling-stroke;
}
#d-chart .guia {
  stroke: var(--axis); stroke-width: 1; vector-effect: non-scaling-stroke;
}
#d-chart .marca-eje {
  fill: var(--muted); font-size: 10px; font-family: var(--font-sans);
}
#d-chart .compra { fill: var(--text-primary); }
#d-chart .punto { fill: var(--accent); stroke: var(--surface-1); stroke-width: 2; }

/* El gráfico de evolución del Resumen es más chico y no marca compras: las
   mismas reglas de trazo, grilla y punto que el de precio de una posición
   (`#d-chart`), sin repetirlas — sólo el selector cambia. */
#resumen-chart {
  width: 100%; height: 220px; display: block; margin-top: 4px;
  vector-effect: non-scaling-stroke;
}
#resumen-chart .linea {
  fill: none; stroke: var(--accent); stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}
#resumen-chart .area { fill: var(--accent-soft); stroke: none; }
#resumen-chart .grilla {
  stroke: var(--grid); stroke-width: 1; vector-effect: non-scaling-stroke;
}
#resumen-chart .guia {
  stroke: var(--axis); stroke-width: 1; vector-effect: non-scaling-stroke;
}
#resumen-chart .marca-eje {
  fill: var(--muted); font-size: 10px; font-family: var(--font-sans);
}
#resumen-chart .punto { fill: var(--accent); stroke: var(--surface-1); stroke-width: 2; }

/* La lectura va ARRIBA del gráfico y en su propio renglón fijo: si apareciera
   flotando junto al cursor movería el layout, y si no tuviera altura reservada
   el gráfico saltaría cada vez que entra y sale el mouse. */
.chart-read {
  min-height: 22px; font-size: 12.5px; color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.chart-read strong { color: var(--text-primary); font-weight: 500; }

/* --- donut --- */

.donut-row { display: flex; gap: 20px; align-items: center; flex-wrap: wrap; }
.donut-row svg { max-width: 100%; height: auto; }

/* El nombre escrito al lado de cada porción. Es lo que saca al color de tener
   que cargar la identidad: leés la etiqueta, no emparejás un cuadradito. */
.slice-label {
  font: 11px system-ui, -apple-system, "Segoe UI", sans-serif;
  fill: var(--text-secondary);
}
.legend { display: flex; flex-direction: column; gap: 9px; min-width: 200px; flex: 1; }
.legend-item { display: flex; align-items: center; gap: 9px; font-size: 13px; }
.swatch { width: 11px; height: 11px; border-radius: 3px; flex: none; }
.legend .val {
  margin-left: auto; color: var(--text-secondary);
  font-variant-numeric: tabular-nums; font-weight: 500;
}

.heat { border-radius: 3px; }

.warn {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 3px; padding: 10px 14px; margin-bottom: 12px; font-size: 13px;
  color: var(--text-secondary);
}
.warn.alert { border-left-color: var(--critical); }
.ok-badge { color: var(--good); font-weight: 500; }

/* --- filtros de movimientos --- */

.filters {
  display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-end;
  padding-bottom: 22px; margin-bottom: 22px;
  border-bottom: 1px solid var(--grid);
}
.filters label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 10px; color: var(--muted); font-weight: 500;
  text-transform: uppercase; letter-spacing: .12em;
}
.filters input, .filters select {
  font: inherit; font-weight: 400; text-transform: none; letter-spacing: normal;
  padding: 8px 11px; min-height: 38px; font-size: 13px;
  border: 1px solid var(--border); border-radius: 3px;
  background: var(--surface-1); color: var(--text-primary);
}
.filters input:focus, .filters select:focus {
  outline: 2px solid var(--accent); outline-offset: -1px;
}
.filters .ghost { text-transform: none; letter-spacing: normal; }
.filter-summary { color: var(--muted); font-size: 12px; margin-bottom: 18px; }

/* The account column earns its place only when there is more than one account.
   With a single broker it is the same word on every row, which is noise, not
   information. The <body> carries .multi-account when the data has several. */
body:not(.multi-account) .col-account { display: none; }
.account-tag {
  font-size: 11.5px; color: var(--muted); white-space: nowrap;
}

tr.quarantined td { opacity: .55; }
.flag {
  font-size: 10.5px; font-weight: 500; padding: 1px 6px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-strong); margin-left: 6px;
  text-transform: uppercase; letter-spacing: .04em;
}
.empty { color: var(--muted); text-align: center; padding: 22px 0; }

/* --- movimientos: encabezados congelados y detalle desplegable ---
 *
 * La tabla de movimientos es la única larga de la app — 300 filas y creciendo
 * — y a la mitad ya no se sabe qué columna se está mirando. Así que scrollea
 * dentro de su propia caja, con el encabezado y la fila de totales clavados,
 * igual que un "inmovilizar paneles" de Excel.
 *
 * `.scroll` a secas no alcanza: con `overflow-x: auto` el navegador computa
 * `overflow-y: auto` también, y sin una altura máxima esa caja nunca scrollea
 * — el que scrollea es el documento, y ahí un `position: sticky` adentro no
 * tiene contra qué pegarse. La altura es lo que hace que funcione. */
.scroll.freeze { max-height: max(320px, calc(100vh - 260px)); overflow: auto; }
.scroll.freeze thead th {
  position: sticky; top: 0; z-index: 2;
  /* Opaco a propósito: las filas pasan POR DEBAJO al scrollear. */
  background: var(--surface-1);
  /* La línea va de sombra y no de borde. Con `border-collapse: collapse` el
     borde lo pinta la tabla, no la celda, así que una celda pegajosa se
     despega de su propio borde y la raya se queda arriba mientras el
     encabezado baja. La sombra sí viaja con la celda. */
  border-bottom: 0; box-shadow: inset 0 -1px 0 var(--axis);
}
.scroll.freeze tfoot td {
  position: sticky; bottom: 0; z-index: 2;
  background: var(--surface-1);
  border-top: 0; box-shadow: inset 0 1px 0 var(--axis);
}

/* La fila abierta se marca apenas: el detalle debajo ya se ve. */
#movements tr.open td { background: var(--accent-soft); }
tr.detail-row:hover { background: transparent; }
tr.detail-row > td { padding: 0 2px 20px; border-bottom: 1px solid var(--grid); }

.bd-grid {
  display: grid; gap: 14px 40px; text-align: left;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  background: var(--accent-soft); padding: 18px 20px; border-radius: 3px;
}
.bd-title {
  font-size: 10px; text-transform: uppercase; letter-spacing: .12em;
  color: var(--muted); margin-bottom: 10px; font-weight: 500;
}
.bd-row {
  display: flex; justify-content: space-between; gap: 20px;
  font-size: 12.5px; padding: 3px 0; white-space: normal;
}
.bd-row > span:first-child { color: var(--text-secondary); }
.bd-row > span:last-child { font-variant-numeric: tabular-nums; }
.bd-total {
  border-top: 1px solid var(--axis); margin-top: 6px; padding-top: 8px;
  font-weight: 500;
}
.bd-warn {
  margin-top: 12px; font-size: 12px; line-height: 1.6; color: var(--text-secondary);
  border-left: 2px solid var(--axis); padding-left: 12px; text-align: left;
  white-space: normal;
}
.bd code { font-size: 11.5px; color: var(--muted); }

/* ---------- carga de datos ---------- */
.dropzone {
  border: 1px dashed var(--axis); border-radius: 3px;
  padding: 44px 24px; text-align: center; cursor: pointer;
  display: flex; flex-direction: column; gap: 6px;
  transition: border-color .12s, background .12s;
}
.dropzone:hover, .dropzone:focus-visible, .dropzone.over {
  border-color: var(--ramp-4); background: var(--accent-soft); outline: none;
}
.upload-row {
  display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap;
  padding: 8px 10px; margin-top: 8px; border-radius: 3px;
  background: var(--page); font-size: 13px;
}
.upload-row.bad { background: color-mix(in srgb, var(--critical) 12%, transparent); }
.upload-name { font-weight: 500; }
.upload-kind {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--accent-strong);
}
.actions { display: flex; gap: 12px; align-items: center; margin-top: 22px; flex-wrap: wrap; }

.form-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 18px; margin: 22px 0 6px;
}
.form-grid .wide { grid-column: 1 / -1; }
.form-grid label {
  display: flex; flex-direction: column; gap: 7px;
  font-size: 10px; color: var(--muted); font-weight: 500;
  text-transform: uppercase; letter-spacing: .12em;
}
.form-grid label input, .form-grid label select {
  text-transform: none; letter-spacing: normal; font-weight: 400;
}
.form-grid input, .form-grid select {
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 3px;
  background: var(--surface-1); color: var(--text-primary);
  font: inherit; font-size: 13px;
}
.form-grid input:focus-visible, .form-grid select:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.upload-sub { flex-basis: 100%; font-size: 12px; margin-top: 4px; }
.warn-inline { color: var(--critical); }

/* Plegables. La carga manual es el camino menos frecuente, así que arranca
   cerrada; el desglose de comisiones, más raro todavía, va anidado. */
#manual-panel > summary, #m-breakdown > summary {
  cursor: pointer; list-style: none; display: flex; align-items: baseline;
  gap: 10px; flex-wrap: wrap;
}
#manual-panel > summary::-webkit-details-marker,
#m-breakdown > summary::-webkit-details-marker { display: none; }
#manual-panel > summary::before, #m-breakdown > summary::before {
  content: "▸"; color: var(--muted); font-size: 12px;
}
#manual-panel[open] > summary::before, #m-breakdown[open] > summary::before {
  content: "▾";
}
#manual-panel > summary h2 { margin: 0; }
#m-breakdown > summary {
  font-size: 12.5px; color: var(--accent-strong); font-weight: 500;
  padding: 8px 0; border-top: 1px solid var(--border);
}
#m-breakdown[open] { padding-bottom: 4px; }

.hidden-block { display: none; }

/* Selector de cuenta. Vive arriba del pie de la barra porque reencuadra toda
   la página, igual que el toggle de moneda — no es un filtro de una sección.
   Es un control segmentado, no un desplegable: con dos o tres cuentas las
   opciones entran a la vista y cambiar es un clic, no dos. */
.account-picker { display: flex; flex-direction: column; gap: 6px; padding: 0 10px; }
.picker-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); font-weight: 500;
}
.acct-toggle {
  display: flex; flex-wrap: wrap; gap: 3px; padding: 3px;
  border: 1px solid var(--border); border-radius: 3px;
  background: var(--page);
}
.acct-toggle button {
  appearance: none; border: 0; cursor: pointer; font: inherit;
  flex: 1 1 auto; min-width: 62px; min-height: 34px;
  padding: 6px 10px; border-radius: 3px;
  background: transparent; color: var(--text-secondary);
  font-size: 12.5px; font-weight: 500;
  transition: background .12s ease, color .12s ease;
}
.acct-toggle button {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.chip-logo {
  width: 15px; height: 15px; border-radius: 3px; flex: none;
  object-fit: contain; background: #fff;
}
.acct-toggle button:hover[aria-pressed="false"] { background: var(--accent-soft); }

/* Sugerencias del buscador de activos. Se apoyan sobre el formulario en vez de
   empujarlo: si los campos se movieran al tipear, perderías el que estás
   completando. */
.suggest {
  position: absolute; z-index: 5; margin-top: 2px; min-width: 240px;
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: 3px; box-shadow: 0 2px 10px rgba(20, 18, 15, .06);
  overflow: hidden; max-height: 260px; overflow-y: auto;
}
.suggest button {
  display: block; width: 100%; text-align: left; appearance: none;
  border: 0; background: transparent; cursor: pointer; font: inherit;
  font-size: 13px; padding: 8px 11px; color: var(--text-primary);
}
.suggest button:hover { background: var(--accent-soft); }
.form-grid label { position: relative; }
.acct-toggle button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Que nunca se te pase que estás viendo una parte y no el todo. Lleva el color
   de la cuenta elegida, así el chip de la barra y el aviso de arriba son
   obviamente la misma cosa. */
.account-badge {
  display: inline-block; margin-bottom: 14px;
  font-size: 12.5px; font-weight: 500;
  color: var(--on-acct); background: var(--acct-0);
  padding: 6px 12px; border-radius: 999px;
}
/* Con una cuenta a la vista, su nombre ya está en el encabezado. */
body.one-account-view .col-account { display: none; }

/* Editar y borrar sólo existen con servidor detrás; cartera.html es una foto. */
body:not(.can-edit) .col-actions { display: none; }
.col-actions { white-space: nowrap; text-align: right; }
.mini {
  font-size: 11px; padding: 2px 8px; border-radius: 3px;
  border: 1px solid var(--border); background: var(--surface-1);
  color: var(--text-secondary); cursor: pointer; text-transform: none;
  letter-spacing: normal;
}
.mini:hover { border-color: var(--accent); color: var(--accent-strong); }
.mini.danger:hover { border-color: var(--critical); color: var(--critical); }
.confirm { font-size: 11.5px; color: var(--critical); white-space: nowrap; }
.confirm .mini { margin-left: 4px; }

.editing-banner:not(:empty) {
  font-size: 12.5px; font-weight: 500; color: var(--accent-strong);
  background: var(--accent-soft); padding: 6px 10px; border-radius: 3px;
  margin-top: 12px;
}
.derived { font-size: 13px; }
#m-ticker-info, #m-derived { min-height: 18px; font-size: 12.5px; }

.ok-msg { color: var(--good); font-size: 12.5px; }
/* The engine's message names the number to fix, so it needs room to be read. */
.err-msg { color: var(--critical); font-size: 12.5px; max-width: 46ch; }

[hidden] { display: none !important; }

@media (max-width: 860px) {
  .shell { flex-direction: column; }
  .sidebar {
    width: auto; height: auto; position: static;
    border-right: 0; border-bottom: 1px solid var(--border);
    flex-direction: row; align-items: center; gap: 12px;
    padding: 12px 14px; overflow-x: auto;
  }
  #nav { flex-direction: row; gap: 4px; }
  .nav-item { white-space: nowrap; }
  .sidebar-foot { margin: 0 0 0 auto; flex-direction: row; }
  .main { padding: 18px 16px 56px; }
}

@media (max-width: 560px) {
  .hero { font-size: 34px; }
  .filters label { flex: 1 1 130px; }
}

/* Un pagador DEDUCIDO no se muestra igual que uno que vino en el archivo.
   Intervalores nombra al suyo; Cocos deja la columna vacía y hay que inferirlo
   de las tenencias y del calendario de ex-dates. El punteado dice "esto lo
   dedujimos" sin agregar ningún glifo que se caiga a la línea de abajo —que es
   lo que hacía el "?" suelto— y el motivo entero está en el title. */
.ticker.deducido {
  border-bottom: 1px dotted var(--muted);
  cursor: help;
}

/* Cuántos dólares fueron, debajo de la cifra en pesos. Acompaña, no reemplaza:
   la columna tiene un total al pie y una celda en otra moneda dejaría de sumar
   con las demás. */
.en-su-moneda {
  font-size: 11px; color: var(--muted); font-weight: 400;
  margin-top: 2px; white-space: nowrap;
}

/* --- cobros a confirmar a mano ---
 *
 * Cuando la evidencia no alcanza, el motor no elige: nombra a los candidatos y
 * se detiene. Esta tarjeta es donde eso se vuelve una pregunta contestable. */

.pendiente {
  border-top: 1px solid var(--border);
  padding: 14px 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
}
.pendiente:first-child { border-top: 0; }

.pend-que { display: flex; align-items: baseline; gap: 12px; min-width: 260px; }
.pend-fecha { font-variant-numeric: tabular-nums; }
.pend-monto { font-weight: 500; }

/* El motivo ocupa su propio renglón: es una frase larga y meterla en la misma
   línea que el importe empuja el selector fuera de la tarjeta. */
.pend-porque { flex-basis: 100%; font-size: 12px; line-height: 1.5; }

.pend-elegir { display: flex; align-items: center; gap: 8px; margin-left: auto; }
/* Ancho suficiente para que entre "TICKER — Nombre (ex fecha, daría X)"
   sin cortar el importe, que es el dato con el que se elige. */
.pend-elegir select { max-width: 58ch; }

/* Un pagador que elegiste VOS. Es el tercer estado —el archivo lo dijo, lo
   dedujimos, lo elegiste— y el más fuerte de los tres: es el único que no
   viene de un proveedor. Por eso va sólido y no punteado como el deducido. */
.ticker.confirmado {
  border-bottom: 1px solid var(--muted);
  cursor: help;
}

/* --- menú de la cuenta, arriba a la derecha --- */

.topbar {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; margin-bottom: 26px;
}
.topbar .topline { margin-bottom: 0; }

.acct-menu { position: relative; flex: none; }
.acct-menu-btn {
  appearance: none; cursor: pointer; display: flex; align-items: center;
  gap: 6px; background: var(--surface-1); border: 1px solid var(--border);
  border-radius: 999px; padding: 6px 14px; font: inherit; font-size: 12.5px;
  color: var(--text-secondary);
  transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.acct-menu-btn:hover, .acct-menu-btn[aria-expanded="true"] {
  background: var(--accent-soft); color: var(--text-primary); border-color: var(--axis);
}
.quien-nombre {
  max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.acct-caret { font-size: 10px; opacity: .7; }

/* El panel cuelga del botón, no del flujo: si empujara el layout, abrirlo
   correría todo lo de abajo un poco hacia la izquierda. */
.acct-menu-panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 20;
  min-width: 240px; background: var(--surface-1); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: var(--card-shadow, 0 8px 24px rgba(0, 0, 0, .12));
  padding: 14px; display: flex; flex-direction: column; gap: 10px;
}
.acct-menu-label {
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted);
}
.acct-menu-divider { height: 1px; background: var(--grid); margin: 2px 0; }
.acct-menu-item {
  appearance: none; cursor: pointer; text-align: left; background: transparent;
  border: 0; border-radius: 6px; padding: 8px 6px; font: inherit; font-size: 12.5px;
  color: var(--text-secondary); transition: background .14s ease, color .14s ease;
}
.acct-menu-item:hover { background: var(--accent-soft); color: var(--text-primary); }

/* El picker de tema, reusado adentro del menú: más chico que en su tarjeta
   propia original, porque acá compite por espacio con el resto del panel. */
.acct-menu-section .tema-opciones { margin-top: 10px; gap: 8px; }
.acct-menu-section .tema-opcion { min-width: 0; padding: 8px 10px; }

/* --- cambiar contraseña --- */

.cuenta-aviso {
  font-size: 12.5px; line-height: 1.6; color: var(--text-secondary);
  border-left: 2px solid var(--axis); padding: 2px 0 2px 12px; margin: 18px 0;
}
.cuenta-aviso:empty { display: none; }
.cuenta-aviso.error { border-left-color: var(--critical); color: var(--critical); }
.cuenta-aviso.ok { border-left-color: var(--good); }
#cuenta-form { margin-top: 18px; }
#cuenta-form .actions { margin-top: 18px; display: flex; gap: 10px; }

/* --- selector de tema --- */

.tema-opciones {
  display: flex; flex-wrap: wrap; gap: 14px; margin-top: 18px;
}
.tema-opcion {
  appearance: none; cursor: pointer; text-align: left;
  background: var(--surface-2, var(--surface-1)); border: 1px solid var(--border);
  border-radius: 10px; padding: 12px 16px; font: inherit; color: var(--text-primary);
  display: flex; align-items: center; gap: 12px; min-width: 168px;
  transition: border-color .14s ease, background .14s ease;
}
.tema-opcion:hover { border-color: var(--axis); }
.tema-opcion[aria-checked="true"] {
  border-color: var(--accent); background: var(--accent-soft);
}
.tema-nombre { font-size: 13px; font-weight: 500; }

/* Cada muestra pinta SU propio tema en miniatura, sin depender de cuál esté
   activo — por eso son colores literales y no `var(--algo)`: acá el punto es
   mostrar los tres a la vez, uno de ellos necesariamente distinto del que se
   está mirando en este momento. */
.tema-muestra {
  width: 34px; height: 24px; border-radius: 5px; flex: none;
  display: block; position: relative; overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}
.tema-muestra::before, .tema-muestra::after {
  content: ""; position: absolute; border-radius: 3px;
}
.tema-muestra-soft-ui {
  background: #f2f0fb;
}
.tema-muestra-soft-ui::before {
  inset: 5px 5px 5px 5px; background: #ffffff;
  box-shadow: 0 3px 6px -2px rgba(76, 68, 148, .35);
}
.tema-muestra-soft-ui::after {
  inset: 9px auto auto 9px; width: 8px; height: 8px; background: #7c6ff0;
}
.tema-muestra-fintech-dark {
  background: #060714;
}
.tema-muestra-fintech-dark::before {
  inset: 5px 5px 5px 5px; background: rgba(57, 255, 176, .12);
  box-shadow: inset 0 0 0 1px rgba(180, 190, 255, .3);
}
.tema-muestra-fintech-dark::after {
  inset: 9px auto auto 9px; width: 8px; height: 8px; background: #39ffb0;
  box-shadow: 0 0 6px 1px rgba(57, 255, 176, .7);
}
.tema-muestra-trading-pro {
  background: #050912;
}
.tema-muestra-trading-pro::before {
  inset: 5px 5px 5px 5px; background: #0a0f1c;
  box-shadow: inset 0 0 0 1px rgba(233, 237, 247, .18);
}
.tema-muestra-trading-pro::after {
  inset: 9px auto auto 9px; width: 8px; height: 8px; background: #00e6a0;
}
