/* ==========================================================================
   Analizador — hoja de estilos única
   Paleta y especificaciones de gráficos: paleta de referencia validada
   (banda de luminosidad, piso de croma, separación CVD ≥ 8 ΔE OKLab).
   ========================================================================== */

:root {
  color-scheme: light;

  /* ---------- Neutros ----------
     Toda la escala sale del gris secundario de la marca (#b4b4b4 = n-400).
     Es un gris limpio, sin tinte: así el acento turquesa es lo único con color
     en la pantalla y no compite con un fondo azulado.

     Los pasos oscuros llevan un punto de temperatura fría (2 puntos de azul)
     para que el texto sobre blanco no se vea marrón, pero se mantienen dentro
     del mismo tono. */
  --n-0:    #ffffff;
  --n-25:   #fafafa;
  --n-50:   #f6f6f7;
  --n-100:  #ededee;
  --n-200:  #e0e0e2;
  --n-300:  #cacacc;
  --n-400:  #b4b4b4;   /* el de la marca */
  --n-500:  #909093;
  --n-600:  #6e6e72;
  --n-700:  #515156;
  --n-800:  #35353a;
  --n-900:  #1e1e22;

  /* Fondo de página gris muy claro y tarjetas blancas: es lo que separa un
     compartimento del lienzo sin necesidad de sombras fuertes. */
  --page:            #f8f9fa;   /* el lienzo */
  --surface-1:       #ffffff;   /* las tarjetas, blanco puro */
  --surface-2:       #f3f4f6;   /* relleno suave dentro de una tarjeta */
  --surface-sunken:  #eceef1;
  --text-primary:    #1f2937;
  --text-secondary:  #6b7280;
  --text-muted:      #8d9197;
  --grid:            #f0f1f3;
  --axis:            #d1d5db;
  --border:          #e5e7eb;   /* el borde de pelo que separa */
  --border-strong:   #d1d5db;

  /* Sombras casi invisibles: el borde ya hace el trabajo de separar. */
  --shadow:          0 1px 2px rgba(31, 41, 55, .04);
  --shadow-alta:     0 1px 3px rgba(31, 41, 55, .06), 0 12px 28px -16px rgba(31, 41, 55, .16);

  /* ---------- La tinta ----------
     La piel oscura de la casa, y la única. Nació en la puerta de entrada y
     ahora la usan las dos: la puerta la lee como --e-*, la aplicación la lee
     como su tema oscuro. Viven aquí y no allí porque tener dos negros de marca
     en el mismo producto es lo que hace que una pantalla no parezca de la
     misma casa que la anterior, y nadie sabe decir por qué.

     No es un gris neutro: lleva un verde muy apagado dentro. Contra el negro
     puro del navegador se nota que está elegido, y contra la turquesa del
     logotipo no pelea, porque salen de la misma familia. */
  --tinta-fondo:  #0b1416;   /* el lienzo */
  --tinta-hondo:  #081011;   /* lo que se hunde: la barra lateral */
  --tinta-alza:   #152124;   /* lo que se levanta: tarjetas y campos */
  --tinta-alza-2: #1c2c2f;   /* lo que se levanta un poco más */
  --tinta-linea:  #26383b;   /* el borde de pelo */
  --tinta-linea-2:#33494d;   /* el borde cuando tiene que verse */
  --tinta-ink:    #f1efe8;   /* crema, no blanco: el blanco puro sobre negro
                                vibra y cansa a las dos frases */
  --tinta-ink-2:  #a4b6b8;   /* secundario */
  --tinta-ink-3:  #74898b;   /* metadatos */
  --tinta-marca:  #22b6d2;   /* la turquesa del logotipo, aclarada para leerse
                                sobre tinta */
  --tinta-marca-ink: #04191c;
  --tinta-mal:    #ff9080;   /* el error, legible sobre tinta */

  /* Categóricos (orden fijo — nunca ciclar) */
  --series-1: #2a78d6;
  --series-2: #eb6834;
  --series-3: #1baf7a;
  --series-4: #eda100;
  --series-5: #e87ba4;
  --series-6: #008300;
  --series-7: #4a3aa7;
  --series-8: #e34948;

  /* Secuencial azul (magnitud) */
  --seq-250: #86b6ef;
  --seq-350: #5598e7;
  --seq-450: #2a78d6;
  --seq-600: #184f95;

  /* Par divergente (polaridad: ahorro sí / no). Validado con el script de la
     paleta: ΔE 21.6 con protanopia sobre la superficie clara. */
  --div-pos: #2a78d6;
  --div-neg: #e34948;
  --div-neutro: #f0efec;

  /* Estado (reservado — jamás como serie) */
  --good:     #0ca30c;
  --warning:  #fab219;
  --serious:  #ec835a;
  --critical: #d03b3b;
  --success-text: #006300;

  /* ---------- Acento ----------
     Se reserva para tres cosas: la acción principal, el foco y lo que está
     activo. Si además se pintaran los títulos, los iconos y los bordes, dejaría
     de señalar nada. NO es un color de datos: las series van por su cuenta. */
  --accent:        #0097b2;
  --accent-hover:  #007e94;
  --accent-activo: #006b7f;
  --accent-ink:    #ffffff;
  --accent-soft:   color-mix(in srgb, var(--accent) 10%, var(--n-0));
  --accent-suave:  color-mix(in srgb, var(--accent) 16%, var(--n-0));
  --accent-border: color-mix(in srgb, var(--accent) 30%, var(--n-200));

  /* Deshabilitado: se lee como «existe pero no ahora», nunca como invisible. */
  --disabled-bg:   var(--n-100);
  --disabled-ink:  var(--n-400);
  --disabled-borde: var(--n-200);

  /* Tres radios y ni uno más: contenedor, control y pastilla. Un radio distinto
     por componente es lo que hace que una interfaz parezca de varias manos. */
  --radius: 14px;      /* tarjetas y contenedores */
  --radius-lg: 16px;   /* tarjetas grandes y el modal */
  --radius-sm: 10px;   /* botones, campos, celdas */
  --radius-xs: 6px;    /* etiquetas y microelementos */
  --radius-pill: 999px;

  /* Movimiento. Una sola curva para todo, para que la app se mueva "igual" en
     todas partes. Las duraciones se anulan enteras si el sistema pide menos
     animación (más abajo). */
  --curva: cubic-bezier(.2, .8, .2, 1);
  --curva-salida: cubic-bezier(.4, 0, .2, 1);
  --rapido: 140ms;
  --normal: 260ms;
  --lento: 480ms;

  /* Alto mínimo de cualquier cosa que se pulse con el dedo. */
  --tactil: 48px;
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* ---------- Tipografía ----------
     Siete papeles y siete medidas. Cada texto de la aplicación tiene que poder
     decir cuál de estos es; si no encaja en ninguno, el problema es del diseño,
     no de la escala. El peso sube despacio: con 600 ya se distingue un título,
     no hace falta llegar a 800. */
     Las siete medidas salen de --texto-base, no son píxeles fijos. Con píxeles
     fijos el ajuste «tamaño de texto» de Ajustes solo agrandaba lo que no
     declaraba tamaño —o sea, casi nada—: alguien elegía «enorme» y la pantalla
     se quedaba igual salvo un par de párrafos sueltos. Las proporciones son las
     que había: con la base en 15px salen exactamente 22, 15, 28, 38, 14, 13, 12
     y 11.5, así que nada se mueve para quien no toca el ajuste. */
  --t-pagina:     calc(var(--texto-base) * 1.467);   /* título de la pantalla, uno por vista */
  --t-seccion:    calc(var(--texto-base) * 1);       /* rótulo de un grupo de tarjetas */
  --t-tarjeta:    calc(var(--texto-base) * 1);       /* título de una tarjeta */
  --t-cifra:      calc(var(--texto-base) * 1.867);   /* el número de un KPI */
  --t-cifra-media: calc(var(--texto-base) * 1.333);  /* cifra de apoyo, no protagonista */
  --t-cifra-alta: calc(var(--texto-base) * 2.533);   /* la cifra protagonista de Inicio */
  --t-cuerpo:     calc(var(--texto-base) * 0.933);
  --t-secundario: calc(var(--texto-base) * 0.867);
  --t-etiqueta:   calc(var(--texto-base) * 0.8);     /* labels de formulario */
  --t-meta:       calc(var(--texto-base) * 0.767);   /* fechas, contadores, pistas */

  --peso-normal: 400;
  --peso-medio:  500;
  --peso-fuerte: 600;

  /* Escala de espacio en pasos de 4. Todo margen y todo hueco de la aplicación
     sale de aquí: no hay números sueltos. La densidad la cambia de golpe. */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --card-pad: 20px;
  --celda-y: 11px;
  --control-alto: 44px;
  /* En rem, no en px: así sigue el tamaño de letra que la persona tenga puesto
     en su navegador o en su teléfono. 0.9375rem son los 15px de siempre con la
     configuración por omisión, pero quien tiene la letra grande la ve grande aquí
     sin tener que buscar ningún ajuste — que es lo que hacía la opción «tamaño de
     texto» que se quitó de Ajustes. */
  --texto-base: 0.9375rem;
}

/* Se quitaron de aquí siete colores de acento, tres densidades y cuatro tamaños
   de texto: 84 combinaciones que mantener y probar para una aplicación pública.
   El acento es el turquesa de la marca y punto; la densidad, la de siempre; y el
   tamaño de texto lo decide el navegador, porque --texto-base va en rem.

   El objetivo táctil sí se sube con el dedo: apretar el aire está bien, apretar
   lo que hay que tocar es un fallo de uso. */
@media (pointer: coarse) {
  :root { --control-alto: 48px; }
}

/* ---------- El tema oscuro ----------
   Es la tinta de la puerta, sin una variante. Antes eran dos pieles distintas
   —la puerta en tinta verdosa, la aplicación en un gris neutro— y el salto se
   veía justo al entrar: la misma sesión cambiaba de casa al pulsar «Entrar».

   Se escribe dos veces porque son dos preguntas distintas: «el sistema está en
   oscuro y nadie ha elegido otra cosa» y «esta persona eligió oscuro». */
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    /* La tinta, entera. Los mismos valores que la puerta de entrada. */
    color-scheme: dark;
    --page:            var(--tinta-fondo);
    --surface-1:       var(--tinta-alza);
    --surface-2:       var(--tinta-alza-2);
    --surface-sunken:  var(--tinta-hondo);
    --text-primary:    var(--tinta-ink);
    --text-secondary:  var(--tinta-ink-2);
    --text-muted:      var(--tinta-ink-3);
    --border:          var(--tinta-linea);
    --border-strong:   var(--tinta-linea-2);
    --grid:            var(--tinta-linea);
    --axis:            var(--tinta-linea-2);
    
    /* El acento se aclara. El #0097b2 de la marca sobre tinta se apaga y deja
       de señalar; este es el mismo turquesa subido de luz, no otro color. */
    --accent:        var(--tinta-marca);
    --accent-hover:  #45c6de;
    --accent-activo: #6ad3e7;
    --accent-ink:    var(--tinta-marca-ink);
    --accent-soft:   color-mix(in srgb, var(--accent) 14%, var(--tinta-alza));
    --accent-suave:  color-mix(in srgb, var(--accent) 22%, var(--tinta-alza));
    --accent-border: color-mix(in srgb, var(--accent) 38%, var(--tinta-linea));
    
    --critical: #ff6b5a;   --div-neg: #ff8a78;
    --disabled-bg:    var(--tinta-alza-2);
    --disabled-ink:   var(--tinta-ink-3);
    --disabled-borde: var(--tinta-linea);
    --shadow:      0 1px 2px rgba(0,0,0,.5);
    --shadow-alta: 0 1px 3px rgba(0,0,0,.5), 0 14px 32px -18px rgba(0,0,0,.85);
    --series-1: #3987e5;  --series-2: #d95926;
    --series-3: #199e70;  --series-4: #c98500;
    --series-5: #d55181;  --series-6: #008300;
    --series-7: #9085e9;  --series-8: #e66767;
    --seq-250: #86b6ef;   --seq-350: #5598e7;
    --seq-450: #3987e5;   --seq-600: #184f95;
    --success-text: #0ca30c;
    --div-pos: #3987e5;   --div-neg: #e66767;   --div-neutro: #2b3d40;
  }
}

:root[data-theme="dark"] {
  /* La tinta, entera. Los mismos valores que la puerta de entrada. */
  color-scheme: dark;
  --page:            var(--tinta-fondo);
  --surface-1:       var(--tinta-alza);
  --surface-2:       var(--tinta-alza-2);
  --surface-sunken:  var(--tinta-hondo);
  --text-primary:    var(--tinta-ink);
  --text-secondary:  var(--tinta-ink-2);
  --text-muted:      var(--tinta-ink-3);
  --border:          var(--tinta-linea);
  --border-strong:   var(--tinta-linea-2);
  --grid:            var(--tinta-linea);
  --axis:            var(--tinta-linea-2);
  
  /* El acento se aclara. El #0097b2 de la marca sobre tinta se apaga y deja
     de señalar; este es el mismo turquesa subido de luz, no otro color. */
  --accent:        var(--tinta-marca);
  --accent-hover:  #45c6de;
  --accent-activo: #6ad3e7;
  --accent-ink:    var(--tinta-marca-ink);
  --accent-soft:   color-mix(in srgb, var(--accent) 14%, var(--tinta-alza));
  --accent-suave:  color-mix(in srgb, var(--accent) 22%, var(--tinta-alza));
  --accent-border: color-mix(in srgb, var(--accent) 38%, var(--tinta-linea));
  
  --critical: #ff6b5a;   --div-neg: #ff8a78;
  --disabled-bg:    var(--tinta-alza-2);
  --disabled-ink:   var(--tinta-ink-3);
  --disabled-borde: var(--tinta-linea);
  --shadow:      0 1px 2px rgba(0,0,0,.5);
  --shadow-alta: 0 1px 3px rgba(0,0,0,.5), 0 14px 32px -18px rgba(0,0,0,.85);
  --series-1: #3987e5;  --series-2: #d95926;
  --series-3: #199e70;  --series-4: #c98500;
  --series-5: #d55181;  --series-6: #008300;
  --series-7: #9085e9;  --series-8: #e66767;
  --seq-250: #86b6ef;   --seq-350: #5598e7;
  --seq-450: #3987e5;   --seq-600: #184f95;
  --success-text: #0ca30c;
  --div-pos: #3987e5;   --div-neg: #e66767;   --div-neutro: #2b3d40;
}

* { box-sizing: border-box; }

/* El atributo `hidden` debe ganar siempre: sin esto, cualquier clase con
   `display` (.modal-host, .field, .stack) lo anula y deja la capa del modal
   invisible pero encima de la página, bloqueando todos los clics. */
[hidden] { display: none !important; }

html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--sans);
  font-size: var(--texto-base);
  line-height: 1.5;
  color: var(--text-primary);
  background: var(--page);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 20px; }
h2 { font-size: 15px; }
h3 { font-size: 13px; }
p { margin: 0; }
small { font-size: 11.5px; }   /* el 0.8em del navegador se quedaba en 10px */
button, input, select, textarea { font: inherit; color: inherit; }
.muted { color: var(--text-muted); }
.secondary { color: var(--text-secondary); }
.nowrap { white-space: nowrap; }
.tnum { font-variant-numeric: tabular-nums; }

.skip-link {
  position: absolute; left: -999px; top: 8px; z-index: 100;
  background: var(--surface-1); padding: 8px 12px; border-radius: var(--radius-sm);
}
.skip-link:focus { left: 8px; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ---------- Estructura ---------- */
/* ---------- El fondo de tinta ----------

   El mismo papel rayado y las mismas dos luces de la puerta de entrada, para
   que dentro y fuera sean el mismo sitio. Con una diferencia deliberada: aquí
   NO se mueve nada.

   En la puerta la animación era el contenido — enseñaba lo que hace la
   aplicación a quien todavía no la ha usado. Aquí el contenido son tus cifras,
   y un fondo que se mueve detrás de un número que intentas leer no es
   ambiente, es competencia. Además la puerta se ve un minuto y esto se ve toda
   la tarde: lo que allí cuesta una animación, aquí cuesta batería en cada
   pantalla y todo el rato.

   Por eso tampoco está el horizonte de barras: detrás de una tabla de
   movimientos, dos gráficos discutirían cuál hay que mirar.

   Al ser gradientes quietos no hace falta apagarlo con prefers-reduced-motion:
   no hay nada que apagar. */
:root[data-theme="dark"] body::before {
  content: '';
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    /* Las dos luces. Aquí son gradientes y no círculos desenfocados como en la
       puerta: un radial-gradient ya nace suave, y así el navegador no tiene que
       mantener un blur de 90 px encima de toda la pantalla. */
    radial-gradient(48vw 48vw at 6% -8%,
      color-mix(in srgb, var(--tinta-marca) 11%, transparent), transparent 70%),
    radial-gradient(42vw 42vw at 98% 106%,
      color-mix(in srgb, #1f7f93 10%, transparent), transparent 72%),
    /* El papel rayado del libro de cuentas. Al 3% no se ve: se nota. */
    repeating-linear-gradient(to bottom,
      color-mix(in srgb, var(--tinta-ink) 3%, transparent) 0 1px,
      transparent 1px 34px),
    repeating-linear-gradient(to right,
      color-mix(in srgb, var(--tinta-ink) 2%, transparent) 0 1px,
      transparent 1px 120px);
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) body::before {
    content: '';
    position: fixed; inset: 0; z-index: 0; pointer-events: none;
    background:
      /* Las dos luces. Aquí son gradientes y no círculos desenfocados como en la
         puerta: un radial-gradient ya nace suave, y así el navegador no tiene que
         mantener un blur de 90 px encima de toda la pantalla. */
      radial-gradient(48vw 48vw at 6% -8%,
        color-mix(in srgb, var(--tinta-marca) 11%, transparent), transparent 70%),
      radial-gradient(42vw 42vw at 98% 106%,
        color-mix(in srgb, #1f7f93 10%, transparent), transparent 72%),
      /* El papel rayado del libro de cuentas. Al 3% no se ve: se nota. */
      repeating-linear-gradient(to bottom,
        color-mix(in srgb, var(--tinta-ink) 3%, transparent) 0 1px,
        transparent 1px 34px),
      repeating-linear-gradient(to right,
        color-mix(in srgb, var(--tinta-ink) 2%, transparent) 0 1px,
        transparent 1px 120px);
  }
}

/* Y todo lo demás por encima del fondo. Sin esto el fondo se pinta sobre el
   contenido: `position: fixed` crea contexto de apilamiento y gana a lo que no
   tiene z-index. */
.app { display: grid; grid-template-columns: 240px 1fr; min-height: 100vh; position: relative; z-index: 1; }

.sidebar {
  padding: 18px 14px;
  /* Ojo: sistema.css la vuelve a pintar después (con --surface-1) y además la
     hace translúcida en oscuro. Esta regla la gana esa. */
  background: var(--surface-sunken);
  border-right: 1px solid var(--border);
  position: sticky; top: 0; height: 100vh;
}
.sidebar__panel { display: flex; flex-direction: column; gap: 20px; height: 100%; }
.brand { display: flex; gap: 10px; align-items: center; padding: 4px 6px 0; }
.brand strong { display: block; font-size: 15px; }
.brand span { display: block; font-size: 11px; color: var(--text-muted); }

.nav { display: flex; flex-direction: column; gap: 2px; }
.nav__item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 11px; border: 1px solid transparent; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-secondary); cursor: pointer;
  font-size: 13.5px; font-weight: 500; text-align: left;
  transition: background .15s ease, color .15s ease;
}
.nav__item:hover { background: var(--surface-2); color: var(--text-primary); }
.nav__item[aria-current="page"] {
  background: var(--accent-soft); color: var(--text-primary);
  border-color: var(--accent-border); font-weight: 600;
}
.nav__icon { width: 18px; text-align: center; font-size: 14px; color: var(--text-muted); flex: 0 0 auto; }
.nav__item[aria-current="page"] .nav__icon { color: var(--accent); }
.nav__badge {
  margin-left: auto; font-size: 11px; padding: 1px 7px; border-radius: 999px;
  background: var(--surface-2); color: var(--text-muted); font-variant-numeric: tabular-nums;
}
.nav__item[aria-current="page"] .nav__badge { background: var(--surface-2); color: var(--text-secondary); }

.sidebar__foot { margin-top: auto; display: grid; gap: 10px; }
.sidebar__note { font-size: 11px; color: var(--text-muted); padding: 0 6px; }
.theme-switch {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px;
  background: var(--surface-2); padding: 3px; border-radius: 999px;
}
.theme-switch button {
  border: 0; background: transparent; border-radius: 999px; padding: 5px;
  cursor: pointer; color: var(--text-muted); font-size: 13px;
}
.theme-switch button[aria-pressed="true"] {
  background: var(--surface-1); color: var(--text-primary); box-shadow: var(--shadow);
}

.main { display: flex; flex-direction: column; min-width: 0; }
.topbar {
  display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-end;
  justify-content: space-between;
  padding: 18px 24px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--page);
  position: sticky; top: 0; z-index: 20;
}
.topbar__head p { font-size: 12.5px; }
.filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.field { display: grid; gap: 4px; }
.field > span { font-size: 11px; color: var(--text-muted); padding-left: 2px; }
input, select, textarea {
  background: var(--surface-1); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); padding: 7px 9px; min-width: 0;
}
input:hover, select:hover { border-color: var(--axis); }
textarea { resize: vertical; }
input[type="checkbox"] { accent-color: var(--accent); width: 16px; height: 16px; }

.view { padding: 22px 24px 60px; display: grid; gap: 18px; align-content: start; }

/* ---------- Campos ---------- */
input:not([type="checkbox"]):not([type="radio"]), select, textarea {
  min-height: var(--control-alto);
  transition: border-color .15s ease, box-shadow .15s ease;
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* La cabecera se queda arriba: en una tabla larga siempre se ve en qué vista
   estás y los filtros quedan a mano. */
.topbar {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--page) 88%, transparent);
  backdrop-filter: blur(8px);
}

/* Navegación del periodo (quincena/semana/mes) */
.periodo-nav { display: flex; align-items: center; gap: 6px; align-self: end; }
.periodo-nav #periodoEtiqueta { font-size: 12.5px; font-weight: 600; min-width: 132px;
  text-align: center; color: var(--text-primary); }
/* Fuera del periodo actual se avisa con el acento: es fácil olvidar que estás
   mirando la quincena pasada. */
.periodo-nav #periodoEtiqueta[data-desplazado="1"] { color: var(--accent); }
.periodo-nav .btn { padding: 4px 8px; }

/* Botón de cuenta (pie de la barra lateral) */
.cuenta-btn { width: 100%; justify-content: flex-start; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.cuenta-btn[data-dentro="1"] { border-color: var(--accent-border); background: var(--accent-soft); }
.cuenta-btn[data-dentro="1"]::before { content: "●"; color: var(--good); font-size: 10px; }

/* Separador dentro de una tarjeta, para agrupar ajustes sin abrir otra */
.divisor { height: 1px; background: var(--border); margin: 16px 0 12px; }

/* Nota al pie de las cifras del panel: explica sin competir con los números */
.tile--nota { background: var(--surface-2); border: none; padding: 10px 12px; }
.tile--nota .tile__foot { font-size: 12px; line-height: 1.45; }

/* Avisos (campana de la barra superior) */
.avisos-zona { position: relative; }
.avisos-btn { position: relative; padding: 6px 10px; }
.avisos-btn[data-hay="1"] { border-color: var(--accent-border); background: var(--accent-soft); }
.avisos-btn__cuenta {
  position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px;
  border-radius: var(--radius-pill); background: var(--critical); color: #fff;
  font-size: 11px; font-weight: 700; display: grid; place-items: center; padding: 0 5px;
}
.avisos-panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40; width: min(360px, 92vw);
  background: var(--surface-1); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); box-shadow: var(--shadow); padding: 6px;
  max-height: 70vh; overflow: auto;
}
.avisos-panel__cabeza { display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 6px 10px 8px; }
.aviso-fila { display: flex; align-items: flex-start; gap: 6px; padding: 2px; }
.aviso-fila__ir { flex: 1 1 auto; text-align: left; background: none; border: 0; cursor: pointer;
  padding: 8px 10px; border-radius: var(--radius-sm); color: var(--text-primary);
  display: grid; gap: 2px; border-left: 3px solid transparent; }
.aviso-fila__ir:hover { background: var(--surface-2); }
.aviso-fila__ir strong { font-size: 13px; font-weight: 600; }
.aviso-fila__ir span { font-size: 12px; }
.aviso-fila[data-nivel="grave"] .aviso-fila__ir { border-left-color: var(--critical); }
.aviso-fila[data-nivel="atencion"] .aviso-fila__ir { border-left-color: var(--warning); }
.aviso-fila[data-nivel="info"] .aviso-fila__ir { border-left-color: var(--accent); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---------- Selector de espacio ---------- */
/* Va bajo la marca porque es el contexto de todo lo demás: mirando ahí siempre
   se sabe en qué espacio estás trabajando. */
.espacio-sel {
  display: flex; align-items: center; gap: 9px; width: 100%;
  margin: 0 0 var(--sp-3); padding: 8px 10px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); cursor: pointer; text-align: left;
  transition: border-color .15s ease, background .15s ease;
}
.espacio-sel:hover { border-color: var(--accent-border); background: var(--accent-soft); }
.espacio-sel__icono {
  width: 30px; height: 30px; border-radius: var(--radius-sm); flex: 0 0 auto;
  display: grid; place-items: center; font-size: 15px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
}
.espacio-sel__texto { flex: 1 1 auto; min-width: 0; display: block; line-height: 1.25; }
.espacio-sel__texto strong { display: block; font-size: 13.5px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.espacio-sel__texto span { display: block; font-size: 11.5px; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.espacio-sel__flecha { color: var(--text-muted); font-size: 13px; flex: 0 0 auto; }

.espacio-menu {
  margin: -8px 0 var(--sp-3); padding: 6px;
  background: var(--surface-1); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); box-shadow: var(--shadow);
  display: grid; gap: 2px; max-height: 60vh; overflow: auto;
}
.espacio-menu__titulo { font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-muted); padding: 4px 8px 6px; }
.espacio-menu__item {
  display: flex; align-items: center; gap: 9px; width: 100%; padding: 7px 8px;
  background: transparent; border: 0; border-radius: var(--radius-sm);
  cursor: pointer; text-align: left; color: var(--text-primary); min-height: 40px;
}
.espacio-menu__item:hover { background: var(--surface-2); }
.espacio-menu__item[aria-current="true"] { background: var(--accent-soft); }
.espacio-menu__icono { width: 24px; height: 24px; border-radius: 6px; flex: 0 0 auto;
  display: grid; place-items: center; font-size: 13px; }
.espacio-menu__icono--plano { background: var(--surface-2); }
.espacio-menu__texto { flex: 1 1 auto; min-width: 0; line-height: 1.2; }
.espacio-menu__texto strong { display: block; font-size: 13px; }
.espacio-menu__texto span { display: block; font-size: 11px; }
.espacio-menu__check { color: var(--accent); font-weight: 700; }

/* ---------- Tarjetas de espacio (pantalla Mis espacios) ---------- */
.espacios { display: grid; gap: var(--sp-3); margin-top: var(--sp-3); justify-content: start;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 340px)); }
.espacio { border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--sp-4); background: var(--surface-1); display: grid; gap: 10px;
  align-content: start; transition: border-color .15s ease, transform .1s ease; }
.espacio:hover { border-color: var(--border-strong); }
.espacio--activo { border-color: var(--accent-border); background: var(--accent-soft); }
.espacio__cabeza { display: flex; align-items: center; gap: 10px; }
.espacio__icono { width: 38px; height: 38px; border-radius: var(--radius-sm); flex: 0 0 auto;
  display: grid; place-items: center; font-size: 19px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18); }
.espacio__titulo { flex: 1 1 auto; min-width: 0; line-height: 1.25; }
.espacio__titulo strong { display: block; font-size: 15px; }
.espacio__titulo span { font-size: 11.5px; }
.espacio__cifras { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px 12px; margin: 0; }
.espacio__cifras dt { font-size: 11px; margin: 0; }
.espacio__cifras dd { margin: 0; font-size: 14px; font-weight: 600; }
.espacio__acciones { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }

/* Selector de icono al crear un espacio */
.iconos { display: flex; gap: 6px; flex-wrap: wrap; }
.icono-op { width: 36px; height: 36px; border-radius: var(--radius-sm); font-size: 17px;
  background: var(--surface-2); border: 1px solid var(--border); cursor: pointer; }
.icono-op[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); }

/* ---------- Botones ---------- */
.btn {
  border: 1px solid var(--border-strong); background: var(--surface-1);
  color: var(--text-primary); border-radius: var(--radius-sm);
  padding: 7px 13px; cursor: pointer; font-size: 13px; font-weight: 500;
  min-height: var(--control-alto);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  white-space: nowrap;
  transition: background .15s ease, border-color .15s ease, transform .08s ease;
}
.btn:hover { background: var(--surface-2); }
.btn:active { transform: translateY(1px); }
.btn--primary { background: var(--accent); border-color: transparent; color: var(--accent-ink);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--accent) 40%, transparent); }
.btn--primary:hover { background: var(--accent-hover); filter: none; }
.btn--ghost { border-color: transparent; background: transparent; color: var(--text-secondary); }
.btn--ghost:hover { background: var(--surface-2); color: var(--text-primary); }
.btn--danger { color: var(--critical); border-color: var(--border-strong); }
.btn--danger:hover { background: color-mix(in srgb, var(--critical) 10%, var(--surface-1)); }
.btn--sm { padding: 4px 9px; font-size: 12px; }
.btn:disabled { opacity: .45; cursor: not-allowed; }

/* Control segmentado (tema): tres opciones que se leen como una sola pieza. */
.segmento { display: inline-flex; width: fit-content; align-self: flex-start;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-1); }
.segmento .btn { border: 0; border-radius: 0; box-shadow: none; }
.segmento .btn + .btn { border-left: 1px solid var(--border); }
.segmento .btn[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); font-weight: 600; }

/* Muestras de color de acento (Ajustes → Apariencia) */
.swatches { display: flex; gap: 8px; flex-wrap: wrap; }
.swatch {
  width: 34px; height: 34px; border-radius: var(--radius-pill);
  border: 2px solid var(--border-strong); cursor: pointer; padding: 0;
  position: relative; transition: transform .12s ease, border-color .12s ease;
}
.swatch:hover { transform: scale(1.08); }
.swatch[aria-pressed="true"] { border-color: var(--text-primary); }
.swatch[aria-pressed="true"]::after {
  content: "✓"; position: absolute; inset: 0; display: grid; place-items: center;
  color: #fff; font-size: 15px; font-weight: 700; text-shadow: 0 1px 2px rgba(0,0,0,.5);
}
.swatch--azul     { background: #2a78d6; }
.swatch--verde    { background: #12855c; }
.swatch--morado   { background: #6244c5; }
.swatch--magenta  { background: #b83280; }
.swatch--naranja  { background: #c2560f; }
.swatch--pizarra  { background: #40566b; }

/* ---------- Tarjetas ---------- */
.card {
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--card-pad);
}
.card__head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 4px;
}
.card__head p { font-size: 12px; color: var(--text-muted); }
.card__tools { display: flex; gap: 6px; align-items: center; }

.grid { display: grid; gap: 16px; }
/* min() evita que la columna mínima sea más ancha que la pantalla: en móvil la
   rejilla cae a una columna en lugar de provocar scroll horizontal. */
.grid--tiles { grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); }

/* Encabezado del panel: saludo, fecha y cuánto queda del mes. */
.saludo { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap; }
.saludo h2 { font-size: clamp(17px, 2.4vw, 21px); }
.saludo__meta { color: var(--text-secondary); font-size: 12.5px; margin-top: 2px; }
.saludo__acciones { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* Barra de avance del mes: cuánto se ha gastado del ingreso del periodo. */
.avance { margin-top: var(--sp-4); }
.avance__cifras { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; }
.avance__valor { font-size: clamp(24px, 4.5vw, 34px); font-weight: 650; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums; }
.avance__de { color: var(--text-secondary); font-size: 13px; }
.avance__barra { position: relative; height: 10px; margin-top: var(--sp-2);
  background: var(--surface-sunken); border-radius: var(--radius-pill); overflow: hidden; }
.avance__barra > i { display: block; height: 100%; border-radius: var(--radius-pill);
  background: var(--accent); transition: width .3s ease; }
.avance__barra[data-nivel="alto"] > i { background: var(--warning); }
.avance__barra[data-nivel="pasado"] > i { background: var(--critical); }
.avance__pie { display: flex; gap: var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-2);
  color: var(--text-secondary); font-size: 12.5px; }

/* Avisos accionables: cada uno lleva a la pantalla donde se resuelve. */
.avisos { display: grid; gap: var(--sp-2); }
.aviso { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-1); cursor: pointer; font-size: 13px;
  transition: border-color .15s ease, background .15s ease; }
.aviso:hover { border-color: var(--accent-border); background: var(--accent-soft); }
.aviso__icono { flex: 0 0 auto; width: 22px; height: 22px; border-radius: var(--radius-pill);
  display: grid; place-items: center; font-size: 12px; font-weight: 700; }
.aviso[data-tono="atencion"] .aviso__icono { background: color-mix(in srgb, var(--warning) 22%, transparent); color: var(--warning); }
.aviso[data-tono="grave"] .aviso__icono { background: color-mix(in srgb, var(--critical) 18%, transparent); color: var(--critical); }
.aviso[data-tono="info"] .aviso__icono { background: var(--accent-soft); color: var(--accent); }
.aviso__texto { flex: 1 1 auto; }
.aviso__texto strong { display: block; font-weight: 600; }
.aviso__texto span { color: var(--text-secondary); font-size: 12px; }
.aviso__ir { color: var(--text-muted); font-size: 15px; flex: 0 0 auto; }

/* ---------- Stat tiles / hero ---------- */
.tile { display: grid; gap: 6px; align-content: start; }
.tile__label { font-size: 12px; color: var(--text-muted); }
.tile__value { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; }
.tile__foot {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 2px 8px; font-size: 12px; color: var(--text-muted);
}
.delta { display: inline-flex; align-items: center; gap: 3px; font-weight: 600; }
.delta--good { color: var(--success-text); }
.delta--bad { color: var(--critical); }
.delta--flat { color: var(--text-muted); }
.spark { display: block; width: 100%; height: 30px; overflow: visible; }

.hero { display: grid; gap: 10px; align-content: center; }
.hero__label { font-size: 12.5px; color: var(--text-muted); }
.hero__value { font-size: 48px; line-height: 1.05; font-weight: 600; letter-spacing: -0.03em; }
.hero__meta { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12.5px; color: var(--text-secondary); }

/* ---------- Gráficos ---------- */
/* overflow: hidden como red de seguridad. El recorte real lo hace un clipPath
   dentro del SVG, pero si alguna vez se cuela un dato fuera de escala, aquí se
   queda: antes una línea se dibujaba encima de las tarjetas de abajo. */
.chart { width: 100%; display: block; overflow: hidden; }
.chart-wrap { position: relative; }
.legend { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 10px; }
.legend__item { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-secondary); }
.legend__swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.legend__key { width: 14px; height: 2px; border-radius: 2px; flex: none; }
.legend__item[data-off="1"] { opacity: .4; }
.legend button { border: 0; background: none; padding: 0; cursor: pointer; color: inherit; display: inline-flex; align-items: center; gap: 6px; }

.viz-tooltip {
  position: fixed; z-index: 90; pointer-events: none;
  background: var(--surface-1); border: 1px solid var(--border-strong);
  box-shadow: var(--shadow); border-radius: var(--radius-sm);
  padding: 8px 10px; font-size: 12px; min-width: 120px; max-width: 260px;
}
.viz-tooltip b { display: block; font-size: 12.5px; margin-bottom: 4px; }
.viz-tooltip .row { display: flex; align-items: center; gap: 7px; justify-content: space-between; }
.viz-tooltip .row span:last-child { font-variant-numeric: tabular-nums; font-weight: 600; }
.viz-tooltip .dot { width: 8px; height: 8px; border-radius: 3px; flex: none; }

.empty {
  display: grid; place-items: center; gap: 8px; text-align: center;
  padding: 34px 16px; color: var(--text-muted); font-size: 13px;
}
.empty strong { color: var(--text-secondary); font-size: 14px; }

/* Gráficos pequeños con la misma escala (small multiples): cuatro categorías se
   comparan mejor así que con cuatro líneas cruzándose, y en el móvil es la única
   forma legible. */
.multiples { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); }
.multiple { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px 6px;
  background: var(--surface-1); }
.multiple__cabeza { display: flex; align-items: center; gap: 7px; }
.multiple__punto { width: 9px; height: 9px; border-radius: 2px; flex: 0 0 auto; }
.multiple__nombre { font-size: 12.5px; font-weight: 600; flex: 1 1 auto; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.multiple__cifra { font-size: 12.5px; color: var(--text-secondary); }
.multiple__lienzo { margin-top: 2px; }
.multiple__pie { font-size: 11.5px; }

/* ---------- Medidores (presupuestos) ---------- */
.meter-row { display: grid; gap: 7px; padding: 12px 0; border-bottom: 1px solid var(--grid); }
.meter-row:last-child { border-bottom: 0; }
.meter-row__top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.meter-row__name { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; }
.meter-row__val { font-size: 12.5px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.meter { height: 8px; border-radius: 999px; overflow: hidden; position: relative; }
.meter__track { position: absolute; inset: 0; }
.meter__fill { position: absolute; inset: 0 auto 0 0; border-radius: 999px; }
.meter-row__note { font-size: 11.5px; display: flex; align-items: center; gap: 5px; }

.pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px;
  background: var(--surface-2); color: var(--text-secondary);
}
.pill--good { color: var(--success-text); background: color-mix(in srgb, var(--good) 12%, var(--surface-1)); }
.pill--warning { color: var(--text-primary); background: color-mix(in srgb, var(--warning) 26%, var(--surface-1)); }
.pill--serious { color: var(--text-primary); background: color-mix(in srgb, var(--serious) 26%, var(--surface-1)); }
.pill--critical { color: var(--critical); background: color-mix(in srgb, var(--critical) 12%, var(--surface-1)); }
.pill--info { color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, var(--surface-1)); }
/* Apagada: para lo que existe pero no reclama nada. Un fijo que saltaste ese mes
   no es un problema ni un logro; enseñarlo en verde o en rojo sería decir algo
   que no pasó. */
.pill--muted { color: var(--text-muted); background: var(--surface-2); }

.dot-cat { width: 9px; height: 9px; border-radius: 3px; flex: none; display: inline-block; }

/* ---------- Tablas ---------- */
.table-scroll { overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; font-size: 13px; }
table.data th, table.data td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--grid); }
table.data thead th {
  position: sticky; top: 0; background: var(--surface-1); z-index: 1;
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-muted); font-weight: 600; white-space: nowrap;
}
table.data tbody tr:hover { background: var(--surface-2); }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data.compact th, table.data.compact td { padding: 6px 8px; font-size: 12px; }
.cell-desc { max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.amount-out { font-weight: 600; }
.amount-in { font-weight: 600; color: var(--success-text); }
.row-actions { display: flex; gap: 4px; justify-content: flex-end; opacity: .5; }
tr:hover .row-actions { opacity: 1; }
.sortable { cursor: pointer; user-select: none; }
.sortable[aria-sort]:not([aria-sort="none"]) { color: var(--text-primary); }

.pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 12px; }

/* Refinado de tablas: la cabecera se queda visible al desplazar una tabla larga
   (movimientos de un mes entero) y las filas alternas ayudan a seguir la línea. */
.table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--surface-1);
  box-shadow: inset 0 -1px 0 var(--border);
}
.table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--surface-2) 45%, transparent); }
.table tbody tr:hover { background: var(--accent-soft); }
.table td, .table th { padding-top: var(--celda-y); padding-bottom: var(--celda-y); }
.table td.num, .table th.num { font-variant-numeric: tabular-nums; }

/* ---------- Importador ---------- */
.dropzone {
  border: 1.5px dashed var(--axis); border-radius: var(--radius);
  padding: 30px 20px; text-align: center; display: grid; gap: 10px; place-items: center;
  background: var(--surface-1); cursor: pointer;
}
.dropzone[data-hover="1"] { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--surface-1)); }
.dropzone__icon { font-size: 26px; color: var(--accent); }
.dropzone strong { font-size: 15px; }
.dropzone small { color: var(--text-muted); }

.steps { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.step { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text-muted); }
.step__n {
  width: 20px; height: 20px; border-radius: 999px; display: grid; place-items: center;
  background: var(--surface-2); font-size: 11px; font-weight: 700;
}
.step[data-active="1"] { color: var(--text-primary); font-weight: 600; }
.step[data-active="1"] .step__n { background: var(--accent); color: var(--accent-ink); }
.step[data-done="1"] .step__n { background: color-mix(in srgb, var(--good) 20%, var(--surface-1)); color: var(--success-text); }

.map-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: 12px; }
.preview-scroll { max-height: 460px; overflow: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.dupe { background: color-mix(in srgb, var(--warning) 10%, transparent); }
.log { font-family: ui-monospace, "Cascadia Code", Consolas, monospace; font-size: 11.5px;
  background: var(--surface-sunken); border-radius: var(--radius-sm); padding: 10px;
  max-height: 160px; overflow: auto; white-space: pre-wrap; color: var(--text-secondary); }

.toast__accion { margin-left: 10px; padding: 3px 10px; font-size: 12px; font-weight: 600;
  color: var(--text-primary); background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); cursor: pointer; flex: 0 0 auto; }
.toast__accion:hover { background: var(--surface-3, var(--surface-2)); }

/* Sin conexión: una franja discreta arriba, sin tapar nada. */
body[data-conexion="no"] .topbar::before { content: "Sin conexión"; display: block;
  font-size: 11.5px; font-weight: 600; letter-spacing: .02em; color: var(--warning);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  border-radius: var(--radius-sm); padding: 2px 8px; margin-bottom: 8px; width: fit-content; }

.bar-progress { height: 6px; background: var(--surface-2); border-radius: 999px; overflow: hidden; }
.bar-progress > i { display: block; height: 100%; background: var(--accent); border-radius: var(--radius-pill); transition: width .25s ease; }

/* ---------- Modal ---------- */
body.menu-abierto { overflow: hidden; }

/* ==========================================================================
   Portada (la puerta de entrada)
   ==========================================================================
   Una columna centrada, un paso por pantalla, idéntica en el teléfono y en el
   ordenador. No se reorganiza al cambiar de tamaño porque no hay nada que
   reorganizar: lo que se ve en el móvil es lo que se ve en el escritorio, con
   más aire alrededor.

   ── Por qué tiene su propia piel ──

   La aplicación deja elegir tema y color de acento, y son siete colores. La
   puerta NO participa de eso, por dos razones. La primera es práctica: aquí
   todavía no hay nadie identificado, así que no hay preferencia que respetar.
   La segunda es de marca: una entrada que cambia de color según un ajuste no
   parece de nadie. Se ve exactamente igual para todo el mundo, siempre, y eso
   es lo que la hace reconocible.

   Los diez valores de abajo son la piel entera. Cambiarlos cambia la entrada
   completa y no toca ni una de las otras pantallas.
   ========================================================================== */

.portada {
  /* La piel de la puerta. Tinta, crema y un verde de marca. Nada más. */
  --e-fondo:     var(--tinta-fondo);
  --e-alza:      var(--tinta-alza);
  --e-alza-2:    var(--tinta-alza-2);
  --e-linea:     var(--tinta-linea);
  --e-tinta:     var(--tinta-ink);
  --e-tinta-2:   var(--tinta-ink-2);
  --e-tinta-3:   var(--tinta-ink-3);
  /* La turquesa del logotipo aclarada para leerse sobre tinta. Es la misma que
     usa el tema oscuro de la aplicación, y eso importa: el archivo del logotipo
     es #0097b2 casi entero, así que un verde ligeramente distinto al lado dejaría
     dos turquesas en pantalla discutiendo cuál es la de la marca. */
  --e-marca:     var(--tinta-marca);   /* la acción, el foco, lo activo. Una sola. */
  --e-marca-ink: var(--tinta-marca-ink);
  --e-mal:       var(--tinta-mal);

  position: fixed; inset: 0; z-index: 60; overflow: auto;
  background: var(--e-fondo);
  color: var(--e-tinta);
  display: grid; place-items: center;
  padding:
    max(var(--sp-5), env(safe-area-inset-top))
    var(--sp-4)
    max(var(--sp-5), env(safe-area-inset-bottom));
  /* Los números de la muestra en tabular para que las columnas cuadren. */
  font-variant-numeric: tabular-nums;
}
body.con-portada { overflow: hidden; }
body.con-portada .app { display: none; }

.entrada {
  width: min(420px, 100%);
  display: grid; gap: var(--sp-5); align-content: center;
}
.entrada__panel { display: grid; gap: var(--sp-5); align-content: start; }

/* ---------- El lado de la historia (solo en pantalla ancha) ---------- */

/* En el móvil también se ve —el mismo logotipo y la misma cinta ordenando—,
   pero SOLO en la bienvenida. En los formularios no: en un teléfono, entrar
   con tu contraseña no puede obligarte a pasar por delante de una demo.

   Se decide con el data-paso que la portada ya escribe, no con JavaScript:
   así no hay que volver a pintar nada al girar el teléfono, y quien está
   escribiendo su correo no ve cómo se le vacía el campo.  */
.entrada__lado { display: none; }
/* Rótulo, no titular: dice qué está pasando debajo. El único titular de la
   pantalla es el del panel.

   Va en la base y no dentro del bloque de pantalla ancha, que es donde estaba:
   en el móvil se quedaba sin estilo y salía como un párrafo grande y blanco,
   compitiendo con el titular de verdad y sin el punto de «en vivo». */
.entrada__ladoRotulo {
  display: flex; align-items: center; gap: 8px;
  margin: var(--sp-2) 0 0; color: var(--e-tinta-3);
  font-size: var(--t-meta); font-weight: var(--peso-fuerte);
  text-transform: uppercase; letter-spacing: .08em;
}

#portada[data-paso="bienvenida"] .entrada__lado {
  display: grid; gap: var(--sp-4); align-content: start;
}
/* Los tres puntos son para la pantalla ancha. En el teléfono alargarían la
   bienvenida hasta hacerla desplazable, y lo que hay que ver —la cinta y los
   dos caminos— se iría por debajo del borde. */
#portada[data-paso="bienvenida"] .entrada__puntos { display: none; }
/* Y con el logotipo del lado puesto, el de la pantalla sobra. */
#portada[data-paso="bienvenida"] .entrada__hoja .entrada__marca { display: none; }

/* La cinta, apretada para un teléfono. */
@media (max-width: 1023px) {
  .cinta { padding: var(--sp-3); gap: var(--sp-3); }
  .cinta__total { font-size: 19px; }
  .cinta__entrante { min-height: 42px; padding: 7px var(--sp-3); }
  .cinta__lista { gap: var(--sp-3); }
}


/* La hoja es lo que se mueve al cambiar de paso. Envuelve solo la pantalla, no
   el pie: si el pie se moviera también, cada paso parecería una página nueva. */
.entrada__hoja { display: grid; }
.entrada__pantalla { display: grid; gap: var(--sp-4); }

/* ---------- Marca y barra superior ---------- */

.entrada__marca { display: flex; align-items: center; }
.entrada__marca--grande { margin-bottom: var(--sp-1); }
/* El logotipo va tal cual, sin filtro. El archivo es turquesa (#0097b2) sobre
   transparente, no negro, así que sobre tinta se lee a 5,5:1. Pasarlo por
   brightness(0) invert(1) —el reflejo de cualquiera al poner un logotipo sobre
   fondo oscuro— lo dejaría en una silueta blanca y le quitaría justo lo único
   que lo hace la marca. */

.entrada__barra {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); min-height: var(--control-alto);
}
.entrada__hueco { width: var(--control-alto); }
.entrada__volver {
  appearance: none; cursor: pointer;
  width: var(--control-alto); height: var(--control-alto);
  display: grid; place-items: center;
  background: transparent; border: 1px solid var(--e-linea);
  border-radius: var(--radius-pill);
  color: var(--e-tinta-2); font-size: 18px; line-height: 1;
  transition: border-color var(--rapido) var(--curva), color var(--rapido) var(--curva);
}
.entrada__volver:hover { border-color: var(--e-tinta-3); color: var(--e-tinta); }
.entrada__volver:focus-visible { outline: 2px solid var(--e-marca); outline-offset: 2px; }

/* ---------- Texto ---------- */

/* Grande y apretado. Es la única cosa que se lee entera en esta pantalla, así
   que puede permitírselo. */
.entrada__titulo {
  font-size: clamp(30px, 7vw, 40px);
  font-weight: var(--peso-fuerte);
  line-height: 1.08; letter-spacing: -.032em;
  margin: 0; color: var(--e-tinta);
  text-wrap: balance;
}
.entrada__bajada {
  margin: 0; color: var(--e-tinta-2);
  font-size: 15px; line-height: 1.5; max-width: 38ch;
}
.entrada__nota {
  margin: 0; color: var(--e-tinta-3);
  font-size: var(--t-meta); line-height: 1.5;
}
.entrada__aviso {
  margin: 0; color: var(--e-mal);
  font-size: var(--t-secundario); line-height: 1.4; min-height: 1em;
}
.entrada__pie {
  margin: 0; color: var(--e-tinta-3);
  font-size: 11.5px; line-height: 1.55; text-align: center;
}

/* ---------- Botones ---------- */

/* Altos y a todo el ancho. En el móvil se pulsan con el pulgar sin apuntar, y
   en el escritorio dejan claro cuál es el camino principal. */
.entrada__acciones { display: grid; gap: var(--sp-2); }
.entrada__btn {
  appearance: none; cursor: pointer; width: 100%;
  min-height: 52px; padding: 0 var(--sp-4);
  border-radius: var(--radius-sm); border: 1px solid transparent;
  font: inherit; font-size: 15px; font-weight: var(--peso-fuerte);
  letter-spacing: -.005em;
  transition: background var(--rapido) var(--curva),
              border-color var(--rapido) var(--curva),
              transform var(--rapido) var(--curva);
}
.entrada__btn:active { transform: scale(.985); }
.entrada__btn:focus-visible { outline: 2px solid var(--e-marca); outline-offset: 2px; }
.entrada__btn:disabled { opacity: .55; cursor: default; transform: none; }

.entrada__btn--principal { background: var(--e-marca); color: var(--e-marca-ink); }
.entrada__btn--principal {
  /* El halo es del color de la marca y muy abierto: hace que el botón parezca
     encendido en vez de pintado, que es lo que se busca en el único sitio de
     la pantalla donde se quiere que se pulse. */
  box-shadow: 0 10px 30px -12px color-mix(in srgb, var(--e-marca) 70%, transparent);
  transition: background var(--rapido) var(--curva),
              box-shadow var(--rapido) var(--curva),
              transform var(--rapido) var(--curva);
}
.entrada__btn--principal:hover:not(:disabled) {
  background: #45c7de;
  box-shadow: 0 14px 38px -12px color-mix(in srgb, var(--e-marca) 85%, transparent);
  transform: translateY(-1px);
}

.entrada__btn--secundario {
  background: transparent; color: var(--e-tinta); border-color: var(--e-linea);
}
.entrada__btn--secundario:hover:not(:disabled) { border-color: var(--e-tinta-3); }

/* Los dos caminos de la bienvenida. No es un botón con más texto: es una
   opción, y por eso lleva flecha y se alinea a la izquierda como una fila de
   lista, no como un botón centrado. */
.entrada__camino {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); text-align: left;
  min-height: 0; padding: 13px var(--sp-4);
}
.entrada__caminoTexto { display: grid; gap: 1px; }
.entrada__caminoTexto strong { font-size: 15px; font-weight: var(--peso-fuerte); }
.entrada__caminoTexto small {
  font-size: 12.5px; font-weight: var(--peso-normal); line-height: 1.35;
  opacity: .72;
}
.entrada__caminoFlecha {
  font-size: 16px; opacity: .5; flex: none;
  transition: transform var(--rapido) var(--curva), opacity var(--rapido) var(--curva);
}
.entrada__camino:hover .entrada__caminoFlecha { transform: translateX(3px); opacity: 1; }

/* Los tres sellos: las dudas que tiene cualquiera antes de escribir su correo.
   En fila y con separadores, no como lista con viñetas — son tres etiquetas,
   no tres frases. */
.entrada__sellos {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px var(--sp-3);
  margin: 0; padding: 0; list-style: none;
  font-size: var(--t-meta); color: var(--e-tinta-3);
}
.entrada__sellos li { display: flex; align-items: center; gap: var(--sp-3); }
.entrada__sellos li:not(:last-child)::after {
  content: ""; width: 3px; height: 3px; border-radius: 50%;
  background: currentColor; opacity: .55;
}

.entrada__enlace {
  appearance: none; background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: var(--t-secundario); font-weight: var(--peso-medio);
  color: var(--e-marca); text-align: left;
}
.entrada__enlace:hover { text-decoration: underline; }
.entrada__enlace:focus-visible { outline: 2px solid var(--e-marca); outline-offset: 2px; }

.entrada__abajo {
  display: grid; gap: var(--sp-2); justify-items: center; text-align: center;
  margin-top: var(--sp-1);
}
.entrada__cambio { font-size: var(--t-secundario); color: var(--e-tinta-3); }

/* ---------- Campos ---------- */

.entrada__form { display: grid; gap: var(--sp-3); }
.entrada__campo { display: grid; gap: 6px; }
.entrada__etiqueta {
  font-size: var(--t-etiqueta); font-weight: var(--peso-medio);
  color: var(--e-tinta-2);
}
/* Sin tarjeta blanca alrededor: el campo se levanta del fondo por su propio
   relleno. Una tarjeta clara aquí sería el detalle que la vuelve una plantilla. */
.portada input {
  width: 100%; min-height: 52px;
  padding: 0 var(--sp-4);
  background: var(--e-alza); color: var(--e-tinta);
  border: 1px solid var(--e-linea); border-radius: var(--radius-sm);
  font: inherit; font-size: 16px;   /* 16px o iOS hace zoom al enfocar */
  transition: border-color var(--rapido) var(--curva), background var(--rapido) var(--curva);
}
.portada input::placeholder { color: var(--e-tinta-3); }
.portada input:hover { border-color: var(--e-tinta-3); }
.portada input:focus {
  outline: 0; background: var(--e-alza-2);
  border-color: var(--e-marca);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--e-marca) 22%, transparent);
}
/* El autocompletado de Chrome pinta el campo de amarillo y se lleva por delante
   la piel entera. La sombra interior es la única forma de taparlo. */
.portada input:-webkit-autofill {
  -webkit-text-fill-color: var(--e-tinta);
  -webkit-box-shadow: 0 0 0 100px var(--e-alza-2) inset;
  caret-color: var(--e-tinta);
}

.entrada__conOjo { position: relative; display: block; }
.entrada__conOjo input { padding-right: 88px; }
.entrada__ojo {
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: var(--t-secundario); font-weight: var(--peso-fuerte);
  color: var(--e-marca); padding: 8px 10px; border-radius: var(--radius-xs);
}
.entrada__ojo:hover { background: color-mix(in srgb, var(--e-marca) 14%, transparent); }
.entrada__ojo:focus-visible { outline: 2px solid var(--e-marca); outline-offset: 1px; }

/* El medidor de fuerza vive en la aplicación con los colores del tema claro.
   Aquí hay que repintarlo o no se lee. */
.portada .fuerza { font-size: var(--t-meta); color: var(--e-tinta-3); margin: 0; }
.portada .fuerza[data-nivel="flojo"] { color: var(--e-mal); }
.portada .fuerza[data-nivel="medio"] { color: #f3c46a; }
.portada .fuerza[data-nivel="bueno"],
.portada .fuerza[data-nivel="fuerte"] { color: var(--e-marca); }

/* ---------- En pantalla ancha, dos lados ----------

   Va al final de la sección a propósito: varias de estas reglas tienen la misma
   especificidad que la base que corrigen (.entrada__pie, .entrada__barra), así que
   lo único que decide es el orden. Estaba arriba y esas dos no hacían nada; se vio
   en una captura, no leyendo el archivo.  */
@media (min-width: 1024px) {
  .entrada {
    width: min(1040px, 100%);
    grid-template-columns: 1fr 420px;
    gap: clamp(var(--sp-5), 6vw, 80px);
    /* Por arriba. Centrada, la tarjeta flotaba a media altura contra una columna
       mucho más alta; estirada, el hueco se metía DENTRO de la tarjeta, que es
       peor —una tarjeta medio vacía se ve más vacía que una pequeña—. Alineadas
       por arriba, la tarjeta es del tamaño de lo que pide cada paso y se lee como
       algo terminado. */
    align-items: start;
  }

  /* Aquí sí en todos los pasos: hay sitio, y el decorado quieto al lado del
     panel que cambia es lo que hace que se lea como un recorrido. */
  .entrada__lado,
  #portada[data-paso="bienvenida"] .entrada__lado {
    display: grid; gap: var(--sp-4); align-content: center;
  }
  #portada[data-paso="bienvenida"] .entrada__puntos { display: grid; }

  .entrada__puntos {
    display: grid; gap: var(--sp-3);
    margin: 0; padding: 0; list-style: none;
  }
  .entrada__puntos li {
    display: grid; gap: 2px;
    /* La rayita hace de viñeta. Un punto redondo o un ✓ pediría explicar qué
       significa; una raya solo separa. */
    padding-left: var(--sp-3);
    border-left: 2px solid color-mix(in srgb, var(--e-marca) 55%, transparent);
  }
  .entrada__puntos strong {
    font-size: var(--t-secundario); font-weight: var(--peso-fuerte);
    color: var(--e-tinta);
  }
  .entrada__puntos span {
    font-size: var(--t-secundario); line-height: 1.45; color: var(--e-tinta-2);
  }

  /* El paso, dentro de una tarjeta. Flotando sobre el fondo se veía ligero;
     con suelo propio se ve como el sitio donde se hace la cosa. */
  .entrada__panel {
    position: relative;
    background:
      linear-gradient(to bottom,
        color-mix(in srgb, var(--e-alza-2) 60%, var(--e-alza)),
        var(--e-alza) 42%);
    border: 1px solid var(--e-linea);
    border-radius: calc(var(--radius) * 1.5);
    padding: var(--sp-5);
    gap: var(--sp-4);
    /* Sombra hacia abajo y una línea de luz arriba, como si le diera la luz de
       la pantalla. Es lo que la despega del fondo sin ponerle un borde de
       color, que la convertiría en un cartel. */
    box-shadow:
      0 24px 60px -30px rgba(0, 0, 0, .9),
      inset 0 1px 0 color-mix(in srgb, var(--e-tinta) 8%, transparent);
    animation: panelEntra 420ms var(--curva) backwards;
  }
  @keyframes panelEntra {
    from { opacity: 0; transform: translateY(10px); }
  }
  /* Los campos y la muestra se levantan del fondo; dentro de la tarjeta el
     fondo ya es ese, así que suben un escalón más para seguir viéndose. */
  .entrada__panel input { background: var(--e-fondo); }

  /* El logotipo ya está en el lado: en la hoja sobra, en cualquier paso. */
  .entrada__hoja .entrada__marca { display: none; }

  /* Y la bajada de la bienvenida, que repetía punto por punto lo que los tres
     puntos de al lado cuentan mejor. En el móvil sigue: allí no hay puntos. */
  .entrada__pantalla--bienvenida > .entrada__bajada { display: none; }

  /* Sin el logotipo, la barra se queda solo con la flecha de volver: que se
     quede a la izquierda en vez de estirarse a lo ancho. */
  .entrada__barra { justify-content: flex-start; }
  .entrada__pantalla--bienvenida > .entrada__barra:empty { display: none; }

  /* El título del paso, algo menor: aquí el que manda es el lema de al lado.
     Dos titulares del mismo tamaño compiten y no se lee ninguno. */
  .entrada__hoja .entrada__titulo { font-size: 26px; }
  .entrada__pie { text-align: left; }
}

/* ---------- El fondo, vivo ----------

   Tres capas y ninguna es un adorno de catálogo. Las manchas de color que
   flotan y el cristal esmerilado están en mil pantallas de entrada y por eso
   mismo no dicen nada de esta: podrían estar delante de una tienda de zapatos.
   Aquí el fondo usa el lenguaje de los gráficos de dentro.

   Todo se mueve con transform y opacity, que el navegador resuelve sin volver
   a calcular la página. Nada anima anchos ni posiciones.  */

.portada__fondo {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
}
.entrada { position: relative; z-index: 1; }

/* 1 · Papel rayado, como un libro de cuentas. Al 3% no se ve: se nota. */
.fondo__papel {
  position: absolute; inset: -2px;
  background-image:
    repeating-linear-gradient(to bottom,
      color-mix(in srgb, var(--e-tinta) 3%, transparent) 0 1px,
      transparent 1px 34px),
    repeating-linear-gradient(to right,
      color-mix(in srgb, var(--e-tinta) 2%, transparent) 0 1px,
      transparent 1px 120px);
  /* Se desvanece hacia el centro para que no compita con lo que se lee. */
  mask-image: radial-gradient(120% 90% at 50% 45%, transparent 20%, #000 78%);
}

/* 2 · Dos luces muy lentas. Dan profundidad para que la tinta no sea una pared
      plana. Si se notan, sobran: por eso van al 40% de opacidad y tardan un
      minuto largo en dar una vuelta. */
.fondo__luz {
  position: absolute; border-radius: 50%;
  filter: blur(90px); opacity: .4;
  will-change: transform;
}
.fondo__luz--a {
  width: 46vw; height: 46vw; min-width: 380px; min-height: 380px;
  top: -14vh; left: -8vw;
  background: radial-gradient(circle, color-mix(in srgb, var(--e-marca) 22%, transparent), transparent 68%);
  animation: derivaA 46s ease-in-out infinite;
}
.fondo__luz--b {
  width: 38vw; height: 38vw; min-width: 320px; min-height: 320px;
  bottom: -16vh; right: -6vw;
  background: radial-gradient(circle, color-mix(in srgb, #1f7f93 20%, transparent), transparent 70%);
  animation: derivaB 62s ease-in-out infinite;
}
@keyframes derivaA {
  50% { transform: translate3d(7vw, 5vh, 0) scale(1.14); }
}
@keyframes derivaB {
  50% { transform: translate3d(-6vw, -4vh, 0) scale(1.1); }
}

/* 3 · El horizonte: el perfil de un mes, respirando. Es el gráfico de barras de
      dentro convertido en paisaje. Dice «esto va de dinero» sin un icono de
      moneda ni un billete, que es lo que pondría cualquiera. */
.fondo__horizonte {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: min(24vh, 210px);
  display: flex; align-items: flex-end; gap: .55vw;
  padding: 0 2vw;
  /* Bajo y tenue. Más alto pisaba el texto de los puntos, y un fondo que
     compite con lo que hay que leer no es fondo. */
  opacity: .34;
  mask-image: linear-gradient(to top, #000, transparent 92%);
}
.fondo__barra {
  flex: 1 1 0; height: var(--alto);
  border-radius: 3px 3px 0 0;
  background: linear-gradient(to top,
    color-mix(in srgb, var(--e-marca) 16%, transparent),
    color-mix(in srgb, var(--e-marca) 4%, transparent));
  transform-origin: bottom;
  animation: respira var(--tarda) ease-in-out infinite alternate;
  animation-delay: var(--espera);
  will-change: transform;
}
@keyframes respira { to { transform: scaleY(.62); } }

/* ---------- La cinta que clasifica sola ----------

   Lo que de verdad hace la aplicación, en bucle: un movimiento entra en crudo,
   se le pone categoría y engorda su barra. Es lo único de esta pantalla que
   ninguna otra puerta de entrada puede copiar, porque es el producto.  */

.cinta {
  background: color-mix(in srgb, var(--e-alza) 88%, transparent);
  border: 1px solid var(--e-linea);
  border-radius: calc(var(--radius) * 1.4);
  padding: var(--sp-4);
  display: grid; gap: var(--sp-3);
  backdrop-filter: blur(6px);
  transition: opacity var(--lento) var(--curva);
}
.cinta--reinicia { opacity: .45; }

.cinta__cab {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3);
  padding-bottom: var(--sp-3); border-bottom: 1px solid var(--e-linea);
}
.cinta__mes {
  font-size: var(--t-meta); font-weight: var(--peso-fuerte);
  text-transform: uppercase; letter-spacing: .07em; color: var(--e-tinta-3);
}
.cinta__total {
  font-size: 22px; font-weight: var(--peso-fuerte); letter-spacing: -.02em;
  color: var(--e-tinta);
}

/* El renglón de arriba: lo que acaba de llegar del banco. Alto fijo — si
   creciera y menguara con el texto, la tarjeta daría un salto en cada
   movimiento y la pantalla entera temblaría. */
.cinta__entrante {
  display: grid; grid-template-columns: 1fr auto; gap: 2px var(--sp-3);
  align-items: center; min-height: 46px;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--e-fondo) 60%, transparent);
  border: 1px dashed var(--e-linea);
}
.cinta__crudo {
  font-size: var(--t-meta); letter-spacing: .04em;
  color: var(--e-tinta-2); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.cinta__entranteMonto {
  font-size: var(--t-secundario); font-weight: var(--peso-medio);
  color: var(--e-tinta);
}
/* La categoría que le pone la aplicación. Ocupa su sitio desde el principio
   (grid-column) aunque esté vacía, por lo mismo: nada se mueve al aparecer. */
.cinta__chip {
  grid-column: 1 / -1; justify-self: start;
  font-size: 11px; font-weight: var(--peso-fuerte);
  padding: 2px 9px; border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--e-marca) 16%, transparent);
  color: var(--e-marca);
  opacity: 0; transform: translateY(4px) scale(.94);
  transition: opacity 260ms var(--curva), transform 260ms var(--curva);
}
.cinta__chip--puesta { opacity: 1; transform: none; }

/* Entra deslizándose desde arriba: viene de fuera, del archivo del banco. */
@keyframes entraMovimiento {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: none; }
}
.cinta__entrante--entra { animation: entraMovimiento 380ms var(--curva) backwards; }
/* Al clasificarse deja de ser un renglón crudo: el borde se vuelve sólido y se
   tiñe de marca. Es el «ya sé lo que eres» dicho sin palabras. */
.cinta__entrante--clasificado {
  border-style: solid;
  border-color: color-mix(in srgb, var(--e-marca) 34%, transparent);
  background: color-mix(in srgb, var(--e-marca) 7%, var(--e-fondo));
  transition: border-color 300ms var(--curva), background 300ms var(--curva);
}
.cinta__entrante--quieta { border-style: solid; }

.cinta__lista { display: grid; gap: var(--sp-3); }
.cinta__fila {
  display: grid; grid-template-columns: 1fr auto; gap: 3px var(--sp-3);
  align-items: baseline;
  padding: 2px 6px; margin: -2px -6px;
  border-radius: 8px;
  transition: background 320ms var(--curva);
}
/* La fila que acaba de recibir se enciende un momento: sin eso hay que estar
   mirando el número exacto para saber cuál creció. */
.cinta__fila--recibe { background: color-mix(in srgb, var(--e-marca) 9%, transparent); }
.cinta__nombre { font-size: var(--t-secundario); color: var(--e-tinta-2); }
.cinta__monto {
  font-size: var(--t-secundario); font-weight: var(--peso-medio); color: var(--e-tinta);
}
.cinta__barra {
  grid-column: 1 / -1;
  height: 6px; border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--e-tinta-3) 20%, transparent);
  overflow: hidden;
}
.cinta__relleno {
  display: block; height: 100%; border-radius: var(--radius-pill);
  background: linear-gradient(to right,
    color-mix(in srgb, var(--e-marca) 72%, transparent), var(--e-marca));
  transform: scaleX(var(--parte, 0)); transform-origin: left;
  /* Lento y con freno: la barra «llega», no aparece. */
  transition: transform 620ms var(--curva);
}

/* El punto de «en vivo». Late despacio, como el de una grabación: sin él, los
   números que se mueven solos parecen un fallo. */
.entrada__vivo {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--e-marca); flex: none;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--e-marca) 55%, transparent);
  animation: late 2.4s ease-out infinite;
}
@keyframes late {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--e-marca) 55%, transparent); }
  70%  { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

@media (prefers-reduced-motion: reduce) {
  /* Para quien tiene vértigo o migraña vestibular una pantalla que se mueve
     sola marea de verdad. No se suaviza: se apaga. */
  .fondo__luz, .fondo__barra, .entrada__vivo, .entrada__panel { animation: none; }
  .cinta__entrante--entra { animation: none; }
  .cinta__relleno, .cinta__chip, .cinta__fila, .cinta__entrante { transition: none; }
}
/* ---------- Invitación ---------- */

/* A qué te invitan, antes de pedirte la contraseña: si no, quien no tiene cuenta
   no sabe para qué se la están pidiendo. */
.entrada__invitacion {
  display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3);
  align-items: start;
  background: color-mix(in srgb, var(--e-marca) 10%, var(--e-alza));
  border: 1px solid color-mix(in srgb, var(--e-marca) 26%, transparent);
  border-radius: var(--radius); padding: var(--sp-3) var(--sp-4);
}
.entrada__invitacionIcono { font-size: 22px; line-height: 1.2; }
.entrada__invitacionTexto { display: grid; gap: 3px; }
.entrada__invitacion strong { font-size: var(--t-cuerpo); color: var(--e-tinta); }
.entrada__invitacion span { font-size: var(--t-secundario); color: var(--e-tinta-2); }
.entrada__invitacion small { font-size: var(--t-meta); color: var(--e-tinta-3); }

/* ---------- El sello del mensaje ---------- */

.entrada__sello {
  width: 52px; height: 52px; border-radius: var(--radius-pill);
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--e-marca) 16%, transparent);
  color: var(--e-marca); font-size: 24px; font-weight: var(--peso-fuerte);
}

/* ---------- El paso de una pantalla a otra ---------- */

/* Hacia dónde se mueve dice si avanzas o vuelves, sin una miga de texto. Es la
   única animación de la puerta: si además se movieran los botones y los campos,
   cada paso costaría medio segundo de mirar. */
.portada[data-dir="ade"] .entrada__pantalla { animation: entraAde var(--normal) var(--curva); }
.portada[data-dir="atras"] .entrada__pantalla { animation: entraAtras var(--normal) var(--curva); }
@keyframes entraAde {
  from { opacity: 0; transform: translateX(14px); }
  to { opacity: 1; transform: none; }
}
@keyframes entraAtras {
  from { opacity: 0; transform: translateX(-14px); }
  to { opacity: 1; transform: none; }
}

/* Con el movimiento apagado no se anima nada, pero las barras tienen que
   quedarse en su tamaño final: sin esto se quedarían a cero y la muestra
   parecería un mes sin gastos. */
@media (prefers-reduced-motion: reduce) {
  .portada[data-dir] .entrada__pantalla { animation: none; }
  /* Y las barras se quedan del tamaño que les toca. Sin esto valdrían cero con el
     movimiento apagado, y la pantalla diría que ese mes no se gastó nada. */
  .cinta__relleno { transition: none; }
}

/* En pantallas bajas —un móvil apaisado, un portátil de 13"— la columna se pega
   arriba en vez de centrarse, que es lo que provoca que el título se salga por
   encima sin poder desplazarse. */
@media (max-height: 760px) {
  .portada { place-items: start center; }
  .entrada { gap: var(--sp-4); }
}

/* Lista de puntos sin viñeta, para explicaciones cortas dentro de una tarjeta. */
.lista-limpia { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.lista-limpia li { font-size: 13px; line-height: 1.5; }
.lista-limpia strong { color: var(--text-primary); }
.lista-limpia span { color: var(--text-secondary); }

/* ---------- Pantalla de bloqueo ---------- */
/* Cubre la aplicación entera. No es "seguridad" por sí misma: lo que protege los
   datos es que están cifrados y sin la contraseña no hay nada que mostrar. */
.candado {
  position: fixed; inset: 0; z-index: 70;
  display: grid; place-items: center; padding: 20px;
  background: var(--page);
}
body.bloqueada { overflow: hidden; }
.candado__caja {
  width: min(420px, 100%); display: grid; gap: 14px;
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow);
}
.candado__marca { display: flex; align-items: center; gap: 10px; }
.candado__marca svg { width: 34px; height: 34px; flex: none; }
.candado__marca strong { font-size: 16px; }
.candado__marca span { display: block; font-size: 11.5px; color: var(--text-muted); }
.candado__nota { font-size: 12px; color: var(--text-secondary); }
.candado__error { font-size: 12.5px; color: var(--critical); min-height: 18px; }
.candado input { width: 100%; }
.candado__pie { font-size: 11.5px; color: var(--text-muted); }
.fuerza { font-size: 11.5px; }
.fuerza[data-nivel="corta"], .fuerza[data-nivel="debil"] { color: var(--critical); }
.fuerza[data-nivel="mejorable"], .fuerza[data-nivel="aceptable"] { color: var(--text-secondary); }
.fuerza[data-nivel="buena"] { color: var(--success-text); }

.modal-host {
  position: fixed; inset: 0; z-index: 80; display: grid; place-items: center;
  background: color-mix(in srgb, var(--text-primary) 32%, transparent);
  padding: 20px; overflow: auto;
}
.modal {
  background: var(--surface-1); border-radius: var(--radius); border: 1px solid var(--border);
  box-shadow: var(--shadow); width: min(560px, 100%); padding: 18px; display: grid; gap: 14px;
}
.modal--wide { width: min(900px, 100%); }
.modal__head { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.modal__body { display: grid; gap: 12px; }
.modal__foot { display: flex; justify-content: flex-end; gap: 8px; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr)); gap: 12px; }
.form-grid .field--wide { grid-column: 1 / -1; }

/* ==========================================================================
   El recorrido de bienvenida
   ==========================================================================
   Lleva la piel de la puerta de entrada —las mismas fichas --e-*— por dos
   razones. Una: reutiliza la cinta que clasifica sola, y esa está escrita
   contra esas fichas. Dos: quien acaba de entrar viene de ver la puerta hace
   diez segundos, y encontrarse la misma tinta hace que esto se lea como el
   paso siguiente y no como otra aplicación.

   Las fichas se declaran aquí en vez de heredarse porque esta capa NO cuelga
   de `.portada`: es hermana suya, y vive cuando la puerta ya se cerró.  */

.bienv {
  --e-fondo: var(--tinta-fondo);
  --e-alza: var(--tinta-alza);
  --e-alza-2: var(--tinta-alza-2);
  --e-linea: var(--tinta-linea);
  --e-tinta: var(--tinta-ink);
  --e-tinta-2: var(--tinta-ink-2);
  --e-tinta-3: var(--tinta-ink-3);
  --e-marca: var(--tinta-marca);
  --e-marca-ink: var(--tinta-marca-ink);

  position: fixed; inset: 0; z-index: 90;
  color: var(--e-tinta);
  display: grid; place-items: center;
  padding: max(var(--sp-4), env(safe-area-inset-top)) var(--sp-4)
           max(var(--sp-4), env(safe-area-inset-bottom));
  overflow: auto;
  font-variant-numeric: tabular-nums;

  /* El fondo atenúa la aplicación en vez de taparla. Que se siga viendo lo que
     hay detrás cambia lo que esto significa: no es otra pantalla a la que te han
     mandado, es algo que está encima de TU aplicación y que se puede cerrar.
     Además quita el susto de «¿y esto dónde me metió?» en el primer minuto. */
  background: color-mix(in srgb, var(--page) 72%, transparent);
  backdrop-filter: blur(6px);
  animation: bienvEntra var(--normal) var(--curva);
}
.bienv--sale { animation: bienvSale var(--rapido) var(--curva-salida) forwards; }
@keyframes bienvEntra { from { opacity: 0; } }
@keyframes bienvSale { to { opacity: 0; } }

/* El panel. Lleva la piel de tinta —y el fondo vivo dentro— mientras la
   aplicación se ve alrededor, atenuada.

   El alto es fijo y no «lo que ocupe»: los pasos no miden lo mismo (uno lleva la
   cinta, otro tres filas, el último tres botones) y un panel que crece y encoge
   en cada paso mueve los botones bajo el dedo. Con el alto quieto, «Siguiente»
   está siempre en el mismo sitio. */
.bienv__caja {
  position: relative; z-index: 1; overflow: hidden;
  width: min(560px, 100%);
  height: min(680px, 92vh);
  background: var(--e-fondo);
  border: 1px solid var(--e-linea);
  border-radius: var(--radius-lg);
  box-shadow: 0 28px 70px -28px rgba(0, 0, 0, .85);
  animation: bienvSube var(--normal) var(--curva);
}
.bienv__caja:focus { outline: none; }
@keyframes bienvSube {
  from { opacity: 0; transform: translateY(12px) scale(.985); }
}

/* El contenido, por encima del fondo vivo del panel. Se desplaza por dentro si
   un paso no cabe, en vez de desbordar el panel. */
/* El horizonte de barras, contenido. En la puerta ocupa el bajo de una pantalla
   entera y queda discreto; dentro de un panel de 660 px es proporcionalmente el
   triple y sale justo detrás de «Siguiente», compitiendo con el botón que hay que
   pulsar. Se queda como textura, no como dibujo. */
.bienv__caja .fondo__horizonte { height: 92px; opacity: .16; }
.bienv__caja .fondo__luz { opacity: .3; }

.bienv__dentro {
  position: relative; z-index: 1;
  height: 100%;
  display: grid; grid-template-rows: auto 1fr auto; gap: var(--sp-4);
  padding: var(--sp-5);
  /* NO se desplaza el panel entero: si rueda esto, el pie —con «Siguiente»— se
     va por debajo del borde y no hay forma de seguir. Lo que rueda es la escena,
     que es la fila de en medio. */
  overflow: hidden;
}

/* Discreto y siempre disponible. Un recorrido del que no se puede salir en el
   primer segundo es una trampa, no una bienvenida. */
/* Dentro del panel y arriba a la derecha: fuera se salía por encima del borde
   en cuanto el panel dejó de ocupar la pantalla entera. */
.bienv__saltar {
  justify-self: end;
  background: none; border: 0; cursor: pointer; padding: 4px 6px;
  color: var(--e-tinta-3); font-size: var(--t-meta);
}
.bienv__saltar:hover { color: var(--e-tinta); }

/* Cada paso entra desde abajo.

   La escena es lo ÚNICO que se desplaza, y `min-height: 0` es lo que lo hace
   posible. Es fácil de no ver: una fila de rejilla no encoge por debajo de su
   contenido a menos que se le diga explícitamente. Sin esa línea la fila del
   medio crecía, el panel se desbordaba, y lo que rodaba era el panel entero —
   con el botón de «Siguiente» fuera de la pantalla y sin forma de seguir. */
.bienv__escena {
  display: grid; align-content: start;
  min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  /* Un poco de aire a la derecha para que la barra de desplazamiento no se pegue
     al texto cuando aparece. */
  padding-right: 2px;
}
.bienv__escena--entra .bienv__paso { animation: bienvPaso var(--normal) var(--curva); }
@keyframes bienvPaso {
  from { opacity: 0; transform: translateY(10px); }
}
.bienv__paso { display: grid; gap: var(--sp-3); align-content: start; }

.bienv__rotulo {
  margin: 0; color: var(--e-marca);
  font-size: var(--t-meta); font-weight: var(--peso-fuerte);
  text-transform: uppercase; letter-spacing: .08em;
}
.bienv__titulo {
  margin: 0; font-size: clamp(24px, 5.5vw, 32px); line-height: 1.15;
  letter-spacing: -.02em; color: var(--e-tinta);
}
.bienv__texto { margin: 0 0 var(--sp-2); color: var(--e-tinta-2); max-width: 44ch; }

/* ── Las listas de cada paso ── */
.bienv__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.bienv__lista li {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: var(--sp-3); border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--e-alza) 70%, transparent);
  border: 1px solid var(--e-linea);
  /* Entran escalonadas: el ojo las recorre en orden en vez de encontrarse tres
     bloques de golpe. El retraso sale del índice que pone el JS. */
  animation: bienvFila var(--normal) var(--curva) backwards;
  animation-delay: calc(var(--i, 0) * 70ms + 90ms);
}
@keyframes bienvFila { from { opacity: 0; transform: translateY(8px); } }
.bienv__lista strong { display: block; font-size: var(--t-cuerpo); }
.bienv__lista span { color: var(--e-tinta-2); font-size: var(--t-menor); }
.bienv__icono { font-size: 20px; line-height: 1.2; flex: 0 0 auto; }

/* ── Los tres caminos del final ── */
.bienv__caminos { display: grid; gap: var(--sp-3); }
.bienv__camino {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; text-align: left; cursor: pointer;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-sm);
  border: 1px solid var(--e-linea);
  background: color-mix(in srgb, var(--e-alza) 70%, transparent);
  color: var(--e-tinta);
  transition: border-color var(--rapido) var(--curva),
              transform var(--rapido) var(--curva);
  animation: bienvFila var(--normal) var(--curva) backwards;
}
.bienv__camino:nth-child(2) { animation-delay: 70ms; }
.bienv__camino:nth-child(3) { animation-delay: 140ms; }
.bienv__camino:hover { border-color: var(--e-marca); transform: translateX(2px); }
.bienv__caminoTxt { display: grid; gap: 2px; flex: 1 1 auto; min-width: 0; }
.bienv__caminoTxt strong { font-size: var(--t-cuerpo); }
.bienv__caminoTxt span { color: var(--e-tinta-2); font-size: var(--t-menor); }
.bienv__flecha { color: var(--e-tinta-3); flex: 0 0 auto; transition: transform var(--rapido) var(--curva); }
.bienv__camino:hover .bienv__flecha { transform: translateX(3px); }

/* El primero lleva el acento: es el que convierte esto en «se mantiene solo». */
.bienv__camino--fuerte {
  background: var(--e-marca); color: var(--e-marca-ink); border-color: var(--e-marca);
}
.bienv__camino--fuerte .bienv__caminoTxt span,
.bienv__camino--fuerte .bienv__flecha { color: color-mix(in srgb, var(--e-marca-ink) 78%, transparent); }
.bienv__camino--fuerte:hover { filter: brightness(1.06); }

/* ── El pie ── */
.bienv__pie { display: flex; align-items: center; gap: var(--sp-3); }
.bienv__pie--final { justify-content: center; }
.bienv__pie .btn--primary { margin-left: auto; }
.bienv__atras { color: var(--e-tinta-2); }

.bienv__puntos { display: flex; gap: 6px; margin: 0 auto; }
.bienv__punto {
  width: 7px; height: 7px; border-radius: var(--radius-pill);
  background: var(--e-linea); cursor: pointer;
  transition: background var(--rapido) var(--curva), width var(--rapido) var(--curva);
}
.bienv__punto--hecho { background: var(--e-tinta-3); }
.bienv__punto--aqui { background: var(--e-marca); width: 18px; }

/* En el teléfono el paso ocupa lo que necesite y el pie se queda abajo. */
/* En el teléfono sigue siendo un panel, no una pantalla: se le deja el margen
   justo para que se vea que hay aplicación detrás. Sin margen volvería a
   parecer que te mandaron a otro sitio, que es lo que se quería evitar. */
@media (max-width: 560px) {
  .bienv { padding: var(--sp-3); }
  .bienv__caja { width: 100%; height: min(100%, 96vh); }
  .bienv__dentro { padding: var(--sp-4); gap: var(--sp-3); }
}

/* Movimiento reducido: se ve todo puesto, sin nada que entre ni se deslice.
   Un recorrido de bienvenida con cinco transiciones seguidas es justo lo que
   marea a quien tiene vértigo — y es su primer minuto en la aplicación. */
@media (prefers-reduced-motion: reduce) {
  .bienv, .bienv--sale, .bienv__caja, .bienv__escena--entra .bienv__paso,
  .bienv__lista li, .bienv__camino { animation: none; }
  .bienv__camino, .bienv__flecha, .bienv__punto { transition: none; }
}

/* ---------- Toasts ---------- */
.toasts { position: fixed; bottom: 18px; right: 18px; z-index: 95; display: grid; gap: 8px; justify-items: end; pointer-events: none; }
.toast {
  background: var(--surface-1); border: 1px solid var(--border-strong); box-shadow: var(--shadow);
  border-radius: var(--radius-sm); padding: 10px 13px; font-size: 13px; max-width: 340px; pointer-events: auto;
  display: flex; gap: 9px; align-items: flex-start; animation: toastIn .18s ease-out;
}
.toast__icon { font-size: 13px; line-height: 1.4; }
.toast--good .toast__icon { color: var(--success-text); }
.toast--bad .toast__icon { color: var(--critical); }
.toast--warn .toast__icon { color: var(--warning); }
@keyframes toastIn { from { opacity: 0; transform: translateY(6px); } }

/* ---------- Utilidades ---------- */
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row--between { justify-content: space-between; }
.stack { display: grid; gap: 10px; }
.sep { height: 1px; background: var(--grid); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  border: 1px solid var(--border-strong); background: var(--surface-1);
  border-radius: 999px; padding: 3px 10px; cursor: pointer;
}
.chip[aria-pressed="true"] { background: var(--accent); border-color: transparent; color: var(--accent-ink); }
.chip__x { border: 0; background: none; cursor: pointer; color: inherit; font-size: 13px; line-height: 1; padding: 0; }

/* ==========================================================================
   Responsive
   Un solo salto para la navegación (1024px): de barra lateral fija a barra
   inferior, que es lo cómodo con el pulgar. Debajo de 640px se compactan
   tipografías, tarjetas y tablas, y los modales pasan a hoja inferior.
   ========================================================================== */

.only-movil { display: none; }
.topbar__acciones { display: none; gap: 6px; align-items: center; }
@media (max-width: 1023px) { .topbar__acciones.only-movil { display: flex; } }
@media (max-width: 640px) { i.only-movil { display: inline-block; } }

.card__head, .card__tools, .filters, .row { min-width: 0; }
.app, .main, .view, .card, .topbar { min-width: 0; }
table.data { max-width: 100%; }

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

  /* La barra lateral se convierte en un menú desplegable: el botón vive en la
     cabecera y el panel cae desde arriba con todas las secciones a la vista.
     Se abre y cierra con data-abierto (no con [hidden]) para que en escritorio
     la barra siga estando siempre visible. */
  .sidebar {
    display: none;
    position: fixed; inset: 0; z-index: 50;
    height: auto; width: auto; padding: 0;
    background: color-mix(in srgb, var(--text-primary) 42%, transparent);
    border-right: 0;
  }
  .sidebar[data-abierto="1"] { display: block; }

  .sidebar__panel {
    /* height:100% viene del escritorio: aquí el panel mide lo que ocupa su
       contenido, o el conmutador de tema se estiraría hasta abajo. */
    height: auto; align-content: start;
    background: var(--surface-1);
    border-bottom: 1px solid var(--border-strong);
    box-shadow: 0 14px 32px -18px rgba(0, 0, 0, .55);
    padding: 12px 14px calc(14px + env(safe-area-inset-bottom, 0px));
    max-height: min(88vh, 660px); overflow-y: auto;
    display: grid; gap: 12px;
    animation: menuBaja .16s ease-out;
  }
  @keyframes menuBaja { from { transform: translateY(-10px); opacity: .5; } }

  .brand { padding: 0 2px; }
  .sidebar__foot { margin-top: 2px; }
  .sidebar__note { display: none; }

  /* ── El menú del cajón ──

     Las dos columnas van DENTRO de cada grupo, no entre grupos.

     Antes la rejilla de dos columnas estaba en `.nav`, cuyos hijos son los
     GRUPOS. Así que colocaba «Inicio» al lado de «Mi dinero» entero, y como
     una fila de rejilla mide lo que el hijo más alto, el botón de Inicio se
     estiraba hasta 231 px: una caja enorme y vacía al lado de una lista. Los
     rótulos de sección quedaban descolocados y lo de abajo, cortado.

     Con la rejilla dentro del grupo se conserva lo que se buscaba —ver todas
     las secciones sin desplazarse— y además se lee: el rótulo ocupa la fila
     entera y debajo van sus enlaces en dos columnas.

     `align-items: start` es lo que impide que vuelvan a estirarse. */
  .nav { display: grid; grid-template-columns: 1fr; gap: var(--sp-4); }
  .nav__grupo {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px; align-items: start;
  }
  .nav__grupo-rotulo { grid-column: 1 / -1; margin: 0; }
  /* El primer grupo es solo «Inicio»: media fila para él sería una caja suelta. */
  .nav__grupo:first-child .nav__item { grid-column: 1 / -1; }
  .nav__item { min-height: 44px; height: auto; font-size: 13px; padding: 10px; }
  .nav__icon { font-size: 15px; }
  .nav__badge { display: inline-flex; }

  .main { padding-bottom: 16px; }

  /* Cabecera compacta.
     Aquí vivía el plegado de la barra de periodo, y no funcionaba: la regla era
     `.topbar[data-filtros="1"] .filters`, pero `.filters` es HERMANO de
     `.topbar` (sale después de `</header>`), así que el selector no casaba
     nunca. El `display: none` tampoco pintaba nada, porque sistema.css carga
     después y su `.filters { display: flex }` lo pisa por orden de fuente.
     Resultado: la barra estaba siempre abierta y el botón solo giraba la flecha.

     El periodo y la cuenta ya no se pliegan: son contexto, y esconder el
     contexto obliga a abrirlo para saber si la cifra que ves es de este mes o
     del año entero. Se pintan como dos fichas en sistema.css. */
  .topbar { padding: 12px 14px; gap: 10px; align-items: center; }
  .topbar__head { flex: 1 1 auto; min-width: 0; }
  .only-movil { display: inline-flex; }
  .view { padding: 16px 14px 28px; }

  /* Se toca con el dedo: objetivos cómodos. Los controles dentro de tablas
     densas se quedan en 32px — la fila completa abre la ficha del movimiento. */
  input:not([type="checkbox"]), select, textarea { min-height: 40px; }
  .btn { min-height: 38px; }
  .btn--sm { min-height: 34px; }
  table.data select, table.data input:not([type="checkbox"]) { min-height: 32px; font-size: 13px; }
  table.data input[type="checkbox"] { width: 18px; height: 18px; }
  .card__head, .card__tools, .filters { flex-wrap: wrap; }
  .chip { min-height: 32px; padding: 6px 12px; }
  .theme-switch button { min-height: 34px; }
}

@media (max-width: 640px) {
  h1 { font-size: 17px; }
  .topbar__head p { display: none; }
  .view { padding: 12px 12px 24px; gap: 12px; }
  .grid { gap: 12px; }
  .card { padding: 13px; border-radius: 10px; }
  .hero__value { font-size: clamp(30px, 8.5vw, 48px); }
  .tile__value { font-size: 21px; }
  .hero__meta { gap: 4px 10px; font-size: 12px; }

  /* 16px en los campos evita que iOS haga zoom al enfocarlos. */
  input:not([type="checkbox"]), select, textarea { font-size: 16px; }
  .btn { padding: 8px 13px; }
  .card__head { flex-wrap: wrap; gap: 8px; }
  .card__tools { flex-wrap: wrap; }
  .cell-desc { max-width: 46vw; }
  .dropzone { padding: 22px 14px; }
  .dropzone strong { font-size: 14px; }
  .legend { gap: 4px 12px; }
  .meter-row__top { flex-wrap: wrap; }
  .pager { flex-wrap: wrap; gap: 8px; }
  .toasts { left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); justify-items: stretch; }
  .toast { max-width: none; }

  /* Aquí NO se esconde ninguna columna: por debajo de 640 px la tabla ya no es
     una tabla, cada fila se apila en vertical (sistema.css, «La tabla en un
     teléfono») y todas caben. Esconderlas era el apaño para que entrara de
     ancho, y costaba que quien mira sus gastos desde el móvil viera la mitad de
     lo que ve en el ordenador. La regla vive ahora en el tramo de tableta, más
     abajo, donde todavía es una tabla de verdad y va justa. */

  /* Modal como hoja inferior. */
  .modal-host { padding: 0; place-items: end stretch; }
  .modal {
    width: 100%; max-height: 92vh; overflow-y: auto;
    border-radius: 14px 14px 0 0; padding: 16px 14px calc(16px + env(safe-area-inset-bottom, 0px));
  }
  .modal--wide { width: 100%; }
  .modal__foot { position: sticky; bottom: 0; background: var(--surface-1); padding-top: 10px; }
  .modal__foot .btn { flex: 1 1 auto; justify-content: center; }
}

/* Tramo de tableta: la tabla sigue siendo una tabla y va justa de ancho, así que
   aquí sí se esconden las columnas secundarias. Por debajo de 640 px la fila se
   apila en vertical y vuelven a verse todas — de ahí el mínimo de 641px. */
@media (min-width: 641px) and (max-width: 1023px) {
  .hide-sm { display: none !important; }
}

@media (max-width: 380px) {
  /* Por debajo de 380 px, dos columnas dejan los nombres partidos por la
     mitad («Ordenar lo / suelto»). Mejor desplazarse que leer a trozos. */
  .nav__grupo { grid-template-columns: 1fr; }
  .card { padding: 11px; }
  .view { padding: 10px 10px 20px; }
}

/* Menos altura de gráfico en pantallas cortas (móvil en horizontal). */
@media (max-height: 520px) and (max-width: 1023px) {
  .chart-wrap { max-height: 210px; }
}

@media print {
  .sidebar, .filters, .card__tools, .row-actions { display: none !important; }
  .app { grid-template-columns: 1fr; }
  .main { padding-bottom: 0; }
  .card { break-inside: avoid; }
}

