/* ============================================================================
   Patatas Meléndez · La buena patata · RRHH
   Sigue el manual de imagen corporativa "La buena patata 2025" (src/Manual...pdf)
   Paleta Pantone oficial, tipografía Epilogue.
============================================================================ */

/* Tipografías corporativas vía Google Fonts (Epilogue es la oficial para
   textos). Hagrid/Recoleta no están en Google Fonts → fallback decente. */
@import url('https://fonts.googleapis.com/css2?family=Epilogue:wght@300;400;500;600;700;800&display=swap');

:root {
  /* ============ Paleta corporativa Pantone (manual 2025) ============ */
  --c-naranja:       #DE5014;  /* Pantone 1655 C - acento principal */
  --c-amarillo:      #FFC72C;  /* Pantone 123 C — color visual dominante de la marca */
  --c-marron-tierra: #A68155;  /* Pantone 729 C */
  --c-morado:        #711853;  /* Pantone 235 C */
  --c-lavanda:       #73688E;  /* Pantone 667 C */
  --c-salmon:        #EDA38A;  /* Pantone 1625 C */
  --c-negro:         #222221;
  --c-blanco:        #FFFFFF;

  /* ============ Tokens semánticos derivados ============ */
  --color-primary:   var(--c-naranja);     /* CTAs y botones (alto contraste sobre blanco) */
  --color-secondary: var(--c-amarillo);    /* Color visual dominante de la marca: fondos, banners, acentos */
  --color-accent:    var(--c-marron-tierra);
  --color-fg:        var(--c-negro);
  --color-muted:     #6b6b69;
  --color-line:      #e0d8d0;
  --color-bg:        #faf7f4;     /* crema suave, derivado del salmón pálido */
  --color-card-bg:   var(--c-blanco);

  /* Estados — el manual no especifica verde de éxito, usamos un verde
     sobrio independiente coherente con la temática agrícola. */
  --color-success:   #5c8a3e;
  --color-warning:   var(--c-amarillo);    /* el amarillo de la marca funciona como advertencia */
  --color-danger:    #a01a1a;

  /* Zonas (del Excel original — operativas, no corporativas) */
  /* Columna de botones de las listas de configuración: cabe «Editar líneas»
     + «Ajustes», que es el caso más ancho. */
  --ancho-acciones: 13.5rem;

  --color-zona-envasado: #d6c5e8;
  --color-zona-pa:       #b8e986;

  --radius: 6px;
  --shadow: 0 1px 3px rgba(34, 34, 33, 0.08);
  --font-body: 'Epilogue', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--color-fg);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--color-primary); text-decoration: none; transition: color .15s; }
a:hover { color: var(--c-morado); text-decoration: underline; }
h1, h2, h3 { font-weight: 700; letter-spacing: -0.01em; }

/* ---------- TOPBAR ---------- */
.topbar {
  display: flex; align-items: center; gap: 1rem;
  padding: 0.75rem 1.5rem;
  background: var(--c-blanco);
  border-bottom: 4px solid var(--c-amarillo);  /* amarillo Meléndez como firma visual */
  box-shadow: var(--shadow);
}
.brand a {
  color: var(--color-fg); font-size: 1rem; font-weight: 600;
  display: flex; align-items: center; gap: 0.4rem;
}
.brand .tagline {
  font-style: italic; font-weight: 400; color: var(--c-marron-tierra);
  margin-left: 0.4rem; font-size: 0.85rem;
}
.nav { flex: 1; display: flex; gap: 0.25rem; margin-left: 2rem; }
.nav a {
  padding: 0.4rem 0.8rem; border-radius: 4px;
  color: var(--color-muted); font-weight: 500;
}
.nav a:hover { background: var(--color-bg); text-decoration: none; color: var(--color-fg); }
.nav a.active {
  color: var(--color-primary); background: rgba(222,80,20,0.08);
}
.user { display: flex; align-items: center; gap: 0.75rem; font-size: 0.85rem; }
.user-name { font-weight: 600; }
.user-role {
  text-transform: uppercase; font-size: 0.65rem;
  padding: 0.2rem 0.55rem; border-radius: 12px;
  background: var(--color-primary); color: white;
  letter-spacing: 0.7px; font-weight: 700;
}
.logout, .login { color: var(--color-muted); font-size: 0.85rem; }
/* «Salir» es un botón (POST) con el aspecto del enlace de antes. */
.logout-form { display: inline; margin: 0; }
button.logout { background: none; border: 0; padding: 0; font: inherit; font-size: 0.85rem;
  cursor: pointer; text-decoration: underline; }

/* ---------- LAYOUT ---------- */
.content { max-width: 1400px; margin: 1.75rem auto; padding: 0 1.5rem; }
.bottombar {
  text-align: center; padding: 1.5rem 1rem;
  color: var(--color-muted); font-size: 0.75rem;
  border-top: 1px solid var(--color-line); margin-top: 3rem;
  background: var(--c-blanco);
}

/* ---------- FLASH ---------- */
.flash {
  padding: 0.75rem 1rem; border-radius: var(--radius);
  margin-bottom: 1rem; border-left: 4px solid;
}
.flash-info    { background: rgba(115, 104, 142, 0.1); border-color: var(--c-lavanda); }
.flash-success { background: rgba(92, 138, 62, 0.1);   border-color: var(--color-success); }
.flash-warning { background: rgba(255, 199, 44, 0.15); border-color: var(--c-amarillo); }
.flash-error   { background: rgba(160, 26, 26, 0.08);  border-color: var(--color-danger); }

/* ---------- DASHBOARD CARDS ---------- */
.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem;
}
.card {
  background: var(--color-card-bg);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.25rem;
  display: flex; flex-direction: column; gap: 0.5rem;
  border-top: 3px solid transparent;
  transition: border-color .15s, transform .15s;
}
.card:hover { border-top-color: var(--color-primary); }
.card-title { font-weight: 700; color: var(--color-fg); margin: 0; font-size: 1rem; }
.card-subtitle { color: var(--color-muted); font-size: 0.85rem; margin: 0; }
.card-body { flex: 1; }
.card-footer { display: flex; justify-content: flex-end; gap: 0.5rem; }
.btn {
  display: inline-block; padding: 0.5rem 1rem;
  background: var(--color-primary); color: white;
  border: 0; border-radius: 4px; cursor: pointer;
  font-family: var(--font-body); font-size: 0.85rem; font-weight: 600;
  text-decoration: none; transition: background .15s;
}
.btn:hover { background: var(--c-morado); text-decoration: none; color: white; }
.btn-secondary {
  background: transparent; color: var(--color-primary);
  border: 1px solid var(--color-primary);
}
.btn-secondary:hover { background: var(--color-primary); color: white; }
.threshold-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.6rem 0.8rem;
  margin: 0.5rem 0;
}
.threshold-grid label {
  display: flex; flex-direction: column; gap: 0.2rem;
  font-size: 0.8rem; color: var(--color-muted); font-weight: 500;
}
.threshold-grid input[type="number"] {
  padding: 0.4rem 0.5rem; font-size: 0.95rem;
  border: 1px solid var(--color-line); border-radius: 4px;
  background: var(--color-bg); color: var(--color-fg);
  font-family: var(--font-body);
}
.threshold-grid input:focus {
  outline: 2px solid var(--color-primary); outline-offset: -1px;
}
.threshold-help {
  font-size: 0.78rem; color: var(--color-muted);
  margin: 0.4rem 0 0.6rem 0;
}
.threshold-help code {
  background: var(--color-line); padding: 0 0.3rem; border-radius: 2px;
}
.progress {
  height: 6px; background: var(--color-line); border-radius: 3px;
  overflow: hidden; margin: 0.4rem 0;
}
.progress-fill { height: 100%; background: var(--color-success); }
.metric { font-size: 2rem; font-weight: 700; color: var(--color-primary); }
.metric-small { font-size: 0.85rem; color: var(--color-muted); }

/* ---------- PLANTILLA / GRID DE PUESTOS ---------- */
.plantilla-header {
  /* `wrap` porque en un movil esta barra no cabe: la navegacion del dia, el
     selector de turno y el boton de recalcular suman mas de 375px, y sin
     envolver empujaban la pagina entera 341px a la derecha (medido el
     2026-09-22). La web tiene que valer en PC y en movil. */
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding: 1rem; background: var(--c-blanco);
  border-radius: var(--radius); box-shadow: var(--shadow);
  margin-bottom: 1rem;
}
/* Novedades de un dia cerrado que esperan decision. Solo aparece cuando hay
   algo que decidir: un panel vacio permanente pasa a ser decorado. */
.incidencias-panel {
  border: 1px solid var(--c-naranja, #DE5014);
  border-left-width: 4px;
  background: rgba(222, 80, 20, 0.05);
  border-radius: var(--radius);
  padding: 0.7rem 0.9rem; margin: 0 0 0.9rem;
}
.incidencias-panel h3 {
  margin: 0 0 0.3rem; font-size: 0.95rem; color: var(--c-naranja, #DE5014);
}
.incidencias-intro { margin: 0 0 0.6rem; font-size: 0.85rem; color: var(--color-muted); }
.incidencias-lista { list-style: none; margin: 0; padding: 0; }
.incidencias-lista > li {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.8rem; flex-wrap: wrap;
  padding: 0.45rem 0; border-top: 1px solid var(--color-line);
}
.incidencia-que { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.incidencia-puesto { font-weight: 600; }
.incidencia-motivo { color: var(--color-muted); font-size: 0.82rem; }
.incidencia-acciones { display: flex; align-items: center; gap: 0.35rem; flex-wrap: wrap; }
.incidencia-form { display: flex; align-items: center; gap: 0.25rem; margin: 0; }
.incidencia-form select { font-size: 0.8rem; padding: 0.2rem; max-width: 14rem; }
.btn-enlace {
  background: none; border: none; padding: 0.2rem 0.3rem; cursor: pointer;
  color: var(--color-muted); text-decoration: underline; font-size: 0.8rem;
  font-family: var(--font-body);
}
.btn-enlace:hover { color: var(--color-fg); }
/* En movil cada novedad se lee entera antes de decidir: los botones debajo. */
@media (max-width: 640px) {
  .incidencias-lista > li { flex-direction: column; align-items: stretch; }
}

/* Vista semanal: la hoja de Excel de RRHH, con scroll lateral por dias.
   La primera columna y la cabecera se quedan fijas -- sin eso, al desplazarse a
   la derecha no se sabe que puesto se esta mirando, que es justo el dato que
   hace falta. */
.semana-scroll {
  overflow-x: auto; border: 1px solid var(--color-line);
  border-radius: var(--radius); background: var(--c-blanco);
}
table.semana { border-collapse: separate; border-spacing: 0; width: max-content; min-width: 100%; }
table.semana th, table.semana td {
  border-bottom: 1px solid var(--color-line); padding: 0.3rem 0.5rem;
  font-size: 0.8rem; vertical-align: top; text-align: left;
}
table.semana thead th {
  position: sticky; top: 0; z-index: 3; background: var(--c-blanco);
  border-bottom: 2px solid var(--color-primary, #FFC72C); white-space: nowrap;
}
.semana-fila-cabecera {
  position: sticky; left: 0; z-index: 2; background: var(--c-blanco);
  font-weight: 600; white-space: nowrap; max-width: 15rem;
  overflow: hidden; text-overflow: ellipsis;
  border-right: 1px solid var(--color-line);
}
table.semana thead .semana-fila-cabecera { z-index: 4; }
table.semana td { min-width: 8.5rem; }
.semana-zona td, .semana-seccion td { position: sticky; left: 0; }
.semana-zona td {
  background: rgba(115, 104, 142, 0.12); font-weight: 700; letter-spacing: .03em;
  text-transform: uppercase; font-size: 0.75rem; color: var(--c-morado, #73688E);
}
.semana-seccion td {
  background: var(--color-bg); font-weight: 600; font-size: 0.78rem;
  color: var(--color-muted);
}
.semana-finde { background: rgba(0, 0, 0, 0.025); }
.semana-nota { font-size: 0.68rem; font-weight: 400; color: var(--color-muted); }
/* El nombre entero parte en dos lineas si hace falta: cortarlo a dos palabras
   producia «MARIA DEL». */
.semana-persona { line-height: 1.25; }
.semana-ausente { color: var(--c-naranja, #DE5014); text-decoration: line-through; }
.semana-ett {
  font-size: 0.62rem; padding: 0 0.25rem; border-radius: 3px;
  background: var(--c-lavanda, #B6AECF); color: #fff; vertical-align: middle;
}
.semana-falta { color: var(--color-muted); font-size: 0.75rem; }
.semana-falta-ett { color: var(--c-naranja, #DE5014); font-weight: 600; }
.semana-sinett { color: var(--c-morado, #73688E); font-size: 0.72rem; }
.semana-apagada { background: repeating-linear-gradient(45deg, #fafafa, #fafafa 6px, #f0f0f0 6px, #f0f0f0 12px); }
.semana-apagada-txt { color: var(--color-muted); font-size: 0.72rem; font-style: italic; }

/* Contenedor con scroll para las tablas anchas (matriz ILUO, semana). La clase
   `.matriz-scroll` se usaba en la vista desde el principio pero NO tenia
   estilos: parecia un contenedor con scroll y no lo era, asi que la tabla
   empujaba la pagina entera (visto el 2026-09-22 al añadir la de ETT). */
.matriz-scroll { overflow-x: auto; }

/* Avisos: la campana de la cabecera y la bandeja. El contador solo existe
   cuando hay algo que contar -- una campana siempre a cero es ruido. */
.avisos-campana {
  position: relative; text-decoration: none; font-size: 1.1rem;
  padding: 0.1rem 0.3rem; border-radius: var(--radius); line-height: 1;
}
.avisos-campana:hover, .avisos-campana.active { background: var(--color-line); }
.avisos-cuenta {
  position: absolute; top: -0.25rem; right: -0.35rem;
  min-width: 1.05rem; padding: 0 0.25rem;
  background: var(--color-primary); color: var(--c-blanco);
  border-radius: 1rem; font-size: 0.65rem; font-weight: 700;
  text-align: center; line-height: 1.05rem;
}
/* La campana es un botón que despliega los últimos avisos (2026-09-30). */
button.avisos-campana { background: none; border: 0; cursor: pointer; color: inherit; }
.avisos-campana:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.avisos-menu { position: relative; }
.avisos-panel {
  position: absolute; right: 0; top: calc(100% + 0.4rem); z-index: 300;
  width: min(24rem, calc(100vw - 2rem)); max-height: 70vh; overflow-y: auto;
  background: var(--c-blanco); color: var(--color-fg);
  border: 1px solid var(--color-line); border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18); font-size: 0.85rem;
}
.avisos-panel[hidden] { display: none; }
.avisos-panel-cabecera {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--color-line);
  position: sticky; top: 0; background: var(--c-blanco);
}
.avisos-panel-todos, .aviso-mini-visto {
  background: none; border: 0; padding: 0.2rem 0.3rem; cursor: pointer;
  color: var(--color-primary); font: inherit; font-size: 0.8rem; text-decoration: underline;
}
.avisos-panel-vacio { margin: 0; padding: 0.9rem 0.8rem; color: var(--color-muted); }
.avisos-panel-lista { list-style: none; margin: 0; padding: 0; }
.aviso-mini { border-bottom: 1px solid var(--color-line); }
.aviso-mini-form { margin: 0; }
.aviso-mini-boton {
  display: flex; gap: 0.6rem; align-items: flex-start; width: 100%;
  padding: 0.6rem 0.8rem; background: none; border: 0; text-align: left;
  font: inherit; color: inherit; cursor: pointer;
}
.aviso-mini-sin-enlace { cursor: default; }
button.aviso-mini-boton:hover, button.aviso-mini-boton:focus-visible { background: #fff8e1; }
.aviso-mini-cuerpo { display: flex; flex-direction: column; gap: 0.15rem; flex: 1; min-width: 0; }
.aviso-mini-titulo { font-weight: 700; }
.aviso-mini-texto { color: var(--color-fg); overflow-wrap: anywhere; }
.aviso-mini-pie { color: var(--color-muted); font-size: 0.75rem; }
/* Lo leído se aparta: sin negrita y más claro. */
.aviso-mini.aviso-leido .aviso-mini-titulo { font-weight: 400; }
.aviso-mini.aviso-leido { opacity: 0.7; }
.avisos-panel-pie { padding: 0.5rem 0.8rem; text-align: right; }
/* En un móvil el panel ocupa el ancho de la pantalla, bajo la cabecera. */
@media (max-width: 600px) {
  .avisos-panel { position: fixed; left: 1rem; right: 1rem; top: 3.5rem; width: auto; }
}
/* Solo para lectores de pantalla. */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.avisos-acciones { margin: 0.8rem 0; }
.avisos-lista { display: flex; flex-direction: column; gap: 0.5rem; }
.aviso {
  display: flex; align-items: flex-start; gap: 0.7rem;
  background: var(--c-blanco); border: 1px solid var(--color-line);
  border-left: 3px solid var(--color-primary);
  border-radius: var(--radius); padding: 0.7rem 0.9rem;
}
/* Leido: sigue estando, pero deja de pedir atencion. */
.aviso-leido { border-left-color: var(--color-line); opacity: 0.62; }
.aviso-icono { font-size: 1.1rem; line-height: 1.4; }
.aviso-cuerpo { flex: 1; min-width: 0; }
.aviso-titulo { font-weight: 700; font-size: 0.9rem; }
.aviso-texto { font-size: 0.85rem; margin-top: 0.15rem; }
.aviso-pie {
  font-size: 0.75rem; color: var(--color-muted); margin-top: 0.3rem;
  display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap;
}
.aviso-acciones { display: flex; align-items: center; gap: 0.35rem; }

/* Calendario de produccion (/configuracion/calendario). El año se recorre con
   dos flechas: un selector de 12 meses seria mas ruido que utilidad para una
   pantalla que se abre dos veces al año. */
.cal-anios {
  display: flex; align-items: center; gap: 0.8rem; margin: 0.8rem 0 1rem;
}
.cal-anio-actual { font-size: 1.2rem; }
.cal-form { display: flex; flex-direction: column; gap: 0.8rem; }
.cal-form-grid {
  display: grid; gap: 0.8rem;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}
.cal-form label { display: flex; flex-direction: column; gap: 0.25rem;
                  font-size: 0.85rem; font-weight: 600; }
.cal-form input[type="date"], .cal-form input[type="text"], .cal-form select {
  font-weight: 400;
}
.cal-opcional { font-weight: 400; color: var(--color-muted); }
.cal-pico {
  border: 1px solid var(--color-line); border-radius: var(--radius);
  padding: 0.8rem; display: flex; flex-direction: column; gap: 0.6rem;
}
/* `display: flex` de arriba gana al estilo del navegador para [hidden], asi que
   el bloque salia siempre. Hay que decirlo a mano. */
.cal-pico[hidden] { display: none; }
.cal-pico legend { font-size: 0.8rem; color: var(--color-muted); font-weight: 600; }
.cal-checks { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; }
.cal-checks-titulo { font-size: 0.8rem; font-weight: 600; min-width: 4rem; }
.cal-check { display: flex; align-items: center; gap: 0.3rem; font-size: 0.85rem; }
.cal-ayuda { color: var(--color-muted); font-size: 0.8rem; margin: 0; }
.cal-sembrar { margin: 1rem 0; }
.cal-detalle { color: var(--color-muted); font-size: 0.82rem; }

/* Que se trabaja hoy cuando no es lo de siempre: finde, festivo o pico. Solo
   sale en esos dias -- en uno normal estorbaria los 250 dias del ano. */
.dia-produccion {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  border: 1px solid var(--color-line); border-radius: var(--radius);
  padding: 0.5rem 0.8rem; margin: -0.4rem 0 0.8rem; font-size: 0.85rem;
  background: var(--color-bg);
}
.dia-produccion-pico {
  border-color: var(--c-naranja, #DE5014);
  background: rgba(222, 80, 20, 0.06);
}
.dia-produccion-que { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.dia-produccion-nombre { font-style: italic; }
.dia-produccion-detalle { color: var(--color-muted); }
.dia-produccion-alta summary { cursor: pointer; display: inline-block; list-style: none; }
.dia-produccion-alta summary::-webkit-details-marker { display: none; }
.dia-produccion-form {
  margin-top: 0.6rem; padding: 0.6rem; border: 1px solid var(--color-line);
  border-radius: var(--radius); background: var(--c-blanco);
  display: flex; flex-direction: column; gap: 0.5rem; min-width: 18rem;
}
.dia-produccion-form fieldset {
  border: none; padding: 0; margin: 0; display: flex; gap: 0.7rem; flex-wrap: wrap;
}
.dia-produccion-form legend {
  font-size: 0.78rem; color: var(--color-muted); font-weight: 600; padding: 0;
}
.dia-produccion-check { display: flex; align-items: center; gap: 0.3rem; }
.dia-produccion-ayuda { color: var(--color-muted); font-size: 0.78rem; margin: 0; }
/* Dentro del grupo de casillas la ayuda va SOLA en su linea: si comparte fila
   se lee como la etiqueta de la ultima zona marcada. */
.dia-produccion-form fieldset .dia-produccion-ayuda { flex: 1 0 100%; }

/* La ayuda del bloque "hoy no les toca" del modal: explica que el boton no es
   un atajo, es una decision acordada. */
.modal-excluded-ayuda {
  margin: 0.3rem 0 0.6rem; font-size: 0.78rem; color: var(--color-muted);
}
/* Lo accionable del bloque, en el propio resumen: es el dato por el que RRHH lo
   abre. */
.modal-excluded-saltables {
  margin-left: 0.5rem; font-size: 0.78rem; font-weight: 600;
  color: var(--c-morado);
}
/* La tabla de excluidos lleva tres cosas anchas —nombre completo, motivo en
   cristiano y un boton de dos palabras—, asi que no vale el reparto de la lista
   de candidatos: con la accion en 90px el boton se parte en dos lineas y los
   nombres largos en tres. */
.modal-excluded .cand-action { width: auto; white-space: nowrap; }
.modal-excluded .cand-name { width: 40%; }
.modal-excluded .cand-meta { white-space: normal; }
/* Lo accionable primero y con su color: las filas sin boton son informacion. */
.modal-excluded tbody tr:has(button) .cand-name { color: var(--color-text); }

/* Estado de la plantilla del dia: en borrador la maquina la rehace sola; una
   vez cerrada, no. Va pegado a la cabecera y en una sola linea, porque es
   contexto permanente y no un aviso: si ocupa como una tarjeta, estorba. */
.estado-plantilla {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding: 0.5rem 0.8rem; border-radius: var(--radius);
  margin: -0.4rem 0 0.8rem; font-size: 0.85rem;
}
.estado-plantilla-info {
  display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
}
.estado-plantilla-detalle { color: var(--color-muted); }
.estado-plantilla-conformes {
  display: flex; align-items: center; gap: 0.6rem;
  padding-left: 0.6rem; border-left: 1px solid var(--color-line);
}
.estado-plantilla-acciones { display: flex; align-items: center; gap: 0.4rem; }
/* En pantalla pequena el estado manda mas que los botones: primero se lee en
   que punto esta y luego se actua. */
@media (max-width: 640px) {
  .estado-plantilla { flex-direction: column; align-items: stretch; }
  .estado-plantilla-conformes { padding-left: 0; border-left: none; }
}

.day-nav { display: flex; align-items: center; gap: 0.5rem; font-size: 1rem;
           flex-wrap: wrap; }
.day-nav button {
  background: var(--c-blanco); border: 1px solid var(--color-line);
  border-radius: 4px; padding: 0.4rem 0.7rem; cursor: pointer;
  color: var(--color-fg); font-family: var(--font-body);
}
.day-nav button:hover { background: var(--color-bg); border-color: var(--color-primary); }
.turno-selector {
  display: flex; gap: 0.25rem; margin-left: auto;
  background: var(--color-bg); padding: 0.2rem; border-radius: 4px;
}
/* Al envolver, el `margin-left: auto` dejaba el selector solo y pegado a la
   derecha en su propia linea. En pantalla estrecha va donde caiga. */
@media (max-width: 640px) {
  .turno-selector { margin-left: 0; }
}
.turno-selector a {
  padding: 0.4rem 0.8rem; border-radius: 3px;
  color: var(--color-muted); font-weight: 600;
}
.turno-selector a.active {
  background: var(--color-primary); color: white;
  box-shadow: var(--shadow);
}
.turno-selector a:hover { text-decoration: none; }

/* Banner de zona */
.zone-banner {
  padding: 0.7rem 1rem; margin: 1.75rem 0 0.75rem;
  font-weight: 700; font-size: 0.9rem;
  letter-spacing: 0.5px; text-transform: uppercase;
  border-radius: var(--radius);
}
.zone-envasado { background: var(--color-zona-envasado); color: #4a2e6b; }
.zone-expediciones { background: #fde4d3; color: #8a3410; }
.zone-pa { background: var(--color-zona-pa); color: #2d5a1e; }
/* Una zona que no es del supervisor: la ve, no la toca (Pablo, 2026-09-30). */
.zona-solo-ver {
  margin-left: 0.6rem; padding: 0.1rem 0.5rem; border-radius: 999px;
  background: rgba(255, 255, 255, 0.7); font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0; text-transform: none; vertical-align: middle;
}

/* Admin · Zonas del supervisor: una casilla por zona, en rejilla. */
.zonas-supervisor-lista {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0.35rem 0.75rem; margin: 0.6rem 0; padding: 0; border: 0;
}
.zonas-supervisor-lista label { display: flex; align-items: center; gap: 0.4rem; }
.zonas-supervisor-nota { color: var(--color-muted); font-size: 0.8rem; }

/* Grid de puestos */
.positions-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.75rem;
}
.position-card {
  background: var(--c-blanco); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 0.75rem; font-size: 0.85rem;
  border-left: 3px solid transparent;
}
.position-card:hover { border-left-color: var(--color-primary); }
.position-card-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.5rem; padding-bottom: 0.4rem; border-bottom: 1px solid var(--color-line);
  margin-bottom: 0.5rem;
}
.position-name { font-weight: 700; color: var(--color-fg); }
.position-cupo {
  font-size: 0.75rem; color: var(--color-fg); font-weight: 600;
  background: var(--color-bg); padding: 0.15rem 0.5rem; border-radius: 10px;
}
.position-slots { display: flex; flex-direction: column; gap: 0.2rem; }
.slot { display: flex; align-items: center; gap: 0.4rem; padding: 0.25rem 0;
        border-bottom: 1px dashed transparent; }
.slot:not(:last-child) { border-bottom-color: var(--color-line); }
.slot-filled .slot-icon { color: var(--c-amarillo); font-size: 0.8rem; }
.slot-encargado {
  background: rgba(166, 129, 85, 0.10);
  border-left: 3px solid var(--c-marron-tierra);
  padding-left: 0.4rem;
}
.slot-encargado .slot-icon { color: var(--c-marron-tierra); font-size: 0.9rem; }
.slot-encargado .slot-worker { font-weight: 700; }
.badge-encargado {
  background: rgba(166, 129, 85, 0.22); color: var(--c-marron-tierra);
  font-size: 0.6rem; font-weight: 700;
}
.slot-empty .slot-icon { color: var(--color-primary); }
.slot-empty { color: var(--color-muted); }
.slot-worker { font-weight: 600; color: var(--color-fg); flex: 1; }
.slot-action-del {
  background: transparent; border: 1px solid var(--color-line);
  color: var(--color-danger); font-size: 0.85rem; cursor: pointer;
  padding: 0.05rem 0.4rem; border-radius: 3px; line-height: 1;
}
.slot-action-del:hover { background: var(--color-danger); color: white; border-color: var(--color-danger); }
/* Quitando a alguien con el ✕: la fila se apaga en cuanto se acepta la
   confirmación, sin esperar a la respuesta. Antes no cambiaba nada durante el
   rato que tarda y parecía que el botón no había hecho caso (Pablo 2026-09-24).
   htmx pone y quita la clase; si falla, la fila vuelve tal cual y sale el aviso. */
.slot.htmx-request,
.line-slot-worker.htmx-request,
.line-slot-worker-standalone.htmx-request {
  opacity: 0.4; text-decoration: line-through; pointer-events: none;
  transition: opacity 0.12s ease-out;
}
.slot-action-add {
  background: transparent; border: 1px dashed var(--color-primary);
  color: var(--color-primary); cursor: pointer; flex: 1; text-align: left;
  padding: 0.2rem 0.5rem; border-radius: 4px; font-family: var(--font-body);
  font-size: 0.85rem;
}
.slot-action-add:hover { background: rgba(222, 80, 20, 0.08); }
/* Si no caben el botón y «No pedir ETT» en una fila, baja la casilla: partir el
   botón en dos renglones («Asignar / trabajador») se leía peor. */
.slot-empty { flex-wrap: wrap; }
.slot-empty .slot-action-add { white-space: nowrap; }
.slot-action-add-disabled { color: var(--color-muted); font-style: italic; flex: 1; }
.position-faltan {
  font-size: 0.7rem; color: var(--color-danger); margin-left: 0.4rem;
  font-weight: 700;
}
.position-sobran {
  font-size: 0.7rem; color: var(--color-success); margin-left: 0.4rem;
  font-weight: 700;
}
.slot-meta {
  font-size: 0.7rem; color: var(--color-muted); margin-left: auto;
  display: flex; gap: 0.25rem;
}
.badge {
  font-size: 0.65rem; padding: 0.1rem 0.45rem; border-radius: 8px;
  font-weight: 700;
}
.badge-ett { background: var(--c-salmon); color: var(--c-morado); }
.badge-formacion { background: rgba(255, 199, 44, 0.25); color: var(--c-marron-tierra); }
.badge-pe { background: rgba(222, 80, 20, 0.15); color: var(--color-primary); }
/* Vino estando en otro turno, de descanso o de vacaciones: acuerdo entre RRHH y
   el trabajador. No es un aviso -- es un dato que cualquiera tiene que ver al
   mirar la plantilla. Morado, que aqui es "decision humana" (igual que el
   dialogo de accion delicada). */
.badge-fuera-turno { background: rgba(93, 42, 92, 0.12); color: var(--c-morado); }
/* Es el badge mas largo que hay, y en una tarjeta estrecha se comia el nombre
   («ADRIAN / GABRIEL / ROSU», tres lineas). Cuando aparece, el nombre se queda
   con la fila entera y el badge baja debajo. Solo en esa fila: el resto de
   tarjetas no se toca. */
.slot:has(.badge-fuera-turno) { flex-wrap: wrap; }
.slot:has(.badge-fuera-turno) .slot-worker { flex: 1 1 60%; }
.badge-success { background: rgba(92, 138, 62, 0.18); color: var(--color-success); }
.badge-muted   { background: var(--color-line); color: var(--color-muted); }
/* Config que no cuadra y hay que mirar: no es un error, pero deja al plan sin
   poder hacer su trabajo (p. ej. un puesto con menos plazas que gente). */
.badge-aviso { background: #fff3cd; color: #7a5b00; cursor: help; }
/* Asignado pero AUSENTE hoy según Bizneo (ausencia posterior a materializar) */
.badge-ausente { background: rgba(198, 40, 40, 0.15); color: #c62828; cursor: help; }

/* ---------- TABLA DE DATOS (admin / PRL) ---------- */
.table-data {
  width: 100%; border-collapse: collapse; font-size: 0.85rem;
  background: var(--c-blanco); border-radius: var(--radius); overflow: hidden;
  margin-top: 0.5rem;
}
.table-data th, .table-data td {
  padding: 0.5rem 0.7rem; border-bottom: 1px solid var(--color-line);
  text-align: left; vertical-align: top;
}
.table-data thead th {
  background: var(--color-bg); color: var(--color-fg);
  font-size: 0.75rem; text-transform: uppercase; font-weight: 700;
  letter-spacing: 0.02em;
}
.table-data tbody tr:last-child td { border-bottom: 0; }
.table-data tbody tr:hover { background: rgba(255, 199, 44, 0.08); }

/* ---------- FORM DE FORMACIONES ---------- */
.formaciones-form-grid {
  display: grid;
  grid-template-columns: minmax(180px, 2fr) 80px 80px 100px;
  gap: 0.6rem 0.8rem;
  align-items: end;
  margin: 0.5rem 0;
}
.formaciones-form-grid label {
  display: flex; flex-direction: column; gap: 0.2rem;
  font-size: 0.78rem; color: var(--color-muted); font-weight: 500;
}
.formaciones-form-grid input[type="text"],
.formaciones-form-grid select {
  padding: 0.45rem 0.55rem; font-size: 0.9rem;
  border: 1px solid var(--color-line); border-radius: 4px;
  background: var(--color-bg); color: var(--color-fg);
  font-family: var(--font-body);
}
.formaciones-form-grid input:focus,
.formaciones-form-grid select:focus {
  outline: 2px solid var(--color-primary); outline-offset: -1px;
}
.formaciones-form-active {
  flex-direction: row !important; align-items: center; gap: 0.4rem !important;
  padding-bottom: 0.4rem; color: var(--color-fg) !important; font-size: 0.85rem !important;
}
.formaciones-form-desc {
  grid-column: 1 / -1;
}

/* ---------- FORM DE CUPOS ---------- */
/* El alta de usuarios tiene sus propias medidas: el correo y el nombre de la
   ficha son largos, y la rejilla de cupos -pensada para numeros de 110px- los
   estrangulaba. Tomar prestada una rejilla de otra pantalla sale barato hasta
   que el contenido no es el mismo. */
.usuarios-form-grid {
  display: grid;
  grid-template-columns: minmax(230px, 2fr) 150px minmax(220px, 2fr) minmax(150px, 1fr);
  gap: 0.6rem 0.8rem; align-items: start; margin: 0.5rem 0;
}
.usuarios-form-grid label {
  display: flex; flex-direction: column; gap: 0.2rem;
  font-size: 0.78rem; color: var(--color-muted); font-weight: 500;
}
.usuarios-form-grid input,
.usuarios-form-grid select {
  padding: 0.4rem 0.5rem; border: 1px solid var(--color-line);
  border-radius: 4px; font-family: var(--font-body); font-size: 0.9rem;
  color: var(--color-fg); background: var(--c-blanco); width: 100%;
}
.usuarios-form-grid small { font-size: 0.72rem; }
@media (max-width: 760px) {
  .usuarios-form-grid { grid-template-columns: 1fr; }
}

.cupos-form-grid {
  display: grid;
  grid-template-columns: minmax(180px, 2fr) 120px 110px 110px 160px;
  gap: 0.6rem 0.8rem; align-items: end; margin: 0.5rem 0;
}
.cupos-form-grid label {
  display: flex; flex-direction: column; gap: 0.2rem;
  font-size: 0.78rem; color: var(--color-muted); font-weight: 500;
}
.cupos-form-grid input[type="text"],
.cupos-form-grid input[type="number"],
.cupos-form-grid select {
  padding: 0.45rem 0.55rem; font-size: 0.9rem;
  border: 1px solid var(--color-line); border-radius: 4px;
  background: var(--color-bg); color: var(--color-fg);
  font-family: var(--font-body);
}
.cupos-form-auto-ett {
  flex-direction: row !important; align-items: center; gap: 0.4rem !important;
  padding-bottom: 0.5rem; color: var(--color-fg) !important; font-size: 0.85rem !important;
}

/* ETT a solicitar */
.ett-section {
  margin-top: 2rem; padding: 1rem;
  background: rgba(237, 163, 138, 0.2); border: 1px solid var(--c-salmon);
  border-radius: var(--radius);
}
.ett-section h3 { margin-top: 0; color: var(--c-morado); }
.ett-list { list-style: none; padding: 0; margin: 0; }
.ett-list li { padding: 0.4rem 0; border-bottom: 1px solid var(--c-salmon); }
.ett-list li:last-child { border-bottom: 0; }

/* ---------- MATRIZ TABLE ---------- */
.matriz-table {
  width: 100%; border-collapse: collapse; font-size: 0.8rem;
  background: var(--c-blanco); border-radius: var(--radius); overflow: hidden;
}
.matriz-table th, .matriz-table td {
  padding: 0.3rem 0.5rem; border: 1px solid var(--color-line);
  text-align: center; min-width: 32px;
}
.matriz-table thead th {
  background: var(--color-primary); color: white; font-size: 0.7rem;
  position: sticky; top: 0; font-weight: 700;
}
.matriz-table th.row-header, .matriz-table td.row-header {
  text-align: left; min-width: 180px; font-weight: 600;
  background: var(--color-bg);
}
/* Niveles ILUO — coherentes con paleta corporativa */
.lvl-O { background: var(--c-amarillo); color: var(--c-negro); font-weight: 800; }
.lvl-U { background: rgba(255, 199, 44, 0.55); color: var(--c-negro); font-weight: 700; }
.lvl-L { background: var(--c-salmon); color: var(--c-morado); font-weight: 600; }
.lvl-I { background: rgba(237, 163, 138, 0.4); color: var(--c-marron-tierra); }
/* Niveles inferidos del histórico (no certificados oficialmente) — patrón rayado */
.lvl-calc {
  background-image: repeating-linear-gradient(
    45deg, transparent, transparent 3px,
    rgba(255,255,255,0.4) 3px, rgba(255,255,255,0.4) 6px
  ) !important;
  opacity: 0.85;
}
.lvl-calc sup { font-size: 0.6em; }
.matriz-row-calc .row-header { font-style: italic; color: var(--color-muted); }
.badge-calc {
  background: rgba(115, 104, 142, 0.18); color: var(--c-lavanda);
  font-weight: 800; padding: 0 0.35rem; border-radius: 8px;
  margin-left: 0.2rem; font-size: 0.85rem;
}

/* ---------- 403 / errores ---------- */
.error-page {
  max-width: 480px; margin: 4rem auto; text-align: center;
  padding: 2.5rem; background: var(--c-blanco);
  border-radius: var(--radius); box-shadow: var(--shadow);
  border-top: 4px solid var(--color-primary);
}
.error-page .icon { font-size: 4rem; }
.error-page h1 { color: var(--c-morado); }

/* ---------- LOGIN ---------- */
.login-page {
  max-width: 420px; margin: 4rem auto; padding: 3rem 2.5rem;
  background: var(--c-blanco); border-radius: var(--radius); box-shadow: var(--shadow);
  text-align: center;
  border-top: 4px solid var(--color-primary);
}
.login-page h1 {
  margin: 0 0 0.25rem;
  font-size: 1.6rem;
}
.login-page .tagline {
  font-style: italic; color: var(--c-marron-tierra);
  margin-bottom: 1.25rem; font-size: 1rem;
}
.login-page p { color: var(--color-muted); margin: 0 0 2rem; }
.login-btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: var(--c-negro); color: white;
  padding: 0.85rem 1.75rem; border-radius: 4px;
  font-size: 0.95rem; font-weight: 600; text-decoration: none;
  transition: background .15s;
}
.login-btn:hover { background: var(--color-primary); text-decoration: none; }

/* ---------- LAYOUT JERARQUICO PLANTILLA (sección título + líneas) ---------- */
.section-title {
  margin: 1rem 0 0.4rem;
  font-size: 0.95rem; font-weight: 700; color: var(--c-marron-tierra);
  text-transform: uppercase; letter-spacing: 0.04em;
  border-bottom: 1px solid var(--color-line); padding-bottom: 0.25rem;
}
.lines-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.6rem;
}
/* Una LÍNEA es un puesto más (Pablo, 2026-09-28): la tarjeta tiene el aspecto
   de `.position-card` y dentro lleva sus mismas filas y botones (`.slot`,
   «Asignar trabajador», «No pedir ETT»). Antes tenía su propio dibujo, con el ✕
   cayendo debajo del nombre y sin forma de añadir a nadie con la línea llena. */
.line-card {
  background: var(--c-blanco); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 0.75rem; font-size: 0.85rem;
  border-left: 3px solid transparent;
  /* En columna, y lo del medio crece: las tarjetas de una fila miden lo mismo
     (la rejilla las estira) y «Cerrar línea N» queda al pie en todas, aunque en
     una el nombre ocupe dos renglones. */
  display: flex; flex-direction: column;
}
.line-card > .line-slots,
.line-card > .line-inactive-msg { flex: 1 0 auto; }
.line-card:hover { border-left-color: var(--color-primary); }
/* La de «sin línea asignada» (y la de la TV) sigue siendo un aviso aparte. */
.line-card-extra {
  background: rgba(255, 199, 44, 0.10);
  border: 1px dashed var(--color-line);
  display: flex; flex-direction: column; gap: 0.3rem;
}
.line-card-inactive {
  background: repeating-linear-gradient(
    45deg, transparent, transparent 6px,
    rgba(115, 104, 142, 0.06) 6px, rgba(115, 104, 142, 0.06) 12px
  );
  border-style: dashed; opacity: 0.75;
}
.line-card-inactive .line-name,
.line-card-inactive .position-name { color: var(--color-muted); }
.line-inactive-msg {
  font-size: 0.72rem; color: var(--color-muted);
  font-style: italic; padding: 0.4rem 0;
  text-align: center;
}
.slot-action-encargado {
  background: transparent; border: 1px solid var(--color-line);
  font-size: 0.85rem; cursor: pointer; line-height: 1;
  padding: 0.05rem 0.4rem; border-radius: 3px;
  filter: grayscale(1) opacity(0.45);
  transition: filter 0.12s, background 0.12s, border-color 0.12s;
}
.slot-action-encargado:hover {
  filter: none;
  background: rgba(166, 129, 85, 0.10);
  border-color: var(--c-marron-tierra);
}
.slot-action-encargado.is-encargado {
  filter: none;
  background: rgba(166, 129, 85, 0.18);
  border-color: var(--c-marron-tierra);
}
.slot-action-encargado.is-encargado:hover { background: rgba(166, 129, 85, 0.28); }

/* Fila de hueco pendiente (cupo > filled) sin botón asignar individual
   — el botón "+ Asignar trabajador" vive en el slot extra al final. */
.slot-hueco { flex: 1; align-items: center; }
.slot-hueco-label {
  flex: 1; font-size: 0.78rem;
  color: var(--color-muted); font-style: italic;
}
.slot-hueco .slot-icon { color: var(--color-muted); font-size: 0.85rem; }

/* Slot extra siempre visible al final del card. La raya de arriba ya la pone
   la fila anterior (`.slot:not(:last-child)`): con la suya salían dos. */
.slot-extra-add { padding-top: 0.35rem; }
.slot-extra-add:first-child { border-top: 1px dashed var(--color-line); }

/* Slot vacío desactivado por RRHH dentro de un position-card */
.slot-disabled {
  background: rgba(115, 104, 142, 0.06);
  border: 1px dashed rgba(115, 104, 142, 0.30) !important;
  border-radius: 4px;
}
.slot-add-btn-line {
  align-self: flex-start;
  background: transparent;
  border: 1px dashed var(--c-naranja);
  color: var(--c-naranja);
  font-size: 0.72rem; padding: 0.18rem 0.55rem;
  border-radius: 3px; cursor: pointer;
  margin-top: 0.15rem;
  font-family: inherit;
  transition: background 0.1s;
}
.slot-add-btn-line:hover {
  background: rgba(222, 80, 20, 0.08);
}
.slot-empty-actions {
  display: flex; align-items: center; gap: 0.5rem;
  flex-wrap: wrap; margin-top: 0.15rem;
}
.slot-sin-ett-form { margin: 0; display: inline-flex; }
.slot-sin-ett-toggle {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-size: 0.7rem; color: var(--color-muted);
  cursor: pointer; user-select: none;
  padding: 0.18rem 0.45rem;
  border: 1px solid var(--color-line); border-radius: 3px;
  background: var(--color-card-bg);
}
.slot-sin-ett-toggle:hover { background: var(--color-bg); }
.slot-sin-ett-toggle input[type="checkbox"] {
  margin: 0; accent-color: var(--c-morado);
}
.slot-sin-ett-pill {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-size: 0.7rem; color: var(--c-morado);
  background: rgba(115, 104, 142, 0.10);
  border: 1px solid rgba(115, 104, 142, 0.25);
  padding: 0.18rem 0.55rem; border-radius: 3px;
  font-style: italic;
}
.badge-inactive {
  background: var(--c-marron-tierra); color: white;
  font-size: 0.6rem; padding: 0.05rem 0.4rem; margin-left: 0.4rem;
  border-radius: 3px; vertical-align: middle;
}
/* «Cerrar línea N»: al pie de la tarjeta, discreto y con la letra del resto de
   botones. Antes era una caja gris con un ⏹ que llamaba más que el propio puesto. */
.line-toggle {
  margin: 0.5rem 0 0; padding-top: 0.4rem;
  border-top: 1px dashed var(--color-line);
  display: flex; justify-content: flex-end;
}
.line-toggle-btn {
  background: transparent; border: 1px solid var(--color-line);
  color: var(--color-muted); font-family: var(--font-body);
  font-size: 0.72rem; font-weight: 500;
  padding: 0.2rem 0.6rem; border-radius: 4px; cursor: pointer;
}
.line-toggle-btn.is-active:hover {
  border-color: var(--c-marron-tierra); color: var(--c-marron-tierra);
}
.line-toggle-btn.is-inactive {
  border-color: var(--c-amarillo); color: var(--c-negro);
  background: rgba(255, 199, 44, 0.15);
}
.line-toggle-btn.is-inactive:hover { background: rgba(255, 199, 44, 0.30); }

/* ---------- Cupo con sus flechas en la plantilla (2026-09-23) ----------
   Un campo numérico con las flechas del navegador, que se ven siempre: sin pasar
   el ratón por encima nadie sabría que el número se puede cambiar. El 24-sep
   hubo botones − / + a los lados y sobraban teniendo ya las flechas (Pablo). */
.cupo-stepper-form { display: inline-flex; margin: 0; vertical-align: middle; flex: 0 0 auto; }
.cupo-stepper {
  width: 2.9rem; height: 1.4rem; font: inherit; font-size: 0.8rem; font-weight: 700;
  line-height: 1; padding: 0 0.1rem 0 0.4rem;
  border: 1px solid var(--color-line); border-radius: 4px;
  background: var(--color-card-bg); color: var(--color-fg);
}
.cupo-stepper::-webkit-inner-spin-button,
.cupo-stepper::-webkit-outer-spin-button { opacity: 1; height: 1.2rem; }
.cupo-stepper:hover { border-color: var(--c-marron-tierra); }
.cupo-stepper:focus {
  outline: none; border-color: var(--c-marron-tierra);
  box-shadow: 0 0 0 2px rgba(255, 199, 44, 0.55);
}
.cupo-stepper-form.htmx-request .cupo-stepper { opacity: 0.55; }
.cupo-num { font-weight: 700; }

/* La pastilla «1 / − 1 +» no se parte nunca: si falta sitio, que se estreche el
   nombre del puesto, que ya sabe partirse. */
.position-cupo:has(.cupo-stepper-form),
.line-meta:has(.cupo-stepper-form) {
  display: inline-flex; align-items: center; gap: 0.3rem;
  white-space: nowrap; flex: 0 0 auto;
}
.position-cupo:has(.cupo-stepper-form) { padding: 0.1rem 0.15rem 0.1rem 0.45rem; }
.position-cupo:has(.cupo-stepper-form) .position-faltan,
.position-cupo:has(.cupo-stepper-form) .position-sobran,
.line-meta:has(.cupo-stepper-form) .position-faltan { margin-left: 0.1rem; }
.position-name { min-width: 0; }

/* El cupo del puesto en una sección de líneas: no es la suma de sus líneas. */
.grupo-cupo-puesto {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem 0.6rem;
  font-size: 0.75rem; color: var(--color-muted); margin: 0 0 0.45rem;
}
.grupo-cupo-aviso { color: var(--color-danger); font-weight: 600; }

/* ---------- Ocultos de una sección: cupo 0 y líneas cerradas hoy ---------- */
.grupo-ocultos {
  margin: 0.55rem 0 0.2rem;
  border: 1px dashed var(--color-line); border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.55);
}
.grupo-ocultos > summary {
  cursor: pointer; padding: 0.35rem 0.6rem;
  font-size: 0.78rem; color: var(--color-muted);
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem 0.6rem;
}
.grupo-ocultos > summary::before { content: '▸'; color: var(--c-marron-tierra); }
.grupo-ocultos[open] > summary::before { content: '▾'; }
.grupo-ocultos > summary::-webkit-details-marker { display: none; }
.grupo-ocultos > summary { list-style: none; }
.grupo-ocultos-titulo { font-weight: 700; color: var(--c-marron-tierra); }
.grupo-ocultos-que {
  font-size: 0.7rem; background: var(--color-bg);
  border-radius: 10px; padding: 0.05rem 0.5rem;
}
.grupo-ocultos-lista {
  list-style: none; margin: 0; padding: 0.15rem 0.6rem 0.5rem;
  display: grid; gap: 0.3rem 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
}
.oculto {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem;
  font-size: 0.78rem; padding: 0.3rem 0.1rem;
  border-bottom: 1px dotted var(--color-line);
}
.oculto-nombre { font-weight: 700; color: var(--color-fg); }
.oculto-que { color: var(--color-muted); font-size: 0.72rem; }
.oculto-accion { margin: 0 0 0 auto; }
.oculto-cerrada .oculto-que { color: var(--c-marron-tierra); }

/* ============================================================================
   Personal disponible / ausente (tras zona PA, antes de huecos/ETT).
============================================================================ */
.personal-grid {
  display: grid; gap: 0.8rem; margin: 1rem 0 0.8rem;
  grid-template-columns: 1fr 1fr;
}
@media (max-width: 900px) {
  .personal-grid { grid-template-columns: 1fr; }
}
.personal-section {
  background: var(--color-card-bg);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  padding: 0.7rem 0.95rem 0.8rem;
}
.personal-section h3 {
  margin: 0 0 0.2rem; font-size: 0.95rem;
  display: flex; align-items: center; gap: 0.4rem;
}
.personal-count { color: var(--color-muted); font-weight: 500; font-size: 0.85rem; }
.personal-section-help {
  font-size: 0.75rem; color: var(--color-muted);
  margin: 0 0 0.5rem; line-height: 1.4;
}
.personal-section-available { border-top: 3px solid var(--c-amarillo); }
.personal-section-absent    { border-top: 3px solid var(--c-marron-tierra); }
.personal-empty {
  font-size: 0.8rem; color: var(--color-muted);
  font-style: italic; margin: 0.3rem 0;
}
.personal-table {
  width: 100%; border-collapse: collapse;
  font-size: 0.8rem;
  max-height: 320px; display: block; overflow-y: auto;
}
.personal-table thead {
  position: sticky; top: 0; background: var(--color-bg);
  z-index: 1;
}
.personal-table th {
  text-align: left; font-weight: 600;
  color: var(--color-muted); font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.04em;
  padding: 0.3rem 0.5rem;
  border-bottom: 1px solid var(--color-line);
}
.personal-table td {
  padding: 0.3rem 0.5rem;
  border-bottom: 1px dashed var(--color-line);
  vertical-align: top;
}
.personal-table tr:last-child td { border-bottom: 0; }
.personal-table tbody tr:hover { background: rgba(255, 199, 44, 0.06); }
.personal-table .personal-name {
  font-weight: 600; color: var(--color-fg);
  white-space: nowrap;
}
.personal-table .personal-puesto {
  font-size: 0.74rem; color: var(--color-muted);
}
.personal-table .personal-schedule {
  font-size: 0.74rem; color: var(--c-marron-tierra);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.personal-table .personal-reason {
  font-size: 0.7rem; color: var(--c-marron-tierra);
  white-space: nowrap;
}

/* Personal ausente — lista expandible: motivo + periodo visibles; puesto y
   resto del detalle dentro del desplegable (click en el trabajador). */
.absent-list {
  max-height: 320px; overflow-y: auto;
  display: flex; flex-direction: column;
}
.absent-item { border-bottom: 1px dashed var(--color-line); }
.absent-item:last-child { border-bottom: 0; }
.absent-item[open] { background: rgba(166, 129, 85, 0.07); }
.absent-summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: baseline; gap: 0.45rem;
  padding: 0.35rem 0.45rem; font-size: 0.8rem;
}
.absent-summary::-webkit-details-marker { display: none; }
.absent-summary:hover { background: rgba(255, 199, 44, 0.06); }
.absent-caret {
  color: var(--color-muted); font-size: 0.65rem;
  transition: transform 0.12s ease; flex: none;
}
.absent-item[open] .absent-caret { transform: rotate(90deg); }
.absent-name { font-weight: 600; color: var(--color-fg); }
.absent-motivo {
  font-size: 0.68rem; color: var(--c-marron-tierra);
  background: rgba(166, 129, 85, 0.13);
  border-radius: 999px; padding: 0.05rem 0.5rem;
  white-space: nowrap;
}
.absent-fechas {
  margin-left: auto; font-size: 0.72rem; color: var(--color-muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.absent-detail { padding: 0.05rem 0.45rem 0.5rem 1.35rem; }
.absent-dl {
  margin: 0; display: grid; grid-template-columns: auto 1fr;
  gap: 0.12rem 0.7rem; font-size: 0.74rem;
}
.absent-dl dt { color: var(--color-muted); white-space: nowrap; }
.absent-dl dd { margin: 0; color: var(--color-fg); }

/* ============================================================================
   UI DIALOGS (uiConfirm / uiAlert / uiPrompt y htmx:confirm intercept).
   Regla del proyecto: prohibido usar alert/confirm/prompt nativos del
   navegador sin pasar por aquí. Decisión usuario 2026-05-14.
============================================================================ */
.ui-dialog-backdrop {
  position: fixed; inset: 0; background: rgba(34, 34, 33, 0.55);
  display: flex; align-items: center; justify-content: center;
  z-index: 2000; padding: 1rem;
  animation: ui-dialog-fade-in 0.12s ease-out;
  backdrop-filter: blur(2px);
}
@keyframes ui-dialog-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.ui-dialog {
  background: var(--color-card-bg);
  border-radius: var(--radius);
  box-shadow: 0 14px 36px rgba(34, 34, 33, 0.25);
  border-top: 4px solid var(--c-amarillo);
  max-width: 460px; width: 100%;
  padding: 1.1rem 1.4rem 1rem;
  animation: ui-dialog-pop 0.14s ease-out;
}
@keyframes ui-dialog-pop {
  from { transform: scale(0.96); opacity: 0; }
  to   { transform: scale(1);    opacity: 1; }
}
.ui-dialog-header {
  border-bottom: 1px solid var(--color-line);
  padding-bottom: 0.5rem; margin-bottom: 0.65rem;
}
.ui-dialog-header h3 {
  margin: 0; font-size: 1.02rem;
  color: var(--color-fg); font-weight: 700;
}
.ui-dialog-body {
  font-size: 0.9rem; color: var(--color-fg);
  line-height: 1.5; padding: 0.1rem 0 0.65rem;
}
.ui-dialog-input {
  width: 100%; padding: 0.5rem 0.7rem;
  border: 1px solid var(--color-line); border-radius: 4px;
  font-size: 0.9rem; background: var(--color-bg);
  color: var(--color-fg); margin-bottom: 0.7rem;
}
.ui-dialog-input:focus {
  outline: 2px solid var(--c-amarillo); outline-offset: -1px;
}
.ui-dialog-actions {
  display: flex; justify-content: flex-end; gap: 0.5rem;
  padding-top: 0.4rem;
}
.ui-dialog-btn {
  padding: 0.45rem 1.05rem; font-size: 0.85rem; border-radius: 4px;
  cursor: pointer; border: 1px solid var(--color-line);
  background: var(--color-card-bg); color: var(--color-fg);
  font-family: inherit; transition: background 0.1s, border-color 0.1s;
}
.ui-dialog-btn:focus { outline: 2px solid var(--c-amarillo); outline-offset: 1px; }
.ui-dialog-btn-cancel:hover { background: var(--color-bg); }
.ui-dialog-btn-primary {
  background: var(--c-naranja); color: white;
  border-color: var(--c-naranja); font-weight: 600;
}
.ui-dialog-btn-primary:hover { filter: brightness(0.95); }
.ui-dialog-btn-danger {
  background: var(--c-morado); color: white;
  border-color: var(--c-morado); font-weight: 600;
}
.ui-dialog-btn-danger:hover { filter: brightness(0.92); }
.line-card-header {
  display: flex; justify-content: space-between; align-items: center;
  border-bottom: 1px solid var(--color-line); padding-bottom: 0.3rem;
}
.line-name {
  font-weight: 700; color: var(--color-fg); font-size: 0.85rem;
  letter-spacing: 0.02em;
}
.line-meta {
  font-size: 0.7rem; color: var(--color-muted);
}
.line-slots { display: flex; flex-direction: column; gap: 0.25rem; }
.line-slot {
  display: grid; grid-template-columns: 56px 1fr;
  gap: 0.4rem; align-items: start;
  padding: 0.15rem 0;
}
.line-slot:not(:last-child) { border-bottom: 1px dashed var(--color-line); }
.line-slot-name {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.72rem; color: var(--color-muted); font-weight: 600;
  padding-top: 0.15rem;
}
.line-slot-workers { display: flex; flex-direction: column; gap: 0.2rem; }
/* Con un solo hueco no se escribe su número (la tarjeta ya dice qué línea es),
   y lo de dentro caía en la columna de 56 px pensada para ese número: «No pedir
   ETT» y «+ Asignar trabajador» salían partidos en tres renglones. */
.line-slot > .line-slot-workers:first-child { grid-column: 1 / -1; }
.line-slot-worker, .line-slot-worker-standalone {
  font-size: 0.82rem; color: var(--color-fg); font-weight: 500;
  display: inline-flex; gap: 0.3rem; align-items: center; flex-wrap: wrap;
}
.line-slot-sched {
  font-size: 0.7rem; color: var(--color-muted); font-style: italic;
}
/* Su horario de Bizneo no es el normal del turno: es lo que RRHH quiere ver. */
.slot-horario-distinto {
  font-style: normal; font-weight: 700; color: var(--c-naranja);
}
/* De paso: su jornada empieza en OTRO turno y aqui esta media (el 4ºT el sabado
   por la tarde). Se ve, pero no como quien cubre el turno -- porque no lo
   cubre, y el cupo tampoco le cuenta aqui. */
.slot-de-paso {
  font-style: normal; font-weight: 600;
  background: rgba(93, 42, 92, 0.1); color: var(--c-morado);
  border-radius: 0.6rem; padding: 0.05rem 0.4rem;
}
/* Cambia de puesto durante el turno (2026-09-30): «hasta 11:00» en el puesto
   de donde sale, «desde 11:00» en el que entra. Discreto, junto al nombre. */
.slot-tramo {
  font-size: 0.7rem; font-weight: 600; color: var(--c-marron-tierra);
  border: 1px solid currentColor; border-radius: 0.6rem; padding: 0 0.35rem;
  white-space: nowrap;
}
/* La etiqueta de horario es ancha y en una tarjeta estrecha parte el nombre en
   cuatro lineas («ALBA / MARIA / MORALES / CAMPOS»). El nombre se queda con la
   fila y la etiqueta baja debajo -- mismo trato que el badge de fuera de turno. */
.slot:has(.slot-de-paso) { flex-wrap: wrap; }
.slot:has(.slot-de-paso) .slot-worker { font-weight: 400; flex: 1 1 60%; }
.slot:has(.slot-de-paso) .slot-icon { opacity: 0.45; }
/* Lo mismo cuando lleva su jornada completa (donde empieza): tambien es larga. */
.slot:has(.line-slot-sched) { flex-wrap: wrap; }
.slot:has(.line-slot-sched) .slot-worker { flex: 1 1 60%; }

/* ---------- MODAL DE RECOMENDACIÓN ---------- */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(34, 34, 33, 0.4);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000; padding: 1rem;
}
.modal {
  background: var(--color-card-bg); border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(34, 34, 33, 0.18);
  max-width: 640px; width: 100%; max-height: 80vh; overflow-y: auto;
  padding: 1.25rem 1.5rem;
}
.modal-header {
  display: flex; justify-content: space-between; align-items: center;
  border-bottom: 1px solid var(--color-line); padding-bottom: 0.5rem; margin-bottom: 0.3rem;
}
.modal-header h3 { margin: 0; font-size: 1.05rem; color: var(--color-fg); }
.modal-close {
  background: transparent; border: 0; cursor: pointer;
  font-size: 1.1rem; color: var(--color-muted);
}
.modal-close:hover { color: var(--color-fg); }
.modal-subtitle { color: var(--color-muted); font-size: 0.85rem; margin: 0 0 0.4rem; }
.modal-note {
  font-size: 0.75rem; color: var(--c-marron-tierra);
  background: rgba(166, 129, 85, 0.08);
  padding: 0.4rem 0.6rem; border-radius: 4px;
  border-left: 3px solid var(--c-marron-tierra);
  margin: 0 0 0.75rem;
}
.modal-body { margin-top: 0.5rem; }

/* Modal de asignación: variante ancha + buscador + grupos por nivel ILUO */
.modal-wide { max-width: 760px; }
.modal-search {
  position: sticky; top: 0; background: var(--color-card-bg);
  padding: 0.4rem 0 0.6rem; z-index: 2;
  border-bottom: 1px solid var(--color-line);
}
.modal-search input[type="search"] {
  width: 100%; padding: 0.45rem 0.7rem;
  border: 1px solid var(--color-line); border-radius: 4px;
  font-size: 0.9rem; background: var(--color-bg);
}
.modal-search input[type="search"]:focus {
  outline: 2px solid var(--c-amarillo); outline-offset: -1px;
}
.cand-group { margin: 0.6rem 0 0.9rem; }
.cand-group-title {
  display: inline-block; margin: 0 0 0.15rem;
  padding: 0.15rem 0.55rem; border-radius: 3px;
  font-size: 0.85rem;
}
.cand-group-title.lvl-none {
  background: rgba(115, 104, 142, 0.12);
  color: var(--color-muted);
  font-style: italic;
}
.cand-group-count { font-weight: 500; opacity: 0.7; margin-left: 0.3rem; }
.cand-group-desc {
  margin: 0 0 0.35rem; font-size: 0.75rem;
  color: var(--color-muted);
}
.table-compact th, .table-compact td { padding: 0.3rem 0.5rem; font-size: 0.85rem; }
.cand-name { width: 50%; }
.cand-meta { font-size: 0.75rem; color: var(--color-muted); white-space: nowrap; }
/* Afinidad de línea: qué líneas ha trabajado el candidato (días en histórico).
   La línea del hueco se resalta en naranja corporativo. */
.cand-lineas { margin-top: 0.25rem; display: flex; flex-wrap: wrap; gap: 0.2rem; white-space: normal; }
.cand-linea {
  display: inline-block; padding: 0.05rem 0.35rem; border-radius: 0.5rem;
  font-size: 0.68rem; font-weight: 600; line-height: 1.4;
  background: rgba(166,129,85,0.12); color: var(--color-accent);
}
.cand-linea-match { background: var(--color-primary); color: #fff; }
.cand-linea-none { font-size: 0.68rem; font-style: italic; color: var(--color-muted); }
.cand-action { width: 90px; text-align: right; }
.btn-sm { padding: 0.3rem 0.7rem; font-size: 0.78rem; }
.modal-excluded {
  margin-top: 0.8rem; padding-top: 0.6rem;
  border-top: 1px dashed var(--color-line);
  font-size: 0.82rem; color: var(--color-muted);
}
.modal-excluded summary { cursor: pointer; }

/* ---------- RESPONSIVE ---------- */
@media (max-width: 700px) {
  .topbar { flex-wrap: wrap; padding: 0.5rem 0.75rem; }
  .nav { order: 3; width: 100%; margin: 0.5rem 0 0; gap: 0.5rem; overflow-x: auto; }
  .user { font-size: 0.8rem; }
  .content { padding: 0 0.75rem; }
}

/* ============================================================================
   PANTALLAS DE LA FÁBRICA (/tv/<token>)
   Una tablet de 10" (1280×800 en horizontal, 800×1280 en vertical) o una TV,
   mirada a un metro y sin tocarla: nada de scroll. Todas las zonas van en UN
   flujo de columnas (.tv-flow) y todo lo de dentro mide en `em` de su letra,
   `--tv-letra`, que pone app/js/tv.js: la más grande con la que cabe entero,
   sin bajar de 16 px; si ni así cabe, pasa por páginas cada 15 s.
   Reusa _position_card y _line_card con canEdit=false.
============================================================================ */
body.tv-mode {
  height: 100vh;
  height: 100dvh;
  margin: 0;
  overflow: hidden;
  background: var(--color-bg);
  display: flex;
  flex-direction: column;
}

/* ---- Cabecera: marca y pantalla · turno y horario · reloj y página ---- */
.tv-header {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.75rem;
  padding: 0.3rem 0.9rem 0.4rem;
  background: var(--c-blanco);
  border-bottom: 3px solid var(--c-amarillo);
}
.tv-brand { display: flex; align-items: center; gap: 0.45rem; min-width: 0; }
.tv-brand-emoji { font-size: 1.7rem; line-height: 1; }
.tv-brand-texto { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }
.tv-brand-nombre { font-weight: 700; font-size: 1rem; color: var(--color-fg); }
.tv-pantalla {
  font-size: 0.9rem; color: var(--c-marron-tierra); font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tv-turno { text-align: center; line-height: 1.05; }
.tv-turno-label { font-size: 2rem; font-weight: 800; letter-spacing: 2px; }
.tv-turno-manana { color: #c89500; }
.tv-turno-tarde  { color: var(--color-primary); }
.tv-turno-noche  { color: var(--c-lavanda); }
.tv-turno-sub {
  font-size: 1.1rem; font-weight: 700; color: var(--color-fg);
  font-variant-numeric: tabular-nums;
}
.tv-clock { text-align: right; line-height: 1.15; min-width: 0; }
.tv-clock-time {
  font-size: 2rem; font-weight: 700; color: var(--color-fg);
  font-variant-numeric: tabular-nums; line-height: 1;
}
.tv-clock-date { font-size: 0.9rem; color: var(--color-muted); }
.tv-clock-date::first-letter { text-transform: uppercase; }
.tv-pagina {
  font-size: 0.85rem; font-weight: 700; color: var(--color-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tv-pagina:empty { display: none; }
/* Lo que falta para pasar de página, en el filo de la cabecera. */
.tv-progreso {
  position: absolute; left: 0; right: 0; bottom: -3px; height: 3px;
  background: var(--color-primary);
  transform-origin: left center; transform: scaleX(0);
  visibility: hidden;
}
.tv-paginada .tv-progreso { visibility: visible; }

/* ---- El flujo de columnas ---- */
.tv-content {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.tv-flow {
  position: absolute;
  inset: 0.5rem 0.6rem;
  overflow: hidden;
  font-size: var(--tv-letra, 18px);
  line-height: 1.2;
  /* Alto fijo y `auto`: lo que no cabe sigue en columnas a la derecha, que es
     lo que tv.js mide y por donde pasa de página. */
  column-width: 15em;
  column-gap: 0.7em;
  column-fill: auto;
}
.tv-midiendo .tv-flow { visibility: hidden; }
.tv-mode .tv-fuera { display: none !important; }

.tv-mode .zone-banner {
  margin: 0 0 0.3em;
  padding: 0.2em 0.5em;
  font-size: 0.95em;
  border-radius: 4px;
  break-inside: avoid;
  break-after: avoid;
}
.tv-mode .tv-zone + .tv-zone .zone-banner { margin-top: 0.6em; }
.tv-mode .section-title {
  margin: 0.45em 0 0.2em;
  padding-bottom: 0.1em;
  font-size: 0.78em;
  break-inside: avoid;
  break-after: avoid;
}

/* ---- Tarjetas: que no se partan entre columnas ---- */
.tv-mode .position-card,
.tv-mode .line-card {
  display: block;
  break-inside: avoid;
  margin: 0 0 0.35em;
  padding: 0.25em 0.45em 0.2em;
  font-size: 1em;
  box-shadow: none;
  border: 1px solid var(--color-line);
  border-left: 3px solid var(--c-amarillo);
}
.tv-mode .position-card-header,
.tv-mode .line-card-header {
  flex-wrap: wrap;
  gap: 0 0.4em;
  padding-bottom: 0.1em;
  margin-bottom: 0.1em;
}
.tv-mode .position-name,
.tv-mode .line-name {
  font-size: 0.9em;
  line-height: 1.15;
  letter-spacing: 0.02em;
}
.tv-mode .position-cupo,
.tv-mode .line-meta {
  margin-left: auto;
  font-size: 0.75em;
  padding: 0.05em 0.4em;
  white-space: nowrap;
}
.tv-mode .position-faltan,
.tv-mode .position-sobran { font-size: 1em; margin-left: 0.3em; }

/* Filas: el nombre manda; lo demás, más pequeño y debajo si no cabe al lado. */
.tv-mode .position-slots,
.tv-mode .line-slots { gap: 0; }
.tv-mode .slot,
.tv-mode .line-slot-worker-standalone {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.3em;
  padding: 0.08em 0;
  font-size: 1em;
}
.tv-mode .slot:not(:last-child),
.tv-mode .line-slot-worker-standalone:not(:last-child) {
  border-bottom: 1px solid var(--color-line);
}
.tv-mode .slot-icon { font-size: 0.6em; flex: 0 0 auto; }
.tv-mode .slot-worker,
.tv-mode .line-slot-worker-name {
  font-size: 1em;
  font-weight: 600;
  line-height: 1.2;
  /* Base corta: un nombre largo se parte en su sitio, al lado del ●, en vez
     de bajar entero y dejar el ● solo en la fila de arriba. */
  flex: 1 1 9em;
  min-width: 0;
  overflow-wrap: anywhere;
}
.tv-mode .slot-encargado { padding-left: 0.3em; }
.tv-mode .slot-meta {
  font-size: 0.72em;
  margin-left: auto;
  gap: 0.25em;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.tv-mode .slot-meta > * { font-size: 1em; }
.tv-mode .line-slot-worker-standalone > .badge,
.tv-mode .line-slot-worker-standalone > .line-slot-sched { font-size: 0.72em; }
.tv-mode .badge { padding: 0.05em 0.4em; line-height: 1.2; }
.tv-mode .line-slot-sched { font-style: normal; font-weight: 600; color: var(--color-fg); }
.tv-mode .line-slot-sched.slot-horario-distinto { font-weight: 700; color: var(--c-naranja); }

/* Hueco sin nadie: «Sin asignar» en rojo, en vez del «Asignar...» de la
   plantilla. El texto original se esconde con font-size 0, así que el tamaño
   del nuevo sale de --tv-letra y no del em de su padre (que es 0). */
.tv-mode .slot-empty .slot-icon { color: var(--color-danger); }
.tv-mode .slot-empty .slot-action-add-disabled { font-size: 0; line-height: 0; flex: 1 1 auto; }
.tv-mode .slot-empty .slot-action-add-disabled::before {
  content: "Sin asignar";
  font-size: calc(var(--tv-letra, 18px) * 0.85);
  line-height: 1.2;
  color: var(--color-danger); font-style: normal; font-weight: 600;
}
.tv-mode .slot-sin-ett-pill { font-size: 0.75em; padding: 0.05em 0.45em; }
.tv-mode .line-inactive-msg { font-size: 0.75em; padding: 0.2em 0; }

/* Pantalla vacía */
.tv-empty {
  text-align: center; padding: 2em 1em;
  color: var(--color-muted); font-size: 1.2em;
  background: var(--c-blanco); border-radius: var(--radius);
}

/* En vertical la cabecera se aprieta: lo del medio (el turno) no se toca. */
@media (max-width: 820px) {
  .tv-header { gap: 0.5rem; padding: 0.3rem 0.6rem 0.4rem; }
  .tv-brand-emoji { display: none; }
  .tv-turno-label, .tv-clock-time { font-size: 1.7rem; }
}

/* ---- /admin/pantallas: la lista de pantallas y su enlace ---- */
.pantalla-nota { color: var(--color-muted); }
.pantalla-card { margin: 1rem 0; }
.pantalla-resaltada { border-top-color: var(--color-success); }
.pantalla-aviso {
  margin: 0; padding: 0.4rem 0.7rem; font-size: 0.85rem;
  background: #fff3cd; color: #7a5b00; border-radius: 4px;
}
.pantalla-enlace { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.pantalla-enlace input {
  flex: 1 1 22rem; min-width: 0; padding: 0.45rem 0.55rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.85rem;
  border: 1px solid var(--color-line); border-radius: 4px;
  background: var(--color-bg); color: var(--color-fg);
}
.pantalla-editar summary { cursor: pointer; font-size: 0.9rem; color: var(--color-primary); }
.pantalla-editar form { margin-top: 0.6rem; display: flex; flex-direction: column; gap: 0.6rem; }
.pantalla-card > form { display: flex; flex-direction: column; gap: 0.6rem; }
.pantalla-campo { display: flex; flex-direction: column; gap: 0.2rem; max-width: 26rem; }
.pantalla-campo span { font-size: 0.78rem; color: var(--color-muted); font-weight: 500; }
.pantalla-campo input {
  padding: 0.45rem 0.55rem; font-size: 0.9rem; font-family: var(--font-body);
  border: 1px solid var(--color-line); border-radius: 4px; background: var(--c-blanco);
}
.pantalla-zonas {
  margin: 0; padding: 0.5rem 0.8rem 0.7rem;
  border: 1px solid var(--color-line); border-radius: 4px;
}
.pantalla-zonas legend { font-size: 0.78rem; color: var(--color-muted); font-weight: 500; padding: 0 0.3rem; }
.pantalla-alcance { display: flex; align-items: baseline; gap: 0.4rem; font-size: 0.9rem; }
.pantalla-alcance small { color: var(--color-muted); }
.pantalla-zonas-casillas {
  display: flex; flex-wrap: wrap; gap: 0.3rem 1rem;
  margin: 0.3rem 0 0 1.5rem; font-size: 0.88rem;
}
.pantalla-zonas-casillas label { display: inline-flex; align-items: center; gap: 0.3rem; }

/* ===========================================================================
   Mover trabajadores arrastrando (app/js/plantilla-dnd.js)
   Sin retorno visual, arrastrar es adivinar: hay que ver QUE se coge, DONDE
   se puede soltar y que ha pasado al soltar.
   =========================================================================== */

/* Lo agarrable se nota al pasar por encima, pero sin gritar: la plantilla ya
   tiene mucha informacion y esto es un atajo, no la accion principal. */
[data-arrastrable="1"] {
  cursor: grab;
}
[data-arrastrable="1"]:active {
  cursor: grabbing;
}
.slot-filled[data-arrastrable="1"]:hover,
.line-slot-worker[data-arrastrable="1"]:hover,
.personal-table tr[data-arrastrable="1"]:hover {
  outline: 1px solid var(--color-line);
  outline-offset: 1px;
}

/* El que va en el aire se queda atenuado en su sitio de origen, para no perder
   de vista de donde salio. */
.dnd-origen {
  opacity: 0.4;
}

/* Mientras se arrastra, los sitios donde SI se puede soltar se insinuan. Solo
   entonces: en reposo seria ruido permanente. */
body.dnd-activo [data-soltar] {
  outline: 1px dashed var(--color-line);
  outline-offset: 2px;
}
body.dnd-activo [data-soltar].dnd-encima {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  background: color-mix(in srgb, var(--color-primary) 8%, transparent);
}
/* Soltar en "Personal disponible" quita del puesto: se avisa en rojo porque
   no es lo mismo que mover a otro sitio. */
body.dnd-activo [data-soltar="quitar"].dnd-encima {
  outline-color: var(--color-danger);
  background: color-mix(in srgb, var(--color-danger) 8%, transparent);
}
body.dnd-enviando {
  cursor: progress;
}

/* --- avisos breves (window.uiToast) --- */
#ui-toasts {
  position: fixed;
  bottom: 1rem;
  right: 1rem;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  pointer-events: none;
}
.ui-toast {
  background: var(--color-fg);
  color: var(--c-blanco);
  padding: 0.6rem 0.9rem;
  border-radius: 6px;
  font-size: 0.85rem;
  max-width: 22rem;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  border-left: 3px solid var(--color-success);
  animation: ui-toast-in 0.18s ease-out;
}
.ui-toast-error {
  border-left-color: var(--color-danger);
}
.ui-toast-out {
  opacity: 0;
  transition: opacity 0.25s ease-out;
}
@keyframes ui-toast-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ui-toast { animation: none; }
}

/* Franja para quitar del puesto arrastrando.
   En reposo se queda como una linea discreta: no molesta y ENSEÑA que el gesto
   existe, que si solo apareciera al arrastrar nadie lo descubriria. Al arrastrar
   crece y se pone en rojo. No se oculta con display:none a proposito: un destino
   que no existe hasta media accion no se puede soltar encima. */
.dnd-zona-quitar {
  margin: 0.4rem 0;
  /* Tamaño FIJO: si la franja creciera al empezar a arrastrar, movería el resto
     de la pagina justo cuando el usuario esta apuntando. Solo cambia el color. */
  min-height: 2.4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 0.78rem;
  color: var(--color-muted);
  border: 2px dashed var(--color-line);
  border-radius: 6px;
  transition: color 0.12s ease-out, border-color 0.12s ease-out,
              background 0.12s ease-out;
}
body.dnd-activo .dnd-zona-quitar {
  color: var(--color-danger);
  border-color: var(--color-danger);
  background: color-mix(in srgb, var(--color-danger) 5%, transparent);
}
body.dnd-activo .dnd-zona-quitar.dnd-encima {
  background: color-mix(in srgb, var(--color-danger) 14%, transparent);
  outline: none;
}
@media (prefers-reduced-motion: reduce) {
  .dnd-zona-quitar { transition: none; }
}

/* Tarjeta de aviso dentro de un grupo de líneas: gente que está en el puesto
   pero sin línea. No es un error, pero hay que resolverlo, así que se marca. */
.line-card-aviso {
  border: 2px dashed var(--color-warning);
}
.line-card-aviso-texto {
  margin: 0 0 0.5rem;
  padding: 0 0.6rem;
  font-size: 0.78rem;
  color: var(--color-muted);
}

/* ============================================================================
   «Personal disponible» anclado abajo (Pablo 2026-09-17: "un pincho para que se
   quede fijo en la parte de abajo y se pueda hacer el drag and drop desde
   cualquier sitio sin perder tiempo en el scroll").

   Se ancla SOLO la lista de disponibles, que es de lo unico que se arrastra. El
   panel de ausentes se queda donde estaba en la pagina (Pablo, 2026-09-17: "me
   oculta el personal ausente, ese dejalo donde esta").

   La clase vive en el <body>, no en el panel: el panel se re-renderiza entero
   tras cada asignacion (hx-swap-oob) y se llevaria el estado por delante.
============================================================================ */
body.personal-anclado .personal-section-available {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  background: var(--color-card-bg);
  border: none;
  border-top: 3px solid var(--c-amarillo);
  border-radius: 0;
  box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.13);
  padding: 0.35rem 1rem 0.5rem;
  max-height: 40vh;
  overflow-y: auto;
}
/* Al salirse de la rejilla el hueco que deja no se reparte: los ausentes pasan
   a ocupar el ancho entero en vez de quedarse en media pagina. */
body.personal-anclado .personal-grid { grid-template-columns: 1fr; }
body.personal-anclado .personal-section-available .personal-section-help {
  display: none;
}
body.personal-anclado .personal-section-available .personal-table {
  max-height: 22vh;
}
/* Hueco al final de la pagina para que la franja no tape el ultimo bloque. */
body.personal-anclado { padding-bottom: 42vh; }

.personal-anclar-btn {
  margin-left: auto;
  background: none;
  border: 1px solid var(--color-line);
  border-radius: 6px;
  padding: 0.15rem 0.5rem;
  font-size: 0.75rem;
  color: var(--color-muted);
  cursor: pointer;
  white-space: nowrap;
}
.personal-anclar-btn:hover {
  border-color: var(--c-naranja);
  color: var(--c-naranja);
}
body.personal-anclado .personal-anclar-btn {
  border-color: var(--c-naranja);
  color: var(--c-naranja);
}
@media (max-width: 700px) {
  /* En pantalla pequeña la franja se comeria la plantilla entera. */
  body.personal-anclado .personal-section-available { max-height: 32vh; }
  body.personal-anclado { padding-bottom: 34vh; }
}

/* ============================================================================
   Colapsar el asistente de sustituciones (Pablo 2026-09-17: "pon un boton para
   colapsar esa seccion"). Es un <details>: basta con enseñar el estado, porque
   pulsar el encabezado ya abre y cierra.
============================================================================ */
.seccion-plegar {
  border: 1px solid var(--color-line);
  border-radius: 6px;
  padding: 0.15rem 0.5rem;
  font-size: 0.75rem;
  color: var(--color-muted);
  white-space: nowrap;
}
details[open] > summary .seccion-plegar-abrir,
details:not([open]) > summary .seccion-plegar-cerrar { display: none; }

/* ============================================================================
   Desplegable de icono de seccion. Antes era una parrilla de 30 emojis metida
   en medio del formulario: ocupaba media pantalla y no tenia el aspecto del
   resto de campos (Pablo 2026-09-17). Un <select> normal queda a la altura de
   los demas y ocupa lo que tiene que ocupar.
============================================================================ */
.select-emoji {
  width: 5.5rem;
  font-size: 1rem;
  line-height: 1.4;
  text-align: center;
}

/* ============================================================================
   Listas ordenables arrastrando: zonas, secciones y puestos (Pablo 2026-09-17,
   "en vez de orden numérico vas a hacer un drag and drop").

   Son listas, no tablas: `draggable` sobre un <tr> no arranca el arrastre en
   Chromium (ya pasó con el panel de personal), y una lista con rejilla se lee
   igual de bien y se puede mover sin pelearse con el navegador.
============================================================================ */
.lista-ordenable { list-style: none; margin: 0; padding: 0; }

.lista-ordenable > li {
  display: grid;
  align-items: center;
  gap: 0.6rem;
  padding: 0.45rem 0.2rem;
  border-bottom: 1px solid var(--color-line);
  background: var(--color-card-bg);
}
.lista-ordenable > li:last-child { border-bottom: none; }
/* La celda de botones ocupa su columna entera y alinea dentro: encogerla con
   `justify-self` la sacaría de la rejilla y volvería a descuadrar la cabecera. */
.lista-ordenable > li > span:last-of-type { justify-content: flex-end; }

/* Cada bloque dice sus columnas: el asa siempre primero.
 *
 * La última columna (los botones) va con ANCHO FIJO, no `auto`. Con `auto` cada
 * fila es su propio grid y mide lo que ocupen sus botones: la cabecera, que ahí
 * no tiene nada, daba 0 y las filas 74px —o 209 las que llevan «Editar líneas»
 * y «Ajustes»—. El sobrante se lo comía la columna del nombre, así que MAÑANA,
 * TARDE y NOCHE salían 74px a la derecha de sus propios números, y las filas
 * tampoco cuadraban entre sí (Pablo, 2026-09-21). Cabe el caso más ancho. */
.lista-zonas    > li { grid-template-columns: 1.4rem 1fr 2fr var(--ancho-acciones); }
.lista-secciones > li { grid-template-columns: 1.4rem 1fr 5rem var(--ancho-acciones); }
.lista-puestos  > li { grid-template-columns: 1.4rem 1fr repeat(3, 4.6rem) 5rem var(--ancho-acciones); }
@media (max-width: 800px) {
  .lista-zonas > li, .lista-secciones > li, .lista-puestos > li {
    grid-template-columns: 1.4rem 1fr auto;
  }
  .lista-ordenable .col-opcional { display: none; }
}

/* El asa. Solo ella arrastra: dentro de la fila hay botones y desplegables. */
/* El distintivo no puede partir la fila en dos: parte la linea y la celda
   crece al doble, y con 44 puestos la lista se vuelve un acordeon. */
.lista-puestos .badge { white-space: nowrap; }

.orden-asa {
  cursor: grab;
  color: var(--color-line);
  font-size: 0.95rem;
  line-height: 1;
  text-align: center;
  user-select: none;
}
.orden-asa:hover { color: var(--c-naranja, #DE5014); }
.orden-asa:active { cursor: grabbing; }

.lista-ordenable > li.orden-moviendo { opacity: 0.4; }
/* Solo se marca el sitio donde se puede soltar, y solo mientras se arrastra:
   un recuadro permanente sería un cartel sin función. */
body.orden-activo .lista-ordenable.orden-destino {
  outline: 2px dashed var(--c-amarillo);
  outline-offset: 3px;
  border-radius: 6px;
}
body.orden-guardando { cursor: progress; }

/* Un grupo vacío tiene que poder recibir algo arrastrado, así que ocupa sitio. */
/* Un grupo vacio tiene que poder recibir lo que se arrastra, y para eso tiene
   que ocupar sitio: con altura cero no hay donde soltar.
   Esto era `:empty::after`, que NO funcionaba: `:empty` no casa si dentro hay
   saltos de linea, y la plantilla los deja. Resultado: WYMA, que estaba vacia,
   no admitia nada (Pablo 2026-09-17). El aviso se pinta ahora desde la vista. */
.lista-ordenable { min-height: 2.2rem; }
/* Con `.lista-vacia` a secas gana `.lista-ordenable > li` y el aviso hereda la
   rejilla: el texto se mete en la columna del asa y se parte en trece lineas. */
.lista-ordenable > li.lista-vacia {
  display: block;
  padding: 0.55rem 0.2rem;
  font-size: 0.8rem;
  font-style: italic;
  color: var(--color-muted);
}
body.orden-activo .lista-vacia { color: var(--c-naranja, #DE5014); }

.grupo-ordenable { margin: 0 0 0.9rem; }
.grupo-ordenable > h4 {
  margin: 0 0 0.25rem;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--color-muted);
  text-transform: uppercase;
}
.fila-cabecera {
  display: grid; gap: 0.6rem;
  padding: 0 0.2rem 0.3rem;
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--color-muted);
  border-bottom: 1px solid var(--color-line);
}
/* Mismas columnas que su lista, o las cabeceras no caen sobre sus datos. */
.cab-zonas    { grid-template-columns: 1.4rem 1fr 2fr var(--ancho-acciones); }
.cab-secciones { grid-template-columns: 1.4rem 1fr 5rem var(--ancho-acciones); }
.cab-puestos  { grid-template-columns: 1.4rem 1fr repeat(3, 4.6rem) 5rem var(--ancho-acciones); }
@media (max-width: 800px) {
  .cab-zonas, .cab-secciones, .cab-puestos {
    grid-template-columns: 1.4rem 1fr auto;
  }
}

/* ============================================================================
   El SÁBADO por la mañana (Pablo, 2026-09-29)

   Hereda el cupo de entre semana; solo se marca lo distinto. El color del
   sábado es el marrón tierra de la marca. La ficha es la misma en
   /configuracion/cupos, en /configuracion/linea_cupos y en su leyenda:
     gris y a trazos = como entre semana · negrita = cupo propio · 🛌 = no trabaja
   ============================================================================ */
.col-sabado { text-align: center; }
.lista-puestos > li > .col-sabado,
.cab-puestos > .col-sabado { justify-self: center; }
.cab-puestos > .col-sabado { color: var(--c-marron-tierra); font-weight: 700; }
.tabla-lineas th.col-sabado { color: var(--c-marron-tierra); }

.sab-ficha { position: relative; display: inline-block; }
.sab-chip {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.2rem; height: 1.75rem; padding: 0 0.55rem;
  border-radius: 999px;
  font-size: 0.88rem; font-weight: 700; line-height: 1;
  cursor: pointer; user-select: none; list-style: none;
  transition: box-shadow 0.12s ease, background-color 0.12s ease;
}
.sab-chip::-webkit-details-marker { display: none; }
.sab-chip::marker { content: ''; }
.sab-hereda {
  color: var(--color-muted); font-style: italic; font-weight: 500;
  border: 1px dashed #cdbfb0; background: transparent;
}
.sab-hereda-no { font-style: normal; opacity: 0.55; }
.sab-propio {
  color: #6f5233; background: rgba(166, 129, 85, 0.16);
  border: 1px solid var(--c-marron-tierra);
}
.sab-no { background: #f2ece5; border: 1px solid #d9cfc4; }
/* El 🛌 sale diminuto a tamaño de texto en la fuente de emojis de Windows. */
.sab-no, .sab-hereda-no { font-size: 1.05rem; }
.sab-chip:hover,
.sab-ficha[open] > .sab-chip { box-shadow: 0 0 0 3px rgba(166, 129, 85, 0.22); }
.sab-chip:focus-visible { outline: 2px solid var(--c-marron-tierra); outline-offset: 2px; }

.sab-editor {
  position: absolute; z-index: 40; right: 0; top: calc(100% + 6px);
  width: 17.5rem;
  display: grid; gap: 0.3rem;
  padding: 0.75rem 0.8rem 0.65rem;
  background: var(--color-card-bg);
  border: 1px solid var(--color-line);
  border-top: 3px solid var(--c-marron-tierra);
  border-radius: var(--radius);
  box-shadow: 0 10px 28px rgba(34, 34, 33, 0.16);
  text-align: left; font-size: 0.86rem; font-weight: 400; font-style: normal;
  text-transform: none; letter-spacing: normal; color: var(--color-fg);
}
.sab-editor-titulo {
  margin: 0 0 0.25rem; font-weight: 700; color: var(--c-marron-tierra);
}
.sab-editor-titulo span {
  display: block; font-weight: 500; font-size: 0.76rem; color: var(--color-muted);
}
.sab-opcion {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.35rem 0.45rem; border-radius: 5px; cursor: pointer;
}
.sab-opcion:hover { background: #faf5ef; }
.sab-opcion:has(input[type="radio"]:checked) {
  background: rgba(166, 129, 85, 0.12);
  box-shadow: inset 0 0 0 1px rgba(166, 129, 85, 0.45);
}
.sab-opcion input[type="radio"] { accent-color: var(--c-marron-tierra); margin: 0; }
.sab-opcion em { font-style: normal; font-weight: 700; margin-left: 0.2rem; }
.sab-cupo { width: 4.2rem; margin-left: auto; }
.sab-editor-pie {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  margin-top: 0.3rem; padding-top: 0.55rem;
  border-top: 1px solid var(--color-line);
  font-size: 0.74rem; color: var(--color-muted);
}

.sab-leyenda {
  margin: 0.4rem 0 0.9rem; padding: 0.6rem 0.85rem;
  border-left: 3px solid var(--c-marron-tierra);
  border-radius: var(--radius);
  background: #fbf7f2;
  font-size: 0.85rem; line-height: 1.7;
}
.sab-leyenda > strong { color: var(--c-marron-tierra); }
.sab-leyenda-muestras {
  display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.5rem;
  margin: 0 0.4rem;
}
.sab-leyenda .sab-chip { cursor: default; min-width: 1.9rem; height: 1.45rem; font-size: 0.8rem; }
.sab-leyenda .sab-chip:hover { box-shadow: none; }

/* El interruptor de una sección entera. */
.grupo-ordenable-titulo {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.6rem 1rem; flex-wrap: wrap;
}
.sab-seccion { margin: 0; display: inline-flex; }
.sab-switch {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.2rem 0.75rem 0.2rem 0.3rem;
  border: 1px solid var(--color-line); border-radius: 999px;
  background: var(--color-card-bg);
  font: inherit; font-size: 0.78rem; font-weight: 600; color: var(--color-fg);
  text-transform: none; letter-spacing: normal;
  cursor: pointer;
}
.sab-switch:hover { border-color: var(--c-marron-tierra); }
.sab-switch:focus-visible { outline: 2px solid var(--c-marron-tierra); outline-offset: 2px; }
.sab-switch-pista {
  position: relative; width: 2.1rem; height: 1.2rem; border-radius: 999px;
  background: var(--color-success); transition: background-color 0.15s ease;
}
.sab-switch-bola {
  position: absolute; top: 0.1rem; left: calc(100% - 1.1rem);
  width: 1rem; height: 1rem; border-radius: 50%;
  background: var(--c-blanco); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: left 0.15s ease;
}
.sab-switch.is-off {
  border-color: var(--c-marron-tierra); background: rgba(166, 129, 85, 0.1);
  color: #6f5233;
}
.sab-switch.is-off .sab-switch-pista { background: #cdbfb0; }
.sab-switch.is-off .sab-switch-bola { left: 0.1rem; }
.grupo-sin-sabado .cab-puestos > .col-sabado::after { content: ' 🛌'; }

/* Cupos por línea: la ficha del puesto en la cabecera de su tarjeta. */
.card-title-con-sabado {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.5rem 1rem; flex-wrap: wrap;
}
.sab-puesto-lineas {
  display: inline-flex; align-items: center; gap: 0.45rem;
  font-size: 0.78rem; font-weight: 500; color: var(--color-muted);
}

/* La plantilla de un sábado por la mañana. */
.cinta-sabado {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 1rem;
  margin: 0.6rem 0; padding: 0.55rem 0.95rem;
  background: linear-gradient(90deg, rgba(166, 129, 85, 0.16), rgba(166, 129, 85, 0.04));
  border-left: 4px solid var(--c-marron-tierra);
  border-radius: var(--radius);
  font-size: 0.88rem;
}
.cinta-sabado-que { font-weight: 700; color: #6f5233; }
.cinta-sabado-detalle { color: var(--color-fg); }
.cinta-sabado-enlace {
  margin-left: auto; font-weight: 600; color: var(--c-naranja); text-decoration: none;
  white-space: nowrap;
}
.cinta-sabado-enlace:hover { text-decoration: underline; }
.cupo-stepper.cupo-stepper-sabado {
  border-color: var(--c-marron-tierra); background: rgba(166, 129, 85, 0.08);
}
.cupo-entre-semana {
  display: inline-block; margin-left: 0.3rem; padding: 0 0.4rem;
  border: 1px dashed #cdbfb0; border-radius: 999px;
  font-size: 0.66rem; font-weight: 500; color: var(--color-muted);
  white-space: nowrap; vertical-align: middle;
}
.grupo-ocultos-que.grupo-ocultos-sabado { color: #6f5233; font-weight: 600; }
.oculto.oculto-sabado { background: rgba(166, 129, 85, 0.06); }
.oculto-que.oculto-que-sabado { color: #6f5233; font-weight: 600; }

.editor-fila {
  grid-column: 1 / -1;
  margin-top: 0.5rem;
  padding: 0.7rem 0.9rem;
  background: var(--color-bg);
  border-radius: 6px;
}

/* ============================================================================
   Fijar a alguien a un puesto (Pablo 2026-09-18): "si está disponible, siempre
   va al mismo puesto". El pin se ve apagado hasta que se usa, como el resto de
   acciones de la tarjeta, y encendido cuando la persona está fijada — que es lo
   que hay que poder leer de un vistazo al mirar la plantilla.
============================================================================ */
.slot-action-fijar {
  background: none;
  border: none;
  padding: 0 0.15rem;
  font-size: 0.8rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.3;
  filter: grayscale(1);
}
.slot-action-fijar:hover { opacity: 0.8; filter: none; }
.slot-action-fijar.esta-fijado { opacity: 1; filter: none; }

/* ============================================================================
   Avisos de "guardado / no se pudo guardar" (.alert)

   Las pantallas de configuración llevaban tiempo pintando `.alert alert-success`
   sin que existiera la clase: el mensaje salía como texto suelto, sin fondo ni
   margen, y parecía parte de la página. Se define aquí, con los mismos colores
   que los avisos de la plantilla, para que todas las pantallas avisen igual.
============================================================================ */
.alert {
  margin: 0.6rem 0;
  padding: 0.55rem 0.85rem;
  border-radius: 6px;
  border-left: 3px solid var(--color-line);
  background: var(--color-card-bg);
  font-size: 0.92rem;
}
.alert-success { background: #e8f5e9; border-left-color: #2e7d32; }
.alert-error   { background: #ffebee; border-left-color: #c62828; }
.alert-warning { background: #fff8e1; border-left-color: var(--c-amarillo); }
.alert-info    { background: #f3f0fa; border-left-color: var(--c-lavanda); }

/* ============================================================================
   Cupos por línea: se lee como una tabla, se edita en la propia fila

   Pablo, 2026-09-21, en dos pasos. Primero: *"los cupos se modifican en la
   misma línea de los cupos que ya hay, no hace falta enseñar nuevos cuadros"*.
   Y al verlo todo editable a la vez: *"la edición de cada línea tiene que estar
   escondida detrás de un botón de editar, como estaba"*.

   En reposo, texto; al pulsar «Editar», esa misma fila cambia a campos, en las
   mismas celdas. Lo que se quitó fue la fila desplegada debajo, que repetía los
   tres turnos en cuadros nuevos y traía cuatro botones.
============================================================================ */
.tabla-lineas td { vertical-align: middle; height: 2.9rem; }
.tabla-lineas .editar { display: none; }
.tabla-lineas tr.editando .ver { display: none; }
.tabla-lineas tr.editando .editar { display: inline-flex; }
.tabla-lineas tr.editando td { background: #fffdf5; }
.tabla-lineas .nombre-linea { font-weight: 600; }
.tabla-lineas .sin-dato { color: var(--color-muted); }

.tabla-lineas input[type="text"],
.tabla-lineas input[type="number"] {
  font: inherit;
  color: var(--color-fg);
  background: var(--color-card-bg);
  border: 1px solid var(--color-line);
  border-radius: 5px;
  padding: 0.25rem 0.4rem;
}
.tabla-lineas input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px rgba(222, 80, 20, 0.15);
}
.tabla-lineas .celda-nombre { width: 11.5rem; font-weight: 600; }
.tabla-lineas input[type="number"] { width: 3.2rem; text-align: center; }

/* "sin ETT" es la excepción y por eso se ve en reposo; el resto de la fila son
   números y no necesita adornos. */
.pill-no-ett {
  font-size: 0.68rem;
  color: var(--color-accent);
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 0 0.35rem;
  white-space: nowrap;
}

.celda-cupo { align-items: center; gap: 0.4rem; }
.celda-cupo label {
  display: inline-flex; align-items: center; gap: 0.25rem;
  font-size: 0.7rem; color: var(--color-muted); cursor: pointer;
  user-select: none;
}
.celda-cupo input[type="checkbox"] {
  margin: 0; cursor: pointer;
  accent-color: var(--color-primary);
  width: 0.85rem; height: 0.85rem;
}
.celda-cupo label:has(input:not(:checked)) {
  color: var(--color-accent); font-weight: 600;
}

.celda-acciones { white-space: nowrap; }
.celda-acciones > * { margin-right: 0.4rem; }
.tabla-lineas .btn-small:disabled {
  background: transparent;
  color: var(--color-muted);
  border: 1px solid var(--color-line);
  cursor: default;
  opacity: 1;
}
/* Cancelar y Quitar no compiten con Guardar: son texto hasta que se apunta. */
.btn-plano, .btn-quitar {
  background: none; border: 0; padding: 0.25rem 0.4rem;
  font: inherit; font-size: 0.82rem;
  color: var(--color-muted); cursor: pointer; border-radius: 5px;
}
.btn-plano:hover { background: var(--color-bg); color: var(--color-fg); }
.btn-quitar:hover, .btn-quitar:focus-visible {
  background: #ffebee; color: var(--color-danger); outline: none;
}

.tabla-lineas .fila-nueva td { background: var(--color-bg); }
.tabla-lineas .fila-guardada td { background: #e8f5e9; transition: background 0.4s; }
.tabla-lineas .fila-error td { background: #ffebee; }

.nota-lineas {
  margin: 0.2rem 0 1rem;
  font-size: 0.82rem;
  color: var(--color-muted);
  max-width: 62ch;
}

/* No aptos. El motivo es lo unico que hace util esta pantalla, asi que se lee;
   en cualquier OTRA sale solo el hecho (lo escribio una persona sobre otra). */
.na-ayuda { color: var(--color-muted); font-size: 0.82rem; margin: 0.2rem 0 0.6rem; }
.na-motivo { font-style: italic; max-width: 22rem; }
.na-meta { font-size: 0.78rem; color: var(--color-muted); }
.na-meta-val { color: var(--c-morado); }
/* /no_aptos por tipos (2026-09-30): el alta a mano, el buscador y los grupos. */
.na-alta { margin: 0.8rem 0; }
.na-alta > summary { cursor: pointer; }
.na-alta-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
                gap: 0.6rem 1rem; margin-top: 0.6rem; }
.na-campo { display: grid; gap: 0.25rem; }
.na-campo > span { font-weight: 600; font-size: 0.85rem; }
.na-campo input, .na-campo select, .na-campo textarea { font: inherit; width: 100%; }
.na-campo-motivo { grid-column: 1 / -1; }
.na-alta-form .card-footer { grid-column: 1 / -1; }
.na-filtro { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin: 0.8rem 0; }
.na-filtro input[type="search"] { min-width: 14rem; font: inherit; }
.na-filtro-quitar { font-size: 0.85rem; }
.na-tipo { margin: 0.8rem 0 0.3rem; font-size: 0.9rem; color: var(--c-marron-tierra); }
/* En la plantilla: el hecho, nunca el motivo. */
.badge-no-apto { background: #fde2e1; color: #8a1c14; }
/* El boton de NO APTO del supervisor, junto al resto de acciones de la persona. */
.slot-action-noapto {
  border: 1px solid var(--color-line); background: transparent;
  border-radius: var(--radius); cursor: pointer; padding: 0 0.25rem;
  font-size: 0.8rem; line-height: 1.3;
}
.slot-action-noapto:hover { background: rgba(93, 42, 92, 0.12); }
/* El parte de presencia: un boton por persona, discreto. */
.slot-action-presencia {
  border: 1px solid var(--color-line); background: transparent;
  border-radius: var(--radius); cursor: pointer; padding: 0 0.25rem;
  font-size: 0.8rem; line-height: 1.3;
}
.slot-action-presencia:hover { background: var(--color-line); }
.slot-action-presencia.no-vino { border-color: var(--color-danger); }
/* Marcado como no presentado. Sigue puesto a proposito: lo previsto es un dato y
   lo ocurrido es otro, y sin los dos no se concilia la factura de una ETT. */
.badge-no-vino { background: rgba(200, 30, 30, 0.14); color: #a01414; }
.slot:has(.badge-no-vino) .slot-worker,
.line-slot-worker:has(.badge-no-vino) .line-slot-worker-name,
.line-slot-worker-standalone:has(.badge-no-vino) .line-slot-worker-name {
  text-decoration: line-through; opacity: 0.7;
}
/* «No se ha presentado» y «No apto» del supervisor, plegados tras un ⋯ para no
   darles sin querer (Pablo 2026-09-24). El menú flota sobre la tarjeta: abierto
   no empuja la fila ni cambia el alto de la tarjeta. */
.acciones-supervisor { position: relative; display: inline-block; }
.acciones-supervisor-abrir {
  list-style: none; cursor: pointer; user-select: none;
  border: 1px solid var(--color-line); border-radius: 3px;
  padding: 0 0.35rem; font-size: 0.85rem; line-height: 1.3; font-weight: 700;
  color: var(--color-muted);
}
.acciones-supervisor-abrir::-webkit-details-marker { display: none; }
.acciones-supervisor-abrir:hover,
.acciones-supervisor[open] > .acciones-supervisor-abrir {
  background: var(--color-line); color: var(--color-fg);
}
.acciones-supervisor-menu {
  position: absolute; right: 0; top: calc(100% + 3px); z-index: 30;
  display: flex; flex-direction: column; gap: 0.25rem;
  min-width: 13rem; padding: 0.35rem;
  background: var(--c-blanco); border: 1px solid var(--color-line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.acciones-supervisor-menu form { margin: 0; }
.acciones-supervisor-menu .slot-action-presencia,
.acciones-supervisor-menu .slot-action-noapto {
  width: 100%; text-align: left; white-space: nowrap;
  padding: 0.3rem 0.5rem; font-size: 0.82rem; font-family: var(--font-body);
}
/* Huecos de ultima hora. Rojo y arriba del panel: es lo unico de esta columna
   que hay que mirar con el turno ya empezado. */
.ultima-hora { border-left: 3px solid var(--color-danger); margin-bottom: 0.8rem; }
.ultima-hora-ayuda { font-size: 0.82rem; color: var(--color-muted); margin: 0.3rem 0 0.6rem; }
.ultima-hora-lista { margin: 0; padding-left: 1.1rem; font-size: 0.86rem; }
/* Reparto de huecos entre las ETT. Colgando del hueco: repartir sin ver cuanto
   falta al lado es pedir a ciegas. */
.reparto { margin: 0.4rem 0; font-size: 0.85rem; }
.reparto summary { cursor: pointer; }
.reparto-faltan { color: var(--color-primary); font-weight: 600; }
.reparto-repartido, .reparto-esperando { color: var(--color-muted); font-size: 0.8rem; }
.reparto-lista { margin: 0.3rem 0 0.5rem; padding-left: 1.2rem; }
/* UN formulario para todo el panel y un solo «Pedir» (2026-09-28): cada puesto
   con sus filas de empresa y cantidad, y «+ Otra empresa» para repartirlo. */
.reparto-form { display: flex; flex-direction: column; gap: 0.1rem; margin: 0.3rem 0 0.2rem; }
.reparto-filas { display: flex; flex-direction: column; gap: 0.3rem; margin: 0.35rem 0 0.25rem; }
.reparto-fila { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
.reparto-fila select { max-width: 12rem; }
.reparto-fila input[type="number"] { width: 4.5rem; }
.reparto-empresa { min-width: 8rem; font-weight: 600; }
.reparto-quitar {
  background: transparent; border: 1px solid var(--color-line); color: var(--color-danger);
  border-radius: 3px; padding: 0.05rem 0.4rem; line-height: 1; cursor: pointer;
}
.reparto-otra {
  background: transparent; border: 1px dashed var(--color-primary); color: var(--color-primary);
  border-radius: 4px; padding: 0.15rem 0.55rem; font-size: 0.78rem; cursor: pointer;
  font-family: var(--font-body); margin: 0 0 0.3rem;
}
.reparto-otra:hover { background: rgba(222, 80, 20, 0.08); }
.reparto-acciones {
  display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap;
  margin-top: 0.4rem; padding-top: 0.5rem; border-top: 1px dashed var(--color-line);
}
.reparto-aviso { margin: 0.3rem 0 0.5rem; }
.reparto-ayuda { color: var(--color-muted); font-size: 0.85rem; }

/* El ETT que aparece sin estar en el sistema. Plegado: es la excepcion, no la
   norma, pero tiene que estar a mano durante el turno. */
.no-convocado { margin: 1rem 0; font-size: 0.88rem; }
.no-convocado summary { cursor: pointer; font-weight: 600; }
.no-convocado-ayuda { color: var(--color-muted); font-size: 0.82rem; margin: 0.4rem 0; }
.no-convocado-form {
  /* `flex-start` y no `flex-end`: los campos tienen alturas distintas (uno lleva
     nota debajo) y alineandolos por abajo las etiquetas salen a distinta altura. */
  display: flex; flex-wrap: wrap; gap: 0.8rem; align-items: flex-start;
  background: var(--c-blanco); border: 1px solid var(--color-line);
  border-radius: var(--radius); padding: 0.8rem; margin-top: 0.4rem;
}
.no-convocado-form label { display: flex; flex-direction: column; gap: 0.25rem;
                           font-size: 0.82rem; font-weight: 600; }
/* El `display: flex` de arriba gana al estilo del navegador para [hidden], asi
   que el puesto salia siempre aunque no se hubiera marcado la casilla. */
.no-convocado-form label[hidden] { display: none; }
.no-convocado-form input, .no-convocado-form select { font-weight: 400; }
.no-convocado-check { flex-direction: row !important; align-items: center; }
.no-convocado-nota { font-weight: 400; color: var(--color-muted); font-size: 0.75rem; }
/* Vino sin que se le pidiera. Se ve en la plantilla porque en la factura del mes
   ser indistinguible de alguien a quien se pidio es lo que no puede pasar. */
.badge-no-convocado { background: rgba(222, 80, 20, 0.16); color: var(--color-primary); }
/* El boton se alinea con los campos, no con sus etiquetas. */
.no-convocado-enviar { align-self: flex-end; }

/* ---------------------------------------------------------------------------
   Movil: las tablas anchas se desplazan ELLAS, no la pagina
   ---------------------------------------------------------------------------
   Una tabla de datos (usuarios, personal del dia, no aptos…) no cabe en 390px,
   y sin esto empujaba la pagina entera y dejaba toda la pantalla desplazandose
   a la derecha. Como bloque con scroll propio, la pagina se queda quieta y la
   tabla se mira arrastrando, que es lo que espera cualquiera en un movil.

   Solo en pantalla estrecha: en un PC la tabla es una tabla. */
@media (max-width: 720px) {
  .table-data,
  .data-table { display: block; overflow-x: auto; max-width: 100%; }
  .personal-section { min-width: 0; }
}

/* ---------------------------------------------------------------------------
   Movil: los formularios en rejilla se apilan
   ---------------------------------------------------------------------------
   `.cupos-form-grid` reparte sus campos en columnas fijas que suman mas de
   700px: en un movil no caben y empujaban la pagina (el plan fijo llegaba a
   875px de ancho con sus seis columnas). Apilados en una columna caben, y de
   paso los campos se ven enteros en lugar de recortados.

   El ancho de seis columnas del plan fijo vivia en un `style=` dentro de la
   vista, donde ninguna media query podia alcanzarlo. Por eso esta aqui. */
.cupos-form-grid--plan { grid-template-columns: 1.4fr 1.4fr 0.6fr 1fr 1fr 0.8fr; }
@media (max-width: 720px) {
  .cupos-form-grid,
  .cupos-form-grid--plan { grid-template-columns: 1fr; }
  .cupos-form-grid input[type="text"],
  .cupos-form-grid input[type="number"],
  .cupos-form-grid input[type="date"],
  .cupos-form-grid select { width: 100%; min-width: 0; }
}


/* En movil, las rejillas de formulario de una columna. Las medidas fijas
   (80px, 110px, dos columnas) estan pensadas para un monitor; en 390px suman
   mas que la pantalla y empujaban la pagina. */
@media (max-width: 720px) {
  .formaciones-form-grid,
  .threshold-grid { grid-template-columns: 1fr; }
  .formaciones-form-grid input[type="text"],
  .formaciones-form-grid select,
  .threshold-grid input[type="number"] { width: 100%; min-width: 0; }
}

/* Cabecera de pagina: titulo a un lado, botones al otro. Cuando no caben en
   la misma linea, bajan -- antes salian fuera de la pantalla. */
.page-header-row {
  display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; flex-wrap: wrap;
}

/* Ficha de ILUO de una persona al pulsar su nombre (Pablo 2026-09-24). El
   nombre se subraya al pasar para que se vea que se puede pulsar. */
[data-ficha-iluo] { cursor: pointer; }
.slot-worker[data-ficha-iluo]:hover, .line-slot-worker-name[data-ficha-iluo]:hover,
.asist-persona[data-ficha-iluo]:hover {
  text-decoration: underline; text-decoration-style: dotted;
}
/* Asistente de sustituciones: a quién se ha descartado para ese hueco, y el
   aviso tras rechazar (Pablo y RRHH, 2026-09-29). */
.asist-descartados { margin-top: 0.15rem; font-size: 0.74rem; color: var(--color-muted); }
/* Los estados del turno (Pablo, 2026-09-30): qué toca hacer a quien la mira,
   por qué está bloqueado el auto-relleno, y «Aceptar cambios» destacado. */
.estado-plantilla-toca { font-size: 0.82rem; font-weight: 600; color: var(--color-fg); }
.estado-plantilla-bloqueo { font-size: 0.8rem; color: var(--c-marron-tierra); }
.btn.estado-plantilla-destacado {
  background: var(--c-naranja); color: var(--c-blanco); border-color: var(--c-naranja);
  box-shadow: 0 0 0 3px rgba(222, 80, 20, 0.18);
}
/* Turnos atrasados sin cerrar: solo RRHH y admin, arriba de la plantilla. */
.aviso-atrasados {
  margin: 0.6rem 0; padding: 0.5rem 0.85rem;
  border-left: 4px solid var(--c-naranja); border-radius: var(--radius);
  background: rgba(222, 80, 20, 0.07); font-size: 0.86rem; line-height: 1.6;
}
.aviso-atrasados a { color: var(--c-naranja); font-weight: 600; white-space: nowrap; }
.aviso-rechazo {
  margin: 0.6rem 0; padding: 0.5rem 0.8rem;
  background: #fbf7f2; border-left: 3px solid var(--c-marron-tierra);
}
/* «Mandar a la ETT» desde el asistente (Pablo, 2026-09-29): el estado de la
   fila, por qué no se puede cuando no, el aviso de arriba y el hueco del
   reparto que se abre a la vista. */
.badge-ett-mandado { background: var(--c-salmon); color: var(--c-morado); }
.asist-no-ett {
  margin-top: 0.2rem; max-width: 18rem; white-space: normal;
  font-size: 0.74rem; color: var(--color-muted);
}
.aviso-mandado-ett {
  margin: 0.6rem 0; padding: 0.5rem 0.8rem;
  background: rgba(237, 163, 138, 0.2); border-left: 3px solid var(--c-naranja, #DE5014);
}
.reparto-enfoque {
  padding: 0.3rem 0.5rem; border-radius: var(--radius);
  outline: 2px solid var(--c-naranja, #DE5014); background: #fff;
}
.ficha-iluo-abrir {
  margin-left: 0.4rem; padding: 0 0.3rem; font-size: 0.65rem; font-weight: 700;
  border: 1px solid var(--color-line); border-radius: 3px; background: transparent;
  color: var(--color-muted); cursor: pointer; line-height: 1.4;
}
.ficha-iluo-abrir:hover { color: var(--color-fg); border-color: var(--color-fg); }
.ficha-iluo-dialogo {
  border: 0; border-top: 4px solid var(--c-amarillo); border-radius: var(--radius);
  padding: 1rem 1.2rem; width: min(30rem, calc(100vw - 2rem)); box-shadow: var(--shadow);
  font-family: var(--font-body);
}
.ficha-iluo-dialogo::backdrop { background: rgba(0, 0, 0, 0.35); }
.ficha-iluo-nombre { font-size: 1.05rem; margin: 0 0 0.6rem; }
.ficha-iluo-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem; }
.ficha-iluo-lista li { display: grid; grid-template-columns: 2.2rem 1fr; gap: 0 0.6rem; align-items: center; }
.ficha-iluo-nivel {
  grid-row: span 2; display: inline-flex; align-items: center; justify-content: center;
  height: 1.8rem; border-radius: 4px; font-size: 0.9rem;
}
.ficha-iluo-puesto { font-weight: 700; font-size: 0.9rem; }
.ficha-iluo-detalle, .ficha-iluo-leyenda, .ficha-iluo-nada { font-size: 0.8rem; color: var(--color-muted); }
.ficha-iluo-leyenda { margin: 0.7rem 0 0; }
.ficha-iluo-pie { display: flex; justify-content: flex-end; margin: 0.8rem 0 0; }

/* ============================================================================
   Disponibles de ETT y pedidos con nombre (Pablo, 2026-09-24)
============================================================================ */
.ett-disp { margin: 0.6rem 0; padding: 0.6rem 0.8rem; border-left: 3px solid var(--c-salmon); }
.ett-disp-titulo { cursor: pointer; font-weight: 700; color: var(--color-fg); }
.ett-disp-bloque { margin-top: 0.5rem; }
.ett-disp-bloque > summary { cursor: pointer; font-weight: 600; font-size: 0.9rem; color: var(--color-fg); }
.ett-disp-bloque[hidden], #ett-disponibles-panel [data-ett-fila][hidden] { display: none !important; }
.ett-disp-nota { font-size: 0.85em; color: var(--color-muted); }
.ett-disp-accion { text-align: right; white-space: nowrap; }

.badge-ett-pendiente { background: #fff3e0; color: #8a4b00; border: 1px dashed #DE5014; }
.badge-ett-propuesta { background: #ede7f6; color: var(--c-morado); }

.slot-action-pedido {
  background: none; border: 1px solid var(--color-line); border-radius: 3px;
  font-size: 0.72rem; padding: 0.05rem 0.35rem; line-height: 1.2; cursor: pointer;
  color: var(--color-fg);
}
.slot-action-pedido:hover { border-color: #DE5014; color: #DE5014; }
.slot-action-mover-pedido {
  background: none; border: none; padding: 0 0.15rem; font-size: 0.8rem;
  line-height: 1; cursor: pointer; opacity: 0.55;
}
.slot-action-mover-pedido:hover { opacity: 1; }

/* También el formulario de «Cambiar de puesto» (_cambio_puesto_modal.eta). */
.ett-pedir-form, .cambio-puesto-form { display: grid; gap: 0.7rem; margin-top: 0.5rem; }
.ett-pedir-campo, .cambio-puesto-campo { display: grid; gap: 0.3rem; border: none; margin: 0; padding: 0; }
.ett-pedir-campo > legend, .ett-pedir-campo > span, .cambio-puesto-campo > span { font-weight: 600; font-size: 0.9rem; }
.cambio-puesto-campo select, .cambio-puesto-campo input { font: inherit; }
.cambio-puesto-campo select { width: 100%; }
.cambio-puesto-campo input[type="time"] { max-width: 9rem; }
.ett-pedir-campo label { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.ett-pedir-campo textarea, .ett-pedir-campo select { width: 100%; font: inherit; }
.modal-acciones { display: flex; gap: 0.5rem; justify-content: flex-end; flex-wrap: wrap; margin-top: 0.6rem; }
.ett-pedido-estado { margin: 0.6rem 0; padding: 0.5rem 0.7rem; border-radius: 4px; background: #f7f3ec; }
.ett-pedido-estado-confirmado { background: #e8f5e9; }
.ett-pedido-estado-rechazado, .ett-pedido-estado-cancelado { background: #ffebee; }
.ett-pedido-accion { margin-top: 0.5rem; }
.ett-pedido-accion > summary { cursor: pointer; font-weight: 600; }
.ett-pedido-form { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; margin-top: 0.4rem; }
@media (max-width: 640px) {
  .ett-disp-nota { display: none; }
}

/* Los turnos de un supervisor (portada y aviso de turno ajeno). */
.mis-turnos { display: flex; gap: 1.2rem; flex-wrap: wrap; margin-top: 0.6rem; }
.mis-turnos-grupo { min-width: 12rem; }
.mis-turnos-grupo h4 { margin: 0 0 0.3rem; font-size: 0.85rem; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.mis-turnos-grupo ul { list-style: none; margin: 0; padding: 0; }
.mis-turnos-grupo li { margin: 0.15rem 0; }
.mis-turnos-grupo a { text-decoration: none; }
.mis-turnos-grupo a:hover { text-decoration: underline; }


/* --- Chat de RRHH en la plantilla (2026-09-28, _chat_panel.eta + js/chat-rrhh.js) --- */
.chat-rrhh-boton {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 900;
  background: var(--color-primary); color: white; border: 0; border-radius: 999px;
  padding: 0.65rem 1.1rem; font-family: var(--font-body); font-weight: 700; font-size: 0.9rem;
  box-shadow: 0 4px 14px rgba(34, 34, 33, 0.25); cursor: pointer;
}
.chat-rrhh-boton:hover { background: var(--c-morado); }
.chat-rrhh-panel {
  position: fixed; right: 1rem; bottom: 4.2rem; z-index: 900;
  width: min(430px, calc(100vw - 2rem)); height: min(70vh, 640px);
  display: flex; flex-direction: column;
  background: var(--color-card-bg); border: 1px solid var(--color-line);
  border-top: 4px solid var(--color-secondary); border-radius: var(--radius);
  box-shadow: 0 8px 28px rgba(34, 34, 33, 0.22);
}
/* `display: flex` pisa al atributo `hidden`: se dice explícito. */
.chat-rrhh-panel[hidden], .chat-rrhh-estado[hidden] { display: none; }
.chat-rrhh-cabecera {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 0.5rem;
  padding: 0.6rem 0.75rem; border-bottom: 1px solid var(--color-line);
}
.chat-rrhh-sub { font-size: 0.75rem; color: var(--color-muted); margin-top: 0.1rem; }
.chat-rrhh-acciones { display: flex; gap: 0.3rem; flex-shrink: 0; }
.chat-rrhh-mensajes {
  flex: 1; overflow-y: auto; padding: 0.75rem; display: flex; flex-direction: column; gap: 0.55rem;
  background: var(--color-bg);
}
.chat-rrhh-msg {
  max-width: 92%; padding: 0.5rem 0.7rem; border-radius: 10px; font-size: 0.86rem;
  line-height: 1.4; overflow-wrap: anywhere;
}
.chat-rrhh-msg p { margin: 0 0 0.4rem; }
.chat-rrhh-msg p:last-child { margin-bottom: 0; }
.chat-rrhh-msg ul, .chat-rrhh-msg ol { margin: 0.2rem 0 0.4rem; padding-left: 1.2rem; }
.chat-rrhh-msg table { border-collapse: collapse; margin: 0.3rem 0; font-size: 0.8rem; display: block; overflow-x: auto; }
.chat-rrhh-msg th, .chat-rrhh-msg td { border: 1px solid var(--color-line); padding: 0.2rem 0.4rem; text-align: left; overflow-wrap: normal; }
.chat-rrhh-msg th { background: #fff6dc; white-space: nowrap; }
.chat-rrhh-yo { align-self: flex-end; background: var(--c-amarillo); color: var(--c-negro); }
.chat-rrhh-el { align-self: flex-start; background: var(--c-blanco); border: 1px solid var(--color-line); }
.chat-rrhh-error { align-self: stretch; background: #fdecea; color: var(--color-danger); border: 1px solid #f3c3bd; }
.chat-rrhh-pie { margin-top: 0.35rem; font-size: 0.72rem; color: var(--color-muted); }
.chat-rrhh-sin-datos { color: var(--color-danger); }
.chat-rrhh-vacio { font-size: 0.85rem; color: var(--color-muted); }
.chat-rrhh-vacio p { margin: 0 0 0.5rem; }
.chat-rrhh-ejemplo {
  display: block; width: 100%; text-align: left; margin: 0.3rem 0; padding: 0.4rem 0.6rem;
  background: var(--c-blanco); border: 1px dashed var(--color-accent); border-radius: 8px;
  font-family: var(--font-body); font-size: 0.84rem; color: var(--color-fg); cursor: pointer;
}
.chat-rrhh-ejemplo:hover { border-style: solid; }
.chat-rrhh-estado { padding: 0.3rem 0.75rem; font-size: 0.78rem; color: var(--color-muted); }
.chat-rrhh-form { display: flex; gap: 0.4rem; padding: 0.6rem; border-top: 1px solid var(--color-line); }
.chat-rrhh-form textarea {
  flex: 1; resize: none; font-family: var(--font-body); font-size: 0.86rem;
  padding: 0.45rem 0.55rem; border: 1px solid var(--color-line); border-radius: 6px;
}
.chat-rrhh-form textarea:focus { outline: 2px solid var(--c-amarillo); border-color: var(--c-amarillo); }
@media (max-width: 600px) {
  .chat-rrhh-panel { right: 0.5rem; left: 0.5rem; width: auto; bottom: 3.8rem; height: 75vh; }
  .chat-rrhh-boton { right: 0.75rem; bottom: 0.75rem; }
}

/* --- Botón flotante de feedback (2026-09-29, js/feedback-widget.js) ---
   A la izquierda a propósito: el chat de RRHH ya ocupa la esquina inferior
   derecha (.chat-rrhh-boton) y este botón sale en TODAS las páginas. */
.feedback-boton {
  position: fixed; left: 1rem; bottom: 1rem; z-index: 900;
  width: 3rem; height: 3rem; border-radius: 999px; border: 0;
  background: var(--c-morado); color: var(--c-blanco); font-size: 1.3rem;
  box-shadow: 0 4px 14px rgba(34, 34, 33, 0.25); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.feedback-boton:hover { filter: brightness(1.08); }
.feedback-boton:disabled { cursor: wait; opacity: 0.75; }
.feedback-modal { max-width: 420px; }
.feedback-preview {
  display: block; width: 100%; border-radius: 4px; margin-bottom: 0.6rem;
  border: 1px solid var(--color-line);
}
.feedback-textarea { resize: vertical; min-height: 4.5rem; font-family: var(--font-body); margin-bottom: 0; }
@media (max-width: 600px) {
  .feedback-boton { left: 0.75rem; bottom: 0.75rem; }
}

/* «Personal de ETT por verificar» (envíos de las ETT sin puesto, 2026-09-30) */
.envios-ett-panel { border: 2px solid var(--color-secondary, #DE5014); border-radius: 8px; background: #fff7f0; padding: .75rem 1rem; margin: .75rem 0; }
.envios-ett-panel h3 { margin: 0 0 .25rem; }
.envios-ett-ayuda { margin: 0 0 .5rem; font-size: .85rem; color: var(--color-muted, #666); }
.envios-ett-lista { display: flex; flex-direction: column; gap: .5rem; }
.envio-fila { display: grid; grid-template-columns: minmax(12rem, 1.2fr) minmax(12rem, 1.4fr) minmax(8rem, 1fr) auto; gap: .25rem .75rem; align-items: center; background: #fff; border: 1px solid #e6d5c5; border-radius: 6px; padding: .5rem .75rem; }
.envio-origen-supervisor { color: #A68155; font-weight: 600; }
.envio-sin-colocar { color: #b3260e; font-weight: 600; }
.envio-nota { grid-column: 1 / -1; font-size: .85rem; color: var(--color-muted, #666); }
.envio-acciones { display: flex; gap: .5rem; align-items: flex-start; flex-wrap: wrap; }
.envio-form-inline { margin: 0; }
.envio-rechazo summary { list-style: none; cursor: pointer; }
.envio-rechazo summary::-webkit-details-marker { display: none; }
.envio-form-motivo { display: flex; flex-direction: column; gap: .35rem; margin-top: .4rem; min-width: 16rem; }
.envio-resumen { background: #f7f3ee; border-radius: 6px; padding: .5rem .75rem; }
.personal-ett td { background: #fff7f0; }
@media (max-width: 800px) { .envio-fila { grid-template-columns: 1fr; } }
