/* ═══════════════════════════════════════════════════════════════════════
   STRATUM CRISTAL — capa de dirección visual
   ═══════════════════════════════════════════════════════════════════════

   Se carga DESPUÉS de stratum-pro.css y solo redefine VALORES de tokens
   (--sp-*), más un puñado de utilidades nuevas. No redefine selectores de
   componente existentes, así que no puede romper la cascada previa:
   quitar el <link> de base.html revierte el rediseño entero.

   Restricción deliberada — el tutorial guiado mide posiciones con
   getBoundingClientRect() sobre estos 9 selectores:

     #ndDiagnostico  .nd-pulse  .nd-right  .nd-input-bar
     a[href*="mis-datos"]  a[href*="history"]
     #cliente-estado-card  #cliente-nuevo-analisis  #cliente-informes

   Por eso aquí NO hay animaciones de entrada sobre contenido del panel:
   un elemento con transform/opacity en vuelo devuelve un rect equivocado y
   el foco del tutorial se dibujaría en el sitio incorrecto. El movimiento
   de esta capa es solo hover/estado, que ocurre después de la medición.
   ═══════════════════════════════════════════════════════════════════════ */


/* ── 1. Paleta: claro ──────────────────────────────────────────────────
   Neutros con sesgo frío hacia el acento, nunca gris puro.               */
:root {
  --sp-bg-app:            #F6F8FC;
  --sp-bg-sidebar:        #FFFFFF;
  --sp-bg-card:           #FFFFFF;
  --sp-bg-card-hover:     #FAFBFE;
  --sp-bg-input:          #EFF2F8;
  --sp-bg-input-focus:    #FFFFFF;
  --sp-bg-secondary:      #E6EAF3;

  --sp-text-primary:      #0E1420;
  --sp-text-secondary:    #4A5567;
  --sp-text-muted:        #6E7C90;   /* subido de #6B7280: contraste real */

  --sp-border:            #E1E7F0;
  --sp-border-light:      #EFF2F8;
  --sp-border-focus:      #5F77E8;

  --sp-accent:            #4E5FD8;
  --sp-accent-hover:      #3F4FC4;
  --sp-accent-light:      rgba(78, 95, 216, .09);
  --sp-accent-subtle:     rgba(78, 95, 216, .055);

  --sp-sidebar-active-bg:   rgba(78, 95, 216, .085);
  --sp-sidebar-active-text: #4E5FD8;
  --sp-sidebar-active-bar:  #4E5FD8;

  --sp-success:  #0E9F6E;
  --sp-warning:  #B4740A;
  --sp-danger:   #D93A46;
  --sp-info:     #2563EB;

  /* Latón: el especular cálido. Solo énfasis, nunca superficie. */
  --sp-brass:       #B07A32;
  --sp-brass-soft:  rgba(176, 122, 50, .11);

  /* Cristal (claro) */
  --sp-glass-face:  linear-gradient(148deg, rgba(255,255,255,.92), rgba(255,255,255,.68) 44%, rgba(255,255,255,.86));
  --sp-glass-edge:  rgba(14, 20, 32, .07);
  --sp-glass-spec:  rgba(255, 255, 255, .95);
  --sp-glass-blur:  blur(26px) saturate(165%);

  /* Sombras: más difusas y con tinte del fondo, no negro puro */
  --sp-shadow-sm:   0 1px 2px rgba(14,20,32,.05);
  --sp-shadow-md:   0 2px 6px rgba(14,20,32,.06), 0 1px 2px rgba(14,20,32,.04);
  --sp-shadow-lg:   0 8px 24px -8px rgba(14,20,32,.12), 0 2px 6px rgba(14,20,32,.05);
  --sp-shadow-xl:   0 18px 48px -16px rgba(14,20,32,.17), 0 3px 10px rgba(14,20,32,.06);
  --sp-shadow-card: 0 1px 3px rgba(14,20,32,.05), 0 1px 2px rgba(14,20,32,.03);

  /* Radios: un punto más generosos, la curva de Apple */
  --sp-radius-sm:   8px;
  --sp-radius-md:   11px;
  --sp-radius-lg:   15px;
  --sp-radius-xl:   20px;

  /* Curva de easing única para todo el producto */
  --sp-ease:        cubic-bezier(.16, 1, .3, 1);
  --sp-ease-out:    cubic-bezier(.32, .72, 0, 1);
  --sp-dur:         .42s;
  --sp-dur-fast:    .22s;
}


/* ── 2. Paleta: oscuro (el modo por defecto del producto) ────────────── */
html.dark {
  --sp-bg-app:            #080B11;
  --sp-bg-sidebar:        #0C111A;
  --sp-bg-card:           #101725;
  --sp-bg-card-hover:     #141C2D;
  --sp-bg-input:          #131A29;
  --sp-bg-input-focus:    #182133;
  --sp-bg-secondary:      #17202F;

  --sp-sidebar-border:      rgba(255,255,255,.065);
  --sp-sidebar-text:        #C3CEDC;
  --sp-sidebar-text-muted:  #8494A8;
  --sp-sidebar-text-heading:#EEF2F9;
  --sp-sidebar-hover-bg:    rgba(255,255,255,.055);
  --sp-sidebar-hover-text:  #EEF2F9;
  --sp-sidebar-active-bg:   rgba(143,164,255,.13);
  --sp-sidebar-active-text: #A9BAFF;
  --sp-sidebar-active-bar:  #8FA4FF;

  --sp-text-primary:      #EEF2F9;
  --sp-text-secondary:    #9DAABA;
  --sp-text-muted:        #8494A8;   /* era #6B7280 — corrige el contraste
                                        bajo documentado en la PWA/Cartera */

  --sp-border:            #212C3E;
  --sp-border-light:      #18202F;
  --sp-border-focus:      #8FA4FF;

  --sp-accent:            #8FA4FF;
  --sp-accent-hover:      #A9BAFF;
  --sp-accent-light:      rgba(143,164,255,.12);
  --sp-accent-subtle:     rgba(143,164,255,.07);

  --sp-success:  #4ED7A4;
  --sp-warning:  #F0B45A;
  --sp-danger:   #F2707C;
  --sp-info:     #6E9BFF;

  --sp-brass:       #DFAB6E;
  --sp-brass-soft:  rgba(223,171,110,.13);

  --sp-glass-face:  linear-gradient(148deg, rgba(255,255,255,.075), rgba(255,255,255,.018) 42%, rgba(255,255,255,.045));
  --sp-glass-edge:  rgba(255,255,255,.10);
  --sp-glass-spec:  rgba(255,255,255,.16);
  --sp-glass-blur:  blur(30px) saturate(175%);

  --sp-shadow-sm:   0 1px 3px rgba(0,0,0,.35);
  --sp-shadow-md:   0 2px 10px -2px rgba(0,0,0,.45);
  --sp-shadow-lg:   0 12px 32px -12px rgba(0,0,0,.6), 0 2px 6px rgba(0,0,0,.35);
  --sp-shadow-xl:   0 28px 70px -26px rgba(0,0,0,.85), 0 2px 10px -4px rgba(0,0,0,.55);
  --sp-shadow-card: 0 1px 4px rgba(0,0,0,.35), 0 1px 2px rgba(0,0,0,.2);
}


/* ── 3. Atmósfera de fondo ──────────────────────────────────────────────
   El cristal necesita algo detrás que refractar. Sobre negro plano
   cualquier backdrop-filter parece plástico gris.

   FIX 23/8, vigesimotercera continuación: esto llevaba desde el commit
   4180714 forzando `position:relative` en TODOS los hijos directos de
   <body> para que pintaran por encima de este fondo — incluidos los que
   ya eran `position:fixed` a propósito: `.sp-skip-link` (enlace de
   accesibilidad "saltar al contenido"), `#sp-page-loader` (barra de
   progreso), `.sp-scroll-top` (botón flotante) y `.sp-loading-overlay`
   (overlay de carga a pantalla completa). Al pasar a `relative` dejaban
   de estar fuera del flujo del documento y volvían a reservar su alto
   natural dentro de <body> — unos 26px en la página del panel — así que
   `.sp-app`, con altura fija a 100vh desde la sección 9, se salía esos
   mismos 26px por debajo de la ventana. Con el scroll de página normal
   (antes de la sección 9) esos 26px de más simplemente alargaban una
   página que ya se desplazaba entera, así que nunca se notaron: el `<
   overflow:hidden` de la sección 9 fue lo que empezó a recortarlos de
   verdad — la barra de mensajes del chat cortada contra el borde inferior
   de la ventana es el síntoma, no la causa.

   Arreglado sin la promoción de posición: en vez de subir cada hijo de
   <body> a un nivel de apilamiento por encima del fondo, se baja el
   propio fondo por debajo de todo con z-index negativo — así los hijos
   `position:fixed` recuperan su comportamiento real (fuera del flujo,
   fijos a la ventana) y el contenido normal de <body> sigue pintando por
   encima del gradiente sin necesitar ningún truco de posición.           */
html.dark body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(820px 560px at 14% -8%,  rgba(95,119,232,.16), transparent 62%),
    radial-gradient(700px 480px at 92% 4%,   rgba(223,171,110,.055), transparent 60%),
    radial-gradient(900px 660px at 60% 96%,  rgba(143,164,255,.06), transparent 64%);
}


/* ── 4. Superficies: canto especular ────────────────────────────────────
   Lo que separa "tarjeta oscura" de "vidrio": una línea de luz de 1px en
   el borde superior, donde la luz ambiental se acumularía de verdad.
   Barato (sin backdrop-filter) y aplicable a las 50 pantallas.           */
html.dark .sp-card,
html.dark .sp-panel,
html.dark .nd-card,
html.dark .stat-card {
  box-shadow: var(--sp-shadow-card), inset 0 1px 0 rgba(255,255,255,.055);
}


/* ── 5. Utilidad de cristal — opt-in, no global ─────────────────────────
   backdrop-filter es caro. Se aplica a mano en las superficies elevadas
   (modales, barra de chat, cabeceras fijas), nunca a todas las tarjetas. */
.sp-glass {
  position: relative;
  background: var(--sp-glass-face);
  backdrop-filter: var(--sp-glass-blur);
  -webkit-backdrop-filter: var(--sp-glass-blur);
  border: 1px solid var(--sp-glass-edge);
  border-radius: var(--sp-radius-xl);
  box-shadow:
    var(--sp-shadow-xl),
    inset 0  1px 0 var(--sp-glass-spec),
    inset 0 -1px 0 rgba(255,255,255,.035);
}

/* Especular que sigue al cursor. Las variables --sp-mx/--sp-my las
   escribe cristal.js; sin JS el bloque simplemente no se ve. */
.sp-glass--live::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(320px circle at var(--sp-mx, 50%) var(--sp-my, 0%),
              rgba(255,255,255,.10), transparent 60%);
  opacity: 0;
  transition: opacity .5s var(--sp-ease);
}
.sp-glass--live:hover::after { opacity: 1; }


/* ── 6. Movimiento: solo estado, nunca entrada ──────────────────────────
   Ver la nota de cabecera sobre el tutorial.                             */
.sp-btn, .sp-chip, .nd-chip-q, .sp-card--interactive {
  transition:
    transform  var(--sp-dur) var(--sp-ease),
    box-shadow var(--sp-dur) var(--sp-ease),
    background var(--sp-dur-fast) var(--sp-ease),
    border-color var(--sp-dur-fast) var(--sp-ease);
}
.sp-btn:hover, .sp-chip:hover, .nd-chip-q:hover {
  transform: translateY(-1px);
}
.sp-btn:active, .sp-chip:active, .nd-chip-q:active {
  transform: translateY(0) scale(.985);
  transition-duration: .09s;
}
.sp-card--interactive:hover {
  transform: translateY(-2px);
  box-shadow: var(--sp-shadow-lg), inset 0 1px 0 rgba(255,255,255,.08);
}

/* Foco visible y consistente en todo el producto (accesibilidad) */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--sp-accent);
  outline-offset: 2px;
  border-radius: var(--sp-radius-sm);
}

/* Cifras alineadas allá donde haya columnas de números */
.sp-num, .nd-kpi-value, .stat-value, td.num {
  font-variant-numeric: tabular-nums;
}


/* ── 7. Respeto a prefers-reduced-motion ────────────────────────────────
   Obligatorio: hay usuarios con sensibilidad vestibular y es criterio
   WCAG 2.3.3.                                                            */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .sp-btn:hover, .sp-chip:hover, .nd-chip-q:hover,
  .sp-card--interactive:hover { transform: none; }
}


/* ── 8. Tinta sobre el acento (REGRESIÓN CORREGIDA) ────────────────────────
   La sección 2 subió --sp-accent a #8FA4FF, un peribleu claro. Hay 36 reglas
   repartidas entre 4 hojas CSS y 22 plantillas que pintan texto BLANCO sobre
   ese acento — botones primarios, el enlace de "saltar al contenido", CTAs.
   Con blanco encima, el contraste real es:

     blanco sobre #7C85D6 (acento anterior)   3.40:1   ya fallaba
     blanco sobre #8FA4FF (acento nuevo)      2.35:1   peor
     tinta  #05070A sobre #8FA4FF             8.57:1   correcto

   Es decir: el fallo era previo, pero la sección 2 lo agravó. Se arregla
   invirtiendo la tinta, que es lo correcto sobre un acento claro.

   Solo en modo OSCURO: en claro el acento es #4E5FD8 y el blanco encima da
   5.31:1, que sí cumple — ahí no se toca nada.

   El prefijo `html.dark` no es decorativo: sube la especificidad a (0,1,1),
   necesaria para ganar a las reglas de clase simple (0,1,0) que viven en
   bloques <style> dentro de las plantillas hijas, que se resuelven después
   de esta hoja en el orden del documento.                                   */

html.dark .sp-skip-link,
html.dark .sp-btn-primary,
html.dark .sp-btn-primary:hover,
html.dark .exec-btn-primary,
html.dark .sp-exec-action-icon,
html.dark .upgrade-modal-cta,
html.dark .sp-pdf-fab,
html.dark .sp-consultas-send-btn,
html.dark .simulate-ia-btn,
html.dark .sp-scroll-top:hover,
html.dark .dp-btn-primary,
html.dark .dp-btn-primary:hover,
html.dark .dp-brief-empty-btn,
html.dark .sp-notif__action--primary,
html.dark .hist-filter-btn.active,
html.dark .hist-badge:hover,
html.dark .nd-empty-cta,
html.dark .nd-btn-send,
html.dark .nd-na-primary,
html.dark .md-drop-btn,
html.dark .btn-save,
html.dark .salud-sim-tab.active,
html.dark .role-admin,
html.dark .action-btn-primary,
html.dark .pw-btn,
html.dark .admin-topbar-btn,
html.dark .err-btn,
html.dark .pg-invite-btn,
html.dark .btn-launch,
html.dark .btn-primary-sm,
html.dark .dv6g-btn-batch,
html.dark .gu-submit {
  color: #05070A;
  /* -webkit-text-fill-color ademas de color: varios de estos botones tienen
     una transicion CSS de `color` que puede quedarse en estado `running`, y
     las declaraciones de transicion ganan en la cascada incluso a un
     !important de autor. text-fill-color no participa de esa transicion, asi
     que es lo unico que pinta el texto de forma fiable en ese caso. */
  -webkit-text-fill-color: #05070A;
}

/* Los iconos SVG de dentro heredan por currentColor, pero algunos fijan
   stroke propio; se fuerzan a la misma tinta para que no queden blancos
   sobre el fondo claro del botón. */
html.dark .sp-btn-primary svg,
html.dark .dp-btn-primary svg,
html.dark .nd-btn-send svg,
html.dark .nd-na-primary svg,
html.dark .sp-consultas-send-btn svg,
html.dark .sp-pdf-fab svg {
  stroke: currentColor;
  fill: none;
}


/* ── 9. Marco fijo de aplicación (sin scroll de página) ────────────────────
   Medido en producción: el documento ocupaba 749px en una ventana de 657px,
   así que la página entera se desplazaba 92px y la barra de KPIs se salía de
   vista. Sensación de web, no de aplicación.

   El panel YA es una pantalla fija por dentro — .nd-wrap es
   `height: calc(100vh - 56px); overflow: hidden` con paneles de scroll
   propios. Lo que desbordaba era el contenedor de alrededor: .sp-main con
   `min-height: 100vh` (crece, no se limita) más el relleno de .sp-content
   (56px arriba para el topbar fijo + 24px abajo) sumados encima de un hijo
   que ya medía casi la ventana entera.

   Aquí se invierte: el marco se fija a la ventana y el scroll pasa a vivir
   DENTRO del panel de contenido. Ojo, no se elimina el scroll: el chat, el
   historial y las tablas largas tienen que poder desplazarse. Lo que
   desaparece es que se mueva el marco.

   Acotado a escritorio con ventana alta: por debajo de 901px de ancho o
   640px de alto se deja el scroll de página normal, porque ahí fijar la
   altura deja contenido inalcanzable (y en móvil pelea con la barra de
   direcciones que aparece y desaparece).                                    */

@media (min-width: 901px) and (min-height: 640px) {

  html, body {
    height: 100%;
    overflow: hidden;
  }

  .sp-main {
    height: 100vh;
    min-height: 0;      /* anula el min-height:100vh que permitía crecer */
    overflow: hidden;
  }

  /* El único elemento que se desplaza en las páginas normales. */
  .sp-content {
    flex: 1 1 auto;
    min-height: 0;      /* sin esto un hijo flex no puede encoger y el
                           overflow-y no llega a activarse nunca */
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* El panel gestiona su propio scroll interno: darle otro aquí produciría
     dos barras anidadas. Se le quita el relleno y se le deja llenar el
     hueco exacto que queda bajo el topbar fijo. */
  .sp-content:has(.nd-wrap) {
    padding: 56px 0 0 !important;   /* 48px de topbar + 8px de aire */
    max-width: none;
    overflow: hidden;
  }
  .sp-content:has(.nd-wrap) .nd-wrap {
    height: 100%;       /* en vez de calc(100vh - 56px): ya está encajado */
  }

  /* Barra de scroll discreta dentro del panel, para que el borde del
     contenedor no compita visualmente con el contenido. */
  .sp-content::-webkit-scrollbar { width: 10px; }
  .sp-content::-webkit-scrollbar-track { background: transparent; }
  .sp-content::-webkit-scrollbar-thumb {
    background: rgba(255,255,255,.10);
    border-radius: 10px;
    border: 3px solid transparent;
    background-clip: padding-box;
  }
  .sp-content::-webkit-scrollbar-thumb:hover { background-color: rgba(255,255,255,.18); background-clip: padding-box; }
  .sp-content { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.14) transparent; }
}


/* ══════════════════════════════════════════════════════════════════════════
   10. REDISEÑO DE COMPONENTES — ESCRITORIO
   ══════════════════════════════════════════════════════════════════════════

   Las secciones 1-9 solo retocaban VALORES de tokens: color, sombra, radio.
   Eso cambia el tono pero no la forma, y el escritorio seguía viéndose igual
   que antes. Aquí se rediseñan los componentes en sí: superficie, densidad,
   jerarquía tipográfica y respuesta al puntero.

   Sigue en pie la restricción del tutorial: NADA de animaciones de entrada.
   El tutorial mide con getBoundingClientRect() sobre #ndDiagnostico,
   .nd-pulse, .nd-right y .nd-input-bar; un elemento con transform en vuelo
   devuelve un rect equivocado. Cambiar tamaño o color de forma ESTÁTICA es
   seguro — se mide lo que haya en ese momento. Lo prohibido es que se esté
   moviendo mientras se mide.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 10.1 Barra lateral ───────────────────────────────────────────────────
   Antes: bloque plano del mismo tono que el fondo. Ahora: plano propio, con
   separación por luz en vez de por línea dura. */
html.dark .sp-sidebar {
  background: linear-gradient(180deg, rgba(255,255,255,.028), rgba(255,255,255,.008) 38%, transparent);
  background-color: #0A0F18;
  border-right: 1px solid rgba(255,255,255,.055);
  box-shadow: inset -1px 0 0 rgba(255,255,255,.02);
}

html.dark .sp-sidebar-header {
  border-bottom: 1px solid rgba(255,255,255,.05);
}

/* Identidad de empresa: revertido a texto suelto, sin caja.
   [23/8] El intento de "tarjeta con material" (fondo + borde + radio 12px
   sin padding, ver historial git) quedaba como una píldora apretada
   pegada al texto, sin relación visual con el icono de arriba ni con la
   tarjeta real de "cfossss" de abajo — confirmado por Álvaro con captura.
   Sin caja es lo que ya funcionaba bien; no hacía falta un tratamiento
   aquí. */

/* Navegación: el estado activo se marca con luz, no con un bloque de color */
.sp-nav-link {
  border-radius: 10px;
  padding: 10px 12px;
  font-weight: 500;
  letter-spacing: -.005em;
  transition: background .22s var(--sp-ease), color .22s var(--sp-ease);
}
html.dark .sp-nav-link:hover { background: rgba(255,255,255,.05); }
html.dark .sp-nav-link.active {
  background: linear-gradient(90deg, rgba(143,164,255,.16), rgba(143,164,255,.05));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07);
}
/* La marca del elemento activo: un trazo de luz, no una barra maciza */
html.dark .sp-nav-link.active::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  width: 2px; height: 17px;
  margin-top: -8.5px;
  border-radius: 0 2px 2px 0;
  background: var(--sp-accent);
  box-shadow: 0 0 10px var(--sp-accent);
}
.sp-nav-section-label {
  font-size: 10px;
  letter-spacing: .13em;
  opacity: .72;
}

/* ── 10.2 Barra superior: cristal ─────────────────────────────────────── */
html.dark .app-topbar {
  background: rgba(10, 15, 24, .72);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  border-bottom: 1px solid rgba(255,255,255,.06);
  box-shadow: 0 1px 0 rgba(255,255,255,.02), 0 8px 24px -18px rgba(0,0,0,.9);
}
.app-topbar__title {
  font-weight: 600;
  letter-spacing: -.012em;
  font-size: 15px;
}

/* ── 10.3 Superficies: canto especular y profundidad por capas ────────── */
html.dark .sp-card {
  background:
    linear-gradient(168deg, rgba(255,255,255,.045), rgba(255,255,255,.012) 45%, rgba(255,255,255,.028)),
    var(--sp-bg-card);
  border: 1px solid rgba(255,255,255,.075);
  border-radius: 16px;
  box-shadow:
    0 1px 2px rgba(0,0,0,.4),
    0 12px 28px -16px rgba(0,0,0,.75),
    inset 0 1px 0 rgba(255,255,255,.075);
}
html.dark .sp-card-interactive {
  transition: transform .42s var(--sp-ease), box-shadow .42s var(--sp-ease), border-color .25s var(--sp-ease);
}
html.dark .sp-card-interactive:hover {
  transform: translateY(-2px);
  border-color: rgba(143,164,255,.28);
  box-shadow:
    0 2px 4px rgba(0,0,0,.4),
    0 22px 48px -20px rgba(0,0,0,.85),
    inset 0 1px 0 rgba(255,255,255,.1);
}

/* ── 10.4 Botones ─────────────────────────────────────────────────────── */
.sp-btn {
  border-radius: 11px;
  padding: 10px 18px;
  letter-spacing: -.006em;
  transition: transform .38s var(--sp-ease), box-shadow .38s var(--sp-ease),
              background .2s var(--sp-ease), border-color .2s var(--sp-ease);
}
html.dark .sp-btn-primary {
  background: linear-gradient(168deg, #B9C6FF, var(--sp-accent) 48%, #6F86F0);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.55), 0 8px 20px -10px var(--sp-accent-glow, rgba(143,164,255,.4));
}
html.dark .sp-btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.65), 0 16px 32px -12px rgba(143,164,255,.45);
}
html.dark .sp-btn-secondary,
html.dark .sp-btn-ghost {
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.09);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
}
html.dark .sp-btn-secondary:hover,
html.dark .sp-btn-ghost:hover {
  background: rgba(255,255,255,.085);
  border-color: rgba(255,255,255,.14);
  transform: translateY(-1px);
}
.sp-btn:active { transform: translateY(0) scale(.985); transition-duration: .08s; }

/* ── 10.5 Insignias ───────────────────────────────────────────────────── */
.sp-badge {
  padding: 4px 11px;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: .02em;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08);
}

/* ── 10.6 Campos de formulario ────────────────────────────────────────── */
html.dark input[type="text"], html.dark input[type="email"],
html.dark input[type="password"], html.dark input[type="number"],
html.dark input[type="date"], html.dark select, html.dark textarea {
  background: rgba(255,255,255,.035);
  border: 1px solid rgba(255,255,255,.085);
  border-radius: 11px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
  transition: border-color .22s var(--sp-ease), background .22s var(--sp-ease), box-shadow .22s var(--sp-ease);
}
html.dark input:focus, html.dark select:focus, html.dark textarea:focus {
  background: rgba(255,255,255,.055);
  border-color: rgba(143,164,255,.45);
  box-shadow: 0 0 0 3px rgba(143,164,255,.13), inset 0 1px 0 rgba(255,255,255,.05);
  outline: none;
}

/* ── 10.7 Panel: barra de KPIs ────────────────────────────────────────────
   Es un objetivo del tutorial (.nd-pulse). Solo estilo estático. */
html.dark .nd-pulse {
  background: linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,.01));
  border-bottom: 1px solid rgba(255,255,255,.07);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
}
html.dark .nd-chip { border-right-color: rgba(255,255,255,.055); }
html.dark .nd-chip-label { letter-spacing: .12em; opacity: .82; }
html.dark .nd-chip-val { letter-spacing: -.02em; font-variant-numeric: tabular-nums; }

/* ── 10.8 Panel: tarjeta de diagnóstico ─────────────────────────────────
   #ndDiagnostico, objetivo del tutorial. Estilo estático, sin movimiento. */
html.dark .nd-diagn {
  background:
    linear-gradient(160deg, rgba(255,255,255,.05), rgba(255,255,255,.012) 48%, rgba(255,255,255,.03)),
    rgba(16,23,37,.72);
  border: 1px solid rgba(255,255,255,.085);
  border-radius: 16px;
  box-shadow:
    0 18px 44px -24px rgba(0,0,0,.85),
    inset 0 1px 0 rgba(255,255,255,.1);
  padding: 16px 18px;
}
html.dark .nd-diagn-label { letter-spacing: .13em; opacity: .8; }
html.dark .nd-diagn-text { letter-spacing: -.011em; }
html.dark .nd-diagn-ev-val { font-variant-numeric: tabular-nums; }

/* ── 10.9 Panel: burbujas de chat ─────────────────────────────────────── */
html.dark .nd-bub {
  border-radius: 15px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.055);
  letter-spacing: -.005em;
}
html.dark .nd-msg-user .nd-bub {
  background: linear-gradient(160deg, rgba(143,164,255,.19), rgba(95,119,232,.12));
  border: 1px solid rgba(143,164,255,.24);
}
html.dark .nd-av {
  background: rgba(255,255,255,.06);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);
}

/* ── 10.10 Panel: barra de entrada ──────────────────────────────────────
   .nd-input-bar, objetivo del tutorial. Estático. */
html.dark .nd-input-bar {
  background: rgba(255,255,255,.03);
  border-top: 1px solid rgba(255,255,255,.06);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.035);
}

/* ── 10.11 Panel: columna derecha ──────────────────────────────────────── */
html.dark .nd-kpi {
  background: linear-gradient(165deg, rgba(255,255,255,.045), rgba(255,255,255,.012));
  border: 1px solid rgba(255,255,255,.07);
  border-radius: 13px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07);
}
html.dark .nd-kpi-val { font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
html.dark .nd-kpi-lbl, html.dark .nd-sec-lbl { letter-spacing: .12em; opacity: .82; }

html.dark .nd-hist-item, html.dark .nd-pdf {
  border-radius: 12px;
  border: 1px solid rgba(255,255,255,.06);
  background: rgba(255,255,255,.026);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
  transition: background .25s var(--sp-ease), border-color .25s var(--sp-ease), transform .38s var(--sp-ease);
}
html.dark .nd-hist-item:hover, html.dark .nd-pdf:hover {
  background: rgba(255,255,255,.05);
  border-color: rgba(255,255,255,.1);
  transform: translateY(-1px);
}

/* Chips de acción rápida del chat */
html.dark .nd-chip-q {
  background: rgba(255,255,255,.045);
  border: 1px solid rgba(255,255,255,.085);
  border-radius: 100px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
}
html.dark .nd-chip-q:hover {
  background: rgba(143,164,255,.13);
  border-color: rgba(143,164,255,.3);
}

/* ── 10.12 Tablas ─────────────────────────────────────────────────────── */
html.dark table thead th {
  font-size: 10.5px;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--sp-text-muted);
  border-bottom: 1px solid rgba(255,255,255,.07);
  font-weight: 650;
}
html.dark table tbody tr { transition: background .22s var(--sp-ease); }
html.dark table tbody tr:hover { background: rgba(255,255,255,.032); }
html.dark table td { border-bottom-color: rgba(255,255,255,.045); }
table td, table th { font-variant-numeric: tabular-nums; }

/* ── 10.13 Jerarquía tipográfica ──────────────────────────────────────────
   El ajuste que más "producto caro" aporta y menos se nota conscientemente:
   títulos con tracking negativo y rótulos en versalita con tracking abierto. */
h1, h2, h3, .sp-card-header, .hist-head-title, .md-page-title {
  letter-spacing: -.018em;
  text-wrap: balance;
}
.sp-section-label, .nav-section-label { letter-spacing: .13em; font-size: 10px; }

/* ── 10.14 Desvanecido en los bordes de las zonas con scroll ──────────────
   Detalle pequeño y muy visible: sin esto, el texto del chat queda
   guillotinado a media línea contra el borde del contenedor al desplazarse.
   Es lo que hace que una interfaz parezca barata aunque el resto esté bien.
   Con la máscara, el contenido se disuelve en el borde en vez de cortarse.

   mask-image sobre el elemento que ya tiene overflow. No afecta a la
   posición ni al tamaño, así que no interfiere con las mediciones del
   tutorial. */
.nd-messages {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 18px, #000 calc(100% - 10px), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 18px, #000 calc(100% - 10px), transparent 100%);
}
.nd-right {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
}
/* El panel de contenido de las páginas normales, igual */
@media (min-width: 901px) and (min-height: 640px) {
  .sp-content:not(:has(.nd-wrap)) {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 10px, #000 calc(100% - 12px), transparent 100%);
            mask-image: linear-gradient(to bottom, transparent 0, #000 10px, #000 calc(100% - 12px), transparent 100%);
  }
}

/* ── 10.15 Respeto a prefers-reduced-motion ───────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html.dark .sp-card-interactive:hover,
  html.dark .sp-btn-primary:hover,
  html.dark .sp-btn-secondary:hover,
  html.dark .sp-btn-ghost:hover,
  html.dark .nd-hist-item:hover,
  html.dark .nd-pdf:hover,
  .sp-btn:active { transform: none; }
}
