/* ============================================================
   NÚCLEO — Grafito + Esmeralda
   Sistema de diseño de la app. Sobrio y elegante, fintech premium:
   base casi monocroma de grafito cálido con un único acento verde
   esmeralda. Instrument Serif (títulos) + Geist (cuerpo y cifras).

   Premisas: DESIGN.md

   REGLA QUE SOSTIENE TODO ESTE ARCHIVO: ningún componente escribe
   un color literal. Todo lo que dependa del tema tiene token aquí,
   y cambiar de tema solo redefine tokens — no se reescribe un solo
   componente. Un rgba() suelto en un componente se queda esmeralda
   cuando el tema claro ya no lo es.

   Los nombres --brand-*, --surface-*, --chrome-*, --midnight-* vienen
   del sistema anterior y se conservan a propósito: son los que usan
   ~600 sitios en las plantillas, así que renombrarlos sería churn sin
   diseño. Debajo de cada bloque están los alias con el vocabulario de
   las premisas (--primary, --card, --sidebar, --ring…), que es el que
   debe usar el código nuevo.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600;700&display=swap');

/* ============================================================
   MODO OSCURO — grafito cálido, tarjetas elevadas sobre el fondo
   Escala de elevación: fondo 0.165 → chrome 0.185 → tarjeta 0.205
   → muted 0.235 → secondary 0.255 → accent 0.30. Nunca negro puro.
   Valores en hex convertidos desde el OKLCH del documento (los
   derivados translúcidos necesitan la tripleta rgb).
   ============================================================ */
:root {
  /* ---------- ESCALA GRAFITO ----------
     (el nombre --midnight-* se conserva; los valores son la rampa
     neutra cálida de matiz ~260 y croma casi nulo) */
  --midnight-50:  #f5f7f9;
  --midnight-100: #e6e8ea;
  --midnight-200: #cfd1d4;
  --midnight-300: #a2a5a8;   /* texto secundario */
  --midnight-400: #7e8084;   /* iconos inactivos */
  --midnight-500: #5b5e62;   /* líneas decorativas */
  --midnight-600: #45484c;   /* barras de gráfico inactivas */
  --midnight-700: #2e3034;   /* hover, bordes sutiles */
  --midnight-800: #1c1e22;   /* tarjetas elevadas */
  --midnight-900: #0d0e11;   /* fondo principal */

  /* ---------- ACENTO ESMERALDA ----------
     El acento se aclara en oscuro — oklch(0.7 0.13 164) — para
     conservar contraste sobre grafito profundo, y su texto pasa a
     ser oscuro. La rampa mantiene la convención del sistema:
     300 es texto/enlace, 400 es relleno. */
  --brand-200: #95e1be;   /* hover de enlace */
  --brand-300: #69cfa4;   /* texto, enlaces, gráficas */
  --brand-400: #3ab788;   /* relleno esmeralda — cifra clave, CTA verde */
  --brand-500: #289c72;
  --brand-600: #1f7f5c;
  --brand-rgb: 58, 183, 136;
  --brand-glow:   rgba(var(--brand-rgb), 0.25);
  --brand-subtle: rgba(var(--brand-rgb), 0.13);
  --brand-border: rgba(var(--brand-rgb), 0.32);
  --on-brand: #0d0e11;    /* texto/iconos sobre un relleno esmeralda */

  /* ---------- FONDO / SUPERFICIE ---------- */
  --background:      #0d0e11;   /* oklch(0.165 0.006 260) */
  --background-alt:  #1c1e22;   /* muted — superficies de apoyo */
  --surface-100:     #15171b;   /* card — oklch(0.205 0.008 260) */
  --surface-200:     #212327;   /* secondary — botones, item activo */
  --surface-300:     #2b2e33;   /* accent — hover */
  --surface-overlay: rgba(13, 14, 17, 0.72);

  /* ---------- TEXTO ---------- */
  --foreground:         #f0f2f4;   /* oklch(0.96 0.003 260) */
  --foreground-muted:   #bfc1c5;
  --foreground-subtle:  #9c9ea2;   /* oklch(0.7 0.006 260) */
  --foreground-inverse: #0d0e11;

  /* ---------- BORDES ----------
     Blanco con opacidad, no un gris fijo: así un borde se integra
     con cualquiera de las superficies de la escala. El documento
     pide bordes al 9% y campos al 13–16%. */
  --border:        rgba(255, 255, 255, 0.09);
  --border-strong: rgba(255, 255, 255, 0.16);
  --border-brand:  var(--brand-400);

  /* ---------- ESTADOS SEMÁNTICOS ----------
     Positivo = esmeralda (el mismo matiz que la marca: en Núcleo el
     acento y el positivo son el mismo verde). Rojo solo para
     negativo/destructivo. El "info" es grafito azulado casi neutro:
     máximo 3–5 colores percibidos, sin morados. */
  --success-rgb: 66, 190, 143;
  --success:     #42be8f;   /* oklch(0.72 0.13 164) */
  --success-bg:  rgba(var(--success-rgb), 0.13);
  --success-border: rgba(var(--success-rgb), 0.30);
  --warning-rgb: 242, 175, 72;
  --warning:     #f2af48;
  --warning-bg:  rgba(var(--warning-rgb), 0.13);
  --warning-border: rgba(var(--warning-rgb), 0.30);
  --destructive-rgb: 246, 109, 103;
  --destructive: #f66d67;   /* oklch(0.7 0.17 25), aclarado para el fondo profundo */
  --destructive-bg: rgba(var(--destructive-rgb), 0.13);
  --destructive-border: rgba(var(--destructive-rgb), 0.30);
  --info-rgb:    170, 180, 196;
  --info:        #aab4c4;
  --info-bg:     rgba(var(--info-rgb), 0.13);
  --info-border: rgba(var(--info-rgb), 0.30);

  /* Cifras con signo (saldos, P&L). El esmeralda es a la vez acento
     y positivo — esa es la premisa de Núcleo —, pero el rojo sigue
     siendo solo del dinero que baja y de lo destructivo. */
  --positive: var(--success);
  --negative: var(--destructive);

  /* ---------- CHROME (topbar + sidebar) ----------
     El sidebar es un escalón por encima del fondo (0.185 vs 0.165):
     enmarca sin separarse. En claro sigue al lienzo, no lo invierte. */
  --chrome-bg:        #111316;
  --chrome-glass:     rgba(17, 19, 22, 0.72);
  --chrome-fg:        var(--foreground);
  --chrome-fg-muted:  var(--foreground-muted);
  --chrome-fg-subtle: var(--foreground-subtle);
  --chrome-border:    var(--border);
  --chrome-hover:     var(--surface-300);
  --chrome-accent:    var(--brand-300);
  --chrome-accent-bg: var(--brand-subtle);

  /* ---------- EFECTOS DEPENDIENTES DEL TEMA ---------- */
  --hover-overlay: rgba(255, 255, 255, 0.06);
  --scrim:         rgba(5, 6, 8, 0.62);
  --grid-line:     rgba(255, 255, 255, 0.04);
  --chart-grid:    rgba(255, 255, 255, 0.08);
  --chart-tick:    var(--foreground-subtle);
  --chart-inactive: var(--midnight-600);   /* barras del mes inactivo */
  --close-filter:  invert(1) grayscale(100%) brightness(2);

  /* Sin gradientes (regla de oro de Núcleo). Los tokens se conservan
     porque los piden las plantillas, pero ya no describen degradados:
     el ambiente es `none` y el "gradiente" primario es un relleno
     plano de grafito. */
  --gradient-ambient: none;
  --gradient-primary: var(--primary);
  --gradient-primary-fg: var(--primary-foreground);

  /* ---------- TIPOGRAFÍA ----------
     Instrument Serif para títulos (aire editorial y elegante), Geist
     para todo lo demás. Las cifras van en Geist con tabular-nums, no
     en una monoespaciada: la premisa pide numeración tabular para que
     los montos no salten al actualizarse, no estética de terminal. */
  --font-display: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  --font-sans: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --font-numeric: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --font-code: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  /* Alias heredado: ~30 sitios piden --font-mono para pintar montos.
     Apunta a la numérica a propósito, para que hereden la premisa sin
     tocar plantilla. Para código de verdad, usa --font-code. */
  --font-mono: var(--font-numeric);

  --text-2xs: 11px;  --text-xs: 12px;   --text-sm: 13px;
  --text-base: 14px; --text-md: 16px;   --text-lg: 18px;
  --text-xl: 20px;   --text-2xl: 24px;  --text-3xl: 28px;
  --text-4xl: 40px;  --text-5xl: 48px;  --text-6xl: 60px;
  --text-7xl: 72px;  --text-8xl: 96px;

  --fw-regular: 400; --fw-medium: 500; --fw-semibold: 600; --fw-bold: 700;

  --lh-tight: 1.1; --lh-snug: 1.25; --lh-normal: 1.5; --lh-relaxed: 1.65;

  /* La serif no admite el tracking apretado de una grotesca: se
     queda casi en neutro. */
  --tracking-tight: -0.01em;
  --tracking-snug: -0.005em;
  --tracking-normal: 0;
  --tracking-caps: 0.08em;

  /* ---------- RADIOS ----------
     Radio base 0.625rem (10px). Discretos y consistentes: nada de
     cápsulas para contenedores — el radio completo queda solo para
     badges y chips pequeños. */
  --radius-xs: 6px;   --radius-sm: 8px;   --radius-md: 10px;
  --radius-lg: 12px;  --radius-xl: 14px;  --radius-2xl: 16px;
  --radius-3xl: 20px; --radius-4xl: 24px; --radius-full: 999px;

  /* ---------- LAYOUT ----------
     El ancho de la barra y el tope del contenido son tokens porque
     los mueve el colapso de la navegación (ver más abajo). */
  --topbar-h: 56px;
  --sidebar-w-open: 240px;          /* la barra desplegada, con etiquetas */
  --sidebar-w: var(--sidebar-w-open); /* el ANCHO RESERVADO en el layout */
  --sidebar-w-rail: 68px;
  --content-max: 1400px;

  /* ---------- ESPACIADO (rejilla de 4px) ---------- */
  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;
  --space-4: 16px;  --space-5: 20px;  --space-6: 24px;
  --space-8: 32px;  --space-10: 40px; --space-12: 48px;
  --space-16: 64px; --space-20: 80px; --space-24: 96px; --space-32: 128px;

  /* ---------- SOMBRAS ----------
     Discretas: la separación de superficies la hace el borde de 1px,
     la sombra solo acompaña. */
  --shadow-rgb: 0, 0, 0;
  --shadow-soft: 0 1px 2px rgba(0, 0, 0, 0.30), 0 8px 20px -14px rgba(0, 0, 0, 0.50);
  --shadow-lift: 0 2px 6px rgba(0, 0, 0, 0.30), 0 16px 32px -18px rgba(0, 0, 0, 0.55);
  --shadow-sm: var(--shadow-soft);
  --shadow-md: var(--shadow-soft);
  --shadow-lg: var(--shadow-lift);
  --shadow-focus: 0 0 0 3px var(--brand-glow);
  --glass-blur: blur(18px) saturate(140%);

  /* ---------- MOVIMIENTO ---------- */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --dur-fast: 150ms; --dur-normal: 200ms; --dur-slow: 300ms;

  /* ---------- GRÁFICOS ----------
     La serie destacada es siempre la esmeralda; las secundarias son
     grises neutros, de más oscuro a más claro. */
  --chart-1: var(--brand-400);
  --chart-2: #45484c;
  --chart-3: #5b5e62;
  --chart-4: #7e8084;
  --chart-5: #a2a5a8;

  /* ---------- ALIAS DE LAS PREMISAS ----------
     El vocabulario del documento. Para código nuevo, usa estos.
     OJO: en Núcleo el PRIMARIO es grafito (claro sobre oscuro aquí,
     oscuro sobre claro en el tema claro); el esmeralda es el ACENTO
     (--brand-400 / --ring), reservado a cifras clave y positivos. */
  --card: var(--surface-100);
  --popover: var(--surface-100);
  --primary: #f0f2f4;
  --primary-foreground: #15171b;
  --primary-hover: #d9dbdf;
  --secondary: var(--surface-200);
  --muted: var(--background-alt);
  --muted-foreground: var(--foreground-muted);
  --accent: var(--surface-300);
  --input: var(--border-strong);
  --ring: var(--brand-400);
  --sidebar: var(--chrome-bg);
  --sidebar-accent: var(--brand-subtle);
  --sidebar-primary: var(--brand-300);
}

/* ============================================================
   MODO CLARO — paridad total de contraste para uso diurno
   Lienzo casi blanco — oklch(0.985 0.002 250) —, tarjetas blancas y
   el mismo esmeralda un escalón más profundo para llegar a AA como
   texto. No es el modo oscuro invertido a mano: solo se redefinen
   tokens.
   ============================================================ */
:root[data-theme="light"] {
  /* ---------- ACENTO ESMERALDA ----------
     El oklch(0.6 0.114 163) del documento se queda en ~3.6:1 con
     texto blanco encima, así que el relleno baja a #177b57 (5.2:1)
     y texto/enlaces usan ese mismo escalón (5.0:1 sobre el lienzo).
     El hover baja otro paso. */
  --brand-200: #076546;   /* hover de enlace */
  --brand-300: #177b57;   /* texto y enlaces */
  --brand-400: #177b57;   /* relleno esmeralda — cifra clave, CTA verde */
  --brand-500: #106e4e;
  --brand-600: #076546;
  --brand-rgb: 23, 123, 87;
  --brand-glow:   rgba(var(--brand-rgb), 0.22);
  --brand-subtle: rgba(var(--brand-rgb), 0.10);
  --brand-border: rgba(var(--brand-rgb), 0.28);
  --on-brand: #ffffff;

  /* ---------- FONDO / SUPERFICIE ---------- */
  --background:      #f9fafb;   /* oklch(0.985 0.002 250) */
  --background-alt:  #f2f3f6;   /* muted */
  --surface-100:     #ffffff;   /* card */
  --surface-200:     #f2f3f6;   /* secondary */
  --surface-300:     #eef0f4;   /* accent — hover */
  --surface-overlay: rgba(249, 250, 251, 0.72);

  /* ---------- TEXTO ---------- */
  --foreground:         #171b20;   /* oklch(0.22 0.012 260) */
  --foreground-muted:   #52565c;   /* 7.2:1 */
  --foreground-subtle:  #66696f;   /* 5.3:1 — el oklch(0.52) del doc */
  --foreground-inverse: #f9fafb;

  /* ---------- BORDES ---------- */
  --border:        #dfe1e5;   /* oklch(0.91 0.005 260) */
  --border-strong: #c9ccd2;
  --border-brand:  var(--brand-400);

  /* ---------- ESTADOS ----------
     Los tonos pensados como relleno sobre fondo profundo se quedan
     en 2–3:1 como TEXTO sobre papel. Aquí bajan al escalón que sí
     llega a 4.5:1; el relleno translúcido conserva el matiz. */
  --success-rgb: 23, 123, 87;
  --success:     #177b57;
  --warning-rgb: 164, 94, 0;
  --warning:     #a45e00;
  --destructive-rgb: 179, 34, 40;
  --destructive: #b32228;   /* el oklch(0.575 0.19 24) baja a AA */
  --info-rgb:    71, 86, 107;
  --info:        #47566b;
  --success-bg:  rgba(var(--success-rgb), 0.09);
  --success-border: rgba(var(--success-rgb), 0.26);
  --warning-bg:  rgba(var(--warning-rgb), 0.09);
  --warning-border: rgba(var(--warning-rgb), 0.26);
  --destructive-bg: rgba(var(--destructive-rgb), 0.08);
  --destructive-border: rgba(var(--destructive-rgb), 0.26);
  --info-bg:     rgba(var(--info-rgb), 0.08);
  --info-border: rgba(var(--info-rgb), 0.26);
  --positive: var(--success);
  --negative: var(--destructive);

  /* ---------- CHROME ----------
     El chrome claro (#f4f6f8) se separa del lienzo por un escalón,
     igual que en oscuro. El chrome no invierte el tema. */
  --chrome-bg:        #f4f6f8;
  --chrome-glass:     rgba(244, 246, 248, 0.72);
  --chrome-fg:        var(--foreground);
  --chrome-fg-muted:  var(--foreground-muted);
  --chrome-fg-subtle: var(--foreground-subtle);
  --chrome-border:    var(--border);
  --chrome-hover:     var(--surface-300);
  --chrome-accent:    var(--brand-300);
  --chrome-accent-bg: var(--brand-subtle);

  /* ---------- EFECTOS ---------- */
  --hover-overlay: rgba(23, 27, 32, 0.05);
  --scrim:         rgba(23, 27, 32, 0.38);
  --grid-line:     rgba(23, 27, 32, 0.04);
  --chart-grid:    rgba(23, 27, 32, 0.08);
  --chart-tick:    var(--foreground-subtle);
  --chart-inactive: var(--midnight-200);
  --close-filter:  none;

  --gradient-ambient: none;
  --gradient-primary: var(--primary);
  --gradient-primary-fg: var(--primary-foreground);

  /* Sombras neutras y mucho más suaves: sobre papel, una sombra
     negra al 55% se ve como suciedad. */
  --shadow-rgb: 23, 27, 32;
  --shadow-soft: 0 1px 2px rgba(23, 27, 32, 0.05), 0 8px 20px -14px rgba(23, 27, 32, 0.14);
  --shadow-lift: 0 2px 6px rgba(23, 27, 32, 0.07), 0 16px 32px -18px rgba(23, 27, 32, 0.20);
  --shadow-sm: var(--shadow-soft);
  --shadow-md: var(--shadow-soft);
  --shadow-lg: var(--shadow-lift);

  /* ---------- GRÁFICOS ---------- */
  --chart-2: #2e3034;
  --chart-3: #5b5e62;
  --chart-4: #7e8084;
  --chart-5: #a2a5a8;

  /* ---------- ALIAS ----------
     El primario grafito del documento: oklch(0.27 0.015 260). */
  --primary: #22272e;
  --primary-foreground: #f9fafb;
  --primary-hover: #333a42;
}

/* ============================================================
   ESTILOS DE TEXTO SEMÁNTICOS
   Los títulos van en Instrument Serif (solo existe en 400: nada de
   negritas sintéticas); el cuerpo y las cifras, en Geist.
   ============================================================ */
.jm-display { font: var(--fw-regular) var(--text-7xl)/0.95 var(--font-display); letter-spacing: var(--tracking-tight); color: var(--foreground); }
.jm-h1 { font: var(--fw-regular) var(--text-4xl)/var(--lh-tight) var(--font-display); letter-spacing: var(--tracking-tight); color: var(--foreground); }
.jm-h2 { font: var(--fw-regular) var(--text-3xl)/var(--lh-snug) var(--font-display); letter-spacing: var(--tracking-snug); color: var(--foreground); }
.jm-h3 { font: var(--fw-regular) var(--text-xl)/var(--lh-snug) var(--font-display); letter-spacing: var(--tracking-snug); color: var(--foreground); }
.jm-h4 { font: var(--fw-regular) var(--text-md)/var(--lh-snug) var(--font-display); color: var(--foreground); }
.jm-body { font: var(--fw-regular) var(--text-md)/var(--lh-relaxed) var(--font-sans); color: var(--foreground-muted); }
.jm-body-sm { font: var(--fw-regular) var(--text-base)/var(--lh-normal) var(--font-sans); color: var(--foreground-muted); }
.jm-caption { font: var(--fw-regular) var(--text-xs)/var(--lh-normal) var(--font-sans); color: var(--foreground-subtle); }
.jm-eyebrow, .jm-tag {
  font: var(--fw-medium) var(--text-2xs)/1 var(--font-sans);
  letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--foreground-muted);
}
.jm-mono { font-family: var(--font-numeric); font-variant-numeric: tabular-nums; font-size: var(--text-base); color: var(--foreground); }

/* ============================================================
   LIENZO
   Sin luz ambiental: en Núcleo el fondo es plano (sin gradientes).
   `--gradient-ambient` es `none`, así que la primera capa no pinta
   nada y queda solo el color de fondo. La regla se conserva para no
   tocar el marcado que ya usa .jm-root.
   ============================================================ */
.jm-root {
  background: var(--gradient-ambient), var(--background);
  background-attachment: fixed;
  color: var(--foreground);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

/* ============================================================
   UTILIDADES DE PROFUNDIDAD
   ============================================================ */
.surface-glass {
  background: var(--chrome-glass);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}
/* Sin soporte de backdrop-filter el 72% deja ver el contenido a
   través del header al hacer scroll. Ahí se cae a opaco. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .surface-glass { background: var(--chrome-bg); }
}
/* Relleno primario plano (el nombre viene del sistema anterior;
   ya no hay degradado detrás). */
.gradient-primary {
  background: var(--gradient-primary);
  color: var(--gradient-primary-fg);
}
.jm-elevate {
  transition: transform var(--dur-normal) var(--ease-standard),
              box-shadow var(--dur-normal) var(--ease-standard),
              border-color var(--dur-normal) var(--ease-standard);
}
.jm-elevate:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
@media (prefers-reduced-motion: reduce) {
  .jm-elevate:hover { transform: none; }
}

/* ============================================================
   PRIMITIVAS DE COMPONENTE
   ============================================================ */
.jm-btn {
  display: inline-flex; align-items: center; gap: 8px;
  height: 38px; padding: 0 16px;
  border-radius: var(--radius-sm);
  font: var(--fw-medium) var(--text-base)/1 var(--font-sans);
  border: 1px solid transparent; cursor: pointer;
  transition: all var(--dur-fast) var(--ease-standard);
}
/* El botón primario es GRAFITO (claro sobre oscuro / oscuro sobre
   claro), no esmeralda: en Núcleo el acento se reserva a cifras y
   estados positivos, y así el CTA no compite con el dinero. */
.jm-btn--primary {
  background: var(--primary); color: var(--primary-foreground); border-color: var(--primary);
  box-shadow: var(--shadow-soft);
}
.jm-btn--primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); color: var(--primary-foreground); }
.jm-btn--secondary { background: var(--surface-200); color: var(--foreground); border-color: var(--border); }
.jm-btn--secondary:hover { background: var(--surface-300); border-color: var(--border-strong); }
.jm-btn--ghost { background: transparent; color: var(--foreground-muted); }
.jm-btn--ghost:hover { background: var(--hover-overlay); color: var(--foreground); }

.jm-card {
  background: var(--surface-100);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-soft);
}

.jm-input {
  height: 38px; padding: 0 14px;
  background: var(--background);
  border: 1px solid var(--input);
  border-radius: var(--radius-sm);
  color: var(--foreground);
  font: var(--fw-regular) var(--text-base)/1 var(--font-sans);
  transition: border var(--dur-fast), box-shadow var(--dur-fast);
}
.jm-input:focus { outline: none; border-color: var(--ring); box-shadow: var(--shadow-focus); }

/* Campo de búsqueda/filtro. Conserva el nombre .jm-pill, pero ya no
   es una cápsula: Núcleo no usa rounded-full en contenedores, así
   que baja al radio discreto de los controles. */
.jm-pill {
  height: 38px; padding: 0 16px;
  background: var(--muted);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  color: var(--foreground);
  font: var(--fw-regular) var(--text-base)/1 var(--font-sans);
}
.jm-pill::placeholder { color: var(--foreground-subtle); }
.jm-pill:focus { outline: none; border-color: var(--ring); box-shadow: var(--shadow-focus); }

.jm-badge {
  display: inline-flex; align-items: center; gap: 4px;
  height: 22px; padding: 0 10px;
  font: var(--fw-medium) var(--text-2xs)/1 var(--font-sans);
  letter-spacing: var(--tracking-caps); text-transform: uppercase;
  border-radius: var(--radius-full);
  border: 1px solid var(--border);
  background: var(--muted);
  color: var(--foreground-muted);
}
.jm-badge--brand { background: var(--brand-subtle); border-color: var(--brand-border); color: var(--brand-300); }
.jm-badge--warning { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning); }
.jm-badge--destructive { background: var(--destructive-bg); border-color: var(--destructive-border); color: var(--destructive); }

/* Anillo de foco visible en cualquier control: esmeralda (--ring). */
:where(a, button, [role="button"], input, select, textarea, summary):focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* ============================================================
   NAVEGACIÓN — tres modos (el modelo de Supabase Studio)

   `data-sidebar-mode` en <html> guarda la ELECCIÓN del usuario:
   - `expanded`  — 240px con etiquetas, siempre.
   - `collapsed` — carril de 68px, siempre; el nombre lo da la etiqueta
                   flotante al hover.
   - `hover`     — **el de fábrica**: reserva el carril y despliega el
                   panel encima al pasar el ratón.

   `data-sidebar="collapsed"` es distinto: describe el ANCHO RESERVADO
   en el layout, no el modo. Vale para `collapsed` y para `hover`, que
   reservan lo mismo. De ahí cuelgan las dos reglas de abajo, y por eso
   en modo hover el contenido no se mueve al desplegar: lo reservado no
   cambia — solo el panel, que flota (ver `.jm-sidebar__inner` en el
   puente).

   El estado se aplica antes del primer paint (script inline en
   base.html), igual que el tema: si se aplicara con JS al final, la
   barra daría un salto de 172px en cada carga.

   Colapsar la barra SIN soltar el tope del contenido no gana nada: en
   una pantalla de 1920px el contenido está topado a 1400 y centrado,
   así que al encoger la barra el contenido solo se recentra y el
   usuario no ve un píxel de más. Por eso el colapso mueve las dos
   cosas — la barra y el tope — y eso es lo que lo convierte en un
   modo foco de verdad. El tope sube a 1720 y no a "sin tope" porque
   una línea de texto de 1900px deja de ser legible.

   Va sobre `body.has-sidebar` y no sobre `:root` porque el estado se
   guarda global: sin esa condición, Home y /apps/ —que no tienen barra
   que colapsar— también ensancharían su contenido.
   ============================================================ */
@media (min-width: 992px) {
  :root[data-sidebar="collapsed"] body.has-sidebar {
    --sidebar-w: var(--sidebar-w-rail);
    --content-max: 1720px;
  }
}
