@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap');

.material-symbols-outlined {
  font-variation-settings:
    'FILL' 0,
    'wght' 400,
    'GRAD' 0,
    'opsz' 20;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  line-height: 1;
  font-size: 1.25rem;
  user-select: none;
}

:root {
  --bg-dark: #f4f7fa; /* Premium Light Blue Slate */
  --bg-card: rgba(255, 255, 255, 0.85);
  --bg-card-hover: rgba(255, 255, 255, 0.98);
  --border-color: rgba(15, 61, 100, 0.08);
  --border-color-active: rgba(78, 166, 224, 0.5);
  
  --primary: #0f3d64; /* Digitaldocu Corporate Deep Blue */
  --primary-glow: rgba(15, 61, 100, 0.08);
  --accent-cyan: #4ea6e0; /* Digitaldocu Sky Blue */
  --accent-purple: #0077b6; /* Premium brand sky blue/tech blue accent */
  
  --text-main: #0f2d4a; /* Deep Slate/Charcoal Blue Text */
  --text-muted: #5a738e; /* Mid Slate Blue Text */
  --text-inverse: #ffffff;
  
  --success: #10b981; /* Premium Emerald Teal */
  --error: #ef4444;
  --warning: #f59e0b;
  
  --shadow-sm: 0 1px 3px rgba(15, 61, 100, 0.04);
  --shadow-md: 0 4px 20px rgba(15, 61, 100, 0.05);
  --shadow-lg: 0 10px 30px rgba(15, 61, 100, 0.08);
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font-family: 'Roboto', sans-serif;
  scrollbar-width: thin;
  scrollbar-color: rgba(15, 61, 100, 0.1) transparent;
}

body {
  background-color: var(--bg-dark);
  color: var(--text-main);
  min-height: 100vh;
  overflow-x: hidden;
  position: relative;
  background-image: 
    radial-gradient(circle at 10% 20%, rgba(78, 166, 224, 0.03) 0%, transparent 40%),
    radial-gradient(circle at 90% 80%, rgba(15, 61, 100, 0.03) 0%, transparent 45%);
  background-attachment: fixed;
}

/* Background Animated Glows (highly diluted for light mode) */
.bg-glow-1 {
  position: fixed;
  top: -10%;
  left: 20%;
  width: 400px;
  height: 400px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(78, 166, 224, 0.04) 0%, transparent 70%);
  filter: blur(40px);
  z-index: -1;
  pointer-events: none;
}

.bg-glow-2 {
  position: fixed;
  bottom: 0%;
  right: 15%;
  width: 500px;
  height: 500px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(15, 61, 100, 0.03) 0%, transparent 70%);
  filter: blur(50px);
  z-index: -1;
  pointer-events: none;
}

/* AVISOS PUSH: fuera en la app nativa.
   No hay plugin de notificaciones ni Firebase, así que el botón solo sirve para
   contestar «en la app nativa los avisos llegan por otro canal» (index.js:4778).
   Ofrecer un campo y un botón para luego decir que no va es una promesa rota, y
   encima es lo primero que se ve al entrar en Expediciones. En web sigue igual:
   la clase la pone native-config.js, que NO se carga en la web. */
html.deca-native #dca-push-box { display: none !important; }

/* Layout container */
#app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* Respeta notch/Dynamic Island y home indicator en la app nativa (iOS/Android).
     En web los insets valen 0 → sin efecto. Requiere viewport-fit=cover. */
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  /* Y los LADOS: en horizontal, con muesca o barra de gestos, sin esto el
     contenido se mete debajo. En vertical valen 0 y no cambia nada. */
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

/* Botones de acción del documento DeCA: SOLO-ICONO + tooltip al pasar por encima
   (web Y app nativa; antes solo nativa). La leyenda se colapsa; el icono queda grande.
   OJO AL AÑADIR UN BOTÓN NUEVO A ESTA FILA: si su clase no está aquí, sale con
   texto y rompe la hilera de cuadrados. Pasó con «Recoger mercancía» y
   «Expediente». Hay un test que lo vigila (tests/iconos-fila.test.mjs). */
.dca-view-pdf-btn,
.dca-qr-btn,
.dca-new-version-btn,
.dca-sign-delivery-btn,
.dca-pickup-btn,
.dca-insp-ini-btn,
.dca-insp-fin-btn,
.dca-expediente-btn,
.dca-revocar-btn,
.dca-delete-btn {
  font-size: 0 !important;   /* colapsa la leyenda (nodo de texto suelto) */
  gap: 0 !important;
  /* MISMO "palo" para los 4: cuadrado icon-only, fondo blanco, borde e icono
     primarios. Sobrescribe con !important los estilos inline divergentes
     (btn-primary azul, var(--success) verde, borde primario, etc.). */
  width: 40px !important;
  height: 40px !important;
  padding: 0 !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  background: #fff !important;
  background-image: none !important;
  border: 1.5px solid var(--border-color) !important;
  border-radius: 12px !important;
  color: var(--primary) !important;
  box-shadow: none !important;
  position: relative;
  transition: background .14s ease, border-color .14s ease, transform .14s ease;
}
.dca-view-pdf-btn:hover,
.dca-qr-btn:hover,
.dca-new-version-btn:hover,
.dca-sign-delivery-btn:hover,
.dca-pickup-btn:hover,
.dca-insp-ini-btn:hover,
.dca-insp-fin-btn:hover,
.dca-expediente-btn:hover {
  background: var(--primary-glow) !important;
  border-color: var(--primary) !important;
  transform: translateY(-1px);
}
/* Eliminar: mismo cuadrado que los demás EN REPOSO —la fila tiene que leerse
   homogénea— y rojo solo al posarse encima, que es el instante en que importa
   saber que esto no se deshace. Hay confirmación detrás, pero el color es lo que
   frena el clic de más. */
.dca-delete-btn:hover {
  background: rgba(239, 68, 68, .08) !important;
  border-color: var(--error) !important;
  transform: translateY(-1px);
}
.dca-delete-btn:hover .material-symbols-outlined { color: var(--error) !important; }
/* INSPECCIÓN DE VEHÍCULO: el mismo coche en dos colores, para que el chófer
   distinga de un vistazo la recogida (verde: empieza) de la entrega (rojo:
   termina). Pedido por Luis el 8-sep. Va después de la regla solo-icono y con
   la misma fuerza, que es lo que la hace ganar. */
/* El coche de la RECOGIDA no es verde mientras está pendiente: el verde
   significa «hecha» y lo lleva el distintivo que sale al cerrarla (Luis,
   9-sep-2026). Pendiente = azul, como el resto de acciones. */
.dca-doc-actions .dca-insp-ini-btn .material-symbols-outlined { color: var(--primary) !important; }
.dca-doc-actions .dca-pickup-done .material-symbols-outlined { color: var(--success) !important; }
.dca-doc-actions .dca-insp-fin-btn .material-symbols-outlined { color: var(--error) !important; }
.dca-doc-actions .dca-insp-ini-btn:hover { background: var(--primary-glow) !important; border-color: var(--primary) !important; }
.dca-doc-actions .dca-insp-fin-btn:hover { background: rgba(239, 68, 68, .08) !important; border-color: var(--error) !important; }
.dca-view-pdf-btn .material-symbols-outlined,
.dca-qr-btn .material-symbols-outlined,
.dca-new-version-btn .material-symbols-outlined,
.dca-sign-delivery-btn .material-symbols-outlined,
.dca-pickup-btn .material-symbols-outlined,
.dca-insp-ini-btn .material-symbols-outlined,
.dca-insp-fin-btn .material-symbols-outlined,
.dca-expediente-btn .material-symbols-outlined,
.dca-delete-btn .material-symbols-outlined {
  font-size: 1.3rem !important;   /* icono al quedarse solo */
  color: var(--primary) !important;   /* mismo color en los 4 (mata el white inline) */
}
/* Tooltip propio (usa el aria-label del botón), no el del navegador. */
.dca-doc-actions button[aria-label]::after {
  content: attr(aria-label);
  position: absolute; bottom: calc(100% + 9px); left: 50%;
  transform: translateX(-50%) translateY(4px);
  background: var(--text-main); color: #fff;
  font-size: 0.72rem; font-weight: 600; letter-spacing: .2px; line-height: 1;
  padding: 6px 10px; border-radius: 8px; white-space: nowrap;
  opacity: 0; pointer-events: none; z-index: 60;
  box-shadow: 0 6px 18px rgba(15, 45, 74, .22);
  transition: opacity .14s ease, transform .14s ease;
}
.dca-doc-actions button[aria-label]::before {
  content: ""; position: absolute; bottom: calc(100% + 4px); left: 50%;
  transform: translateX(-50%); border: 5px solid transparent;
  border-top-color: var(--text-main); opacity: 0; pointer-events: none; z-index: 60;
  transition: opacity .14s ease;
}
.dca-doc-actions button[aria-label]:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); }
.dca-doc-actions button[aria-label]:hover::before { opacity: 1; }

/* Login screen styles */
.login-container {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
}

/* Móviles estrechos (~320-380px). La login-card gasta 40px de padding por lado y
   dejaba ~200px útiles: el logo (271px de ancho a 50px de alto) NO cabía y, como la
   card tiene overflow:hidden, salía RECORTADO (se comía la "u" de Digitaldocu).
   Aquí le damos aire; el <img> además lleva max-width:100% para escalar solo.
   Corte en 380px a propósito: los iPhone (>=390px) ya caben y se quedan IGUAL. */
@media (max-width: 380px) {
  .login-container { padding: 12px; }
  .login-card { padding: 28px 20px; }
}

.login-card {
  background: var(--bg-card);
  backdrop-filter: blur(20px);
  border: 1px solid var(--border-color);
  padding: 40px;
  border-radius: 24px;
  width: 100%;
  max-width: 480px;
  box-shadow: var(--shadow-lg);
  position: relative;
  overflow: hidden;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.login-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 20px 40px rgba(15, 23, 42, 0.12), 0 0 30px rgba(99, 102, 241, 0.05);
  border-color: rgba(15, 23, 42, 0.15);
}

.login-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background: linear-gradient(90deg, var(--primary), var(--accent-cyan));
}

.logo-header {
  text-align: center;
  margin-bottom: 30px;
}

.logo-header h1 {
  font-size: 2.2rem;
  font-weight: 800;
  background: linear-gradient(135deg, var(--primary) 30%, var(--accent-cyan) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  margin-bottom: 8px;
  letter-spacing: -0.5px;
}

.logo-header p {
  color: var(--text-muted);
  font-size: 0.95rem;
}

.form-group {
  margin-bottom: 20px;
}

.form-group label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  margin-bottom: 8px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.input-wrapper {
  position: relative;
}

.input-wrapper input {
  width: 100%;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid var(--border-color);
  background: rgba(255, 255, 255, 0.8);
  color: var(--text-main);
  font-size: 0.95rem;
  outline: none;
  transition: all 0.25s ease;
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.02);
}

.input-wrapper input:focus {
  border-color: var(--primary);
  background: #ffffff;
  box-shadow: 0 0 0 4px var(--primary-glow), inset 0 1px 2px rgba(15, 23, 42, 0.02);
}

.credential-tip {
  margin-top: 6px;
  font-size: 0.75rem;
  color: var(--accent-cyan);
  display: flex;
  align-items: center;
  gap: 4px;
  font-weight: 500;
}

.btn-primary {
  width: 100%;
  padding: 14px;
  border-radius: 12px;
  border: none;
  background: linear-gradient(90deg, var(--primary), var(--accent-cyan));
  color: var(--text-inverse);
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.25s ease;
  box-shadow: 0 4px 12px rgba(15, 61, 100, 0.2);
  margin-top: 10px;
}

.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(79, 70, 229, 0.35);
  opacity: 0.95;
}

.btn-primary:active {
  transform: translateY(1px);
}

.btn-primary:disabled {
  background: var(--text-muted);
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
  opacity: 0.5;
}

/* ── Las tres rayas ────────────────────────────────────────────────────────
   Solo existen en móvil. Por debajo de 768px la barra lateral se convierte en
   una franja horizontal y el menú NO cabía: estaba puesto a display:none, así
   que desde un teléfono no había forma de llegar a Chóferes —su única entrada
   es esa lista—. Ahora el menú se despliega debajo de la franja. */
.nav-toggle {
  display: none;
  align-items: center; justify-content: center;
  width: 42px; height: 42px; flex: none;
  border: 1px solid var(--border-color); border-radius: 12px;
  background: var(--bg-card, #fff); color: var(--text-main); cursor: pointer;
  transition: background .15s;
}
.nav-toggle:hover { background: rgba(15, 23, 42, 0.04); }
.nav-toggle .material-symbols-outlined { font-size: 1.5rem; }
/* Los dos iconos viven en el HTML y se turnan por CSS. Escribirlos ahí y no
   desde JS es lo que hace que el barrido de scripts/icon-names.mjs los vea y
   entren en la fuente subsetada; asignados por código se quedarían fuera y
   saldría la palabra «menu» escrita en pantalla. */
.nav-toggle .nav-toggle-cerrar { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle-abrir { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle-cerrar { display: inline-block; }

/* Dashboard screen styles */
.dashboard-layout {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  width: 280px;
  background: rgba(255, 255, 255, 0.85);
  border-right: 1px solid var(--border-color);
  backdrop-filter: blur(16px);
  padding: 30px 20px;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  z-index: 10;
  box-shadow: 2px 0 15px rgba(15, 23, 42, 0.02);
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 40px;
  padding: 0 10px;
}

/* Selector de idioma (bola del mundo + código). En desktop cuelga debajo del menú;
   en móvil pasa a la fila de la cabecera (ver media query, donde se anulan los
   márgenes verticales para que quede alineado con logo/logout/avatar). */
.sidebar-lang {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  margin-top: 14px;
}

.brand-dot {
  width: 12px;
  height: 12px;
  background: var(--primary);
  border-radius: 50%;
  box-shadow: 0 0 10px var(--primary);
  animation: pulse 2s infinite;
}

.sidebar-brand h2 {
  font-size: 1.3rem;
  font-weight: 750;
  background: linear-gradient(to right, #0f172a, #475569);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.nav-menu {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex-grow: 1;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border-radius: 12px;
  cursor: pointer;
  color: var(--text-muted);
  font-size: 0.95rem;
  font-weight: 600;
  transition: all 0.2s ease;
}

.nav-item:hover {
  background: rgba(15, 61, 100, 0.03);
  color: var(--text-main);
}

.nav-item.active {
  background: rgba(78, 166, 224, 0.08);
  color: var(--primary);
  border-left: 4px solid var(--accent-cyan);
}

.sidebar-user {
  margin-top: auto;
  border-top: 1px solid var(--border-color);
  padding-top: 20px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.user-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--primary), var(--accent-cyan));
  color: var(--text-inverse);
  display: flex;
  justify-content: center;
  align-items: center;
  font-weight: 700;
  font-size: 1.1rem;
  box-shadow: 0 0 12px rgba(15, 61, 100, 0.15);
  /* Es un botón: abre los ajustes de avisos. Sin borde ni tipografía heredada del
     user-agent, y con pista de que se puede pulsar. */
  border: none;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
  flex-shrink: 0;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.user-avatar:hover {
  transform: scale(1.06);
  box-shadow: 0 0 16px rgba(15, 61, 100, 0.3);
}

.user-avatar:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.user-info {
  display: flex;
  flex-direction: column;
  max-width: 170px;
}

.user-name {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--text-main);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-role {
  font-size: 0.75rem;
  color: var(--text-muted);
}

.btn-logout {
  background: none;
  border: none;
  color: var(--error);
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 600;
  margin-top: 4px;
  text-align: left;
  opacity: 0.8;
  transition: opacity 0.2s ease;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.btn-logout:hover {
  opacity: 1;
}

/* El icono de logout solo se muestra en móvil (en escritorio va el texto) */
.logout-icon {
  display: none;
}

/* Main Content Area */
.main-content {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow-y: auto;
  padding: 40px;
}

.content-header {
  margin-bottom: 30px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.content-header h1 {
  font-size: 1.8rem;
  font-weight: 800;
  letter-spacing: -0.5px;
  color: var(--text-main);
}

.content-header p {
  color: var(--text-muted);
  font-size: 0.95rem;
  margin-top: 4px;
}

/* Cabecera de Expediciones. Vivía en un style= dentro del HTML, y desde ahí no
   hay forma de que un @media la corrija: el inline gana siempre. Se saca aquí
   para poder apartarla de la franja superior en móvil. Doble clase para ganarle
   a .content-header sin depender de quién esté escrito antes. */
.content-header.exp-cabecera {
  position: sticky; top: calc(-40px + var(--deca-barra, 0px)); z-index: 90;
  margin: -40px 0 30px; padding: 40px 0 20px;
  background: rgba(248, 250, 252, 0.95);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--border-color);
  display: flex; justify-content: space-between; align-items: center;
}

.tab-pane {
  display: none;
  animation: fadeIn 0.35s ease forwards;
}

.tab-pane.active {
  display: block;
}

/* Dashboard Cards Grid */
.summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
  margin-bottom: 40px;
}

.summary-card {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 20px;
  padding: 24px;
  display: flex;
  align-items: center;
  gap: 20px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: var(--shadow-sm);
}

.summary-card:hover {
  transform: translateY(-4px);
  background: var(--bg-card-hover);
  border-color: var(--border-color-active);
  box-shadow: var(--shadow-md);
}

.card-icon {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.5rem;
}

.card-icon.blue {
  background: rgba(15, 61, 100, 0.1);
  color: var(--primary);
}

.card-icon.purple {
  background: rgba(0, 119, 182, 0.1);
  color: var(--accent-purple);
}

.card-icon.cyan {
  background: rgba(8, 145, 178, 0.1);
  color: var(--accent-cyan);
}

.card-details h3 {
  font-size: 0.85rem;
  text-transform: uppercase;
  color: var(--text-muted);
  letter-spacing: 0.5px;
  margin-bottom: 4px;
  font-weight: 700;
}

.card-details .value {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--text-main);
}

/* DMS Explorer Styles */
.explorer-container {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 30px;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 20px;
  min-height: 500px;
  backdrop-filter: blur(16px);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.explorer-tree {
  border-right: 1px solid var(--border-color);
  padding: 24px;
  background: rgba(255, 255, 255, 0.3);
}

.explorer-tree h3 {
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  margin-bottom: 16px;
  font-weight: 700;
}

.tree-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tree-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.95rem;
  color: var(--text-muted);
  font-weight: 500;
  transition: all 0.2s ease;
}

.tree-item:hover {
  background: rgba(15, 23, 42, 0.02);
  color: var(--text-main);
}

.tree-item.active {
  background: rgba(79, 70, 229, 0.08);
  color: var(--primary);
  font-weight: 700;
}

.explorer-content {
  padding: 24px;
  display: flex;
  flex-direction: column;
}

.content-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.breadcrumbs {
  font-size: 0.95rem;
  display: flex;
  align-items: center;
  gap: 6px;
}

.breadcrumbs span {
  color: var(--text-muted);
}

.breadcrumbs strong {
  color: var(--text-main);
  font-weight: 700;
}

.dms-table-container {
  flex-grow: 1;
  overflow-x: auto;
}

.dms-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}

.dms-table th {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-color);
  color: var(--text-muted);
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.dms-table td {
  padding: 14px 16px;
  border-bottom: 1px solid rgba(15, 23, 42, 0.03);
  font-size: 0.95rem;
  color: var(--text-main);
}

.dms-table tr:hover td {
  background: rgba(15, 23, 42, 0.01);
}

.file-name-cell {
  display: flex;
  align-items: center;
  gap: 12px;
  font-weight: 600;
  color: var(--text-main);
}

.file-icon {
  font-size: 1.2rem;
  color: var(--primary);
}

/* Upload & AI Scanner Area */
.uploader-box {
  border: 2px dashed rgba(79, 70, 229, 0.25);
  border-radius: 20px;
  padding: 40px;
  text-align: center;
  cursor: pointer;
  background: rgba(255, 255, 255, 0.4);
  transition: all 0.25s ease;
  position: relative;
  overflow: hidden;
  margin-bottom: 30px;
}

.uploader-box:hover {
  border-color: var(--primary);
  background: rgba(79, 70, 229, 0.02);
}

.uploader-box.dragover {
  border-color: var(--accent-cyan);
  background: rgba(8, 145, 178, 0.03);
}

.uploader-icon {
  font-size: 3rem;
  margin-bottom: 16px;
  display: inline-block;
  animation: float 3s ease-in-out infinite;
}

.uploader-box h3 {
  font-size: 1.15rem;
  font-weight: 700;
  margin-bottom: 8px;
}

.uploader-box p {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin-bottom: 16px;
}

.btn-file-select {
  display: inline-block;
  padding: 10px 24px;
  background: #ffffff;
  border: 1px solid var(--border-color);
  color: var(--text-main);
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  transition: all 0.2s ease;
  box-shadow: var(--shadow-sm);
}

.uploader-box:hover .btn-file-select {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--text-inverse);
}

/* Scanner Animation Overlay */
.scanner-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.95);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 5;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.uploader-box.scanning .scanner-overlay {
  opacity: 1;
  pointer-events: auto;
}

.scanner-line {
  position: absolute;
  width: 100%;
  height: 3px;
  background: linear-gradient(90deg, transparent, var(--primary), transparent);
  box-shadow: 0 0 15px var(--primary);
  top: 0;
  left: 0;
  animation: scan 2s linear infinite;
}

.scanner-text {
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.5px;
  margin-top: 15px;
  background: linear-gradient(90deg, #0f172a, var(--primary), #0f172a);
  background-size: 200% auto;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shine 2s linear infinite;
}

/* AI Data Results Display */
.ai-results-card {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 20px;
  padding: 30px;
  box-shadow: var(--shadow-sm);
  animation: slideUp 0.4s ease forwards;
}

.results-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--border-color);
  padding-bottom: 16px;
  margin-bottom: 20px;
}

.results-header h3 {
  font-size: 1.2rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 10px;
}

.badge-ai {
  padding: 4px 10px;
  border-radius: 20px;
  background: rgba(5, 150, 105, 0.1);
  color: var(--success);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.results-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 20px;
}

.result-field {
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  padding: 16px;
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.01);
  transition: all 0.2s ease;
}

.result-field:hover {
  border-color: var(--border-color-active);
  background: #ffffff;
}

.field-label {
  font-size: 0.75rem;
  color: var(--text-muted);
  text-transform: uppercase;
  font-weight: 700;
  margin-bottom: 4px;
}

.field-value {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text-main);
  word-break: break-all;
}

/* Custom Notifications */
.notification-toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  background: #ffffff;
  border: 1px solid var(--border-color);
  padding: 16px 24px;
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(15, 23, 42, 0.1);
  display: flex;
  align-items: center;
  gap: 12px;
  /* Por encima de los modales (.modal-overlay = 1000). Antes era 100 y quedaba
     OCULTO tras un modal abierto: los avisos de error en la firma de entrega no
     se veían ("no dice nada") porque el modal seguía abierto encima del toast. */
  z-index: 3000;
  transform: translateY(100px);
  opacity: 0;
  transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.notification-toast.show {
  transform: translateY(0);
  opacity: 1;
}

.toast-icon {
  font-size: 1.2rem;
  font-weight: 700;
}

.toast-icon.success { color: var(--success); }
.toast-icon.error { color: var(--error); }
.toast-icon.info { color: var(--primary); }

.toast-message {
  font-size: 0.95rem;
  font-weight: 600;
}

/* High Contrast DCA elements */
.dca-doc-card {
  background: #ffffff;
  border: 1px solid var(--border-color);
  border-radius: 16px;
  padding: 20px;
  display: flex;
  flex-wrap: wrap;   /* la documentación adjunta baja a su propia fila (ver abajo) */
  justify-content: space-between;
  align-items: center;
  box-shadow: var(--shadow-sm);
  transition: all 0.2s ease;
}

.dca-doc-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--border-color-active);
}

.dca-doc-details {
  display: flex;
  align-items: center;
  gap: 16px;
}

/* PLANTILLAS DE «GENERAR DeCA», en una sola fila: el desplegable manda y
   guardar/gestionar son dos iconos. Va en la hoja de estilos y NO en un
   atributo `style` del HTML a propósito: index.js hace `tpl-bar.style.display
   = ''` al volver al formulario, y eso borraba un `display:flex` inline —la
   barra se desmontaba en tres líneas apiladas (8-sep-2026). Desde aquí, ese
   mismo reinicio la devuelve a su sitio. */
#tpl-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 18px;
}
#tpl-bar #tpl-select {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--border-color);
  border-radius: 10px;
  background: #ffffff;
  font-size: 0.88rem;
  color: var(--text-main);
  outline: none;
}
.tpl-icon-btn {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1.5px solid var(--border-color);
  border-radius: 12px;
  background: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background .14s ease, border-color .14s ease, transform .14s ease;
}
.tpl-icon-btn .material-symbols-outlined { font-size: 1.3rem; color: var(--primary); }
.tpl-icon-btn:hover {
  background: var(--primary-glow);
  border-color: var(--primary);
  transform: translateY(-1px);
}

/* La documentación adjunta va SIEMPRE en su propia fila, debajo de
   [documento | iconos]: cuando aparece solo añade altura y no desplaza los
   iconos hacia la izquierda (era un tercer hijo de la fila «space-between»). */
.attached-docs-section { flex: 1 1 100%; }

.dca-doc-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  background: rgba(79, 70, 229, 0.08);
  color: var(--primary);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.4rem;
}

.dca-doc-text h4 {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text-main);
  margin-bottom: 2px;
}

.dca-doc-text p {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.dca-doc-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
}

.dca-doc-badge.signed {
  background: #ecfdf5;
  color: var(--success);
}

.dca-doc-actions {
  display: flex;
  gap: 10px;
}

/* Animations */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes slideUp {
  from { transform: translateY(20px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

@keyframes pulse {
  0% { transform: scale(1); box-shadow: 0 0 10px var(--primary); }
  50% { transform: scale(1.15); box-shadow: 0 0 20px var(--primary); }
  100% { transform: scale(1); box-shadow: 0 0 10px var(--primary); }
}

@keyframes float {
  0% { transform: translateY(0px); }
  50% { transform: translateY(-8px); }
  100% { transform: translateY(0px); }
}

@keyframes scan {
  0% { top: 0%; }
  50% { top: 100%; }
  100% { top: 0%; }
}

@keyframes shine {
  to { background-position: 200% center; }
}

/* Responsive adjustments */
@media (max-width: 1024px) {
  .explorer-container {
    grid-template-columns: 1fr;
  }
  .explorer-tree {
    border-right: none;
    border-bottom: 1px solid var(--border-color);
  }
}

@media (max-width: 768px) {
  .dashboard-layout {
    flex-direction: column;
  }
  /* Cabecera compacta en móvil: logo a la izquierda, usuario a la derecha */
  .sidebar {
    width: 100%;
    height: auto;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border-right: none;
    border-bottom: 1px solid var(--border-color);
    /* SIN env() aquí: el inset superior ya lo aplica #app (medido en iPhone 17 Pro:
       env=62px, #app=62px). Si se suma también aquí, la cabecera queda a 134px del
       borde y sobran ~62px de hueco sobre el logo. Una sola fuente: #app. */
    padding: 10px 16px;
  }
  /* En la cabecera-fila, los márgenes verticales pensados para el sidebar vertical
     DESCENTRAN los items: flex align-items:center centra la caja CON el margen.
     El !important es obligatorio aquí: .sidebar-brand lleva margin-bottom inline
     en el HTML y sin él gana el inline (por eso el logo salía más alto). */
  .sidebar-brand {
    margin-bottom: 0 !important;
    padding: 0;
    flex-shrink: 1;
    min-width: 0;
  }
  .sidebar-lang {
    margin-top: 0;
    padding: 0;
  }
  .sidebar-brand img {
    height: 24px !important; /* logo más pequeño en móvil para que quepa todo */
    width: auto;
  }
  .nav-toggle { display: inline-flex; order: -1; }
  /* La franja no se va con el scroll: es donde vive el botón del menú, y un menú
     al que hay que subir del todo para abrirlo no sirve de mucho. El desplegable
     cuelga de ella (position:absolute), así que además tiene que ser el marco.
     El tope va con env(): #app ya aparta el notch con su padding, y con top:0 la
     franja se colaría por debajo del reloj al desplazarse. En web env() vale 0. */
  /* Por encima de las cabeceras fijas del contenido, que llevan z-index 90.
     Con el 10 de escritorio, la de Expediciones se pintaba ENCIMA de la
     franja y se tragaba el logo y el botón del menú. */
  .sidebar { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 100; }
  .nav-menu {
    display: none;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; gap: 4px;
    background: #fff; border-bottom: 1px solid var(--border-color);
    padding: 10px 16px 14px; margin: 0;
    box-shadow: var(--shadow-lg); z-index: 30;
    max-height: calc(100vh - 90px); overflow-y: auto;
  }
  body.deca-nav-abierto .nav-menu { display: flex; }
  .sidebar-user {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
    flex-direction: row-reverse; /* avatar al borde derecho, datos a su izquierda */
    gap: 10px;
    flex-shrink: 0;
  }
  .user-avatar {
    width: 38px;
    height: 38px;
    font-size: 0.95rem;
  }
  .user-info {
    max-width: 55vw;
    align-items: flex-end;
    text-align: right;
  }
  /* En móvil basta con el avatar (iniciales) + un icono de logout */
  .user-name,
  .user-role,
  .logout-text {
    display: none;
  }
  .logout-icon {
    display: inline-flex;
    font-size: 1.5rem;
  }
  .btn-logout {
    margin-top: 0;
    padding: 6px;
    opacity: 1;
  }
  .main-content {
    padding: 20px;
    height: auto;
    overflow-y: visible;
  }
  /* TARJETA DE DOCUMENTO EN MÓVIL: la fila [detalles | botones] no cabe y los
     botones se apilaban en una columna cortada por la derecha (captura del
     iPhone, 8-sep-2026). Los botones bajan a su propia fila, a ancho completo. */
  .dca-doc-card { flex-wrap: wrap; row-gap: 12px; }
  .dca-doc-details { min-width: 0; flex: 1 1 100%; }
  .dca-doc-text { min-width: 0; }
  .dca-doc-text h5, .dca-doc-text p { overflow-wrap: anywhere; }
  .dca-doc-actions { flex: 1 1 100%; justify-content: flex-start; }
}

/* PANTALLAS ESTRECHAS: cada marco anidado (página, grupo de entregas, tarjeta)
   restaba 20+32+48 px y al título de la expedición le quedaban 151 px. Los
   paddings van inline desde index.js, por eso el !important. */
@media (max-width: 480px) {
  .main-content { padding: 12px !important; }
  .summary-card { padding: 16px !important; }
  .deca-grupo { padding: 8px !important; }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* Modal Overlay Styling for DCA Portal */
/* ── La caja de un diálogo ─────────────────────────────────────────────────
   Los modales de esta app se escribieron cada uno con sus estilos EN LÍNEA, así
   que cambiar el aspecto de «los diálogos» significaba editarlos de uno en uno.
   Estas cuatro clases recogen lo que todos repetían —tarjeta blanca, esquinas de
   24, cabecera con su aspa, pie con los botones a la derecha—. Los nuevos las
   usan; los viejos se pueden ir pasando cuando toque tocarlos.
   Se definen ANTES de usarlas, que es la lección del día: una clase inventada no
   avisa, simplemente no pinta nada. */
.modal-card {
  background: var(--bg-card, #fff);
  border-radius: 24px;
  box-shadow: 0 20px 50px rgba(15, 23, 42, 0.35);
  width: 100%;
  max-width: 460px;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  margin: 16px;
  overflow: hidden;
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 22px 26px 14px;
}
.modal-head h3 {
  font-size: 1.15rem; font-weight: 800; margin: 0; color: var(--primary);
}
.modal-head button {
  background: none; border: none; cursor: pointer; color: var(--text-muted);
  display: flex; padding: 4px; border-radius: 8px; line-height: 1;
}
.modal-head button:hover { background: rgba(15, 23, 42, 0.06); color: var(--text-main); }
/* El cuerpo es lo único que scrollea: la cabecera dice dónde estás y el pie
   lleva la acción, y perder cualquiera de los dos a media lectura es peor. */
.modal-body { padding: 0 26px 4px; overflow-y: auto; }
.modal-foot {
  display: flex; justify-content: flex-end; align-items: center; gap: 10px;
  flex-wrap: wrap; padding: 18px 26px 22px;
}

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(15, 23, 42, 0.8) !important;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  opacity: 1 !important;
  pointer-events: auto !important;
  backdrop-filter: blur(12px) !important;
  -webkit-backdrop-filter: blur(12px) !important;
  overflow-y: auto;
}

/* Paginación, Geolocalización e Interfaz de Filtros Premium */
.filter-tabs-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  gap: 16px;
  flex-flow: wrap;
  padding: 8px;
  background: rgba(15, 61, 100, 0.02);
  border: 1px solid var(--border-color);
  border-radius: 16px;
}

.filter-tabs-group {
  display: flex;
  flex-wrap: wrap;      /* en un móvil de 375 px los tres filtros no caben en una fila */
  max-width: 100%;
  gap: 6px;
  background: rgba(15, 61, 100, 0.04);
  padding: 4px;
  border-radius: 12px;
}

.filter-tab {
  padding: 8px 16px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-muted);
  background: transparent;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  align-items: center;
  gap: 6px;
}

.filter-tab:hover {
  color: var(--primary);
  background: rgba(255, 255, 255, 0.4);
}

.filter-tab.active {
  color: var(--primary);
  background: #ffffff;
  box-shadow: 0 2px 8px rgba(15, 61, 100, 0.06);
}

.filter-tab span {
  font-size: 0.72rem;
  font-weight: 700;
  background: rgba(15, 61, 100, 0.08);
  color: var(--primary);
  padding: 2px 6px;
  border-radius: 6px;
}

.filter-tab.active span {
  background: var(--primary);
  color: #ffffff;
}

.btn-geolocalize {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  width: 42px;
  height: 42px;
  padding: 0;
  font-size: 0;                 /* colapsa la leyenda -> va como tooltip */
  color: #ffffff;
  background: linear-gradient(135deg, var(--primary) 0%, #1e5a8f 100%);
  border: none;
  border-radius: 12px;
  cursor: pointer;
  transition: all 0.2s ease;
  box-shadow: 0 4px 12px rgba(15, 61, 100, 0.15);
  position: relative;
}
.btn-geolocalize > span { font-size: 1.3rem !important; margin: 0 !important; }
/* Tooltip propio con el aria-label (lo sincroniza el JS con el estado on/off). */
.btn-geolocalize[aria-label]::after {
  content: attr(aria-label);
  position: absolute; bottom: calc(100% + 9px); left: 50%;
  transform: translateX(-50%) translateY(4px);
  background: var(--text-main); color: #fff;
  font-size: 0.72rem; font-weight: 600; line-height: 1;
  padding: 6px 10px; border-radius: 8px; white-space: nowrap;
  opacity: 0; pointer-events: none; z-index: 60;
  box-shadow: 0 6px 18px rgba(15, 45, 74, .22);
  transition: opacity .14s ease, transform .14s ease;
}
.btn-geolocalize[aria-label]::before {
  content: ""; position: absolute; bottom: calc(100% + 4px); left: 50%;
  transform: translateX(-50%); border: 5px solid transparent;
  border-top-color: var(--text-main); opacity: 0; pointer-events: none; z-index: 60;
  transition: opacity .14s ease;
}
.btn-geolocalize[aria-label]:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); }
.btn-geolocalize[aria-label]:hover::before { opacity: 1; }

.btn-geolocalize:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(15, 61, 100, 0.25);
  background: linear-gradient(135deg, #164f7f 0%, #296ea9 100%);
}

.btn-geolocalize:active {
  transform: translateY(1px);
}

.btn-geolocalize.active {
  background: linear-gradient(135deg, var(--success) 0%, #059669 100%);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.25);
}

.pagination-footer {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--border-color);
}

.btn-pagination {
  width: 36px;
  height: 36px;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-muted);
  background: #ffffff;
  border: 1px solid var(--border-color);
  border-radius: 10px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.btn-pagination:hover:not(:disabled) {
  color: var(--primary);
  border-color: var(--primary);
  background: rgba(15, 61, 100, 0.02);
  transform: translateY(-1px);
}

.btn-pagination.active {
  color: #ffffff;
  background: var(--primary);
  border-color: var(--primary);
  box-shadow: 0 2px 8px rgba(15, 61, 100, 0.15);
}

.btn-pagination:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.stop-distance-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--accent-purple);
  background: rgba(0, 119, 182, 0.08);
  padding: 4px 8px;
  border-radius: 8px;
  margin-top: 6px;
  width: fit-content;
}

/* ══════════ Módulo Generar DeCA (gremio) ══════════ */
/* Sub-tabs Nuevo / Mis DeCAs */
.gen-tabs { display: flex; gap: 8px; margin-bottom: 22px; }
.gen-tab {
  padding: 9px 18px; border-radius: 12px; border: 1.5px solid var(--border-color);
  background: #fff; color: var(--text-muted); font-weight: 700; font-size: 0.88rem;
  cursor: pointer; font-family: 'Roboto', sans-serif;
}
.gen-tab.active { border-color: var(--primary); color: var(--primary); background: var(--primary-glow); }

/* Formulario por secciones */
.gen-form { max-width: 860px; }
.gen-section {
  background: var(--bg-card, #fff); border: 1px solid var(--border-color);
  border-radius: 18px; padding: 20px 22px; margin-bottom: 16px;
}
.gen-section h3 {
  display: flex; align-items: center; gap: 10px; font-size: 0.98rem;
  color: var(--text-main); margin-bottom: 14px;
}
.gen-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 8px; background: var(--primary);
  color: #fff; font-size: 0.8rem; font-weight: 800;
}
.gen-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 16px; }
.gen-grid .form-group { margin-bottom: 0; }
.gen-col2 { grid-column: span 2; }
.gen-col3 { grid-column: span 3; }
@media (max-width: 760px) {
  .gen-grid { grid-template-columns: 1fr; }
  .gen-col2, .gen-col3 { grid-column: span 1; }
}
.gen-form input:invalid.touched { border-color: var(--error, #c0392b); }

/* CAMPO PENDIENTE: obligatorio y todavía vacío. Ámbar y no rojo a propósito —
   rojo es "lo has hecho mal" y se reserva para cuando ya has intentado generar
   (.touched). Esto es "aún te falta", que no es lo mismo y no debe alarmar
   mientras rellenas. La barrita de la izquierda hace que se localicen de un
   vistazo en un formulario largo, sin repintar todo el campo. */
.gen-form input.pendiente,
.gen-form textarea.pendiente,
.gen-form select.pendiente {
  border-color: #f0b354;
  box-shadow: inset 3px 0 0 0 #f0b354;
}
.gen-form input.pendiente:focus,
.gen-form textarea.pendiente:focus,
.gen-form select.pendiente:focus { box-shadow: inset 3px 0 0 0 #f0b354; }

/* Éxito */
.gen-ok {
  max-width: 560px; margin: 30px auto; text-align: center; padding: 34px 26px;
  background: var(--bg-card, #fff); border: 1px solid var(--border-color); border-radius: 20px;
}
.gen-ok h3 { color: var(--success); font-size: 1.3rem; margin: 8px 0 6px; }
.gen-ok p { color: var(--text-muted); margin-bottom: 12px; line-height: 1.55; }

/* Histórico */
.hist-list { display: flex; flex-direction: column; gap: 10px; max-width: 860px; }
.hist-row {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: var(--bg-card, #fff); border: 1px solid var(--border-color);
  border-radius: 14px; padding: 14px 18px;
}
.hist-exp { font-weight: 800; color: var(--text-main); min-width: 150px; }
.hist-route { color: var(--text-muted); font-size: 0.9rem; flex: 1; min-width: 180px; }
.hist-state {
  font-size: 0.72rem; font-weight: 800; letter-spacing: .4px; text-transform: uppercase;
  padding: 5px 10px; border-radius: 999px; background: var(--primary-glow); color: var(--primary);
}
.hist-state.entregado { background: rgba(16,185,129,.12); color: var(--success); }
.hist-empty { color: var(--text-muted); text-align: center; padding: 40px 0; }

/* Aviso de suscripción sin activar (banner persistente, encima de las pestañas).
   Ámbar = requiere acción pero no es un error roto. Se rellena por JS. */
.tenant-status-banner {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin: 0 0 22px; padding: 16px 20px;
  background: rgba(245, 158, 11, .10);
  border: 1.5px solid rgba(245, 158, 11, .45);
  border-radius: 14px;
  box-shadow: 0 4px 14px rgba(245, 158, 11, .08);
}
.tenant-status-banner .tsb-icon {
  font-size: 1.6rem; color: var(--warning); flex-shrink: 0;
}
.tenant-status-banner .tsb-text { flex: 1; min-width: 220px; }
.tenant-status-banner .tsb-title {
  font-weight: 800; color: #b45309; font-size: 0.98rem; margin: 0 0 3px;
}
.tenant-status-banner .tsb-desc {
  color: var(--text-muted); font-size: 0.88rem; line-height: 1.45; margin: 0;
}
.tenant-status-banner .tsb-cta {
  flex-shrink: 0; border: none; cursor: pointer;
  /* #b45309 (amber-700) sobre blanco = 5.02:1 (WCAG AA). var(--warning) #f59e0b
     daba 2.15:1 con texto blanco → ilegible. */
  background: #b45309; color: #fff;
  font-weight: 700; font-size: 0.9rem; font-family: inherit;
  padding: 11px 20px; border-radius: 10px;
  display: inline-flex; align-items: center; gap: 8px;
  transition: filter .15s ease, transform .15s ease;
}
.tenant-status-banner .tsb-cta:hover { filter: brightness(1.06); transform: translateY(-1px); }
.tenant-status-banner .tsb-cta:focus-visible {
  outline: 3px solid rgba(245, 158, 11, .4); outline-offset: 2px;
}


/* Feedback GLOBAL de pulsación: al presionar, todo botón (y los enlaces-botón y
   tarjetas clicables) se "hunde" y oscurece un instante — que se NOTE el clic,
   en ratón y en táctil. Instantáneo (sin transición) para que sea nítido; los
   deshabilitados no reaccionan. */
button:active:not(:disabled),
a.btn-primary:active,
.nav-item:active,
.tsb-cta:active:not(:disabled) {
  transform: translateY(1px) scale(0.97);
  filter: brightness(0.92);
}

/* ── Ajustes: menú lateral y una sección a la vez ─────────────────────────
   Eran ocho tarjetas seguidas en un modal con scroll infinito. Lo que las
   ordena no es el tamaño sino el TRABAJO —quién soy, mis documentos, a quién
   aviso, qué gasto, cómo me integro—, y eso junta cosas que estaban en
   extremos opuestos: el aviso al chófer y el aviso al ERP son la misma
   pregunta. Con el menú, además, el scroll deja de ser del modal entero y pasa
   a ser el de UNA sección, que es lo que hace que se pueda encontrar algo. */
/* En Ajustes no se mueve nada de lo que te dice DÓNDE estás: la cabecera de la
   pantalla, el menú de apartados y el rótulo del apartado abierto. Los tres se
   quedan, pegados uno debajo de otro y sin hueco entre ellos — un hueco de dos
   dedos entre dos barras fijas deja ver pasar el contenido por en medio, que es
   peor que no fijar nada.
   Todos los desfases salen del padding de .main-content, así que ese padding es
   UNA variable y no un 40 repartido por seis sitios: el día que cambie, cambia
   en un lado. --cfg-cab (la altura de la cabecera) la mide index.js, porque el
   subtítulo cae en una línea o en dos según el ancho y el idioma. */
:root { --cfg-pad: 40px; }
@media (max-width: 768px) { :root { --cfg-pad: 20px; } }

#tab-ajustes .content-header {
  /* top NEGATIVO, del tamaño del padding. Con top:0 se pegaba justo por debajo
     del borde y quedaba una franja de ese padding por la que se veía pasar el
     contenido; así el borde de la caja se clava arriba del todo y el fondo tapa
     hasta el filo. El hueco lo pone el padding, no la posición. */
  position: sticky; top: calc(var(--deca-barra, 0px) - var(--cfg-pad)); z-index: 5;
  background: var(--bg-dark);
  margin: calc(-1 * var(--cfg-pad)) calc(-1 * var(--cfg-pad)) 26px;
  padding: var(--cfg-pad) var(--cfg-pad) 14px;
}
/* Lo que se pega DENTRO del panel arranca justo donde acaba la cabecera. El
   desfase del sticky se mide desde el borde interior del área que scrollea, no
   desde el filo de la ventana: de ahí el menos padding. */
.cfg-nav, .cfg-cab { top: calc(var(--cfg-cab, 132px) + var(--deca-barra, 0px) - var(--cfg-pad)); }

.cfg-cuerpo { display: flex; min-height: 0; flex: 1; }
/* El menú tampoco se mueve. Se pega POR DEBAJO de la cabecera, que también está
   fija: --cfg-cab lleva su altura real y la pone el JS, porque el subtítulo
   ocupa una línea o dos según el ancho y el idioma. El valor por defecto es
   solo el arranque, antes de la primera medición.
   El filete separador se lo queda .cfg-cont: con align-self:flex-start el menú
   mide lo que miden sus botones, y su borde derecho dejaría de llegar abajo. */
.cfg-nav {
  flex: none; width: 208px; padding: 18px 12px 18px 18px;
  display: flex; flex-direction: column; gap: 2px;
  align-self: flex-start; position: sticky;
}
.cfg-nav button {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 12px; border: none; background: none; border-radius: 10px;
  font: inherit; font-size: 0.88rem; color: var(--text-muted);
  text-align: left; cursor: pointer; transition: background .15s, color .15s;
}
.cfg-nav button .material-symbols-outlined { font-size: 1.2rem; flex: none; }
.cfg-nav button:hover { background: rgba(15,23,42,0.05); color: var(--text-main); }
.cfg-nav button[aria-current="true"] {
  background: var(--primary-glow); color: var(--primary); font-weight: 600;
}
/* SIN scroll propio: la página ya scrollea (.main-content). Dos barras
   anidadas —una dentro de otra, con la de fuera a medio camino— hacen que no se
   sepa cuál mueve qué. Esto venía de cuando Ajustes era un modal, donde la
   ventana sí tenía altura fija y el scroll de dentro era el único que había. */
.cfg-cont { flex: 1; min-width: 0; padding: 22px 28px 28px;
  border-left: 1px solid var(--border-color); }
/* Solo se ve la sección elegida: el resto no se descarga ni se destruye, solo
   se esconde — así no se pierde lo que el admin estuviera escribiendo. */
.cfg-grupo { display: none; }
.cfg-grupo.cfg-activa { display: block; }
.cfg-grupo[hidden] { display: none; }
.cfg-grupo-t {
  display: flex; align-items: center; gap: 8px;
  font-size: 1.08rem; font-weight: 700; color: var(--text-main);
  margin: 0 0 2px; padding-bottom: 10px;
  border-bottom: 1px solid var(--border-color);
}
/* El icono de la cabecera es el MISMO que el del menú, y el menú está a diez
   píxeles marcando dónde estás: pintarlo dos veces no dice nada nuevo. Sigue
   en el DOM porque de ahí lo copia repasarGrupos() para montar el menú —
   borrarlo dejaría las entradas del menú sin icono. */
.cfg-grupo-t .material-symbols-outlined { display: none; }
.cfg-grupo-sub {
  color: var(--text-muted); font-size: 0.85rem;
  margin: 10px 0 0; line-height: 1.5;   /* el hueco de abajo lo pone .cfg-cab */
}

/* El rótulo del apartado tampoco se va: al mismo tope que el menú, así que
   quedan alineados. Los márgenes negativos igualan el padding de .cfg-cont —
   pegado al borde, sin ese estirón se vería contenido colarse por los lados. */
.cfg-cab {
  position: sticky; z-index: 2;
  background: #fff;
  margin: -22px -28px 16px; padding: 22px 28px 10px;
}
/* En móvil el menú se pone arriba, en fila y desplazable: una columna de 208px
   se comería media pantalla. */
@media (max-width: 700px) {
  .cfg-cuerpo { flex-direction: column; }
  /* En horizontal no se pega: taparía el contenido al bajar. Y el filete vuelve
     al menú, que aquí va arriba y no al lado. */
  .cfg-nav {
    width: auto; flex-direction: row; overflow-x: auto; gap: 6px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
    align-self: auto; position: static;
  }
  .cfg-cont { border-left: none; }
  /* Mismo ajuste al padding que tiene .cfg-cont en móvil. */
  .cfg-cab { margin: -18px -16px 14px; padding: 18px 16px 10px; }
  .cfg-nav button { width: auto; white-space: nowrap; padding: 7px 12px; }
  .cfg-cont { padding: 18px 16px 24px; }
}

/* Las tarjetas de dentro de una sección. Iban con borde DISCONTINUO, y en una
   interfaz el punteado significa «suelta aquí un fichero», «esto está vacío» o
   «esto está desactivado» — ninguna de las tres. Además, al vivir dentro del
   panel blanco eran caja dentro de caja: dos bordes y dos paddings para separar
   lo que ya separaba el menú. Se quedan en una superficie tintada y sin borde,
   que agrupa igual y quita un nivel. */
.cfg-caja {
  background: var(--primary-glow);
  border: 0;
  border-radius: 14px;
  padding: 18px 20px;
  margin: 0 0 16px;
}
.cfg-caja:last-child { margin-bottom: 0; }
/* A partir de ~70 caracteres el ojo pierde el renglón al saltar de línea, y
   estas descripciones se estaban yendo a 110 sobre el ancho del panel. */
.cfg-grupo-sub,
.cfg-caja > p,
.cfg-caja label > span:last-child { max-width: 66ch; }

/* El contenedor de Ajustes dentro de su sección. Ya no es un modal flotante:
   es una tarjeta más de la página, con su menú a la izquierda. */
.cfg-panel {
  /* Blanco OPACO, no --bg-card (que es blanco al 85%): dentro hay rótulos que
     se quedan fijos, y con un fondo translúcido se vería pasar el contenido
     por debajo de ellos. */
  background: #fff;
  border: 1px solid var(--border-color);
  border-radius: 20px;
  /* NADA de overflow:hidden aquí: un ancestro recortado convierte el menú
     sticky en un menú quieto (se pega al scrollport del ancestro, que no
     scrollea). El único que recortaba era el borde del menú, y ese ya casa
     con la esquina sin ayuda. */
  display: flex;
  min-height: 420px;
  max-width: 980px;
}
.cfg-panel .cfg-cuerpo { flex: 1; min-width: 0; }
@media (max-width: 700px) {
  .cfg-panel { border-radius: 16px; min-height: 0; }
}

/* ── Botones de Ajustes ───────────────────────────────────────────────────
   .btn-secondary se usaba en catorce sitios y no estaba definida en ninguna
   hoja: el navegador los pintaba con su gris de sistema, justo al lado de
   botones que sí tenían estilo. Y «Guardar» —la acción que cierra el trabajo
   de la sección— pesaba lo mismo que lo que tenía al lado, o menos. */
.btn-secondary {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 16px; border-radius: 9px;
  border: 1px solid var(--border-color); background: var(--bg-card, #fff);
  color: var(--text-main); font: inherit; font-size: 0.88rem; font-weight: 600;
  cursor: pointer; transition: background .15s, border-color .15s;
}
.btn-secondary:hover:not(:disabled) { background: rgba(15, 23, 42, 0.04); }
.btn-secondary:disabled { opacity: .55; cursor: not-allowed; }
/* Mismo degradado que .btn-primary: que «Guardar» y «Activar firma» se lean
   como la misma familia, no como dos sistemas distintos. */
.btn-cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 18px; border-radius: 9px; border: 1px solid transparent;
  background: linear-gradient(90deg, var(--primary), var(--accent-cyan));
  color: var(--text-inverse); font: inherit; font-size: 0.88rem; font-weight: 600;
  cursor: pointer; transition: filter .15s, box-shadow .15s, transform .15s;
  box-shadow: 0 2px 8px rgba(15, 61, 100, 0.18);
}
.btn-cta:hover:not(:disabled) { filter: brightness(1.06); box-shadow: 0 4px 14px rgba(15, 61, 100, 0.24); }
.btn-cta:active:not(:disabled) { transform: translateY(1px); }
.btn-cta:disabled { opacity: .55; cursor: not-allowed; box-shadow: none; }

/* ── HOJA DE RUTA DE VIAJEROS: los desplegables, como las cajas de texto ──────
   La aplicación estiliza `.input-wrapper input`, pero NO `select`: hasta ahora
   solo había un desplegable en un formulario (#tpl-select) y llevaba su propia
   regla por id. El formulario de viajeros tiene cuatro —plantilla, autobús,
   naturaleza y los de cada servicio— y salían con el aspecto crudo del
   navegador, estrechos y sin borde, al lado de campos de texto que sí lo tienen.

   Va ACOTADO a #tab-viajeros a propósito. Una regla global `.input-wrapper
   select` tocaría desplegables de pantallas que hoy funcionan, y eso es
   exactamente lo que no se hace aquí. */
#tab-viajeros .input-wrapper select {
  width: 100%;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid var(--border-color);
  background: rgba(255, 255, 255, 0.8);
  color: var(--text-main);
  font-size: 0.95rem;
  outline: none;
  transition: all 0.25s ease;
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.02);
}
#tab-viajeros .input-wrapper select:focus {
  border-color: var(--primary);
  background: #ffffff;
  box-shadow: 0 0 0 4px var(--primary-glow), inset 0 1px 2px rgba(15, 23, 42, 0.02);
}

/* La barra de plantillas de la hoja de ruta, igual que la del DeCA. El
   desplegable ocupa el hueco y los dos botones cuadrados van pegados a él, no en
   el borde de la pantalla. Va DESPUÉS de la regla de arriba, con la que empata en
   especificidad, para poder afinarle el tamaño sin `!important`. */
#hrv-tpl-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 18px;
}
#hrv-tpl-bar .input-wrapper {
  flex: 1;
  min-width: 0;
}
#hrv-tpl-bar .input-wrapper select {
  padding: 9px 12px;
  border-radius: 10px;
  background: #ffffff;
  font-size: 0.88rem;
}
