/* ============================================================
   SARP Admin · Capa de interfaz (2026-09-08)
   Alinea el aspecto con el Aula Virtual: barra blanca, botones
   ovalados, espaciados parejos, y que sirva en el teléfono.

   Va DESPUÉS de styles.css a propósito: refina lo que ya existe
   en vez de reescribirlo, así ninguna pantalla se rompe.
   ============================================================ */

:root{
  /* La identidad ya compartía el azul con el Aula; se le suma el navy. */
  --navy:#0f2d40;
  --primary-soft:#e8f4fa;

  /* Escala de espaciado: antes cada pantalla usaba su propio número. */
  --sp-1:6px; --sp-2:10px; --sp-3:16px; --sp-4:24px; --sp-5:32px;

  /* Redondeos: los botones son ovalados, nunca cuadrados. */
  --r-pill:999px;
  --r-card:14px;
  --r-field:10px;

  --sombra-1:0 1px 2px rgba(16,42,60,.06), 0 1px 3px rgba(16,42,60,.04);
  --sombra-2:0 4px 16px rgba(16,42,60,.08);
  --sombra-3:0 12px 32px rgba(16,42,60,.12);
}

body{
  font-family:system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  background:#f4f7fa;
  -webkit-font-smoothing:antialiased;
}

/* ============ BARRA SUPERIOR BLANCA (como el Aula) ============ */
.topnav{
  background:#fff;
  color:var(--navy);
  border-bottom:1px solid #e4ebf0;
  box-shadow:var(--sombra-1);
  padding:10px var(--sp-4);
}
.topnav .brand{color:var(--primary)}
.topnav .brand small{color:var(--gray)}
.nav-tab{
  color:var(--gray);
  border-radius:var(--r-pill);
  padding:8px 16px;
  transition:background .15s,color .15s;
}
.nav-tab:hover:not(.active){background:var(--light);color:var(--navy)}
.nav-tab.active{background:var(--primary);color:#fff;box-shadow:0 2px 8px rgba(19,157,203,.28)}
.user-menu{color:var(--gray)}

/* ============ BOTONES OVALADOS ============ */
.btn{
  border-radius:var(--r-pill);
  padding:10px 20px;
  transition:filter .15s,box-shadow .15s,transform .06s;
  line-height:1.2;
}
.btn:hover{box-shadow:var(--sombra-1)}
.btn:active{transform:translateY(1px)}
.btn.small{padding:6px 14px}
.btn.alt{border-color:#dbe4ea}
.btn.alt:hover{background:var(--primary-soft);border-color:var(--primary);color:var(--primary-dark)}
.btn:disabled{opacity:.55;cursor:not-allowed;box-shadow:none;transform:none}

/* El foco tiene que verse: hay quien navega con el tabulador. */
.btn:focus-visible,
.nav-tab:focus-visible,
.cm-seccion:focus-visible,
.subnav button:focus-visible{
  outline:3px solid rgba(19,157,203,.45);
  outline-offset:2px;
}

/* ============ CAMPOS ============ */
.field input,.field textarea,.field select,
.toolbar input,.toolbar select,
.form-group input,.form-group textarea,.form-group select,
.cmp-select{
  border-radius:var(--r-field);
  border-color:#dbe4ea;
  padding:10px 13px;
  transition:border-color .15s,box-shadow .15s;
}
.field input:focus,.field textarea:focus,.field select:focus,
.toolbar input:focus,.toolbar select:focus,
.form-group input:focus,.form-group textarea:focus,.form-group select:focus,
.cmp-select:focus{
  outline:none;
  border-color:var(--primary);
  box-shadow:0 0 0 3px rgba(19,157,203,.18);
}
/* Campo con dato inválido: se marca en rojo, no solo con un aviso suelto. */
.field input[aria-invalid="true"],
.form-group input[aria-invalid="true"],
.field select[aria-invalid="true"],
.form-group select[aria-invalid="true"],
.field textarea[aria-invalid="true"],
.form-group textarea[aria-invalid="true"]{
  border-color:var(--danger);
  box-shadow:0 0 0 3px rgba(239,68,68,.15);
}
.campo-error{color:var(--danger);font-size:12px;margin-top:4px;display:block}

/* ============ TARJETAS Y TABLAS ============ */
.module-card,.detail-card,.form-panel,.user-card,
.empleado-card,.nota-card,.quincena-card,.stat-card,
.cmp-card,.cmp-tarea,.cmp-meta-card,.pub-row{
  border-radius:var(--r-card);
  box-shadow:var(--sombra-1);
}
.module-card:hover,.empleado-card:hover,.quincena-card:hover{box-shadow:var(--sombra-2)}
.modal-content{border-radius:var(--r-card);box-shadow:var(--sombra-3);padding:26px}

table.data-table{border-radius:var(--r-card);box-shadow:var(--sombra-1)}
table.data-table th{background:#f7fafc;color:var(--gray);border-bottom:1px solid #e4ebf0}
table.data-table td{border-top:1px solid #eef3f7}
table.data-table tbody tr:hover td{background:#f9fcfe}

/* Que se vea qué está escogido: fila marcada, tarjeta marcada. */
table.data-table tr.seleccionada td,
tr[aria-selected="true"] td{
  background:var(--primary-soft)!important;
  box-shadow:inset 3px 0 0 var(--primary);
}
.cmp-card.seleccionada,.empleado-card.seleccionada,.pub-row.seleccionada{
  border-color:var(--primary);
  box-shadow:0 0 0 2px rgba(19,157,203,.35);
}

/* Casillas de marcar: más grandes, más fáciles de dar con el dedo. */
input[type="checkbox"],input[type="radio"]{
  width:17px;height:17px;
  accent-color:var(--primary);
  cursor:pointer;
  vertical-align:middle;
}

/* Barra de acciones que aparece al marcar varios. */
.barra-seleccion{
  position:sticky;bottom:0;z-index:40;
  display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;
  background:var(--navy);color:#fff;
  padding:12px var(--sp-3);
  border-radius:var(--r-card);
  box-shadow:var(--sombra-3);
  margin-top:var(--sp-3);
}
.barra-seleccion .cuenta{font-weight:700}
.barra-seleccion .btn.alt{background:transparent;color:#fff;border-color:rgba(255,255,255,.4)}
.barra-seleccion .btn.alt:hover{background:rgba(255,255,255,.12);color:#fff}

/* ============ SUB-PESTAÑAS ============ */
.subnav button{border-radius:var(--r-pill) var(--r-pill) 0 0;padding:10px 18px}

/* ============ TELÉFONO ============ */
/* Antes había 8 reglas de móvil en toda la aplicación. */
@media (max-width:820px){
  .container{padding:0 12px;margin:14px auto}
  .topnav{padding:10px 14px}
  .page h1{font-size:20px}
  .page-header{align-items:flex-start}

  /* Las barras de herramientas se apilan y los controles ocupan el ancho. */
  .toolbar{flex-direction:column;align-items:stretch}
  .toolbar .grow{min-width:0;width:100%}
  .toolbar input,.toolbar select,.toolbar .btn{width:100%}

  /* Las tablas anchas ruedan de lado en vez de romper la página. */
  .tabla-scroll,.cmp-tabla-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  table.data-table{display:block;overflow-x:auto;white-space:nowrap}

  /* Los modales ocupan casi toda la pantalla: se leen y se llenan mejor. */
  .modal{padding:0;align-items:flex-end}
  .modal-content{
    max-width:100%;
    border-radius:var(--r-card) var(--r-card) 0 0;
    max-height:94vh;
    padding:20px 18px calc(20px + env(safe-area-inset-bottom));
  }
  .form-actions{flex-direction:column-reverse}
  .form-actions .btn{width:100%}

  /* Las fichas dejan de pelear por el ancho. */
  .empleado-card,.nota-card,.user-card,.quincena-card,.pub-row{
    grid-template-columns:1fr;
    flex-direction:column;
    align-items:flex-start;
  }
  .quincena-card .counts{width:100%;justify-content:space-between}
  .pub-row{display:flex}
  .pub-row .actions{flex-direction:row;align-items:center;width:100%;justify-content:flex-start}

  .stats-row{grid-template-columns:repeat(auto-fit,minmax(108px,1fr))}
  .detail-card .info{grid-template-columns:1fr 1fr}
}

@media (max-width:480px){
  .detail-card .info{grid-template-columns:1fr}
  .stats-row{grid-template-columns:1fr 1fr}
  .btn{padding:11px 18px}          /* el dedo necesita más área que el ratón */
  .btn.small{padding:8px 14px}
}

/* En pantalla táctil, todo lo que se toca mide al menos 40px. */
@media (hover:none){
  .btn,.nav-tab,.cm-seccion,.subnav button{min-height:40px}
  .cmp-file-x{width:28px;height:28px;font-size:18px}
}

/* Respeta a quien pidió menos animación en su sistema. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}
}

/* ============ IMPRESIÓN ============ */
/* La nota de entrega se imprime como siempre: nada de esto la toca. */
@media print{
  .topnav,.barra-seleccion{display:none!important}
  body{background:#fff}
}

/* ============================================================
   SELECCIÓN: desplegables buscables y casillas
   ============================================================ */

/* --- Desplegable buscable --- */
/* El <select> real se queda debajo (lo lee el código de siempre) y encima va
   una caja de texto que filtra. */
.sel-buscable{position:relative}
.sel-buscable-oculto{
  position:absolute;
  opacity:0;
  pointer-events:none;
  height:0;
  width:0;
}
.sel-buscable-input{
  width:100%;
  border:1px solid #dbe4ea;
  border-radius:var(--r-field);
  padding:10px 13px;
  font-size:14px;
  background:#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 12px center;
  cursor:text;
}
.sel-buscable-input:focus{
  outline:none;
  border-color:var(--primary);
  box-shadow:0 0 0 3px rgba(19,157,203,.18);
}
.sel-buscable-lista{
  position:absolute;
  z-index:120;
  top:100%;
  left:0;
  right:0;
  margin-top:4px;
  max-height:260px;
  overflow-y:auto;
  background:#fff;
  border:1px solid #dbe4ea;
  border-radius:var(--r-field);
  box-shadow:var(--sombra-3);
}
.sel-op{padding:9px 13px;cursor:pointer;font-size:14px;line-height:1.3}
.sel-op:hover,.sel-op.marcada{background:var(--primary-soft)}
.sel-op.actual{font-weight:700;color:var(--primary-dark)}
.sel-vacio{padding:12px 13px;color:var(--gray);font-size:13px;text-align:center}

/* --- Casilla de marcar dentro de la tabla --- */
td[data-sel-caja]{text-align:center;cursor:default}
.sel-caja{margin:0}
table.data-table th:first-child .sel-todas{margin:0;vertical-align:middle}

/* En el teléfono la lista del buscable no debe salirse de la pantalla. */
@media (max-width:640px){
  .sel-buscable-lista{max-height:210px}
}

/* ============================================================
   CONTRASTE: que no se pierdan las letras (2026-09-09)

   Medido con la fórmula de contraste estándar sobre blanco. El mínimo
   legible es 4.5. Estaban por debajo:
     gris claro #94a3b8  2.56      verde  #10b981  2.54
     azul       #139DCB  3.13      naranja #f59e0b 2.15
     rojo       #ef4444  3.76      gris   #64748b  4.43 (sobre la página)

   Se conserva el mismo color, oscurecido hasta que se lee. El azul y el
   verde claros SIGUEN usándose como FONDO (ahí no hay problema: encima
   va texto blanco); lo que cambia es cuando son LETRA.
   ============================================================ */
:root{
  --azul-texto:#0b6d8f;      /* 5.84 sobre blanco */
  --verde-texto:#067a52;     /* 5.37 */
  --naranja-texto:#b45309;   /* 5.02 */
  --rojo-texto:#d32f2f;      /* 4.98 */
  --gray:#5b6a7d;            /* 5.52 — antes #64748b, quedaba corto */
}

/* Números grandes de los tableros */
.stat-card .num{color:var(--azul-texto)}
.stat-card.green .num{color:var(--verde-texto)}
.stat-card.orange .num{color:var(--naranja-texto)}
.stat-card.red .num{color:var(--rojo-texto)}

/* Contadores de las fichas */
.empleado-card .stats strong,
.quincena-card .counts strong{color:var(--azul-texto)}
.quincena-card .counts .pendientes strong{color:var(--naranja-texto)}
.quincena-card .counts .aprobadas strong{color:var(--verde-texto)}
.quincena-card .counts .rechazadas strong{color:var(--rojo-texto)}

/* Enlaces, títulos de sección y pestañas activas */
.pub-row .body .meta a,
.form-panel h3.subhead,
.subnav button.active{color:var(--azul-texto)}
.subnav button.active{border-bottom-color:var(--azul-texto)}
.pub-row .body .comentario{color:var(--rojo-texto)}
.error-msg{color:var(--rojo-texto)}
.error-msg.success{color:var(--verde-texto)}

/* Textos apagados: "Sin asignar", "Sin descripción" y similares */
.apagado,
em[style*="94a3b8"]{color:var(--gray)!important;font-style:italic}

/* Módulo de proyectos y tareas */
.cmp-meta-num{color:var(--dark)}
.cmp-alerta{color:var(--rojo-texto)}
.sel-op.actual{color:var(--azul-texto)}

/* La barra superior blanca: nada hereda ya el blanco de cuando era oscura */
.topnav,.topnav *{color:inherit}
.topnav{color:var(--dark)}
.topnav .brand{color:var(--azul-texto)}
.topnav .brand small{color:var(--gray)}
.nav-tab{color:var(--gray)}
.nav-tab.active,.nav-tab.active *{color:#fff}
.user-menu,#userLabel{color:var(--gray)}
/* Los botones de la barra tienen que verse sobre fondo blanco */
.topnav .btn.alt{border-color:#c8d4dd;color:var(--dark)}

/* ============================================================
   CAMPOS PAREJOS (2026-09-09)

   María: "unos tienen un ancho otros otro y así". La causa de fondo era
   que el módulo de proyectos usaba unas clases (.form-group/.form-row)
   que no estaban definidas en ninguna hoja; ya se pasó a las mismas del
   resto (.field/.form-grid). Esto asegura además que TODO campo, esté
   donde esté, mida igual.
   ============================================================ */

/* Mismo ancho y misma altura para todo lo que se escribe. */
.field input:not([type="checkbox"]):not([type="radio"]),
.field select,
.field textarea,
.modal-body input:not([type="checkbox"]):not([type="radio"]),
.modal-body select,
.modal-body textarea,
.form-panel input:not([type="checkbox"]):not([type="radio"]),
.form-panel select,
.form-panel textarea{
  width:100%;
  min-height:42px;
  font-size:14px;
}
.field textarea,.modal-body textarea,.form-panel textarea{
  min-height:84px;
  resize:vertical;
  line-height:1.45;
}

/* Las etiquetas, todas iguales y siempre encima del campo. */
.field label{
  font-size:11px;
  text-transform:uppercase;
  letter-spacing:.5px;
  color:var(--gray);
  font-weight:600;
  margin-bottom:2px;
}

/* Separación pareja entre campos: antes cada pantalla usaba la suya. */
.field{margin-bottom:var(--sp-3)}
.form-grid{gap:var(--sp-3) var(--sp-3)}
.modal-body .field:last-child{margin-bottom:0}

/* En una rejilla de dos, el campo marcado como ancho ocupa las dos. */
.form-grid .full,.form-grid .ancho{grid-column:1/-1}

/* El desplegable buscable ocupa el mismo hueco que un campo normal. */
.sel-buscable{width:100%}
.sel-buscable-input{min-height:42px}

/* En el teléfono todo va en una sola columna. */
@media (max-width:640px){
  .form-grid,.form-grid.cols-3{grid-template-columns:1fr}
}

/* ============================================================
   Los cinco últimos textos ilegibles (2026-09-09)
   Encontrados midiendo TODAS las combinaciones del CSS servido,
   no a ojo. Los demás casos que parecían bajos eran falsos:
   bordes, o texto claro sobre fondo oscuro (donde se lee bien).
   ============================================================ */

/* Celda de fin de semana CON dato: era azul claro sobre amarillo
   claro (2.49). El dato es lo importante de esa tabla. */
.matriz-table td.cell-weekend.cell-has{color:var(--dark)!important;font-weight:700}

/* Celda vacía de la matriz: era casi invisible (1.49). Sigue siendo
   discreta —solo marca el hueco— pero ahora se ve. */
.matriz-table .cell-empty{color:#7b8794}

/* La × de cerrar el modal de baja: 2.56 sobre blanco. */
.baja-close{color:var(--gray)}
.baja-close:hover{color:var(--dark)}

/* Títulos y logo del formulario de baja: azul claro sobre blanco. */
.bf-section h3,.bp-logo{color:var(--azul-texto)}

/* El recuadro de la marca, en pantalla. En la hoja impresa se deja el
   azul original: sobre papel el contraste no es el mismo problema. */
.login-brand .logo-box,.topnav .brand{color:var(--azul-texto)}

/* ============================================================
   VALIDACIÓN DE FORMULARIOS (2026-09-09)
   El aviso va pegado al campo, no en una línea suelta al final.
   ============================================================ */
.campo-error{
  display:block;
  color:var(--rojo-texto);
  font-size:12.5px;
  line-height:1.35;
  margin-top:5px;
  min-height:0;
}
.campo-error:empty{display:none}

/* Aviso ámbar: algo que conviene mirar, pero NO impide guardar.
   Se usa para el serial repetido: hay equipos legítimos sin serial. */
.campo-aviso{
  display:block;
  color:var(--naranja-texto);
  background:#fff8ec;
  border-left:3px solid var(--naranja-texto);
  border-radius:0 8px 8px 0;
  font-size:12.5px;
  line-height:1.4;
  margin-top:6px;
  padding:7px 10px;
}

/* El campo con error se nota antes de leer el mensaje. */
[aria-invalid="true"]{
  border-color:var(--rojo-texto)!important;
  box-shadow:0 0 0 3px rgba(211,47,47,.13)!important;
}
[aria-invalid="true"]:focus{
  box-shadow:0 0 0 3px rgba(211,47,47,.24)!important;
}

/* ============================================================
   Sub-pestañas de Productividad CM (2026-09-09)
   Se llamaban .cm-subtab, igual que las pestañas internas de una
   quincena que ya existían en styles.css. La regla vieja
   (.cm-subtabs button.active) ganaba por especificidad y pintaba el
   texto AZUL sobre el fondo AZUL: solo se veían los emojis, que no
   heredan el color. Se renombraron a .cm-seccion; esto lo blinda.
   ============================================================ */
.cm-secciones .cm-seccion.active,
.cm-secciones button.cm-seccion.active{
  background:var(--primary);
  color:#fff;
  border-bottom-color:transparent;
}
.cm-secciones .cm-seccion:hover:not(.active){color:var(--dark)}

/* ============================================================
   INVENTARIO: alertas e historial (2026-09-09)
   ============================================================ */

/* --- Caja de alertas --- */
.alertas-caja{
  border:1px solid #e4ebf0;
  border-left:4px solid var(--naranja-texto);
  border-radius:var(--r-card);
  background:#fff;
  margin-bottom:var(--sp-3);
  overflow:hidden;
  box-shadow:var(--sombra-1);
}
.alertas-caja.con-urgentes{border-left-color:var(--rojo-texto)}
.alertas-cabeza{
  display:flex;align-items:center;gap:10px;
  width:100%;
  background:none;border:0;
  padding:13px 16px;
  cursor:pointer;
  text-align:left;
  font-size:14px;
  color:var(--dark);
}
.alertas-cabeza:hover{background:#f9fbfc}
.alertas-ico{font-size:17px}
.alertas-resumen{
  flex:1;
  color:var(--gray);
  font-size:12.5px;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.alertas-flecha{color:var(--gray)}
.alertas-cuerpo{padding:0 16px 14px;border-top:1px solid #eef3f7}
.alerta-grupo{margin-top:16px}
.alerta-grupo h4{font-size:13.5px;display:flex;align-items:center;gap:8px}
.alerta-grupo.urgente h4{color:var(--rojo-texto)}
.alerta-porque{font-size:12.5px;color:var(--gray);margin:3px 0 7px}
.alerta-lista{list-style:none;margin:0;padding:0;font-size:13px}
.alerta-lista li{padding:5px 0;border-bottom:1px solid #f2f6f9;line-height:1.45}
.alerta-lista li:last-child{border-bottom:0}
.alerta-lista a{color:var(--azul-texto);font-weight:600;text-decoration:none;cursor:pointer}
.alerta-lista a:hover{text-decoration:underline}

/* --- Historial de un equipo --- */
.hi-cabeza{
  background:var(--bg-soft,#f6f8fa);
  border-radius:12px;
  padding:14px 16px;
  margin-bottom:16px;
}
.hi-resumen{display:flex;flex-wrap:wrap;gap:8px 20px;margin-top:9px;font-size:13px;color:var(--gray)}
.hi-resumen b{color:var(--dark)}
.hi-linea{list-style:none;margin:0;padding:0;position:relative}
/* El hilo que une los hitos. */
.hi-linea::before{
  content:'';position:absolute;left:15px;top:12px;bottom:12px;
  width:2px;background:#e4ebf0;
}
.hi-hito{
  display:flex;align-items:flex-start;gap:12px;
  padding:11px 0;position:relative;
}
.hi-ico{
  width:32px;height:32px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  background:#fff;border:2px solid #e4ebf0;border-radius:50%;
  font-size:14px;z-index:1;
}
.hi-baja .hi-ico{border-color:var(--rojo-texto)}
.hi-ingreso .hi-ico{border-color:var(--verde-texto)}
.hi-texto{flex:1;min-width:0}
.hi-tit{font-weight:600;font-size:14px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.hi-fecha{font-size:12.5px;color:var(--gray);white-space:nowrap;padding-top:7px}
.hi-cambios{margin-top:18px;font-size:13px}
.hi-cambios summary{cursor:pointer;color:var(--gray);padding:7px 0}
.hi-cambios summary:hover{color:var(--dark)}
.modal-wide{max-width:680px}

@media (max-width:640px){
  .alertas-resumen{display:none}
  .hi-fecha{padding-top:0;font-size:12px}
  .hi-hito{flex-wrap:wrap}
}

/* ============================================================
   BARRA DE DESHACER (2026-09-09)
   Aparece tras un cambio sobre varios equipos. Nació del error del
   día 8: entonces hubo que ir al respaldo para recuperar 12 estados.
   ============================================================ */
.barra-deshacer{
  position:fixed;
  left:50%;
  bottom:24px;
  transform:translate(-50%,140%);
  z-index:210;
  display:flex;align-items:center;gap:12px;
  background:var(--navy);
  color:#fff;
  padding:12px 16px;
  border-radius:var(--r-pill);
  box-shadow:var(--sombra-3);
  font-size:13.5px;
  max-width:calc(100vw - 32px);
  transition:transform .25s ease, opacity .25s ease;
  opacity:0;
  pointer-events:none;
}
.barra-deshacer.visible{transform:translate(-50%,0);opacity:1;pointer-events:auto}
.barra-deshacer .btn.alt{
  background:transparent;color:#fff;border-color:rgba(255,255,255,.45);
}
.barra-deshacer .btn.alt:hover{background:rgba(255,255,255,.14);color:#fff}

.lote-fila{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0}

@media (max-width:640px){
  .barra-deshacer{left:12px;right:12px;transform:translateY(140%);max-width:none;flex-wrap:wrap}
  .barra-deshacer.visible{transform:translateY(0)}
}
