/* ============================================================
   NÚCLEO × Bootstrap bridge
   Monta los tokens de grafito + esmeralda sobre Bootstrap 5 para que
   el marcado que ya existe (.btn/.card/.modal/.form-control/.table
   /.navbar) herede el sistema sin reescribir plantilla por plantilla.
   Cargar DESPUÉS de bootstrap.min.css y DESPUÉS de jm-design.css.
   ============================================================ */

html, body { background: var(--background); color: var(--foreground); }
body { font-family: var(--font-sans); }

/* Le dice al navegador cómo pintar lo que no controlamos: scrollbars
   nativos, date pickers, autofill. Sin esto el tema claro conserva
   widgets oscuros del sistema. */
:root { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

/* Transición del cambio de tema. La clase la pone y la quita el
   toggle, así el coste del selector universal dura solo el cruce y
   no penaliza el resto de la sesión ni el primer paint. */
html.jm-theme-anim *,
html.jm-theme-anim *::before,
html.jm-theme-anim *::after {
  transition: background-color var(--dur-normal) var(--ease-standard),
              border-color var(--dur-normal) var(--ease-standard),
              color var(--dur-normal) var(--ease-standard),
              fill var(--dur-normal) var(--ease-standard) !important;
}
@media (prefers-reduced-motion: reduce) {
  html.jm-theme-anim *,
  html.jm-theme-anim *::before,
  html.jm-theme-anim *::after { transition: none !important; }
}

/* ---------- Bootstrap CSS variable overrides ---------- */
:root {
  --bs-body-bg: var(--background);
  --bs-body-color: var(--foreground);
  --bs-body-font-family: var(--font-sans);
  --bs-body-font-size: var(--text-base);

  --bs-border-color: var(--border);
  --bs-border-color-translucent: var(--border);
  --bs-border-radius: var(--radius-sm);
  --bs-border-radius-sm: var(--radius-xs);
  --bs-border-radius-lg: var(--radius-lg);
  --bs-border-radius-xl: var(--radius-xl);
  --bs-border-radius-pill: var(--radius-full);

  --bs-primary: var(--brand-400);
  --bs-primary-rgb: var(--brand-rgb);
  --bs-success: var(--success);
  --bs-success-rgb: var(--success-rgb);
  --bs-danger: var(--destructive);
  --bs-danger-rgb: var(--destructive-rgb);
  --bs-warning: var(--warning);
  --bs-warning-rgb: var(--warning-rgb);
  --bs-info: var(--info);
  --bs-info-rgb: var(--info-rgb);

  --bs-secondary-color: var(--foreground-muted);
  --bs-tertiary-color: var(--foreground-subtle);
  --bs-secondary-bg: var(--surface-100);
  --bs-tertiary-bg: var(--surface-200);

  --bs-link-color: var(--brand-300);
  --bs-link-hover-color: var(--brand-200);
  --bs-link-color-rgb: var(--brand-rgb);
}

/* ---------- Typography overrides ---------- */
/* Instrument Serif solo existe en 400: un semibold aquí sería una
   negrita sintética que empasta la serif. */
h1, h2, h3, h4, h5, h6 {
  color: var(--foreground);
  font-family: var(--font-display);
  font-weight: var(--fw-regular);
  letter-spacing: var(--tracking-snug);
}
.text-muted { color: var(--foreground-muted) !important; }
.text-secondary { color: var(--foreground-muted) !important; }
small, .small { color: var(--foreground-subtle); }
code, kbd, pre { font-family: var(--font-code); color: var(--foreground); }

/* ---------- Cards ----------
   La elevación ya no es solo borde: ahora hay sombra suave en reposo
   (§6). El levantamiento de 2px del hover es opt-in con `.jm-lift`
   y va solo en rejillas de tarjetas-objeto (cuentas, estrategias,
   metas): una tarjeta que es contenedor de un formulario o de una
   tabla no debe saltar al pasar el ratón por encima. */
.card {
  background: var(--surface-100);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  color: var(--foreground);
}
.card.jm-lift {
  transition: transform var(--dur-normal) var(--ease-standard),
              box-shadow var(--dur-normal) var(--ease-standard),
              border-color var(--dur-normal) var(--ease-standard);
}
.card.jm-lift:hover {
  box-shadow: var(--shadow-lift);
  transform: translateY(-2px);
  border-color: var(--border-strong);
}
@media (prefers-reduced-motion: reduce) {
  .card.jm-lift:hover { transform: none; }
}
.card-header {
  background: var(--surface-100);
  border-bottom: 1px solid var(--border);
  color: var(--foreground);
  font-weight: var(--fw-semibold);
}
.card-footer {
  background: var(--surface-100);
  border-top: 1px solid var(--border);
  color: var(--foreground-muted);
}

/* ---------- Buttons ---------- */
.btn { font-family: var(--font-sans); font-weight: var(--fw-medium); border-radius: var(--radius-sm); transition: all var(--dur-fast) var(--ease-standard); }
.btn:hover { transform: none; }
/* El primario es GRAFITO (Núcleo): claro sobre oscuro, oscuro sobre
   claro. El esmeralda queda para .btn-success — acciones de dinero
   que entra (registrar pago, abonar) — y para las cifras. */
.btn-primary,
.btn-brand {
  background: var(--primary);
  color: var(--primary-foreground);
  border-color: var(--primary);
}
.btn-primary:hover,
.btn-brand:hover,
.btn-primary:focus,
.btn-brand:focus {
  background: var(--primary-hover);
  color: var(--primary-foreground);
  border-color: var(--primary-hover);
  box-shadow: var(--shadow-focus);
}
.btn-success {
  background: var(--brand-400);
  color: var(--on-brand);
  border-color: var(--brand-400);
}
.btn-success:hover,
.btn-success:focus {
  background: var(--brand-500);
  color: var(--on-brand);
  border-color: var(--brand-500);
  box-shadow: var(--shadow-focus);
}
.btn-outline-primary {
  color: var(--foreground);
  border-color: var(--border-strong);
  background: transparent;
}
.btn-outline-primary:hover {
  background: var(--surface-200);
  color: var(--foreground);
  border-color: var(--border-strong);
}
.btn-outline-success {
  color: var(--brand-300);
  border-color: var(--border-strong);
  background: transparent;
}
.btn-outline-success:hover {
  background: var(--brand-subtle);
  color: var(--brand-300);
  border-color: var(--brand-400);
}
.btn-secondary {
  background: var(--surface-100);
  color: var(--foreground);
  border-color: var(--border-strong);
}
.btn-secondary:hover {
  background: var(--surface-200);
  color: var(--foreground);
  border-color: var(--border-strong);
}
.btn-outline-secondary {
  background: transparent;
  color: var(--foreground-muted);
  border-color: var(--border-strong);
}
.btn-outline-secondary:hover {
  background: var(--surface-200);
  color: var(--foreground);
  border-color: var(--border-strong);
}
.btn-danger,
.btn-outline-danger {
  --bs-btn-color: var(--destructive);
  --bs-btn-border-color: rgba(var(--destructive-rgb), 0.4);
  --bs-btn-bg: transparent;
  --bs-btn-hover-bg: var(--destructive-bg);
  --bs-btn-hover-color: var(--destructive);
  --bs-btn-hover-border-color: var(--destructive);
  --bs-btn-active-bg: var(--destructive);
  --bs-btn-active-color: var(--foreground-inverse);
}
.btn-link { color: var(--brand-300); text-decoration: none; }
.btn-link:hover { color: var(--brand-200); text-decoration: underline; }

/* ---------- Forms ---------- */
.form-control,
.form-select,
.input-group-text {
  background: var(--background);
  border: 1px solid var(--input);
  color: var(--foreground);
  border-radius: var(--radius-sm);
}
.form-control::placeholder { color: var(--foreground-subtle); }
.form-control:focus,
.form-select:focus {
  background: var(--background);
  color: var(--foreground);
  border-color: var(--ring);
  box-shadow: var(--shadow-focus);
}
.form-control:disabled,
.form-control[readonly] {
  background: var(--surface-200);
  color: var(--foreground-muted);
}
.form-label { color: var(--foreground); font-weight: var(--fw-medium); }
.form-text { color: var(--foreground-subtle); }
.form-check-input {
  background-color: var(--background-alt);
  border-color: var(--border-strong);
}
.form-check-input:checked {
  background-color: var(--brand-400);
  border-color: var(--brand-400);
}
.input-group-text { color: var(--foreground-muted); }

/* ---------- Tables ---------- */
.table {
  --bs-table-bg: transparent;
  --bs-table-color: var(--foreground);
  --bs-table-border-color: var(--border);
  --bs-table-striped-bg: var(--background-alt);
  --bs-table-striped-color: var(--foreground);
  --bs-table-hover-bg: var(--surface-200);
  --bs-table-hover-color: var(--foreground);
  color: var(--foreground);
  border-color: var(--border);
}
.table thead th {
  background: var(--background-alt);
  color: var(--foreground-muted);
  font-weight: var(--fw-medium);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  border-bottom: 1px solid var(--border);
}
.table tbody tr { border-color: var(--border); }
.table-hover > tbody > tr:hover > * { background: var(--surface-200); color: var(--foreground); }

/* Las columnas de cifras van en la numérica con tabular-nums: los
   montos no pueden saltar de ancho al actualizarse (§4). */
.table .num,
.table .mono,
td.num, th.num {
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ---------- Modals ---------- */
.modal-content {
  background: var(--surface-100);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  color: var(--foreground);
  box-shadow: var(--shadow-lg);
}
.modal-header {
  border-bottom: 1px solid var(--border);
}
.modal-footer {
  border-top: 1px solid var(--border);
}
.modal-title { color: var(--foreground); }
.btn-close {
  filter: var(--close-filter);
  opacity: 0.7;
}
.btn-close:hover { opacity: 1; }
.modal-backdrop.show { opacity: 0.7; }

/* ---------- Navbar (tokens de chrome; el header es vidrio esmerilado) ---------- */
.navbar {
  background: var(--chrome-glass);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--chrome-border);
}
.navbar-brand,
.navbar .nav-link {
  color: var(--chrome-fg-muted);
}
.navbar .nav-link:hover,
.navbar .nav-link.active,
.navbar .nav-link.show {
  color: var(--chrome-fg);
}
.navbar .nav-link.active {
  color: var(--chrome-accent);
}
.navbar-toggler {
  border-color: var(--chrome-border);
  color: var(--chrome-fg-muted);
}
.dropdown-menu {
  background: var(--surface-100);
  border: 1px solid var(--border);
  color: var(--foreground);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
}
.dropdown-item { color: var(--foreground-muted); }
.dropdown-item:hover,
.dropdown-item:focus {
  background: var(--surface-200);
  color: var(--foreground);
}
.dropdown-divider { border-color: var(--border); }

/* ---------- List groups ---------- */
.list-group { background: transparent; }
.list-group-item {
  background: var(--surface-100);
  border-color: var(--border);
  color: var(--foreground);
}
.list-group-item-action:hover,
.list-group-item-action:focus {
  background: var(--surface-200);
  color: var(--foreground);
}

/* ---------- Alerts ---------- */
.alert {
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--background-alt);
  color: var(--foreground);
}
.alert-success { background: var(--success-bg); border-color: var(--success-border); color: var(--success); }
.alert-warning { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning); }
.alert-danger  { background: var(--destructive-bg); border-color: var(--destructive-border); color: var(--destructive); }
.alert-info    { background: var(--info-bg); border-color: var(--info-border); color: var(--info); }

/* ---------- Badges (Bootstrap-style → CONFEAT look) ---------- */
.badge {
  font-weight: var(--fw-medium);
  font-size: var(--text-2xs);
  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);
  padding: 4px 10px;
}
.badge.bg-primary,
.badge.text-bg-primary {
  background: var(--brand-subtle) !important;
  border-color: var(--brand-border);
  color: var(--brand-300) !important;
}
/* "success" aquí es estado (PAGADO, ACTIVO…), no la marca: conserva
   su verde también en claro, donde el acento pasa a ser oro. */
.badge.bg-success,
.badge.text-bg-success {
  background: var(--success-bg) !important;
  border-color: var(--success-border);
  color: var(--success) !important;
}
.badge.bg-warning,
.badge.text-bg-warning {
  background: var(--warning-bg) !important;
  border-color: var(--warning-border);
  color: var(--warning) !important;
}
.badge.bg-danger,
.badge.text-bg-danger {
  background: var(--destructive-bg) !important;
  border-color: var(--destructive-border);
  color: var(--destructive) !important;
}
.badge.bg-info,
.badge.text-bg-info {
  background: var(--info-bg) !important;
  border-color: var(--info-border);
  color: var(--info) !important;
}
.badge.bg-secondary,
.badge.text-bg-secondary {
  background: var(--background-alt) !important;
  color: var(--foreground-muted) !important;
}

/* ---------- Bootstrap subtle / emphasis color variants ---------- */
.bg-success-subtle { background-color: var(--success-bg) !important; }
.text-success-emphasis { color: var(--success) !important; }
.bg-danger-subtle { background-color: var(--destructive-bg) !important; }
.text-danger-emphasis { color: var(--destructive) !important; }
.bg-warning-subtle { background-color: var(--warning-bg) !important; }
.text-warning-emphasis { color: var(--warning) !important; }
.bg-info-subtle { background-color: var(--info-bg) !important; }
.text-info-emphasis { color: var(--info) !important; }
.bg-primary-subtle { background-color: var(--brand-subtle) !important; }
.text-primary-emphasis { color: var(--brand-300) !important; }
.bg-secondary-subtle { background-color: var(--background-alt) !important; }
.text-secondary-emphasis { color: var(--foreground-muted) !important; }
.bg-light-subtle { background-color: var(--surface-100) !important; }
.text-light-emphasis { color: var(--foreground-muted) !important; }
.bg-dark-subtle { background-color: var(--background) !important; }
.text-dark-emphasis { color: var(--foreground) !important; }

/* Plain .text-light / .text-dark — flip them in dark mode so they remain readable */
.text-dark { color: var(--foreground) !important; }
.text-light { color: var(--foreground-muted) !important; }
.text-white { color: var(--foreground) !important; }
.text-black { color: var(--foreground) !important; }
.text-body { color: var(--foreground) !important; }

/* "Rounded-pill" badges with subtle backgrounds — inherit subtle bg + emphasis text */
.badge.rounded-pill {
  border: 1px solid transparent;
  background: var(--background-alt);
  color: var(--foreground-muted);
}

/* ---------- Pagination ---------- */
.pagination .page-link {
  background: var(--surface-100);
  border-color: var(--border);
  color: var(--foreground-muted);
}
.pagination .page-link:hover {
  background: var(--surface-200);
  color: var(--foreground);
}
.pagination .page-item.active .page-link {
  background: var(--brand-400);
  border-color: var(--brand-400);
  color: var(--on-brand);
}

/* ---------- Background utilities used by base/old CSS ---------- */
.bg-surface { background: var(--surface-100) !important; color: var(--foreground); }
.bg-light, .bg-white { background: var(--surface-100) !important; color: var(--foreground); }
.bg-body { background: var(--background) !important; color: var(--foreground); }
.border, .border-top, .border-bottom, .border-start, .border-end { border-color: var(--border) !important; }
.border-subtle { border-color: var(--border) !important; }
hr { border-color: var(--border); opacity: 1; }

/* ---------- Links inside body content ---------- */
a { color: var(--brand-300); text-decoration: none; }
a:hover { color: var(--brand-200); text-decoration: underline; }
.nav-link, .navbar-brand, .dropdown-item { text-decoration: none; }

/* ---------- Scrollbars ---------- */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--background); }
::-webkit-scrollbar-thumb { background: var(--surface-200); border-radius: var(--radius-full); }
::-webkit-scrollbar-thumb:hover { background: var(--border-strong); }

/* ---------- Selection ---------- */
::selection { background: var(--brand-subtle); color: var(--foreground); }

/* ---------- Display helpers (cabeceras de página) ---------- */
.jm-page-title { font: var(--fw-regular) var(--text-3xl)/var(--lh-snug) var(--font-display); letter-spacing: var(--tracking-tight); color: var(--foreground); margin: 0 0 var(--space-2); }
.jm-page-subtitle { color: var(--foreground-muted); margin: 0 0 var(--space-6); }
.jm-section-title { font: var(--fw-medium) var(--text-2xs)/1 var(--font-sans); letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--foreground-muted); margin: 0 0 var(--space-3); }
.jm-num { font-family: var(--font-numeric); font-variant-numeric: tabular-nums; }
.jm-num--lg { font-family: var(--font-numeric); font-variant-numeric: tabular-nums; font-size: var(--text-3xl); font-weight: var(--fw-semibold); color: var(--foreground); letter-spacing: var(--tracking-tight); }
.jm-num--positive { color: var(--positive); }
.jm-num--negative { color: var(--negative); }

/* KPI card variant — leaner than .jm-card padding-wise */
.jm-kpi {
  background: var(--surface-100);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
  box-shadow: var(--shadow-soft);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.jm-kpi__label { font: var(--fw-medium) var(--text-2xs)/1 var(--font-sans); letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--foreground-muted); }
.jm-kpi__value { font-family: var(--font-numeric); font-variant-numeric: tabular-nums; font-size: var(--text-3xl); font-weight: var(--fw-semibold); color: var(--foreground); letter-spacing: var(--tracking-tight); }
.jm-kpi__delta { font-size: var(--text-xs); color: var(--foreground-subtle); }
.jm-kpi__delta--up { color: var(--positive); }
.jm-kpi__delta--down { color: var(--negative); }

/* El KPI insignia: relleno grafito PLANO (sin gradientes ni brillos
   en Núcleo). Es el único relleno invertido de la vista — el acento
   es un invitado, no un inquilino, así que si dos KPI lo llevan deja
   de haber jerarquía y vuelve a ser una rejilla plana. */
.jm-kpi--primary {
  background: var(--gradient-primary);
  border-color: transparent;
  color: var(--gradient-primary-fg);
  box-shadow: var(--shadow-lift);
  position: relative;
  overflow: hidden;
}
.jm-kpi--primary .jm-kpi__label,
.jm-kpi--primary .jm-kpi__value,
.jm-kpi--primary .jm-kpi__delta { color: var(--gradient-primary-fg); position: relative; }
.jm-kpi--primary .jm-kpi__label,
.jm-kpi--primary .jm-kpi__delta { opacity: 0.78; }

/* App-launcher card */
.jm-app-card {
  background: var(--surface-100);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-soft);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  transition: transform var(--dur-normal) var(--ease-standard),
              box-shadow var(--dur-normal) var(--ease-standard),
              border-color var(--dur-normal) var(--ease-standard);
  text-decoration: none;
  color: inherit;
  height: 100%;
}
.jm-app-card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-lift);
  transform: translateY(-2px);
  text-decoration: none;
  color: inherit;
}
@media (prefers-reduced-motion: reduce) {
  .jm-app-card:hover { transform: none; }
}
.jm-app-card--available { border-style: dashed; }
.jm-app-card--soon { opacity: 0.6; }
.jm-app-card__icon {
  width: 36px; height: 36px;
  border-radius: var(--radius-md);
  background: var(--brand-subtle);
  color: var(--brand-300);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 18px;
}
.jm-app-card__title { font: var(--fw-semibold) var(--text-lg)/var(--lh-snug) var(--font-sans); color: var(--foreground); margin: 0; }
.jm-app-card__desc { color: var(--foreground-muted); font-size: var(--text-base); margin: 0; flex: 1; }

/* Inline brand wordmark sizing helper */
.jm-wordmark { height: 28px; width: auto; display: inline-block; }
.jm-mark { height: 24px; width: 24px; display: inline-block; }

/* ============================================================
   SIDEBAR — navegación de app (finanza y trader)
   Vivía duplicado línea por línea en los dos `includes/sidebar*.html`.
   Está aquí para que exista UNA definición: mientras estuvo copiado,
   cualquier arreglo había que hacerlo dos veces y el segundo se
   olvidaba. Cada plantilla se queda solo con sus enlaces.

   Tres modos en desktop, a elección del usuario (`data-sidebar-mode`),
   más el cajón de móvil:
   - `expanded`  → 240px con etiquetas, siempre
   - `collapsed` → carril de 68px, siempre; el nombre lo da la etiqueta flotante
   - `hover`     → **de fábrica**: reserva el carril y despliega el panel encima
   - móvil       → cajón fuera de lienzo (.is-open); ahí los modos no aplican

   **`.jm-sidebar` es el HUECO; `.jm-sidebar__inner` es el PANEL.** Esa
   separación es la que hace posible el modo hover: al desplegar solo
   cambia el panel —que en desktop flota— y el hueco reservado se queda
   igual, así que el contenido no se recoloca al pasar el ratón. Si el
   ancho viviera en un solo elemento, cada hover empujaría la página
   entera 172px.
   ============================================================ */
.jm-sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  border-right: 1px solid var(--chrome-border);
  background: var(--chrome-bg);
  align-self: stretch;
  transition: width var(--dur-normal) var(--ease-standard);
}
.jm-sidebar__inner {
  position: sticky;
  top: var(--topbar-h);
  max-height: calc(100vh - var(--topbar-h));
  display: flex;
  flex-direction: column;
  /* Visible, no `hidden`: el desplegable del control del pie es un
     dropup y un `overflow:hidden` aquí lo recortaría. Quien recorta es
     `.jm-side-nav`, que es el que scrollea. */
  overflow: visible;
}
.jm-side-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--space-5) var(--space-3);
}

/* Pie de la barra: ahí vive el control de la navegación, igual que en
   Supabase — el header se queda solo con el contexto global. */
.jm-sidebar__footer {
  flex-shrink: 0;
  padding: var(--space-2) var(--space-3) var(--space-3);
  border-top: 1px solid var(--chrome-border);
}
button.jm-side-link {
  width: 100%;
  background: transparent;
  border: 0;
  font-family: inherit;
  cursor: pointer;
}
.jm-side-link__chevron { margin-left: auto; font-size: 12px; opacity: 0.7; }
:root[data-sidebar="collapsed"]:not([data-sidebar-peek]) .jm-side-link__chevron { display: none; }

/* Un <button> dentro de un menú necesita que le quiten la caja nativa.
   Estaba resuelto con `style="border:0; background:transparent…"`
   repetido en cada plantilla; aquí es una regla y ya. */
button.jm-dropdown__item {
  width: 100%;
  border: 0;
  background: transparent;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
}
.jm-dropdown__group {
  font: var(--fw-medium) var(--text-2xs)/1 var(--font-sans);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--foreground-subtle);
  padding: var(--space-2) var(--space-3);
}

/* La marca del modo activo la decide el CSS a partir de
   `data-sidebar-mode`, no el JS: así el desplegable ya nace bien
   marcado y no hay un primer pintado con el check en el sitio que no
   es. */
.jm-mode-check { display: none; margin-left: auto; color: var(--brand-300); }
:root[data-sidebar-mode="expanded"]  .jm-dropdown [data-sidebar-mode="expanded"]  .jm-mode-check,
:root[data-sidebar-mode="collapsed"] .jm-dropdown [data-sidebar-mode="collapsed"] .jm-mode-check,
:root[data-sidebar-mode="hover"]     .jm-dropdown [data-sidebar-mode="hover"]     .jm-mode-check { display: inline; }
.jm-side-group {
  font: var(--fw-medium) var(--text-2xs)/1 var(--font-sans);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--chrome-fg-subtle);
  padding: var(--space-4) var(--space-3) var(--space-2);
  white-space: nowrap;
}
.jm-side-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--chrome-fg-muted);
  font: var(--fw-medium) var(--text-base)/1 var(--font-sans);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-standard),
              background var(--dur-fast) var(--ease-standard);
}
.jm-side-link:hover {
  color: var(--chrome-fg);
  background: var(--chrome-hover);
  text-decoration: none;
}
.jm-side-link.is-active {
  color: var(--chrome-accent);
  background: var(--chrome-accent-bg);
}
.jm-side-link i.bi { font-size: 16px; width: 18px; text-align: center; flex-shrink: 0; }

.jm-sidebar__backdrop { display: none; }

/* ---------- Móvil: cajón fuera de lienzo ----------
   Por debajo de 992px el colapso no aplica: un carril de iconos en un
   móvil ocupa espacio sin dar navegación. Ahí la barra sigue siendo un
   cajón que entra por la izquierda. */
@media (max-width: 991.98px) {
  .jm-sidebar {
    position: fixed;
    top: var(--topbar-h);
    left: 0;
    z-index: 1045;
    height: calc(100vh - var(--topbar-h));
    width: var(--sidebar-w);
    transform: translateX(-100%);
    transition: transform var(--dur-fast) var(--ease-standard);
  }
  .jm-sidebar.is-open { transform: translateX(0); }
  .jm-sidebar__inner { height: 100%; max-height: 100%; }
  /* Los tres modos son de desktop: en un cajón de móvil el mando no
     cambiaría nada visible, así que solo sería ruido. */
  .jm-sidebar__footer { display: none; }
  .jm-sidebar__backdrop {
    position: fixed;
    inset: var(--topbar-h) 0 0 0;
    background: var(--scrim);
    z-index: 1044;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease-standard);
  }
  .jm-sidebar__backdrop.is-open { display: block; opacity: 1; pointer-events: auto; }
}

/* ---------- Desktop: el panel flota sobre el lienzo ---------- */
@media (min-width: 992px) {
  /* Aquí el panel se despega del hueco. `fixed` y no `sticky` porque en
     modo hover tiene que poder crecer POR ENCIMA del contenido sin
     ocupar sitio; un elemento en flujo, por muy sticky que sea, empuja.
     Va por debajo del topbar (1050) y arranca justo a su altura, así
     que nunca se solapan. */
  .jm-sidebar__inner {
    position: fixed;
    top: var(--topbar-h);
    left: 0;
    bottom: 0;
    width: var(--sidebar-w);
    max-height: none;
    background: var(--chrome-bg);
    border-right: 1px solid var(--chrome-border);
    z-index: 1046;
    transition: width var(--dur-normal) var(--ease-standard),
                box-shadow var(--dur-normal) var(--ease-standard),
                border-color var(--dur-normal) var(--ease-standard);
  }

  /* Modo hover: el panel se despliega al pasar el ratón (o al recibir
     el foco con el teclado, que si no la barra sería inalcanzable sin
     ratón). El hueco reservado NO cambia — por eso el contenido se
     queda quieto. La sombra es lo que dice que está flotando encima. */
  :root[data-sidebar-peek] .jm-sidebar__inner {
    width: var(--sidebar-w-open);
    box-shadow: var(--shadow-lift);
    border-right-color: var(--border-strong);
  }
  @media (prefers-reduced-motion: reduce) {
    .jm-sidebar__inner { transition: none; }
  }

  :root[data-sidebar="collapsed"]:not([data-sidebar-peek]) .jm-side-link {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
  }
  /* Las etiquetas se ocultan con `display:none`, no con `width:0`:
     un texto de ancho cero sigue siendo leído por el lector de
     pantalla y deja el enlace anunciando dos veces su nombre. El
     `title` del propio enlace es lo que queda como nombre accesible. */
  :root[data-sidebar="collapsed"]:not([data-sidebar-peek]) .jm-side-link > span { display: none; }
  /* El encabezado de grupo no cabe en 68px. Se sustituye por una
     regla: la agrupación se sigue viendo aunque no se lea. */
  :root[data-sidebar="collapsed"]:not([data-sidebar-peek]) .jm-side-group {
    height: 0;
    /* `min-height: 0` y `padding: 0` no son adorno, son lo que hace que
       el texto desaparezca de verdad:
       - en una columna flex los hijos llevan `min-height: auto`, que es
         el alto de su contenido, así que sin esto el alto 0 se ignora;
       - `overflow: hidden` recorta a la caja de PADDING, no a la de
         contenido, así que con el padding vertical que había antes el
         rótulo cabía dentro y seguía viéndose en el carril.
       El aire lo pone el margen, que queda fuera del recorte. */
    min-height: 0;
    padding: 0;
    overflow: hidden;
    border-top: 1px solid var(--chrome-border);
    margin: var(--space-4) var(--space-2) var(--space-3);
  }

  /* Etiqueta flotante al pasar el ratón: sin ella, un carril de solo
     iconos obliga a adivinar. Es un ::after del enlace, no un
     `title` nativo, porque el nativo tarda ~1s en aparecer.

     Solo en el modo `collapsed` PERSISTENTE: en modo hover el propio
     panel se despliega y enseña el nombre, así que una etiqueta
     flotante encima sería el mismo dato dos veces. */
  :root[data-sidebar-mode="collapsed"] .jm-side-link { position: relative; }
  :root[data-sidebar-mode="collapsed"] .jm-side-link::after {
    content: attr(data-label);
    position: absolute;
    left: calc(100% + var(--space-2));
    top: 50%;
    transform: translateY(-50%);
    background: var(--surface-100);
    color: var(--foreground);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-soft);
    padding: var(--space-2) var(--space-3);
    font: var(--fw-medium) var(--text-sm)/1 var(--font-sans);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease-standard);
    z-index: 1060;
  }
  :root[data-sidebar-mode="collapsed"] .jm-side-link:hover::after,
  :root[data-sidebar-mode="collapsed"] .jm-side-link:focus-visible::after { opacity: 1; }
}

/* El carril no puede recortar la etiqueta flotante. Y `overflow-x:
   visible` con `overflow-y: auto` NO sirve: si un eje no es visible,
   el otro se calcula como `auto` y vuelve a recortar. Así que en el
   modo colapsado persistente la lista deja de scrollear: son 8 iconos,
   caben de sobra en cualquier viewport, y si no cupieran scrollea la
   página. En modo hover no hace falta — ahí no hay etiqueta flotante
   que recortar. */
@media (min-width: 992px) {
  :root[data-sidebar-mode="collapsed"] .jm-side-nav { overflow: visible; }
}
