/* Transporte Nidalx — estilos complementarios a Tailwind (CDN)
   Dirección de arte: Fase 6 "Titanium Cyber-Industrial / Sci-Fi Logistics"
   — evolución del 3D Industrial Metálico con iluminación viva, ambiente
   dinámico (aurora mesh), bordes shimmer animados y neón en KPIs. Ver
   CLAUDE.md — sección "Dirección de arte" — para los design tokens y
   reglas completas. */

/* Ángulo animable para los bordes "beam" (conic-gradient) de las tarjetas
   KPI y el banner de seguro — registrar como <angle> es lo que permite que
   @keyframes lo anime de forma continua en vez de saltar de 0 a 360. */
@property --tm-beam-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

::selection { background: #d97706; color: #181f2a; }

* { scrollbar-width: thin; scrollbar-color: #3d495e #1f2735; }
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-track { background: #1f2735; }
*::-webkit-scrollbar-thumb { background: #3d495e; border-radius: 6px; }
*::-webkit-scrollbar-thumb:hover { background: #54627a; }

:focus-visible {
  outline: 2px solid #f59e0b;
  outline-offset: 2px;
  border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}

/* ---------- Fondo de página: acero técnico + micro-grid + resplandor ambiental ----------
   Dos capas de background-image sobre el mismo elemento: el gradiente
   radial de siempre (tono base) + una cuadrícula técnica de puntos de 28px
   (textura "instrumento de precisión"). El movimiento de luz real vive en
   .tm-aurora (ver abajo), que son elementos DOM aparte porque un
   background-image no se puede animar en posición de forma barata/fluida
   comparado con transform en una capa compuesta propia. */
html, body {
  background:
    radial-gradient(circle at 50% 0%, #2b3648 0%, #181f2a 55%, #141a24 100%),
    radial-gradient(rgba(255, 255, 255, 0.08) 1px, transparent 1px) !important;
  background-size: 100% 100%, 28px 28px !important;
  background-position: 0 0, 0 0 !important;
  background-repeat: no-repeat, repeat !important;
  background-attachment: fixed, fixed;
}

/* ---------- Ambient Aurora Mesh — Fase 6.3 "Líquidos Inmiscibles / Blobs Fluidos" ----------
   Elementos DOM fijos detrás de todo el layout (ver #app-shell más abajo,
   que sube a z-1) — no son background-image porque necesitan animar
   transform (GPU) de forma fluida e independiente sin repintar el fondo
   completo en cada frame.

   Morfología: cada orbe deforma su `border-radius` (8 valores compuestos,
   4 elipses distintas por vuelta) en sincronía con la traslación y una
   rotación completa (0→360deg), simulando una gota líquida en suspensión
   que se estira/aplana en vez de un círculo rígido que solo se traslada.

   Trayectoria: cada `@keyframes` recorre 4 puntos de la pantalla completa
   (esquina de origen → cuadrante opuesto → borde contrario → centro →
   regreso al origen), con desplazamientos en `vw`/`vh` de hasta ~70-80
   puntos — cruzan el lienzo entero, no un área acotada como en la Fase 6.2.

   Async: duraciones en segundos primos e independientes (ámbar 31s, cian
   43s, azul 37s) con `ease-in-out infinite alternate` — al no compartir
   múltiplo común bajo, los tres orbes casi nunca están en la misma fase de
   su recorrido a la vez, así que se cruzan en cuadrantes distintos en cada
   pasada y la superposición nunca se percibe como un ciclo repetitivo.

   Inmiscibilidad: `mix-blend-mode: screen` en vez de opacidad plana — al
   traslaparse dos orbes de color distinto, el resultado es un destello de
   luz más brillante (como líquidos que refractan luz al tocarse) en vez de
   un manchón sucio por alpha-blending normal. */
.tm-aurora {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  will-change: transform;
}
.tm-aurora-orb {
  position: absolute;
  filter: blur(75px);
  mix-blend-mode: screen;
  will-change: transform, border-radius, opacity;
  transform: translate3d(0, 0, 0);
  pointer-events: none;
}
.tm-aurora-amber-1 {
  width: 40vw; height: 40vw;
  min-width: 320px; min-height: 320px;
  top: 10vh; left: 10vw;
  background: radial-gradient(circle at 35% 35%, #fef3c7 0%, #fbbf24 35%, #f59e0b 65%, transparent 78%);
  opacity: 0.42;
  animation: tm-aurora-drift-amber 31s ease-in-out infinite alternate;
}
.tm-aurora-cyan-1 {
  width: 36vw; height: 36vw;
  min-width: 280px; min-height: 280px;
  top: 80vh; left: 15vw;
  background: radial-gradient(circle at 60% 40%, #cffafe 0%, #22d3ee 35%, #06b6d4 65%, transparent 78%);
  opacity: 0.42;
  animation: tm-aurora-drift-cyan 43s ease-in-out infinite alternate;
}
.tm-aurora-blue-1 {
  width: 32vw; height: 32vw;
  min-width: 250px; min-height: 250px;
  top: 5vh; left: 50vw;
  background: radial-gradient(circle at 45% 55%, #dbeafe 0%, #3b82f6 35%, #2563eb 65%, transparent 78%);
  opacity: 0.4;
  animation: tm-aurora-drift-blue 37s ease-in-out infinite alternate;
}
/* Ámbar: origen sup-izq (10,10) → cuadrante inf-der (75,80) →
   borde derecho arriba (80,15) → centro (45,50) → regresa a origen. */
@keyframes tm-aurora-drift-amber {
  0%   { transform: translate3d(0, 0, 0) scale(0.95) rotate(0deg); border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
  25%  { transform: translate3d(65vw, 70vh, 0) scale(1.2) rotate(90deg); border-radius: 40% 60% 70% 30% / 50% 60% 30% 60%; }
  50%  { transform: translate3d(70vw, 5vh, 0) scale(0.85) rotate(180deg); border-radius: 70% 30% 50% 50% / 30% 70% 40% 60%; }
  75%  { transform: translate3d(35vw, 40vh, 0) scale(1.25) rotate(270deg); border-radius: 45% 55% 65% 35% / 55% 45% 55% 45%; }
  100% { transform: translate3d(0, 0, 0) scale(1) rotate(360deg); border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
}
/* Cian: origen inf-izq (15,80) → diagonal a sup-der (70,10) →
   baja por el borde derecho (75,70) → cruza horizontal a la izquierda
   (20,65) → regresa a origen. */
@keyframes tm-aurora-drift-cyan {
  0%   { transform: translate3d(0, 0, 0) scale(1) rotate(0deg); border-radius: 40% 60% 70% 30% / 50% 60% 30% 60%; }
  25%  { transform: translate3d(55vw, -70vh, 0) scale(1.15) rotate(-90deg); border-radius: 70% 30% 50% 50% / 30% 70% 40% 60%; }
  50%  { transform: translate3d(60vw, -10vh, 0) scale(0.9) rotate(-180deg); border-radius: 45% 55% 65% 35% / 55% 45% 55% 45%; }
  75%  { transform: translate3d(5vw, -15vh, 0) scale(1.2) rotate(-270deg); border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
  100% { transform: translate3d(0, 0, 0) scale(1) rotate(-360deg); border-radius: 40% 60% 70% 30% / 50% 60% 30% 60%; }
}
/* Azul: origen centro-sup (50,5) → desciende en espiral al cuadrante
   inf-izq (10,75) → cruza diagonal hacia arriba (65,20) → orbita el fondo
   (30,45) → regresa a origen. */
@keyframes tm-aurora-drift-blue {
  0%   { transform: translate3d(0, 0, 0) scale(1.05) rotate(0deg); border-radius: 70% 30% 50% 50% / 30% 70% 40% 60%; }
  25%  { transform: translate3d(-40vw, 70vh, 0) scale(0.85) rotate(120deg); border-radius: 45% 55% 65% 35% / 55% 45% 55% 45%; }
  50%  { transform: translate3d(15vw, 15vh, 0) scale(1.3) rotate(240deg); border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
  75%  { transform: translate3d(-20vw, 40vh, 0) scale(0.9) rotate(300deg); border-radius: 40% 60% 70% 30% / 50% 60% 30% 60%; }
  100% { transform: translate3d(0, 0, 0) scale(1) rotate(360deg); border-radius: 70% 30% 50% 50% / 30% 70% 40% 60%; }
}

/* En móvil los orbes se fijan a un tamaño en px proporcional a un iPhone
   16 Pro (~390px de ancho) y desenfoque reducido (55px) porque en un
   viewport angosto el radio de acción en vw + blur alto diluía el color
   casi por completo (mismo hallazgo que la Fase 6.2). Las trayectorias de
   cruce se redefinen con amplitud propia (`-m`) acotada a 0-65vw/0-75vh
   (en vez de reusar los keyframes de escritorio, que llegan a ~80vw/80vh)
   para que los 3 líquidos se posicionen bajo/entre las tarjetas de
   Dashboard y Equipos en pantalla vertical sin salirse del área útil. */
@media (max-width: 640px) {
  .tm-aurora-orb { filter: blur(55px); }
  .tm-aurora-amber-1 {
    width: 280px; height: 280px; min-width: 0; min-height: 0;
    top: 5vh; left: 5vw;
    opacity: 0.45;
    animation-name: tm-aurora-drift-amber-m;
  }
  .tm-aurora-cyan-1 {
    width: 260px; height: 260px; min-width: 0; min-height: 0;
    top: 68vh; left: 5vw;
    opacity: 0.45;
    animation-name: tm-aurora-drift-cyan-m;
  }
  .tm-aurora-blue-1 {
    width: 240px; height: 240px; min-width: 0; min-height: 0;
    top: 2vh; left: 35vw;
    opacity: 0.42;
    animation-name: tm-aurora-drift-blue-m;
  }
  @keyframes tm-aurora-drift-amber-m {
    0%   { transform: translate3d(0, 0, 0) scale(0.95) rotate(0deg); border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
    25%  { transform: translate3d(45vw, 55vh, 0) scale(1.15) rotate(90deg); border-radius: 40% 60% 70% 30% / 50% 60% 30% 60%; }
    50%  { transform: translate3d(50vw, 8vh, 0) scale(0.85) rotate(180deg); border-radius: 70% 30% 50% 50% / 30% 70% 40% 60%; }
    75%  { transform: translate3d(25vw, 30vh, 0) scale(1.2) rotate(270deg); border-radius: 45% 55% 65% 35% / 55% 45% 55% 45%; }
    100% { transform: translate3d(0, 0, 0) scale(1) rotate(360deg); border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
  }
  @keyframes tm-aurora-drift-cyan-m {
    0%   { transform: translate3d(0, 0, 0) scale(1) rotate(0deg); border-radius: 40% 60% 70% 30% / 50% 60% 30% 60%; }
    25%  { transform: translate3d(40vw, -55vh, 0) scale(1.1) rotate(-90deg); border-radius: 70% 30% 50% 50% / 30% 70% 40% 60%; }
    50%  { transform: translate3d(45vw, -8vh, 0) scale(0.9) rotate(-180deg); border-radius: 45% 55% 65% 35% / 55% 45% 55% 45%; }
    75%  { transform: translate3d(5vw, -12vh, 0) scale(1.15) rotate(-270deg); border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
    100% { transform: translate3d(0, 0, 0) scale(1) rotate(-360deg); border-radius: 40% 60% 70% 30% / 50% 60% 30% 60%; }
  }
  @keyframes tm-aurora-drift-blue-m {
    0%   { transform: translate3d(0, 0, 0) scale(1.05) rotate(0deg); border-radius: 70% 30% 50% 50% / 30% 70% 40% 60%; }
    25%  { transform: translate3d(-30vw, 55vh, 0) scale(0.85) rotate(120deg); border-radius: 45% 55% 65% 35% / 55% 45% 55% 45%; }
    50%  { transform: translate3d(10vw, 12vh, 0) scale(1.2) rotate(240deg); border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
    75%  { transform: translate3d(-15vw, 30vh, 0) scale(0.9) rotate(300deg); border-radius: 40% 60% 70% 30% / 50% 60% 30% 60%; }
    100% { transform: translate3d(0, 0, 0) scale(1) rotate(360deg); border-radius: 70% 30% 50% 50% / 30% 70% 40% 60%; }
  }
}

/* Contenedor real de la app: por encima del aurora (z-0), para que el
   fondo se vea únicamente detrás/entre tarjetas y contenido transparente. */
#app-shell { position: relative; z-index: 1; }

/* ---------- Scroll táctil ---------- */
.overflow-x-auto, .overflow-y-auto {
  -webkit-overflow-scrolling: touch;
}
.tm-no-scrollbar { scrollbar-width: none; -ms-overflow-style: none; }
.tm-no-scrollbar::-webkit-scrollbar { display: none; }

/* ---------- Topbar: safe-area para notch (iPhone) ---------- */
.tm-topbar {
  padding-top: calc(0.5rem + env(safe-area-inset-top));
  height: auto;
  min-height: 4rem;
  /* El `backdrop-blur` de esta clase ya genera un stacking context propio
     (backdrop-filter != none lo crea aunque el elemento no esté
     posicionado), lo que atrapaba el z-index:60 de #notif-panel dentro de
     ese contexto interno del topbar — solo competía con sus hermanos
     dentro del header, nunca con el banner de seguro (position:relative,
     z-index:auto) que vive fuera del header y pinta por delante de un
     bloque no posicionado. Fijar position+z-index aquí saca al topbar
     completo (con su dropdown) a competir por z-index en el stacking
     context de #app-shell, por delante del banner y el resto del
     contenido — igual que #app-shell ya usa z-index:1 para separarse del
     aurora de fondo. */
  position: relative;
  z-index: 20;
}

/* ---------- Notched corner: firma visual del sistema ---------- */
.tm-notch {
  clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%);
}
.tm-notch-sm {
  clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 9px, 100% 100%, 0 100%);
}

/* ---------- Sidebar nav links: cápsula metálica + LED lateral en el activo ---------- */
.tm-nav-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  padding: 0.55rem 0.75rem;
  border-radius: 9999px;
  font-size: 0.875rem;
  font-weight: 500;
  color: #9aabc2;
  border: 1px solid transparent;
  transition: color 150ms ease, background-color 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
  text-align: left;
}
.tm-nav-link:hover { color: #e7edf5; background-color: rgba(255,255,255,0.05); }
.tm-nav-link:hover .tm-nav-icon { filter: drop-shadow(0 0 4px rgba(245,158,11,0.55)); }
.tm-nav-link[aria-current="page"] {
  color: #fbbf24;
  background: linear-gradient(90deg, rgba(245,158,11,0.22), rgba(245,158,11,0.04));
  border-color: rgba(245,158,11,0.45);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0 0 16px rgba(245,158,11,0.22);
}
.tm-nav-link[aria-current="page"]::before {
  content: '';
  position: absolute;
  left: -0.7rem;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 62%;
  border-radius: 4px;
  background: linear-gradient(180deg, #fde68a, #f59e0b);
  box-shadow: 0 0 9px 2px rgba(245,158,11,0.85);
}
.tm-nav-link[aria-current="page"] .tm-nav-icon { filter: drop-shadow(0 0 5px rgba(245,158,11,0.7)); }
.tm-nav-icon { width: 18px; height: 18px; flex-shrink: 0; transition: filter 150ms ease; }

/* ---------- Mobile horizontal tab strip ---------- */
.tm-tab-chip {
  font-family: "IBM Plex Sans", sans-serif;
  font-size: 0.78rem;
  font-weight: 600;
  color: #9aabc2;
  padding: 0.5rem 0.9rem;
  border-radius: 0.5rem;
  background: linear-gradient(180deg, #29334580 0%, #1c2432 100%);
  border: 1px solid rgba(255,255,255,0.06);
  transition: color 150ms ease, background-color 150ms ease, border-color 150ms ease, transform 120ms ease;
}
.tm-tab-chip:active { transform: translateY(1px) scale(0.98); }
.tm-tab-chip[aria-current="page"] {
  color: #181f2a;
  background: linear-gradient(180deg, #fbbf24 0%, #d97706 100%);
  border-color: rgba(255,255,255,0.3);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), 0 2px 6px -1px rgba(0,0,0,0.4);
}

/* ---------- Cards: superficie de titanio pulido con relieve + luz viva ----------
   position:relative + overflow:hidden habilitan el barrido de luz (::after)
   y el anillo "beam" (.tm-card-beam::before) sin desbordar el layout. Las
   tarjetas que necesitan scroll horizontal (tablas) combinan la clase
   `.overflow-x-auto` de Tailwind — la regla de abajo (0,2,0 de
   especificidad) le gana a `.tm-card` (0,1,0) sin importar el orden real
   en que el CDN de Tailwind inyecte su <style>, así el scroll de tablas
   sigue funcionando igual que antes. */
.tm-card {
  position: relative;
  overflow: hidden;
  background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 0.6rem;
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.14),
    0 10px 30px -10px rgba(0,0,0,0.8),
    0 0 15px rgba(245,158,11,0.08);
  transition: transform 220ms cubic-bezier(0.4,0,0.2,1), box-shadow 220ms cubic-bezier(0.4,0,0.2,1), border-color 220ms ease;
  will-change: transform;
}
.tm-card.overflow-x-auto { overflow-x: auto; overflow-y: hidden; }
.tm-card:hover:not(.tm-modal-panel) {
  transform: translate3d(0, -3px, 0) scale(1.004);
  border-color: rgba(245,158,11,0.32);
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.18),
    0 18px 40px -10px rgba(0,0,0,0.85),
    0 0 22px rgba(245,158,11,0.22);
}
.tm-card-header {
  border-bottom: 1px solid rgba(255,255,255,0.08);
  background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0) 60%);
}

/* En móvil el gradiente opaco de .tm-card tapaba por completo el aurora
   mesh que pasa detrás/entre tarjetas (donde más se necesita presencia
   visual, según CLAUDE.md). Se cambia a un panel semi-traslúcido con
   glassmorphism (mismo tono que graphite-950 en rgba + blur) para que las
   luces ámbar/cian/azul se proyecten suavizadas a través de la tarjeta
   sin sacrificar legibilidad del texto (blur 12px difumina el color, no
   lo deja pasar nítido). Solo aplica bajo 640px — en desktop se conserva
   la superficie opaca de titanio de la regla 1 de CLAUDE.md. */
@media (max-width: 640px) {
  .tm-card {
    background: rgba(24, 31, 42, 0.78);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
  }
}

/* Light Sweep: haz de luz translúcido a 45° que cruza la tarjeta al pasar
   el cursor. Automático por selector CSS sobre .tm-card — Equipos,
   Trabajos, Métricas y cualquier tarjeta nueva lo heredan sin clase extra. */
.tm-card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(115deg, transparent 40%, rgba(255,255,255,0.14) 50%, transparent 60%);
  transform: translateX(-120%);
  pointer-events: none;
}
.tm-card:hover:not(.tm-modal-panel)::after {
  transform: translateX(120%);
  transition: transform 650ms cubic-bezier(0.4,0,0.2,1);
}

/* ---------- Border-Beam: anillo shimmer animado (tarjetas KPI + banner de seguro) ----------
   conic-gradient rotando sobre --tm-beam-angle, recortado a un anillo de
   2px con mask-composite:exclude (sin tocar el box-shadow del elemento,
   a diferencia de clip-path). --tm-beam-color permite tintar el anillo
   por estado (ver dashboard.js). */
.tm-card-beam {
  position: relative;
}
.tm-card-beam::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  padding: 2px;
  background: conic-gradient(
    from var(--tm-beam-angle),
    transparent 0deg, transparent 250deg,
    color-mix(in srgb, var(--tm-beam-color, #f59e0b) 45%, white) 292deg,
    var(--tm-beam-color, #f59e0b) 312deg,
    color-mix(in srgb, var(--tm-beam-color, #f59e0b) 45%, white) 332deg,
    transparent 360deg
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  animation: tm-beam-spin 4.5s linear infinite;
  pointer-events: none;
  will-change: transform;
}
@keyframes tm-beam-spin {
  to { --tm-beam-angle: 360deg; }
}

/* ---------- Notificaciones: popover con fondo sólido y posicionamiento
   responsive ----------
   En móvil (<640px) se ancla `fixed` bajo el topbar (respetando el
   safe-area del notch) como panel flotante centrado y acotado en ancho
   (`left`/`right` en vez de un `width` fijo con offset absoluto, que se
   salía del viewport en pantallas angostas tipo iPhone 16 Pro), con
   altura máxima y scroll interno propio para no empujar el layout si hay
   muchas notificaciones. Desde `sm:` vuelve a comportarse como dropdown
   anclado al botón campana. El fondo sólido (sin canal alpha) y el
   z-index elevado evitan que el banner de seguro (u otro contenido de
   fondo) se transparente a través del panel — bug reportado en móvil,
   donde el `backdrop-blur` del topbar dejaba ver el texto del banner
   detrás. Selector por id (especificidad 1,0,0) para ganar de forma
   determinista sobre `.tm-card` (0,1,0) sin depender del orden en que el
   CDN de Tailwind inyecta su propio `<style>` (mismo motivo que la regla
   `.tm-card.overflow-x-auto` de más arriba). */
#notif-panel {
  position: fixed;
  left: 0.75rem;
  right: 0.75rem;
  top: calc(4rem + env(safe-area-inset-top) + 0.5rem);
  width: auto;
  max-width: none;
  max-height: 75vh;
  overflow-y: auto;
  background-color: #0f172a;
  border: 1px solid rgba(255, 255, 255, 0.15);
  box-shadow: 0 20px 40px -5px rgba(0, 0, 0, 0.9), 0 0 15px rgba(245, 158, 11, 0.2);
  z-index: 60;
}
@media (min-width: 640px) {
  #notif-panel {
    position: absolute;
    left: auto;
    right: 0;
    top: 100%;
    margin-top: 0.5rem;
    width: 24rem;
    max-height: none;
    overflow-y: hidden;
  }
}

/* ---------- Instrument-style KPI label ---------- */
.tm-gauge-label {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.68rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: #7c8ba5;
}

/* ---------- Chromed/platinum heading text ----------
   Excluye .text-3xl/.text-2xl: son los valores grandes de KPI, que llevan
   su propio color de acento semántico (verde/rojo/ámbar/cian) y no deben
   perder ese significado bajo el gradiente cromado. */
.font-display.font-bold:not(.text-3xl):not(.text-2xl) {
  background: linear-gradient(180deg, #ffffff 0%, #cbd5e1 55%, #94a3b8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: #e7edf5;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.45));
}

/* ---------- Status dots: estilo LED de cabina ---------- */
.tm-dot { display: inline-block; width: 8px; height: 8px; border-radius: 9999px; flex-shrink: 0; box-shadow: inset 0 -1px 1px rgba(0,0,0,0.35), inset 0 1px 1px rgba(255,255,255,0.5); }
.tm-dot-green { background-color: #4ade80; box-shadow: inset 0 -1px 1px rgba(0,0,0,0.3), inset 0 1px 1px rgba(255,255,255,0.6), 0 0 7px 1px rgba(74,222,128,0.7); }
.tm-dot-amber { background-color: #f59e0b; box-shadow: inset 0 -1px 1px rgba(0,0,0,0.3), inset 0 1px 1px rgba(255,255,255,0.6), 0 0 7px 1px rgba(245,158,11,0.7); }
.tm-dot-sky   { background-color: #38bdf8; box-shadow: inset 0 -1px 1px rgba(0,0,0,0.3), inset 0 1px 1px rgba(255,255,255,0.6), 0 0 7px 1px rgba(56,189,248,0.65); }
.tm-dot-slate { background-color: #64748b; }
.tm-dot-red   { background-color: #ef4444; box-shadow: inset 0 -1px 1px rgba(0,0,0,0.3), inset 0 1px 1px rgba(255,255,255,0.6), 0 0 7px 1px rgba(239,68,68,0.7); }

/* ---------- Hazard stripes: reservado al banner crítico de seguro ---------- */
.tm-hazard {
  background-image: repeating-linear-gradient(
    135deg,
    #d97706 0px, #d97706 16px,
    #181f2a 16px, #181f2a 32px
  );
}
.tm-hazard-pulse { animation: tm-hazard-pulse 1.6s ease-in-out infinite; }
@keyframes tm-hazard-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

/* ---------- Toggle switch (Activo/Inactivo) ---------- */
.tm-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 42px;
  height: 24px;
  border-radius: 9999px;
  background: linear-gradient(180deg, #1a2029, #232c3a);
  border: 1px solid rgba(255,255,255,0.1);
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.5);
  cursor: pointer;
  transition: background-color 180ms ease, border-color 180ms ease;
  flex-shrink: 0;
}
.tm-switch[aria-checked="true"] {
  background: linear-gradient(180deg, #6ee7a0, #34c765);
  border-color: rgba(255,255,255,0.25);
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.25);
}
.tm-switch-knob {
  position: absolute;
  top: 1px;
  left: 1px;
  width: 18px;
  height: 18px;
  border-radius: 9999px;
  background: linear-gradient(180deg, #f4f6f9, #cbd5e1);
  box-shadow: 0 1px 3px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.6);
  transition: transform 180ms cubic-bezier(0.4,0,0.2,1);
}
.tm-switch[aria-checked="true"] .tm-switch-knob {
  transform: translateX(18px);
  background: linear-gradient(180deg, #ffffff, #dfe7ee);
}

/* ---------- Tabs (bitácora de servicio) ---------- */
.tm-tab {
  padding: 0.55rem 1rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: #9aabc2;
  border-bottom: 2px solid transparent;
  transition: color 150ms ease, border-color 150ms ease;
}
.tm-tab[aria-selected="true"] { color: #fbbf24; border-bottom-color: #f59e0b; }
.tm-tab:hover { color: #e7edf5; }

/* ---------- Repuestos (reparaciones) ---------- */
/* En móvil cada fila de repuesto se distingue con tarjeta propia porque el
   grid de 12 columnas colapsa a 2; en sm+ vuelve a ser una fila plana. */
.tm-pieza-row {
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 0.5rem;
  padding: 0.75rem;
}
@media (min-width: 640px) {
  .tm-pieza-row {
    border: 0;
    border-radius: 0;
    padding: 0;
    background: transparent;
  }
}

/* ---------- Modal ---------- */
.tm-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  background-color: rgba(5, 8, 15, 0.72);
  backdrop-filter: blur(16px);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 4vh 1rem;
  overflow-y: auto;
  animation: tm-fade-in 160ms ease-out;
}
.tm-modal-panel {
  background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
  border: 1px solid rgba(245,158,11,0.3);
  border-radius: 0.6rem;
  width: 100%;
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.16),
    0 24px 48px -12px rgba(0,0,0,0.75),
    0 0 30px rgba(245,158,11,0.14);
  animation: tm-modal-in 180ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes tm-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes tm-modal-in {
  from { opacity: 0; transform: translateY(10px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

/* Bottom-sheet en móvil: viewport mínimo iPhone 16 Pro (390–402px) */
@media (max-width: 640px) {
  .tm-modal-overlay {
    align-items: flex-end;
    padding: 0;
  }
  .tm-modal-panel {
    border-radius: 1rem 1rem 0 0;
    max-height: 92dvh;
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    animation: tm-sheet-in 220ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .tm-modal-panel [data-modal-body] {
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .tm-modal-panel [data-modal-footer] {
    position: sticky;
    bottom: 0;
    background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
    padding-bottom: calc(1rem + env(safe-area-inset-bottom));
    flex-shrink: 0;
  }
  @keyframes tm-sheet-in {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
  }
}

/* ---------- Form controls ---------- */
.tm-label {
  display: block;
  font-size: 0.78rem;
  font-weight: 500;
  color: #9aabc2;
  margin-bottom: 0.3rem;
}
.tm-input, .tm-select, .tm-textarea {
  width: 100%;
  background: linear-gradient(180deg, #171d28, #1b2230);
  border: 1px solid rgba(255,255,255,0.09);
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.45);
  border-radius: 0.4rem;
  padding: 0.5rem 0.7rem;
  font-size: 0.875rem;
  color: #e7edf5;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.tm-input:focus, .tm-select:focus, .tm-textarea:focus {
  border-color: #f59e0b;
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.45), 0 0 0 3px rgba(245,158,11,0.18);
  outline: none;
}
.tm-input::placeholder, .tm-textarea::placeholder { color: #5a6a84; }
.tm-input.tm-invalid, .tm-select.tm-invalid { border-color: #ef4444; }
.tm-error-text { font-size: 0.72rem; color: #f87171; margin-top: 0.25rem; }

/* ---------- Buttons ---------- */
/* Primario: bisel dorado + respiración de resplandor continua + reflejo
   diagonal recorriendo el botón cada 4s + compresión mecánica real al clic. */
.tm-btn-primary {
  position: relative;
  overflow: hidden;
  background: linear-gradient(180deg, #fbbf24 0%, #d97706 100%);
  color: #241704;
  font-weight: 700;
  padding: 0.55rem 1.1rem;
  font-size: 0.85rem;
  border-radius: 0.4rem;
  border: 1px solid rgba(255,255,255,0.2);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.45), 0 4px 0 #92400e, 0 8px 15px -3px rgba(0,0,0,0.45), 0 0 12px rgba(245,158,11,0.35);
  transform: translateY(0);
  transition: transform 120ms cubic-bezier(0.4,0,0.2,1), box-shadow 120ms cubic-bezier(0.4,0,0.2,1), filter 150ms ease;
  animation: tm-btn-breathe 2.6s ease-in-out infinite;
  will-change: transform;
}
.tm-btn-primary::after {
  content: '';
  position: absolute;
  top: 0;
  left: -75%;
  width: 45%;
  height: 100%;
  background: linear-gradient(115deg, transparent, rgba(255,255,255,0.65), transparent);
  transform: skewX(-20deg);
  animation: tm-btn-sweep 4s ease-in-out infinite;
  pointer-events: none;
}
@keyframes tm-btn-breathe {
  0%, 100% { box-shadow: inset 0 1px 0 rgba(255,255,255,0.45), 0 4px 0 #92400e, 0 8px 15px -3px rgba(0,0,0,0.45), 0 0 10px rgba(245,158,11,0.3); }
  50% { box-shadow: inset 0 1px 0 rgba(255,255,255,0.45), 0 4px 0 #92400e, 0 8px 15px -3px rgba(0,0,0,0.45), 0 0 22px rgba(245,158,11,0.6); }
}
@keyframes tm-btn-sweep {
  0% { left: -75%; }
  30%, 100% { left: 130%; }
}
.tm-btn-primary:hover { filter: brightness(1.08); }
.tm-btn-primary:active {
  transform: scale(0.97) translateY(2px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.3), 0 1px 0 #92400e, 0 2px 6px -2px rgba(0,0,0,0.4);
  animation-play-state: paused;
}
.tm-btn-primary:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
  animation: none;
}
.tm-btn-primary:disabled::after { animation: none; display: none; }

/* Secundario: cromo/acero, resplandor cian/platino al hover. */
.tm-btn-secondary {
  background: linear-gradient(180deg, #374151 0%, #1f2937 100%);
  border: 1px solid rgba(255,255,255,0.12);
  color: #dbe3ee;
  font-weight: 500;
  padding: 0.55rem 1.1rem;
  font-size: 0.85rem;
  border-radius: 0.4rem;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.12), 0 3px 0 #0f1520, 0 6px 12px -4px rgba(0,0,0,0.4);
  transform: translateY(0);
  transition: transform 120ms cubic-bezier(0.4,0,0.2,1), box-shadow 150ms cubic-bezier(0.4,0,0.2,1), border-color 150ms ease, color 150ms ease;
}
.tm-btn-secondary:hover {
  border-color: rgba(56,189,248,0.55);
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.14), 0 3px 0 #0f1520, 0 6px 12px -4px rgba(0,0,0,0.4), 0 0 14px rgba(56,189,248,0.35);
}
.tm-btn-secondary:active {
  transform: translateY(2px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 1px 0 #0f1520, 0 2px 6px -2px rgba(0,0,0,0.35);
}

/* ---------- Toast ---------- */
.tm-toast {
  pointer-events: auto;
  min-width: 240px;
  max-width: 340px;
  background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
  border: 1px solid rgba(255,255,255,0.1);
  border-left: 3px solid #f59e0b;
  border-radius: 0.4rem;
  padding: 0.7rem 0.9rem;
  font-size: 0.82rem;
  color: #e7edf5;
  box-shadow: inset 0 1px 1px rgba(255,255,255,0.1), 0 12px 28px -8px rgba(0,0,0,0.6);
  animation: tm-toast-in 180ms cubic-bezier(0.16, 1, 0.3, 1);
}
.tm-toast[data-kind="success"] { border-left-color: #4ade80; }
.tm-toast[data-kind="error"] { border-left-color: #ef4444; }
@keyframes tm-toast-in {
  from { opacity: 0; transform: translateX(12px); }
  to { opacity: 1; transform: translateX(0); }
}

/* ---------- Truck-code badge ---------- */
.tm-code-badge {
  font-family: "IBM Plex Mono", monospace;
  font-weight: 600;
  letter-spacing: 0.02em;
  font-size: 0.78rem;
  color: #fbbf24;
  background: linear-gradient(180deg, rgba(245,158,11,0.16), rgba(245,158,11,0.06));
  border: 1px solid rgba(245, 158, 11, 0.4);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.12);
  padding: 0.1rem 0.45rem;
  border-radius: 0.25rem;
}

table.tm-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
/* ---------- Checklist de inspección (bitácora preventiva) ---------- */
.tm-checkbox {
  appearance: none;
  -webkit-appearance: none;
  width: 17px;
  height: 17px;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 0.25rem;
  background: linear-gradient(180deg, #171d28, #1f2735);
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.4);
  cursor: pointer;
  position: relative;
  flex-shrink: 0;
  transition: background-color 150ms ease, border-color 150ms ease;
}
.tm-checkbox:hover { border-color: #7c8ba5; }
.tm-checkbox:checked {
  background: linear-gradient(180deg, #fbbf24, #d97706);
  border-color: rgba(255,255,255,0.3);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
}
.tm-checkbox:checked::after {
  content: '';
  position: absolute;
  left: 5px;
  top: 2px;
  width: 4px;
  height: 8px;
  border: solid #241704;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* ---------- Desglose de reparación (fila expandible) ---------- */
.tm-desglose-row td {
  background-color: #171d28;
  padding: 0.75rem 0.85rem 0.9rem;
}

table.tm-table th {
  text-align: left;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #7c8ba5;
  font-weight: 600;
  padding: 0.6rem 0.85rem;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  white-space: nowrap;
}
table.tm-table td {
  padding: 0.65rem 0.85rem;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  vertical-align: middle;
}
table.tm-table tbody tr { transition: background-color 150ms ease; }
table.tm-table tbody tr:hover { background-color: rgba(255,255,255,0.04); }
table.tm-table tbody tr:last-child td { border-bottom: none; }
