/* ─────────────────────────────────────────────────────────────
   Design tokens — fuente de verdad: DESIGN.md (estilo Soft SaaS)
   Regla: ningún color/radio/sombra hardcodeado fuera de aquí.
   ───────────────────────────────────────────────────────────── */
:root {
  --bg: #F1F1F8;
  --surface: #FFFFFF;
  --surface-2: #F7F7FC;
  --brand: #3F9FE8;       /* celeste BeMo (acento por defecto; ver data-accent) */
  --brand-soft: #DFEFFB;
  --sidebar: var(--brand); /* fondo del menú lateral; en modo oscuro se atenúa (menos brillo) */
  --navy: #1B1C4D;
  --ink: #23244D;
  --muted: #9295AD;
  --line: #E8E9F2;
  --green: #57AD8D;
  --green-soft: #DFF2EA;
  --red: #ED6E75;
  --red-soft: #FBE3E5;
  --amber: #E9A23B;
  --amber-soft: #FBF0DD;
  --cyan-soft: #DFF0F7;
  --violet: #7c3aed;

  --radius: 20px;        /* tarjetas y paneles (radius-lg) */
  --radius-md: 14px;     /* inputs, tiles */
  --radius-btn: 10px;    /* botones: rectángulo redondeado con más carácter (no píldora) */
  --radius-pill: 999px;
  --content-w: 1280px;   /* ancho máximo del contenido (centrado en pantallas anchas) */
  --shadow: 0 8px 28px rgba(27, 28, 77, .07);       /* shadow-card */
  --shadow-pop: 0 16px 44px rgba(27, 28, 77, .14);
}

/* ─────────────────────────────────────────────────────────────
   Temas: cada modo solo redefine tokens (data-theme en <html>).
   Se eligen desde el dial de configuración; persisten en el equipo.
   ───────────────────────────────────────────────────────────── */
:root[data-theme="oscuro"] {
  --bg: #101117; --surface: #191B24; --surface-2: #22242F;
  --brand: #7D7DF2; --brand-soft: #2B2C4D; --navy: #5B5BF0;
  --sidebar: color-mix(in srgb, var(--brand) 40%, #15161e); /* menú atenuado: lindo pero no brillante */
  --ink: #E9EBF5; --muted: #8D91A8; --line: #2B2E3C;
  --grid: rgba(255, 255, 255, .05); /* cuadrícula de gráficas: muy tenue en oscuro */
  --green: #5FC09A; --green-soft: #1D3A30; --red: #F08089; --red-soft: #462329;
  --amber: #E7AC52; --amber-soft: #413319; --cyan-soft: #1D3340;
  --shadow: 0 8px 28px rgba(0, 0, 0, .45); --shadow-pop: 0 16px 44px rgba(0, 0, 0, .6);
}
:root[data-theme="atenuado"] {
  --bg: #16171B; --surface: #1D1E24; --surface-2: #24252C;
  --brand: #8C8CC8; --brand-soft: #2A2B3A; --navy: #6A6AB0;
  --sidebar: color-mix(in srgb, var(--brand) 34%, #1a1b22);
  --ink: #C9CCD6; --muted: #7C7F8E; --line: #2A2B33;
  --grid: rgba(255, 255, 255, .045); /* cuadrícula de gráficas: muy tenue en atenuado */
  --green: #6FA890; --green-soft: #20312B; --red: #C9858C; --red-soft: #3A282B;
  --amber: #C2A06A; --amber-soft: #383022; --cyan-soft: #243038;
  --shadow: 0 8px 28px rgba(0, 0, 0, .35); --shadow-pop: 0 16px 44px rgba(0, 0, 0, .5);
}
:root[data-theme="gris"] {
  --bg: #ECEDEF; --surface: #FFFFFF; --surface-2: #F4F5F7;
  --brand: #5B6172; --brand-soft: #E3E5EA; --navy: #2A2D35;
  --ink: #26282E; --muted: #8A8E99; --line: #E2E4E8;
  --cyan-soft: #E7EAEE;
}
:root[data-theme="rosa"] {
  --bg: #FBF1F5; --surface: #FFFFFF; --surface-2: #FCF6F9;
  --brand: #E0639A; --brand-soft: #FADCE9; --navy: #8D2F5C;
  --ink: #4A2238; --muted: #B58CA0; --line: #F3DEE8;
  --red: #E05A6E; --red-soft: #FBE3E7; --cyan-soft: #F4E4F8;
  --shadow: 0 8px 28px rgba(141, 47, 92, .08); --shadow-pop: 0 16px 44px rgba(141, 47, 92, .16);
}
:root[data-theme="tornasol"] {
  --bg: #F0F2FA; --surface: #FFFFFF; --surface-2: #F6F5FC;
  --brand: #8A66E8; --brand-soft: #EBE4FB; --navy: #3B2D72;
  --ink: #2C2750; --muted: #9694B5; --line: #E7E6F4;
  --green: #4FB39C; --green-soft: #DFF4EE; --cyan-soft: #DFEEF9;
  --shadow: 0 8px 28px rgba(89, 70, 180, .09); --shadow-pop: 0 16px 44px rgba(89, 70, 180, .18);
}
/* El tornasol lleva un velo iridiscente muy sutil sobre el fondo */
:root[data-theme="tornasol"] body {
  background-image: linear-gradient(120deg, rgba(138, 102, 232, .05), rgba(95, 179, 255, .05) 35%, rgba(255, 173, 226, .06) 70%, rgba(255, 233, 170, .05));
  background-attachment: fixed;
}

/* ─────────────────────────────────────────────────────────────
   Acentos (data-accent en <html>): recolorean la pestaña principal,
   el dial y todo lo que use --brand, en cualquier tema. El tinte
   suave se deriva del acento y la superficie del tema activo.
   ───────────────────────────────────────────────────────────── */
:root[data-accent="indigo"] { --brand: #6C6CE5; }
:root[data-accent="violeta"] { --brand: #8A66E8; }
:root[data-accent="ciruela"] { --brand: #8B5C9E; }
:root[data-accent="esmeralda"] { --brand: #2FA98C; }
:root[data-accent="turquesa"] { --brand: #1FA39B; }
:root[data-accent="ambar"] { --brand: #CF8A33; }
:root[data-accent="coral"] { --brand: #F07B6E; }
:root[data-accent="vino"] { --brand: #A83246; }
:root[data-accent="grafito"] { --brand: #5B6172; }
:root[data-accent] { --brand-soft: color-mix(in srgb, var(--brand) 15%, var(--surface)); }

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* Sin efecto "rebote" ni scroll encadenado al llegar al borde de la página
   (también desactiva el pull-to-refresh accidental en móvil). */
html, body { overscroll-behavior-y: none; }
body {
  margin: 0; min-height: 100vh; background: var(--bg); color: var(--ink);
  font: 14px/1.5 "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.hidden { display: none !important; }

/* ─────────────────────────────────────────────────────────────
   Login BeMo F: campo de partículas azules sobre negro profundo
   (canvas, reacciona al cursor — referencia: antigravity.google)
   y tarjeta de cristal oscuro flotante con tilt 3D (js/login-fx.js).
   ───────────────────────────────────────────────────────────── */
.login-screen {
  position: fixed; inset: 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: #020308; /* negro profundo: las partículas viven en el canvas */
}
#login-canvas { position: absolute; inset: 0; }

/* Tarjeta de cristal sobre papel: deja ver la tinta marmoleada detrás */
.login-stage { position: relative; perspective: 1000px; }
.login-card {
  position: relative; width: min(420px, 92vw); padding: 38px 38px 24px;
  display: flex; flex-direction: column;
  background: rgba(16, 18, 26, .58);
  -webkit-backdrop-filter: blur(28px) saturate(140%); backdrop-filter: blur(28px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, .1); border-radius: 24px;
  box-shadow: 0 40px 90px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .08);
  color: #f2f4f8; will-change: transform; cursor: default;
  /* solo "backwards": al terminar, la animación suelta el control y el tilt 3D (JS) toma la tarjeta */
  animation: cardIn 1.1s cubic-bezier(.22, .8, .3, 1) backwards;
}
@keyframes cardIn {
  from { opacity: 0; transform: translateY(28px) scale(.96); filter: blur(10px); }
}

/* Control segmentado (estilo Apple): el thumb blanco se desliza a la pestaña activa */
.seg {
  position: relative; display: grid; grid-template-columns: 1fr 1fr;
  background: rgba(255, 255, 255, .07); border: 1px solid rgba(255, 255, 255, .08);
  border-radius: var(--radius-pill); padding: 4px; margin-bottom: 26px;
}
.seg-thumb {
  position: absolute; top: 4px; bottom: 4px; left: 4px; width: calc(50% - 4px);
  background: #fff; border-radius: var(--radius-pill);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
  transition: transform .35s cubic-bezier(.22, .8, .3, 1);
}
.seg-btn {
  position: relative; z-index: 1; border: 0; background: none; cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 700; padding: 9px 6px;
  color: rgba(242, 244, 248, .6); border-radius: var(--radius-pill);
  transition: color .3s ease;
}
.seg-btn:hover { color: rgba(242, 244, 248, .85); }
.seg-btn.active { color: #0c0d12; cursor: default; }

/* Fila final del formulario: recuperar contraseña + CTA */
.login-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 4px; }
.login-row .login-btn { margin-left: auto; } /* sin el enlace (modo registro), el CTA sigue a la derecha */
.forgot-link { font-size: 12.5px; font-weight: 600; color: rgba(242, 244, 248, .42); text-decoration: none; transition: color .25s ease, opacity .3s ease, transform .3s ease; }
.forgot-link:hover { color: #8ab1ff; }
/* En el registro el enlace se desvanece con un pequeño desplazamiento (no display:none). */
.forgot-link.desvanecido { opacity: 0; transform: translateX(-8px); pointer-events: none; }

/* Revelado del campo "Confirma la contraseña": altura REAL vía grid 0fr→1fr. */
.field-reveal {
  display: grid; grid-template-rows: 0fr; opacity: 0;
  transition: grid-template-rows .42s cubic-bezier(.22, .8, .3, 1), opacity .32s ease;
}
.field-reveal.open { grid-template-rows: 1fr; opacity: 1; }
.field-reveal-in { overflow: hidden; min-height: 0; padding-top: 12px; }
.login-brand {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  margin-bottom: 24px;
}
.brand-word { display: inline-flex; align-items: center; gap: 8px; font-size: 24px; font-weight: 800; letter-spacing: -.3px; color: #fff; }
/* La "F" ENCERRADA: la marca de la casa — chip redondeado con degradado celeste,
   brillo superior y sombra de color (misma F del resto de la familia). */
.brand-word em {
  font-style: normal; font-weight: 800; font-size: 18px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 9px;
  background: linear-gradient(135deg, #4db1ff, #2e5cff);
  color: #fff;
  box-shadow: 0 8px 22px rgba(63, 159, 232, .45), inset 0 1px 0 rgba(255, 255, 255, .35);
}
.brand-sub {
  font-size: 10.5px; font-weight: 600; letter-spacing: .22em; text-transform: uppercase;
  color: rgba(242, 244, 248, .38);
}
/* Saludo bajo la marca: cambia con la pestaña activa (crossfade en syncAuthMode). */
.login-hi {
  margin: -8px 0 20px; text-align: center;
  font-size: 15px; font-weight: 600; color: rgba(242, 244, 248, .78);
  transition: opacity .16s ease, transform .16s ease;
}
.login-hi.swap { opacity: 0; transform: translateY(6px); }

/* Campos minimalistas: línea base + etiqueta flotante + subrayado azul */
.lfield { position: relative; margin-bottom: 26px; }
.lfield input {
  width: 100%; background: transparent; border: 0; border-radius: 0;
  border-bottom: 1px solid rgba(242, 244, 248, .18);
  padding: 13px 2px 11px; color: #f2f4f8; font-size: 14.5px; caret-color: #8ab1ff;
  transition: border-color .4s ease;
}
.lfield input:focus { outline: none; background: transparent; border-color: rgba(242, 244, 248, .08); }
.lfield::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px;
  background: linear-gradient(90deg, #2e5cff, #8ab1ff 60%, rgba(138, 177, 255, 0));
  transform: scaleX(0); transform-origin: left;
  transition: transform .55s cubic-bezier(.22, .8, .3, 1);
}
.lfield:focus-within::after { transform: scaleX(1); }
.lfield label {
  position: absolute; left: 2px; top: 13px; pointer-events: none;
  font-size: 14px; color: rgba(242, 244, 248, .4);
  transition: top .35s cubic-bezier(.22, .8, .3, 1), font-size .35s, color .35s, letter-spacing .35s;
}
.lfield input:focus + label,
.lfield input:not(:placeholder-shown) + label {
  top: -11px; font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: rgba(242, 244, 248, .55);
}
.lfield input:-webkit-autofill {
  -webkit-text-fill-color: #f2f4f8;
  -webkit-box-shadow: 0 0 0 1000px rgba(18, 21, 32, .95) inset;
  transition: background-color 9999s ease-out;
}

/* CTA blanco (como el pill de la referencia) + lienzo para el efecto magnético (JS) */
.login-btn, .btn.login-btn {
  padding: 12px 36px; font-size: 13.5px; font-weight: 700;
  border-radius: var(--radius-pill);
  background: #fff !important; color: #0c0d12;
  box-shadow: 0 10px 30px rgba(140, 170, 255, .22);
  will-change: transform; transition: box-shadow .4s ease, filter .3s ease;
}
.login-btn:hover { box-shadow: 0 14px 40px rgba(140, 170, 255, .38); filter: none; }
.login-sep { border: 0; border-top: 1px solid rgba(255, 255, 255, .08); margin: 22px 0 0; }
.login-foot {
  margin-top: 16px; font-size: 10.5px; letter-spacing: .03em;
  color: rgba(242, 244, 248, .3); text-align: center;
  display: flex; flex-direction: column; gap: 3px;
}
.login-legal a { color: rgba(138, 177, 255, .75); text-decoration: none; font-weight: 600; transition: color .25s ease; }
.login-legal a:hover { color: #8ab1ff; }
.login-card code { background: rgba(255, 255, 255, .12); padding: 1px 5px; border-radius: 5px; font-size: 12px; }

/* Entrada a la demo: pill oscuro con borde degradado azul (la opción llamativa) */
.demo-btn {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; margin-top: 16px; padding: 11px; cursor: pointer;
  font-family: inherit; font-size: 12.5px; font-weight: 600; color: #dfe7ff;
  border: 1px solid transparent; border-radius: var(--radius-pill);
  background:
    linear-gradient(rgba(14, 17, 28, .92), rgba(14, 17, 28, .92)) padding-box,
    linear-gradient(120deg, #2e5cff, #8ab1ff, #2e5cff) border-box;
  transition: box-shadow .3s ease, transform .2s ease, filter .25s ease;
}
.demo-btn svg { width: 14px; height: 14px; color: #8ab1ff; }
.demo-btn:hover {
  transform: translateY(-1px); filter: brightness(1.2);
  box-shadow: 0 10px 34px rgba(60, 105, 255, .3);
}

/* Login en pantallas angostas: la tarjeta respira con menos padding */
@media (max-width: 760px) {
  .login-card { padding: 28px 24px 18px; }
}

@media (prefers-reduced-motion: reduce) {
  .login-card { animation: none; }
}

/* ─────────────────────────────────────────────────────────────
   Pestaña de navegación: blob índigo en el borde izquierdo,
   centrado vertical, con curvas orgánicas donde nace del borde.
   Tooltips: etiqueta pill flotante al hacer hover en cada icono.
   ───────────────────────────────────────────────────────────── */
.app { display: block; }

.sidebar {
  position: fixed; left: 0; top: 50%; transform: translateY(-50%);
  width: 74px; padding: 18px 13px;
  background: var(--sidebar); border-radius: 0 30px 30px 0;
  box-shadow: 10px 14px 34px color-mix(in srgb, var(--sidebar) 32%, transparent);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  z-index: 40;
}
/* Curvas suaves arriba y abajo (radio invertido hacia el borde) */
.sidebar::before, .sidebar::after {
  content: ''; position: absolute; left: 0; width: 30px; height: 30px; pointer-events: none;
}
.sidebar::before { top: -30px; background: radial-gradient(circle at 100% 0, rgba(0,0,0,0) 29.5px, var(--sidebar) 30px); }
.sidebar::after { bottom: -30px; background: radial-gradient(circle at 100% 100%, rgba(0,0,0,0) 29.5px, var(--sidebar) 30px); }

#nav { display: flex; flex-direction: column; gap: 6px; }
.nav-item, .logout-btn {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 46px; height: 44px; border: 0; border-radius: var(--radius-md);
  background: none; color: rgba(255, 255, 255, .92); cursor: pointer;
  transition: background .15s ease, color .15s ease, transform .15s ease;
}
/* flex:none — el icono NO se encoge al contraerse el menú (la etiqueta oculta lo aplastaba a ~8px). */
.nav-item svg, .logout-btn svg { width: 21px; height: 21px; flex: none; stroke-width: 2.4px; }
.nav-item:hover, .logout-btn:hover { background: rgba(255, 255, 255, .16); color: #fff; transform: translateY(-1px); }
.nav-item.active {
  background: var(--surface); color: var(--brand);
  box-shadow: 0 8px 18px rgba(27, 28, 77, .22);
}
/* Iconos inactivos en BLANCO pleno (no .92) para que destaquen sobre cualquier acento,
   incluido grafito/gris donde el trazo fino se perdía. El activo conserva su color de marca. */
.nav-item:not(.active), .logout-btn { color: #fff; }

/* Etiqueta flotante (pill) con el nombre del módulo */
.nav-label {
  position: absolute; left: calc(100% + 14px); top: 50%;
  transform: translateY(-50%) translateX(-6px);
  background: var(--navy); color: #fff;
  font-size: 12px; font-weight: 700; white-space: nowrap;
  padding: 7px 14px; border-radius: var(--radius-pill);
  box-shadow: var(--shadow-pop);
  opacity: 0; pointer-events: none;
  transition: opacity .16s ease, transform .16s ease;
}
.nav-item:hover .nav-label, .logout-btn:hover .nav-label {
  opacity: 1; transform: translateY(-50%) translateX(0);
}

.sidebar-foot {
  display: flex; flex-direction: column; align-items: center;
  padding-top: 10px; margin-top: 4px; border-top: 1px solid rgba(255, 255, 255, .25);
}

/* Acceso al panel de administración: separado con un hairline, solo lo ve el admin */
.nav-item.admin-link { margin-top: 8px; }
.nav-item.admin-link::before {
  content: ''; position: absolute; top: -7px; left: 8px; right: 8px;
  border-top: 1px solid rgba(255, 255, 255, .25);
}

/* ---------- Menú lateral extensible (solo escritorio) ----------
   Modos (clase en #app-root): menu-iconos (compacto, pill flotante al hover · por defecto del CSS),
   menu-fijo (siempre extendido) y menu-hover (se extiende al pasar el cursor).
   Clave anti-parpadeo: en los modos extensibles la etiqueta SIEMPRE es texto inline (nunca vuelve a
   pill flotante); al abrir/cerrar solo crece/encoge su ancho + opacidad. El icono queda fijo a la
   izquierda con padding constante (no salta). El botón "Personalización" (.tema-btn) NO se incluye:
   sigue siendo un satélite circular con su pill flotante al hover. */
.sidebar { transition: width .24s cubic-bezier(.2, .8, .2, 1); }
/* Disparador del modo hover: NO expandir cuando se pasa solo por el botón Personalización
   (con :has) — eso evitaba el temblor al acercarse a él. */
.app.menu-fijo .sidebar,
.app.menu-hover #sidebar:hover:not(:has(.tema-btn:hover)) { width: 228px; }
.app.menu-hover #nav, .app.menu-fijo #nav,
.app.menu-hover .sidebar-foot, .app.menu-fijo .sidebar-foot { width: 100%; align-items: stretch; }
.app.menu-hover #nav .nav-item, .app.menu-hover .sidebar-foot .logout-btn,
.app.menu-fijo #nav .nav-item, .app.menu-fijo .sidebar-foot .logout-btn {
  width: 100%; justify-content: flex-start; padding: 0 13px;
}
/* Etiqueta inline (oculta = ancho 0 + opacidad 0; visible al expandir). */
.app.menu-hover :is(#nav, .sidebar-foot) .nav-label,
.app.menu-fijo :is(#nav, .sidebar-foot) .nav-label {
  position: static; transform: none; box-sizing: border-box;
  background: none; box-shadow: none; color: inherit; pointer-events: none;
  white-space: nowrap; overflow: hidden; font-weight: 650; font-size: 13px; letter-spacing: -.01em;
  min-width: 0; max-width: 0; padding-left: 0; opacity: 0;
  transition: max-width .24s cubic-bezier(.2, .8, .2, 1), padding-left .24s, opacity .18s ease;
}
.app.menu-fijo :is(#nav, .sidebar-foot) .nav-label,
.app.menu-hover #sidebar:hover:not(:has(.tema-btn:hover)) :is(#nav, .sidebar-foot) .nav-label {
  max-width: 172px; padding-left: 12px; opacity: 1;
}
/* En modo fijo el contenido se corre para dejar sitio; en hover el menú se superpone (no reflow). */
.app.menu-fijo .content { margin-left: max(254px, calc((100% - var(--content-w)) / 2)); transition: margin-left .24s ease; }
/* Modo hover: al extenderse el menú, el contenido se corre a la derecha para que NO lo tape
   (solo donde habría choque; en pantallas anchas el max() lo deja igual). */
.app.menu-hover #sidebar:hover:not(:has(.tema-btn:hover)) ~ .content {
  margin-left: max(252px, calc((100% - var(--content-w)) / 2));
}
.field-hint { font-size: 11.5px; color: var(--muted); margin: 5px 0 0; }

/* ---------- Contenido ---------- */
/* Contenido centrado: en pantallas anchas el espacio sobrante se reparte a ambos lados
   (no todo a la derecha); en medianas sigue despejando el sidebar flotante (~102px). */
.content {
  max-width: var(--content-w);
  margin-left: max(102px, calc((100% - var(--content-w)) / 2));
  margin-right: auto;
  padding: 22px 30px;
  transition: margin-left .24s ease;
}
.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; }
.topbar h1 { font-size: 23px; font-weight: 800; margin: 0; }
.topbar .btn svg { width: 15px; height: 15px; vertical-align: -2px; }
.topbar-right { display: flex; align-items: center; gap: 10px; }
.user-chip {
  background: var(--surface); border: 1px solid var(--line); color: var(--muted);
  font-size: 12px; font-weight: 600; padding: 7px 14px; border-radius: var(--radius-pill);
}
.user-chip.demo { background: var(--amber-soft); border-color: var(--amber-soft); color: var(--amber); }

.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin-bottom: 22px; }
.kpi { background: var(--surface); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow); }
.kpi .label { color: var(--muted); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.kpi .value { font-size: 24px; font-weight: 800; margin-top: 6px; font-variant-numeric: tabular-nums; }
.kpi .value.green { color: var(--green); } .kpi .value.red { color: var(--red); }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.card {
  background: var(--surface); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow);
  transition: box-shadow .18s ease, transform .18s ease;
}
.card h3 { margin: 0 0 4px; font-size: 15px; }
.card .sub { color: var(--muted); font-size: 12px; }
.card-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 8px; font-size: 13px; }
.card-row .k { color: var(--muted); }
.card-row .k svg { width: 14px; height: 14px; vertical-align: -2px; margin-right: 5px; opacity: .8; }
/* Patrimonio · composición en dos columnas (activos | pasivos) */
.patrim-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 6px 30px; }
.patrim-col-h { font-weight: 800; font-size: 13px; margin: 2px 0 2px; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
/* Vínculo deuda↔patrimonio: ajuste "¿Sumar a tu patrimonio?" + aviso de posible doble conteo */
.patrim-toggle { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); }
.patrim-toggle-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.patrim-toggle-label { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: var(--ink); }
.patrim-toggle-label svg { width: 14px; height: 14px; opacity: .7; flex: none; }
.patrim-toggle-help { margin: 6px 0 0; font-size: 11.5px; line-height: 1.45; color: var(--muted); }
/* Switch on/off (botón, no checkbox: al tocarlo dispara la API y re-renderiza) */
.patrim-switch { display: inline-flex; align-items: center; gap: 8px; padding: 4px 0; background: none; border: 0; cursor: pointer; font-family: inherit; flex: none; }
.patrim-switch .ps-track { position: relative; width: 40px; height: 23px; background: var(--line); border-radius: 999px; transition: background .18s ease; flex: none; }
.patrim-switch .ps-knob { position: absolute; top: 3px; left: 3px; width: 17px; height: 17px; background: #fff; border-radius: 50%; box-shadow: 0 1px 3px rgba(27, 28, 77, .25); transition: transform .18s ease; }
.patrim-switch.on .ps-track { background: var(--green); }
.patrim-switch.on .ps-knob { transform: translateX(17px); }
.patrim-switch .ps-state { font-size: 12.5px; font-weight: 700; color: var(--muted); transition: color .18s ease; }
.patrim-switch.on .ps-state { color: var(--green); }
.patrim-warn { display: flex; align-items: flex-start; gap: 6px; margin-top: 8px; padding: 8px 10px; border-radius: var(--radius-md); background: var(--amber-soft); color: var(--amber); font-size: 11.5px; line-height: 1.4; }
.patrim-warn svg { width: 14px; height: 14px; flex: none; margin-top: 1px; }
/* Inventario de activos: filas de ítems en el detalle (nombre + compra/venta + ganancia) */
.inv-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.inv-row:last-of-type { border-bottom: none; }
.inv-name { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.inv-sub { font-size: 11.5px; color: var(--muted); }
.inv-acts { display: flex; gap: 4px; flex: none; }
/* Estados de cuenta importados: chips de estados (incluir/excluir + eliminar) y asistente CSV */
.est-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.est-chip { display: inline-flex; align-items: stretch; border-radius: var(--radius-btn); overflow: hidden; border: 1px solid var(--line); background: var(--surface-2); }
.est-chip.off { opacity: .55; }
.est-chip-tog { background: none; border: 0; color: var(--ink); font: inherit; font-size: 12.5px; font-weight: 600; padding: 7px 11px; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; }
.est-chip-tog svg { width: 14px; height: 14px; }
.est-chip-n { background: var(--brand-soft); color: var(--brand); border-radius: 999px; padding: 1px 7px; font-size: 11px; font-weight: 700; }
.est-chip-del { background: none; border: 0; border-left: 1px solid var(--line); color: var(--muted); font-size: 16px; line-height: 1; padding: 0 9px; cursor: pointer; }
.est-chip-del:hover { color: var(--red); background: var(--red-soft); }
.ie-modal { width: min(760px, 94vw); }
.ie-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px 14px; }
.ie-lbl { display: block; font-size: 12px; font-weight: 600; color: var(--muted); margin-bottom: 4px; }
.ie-h { font-size: 13px; font-weight: 800; margin: 16px 0 8px; }
/* Filtros tipo pestaña (Informes): texto, una línea divisoria fina entre secciones
   seleccionables, y un puntito de acento con brillo bajo el activo. Mismo lenguaje para
   las secciones (Resumen/Flujo/…) y para los elementos (suscripciones, tarjetas, cuentas). */
.filt-tabs { display: flex; flex-wrap: wrap; gap: 2px 22px; align-items: center; margin: 12px 0 2px; }
.filt-tabs.filt-el { margin-bottom: 12px; }
.filt-tab { background: none; border: 0; padding: 6px 2px 13px; font-family: inherit; font-size: 14px; font-weight: 600; letter-spacing: -.01em; color: var(--muted); cursor: pointer; position: relative; transition: color .15s ease; }
.filt-tab:hover { color: var(--ink); }
.filt-tab.on { color: var(--ink); font-weight: 700; }
/* Divisoria clara centrada en el hueco entre opciones (indica que son seleccionables) */
.filt-tab:not(:first-child)::before { content: ''; position: absolute; left: -11px; top: 7px; bottom: 13px; border-left: 1px solid var(--line); }
.filt-tab.on::after { content: ''; position: absolute; left: 50%; bottom: 4px; transform: translateX(-50%); width: 6px; height: 6px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 7px 1px var(--brand); }
/* Informe en móvil: las secciones se pliegan tras un botón (en escritorio siempre visibles) */
.rep-filtros-toggle { display: none; }
.rep-filtros-n { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--brand); background: var(--brand-soft); border-radius: 999px; padding: 2px 9px; }
@media (max-width: 760px) {
  .rep-filtros-toggle {
    display: flex; align-items: center; gap: 9px; width: 100%; min-height: 46px;
    padding: 10px 14px; margin: 14px 0 0; border: 1px solid var(--line);
    border-radius: 12px; background: var(--surface); color: var(--ink);
    font-family: inherit; font-size: 14px; font-weight: 700; cursor: pointer;
  }
  .rep-filtros-toggle > span:first-child { display: inline-flex; align-items: center; gap: 8px; }
  .rep-filtros-toggle svg { width: 18px; height: 18px; }
  .rep-filtros-toggle > svg { color: var(--muted); transition: transform .2s ease; }
  .rep-filtros-toggle.open > svg { transform: rotate(180deg); }
  .filt-tabs.rep-filtros { display: none; margin-top: 0; padding: 12px 13px 6px; gap: 8px 18px;
    border: 1px solid var(--line); border-top: 0; border-radius: 0 0 12px 12px; }
  .filt-tabs.rep-filtros.abierto { display: flex; }
  .rep-filtros-toggle.open { border-radius: 12px 12px 0 0; }
}
/* Calculadora rápida: cajón colapsable al borde derecho (solo escritorio) */
.calc-drawer { position: fixed; right: 0; top: 50%; transform: translate(248px, -50%); z-index: 90; display: flex; align-items: center; transition: transform .32s cubic-bezier(.4, .7, .2, 1); }
.calc-drawer.open { transform: translate(0, -50%); }
/* Pestaña pequeña con el color del menú (--brand); se asienta centrada, no estirada */
.calc-tab { width: 32px; height: 60px; flex: none; align-self: center; border: 0; border-radius: 13px 0 0 13px; background: var(--brand); color: #fff; cursor: pointer; display: grid; place-items: center; box-shadow: -8px 0 24px rgba(0, 0, 0, .28); transition: filter .14s ease, width .14s ease; }
.calc-tab:hover { filter: brightness(1.06); width: 35px; }
.calc-drawer.open .calc-tab { border-radius: 13px 0 0 13px; }
.calc-tab svg { width: 17px; height: 17px; }
.calc-panel { width: 248px; box-sizing: border-box; background: var(--surface); border: 1px solid var(--line); border-right: 0; border-radius: 0 0 0 18px; padding: 14px; box-shadow: var(--shadow-pop); }
.calc-display { background: var(--surface-2); border-radius: 12px; padding: 12px 14px; margin-bottom: 12px; text-align: right; }
.calc-expr { font-size: 12px; color: var(--muted); min-height: 15px; font-family: 'Space Mono', ui-monospace, monospace; word-break: break-all; }
.calc-out { font-size: 26px; font-weight: 800; color: var(--ink); font-family: 'Space Mono', ui-monospace, monospace; word-break: break-all; line-height: 1.15; }
.calc-keys { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.calc-keys button { border: 0; border-radius: 12px; background: var(--surface-2); color: var(--ink); font-size: 16px; font-weight: 600; padding: 13px 0; cursor: pointer; transition: filter .12s ease, transform .08s ease; }
.calc-keys button:hover { filter: brightness(1.08); }
.calc-keys button:active { transform: scale(.93); }
.calc-keys .k-op { color: var(--brand); }
.calc-keys .k-fn { color: var(--muted); font-size: 14px; }
.calc-keys .k-eq { background: var(--brand); color: #fff; }
@media (max-width: 860px) { .calc-drawer { display: none; } }

/* Notas rápidas: cajón colapsable al borde derecho, arriba de la calculadora */
.notas-drawer { position: fixed; right: 0; top: 84px; z-index: 91; display: flex; align-items: flex-start; transform: translate(320px, 0); transition: transform .32s cubic-bezier(.4, .7, .2, 1); }
.notas-drawer.open { transform: translate(0, 0); }
.notas-tab { width: 32px; height: 60px; flex: none; margin-top: 8px; border: 0; border-radius: 13px 0 0 13px; background: var(--brand); color: #fff; cursor: pointer; display: grid; place-items: center; box-shadow: -8px 0 24px rgba(0, 0, 0, .28); transition: filter .14s ease, width .14s ease; }
.notas-tab:hover { filter: brightness(1.06); width: 35px; }
.notas-tab svg { width: 17px; height: 17px; }
.notas-panel { width: 320px; box-sizing: border-box; background: var(--surface); border: 1px solid var(--line); border-right: 0; border-radius: 0 0 0 18px; box-shadow: var(--shadow-pop); display: flex; flex-direction: column; max-height: min(72vh, 620px); }
.notas-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--line); flex: none; }
.notas-title { display: flex; align-items: center; gap: 7px; font-weight: 800; font-size: 14px; color: var(--ink); }
.notas-title svg { width: 16px; height: 16px; color: var(--brand); }
.notas-add { width: 30px; height: 30px; border: 0; border-radius: 9px; background: var(--surface-2); color: var(--brand); cursor: pointer; display: grid; place-items: center; transition: filter .12s ease, transform .08s ease; }
.notas-add:hover { filter: brightness(1.06); }
.notas-add:active { transform: scale(.92); }
.notas-add svg { width: 16px; height: 16px; }
.notas-list { overflow-y: auto; padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.notas-empty { color: var(--muted); font-size: 13px; text-align: center; padding: 22px 6px; line-height: 1.5; }
.nota { border: 1px solid var(--line); border-radius: 14px; background: var(--surface-2); padding: 11px 12px; display: flex; gap: 10px; align-items: flex-start; transition: border-color .16s ease, box-shadow .16s ease; }
.nota:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(79, 169, 238, .16); }
.nota-done { flex: 0 0 auto; width: 18px; height: 18px; margin-top: 4px; border: 2px solid var(--line); border-radius: 50%; background: transparent; cursor: pointer; display: grid; place-items: center; padding: 0; transition: border-color .14s ease; }
.nota-done::after { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--brand); transform: scale(0); transition: transform .14s ease; }
.nota.done .nota-done { border-color: var(--brand); }
.nota.done .nota-done::after { transform: scale(1); }
.nota-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.nota-text { width: 100%; box-sizing: border-box; border: 0; background: transparent; resize: none; outline: none; color: var(--ink); font: inherit; font-size: 13.5px; line-height: 1.5; overflow: hidden; min-height: 24px; padding: 2px 0; }
.nota-text::placeholder { color: var(--muted); }
.nota.done .nota-text { text-decoration: line-through; color: var(--muted); }
/* Nota larga colapsada a 3 líneas: se desvanece abajo para indicar que hay más. */
.nota.nota-colapsada .nota-text { -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent); mask-image: linear-gradient(to bottom, #000 62%, transparent); }
.nota-exp { align-self: stretch; margin-top: 4px; height: 16px; border: 0; background: transparent; color: var(--muted); cursor: pointer; display: grid; place-items: center; padding: 0; }
.nota-exp[hidden] { display: none; } /* el atributo hidden debe ganar al display:grid */
.nota-exp:hover { color: var(--brand); }
.nota-exp svg { width: 14px; height: 14px; transition: transform .16s ease; }
.nota-exp.abierto svg { transform: rotate(180deg); }
.nota-del { flex: 0 0 auto; width: 24px; height: 24px; border: 0; border-radius: 7px; background: transparent; color: var(--muted); cursor: pointer; display: grid; place-items: center; opacity: 0; transition: opacity .14s ease, color .14s ease, background .14s ease; }
.nota:hover .nota-del, .nota:focus-within .nota-del { opacity: 1; }
.nota-del:hover { color: var(--red); background: var(--surface); }
.nota-del svg { width: 14px; height: 14px; }
@media (max-width: 860px) { .notas-panel { width: min(320px, 86vw); } .notas-drawer { top: 68px; } }
/* Constructor de inventario en el formulario de activo (filas + totales en vivo) */
.inv-build-row { display: grid; grid-template-columns: 1fr 1fr auto; gap: 6px; margin-bottom: 8px; align-items: center; }
.inv-build-row .inv-build-name { grid-column: 1 / -1; }
.inv-build-totals { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line); }
/* Fila de metadatos: estado, titular, etiquetas — separados con aire, nunca texto corrido */
.card-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 8px; }

.panel { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow); padding: 18px; margin-bottom: 18px; }
.panel h2 { font-size: 16px; font-weight: 700; margin: 0 0 12px; }

/* Tablas: contenedor redondeado + filas que se elevan suavemente al hover */
.table-wrap { border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden; }
table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); }
th { color: var(--muted); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: .03em; background: var(--surface-2); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
/* La fecha (1ª columna) y la celda de acciones nunca se parten en dos líneas:
   los iconos quedan uno al lado del otro y la fecha entera y seguida.
   La descripción (que sí puede ser larga) absorbe el ancho y envuelve sola. */
.table-wrap td:first-child { white-space: nowrap; }
.table-wrap td:has(.icon-btn) { white-space: nowrap; }
.table-wrap td .icon-btn + .icon-btn { margin-left: 6px; }
.table-wrap tbody tr { transition: transform .16s ease, background-color .16s ease, box-shadow .16s ease; }
.table-wrap tbody tr:hover { background: var(--surface-2); transform: scale(1.012); box-shadow: var(--shadow); position: relative; }
.table-wrap tr:last-child td { border-bottom: 0; }

.bar { height: 8px; background: var(--line); border-radius: 6px; overflow: hidden; margin-top: 6px; }
.bar > span { display: block; height: 100%; background: var(--brand); }

.badge { display: inline-block; padding: 2px 9px; border-radius: var(--radius-pill); font-size: 11px; font-weight: 600; }
.badge.activa, .badge.activo, .badge.pagado, .badge.abierto, .badge.ingreso { background: var(--green-soft); color: var(--green); }
.badge.pendiente, .badge.generado, .badge.pausada { background: var(--amber-soft); color: var(--amber); }
.badge.vencido, .badge.cancelada, .badge.fallido, .badge.fondos_insuficientes, .badge.suspendida, .badge.egreso { background: var(--red-soft); color: var(--red); }
.badge.parcialmente_pagado, .badge.completada, .badge.transferencia { background: var(--brand-soft); color: var(--brand); }
.badge.al_dia { background: var(--green-soft); color: var(--green); }
.badge.atrasada { background: var(--amber-soft); color: var(--amber); }
/* Estados de ciclo de vida (activos / préstamos / deudas) */
.badge.vendido, .badge.liquidada, .badge.saldada { background: var(--green-soft); color: var(--green); }
.badge.transferido, .badge.refinanciada { background: var(--brand-soft); color: var(--brand); }
.badge.condonada { background: var(--amber-soft); color: var(--amber); }
.badge.incobrable { background: var(--red-soft); color: var(--red); }
.badge.archivado, .badge.archivada { background: var(--line); color: var(--muted); }
/* Sección de historial colapsable */
.hist-panel > summary { cursor: pointer; font-size: 15px; font-weight: 700; list-style-position: inside; }
.hist-panel > summary .h2-note { font-weight: 600; }
.badge.en_mora { background: var(--red-soft); color: var(--red); }
.badge.refinanciada { background: var(--brand-soft); color: var(--brand); }
/* Aviso de préstamos con cuotas vencidas (módulo Préstamos) */
.banner-aviso { display: flex; align-items: center; gap: 10px; border-color: var(--amber) !important;
  color: var(--amber); font-size: 13.5px; font-weight: 600; }
.banner-aviso svg { width: 18px; height: 18px; flex: none; }
/* Barra superior de un detalle (resumen a la izquierda, acciones a la derecha) */
.detail-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.detail-toolbar .btn svg { width: 15px; height: 15px; }
/* Configuración por secciones (estilo ajustes iOS): grupos redondeados con filas */
.cfg-email { display: flex; align-items: center; gap: 10px; padding: 14px 16px; margin-bottom: 6px;
  border-radius: 14px; background: var(--surface-2, color-mix(in srgb, var(--line) 40%, var(--surface)));
  font-weight: 700; color: var(--ink); word-break: break-all; }
.cfg-email svg { width: 18px; height: 18px; color: var(--muted); flex: none; }
.cfg-sec-tt { margin: 20px 4px 8px; font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted); }
.cfg-group { border: 1px solid var(--line); border-radius: 16px; overflow: hidden; background: var(--surface); }
/* Grupo sin título (p. ej. Cerrar sesión): un respiro extra que lo separa del anterior. */
.cfg-group-sep { margin-top: 18px; }
.cfg-item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 16px; border: 0;
  border-bottom: 1px solid var(--line); background: none; cursor: pointer; font-family: inherit;
  font-size: 15px; color: var(--ink); text-align: left; transition: background .12s ease; }
.cfg-item:last-child { border-bottom: 0; }
.cfg-item:hover { background: var(--surface-2, color-mix(in srgb, var(--line) 30%, var(--surface))); }
.cfg-item-ic { display: flex; color: var(--muted); flex: none; }
.cfg-item-ic svg { width: 20px; height: 20px; }
.cfg-item-l { flex: 1; font-weight: 500; }
.cfg-item-v { color: var(--muted); font-size: 13.5px; }
.cfg-item-ch { display: flex; color: var(--muted); flex: none; }
.cfg-item-ch svg { width: 16px; height: 16px; }
.cfg-item.danger .cfg-item-l, .cfg-item.danger .cfg-item-ic { color: var(--red); }

/* ── Configuración a dos columnas (escritorio ≥900px) ──────────────────────────
   El índice queda fijo a la izquierda y el ajuste elegido se despliega a la derecha,
   dentro de la misma ventana: no se apilan modales para cada opción. */
.modal.cfg-split {
  display: grid; grid-template-columns: 264px minmax(0, 1fr);
  width: min(940px, 94vw); max-width: 940px;
  height: min(640px, 86vh); max-height: 86vh;
  padding: 0; overflow: hidden; position: relative;
}
.modal.cfg-split::before { display: none; } /* el borde esmerilado es del scroll de .modal */
.cfg-nav, .cfg-pane { overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
.cfg-nav::-webkit-scrollbar, .cfg-pane::-webkit-scrollbar { width: 9px; }
.cfg-nav::-webkit-scrollbar-thumb, .cfg-pane::-webkit-scrollbar-thumb {
  background: var(--line); border-radius: var(--radius-pill); border: 3px solid transparent; background-clip: padding-box;
}
.cfg-nav {
  padding: 20px 12px 22px; border-right: 1px solid var(--line);
  background: var(--surface-2, color-mix(in srgb, var(--line) 40%, var(--surface)));
}
/* La cabecera se queda fija: al bajar por el índice no se pierde de vista dónde estás. */
.cfg-nav-head {
  position: sticky; top: -20px; z-index: 2;
  margin: -20px -12px 12px; padding: 20px 18px 12px;
  background: var(--surface-2, color-mix(in srgb, var(--line) 40%, var(--surface)));
}
.cfg-nav-head h3 { margin: 0 0 12px; font-size: 17px; font-weight: 800; }
.cfg-nav .cfg-email { padding: 9px 11px; margin: 0; font-size: 12.5px; font-weight: 600; background: var(--surface); border: 1px solid var(--line); border-radius: 11px; gap: 8px; }
.cfg-nav .cfg-email svg { width: 15px; height: 15px; }
.cfg-nav .cfg-sec-tt { margin: 16px 8px 6px; font-size: 11px; }
.cfg-nav .cfg-group, .cfg-nav .cfg-group-sep { border: 0; background: none; border-radius: 0; overflow: visible; }
.cfg-nav .cfg-group-sep { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.cfg-nav .cfg-item {
  gap: 10px; padding: 9px 11px; border-bottom: 0; border-radius: 11px;
  font-size: 14px; margin-bottom: 1px; transition: background .14s ease, color .14s ease;
}
.cfg-nav .cfg-item-ic svg { width: 17px; height: 17px; }
.cfg-nav .cfg-item-v { font-size: 12px; }
.cfg-nav .cfg-item.active {
  background: var(--surface); color: var(--brand); font-weight: 600;
  box-shadow: 0 1px 3px rgba(27, 28, 77, .07); border: 1px solid var(--line); padding: 8px 10px;
}
.cfg-nav .cfg-item.active .cfg-item-ic { color: var(--brand); }
.cfg-nav .cfg-item.active .cfg-item-l { font-weight: 600; }

.cfg-pane { padding: 24px 26px 28px; background: var(--surface); }
.cfg-pane-t { margin: 0 0 16px; font-size: 19px; font-weight: 800; padding-right: 34px; }
.cfg-split-x { position: absolute; top: 14px; right: 18px; float: none; z-index: 2; line-height: 1; }

/* Si la ventana se estrecha con Configuración abierta, el índice se retira y queda el ajuste. */
@media (max-width: 899px) {
  .modal.cfg-split { grid-template-columns: minmax(0, 1fr); }
  .cfg-split .cfg-nav { display: none; }
}
/* Campo con guardado en línea (nombre de perfil): input + botón juntos */
.inline-save { display: flex; gap: 8px; align-items: stretch; }
.inline-save input { flex: 1; min-width: 0; }
/* Texto legal (política de privacidad): encabezados compactos y lectura cómoda */
.legal h3 { font-size: 14px; margin: 16px 0 4px; color: var(--ink); }
.legal p { font-size: 13.5px; line-height: 1.55; color: var(--ink); margin: 0 0 8px; }
.legal .section-sub { margin-bottom: 12px; }
/* Botón "Configuración" del menú móvil (única entrada bajo los módulos) */
.msheet-config { display: flex; align-items: center; gap: 12px; width: 100%; margin-top: 8px; padding: 15px 16px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--surface); cursor: pointer;
  font-family: inherit; font-size: 15px; font-weight: 600; color: var(--ink); }
.msheet-config > svg:first-child { width: 20px; height: 20px; color: var(--brand); flex: none; }
.msheet-config span { flex: 1; text-align: left; }
.msheet-config > svg:last-child { width: 16px; height: 16px; color: var(--muted); flex: none; }
.badge.aporte_meta { background: var(--brand-soft); color: var(--violet); }

.btn {
  background: var(--navy); color: #fff; border: 0; border-radius: var(--radius-btn);
  padding: 9px 15px; font-size: 13px; font-weight: 600; cursor: pointer; font-family: inherit;
  transition: filter .15s ease, transform .15s ease;
}
.btn:hover { filter: brightness(1.12); transform: translateY(-1px); }
.btn:disabled { opacity: .6; cursor: default; transform: none; }
/* Ghost: relleno tenue + borde suave (menos "contorno IA", más botón diseñado). */
.btn.ghost { background: var(--surface-2); color: var(--ink); border: 1px solid var(--line); }
.btn.ghost:hover { background: var(--surface); border-color: var(--line); box-shadow: var(--shadow-card); transform: translateY(-1px); filter: none; }
.btn.sm { padding: 7px 13px; font-size: 12.5px; }
/* Acciones dentro de tarjetas y modales de detalle: botones cómodos y aireados en escritorio
   (en móvil ya se vuelven cuadrados 2×2 en su media query). Igualan el confort del CTA. */
.card .actions, .modal .actions { gap: 10px; }
.card .actions > .btn, .modal .actions > .btn {
  padding: 9px 16px; font-size: 13px; min-height: 40px; border-radius: var(--radius-md);
  display: inline-flex; align-items: center; gap: 7px;
}
.card .actions > .btn svg, .modal .actions > .btn svg { width: 16px; height: 16px; }
.btn.green { background: var(--green); }
.login-btn, .modal .btn:not(.ghost) { background: var(--brand); }
.actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
/* Filtro por contacto en Deudas (select dentro de la fila de acciones). */
.deuda-filtro {
  font-size: 13px; font-weight: 600; color: var(--ink); margin-left: auto;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-btn, 10px);
  padding: 9px 12px; cursor: pointer; max-width: 240px;
}
.deuda-filtro:hover { border-color: var(--brand); }
.deuda-contacto-banner .panel-head { margin-bottom: 12px; }

.toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: end; margin-bottom: 14px; }
.field { display: flex; flex-direction: column; gap: 4px; }
.field label { font-size: 12px; color: var(--muted); font-weight: 500; }
input, select, textarea {
  padding: 9px 11px; border: 1px solid var(--line); border-radius: var(--radius-md);
  font-size: 13px; background: var(--surface-2); font-family: inherit; color: var(--ink);
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--brand-soft); border-color: var(--brand); background: var(--surface); }
/* Áreas de texto cómodas: varias líneas visibles y extensibles por el usuario */
textarea { resize: vertical; min-height: 44px; line-height: 1.45; width: 100%; }
/* Móvil: 16px mínimo en los campos evita el ZOOM automático de iOS al enfocarlos
   (solo se abre el teclado, sin acercar). !important para ganar a tamaños menores. */
@media (max-width: 760px) { input, select, textarea { font-size: 16px !important; } }

.alert { padding: 12px 16px; border-radius: var(--radius-md); margin-bottom: 14px; font-size: 13px; }
.alert.critica { background: var(--red-soft); color: var(--red); border: 1px solid var(--red-soft); }
.alert.ok { background: var(--green-soft); color: var(--green); }
.alert.aviso { background: var(--amber-soft); color: var(--amber); margin-bottom: 8px; }

/* ── Configuración › Impuestos: plantilla por país ──────────────────────────── */
.imp-preset { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-md); padding: 14px 15px; margin-bottom: 16px; }
.imp-preset-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 11px; }
.imp-preset-head h4 { margin: 0; display: inline-flex; align-items: center; gap: 7px; font-size: 13.5px; font-weight: 700; color: var(--ink); }
.imp-preset-head h4 svg { width: 16px; height: 16px; color: var(--brand); }
.imp-pais-badge { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 700; color: var(--brand); background: var(--brand-soft); padding: 4px 12px; border-radius: var(--radius-pill); }
.imp-pais-badge.none { color: var(--muted); background: var(--surface); border: 1px dashed var(--line); font-weight: 600; }
.imp-preset-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.imp-preset-row .deuda-filtro { flex: 1 1 190px; margin-left: 0; max-width: none; }
.imp-preset-row .btn { flex: none; }
.imp-preview { margin-top: 11px; }
.imp-preset-note { margin: 11px 0 0; font-size: 11.5px; line-height: 1.45; color: var(--muted); display: flex; gap: 6px; align-items: flex-start; }
.imp-preset-note svg { width: 14px; height: 14px; flex: none; margin-top: 1px; opacity: .8; }
.imp-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.imp-pill { display: inline-flex; align-items: center; font-size: 11.5px; font-weight: 600; color: var(--ink); background: var(--surface); border: 1px solid var(--line); padding: 4px 11px; border-radius: var(--radius-pill); font-variant-numeric: tabular-nums; }
.imp-pill.on { color: var(--green); background: var(--green-soft); border-color: color-mix(in srgb, var(--green) 38%, var(--line)); }
.imp-pill.off { color: var(--muted); background: var(--surface); border-style: dashed; text-decoration: line-through; }
.imp-cf-row { margin: 12px 0 7px; font-size: 13px; line-height: 1.5; color: var(--ink); }
.imp-cf-row:first-of-type { margin-top: 4px; }
/* Tarjeta de impuesto oculto: atenuada (el switch indica el estado). */
.imp-card { transition: opacity .18s ease; }
.imp-card.is-off { opacity: .6; }

.modal-bg { position: fixed; inset: 0; background: rgba(27, 28, 77, .45); display: flex; align-items: center; justify-content: center; z-index: 50; }
.modal {
  background: var(--surface); border-radius: var(--radius); padding: 0 24px 24px; width: min(440px, 92vw);
  box-shadow: var(--shadow-pop); max-height: 90vh; overflow: auto;
  scroll-behavior: smooth; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--line) transparent;
}
.modal::-webkit-scrollbar { width: 9px; }
.modal::-webkit-scrollbar-thumb { background: var(--line); border-radius: var(--radius-pill); border: 3px solid transparent; background-clip: padding-box; }
.modal::-webkit-scrollbar-thumb:hover { background: var(--muted); }
.modal::-webkit-scrollbar-track { background: transparent; }
/* Borde superior esmerilado (efecto "scroll edge" de iOS): una franja sticky difumina y
   desvanece el contenido que sube al hacer scroll, en vez de cortarlo contra el límite.
   Solo escritorio (≥721px); en móvil el ::before es el asa de la hoja. */
@media (min-width: 721px) {
  .modal::before {
    content: ''; position: sticky; top: 0; z-index: 3; display: block;
    height: 28px; margin: 0 -24px -4px; pointer-events: none;
    background: linear-gradient(to bottom, var(--surface) 55%, transparent);
    backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px);
    border-radius: var(--radius) var(--radius) 0 0;
  }
}
.modal h3 { margin: 0 0 14px; font-weight: 700; }
.modal .field { margin-bottom: 12px; }
.modal .modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }

/* Botón de información "i" y su modal explicativo (educación al usuario). */
.info-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; padding: 0; margin-left: 3px; border-radius: 50%;
  border: 1.4px solid var(--muted); background: transparent; color: var(--muted);
  font-family: Georgia, 'Times New Roman', serif; font-style: italic; font-weight: 700;
  font-size: 10px; line-height: 1; cursor: pointer; vertical-align: middle; flex: none;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.info-btn:hover, .info-btn:focus-visible { background: var(--brand); border-color: var(--brand); color: #fff; outline: none; }
.modal.info-modal { width: min(460px, 92vw); }
.info-body { color: var(--ink); font-size: 14px; line-height: 1.55; }
.info-body p { margin: 0 0 12px; }
.info-body ul { margin: 0 0 12px; padding-left: 20px; }
.info-body li { margin-bottom: 6px; }
/* Info en formato preguntas desplegables (acordeón): la pregunta es un botón que abre su respuesta */
.info-faq { display: flex; flex-direction: column; gap: 7px; }
.faq-item { border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden; }
.faq-q { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 11px 14px; background: transparent; border: none; text-align: left; font: inherit; font-size: 13.5px; font-weight: 600; color: var(--ink); cursor: pointer; transition: color .15s ease; }
.faq-q:hover, .faq-q:focus-visible { color: var(--brand); outline: none; }
.faq-q svg { width: 16px; height: 16px; flex: none; color: var(--muted); transition: transform .2s ease; }
.faq-q.open svg { transform: rotate(180deg); color: var(--brand); }
/* Respuesta plegable con animación (acordeón de una sola apertura) */
/* Expansión con grid-template-rows 0fr→1fr (no max-height): anima a la altura REAL
   del contenido — sin el retardo al cerrar ni el ritmo falso del viejo max-height. */
.faq-a {
  display: grid; grid-template-rows: 0fr;
  opacity: 0; padding: 0 14px;
  font-size: 13.5px; line-height: 1.55; color: var(--ink);
  transition: grid-template-rows .32s cubic-bezier(.4, .7, .2, 1), opacity .25s ease, padding .32s ease;
}
.faq-a-in { overflow: hidden; min-height: 0; }
.faq-q.open + .faq-a { grid-template-rows: 1fr; opacity: 1; padding: 2px 14px 12px; }
.faq-a p { margin: 6px 0; } .faq-a ul { margin: 6px 0; padding-left: 20px; } .faq-a li { margin-bottom: 5px; }
@media (prefers-reduced-motion: reduce) { .faq-a { transition: none; } }
/* "¿Qué significa mi resultado?" — interpretación personalizada del Freedom Score */
.fsi-modal { width: min(560px, 94vw); }
.fsi-top { display: flex; align-items: center; gap: 16px; padding-bottom: 14px; margin-bottom: 4px; border-bottom: 1px solid var(--line); }
.fsi-score { font-size: 40px; font-weight: 800; color: var(--brand); line-height: 1; flex: none; }
.fsi-score span { font-size: 16px; font-weight: 700; color: var(--muted); }
.fsi-cat { font-size: 15px; font-weight: 800; color: var(--ink); }
.fsi-ver { margin: 4px 0 0; font-size: 13px; color: var(--muted); line-height: 1.5; }
.fsi-h { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin: 14px 0 6px; }
.fsi-row { padding: 10px 0; border-bottom: 1px solid var(--line); }
.fsi-row:last-of-type { border-bottom: 0; }
.fsi-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.fsi-head b { font-size: 14px; }
.fsi-badge { font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: 999px; flex: none; }
.fsi-badge.pos { background: var(--green-soft); color: var(--green); }
.fsi-badge.warn { background: var(--amber-soft); color: var(--amber); }
.fsi-badge.neg { background: var(--red-soft); color: var(--red); }
.fsi-det { margin: 5px 0 0; font-size: 13px; color: var(--muted); line-height: 1.5; }
.fsi-acc { display: flex; gap: 7px; align-items: flex-start; margin: 7px 0 0; font-size: 13px; color: var(--ink); }
.fsi-acc svg { width: 15px; height: 15px; flex: none; color: var(--brand); margin-top: 2px; }
.fsi-foot { display: flex; gap: 8px; align-items: flex-start; margin-top: 14px; font-size: 12.5px; color: var(--muted); }
.fsi-foot svg { width: 15px; height: 15px; flex: none; color: var(--brand); margin-top: 2px; }
.link-btn { background: none; border: 0; padding: 0; font: inherit; color: var(--brand); font-weight: 700; cursor: pointer; text-decoration: underline; }
.link-btn:hover { color: var(--ink); }
.fs-explica-btn { width: 100%; justify-content: center; margin-top: 14px; }
.fs-explica-link { display: inline-flex; align-items: center; gap: 5px; margin-top: 10px; text-decoration: none; font-size: 12px; }
.fs-explica-link svg { width: 14px; height: 14px; }
.fs-explica-link:hover { text-decoration: underline; }

/* Apertura suave de modales (escritorio); en móvil el sheetUp de la media query manda. */
.modal-bg { animation: bgFade .2s ease; }
.modal { animation: modalPop .24s cubic-bezier(.22, .8, .3, 1); }
@keyframes bgFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalPop { from { opacity: 0; transform: translateY(10px) scale(.97); } to { opacity: 1; transform: none; } }
/* Cierre con animación (se oculta por donde salió) */
.modal-bg.closing { animation: bgFadeOut .24s ease forwards; }
.modal-bg.closing .modal { animation: modalPopOut .24s cubic-bezier(.4, 0, 1, 1) forwards; }
@keyframes bgFadeOut { to { opacity: 0; } }
@keyframes modalPopOut { to { opacity: 0; transform: translateY(10px) scale(.97); } }
@media (prefers-reduced-motion: reduce) { .modal, .modal-bg { animation: none; } }

/* Detalle de un movimiento (clic en la fila) */
.mov-det-amount { font-size: 34px; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; margin-top: 2px; }
.mov-det-tags { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0 14px; }
.mov-det-rows { display: grid; gap: 2px; }
.mov-det .card-row.col { flex-direction: column; align-items: flex-start; gap: 3px; }
.mov-det .card-row.col span:last-child { color: var(--ink); text-align: left; }
.mov-det-note { display: flex; gap: 9px; align-items: flex-start; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-md); padding: 12px 14px; margin-top: 14px; font-size: 13px; color: var(--muted); line-height: 1.45; }
.mov-det-note svg { width: 16px; height: 16px; flex: none; color: var(--brand); margin-top: 2px; }
.mov-det-note > span { flex: 1; min-width: 0; }
.mov-det-note b { color: var(--ink); }
/* Selector de categoría en línea dentro de la tabla de la tarjeta */
.cat-inline { font-family: inherit; font-size: 12.5px; padding: 4px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink); max-width: 170px; cursor: pointer; }
.cat-inline:hover { border-color: var(--brand); }
.cat-inline:focus { outline: 2px solid var(--brand-soft); border-color: var(--brand); }
/* Fila de movimiento clicable */
.row-click { cursor: pointer; }
.row-click:hover { background: var(--surface-2); }
.empty { color: var(--muted); padding: 18px 0; text-align: center; }
/* Estado de carga al cambiar de módulo: visible al instante, sin congelar la pantalla. */
.view-loading { display: flex; align-items: center; justify-content: center; gap: 10px; color: var(--muted); padding: 52px 0; font-weight: 600; }
.spin { width: 18px; height: 18px; border: 2.5px solid var(--line); border-top-color: var(--brand); border-radius: 50%; display: inline-block; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.view-in { animation: viewIn .26s ease both; }
@keyframes viewIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
/* Reveal escalonado: cada tarjeta/sección entra con su propio retardo (--rv-delay). */
/* fill `backwards`: invisible durante su retardo (para el escalonado) y, al terminar,
   vuelve al estado normal del elemento — así nunca queda una tarjeta pegada en opacity 0. */
.reveal-item { animation: revealIn var(--rv-dur, 360ms) cubic-bezier(.22, .8, .36, 1) var(--rv-delay, 0ms) backwards; will-change: transform, opacity; }
@keyframes revealIn { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
.reveal-welcome .reveal-item { animation-name: revealWelcome; }
@keyframes revealWelcome { from { opacity: 0; transform: translateY(15px) scale(.99); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .view-in, .spin, .reveal-item { animation: none; } }

/* ── Feedback de red global ─────────────────────────────────────────────────
   Barra superior animada (algo en curso) + escudo transparente que bloquea clics
   repetidos mientras se guarda algo (evita registrar la misma acción varias veces). */
#netbar { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 101; pointer-events: none; opacity: 0; transition: opacity .2s ease; }
#netbar > span { display: block; height: 100%; width: 35%; border-radius: 0 3px 3px 0;
  background: linear-gradient(90deg, transparent, var(--brand), transparent); }
body.net-busy #netbar { opacity: 1; }
body.net-busy #netbar > span { animation: netSlide 1.05s ease-in-out infinite; }
@keyframes netSlide { 0% { transform: translateX(-40%); } 100% { transform: translateX(330%); } }
#busy-shield { position: fixed; inset: 0; z-index: 96; background: transparent; cursor: progress; display: none; }
body.shield-on { cursor: progress; }
body.shield-on #busy-shield { display: block; }

/* Estado de error de una ventana: claro y con botón para reintentar (no se queda colgada). */
.view-error { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 12px;
  padding: 48px 22px; color: var(--muted); }
.view-error > svg { width: 38px; height: 38px; color: var(--amber); }
.view-error .ve-txt b { display: block; color: var(--ink); font-size: 15px; margin-bottom: 4px; }
.view-error .ve-txt p { margin: 0; font-size: 13px; max-width: 420px; line-height: 1.5; }
.view-error .btn { display: inline-flex; align-items: center; gap: 7px; }
.view-error .btn svg { width: 15px; height: 15px; }

/* Esqueleto de carga: bloques con un brillo que recorre, para que se vea "vivo". */
.skel-wrap { animation: viewIn .26s ease both; }
.skel { background: var(--surface); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow); }
.sk-kpis { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; margin-bottom: 16px; }
.sk-panel { margin-bottom: 16px; }
.sk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.sk-card { min-height: 150px; }
.sk-line { position: relative; overflow: hidden; height: 12px; margin: 11px 0; border-radius: 7px; background: var(--surface-2); }
.sk-line.tall { height: 24px; } .sk-line.sh { width: 55%; } .sk-line.md { width: 78%; } .sk-line.lg { width: 100%; }
.sk-line::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--ink) 7%, transparent), transparent);
  animation: skShimmer 1.3s ease-in-out infinite; }
@keyframes skShimmer { 100% { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  body.net-busy #netbar > span, .sk-line::after { animation: none; }
}

.pos { color: var(--green); } .neg { color: var(--red); }

/* Cuentas clicables (filtro de movimientos) */
.card.sel { cursor: pointer; }
.card.sel:hover { box-shadow: var(--shadow-pop); transform: translateY(-2px); }
.card.active-card { outline: 2px solid var(--brand); }

/* Presupuestos */
.budget-row { margin: 0 -8px 8px; padding: 7px 8px; border-radius: 10px; cursor: pointer; transition: background .15s ease; }
.budget-row:hover { background: var(--surface-2); }
.budget-head { display: flex; justify-content: space-between; align-items: center; font-size: 13px; margin-bottom: 2px; }
.budget-head .k { color: var(--muted); display: flex; align-items: center; gap: 6px; }

/* Charts: el grid lleva el espaciado externo; los paneles internos no suman márgenes */
.chart-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; margin-bottom: 18px; }
.chart-grid .panel { margin-bottom: 0; }
.chart-box { position: relative; height: 260px; }
.chart-box.tall { height: 300px; }

/* Toasts */
#toast-root { position: fixed; top: 16px; right: 16px; display: flex; flex-direction: column; gap: 10px; z-index: 100; }
/* Toast = tarjeta limpia de superficie con el icono en un CUADRADITO tinteado suave
   (color del estado al ~15% sobre la superficie, icono en el color saturado) — el
   patrón "chip duotone" de las listas de features. Antes usaba var(--radius-lg),
   token que NO existía → esquinas cuadradas; y el tinte degradado ensuciaba. */
.toast {
  background: var(--surface); color: var(--ink); padding: 13px 16px; border-radius: 16px;
  box-shadow: var(--shadow-pop); border: 1px solid var(--line); font-size: 13px; max-width: 384px;
  display: flex; gap: 12px; align-items: center; animation: toastIn .28s cubic-bezier(.22, .8, .3, 1);
}
.toast-ic {
  flex: none; width: 40px; height: 40px; border-radius: 12px;
  display: grid; place-items: center;
  background: var(--brand-soft); color: var(--brand);
}
.toast.ok .toast-ic { background: var(--green-soft); color: var(--green); }
.toast.warn .toast-ic { background: var(--amber-soft); color: var(--amber); }
.toast.err .toast-ic { background: var(--red-soft); color: var(--red); }
.toast-ic svg { width: 20px; height: 20px; }
.toast-body { min-width: 0; }
.toast b { display: block; margin-bottom: 2px; font-weight: 700; font-size: 13.5px; color: var(--ink); }
.toast .toast-msg { color: var(--ink); line-height: 1.45; }
.toast.has-title .toast-msg { color: var(--muted); }
@keyframes toastIn { from { transform: translateY(-8px) scale(.98); opacity: 0; } to { transform: none; opacity: 1; } }
/* Aviso repetido: el toast ya visible TIEMBLA en vez de duplicarse. */
.toast.shake { animation: toastShake .5s cubic-bezier(.36, .07, .19, .97); }
@keyframes toastShake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(3px); }
  30%, 50%, 70% { transform: translateX(-5px); }
  40%, 60% { transform: translateX(5px); }
}

/* Timeline (calendario) */
.timeline { position: relative; margin-left: 8px; padding-left: 22px; border-left: 2px solid var(--line); }
.tl-month { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; margin: 16px 0 8px -22px; padding-left: 22px; }
.tl-item {
  position: relative; display: flex; justify-content: space-between; align-items: center;
  background: var(--surface); border-radius: var(--radius-md); padding: 10px 14px; margin-bottom: 8px; box-shadow: var(--shadow);
}
.tl-item::before {
  content: ''; position: absolute; left: -29px; top: 50%; width: 12px; height: 12px; border-radius: 50%;
  transform: translateY(-50%); background: var(--red); border: 2px solid var(--surface);
}
.tl-item.entrante::before { background: var(--green); }
.tl-item .tl-left { display: flex; flex-direction: column; }
.tl-item .tl-date { font-size: 11px; color: var(--muted); }
.tl-item .tl-detail { font-weight: 600; }
.tl-item .tl-type { font-size: 11px; color: var(--muted); }

.modal.wide { width: min(640px, 94vw); }
.modal .close-x { float: right; cursor: pointer; color: var(--muted); border: 0; background: none; font-size: 20px; }
/* Flecha "atrás": regresa al panel padre (Configuración) sin cerrar todo */
.modal .back-x { float: left; cursor: pointer; color: var(--muted); border: 0; background: none; padding: 0; margin: -2px 10px 0 0; display: flex; align-items: center; }
.modal .back-x svg { width: 22px; height: 22px; }
.modal .back-x:hover { color: var(--brand); }
.modal h3.has-back { margin-top: 0; }
.section-sub { color: var(--muted); font-size: 13px; margin: -6px 0 14px; }
.card-desc { color: var(--muted); font-size: 12px; margin: -2px 0 10px; line-height: 1.45; white-space: pre-wrap; }

/* ─────────────────────────────────────────────────────────────
   Iconos Lucide en títulos, alertas y botones (sustituyen emojis)
   ───────────────────────────────────────────────────────────── */
.panel h2 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.panel h2 svg { width: 17px; height: 17px; color: var(--brand); flex: none; }
.card h3 svg { width: 15px; height: 15px; color: var(--brand); vertical-align: -2px; }
.alert svg { width: 15px; height: 15px; vertical-align: -3px; margin-right: 6px; }
.btn svg { width: 14px; height: 14px; vertical-align: -2px; }
.login-brand { display: flex; align-items: center; justify-content: center; gap: 9px; }
.login-brand svg { width: 22px; height: 22px; color: var(--brand); }
.h2-note {
  font-size: 11px; font-weight: 600; color: var(--brand); background: var(--brand-soft);
  padding: 3px 10px; border-radius: var(--radius-pill); text-transform: none; letter-spacing: 0;
}

/* Botones de acción por fila (editar / eliminar) */
.icon-btn {
  width: 30px; height: 30px; border: 0; border-radius: 9px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform .15s ease, filter .15s ease;
}
.icon-btn svg { width: 15px; height: 15px; }
.icon-btn.edit { background: var(--brand-soft); color: var(--brand); }
.icon-btn.del { background: var(--red-soft); color: var(--red); }
.icon-btn:hover { transform: translateY(-1px); filter: brightness(.96); }
/* Etiqueta de texto opcional dentro de un icon-btn: oculta en escritorio, se
   muestra en móvil donde el botón se vuelve cuadrado con icono + texto. */
.icon-btn .lbl { display: none; }

/* ─────────────────────────────────────────────────────────────
   Módulo Cuentas: tintes difuminados, selección múltiple y resumen
   ───────────────────────────────────────────────────────────── */
.card.tint-0 { background: linear-gradient(140deg, var(--surface) 40%, var(--brand-soft) 145%); }
.card.tint-1 { background: linear-gradient(140deg, var(--surface) 40%, var(--green-soft) 145%); }
.card.tint-2 { background: linear-gradient(140deg, var(--surface) 40%, var(--amber-soft) 145%); }
.card.tint-3 { background: linear-gradient(140deg, var(--surface) 40%, var(--cyan-soft) 145%); }
.card.tint-4 { background: linear-gradient(140deg, var(--surface) 40%, var(--red-soft) 145%); }

.cuentas-layout {
  display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 14px;
  grid-template-areas: "cards resumen" "proj resumen";
  margin-top: 14px; align-items: start;
}
.col-izq { grid-area: cards; display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.col-izq .panel { margin-bottom: 0; }
.cuentas-layout > .resumen-panel { grid-area: resumen; }
.cuentas-layout > .gastos-prox { grid-area: proj; margin: 0; }

/* Panel de proyección: encabezado-botón (colapsable en móvil), grupos y filas. */
/* Plegable también en escritorio (no solo móvil): chevron + clic en la cabecera */
.proj-toggle { display: flex; align-items: center; gap: 10px; width: 100%; background: none; border: 0; padding: 0; margin: 0; text-align: left; color: inherit; cursor: pointer; }
.proj-toggle h2 { margin: 0; flex: 1; }
.proj-toggle-mob { display: none; }
.proj-chevron { display: inline-flex; color: var(--muted); transition: transform .2s ease; }
.gastos-prox.proj-open .proj-chevron { transform: rotate(180deg); }
.gastos-prox .proj-body { display: none; }
.gastos-prox.proj-open .proj-body { display: block; }
/* Aire para la descripción bajo la cabecera del panel */
.proj-body > .section-sub:first-child { margin: 12px 0 14px; line-height: 1.5; }
.proj-grupo { margin-top: 12px; }
.proj-grupo:first-child { margin-top: 8px; }
.proj-grupo-tit { font-size: 12px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.proj-grupo-tit svg { width: 13px; height: 13px; }
.proj-row .gp-monto.pos { color: var(--green); }
.proj-row .gp-monto.neg { color: var(--red); }
.gp-proj-stat .k { color: var(--ink); font-weight: 600; }
.gp-proj-stat b { font-size: 17px; }
/* Lista del planificador en columnas: densa y sin estirar la página */
.gp-lista { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 6px; }
.gp-tot { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.gp-stat {
  flex: 1; min-width: 130px; background: var(--surface-2); border-radius: 10px;
  padding: 9px 12px; display: flex; flex-direction: column; gap: 2px;
}
.gp-stat .k { font-size: 10.5px; }
.gp-stat b { font-size: 15px; font-variant-numeric: tabular-nums; }

/* Tile fantasma "+ Nueva cuenta" (patrón DESIGN.md §4.11): llena el grid e invita a crear */
.ghost-tile {
  background: var(--surface-2); border: 2px dashed var(--line); border-radius: var(--radius);
  min-height: 150px; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: 600;
  color: var(--muted); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  transition: border-color .2s ease, color .2s ease, transform .2s ease;
}
.ghost-tile:hover { border-color: var(--brand); color: var(--brand); transform: translateY(-2px); }
.ghost-tile .plus {
  width: 34px; height: 34px; border-radius: 50%; background: var(--brand); color: #fff;
  display: flex; align-items: center; justify-content: center;
}
.ghost-tile .plus svg { width: 16px; height: 16px; }

/* Planificador de gastos próximos del mes */
.gp-row {
  display: flex; align-items: center; gap: 9px; padding: 8px 10px; margin-bottom: 5px;
  background: var(--surface-2); border-radius: 10px; cursor: pointer; font-size: 12.5px;
  transition: background .18s ease, opacity .25s ease;
}
.gp-row:hover { background: var(--brand-soft); }
.gp-row input { accent-color: var(--brand); width: 14px; height: 14px; flex: none; }
.gp-row > svg { width: 14px; height: 14px; color: var(--brand); flex: none; }
.gp-row .gp-info { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.gp-row .gp-sub { font-size: 10.5px; color: var(--muted); }
.gp-row .gp-monto { font-variant-numeric: tabular-nums; white-space: nowrap; }
.gp-row.gp-off { opacity: .45; }
.gp-row.gp-off .gp-monto, .gp-row.gp-off b { text-decoration: line-through; }
.cuentas-grid { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }

.card.sel { position: relative; }
.card .sel-check {
  position: absolute; top: 12px; right: 12px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--brand); color: #fff; display: flex; align-items: center; justify-content: center;
  opacity: 0; transform: scale(.6); transition: opacity .18s ease, transform .18s ease;
}
.card .sel-check svg { width: 13px; height: 13px; }
.card.active-card .sel-check { opacity: 1; transform: scale(1); }

.resumen-panel { margin-bottom: 0; background: linear-gradient(165deg, var(--surface) 55%, var(--brand-soft) 170%); }
.resumen-total { font-size: 28px; font-weight: 800; font-variant-numeric: tabular-nums; margin-top: 12px; }
.resumen-total-label {
  color: var(--muted); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em; margin-bottom: 8px;
}
.sep { border: 0; border-top: 1px solid var(--line); margin: 12px 0 4px; }
/* Resumen multi-divisa: subtotal por moneda (sin conversión, Fase A) */
.resumen-multi { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.rm-row { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 11px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-md); }
.rm-cur { font-size: 11px; font-weight: 800; letter-spacing: .04em; color: var(--brand);
  background: var(--brand-soft); padding: 3px 8px; border-radius: var(--radius-pill); flex: none; }
.rm-vals { text-align: right; display: flex; flex-direction: column; line-height: 1.25; }
.rm-vals b { font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; }
.rm-vals .k { font-size: 11px; }

/* Seguimiento del reservado: a qué está anclado cada monto */
.reservas-det { display: flex; flex-direction: column; gap: 4px; margin: 6px 0 2px; }
.reserva-row {
  display: flex; align-items: center; gap: 8px; width: 100%;
  border: 0; background: var(--surface-2); border-radius: 10px; padding: 7px 10px;
  cursor: pointer; font-family: inherit; font-size: 12px; color: var(--ink); text-align: left;
  transition: background .15s ease, transform .15s ease;
}
.reserva-row:hover { background: var(--brand-soft); transform: translateX(2px); }
.reserva-row svg { width: 13px; height: 13px; color: var(--brand); flex: none; }
.reserva-row .reserva-nombre { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.reserva-row .reserva-sub { font-size: 10px; color: var(--muted); }
.reserva-row b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--brand-soft); color: var(--brand); font-size: 11px; font-weight: 600;
  padding: 3px 10px; border-radius: var(--radius-pill);
}
.chip svg { width: 11px; height: 11px; flex: none; }
.hint { margin-top: 6px; }

/* Transición continua al re-renderizar paneles del módulo */
.fade-in { animation: fadeUp .28s ease; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.badge.conciliacion { background: var(--amber-soft); color: var(--amber); }

/* Panel de administración (#/admin): estados de usuarios y códigos de acceso */
.badge.activo, .badge.disponible { background: var(--green-soft); color: var(--green); }
.badge.inactivo { background: var(--amber-soft); color: var(--amber); }
.badge.sin_plan, .badge.usado { background: var(--surface-2); color: var(--muted); }
.badge.expirado, .badge.revocado { background: var(--red-soft); color: var(--red); }
.badge.temporal { background: var(--amber-soft); color: var(--amber); }
.badge.lifetime { background: var(--brand-soft); color: var(--brand); }
.badge.temporary { background: var(--amber-soft); color: var(--amber); }
.badge.pro { background: var(--green-soft); color: var(--green); }
.badge.vida { background: var(--brand-soft); color: var(--brand); }
.badge.gratis { background: var(--surface-2); color: var(--muted); }
.badge.info { background: var(--brand-soft); color: var(--brand); }
.badge.mejora { background: var(--green-soft); color: var(--green); }
.badge.aviso { background: var(--amber-soft); color: var(--amber); }
/* Detalle de usuario (panel admin): subtítulos de sección y datos del perfil. */
.det-sub { display: flex; align-items: center; gap: 6px; margin: 0 0 8px; font-size: 14px; font-weight: 700; }
.det-sub .h2-note { font-weight: 600; }
.dato-grid { display: grid; gap: 2px; }
.muted { color: var(--muted); font-size: 12px; word-break: break-all; }
.code-chip { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .05em; }
.badge.consumo { background: var(--red-soft); color: var(--red); }
.badge.pago, .badge.comprado, .badge.pagada { background: var(--green-soft); color: var(--green); }
.badge.cargada { background: var(--brand-soft); color: var(--brand); }
.badge.pausado { background: var(--surface-2); color: var(--muted); }
.badge.cancelado { background: var(--red-soft); color: var(--red); }

/* ─────────────────────────────────────────────────────────────
   Visual de tarjeta física (chip, contactless, número enmascarado)
   ───────────────────────────────────────────────────────────── */
/* ── Tarjeta "física" estilo mesh (degradado por capas = blob con profundidad) ── */
.tarjeta-fisica {
  position: relative; overflow: hidden; isolation: isolate;
  width: 100%; max-width: 360px; aspect-ratio: 1.62 / 1; margin: 12px 0 10px;
  border-radius: 18px; padding: 15px 18px;
  background: var(--card-bg); color: var(--card-ink);
  box-shadow: 0 14px 30px rgba(27, 28, 77, .16), inset 0 0 0 1px var(--card-line);
  display: flex; flex-direction: column;
}
.tf-mesh { display: none; } /* el mesh ahora vive en el fondo de la tarjeta (ver skins) */
.tf-content { position: relative; z-index: 1; display: flex; flex-direction: column; height: 100%; min-height: 0; }
.tf-head { display: flex; justify-content: space-between; align-items: center; }
.tf-brand { font-family: 'Space Grotesk', 'Plus Jakarta Sans', sans-serif; font-weight: 700; font-size: 15px; }
.tf-tipo { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; padding: 3px 9px; border-radius: var(--radius-pill); background: var(--card-line); }
.tf-num { font-family: 'Space Mono', monospace; font-size: 14.5px; letter-spacing: .5px; margin-top: 9px; opacity: .9; }
.tf-name { font-family: 'Space Grotesk', 'Plus Jakarta Sans', sans-serif; font-weight: 600; font-size: 12px; margin-top: 2px; color: var(--card-sub); }
.tf-foot { margin-top: auto; }
.tarjeta-fisica .tf-label { display: block; font-size: 8px; text-transform: uppercase; letter-spacing: .1em; color: var(--card-sub); margin-bottom: 1px; opacity: 1; }
.tf-use-head { display: flex; justify-content: space-between; align-items: baseline; }
.tf-pct { font-size: 11px; color: var(--card-sub); }
.tf-usebar { height: 5px; border-radius: var(--radius-pill); background: var(--card-line); overflow: hidden; margin: 3px 0 3px; }
.tf-usebar span { display: block; height: 100%; border-radius: var(--radius-pill); background: var(--card-accent); }
.tf-use-amt { display: flex; align-items: baseline; gap: 6px; }
.tf-use-amt b { font-size: 15px; }
.tf-sub { font-size: 10px; color: var(--card-sub); }
.tf-foot-row { display: flex; justify-content: space-between; align-items: flex-end; gap: 10px; margin-top: 7px; }
.tf-fi.tf-right { text-align: right; }
.tf-fi b { font-size: 13px; }
.tf-due { color: var(--card-due); }
/* Números de la app: misma fuente que el resto (Plus Jakarta Sans) con cifras de ancho
   fijo para que alineen. El número de tarjeta (.tf-num) conserva su monoespaciada aparte. */
.mono { font-family: inherit; font-variant-numeric: tabular-nums; letter-spacing: 0; }

/* Skins premium: grises elegantes, oscuros con degradado y metálicos sólidos (acero/oro).
   Nada de mesh multicolor. El degradado va en el FONDO (lo recorta el border-radius de
   forma nativa, también en iOS): láminas diagonales + un velo de brillo metálico.
   Las CLAVES se conservan (aurora/indigo/… ) por compatibilidad con tarjetas ya guardadas;
   solo cambia su aspecto y su nombre visible (ver SKINS_UI en app.js). */

/* Grafito — grafito oscuro con degradado suave (skin por defecto) */
.skin-aurora {
  --card-bg: #23262e; --card-ink: #f0f1f5; --card-sub: rgba(255, 255, 255, .60);
  --card-line: rgba(255, 255, 255, .14); --card-accent: #aeb6c4; --card-due: #e2949c;
  background:
    radial-gradient(130% 95% at 85% -12%, rgba(255, 255, 255, .12), transparent 55%),
    linear-gradient(135deg, #2c303b, #1d2027 55%, #262a33),
    var(--card-bg);
}
/* Acero — metálico cepillado claro (plata) */
.skin-indigo {
  --card-bg: #e7e9ee; --card-ink: #2a2e38; --card-sub: #6b7180;
  --card-line: rgba(40, 44, 56, .13); --card-accent: #5b6172; --card-due: #c0485f;
  background:
    linear-gradient(135deg, rgba(255, 255, 255, .85), rgba(255, 255, 255, 0) 28%, rgba(0, 0, 0, .05) 56%, rgba(255, 255, 255, .65)),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0) 0 2px, rgba(0, 0, 0, .014) 2px 4px),
    linear-gradient(180deg, #eef0f4, #dde0e7),
    var(--card-bg);
}
/* Ónix — negro profundo con destello frío sutil */
.skin-esmeralda {
  --card-bg: #14151a; --card-ink: #f2f3f7; --card-sub: rgba(255, 255, 255, .56);
  --card-line: rgba(255, 255, 255, .12); --card-accent: #8c93a3; --card-due: #e08a92;
  background:
    radial-gradient(120% 85% at 80% -12%, rgba(125, 138, 168, .20), transparent 55%),
    linear-gradient(160deg, #1c1e25, #0f1014 72%),
    var(--card-bg);
}
/* Platino — perla clara, brillo nacarado */
.skin-coral {
  --card-bg: #f2f3f6; --card-ink: #2c303a; --card-sub: #757a88;
  --card-line: rgba(44, 48, 58, .11); --card-accent: #8a90a0; --card-due: #c0485f;
  background:
    radial-gradient(105% 75% at 14% 8%, rgba(255, 255, 255, .9), transparent 50%),
    linear-gradient(135deg, #ffffff, #eceef2 46%, #f4f5f8 70%, #e3e5ec),
    var(--card-bg);
}
/* Oro — champán metálico cepillado (cálido pero sobrio) */
.skin-ambar {
  --card-bg: #efe6d2; --card-ink: #3a3220; --card-sub: #8a7d5e;
  --card-line: rgba(58, 50, 32, .13); --card-accent: #b79753; --card-due: #c0485f;
  background:
    linear-gradient(135deg, rgba(255, 255, 255, .60), rgba(255, 255, 255, 0) 26%, rgba(120, 95, 40, .12) 58%, rgba(255, 250, 235, .55)),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0) 0 2px, rgba(90, 70, 20, .022) 2px 4px),
    linear-gradient(180deg, #f3ead6, #e2d3b0),
    var(--card-bg);
}
/* Titanio — titanio oscuro azulado con degradado */
.skin-noche {
  --card-bg: #20242c; --card-ink: #eaedf3; --card-sub: rgba(255, 255, 255, .56);
  --card-line: rgba(255, 255, 255, .13); --card-accent: #7e94b0; --card-due: #dc8a93;
  background:
    radial-gradient(120% 88% at 18% -12%, rgba(150, 175, 205, .18), transparent 55%),
    linear-gradient(150deg, #272c36, #1a1d24 66%, #21252e),
    var(--card-bg);
}

/* Panel "Tus tarjetas" del Dashboard: las tarjetas NO usan el skin elegido, se adaptan al
   tema para no desentonar con la página — gris claro en modos claros, negro en modos oscuros —
   con un borde fino del acento que las distingue. El módulo Cuentas/Tarjetas sigue mostrando
   el skin real de cada tarjeta (esto solo afecta a `.dash-cards`). */
.dash-cards .tarjeta-fisica {
  --card-ink: #2a2e38; --card-sub: #6b7180; --card-line: rgba(40, 44, 56, .12);
  --card-accent: var(--brand); --card-due: var(--red);
  background: linear-gradient(135deg, #f6f7fa, #e8ebf0 55%, #eef1f5);
  border: 1px solid color-mix(in srgb, var(--brand) 42%, transparent);
  box-shadow: 0 14px 30px rgba(27, 28, 77, .12);
}
:root[data-theme="oscuro"] .dash-cards .tarjeta-fisica,
:root[data-theme="atenuado"] .dash-cards .tarjeta-fisica {
  --card-ink: #f2f3f7; --card-sub: rgba(255, 255, 255, .56); --card-line: rgba(255, 255, 255, .12);
  --card-accent: var(--brand); --card-due: #e08a92;
  background: linear-gradient(155deg, #1c1e25, #101218 72%);
  border: 1px solid color-mix(in srgb, var(--brand) 50%, transparent);
  box-shadow: 0 14px 30px rgba(0, 0, 0, .45);
}

/* Lista de tarjetas: la tarjeta mesh es el protagonista, centrada (y 1 por fila en móvil). */
.tarjetas-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 18px; justify-items: center; }
.tarjeta-item { background: none; border: 0; padding: 0; width: 100%; cursor: pointer; display: flex; justify-content: center; font-family: inherit; transition: transform .16s ease; }
.tarjeta-item:hover { transform: translateY(-3px); }
.tarjeta-item .tarjeta-fisica { margin: 0; }
/* Reordenar tarjetas (drag & drop) */
.tarjetas-grid .tarjeta-item { cursor: grab; }
.tarjetas-grid .tarjeta-item:active { cursor: grabbing; }
.tarjeta-ghost { opacity: .35; }
.tarjeta-item.tarjeta-chosen { transform: scale(1.04); }
.reorder-hint { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--muted); }
.reorder-hint svg { width: 14px; height: 14px; }
/* Preview en vivo dentro del formulario de nueva/editar tarjeta */
.tf-preview { display: flex; justify-content: center; margin: 2px 0 10px; }
.tf-preview .tarjeta-fisica { margin: 0; max-width: 330px; }
/* Detalle de tarjeta: hero (tarjeta grande + anillo de uso + KPIs) */
.tcard-hero { display: grid; grid-template-columns: 360px 1fr; gap: 24px; align-items: center; }
.tcard-visual { display: flex; justify-content: center; }
.tcard-visual .tarjeta-fisica { margin: 0; }
.tcard-stats { min-width: 0; }
.tcard-stats h2 { margin: 0 0 6px; }
.tcard-gauge-row { display: flex; align-items: center; gap: 22px; margin-top: 14px; flex-wrap: wrap; }
.tcard-ring { position: relative; width: 116px; height: 116px; flex: none; }
.tcard-ring .chart-box { height: 116px; }
.tcard-ring .ring-center b { font-size: 21px; color: var(--ink); }
.tcard-ring .ring-center span { font-size: 9px; margin-top: 2px; }
.tcard-kpis { flex: 1; min-width: 220px; display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
@media (max-width: 760px) {
  .tcard-hero { grid-template-columns: 1fr; gap: 16px; }
  .tcard-visual .tarjeta-fisica { margin: 0 auto; max-width: 360px; }
}

/* Desglose de motivos en deudas detalladas */
.mot-rows { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.mot-row { display: grid; grid-template-columns: 1fr 100px 30px; gap: 6px; align-items: center; }
.mot-row input { padding: 7px 9px; font-size: 12px; }
.mot-list { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.mot-check { justify-content: flex-start; padding: 7px 10px; background: var(--surface-2); border-radius: 10px; }
.mot-check .mot-nombre { flex: 1; }
.mot-check b { font-variant-numeric: tabular-nums; }

/* Encabezado de sección fuera de panel (agrupación por estado del ciclo) */
.sec-ciclo { margin-top: 16px; margin-bottom: 18px; }
.sec-title {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: 700; margin: 0 0 10px;
}
.sec-title svg { width: 15px; height: 15px; color: var(--brand); }

/* Nota secundaria dentro de una celda (notas, desglose de impuestos) */
.cell-note { font-size: 11px; color: var(--muted); margin-top: 2px; }

/* ─────────────────────────────────────────────────────────────
   Pestañas del módulo Cuentas y tarjetas
   ───────────────────────────────────────────────────────────── */
.tabs {
  display: inline-flex; gap: 4px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  padding: 4px; margin-bottom: 14px;
}
/* "Tu evolución": titular + tarjetas de noticias buenas/alerta */
.evo-periodos { margin-bottom: 14px; }
/* Titular del periodo: tarjeta con disco de color, no una franja teñida de lado a lado. */
.evo-titular {
  display: flex; align-items: center; gap: 11px; padding: 13px 15px; margin-bottom: 14px;
  border-radius: 16px; font-size: 14.5px; color: var(--ink);
  border: 1px solid color-mix(in srgb, var(--evo-c, var(--line)) 26%, var(--line));
  background: linear-gradient(120deg, color-mix(in srgb, var(--evo-c, var(--line)) 9%, var(--surface)), var(--surface) 62%);
}
.evo-titular svg {
  flex: none; box-sizing: border-box; width: 31px; height: 31px; padding: 6px;
  border-radius: 50%; color: var(--evo-c, var(--muted));
  background: color-mix(in srgb, var(--evo-c, var(--muted)) 15%, transparent);
}
.evo-titular.evo-bien { --evo-c: var(--green); }
.evo-titular.evo-alerta { --evo-c: var(--amber); }
.evo-titular.evo-neutral { --evo-c: var(--muted); }

/* Tarjetas de métrica. El tono ya no es una franja lateral (se veía a plantilla): va en el
   chip del icono, en la píldora del cambio y en un halo diagonal muy tenue de la esquina. */
.evo-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.evo-card {
  --evo-c: var(--muted); --evo-soft: var(--surface-2, color-mix(in srgb, var(--line) 40%, var(--surface)));
  position: relative; overflow: hidden; padding: 15px 16px 16px;
  border: 1px solid var(--line); border-radius: 18px;
  background: radial-gradient(118% 88% at 100% 0%, color-mix(in srgb, var(--evo-c) 12%, transparent), transparent 58%), var(--surface);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.evo-card:hover {
  transform: translateY(-2px); box-shadow: var(--shadow);
  border-color: color-mix(in srgb, var(--evo-c) 32%, var(--line));
}
.evo-card.evo-bien { --evo-c: var(--green); --evo-soft: var(--green-soft); }
.evo-card.evo-alerta { --evo-c: var(--red); --evo-soft: var(--red-soft); }
.evo-card-top { display: flex; align-items: center; gap: 9px; }
.evo-ic {
  display: grid; place-items: center; flex: none; width: 28px; height: 28px;
  border-radius: 9px; background: var(--evo-soft); color: var(--evo-c);
}
.evo-ic svg { width: 15px; height: 15px; }
.evo-label { font-weight: 600; font-size: 13px; color: var(--muted); flex: 1; }
.evo-card-mid { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 9px; margin: 9px 0 5px; }
.evo-chg {
  font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap;
  padding: 3px 9px; border-radius: var(--radius-pill); background: var(--evo-soft); color: var(--evo-c);
}
.evo-val { font-size: 23px; font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }
.evo-msg { font-size: 12.5px; color: var(--muted); line-height: 1.35; }
@media (prefers-reduced-motion: reduce) { .evo-card:hover { transform: none; } }
.evo-chart-cap { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); margin-bottom: 4px; }
.evo-insights { margin-top: 14px; border: 1px solid var(--line); border-radius: 14px; padding: 12px 14px; background: var(--surface); }
.evo-insights-t { display: flex; align-items: center; gap: 6px; font-weight: 800; font-size: 13px; margin-bottom: 8px; }
.evo-insights-t svg { width: 16px; height: 16px; color: var(--brand); }
.evo-insights ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 7px; }
.evo-insights li { font-size: 13px; line-height: 1.4; display: flex; align-items: flex-start; gap: 8px; }
.evo-insights li svg { flex: 0 0 auto; width: 15px; height: 15px; margin-top: 2px; color: var(--brand); }
/* Dos filas de pestañas apiladas (módulo Suscripciones): una arriba de la otra */
.tabs-stack { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin-bottom: 14px; }
.tabs-stack .tabs { margin-bottom: 0; }
.tab {
  border: 0; background: none; color: var(--muted); font-family: inherit;
  font-weight: 600; font-size: 13px; padding: 7px 16px; border-radius: var(--radius-pill);
  cursor: pointer; display: inline-flex; align-items: center; gap: 7px;
  transition: background .16s ease, color .16s ease;
}
.tab svg { width: 15px; height: 15px; }
.tab.active { background: var(--brand); color: #fff; box-shadow: 0 4px 12px color-mix(in srgb, var(--brand) 35%, transparent); animation: tabIn .26s cubic-bezier(.22, .8, .36, 1); }
@keyframes tabIn { from { transform: scale(.9); opacity: .45; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .tab.active { animation: none; } }
.tab:not(.active):hover { color: var(--ink); background: var(--surface-2); }
/* Pestaña Premium bloqueada dentro de un módulo gratis (p. ej. Formales en Deudas) */
.premium-lock { text-align: center; padding: 34px 22px; }
.premium-lock-ic { width: 52px; height: 52px; margin: 0 auto 12px; display: grid; place-items: center; border-radius: 16px; background: var(--brand-soft); color: var(--brand); }
.premium-lock-ic svg { width: 26px; height: 26px; }
.premium-lock .section-sub { max-width: 460px; margin: 4px auto 16px; }
/* "Movimientos" pagina solo en móvil: en escritorio los movimientos siguen bajo "Cuentas". */
.tab-mob-only { display: none; }

/* ─────────────────────────────────────────────────────────────
   Móvil: base de áreas táctiles grandes (mín. 44 px, guía de Apple).
   Botones más altos, menús de módulo como segmentos a todo el ancho,
   iconos de acción de 30 → 44 px. Solo afecta a pantallas ≤ 760 px;
   el escritorio queda intacto. (Fase 1: tamaños; los botones con
   texto + cuadrícula 2×2 por tarjeta llegan por módulo.)
   ───────────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  .btn { min-height: 44px; padding: 11px 16px; font-size: 14px; }
  .btn.sm { min-height: 44px; padding: 10px 14px; font-size: 14px; }
  .btn svg { width: 17px; height: 17px; }

  .icon-btn { width: 44px; height: 44px; border-radius: 12px; }
  .icon-btn svg { width: 20px; height: 20px; }

  .tabs { display: flex; width: 100%; gap: 6px; border-radius: 14px; }
  .tab { flex: 1; justify-content: center; min-height: 44px; padding: 11px 8px; border-radius: 10px; }

  .deuda-filtro { min-height: 44px; }
  .actions { gap: 10px; }
}

/* ─────────────────────────────────────────────────────────────
   Tarjetas de crédito: urgencia de pago y entrada al detalle
   ───────────────────────────────────────────────────────────── */
.tarjeta-card .open-hint { margin-top: 10px; display: flex; align-items: center; gap: 6px; }
.tarjeta-card .open-hint svg { width: 12px; height: 12px; }
.card.urg-amber, .panel.urg-amber {
  background: linear-gradient(140deg, var(--surface) 20%, var(--amber-soft) 115%);
  outline: 1px solid var(--amber);
}
.card.urg-red, .panel.urg-red {
  background: linear-gradient(140deg, var(--red-soft) 0%, var(--red-soft) 100%);
  outline: 2px solid var(--red);
  animation: pulseRed 2s ease-in-out infinite;
}
@keyframes pulseRed {
  0%, 100% { box-shadow: var(--shadow); }
  50% { box-shadow: 0 8px 28px rgba(237, 110, 117, .4); }
}

/* Dolly zoom: la vista se acerca y desvanece, el detalle entra desde grande */
#view.dolly-out { animation: dollyOut .28s ease forwards; }
@keyframes dollyOut { to { transform: scale(1.06); opacity: 0; } }
.card.dolly-focus { transform: scale(1.12); box-shadow: var(--shadow-pop); z-index: 5; }
.dolly-in { animation: dollyIn .34s cubic-bezier(.22, .8, .36, 1); }
@keyframes dollyIn { from { transform: scale(1.07); opacity: 0; } to { transform: none; opacity: 1; } }

/* Filtros discretos (movimientos, detalle de tarjeta) */
.filter-bar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.filter-bar select, .filter-bar input { font-size: 12px; padding: 7px 10px; }
.filter-bar input[type="search"] { min-width: 170px; }
.filter-bar .f-monto { width: 92px; }
/* Botón "Filtrar" (solo móvil): la barra inline vive en escritorio. */
.filter-mob { display: none; gap: 8px; align-items: center; margin-bottom: 12px; flex-wrap: wrap; }
.filter-count { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-pill); background: var(--brand); color: #fff; font-size: 11px; font-weight: 700; margin-left: 4px; }
/* Hoja de filtros (móvil): controles a todo el ancho. */
.filtros-sheet { display: grid; gap: 10px; margin: 4px 0 14px; }
.filtros-sheet input, .filtros-sheet select { width: 100%; font-size: 14px; padding: 10px 12px; }

/* Chevron "tocable" al final de cada fila de movimientos (reemplaza ✎/🗑). */
.row-chevron { display: inline-flex; align-items: center; justify-content: center; color: var(--muted); opacity: .55; transition: color .15s ease, opacity .15s ease; }
.row-chevron svg { width: 18px; height: 18px; }
.movs-panel table td:last-child { width: 28px; text-align: right; }
.row-click:hover .row-chevron { opacity: 1; color: var(--brand); }

/* Crear categoría "Otra…" en línea (bajo cualquier selector de categoría). */
.cat-new { margin-top: 8px; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface-2); display: grid; gap: 8px; }
.cat-new-input { width: 100%; }
.cat-new-hint { font-size: 12px; color: var(--muted); min-height: 17px; }
.cat-new-hint b { color: var(--ink); }
.cat-new-hint .cat-use { border: 1px solid var(--line); background: var(--surface); color: var(--brand); border-radius: var(--radius-pill); padding: 3px 10px; font-size: 12px; font-weight: 600; cursor: pointer; margin: 2px 4px 0 0; }
.cat-new-hint .cat-use:hover { background: var(--brand-soft); }
.cat-new-actions { display: flex; justify-content: flex-end; gap: 8px; }

/* Impuestos incluidos en el precio (formulario de movimiento/consumo) */
.check-row { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); cursor: pointer; }
.check-row input { accent-color: var(--brand); width: 15px; height: 15px; }
.tax-rows { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.tax-row { display: grid; grid-template-columns: 70px 1fr 110px; gap: 6px; align-items: center; }
.tax-row .tax-name { font-size: 12px; font-weight: 600; color: var(--muted); }
.tax-row input, .tax-row select { padding: 7px 9px; font-size: 12px; }

/* Montos rápidos al pagar tarjeta */
.quick-amounts { display: flex; gap: 6px; flex-wrap: wrap; }

/* Iconos de plataformas de suscripción (Simple Icons vía CDN, respaldo Lucide) */
.svc-ico {
  width: 28px; height: 28px; border-radius: 9px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--brand-soft);
}
.svc-ico img { width: 15px; height: 15px; display: block; object-fit: contain; }
.svc-ico svg { width: 14px; height: 14px; color: var(--brand); display: none; }
.svc-ico.fallback img { display: none; }
.svc-ico.fallback svg { display: block; }
/* Monograma de respaldo (cuando no hay logo ni favicon): inicial sobre el color de marca */
.svc-mono { display: none; font-weight: 800; font-size: 13px; color: #fff; line-height: 1; }
.svc-ico.mono { background: var(--svc, var(--brand)) !important; }
.svc-ico.mono img { display: none; }
.svc-ico.mono .svc-mono { display: block; }
.sub-main .svc-ico.mono .svc-mono { font-size: 20px; }
/* Chip-enlace "Abrir ↗" */
a.chip-link { text-decoration: none; cursor: pointer; transition: background .15s ease, color .15s ease; }
a.chip-link:hover { background: var(--brand); color: #fff; }
a.chip-link:hover svg { color: #fff; }
/* Icono inline de las notas (perfiles, categoría, próximo pago…): tamaño de texto, no 24px. */
.cell-note svg { width: 14px; height: 14px; vertical-align: -2px; flex: none; }
.svc-cell { display: flex; align-items: center; gap: 10px; }
.svc-cell .cell-note svg { width: 10px; height: 10px; vertical-align: -1px; }

/* ─────────────────────────────────────────────────────────────
   Tarjeta de suscripción (referencia: logo grande, precio héroe,
   pill de días restantes y acciones como píldoras)
   ───────────────────────────────────────────────────────────── */
.sub-card { display: flex; flex-direction: column; }
.sub-card.sub-off { opacity: .7; }
.sub-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.pill-days {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  padding: 4px 11px; border-radius: var(--radius-pill);
  background: var(--surface-2); color: var(--muted);
}
.pill-days.warn { background: var(--amber-soft); color: var(--amber); }
.pill-days.urgent { background: var(--red-soft); color: var(--red); }
.btn.sub-pay {
  background: var(--brand); border-radius: var(--radius-btn); padding: 7px 14px;
  display: inline-flex; align-items: center; gap: 5px;
}
.btn.sub-pay svg { width: 12px; height: 12px; }
.sub-main { display: flex; align-items: center; gap: 12px; margin: 14px 0 10px; }
.sub-main .svc-ico { width: 48px; height: 48px; border-radius: 14px; }
.sub-main .svc-ico img { width: 26px; height: 26px; }
.sub-main .svc-ico svg { width: 22px; height: 22px; }
.sub-main h3 { margin: 0 0 2px; font-size: 17px; }
.sub-bottom { display: flex; justify-content: space-between; align-items: flex-end; gap: 10px; margin-top: auto; }
.sub-price { font-variant-numeric: tabular-nums; color: var(--ink); }
.sub-price b { font-size: 30px; font-weight: 800; letter-spacing: -.5px; }
.sub-price .dec { font-size: 15px; font-weight: 700; }
.sub-price .per { font-size: 12px; color: var(--muted); margin-left: 4px; font-weight: 500; }
/* Desglose del precio: sin impuestos vs impuestos */
.sub-desglose {
  display: flex; gap: 14px; flex-wrap: wrap; margin-top: 8px; padding-top: 8px;
  border-top: 1px dashed var(--line); font-size: 11px; color: var(--muted);
}
.sub-desglose b { color: var(--ink); font-variant-numeric: tabular-nums; }

/* Confirmación apilada (cambios sin guardar) */
.modal.mini { width: min(360px, 90vw); }

/* Gestor de categorías */
.cat-title { font-size: 13px; font-weight: 700; margin: 14px 0 6px; }
.cat-chip { display: inline-flex; align-items: center; gap: 6px; }
.chip-x {
  border: 0; background: none; color: inherit; cursor: pointer;
  font-size: 13px; line-height: 1; padding: 0; opacity: .65;
}
.chip-x:hover { opacity: 1; }
.cat-form { display: flex; gap: 8px; margin-top: 16px; }
.cat-form input { flex: 1; }

/* Móvil: chips de categoría y formulario grandes y cuadrados (toque cómodo). */
@media (max-width: 760px) {
  .cat-chip {
    font-size: 14px; padding: 8px 8px 8px 14px; min-height: 44px;
    border-radius: var(--radius-md);
  }
  .cat-chip .chip-x {
    width: 32px; height: 32px; border-radius: 9px; font-size: 19px; opacity: 1;
    display: inline-flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--brand) 14%, transparent);
  }
  .cat-form { flex-wrap: wrap; gap: 10px; }
  .cat-form input { flex: 1 1 100%; min-height: 46px; }
  .cat-form select { flex: 1 1 0; min-height: 46px; }
  .cat-form .btn { flex: 1 1 0; min-height: 46px; }
}

/* ─────────────────────────────────────────────────────────────
   Ciclos por pagar: información apilada, monto y acción con aire
   ───────────────────────────────────────────────────────────── */
.ciclo-row {
  display: flex; justify-content: space-between; align-items: center; gap: 14px;
  padding: 12px 0; border-bottom: 1px solid var(--line);
}
.ciclo-row:last-child { border-bottom: 0; padding-bottom: 0; }
.ciclo-info { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.ciclo-info .k { color: var(--muted); font-size: 12px; }
.ciclo-pay { display: flex; align-items: center; gap: 10px; }

/* ─────────────────────────────────────────────────────────────
   Deudas personales: casillas de cuota y estado saldado
   ───────────────────────────────────────────────────────────── */
.cuotas { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 10px; }
.cuota {
  width: 24px; height: 24px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700; color: var(--muted);
  background: var(--surface-2); border: 1px solid var(--line);
  transition: background .2s ease, color .2s ease, transform .2s ease;
}
.cuota.pagada { background: var(--green); border-color: var(--green); color: #fff; transform: scale(1.04); }
.card.deuda-saldada { opacity: .65; }
.card.deuda-saldada .bar > span { background: var(--green); }

/* ─────────────────────────────────────────────────────────────
   Dinamismo: deslizamiento de selección (View Transitions) y
   micro-interacciones al presionar
   ───────────────────────────────────────────────────────────── */
.tab.active { view-transition-name: tab-active; }
.nav-item.active { view-transition-name: nav-active; }
::view-transition-group(tab-active),
::view-transition-group(nav-active) {
  animation-duration: .32s;
  animation-timing-function: cubic-bezier(.22, .8, .36, 1);
}
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .22s; }

.btn:active, .tab:active, .icon-btn:active { transform: scale(.96); }
.nav-item:active { transform: scale(.92); }
.card.sel:active { transform: scale(.99); }

@media (max-width: 900px) {
  /* Una columna: las tarjetas, luego el Resumen y al final la Proyección. */
  .cuentas-layout { grid-template-columns: 1fr; grid-template-areas: "cards" "resumen" "proj"; }
}

@media (max-width: 720px) {
  .sidebar { width: 62px; padding: 14px 9px; border-radius: 0 24px 24px 0; }
  .nav-item, .logout-btn { width: 42px; height: 40px; }
  .content { margin-left: 76px; padding: 16px 14px 16px 6px; }
  .user-chip { display: none; }
}

/* ─────────────────────────────────────────────────────────────
   Dial de configuración: botón circular movible que despliega
   sus opciones en abanico (referencia: Huly Dial). Vive en app.js.
   ───────────────────────────────────────────────────────────── */
/* Dial estático: sin transición de posición para que NO se deslice al cargar ni
   se "arrastre" cuando el menú lateral se expande. Aparece directo en su sitio. */
#dial { position: fixed; left: 37px; top: 36px; z-index: 70; width: 0; height: 0; }
.dial-core {
  position: absolute; transform: translate(-50%, -50%);
  width: 48px; height: 48px; border-radius: 50%; border: 0;
  background: var(--sidebar); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 10px 26px color-mix(in srgb, var(--sidebar) 40%, transparent);
  transition: background .25s ease, transform .2s ease, box-shadow .25s ease;
}
.dial-core:hover { box-shadow: 0 12px 32px color-mix(in srgb, var(--sidebar) 52%, transparent); transform: translate(-50%, -50%) scale(1.05); }
.dial-core svg { width: 21px; height: 21px; }
#dial.open .dial-core { background: var(--navy); transform: translate(-50%, -50%) rotate(90deg); }

/* Panel de opciones en CUADROS que se desliza desde el botón (reemplaza al flujo radial) */
.dial-panel {
  position: absolute; top: 42px; left: 50%;
  transform: translateX(-50%) translateY(-10px) scale(.96); transform-origin: top center;
  width: min(384px, 92vw);
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 18px; box-shadow: var(--shadow-pop); padding: 14px;
  opacity: 0; pointer-events: none; z-index: 71;
  transition: opacity .22s ease, transform .26s cubic-bezier(.22, .8, .3, 1);
}
#dial.open .dial-panel { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0) scale(1); }
/* Dial reubicado abajo-izquierda: el panel abre hacia ARRIBA y se ancla a la
   izquierda (es ancho) para no salirse de la pantalla. */
#dial.dial--up .dial-panel {
  top: auto; bottom: 56px; left: 0;
  transform: translateX(-14px) translateY(10px) scale(.96); transform-origin: bottom left;
}
#dial.dial--up.open .dial-panel { transform: translateX(-14px) translateY(0) scale(1); }
.dial-box {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  text-align: center; min-height: 78px;
  border: 1px solid var(--line); background: var(--surface-2, color-mix(in srgb, var(--line) 40%, var(--surface)));
  border-radius: 14px; padding: 12px 8px; cursor: pointer; font-family: inherit;
  font-size: 11.5px; font-weight: 600; color: var(--ink); line-height: 1.2;
  transition: transform .12s ease, background .15s ease, border-color .15s ease, color .15s ease;
}
.dial-box svg { width: 20px; height: 20px; color: var(--brand); }
.dial-box:hover { background: var(--brand); border-color: transparent; color: #fff; transform: translateY(-2px); }
.dial-box:hover svg { color: #fff; }

/* Velo de enfoque: difumina el resto de la pantalla mientras el menú está abierto */
.dial-velo {
  position: fixed; inset: 0; z-index: 64;
  background: rgba(12, 14, 28, .16);
  -webkit-backdrop-filter: blur(0px); backdrop-filter: blur(0px);
  opacity: 0; pointer-events: none;
  transition: opacity .26s ease, -webkit-backdrop-filter .26s ease, backdrop-filter .26s ease;
}
.dial-velo.on {
  opacity: 1; pointer-events: auto;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}

/* Líneas que sujetan cada opción al nodo central (diagrama de flujo) */
.dial-lineas {
  position: absolute; left: -260px; top: -260px; width: 520px; height: 520px;
  pointer-events: none; opacity: 0; transition: opacity .25s ease;
}
#dial.open .dial-lineas { opacity: 1; }
/* Las curvas se "dibujan" desde el nodo hasta cada opción (recorrido) */
.dial-lineas path {
  fill: none; stroke: color-mix(in srgb, var(--brand) 50%, transparent);
  stroke-width: 1.5; stroke-linecap: round;
  stroke-dasharray: 1; stroke-dashoffset: 1;
  transition: stroke-dashoffset .5s cubic-bezier(.4, 0, .2, 1) .06s;
}
#dial.open .dial-lineas path { stroke-dashoffset: 0; }

/* Opciones: pills con icono y texto, repartidos en pétalos legibles */
.dial-item {
  position: absolute; left: 0; top: 0;
  display: flex; align-items: center; gap: 8px;
  padding: 10px 16px 10px 13px; border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: var(--surface); color: var(--ink); cursor: pointer; white-space: nowrap;
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  box-shadow: var(--shadow-pop);
  opacity: 0; pointer-events: none;
  transform: translate(-18px, -14px) scale(.4);
  transition: transform .32s cubic-bezier(.22, .8, .3, 1), opacity .2s ease,
              background .2s ease, color .2s ease, border-color .2s ease;
  transition-delay: calc(var(--i) * 16ms);
}
.dial-item svg { width: 15px; height: 15px; color: var(--brand); flex: none; transition: color .2s ease; }
.dial-item:hover { background: var(--brand); border-color: transparent; color: #fff; }
.dial-item:hover svg { color: #fff; }
#dial.open .dial-item { opacity: 1; pointer-events: auto; }

/* Personalización: satélite propio debajo de la pestaña principal —
   opciones y apariencia, fuera de la gestión financiera */
.tema-btn {
  /* left fijo (centro del blob contraído) para que NO se desplace al expandirse el menú.
     top deja sitio ARRIBA para el dial: menú → dial → personalización, sin solaparse. */
  position: absolute; top: calc(100% + 122px); left: 37px; transform: translateX(-50%);
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--brand) 28%, var(--line));
  background: color-mix(in srgb, var(--surface) 58%, transparent);
  -webkit-backdrop-filter: blur(12px) saturate(140%); backdrop-filter: blur(12px) saturate(140%);
  color: var(--brand); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow);
  transition: transform .2s ease, background .2s ease, border-color .2s ease;
}
.tema-btn:hover {
  transform: translateX(-50%) scale(1.08);
  background: var(--brand-soft); border-color: var(--brand);
}
.tema-btn svg { width: 18px; height: 18px; }
.tema-btn .nav-label { z-index: 2; }
.tema-btn:hover .nav-label { opacity: 1; transform: translateY(-50%) translateX(0); }

/* Llamado a la acción para quien aún no tiene plan: esquina inferior derecha */
#cta-pro {
  position: fixed; right: 22px; bottom: 22px; z-index: 60;
  display: flex; align-items: center; gap: 8px;
  padding: 12px 20px; border: 0; border-radius: var(--radius-pill); cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 700; color: #fff;
  background: linear-gradient(135deg, var(--brand), var(--navy) 140%);
  animation: ctaGlow 3.2s ease-in-out infinite;
  transition: transform .2s ease, filter .2s ease;
}
#cta-pro:hover { transform: translateY(-2px); filter: brightness(1.1); }
#cta-pro svg { width: 15px; height: 15px; }
@keyframes ctaGlow {
  0%, 100% { box-shadow: 0 12px 30px color-mix(in srgb, var(--brand) 40%, transparent); }
  50% { box-shadow: 0 14px 42px color-mix(in srgb, var(--brand) 65%, transparent); }
}
@media (max-width: 720px) { #cta-pro { right: 14px; bottom: 14px; padding: 11px 16px; font-size: 12px; } }

/* Selector de acento (en el modal de tema) */
.acentos { display: flex; gap: 10px; flex-wrap: wrap; }
.acento-dot {
  width: 32px; height: 32px; border-radius: 50%; cursor: pointer;
  border: 3px solid var(--surface); outline: 2px solid transparent;
  box-shadow: var(--shadow); transition: transform .2s ease, outline-color .2s ease;
}
.acento-dot:hover { transform: scale(1.12); }
.acento-dot.activo { outline-color: var(--ink); }

/* Swatches del selector de tema */
.tema-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; }
.tema-swatch {
  border: 2px solid var(--line); border-radius: var(--radius-md); cursor: pointer;
  background: var(--surface); padding: 10px; font-family: inherit; font-size: 12px;
  font-weight: 600; color: var(--ink); text-align: left;
  display: flex; flex-direction: column; gap: 8px;
  transition: border-color .2s ease, transform .2s ease;
}
.tema-swatch:hover { transform: translateY(-2px); }
.tema-swatch.activo { border-color: var(--brand); }
.tema-swatch .muestras { display: flex; gap: 5px; }
.tema-swatch .muestras span { width: 22px; height: 22px; border-radius: 7px; border: 1px solid rgba(0, 0, 0, .08); }

/* Salir de pantalla completa: botón discreto en la esquina (solo en ese modo) */
/* Pantalla completa: opción FIJA y discreta en la esquina (entrar/salir). */
#fs-exit {
  position: fixed; top: 14px; right: 14px; z-index: 80;
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--surface); color: var(--muted); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow); opacity: .4; transition: opacity .25s ease;
}
#fs-exit:hover { opacity: 1; color: var(--ink); }
#fs-exit svg { width: 16px; height: 16px; }

/* ─────────────────────────────────────────────────────────────
   Modal de Planes (3 tarjetas + toggle de periodicidad + cupón)
   ───────────────────────────────────────────────────────────── */
.modal.modal-planes { width: min(940px, 96vw); }
.planes-head { text-align: center; margin: 0 0 2px; }
.planes-sub { text-align: center; color: var(--muted); font-size: 13px; margin: 0 0 18px; }
.planes-toggle { display: flex; justify-content: center; margin-bottom: 20px; }
.per-seg {
  display: inline-flex; gap: 4px; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--radius-pill); padding: 4px;
}
.per-seg button {
  border: 0; background: none; font-family: inherit; font-weight: 600; font-size: 13px;
  padding: 7px 18px; border-radius: var(--radius-pill); color: var(--muted); cursor: pointer;
  transition: background .2s ease, color .2s ease;
}
.per-seg button.activo { background: var(--brand); color: #fff; }

.planes-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; align-items: stretch; }
.plan-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 20px; display: flex; flex-direction: column;
}
.plan-card.popular {
  background: var(--brand); border-color: transparent; color: #fff;
  box-shadow: 0 16px 40px color-mix(in srgb, var(--brand) 40%, transparent);
}
.plan-badge {
  align-self: flex-start; background: rgba(255, 255, 255, .22); color: #fff;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  padding: 4px 11px; border-radius: var(--radius-pill); margin-bottom: 10px;
}
.plan-precio { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; min-height: 38px; }
.plan-precio b { font-size: 30px; font-weight: 800; letter-spacing: -.5px; font-variant-numeric: tabular-nums; }
.plan-precio .per { font-size: 12.5px; opacity: .7; }
.plan-precio .tachado { font-size: 15px; text-decoration: line-through; opacity: .55; font-weight: 600; }
.plan-card h3 { font-size: 18px; margin: 8px 0 4px; }
.plan-desc { font-size: 12.5px; opacity: .82; margin: 0 0 14px; }
.plan-feats { list-style: none; padding: 0; margin: 0 0 16px; display: flex; flex-direction: column; gap: 8px; font-size: 13px; flex: 1; }
.plan-feats li { display: flex; align-items: center; gap: 8px; }
.plan-feats svg { width: 15px; height: 15px; flex: none; }
.plan-card:not(.popular) .plan-feats svg { color: var(--green); }
.plan-card.popular .plan-feats svg { color: #fff; }
.plan-feats li.off { opacity: .5; }
.plan-cta { width: 100%; }
.modal .plan-card.popular .plan-cta { background: #fff; color: var(--brand); }
.modal .plan-card.popular .plan-cta:hover { filter: brightness(.97); }
.plan-actual { text-align: center; font-size: 13px; font-weight: 700; color: var(--muted); padding: 9px; }

.cupon-row { display: flex; gap: 8px; margin-top: 20px; }
.cupon-row input { flex: 1; }
/* Pie legal del punto de compra: las pasarelas exigen ver términos, privacidad y
   reembolsos antes de pagar, y que la renovación automática se anuncie. */
.planes-legal {
  margin: 18px 0 0; font-size: 12px; line-height: 1.5; color: var(--muted); text-align: center;
}
.planes-legal a { color: var(--muted); text-decoration: underline; }
.planes-legal a:hover { color: var(--brand); }
#cupon-msg { font-size: 12.5px; margin-top: 8px; min-height: 16px; }
#cupon-msg.ok { color: var(--green); }
#cupon-msg.err { color: var(--red); }

@media (max-width: 760px) { .planes-grid { grid-template-columns: 1fr; } }

/* ─────────────────────────────────────────────────────────────
   Navegación móvil: barra inferior de 1 toque + hoja de menú en
   píldoras (reemplaza al sidebar y al dial radial en pantallas
   pequeñas). El escritorio no se ve afectado. Vive en app.js.
   ───────────────────────────────────────────────────────────── */
#mnav { display: none; }

/* Hoja: presente en el DOM pero inerte hasta abrirse (para animar el slide-up) */
#msheet { position: fixed; inset: 0; z-index: 90; pointer-events: none; }
#msheet.open { pointer-events: auto; }
.msheet-bg { position: absolute; inset: 0; background: rgba(12, 14, 28, .42); opacity: 0; transition: opacity .25s ease; }
#msheet.open .msheet-bg { opacity: 1; }
.msheet-panel {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: var(--surface); border-radius: 24px 24px 0 0;
  padding: 10px 18px calc(26px + env(safe-area-inset-bottom));
  box-shadow: 0 -18px 48px rgba(12, 14, 28, .22);
  transform: translateY(100%); transition: transform .32s cubic-bezier(.22, .8, .3, 1);
  max-height: 86vh; overflow-y: auto;
}
#msheet.open .msheet-panel { transform: translateY(0); }
.msheet-grab { width: 42px; height: 5px; border-radius: 999px; background: var(--line); margin: 6px auto 12px; }
.msheet-tt { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: 14px 2px 10px; }
/* Opciones del menú móvil como CUADROS (grid de cajas), no píldoras */
.mpills { display: grid; grid-template-columns: repeat(auto-fill, minmax(98px, 1fr)); gap: 10px; }
.mpill {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 9px;
  text-align: center; min-height: 86px;
  border: 1px solid var(--line); background: var(--surface-2);
  border-radius: 16px; padding: 14px 8px; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 600; color: var(--ink); line-height: 1.2;
  transition: transform .12s ease, background .15s ease, border-color .15s ease, color .15s ease;
}
.mpill svg { width: 22px; height: 22px; color: var(--brand); flex: none; }
.mpill:active { transform: scale(.95); }
.mpill.active { background: var(--brand); border-color: transparent; color: #fff; }
.mpill.active svg { color: #fff; }
.mpill.danger { color: var(--red); }
.mpill.danger svg { color: var(--red); }

@media (max-width: 720px) {
  /* Ocultar navegación de escritorio (y el toggle de pantalla completa: en la
     PWA instalada ya se abre a pantalla completa) */
  .sidebar, #dial, .dial-velo, .tema-btn, #fs-exit { display: none !important; }
  .content { margin-left: 0; padding: 14px 18px calc(108px + env(safe-area-inset-bottom)); }

  /* "Movimientos" se ve solo en móvil dentro de Cuentas y tarjetas. */
  .tab-mob-only { display: inline-flex; }

  /* ── Barra flotante estilo iOS (Liquid Glass) ──────────────────
     NO ocupa todo el ancho ni se pega al borde: flota centrada, con
     una píldora de cristal (acciones rápidas del módulo) + un botón
     circular separado a la derecha que abre el menú general. */
  #mnav {
    display: flex; position: fixed; left: 0; right: 0; z-index: 80;
    bottom: calc(14px + env(safe-area-inset-bottom));
    justify-content: center; align-items: center; gap: 10px;
    padding: 0 14px; pointer-events: none;
  }
  #mnav > * { pointer-events: auto; }

  .mnav-pill {
    display: flex; align-items: stretch; gap: 2px;
    min-width: 0; max-width: calc(100vw - 96px); overflow-x: auto;
    padding: 6px;
    background: color-mix(in srgb, var(--surface) 76%, transparent);
    /* Blur moderado: 24px + saturate obligaba a la GPU del teléfono a re-desenfocar
       todo el scroll en cada frame (causa #1 de congelones en la barra flotante). */
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    border: 1px solid color-mix(in srgb, #fff 34%, var(--line));
    border-radius: var(--radius-pill);
    box-shadow: 0 12px 36px rgba(12, 14, 28, .22), 0 2px 8px rgba(12, 14, 28, .10);
    scrollbar-width: none;
  }
  .mnav-pill::-webkit-scrollbar { display: none; }
  .qa-item {
    flex: none; border: 0; background: transparent; cursor: pointer; font-family: inherit;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    min-width: 62px; padding: 8px 14px; border-radius: var(--radius-pill);
    color: var(--ink); font-size: 11px; font-weight: 700; line-height: 1;
    transition: transform .14s ease, background .18s ease, color .18s ease;
  }
  .qa-item svg { width: 22px; height: 22px; }
  .qa-item:active { transform: scale(.9); }
  /* Acción destacada: "blob" relleno (como la pestaña activa de la referencia) */
  .qa-item.primary { background: var(--brand); color: #fff; box-shadow: 0 6px 16px color-mix(in srgb, var(--brand) 40%, transparent); }
  .qa-item.primary svg { color: #fff; }

  .mnav-menu {
    position: relative;
    flex: none; width: 56px; height: 56px; border-radius: 50%;
    border: 1px solid color-mix(in srgb, #fff 34%, var(--line));
    background: color-mix(in srgb, var(--surface) 76%, transparent);
    /* Blur moderado: 24px + saturate obligaba a la GPU del teléfono a re-desenfocar
       todo el scroll en cada frame (causa #1 de congelones en la barra flotante). */
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    box-shadow: 0 12px 36px rgba(12, 14, 28, .22), 0 2px 8px rgba(12, 14, 28, .10);
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    color: var(--ink); transition: transform .14s ease, color .18s ease, background .18s ease;
  }
  .mnav-menu svg { width: 24px; height: 24px; }
  .mnav-menu:active { transform: scale(.92); }
  body.sheet-open .mnav-menu { color: var(--brand); background: var(--brand-soft); }

  /* En móvil las acciones de crear viven en la barra flotante: ocultamos
     los botones redundantes de la fila superior de cada módulo (siguen en
     el DOM, la barra los "pulsa"). Lo demás de la fila (p. ej. Editar
     categorías) se mantiene. Las acciones DENTRO de tarjetas/paneles no se tocan. */
  #new-acc, #new-mov, #new-card, #new-goal, #new-plist, #new-fund,
  #new-sub, #new-profile, #new-svc, #new-rec, #new-asset, #new-debt, #snap,
  #new-pdebt-cobrar, #new-pdebt-pagar { display: none; }

  /* El CTA flotante sube por encima de la barra */
  #cta-pro { bottom: calc(98px + env(safe-area-inset-bottom)); right: 14px; }
}

body.sheet-open { overflow: hidden; }

/* ─────────────────────────────────────────────────────────────
   Dashboard renovado: hero con Freedom Score + paneles ricos.
   ───────────────────────────────────────────────────────────── */
.dash-hero {
  display: grid; grid-template-columns: 1fr auto; gap: 24px; align-items: center;
  background: linear-gradient(135deg, color-mix(in srgb, var(--score-col, var(--brand)) 14%, var(--surface)), var(--surface) 68%);
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 22px 24px; margin-bottom: 22px; position: relative; overflow: hidden;
}
.dash-hero::before {
  content: ''; position: absolute; right: -70px; top: -70px; width: 230px; height: 230px;
  background: radial-gradient(circle, color-mix(in srgb, var(--score-col, var(--brand)) 28%, transparent), transparent 70%);
  pointer-events: none;
}
.dash-hero-copy { position: relative; z-index: 1; }
.dash-hero-cta { margin-top: 14px; }
.dash-greet { font-size: 13px; font-weight: 700; color: var(--muted); }
.dash-headline { font-size: clamp(22px, 3vw, 30px); font-weight: 800; margin: 6px 0 8px; letter-spacing: -.02em; }
.dash-headline b { color: var(--score-col, var(--brand)); }
.dash-msg { color: var(--muted); font-size: 14px; max-width: 46ch; }
.dash-mini { display: flex; flex-wrap: wrap; gap: 24px; margin-top: 18px; }
.dash-mini .k { display: block; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.dash-mini b { font-size: 18px; font-weight: 800; font-variant-numeric: tabular-nums; }

.dash-score { display: flex; flex-direction: column; align-items: stretch; gap: 8px; position: relative; z-index: 1; }
/* Freedom Score: SIN recuadro, integrado al hero. Número grande de fondo + línea
   de factores con puntos que resaltan (glow vía plugin en app.js) + un "sheen"
   degradado que recorre en loop. Compacto. */
.fs-card { position: relative; width: 300px; max-width: 100%; overflow: hidden; }
.fs-bignum {
  position: absolute; inset: 0 0 28px; z-index: 0; pointer-events: none;
  display: flex; align-items: center; justify-content: center; line-height: 1;
  font-size: 86px; font-weight: 800; letter-spacing: -.04em; font-variant-numeric: tabular-nums;
  color: color-mix(in srgb, var(--score-col, var(--brand)) 28%, transparent);
}
.fs-chart { position: relative; z-index: 1; height: 104px; }
/* Sheen en LOOP sin corte: una franja que entra por la izquierda, cruza y SALE del todo
   por la derecha; el salto del loop ocurre fuera de cuadro, así no se nota el reinicio. */
.fs-chart::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: 55%; z-index: 2; pointer-events: none;
  background: linear-gradient(100deg, transparent, color-mix(in srgb, var(--score-col, var(--brand)) 16%, transparent) 50%, transparent);
  transform: translateX(-200%); animation: fsSheen 3.6s linear infinite;
}
@keyframes fsSheen { to { transform: translateX(360%); } }
.fs-foot { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 2px; }
.fs-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.score-cat { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; color: var(--score-col, var(--brand)); }
@media (prefers-reduced-motion: reduce) { .fs-chart::after { animation: none; opacity: 0; } }

.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.panel-head h2 { margin: 0; }
.panel-tags { display: flex; gap: 8px; flex-wrap: wrap; }
.tag { font-size: 12px; font-weight: 700; color: var(--brand); background: var(--brand-soft, color-mix(in srgb, var(--brand) 14%, transparent)); padding: 5px 11px; border-radius: 999px; font-variant-numeric: tabular-nums; }
.tag-red { color: var(--red); background: color-mix(in srgb, var(--red) 14%, transparent); }

.donut-wrap { position: relative; }
.donut-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; pointer-events: none; }
.donut-center .k { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.donut-center b { font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }
.donut-legend { display: grid; gap: 9px; margin-top: 14px; }
.lg-item { display: grid; grid-template-columns: 12px 1fr auto 42px; align-items: center; gap: 9px; font-size: 13px; }
.lg-dot { width: 10px; height: 10px; border-radius: 3px; }
.lg-name { color: var(--ink); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lg-val { font-weight: 700; font-variant-numeric: tabular-nums; }
.lg-pct { color: var(--muted); font-size: 12px; text-align: right; }

.deuda-quick { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.dq { background: var(--surface-2, color-mix(in srgb, var(--line) 45%, var(--surface))); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.dq .k { display: block; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-bottom: 6px; }
.dq b { font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }
.dq-bal { grid-column: 1 / -1; }

@media (max-width: 720px) {
  /* Hero del Dashboard compacto: Freedom Score más pequeño y menos aire. */
  .dash-hero { grid-template-columns: 1fr; text-align: center; padding: 16px; gap: 12px; }
  .dash-mini { justify-content: center; gap: 16px; margin-top: 12px; }
  .dash-msg { margin-left: auto; margin-right: auto; }
  .dash-headline { font-size: 20px; }
  .dash-score { align-items: stretch; }
  .fs-card { width: 100%; }
  .fs-bignum { font-size: 84px; }
  /* Dashboard en una columna, más compacto (menos scroll en móvil). */
  .dash-grid { gap: 12px; }
  .dash-main, .dash-rail { gap: 12px; }
  .dash .panel { padding: 14px; }
  .dash .kpis { gap: 10px; margin-bottom: 0; }
  /* Clip de seguridad: nada se sale de la pantalla en horizontal. */
  #view { overflow-x: clip; }
  /* Tarjetas (lista): una por fila — evita el min de 320px que se salía. */
  .tarjetas-grid { grid-template-columns: 1fr; }
  /* Detalle de tarjeta: centrado, sin desbordes y anillo a tono. */
  .tcard-gauge-row { justify-content: center; }
  .tcard-kpis { min-width: 0; }
  .tcard-visual .tarjeta-fisica { max-width: 340px; width: 100%; }
}

/* ─────────────────────────────────────────────────────────────
   Dashboard bento: dos zonas (principal + rail) + capa de movimiento
   "movimiento con significado" — Etapa 1 (2026-06-19)
   ───────────────────────────────────────────────────────────── */
.dash-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 16px; align-items: start; }
.dash-main { display: grid; gap: 18px; min-width: 0; }
.dash-rail { display: grid; gap: 24px; min-width: 0; position: sticky; top: 14px; }
.dash-main > *, .dash-rail > * { margin-bottom: 0; }
/* El hero (patrimonio neto + Freedom Score) permanece visible al desplazarse, como el rail.
   Con aire arriba (top:14px) + un "tapón" del color de la página que cubre ese hueco para
   que no se asomen los paneles; el blur difumina lo que pasa por detrás y la sombra inferior
   da el efecto de que el contenido se mete por debajo (no que se corta de golpe). */
.dash-hero { position: sticky; top: 14px; z-index: 5; }
@media (min-width: 1081px) {
  .dash-hero {
    background: linear-gradient(135deg, color-mix(in srgb, var(--score-col, var(--brand)) 14%, transparent), transparent 55%),
      color-mix(in srgb, var(--surface) 86%, transparent);
    -webkit-backdrop-filter: blur(20px) saturate(1.4); backdrop-filter: blur(20px) saturate(1.4);
    /* 1.ª sombra = "tapón" del color de la página que cubre el hueco superior (no se
       recorta por overflow:hidden, a diferencia de un pseudo); 2.ª = elevación inferior. */
    box-shadow: 0 -14px 0 var(--bg), var(--shadow-pop);
  }
  /* En sticky NO levantamos el hero al pasar el cursor (descubriría el hueco) y mantenemos
     el tapón + la sombra. */
  .dash-hero:hover { transform: none; box-shadow: 0 -14px 0 var(--bg), var(--shadow-pop); }
}
/* Sheen en loop dentro del espacio de las barras de "Obligaciones próximas". */
.dash [data-dpanel="obligaciones"] .chart-box { position: relative; overflow: hidden; }
.dash [data-dpanel="obligaciones"] .chart-box::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: 42%; z-index: 2; pointer-events: none;
  background: linear-gradient(100deg, transparent, color-mix(in srgb, var(--brand) 13%, transparent) 50%, transparent);
  transform: translateX(-200%); animation: fsSheen 4.4s linear infinite;
}
/* Cabecera tipo "overview" del panel de obligaciones (titular grande + chips + histograma). */
.oblig-sub { margin: -2px 0 12px; font-size: 12.5px; color: var(--muted); }
.oblig-top { display: flex; justify-content: space-between; align-items: flex-end; flex-wrap: wrap; gap: 12px 18px; margin-bottom: 14px; }
.oblig-amount { font-size: clamp(26px, 3vw, 34px); font-weight: 800; letter-spacing: -.02em; line-height: 1; color: var(--ink); }
.oblig-chips { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.oblig-metric { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; color: var(--muted); }
.chip-pill { font-size: 12.5px; font-weight: 700; padding: 3px 10px; border-radius: var(--radius-pill); font-variant-numeric: tabular-nums; line-height: 1.5; }
.chip-pill.warn { background: var(--red-soft); color: var(--red); }
.chip-pill.brand { background: var(--brand-soft); color: var(--brand); }
.chip-pill.mute { background: var(--surface-2); color: var(--muted); }
.oblig-panel .chart-box { height: 210px; }
.dash .panel .kpis { margin-bottom: 0; }

/* Hover-lift sutil en cada panel del dashboard (premia acercarse, no se mueve solo). */
.dash .panel, .dash-hero { transition: transform .25s cubic-bezier(.2, .8, .2, 1), box-shadow .25s; }
.dash .panel:hover, .dash-hero:hover { transform: translateY(-3px); box-shadow: var(--shadow-pop); }

/* Freedom Score: al pasar el cursor el aro brilla suave y el número crece sobresaliendo
   (sin contador). Al salir, todo se desvanece en reversa gracias a las transiciones. */
.dash .ring-box { transition: filter .35s ease; cursor: default; -webkit-tap-highlight-color: transparent; }
.dash .ring-box:hover { filter: drop-shadow(0 0 14px color-mix(in srgb, var(--score-col, var(--brand)) 50%, transparent)); }
.dash .ring-center b { transition: transform .35s cubic-bezier(.2, .8, .2, 1), color .35s, text-shadow .35s; transform-origin: center; }
/* Al pasar/tocar: el número crece y se aclara a tinta, con un halo BLANCO limpio para separarlo
   del aro (sin sombra oscura). El flash negro al tocar era el tap-highlight nativo, ya desactivado. */
.dash .ring-box:hover .ring-center b {
  transform: scale(1.3); color: var(--ink);
  text-shadow: 0 0 12px var(--surface), 0 0 22px var(--surface), 0 0 6px var(--surface);
}

/* Barras de presupuesto: destello que cruza el relleno al pasar el cursor. */
.dash .budget-row .bar { overflow: hidden; }
.dash .budget-row .bar span { position: relative; overflow: hidden; }
.dash .budget-row .bar span::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-130%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .55), transparent);
}
.dash .budget-row:hover .bar span::after { animation: dashShine 1s ease; }
@keyframes dashShine { to { transform: translateX(240%); } }

/* Rail · pila de tarjetas estilo Wallet con DOS etapas:
   1) al pasar el cursor por el panel, el abanico se DESPLIEGA (cada tarjeta gana su franja).
   2) al apuntar a una tarjeta, esa salta al frente SIN moverse (solo z-index + sombra), así
      el cursor no la "pierde" y no hay parpadeo. Al salir, todo vuelve a la pila compacta. */
.dash-cards { overflow: visible; }
.dash-fan { position: relative; min-height: 238px; margin-top: 4px; transition: min-height .4s cubic-bezier(.2, .85, .2, 1); }
.dash-fcard { position: absolute; left: 0; right: 0; top: 0; cursor: pointer; transition: transform .4s cubic-bezier(.2, .85, .2, 1), filter .3s; }
.dash-fcard .tarjeta-fisica { margin: 0; max-width: none; }
.dash-fcard:nth-child(1) { z-index: 3; }
.dash-fcard:nth-child(2) { z-index: 2; transform: translateY(20px) scale(.955); }
.dash-fcard:nth-child(3) { z-index: 1; transform: translateY(40px) scale(.91); }
.dash-fan--multi:hover { min-height: 344px; }
.dash-fan--multi:hover .dash-fcard:nth-child(1) { transform: translateY(0); }
.dash-fan--multi:hover .dash-fcard:nth-child(2) { transform: translateY(78px) scale(1); }
.dash-fan--multi:hover .dash-fcard:nth-child(3) { transform: translateY(156px) scale(1); }
.dash-fan .dash-fcard:hover { z-index: 9; filter: drop-shadow(0 18px 32px rgba(27, 28, 77, .26)); }
.dash-more { text-align: center; font-size: 11px; font-weight: 600; color: var(--muted); margin-top: 8px; }
.dash-dots { display: none; }

/* Móvil: el abanico de tarjetas (que sin cursor queda apretado) se vuelve un
   CARRUSEL deslizable con scroll-snap — una tarjeta COMPLETA a la vez, deslizando
   izquierda/derecha, con puntos indicadores debajo.
   El escritorio conserva el abanico que se abre al pasar el cursor. */
@media (max-width: 720px) {
  /* min-width:0 en toda la cadena: sin esto los slides flex traen min-width:auto y
     desbordan el panel (la tarjeta se ve a medias / cortada). */
  .dash-cards { min-width: 0; }
  .dash-fan, .dash-fan--multi, .dash-fan--multi:hover { min-height: 0; }
  .dash-fan {
    display: flex; gap: 14px; width: 100%; min-width: 0; max-width: 100%;
    overflow-x: auto; scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch; padding: 8px 0 22px; scrollbar-width: none;
  }
  .dash-fan::-webkit-scrollbar { display: none; }
  .dash-fan .dash-fcard {
    position: static; transform: none !important; filter: none !important;
    flex: 0 0 100%; min-width: 0; scroll-snap-align: center;
  }
  /* Sombra más suave y contenida: el overflow del carrusel recortaba la sombra
     grande en una línea recta bajo el naipe. */
  .dash-fan .dash-fcard .tarjeta-fisica { box-shadow: 0 6px 16px rgba(27, 28, 77, .12), inset 0 0 0 1px var(--card-line); }
  .dash-dots { display: flex; justify-content: center; gap: 6px; margin-top: 10px; }
  .dash-dot { width: 7px; height: 7px; border-radius: 999px; background: var(--line); transition: width .2s ease, background .2s ease; }
  .dash-dot.on { width: 18px; background: var(--brand); }
}

/* Rail · lista compacta de suscripciones próximas. Al pasar el cursor, la fila se eleva
   como tarjeta flotante que sobresale del panel; al tocarla se abre su detalle (read-only). */
.dash-subs { display: flex; flex-direction: column; overflow: visible; }
.dash-sub { display: flex; align-items: center; gap: 11px; padding: 9px 10px; border-radius: 12px; cursor: pointer; position: relative; transition: transform .2s cubic-bezier(.2, .8, .2, 1), box-shadow .2s, background .2s; }
.dash-sub:hover { background: var(--surface); transform: scale(1.045); box-shadow: var(--shadow-pop); z-index: 3; }
.dash-sub + .dash-sub { border-top: 1px solid var(--line); }
.dash-sub .svc-ico { width: 34px; height: 34px; border-radius: 11px; flex: none; }
.dash-sub .svc-ico img { width: 19px; height: 19px; }
.dash-sub-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.dash-sub-main b { font-size: 13px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-sub-main .k { font-size: 11px; color: var(--muted); display: inline-flex; align-items: center; gap: 4px; }
.dash-sub-main .k svg { width: 12px; height: 12px; }
/* Carrusel del dashboard: control segmentado Suscripciones / Servicios */
[data-dpanel="rail-subs"] .panel-head { flex-wrap: wrap; gap: 8px; }
.rail-seg { display: inline-flex; background: var(--surface-2); border: 1px solid var(--line); border-radius: 999px; padding: 2px; gap: 2px; }
.rail-seg-b { background: none; border: 0; border-radius: 999px; padding: 5px 10px; font: inherit; font-size: 11.5px; font-weight: 600; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; transition: background .15s ease, color .15s ease; }
.rail-seg-b svg { width: 13px; height: 13px; }
.rail-seg-b.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-card); }
.rail-vp { overflow: hidden; }
.rail-track { display: flex; width: 200%; transition: transform .34s cubic-bezier(.4, .7, .2, 1); }
.rail-slide { width: 50%; flex: 0 0 50%; }
.dash-sub-amt { font-size: 14px; font-weight: 800; flex: none; }

/* "Próximo pago" sin icono — solo texto elegante (suscripciones y servicios). */
.cell-note-strong { color: var(--ink); font-weight: 600; }

/* Panel "Cuentas más activas": las 2 cuentas con más movimientos + atajos al módulo. */
.dash-accounts .dash-acc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px; }
.dash-acc { background: var(--surface-2); border: 1px solid var(--line); border-radius: 14px; padding: 13px 15px; transition: transform .2s, box-shadow .2s; }
.dash-acc:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.dash-acc-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.dash-acc-top b { font-size: 14px; font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-acc-saldo { font-size: 20px; font-weight: 800; margin: 7px 0 2px; }
.dash-acc .k { font-size: 11px; color: var(--muted); }
.dash-acc-actions { display: flex; gap: 10px; flex-wrap: wrap; }
@media (max-width: 520px) { .dash-accounts .dash-acc-grid { grid-template-columns: 1fr; } }

/* Botón "Volver" del topbar: minimalista, aparece solo cuando hay a dónde regresar. */
.nav-back {
  display: inline-flex; align-items: center; gap: 6px; margin-right: 12px;
  font-size: 13px; font-weight: 600; color: var(--muted); cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-btn, 10px);
  padding: 7px 12px; transition: color .15s, border-color .15s, transform .15s;
}
.nav-back:hover { color: var(--ink); border-color: var(--brand); transform: translateX(-2px); }
.nav-back svg { width: 16px; height: 16px; }
.nav-back[hidden] { display: none; }

/* Barra del Dashboard con el botón "Configurar paneles". */
.dash-toolbar { display: flex; justify-content: flex-end; margin-bottom: 12px; }

/* Configurador de paneles: lista con interruptores estilo iOS (mostrar/ocultar). */
.cfg-list { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.cfg-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 4px; font-size: 14px; cursor: pointer; }
.cfg-row + .cfg-row { border-top: 1px solid var(--line); }
.cfg-switch { position: relative; flex: none; width: 42px; height: 24px; }
.cfg-switch input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; margin: 0; cursor: pointer; }
.cfg-switch .cfg-knob { position: absolute; inset: 0; background: var(--line); border-radius: 999px; transition: background .18s; }
.cfg-switch .cfg-knob::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; background: #fff; border-radius: 50%; box-shadow: 0 1px 3px rgba(27, 28, 77, .25); transition: transform .18s; }
.cfg-switch input:checked + .cfg-knob { background: var(--brand); }
.cfg-switch input:checked + .cfg-knob::after { transform: translateX(18px); }

/* Entrada escalonada de los paneles al cargar el dashboard (wow de bienvenida). */
.dash-main > *, .dash-rail > * { animation: dashUp .5s both; }
.dash-main > *:nth-child(2) { animation-delay: .05s; }
.dash-main > *:nth-child(3) { animation-delay: .10s; }
.dash-main > *:nth-child(4) { animation-delay: .15s; }
.dash-main > *:nth-child(5) { animation-delay: .20s; }
.dash-main > *:nth-child(6) { animation-delay: .25s; }
.dash-rail > *:nth-child(1) { animation-delay: .12s; }
.dash-rail > *:nth-child(2) { animation-delay: .18s; }
.dash-rail > *:nth-child(3) { animation-delay: .24s; }
@keyframes dashUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

@media (max-width: 1080px) {
  .dash-grid { grid-template-columns: 1fr; }
  .dash-rail, .dash-hero { position: static; }
}

/* Accesibilidad: si el usuario pide menos movimiento, se apaga toda la capa. */
@media (prefers-reduced-motion: reduce) {
  .dash .panel, .dash-hero, .dash .ring-box, .dash .ring-center b, .dash-fan, .dash-fcard, .dash-sub, .dash-acc { transition: none; }
  .dash-main > *, .dash-rail > * { animation: none; }
  .dash .budget-row:hover .bar span::after { animation: none; }
  .dash [data-dpanel="obligaciones"] .chart-box::after { animation: none; opacity: 0; }
}

/* ─────────────────────────────────────────────────────────────
   Modales como HOJAS INFERIORES en móvil (estilo iOS): suben desde
   abajo, ocupan todo el ancho (sin desplazamiento lateral), tienen
   asa para arrastrar y se cierran deslizando hacia abajo (app.js).
   ───────────────────────────────────────────────────────────── */
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
@media (max-width: 720px) {
  .modal-bg { align-items: flex-end; z-index: 95; } /* sobre la barra inferior y el menú */
  .modal, .modal.mini, .modal.wide, .modal.modal-planes {
    position: relative; width: 100%; max-width: 100%;
    border-radius: 22px 22px 0 0;
    max-height: 92vh; padding-top: 26px;
    padding-bottom: calc(20px + env(safe-area-inset-bottom));
    animation: sheetUp .3s cubic-bezier(.22, .8, .3, 1);
    transition: transform .25s ease;
    will-change: transform;
  }
  .modal::before {
    content: ''; position: absolute; top: 9px; left: 50%; transform: translateX(-50%);
    width: 42px; height: 5px; border-radius: 999px; background: var(--line);
  }
  /* Cierre en móvil: la hoja se desliza hacia abajo (por donde salió) */
  .modal-bg.closing .modal,
  .modal-bg.closing .modal.mini,
  .modal-bg.closing .modal.wide,
  .modal-bg.closing .modal.modal-planes { animation: sheetDown .28s cubic-bezier(.4, 0, 1, 1) forwards; }
}
@keyframes sheetDown { from { transform: translateY(0); } to { transform: translateY(100%); } }

/* ─────────────────────────────────────────────────────────────
   F3 parte 2 — Cuentas en móvil: layout en una columna, filtros
   apilados y la tabla de movimientos convertida en lista de
   tarjetas estilo app de banco (fecha · descripción · monto).
   ───────────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .cuentas-layout { grid-template-columns: 1fr; gap: 12px; }
  .cuentas-grid { grid-template-columns: 1fr 1fr; }
  .resumen-panel { position: static; }

  /* Proyección colapsada: el panel se reduce al botón "Proyectar movimientos"
     (debajo del Resumen); al tocarlo se despliegan las opciones. */
  .gastos-prox { padding-top: 14px; padding-bottom: 14px; }
  /* En móvil la cabecera usa la etiqueta corta "Proyectar movimientos" en vez del h2 */
  .proj-toggle h2 { display: none; }
  .proj-toggle-mob { display: inline-flex; align-items: center; gap: 8px; flex: 1; font-weight: 700; color: var(--ink); font-size: 15px; }
  .proj-toggle-mob svg { width: 17px; height: 17px; color: var(--brand); }

  /* Paginación móvil del módulo: la pestaña "Movimientos" muestra los
     movimientos APARTE para no hacer scroll largo (en escritorio conviven). */
  .cuentas-pages[data-sub="cuentas"] .movs-panel { display: none; }
  .cuentas-pages[data-sub="movimientos"] .cuentas-layout { display: none; }
  .cuentas-pages[data-sub="movimientos"] .movs-panel { margin-top: 16px !important; }

  /* Filtros en móvil: la barra inline se oculta; se usa el botón "Filtrar" → hoja. */
  .filter-bar { display: none; }
  .filter-mob { display: flex; }

  /* Tabla de movimientos → tarjetas (solo en el panel de movimientos).
     Se prefija todo con `.movs-panel .table-wrap` para ganar en especificidad
     al patrón genérico "tabla → tarjeta etiqueta:valor" que viene más abajo. */
  .movs-panel .table-wrap { overflow: visible; }
  .movs-panel .table-wrap table, .movs-panel .table-wrap tbody { display: block; width: 100%; }
  .movs-panel .table-wrap thead { display: none; }
  /* Estilo extracto bancario: descripción amplia · monto + chevron · saldo debajo.
     `background/border/border-radius` se ANULAN explícitamente para vencer la cascada
     del patrón genérico (que sí los pone) — sin esto el marco reaparece. */
  .movs-panel .table-wrap tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas: "desc monto chevron" "fecha saldo chevron";
    column-gap: 10px; row-gap: 2px; align-items: center;
    background: transparent; border: 0; border-radius: 0; margin: 0;
    padding: 14px 2px; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  }
  .movs-panel .table-wrap tbody tr:last-child { border-bottom: 0; }
  .movs-panel .table-wrap tbody td { display: block; border: 0 !important; padding: 0; text-align: left; }
  .movs-panel .table-wrap td:nth-child(5) { grid-area: desc; font-weight: 700; color: var(--ink); font-size: 14.5px; line-height: 1.3; }
  .movs-panel .table-wrap td:nth-child(6) { grid-area: monto; text-align: right; font-weight: 800; font-size: 15px; white-space: nowrap; }
  .movs-panel .table-wrap td:nth-child(7) { grid-area: saldo; text-align: right; color: var(--muted); font-size: 12.5px; white-space: nowrap; font-variant-numeric: tabular-nums; }
  .movs-panel .table-wrap td:nth-child(1) { grid-area: fecha; color: var(--muted); font-size: 12px; }
  .movs-panel .table-wrap td:nth-child(8) { grid-area: chevron; text-align: right; color: var(--muted); align-self: center; }
  /* Ocultar columnas secundarias en móvil: tipo, cuenta, categoría. */
  .movs-panel .table-wrap td:nth-child(2), .movs-panel .table-wrap td:nth-child(3),
  .movs-panel .table-wrap td:nth-child(4) { display: none; }
  .movs-panel .table-wrap tbody td.empty { grid-column: 1 / -1; text-align: center; color: var(--muted); }
  .movs-panel .cell-note { font-size: 11.5px; }
}

/* ─────────────────────────────────────────────────────────────
   Patrón reutilizable: CUALQUIER tabla (.table-wrap) se vuelve una
   lista de tarjetas "etiqueta: valor" en móvil (Deudas, Proyecciones,
   Patrimonio, etc.). El helper table() emite data-th en cada celda.
   La lista de Movimientos conserva su diseño propio (.movs-panel).
   ───────────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .table-wrap { overflow: visible; }
  .table-wrap table, .table-wrap tbody { display: block; width: 100%; }
  .table-wrap thead { display: none; }
  .table-wrap tbody tr {
    display: block;
    background: var(--surface-2, color-mix(in srgb, var(--line) 40%, var(--surface)));
    border: 1px solid var(--line); border-radius: 14px;
    padding: 8px 14px; margin-bottom: 10px;
  }
  .table-wrap tbody td {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    padding: 6px 0; border: 0 !important; text-align: right; font-size: 13.5px;
  }
  .table-wrap tbody td + td { border-top: 1px solid color-mix(in srgb, var(--line) 60%, transparent) !important; }
  .table-wrap tbody td::before {
    content: attr(data-th); color: var(--muted); font-weight: 600; font-size: 12px;
    text-align: left; flex: none;
  }
  .table-wrap tbody td[data-th=""]::before { content: ""; display: none; }
  /* Columna de acciones (encabezado vacío) en tarjeta-tabla: botones grandes
     cuadrados, 2 por fila (mismo estándar que .card .actions y .modal .actions). */
  .table-wrap tbody td[data-th=""] { flex-wrap: wrap; gap: 8px; padding-top: 10px; }
  .table-wrap tbody td[data-th=""] > .btn,
  .table-wrap tbody td[data-th=""] > .icon-btn {
    flex: 1 1 calc(50% - 4px); width: auto; min-height: 44px; height: auto;
    border-radius: 12px; justify-content: center;
  }
  .table-wrap tbody td[data-th=""] .icon-btn { gap: 8px; font-size: 14px; font-weight: 600; padding: 10px 12px; }
  .table-wrap tbody td[data-th=""] .icon-btn .lbl { display: inline; }
  .table-wrap tbody td.empty { justify-content: center; }
  .table-wrap tbody td.empty::before { content: none; }
  /* La lista de Movimientos conserva su formato bank-style propio (definido
     arriba con `.movs-panel .table-wrap`, que ya gana en especificidad).
     Aquí solo se neutralizan las etiquetas y separadores del patrón genérico. */
  .movs-panel .table-wrap tbody td::before { content: none !important; }
  .movs-panel .table-wrap tbody td + td { border-top: 0 !important; }
}

/* ─────────────────────────────────────────────────────────────
   Compartir registro: recibo (mini factura) + animación de
   "impresión" desde una ranura. El recibo usa colores fijos (papel
   blanco) a propósito: se ve igual en cualquier tema y al capturarlo
   como PDF/JPG. Vive en app.js (compartirRegistroDeuda).
   ───────────────────────────────────────────────────────────── */
.print-overlay {
  position: fixed; inset: 0; z-index: 200; padding: 24px;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  background: rgba(12, 14, 28, .55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: 0; transition: opacity .24s ease; overflow: auto;
}
.print-overlay.show { opacity: 1; }
/* Auto-margins: centran el grupo cuando cabe; cuando el documento es más alto que la
   pantalla se clampan a 0 → arranca arriba y se puede scrollear hasta abajo sin recortar
   el encabezado (evita el clip de top que produce justify-content:center + overflow). */
.print-stage { display: flex; flex-direction: column; align-items: center; margin-top: auto; }

/* Impresora metálica con ranura (referencia: imagen del recibo) */
.printer {
  width: 360px; max-width: 86vw; height: 54px; border-radius: 12px;
  background: linear-gradient(#edeef2, #c6cad2 55%, #aab0ba);
  box-shadow: 0 12px 30px rgba(0, 0, 0, .35), inset 0 2px 2px rgba(255, 255, 255, .75), inset 0 -3px 6px rgba(0, 0, 0, .18);
  position: relative; z-index: 2;
  display: flex; align-items: flex-end; justify-content: center;
}
.printer-slot {
  width: 322px; max-width: 80vw; height: 9px; margin-bottom: 9px;
  background: #2a2d33; border-radius: 6px; box-shadow: inset 0 2px 5px rgba(0, 0, 0, .85);
}
/* Máscara que recorta el papel mientras "sale" de la ranura */
.paper-mask { width: 340px; max-width: 80vw; overflow: hidden; margin-top: -4px; z-index: 1; }
@keyframes printOut { from { transform: translateY(-100%); } to { transform: translateY(0); } }

.receipt {
  width: 340px; max-width: 80vw; background: #fff; color: #15171c;
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  padding: 26px 26px 0; border-radius: 4px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .28);
  animation: printOut 1.6s cubic-bezier(.25, .8, .3, 1) both; transform-origin: top center;
}
.rc-head { text-align: center; }
.rc-title { font-size: 26px; font-weight: 800; letter-spacing: .05em; }
.rc-brand { font-size: 11px; color: #6b7280; margin-top: 4px; letter-spacing: .02em; }
.rc-rule { border-top: 2px solid #15171c; margin: 13px 0; }
.rc-rule.dashed { border-top: 1px dashed #9aa0aa; }
.rc-row { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; font-size: 13px; margin: 5px 0; }
.rc-row > span { color: #6b7280; }
.rc-row b { color: #15171c; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.rc-colhead > span { color: #15171c; font-weight: 700; }
.rc-items { margin: 4px 0; }
.rc-item { display: flex; justify-content: space-between; gap: 14px; font-size: 13px; margin: 4px 0; }
.rc-item span { color: #15171c; }
.rc-item b { font-variant-numeric: tabular-nums; }
.rc-total > span, .rc-total b { font-size: 15px; font-weight: 800; color: #15171c; }
.rc-foot { text-align: center; margin-top: 16px; }
.rc-barcode { display: flex; align-items: stretch; justify-content: center; gap: 1px; height: 52px; margin: 6px 0 8px; }
.rc-barcode i { display: block; height: 100%; }
.rc-num { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 12px; color: #15171c; letter-spacing: .08em; }
.rc-thanks { font-size: 11px; color: #6b7280; margin-top: 6px; }
.rc-zig { display: block; width: calc(100% + 52px); margin: 16px -26px 0; }

/* ── Estado de cuenta consolidado (documento ANCHO tipo factura) ── */
.printer.printer-wide { width: 680px; max-width: 94vw; }
.printer-wide .printer-slot { width: 640px; max-width: 90vw; }
.paper-mask.paper-wide { width: 660px; max-width: 94vw; }
.estado-cuenta {
  width: 660px; max-width: 94vw; background: #fff; color: #15171c;
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  padding: 28px 32px 22px; border-radius: 4px; box-shadow: 0 18px 44px rgba(0, 0, 0, .28);
  animation: printOut 1.6s cubic-bezier(.25, .8, .3, 1) both; transform-origin: top center;
}
.ec-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; }
.ec-title { font-size: 24px; font-weight: 800; letter-spacing: .04em; }
.ec-brand { font-size: 11px; color: #6b7280; margin-top: 4px; }
.ec-doc { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 11px; color: #15171c; letter-spacing: .05em; }
.ec-rule { border-top: 2px solid #15171c; margin: 13px 0; }
.ec-sub { display: flex; gap: 32px; margin-bottom: 14px; }
.ec-sub span { display: block; color: #6b7280; font-size: 11px; }
.ec-sub b { color: #15171c; font-size: 14px; }
.ec-table { width: 100%; border-collapse: collapse; }
.ec-table th { text-align: left; color: #6b7280; font-weight: 700; font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; padding: 6px 8px; border-bottom: 1.5px solid #15171c; }
.ec-table td { padding: 8px; border-bottom: 1px solid #e9eaee; color: #15171c; font-size: 12.5px; vertical-align: middle; }
.ec-n { text-align: right; font-variant-numeric: tabular-nums; }
.ec-concepto { font-weight: 600; }
.ec-pend { font-weight: 800; }
.ec-dir { display: inline-block; font-size: 10.5px; font-weight: 700; padding: 2px 9px; border-radius: 999px; }
.ec-cob { color: #1d9e75; }
.ec-pag { color: #d85a30; }
.ec-dir.ec-cob { background: #e1f5ee; color: #0f6e56; }
.ec-dir.ec-pag { background: #faece7; color: #993c1d; }
.ec-empty { text-align: center; color: #6b7280; padding: 16px; }
.ec-totales { margin: 16px 0 0 auto; width: 300px; }
.ec-trow { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; font-size: 13px; margin: 5px 0; }
.ec-trow > span { color: #6b7280; }
.ec-trow b { font-variant-numeric: tabular-nums; }
.ec-bal { border-top: 1.5px solid #15171c; margin-top: 8px; padding-top: 8px; font-size: 15px; font-weight: 800; }
.ec-bal > span { color: #15171c; font-weight: 800; }
.ec-foot { text-align: center; margin-top: 18px; }
.ec-thanks { font-size: 11px; color: #6b7280; margin-top: 6px; }
.dcb-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* ─────────────────────────────────────────────────────────────
   Móvil (Fase 2) · ESTÁNDAR de acciones táctiles. Las filas de
   acciones de TODA tarjeta (.card .actions) y de TODO modal de
   detalle (.modal .actions) se vuelven botones cuadrados con
   icono + texto, 2 por fila (cuadrícula natural). Para que un
   icon-btn muestre texto en móvil basta con incluir un
   <span class="lbl">…</span> dentro. Solo ≤ 760 px; escritorio igual.
   ───────────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  .card .actions, .modal .actions { display: flex; flex-wrap: wrap; gap: 10px; }
  .card .actions > .btn, .card .actions > .icon-btn,
  .modal .actions > .btn, .modal .actions > .icon-btn {
    flex: 1 1 calc(50% - 5px); width: auto; min-height: 48px; height: auto;
    border-radius: 12px; justify-content: center;
  }
  .card .actions .icon-btn, .modal .actions .icon-btn { gap: 8px; font-size: 14px; font-weight: 600; padding: 10px 12px; }
  .card .actions .icon-btn .lbl, .modal .actions .icon-btn .lbl { display: inline; }

  /* Barra superior de Deudas: cada control a todo el ancho (el filtro es desplegable). */
  .deuda-toolbar { display: flex; flex-direction: column; gap: 10px; }
  .deuda-toolbar .btn,
  .deuda-toolbar .deuda-filtro { width: 100%; justify-content: center; }

  /* Banner del contacto seleccionado: acciones 2 por fila. */
  .dcb-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  .dcb-actions .btn { width: 100%; justify-content: center; }
}

.print-actions {
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 18px; margin-bottom: auto;
  opacity: 0; transform: translateY(8px); transition: opacity .3s ease, transform .3s ease; pointer-events: none;
}
.print-actions.ready { opacity: 1; transform: none; pointer-events: auto; }
@media (prefers-reduced-motion: reduce) { .receipt { animation: none; } }

/* Certificado de código (panel admin): tarjeta premium centrada con entrada suave */
.cert-shadow { border-radius: 28px; box-shadow: 0 22px 50px rgba(12, 14, 28, .35); animation: certIn .42s cubic-bezier(.25, .8, .3, 1) both; }
@keyframes certIn { from { opacity: 0; transform: translateY(14px) scale(.97); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .cert-shadow { animation: none; } }

/* ─── Campana de notificaciones ─────────────────────────────────── */
.notif-bell {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--radius-pill); border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); cursor: pointer; transition: background .15s ease, border-color .15s ease;
}
.notif-bell:hover { background: var(--surface-2); }
.notif-bell i { width: 18px; height: 18px; }
.notif-dot {
  position: absolute; top: 7px; right: 7px; width: 9px; height: 9px; border-radius: 50%;
  background: var(--red); border: 2px solid var(--surface); box-shadow: 0 0 0 1px var(--red);
}
/* Punto rojo en móvil: botón de menú y píldora "Notificaciones" */
.mnav-menu.has-dot::after, .mpill.has-dot::after {
  content: ''; position: absolute; top: 8px; right: 8px; width: 9px; height: 9px;
  border-radius: 50%; background: var(--red); border: 2px solid var(--surface);
}
.mpill { position: relative; }

.notif-pop { position: fixed; inset: 0; z-index: 240; opacity: 0; transition: opacity .18s ease; }
.notif-pop.show { opacity: 1; }
.notif-pop-bg { position: absolute; inset: 0; background: rgba(12, 14, 28, .28); }
.notif-pop-card {
  position: absolute; top: 64px; right: 24px; width: min(380px, calc(100vw - 32px));
  max-height: min(70vh, 560px); display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-pop, 0 16px 44px rgba(27, 28, 77, .16)); overflow: hidden;
  transform: translateY(-8px) scale(.98); transition: transform .2s cubic-bezier(.25,.8,.3,1);
}
.notif-pop.show .notif-pop-card { transform: none; }
.notif-pop-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.notif-pop-head b { display: inline-flex; align-items: center; gap: 8px; font-size: 15px; }
.notif-pop-head i { width: 18px; height: 18px; }
.notif-pop-body { overflow-y: auto; padding: 6px; }
.notif-item { display: flex; gap: 12px; padding: 12px; border-radius: 14px; }
.notif-item + .notif-item { margin-top: 2px; }
.notif-item.no-leida { background: var(--brand-soft); }
.notif-ic { flex: 0 0 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; border-radius: 10px; background: var(--surface-2); color: var(--brand); }
.notif-item.t-aviso .notif-ic { background: var(--amber-soft); color: var(--amber); }
.notif-item.t-mejora .notif-ic { background: var(--green-soft); color: var(--green); }
.notif-ic i { width: 18px; height: 18px; }
.notif-tx { min-width: 0; }
.notif-tx b { display: block; font-size: 14px; color: var(--ink); }
.notif-tx p { margin: 3px 0 0; font-size: 13px; color: var(--muted); line-height: 1.45; }
.notif-fecha { display: block; margin-top: 5px; font-size: 11px; color: var(--muted); }
@media (max-width: 720px) {
  .notif-pop-card { top: 12px; right: 12px; left: 12px; width: auto; max-height: 80vh; }
}

/* ─────────────────────────────────────────────────────────────
   Detalle de tarjeta de crédito en móvil: estilo app bancaria.
   Card visual arriba + KPIs compactos + movimientos como tarjetas
   (descripción · monto / fecha · categoría). El escritorio no cambia.
   ───────────────────────────────────────────────────────────── */
.only-mobile { display: none; }
@media (max-width: 720px) {
  .only-mobile { display: block; }
  .tarjeta-visual-wrap { margin: 12px 0 2px; display: flex; justify-content: center; }
  .tarjeta-head .kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

  .tcard-movs .table-wrap { overflow: visible; }
  .tcard-movs .table-wrap table, .tcard-movs .table-wrap tbody { display: block; width: 100%; }
  .tcard-movs .table-wrap thead { display: none; }
  .tcard-movs .table-wrap tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "desc monto" "meta cat";
    gap: 3px 10px; align-items: center;
    background: transparent; border: 0; border-radius: 0; margin: 0;
    padding: 13px 2px; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  }
  .tcard-movs .table-wrap tbody tr:last-child { border-bottom: 0; }
  .tcard-movs .table-wrap tbody td { display: block; border: 0 !important; padding: 0; text-align: left; }
  .tcard-movs .table-wrap tbody td::before { content: none !important; }
  .tcard-movs .table-wrap td:nth-child(4) { grid-area: desc; font-weight: 700; color: var(--ink); font-size: 14px; }
  .tcard-movs .table-wrap td:nth-child(5) { grid-area: monto; text-align: right; font-weight: 800; font-size: 15px; white-space: nowrap; }
  .tcard-movs .table-wrap td:nth-child(1) { grid-area: meta; color: var(--muted); font-size: 12px; }
  .tcard-movs .table-wrap td:nth-child(3) { grid-area: cat; text-align: right; color: var(--muted); font-size: 12px; }
  .tcard-movs .table-wrap td:nth-child(2) { display: none; }
  .tcard-movs .table-wrap tbody td.empty { grid-column: 1 / -1; text-align: center; }
}

/* Paso post-pago (PayPal): instrucciones para enviar el comprobante y activar */
.pay-ol { margin: 10px 0 16px; padding-left: 20px; display: grid; gap: 8px; font-size: 14px; color: var(--ink); }
.pay-ol li { line-height: 1.45; }
.pay-steps .actions { gap: 10px; }
.pay-steps .actions a.btn { text-decoration: none; }
.pay-hint { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--muted); margin-top: 14px; }
.pay-hint svg { width: 15px; height: 15px; color: var(--green); flex: none; }

/* ── Insignia PRO en la navegación ─────────────────────────────────────────
   Solo la ven la demo y el plan gratis: marca los módulos premium ANTES de
   tocarlos (en vez de descubrir el paywall al hacer clic). Los usuarios
   Pro/De por vida no ven ninguna insignia. */
.nav-pro,
.mpill.pro-locked > span::after {
  display: inline-block;
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: .5px;
  line-height: 1;
  padding: 2.5px 5px;
  border-radius: 6px;
  margin-left: 7px;
  vertical-align: 2px;
  color: #9a6b00;
  background: rgba(244, 187, 68, .18);
  border: 1px solid rgba(244, 187, 68, .4);
}
.mpill.pro-locked > span::after { content: 'PRO'; }

/* ── Acento personalizado (input color disfrazado de punto arcoíris) ───────── */
.acento-libre {
  position: relative;
  cursor: pointer;
  background: conic-gradient(#f66, #fc6, #6d6, #6cf, #96f, #f6c, #f66);
}
.acento-libre input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.acento-libre::after {
  content: '+';
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 800; font-size: 14px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .35);
}
/* Con color elegido: solo el aro de selección (outline de .acento-dot.activo),
   sin glifo encima — igual que al seleccionar un tema. */
.acento-libre.activo::after { content: none; }

/* ── Fondos animados (recompensas) ──────────────────────────────────────────
   Decoración detrás de los paneles: pocos nodos, solo transform/opacity (van por
   el compositor, no fuerzan layout/paint) y se desmontan al elegir "Ninguno". */
#fondo-fx { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.app > main.content { position: relative; z-index: 1; }
#fondo-fx span { position: absolute; display: block; will-change: transform, opacity; }

/* Estrellas: puntos del color de marca que titilan en posiciones fijas. */
.fx-estrellas span {
  left: var(--x); top: var(--y);
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--brand);
  opacity: 0;
  animation: fx-titilar var(--t) ease-in-out var(--d) infinite;
}
@keyframes fx-titilar {
  0%, 100% { opacity: 0; transform: scale(.5); }
  50% { opacity: .5; transform: scale(var(--s)); }
}

/* Corazones: suben flotando muy tenues desde abajo. */
.fx-corazones span { left: var(--x); bottom: -6%; animation: fx-flotar var(--t) linear var(--d) infinite; }
.fx-corazones span::before {
  content: '♥';
  display: block;
  font-size: calc(15px * var(--s) + 6px);
  color: var(--red);
}
@keyframes fx-flotar {
  0% { transform: translateY(0) translateX(0) rotate(-8deg); opacity: 0; }
  12% { opacity: .3; }
  85% { opacity: .22; }
  100% { transform: translateY(-112vh) translateX(5vw) rotate(10deg); opacity: 0; }
}

/* Hojas: caen girando suavemente. */
.fx-hojas span { left: var(--x); top: -8%; animation: fx-caer var(--t) linear var(--d) infinite; }
.fx-hojas span::before { content: '🍃'; display: block; font-size: calc(13px * var(--s) + 5px); }
@keyframes fx-caer {
  0% { transform: translateY(0) translateX(0) rotate(0deg); opacity: 0; }
  10% { opacity: .38; }
  88% { opacity: .28; }
  100% { transform: translateY(118vh) translateX(-6vw) rotate(300deg); opacity: 0; }
}

/* Ondas: dos-tres elipses gigantes del color de marca girando muy lento
   (la curvatura que asoma por abajo se lee como oleaje). */
.fx-ondas span {
  left: 50%; top: 100%;
  width: 160vmax; height: 150vmax;
  margin-left: -80vmax;
  border-radius: 41% 45% 43% 47%;
  background: color-mix(in srgb, var(--brand) 7%, transparent);
  animation: fx-ola var(--t) linear var(--d) infinite;
  transform-origin: 50% 50%;
}
.fx-ondas span:nth-child(2) { background: color-mix(in srgb, var(--brand) 5%, transparent); border-radius: 46% 42% 48% 40%; }
.fx-ondas span:nth-child(3) { background: color-mix(in srgb, var(--brand) 4%, transparent); border-radius: 43% 47% 41% 46%; }
@keyframes fx-ola { to { transform: rotate(360deg); } }

/* Tarjetas del selector de fondos (Personalización). */
.fondo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; }
.fondo-card {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 14px 10px 11px;
  background: var(--surface-2);
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  font: inherit; color: var(--ink);
  transition: transform .14s ease, border-color .14s ease;
}
.fondo-card:hover { transform: translateY(-2px); }
.fondo-card.activo { border-color: var(--brand); }
.fondo-card b { font-size: 13px; }
.fondo-prev { font-size: 22px; line-height: 1.2; color: var(--brand); }
.fondo-prev svg { width: 18px; height: 18px; }
.fondo-card .fondo-sub { font-size: 10.5px; color: var(--muted); text-align: center; line-height: 1.35; }
.fondo-card.bloqueado { opacity: .72; }
.fondo-card.bloqueado .fondo-prev { color: var(--muted); }

/* ── Chip de racha 🔥 (topbar, solo móvil) ─────────────────────────────────
   Recompensa por constancia: días seguidos entrando. Toca → detalle con las
   próximas recompensas. En escritorio no aparece (la topbar ya va cargada). */
.racha-chip {
  display: none;
  align-items: center;
  gap: 4px;
  padding: 6px 11px;
  border: 1px solid var(--amber-soft);
  border-radius: var(--radius-pill);
  background: var(--amber-soft);
  color: var(--amber);
  font: inherit;
  font-size: 13px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: transform .14s ease;
}
.racha-chip:active { transform: scale(.94); }
@media (max-width: 720px) {
  .racha-chip:not([hidden]) { display: inline-flex; }
}

/* Detalle de la racha (modal): flama grande + número, estilo "streak". */
.racha-hero { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 8px 0 2px; }
.racha-flama {
  width: 68px; height: 68px;
  border-radius: 50%;
  background: var(--amber-soft);
  display: flex; align-items: center; justify-content: center;
  font-size: 30px;
}
.racha-num { font-size: 44px; font-weight: 800; line-height: 1.15; font-variant-numeric: tabular-nums; }
.racha-sub { color: var(--muted); font-size: 13px; }

/* ── Flor de colores (selector de acento personalizado) ─────────────────────
   Pétalos superpuestos dentro de un anillo arcoíris. El pétalo bajo el cursor
   se ELEVA (escala + aro blanco + sombra) por encima de los demás, y la flor
   completa se inclina en 3D siguiendo el cursor (JS pone el transform). */
.flor-pop {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .18s ease;
}
.flor-pop.show { opacity: 1; }
.flor-velo { position: absolute; inset: 0; background: rgba(12, 13, 22, .58); }
.flor-wrap { position: relative; display: flex; flex-direction: column; align-items: center; gap: 20px; }
.flor {
  position: relative; width: 216px; height: 216px;
  /* Sin transition: la inclinación la suaviza JS (rAF + lerp). Una transition aquí
     seguía moviendo los pétalos tras parar el cursor y hacía parpadear el hover. */
  transform-style: preserve-3d;
}
.flor-anillo {
  position: absolute; inset: 0; border-radius: 50%; padding: 3px;
  background: conic-gradient(#f43f5e, #f59e0b, #a3e635, #10b981, #06b6d4, #3b82f6, #8b5cf6, #d946ef, #f43f5e);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  filter: drop-shadow(0 0 16px rgba(139, 92, 246, .35));
}
.petalo {
  position: absolute; left: 50%; top: 50%;
  width: var(--talla, 44px); height: var(--talla, 44px);
  transform: translate(calc(-50% + var(--x, 0px)), calc(-50% + var(--y, 0px)));
  border: 0; border-radius: 50%;
  background: var(--c);
  cursor: pointer;
  transition: transform .16s ease, box-shadow .16s ease;
}
/* La elevación la decide JS (el pétalo MÁS CERCANO al cursor, con histéresis) en
   vez de :hover: la inclinación 3D movía los pétalos bajo el cursor quieto y el
   hover nativo entraba/salía en bucle (el parpadeo reportado). */
.petalo.alzado, .petalo:active {
  transform: translate(calc(-50% + var(--x, 0px)), calc(-50% + var(--y, 0px))) scale(1.28);
  z-index: 6;
  box-shadow: 0 8px 20px rgba(0, 0, 0, .38), 0 0 0 3px rgba(255, 255, 255, .9);
}
.petalo-centro {
  display: flex; align-items: center; justify-content: center;
  z-index: 2;
  color: #fff;
}
.petalo-centro svg { width: 24px; height: 24px; pointer-events: none; }
.flor-tools {
  display: flex; gap: 8px;
  background: rgba(24, 25, 36, .88);
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: var(--radius-pill);
  padding: 8px 10px;
}
.flor-tools button {
  width: 46px; height: 40px;
  border: 0; border-radius: 12px;
  background: transparent; color: #cfd2e0;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.flor-tools button:hover { background: rgba(255, 255, 255, .09); }
.flor-tools svg { width: 18px; height: 18px; }

/* ── Login v2: destello de la F, halo de error, panel de privacidad y hub ── */

/* (a) Destello que recorre el chip de la F cada ~6 s: vida sin ruido. */
.brand-word em { position: relative; overflow: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .brand-word em::after {
    content: '';
    position: absolute; inset: -40%;
    background: linear-gradient(115deg, transparent 42%, rgba(255, 255, 255, .75) 50%, transparent 58%);
    transform: translateX(-140%);
    animation: fShine 6s ease-in-out 1.2s infinite;
  }
  @keyframes fShine {
    0%, 78% { transform: translateX(-140%); }
    92%, 100% { transform: translateX(140%); }
  }
}

/* (b) Halo de error: pulso rojo que emana de la tarjeta cuando algo falla. */
.login-card.halo-err { animation: haloErr .9s ease-out; }
@keyframes haloErr {
  0% { box-shadow: 0 40px 90px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .08), 0 0 0 0 rgba(237, 110, 117, .65); }
  100% { box-shadow: 0 40px 90px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .08), 0 0 0 30px rgba(237, 110, 117, 0); }
}

/* Enlace discreto al hub (esquina superior derecha). */
.login-hub {
  position: absolute; top: 18px; right: 20px; z-index: 4;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px;
  font-size: 12px; font-weight: 600; text-decoration: none;
  color: rgba(242, 244, 248, .5);
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: var(--radius-pill);
  background: rgba(16, 18, 26, .45);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  transition: color .25s ease, border-color .25s ease, box-shadow .3s ease;
}
.login-hub svg { width: 13px; height: 13px; }
.login-hub svg:last-child { width: 11px; height: 11px; opacity: .7; }
.login-hub:hover {
  color: #fff; border-color: rgba(138, 177, 255, .45);
  box-shadow: 0 8px 26px rgba(60, 105, 255, .22);
}
@media (max-width: 560px) { .login-hub span { display: none; } .login-hub { padding: 8px 10px; } }

/* Panel de privacidad: hoja lateral OSCURA que entra por la derecha; la tarjeta
   de login se desliza a la izquierda para hacerle sitio (solo en pantallas anchas;
   en móvil el panel cubre encima). */
.login-stage { transition: transform .55s cubic-bezier(.22, .8, .3, 1); }
.privacy-panel {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 6;
  width: min(440px, 100vw);
  display: flex; flex-direction: column;
  padding: 24px 30px 20px;
  background: rgba(13, 15, 23, .9);
  -webkit-backdrop-filter: blur(22px) saturate(130%); backdrop-filter: blur(22px) saturate(130%);
  border-left: 1px solid rgba(255, 255, 255, .09);
  box-shadow: -30px 0 80px rgba(0, 0, 0, .55);
  color: #dfe3f0;
  transform: translateX(105%);
  transition: transform .55s cubic-bezier(.22, .8, .3, 1);
  overflow-y: auto; overscroll-behavior: contain;
}
.login-screen.pp-open .privacy-panel { transform: translateX(0); }
@media (min-width: 1020px) {
  .login-screen.pp-open .login-stage { transform: translateX(max(-14vw, -190px)); }
}
.pp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.pp-head h3 { margin: 0; font-size: 18px; font-weight: 800; color: #fff; letter-spacing: -.2px; }
.pp-head button {
  width: 34px; height: 34px; border: 1px solid rgba(255, 255, 255, .12); border-radius: 50%;
  background: rgba(255, 255, 255, .06); color: rgba(242, 244, 248, .7);
  font-size: 17px; line-height: 1; cursor: pointer;
  transition: background .25s ease, color .25s ease;
}
.pp-head button:hover { background: rgba(255, 255, 255, .14); color: #fff; }
.pp-item { padding: 13px 0; border-bottom: 1px solid rgba(255, 255, 255, .07); }
.pp-item h4 { margin: 0 0 5px; font-size: 13.5px; font-weight: 700; color: #cfe0ff; }
.pp-item p { margin: 0; font-size: 12.5px; line-height: 1.6; color: rgba(223, 227, 240, .72); }
.pp-item b { color: #f2f4f8; }
.pp-foot { margin: 14px 0 0; font-size: 12px; color: rgba(223, 227, 240, .55); line-height: 1.6; }
.pp-foot a { color: #8ab1ff; text-decoration: none; font-weight: 600; }

/* ── Login día/noche: crear cuenta "amanece" ────────────────────────────────
   El canvas interpola fondo y partículas (js/login-fx.js); aquí solo acompañan
   el color base de la pantalla (visible un instante antes del primer frame) y
   los elementos que viven FUERA de la tarjeta oscura. */
.login-screen { transition: background .9s ease; }
.login-screen.modo-claro { background: #eef1f9; }
.login-screen.modo-claro .login-hub {
  background: rgba(255, 255, 255, .65);
  border-color: rgba(23, 28, 48, .14);
  color: rgba(23, 28, 48, .62);
}
.login-screen.modo-claro .login-hub:hover {
  color: #17203a;
  border-color: rgba(46, 92, 255, .4);
  box-shadow: 0 8px 26px rgba(60, 105, 255, .18);
}
