/* ==========================================================================
   Momentum — Sistema de Diseño & Estilos Globales
   Gastos Familiares Semanales | Mobile-First (375px)
   Sin Frameworks | Sistema minimalista tipo shadcn/ui, acromático
   (blanco/negro/grises) con un único acento de color — rojo "ember" —
   reservado EXCLUSIVAMENTE para estados destructivos/error. Tokens tomados
   tal cual de https://styles.refero.design/style/0fd67ec5-7e9c-4ca9-b368-5d9c7388477a
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Importación de Tipografía (Google Fonts) — Geist, la familia exacta de
   la referencia (disponible en Google Fonts; no hizo falta caer al fallback
   Inter que declara la propia referencia).
   -------------------------------------------------------------------------- */
@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600&display=swap');

/* --------------------------------------------------------------------------
   1. Variables CSS del Sistema de Diseño (Design Tokens)
   -------------------------------------------------------------------------- */
:root {
  /* ---- Colores (Modo Claro — única variante definida por la referencia) ---- */
  --color-canvas: #f5f5f5;       /* fondo de página */
  --color-paper: #ffffff;        /* tarjetas, popovers */
  --color-surface-alt: #fafafa;  /* variantes sutiles / texto sobre botón relleno */
  --color-ink: #0a0a0a;          /* texto primario */
  --color-ink-soft: #171717;     /* fondo de botones rellenos */
  --color-mid-gray: #737373;     /* texto mutado */
  --color-hairline: #e5e5e5;     /* bordes */
  --color-ember: #e7000b;        /* SOLO acciones destructivas/error */

  /* ---- Compat retro: alias usados por app.js (estado de salud del
     presupuesto). Solo "excedido" usa el acento de color — es, literalmente,
     el estado de error del sistema. ---- */
  --budget-sano: var(--color-ink);
  --budget-cerca-limite: var(--color-ink);
  --budget-excedido: var(--color-ember);

  /* ---- Tipografía ---- */
  --font-geist: 'Geist', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;

  --text-caption: 12px; --leading-caption: 1.33; --tracking-caption: 0.6px;
  --text-body: 14px; --leading-body: 1.43;
  --text-body-lg: 16px; --leading-body-lg: 1.5;
  --text-subheading: 18px; --leading-subheading: 1.56;
  --text-heading-sm: 24px; --leading-heading-sm: 1.33; --tracking-heading-sm: -0.6px;
  --text-heading: 30px; --leading-heading: 1.2; --tracking-heading: -0.75px;
  --text-heading-lg: 36px; --leading-heading-lg: 1.11; --tracking-heading-lg: -0.9px;
  --text-display: 48px; --leading-display: 1.1; --tracking-display: -2.4px;

  /* ---- Espaciado (unidad base 4px) ---- */
  --spacing-4: 4px; --spacing-8: 8px; --spacing-12: 12px; --spacing-16: 16px;
  --spacing-20: 20px; --spacing-24: 24px; --spacing-48: 48px;

  /* ---- Radios ---- */
  --radius-small: 6px; --radius-nested: 10px; --radius-badges: 18px;
  --radius-inputs: 18px; --radius-buttons: 18px; --radius-cards: 24px;
  --radius-pill: 999px;

  /* ---- Sombra (único valor sutil, para separar superficies, no para "peso") ---- */
  --shadow-subtle: oklab(0.145 -0.00000143796 0.00000340492 / 0.05) 0px 0px 0px 1px, rgba(0,0,0,0.1) 0px 1px 3px 0px, rgba(0,0,0,0.1) 0px 1px 2px -1px;

  --page-max-width: 1280px;
  --card-padding: 20px;
  --element-gap: 8px;

  /* ---- Transiciones (no son parte de la referencia visual, utilitario interno) ---- */
  --transition-fast: 150ms ease;
  --transition-normal: 220ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-bounce: 280ms cubic-bezier(0.16, 1, 0.3, 1); /* ease-out-expo, sin rebote: desacelera como un objeto real, no "salta" */
}

/* --------------------------------------------------------------------------
   2. Modo Oscuro — la referencia es light-only ("el color es ausencia, no
   expresión"); esta es una inversión tonal propia, coherente con el mismo
   espíritu acromático: fondos casi negros, texto casi blanco, mismo único
   acento rojo "ember" para error (sin cambios de matiz entre temas).
   Activable por [data-theme="dark"]/.dark/.dark-theme, o por preferencia
   del SO si no se forzó un tema.
   -------------------------------------------------------------------------- */
[data-theme="dark"],
.dark,
.dark-theme {
  --color-canvas: #0a0a0a;
  --color-paper: #171717;
  --color-surface-alt: #1f1f1f;
  --color-ink: #fafafa;
  --color-ink-soft: #e5e5e5;
  --color-mid-gray: #a1a1aa;
  --color-hairline: #262626;
  --color-ember: #e7000b;

  --shadow-subtle: 0 0 0 1px rgba(255,255,255,0.08), 0 1px 3px rgba(0,0,0,0.6), 0 1px 2px rgba(0,0,0,0.5);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not(.light) {
    --color-canvas: #0a0a0a;
    --color-paper: #171717;
    --color-surface-alt: #1f1f1f;
    --color-ink: #fafafa;
    --color-ink-soft: #e5e5e5;
    --color-mid-gray: #a1a1aa;
    --color-hairline: #262626;
    --color-ember: #e7000b;

    --shadow-subtle: 0 0 0 1px rgba(255,255,255,0.08), 0 1px 3px rgba(0,0,0,0.6), 0 1px 2px rgba(0,0,0,0.5);
  }
}

/* --------------------------------------------------------------------------
   3. Reseteo y Base Tipográfica
   -------------------------------------------------------------------------- */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
}

html {
  font-size: 16px;
  scroll-behavior: smooth;
  text-size-adjust: 100%;
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  background-color: var(--color-canvas);
  color: var(--color-ink);
  font-family: var(--font-geist);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  transition: background-color var(--transition-normal), color var(--transition-normal);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-geist);
  color: var(--color-ink);
  font-weight: var(--font-weight-semibold);
}

h1 { font-size: var(--text-heading-sm); line-height: var(--leading-heading-sm); letter-spacing: var(--tracking-heading-sm); }
h2 { font-size: var(--text-subheading); line-height: var(--leading-subheading); }
h3 { font-size: var(--text-body-lg); line-height: var(--leading-body-lg); font-weight: var(--font-weight-semibold); }
h4 { font-size: var(--text-body); font-weight: var(--font-weight-semibold); }

p { color: var(--color-mid-gray); }

a {
  color: var(--color-ink);
  text-decoration: none;
  transition: color var(--transition-fast);
}

button, input, select, textarea {
  font-family: inherit;
  font-size: inherit;
  border: none;
  outline: none;
  background: none;
}

button { cursor: pointer; user-select: none; }

/* Anillo de foco solo para navegación por teclado (no aparece con mouse/touch).
   El reset de arriba saca el outline nativo en TODO elemento interactivo sin
   dejar ningún reemplazo — eso deja la app inusable con teclado. Este bloque
   es el único cambio que lo corrige, sin tocar la apariencia a simple vista.
   --color-ink ya se invierte solo en modo oscuro (ver sección 2), así que no
   hace falta ningún override extra acá. */
:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   4. Cifras Numéricas y Monetarias Tabulares
   -------------------------------------------------------------------------- */
.tabular-nums,
.num,
.amount,
.currency,
.stat-value,
.budget-amount,
.budget-health__value,
.expense-amount,
input[type="number"] {
  font-family: var(--font-geist);
  font-variant-numeric: tabular-nums;
  -moz-font-feature-settings: "tnum";
  -webkit-font-feature-settings: "tnum";
  font-feature-settings: "tnum";
}

/* --------------------------------------------------------------------------
   5. Contenedor de la Aplicación (Mobile-First 375px)
   -------------------------------------------------------------------------- */
.app-container {
  width: 100%;
  min-width: 320px;
  max-width: 480px;
  margin-left: auto;
  margin-right: auto;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 0 var(--spacing-16) 6.5rem var(--spacing-16);
  position: relative;
  display: flex;
  flex-direction: column;
}

@media (min-width: 375px) {
  .app-container {
    padding-left: var(--spacing-20);
    padding-right: var(--spacing-20);
  }
}

/* --------------------------------------------------------------------------
   6. Encabezado (.header)
   -------------------------------------------------------------------------- */
.header {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-16) var(--spacing-4) var(--spacing-12) var(--spacing-4);
  background-color: color-mix(in srgb, var(--color-paper) 86%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--color-hairline);
  transition: background-color var(--transition-normal), border-color var(--transition-normal);
}

.header__title-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.header__brand {
  font-family: var(--font-geist);
  font-size: var(--text-subheading);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  display: flex;
  align-items: center;
  gap: 6px;
  letter-spacing: -0.01em;
}

.header__subtitle {
  font-size: var(--text-caption);
  font-weight: var(--font-weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caption);
  color: var(--color-mid-gray);
}

.header__actions { display: flex; align-items: center; gap: var(--spacing-8); }

.header__btn-icon {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-pill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background-color: var(--color-paper);
  color: var(--color-ink);
  border: 1px solid var(--color-hairline);
  transition: transform var(--transition-fast), background-color var(--transition-fast);
}

.header__btn-icon:active { transform: scale(0.92); }

/* -- Marca / wordmark (login, header) -- */
.brand-mark {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--color-ink);
}

/* --------------------------------------------------------------------------
   7. Tarjetas (.card)
   -------------------------------------------------------------------------- */
.card {
  position: relative;
  background-color: var(--color-paper);
  border-radius: var(--radius-cards);
  padding: var(--card-padding);
  margin-bottom: var(--spacing-16);
  box-shadow: var(--shadow-subtle);
  border: 1px solid var(--color-hairline);
  transition: box-shadow var(--transition-normal), background-color var(--transition-normal), border-color var(--transition-normal);
  overflow: hidden;
}

.card--mint,
.card-mint {
  background-color: var(--color-surface-alt);
}

.card--interactive { cursor: pointer; }
.card--interactive:active { transform: scale(0.99); }

.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--spacing-16);
}

.card__title {
  font-size: var(--text-body-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
}

.card__caption { font-size: var(--text-caption); color: var(--color-mid-gray); }

.card__body { display: flex; flex-direction: column; gap: var(--spacing-12); }

.card__footer {
  margin-top: var(--spacing-20);
  padding-top: var(--spacing-12);
  border-top: 1px solid var(--color-hairline);
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--text-caption);
  color: var(--color-mid-gray);
}

/* --------------------------------------------------------------------------
   8. Botones — primario (relleno), secundario/ghost, outline
   -------------------------------------------------------------------------- */
.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-8);
  width: 100%;
  padding: 0.85rem 1.5rem;
  border-radius: var(--radius-buttons);
  background-color: var(--color-ink-soft);
  color: var(--color-surface-alt);
  font-family: var(--font-geist);
  font-size: var(--text-body-lg);
  font-weight: var(--font-weight-semibold);
  box-shadow: none;
  border: 1px solid transparent;
  transition: background-color var(--transition-normal), transform var(--transition-fast), opacity var(--transition-fast);
  text-align: center;
  text-decoration: none;
}

.btn-primary:hover { background-color: var(--color-ink); }
.btn-primary:active { transform: scale(0.97); }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

.btn-primary--inline { width: auto; padding: 0.55rem 1.1rem; font-size: var(--text-body); }

/* Secundario / ghost — fondo canvas, texto ink (disponible para el sistema,
   mismo vocabulario que el resto de los componentes) */
.btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-8);
  padding: 0.85rem 1.5rem;
  border-radius: var(--radius-buttons);
  background-color: var(--color-canvas);
  color: var(--color-ink);
  font-weight: var(--font-weight-medium);
  border: 1px solid transparent;
  transition: background-color var(--transition-fast);
}
.btn-secondary:hover { background-color: var(--color-hairline); }

/* Outline — transparente, borde hairline */
.btn-outline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-8);
  padding: 0.85rem 1.5rem;
  border-radius: var(--radius-buttons);
  background-color: transparent;
  color: var(--color-ink);
  font-weight: var(--font-weight-medium);
  border: 1px solid var(--color-hairline);
  transition: background-color var(--transition-fast);
}
.btn-outline:hover { background-color: var(--color-canvas); }

/* --------------------------------------------------------------------------
   9. Floating Action Button (.fab) — monocromo, sombra sutil única
   -------------------------------------------------------------------------- */
.fab {
  position: fixed;
  bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px));
  right: max(1.25rem, calc((100vw - 480px) / 2 + 1.25rem));
  z-index: 50;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: var(--radius-pill);
  background-color: var(--color-ink-soft);
  color: var(--color-surface-alt);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-subtle), 0 8px 20px -6px rgba(0,0,0,0.35);
  border: none;
  cursor: pointer;
  transition: transform var(--transition-bounce), background-color var(--transition-normal);
}

.fab:hover { background-color: var(--color-ink); transform: translateY(-2px); }
.fab:active { transform: translateY(0) scale(0.92); }

.fab svg, .fab .icon {
  width: 1.6rem;
  height: 1.6rem;
  stroke-width: 2.4;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   10. Píldoras y Chips de Categoría (.chip)
   -------------------------------------------------------------------------- */
.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0.5rem 1rem;
  border-radius: var(--radius-badges);
  background-color: var(--color-canvas);
  color: var(--color-ink);
  font-family: var(--font-geist);
  font-size: var(--text-body);
  font-weight: var(--font-weight-medium);
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: all var(--transition-fast);
  user-select: none;
}

.chip:hover { background-color: var(--color-hairline); }
.chip:active { transform: scale(0.96); }

.chip.active,
.chip--active {
  background-color: var(--color-ink-soft);
  color: var(--color-surface-alt);
  border-color: var(--color-ink-soft);
}

.chip__icon { font-size: 1rem; display: inline-flex; align-items: center; }

.chips-scroll {
  display: flex;
  align-items: center;
  gap: var(--spacing-8);
  overflow-x: auto;
  padding: 4px 4px 12px 4px;
  margin: 0 -4px;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.chips-scroll::-webkit-scrollbar { display: none; }

/* --------------------------------------------------------------------------
   11. Salud Presupuestaria (.budget-health)
   Decisión de diseño: el sistema es acromático a propósito ("el color es
   ausencia, no expresión") y el único acento de color (ember) está
   reservado a estados destructivos/error. "Excedido" encaja ahí sin más.
   "Sano" y "cerca del límite" NO usan tinte de color: se distinguen por
   icono + peso visual del badge (outline hueco → sólido en tinta) y por el
   tono de relleno de la barra de progreso (gris medio → negro). Esto
   escala de forma legible de un vistazo (outline gris / sólido negro /
   sólido rojo) sin inventar colores semánticos nuevos fuera de la paleta.
   -------------------------------------------------------------------------- */
.budget-health {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-12);
  padding: var(--spacing-20);
  border-radius: var(--radius-cards);
  background-color: var(--color-paper);
  border: 1px solid var(--color-hairline);
  box-shadow: var(--shadow-subtle);
  overflow: hidden;
  transition: border-color var(--transition-normal);
}

.budget-health.excedido { border-color: var(--color-ember); }

.budget-health__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.budget-health__label {
  font-size: var(--text-caption);
  font-weight: var(--font-weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caption);
  color: var(--color-mid-gray);
}

.budget-health__badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: var(--radius-badges);
  font-family: var(--font-geist);
  font-size: var(--text-caption);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caption);
  border: 1px solid var(--color-hairline);
  background-color: transparent;
  color: var(--color-ink);
}
.budget-health__badge .health-icon { width: 13px; height: 13px; flex-shrink: 0; }

/* Sano — badge outline (hueco), el estado de menor peso visual */
.budget-health.sano .budget-health__badge {
  background-color: transparent;
  border-color: var(--color-hairline);
  color: var(--color-ink);
}

/* Cerca del límite — badge sólido en tinta, mayor peso que "sano" sin usar color */
.budget-health.cerca-limite .budget-health__badge {
  background-color: var(--color-ink-soft);
  border-color: var(--color-ink-soft);
  color: var(--color-surface-alt);
}

/* Excedido — único estado con acento de color (error) */
.budget-health.excedido .budget-health__badge {
  background-color: var(--color-ember);
  border-color: var(--color-ember);
  color: #ffffff;
}

.budget-health__track {
  width: 100%;
  height: 8px;
  background-color: var(--color-hairline);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.budget-health__progress {
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left;
  border-radius: var(--radius-pill);
  background-color: var(--color-mid-gray);
  /* transform en vez de width: evita layout thrash (width fuerza reflow en
     cada frame; transform solo compone en GPU) */
  transition: transform 600ms cubic-bezier(0.16, 1, 0.3, 1), background-color var(--transition-normal);
}

.budget-health.sano .budget-health__progress { background-color: var(--color-mid-gray); }
.budget-health.cerca-limite .budget-health__progress { background-color: var(--color-ink); }
.budget-health.excedido .budget-health__progress { background-color: var(--color-ember); }

.budget-health__numbers {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}

.budget-health__spent {
  font-size: var(--text-heading-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  letter-spacing: var(--tracking-heading-sm);
}

.budget-health__limit { font-size: var(--text-body); font-weight: var(--font-weight-medium); color: var(--color-mid-gray); }

/* --------------------------------------------------------------------------
   12. Elementos de Formulario — pill inputs
   -------------------------------------------------------------------------- */
.form-group { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--spacing-16); }

.form-label {
  font-size: var(--text-caption);
  font-weight: var(--font-weight-medium);
  color: var(--color-mid-gray);
}

.form-control,
.input {
  width: 100%;
  padding: 0.8rem 1rem;
  background-color: var(--color-canvas);
  border: 1px solid transparent;
  border-radius: var(--radius-inputs);
  color: var(--color-ink);
  font-family: var(--font-geist);
  font-size: var(--text-body);
  transition: box-shadow var(--transition-fast), border-color var(--transition-fast);
}

.form-control:focus,
.input:focus {
  border-color: var(--color-hairline);
  box-shadow: 0 0 0 3px var(--color-hairline);
}

.form-control::placeholder,
.input::placeholder { color: var(--color-mid-gray); }

/* Campo de monto grande (Bottom Sheet de carga de gasto) */
.amount-field {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: var(--spacing-20) var(--spacing-16);
  margin-bottom: var(--spacing-16);
  background-color: var(--color-canvas);
  border-radius: var(--radius-cards);
  border: 1px solid var(--color-hairline);
}

.amount-field__label {
  font-size: var(--text-caption);
  font-weight: var(--font-weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caption);
  color: var(--color-mid-gray);
}

.input-amount {
  font-family: var(--font-geist);
  font-size: var(--text-heading-lg);
  font-weight: var(--font-weight-semibold);
  text-align: center;
  padding: 4px;
  border: none;
  background: transparent;
  color: var(--color-ink);
  letter-spacing: var(--tracking-heading-lg);
  width: 100%;
}

.input-amount:focus { box-shadow: none; }
.input-amount:focus-visible { outline: 2px solid var(--color-ink); outline-offset: 4px; border-radius: var(--radius-small); }
.input-amount::placeholder { color: var(--color-mid-gray); }

/* --------------------------------------------------------------------------
   13. Lista y Tarjetas de Gastos (.expense-item)
   -------------------------------------------------------------------------- */
.expense-list { display: flex; flex-direction: column; gap: var(--spacing-8); }

.expense-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-12);
  background-color: var(--color-paper);
  border-radius: var(--radius-nested);
  border: 1px solid var(--color-hairline);
  transition: background-color var(--transition-fast);
}

.expense-item:active { background-color: var(--color-canvas); }

.expense-item__left { display: flex; align-items: center; gap: var(--spacing-12); min-width: 0; }

.expense-item__icon {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-pill);
  background-color: var(--color-canvas);
  border: 1px solid var(--color-hairline);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  color: var(--color-ink);
  flex-shrink: 0;
}

.expense-item__details { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.expense-item__title {
  font-size: var(--text-body);
  font-weight: var(--font-weight-medium);
  color: var(--color-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.expense-item__meta { font-size: var(--text-caption); color: var(--color-mid-gray); }

.expense-item__amount {
  font-family: var(--font-geist);
  font-size: var(--text-body);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  text-align: right;
  flex-shrink: 0;
  padding-left: var(--spacing-8);
}

/* --------------------------------------------------------------------------
   14. Barra de Navegación Inferior Móvil (.nav-bottom)
   -------------------------------------------------------------------------- */
.nav-bottom {
  position: fixed;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: 480px;
  background-color: color-mix(in srgb, var(--color-paper) 92%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--color-hairline);
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: var(--spacing-8) var(--spacing-8) calc(var(--spacing-8) + env(safe-area-inset-bottom, 0px)) var(--spacing-8);
  z-index: 30;
}

.nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 0.3rem 0.65rem;
  color: var(--color-mid-gray);
  font-size: var(--text-caption);
  font-weight: var(--font-weight-medium);
  transition: color var(--transition-fast);
}

.nav-item.active,
.nav-item--active { color: var(--color-ink); }

.nav-item svg {
  width: 1.3rem;
  height: 1.3rem;
  padding: 0.4rem;
  box-sizing: content-box;
  border-radius: var(--radius-pill);
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.nav-item.active svg { background-color: var(--color-canvas); }

/* --------------------------------------------------------------------------
   15. Clases de Utilidad y Helpers
   -------------------------------------------------------------------------- */
.text-primary { color: var(--color-ink) !important; }
.text-secondary { color: var(--color-mid-gray) !important; }
.text-muted { color: var(--color-mid-gray) !important; }
.text-center { text-align: center; }
.text-right { text-align: right; }

.bg-mint { background-color: var(--color-surface-alt) !important; }
.bg-surface { background-color: var(--color-paper) !important; }

.rounded-full { border-radius: var(--radius-pill) !important; }
.rounded-card { border-radius: var(--radius-cards) !important; }

.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-center { display: flex; align-items: center; justify-content: center; }

.gap-1 { gap: 4px; } .gap-2 { gap: var(--spacing-8); } .gap-3 { gap: var(--spacing-12); } .gap-4 { gap: var(--spacing-16); }
.mt-2 { margin-top: var(--spacing-8); } .mt-4 { margin-top: var(--spacing-16); } .mt-6 { margin-top: 1.5rem; }
.mb-2 { margin-bottom: var(--spacing-8); } .mb-4 { margin-bottom: var(--spacing-16); } .mb-6 { margin-bottom: 1.5rem; }

/* ==========================================================================
   16. Pantallas de Auth/Onboarding, Toast, Bottom-Sheet, Estados Vacíos/
   Error, Switch, Tabs y utilidades de layout
   ========================================================================== */

.full-screen {
  display: none;
  min-height: 100vh;
  min-height: 100dvh;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.25rem;
  background-color: var(--color-canvas);
}
.full-screen.active { display: flex; }

.auth-card {
  width: 100%;
  max-width: 400px;
  background-color: var(--color-paper);
  border-radius: var(--radius-cards);
  box-shadow: var(--shadow-subtle);
  border: 1px solid var(--color-hairline);
  padding: 2rem 1.75rem;
}

.auth-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-8);
  font-family: var(--font-geist);
  font-size: var(--text-subheading);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin-bottom: 4px;
  text-align: center;
}

.auth-subtitle {
  text-align: center;
  font-size: var(--text-caption);
  color: var(--color-mid-gray);
  margin-bottom: var(--spacing-24);
}

.auth-switch { text-align: center; margin-top: var(--spacing-20); font-size: var(--text-caption); color: var(--color-mid-gray); }
.auth-switch button { color: var(--color-ink); font-weight: var(--font-weight-semibold); }

.auth-tabs {
  display: flex;
  background-color: var(--color-canvas);
  border-radius: var(--radius-pill);
  padding: 4px;
  margin-bottom: var(--spacing-24);
  gap: 4px;
}
.auth-tabs button {
  flex: 1;
  padding: 0.55rem 0.5rem;
  border-radius: var(--radius-pill);
  font-size: var(--text-body);
  font-weight: var(--font-weight-medium);
  color: var(--color-mid-gray);
  text-align: center;
}
.auth-tabs button.active {
  background-color: var(--color-paper);
  color: var(--color-ink);
  box-shadow: var(--shadow-subtle);
}

.family-code-box {
  display: flex;
  align-items: center;
  gap: var(--spacing-8);
  background-color: var(--color-canvas);
  border: 1px dashed var(--color-hairline);
  border-radius: var(--radius-inputs);
  padding: 0.65rem 0.85rem;
}
.family-code-box code {
  flex: 1;
  font-family: var(--font-geist);
  font-size: var(--text-caption);
  word-break: break-all;
  color: var(--color-ink);
}

/* -- Toast -- */
#toast {
  position: fixed;
  left: 50%;
  bottom: 6.5rem;
  transform: translate(-50%, 1rem);
  background-color: var(--color-ink-soft);
  color: var(--color-surface-alt);
  padding: 0.7rem 1.1rem;
  border-radius: var(--radius-pill);
  font-size: var(--text-caption);
  font-weight: var(--font-weight-medium);
  box-shadow: var(--shadow-subtle), 0 8px 20px -6px rgba(0,0,0,0.3);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition-normal), transform var(--transition-normal);
  z-index: 100;
  max-width: calc(100% - 2.5rem);
  text-align: center;
}
#toast.show { opacity: 1; transform: translate(-50%, 0); }

/* -- Bottom Sheet (Carga Rápida de Gasto, FAB expandido) -- */
.sheet-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background-color: rgba(10, 10, 10, 0.45);
  z-index: 60;
  align-items: flex-end;
  justify-content: center;
}
.sheet-overlay.open { display: flex; }

.sheet {
  width: 100%;
  max-width: 480px;
  background-color: var(--color-paper);
  border-radius: var(--radius-cards) var(--radius-cards) 0 0;
  padding: 1.5rem 1.25rem calc(1.5rem + env(safe-area-inset-bottom, 0px)) 1.25rem;
  box-shadow: var(--shadow-subtle), 0 -4px 24px rgba(0,0,0,0.12);
  max-height: 88vh;
  overflow-y: auto;
  animation: sheet-up var(--transition-bounce);
}
@keyframes sheet-up {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}

.sheet__handle {
  width: 2.5rem;
  height: 0.3rem;
  border-radius: var(--radius-pill);
  background-color: var(--color-hairline);
  margin: 0 auto 1.25rem auto;
}

.sheet__header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--spacing-16); }

/* -- Estados vacíos / error / alertas -- */
.empty-state { text-align: center; padding: 2.5rem 1rem; color: var(--color-mid-gray); font-size: var(--text-body); }
.empty-state__icon { font-size: 2.25rem; margin-bottom: var(--spacing-12); display: block; }
.empty-state__title {
  font-family: var(--font-geist);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin-bottom: 4px;
  font-size: var(--text-body);
}

.alert-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-8);
  padding: 0.85rem 1rem;
  border-radius: var(--radius-nested);
  margin-bottom: var(--spacing-16);
  font-size: var(--text-caption);
  font-weight: var(--font-weight-medium);
  border: 1px solid var(--color-hairline);
  background-color: var(--color-canvas);
  color: var(--color-ink);
}
.alert-banner .health-icon { width: 16px; height: 16px; flex-shrink: 0; margin-top: 1px; }
.alert-banner.excedido {
  border-color: var(--color-ember);
  background-color: var(--color-paper);
  color: var(--color-ember);
}
.alert-banner.info { border-color: var(--color-hairline); background-color: var(--color-canvas); color: var(--color-ink); }

.error-card {
  text-align: center;
  padding: var(--spacing-20);
  border-radius: var(--radius-nested);
  background-color: var(--color-paper);
  border: 1px solid var(--color-ember);
  color: var(--color-ember);
  font-size: var(--text-body);
  font-weight: var(--font-weight-medium);
}

/* -- Switch (toggle) -- */
.switch { position: relative; display: inline-block; width: 2.75rem; height: 1.6rem; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background-color: var(--color-hairline);
  border-radius: var(--radius-pill);
  transition: var(--transition-fast);
}
.switch .slider::before {
  content: "";
  position: absolute;
  width: 1.2rem;
  height: 1.2rem;
  left: 0.2rem;
  bottom: 0.2rem;
  background-color: var(--color-paper);
  border-radius: 50%;
  transition: var(--transition-fast);
  box-shadow: var(--shadow-subtle);
}
.switch input:checked + .slider { background-color: var(--color-ink-soft); }
.switch input:checked + .slider::before {
  transform: translateX(1.15rem);
  background-color: var(--color-surface-alt);
}

/* -- Tabs segmentadas genéricas (Historial, Config) -- */
.tabs-segmented {
  display: flex;
  background-color: var(--color-canvas);
  border-radius: var(--radius-pill);
  padding: 4px;
  gap: 4px;
  margin-bottom: var(--spacing-16);
}
.tabs-segmented button {
  flex: 1;
  padding: 0.5rem 0.5rem;
  border-radius: var(--radius-pill);
  font-size: var(--text-body);
  font-weight: var(--font-weight-medium);
  color: var(--color-mid-gray);
}
.tabs-segmented button.active {
  background-color: var(--color-paper);
  color: var(--color-ink);
  box-shadow: var(--shadow-subtle);
}

/* -- Estadísticas en grilla (Reportes) -- */
.stats-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-12); margin-bottom: var(--spacing-16); }
.chart-card { position: relative; height: 220px; }

/* -- Semana (historial, acordeón) -- */
.week-row { display: flex; align-items: center; justify-content: space-between; padding: 0.85rem 1rem; cursor: pointer; }
.week-row__detail { display: none; padding: 0 1rem 1rem 1rem; }
.week-row__detail.open { display: block; }

/* -- Loading skeleton simple -- */
.skeleton {
  border-radius: var(--radius-nested);
  background: linear-gradient(90deg, var(--color-canvas) 25%, var(--color-hairline) 50%, var(--color-canvas) 75%);
  background-size: 200% 100%;
  animation: skeleton-shine 1.4s ease infinite;
  height: 4.5rem;
  margin-bottom: var(--spacing-12);
}
@keyframes skeleton-shine {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* -- Header: toggle de tema -- */
.theme-toggle-icon .icon-sun { display: none; }
.theme-toggle-icon .icon-moon { display: inline-flex; }
[data-theme="dark"] .theme-toggle-icon .icon-sun,
.dark .theme-toggle-icon .icon-sun,
.dark-theme .theme-toggle-icon .icon-sun { display: inline-flex; }
[data-theme="dark"] .theme-toggle-icon .icon-moon,
.dark .theme-toggle-icon .icon-moon,
.dark-theme .theme-toggle-icon .icon-moon { display: none; }

.field-hint { font-size: var(--text-caption); color: var(--color-mid-gray); margin-top: 4px; }

.form-control:disabled, .input:disabled { opacity: 0.6; cursor: not-allowed; }

/* Range nativo (umbral de alerta en Configuración) — accent-color monocromo
   para que el thumb/track no caigan al azul por default del navegador */
input[type="range"] { accent-color: var(--color-ink-soft); }

.member-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--color-hairline);
  font-size: var(--text-body);
}
.member-row:last-child { border-bottom: none; }

/* -- Badges de estado (historial) — mismo vocabulario que .budget-health:
   outline hueco (sano) → sólido en tinta (cerca del límite) → sólido ember
   (excedido, único estado con color). -- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: var(--radius-badges);
  font-size: var(--text-caption);
  font-weight: var(--font-weight-semibold);
  border: 1px solid var(--color-hairline);
  background-color: transparent;
  color: var(--color-ink);
}
.badge .health-icon { width: 12px; height: 12px; flex-shrink: 0; }
.badge.sano { background-color: transparent; border-color: var(--color-hairline); color: var(--color-ink); }
.badge.cerca-limite { background-color: var(--color-ink-soft); border-color: var(--color-ink-soft); color: var(--color-surface-alt); }
.badge.excedido { background-color: var(--color-ember); border-color: var(--color-ember); color: #ffffff; }
