/* ======================================================
   LAYOUT: cabecera, navegación, Inicio, Perfil, Onboarding
   (Paso 18 · refinamiento)
   ====================================================== */

/* --- Marca / wordmark (ver public/js/marca.js) --- */
.brand { display: inline-flex; align-items: center; gap: var(--space-2); }
.brand .isotipo { width: 26px; height: 26px; display: block; flex-shrink: 0; }
.brand .isotipo svg { display: block; width: 100%; height: 100%; }
.brand-name {
    position: relative;
    font-size: var(--text-lg); font-weight: 750;
    letter-spacing: var(--tracking-tight);
    color: var(--color-text);
}
/* "IA" del wordmark en fucsia (rasgo de la identidad). */
.brand-ia { color: var(--color-primary); }
/* Destello de IA (panel 09), arriba-derecha del wordmark. Escala con la
   tipografía. Decorativo. */
.brand-name.has-star { padding-right: 0.72em; }
.brand-star {
    position: absolute; top: -0.30em; right: -0.06em;
    width: 0.62em; height: 0.62em;
    color: var(--color-primary);
    display: block;
}
.brand-star svg { display: block; width: 100%; height: 100%; }

/* --- Navegación inferior --- */
.bottom-nav {
    position: sticky; bottom: 0; z-index: 20;
    display: flex;
    width: 100%; max-width: 100%;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    padding-bottom: env(safe-area-inset-bottom, 0px);
}
/* `button.nav-mas` ("Más", Fase 4) comparte EXACTAMENTE el mismo aspecto que
   los `a` de navegación -- mismo selector combinado, ninguna regla propia --
   para que la barra se vea uniforme aunque el último ítem no sea un enlace
   de ruta sino un botón que abre un sheet (ver public/js/mas.js). El reset
   global `button { background:none; border:none; ... }` (base.css) ya deja
   el botón sin cromo de navegador. */
.bottom-nav a, .bottom-nav button.nav-mas {
    position: relative;
    flex: 1 1 0;
    min-width: 0;             /* los 5 items reparten el ancho: nunca ensanchan la barra */
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px;
    padding: 0 2px;
    min-height: var(--bottom-nav-height);
    color: var(--color-muted);
    text-decoration: none;
    font-size: 0.75rem; font-weight: 600;
}
/* La etiqueta nunca fuerza el ancho: en pantallas muy estrechas se recorta
   con puntos suspensivos antes que desbordar la barra. */
.bottom-nav a span:last-child, .bottom-nav button.nav-mas span:last-child {
    max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bottom-nav a svg, .bottom-nav button.nav-mas svg { width: 23px; height: 23px; }
/* A ≤ 340 px (p. ej. 320) se reduce ligeramente icono y texto para que
   "Movimientos" quepa entero sin recortes ni apreturas. */
@media (max-width: 340px) {
    .bottom-nav a, .bottom-nav button.nav-mas { font-size: 0.7rem; }
    .bottom-nav a svg, .bottom-nav button.nav-mas svg { width: 21px; height: 21px; }
}
/* Indicador activo: barra corta superior integrada + azul en icono y texto. */
.bottom-nav a::before, .bottom-nav button.nav-mas::before {
    content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
    width: 22px; height: 3px; border-radius: 0 0 3px 3px;
    background: var(--color-primary);
    opacity: 0;
    transition: opacity var(--transition);
}
.bottom-nav a[aria-current="page"], .bottom-nav button.nav-mas[aria-current="page"] { color: var(--color-primary-strong); }
.bottom-nav a[aria-current="page"]::before, .bottom-nav button.nav-mas[aria-current="page"]::before { opacity: 1; }

/* --- INICIO (rebranding GenkIA · C3) --- */

/* Banda de marca a sangre tras el saludo: gradiente lavanda->rosa del
   manual + dos formas orgánicas muy tenues (panel 09), detrás del texto.
   Mismo patrón que .auth, acotado a la cabecera de Inicio; nunca en tarjetas
   de dato ni listas. `overflow:hidden` recorta las siluetas al sangrado. */
.inicio-hero {
    position: relative;
    margin: calc(-1 * var(--screen-top)) calc(-1 * var(--space-4)) var(--space-5);
    padding: var(--space-5) var(--space-4) var(--space-6);
    background: var(--genkia-gradient-soft);
    overflow: hidden;
}
.inicio-hero::before {
    content: "";
    position: absolute; inset: 0; z-index: 0;
    pointer-events: none;
    background-repeat: no-repeat;
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cpath fill='%23FFB3D6' d='M100 18c34 0 62 26 66 60 4 34-16 66-52 74-36 8-74-6-84-40C20 78 34 40 66 26c11-5 22-8 34-8Z'/%3E%3C/svg%3E"),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cpath fill='%23D8CEF2' d='M104 20c36 2 60 30 62 64 2 34-20 64-56 70-36 6-72-10-80-44-8-34 8-70 42-82 10-4 22-8 32-8Z'/%3E%3C/svg%3E");
    background-position: right -66px top -96px, left -84px bottom -70px;
    background-size: 230px 230px, 200px 200px;
    opacity: 0.4;
}
.inicio-hero > * { position: relative; z-index: 1; }

.inicio-hello { font-size: var(--text-xl); font-weight: 750; letter-spacing: var(--tracking-tight); line-height: var(--lh-tight); }
.inicio-sub { color: var(--color-muted); font-size: var(--text-sm); margin-top: var(--space-1); }

/* Disponible: tarjeta con tinte lavanda + acento fucsia y el destello de IA
   junto a la etiqueta. El número (en --color-text, tabular) manda. */
.balance-block {
    position: relative;
    margin: 0 0 var(--space-5);
    padding: var(--space-5);
    background: var(--color-primary-tint);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-primary);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-soft);
}
.balance-label {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: var(--text-xs); font-weight: 700;
    letter-spacing: 0.11em; text-transform: uppercase;
    color: var(--color-primary-strong);
}
.balance-star { width: 12px; height: 12px; color: var(--color-primary); display: inline-flex; flex-shrink: 0; }
.balance-star svg { width: 100%; height: 100%; display: block; }
.balance-amount {
    font-size: var(--text-balance);
    font-weight: 800; letter-spacing: -0.025em;
    font-variant-numeric: tabular-nums; line-height: 1.05;
    margin-top: var(--space-1);
    color: var(--color-text);
    overflow-wrap: anywhere;
}
.balance-hint { font-size: var(--text-xs); color: var(--color-muted); margin-top: var(--space-1); }

/* Ingresos / gastos del mes: dos superficies suaves; el tipo se distingue
   por punto de color + etiqueta de texto (nunca sólo color). El ingreso,
   además, en verde semántico. */
.month-flow { display: flex; gap: var(--space-3); margin: var(--space-5) 0 0; }
.month-flow > div {
    flex: 1; min-width: 0;
    padding: var(--space-3) var(--space-4);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}
.month-flow .k { font-size: var(--text-xs); color: var(--color-muted); display: flex; align-items: center; gap: 5px; }
.month-flow .k::before { content: ""; width: 7px; height: 7px; border-radius: 2px; flex-shrink: 0; }
.month-flow .in .k::before { background: var(--color-income); }
.month-flow .out .k::before { background: var(--color-expense); }
.month-flow .v { font-weight: 700; font-size: var(--text-lg); font-variant-numeric: tabular-nums; margin-top: var(--space-1); }
.month-flow .in .v { color: var(--color-income); }

/* Registrar por WhatsApp: franja integrada con acento fucsia y tesela de marca. */
.wa-strip {
    display: flex; align-items: center; gap: var(--space-3);
    margin-top: var(--space-6);
    padding: var(--space-3) var(--space-4);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    border-left: 3px solid var(--color-primary);
}
.wa-strip .imark { background: var(--color-primary-soft); color: var(--color-primary-strong); }
.wa-strip .wa-main { flex: 1; min-width: 0; }
.wa-strip .wa-title { font-weight: 650; font-size: var(--text-sm); }
.wa-strip .wa-sub { font-size: var(--text-xs); color: var(--color-muted); margin-top: 1px; }
.wa-strip .wa-action { flex-shrink: 0; }

/* Estado vacío con mascota (Inicio · "En qué se te va" / Movimientos / Metas):
   la mascota centrada, una sola vez, sin saturar. Reutiliza .state (columna
   centrada, sobria). */
.state-brand .mascota { display: block; margin-bottom: var(--space-1); }
.state-brand .mascota img { display: block; }

/* --- MOVIMIENTOS (rebranding GenkIA · C4) --- */
.btn-compact { min-height: 38px; padding: 0 var(--space-3); }
/* "+ Nuevo movimiento" (acción principal, crece) + "CSV" (compacto, ancho
   de contenido) en una misma fila -- exportar CSV (Paso "exportar CSV"). */
.mov-nuevo { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-5); }
.mov-nuevo .btn-primary { flex: 1; min-width: 0; }
/* "Subir factura o recibo" (acción secundaria, Fase 6): margen propio en
   vez de la utilidad genérica `.mt-1` -- al ser MENOR que el
   `margin-bottom` de `.mov-nuevo` (arriba), el colapso de márgenes lo
   dejaba sin ningún efecto visible y el botón quedaba pegado a la fila de
   "+ Nuevo movimiento"/CSV. */
.mov-subir-factura { margin-top: var(--space-6); }
/* Separación entre "Subir factura o recibo" y la barra de filtros (Todos |
   Ingresos | Gastos | Préstamos | Anulados): PADDING, no margin -- inmune
   al colapso de márgenes entre hermanos (a diferencia de `.mov-subir-
   factura` arriba, que si depende de perder ese colapso a su favor). No
   toca `.segmented` en sí (compartida con Metas, el selector de tipo de
   "Nuevo movimiento", etc.) -- este wrapper es exclusivo de Movimientos. */
.mov-filtros { padding-top: var(--space-5); }
.mov-lista { margin-top: var(--space-5); }

/* --- PERFIL (rebranding GenkIA · C7) --- */
.profile-id { display: flex; align-items: center; gap: var(--space-4); margin: var(--space-2) 0 var(--space-6); }
/* Avatar = tesela de marca (gradiente morado->fucsia, inicial en blanco),
   mismo lenguaje que la tesela del isotipo en Auth. Texto grande -> AA. */
.avatar {
    width: 54px; height: 54px; border-radius: var(--radius-lg);
    background: var(--genkia-gradient-brand);
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-weight: 800; font-size: var(--text-xl);
    flex-shrink: 0;
    box-shadow: var(--shadow-card);
}
.profile-id .name { font-size: var(--text-lg); font-weight: 750; letter-spacing: var(--tracking-tight); overflow-wrap: anywhere; }
.profile-id .wa { font-size: var(--text-sm); color: var(--color-muted); margin-top: 1px; }
.profile-id .wa.linked { color: var(--color-income); }

/* Cada sección de Perfil = UN contenedor blanco + filas separadas dentro
   (no una card por fila). Etiqueta de sección encima, en gris. */
.settings-group { margin-top: var(--space-6); }
.settings-group:first-of-type { margin-top: var(--space-2); }
.settings-group > h2 {
    font-size: var(--text-xs); font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.08em;
    color: var(--color-muted);
    margin: 0 0 var(--space-2) var(--space-1);
}
.settings-group .rows {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-soft);
    overflow: hidden;
}
/* Pie: wordmark compacto + versión. */
.profile-foot {
    margin-top: var(--space-8);
    text-align: center;
    font-size: var(--text-xs); color: var(--color-muted);
}
.profile-foot .brand-name { font-size: var(--text-sm); color: var(--color-text); }
.profile-foot .brand-ia { color: var(--color-primary); }
.settings-group .row {
    padding-left: var(--space-4);
    padding-right: var(--space-4);
    min-height: 52px;
}
.settings-group .rows .row:last-child { border-bottom: none; }
button.settings-group__row:hover, .settings-group button.row:hover { background: var(--color-primary-tint); }

/* El valor secundario baja de jerarquía y puede ir a 2 líneas. */
.settings-group .row-title { font-weight: 600; }
.settings-group .row-title.pend { color: var(--color-muted); font-weight: 500; }
.settings-group .row .row-value { color: var(--color-faint); font-size: var(--text-xs); }

/* Badge rojo de "atención administrativa" (Paso 27.5, p. ej. "Panel
   administrativo"). Mismo lenguaje visual que .adm-nav-badge del panel
   admin (public/css/admin.css) -- no se reutiliza esa clase literal porque
   admin.css no se carga en la SPA principal, pero sí los mismos tokens. */
.row-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    margin-left: var(--space-2);
    border-radius: 999px;
    background: var(--color-danger);
    color: var(--color-surface);
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}

@media (max-width: 360px) {
    .settings-group .row { flex-wrap: wrap; position: relative; padding-right: 34px; }
    .settings-group .row .row-value { max-width: 100%; text-align: left; width: 100%; margin-top: 2px; }
    .settings-group .row .row-chevron { position: absolute; right: var(--space-4); top: var(--space-3); }
}

/* --- ANÁLISIS (rebranding GenkIA · C5) --- */
.analysis-controls { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); margin: var(--space-4) 0 var(--space-5); }
.analysis-controls .field { margin: 0; }

/* Total del período: misma métrica-tarjeta que "Disponible" en Inicio
   (tinte lavanda + acento fucsia). La frase de comparación vive dentro. */
.analysis-total {
    margin: var(--space-4) 0 var(--space-6);
    padding: var(--space-5);
    background: var(--color-primary-tint);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-primary);
    border-radius: var(--radius-lg);
}
.analysis-total .balance-label { color: var(--color-muted); }
.analysis-total .balance-amount { font-size: var(--text-2xl); overflow-wrap: anywhere; }
/* Comparación ▲▼: SIEMPRE color semántico (verde/rojo), nunca fucsia. */
.compare-line { font-size: var(--text-sm); color: var(--color-text); margin-top: var(--space-2); }
.compare-line .up { color: var(--color-expense); font-weight: 650; }
.compare-line .down { color: var(--color-income); font-weight: 650; }

/* Encabezado de bloque ("Por categoría", "Evolución diaria"): Poppins bold,
   sin las capas de estilo inline que tenía antes. */
.analysis-h {
    font-size: var(--text-lg); font-weight: 700;
    letter-spacing: var(--tracking-tight);
    margin: var(--space-6) 0 var(--space-3);
}

/* Evolución diaria: gráfico SVG propio con línea base y etiquetas mínimas. */
.timeline { margin-top: var(--space-3); }
.timeline svg { width: 100%; height: 96px; display: block; color: var(--color-primary-light); }
.timeline .axis { display: flex; justify-content: space-between; font-size: 0.6875rem; color: var(--color-faint); margin-top: var(--space-1); }
.timeline-lite { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-3); }
.timeline-lite .tl-row { display: grid; grid-template-columns: 5.5rem 1fr auto; gap: var(--space-3); align-items: center; }
.timeline-lite .tl-date { font-size: var(--text-xs); color: var(--color-muted); }
.timeline-lite .tl-bar { height: 8px; border-radius: 999px; background: var(--color-surface-2); overflow: hidden; }
.timeline-lite .tl-bar span { display: block; height: 100%; width: var(--bar-w, 0%); background: var(--color-primary-light); border-radius: 999px; }
.timeline-lite .tl-val { font-size: var(--text-xs); font-variant-numeric: tabular-nums; color: var(--color-muted); }

/* Título de pantalla con destello de IA junto a la palabra (acento de marca
   puntual, panel 09). Se usa en Análisis; el destello es decorativo. Bloque
   con margen inferior propio -> mismo ritmo hacia el selector que el
   `.head-bar` de Movimientos / Metas (no dependía de un margin-top suelto). */
.screen-title.has-star {
    display: flex; align-items: center; gap: var(--space-2);
    margin-bottom: var(--space-5);
}
.title-star { width: 14px; height: 14px; color: var(--color-primary); display: inline-flex; flex-shrink: 0; }
.title-star svg { width: 100%; height: 100%; display: block; }

/* --- METAS (rebranding GenkIA · C6) --- */
/* Relleno de la barra de progreso según el estado de la meta: activa =
   gradiente de marca (momento destacado), cumplida = verde, pausada = gris.
   El estado ya se comunica además por la .state-tag con texto. */
.goal--active .bar-fill { background: var(--genkia-gradient-brand); }
.goal--completed .bar-fill { background: var(--color-income); }
.goal--paused .bar-fill { background: var(--color-border-strong); }
/* Lista de metas envuelta en una superficie sutil (no una card por meta).
   `.cards-wrap` (Fase 4, pantalla Tarjetas) es la misma envoltura para la
   lista de tarjetas -- se combina en el mismo selector en vez de duplicar
   la regla. */
.goals-wrap, .cards-wrap {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 0 var(--space-4);
    box-shadow: var(--shadow-soft);
}
.goals-wrap .rows, .cards-wrap .rows { border-top: 0; }
.cards-wrap + .note { margin-top: 1.25rem; }

/* --- ONBOARDING (rebranding GenkIA · C8) --- */
/* Superficie de marca a sangre: gradiente lavanda->rosa del manual (mismo
   token que Auth). Formas orgánicas tenues en `.onb::before`. Los formularios
   y tarjetas van en blanco encima. Se conserva `min-height:100dvh` y el
   scroll natural (sin overflow oculto, sin alturas fijas). */
.onb { padding: var(--space-6) var(--space-4) var(--space-8); min-height: 100dvh; display: flex; flex-direction: column; background: var(--genkia-gradient-soft); position: relative; }
.onb h1 { font-size: var(--text-2xl); font-weight: 800; letter-spacing: -0.025em; line-height: var(--lh-tight); margin-bottom: var(--space-3); }
.onb .lead { color: var(--color-muted); }
.onb ul.benefits { margin: var(--space-6) 0; display: flex; flex-direction: column; gap: var(--space-4); }
.onb ul.benefits li { display: flex; gap: var(--space-3); align-items: flex-start; }
.onb ul.benefits svg { width: 20px; height: 20px; color: var(--color-primary); flex-shrink: 0; margin-top: 2px; }
.onb .spacer { flex: 1; }
.onb .steps { font-size: var(--text-xs); color: var(--color-muted); margin-bottom: var(--space-4); }
.onb .multi { display: flex; flex-direction: column; gap: var(--space-2); margin: var(--space-4) 0; }
.onb .multi label { display: flex; align-items: center; gap: var(--space-3); min-height: 48px; padding: 0 var(--space-4); border: 1px solid var(--color-border-strong); border-radius: var(--radius-sm); background: var(--color-surface); }
.onb .multi input { width: 18px; height: 18px; }

/* --- Onboarding · paso "Chatea con Atom en WhatsApp" (Paso 26, 2ª iteración) ---
   SÓLO presentación. Icono + título + explicación + aviso + pasos forman UN
   grupo compacto (`.onb-wa__group`) centrado en la altura disponible
   (`.onb-wa__stage`), SIN `justify-content:space-between`. Las acciones van
   debajo. Misma identidad de Atom; sin gradientes, glassmorphism, sombras
   fuertes ni una tarjeta que envuelva la pantalla. Alcance acotado a `.onb-wa`. */
.onb-wa__stage {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-4);
    /* Reparto asimétrico (mismo total que antes): sesga el grupo centrado
       hacia abajo para acercar las acciones al indicador de pasos sin
       pegarlos y sin alturas fijas. En 320 px el total no cambia. */
    padding: var(--space-6) 0 var(--space-1);
}
.onb-wa__group {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    max-width: 24rem;
    text-align: center;
}
.onb-wa__group h1 {
    font-size: var(--text-xl);
    font-weight: 800;
    line-height: var(--lh-tight);
    margin: var(--space-1) 0;
    max-width: 14rem;
    text-wrap: balance;
}
.onb-wa .lead {
    text-align: center;
    max-width: 22rem;
    line-height: var(--lh-normal);
    margin: 0;
}
/* La frase con énfasis va justo debajo de la introducción, sin aire extra. */
.onb-wa__group .lead + .lead { margin-top: calc(-1 * var(--space-1)); }
.onb-wa__icon {
    width: 56px; height: 56px;
    border-radius: 999px;
    background: var(--color-primary-soft);
    color: var(--color-primary);
    display: grid; place-items: center;
}
.onb-wa__icon svg { width: 26px; height: 26px; }
/* Aviso: superficie azul MUY suave, redondeada, con icono informativo.
   NO una línea vertical a la izquierda. Mismo componente en dev y prod. */
.onb-wa__note {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    width: 100%;
    margin-top: var(--space-1);
    text-align: left;
    font-size: var(--text-sm);
    line-height: var(--lh-normal);
    color: var(--color-text);
    background: var(--color-primary-tint);
    border: 1px solid var(--color-primary-soft);
    border-radius: var(--radius-lg);
    padding: var(--space-3) var(--space-4);
}
.onb-wa__note-ic { color: var(--color-primary); flex-shrink: 0; margin-top: 1px; }
.onb-wa__note-ic svg { width: 18px; height: 18px; }
.onb-wa__note strong { color: var(--color-primary); }
/* Indicador de 3 pasos: pegado al grupo, sobrio; el activo en azul y más largo. */
.onb-wa__steps {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
}
.onb-wa__steps .steps { margin-bottom: 0; }
.onb-dots { display: flex; align-items: center; gap: var(--space-2); }
.onb-dot {
    width: 7px; height: 7px;
    border-radius: 999px;
    background: var(--color-border-strong);
}
.onb-dot.is-active { width: 20px; background: var(--color-primary); }
/* Acciones: apiladas al pie, sin dispersión. */
.onb-wa__actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
    /* Un poco menos de aire antes de las acciones (sigue habiendo separación). */
    padding-top: var(--space-3);
}
.onb-wa__actions .field-error { text-align: center; margin-bottom: var(--space-1); }
.onb-wa__actions .link-btn { align-self: center; margin-top: var(--space-1); }

.dev-badge {
    display: inline-block;
    font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.04em;
    color: var(--color-muted);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    padding: 2px var(--space-2);
}

/* Onboarding · formas orgánicas + bienvenida del paso 1 (fuera del bloque
   `.onb-wa__*`, cuya composición compacta ya está fijada por sus tests). */
.onb::before {
    content: "";
    position: absolute; inset: 0; z-index: 0;
    pointer-events: none;
    background-repeat: no-repeat;
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cpath fill='%23FFB3D6' d='M100 18c34 0 62 26 66 60 4 34-16 66-52 74-36 8-74-6-84-40C20 78 34 40 66 26c11-5 22-8 34-8Z'/%3E%3C/svg%3E"),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cpath fill='%23D8CEF2' d='M104 20c36 2 60 30 62 64 2 34-20 64-56 70-36 6-72-10-80-44-8-34 8-70 42-82 10-4 22-8 32-8Z'/%3E%3C/svg%3E");
    background-position: right -70px top -104px, left -84px bottom -64px;
    background-size: 240px 240px, 208px 208px;
    opacity: 0.36;
}
.onb > * { position: relative; z-index: 1; }

/* --- Transición "preparando tu experiencia" tras confirmar el saldo ---
   Pantalla breve y automática (ver renderPreparandoExperiencia() en
   public/js/screens/onboarding.js), sin interacción del usuario. Clases
   PROPIAS (`.onb-preparando__*`): nunca reutiliza `.onb-wa__*`, que queda
   acotado a su propio paso (ver paso26-1-onboarding-wa-ux.test.js, P26.1-1).
   Monedas en CSS puro (sin librería de animación): ilusión ligera de
   "entrando a la alcancía", desactivable con prefers-reduced-motion. */
.onb-preparando__stage {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-4);
    text-align: center;
}
.onb-preparando__stage h1 {
    font-size: var(--text-xl);
    font-weight: 800;
    line-height: var(--lh-tight);
    max-width: 18rem;
    text-wrap: balance;
    margin: 0;
}
.onb-preparando__stage .lead {
    max-width: 22rem;
    margin: 0;
}
.onb-preparando__hucha {
    position: relative;
    width: 128px;
    height: 128px;
}
.onb-preparando__hucha .mascota,
.onb-preparando__hucha .mascota img { display: block; }
.onb-preparando__moneda {
    position: absolute;
    left: 50%;
    top: -24px;
    width: 16px;
    height: 16px;
    margin-left: -8px;
    border-radius: 999px;
    background: var(--color-warning);
    opacity: 0;
    animation: onb-moneda-cae 1.6s ease-in infinite;
}
.onb-preparando__moneda--2 { left: 63%; animation-delay: 0.5s; }
.onb-preparando__moneda--3 { left: 37%; animation-delay: 1s; }
@keyframes onb-moneda-cae {
    0%   { opacity: 0; top: -24px; transform: scale(0.85); }
    20%  { opacity: 1; }
    75%  { opacity: 1; }
    100% { opacity: 0; top: 58px; transform: scale(0.55); }
}
@media (prefers-reduced-motion: reduce) {
    .onb-preparando__moneda { animation: none; opacity: 0; }
}

/* Bienvenida del paso 1 (WhatsApp) y transición de saldo: únicas dos
   presencias destacadas de la mascota en todo el onboarding. */
.onb-welcome {
    display: flex; flex-direction: column; align-items: center;
    gap: var(--space-2);
    text-align: center;
    margin-bottom: var(--space-3);
}
.onb-welcome .mascota,
.onb-welcome .mascota img { display: block; }
.onb-welcome .brand-name { font-size: var(--text-xl); font-weight: 750; }
.onb-welcome__tag {
    margin: 0;
    font-size: var(--text-sm); font-weight: 500;
    color: var(--color-primary-strong);
}

/* --- AUTENTICACIÓN (rebranding GenkIA): login / registro / gate legal ---
   Superficie de marca a sangre completa: gradiente lavanda->rosa del manual
   con dos formas orgánicas muy tenues detrás (panel 09). El formulario va en
   una tarjeta blanca claramente definida (no una tarjeta dentro de otra).
   Sin glassmorphism, sin blur, sin ilustraciones de stock. */
.auth-loading {
    min-height: 100dvh;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: var(--space-3);
    color: var(--color-muted);
    background: var(--genkia-gradient-soft);
}
.auth-loading .isotipo { width: 40px; height: 40px; display: block; }
.auth-loading .isotipo svg { width: 100%; height: 100%; display: block; }

.auth {
    flex: 1;
    min-height: 100dvh;
    display: flex; flex-direction: column; justify-content: center;
    gap: var(--space-6);
    padding: var(--space-8) var(--space-5);
    position: relative;
    background: var(--genkia-gradient-soft);
}
/* Formas orgánicas del sistema visual (panel 09): siluetas de relleno
   sólido, muy tenues, detrás del contenido. Data-URI SVG plano (sin
   gradientes ni blur). Puramente decorativas. */
.auth:not(.legal-doc)::before {
    content: "";
    position: absolute; inset: 0; z-index: 0;
    pointer-events: none;
    background-repeat: no-repeat;
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cpath fill='%23FFB3D6' d='M100 18c34 0 62 26 66 60 4 34-16 66-52 74-36 8-74-6-84-40C20 78 34 40 66 26c11-5 22-8 34-8Z'/%3E%3C/svg%3E"),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cpath fill='%23D8CEF2' d='M104 20c36 2 60 30 62 64 2 34-20 64-56 70-36 6-72-10-80-44-8-34 8-70 42-82 10-4 22-8 32-8Z'/%3E%3C/svg%3E");
    background-position: right -80px top -90px, left -70px bottom -80px;
    background-size: 300px 300px, 340px 340px;
    opacity: 0.5;
}
.auth-head, .auth-card, .auth-mascota { position: relative; z-index: 1; }

/* Mascota en puntos de bienvenida (login). Discreta, centrada. */
.auth-mascota { display: flex; justify-content: center; margin-bottom: var(--space-2); }
.mascota, .mascota img { display: block; }

.auth-head { text-align: center; }
.auth-brand {
    display: inline-flex; align-items: center; gap: var(--space-3);
    margin-bottom: var(--space-3);
}
/* Tesela de marca: cuadrado con gradiente morado->fucsia + isotipo blanco
   (panel 04, versión principal). */
.auth-logo {
    width: 48px; height: 48px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--genkia-gradient-brand);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
}
.auth-logo svg { width: 30px; height: 30px; display: block; }
.auth-brand .brand-name {
    font-size: var(--text-xl); font-weight: 750;
    letter-spacing: var(--tracking-tight); color: var(--color-text);
}
/* Tagline de marca bajo el nombre (sólo en puntos de bienvenida). Discreto,
   no es una pieza publicitaria. */
.auth-tagline {
    margin: 0 0 var(--space-5);
    font-size: var(--text-sm); font-weight: 500;
    color: var(--color-primary-strong);
}
.auth-title {
    font-size: var(--text-2xl); font-weight: 800;
    letter-spacing: -0.025em; line-height: var(--lh-tight);
}
.auth-sub { color: var(--color-muted); margin-top: var(--space-2); font-size: var(--text-sm); }

.auth-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    padding: var(--space-6) var(--space-5);
}
.auth-form { display: flex; flex-direction: column; }
.auth-form .btn-primary { margin-top: var(--space-2); }
.auth-alt {
    text-align: center;
    margin-top: var(--space-5);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-border);
    font-size: var(--text-sm); color: var(--color-muted);
}
.auth-alt .link-btn { display: inline; }

@media (min-width: 480px) {
    .auth { padding: var(--space-8) var(--space-6); }
}

/* Composición de autenticación (login / registro) algo más compacta y
   refinada: cabecera + tarjeta al MISMO ancho, centradas. En 320 px la
   tarjeta cede a `width:100%` y conserva el padding lateral de `.auth`.
   Las páginas legales (.legal-doc) mantienen su ancho de lectura. */
.auth:not(.legal-doc) { align-items: center; }
.auth:not(.legal-doc) .auth-head,
.auth:not(.legal-doc) .auth-card {
    width: 100%;
    max-width: 22rem;
}

/* Campo de contraseña: el <input> ocupa todo el ancho y el botón OJO va
   DENTRO, alineado a la derecha. Botón real (foco por teclado), no tapa el
   texto (padding-right en el input). */
.pass-wrap { position: relative; display: block; }
.pass-wrap input { width: 100%; padding-right: 2.75rem; }
.pass-toggle {
    position: absolute;
    top: 0;
    right: 0;
    width: 2.75rem;
    height: 100%;
    display: grid;
    place-items: center;
    color: var(--color-muted);
    background: transparent;
    border: 0;
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.pass-toggle:hover { color: var(--color-primary); }
.pass-toggle:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.pass-toggle svg { width: 20px; height: 20px; }

/* ======================================================
   MIGRACIÓN DE ESTILOS INLINE — ETAPA 1 (F1–F32 fijos)
   ======================================================
   Cada regla reemplaza un `style=` inline fijo (ver auditoría F-nn).
   Valores LITERALES: .4rem / .35rem / .5rem / .75rem / 1rem / 1.25rem / 2rem
   NO se sustituyen por tokens --space-*. Colocadas al final de app.css (la
   hoja más tardía) para ganar los empates de especificidad frente a las
   reglas base sin subir selectores. NO se toca ninguna clase base. */

/* F4 / F19: tamaño de fuente contextual sobre `.balance-amount` (modifica-
   dores; la clase base conserva su font-size --text-balance). */
.balance-amount-xl   { font-size: var(--text-xl); }   /* hoja "Ajustar saldo" */
.balance-amount-2rem { font-size: 2rem; }             /* detalle de movimiento */

/* F5: botón "Ajustar saldo" bajo el hint dentro de la tarjeta de saldo. */
.balance-block .link-btn { margin-top: .4rem; }

/* F7: nota "asignar a una meta no cambia el saldo" tras la lista. */
.goals-wrap + .note { margin-top: 1.25rem; }

/* F8 / F9: cabecera del detalle de meta (título + etiqueta de estado). */
.goal-detail-head { display: flex; align-items: center; gap: .75rem; margin-bottom: .75rem; }
.sheet .goal-detail-head .sheet-title { margin: 0; flex: 1; }

/* F13: nota tras las acciones del sheet de meta. */
.sheet-actions + .note { margin-top: 1rem; }

/* F20: etiqueta "Anulado" bajo el monto en el detalle de movimiento. */
.mov-anulado-tag { margin: .35rem 0 0; }

/* F24 / F25 / F26: bloque "cambio de WhatsApp pendiente" en el sheet de perfil. */
.wa-pend-note { margin: .75rem 0 .35rem; }
.wa-pend-tag  { margin: 0 0 .5rem; }
.wa-pend-hint { margin: 0 0 .75rem; }

/* F29 / F32: sheet de eliminación de cuenta. */
.del-pend-note    { margin: .75rem 0 .75rem; }
.del-confirm-form { margin-top: .5rem; }

/* ======================================================
   MIGRACIÓN DE ESTILOS INLINE — ETAPA 2 (D1–D5 dinámicos)
   ======================================================
   El ANCHO de las barras es data-driven -> custom property `--bar-w`
   (`.bar-fill` y `.timeline-lite .tl-bar span` en components/app: width:
   var(--bar-w, 0%)); el JS sólo hace `style.setProperty("--bar-w", ...)`.
   El COLOR de categoría (D1/D3) pasa de `background:#hex` inline a estas
   clases. Los hexes coinciden EXACTAMENTE con PALETA_CATEGORIAS /
   COLOR_SIN_CATEGORIA de public/js/colores.js y el índice lo calcula
   `indiceColorCategoria()` con el MISMO hash/normalización de siempre.
   `.bar-fill.bar-c-N` (0,0,2,0) gana a `.bar-fill` base sin afectar a las
   barras de meta (`.goal--* .bar-fill`), que no llevan clase `bar-c-*`. */
.bar-fill.bar-c-0 { background: #581CCB; }
.bar-fill.bar-c-1 { background: #0E7490; }
.bar-fill.bar-c-2 { background: #0F7D55; }
.bar-fill.bar-c-3 { background: #B45309; }
.bar-fill.bar-c-4 { background: #C2374C; }
.bar-fill.bar-c-5 { background: #7E57C2; }
.bar-fill.bar-c-6 { background: #475569; }
.bar-fill.bar-c-7 { background: #DB2777; }
.bar-fill.bar-c-none { background: #9C93A9; }

/* ======================================================
   GRUPOS -- DENSIDAD COMPACTA (Fase intermedia, previa a abonos)
   ======================================================
   TODO scoped a `.grupos-compacto` (la raíz de #/grupos y #/grupos/:id,
   ver public/js/screens/grupos.js) -- nunca toca `.row`/`.analysis-h`/
   `.state`/`.panel`/`.screen-title` SIN calificar, que son compartidas por
   el resto de la app (Movimientos, Metas, Tarjetas, Análisis...). Móvil
   primero: menos padding vertical, misma legibilidad, mismo padding
   lateral de `.screen` (ya son 16px -- var(--space-4) -- no se duplica). */

.grupos-compacto .screen-title { font-size: var(--text-lg); }
.grupos-compacto .head-bar { margin-bottom: var(--space-3); }

/* Jerarquía visual del detalle de evento (auditoría "Grupos -- UX deuda",
   punto 8): el nombre del evento (`.event-title`, sólo en el detalle) es
   lo más protagonista -- más grande que el `.screen-title` compacto de
   arriba, que sigue rigiendo la lista de eventos sin tocarla. La fecha
   (`.screen-sub`) ya era secundaria y no cambia. `overflow-wrap` evita que
   un nombre largo sin espacios fuerce scroll horizontal (320–430px). */
.grupos-compacto .event-title { font-size: var(--text-2xl); overflow-wrap: anywhere; }

/* El valor de "Tu balance" reduce tamaño/peso para no competir con el
   nombre del evento -- sigue siendo el mismo componente `.balance-amount`
   que el resto de la app (detalle de movimiento, etc.), esta regla sólo
   aplica dentro de Grupos. */
.grupos-compacto .balance-amount-2rem { font-size: var(--text-lg); font-weight: 700; }

/* Encabezados de sección (Balances / Cómo quedar al día / Gastos /
   Actividad): mismo peso visual, menos aire alrededor. */
.grupos-compacto .analysis-h {
    font-size: var(--text-base);
    margin: var(--space-5) 0 var(--space-2);
}
.grupos-compacto .analysis-h:first-child { margin-top: 0; }

/* Separación ESPECÍFICA "Editar evento" -> "Balances" y "última fila de
   Balances" -> "Cómo quedar al día" (auditoría "Grupos -- separación de
   secciones móvil"): subir el `margin-top` genérico de `.analysis-h`
   (arriba, de `--space-4` a `--space-5`) NO tuvo ningún efecto en estos
   dos títulos -- la regla `.analysis-h:first-child { margin-top: 0; }`
   (justo arriba) tiene MÁS especificidad y siempre gana, y "Balances"/
   "Cómo quedar al día" son cada uno el primer hijo de su propio
   contenedor, así que su `margin-top` real SIEMPRE fue 0, sin importar el
   valor de `--space-4`/`--space-5`. `.groups-section` envuelve a ambos
   (public/js/screens/grupos.js -- `seccionBalances`/`seccionLiquidacion`)
   con `padding-top`, que no depende del margin del h2 ni de ese `:first-
   child` -- el espacio queda garantizado en `--space-6` (28px) sin
   importar qué venga antes, y nunca afecta a otros títulos (p. ej.
   "Gastos", que sigue sin esta clase). */
.grupos-compacto .groups-section { padding-top: var(--space-6); }

/* Separación entre el filtro "Activos/Anulados" de Gastos y la primera
   fila/tarjeta de la lista (ajuste puntual de spacing): clase propia de
   Grupos -- `.segmented` en sí (el control genérico reutilizado en el
   resto de la app) queda intacto. */
.grupos-compacto .grupos-filtro-gastos { margin-bottom: var(--space-2); }

/* Filas informativas (balances/liquidación/desglose/actividad/gastos):
   fondo sutil + borde suave en vez de línea divisoria (auditoría "Grupos
   -- sheets móviles / layout", puntos 15/16/17) -- NUNCA subrayado (se
   leería como un enlace) ni colores fuertes. Mismos tokens que ya usa
   `.month-flow > div` en el resto de la app, así que se ve coherente y
   funciona igual en claro/oscuro sin valores nuevos. Al separar cada fila
   con su propia superficie, `.rows` ya no necesita la línea superior ni
   `.row` el `border-bottom` -- el espacio entre filas lo da el `gap` de
   `.rows` (evita el "doble separador" del punto 16). Las filas que SÍ son
   botón (gastos, con chevron) mantienen suficiente alto táctil (40px
   sigue por encima del mínimo usable en una lista). */
.grupos-compacto .rows {
    border-top: none;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.grupos-compacto .row {
    min-height: 40px;
    padding: var(--space-2) var(--space-3);
    gap: var(--space-3);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
}
.grupos-compacto .row-sub { margin-top: 0; }

/* Monto SIEMPRE corto y monetario -- "Cómo quedar al día", Balances y
   Desglose por concepto (puntos 12-18): a diferencia de `.row-value`
   genérico (compartido con fechas/texto en Actividad, que sí puede
   necesitar envolver), este NUNCA se encoge ni pasa a una segunda línea;
   el bloque de nombres (`.row-title`, ya con `overflow-wrap: anywhere`)
   es el que cede espacio y envuelve primero. */
.row-money { flex-shrink: 0; max-width: none; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Colores suaves para "A favor"/"Debe" (auditoría "Grupos -- ajuste
   visual detalle", punto 2) -- Balances y "Cómo quedar al día". Reutiliza
   EXACTAMENTE los tokens ya calibrados de ingreso/gasto (variables.css:
   verde/rojo "serenos", pensados para texto legible sin leerse como una
   alerta -- el mismo criterio que ya usa `.amount-in` en Movimientos).
   Nunca colores nuevos; el estado neutral ("Al día"/"Estás al día") no
   recibe ninguna de las dos -- se queda con el `color: var(--color-muted)`
   de siempre en `.row-value`. */
.balance-favor { color: var(--color-income); }
.balance-debe { color: var(--color-expense); }

/* Panel "Tu balance": mismo componente, menos relleno vertical. */
.grupos-compacto .panel { padding: var(--space-3) var(--space-4); }

.grupos-compacto .sheet-actions { margin-top: var(--space-3); gap: var(--space-2); }

/* Estados vacíos compactos (punto 24): nunca el bloque grande de `.state`
   (pensado para una pantalla vacía completa) dentro de una sección chica
   como "Actividad" o "Cómo quedar al día". Clase propia, reutilizable en
   cualquier pantalla futura que la necesite -- no modifica `.state`. */
.state-compact {
    padding: var(--space-3) var(--space-2);
    text-align: left;
    color: var(--color-muted);
    font-size: var(--text-sm);
}
.state-compact strong { font-size: var(--text-sm); }

/* Bloques de "Desglose por concepto" (auditoría "Grupos -- UX deuda" v2,
   punto 4) -- clase GLOBAL a propósito: los sheets (`public/js/dom.js::
   abrirSheet`) se montan en `document.body`, fuera de `.grupos-compacto`,
   así que una regla calificada con ese prefijo nunca les llegaría. */
.concept-block { margin-top: var(--space-5); padding-top: var(--space-3); border-top: 1px solid var(--color-border); }
.concept-block:first-child { margin-top: 0; padding-top: 0; border-top: none; }
