:root {
  --bg-1: #F5F1E8;
  --bg-2: #EDE5D3;
  --card: #FAF6ED;
  --border: #E8DFD0;
  --grid: #D4C9B0;
  --ink: #2A2520;
  --ink-2: #3A3028;
  --muted: #8B7355;
  --muted-2: #6B5B4A;
  --accent: #D4A24C;
  --red: #C8553D;
  --red-2: #8B4A3F;
  --green: #6B8E4E;
  --green-2: #9BBE7C;
  --purple: #8E5A9E;
  --purple-2: #D9A8E8;
  --blue: #4A6B8A;
  --blue-2: #88A8C4;
  --orange: #E8A07C;
  --tooltip-bg: #2A2520;
  --tooltip-text: #F5F1E8;
  --on-dark-bg: #2A2520;
  --on-dark-text: #F5F1E8;
}

/* Dark mode */
[data-theme="dark"] {
  --bg-1: #1A1714;
  --bg-2: #14110F;
  --card: #221E1A;
  --border: #2F2A24;
  --grid: #3A332B;
  --ink: #EFE7D6;
  --ink-2: #DDD3BE;
  --muted: #948775;
  --muted-2: #B5A892;
  --accent: #E8B765;
  --red: #E07560;
  --red-2: #C8553D;
  --green: #8FAE6E;
  --green-2: #B5D095;
  --purple: #B07AC0;
  --purple-2: #D9A8E8;
  --blue: #6F92B5;
  --blue-2: #A8C4DC;
  --orange: #F2B589;
  --tooltip-bg: #EFE7D6;
  --tooltip-text: #1A1714;
  --on-dark-bg: #0F0D0B;
  --on-dark-text: #EFE7D6;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: 'Inter', system-ui, sans-serif;
  background: var(--bg-1);
  min-height: 100vh;
  /* Padding lateral generoso: 40px lateral da respiro sin ser excesivo.
     Padding vertical 40px arriba, 40px abajo. */
  padding: 40px 40px;
  color: var(--ink);
}
.container {
  /* Ancho máximo generoso para aprovechar pantallas anchas. Antes era 1200px
     lo cual dejaba mucho espacio vacío en los costados en monitores grandes.
     1800px da lugar a que grids y tablas usen más columnas cuando hay
     espacio, y en pantallas más chicas el max-width no aplica (el ancho lo
     controla el padding del body). */
  max-width: 1800px;
  margin: 0 auto;
}
.mono { font-family: 'JetBrains Mono', monospace; }
.display-font { font-family: 'Fraunces', serif; }

header {
  margin-bottom: 32px;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
  flex-wrap: wrap;
}
header {
  margin-bottom: 16px;
}
header .title-block {
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-items: flex-start;
}
header .brand-block {
  display: flex;
  align-items: center;
  gap: 12px;
  /* Igualar la altura aproximada del h1 para que el logo quede centrado verticalmente con el título */
  min-height: 64px;
}
header .brand-logo {
  width: 56px;
  height: 56px;
  border-radius: 12px;
  box-shadow: 0 1px 4px rgba(42, 37, 32, 0.10);
}
header .brand-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
header .brand-name {
  font-family: 'Fraunces', serif;
  font-size: 26px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.02em;
  line-height: 1;
}
header .brand-tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: var(--muted-2);
}
header .eyebrow {
  display: flex; align-items: baseline; gap: 12px;
  flex-wrap: wrap;
}
header .eyebrow-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 2px; color: var(--red-2);
  text-transform: uppercase;
}
header .eyebrow-period {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: #A09080;
}
header .eyebrow-sep {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: #A09080;
}
header .eyebrow-sources {
  font-size: 13px; color: var(--muted);
}
header h1 {
  font-family: 'Fraunces', serif;
  font-size: clamp(36px, 5vw, 56px);
  font-weight: 300; line-height: 1.05; letter-spacing: -0.02em;
  margin: 0; font-style: italic;
}
header h1 strong { font-weight: 700; font-style: normal; }

/* Ocultar el footer visualmente sin removerlo del DOM. Los elementos
   internos (#periodLabel, #sourcesLabel) siguen existiendo para que el
   JS pueda escribir en ellos sin errores — si se elimina físicamente,
   varias funciones del render fallan silenciosamente y rompen cascadas
   posteriores (por ejemplo el bind del botón de conectar Drive). */
footer {
  display: none !important;
}

footer .eyebrow {
  display: flex; align-items: baseline; gap: 12px;
  flex-wrap: wrap;
}
footer .eyebrow-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 2px; color: var(--red-2);
  text-transform: uppercase;
}
footer .eyebrow-period {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: #A09080;
}
footer .eyebrow-sep {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: #A09080;
}
footer .eyebrow-sources {
  font-size: 13px; color: var(--muted);
}

.controls-row {
  display: flex; justify-content: space-between;
  align-items: flex-end; gap: 20px; margin-bottom: 18px; flex-wrap: wrap;
}
.actions-row {
  display: flex; gap: 10px;
  align-items: flex-end; flex-wrap: wrap;
  margin-bottom: 12px;
  justify-content: flex-end;
}
/* Barra superior fija: header + controls + tabs siempre visibles arriba mientras
   se hace scroll del contenido de la solapa.
   - position: sticky con top:0 → queda pegada al viewport al scrollear el body
   - z-index alto para quedar sobre las .section-card y sus posibles overlays
   - Background con el gradiente del body para tapar lo que pase por detrás al
     scrollear (sino se vería transparente). Como el gradient es el mismo del
     body y el .container ocupa max-width:1200px centrado, los bordes laterales
     del viewport igual muestran el mismo gradient sin discontinuidad visual.
   - margin-top negativo para anular el padding-top del body (40px) y que el
     sticky arranque pegado al borde superior.
   - padding-top compensatorio para no perder el espacio visual arriba del h1. */
.app-top-bar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg-1);
  margin-top: -40px;
  padding-top: 40px;
  margin-bottom: 16px;
}
@media (max-width: 720px){
  .app-top-bar { margin-top: -24px; padding-top: 24px; }
}
.main-tabs {
  display: flex; gap: 0;
  border-bottom: 1px solid var(--border);
  margin-top: 8px; margin-bottom: 0;
  flex-wrap: wrap;
}
.main-tab {
  background: transparent; border: none;
  padding: 14px 22px;
  font-family: 'Inter', system-ui;
  font-size: 14px; font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  display: inline-flex; align-items: center; gap: 8px;
  transition: all 0.15s;
}
.main-tab:hover { color: var(--ink); }
.main-tab.active {
  color: var(--ink);
  border-bottom-color: var(--accent);
  font-weight: 700;
}
.main-tab-panel.hidden { display: none; }
.assets-grid {
  display: grid;
  /* Una sola columna: las 5 secciones (Reserva, Inversiones, Trading, JALM, CLM)
     se apilan verticalmente. Gap chico (10px) para que se vean claramente
     separadas pero sin desperdiciar espacio vertical entre paneles colapsados. */
  grid-template-columns: 1fr;
  gap: 10px;
  margin-bottom: 32px;
}
.asset-section { margin-bottom: 0; }  /* Tag picker modal */
.tag-picker-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 14px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  min-height: 80px;
  max-height: 50vh;
  overflow-y: auto;
}
.tag-picker-create-link {
  flex: 1 1 100%;
  margin-top: 8px;
  padding: 10px 12px;
  border-top: 1px dashed var(--border);
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted-2);
  letter-spacing: 0.3px;
}
.tag-picker-admin-link {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px dotted var(--accent);
}
.tag-picker-admin-link:hover {
  border-bottom-style: solid;
  opacity: 0.85;
}
.tag-picker-chip {
  font-family: 'Inter', system-ui;
  font-size: 12px;
  font-weight: 500;
  padding: 6px 12px;
  border-radius: 100px;
  cursor: pointer;
  border: 2px solid transparent;
  transition: all 0.15s;
  user-select: none;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.tag-picker-chip.selected {
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1);
}
.tag-picker-chip .check-icon { display: none; }
.tag-picker-chip.selected .check-icon { display: inline-flex; }
.tag-picker-chip:hover { transform: translateY(-1px); }

/* Parámetros tab */
/* Tab Reglas (Administración) */
.rules-add-form {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.rule-add-row {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  flex-wrap: wrap;
}
.rule-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.rule-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted-2);
  text-transform: uppercase;
}
.rule-tags-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  min-height: 36px;
  padding: 4px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 6px;
}
/* Variante "en línea" cuando el picker está en una fila con otros fields.
   Necesita scroll vertical interno si hay muchas etiquetas, para no estirar
   la fila completa. Las etiquetas wrap como siempre pero el contenedor tiene
   un max-height razonable. */
.rule-tags-picker-inline {
  max-height: 80px;
  overflow-y: auto;
  align-items: flex-start;
  align-content: flex-start;
}
.rule-tags-picker .tag-picker-empty {
  font-family: 'Inter', system-ui;
  font-size: 11px;
  color: var(--muted);
  font-style: italic;
  padding: 2px 8px;
}
.rule-row-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 4px;
  grid-column: 3 / span 2;
}
.rule-row-tag-chip {
  font-family: 'Inter', system-ui;
  font-size: 10px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 100px;
  white-space: nowrap;
}
.rules-list-header {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted-2);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.rules-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* Crece naturalmente según el contenido. El scroll lo maneja el contenedor
     padre del modal (el body del cat-modal ya es scrolleable). Antes tenía
     flex:1 + overflow-y:auto que dependía de que todos los ancestros tuvieran
     flex layout — cuando algún ancestro no lo era, el scroll interno no
     aparecía y las reglas quedaban visualmente cortadas. */
  padding-right: 4px;
}
.rule-row {
  display: grid;
  grid-template-columns: 24px 120px 1fr 1fr 110px 28px 28px 28px 28px;
  /* Filas explícitas: primera fila para el contenido principal, segunda fila
     opcional para los chips de tags. */
  grid-template-rows: auto auto;
  gap: 6px 10px;
  /* align-items: start es importante cuando hay 2 filas (chip JALM/CLM abajo).
     Con `center` el contenido principal se centraba respecto a la altura total
     del row (incluyendo la fila del chip), creando un offset visual. */
  align-items: start;
  padding: 10px 12px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 12px;
}
/* Los controles (botones, enabler, etc) solo viven en la primera fila —
   forzamos grid-row: 1 para que no se "centren" verticalmente respecto a la
   altura total del row (con o sin tags) y queden alineados consistentemente.
   align-self: center dentro de la fila 1 para que botones y texto queden
   verticalmente alineados al medio dentro de su propia fila. */
.rule-row > * { grid-row: 1; align-self: center; }
.rule-row > .rule-row-tags { grid-row: 2; align-self: start; }
.rule-row.disabled {
  opacity: 0.45;
}
.rule-row-enabler {
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.rule-row-mt {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.5px;
  color: var(--muted-2);
  text-transform: uppercase;
}
.rule-row-pattern {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rule-row-cat {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px;
  color: var(--ink);
}
.rule-row-peri {
  font-size: 11px;
  color: var(--muted-2);
}
.rule-row-action {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--muted);
  transition: all 0.15s;
}
.rule-row-action:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.rule-row-action.danger:hover {
  border-color: var(--red);
  color: var(--red);
}
.rules-empty {
  padding: 30px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 12px;
  font-style: italic;
}

.params-list {
  display: flex; flex-direction: column; gap: 14px;
  flex: 1 1 auto;
  overflow-y: auto;
}
.param-row {
  display: flex; justify-content: space-between; align-items: center;
  gap: 20px;
  padding: 16px 18px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.param-info { flex: 1 1 auto; }
.param-label {
  font-family: 'Fraunces', serif;
  font-size: 16px; font-weight: 600;
  color: var(--ink); margin-bottom: 4px;
}
.param-desc {
  font-size: 12px; color: var(--muted-2); line-height: 1.4;
}
.param-input-wrap {
  display: inline-flex; align-items: center;
  background: var(--card);
  border: 1px solid var(--grid);
  border-radius: 8px;
  padding: 0 12px;
  transition: border-color 0.15s;
  flex-shrink: 0;
  /* Ancho fijo del wrap para que todos los inputs de Parámetros (con o sin
     prefix/suffix de distinto largo) tengan el mismo ancho visual. */
  width: 220px;
  box-sizing: border-box;
}
/* Si el wrap contiene un toggle (no un input de texto/select), el chrome
   visual del wrap (fondo + borde + padding + ancho fijo) sobra y queda como
   un óvalo gris alrededor del toggle. Lo dejamos transparente y alineado
   a la derecha. */
.param-input-wrap:has(> .config-toggle) {
  background: transparent;
  border: none;
  padding: 0;
  width: auto;
  justify-content: flex-end;
}
.param-input-wrap:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(212,162,76,0.15);
}
.param-prefix {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px; color: var(--muted);
  margin-right: 4px;
}
.param-suffix {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px; color: var(--muted);
  margin-left: 4px;
}
.param-input-wrap input {
  background: transparent; border: none; outline: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px; color: var(--ink);
  padding: 10px 4px;
  flex: 1 1 auto;
  min-width: 0;
  text-align: right;
}
.param-input-wrap input.modified { color: var(--accent); }
/* Reserva: bloque vertical compacto en Parámetros */
.param-row.param-row-vertical {
  flex-direction: column;
  align-items: stretch;
}
.param-row-vertical .param-info { width: 100%; }
.reserva-controls {
  display: flex; flex-direction: column; gap: 12px;
  margin-top: 14px;
  width: 100%;
}
.reserva-mode-toggle {
  display: flex; gap: 6px;
  background: rgba(42,37,32,0.06);
  padding: 4px;
  border-radius: 8px;
  width: fit-content;
}
.reserva-mode-btn {
  background: transparent; border: none;
  padding: 7px 14px; border-radius: 6px;
  font-size: 12px; font-family: 'Inter', sans-serif;
  color: var(--ink); cursor: pointer;
  transition: all 0.15s;
}
.reserva-mode-btn:hover { background: rgba(42,37,32,0.04); }
.reserva-mode-btn.active {
  background: linear-gradient(135deg, var(--blue) 0%, #2F4659 100%);
  color: #F5F1E8;
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(74, 107, 138, 0.25);
}
[data-theme="dark"] .reserva-mode-btn.active {
  background: linear-gradient(135deg, var(--blue) 0%, #2F4659 100%);
  color: #F5F1E8;
}
.reserva-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 14px;
}
.reserva-field { display: flex; flex-direction: column; gap: 6px; }
.reserva-field-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 1.2px;
  color: var(--muted); text-transform: uppercase;
}
.reserva-field input,
.reserva-field input[readonly] {
  background: var(--card);
  border: 1px solid var(--grid);
  border-radius: 8px;
  padding: 9px 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px; color: var(--ink);
  outline: none;
}
.reserva-field input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(212,162,76,0.15);
}
.reserva-field input.modified { color: var(--accent); border-color: var(--accent); }
.reserva-field input[readonly] {
  background: var(--bg-1); color: var(--muted-2); cursor: default;
}
.reserva-hint {
  font-size: 11px; color: var(--muted-2); line-height: 1.4;
  background: var(--bg-1);
  border-left: 2px solid var(--accent);
  padding: 8px 12px;
  border-radius: 0 6px 6px 0;
}
/* Barra de progreso Activos > Reserva */
.reserva-progress-bar {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 100px;
  height: 10px;
  overflow: hidden;
  position: relative;
}
.reserva-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #6B8E4E 0%, #9BBE7C 100%);
  border-radius: 100px;
  transition: width 0.6s ease-out;
}
.reserva-progress-fill.over {
  background: linear-gradient(90deg, #D4A24C 0%, #E8C47C 100%);
}
.reserva-progress-meta {
  display: flex; justify-content: space-between;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; color: var(--muted); margin-top: 6px;
  letter-spacing: 0.5px;
}
/* Checks de cumplimiento mensual de la reserva */
.reserva-checks {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20px, 1fr));
  gap: 4px;
  margin-top: 8px;
}
.reserva-check {
  aspect-ratio: 1;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  transition: all 0.15s;
}
.reserva-check.done {
  background: var(--green);
  border-color: var(--green);
  color: white;
}
.reserva-check:hover {
  border-color: var(--accent);
}
.reserva-checks-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  text-align: center;
  margin-top: 4px;
  letter-spacing: 0.5px;
}
.selectors {
  display: flex; gap: 20px;
  flex-wrap: wrap; align-items: flex-end;
}
.buttons-group {
  display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap;
}
.selector-group { display: flex; flex-direction: column; }
.period-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 1.5px; color: var(--muted);
  text-transform: uppercase; margin-bottom: 6px;
}
.period-select {
  background: var(--card); border: 1px solid var(--grid);
  border-radius: 8px; padding: 10px 14px 10px 14px;
  padding-right: 36px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px; font-weight: 500; color: var(--ink);
  cursor: pointer; appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238B7355' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
  background-repeat: no-repeat; background-position: right 10px center;
  background-size: 14px; transition: all 0.2s; outline: none;
}
.period-select:hover { border-color: var(--muted); }
.period-select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(212,162,76,0.15); }
.period-select:disabled { opacity: 0.4; cursor: not-allowed; }

.upload-btn {
  background: var(--ink); color: var(--accent); border: none;
  padding: 12px 22px; border-radius: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; font-weight: 600; letter-spacing: 1.5px;
  cursor: pointer; display: inline-flex; align-items: center; gap: 8px;
  transition: all 0.2s;
}
.upload-btn:hover:not(:disabled) { background: var(--ink-2); transform: translateY(-1px); }
.upload-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.upload-btn.csv-btn {
  background: transparent; color: var(--ink); border: 1px solid var(--ink);
}
.upload-btn.csv-btn:hover:not(:disabled) {
  background: var(--ink); color: var(--accent); transform: translateY(-1px);
}
.upload-btn.csv-btn:disabled {
  opacity: 0.35; cursor: not-allowed;
}

/* Dark mode: estilo de "tarjeta inversiones" (gradiente púrpura) para botones primary */
[data-theme="dark"] .upload-btn {
  background: linear-gradient(135deg, #8E5A9E 0%, #5D3A6B 100%);
  color: #F5F1E8;
}
/* Hover en botones con fondo oscuro: gradiente azul del totalizador "Trading" */
[data-theme="dark"] .upload-btn:hover:not(:disabled) {
  background: linear-gradient(135deg, #4A6B8A 0%, #2F4659 100%);
  color: #F5F1E8;
  transform: translateY(-1px);
}
/* Outline buttons en dark: borde claro, al hover el gradiente azul */
[data-theme="dark"] .upload-btn.csv-btn {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--ink);
}
[data-theme="dark"] .upload-btn.csv-btn:hover:not(:disabled) {
  background: linear-gradient(135deg, #4A6B8A 0%, #2F4659 100%);
  color: #F5F1E8;
  border-color: #4A6B8A;
  transform: translateY(-1px);
}

.delete-btn {
  background: transparent; color: #C8553D; border: 1px solid #C8553D;
  padding: 5px 10px; border-radius: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; font-weight: 600; letter-spacing: 1.2px;
  cursor: pointer; display: inline-flex; align-items: center; gap: 5px;
  transition: all 0.2s;
}
.delete-btn:hover { background: #C8553D; color: #F5F1E8; }
#deleteScopeBtns .source-btn.active {
  background: #C8553D; color: #F5F1E8; border-color: #C8553D;
}

.modal-card.medical-modal-card {
  width: 100%;
  max-width: 1200px;
  max-height: 90vh;
  display: flex; flex-direction: column;
  overflow: hidden;
}  .medical-period {
  font-size: 11px; letter-spacing: 1.5px; color: var(--muted);
  text-transform: uppercase; margin-top: 4px;
}
.medical-vitals {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin: 8px 0 22px;
  padding: 14px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.medical-vital {
  display: flex; flex-direction: column; gap: 2px;
}
.medical-vital-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; letter-spacing: 1.3px; color: var(--muted);
  text-transform: uppercase;
}
.medical-vital-value {
  font-family: 'Fraunces', serif;
  font-size: 18px; font-weight: 600;
}
.medical-vital-value.good { color: #6B8E4E; }
.medical-vital-value.warn { color: #D4A24C; }
.medical-vital-value.bad { color: #C8553D; }  @media (max-width: 900px){  }
.medical-section { margin-bottom: 0; }
.medical-section-title {
  display: flex; align-items: center; gap: 8px;
  font-family: 'Fraunces', serif;
  font-size: 16px; font-weight: 600;
  margin-bottom: 12px; color: var(--ink);
  padding: 4px 0 10px 0;
  border-bottom: 1px solid var(--border);
}

.medical-list {
  display: flex; flex-direction: column; gap: 10px;
}
.medical-item {
  padding: 12px 14px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-left: 3px solid var(--muted);
  border-radius: 8px;
  display: flex; gap: 12px; align-items: flex-start;
}  .medical-item.severity-mid { border-left-color: #8B7355; background: var(--bg-1); }
/* Dark mode: usar gradiente Trading (azul) para que el contenido sea legible */
[data-theme="dark"] .medical-item {
  background: linear-gradient(135deg, #4A6B8A 0%, #2F4659 100%);
  color: #F5F1E8;
  border: 1px solid #2F4659;
  border-left: 3px solid var(--muted);
}  [data-theme="dark"] .medical-item.severity-mid {
  border-left-color: #948775;
  background: linear-gradient(135deg, #4A6B8A 0%, #2F4659 100%);
}
[data-theme="dark"] .medical-item-title {
  color: #F5F1E8;
}
[data-theme="dark"] .medical-item-detail {
  color: rgba(245, 241, 232, 0.85);
}
[data-theme="dark"] .medical-item-metric {
  background: rgba(0, 0, 0, 0.25);
  border-color: rgba(245, 241, 232, 0.15);
  color: #F5F1E8;
}
.medical-item-num {
  flex-shrink: 0;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--ink); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 700;
}  .medical-item-body { flex: 1 1 auto; }
.medical-item-title {
  font-weight: 600; font-size: 14px;
  color: var(--ink); margin-bottom: 4px;
}
.medical-item-detail {
  font-size: 12px; color: var(--muted-2); line-height: 1.5;
}
.medical-item-metric {
  display: inline-block;
  margin-top: 6px;
  padding: 3px 8px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--ink);
}

.medical-empty {
  padding: 30px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
  background: var(--bg-1);
  border: 1px dashed var(--border);
  border-radius: 8px;
}
.medical-empty.good { color: #6B8E4E; background: #E4F2DC; border-color: #9BBE7C; }

.medical-tab-content {
  flex: 1 1 auto;
  overflow-y: auto;
  margin-bottom: 16px;
  min-height: 0;
}
.medical-tab-panel.hidden { display: none; }

/* ==== Presupuesto modal ==== */
.modal-card.budget-modal-card {
  width: 100%;
  max-width: 1200px;
  max-height: 90vh;
  display: flex; flex-direction: column;
  overflow: hidden;
}

.budget-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px;
  padding: 14px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 16px;
}
.budget-summary-item {
  display: flex; flex-direction: column; gap: 2px;
}
.budget-summary-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; letter-spacing: 1.3px; color: var(--muted);
  text-transform: uppercase;
}
.budget-summary-value {
  font-family: 'Fraunces', serif;
  font-size: 16px; font-weight: 600;
}
.budget-summary-value.good { color: #6B8E4E; }
.budget-summary-value.warn { color: #D4A24C; }
.budget-summary-value.bad { color: #C8553D; }

.budget-edit-list {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-1);
  overflow: hidden;
  flex: 1 1 auto;
  overflow-y: auto;
  max-height: 55vh;
}
.budget-group-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 14px;
  background: var(--on-dark-bg);
  color: var(--accent);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 1.5px; text-transform: uppercase;
  position: sticky; top: 0; z-index: 1;
}
.budget-group-total {
  font-weight: 600;
}
.budget-row {
  display: grid;
  grid-template-columns: 28px 1fr 130px 130px 90px;
  align-items: center;
  gap: 12px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--border);
}
.budget-row:last-child { border-bottom: none; }
.budget-row:hover { background: rgba(200,85,61,0.04); }
.b-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 5px;
  flex-shrink: 0;
}
.budget-row .b-icon {
  width: 24px; height: 24px; border-radius: 5px;
  display: flex; align-items: center; justify-content: center;
}
.budget-row .b-name { font-size: 13px; font-weight: 500; }
.budget-row .b-real {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--muted);
  text-align: right;
}
.budget-row .b-input {
  background: var(--card);
  border: 1px solid var(--grid);
  border-radius: 6px;
  padding: 6px 9px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; color: var(--ink);
  text-align: right;
  width: 100%;
  outline: none;
}
.budget-row .b-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(212,162,76,0.15);
}
.budget-row .b-input.modified {
  border-color: var(--accent); background: #FAF3E4;
}
.budget-row .b-diff {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-align: right;
}
.budget-row .b-diff.over { color: #C8553D; }
.budget-row .b-diff.under { color: #6B8E4E; }

.budget-annual-wrap {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-1);
  overflow-x: auto;
  overflow-y: visible;
  flex: 0 0 auto;
  /* Ocultar el scrollbar horizontal (mantiene scrollable via wheel/trackpad) */
  scrollbar-width: none; /* Firefox */
}
.budget-annual-wrap::-webkit-scrollbar {
  height: 0; /* Chrome/Safari */
  display: none;
}
.budget-annual-section-title {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--red-2);
  font-weight: 600;
  margin: 18px 0 8px 2px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.budget-annual-section-title:first-child { margin-top: 0; }
.budget-annual-section-title .count {
  font-size: 10px;
  color: var(--muted);
  font-weight: 400;
  letter-spacing: 0.5px;
  text-transform: none;
}
.budget-annual-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
  /* table-layout: fixed para que las 4 grillas (Sistema/Básicas/Discrec/Total) tengan
     columnas con anchos idénticos. Cat: 140px fijo · 12 meses + Total con flex-grow uniforme. */
  table-layout: fixed;
}
.budget-annual-table th {
  position: sticky; top: 0;
  background: var(--on-dark-bg);
  color: var(--on-dark-text);
  padding: 8px 5px;
  text-align: right;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 500;
  letter-spacing: 0.5px;
  font-size: 10px;
  z-index: 2;
  /* Cada columna mensual + total: ancho uniforme calculado vs total - cat (140px) / 13 cols */
  width: calc((100% - 140px) / 13);
}
.budget-annual-table th.cat-col {
  text-align: left;
  width: 140px;
  min-width: 140px;
  max-width: 140px;
  position: sticky; left: 0;
  z-index: 3;
}
.budget-annual-table th:last-child {
  background: #3A3028;
  color: var(--accent);
}
.budget-annual-table td {
  padding: 11px 5px;
  border-bottom: 1px solid var(--border);
  font-family: 'JetBrains Mono', monospace;
  text-align: right;
  white-space: nowrap;
  vertical-align: middle;
  font-size: 11px;
}
.budget-annual-table td.cat-col {
  text-align: left;
  background: var(--bg-1);
  position: sticky; left: 0;
  z-index: 1;
  font-family: 'Inter', system-ui;
  font-size: 12px;
  font-weight: 500;
  vertical-align: middle;
  width: 140px;
  min-width: 140px;
  max-width: 140px;
  white-space: normal;
}
.budget-annual-table td.cat-col .cat-col-content {
  display: flex; align-items: center; gap: 7px;
  line-height: 1.2;
}
.budget-annual-table td.cat-col.cat-col-clickable {
  cursor: pointer;
  transition: background 0.15s;
}
.budget-annual-table td.cat-col.cat-col-clickable:hover {
  background: rgba(212, 162, 76, 0.10);
}
/* Modal de presupuesto anual por categoría */
.cat-budget-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px 16px;
  max-height: 60vh;
  overflow-y: auto;
}
.cat-budget-row {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 12px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}
.cat-budget-row:last-child { border-bottom: none; }
.cat-budget-month {
  font-size: 12px;
  color: var(--muted-2);
  font-family: 'JetBrains Mono', monospace;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.cat-budget-cell {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
}
.cat-budget-real-top {
  font-size: 10px;
  color: var(--green);
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: 0.5px;
  padding-left: 9px;
}
.cat-budget-input {
  height: 36px;
  background: var(--bg-1);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  text-align: right;
  width: 100%;
  box-sizing: border-box;
}
.cat-budget-input:focus {
  border-color: var(--accent);
  outline: none;
}
.cat-budget-input.modified {
  background: rgba(212, 162, 76, 0.18);
  border-color: var(--accent);
}
.cat-budget-totals {
  margin-top: 14px;
  padding: 14px 16px;
  background: rgba(212, 162, 76, 0.10);
  border: 1px solid rgba(212, 162, 76, 0.30);
  border-radius: 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.cat-budget-totals .label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 1.2px;
  color: var(--muted-2);
  text-transform: uppercase;
}
.cat-budget-totals .value {
  font-family: 'Fraunces', serif;
  font-size: 20px;
  font-weight: 600;
  color: var(--accent);
}
@media (max-width: 720px){
  .cat-budget-grid { grid-template-columns: 1fr; }
}
.budget-annual-table td.cat-col .cat-col-content > span:last-child {
  /* Permitir hasta 2 líneas para nombres largos como "Suscripciones digitales" */
  word-break: break-word;
  overflow-wrap: anywhere;
  hyphens: auto;
}
.budget-annual-table td.cat-col .cat-col-content.clickable {
  cursor: pointer;
  transition: color 0.15s;
}
.budget-annual-table td.cat-col .cat-col-content.clickable:hover {
  color: var(--accent);
}
/* Modal: editor mensual de presupuesto por categoría */
.cat-budget-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
@media (max-width: 700px){
  .cat-budget-grid { grid-template-columns: repeat(2, 1fr); }
}
    .cat-budget-totals {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 16px;
  padding: 12px 14px;
  background: #FAF3E4;
  border: 1px solid var(--accent);
  border-radius: 8px;
}
[data-theme="dark"] .cat-budget-totals {
  background: #3A3028;
}
.cat-budget-totals .label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #8B6A2A;
}
[data-theme="dark"] .cat-budget-totals .label {
  color: var(--accent);
}
.cat-budget-totals .value {
  font-family: 'Fraunces', serif;
  font-size: 20px;
  font-weight: 600;
  color: var(--ink);
}
.budget-annual-table td.cell-dual {
  padding: 4px 6px;
  line-height: 1.25;
}
.budget-annual-table td .cell-budget {
  display: block;
  color: var(--red);
  font-size: 11px;
}
.budget-annual-table td .cell-real {
  display: block;
  color: var(--green);
  font-size: 11px;
}
.budget-annual-table td .cell-empty {
  display: block;
  color: var(--muted);
  opacity: 0.45;
}
.budget-annual-table td.total {
  background: #FAF3E4;
  color: var(--ink);
  font-weight: 600;
}
/* Dark mode: estilo gradiente Trading para columna Total */
[data-theme="dark"] .budget-annual-table td.total {
  background: linear-gradient(135deg, #4A6B8A 0%, #2F4659 100%);
  color: #F5F1E8;
}
/* Header de la columna Total también con el estilo Trading en dark */
[data-theme="dark"] .budget-annual-table th:last-child {
  background: linear-gradient(135deg, #4A6B8A 0%, #2F4659 100%);
  color: #F5F1E8;
}
.budget-annual-table tr.section-row td {
  background: var(--card);
  color: var(--red-2);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  padding: 8px 10px;
  text-align: left;
  font-weight: 600;
}
.budget-annual-table tr.totals-row td {
  background: var(--on-dark-bg);
  color: var(--accent);
  font-weight: 600;
  border-bottom: none;
}
.budget-annual-table tr.totals-row td.cat-col {
  background: var(--on-dark-bg);
  color: var(--accent);
}  .budget-annual-table tr.subtotal-row td {
  background: #FAF3E4;
  color: #8B6A2A;
  font-weight: 600;
  border-top: 2px solid #D4A24C;
  border-bottom: 2px solid #D4A24C;
}
.budget-annual-table tr.subtotal-row td.cat-col {
  background: #FAF3E4;
  color: #8B6A2A;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
[data-theme="dark"] .budget-annual-table tr.subtotal-row td {
  background: #3A3028;
  color: var(--accent);
  border-top: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
}
[data-theme="dark"] .budget-annual-table tr.subtotal-row td.cat-col {
  background: #3A3028;
  color: var(--accent);
}
/* Fila de variación (real - presupuesto): usa colores semánticos verde/rojo */
.budget-annual-table tr.variation-row td {
  background: rgba(0, 0, 0, 0.02);
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
}
/* Celda doble de variación: monto arriba, % abajo (wrapper interno con flex) */
.budget-annual-table td.cell-var-dual {
  text-align: right;
  padding: 6px 8px;
  vertical-align: middle;
  line-height: 1.2;
}
.budget-annual-table td.cell-var-dual .cell-var-wrap {
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-end;
}
/* Tamaño explícito y consistente del monto y % de variación */
.budget-annual-table tr.variation-row td.cell-var-dual .cell-var-amount {
  font-size: 12px;
  font-weight: 600;
  color: inherit;
  line-height: 1;
}
.budget-annual-table tr.variation-row td.cell-var-dual .cell-var-pct {
  font-size: 10px;
  font-weight: 500;
  opacity: 0.75;
  color: inherit;
  line-height: 1;
}
.budget-annual-table tr.variation-row td.cell-var-dual .cell-empty {
  font-size: 12px;
  color: var(--muted);
  opacity: 0.45;
}
.budget-annual-table td.cell-var-dual.over { color: var(--red); }
.budget-annual-table td.cell-var-dual.under { color: var(--green); }
.budget-annual-table td.cell-var-dual.neutral { color: var(--muted); }
.budget-annual-table tr.variation-row td.cat-col {
  color: var(--muted-2);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-weight: 500;
}
[data-theme="dark"] .budget-annual-table tr.variation-row td {
  background: rgba(255, 255, 255, 0.02);
}
.budget-annual-table td.cell-var {
  text-align: right;
  padding: 6px 8px;
  color: var(--muted);
  white-space: nowrap;
}
.budget-annual-table td.cell-var.over {
  color: var(--red);
}
.budget-annual-table td.cell-var.under {
  color: var(--green);
}
.budget-annual-table td.cell-var.neutral {
  color: var(--muted);
}

.step-indicator {
  display: flex; align-items: center; justify-content: center;
  gap: 8px; margin-bottom: 18px;
}
.step-dot {
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--bg-1); border: 1.5px solid var(--grid);
  color: var(--muted); font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center;
}
.step-dot.active {
  background: linear-gradient(135deg, var(--blue) 0%, #2F4659 100%);
  color: #F5F1E8;
  border-color: #2F4659;
  box-shadow: 0 2px 8px rgba(74, 107, 138, 0.25);
}
[data-theme="dark"] .step-dot.active {
  border-color: var(--blue);
}
.step-dot.done { background: var(--green); color: #F5F1E8; border-color: var(--green); }
.step-sep { width: 34px; height: 2px; background: var(--grid); }
.step-sep.done { background: var(--green); }

.step-title {
  font-family: 'Fraunces', serif;
  font-size: 16px; font-weight: 600; text-align: center;
  margin-bottom: 18px; color: var(--ink);
}

.step-list {
  margin: 8px 0 0; padding-left: 22px;
  font-size: 13px; color: var(--muted-2); line-height: 1.7;
}
.step-list li { margin-bottom: 4px; }
.step-list strong { color: var(--ink); }

.sync-status {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 100px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--muted-2);
  flex-shrink: 0;
}
.sync-status.connected { border-color: #6B8E4E; color: #3F5F2A; background: #E4F2DC; }
.sync-status.saving { border-color: #D4A24C; color: #8B6A2A; background: #FAF3E4; }
.sync-status.error { border-color: #C8553D; color: #8B2E1F; background: #FCE8E4; }
.sync-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--muted);
}
.sync-status.connected .sync-dot { background: #6B8E4E; }
.sync-status.saving .sync-dot { background: #D4A24C; animation: pulse 1s ease-in-out infinite; }
.sync-status.error .sync-dot { background: #C8553D; }
@keyframes pulse{
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

/* Recordatorios suaves de carga (banner debajo del header) */
/* Fila de badges de estado en el header: notificación de Drive + recordatorios
   de carga, uno al lado del otro. */
.status-badges-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.load-reminders-wrap {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.load-reminders-wrap.hidden { display: none; }
/* Badge pill de recordatorio, con el mismo lenguaje visual que .sync-status.
   Normal = amarillo (accent), urgente = rojo. */
.load-reminder-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 6px 5px 12px;
  border-radius: 100px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  flex-shrink: 0;
  border: 1px solid #D4A24C;
  background: #FAF3E4;
  color: #8B6A2A;
}
.load-reminder-badge.urgent {
  border-color: #C8553D;
  background: #FCE8E4;
  color: #8B2E1F;
}
[data-theme="dark"] .load-reminder-badge {
  background: rgba(212, 162, 76, 0.15);
}
[data-theme="dark"] .load-reminder-badge.urgent {
  background: rgba(200, 85, 61, 0.18);
}
.load-reminder-badge-text {
  white-space: nowrap;
}
.load-reminder-badge-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px; height: 20px;
  border: none;
  border-radius: 50%;
  background: rgba(139, 106, 42, 0.15);
  color: inherit;
  cursor: pointer;
  transition: background 0.12s;
  flex-shrink: 0;
}
.load-reminder-badge.urgent .load-reminder-badge-close {
  background: rgba(139, 46, 31, 0.15);
}
.load-reminder-badge-close:hover {
  background: rgba(200, 85, 61, 0.7);
  color: #fff;
}
/* Command palette (Cmd/Ctrl+K) y modal de atajos */
.cmd-palette-input-wrap {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-1);
}
.cmd-palette-input-wrap input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 15px;
  color: var(--ink);
  padding: 0;
}
.cmd-palette-input-wrap input::placeholder { color: var(--muted); }
.cmd-palette-hint {
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted);
  text-transform: uppercase;
  flex-shrink: 0;
}
.cmd-palette-list {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
  padding: 6px 0;
}
.cmd-palette-empty {
  padding: 36px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
  font-style: italic;
}
.cmd-palette-group-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
  padding: 10px 18px 4px;
}
.cmd-palette-item {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 9px 18px;
  cursor: pointer;
  transition: background 0.1s;
}
.cmd-palette-item:hover,
.cmd-palette-item.active {
  background: rgba(212, 162, 76, 0.10);
}
.cmd-palette-item.active {
  background: rgba(212, 162, 76, 0.16);
}
.cmd-palette-item .cmd-icon {
  color: var(--muted);
  display: flex; align-items: center; justify-content: center;
}
.cmd-palette-item.active .cmd-icon { color: var(--accent); }
.cmd-palette-item .cmd-label {
  font-size: 13px;
  color: var(--ink);
}
.cmd-palette-item .cmd-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted);
  text-transform: uppercase;
}
.cmd-palette-footer {
  display: flex;
  justify-content: center;
  gap: 18px;
  padding: 10px 14px;
  border-top: 1px solid var(--border);
  background: var(--bg-1);
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted);
}
.cmd-palette-footer kbd {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--ink);
  margin-right: 2px;
}

/* Modal de atajos */
.shortcuts-group-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
  margin-top: 8px;
  margin-bottom: 8px;
  font-weight: 600;
}
.shortcuts-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.shortcut-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 8px 12px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.shortcut-keys {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}
.shortcut-keys kbd {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 2px 7px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--ink);
  box-shadow: 0 1px 0 var(--border);
}
.shortcut-keys .kbd-os {
  font-size: 9px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-left: 2px;
  font-family: 'JetBrains Mono', monospace;
}
.shortcut-label {
  font-size: 12px;
  color: var(--muted-2);
  text-align: right;
}

/* Modal de diagnóstico del archivo */
.validation-group {
  margin-bottom: 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.validation-group-header {
  padding: 12px 14px;
  background: var(--bg-1);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  transition: background 0.15s;
}
.validation-group-header:hover {
  background: rgba(212, 162, 76, 0.06);
}
.validation-group-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  flex: 1;
}
.validation-group-title .badge {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  padding: 2px 8px;
  border-radius: 100px;
  background: var(--card);
  color: var(--muted);
  border: 1px solid var(--border);
}
.validation-group-title .badge.warn { color: #D4A24C; border-color: #D4A24C; }
.validation-group-title .badge.err { color: var(--red); border-color: var(--red); }
.validation-group-header .chevron {
  color: var(--muted);
  transition: transform 0.15s;
}
.validation-group.expanded .chevron { transform: rotate(180deg); }
.validation-group-body {
  display: none;
  border-top: 1px solid var(--border);
}
.validation-group.expanded .validation-group-body { display: block; }
.validation-issue-row {
  display: grid;
  grid-template-columns: 80px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 10px 14px;
  border-top: 1px dashed var(--border);
  font-size: 12px;
}
.validation-issue-row:first-of-type { border-top: none; }
.validation-issue-row .meta {
  font-family: 'JetBrains Mono', monospace;
  color: var(--muted);
  font-size: 11px;
}
.validation-issue-row .body { min-width: 0; }
.validation-issue-row .desc {
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.validation-issue-row .problem {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--red);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.validation-issue-row .goto-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  transition: all 0.15s;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.validation-issue-row .goto-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.validation-issue-row.no-tx {
  grid-template-columns: 1fr;
}
.validation-summary-banner {
  padding: 12px 14px;
  background: rgba(212, 162, 76, 0.10);
  border: 1px solid rgba(212, 162, 76, 0.35);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  margin-bottom: 16px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
}
.validation-summary-banner.error {
  background: rgba(200, 85, 61, 0.10);
  border-color: rgba(200, 85, 61, 0.35);
  border-left-color: var(--red);
}
.validation-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}

/* Flash de fila resaltada al "Ir al movimiento" */
.mov-row-highlight {
  animation: movRowHighlight 2.5s ease-out;
}
@keyframes movRowHighlight{
  0%, 20% { background: rgba(212, 162, 76, 0.30); }
  100% { background: transparent; }
}

/* Forecasting / proyecciones en Salud financiera */
.forecast-block {
  margin-top: 14px;
  padding: 12px 14px;
  background: rgba(74, 107, 138, 0.08);
  border-left: 3px solid var(--blue);
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
[data-theme="dark"] .forecast-block {
  background: rgba(74, 107, 138, 0.15);
}
.forecast-block .forecast-icon {
  color: var(--blue);
  flex-shrink: 0;
  margin-top: 2px;
}
.forecast-block .forecast-content { flex: 1; }
.forecast-block .forecast-title {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--blue);
  font-weight: 600;
  margin-bottom: 4px;
}
.forecast-block .forecast-text strong {
  font-weight: 600;
}
.forecast-block.warn {
  background: rgba(200, 85, 61, 0.08);
  border-left-color: var(--red);
}
[data-theme="dark"] .forecast-block.warn {
  background: rgba(200, 85, 61, 0.15);
}
.forecast-block.warn .forecast-icon,
.forecast-block.warn .forecast-title {
  color: var(--red);
}
.forecast-block.ok {
  background: rgba(107, 142, 78, 0.08);
  border-left-color: var(--green);
}
[data-theme="dark"] .forecast-block.ok {
  background: rgba(107, 142, 78, 0.15);
}
.forecast-block.ok .forecast-icon,
.forecast-block.ok .forecast-title {
  color: var(--green);
}

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px; margin-bottom: 32px;
}
@media (max-width: 900px){
  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 500px){
  .kpi-grid { grid-template-columns: 1fr; }
}
/* Sección de avisos */
.recurring-bulk-btn {
  background: transparent;
  border: 1px solid #6B8E4E;
  color: #6B8E4E;
  border-radius: 6px;
  padding: 5px 10px;
  font-size: 10px;
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: 1px;
  text-transform: uppercase;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px;
  transition: all 0.15s;
}
.recurring-bulk-btn:hover {
  background: #6B8E4E;
  color: #F5F1E8;
}
.recurring-action-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 11px;
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  color: var(--muted);
  transition: all 0.15s;
  white-space: nowrap;
}
.recurring-action-btn.primary {
  border-color: #6B8E4E;
  color: #6B8E4E;
}
.recurring-action-btn.primary:hover {
  background: #6B8E4E;
  color: #F5F1E8;
}
.recurring-action-btn.ghost:hover {
  border-color: var(--muted-2);
  color: var(--ink);
}
/* Botones de acción dentro de un medical-item (recurrentes detectados) */
.recurring-actions-row {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  flex-wrap: wrap;
}
[data-theme="dark"] .recurring-medical-item .recurring-action-btn.primary {
  border-color: #9BBE7C;
  color: #9BBE7C;
}
[data-theme="dark"] .recurring-medical-item .recurring-action-btn.primary:hover {
  background: #9BBE7C;
  color: #2A2520;
}
[data-theme="dark"] .recurring-medical-item .recurring-action-btn.ghost {
  border-color: rgba(245, 241, 232, 0.3);
  color: rgba(245, 241, 232, 0.7);
}
[data-theme="dark"] .recurring-medical-item .recurring-action-btn.ghost:hover {
  border-color: #F5F1E8;
  color: #F5F1E8;
}

/* Modo viaje (Parámetros) */
.travel-add-form {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 8px;
}
.travel-add-row {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  flex-wrap: wrap;
}
.travel-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.travel-field-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted-2);
  text-transform: uppercase;
}
.travels-list-wrap { margin-top: 18px; }
.travels-list-header {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted-2);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.travels-list { display: flex; flex-direction: column; gap: 8px; }
.travel-row {
  display: grid;
  grid-template-columns: 1fr auto auto auto auto;
  gap: 14px;
  align-items: center;
  padding: 12px 14px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13px;
}
.travel-row-info { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.travel-row-name {
  display: flex; align-items: center; gap: 8px;
  font-weight: 600;
  color: var(--ink);
}
.travel-row-name .travel-tag-chip {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  padding: 2px 7px;
  border-radius: 100px;
  text-transform: uppercase;
  color: #F5F1E8;
}
.travel-row-name .travel-status {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 100px;
  background: rgba(107, 142, 78, 0.15);
  color: #6B8E4E;
}
.travel-row-name .travel-status.finished {
  background: rgba(139, 115, 85, 0.15);
  color: var(--muted-2);
}
.travel-row-name .travel-status.future {
  background: rgba(74, 107, 138, 0.15);
  color: #4A6B8A;
}
.travel-row-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted-2);
}
.travel-row-total {
  text-align: right;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}
.travel-row-total .total-label {
  display: block;
  font-size: 9px;
  font-weight: 400;
  letter-spacing: 1px;
  color: var(--muted-2);
  text-transform: uppercase;
  margin-bottom: 2px;
}
.travel-row-delete {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--muted);
  transition: all 0.15s;
}
.travel-row-delete:hover {
  border-color: var(--red);
  color: var(--red);
}
.travel-row-edit {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--muted);
  transition: all 0.15s;
}
.travel-row-edit:hover {
  border-color: var(--accent);
  color: var(--accent);
}
/* Botón "IR A MOVIMIENTOS" — diseño igual a otros botones de acción de la fila
   pero con texto + icono y color destacado (verde, sugiriendo navegación). */
.travel-row-go {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0 12px;
  height: 30px;
  cursor: pointer;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 1.2px;
  font-weight: 600;
  font-family: 'JetBrains Mono', monospace;
  text-transform: uppercase;
  transition: all 0.15s;
}
.travel-row-go:hover {
  border-color: var(--green);
  color: var(--green);
}
.travels-empty {
  padding: 26px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 12px;
  font-style: italic;
  background: var(--bg-1);
  border: 1px dashed var(--border);
  border-radius: 8px;
}
.travel-intro {
  margin: 0 0 14px 0;
  font-size: 13px;
  color: var(--muted-2);
  line-height: 1.5;
}  .config-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
@media (max-width: 720px){
  .config-list { grid-template-columns: 1fr; }
}
.config-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 10px 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: border-color 0.15s;
}
.config-row.modified { border-color: var(--accent); }
.config-row-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.config-row-name { font-size: 13px; font-weight: 500; color: var(--ink); }
.config-row-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted-2);
  letter-spacing: 0.3px;
}
.config-toggle {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  user-select: none;
}
.config-toggle input { display: none; }
.config-toggle .track {
  position: relative;
  width: 36px; height: 20px;
  background: rgba(139, 115, 85, 0.3);
  border-radius: 100px;
  transition: background 0.2s;
}
.config-toggle .track::after {
  content: '';
  position: absolute;
  top: 2px; left: 2px;
  width: 16px; height: 16px;
  background: #F5F1E8;
  border-radius: 50%;
  transition: transform 0.2s;
}
.config-toggle input:checked + .track {
  background: var(--green);
}
.config-toggle input:checked + .track::after {
  transform: translateX(16px);
}

/* Sección oculta por preferencia del usuario (Configuración → Visualización) */
.hidden-by-pref { display: none !important; }

/* KPIs configurator */
.kpi-cfg-header {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.kpi-cfg-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}
@media (max-width: 1000px){
  .kpi-cfg-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px){
  .kpi-cfg-list { grid-template-columns: 1fr; }
}
.kpi-cfg-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 10px;
  align-items: center;
  padding: 10px 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: border-color 0.15s;
  min-width: 0;
}
.kpi-cfg-row.modified { border-color: var(--accent); }
.kpi-cfg-row.disabled { opacity: 0.6; }

/* COLUMNA 2: acciones (editar, eliminar, habilitar) en fila */
.kpi-cfg-col2 {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.kpi-cfg-icon-preview {
  width: 32px; height: 32px;
  border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.kpi-cfg-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.kpi-cfg-edit-btn,
.kpi-cfg-delete-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--muted);
  transition: all 0.15s;
}
.kpi-cfg-edit-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.kpi-cfg-delete-btn:hover {
  border-color: var(--red);
  color: var(--red);
}

/* Modal de edición de KPI */
.kpi-editor-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 14px;
}
.kpi-editor-grid .full { grid-column: 1 / -1; }
.kpi-editor-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.kpi-editor-field-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted-2);
  text-transform: uppercase;
}
.kpi-editor-field input[type="text"],
.kpi-editor-field input[type="color"],
.kpi-editor-field select {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 13px;
  color: var(--ink);
  font-family: inherit;
}
.kpi-editor-field input[type="color"] {
  padding: 4px;
  height: 38px;
}
.kpi-editor-section {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px;
  margin-bottom: 14px;
}
.kpi-editor-section-title {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
  font-weight: 600;
  margin-bottom: 10px;
}
.kpi-editor-preview {
  margin-top: 10px;
  padding: 12px;
  background: var(--card);
  border-radius: 8px;
  border: 1px solid var(--border);
}
.kpi-editor-preview-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  color: var(--muted-2);
  margin-bottom: 6px;
}

/* Icon picker trigger + grid */
.kpi-icon-picker-trigger {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 12px;
  cursor: pointer;
  font-family: inherit;
  font-size: 13px;
  color: var(--ink);
  transition: border-color 0.15s;
}
.kpi-icon-picker-trigger:hover {
  border-color: var(--accent);
}
.kpi-icon-picker-name {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--muted);
}
.kpi-icon-picker-hint {
  font-size: 11px;
  color: var(--muted-2);
  font-style: italic;
}
.kpi-icon-picker-search-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 14px;
}
.kpi-icon-picker-search-wrap input {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--ink);
  font-size: 13px;
  font-family: inherit;
  outline: none;
}
.kpi-icon-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
  gap: 6px;
  max-height: 420px;
  overflow-y: auto;
  padding: 4px;
}
.kpi-icon-cat-label {
  grid-column: 1 / -1;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
  padding: 8px 4px 4px 4px;
  border-top: 1px solid var(--border);
  margin-top: 4px;
}
.kpi-icon-cat-label:first-child {
  border-top: none;
  margin-top: 0;
  padding-top: 0;
}
.kpi-icon-cell {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 4px 6px 4px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  transition: all 0.15s;
  color: var(--ink);
}
.kpi-icon-cell:hover {
  border-color: var(--accent);
  background: var(--card);
  transform: translateY(-1px);
}
.kpi-icon-cell.selected {
  border-color: var(--accent);
  background: rgba(212, 162, 76, 0.12);
}
.kpi-icon-cell-name {
  font-family: 'JetBrains Mono', monospace;
  font-size: 8px;
  letter-spacing: 0.3px;
  color: var(--muted-2);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.kpi-icon-empty {
  grid-column: 1 / -1;
  padding: 30px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
  font-style: italic;
}

/* Export selectivo modal */
.export-section {
  margin-bottom: 18px;
}
.export-section-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
  margin-bottom: 8px;
  font-weight: 600;
}
.export-radio-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.export-radio-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.15s;
  font-size: 13px;
}
.export-radio-row:hover {
  border-color: var(--muted-2);
}
.export-radio-row.active {
  border-color: var(--accent);
  background: rgba(212, 162, 76, 0.06);
}
.export-radio-row input[type="radio"] {
  accent-color: var(--accent);
  margin: 0;
}
.export-radio-row .opt-label { flex: 1; }
.export-radio-row .opt-hint {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted-2);
}
.export-cat-select-wrap {
  margin-top: 8px;
  padding-left: 26px;
}
.export-cat-select-wrap.hidden { display: none; }
.export-summary {
  margin-top: 14px;
  padding: 10px 12px;
  background: rgba(212, 162, 76, 0.08);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  font-size: 12px;
  color: var(--ink);
}
.export-summary strong { font-weight: 600; }

.kpi-card {
  background: var(--card); border-radius: 12px; padding: 18px;
  border: 1px solid var(--border); position: relative; overflow: hidden;
  transition: transform 0.3s;
}
.kpi-card:hover { transform: translateY(-2px); }
.kpi-card .bar { position: absolute; top: 0; left: 0; right: 0; height: 3px; }
.kpi-card .header-row {
  display: flex; justify-content: space-between;
  align-items: flex-start; margin-bottom: 10px;
}
.kpi-card .label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 1.5px; color: var(--muted);
  text-transform: uppercase;
}
.kpi-card .value {
  font-family: 'Fraunces', serif;
  font-size: 20px; font-weight: 600; letter-spacing: -0.02em;
  margin-bottom: 4px;
}
.kpi-card .hint { font-size: 11px; color: var(--muted); }

.section-card {
  background: var(--card); border-radius: 12px; padding: 24px;
  border: 1px solid var(--border); margin-bottom: 32px;
}
.section-card .section-header { margin-bottom: 16px; }
.section-card .section-title {
  font-family: 'Fraunces', serif;
  font-size: 20px; font-weight: 600; letter-spacing: -0.01em;
}
.section-card .section-subtitle {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 1.5px; color: var(--muted);
  margin-top: 4px; text-transform: uppercase;
}
.chart-wrap { position: relative; height: 320px; width: 100%; }
.chart-wrap > canvas { width: 100% !important; height: 100% !important; }
.chart-wrap.small { height: 240px; }
.chart-wrap.balance { height: 260px; }
.chart-wrap.stacked { height: 220px; }
.chart-wrap.pie { height: 340px; }
/* Para el chart de saldo MP — ocupa todo el alto de la columna 1 */
.chart-wrap.balance-fill { height: 100%; min-height: 280px; }

.balance-layout {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: 16px;
  align-items: stretch;
}
@media (max-width: 900px){
  .balance-layout { grid-template-columns: 1fr; }
}
.balance-stats-col {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.balance-stats-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  flex: 1 1 0;
}
.balance-chart-col {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.balance-chart-col .chart-wrap { flex: 1 1 auto; }

.legend {
  display: flex; gap: 14px; justify-content: center;
  margin-top: 12px; flex-wrap: wrap;
}
.legend-dot { display: flex; align-items: center; gap: 6px; }
.legend-dot .swatch { width: 10px; height: 10px; border-radius: 2px; }
.legend-dot .label { font-size: 11px; color: var(--muted-2); }

.invest-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px; margin-bottom: 24px;
}
.invest-card {
  color: var(--bg-1); padding: 22px 24px; border-radius: 10px;
}
.invest-card.purple { background: linear-gradient(135deg, var(--purple) 0%, #5D3A6B 100%); }
.invest-card.blue { background: linear-gradient(135deg, var(--blue) 0%, #2F4659 100%); }
.invest-card .invest-header {
  display: flex; align-items: center; gap: 8px; margin-bottom: 14px;
}
.invest-card .invest-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 2px;
}
.invest-card .flow-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; opacity: 0.75; margin-bottom: 4px;
}
.invest-card .flow-value {
  font-family: 'Fraunces', serif;
  font-size: 26px; font-weight: 600; line-height: 1.1; margin-bottom: 12px;
}
.invest-card .stock-row {
  display: flex; justify-content: space-between; align-items: flex-end;
  padding-top: 12px; border-top: 1px solid rgba(245,241,232,0.15);
}
.invest-card .stock-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; opacity: 0.6; margin-bottom: 2px;
}
.invest-card .stock-value {
  font-family: 'Fraunces', serif;
  font-size: 18px; font-weight: 600;
}
.invest-card .stock-tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; opacity: 0.6;
}

.position-panel {
  padding: 16px 20px; background: var(--bg-1); border-radius: 10px;
  border: 1px solid var(--border); margin-bottom: 20px;
}
.position-panel .position-header {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 10px;
}
.position-panel .position-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 2px; color: var(--muted); text-transform: uppercase;
}
.position-panel .position-value {
  font-family: 'Fraunces', serif;
  font-size: 20px; font-weight: 700; color: var(--accent);
}
.position-bar {
  display: flex; height: 10px; border-radius: 5px;
  overflow: hidden; background: var(--border);
}
.position-bar-row {
  display: flex; justify-content: space-between; margin-top: 6px;
}
.position-bar-row .mono {
  font-family: 'JetBrains Mono', monospace; font-size: 10px;
}

.stat-box {
  padding: 16px; background: var(--card); border-radius: 10px;
  border: 1px solid var(--border);
}
.stat-box .stat-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; letter-spacing: 1.5px; color: var(--muted);
  text-transform: uppercase; display: flex; align-items: center; gap: 6px;
  margin-bottom: 4px;
}
.stat-box .stat-value {
  font-family: 'Fraunces', serif;
  font-size: 18px; font-weight: 600;
}

.food-banner {
  background: linear-gradient(135deg, var(--red) 0%, var(--red-2) 100%);
  color: var(--bg-1); padding: 20px 24px; border-radius: 10px;
  margin-bottom: 24px; display: flex; justify-content: space-between;
  align-items: center; flex-wrap: wrap; gap: 12px;
}
.food-banner .food-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 2px; opacity: 0.8; margin-bottom: 6px;
}
.food-banner .food-value {
  font-family: 'Fraunces', serif;
  font-size: 32px; font-weight: 600; line-height: 1;
}  @media (max-width: 700px){ }

  
.cat-row {
  display: grid; grid-template-columns: 28px 1.3fr 1.5fr auto auto;
  align-items: center; padding: 10px 8px;
  border-bottom: 1px solid var(--border); gap: 12px;
  transition: background 0.2s;
}
.cat-row:last-of-type { border-bottom: none; }
.cat-row:hover { background: rgba(200,85,61,0.06); }
.cat-row .cat-icon {
  width: 24px; height: 24px; border-radius: 5px;
  display: flex; align-items: center; justify-content: center;
}
.cat-row .cat-name { font-weight: 500; font-size: 13px; }
.cat-row .cat-bar { background: var(--border); height: 5px; border-radius: 3px; overflow: hidden; }
.cat-row .cat-bar-fill { height: 100%; border-radius: 3px; }
.cat-row .cat-pct {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--muted);
  min-width: 40px; text-align: right;
}
.cat-row .cat-amount {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 600;
  min-width: 100px; text-align: right;
}
.cat-total-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 8px; margin-top: 8px; border-top: 2px solid var(--ink);
}
.cat-total-row .total-label {
  font-family: 'Fraunces', serif;
  font-size: 15px; font-weight: 600;
}
.cat-total-row .total-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 15px; font-weight: 700;
}

.monthly-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px; margin-top: 8px;
}
.monthly-card {
  padding: 20px; background: var(--card); border-radius: 10px;
  border: 1px solid var(--border);
}
.monthly-card .month-title {
  font-family: 'Fraunces', serif;
  font-size: 20px; font-weight: 600; margin-bottom: 12px;
  text-transform: capitalize;
}
.monthly-card .row {
  display: flex; justify-content: space-between; align-items: center; padding: 4px 0;
}
.monthly-card .row .label { font-size: 12px; color: var(--muted); }
.monthly-card .row .value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 500;
}
.monthly-card .neto-row {
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--border);
  display: flex; justify-content: space-between;
}
.monthly-card .neto-label { font-size: 12px; font-weight: 600; }
.monthly-card .neto-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px; font-weight: 700;
}
.monthly-card .neto-formula {
  font-size: 10px; color: var(--muted); margin-top: 4px; text-align: right;
}

/* Modal */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(42,37,32,0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px; z-index: 100;
}
[data-theme="dark"] .modal-overlay {
  background: rgba(0,0,0,0.78);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.modal-card {
  background: var(--card); border-radius: 14px; padding: 28px;
  max-width: 460px; width: 100%;
  box-shadow: 0 20px 50px rgba(42,37,32,0.25);
  border: 1px solid var(--border);
}
.modal-header {
  display: flex; justify-content: space-between;
  align-items: flex-start; margin-bottom: 20px;
}
.modal-header .modal-eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 2px; color: var(--red-2);
  text-transform: uppercase; margin-bottom: 6px;
}
.modal-header h2 {
  font-family: 'Fraunces', serif;
  font-size: 24px; font-weight: 600; margin: 0; letter-spacing: -0.01em;
}
.modal-close {
  background: transparent; border: none; cursor: pointer;
  color: var(--muted); padding: 4px;
}
.modal-close:disabled { opacity: 0.4; cursor: not-allowed; }

.source-btn { 
  background: var(--bg-1); border: 1px solid var(--grid);
  padding: 10px 14px; border-radius: 8px;
  font-family: 'Inter', system-ui; font-size: 12px; font-weight: 500;
  color: var(--ink); cursor: pointer; transition: all 0.15s;
}
.source-btn:hover { border-color: var(--muted); }
.source-btn.active {
  background: linear-gradient(135deg, var(--blue) 0%, #2F4659 100%);
  color: #F5F1E8;
  border-color: #2F4659;
  box-shadow: 0 2px 8px rgba(74, 107, 138, 0.25);
}
[data-theme="dark"] .source-btn.active {
  border-color: var(--blue);
}

/* Drive mode buttons: usan el estilo gradiente azul de la tarjeta Trading. */
#driveModeBtns .source-btn {
  flex: 1 1 0;
  min-width: 200px;
  padding: 14px 16px;
  border-radius: 10px;
  background: var(--bg-1);
  border: 1px solid var(--grid);
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  font-weight: 600;
  transition: all 0.2s;
}
#driveModeBtns .source-btn:hover {
  border-color: var(--muted);
  transform: translateY(-1px);
}
/* Especificidad: como la regla base #driveModeBtns .source-btn fuerza background,
   necesitamos repetir el active con la misma especificidad para que gane el azul. */
#driveModeBtns .source-btn.active {
  background: linear-gradient(135deg, var(--blue) 0%, #2F4659 100%);
  color: #F5F1E8;
  border-color: #2F4659;
  box-shadow: 0 2px 8px rgba(74, 107, 138, 0.25);
}
[data-theme="dark"] #driveModeBtns .source-btn.active {
  border-color: var(--blue);
}
.alert-box {
  padding: 12px; border-radius: 8px;
  margin-bottom: 16px; font-size: 12px;
}
.alert-box.error { background: #FCE8E4; border: 1px solid #E8A898; color: #8B2E1F; }
.alert-box.success { background: #E4F2DC; border: 1px solid var(--green-2); color: #3F5F2A; }
.alert-box strong { font-weight: 600; }

.info-box {
  padding: 14px; background: var(--bg-1); border-radius: 8px;
  border: 1px solid var(--border); margin-bottom: 20px;
}
.info-box .info-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 1.5px; color: var(--red-2);
  margin-bottom: 6px; text-transform: uppercase;
}
.info-box .info-text { font-size: 12px; color: var(--muted-2); line-height: 1.5; }

.modal-actions {
  display: flex; gap: 10px; justify-content: flex-end;
}
.btn-cancel {
  background: transparent; border: 1px solid var(--grid); color: var(--muted-2);
  padding: 10px 18px; border-radius: 8px; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 500;
}
.btn-cancel:disabled { opacity: 0.4; cursor: not-allowed; }

.modal-card.cat-modal-card {
  width: 100%;
  max-width: 1200px;
  height: 85vh;
  max-height: 85vh;
  display: flex; flex-direction: column;
  overflow: hidden;
}
/* Que el contenido del tab se expanda */
.modal-card.cat-modal-card .cat-tab-panel {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
.modal-card.cat-modal-card .cat-tab-panel.hidden {
  display: none;
}
.cat-modal-filters {
  display: flex; gap: 14px; margin-bottom: 16px; flex-wrap: wrap;
}
.cat-modal-filters input.period-select {
  background: var(--bg-1);
}

.cat-tabs {
  display: flex; gap: 4px; margin-bottom: 18px;
  border-bottom: 1px solid var(--border);
}
.cat-tab {
  background: transparent; border: none;
  padding: 10px 16px;
  font-family: 'Inter', system-ui;
  font-size: 13px; font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  display: inline-flex; align-items: center; gap: 6px;
  transition: all 0.15s;
}
.cat-tab:hover { color: var(--ink); }
.cat-tab.active {
  color: var(--ink); border-bottom-color: var(--accent);
  font-weight: 600;
}
.cat-tab-panel.hidden { display: none; }

/* Panel "Ficha médica" en Administración: scrollable porque tiene dos secciones grandes apiladas.
   Cada sección se renderiza como una "card" (estilo Reserva) con header + cuerpo. */
#catTabConfig {
  overflow-y: auto;
}
.fm-section {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  margin-bottom: 16px;
}
.fm-section:last-child { margin-bottom: 0; }
.fm-section-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}
.fm-section-icon {
  width: 28px; height: 28px;
  border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(212, 162, 76, 0.12);
  color: var(--accent);
  flex-shrink: 0;
}
.fm-section-title {
  font-family: 'Fraunces', serif;
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.fm-section-desc {
  font-size: 12px;
  color: var(--muted-2);
  line-height: 1.5;
  margin: 0 0 12px 0;
  padding-left: 38px;
}
/* Listas dentro de fm-section ya alineadas con el head/desc */
.fm-section .config-list,
.fm-section .kpi-cfg-list {
  margin-left: 38px;
}
@media (max-width: 720px){
  .fm-section-desc { padding-left: 0; }
  .fm-section .config-list,
  .fm-section .kpi-cfg-list { margin-left: 0; }
  .fm-section .kpi-cfg-header { padding-left: 0 !important; }
}

/* ===== NUEVO LAYOUT: tab "Categorías y etiquetas" =====
   Estructura por filas verticales:
     1. Descripción cats
     2. Form unificado (cat/sub/etiqueta)
     3. Master+detail de cats
     4. Descripción etiquetas
     5. Grilla de etiquetas
   La densidad de las grillas es alta (~30px de alto por fila). */

/* Form unificado para agregar cat / sub / etiqueta */
.cat-add-unified {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 16px;
  margin-bottom: 16px;
}
.cat-add-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}
.cat-add-field-type { min-width: 140px; }
.cat-add-field-class { min-width: 140px; }
.cat-add-field-name { flex: 1 1 200px; background-image: none; padding-right: 14px; }
.cat-add-field-parent { min-width: 200px; }
.cat-add-field-color { width: 40px; }
.cat-add-btn { flex-shrink: 0; }
/* =================================================================
   Modal "Aprender reglas"
   Filas con checkbox por cada patrón detectado en tus tx clasificadas manualmente
   de los últimos 3 meses. Densidad media para que entren ~10 sugerencias visibles.
   ================================================================= */
.learn-rule-row {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.12s;
}
.learn-rule-row:last-child { border-bottom: none; }
.learn-rule-row:hover { background: rgba(212, 162, 76, 0.06); }
.learn-rule-row.selected { background: rgba(212, 162, 76, 0.10); }
.learn-rule-row input[type="checkbox"] {
  width: 16px; height: 16px; cursor: pointer; accent-color: var(--accent);
}
.learn-rule-pattern {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
}
.learn-rule-meta {
  font-size: 11px;
  color: var(--muted-2);
  margin-top: 2px;
}
.learn-rule-meta strong { color: var(--ink); font-weight: 600; }
.learn-rule-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}
.learn-rules-empty {
  padding: 36px 24px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
  font-style: italic;
}

/* Hint inline al lado del nombre del label "Texto / patrón". Mantiene el mismo
   estilo monoespaciado del label pero más liviano y entre paréntesis. */
.rule-label-hint {
  font-family: 'Inter', system-ui, sans-serif;
  text-transform: none;
  letter-spacing: normal;
  font-size: 10px;
  color: var(--muted);
  font-weight: 400;
  margin-left: 6px;
}
.rule-label-hint code {
  background: rgba(212, 162, 76, 0.15);
  color: var(--accent);
  padding: 1px 5px;
  border-radius: 3px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
}
.rule-label-hint.hidden { display: none; }
.cat-add-error {
  margin-top: 8px;
  padding: 6px 10px;
  background: rgba(200, 85, 61, 0.12);
  border-left: 3px solid var(--red);
  border-radius: 4px;
  font-size: 12px;
  color: var(--red);
}

/* Layout Master / Detail.
   Altura mínima calibrada para mostrar 15 filas completas de categorías sin
   scroll. Es min-height (no height fijo) así que si hay más filas la grilla
   crece hasta donde el contenido lo necesite, y recién ahí aparece el scroll
   interno de la lista. El detail (subs) usa el mismo alto. */
.cat-md-wrap {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  min-height: 540px;
}
.cat-md-wrap.cat-md-wrap-single {
  grid-template-columns: 1fr;
  min-height: 540px;
}
.cat-md-master, .cat-md-detail {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-1);
  overflow: hidden;
}
.cat-md-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--card);
  flex-shrink: 0;
}
.cat-md-title {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
  font-weight: 600;
}
.cat-md-hint {
  font-size: 11px;
  color: var(--muted-2);
  font-style: italic;
}
.cat-md-filter {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--bg-1);
  border-radius: 6px;
  border: 1px solid var(--border);
}
.cat-md-filter-btn {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  padding: 4px 10px;
  border-radius: 4px;
  text-transform: uppercase;
  font-weight: 600;
  transition: all 0.12s;
}
.cat-md-filter-btn:hover { color: var(--ink); }
.cat-md-filter-btn.active {
  background: var(--accent);
  color: var(--accent-contrast);
}

/* Listas (master y detail) — alta densidad */
.cat-master-list, .cat-detail-list {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}
.cat-master-row, .cat-detail-row {
  display: grid;
  align-items: center;
  gap: 8px;
  padding: 4px 10px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.12s;
  min-height: 30px;
}
/* Master: solo input nombre + clasificación + botón cambiar-tipo + eliminar.
   El ID (key) ya no se muestra: lo guardamos en data-* para JS. */
.cat-master-row { grid-template-columns: 1fr 110px 28px 28px; }
/* Detail: solo nombre + clasificación + eliminar. */
.cat-detail-row { grid-template-columns: 1fr 110px 28px; cursor: default; }
.cat-master-row:last-child, .cat-detail-row:last-child { border-bottom: none; }
.cat-master-row:hover { background: rgba(212, 162, 76, 0.08); }
.cat-master-row.selected {
  background: rgba(212, 162, 76, 0.18);
  border-left: 3px solid var(--accent);
  padding-left: 7px;
}
.cat-master-row.modified, .cat-detail-row.modified { background: rgba(212, 162, 76, 0.12); }
.cat-master-row.removed, .cat-detail-row.removed {
  opacity: 0.4; text-decoration: line-through; background: rgba(200, 85, 61, 0.06);
}
/* Inputs dentro de filas — más compactos */
.cat-master-row .cat-manage-input,
.cat-detail-row .cat-manage-input {
  padding: 3px 6px;
  font-size: 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--ink);
  width: 100%;
  transition: all 0.12s;
}
.cat-master-row .cat-manage-input:focus,
.cat-detail-row .cat-manage-input:focus {
  background: var(--card);
  border-color: var(--accent);
  outline: none;
}
/* Select de clasificación */
.cat-master-row .cat-manage-select,
.cat-detail-row .cat-manage-select {
  padding: 2px 4px;
  font-size: 11px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--muted);
  cursor: pointer;
  background-image: none;
}
.cat-master-row .cat-manage-select:hover,
.cat-detail-row .cat-manage-select:hover {
  border-color: var(--border);
}
.cat-master-row .cat-manage-select:focus,
.cat-detail-row .cat-manage-select:focus {
  background: var(--card);
  border-color: var(--accent);
  outline: none;
}
/* Botones eliminar / convertir tipo */
.cat-master-row .cat-manage-delete,
.cat-detail-row .cat-manage-delete,
.cat-master-row .cat-manage-swap-type {
  width: 24px; height: 24px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.12s;
}
.cat-master-row .cat-manage-delete:hover,
.cat-detail-row .cat-manage-delete:hover {
  border-color: var(--red);
  color: var(--red);
}
.cat-master-row .cat-manage-swap-type:hover {
  border-color: var(--accent);
  color: var(--accent);
}
/* Estado vacío de detalle */
.cat-detail-empty {
  padding: 30px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 12px;
  font-style: italic;
}
/* Input nuevo (sub o etiqueta inline) deshabilitado opcional */
.cat-add-field-name:disabled, .cat-add-field-parent:disabled, .cat-add-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Override: filas de etiquetas tienen 3 columnas (nombre + color + delete) */
.cat-master-row.label-row { grid-template-columns: 1fr 40px 28px; }

/* El span con el "key" técnico se ocultó del UI por simplicidad. Por si quedó
   alguna ocurrencia escapada, la suprimimos defensivamente. */
.cat-manage-key { display: none; }

/* Etiquetas */
.label-color-input {
  width: 44px;
  height: 36px;
  padding: 2px;
  border: 1px solid var(--grid);
  border-radius: 6px;
  background: var(--card);
  cursor: pointer;
  flex: 0 0 auto;
}
.label-color-input::-webkit-color-swatch-wrapper { padding: 0; }
.label-color-input::-webkit-color-swatch { border: none; border-radius: 3px; }
.label-color-input::-moz-color-swatch { border: none; border-radius: 3px; }

.label-color-edit {
  width: 30px; height: 26px;
  padding: 1px;
  border: 1px solid var(--grid);
  border-radius: 4px;
  background: var(--card);
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}
.label-color-edit::-webkit-color-swatch-wrapper { padding: 0; }
.label-color-edit::-webkit-color-swatch { border: none; border-radius: 2px; }
.label-color-edit::-moz-color-swatch { border: none; border-radius: 2px; }
.cat-master-row.label-row { grid-template-columns: 1fr 1fr 50px 28px; }  .cat-manage-key {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--muted-2);
  padding: 5px 8px;
  background: var(--card);
  border-radius: 4px;
  border: 1px solid var(--border);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cat-manage-input {
  background: var(--card);
  border: 1px solid var(--grid);
  border-radius: 6px;
  padding: 7px 10px;
  font-family: 'Inter', system-ui;
  font-size: 13px;
  color: var(--ink);
  width: 100%;
  outline: none;
}
.cat-manage-input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(212,162,76,0.15); }
.cat-manage-input.modified { border-color: var(--accent); background: #FAF3E4; }

/* Dark mode: estilo Trading (gradiente azul) para nuevas filas e inputs modificados */
[data-theme="dark"] .cat-manage-input.modified {
  border-color: #4A6B8A;
  background: linear-gradient(135deg, #4A6B8A 0%, #2F4659 100%);
  color: #F5F1E8;
}
[data-theme="dark"] .cat-master-row.modified,
[data-theme="dark"] .cat-detail-row.modified {
  background: linear-gradient(135deg, rgba(74, 107, 138, 0.20) 0%, rgba(47, 70, 89, 0.25) 100%);
  border-left: 3px solid #4A6B8A;
  padding-left: 11px;
}
[data-theme="dark"] .cat-master-row.modified .cat-manage-key,
[data-theme="dark"] .cat-detail-row.modified .cat-manage-key {
  background: rgba(0, 0, 0, 0.3);
  color: #B5C8D9;
  border-color: #4A6B8A;
}
.cat-manage-delete {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  width: 32px; height: 32px;
  border-radius: 6px;
  cursor: pointer;
  display: inline-flex;
  align-items: center; justify-content: center;
  transition: all 0.15s;
}
.cat-manage-delete:hover {
  border-color: #C8553D; color: #C8553D; background: rgba(200,85,61,0.08);
}
.cat-manage-delete.removed-state {
  border-color: var(--green); color: var(--green);
}
.cat-manage-delete.removed-state:hover {
  background: rgba(107,142,78,0.08);
}
.cat-manage-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 12px;
}

.manual-list {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-1);
  max-height: 50vh;
  overflow-y: auto;
  /* Evitar scroll horizontal: si algún row se pasa por unos pixeles del
     ancho, cortamos en vez de mostrar la barra scroll (muy invasiva
     visualmente). Los grids fijos ya están dimensionados para caber. */
  overflow-x: hidden;
}
.manual-row {
  display: grid;
  grid-template-columns: 120px minmax(260px, 1fr) 100px 150px 30px;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  align-items: center;
}
.manual-row:last-child { border-bottom: none; }
.manual-row input,
.manual-row select {
  background: var(--card);
  border: 1px solid var(--grid);
  border-radius: 6px;
  padding: 7px 9px;
  font-family: 'Inter', system-ui;
  font-size: 12px;
  color: var(--ink);
  width: 100%;
  outline: none;
}
.manual-row input[type="date"] {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
}
.manual-row input[type="number"] {
  font-family: 'JetBrains Mono', monospace;
  text-align: right;
}
.manual-row input:focus,
.manual-row select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(212,162,76,0.15);
}
.manual-row select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238B7355' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 12px;
  padding-right: 26px;
}
.manual-row input.invalid,
.manual-row select.invalid {
  border-color: var(--red);
  background-color: rgba(200,85,61,0.06);
}
.manual-row-delete {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  width: 30px; height: 30px;
  border-radius: 6px;
  cursor: pointer;
  display: inline-flex;
  align-items: center; justify-content: center;
  transition: all 0.15s;
}
.manual-row-delete:hover {
  border-color: #C8553D; color: #C8553D; background: rgba(200,85,61,0.08);
}
@media (max-width: 700px){
  .manual-row {
    grid-template-columns: 1fr 1fr;
    gap: 6px;
  }
  .manual-row-delete { grid-column: 2; justify-self: end; }
}
.cat-movements-list {
  flex: 1 1 auto;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-1);
  min-height: 280px;
}
/* Historia clínica usa virtualización: el contenedor tiene altura fija y scroll
   interno. Las filas se renderizan en una "ventana" alrededor del viewport.
   Los spacers (top y bottom) preservan el scroll total. */
#mainMovementsList {
  height: calc(100vh - 360px);
  min-height: 400px;
  max-height: 800px;
  position: relative;
}
.mov-virt-spacer { width: 100%; flex-shrink: 0; pointer-events: none; }
.mov-virt-spacer-empty { display: none; }
.cat-movement-row {
  display: grid;
  grid-template-columns: 130px 28px 1fr 100px 200px 110px 30px 30px;
  gap: 10px;
  padding: 5px 12px;
  border-bottom: 1px solid var(--border);
  align-items: center;
  transition: background 0.15s;
}
.cat-movement-row:last-child { border-bottom: none; }
.cat-movement-row:hover { background: rgba(200, 85, 61, 0.04); }
.cat-movement-row.main-mov-row {
  /* Rebalanceo de las columnas 3 (descripción) y 5 (categoría):
     - Descripción: 1.6fr → 1.85fr con min-width 200px (gana ancho)
     - Categoría:   1fr  → 0.75fr con min-width 200px (pierde 25% del share
       pero mantiene un piso de 200px para que el texto largo siga entrando
       sin cortarse, ej. "Herramientas y Aplicaciones"). */
  grid-template-columns: 130px 28px minmax(200px, 1.85fr) 100px minmax(200px, 0.75fr) 125px 130px 36px 28px 28px;
}
/* Date input: misma altura/estilo que selects para que no rompa la grilla */
.mov-date-input {
  height: 28px;
  background: var(--bg-1);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  width: 100%;
  box-sizing: border-box;
}
.mov-date-input::-webkit-calendar-picker-indicator {
  filter: invert(0.5);
  cursor: pointer;
}
[data-theme="dark"] .mov-date-input::-webkit-calendar-picker-indicator {
  filter: invert(0.7);
}
/* Botones de acción dentro de la fila (tag, budget, delete): mismo tamaño y estilo */
.tag-picker-btn, .mov-budget-btn, .mov-delete-btn {
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  background: var(--bg-1);
  color: var(--muted);
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: all 0.15s;
  box-sizing: border-box;
  overflow: hidden;
}
.tag-picker-btn { width: 36px; }
.tag-picker-btn:hover, .mov-budget-btn:hover {
  background: var(--accent);
  color: white;
  border-color: var(--accent);
}
.mov-delete-btn:hover {
  background: var(--red);
  color: white;
  border-color: var(--red);
}
/* Si tiene chips de tags adentro, ajustar */
.tag-picker-btn .tag-chip {
  font-size: 9px;
  padding: 1px 4px;
  border-radius: 3px;
}  .inc-budget-mode-btn {
  background: transparent;
  border: none;
  padding: 7px 14px;
  border-radius: 6px;
  font-size: 12px;
  font-family: 'Inter', sans-serif;
  color: var(--ink);
  cursor: pointer;
  transition: all 0.15s;
}
.inc-budget-mode-btn:hover { background: rgba(42,37,32,0.04); }
.inc-budget-mode-btn.active {
  background: linear-gradient(135deg, var(--blue) 0%, #2F4659 100%);
  color: #F5F1E8;
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(74, 107, 138, 0.25);
}
[data-theme="dark"] .inc-budget-mode-btn.active {
  background: linear-gradient(135deg, var(--blue) 0%, #2F4659 100%);
  color: #F5F1E8;
}
.cat-movement-origen {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  color: var(--muted-2);
  text-transform: uppercase;
  padding: 3px 0;
  background: var(--bg-1);
  border-radius: 4px;
  border: 1px solid var(--border);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  cursor: help;
}
.cat-movement-row.modified { background: rgba(212, 162, 76, 0.1); }
.cat-movement-row.modified:hover { background: rgba(212, 162, 76, 0.18); }
.cat-movement-row.reserved-cat {
  background: rgba(74, 107, 138, 0.10);
  border-left: 3px solid #4A6B8A;
}
.cat-movement-row.reserved-cat:hover { background: rgba(74, 107, 138, 0.18); }
.cat-movement-row.reserved-cat.modified { background: rgba(74, 107, 138, 0.20); }
[data-theme="dark"] .cat-movement-row.reserved-cat {
  background: rgba(120, 160, 200, 0.10);
  border-left-color: #88A8C4;
}
[data-theme="dark"] .cat-movement-row.reserved-cat:hover { background: rgba(120, 160, 200, 0.18); }
.cat-movement-fecha {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--muted-2);
}  .cat-movement-desc {
  font-size: 12px; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cat-movement-monto {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 600;
  text-align: right;
}
.cat-movement-monto.negative { color: var(--red); }
.cat-movement-monto.positive { color: var(--green); }
.cat-movement-cat-select {
  background: var(--card); border: 1px solid var(--grid);
  border-radius: 6px; padding: 5px 24px 5px 8px;
  font-family: 'Inter'; font-size: 12px; color: var(--ink);
  cursor: pointer; appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238B7355' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
  background-repeat: no-repeat; background-position: right 6px center;
  background-size: 12px;
  width: 100%;
}
.cat-movement-cat-select:hover { border-color: var(--muted); }
.cat-movement-cat-select.modified {
  border-color: var(--accent); background-color: #FAF3E4;
}
/* Dark mode: usar gradiente Trading para select modificado */
[data-theme="dark"] .cat-movement-cat-select.modified {
  border-color: #4A6B8A;
  background-color: #2F4659;
  background-image: linear-gradient(135deg, #4A6B8A 0%, #2F4659 100%), url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F5F1E8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
  background-repeat: no-repeat, no-repeat;
  background-position: 0 0, right 6px center;
  background-size: 100% 100%, 12px;
  color: #F5F1E8;
}
[data-theme="dark"] .cat-movement-row.modified {
  background: linear-gradient(135deg, rgba(74, 107, 138, 0.18) 0%, rgba(47, 70, 89, 0.22) 100%);
}
[data-theme="dark"] .cat-movement-row.modified:hover {
  background: linear-gradient(135deg, rgba(74, 107, 138, 0.28) 0%, rgba(47, 70, 89, 0.32) 100%);
}
.cat-modal-footer {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border);
  gap: 12px; flex-wrap: wrap;
}
.cat-modal-status {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--muted);
}
.cat-empty-state {
  padding: 60px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}
.cat-empty-state .empty-icon { margin-bottom: 12px; opacity: 0.5; }
/* Empty state de Ficha médica (sin datos en período) */
.medical-empty-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 80px 24px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.medical-empty-icon {
  color: var(--muted);
  opacity: 0.55;
  margin-bottom: 8px;
}
.medical-empty-title {
  font-family: 'Fraunces', serif;
  font-size: 22px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.medical-empty-hint {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  color: var(--muted-2);
  max-width: 480px;
  line-height: 1.5;
}
.medical-empty-hint strong {
  color: var(--accent);
  font-weight: 600;
}
@media (max-width: 700px){
  .cat-movement-row { grid-template-columns: 80px 28px 1fr 100px 28px 28px; }
}

.hidden { display: none !important; }  @media (max-width: 900px){ }

.dist-grid {
  display: grid;
  grid-template-columns: minmax(320px, 400px) 1fr;
  gap: 32px;
  align-items: start;
}
.dist-chart-col { position: sticky; top: 20px; }
.dist-detail-col { min-width: 0; }
@media (max-width: 900px){
  .dist-grid { grid-template-columns: 1fr; gap: 24px; }
  .dist-chart-col { position: static; }
}

/* Vista compacta de las 3 distribuciones (anillos lado a lado, sin ranking) */
.dist-rings-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  gap: 24px;
  align-items: start;
}
.dist-rings-col {
  min-width: 0;
  position: relative;  /* anchor para el label superpuesto */
}
/* Wrapper del canvas — necesario para que el label sea position:absolute relativo
   al wrap y no al col entero (que podría tener otros elementos en el futuro). */
.dist-rings-chart-wrap {
  position: relative;
}
/* Label clickeable dentro del donut. Va centrado en el cutout (~55% del radio). */
.dist-rings-label {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.2px;
  color: var(--muted-2);
  text-transform: uppercase;
  text-align: center;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 8px;
  border-radius: 8px;
  transition: background 0.15s, color 0.15s;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  user-select: none;
  z-index: 2;
  /* Que el donut sea hoverable atrás del texto: cualquier click fuera del label
     sigue siendo del canvas Chart.js para tooltips */
  pointer-events: auto;
  max-width: 70%;
  line-height: 1.3;
}
.dist-rings-label:hover {
  background: rgba(212, 162, 76, 0.12);
  color: var(--ink);
}
.dist-rings-label.is-open {
  color: var(--accent);
}
.dist-rings-label .eye-icon {
  opacity: 0.7;
}
@media (max-width: 1200px){
  .dist-rings-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 700px){
  .dist-rings-grid { grid-template-columns: 1fr; gap: 32px; }
}

/* Botón "ojo" centrado en el donut de cada sección detallada de distribución.
   Click → oculta la sección (persiste en visibilityPrefs). Para volver a
   mostrarla, se usa la sección compacta o Administración → Visualización. */
.dist-detail-chart-wrap {
  position: relative;
}
.dist-detail-hide-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--muted-2);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
  z-index: 2;
  /* leve sombra para que se note sobre el fondo del card */
  box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}
.dist-detail-hide-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--card);
}

.source-btns { display: flex; flex-wrap: wrap; gap: 8px; }
.form-block { margin-bottom: 20px; }

/* Resumen (contador + totalizador) en Historia clínica, antes del botón GUARDAR.
   Alineado a la derecha con tipografía monoespaciada para que los números entren
   alineados visualmente entre sí. */
.main-mov-summary {
  display: flex;
  flex-direction: row;
  gap: 14px;
  align-items: stretch;
}
.main-mov-summary-block {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  padding: 4px 12px;
  border-left: 1px solid var(--border);
  line-height: 1.2;
}
.main-mov-summary-block:first-child { border-left: none; padding-left: 0; }
.main-mov-summary-label {
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 1px;
  font-size: 9px;
  font-family: 'JetBrains Mono', monospace;
}
.main-mov-summary-count {
  font-size: 11px;
  font-weight: 500;
  color: var(--muted-2);
}
.main-mov-summary-value {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  min-width: 80px;
  text-align: right;
}

/* Botón del ícono dentro de la tarjeta KPI — al click abre el editor del KPI.
   Damos hover sutil para indicar que es clickeable. */
.kpi-icon-btn { transition: transform 0.12s, opacity 0.12s; }
.kpi-icon-btn:hover { transform: scale(1.15); opacity: 0.85; }

/* Monto de tarjeta KPI clickeable (drill-down a Historia clínica) */
.kpi-value-drill { transition: color 0.12s, transform 0.12s; }
.kpi-value-drill:hover { color: var(--accent); transform: translateX(2px); }

/* Barra + chip del filtro de tarjeta activo en Historia clínica */
.mov-cardfilter-bar {
  display: flex;
  align-items: center;
  margin-bottom: 14px;
}
.mov-cardfilter-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px 6px 14px;
  background: rgba(212, 162, 76, 0.12);
  border: 1px solid rgba(212, 162, 76, 0.4);
  border-radius: 100px;
  font-size: 12px;
  color: var(--ink);
}
.mov-cardfilter-label {
  font-weight: 600;
  color: var(--accent);
}
.mov-cardfilter-desc {
  color: var(--muted-2);
}
.mov-cardfilter-clear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(212, 162, 76, 0.2);
  border: none;
  border-radius: 50%;
  width: 22px;
  height: 22px;
  cursor: pointer;
  color: var(--ink);
  transition: background 0.12s;
  margin-left: 2px;
}
.mov-cardfilter-clear:hover { background: var(--red); color: #fff; }

/* ===== HEALTH SCORE CARD ===== */
/* La tarjeta principal del score: número grande + label + barra de progreso
   a la izquierda; desglose de los 4 componentes a la derecha. Layout en grid
   para que en mobile se apilen verticalmente sin perder legibilidad. */
.health-score-card {
  padding: 28px 32px;
}
.health-score-grid {
  display: grid;
  /* La col izquierda ahora aloja número + meta + sparkline (220px). Necesita
     min-width considerable para no apretar. Subimos a 480px (≈ 84px del número
     + 16px gap + 130px del meta + 20px gap + 220px del sparkline + márgenes).
     Proporción: 1.2fr:1fr para darle un poco más de aire a la izquierda que
     a los componentes. */
  /* Dos columnas del mismo ancho: score visual a la izquierda, componentes
     a la derecha. Cada una ocupa aprox el ancho de una tarjeta KPI. */
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  align-items: stretch;
}
/* Columna izquierda: eyebrow arriba, value-row (número+meta), barra de
   progreso INMEDIATAMENTE debajo del número, y el sparkline al fondo
   (empujado con margin-top: auto en el sparkline). Ambos (barra y
   sparkline) ocupan el 100% del ancho de la columna, por lo tanto
   tienen el MISMO ancho. */
.health-score-main {
  display: flex;
  flex-direction: column;
}
.health-score-main .health-score-sparkline-wrap {
  margin-top: auto;
}
@media (max-width: 1024px) {
  .health-score-grid { grid-template-columns: 1fr; gap: 20px; }
}
.health-score-eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 2px;
  color: var(--muted-2);
  margin-bottom: 14px;
}
.health-score-value-row {
  display: flex;
  /* stretch para que .health-score-meta tome la altura del número y pueda
     distribuir su contenido (ícono arriba, label abajo) con space-between
     contra los bordes del número. */
  align-items: stretch;
  gap: 18px;
  margin-bottom: 16px;
}
/* El meta (ícono + label + period) ocupa la altura del número, con el ícono
   pegado al tope (alineado con la línea superior del número) y el label
   pegado al fondo (alineado con la base del número). */
.health-score-value-row .health-score-meta {
  flex: 0 0 auto;
  justify-content: space-between;
  align-items: flex-start;
  /* Línea de altura igual a la del número (84px font-size, line-height: 1) */
  min-height: 84px;
  /* No queremos que el gap interno se sume al efecto de space-between */
  gap: 0;
}
.health-score-number {
  font-family: 'Fraunces', serif;
  font-size: 84px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ink);
  /* Color dinámico inyectado inline desde JS según el rango (verde/amarillo/rojo) */
}
.health-score-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Wrapper de label + period: queda alineado al fondo del meta para que el
   label limite con la base del número (cuando .health-score-meta usa
   justify-content: space-between dentro de .health-score-value-row). */
.health-score-meta-bottom {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.health-score-label {
  font-family: 'Fraunces', serif;
  font-size: 22px;
  font-weight: 600;
  /* Color dinámico inline */
}
.health-score-period {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted-2);
  /* Texto largo (con reason): que haga wrap en lugar de empujar el layout */
  white-space: normal;
  word-break: normal;
  overflow-wrap: anywhere;
  max-width: 320px;
  line-height: 1.3;
}
.health-score-bar-wrap {
  width: 100%;
  height: 8px;
  border-radius: 100px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  overflow: hidden;
  position: relative;
  /* Pequeño espacio para separar la barra del value-row (número). */
  margin-top: 6px;
}
.health-score-bar {
  height: 100%;
  width: 0;
  border-radius: 100px;
  transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.4s;
}
/* Desglose de componentes a la derecha */
.health-score-components {
  /* Layout flex column con justify-content: center para centrar los
     componentes verticalmente. Con align-items: stretch del grid padre,
     el contenedor toma el alto completo del score; adentro los items
     ocupan su alto natural y se centran en el medio de la sección. */
  display: flex;
  flex-direction: column;
  gap: 10px;
  justify-content: center;
}
@media (max-width: 540px) {
  .health-score-components { gap: 8px; }
}
.health-score-component {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Modificador para que un componente ocupe las 2 columnas de la grilla.
   Usado por "Reservas (meses de vida)" para que no quede solo en una columna
   con un hueco al lado. */
.health-score-component-fullrow {
  grid-column: 1 / -1;
}
.health-score-component-row1 {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.health-score-component-name {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
}
.health-score-component-points {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted-2);
  flex-shrink: 0;
}
.health-score-component-row2 {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.health-score-component-value {
  font-family: 'Fraunces', serif;
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
}
.health-score-component-hint {
  font-size: 10px;
  color: var(--muted-2);
  text-align: right;
}
.health-score-component-bar-wrap {
  width: 100%;
  height: 3px;
  border-radius: 100px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  overflow: hidden;
  margin-top: 2px;
}
.health-score-component-bar {
  height: 100%;
  border-radius: 100px;
  transition: width 0.5s;
}
.health-score-card.no-data {
  text-align: center;
  padding: 20px 32px;
}
.health-score-card.no-data .health-score-number {
  font-size: 36px;
  color: var(--muted-2);
}

/* ===== HEALTH SCORE CONFIG PANEL (en Admin → Parámetros) ===== */
.health-score-config-panel,
.reserva-config-panel {
  margin-top: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0;
  background: var(--bg-1);
}
.health-score-config-panel summary,
.reserva-config-panel summary {
  padding: 12px 16px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  user-select: none;
}
.health-score-config-panel summary::-webkit-details-marker,
.reserva-config-panel summary::-webkit-details-marker { display: none; }
.health-score-config-panel summary::before,
.reserva-config-panel summary::before {
  content: '▸';
  font-family: monospace;
  color: var(--muted-2);
  transition: transform 0.15s;
}
.health-score-config-panel[open] summary::before,
.reserva-config-panel[open] summary::before { transform: rotate(90deg); }
/* Padding del contenido del panel de reserva (los controles internos
   conservan sus estilos originales .reserva-controls/.reserva-fields). */
.reserva-config-panel > .reserva-controls {
  padding: 4px 16px 16px 16px;
}
.health-score-config-grid {
  padding: 4px 16px 16px 16px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
@media (max-width: 720px) {
  .health-score-config-grid { grid-template-columns: 1fr; }
}
.health-score-config-block {
  padding: 10px 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.health-score-config-block-full { grid-column: 1 / -1; }
.health-score-config-title {
  font-size: 12px;
  font-weight: 600;
  margin-bottom: 8px;
  color: var(--ink);
}
.health-score-config-sub {
  font-weight: 400;
  font-size: 10px;
  color: var(--muted-2);
  margin-left: 4px;
}
.health-score-config-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 12px;
}
.health-score-config-fields label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--muted-2);
}
.health-score-config-fields input {
  width: 50px;
  padding: 4px 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--card);
  color: var(--ink);
  text-align: right;
}
.health-score-config-hint {
  font-size: 10px;
  color: var(--muted-2);
  margin-top: 8px;
  font-style: italic;
}
.health-score-config-actions {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 12px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
}
.health-score-config-weight-status {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted-2);
}
.health-score-config-weight-status.error { color: #C8553D; font-weight: 600; }
.health-score-config-weight-status.ok { color: #6B8E4E; }

/* ===== SPARKLINES en tarjetas KPI ===== */
/* Sparkline va en una fila adicional al pie de la tarjeta, junto al hint. La
   hint queda a la izquierda y la sparkline a la derecha. Layout flex con gap
   pequeño para no romper si el hint es largo. */
.kpi-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 4px;
}
.kpi-card-footer .hint {
  flex: 1;
  min-width: 0;
  /* Truncamos el hint si es muy largo para no empujar el sparkline */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kpi-sparkline-wrap {
  flex-shrink: 0;
  opacity: 0.85;
  transition: opacity 0.15s;
}
.kpi-sparkline-wrap:hover { opacity: 1; }
.kpi-sparkline { display: block; }

/* ===== VIEW MODE TOGGLE (Resumen / Completa) ===== */
.view-mode-toggle-row {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 14px;
}
.view-mode-toggle {
  display: inline-flex;
  gap: 0;
  padding: 3px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 100px;
}
.view-mode-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border: none;
  background: transparent;
  border-radius: 100px;
  font-family: 'Inter', system-ui;
  font-size: 12px;
  font-weight: 500;
  color: var(--muted-2);
  cursor: pointer;
  transition: all 0.15s;
}
.view-mode-btn:hover { color: var(--ink); }
.view-mode-btn.active {
  background: var(--ink);
  color: var(--card);
  font-weight: 600;
}
[data-theme="dark"] .view-mode-btn.active {
  background: var(--accent);
  color: #2A2520;
}

/* Cuando el modo es "resumen", se oculta toda sección que NO tenga la clase
   .summary-keep. Esto se aplica via attribute en medicalContentWrap. */
#medicalContentWrap[data-view-mode="resumen"] .section-card:not(.summary-keep) {
  display: none;
}
/* kpi-grid es un caso especial: no es section-card (es un grid de tarjetas),
   pero queremos poder ocultarla desde "Vista resumen". Misma lógica. */
#medicalContentWrap[data-view-mode="resumen"] .kpi-grid:not(.summary-keep) {
  display: none;
}

/* ===== EXPORT MENU (PNG / PDF) ===== */
.export-menu-wrap {
  position: relative;
  display: inline-block;
}
.export-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 180px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(42, 37, 32, 0.15);
  padding: 4px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.export-menu.hidden { display: none; }
.export-menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: transparent;
  border: none;
  border-radius: 6px;
  font-family: 'Inter', system-ui;
  font-size: 12px;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  transition: background 0.12s;
}
.export-menu-item:hover { background: var(--bg-1); }
.export-menu-item:disabled {
  opacity: 0.5;
  cursor: wait;
}

/* Modo "exportando": ocultar el top-bar y los controles flotantes para que la
   captura se vea limpia. Se aplica via body[data-exporting="true"]. */
body[data-exporting="true"] .app-top-bar {
  position: static;
  background: transparent;
}
body[data-exporting="true"] .view-mode-toggle-row,
body[data-exporting="true"] .export-menu,
body[data-exporting="true"] .kpi-icon-btn,
body[data-exporting="true"] .dist-detail-hide-btn {
  display: none !important;
}
/* En modo export anulamos el comportamiento visual de hover/drill del valor
   del KPI (cursor pointer, transformaciones), pero NO ocultamos el monto.
   El bug previo era hacer display:none sobre .kpi-value-drill, que es la clase
   aplicada al <div class="value kpi-value-drill"> que contiene el $X. */
body[data-exporting="true"] .kpi-value-drill {
  cursor: default !important;
  transform: none !important;
  color: inherit !important;
}
body[data-exporting="true"] .section-card {
  break-inside: avoid;
  page-break-inside: avoid;
}

/* Bloque "alternativo" (sin sueldo) — visualmente distinto para que se entienda
   que es una sub-sección. Borde discontinuo y fondo levemente distinto. */
.health-score-config-block-alt {
  background: var(--bg-1);
  border-style: dashed;
}
.health-score-config-alt-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
@media (max-width: 720px) {
  .health-score-config-alt-grid { grid-template-columns: 1fr; }
}
.health-score-config-alt-label {
  font-size: 11px;
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--muted);
}

/* Componente del score sin datos para calcular (ej: margen libre sin sueldo).
   Se renderiza en gris claro para indicar que existe pero no aplica. */
.health-score-component-skipped {
  opacity: 0.45;
}
.health-score-component-skipped .health-score-component-value,
.health-score-component-skipped .health-score-component-points {
  color: var(--muted-2);
  font-style: italic;
}
.health-score-component-skipped .health-score-component-bar-wrap {
  border-style: dashed;
}

/* Editor de KPI: hint pequeño debajo del label del campo (para "Coloreo de tendencia") */
.kpi-editor-field-label .kpi-editor-field-hint {
  display: block;
  font-size: 10px;
  font-weight: 400;
  color: var(--muted-2);
  margin-top: 2px;
  line-height: 1.3;
  font-style: italic;
}
/* Texto que muestra qué dirección se infirió cuando está en modo Automático */
.kpi-editor-trend-inferred {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted-2);
  margin-top: 4px;
}
.kpi-editor-trend-inferred:empty {
  display: none;
}

/* ===== TOP 3 SERIES DEBAJO DE CADA ANILLO ===== */
/* Una línea (gap pequeño) con los 3 nombres principales en el color de su
   slice. Cada item: dot del color + nombre. Layout flex con wrap por si la
   columna es muy angosta — pero apuntamos a una sola línea. */
.dist-rings-top3 {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  justify-content: center;
  margin-top: 8px;
  padding: 0 4px;
  font-family: 'Inter', system-ui;
  font-size: 11px;
  line-height: 1.2;
}
.dist-rings-top3-item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}
.dist-rings-top3-item .swatch {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  flex-shrink: 0;
}
.dist-rings-top3-item .name {
  /* El nombre va en el color del swatch */
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 90px;
}
.dist-rings-top3-item .pct {
  color: var(--muted-2);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
}

/* ===== SPARKLINE DEL SCORE ===== */
/* Va debajo de la barra de progreso, dentro de la columna izquierda. Eyebrow
   chico arriba con texto descriptivo, SVG ocupando ancho completo de la col. */
.health-score-sparkline-wrap {
  /* Ahora vive en su propia fila (fuera de value-row) — ocupa el ancho
     completo de la columna izquierda del score. */
  margin: 12px 0 0;
  width: 100%;
  max-width: none;
  text-align: left;
  align-self: auto;
  padding: 0;
}
.health-score-sparkline-eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
  margin-bottom: 4px;
  white-space: nowrap;
}
.health-score-sparkline-svg {
  /* Contenedor del SVG. El SVG es width:280 fijo en viewBox pero queremos que
     se adapte al ancho asignado por el wrap. */
  width: 100%;
  line-height: 0;
}
.health-score-sparkline-svg svg {
  width: 100%;
  /* Tiene que coincidir con la constante H de buildHealthScoreSparkline()
     (dashboard.js): el SVG usa preserveAspectRatio="none", así que si difieren
     el trazo se estira en vertical. La columna izquierda del score tiene aire
     de sobra —el wrap va con margin-top:auto, pegado abajo— así que el alto
     extra lo absorbe el hueco que quedaba vacío. */
  height: 64px;
}
.health-score-sparkline-svg:empty {
  display: none;
}
/* En mobile no hay espacio para sparkline al costado del número → vuelve abajo. */
@media (max-width: 640px) {
  .health-score-value-row { flex-wrap: wrap; }
  .health-score-sparkline-wrap {
    width: 100%;
    max-width: 100%;
    margin-left: 0;
    margin-top: 8px;
    text-align: left;
  }
}

/* ===== BOTONES "ICON-ONLY" (collapse al hover) =====
   Botones del top-bar (Tema, Drive, Administración) muestran solo el ícono
   normalmente; al pasar el mouse encima se expanden mostrando el texto.
   Aplica solo a .btn-icon-only. Transición suave en padding/max-width.
   IMPORTANTE: el SPAN interno tiene `max-width:0; overflow:hidden` y crece
   en hover, no `display:none` para que la transición sea fluida. */
.upload-btn.btn-icon-only {
  padding-left: 12px;
  padding-right: 12px;
  transition: padding 0.2s, background 0.2s, color 0.2s, transform 0.2s;
}
.upload-btn.btn-icon-only > span {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  margin-left: 0;
  transition: max-width 0.25s ease, opacity 0.2s ease, margin-left 0.25s ease;
}
.upload-btn.btn-icon-only:hover > span,
.upload-btn.btn-icon-only:focus-visible > span {
  max-width: 220px;       /* margen generoso para "CONECTAR DRIVE" */
  opacity: 1;
  margin-left: 0;
}
/* Mientras NO se hace hover, el gap entre icono y span debe colapsar también
   para que el botón quede ajustado. El gap del padre .upload-btn es 8px;
   compensamos restando lo del span. */
.upload-btn.btn-icon-only:not(:hover):not(:focus-visible) {
  gap: 0;
}

/* ===== BOTONES DE GRUPO (Flujo / Movimientos) en Evolución de KPIs ===== */
.kpi-evo-groups {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.kpi-evo-group-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 100px;
  font-family: 'Inter', system-ui;
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  transition: all 0.15s;
  user-select: none;
}
.kpi-evo-group-btn:hover { background: var(--bg-1); color: var(--ink); }
.kpi-evo-group-btn.active {
  background: var(--ink);
  color: var(--card);
  border-color: var(--ink);
}
[data-theme="dark"] .kpi-evo-group-btn.active {
  background: var(--accent);
  color: #2A2520;
  border-color: var(--accent);
}
.kpi-evo-group-btn .dot {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  flex-shrink: 0;
}
.kpi-evo-group-btn .dot-flow       { background: #6B8E4E; }   /* verde flujo */
.kpi-evo-group-btn .dot-movements  { background: #C8553D; }   /* rojo gastos */
.kpi-evo-group-btn .count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  opacity: 0.7;
  padding: 1px 6px;
  background: rgba(0,0,0,0.08);
  border-radius: 100px;
  min-width: 18px;
  text-align: center;
}
.kpi-evo-group-btn.active .count {
  background: rgba(255,255,255,0.18);
}
[data-theme="dark"] .kpi-evo-group-btn.active .count {
  background: rgba(0,0,0,0.18);
}
/* Grupo vacío: deshabilitado visualmente */
.kpi-evo-group-btn[data-empty="true"] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* Fila "Saldo del mes" en la tabla de flujo: es el output final del cálculo
   (Balance flujo − Gastos totales). La destacamos un poco más que las otras
   subtotal-row para que el ojo la ubique como conclusión. */
.budget-annual-table tr.saldo-row td.cat-col {
  font-weight: 700;
}
.budget-annual-table tr.saldo-row {
  border-top: 1px solid var(--border);
}
.budget-annual-table tr.saldo-row .cell-budget,
.budget-annual-table tr.saldo-row .cell-real {
  font-weight: 600;
}

/* ===== Filas especiales en la tabla de flujo =====
   Cada fila tiene su propio color de fondo para diferenciarlas visualmente:
     - balance-row    → azul/celeste  (Balance flujo, output del flujo neto)
     - basic-row      → amarillo claro más sutil (Gastos básicos, egreso obligado)
     - disc-row       → rojo terracota (Gastos discrecionales, egreso evitable)
     - saldo-row      → neutro destacado (resultado final, ya estilado abajo)
   El override pisa los estilos genéricos de .subtotal-row. */

/* Balance flujo — celeste/azul (entrada de plata) */
.budget-annual-table tr.subtotal-row.balance-row td,
.budget-annual-table tr.subtotal-row.balance-row td.cat-col {
  background: #D6E4EE;
  color: #2E4F6B;
  border-top: 2px solid #4A6B8A;
  border-bottom: 2px solid #4A6B8A;
}
[data-theme="dark"] .budget-annual-table tr.subtotal-row.balance-row td,
[data-theme="dark"] .budget-annual-table tr.subtotal-row.balance-row td.cat-col {
  background: #28384A;
  color: #88A8C4;
  border-top: 2px solid #4A6B8A;
  border-bottom: 2px solid #4A6B8A;
}

/* Gastos básicos — amarillo del subtotal-row pero MÁS transparente */
.budget-annual-table tr.subtotal-row.basic-row td,
.budget-annual-table tr.subtotal-row.basic-row td.cat-col {
  background: #FBF7EC;          /* mismo amarillo (#FAF3E4) pero más claro */
  color: #A88C5C;               /* texto un tono más claro que el subtotal normal */
  border-top: 1px solid #D4A24C;   /* borde más fino para sentir menos peso */
  border-bottom: 1px solid #D4A24C;
}
[data-theme="dark"] .budget-annual-table tr.subtotal-row.basic-row td,
[data-theme="dark"] .budget-annual-table tr.subtotal-row.basic-row td.cat-col {
  background: #2F2820;          /* más claro que el #3A3028 del subtotal normal */
  color: #BFA572;
  border-top: 1px solid #D4A24C;
  border-bottom: 1px solid #D4A24C;
}

/* Gastos discrecionales — rojo terracota (egreso evitable) */
.budget-annual-table tr.subtotal-row.disc-row td,
.budget-annual-table tr.subtotal-row.disc-row td.cat-col {
  background: #F5D9D2;
  color: #8B3A2A;
  border-top: 2px solid #C8553D;
  border-bottom: 2px solid #C8553D;
}
[data-theme="dark"] .budget-annual-table tr.subtotal-row.disc-row td,
[data-theme="dark"] .budget-annual-table tr.subtotal-row.disc-row td.cat-col {
  background: #4A2A22;
  color: #E8A57F;
  border-top: 2px solid #C8553D;
  border-bottom: 2px solid #C8553D;
}

/* ===== Panel "Últimas cargas" en el modal de importación ===== */
.upload-history-panel {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 14px;
}
.upload-history-header {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.upload-history-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.upload-history-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  gap: 10px;
  flex-wrap: wrap;
}
.upload-history-item .uh-origen {
  font-weight: 600;
  color: var(--ink);
}
.upload-history-item .uh-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted);
}

/* ===== COLUMNA DEL MES EN CURSO =====
   En las grillas de la solapa Evolución, marcamos las celdas de la columna del
   mes actual con un overlay translúcido oscuro. Esto preserva el color base de
   cada fila (verde balance, rojo discrecionales, amarillo subtotal, etc.) pero
   lo oscurece de forma uniforme, generando contraste sin romper la paleta.
   Solo se aplica cuando state.selYear === año actual (controlado en JS). */
.budget-annual-table th.current-month,
.budget-annual-table td.current-month {
  /* Light mode: overlay oscuro translúcido (tira a gris-marrón profundo pero
     deja respirar el color de la fila por debajo). */
  box-shadow: inset 0 0 0 9999px rgba(42, 37, 32, 0.40);
  position: relative;
}
[data-theme="dark"] .budget-annual-table th.current-month,
[data-theme="dark"] .budget-annual-table td.current-month {
  /* Dark mode: invertimos. El fondo base ya es oscuro, así que un overlay
     más oscuro se confunde con el body. Usamos un overlay CLARO translúcido
     para que la columna del mes actual destaque por contraste positivo. */
  box-shadow: inset 0 0 0 9999px rgba(245, 241, 232, 0.18);
}
/* Combinaciones con cond-over / cond-under: priorizamos el cond color porque
   transmite info más rica que la marca de mes actual. Mantenemos un poco de
   oscuridad/luminosidad extra para que se sienta como "mes actual también". */
.budget-annual-table td.current-month.cond-over {
  box-shadow: inset 0 0 0 9999px rgba(200, 85, 61, 0.55);
}
.budget-annual-table td.current-month.cond-under {
  box-shadow: inset 0 0 0 9999px rgba(107, 142, 78, 0.55);
}
[data-theme="dark"] .budget-annual-table td.current-month.cond-over {
  box-shadow: inset 0 0 0 9999px rgba(200, 85, 61, 0.65);
}
[data-theme="dark"] .budget-annual-table td.current-month.cond-under {
  box-shadow: inset 0 0 0 9999px rgba(107, 142, 78, 0.65);
}
/* El <th> del mes en curso queda un poco más destacado: borde inferior */
.budget-annual-table th.current-month {
  position: relative;
}
.budget-annual-table th.current-month::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--accent);
  opacity: 0.5;
}

/* ===== COLOREO CONDICIONAL POR CELDA (real vs presupuesto) =====
   Se aplica solo a celdas de categorías individuales en meses pasados, cuando
   ambos datos (presupuesto + real) existen. La técnica es la misma que la
   columna del mes actual: inset box-shadow translúcido para no pisar los
   colores de fila y poder combinarse con .current-month.
   - cond-over  → real > presupuesto en cats de gasto (o real < presup en flujo) → desfavorable → ROJO
   - cond-under → caso contrario → favorable → VERDE
   Los colores son tintes de --red y --green del proyecto. Intensidad alta
   (45%) para que se distingan claramente de las celdas no-coloreadas. */
.budget-annual-table td.cond-over {
  box-shadow: inset 0 0 0 9999px rgba(200, 85, 61, 0.45);
}
.budget-annual-table td.cond-under {
  box-shadow: inset 0 0 0 9999px rgba(107, 142, 78, 0.45);
}
/* Dark mode: necesitamos tintes aún más opacos para que se distingan sobre
   el fondo oscuro. */
[data-theme="dark"] .budget-annual-table td.cond-over {
  box-shadow: inset 0 0 0 9999px rgba(200, 85, 61, 0.55);
}
[data-theme="dark"] .budget-annual-table td.cond-under {
  box-shadow: inset 0 0 0 9999px rgba(107, 142, 78, 0.55);
}

/* ===== OVERLAY DE BLOQUEO POR DRIVE OBLIGATORIO =====
   Se muestra al iniciar la web si no hay Drive conectado, y bloquea por
   completo el acceso al dashboard. NO se puede cerrar — la única forma de
   continuar es conectar. Background opaco (no translúcido) para esconder
   totalmente cualquier dato local que pudiera estar en pantalla. */
.drive-required-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;        /* arriba de todo (modals, banners, etc.) */
  background: var(--bg-1);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  font-family: 'Inter', system-ui, sans-serif;
}
.drive-required-overlay.hidden {
  display: none;
}
.drive-required-content {
  max-width: 480px;
  text-align: center;
}
/* Bloque brand: logo + nombre + tagline. Centrado, idéntico al brand-block
   del header del dashboard pero en escala más grande para que sea el primer
   elemento visual fuerte al abrir la app. */
.drive-required-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-bottom: 28px;
}
.drive-required-logo {
  width: 56px;
  height: 56px;
  border-radius: 12px;
  box-shadow: 0 1px 4px rgba(42, 37, 32, 0.10);
}
.drive-required-brand-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
}
.drive-required-brand-name {
  font-family: 'Fraunces', serif;
  font-size: 28px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.02em;
  line-height: 1;
}
.drive-required-brand-tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted-2);
  margin-top: 6px;
}
.drive-required-title {
  font-family: 'Fraunces', serif;
  font-size: 28px;
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 16px;
  letter-spacing: -0.01em;
}
.drive-required-message {
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
  margin: 0 0 28px;
}
.drive-required-message strong {
  color: var(--ink);
  font-weight: 600;
}
.drive-required-cta {
  /* hereda .upload-btn (primary style del dashboard) — fondo oscuro, texto dorado.
     Solo agregamos un poco más de padding para hacerlo más prominente. */
  padding: 14px 28px !important;
  font-size: 13px !important;
}
.drive-required-help {
  margin-top: 24px;
  font-size: 11px;
  color: var(--muted-2);
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: 0.3px;
  line-height: 1.5;
}

/* Banner persistente cuando Drive se desconecta DESPUÉS de haber iniciado.
   No bloquea (deja seguir trabajando con localStorage como red de seguridad)
   pero advierte que los cambios no se están respaldando. */
.drive-disconnected-banner {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 999;
  background: var(--red);
  color: #fff;
  padding: 10px 18px;
  border-radius: 100px;
  font-size: 12px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
  font-family: 'Inter', system-ui, sans-serif;
}
.drive-disconnected-banner.hidden {
  display: none;
}
.drive-disconnected-banner button {
  background: rgba(255, 255, 255, 0.2);
  border: none;
  color: #fff;
  padding: 4px 12px;
  border-radius: 100px;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}
.drive-disconnected-banner button:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* ============================================================
   MODO DEMO
   ============================================================ */

/* Entrada secundaria del welcome: link discreto debajo del CTA de Drive.
   Deliberadamente sin peso visual — conectar Drive es la acción principal;
   el demo es la salida para quien solo viene a mirar. */
.drive-required-demo {
  margin-top: 14px;
  background: none;
  border: none;
  color: var(--muted);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: 6px;
  transition: color 140ms, background 140ms;
}
.drive-required-demo:hover {
  color: var(--accent);
  background: rgba(212, 162, 76, 0.08);
}

/* Banner de modo demo: mismo patrón que el de Drive desconectado, pero en
   dorado (aviso, no error). Va abajo y no arriba porque arriba se superponía
   con el título del período y los tabs. No hay riesgo de chocar con el banner
   de Drive desconectado: en modo demo no hay Drive conectado que se caiga. */
.demo-mode-banner {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 999;
  background: var(--accent);
  color: #2A2520;
  padding: 10px 18px;
  border-radius: 100px;
  font-size: 12px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
  font-family: 'Inter', system-ui, sans-serif;
  max-width: calc(100vw - 32px);
}
.demo-mode-banner.hidden {
  display: none;
}
.demo-mode-banner button {
  background: rgba(42, 37, 32, 0.15);
  border: none;
  color: #2A2520;
  padding: 4px 12px;
  border-radius: 100px;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
}
.demo-mode-banner button:hover {
  background: rgba(42, 37, 32, 0.28);
}

/* Cuando el overlay de bloqueo Drive está visible, los modales que se abren
   desde él (en particular #driveModalOverlay) tienen que aparecer POR ENCIMA
   del bloqueo, no debajo. Z-index del bloqueo = 10000; subimos modal Drive
   a 10001. Igual aplica al modal de "reemplazar archivo Drive" que es parte
   del mismo flujo. */
#driveModalOverlay,
#driveReplaceOverlay {
  z-index: 10001;
}

/* ===== Botones icon-only de Export/Import en headers ===== */
/* Reemplaza la barra config-io-bar (eliminada): ahora los botones de
   Export/Import viven dentro de los headers existentes de cada grilla. */
.cat-md-io-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  background: var(--bg-0);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.15s;
}
.cat-md-io-btn:hover {
  background: var(--accent);
  color: var(--on-accent, #fff);
  border-color: var(--accent);
}
/* Variante grande del cat-md-io-btn: igual altura que .upload-btn (~36px),
   cuadrado. Se usa en los headers que mezclan botones .upload-btn con iconos. */
.cat-md-io-btn-large {
  width: 36px;
  height: 36px;
  border-radius: 8px;
}
/* Layout: contenedor para los botones dentro del cat-md-header */
.cat-md-header-actions {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

/* ===== Densidad alta para la grilla de Visualización (Ficha médica) ===== */
.visualization-grid {
  gap: 0;  /* sin gap entre filas, los bordes lo separan */
}
.viz-grid-header {
  padding: 6px 12px;  /* antes 10px 14px */
  font-size: 9px;     /* antes 10px */
}
.viz-grid-row {
  padding: 5px 12px;  /* antes 10px 14px */
}
.viz-grid-row-name {
  font-size: 12px;    /* antes 13px */
}
.viz-grid-row-meta {
  font-size: 9px;     /* antes 10px */
}
/* El toggle (clase .config-toggle) usa por defecto 36×20px; lo achicamos */
.visualization-grid .config-toggle {
  --toggle-w: 30px;
  --toggle-h: 16px;
}
.visualization-grid .config-toggle .track {
  width: 30px;
  height: 16px;
}
.visualization-grid .config-toggle .track::after {
  width: 12px;
  height: 12px;
}
.visualization-grid .config-toggle input:checked + .track::after {
  transform: translateX(14px);
}

/* ===== Densidad compacta (sin encimar) para la grilla de Reglas ===== */
.rules-list {
  display: flex;
  flex-direction: column;
  gap: 4px;       /* separación entre grupos */
}
.rules-list .rule-row {
  padding: 8px 12px !important;
  min-height: 0 !important;
}
.rules-list .rule-row-pattern,
.rules-list .rule-row-cat,
.rules-list .rule-row-mt,
.rules-list .rule-row-peri {
  font-size: 11px;
}

/* Agrupación de reglas por categoría — vista colapsable */
.rules-group {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
.rules-group-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  cursor: pointer;
  user-select: none;
  transition: background 0.15s;
}
.rules-group-header:hover {
  background: rgba(212, 162, 76, 0.06);
}
.rules-group-chevron {
  color: var(--muted-2);
  flex-shrink: 0;
}
.rules-group-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}
.rules-group-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted-2);
  letter-spacing: 0.3px;
  margin-left: auto;
}
.rules-group-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 8px 8px;
  border-top: 1px solid var(--border);
  background: var(--bg-0);
}
.rules-group-body .rule-row {
  background: var(--bg-1);
}

/* ===== Modal de confirmación de import ===== */
.import-mode-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 16px 0;
}
.import-mode-option {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.import-mode-option:hover {
  border-color: var(--accent);
}
.import-mode-option input[type="radio"] {
  margin-top: 3px;
}
.import-mode-text {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
}
.import-mode-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}
.import-mode-desc {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.4;
}
.import-preview {
  margin-top: 14px;
  padding: 12px 14px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 12px;
  color: var(--ink);
  line-height: 1.6;
}
.import-preview:empty {
  display: none;
}
.import-preview-row {
  display: flex;
  justify-content: space-between;
  padding: 3px 0;
}
.import-preview-row .label {
  color: var(--muted);
}
.import-preview-row .value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
}

/* ===== Modal Full Config (selector de secciones) ===== */
.fullconfig-sections {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 14px 0;
}
.fullconfig-section {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}
.fullconfig-section input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
}
.fullconfig-section-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}
.fullconfig-section-label strong {
  font-size: 13px;
  color: var(--ink);
}
.fullconfig-section-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted);
}

/* ===== Grilla unificada de Visualización (Completa + Resumen) ===== */
.visualization-grid {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-0);
}
.viz-grid-header {
  display: grid;
  grid-template-columns: 1fr 110px 110px;
  align-items: center;
  padding: 10px 14px;
  background: var(--bg-1);
  border-bottom: 1px solid var(--border);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
}
.viz-grid-header > span:not(:first-child) {
  text-align: center;
}
.viz-grid-row {
  display: grid;
  grid-template-columns: 1fr 110px 110px;
  align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  transition: background 0.15s;
}
.viz-grid-row:last-child {
  border-bottom: none;
}
.viz-grid-row.modified {
  background: rgba(212, 162, 76, 0.08);
}
.viz-grid-row.disabled-row {
  opacity: 0.45;
}
.viz-grid-row-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.viz-grid-row-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
}
.viz-grid-row-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted-2);
  letter-spacing: 0.3px;
}
.viz-grid-row-toggle {
  display: flex;
  justify-content: center;
}

/* ===== Grupos colapsables por categoría en vista RESUMEN ===== */
.mov-groups {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.mov-group {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
/* Variante para categorías de flujo (Sueldo, Préstamo, Inversión, Trading,
   Jubilación, Reserva) — se diferencian visualmente del resto. */
.mov-group.flow-group {
  background: rgba(74, 107, 138, 0.08);     /* azul muy sutil del color de flujo */
  border-color: rgba(74, 107, 138, 0.35);
}
.mov-group-header {
  display: grid;
  grid-template-columns: 20px 1fr auto auto auto;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  cursor: pointer;
  user-select: none;
  transition: background 0.15s;
}
.mov-group-header:hover { background: rgba(212, 162, 76, 0.06); }
.mov-group.flow-group .mov-group-header:hover { background: rgba(74, 107, 138, 0.12); }
.mov-group-chevron {
  color: var(--muted-2);
  flex-shrink: 0;
}
.mov-group-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}
.mov-group.flow-group .mov-group-name { color: var(--blue, #4A6B8A); }
.mov-group-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted-2);
  letter-spacing: 0.3px;
}
.mov-group-total {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
  text-align: right;
  min-width: 110px;
}
.mov-group-pct {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted-2);
  text-align: right;
  min-width: 40px;
}
.mov-group-body {
  padding: 4px 8px 8px;
  border-top: 1px solid var(--border);
  background: var(--bg-0);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.mov-group.flow-group .mov-group-body {
  background: rgba(74, 107, 138, 0.03);
}

/* ===== Slot para los toggles Resumen/Completa dentro de la fila de tabs ===== */
/* Los dos toggles (Movimientos y Ficha Médica) viven dentro de .main-tabs y se
   muestran/ocultan según el tab activo (gestionado por JS en setMainTab). */
.main-tabs { align-items: center; }
.main-tabs-toggle-slot {
  margin-left: auto;          /* empuja los toggles al extremo derecho */
  margin-bottom: 0;
  display: flex;
  align-items: center;
  /* Como vive dentro del border-bottom de .main-tabs, levantamos el slot
     un poco para que no quede pegado al border. */
  padding-bottom: 6px;
}
.main-tabs-toggle-slot .view-mode-toggle { display: none; }
.main-tabs-toggle-slot .view-mode-toggle.tab-visible { display: inline-flex; }

/* ===== Toggle de modo de visualización en Evolución (Presupuestado/Real/VS) =====
   La clase se aplica al wrapper #mainTabBudget como data-budget-view. CSS
   controla qué partes de las celdas se ven sin tener que re-renderizar las
   tablas (más rápido y conserva todo el estado de scroll/selección).

   En modos no-VS ocultamos uno de los dos valores de la celda dual. Para que
   las celdas con datos no se vean visualmente más cortas que las celdas
   vacías (que sí muestran "—" en las dos posiciones), reemplazamos el span
   oculto por una "—" con la misma altura/estilo que .cell-empty. */
#mainTabBudget[data-budget-view="budgeted"] .cell-real,
#mainTabBudget[data-budget-view="budgeted"] .variation-row { display: none; }
#mainTabBudget[data-budget-view="real"] .cell-budget,
#mainTabBudget[data-budget-view="real"] .variation-row { display: none; }
/* En modo VS (default) no se oculta nada. */

/* Reemplazos visuales: si la celda dual tiene un valor (cell-budget en modo
   real, o cell-real en modo budgeted) que NO se va a mostrar, agregamos
   un "—" como placeholder en su lugar para conservar la simetría visual
   con las celdas que están totalmente vacías. */
#mainTabBudget[data-budget-view="real"] td.cell-dual:has(.cell-budget)::before {
  content: '—';
  display: block;
  color: var(--muted-2);
  font-size: 11px;
  line-height: 1.25;
  text-align: center;
}
#mainTabBudget[data-budget-view="budgeted"] td.cell-dual:has(.cell-real)::after {
  content: '—';
  display: block;
  color: var(--muted-2);
  font-size: 11px;
  line-height: 1.25;
  text-align: center;
}

/* En modos no-VS, la celda dual queda con un solo span. Achicamos la altura
   y centramos verticalmente para que las filas no queden con espacio vacío. */
#mainTabBudget[data-budget-view="budgeted"] .cell-dual,
#mainTabBudget[data-budget-view="real"] .cell-dual {
  display: table-cell;
  vertical-align: middle;
}

/* ===== Estado "incluida en presupuesto" del botón calculadora ===== */
/* El botón usa la clase .mov-budget-btn por defecto (ícono calculator). Cuando
   la tx ya fue agregada a algún presupuesto le ponemos un fondo accent verde
   para diferenciarla visualmente. El ícono cambia a check-circle. */
.mov-budget-btn.included {
  background: rgba(107, 142, 78, 0.18);     /* verde --green con baja opacidad */
  color: var(--green);
  border-radius: 6px;
}
.mov-budget-btn.included:hover {
  background: rgba(107, 142, 78, 0.28);
}
.mov-budget-btn.included i { color: var(--green); }

/* ===== Carga manual de movimientos — fila extendida ===== */
/* La fila extendida agrupa: línea principal (fecha+desc+monto+delete),
   línea de extras (cat+peri+pago) y línea de etiquetas (chips).
   Las dos primeras filas usan el MISMO grid de 4 columnas para que se
   alineen verticalmente y ocupen el ancho completo de la sección. */
.manual-row-extended {
  display: flex !important;
  flex-direction: column;
  gap: 6px;
  grid-template-columns: none !important;
  padding: 12px 12px;
  border-bottom: 1px solid var(--border);
}
.manual-row-main {
  display: grid;
  /* fecha | descripción (toma el resto) | monto | delete */
  grid-template-columns: 130px 1fr 130px 32px;
  gap: 8px;
  align-items: center;
  width: 100%;
}
.manual-row-extras {
  display: grid;
  /* categoría (más ancha) | periodicidad | forma de pago — ocupan el mismo
     ancho total que la fila principal, pero distribuido en 3 columnas. */
  grid-template-columns: 2fr 1fr 1fr;
  gap: 8px;
  align-items: center;
  width: 100%;
}
.manual-extra-field {
  background: var(--card);
  border: 1px solid var(--grid);
  border-radius: 6px;
  padding: 7px 9px;
  font-family: 'Inter', system-ui;
  font-size: 12px;
  color: var(--ink);
  width: 100%;
  outline: none;
  box-sizing: border-box;
}
.manual-extra-field.invalid { border-color: var(--red); }

/* Input de monto: sin spinners (las flechitas up/down de number) */
.manual-row input[type="number"]::-webkit-outer-spin-button,
.manual-row input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.manual-row input[type="number"] {
  -moz-appearance: textfield;
}

.manual-row-tags-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: flex-start;
}
.manual-tags-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
}
.manual-tags-chips {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
}
.manual-tag-chip {
  background: transparent;
  padding: 4px 10px;
  font-size: 11px;
  border-radius: 100px;
  cursor: pointer;
  font-family: 'Inter', system-ui;
  transition: all 0.15s;
  letter-spacing: 0.3px;
}
.manual-tag-chip:hover { transform: translateY(-1px); }
.manual-tags-empty {
  font-size: 11px;
  color: var(--muted);
  font-style: italic;
}

/* ===== Carga de inversiones (modal cuando source = 'Inversion') ===== */
.investment-batch-controls {
  display: grid;
  grid-template-columns: 1fr 200px;
  gap: 12px;
  padding: 12px 14px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.investment-batch-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.investment-row {
  display: grid !important;
  /* fecha | broker | ticker | cantidad | precio | total (read-only, flex) | delete
     Anchos calibrados para caber cómodos en el modal (~950px de contenido)
     sin generar scroll horizontal. La columna "total" absorbe el sobrante. */
  grid-template-columns: 120px 140px 130px 100px 100px 1fr 30px !important;
  gap: 6px;
  align-items: center;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  /* min-width: 0 permite que los inputs internos con contenido largo
     no fuercen el grid a expandirse (comportamiento default de grid: cada
     track tiene min-content = alto natural del contenido, que puede
     exceder el tamaño asignado). */
  min-width: 0;
}
.investment-row > * {
  min-width: 0;
}
.investment-row:last-child { border-bottom: none; }
.investment-row input {
  background: var(--card);
  border: 1px solid var(--grid);
  border-radius: 6px;
  padding: 7px 9px;
  font-family: 'Inter', system-ui;
  font-size: 12px;
  color: var(--ink);
  width: 100%;
  outline: none;
  box-sizing: border-box;
}
.investment-row input.invalid { border-color: var(--red); }
.investment-row-total {
  text-align: right;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
}

/* Detalle de activos cargados, visible en Salud financiera */
.investment-detail-panel {
  margin-top: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-1);
  overflow: hidden;
}
.investment-detail-panel summary {
  padding: 10px 14px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  user-select: none;
}
.investment-detail-panel summary::-webkit-details-marker { display: none; }
.investment-detail-panel summary::before {
  content: '▸';
  font-family: monospace;
  color: var(--muted-2);
  transition: transform 0.15s;
}
.investment-detail-panel[open] summary::before { transform: rotate(90deg); }
.investment-detail-panel summary .investment-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted-2);
  margin-left: auto;
}
.investment-detail-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
  border-top: 1px solid var(--border);
  /* table-layout: fixed hace que los anchos de las columnas sean los
     declarados en el <colgroup> que emite buildInvestmentDetailPanel(),
     no calculados por el contenido. Esto es CRÍTICO para que la tabla ARS
     y la tabla USD tengan las mismas columnas alineadas — sin esto, cada
     tabla calcula anchos independientes según su contenido y se ven
     desalineadas. */
  table-layout: fixed;
}
/* Los anchos de columna viven EXCLUSIVAMENTE en el <colgroup> del HTML que
   genera buildInvestmentDetailPanel() (dashboard.js). No agregar reglas
   `th/td:nth-child(n) { width }` acá: pisan al colgroup y quedan
   desincronizadas apenas se toca el orden o el ancho de una columna — que
   es exactamente lo que pasó antes (Broker 85px vs 140px, Ticker 60px vs
   70px, Descripción 380px vs 340px). Para cambiar un ancho, editá el
   <col> correspondiente en dashboard.js. */
.investment-detail-table th,
.investment-detail-table td {
  /* Padding lateral 10px para dar buen espacio entre columnas.
     Los `<col style="width:...">` del colgroup ya definen el ancho de
     cada columna; este padding se aplica DENTRO del ancho definido. */
  padding: 6px 10px;
  text-align: left;
  border-bottom: 1px solid var(--border);
}
.investment-detail-table th {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  color: var(--muted-2);
  text-transform: uppercase;
  background: var(--bg-0);
}
.investment-detail-table td.num,
.investment-detail-table th.num {
  text-align: right;
  font-family: 'JetBrains Mono', monospace;
}
.investment-detail-table td.ticker {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
  color: var(--accent);
}
.investment-detail-table tr:last-child td { border-bottom: none; }
.investment-detail-table .inv-delete-btn {
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--muted-2);
  padding: 2px;
}
.investment-detail-table .inv-delete-btn:hover { color: var(--red); }

/* ===== Vista agrupada por ticker ===== */
.investment-detail-grouped .inv-ticker-toggle {
  /* Ancho controlado por el <colgroup> de la tabla (20px). Padding 0 para
     que la siguiente columna (Broker/Exchange) empiece pegada al chevron
     sin espacio muerto entre ambos. */
  width: 20px !important;
  padding: 4px 0 !important;
  text-align: center;
}
.investment-detail-grouped .inv-toggle-btn {
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--muted-2);
  padding: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.investment-detail-grouped .inv-toggle-btn i,
.investment-detail-grouped .inv-toggle-btn svg {
  transition: transform 0.15s;
}
.investment-detail-grouped .inv-toggle-btn:hover { color: var(--accent); }

.inv-desc-input,
.inv-price-input {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 4px 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  /* Precio actual con mismo color/peso que el ticker (var(--accent) + bold)
     para destacarlo visualmente como dato "vivo" del portfolio. */
  color: var(--accent);
  font-weight: 600;
  width: 100%;
  outline: none;
  box-sizing: border-box;
}
.inv-desc-input:hover,
.inv-price-input:hover {
  border-color: var(--border);
}
.inv-desc-input:focus,
.inv-price-input:focus {
  border-color: var(--accent);
  background: var(--bg-1);
}
.inv-price-input {
  text-align: right;
  font-family: 'JetBrains Mono', monospace;
}
/* Sacar las flechitas del input numeric */
.inv-price-input::-webkit-outer-spin-button,
.inv-price-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.inv-price-input {
  -moz-appearance: textfield;
}

.inv-gp-positive { color: var(--green); font-weight: 600; }
.inv-gp-negative { color: var(--red); font-weight: 600; }
.inv-gp-pct {
  font-size: 9px;
  font-weight: 500;
  opacity: 0.75;
  margin-top: 1px;
}
.inv-na { color: var(--muted-2); opacity: 0.6; }

/* Subtabla de detalle (entradas individuales) — se renderiza dentro de la
   fila expandida del agrupado por ticker. */
.inv-detail-row.hidden { display: none; }
.inv-detail-row .inv-detail-cell {
  padding: 0 !important;
  background: var(--bg-0);
  border-bottom: 2px solid var(--border) !important;
}
.investment-entries-subtable {
  /* Ancho acotado + centrado horizontal para que la tabla de compras
     individuales no se estire de borde a borde (perdiendo lectura).
     max-width: 720px es cómodo para las 5-6 columnas típicas. */
  width: auto;
  max-width: 720px;
  margin: 0 auto;
  border-collapse: collapse;
  font-size: 10px;
}
.investment-entries-subtable th,
.investment-entries-subtable td {
  padding: 5px 14px;
  border-bottom: 1px solid var(--border);
  /* Todos los datos centrados (fecha, cantidad, precio, total, acciones).
     La única col que difiere es .num que ya trae text-align:right explícito. */
  text-align: center;
}
.investment-entries-subtable th {
  font-family: 'JetBrains Mono', monospace;
  font-size: 8px;
  letter-spacing: 1px;
  color: var(--muted-2);
  text-transform: uppercase;
  font-weight: 500;
}
.investment-entries-subtable .num {
  /* Centrado (según pedido: todos los datos del detalle centrados).
     Mantenemos la fuente mono para alineación visual de los dígitos. */
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
}
.investment-entries-subtable tr:last-child td {
  border-bottom: none;
}
.investment-entries-subtable .inv-delete-btn {
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--muted-2);
  padding: 2px;
}
.investment-entries-subtable .inv-delete-btn:hover { color: var(--red); }

/* ===== Header del panel de inversión con stats agregados ===== */
.investment-detail-panel summary {
  /* Override del summary para acomodar título a la izquierda y stats a la derecha */
  justify-content: space-between;
  gap: 16px;
}
.inv-summary-title {
  flex-shrink: 0;
}
.inv-summary-stats {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-left: auto;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.inv-summary-stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  align-items: flex-end;
  line-height: 1.1;
}
.inv-summary-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  color: var(--muted-2);
  text-transform: uppercase;
}
.inv-summary-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
}
/* Override del color cuando el span value tiene clase gp-positive/negative.
   Mayor especificidad para ganarle al color base. El % interno también hereda. */
.inv-summary-value.inv-gp-positive,
.inv-summary-value.inv-gp-positive .inv-summary-pct { color: var(--green); }
.inv-summary-value.inv-gp-negative,
.inv-summary-value.inv-gp-negative .inv-summary-pct { color: var(--red); }
.inv-summary-pct {
  font-size: 10px;
  font-weight: 500;
  opacity: 0.85;
}

/* ===== Header: separador vertical entre ARS y USD ===== */
.inv-summary-currency {
  display: flex;
  align-items: center;
  gap: 18px;
  position: relative;
}
.inv-summary-currency-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.5px;
  color: var(--muted-2);
  text-transform: uppercase;
  font-weight: 600;
  padding-right: 6px;
}
.inv-summary-separator {
  width: 1px;
  align-self: stretch;
  background: var(--border);
  margin: 0 4px;
}

/* Para que el % dentro de G/P herede el color del padre */
.inv-summary-pct.inv-gp-positive,
.inv-summary-pct.inv-gp-negative {
  font-weight: 500;
}

/* ===== Divisores horizontales ARS / USD dentro de la tabla ===== */
.inv-section-header td {
  background: var(--bg-0);
  padding: 8px 14px !important;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.inv-section-header:first-child td {
  border-top: none;
}
.inv-section-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--accent);
  text-transform: uppercase;
  font-weight: 600;
  margin-right: 10px;
}
.inv-section-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted-2);
}
.inv-section-empty td {
  text-align: center;
  color: var(--muted-2);
  font-size: 11px;
  font-style: italic;
  padding: 14px !important;
  background: transparent;
}

/* ===== Dos tablas separadas (una por moneda) ===== */
.investment-detail-tables {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.investment-detail-tables .investment-detail-table {
  /* Borde divisor entre las dos tablas (ARS y USD) */
  border-top: 1px solid var(--border);
}
.investment-detail-tables .investment-detail-table:first-child {
  border-top: none;
}
/* Primera fila del thead: label de moneda. El background lo define la regla
   .investment-detail-tables .inv-currency-header-row th más abajo (uniforme
   para ARS y USD). El display:flex permite que el botón "actualizar precios"
   (solo en ARS) quede empujado a la derecha vía margin-left:auto, sin que
   afecte la posición del label — así ARS y USD arrancan en la misma X. */
.inv-currency-header-row th {
  display: flex;
  align-items: center;
  /* Padding lateral reducido para alinear el label "ARS/USD" con el inicio
     de las columnas de abajo, sin desperdiciar espacio a la izquierda. */
  padding: 8px 5px !important;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.5px;
  color: var(--accent);
  text-transform: uppercase;
  text-align: left;
  border-bottom: 1px solid var(--border);
}
.inv-currency-header-row .inv-section-label {
  color: var(--accent);
  font-weight: 600;
  margin-right: 10px;
}
.inv-currency-header-row .inv-section-count {
  color: var(--muted-2);
  font-weight: 500;
  letter-spacing: 1.2px;
}
/* Segunda fila del thead: títulos de columnas (usa el estilo th por default) */

/* ===== Fondo distintivo por panel (Reserva, Inversión, Trading, Jubilaciones) =====
   El color de cada panel viene del accent de la tarjeta KPI correspondiente
   (state.kpiCardsConfig). El JS aplica el accent como CSS variable inline
   --inv-accent, y acá lo combinamos con transparent vía color-mix para
   obtener un tinte sutil de fondo + un borde-izquierdo más saturado. */
.investment-detail-panel {
  background: linear-gradient(180deg, color-mix(in srgb, var(--inv-accent, #8B7355) 6%, transparent), transparent 60%);
  border-left: 3px solid color-mix(in srgb, var(--inv-accent, #8B7355) 55%, transparent);
}

/* ===== Encabezado de moneda — mismo fondo para ARS y USD =====
   Ambas filas "ARS · N tickers" y "USD · N tickers" usan el mismo color de
   fondo (azul-acero sutil) para que se vean uniformes como divisores de
   sección. La diferencia entre las dos sub-tablas se mantiene a nivel del
   fondo del <table> en sí (la tabla USD tiene un tinte general más sutil). */
.investment-detail-tables .inv-currency-header-row th {
  background: rgba(74, 107, 138, 0.12);
}

/* ===== Color de fondo distinto para la tabla USD ===== */
/* La tabla USD usa un fondo levemente teñido para diferenciarla visualmente
   de la tabla ARS dentro del mismo panel. El encabezado ya es uniforme (regla
   de arriba); el tinte del body es lo que distingue una tabla de la otra. */
.investment-detail-tables .inv-table-usd {
  background: rgba(74, 107, 138, 0.06);
}
/* Y para no perder contraste, las filas de tickers en USD tienen un hover más visible */
.investment-detail-tables .inv-table-usd tbody tr:hover {
  background: rgba(74, 107, 138, 0.08);
}

/* ===== Header del panel — layout 3 columnas (nombre · totales · sparkline) ===== */
.investment-detail-panel summary {
  /* Override: el nuevo header usa un grid interno, así que el summary debe
     no pelearse con flex/space-between/etc */
  display: block;
  padding: 14px 16px;
}
.inv-header-grid {
  display: grid;
  /* Columna 1: nombre del panel. Columna 2: stack de totales (cada fila ya
     incluye su mini gráfico al final). Ya no hay columna 3 separada para el
     sparkline — el sparkline va al final de la fila ARS+USD. */
  grid-template-columns: minmax(140px, 1fr) minmax(640px, 5fr);
  gap: 20px;
  align-items: center;
}
.inv-header-name {
  font-family: 'Fraunces', serif;
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
  position: relative;
  padding-left: 18px;
}
/* Chevron de expand/colapsar a la izquierda del nombre (el details::marker queda oculto) */
.investment-detail-panel summary::-webkit-details-marker { display: none; }
.investment-detail-panel summary::before {
  display: none;
}
.inv-header-name::before {
  content: '▸';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  font-family: monospace;
  font-size: 12px;
  color: var(--muted-2);
  transition: transform 0.15s;
}
.investment-detail-panel[open] .inv-header-name::before {
  transform: translateY(-50%) rotate(90deg);
}
.inv-header-totals {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-family: 'JetBrains Mono', monospace;
}
.inv-header-total-row {
  display: grid;
  /* Label | Líquido | Invertido | Actualizado | Variación | Chart (distbar o sparkline) */
  grid-template-columns: 60px 1fr 1fr 1fr 1.3fr 1.4fr;
  gap: 12px;
  align-items: center;
  padding: 4px 0;
}
.inv-header-total-label {
  font-size: 11px;
  letter-spacing: 1.2px;
  color: var(--accent);
  text-transform: uppercase;
  font-weight: 600;
}
.inv-header-total-cell {
  display: flex;
  flex-direction: column;
  gap: 1px;
  align-items: flex-end;
  text-align: right;
}
.inv-header-cell-label {
  font-size: 8px;
  letter-spacing: 1.2px;
  color: var(--muted-2);
  text-transform: uppercase;
  font-family: 'JetBrains Mono', monospace;
}
.inv-header-cell-value {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
  font-family: 'JetBrains Mono', monospace;
}
.inv-header-cell-value.inv-gp-positive { color: var(--green); }
.inv-header-cell-value.inv-gp-negative { color: var(--red); }
.inv-header-pct {
  font-size: 10px;
  font-weight: 500;
  opacity: 0.85;
}

.inv-header-total-combined {
  border-top: 1px solid var(--border);
  padding-top: 6px;
  margin-top: 2px;
}
.inv-header-total-combined .inv-header-cell-value { font-size: 13px; }

/* Cuando el panel está colapsado, ocultamos las líneas meta (días invertidos +
   cotización MEP) — son detalles que solo aportan cuando ves el contenido
   completo. Reaparecen apenas se expande el <details>. */
.investment-detail-panel:not([open]) .inv-header-cotizacion {
  display: none;
}

.inv-header-cotizacion {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
}
/* Cuando hay varias líneas meta seguidas (días + cotización), solo la primera
   muestra el separador superior. Las siguientes se pegan compactas. */
.inv-header-cotizacion + .inv-header-cotizacion {
  margin-top: 2px;
  padding-top: 0;
  border-top: none;
}
.inv-header-cotizacion-label {
  font-size: 9px;
  letter-spacing: 1.2px;
  color: var(--muted-2);
  text-transform: uppercase;
  font-family: 'JetBrains Mono', monospace;
}
.inv-header-cotizacion-value {
  font-size: 11px;
  color: var(--ink);
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
}

.inv-sparkline {
  width: 100%;
  height: 32px;
  display: block;
}

@media (max-width: 900px) {
  .inv-header-grid {
    grid-template-columns: 1fr;
    gap: 12px;
  }
}

/* ===== Cotización MEP — botón "actualizar desde dolarapi" ===== */
.mep-input-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
}
.param-fetch-btn {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 6px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--accent);
  transition: all 0.15s;
  padding: 0;
  flex-shrink: 0;
}
.param-fetch-btn:hover:not(:disabled) {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.param-fetch-btn:disabled {
  opacity: 0.6;
  cursor: wait;
}
.param-fetch-btn.loading svg,
.param-fetch-btn.loading i {
  animation: spin 0.8s linear infinite;
}
@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ===== Celda chart en la fila del header (distbar o sparkline) ===== */
.inv-header-cell-chart {
  display: flex;
  align-items: center;
  justify-content: stretch;
  min-height: 22px;
}
.inv-header-cell-chart .inv-sparkline {
  width: 100%;
  max-width: 100%;
  height: 32px;
}

/* ===== Stacked bar de distribución por ticker ===== */
.inv-distbar {
  display: flex;
  width: 100%;
  height: 14px;
  border-radius: 7px;
  overflow: hidden;
  background: var(--bg-0);
  border: 1px solid var(--border);
}
.inv-distbar-seg {
  display: block;
  height: 100%;
  transition: filter 0.15s;
  cursor: default;
  min-width: 2px;
}
.inv-distbar-seg:hover {
  filter: brightness(1.15);
}
.inv-distbar-empty {
  background: var(--bg-0);
  opacity: 0.5;
}

/* ===== Fila META (solo en panel Reserva) ===== */
/* Va arriba de la fila ARS. Tiene el mismo grid de 5 columnas que las otras
   filas. Debajo se separa con un divisor horizontal antes de la fila ARS
   (mismo tratamiento que la fila ARS+USD vs USD). */
.inv-header-meta-row {
  /* La fila META tiene una línea divisora ABAJO, no arriba — separa del
     bloque de monedas. */
  padding-bottom: 8px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.inv-header-meta-row .inv-header-total-label {
  color: var(--green);  /* META en verde para distinguirla de ARS/USD/ARS+USD (accent) */
}
.inv-meta-aporte {
  font-size: 10px;
  color: var(--muted-2);
  font-weight: 500;
}

/* Barra de progreso de la meta */
.inv-meta-progress {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
}
.inv-meta-progress-bar {
  height: 14px;
  background: var(--bg-0);
  border: 1px solid var(--border);
  border-radius: 7px;
  overflow: hidden;
}
.inv-meta-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--green), #9BBE7C);
  transition: width 0.3s ease-out;
  border-radius: 7px 0 0 7px;
}
.inv-meta-progress-fill.over {
  /* Si se sobrecumplió la meta (>100%), barra dorada */
  background: linear-gradient(90deg, var(--accent), #E8C078);
  border-radius: 7px;
}
.inv-meta-progress-pct {
  font-size: 10px;
  font-weight: 600;
  color: var(--green);
  text-align: right;
  font-family: 'JetBrains Mono', monospace;
}
.inv-meta-progress-fill.over ~ .inv-meta-progress-pct,
.inv-meta-progress:has(.inv-meta-progress-fill.over) .inv-meta-progress-pct {
  color: var(--accent);
}


/* ===== Botón "Actualizar" dentro de la fila ARS · N tickers ===== */
/* El th hace de contenedor flex para poner el botón al extremo derecho */
.inv-currency-header-row th {
  /* Heredan padding/font de la regla genérica; agregamos layout flex */
  display: flex;
  align-items: center;
  gap: 10px;
}
.inv-currency-header-row .inv-update-prices-btn {
  margin-left: auto;
  width: 22px;
  height: 22px;
  border-radius: 5px;
}
/* Anular los estilos previos del botón que asumían que estaba en .inv-header-name */
.inv-update-prices-btn {
  background: transparent;
  border: 1px solid var(--border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--muted-2);
  transition: all 0.15s;
  padding: 0;
  flex-shrink: 0;
}
.inv-update-prices-btn:hover:not(:disabled) {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.inv-update-prices-btn:disabled {
  opacity: 0.5;
  cursor: wait;
}
.inv-update-prices-btn.loading svg,
.inv-update-prices-btn.loading i {
  animation: spin 0.8s linear infinite;
}

/* ===== Botón ↻ al lado de "Cotización MEP usada" ===== */
.inv-mep-refresh-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 4px;
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--muted-2);
  transition: all 0.15s;
  padding: 0;
  margin-left: 4px;
  flex-shrink: 0;
}
.inv-mep-refresh-btn:hover:not(:disabled) {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.inv-mep-refresh-btn:disabled {
  opacity: 0.5;
  cursor: wait;
}
.inv-mep-refresh-btn.loading svg,
.inv-mep-refresh-btn.loading i {
  animation: spin 0.8s linear infinite;
}

/* ===== appAlert/appConfirm — preservar saltos de línea ===== */
/* Los mensajes que vienen con \n (típicamente avisos multi-línea de fetch de
   precios o cotización) deben mostrar sus saltos de línea como párrafos
   visuales. Usamos pre-line para que respete \n pero colapse espacios.
   El selector apunta al div del mensaje del modal genérico de confirmación. */
#appConfirmMessage {
  white-space: pre-line;
  line-height: 1.5;
}

/* ===== Celda LÍQUIDO clickeable (lleva a Historia clínica filtrada) ===== */
/* Solo la celda LÍQUIDO de la fila ARS+USD es clickeable (las filas ARS y USD
   individuales muestran "—" y no tienen sentido para navegar). Visual feedback
   con hover sutil + cursor pointer. */
.inv-liq-clickable {
  cursor: pointer;
  border-radius: 6px;
  transition: background 0.15s, transform 0.1s;
  padding: 2px 6px !important;
  margin: -2px -6px;  /* compensar el padding para no agrandar la celda */
}
.inv-liq-clickable:hover {
  background: rgba(212, 162, 76, 0.12);  /* accent dorado al 12% */
}
.inv-liq-clickable:active {
  transform: scale(0.98);
}
/* Sutil indicador visual de que es clickeable: línea inferior punteada en el valor */
.inv-liq-clickable .inv-header-cell-value {
  border-bottom: 1px dotted var(--muted-2);
  padding-bottom: 1px;
}

/* ============================================================
   REDISEÑO MODAL EDITAR TARJETA KPI — layout 2 columnas + densidad
   ============================================================ */
/* El modal pasa de ~640px a ~960px y distribuye su contenido en 2 columnas
   en desktop (Apariencia + Operación a la izquierda, Hint a la derecha).
   La vista previa queda sticky-bottom abarcando todo el ancho. En mobile
   (<900px) colapsa a 1 columna preservando el layout anterior. */
.kpi-editor-modal {
  max-width: min(960px, 92vw);
  width: 960px;
  display: flex;
  flex-direction: column;
  max-height: 90vh;
}
.kpi-editor-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  overflow-y: auto;
  /* Padding-right para que el scrollbar no choque con el contenido. */
  padding-right: 4px;
  /* min-height:0 es necesario para que el grid hijo respete el overflow. */
  min-height: 0;
  flex: 1 1 auto;
  /* align-items: start evita que las dos secciones de la fila superior
     (Apariencia y Hint) se estiren artificialmente a la misma altura —
     cada una mide lo que su contenido necesita. */
  align-items: start;
}
/* Sección que ocupa toda la fila (las 2 columnas) — para "Operación de cálculo"
   que tiene varios sub-controles y aprovecha mejor el ancho completo. */
.kpi-editor-section-fullrow {
  grid-column: 1 / -1;
}
/* Dentro del fullrow, el grid interno aprovecha 4 sub-columnas para que los
   campos cortos (tipo, periodicidad) queden lado a lado en vez de stacked. */
.kpi-editor-grid-wide {
  grid-template-columns: repeat(4, 1fr);
}
.kpi-editor-grid-wide .kpi-editor-field.full {
  grid-column: 1 / -1;
}
/* Densidad: secciones más compactas en el nuevo layout */
.kpi-editor-modal .kpi-editor-section {
  margin-bottom: 0;  /* el gap del col se encarga */
  padding: 12px;
}
/* Vista previa sticky: queda al fondo del modal, separada de las columnas */
.kpi-editor-preview-sticky {
  margin-top: 12px;
  flex-shrink: 0;
}
/* Selectores compactos: para Posición, Periodicidad, Decimales —
   campos cuyo contenido es siempre corto. Tienen min-width que respeta
   el texto más largo de las opciones para evitar cortes. */
.kpi-editor-select-compact {
  min-width: 140px;
  max-width: 220px;
}
/* Campo compacto: se usa para Color de borde y Activa (controles chicos)
   junto a inputs más anchos en la misma fila. */
.kpi-editor-field-compact {
  max-width: 160px;
}
/* Hint inline en labels (texto explicativo en lowercase al lado del label) */
.kpi-editor-field-hint {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
  margin-left: 6px;
  font-style: italic;
}
/* Mobile / pantallas angostas: 1 columna apilada (vuelve al layout anterior) */
@media (max-width: 900px) {
  .kpi-editor-modal {
    width: 100%;
    max-width: 96vw;
  }
  .kpi-editor-body {
    grid-template-columns: 1fr;
  }
  .kpi-editor-section-fullrow {
    grid-column: 1 / -1;  /* sigue siendo todo el ancho (que es 1 col en mobile) */
  }
  .kpi-editor-grid-wide {
    grid-template-columns: 1fr 1fr;  /* 4 cols → 2 cols en mobile */
  }
  .kpi-editor-field-compact { max-width: none; }
  .kpi-editor-select-compact { max-width: none; }
}

/* Compactar los grids internos de sección para mayor densidad */
.kpi-editor-modal .kpi-editor-grid {
  gap: 10px;
  margin-bottom: 0;  /* el padding de la sección ya da espacio */
}
.kpi-editor-modal .kpi-editor-field input[type="text"],
.kpi-editor-modal .kpi-editor-field input[type="color"],
.kpi-editor-modal .kpi-editor-field select {
  padding: 7px 9px;
  font-size: 13px;
}
.kpi-editor-modal .kpi-editor-section-title {
  font-size: 10px;
  margin-bottom: 8px;
}

/* ============================================================
   EDICIÓN INLINE de descripción y monto en Historia Clínica
   ============================================================ */
/* Las celdas contenteditable necesitan visual feedback de que son editables.
   Por defecto sin marca visible para no recargar la grilla. Al hover de
   celdas SIN tooltip de original, cursor "text"; al hover de celdas CON
   tooltip (.has-original), cursor "help" para indicar que hay info extra. */
.mov-editable-desc,
.mov-editable-monto {
  cursor: text;
  /* min-width y padding mínimos para que la celda sea "clickeable" aún si
     el texto es corto. */
  min-width: 60px;
  padding: 2px 4px;
  margin: -2px -4px;       /* compensa el padding para que no agrande la fila */
  border-radius: 3px;
  transition: background 0.12s;
}
.mov-editable-desc:hover,
.mov-editable-monto:hover {
  background: rgba(212, 162, 76, 0.08);
}
.mov-editable-desc:focus,
.mov-editable-monto:focus {
  outline: none;
  background: rgba(212, 162, 76, 0.15);
  box-shadow: inset 0 0 0 1px rgba(212, 162, 76, 0.5);
}
/* .has-original marca que la celda fue editada (hay original guardado).
   El cursor "help" + el tooltip nativo cuentan al usuario que puede ver
   el valor previo. */
.mov-editable-desc.has-original,
.mov-editable-monto.has-original {
  cursor: help;
  /* Subrayado sutil punteado para indicar "hay info extra al hover". */
  text-decoration: underline dotted rgba(212, 162, 76, 0.6);
  text-underline-offset: 2px;
}
.mov-editable-desc.has-original:focus,
.mov-editable-monto.has-original:focus {
  /* Durante la edición, sacamos el underline para no distraer. */
  text-decoration: none;
}

/* ============================================================
   CAT_COMBINE: lista de operandos en el editor de KPI
   ============================================================ */
/* Cada operando se muestra como una "card" con borde sutil. Adentro:
   un header con signo + número + delete button; abajo un mini-grid con
   cat/sub + periodicidad + tags. El conjunto vive dentro del wrap
   #kpiOpCombineList o #kpiHintCombineList. */
.cat-combine-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 10px;
}
.cat-combine-operand {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  background: var(--bg-1);
  /* Borde-left más visible para distinguir cada operando */
  border-left: 3px solid color-mix(in srgb, var(--accent, #D4A24C) 60%, transparent);
}
.cat-combine-operand-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 4px;
}
.cat-combine-sign {
  width: 60px;
  padding: 4px 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  font-weight: 700;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-0);
  color: var(--ink);
  cursor: pointer;
}
.cat-combine-operand-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted-2);
  letter-spacing: 1px;
}
.cat-combine-delete-btn {
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 6px;
  cursor: pointer;
  color: var(--muted-2);
  transition: all 0.12s;
}
.cat-combine-delete-btn:hover {
  background: rgba(200, 85, 61, 0.08);
  color: var(--red);
  border-color: var(--red);
}
.cat-combine-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: 8px;
  cursor: pointer;
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
  font-family: inherit;
  transition: all 0.15s;
}
.cat-combine-add-btn:hover {
  background: color-mix(in srgb, var(--accent, #D4A24C) 6%, transparent);
  border-color: var(--accent, #D4A24C);
  color: var(--accent, #D4A24C);
  border-style: solid;
}


/* ============================================================
   TOGGLE ARS/USD (Ficha Médica) + indicador de cotización
   ============================================================ */
.view-mode-toggle.currency-toggle .view-mode-btn {
  /* Botones ARS/USD un poquito más compactos que Resumen/Completa porque no
     llevan icono. Mantienen la misma altura para alineación con el toggle vecino. */
  padding: 6px 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 1px;
  font-weight: 600;
}
/* Indicador de cotización al lado del toggle USD. Se muestra solo cuando el
   modo USD está activo. Compacto y mono para no robar protagonismo. */
.kpi-currency-indicator {
  display: inline-flex;
  align-items: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted-2);
  margin-left: 8px;
  letter-spacing: 0.5px;
}
.kpi-currency-indicator.warn {
  color: var(--red, #C8553D);
}

/* Símbolo de moneda dentro del valor de las tarjetas KPI. Lo coloreamos en
   un tono apagado (muted-2 — marrón cálido de la paleta tierra) para que el
   monto siga siendo el protagonista visual y el símbolo se lea como prefijo
   discreto. Misma fuente y tamaño que el número, solo cambia el color.
   También una sutil reducción de peso para reforzar la jerarquía. */
.kpi-card .value .kpi-currency-symbol {
  color: var(--muted-2);
  font-weight: 500;
  /* Separación micro entre símbolo y monto: 1px de margen derecho da aire
     sin afectar el alineamiento. */
  margin-right: 1px;
}

/* ============================================================
   SIDEBAR LATERAL — panel de controles global
   ------------------------------------------------------------
   Aloja el header (título+logo+pin), los selectores de período
   y los botones utility. Dos modos:
   1. Auto-oculto (default): sidebar fuera de pantalla; se abre
      con hover en el borde izquierdo; cierra con click en
      backdrop o Escape.
   2. Pineado (state.params.sidebarPinned=true): sidebar fijo
      visible, contenido shifted 260px a la derecha, sin backdrop.
   ============================================================ */

/* Contenedor principal del sidebar */
.app-sidebar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 260px;
  background: var(--bg-1, #F5F1E8);
  border-right: 1px solid var(--border, #E8DFD0);
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 20px 18px;
  overflow-y: auto;
  overflow-x: hidden;
  /* Slide horizontal cuando abre/cierra */
  transform: translateX(-100%);
  transition: transform 260ms ease;
  box-shadow: 4px 0 24px rgba(42, 37, 32, 0.10);
}
/* Estado abierto (auto-oculto pero desplegado) o pineado: visible */
.app-sidebar.open,
.app-sidebar.pinned {
  transform: translateX(0);
}
/* Cuando está pineado, no queremos la sombra pronunciada */
.app-sidebar.pinned {
  box-shadow: 1px 0 0 var(--border, #E8DFD0);
}

/* Header del sidebar: logo + brand + botón pin */
.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border, #E8DFD0);
}
.sidebar-header .brand-block {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.sidebar-header .brand-logo {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* SVG del logo: escala al contenedor sin distorsionarse. */
.sidebar-header .brand-logo svg {
  width: 100%;
  height: 100%;
  display: block;
}
.sidebar-header .brand-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.sidebar-header .brand-name {
  font-family: 'Fraunces', serif;
  font-size: 18px;
  font-weight: 600;
  color: var(--ink, #2A2520);
  line-height: 1.1;
}
.sidebar-header .brand-tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  color: var(--muted-2, #8B7355);
  text-transform: uppercase;
}
/* Estilo especial cuando el sidebar está pineado: el botón queda destacado
   con el color accent para dar retroalimentación clara del estado activo. */
.app-sidebar.pinned #sidebarPinBtn {
  background: var(--accent, #D4A24C) !important;
  color: var(--ink, #2A2520) !important;
  border-color: var(--accent, #D4A24C) !important;
}

/* Bloque de título dinámico + estado sync */
.sidebar-title-block h1 {
  font-family: 'Fraunces', serif;
  font-size: 18px;
  font-weight: 400;
  font-style: italic;
  line-height: 1.15;
  margin: 0 0 8px 0;
  color: var(--ink, #2A2520);
}
.sidebar-title-block h1 strong {
  font-weight: 700;
  font-style: normal;
}
.sidebar-title-block .status-badges-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Selectores stackeados verticalmente */
.sidebar-selectors {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.sidebar-selectors .selector-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sidebar-selectors .period-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted-2, #8B7355);
}
.sidebar-selectors .period-select {
  width: 100%;
  min-width: 0;
}

/* Botones utility en columna */
.sidebar-utility-buttons {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--border, #E8DFD0);
}
.sidebar-utility-buttons .upload-btn,
.sidebar-utility-buttons .export-menu-wrap {
  width: 100%;
}
/* Dentro del sidebar los botones muestran texto SIEMPRE (aunque tengan
   la clase btn-icon-only en el HTML). El sidebar tiene el ancho
   suficiente y el texto es útil para diferenciarlos. Override localizado
   del comportamiento colapsable.
   ⚠ Los !important son necesarios porque la regla base
   ".upload-btn.btn-icon-only:not(:hover):not(:focus-visible) { gap: 0 }"
   tiene mayor especificidad que este selector y colapsa el gap a 0. */
.sidebar-utility-buttons .upload-btn.btn-icon-only {
  padding: 10px 14px !important;
  justify-content: flex-start !important;
  gap: 14px !important;
  max-width: 100% !important;
}
.sidebar-utility-buttons .upload-btn.btn-icon-only > span {
  opacity: 1 !important;
  max-width: 200px !important;
  margin-left: 0 !important;
  overflow: visible !important;
  white-space: nowrap;
  font-size: 11px;
  letter-spacing: 0.5px;
}
.sidebar-utility-buttons .export-menu-wrap {
  position: relative;
}
.sidebar-utility-buttons .export-menu {
  /* En el sidebar el menú abre a la derecha del botón para no cortarse */
  left: 100%;
  top: 0;
  right: auto;
  margin-left: 4px;
}

/* Franja de hover en el borde izquierdo: al pasar el mouse por ahí
   abre el sidebar (shortcut). Solo activa en modo no-pineado. */
.sidebar-hover-zone {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 8px;
  z-index: 89;
  cursor: e-resize;
}
body.sidebar-pinned .sidebar-hover-zone {
  display: none;
}

/* Backdrop: overlay oscuro cuando el sidebar está abierto (modo no-pineado).
   Click en él lo cierra. */
.sidebar-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(42, 37, 32, 0.45);
  z-index: 99;
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms ease;
}
body.sidebar-open:not(.sidebar-pinned) .sidebar-backdrop {
  opacity: 1;
  pointer-events: auto;
}

/* Contenido principal: cuando el sidebar está pineado, se shifta
   260px a la derecha. Cuando está auto-oculto, ocupa el 100%. */
body.sidebar-pinned .app-top-bar,
body.sidebar-pinned .main-tab-panel,
body.sidebar-pinned #catModalOverlay,
body.sidebar-pinned .app-content-wrapper {
  margin-left: 260px;
  transition: margin-left 260ms ease;
}
body:not(.sidebar-pinned) .app-top-bar,
body:not(.sidebar-pinned) .main-tab-panel {
  margin-left: 0;
  transition: margin-left 260ms ease;
}

/* Cuando no está pineado, el sidebar es overlay. El contenido ocupa
   todo el ancho disponible, sin padding-left de compensación. */

/* Responsive — mobile: sidebar full-width overlay */
@media (max-width: 600px) {
  .app-sidebar { width: 88vw; max-width: 320px; }
  body.sidebar-pinned .app-top-bar,
  body.sidebar-pinned .main-tab-panel {
    margin-left: 0;
  }
  /* En mobile ignoramos el pin visual — siempre es overlay */
  .app-sidebar.pinned {
    transform: translateX(-100%);
  }
  .app-sidebar.pinned.open {
    transform: translateX(0);
  }
}

/* ============================================================
   FILA DE HEADER DE PERÍODO
   Sobre los tabs principales. Título dinámico a la izq
   ("Anatomía de un trimestre") y estado de sync a la derecha.
   ============================================================ */
.period-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 4px 0 12px 0;
  flex-wrap: wrap;
}
/* El título ocupa el espacio central y el sync status queda a la derecha,
   alineados verticalmente al centro por el align-items: center del row. */
.period-header-row .period-title {
  font-family: 'Fraunces', serif;
  font-size: 22px;
  font-weight: 400;
  font-style: italic;
  line-height: 1.15;
  margin: 0;
  color: var(--ink, #2A2520);
  flex: 1 1 auto;
  min-width: 0;
}
.period-header-row .period-title strong {
  font-weight: 700;
  font-style: normal;
}
.period-header-row .period-header-sync {
  /* Fila horizontal: recordatorios de carga a la izquierda, status Drive
     a la derecha. En layouts angostos hace wrap para que no se solapen. */
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}
/* En mobile, si no entran horizontalmente, wrap y quedan uno debajo del otro */
@media (max-width: 700px) {
  .period-header-row .period-title { font-size: 18px; }
  .period-header-row .period-header-sync { justify-content: flex-start; }
}

/* ============================================================
   FILA DEL SCORE + COLUMNAS LATERALES (Ficha Médica)
   Layout de 3 columnas: [ col izq (1fr) | score (2fr) | col der (1fr) ]
   El score ocupa el ancho de 2 tarjetas KPI; cada columna lateral
   ocupa el ancho de 1 tarjeta KPI y puede alojar hasta 3 tarjetas
   apiladas. Todas las tarjetas mantienen el alto NATURAL de una
   tarjeta KPI de la grilla principal.
   ============================================================ */

/* Alto de referencia de una tarjeta KPI. Es la unidad de "medida" para
   dimensionar el score. Se calibró empíricamente para aproximar el alto
   natural de una tarjeta KPI con sparkline (padding + eyebrow + valor +
   hint + sparkline). Con este valor, las 3 alturas quedan consistentes:
   tarjeta grilla ≈ tarjeta lateral ≈ media del score card. */
:root {
  --kpi-card-height: 140px;
}

.health-score-row {
  /* Grid de 4 columnas 1fr que ESPEJA la grilla KPI de abajo (que también
     usa repeat(4, 1fr) con gap 16px). Con esto la columna lateral izquierda
     del score coincide PIXEL A PIXEL con la 1ra tarjeta KPI, y la derecha
     con la 4ta. El score card ocupa las 2 columnas del medio + su gap
     intermedio via grid-column: 2 / 4. Este approach elimina el desfasaje
     que había con "1fr 2fr 1fr" (que tenía 2 gaps en lugar de 3, así la
     col lateral era 4px más ancha que una tarjeta KPI). */
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 12px;
  align-items: stretch;
}
.health-score-row .score-left-column {
  grid-column: 1 / 2;
}
.health-score-row #healthScoreSection {
  /* El score card ocupa 2 columnas + el gap intermedio */
  grid-column: 2 / 4;
}
.health-score-row .score-right-column {
  grid-column: 4 / 5;
}
/* Cuando una columna lateral está vacía, el score se extiende para ocupar
   ese espacio. Usamos selectores :has() para el layout adaptativo. */
.health-score-row:has(.score-left-column.empty):has(.score-right-column.empty) #healthScoreSection {
  grid-column: 1 / -1;
}
.health-score-row:has(.score-right-column.empty):not(:has(.score-left-column.empty)) #healthScoreSection {
  grid-column: 2 / -1;
}
.health-score-row:has(.score-left-column.empty):not(:has(.score-right-column.empty)) #healthScoreSection {
  grid-column: 1 / 4;
}
.health-score-row .score-left-column.empty,
.health-score-row .score-right-column.empty {
  display: none;
}
/* Las reglas :has() para columnas vacías ya están definidas más arriba
   junto con el grid-column: 2/4 del score. No hace falta duplicarlas. */

/* Columnas laterales: stack vertical de tarjetas KPI. Cada tarjeta
   ocupa el ALTO NATURAL de una KPI de la grilla principal — NO se
   estira aunque el grid padre esté en stretch. */
.score-left-column,
.score-right-column {
  display: flex;
  flex-direction: column;
  /* gap: 16px alineado con el gap de la grilla KPI (16px) para consistencia
     visual — las columnas verticales del score y las horizontales de la
     grilla usan el mismo espacio entre tarjetas. */
  gap: 16px;
  justify-content: flex-start;
  align-items: stretch;
}
.score-left-column .kpi-card,
.score-right-column .kpi-card {
  /* Las tarjetas se ESTIRAN para llenar todo el alto de la columna (que
     está determinado por el alto del score card via align-items: stretch
     del grid padre). Con flex: 1 1 0 las 3 tarjetas dividen el espacio
     disponible en partes iguales — sin dejar hueco al final. Resultado:
     el alto total de la columna = alto del score = mismo alto que la fila. */
  flex: 1 1 0;
}

/* Score card: alto AUTOMÁTICO — se ajusta al alto de las columnas laterales
   (con align-items: stretch del grid padre). Así el score tiene EXACTAMENTE
   el mismo alto que 3 tarjetas KPI apiladas. Forzamos align-self: stretch +
   height: 100% para asegurar que se estire aunque el contenido natural sea
   más chico. margin-bottom: 0 sobrescribe el margin-bottom: 32px heredado
   de .section-card que estaba desalineando el fin del score. */
.health-score-card {
  box-sizing: border-box;
  align-self: stretch;
  height: 100%;
  margin-bottom: 0;
}

/* Responsive: en pantallas chicas colapsa a stack vertical. */
@media (max-width: 900px) {
  .health-score-row {
    grid-template-columns: 1fr;
  }
  .score-left-column,
  .score-right-column {
    flex-direction: row;
    flex-wrap: wrap;
  }
  .score-left-column .kpi-card,
  .score-right-column .kpi-card {
    flex: 1 1 200px;
  }
}

/* ============================================================
   Columna de Tendencia (Evolución)
   Sparkline por fila que compara presupuesto (dorado) vs
   real (verde) con línea de promedio real (punteada gris).
   ============================================================ */
.budget-annual-table th.trend-col {
  min-width: 120px;
  text-align: center;
  padding: 6px 8px;
}
.budget-annual-table td.trend-cell {
  vertical-align: middle;
  text-align: center;
  padding: 4px 8px;
  background: rgba(0, 0, 0, 0.02);
  border-left: 1px solid var(--border);
}
.budget-annual-table td.trend-cell svg.evo-trend-sparkline {
  display: inline-block;
  vertical-align: middle;
}
/* Ajuste de opacidad para las filas de sección (fondos coloreados) */
.budget-annual-table .subtotal-row td.trend-cell,
.budget-annual-table .basic-row td.trend-cell,
.budget-annual-table .disc-row td.trend-cell,
.budget-annual-table .saldo-row td.trend-cell {
  background: rgba(0, 0, 0, 0.04);
}

/* ============================================================
   SUBMENÚ DEL BOTÓN ADMINISTRACIÓN (sidebar)
   Aparece al pasar el mouse sobre el wrap. Contiene acciones
   secundarias como "Borrar datos".
   ============================================================ */
.sidebar-admin-wrap {
  position: relative;
}
/* El submenu aparece al hover del wrap. Usamos display: block al hover
   en lugar de removeChild + hidden porque queremos la transición suave. */
.sidebar-admin-wrap:hover .sidebar-admin-submenu {
  display: block;
}
.sidebar-admin-submenu {
  display: none;
  margin-top: 6px;
  padding: 6px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(42, 37, 32, 0.10);
}
.sidebar-admin-submenu.hidden {
  display: none;
}
.sidebar-admin-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 12px;
  background: transparent;
  border: none;
  border-radius: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  font-weight: 600;
  color: var(--red-2, #C8553D);
  cursor: pointer;
  transition: background 120ms, color 120ms;
  text-align: left;
}
.sidebar-admin-item:hover {
  background: rgba(200, 85, 61, 0.08);
  color: var(--red-2, #C8553D);
}

/* ============================================================
   EXPANSIÓN DE SUBCATEGORÍAS EN LA SOLAPA EVOLUCIÓN
   Categorías con subcategorías (state.subcategoryLabels[cat] con
   al menos 1 entrada) muestran un chevron a la izquierda del ícono.
   Al hacer click, se expanden filas de subcategoría debajo con el
   real de cada mes (el budget se muestra vacío porque el modelo
   no soporta budget por subcategoría).
   ============================================================ */

/* Botón chevron (▶ colapsado / ▼ expandido) */
.budget-annual-table .cat-chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 4px;
  color: var(--muted);
  cursor: pointer;
  transition: background 120ms, color 120ms;
  flex-shrink: 0;
}
.budget-annual-table .cat-chevron:hover {
  background: var(--bg-0);
  color: var(--ink);
}

/* Fila de subcategoría — indentada, compacta (1 línea, sin budget) */
.budget-annual-table tr.sub-row {
  background: rgba(0, 0, 0, 0.015);
}
[data-theme="dark"] .budget-annual-table tr.sub-row {
  background: rgba(255, 255, 255, 0.02);
}
.budget-annual-table tr.sub-row td {
  font-size: 10.5px;
  /* Padding vertical reducido: como es una sola línea (solo real, sin
     budget), no necesita el alto de las celdas dual normales. */
  padding: 4px 5px;
  line-height: 1.2;
}
.budget-annual-table tr.sub-row td.sub-cat-col {
  padding-left: 42px; /* indentación para alinear con el nombre de la cat madre */
  font-family: 'Inter', system-ui;
  font-size: 11px;
  font-weight: 400;
  color: var(--muted);
}
.budget-annual-table tr.sub-row .sub-cat-content {
  display: flex;
  align-items: center;
  gap: 6px;
}
.budget-annual-table tr.sub-row .sub-cat-marker {
  color: var(--muted-2);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  opacity: 0.6;
}
/* Celdas de real de subcategoría: 1 sola línea, monto sin dual layout.
   Usamos --ink (texto principal, cerca del blanco en dark theme) para
   que contraste FUERTE con el verde de las categorías madre — así se
   nota rápidamente la jerarquía al expandir las subcats. */
.budget-annual-table tr.sub-row .sub-real-cell {
  color: var(--ink);
  font-family: 'JetBrains Mono', monospace;
  text-align: right;
  white-space: nowrap;
}

/* ============================================================
   BROKER / EXCHANGE: chip coloreado en la tabla + select en el form
   Colores por broker: BALANZ (azul), NEXO (violeta), BULL MARKET (terracota).
   Uso: <span class="broker-chip broker-bg-BALANZ">BALANZ</span>
        <select class="inv-broker-sel broker-bg-BALANZ">
   ============================================================ */

/* Colores base (compartidos entre chip y select) */
.broker-bg-BALANZ      { background: #4A6B8A; color: #F5F1E8; }
.broker-bg-NEXO        { background: #8E5A9E; color: #F5F1E8; }
.broker-bg-BULL_MARKET { background: #C8553D; color: #F5F1E8; }
.broker-bg-multi       { background: var(--muted-2); color: var(--bg-1); }
.broker-bg-none        { background: transparent; color: var(--muted); border: 1px dashed var(--border); }

/* Chip pequeño para la celda de la tabla de tickers */
.broker-chip {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.8px;
  white-space: nowrap;
  text-align: center;
}
.investment-detail-table td.broker-cell {
  /* Chip centrado dentro de la columna Broker/Exchange. Especificidad
     .investment-detail-table td.broker-cell (0,0,2,1) supera a
     .investment-detail-table td (0,0,1,1) para vencer el text-align:left
     genérico de la tabla. */
  text-align: center;
  padding: 6px 8px;
}

/* Select del broker en el form de carga de inversiones. Toma el color del
   broker seleccionado como fondo — visualización inmediata sin abrir el select. */
.inv-broker-sel {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.5px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: none;
  /* width: 100% del track del grid. Sin min-width para no forzar el
     ancho — el track ya es 140px cómodo para "BULL MARKET". */
  width: 100%;
  padding-right: 22px;
  box-sizing: border-box;
}
.inv-broker-sel:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* Cuando el <select> tiene la clase de color, los <option> internos también
   heredan el fondo. Los option a nivel del native picker no siempre respetan
   estos colors (depende del OS/browser), pero el select cerrado sí. */
.inv-broker-sel option {
  background: var(--bg-1);
  color: var(--ink);
}

/* Header "BROKER/EXCHANGE" centrado dentro de su columna. */
.investment-detail-table .inv-columns-header-row th:nth-child(2) {
  text-align: center;
}
/* Espacio extra al inicio de la columna Ticker (padding-left más grande)
   para separar visualmente Broker/Exchange de Ticker. */
.investment-detail-table th:nth-child(3),
.investment-detail-table td:nth-child(3) {
  padding-left: 14px;
}
