@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

:root {
  --ink: #12131e;
  --surface: #161826;
  --surface-alt: #232532;
  --surface-2: #2b2e3f;
  --divider: rgba(233,233,237,.16);
  --cream: #e9e9ed;
  --muted: rgba(233,233,237,.55);
  --muted-2: rgba(233,233,237,.72);

  --accent: #9184d9;
  --accent-100: #f5f4ff;
  --accent-300: #d2cefd;
  --accent-400: #b5abfc;
  --accent-600: #796cbf;
  --accent-800: #423a6a;
  --accent-900: #2b2741;

  --income: oklch(72% .14 150);
  --income-bg: oklch(26% .05 150);
  --income-text: oklch(88% .06 150);
  --expense: oklch(70% .14 45);
  --expense-bg: oklch(26% .05 45);
  --expense-text: oklch(88% .06 45);

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 14px;

  --shadow-sm: 0 0 0 1px rgba(233,233,237,.08);
  --shadow-md: 0 0 0 1px rgba(233,233,237,.10), 0 6px 18px rgba(0,0,0,.55);
  --shadow-lg: 0 0 0 1px rgba(233,233,237,.14), 0 16px 40px rgba(0,0,0,.65);
}

/* ══════════════ Modo claro (preferencia por cuenta, no afecta a los demás) ══════════════ */
body.tema-claro {
  --ink: #f3f3f6;
  --surface: #ffffff;
  --surface-alt: #eceef3;
  --surface-2: #dfe2e9;
  --divider: rgba(18,19,30,.12);
  --cream: #14151f;
  --muted: rgba(18,19,30,.58);
  --muted-2: rgba(18,19,30,.75);

  --accent: #7a6bd0;
  --accent-100: #ffffff;
  --accent-300: #6a5bc4;
  --accent-400: #5a4bb5;
  --accent-600: #9184d9;
  --accent-800: #d2cefd;
  --accent-900: #ffffff;

  --income: oklch(52% .14 150);
  --income-bg: oklch(94% .03 150);
  --income-text: oklch(38% .10 150);
  --expense: oklch(52% .16 35);
  --expense-bg: oklch(94% .03 35);
  --expense-text: oklch(40% .12 35);

  --shadow-sm: 0 0 0 1px rgba(18,19,30,.06);
  --shadow-md: 0 0 0 1px rgba(18,19,30,.08), 0 6px 18px rgba(18,19,30,.10);
  --shadow-lg: 0 0 0 1px rgba(18,19,30,.10), 0 16px 40px rgba(18,19,30,.14);
}


* { box-sizing: border-box; }

/* ══════════════ Scrollbar personalizada ══════════════
   La barra de scroll nativa del sistema (gris, con flechitas arriba/abajo, con huecos
   feos en los extremos) desentona con el tema oscuro — se sustituye por una versión fina,
   sin botones de flecha, a juego con los colores de la app. scrollbar-width/-color cubren
   Firefox; las pseudo-clases ::-webkit-scrollbar-* cubren Chrome/Edge (y por tanto la app
   instalada como PWA, que es Chromium por debajo). */
html { scrollbar-width: thin; scrollbar-color: var(--surface-2) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--surface-2); border-radius: 20px; border: 2px solid var(--ink);
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--accent-600); }
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
::-webkit-scrollbar-corner { background: transparent; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--cream);
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  font-variant-numeric: tabular-nums;
  display: flex;
  justify-content: center;
}

#app {
  width: 100%;
  max-width: 480px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

header {
  padding: 28px 18px 16px;
  border-bottom: 1px solid var(--divider);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
header .title { font-family: 'Inter', sans-serif; font-weight: 500; font-size: 21px; letter-spacing: -0.015em; }
header .subtitle { font-size: 11px; color: var(--muted); letter-spacing: 1.2px; text-transform: uppercase; margin-left: 8px; }
#btn-refresh {
  background: transparent; border: 1px solid var(--divider); color: var(--muted);
  width: 30px; height: 30px; border-radius: 50%; font-size: 15px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: background .15s ease;
}
#btn-refresh:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); border-color: var(--accent); }
#btn-refresh.spinning { animation: spin 0.6s linear; }
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

main { flex: 1; padding: 18px 18px 100px; }
.hidden { display: none !important; }

.section-label { font-size: 11px; color: var(--muted); letter-spacing: 1px; text-transform: uppercase; font-weight: 500; }

.lang-desktop-corner { display: none; }

.patrocinador-logo {
  height: 24px; max-width: 100px; object-fit: contain;
  filter: grayscale(1); opacity: .7; transition: filter .2s, opacity .2s;
}
.patrocinador-logo:hover { filter: none; opacity: 1; }

/* Tarjeta genérica de fondo (usada en el nuevo Resumen: salud/balance, moneda, objetivos, disponible, categorías) */
.card {
  background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}

/* Balance card */
.balance-card {
  background: var(--surface); border-radius: var(--radius-lg); padding: 22px 20px;
  box-shadow: var(--shadow-sm); position: relative; overflow: hidden; margin-bottom: 18px;
}
.balance-card::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: linear-gradient(180deg, var(--accent), transparent 85%);
}
.balance-amount {
  font-family: 'Inter', sans-serif; font-weight: 500; letter-spacing: -0.02em;
  font-size: 34px; margin-top: 4px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.balance-row { display: flex; gap: 20px; margin-top: 14px; }
.balance-row span { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; }

.metodo-row {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--surface); border-radius: var(--radius-md); padding: 12px 14px;
  box-shadow: var(--shadow-sm); margin-bottom: 8px; font-size: 14px;
}
.bar-bg { height: 5px; background: var(--surface-2); border-radius: 3px; overflow: hidden; margin-top: 4px; }
.bar-fill { height: 100%; border-radius: 3px; transition: width .6s cubic-bezier(.16,1,.3,1); }

.empty-state { text-align: center; padding: 70px 20px 0; }
.empty-state .title { font-family: 'Inter', sans-serif; font-weight: 500; font-size: 18px; margin: 14px 0 8px; }
.empty-state .body { font-size: 13.5px; color: var(--muted); line-height: 1.55; }

.filtros { display: flex; gap: 8px; margin-bottom: 16px; }
.filtro-btn {
  padding: 6px 14px; border-radius: 20px; font-size: 12.5px; cursor: pointer; font-weight: 500;
  border: 1px solid var(--divider); background: transparent; color: var(--muted); transition: all .15s ease;
}
.filtro-btn.active { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent-300); }

.ledger { position: relative; padding-left: 16px; }
.ledger::before { content: ''; position: absolute; left: 4px; top: 4px; bottom: 4px; width: 1px; background: var(--divider); }
.tx-item { position: relative; margin-bottom: 12px; opacity: 0; animation: rise .35s ease forwards; }
.tx-item:nth-child(n) { animation-delay: calc(var(--i, 0) * 20ms); }
@keyframes rise { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
.tx-dot { position: absolute; left: -16px; top: 6px; width: 6px; height: 6px; border-radius: 50%; }
.tx-dot.ingreso { background: var(--income); }
.tx-dot.gasto { background: var(--expense); }
.tx-card {
  background: var(--surface); border-radius: var(--radius-md); padding: 12px 14px; box-shadow: var(--shadow-sm);
  display: flex; justify-content: space-between; align-items: center; gap: 10px; transition: box-shadow .15s ease;
}
.tx-card:hover { box-shadow: var(--shadow-md); }
.tx-desc { font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 180px; }
.tx-meta { font-size: 11px; color: var(--muted); margin-top: 1px; }
.tx-amount { font-weight: 500; font-size: 14px; font-variant-numeric: tabular-nums; }
.tx-amount.ingreso { color: var(--income-text); }
.tx-amount.gasto { color: var(--expense-text); }
.tx-delete { background: none; border: none; cursor: pointer; color: var(--muted); padding: 2px; transition: color .15s ease; }
.tx-delete:hover { color: var(--expense-text); }
.tx-edit { background: none; border: none; cursor: pointer; color: var(--muted); padding: 2px; margin-right: 4px; transition: color .15s ease; }
.tx-edit:hover { color: var(--accent-300); }

/* KPIs / gráficos */
.kpi-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 20px; }
.kpi-card { background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); padding: 14px; min-width: 0; }
.kpi-label { font-size: 10.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .6px; font-weight: 500; }
.kpi-value { font-weight: 500; font-size: 17px; margin-top: 6px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.kpi-sub { font-size: 11px; color: var(--muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Efectivo/Banco/Inversión en Patrimonio: mismas tarjetas que .kpi-card en el resto de la app,
   pero más altas y con el contenido centrado, para que la fila entera pese visualmente parecido
   a la tarjeta de análisis que tiene justo encima (que es bastante más alta que un kpi-card
   normal) en vez de quedar como una tira fina y desequilibrada debajo. */
.kpi-card-patrimonio { padding: 20px 16px; min-height: 112px; display: flex; flex-direction: column; justify-content: center; }
/* Efectivo/Banco/Inversión: a partes iguales en una sola fila (en vez de las 2 columnas fijas de
   .kpi-grid), sea cual sea el número de tarjetas que haya según los tipos de activo declarados. */
.kpi-grid.kpi-grid-patrimonio { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); }
/* Igual que .kpi-sub pero para frases/párrafos largos: sí hace salto de línea normal.
   .kpi-sub a secas se queda así a propósito (recorta con "...") para etiquetas cortas de una
   línea, como la descripción de un movimiento en una fila de tabla — ahí SÍ interesa que corte. */
.kpi-sub-texto { font-size: 12.5px; color: var(--muted); line-height: 1.55; white-space: normal; overflow: visible; text-overflow: clip; }

.stats-charts-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }
.chart-block {
  margin-bottom: 0; background: var(--surface); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm); padding: 18px 18px 20px; min-width: 0;
}
.chart-block.chart-block-wide { grid-column: 1 / -1; }
/* Este bloque de análisis va suelto (no dentro de .stats-charts-grid), justo debajo de
   Patrimonio Neto y antes del kpi-grid de Efectivo/Banco/Inversión — necesita su propio margen
   inferior, que .chart-block no lleva porque normalmente lo pone el gap del grid que lo envuelve. */
.chart-block-analisis-patrimonio { margin-bottom: 14px; }
.chart-block svg { width: 100%; height: auto; display: block; }
/* El donut lleva tamaño fijo a propósito (no debe estirarse a lo ancho de la tarjeta,
   o el círculo crece de forma desproporcionada) — solo las demás gráficas ocupan el 100%. */
.chart-block svg.chart-donut-svg { width: auto; max-width: 100%; margin: 0 auto; }
.chart-donut-row { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; justify-content: center; }
.chart-block path, .chart-block polyline { stroke-dasharray: 1000; stroke-dashoffset: 1000; animation: draw 1.1s cubic-bezier(.16,1,.3,1) forwards; }
.chart-block circle { animation: fadein .5s ease forwards; opacity: 0; }
.chart-block rect { transform-box: fill-box; transform-origin: bottom; animation: growbar .5s cubic-bezier(.16,1,.3,1) backwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes fadein { to { opacity: 1; } }
@keyframes growbar { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) {
  .chart-block path, .chart-block polyline, .chart-block circle, .chart-block rect, .tx-item { animation: none !important; opacity: 1 !important; stroke-dashoffset: 0 !important; transform: none !important; }
}
.chart-legend { display: flex; flex-wrap: wrap; gap: 10px 16px; margin-top: 10px; }
.chart-legend .item { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); }
.chart-legend .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
@media (min-width: 720px) {
  .stats-charts-grid { grid-template-columns: 1fr 1fr; }
}

/* Filtros avanzados historial */
.filters-panel { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.search-input {
  width: 100%; background: var(--surface); border: 1px solid var(--divider); border-radius: var(--radius-md);
  padding: 10px 12px; color: var(--cream); font-size: 14px; outline: none; font-family: inherit;
}
.search-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.select-row { display: flex; gap: 8px; }
.select-field {
  flex: 1; background: var(--surface); border: 1px solid var(--divider); border-radius: var(--radius-md);
  padding: 9px 8px; color: var(--cream); font-size: 12.5px; outline: none; font-family: inherit;
}
.select-field:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.csv-btn {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 0; border-radius: var(--radius-md); font-size: 12.5px; cursor: pointer; font-weight: 500;
  border: 1px solid var(--accent); background: transparent; color: var(--accent); transition: background .15s ease;
}
.csv-btn:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.results-count { font-size: 11.5px; color: var(--muted); margin: -4px 0 12px; }

/* Wizard */
.progress { display: flex; gap: 6px; margin-bottom: 26px; }
.progress div { flex: 1; height: 2px; border-radius: 2px; background: var(--divider); transition: background .3s ease; }
.progress div.done { background: var(--accent); }
.question-label { font-family: 'Inter', sans-serif; font-weight: 500; font-size: 19px; margin-bottom: 16px; letter-spacing: -0.01em; }

.input-field {
  width: 100%; box-sizing: border-box; background: var(--surface); border: 1px solid var(--divider); border-radius: var(--radius-md);
  padding: 14px 16px; color: var(--cream); font-size: 16px; outline: none; margin-bottom: 12px; font-family: inherit;
}
.input-field:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Campo marcado como inválido por la validación en tiempo real (ver assets/js/validacion-formularios.js):
   mismo rojo que ya se usa en el resto de la app para "gasto/error" (--expense), para no meter un color nuevo. */
.input-field[aria-invalid="true"], .select-field[aria-invalid="true"] { border-color: var(--expense); }
.input-field[aria-invalid="true"]:focus-visible, .select-field[aria-invalid="true"]:focus-visible { outline-color: var(--expense); }
/* Mensaje justo debajo del campo que ha fallado — oculto por defecto, se muestra añadiendo
   "visible" (igual que el patrón que ya usa contact.php con sus .ct-error). El margen negativo
   arriba lo acerca al campo, compensando el margin-bottom que ya trae .input-field. */
.field-error { display: none; color: var(--expense-text); font-size: 11.5px; margin: -8px 0 12px; line-height: 1.5; }
.field-error.visible { display: block; }
.amount-wrap { position: relative; }
.amount-wrap input { font-weight: 500; font-size: 26px; padding-right: 40px; font-variant-numeric: tabular-nums; }
.amount-wrap .currency { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); color: var(--muted); }

.option-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.option-row-list { display: flex; flex-direction: column; gap: 10px; }
.option-pair { display: flex; gap: 10px; }

.option-card {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 22px 10px; border-radius: var(--radius-md); cursor: pointer; transition: all .15s ease;
  border: 1px solid var(--divider); background: var(--surface); color: var(--cream); text-align: center; flex: 1;
}
.option-card.small { padding: 16px 8px; }
.option-card.active { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.option-card span { font-size: 13.5px; }
.option-card.small span { font-size: 12px; }

.option-row {
  display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-radius: var(--radius-md); cursor: pointer;
  border: 1px solid var(--divider); background: var(--surface); color: var(--cream); transition: all .15s ease;
}
.option-row.active { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.option-row .check { margin-left: auto; color: var(--accent); }

.wizard-nav { display: flex; gap: 10px; margin-top: 28px; }
.nav-btn {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 13px 0; border-radius: var(--radius-md); font-size: 14px; cursor: pointer; font-weight: 500;
  border: 1px solid var(--divider); background: transparent; color: var(--muted); text-decoration: none;
  transition: background .15s ease, transform .1s ease, border-color .15s ease;
}
.nav-btn:hover { border-color: var(--muted); }
.nav-btn.primary { border-color: var(--accent); background: var(--accent); color: var(--accent-900); }
.nav-btn.primary:hover { filter: brightness(1.08); }
.nav-btn.primary:active { transform: scale(.98); }
.nav-btn.primary:disabled { opacity: 0.4; cursor: default; filter: none; }
.nav-btn.danger { border-color: var(--expense); color: var(--expense-text); }
.nav-btn.danger:hover { background: color-mix(in srgb, var(--expense) 14%, transparent); }
.nav-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.error-banner {
  margin-top: 12px; padding: 10px 14px; border-radius: var(--radius-md);
  background: var(--expense-bg); border: 1px solid color-mix(in srgb, var(--expense) 50%, transparent);
  color: var(--expense-text); font-size: 13px;
}

/* Ajustes */
.settings-group { margin-bottom: 22px; }
.settings-group-title { font-size: 11px; color: var(--muted); letter-spacing: 1px; text-transform: uppercase; margin-bottom: 10px; font-weight: 500; }
.toggle-row {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
  padding: 13px 14px; margin-bottom: 8px; font-size: 14px;
}
.switch { position: relative; width: 42px; height: 24px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .slider { position: absolute; inset: 0; background: var(--surface-2); border-radius: 20px; cursor: pointer; transition: .2s; }
.switch .slider::before { content: ''; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px; background: var(--cream); border-radius: 50%; transition: .2s; }
.switch input:checked + .slider { background: var(--accent); }
.switch input:checked + .slider::before { transform: translateX(18px); background: var(--accent-900); }

.profile-card { background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 16px; margin-bottom: 22px; }
.profile-name { font-family: 'Inter', sans-serif; font-weight: 500; font-size: 17px; overflow-wrap: anywhere; }
.profile-email { font-size: 12.5px; color: var(--muted); margin-top: 2px; overflow-wrap: anywhere; }
.profile-sub { font-size: 12px; color: var(--income-text); margin-top: 10px; }

/* Esqueletos de carga — silueta animada que rellena el hueco de una tarjeta mientras su llamada a
   la API está en camino, en vez de dejarlo en blanco. */
.skel-block {
  background: linear-gradient(90deg, var(--surface-2) 25%, color-mix(in srgb, var(--surface-2) 55%, var(--cream) 10%) 37%, var(--surface-2) 63%);
  background-size: 480px 100%;
  animation: skel-shimmer 1.3s ease-in-out infinite;
}
@keyframes skel-shimmer { 0% { background-position: -240px 0; } 100% { background-position: 240px 0; } }
@media (prefers-reduced-motion: reduce) { .skel-block { animation: none; opacity: .6; } }

/* Toasts — abajo a la derecha (por encima del menú inferior en móvil, que es sticky y tiene su
   propia zona segura al final de la pantalla) */
#toast-alertas { position: fixed; bottom: calc(84px + env(safe-area-inset-bottom, 0px)); right: 14px; left: auto; transform: none; z-index: 50; width: calc(100% - 28px); max-width: 380px; display: flex; flex-direction: column; }
.toast {
  background: var(--surface); border: 1px solid color-mix(in srgb, var(--expense) 50%, transparent); border-radius: var(--radius-md);
  padding: 12px 14px; margin-bottom: 8px; font-size: 13px; box-shadow: var(--shadow-lg); animation: toast-in 0.25s ease;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* Modal */
#modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.6); z-index: 100; display: flex; align-items: center; justify-content: center; padding: 24px; transition: backdrop-filter .3s ease; }
#modal-overlay.overlay-bienvenida { background: rgba(10,8,20,0.72); backdrop-filter: blur(3px); }
#modal-analisis { background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 24px; max-width: 400px; width: 100%; max-height: 80vh; overflow-y: auto; }
#modal-analisis .modal-title { font-family: 'Inter', sans-serif; font-weight: 500; font-size: 18px; margin-bottom: 12px; }
#modal-analisis .modal-body { font-size: 13.5px; line-height: 1.6; color: var(--cream); white-space: pre-line; }

/* Bienvenida con IA — popup de bienvenida (primera vez que se entra a la app), más vistoso y
   animado que el modal estándar de análisis: cabecera degradada con icono animado, chispas
   flotantes decorativas, y el propio popup entra con un "pop" elástico. */
/* overflow-x oculto (para recortar bien las esquinas redondeadas y las chispas decorativas de la
   cabecera), pero overflow-y con scroll: si el texto que genera la IA es un poco largo, antes el
   botón de cerrar quedaba recortado fuera de la vista y sin forma de hacer scroll para llegar a
   él — con esto el popup siempre se puede cerrar, tenga el texto que tenga. */
#modal-analisis.modal-bienvenida { padding: 0; overflow-x: hidden; overflow-y: auto; max-width: 380px; animation: bienvenida-pop .5s cubic-bezier(.34,1.56,.64,1); }
@keyframes bienvenida-pop { from { opacity: 0; transform: scale(.82) translateY(14px); } to { opacity: 1; transform: scale(1) translateY(0); } }

.bienvenida-ia-header {
  position: relative; background: linear-gradient(135deg, var(--accent-400), var(--accent) 55%, var(--accent-600));
  padding: 32px 20px 28px; text-align: center; overflow: hidden;
}
.bienvenida-ia-header .chispa {
  position: absolute; color: rgba(255,255,255,.55); font-size: 13px; animation: sparkle-float 2.6s ease-in-out infinite;
}
.bienvenida-ia-header .chispa:nth-child(1) { top: 16px; left: 26px; font-size: 15px; animation-delay: .1s; }
.bienvenida-ia-header .chispa:nth-child(2) { top: 22px; right: 30px; font-size: 10px; animation-delay: .9s; }
.bienvenida-ia-header .chispa:nth-child(3) { bottom: 14px; left: 44px; font-size: 9px; animation-delay: 1.6s; }
@keyframes sparkle-float { 0%, 100% { transform: translateY(0) scale(1); opacity: .45; } 50% { transform: translateY(-6px) scale(1.25); opacity: 1; } }

.bienvenida-ia-icono {
  width: 62px; height: 62px; border-radius: 50%; background: rgba(255,255,255,.16);
  display: flex; align-items: center; justify-content: center; font-size: 28px; margin: 0 auto;
  box-shadow: 0 0 0 6px rgba(255,255,255,.09); animation: bienvenida-icono-pop .6s .18s cubic-bezier(.34,1.56,.64,1) both;
}
@keyframes bienvenida-icono-pop { from { opacity: 0; transform: scale(.3) rotate(-18deg); } to { opacity: 1; transform: scale(1) rotate(0); } }

.bienvenida-ia-body { padding: 22px 22px 24px; animation: rise .5s .2s both; }
.bienvenida-ia-titulo { font-family: 'Inter', sans-serif; font-weight: 600; font-size: 19px; text-align: center; margin-bottom: 10px; color: var(--cream); }
.bienvenida-ia-texto { font-size: 14px; line-height: 1.65; color: var(--cream); text-align: center; opacity: .9; }
.bienvenida-ia-btn { width: 100%; margin-top: 22px; box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 45%, transparent); }

/* Menú "Más" */
.menu-list { display: flex; flex-direction: column; gap: 8px; }
.menu-item {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
  padding: 15px 16px; cursor: pointer; color: var(--cream); font-size: 14.5px; text-decoration: none; transition: box-shadow .15s ease;
}
.menu-item:hover { box-shadow: var(--shadow-md); }
.menu-item .arrow { color: var(--muted); }
.subview-back { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 13px; cursor: pointer; margin-bottom: 18px; background: none; border: none; padding: 0; text-decoration: none; }
.subview-back:hover { color: var(--accent); }

/* Presupuesto */
.budget-intro { background: var(--surface); border-radius: var(--radius-lg); padding: 18px 20px; margin-bottom: 18px; }
.budget-intro-title { display: flex; align-items: center; gap: 8px; font-family: 'Inter', sans-serif; font-weight: 500; font-size: 14.5px; margin-bottom: 8px; }
.budget-intro p { font-size: 13px; color: var(--muted); line-height: 1.6; margin: 0 0 8px; }
.budget-intro p:last-child { margin-bottom: 0; }

.budget-split-preview { display: flex; height: 10px; border-radius: 6px; overflow: hidden; margin: 14px 0 22px; background: var(--surface-2); }
.budget-split-preview div { transition: width .15s ease; }

.pct-row { margin-bottom: 20px; }
.pct-row-head { display: flex; align-items: center; gap: 8px; font-size: 13.5px; margin-bottom: 8px; }
.pct-row-head .dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.pct-row-head .pct-num { margin-left: auto; font-family: ui-monospace, monospace; font-weight: 600; font-size: 14px; }

.pct-slider {
  width: 100%; height: 8px; border-radius: 6px; appearance: none; -webkit-appearance: none;
  background: var(--surface-2); cursor: pointer; outline: none;
}
.pct-slider::-webkit-slider-thumb {
  appearance: none; -webkit-appearance: none; width: 20px; height: 20px; border-radius: 50%;
  background: var(--cream); box-shadow: var(--shadow-md); border: 3px solid var(--track-color, var(--accent));
  cursor: grab; margin-top: -6px;
}
.pct-slider::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 50%; background: var(--cream); box-shadow: var(--shadow-md);
  border: 3px solid var(--track-color, var(--accent)); cursor: grab;
}
.pct-slider::-webkit-slider-runnable-track { height: 8px; border-radius: 6px; background: transparent; }
.pct-slider::-moz-range-track { height: 8px; border-radius: 6px; background: transparent; }
.pct-slider.gasto::-webkit-slider-thumb { border-color: var(--expense); }
.pct-slider.gasto::-moz-range-thumb { border-color: var(--expense); }
.pct-slider.ahorro::-webkit-slider-thumb { border-color: var(--accent); }
.pct-slider.ahorro::-moz-range-thumb { border-color: var(--accent); }
.pct-slider.inversion::-webkit-slider-thumb { border-color: var(--income); }
.pct-slider.inversion::-moz-range-thumb { border-color: var(--income); }

.pct-total { text-align: center; font-size: 13.5px; margin: 4px 0 18px; padding: 10px; border-radius: 10px; background: var(--surface-2); color: var(--muted); }
.pct-total.ok { color: var(--income-text); background: var(--income-bg); }
.pct-total.bad { color: var(--expense-text); background: var(--expense-bg); }
.budget-compare { margin-top: 22px; }
.budget-compare-row { margin-bottom: 14px; }
.budget-compare-labels { display: flex; justify-content: space-between; font-size: 12.5px; margin-bottom: 4px; }

/* Patrimonio / activos */
.activo-card { display: flex; justify-content: space-between; align-items: center; background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); padding: 13px 14px; margin-bottom: 8px; gap: 10px; }
/* min-width:0 es necesario porque .activo-info es un hijo flex sin ancho fijo: por defecto un
   hijo flex nunca se encoge por debajo del ancho de su contenido, así que un nombre largo (de
   una transacción, un activo o el email de un miembro familiar) empujaría la tarjeta más allá
   del ancho de la pantalla en vez de recortarse con los puntos suspensivos de abajo. */
.activo-info { flex: 1; min-width: 0; }
.activo-info .nombre { font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.activo-info .tipo { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.activo-valor { font-weight: 500; font-size: 14px; display: flex; align-items: center; gap: 10px; font-variant-numeric: tabular-nums; flex-shrink: 0; }

/* Agenda de recurrentes (pestaña Recurrentes, solo Pro) — cabecera + layout a dos columnas:
   a la izquierda la línea de tiempo con las próximas fechas, a la derecha el resumen del mes y
   la lista completa. En móvil las columnas se apilan (rec-layout sin grid-template-columns). */
.rec-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
.rec-header-title { font-size: 20px; font-weight: 600; letter-spacing: -0.01em; }
.rec-header-sub { font-size: 13px; color: var(--muted); margin-top: 4px; }
.rec-layout { display: flex; flex-direction: column; gap: 14px; }
.rec-col-lateral { display: flex; flex-direction: column; }

.rec-mes-nav { display: flex; align-items: center; gap: 10px; }
.rec-mes-btn { width: 30px; height: 30px; border-radius: var(--radius-md); border: 1px solid var(--divider); background: var(--surface-alt); color: var(--cream); font-size: 15px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background .15s ease; }
.rec-mes-btn:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.rec-mes-actual { font-size: 13.5px; font-weight: 500; }

/* Cada fila = badge de fecha + tramo de línea vertical (conecta con la siguiente fila salvo la
   última) + tarjeta del movimiento. El :last-child quita la línea/hueco sobrante debajo de la
   fecha para que no "sobresalga" de la última fila. */
.rec-timeline { display: flex; flex-direction: column; }
.rec-timeline-row { display: flex; gap: 14px; }
.rec-timeline-fecha { width: 52px; flex-shrink: 0; display: flex; flex-direction: column; align-items: center; padding: 10px 0; background: var(--surface-alt); border-radius: var(--radius-md); height: fit-content; }
.rec-timeline-fecha .dia { font-size: 19px; font-weight: 600; line-height: 1.1; }
.rec-timeline-fecha .mes { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin-top: 2px; }
.rec-timeline-linea { width: 16px; flex-shrink: 0; display: flex; justify-content: center; position: relative; }
.rec-timeline-linea::before { content: ''; position: absolute; top: 0; bottom: -14px; width: 1px; background: var(--divider); }
.rec-timeline-row:last-child .rec-timeline-linea::before { display: none; }
.rec-timeline-linea .punto { width: 9px; height: 9px; border-radius: 50%; background: var(--accent-300); border: 2px solid var(--surface); margin-top: 24px; z-index: 1; }
.rec-timeline-row { margin-bottom: 14px; }
.rec-timeline-row:last-child { margin-bottom: 0; }

.rec-item { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); padding: 12px 13px; }
.rec-item-icon { width: 36px; height: 36px; border-radius: 10px; background: var(--surface-alt); display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; }
.rec-item-info { flex: 1; min-width: 0; }
.rec-item-nombre { font-size: 13.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rec-item-meta { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px; }
.rec-badge { font-size: 10.5px; font-weight: 600; border-radius: 20px; padding: 3px 9px; flex-shrink: 0; white-space: nowrap; display: none; }
.rec-badge.gasto { color: var(--expense-text); background: var(--expense-bg); }
.rec-badge.ingreso { color: var(--income-text); background: var(--income-bg); }
.rec-item-importe { font-weight: 500; font-size: 13.5px; font-variant-numeric: tabular-nums; flex-shrink: 0; }
.rec-item-importe.gasto { color: var(--expense-text); }
.rec-item-importe.ingreso { color: var(--income-text); }
.rec-item .tx-delete { flex-shrink: 0; }
.rec-nota { display: flex; align-items: flex-start; gap: 6px; font-size: 12px; color: var(--muted); margin-top: 16px; }

.rec-mes-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.rec-mes-card { display: flex; align-items: center; gap: 10px; background: var(--surface); border-radius: var(--radius-md); padding: 12px; min-width: 0; }
.rec-mes-card-icon { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 14px; flex-shrink: 0; }
.rec-mes-card.gasto .rec-mes-card-icon { color: var(--expense-text); background: var(--expense-bg); }
.rec-mes-card.ingreso .rec-mes-card-icon { color: var(--income-text); background: var(--income-bg); }
.rec-mes-card .kpi-value { font-size: 15px; margin-top: 2px; }

.rec-lista-header { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.rec-lista { display: flex; flex-direction: column; gap: 8px; }

@media (min-width: 860px) {
  .rec-layout { display: grid; grid-template-columns: 1.6fr 1fr; align-items: start; }
  .rec-badge { display: inline-flex; align-items: center; }
}

/* Calendario de vencimientos (Facturas). IMPORTANTE: las celdas usan una altura fija
   (var(--cal-cell)), nunca aspect-ratio:1 — en una cuadrícula de 7 columnas dentro de un
   panel ancho, aspect-ratio hace que cada celda sea tan alta como ancha (columnas de
   ~90-100px → celdas de ~90-100px de alto), disparando la altura del calendario entero. */
.cal-card { --cal-cell: 34px; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-grid-header { margin-bottom: 6px; text-align: center; font-size: 10.5px; color: var(--muted); font-weight: 600; letter-spacing: .02em; }
.cal-dia { height: var(--cal-cell); display: flex; flex-direction: column; align-items: center; justify-content: center; border-radius: 8px; font-size: 12.5px; color: var(--cream); }
.cal-dia-evento { background: var(--surface-alt); }
.cal-dia-hoy { background: var(--accent); color: #12131E; font-weight: 700; }
.cal-dia-dots { display: flex; gap: 2px; margin-top: 2px; line-height: 0; }
.cal-dia-dots i { width: 4px; height: 4px; border-radius: 50%; display: block; }
.cal-proximos { margin-top: 14px; display: flex; flex-direction: column; gap: 7px; }
.cal-proximo-item { display: flex; align-items: center; gap: 10px; font-size: 12.5px; }
.cal-proximo-dia { width: 26px; height: 26px; border-radius: 7px; background: var(--surface-alt); display: flex; align-items: center; justify-content: center; font-size: 11.5px; color: var(--muted); flex-shrink: 0; }
.cal-proximo-item span:nth-child(2) { flex: 1; color: var(--cream); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-proximo-importe { font-family: ui-monospace, monospace; flex-shrink: 0; }
@media (max-width: 480px) {
  .cal-card { --cal-cell: 30px; }
  .cal-dia { font-size: 11.5px; }
}

.ia-box { background: color-mix(in srgb, var(--accent) 8%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); border-radius: var(--radius-md); padding: 16px; margin-top: 16px; font-size: 13.5px; line-height: 1.6; white-space: pre-line; }
.ia-btn { width: 100%; padding: 13px 0; border-radius: var(--radius-md); border: 1px solid var(--accent); background: transparent; color: var(--accent); font-size: 14px; cursor: pointer; margin-top: 10px; font-weight: 500; transition: background .15s ease; }
.ia-btn:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); }

/* Modo inversión */
.badge-vivo { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--income-text); background: color-mix(in srgb, var(--income-text) 14%, transparent); border-radius: 20px; padding: 2px 8px; margin-left: 6px; vertical-align: middle; }
.badge-vivo::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: pulso-vivo 1.8s ease-in-out infinite; }
@keyframes pulso-vivo { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.inv-mercado-estado {
  display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 500; color: var(--muted);
  background: var(--surface); border-radius: 20px; padding: 6px 12px 6px 10px; margin-bottom: 14px;
}
.inv-mercado-estado .punto { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex-shrink: 0; }
.inv-mercado-estado.abierto { color: var(--income-text); }
.inv-mercado-estado.abierto .punto { background: var(--income-text); box-shadow: 0 0 0 3px color-mix(in srgb, var(--income-text) 20%, transparent); animation: pulso-vivo 1.8s ease-in-out infinite; }
.inv-mercado-estado.cerrado .punto { background: var(--expense-text); }
.inv-heatmap-card { background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); padding: 14px; margin-top: 2px; }
.inv-leyenda-card { background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); padding: 16px; margin-top: 14px; }
.inv-leyenda-item { display: flex; align-items: flex-start; gap: 10px; margin-top: 12px; }
.inv-leyenda-icon {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px; background: var(--surface-alt); color: var(--muted);
  display: flex; align-items: center; justify-content: center;
}
.inv-leyenda-icon svg { width: 16px; height: 16px; }
.inv-leyenda-item-titulo { font-size: 13px; font-weight: 600; }
.inv-leyenda-item-desc { font-size: 12px; color: var(--muted); line-height: 1.5; margin-top: 2px; }
.inv-leyenda-escala { margin: 10px 0 4px 40px; }
.inv-leyenda-escala span {
  display: block; height: 6px; border-radius: 4px;
  background: linear-gradient(90deg, var(--expense-text), var(--surface-alt) 50%, var(--income-text));
}
.inv-mover-card { flex: 1; min-width: 0; background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); padding: 10px 12px; border-left: 2px solid transparent; }
.inv-mover-card.up { border-left-color: var(--income-text); }
.inv-mover-card.down { border-left-color: var(--expense-text); }
.inv-disclaimer {
  display: flex; align-items: flex-start; gap: 8px; font-size: 12px; line-height: 1.5; color: var(--muted);
  background: color-mix(in srgb, var(--accent) 7%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 24%, transparent);
  border-radius: var(--radius-md); padding: 10px 12px; margin-bottom: 14px;
}
.inv-tabs { display: flex; gap: 8px; margin-bottom: 14px; overflow-x: auto; }
.inv-tab { flex: 0 0 auto; padding: 8px 14px; border-radius: var(--radius-md); border: 1px solid var(--divider); background: var(--surface); color: var(--muted); font-size: 13px; cursor: pointer; white-space: nowrap; font-family: inherit; }
.inv-tab.active { border-color: var(--accent); color: var(--cream); background: color-mix(in srgb, var(--accent) 16%, transparent); }

/* Tarjeta principal de la cartera: valor grande + variación de hoy, estilo hero como .balance-card */
.inv-hero {
  background: var(--surface); border-radius: var(--radius-lg); padding: 20px; box-shadow: var(--shadow-sm);
  position: relative; overflow: hidden; margin-bottom: 16px;
}
.inv-hero::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; background: linear-gradient(180deg, var(--accent), transparent 85%); }
[dir="rtl"] .inv-hero::before { left: auto; right: 0; }
.inv-hero-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.inv-hero-valor { font-family: 'Inter', sans-serif; font-weight: 500; letter-spacing: -0.02em; font-size: 32px; margin-top: 6px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.inv-hero-sub { font-size: 13.5px; font-weight: 500; margin-top: 6px; }
.inv-hero-sub.up { color: var(--income-text); }
.inv-hero-sub.down { color: var(--expense-text); }
.inv-hero-invertido { font-size: 12px; color: var(--muted); margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--divider); }
.inv-hero-pill {
  display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; white-space: nowrap;
  padding: 4px 10px; border-radius: 20px; font-variant-numeric: tabular-nums;
}
.inv-hero-pill.up { color: var(--income-text); background: color-mix(in srgb, var(--income-text) 14%, transparent); }
.inv-hero-pill.down { color: var(--expense-text); background: color-mix(in srgb, var(--expense-text) 14%, transparent); }

/* Pestaña "Noticias" de Modo Inversión: próximos eventos + última hora (ver
   includes/inversion_noticias.php y la función renderInversionNoticias() de app.js). */
.inv-eventos-lista, .inv-noticias-lista { display: flex; flex-direction: column; gap: 8px; }
.inv-evento-row { display: flex; align-items: center; gap: 14px; background: var(--surface); border-radius: var(--radius-md); padding: 12px 14px; }
.inv-evento-fecha { flex: 0 0 auto; text-align: center; width: 42px; }
.inv-evento-fecha .dia { font-size: 17px; font-weight: 600; line-height: 1.1; }
.inv-evento-fecha .mes { font-size: 10px; color: var(--muted); text-transform: uppercase; }
.inv-evento-info { flex-grow: 1; min-width: 0; }
.inv-evento-titulo { font-size: 13.5px; font-weight: 500; }
.inv-impacto-badge { flex: 0 0 auto; font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 20px; }
.inv-impacto-badge.alto { color: var(--expense-text); background: var(--expense-bg); }
.inv-impacto-badge.medio { color: var(--cream); background: color-mix(in srgb, var(--accent) 22%, transparent); }
.inv-impacto-badge.bajo { color: var(--muted); background: var(--surface-alt); }

.inv-noticia-card { background: var(--surface); border-radius: var(--radius-md); padding: 14px 16px; border-left: 2px solid var(--expense-text); }
.inv-noticia-cabecera { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.inv-noticia-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--expense-text); background: var(--expense-bg); border-radius: 20px; padding: 2px 8px; }
.inv-noticia-titular { font-size: 14.5px; font-weight: 600; }
.inv-noticia-resumen { font-size: 12.5px; color: var(--muted-2); line-height: 1.55; margin-top: 4px; white-space: normal; }
.inv-noticia-impacto { font-size: 12px; font-weight: 500; margin-top: 10px; }
.inv-noticia-guardar {
  margin-left: auto; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 8px; border: none; background: transparent; color: var(--muted);
  cursor: pointer; transition: color .15s ease, background .15s ease;
}
.inv-noticia-guardar:hover { background: var(--surface-alt); color: var(--cream); }
.inv-noticia-guardar svg { width: 16px; height: 16px; stroke: currentColor; fill: none; }
.inv-noticia-guardar.activa { color: var(--accent-300); }
.inv-noticia-guardar.activa svg { fill: var(--accent-300); }
.inv-not-vacio { text-align: center; padding: 32px 16px; color: var(--muted); font-size: 13px; }

.inv-posicion { background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); padding: 13px 14px; margin-bottom: 8px; cursor: pointer; transition: box-shadow .15s ease; }
.inv-posicion:hover { box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent); }
.inv-posicion-cabecera { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.inv-posicion-ficha { display: flex; align-items: center; gap: 10px; }
.inv-posicion-nombre { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.inv-posicion-avatar {
  flex: 0 0 auto; width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; letter-spacing: .01em; background: var(--surface-2); color: var(--muted);
}
.inv-posicion-avatar.up { color: var(--income-text); background: color-mix(in srgb, var(--income-text) 16%, transparent); }
.inv-posicion-avatar.down { color: var(--expense-text); background: color-mix(in srgb, var(--expense-text) 16%, transparent); }
.inv-posicion-detalle { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--divider); }
.inv-lote-row { display: flex; justify-content: space-between; align-items: center; font-size: 12.5px; color: var(--muted); padding: 5px 0; }
.inv-buscador-resultados { position: relative; }
.inv-buscador-lista { position: absolute; z-index: 5; left: 0; right: 0; top: 100%; background: var(--surface); border: 1px solid var(--divider); border-radius: var(--radius-md); max-height: 220px; overflow-y: auto; box-shadow: var(--shadow-sm); }
.inv-buscador-item { padding: 9px 12px; font-size: 13px; cursor: pointer; border-bottom: 1px solid var(--divider); }
.inv-buscador-item:last-child { border-bottom: none; }
.inv-buscador-item:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.ia-btn:disabled { opacity: 0.5; }

/* Tarjeta "Efectivo disponible" de Modo Inversión */
.inv-efectivo-valor { font-family: 'Inter', sans-serif; font-weight: 500; letter-spacing: -0.01em; font-size: 23px; margin: 4px 0 2px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.inv-efectivo-acciones { display: flex; gap: 8px; }
.inv-efectivo-acciones .inv-tab { flex: 1; text-align: center; margin-bottom: 0; }
.inv-efectivo-form-box { background: var(--surface-2); border-radius: var(--radius-md); padding: 12px; margin-top: 12px; }
.inv-efectivo-historial-link { display: inline-flex; align-items: center; gap: 3px; margin-top: 12px; font-size: 12.5px; color: var(--accent); text-decoration: none; cursor: pointer; }
.inv-efectivo-historial-link:hover { text-decoration: underline; }

/* Cabecera de Modo Inversión: título + subtítulo + botón "Registrar operación", por encima de
   las pestañas Cartera/Seguimiento/Mapa de calor/Noticias (inv-tabs). */
.inv-page-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }
.inv-page-title { font-size: 20px; font-weight: 600; letter-spacing: -0.01em; }
.inv-page-sub { font-size: 13px; color: var(--muted); margin-top: 4px; }
.inv-tabs-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.inv-tabs-row .inv-tabs { margin-bottom: 0; flex: 1 1 auto; }
.inv-tabs-row-btn { flex: 0 0 auto; padding: 0 16px; height: 40px; white-space: nowrap; }
@media (max-width: 560px) { .inv-tabs-row-btn { flex: 1 1 100%; order: -1; } }

/* Fila de 4 KPIs (valor de las posiciones, resultado acumulado, cambio de hoy, efectivo
   registrado) que sustituye al bloque .inv-hero suelto — mismo patrón que .rec-mes-card. */
.inv-kpi-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 16px; }
.inv-kpi-card { display: flex; align-items: flex-start; gap: 10px; background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); padding: 13px; min-width: 0; }
.inv-kpi-card-icon { width: 34px; height: 34px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 14px; flex-shrink: 0; background: var(--surface-alt); color: var(--muted); }
.inv-kpi-card-icon.up { color: var(--income-text); background: var(--income-bg); }
.inv-kpi-card-icon.down { color: var(--expense-text); background: var(--expense-bg); }
.inv-kpi-card-valor { font-size: 16px; font-weight: 500; margin-top: 2px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.inv-kpi-card-valor.up { color: var(--income-text); }
.inv-kpi-card-valor.down { color: var(--expense-text); }
@media (min-width: 720px) { .inv-kpi-grid { grid-template-columns: repeat(4, 1fr); } }

/* Buscador + filtros por encima de la lista de posiciones */
.inv-buscar-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.inv-buscar-row input { flex: 1; min-width: 160px; margin-bottom: 0; }
.inv-filtros { display: flex; gap: 6px; flex-wrap: wrap; }
.inv-filtro-btn { flex: 0 0 auto; padding: 0 14px; height: 44px; border-radius: var(--radius-md); border: 1px solid var(--divider); background: var(--surface); color: var(--muted); font-size: 13px; cursor: pointer; white-space: nowrap; font-family: inherit; }
.inv-filtro-btn.active { border-color: var(--accent); color: var(--cream); background: color-mix(in srgb, var(--accent) 16%, transparent); }

/* Cabecera de columnas de la tabla de posiciones — solo visible en escritorio, donde hay hueco
   para alinear las columnas con las filas (.inv-posicion-cabecera usa el mismo grid). En móvil
   cada fila ya se explica sola (símbolo, %, importe), así que la cabecera solo estorbaría. */
.inv-tabla-header { display: none; font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; padding: 0 14px; margin-bottom: 6px; }
/* En móvil la fila sigue siendo flex (ficha | precio actual | resultado%), como antes de
   convertir la lista en tabla — "Unidades" y "Precio medio" se ocultan como columnas propias
   porque ya van debajo del símbolo dentro de la ficha, y duplicarlas solo añadiría ruido. */
.inv-posicion-cabecera:not(.inv-seg-fila) > div:nth-child(2), .inv-posicion-cabecera:not(.inv-seg-fila) > div:nth-child(3) { display: none; }
.inv-posicion-cabecera:not(.inv-seg-fila) > div:nth-child(4) { margin-left: auto; text-align: right; }
.inv-posicion-cabecera:not(.inv-seg-fila) > div:nth-child(5) { text-align: right; }
@media (min-width: 720px) {
  .inv-posicion-cabecera:not(.inv-seg-fila) > div:nth-child(2), .inv-posicion-cabecera:not(.inv-seg-fila) > div:nth-child(3) { display: block; }
  .inv-posicion-cabecera:not(.inv-seg-fila) > div:nth-child(4) { margin-left: 0; }
  .inv-tabla-header:not(.inv-seg-tabla-header), .inv-posicion-cabecera:not(.inv-seg-fila) { grid-template-columns: 2fr 1fr 1fr 1fr 1fr; align-items: center; gap: 10px; }
  .inv-tabla-header:not(.inv-seg-tabla-header) { display: grid; }
  .inv-posicion-cabecera:not(.inv-seg-fila) { display: grid; }
  .inv-posicion-cabecera:not(.inv-seg-fila) > div:not(.inv-posicion-ficha) { text-align: right; }
}

/* Fila de la lista de Seguimiento: mismo look que .inv-posicion pero solo 4 columnas (empresa,
   precio, cambio del día, acciones) — en vez de reutilizar el grid de 5 de Cartera. */
.inv-seg-fila { padding: 0; }
.inv-seg-fila > div:not(.inv-posicion-ficha) { text-align: right; }
.inv-seg-fila > div:last-child { text-align: right; }
@media (min-width: 720px) {
  .inv-seg-tabla-header, .inv-seg-fila { grid-template-columns: 2fr 1fr 1fr 60px; align-items: center; gap: 10px; }
  .inv-seg-tabla-header { display: grid; }
  .inv-seg-fila { display: grid; }
}

/* Barra de efectivo, ahora al pie de la cartera (icono + valor + descripción a la izquierda,
   acciones de añadir/retirar a la derecha) en vez de tarjeta suelta arriba. */
.inv-cash-bar { display: flex; align-items: center; gap: 14px; background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 16px; margin-top: 16px; flex-wrap: wrap; }
.inv-cash-bar-icon { width: 44px; height: 44px; border-radius: 12px; background: var(--surface-alt); display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }
.inv-cash-bar-info { flex: 1; min-width: 200px; }
.inv-cash-bar-valor { font-size: 19px; font-weight: 500; font-variant-numeric: tabular-nums; }
.inv-cash-bar-acciones { display: flex; gap: 8px; flex: 0 0 auto; }
.inv-cash-bar-acciones .inv-tab { margin-bottom: 0; }

/* Auth / pricing pages */
.auth-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; }
.auth-card { width: 100%; max-width: 380px; background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); padding: 30px 26px; }
.auth-title { font-family: 'Inter', sans-serif; font-weight: 500; font-size: 22px; text-align: center; letter-spacing: -0.015em; }
.auth-subtitle { font-size: 13px; color: var(--muted); text-align: center; margin-top: 6px; margin-bottom: 22px; }
.auth-label { font-size: 12px; color: var(--muted); display: block; margin-bottom: 6px; margin-top: 12px; }
.auth-footer { text-align: center; font-size: 12.5px; color: var(--muted); margin-top: 20px; }
.auth-footer a { color: var(--accent); text-decoration: none; }
.auth-footer a:hover { text-decoration: underline; }

.plan-card { border: 1px solid var(--divider); border-radius: var(--radius-lg); padding: 22px; margin-top: 10px; background: var(--surface-alt); }
.plan-name { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 1px; font-weight: 500; }
.plan-price { font-weight: 500; font-size: 32px; margin-top: 6px; letter-spacing: -0.02em; }
.plan-price-block { min-height: 68px; }
.plan-price span { font-size: 13px; color: var(--muted); font-weight: 400; }
.plan-features { list-style: none; padding: 0; margin: 16px 0; font-size: 13.5px; color: var(--cream); line-height: 2; }

/* Bottom nav (mobile) */
nav.bottom-nav {
  position: sticky; bottom: 0; width: 100%;
  background: color-mix(in srgb, var(--surface) 94%, transparent); backdrop-filter: blur(16px);
  border-top: 1px solid var(--divider);
  display: flex; align-items: flex-end; justify-content: space-around;
  padding: 8px 6px max(10px, env(safe-area-inset-bottom));
}
nav.bottom-nav button {
  position: relative; z-index: 1;
  flex: 1; max-width: 76px; background: none; border: none; padding: 7px 4px 5px; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 3px; color: var(--muted);
  border-radius: 14px; transition: color .15s ease;
}
nav.bottom-nav button.active { color: var(--accent-300); }

/* Navegación líquida: una "gota" de cristal que se desliza (JS: moverIndicadorLiquido() en
   app.js) hasta quedar debajo del botón activo, con un rebote elástico en vez de un movimiento
   lineal — de ahí el efecto "líquido". No se aplica al botón central "+" (bottom-nav-fab), que ya
   flota como círculo propio por encima de la barra. */
.liquid-indicator {
  position: absolute; top: 6px; left: 0; height: calc(100% - 12px); width: 0; opacity: 0;
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 34%, transparent);
  border-radius: 16px; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 14%, transparent) inset,
              0 4px 16px color-mix(in srgb, var(--accent) 30%, transparent);
  pointer-events: none; z-index: 0; will-change: transform, width;
  transition: transform .5s cubic-bezier(.34, 1.56, .64, 1),
              width .5s cubic-bezier(.34, 1.56, .64, 1),
              opacity .2s ease;
}
@media (prefers-reduced-motion: reduce) { .liquid-indicator { transition: opacity .2s ease; } }
nav.bottom-nav button span:last-child {
  font-size: 10px; letter-spacing: 0.1px; white-space: nowrap;
  font-weight: 500;
}
nav.bottom-nav .nav-icon { line-height: 1; display: flex; align-items: center; justify-content: center; }
nav.bottom-nav .nav-icon svg { width: 20px; height: 20px; }

/* Botón central "Añadir": círculo elevado, flotando por encima de la barra */
nav.bottom-nav .bottom-nav-fab {
  flex: 0 0 auto; max-width: none; width: 52px; height: 52px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-300));
  box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 45%, transparent);
  margin: -22px 6px 0; padding: 0; align-items: center; justify-content: center;
  border: 3px solid var(--ink);
}
nav.bottom-nav .bottom-nav-fab:active { transform: scale(.94); }
nav.bottom-nav .bottom-nav-fab .nav-icon-plus { font-size: 26px; font-weight: 400; color: var(--ink); line-height: 1; }

/* ══════════════ Escritorio: barra lateral + reflow a paneles ══════════════ */
.sidebar { display: none; }

@media (min-width: 1024px) {
  body { align-items: flex-start; }
  #app { max-width: 1240px; flex-direction: row; min-height: 100vh; }

  .sidebar {
    display: flex; flex-direction: column; justify-content: space-between;
    width: 240px; flex-shrink: 0; padding: 18px 16px; border-right: 1px solid var(--divider);
    position: sticky; top: 0; height: 100vh;
    /* El espaciado de aquí abajo está pensado para que las 10 secciones + el bloque de usuario
       quepan sin scroll en la mayoría de ventanas (incluidas pantallas de portátil, más bajas de
       lo que parece por la barra de tareas/navegador). overflow-y: auto se deja como red de
       seguridad para ventanas todavía más bajas, no como solución principal. */
    overflow-y: auto;
  }
  .sidebar-top { display: flex; flex-direction: column; gap: 10px; }
  .sidebar-brand { font-family: 'Inter', sans-serif; font-weight: 500; font-size: 17px; padding: 0 8px; letter-spacing: -0.01em; }
  .sidebar-top .nav-btn.primary { padding: 12px 0; font-size: 14px; border-radius: var(--radius-lg); }
  .sidebar-nav { display: flex; flex-direction: column; gap: 1px; }
  .sidebar-section-title {
    font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
    color: var(--muted); padding: 14px 10px 4px;
  }
  .sidebar-section-title:first-child { padding-top: 4px; }
  .sidebar-nav button {
    position: relative;
    display: flex; align-items: center; gap: 12px; padding: 8px 10px; border-radius: var(--radius-md);
    background: none; border: none; color: var(--muted); font-size: 13.5px; font-weight: 500; cursor: pointer;
    text-align: left; font-family: inherit; transition: background .15s ease, color .15s ease;
  }
  .sidebar-nav button:hover { background: var(--surface); color: var(--cream); }
  .sidebar-nav button.active { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent-300); }
  /* Barra de acento pegada al borde izquierdo del propio sidebar (no del botón) para el item
     activo, a juego con el rediseño que agrupa la navegación en secciones. */
  .sidebar-nav button.active::before {
    content: ''; position: absolute; left: -16px; top: 50%; transform: translateY(-50%);
    width: 3px; height: 18px; border-radius: 0 3px 3px 0; background: var(--accent-300);
  }
  .sidebar-nav .nav-icon { width: 18px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
  .sidebar-nav .nav-icon svg { width: 18px; height: 18px; flex-shrink: 0; stroke: var(--cream); }
  .sidebar-nav button.active .nav-icon svg { stroke: var(--accent-300); }

  .sidebar-bottom { border-top: 1px solid var(--divider); padding-top: 10px; }
  .sidebar-user { display: flex; align-items: center; gap: 10px; padding: 6px 8px; }
  .sidebar-user .avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--accent); color: var(--accent-900); display: flex; align-items: center; justify-content: center; font-size: 13.5px; font-weight: 600; flex-shrink: 0; }
  .sidebar-user-info { flex: 1; min-width: 0; }
  .sidebar-user .name { font-size: 12.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .sidebar-user .plan { font-size: 11px; color: var(--muted); margin-top: 1px; }
  .sidebar-user .plan.plan-badge-pro {
    display: inline-block; background: var(--accent); color: var(--accent-900); font-weight: 600;
    border-radius: 20px; padding: 1px 9px; margin-top: 3px;
  }
  .sidebar-user-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
  .sidebar-icon-btn {
    width: 28px; height: 28px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
    background: none; border: none; color: var(--muted); line-height: 1; cursor: pointer;
    text-decoration: none; font-family: inherit; transition: background .15s ease, color .15s ease;
  }
  .sidebar-icon-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
  .sidebar-icon-btn:hover { background: var(--surface); color: var(--cream); }

  #app > header, #app > nav.bottom-nav { display: none; }
  .menu-item-solo-movil { display: none; }
  #app > main { flex: 1; padding: 40px 48px 60px; max-width: 900px; }
  #toast-alertas { max-width: 380px; right: 24px; left: auto; bottom: 24px; transform: none; }
  .lang-desktop-corner { display: flex; align-items: center; gap: 10px; position: fixed; top: 24px; right: 24px; z-index: 50; }

  .balance-card { padding: 26px 24px; }
  .balance-amount { font-size: 40px; }
  .kpi-grid { grid-template-columns: repeat(4, 1fr); }
  .option-grid { grid-template-columns: repeat(3, 1fr); }
  .auth-card { max-width: 420px; }

  /* En Patrimonio, cuando el gráfico de evolución no tiene al lado el donut de composición
     (usuarios con un único tipo de activo, p.ej. solo Modo Inversión), es el único hijo de
     .stats-charts-grid y antes se veía enorme — mucho más alto de lo que aporta. Se le pone un
     tope de ancho propio en vez de tocar .chart-block en general, así el resto de gráficas
     (Estadísticas, etc.) siguen ocupando el espacio que les corresponde. */
  .chart-block-patrimonio-evolucion { max-width: 420px; }
}

/* ══════════════ PWA instalada en escritorio: Window Controls Overlay ══════════════
   Con manifest.php pidiendo 'window-controls-overlay' (ver display_override), Windows/Chrome
   puede dibujar los botones de minimizar/maximizar/cerrar superpuestos en la esquina en vez de
   reservar una barra de título entera — así no se ve el borde grueso de arriba que había antes.
   Para que funcione hacen falta dos cosas: (1) una franja marcada como "arrastrable" del tamaño
   exacto que reporta env(titlebar-area-*), porque si no queda nada arrastrable la ventana no se
   puede mover con el ratón; y (2) que el resto de la app (sidebar, contenido, modales) NO quede
   marcado como arrastrable, para que los clics y el scroll con el ratón sigan funcionando igual
   que siempre. El <div class="titlebar-drag-strip"> vive justo tras <body> en app.php.
   Si el navegador/SO no soporta WCO (móvil, Firefox, Safari, o abierto como pestaña normal sin
   instalar), esta media query no aplica nada y la app se ve exactamente igual que antes. */
@media (display-mode: window-controls-overlay) {
  .titlebar-drag-strip {
    display: block; position: fixed; top: 0; left: env(titlebar-area-x, 0);
    width: env(titlebar-area-width, 100%); height: env(titlebar-area-height, 33px);
    -webkit-app-region: drag; app-region: drag; z-index: 999;
  }
  body { padding-top: env(titlebar-area-height, 0px); }
  @media (min-width: 1024px) {
    .sidebar {
      padding-top: calc(18px + env(titlebar-area-height, 0px));
      height: calc(100vh - env(titlebar-area-height, 0px));
    }
  }
}
.titlebar-drag-strip { display: none; }

/* ══════════════ RTL (árabe) ══════════════ */
[dir="rtl"] { text-align: right; }
[dir="rtl"] .balance-card::before { left: auto; right: 0; background: linear-gradient(180deg, var(--accent), transparent 85%); }
[dir="rtl"] .ledger { padding-left: 0; padding-right: 16px; }
[dir="rtl"] .ledger::before { left: auto; right: 4px; }
[dir="rtl"] .tx-dot { left: auto; right: -16px; }
[dir="rtl"] .amount-wrap .currency { right: auto; left: 16px; }
[dir="rtl"] .subview-back, [dir="rtl"] .auth-footer a, [dir="rtl"] .menu-item .arrow { transform: scaleX(-1); display: inline-block; }
[dir="rtl"] .switch input:checked + .slider::before { transform: translateX(-18px); }
[dir="rtl"] .switch .slider::before { left: auto; right: 3px; }
[dir="rtl"] .sidebar { border-right: none; border-left: 1px solid var(--divider); }
[dir="rtl"] .lang-desktop-corner { right: auto; left: 24px; }
[dir="rtl"] #toast-alertas { left: 14px; right: auto; transform: none; }
@media (min-width: 1024px) {
  [dir="rtl"] #toast-alertas { left: 24px; right: auto; bottom: 24px; }
}
[dir="rtl"] .sidebar-nav button { text-align: right; }
[dir="rtl"] .nav-icon { margin-left: 0; }
[dir="rtl"] .sidebar-nav button.active::before { left: auto; right: -16px; border-radius: 3px 0 0 3px; }


/* ══════════════ Páginas de marketing (landing + detalle de planes) ══════════════ */

  body { display: block; position: relative; overflow-x: hidden; }
  body::before {
    content: ''; position: fixed; top: -10%; left: 50%; transform: translateX(-50%);
    width: 900px; height: 500px; background: radial-gradient(ellipse, color-mix(in srgb, var(--accent) 16%, transparent), transparent 70%);
    pointer-events: none; z-index: 0;
  }
  .lp-wrap { max-width: 1320px; margin: 0 auto; padding: 0 32px; position: relative; z-index: 1; }
  .lp-nav {
    display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px;
    padding: 20px 32px; margin: 0 -32px; border-bottom: 1px solid var(--divider);
    position: sticky; top: 0; z-index: 50;
    background: color-mix(in srgb, var(--ink) 82%, transparent);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  }
  .lp-brand { font-family: 'Inter', sans-serif; font-weight: 500; font-size: 18px; letter-spacing: -0.01em; }
  .lp-nav-links { display: flex; align-items: center; gap: 24px; justify-content: center; }
  .lp-nav-actions { display: flex; align-items: center; gap: 10px; justify-content: flex-end; }
  /* Botón "menú" para móvil: en escritorio no se ve nunca (solo aparece dentro del media query de
     abajo, donde .lp-nav-links se oculta). Reutiliza el mismo patrón que la home (mv2-nav-toggle). */
  .lp-nav-toggle {
    display: none; align-items: center; justify-content: center; width: 34px; height: 34px;
    border-radius: var(--radius-md); border: 1px solid var(--divider); background: transparent;
    color: var(--cream); font-size: 16px; cursor: pointer; flex-shrink: 0; justify-self: start;
  }
  .lp-nav-toggle:hover { border-color: var(--accent); }
  .lp-nav-dropdown {
    display: none; flex-direction: column; gap: 2px; position: absolute; top: calc(100% + 8px); left: 0;
    min-width: 190px; padding: 6px; background: var(--surface); border: 1px solid var(--divider);
    border-radius: 12px; box-shadow: var(--shadow-md); z-index: 55;
  }
  .lp-nav-dropdown.abierto { display: flex; }
  .lp-nav-dropdown a { padding: 10px 12px; border-radius: 8px; font-size: 14px; color: var(--muted); text-decoration: none; }
  .lp-nav-dropdown a:hover { background: var(--surface-alt); color: var(--cream); }
  @media (max-width: 640px) {
    /* 3 columnas ahora (antes 2): logo, botón de menú, y las acciones empujadas al extremo derecho. */
    .lp-nav { grid-template-columns: auto auto 1fr; }
    .lp-nav-links { display: none; }
    .lp-nav-toggle { display: inline-flex; }
  }
  .lp-link { color: var(--muted); text-decoration: none; font-size: 14px; padding: 8px 4px; }
  .lp-link:hover { color: var(--cream); }
  .lp-btn {
    display: inline-flex; align-items: center; justify-content: center; padding: 9px 18px;
    border-radius: var(--radius-md); font-size: 14px; font-weight: 500; text-decoration: none;
    border: 1px solid var(--divider); color: var(--cream); transition: border-color .15s ease, transform .1s ease;
  }
  .lp-btn:hover { border-color: var(--accent); }
  .lp-btn:active { transform: scale(.97); }
  .lp-btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-900); }
  .lp-btn-primary:hover { filter: brightness(1.08); }

  .lp-hero { padding: 120px 0 100px; display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 80px; align-items: center; }
  .lp-eyebrow { color: var(--accent-300); font-size: 12px; letter-spacing: 1.2px; text-transform: uppercase; font-weight: 500; margin-bottom: 14px; }
  .lp-hero h1 { font-size: 54px; line-height: 1.08; letter-spacing: -0.02em; margin: 0 0 20px; }
  .lp-hero h1 span { color: var(--accent-300); }
  .lp-hero p { font-size: 17px; color: var(--muted-2); line-height: 1.6; max-width: 500px; margin: 0 0 28px; }
  .lp-hero-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
  .lp-hero-note { font-size: 12.5px; color: var(--muted); margin-top: 14px; }

  .lp-mock { background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 24px; }
  .lp-mock-label { font-size: 11px; color: var(--accent-300); text-transform: uppercase; letter-spacing: 1px; font-weight: 500; }
  .lp-mock-amount { font-size: 36px; font-weight: 500; letter-spacing: -0.02em; margin: 6px 0 16px; }
  .lp-mock-row { display: flex; justify-content: space-between; align-items: center; padding: 12px 0; border-top: 1px solid var(--divider); font-size: 13.5px; }
  .lp-mock-row:first-of-type { border-top: none; }
  .lp-mock-chart { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--divider); }
  .lp-mock-chart-label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .6px; margin-bottom: 10px; }

  .lp-section { padding: 80px 0; border-top: 1px solid var(--divider); }
  .lp-section h2 { font-size: 28px; letter-spacing: -0.015em; margin: 0 0 10px; }
  .lp-section-sub { color: var(--muted); font-size: 14.5px; max-width: 520px; margin-bottom: 40px; }
  .lp-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; }
  .icon-chip {
    width: 40px; height: 40px; border-radius: 11px; display: flex; align-items: center; justify-content: center;
    font-size: 19px; margin-bottom: 14px; background: color-mix(in srgb, var(--accent) 14%, transparent);
  }
  .lp-card { background: var(--surface); border-radius: var(--radius-lg); padding: 22px; box-shadow: var(--shadow-sm); transition: box-shadow .2s ease, transform .2s ease; }
  .lp-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
  .lp-card h3 { font-size: 16px; font-weight: 500; margin: 0 0 8px; }
  .lp-card p { font-size: 13.5px; color: var(--muted); line-height: 1.55; margin: 0; }

  .lp-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; counter-reset: paso; }
  .lp-step { position: relative; padding-left: 4px; }
  .lp-step::before {
    counter-increment: paso; content: counter(paso);
    display: flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; border-radius: 50%; margin-bottom: 16px;
    background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent-300);
    font-weight: 600; font-size: 14px;
  }
  .lp-step h3 { font-size: 15.5px; font-weight: 500; margin: 0 0 6px; }
  .lp-step p { font-size: 13.5px; color: var(--muted); line-height: 1.55; margin: 0; }

  .lp-faq { max-width: 720px; }
  .lp-faq details {
    border-bottom: 1px solid var(--divider); padding: 18px 0;
  }
  .lp-faq summary {
    cursor: pointer; font-size: 15px; font-weight: 500; list-style: none;
    display: flex; justify-content: space-between; align-items: center; gap: 12px;
  }
  .lp-faq summary::-webkit-details-marker { display: none; }
  .lp-faq summary::after { content: '+'; color: var(--accent-300); font-size: 20px; font-weight: 300; flex-shrink: 0; transition: transform .2s ease; }
  .lp-faq details[open] summary::after { transform: rotate(45deg); }
  .lp-faq p { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin: 12px 0 0; }

  .lp-plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; max-width: 920px; margin: 0 auto; }
  .lp-cta-band {
    text-align: center; padding: 70px 0; border-top: 1px solid var(--divider);
  }
  .lp-cta-band h2 { font-size: 30px; margin: 0 0 10px; letter-spacing: -0.015em; }
  .lp-cta-band p { color: var(--muted); margin: 0 0 26px; }

  .lp-footer { padding: 40px 0 50px; border-top: 1px solid var(--divider); display: flex; flex-direction: column; align-items: center; gap: 18px; }
  .lp-footer-links { display: flex; gap: 18px; flex-wrap: wrap; justify-content: center; }
  .lp-footer-links a { color: var(--muted); font-size: 12.5px; text-decoration: none; }
  .lp-footer-links a:hover { color: var(--cream); }
  .lp-footer-brand { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12.5px; }

  /* Pie de página "rico" (includes/marketing_footer.php): columnas de enlaces + copyright,
     en vez del único bloque centrado de antes. Se apoya en las mismas clases .lp-footer y
     .lp-footer-brand de arriba para no romper nada donde todavía no se use. */
  .lp-footer-rich { align-items: stretch; gap: 34px; }
  .lp-footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 28px; width: 100%; }
  .lp-footer-brand-col { display: flex; flex-direction: column; gap: 10px; }
  .lp-footer-rich .lp-footer-brand { font-size: 14px; color: var(--cream); font-weight: 600; }
  .lp-footer-tagline { margin: 0; color: var(--muted); font-size: 12.5px; line-height: 1.6; max-width: 280px; }
  .lp-footer-col { display: flex; flex-direction: column; gap: 10px; }
  .lp-footer-col-title { font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--cream); opacity: 0.6; }
  .lp-footer-col a { color: var(--muted); font-size: 12.5px; text-decoration: none; }
  .lp-footer-col a:hover { color: var(--cream); }
  .lp-footer-bottom { width: 100%; padding-top: 22px; border-top: 1px solid var(--divider); text-align: center; color: var(--muted); font-size: 11.5px; }
  @media (max-width: 760px) {
    .lp-footer-grid { grid-template-columns: 1fr 1fr; text-align: left; }
    .lp-footer-brand-col { grid-column: 1 / -1; }
  }

  .lp-reveal { opacity: 0; transform: translateY(16px); transition: opacity .6s ease, transform .6s ease; }
  .lp-reveal.lp-visible { opacity: 1; transform: translateY(0); }
  @media (prefers-reduced-motion: reduce) { .lp-reveal { opacity: 1; transform: none; transition: none; } }

  @media (max-width: 760px) {
    .lp-hero { grid-template-columns: 1fr; padding: 50px 0 40px; text-align: left; }
    .lp-hero h1 { font-size: 32px; }
    .lp-plans { grid-template-columns: 1fr; }
    .lp-steps { grid-template-columns: 1fr; }
    .lp-nav-actions .lp-link { display: none; }
  }

/* ---- Páginas de detalle de plan ---- */
.pd-hero {
  padding: 52px 0 36px; text-align: center; max-width: 560px; margin: 0 auto;
}
.pd-badge {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 12px; border-radius: 20px;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent-300);
  font-size: 11.5px; font-weight: 500; letter-spacing: .4px; margin-bottom: 12px;
}
.pd-hero h1 { font-size: 28px; letter-spacing: -0.02em; margin: 0 0 10px; line-height: 1.16; }
.pd-hero .pd-price { font-family: 'Inter', sans-serif; font-size: 15px; color: var(--muted-2); margin-bottom: 14px; }
.pd-hero .pd-price strong { font-size: 27px; color: var(--cream); font-weight: 500; letter-spacing: -0.02em; }
.pd-hero p { font-size: 14.5px; color: var(--muted-2); line-height: 1.5; margin: 0 auto 18px; max-width: 460px; }

.pd-trust-row {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 18px;
  margin: 22px auto 4px; font-size: 12px; color: var(--muted);
}
.pd-trust-row span { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }

.pd-feature-row {
  display: grid; grid-template-columns: 42px 1fr; gap: 14px; padding: 16px 0;
  border-top: 1px solid var(--divider); align-items: start;
}
.pd-feature-row:first-of-type { border-top: none; }
.pd-feature-row .pd-icon {
  width: 36px; height: 36px; border-radius: 10px; display: flex; align-items: center; justify-content: center;
  font-size: 17px; background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.pd-feature-row h3 { font-size: 15px; font-weight: 500; margin: 2px 0 4px; }
.pd-feature-row p { font-size: 13.5px; color: var(--muted); line-height: 1.55; margin: 0; max-width: 560px; }

.pd-compare { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.pd-compare th, .pd-compare td { padding: 10px 12px; text-align: center; border-bottom: 1px solid var(--divider); }
.pd-compare th { font-weight: 500; color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .4px; }
.pd-compare td:first-child, .pd-compare th:first-child { text-align: left; color: var(--cream); }
.pd-compare .pd-col-actual { background: color-mix(in srgb, var(--accent) 7%, transparent); border-left: 1px solid var(--accent); border-right: 1px solid var(--accent); }
.pd-compare .yes { color: var(--income-text); }
.pd-compare .no { color: var(--muted); }

.pd-example {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 420px); gap: 52px; align-items: center;
}
.pd-example .lp-mock { max-width: none; }

.pd-plans-switch { display: flex; justify-content: center; gap: 8px; margin: 20px 0 4px; flex-wrap: wrap; }
.pd-plans-switch a {
  padding: 6px 14px; border-radius: 20px; font-size: 12.5px; text-decoration: none;
  border: 1px solid var(--divider); color: var(--muted);
}
.pd-plans-switch a.pd-activo { border-color: var(--accent); color: var(--accent-300); background: color-mix(in srgb, var(--accent) 12%, transparent); }

@media (max-width: 640px) {
  .pd-hero h1 { font-size: 24px; }
  .pd-feature-row { grid-template-columns: 1fr; }
  .pd-compare { font-size: 12px; }
  .pd-example { grid-template-columns: 1fr; gap: 24px; }
}

/* ---- Banner del código promocional diario (plan familiar) ---- */
.promo-familiar-banner {
  position: relative; display: flex; align-items: center; justify-content: center;
  padding: 10px 44px; background: linear-gradient(90deg, var(--accent-900), color-mix(in srgb, var(--accent) 32%, var(--accent-900)));
  color: var(--cream); font-size: 13px; text-align: center;
}
.promo-familiar-inner { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: center; }
.promo-familiar-text a { color: inherit; text-decoration: underline; }
.promo-familiar-code {
  display: inline-flex; align-items: center; gap: 6px; font-weight: 600; letter-spacing: .4px;
  padding: 5px 12px; border-radius: 20px; border: 1px dashed color-mix(in srgb, var(--cream) 50%, transparent);
  background: color-mix(in srgb, var(--cream) 12%, transparent); color: var(--cream);
  cursor: pointer; font-size: 13px; font-family: inherit;
}
.promo-familiar-code:hover { background: color-mix(in srgb, var(--cream) 22%, transparent); }
.promo-familiar-copy-icon { font-size: 12px; opacity: .8; }
.promo-familiar-note { font-size: 11px; opacity: .75; }
.promo-familiar-close {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  background: none; border: none; color: var(--cream); opacity: .7; cursor: pointer; font-size: 14px; padding: 6px;
}
.promo-familiar-close:hover { opacity: 1; }
@media (max-width: 640px) {
  .promo-familiar-banner { padding: 10px 38px 10px 12px; font-size: 12px; }
  .promo-familiar-note { display: none; }
}

/* ---- Página de características: zigzag + cuadrícula ---- */
.feat-zigzag {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 60px; align-items: center;
  padding: 90px 0; border-top: 1px solid var(--divider);
}
.feat-zigzag-text h2 { margin-bottom: 18px; }
.feat-zigzag-text p { margin-bottom: 16px; }
.feat-zigzag-text p:last-of-type { margin-bottom: 0; }
.feat-zigzag:first-of-type { border-top: none; }
.feat-zigzag:nth-of-type(even) .feat-zigzag-text { order: 2; }
.feat-zigzag-icon {
  width: 52px; height: 52px; border-radius: 15px; display: flex; align-items: center; justify-content: center;
  font-size: 24px; background: color-mix(in srgb, var(--accent) 16%, transparent); margin-bottom: 18px;
}
.feat-zigzag h2 { font-size: 24px; letter-spacing: -0.01em; margin: 0 0 12px; }
.feat-zigzag p { font-size: 14.5px; color: var(--muted); line-height: 1.65; margin: 0 0 10px; }
.feat-zigzag-example {
  background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  padding: 22px; position: relative;
}
.feat-zigzag-example::before {
  content: ''; position: absolute; inset: -20px; z-index: -1; border-radius: 24px;
  background: radial-gradient(circle at 30% 30%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 70%);
}

/* ---- Página de características: selector de pestañas ---- */
.feat-tabs {
  display: flex; gap: 8px; margin-bottom: 28px; flex-wrap: wrap;
}
.feat-tab {
  flex: 1; min-width: 150px; display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 12px; border-radius: var(--radius-md); border: 1px solid var(--divider);
  background: var(--surface); color: var(--cream); font-size: 14px; font-weight: 500;
  cursor: pointer; transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.feat-tab .feat-tab-icon { font-size: 17px; }
.feat-tab:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--divider)); }
.feat-tab.active {
  background: var(--accent); border-color: var(--accent); color: var(--accent-900); font-weight: 600;
}
.feat-tab-panel {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 60px; align-items: center;
  background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  padding: 44px 48px;
}
.feat-tab-panel.hidden { display: none; }
.feat-tab-panel .feat-zigzag-icon { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.feat-tab-panel .feat-zigzag-example { box-shadow: none; }
.feat-tab-panel .feat-zigzag-example::before { content: none; }

@media (max-width: 760px) {
  .feat-tab-panel { grid-template-columns: 1fr; gap: 28px; padding: 30px 24px; }
  .feat-tab { min-width: 44%; font-size: 13px; padding: 12px 8px; }
}

.feat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.feat-card {
  background: var(--surface); border-radius: var(--radius-lg); padding: 24px;
  box-shadow: var(--shadow-sm); transition: box-shadow .2s ease, transform .2s ease;
}
.feat-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.feat-card h3 { font-size: 15px; font-weight: 500; margin: 0 0 8px; }
.feat-card p { font-size: 13px; color: var(--muted); line-height: 1.55; margin: 0; }

@media (max-width: 760px) {
  .feat-zigzag { grid-template-columns: 1fr; gap: 28px; padding: 56px 0; }
  .feat-zigzag:nth-of-type(even) .feat-zigzag-text { order: 0; }
  .feat-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
  .feat-grid { grid-template-columns: 1fr; }
}

/* ============ Blog: listado y artículos ============ */
.blog-list { display: flex; flex-direction: column; gap: 14px; margin-top: 24px; }
.blog-card {
  display: flex; align-items: flex-start; gap: 20px;
  padding: 22px 24px; background: var(--surface-alt);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  text-decoration: none; color: inherit; border: 1px solid transparent;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.blog-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--accent-800); }
.blog-card-icon {
  flex: 0 0 auto; width: 46px; height: 46px; border-radius: var(--radius-md);
  background: linear-gradient(135deg, var(--accent-600), var(--accent-400));
  display: flex; align-items: center; justify-content: center; font-size: 20px;
}
.blog-card-body { flex: 1; min-width: 0; }
.blog-card-meta { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; flex-wrap: wrap; }
.blog-card-tag {
  font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--accent-300); background: var(--accent-900); padding: 3px 9px; border-radius: 20px;
}
.blog-card-date { font-size: 12px; color: var(--muted); }
.blog-card h3 { font-size: 17px; font-weight: 600; margin: 0 0 6px; letter-spacing: -0.01em; }
.blog-card p { font-size: 13.5px; color: var(--muted); line-height: 1.55; margin: 0; }
.blog-card-arrow { flex: 0 0 auto; align-self: center; color: var(--muted); font-size: 20px; transition: transform .18s ease, color .18s ease; }
.blog-card:hover .blog-card-arrow { transform: translateX(4px); color: var(--accent-300); }
@media (max-width: 560px) {
  .blog-card { flex-direction: column; gap: 12px; padding: 18px; }
  .blog-card-arrow { display: none; }
}

.blog-back-link {
  display: inline-flex; align-items: center; gap: 6px; font-size: 13px;
  color: var(--muted); text-decoration: none; margin-bottom: 22px;
  transition: color .15s ease;
}
.blog-back-link:hover { color: var(--accent-300); }
.blog-tag-row { display: flex; gap: 10px; align-items: center; margin-bottom: 12px; flex-wrap: wrap; }

/* ============ FAQ (acordeón nativo con <details>) ============ */
.faq-list { max-width: 720px; margin: 0 auto; display: flex; flex-direction: column; gap: 10px; }
.faq-item {
  background: var(--surface-alt); border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm); padding: 4px 20px;
}
.faq-item summary {
  cursor: pointer; list-style: none; padding: 16px 0;
  font-size: 15px; font-weight: 500; display: flex; justify-content: space-between; align-items: center; gap: 12px;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: '+'; font-size: 20px; color: var(--muted); flex: 0 0 auto; transition: transform .18s ease; }
.faq-item[open] summary::after { transform: rotate(45deg); }

/* Partículas ambientales de temporada (ver assets/js/tema-particulas.js) — flotan/caen por
   encima de toda la página pero nunca bloquean clics ni tapan al modal (que va en z-index 100). */
.tema-particulas-contenedor { position: fixed; inset: 0; pointer-events: none; z-index: 40; overflow: hidden; opacity: 1; transition: opacity 1.4s ease; }
.tema-particulas-contenedor.tema-particulas-desvanecer { opacity: 0; }
.tema-particula { position: absolute; top: -40px; will-change: transform, opacity; line-height: 1; }
.tema-particula.caer { animation-name: tema-particula-caer; animation-timing-function: linear; animation-iteration-count: infinite; }
.tema-particula.flotar { top: auto; bottom: -40px; animation-name: tema-particula-flotar; animation-timing-function: ease-in-out; animation-iteration-count: infinite; }
@keyframes tema-particula-caer {
  0%   { transform: translateY(0) translateX(0) rotate(0deg); }
  100% { transform: translateY(110vh) translateX(26px) rotate(200deg); }
}
@keyframes tema-particula-flotar {
  0%   { transform: translateY(0) translateX(0); opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { transform: translateY(-110vh) translateX(-18px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .tema-particulas-contenedor { display: none; } }
.faq-item p { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin: 0 0 18px; }

/* Cajas animadas para códigos de un solo uso (2FA obligatorio, restablecer 2FA, verificación por
   correo...) — ver assets/js/otp-boxes.js. */
.otp-boxes { display: flex; gap: 10px; justify-content: center; margin: 18px 0; }
.otp-boxes input {
  width: 46px; height: 56px; text-align: center; font-size: 22px; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--cream); background: var(--surface);
  border: 1.5px solid var(--divider); border-radius: 12px; outline: none;
  transition: border-color .18s ease, box-shadow .18s ease, transform .12s ease;
}
.otp-boxes input:focus {
  border-color: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 22%, transparent);
}
.otp-boxes input.otp-filled { border-color: var(--accent); animation: otp-pop .18s ease; }
/* Código correcto: todas las cajas se iluminan en verde antes de dejar pasar. */
.otp-boxes.otp-success input {
  border-color: var(--income); color: var(--income);
  background: color-mix(in srgb, var(--income) 14%, var(--surface));
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--income) 22%, transparent),
              0 0 18px color-mix(in srgb, var(--income) 45%, transparent);
  animation: otp-pop .22s ease;
}
/* Código incorrecto: al revés — todas las cajas en rojo con un pequeño tembleque, y luego se
   vacían solas para volver a intentarlo (ver marcarError() en otp-boxes.js). */
.otp-boxes.otp-error input {
  border-color: var(--expense); color: var(--expense-text);
  background: color-mix(in srgb, var(--expense) 12%, var(--surface));
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--expense) 22%, transparent),
              0 0 18px color-mix(in srgb, var(--expense) 45%, transparent);
  animation: otp-shake .32s ease;
}
@keyframes otp-pop {
  0% { transform: scale(1); }
  45% { transform: scale(1.12); }
  100% { transform: scale(1); }
}
@keyframes otp-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-6px); }
  75% { transform: translateX(6px); }
}
@media (max-width: 420px) {
  .otp-boxes { gap: 7px; }
  .otp-boxes input { width: 38px; height: 48px; font-size: 19px; }
}

/* ============ Enlace "saltar al contenido" (accesibilidad) ============
   Compartido por app.php, includes/marketing_nav.php y includes/admin_layout.php: primer elemento
   enfocable de la página, invisible hasta que alguien navega con Tab (así no estorba visualmente a
   nadie que use ratón, pero deja saltarse la barra lateral/menú a quien navega por teclado o con
   lector de pantalla). Apunta siempre a #main-content. */
.skip-link {
  position: absolute; z-index: 200; top: -100px; left: 16px;
  padding: 12px 20px; background: var(--accent); color: var(--accent-900);
  border-radius: 10px; text-decoration: none; font-size: 13px; font-weight: 600;
  transition: top .15s ease;
}
.skip-link:focus { top: 12px; }

/* ============ Botón "volver arriba" ============
   Aparece flotando abajo a la derecha en cuanto se hace scroll (ver initBackToTop() en app.js /
   assets/js/marketing.js), y se coloca por encima del bottom-nav en móvil usando la misma zona
   segura que ya usa #toast-alertas. En páginas sin bottom-nav (marketing) simplemente usa el hueco
   normal abajo a la derecha. */
.back-to-top {
  position: fixed; z-index: 45;
  right: 16px; bottom: calc(84px + env(safe-area-inset-bottom, 0px));
  width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--divider);
  background: var(--surface); color: var(--cream); box-shadow: var(--shadow-lg);
  display: flex; align-items: center; justify-content: center; font-size: 17px; cursor: pointer;
  opacity: 0; pointer-events: none; transform: translateY(8px);
  transition: opacity .2s ease, transform .2s ease, border-color .15s ease;
}
.back-to-top.visible { opacity: 1; pointer-events: auto; transform: translateY(0); }
.back-to-top:hover { border-color: var(--accent); color: var(--accent-300); }
body:not(.tiene-bottom-nav) .back-to-top { bottom: 20px; }
@media (prefers-reduced-motion: reduce) { .back-to-top { transition: opacity .2s ease; } }

/* ============ Estados de carga (cursor + botones) ============
   body.cursor-espera se añade/quita desde apiCall() en app.js mientras hay una petición en curso
   que no tiene ya su propio spinner visual — así el cursor deja claro que "algo está pasando" en
   vez de parecer que la app se ha quedado colgada. .btn-cargando es para un botón concreto: apaga
   su contenido y muestra un spinner en su lugar, sin cambiar el tamaño del botón. */
body.cursor-espera, body.cursor-espera * { cursor: wait !important; }
.btn-cargando { position: relative; color: transparent !important; pointer-events: none; }
.btn-cargando::after {
  content: ''; position: absolute; top: 50%; left: 50%; width: 16px; height: 16px;
  margin: -8px 0 0 -8px; border-radius: 50%; border: 2px solid currentColor; color: var(--cream);
  border-top-color: transparent; animation: btn-spin .7s linear infinite;
}
.nav-btn.primary.btn-cargando::after, .nav-btn.danger.btn-cargando::after { color: var(--accent-900); }
.nav-btn.danger.btn-cargando::after { color: #fff; }
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .btn-cargando::after { animation-duration: 1.4s; } }

/* ============ Mostrar/ocultar contraseña ============ */
.pw-field-wrap { position: relative; }
.pw-field-wrap .input-field { padding-right: 46px; margin-bottom: 12px; }
.pw-toggle {
  position: absolute; top: 0; right: 0; bottom: 12px; width: 42px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; color: var(--muted); cursor: pointer; padding: 0;
}
.pw-toggle:hover { color: var(--cream); }
.pw-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 6px; }
.pw-toggle svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.pw-toggle .pw-icon-oculta { display: block; }
.pw-toggle .pw-icon-visible { display: none; }
.pw-toggle[aria-pressed="true"] .pw-icon-oculta { display: none; }
.pw-toggle[aria-pressed="true"] .pw-icon-visible { display: block; }

/* ============ Botón de copiar (genérico) ============
   Variante compacta e icono-solo del patrón "Copiar" que ya usaba el enlace de referidos
   (assets/js/app.js) — para pegar junto a datos puntuales (número de factura, código, email...)
   sin ocupar una fila entera. Mismo truco de "✓ Copiado" temporal vía JS, aquí solo cambia el
   icono en vez del texto (copiarBoton() en app.js). */
.copy-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  border: 1px solid var(--divider); background: var(--surface); color: var(--muted);
  border-radius: 8px; padding: 5px 9px; font-size: 11.5px; font-family: inherit; cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.copy-btn:hover { border-color: var(--accent); color: var(--accent-300); }
.copy-btn.copiado { border-color: var(--income); color: var(--income-text); }
.copy-btn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }

/* ============ Modal de confirmación (reutiliza #modal-overlay / #modal-analisis) ============
   Variante de #modal-analisis para "¿seguro que quieres...?" — la usa confirmarAccion() en
   app.js como reemplazo de confirm() nativo (bloquea el hilo y no se puede estilar) para las
   acciones irreversibles: borrar transacciones/metas/deudas/facturas/categorías/recurrentes,
   quitar a alguien de familia, revocar dispositivos de confianza y desactivar 2FA. */
#modal-analisis.modal-confirmar { max-width: 360px; }
#modal-analisis.modal-confirmar .modal-body { margin-bottom: 4px; }
.modal-confirmar-acciones { display: flex; gap: 8px; margin-top: 18px; }
.modal-confirmar-acciones .nav-btn { flex: 1; margin: 0; width: auto; }

/* ============ Aviso de "novedades" (punto "Qué hay de nuevo") ============ */
.updates-dot {
  position: absolute; top: 2px; right: 2px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 0 2px var(--surface);
}
#modal-analisis.modal-novedades .modal-title { display: flex; align-items: center; gap: 8px; }
.novedad-fecha { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .3px; margin: 0 0 10px; }
.novedad-cuerpo { font-size: 13.5px; line-height: 1.7; color: var(--cream); white-space: pre-line; }

/* ============ Botón "Vídeo recomendado" (aviso animado junto al selector de idioma) ============
   El admin mantiene la lista en Admin → Vídeos recomendados (ver includes/videos_recomendados.php);
   la app rota sola por los vídeos activos cada 2 días y enseña uno cada vez aquí. El botón se queda
   oculto (atributo [hidden], puesto en el PHP) hasta que app.js confirma que hay un vídeo activo que
   enseñar — así nunca aparece vacío si el admin todavía no ha añadido ninguno. */
.video-rec-btn {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%; padding: 0;
  background: var(--surface); border: 1px solid var(--divider); box-shadow: var(--shadow-sm);
  color: var(--accent-300); cursor: pointer; position: relative; flex-shrink: 0;
  transition: border-color .15s ease, background .15s ease, transform .15s ease;
}
.video-rec-btn:hover { border-color: var(--accent); background: var(--surface-alt); transform: scale(1.06); }
.video-rec-btn svg { width: 16px; height: 16px; margin-left: 1px; }
.video-rec-btn[hidden] { display: none; }

.video-rec-dot {
  position: absolute; top: -2px; right: -2px; width: 11px; height: 11px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--bg, var(--surface)); display: none;
}
/* Solo anima mientras el usuario no haya abierto todavía el vídeo que toca ahora — en cuanto lo
   abre una vez (abrirVideoRecomendado() en app.js) se le quita la clase y deja de llamar la
   atención, hasta que la rotación pase al siguiente vídeo de la lista. */
.video-rec-btn.nuevo .video-rec-dot { display: block; animation: video-rec-pulso 1.8s ease-in-out infinite; }
.video-rec-btn.nuevo { animation: video-rec-anillo 1.8s ease-in-out infinite; }
@keyframes video-rec-pulso {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); }
  50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 0%, transparent); }
}
@keyframes video-rec-anillo {
  0%, 100% { border-color: var(--divider); }
  50% { border-color: var(--accent); }
}
@media (prefers-reduced-motion: reduce) {
  .video-rec-btn.nuevo, .video-rec-btn.nuevo .video-rec-dot { animation: none; }
}

#modal-analisis.modal-video-recomendado .modal-title { display: flex; align-items: center; gap: 8px; }
.video-rec-desc { font-size: 13.5px; line-height: 1.6; color: var(--cream); margin: 10px 0 18px; white-space: pre-line; }
.video-rec-link {
  display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: 10px;
  background: var(--surface-alt); color: var(--accent-300); text-decoration: none; font-size: 13.5px; font-weight: 500;
  transition: background .15s ease;
}
.video-rec-link:hover { background: color-mix(in srgb, var(--accent) 14%, var(--surface-alt)); }
.video-rec-link svg { width: 18px; height: 18px; flex-shrink: 0; }

/* ============ Hoja de estilo para imprimir ============
   Pensada sobre todo para app.php (informes, historial, presupuesto...) pero escrita con
   selectores compartidos por las páginas de marketing también, así una sola hoja cubre todo el
   sitio. Oculta navegación, botones de acción, modales y cualquier elemento marcado con
   .no-print; muestra en su sitio lo que lleve .print-only (por ejemplo la fecha del informe). */
@media print {
  .sidebar, .bottom-nav, header, #toast-alertas, #modal-overlay, .skip-link, .back-to-top,
  .lp-nav, .lp-nav-dropdown, .lp-footer, .nav-btn, .csv-btn, .copy-btn, .pw-toggle,
  .no-print, #service-worker-update-banner { display: none !important; }
  .print-only { display: block !important; }
  body, #app, main { background: #fff !important; color: #000 !important; }
  * { box-shadow: none !important; text-shadow: none !important; }
  a { color: #000 !important; text-decoration: underline; }
  .admin-card, .ia-box, .kpi-card { border: 1px solid #ccc !important; background: #fff !important; break-inside: avoid; }
}
.print-only { display: none; }
