:root {
  color-scheme: light;
  --bg: #f5f7fb;
  --card: #ffffff;
  --text: #1f2a37;
  --muted: #64748b;
  --primary: #1b4dff;
  --secondary: #e2e8f0;
  --success: #16a34a;
  --warning: #f59e0b;
  --danger: #ef4444;
  --info: #0ea5e9;
  --shadow: 0 10px 24px rgba(15, 23, 42, 0.08);
  --radius: 16px;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: "Inter", system-ui, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
}

.app {
  display: grid;
  grid-template-columns: 280px 1fr;
  min-height: 100vh;
}

body.sidebar-collapsed .app {
  grid-template-columns: 88px 1fr;
}

.sidebar {
  background: #111827;
  color: #e5e7eb;
  padding: 24px 20px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  position: sticky;
  top: 0;
  height: 100vh;
  /* La barra como tal no se desborda; el menu interno hace scroll. */
  overflow: hidden;
  transition: width 0.3s ease;
}

.sidebar__brand {
  display: flex;
  gap: 12px;
  align-items: center;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  border-radius: 12px;
  transition: opacity 0.15s ease;
}

.sidebar__brand:hover {
  opacity: 0.85;
}

.logo {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: linear-gradient(135deg, #1b4dff, #22c55e);
  display: grid;
  place-items: center;
  font-weight: 700;
}

.sidebar__brand h1 {
  font-size: 18px;
}

.sidebar__brand span {
  font-size: 12px;
  color: #9ca3af;
}

.sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: 12px;
  /* Ocupa el espacio disponible y hace scroll si hay muchos modulos
     (brand arriba y footer abajo permanecen visibles). */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Scrollbar discreta sobre el fondo oscuro. */
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.25) transparent;
}

.sidebar__nav::-webkit-scrollbar {
  width: 6px;
}

.sidebar__nav::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.2);
  border-radius: 999px;
}

.sidebar__nav a {
  text-decoration: none;
  color: inherit;
  padding: 12px 14px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  transition: all 0.2s ease;
}

.sidebar.collapsed {
  width: 88px;
}

.sidebar.collapsed .sidebar__brand h1,
.sidebar.collapsed .sidebar__brand span,
.sidebar.collapsed .sidebar__nav a span,
.sidebar.collapsed .sidebar__footer button {
  display: none;
}

.sidebar__nav a i {
  font-size: 18px;
}

.sidebar__nav a.active,
.sidebar__nav a:hover {
  background: rgba(255, 255, 255, 0.1);
}

.sidebar__footer {
  margin-top: auto;
}

.main {
  padding: 24px 32px 80px;
  /* Evita que un contenido ancho (tablas) expanda la columna del grid y
     desborde la pagina; los .table-card hacen scroll interno en su lugar. */
  min-width: 0;
  overflow-x: hidden;
}

.header {
  background: var(--card);
  border-radius: var(--radius);
  padding: 16px 20px;
  box-shadow: var(--shadow);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  position: sticky;
  top: 0;
  z-index: 10;
}

.header__left {
  display: flex;
  align-items: center;
  gap: 20px;
}

.header__right {
  display: flex;
  align-items: center;
  gap: 16px;
}

.eyebrow {
  font-size: 12px;
  color: var(--muted);
}

.select {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}

select,
input {
  border: 1px solid #e2e8f0;
  padding: 10px 12px;
  border-radius: 12px;
  font-family: inherit;
  background: #fff;
}

.user {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  min-width: 0;
}

.user span {
  font-weight: 600;
}

.user small {
  font-size: 12px;
  color: var(--muted);
}

.avatar {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: #1f2937;
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 14px;
  flex-shrink: 0;
}

.icon {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  border: 1px solid #e2e8f0;
  background: #fff;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}

.content {
  margin-top: 32px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.section__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}

.actions {
  display: flex;
  gap: 10px;
}

.card {
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
}

.grid {
  display: grid;
  gap: 20px;
}

.kpi-grid {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.chart-grid {
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.two-cols {
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

.kpi {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.kpi h4 {
  font-size: 28px;
}

/* Tarjetas KPI del dashboard que navegan a su modulo. */
.kpi--link {
  cursor: pointer;
  transition: box-shadow 0.15s ease, transform 0.05s ease;
}

.kpi--link:hover {
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.14);
}

.kpi--link:active {
  transform: translateY(1px);
}

.icon-pill {
  width: 46px;
  height: 46px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  color: #fff;
  flex-shrink: 0;
}

/* Evita que un numero largo (p.ej. costos) deforme el icono o desborde el card. */
.kpi > div {
  min-width: 0;
}

.kpi h4 {
  overflow-wrap: anywhere;
}

.icon-pill.success { background: var(--success); }
.icon-pill.warning { background: var(--warning); }
.icon-pill.danger { background: var(--danger); }
.icon-pill.info { background: var(--info); }

.trend {
  font-size: 12px;
}

.trend.up { color: var(--success); }
.trend.down { color: var(--danger); }
.trend.warning { color: var(--warning); }

/* Permite que la tabla haga scroll horizontal dentro del card en vez de
   desbordarse, y que el card pueda encogerse dentro de un grid (min-width:0). */
.table-card {
  overflow-x: auto;
  min-width: 0;
}

/* En planes la tabla (7 columnas) comparte fila con el editor de checklist;
   en escritorio le damos mas ancho para que quepa sin recortarse. */
@media (min-width: 900px) {
  #planes .grid.two-cols {
    grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr);
  }
}

/* En repuestos la tabla tiene 7 columnas + la barra de exportar/buscar de
   DataTables: no cabe bien compartiendo fila con el panel "Kardex visual" (se
   recortaba y aparecia scroll horizontal). Se apila: tabla a todo el ancho y el
   kardex debajo como una tira compacta de 3 estadisticas. */
#repuestos .grid.two-cols {
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  #repuestos .kardex {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.table-card table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.table-card th,
.table-card td {
  padding: 12px 10px;
  border-bottom: 1px solid #e2e8f0;
  text-align: left;
}

.table-card td.actions {
  display: flex;
  gap: 6px;
}

.table-card td.loading,
.table-card td.empty,
.table-card td.error {
  text-align: center;
  color: var(--muted);
}

.table-card td.error {
  color: var(--danger);
}

/* Filas seleccionables y resaltado de la fila activa (p. ej. el plan cuyo
   checklist se esta editando en /planes). */
.table-card tbody tr.clickable {
  cursor: pointer;
  transition: background 0.12s ease;
}

.table-card tbody tr.clickable:hover td {
  background: #f8fafc;
}

.table-card tbody tr.is-selected td,
.table-card tbody tr.is-selected:hover td {
  background: rgba(27, 77, 255, 0.10);
}

.table-card tbody tr.is-selected td:first-child {
  box-shadow: inset 3px 0 0 var(--primary);
}

/* Nombre del plan activo junto al titulo "Editor de checklist". */
.checklist-plan-label {
  color: var(--primary);
  font-weight: 600;
}

/* Cabecera del editor de checklist con su icono de ayuda. */
.checklist-editor-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.checklist-editor-header h5 {
  margin: 0;
}

.btn-help {
  border: none;
  background: transparent;
  color: var(--muted, #64748b);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  padding: 4px 6px;
  border-radius: 6px;
  transition: background 0.12s ease, color 0.12s ease;
}

.btn-help:hover {
  color: var(--primary);
  background: #eef2ff;
}

/* Contenido del modal de ayuda del checklist. */
.help-steps {
  margin: 6px 0 14px;
  padding-left: 20px;
}

.help-steps li {
  margin: 5px 0;
}

.help-example {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  padding: 12px 16px;
}

.help-example ul {
  margin: 0;
  padding-left: 18px;
}

.help-example li {
  margin: 4px 0;
}

.help-tip {
  margin-top: 12px;
}

.card__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.badge {
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  color: #fff;
}

.badge.success { background: var(--success); }
.badge.warning { background: var(--warning); }
.badge.danger { background: var(--danger); }
.badge.info { background: var(--info); }
.badge.secondary { background: var(--muted); }

/* Niveles de prioridad. El color sale de una variable que pone el navegador al
   arrancar (`utils/prioridad.js`) desde lo guardado en Configuracion; el valor
   de reserva es el tono de siempre, para que un fallo al leer los parametros
   deje badges correctos y no badges invisibles. El texto se decide por la
   luminancia del fondo: sobre un color claro el blanco no se leeria. */
.badge.prio { color: var(--prio-fg, #fff); background: var(--prio-bg, var(--info)); }

/* Selectores de color de Configuracion: cada uno con su etiqueta de muestra,
   que se repinta en vivo -no al guardar- para poder comparar los cuatro. */
/* Prefijo + digitos del codigo de equipo, en una linea. */
.secuencia-codigo { display: flex; gap: 8px; }
.secuencia-codigo > input[type="text"] { flex: 1 1 auto; min-width: 0; }
.secuencia-codigo > input[type="number"] { flex: 0 0 70px; }

.prio-colores { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.prio-colores__item { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
/* Con el `#configuracion` delante a proposito: los selectores de color de esa
   pantalla ya tienen una regla por id (`width: 100%`, para los de la etiqueta y
   la PWA, que van solos en su campo) y ganaria por especificidad, dejando estos
   cuatro reducidos a una raya. */
#configuracion .prio-colores__item input[type="color"] {
  display: inline-block; width: 38px; height: 32px; padding: 2px;
  border: 1px solid #e2e8f0; border-radius: 8px; background: #fff; cursor: pointer;
}
.badge.prio--critica { --prio-bg: var(--prio-critica-bg, #ef4444); --prio-fg: var(--prio-critica-fg, #fff); }
.badge.prio--alta    { --prio-bg: var(--prio-alta-bg, #f59e0b);    --prio-fg: var(--prio-alta-fg, #fff); }
.badge.prio--media   { --prio-bg: var(--prio-media-bg, #0ea5e9);   --prio-fg: var(--prio-media-fg, #fff); }
.badge.prio--baja    { --prio-bg: var(--prio-baja-bg, #16a34a);    --prio-fg: var(--prio-baja-fg, #fff); }

/* Estados de la orden de trabajo (`utils/estado-ot.js`). Van en tinta sobre
   fondo tenue -no macizos como los de prioridad- en la misma familia de tonos
   que usa cada columna del Kanban. Antes salian del mapa generico de la
   tabla, donde "pendiente" y "en_proceso" compartian amarillo y "pausada"
   caia en el azul de la prioridad "media": el estado no se distinguia de un
   vistazo. Que el badge
   sea tenue tambien lo separa del de prioridad, que en Ordenes va en la celda
   de al lado. */
.badge.estado {
  display: inline-block;
  background: var(--estado-bg);
  color: var(--estado-fg);
  border: 1px solid var(--estado-bd);
}
.badge.estado--pendiente,  .gantt .estado--pendiente  { --estado-bg: #fef3c7; --estado-fg: #92400e; --estado-bd: #fbbf24; }
.badge.estado--en_proceso, .gantt .estado--en_proceso { --estado-bg: #e0f2fe; --estado-fg: #075985; --estado-bd: #38bdf8; }
.badge.estado--pausada,    .gantt .estado--pausada    { --estado-bg: #e2e8f0; --estado-fg: #334155; --estado-bd: #94a3b8; }
.badge.estado--finalizada, .gantt .estado--finalizada { --estado-bg: #dcfce7; --estado-fg: #166534; --estado-bd: #4ade80; }
.badge.estado--cancelada,  .gantt .estado--cancelada  { --estado-bg: #fee2e2; --estado-fg: #991b1b; --estado-bd: #f87171; }

.filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}

.tabs__header {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tabs__header button {
  border: 1px solid #e2e8f0;
  background: #fff;
  padding: 10px 16px;
  border-radius: 12px;
}

.tabs__header button.active {
  background: #1b4dff;
  color: #fff;
  border-color: transparent;
}

.timeline {
  display: grid;
  gap: 12px;
}

.timeline__item {
  padding: 12px;
  border-radius: 12px;
  background: #f8fafc;
}

.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
}

.list {
  list-style: none;
  display: grid;
  gap: 12px;
}

.list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.checklist {
  display: grid;
  gap: 8px;
  margin-bottom: 12px;
}

.detail {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.detail__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.detail__actions {
  display: flex;
  gap: 10px;
}

.kardex {
  display: grid;
  gap: 12px;
}

.kardex div {
  display: flex;
  justify-content: space-between;
  background: #f8fafc;
  padding: 12px;
  border-radius: 12px;
}

/* ===== Detalle de repuesto (#repuesto/<id>) ===== */
/* Sidebar (imagen + stock/costo) con ancho fijo; la columna principal toma el
   resto. En pantallas chicas se apila (hereda el auto-fit de .two-cols). */
@media (min-width: 900px) {
  #repuestoDetail .grid.two-cols {
    grid-template-columns: minmax(0, 1fr) 320px;
    align-items: start;
  }
}

.rep-hero__main { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.rep-hero__main h3 { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rep-hero__icon {
  width: 38px; height: 38px; border-radius: 11px; display: inline-grid; place-items: center;
  background: #eef2ff; color: var(--primary, #1b4dff); font-size: 18px; flex: 0 0 auto;
}
.rep-sku {
  font-size: 12px; font-weight: 700; letter-spacing: .3px; color: var(--primary, #1b4dff);
  background: #eef2ff; padding: 2px 8px; border-radius: 999px;
}
.rep-chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.rep-chip {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted, #64748b);
  background: #f1f5f9; border-radius: 999px; padding: 3px 10px;
}

.rep-info li { gap: 16px; }
.rep-info li span:last-child { text-align: right; color: var(--text, #0f172a); font-weight: 500; overflow-wrap: anywhere; }
.rep-info__lbl, .rep-extra__lbl {
  font-size: 11px; text-transform: uppercase; letter-spacing: .4px; font-weight: 700; color: var(--muted, #64748b);
}

.rep-sidebar { display: flex; flex-direction: column; }
@media (min-width: 900px) { .rep-sidebar { position: sticky; top: 16px; } }

/* Imagen del producto */
.rep-img {
  width: 100%; aspect-ratio: 1 / 1; border-radius: 14px; overflow: hidden;
  display: grid; place-items: center; background: #f8fafc;
  border: 1px dashed var(--border, #e2e8f0); color: #cbd5e1; font-size: 54px;
}
.rep-img.has-img { border-style: solid; }
.rep-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rep-img > a { display: block; width: 100%; height: 100%; cursor: zoom-in; }

/* Stock destacado */
.rep-stock-hero {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: #f8fafc; border-radius: 12px; padding: 14px; margin-bottom: 14px;
}
.rep-stock-hero__lbl { font-size: 11px; text-transform: uppercase; letter-spacing: .4px; color: var(--muted, #64748b); font-weight: 700; }
.rep-stock-hero__num { font-size: 34px; font-weight: 800; line-height: 1.1; color: #0f172a; }
.rep-stock-hero__unit { font-size: 12px; color: var(--muted, #64748b); }

.rep-kpi { gap: 8px; }
.rep-kpi li { display: flex; justify-content: space-between; align-items: center; gap: 12px; font-size: 13px; }
.rep-kpi li span { color: var(--muted, #64748b); }
.rep-kpi li strong { color: #0f172a; }
.rep-kpi__total { border-top: 1px solid var(--border, #e2e8f0); padding-top: 10px; margin-top: 2px; }
.rep-kpi__total span, .rep-kpi__total strong { font-weight: 700; color: var(--primary, #1b4dff); }

/* Tabla de Movimientos / Kardex: tipografia mas compacta y prolija (evita que la
   fecha y la OT se partan en varias lineas y se vean desordenadas). */
#repuestoDetail .detail-table table { font-size: 13px; }
#repuestoDetail .detail-table th,
#repuestoDetail .detail-table td { padding: 9px 12px; vertical-align: middle; line-height: 1.35; }
#repuestoDetail .detail-table td:first-child,   /* Fecha */
#repuestoDetail .detail-table td:nth-child(3) { white-space: nowrap; }  /* Cantidad */
#repuestoDetail .detail-table td a { display: inline-flex; align-items: center; gap: 4px; }
#repuestoDetail .detail-table td a .bi { font-size: 11px; opacity: .8; }

/* ===== Agenda / calendario moderno ===== */
.agenda-toolbar { display: flex; align-items: center; gap: 10px; }
.agenda-bell {
  width: 40px; height: 40px; border-radius: 10px; display: inline-flex;
  align-items: center; justify-content: center; font-size: 18px;
}
.agenda-bell.is-on { color: var(--primary); background: #eef2ff; }
.agenda-lead {
  height: 40px; border-radius: 10px; border: 1px solid var(--border, #e2e8f0);
  padding: 0 10px; background: #fff; font-size: 13px; color: var(--text, #0f172a);
}

.agenda-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 16px;
  margin-bottom: 16px;
}
@media (max-width: 980px) { .agenda-layout { grid-template-columns: 1fr; } }

.calendar__toolbar {
  display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px;
}
.calendar__nav { display: flex; align-items: center; gap: 8px; }
.calendar__nav strong { font-size: 16px; min-width: 150px; text-align: center; }

.calendar__weekdays {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px;
  text-align: center; font-size: 12px; font-weight: 600; color: var(--muted); margin-bottom: 6px;
}

.calendar__grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }

.cal-cell {
  position: relative; min-height: 96px; background: #f8fafc;
  border: 1px solid transparent; border-radius: 10px; padding: 6px 6px 4px;
  display: flex; flex-direction: column; gap: 4px; cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.cal-cell:hover { background: #eef2ff; border-color: #c7d2fe; }
.cal-cell__num { font-size: 12px; font-weight: 600; color: #475569; align-self: flex-end; }
.cal-cell.is-other { background: #fff; opacity: .5; cursor: default; }
.cal-cell.is-other:hover { background: #fff; border-color: transparent; }
.cal-cell.is-today { border-color: var(--primary); background: #fff; }
.cal-cell.is-today .cal-cell__num {
  background: var(--primary); color: #fff; border-radius: 999px;
  width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
}

.cal-cell__events { display: flex; flex-direction: column; gap: 3px; overflow: hidden; }
.cal-chip {
  display: flex; align-items: center; gap: 5px; width: 100%; text-align: left;
  border: 0; border-left: 3px solid var(--chip, #1b4dff); border-radius: 4px;
  padding: 2px 6px; cursor: pointer; font-size: 11px;
  color: #334155; background: #fff; box-shadow: 0 1px 2px rgba(15, 23, 42, .06);
}
.cal-chip:hover { background: #f1f5f9; }
.cal-chip__time { font-weight: 700; color: var(--chip, #1b4dff); flex: 0 0 auto; }
.cal-chip__txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-cell__more { border: 0; background: transparent; color: var(--muted); font-size: 11px; cursor: pointer; text-align: left; padding: 0 6px; }
.cal-cell__more:hover { color: var(--primary); }

.calendar__legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 12px; font-size: 12px; color: var(--muted); }
.cal-legend__item { display: inline-flex; align-items: center; gap: 6px; }
.cal-legend__dot { width: 10px; height: 10px; border-radius: 3px; }

/* Panel de proximos eventos */
.agenda-side h5 { margin: 0 0 12px; display: flex; align-items: center; gap: 6px; }
.agenda-upcoming { display: flex; flex-direction: column; gap: 8px; }
.upcoming-item {
  display: flex; align-items: flex-start; gap: 10px; width: 100%; text-align: left;
  border: 1px solid var(--border, #e2e8f0); border-radius: 10px; padding: 10px;
  background: #fff; cursor: pointer; transition: border-color .12s ease, background .12s ease;
}
.upcoming-item:hover { border-color: var(--primary); background: #f8faff; }
.upcoming-item__dot { width: 10px; height: 10px; border-radius: 50%; margin-top: 5px; flex: 0 0 auto; }
.upcoming-item__body { display: flex; flex-direction: column; min-width: 0; }
.upcoming-item__title { font-weight: 600; font-size: 13px; color: #0f172a; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.upcoming-item__when { font-size: 12px; color: var(--muted); }

/* ===== Aviso "Programacion de hoy" (briefing al ingresar) ===== */
.briefing__date { margin: -4px 0 14px; color: var(--muted); font-size: 13px; }
.briefing__empty {
  display: flex; align-items: center; gap: 8px; justify-content: center;
  padding: 18px 12px; color: var(--muted); font-size: 14px;
  background: #f0fdf4; border: 1px solid #dcfce7; border-radius: 12px;
}
.briefing__empty i { color: #16a34a; font-size: 18px; }
.briefing__stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 16px; }
.briefing__stat {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px; border-radius: 12px; background: #f8fafc; border: 1px solid #eef2f7;
}
.briefing__stat i { font-size: 18px; }
.briefing__stat-num { font-size: 22px; font-weight: 700; color: #0f172a; line-height: 1; }
.briefing__stat-label { font-size: 11px; color: var(--muted); text-align: center; }
.briefing__stat--primary i { color: var(--primary); }
.briefing__stat--info i { color: #0ea5e9; }
.briefing__stat--danger i { color: var(--danger); }
.briefing__stat--danger .briefing__stat-num { color: var(--danger); }

.briefing__body { display: flex; flex-direction: column; gap: 16px; max-height: 48vh; overflow-y: auto; }
.briefing__section h6 {
  margin: 0 0 8px; font-size: 13px; display: flex; align-items: center; gap: 6px; color: #334155;
}
.briefing__count {
  margin-left: auto; background: #eef2ff; color: var(--primary); border-radius: 999px;
  padding: 1px 8px; font-size: 11px; font-weight: 700;
}
.briefing__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.briefing__item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border: 1px solid var(--border, #e2e8f0); border-radius: 10px; background: #fff;
}
/* Previsualizacion de fotos en el registro de inspeccion (#registrar). */
.reg-fotos { display: flex; flex-wrap: wrap; gap: 10px; }
.reg-fotos__botones { display: flex; flex-wrap: wrap; gap: 8px; }

/* Tecnico de la tarjeta del Kanban cuando el usuario no puede reasignar
   (entonces no se pinta el desplegable, solo el nombre). */
.kanban-card__tecnico {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 8px; font-size: 12.5px; color: var(--muted, #64748b);
}
.kanban-card__tecnico i { font-size: 13px; }

/* Eleccion de que se viene a registrar al abrir el QR (#registrar). */
.reg-modos { display: flex; flex-wrap: wrap; gap: 12px; }
.reg-modo {
  flex: 1 1 260px; display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  text-align: left; padding: 16px; border: 1px solid var(--border, #e2e8f0); border-radius: 14px;
  background: #fff; cursor: pointer; font: inherit; color: inherit;
  transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
.reg-modo:hover { border-color: var(--primary); background: #f8faff; box-shadow: 0 4px 14px rgba(27,77,255,.08); }
.reg-modo > i { font-size: 22px; color: var(--primary); }
.reg-modo strong { font-size: 15px; }
.reg-modo span { font-size: 13px; color: var(--muted, #64748b); line-height: 1.5; }
#btnModoAveria > i { color: var(--danger, #ef4444); }
#btnModoAveria:hover { border-color: var(--danger, #ef4444); background: #fff7f7; box-shadow: 0 4px 14px rgba(239,68,68,.08); }
/* El "Cambiar" vive dentro del <h5>, que es flex: que no lo estire. */
.reg-cambiar { margin-left: auto; padding: 4px 10px; font-size: 12px; border-radius: 8px; flex: 0 0 auto; }
.req { color: var(--danger, #ef4444); font-weight: 600; }
.reg-foto { position: relative; width: 96px; height: 96px; border-radius: 10px; overflow: hidden; border: 1px solid var(--border, #e2e8f0); background: #f8fafc; }
.reg-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.reg-foto__del {
  position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%; cursor: pointer;
  background: rgba(15, 23, 42, 0.65); color: #fff; font-size: 11px; line-height: 1;
}
.reg-foto__del:hover { background: var(--danger, #ef4444); }

.briefing__item--link { cursor: pointer; transition: border-color .15s, background .15s, box-shadow .15s; }
.briefing__item--link:hover,
.briefing__item--link:focus-visible {
  border-color: var(--primary, #1b4dff); background: #f5f8ff;
  box-shadow: 0 1px 6px rgba(27, 77, 255, 0.12); outline: none;
}
.briefing__dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.briefing__item-main { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.briefing__item-main strong { font-size: 13px; color: #0f172a; }
.briefing__item-main .muted { font-size: 12px; }
.briefing__more { list-style: none; font-size: 12px; color: var(--muted); padding: 2px 4px; }

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}

.install-summary {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  padding: 16px;
  font-size: 12px;
  line-height: 1.6;
  white-space: pre-wrap;
  color: #1f2937;
  max-height: 320px;
  overflow: auto;
}

.install-hint {
  color: var(--muted);
  font-size: 14px;
  margin: 8px 0 12px;
}

button {
  border: none;
  padding: 10px 16px;
  border-radius: 12px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
}

button.primary {
  background: var(--primary);
  color: #fff;
}

button.secondary {
  background: var(--secondary);
  color: #1f2937;
}

button.danger {
  background: var(--danger);
  color: #fff;
}

button.ghost {
  background: transparent;
  color: inherit;
}

button.ghost.danger {
  color: var(--danger);
}

/* Un enlace con clase de boton ("Ver el panel", "Volver") se ve como boton.
   Las reglas de arriba solo alcanzan a <button>, y un <a class="secondary">
   salia como enlace azul subrayado de 16px junto a botones grises de 13px.
   El tamano de letra es el que el navegador da a <button> por defecto. */
a.primary,
a.secondary,
a.danger,
a.ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 16px;
  border-radius: 12px;
  font-size: 13.3333px;
  font-weight: 600;
  line-height: normal;
  text-decoration: none;
  cursor: pointer;
}
a.primary { background: var(--primary); color: #fff; }
a.secondary { background: var(--secondary); color: #1f2937; }
a.danger { background: var(--danger); color: #fff; }
a.ghost { background: transparent; color: inherit; }

.breadcrumbs {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 14px;
}

.toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  background: #0f172a;
  color: #fff;
  padding: 14px 18px;
  border-radius: 12px;
  display: flex;
  gap: 10px;
  align-items: center;
  box-shadow: var(--shadow);
  opacity: 0;
  transition: opacity 0.3s ease;
  /* Sobre el modal (1000): las notificaciones deben verse aun con un modal abierto. */
  z-index: 1100;
  /* El toast se apaga con `opacity: 0`, y un elemento transparente SIGUE
     recibiendo los toques. Como esta fijo en la esquina inferior derecha y por
     encima del modal, se comia el clic del boton Guardar: en el escritorio el
     modal es angosto y sus botones quedan lejos de esa esquina, pero en el
     telefono el modal ocupa casi toda la pantalla y su fila de acciones
     (alineada a la derecha) cae justo encima del toast invisible. El sintoma
     era "el boton Guardar no hace nada" en el movil.
     El toast no tiene nada que pulsar, asi que nunca debe recibir el puntero. */
  pointer-events: none;
}

.toast.success {
  background: #16a34a;
}

.toast.error {
  background: #ef4444;
}

.modal {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.6);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  /* Por encima del header sticky (z-index:10) para que no lo tape. */
  z-index: 1000;
}

.modal.active {
  animation: cmms-fade-in 0.18s ease;
}

.modal__content {
  background: #fff;
  padding: 24px;
  border-radius: 18px;
  max-width: 360px;
  width: 100%;
  /* El formulario puede ser mas alto que la pantalla: scroll interno. */
  max-height: 90vh;
  /* `dvh` es el alto que queda DE VERDAD. En el movil `vh` se mide con la barra
     de direcciones OCULTA, asi que un modal de 90vh sobresale por abajo de la
     pantalla y su ultima fila -la de los botones- cae fuera. */
  max-height: 90dvh;
  overflow-y: auto;
  animation: cmms-modal-in 0.22s ease;
}

.modal__content--wide {
  max-width: 600px;
}

.modal__content--detail {
  max-width: 860px;
}

@keyframes cmms-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes cmms-modal-in {
  from { opacity: 0; transform: translateY(14px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ===== Detalle (vista) dentro del modal ===== */
/* Solo se muestra la pestana activa (sin esto se veian todas a la vez). */
.tab-panel {
  display: none;
}

.tab-panel.active {
  display: block;
}

/* ===== Detalle de equipo (modal) — diseno elegante ===== */
/* Tabs estilo "underline" en vez de botones pildora. */
#equipoDetail.tabs .tabs__header {
  gap: 2px;
  border-bottom: 1px solid #e9eef5;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

#equipoDetail.tabs .tabs__header button {
  border: none;
  background: transparent;
  border-radius: 0;
  padding: 10px 16px;
  color: var(--muted);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.15s ease, border-color 0.15s ease;
}

#equipoDetail.tabs .tabs__header button:hover {
  color: var(--text);
}

#equipoDetail.tabs .tabs__header button.active {
  background: transparent;
  color: var(--primary);
  border-bottom-color: var(--primary);
}

.detail-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 240px;
  gap: 24px;
  align-items: start;
}

.detail-section-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin-bottom: 12px;
}

.ficha-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 24px;
}

.ficha-item {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 9px 0;
  border-bottom: 1px solid #eef2f7;
  min-width: 0;
}

.ficha-item--full {
  grid-column: 1 / -1;
}

.ficha-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
}

.ficha-item > span:last-child {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  word-break: break-word;
}

.detail-aside {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.detail-card {
  background: #f8fafc;
  border: 1px solid #eef2f7;
  border-radius: 14px;
  padding: 16px;
}

/* Tablas dentro de los tabs del detalle */
.detail-table {
  border: 1px solid #eef2f7;
  border-radius: 14px;
  overflow: auto;
}

.detail-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.detail-table th {
  text-align: left;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
  background: #f8fafc;
  padding: 11px 14px;
  border-bottom: 1px solid #eef2f7;
  white-space: nowrap;
}

.detail-table td {
  padding: 11px 14px;
  border-bottom: 1px solid #f1f5f9;
}

.detail-table tbody tr:last-child td {
  border-bottom: none;
}

/* Segunda linea de una celda (el modo y la causa de falla bajo el trabajo
   realizado, en el historial del equipo): `small` es inline y sin esto se
   pegaria al final del texto en vez de leerse como un pie. */
.detail-table td small {
  display: block;
  margin-top: 3px;
  font-size: 12px;
}

/* Columnas de cifras (horas de parada, costo). La regla `.num` de siempre solo
   alcanzaba a `.table-card`. El `nowrap` evita que un importe se parta en dos
   lineas cuando la columna queda estrecha. */
.detail-table th.num,
.detail-table td.num {
  text-align: right;
  white-space: nowrap;
}

.detail-table tbody tr.clickable {
  cursor: pointer;
  transition: background 0.12s ease;
}

.detail-table tbody tr.clickable:hover {
  background: #f8fafc;
}

.detail-table td.empty,
.detail-table td.loading,
.detail-table td.error {
  text-align: center;
  color: var(--muted);
  padding: 28px;
}

.detail-table td.error {
  color: var(--danger);
}

/* El badge muestra el texto del estado en una sola linea, sin encimarse. */
.detail-table .badge {
  display: inline-block;
  white-space: nowrap;
}

@media (max-width: 720px) {
  .detail-layout {
    grid-template-columns: 1fr;
  }

  .ficha-grid {
    grid-template-columns: 1fr;
  }
}

.qr-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 8px;
}

.qr-box img {
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 12px;
  padding: 6px;
  background: #fff;
}

.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.modal__form label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  color: var(--muted);
}

/* Texto del label + asterisco en una sola linea (ahorra alto en el formulario). */
.field-label {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.required {
  color: #ef4444;
  font-weight: 700;
}

.help-text {
  font-size: 11px;
  color: var(--muted);
}

/* ===== Select con buscador (combobox) ===== */
.search-select {
  position: relative;
}

.search-select__caret {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--muted, #64748b);
  font-size: 12px;
  transition: transform 0.15s ease;
}

.search-select.open .search-select__caret {
  transform: translateY(-50%) rotate(180deg);
}

.search-select__list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 20;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: #fff;
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 10px;
  max-height: 220px;
  overflow-y: auto;
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.14);
}

.search-select__item {
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text, #0f172a);
}

.search-select__item:hover {
  background: #f1f5f9;
}

.search-select__item.active {
  background: rgba(27, 77, 255, 0.1);
  font-weight: 600;
}

/* Navegacion con flechas dentro de la lista. */
.search-select__item.resaltado {
  background: #f1f5f9;
}

.search-select__empty {
  color: var(--muted, #64748b);
  cursor: default;
}

/* En las barras de filtro el combo ocupa la celda completa de la grilla. */
.search-select__input {
  width: 100%;
  padding-right: 30px;
}

.modal__form .form-grid {
  gap: 12px;
}

.modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 16px;
}

/* Guardar/Cancelar SIEMPRE a la vista en el modal del formulario. El de una OT
   mide ~1150px de alto: en el telefono hay que deslizar ~500px DENTRO del modal
   para llegar al boton, y mientras el teclado esta abierto ese tramo final
   queda debajo del teclado (el viewport de layout no se encoge solo), asi que
   el boton no se ve ni se puede pulsar. El sintoma es "le doy a Guardar y no
   pasa nada" porque no se le esta dando a nada. Pegado al fondo del scroll
   interno, el boton esta siempre bajo el dedo.
   El padding de abajo lo pone la barra, no `.modal__content`: dejandolo en el
   contenedor, `bottom: 0` deja 24px por los que asoma el campo de arriba al
   deslizar. */
#crudModal .modal__content {
  padding-bottom: 0;
}

#crudModal .modal__form .modal__actions {
  position: sticky;
  bottom: 0;
  margin-top: 8px;
  padding: 12px 0 20px;
  background: #fff;
  border-top: 1px solid #eef2f7;
  /* Por encima de los campos, que pasan por detras al deslizar. */
  z-index: 2;
}


/* ----- Acciones de cada mensaje (responder / eliminar) ----- */
/* En escritorio aparecen al pasar el raton; en el telefono no hay hover, asi
   que se ven siempre, atenuadas. */
.chat__burbuja { position: relative; }

/* UN boton por mensaje, que abre el menu. Antes eran dos iconos sueltos sobre
   la burbuja y se pisaban el texto en cuanto la pantalla era estrecha. */
.chat__menu-btn {
  position: absolute;
  top: 2px;
  right: 2px;
  border: 0;
  background: transparent;
  border-radius: 6px;
  padding: 1px 4px;
  font-size: 11px;
  line-height: 1.4;
  color: var(--muted, #64748b);
  opacity: 0;
  transition: opacity 0.15s ease;
  cursor: pointer;
}

.chat__burbuja:hover .chat__menu-btn,
.chat__burbuja:focus-within .chat__menu-btn { opacity: 0.85; }
.chat__menu-btn:hover { color: var(--primary, #1b4dff); }

/* Menu de acciones del mensaje. */
.msg-menu {
  position: absolute;
  top: 20px;
  right: 4px;
  z-index: 30;
  min-width: 190px;
  padding: 4px;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.18);
}

/* Cuando no cabe hacia abajo (el ultimo mensaje esta pegado al campo). */
.msg-menu--arriba { top: auto; bottom: 20px; }

/* En los mensajes RECIBIDOS el menu se abre hacia la derecha. Anclado a la
   derecha de la burbuja crecia hacia la izquierda, y como esas burbujas van
   pegadas al borde izquierdo del hilo (y suelen ser mas estrechas que el menu),
   se salia de `.chat__mensajes` -que recorta por tener scroll- y las opciones
   no se veian. Los propios van pegados a la derecha: ahi la regla de arriba ya
   sirve. */
.chat__burbuja:not(.chat__burbuja--propia) .msg-menu { left: 4px; right: auto; }

.msg-menu__item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  border: 0;
  background: transparent;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 13px;
  text-align: left;
  color: var(--text, #0f172a);
  cursor: pointer;
}

.msg-menu__item:hover { background: #f1f5f9; }
.msg-menu__item--danger { color: #b91c1c; }
.msg-menu__item--danger:hover { background: #fef2f2; }

/* Al ir a un mensaje desde una cita, se resalta un momento para encontrarlo. */
.chat__burbuja.chat__burbuja--resaltada {
  box-shadow: 0 0 0 3px rgba(27, 77, 255, 0.55);
  background-color: #fef9c3;
  transition: box-shadow 0.3s ease, background-color 0.3s ease;
}

/* ----- Cita dentro de la burbuja ----- */
.chat__cita {
  display: block;
  margin: 0 0 4px;
  padding: 4px 8px;
  border-left: 3px solid var(--primary, #1b4dff);
  border-radius: 6px;
  background: rgba(15, 23, 42, 0.05);
  font-size: 12px;
  line-height: 1.35;
  cursor: pointer;
}

.chat__cita strong { display: block; color: var(--primary, #1b4dff); font-size: 11.5px; }
.chat__cita span { display: block; color: var(--muted, #64748b); }
.chat__cita--borrada { border-left-color: #94a3b8; font-style: italic; }

/* ----- Barra "respondiendo a", encima del campo ----- */
.chat__respondiendo {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-top: 1px solid #eef2f7;
  background: #f8fafc;
  font-size: 12.5px;
  color: var(--muted, #64748b);
}

.chat__respondiendo[hidden] { display: none; }

.chat__respondiendo-texto {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ----- Panel de emojis ----- */
.chat__escribir { position: relative; }

.emoji-panel {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 8px;
  z-index: 20;
  width: min(320px, calc(100vw - 32px));
  max-height: 260px;
  overflow-y: auto;
  padding: 10px;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 14px;
  box-shadow: 0 16px 40px rgba(15, 23, 42, 0.16);
}

.emoji-grupo + .emoji-grupo { margin-top: 8px; }

.emoji-grupo__titulo {
  display: block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted, #64748b);
  margin-bottom: 4px;
}

.emoji-grupo__rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
  gap: 2px;
}

.emoji-btn {
  border: 0;
  background: transparent;
  border-radius: 8px;
  padding: 4px;
  font-size: 20px;
  line-height: 1.2;
  cursor: pointer;
}

.emoji-btn:hover { background: #f1f5f9; }

@media (max-width: 720px) {
  /* Sin hover no hay forma de descubrirlas: se dejan visibles. */
  .chat__acciones { opacity: 0.55; }
}

/* ----- Adjuntos del chat (imagen, audio, archivo) ----- */
/* Foto en la burbuja. La caja tiene el tamano FINAL de la foto (lo pone
   chatHilo.js con las medidas guardadas al subirla), asi el hilo no salta al
   llegar la imagen. Sin medidas -fotos anteriores- usa un hueco fijo. */
.chat__foto {
  position: relative;
  display: block;
  width: 220px;
  max-width: 100%;
  aspect-ratio: 4 / 3;
  padding: 0;
  margin: 2px 0 4px;
  border: 0;
  border-radius: 10px;
  overflow: hidden;
  background: #e9eef5;
  cursor: zoom-in;
}
.chat__imagen {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.25s ease;
}
.chat__foto-estado {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px;
  font-size: 12px;
  color: #64748b;
  text-align: center;
}
/* Mientras carga: brillo que recorre la caja y el aviso encima. */
.chat__foto--cargando {
  background: linear-gradient(100deg, #e9eef5 30%, #f5f7fb 50%, #e9eef5 70%);
  background-size: 300% 100%;
  animation: chat-foto-brillo 1.3s ease-in-out infinite;
  cursor: progress;
}
.chat__foto--cargando .chat__imagen { opacity: 0; }
.chat__foto--cargando .chat__foto-estado,
.chat__foto--error .chat__foto-estado { display: flex; }
.chat__foto--error { cursor: default; }
.chat__foto--error .chat__imagen { display: none; }
@keyframes chat-foto-brillo { from { background-position: 100% 0; } to { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) { .chat__foto--cargando { animation: none; } }

/* ===== Visor de imagenes (components/visorImagenes.js) ===== */
.visor {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  flex-direction: column;
  background: rgba(8, 12, 20, 0.94);
  color: #fff;
  animation: cmms-fade-in 0.18s ease;
}
.visor[hidden] { display: none; }
.visor__barra {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  padding-top: max(10px, env(safe-area-inset-top));
  font-size: 13px;
}
.visor__contador { font-weight: 700; min-width: 44px; }
.visor__nombre { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: 0.8; }
.visor__boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 18px;
  cursor: pointer;
  text-decoration: none;
}
.visor__boton:hover { background: rgba(255, 255, 255, 0.24); }
.visor__zoom {
  min-width: 52px;
  height: 32px;
  padding: 0 8px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}
.visor__zoom:hover { background: rgba(255, 255, 255, 0.24); }
.visor__boton:disabled { opacity: 0.35; cursor: default; }
.visor__escenario {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 56px 16px;
  overflow: hidden;
  /* Los gestos (arrastrar, pellizcar) los resuelve el visor, no el navegador. */
  touch-action: none;
}
.visor__imagen {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 4px;
  cursor: zoom-in;
  user-select: none;
  -webkit-user-drag: none;
  transform-origin: center center;
  will-change: transform;
  transition: filter 0.2s ease;
}
.visor__imagen--animada { transition: filter 0.2s ease, transform 0.18s ease; }
/* Mientras llega la foto completa se ve la miniatura, desenfocada. */
.visor--cargando .visor__imagen { filter: blur(6px); }
.visor__estado {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  font-size: 13px;
}
.visor__estado:empty { display: none; }
/* Ampliada: la foto se mueve arrastrandola. */
.visor--ampliada .visor__imagen { cursor: grab; }
.visor--ampliada .visor__imagen:active { cursor: grabbing; }
/* Tira de miniaturas de la galeria. */
.visor__tira {
  display: flex;
  gap: 8px;
  padding: 8px 14px;
  padding-bottom: max(10px, env(safe-area-inset-bottom));
  overflow-x: auto;
  justify-content: safe center;
  scrollbar-width: thin;
}
.visor__tira[hidden] { display: none; }
.visor__mini {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.15s ease, border-color 0.15s ease;
}
.visor__mini:hover { opacity: 0.85; }
.visor__mini--activa { border-color: #fff; opacity: 1; }
.visor__mini img { width: 100%; height: 100%; object-fit: cover; display: block; }
.visor__flecha {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  font-size: 22px;
  cursor: pointer;
}
.visor__flecha:hover { background: rgba(255, 255, 255, 0.28); }
.visor__flecha[hidden] { display: none; }
.visor__flecha--izq { left: 8px; }
.visor__flecha--der { right: 8px; }
@media (max-width: 560px) {
  .visor__escenario { padding: 4px 4px 16px; }
  /* En el telefono se cambia de foto deslizando; las flechas quedan chicas y abajo. */
  .visor__flecha { top: auto; bottom: 12px; transform: none; width: 38px; height: 38px; font-size: 18px; }
  /* Con la tira de miniaturas ya se toca la foto que se quiere. */
  .visor--galeria .visor__flecha { display: none; }
  .visor__barra { gap: 6px; }
  .visor__boton { width: 36px; height: 36px; font-size: 16px; }
  .visor__mini { width: 48px; height: 48px; }
}

.chat__audio { display: flex; align-items: center; gap: 8px; margin: 2px 0 4px; }
/* El reproductor nativo: cambia de un navegador a otro, pero traerse uno
   propio significaria reimplementar play, barra y tiempo por gusto. */
.chat__audio audio { height: 38px; max-width: 240px; }
.chat__audio-dur { color: var(--muted, #64748b); font-size: 11px; }

.chat__archivo {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 2px 0 4px;
  padding: 8px 10px;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  background: #f8fafc;
  color: inherit;
  text-decoration: none;
  max-width: 260px;
}

.chat__archivo span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat__archivo small { color: var(--muted, #64748b); flex: 0 0 auto; }

/* ----- Botones de la barra de escritura ----- */
.chat__accion {
  flex: 0 0 auto;
  padding: 8px 10px;
  border-radius: 10px;
  font-size: 16px;
  line-height: 1;
  color: var(--muted, #64748b);
}

.chat__accion:hover { color: var(--primary, #1b4dff); background: #eef3ff; }

/* ----- Grabacion de una nota de voz ----- */
/* Sustituye a la barra de escritura mientras se graba: tener las dos a la vez
   deja en duda que va a pasar al pulsar Enviar. */
.chat__grabando {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-top: 1px solid #eef2f7;
  background: #fff;
  font-size: 13px;
}

.chat__grabando[hidden] { display: none; }
.chat__grabando-texto { flex: 1 1 auto; color: var(--muted, #64748b); }
.chat__grabando-reloj { font-variant-numeric: tabular-nums; font-weight: 600; }

/* El punto rojo que parpadea: es la senal de que el microfono esta abierto. */
.chat__rec {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #ef4444;
  animation: cmms-rec 1.1s ease-in-out infinite;
}

@keyframes cmms-rec { 50% { opacity: 0.25; } }

/* Adjunto elegido y aun sin enviar: se ve encima de la barra de escritura y
   sale al pulsar Enviar. La crea components/adjuntosChat.js. */
.chat__pendiente {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-top: 1px solid #eef2f7;
  background: #f8fafc;
  font-size: 13px;
  min-width: 0;
}

.chat__pendiente[hidden] { display: none; }
.chat__pendiente-foto {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 8px;
  flex: 0 0 auto;
}
.chat__pendiente-audio { flex: 1 1 auto; min-width: 0; max-width: 260px; height: 36px; }
.chat__pendiente-icono { font-size: 28px; color: var(--muted, #64748b); flex: 0 0 auto; }
.chat__pendiente-info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.chat__pendiente-info strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat__pendiente-info small { color: var(--muted, #64748b); }
.chat__pendiente-quitar { flex: 0 0 auto; }

/* Varios adjuntos: tira de miniaturas con desplazamiento horizontal. */
.chat__pendiente:has(.chat__pendiente-lista) { flex-direction: column; align-items: stretch; gap: 4px; }
.chat__pendiente-lista { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px; }
.chat__pendiente-item { position: relative; flex: 0 0 auto; }
.chat__pendiente-item .chat__pendiente-quitar {
  position: absolute;
  top: -4px;
  right: -4px;
  width: 22px;
  height: 22px;
  padding: 0;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.25);
  font-size: 11px;
  line-height: 1;
}
.chat__pendiente-ficha {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 56px;
  height: 56px;
  border-radius: 8px;
  background: #e2e8f0;
  color: var(--muted, #64748b);
  font-size: 20px;
}
.chat__pendiente-ficha small {
  max-width: 52px;
  font-size: 9px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chat__pendiente-resumen { color: var(--muted, #64748b); }

@media (prefers-reduced-motion: reduce) {
  .chat__rec { animation: none; }
}

@media (max-width: 720px) {
  .chat__foto { max-width: 200px; }
  .chat__audio audio { max-width: 180px; }
}

/* ===== Invitacion a activar los avisos del dispositivo ===== */
/* Va debajo de la cabecera, dentro del flujo: no es un toast que se va solo ni
   un modal que hay que cerrar. La opcion vivia en el menu de usuario y nadie
   entraba ahi, asi que el telefono del tecnico no sonaba nunca. */
.aviso-push {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 16px 32px 0;
  padding: 12px 16px;
  border: 1px solid #fde68a;
  border-radius: 14px;
  background: #fffbeb;
  color: #92400e;
  font-size: 13.5px;
}

.aviso-push__icono { font-size: 18px; flex: 0 0 auto; }
.aviso-push__texto { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.aviso-push__texto strong { color: #78350f; }
.aviso-push button { flex: 0 0 auto; }

@media (max-width: 720px) {
  /* En el telefono el texto manda y los botones bajan: es justo el dispositivo
     donde este aviso importa. */
  .aviso-push {
    margin: 14px 12px 0;
    flex-wrap: wrap;
  }
  .aviso-push__texto { flex-basis: 100%; }
  .aviso-push button { flex: 1 1 auto; }
}

/* ===== Chat interno ===== */
/* Dos paneles en escritorio (lista + hilo) y UNO en el telefono: la clase
   `chat--hilo` (la pone chat.js al abrir una conversacion) decide cual se ve.
   El alto se fija con `dvh` y no con `vh` para que el hilo no quede debajo de
   la barra del navegador ni del teclado, que es donde se escribe. */
.chat {
  display: grid;
  grid-template-columns: minmax(260px, 340px) 1fr;
  gap: 16px;
  height: calc(100dvh - 210px);
  min-height: 420px;
}

.chat__lista,
.chat__hilo {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: #fff;
  border: 1px solid #e9eef5;
  border-radius: 16px;
  overflow: hidden;
}

.chat__buscador {
  display: flex;
  gap: 8px;
  padding: 12px;
  border-bottom: 1px solid #eef2f7;
}

.chat__buscador input { flex: 1 1 auto; min-width: 0; }
.chat__nueva { flex: 0 0 auto; padding: 8px 12px; }

.chat__conversaciones {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1 1 auto;
}

.chat__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid #f3f6fa;
  cursor: pointer;
}

.chat__item:hover { background: #f8fafc; }
.chat__item--activa { background: #eef3ff; }

.chat__avatar {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #e8eefc;
  color: var(--primary, #1b4dff);
  font-weight: 700;
  font-size: 13px;
}

.chat__item-texto { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.chat__item-titulo { font-weight: 600; font-size: 14px; display: flex; align-items: center; gap: 6px; }
.chat__mute { color: var(--muted, #64748b); font-size: 12px; }

/* El adelanto del ultimo mensaje nunca parte la fila: una linea y puntos. */
.chat__item-previo {
  font-size: 12.5px;
  color: var(--muted, #64748b);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat__item-meta { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }

.chat__badge {
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--primary, #1b4dff);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  text-align: center;
}

.chat__badge--tab { margin-left: 4px; }

.chat__hilo-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border-bottom: 1px solid #eef2f7;
}

.chat__hilo-titulo { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.chat__hilo-titulo span { font-size: 12px; }
.chat__hilo-acciones { display: flex; gap: 6px; align-items: center; }

/* Menu de los tres puntos de la cabecera del hilo. */
.chat__opciones-wrap { position: relative; }
.chat__opciones {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 40;
  min-width: 210px;
  padding: 4px;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.18);
}
/* `.msg-menu__item` pone display:flex y eso anula el atributo hidden. */
.chat__opciones [hidden] { display: none; }
.chat__opciones[hidden] { display: none; }

/* "Ver orden" en la cabecera de un hilo de OT: pildora con el color de la
   marca, no un enlace suelto. */
.chat__ver-ot {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px 6px 12px;
  border-radius: 999px;
  border: 1px solid #c9d6ff;
  background: #eef3ff;
  color: var(--primary, #1b4dff);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.chat__ver-ot:hover {
  background: var(--primary, #1b4dff);
  border-color: var(--primary, #1b4dff);
  color: #fff;
  box-shadow: 0 4px 12px rgba(27, 77, 255, 0.25);
}
.chat__ver-ot:focus-visible { outline: 2px solid var(--primary, #1b4dff); outline-offset: 2px; }
.chat__ver-ot-flecha { font-size: 18px; line-height: 1; transition: transform 0.15s ease; }
.chat__ver-ot:hover .chat__ver-ot-flecha { transform: translateX(2px); }
.chat__ver-ot[hidden] { display: none; }
@media (max-width: 560px) {
  /* En el telefono la cabecera es estrecha: queda el icono y la flecha. */
  .chat__ver-ot span { display: none; }
  .chat__ver-ot { padding: 6px 6px 6px 10px; }
}
/* El "volver" es del telefono: en escritorio se ven los dos paneles a la vez. */
.chat__volver { display: none; }

.chat__mensajes {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: #f5f7fb;
}

/* Dentro de la OT el hilo va empotrado en una tarjeta, con alto propio. */
.chat__mensajes--ot {
  height: 380px;
  border: 1px solid #eef2f7;
  border-radius: 12px;
  margin-bottom: 10px;
}

.chat__mas {
  align-self: center;
  flex: none;
  padding: 4px 14px;
  border: 1px solid #cbd5e1;
  border-radius: 999px;
  background: #fff;
  color: #334155;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.chat__mas:hover:not(:disabled) { background: #f1f5f9; }
.chat__mas:disabled { opacity: .6; cursor: default; }

.chat__dia {
  align-self: center;
  padding: 2px 10px;
  border-radius: 999px;
  background: #e2e8f0;
  color: #475569;
  font-size: 11px;
  font-weight: 600;
}

.chat__burbuja {
  align-self: flex-start;
  max-width: min(74%, 520px);
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 12px;
  border-radius: 14px 14px 14px 4px;
  background: #fff;
  border: 1px solid #e9eef5;
  font-size: 14px;
}

.chat__burbuja--propia {
  align-self: flex-end;
  background: #e8eefc;
  border-color: #d7e2fb;
  border-radius: 14px 14px 4px 14px;
}

.chat__autor { font-size: 11.5px; font-weight: 700; color: var(--primary, #1b4dff); }
/* El mensaje respeta los saltos de linea que escribio quien lo mando, y parte
   las palabras largas: una URL pegada desbordaba la burbuja. */
.chat__cuerpo { white-space: pre-wrap; overflow-wrap: anywhere; }
.chat__hora { align-self: flex-end; font-size: 10.5px; color: var(--muted, #64748b); }
.chat__editado { font-style: italic; margin-right: 3px; }
.chat__estrella { color: #f59e0b; margin-right: 3px; }

/* Lista de destacados de la conversacion (#chatDestacadosModal). */
.chat__destacados { list-style: none; margin: 0; padding: 0; max-height: 60vh; overflow-y: auto; }
.chat__destacado {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 8px; border-bottom: 1px solid #f1f5f9; cursor: pointer; border-radius: 8px;
}
.chat__destacado:hover { background: #f8fafc; }
.chat__destacado-cab { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--muted, #64748b); }
.chat__destacado-cab strong { color: #0f172a; }
.chat__destacado-texto { font-size: 13.5px; white-space: pre-wrap; word-break: break-word; }

/* Buscador de la conversacion (#chatBuscarModal). Reusa la lista de destacados. */
.chat__ot-titulo { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.chat__buscar-input { width: 100%; margin: 4px 0 8px; box-sizing: border-box; }
.chat__destacado-texto mark { background: #fde68a; color: inherit; border-radius: 2px; padding: 0 1px; }

/* Barra de escritura. El campo va dentro de una "pildora" con sus botones y
   el de enviar queda fuera, redondo: con todo en una sola fila, en el telefono
   el campo se quedaba en 94 px de ancho y no se podia escribir. */
.chat__escribir {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 8px 10px;
  border-top: 1px solid #eef2f7;
  background: #f0f2f5;
}

.chat__campo {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: flex-end;
  gap: 2px;
  padding: 3px 6px;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 22px;
}

.chat__campo textarea {
  flex: 1 1 auto;
  min-width: 0;
  resize: none;
  border: 0;
  outline: none;
  background: transparent;
  max-height: 120px;
  padding: 9px 4px;
  font: inherit;
  font-size: 15px;
  line-height: 1.35;
}

/* Botones de dentro de la pildora: planos, sin marco, para que no compitan
   con el texto. */
.chat__accion {
  flex: 0 0 auto;
  border: 0;
  background: transparent;
  padding: 7px 6px;
  border-radius: 50%;
  font-size: 18px;
  line-height: 1;
  color: var(--muted, #64748b);
  cursor: pointer;
}

.chat__accion:hover { color: var(--primary, #1b4dff); background: #f1f5f9; }

/* Enviar y microfono: el circulo de siempre. Solo uno de los dos se ve. */
.chat__redondo {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--primary, #1b4dff);
  color: #fff;
  font-size: 17px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.chat__redondo[hidden] { display: none; }
.chat__redondo:hover { filter: brightness(1.08); }

.chat__vacio {
  margin: auto;
  color: var(--muted, #64748b);
  font-size: 13px;
  text-align: center;
  padding: 16px;
}

.chat__contactos { list-style: none; margin: 8px 0 0; padding: 0; max-height: 50vh; overflow-y: auto; }

.chat__contacto {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border-radius: 10px;
  cursor: pointer;
}

.chat__contacto:hover { background: #f1f5f9; }
.chat__contacto span > small { display: block; }

/* Grupos: el acceso "Nuevo grupo" del selector es un boton con la misma forma
   que una fila de contacto. */
.chat__nuevo-grupo {
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  color: inherit;
  text-align: left;
}

/* Marcar personas (nuevo grupo / agregar): la fila marcada y su check. */
.chat__check { margin-left: auto; color: #cbd5e1; font-size: 18px; }
.chat__contacto--sel { background: #eef3ff; }
.chat__contacto--sel .chat__check { color: var(--primary, #1b4dff); }

.chat__chips { list-style: none; padding: 0; margin: 8px 0 10px; display: flex; flex-wrap: wrap; gap: 6px; }
.chat__chips:empty { display: none; }
.chat__chip {
  display: inline-flex; align-items: center; gap: 2px;
  background: #eef2ff; color: #3730a3; border: 1px solid #c7d2fe;
  border-radius: 999px; padding: 2px 4px 2px 10px; font-size: 13px;
}
.chat__chip-del {
  border: 0; background: transparent; color: #4338ca; cursor: pointer;
  padding: 0 2px; border-radius: 50%; line-height: 1;
}
.chat__chip-del:hover { background: #c7d2fe; }

/* Modal del grupo. Mas ancho que el modal por defecto (360 px): cada fila lleva
   nombre y dos acciones, y con 360 el nombre se partia en dos lineas. */
#chatGrupoModal .modal__content { max-width: 440px; }
.chat__grupo-bloque { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.chat__grupo-nombre { display: flex; gap: 8px; }
.chat__grupo-nombre-fijo { display: flex; flex-direction: column; gap: 2px; }
.chat__grupo-nombre input { flex: 1 1 auto; min-width: 0; }
.chat__grupo-cabecera { display: flex; align-items: center; justify-content: space-between; margin-top: 4px; }
.chat__miembro { cursor: default; }
.chat__miembro:hover { background: transparent; }
.chat__miembro-nombre { flex: 1 1 auto; min-width: 0; }
.chat__miembro-acciones { display: flex; gap: 4px; flex: 0 0 auto; }

@media (max-width: 860px) {
  /* Un panel cada vez: la lista, o el hilo abierto. */
  .chat { grid-template-columns: 1fr; height: calc(100dvh - 190px); }
  .chat .chat__hilo { display: none; }
  .chat.chat--hilo .chat__lista { display: none; }
  .chat__volver { display: inline-flex; }
  .chat__burbuja { max-width: 86%; }

  /* La conversacion abierta ocupa la PANTALLA ENTERA, como en cualquier chat
     de telefono. Antes quedaba dentro del flujo de la pagina, debajo de la
     cabecera, del titulo de la seccion y del aviso de notificaciones: el campo
     de escritura acababa a 900 px del borde superior en una pantalla de 727,
     o sea fuera, y habia que hacer scroll de toda la pagina para escribir. */
  .chat.chat--hilo .chat__hilo {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 900; /* sobre la cabecera (10), bajo los modales (1000) */
    border: 0;
    border-radius: 0;
  }

  .chat.chat--hilo .chat__hilo-head {
    padding: 10px 12px;
    /* Hueco de la barra de estado en un movil con muesca. */
    padding-top: max(10px, env(safe-area-inset-top));
  }

  .chat.chat--hilo .chat__escribir {
    padding-bottom: max(8px, env(safe-area-inset-bottom));
  }

  .chat__campo textarea { font-size: 16px; } /* menos de 16 px y iOS hace zoom */

  /* Sin hover no hay forma de descubrir el menu: se deja visible. */
  .chat__menu-btn { opacity: 0.5; }
}

.skeleton {
  width: 140px;
  height: 10px;
  background: linear-gradient(90deg, #e2e8f0, #f8fafc, #e2e8f0);
  border-radius: 999px;
  animation: shimmer 1.6s infinite;
  margin-top: 20px;
}

@keyframes shimmer {
  0% { background-position: -120px; }
  100% { background-position: 120px; }
}

.muted { color: var(--muted); }

@media (max-width: 1024px) {
  /* En tablet/movil el layout es de UNA sola columna siempre, incluso si el
     usuario dejo el sidebar colapsado en escritorio. Sin incluir
     `body.sidebar-collapsed .app` aqui, esa regla (mayor especificidad) seguiria
     forzando `88px 1fr` y, como el sidebar pasa a position:fixed, el .main caia
     en la columna de 88px y todo el contenido quedaba aplastado. */
  .app,
  body.sidebar-collapsed .app {
    grid-template-columns: 1fr;
  }

  .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    width: min(280px, 82vw);
    transform: translateX(-100%);
    transition: transform 0.3s ease;
    z-index: 20;
  }

  /* El "colapsado" es un concepto de escritorio. En el drawer movil mostramos
     siempre el ancho y las etiquetas completas para que sea navegable. */
  .sidebar.collapsed {
    width: min(280px, 82vw);
  }

  .sidebar.collapsed .sidebar__brand h1,
  .sidebar.collapsed .sidebar__brand span,
  .sidebar.collapsed .sidebar__nav a span,
  .sidebar.collapsed .sidebar__footer button {
    display: revert;
  }

  .sidebar.open {
    transform: translateX(0);
  }

  .header {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (max-width: 720px) {
  .header {
    padding: 12px 14px;
    gap: 12px;
  }

  .header__left {
    width: 100%;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 14px;
  }

  .header__left h2 {
    font-size: 17px;
  }

  .header__left .select {
    width: 100%;
  }

  .header__left .select select {
    width: 100%;
  }

  .header__right {
    width: 100%;
    justify-content: flex-start;
    gap: 10px;
  }

  .header__right .user {
    margin-left: auto;
    text-align: right;
  }

  .section__header {
    flex-direction: column;
    align-items: stretch;
  }

  /* Los botones de accion ocupan el ancho en movil, pero el "?" de ayuda NO:
     esta dentro del <h3>, es un circulo de 20px y con width:100% salia como un
     ovalo aplastado de lado a lado. */
  .section__header button:not(.help-btn) {
    width: 100%;
    justify-content: center;
  }

  /* Aprovechar el ancho de pantalla en móvil: el contenedor principal y las
     tarjetas tenían demasiado padding lateral (32px + 20px) y desperdiciaban
     ~50px por lado en pantallas chicas. */
  .main {
    padding: 16px 12px 72px;
  }

  .content {
    margin-top: 18px;
    gap: 14px;
  }

  .card,
  .table-card,
  .card.filters,
  .kpi {
    padding: 14px;
  }

  /* Las tablas (DataTables) hacen scroll horizontal dentro de su tarjeta: que la
     tarjeta no añada padding lateral para ganar ancho útil. */
  .table-card {
    padding: 12px 10px;
  }
}

/* En teléfonos muy estrechos, pegar aún más el contenido a los bordes. */
@media (max-width: 430px) {
  .main {
    padding: 14px 8px 68px;
  }
  .card,
  .card.filters,
  .kpi {
    padding: 12px;
  }
}

/* ===== Loaders / Spinners ===== */
/* El loader global esta OCULTO por defecto y solo se muestra con .active.
   Sin estas reglas el overlay "Cargando aplicacion..." quedaba visible para siempre. */
.global-loader {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

.global-loader.active {
  display: flex;
}

.global-loader .loader-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
}

.global-loader .loader-content {
  position: relative;
  background: #fff;
  padding: 28px 40px;
  border-radius: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  box-shadow: 0 12px 40px rgba(15, 23, 42, 0.2);
}

.loader {
  width: 40px;
  height: 40px;
  border: 4px solid #e2e8f0;
  border-top-color: var(--primary, #1b4dff);
  border-radius: 50%;
  animation: cmms-spin 0.8s linear infinite;
}

.spinner,
.spinner-small {
  width: 20px;
  height: 20px;
  border: 3px solid #e2e8f0;
  border-top-color: var(--primary, #1b4dff);
  border-radius: 50%;
  animation: cmms-spin 0.8s linear infinite;
  display: inline-block;
}

.spinner-small {
  width: 14px;
  height: 14px;
  border-width: 2px;
  vertical-align: middle;
}

@keyframes cmms-spin {
  to { transform: rotate(360deg); }
}

/* Un boton deshabilitado tiene que VERSE deshabilitado: hasta ahora solo lo
   parecia .dt-btn, y un boton bloqueado mientras guarda se veia igual que uno
   activo que "no responde". */
button:disabled {
  cursor: not-allowed;
  opacity: 0.65;
}

/* Barra de progreso de guardado (components/barraProgreso.js, la maneja api.js). */
.barra-progreso {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 10001;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.barra-progreso.activa {
  opacity: 1;
}

.barra-progreso::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -40%;
  width: 40%;
  background: var(--primary, #1b4dff);
  border-radius: 0 3px 3px 0;
  animation: cmms-barra-progreso 1.1s ease-in-out infinite;
}

@keyframes cmms-barra-progreso {
  to { left: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .barra-progreso::before {
    left: 0;
    width: 100%;
    animation: none;
    opacity: 0.7;
  }
}

/* Tarjeta del Kanban mientras se guarda su cambio de estado (ver moverOrden). */
.kanban-card--guardando {
  position: relative;
  opacity: 0.6;
  pointer-events: none;
}

.kanban-card--guardando::after {
  content: "";
  position: absolute;
  top: 10px;
  right: 10px;
  width: 16px;
  height: 16px;
  border: 2px solid #e2e8f0;
  border-top-color: var(--primary, #1b4dff);
  border-radius: 50%;
  animation: cmms-spin 0.8s linear infinite;
}

.loader-text {
  color: var(--muted, #64748b);
  font-size: 14px;
  margin: 0;
}

.loader-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 48px 16px;
  color: var(--muted, #64748b);
}

.loader-inline,
.inline-loader,
.loader-overlay {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px;
  color: var(--muted, #64748b);
}

.loader-overlay {
  position: absolute;
  inset: 0;
  flex-direction: column;
  background: rgba(255, 255, 255, 0.7);
}

td.loading,
td.empty,
td.error {
  text-align: center;
  color: var(--muted, #64748b);
  padding: 24px;
}

.empty-state,
.error-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: var(--muted, #64748b);
  padding: 16px;
}

.empty-state i,
.error-state i {
  font-size: 28px;
  opacity: 0.6;
}

/* ===== Kanban de ordenes ===== */
.kanban {
  display: grid;
  grid-template-columns: repeat(5, minmax(220px, 1fr));
  gap: 16px;
  align-items: start;
  margin-top: 20px;
  overflow-x: auto;
  padding-bottom: 8px;
}

.kanban__col {
  background: #f1f5f9;
  border-radius: 14px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}

.kanban__col.drag-over {
  background: #e0e7ff;
  box-shadow: inset 0 0 0 2px var(--primary);
}

/* Color por estado para identificar cada columna de un vistazo. Cada columna
   lleva una franja superior, fondo tenue y badge/encabezado en su color. */
.kanban__col {
  border-top: 3px solid transparent;
}
.kanban__col[data-estado="pendiente"]  { border-top-color: #f59e0b; background: #fffbeb; }
.kanban__col[data-estado="en_proceso"] { border-top-color: #0ea5e9; background: #f0f9ff; }
.kanban__col[data-estado="pausada"]    { border-top-color: #94a3b8; background: #f8fafc; }
.kanban__col[data-estado="finalizada"] { border-top-color: #16a34a; background: #f0fdf4; }
.kanban__col[data-estado="cancelada"]  { border-top-color: #ef4444; background: #fef2f2; }

.kanban__col[data-estado="pendiente"]  .kanban__col-header,
.kanban__col[data-estado="pendiente"]  .kanban__col-header i { color: #b45309; }
.kanban__col[data-estado="en_proceso"] .kanban__col-header,
.kanban__col[data-estado="en_proceso"] .kanban__col-header i { color: #0369a1; }
.kanban__col[data-estado="pausada"]    .kanban__col-header,
.kanban__col[data-estado="pausada"]    .kanban__col-header i { color: #475569; }
.kanban__col[data-estado="finalizada"] .kanban__col-header,
.kanban__col[data-estado="finalizada"] .kanban__col-header i { color: #15803d; }
.kanban__col[data-estado="cancelada"]  .kanban__col-header,
.kanban__col[data-estado="cancelada"]  .kanban__col-header i { color: #b91c1c; }

.kanban__col[data-estado="pendiente"]  .kanban__count { background: #f59e0b; color: #fff; }
.kanban__col[data-estado="en_proceso"] .kanban__count { background: #0ea5e9; color: #fff; }
.kanban__col[data-estado="pausada"]    .kanban__count { background: #94a3b8; color: #fff; }
.kanban__col[data-estado="finalizada"] .kanban__count { background: #16a34a; color: #fff; }
.kanban__col[data-estado="cancelada"]  .kanban__count { background: #ef4444; color: #fff; }

.kanban__col-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
  font-size: 14px;
  color: var(--text);
  padding: 4px 4px 0;
}

.kanban__col-header i {
  color: var(--muted);
  margin-right: 4px;
}

.kanban__count {
  background: #fff;
  color: var(--muted);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 12px;
  font-weight: 600;
}

.kanban__nota { margin: -4px 0 6px; font-size: 11px; color: var(--muted, #64748b); }
.kanban__nota:empty { display: none; }
.kanban__cards {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 60px;
}

.kanban__msg {
  color: var(--muted);
  font-size: 13px;
  text-align: center;
  padding: 16px 8px;
  margin: 0;
}

.kanban-card {
  background: #fff;
  border: 1px solid #e9eef5;
  border-radius: 12px;
  padding: 12px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: box-shadow 0.15s ease, opacity 0.1s ease;
}

.kanban-card:hover {
  box-shadow: 0 6px 16px rgba(15, 23, 42, 0.1);
}

.kanban-card.dragging {
  opacity: 0.45;
}

.kanban-card__top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}

.kanban-card__code {
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
}

.kanban-card__equipo {
  font-size: 13px;
  color: var(--text);
  margin: 0;
}

.kanban-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-size: 12px;
  color: var(--muted);
}

.kanban-card__meta i {
  margin-right: 3px;
}

.kanban-card__assign {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted);
}

.kanban-card__assign select {
  flex: 1;
  min-width: 0;
  padding: 5px 8px;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  font-size: 12px;
  background: #fff;
  cursor: pointer;
}

/* En pantallas estrechas, columnas en carrusel horizontal. */
@media (max-width: 1024px) {
  .kanban {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(240px, 78%);
  }
}

/* ===== Permisos de rol (RBAC) ===== */
.permisos-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  margin: 4px 0 16px;
}

.permisos-toolbar #permisosSearch {
  flex: 1 1 220px;
  min-width: 180px;
  padding: 9px 12px;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  font-size: 14px;
}

.permisos-toolbar__actions {
  display: flex;
  gap: 8px;
}

.permisos-toolbar__actions .ghost {
  padding: 7px 12px;
  font-size: 13px;
}

.permisos-count {
  color: var(--muted, #64748b);
  font-size: 13px;
  margin-left: auto;
  white-space: nowrap;
}

.permisos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
}

.permiso-modulo {
  border: 1px solid #e2e8f0;
  border-radius: 14px;
  background: #f8fafc;
  overflow: hidden;
}

.permiso-modulo__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 14px;
  background: #fff;
  border-bottom: 1px solid #e2e8f0;
}

.permiso-modulo__title {
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: #0f172a;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.permiso-modulo__title i {
  color: var(--primary, #1b4dff);
}

.permiso-modulo__all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted, #64748b);
  cursor: pointer;
  white-space: nowrap;
}

.permiso-modulo__items {
  display: flex;
  flex-direction: column;
  padding: 8px 6px;
}

.permiso-item {
  display: flex;
  /* Arriba y no al centro: con la descripcion debajo, la casilla tiene que
     quedar a la altura del nombre de la accion, no en mitad del parrafo. */
  align-items: flex-start;
  gap: 9px;
  padding: 7px 10px;
  border-radius: 8px;
  font-size: 14px;
  color: #1e293b;
  cursor: pointer;
  transition: background 0.12s ease;
}

.permiso-item:hover {
  background: #eef2ff;
}

/* Que desbloquea el permiso, debajo de su nombre. */
.permiso-item__texto { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.permiso-item__accion { line-height: 1.35; }
.permiso-item__desc {
  font-size: 12px; line-height: 1.45; color: var(--muted, #64748b);
  /* Sin esto, una descripcion larga estira la tarjeta del modulo. */
  text-wrap: pretty;
}

.permiso-item input[type="checkbox"] { margin-top: 2px; flex: 0 0 auto; }

.permiso-item input[type="checkbox"],
.permiso-modulo__all input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--primary, #1b4dff);
  cursor: pointer;
}

/* ===== Detalle de tecnico (KPIs) ===== */
.tecnico-detail { display: flex; flex-direction: column; gap: 16px; }

.tecnico-detail__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.tecnico-detail__id { display: flex; align-items: center; gap: 14px; }

.tecnico-detail__avatar {
  width: 52px;
  height: 52px;
  border-radius: 14px;
  background: linear-gradient(135deg, #1b4dff, #0ea5e9);
  color: #fff;
  font-weight: 700;
  font-size: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.tecnico-detail__id h4 { margin: 0; font-size: 18px; }
.tecnico-detail__id p { margin: 2px 0 0; font-size: 13px; }

.tecnico-detail__periodo {
  font-size: 12px;
  color: var(--muted, #64748b);
  background: #f1f5f9;
  border-radius: 999px;
  padding: 6px 12px;
  white-space: nowrap;
}

.kpi-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 12px;
}

.kpi-tile {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border: 1px solid #e2e8f0;
  border-radius: 14px;
  background: #fff;
}

.kpi-tile__icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  flex: 0 0 auto;
  background: #eef2ff;
  color: #1b4dff;
}

.kpi-tile--success .kpi-tile__icon { background: #dcfce7; color: #16a34a; }
.kpi-tile--warning .kpi-tile__icon { background: #fef3c7; color: #b45309; }
.kpi-tile--danger  .kpi-tile__icon { background: #fee2e2; color: #dc2626; }
.kpi-tile--info    .kpi-tile__icon { background: #e0f2fe; color: #0284c7; }
.kpi-tile--neutral .kpi-tile__icon { background: #f1f5f9; color: #475569; }

.kpi-tile__body { display: flex; flex-direction: column; min-width: 0; }
.kpi-tile__value { font-size: 20px; font-weight: 700; color: #0f172a; line-height: 1.1; }
.kpi-tile__label { font-size: 12px; color: #475569; margin-top: 2px; }
.kpi-tile__hint { font-size: 11px; color: #94a3b8; margin-top: 2px; }

/* Lista compacta etiqueta/valor reutilizada en el detalle del tecnico. */
.kpi-mini { display: flex; flex-direction: column; gap: 2px; }
.kpi-mini > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px dashed #e2e8f0;
}
.kpi-mini > div:last-child { border-bottom: 0; }
.kpi-mini span { color: var(--muted, #64748b); font-size: 13px; }
.kpi-mini strong { font-size: 15px; color: #0f172a; }

.tecnico-detail .chart canvas { max-height: 240px; }

/* Detalle del tecnico como pagina */
.tecnico-detail__topbar { margin-bottom: 2px; }

.hint-click { font-size: 11px; font-weight: 400; margin-left: 6px; }

/* Filas clicables de carga / tipo / prioridad */
.kpi-mini .kpi-mini__row {
  padding: 8px;
  margin: 0 -8px;
  cursor: pointer;
  border-radius: 8px;
  transition: background 0.12s ease;
}
.kpi-mini .kpi-mini__row:hover { background: #eff3ff; }
.kpi-mini__row strong i { font-size: 11px; color: #94a3b8; margin-left: 2px; }

/* Detalle de OT por categoria (drill-down) */
.tecnico-drill__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.tecnico-drill__head h5 { margin: 0; }
.tecnico-drill__total { margin: 12px 2px 0; font-size: 13px; color: #475569; }

.table-card th.num, .table-card td.num { text-align: right; }

/* Oculta la columna de costo de M.O. cuando el rol no tiene permiso de costos. */
#tecnicoDrillCard.hide-costo .col-costo { display: none; }

/* Select con creacion de opciones inline (boton "+" en el formulario). */
.select-creatable__row { display: flex; gap: 8px; align-items: center; }
.select-creatable__row select { flex: 1; min-width: 0; }
.select-creatable__add {
  flex: 0 0 auto;
  padding: 8px 11px;
  border: 1px dashed var(--border, #cbd5e1);
  border-radius: 8px;
  cursor: pointer;
}
.select-creatable__add:hover { color: var(--primary); border-color: var(--primary); background: #eef2ff; }

/* Aviso de version nueva disponible. Solo sale cuando la app NO puede recargarse
   sola (hay un formulario abierto encima), asi que va fija y no se va sola. */
.aviso-actualizacion {
  position: fixed;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100vw - 32px);
  padding: 10px 14px;
  border-radius: 999px;
  background: #0f172a;
  color: #fff;
  font-size: 13px;
  box-shadow: var(--shadow);
  /* Sobre el modal (1000) y sobre el toast (1100): es lo unico que resuelve. */
  z-index: 1300;
}

.aviso-actualizacion__btn {
  flex: 0 0 auto;
  padding: 6px 12px;
  border: 0;
  border-radius: 999px;
  background: var(--primary, #1b4dff);
  color: #fff;
  font-size: 13px;
  cursor: pointer;
}

/* Aviso de por que no se guardo, dentro del propio modal del formulario, y
   marca del campo que falta. El toast dura unos segundos en una esquina: quien
   mira el formulario se quedaba con la modal abierta y sin explicacion. */
.form-error {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 14px 0 0;
  padding: 10px 12px;
  border: 1px solid #fecaca;
  border-radius: 10px;
  background: #fef2f2;
  color: #b91c1c;
  font-size: 13px;
  line-height: 1.4;
}

.form-error[hidden] { display: none; }

input.campo--error,
select.campo--error,
textarea.campo--error,
.search-select.campo--error .search-select__input {
  border-color: #ef4444;
  box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.15);
}

/* Modal de creacion rapida (p. ej. "Nueva categoria"), apilado sobre el modal
   del formulario sin alterar su layout. */
.modal.modal--stack { z-index: 1200; }
.cc-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 4px; }
.cc-field .cc-input { width: 100%; }

/* ===== Header: menus, dropdowns y perfil ===== */
.header-menu { position: relative; }

.icon { position: relative; }

.icon-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: #ef4444;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.user-trigger {
  display: flex;
  align-items: center;
  gap: 10px;
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 12px;
  transition: background 0.15s ease;
}
.user-trigger:hover { background: rgba(15, 23, 42, 0.05); }
.user-trigger__caret { color: var(--muted, #64748b); font-size: 12px; }

.dropdown {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 260px;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 14px;
  box-shadow: 0 16px 40px rgba(15, 23, 42, 0.16);
  padding: 8px;
  z-index: 50;
  display: none;
  animation: cmms-fade-in 0.12s ease;
}
.dropdown.open { display: block; }
.dropdown--right { right: 0; }

.dropdown__title {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted, #64748b);
  padding: 6px 10px;
}

.dropdown__body { max-height: 320px; overflow-y: auto; }

.dropdown__empty {
  color: var(--muted, #64748b);
  font-size: 13px;
  text-align: center;
  padding: 18px 8px;
  margin: 0;
}

.dropdown__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border: 0;
  background: transparent;
  border-radius: 10px;
  font-size: 14px;
  color: #1e293b;
  text-align: left;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.12s ease;
}
.dropdown__item:hover { background: #eef2ff; }
.dropdown__item i { color: var(--muted, #64748b); width: 16px; text-align: center; }
.dropdown__item--danger { color: #dc2626; }
.dropdown__item--danger:hover { background: #fef2f2; }
.dropdown__item--danger i { color: #dc2626; }

.dropdown__sep { height: 1px; background: #e2e8f0; margin: 6px 4px; }

.dropdown__user {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
}
.dropdown__user strong { display: block; font-size: 14px; }
.dropdown__user .muted { font-size: 12px; }
/* Un correo largo se parte en vez de ensanchar el menu fuera de la pantalla. */
.dropdown__user > div { min-width: 0; }
.dropdown__user strong,
.dropdown__user .muted { overflow-wrap: anywhere; }

.dropdown__foot {
  font-size: 11px;
  color: #94a3b8;
  padding: 8px 10px 4px;
  text-align: center;
}

.notif-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  font-size: 14px;
  color: #1e293b;
  text-decoration: none;
  transition: background 0.12s ease;
}
.notif-item:hover { background: #eef2ff; }
.notif-item__icon {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  background: #e0f2fe;
  color: #0284c7;
}
.notif-item__icon--danger { background: #fee2e2; color: #dc2626; }
.notif-item__icon--success { background: #dcfce7; color: #16a34a; }
.notif-item__icon--info { background: #e0f2fe; color: #0284c7; }

.perfil-head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
}
.perfil-head strong { display: block; font-size: 16px; }
.perfil-head .muted { font-size: 13px; }
.avatar--lg { width: 52px; height: 52px; font-size: 18px; border-radius: 14px; }

.field { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: #475569; }
.field input {
  padding: 9px 12px;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  font-size: 14px;
}

@media (max-width: 720px) {
  .user-trigger .user { display: none; }

  /* En móvil los botones del header se empacan a la izquierda, así que un menú
     anclado con `right: 0` se desbordaba por el borde izquierdo y cortaba las
     opciones. Se anclan a la IZQUIERDA de su botón (extienden hacia la derecha,
     donde sí hay espacio) y se limitan al ancho de pantalla. */
  .header-menu .dropdown,
  .header-menu .dropdown--right {
    left: 0;
    right: auto;
    min-width: 0;
    width: max-content;
    max-width: calc(100vw - 20px);
  }
}

/* ===== Detalle de OT (pagina) — diseño elegante ===== */
#ordenBody { display: flex; flex-direction: column; gap: 20px; }

.ot-head {
  position: relative; overflow: hidden; padding-left: 28px;
  display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap;
}
.ot-head::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 6px; background: var(--primary);
}
.ot-head[data-estado="pendiente"]::before { background: #f59e0b; }
.ot-head[data-estado="en_proceso"]::before { background: #0ea5e9; }
.ot-head[data-estado="pausada"]::before  { background: #94a3b8; }
.ot-head[data-estado="finalizada"]::before { background: #16a34a; }
.ot-head[data-estado="cancelada"]::before { background: #ef4444; }

.ot-head__main { flex: 1 1 340px; min-width: 0; }
.ot-head__title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ot-head__title h3 { margin: 0; font-size: 22px; letter-spacing: -0.01em; }
.ot-head__actions { display: flex; flex-direction: column; align-items: flex-end; gap: 12px; }
.ot-acciones { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.ot-acciones button { padding: 9px 14px; border-radius: 10px; }

.ot-meta {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px; margin: 18px 0 14px;
}
.ot-meta > div {
  display: flex; flex-direction: column; gap: 2px;
  background: #f8fafc; border: 1px solid #eef2f7; border-radius: 12px; padding: 10px 12px;
}
.ot-meta span { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted, #64748b); }
.ot-meta strong { font-size: 14px; color: #0f172a; font-weight: 600; }
.ot-desc { margin: 4px 0 0; color: #334155; background: #f8fafc; border: 1px solid #eef2f7; border-radius: 12px; padding: 12px 14px; }

/* Encabezados de las tarjetas de seccion */
#ordenBody .card > h5 {
  display: flex; align-items: center; gap: 8px; margin: 0 0 14px;
  font-size: 15px; padding-bottom: 10px; border-bottom: 1px solid #eef2f7;
}
#ordenBody .card > h5 i { color: var(--primary); }

.ot-add { display: flex; gap: 8px; margin: 0 0 14px; flex-wrap: wrap; }
.ot-add input, .ot-add select {
  flex: 1 1 140px; padding: 10px 12px; border: 1px solid #e2e8f0; border-radius: 10px; font-size: 14px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.ot-add input:focus, .ot-add select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(27,77,255,.12); }
.ot-add button { white-space: nowrap; }

.ot-list { list-style: none; padding: 0; margin: 0; }
.ot-list li { display: flex; justify-content: space-between; gap: 10px; padding: 10px 8px; border-radius: 8px; font-size: 14px; }
.ot-list li:nth-child(odd) { background: #f8fafc; }
.ot-total { text-align: right; font-weight: 700; margin: 12px 4px 0; color: #0f172a; }
.ot-crono { margin-bottom: 14px; padding: 12px 14px; border: 1px solid #e2e8f0; border-radius: 12px; background: #f8fafc; }
.ot-crono__cab { font-weight: 700; margin-bottom: 8px; color: #0f172a; }
.ot-crono__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.ot-crono__fila { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.ot-crono__quien { flex: 1 1 160px; }
.ot-crono__tiempo { font-variant-numeric: tabular-nums; font-size: 1.25rem; }
.ot-crono__acciones, .ot-crono__nuevo { display: flex; gap: 8px; flex-wrap: wrap; }
.ot-crono__nuevo { margin-top: 8px; }

.aviso-alcance { display: flex; gap: 12px; align-items: flex-start; border-left: 4px solid var(--primary); }
.aviso-alcance > i { font-size: 20px; color: var(--primary); line-height: 1.2; }
.aviso-alcance p { margin: 4px 0 0; color: #475569; font-size: 14px; }
.aviso-alcance code { background: #f1f5f9; padding: 1px 5px; border-radius: 4px; font-size: 13px; }

/* Sub-pestanas Usuarios / Roles dentro de su panel */
.subtabs__header { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.subtabs__header button {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--border, #e2e8f0); background: #fff;
  padding: 9px 16px; border-radius: 12px; font-size: 14px; font-weight: 500;
}
.subtabs__header button i { color: var(--muted, #64748b); }
.subtabs__header button:hover { background: #f1f5f9; }
.subtabs__header button.active {
  background: var(--primary, #1b4dff); color: #fff; border-color: transparent;
}
.subtabs__header button.active i { color: #fff; }
.subtab-panel { display: none; }
.subtab-panel.active { display: block; }

/* Menu del modulo de Configuracion: vertical a la izquierda, contenido a la
   derecha. Con nombres largos ("Aplicacion instalable (PWA)") una fila de
   pestanas se parte en dos lineas y se lee peor que una lista. */
.config-tabs {
  display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 22px; align-items: start;
}
.config-tabs .tabs__header {
  flex-direction: column; gap: 4px; margin: 0; padding: 0;
  /* Acompana al contenido al hacer scroll: los paneles son largos. */
  position: sticky; top: 16px;
}
.config-tabs .tabs__header button {
  width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; text-align: left; font-size: 14px; font-weight: 500;
  border-color: transparent; background: transparent;
}
.config-tabs .tabs__header button i { font-size: 16px; color: var(--muted, #64748b); flex: 0 0 auto; }
.config-tabs .tabs__header button:hover { background: #f1f5f9; }
/* Hace falta repetir el activo: `.config-tabs .tabs__header button` tiene la
   misma especificidad que `.tabs__header button.active` y, al ir despues en el
   archivo, le ganaba el fondo transparente y el elegido no se distinguia. */
.config-tabs .tabs__header button.active {
  background: var(--primary, #1b4dff); color: #fff; border-color: transparent;
}
.config-tabs .tabs__header button.active i { color: #fff; }
/* El contenido ya no necesita el margen que separaba una tarjeta de la anterior. */
.config-tabs .tab-panel > .card:first-child { margin-top: 0; }

@media (max-width: 900px) {
  /* Sin sitio para dos columnas: el menu pasa arriba, a lo ancho. */
  .config-tabs { grid-template-columns: 1fr; gap: 14px; }
  .config-tabs .tabs__header {
    position: static; padding-bottom: 12px;
    border-bottom: 1px solid var(--border, #e2e8f0);
  }
}

/* Aviso de inspeccion sin OT, con el boton para generarla. */
.insp-sin-ot {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: #fffbeb; border: 1px solid #fde68a; border-left: 4px solid #f59e0b;
  border-radius: 10px; padding: 12px 14px; margin-bottom: 16px;
}
.insp-sin-ot > i { font-size: 20px; color: #b45309; }
.insp-sin-ot__texto { flex: 1 1 260px; min-width: 0; }
.insp-sin-ot__texto strong { display: block; font-size: 14px; }
.insp-sin-ot__texto .help-text { margin: 2px 0 0; }
.insp-sin-ot select { flex: 0 0 auto; }
.insp-sin-ot button { flex: 0 0 auto; }

/* Estado de la app instalable (Configuracion > PWA) */
.pwa-estado {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: #f8fafc; border: 1px solid #e2e8f0; border-left: 4px solid var(--primary);
  border-radius: 10px; padding: 12px 14px;
}
.pwa-estado > i { font-size: 20px; color: var(--primary); }
.pwa-estado > div { flex: 1 1 220px; min-width: 0; }
.pwa-estado button { flex: 0 0 auto; }
.pwa-estado--ok { border-left-color: var(--success, #16a34a); }
.pwa-estado--ok > i { color: var(--success, #16a34a); }
/* Un <input type="color"> con los estilos generales sale diminuto y se queda
   pegado a su etiqueta, como si faltara el campo. Se le da el ancho del resto. */
#configuracion input[type="color"] {
  display: block; width: 100%; height: 42px; padding: 4px; cursor: pointer;
}

/* Logo de la etiqueta QR (Configuracion > Impresora de etiquetas) */
.logo-etiqueta {
  display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap;
  margin-top: 18px; padding-top: 18px; border-top: 1px solid #e2e8f0;
}
.logo-etiqueta__preview {
  width: 180px; min-height: 78px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed #cbd5e1; border-radius: 8px; padding: 10px;
  background: #fff; background-image:
    linear-gradient(45deg, #f1f5f9 25%, transparent 25%, transparent 75%, #f1f5f9 75%),
    linear-gradient(45deg, #f1f5f9 25%, transparent 25%, transparent 75%, #f1f5f9 75%);
  background-size: 14px 14px; background-position: 0 0, 7px 7px;
}
.logo-etiqueta__preview img { max-width: 100%; max-height: 60px; object-fit: contain; }
.logo-etiqueta__acciones { flex: 1 1 260px; min-width: 0; }
.logo-etiqueta__botones { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }

.ot-list__right { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.ot-list__del {
  border: 0; background: transparent; color: #b91c1c; cursor: pointer;
  padding: 2px 5px; border-radius: 6px; line-height: 1; font-size: 12px;
}
.ot-list__del:hover { background: #fee2e2; }
.ot-list__del:focus-visible { outline: 2px solid #b91c1c; outline-offset: 1px; }
.ot-list__meta { display: block; color: #64748b; font-size: 12px; margin-top: 2px; }

/* Mano de obra: cuadrilla (chips) y ventana de trabajo */
.ot-chips { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.ot-chips:empty { display: none; }
.ot-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: #eef2ff; color: #3730a3; border: 1px solid #c7d2fe;
  border-radius: 999px; padding: 4px 6px 4px 12px; font-size: 13px;
}
.ot-chip__del {
  border: 0; background: transparent; color: #4338ca; cursor: pointer;
  padding: 0 2px; border-radius: 50%; line-height: 1; font-size: 13px;
}
.ot-chip__del:hover { background: #c7d2fe; }
.ot-chip__del:focus-visible { outline: 2px solid #4338ca; outline-offset: 1px; }
.ot-field { flex: 1 1 150px; display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: #64748b; }
.ot-hint { margin: 0; font-size: 12px; color: #64748b; }
.ot-add input[readonly] { background: #f1f5f9; color: #475569; }

/* Datos de contacto de soporte (#soporteModal). */
.soporte-list { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.soporte-list li { display: flex; align-items: flex-start; gap: 11px; }
.soporte-list li > i { font-size: 16px; color: var(--primary, #1b4dff); width: 20px; text-align: center; flex: none; margin-top: 2px; }
.soporte-list span { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted, #64748b); }
.soporte-list a { font-size: 14px; color: var(--text, #1f2a37); text-decoration: none; word-break: break-word; }
.soporte-list a:hover { color: var(--primary, #1b4dff); text-decoration: underline; }

.soporte-redes { display: flex; gap: 10px; justify-content: center; padding: 12px 0 4px; border-top: 1px solid var(--border, #e2e8f0); }
.soporte-redes a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: #f1f5f9; color: var(--muted, #64748b); font-size: 16px;
  text-decoration: none; transition: background .15s ease, color .15s ease;
}
.soporte-redes a:hover { background: var(--primary, #1b4dff); color: #fff; }

/* El "Visitar el sitio" es un enlace, no un boton (abre otra pestana sin JS),
   pero `button.primary` solo aplica a <button>: aqui se le da el mismo aspecto. */
.modal__actions a.primary {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 16px; border-radius: 12px;
  font-weight: 600; font-size: 14px;
  background: var(--primary, #1b4dff); color: #fff; text-decoration: none;
}

/* Boton "?" junto al titulo del modulo: abre el manual por su seccion. */
.help-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; margin-left: 8px; padding: 0;
  /* Tamano fijo pase lo que pase: el boton cuelga del <h3> del modulo y acaba
     dentro de contenedores flex ajenos que, sin esto, lo encogen a un ovalo. */
  min-width: 20px; flex: 0 0 auto;
  vertical-align: middle;
  border: 1px solid var(--border, #e2e8f0); border-radius: 50%;
  background: var(--card, #fff); color: var(--muted, #64748b);
  font-size: 11px; line-height: 1; cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.help-btn:hover { background: var(--primary, #1b4dff); border-color: var(--primary, #1b4dff); color: #fff; }
.help-btn:focus-visible { outline: 2px solid var(--primary, #1b4dff); outline-offset: 2px; }
/* No debe salir en el papel: es un control, no contenido. */
@media print { .help-btn { display: none !important; } }

/* ===== Recorrido guiado (components/tour.js y components/guia.js) ===== */

/* Boton de recorrido junto al "?": mismo tamano, con el color de la marca para
   distinguirlo del que abre el manual. */
.help-btn--tour { color: var(--primary, #1b4dff); border-color: currentColor; }
.help-btn--tour:hover { color: #fff; }

/* Invitacion de primera vez, arriba de la vista del modulo. Discreta: no tapa
   nada y se cierra con un clic. */
.guia-invitacion {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 0 0 16px; padding: 12px 16px;
  background: #eef2ff; border: 1px solid #c7d2fe; border-radius: var(--radius, 12px);
  color: var(--text, #1f2a37); font-size: 14px; line-height: 1.4;
  animation: guia-entrada .25s ease;
}
.guia-invitacion__icono { font-size: 22px; color: var(--primary, #1b4dff); flex: 0 0 auto; }
.guia-invitacion__texto { flex: 1 1 240px; min-width: 0; }
.guia-invitacion__acciones { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.guia-btn {
  font: inherit; font-size: 13px; padding: 7px 12px; cursor: pointer;
  border: 1px solid #c7d2fe; border-radius: 8px; background: #fff; color: var(--text, #1f2a37);
}
.guia-btn:hover { background: #e0e7ff; }
.guia-btn--pri { background: var(--primary, #1b4dff); border-color: var(--primary, #1b4dff); color: #fff; font-weight: 600; }
.guia-btn--pri:hover { background: #1740d6; }
.guia-btn--enlace { border-color: transparent; background: transparent; color: var(--muted, #64748b); text-decoration: underline; padding-left: 4px; padding-right: 4px; }
.guia-btn--enlace:hover { background: transparent; color: var(--text, #1f2a37); }
.guia-btn:focus-visible { outline: 2px solid var(--primary, #1b4dff); outline-offset: 2px; }
@keyframes guia-entrada { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

/* El recorrido: por encima de los modales (1000-1300) y por debajo de los avisos
   (toast, 9999). Capa a pantalla completa que bloquea los clics de la pagina. */
.tour { position: fixed; inset: 0; z-index: 5000; }
.tour__fondo { position: absolute; inset: 0; background: rgba(15, 23, 42, .62); display: none; }
.tour--sin-foco .tour__fondo { display: block; }

/* El "foco": un hueco sobre el elemento. La sombra enorme oscurece todo lo demas. */
.tour__spot {
  position: fixed; border-radius: 10px; pointer-events: none;
  box-shadow: 0 0 0 100vmax rgba(15, 23, 42, .62), 0 0 0 3px var(--primary, #1b4dff), 0 0 0 6px rgba(255, 255, 255, .85);
  transition: top .25s ease, left .25s ease, width .25s ease, height .25s ease;
}

.tour__card {
  position: fixed; z-index: 1; box-sizing: border-box;
  width: 340px; max-width: calc(100vw - 24px);
  padding: 16px 18px 14px; outline: none;
  background: var(--card, #fff); color: var(--text, #1f2a37);
  border-radius: 14px; box-shadow: 0 20px 48px rgba(15, 23, 42, .38);
}
.tour__card--centro { top: 50%; left: 50%; transform: translate(-50%, -50%); width: min(440px, calc(100vw - 24px)); }
.tour__modulo { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--primary, #1b4dff); margin: 0 28px 4px 0; }
.tour__titulo { margin: 0 24px 6px 0; font-size: 17px; line-height: 1.25; }
.tour__texto { margin: 0 0 14px; font-size: 14px; line-height: 1.5; color: var(--text, #1f2a37); }
.tour__texto strong { font-weight: 600; }
.tour__pie { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tour__cuenta { font-size: 12px; color: var(--muted, #64748b); white-space: nowrap; }
.tour__botones { display: flex; gap: 8px; }
.tour__btn { font: inherit; font-size: 13px; padding: 8px 14px; border-radius: 8px; cursor: pointer; border: 1px solid var(--border, #e2e8f0); background: #fff; color: var(--text, #1f2a37); }
.tour__btn:hover { background: #f1f5f9; }
.tour__btn--pri { background: var(--primary, #1b4dff); border-color: var(--primary, #1b4dff); color: #fff; font-weight: 600; }
.tour__btn--pri:hover { background: #1740d6; }
.tour__btn:focus-visible, .tour__x:focus-visible { outline: 2px solid var(--primary, #1b4dff); outline-offset: 2px; }
.tour__x { position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; border: 0; border-radius: 50%; background: transparent; color: var(--muted, #64748b); cursor: pointer; font-size: 13px; }
.tour__x:hover { background: #f1f5f9; color: var(--text, #1f2a37); }

/* Solo para lectores de pantalla: anuncia el paso al cambiar. */
.tour__vivo { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

@media (max-width: 640px) {
  .tour__card { padding: 14px 14px 12px; }
  .tour__pie { flex-wrap: wrap; }
  .tour__botones { margin-left: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .tour__spot { transition: none; }
  .guia-invitacion { animation: none; }
}
@media print { .tour, .guia-invitacion, .help-btn--tour { display: none !important; } }

/* Barra de acciones de una pestana del detalle (p. ej. Planes del equipo). */
.detail-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 12px;
}
.detail-toolbar p { margin: 0; font-size: 12.5px; max-width: 62ch; }
.detail-table .text-right { text-align: right; white-space: nowrap; }
@media (max-width: 720px) {
  .detail-toolbar { align-items: stretch; }
  .detail-toolbar button:not(.help-btn) { width: 100%; }
}

/* Timeline de seguimiento con linea conectora */
.ot-timeline { list-style: none; padding: 0; margin: 0; }
.ot-timeline li { display: flex; gap: 12px; padding: 4px 0 14px; position: relative; }
.ot-timeline li:not(:last-child)::before {
  content: ''; position: absolute; left: 5px; top: 16px; bottom: 0; width: 2px; background: #e2e8f0;
}
/* Los formularios de la orden (mano de obra, repuestos) en una sola linea.
   `flex-end` alinea los controles entre si, no las etiquetas de encima, que no
   miden todas igual; asi el boton queda a la altura de los inputs. El
   `flex-wrap` de `.ot-add` sigue vigente: en el telefono los campos se apilan
   solos y no hace falta media query. Los anchos van por peso, no fijos: manda
   el campo con el texto mas largo de cada formulario. */
.ot-fila { align-items: flex-end; }
.ot-fila .ot-field { flex: 1 1 150px; min-width: 0; }
.ot-fila .ot-field--tecnico { flex: 2 1 190px; }
.ot-fila .ot-field--horas { flex: 0 1 110px; }
.ot-fila .ot-field--repuesto { flex: 3 1 240px; }
.ot-fila .ot-field--almacen { flex: 1 1 170px; }
.ot-fila .ot-field--cantidad { flex: 0 1 120px; }
/* El buscador que reemplaza al select es un div suelto: sin esto se encoge. */
.ot-fila .ot-field > .search-select { width: 100%; }
.ot-fila .ot-field input, .ot-fila .ot-field select { flex: none; width: 100%; }
/* En mano de obra la fila no es lo ultimo: debajo van los chips y la ayuda. */
#otAddManoObra { margin-bottom: 14px; }
#otAddManoObra .ot-add { margin-bottom: 8px; }
#otTecnicosMo:not(:empty) { margin-bottom: 6px; }

/* Tarjeta de tecnico editable: el valor ES el selector, asi que hereda la
   tipografia del `strong` de al lado y no parece un control metido a la fuerza.
   El chevron va en el `::after` de la tarjeta y no como imagen de fondo, para
   que la flecha nativa (que cada navegador dibuja a su manera) se pueda apagar. */
.ot-meta__editable { position: relative; cursor: pointer; }
.ot-meta__editable::after {
  content: "\F282"; font-family: bootstrap-icons; font-size: 11px;
  position: absolute; right: 12px; bottom: 12px; color: var(--muted, #64748b); pointer-events: none;
}
.ot-meta__editable:hover { background: #fff; border-color: #dbe3ee; }
.ot-meta__editable select {
  appearance: none; -webkit-appearance: none;
  width: 100%; border: 0; background: transparent; padding: 0 16px 0 0; margin: 0;
  font: inherit; font-size: 14px; font-weight: 600; color: #0f172a; cursor: pointer;
}
.ot-meta__editable select:focus { outline: none; color: var(--primary); }

/* Linea de tiempo de la orden: el autor y la fecha bajo cada paso. */
.ot-timeline__meta { display: block; font-size: 12px; color: var(--muted, #64748b); margin-top: 1px; }
.ot-timeline__detalle { margin: 4px 0 0; font-size: 13px; color: #475569; }

.ot-timeline__dot {
  width: 12px; height: 12px; border-radius: 50%; background: var(--primary); margin-top: 4px;
  flex: 0 0 auto; box-shadow: 0 0 0 3px rgba(27,77,255,.15); position: relative; z-index: 1;
}
.ot-timeline p { margin: 0; font-size: 14px; }

/* Zona de subida y galeria de adjuntos */
.ot-upload {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px;
  border: 1.5px dashed #cbd5e1; border-radius: 12px; padding: 14px; background: #f8fafc;
}
.ot-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 12px; }
.ot-thumb {
  position: relative; margin: 0; border-radius: 14px; overflow: hidden; background: #0f172a;
  box-shadow: 0 4px 12px rgba(15,23,42,.08); transition: transform .15s ease, box-shadow .15s ease;
}
.ot-thumb:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(15,23,42,.16); }
.ot-thumb a { display: block; }
.ot-thumb img { width: 100%; height: 120px; object-fit: cover; display: block; transition: transform .25s ease; }
.ot-thumb:hover img { transform: scale(1.05); }
.ot-file { height: 120px; display: flex; align-items: center; justify-content: center; font-size: 40px; color: #fff; background: linear-gradient(135deg,#ef4444,#b91c1c); }
/* Solicitudes: el icono de un adjunto que no es imagen toma el color de su
   programa (el rojo de .ot-file es el del PDF). */
.ot-file.sol-file--word { background: linear-gradient(135deg, #3b82f6, #1d4ed8); }
.ot-file.sol-file--excel { background: linear-gradient(135deg, #22c55e, #15803d); }

/* Solicitudes: bloques del detalle (piezas y adjuntos). */
.sol-bloque { margin-top: 18px; }
.sol-bloque h5 { margin: 0 0 10px; display: flex; align-items: center; gap: 6px; }
.sol-piezas { list-style: none; margin: 0 0 10px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.sol-pieza {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border: 1px solid #e9eef5; border-radius: 10px; background: #fff;
}
.sol-pieza__cant { flex: 0 0 auto; font-weight: 700; min-width: 64px; }
.sol-pieza__texto { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.sol-pieza__texto strong { overflow-wrap: anywhere; }
.sol-pieza .badge { flex: 0 0 auto; white-space: nowrap; }

.sol-pieza-form { display: flex; flex-direction: column; gap: 8px; }
.sol-pieza-fila { display: flex; flex-wrap: wrap; gap: 8px; }
.sol-pieza-fila #solPiezaCantidad { flex: 0 0 110px; }
.sol-pieza-fila #solPiezaUnidad { flex: 0 0 110px; }
.sol-pieza-fila #solPiezaNota { flex: 1 1 200px; min-width: 0; }

/* Buscador de repuestos con sus sugerencias debajo. */
.sol-buscador { position: relative; }
.sol-buscador input { width: 100%; }
.sol-sugerencias {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 20;
  list-style: none; margin: 0; padding: 4px; max-height: 260px; overflow-y: auto;
  background: #fff; border: 1px solid #e2e8f0; border-radius: 10px;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.18);
}
.sol-sugerencias li {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 10px; border-radius: 8px; cursor: pointer; font-size: 13px;
}
.sol-sugerencias li:hover { background: #f1f5f9; }
.sol-sugerencias [data-libre] { border-top: 1px solid #f1f5f9; color: var(--primary, #1b4dff); }

/* Solicitudes: formulario de alta. Tipo y prioridad en una fila; titulo,
   equipo y descripcion a lo ancho; debajo, piezas y adjuntos (los mismos
   bloques del detalle, movidos aqui mientras se crea). */
#crudFields.form-solicitudes { grid-template-columns: 1fr 1fr; gap: 14px 16px; }
#crudFields.form-solicitudes .span-2 { grid-column: 1 / -1; }
.sol-alta-extras { border-top: 1px solid #eef2f7; margin-top: 18px; }
.sol-alta-extras .sol-bloque:first-child { margin-top: 14px; }
.sol-alta-extras .ot-upload { margin-bottom: 10px; }

@media (max-width: 560px) {
  #crudFields.form-solicitudes { grid-template-columns: 1fr; }
  .sol-pieza { flex-wrap: wrap; }
  .sol-pieza-fila #solPiezaCantidad,
  .sol-pieza-fila #solPiezaUnidad { flex: 1 1 45%; }
}
.ot-thumb figcaption {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 16px 8px 6px;
  font-size: 11px; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  background: linear-gradient(to top, rgba(0,0,0,.72), transparent);
}
.ot-thumb__del {
  position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; border: 0; border-radius: 8px;
  background: rgba(220,38,38,.92); color: #fff; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .15s ease;
}
.ot-thumb:hover .ot-thumb__del { opacity: 1; }
.ot-thumb__del:hover { background: #b91c1c; }

/* ===== Formulario de usuario (layout elegante 2 columnas) ===== */
#crudFields.form-usuarios { grid-template-columns: 1fr 1fr; gap: 14px 16px; }
#crudFields.form-usuarios .span-2 { grid-column: 1 / -1; }
@media (max-width: 560px) { #crudFields.form-usuarios { grid-template-columns: 1fr; } }

/* Inputs del formulario CRUD: consistencia y foco */
.modal__form input:not([type="checkbox"]),
.modal__form select,
.modal__form textarea {
  width: 100%;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 14px;
  font-family: inherit;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.modal__form input:focus,
.modal__form select:focus,
.modal__form textarea:focus {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(27,77,255,.12);
}
.modal__form label { gap: 6px; }
.modal__form .field-label { font-weight: 500; color: #334155; }

/* ===== Campo booleano (checkbox) =====
   Se dibuja como una caja con borde, igual que los inputs de al lado, porque
   dentro de la grilla del formulario una casilla nativa suelta -con el texto
   debajo, en gris y a 13px- parece un campo sin terminar. El texto va A LA
   DERECHA y toda la caja es clicable. `align-self: end` la alinea con la fila
   del input de los campos vecinos, que gastan la parte de arriba en su
   etiqueta. */
.modal__form label.campo-check {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  align-self: end;
  gap: 10px;
  min-height: 42px;
  padding: 10px 12px;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  background: #fff;
  font-size: 14px;
  color: #334155;
  cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease;
}
.modal__form label.campo-check:hover { border-color: #cbd5e1; }
.modal__form label.campo-check:focus-within {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(27, 77, 255, .12);
}
/* Marcado = activo. Tenerlo en el borde y el fondo deja leer de un vistazo
   cuales estan puestos, que es justo lo que se mira en un formulario con
   media docena de banderas (Tipos de equipo). */
.modal__form label.campo-check:has(input[type="checkbox"]:checked) {
  border-color: var(--primary);
  background: rgba(27, 77, 255, .04);
  color: #1e293b;
}
.modal__form label.campo-check input[type="checkbox"] {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--primary);
  cursor: pointer;
}
.modal__form label.campo-check .campo-check__texto { flex: 1 1 auto; }
/* La ayuda salta de linea y se alinea con el texto, no con la casilla. */
.modal__form label.campo-check .help-text { flex: 1 1 100%; min-width: 0; margin-left: 28px; }

/* Campo de contraseña con boton ver/ocultar integrado */
.password-field { position: relative; display: flex; align-items: center; }
.password-field input { padding-right: 42px; }
.password-field .toggle-password {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 32px; height: 32px; padding: 0; border: 0; background: transparent; color: var(--muted, #64748b);
  border-radius: 8px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.password-field .toggle-password:hover { background: #f1f5f9; color: var(--text, #0f172a); }

.qr-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }

/* ============================================================================
   DataTables — tema acorde al sistema (listas server-side y tabs de detalle)
   ========================================================================== */
.dataTables_wrapper { width: 100%; color: var(--text); }

/* Barra superior: buscador propio + herramientas (exportar/imprimir) */
.dataTables_wrapper .dt-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 14px;
}
.dataTables_wrapper .dt-tools { display: flex; gap: 8px; flex-wrap: wrap; }

/* Botones de exportar / imprimir */
.dt-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px; font-size: 13px; font-weight: 600;
  color: var(--muted); background: #fff;
  border: 1px solid var(--secondary); border-radius: 10px;
  cursor: pointer; transition: all .15s ease;
}
.dt-btn:hover { color: var(--primary); border-color: var(--primary); background: #eef2ff; }
.dt-btn:active { transform: translateY(1px); }
.dt-btn:disabled { opacity: .55; cursor: default; }
.dt-btn i { font-size: 15px; }

/* Buscador */
.dataTables_wrapper .dataTables_filter { margin: 0; }
.dataTables_wrapper .dataTables_filter label { color: var(--muted); font-size: 0; }
.dataTables_wrapper .dataTables_filter input {
  margin: 0; min-width: 240px; padding: 9px 12px;
  border: 1px solid var(--secondary); border-radius: 10px;
  font-size: 14px; color: var(--text); background: #fff; outline: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.dataTables_wrapper .dataTables_filter input::placeholder { color: #9aa6b2; }
.dataTables_wrapper .dataTables_filter input:focus {
  border-color: var(--primary); box-shadow: 0 0 0 3px rgba(27, 77, 255, .12);
}

/* Selector de cantidad por pagina */
.dataTables_wrapper .dataTables_length { color: var(--muted); font-size: 13px; }
.dataTables_wrapper .dataTables_length select {
  margin: 0 6px; padding: 6px 26px 6px 10px; border: 1px solid var(--secondary);
  border-radius: 8px; background: #fff; color: var(--text); cursor: pointer;
}

/* Tabla */
table.dataTable { width: 100% !important; border-collapse: collapse; margin: 0 !important; }
table.dataTable thead th {
  position: relative; text-align: left; padding: 12px 26px 12px 14px;
  font-size: 12px; font-weight: 700; letter-spacing: .02em; text-transform: uppercase;
  color: var(--muted); background: #f8fafc;
  border-bottom: 1px solid var(--secondary);
}
table.dataTable thead th:first-child { border-top-left-radius: 10px; }
table.dataTable thead th:last-child  { border-top-right-radius: 10px; }
table.dataTable tbody td {
  padding: 12px 14px; font-size: 14px; color: var(--text);
  border-bottom: 1px solid #eef2f7; vertical-align: middle;
}
table.dataTable tbody tr { background: #fff; transition: background .12s ease; }
table.dataTable tbody tr:hover { background: #f7f9ff; cursor: default; }
/* Tablas cuyo clic en la fila abre un detalle: que se note que son clicables. */
table.dataTable.has-row-click tbody tr { cursor: pointer; }
table.dataTable.has-row-click tbody tr:hover { background: #eef2ff; cursor: pointer; }
table.dataTable tbody tr.is-selected,
table.dataTable tbody tr.selected { background: #eef2ff; }
table.dataTable tbody tr.is-selected td { box-shadow: inset 3px 0 0 var(--primary); }

/* Indicadores de orden: ocultamos el doble icono de la libreria (::before) y
   usamos ::after como unica flecha, al estilo del sistema. */
table.dataTable thead th.sorting,
table.dataTable thead th.sorting_asc,
table.dataTable thead th.sorting_desc { cursor: pointer; }
table.dataTable thead th.sorting::before,
table.dataTable thead th.sorting_asc::before,
table.dataTable thead th.sorting_desc::before { content: '' !important; display: none !important; }
table.dataTable thead th.sorting::after,
table.dataTable thead th.sorting_asc::after,
table.dataTable thead th.sorting_desc::after {
  position: absolute; right: 10px; top: 50%; left: auto; bottom: auto;
  transform: translateY(-50%); font-size: 11px; line-height: 1; opacity: 1 !important;
}
table.dataTable thead th.sorting::after     { content: '\2195' !important; color: var(--muted); opacity: .4 !important; }
table.dataTable thead th.sorting_asc::after { content: '\2191' !important; color: var(--primary); }
table.dataTable thead th.sorting_desc::after{ content: '\2193' !important; color: var(--primary); }
table.dataTable thead th:hover.sorting::after { opacity: .7 !important; }

/* Celda de acciones dentro de DataTables */
table.dataTable td.actions { white-space: nowrap; text-align: right; width: 1%; }

/* Pie: info + paginacion */
.dataTables_wrapper .dataTables_info {
  color: var(--muted); font-size: 13px; padding-top: 16px;
}
.dataTables_wrapper .dataTables_paginate { float: right; padding-top: 12px; }
.dataTables_wrapper .dataTables_paginate .paginate_button {
  box-sizing: border-box; min-width: 34px; height: 34px; padding: 0 10px !important;
  margin: 0 2px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--secondary) !important; border-radius: 9px !important;
  color: var(--text) !important; background: #fff !important; cursor: pointer;
  font-size: 13px; transition: all .15s ease;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
  border-color: var(--primary) !important; color: var(--primary) !important;
  background: #eef2ff !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
  background: var(--primary) !important; border-color: var(--primary) !important;
  color: #fff !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,
.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover {
  opacity: .45; color: var(--muted) !important; background: #fff !important;
  border-color: var(--secondary) !important; cursor: default;
}

/* Overlay de carga */
.dataTables_wrapper .dataTables_processing {
  background: rgba(255, 255, 255, .82); color: var(--muted); font-weight: 600;
  border: 0; box-shadow: none; border-radius: 12px;
}

/* En las tablas del detalle (tabs) el wrapper va dentro de .detail-table */
.detail-table .dataTables_wrapper .dt-head { margin-bottom: 10px; }

/* Responsivo */
@media (max-width: 720px) {
  .dataTables_wrapper .dataTables_filter input { min-width: 0; width: 100%; }
  .dataTables_wrapper .dt-head { flex-direction: column; align-items: stretch; }
  .dataTables_wrapper .dataTables_paginate { float: none; text-align: center; margin-top: 12px; }
}

/* ============================================================================
   Vista de factura (diseño de factura, en el modal de detalle e impresión)
   ========================================================================== */
.modal__header-actions { display: flex; gap: 8px; align-items: center; }

.invoice {
  background: #fff; color: var(--text); padding: 8px 4px;
  font-size: 14px; max-width: 820px; margin: 0 auto;
}
.invoice__head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 24px; border-bottom: 2px solid var(--primary); padding-bottom: 16px;
}
.invoice__brand { display: flex; gap: 12px; align-items: center; }
.invoice__logo {
  width: 48px; height: 48px; border-radius: 12px; background: var(--primary);
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 17px; flex: 0 0 auto;
}
.invoice__brand h2 { margin: 0; font-size: 19px; }
.invoice__brand p { margin: 2px 0 0; color: var(--muted); font-size: 12px; }
.invoice__title { text-align: right; }
.invoice__title h1 { margin: 0; font-size: 28px; letter-spacing: 2px; color: var(--primary); }
.invoice__num { margin: 4px 0 8px; color: var(--muted); font-size: 13px; }

.invoice__parties {
  display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin: 22px 0;
}
.invoice__party h4, .invoice__notes h4 {
  margin: 0 0 6px; font-size: 12px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted);
}
.invoice__party p { margin: 2px 0; font-size: 13px; }
.invoice__party .strong { font-weight: 700; font-size: 15px; }
.invoice__meta { display: grid; grid-template-columns: auto auto; gap: 8px 20px; align-content: start; }
.invoice__meta div { display: flex; flex-direction: column; }
.invoice__meta span { font-size: 11px; color: var(--muted); }
.invoice__meta b { font-size: 13px; }

table.invoice__items { width: 100%; border-collapse: collapse; margin-top: 6px; font-size: 13px; }
.invoice__items th {
  background: #f1f5f9; text-align: left; padding: 10px; font-size: 11px;
  text-transform: uppercase; letter-spacing: .03em; color: #475569;
}
.invoice__items td { padding: 10px; border-bottom: 1px solid #eef2f7; }
.invoice__items .num, .invoice__items th.num { text-align: right; }

.invoice__footer { display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin-top: 20px; }
.invoice__notes p { font-size: 12px; color: #475569; margin: 0; max-width: 340px; }
.invoice__totals { min-width: 250px; margin-left: auto; }
.invoice__totals div { display: flex; justify-content: space-between; padding: 6px 0; font-size: 14px; }
.invoice__totals span { color: var(--muted); }
.invoice__grand {
  border-top: 2px solid var(--primary); margin-top: 6px; padding-top: 10px !important;
  font-size: 18px !important; font-weight: 800; color: var(--primary);
}
.invoice__grand span { color: var(--primary) !important; }

/* ===== Acceso por huella (WebAuthn) ===== */
/* El atributo `hidden` debe ganarle a los `display:flex/inline-flex` de los
   componentes (p. ej. .dropdown__item), que si no lo dejan visible igual. */
[hidden] { display: none !important; }
.huella-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 6px; }
.huella-item {
  display: flex; align-items: center; gap: 12px;
  border: 1px solid var(--border, #e2e8f0); border-radius: 12px; padding: 10px 12px;
}
.huella-item__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 10px; flex: 0 0 auto;
  background: #1b4dff12; color: var(--primary); font-size: 18px;
}
.huella-item__info { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.huella-item__info strong { font-size: 14px; }
.huella-item__info .muted { font-size: 11.5px; }

/* ===== Nueva orden de compra (#compra) =====
   El alta de OC se saco de la modal a una pagina: las lineas de servicio piden
   equipo + servicio + detalle y no cabian. Aqui cada linea usa el ancho
   completo y los campos respiran. */
#compraNueva .oc-full { grid-column: 1 / -1; }

#compraNueva .req { color: var(--danger, #dc2626); font-weight: 700; }

#compraNueva .form-grid label,
#compraNueva .oc-mini {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: #334155;
}

#compraNueva .form-grid label > select,
#compraNueva .form-grid label > input,
#compraNueva .oc-mini > select,
#compraNueva .oc-mini > input,
#compraNueva .oc-mini > .search-select { margin-top: 6px; }

#compraNueva .oc-mini { font-size: 12px; font-weight: 500; color: var(--muted); }

#compraNueva select,
#compraNueva input[type="text"],
#compraNueva input[type="date"],
#compraNueva input[type="number"] { width: 100%; }

#compraNueva .oc-add-btns { display: flex; gap: 8px; flex-wrap: wrap; }

/* La tabla de lineas: se alinea arriba porque la celda de servicio es alta. */
#compraNueva .oc-lineas { overflow: visible; }
#compraNueva .oc-lineas table { table-layout: fixed; }
#compraNueva .oc-lineas td > label,
#compraNueva .oc-lineas .oc-linea-servicio { min-width: 0; }
#compraNueva .oc-lineas td { vertical-align: top; padding: 14px 12px; }
#compraNueva .oc-lineas th { padding: 10px 12px; }

#compraNueva .oc-col-tipo { width: 150px; }
#compraNueva .oc-col-cant { width: 120px; }
#compraNueva .oc-col-costo { width: 150px; }
#compraNueva .oc-col-sub { width: 140px; text-align: right; font-weight: 600; }
#compraNueva .oc-col-del { width: 56px; text-align: center; }

/* Los tres campos del servicio: equipo y servicio en dos columnas, el detalle
   ocupando toda la fila. */
#compraNueva .oc-linea-servicio {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}
#compraNueva .oc-linea-servicio .oc-full { grid-column: 1 / -1; }

/* Barra de total y acciones, pegada abajo al hacer scroll. */
#compraNueva .oc-footer {
  margin-top: 16px;
  position: sticky;
  bottom: 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
#compraNueva .oc-resumen { display: flex; align-items: baseline; gap: 16px; }
#compraNueva .oc-total { font-size: 20px; }
#compraNueva .oc-footer__actions { display: flex; gap: 8px; }

@media (max-width: 900px) {
  /* En movil la tabla no cabe: cada linea se vuelve una tarjeta. */
  #compraNueva .oc-lineas table,
  #compraNueva .oc-lineas tbody,
  #compraNueva .oc-lineas tr,
  #compraNueva .oc-lineas td { display: block; width: auto; }
  #compraNueva .oc-lineas thead { display: none; }
  #compraNueva .oc-lineas tr {
    border: 1px solid #e2e8f0;
    border-radius: 12px;
    padding: 8px;
    margin-bottom: 12px;
  }
  #compraNueva .oc-lineas td { border: 0; padding: 8px; }
  #compraNueva .oc-col-sub { text-align: left; }
  #compraNueva .oc-col-sub::before { content: 'Subtotal: '; color: var(--muted); font-weight: 400; }
  #compraNueva .oc-col-del { text-align: right; }
  #compraNueva .oc-footer { position: static; }
}


/* =====================================================================
   Editor de plantillas de checklist (#checklist/<id>)
   Cada seccion es una tarjeta con sus items; el ancho completo de la
   pagina es lo que permite editar textos largos comodamente.
   ===================================================================== */
#checklistEditor .cl-header-actions { display: flex; gap: 8px; }
#checklistEditor .cl-check {
  display: flex;
  align-items: center;
  gap: 8px;
  grid-column: 1 / -1;
}
#checklistEditor .cl-check input { width: auto; }
#checklistEditor .cl-alcance { margin: 10px 0 0; font-size: 13px; }
#checklistEditor .cl-vacio { padding: 18px 0; text-align: center; }

#checklistEditor .cl-seccion {
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  padding: 12px;
  margin-bottom: 14px;
  background: #fbfdff;
}
#checklistEditor .cl-seccion__head {
  display: flex;
  align-items: center;
  gap: 10px;
}
#checklistEditor .cl-seccion__n {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--primary, #2563eb);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  display: grid;
  place-items: center;
}
#checklistEditor .cl-seccion-titulo {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 600;
}
#checklistEditor .cl-items {
  margin: 10px 0 0 36px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
#checklistEditor .cl-item {
  display: flex;
  align-items: center;
  gap: 8px;
}
#checklistEditor .cl-item__icon { color: var(--muted, #64748b); flex: 0 0 auto; }
#checklistEditor .cl-item-label { flex: 1 1 auto; min-width: 0; }
#checklistEditor .cl-item__id {
  /* Ancho fijo: si el chip creciera con el texto, cada fila cortaria el input
     del item a un largo distinto y la columna quedaria dentada. */
  flex: 0 0 150px;
  text-align: center;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--muted, #64748b);
  background: #eef2f7;
  border-radius: 6px;
  padding: 2px 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#checklistEditor .cl-item__id--nuevo { background: #ecfdf5; color: #047857; }
#checklistEditor .cl-btns { display: flex; gap: 2px; flex: 0 0 auto; }
#checklistEditor .cl-btns button { padding: 4px 6px; }
#checklistEditor .cl-btns button[disabled] { opacity: .35; cursor: default; }
#checklistEditor .cl-add-item { margin: 8px 0 0 36px; }

#checklistEditor .cl-aviso {
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 13px;
  color: #92400e;
  margin-bottom: 12px;
}
#checklistEditor .cl-aviso code { word-break: break-all; }

#checklistEditor .cl-footer {
  margin-top: 16px;
  position: sticky;
  bottom: 12px;
}
#checklistEditor .cl-footer__actions { display: flex; justify-content: flex-end; gap: 8px; }

#checklistEditor .cl-preview__seccion { margin-bottom: 16px; }
#checklistEditor .cl-preview__seccion h5 { margin: 0 0 8px; }
/* .modal__form apila label y control en columna; en la vista previa el item debe
   verse como lo vera el tecnico: casilla y texto en la misma linea. */
#checklistEditor #clPreviewBody .checklist label {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--text, #0f172a);
}
#checklistEditor #clPreviewBody .checklist input[type="checkbox"] { width: auto; flex: 0 0 auto; }

@media (max-width: 720px) {
  /* En movil los botones no caben en la misma fila que el texto del item. */
  #checklistEditor .cl-items,
  #checklistEditor .cl-add-item { margin-left: 0; }
  #checklistEditor .cl-item { flex-wrap: wrap; }
  #checklistEditor .cl-item-label { flex: 1 1 100%; order: -1; }
  #checklistEditor .cl-item__id { flex: 0 0 auto; max-width: 60%; }
  #checklistEditor .cl-footer { position: static; }
}


/* =====================================================================
   Campo de texto por item del checklist ("nota").
   La plantilla decide con `nota: true` que items lo llevan; el tecnico lo
   rellena al escanear el QR y queda visible en el detalle de la inspeccion.
   ===================================================================== */

/* --- Formulario del QR (#registrar/<id_equipo>) --- */
/* Campo de tecnicos participantes. Es un <div> y no un <label> a proposito:
   dentro de un label, el clic en la "x" de un chip se reenvia al <select> y lo
   abre. La tipografia se deja heredar para que se lea igual que Fecha/Operador. */
.reg-tecnicos { display: flex; flex-direction: column; gap: 6px; align-items: stretch; }
.reg-tecnicos > select { width: 100%; }
.reg-tecnicos > .ot-chips { margin-top: 2px; }
.reg-item { display: flex; flex-direction: column; gap: 6px; }
.reg-nota {
  /* Sangrado a la altura del texto del item, para que se lea como su detalle. */
  margin-left: 26px;
  padding: 8px 10px;
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 8px;
  font-size: 14px;
  font-family: inherit;
  background: #fffdf7;
}
.reg-nota:focus {
  outline: none;
  border-color: var(--primary, #2563eb);
  background: #fff;
}

/* --- El detalle de la inspeccion estiliza su nota en inspecciones.view.html,
   junto a las reglas de .insp-items de las que depende. --- */

/* --- Editor de plantillas: interruptor por item --- */
#checklistEditor .cl-nota-btn { color: var(--muted, #64748b); }
#checklistEditor .cl-nota-btn.is-on { color: var(--primary, #2563eb); }
#checklistEditor .cl-item--nota { position: relative; }
#checklistEditor .cl-item__nota-hint {
  flex: 1 1 100%;
  margin: 0 0 2px 26px;
  font-size: 12px;
  color: var(--primary, #2563eb);
}
#checklistEditor .cl-item__nota-hint .bi { opacity: .7; }
#checklistEditor .cl-item { flex-wrap: wrap; }
#checklistEditor .cl-preview__nota {
  /* `.modal__form input` fuerza width:100%; sumado al margen izquierdo eso
     desbordaba la modal, asi que se descuenta el margen del ancho. */
  display: block;
  box-sizing: border-box;
  width: calc(100% - 26px);
  margin: 2px 0 8px 26px;
  padding: 6px 10px;
  border: 1px dashed var(--border, #cbd5e1);
  border-radius: 8px;
  font-size: 13px;
  background: #fffdf7;
}

@media (max-width: 720px) {
  .reg-nota, #checklistEditor .cl-item__nota-hint,
  #checklistEditor .cl-preview__nota { margin-left: 0; }
}


/* --- Equipos vinculados a una plantilla de checklist --- */
#checklistEditor .cl-opcional { font-weight: 400; font-size: 12px; }
#checklistEditor .cl-eq-ayuda { margin: 0 0 12px; font-size: 13px; }
#checklistEditor .cl-eq-ayuda--activa { color: var(--primary, #2563eb); }
#checklistEditor .cl-eq-lista { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
#checklistEditor .cl-eq-vacio { margin: 0; font-size: 13px; }
#checklistEditor .cl-eq-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 6px 5px 10px;
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 999px;
  background: #f8fafc;
  font-size: 13px;
}
#checklistEditor .cl-eq-chip .bi-cpu { color: var(--muted, #64748b); }
#checklistEditor .cl-eq-chip__cat {
  font-size: 11px;
  color: var(--muted, #64748b);
  background: #eef2f7;
  border-radius: 999px;
  padding: 1px 7px;
}
#checklistEditor .cl-eq-chip__del {
  display: grid;
  place-items: center;
  width: 20px; height: 20px; padding: 0;
  border: none; border-radius: 50%;
  background: transparent; color: var(--muted, #64748b);
  cursor: pointer; font-size: 10px;
}
#checklistEditor .cl-eq-chip__del:hover { background: var(--danger, #ef4444); color: #fff; }


/* --- Volcado masivo de equipos por categoria --- */
#checklistEditor .cl-eq-controles {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-start;
}
#checklistEditor .cl-eq-picker { flex: 1 1 320px; max-width: 460px; }
#checklistEditor .cl-eq-bulk { display: flex; gap: 8px; flex: 1 1 320px; max-width: 460px; }
#checklistEditor .cl-eq-bulk select { flex: 1 1 auto; min-width: 0; }
#checklistEditor .cl-eq-bulk button { flex: 0 0 auto; white-space: nowrap; }
#checklistEditor .cl-eq-nota-bulk {
  margin: 10px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  border-left: 3px solid var(--border, #e2e8f0);
  padding-left: 10px;
}
#checklistEditor .cl-eq-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--border, #e2e8f0);
  font-size: 13px;
}
#checklistEditor .cl-eq-cabecera + .cl-eq-lista { margin-top: 8px; }

@media (max-width: 720px) {
  #checklistEditor .cl-eq-picker,
  #checklistEditor .cl-eq-bulk { max-width: none; }
}
/* ===== Carga por tecnico (panel de reparto en Ordenes) ===== */
.carga-panel { padding: 14px 16px; }

.carga-panel__head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.carga-panel__head h5 { margin: 0; font-size: 14px; }
.carga-panel__head h5 i { color: var(--primary); margin-right: 4px; }
.carga-panel__resumen { color: var(--muted); font-size: 12px; }
.carga-panel__head .btn-small { margin-left: auto; }

.carga-panel__list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 10px;
}

/* Cada fila es un boton: filtra las ordenes por ese tecnico. */
.carga-row {
  display: grid;
  grid-template-columns: minmax(120px, 1.2fr) minmax(80px, 2fr) minmax(0, 1.4fr) auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 6px 8px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  text-align: left;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
}
.carga-row:hover { background: #f8fafc; }

.carga-row__nombre {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.carga-row__nombre .badge { font-weight: 500; }

.carga-row__bar {
  display: block;
  height: 8px;
  border-radius: 999px;
  background: #e2e8f0;
  overflow: hidden;
}
.carga-row__fill { display: block; height: 100%; border-radius: 999px; }
.carga-row__fill.is-success { background: #16a34a; }
.carga-row__fill.is-warning { background: #f59e0b; }
.carga-row__fill.is-danger  { background: #ef4444; }

.carga-row__detalle {
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La fila "Sin asignar" no lleva barra: sin esto su contador se estiraria
   ocupando la columna de la barra. */
.carga-row--libre {
  grid-template-columns: minmax(120px, 1.2fr) 1fr auto;
}
.carga-row--libre .carga-row__nombre { font-weight: 500; color: var(--muted); }

@media (max-width: 720px) {
  .carga-row { grid-template-columns: 1fr auto; grid-template-areas: "nombre num" "bar bar" "detalle detalle"; }
  .carga-row__nombre  { grid-area: nombre; }
  .carga-row__bar     { grid-area: bar; }
  .carga-row__detalle { grid-area: detalle; }
  .carga-row .badge   { grid-area: num; }
}

/* =====================================================================
   Grupos plegables del menu lateral
   Los estrena el area de Informatica: son ocho modulos y el menu ya era
   largo. El titulo del grupo es un boton; los enlaces viven dentro y solo
   se ven cuando el grupo tiene la clase .open.
   ===================================================================== */
.sidebar__group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.sidebar__group-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 14px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-align: left;
  transition: background 0.2s ease;
}

.sidebar__group-toggle:hover {
  background: rgba(255, 255, 255, 0.1);
}

.sidebar__group-toggle i:first-child { font-size: 18px; }

.sidebar__group-caret {
  margin-left: auto;
  font-size: 12px;
  transition: transform 0.2s ease;
}

.sidebar__group.open .sidebar__group-caret { transform: rotate(180deg); }

.sidebar__group-items {
  display: none;
  flex-direction: column;
  gap: 4px;
  /* Sangria + linea a la izquierda: se ve de un vistazo que cuelgan del grupo. */
  margin-left: 14px;
  padding-left: 10px;
  border-left: 1px solid rgba(255, 255, 255, 0.15);
}

.sidebar__group.open .sidebar__group-items { display: flex; }

.sidebar__group-items a {
  padding: 9px 12px;
  font-size: 14px;
}

/* Con el menu colapsado no hay sitio para el grupo: se ocultan el titulo y la
   sangria, y los iconos de los modulos quedan como los demas. */
.sidebar.collapsed .sidebar__group-toggle span,
.sidebar.collapsed .sidebar__group-caret { display: none; }

.sidebar.collapsed .sidebar__group-items {
  display: flex;
  margin-left: 0;
  padding-left: 0;
  border-left: 0;
}

/* =====================================================================
   Area de Informatica (TI)
   ===================================================================== */

/* Casilla en linea dentro de una barra de filtros o de una cabecera. */
.field--check {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

.field--check input { width: auto; }

/* --- Comparacion del escaneo --------------------------------------- */
/* Las filas que difieren se destacan: son las que vienen premarcadas y las
   unicas que cambian algo si se aceptan. */
.ti-scan-tabla { max-height: 340px; overflow-y: auto; }
.ti-scan-difiere td { background: rgba(245, 158, 11, 0.08); }

.ti-scan-lista {
  max-height: 220px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
}

.ti-scan-programa {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}

.ti-scan-programa small { color: var(--muted); }

/* --- Programas instalados de un equipo ------------------------------ */
.ti-programas-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 10px;
  margin-top: 10px;
}

.ti-programa {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 6px 10px;
  padding: 10px 12px;
  border: 1px solid var(--secondary);
  border-radius: 12px;
}

.ti-programa input[type="text"] {
  grid-column: 1 / -1;
  padding: 6px 8px;
  border: 1px solid var(--secondary);
  border-radius: 8px;
  font-size: 13px;
}

/* --- Progreso de los escaneos por lotes ----------------------------- */
.ti-progreso { margin-top: 12px; }

.ti-progreso__barra {
  height: 8px;
  border-radius: 999px;
  background: var(--secondary);
  overflow: hidden;
}

.ti-progreso__barra span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--primary);
  transition: width 0.2s ease;
}

/* --- Escaner de puertos --------------------------------------------- */
.ti-puertos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 8px;
  margin-top: 10px;
}

.ti-puerto {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--secondary);
  border-radius: 10px;
  font-size: 13px;
}

.ti-puerto span:first-of-type { flex: 1; color: var(--muted); }
.ti-puerto--abierto { border-color: var(--success); }

/* Lo que responde en la red pero NO esta en el inventario es justo lo que se
   busca al barrer un rango: se marca para que no pase inadvertido. */
.ti-red-nuevo td { background: rgba(245, 158, 11, 0.1); }

/* --- Documentacion --------------------------------------------------- */
/* El contenido se pinta como texto plano (textContent), asi que los saltos de
   linea los tiene que respetar el estilo. */
.ti-doc-contenido {
  white-space: pre-wrap;
  font-size: 14px;
  line-height: 1.7;
  margin: 12px 0;
}

/* Ultimos cambios de custodia, bajo los indicadores del inventario. */
.ti-movimiento {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  padding: 7px 0;
  border-bottom: 1px solid var(--secondary);
  font-size: 13px;
}

.ti-movimiento:last-child { border-bottom: 0; }
.ti-movimiento > span:first-child { color: var(--muted); min-width: 150px; }

/* Panel de Informatica: lo que falta por completar del inventario. */
.ti-pendientes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 12px;
  margin-top: 10px;
}

.ti-pendiente {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--secondary);
  border-radius: 12px;
}

.ti-pendiente > div { display: flex; flex-direction: column; }
.ti-pendiente strong { font-size: 14px; }
.ti-pendiente small { font-size: 12px; }

/* Una fila de movimiento que lleva a la ficha del equipo. */
.ti-movimiento.clickable { cursor: pointer; }
.ti-movimiento.clickable:hover { background: rgba(27, 77, 255, 0.05); }

/* Los graficos del panel no deben estirarse a lo alto sin limite. */
#ti-dashboard .chart-grid canvas { max-height: 260px; }

/* Barra de reparto del panel de Informatica (equipos por departamento).
   Componente propio y no el `carga-row` de Tecnicos: alli la barra es un
   semaforo de sobrecarga y aqui solo reparte un total. */
.ti-barra {
  display: grid;
  grid-template-columns: minmax(120px, 1.2fr) 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 7px 0;
}

.ti-barra__nombre {
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ti-barra__pista {
  display: block;
  height: 8px;
  border-radius: 999px;
  background: var(--secondary);
  overflow: hidden;
}

.ti-barra__relleno {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--primary);
}

@media (max-width: 720px) {
  .ti-barra { grid-template-columns: 1fr auto; }
  .ti-barra__pista { grid-column: 1 / -1; }
}

/* =====================================================================
   Avisos de la campana
   Los items dejaron de ser enlaces a un modulo para pasar a ser avisos
   reales: llevan titulo, detalle y hora, y se marcan leidos al tocarlos.
   ===================================================================== */
.notif-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.notif-item:hover {
  background: rgba(27, 77, 255, 0.06);
}

/* Lo no leido se distingue de un vistazo: es lo unico que pide accion. */
.notif-item--nuevo {
  background: rgba(27, 77, 255, 0.05);
}

.notif-item--nuevo strong::after {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-left: 6px;
  border-radius: 50%;
  background: var(--primary);
  vertical-align: middle;
}

.notif-item__texto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.notif-item__texto strong { font-size: 13px; }
.notif-item__texto small { font-size: 12px; line-height: 1.35; }

.notif-todos {
  display: block;
  width: 100%;
  padding: 8px 12px;
  border: 0;
  background: transparent;
  color: var(--primary);
  font: inherit;
  font-size: 12px;
  text-align: right;
  cursor: pointer;
}

.notif-todos:hover { text-decoration: underline; }

.avisos-estado {
  margin-bottom: 14px;
  font-size: 13px;
}

.avisos-estado p { margin: 0; }
/* ===== Importar equipos de TI desde Excel ===== */
.importar__pasos {
  margin: 0 0 14px;
  padding-left: 20px;
  font-size: 13px;
  line-height: 1.6;
}

.importar__resultado {
  margin-top: 12px;
  font-size: 13px;
}

.importar__resultado p { margin: 6px 0; }

.importar__resumen {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 8px;
}

.importar__dato {
  padding: 6px 12px;
  border-radius: 10px;
  background: var(--secondary);
}

.importar__dato--ok { background: rgba(22, 163, 74, 0.12); color: var(--success); }
.importar__dato--error { background: rgba(239, 68, 68, 0.12); color: var(--danger); }

.importar__error { color: var(--danger); }

.importar__tabla {
  max-height: 260px;
  overflow: auto;
  border: 1px solid var(--secondary);
  border-radius: 10px;
}

.importar__tabla table { width: 100%; border-collapse: collapse; font-size: 12px; }
.importar__tabla th,
.importar__tabla td { padding: 6px 8px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--secondary); }
.importar__tabla th { position: sticky; top: 0; background: var(--card); }
.importar__tabla td:first-child { white-space: nowrap; }

/* ---- Ordenes: selector de vista (Kanban | Tabla | Gantt) ------------------ */
/* flex-shrink: 0 porque lleva overflow: hidden (para las esquinas): si .actions
   lo encoge, el ultimo boton queda recortado en vez de bajar de linea. */
.vista-selector { display: inline-flex; flex-shrink: 0; border-radius: 10px; overflow: hidden; border: 1px solid var(--secondary); }
.vista-selector button { border-radius: 0; border: 0; box-shadow: none; white-space: nowrap; }
.vista-selector button + button { border-left: 1px solid var(--secondary); }
.vista-selector button.active { background: var(--primary); color: #fff; }

/* ---- Ordenes: diagrama de Gantt (ordenes.gantt.js) -------------------------
   Una fila por OT: etiqueta fija a la izquierda y una "pista" con la barra
   posicionada en % del periodo. La pista mide como minimo dias x ancho-dia:
   en pantallas estrechas el diagrama se desplaza en horizontal y la etiqueta
   se queda pegada (sticky). Las lineas de cada dia son un fondo repetido, no
   un elemento por dia y fila. */
.gantt { margin-top: 20px; padding: 16px; }
.gantt__herramientas { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; }
.gantt__nav, .gantt__opciones { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.gantt__nav button { padding: 6px 10px; }
.gantt__rango { margin-left: 6px; }
.gantt__nota { margin: 8px 0 0; color: var(--warning); font-size: 13px; }
.gantt__nota:empty { display: none; }
.gantt__scroll { overflow-x: auto; margin-top: 12px; border: 1px solid var(--secondary); border-radius: 12px; }
.gantt__tabla { --etiqueta: 190px; min-width: calc(var(--etiqueta) + var(--dias) * var(--ancho-dia)); }
.gantt__fila { display: grid; grid-template-columns: var(--etiqueta) 1fr; border-bottom: 1px solid #eef2f7; min-height: 38px; }
.gantt__fila:last-child { border-bottom: 0; }
.gantt__etiqueta {
  /* Por encima de las barras (z-index 2): al desplazar en horizontal, las
     barras pasan POR DEBAJO de la columna fija, no sobre ella. */
  position: sticky; left: 0; z-index: 4;
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  padding: 4px 10px; background: var(--card); border-right: 1px solid var(--secondary);
  min-width: 0;
}
/* Una sola linea: un codigo largo (OT-20260614082555-986) partido en tres
   hacia cada fila el triple de alta en el telefono. El codigo entero sigue en
   la barra y en el title. */
.gantt__etiqueta a { font-weight: 600; font-size: 13px; color: var(--primary); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gantt__etiqueta small { color: var(--muted); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gantt__pista {
  position: relative;
  background-image: linear-gradient(to right, #eef2f7 1px, transparent 1px);
  background-size: calc(100% / var(--dias)) 100%;
}
.gantt__fila--cabecera { position: sticky; top: 0; z-index: 5; background: var(--card); min-height: 44px; }
.gantt__fila--cabecera .gantt__etiqueta { font-size: 12px; font-weight: 600; color: var(--muted); }
.gantt__dias { display: grid; grid-template-columns: repeat(var(--dias), 1fr); background-image: none; }
.gantt__dia {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-size: 11px; color: var(--muted); border-left: 1px solid #eef2f7; line-height: 1.2;
}
.gantt__dia span { text-transform: capitalize; }
.gantt__dia strong { font-size: 13px; color: var(--text); }
.gantt__dia--finde { background: #f8fafc; }
.gantt__dia--hoy { background: rgba(27, 77, 255, 0.08); }
.gantt__dia--hoy strong { color: var(--primary); }
.gantt__grupo { background: #f8fafc; border-bottom: 1px solid #eef2f7; font-size: 12px; font-weight: 700; color: var(--text); }
.gantt__grupo-texto {
  position: sticky; left: 0; z-index: 4;
  display: inline-flex; align-items: center; gap: 8px; padding: 6px 10px;
}
.gantt__grupo-texto small { background: var(--secondary); border-radius: 999px; padding: 0 7px; font-weight: 600; color: var(--muted); }
.gantt__hoy { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--danger); opacity: 0.7; z-index: 1; pointer-events: none; }
.gantt__barra {
  position: absolute; top: 7px; height: 24px; min-width: 8px;
  display: flex; align-items: center; overflow: hidden;
  padding: 0 6px; border-radius: 6px; cursor: pointer;
  background: var(--estado-bg, #e2e8f0); color: var(--estado-fg, #334155);
  border: 1px solid var(--estado-bd, #94a3b8);
  font-size: 11px; font-weight: 600; text-align: left; z-index: 2;
}
.gantt__barra:hover, .gantt__barra:focus-visible { filter: brightness(0.96); box-shadow: 0 2px 8px rgba(15, 23, 42, 0.18); outline: none; }
.gantt__texto { position: relative; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Prioridad: franja izquierda con el color configurable de cada nivel. */
.gantt__barra--prio-critica { border-left: 4px solid var(--prio-critica-bg, #ef4444); }
.gantt__barra--prio-alta    { border-left: 4px solid var(--prio-alta-bg, #f59e0b); }
.gantt__barra--prio-media   { border-left: 4px solid var(--prio-media-bg, #0ea5e9); }
.gantt__barra--prio-baja    { border-left: 4px solid var(--prio-baja-bg, #16a34a); }
/* Pendiente cuyo fin previsto ya paso. */
.gantt__barra--vencida { outline: 2px solid var(--danger); outline-offset: -2px; }
/* La barra sigue antes o despues del periodo visible. */
.gantt__barra--corte-izq { border-top-left-radius: 0; border-bottom-left-radius: 0; border-left-style: dashed; }
.gantt__barra--corte-der { border-top-right-radius: 0; border-bottom-right-radius: 0; border-right-style: dashed; }
/* Lo que una OT en curso lleva por encima de su duracion estimada. */
.gantt__exceso {
  position: absolute; top: 0; bottom: 0; right: 0;
  background: repeating-linear-gradient(135deg, rgba(239, 68, 68, 0.28) 0 5px, transparent 5px 10px);
  pointer-events: none;
}
.gantt__msg { padding: 24px; text-align: center; color: var(--muted); margin: 0; }
.gantt__msg--error { color: var(--danger); }
.gantt__leyenda { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 12px; font-size: 12px; color: var(--muted); }
.gantt__leyenda span { display: inline-flex; align-items: center; gap: 6px; }
.gantt__muestra {
  display: inline-block; width: 18px; height: 10px; border-radius: 3px;
  background: var(--estado-bg, #fff); border: 1px solid var(--estado-bd, var(--muted));
}
.gantt__muestra--vencida { outline: 2px solid var(--danger); outline-offset: -2px; }
.gantt__muestra--exceso { background: repeating-linear-gradient(135deg, rgba(239, 68, 68, 0.4) 0 3px, transparent 3px 6px); }
.gantt__muestra--hoy { width: 2px; height: 14px; border: 0; background: var(--danger); }

@media (max-width: 640px) {
  .gantt { padding: 12px; }
  .gantt__tabla { --etiqueta: 120px; }
  /* En el telefono el selector va en su propia fila, a todo el ancho, y
     "Nueva OT" debajo: en una sola fila no caben los tres botones. */
  #ordenes .section__header .actions { flex-wrap: wrap; width: 100%; }
  #ordenes .vista-selector { flex: 1 1 100%; }
  .vista-selector button { flex: 1; justify-content: center; padding: 8px 10px; font-size: 13px; }
}
/* ===== Formulario por secciones (form.js: entradas `type: 'section'`) =====
   Cada seccion es una tarjeta con su titulo y su propia cuadricula: el numero
   de columnas lo pone el esquema (`cols`) en la variable --form-cols. Lo usa
   el equipo informatico, que con veintitantos campos en una sola rejilla era
   una pared de inputs sin orden. */
#crudModal .modal__content:has(.form--secciones) { max-width: 920px; }
#crudFields.form--secciones { display: flex; flex-direction: column; gap: 14px; }
.form-seccion {
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  background: #fbfcfe;
  padding: 14px 16px 16px;
}
.form-seccion__titulo {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eef2f7;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--primary);
}
.form-seccion__icono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  background: rgba(27, 77, 255, .08);
  font-size: 14px;
}
.form-seccion__campos {
  display: grid;
  grid-template-columns: repeat(var(--form-cols, 4), minmax(0, 1fr));
  gap: 12px 14px;
}
.form-seccion__campos > label { min-width: 0; }
.form-seccion__campos input,
.form-seccion__campos select,
.form-seccion__campos textarea { width: 100%; min-width: 0; }

@media (max-width: 860px) {
  .form-seccion__campos { grid-template-columns: repeat(min(var(--form-cols, 4), 2), minmax(0, 1fr)); }
}
@media (max-width: 520px) {
  .form-seccion { padding: 12px; }
  .form-seccion__campos { grid-template-columns: minmax(0, 1fr); }
}
/* ===== Ficha del equipo informatico (#ti-equipo/<id>) =====
   Cabecera con lo esencial y, debajo, todo a la vista en tarjetas de dos
   columnas con filas etiqueta / valor: la ficha se abre para encontrar un dato
   concreto y tiene que poder leerse de un vistazo, sin pestanas. */
.ti-hero {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  padding: 22px 24px;
  margin-bottom: 18px;
  border-radius: var(--radius);
  background: linear-gradient(120deg, #1b4dff 0%, #4f74ff 55%, #6d8bff 100%);
  color: #fff;
  box-shadow: 0 12px 28px rgba(27, 77, 255, .22);
}
.ti-hero__volver {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .18);
  color: #fff;
  font-size: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background .15s ease;
}
.ti-hero__volver:hover { background: rgba(255, 255, 255, .3); }
.ti-hero__main { flex: 1 1 320px; min-width: 0; }
.ti-hero__tipo {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  opacity: .85;
}
.ti-hero__titulo {
  margin: 2px 0 8px;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -.01em;
  color: #fff;
  overflow-wrap: anywhere;
}
.ti-hero__titulo .help-btn { vertical-align: middle; }
.ti-hero__chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.ti-hero__chips .badge { box-shadow: 0 0 0 2px rgba(255, 255, 255, .35); }
.ti-hero__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .16);
  font-size: 12px;
  font-weight: 500;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ti-hero__acciones { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.ti-hero__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid rgba(255, 255, 255, .55);
  border-radius: 10px;
  background: rgba(255, 255, 255, .12);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease;
}
.ti-hero__btn:hover { background: rgba(255, 255, 255, .24); }
.ti-hero__btn--fuerte { background: #fff; border-color: #fff; color: #1b4dff; }
.ti-hero__btn--fuerte:hover { background: #eef2ff; }
.ti-hero__btn:disabled { opacity: .6; cursor: wait; }

.ti-ficha {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  align-items: start;
}
.ti-ficha__col { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.ti-ficha--abajo { margin-top: 18px; }
.ti-panel { padding: 18px 20px; margin: 0; }
.ti-panel__cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.ti-panel__cabecera .ti-panel__titulo { margin-bottom: 0; border-bottom: 0; padding-bottom: 0; }
.ti-panel__cabecera { padding-bottom: 12px; border-bottom: 1px solid #eef2f7; margin-bottom: 12px; }
.ti-panel__titulo {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 8px;
  padding-bottom: 12px;
  border-bottom: 1px solid #eef2f7;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #1b4dff;
}
.ti-panel__icono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: rgba(27, 77, 255, .08);
  font-size: 14px;
}
.ti-panel__botones { display: flex; gap: 6px; }
.ti-panel__btn { padding: 6px 12px; font-size: 13px; border-radius: 8px; }
.ti-panel__ayuda { font-size: 12px; margin: 0 0 10px; }
.ti-panel__nota {
  margin: 12px 0 0;
  padding: 10px 12px;
  border-left: 3px solid #1b4dff;
  border-radius: 0 8px 8px 0;
  background: #f8fafc;
  font-size: 13px;
  white-space: pre-wrap;
  color: #334155;
}
.ti-panel__enlace {
  width: 100%;
  margin-top: 14px;
  padding: 9px 12px;
  border: 1px solid #c7d2fe;
  border-radius: 10px;
  background: #fff;
  color: #1b4dff;
  font-weight: 600;
  font-size: 13px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
}
.ti-panel__enlace:hover { background: #eef2ff; }

/* Filas etiqueta / valor */
.ti-kv { margin: 0; }
.ti-kv__fila {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  padding: 9px 0;
  border-bottom: 1px solid #f1f5f9;
}
.ti-kv__fila:last-child { border-bottom: 0; }
.ti-kv dt {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--muted);
}
.ti-kv dd {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 14px;
  font-weight: 500;
  color: #0f172a;
  overflow-wrap: anywhere;
}
.ti-kv__vacio { color: #cbd5e1; font-weight: 400; }
.ti-kv__copiar {
  flex: 0 0 auto;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  background: #fff;
  color: var(--muted);
  padding: 1px 6px;
  font-size: 12px;
  line-height: 1.5;
  cursor: pointer;
}
.ti-kv__copiar:hover { color: #1b4dff; border-color: #c7d2fe; }

/* Programas instalados (modo lectura) */
.ti-instalados { list-style: none; margin: 0; padding: 0; }
.ti-instalados li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid #f1f5f9;
}
.ti-instalados li:last-child { border-bottom: 0; }
.ti-instalados__nombre { flex: 1 1 auto; min-width: 0; font-weight: 500; color: #0f172a; overflow-wrap: anywhere; }
.ti-instalados__nombre i { color: var(--success); margin-right: 4px; }

/* Bitacora de movimientos */
.ti-bitacora { list-style: none; margin: 0; padding: 0 0 0 14px; border-left: 2px solid #e2e8f0; }
.ti-bitacora__item { position: relative; padding: 0 0 14px 12px; }
.ti-bitacora__item:last-child { padding-bottom: 0; }
.ti-bitacora__item::before {
  content: '';
  position: absolute;
  left: -21px;
  top: 5px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #1b4dff;
}
.ti-bitacora__cabecera { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.ti-bitacora__cabecera time { font-size: 12px; color: var(--muted); }
.ti-bitacora__detalle { font-size: 13px; color: #334155; }
.ti-bitacora__vacio { margin-left: -14px; padding-left: 0; list-style: none; }
.ti-bitacora:has(.ti-bitacora__vacio) { border-left: 0; padding-left: 0; }

@media (max-width: 900px) {
  .ti-ficha { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .ti-hero { padding: 16px; gap: 12px; }
  .ti-hero__titulo { font-size: 21px; }
  .ti-hero__acciones { width: 100%; justify-content: stretch; }
  .ti-hero__btn { flex: 1 1 calc(50% - 4px); justify-content: center; }
  .ti-panel { padding: 14px; }
  .ti-kv__fila { grid-template-columns: 112px minmax(0, 1fr); gap: 8px; }
}

/* ===== Ficha de la persona de TI (modal de #ti-personas) =====
   Reutiliza las tarjetas de la ficha del equipo (.ti-ficha, .ti-panel, .ti-kv,
   .ti-bitacora, .ti-instalados); aqui solo va lo propio. */
#tiPersonaFichaOverlay .modal__content { max-width: 980px; }
.ti-persona { background: transparent; }
.ti-persona__hero {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 20px;
  margin-bottom: 16px;
  border-radius: 14px;
  background: linear-gradient(120deg, #1b4dff 0%, #4f74ff 55%, #6d8bff 100%);
  color: #fff;
}
.ti-persona__avatar {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .2);
  border: 2px solid rgba(255, 255, 255, .55);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: .02em;
}
.ti-persona__main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ti-persona__nombre { font-size: 20px; font-weight: 800; line-height: 1.2; overflow-wrap: anywhere; }
.ti-persona__puesto { font-size: 13px; opacity: .9; }
.ti-persona__chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.ti-persona__chips .badge { box-shadow: 0 0 0 2px rgba(255, 255, 255, .35); }
.ti-persona__chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .16);
  font-size: 12px;
  font-weight: 500;
}
.ti-persona .ti-panel { box-shadow: none; border: 1px solid #e2e8f0; }
.ti-panel__cuenta { color: var(--muted); font-weight: 600; letter-spacing: 0; }
.ti-ficha--una { grid-template-columns: minmax(0, 1fr); }

/* Equipos de la persona: cada uno lleva a su ficha */
.ti-equipos-lista { display: flex; flex-direction: column; gap: 8px; }
.ti-equipo-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  background: #fff;
  text-align: left;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.ti-equipo-item:hover { border-color: #c7d2fe; box-shadow: 0 4px 12px rgba(27, 77, 255, .08); }
.ti-equipo-item__icono {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: rgba(27, 77, 255, .08);
  color: #1b4dff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}
.ti-equipo-item__texto { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ti-equipo-item__texto strong { font-size: 14px; color: #0f172a; overflow-wrap: anywhere; }
.ti-equipo-item__texto small { font-size: 12px; color: #475569; overflow-wrap: anywhere; }
.ti-equipo-item__ir { color: #94a3b8; }
.ti-instalados .d-block { display: block; }

@media (max-width: 560px) {
  .ti-persona__hero { padding: 14px; gap: 12px; }
  .ti-persona__avatar { width: 46px; height: 46px; font-size: 17px; }
  .ti-persona__nombre { font-size: 18px; }
  .ti-equipo-item { display: grid; grid-template-columns: 38px minmax(0, 1fr); column-gap: 12px; row-gap: 6px; }
  .ti-equipo-item .badge { grid-column: 2; justify-self: start; }
  .ti-equipo-item__ir { display: none; }
}
