/* BCN HUB — Components
   Piezas reutilizables. Cada componente definido acá es la forma canónica:
   si una página necesita un componente nuevo, se agrega acá primero + al
   styleguide, y después se usa. No hay estilos de componentes en otro lado. */

/* ---------- Cards (override Bootstrap) ---------- */
.card {
  background: var(--bg-card) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-md);
}
.card .card-title {
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

/* ---------- Stat card ---------- */
.stat-value {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  margin-bottom: var(--space-2);
  color: var(--text-heading);
}
.stat-label {
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-wider);
  color: var(--text-muted);
  text-transform: uppercase;
}

/* ---------- Tables ---------- */
.table {
  --bs-table-bg:           transparent;
  --bs-table-color:        var(--text);
  --bs-table-border-color: var(--border);
  --bs-table-hover-bg:     var(--bg-hover);
  --bs-table-hover-color:  var(--text);
  color: var(--text);
  margin-bottom: 0;
}
.table > thead {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-wide);
}
.table > thead th {
  border-bottom: 1px solid var(--border);
  font-weight: var(--fw-semibold);
  padding: var(--space-3) var(--space-4);
  text-transform: uppercase;
}
.table > tbody > tr > td {
  padding: var(--space-3) var(--space-4);
  border-color: var(--border);
  vertical-align: middle;
}
tr.clickable { cursor: pointer; }

/* ---------- Estado pill (OT estados) ----------
   Lenguaje "Picnic vibe": dot color + label blanco + bg casi imperceptible
   con borde teñido y leve glow. Contrasta limpio con los .prio pills que
   son más densos. */
.estado-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  font-size: 12px;
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-heading);
  line-height: 1;
  --pill-color: var(--neutral);
}
.estado-pill::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--pill-color);
  box-shadow: 0 0 7px color-mix(in srgb, var(--pill-color) 90%, transparent),
              0 0 2px color-mix(in srgb, var(--pill-color) 90%, transparent);
  flex-shrink: 0;
}

.estado-pill--borrador    { --pill-color: var(--estado-borrador); }
.estado-pill--pendiente   { --pill-color: var(--estado-pendiente); }
.estado-pill--asignada    { --pill-color: var(--estado-asignada); }
.estado-pill--en-progreso { --pill-color: var(--estado-en-progreso); }
.estado-pill--completada  { --pill-color: var(--estado-completada); }
.estado-pill--cerrada     { --pill-color: var(--estado-cerrada); }
.estado-pill--cancelada   { --pill-color: var(--estado-cancelada); }

/* ---------- OT row strip (lista de OTs) ----------
   Franja vertical 2px al inicio del primer td, color del estado, alto 66%
   centrado verticalmente — mismo lenguaje que el sidebar activo. */
.ot-row td:first-child {
  position: relative;
  --row-strip: var(--neutral);
}
.ot-row td:first-child::before {
  content: '';
  position: absolute;
  left: 0;
  top: 17%;
  height: 66%;
  width: 2px;
  background: var(--row-strip);
  border-radius: 0 2px 2px 0;
}
.ot-row--borrador     td:first-child { --row-strip: var(--estado-borrador); }
.ot-row--pendiente    td:first-child { --row-strip: var(--estado-pendiente); }
.ot-row--asignada     td:first-child { --row-strip: var(--estado-asignada); }
.ot-row--en-progreso  td:first-child { --row-strip: var(--estado-en-progreso); }
.ot-row--completada   td:first-child { --row-strip: var(--estado-completada); }
.ot-row--cerrada      td:first-child { --row-strip: var(--estado-cerrada); }
.ot-row--cancelada    td:first-child { --row-strip: var(--estado-cancelada); }

/* ---------- Prioridad pills ---------- */
.prio {
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}
.prio-baja    { background: var(--neutral-dim); color: var(--text-muted); }
.prio-normal  { background: var(--accent-dim);  color: var(--accent); }
.prio-alta    { background: var(--estado-en-progreso-dim); color: var(--estado-en-progreso); }
.prio-urgente { background: var(--estado-cancelada-dim);   color: var(--estado-cancelada); }

/* ---------- Role badge ---------- */
.role-badge {
  background: var(--accent-dim);
  color: var(--accent);
  padding: 3px var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

/* ---------- User chip (topbar) ---------- */
.user-chip {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--text);
  font-size: var(--fs-base);
}
.avatar {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-pill);
}

/* ---------- Buttons (overrides Bootstrap) ---------- */
.btn-primary {
  --bs-btn-bg:                  var(--accent);
  --bs-btn-border-color:        var(--accent);
  --bs-btn-hover-bg:            var(--accent-hover);
  --bs-btn-hover-border-color:  var(--accent-hover);
  --bs-btn-active-bg:           var(--accent-hover);
  --bs-btn-active-border-color: var(--accent-hover);
  font-weight: var(--fw-medium);
  box-shadow: 0 4px 14px rgba(23,171,229,0.20);
  transition: box-shadow var(--transition-fast), transform var(--transition-fast);
}
.btn-primary:hover {
  box-shadow: 0 6px 20px rgba(23,171,229,0.35);
}
.btn-outline-secondary {
  --bs-btn-color:              var(--text-muted);
  --bs-btn-border-color:       var(--border);
  --bs-btn-hover-bg:           var(--bg-hover);
  --bs-btn-hover-border-color: var(--border);
  --bs-btn-hover-color:        var(--text);
}
.btn-google {
  font-weight: var(--fw-medium);
  background: #fff;
  color: var(--text-invert);
}
.btn-google:hover { background: #f3f4f6; color: var(--text-invert); }

/* ---------- Auth card (login / pending) ---------- */
.auth-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-8) var(--space-7);
  max-width: 420px;
  width: 100%;
  text-align: center;
  box-shadow: var(--shadow-md);
}
.auth-card h1 {
  color: var(--text-heading);
  font-weight: var(--fw-bold);
}
.auth-card-logo {
  display: block;
  height: 56px;
  width: auto;
  max-width: 100%;
  margin: 0 auto var(--space-4);
  object-fit: contain;
}

/* ---------- Alerts ---------- */
.alert-danger {
  background: var(--danger-dim);
  color: #fca5a5;
  border-color: rgba(239, 68, 68, 0.3);
}

/* ---------- User status pill ----------
   Mismo patrón que estado-pill: dim bg + color saturado + dot. */
.user-status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  line-height: 1;
}
.user-status::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: currentColor;
  flex-shrink: 0;
}
.user-status--pending  { background: var(--estado-en-progreso-dim); color: var(--estado-en-progreso); }
.user-status--active   { background: var(--estado-completada-dim);  color: var(--estado-completada); }
.user-status--disabled { background: var(--neutral-dim);            color: var(--text-muted); }

/* ---------- Tabs ---------- */
.tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-5);
}
.tab {
  background: none;
  border: none;
  color: var(--text-muted);
  padding: var(--space-3) var(--space-4);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--transition-fast), border-color var(--transition-fast);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.tab:hover { color: var(--text); }
.tab.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.tab-count {
  background: var(--bg-hover);
  color: var(--text-muted);
  font-size: var(--fs-xs);
  padding: 1px var(--space-2);
  border-radius: var(--radius-pill);
  font-weight: var(--fw-semibold);
  min-width: 20px;
  text-align: center;
}
.tab.active .tab-count {
  background: var(--accent-dim);
  color: var(--accent);
}

/* Tabs con color de estado: la tab activa toma el color de su categoría
   (completada verde, en progreso ámbar, etc.) en vez del accent genérico.
   Mismos tokens que .estado-pill / .ot-row. */
.tab--borrador    { --tab-color: var(--estado-borrador);    --tab-color-dim: var(--estado-borrador-dim); }

/* ---------- Solapa Sala (Telegram por OT) ----------
   Tabs del detalle de OT + filas de invitación con chip de estado.
   El chip toma su color por --chip-color (mismo patrón que estado-pill). */
.ot-detail-tabs { margin-bottom: var(--space-5); }

.sala-inv-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-card-soft);
  transition: border-color .2s ease;
}
.sala-inv-row:hover { border-color: var(--border-strong); }

.sala-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 10px;
  border-radius: 14px;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--chip-color);
  background: color-mix(in srgb, var(--chip-color) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--chip-color) 30%, transparent);
  white-space: nowrap;
}

/* ---------- Drag & drop en tablas de plantillas ---------- */
.pl-grip { cursor: grab; color: var(--text-muted, #7f8ea3); }
.pl-row.dragging { opacity: 0.45; }
.pl-row[draggable="true"] { cursor: default; }
.tab--pendiente   { --tab-color: var(--estado-pendiente);   --tab-color-dim: var(--estado-pendiente-dim); }
.tab--asignada    { --tab-color: var(--estado-asignada);    --tab-color-dim: var(--estado-asignada-dim); }
.tab--en-progreso { --tab-color: var(--estado-en-progreso); --tab-color-dim: var(--estado-en-progreso-dim); }
.tab--completada  { --tab-color: var(--estado-completada);  --tab-color-dim: var(--estado-completada-dim); }
.tab--cerrada     { --tab-color: var(--estado-cerrada);     --tab-color-dim: var(--estado-cerrada-dim); }
.tab--cancelada   { --tab-color: var(--estado-cancelada);   --tab-color-dim: var(--estado-cancelada-dim); }
.tab[class*="tab--"].active {
  color: var(--tab-color);
  border-bottom-color: var(--tab-color);
}
.tab[class*="tab--"].active .tab-count {
  background: var(--tab-color-dim);
  color: var(--tab-color);
}

/* ---------- Forms (override Bootstrap) ---------- */
.form-label {
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
  font-weight: var(--fw-semibold);
  margin-bottom: var(--space-2);
}
.form-control,
.form-select {
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-3);
  font-size: var(--fs-base);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.form-control:focus,
.form-select:focus {
  background: var(--bg-input);
  color: var(--text);
  border-color: var(--border-focus);
  box-shadow: 0 0 0 3px var(--accent-dim);
  outline: none;
}
.form-control::placeholder { color: var(--text-muted); opacity: 0.6; }
.form-control:disabled,
.form-select:disabled {
  background: var(--bg-card);
  color: var(--text-muted);
  cursor: not-allowed;
}
textarea.form-control { min-height: 90px; resize: vertical; }

.form-text { color: var(--text-muted); font-size: var(--fs-sm); }

/* ---------- Modal overrides (Bootstrap) ---------- */
.modal-content {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}
.modal-header {
  border-bottom: 1px solid var(--border);
  padding: var(--space-4) var(--space-5);
}
.modal-body { padding: var(--space-5); }

/* Fix: modal-dialog-scrollable de Bootstrap espera que .modal-body sea hijo
   directo de .modal-content. Cuando hay un <form> envolviendo header+body+footer
   (patrón común en este repo), el layout flex se rompe y el body no scrollea.
   Forzamos el comportamiento esperado, sin importar si hay form intermedio. */
.modal-dialog-scrollable .modal-content,
.modal-dialog-scrollable .modal-content > form {
  max-height: calc(100vh - 3.5rem);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.modal-dialog-scrollable .modal-body {
  overflow-y: auto;
  flex: 1 1 auto;
}
.modal-footer {
  border-top: 1px solid var(--border);
  padding: var(--space-4) var(--space-5);
}
.modal-title { color: var(--text-heading); font-weight: var(--fw-semibold); }

/* ---------- Empty state ---------- */
.empty-state {
  text-align: center;
  padding: var(--space-9) var(--space-5);
  color: var(--text-muted);
}
.empty-state i {
  font-size: 48px;
  display: block;
  margin-bottom: var(--space-4);
  opacity: 0.5;
}
.empty-state h3 {
  color: var(--text);
  font-size: var(--fs-lg);
  margin-bottom: var(--space-2);
}

/* ---------- Button variants extra ---------- */
.btn-danger {
  --bs-btn-bg:                  var(--estado-cancelada);
  --bs-btn-border-color:        var(--estado-cancelada);
  --bs-btn-hover-bg:            #ff7575;
  --bs-btn-hover-border-color:  #ff7575;
  --bs-btn-color:               #3a0a0a;
  --bs-btn-hover-color:         #3a0a0a;
  font-weight: var(--fw-medium);
}
.btn-ghost {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  transition: background var(--transition-fast), color var(--transition-fast);
  cursor: pointer;
}
.btn-ghost:hover { background: var(--bg-hover); color: var(--text); }

/* ---------- Toolbar (filtros + acciones sobre una tabla) ---------- */
.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}
.toolbar-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* Buscador dentro de .toolbar-actions (listas): ancho fijo en desktop,
   100% en mobile (ver bloque responsive). */
.toolbar-actions > .toolbar-search { width: 280px; }

/* Fila de tabs + buscador a la derecha (herramientas). En mobile el
   buscador pasa arriba a ancho completo (ver bloque responsive). */
.tabs-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-5);
}
.tabs-row > .tabs { border-bottom: 0; margin-bottom: 0; flex: 1 1 auto; min-width: 0; }
.tabs-row-search { max-width: 240px; margin-left: auto; flex: 0 1 240px; }
.tabs-row-search > .form-select { min-width: 180px; }

/* ---------- Action buttons row (detail pages) ---------- */
.action-bar {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* ---------- User menu (topbar dropdown) ----------
   El TRIGGER vive en la sección "user-menu-trigger-v2" más abajo.
   Acá sólo el wrapper + el panel del dropdown. */
.user-menu {
  position: relative;
}
/* Dropdown menu panel */
.user-menu-panel.dropdown-menu {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: var(--space-2);
  min-width: 240px;
  margin-top: var(--space-2);
}
.user-menu-header {
  padding: var(--space-3) var(--space-3) var(--space-2);
  color: var(--text);
}
.user-menu-header strong {
  display: block;
  color: var(--text-heading);
}
.user-menu-header small {
  color: var(--text-muted);
  font-size: var(--fs-xs);
}
.user-menu-panel .dropdown-item {
  color: var(--text);
  padding: var(--space-3) var(--space-3);
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--fs-base);
  transition: background var(--transition-fast);
}
.user-menu-panel .dropdown-item i {
  color: var(--text-muted);
  width: 18px;
  text-align: center;
}
.user-menu-panel .dropdown-item:hover {
  background: var(--bg-hover);
  color: var(--text);
}
.user-menu-panel .dropdown-item:hover i { color: var(--accent); }
.user-menu-panel .dropdown-item--danger { color: var(--estado-cancelada); }
.user-menu-panel .dropdown-item--danger i { color: var(--estado-cancelada); }
.user-menu-panel .dropdown-item--danger:hover {
  background: var(--danger-dim);
  color: var(--estado-cancelada);
}
.user-menu-panel .dropdown-divider {
  border-color: var(--border);
  margin: var(--space-2) 0;
}

/* ---------- Checklist (OT detail) ----------
   La forma canónica del checklist vive en la sección "CHECKLIST v3"
   más abajo (.checklist-tl-*). Acá sólo queda el progress bar compartido. */
.checklist-progress {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.checklist-progress-bar {
  flex: 1;
  height: 6px;
  background: var(--bg-input);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.checklist-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--success));
  border-radius: var(--radius-pill);
  transition: width var(--transition-base);
}
.checklist-progress-label {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

/* ---------- Cliente tree (detalle de cliente) ----------
   Árbol jerárquico Sitio → Zona → Ubicación → Equipo, con líneas guía
   y cards para equipos. Reemplaza al primer intento que sentía más texto
   plano que app. */
.tree-node {
  position: relative;
}
.tree-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-2);
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast);
}
.tree-row:hover {
  background: var(--bg-hover);
}
.tree-row:hover .tree-row-actions { opacity: 1; }
.tree-row-actions {
  display: flex;
  gap: var(--space-1);
  margin-left: auto;
  opacity: 0.25;
  transition: opacity var(--transition-fast);
}
.tree-toggle {
  background: transparent;
  border: none;
  color: var(--text-muted);
  width: 20px;
  height: 20px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform var(--transition-fast), color var(--transition-fast);
  flex-shrink: 0;
}
.tree-toggle:hover { color: var(--accent); }
.tree-toggle--open { transform: rotate(90deg); }
.tree-toggle--leaf { cursor: default; opacity: 0.25; }
.tree-icon {
  color: var(--text-muted);
  font-size: var(--fs-base);
  width: 18px;
  text-align: center;
  flex-shrink: 0;
}
.tree-children {
  position: relative;
  margin-left: 11px;
  padding-left: var(--space-5);
  border-left: 1px dashed var(--border);
}
/* Línea más sutil para niveles profundos */
.tree-children .tree-children { border-left-style: dotted; }

.tree-label {
  color: var(--text);
  font-weight: var(--fw-medium);
}
.tree-label-sub {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  margin-left: var(--space-2);
}
.tree-count {
  background: var(--bg-hover);
  color: var(--text-muted);
  font-size: var(--fs-xs);
  padding: 1px var(--space-2);
  border-radius: var(--radius-pill);
  font-weight: var(--fw-semibold);
  margin-left: var(--space-2);
}

/* Equipo card dentro del árbol — destaca que el equipo es el nodo "real". */
.equipo-card {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-2);
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.equipo-card:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}
.equipo-card:hover .tree-row-actions { opacity: 1; }
.equipo-card-icon {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  background: var(--accent-dim);
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-lg);
  flex-shrink: 0;
}
.equipo-card-body { flex: 1; min-width: 0; }
.equipo-card-title {
  color: var(--text);
  font-weight: var(--fw-medium);
  font-size: var(--fs-base);
}
.equipo-card-meta {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  margin-top: 2px;
}

/* ============================================================
   PAGE HERO — header de página 2026
   Reemplaza al .page-header viejo (h4 + p gris). Más presencia,
   eyebrow con icono, título grande, subtítulo más relajado.
   ============================================================ */
.page-hero {
  position: relative;
  margin: calc(var(--page-padding-y) * -1) calc(var(--page-padding-x) * -1) var(--space-7);
  padding: var(--space-6) var(--page-padding-x) var(--space-6);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
}
/* Glow apenas perceptible — solo punto cyan arriba a la izq, fade a transparente.
   Sin border-bottom, sin background sólido. Limpio. */
.page-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(560px 220px at 4% 0%, rgba(23,171,229,0.10), transparent 70%);
  pointer-events: none;
  z-index: 0;
  -webkit-mask-image: linear-gradient(180deg, #000 50%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 50%, transparent 100%);
}
.page-hero > * { position: relative; z-index: 1; }
.page-hero-body { flex: 1; min-width: 0; }
.page-hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px var(--space-3);
  background: var(--accent-dim);
  color: var(--accent);
  border: 1px solid rgba(23,171,229,0.25);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  margin-bottom: var(--space-3);
  box-shadow: 0 0 18px rgba(23,171,229,0.18);
}
.page-hero-title {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  color: var(--text-heading);
  margin: 0 0 var(--space-2);
  letter-spacing: -0.01em;
}
.page-hero-sub {
  color: var(--text-muted);
  font-size: var(--fs-md);
  line-height: var(--lh-relaxed);
  max-width: 760px;
  margin: 0;
}
.page-hero-actions {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
}

/* Generic card hover lift (suave) */
.card { transition: border-color var(--transition-fast), transform var(--transition-fast); }
.card:hover { border-color: var(--border-strong) !important; }

/* Action icon button — usado en sentence-builder, checklist, etc. */
.btn-icon {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted);
  width: 30px;
  height: 30px;
  padding: 0;
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all var(--transition-fast);
}
.btn-icon:hover {
  background: var(--bg-hover);
  color: var(--text);
  border-color: var(--border);
}
.btn-icon--danger:hover {
  color: var(--danger);
  background: var(--danger-dim);
  border-color: rgba(239,68,68,0.3);
}

/* ============================================================
   NOTIFICATION RULES v2 — sentence-builder
   ============================================================ */
.rules-stack { display: flex; flex-direction: column; gap: var(--space-7); }

.trigger-section {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
}
.trigger-section-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px dashed var(--border);
}
.trigger-section-title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--fs-lg);
  color: var(--text-heading);
  font-weight: var(--fw-semibold);
}
.trigger-section-title i { color: var(--accent); font-size: var(--fs-xl); }
.trigger-section-key {
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  background: var(--bg-input);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
}
.trigger-section-desc {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  margin: var(--space-2) 0 var(--space-2);
}
.trigger-section-meta {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.trigger-section-fallback {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px var(--space-3);
  background: var(--bg-input);
  border-radius: var(--radius-pill);
  border: 1px dashed var(--border-strong);
}
.trigger-section-fallback b { color: var(--accent); font-weight: var(--fw-semibold); }

.rule-grid {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.rule-card-v2 {
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  transition: all var(--transition-fast);
}
.rule-card-v2:hover {
  border-color: var(--border-strong);
  border-left-color: var(--accent-hover);
  transform: translateX(2px);
}
.rule-card-v2--off {
  opacity: 0.55;
  border-left-color: var(--text-muted);
}
.rule-card-v2-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.rule-card-v2-title {
  flex: 1;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  margin: 0;
}
.rule-card-v2-actions { display: flex; gap: var(--space-1); }

/* Sentence visual */
.sentence {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  line-height: 1.8;
}
.sentence-kw {
  font-size: 10px;
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  padding: 2px var(--space-2);
  background: var(--bg-card);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}
.sentence-conj {
  font-size: 10px;
  font-weight: var(--fw-bold);
  color: var(--accent);
  padding: 0 var(--space-1);
}
.sentence-muted { color: var(--text-muted); font-style: italic; font-size: var(--fs-sm); }

.sentence-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text);
}
.sentence-chip b { color: var(--text-heading); font-weight: var(--fw-semibold); }
.sentence-chip i { font-size: 11px; }
.sentence-chip--trigger { background: var(--accent-dim); color: var(--accent); border-color: rgba(23,171,229,0.3); }
.sentence-chip--cond    { background: var(--bg-card); border-color: var(--border-strong); }
.sentence-chip--aud     { background: var(--info-dim); color: #93c5fd; border-color: rgba(59,130,246,0.3); }
.sentence-chip--aud-tecnico { background: var(--success-dim); color: var(--success); border-color: rgba(0,204,136,0.3); }
.sentence-chip--aud-chat    { background: var(--warning-dim); color: var(--warning); border-color: rgba(232,212,76,0.3); }
.sentence-chip--tpl     { background: var(--bg-input); border-color: var(--border-strong); }
.sentence-chip--time    { background: var(--bg-input); border-color: var(--border-strong); color: var(--text-muted); }
.sentence-chip--debounce{ background: var(--bg-input); border-color: var(--border-strong); color: var(--text-muted); }

/* Editor modal — form grid */
.form-grid { display: flex; flex-direction: column; gap: var(--space-5); }
.form-row { display: flex; flex-direction: column; gap: var(--space-2); }
.form-row--cols-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
}
@media (max-width: 720px) { .form-row--cols-2 { grid-template-columns: 1fr; } }

.trigger-display {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--accent-dim);
  border: 1px solid rgba(23,171,229,0.3);
  border-radius: var(--radius-md);
  color: var(--accent);
  width: fit-content;
}
.trigger-display strong { color: var(--text-heading); }
.trigger-display code {
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  background: var(--bg);
  padding: 2px 6px;
  border-radius: var(--radius-sm);
}

.default-template-preview {
  margin-top: var(--space-2);
}
.default-template-preview summary {
  cursor: pointer;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  user-select: none;
}
.default-template-preview pre {
  margin-top: var(--space-2);
  padding: var(--space-3);
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  white-space: pre-wrap;
  max-height: 200px;
  overflow-y: auto;
}

/* Conditions builder */
.conditions-builder {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}
.cond-list { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-3); }
.cond-empty { color: var(--text-muted); font-style: italic; font-size: var(--fs-sm); padding: var(--space-2); }
.cond-row {
  display: grid;
  grid-template-columns: 1.4fr 1.2fr 1.6fr auto;
  gap: var(--space-2);
  align-items: center;
}
@media (max-width: 720px) { .cond-row { grid-template-columns: 1fr; } }
.cond-add-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding-top: var(--space-3);
  border-top: 1px dashed var(--border);
}
.cond-op-toggle {
  margin-left: auto;
  display: inline-flex;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 3px;
}
.cond-op-btn {
  background: transparent;
  border: none;
  padding: 4px var(--space-3);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: all var(--transition-fast);
}
.cond-op-btn--on {
  background: var(--accent);
  color: var(--text-invert);
}

/* Audiences builder */
.audiences-builder {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}
.audiences-list { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-3); }
.aud-card {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.aud-card > i { font-size: 20px; color: var(--accent); margin-top: 2px; }
.aud-card-body { flex: 1; min-width: 0; }
.aud-card-body strong { display: block; color: var(--text-heading); font-size: var(--fs-base); }
.aud-add-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px dashed var(--border);
}

/* Day picker (M/T/W/T/F/S/S) */
.day-picker { display: flex; gap: 4px; }
.day-pill {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  cursor: pointer;
  transition: all var(--transition-fast);
}
.day-pill:hover { color: var(--text); border-color: var(--border-strong); }
.day-pill--on {
  background: var(--accent);
  color: var(--text-invert);
  border-color: var(--accent);
}

/* ============================================================
   LEGACY Notification rules table (v1) — mantengo por compat
   ============================================================ */
.rule-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-3);
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  transition: border-color var(--transition-fast);
}
.rule-card:hover { border-color: var(--border-strong); }
.rule-card--disabled { opacity: 0.5; }
.rule-card--overridden { border-left: 3px solid var(--accent); }
.rule-card-body { flex: 1; min-width: 0; }
.rule-card-title {
  color: var(--text-heading);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-md);
  margin-bottom: var(--space-1);
}
.rule-card-key {
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  background: var(--bg-input);
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  margin-left: var(--space-2);
}
.rule-card-audiences {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.rule-card-audience {
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  font-weight: var(--fw-semibold);
}
.rule-card-audience--ops     { background: var(--accent-dim);  color: var(--accent); }
.rule-card-audience--tecnico { background: var(--estado-completada-dim); color: var(--estado-completada); }
.rule-card-actions {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-shrink: 0;
}
.rule-card-preview {
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  white-space: pre-wrap;
  max-height: 160px;
  overflow-y: auto;
}

/* Toggle switch (Bootstrap-compatible dark style) */
.form-switch .form-check-input {
  background-color: var(--bg-input);
  border-color: var(--border-strong);
}
.form-switch .form-check-input:checked {
  background-color: var(--accent);
  border-color: var(--accent);
}

/* ---------- Styleguide-specific ----------
   Pequeños helpers para mostrar tokens visualmente en /styleguide.
   No usar en features — son solo para la página de referencia. */
.sg-section { margin-bottom: var(--space-8); }
.sg-section > h2 {
  font-size: var(--fs-xl);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
}
.sg-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-3);
}
.sg-swatch {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
  font-size: var(--fs-xs);
}
.sg-swatch .sg-chip {
  display: block;
  height: 40px;
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-2);
  border: 1px solid var(--border);
}
.sg-swatch code {
  color: var(--text-muted);
  font-family: var(--ff-mono);
}
.sg-row {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  align-items: center;
}

/* ============================================================
   ENTITY PILL — Picnic vibe.
   Pill oscura, dot color a la izquierda, label bold + sublabel mono muted.
   Usado para representar entidades (cliente, sitio, equipo, cuadrilla,
   técnicos, integraciones). Lenguaje visual canónico para "esto es una cosa".
   Variantes: --cyan, --green, --orange, --purple, --neutral.
   Tamaños: default, --sm, --lg.
   ============================================================ */
.entity-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px 8px 12px;
  background: rgba(255,255,255,0.025);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  color: var(--text);
  font-size: var(--fs-sm);
  line-height: 1.2;
  transition: border-color var(--transition-fast), background var(--transition-fast);
  text-decoration: none;
  max-width: 100%;
}
.entity-pill:hover {
  border-color: var(--border-strong);
  background: rgba(255,255,255,0.04);
  color: var(--text);
}
.entity-pill::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--neutral);
  flex-shrink: 0;
  box-shadow: 0 0 8px currentColor;
  color: var(--neutral);
}
.entity-pill-label {
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.entity-pill-sub {
  color: var(--text-muted);
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.entity-pill--cyan::before    { background: var(--accent);  color: var(--accent); }
.entity-pill--green::before   { background: var(--success); color: var(--success); }
.entity-pill--orange::before  { background: var(--bcn-orange); color: var(--bcn-orange); }
.entity-pill--purple::before  { background: var(--purple); color: var(--purple); }
.entity-pill--red::before     { background: var(--danger); color: var(--danger); }
.entity-pill--neutral::before { background: var(--neutral); color: var(--neutral); }

.entity-pill--sm { padding: 5px 10px 5px 9px; font-size: var(--fs-xs); gap: 8px; }
.entity-pill--sm::before { width: 6px; height: 6px; }

.entity-pill--clickable { cursor: pointer; }

/* Lista de pills horizontal con wrap */
.entity-pill-row {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  align-items: center;
}

/* ============================================================
   MONO MUTED — helper tipográfico para metadata (fechas, IDs, números).
   Le da el "look techie" sin que sea ruido visual. Usar para todo
   lo que no sea texto-de-lectura: timestamps, contadores, claves.
   ============================================================ */
.text-mono-muted {
  font-family: var(--ff-mono);
  color: var(--text-muted);
  font-size: 12px;
  letter-spacing: 0.01em;
}
.text-mono-accent {
  font-family: var(--ff-mono);
  color: var(--accent);
  font-size: 12px;
  letter-spacing: 0.01em;
}

/* ============================================================
   SECTION HEADING — etiqueta tipo "DESCRIPCIÓN", "FECHAS", etc.
   Reemplaza al .card-title h6 viejo cuando queremos algo más techie.
   ============================================================ */
.section-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--ff-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}
.section-eyebrow::before {
  content: '';
  width: 4px;
  height: 4px;
  background: var(--accent);
  border-radius: 50%;
  box-shadow: 0 0 6px var(--accent);
}

/* ============================================================
   DATA ROW — par label + value en formato compacto, sin tabla.
   Reemplaza al <dl class="row"> viejo. Más legible, mejor jerarquía.
   ============================================================ */
.data-rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.data-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  border-bottom: 1px dashed rgba(255,255,255,0.05);
  padding-bottom: var(--space-3);
}
.data-row:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.data-row-label {
  font-family: var(--ff-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  flex-shrink: 0;
  width: 100px;
}
.data-row-value {
  flex: 1;
  color: var(--text);
  min-width: 0;
}
.data-row-value--mono {
  font-family: var(--ff-mono);
  color: var(--text);
  font-size: 13px;
}

/* ============================================================
   USER MENU TRIGGER — versión 2: avatar + nombre INLINE + caret.
   Sin apilar nombre/rol verticalmente. Rol es un pill chico.
   IMPORTANTE: reset agresivo porque Bootstrap mete defaults en <button>
   y nos pintaba el botón blanco.
   ============================================================ */
button.user-menu-trigger-v2,
.user-menu-trigger-v2 {
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: rgba(255,255,255,0.025) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-pill) !important;
  padding: 4px 14px 4px 4px !important;
  color: var(--text) !important;
  cursor: pointer;
  transition: all var(--transition-fast);
  font-family: var(--ff-sans);
  font-size: var(--fs-sm);
  line-height: 1.2;
  box-shadow: none !important;
}
.user-menu-trigger-v2:hover {
  border-color: var(--border-strong);
  background: rgba(255,255,255,0.05);
}
.user-menu-trigger-v2 .user-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
.user-menu-trigger-v2 .user-avatar-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-dim);
  color: var(--accent);
  font-weight: var(--fw-semibold);
  font-size: 11px;
  border: 1px solid rgba(23,171,229,0.30);
}
.user-menu-trigger-v2 .user-name-line {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-heading);
}
.user-menu-trigger-v2 .role-pill {
  font-family: var(--ff-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
  background: var(--accent-dim);
  padding: 2px 7px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(23,171,229,0.25);
}
.user-menu-trigger-v2 .caret {
  color: var(--text-muted);
  font-size: 11px;
}

/* ============================================================
   OT DETAIL HERO — header de OT con número grande + pills inline.
   Quita el aire monótono del page-header viejo.
   ============================================================ */
.ot-hero {
  position: relative;
  margin: calc(var(--page-padding-y) * -1) calc(var(--page-padding-x) * -1) var(--space-6);
  padding: var(--space-6) var(--page-padding-x) var(--space-5);
}
.ot-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(700px 280px at 0% 0%, rgba(23,171,229,0.10), transparent 70%);
  pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, #000 60%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 60%, transparent 100%);
  z-index: 0;
}
.ot-hero > * { position: relative; z-index: 1; }

.ot-hero-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--ff-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-bottom: var(--space-4);
  text-decoration: none;
}
.ot-hero-back:hover { color: var(--accent); }

.ot-hero-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5);
  flex-wrap: wrap;
}
.ot-hero-body { flex: 1; min-width: 0; }

.ot-hero-numero {
  font-family: var(--ff-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--accent);
  margin-bottom: 6px;
}
.ot-hero-title {
  font-size: 26px;
  font-weight: var(--fw-bold);
  color: var(--text-heading);
  margin: 0 0 var(--space-3);
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.ot-hero-meta {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-wrap: wrap;
}
.ot-hero-actions {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-shrink: 0;
}

/* ============================================================
   PANEL — caja interior tipo card pero más sobria, sin redondeo grande.
   Usar para secciones del OT detail (descripción, fechas, etc).
   ============================================================ */
.panel {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  position: relative;
}
.panel--accent {
  border-left: 2px solid var(--accent);
}
.panel-empty {
  color: var(--text-muted);
  font-style: italic;
  font-size: var(--fs-sm);
}

/* ============================================================
   STAT CARD v3 — Picnic Tickets vibe.
   Card oscura, número GRANDE coloreado, label uppercase muted abajo.
   Sin top accent bar, sin gradient. Variantes por color del número.
   ============================================================ */
.stat-card-v3 {
  position: relative;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-5) var(--space-5);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  transition: transform var(--transition-fast), border-color var(--transition-fast), box-shadow var(--transition-fast);
  min-height: 110px;
  justify-content: center;
}
.stat-card-v3:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: 0 12px 28px rgba(0,0,0,0.35);
}
.stat-card-v3-value {
  font-size: 38px;
  font-weight: var(--fw-bold);
  line-height: 1;
  margin-bottom: 8px;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.stat-card-v3-label {
  font-family: var(--ff-mono);
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.10em;
}

/* Variantes — color del número con drop-shadow muy sutil */
.stat-card-v3--orange .stat-card-v3-value { color: var(--bcn-orange); text-shadow: 0 0 24px var(--orange-a30); }
.stat-card-v3--cyan   .stat-card-v3-value { color: var(--accent);     text-shadow: 0 0 24px var(--accent-a30); }
.stat-card-v3--green  .stat-card-v3-value { color: var(--success);    text-shadow: 0 0 24px var(--success-a30); }
.stat-card-v3--blue   .stat-card-v3-value { color: var(--info);       text-shadow: 0 0 24px var(--info-a30); }
.stat-card-v3--white  .stat-card-v3-value { color: var(--text-heading); }
.stat-card-v3--red    .stat-card-v3-value { color: var(--danger);     text-shadow: 0 0 24px var(--danger-a30); }

/* ============================================================
   SECTION HERO — header de sección estilo Picnic Tickets.
   Icono color + título + subtítulo a la izquierda, count pill a la derecha.
   Arriba de un grid de stat-card-v3.
   ============================================================ */
.section-hero {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-2) 0 var(--space-4);
  flex-wrap: wrap;
}
.section-hero-left {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  flex: 1;
  min-width: 0;
}
.section-hero-icon {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  flex-shrink: 0;
  color: var(--accent);
  filter: drop-shadow(0 0 8px var(--accent-a40));
  margin-top: 2px;
}
.section-hero-icon--orange { color: var(--bcn-orange); filter: drop-shadow(0 0 8px var(--orange-a45)); }
.section-hero-icon--green  { color: var(--success);    filter: drop-shadow(0 0 8px var(--success-a45)); }
.section-hero-icon--purple { color: var(--purple);     filter: drop-shadow(0 0 8px var(--purple-a45)); }
.section-hero-body { flex: 1; min-width: 0; }
.section-hero-title {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  color: var(--text-heading);
  margin: 0;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.section-hero-sub {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  margin: 4px 0 0;
}
.section-hero-count {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(255,255,255,0.025);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 6px 14px;
  font-family: var(--ff-mono);
  font-size: 12px;
  color: var(--text);
  letter-spacing: 0.04em;
  flex-shrink: 0;
}
.section-hero-count strong { color: var(--text-heading); font-weight: var(--fw-semibold); }

.section-hero + .row { margin-top: 0; }

/* Separador sutil entre secciones del dashboard */
.section-divider {
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--border) 20%, var(--border) 80%, transparent);
  margin: var(--space-7) 0 var(--space-5);
}

/* ============================================================
   CHECKLIST — basado en hub-roadmap (cuestionario-reunion/hub v2.html).
   Forma canónica. Cada item es una row redondeada con marker 32px + body
   jerarquizado (título bold + status pill + fecha mono + descripción muted).
   Línea vertical conecta los markers, verde si el anterior está done.
   ============================================================ */
.checklist-tl {
  display: flex;
  flex-direction: column;
  gap: 0;
  position: relative;
  margin: var(--space-3) 0 0;
  padding: 0;
}
.checklist-tl-item {
  display: flex;
  gap: 16px;
  padding: 16px 12px;
  margin: 0 -12px;
  border-radius: 10px;
  position: relative;
  cursor: pointer;
  transition: background var(--transition-fast);
}
.checklist-tl-item:hover {
  background: var(--accent-a05);
}
.checklist-tl-item--urgent:not(.checklist-tl-item--done):hover {
  background: var(--danger-a06);
}
/* Línea vertical entre markers */
.checklist-tl-item:not(:last-child)::before {
  content: '';
  position: absolute;
  left: 28px;        /* 12px padding + 16px (centro del marker 32px) */
  top: 56px;         /* 16px padding + 32px marker + 8px gap */
  bottom: -4px;
  width: 2px;
  background: var(--border);
}
.checklist-tl-item--done:not(:last-child)::before {
  background: var(--success);
}

.checklist-tl-dot {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: var(--fw-bold);
  font-family: var(--ff-mono);
  border: 2px solid var(--border);
  background: var(--bg-card);
  color: var(--text-muted);
  z-index: 1;
  transition: all var(--transition-base);
}
.checklist-tl-item--done .checklist-tl-dot {
  background: var(--success);
  border-color: var(--success);
  color: var(--text-on-color);
}
.checklist-tl-item--current .checklist-tl-dot,
.checklist-tl-item:not(.checklist-tl-item--done):not(.checklist-tl-item--urgent):hover .checklist-tl-dot {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-on-color);
  box-shadow: 0 0 0 4px var(--accent-a20);
}
.checklist-tl-item--urgent:not(.checklist-tl-item--done) .checklist-tl-dot {
  background: var(--danger);
  border-color: var(--danger);
  color: var(--text-on-color);
  box-shadow: 0 0 0 4px var(--danger-a18);
  animation: tl-pulse 2s ease-in-out infinite;
}
@keyframes tl-pulse {
  0%, 100% { box-shadow: 0 0 0 4px var(--danger-a20); }
  50%      { box-shadow: 0 0 0 8px var(--danger-a10); }
}

.checklist-tl-body {
  flex: 1;
  min-width: 0;
}
.checklist-tl-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.checklist-tl-title {
  font-size: 15px;
  font-weight: var(--fw-bold);
  color: var(--text-heading);
}
.checklist-tl-item--done .checklist-tl-title {
  color: var(--text-muted);
}
.checklist-tl-status {
  font-size: 10px;
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  line-height: 1;
}
.checklist-tl-status--done    { background: var(--success-a15); color: var(--success); }
.checklist-tl-status--pending { background: var(--neutral-dim); color: var(--text-muted); }
.checklist-tl-status--urgent  { background: var(--danger-a15);  color: var(--danger); }
.checklist-tl-date {
  font-size: 11px;
  font-family: var(--ff-mono);
  color: var(--text-muted);
}
.checklist-tl-detalle {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.55;
}
.checklist-tl-item--done .checklist-tl-detalle {
  opacity: 0.7;
}
.checklist-tl-actions {
  display: flex;
  gap: 2px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity var(--transition-fast);
  align-self: flex-start;
}
.checklist-tl-item:hover .checklist-tl-actions { opacity: 1; }

/* Checkbox oculto — el dot/row es el control real (click toggle done) */
.checklist-tl-item input[type=checkbox] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

/* ===========================================================
   ATTACHMENTS GRID (fotos subidas desde bot/miniapps)
   =========================================================== */
.attachments-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
}
.attachment-tile {
  position: relative;
  display: block;
  border-radius: 10px;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--bg-card);
  border: 1px solid var(--border);
  text-decoration: none;
  transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}
.attachment-tile:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
}
.attachment-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.attachment-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 6px 10px;
  font-size: 12px;
  line-height: 1.3;
  color: #fff;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));
  font-family: var(--font-mono);
}
.attachment-tile--file {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 6px;
  color: var(--text-muted);
}
.attachment-tile--file i { font-size: 28px; }
.attachment-filename {
  font-size: 11px;
  font-family: var(--font-mono);
  max-width: 90%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* =========================================================================
   OT DETAIL — hero enriquecido, descripción jerarquizada, notas chat-style
   ========================================================================= */

/* Asignación embebida en el hero (reemplaza el card lateral aislado) */
.ot-hero-assign {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}
.section-eyebrow--inline {
  margin: 0 !important;
  font-size: 10px;
  flex-shrink: 0;
}

/* Descripción con más aire y tipografía jerarquizada */
.ot-description {
  font-size: 15px;
  line-height: 1.7;
  color: var(--text-primary);
  white-space: pre-wrap;
  letter-spacing: 0.005em;
}

/* =========================================================================
   CHAT THREAD — notas del técnico como mensajes de chat
   ========================================================================= */
.chat-thread {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: 520px;
  overflow-y: auto;
  padding-right: 6px;
}
.chat-msg {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.chat-msg-avatar {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
.chat-msg-bubble {
  flex: 1;
  min-width: 0;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 4px 14px 14px 14px;
  padding: 10px 14px 12px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
.chat-msg-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 4px;
  flex-wrap: wrap;
}
.chat-msg-author {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
}
.chat-msg-time {
  font-size: 11px;
  font-family: var(--font-mono);
  color: var(--text-muted);
}
.chat-msg-text {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-secondary);
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* Variante audio: notas generadas desde las mini apps con el AudioRecorder */
.chat-msg--audio .chat-msg-bubble {
  background: linear-gradient(180deg, rgba(220, 38, 38, 0.06) 0%, rgba(255, 255, 255, 0.04) 40%);
  border-color: rgba(220, 38, 38, 0.22);
}
.chat-msg-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(220, 38, 38, 0.14);
  color: #fca5a5;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-left: auto;
}
.chat-msg-badge i { font-size: 10px; }
.chat-msg-summary {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-primary);
  font-style: italic;
  padding: 8px 10px;
  background: rgba(37, 99, 235, 0.08);
  border-left: 2px solid rgba(37, 99, 235, 0.5);
  border-radius: 4px;
  margin-bottom: 8px;
}
.chat-msg-audio {
  display: block;
  width: 100%;
  margin-top: 8px;
  height: 36px;
  border-radius: 8px;
}
.chat-msg-audio::-webkit-media-controls-panel {
  background: rgba(255, 255, 255, 0.05);
}
.chat-msg-transcript {
  margin-top: 8px;
  background: rgba(0, 0, 0, 0.22);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  padding: 6px 10px;
}
.chat-msg-transcript summary {
  cursor: pointer;
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 600;
  list-style: none;
  user-select: none;
}
.chat-msg-transcript summary::-webkit-details-marker { display: none; }
.chat-msg-transcript summary::before { content: '▸ '; margin-right: 2px; }
.chat-msg-transcript[open] summary::before { content: '▾ '; }
.chat-msg-transcript-text {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-secondary);
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* =========================================================================
   ACTIVITY TIMELINE — feed de cambios de una OT (ots-detail.js)
   ========================================================================= */
.activity-feed {
  display: flex;
  flex-direction: column;
  gap: 0;
  position: relative;
}
.activity-item {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 12px;
  padding: 10px 0;
  position: relative;
}
.activity-item::before {
  /* línea vertical que conecta los dots */
  content: '';
  position: absolute;
  left: 15px;
  top: 28px;
  bottom: -6px;
  width: 2px;
  background: var(--border-subtle, rgba(255,255,255,0.08));
}
.activity-item:last-child::before { display: none; }
.activity-dot {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--bg-elevated, #2a2a2a);
  border: 2px solid var(--border-subtle, rgba(255,255,255,0.1));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--text-secondary);
  z-index: 1;
  flex-shrink: 0;
}
.activity-body {
  min-width: 0;
  padding-top: 4px;
}
.activity-text {
  font-size: 14px;
  line-height: 1.45;
  color: var(--text-primary);
  word-wrap: break-word;
}
.activity-text strong { font-weight: 600; }
.activity-time {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
  font-family: var(--font-mono, monospace);
}

/* Color variants por tipo de actividad */
.activity-item.act--create    .activity-dot { color: #7ee787; border-color: rgba(126,231,135,0.4); }
.activity-item.act--edit      .activity-dot { color: #79c0ff; border-color: rgba(121,192,255,0.4); }
.activity-item.act--state     .activity-dot { color: #d2a8ff; border-color: rgba(210,168,255,0.4); }
.activity-item.act--assign    .activity-dot { color: #ffa657; border-color: rgba(255,166,87,0.4); }
.activity-item.act--note      .activity-dot { color: #a5d6ff; border-color: rgba(165,214,255,0.4); }
.activity-item.act--photo     .activity-dot { color: #56d364; border-color: rgba(86,211,100,0.4); }
.activity-item.act--audio     .activity-dot { color: #ff7b72; border-color: rgba(255,123,114,0.4); }
.activity-item.act--cl-add    .activity-dot { color: #79c0ff; border-color: rgba(121,192,255,0.4); }
.activity-item.act--cl-done   .activity-dot { color: #56d364; border-color: rgba(86,211,100,0.4); }
.activity-item.act--cl-undo   .activity-dot { color: #8b949e; border-color: rgba(139,148,158,0.4); }
.activity-item.act--hours     .activity-dot { color: #ffa657; border-color: rgba(255,166,87,0.4); }
.activity-item.act--mat       .activity-dot { color: #d2a8ff; border-color: rgba(210,168,255,0.4); }
.activity-item.act--danger    .activity-dot { color: #f85149; border-color: rgba(248,81,73,0.4); }
.activity-item.act--neutral   .activity-dot { color: var(--text-muted); }

/* =========================================================================
   OT LOCATION PATH — breadcrumb cliente › sitio › ubicación (NO pills)
   ========================================================================= */
.ot-loc-path {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  margin-top: 18px;
}
.ot-loc-item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.ot-loc-icon {
  font-size: 16px;
  color: var(--text-muted);
  flex-shrink: 0;
}
.ot-loc-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.2;
}
.ot-loc-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--text-muted);
}
.ot-loc-value {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ot-loc-sep {
  color: var(--text-muted);
  opacity: 0.5;
  font-size: 12px;
}

/* Asignación en hero — eyebrow arriba, pills abajo (alineación correcta) */
.ot-hero-assign {
  display: block;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.ot-hero-assign .section-eyebrow {
  display: block;
  margin: 0 0 8px 0;
}
/* block wrapper — no flex acá porque los hijos (spans sueltos + .entity-pill-row)
   ya se reparten en sus propias filas. Un flex externo los mete en línea
   y rompe la alineación. */
.ot-hero-assign-body { display: block; }
.ot-hero-assign-body > .entity-pill { margin-right: 6px; }

/* =========================================================================
   CHECKLIST DRAG & DROP
   ========================================================================= */
/* Grip absoluto sobre el borde izquierdo — NO participa del flex row, así el
   dot/línea del timeline mantienen sus coordenadas originales. */
.checklist-tl-grip {
  position: absolute;
  left: -8px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  cursor: grab;
  font-size: 16px;
  opacity: 0;
  transition: opacity 0.15s;
  z-index: 2;
}
.checklist-tl-item:hover .checklist-tl-grip { opacity: 0.7; }
.checklist-tl-grip:hover { opacity: 1 !important; }
.checklist-tl-grip:active { cursor: grabbing; }
.checklist-tl-item[draggable="true"] { cursor: default; }
.checklist-tl-item.dragging {
  opacity: 0.4;
}
.checklist-tl-item.drop-above {
  box-shadow: 0 -2px 0 0 var(--brand-primary, #4f46e5);
}
.checklist-tl-item.drop-below {
  box-shadow: 0 2px 0 0 var(--brand-primary, #4f46e5);
}

/* Checklist agrupado por unidad (OT con varias unidades): un bloque por
   unidad + "General", cada uno con encabezado, progreso y "+ Agregar". */
.checklist-bloques {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.checklist-bloque + .checklist-bloque {
  border-top: 1px solid var(--border);
  padding-top: var(--space-4);
}
.checklist-bloque-head {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.checklist-bloque-icon {
  font-size: 16px;
  color: var(--text-muted);
  flex-shrink: 0;
}
.checklist-bloque-text {
  flex: 1;
  min-width: 0;
  line-height: 1.25;
}
.checklist-bloque-title {
  font-weight: 600;
  color: var(--text);
  overflow-wrap: anywhere;
}
.checklist-bloque-sub {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}
.checklist-bloque-count {
  font-family: var(--ff-mono);
  font-size: 12px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.checklist-bloque-count--done { color: var(--success); }
.checklist-bloque-add { flex-shrink: 0; font-size: 13px; white-space: nowrap; }
.checklist-bloque .checklist-tl { margin-top: var(--space-2); }
.checklist-bloque-empty { padding: var(--space-2) 0 0 26px; }

/* Card "Unidades" del detalle de OT: una fila clickeable por unidad. */
.ot-unidades-list {
  display: flex;
  flex-direction: column;
}
.ot-unidad-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 10px 0;
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dashed rgba(255,255,255,0.05);
}
.ot-unidad-row:last-child { border-bottom: none; padding-bottom: 0; }
.ot-unidad-row:first-child { padding-top: 0; }
.ot-unidad-row:hover .ot-unidad-title > span:first-child { color: var(--accent); }
.ot-unidad-main { flex: 1; min-width: 0; }
.ot-unidad-title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  font-weight: 600;
  color: var(--text);
}
.ot-unidad-inst { font-weight: 400; color: var(--text-muted); }
.ot-unidad-sub {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  margin-top: 2px;
  overflow-wrap: anywhere;
}
.ot-unidad-chevron { color: var(--text-muted); opacity: 0.6; flex-shrink: 0; }

/* =========================================================================
   SORTABLE TABLE HEADERS (ots-list.js)
   -------------------------------------------------------------------------
   Headers clickeables con indicador de dirección. La columna activa muestra
   el caret filled (up/down según sortDir); las inactivas un caret down mate.
   ========================================================================= */
th.th-sort {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: color 0.12s ease, background 0.12s ease;
}
th.th-sort:hover { color: var(--text-heading, #f0f2f8); }
th.th-sort i {
  font-size: 0.85em;
  margin-left: 4px;
  opacity: 0.4;
  transition: opacity 0.12s ease;
}
th.th-sort:hover i { opacity: 0.75; }
th.th-sort--active {
  color: var(--text-heading, #f0f2f8);
}
th.th-sort--active i {
  opacity: 1;
  color: var(--accent, #17abe5);
}

/* =========================================================================
   TOOLBAR variant para /ots — tabs + filtros inline sin que se apilen
   ========================================================================= */
.toolbar--ots {
  align-items: center;
}
.toolbar--ots .tabs {
  flex: 0 1 auto;      /* tabs no crecen infinito; shrink OK */
  min-width: 0;
  overflow-x: auto;    /* en viewport angosto, scrollea en vez de wrappear */
  overflow-y: hidden;  /* evita que Chrome muestre scroll vertical vacío */
  scrollbar-width: none;     /* Firefox */
  -ms-overflow-style: none;  /* IE/Edge viejo */
}
.toolbar--ots .tabs::-webkit-scrollbar { display: none; width: 0; height: 0; }
.toolbar-actions--ots {
  flex-wrap: nowrap;   /* filtros siempre en la misma fila */
  flex: 0 0 auto;
  margin-left: auto;   /* los pega a la derecha cuando queda espacio */
}
.toolbar-actions--ots .form-select,
.toolbar-actions--ots .form-control {
  width: auto;
  min-width: 160px;
}
.toolbar-actions--ots .form-select { max-width: 220px; }
.toolbar-actions--ots .form-control { max-width: 220px; }

/* En viewport angosto caen abajo como un bloque completo, no intercalados */
@media (max-width: 860px) {
  .toolbar--ots {
    flex-direction: column;
    align-items: stretch;
  }
  .toolbar-actions--ots {
    margin-left: 0;
    width: 100%;
  }
  .toolbar-actions--ots .form-select,
  .toolbar-actions--ots .form-control {
    flex: 1 1 0;
    max-width: none;
  }
}

/* =========================================================================
   SUB-FILTERS — fila secundaria de filtros, estilo ghost sutil
   -------------------------------------------------------------------------
   Se muestra ABAJO de la toolbar principal (tabs + search). Los filtros
   acá no compiten visualmente con los tabs — son texto + dropdown nativo
   sin chrome. Se parecen más a breadcrumbs que a form-controls.
   ========================================================================= */
/* =========================================================================
   SUB-FILTERS — fila secundaria de filtros (ghost, consistente con el site).
   -------------------------------------------------------------------------
   El site override de `.form-select` en línea 295 usa `background:` shorthand
   que NUKE el background-image SVG del chevron de Bootstrap. Acá lo
   restauramos manualmente con el mismo SVG que Bootstrap usa en dark mode,
   y forzamos display:flex para que label+select queden en la misma línea.
   ========================================================================= */
.sub-filters {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-5, 24px);
  padding: var(--space-3) 2px var(--space-4);
  font-size: 13px;
}
.sub-filter {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  cursor: pointer;
}
.sub-filter-label {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
  user-select: none;
  white-space: nowrap;
}

/* Restauramos el chevron (SVG inline). El color queda via CSS var para que
   matchee text-muted del site. Si en el futuro cambia el token, cambia acá. */
.sub-filter-select.form-select {
  width: auto;
  min-width: 240px;
  max-width: 320px;
  background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%238b90a5' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 14px;
  border: 1px solid var(--border);
  color: var(--text);
  padding: 6px 34px 6px 12px;   /* right padding > chevron size */
  font-size: 13px;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}
.sub-filter-select.form-select:hover {
  background-color: var(--bg-hover, rgba(255,255,255,0.04));
  border-color: var(--border-focus, var(--accent, #17abe5));
}
.sub-filter-select.form-select:focus {
  background-color: var(--bg-hover, rgba(255,255,255,0.04));
  border-color: var(--border-focus, var(--accent, #17abe5));
  box-shadow: 0 0 0 3px var(--accent-dim, rgba(23,171,229,0.12));
  outline: none;
}

.sub-filter-clear {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 500;
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background 0.12s ease, color 0.12s ease;
}
.sub-filter-clear:hover {
  background: var(--bg-hover, rgba(255,255,255,0.04));
  color: var(--text);
}
.sub-filter-clear i { font-size: 11px; }

/* =========================================================================
   ENTITY CARDS — listas como cards en mobile (<= 640px). Markup en
   js/cards.js. En desktop manda la tabla (.ent-table) y las cards no se
   renderizan (display:none). Franja izquierda via --card-strip.
   ========================================================================= */
.ent-cards { display: none; }
.sub-filter--cards-only { display: none; }
.ent-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--card-strip, var(--border-strong));
  border-radius: var(--radius-md);
  padding: 12px 14px 10px;
  color: var(--text);
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.ent-card[data-href] { cursor: pointer; }
.ent-card[data-href]:hover,
.ent-card[data-href]:active { background: var(--bg-hover); border-color: var(--border-strong); border-left-color: var(--card-strip, var(--border-strong)); }
.ent-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ent-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 16px;
}
.ent-card-eyebrow {
  font-family: var(--ff-mono);
  font-size: 11px;
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ent-card-badge { flex-shrink: 0; display: inline-flex; align-items: center; }
.ent-card-estado { font-size: 11px; }
.ent-card-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ent-card-headtext { min-width: 0; flex: 1; }
.ent-card-avatar { flex-shrink: 0; display: flex; }
.ent-card-avatar .tecnico-foto-thumb { width: 40px; height: 40px; }
.ent-card-title {
  font-size: 15px;
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ent-card-title .criticidad-pill,
.ent-card-title .role-badge,
.ent-card-title .pill { vertical-align: middle; margin-left: 4px; }
.ent-card-sub { font-size: 12px; color: var(--text-muted); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; }
.ent-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 3px 14px;
  font-size: 12px;
  color: var(--text-muted);
  min-width: 0;
}
.ent-card-meta > span { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.ent-card-meta > span:first-child { color: var(--text); font-weight: var(--fw-medium); }
.ent-card-meta i { font-size: 11px; opacity: 0.7; }
.ent-card-pills { display: flex; flex-wrap: wrap; gap: 4px; }
.ent-card-foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin-top: 2px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-muted);
}
.ent-card-foot > span { display: inline-flex; align-items: center; gap: 5px; }
.ent-card-muted { color: var(--text-muted); }
.ent-card-foot-end {
  margin-left: auto;
  font-family: var(--ff-mono);
  font-size: 11px;
  white-space: nowrap;
}
.ent-card-foot-end i { margin-right: 5px; opacity: 0.7; }
.ent-card-actions { margin-left: auto; gap: 4px; }
.ent-card-foot-end + .ent-card-actions { margin-left: 8px; }
/* Acciones: separadas en su propia fila cuando hay muchas */
.ent-card-actions .btn, .ent-card-actions .btn-ghost { min-height: 36px; min-width: 36px; }

@media (max-width: 640px) {
  .ent-table { display: none; }
  .ent-cards { display: flex; flex-direction: column; gap: var(--space-3); }
  .sub-filter--cards-only { display: flex; }
}

/* =========================================================================
   AGENDA DEL DÍA (home.js)
   -------------------------------------------------------------------------
   Sección con navegación por día (← Hoy →) + grid responsive de OT cards.
   Las cards tienen una franja vertical izquierda que refleja la prioridad
   (mismo patrón visual que .ot-row de la lista de OTs).
   ========================================================================= */
.agenda-block {
  margin-bottom: var(--space-5, 24px);
}
.agenda-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}
.agenda-title {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-heading, #f0f2f8);
}
.agenda-title i { color: var(--accent, #17abe5); font-size: 18px; }
.agenda-nav {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.agenda-nav-btn {
  appearance: none;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1;
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
}
.agenda-nav-btn:hover {
  background: var(--bg-hover, rgba(255,255,255,0.04));
  border-color: var(--border-focus, var(--accent, #17abe5));
  color: var(--text);
}
.agenda-nav-today {
  min-width: auto;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.agenda-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--space-3);
}
.agenda-loading,
.agenda-error,
.agenda-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 32px 16px;
  color: var(--text-muted);
  background: var(--bg-card);
  border: 1px dashed var(--border);
  border-radius: var(--radius, 10px);
}
.agenda-empty i { display: block; font-size: 28px; margin-bottom: 8px; opacity: 0.6; }
.agenda-error { color: #fca5a5; border-color: rgba(239,68,68,0.3); }

.agenda-card {
  position: relative;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: var(--radius, 10px);
  padding: 14px 14px 12px;
  cursor: pointer;
  transition: border-color 0.12s ease, transform 0.12s ease, background 0.12s ease;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.agenda-card:hover {
  border-color: var(--border-focus, var(--accent, #17abe5));
  transform: translateY(-1px);
}
.agenda-card:focus-visible {
  outline: 2px solid var(--accent, #17abe5);
  outline-offset: 2px;
}

/* Franja vertical izquierda según prioridad (alineado con .ot-row) */
.agenda-card--urgente { border-left-color: #ef4444; }
.agenda-card--alta    { border-left-color: #f59e0b; }
.agenda-card--normal  { border-left-color: #17abe5; }
.agenda-card--baja    { border-left-color: #64748b; }

.agenda-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.agenda-card-num {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.agenda-card-estado { font-size: 10px; }

.agenda-card-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-heading, #f0f2f8);
  line-height: 1.35;
  /* 2-line clamp */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.agenda-card-meta {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 12px;
  color: var(--text-muted);
}
.agenda-card-meta i {
  margin-right: 5px;
  opacity: 0.7;
  font-size: 11px;
}
.agenda-card-cliente,
.agenda-card-sitio {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.agenda-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}
.agenda-card-hora {
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* ---------- Pills (badges compactos) ---------- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: 10px;
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  line-height: 1.4;
  white-space: nowrap;
}
.pill--muted   { background: rgba(255,255,255,0.06); color: var(--text-muted); border: 1px solid rgba(255,255,255,0.08); }
.pill--warning { background: rgba(245, 158, 11, 0.12); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.25); }
.pill--danger  { background: rgba(239, 68, 68, 0.12); color: #fca5a5; border: 1px solid rgba(239, 68, 68, 0.25); }
.pill--info    { background: var(--accent-dim); color: var(--accent); border: 1px solid rgba(23,171,229,0.25); }

/* ---------- Source badges (cascada de plantilla de checklist) ----------
   Indican el nivel en el que un ChecklistFieldDefinition está definido:
   global preset (gris), equipo (azul), unidad (verde). El badge "override"
   en naranja se muestra adicional cuando una def reemplaza una heredada
   con mismo slug. Más fuerte que un .pill normal para que la columna
   "Fuente" sea legible de un vistazo. */
.source-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: 10px;
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-wide);
  line-height: 1.4;
  white-space: nowrap;
}
.source-badge + .source-badge { margin-left: 4px; }
.source-badge--global   { background: rgba(255,255,255,0.06); color: var(--text-muted); border: 1px solid rgba(255,255,255,0.10); }
.source-badge--equipo   { background: rgba(23, 171, 229, 0.12); color: #5dc7f1;        border: 1px solid rgba(23, 171, 229, 0.30); }
.source-badge--unidad   { background: rgba(34, 197, 94, 0.12);  color: #4ade80;        border: 1px solid rgba(34, 197, 94, 0.30); }
.source-badge--override { background: rgba(245, 158, 11, 0.14); color: #fbbf24;        border: 1px solid rgba(245, 158, 11, 0.32); text-transform: uppercase; }

/* ---------- Checklist preview en form de creación de OT ----------
   Sección que muestra qué items se van a materializar al guardar la OT,
   con edits inline (modal `ot_preview`). Más compacto que el timeline
   del checklist en OT detail porque acá no hay valor / estado / actions
   de ejecución — sólo metadata de la definición. */
.ot-checklist-prev-card--disabled .card-body { opacity: 0.6; }
.ot-checklist-prev-item {
  padding: 10px 12px;
  border: 1px solid var(--border, rgba(255,255,255,0.08));
  border-radius: var(--radius, 8px);
  background: rgba(255,255,255,0.02);
}
.ot-checklist-prev-item .min-w-0 { min-width: 0; }

/* Bloque plegable por unidad (o "General") dentro del preview. */
.ot-cl-block {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-card-soft);
}
.ot-cl-block-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  min-height: 48px;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: 0;
  color: var(--text);
  text-align: left;
  border-radius: var(--radius-md);
}
.ot-cl-block-head:hover { background: var(--bg-hover); }
.ot-cl-block-head .min-w-0,
.ot-pick-row .min-w-0 { min-width: 0; }
.ot-cl-block-body { padding: 0 var(--space-3) var(--space-3); }
.ot-fold-chev { transition: transform 0.15s ease; flex-shrink: 0; color: var(--text-muted); }
.ot-cl-block.is-open > .ot-cl-block-head .ot-fold-chev,
.ot-unid-zona.is-open .ot-unid-zona-toggle .ot-fold-chev { transform: rotate(90deg); }

/* ---------- Selección de sitios / unidades en form de OT ----------
   Filas completas clickeables (target táctil ≥44px), checkbox a la
   izquierda. Las unidades van en un árbol Zona → Ubicación plegable. */
.ot-pick-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ot-pick-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  margin: 0;
  padding: 6px var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255,255,255,0.02);
  cursor: pointer;
  user-select: none;
}
.ot-pick-row:hover { background: var(--bg-hover); }
.ot-pick-row.is-checked {
  border-color: rgba(var(--accent-rgb), 0.45);
  background: var(--accent-dim);
}
.ot-pick-row .form-check-input { margin: 0; flex-shrink: 0; }
.ot-pick-row--unid { border-color: transparent; background: transparent; padding-left: var(--space-2); }

.ot-unid-tree { display: flex; flex-direction: column; gap: var(--space-3); }
.ot-unid-sitio { display: flex; flex-direction: column; gap: var(--space-2); }
.ot-unid-sitio-title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-heading);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}
.ot-unid-zona {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-card-soft);
}
.ot-unid-zona-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-right: var(--space-3);
}
.ot-unid-zona-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: 0;
  color: var(--text);
  font-weight: var(--fw-medium);
  text-align: left;
  border-radius: var(--radius-md);
}
.ot-unid-zona-toggle:hover { background: var(--bg-hover); }
.ot-unid-zona-count {
  margin-left: auto;
  flex-shrink: 0;
  font-size: var(--fs-xs);
  color: var(--text-muted);
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  background: var(--neutral-dim);
}
.ot-unid-zona-count.has-sel { color: var(--accent); background: var(--accent-dim); }
.ot-unid-all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  min-height: 44px;
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
}
.ot-unid-all .form-check-input { margin: 0; }
.ot-unid-all--sm { min-height: 36px; font-size: var(--fs-xs); }
.ot-unid-zona-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: 0 var(--space-3) var(--space-3);
}
.ot-unid-ubic {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-left: var(--space-2);
  border-left: 2px solid var(--border);
}
.ot-unid-ubic-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-width: 0;
  padding-left: var(--space-2);
}
/* En desktop el árbol scrollea dentro de su caja si es muy largo; en
   mobile fluye con la página (scroll anidado en touch es incómodo). */
@media (min-width: 768px) {
  .ot-unid-tree { max-height: 460px; overflow-y: auto; padding-right: 2px; }
}

/* ---------- Marca pills (filtro rápido por marca en Equipos) ---------- */
.marca-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 4px 0;
}
.marca-pill {
  --pill-bg: #4a5568;
  --pill-fg: #ffffff;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px 6px 14px;
  border-radius: var(--radius-pill);
  background: rgba(255,255,255,0.04);
  color: var(--text-muted);
  border: 1px solid rgba(255,255,255,0.08);
  font-size: 12px;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.02em;
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.12s;
  cursor: pointer;
  position: relative;
}
.marca-pill::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pill-bg);
  display: inline-block;
  flex-shrink: 0;
}
.marca-pill[data-marca=""]::before { display: none; }
.marca-pill:hover {
  background: rgba(255,255,255,0.08);
  color: var(--text);
  border-color: rgba(255,255,255,0.14);
  transform: translateY(-1px);
}
.marca-pill--active {
  background: var(--pill-bg);
  color: var(--pill-fg);
  border-color: var(--pill-bg);
  box-shadow: 0 4px 14px rgba(0,0,0,0.25);
}
.marca-pill--active::before {
  background: rgba(255,255,255,0.7);
}
.marca-pill[data-marca=""].marca-pill--active {
  background: var(--accent);
  color: var(--text-invert);
  border-color: var(--accent);
}
.marca-pill-count {
  font-size: 10px;
  font-weight: var(--fw-bold);
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  background: rgba(255,255,255,0.1);
  color: inherit;
}
.marca-pill--active .marca-pill-count {
  background: rgba(255,255,255,0.22);
}

/* ---------- Grilla de fotos de Unidad ---------- */
.unidad-fotos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 8px;
}
.unidad-foto {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--bg-sunken);
}
.unidad-foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.unidad-foto-del {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(0,0,0,0.6);
  color: #fff;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s;
}
.unidad-foto:hover .unidad-foto-del { opacity: 1; }
.unidad-foto-del:hover { background: rgba(239, 68, 68, 0.9); }

/* ---------- Tecnico foto (lista + modal) ---------- */
.tecnico-foto-thumb {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg-elev-1);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 18px;
  flex-shrink: 0;
}
.tecnico-foto-thumb--empty { border: 1px dashed var(--border); }

.tecnico-foto-preview {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--bg-elev-1);
  border: 1px dashed var(--border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  color: var(--text-muted);
  font-size: 32px;
  flex-shrink: 0;
}
.tecnico-foto-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Role-badge variantes para empresa de técnico */
.role-badge--externo {
  background: rgba(245, 158, 11, 0.15);
  color: rgb(245, 158, 11);
}
.role-badge--inst {
  background: rgba(56, 189, 248, 0.15);
  color: rgb(56, 189, 248);
}

/* ---------- Criticidad pill ---------- */
.criticidad-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}
.criticidad-pill--confort {
  background: var(--estado-completada-dim);
  color: var(--estado-completada);
}
.criticidad-pill--critico {
  background: var(--estado-cancelada-dim, rgba(239, 68, 68, 0.15));
  color: var(--estado-cancelada, rgb(239, 68, 68));
}

/* ---------- Vehiculo service alerts ---------- */
.service-alert {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}
.service-alert--warn {
  background: rgba(245, 158, 11, 0.15);
  color: rgb(245, 158, 11);
}
.service-alert--danger {
  background: rgba(239, 68, 68, 0.15);
  color: rgb(239, 68, 68);
}

/* ============================================================
   CHECKLIST WIDGETS — 8 tipos de captura (boolean, tri_state,
   selector, numeric, multi_numeric, text, photo, signature).
   Reusan tokens de tokens.css (--success/--warning/--danger).
   ============================================================ */

/* Item moderno: estructura general */
.checklist-tl-item--widget {
  cursor: default;
  flex-direction: row;
  align-items: stretch;
}
.checklist-tl-item--required-missing {
  border-left: 3px solid var(--danger);
  padding-left: 12px;
}
.checklist-tl-item--flash {
  background: var(--warning-dim) !important;
  transition: background var(--transition-base);
}

/* Badges chiquitos al lado del título */
.checklist-badges {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-left: 8px;
}
.checklist-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  background: var(--bg-hover);
  color: var(--text-muted);
}
.checklist-badge--urgent  { background: var(--danger-a15);  color: var(--danger); }
.checklist-badge--required { background: var(--accent-a05); color: var(--accent); }
.checklist-badge--hidden   { background: var(--bg-hover);   color: var(--text-muted); font-style: italic; }

/* Body del widget — espacio común */
.checklist-widget-body {
  margin-top: 10px;
}
.checklist-widget-footer {
  margin-top: 8px;
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

/* Comentario opcional bajo cada widget */
.checklist-widget-comment {
  margin-top: 8px;
}
.checklist-widget-comment-input {
  font-size: var(--fs-sm);
}

/* Row legacy (boolean viejo) */
.checklist-legacy-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* --- BOOLEAN moderno --- */
.checklist-widget-bool {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

/* --- TRI_STATE: pass / flag / fail --- */
.checklist-widget-tri {
  display: inline-flex;
  gap: 6px;
}
.checklist-tri-btn {
  padding: 6px 14px;
  border-radius: var(--radius-md);
  border: 1.5px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-sm);
  cursor: pointer;
  transition: all var(--transition-fast);
}
.checklist-tri-btn:hover { border-color: var(--text-muted); }
.checklist-tri-btn--pass.is-selected { background: var(--success-dim); border-color: var(--success); color: var(--success); }
.checklist-tri-btn--flag.is-selected { background: var(--warning-dim); border-color: var(--warning); color: var(--warning); }
.checklist-tri-btn--fail.is-selected { background: var(--danger-dim);  border-color: var(--danger);  color: var(--danger);  }

/* --- SELECTOR --- */
.checklist-widget-selector {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 320px;
}
.checklist-selector-badge {
  display: inline-block;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1px solid var(--border);
}

/* --- NUMERIC / MULTI_NUMERIC --- */
.checklist-widget-numeric, .checklist-widget-multi {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.checklist-num-row {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.checklist-num-input {
  display: inline-flex;
  align-items: center;
  background: var(--bg-card);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0 8px;
  max-width: 160px;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.checklist-num-input input {
  border: none;
  background: transparent;
  width: 100%;
  padding: 6px 4px;
  color: var(--text);
}
.checklist-num-input input:focus { outline: none; box-shadow: none; }
.checklist-num-unit {
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
}
.checklist-num-input--ok       { border-color: var(--success); background: var(--success-dim); }
.checklist-num-input--warn     { border-color: var(--warning); background: var(--warning-dim); }
.checklist-num-input--critical { border-color: var(--danger);  background: var(--danger-dim);  }
.checklist-num-input--empty    { /* default */ }
.checklist-num-dot {
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--border);
}
.checklist-num-dot--ok       { background: var(--success); }
.checklist-num-dot--warn     { background: var(--warning); }
.checklist-num-dot--critical { background: var(--danger);  }
.checklist-num-range {
  font-size: var(--fs-xs);
  color: var(--text-muted);
}
.checklist-multi-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.checklist-multi-slot {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.checklist-multi-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  font-family: var(--ff-mono);
}
.checklist-desbalance {
  padding: 6px 10px;
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
  display: inline-block;
  align-self: flex-start;
}
.checklist-desbalance--ok       { background: var(--success-dim); color: var(--success); }
.checklist-desbalance--warn     { background: var(--warning-dim); color: var(--warning); }
.checklist-desbalance--critical { background: var(--danger-dim);  color: var(--danger);  }

/* --- TEXT --- */
.checklist-widget-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: 540px;
}
.checklist-text-counter {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  align-self: flex-end;
  font-family: var(--ff-mono);
}

/* --- PHOTO --- */
.checklist-widget-photo {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.checklist-photo-grid {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.checklist-photo-thumb {
  position: relative;
  width: 72px; height: 72px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--border);
}
.checklist-photo-thumb img {
  width: 100%; height: 100%; object-fit: cover;
}
.checklist-photo-remove {
  position: absolute;
  top: 2px; right: 2px;
  width: 20px; height: 20px;
  border-radius: 50%;
  border: none;
  background: rgba(0,0,0,0.65);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  font-size: 12px;
}
.checklist-photo-add {
  width: 72px; height: 72px;
  border-radius: var(--radius-sm);
  border: 1.5px dashed var(--border);
  background: transparent;
  color: var(--text-muted);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 2px;
  cursor: pointer;
  font-size: var(--fs-xs);
  transition: all var(--transition-fast);
}
.checklist-photo-add:hover { border-color: var(--accent); color: var(--accent); }
.checklist-photo-count {
  font-size: var(--fs-xs);
  color: var(--text-muted);
}
.checklist-photo-count.is-missing { color: var(--danger); font-weight: var(--fw-semibold); }

/* --- SIGNATURE --- */
.checklist-widget-signature {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.checklist-signature-img {
  max-height: 60px;
  background: #fff;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  padding: 4px;
}
.checklist-signature-canvas {
  width: 100%;
  height: 240px;
  background: #fff;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  touch-action: none;
  cursor: crosshair;
}

/* --- Modal de obligatorios pendientes --- */
.checklist-obligatorios-list {
  padding-left: 18px;
  margin: 0;
}
.checklist-obligatorios-list a {
  color: var(--accent);
  text-decoration: none;
}
.checklist-obligatorios-list a:hover { text-decoration: underline; }

/* ============================================================
   LIGHTBOX — visor de fotos con carrusel (js/lightbox.js)
   Overlay estilo modal: backdrop oscuro + blur, imagen centrada,
   flechas de navegación y caption/counter abajo.
   ============================================================ */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: 1080; /* arriba de los modales de Bootstrap (1055) */
  display: none;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-6);
  background: rgba(0, 0, 0, 0.82);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.lightbox-overlay.is-open {
  display: flex;
  animation: lightbox-fade .15s ease;
}
@keyframes lightbox-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.lightbox-stage {
  margin: 0;
  max-width: min(1100px, 88vw);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}
.lightbox-img {
  max-width: 100%;
  max-height: 80vh;
  object-fit: contain;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  box-shadow: 0 32px 80px rgba(0, 0, 0, 0.6);
  background: var(--bg-card);
}
.lightbox-meta {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  color: var(--text-muted);
  font-size: var(--fs-sm);
  min-height: 1.4em;
}
.lightbox-caption { color: var(--text); }
.lightbox-counter {
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
}
.lightbox-btn {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  color: var(--text);
  width: 42px;
  height: 42px;
  border-radius: var(--radius-pill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast);
  flex: 0 0 auto;
}
.lightbox-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: var(--border-strong);
}
.lightbox-close {
  position: absolute;
  top: var(--space-5);
  right: var(--space-5);
}
.lightbox-close:hover {
  background: rgba(255, 107, 107, 0.14);
  border-color: rgba(255, 107, 107, 0.4);
}
@media (max-width: 576px) {
  .lightbox-overlay { padding: var(--space-3); gap: var(--space-2); }
  .lightbox-prev, .lightbox-next {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 1;
  }
  .lightbox-prev { left: var(--space-3); }
  .lightbox-next { right: var(--space-3); }
}

/* Foto grande del técnico en su página de detalle (tecnico-detail.js). */
.tecnico-foto-hero {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg-elev-1);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 28px;
  flex-shrink: 0;
}
.tecnico-foto-hero--empty { border: 1px dashed var(--border); }

/* ============================================================
   RESPONSIVE — mobile / tablet vertical
   Reglas transversales a todos los componentes. Las específicas de un
   componente que ya tenían breakpoint propio (toolbar--ots, lightbox,
   global search) quedan donde están.
   ============================================================ */
@media (max-width: 900px) {
  /* Tabs: una sola fila que scrollea, sin wrap ni scrollbar visible */
  .tabs {
    max-width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    flex-wrap: nowrap;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tab { white-space: nowrap; flex-shrink: 0; }

  /* Tablas: scrollean adentro de su wrapper con scrollbar fina */
  .table-responsive {
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
    -webkit-overflow-scrolling: touch;
  }
  .table-responsive::-webkit-scrollbar { height: 5px; }
  .table-responsive::-webkit-scrollbar-track { background: transparent; }
  .table-responsive::-webkit-scrollbar-thumb { background: var(--border); border: 0; border-radius: var(--radius-pill); }
  .table > thead th,
  .table > tbody > tr > td { padding: var(--space-3) var(--space-3); white-space: nowrap; }

  /* Sub-filtros (lista de OTs): pueden wrappear */
  .sub-filters { flex-wrap: wrap; row-gap: var(--space-2); }
  .sub-filter-select.form-select { min-width: 0; max-width: 100%; }

  /* Hero de página */
  .page-hero { gap: var(--space-4); }
  .page-hero-title { font-size: var(--fs-xl); }
  .page-hero-sub { font-size: var(--fs-base); }

  /* Hero de OT */
  .ot-hero-title { font-size: 21px; }
  .ot-hero-row { gap: var(--space-4); }
  .ot-hero-actions { flex-wrap: wrap; width: 100%; }

  /* Stats del dashboard: número más chico, cards más bajas */
  .stat-card-v3 { min-height: 88px; padding: var(--space-4) var(--space-3); }
  .stat-card-v3-value { font-size: 30px; }

  /* Agenda / grids de cards: una columna en angosto */
  .agenda-cards { grid-template-columns: 1fr; }
  .agenda-nav-btn { min-height: 36px; min-width: 40px; }

  /* Reglas de notificación: header de cada trigger puede wrappear */
  .trigger-section { padding: var(--space-4); }
  .trigger-section-head,
  .trigger-section-title { flex-wrap: wrap; }

  /* Paneles y modales: menos aire */
  .modal-header, .modal-footer { padding: var(--space-3) var(--space-4); }
  .modal-body { padding: var(--space-4); }
  .modal-footer { flex-wrap: wrap; }
}

@media (max-width: 576px) {
  /* iOS Safari hace zoom al enfocar inputs con font-size < 16px.
     Subimos los controles a 16px en celular; el layout no cambia. */
  .form-control, .form-select, .form-control-sm, .form-select-sm,
  textarea.form-control, .sub-filter-select.form-select {
    font-size: 16px;
  }

  /* Hero de página: acciones en fila propia, botones a ancho completo si son pocos */
  .page-hero { flex-direction: column; align-items: stretch; }
  .page-hero-actions { width: 100%; }
  .page-hero-actions > .btn { flex: 1 1 auto; }

  /* Acciones del hero de OT: Editar + Cambiar estado se reparten el ancho;
     el botón ícono (eliminar) mantiene su tamaño. */
  .ot-hero-actions > * { flex: 1 1 auto; }
  .ot-hero-actions > .btn-ghost { flex: 0 0 auto; }
  .ot-hero-actions .btn-group { display: flex; }
  .ot-hero-actions .btn-group > .btn { flex: 1 1 auto; }

  /* Section hero (dashboard): título arriba, contador abajo */
  .section-hero { flex-direction: column; align-items: flex-start; gap: var(--space-2); }

  /* Árbol de sitios (cliente): las acciones bajan a su propia línea */
  .tree-row { flex-wrap: wrap; }

  /* Data rows: label arriba del valor, así los valores largos no se aplastan */
  .data-row { flex-direction: column; gap: 2px; align-items: stretch; }
  .data-row-label { width: auto; }

  /* Modal: pegado abajo, esquinas redondeadas arriba (patrón sheet) */
  .modal-dialog { margin: 0; position: fixed; left: 0; right: 0; bottom: 0; max-width: none; width: 100%; }
  .modal.fade .modal-dialog { transform: translateY(24px); }
  .modal.show .modal-dialog { transform: none; }
  .modal-content { border-radius: var(--radius-lg, 14px) var(--radius-lg, 14px) 0 0; border-bottom: 0; max-height: calc(100dvh - 24px); }
  .modal-dialog-scrollable .modal-content,
  .modal-dialog-scrollable .modal-content > form { max-height: calc(100dvh - 24px); }
  .modal-footer { padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom)); }
  .modal-footer > .btn { flex: 1 1 auto; }

  /* Toolbars: acciones a ancho completo. `nowrap` es clave: un flex en
     columna CON wrap dimensiona la línea por el hijo más ancho (los tabs)
     y desborda el viewport. */
  .toolbar { flex-direction: column; align-items: stretch; flex-wrap: nowrap; }
  .toolbar-actions { width: 100%; }
  .toolbar-actions > .toolbar-search { width: 100%; }
  .tabs-row { flex-wrap: wrap; }
  .tabs-row-search { max-width: none; width: 100%; margin: 0 0 var(--space-2); order: -1; }
  .toolbar-actions > .btn,
  .toolbar-actions > .form-control,
  .toolbar-actions > .form-select { flex: 1 1 auto; }

  /* Ubicación de la OT: cada tramo en su línea */
  .ot-loc-path { flex-direction: column; align-items: stretch; gap: var(--space-2); }
  .ot-loc-sep { display: none; }
}

/* Sin puntero (touch): lo que se revela con hover tiene que estar visible
   siempre — no hay hover en el celular. */
@media (hover: none) {
  .tree-row-actions { opacity: 1; }
  .checklist-tl-actions { opacity: 1; }
  .checklist-tl-grip { opacity: 0.6; }
  .unidad-foto-del { opacity: 1; }
}
