/* =========================================================
   Difereti Master Dashboard · tema shadcn/ui
   Tokens basados en shadcn/ui (zinc, light por defecto).
   ========================================================= */

:root {
  --background: hsl(0 0% 100%);
  --foreground: hsl(240 10% 3.9%);
  --card: hsl(0 0% 100%);
  --card-foreground: hsl(240 10% 3.9%);
  --popover: hsl(0 0% 100%);
  --popover-foreground: hsl(240 10% 3.9%);
  --primary: hsl(240 5.9% 10%);
  --primary-foreground: hsl(0 0% 98%);
  --secondary: hsl(240 4.8% 95.9%);
  --secondary-foreground: hsl(240 5.9% 10%);
  --muted: hsl(240 4.8% 95.9%);
  --muted-foreground: hsl(240 3.8% 46.1%);
  --accent: hsl(240 4.8% 95.9%);
  --accent-foreground: hsl(240 5.9% 10%);
  --destructive: hsl(0 84.2% 60.2%);
  --destructive-foreground: hsl(0 0% 98%);
  --border: hsl(240 5.9% 90%);
  --input: hsl(240 5.9% 90%);
  --ring: hsl(240 10% 3.9%);
  --radius: 0.5rem;
  --sidebar-w: 14.5rem;
  --success: hsl(152 76% 40%);
  --success-foreground: hsl(0 0% 98%);
  --warning: hsl(32 95% 44%);
  --chart-1: #f97316;
  --chart-2: #3b82f6;
  --chart-3: #8b5cf6;
  --chart-4: #22c55e;
  --chart-5: #eab308;
  --salud-rango-normal: hsl(24 95% 55%);
  --salud-gauge-linea: hsl(240 10% 3.9%);
  --salud-gauge-punto: hsl(240 10% 3.9%);
  --finanzas-tabbar-bg: hsl(0 0% 100% / 0.92);
  --finanzas-tabbar-fg: hsl(240 3.8% 46.1%);
  --finanzas-tabbar-fg-activo: hsl(240 5.9% 10%);
  --finanzas-tabbar-borde: hsl(240 5.9% 90%);
  --finanzas-hoy: #f97316;
  /* Acciones circulares del editor rápido: verde para confirmar, rojo para
     descartar. No se reutilizan --success/--destructive crudos porque sobre
     fondo blanco quedan en 2,71:1 y 3,76:1 — por debajo del 4,5:1 que exige
     AA para un glifo que se lee como texto; aquí se declaran las variantes con
     contraste medido (5,48:1 y 6,64:1). */
  --finanzas-rapida-guardar: hsl(152 62% 29%);
  --finanzas-rapida-cancelar: hsl(0 74% 41%);
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-tema]) {
    /* Acciones circulares del editor rápido: el mismo par, en la variante
       clara que pide el fondo oscuro (9,03:1 y 5,86:1 de contraste medido). */
    --finanzas-rapida-guardar: hsl(152 62% 48%);
    --finanzas-rapida-cancelar: hsl(0 84% 64%);
    --background: hsl(240 10% 3.9%);
    --foreground: hsl(0 0% 98%);
    --card: hsl(240 10% 3.9%);
    --card-foreground: hsl(0 0% 98%);
    --popover: hsl(240 10% 3.9%);
    --popover-foreground: hsl(0 0% 98%);
    --primary: hsl(0 0% 98%);
    --primary-foreground: hsl(240 5.9% 10%);
    --secondary: hsl(240 3.7% 15.9%);
    --secondary-foreground: hsl(0 0% 98%);
    --muted: hsl(240 3.7% 15.9%);
    --muted-foreground: hsl(240 5% 64.9%);
    --accent: hsl(240 3.7% 15.9%);
    --accent-foreground: hsl(0 0% 98%);
    --destructive: hsl(0 62.8% 30.6%);
    --destructive-foreground: hsl(0 0% 98%);
    --border: hsl(240 3.7% 15.9%);
    --input: hsl(240 3.7% 15.9%);
    --ring: hsl(240 4.9% 83.9%);
    --salud-gauge-linea: hsl(0 0% 98%);
    --salud-gauge-punto: hsl(0 0% 98%);
    --finanzas-tabbar-bg: hsl(240 10% 3.9% / 0.9);
    --finanzas-tabbar-fg: hsl(240 5% 64.9%);
    --finanzas-tabbar-fg-activo: hsl(0 0% 98%);
    --finanzas-tabbar-borde: hsl(240 3.7% 15.9%);
  }
}

/* Modo oscuro manual (toggle del masthead): mismos tokens que el oscuro por
   sistema, gobernados por el atributo data-tema en <html>. La media query de
   arriba queda anulada en cuanto existe elección explícita. */
:root[data-tema="oscuro"] {
  color-scheme: dark;
  /* Acciones circulares del editor rápido (mismo par que el oscuro por
     sistema). */
  --finanzas-rapida-guardar: hsl(152 62% 48%);
  --finanzas-rapida-cancelar: hsl(0 84% 64%);
  --background: hsl(240 10% 3.9%);
  --foreground: hsl(0 0% 98%);
  --card: hsl(240 10% 3.9%);
  --card-foreground: hsl(0 0% 98%);
  --popover: hsl(240 10% 3.9%);
  --popover-foreground: hsl(0 0% 98%);
  --primary: hsl(0 0% 98%);
  --primary-foreground: hsl(240 5.9% 10%);
  --secondary: hsl(240 3.7% 15.9%);
  --secondary-foreground: hsl(0 0% 98%);
  --muted: hsl(240 3.7% 15.9%);
  --muted-foreground: hsl(240 5% 64.9%);
  --accent: hsl(240 3.7% 15.9%);
  --accent-foreground: hsl(0 0% 98%);
  --destructive: hsl(0 62.8% 30.6%);
  --destructive-foreground: hsl(0 0% 98%);
  --border: hsl(240 3.7% 15.9%);
  --input: hsl(240 3.7% 15.9%);
  --ring: hsl(240 4.9% 83.9%);
  --salud-gauge-linea: hsl(0 0% 98%);
  --salud-gauge-punto: hsl(0 0% 98%);
  --finanzas-tabbar-bg: hsl(240 10% 3.9% / 0.9);
  --finanzas-tabbar-fg: hsl(240 5% 64.9%);
  --finanzas-tabbar-fg-activo: hsl(0 0% 98%);
  --finanzas-tabbar-borde: hsl(240 3.7% 15.9%);
}

:root[data-tema="claro"] {
  color-scheme: light;
}

* {
  box-sizing: border-box;
  border-color: var(--border);
}

[hidden] {
  display: none !important;
}

html {
  scroll-behavior: smooth;
  /* El doble toque no acerca la página: el navegador solo desplaza o
     pellizca. El viewport ya fija maximum-scale=1. */
  touch-action: manipulation;
}

body {
  margin: 0;
  overflow-x: hidden;
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a {
  color: inherit;
}

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

.skip-link {
  position: absolute;
  top: -3rem;
  left: 0.75rem;
  z-index: 20;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius);
  background: var(--primary);
  color: var(--primary-foreground);
  font-size: 0.8rem;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link:focus {
  top: 0.75rem;
}

/* ─── Header sticky (legado dashboard). En shell iOS de Cadushi no se usa:
   la marca vive en el ícono PWA y la navegación en la tab bar inferior. ─── */

.masthead {
  display: none;
}

.identity-mark {
  display: grid;
  width: 1.75rem;
  height: 1.75rem;
  place-items: center;
  border-radius: 0.4rem;
  background: var(--primary);
  color: var(--primary-foreground);
  font-size: 0.8rem;
  font-weight: 800;
}

.clock-block {
  display: grid;
  gap: 0.05rem;
  min-width: 6.5rem;
  text-align: right;
}

.clock-block span {
  color: var(--muted-foreground);
  font-size: 0.68rem;
}

.clock-block time {
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* Toggle día/noche: sol visible en modo día, luna en modo noche. El ícono
   indica el modo ACTUAL y el clic alterna. En móvil se empuja al borde
   derecho (el reloj se oculta por espacio). */
.tema-toggle {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  margin-left: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
}

.tema-toggle:hover {
  background: var(--accent);
  color: var(--accent-foreground);
}

.tema-toggle:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

.tema-toggle .icono-luna {
  display: none;
}

:root[data-tema="oscuro"] .tema-toggle .icono-luna {
  display: block;
}

:root[data-tema="oscuro"] .tema-toggle .icono-sol {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-tema]) .tema-toggle .icono-luna {
    display: block;
  }

  :root:not([data-tema]) .tema-toggle .icono-sol {
    display: none;
  }
}

/* Accesos rápidos de solo-icono: visibles únicamente en móvil, donde el
   sidebar fijo se convierte en cajón. En desktop el sidebar ya da acceso. */
.masthead-nav {
  display: none;
}

/* Iconos de la cabecera móvil un poco más gruesos para leerse mejor al toque. */
.masthead-nav svg path,
.masthead-nav svg rect,
.sidebar-burger svg path {
  stroke-width: 2.4;
}

/* ─── Lienzo ─── */

.dashboard-canvas {
  flex: 1;
  width: 100%;
  max-width: none;
  min-width: 0;
  padding: 0.25rem 0 2rem;
  /* Los gestos horizontales quedan reservados para la navegación por
     deslizamiento; el scroll vertical sigue siendo nativo. */
  touch-action: pan-y;
}

/* ─── Navegación por deslizamiento entre módulos ─── */

/* Cada vista muestra un único módulo, acotado para que las tarjetas no se
   estiren de más en pantallas ultrawide. Vive en el carril de módulos: cada
   vista ocupa exactamente el ancho del lienzo (flex) y el arrastre táctil
   desplaza el carril completo. */
.module-view {
  flex: 0 0 100%;
  min-width: 100%;
  max-width: 1900px;
}

/* ─── Carril de módulos (navegación por deslizamiento) ──────────────────── */
/* El carril se mueve con transform (px) controlado por JS: 1:1 con el dedo
   durante el gesto y con transición al soltar o al navegar por el sidebar.
   La altura del envoltorio se fija a la vista activa (evita el scroll
   fantasma de las vecinas) y se libera durante el arrastre. */
.module-track-wrap {
  overflow-x: hidden;
  overflow-y: hidden;
  width: 100%;
  transition: height 220ms cubic-bezier(0.22, 1, 0.36, 1);
}

.module-track-wrap.arrastrando {
  transition: none;
}

.module-track {
  display: flex;
  /* Cada vista conserva su altura natural: sin esto, el flex estira todas las
     vistas a la altura de la más alta y los módulos cortos dejan un hueco
     fantasma hasta la franja de avisos (reportado por Santiago). */
  align-items: flex-start;
  width: 100%;
  transform: translateX(0);
  will-change: transform;
}

.module-track.animando {
  transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* ─── Shell: sidebar fijo al borde + marco del contenido ─── */

.app-frame {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin-left: var(--sidebar-w);
  min-width: 0;
  transition: margin-left 0.18s ease;
}

.sidebar-burger {
  display: none;
}

.app-sidebar {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: var(--sidebar-w);
  padding: 0.85rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-right: 1px solid var(--border);
  background: var(--card);
  color: var(--card-foreground);
  transition: width 0.18s ease;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 0.55rem;
}

.sidebar-brand-name {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 650;
}

.sidebar-brand-sub {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.sidebar-nav {
  display: grid;
  gap: 0.7rem;
}

.sidebar-group-title {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.sidebar-nav ul {
  display: grid;
  gap: 2px;
  margin: 0.25rem 0 0;
  padding: 0;
  list-style: none;
}

.sidebar-link-row {
  display: flex;
  align-items: stretch;
  gap: 0.1rem;
}

.sidebar-link-row .sidebar-link {
  flex: 1;
  min-width: 0;
}

.sidebar-sublist-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  border: none;
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
}

.sidebar-sublist-toggle:hover {
  color: var(--foreground);
}

.sidebar-sublist-chevron {
  transition: transform 0.15s ease;
}

.sidebar-sublist-toggle[aria-expanded="false"] .sidebar-sublist-chevron {
  transform: rotate(-90deg);
}

.sidebar-link {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.6rem;
  border-radius: var(--radius);
  color: var(--muted-foreground);
  font-size: 0.84rem;
  font-weight: 550;
  text-decoration: none;
}

.sidebar-link svg {
  flex: none;
  opacity: 0.85;
}

.sidebar-link:hover {
  background: var(--accent);
  color: var(--accent-foreground);
}

.sidebar-link[aria-current="page"] {
  background: var(--muted);
  color: var(--foreground);
}

.sidebar-planned {
  display: flex;
  align-items: center;
  padding: 0.45rem 0.6rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--muted-foreground);
  font-size: 0.78rem;
  opacity: 0.75;
  cursor: default;
}

.sidebar-note {
  margin: auto 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  color: var(--muted-foreground);
  font-size: 0.66rem;
  line-height: 1.4;
}

.sidebar-backdrop {
  display: none;
}

/* ─── Card base ─── */

.module-card {
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--card);
  color: var(--card-foreground);
  box-shadow: 0 1px 2px hsl(240 5% 65% / 0.08);
}

/* Cada tarjeta de módulo es un contenedor: sus componentes se adaptan al
   ancho real de la tarjeta (no del viewport) para que los valores nunca se
   trunquen cuando el sidebar estrecha el lienzo. */
.operations-board {
  container-type: inline-size;
}

/* ─── Cabecera de módulo ─── */

.board-header,
.ds-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.1rem 1.25rem 0.9rem;
}

/* La identidad del servidor (M01) cae en su propia fila completa bajo el
   título: una sola línea, con ellipsis solo como respaldo extremo. */
.board-header {
  flex-wrap: wrap;
}

.board-title {
  flex: 1 1 auto;
  min-width: 0;
}

.board-identity {
  flex-basis: 100%;
  margin: 0.05rem 0 0;
  color: var(--muted-foreground);
  font-size: 0.82rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.board-title h2,
.ds-header-title h2 {
  margin: 0.1rem 0 0.25rem;
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}

.board-title p,
.ds-header-title p {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.82rem;
}

.module-eyebrow {
  color: var(--muted-foreground);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Botones shadcn */

.btn-outline {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2rem;
  padding: 0.35rem 0.8rem;
  border: 1px solid var(--input);
  border-radius: calc(var(--radius) - 2px);
  background: var(--background);
  color: var(--foreground);
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 550;
  box-shadow: 0 1px 2px hsl(240 5% 65% / 0.08);
}

.btn-outline:hover {
  background: var(--accent);
}

.btn-outline:disabled {
  opacity: 0.5;
  pointer-events: none;
}

/* Botón Actualizar: etiqueta y última lectura apiladas en dos líneas */
.refresh-text {
  display: grid;
  justify-items: start;
  gap: 0.05rem;
  line-height: 1.15;
}

.refresh-button {
  padding: 0.3rem 0.7rem;
}

.refresh-button time {
  color: var(--muted-foreground);
  font-size: 0.62rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.ds-button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2rem;
  padding: 0.35rem 0.85rem;
  border: none;
  border-radius: calc(var(--radius) - 2px);
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 600;
}

.ds-button-white {
  background: var(--primary);
  color: var(--primary-foreground);
}

.ds-button-white:hover {
  opacity: 0.9;
}

.ds-button-white:disabled {
  opacity: 0.5;
}

/* ─── M01 · VPS ─── */

.vps-overview {
  padding: 1rem 1.25rem;
  border-top: 1px solid var(--border);
}

.vps-server-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.3rem 0.9rem;
  margin-bottom: 0.9rem;
}

.vps-server-primary {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  min-width: 0;
}

.vps-server-primary strong,
.vps-server-primary p {
  margin: 0;
}

.vps-server-primary strong {
  overflow: hidden;
  font-size: 0.9rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vps-server-primary p {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--muted-foreground);
  font-size: 0.78rem;
}

/* Servidor e IPv4 viven en la misma línea del sistema operativo y el plan. */
.vps-server-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.9rem;
  margin: 0;
}

.vps-server-facts div {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  min-width: 0;
}

.vps-server-facts dt {
  color: var(--muted-foreground);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.vps-server-facts dd {
  overflow: hidden;
  margin: 0;
  font-size: 0.8rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Badge / status pill */

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--secondary);
  color: var(--secondary-foreground);
  font-size: 0.68rem;
  font-weight: 650;
  white-space: nowrap;
}

.status-pill[data-state="running"] {
  border-color: color-mix(in srgb, var(--success) 30%, transparent);
  background: color-mix(in srgb, var(--success) 8%, transparent);
  color: color-mix(in srgb, var(--success) 78%, var(--foreground));
}

/* KPI tiles */

.vps-metric-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.7rem;
}

.swap-strip .vps-metric-tile {
  min-height: 7.4rem;
}

.swap-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.7rem;
}

/* Dispositivos de swap: una sola fila horizontal, un donut por dispositivo. */
#swap-dispositivos {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 0.45rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.swap-dispositivo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.28rem;
  min-width: 0;
  padding: 0.45rem 0.2rem;
  text-align: center;
}

.swap-dispositivo .swap-dispositivo-ring {
  width: 3.1rem;
  height: 3.1rem;
  flex: none;
}

.swap-dispositivo-ruta {
  overflow: hidden;
  max-width: 100%;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.72rem;
  font-weight: 600;
}

.swap-dispositivo-capacidad {
  color: var(--foreground);
  font-size: 0.68rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.swap-dispositivo-prio {
  color: var(--muted-foreground);
  font-size: 0.62rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.swap-tuning {
  margin: 0.5rem 0 0.25rem;
  color: var(--muted-foreground);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
}

.swap-scope-note {
  margin: -0.15rem 0 0.45rem;
  color: var(--muted-foreground);
  font-size: 0.68rem;
  line-height: 1.35;
}

/* Filas de la ficha zram: la columna de valores queda alineada en el borde
   derecho con un grid de dos columnas, sin importar el largo de la etiqueta. */
.zram-fila {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.15rem 0.8rem;
  padding: 0.25rem 0;
  font-size: 0.78rem;
}

.zram-fila-label {
  overflow: hidden;
  color: var(--muted-foreground);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.zram-fila-valor {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Los popovers de intercambio son compactos: no necesitan estirarse. La
   doble clase gana en cascada al ancho base de .disco-popover. */
.disco-popover.swap-popover {
  width: min(20rem, calc(100vw - 2.5rem));
  max-height: 60vh;
  overflow-y: auto;
}

.disco-popover.zram-popover {
  width: min(16rem, calc(100vw - 2.5rem));
}

.vps-metric-tile {
  display: grid;
  gap: 0.4rem;
  min-width: 0;
  min-height: 8.2rem;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--card);
}

.vps-metric-tile[data-severity="warning"] .tile-reading strong {
  color: var(--warning);
}

.vps-metric-tile[data-severity="critical"] .tile-reading strong {
  color: var(--destructive);
}

.tile-label {
  color: var(--muted-foreground);
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.tile-reading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  min-width: 0;
}

.tile-reading strong {
  overflow: hidden;
  font-size: 1.7rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.vps-metric-tile small,
.ds-card-note {
  overflow: hidden;
  color: var(--muted-foreground);
  font-size: 0.7rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mini-chart {
  width: 4.2rem;
  height: 2.6rem;
  flex: none;
}

.mini-chart path {
  fill: none;
  stroke: var(--chart-2);
  stroke-width: 1.6;
  stroke-linecap: round;
}

.capacity-ring {
  --ring-value: 0;
  display: inline-block;
  width: 2.2rem;
  height: 2.2rem;
  flex: none;
  border-radius: 50%;
  background: conic-gradient(var(--primary) calc(var(--ring-value) * 1%), var(--muted) 0);
}

.capacity-ring[data-empty="true"] {
  background: var(--muted);
}

.vps-strip {
  padding: 0.9rem 1.25rem;
  border-bottom: 1px solid var(--border);
}

.strip-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.6rem;
}

.strip-heading h2 {
  margin: 0;
  font-size: 0.9rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.strip-heading p {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.74rem;
}

.activity-list-h {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(11rem, 1fr);
  align-items: start;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  overflow-x: auto;
  list-style: none;
}

.backup-chip {
  display: grid;
  gap: 0.3rem;
  min-width: 0;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}

.backup-chip[data-current="true"] {
  border-color: color-mix(in srgb, var(--ring) 65%, var(--border));
}

.backup-chip time {
  display: grid;
  gap: 0.05rem;
  font-variant-numeric: tabular-nums;
}

.backup-chip time strong {
  font-size: 0.88rem;
  font-weight: 650;
}

.backup-chip time span {
  color: var(--muted-foreground);
  font-size: 0.74rem;
}

.backup-chip small {
  color: var(--muted-foreground);
  font-size: 0.68rem;
}

.backup-badge {
  justify-self: start;
  padding: 0.1rem 0.45rem;
  border-radius: calc(var(--radius) - 2px);
  background: var(--secondary);
  color: var(--secondary-foreground);
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.activity-list-h li {
  display: grid;
  grid-template-columns: 0.55rem minmax(0, 1fr);
  gap: 0.55rem;
  align-items: start;
  min-width: 0;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}

.activity-list-h li > div {
  display: grid;
  gap: 0.1rem;
  min-width: 0;
}

.activity-list-h strong {
  overflow: hidden;
  font-size: 0.78rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.activity-list-h time {
  color: var(--muted-foreground);
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
}

.activity-marker {
  width: 0.5rem;
  height: 0.5rem;
  margin-top: 0.28rem;
  border-radius: 50%;
  background: var(--success);
}

.activity-list-h li[data-state="failed"] .activity-marker {
  background: var(--destructive);
}

.activity-list-h li[data-state="pending"] .activity-marker {
  background: var(--warning);
}

.strip-empty {
  padding: 0.65rem 0.75rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--muted-foreground);
  font-size: 0.76rem;
}

/* Error panel */

.error-panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0 1.25rem 0.9rem;
  padding: 0.8rem 1rem;
  border: 1px solid color-mix(in srgb, var(--destructive) 30%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--destructive) 4%, transparent);
}

.error-panel strong {
  font-size: 0.85rem;
}

.error-panel p {
  margin: 0.2rem 0 0;
  color: var(--muted-foreground);
  font-size: 0.78rem;
}

.error-panel button {
  min-height: 2rem;
  padding: 0.35rem 0.8rem;
  border: 1px solid var(--input);
  border-radius: calc(var(--radius) - 2px);
  background: var(--background);
  cursor: pointer;
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}

/* Headline operativo */

.operational-headline {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 1.25rem 0.9rem;
  padding: 0.7rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--muted);
}

.signal-block {
  width: 0.4rem;
  height: 2.2rem;
  flex: none;
  border-radius: 999px;
  background: var(--muted-foreground);
}

.operational-headline[data-severity="normal"] .signal-block {
  background: var(--success);
}

.operational-headline[data-severity="warning"] .signal-block {
  background: var(--warning);
}

.operational-headline[data-severity="critical"] .signal-block {
  background: var(--destructive);
}

.operational-headline h2 {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 650;
}

.operational-headline p {
  margin: 0.15rem 0 0;
  color: var(--muted-foreground);
  font-size: 0.75rem;
}

.operational-headline .freshness {
  display: grid;
  gap: 0.05rem;
  margin-left: auto;
  text-align: right;
}

.freshness span {
  color: var(--muted-foreground);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.freshness time {
  font-size: 0.76rem;
  font-weight: 600;
}

/* Detalle plegable (M02) */

.usage-detail {
  border-top: 1px solid var(--border);
}

.usage-detail > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 2.9rem;
  padding: 0.6rem 1.25rem;
  color: var(--foreground);
  cursor: pointer;
  font-size: 0.78rem;
  font-weight: 600;
  list-style-position: inside;
}

.usage-detail > summary small {
  color: var(--muted-foreground);
  font-weight: 500;
}

.section-heading h2 {
  margin: 0 0 0.15rem;
  font-size: 0.9rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.section-heading p {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.75rem;
}

.table-scroll {
  overflow-x: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
}

caption {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

thead tr {
  border-bottom: 1px solid var(--border);
}

th {
  padding: 0.55rem 0.8rem;
  color: var(--muted-foreground);
  font-size: 0.68rem;
  font-weight: 650;
  text-align: left;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

td {
  padding: 0.5rem 0.8rem;
  border-bottom: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
}

tbody tr:hover {
  background: color-mix(in srgb, var(--accent) 55%, transparent);
}

/* ─── M02 · Consumo (shadcn) ─── */

.ds-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0 1.25rem 0.9rem;
  padding: 0.55rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--muted);
  color: var(--muted-foreground);
  font-size: 0.75rem;
}

.ds-banner-close {
  border: none;
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
  font-size: 0.75rem;
  font-weight: 600;
  text-decoration: underline;
}

.ds-filter-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0 1.25rem 0.9rem;
}

.ds-select {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.1rem;
  padding: 0.2rem 0.6rem;
  border: 1px solid var(--input);
  border-radius: calc(var(--radius) - 2px);
  background: var(--background);
  box-shadow: 0 1px 2px hsl(240 5% 65% / 0.08);
}

.ds-select-label {
  color: var(--muted-foreground);
  font-size: 0.75rem;
}

.ds-select-value {
  border: none;
  background: transparent;
  color: var(--foreground);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  appearance: none;
  padding-right: 1rem;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 0.6rem) 55%, calc(100% - 0.35rem) 55%;
  background-size: 4px 4px;
  background-repeat: no-repeat;
}

.ds-filter-spacer {
  flex: 1;
}

.ds-top-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.8rem;
  padding: 0 1.25rem 0.9rem;
}

@media (min-width: 1180px) {
  /* El primer escritorio amplio ya tiene espacio para mantener la identidad
     del VPS y la actualización junto al título, incluso con el sidebar. */
  #infraestructura .board-header {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr) max-content;
    align-items: center;
    gap: clamp(0.75rem, 1.5vw, 2rem);
    flex-wrap: nowrap;
  }

  #infraestructura .board-title {
    display: flex;
    align-items: baseline;
    gap: 0.65rem;
    min-width: max-content;
    white-space: nowrap;
  }

  #infraestructura .board-title h2 {
    margin: 0;
  }

  #infraestructura .board-identity {
    flex-basis: auto;
    min-width: 0;
    margin: 0;
    overflow: visible;
    text-overflow: clip;
    white-space: nowrap;
  }

  #infraestructura .refresh-button {
    white-space: nowrap;
  }

  #infraestructura .refresh-text {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
  }

  .ds-top-cards {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (min-width: 1180px) and (max-width: 1799px) {
  #infraestructura .board-header {
    gap: 0.65rem;
    padding-inline: 0.75rem;
  }

  #infraestructura .board-title {
    gap: 0.45rem;
  }

  #infraestructura .module-eyebrow {
    font-size: 0.58rem;
    letter-spacing: 0.06em;
  }

  #infraestructura .board-title h2 {
    font-size: 1.1rem;
  }

  #infraestructura .board-identity {
    font-size: 0.72rem;
  }

  #infraestructura .refresh-button {
    padding-inline: 0.5rem;
    font-size: 0.72rem;
  }

  #infraestructura .refresh-button time {
    font-size: 0.56rem;
  }

  #infraestructura .refresh-text {
    gap: 0.25rem;
  }
}

.ds-card {
  min-width: 0;
  padding: 0.95rem 1.05rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--card);
  box-shadow: 0 1px 2px hsl(240 5% 65% / 0.08);
}

.ds-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}

.ds-card-header h3 {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 600;
}

.ds-badge {
  padding: 0.14rem 0.5rem;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--warning) 45%, transparent);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  color: var(--warning);
  font-size: 0.64rem;
  font-weight: 650;
  white-space: nowrap;
}

.ds-card-value {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  margin-top: 0.7rem;
}

.ds-card-value strong {
  overflow: hidden;
  font-size: 1.9rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.ds-card-unit {
  color: var(--muted-foreground);
  font-size: 0.8rem;
  font-weight: 550;
}

/* Métricas del rango: cuarta tarjeta del consumo, apiladas en vertical para
   ganar altura y que la gráfica quede a la vista de inmediato. */
.ds-metrics-stack {
  display: grid;
  gap: 0.4rem;
  margin: 0.7rem 0 0;
}

.ds-metrics-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem;
  min-width: 0;
}

.ds-metrics-row dt {
  color: var(--muted-foreground);
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1.3;
}

.ds-metrics-row dd {
  margin: 0;
  overflow: hidden;
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.ds-chart-card {
  margin: 0 1.25rem 0.9rem;
  padding: 0.95rem 1.05rem 0.8rem;
}

.ds-chart-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.ds-chart-header h3 {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 600;
}

.ds-chart-header h3 span {
  color: var(--muted-foreground);
  font-weight: 500;
}

.ds-toggle {
  display: inline-flex;
  gap: 0.15rem;
  padding: 0.2rem;
  border-radius: calc(var(--radius) - 2px);
  background: var(--muted);
}

.ds-toggle-option {
  min-height: 1.7rem;
  padding: 0.2rem 0.7rem;
  border: none;
  border-radius: calc(var(--radius) - 3px);
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
  font-size: 0.75rem;
  font-weight: 600;
}

.ds-toggle-option.is-active {
  background: var(--background);
  color: var(--foreground);
  box-shadow: 0 1px 2px hsl(240 5% 65% / 0.18);
}

.ds-chart-area {
  position: relative;
}

.usage-bar-chart {
  display: block;
  width: 100%;
  /* Alto único (tope) e igual al alto del viewBox dinámico: el SVG se dibuja
     1:1 sin estiramiento del texto de los ejes en ningún ancho. */
  height: 260px;
}

.usage-bar-chart text {
  fill: var(--muted-foreground);
  font-size: 12px;
  font-weight: 500;
}

.usage-chart-empty {
  fill: var(--muted-foreground);
  font-size: 13px;
  font-weight: 600;
}

.ds-tooltip {
  position: absolute;
  z-index: 4;
  min-width: 13rem;
  max-width: 15rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--popover);
  color: var(--popover-foreground);
  box-shadow: 0 4px 12px hsl(240 5% 45% / 0.18);
  pointer-events: none;
}

.ds-tooltip-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.35rem;
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--border);
}

.ds-tooltip-header strong {
  font-size: 0.76rem;
  font-weight: 700;
}

.ds-tooltip-header span {
  font-size: 0.76rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.ds-tooltip-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.45rem;
  padding: 0.12rem 0;
  font-size: 0.7rem;
}

.ds-tooltip-swatch {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 2px;
}

.ds-tooltip-row span:last-child {
  font-variant-numeric: tabular-nums;
}

.usage-ledger-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 0.8rem;
  padding: 0.9rem 1.25rem;
}

.usage-table-panel {
  min-width: 0;
  padding: 0.9rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
}

.usage-table-panel .section-heading h2 {
  font-size: 0.82rem;
}

.usage-table-panel .section-heading p {
  font-size: 0.7rem;
}

/* ─── Footer ─── */

footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-inline: auto;
  width: calc(100% - clamp(1rem, 2vw, 3rem));
  max-width: none;
  padding: 1rem 0 1.5rem;
  border-top: 1px solid var(--border);
  color: var(--muted-foreground);
  font-size: 0.72rem;
}

footer p {
  margin: 0;
}

.footer-link {
  color: var(--foreground);
  font-weight: 550;
}

/* ─── Responsive ─── */

@media (max-width: 720px) {
  .masthead {
    padding: 0.5rem 0.9rem;
    flex-wrap: wrap;
    row-gap: 0.3rem;
    justify-content: flex-start;
  }

  .btn-outline,
  .ds-button,
  .error-panel button {
    min-height: 44px;
  }

  .clock-block {
    display: none;
  }

  .tema-toggle {
    width: 2.5rem;
    height: 2.5rem;
  }

  /* En móvil los cuatro módulos aparecen como iconos junto a la hamburguesa,
     sin crecer la altura del masthead: una sola fila compacta. */
  .masthead-nav {
    display: flex;
    gap: 0.35rem;
  }

  .masthead-link {
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    flex: none;
    border-radius: var(--radius);
    color: var(--muted-foreground);
    text-decoration: none;
  }

  .masthead-link:hover {
    background: var(--accent);
    color: var(--accent-foreground);
  }

  .masthead-link[aria-current="page"] {
    background: var(--accent);
    color: var(--foreground);
  }

  /* El botón Actualizar sube a la esquina superior derecha del módulo: el
     header se rejilla en dos columnas (título | botón) y la última lectura
     queda integrada en el propio botón. En el M01 la identidad del servidor
     ocupa su propia fila completa, en una sola línea. */
  .board-header,
  .ds-header {
    align-items: start;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "title refresh";
  }

  .board-header {
    grid-template-areas:
      "title refresh"
      "identity identity";
  }

  /* M01 conserva módulo y VPS en la misma línea; el estado remoto vive en
     la segunda, así no convierte la cabecera en tres bloques en móvil. */
  #infraestructura .board-title {
    display: flex;
    align-items: baseline;
    gap: 0.35rem;
    white-space: nowrap;
  }

  #infraestructura .board-header {
    grid-template-areas:
      "title title"
      "identity refresh";
  }

  #infraestructura .board-title h2 {
    margin: 0;
    font-size: 1rem;
    white-space: nowrap;
  }

  #infraestructura .module-eyebrow {
    flex: none;
    font-size: 0.58rem;
    letter-spacing: 0.05em;
  }

  /* El mismo estado aparece completo en .board-identity; no lo repetimos
     dentro del botón deshabilitado, donde forzaría una tercera línea. */
  #infraestructura #freshness-time {
    display: none;
  }

  #infraestructura .refresh-button {
    width: 2.5rem;
    min-width: 2.5rem;
    padding-inline: 0;
    justify-content: center;
  }

  #infraestructura .refresh-text {
    display: none;
  }

  .board-identity {
    grid-area: identity;
    min-width: 0;
    font-size: 0.72rem;
  }

  .board-title,
  .ds-header-title {
    grid-area: title;
    min-width: 0;
  }

  .refresh-button {
    grid-area: refresh;
    justify-self: end;
    align-self: start;
  }

  .activity-list-h {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    overflow-x: hidden;
  }

  .ds-card-value {
    flex-wrap: wrap;
  }

  .ds-card-value strong {
    overflow: visible;
    font-size: 1.45rem;
    text-overflow: clip;
    white-space: normal;
  }

  .ds-card-header {
    flex-wrap: wrap;
    gap: 0.35rem;
  }

  .ds-badge {
    white-space: normal;
  }

  /* La franja del servidor ya es flex con wrap: en móvil la identidad, los
     hechos (Servidor, IPv4) y el plan fluyen en una línea compacta. */

  .vps-metric-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
  }

  /* Swap y ZRAM comparten UNA sola fila en móvil, con el mismo tamaño de los
     tiles de recursos (CPU, memoria, disco): el bloque conserva su estructura. */
  .swap-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
  }

  .swap-strip .vps-metric-tile {
    min-height: 8.2rem;
  }

  .vps-server-facts,
  .ds-top-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* La franja de cuatro tarjetas del consumo se compacta en móvil para que la
     gráfica quede a la vista sin desplazarse. */
  .ds-top-cards {
    gap: 0.6rem;
    padding-bottom: 0.7rem;
  }

  .ds-card {
    padding: 0.7rem 0.8rem;
  }

  .ds-card-value {
    margin-top: 0.45rem;
  }

  .ds-metrics-row dd {
    font-size: 1rem;
  }

  .vps-metric-tile {
    padding: 0.6rem 0.55rem;
  }

  .mini-chart {
    height: 30px;
  }

  .strip-heading {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.2rem;
  }

  /* Rango y API Key conviven en una sola línea aunque la opción elegida sea
     larga (p. ej. "Histórico total"): cada selector cede al 50%, la etiqueta
     se apila encima para darle todo el ancho del grupo al <select> y así el
     texto elegido cabe completo sin recortarse. */
  .ds-filter-row {
    flex-wrap: nowrap;
    gap: 0.4rem;
  }

  .ds-select {
    flex: 1 1 0;
    min-width: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0.15rem;
    padding: 0.3rem 0.5rem;
  }

  .ds-select-label {
    white-space: nowrap;
  }

  .ds-select-value {
    width: 100%;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* El botón Actualizar del consumo replica al M01: icono, etiqueta y hora de
     la lectura apilados, sin ocultar nada en pantallas angostas. */

  /* Shell iOS móvil: sin sidebar ni hamburguesa. Navegación = tab bar +
     «Ver todos» hacia Movimientos. El sidebar queda solo en desktop. */
  .app-frame {
    margin-left: 0;
  }

  .sidebar-burger,
  .app-sidebar,
  .sidebar-backdrop {
    display: none !important;
  }

  body.sidebar-open {
    overflow: auto;
  }

  .shell-ios #contenido,
  .shell-ios .dashboard-canvas {
    padding-left: max(0.85rem, env(safe-area-inset-left, 0px));
    padding-right: max(0.85rem, env(safe-area-inset-right, 0px));
  }

  .shell-ios .finanzas-header {
    padding-top: calc(0.55rem + env(safe-area-inset-top, 0px));
  }

  .shell-ios .finanzas-module {
    border: none;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }

  /* La franja de avisos muestra dos tarjetas a la vez en móvil. */
  .notice-item {
    width: calc(50vw - 22px);
  }
}

/* El costo por día vive ahora en el tooltip y en la card de costo; la línea
   punteada que cruzaba las barras se eliminó del gráfico. */

.ds-legend-cost {
  margin-left: auto;
  color: var(--muted-foreground);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}

.ds-tooltip-cost {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
  color: var(--muted-foreground);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  * {
    scroll-behavior: auto !important;
    transition: none !important;
  }

  .notice-flow {
    animation: none;
  }
}

/* ── Avisos operativos (franja corrida al final) ──────────────────────── */

.notice-bar {
  border-top: 1px solid var(--border);
  background: var(--card);
  display: flex;
  align-items: stretch;
}

/* Contenedor que recorta la pista y desvanece los bordes. */
.notice-marquee {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 3%, #000 97%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 3%, #000 97%, transparent);
}

/* Botón de recarga discreto, anclado al extremo derecho de la franja. */
.notice-reload {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.4rem;
  border: none;
  border-left: 1px solid var(--border);
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
}

.notice-reload:hover {
  color: var(--foreground);
}

.notice-reload:disabled {
  opacity: 0.4;
  pointer-events: none;
}

/* La pista corre de izquierda a derecha en bucle: dos copias idénticas y un
   desplazamiento de -50% ↔ 0 hacen el salto invisible. */
.notice-flow {
  display: flex;
  width: max-content;
  animation: notice-slide 38s linear infinite;
}

.notice-marquee:hover .notice-flow {
  animation-play-state: paused;
}

@keyframes notice-slide {
  from { transform: translateX(-50%); }
  to { transform: translateX(0); }
}

.notice-track {
  list-style: none;
  display: flex;
  gap: 10px;
  margin: 0;
  padding: 8px 16px;
}

.notice-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 24rem;
  max-width: calc(100vw - 32px);
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) - 2px);
  background: var(--background);
}

.notice-head {
  display: flex;
  align-items: center;
  gap: 7px;
}

.notice-head strong {
  color: var(--foreground);
  font-size: 12.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.notice-body {
  color: var(--muted-foreground);
  font-size: 12px;
  line-height: 1.45;
}

.notice-date {
  color: var(--muted-foreground);
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  opacity: 0.85;
}

.notice-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 9999px;
  background: var(--muted-foreground);
}

.notice-dot.ok { background: hsl(142 76% 36%); }
.notice-dot.warning { background: hsl(25 95% 53%); }
.notice-dot.info { background: hsl(217 91% 60%); }

/* ── Gráfica de consumo refinada ──────────────────────────────────────── */

.usage-bar-chart {
  transition: opacity 160ms ease;
}

.usage-bar-chart.is-switching {
  opacity: 0.35;
}

.usage-bar-seg {
  transform-box: fill-box;
  transform-origin: center bottom;
  transition: opacity 140ms ease, filter 140ms ease, transform 320ms ease;
}

.usage-bar-chart.is-ready .usage-bar-seg {
  animation: usage-bar-rise 420ms ease both;
}

@keyframes usage-bar-rise {
  from {
    transform: scaleY(0.08);
    opacity: 0;
  }
  to {
    transform: scaleY(1);
    opacity: 1;
  }
}

.usage-bar-seg.is-hot {
  filter: brightness(1.22);
}

.usage-bar-seg.is-dimmed {
  opacity: 0.22;
}

.ds-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 10px;
}

.ds-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 32px;
  padding: 2px 8px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  background: transparent;
  color: var(--muted-foreground);
  font-size: 12.5px;
  cursor: pointer;
}

.ds-legend-item:hover {
  border-color: var(--border);
}

.ds-legend-item.is-focused {
  border-color: var(--foreground);
  color: var(--foreground);
}

.ds-legend-item:focus-visible {
  outline: 2px solid var(--foreground);
  outline-offset: 2px;
}

.ds-legend-swatch {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 2px;
}

.ds-legend-total {
  color: var(--foreground);
  font-weight: 600;
}

/* La cabecera M02 mantiene título y acción en una fila compacta. */
.usage-module .ds-header {
  align-items: center;
  gap: 0.5rem;
  flex-wrap: nowrap;
}

.usage-module .ds-header-title {
  min-width: 0;
  flex: 1 1 auto;
}

.usage-module #usage-title {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  letter-spacing: 0.04em;
  font-size: 0.62rem;
}

.usage-module .refresh-button {
  flex: 0 0 auto;
  min-height: 44px;
  white-space: nowrap;
  gap: 0.25rem;
  padding-inline: 0.35rem;
  font-size: 0.7rem;
}

.usage-module .refresh-text {
  gap: 0;
}

.usage-module .refresh-button time {
  font-size: 0.5rem;
}

/* ── Vista única: los módulos conviven en una sola página ──────────────── */

@media (prefers-reduced-motion: reduce) {
  .usage-bar-chart.is-ready .usage-bar-seg {
    animation: none;
  }

  .usage-bar-seg,
  .usage-bar-chart {
    transition: none;
  }
}

@media (max-width: 720px) {
  .ds-legend-item {
    font-size: 12px;
  }
}



/* ─── M03 · Salud ─── */

.salud-module {
  padding-bottom: 0.5rem;
}

/* Identidad del paciente en la cabecera del módulo (todos los anchos), a la
   derecha de «M03 · Salud»; en ultrawide recibe además la lectura clínica. */
.salud-header-datos {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex: 1 1 auto;
  min-width: 0;
}

.salud-header-identidad {
  min-width: 0;
}

/* El encabezado «M03 · Salud» nunca se parte en dos líneas. */
.salud-module .ds-header-title h2 {
  white-space: nowrap;
}

/* Tarjeta del paciente: la lectura clínica resumida y las métricas de
   seguimiento; la identidad vive en la cabecera del módulo. */
.salud-paciente {
  min-width: 0;
  margin: 0.9rem 1.25rem 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--card);
  color: var(--card-foreground);
}

.salud-paciente-identidad {
  display: flex;
  align-items: baseline;
  gap: 0.25rem;
  min-width: 0;
}

.salud-paciente-nombre {
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.salud-paciente-detalles {
  color: var(--muted-foreground);
  font-size: 0.78rem;
  white-space: nowrap;
}

.salud-paciente-detalles::before {
  content: '· ';
}

.salud-section {
  min-width: 0;
}

/* La lectura clínica vive dentro de la tarjeta del paciente. */
.salud-resumen {
  padding: 0.75rem 0.9rem 0.9rem;
}

.salud-resumen-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 2.75rem;
  margin: -0.35rem -0.45rem 0.1rem 0;
}

.salud-resumen-cabecera > h3 {
  margin: 0;
}

.salud-resumen-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 2.75rem;
  width: 2.75rem;
  min-height: 2.75rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
}

.salud-resumen-toggle:hover {
  color: var(--foreground);
}

.salud-resumen-toggle:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: -2px;
}

.salud-resumen-toggle[aria-expanded="true"] .salud-chevron {
  transform: rotate(90deg);
}

.salud-resumen > p {
  margin: 0;
  font-size: 0.84rem;
  line-height: 1.55;
}

/* Rejilla inferior: exámenes a la izquierda y hormonas a la derecha. En
   tarjetas angostas colapsa a una sola columna. */
.salud-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-areas:
    'tandas hormonas';
  gap: 0.75rem;
  align-items: start;
  padding: 0.9rem 1.25rem 1.25rem;
}

.salud-tandas-col {
  grid-area: tandas;
}

.salud-hormonas-col {
  grid-area: hormonas;
}

.salud-section > h3 {
  margin: 0 0 0.6rem;
  color: var(--muted-foreground);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

#salud-resumen-texto {
  margin: 0;
  padding: 0;
  color: var(--card-foreground);
  font-size: 0.84rem;
  line-height: 1.55;
}

.salud-tanda {
  margin-bottom: 0.9rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--card);
  overflow: hidden;
}

.salud-tanda:last-child {
  margin-bottom: 0;
}

.salud-tanda-cabecera {
  margin: 0;
  border-bottom: 1px solid var(--border);
  background: var(--secondary);
}

.salud-tanda-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  padding: 0.7rem 0.9rem;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.salud-tanda-toggle:hover {
  background: color-mix(in srgb, var(--foreground) 4%, transparent);
}

.salud-tanda-toggle:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: -2px;
}

.salud-tanda-rotulo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  min-width: 0;
}

.salud-tanda-titulo {
  font-size: 0.88rem;
  font-weight: 700;
}

.salud-tanda-meta {
  flex: 0 0 auto;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
}

.salud-chevron {
  flex: 0 0 auto;
  color: var(--muted-foreground);
  transition: transform 0.18s ease;
}

.salud-tanda-toggle.is-open .salud-chevron {
  transform: rotate(90deg);
}

.salud-tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}

.salud-tabla th {
  padding: 0.45rem 0.9rem;
  border-bottom: 1px solid var(--border);
  color: var(--muted-foreground);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-align: left;
  text-transform: uppercase;
}

.salud-tabla th:last-child,
.salud-tabla td:last-child {
  text-align: center;
}

.salud-tabla td {
  padding: 0.38rem 0.9rem;
  vertical-align: top;
}

.salud-tabla tr + tr td {
  border-top: 1px solid var(--border);
}

.salud-parametro {
  font-weight: 600;
  color: var(--card-foreground);
}

.salud-valor {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.salud-rango {
  color: var(--muted-foreground);
  font-size: 0.76rem;
  font-variant-numeric: tabular-nums;
}

/* Gauge de rango de referencia (M03): línea con tramo naranja del rango
   normal y punto en la posición de la medición. Vive dentro de la celda
   "Rango de referencia" y conserva la altura de una línea de texto. */
.salud-rango-gauge {
  min-width: 7rem;
  max-width: 14rem;
  width: 100%;
  font-variant-numeric: tabular-nums;
}

.salud-rango-gauge-linea {
  position: relative;
  height: 6px;
  margin-top: 2px;
  border-radius: 999px;
  background: var(--salud-gauge-linea);
}

.salud-rango-gauge-segmento {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 999px;
  background: var(--salud-rango-normal);
}

.salud-rango-gauge-punto {
  position: absolute;
  top: 50%;
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: var(--salud-gauge-punto);
  box-shadow: 0 0 0 2px var(--card);
  transform: translate(-50%, -50%);
}

.salud-rango-gauge-escala {
  display: flex;
  justify-content: space-between;
  gap: 0.4rem;
  margin-top: 3px;
  font-size: 0.62rem;
  line-height: 1.2;
  color: var(--muted-foreground);
}

.salud-rango-gauge-max {
  text-align: right;
}

/* Entrada animada del gauge al abrir la tanda: la línea se dibuja de
   izquierda a derecha, el tramo naranja crece sobre ella y el punto se
   desliza desde el origen hasta la posición de la medición. */
@keyframes salud-gauge-linea {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@keyframes salud-gauge-segmento {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@keyframes salud-gauge-punto {
  from { left: 0%; opacity: 0; transform: translate(-50%, -50%) scale(0.3); }
  to { left: var(--gauge-punto, 0%); opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

@keyframes salud-gauge-escala {
  from { opacity: 0; }
  to { opacity: 1; }
}

.salud-rango-gauge-linea {
  animation: salud-gauge-linea 550ms cubic-bezier(0.22, 1, 0.36, 1) both;
  transform-origin: left center;
}

.salud-rango-gauge-segmento {
  animation: salud-gauge-segmento 650ms cubic-bezier(0.22, 1, 0.36, 1) 120ms both;
  transform-origin: left center;
}

.salud-rango-gauge-punto {
  animation: salud-gauge-punto 700ms cubic-bezier(0.34, 1.56, 0.64, 1) 400ms both;
}

.salud-rango-gauge-escala {
  animation: salud-gauge-escala 350ms ease-out 550ms both;
}

.salud-rango-gauge-anot {
  display: inline-block;
  margin-left: 0.3rem;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .salud-rango-gauge-punto {
    transition: none;
  }
}

.salud-estado {
  width: 4.5rem;
}

.salud-nota-row td {
  padding-top: 0.2rem;
  color: var(--muted-foreground);
  font-size: 0.74rem;
  line-height: 1.45;
}

.salud-grupo-row td {
  padding: 0.55rem 0.9rem 0.3rem;
  background: var(--secondary);
  color: var(--muted-foreground);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.salud-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.9rem;
  padding: 0.12rem 0.45rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--secondary);
  font-size: 0.74rem;
  line-height: 1.4;
  animation: salud-chip-aparece 320ms ease-out both;
}

/* Iconos de estado SVG: trazo estilo lucide con entrada sutil. */
@keyframes salud-chip-aparece {
  from { opacity: 0; transform: scale(0.65); }
  to { opacity: 1; transform: scale(1); }
}

@keyframes salud-icono-trazo {
  to { stroke-dashoffset: 0; }
}

.salud-chip svg {
  width: 0.85rem;
  height: 0.85rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

.salud-chip .salud-icono-trazo {
  stroke-dasharray: 10;
  stroke-dashoffset: 10;
  animation: salud-icono-trazo 480ms ease-out 280ms forwards;
}

.salud-chip[data-estado="ok"] {
  border-color: color-mix(in srgb, var(--success) 35%, transparent);
  background: color-mix(in srgb, var(--success) 10%, transparent);
}

.salud-chip[data-estado="warn"] {
  border-color: color-mix(in srgb, var(--warning) 45%, transparent);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
}

.salud-chip[data-estado="info"] {
  border-color: color-mix(in srgb, var(--chart-2) 35%, transparent);
  background: color-mix(in srgb, var(--chart-2) 10%, transparent);
}

.salud-chip[data-estado="pendiente"] {
  border-color: var(--border);
  background: var(--secondary);
}

.salud-hormonas-pendiente {
  display: grid;
  gap: 0.7rem;
  padding: 0.9rem;
  border: 1px dashed var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--card);
}

.salud-hormonas-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.salud-hormonas-cabecera strong {
  font-size: 0.92rem;
}

.salud-hormonas-nota {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.8rem;
  line-height: 1.5;
}

.salud-chip-lista {
  display: grid;
  gap: 0.4rem;
}

.salud-chip-lista-etiqueta {
  color: var(--muted-foreground);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.salud-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.salud-chip-neutral {
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--secondary);
  color: var(--secondary-foreground);
  font-size: 0.74rem;
  font-weight: 600;
}

.salud-pendiente-nota {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.76rem;
}

/* Panel hormonal con valores: unidad y fecha llevan su propia columna. */
.salud-unidad {
  color: var(--muted-foreground);
  font-size: 0.76rem;
  font-variant-numeric: tabular-nums;
}

.salud-fecha {
  color: var(--muted-foreground);
  font-size: 0.74rem;
  white-space: nowrap;
}

.salud-hormonas-pie {
  margin: 0;
  padding: 0.7rem 0.9rem;
  border-top: 1px solid var(--border);
  color: var(--muted-foreground);
  font-size: 0.76rem;
  line-height: 1.5;
}

/* Métricas de seguimiento: una sola fila horizontal dentro de la tarjeta
   del paciente, con desplazamiento propio si el ancho no alcanza. */
.salud-metricas-fila {
  padding: 0.75rem 0.9rem 0.9rem;
  border-top: 1px solid var(--border);
}

.salud-metricas-fila > h3 {
  margin: 0 0 0.6rem;
  color: var(--muted-foreground);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.salud-metricas-grid {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(8rem, 1fr);
  gap: 0.45rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.salud-metrica {
  display: grid;
  gap: 0.2rem;
  align-content: start;
  min-width: 0;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--card);
}

.salud-metrica-etiqueta {
  color: var(--muted-foreground);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.salud-metrica-valor {
  font-size: 0.86rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.salud-metrica-detalle {
  color: var(--muted-foreground);
  font-size: 0.64rem;
  line-height: 1.35;
}

.salud-metricas-contexto {
  margin: 0.8rem 0 0;
  color: var(--muted-foreground);
  font-size: 0.78rem;
  line-height: 1.5;
}

/* ─── M03 · Salud — densidad ultrawide (≥1800px) ───
   La vista aprovecha todo el ancho de la pantalla: el título grande y su
   descripción se compactan, la identidad con la lectura clínica suben a la
   derecha de la cabecera y los tres exámenes de sangre se ven en simultáneo
   junto al panel hormonal, cada uno en su propia columna. */

@media (min-width: 1800px) {
  /* La vista de salud no se acota al ancho legible: usa todo el largo. */
  #vista-salud {
    max-width: none;
  }

  /* Identidad + lectura clínica a la derecha de la cabecera. */
  .salud-header-datos {
    display: grid;
    grid-template-columns: minmax(10rem, auto) minmax(22rem, 1fr);
    gap: 0 1.25rem;
    align-items: center;
    flex: 1 1 auto;
    min-width: 0;
    max-width: 64rem;
    margin-left: auto;
  }

  .salud-header-identidad {
    min-width: 0;
  }

  .salud-header-identidad .salud-paciente-identidad {
    display: flex;
    align-items: baseline;
    gap: 0.3rem;
    min-width: 0;
  }

  .salud-header-identidad .salud-paciente-nombre {
    font-size: 0.92rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    white-space: nowrap;
  }

  .salud-header-identidad .salud-paciente-detalles {
    color: var(--muted-foreground);
    font-size: 0.78rem;
    white-space: nowrap;
  }

  .salud-header-resumen .salud-resumen-cabecera {
    margin: 0;
  }

  .salud-header-resumen .salud-resumen-toggle {
    min-height: 2.75rem;
  }

  .salud-header-resumen p {
    margin: 0;
    font-size: 0.8rem;
    line-height: 1.45;
  }

  /* La tarjeta del paciente conserva las métricas; la lectura clínica sube a
     la cabecera en ultrawide (la identidad ya vive allí en todos los anchos). */
  .salud-paciente #salud-resumen-slot {
    display: none;
  }

  /* Cinco columnas simultáneas: cuatro exámenes y el panel hormonal. */
  .salud-grid {
    grid-template-columns: repeat(5, minmax(0, 1fr));
    grid-template-areas: 'tandas tandas tandas tandas hormonas';
  }

  #salud-tandas {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.75rem;
    align-items: start;
  }

  .salud-tandas-col .salud-tanda {
    margin-bottom: 0;
  }
}

@media (min-width: 1800px) {
  /* M01 · Infraestructura en ultrawide: la cabecera del módulo ocupa la fila
     completa y, debajo, el bloque de recursos (tiles de CPU/memoria/disco/red/
     ancho de banda + franjas de swap/zram y actividad reciente) se limita a la
     mitad izquierda mientras el mapa de puertos ocupa la mitad derecha, en la
     misma fila, para verlo todo a la vez sin desplazarse. El DOM no cambia de
     orden: el rejilla reparte visualmente las secciones por área. */
  #vista-infraestructura {
    max-width: none;
  }

  #infraestructura {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      'cabecera  cabecera'
      'overview  puertos'
      'swap      puertos'
      'actividad puertos'
      'historico historico';
  }

  #infraestructura .board-header {
    grid-area: cabecera;
  }

  #infraestructura .vps-overview {
    grid-area: overview;
    min-width: 0;
  }

  #infraestructura .swap-strip {
    grid-area: swap;
    min-width: 0;
  }

  #infraestructura .activity-strip {
    grid-area: actividad;
    min-width: 0;
  }

  #infraestructura .puertos-strip {
    grid-area: puertos;
    min-width: 0;
    border-left: 1px solid var(--border);
  }

  #infraestructura .historico-panel {
    grid-area: historico;
  }
}

@media (max-width: 720px) {
  .salud-tabla {
    font-size: 0.72rem;
  }

  .salud-tabla th,
  .salud-tabla td {
    padding-left: 0.55rem;
    padding-right: 0.55rem;
  }

  .salud-rango {
    font-size: 0.68rem;
  }

  /* Las métricas dejan la fila deslizable y se reparten en dos columnas
     compactas: las ocho caben de una sola vista, sin deslizar. */
  .salud-metricas-grid {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.4rem;
    overflow-x: visible;
  }

  .salud-metrica {
    padding: 0.4rem 0.5rem;
  }

  .salud-rango-gauge {
    min-width: 5rem;
  }

  .salud-estado {
    width: 3.4rem;
  }

  /* Densidad del encabezado de Salud en móvil: título compacto en una sola
     línea y la identidad del paciente legible a su derecha. */
  #salud .ds-header-title h2 {
    font-size: 0.7rem;
  }

  .salud-paciente-nombre {
    font-size: 0.76rem;
  }

  .salud-paciente-detalles {
    font-size: 0.7rem;
  }
}

/* ─── M04 · Finanzas personales ─── */

.finanzas-top-cards {
  padding: 0 1.25rem 0.9rem;
}

.finanzas-card .ds-card-value strong {
  font-size: clamp(1.25rem, 2vw, 1.6rem);
}

.finanzas-form {
  padding: 0.25rem 1.25rem 1rem;
}

.finanzas-form > h3,
.finanzas-recientes > h3 {
  margin: 0.9rem 0 0.6rem;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.finanzas-fields {
  display: grid;
  grid-template-columns: minmax(8.5rem, 0.9fr) minmax(0, 1.5fr) minmax(0, 1.1fr) minmax(8.5rem, 0.9fr);
  gap: 0.6rem;
}

.finanzas-field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.finanzas-field-label {
  color: var(--muted-foreground);
  font-size: 0.68rem;
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.finanzas-field input,
.finanzas-field select {
  width: 100%;
  min-height: 44px;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  font-size: 0.88rem;
}

.finanzas-field input::placeholder {
  color: var(--muted-foreground);
}

.finanzas-field input:focus-visible,
.finanzas-field select:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

/* Ronda 6 (t_0ca41d80): un solo alto para todos los campos de la captura —los
   44 px del mínimo táctil—: la fecha y el concepto dejan sus 30 px y suben al
   alto de la moneda y del monto. La fecha sigue siendo el selector nativo
   (type=date: el toque abre el calendario del sistema) y conserva su relleno
   lateral; en pantallas de 390 (≤ 420 px) se recorta al mínimo para que el
   valor dd/mm/aaaa —92.22 px de texto a 16 px— entre sin truncarse. */
#finanzas-fecha {
  min-height: 44px;
  padding: 0.1rem 0.35rem;
}

/* El concepto conserva su letra (16px en táctil, el umbral anti-autozoom de
   iOS) y su relleno lateral; el rótulo que lo envuelve mantiene el área
   táctil. */
#finanzas-concepto {
  min-height: 44px;
  padding: 0.1rem 0.65rem;
}

.finanzas-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.75rem;
}

.finanzas-form-status {
  margin: 0;
  min-height: 1.2em;
  font-size: 0.8rem;
}

.finanzas-form-status.is-ok {
  color: var(--success);
}

.finanzas-form-status.is-error {
  color: var(--destructive);
}

.finanzas-recientes {
  padding: 0 1.25rem 1.1rem;
}

.finanzas-lista {
  display: grid;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.finanzas-fila {
  display: grid;
  grid-template-columns: 5.6rem minmax(0, 1fr) auto auto auto;
  gap: 0.6rem;
  align-items: center;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 0.84rem;
}

.finanzas-fila time {
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}

.finanzas-fila .finanzas-concepto {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Alta rápida de categorías: el + vive en la fila del select y el editor
   ocupa la misma celda sin estirar la fila del formulario. */
.finanzas-categoria-campo {
  min-width: 0;
}

/* El guardar del formulario se pinta según el tipo de registro: rojo de
   gasto, verde de ingreso (gana en cascada a los estilos base del botón). */
.finanzas-boton-gasto {
  background: var(--destructive);
  border-color: var(--destructive);
  color: var(--destructive-foreground);
}

.finanzas-boton-ingreso {
  background: var(--success);
  border-color: var(--success);
  color: var(--success-foreground);
}

/* Gastos fijos: fila con icono, estado del mes y acciones compactas. */
.finanzas-fijos-header-datos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}

.finanzas-fijo-mostrar {
  min-height: 34px;
}

.finanzas-fijo-form {
  margin: 0 0 1rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}

.finanzas-fijo-form-title {
  margin: 0 0 0.7rem;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.finanzas-fijo-fields {
  grid-template-columns: minmax(0, 1.6fr) minmax(7.5rem, 0.7fr) minmax(0, 1fr) minmax(8.5rem, 0.9fr);
}

.finanzas-fija-fila {
  grid-template-columns: minmax(0, 1fr) auto auto auto auto;
}

.finanzas-fija-fila .finanzas-concepto {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.finanzas-fija-fila .finanzas-concepto svg {
  flex: none;
  color: var(--muted-foreground);
}

.finanzas-fija-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.finanzas-fijo-estado {
  justify-self: end;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 650;
  white-space: nowrap;
}

.finanzas-fijo-estado.es-pagado {
  background: var(--success);
  color: var(--success-foreground);
}

.finanzas-fijo-estado.es-pendiente {
  background: var(--secondary);
  color: var(--muted-foreground);
}

.finanzas-fijo-acciones {
  display: inline-flex;
  gap: 0.3rem;
  justify-self: end;
}

.finanzas-fijo-accion {
  min-height: 30px;
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
  font: inherit;
  font-size: 0.72rem;
  font-weight: 650;
  white-space: nowrap;
}

.finanzas-fijo-accion:hover {
  border-color: var(--ring);
  color: var(--foreground);
}

.finanzas-fijo-accion.es-pagar {
  border-color: var(--success);
  color: var(--success);
}

.finanzas-fijo-accion.es-eliminar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  min-height: 2.75rem;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--foreground);
}

.finanzas-fijo-accion.es-eliminar svg {
  display: block;
  width: 2rem;
  height: 2rem;
}

.finanzas-fijo-accion.es-eliminar:hover {
  border-color: var(--destructive);
  color: var(--destructive);
}

.finanzas-fijos-totales {
  display: grid;
  gap: 0.35rem;
  margin-top: 0.7rem;
}

.finanzas-fijos-mes {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.25rem 0.65rem;
  font-size: 0.84rem;
}

.finanzas-fijos-mes strong {
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.finanzas-fijos-mes:has(#finanzas-fijos-pagado) strong {
  color: var(--success);
}

/* Chips de categoría con icono. */
.finanzas-categoria-chip,
.finanzas-categorias-nombre {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

/* Selector de iconos en Configuración. */
.finanzas-categoria-icono-boton {
  min-height: 30px;
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
  font: inherit;
  font-size: 0.72rem;
  font-weight: 650;
}

.finanzas-categoria-icono-boton:hover {
  border-color: var(--ring);
  color: var(--foreground);
}

.finanzas-icono-catalogo {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(2.4rem, 1fr));
  gap: 0.3rem;
  margin: 0.3rem 0 0.6rem;
  padding: 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}

.finanzas-icono-item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.4rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
}

.finanzas-icono-item:hover {
  border-color: var(--ring);
  color: var(--foreground);
}

.finanzas-icono-item.es-actual {
  border-color: var(--primary);
  background: var(--secondary);
  color: var(--primary);
}

.finanzas-categoria-select-fila {
  display: flex;
  align-items: stretch;
  gap: 0.4rem;
}

.finanzas-categoria-select-fila select {
  flex: 1;
  min-width: 0;
}

.finanzas-categoria-mas {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  min-height: 44px;
  border: 1px solid var(--primary);
  border-radius: var(--radius);
  background: var(--secondary);
  color: var(--primary);
  cursor: pointer;
}

.finanzas-categoria-mas:hover {
  background: var(--primary);
  color: var(--primary-foreground);
}

.finanzas-categoria-rapida {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.finanzas-categoria-rapida-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

.finanzas-categoria-rapida input {
  flex: 1 1 7.5rem;
  min-width: 0;
  min-height: 44px;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  font-size: 0.88rem;
}

.finanzas-categoria-rapida input:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

.finanzas-categoria-rapida-acciones {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.finanzas-categoria-rapida-acciones .ds-button,
.finanzas-categoria-rapida-acciones .finanzas-boton-ghost {
  min-height: 38px;
}

.finanzas-categoria-rapida-status {
  flex-basis: 100%;
  min-height: 1em;
}

.finanzas-categoria-chip {
  justify-self: start;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  /* Tono característico por categoría (SPEC 006 · iteración): el JS fija
     --cat-hue; sin él, el fallback queda en un azul neutro legible. */
  background: hsl(var(--cat-hue, 240) 72% 93%);
  color: hsl(var(--cat-hue, 240) 45% 28%);
  border: 1px solid hsl(var(--cat-hue, 240) 55% 84%);
  font-size: 0.66rem;
  font-weight: 600;
  white-space: nowrap;
}

.finanzas-monto {
  justify-self: end;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.finanzas-fijos {
  padding: 1rem 1.25rem 1.1rem;
}

.finanzas-fijos-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.3rem;
}

.finanzas-fijos-note {
  margin: 0 0 0.7rem;
  color: var(--muted-foreground);
  font-size: 0.76rem;
}

.finanzas-fijos-caption {
  margin: 0 0 0.6rem;
  color: var(--muted-foreground);
  font-size: 0.78rem;
  font-weight: 600;
}

/* Cabecera de fijos: «Importar gastos fijos de <mes>» (primero) en línea con
   «＋ Agregar gasto fijo». Importar conserva la línea punteada, ahora con
   fondito naranja claro para que se lea como botón (revisión de Santiago). */
.finanzas-fijos-botones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.finanzas-fijos-importar {
  min-height: 34px;
  padding: 0.35rem 0.7rem;
  border: 1px dashed color-mix(in srgb, var(--finanzas-hoy) 45%, var(--border));
  border-radius: calc(var(--radius) - 2px);
  background: color-mix(in srgb, var(--finanzas-hoy) 14%, transparent);
  color: var(--foreground);
  cursor: pointer;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
}

.finanzas-fijos-importar[hidden] {
  display: none;
}

.finanzas-fijos-importar:hover {
  border-color: var(--finanzas-hoy);
  background: color-mix(in srgb, var(--finanzas-hoy) 24%, transparent);
}

.finanzas-fija-fila {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 0.6rem;
  align-items: center;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 0.84rem;
  /* El dedo vertical sigue scrolleando; el horizontal queda para editar. */
  touch-action: pan-y;
}

.finanzas-fija-sub {
  display: block;
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--muted-foreground);
  text-align: right;
}

.finanzas-fijos-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.6rem;
  margin-top: 0.7rem;
  padding: 0.6rem 0.65rem 0;
  border-top: 1px dashed var(--border);
  font-size: 0.84rem;
}

.finanzas-fijos-total strong {
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media (max-width: 720px) {
  .finanzas-fields {
    grid-template-columns: 1fr 1fr;
  }

  .finanzas-field-concepto {
    /* El concepto comparte línea con la fecha en móvil (fecha corta · concepto
       ancho, categoría · moneda y monto · par): filas parejas, sin apilar. */
  }

  /* La fecha móvil va sin el icono del calendario de Chrome: el toque en el
     campo entero sigue abriendo el selector nativo (iOS nunca lo mostró) y a
     6.9rem el valor dd/mm/aaaa cabe completo sin él. */
  .finanzas-form-en-tarjeta #finanzas-fecha::-webkit-calendar-picker-indicator {
    display: none;
  }

  .finanzas-actions {
    flex-direction: column;
    align-items: stretch;
  }

  .finanzas-actions .ds-button {
    width: 100%;
    min-height: 44px;
  }

  .finanzas-fila {
    grid-template-columns: 4.9rem minmax(0, 1fr) auto;
  }

  /* Solo el chip de tipo se oculta en móvil: el de categoría se queda visible
     con su color (revisión de Santiago, 14-sep-2026). */
  .finanzas-tipo-chip {
    display: none;
  }

  .finanzas-categoria-chip {
    max-width: 7.5rem;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .finanzas-fijos-total {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.15rem;
  }

  .finanzas-fija-sub {
    font-size: 0.64rem;
  }
}

/* ─── M04 · Mini-app de finanzas: período, tarjetas y categorías ─── */

/* Cabecera estilo iOS large title: título de pantalla a la izquierda y
   selector de período a la derecha, sin chrome de marca/hamburguesa. */
.finanzas-header {
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding-top: 0.35rem;
  padding-bottom: 0.85rem;
}

.finanzas-large-title {
  margin: 0;
  min-width: 0;
  font-size: clamp(1.55rem, 4.5vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.12;
  color: var(--foreground);
}

.finanzas-large-title.finanzas-titulo-fijos {
  font-size: clamp(1.2rem, 3vw, 1.55rem);
  white-space: nowrap;
}

.finanzas-header .module-eyebrow {
  margin: 0;
  line-height: 1.4;
}

.finanzas-periodo {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.2rem;
  min-width: 0;
}

.finanzas-periodo-selector {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.42rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--background);
  color: var(--foreground);
  cursor: pointer;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 650;
  white-space: nowrap;
}

.finanzas-periodo-selector:hover,
.finanzas-periodo-selector[aria-expanded="true"] {
  border-color: var(--ring);
}

.finanzas-periodo-chevron {
  flex: none;
  transition: transform 0.15s ease;
}

.finanzas-periodo-selector[aria-expanded="true"] .finanzas-periodo-chevron {
  transform: rotate(180deg);
}

/* Panel del calendario de rango, anclado al selector. */
.finanzas-calendario {
  position: absolute;
  top: calc(100% + 0.45rem);
  right: 0;
  z-index: 30;
  width: min(19rem, calc(100vw - 2.5rem));
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: 0 12px 32px -12px rgb(0 0 0 / 0.35);
}

.finanzas-calendario-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.finanzas-calendario-titulo {
  font-size: 0.82rem;
  font-weight: 700;
}

.finanzas-calendario-nav-boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
  font-size: 1.05rem;
  line-height: 1;
}

.finanzas-calendario-nav-boton:hover {
  border-color: var(--border);
  background: var(--secondary);
}

.finanzas-calendario-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 2px;
}

.finanzas-calendario-dia-semana {
  padding: 0.25rem 0;
  color: var(--muted-foreground);
  font-size: 0.64rem;
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
}

.finanzas-calendario-vacio {
  aspect-ratio: 1;
}

.finanzas-calendario-dia {
  aspect-ratio: 1;
  min-width: 0;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
  font: inherit;
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
}

.finanzas-calendario-dia:hover {
  border-color: var(--ring);
}

.finanzas-calendario-dia.en-rango {
  background: var(--secondary);
  border-radius: 0;
}

.finanzas-calendario-dia.en-rango.es-inicio,
.finanzas-calendario-dia.en-rango.es-fin {
  background: var(--primary);
  color: var(--primary-foreground);
}

.finanzas-calendario-dia.en-rango.es-inicio {
  border-radius: var(--radius) 0 0 var(--radius);
}

.finanzas-calendario-dia.en-rango.es-fin {
  border-radius: 0 var(--radius) var(--radius) 0;
}

.finanzas-calendario-dia.en-rango.es-inicio.es-fin {
  border-radius: var(--radius);
}

/* Primer clic de un período nuevo: el día queda «en blanco» (blanco literal,
   legible en cualquier tema) con su marco, esperando el segundo clic. */
.finanzas-calendario-dia.es-seleccion-inicio {
  background: #fff;
  color: hsl(240 5.9% 10%);
  border-color: hsl(240 5.9% 10%);
  border-radius: var(--radius);
  font-weight: 700;
}

/* Mes completo seleccionado: los días interiores forman una banda continua
   con relleno uniforme; el día 1 y el último quedan en blanco como remate
   contrastado (blanco literal #fff: no se funde con el fondo en tema oscuro)
   y el día de hoy es la única pieza en verde de la interfaz, siempre
   visible con o sin rango. */
.finanzas-calendario-grid-mes .finanzas-calendario-dia.en-rango {
  background: color-mix(in srgb, var(--primary) 20%, transparent);
  border-radius: 0;
}

.finanzas-calendario-grid-mes .finanzas-calendario-dia.en-rango.es-inicio,
.finanzas-calendario-grid-mes .finanzas-calendario-dia.en-rango.es-fin {
  background: #fff;
  color: hsl(240 5.9% 10%);
}

.finanzas-calendario-grid-mes .finanzas-calendario-dia.en-rango.es-inicio {
  border-radius: var(--radius) 0 0 var(--radius);
}

.finanzas-calendario-grid-mes .finanzas-calendario-dia.en-rango.es-fin {
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* El día de hoy es verde SIEMPRE (con o sin rango aplicado, y también
   mientras se elige un período nuevo). --success es el verde ya usado en
   la interfaz; en Cadushi (shell-ios) lo pisa la lima de la marca. */
.finanzas-calendario-dia.es-hoy,
.finanzas-calendario-dia.en-rango.es-hoy,
.finanzas-calendario-grid-mes .finanzas-calendario-dia.en-rango.es-hoy {
  background: var(--success);
  color: var(--success-foreground);
  border-radius: var(--radius);
  font-weight: 800;
}

.finanzas-calendario-atajos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--border);
}

.finanzas-calendario-atajo {
  padding: 0.32rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
  font: inherit;
  font-size: 0.68rem;
  font-weight: 600;
}

.finanzas-calendario-atajo:hover {
  border-color: var(--ring);
  color: var(--foreground);
}

/* Desglose por categorías dentro de las tarjetas de resumen. */
.finanzas-categorias-lista {
  display: grid;
  gap: 0.2rem;
  margin: 0.6rem 0 0;
  padding: 0.6rem 0 0;
  border-top: 1px dashed var(--border);
  list-style: none;
}

.finanzas-categorias-fila {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  font-size: 0.76rem;
}

.finanzas-categorias-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted-foreground);
}

.finanzas-categorias-monto {
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.finanzas-card {
  position: relative;
}

.finanzas-card-gasto {
  border-top: 3px solid var(--destructive);
}

.finanzas-card-gasto .ds-card-value strong {
  color: var(--destructive);
}

.finanzas-card-ingreso {
  border-top: 3px solid var(--success);
}

.finanzas-card-ingreso .ds-card-value strong {
  color: var(--success);
}

.finanzas-card-boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  border: none;
  border-radius: 999px;
  cursor: pointer;
  font-size: 1.15rem;
  line-height: 1;
  font-weight: 700;
}

.finanzas-card-gasto .finanzas-card-boton {
  background: var(--destructive);
  color: var(--destructive-foreground);
}

.finanzas-card-ingreso .finanzas-card-boton {
  background: var(--success);
  color: #fff;
}

.finanzas-card-boton:hover {
  opacity: 0.88;
}

.finanzas-actions-botones {
  display: flex;
  gap: 0.5rem;
}

.finanzas-boton-ghost {
  display: inline-flex;
  align-items: center;
  min-height: 2rem;
  padding: 0.35rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) - 2px);
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 600;
}

.finanzas-boton-ghost:hover {
  background: var(--secondary);
}

.finanzas-boton-ghost:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.finanzas-tipo-chip {
  justify-self: start;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.64rem;
  font-weight: 700;
  white-space: nowrap;
}

.finanzas-tipo-chip.tipo-gasto {
  background: color-mix(in srgb, var(--destructive) 14%, transparent);
  color: var(--destructive);
}

.finanzas-tipo-chip.tipo-ingreso {
  background: color-mix(in srgb, var(--success) 16%, transparent);
  color: var(--success);
}

.finanzas-monto.monto-gasto {
  color: var(--destructive);
}

.finanzas-monto.monto-ingreso {
  color: var(--success);
}

/* Configuración: sub-vista de categorías dentro de #vista-finanzas */

.finanzas-configuracion {
  padding: 0.25rem 1.25rem 1.2rem;
}

/* Sub-vistas (gastos fijos y configuración): cabecera compartida con
   enlace de vuelta y título. */
.finanzas-subvista-header {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-bottom: 0.9rem;
}

.finanzas-volver {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  align-self: flex-start;
  color: var(--muted-foreground);
  font-size: 0.8rem;
  font-weight: 650;
  text-decoration: none;
}

.finanzas-volver:hover {
  color: var(--foreground);
}

.finanzas-subvista-header h3 {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.finanzas-configuracion-note {
  margin: 0.3rem 0 0;
  color: var(--muted-foreground);
  font-size: 0.78rem;
}

.finanzas-categoria-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.6rem;
  margin-bottom: 0.8rem;
}

.finanzas-categoria-nueva {
  flex: 1 1 16rem;
  min-width: 0;
}

.finanzas-categoria-form .finanzas-form-status {
  flex-basis: 100%;
}

.finanzas-categoria-lista {
  gap: 0.45rem;
}

.finanzas-categoria-fila {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 0.6rem;
  align-items: center;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 0.86rem;
}

.finanzas-categoria-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.finanzas-categoria-chip {
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--secondary);
  color: var(--muted-foreground);
  font-size: 0.64rem;
  font-weight: 600;
  white-space: nowrap;
}

/* Submenú del sidebar: Configuración bajo Finanzas personales */

.sidebar-nav ul.sidebar-sublist {
  margin: 0.1rem 0 0;
  padding: 0 0 0 1.9rem;
  list-style: none;
}

.sidebar-sublink {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.38rem 0.7rem;
  border-radius: var(--radius);
  color: var(--muted-foreground);
  font-size: 0.78rem;
  font-weight: 550;
  text-decoration: none;
}

.sidebar-sublink:hover {
  background: var(--accent);
  color: var(--accent-foreground);
}

.sidebar-sublink[aria-current="page"] {
  background: var(--muted);
  color: var(--foreground);
  font-weight: 650;
}

@media (max-width: 720px) {
  .finanzas-periodo-selector {
    font-size: 0.72rem;
    padding: 0.4rem 0.65rem;
  }

  .finanzas-fijo-fields {
    grid-template-columns: 1fr 1fr;
  }

  .finanzas-fija-fila {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .finanzas-fija-fila .finanzas-fija-chip {
    display: none;
  }

  .finanzas-fija-fila .finanzas-fijo-estado {
    grid-column: 1;
    justify-self: start;
  }

  .finanzas-fija-fila .finanzas-fijo-acciones {
    grid-column: 2;
    justify-self: end;
  }

  .finanzas-fijos-botones.con-importar {
    width: 100%;
    align-items: stretch;
  }

  .finanzas-fijos-botones.con-importar .finanzas-fijos-importar {
    flex: 1 1 0;
    min-width: 0;
    white-space: normal;
    text-align: center;
    font-size: 0.76rem;
  }

  .finanzas-actions-botones {
    width: 100%;
    /* El par ✓/✗ del formulario de registro se queda a la derecha (pulgar) y
       conserva sus 44 px: no se estira como los botones rotulados. */
    justify-content: flex-end;
  }

  .finanzas-actions-botones .ds-button,
  .finanzas-actions-botones .finanzas-boton-ghost {
    flex: 1;
    min-height: 44px;
    justify-content: center;
  }
}

/* ─── Botón de histórico dentro de cada tile + popover de disco ─── */

.vps-metric-tile {
  position: relative;
}

.tile-historico-boton {
  position: absolute;
  top: 0.45rem;
  right: 0.45rem;
  z-index: 2;
  display: grid;
  width: 1.65rem;
  height: 1.65rem;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) - 2px);
  background: var(--background);
  color: var(--muted-foreground);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.vps-metric-tile:hover .tile-historico-boton,
.tile-historico-boton:focus-visible,
.tile-historico-boton[aria-expanded="true"] {
  opacity: 1;
}

.tile-historico-boton:hover {
  color: var(--foreground);
  border-color: var(--ring);
}

.tile-historico-boton:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

.tile-detalle-target {
  position: absolute;
  inset: 0;
  z-index: 1;
  padding: 0;
  border: 0;
  border-radius: inherit;
  background: transparent;
  cursor: pointer;
}

.tile-detalle-target:focus-visible,
.popover-cerrar:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: -2px;
}

.disco-popover {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 20;
  width: min(18rem, calc(100vw - 2.5rem));
  margin-top: 0.35rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--popover);
  color: var(--popover-foreground);
  box-shadow: 0 8px 24px hsl(240 10% 8% / 0.18);
}

.popover-cerrar {
  position: absolute;
  top: 0.35rem;
  right: 0.45rem;
  display: grid;
  width: 1.65rem;
  height: 1.65rem;
  place-items: center;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--secondary);
  color: var(--foreground);
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

.disco-popover-titulo {
  margin: 0 0 0.55rem;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}

/* Selector de usuarios: chips con la ocupación de cada home. */
.disco-usuarios {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: 0 0 0.55rem;
}

.disco-usuario-chip {
  padding: 0.14rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--secondary);
  color: var(--muted-foreground);
  font: inherit;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.disco-usuario-chip:hover,
.disco-usuario-chip:focus-visible {
  color: var(--foreground);
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

.disco-usuario-chip[aria-current='page'] {
  border-color: var(--ring);
  color: var(--foreground);
  font-weight: 600;
}

/* Grupo de usuarios de sistema: círculo con icono + badge contador. */
.disco-usuarios-grupo {
  display: contents; /* botón y lista expandida participan del flex principal */
}

.disco-usuario-grupo-boton {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.7rem;
  height: 1.7rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--secondary);
  color: var(--muted-foreground);
  cursor: pointer;
}

.disco-usuario-grupo-boton:hover,
.disco-usuario-grupo-boton:focus-visible {
  color: var(--foreground);
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

.disco-usuario-grupo-badge {
  position: absolute;
  top: -0.3rem;
  right: -0.35rem;
  min-width: 0.95rem;
  height: 0.95rem;
  padding: 0 0.18rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-foreground);
  font-size: 0.55rem;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.disco-usuarios-grupo-lista {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

#disco-carpetas {
  display: grid;
  gap: 0.45rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.disco-carpeta-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.15rem 0.6rem;
  align-items: baseline;
  font-size: 0.78rem;
}

.disco-carpeta-ruta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}

.disco-carpeta-bytes {
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}

.disco-carpeta-barra {
  grid-column: 1 / -1;
  height: 4px;
  border-radius: 999px;
  background: var(--secondary);
  overflow: hidden;
}

.disco-carpeta-barra-relleno {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--chart-2);
}

.disco-carpeta-vacio {
  font-size: 0.78rem;
  color: var(--muted-foreground);
}

.disco-popover-fecha {
  margin: 0.6rem 0 0;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
  color: var(--muted-foreground);
  font-size: 0.68rem;
}

/* Pie de coherencia del popover de Memoria: explica por qué la suma de los
   procesos listados no alcanza el total usado del anillo del tile. */
.disco-popover-pie {
  margin: 0.55rem 0 0;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
  color: var(--muted-foreground);
  font-size: 0.7rem;
  line-height: 1.4;
}

/* ─── Popover de disco: breadcrumb y filas navegables ─── */

.disco-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  margin: 0 0 0.5rem;
  padding: 0;
  font-size: 0.72rem;
}

.disco-breadcrumb-link {
  padding: 0.1rem 0.3rem;
  border: 0;
  border-radius: calc(var(--radius) - 4px);
  background: var(--secondary);
  color: var(--muted-foreground);
  font: inherit;
  cursor: pointer;
}

.disco-breadcrumb-link:hover,
.disco-breadcrumb-link:focus-visible {
  color: var(--foreground);
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

.disco-breadcrumb-actual {
  font-weight: 700;
  color: var(--foreground);
}

.disco-carpeta-row {
  cursor: pointer;
  border-radius: calc(var(--radius) - 4px);
  padding: 0.1rem 0.25rem;
}

.disco-carpeta-row:hover {
  background: var(--secondary);
}

.disco-carpeta-row:focus-visible {
  background: var(--secondary);
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

/* En móvil los popovers se vuelven una hoja inferior a todo el ancho:
   nunca se desbordan por la derecha. */
@media (max-width: 720px) {
  /* RAM y disco se abren tocando la tarjeta completa; en la hoja móvil la
     equis duplica el cierre exterior/Escape, por eso no se presenta. */
  #memoria-popover .popover-cerrar,
  #disco-popover .popover-cerrar {
    display: none;
  }

  .disco-popover,
  .memoria-popover {
    position: fixed;
    top: auto;
    left: 0.75rem;
    right: 0.75rem;
    bottom: 0.75rem;
    width: auto;
    max-width: none;
    margin-top: 0;
    max-height: 60vh;
    overflow-y: auto;
  }

  /* Las fichas de recursos usan más del alto real disponible cuando su
     contenido lo necesita. Conservan scroll solo en pantallas bajas. */
  #memoria-popover,
  #disco-popover,
  #swap-popover,
  #zram-popover {
    max-height: min(72dvh, calc(100dvh - 1.5rem));
  }

  /* Los popovers de intercambio van centrados y angostos: no ocupan todo el
     ancho de la pantalla. */
  .disco-popover.swap-popover,
  .disco-popover.zram-popover {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: min(21rem, calc(100vw - 1.5rem));
    max-width: none;
  }

  .swap-dispositivo .swap-dispositivo-ring {
    width: 2.65rem;
    height: 2.65rem;
  }

  /* Previsualización densa en la hoja de memoria: filas a dos columnas con
     barras cortas del ancho de cada celda — caben más procesos por pantalla.
     La fila sintética Kernel + ZRAM abarca ambas columnas. */
  .memoria-popover #memoria-procesos {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.4rem 0.5rem;
  }

  /* Celda móvil: la etiqueta en una sola línea y, debajo, la barra GRUESA
     con el valor y el porcentaje dentro. Sin PID: la línea meta, bytes y %
     se ocultan en la hoja (el PID sigue en el tooltip de escritorio). */
  .memoria-popover .proceso-row {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto;
    gap: 0.12rem;
  }

  .memoria-popover .proceso-cuerpo {
    grid-column: 1;
    grid-row: 1;
  }

  .memoria-popover .proceso-meta,
  .memoria-popover .proceso-bytes,
  .memoria-popover .proceso-pct {
    display: none;
  }

  .memoria-popover .proceso-row .disco-carpeta-barra {
    grid-row: 2;
    position: relative;
    height: 1.1rem;
  }

  .memoria-popover .proceso-barra-texto {
    display: block;
    position: absolute;
    inset: 0;
    margin: auto;
    width: fit-content;
    max-width: 100%;
    overflow: hidden;
    padding: 0 0.45rem;
    border-radius: 999px;
    background: var(--popover);
    font-size: 0.62rem;
    font-weight: 650;
    font-variant-numeric: tabular-nums;
    line-height: 1rem;
    color: var(--foreground);
    white-space: nowrap;
    pointer-events: none;
  }

  .memoria-popover .proceso-row-kernel {
    grid-column: 1 / -1;
  }
}

/* ─── Popover de memoria: procesos por RAM ─── */

.memoria-popover {
  width: min(24rem, calc(100vw - 2.5rem));
}

/* Cabecera del popover de memoria: título + toggle segmentado Top/Resto. */
.memoria-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.55rem;
}

.memoria-cabecera .disco-popover-titulo {
  margin: 0;
}

.memoria-toggle {
  display: inline-flex;
  flex: none;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 999px;
}

.memoria-toggle-boton {
  border: none;
  background: transparent;
  color: var(--muted-foreground);
  font-size: 0.68rem;
  font-weight: 600;
  line-height: 1;
  padding: 0.3rem 0.6rem;
  border-radius: 999px;
  cursor: pointer;
  min-height: 24px;
}

.memoria-toggle-boton:hover {
  background: var(--secondary);
}

.memoria-toggle-boton[aria-pressed="true"] {
  background: var(--accent);
  color: var(--accent-foreground);
}

/* La fila sintética Kernel + ZRAM se separa visualmente de los grupos. */
.proceso-row-kernel {
  border-top: 1px dashed var(--border);
  padding-top: 0.4rem;
}

/* La lista anula el padding por defecto del <ol> del navegador (40px) que
   desaprovechaba la izquierda del popover y empujaba todo a la derecha. */
#memoria-procesos {
  display: grid;
  gap: 0.45rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.proceso-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 0.15rem 0.6rem;
  align-items: center;
  font-size: 0.78rem;
}

.proceso-cuerpo {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 0.1rem;
}

.proceso-etiqueta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}

.proceso-meta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}

.proceso-bytes,
.proceso-pct {
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}

/* El texto dentro de la barra solo existe en la celda móvil. */
.proceso-barra-texto {
  display: none;
}

.vps-metric-tile.fijado {
  border-color: var(--ring);
  box-shadow: 0 0 0 1px var(--ring);
}

/* En táctil (sin hover) el botón queda visible siempre. */
@media (hover: none) {
  .tile-historico-boton {
    opacity: 1;
  }
}

/* ─── Densidad por tarjeta (container queries) ───
   Tarjeta angosta (rejilla de dos columnas junto al sidebar): los tiles
   pasan a dos columnas, los hechos del servidor a dos por fila y las cards
   de consumo a dos, devolviéndole a cada valor el ancho que necesita.
   Van al final del archivo para ganar en cascada a las reglas base. */
@container (max-width: 1100px) {
  /* La franja de identidad ya es flex con wrap: en tarjetas angostas los
     hechos (Servidor, IPv4) fluyen solos a la línea siguiente. */
  .vps-server-facts dd {
    font-size: 0.72rem;
  }

  .vps-metric-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .ds-top-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .tile-reading strong {
    font-size: 1.32rem;
  }

  .mini-chart {
    width: 3rem;
  }

  .ds-card-value strong {
    font-size: 1.7rem;
  }

  .salud-resumen-franja {
    grid-template-columns: minmax(0, 1fr);
  }

  .salud-grid {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      'tandas'
      'hormonas'
      'metricas';
  }
}

/* La mini-app de finanzas apila sus dos tarjetas (ingresos arriba, gastos
   debajo) a ancho COMPLETO, en celular y escritorio: no hereda las cuatro
   columnas del consumo ni el contenedor angosto. Con las dos columnas la
   información no cabía (títulos y montos del desglose cortados en 390) y
   Santiago pidió fila completa para ver los datos sin apretujar
   (23-sep-2026). En escritorio se midió el tope centrado (88rem) y se
   descartó: el resto del Resumen (pendientes, últimos movimientos) ya usa
   todo el ancho del módulo y las tarjetas quedaban desalineadas del
   conjunto. */
.finanzas-top-cards {
  grid-template-columns: minmax(0, 1fr);
}

/* En móvil el valor va arriba y el mini-gráfico debajo a todo el ancho:
   ningún valor se trunca en pantallas angostas. */
@media (max-width: 720px) {
  .tile-reading {
    flex-direction: column;
    align-items: stretch;
    gap: 0.35rem;
  }

  .mini-chart {
    width: 100%;
  }
}

/* ─── F1 · Sidebar colapsable (rail de iconos) ─────────────────────────
   El botón chevron contrae el sidebar fijo a un rail de 3.5rem con solo
   iconos. El estado vive en body.is-collapsed y las reglas van al final
   para ganar la cascada. Solo aplica en escritorio: en móvil el sidebar ya
   es un cajón y el botón se oculta. */

.sidebar-collapse {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: calc(var(--radius) - 2px);
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
}

.sidebar-collapse:hover {
  background: var(--accent);
  color: var(--accent-foreground);
}

.sidebar-collapse svg {
  transition: transform 0.18s ease;
}

/* El rail solo tiene sentido en escritorio; en pantallas angostas el
   sidebar es un cajón que se abre completo y no se puede colapsar. */
@media (min-width: 721px) {
  body.is-collapsed {
    --sidebar-w: 3.5rem;
  }

  body.is-collapsed .sidebar-brand {
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
  }

  body.is-collapsed .sidebar-brand-name,
  body.is-collapsed .sidebar-brand-sub,
  body.is-collapsed .sidebar-group-title,
  body.is-collapsed .sidebar-link span,
  body.is-collapsed .sidebar-planned,
  body.is-collapsed .sidebar-note {
    display: none;
  }

  /* El rail de iconos no tiene espacio para submenús: el sub-ítem de
     finanzas (Configuración) se oculta del todo cuando está contraído y
     vuelve a aparecer como submenú indentado al expandir. */
  body.is-collapsed .sidebar-sublist {
    display: none;
  }

  body.is-collapsed .sidebar-sublist-toggle {
    display: none;
  }

  body.is-collapsed .sidebar-link {
    justify-content: center;
    gap: 0;
    padding: 0.5rem;
    min-height: 44px;
  }

  body.is-collapsed .sidebar-collapse {
    margin-left: 0;
  }

  body.is-collapsed .sidebar-collapse svg {
    transform: rotate(180deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .app-sidebar,
  .app-frame,
  .sidebar-collapse svg {
    transition: none;
  }
}

@media (max-width: 720px) {
  .sidebar-collapse {
    display: none;
  }
}

/* ─── M01 · Histórico on-demand ──────────────────────────────────────────
   Tarjeta anidada que se abre al pulsar una tile de recurso. Va al final
   para ganar en cascada y respeta el movimiento reducido. */

.historico-panel {
  margin: 0 1.25rem 1.25rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 2px);
  background: var(--card);
}

.historico-panel .ds-header {
  padding: 0 0 0.9rem;
}

.historico-panel .ds-header-title h3 {
  margin: 0.1rem 0 0.25rem;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}

.historico-controles {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.historico-panel .ds-select select {
  border: none;
  background: transparent;
  color: var(--foreground);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
}

.historico-chart {
  display: block;
  width: 100%;
  height: 200px;
}

.historico-chart path {
  fill: none;
  stroke: var(--chart-2);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.historico-estado {
  min-height: 1.2rem;
  margin: 0.6rem 0 0;
  color: var(--muted-foreground);
  font-size: 0.78rem;
}

/* Las tiles de recurso son objetivos táctiles con cursor de enlace. */
.vps-metric-tile[role="button"] {
  cursor: pointer;
}

.vps-metric-tile[role="button"]:hover {
  border-color: var(--ring);
}

@media (max-width: 720px) {
  .historico-panel {
    margin: 0 0.75rem 1rem;
    padding: 0.85rem 0.75rem;
  }

  .historico-panel .ds-header {
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }

  .historico-controles {
    width: 100%;
    justify-content: space-between;
  }
}

@media (prefers-reduced-motion: reduce) {
  .historico-chart path {
    transition: none;
  }

  .salud-rango-gauge-linea,
  .salud-rango-gauge-segmento,
  .salud-rango-gauge-punto,
  .salud-rango-gauge-escala,
  .salud-chip,
  .salud-chip .salud-icono-trazo,
  .module-view.swipe-in-izq,
  .module-view.swipe-in-der {
    animation: none;
  }
}

/* ─── Mapa de puertos (M01) ──────────────────────────────────────────────
   Agregado por puerto único (TCP+UDP). El color codifica la exposición:
   pública (todas las interfaces), interna (Docker/Tailscale) o solo local. */

.puertos-strip {
  padding: 0.9rem 1.25rem;
  border-bottom: 1px solid var(--border);
}

.puertos-heading {
  margin-bottom: 0.4rem;
  align-items: flex-start;
}

.puertos-heading-texto {
  min-width: 0;
  flex: 1 1 auto;
}

.puertos-heading-controles {
  display: flex;
  align-items: center;
  gap: 0.2rem;
  flex: none;
}

.puertos-toggle {
  display: grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
}

.puertos-toggle:hover {
  color: var(--foreground);
  border-color: var(--ring);
}

.puertos-toggle svg {
  transition: transform 180ms ease;
}

.puertos-toggle[aria-expanded="false"] svg {
  transform: rotate(-90deg);
}

.puertos-heading h2 {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 0.5rem;
  min-width: 0;
  overflow: hidden;
}

.puertos-heading p {
  margin-top: 0.1rem;
}

.status-pill[data-state="error"] {
  border-color: color-mix(in srgb, var(--destructive) 30%, transparent);
  background: color-mix(in srgb, var(--destructive) 8%, transparent);
  color: color-mix(in srgb, var(--destructive) 78%, var(--foreground));
}

.puertos-resumen {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.5rem;
  margin: 0 0 0.6rem;
}

.puertos-kpi {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.4rem 0.6rem;
  background: var(--card);
  min-width: 0;
}

.puertos-kpi[data-exposicion="publica"] { border-left: 3px solid var(--destructive); }
.puertos-kpi[data-exposicion="interna"] { border-left: 3px solid var(--warning); }
.puertos-kpi[data-exposicion="local"] { border-left: 3px solid var(--success); }

.puertos-kpi dt {
  margin: 0;
  font-size: 0.68rem;
  color: var(--muted-foreground);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.puertos-kpi dd {
  margin: 0.1rem 0 0;
  font-size: 1.05rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.puertos-mapa-wrap {
  position: relative;
  margin-bottom: 0.4rem;
}

.puertos-mapa {
  display: block;
  width: 100%;
  height: auto;
}

.puertos-mapa .puerto-eje {
  stroke: var(--border);
  stroke-width: 1;
  stroke-dasharray: 2 3;
}

.puertos-mapa text {
  font-size: 9px;
  fill: var(--muted-foreground);
}

.puertos-mapa .puerto-punto {
  cursor: default;
  transition: opacity 140ms ease;
}

.puertos-mapa .puerto-punto[data-exposicion="publica"] { fill: var(--destructive); }
.puertos-mapa .puerto-punto[data-exposicion="interna"] { fill: var(--warning); }
.puertos-mapa .puerto-punto[data-exposicion="local"] { fill: var(--success); }

.puertos-mapa .puerto-punto.is-dimmed { opacity: 0.12; }
.puertos-mapa .puerto-punto.is-resaltado {
  stroke: var(--foreground);
  stroke-width: 1.5;
}

.puertos-histograma {
  display: none;
  width: 100%;
  height: 120px;
}

.puertos-histograma rect {
  fill: var(--border);
  opacity: 0.55;
  transition: opacity 140ms ease;
}

.puertos-histograma rect[data-exposicion] { opacity: 1; }

.puertos-histograma rect[data-exposicion="publica"] { fill: var(--destructive); }
.puertos-histograma rect[data-exposicion="interna"] { fill: var(--warning); }
.puertos-histograma rect[data-exposicion="local"] { fill: var(--success); }

.puertos-histograma rect:hover,
.puertos-histograma rect:focus {
  opacity: 0.72;
}

.puertos-histograma text {
  font-size: 8px;
  fill: var(--muted-foreground);
  text-anchor: middle;
}

.puertos-histograma text.barra-conteo {
  font-size: 10px;
  font-weight: 650;
  fill: var(--foreground);
}

.puertos-tooltip {
  min-width: 11rem;
}

.puertos-leyenda {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.6rem;
}

.puertos-leyenda button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 30px;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--foreground);
  border-radius: 999px;
  padding: 0.15rem 0.65rem;
  font-size: 0.72rem;
  font-weight: 600;
  cursor: pointer;
}

.puertos-leyenda button[aria-pressed="true"] {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--primary-foreground);
}

.puertos-leyenda .leyenda-dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  display: inline-block;
  flex: none;
}

.puertos-lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
  gap: 0.4rem;
}

.puertos-lista.is-colapsada {
  display: none;
}

.puerto-chip {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: var(--radius);
  padding: 0.35rem 0.55rem;
  background: var(--card);
  min-width: 0;
  cursor: pointer;
  width: 100%;
  color: inherit;
  font: inherit;
  text-align: left;
}

.puerto-chip[data-exposicion="publica"] { border-left-color: var(--destructive); }
.puerto-chip[data-exposicion="interna"] { border-left-color: var(--warning); }
.puerto-chip[data-exposicion="local"] { border-left-color: var(--success); }

.puerto-chip.is-oculto { display: none; }
.puertos-lista > li.is-oculto { display: none; }

.puerto-chip:hover,
.puerto-chip:focus-visible {
  border-color: var(--ring);
  border-left-width: 3px;
}

.puerto-chip-cabecera {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem;
  min-width: 0;
}

.puerto-chip-numero {
  font-weight: 700;
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
}

.puerto-chip-protocolo {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--muted-foreground);
  text-transform: uppercase;
}

.puerto-chip-etiqueta {
  font-size: 0.72rem;
  color: var(--muted-foreground);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.puerto-chip-meta {
  font-size: 0.66rem;
  color: var(--muted-foreground);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.puerto-detalle {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 70;
  width: 20rem;
  max-width: min(21rem, calc(100vw - 1.5rem));
  max-height: 60vh;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  padding: 0.85rem 1rem;
  box-shadow: 0 14px 40px rgb(0 0 0 / 0.22);
}

.puerto-detalle-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.puerto-detalle-cabecera h3 {
  margin: 0;
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
}

.puerto-detalle-cerrar {
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  flex: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
}

.puerto-detalle-cerrar:hover {
  color: var(--foreground);
  border-color: var(--ring);
}

.puerto-detalle-cuerpo {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.3rem 0.8rem;
  margin: 0.6rem 0 0;
}

.puerto-detalle-fila {
  display: contents;
}

.puerto-detalle-cuerpo dt {
  font-size: 0.7rem;
  color: var(--muted-foreground);
}

.puerto-detalle-cuerpo dd {
  margin: 0;
  font-size: 0.78rem;
  overflow-wrap: anywhere;
  min-width: 0;
}

@media (prefers-reduced-motion: reduce) {
  .puertos-mapa .puerto-punto { transition: none; }
}

@media (max-width: 720px) {
  .puertos-heading {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
  }

  .puertos-resumen {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .puertos-lista {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .puertos-mapa {
    display: none;
  }

  .puertos-histograma {
    display: block;
    height: 120px;
  }

  .puertos-leyenda {
    flex-wrap: nowrap;
  }

  .puertos-leyenda button {
    font-size: 0.66rem;
    gap: 0.25rem;
    padding: 0.15rem 0.5rem;
  }

  .puerto-detalle {
    --puerto-inset-top: env(safe-area-inset-top, 0px);
    --puerto-inset-right: env(safe-area-inset-right, 0px);
    --puerto-inset-bottom: env(safe-area-inset-bottom, 0px);
    --puerto-inset-left: env(safe-area-inset-left, 0px);
    left: 50%;
    right: auto;
    bottom: 0.75rem;
    transform: translateX(-50%);
    width: min(21rem, calc(100vw - var(--puerto-inset-left) - var(--puerto-inset-right) - 1.5rem));
    max-height: calc(100dvh - 1rem);
  }

  .puerto-detalle.is-anclado {
    right: auto;
    bottom: auto;
    transform: none;
  }
}

/* ═══ Barra inferior de finanzas (estilo iOS, solo móvil/tablet) ═══════════ */

/* En escritorio no existe: el sidebar ya navega. */
.finanzas-tabbar {
  display: none;
}

.finanzas-tabbar[hidden] {
  display: none;
}

@media (max-width: 720px) {
  /* Silueta continua del prototipo: dos cinturas curvas y centro circular.
     El SVG es decorativo; enlaces y acciones siguen siendo HTML nativo. */
  .finanzas-tabbar {
    position: fixed;
    left: 50%;
    right: auto;
    bottom: calc(0.6rem + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    width: min(calc((100% - 1.5rem) * 0.82), 322px);
    aspect-ratio: 392 / 90;
    z-index: 40;
    display: block;
    padding: 0;
    border: none;
    border-radius: 0;
    background: transparent;
    isolation: isolate;
    -webkit-tap-highlight-color: transparent;
  }

  .cadushi-nav-superficie {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
    filter: drop-shadow(0 8px 14px hsl(0 0% 0% / 0.14));
  }

  .cadushi-nav-cuerpo {
    fill: #171618;
    stroke: #ffffff26;
    stroke-width: 0.7;
  }

  .cadushi-nav-disco { fill: #f4f4f3; }

  .finanzas-tabbar-tab {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 18.65%;
    min-width: 44px;
    min-height: 44px;
    transform: translateX(-50%);
    display: grid;
    place-items: center;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: none;
    color: #f0efef;
    text-decoration: none;
    touch-action: manipulation;
  }

  .finanzas-tabbar-tab[data-tabbar-tab="principal"] { left: 9.4388%; }
  .finanzas-tabbar-tab[data-tabbar-tab="movimientos"] { left: 28.8265%; }
  .finanzas-tabbar-tab[data-tabbar-tab="gastos-fijos"] { left: 71.1735%; }
  .finanzas-tabbar-tab[data-tabbar-tab="categorias"] { left: 90.5612%; }

  .finanzas-tabbar-tab > svg {
    width: 42%;
    height: auto;
    overflow: visible;
  }

  /* Conserva el nombre accesible completo sin apretar texto bajo los iconos. */
  .finanzas-tabbar-tab > span {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .finanzas-tabbar-tab[data-iluminado="true"] { color: #171618; }

  .finanzas-tabbar-tab:focus-visible,
  .finanzas-tabbar-alta:focus-visible {
    outline: 2px solid var(--cadushi-lime, #c8f542);
    outline-offset: 2px;
  }

  /* El centro conserva las ondas de Cadushi y su entrada de gasto/ingreso. */
  .finanzas-tabbar-alta {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: grid;
    place-items: center;
    width: 16.8%;
    min-width: 44px;
    aspect-ratio: 1;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--cadushi-lime, #c8f542);
    color: #0a0a0a;
    box-shadow: none;
    cursor: pointer;
    touch-action: manipulation;
    z-index: 1;
  }

  .finanzas-tabbar-alta .cadushi-ondas { width: 46%; height: auto; }

  .finanzas-tabbar-alta[aria-expanded="true"] { box-shadow: 0 0 0 3px #171618, 0 0 0 4px var(--cadushi-lime, #c8f542); }

  /* Selector gasto/ingreso: hoja pequeña que flota sobre el botón central. */
  .finanzas-tabbar-alta-menu {
    position: absolute;
    left: 50%;
    bottom: calc(100% + 0.4rem);
    transform: translateX(-50%);
    display: grid;
    gap: 0.2rem;
    width: 11rem;
    padding: 0.4rem;
    background: var(--popover);
    border: 1px solid var(--finanzas-tabbar-borde);
    border-radius: var(--radius);
    box-shadow: 0 10px 32px hsl(0 0% 0% / 0.18);
  }

  .finanzas-tabbar-alta-menu[hidden] {
    display: none;
  }

  .finanzas-tabbar-alta-opcion {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
    padding: 0.55rem 0.75rem;
    border: none;
    border-radius: calc(var(--radius) - 0.15rem);
    background: none;
    color: var(--foreground);
    font-family: var(--font-sans);
    font-size: 0.92rem;
    text-align: left;
    cursor: pointer;
  }

  .finanzas-tabbar-alta-opcion:hover,
  .finanzas-tabbar-alta-opcion:focus-visible {
    background: var(--accent);
    outline: none;
  }

  .finanzas-tabbar-alta-simbolo {
    display: grid;
    place-items: center;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 999px;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1;
    color: #fff;
  }

  .finanzas-tabbar-alta-opcion[data-tabbar-alta-tipo="gasto"] .finanzas-tabbar-alta-simbolo {
    background: var(--destructive);
  }

  .finanzas-tabbar-alta-opcion[data-tabbar-alta-tipo="ingreso"] .finanzas-tabbar-alta-simbolo {
    background: var(--success);
  }

  /* Aire inferior: la barra fija no debe tapar los últimos movimientos. */
  #vista-finanzas .finanzas-module {
    padding-bottom: calc(6.4rem + env(safe-area-inset-bottom, 0px));
  }

  /* El '+' de cada tarjeta de resumen queda en línea con el título, arriba
     a la derecha del contenedor (sin saltar de fila en pantallas angostas). */
  .finanzas-card .ds-card-header {
    flex-wrap: nowrap;
  }

  .finanzas-card .ds-card-header h3 {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ─── Correo → Pendientes por aprobar (M04) ──────────────────────────────── */

.finanzas-pendientes {
  padding: 0 1.25rem 0.4rem;
}

.finanzas-pendientes-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 0.9rem 0 0.6rem;
}

.finanzas-pendientes-cabecera h3 {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.finanzas-pendientes-contador {
  color: var(--primary);
}

.finanzas-pendientes-estado {
  margin: 0 0 0.55rem;
  color: var(--muted-foreground);
  font-size: 0.78rem;
}

/* La pista implícita del grid resolvía al min-content de la fila más larga
   (628 px medidos en una lista de 348 px): la fila corta del aviso cabía en
   UNA línea de esa pista y sus acciones quedaban más allá del borde de la
   lista, recortadas por .module-track-wrap y sin scroll (hallazgo móvil
   390/428, t_449c2e0c). La pista se acota al ancho disponible y la fila
   puede encogerse: con eso toda fila envuelve dentro de la lista. */
.finanzas-pendientes-lista {
  grid-template-columns: minmax(0, 1fr);
}

.finanzas-pendiente-fila {
  display: grid;
  min-width: 0;
  grid-template-columns: 5.6rem minmax(0, 1fr) minmax(7rem, 9rem) auto auto;
  gap: 0.55rem;
  align-items: center;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}

.finanzas-pendiente-fecha {
  color: var(--muted-foreground);
  font-size: 0.78rem;
  white-space: nowrap;
}

.finanzas-pendiente-detalle {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.finanzas-pendiente-concepto {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.finanzas-pendiente-origen {
  color: var(--muted-foreground);
  font-size: 0.72rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.finanzas-pendiente-categoria {
  min-height: 34px;
  padding: 0.2rem 0.35rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  font-size: 0.8rem;
}

.finanzas-pendiente-monto {
  font-weight: 650;
  color: var(--destructive);
  white-space: nowrap;
}

.finanzas-pendiente-monto.monto-pendiente-completar {
  color: var(--muted-foreground);
  font-weight: 550;
}

.finanzas-pendiente-acciones {
  display: flex;
  gap: 0.3rem;
}

.finanzas-pendiente-boton {
  min-width: 34px;
  min-height: 34px;
  padding: 0 0.4rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--secondary);
  color: var(--primary);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 650;
  cursor: pointer;
}

.finanzas-pendiente-boton:hover {
  border-color: var(--primary);
}

.finanzas-pendiente-boton.boton-aprobar {
  color: var(--success);
}

.finanzas-pendiente-boton.boton-descartar {
  color: var(--destructive);
}

/* ─── Conciliación bancaria (SPEC 007) ───────────────────────────────────── */
/* El aviso del banco que coincide con un movimiento registrado: la línea del
   cruce y la acción «Conciliar» (un toque, sin duplicar el gasto). */
.finanzas-pendiente-cruce {
  font-size: 0.78rem;
  color: var(--success);
}

.finanzas-pendiente-cobro {
  font-size: 0.78rem;
  color: var(--muted-foreground);
}

.finanzas-pendiente-boton.boton-conciliar {
  color: var(--success);
  font-weight: 600;
}

.finanzas-ingesta {
  margin-top: 1.4rem;
}

.finanzas-ingesta-token {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem;
}

.finanzas-ingesta-token .finanzas-field {
  flex: 1 1 16rem;
}

.finanzas-ingesta-acciones {
  display: flex;
  gap: 0.5rem;
}

.finanzas-atajo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin: 0.9rem 0 0.3rem;
}

.finanzas-atajo-descargar {
  text-decoration: none;
}

.finanzas-atajo-descargar[aria-disabled='true'] {
  opacity: 0.55;
  pointer-events: none;
}

.finanzas-ingesta-pasos {
  margin: 0.8rem 0;
  font-size: 0.85rem;
  color: var(--muted-foreground);
}

.finanzas-ingesta-pasos summary {
  cursor: pointer;
  color: var(--foreground);
}

.finanzas-ingesta-pasos ol {
  margin: 0.5rem 0 0 1.1rem;
  padding: 0;
  display: grid;
  gap: 0.35rem;
}

.finanzas-ingesta-pasos code {
  font-size: 0.78rem;
}

.finanzas-pendiente-edicion {
  display: grid;
  grid-template-columns: 8.6rem minmax(0, 1fr) minmax(6.5rem, 8rem) auto auto;
  gap: 0.4rem;
  align-items: center;
  grid-column: 1 / -1;
}

.finanzas-pendiente-input {
  min-height: 40px;
  width: 100%;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  font-size: 0.85rem;
}

/* ─── Multi-moneda (SPEC 004) ────────────────────────────────────────────── */
/* El símbolo de la moneda como chip delante del valor («US$ 6,99»): se lee
   de un vistazo que el cobro es extranjero (revisión del preview). */
.finanzas-moneda-chip {
  display: inline-block;
  padding: 0.02rem 0.34rem;
  margin-right: 0.1rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--muted-foreground);
  white-space: nowrap;
}

/* ≈ COP: segunda línea pequeña bajo el monto original. */
.finanzas-monto-aprox {
  display: block;
  font-size: 0.68rem;
  font-weight: 500;
  color: var(--muted-foreground);
}

/* «sin convertir»: el movimiento espera conciliación bancaria. */
.finanzas-monto-aprox.sin-convertir {
  font-style: italic;
}

/* Ronda 2 (t_18a88f2a, 23-sep-2026): el subtotal de monedas del período va EN
   LÍNEA con el total en COP —dentro de la misma fila de valor— y la fila
   envuelve a una segunda línea legible antes que encoger en pantallas
   angostas (con separación horizontal explícita; nada se trunca). */
.finanzas-card .ds-card-value {
  flex-wrap: wrap;
  column-gap: 0.55rem;
  row-gap: 0.2rem;
}

.finanzas-subtotales-moneda {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--destructive);
  white-space: normal;
}

/* Formularios: nota de procedencia de la tasa y el equivalente calculado. */
.finanzas-tasa-nota {
  font-size: 0.72rem;
  color: var(--muted-foreground);
}

.finanzas-tasa-nota.is-error {
  color: var(--destructive);
}

.finanzas-conversion input {
  background: var(--secondary);
  color: var(--muted-foreground);
}

/* Aprobación de un recibo extranjero: la fila se vuelve formulario de tasa. */
.finanzas-pendiente-tasa {
  grid-template-columns: minmax(0, 1.3fr) minmax(5.5rem, 7.5rem) auto auto;
}

.finanzas-pendiente-tasa-campo {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.finanzas-pendiente-conversion {
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--destructive);
  white-space: nowrap;
}

/* Desglose de ítems del recibo: panel plegable dentro de la fila. */
.finanzas-pendiente-desglose {
  grid-column: 1 / -1;
  flex: 1 1 100%;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.15rem;
  padding: 0.55rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--secondary);
}

.finanzas-pendiente-items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.finanzas-pendiente-item {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  min-width: 0;
}

.finanzas-pendiente-item-principal {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.6rem;
}

.finanzas-pendiente-item-nombre {
  min-width: 0;
  font-size: 0.84rem;
  overflow-wrap: anywhere;
}

.finanzas-pendiente-item-nota {
  color: var(--muted-foreground);
  font-size: 0.7rem;
}

.finanzas-pendiente-item-monto {
  font-size: 0.84rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.finanzas-pendiente-totales {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.15rem 0.6rem;
  padding-top: 0.35rem;
  border-top: 1px solid var(--border);
  color: var(--muted-foreground);
  font-size: 0.78rem;
}

.finanzas-pendiente-total-monto {
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.finanzas-pendiente-totales .total-fuerte {
  color: var(--foreground);
  font-weight: 650;
}

.finanzas-pendiente-boton.boton-detalle {
  color: var(--primary);
}

.finanzas-pendientes-pie {
  padding: 0.2rem 0.1rem 0;
  color: var(--muted-foreground);
  font-size: 0.74rem;
}

/* Configuración: cuentas de correo y ajustes de búsqueda */

.finanzas-correo {
  margin-top: 1.4rem;
}

.finanzas-correo-titulo {
  margin: 0 0 0.2rem;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.finanzas-correo-cuentas {
  grid-template-columns: minmax(0, 1fr);
  margin: 0.4rem 0 0.8rem;
}

.finanzas-correo-cuenta {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.finanzas-correo-cuenta-datos {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.finanzas-correo-cuenta-direccion {
  display: block;
  min-width: 0;
  font-size: 0.86rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.finanzas-correo-cuenta-detalle {
  color: var(--muted-foreground);
  font-size: 0.74rem;
}

.finanzas-correo-cuenta-error {
  color: var(--destructive);
  font-size: 0.74rem;
}

.finanzas-correo-cuenta-botones {
  display: flex;
  gap: 0.35rem;
  align-items: center;
  flex: none;
}

.finanzas-correo-cuenta-chip {
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--muted-foreground);
  font-size: 0.72rem;
}

.finanzas-correo-fields {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.6rem;
  margin: 0.2rem 0 0.6rem;
}

@media (max-width: 720px) {
  .finanzas-pendientes-cabecera {
    flex-wrap: wrap;
  }

  .finanzas-pendientes-cabecera h3 {
    white-space: nowrap;
  }

  .finanzas-pendientes-cabecera .finanzas-boton-ghost {
    white-space: nowrap;
  }

  .finanzas-pendiente-fila {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  }

  .finanzas-pendiente-detalle {
    flex: 1 1 8rem;
  }

  .finanzas-pendiente-categoria {
    order: 4;
    flex: 1 1 8rem;
    min-height: 40px;
  }

  .finanzas-pendiente-monto {
    order: 3;
  }

  /* El concepto (título del gasto) baja 2px: más densidad en el ancho de
     pantalla (revisión de Santiago, 12-sep-2026). */
  .finanzas-pendiente-concepto {
    font-size: 0.875rem;
  }

  .finanzas-pendiente-acciones {
    order: 5;
  }

  .finanzas-pendiente-edicion {
    grid-template-columns: 1fr;
  }

  .finanzas-pendiente-edicion .finanzas-pendiente-input {
    min-height: 44px;
  }

  .finanzas-correo-fields {
    grid-template-columns: 1fr;
  }
}

/* WebKit/iOS amplía la página (autozoom) al enfocar un control con letra
   menor a 16px: el encuadre salta y la vista queda descoordinada. En
   pantallas angostas o punteros táctiles los campos del módulo de finanzas
   suben a 1rem; en escritorio conservan su densidad (0.88rem). */
@media (max-width: 720px), (pointer: coarse) {
  .finanzas-field input,
  .finanzas-field select,
  .finanzas-categoria-rapida input,
  .finanzas-pendiente-input,
  .finanzas-pendiente-categoria,
  .finanzas-field .finanzas-calendario-campo {
    font-size: 1rem;
  }

  /* Los select de categoría de los flujos de Fijos y Pendientes se dibujan
     ~14px con el truco de transform: el control conserva su font-size de 16px
     (el umbral de iOS se evalúa sobre lo declarado) y queda alineado con el
     resto de la fila (revisión de Santiago, 12-sep-2026). Ronda 6
     (t_0ca41d80): el select de la CAPTURA sale del truco —con todos los campos
     a 16px y 44px de alto, encogerlo lo dejaría como la única caja de 38.5 px
     y rompería el alto único del formulario. */
  #finanzas-fijo-categoria,
  .finanzas-pendiente-categoria {
    transform: scale(0.875);
    transform-origin: left center;
  }

  /* Ronda 8 (t_3f3dff4b): el alto de los OCHO controles de la captura es UNO
     solo —44 px, el mínimo táctil— y EXPLÍCITO, no emergente. Medido en
     Chrome los ocho ya daban 44.00 px (Δ0): la diferencia visible entre el
     selector y los campos era el line-height (normal vs 24px) y la apariencia
     nativa, no el alto. Con la altura clavada, el control nativo del selector
     o del date picker no puede desviarla al dibujarse. */
  .finanzas-form-en-tarjeta #finanzas-fecha,
  .finanzas-form-en-tarjeta #finanzas-concepto,
  .finanzas-form-en-tarjeta #finanzas-categoria,
  .finanzas-form-en-tarjeta #finanzas-moneda,
  .finanzas-form-en-tarjeta #finanzas-monto,
  .finanzas-form-en-tarjeta #finanzas-monto-ext,
  .finanzas-form-en-tarjeta .finanzas-categoria-mas,
  .finanzas-form-en-tarjeta #finanzas-guardar,
  .finanzas-form-en-tarjeta #finanzas-cancelar {
    height: 44px;
  }
}

/* ─── Movimientos: línea de tiempo del módulo ─── */

.finanzas-recientes-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
}

.finanzas-ver-todos {
  color: var(--muted-foreground);
  font-size: 0.78rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.finanzas-ver-todos:hover {
  color: var(--foreground);
}

.finanzas-movimientos-filtros {
  display: grid;
  /* Los filtros (Tipo · Moneda · Categoría · Origen) van en UNA sola fila en
     cualquier ancho (revisión de Santiago, 14-sep-2026: columnas iguales;
     22-sep-2026: entra Origen). Desde la ronda 3 (23-sep-2026) Origen es una
     píldora MÁS de la fila —mismo aspecto, control y tamaño que los selects.
     Ronda 5 (t_b95c50a8 · 23-sep-2026): Santiago decide que los cuatro van en
     UNA fila TAMBIÉN en el celular («sé que caben»): el ancho que falta se
     paga con rótulos acortados y elididos («…»), jamás envolviendo. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.6rem;
  margin: 0.6rem 0 0.8rem;
}

/* ─── La caja de los CUATRO controles es UNA sola (ronda 5b · t_d16192a7) ───
   Los tres selects y la píldora de Origen comparten la MISMA regla —no copias
   que puedan divergir—: alto, borde (grosor y color), fondo, radios, relleno
   simétrico y letra idénticos, y el texto CENTRADO en la caja. El relleno en
   línea (0.875rem) reserva el sitio del chevron en los dos costados, así que
   la etiqueta queda centrada sin quedar pegada a la flecha ni recortada; lo
   que no entra se ELIDE con «…» (nunca se desborda ni envuelve la fila).

   Los selects sueltan la apariencia nativa (`appearance: none`): en iOS el
   select se dibuja con métricas propias —por eso el mismo `rect` se veía más
   grande en Origen— y el chevron pasa a ser el MISMO svg en los cuatro, del
   mismo tamaño y color, al borde derecho. */
.finanzas-movimientos-filtros select,
.finanzas-movimientos-origen-pill {
  width: 100%;
  min-height: 44px;
  padding: 0.5rem 0.875rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  font-size: 0.88rem;
  text-align: center;
  text-overflow: ellipsis;
  appearance: none;
  -webkit-appearance: none;
  overflow: hidden;
  cursor: pointer;
}

/* El select de la fila viaja en su envoltura: el ancla del chevron. */
.finanzas-movimientos-control {
  position: relative;
  display: block;
  min-width: 0;
}

/* El chevron de la fila: el mismo svg para los cuatro (mismo tamaño y color),
   flotando dentro del relleno derecho —fuera del texto y sin robar el toque—. */
.finanzas-filtro-chevron {
  position: absolute;
  right: 0.25rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--foreground);
  pointer-events: none;
  transition: transform 0.15s ease;
}

/* La píldora de Origen: la caja de arriba y, dentro, su etiqueta centrada (el
   span crece a todo lo ancho). Cerrada muestra el estado; al tocarla abre la
   lista de casillas. */
.finanzas-movimientos-origen-pill {
  position: relative;
  display: flex;
  align-items: center;
}

.finanzas-movimientos-origen-pill:hover,
.finanzas-movimientos-origen-pill[aria-expanded="true"] {
  border-color: var(--ring);
}

.finanzas-movimientos-origen-pill-texto {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Abierta, la flecha de Origen gira —y conserva su centrado vertical—. */
.finanzas-movimientos-origen-pill[aria-expanded="true"] .finanzas-filtro-chevron {
  transform: translateY(-50%) rotate(180deg);
}

/* Lista de casillas: panel flotante anclado a la píldora (no empuja la
   maquetación). Cada fila es un toque de 44 px que alterna SIN cerrarse; el
   estado marcado se distingue por relleno, borde Y la marca «✓». */
.finanzas-origen-panel {
  position: fixed;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.3rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 4px);
  background: var(--card);
  box-shadow: 0 18px 44px hsl(240 10% 3.9% / 0.3);
}

.finanzas-origen-panel[hidden] {
  display: none;
}

.finanzas-origen-opcion {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 44px;
  padding: 0.25rem 0.55rem;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--foreground);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.finanzas-origen-opcion:hover {
  background: var(--secondary);
}

.finanzas-origen-casilla {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 22px;
  height: 22px;
  border: 1.5px solid var(--border);
  border-radius: 6px;
  background: var(--background);
  color: transparent;
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1;
}

.finanzas-origen-opcion[aria-checked="true"] {
  background: var(--secondary);
}

.finanzas-origen-opcion[aria-checked="true"] .finanzas-origen-casilla {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--primary-foreground);
}

/* Uniformidad de la fila en el celular (ronda 4 · 23-sep-2026). Va DESPUÉS de
   las bases de la píldora y de las filas de su lista: la misma regla escrita
   antes (en el bloque de autozoom) la anulaba el orden de la cascada y la
   píldora quedaba en 0.88rem mientras los selects subían a 1rem.

   Ronda 5b (t_d16192a7): los CUATRO suben juntos a 1rem —también los selects,
   que ahora declaran su letra en la caja común— y el relleno en línea ya no se
   recorta aquí: la reserva del chevron (0.875rem en la caja común) es la misma
   en todos los anchos y así la etiqueta sigue centrada. Lo que no entra —la
   categoría, los rótulos largos— se ELIDE con «…», nunca se envuelve. */
@media (max-width: 720px), (pointer: coarse) {
  .finanzas-movimientos-filtros select,
  .finanzas-movimientos-origen-pill,
  .finanzas-origen-opcion {
    font-size: 1rem;
  }
}

@media (max-width: 720px) {
  .finanzas-movimientos-filtros {
    /* Ronda 5 (t_b95c50a8): los CUATRO comparten UNA sola fila también aquí
       —decisión de Santiago—: mismas cuatro columnas que en escritorio, con
       el aire entre columnas recortado (0.3rem) para que quepan. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.3rem;
  }
  .finanzas-movimientos-filtros .finanzas-field-label {
    font-size: 0.62rem;
  }
}

.finanzas-movimientos-totales {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem 1.4rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--secondary);
}

.finanzas-movimientos-total {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.finanzas-movimientos-total strong {
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
}

.finanzas-movimientos-controles {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin: 0.7rem 0 0.4rem;
}

.finanzas-movimientos-conteo {
  color: var(--muted-foreground);
  font-weight: 600;
}

.finanzas-movimientos-lista {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.finanzas-movimiento {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* Fila minimalista (22-sep-2026): sin botones de acción el aire vertical se
     recorta y las zonas táctiles absorben la diferencia con márgenes negativos
     —la densidad sube sin perder áreas de 44 px. */
  gap: 0.35rem 0.5rem;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.finanzas-movimiento-descartado {
  border-style: dashed;
  color: var(--muted-foreground);
}

/* Zonas táctiles de la edición rápida —fecha · concepto/categoría · valor—:
   el control mide 44 px de alto real (el mínimo cómodo), pero ocupa 32 px de
   rejilla gracias al margen negativo: la fila no crece por ellos. */
.finanzas-movimiento-fecha[data-rapida],
.finanzas-movimiento-cuerpo[data-rapida],
.finanzas-movimiento-monto[data-rapida] {
  appearance: none;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  min-height: 44px;
  margin-block: -6px;
  padding: 0.15rem 0.2rem;
  border-radius: var(--radius);
  transition: background-color 0.15s ease;
}

.finanzas-movimiento-fecha[data-rapida]:hover,
.finanzas-movimiento-cuerpo[data-rapida]:hover,
.finanzas-movimiento-monto[data-rapida]:hover {
  background: var(--secondary);
}

.finanzas-movimiento-fecha[data-rapida]:focus-visible,
.finanzas-movimiento-cuerpo[data-rapida]:focus-visible,
.finanzas-movimiento-monto[data-rapida]:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/* Cuña del extremo derecho: el afordante visible de la ficha. */
.finanzas-movimiento-cuna {
  appearance: none;
  background: none;
  border: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  min-width: 44px;
  min-height: 44px;
  margin: -6px -4px -6px 0;
  border-radius: var(--radius);
  color: var(--muted-foreground);
  cursor: pointer;
}

.finanzas-movimiento-cuna:hover {
  color: var(--foreground);
  background: var(--secondary);
}

/* Los descartados solo se ven con el toggle: conservan su única acción. */
.finanzas-movimiento-restaurar {
  flex: none;
  min-height: 34px;
}

.finanzas-movimiento-fecha {
  color: var(--muted-foreground);
  font-size: 0.78rem;
  white-space: nowrap;
  min-width: 3.2rem;
}

@media (max-width: 720px) {
  .finanzas-movimiento-fecha {
    min-width: 0;
  }
}

.finanzas-movimiento-cuerpo {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  flex: 1 1 10rem;
}

.finanzas-movimiento-concepto {
  font-size: 0.88rem;
  overflow-wrap: anywhere;
}

.finanzas-movimiento-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem;
}

.finanzas-movimiento-chip {
  padding: 0.05rem 0.45rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.68rem;
  color: var(--muted-foreground);
}

.finanzas-movimiento-chip.chip-descartado {
  border-color: var(--destructive);
  color: var(--destructive);
}

.finanzas-movimiento-monto {
  font-size: 0.88rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Valor + cuña: un solo bloque que se pega al extremo derecho de la fila. */
.finanzas-movimiento-final {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
}

/* ─── Edición rápida por secciones (22-sep-2026) ───
   El toque sobre una sección de la tarjeta la convierte en su control ahí
   mismo, con Guardar/Cancelar al lado. Todo el modo es cancelable (tocar fuera
   o «Cancelar») y nunca escribe por accidente.
   Fluidez (22-sep-2026, revisión de Santiago en el iPhone): el editor es una
   CAPA FLOTANTE sobre la fila —la fila conserva su contenido y su alto, y la
   lista no se mueve—, no un formulario en el flujo. */
.finanzas-rapida-abierta {
  position: relative;
  z-index: 6;
}

.finanzas-rapida {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 0.35rem 0.45rem;
  width: calc(100% - 4px);
  padding: 0.35rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  /* Tapa lo que deja debajo: la fila sigue ahí, intacta, sin saltar. */
  background: var(--card);
  box-shadow: 0 14px 34px hsl(240 10% 3.9% / 0.22);
}

.finanzas-rapida-campo {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
  flex: 1 1 8rem;
}

.finanzas-rapida-valor .finanzas-rapida-campo {
  flex: 1 1 7rem;
}

/* Editor del concepto: concepto y categoría se reparten la línea con anchos
   EXPLÍCITOS (4 partes / 3 partes, cada uno con mínimo legible) y las dos
   acciones circulares cierran la fila. La línea no se envuelve ni desborda:
   eso es lo que hace que el editor quepa dentro de la tarjeta, a 320 px
   incluidos. Antes los dos campos iban a 1:1 y las acciones caían a un segundo
   renglón (la fila medía 90,8 px de alto con el editor abierto). */
.finanzas-rapida-concepto {
  flex-wrap: nowrap;
}

.finanzas-rapida-concepto .finanzas-rapida-campo-concepto {
  flex: 4 1 0;
  min-width: 5.5rem;
}

.finanzas-rapida-concepto .finanzas-rapida-campo-categoria {
  flex: 3 1 0;
  min-width: 4.5rem;
}

.finanzas-rapida-label {
  color: var(--muted-foreground);
  font-size: 0.68rem;
  line-height: 1.1;
}

.finanzas-rapida-control {
  min-height: 44px;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--input);
  border-radius: var(--radius);
  background: var(--background);
  color: var(--foreground);
  font-size: 0.88rem;
  font-variant-numeric: tabular-nums;
}

/* El campo de fecha no es un input: es el botón que abre el calendario propio.
   Se dibuja como el resto de los controles del editor. */
.finanzas-rapida-fecha-campo,
.finanzas-calendario-campo {
  text-align: left;
  cursor: pointer;
}

.finanzas-rapida-acciones {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.4rem;
  flex: none;
}

.finanzas-rapida-acciones button {
  min-height: 44px;
  flex: none;
}

/* ✓ y ✗: un círculo de 44 px cada uno, sin texto — el mismo par en los tres
   editores rápidos, al final de la línea de los campos. Ocupan 94 px donde los
   dos botones rotulados ocupaban 167: eso es lo que deja la línea en UNA sola.
   El color no es la única información: llevan aria-label y title. */
.finanzas-rapida-accion {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  min-width: 44px;
  height: 44px;
  min-height: 44px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--background);
  cursor: pointer;
}

.finanzas-rapida-accion svg {
  width: 22px;
  height: 22px;
  display: block;
}

.finanzas-rapida-accion:hover {
  background: var(--accent);
}

.finanzas-rapida-accion:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

.finanzas-rapida-accion-guardar {
  color: var(--finanzas-rapida-guardar);
  border-color: color-mix(in srgb, var(--finanzas-rapida-guardar) 45%, var(--border));
}

.finanzas-rapida-accion-cancelar {
  color: var(--finanzas-rapida-cancelar);
  border-color: color-mix(in srgb, var(--finanzas-rapida-cancelar) 45%, var(--border));
}

/* Chip del tipo en el editor del valor: muestra el tipo deducido del signo y
   lo corrige con un toque. Ancho estable: digitar no lo redimensiona. */
.finanzas-rapida-tipo {
  appearance: none;
  flex: none;
  min-width: 4.6rem;
  min-height: 44px;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--muted-foreground);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}

.finanzas-rapida-tipo.tipo-gasto {
  color: var(--destructive);
  border-color: color-mix(in srgb, var(--destructive) 45%, var(--border));
}

.finanzas-rapida-tipo.tipo-ingreso {
  color: var(--success);
  border-color: color-mix(in srgb, var(--success) 45%, var(--border));
}

/* iOS/iPadOS amplía la página (autozoom) al enfocar un control cuya letra
   declarada baja de 16 px: el encuadre salta, los botones parecen agrandarse y
   la interfaz se siente torpe. En pantallas angostas o punteros táctiles el
   editor rápido DECLARA 1rem (el umbral que evalúa iOS) y se DIBUJA a 0.875
   —el mismo truco ya validado en los selects de categoría—, así el texto queda
   del tamaño del resto de la fila sin que la pantalla se vuelva a encuadrar.
   Ojo: esta regla va DESPUÉS de la base; antes quedaba tapada por ella, y el
   recorte se limita al editor rápido: el campo de fecha del formulario
   detallado se dibuja como los demás campos (16 px, 44 px de alto). */
@media (max-width: 720px), (pointer: coarse) {
  .finanzas-rapida .finanzas-rapida-control {
    font-size: 1rem;
    transform: scale(0.875);
    transform-origin: left center;
  }
}

/* ─── Calendario compacto propio (edición rápida y formulario detallado) ───
   Sustituye al selector nativo de iOS: flota anclado a su campo (~344 px,
   celdas de 44 px), no cambia el tamaño de la pantalla, no empuja la
   maquetación y se cierra al elegir el día. */
/* Single-date picker inherits the principal calendar geometry. Only its
   viewport placement differs; no second set of day/header dimensions. */
body.shell-ios .finanzas-calendario-mini { position: fixed; right: auto; z-index: 40; }
.finanzas-calendario-mini[hidden] {
  display: none;
}

/* Editor en la fila · rejilla responsiva (pedido de Santiago, 22-sep-2026):
   en el celular los campos dejaron de apilarse uno por fila — cada campo
   declara su tamaño (corto · tres por fila, medio · dos por fila, dos-tercios ·
   dos por fila con el ancho a favor de la categoría, ancho · bloque propio) y
   la rejilla reparte. Desde 320 px los campos cortos y medios comparten fila
   (fecha + tipo, categoría + monto, moneda + tasa/acciones) sin recortar
   ninguna etiqueta; la nota larga (Concepto) conserva su bloque. En pantallas
   anchas (≥1100 px) campos y acciones caben en una sola línea. */
.finanzas-movimiento-edicion {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0.5rem 0.6rem;
  width: 100%;
  align-items: end;
}

.finanzas-movimiento-edicion .finanzas-campo-corto {
  grid-column: span 2;
}

.finanzas-movimiento-edicion .finanzas-campo-medio {
  grid-column: span 3;
}

/* Dos tercios: para el campo que necesita ancho sin llegar al bloque propio
   (la categoría, con nombres largos reales: a 320 px sigue entrando entera). */
.finanzas-movimiento-edicion .finanzas-campo-dos-tercios {
  grid-column: span 4;
}

.finanzas-movimiento-edicion .finanzas-campo-ancho {
  grid-column: 1 / -1;
}

.finanzas-movimiento-edicion-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  grid-column: span 3;
}

@media (min-width: 1100px) {
  /* Escritorio ancho: una sola línea de campos con el monto junto a la fecha,
     el concepto al centro y las acciones al final; Tasa y COP cobrado (solo
     movimientos extranjeros) bajan a su propia fila sin dejar huérfanos. */
  .finanzas-movimiento-edicion {
    /* Los selectores se miden por contenido (`auto`): su etiqueta entra com-
       pleta incluso con el nombre de categoría más largo. El ancho sobrante va
       a los campos de texto (concepto, monto, fecha), que no recortan. */
    grid-template-columns:
      minmax(7rem, 0.9fr) auto minmax(0, 1.6fr) auto
      minmax(7rem, 0.9fr) auto auto;
  }

  .finanzas-movimiento-edicion .finanzas-movimiento-campo {
    grid-column: auto;
  }

  .finanzas-movimiento-edicion-acciones {
    grid-column: 7 / 8;
    grid-row: 1;
  }
}

/* Conexión de Outlook (código de dispositivo) */
.finanzas-correo-outlook {
  display: grid;
  gap: 8px;
  margin-top: 12px;
}
.finanzas-correo-outlook-codigo {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.35rem;
  letter-spacing: 0.14em;
}

/* Cuentas de correo: chips de proveedor e iconos de origen */
.finanzas-correo [hidden] {
  display: none;
}
.finanzas-correo-conectar {
  display: flex;
  gap: 0.6rem;
  margin: 0.2rem 0 0.8rem;
}
.finanzas-correo-proveedor {
  color: var(--foreground);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: transparent;
  cursor: pointer;
  transition: border-color 150ms ease;
}
.finanzas-correo-proveedor:hover,
.finanzas-correo-proveedor:focus-visible {
  border-color: var(--primary);
}
.finanzas-correo-cuenta-principal {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
}
.finanzas-correo-cuenta-icono {
  flex: none;
  width: 22px;
  height: 22px;
}
.finanzas-pendiente-icono {
  display: inline-block;
  width: 14px;
  height: 14px;
  vertical-align: -2px;
}

.finanzas-correo-outlook-enlace {
  display: inline-block;
  margin-top: 0.35rem;
  color: var(--primary);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.finanzas-correo-outlook-codigo-fila {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0.35rem 0;
}

.finanzas-correo-cuenta-linea {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
}
.finanzas-correo-cuenta-check {
  flex: none;
}

.finanzas-correo-cuenta-botones .finanzas-boton-ghost {
  padding: 0.2rem 0.5rem;
  font-size: 0.74rem;
}
.finanzas-correo-cuenta .finanzas-correo-cuenta-linea {
  flex: 1;
}

/* ─── Ficha de gasto (SPEC 006): popup de detalle por movimiento ─── */

.finanzas-movimiento-tocable {
  cursor: pointer;
}
.finanzas-movimiento-tocable:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

.finanzas-ficha-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: hsl(240 10% 3.9% / 0.5);
}
.finanzas-ficha-overlay[hidden] {
  display: none;
}

.finanzas-ficha {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  width: min(100%, 28rem);
  max-height: min(85vh, 40rem);
  overflow-y: auto;
  padding: 1rem 1.1rem 1.2rem;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 8px);
  background: var(--card);
  color: var(--card-foreground);
  box-shadow: 0 24px 60px -20px hsl(240 10% 3.9% / 0.5);
}

.finanzas-ficha-cabecera {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}
.finanzas-ficha-titulo {
  margin: 0;
  font-size: 1.05rem;
  line-height: 1.25;
}
.finanzas-ficha-cerrar {
  flex: none;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--secondary);
  color: var(--secondary-foreground);
  font-size: 0.8rem;
  cursor: pointer;
}
.finanzas-ficha-cerrar:hover {
  background: var(--accent);
}

/* Acciones de la ficha (22-sep-2026): Editar y Eliminar —ya no viven en la
   fila—; eliminar pide confirmación en el mismo pie. */
.finanzas-ficha-acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

.finanzas-ficha-acciones button {
  min-height: 44px;
}

/* Eliminar es destructivo donde viva (antes en la fila, ahora en la ficha). */
.finanzas-ficha-acciones .boton-eliminar {
  color: var(--destructive);
}

.finanzas-ficha-confirmacion {
  flex: 1 1 100%;
  color: var(--destructive);
  font-size: 0.85rem;
  line-height: 1.35;
}

.finanzas-ficha-monto {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem;
  margin: 0;
  font-size: 1.35rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.finanzas-ficha-monto-aprox {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--muted-foreground);
}
.finanzas-ficha-monto-aprox.sin-convertir {
  color: var(--warning);
}

.finanzas-ficha-campos,
.finanzas-ficha-lineas {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.75rem;
  row-gap: 0.3rem;
  margin: 0;
  font-size: 0.9rem;
}
.finanzas-ficha-etiqueta {
  color: var(--muted-foreground);
}
.finanzas-ficha-valor {
  margin: 0;
  text-align: right;
  overflow-wrap: anywhere;
}

.finanzas-ficha-origen {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}
.finanzas-ficha-origen-titulo {
  margin: 0;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted-foreground);
}
.finanzas-ficha-aviso {
  margin: 0;
  font-size: 0.85rem;
  color: var(--muted-foreground);
}
.finanzas-ficha-items {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0.15rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.9rem;
}
.finanzas-ficha-item {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.finanzas-ficha-item-nombre {
  flex: 1;
  min-width: 0;
}
.finanzas-ficha-item-cantidad {
  font-size: 0.82rem;
  color: var(--muted-foreground);
}
.finanzas-ficha-item-subtotal {
  font-variant-numeric: tabular-nums;
}

/* Móvil: la ficha entra como panel inferior deslizante. */
@media (max-width: 720px) {
  .finanzas-ficha-overlay {
    align-items: flex-end;
    padding: 0;
  }
  .finanzas-ficha {
    width: 100%;
    max-height: 88vh;
    border-bottom: none;
    border-radius: calc(var(--radius) + 10px) calc(var(--radius) + 10px) 0 0;
    padding-bottom: calc(1.2rem + env(safe-area-inset-bottom));
  }
}

/* Con la ficha abierta, el fondo no scrollea. */
body.finanzas-ficha-abierta {
  overflow: hidden;
}

/* ─── Tono característico de categoría (SPEC 006 · iteración) ─── */
/* El chip de la ficha comparte el lenguaje visual del chip de las filas:
   mismo hue estable por categoría, tamaño mayor para destacar a simple vista. */

.finanzas-ficha-categoria {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: hsl(var(--cat-hue, 240) 72% 93%);
  color: hsl(var(--cat-hue, 240) 45% 28%);
  border: 1px solid hsl(var(--cat-hue, 240) 55% 84%);
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}

:root[data-tema="oscuro"] .finanzas-categoria-chip,
:root[data-tema="oscuro"] .finanzas-ficha-categoria {
  background: hsl(var(--cat-hue, 240) 32% 24%);
  color: hsl(var(--cat-hue, 240) 70% 78%);
  border-color: hsl(var(--cat-hue, 240) 28% 38%);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-tema]) .finanzas-categoria-chip,
  :root:not([data-tema]) .finanzas-ficha-categoria {
    background: hsl(var(--cat-hue, 240) 32% 24%);
    color: hsl(var(--cat-hue, 240) 70% 78%);
    border-color: hsl(var(--cat-hue, 240) 28% 38%);
  }
}

/* ─── Filtro de tipo (SPEC 006 · iteración 2): Gasto en rojo, Ingreso en verde ─── */

#finanzas-movimientos-tipo.es-gasto {
  color: var(--destructive);
  border-color: color-mix(in srgb, var(--destructive) 45%, var(--border));
}
#finanzas-movimientos-tipo.es-ingreso {
  color: var(--success);
  border-color: color-mix(in srgb, var(--success) 45%, var(--border));
}
#finanzas-movimientos-tipo option[value="gasto"] {
  color: var(--destructive);
}
#finanzas-movimientos-tipo option[value="ingreso"] {
  color: var(--success);
}

/* ─── Selector de color de categoría (SPEC 006 · iteración 3) ─── */

.finanzas-categoria-color-boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--secondary);
  cursor: pointer;
  flex: none;
}
.finanzas-color-swatch {
  width: 1.15rem;
  height: 1.15rem;
  border-radius: 999px;
  background: hsl(var(--cat-hue, 240) 65% 52%);
  border: 1px solid hsl(var(--cat-hue, 240) 60% 42% / 0.55);
}

.finanzas-color-catalogo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.3rem 0 0;
  padding: 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--background);
}
.finanzas-color-item {
  width: 2rem;
  height: 2rem;
  border: 2px solid transparent;
  border-radius: 999px;
  background: hsl(var(--cat-hue, 240) 65% 52%);
  cursor: pointer;
  flex: none;
}
.finanzas-color-item.es-actual {
  border-color: var(--foreground);
  box-shadow: inset 0 0 0 2px var(--background);
}
.finanzas-color-automatico {
  width: auto;
  padding: 0 0.7rem;
  border: 2px solid var(--border);
  border-radius: 999px;
  background: var(--secondary);
  color: var(--secondary-foreground);
  font-size: 0.72rem;
  font-weight: 650;
}
.finanzas-color-automatico.es-actual {
  border-color: var(--foreground);
  box-shadow: none;
}

/* ─── Captura en la tarjeta y pop-up de confirmación (ronda 2 · t_d2d66a4e) ──
   Un toque en − / + transforma la tarjeta: a la izquierda del botón pulsado
   aparecen cámara y micrófono —44 px reales de área táctil— y los campos de
   alta se mudan DENTRO de la tarjeta (una sola instancia del formulario).
   Las tres vías —manual · foto · voz— terminan en el pop-up de confirmación;
   nada se guarda sin confirmar. */

.finanzas-card-botones {
  display: flex;
  flex: none;
  align-items: center;
  gap: 0.375rem;
}

.finanzas-card-accion {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--secondary);
  color: var(--foreground);
  cursor: pointer;
}

/* Ronda 2f: la cabecera no cambia de alto al entrar al modo captura. Las dos
   cajas altas (44 px de toque) se centran sobre el renglón del − / + (1.9rem)
   con margen negativo: aportan su área táctil sin empujar la fila, así el
   encabezado y los tres botones conservan su sitio (Δ = 0). */
.finanzas-card-botones .finanzas-card-accion {
  margin-block: calc((1.9rem - 44px) / 2);
}

.finanzas-card-accion[hidden] {
  display: none;
}

.finanzas-card-accion:hover {
  background: var(--accent);
}

.finanzas-card-accion:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/* Grabando: el micrófono queda marcado (aria-pressed) y late sin cambiar de
   tamaño —el estado se ve, no salta la maquetación—. */
.finanzas-card-accion[aria-pressed="true"] {
  border-color: var(--destructive);
  background: color-mix(in srgb, var(--destructive) 16%, transparent);
  color: var(--destructive);
}

@keyframes finanzas-captura-entra {
  from {
    opacity: 0;
    transform: translateX(8px) scale(0.92);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes finanzas-captura-late {
  0%, 100% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--destructive) 55%, transparent);
  }
  50% {
    box-shadow: 0 0 0 7px color-mix(in srgb, var(--destructive) 0%, transparent);
  }
}

/* Aparición breve de los dos botones: solo al desplegarse, reversible. */
.finanzas-card-botones .finanzas-card-accion:not([hidden]) {
  animation: finanzas-captura-entra 160ms ease-out;
}

.finanzas-card-accion[aria-pressed="true"] {
  animation: finanzas-captura-late 1.2s ease-in-out infinite;
}

/* Área táctil del − / + al menos 44 px sin agrandar su círculo visible. */
.finanzas-card-boton {
  position: relative;
}

.finanzas-card-boton::after {
  content: '';
  position: absolute;
  inset: -7px;
  border-radius: 999px;
}

.finanzas-card-boton[aria-expanded="true"] {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 45%, transparent);
}

/* El formulario vive DENTRO de la tarjeta: sin padding lateral propio (la
   tarjeta ya lo trae) y separado del contenido por una línea de puntos. */
.finanzas-form-en-tarjeta {
  margin-top: 0.7rem;
  padding: 0.15rem 0 0.3rem;
  border-top: 1px dashed var(--border);
}

.finanzas-form-en-tarjeta > h3 {
  margin-top: 0.35rem;
}

/* Ronda 8 (t_3f3dff4b): la fecha y la moneda bajan a su ancho MÍNIMO medido
   con píxeles y TODO lo liberado pasa a la categoría y al monto. La fecha
   muestra «dd/mm/aaaa» (92.22 px de valor, 16 px —umbral anti-autozoom de
   iOS—) más su relleno y el icono de calendario (10 px de tinta): por debajo
   de 118 px el valor se comprime contra el icono, así que su ancho es el
   mínimo con aire, 120.4 px. La moneda solo muestra la divisa («COP $»,
   48.7 px): con 70 px queda con aire frente a su flecha. Ambas cajas son de
   ancho FIJO (su contenido no crece); el resto del grid es elástico.

   El grid sigue siendo el de SEIS medias columnas, ahora repartidas así:
   C1 = 70 px (la moneda, la columna entera) y C2 = 44 px cierran juntas la
   caja de la fecha (70 + 6.4 de hueco + 44 = 120.4 px, la fecha ocupa C1–C2);
   el monto ocupa C2–C5; la C6 = 96 px clava el par ✗/✓ (44 + 8 + 44) al
   borde derecho; y C3–C5 (elásticas, 1fr) son las columnas que absorben la
   categoría (C3–C6) y el monto (C2–C5). A 390 el panel mide 320.41 px: la
   fecha queda en 120.4 (antes 157), la celda de la categoría en 193.61 (antes
   157), la moneda en 70 (antes 102.53) y el monto en 141.61 (antes 102.55)
   —el monto necesita 81.44 px para «8.500.000»: ahora le sobra aire—. A 428:
   fecha 120.4, categoría 231.61, moneda 70 y monto 179.61. Los controles de
   cada fila se alinean al fondo (align-items: end) para compartir top aunque
   un rótulo se parta en dos líneas. */
.finanzas-form-en-tarjeta .finanzas-fields {
  grid-template-columns: minmax(0, 70px) minmax(0, 44px) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) 44px;
  gap: 0.4rem;
  align-items: end;
}

.finanzas-form-en-tarjeta .finanzas-fields-fila,
.finanzas-form-en-tarjeta .finanzas-categoria-campo {
  display: contents;
}

/* Fila 1 (celular): la fecha ocupa C1–C2 (su ancho mínimo medido) y la celda
   de la categoría C3–C6 (todo el resto). Ojo: el hook va en la CELDA (el
   label #finanzas-fecha-campo), no en el input: el input no es ítem del grid
   y su ancho sale del 100 % de la celda (la regla de la ronda 6 apuntaba al
   input y no colocaba nada). */
.finanzas-form-en-tarjeta #finanzas-fecha-campo {
  grid-column: 1 / 3;
  grid-row: 1;
}

.finanzas-form-en-tarjeta #finanzas-categoria-field {
  grid-column: 3 / 7;
  grid-row: 1;
}

/* Fila 2 (celular): el concepto, solo, a fila completa. */
.finanzas-form-en-tarjeta .finanzas-field-concepto {
  grid-column: 1 / -1;
  grid-row: 2;
}

/* El editor del alta rápida se queda con la fila entera (las cajas de las
   filas de arriba son medias filas: ahí no cabe). Su fila es automática: cae
   debajo de las tres filas ocupadas, así que no empuja nada ni necesita
   condición: mientras está [hidden] no participa del grid. */

/* Fila 3 (celular): la moneda (C1, su ancho mínimo medido), el monto (C2–C5,
   todo el resto) y el par ✗/✓ (C6, 96 px exactos). */
.finanzas-form-en-tarjeta #finanzas-moneda-campo {
  grid-column: 1 / 2;
  grid-row: 3;
}

.finanzas-form-en-tarjeta #finanzas-monto-cop-campo,
.finanzas-form-en-tarjeta #finanzas-monto-ext-campo {
  grid-column: 2 / 6;
  grid-row: 3;
}

/* Los campos de apoyo de la moneda extranjera ocupan la fila completa. */
.finanzas-form-en-tarjeta #finanzas-tasa-campo,
.finanzas-form-en-tarjeta #finanzas-conversion-campo {
  grid-column: 1 / -1;
}

.finanzas-form-en-tarjeta .finanzas-actions-botones {
  grid-column: 6 / 7;
  grid-row: 3;
  align-self: end;
  justify-self: end;
  justify-content: flex-end;
  width: max-content;
}

@media (min-width: 721px) {
  /* Escritorio (ronda 6): los cinco campos en UNA fila de columnas iguales
     —fecha, concepto, categoría (con su «+» dentro), moneda y monto— y el par
     ✗/✓ al cierre, en la columna corta del borde. El reparto móvil en tres
     filas (rondas 7–8) no aplica: la fecha y el concepto conservan su sitio
     en la única fila. El editor del alta rápida sigue cayendo debajo, a fila
     completa. */
  .finanzas-form-en-tarjeta .finanzas-fields {
    grid-template-columns: repeat(5, minmax(0, 1fr)) auto;
    gap: 0.6rem;
  }

  .finanzas-form-en-tarjeta #finanzas-fecha-campo {
    grid-column: 1;
    grid-row: 1;
  }

  .finanzas-form-en-tarjeta .finanzas-field-concepto {
    grid-column: 2;
    grid-row: 1;
  }

  .finanzas-form-en-tarjeta #finanzas-categoria-field {
    grid-column: 3;
    grid-row: 1;
  }

  .finanzas-form-en-tarjeta #finanzas-moneda-campo {
    grid-column: 4;
    grid-row: 1;
  }

  .finanzas-form-en-tarjeta #finanzas-monto-cop-campo,
  .finanzas-form-en-tarjeta #finanzas-monto-ext-campo {
    grid-column: 5;
    grid-row: 1;
  }

  .finanzas-form-en-tarjeta #finanzas-tasa-campo,
  .finanzas-form-en-tarjeta #finanzas-conversion-campo {
    grid-column: 1 / 6;
  }

  .finanzas-form-en-tarjeta .finanzas-actions-botones {
    grid-column: 6;
    grid-row: 1;
  }
}

/* Ronda 6 (t_0ca41d80): los píxeles muertos del pie. El status —y su línea—
   no reservan alto mientras están vacíos: sin mensaje el formulario termina en
   la fila del valor, y cuando lo hay el mensaje aparece con su separación.
   Medición: antes el pie sumaba 15.36 px de línea vacía + 12 px de margen +
   4.8 px de relleno; ahora el relleno de la tarjeta es el único colchón. */
.finanzas-form-en-tarjeta .finanzas-actions {
  margin-top: 0;
}

.finanzas-form-en-tarjeta .finanzas-form-status:empty {
  display: none;
}

.finanzas-form-en-tarjeta .finanzas-actions .finanzas-form-status:not(:empty) {
  margin-top: 0.6rem;
}

/* Ronda 6: en móvil los campos de la captura ceden relleno lateral para que
   los valores entren en las cajas iguales. La fecha necesita 92.22 px de texto
   (16 px) y a 390 su caja mide 102.54: con 0.35rem por lado el valor se
   cortaba; el monto necesita 81.44 px (8.500.000) y los selectores, todo el
   ancho posible para el nombre de la categoría. */
@media (max-width: 720px) {
  .finanzas-form-en-tarjeta #finanzas-fecha {
    padding-left: 0.1rem;
    padding-right: 0.1rem;
  }

  .finanzas-form-en-tarjeta #finanzas-monto {
    padding-left: 0.4rem;
    padding-right: 0.4rem;
  }

  .finanzas-form-en-tarjeta .finanzas-field select {
    padding-left: 0.25rem;
    padding-right: 0.25rem;
  }
}

/* Ronda 2f: mientras la tarjeta registra, su título cede el sitio al rótulo
   del formulario («Registrar gasto» / «Registrar ingreso»). El rótulo viaja
   como capa absoluta sobre el título (que se apaga SIN soltar su caja): las
   dos capas comparten sitio, el cruce dura 180 ms y nada se desplaza. */
.finanzas-card .ds-card-header {
  position: relative;
}

.finanzas-rotulo-en-cabecera {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  margin: 0;
  pointer-events: none;
}

@keyframes finanzas-rotulo-entra {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes finanzas-rotulo-sale {
  from {
    opacity: 1;
    transform: none;
  }
  to {
    opacity: 0;
    transform: translateY(-4px);
    visibility: hidden;
  }
}

/* El cruce (entra y sale) es reversible: la clase manda y la animación se
   re-ejecuta al alternar. La clase de salida declara también su estado final
   (opacity 0 + visibility: hidden): fuera de render, el literal no cuenta ni
   aparece en innerText; con `prefers-reduced-motion` el estado es el mismo sin
   cruce. */
.finanzas-rotulo-entra {
  animation: finanzas-rotulo-entra 180ms ease-out both;
}

.finanzas-rotulo-sale {
  opacity: 0;
  visibility: hidden;
  animation: finanzas-rotulo-sale 180ms ease-in both;
}

/* Mientras la tarjeta registra, su fila de montos (total en COP y subtotales
   por moneda) se oculta TEMPORALMENTE: el espacio liberado lo ocupan los
   campos. Al salir del modo vuelve idéntica, en el mismo nodo. */
.finanzas-card-captura-abierta .ds-card-value {
  display: none;
}

/* Ronda 5c (t_e60505b8): el MISMO tratamiento para la lista de categorías con
   sus valores —ese era el bloque que faltaba liberar y hacía crecer la
   tarjeta—. Viaja el `ul` completo, así que el borde punteado de separación y
   sus márgenes se van con él: no queda hueco ni rótulo huérfanos. Es puro
   `display` sobre la clase que ya marca la tarjeta en captura: al salir, el
   mismo nodo vuelve idéntico —textos, orden y montos formateados byte a
   byte— en todas las salidas. */
.finanzas-card-captura-abierta .finanzas-categorias-lista {
  display: none;
}

/* Barra de grabación dentro de la tarjeta: contador y corte explícito. */
.finanzas-captura-grabacion {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.7rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid color-mix(in srgb, var(--destructive) 55%, var(--border));
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--destructive) 8%, transparent);
}

.finanzas-captura-grabacion[hidden] {
  display: none;
}

.finanzas-captura-grabacion-punto {
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 999px;
  background: var(--destructive);
  animation: finanzas-captura-late-punto 1.1s ease-in-out infinite;
}

@keyframes finanzas-captura-late-punto {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

.finanzas-captura-grabacion-texto {
  flex: 1 1 auto;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

.finanzas-captura-detener {
  min-height: 44px;
  flex: none;
}

/* Pop-up de confirmación: mismo lenguaje de la ficha (panel inferior en
   móvil), con los campos en dos columnas dentro del panel. */
.finanzas-captura .finanzas-captura-campos {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.finanzas-captura-sub {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.82rem;
  line-height: 1.35;
}

/* Lectura sin costo (dictado/recibo ➜ campos): bloque propio del pop-up, en
   columna, botones de 44 px y el resultado línea a línea (aplicado, vacíos,
   notas, ignorados del recibo, avisos). */
.finanzas-captura-lectura {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.2rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--border);
}

.finanzas-captura-lectura-titulo {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.finanzas-captura-lectura-ayuda {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.78rem;
  line-height: 1.35;
}

.finanzas-captura-lectura-texto {
  width: 100%;
  min-height: 4.25rem;
  resize: vertical;
  padding: 0.55rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  font-size: 0.9rem;
  line-height: 1.4;
}

.finanzas-captura-lectura-texto:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

.finanzas-captura-lectura-botones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.finanzas-captura-lectura-botones button {
  flex: 1 1 auto;
  min-height: 44px;
  justify-content: center;
}

.finanzas-captura-dictar.is-dictando {
  border-color: var(--destructive);
  color: var(--destructive);
}

.finanzas-captura-lectura-estado {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.finanzas-captura-lectura-linea {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.4;
}

.finanzas-captura-lectura-linea[data-tipo='aplicados'] {
  color: var(--success);
}

.finanzas-captura-lectura-linea[data-tipo='vacios'],
.finanzas-captura-lectura-linea[data-tipo='notas'] {
  color: var(--muted-foreground);
}

.finanzas-captura-lectura-linea[data-tipo='avisos'],
.finanzas-captura-lectura-estado.is-error .finanzas-captura-lectura-linea[data-tipo='mensaje'] {
  color: var(--destructive);
}

/* Campo que la lectura no pudo llenar: punteado hasta que la persona lo toca. */
.finanzas-captura [data-lectura='vacio'] {
  border-style: dashed;
  border-color: var(--destructive);
}

.finanzas-captura-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

.finanzas-captura-acciones button {
  flex: 1 1 auto;
  min-height: 44px;
  justify-content: center;
}

.finanzas-boton-gasto {
  background: var(--destructive);
  color: var(--destructive-foreground);
}

.finanzas-boton-ingreso {
  background: var(--success);
  color: #fff;
}

.finanzas-boton-gasto:disabled,
.finanzas-boton-ingreso:disabled {
  opacity: 0.55;
}

.finanzas-captura-adjuntos {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.2rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--border);
}

.finanzas-captura-adjuntos-titulo {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.finanzas-captura-adjunto {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.finanzas-captura-foto {
  width: 3.5rem;
  height: 3.5rem;
  object-fit: cover;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  flex: none;
}

.finanzas-captura-audio {
  max-width: 11rem;
  height: 2.5rem;
  flex: none;
}

.finanzas-captura-adjunto-datos {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}

.finanzas-captura-adjunto-nombre {
  overflow: hidden;
  font-size: 0.85rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.finanzas-captura-adjunto-meta {
  color: var(--muted-foreground);
  font-size: 0.75rem;
}

.finanzas-captura-quitar {
  flex: none;
  min-height: 44px;
}

.finanzas-captura-adjunto-nota {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 0.75rem;
  line-height: 1.4;
}

/* El input real de la foto: presente y tocable por el navegador, invisible. */
.finanzas-captura-foto-input {
  position: fixed;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .finanzas-card-botones .finanzas-card-accion:not([hidden]),
  .finanzas-card-accion[aria-pressed="true"],
  .finanzas-rotulo-entra,
  .finanzas-rotulo-sale,
  .finanzas-captura-grabacion-punto {
    animation: none;
  }
}

/* =========================================================
   Cadushi · identidad Pilo-clara (blanco / negro / lima)
   Inspiración de contraste Pilo; marca y copy propios de Cadushi.
   Forzado en claro: alto contraste, cards hero lima, tipografía bold.
   ========================================================= */

body.shell-ios {
  color-scheme: light;
  --cadushi-black: #0a0a0a;
  --cadushi-white: #ffffff;
  --cadushi-lime: #c8f542;
  --cadushi-lime-deep: #a8d92a;
  --cadushi-ink: #111111;
  --cadushi-mute: #5c5c5c;
  --cadushi-line: #e6e6e6;
  --cadushi-wash: #f3f3f3;
  --cadushi-bloom: #e11d48;
  --cadushi-cactus: var(--cadushi-black);
  --cadushi-cactus-bright: var(--cadushi-lime-deep);
  --cadushi-leaf: #3f6b1a;
  --background: var(--cadushi-white);
  --foreground: var(--cadushi-black);
  --card: var(--cadushi-white);
  --card-foreground: var(--cadushi-black);
  --primary: var(--cadushi-black);
  --primary-foreground: var(--cadushi-white);
  --secondary: var(--cadushi-wash);
  --secondary-foreground: var(--cadushi-black);
  --muted: var(--cadushi-wash);
  --muted-foreground: var(--cadushi-mute);
  --accent: var(--cadushi-lime);
  --accent-foreground: var(--cadushi-black);
  --border: var(--cadushi-line);
  --input: var(--cadushi-line);
  --ring: var(--cadushi-black);
  --success: var(--cadushi-leaf);
  --success-foreground: var(--cadushi-white);
  --destructive: var(--cadushi-bloom);
  --destructive-foreground: var(--cadushi-white);
  --radius: 1.35rem;
  --finanzas-tabbar-bg: hsl(0 0% 100% / 0.94);
  --finanzas-tabbar-fg: #6b6b6b;
  --finanzas-tabbar-fg-activo: var(--cadushi-black);
  --finanzas-tabbar-borde: #ececec;
  --finanzas-rapida-guardar: #2f5d12;
  --finanzas-rapida-cancelar: #b91c1c;
  background: var(--cadushi-white);
  color: var(--cadushi-black);
}

/* Modo oscuro del workspace: negro, blanco y la lima del logo.
   El claro de arriba no cambia. No alcanza a la apertura ni al logo. */
:root[data-tema="oscuro"] body.shell-ios {
  color-scheme: dark;
  --cadushi-white: #0a0a0a;
  --cadushi-black: #ffffff;
  --cadushi-lime: #C6F135;
  --cadushi-ink: #ffffff;
  --cadushi-mute: color-mix(in srgb, #ffffff 68%, #0a0a0a);
  --cadushi-line: color-mix(in srgb, #ffffff 24%, #0a0a0a);
  --cadushi-wash: color-mix(in srgb, #ffffff 10%, #0a0a0a);
  --background: #0a0a0a;
  --foreground: #ffffff;
  --card: #0a0a0a;
  --card-foreground: #ffffff;
  --popover: #0a0a0a;
  --popover-foreground: #ffffff;
  --primary: #ffffff;
  --primary-foreground: #0a0a0a;
  --secondary: color-mix(in srgb, #ffffff 10%, #0a0a0a);
  --secondary-foreground: #ffffff;
  --muted: color-mix(in srgb, #ffffff 10%, #0a0a0a);
  --muted-foreground: color-mix(in srgb, #ffffff 68%, #0a0a0a);
  --accent: #C6F135;
  --accent-foreground: #0a0a0a;
  --border: color-mix(in srgb, #ffffff 24%, #0a0a0a);
  --input: color-mix(in srgb, #ffffff 24%, #0a0a0a);
  --ring: #C6F135;
  --success: #C6F135;
  --success-foreground: #0a0a0a;
  --finanzas-tabbar-bg: color-mix(in srgb, #0a0a0a 92%, transparent);
  --finanzas-tabbar-fg: color-mix(in srgb, #ffffff 64%, #0a0a0a);
  --finanzas-tabbar-fg-activo: #ffffff;
  --finanzas-tabbar-borde: #ffffff;
  background: #0a0a0a;
  color: #ffffff;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-tema]) body.shell-ios {
    color-scheme: dark;
    --cadushi-white: #0a0a0a;
    --cadushi-black: #ffffff;
    --cadushi-lime: #C6F135;
    --cadushi-ink: #ffffff;
    --cadushi-mute: color-mix(in srgb, #ffffff 68%, #0a0a0a);
    --cadushi-line: color-mix(in srgb, #ffffff 24%, #0a0a0a);
    --cadushi-wash: color-mix(in srgb, #ffffff 10%, #0a0a0a);
    --background: #0a0a0a;
    --foreground: #ffffff;
    --card: #0a0a0a;
    --card-foreground: #ffffff;
    --popover: #0a0a0a;
    --popover-foreground: #ffffff;
    --primary: #ffffff;
    --primary-foreground: #0a0a0a;
    --secondary: color-mix(in srgb, #ffffff 10%, #0a0a0a);
    --secondary-foreground: #ffffff;
    --muted: color-mix(in srgb, #ffffff 10%, #0a0a0a);
    --muted-foreground: color-mix(in srgb, #ffffff 68%, #0a0a0a);
    --accent: #C6F135;
    --accent-foreground: #0a0a0a;
    --border: color-mix(in srgb, #ffffff 24%, #0a0a0a);
    --input: color-mix(in srgb, #ffffff 24%, #0a0a0a);
    --ring: #C6F135;
    --success: #C6F135;
    --success-foreground: #0a0a0a;
    --finanzas-tabbar-bg: color-mix(in srgb, #0a0a0a 92%, transparent);
    --finanzas-tabbar-fg: color-mix(in srgb, #ffffff 64%, #0a0a0a);
    --finanzas-tabbar-fg-activo: #ffffff;
    --finanzas-tabbar-borde: #ffffff;
    background: #0a0a0a;
    color: #ffffff;
  }
}

body.shell-ios .finanzas-large-title {
  color: var(--cadushi-black);
  font-size: clamp(1.9rem, 7.5vw, 2.45rem);
  font-weight: 780;
  letter-spacing: -0.05em;
}

/* «Gastos fijos» es más largo que «Resumen»: un cuerpo menor para que
   quede en una sola línea y no salte. */
body.shell-ios .finanzas-large-title.finanzas-titulo-fijos {
  font-size: clamp(1.55rem, 6.2vw, 2rem);
  letter-spacing: -0.045em;
  line-height: 1.15;
  white-space: nowrap;
}

body.shell-ios .finanzas-periodo-selector {
  border: 1.5px solid var(--cadushi-black);
  border-radius: 999px;
  background: var(--cadushi-white);
  color: var(--cadushi-black);
  font-weight: 700;
}

/* El selector del mes ocupa la esquina superior derecha, en la misma fila
   que el título. El botón de tema no vive aquí: está en configuración.
   El relleno ancho no vuelve. En el resumen, título y píldora se
   corren el radio de la tarjeta para coincidir con el arranque de la curva. */
body.shell-ios .finanzas-header {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding-left: 0;
  padding-right: 0;
  gap: 0.75rem;
}

/* En el resumen, título y píldora siguen el arranque de la curva de las
   tarjetas (radio 1.5rem), no el borde recto. Las tarjetas no se mueven. */
body.shell-ios:has(#finanzas-principal:not([hidden])) .finanzas-header {
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}

/* Optical baseline only: preserve the calendar selector and header layout. */
body.shell-ios:has(#finanzas-principal:not([hidden])) #finanzas-title {
  position: relative;
  top: -1.5px;
}

body.shell-ios:has(#finanzas-configuracion:not([hidden])) .finanzas-header {
  padding-right: 4.6rem;
}

body.shell-ios .finanzas-header-fila {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex: 1 1 auto;
  width: auto;
  gap: 0.65rem;
  min-width: 0;
}

body.shell-ios .finanzas-header-fila .finanzas-large-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

body.shell-ios .tema-toggle {
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  margin-left: 0;
  border: 1.5px solid var(--cadushi-black);
  border-radius: 999px;
  background: var(--cadushi-white);
  color: var(--cadushi-black);
}

body.shell-ios .finanzas-periodo {
  align-items: flex-end;
  flex: none;
  margin-left: auto;
}

body.shell-ios .finanzas-calendario {
  left: auto;
  right: 0;
}

body.shell-ios .finanzas-recientes {
  padding-left: 0;
  padding-right: 0;
}

body.shell-ios .finanzas-top-cards {
  display: grid;
  gap: 0.85rem;
  padding: 0 0 0.95rem;
}

body.shell-ios .finanzas-card.ds-card {
  padding: 1.15rem 1.2rem 1.2rem;
  border: 1.5px solid var(--cadushi-black);
  border-radius: 1.5rem;
  box-shadow: none;
  overflow: hidden;
}

/* Hero ingresos: lima sólida + tinta negra (patrón Pilo). */
body.shell-ios .finanzas-card-ingreso.ds-card {
  border-color: var(--cadushi-black);
  background: var(--cadushi-lime);
  color: var(--cadushi-black);
}

body.shell-ios .finanzas-card-ingreso .ds-card-header h3,
body.shell-ios .finanzas-card-ingreso .ds-card-unit,
body.shell-ios .finanzas-card-ingreso .finanzas-categorias-lista {
  color: color-mix(in srgb, var(--cadushi-black) 72%, transparent);
}

body.shell-ios .finanzas-card-ingreso .ds-card-value strong {
  color: var(--cadushi-black);
  font-size: clamp(1.9rem, 8vw, 2.5rem);
  font-weight: 800;
  letter-spacing: -0.05em;
}

body.shell-ios .finanzas-card-ingreso .finanzas-card-boton,
body.shell-ios .finanzas-card-gasto .finanzas-card-boton {
  width: 2.85rem;
  height: 2.85rem;
  border: none;
  background: #0a0a0a;
  box-shadow: none;
  animation: cadushi-asistente-respira 2.6s ease-in-out infinite;
  transform-origin: center;
  padding: 0;
  flex-shrink: 0;
  font-size: 1.35rem;
}

/* The approved Dev SVG has the same centered dimensions in Staging. */
body.shell-ios .finanzas-card-boton .finanzas-card-signo {
  display: block; flex: none; width: 1.25rem; height: 1.25rem; pointer-events: none;
}

body.shell-ios .finanzas-card-ingreso .finanzas-card-boton {
  color: var(--cadushi-lime);
}

body.shell-ios .finanzas-card-gasto .finanzas-card-boton {
  color: #ffffff;
}

body.shell-ios .finanzas-asistente[aria-expanded="true"] {
  animation-duration: 1.05s;
}

body.shell-ios .finanzas-asistente:active {
  animation: none;
  transform: scale(0.94);
}

@keyframes cadushi-asistente-respira {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.07);
  }
}

/* Gastos: card blanca, tipografía negra, acento coral solo en el monto. */
body.shell-ios .finanzas-card-gasto.ds-card {
  border-color: var(--cadushi-black);
  background: var(--cadushi-white);
}

body.shell-ios .finanzas-card-gasto .ds-card-header h3 {
  color: var(--cadushi-mute);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

body.shell-ios .finanzas-card-ingreso .ds-card-header h3 {
  color: color-mix(in srgb, var(--cadushi-black) 70%, transparent);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

body.shell-ios .finanzas-card-gasto .ds-card-value strong {
  color: var(--cadushi-bloom);
  font-size: clamp(1.75rem, 7vw, 2.25rem);
  font-weight: 800;
  letter-spacing: -0.045em;
}

body.shell-ios .finanzas-card .ds-card-value {
  margin-top: 0.4rem;
  margin-bottom: 0.4rem;
}

body.shell-ios .finanzas-card .ds-card-unit {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* Los dos títulos del resumen descansan sobre el borde, como rótulos
   elevados. Siguen siendo encabezados: no hay campos ni estado de foco.
   El monto comparte la primera fila con su acción y conserva el wrap. */
body.shell-ios .finanzas-top-cards > .finanzas-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 0.75rem;
  overflow: visible;
}

body.shell-ios .finanzas-top-cards > .finanzas-card > .ds-card-header {
  position: static;
  grid-column: 2;
  grid-row: 1;
  align-self: start;
}

body.shell-ios .finanzas-top-cards > .finanzas-card > .ds-card-header > h3 {
  position: absolute;
  inset: auto;
  top: -0.75px;
  left: 1.5rem;
  translate: 0 -50%;
  max-width: calc(100% - 3rem);
  padding: 0 0.35rem;
  border-radius: 0.2rem;
  background: var(--cadushi-white);
  line-height: 1.2;
  white-space: normal;
  overflow: visible;
  overflow-wrap: anywhere;
}

/* Ingresos ocupa una franja vertical dentro de la lima, de abajo hacia
   arriba. La tinta nunca cruza el fondo de la página ni tapa el borde. */
body.shell-ios .finanzas-top-cards > .finanzas-card-ingreso.ds-card {
  --finanzas-ingreso-gutter: 2.65rem;
  padding-left: var(--finanzas-ingreso-gutter);
  min-height: 7rem;
}

body.shell-ios .finanzas-top-cards > .finanzas-card-ingreso > .ds-card-header > h3 {
  background: transparent;
  color: #0a0a0a;
  display: block;
  left: 0.75rem;
  top: 50%;
  translate: 0 -50%;
  rotate: 180deg;
  writing-mode: vertical-rl;
  text-orientation: mixed;
  padding: 0;
  max-width: none;
  max-height: calc(100% - 2rem);
  white-space: nowrap;
}


body.shell-ios .finanzas-top-cards > .finanzas-card > .ds-card-value {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  min-width: 0;
  margin-top: 0;
}

body.shell-ios .finanzas-top-cards > .finanzas-card > .ds-card-value strong {
  max-width: 100%;
  white-space: normal;
  overflow-wrap: anywhere;
}

body.shell-ios .finanzas-top-cards > .finanzas-card > :is(.finanzas-categorias-lista, .finanzas-form, .finanzas-captura-grabacion) {
  grid-column: 1 / -1;
}

body.shell-ios #finanzas-recientes-title,
body.shell-ios #finanzas-pendientes-title {
  color: var(--cadushi-black);
  font-size: 1.1rem;
  font-weight: 750;
  letter-spacing: -0.025em;
  text-transform: none;
}

body.shell-ios #finanzas-recientes-title {
  font-size: 0.92rem;
}

body.shell-ios #finanzas-recientes .finanzas-fila {
  font-size: 0.74rem;
  padding: 0.4rem 0.5rem;
}

body.shell-ios .finanzas-ver-todos {
  color: var(--cadushi-black);
  font-weight: 700;
  text-decoration: none;
  border-bottom: 1.5px solid var(--cadushi-lime);
}

body.shell-ios .finanzas-lista {
  border: 1.5px solid var(--cadushi-black);
  border-radius: 1.25rem;
  background: var(--cadushi-white);
  overflow: hidden;
}

body.shell-ios .finanzas-pendientes {
  padding: 0.85rem 0 0;
}

body.shell-ios .finanzas-boton-ghost {
  border: 1.5px solid var(--cadushi-black);
  border-radius: 999px;
  background: var(--cadushi-white);
  color: var(--cadushi-black);
  font-weight: 650;
}

/* La barra mantiene tinta negra, disco claro y centro lima en ambos temas. */
body.shell-ios .finanzas-tabbar {
  overflow: visible;
  border: none;
  background: transparent;
  box-shadow: none;
}

body.shell-ios .finanzas-tabbar-tab[aria-current="page"] {
  color: #f0efef;
}

body.shell-ios .finanzas-tabbar-tab[data-iluminado="true"] {
  color: #171618;
}

body.shell-ios .finanzas-tabbar-alta {
  background: var(--cadushi-lime);
  color: #0a0a0a;
  border: none;
  animation: none;
}

body.shell-ios .app-sidebar {
  border-right: 1.5px solid var(--cadushi-black);
  background: var(--cadushi-white);
}

body.shell-ios .sidebar-brand-name {
  color: var(--cadushi-black);
  font-weight: 800;
}

body.shell-ios .identity-mark {
  background: var(--cadushi-lime);
  color: var(--cadushi-black);
  border: 1.5px solid var(--cadushi-black);
}

body.shell-ios .finanzas-module {
  position: relative;
  border: none;
  background: transparent;
  box-shadow: none;
}

/* El sol/luna solo existe dentro de configuración. Flota en la esquina
   superior derecha de esa pantalla, separado del borde. */
body.shell-ios .finanzas-tema-bar {
  position: absolute;
  z-index: 4;
  top: 0.35rem;
  right: 1.25rem;
}

@media (max-width: 720px) {
  body.shell-ios .finanzas-tema-bar {
    top: calc(0.55rem + env(safe-area-inset-top, 0px));
  }
}

/* Selector de calendario y de mes: el día de hoy usa la lima ya presente
   en ingresos, acento y alta rápida. Texto negro, el mismo par de la marca. */
body.shell-ios .finanzas-calendario-dia.es-hoy,
body.shell-ios .finanzas-calendario-dia.en-rango.es-hoy,
body.shell-ios .finanzas-calendario-grid-mes .finanzas-calendario-dia.en-rango.es-hoy,
body.shell-ios .finanzas-calendario-mini-dia.es-hoy:not(.es-elegido) {
  background: var(--cadushi-lime);
  color: var(--cadushi-black);
}

/* Sobre la lima, la tinta sigue negra: el negro del token ya es el blanco
   del papel oscuro, y blanco sobre #C6F135 no se lee. */
:root[data-tema="oscuro"] body.shell-ios .finanzas-card-ingreso.ds-card,
:root[data-tema="oscuro"] body.shell-ios .finanzas-tabbar-alta,
:root[data-tema="oscuro"] body.shell-ios .identity-mark,
:root[data-tema="oscuro"] body.shell-ios .finanzas-calendario-dia.es-hoy,
:root[data-tema="oscuro"] body.shell-ios .finanzas-calendario-dia.en-rango.es-hoy,
:root[data-tema="oscuro"] body.shell-ios .finanzas-calendario-grid-mes .finanzas-calendario-dia.en-rango.es-hoy,
:root[data-tema="oscuro"] body.shell-ios .finanzas-calendario-mini-dia.es-hoy:not(.es-elegido) {
  background: #C6F135;
  color: #0a0a0a;
  border-color: #0a0a0a;
}

:root[data-tema="oscuro"] body.shell-ios .finanzas-card-ingreso .ds-card-header h3,
:root[data-tema="oscuro"] body.shell-ios .finanzas-card-ingreso .ds-card-unit,
:root[data-tema="oscuro"] body.shell-ios .finanzas-card-ingreso .finanzas-categorias-lista,
:root[data-tema="oscuro"] body.shell-ios .finanzas-card-ingreso .ds-card-value strong {
  color: #0a0a0a;
}

:root[data-tema="oscuro"] body.shell-ios .finanzas-card-ingreso .finanzas-card-boton,
:root[data-tema="oscuro"] body.shell-ios .finanzas-card-gasto .finanzas-card-boton {
  background: #0a0a0a;
  color: #ffffff;
  border: none;
  box-shadow: none;
}

:root[data-tema="oscuro"] body.shell-ios .finanzas-card-ingreso .finanzas-card-boton {
  color: #C6F135;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-tema]) body.shell-ios .finanzas-card-ingreso.ds-card,
  :root:not([data-tema]) body.shell-ios .finanzas-tabbar-alta,
  :root:not([data-tema]) body.shell-ios .identity-mark,
  :root:not([data-tema]) body.shell-ios .finanzas-calendario-dia.es-hoy,
  :root:not([data-tema]) body.shell-ios .finanzas-calendario-dia.en-rango.es-hoy,
  :root:not([data-tema]) body.shell-ios .finanzas-calendario-grid-mes .finanzas-calendario-dia.en-rango.es-hoy,
  :root:not([data-tema]) body.shell-ios .finanzas-calendario-mini-dia.es-hoy:not(.es-elegido) {
    background: #C6F135;
    color: #0a0a0a;
    border-color: #0a0a0a;
  }

  :root:not([data-tema]) body.shell-ios .finanzas-card-ingreso .ds-card-header h3,
  :root:not([data-tema]) body.shell-ios .finanzas-card-ingreso .ds-card-unit,
  :root:not([data-tema]) body.shell-ios .finanzas-card-ingreso .finanzas-categorias-lista,
  :root:not([data-tema]) body.shell-ios .finanzas-card-ingreso .ds-card-value strong {
    color: #0a0a0a;
  }

  :root:not([data-tema]) body.shell-ios .finanzas-card-ingreso .finanzas-card-boton,
  :root:not([data-tema]) body.shell-ios .finanzas-card-gasto .finanzas-card-boton {
    background: #0a0a0a;
    color: #ffffff;
    border: none;
    box-shadow: none;
  }

  :root:not([data-tema]) body.shell-ios .finanzas-card-ingreso .finanzas-card-boton {
    color: #C6F135;
  }
}

@media (max-width: 720px) {
  body.shell-ios .finanzas-card.ds-card {
    box-shadow: none;
  }

  body.shell-ios .finanzas-tabbar {
    border-color: var(--cadushi-black);
  }
}

/* Transiciones entre subvistas / large title (Pilo-claro) */
@keyframes cadushi-subvista-in {
  from {
    opacity: 0;
    transform: translate3d(14px, 0, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@keyframes cadushi-title-in {
  from {
    opacity: 0;
    transform: translate3d(0, 6px, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@keyframes cadushi-tab-pop {
  from { transform: scale(0.92); opacity: 0.65; }
  to { transform: scale(1); opacity: 1; }
}

.finanzas-subvista-animar {
  animation: cadushi-subvista-in 280ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.finanzas-title-animar {
  animation: cadushi-title-in 240ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.finanzas-tabbar-tab.finanzas-tab-animar[aria-current="page"] > svg {
  animation: cadushi-tab-pop 220ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Ondas del botón central. Reflejan la grabación existente en las tarjetas.
   El indicador por sí solo no abre el micrófono ni llama a una API. */
.finanzas-tabbar-alta .cadushi-ondas {
  display: block;
}

.finanzas-tabbar-alta .cadushi-onda {
  transform-box: fill-box;
  transform-origin: center;
  fill: currentColor;
}

.finanzas-tabbar-alta[data-escuchando="true"] .cadushi-onda {
  animation-name: cadushi-onda;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}

.finanzas-tabbar-alta[data-escuchando="true"] .cadushi-onda:nth-child(1) {
  animation-duration: 1.05s;
  animation-delay: -0.2s;
}

.finanzas-tabbar-alta[data-escuchando="true"] .cadushi-onda:nth-child(2) {
  animation-duration: 0.9s;
  animation-delay: -0.45s;
}

.finanzas-tabbar-alta[data-escuchando="true"] .cadushi-onda:nth-child(3) {
  animation-duration: 1.2s;
  animation-delay: -0.1s;
}

.finanzas-tabbar-alta[data-escuchando="true"] .cadushi-onda:nth-child(4) {
  animation-duration: 0.95s;
  animation-delay: -0.6s;
}

.finanzas-tabbar-alta[data-escuchando="true"] .cadushi-onda:nth-child(5) {
  animation-duration: 1.1s;
  animation-delay: -0.3s;
}

@keyframes cadushi-onda {
  0%,
  100% {
    transform: scaleY(0.46);
  }
  50% {
    transform: scaleY(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .finanzas-subvista-animar,
  .finanzas-title-animar,
  .finanzas-tabbar-tab.finanzas-tab-animar[aria-current="page"] > svg,
  body.shell-ios .finanzas-card-ingreso .finanzas-card-boton,
  body.shell-ios .finanzas-card-gasto .finanzas-card-boton,
  .finanzas-asistente,
  .finanzas-tabbar-alta,
  .finanzas-tabbar-alta[data-escuchando="true"] .cadushi-onda {
    animation: none;
  }
}

@media (forced-colors: active) {
  .cadushi-nav-superficie { forced-color-adjust: none; filter: none; }
  .cadushi-nav-cuerpo { fill: CanvasText; stroke: Canvas; }
  .cadushi-nav-disco { fill: Canvas; }
  body.shell-ios .finanzas-tabbar-tab,
  body.shell-ios .finanzas-tabbar-tab[aria-current="page"] { forced-color-adjust: none; color: Canvas; }
  body.shell-ios .finanzas-tabbar-tab[data-iluminado="true"] { color: CanvasText; }
  body.shell-ios .finanzas-tabbar-alta { background: ButtonFace; color: ButtonText; border: 1px solid ButtonText; }
  .finanzas-tabbar-tab:focus-visible,
  .finanzas-tabbar-alta:focus-visible { outline-color: Highlight; }
}

/* Apertura: el lockup entra con opacidad y una escala corta (0.96 → 1);
   el velo se funde un poco más para entregar la interfaz.
   Space Grotesk solo vive en el wordmark. El resto de la app no cambia. */
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/space-grotesk-700.woff2") format("woff2");
}

.cadushi-apertura {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding:
    max(1.25rem, env(safe-area-inset-top))
    max(1.25rem, env(safe-area-inset-right))
    max(1.25rem, env(safe-area-inset-bottom))
    max(1.25rem, env(safe-area-inset-left));
  background: #ffffff;
  pointer-events: auto;
  animation: cadushi-apertura-velo 1.9s linear both;
}

.cadushi-apertura-lockup {
  display: flex;
  align-items: center;
  gap: 0.28em;
  max-width: 100%;
  font-size: clamp(2.4rem, 14vw, 4.85rem);
  animation: cadushi-apertura-entra 0.7s cubic-bezier(0.33, 0, 0.2, 1) both;
}

.cadushi-apertura-icono {
  display: block;
  width: 1.38em;
  height: auto;
  flex: none;
}

.cadushi-apertura-nombre {
  margin: 0;
  color: #111111;
  font-family: "Space Grotesk", sans-serif;
  font-size: 1em;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 0.9;
  white-space: nowrap;
  user-select: none;
}

@keyframes cadushi-apertura-entra {
  from {
    opacity: 0;
    transform: scale(0.96);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes cadushi-apertura-velo {
  0%,
  50% {
    opacity: 1;
    visibility: visible;
    animation-timing-function: cubic-bezier(0.33, 0, 0.2, 1);
  }
  100% {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cadushi-apertura-lockup {
    animation: none;
  }

  .cadushi-apertura {
    animation: cadushi-apertura-velo 0.35s linear 0.25s both;
  }
}


/* Asistente: escena de orbe a pantalla completa, con diálogo nativo accesible. */
.cadushi-voz-escena { position: fixed; inset: 0; width: 100%; max-width: none; height: 100dvh; max-height: none; margin: 0; padding: 0; border: 0; border-radius: 0; color: #f4f6ef; background: radial-gradient(ellipse at 50% 28%, #27312b 0, #111713 43%, #0b100d 100%); overflow: auto; overscroll-behavior: contain; color-scheme: dark; }
.cadushi-voz-escena::backdrop { background: #0b100def; }
.cadushi-voz-escena [hidden], .cadushi-voz-mini[hidden] { display: none !important; }
.cadushi-voz-lienzo { width: min(100%, 640px); min-height: 100%; margin: auto; padding: max(18px, env(safe-area-inset-top)) 22px max(18px, env(safe-area-inset-bottom)); display: flex; flex-direction: column; box-sizing: border-box; }
.cadushi-voz-cabecera { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-shrink: 0; }
.cadushi-voz-marca { font-size: 14px; font-weight: 750; letter-spacing: .14em; }
.cadushi-voz-marca span { margin-left: 8px; font-size: 10px; color: #c8f542; }
.cadushi-voz-controles { display: flex; gap: 8px; }
.cadushi-voz-escena button, .cadushi-voz-mini button { min-width: 44px; min-height: 44px; border: 1px solid #ffffff24; border-radius: 999px; padding: 10px 16px; font: inherit; font-size: 14px; color: inherit; background: #ffffff07; cursor: pointer; touch-action: manipulation; }
.cadushi-voz-escena button:disabled { opacity: .45; cursor: default; }
.cadushi-voz-escena button:focus-visible, .cadushi-voz-mini button:focus-visible { outline: 3px solid #c8f542; outline-offset: 4px; }
.cadushi-voz-conversacion { display: flex; flex-direction: column; align-items: center; flex: 1; justify-content: center; text-align: center; padding: 14px 0; }
.cadushi-orbe { --orbe-color: #c8f542; position: relative; width: clamp(150px, 47vw, 244px); height: clamp(150px, 47vw, 244px); margin: 10px 0 22px; flex-shrink: 0; }
.cadushi-orbe-halo { position: absolute; inset: -12%; border: 1px solid #c8f54222; border-radius: 50%; box-shadow: 0 0 72px #b3dc5020, inset 0 0 32px #b3dc5010; }
.cadushi-orbe-esfera { position: absolute; inset: 0; overflow: hidden; border-radius: 47% 53% 51% 49% / 48% 46% 54% 52%; background: radial-gradient(circle at 33% 26%, #e8ffc2 0, #c8f542 17%, #72ac5a 46%, #234c37 73%, #10261b 100%); box-shadow: inset -16px -25px 45px #07170f88, inset 12px 15px 25px #f2ffe880, 0 18px 55px #0005; animation: cadushi-orbe-reposo 9s ease-in-out infinite; }
.cadushi-orbe-flujo { position: absolute; inset: -30%; border-radius: 42%; background: conic-gradient(from 50deg, transparent, #f3ffb466, transparent 30%, #2c704e66, transparent 63%, #d8ff9e88, transparent); filter: blur(13px); animation: cadushi-orbe-giro 18s linear infinite; }
.cadushi-orbe-nucleo { position: absolute; inset: 12%; border-radius: 50%; border-top: 1px solid #efffd59c; filter: blur(2px); transform: rotate(-28deg); }
.cadushi-voz-estado { color: #c8f542; font-size: 12px; letter-spacing: .06em; margin: 0 0 8px; line-height: 1.5; max-width: 360px; }
.cadushi-voz-escena h2 { font-size: clamp(25px, 6vw, 34px); font-weight: 550; letter-spacing: -.045em; margin: 0; color: #f5f7f0; }
#voz-subtitulo { max-width: 390px; color: #bac3b8; line-height: 1.5; font-size: 14px; margin: 10px 0 20px; }
.cadushi-voz-sugerencias { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; width: 100%; max-width: 420px; }
.cadushi-voz-sugerencias button { border-radius: 16px; padding: 11px 10px; text-align: left; font-size: 13px; line-height: 1.4; }
#voz-fijo-pendiente { display: block; font-size: 10px; color: #b9c9ab; }
.cadushi-voz-mensaje { max-width: 420px; font-size: 14px; line-height: 1.5; margin: 16px 0 0; white-space: pre-wrap; }
.cadushi-voz-mensaje:empty { display: none; }
.cadushi-voz-revision { width: 100%; max-width: 440px; }
#voz-borrador { margin: 18px 0 10px; padding: 16px; border: 1px solid #c8f54266; border-radius: 18px; background: #c8f5420b; font-size: 14px; line-height: 1.65; }
.cadushi-voz-acciones { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.cadushi-voz-principal { margin: 20px 0 8px; }
#voz-iniciar, #voz-confirmar { color: #17220d; background: #c8f542; border-color: transparent; font-weight: 650; }
#voz-detener { border-color: #ffffff55; }
.cadushi-voz-destinos { display: flex; flex-wrap: wrap; justify-content: center; margin-top: 10px; gap: 2px 4px; }
.cadushi-voz-destinos button { border-color: transparent; padding-inline: 10px; color: #b9c5b5; font-size: 12px; }
.cadushi-voz-pie { display: block; width: 100%; margin: 0; padding: 8px 0 0; border: 0; text-align: center; flex-shrink: 0; }
.cadushi-voz-manual { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px 8px; color: #b9c5b5; font-size: 12px; }
.cadushi-voz-manual button { border-color: transparent; padding-inline: 8px; text-decoration: underline; text-underline-offset: 4px; }
#voz-privacidad { color: #9da99a; max-width: 450px; margin: 10px auto 0; font-size: 12px; line-height: 1.55; }
.cadushi-voz-escena[data-estado="checking"] .cadushi-orbe-esfera, .cadushi-voz-escena[data-estado="unavailable"] .cadushi-orbe-esfera { filter: saturate(.38); animation: none; }
.cadushi-voz-escena[data-estado="checking"] .cadushi-orbe-flujo, .cadushi-voz-escena[data-estado="unavailable"] .cadushi-orbe-flujo { animation: none; }
.cadushi-voz-escena[data-estado="connecting"] .cadushi-orbe-halo { border-style: dashed; border-color: #c8f54288; animation: cadushi-orbe-giro 7s linear infinite; }
.cadushi-voz-escena[data-estado="thinking"] .cadushi-orbe-flujo { animation-duration: 4s; }
.cadushi-voz-escena[data-estado="listening"] .cadushi-orbe-halo { animation: cadushi-orbe-escucha 3s ease-in-out infinite; }
.cadushi-voz-escena[data-estado="speaking"] .cadushi-orbe-esfera { animation: cadushi-orbe-habla 1.5s ease-in-out infinite; }
.cadushi-voz-escena[data-estado="error"] .cadushi-orbe-halo { border-color: #eaae8a; box-shadow: 0 0 55px #c8754333; }
.cadushi-voz-escena[data-estado="error"] .cadushi-voz-estado { color: #f0b38e; }
.cadushi-voz-mini { position: fixed; right: max(16px, env(safe-area-inset-right)); bottom: calc(94px + env(safe-area-inset-bottom)); z-index: 60; display: flex; align-items: center; gap: 4px; padding: 4px; color: #f4f6ef; background: #152018; border: 1px solid #c8f54255; border-radius: 999px; box-shadow: 0 8px 30px #0004; }
.cadushi-voz-mini button { border: 0; display: flex; align-items: center; gap: 10px; background: none; }
.cadushi-mini-esfera { display: inline-block; width: 30px; height: 30px; border-radius: 50%; background: radial-gradient(circle at 30% 25%, #ebffbd, #b8e946 30%, #316c43 72%); box-shadow: 0 0 16px #c8f54233; }
.cadushi-voz-mini[data-estado="speaking"] .cadushi-mini-esfera { animation: cadushi-orbe-habla 1.5s ease-in-out infinite; }
/* Invitación en reposo, distinta de la señal de micrófono real. */
.finanzas-tabbar-alta[data-escuchando="false"] .cadushi-onda { animation: cadushi-onda-invita 3.8s ease-in-out infinite; }
.finanzas-tabbar-alta[data-escuchando="false"] .cadushi-onda:nth-child(2) { animation-delay: -.4s; }
.finanzas-tabbar-alta[data-escuchando="false"] .cadushi-onda:nth-child(3) { animation-delay: -.8s; }
.finanzas-tabbar-alta[data-escuchando="false"] .cadushi-onda:nth-child(4) { animation-delay: -1.2s; }
.finanzas-tabbar-alta[data-escuchando="false"] .cadushi-onda:nth-child(5) { animation-delay: -1.6s; }
@keyframes cadushi-onda-invita { 0%, 75%, 100% { transform: scaleY(.8); } 35% { transform: scaleY(1.08); } }
@keyframes cadushi-orbe-reposo { 0%, 100% { transform: scale(.97) rotate(-5deg); border-radius: 47% 53% 51% 49% / 48% 46% 54% 52%; } 50% { transform: scale(1) rotate(5deg); border-radius: 53% 47% 46% 54% / 51% 53% 47% 49%; } }
@keyframes cadushi-orbe-giro { to { transform: rotate(360deg); } }
@keyframes cadushi-orbe-escucha { 0%, 100% { transform: scale(.95); opacity: .45; } 50% { transform: scale(1.06); opacity: 1; } }
@keyframes cadushi-orbe-habla { 0%, 100% { transform: scale(.96); } 45% { transform: scale(1.035); } 75% { transform: scale(.99); } }
@media (max-height: 740px) { .cadushi-orbe { width: 145px; height: 145px; margin: 8px 0 18px; } .cadushi-voz-lienzo { padding-top: max(8px, env(safe-area-inset-top)); } .cadushi-voz-conversacion { justify-content: flex-start; padding-top: 8px; } }
@media (min-width: 721px) { .cadushi-voz-mini { bottom: 24px; } }
@media (prefers-reduced-motion: reduce) { .cadushi-orbe *, .cadushi-mini-esfera, .finanzas-tabbar-alta[data-escuchando="false"] .cadushi-onda { animation: none !important; } }
@media (forced-colors: active) { .cadushi-orbe-esfera, .cadushi-mini-esfera { background: Highlight; border: 2px solid CanvasText; } .cadushi-orbe-flujo, .cadushi-orbe-nucleo { display: none; } .cadushi-voz-escena { color: CanvasText; background: Canvas; } .cadushi-voz-escena button { border-color: ButtonText; } }

/* The voice canvas contains only the orb, an exit, and necessary exceptions. */
.cadushi-voz-cabecera { justify-content: flex-end; }
.cadushi-voz-conversacion { justify-content: center; }
.cadushi-voz-escena[data-conversando="true"] .cadushi-voz-pie,
.cadushi-voz-escena[data-conversando="true"] #voz-detener { display: none; }
.cadushi-voz-escena #voz-minimizar { touch-action: none; }
#voz-mini-tiempo { font-variant-numeric: tabular-nums; font-size: 12px; opacity: .75; }
/* Preserve live announcements without a running transcript or status panel. */
.cadushi-voz-escena:is([data-estado="listening"], [data-estado="speaking"], [data-estado="thinking"]) #voz-estado {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.cadushi-voz-escena[data-conversando="true"] .cadushi-voz-principal { margin: 0; }
.cadushi-voz-escena[data-conversando="true"] .cadushi-orbe { width: clamp(180px, 60vw, 300px); height: clamp(180px, 60vw, 300px); margin: 24px 0; }
.cadushi-orbe[data-particulas="true"] > span { display: none; }
.cadushi-orbe canvas { display: block; width: 100%; height: 100%; }
@media (forced-colors: active) {
  .cadushi-orbe[data-particulas="true"] > .cadushi-orbe-esfera { display: block; }
  .cadushi-orbe canvas { display: none; }
}
.cadushi-voz-escena { background: #111; }
/* The orb is the explicit start gesture; the exit remains reachable after review scroll. */
.cadushi-voz-cabecera { position: sticky; top: 0; z-index: 2; background: #111; }
.cadushi-voz-escena #voz-iniciar { padding: 0; border: 0; color: inherit; background: transparent; opacity: 1; }
.cadushi-voz-escena #voz-iniciar:disabled { cursor: default; }
.cadushi-voz-escena .cadushi-voz-pie,
.cadushi-voz-escena:is([data-estado="idle"], [data-estado="ended"]) #voz-estado {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
@media (max-height: 600px) {
  .cadushi-voz-escena[data-conversando] .cadushi-orbe { width: 160px; height: 160px; margin: 10px 0; }
}

.cadushi-voz-escena .cadushi-orbe { display: block; }

/* Legacy first-use trial disclosure remains visible before consent, never in supervised dev. */
.cadushi-voz-escena[data-modo="trial"]:is([data-estado="idle"], [data-estado="unavailable"]) .cadushi-voz-pie {
  position: static; width: 100%; height: auto; padding: 8px 0 0; margin: 0;
  overflow: visible; clip-path: none; white-space: normal;
}
/* Progressive choices appear only after the real categories tool responds. */
#voz-categorias { margin: 12px 0; }
#voz-categorias p { margin: 0 0 12px; font-size: 14px; }
#voz-categorias-lista { max-height: 30dvh; overflow-y: auto; padding: 6px; }
#voz-categorias-lista button { overflow-wrap: anywhere; max-width: 100%; }

/* Radial entry selector, adapted from Bencho's MIT block. */
.finanzas-menu-radial {
  position: fixed;
  width: 0;
  height: 0;
  z-index: 65;
  pointer-events: none;
  visibility: hidden;
}
.finanzas-menu-radial[data-abierto="true"] { visibility: visible; }
.finanzas-radial-opcion {
  position: absolute;
  left: -24px;
  top: -24px;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--foreground) 15%, transparent);
  border-radius: 999px;
  color: var(--foreground);
  background: var(--card);
  box-shadow: 0 4px 16px #0002;
  cursor: pointer;
  opacity: 0;
  transform: translate(0, 0) scale(0.4);
  transition: transform 420ms cubic-bezier(0.24, 1.34, 0.38, 1), opacity 200ms ease, box-shadow 200ms ease;
}
.finanzas-menu-radial[data-abierto="true"] .finanzas-radial-opcion {
  opacity: 1;
  pointer-events: auto;
  transform: translate(var(--radial-x), var(--radial-y)) scale(1);
}
.finanzas-radial-opcion:focus-visible,
.finanzas-radial-opcion[data-apuntado="true"] {
  outline: 2px solid var(--foreground);
  outline-offset: 3px;
  z-index: 2;
}
.finanzas-radial-opcion[aria-disabled="true"] { color: var(--muted-foreground); }
.finanzas-radial-ayuda {
  position: absolute;
  width: min(240px, calc(100vw - 24px));
  margin: 0;
  padding: 10px 12px;
  border-radius: 12px;
  color: var(--foreground);
  background: var(--card);
  box-shadow: 0 4px 24px #0003;
  font-size: 12px;
  line-height: 1.4;
}
.finanzas-radial-ayuda:empty { display: none; }
.finanzas-card-boton[aria-haspopup="menu"] { touch-action: none; }
.finanzas-card-boton[aria-haspopup="menu"] .finanzas-card-signo {
  transition: transform 380ms cubic-bezier(0.24, 1.34, 0.38, 1);
}
.finanzas-radial-abierto .finanzas-card-signo { transform: rotate(135deg); }

/* Keep date and category in the same form row, below the main close action. */
body.shell-ios .finanzas-card-captura-abierta > .finanzas-form-en-tarjeta {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}
@media (prefers-reduced-motion: reduce) {
  .finanzas-radial-opcion,
  .finanzas-card-boton[aria-haspopup="menu"] .finanzas-card-signo {
    transition-duration: 0ms;
    transition-delay: 0ms !important;
  }
}

/* Photo capture stops at a local, dismissible preview until OCR exists. */
.finanzas-foto-pendiente {
  width: min(420px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px);
  overflow: auto;
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: 20px;
  color: var(--foreground);
  background: var(--card);
}
.finanzas-foto-pendiente::backdrop { background: #0008; }
.finanzas-foto-pendiente h3 { margin: 0 0 14px; }
.finanzas-foto-pendiente img { display: block; max-width: 100%; max-height: 50dvh; margin: 0 auto; object-fit: contain; border-radius: 12px; }
.finanzas-foto-pendiente p { font-size: 14px; line-height: 1.5; }
.finanzas-foto-pendiente button { min-height: 44px; padding: 8px 18px; }

/* Bencho LabelInput motion, adapted from the existing login (MIT notice in
   licenses/bencho-MIT.txt). Native focus/value states drive the floating label. */
.finanzas-form-en-tarjeta .finanzas-field {
  position: relative;
  gap: 0;
  margin-top: 7px;
}
.finanzas-form-en-tarjeta .finanzas-field > .finanzas-field-label {
  position: absolute;
  z-index: 1;
  top: 22px;
  left: 8px;
  max-width: calc(100% - 16px);
  padding: 0 4px;
  border-radius: 3px;
  background: var(--background);
  color: var(--muted-foreground);
  font-size: 14px;
  line-height: 14px;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  transform: translateY(-50%);
  transform-origin: left center;
  transition: transform 780ms cubic-bezier(.22,1,.36,1), color 400ms ease;
  pointer-events: none;
}
.finanzas-form-en-tarjeta .finanzas-field:has(input:focus, input:not(:placeholder-shown), select) > .finanzas-field-label {
  transform: translateY(-50%) translateY(-22px) scale(.82);
  color: var(--foreground);
}
.finanzas-form-en-tarjeta .cadushi-label-letters { white-space: pre; }
.finanzas-form-en-tarjeta .cadushi-label-letters > span { display: inline-block; }
.finanzas-form-en-tarjeta .finanzas-field:has(:is(input, select):focus) > .finanzas-field-label .cadushi-label-letters > span {
  animation: cadushi-label-hop 800ms cubic-bezier(.3,.7,.3,1) both;
  animation-delay: var(--label-delay, 0ms);
}
@keyframes cadushi-label-hop { 38% { transform: translateY(-2px); } }
.finanzas-form-en-tarjeta .finanzas-field:has(input:-webkit-autofill) > .finanzas-field-label {
  transform: translateY(-50%) translateY(-22px) scale(.82);
  color: var(--foreground);
}
@supports selector(:autofill) {
  .finanzas-form-en-tarjeta .finanzas-field:has(input:autofill) > .finanzas-field-label {
    transform: translateY(-50%) translateY(-22px) scale(.82);
    color: var(--foreground);
  }
}
.finanzas-form-en-tarjeta .finanzas-field input::placeholder { opacity: 0; }
.finanzas-form-en-tarjeta .finanzas-field :is(input, select) {
  border-color: color-mix(in srgb, var(--foreground) 50%, var(--background));
  border-radius: 26px;
}
.finanzas-form-en-tarjeta .finanzas-field :is(input, select):focus-visible {
  outline: none;
  box-shadow: none;
  border: 2px solid var(--foreground);
  padding: calc(.5rem - 1px) calc(.65rem - 1px);
}
@supports selector(input:user-invalid) {
  .finanzas-form-en-tarjeta .finanzas-field input:user-invalid { border-color: var(--destructive); }
}
.finanzas-form-en-tarjeta .finanzas-field input[aria-invalid="true"] { border-color: var(--destructive); }
.finanzas-form-en-tarjeta .finanzas-categoria-rapida-field { flex: 1 1 7.5rem; }
.finanzas-form-en-tarjeta .finanzas-categoria-rapida-field input { flex: none; width: 100%; }
@media (max-width: 1000px) {


  .finanzas-form-en-tarjeta .finanzas-fields {
    grid-template-columns: 104px calc(120px - 104px - .4rem) minmax(0, 1fr) 44px;
  }
  .finanzas-form-en-tarjeta #finanzas-fecha-campo { grid-column: 1 / 3; grid-row: 1; }
  .finanzas-form-en-tarjeta #finanzas-categoria-field { grid-column: 3 / -1; grid-row: 1; }
  .finanzas-form-en-tarjeta .finanzas-field-concepto { grid-column: 1 / -1; grid-row: 2; }
  .finanzas-form-en-tarjeta #finanzas-moneda-campo { grid-column: 1; grid-row: 3; }
  .finanzas-form-en-tarjeta :is(#finanzas-monto-cop-campo, #finanzas-monto-ext-campo) { grid-column: 2 / 4; grid-row: 3; }
  .finanzas-form-en-tarjeta .finanzas-actions-botones { grid-column: 4; grid-row: 3; }
  .finanzas-form-en-tarjeta :is(#finanzas-tasa-campo, #finanzas-conversion-campo) { grid-column: 1 / -1; }
  .finanzas-form-en-tarjeta #finanzas-fecha { min-width: 0; font-size: 16px; padding-inline: 6px; }
  .finanzas-form-en-tarjeta #finanzas-categoria { font-size: 12px; padding-inline: 6px; }
  .finanzas-form-en-tarjeta :is(#finanzas-fecha, #finanzas-categoria):focus-visible { padding-inline: 5px; }
  .finanzas-form-en-tarjeta :is(#finanzas-monto-cop-campo, #finanzas-monto-ext-campo):has(input:placeholder-shown:not(:focus):not(:is(:-webkit-autofill, :autofill))) > .finanzas-field-label { transform: translateY(-50%) scale(.82); }
}
@media (min-width: 1001px) {
  .finanzas-form-en-tarjeta .finanzas-fields {
    grid-template-columns: 120px minmax(0, 1.1fr) minmax(130px, 1.2fr) minmax(95px, 1.1fr) minmax(75px, .8fr) 44px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .finanzas-form-en-tarjeta .finanzas-field > .finanzas-field-label { transition: none; }
  .finanzas-form-en-tarjeta .finanzas-field:has(:is(input, select):focus) > .finanzas-field-label .cadushi-label-letters > span { animation: none; }
}
@media (forced-colors: active) {
  .finanzas-form-en-tarjeta .finanzas-field > .finanzas-field-label { background: Canvas; color: CanvasText; }
  .finanzas-form-en-tarjeta .finanzas-field :is(input, select) { border-color: ButtonText; }
  .finanzas-form-en-tarjeta .finanzas-field :is(input, select):focus-visible { border-color: Highlight; }
}

/* Center the currency value independently of the label, with symmetric room
   for the arrow. The native select still opens the platform picker. */
.finanzas-form-en-tarjeta #finanzas-moneda {
  appearance: none;
  -webkit-appearance: none;
  text-align: center;
  text-align-last: center;
  padding-inline: 20px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 13px) 52%, calc(100% - 9px) 52%;
  background-size: 4px 4px;
  background-repeat: no-repeat;
}
.finanzas-form-en-tarjeta #finanzas-moneda:focus-visible { padding-inline: 19px; }
@media (max-width: 360px) {
  /* Keep the date readable and the category picker usable on narrow screens;
     its add action sits below instead of reducing the selected value to zero. */
  .finanzas-form-en-tarjeta #finanzas-categoria-field .finanzas-categoria-select-fila { flex-wrap: wrap; }
  .finanzas-form-en-tarjeta #finanzas-categoria { flex-basis: 100%; }
  .finanzas-form-en-tarjeta #finanzas-fecha-campo { align-self: start; }
  .finanzas-form-en-tarjeta :is(#finanzas-monto-cop-campo, #finanzas-monto-ext-campo) { grid-column: 2 / -1; }
  .finanzas-form-en-tarjeta .finanzas-actions-botones { grid-row: 4; }
  .finanzas-form-en-tarjeta :is(#finanzas-monto-label, #finanzas-monto-ext-label) { max-width: none; }
}

.finanzas-fecha-cara { display: none; }

/* Compact capture row: numeric date, category and anchored create popup. */
@media (max-width: 1000px) {
  :root { --capture-date-width: 66px; }

  body.shell-ios .finanzas-top-cards > .finanzas-card.finanzas-card-captura-abierta > .finanzas-form-en-tarjeta { grid-row: 1; }


  .finanzas-form-en-tarjeta .finanzas-fields { grid-template-columns: var(--capture-date-width) minmax(0, 1fr) 44px; gap: 3px; }
  .finanzas-form-en-tarjeta #finanzas-fecha-campo { grid-column: 1; grid-row: 1; align-self: start; }
  .finanzas-form-en-tarjeta #finanzas-categoria-field { grid-column: 2; grid-row: 1; }
  .finanzas-form-en-tarjeta .finanzas-field-concepto { grid-column: 1 / -1; grid-row: 2; }
  .finanzas-form-en-tarjeta .finanzas-fields-fila-valor { display: grid; grid-column: 1 / -1; grid-row: 3; grid-template-columns: 104px minmax(0, 1fr) 44px; gap: 3px; }
  .finanzas-form-en-tarjeta #finanzas-moneda-campo { grid-column: 1; grid-row: 1; width: 104px; }
  .finanzas-form-en-tarjeta :is(#finanzas-monto-cop-campo, #finanzas-monto-ext-campo) { grid-column: 2; grid-row: 1; }
  .finanzas-form-en-tarjeta .finanzas-actions-botones { grid-column: 3; grid-row: 3; }
  .finanzas-form-en-tarjeta .finanzas-categoria-select-fila { gap: 3px; flex-wrap: nowrap; }
  .finanzas-form-en-tarjeta #finanzas-categoria { flex: 1; flex-basis: auto; width: 0; max-width: 112px; padding-inline: 2px; }
  .finanzas-form-en-tarjeta #finanzas-categoria:focus-visible { padding-inline: 1px; }
  .finanzas-form-en-tarjeta #finanzas-fecha { position: absolute; inset: 0; z-index: 2; width: 100%; height: 44px; opacity: 0; font-size: 16px; cursor: pointer; }
  .finanzas-fecha-cara { display: flex; align-items: center; justify-content: center; height: 44px; border: 1px solid var(--border); border-radius: 26px; background: var(--background); color: var(--foreground); font-size: 12px; white-space: nowrap; }
  #finanzas-fecha-campo:has(input:focus-visible) .finanzas-fecha-cara { outline: 2px solid var(--foreground); outline-offset: -2px; }
}
@media (max-width: 360px) {
  /* Keep four usable touch targets on the smallest supported viewport. */

}
@media (max-width: 360px) {

}

#finanzas-categoria-popup { flex: 0 0 44px; width: 44px; height: 44px; }

.category-choice-popup { position:fixed; z-index:100; width:min(288px,calc(100vw - 16px)); max-height:calc(100vh - 16px); overflow:auto; padding:12px; margin:0; border:1px solid var(--border); border-radius:22px; background:var(--popover); color:var(--popover-foreground); }
.category-choice-popup button { min-width:44px; min-height:44px; }

/* Capture refinement: border geometry has a real transparent notch. The
   label never paints a patch over the green/white card. Values keep their
   native controls and the accepted currency alignment. */
.finanzas-form-en-tarjeta .finanzas-field {
  --notch-left: 14px;
  --notch-width: 0px;
  --control-width: 100%;
}
.finanzas-form-en-tarjeta .finanzas-field::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: var(--control-width);
  height: 44px;
  border: 1px solid currentColor;
  border-radius: 26px;
  color: var(--foreground);
  opacity: .65;
  box-sizing: border-box;
  pointer-events: none;
  clip-path: polygon(0 0, var(--notch-left) 0, var(--notch-left) 8px,
    calc(var(--notch-left) + var(--notch-width)) 8px,
    calc(var(--notch-left) + var(--notch-width)) 0, 100% 0,
    100% 100%, 0 100%);
}
.finanzas-form-en-tarjeta .finanzas-field:has(input:focus, input:not(:placeholder-shown), select) {
  --notch-width: var(--label-notch, 0px);
}
.finanzas-form-en-tarjeta .finanzas-field:has(:is(input, select):focus-visible)::before {
  border-width: 2px;
  opacity: 1;
}
.finanzas-form-en-tarjeta .finanzas-field > .finanzas-field-label {
  background: transparent;
  padding: 0;
}
.finanzas-form-en-tarjeta .finanzas-field :is(input, select),
.finanzas-form-en-tarjeta .finanzas-field :is(input, select):focus-visible {
  border-color: transparent;
  background-color: transparent;
}
.finanzas-form-en-tarjeta #finanzas-categoria-field { --control-width: calc(100% - 47px); }
.finanzas-form-en-tarjeta #finanzas-categoria {
  max-width: none;
  appearance: none;
  -webkit-appearance: none;
  text-align: center;
  text-align-last: center;
  padding-inline: 12px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 6px) 52%, calc(100% - 2px) 52%;
  background-size: 4px 4px;
  background-repeat: no-repeat;
}
.finanzas-form-en-tarjeta #finanzas-categoria:focus-visible { padding-inline: 11px; }
.finanzas-form-en-tarjeta #finanzas-fecha-campo {
  --notch-left: calc((100% - var(--label-notch, 0px)) / 2);
}
.finanzas-form-en-tarjeta #finanzas-fecha-campo > .finanzas-field-label {
  left: 50%;
  max-width: none;
  transform-origin: center;
  transform: translate(-50%, -50%) translateY(-22px) scale(.82);
}
.finanzas-form-en-tarjeta #finanzas-fecha {
  position: absolute; inset: 0; z-index: 2; width: 100%; height: 44px;
  opacity: 0; font-size: 16px; cursor: pointer;
}
.finanzas-fecha-cara {
  display: flex; align-items: center; justify-content: center;
  height: 44px; border: 0; background: transparent;
  color: var(--foreground); font-size: 12px; white-space: nowrap;
}
#finanzas-fecha-campo:has(input:focus-visible) .finanzas-fecha-cara { outline: none; }
/* Only the cancel background changes. The existing glyph, ink, breathing
   animation and circle dimensions remain owned by the accepted button. */
body.shell-ios .finanzas-card .finanzas-card-boton[data-manual="true"] { background: #c62828; }
body.shell-ios .finanzas-top-cards > .finanzas-card.finanzas-card-captura-abierta > .finanzas-form-en-tarjeta {
  grid-row: 1; padding-top: 0; margin-top: 0;
}
body.shell-ios .finanzas-top-cards > .finanzas-card > .ds-card-header { z-index: 2; }
.finanzas-form-en-tarjeta .finanzas-fields {
  grid-template-columns: 66px minmax(0, 1fr) calc(2.85rem + .5rem);
  gap: 3px;
}
.finanzas-form-en-tarjeta .finanzas-field { margin-top: 0; }
.finanzas-form-en-tarjeta #finanzas-fecha-campo { grid-column: 1; grid-row: 1; }
.finanzas-form-en-tarjeta #finanzas-categoria-field { grid-column: 2; grid-row: 1; }
.finanzas-form-en-tarjeta .finanzas-field-concepto { grid-column: 1 / -1; grid-row: 2; margin-top: 7px; }
.finanzas-form-en-tarjeta .finanzas-fields-fila-valor {
  display: grid; grid-column: 1 / -1; grid-row: 3;
  grid-template-columns: 104px minmax(0, 1fr) 44px; gap: 3px;
}
.finanzas-form-en-tarjeta #finanzas-moneda-campo { grid-column: 1; grid-row: 1; width: 104px; margin-top: 7px; }
.finanzas-form-en-tarjeta :is(#finanzas-monto-cop-campo, #finanzas-monto-ext-campo) { grid-column: 2; grid-row: 1; margin-top: 7px; }
.finanzas-form-en-tarjeta .finanzas-actions-botones { grid-column: 3; grid-row: 3; }
.finanzas-form-en-tarjeta .finanzas-categoria-select-fila { gap: 3px; flex-wrap: nowrap; }
.finanzas-form-en-tarjeta #finanzas-categoria { flex: 1; width: 0; flex-basis: auto; }
/* The lime card keeps dark field ink in either theme; popup tokens stay
   independent so its dark surface retains light text. */
body.shell-ios .finanzas-card-ingreso .finanzas-form-en-tarjeta { --capture-ink: #0a0a0a; }
.finanzas-form-en-tarjeta .finanzas-field::before,
.finanzas-form-en-tarjeta .finanzas-field > .finanzas-field-label,
.finanzas-form-en-tarjeta .finanzas-field:has(input:focus, input:not(:placeholder-shown), select) > .finanzas-field-label,
.finanzas-form-en-tarjeta .finanzas-field :is(input, select),
.finanzas-form-en-tarjeta .finanzas-fecha-cara { color: var(--capture-ink, var(--foreground)); }
body.shell-ios .finanzas-card :is(#finanzas-nuevo-ingreso, #finanzas-nuevo-gasto)[data-manual="true"] { background: #c62828; }
@media (max-width: 360px) {
  /* Reserve usable widths in every state, rather than widening on Manual.
     The vertical heading retains its own gutter and never enters a field. */
  body.shell-ios .finanzas-top-cards { margin-inline: -20px; }
  body.shell-ios .finanzas-top-cards > .finanzas-card.ds-card { padding-inline: 8px; }
  body.shell-ios .finanzas-top-cards > .finanzas-card-ingreso.ds-card { --finanzas-ingreso-gutter: 32px; padding-left: var(--finanzas-ingreso-gutter); }
  body.shell-ios .finanzas-top-cards > .finanzas-card { column-gap: 3px; }
  .finanzas-form-en-tarjeta .finanzas-fields { grid-template-columns: 66px minmax(0, 1fr) 2.85rem; }
}

.finanzas-form-en-tarjeta .finanzas-field:has(input[aria-invalid="true"])::before { color: var(--destructive); opacity: 1; }
@supports selector(input:user-invalid) {
  .finanzas-form-en-tarjeta .finanzas-field:has(input:user-invalid)::before { color: var(--destructive); opacity: 1; }
}

/* Santiago's final pass: clear the curved edge beneath label ink, retain
   Fecha's center and move other floating labels into the straight top edge. */
.finanzas-form-en-tarjeta .finanzas-field > .finanzas-field-label { left: 16px; }
.finanzas-form-en-tarjeta #finanzas-fecha-campo > .finanzas-field-label { left: 50%; }
body.shell-ios .finanzas-card .finanzas-card-boton[data-manual="true"] { animation: none; transform: none; }
.finanzas-form-en-tarjeta #finanzas-guardar { animation: cadushi-asistente-respira 2.6s ease-in-out infinite; transform-origin: center; }
:root[data-tema="oscuro"] body.shell-ios #finanzas-nuevo-gasto { background: #c62828; }
:root[data-tema="oscuro"] .finanzas-form-en-tarjeta #finanzas-guardar { background: #27643b; color: #fff; }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema]) body.shell-ios #finanzas-nuevo-gasto { background: #c62828; }
  :root:not([data-tema]) .finanzas-form-en-tarjeta #finanzas-guardar { background: #27643b; color: #fff; }
}
@media (prefers-reduced-motion: reduce) { .finanzas-form-en-tarjeta #finanzas-guardar { animation: none; } }
.finanzas-form-en-tarjeta #finanzas-guardar[aria-busy="true"] { animation: none; }

/* A short color handoff and an opacity-only entrance preserve the anchored
   button, final field geometry, focus and the existing radial glyph rotation. */
body.shell-ios .finanzas-card .finanzas-card-boton {
  transition: background-color 340ms cubic-bezier(.25,.1,.25,1);
}
.finanzas-form-en-tarjeta:not([hidden]) .finanzas-fields {
  animation: cadushi-manual-reveal 300ms cubic-bezier(.22,1,.36,1) both;
}
@keyframes cadushi-manual-reveal { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  body.shell-ios .finanzas-card .finanzas-card-boton { transition-duration: 0ms; }
  .finanzas-form-en-tarjeta:not([hidden]) .finanzas-fields { animation: none; }
}

.finanzas-form-en-tarjeta #finanzas-guardar { position:relative; --manual-ring-ink:#fff; }
:root[data-tema="claro"] .finanzas-card-gasto #finanzas-guardar { --manual-ring-ink:#000; }
@media (prefers-color-scheme:light) { :root:not([data-tema]) .finanzas-card-gasto #finanzas-guardar { --manual-ring-ink:#000; } }
.finanzas-form-en-tarjeta #finanzas-guardar > .finanzas-guardar-progreso { position:absolute;inset:-1px;width:calc(100% + 2px);height:calc(100% + 2px);pointer-events:none;overflow:visible;transition:opacity 160ms ease; }
.finanzas-guardar-progreso circle { fill:none;stroke:var(--manual-ring-ink);stroke-width:3;stroke-linecap:round;stroke-dasharray:var(--manual-complete,0) 3;transform:rotate(-90deg);transform-origin:22px 22px;transition:stroke-dasharray 240ms ease,opacity 160ms ease; }
#finanzas-guardar[data-complete="0"] .finanzas-guardar-progreso { opacity:0; }
@media (prefers-reduced-motion:reduce) { .finanzas-form-en-tarjeta #finanzas-guardar > .finanzas-guardar-progreso,.finanzas-guardar-progreso circle { transition:none; } }

/* The existing theme control shares the visible page-title row only in Settings. */
.finanzas-header > .finanzas-tema-bar { display:none; }
body.shell-ios .finanzas-header > .finanzas-tema-bar { position:static;align-self:center;margin-left:auto;flex:0 0 auto; }
.finanzas-module:has(#finanzas-configuracion:not([hidden])) .finanzas-header > .finanzas-tema-bar { display:flex; }
body.shell-ios:has(#finanzas-configuracion:not([hidden])) .finanzas-header { padding-right:0; }
/* Guest identity is already in the session panel; keep the Settings title
   readable beside its 44px theme control at the narrowest width. */
@media (max-width:360px) {
  body.shell-ios:has(#finanzas-configuracion:not([hidden])) .finanzas-header-fila > .finanzas-configuracion-note { display:none; }
}

/* Give the breathing approval circle room without moving its grid slot. */
.finanzas-form-en-tarjeta :is(#finanzas-monto-cop-campo, #finanzas-monto-ext-campo) { margin-inline-end:8px; }
@media (max-width:360px) {
  .finanzas-form-en-tarjeta :is(#finanzas-monto, #finanzas-monto-ext) { padding-inline:4px; }
  .finanzas-form-en-tarjeta :is(#finanzas-monto, #finanzas-monto-ext):focus-visible { padding-inline:3px; }
}

/* Original currency totals: movement count sets rank, never a nominal FX sum. */
body.shell-ios .finanzas-card:not(.finanzas-card-captura-abierta) .ds-card-value.finanzas-totales-brutos { display:grid;gap:8px;min-width:0; }
.finanzas-total-bruto { min-width:0; }
.finanzas-total-bruto-importe { display:flex;align-items:baseline;flex-wrap:wrap;gap:6px;min-width:0; }
body.shell-ios .finanzas-card .finanzas-total-bruto strong { font-size:clamp(1.5rem,6vw,2.25rem);overflow-wrap:anywhere;line-height:1.12; }
body.shell-ios .finanzas-card .finanzas-total-bruto[data-rango="1"] strong { font-size:clamp(1.2rem,4.8vw,1.65rem); }
body.shell-ios .finanzas-card .finanzas-total-bruto[data-rango="2"] strong { font-size:clamp(1rem,4vw,1.25rem); }
.finanzas-total-bruto-nota { display:block;font-size:.65rem;line-height:1.35;color:inherit; }
body.shell-ios .finanzas-card .finanzas-categorias-lista { border-top:1px solid #454545; }
body.shell-ios .finanzas-card-ingreso .finanzas-categorias-lista { border-top-color:#294000; }
:root[data-tema="oscuro"] body.shell-ios .finanzas-card-gasto .finanzas-categorias-lista { border-top-color:#b8b8b8; }
@media (prefers-color-scheme:dark) { :root:not([data-tema]) body.shell-ios .finanzas-card-gasto .finanzas-categorias-lista { border-top-color:#b8b8b8; } }
body.shell-ios .finanzas-card .finanzas-categorias-fila { min-width:0;flex-wrap:wrap; }
body.shell-ios .finanzas-card .finanzas-categorias-monto { min-width:0;max-width:100%;white-space:normal;overflow-wrap:anywhere; }
body.shell-ios .finanzas-card-ingreso .finanzas-categorias-nombre { color:#182600; }

/* Currency chooses only category previews; gross totals retain every currency. */
body.shell-ios:has(#finanzas-principal:not([hidden])) .finanzas-header { flex-wrap:wrap; }
.finanzas-moneda-desglose { flex:0 0 100%;display:flex;gap:4px;justify-content:flex-start; }
.finanzas-moneda-desglose[hidden] { display:none; }
.finanzas-moneda-desglose button { min-height:44px;min-width:44px;padding:3px 10px;border:1px solid currentColor;border-radius:999px;background:transparent;color:inherit;font-size:.7rem;cursor:pointer; }
.finanzas-moneda-desglose button[aria-pressed="true"] { background:#c6f135;color:#182600;border-color:#294000; }
.finanzas-moneda-desglose button:focus-visible { outline:2px solid currentColor;outline-offset:2px; }

/* Read-only voice preview above the navbar waves; the navbar alone resumes it. */
.cadushi-voz-mini { left: 50%; right: auto; transform: translateX(-50%); bottom: calc(94px + env(safe-area-inset-bottom)); width: min(252px, calc(100vw - 24px)); box-sizing: border-box; display: block; padding: 12px; border-radius: 17px; color: #f0f3ea; background: #20251f; border-color: #c8f54240; animation: cadushi-mini-aparece .18s ease-out; }
.cadushi-mini-cabecera { display: flex; align-items: center; gap: 8px; font-size: 11px; }
.cadushi-mini-cabecera .cadushi-mini-esfera { width: 14px; height: 14px; }
.cadushi-mini-cabecera time { margin-left: auto; }
.cadushi-mini-preview { margin-top: 9px; padding-top: 9px; border-top: 1px solid #ffffff16; font-size: 12px; }
.cadushi-mini-tarjeta, .cadushi-mini-detalle { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 4px 8px; }
#voz-mini-contador, #voz-mini-tarjeta-estado { font-size: 10px; color: #bdc5b4; }
#voz-mini-concepto { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; margin: 6px 0; line-height: 1.35; overflow-wrap: anywhere; }
#voz-mini-monto { font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.cadushi-mini-ayuda { margin: 9px 0 0; color: #bdc5b4; font-size: 10px; }
.cadushi-mini-preview[data-tipo="gasto"] #voz-mini-tipo { color: #ffadad; }
.cadushi-mini-preview[data-tipo="ingreso"] #voz-mini-tipo { color: #8de5b5; }
.cadushi-voz-mini[data-teclado="true"] { visibility: hidden; }
html[data-tema="claro"] .cadushi-voz-mini { color: #232a22; background: #f5f7ef; border-color: #62744260; }
html[data-tema="claro"] .cadushi-voz-mini :is(#voz-mini-contador, #voz-mini-tarjeta-estado, .cadushi-mini-ayuda) { color: #55604e; }
html[data-tema="claro"] .cadushi-mini-preview { border-top-color: #26331b20; }
html[data-tema="claro"] .cadushi-mini-preview[data-tipo="gasto"] #voz-mini-tipo { color: #a52d32; }
html[data-tema="claro"] .cadushi-mini-preview[data-tipo="ingreso"] #voz-mini-tipo { color: #17663e; }
@keyframes cadushi-mini-aparece { from { opacity: 0; translate: 0 6px; } to { opacity: 1; translate: 0 0; } }
@media (min-width: 721px) { .cadushi-voz-mini { bottom: 24px; } }
@media (prefers-reduced-motion: reduce) { .cadushi-voz-mini { animation: none; } }
@media (forced-colors: active) { .cadushi-voz-mini { color: CanvasText; background: Canvas; border: 1px solid CanvasText; } .cadushi-voz-mini * { color: CanvasText !important; } }

/* Settings and account keep existing routes/session actions at the top right. */
body.shell-ios .finanzas-header { flex-wrap:wrap; }
.finanzas-topbar { display:flex;align-items:center;justify-content:space-between;flex:0 0 100%;min-width:0;gap:4px; }
.finanzas-topbar .finanzas-moneda-desglose { flex:0 1 auto;gap:2px; }
.finanzas-topbar .finanzas-moneda-desglose button { width:44px;padding-inline:0; }
.finanzas-topbar-actions { display:flex;align-items:center;gap:4px;margin-left:auto;flex:0 0 auto; }
/* Align currency circles with the summary text; keep 44px targets separate
   on narrow screens, and bring the account group toward the income anchor. */
.finanzas-topbar { position:fixed;top:max(12px,env(safe-area-inset-top,0px));left:52px;right:clamp(28px,calc(100vw - 332px),48px);z-index:50;overflow:visible; }
body.shell-ios .finanzas-header { padding-top:calc(68px + env(safe-area-inset-top,0px)); }
.finanzas-topbar-config { display:flex;align-items:center;justify-content:center;width:44px;height:44px;border:1px solid currentColor;border-radius:50%;color:inherit;text-decoration:none; }
.finanzas-topbar-config:focus-visible { outline:2px solid currentColor;outline-offset:2px; }
#cadushi-account-menu { width:44px;height:44px; }

/* Explicit review in the visible mini: complete fields, canonical actions only. */
.cadushi-voz-mini { width: min(320px, calc(100vw - 24px)); max-height: calc(100dvh - 120px - env(safe-area-inset-bottom)); overflow-y: auto; }
#voz-mini-concepto { display: block; overflow: visible; -webkit-line-clamp: unset; }
.cadushi-mini-datos { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; margin: 7px 0; font-size: 11px; }
.cadushi-mini-datos dt { opacity: .75; font-size: 10px; }
.cadushi-mini-datos dd { margin: 2px 0 0; overflow-wrap: anywhere; }
.cadushi-mini-acciones { display: flex; gap: 8px; margin-top: 9px; }
.cadushi-mini-acciones button { flex: 1; justify-content: center; min-height: 44px; border-radius: 12px; font-size: 12px; }
.cadushi-mini-acciones button[hidden] { display: none; }
.cadushi-mini-acciones #voz-mini-aceptar { background: #c8f542; color: #19220e; }

.cadushi-mini-aviso { margin: 6px 0; font-size: 11px; line-height: 1.4; overflow-wrap: anywhere; }
#voz-mini-categoria-nueva { font-weight: 650; }

.finanzas-liquidacion { width: min(420px, calc(100vw - 32px)); box-sizing: border-box; max-height: calc(100dvh - 32px); overflow: auto; padding: 20px; border-radius: 20px; background: var(--popover); color: var(--popover-foreground); }
.finanzas-liquidacion::backdrop { background: #0008; }
.finanzas-liquidacion form { display: grid; gap: 14px; }
.finanzas-liquidacion label { display: grid; gap: 6px; }
.finanzas-liquidacion input, .finanzas-liquidacion select, .finanzas-liquidacion button { min-height: 44px; max-width: 100%; font: inherit; }
.finanzas-liquidacion h2, .finanzas-liquidacion p { overflow-wrap: anywhere; }

.finanzas-liquidacion .finanzas-liquidacion-confirmacion { display: flex; align-items: flex-start; gap: 10px; }
.finanzas-liquidacion .finanzas-liquidacion-confirmacion input { min-height: 20px; width: 20px; height: 20px; flex-shrink: 0; accent-color: #a3cd42; }

/* The fixed control anchor must not clip the avatar ring or focus outline. */
.finanzas-topbar { overflow: visible; }

/* Both radial launchers close with the same fixed red X. */
.finanzas-radial-cruz { display: none; }
:root body.shell-ios .finanzas-card .finanzas-card-boton.finanzas-radial-abierto { background: #c62828; color: #fff; }
body.shell-ios .finanzas-radial-abierto .finanzas-card-signo { transform: none; }
.finanzas-radial-abierto .finanzas-card-signo path:not(.finanzas-radial-cruz) { display: none; }
.finanzas-radial-abierto .finanzas-radial-cruz { display: block; }

/* Fixed controls: selected configuration and brief press feedback. */
.finanzas-topbar-config { transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease; }
.finanzas-topbar-config svg { transition: transform 280ms ease; transform-origin: center; transform:rotate(0deg); }
.finanzas-topbar-config[aria-current="page"] svg { transform: rotate(-180deg); }
.finanzas-topbar-config[aria-current="page"] { background: var(--cadushi-lime); border-color: var(--cadushi-lime); color: #0a0a0a; }
@media (max-width: 720px) {
  body.shell-ios .finanzas-header > .finanzas-tema-bar {
    translate: calc(28px - clamp(28px, calc(100vw - 332px), 48px)) -5.5px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .finanzas-topbar-config, .finanzas-topbar-config svg { transition: none; }
  .finanzas-topbar-config[aria-current="page"] svg { transform: none; }
}

/* Shared selection motion; existing calendar structure, tokens and presets. */
.finanzas-calendario-motion { position: relative; }
.finanzas-calendario-motion[data-range-interactive="true"] { touch-action: none; }
.finanzas-rango-capa { position: absolute; inset: 0; pointer-events: none; }
.finanzas-rango-banda { position: absolute; border-radius: 999px; background: color-mix(in srgb, var(--cadushi-lime) 20%, transparent); }
.finanzas-rango-extremo { position: absolute; border-radius: 50%; background: var(--cadushi-lime); }
.finanzas-calendario-motion .finanzas-calendario-dia { position: relative; z-index: 1; }
.finanzas-calendario-motion .es-rango-preview-fin:not(.es-hoy) { color: var(--primary-foreground); border-radius: 50%; }
.finanzas-calendario-grid:not(.finanzas-calendario-grid-mes) .finanzas-calendario-dia.en-rango.es-fin { border-radius: 50%; }
@media (prefers-reduced-motion: reduce) { .finanzas-rango-banda, .finanzas-rango-extremo { transition: none; } }

/* UIArc selection geometry also remains visible after confirmation: the
   band belongs to the week overlay, never to separate square day cells. */
.finanzas-calendario-motion .finanzas-calendario-dia { background: transparent !important; border-color: transparent !important; border-radius: 50% !important; color: var(--foreground) !important; font-weight: 500; }
.finanzas-calendario-motion .finanzas-calendario-dia.es-rango-extremo { color: #0a0a0a !important; }
.finanzas-calendario-motion .finanzas-calendario-dia.es-hoy::after { content: ""; position: absolute; bottom: 5px; left: 50%; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--cadushi-lime); }
.finanzas-calendario-motion .finanzas-calendario-dia.es-hoy.es-rango-extremo::after { background: #0a0a0a; }

/* Single-date capture uses the same lime circles and Bogota today mark. */
#finanzas-fecha-abrir { display:flex; width:100%; padding:0 .35rem; cursor:pointer; font-family:inherit; }
#finanzas-fecha-abrir:focus-visible { outline:2px solid var(--foreground); outline-offset:-2px; }

/* Currency filter keeps its value while presentation follows available space. */
.finanzas-moneda-desglose .currency-filter-circles { display:flex; gap:inherit; }
.finanzas-moneda-desglose .currency-filter-circles[hidden],
.finanzas-moneda-desglose .currency-filter-pill[hidden] { display:none; }
.finanzas-moneda-desglose .currency-filter-pill { width:88px; max-width:100%; min-width:0; height:44px; padding:0 8px; border:1px solid #294000; border-radius:999px; background:#c6f135; color:#182600; font:inherit; font-size:.7rem; cursor:pointer; }
.finanzas-moneda-desglose .currency-filter-pill:focus-visible { outline:2px solid var(--foreground); outline-offset:2px; }

.finanzas-monedas, .finanzas-microfono-ayuda { margin-block: 24px; }
.finanzas-monedas-lista { list-style: none; padding: 0; display: grid; gap: 10px; }
.finanzas-monedas-lista li { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.finanzas-monedas-lista small { display: block; font-size: 11px; opacity: .7; }
.finanzas-monedas .finanzas-field { min-width: 0; flex: 1; }
.finanzas-monedas select { width: 100%; min-height: 44px; max-width: 100%; }

/* Equal side tracks center the label independently of the selection mark. */
.finanzas-moneda-desglose .currency-filter-pill { display: grid; grid-template-columns: 10px 1fr 10px; align-items: center; gap: 3px; text-align: center; }
.currency-filter-menu { position: fixed; z-index: 1500; padding: 6px; border: 1px solid var(--foreground); border-radius: 18px; background: var(--background); color: var(--foreground); box-shadow: 0 12px 32px rgb(0 0 0 / .18); }
.currency-filter-menu[hidden] { display: none; }
.currency-filter-menu [role="option"] { display: grid; grid-template-columns: 18px 1fr 18px; align-items: center; width: 100%; min-height: 44px; padding: 0 8px; border: 0; border-radius: 12px; background: transparent; color: inherit; font: inherit; font-size: .8rem; text-align: center; cursor: pointer; }
.currency-filter-menu [role="option"][aria-selected="true"] { background: var(--cadushi-lime); color: #0a0a0a; }
.currency-filter-check { visibility: hidden; }
.currency-filter-menu [aria-selected="true"] .currency-filter-check { visibility: visible; }
.currency-filter-menu [role="option"]:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; }
body.shell-ios .finanzas-monedas button { min-height: 44px; padding: 0 14px; border-radius: 999px; }
body.shell-ios .finanzas-monedas-lista button { border: 1px solid #b91c1c; background: #b91c1c; color: #fff; }
body.shell-ios .finanzas-monedas-lista button:disabled { border-style: dashed; background: transparent; color: #9f1239; opacity: 1; cursor: not-allowed; }
[data-tema="oscuro"] body.shell-ios .finanzas-monedas-lista button:disabled { color: #fda4af; border-color: #fda4af; }

.finanzas-topbar .finanzas-moneda-desglose .currency-filter-pill { width: 88px; padding-inline: 8px; }
.currency-filter-label { white-space: nowrap; }

/* Requested compact views: scoped to their existing finance surfaces. */
body.shell-ios:has(#finanzas-configuracion:not([hidden])) .finanzas-header { padding-left: 1.5rem; align-items: flex-start; }
body.shell-ios:has(#finanzas-configuracion:not([hidden])) .finanzas-header-fila { align-items: flex-start; }
body.shell-ios:has(#finanzas-configuracion:not([hidden])) #finanzas-title { position: relative; top: -1.5px; }
body.shell-ios #finanzas-movimientos-lista { border: 0; border-radius: 0; background: transparent; overflow: visible; }
.category-choice-popup { padding-top: 58px; }
.category-choice-popup .category-choice-close { position: absolute; top: 6px; right: 6px; width: 44px; height: 44px; min-width: 44px; padding: 0; font-size: 1.35rem; background: transparent; }
.category-choice-popup .category-icon-entry { grid-column: 1/-1; width: 100%; border: 1px solid var(--border); border-radius: 999px; background: var(--secondary); color: var(--foreground); font: inherit; }
.category-choice-popup .category-icon-panel { grid-column: 1/-1; min-width: 0; }
.category-choice-popup .category-icon-panel[hidden] { display: none; }
.category-icon-group-label { display: grid; gap: 8px; font-size: .75rem; }
.category-icon-group-label select { width: 100%; min-height: 44px; padding: 0 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--background); color: var(--foreground); font: inherit; }
.category-icon-grid { display: grid; grid-template-columns: repeat(5,minmax(0,1fr)); gap: 4px; margin-top: 8px; }
.category-icon-grid .finanzas-icono-item { width: 100%; min-width: 0; min-height: 44px; padding: 0; display: grid; place-items: center; }
.category-choice-popup :focus-visible { outline: 2px solid var(--foreground); outline-offset: 2px; }

/* Local ExpandableCard adaptation: real geometry; controls stay mounted/inert. */
body.shell-ios #finanzas-configuracion { display: grid; gap: 12px; }
body.shell-ios #finanzas-configuracion[hidden] { display: none; }
body.shell-ios #finanzas-configuracion .settings-card {
  padding: 0; margin: 0; border: 1px solid var(--border);
  border-radius: 22px; background: var(--card); color: var(--foreground);
  overflow: clip; min-width: 0;
}
body.shell-ios #finanzas-configuracion .settings-card > h4 { margin: 0; color: inherit; font: inherit; }
body.shell-ios #finanzas-configuracion .settings-card-trigger {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  width: 100%; min-height: 64px; padding: 18px 20px;
  border: 0; border-radius: 22px; background: transparent;
  color: var(--foreground); font: inherit; font-size: .875rem; font-weight: 500; text-align: left; cursor: pointer;
}
body.shell-ios #finanzas-configuracion .settings-card-trigger:focus-visible {
  outline: 2px solid var(--foreground); outline-offset: -4px;
}
body.shell-ios #finanzas-configuracion .settings-card-arrow {
  display: inline-flex; width: 18px; align-items: center; justify-content: center;
  transition: transform 400ms cubic-bezier(.22,1,.36,1);
}
body.shell-ios #finanzas-configuracion .settings-card[data-expanded="true"] .settings-card-arrow { transform: rotate(180deg); }
body.shell-ios #finanzas-configuracion .settings-card-panel { height: 0; overflow: clip; }
body.shell-ios #finanzas-configuracion .settings-card-content {
  padding: 0 20px 20px; min-width: 0; opacity: 0;
  transition: opacity 100ms cubic-bezier(.22,1,.36,1);
}
body.shell-ios #finanzas-configuracion .settings-card[data-expanded="true"] .settings-card-content {
  opacity: 1; transition: opacity 240ms cubic-bezier(.22,1,.36,1) 120ms;
}
@media (prefers-reduced-motion: reduce) {
  body.shell-ios #finanzas-configuracion .settings-card-arrow,
  body.shell-ios #finanzas-configuracion .settings-card-content { transition: none; }
}

/* Restore the compact palette footprint; one body changes between colors/icons. */
.category-choice-popup { display:block; container-type:inline-size; --category-swatch-diameter:40px; padding:12px; width:calc(100vw - 16px); }
.category-appearance-controls { display:grid; grid-template-columns:calc((100% - 16px) / 5) minmax(0,1fr); column-gap:4px; align-items:center; height:44px; margin:0 0 8px; }
.category-appearance-controls .category-group-host { grid-column:2; grid-row:1; }
.category-choice-popup .category-icon-entry { position:relative; grid-column:1; grid-row:1; justify-self:center; display:grid; place-items:center; width:44px; height:44px; padding:0; border:0; border-radius:50%; background:transparent; color:var(--foreground); }
.category-choice-popup .category-icon-entry::before { content:""; position:absolute; width:40px; height:40px; box-sizing:border-box; border:1px solid var(--border); border-radius:50%; background:var(--secondary); }
.category-choice-popup .category-icon-entry > svg { position:relative; display:block; width:20px; height:20px; margin:0; justify-self:center; align-self:center; }
.category-choice-popup .category-icon-entry > .category-color-orb { position:relative; }
.category-choice-popup[data-appearance="icons"] .category-icon-entry::before { background:transparent; border:0; }
.category-appearance-body { min-height:140px; }
.category-appearance-controls [hidden] { display:none; }
.category-color-grid { display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); grid-template-rows:repeat(3,44px); gap:4px; height:140px; }
.category-color-grid .finanzas-color-item { position:relative; width:100%; min-width:0; height:44px; background:transparent; border:0; box-shadow:none; }
.category-color-grid .finanzas-color-item::before { content:""; position:absolute; top:50%; left:50%; width:var(--category-swatch-diameter); height:var(--category-swatch-diameter); box-sizing:border-box; transform:translate(-50%,-50%); border:2px solid transparent; border-radius:50%; background:hsl(var(--cat-hue,240) 65% 52%); }
.category-color-grid .finanzas-color-item.es-actual::before { border-color:var(--foreground); box-shadow:inset 0 0 0 2px var(--background); }
.category-icon-groups { display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:3px; }
.category-choice-popup .category-icon-group { display:grid; place-items:center; min-width:0; padding:0; border:1px solid transparent; border-radius:10px; background:var(--secondary); color:var(--foreground); }
.category-choice-popup .category-icon-group[aria-pressed="true"] { border-color:var(--foreground); background:var(--background); }
.category-icon-grid { display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); grid-template-rows:repeat(3,44px); grid-auto-rows:44px; gap:4px; height:140px; overflow-y:auto; overscroll-behavior:contain; margin-top:0; }

.category-icon-grid .finanzas-icono-item { width:100%; min-width:0; min-height:44px; padding:0; display:grid; place-items:center; }
.category-choice-popup :focus-visible { outline:2px solid var(--foreground); outline-offset:2px; }

.category-color-orb { display:block; box-sizing:border-box; width:var(--category-swatch-diameter); height:var(--category-swatch-diameter); border:2px solid transparent; border-radius:50%; background:radial-gradient(ellipse at 30% 25%,#ffe689b3,transparent 65%),radial-gradient(ellipse at 78% 28%,#76bcffcf,transparent 68%),radial-gradient(ellipse at 75% 85%,#a978ffcf,transparent 68%),radial-gradient(ellipse at 20% 80%,#73dba6cf,transparent 68%),linear-gradient(135deg,#e99391,#b398df); box-shadow:inset 0 0 0 1px #ffffff24; }

/* Approved Oct 6 selection on the existing Staging detailed editor. */
body.shell-ios:has(#finanzas-configuracion:not([hidden])) .finanzas-header > .finanzas-tema-bar { translate: var(--settings-theme-offset, 0px) 0; align-self: center; }
#finanzas-movimientos-lista .finanzas-movimiento-monto[data-tipo="gasto"] { color: #bd203e; }
#finanzas-movimientos-lista .finanzas-movimiento-monto[data-tipo="ingreso"] { color: #146c3a; }
html[data-tema="oscuro"] #finanzas-movimientos-lista .finanzas-movimiento-monto[data-tipo="gasto"] { color: #ff728d; }
html[data-tema="oscuro"] #finanzas-movimientos-lista .finanzas-movimiento-monto[data-tipo="ingreso"] { color: #67db95; }

/* Approved summary colors accompany the Ingresos/Gastos/Neto promotion. */
.finanzas-movimientos-total:has(#finanzas-movimientos-gastos) { color: #bd203e; }
.finanzas-movimientos-total:has(#finanzas-movimientos-ingresos) { color: #146c3a; }
html[data-tema="oscuro"] .finanzas-movimientos-total:has(#finanzas-movimientos-gastos) { color: #ff728d; }
html[data-tema="oscuro"] .finanzas-movimientos-total:has(#finanzas-movimientos-ingresos) { color: #67db95; }

/* Bencho Search, MIT © 2026 Lorenzo Cabra; supplied source adapted for
   Cadushi. https://bencho.dev/licence. Original comments follow. */
/* ── flat panes ────────────────────────────────────────────
   Set data-surface="flat" on any ancestor and every glass
   surface under it becomes a solid fill with a hairline. The
   inner buttons already sit on rgba(var(--ink-rgb), 0.05)
   with no border, which is what flat wants anyway, so they
   need nothing.

   The frost is switched off at the element rather than through
   a token. A var() holding a url() filter cannot be validated
   at parse time, so the browser would treat it as invalid at
   computed-value time and drop the property outright — which
   breaks the two-declaration fallback the glass depends on. */
/* ══ stroke ═════════════════════════════════════════════════
   Whether a component draws a hairline round itself. OFF by
   default, which is the change: every glass surface carried
   one unconditionally, and a grey line round everything makes
   a wall of components look like a wall of boxes rather than
   a wall of things.

   The line is not load-bearing. A flat pane is a fill against
   a different fill and reads on its own; the ring was there
   to sharpen an edge that was already there.

   Placed ABOVE the glass rules on purpose. Glass draws its
   own lit rim, and that rim is the material rather than a
   stroke — it is what gives a pane thickness. So glass wins
   the border wherever the two meet, and Stroke governs the
   drawn line that flat surfaces would otherwise have. */
/* Cadushi: retain only Search's selector; no lab/card/nav/dock rules. */
/* the playful blocks. None of them is glass, so none has a
   lit rim for the stroke to lose to — the hairline is the
   only edge they can have, and it is the whole of what this
   control does for them. */
[data-stroke="on"] .sek .sek-skin::before { border-color: var(--pane-edge); }

/* ══ Seek ═══════════════════════════════════════════════════
   A search icon that becomes a search field, as one object.

   Everything below is width and radius. There is no crossfade
   between two components, no second element to keep in sync,
   and nothing that animates on a clock of its own — the box
   is sprung in JS and every other value here is derived from
   how far through that spring it is. That is the whole reason
   the transformation reads as continuous: there is only one
   number, so nothing can arrive at the wrong time relative to
   anything else. */
.sek {
  /* Cadushi aliases stay on this component, never :root.
     All ink tiers use the existing semantic foreground or muted foreground.
     No glass equivalent: local neutral filter values. --ink-rgb is measured
     from --foreground by the island bridge, three comma-separated numbers. */
  --bg: var(--background);
  --font-ui: var(--font-sans);
  --g-blur: 0px;
  --g-sat: 100%;
  --ink: var(--foreground);
  --ink-2: var(--foreground);
  --ink-3: var(--muted-foreground);
  --ink-4: var(--muted-foreground);
  --ink-5: var(--muted-foreground);
  --ink-rgb: var(--search-ink-rgb, 9, 9, 11);
  --pane: var(--muted);
  --pane-edge: var(--border);
  /* the frame is the composition. It never moves, which is
     what gives the magnet a stable home to measure from and
     keeps the object centred at every width. */
  position: relative;
  display: grid;
  /* Cadushi: latest product request supersedes the original centered frame
     described above. Keep its geometry/motion, anchored to the left gutter. */
  place-items: center start;
  /* Bound the live grid track before ResizeObserver can update the spring.
     An auto track may retain the child's previous intrinsic width on resize. */
  grid-template-columns: minmax(0, 1fr);
  /* ── THE FRAME IS `--frame`, and it was not ──────────────
     Seek.tsx computes `--frame` and `--frameh` from the width
     that is actually set — its note explains why at length:
     the wall fits a card by the BOUNDING BOX, so a frame sized
     for the widest the knob goes makes every smaller setting
     draw smaller. It has been publishing those two numbers to
     a stylesheet that ignored them and used a hard 380 x 96.

     Measured on a phone card: the frame reserved 380 for a
     field set to 320, the wall fitted 380 into 260, and the
     shut button — the only thing drawn at rest — came out at
     44px. The 36px of nothing was being paid for in the one
     part of the object you are looking at.

     With the variables wired up the knob does what its own
     comment says it does, and the frame is tight to what is
     set on every screen. */
  /* Cadushi: the actual container is the stable frame; JS observes it.
     No demo scaling, and row height stays fixed through expansion. */
  width: 100%;
  min-width: 0;
  height: var(--frameh, 64px);
  font-family: var(--font-ui);
}

/* ── the object ─────────────────────────────────────────────
   Width is the state. Height is fixed, so the radius can be
   derived from the width rather than animated beside it —
   at 44 the corner is 22 and the shape IS a circle, and there
   is no frame where the two disagree.

   The surface is the quietest thing that still reads as an
   object: a low-alpha ink fill and a hairline. No shadow, no
   glass, no gradient — at this size any of them would be the
   loudest thing on an otherwise empty page. */
.sek-skin {
  position: relative;
  width: var(--w);
  /* Keep the original spring inside the actual column, including the 5px
     outer focus ring. Resting target widths already reserve26px, unchanged. */
  max-width: calc(100% - 6px);
  /* --shut, NOT a number. The component sets the closed width
     and the height from one constant precisely so they cannot
     drift, and its own comment says so: "the skin's height and
     the closed width are the same number by definition, and
     two places holding it is two places to get it wrong."
     Hard-coded here at 44 against a --shut of 64, the closed
     state was a 64x44 lozenge — a circle that is not round is
     the one shape everybody notices. */
  height: var(--shut);
  /* ── ONE SHAPE RULE ─────────────────────────────────────
     Fully round, at every width. The radius used to
     interpolate 22 → 13, which was a second thing to keep in
     agreement with the first; a stadium corner needs no
     agreement at all. At --shut wide it is a circle and at 320
     a pill, and those are the same rule rather than two ends
     of a tween. Height is fixed, so it cannot be anything
     else. */
  /* the Corner knob's, and ::before and .sek-hit inherit it */
  border-radius: var(--sek-r, 999px);
  /* ── FLAT, and glass only if asked ──────────────────────
     `--pane` is the bench's own material token, so this
     follows the Glass dial rather than deciding for itself:
     at 0 it resolves to a solid board and at 100 to the
     frosted pane. It was a translucent ink wash with an inset
     hairline, which is glass by every visual measure while
     answering to no control — the worst of both, since it
     could not be turned off.

     And it picks up Fill for free. Flat resolves --pane to
     --board, and Fill redeclares --board, so a dark fill
     gives a dark pill without this rule naming a colour. */
  background: var(--pane);
  -webkit-backdrop-filter: blur(var(--g-blur, 2px)) saturate(var(--g-sat, 150%)) brightness(var(--g-bright, 100%));
  backdrop-filter: blur(var(--g-blur, 2px)) saturate(var(--g-sat, 150%)) brightness(var(--g-bright, 100%));
  isolation: isolate;
  /* the magnet, and the press, on one transform — two
     transforms on one element is one of them winning */
  transform: translate(var(--lx), var(--ly)) scale(var(--sk, 1));
  transform-origin: left center;
  transition: transform 260ms cubic-bezier(0.22, 0.9, 0.28, 1), background 220ms ease;
  /* the field is inside from the first frame; this is what
     keeps it from spilling out of a 44px circle */
  overflow: hidden;
}

/* the edge, and NOTHING until Stroke asks for it. A hairline
   nobody switched on is a hairline the control cannot remove,
   which is the same bug the background had. */
.sek-skin::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid transparent;
  pointer-events: none;
  z-index: 2;
}

/* Hover: it comes up a hair and lifts off the ground. Both
   are small enough to be felt rather than seen, which is the
   point — a hover state you notice is a hover state that has
   said too much. */
.sek:not([data-open="true"]) .sek-skin:hover {
  --sk: 1.045;
  /* the surface answers, without drawing an edge it was not
     given — brightness rather than an outline */
  --g-bright: 104%;
}

/* pressed: it yields before it moves. A thing that gives
   under a click reads as having been pushed; a thing that
   only expands reads as having been triggered. */
.sek[data-press="true"] .sek-skin { --sk: 0.93; transition: transform 90ms cubic-bezier(0.4, 0, 0.6, 1); }
/* the field is a text target, and the object is a button */
.sek[data-open="true"] .sek-skin { cursor: text; }

/* ── the lens ───────────────────────────────────────────────
   Fixed to the box's left inset and never animated. At the
   shut width that inset centres it; at the open width it is
   the field's padding. The lens crossing the page is the box
   growing around a mark that stayed still. */
.sek-lens {
  position: absolute;
  left: var(--inset);
  top: 50%;
  width: var(--lens);
  height: var(--lens);
  margin-top: calc(var(--lens) / -2);
  fill: none;
  stroke: var(--ink-3);
  /* 1.5, AND THE NUMBER CANNOT BE COMPARED TO LUCIDE'S.
     Every lucide glyph is drawn on a 24-unit grid; this one is
     drawn on 18. A stroke-width of u paints at u/viewBox of
     the icon's size, so lucide's 2-on-24 is 0.0833 and a 2
     here would be 0.1111 — the same number, a third heavier.
     1.5/18 is 0.0833 exactly, which is the radial menu's
     weight and the nav's.

     The value that stood here was 1.6 (0.0889). That was very
     nearly right; it was changed to 2 on the assumption that
     the two viewBoxes matched, and they never did. */
  stroke-width: 1.5;
  stroke-linecap: round;
  pointer-events: none;
  transition: stroke 200ms ease, stroke-width 200ms ease;
}
.sek-skin:hover .sek-lens { stroke: var(--ink); }
.sek[data-open="true"] .sek-lens { stroke: var(--ink-4); }

/* typing: the lens thickens a hair and darkens. One beat per
   burst, not one per keystroke — a mark that flickers at the
   rate of your typing is noise wearing the costume of
   feedback. */
/* still "a hair", and still the same proportion of the base it
   always was — 1.9 was to 1.6 as 1.8 is to 1.5 */
.sek[data-busy="true"] .sek-lens { stroke: var(--ink-2); stroke-width: 1.8; }

/* ── the field ──────────────────────────────────────────────
   Present from the first frame and revealed by --say, which
   is the last third of the width's own progress. It slides a
   few pixels as it arrives, from the left, so it reads as
   having come out of the lens rather than as having faded up
   where it stood. */
.sek-field {
  position: absolute;
  left: calc(var(--inset) + var(--lens) + 11px);
  right: 44px;
  top: 0;
  height: 100%;
  min-width: 0;
  width: calc(100% - var(--inset) - var(--lens) - 55px);
  border: 0;
  background: none;
  font: inherit;
  /* 14 is the NAV's size, and the nav's field is 44px tall.
     This pill is --shut, 64, and carrying header type in it
     left the words looking like a caption inside the object
     rather than its content. 18 restores roughly the
     proportion the bar has — 0.28 of the height against the
     bar's 0.32 — on a control that is the whole component
     rather than one item in a row of them. */
  /* Cadushi: 16px at 48px height also prevents iOS focus zoom. */
  font-size: 16px;
  letter-spacing: -0.005em;
  color: var(--ink);
  outline: none;
  opacity: var(--say);
  transform: translateX(calc((1 - var(--say)) * -6px));
  /* until it is most of the way open it is not a target, and
     a caret that can be placed in a 44px circle is a caret in
     the wrong place */
  pointer-events: var(--say-hit, none);
}
.sek[data-open="true"] .sek-field { --say-hit: auto; }
.sek-field::placeholder { color: var(--ink-5); }

/* the way in, while there is one */
.sek-hit { position: absolute; inset: 0; border: 0; border-radius: inherit; background: none; cursor: pointer; }
.sek-hit:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px rgba(var(--ink-rgb), 0.4); }
/* Cadushi: skin overflow clips the original button shadow; draw the same
   focus ring outside the skin for button, input and clear control. */
.sek-skin:has(:focus-visible) { outline: 2px solid var(--ring); outline-offset: 3px; }
.sek-clear { position: absolute; top: 0; right: 0; width: 44px; height: var(--shut); border: 0; background: none; color: var(--ink-2); font: inherit; font-size: 22px; cursor: pointer; }
.sek-field::-webkit-search-cancel-button { -webkit-appearance: none; }
.sek[data-flat] .sek-skin, .sek[data-flat] .sek-lens { transition: none; }
.sek[data-flat] .sek-skin:hover { --sk: 1; }
.finanzas-movimientos-search-row { width: 100%; min-width: 0; margin-bottom: 8px; }

/* Transitions.dev — Input clear with dissolve, © 2026 Jakub Antalik.
   Free recipe13 adapted to the existing Search, licenses/transitions-dev.txt.
   Only these local tokens/layers are added; the input keeps its native glyphs,
   caret and keyboard. Captured text is decorative and cancels on new typing. */
.sek {
  --sek-clear-dur: 1000ms;
  --sek-clear-out-dur: 400ms;
  --sek-clear-in-dur: 400ms;
  --sek-clear-out-fly: 12px;
  --sek-clear-in-fly: 12px;
  --sek-clear-out-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --sek-clear-in-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --sek-clear-blur: 2px;
  --sek-glow-delay: 50ms;
  --sek-glow-peak-at: .15;
  --sek-glow-opacity: .42;
  --sek-glow-spread: 1.5;
  --sek-glow-blend: multiply;
}
html[data-tema="oscuro"] .sek { --sek-glow-opacity: .85; --sek-glow-blend: screen; }
.sek-dissolve-region {
  position: absolute;
  left: calc(var(--inset) + var(--lens) + 11px);
  right: 44px;
  top: 0;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
  visibility: hidden;
  opacity: var(--say);
}
.sek[data-clearing="true"] .sek-dissolve-region { visibility: visible; }
.sek[data-clearing="true"] .sek-field::placeholder { color: transparent; }
.sek-dissolve-mirror, .sek-dissolve-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  pointer-events: none;
  white-space: pre;
  overflow: hidden;
  z-index: 2;
}
.sek-dissolve-mirror { color: var(--ink); opacity: 0; }
.sek-dissolve-mirror span { flex-shrink: 0; }
.sek-dissolve-placeholder { color: var(--ink-5); }
/* The JS writes the recipe's per-word gradient stack and rise/peak/fall
   envelope. Multiply darkens a light pane; screen lights a dark one. */
.sek-dissolve-glow { position: absolute; inset: 0; pointer-events: none; opacity: 0; z-index: 3; mix-blend-mode: var(--sek-glow-blend); }
@media (prefers-reduced-motion: reduce) {
  .sek .sek-dissolve-region { visibility: hidden !important; }
  .sek .sek-dissolve-glow { opacity: 0 !important; }
  .sek[data-clearing="true"] .sek-field::placeholder { color: var(--ink-5); }
}

/* A quiet separator sits in the existing 1.4rem flex gap. Absolute position
   consumes no number width and keeps the approved labels, signs and colors. */
.finanzas-movimientos-total { position: relative; }
.finanzas-movimientos-total + .finanzas-movimientos-total::before {
  content: "";
  position: absolute;
  inset-inline-start: -.7rem;
  top: .3rem;
  bottom: .3rem;
  width: 1px;
  background: var(--border);
  opacity: .55;
}

/* Discarded history: the original native action now shares Search's row.
   Reserve its target track before either spring moves; the12px gap contains
   both focus rings. minmax(0,1fr) keeps the live input inside its own track.
   The complete visible state wraps inside the existing48px height; the
   accessible name retains the available action and history count. */
.finanzas-movimientos-search-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 48px;
  gap: 12px;
  align-items: center;
}
.finanzas-movimientos-search-row[data-eye-space="expanded"] { grid-template-columns: minmax(0, 1fr) min(136px, 48%); }
#finanzas-movimientos-search { min-width: 0; }
.discard-eye-frame { min-width: 0; display: flex; justify-content: flex-end; }
.discard-eye {
  position: relative;
  flex: none;
  width: var(--eye-width, 48px);
  max-width: 100%;
  min-width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  border-radius: 24px;
  background: var(--muted);
  color: var(--muted-foreground);
  font-family: var(--font-sans);
  cursor: pointer;
  transform-origin: right center;
  overflow: hidden;
  transition: transform 90ms cubic-bezier(.4,0,.6,1), color 200ms ease;
}
.discard-eye:hover { color: var(--foreground); }
.discard-eye:active { transform: scaleX(.96); }
.discard-eye:focus-visible { outline: 2px solid var(--ring); outline-offset: 3px; }
.discard-eye-icon { position: absolute; right: 13.5px; top: 13.5px; width: 21px; height: 21px; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.discard-eye-label { position: absolute; left: 11px; right: 43px; top: 0; height: 48px; display: flex; align-items: center; font-size: 12px; line-height: 14px; text-align: left; white-space: normal; opacity: var(--eye-say, 0); pointer-events: none; }
.discard-eye-aperture, .discard-eye-pupil {
  transform-box: view-box;
  transform-origin: center;
  transition: transform 180ms cubic-bezier(.2,0,.2,1);
}
.discard-eye-aperture { transform: scaleY(.72); }
.discard-eye-pupil { transform: scale(.65); }
.discard-eye-slash { stroke-dasharray: 1; stroke-dashoffset: 0; opacity: 1; transition: stroke-dashoffset 180ms cubic-bezier(.2,0,.2,1), opacity 180ms ease; }
.discard-eye[aria-pressed="true"] .discard-eye-aperture,
.discard-eye[aria-pressed="true"] .discard-eye-pupil { transform: scale(1); }
.discard-eye[aria-pressed="true"] .discard-eye-slash { stroke-dashoffset: 1; opacity: 0; }
.discard-eye[data-flat="true"] .discard-eye-icon * { transition: none; }
.discard-eye[data-flat="true"] { transition: none; }
.discard-eye[data-flat="true"]:active { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .discard-eye, .discard-eye .discard-eye-icon * { transition: none; }
  .discard-eye:active { transform: none; }
}

/* Approved dark surface hierarchy: subtle neutral layers, without changing
   clear mode, financial accents, navigation, or the real voice controls. */
:root[data-tema="oscuro"] body.shell-ios {
  --cadushi-black: #dedede;
  --cadushi-ink: #dedede;
  --cadushi-mute: #a8a8a8;
  --cadushi-line: rgb(255 255 255 / 0.08);
  --cadushi-wash: #1d1d1d;
  --foreground: #dedede;
  --card: #141414;
  --cadushi-modal: #262626;
  --cadushi-caption: #929292;
  --card-foreground: #dedede;
  --popover: #1d1d1d;
  --popover-foreground: #dedede;
  --secondary: #1d1d1d;
  --muted: #1d1d1d;
  --muted-foreground: #a8a8a8;
  --border: #858585;
  --input: #858585;
}
:root[data-tema="oscuro"] body.shell-ios :is(.finanzas-card.ds-card:not(.finanzas-card-ingreso), .finanzas-lista, .settings-card) { background: var(--card); border-color: var(--cadushi-line); }
:root[data-tema="oscuro"] body.shell-ios .finanzas-card-gasto > .ds-card-header > h3 { background: var(--card); }
:root[data-tema="oscuro"] body.shell-ios #finanzas-recientes .finanzas-fila { background: var(--card); border-color: var(--cadushi-line); }
:root[data-tema="oscuro"] body.shell-ios .finanzas-card-gasto .finanzas-categorias-lista { border-top-color: var(--cadushi-line); }
:root[data-tema="oscuro"] body.shell-ios :is(.finanzas-calendario, .category-choice-popup, .currency-filter-menu) { background: var(--popover); border-color: var(--cadushi-line); }
:root[data-tema="oscuro"] body.shell-ios .movement-sheet-overlay .finanzas-ficha { --card: var(--cadushi-modal); background: var(--cadushi-modal); border-color: var(--cadushi-line); }
:root[data-tema="oscuro"] body.shell-ios .finanzas-movimientos-filtros :is(select, .finanzas-movimientos-origen-pill),
:root[data-tema="oscuro"] body.shell-ios .movement-detail-input:not([aria-invalid="true"]),
:root[data-tema="oscuro"] body.shell-ios :is(.finanzas-periodo-selector, .tema-toggle, .finanzas-boton-ghost) { border-color: var(--input); }
:root[data-tema="oscuro"] body.shell-ios #finanzas-movimientos-tipo.es-gasto { color: #ff728d; }
:root[data-tema="oscuro"] body.shell-ios #finanzas-movimientos-tipo.es-ingreso { color: #67db95; }
:root[data-tema="oscuro"] body.shell-ios :is(.movement-detail-date, .movement-detail-help) { color: var(--cadushi-caption); }
:root[data-tema="oscuro"] body.shell-ios .app-sidebar { border-right-color: var(--cadushi-line); }
@media (prefers-color-scheme: dark) {
  :root:not([data-tema]) body.shell-ios {
    --cadushi-black: #dedede;
    --cadushi-ink: #dedede;
    --cadushi-mute: #a8a8a8;
    --cadushi-line: rgb(255 255 255 / 0.08);
    --cadushi-wash: #1d1d1d;
    --foreground: #dedede;
    --card: #141414;
    --cadushi-modal: #262626;
    --cadushi-caption: #929292;
    --card-foreground: #dedede;
    --popover: #1d1d1d;
    --popover-foreground: #dedede;
    --secondary: #1d1d1d;
    --muted: #1d1d1d;
    --muted-foreground: #a8a8a8;
    --border: #858585;
    --input: #858585;
  }
  :root:not([data-tema]) body.shell-ios :is(.finanzas-card.ds-card:not(.finanzas-card-ingreso), .finanzas-lista, .settings-card) { background: var(--card); border-color: var(--cadushi-line); }
  :root:not([data-tema]) body.shell-ios :is(.finanzas-calendario, .category-choice-popup, .currency-filter-menu) { background: var(--popover); border-color: var(--cadushi-line); }
  :root:not([data-tema]) body.shell-ios .movement-sheet-overlay .finanzas-ficha { --card: var(--cadushi-modal); background: var(--cadushi-modal); border-color: var(--cadushi-line); }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-tema]) body.shell-ios .finanzas-card-gasto > .ds-card-header > h3 { background: var(--card); }
  :root:not([data-tema]) body.shell-ios #finanzas-recientes .finanzas-fila { background: var(--card); border-color: var(--cadushi-line); }
  :root:not([data-tema]) body.shell-ios .finanzas-card-gasto .finanzas-categorias-lista { border-top-color: var(--cadushi-line); }
  :root:not([data-tema]) body.shell-ios .finanzas-movimientos-filtros :is(select, .finanzas-movimientos-origen-pill),
  :root:not([data-tema]) body.shell-ios .movement-detail-input:not([aria-invalid="true"]),
  :root:not([data-tema]) body.shell-ios :is(.finanzas-periodo-selector, .tema-toggle, .finanzas-boton-ghost) { border-color: var(--input); }
  :root:not([data-tema]) body.shell-ios #finanzas-movimientos-tipo.es-gasto { color: #ff728d; }
  :root:not([data-tema]) body.shell-ios #finanzas-movimientos-tipo.es-ingreso { color: #67db95; }
  :root:not([data-tema]) body.shell-ios :is(.movement-detail-date, .movement-detail-help) { color: var(--cadushi-caption); }
  :root:not([data-tema]) body.shell-ios .app-sidebar { border-right-color: var(--cadushi-line); }
}

/* Approved mobile financial presentation; Stage desktop/tablet and voice contracts stay intact. */
@media (max-width:600px) {
/* Exact filtered original-currency subtotals, never a cross-currency sum. */
.finanzas-movimientos-subtotal { display:block; font-size:13px; line-height:1.5; overflow-wrap:anywhere; }

/* One canonical currency, three filters and one exact-money summary row. */
.finanzas-movimientos-filtros { grid-template-columns:repeat(3,minmax(0,1fr)); }
.finanzas-movimientos-totales { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(6px,2vw,18px); }
.finanzas-movimientos-total { min-width:0; }
.finanzas-movimientos-total strong { min-width:0; font-size:clamp(11px,2.8vw,15px); }
.finanzas-movimientos-subtotal { font-size:inherit; overflow-wrap:anywhere; }

/* Exact metric values use one line; exceptional long amounts remain locally scrollable. */
.finanzas-movimientos-total strong { display:block; min-width:0; overflow-x:auto; white-space:nowrap; scrollbar-width:thin; }
.finanzas-movimientos-subtotal { white-space:nowrap; overflow-wrap:normal; }
[data-metric-currency] { white-space:nowrap; }

.finanzas-movimientos-total .finanzas-fijos-total-label { display:flex; align-items:baseline; gap:4px; white-space:nowrap; font-size:clamp(11px,2.8vw,14px); }

/* Fourth review: phone surfaces only; original Citron and category hues retain their source. */
@media (max-width:600px) {
 :root[data-tema="oscuro"] body.shell-ios {--cadushi-white:#000000; --cadushi-black:#ffffff; --cadushi-ink:#ffffff; --foreground:#ffffff; --card-foreground:#ffffff; --popover-foreground:#ffffff; --background:#000000; --card:#171916; --popover:#20251b;
    --cadushi-mute:color-mix(in srgb,#ffffff 68%,#000000);
    --cadushi-line:color-mix(in srgb,#ffffff 24%,#000000);
    --cadushi-wash:color-mix(in srgb,#ffffff 10%,#000000);
    --secondary:color-mix(in srgb,#ffffff 10%,#000000);
    --muted:color-mix(in srgb,#ffffff 10%,#000000);
    --muted-foreground:color-mix(in srgb,#ffffff 68%,#000000);
    --border:color-mix(in srgb,#ffffff 24%,#000000);
    --input:color-mix(in srgb,#ffffff 24%,#000000);
    --finanzas-tabbar-bg:color-mix(in srgb,#000000 92%,transparent);
    background:#000000;}
 :root[data-tema="oscuro"] .cadushi-apertura {background:#000000;}
 :root[data-tema="oscuro"] .cadushi-apertura-icono > g path {fill:#ffffff;}
}
@media (max-width:600px) and (prefers-color-scheme:dark) {
 :root:not([data-tema]) body.shell-ios {--cadushi-white:#000000; --cadushi-black:#ffffff; --cadushi-ink:#ffffff; --foreground:#ffffff; --card-foreground:#ffffff; --popover-foreground:#ffffff; --background:#000000; --card:#171916; --popover:#20251b;
    --cadushi-mute:color-mix(in srgb,#ffffff 68%,#000000);
    --cadushi-line:color-mix(in srgb,#ffffff 24%,#000000);
    --cadushi-wash:color-mix(in srgb,#ffffff 10%,#000000);
    --secondary:color-mix(in srgb,#ffffff 10%,#000000);
    --muted:color-mix(in srgb,#ffffff 10%,#000000);
    --muted-foreground:color-mix(in srgb,#ffffff 68%,#000000);
    --border:color-mix(in srgb,#ffffff 24%,#000000);
    --input:color-mix(in srgb,#ffffff 24%,#000000);
    --finanzas-tabbar-bg:color-mix(in srgb,#000000 92%,transparent);
    background:#000000;}
 :root:not([data-tema]) .cadushi-apertura {background:#000000;}
 :root:not([data-tema]) .cadushi-apertura-icono > g path {fill:#ffffff;}
}

/* Explicit palette metadata only; legacy category hue rules stay unchanged. */
[data-palette-id="cadushi-lima-electric-v1"] {--category-palette-cell:var(--category-palette-cell-light);--category-palette-ink:var(--category-palette-ink-light);}
:root[data-tema="oscuro"] [data-palette-id="cadushi-lima-electric-v1"] {--category-palette-cell:var(--category-palette-cell-dark);--category-palette-ink:var(--category-palette-ink-dark);}
@media(prefers-color-scheme:dark){:root:not([data-tema]) [data-palette-id="cadushi-lima-electric-v1"] {--category-palette-cell:var(--category-palette-cell-dark);--category-palette-ink:var(--category-palette-ink-dark);}}

.category-color-grid .finanzas-color-item[data-palette-id="cadushi-lima-electric-v1"]::before {background:var(--category-palette-cell);}

/* Approved V5 layer is visible only on phones; original presentation stays wider. */
@media(max-width:600px){
 [data-palette-id="cadushi-dual-analogous-proposal-v5"]{--category-palette-cell:var(--category-palette-cell-light);--category-palette-ink:var(--category-palette-ink-light);}
 :root[data-tema="oscuro"] [data-palette-id="cadushi-dual-analogous-proposal-v5"]{--category-palette-cell:var(--category-palette-cell-dark);--category-palette-ink:var(--category-palette-ink-dark);}
 [data-palette-id="cadushi-dual-analogous-proposal-v5"].finanzas-color-item::before{background:var(--category-palette-cell);}
}

@media(max-width:600px) and (prefers-color-scheme:dark){:root:not([data-tema]) [data-palette-id="cadushi-dual-analogous-proposal-v5"]{--category-palette-cell:var(--category-palette-cell-dark);--category-palette-ink:var(--category-palette-ink-dark);}}

@media(max-width:600px){
 .category-palette-restore{min-height:44px;padding:8px 12px;border:1px solid var(--border);border-radius:12px;background:var(--card);color:var(--foreground);font:inherit;cursor:pointer;margin-block:0 8px;}
}


}

@media(max-width:600px){
 .finanzas-movimientos-filtros .finanzas-field:has(#finanzas-movimientos-moneda){display:none;}
 .finanzas-movimientos-filtros{grid-template-columns:repeat(3,minmax(0,1fr));}
 .finanzas-movimientos-total [data-metric-currency]{font-size:inherit;font-weight:400;}
 .finanzas-fijos-header-datos{margin-bottom:.5rem;}
}

/* The account menu owns the same existing logout delegate; retain the card if the menu fails to mount. */
@media(max-width:600px){
 html[data-auth-ready="true"][data-cadushi-private="true"] body.shell-ios:has(#cadushi-account-menu button) #cadushi-account{display:none;}
 body.shell-ios .finanzas-microfono-ayuda{display:none;}
 .finanzas-pendiente-fijo .finanzas-pendiente-boton{min-height:44px;min-width:44px;}
 .finanzas-pendiente-fijo .finanzas-pendiente-monto{color:var(--foreground);}
 .finanzas-fija-fila .finanzas-fija-sub{white-space:normal;max-width:200px;}
}

@media(max-width:600px){
 .finanzas-fijos-lista{display:grid;grid-template-columns:minmax(0,1fr);gap:10px;padding-inline:0;list-style:none;width:100%;}
 .finanzas-fijos-lista .finanzas-fija-fila{width:100%;min-width:0;box-sizing:border-box;background:var(--card);grid-template-columns:minmax(0,1fr) auto;}
 .finanzas-fija-fila .finanzas-concepto{min-width:0;overflow-wrap:anywhere;}
 .finanzas-fija-fila .finanzas-monto{min-width:0;overflow-wrap:anywhere;}
 .finanzas-fija-fila .finanzas-fija-sub{white-space:normal;max-width:none!important;}
 .category-icon-pager{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:10px;}
 .category-icon-pager button{min-width:44px;min-height:44px;border:0;border-radius:8px;background:var(--card);color:var(--foreground);font-size:20px;}
}
/* Mobile category creation reuses the finance sheet surface and input tokens. */
@media (max-width:600px) {
 .category-mobile-heading{display:flex;align-items:center;justify-content:space-between;gap:8px;position:relative;z-index:1;}
 .category-mobile-heading h3{margin:0;font-size:18px;}
 .category-create-trigger{display:flex;align-items:center;gap:6px;min-height:44px;padding:0 10px;white-space:nowrap;font-size:13px;border-radius:22px;}
 dialog.category-create-sheet{position:fixed;inset:auto 0 0;margin:0 auto;width:100%;max-width:36rem;height:75dvh;max-height:calc(100dvh - env(safe-area-inset-top));padding:0;border:1px solid var(--border);border-bottom:0;border-radius:24px 24px 0 0;background:var(--card);color:var(--foreground);overflow:hidden;box-sizing:border-box;}
 dialog.category-create-sheet[open]{display:flex;flex-direction:column;}
 dialog.category-create-sheet::backdrop{background:rgb(0 0 0 / .28);}
 .category-create-header{padding:0 16px 8px;flex-shrink:0;}
 .category-create-header>div{display:flex;align-items:center;justify-content:space-between;gap:8px;}
 .category-create-header h3{font-size:16px;margin:0;}
 .category-create-header button{width:44px;height:44px;display:grid;place-items:center;}
 .category-sheet-handle{display:block;width:36px;height:4px;border-radius:2px;background:var(--muted-foreground);margin:10px auto 4px;}
 .category-create-body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:0 16px calc(16px + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:8px;}
 .category-create-body fieldset{padding:0;margin:0;border:0;min-width:0;}
 .category-create-body legend{font-size:14px;font-weight:600;margin-bottom:6px;}
 .category-create-hint,.category-chosen-icon{margin:0;color:var(--muted-foreground);font-size:12px;line-height:1.4;}
 .category-chosen-icon{margin:4px 0;}
 .category-create-body .category-icon-grid{grid-template-columns:repeat(5,minmax(0,1fr));grid-template-rows:repeat(3,44px);height:140px;gap:4px;}
 .category-create-submit{min-height:44px;flex-shrink:0;border-radius:22px;background:var(--cadushi-lime,#C6F135);color:#182600;}
 .category-create-body .finanzas-color-item::before{background:var(--category-draft-color);}
 .category-create-body .finanzas-color-item[aria-pressed="true"]::before{border-color:var(--foreground);box-shadow:inset 0 0 0 2px var(--card);}
 .category-icon-grid .finanzas-icono-item{border-radius:50%;width:44px;max-width:100%;justify-self:center;}
 .category-icon-grid .finanzas-icono-item[aria-pressed="true"]{background:var(--foreground);color:var(--background);}
 .category-icon-grid{grid-template-columns:repeat(5,minmax(0,1fr));grid-template-rows:repeat(3,44px);gap:4px;}
 .category-icon-pager{gap:8px;margin-top:4px;}
 .category-icon-pager button{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;}
 .category-icon-pager button:disabled{opacity:.4;}
 #finanzas-fijos-hidden-toggle{min-height:44px;font-size:13px;}
}

@media(max-width:600px){
 .cadushi-category-stack:has(.category-mobile-heading){width:100%;}
 .category-create-sheet{--category-swatch-diameter:32px;}
 .category-create-name{display:grid;gap:6px;flex-shrink:0;font-size:14px;}
}

/* Native closed dialogs must stay hidden despite the shared sheet display rule. */
dialog.category-create-sheet:not([open]){display:none;}
@media(max-width:600px){.finanzas-fijo-accion.es-ocultar{min-height:44px;}#finanzas-fijos-hidden-toggle[hidden]{display:none;}}

@media(max-width:600px){
 .finanzas-header-fila:has(#category-create-heading-action:not([hidden])){display:flex;align-items:center;justify-content:space-between;gap:8px;}
 .finanzas-header-fila:has(#category-create-heading-action:not([hidden])) #finanzas-heading{min-width:0;margin:0;font-size:clamp(1.45rem,6vw,2rem);}
 #category-create-heading-action{margin-left:auto;flex:0 0 auto;}
 #category-create-heading-action[hidden]{display:none;}
 .category-choice-popup .category-appearance-controls{height:44px!important;grid-template-rows:44px;align-items:center;}
 .category-choice-popup .category-icon-entry{grid-column:1;grid-row:1;align-self:center;justify-self:center;width:44px;height:44px;}
 .category-choice-popup .category-icon-entry>.category-color-orb{width:40px;height:40px;margin:0;}
 .category-group-scroll{padding:0;}
 .category-group-hint{display:none;}
 .category-group-host{align-self:center;}
 .cadushi-category-groups [data-ebg-item]{min-width:44px!important;min-height:44px!important;height:44px!important;}
 .cadushi-category-groups svg{display:block;flex:none;width:20px;height:20px;}
 .category-create-body .category-group-scroll{margin-bottom:4px;}
}
@media(min-width:601px){#category-create-heading-action{display:none;}}

@media(max-width:600px){.finanzas-header-fila:has(#category-create-heading-action:not([hidden])) #finance-view-status:empty{display:none;}}
