/* ============================================================
   LuxSOP · Lo que Bootstrap no cubre

   REGLA DE ADMISIÓN (spec §7):
   Si algo puede resolverse correctamente con Bootstrap, se resuelve con
   Bootstrap. Este archivo NO es el nuevo components.css.

   §A — Componentes LuxSop. Reusables (2+ pantallas), nombrados, documentados.
        Admisión: "Bootstrap deliberadamente no cubre esto."

   §B — Excepciones por pantalla. Scoped con .pantalla-<nombre>. Cada bloque
        lleva un comentario que responda "¿por qué no Bootstrap?".
        Admisión: una sola pantalla, sin equivalente en Bootstrap.

   Al cerrar cada lote se anota cuánto creció §B. Si crece de forma notoria,
   el problema no es ese lote: es que el catálogo de patrones está incompleto.
   Se arregla el patrón y se vuelve a aplicar, en vez de acumular excepciones.
   ============================================================ */


/* ══════════════════════════════════════════
   §A — Componentes LuxSop
   ══════════════════════════════════════════ */

/* ── .pagina ── Ancho de página.
   ¿Por qué no Bootstrap? Sus contenedores topan en 1320 px en pantallas xxl y no
   exponen variable para cambiarlo; `.container-xl` tampoco sirve, porque en xxl
   vuelve a crecer a 1320. LuxSop trabaja a 1120 (era `--page-max`): más ancho, las
   filas se estiran tanto que el ojo pierde el renglón.
   Uso: <div class="container-fluid pagina py-4">  ← container-fluid pone los
   gutters y el centrado; esta clase solo pone el tope. */
.pagina { max-width: 1120px; }


/* ── .pagina-movil ── Ancho de página para lo que se abre en el teléfono.
   El hermano de `.pagina`, para el recorrido de la operaria: `plan_trabajo/operario_panel`,
   `operario_dia` y `ejecucion`. Las tres las abre en el teléfono, y `.pagina` (1120) las
   dejaría con las tarjetas a lo ancho de un monitor.
   ¿Por qué no Bootstrap? Lo mismo que `.pagina`: sus contenedores no bajan de 540 ni
   exponen variable para fijarlo.
   Las tres lo llevaban en línea, cada una por su cuenta; a la tercera aparición cumple la
   regla de admisión de §A (2+ pantallas) y deja de ser un número suelto repetido.
   Uso: <div class="container pagina-movil pt-4"> */
.pagina-movil { max-width: 540px; }


/* ── .borde-punteado ── El recuadro de «agregar algo».
   ¿Por qué no Bootstrap? `border-dashed` no existe como utilidad en 5.3. El resto del
   recuadro —color, grosor, radio, hover— sí es Bootstrap (`btn btn-outline-* border-2`);
   esto es la única línea que le falta.
   El punteado no es adorno: distingue «aquí se agrega» de un botón normal, y las
   pantallas que lo usan tienen los dos a la vez. Nació en `.pantalla-ejecucion` el
   2026-09-15 y subió aquí el mismo día, con `propuesta_form` de segunda. */
.borde-punteado { border-style: dashed; }


/* ── .tabla-card ── Tabla como tarjeta.
   ¿Por qué no Bootstrap? `.table` es deliberadamente plana y no expone variables
   de fondo, radio ni sombra del contenedor. La tarjeta es identidad de LuxSop.

   OJO CON LA ESTRUCTURA — son DOS divs, no uno:
       <div class="tabla-card"><div class="table-responsive"><table class="table">
   El recorte de esquinas necesita `overflow:hidden`, y `.table-responsive` necesita
   `overflow-x:auto`. En el mismo elemento, `luxsop.css` carga después y el hidden
   gana, dejando la tabla sin scroll horizontal a 360 px. Anidados, el padre recorta
   y el hijo scrollea. */
.tabla-card {
  background: #fff;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(22, 37, 102, .06), 0 2px 6px rgba(22, 37, 102, .05);
}
.tabla-card .table { margin-bottom: 0; }
/* La tarjeta es BLANCA, y sin esta línea no se ve.
   Trampa de Bootstrap 5.3: `.table` declara `--bs-table-bg: var(--bs-body-bg)` y cada
   celda se pinta a sí misma de esa variable (`.table > * > * { background-color }`).
   O sea que las celdas tapan el `background:#fff` de arriba con el `#F5F7FF` del fondo
   de la página, y la tabla queda del MISMO tono que el papel: se ve tibia y no se
   despega. Apuntar la variable a blanco es lo que recorta la tarjeta contra el fondo.
   No se toca `--bs-body-bg`: el azulado del fondo sí se quiere, es el contraste. */
.tabla-card .table { --bs-table-bg: #fff; }
.tabla-card .table > thead > tr > th {
  background: #e9eaef;
  font-size: .72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: #646C80;
  border-bottom: 1px solid #E3E6EF;
  padding: .7rem 1rem;
  white-space: nowrap;
}
.tabla-card .table > tbody > tr > td { padding: .8rem 1rem; }
/* La primera fila no lleva línea arriba: la banda del encabezado ya separa. */
.tabla-card .table > tbody > tr:first-child > td { border-top: 0; }


/* ── .btn-ico ── Acción de fila.
   ¿Por qué no Bootstrap? `.btn-outline-*` dibuja un recuadro por cada ícono y una
   tabla con tres acciones por renglón se vuelve una reja. Aquí el botón es invisible
   en reposo y solo aparece al apuntarlo.
   Los 32 px de lado son el blanco táctil mínimo para la revisión a 360 px. */
.btn-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: none;
  color: #646C80;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.btn-ico:hover { background: #F1F3F9; color: #162566; }
.btn-ico--danger:hover { background: #fff5f5; color: #dc3545; }
.btn-ico:focus-visible { outline: 2px solid #162566; outline-offset: 1px; }

@media (prefers-reduced-motion: reduce) {
  .btn-ico { transition: none; }
}


/* ── .no-spin ── Campo numérico sin las flechitas de subir/bajar.
   ¿Por qué no Bootstrap? Las pinta el NAVEGADOR con un pseudo-elemento propio y no hay
   utilidad que las quite; hacen falta las tres declaraciones porque cada motor las
   expone distinto.
   Se usa donde el número se escribe, no se tantea: un precio se teclea completo, y en
   una celda de 120px las flechitas se comen el espacio del dato.
   Uso: <input type="number" class="form-control no-spin"> */
input.no-spin::-webkit-outer-spin-button,
input.no-spin::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input.no-spin {
  -moz-appearance: textfield;
  appearance: textfield;
}

/* ── .num-tabular ── Dígitos de ancho fijo.
   ¿Por qué no Bootstrap? No hay utilidad de `font-variant-numeric`.
   Los dígitos alineados en columna son lo que deja comparar de un vistazo, y además
   evitan que un número que cambia en su sitio —un contador— empuje lo que tiene al lado.
   SUBIÓ DE §B A §A el 2026-09-05: nació en el detalle de requisición y al convertir
   /admin/roles se volvió la segunda pantalla que lo pedía, que es la regla de admisión
   de esta sección.
   Uso: <td class="text-end num-tabular"> */
.num-tabular { font-variant-numeric: tabular-nums; }

/* ── .inp-orden ── Campo de la columna «Orden» en las tablas de fracciones.

   ¿Por qué no Bootstrap? `.form-control` es `width:100%` y no hay utilidad de ancho en
   píxeles: sin tope, la caja se estira a toda la columna, y un campo de 200 px para
   escribir «3» promete un dato largo que no existe. Mismo criterio que `.no-spin`.

   NACIÓ EN §B (`sop_evento_crear`) Y SUBIÓ A §A el 2026-09-09: `sop_crear` tiene la misma
   columna y el mismo JS de renumerado, y con eso cumple la regla de admisión. */
.inp-orden { max-width: 5rem; }

/* ── .punto ── Punto de color que acompaña a una etiqueta.
   ¿Por qué no Bootstrap? `.badge rounded-pill` es una píldora CON texto dentro; esto es
   solo la marca de color, y el texto va al lado en tinta normal. En una rejilla de doce
   columnas o en la leyenda de una gráfica, una píldora por renglón se lee como semáforo.
   SUBIÓ DE §B A §A el 2026-09-05: la rejilla de consumo de `almacen/por_planta` ya tenía
   uno idéntico y la leyenda de la dona del dashboard de incidencias lo necesitó igual.
   El COLOR lo pone quien lo usa: una clase de estatus, o `style` cuando sale de los datos.
   Uso: <span class="punto" style="background:#8b5cf6"></span> */
.punto {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  flex-shrink: 0;
}

/* ── .filo ── Filo de color en el borde izquierdo de una tarjeta o renglón.
   ¿Por qué no Bootstrap? `border-primary` y sus hermanas pintan los CUATRO lados: la
   tarjeta queda enmarcada de color y una lista de diez se lee como un semáforo. Aquí el
   color va solo en el filo izquierdo, que es lo que deja recorrer una columna con la vista
   y ver en qué anda cada renglón sin leer su pastilla.
   NACIÓ EN §A, no subió: `plan_trabajo/dia` (estado de la tarea) y `rutas/mi_ruta` (tipo
   de tarea) lo pidieron el mismo día, que es la regla de admisión de esta sección.
   El color sale de las variables de Bootstrap, así que sigue al tema en vez de duplicarlo.
   Uso: <div class="card filo filo-warning"> */
/* ── .tipo-extraordinario ── La insignia morada de «Extraordinario».
   ¿Por qué no Bootstrap? Su paleta semántica no tiene morado, y aquí el color ES la
   distinción: separa «Extraordinario» de «Regular» (verde) y «Consecuente» (azul), que van
   pegados en el mismo renglón.
   SUBIÓ DE §B A §A el 2026-09-08: `rutas/mi_ruta` lo tenía y `reportes/reporte_personal`
   —que es la pantalla a la que lleva— lo pidió idéntico, que es la regla de admisión.
   Uso: <span class="badge tipo-extraordinario fw-normal">Extraordinario</span> */
.tipo-extraordinario { background: #ede9fe; color: #5b21b6; }

/* ── .chip-morado / .chip-naranja ── Chips de color que Bootstrap no trae.
   ¿Por qué no Bootstrap? Bootstrap 5.3 tiene `bg-{c}-subtle` + `text-{c}-emphasis` solo
   para sus ocho colores semánticos; no hay morado ni naranja. Estas dos imitan ese mismo
   esquema (fondo claro, texto oscuro del mismo matiz) para que convivan con los chips de
   estado de Bootstrap sin desentonar. El morado reusa los valores de
   `.tipo-extraordinario`: un solo morado en el sistema, no dos parecidos.
   NACIÓ EN §A, no subió: Servicios Especiales las usa en el panel, el detalle y el
   calendario (estatus «autorizada» y chip «Vencida»).
   Los valores viven en variables para que el calendario (§B .pantalla-se-calendario)
   pinte sus barras con los MISMOS colores sin copiarlos.
   Uso: <span class="badge rounded-pill chip-morado">Autorizada</span> */
:root {
  --lx-morado-fondo: #ede9fe;  --lx-morado-texto: #5b21b6;
  --lx-naranja-fondo: #ffedd5; --lx-naranja-texto: #9a3412; --lx-naranja-borde: #ea580c;
}
.chip-morado  { background: var(--lx-morado-fondo);  color: var(--lx-morado-texto); }
.chip-naranja { background: var(--lx-naranja-fondo); color: var(--lx-naranja-texto); }

/* ── .herramientas-list ── La lista de chips que se recorta sola.
   La columna «Herramientas» de un kit puede traer dos chips o quince. En vez de dejar que
   ensanche la tabla o parta el renglón en cuatro líneas, se le fija un ancho, se esconde lo
   que no cabe y aparece un «+N» que expande.

   ¿Por qué no Bootstrap? Porque esto NO es apariencia, es el mecanismo. `colapsarLista()`
   en kits.js decide cuántos chips caben comparando `scrollWidth` contra `clientWidth`:

       if (lista.scrollWidth <= lista.clientWidth) return;   // caben todos → sin botón

   Esa comparación solo da un número distinto de cero si el contenedor tiene un ANCHO
   ACOTADO y `overflow:hidden`. Bootstrap tiene `d-flex flex-nowrap overflow-hidden` —y se
   usan, están en el marcado—, pero NO tiene utilidad de ancho en píxeles, y sin el ancho la
   medición siempre dice que todo cabe: el «+N» no sale nunca y los chips desbordan la
   tabla. Quitar estas líneas no despinta el widget: lo apaga.

   El nombre de la clase es CONTRATO: `kits.js` hace `querySelectorAll('.herramientas-list')`.

   NACIÓ EN §A, no subió: `catalogos/regulares/kits` y `catalogos/eventos/kits_eventos` la
   usan idéntica, que es la regla de admisión de esta sección.
   Uso: <div class="herramientas-list d-flex align-items-center gap-2">
   ⚠️ SIN `flex-nowrap` ni `overflow-hidden`: esas dos las pone la regla de abajo. Ver el
   comentario de `.herramientas-list` para saber por qué no pueden ir como utilidades. */
/* El ancho es un EQUILIBRIO, no un número mágico: es sitio que se le quita al resto de la
   tabla. Bajó de 340 a 300 px el 2026-09-14 porque con 340 el ID («KT-BA-001») no cabía en
   una línea y se partía en dos. Si vuelve a subir, revisar que el ID siga entero.

   ⚠️ `flex-wrap` y `overflow` van AQUÍ y NO como utilidades `flex-nowrap overflow-hidden`
   en el marcado. Las utilidades de Bootstrap llevan `!important`:

       .flex-nowrap    { flex-wrap: nowrap !important }
       .overflow-hidden{ overflow: hidden !important }

   y con ellas puestas, la regla `.expandido` de abajo NUNCA gana: al picar el «+N» los
   chips se quedaban en la misma línea en vez de bajar. Reportado por el usuario el
   2026-09-14 («solo se expanden en la misma fila»). Es la misma trampa que ya anotó el
   lote 1 con `d-flex`: una utilidad con `!important` no se puede alternar desde el JS. */
.herramientas-list           { width: 300px; max-width: 300px;
                               flex-wrap: nowrap; overflow: hidden; }
/* Expandido: los chips bajan de línea y se ven todos. */
.herramientas-list.expandido { flex-wrap: wrap; overflow: visible; }
/* La celda tiene que medir lo mismo que la lista o el ancho de arriba no se respeta. */
.col-herramientas        { width: 300px; vertical-align: top; }

/* ── Editor de pasos ── El asa de arrastre y el número del renglón.
   Los pasos de una metodología se reordenan arrastrando (SortableJS). Casi todo el
   renglón son utilidades —`d-flex align-items-center gap-3 p-3 mb-2 border rounded`—, y
   solo quedan dos cosas que Bootstrap no tiene:

   · `cursor` — no existe ninguna utilidad, y aquí el cursor ES la señal de que el renglón
     se puede arrastrar: sin él nadie descubre la función.
   · el ancho mínimo del número, para que «1.» y «10.» no descoloquen los campos de
     texto que van a su derecha. No hay utilidades de ancho en píxeles.

   `.drag-handle` es CONTRATO con SortableJS: va en su opción `handle`.

   NACIÓ EN §A, no subió: `catalogos/regulares/metodologias_fraccion` y
   `catalogos/eventos/metodologia_evento_detalle` lo tienen idéntico, que es la regla de
   admisión de esta sección.
   Uso: <div class="d-flex align-items-center gap-3 p-3 mb-2 border rounded">
          <span class="drag-handle text-secondary">⠿</span>
          <span class="paso-numero fw-semibold text-secondary">1.</span> … */
.drag-handle        { cursor: grab; }
.drag-handle:active { cursor: grabbing; }
.paso-numero        { min-width: 1.75rem; }

/* ── .filo ── (ver el bloque de abajo) */
.filo { border-left-width: 4px; }
.filo-primary   { border-left-color: var(--bs-primary); }
.filo-success   { border-left-color: var(--bs-success); }
.filo-warning   { border-left-color: var(--bs-warning); }
.filo-info      { border-left-color: var(--bs-info); }
.filo-danger    { border-left-color: var(--bs-danger); }
.filo-secondary { border-left-color: var(--bs-border-color); }


/* ── El editor del día ── Las reglas que comparten `rutas/plan_dia_form` y
   `rutas/plantilla_dia_form`.

   Están en §A y no en dos §B porque las DOS pantallas las usan: son el mismo editor, una
   para el día real y otra para la plantilla, con el 81 % de sus selectores iguales. Tenerlas
   aquí una sola vez es justo lo contrario de lo que las llevó a divergir — mientras vivían
   en dos `<style>` separados, un color se quedó sin pintar en una de ellas durante meses y
   nadie lo vio.

   ── .sidebar-captura ──
   ¿Por qué no Bootstrap? El panel mide 320 px fijos: sus tres formularios llevan `select`
   con nombres largos de área y subárea, y con un ancho en porcentaje la columna crece y
   encoge según la planta que se abra. A partir de `lg` se queda pegado arriba y scrollea
   solo; por debajo se apila, que es lo que lo hace usable en el teléfono. */
@media (min-width: 992px) {
  .sidebar-captura {
    width: 320px; flex: 0 0 320px;
    position: sticky; top: 0; height: 100vh; overflow-y: auto;
  }
}

/* ── .fila-* ── El color del renglón según el tipo de tarea.
   ¿Por qué no Bootstrap? Son DEGRADADOS, y no hay utilidad de gradiente por color
   (`bg-gradient` solo superpone un blanco translúcido). Distinguen de un vistazo las tareas
   que la operaria NO puede mover —inicio, receso, limpieza de equipo— de las que sí, y el
   filo de 4 px repite el dato en el borde.

   ⚠️ `fila-equipo` NO se llama `tipo-limpieza_equipo`, y ahí hubo un fallo que duró meses:
   el marcado de `plan_dia_form` armaba la clase con `|replace('_','-')`, generando
   `tipo-limpieza-equipo`, mientras el CSS declaraba `tipo-limpieza_equipo` CON GUION BAJO.
   Nunca coincidieron y ese verde no se pintó jamás. Ahora el nombre lo pone un mapa de
   Jinja en cada plantilla y no hay transformación que pueda desalinearlos. */
.fila-inicio {
  background: linear-gradient(135deg, #E3F2FD 0%, #BBDEFB 100%);
  border-left: 4px solid #2196F3;
}
.fila-receso {
  background: linear-gradient(135deg, #FFF9C4 0%, #FFF59D 100%);
  border-left: 4px solid #FBC02D;
}
.fila-equipo {
  background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
  border-left: 4px solid #66BB6A;
}
.fila-evento {
  background: linear-gradient(135deg, #FFF8F0 0%, #FFE0B2 100%);
  border-left: 4px solid #FFB74D;
}

/* ── Arrastrar para reordenar ──
   ¿Por qué no Bootstrap? No hay utilidades de `cursor` ni de `transform`, y el renglón que
   se arrastra necesita las dos. `.dragging` y `.drag-over` las alterna el JS: son ganchos. */
.asig-item        { cursor: grab; transition: transform .15s, box-shadow .15s, background .15s; }
.asig-item:active { cursor: grabbing; }
.asig-item.dragging {
  opacity: .5; transform: scale(1.02);
  box-shadow: 0 4px 12px rgba(0,0,0,.15); background: #f0f7ff;
}
/* El hueco donde va a caer: una línea gruesa arriba, con el margen negativo que compensa su
   propio grosor para que la lista no dé un salto al aparecer. */
.asig-item.drag-over { border-top: 3px solid var(--bs-primary); margin-top: -3px; }
.asig-item.no-arrastrable { cursor: default; opacity: .95; }
.asig-item.no-arrastrable .drag-handle { opacity: .3; cursor: not-allowed; }
.drag-handle { cursor: grab; }

/* ── option.ocupada / option.sin-sop ──
   ¿Por qué no Bootstrap? Un `<option>` lo pinta el SISTEMA OPERATIVO y no acepta utilidades
   ni casi nada: hay que teñirlo con una clase propia o no se puede. Son las subáreas ya
   asignadas (gris, deshabilitadas) y los casos sin SOP (ámbar). */
option.ocupada { background-color: #f1f1f1; color: #888; }
option.ocupada:disabled { opacity: .8; }
option.sin-sop { background-color: var(--bs-warning-bg-subtle); color: var(--bs-warning-text-emphasis); }


/* ══════════════════════════════════════════
   §B — Excepciones por pantalla
   ══════════════════════════════════════════ */

/* ── .pantalla-sin-permiso ── */

/* El «403» gigante de la pantalla de acceso denegado (templates/errores/403.html).
   Es UNA regla y solo esta pantalla la usa; todo lo demás de esa pantalla —centrado,
   botones, espaciado, tipografía del título— sale con utilidades de Bootstrap.

   ¿Por qué no Bootstrap? Porque no tiene escalón tipográfico para esto. `display-1` llega
   a 5rem pero hereda el color del texto: aquí el número NO es texto, es marca de agua, y
   lo que lo vuelve marca de agua es el color al 13% del navy. Eso no se puede armar con
   utilidades —`text-*` no da opacidades arbitrarias y `opacity-25` afectaría al elemento
   entero, no solo al color—, y el `letter-spacing` negativo tampoco tiene utilidad. */
.pantalla-sin-permiso .sinpermiso__codigo {
  font-size: 5.5rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.04em;
  color: rgba(22, 37, 102, .13);   /* --navy al 13%: marca de agua, no texto */
  margin-bottom: -.5rem;           /* el número se mete bajo el título, como en el mockup */
}

/* A 360 px, 5.5rem se come el ancho y empuja la página. El número es decorativo: encoge
   sin que se pierda nada. */
@media (max-width: 575.98px) {
  .pantalla-sin-permiso .sinpermiso__codigo { font-size: 3.75rem; }
}

/* ── .pantalla-instructivos ── */

/* Es la pantalla con más excepciones del lote 2, y casi todas son UNA sola decisión: la
   TAXONOMÍA DE COLORES no se convierte, se conserva verbatim.

   Esta pantalla tiene dos taxonomías propias y las dos son diseño de información, no
   decoración: el tipo de FRACCIÓN (admin / prod) y el tipo de DOCUMENTO (it / uh / tmo /
   ficha). Cada una pinta franja, fondo tintado, etiqueta y badge, y es con lo que la gente
   distingue de un vistazo qué está viendo.

   ¿Por qué no Bootstrap? No tiene equivalente para una taxonomía de cuatro familias.
   Mapearla a `bg-*-subtle` cambiaría los colores con los que ya se lee la pantalla, y el
   spec dice explícitamente que la migración no rediseña. Cae en §B por la regla de
   admisión: una sola pantalla, sin equivalente. */

/* ¿Por qué no Bootstrap? `row-cols-*` fija CUÁNTAS columnas hay por breakpoint; esto deriva
   el número del ancho disponible con `auto-fill minmax()`, que es otra cosa y Bootstrap no
   tiene. Importa aquí porque el número de tarjetas varía muchísimo —una fracción puede
   tener 1 documento o 12— y con un número fijo de columnas quedan huecos o renglones de
   una sola tarjeta. Se conservan como grid: además, así el JS sigue metiendo las tarjetas
   directo, sin envolver cada una en un `.col`. */
.pantalla-instructivos .frac-grid,
.pantalla-instructivos #docGrid {
  display: grid;
  gap: 14px;
}
.pantalla-instructivos .frac-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.pantalla-instructivos #docGrid   { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }

@media (max-width: 600px) {
  .pantalla-instructivos .frac-grid,
  .pantalla-instructivos #docGrid { grid-template-columns: 1fr; }
}

/* ¿Por qué no Bootstrap? No hay utilidades de `cursor` ni de sombra al pasar el mouse. La
   tarjeta ENTERA es el clic que abre el detalle —no hay botón «abrir»—, así que sin la
   manita y sin el realce no se lee que se puede picar. La caja (fondo, borde, radio) sí es
   `.card` de Bootstrap; esto es solo lo que le falta. */
.pantalla-instructivos .frac-card {
  cursor: pointer;
  transition: box-shadow .2s, border-color .2s;
}
.pantalla-instructivos .frac-card:hover { box-shadow: 0 4px 14px rgba(0,0,0,.1); border-color: #bbb; }
.pantalla-instructivos .frac-card.vacia { border-style: dashed; background: #fafafa; opacity: .85; }

/* ¿Por qué no Bootstrap? `.border-dashed` no existe como utilidad, ni un alto mínimo en
   píxeles. Es la tarjeta fantasma de «asociar»: se ve como un hueco por llenar, no como
   una tarjeta con contenido. */
.pantalla-instructivos .card-asociar {
  border: 1.5px dashed;
  background: transparent;
  cursor: pointer;
  min-height: 130px;
}
.pantalla-instructivos .card-asociar__icon { width: 32px; height: 32px; }
.pantalla-instructivos .card-asociar__icon svg { width: 16px; height: 16px; stroke: #888; fill: none; stroke-width: 2; }

/* Tipo de fracción */
.pantalla-instructivos .stripe-admin { border-left: 3px solid #1976d2; }
.pantalla-instructivos .stripe-prod  { border-left: 3px solid #e65100; }
.pantalla-instructivos .tipo-header-admin { background: #e3f2fd; color: #1976d2; }
.pantalla-instructivos .tipo-header-prod  { background: #fff3e0; color: #e65100; }
.pantalla-instructivos .punto-admin { background: #1976d2; }
.pantalla-instructivos .punto-prod  { background: #e65100; }
.pantalla-instructivos .card-asociar-admin { border-color: #93c5fd; }
.pantalla-instructivos .card-asociar-prod  { border-color: #fdba74; }

/* Tipo de documento: franja, fondo y etiqueta. Los tres van juntos por familia. */
.pantalla-instructivos .doc-card--it    { background: #eff6ff; }
.pantalla-instructivos .doc-card--uh    { background: #ecfdf5; }
.pantalla-instructivos .doc-card--tmo   { background: #fffbeb; }
.pantalla-instructivos .doc-card--ficha { background: #fff1f2; }
.pantalla-instructivos .doc-card--it    .doc-card__stripe { background: #dbeafe; }
.pantalla-instructivos .doc-card--uh    .doc-card__stripe { background: #d1fae5; }
.pantalla-instructivos .doc-card--tmo   .doc-card__stripe { background: #fef3c7; }
.pantalla-instructivos .doc-card--ficha .doc-card__stripe { background: #ffe4e6; }
.pantalla-instructivos .doc-card--it    .doc-card__label { color: #1d4ed8; }
.pantalla-instructivos .doc-card--uh    .doc-card__label { color: #065f46; }
.pantalla-instructivos .doc-card--tmo   .doc-card__label { color: #92400e; }
.pantalla-instructivos .doc-card--ficha .doc-card__label { color: #9f1239; }

/* ¿Por qué no Bootstrap? No hay utilidad de ancho en píxeles. La franja de color es lo que
   identifica la familia del documento antes de leer nada. */
.pantalla-instructivos .doc-card__stripe { width: 4px; }

/* ¿Por qué no Bootstrap? `.card` es `flex-direction: column` y trae `overflow: visible`.
   Esta tarjeta es una FILA (franja de color a la izquierda + contenido) y necesita recortar,
   o la franja se sale por la esquina redondeada. Dos declaraciones, no un componente nuevo. */
.pantalla-instructivos .doc-card {
  flex-direction: row;
  overflow: hidden;
}

/* ¿Por qué no Bootstrap? Es un menú que el JS CREA al vuelo y posiciona con `position:
   fixed` contra un anclaje arbitrario. El `.dropdown-menu` de Bootstrap exige la relación
   con un botón `data-bs-toggle` y su instancia de Popper, que este código no tiene: se
   abre desde una tarjeta pintada por JS. Convertirlo obligaría a reescribir el
   posicionamiento, que es justo lo que esta migración no debe tocar. */
.pantalla-instructivos .dropdown-gestionar {
  background: #fff;
  border: 0.5px solid #ddd;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,.12);
  min-width: 200px;
  overflow: hidden;
}
.pantalla-instructivos .dd-item {
  padding: 10px 14px;
  font-size: .83rem;
  cursor: pointer;
  border-bottom: 0.5px solid #f0f0f0;
  display: flex;
  align-items: center;
  gap: 10px;
  color: #333;
}
.pantalla-instructivos .dd-item:last-child { border-bottom: none; }
.pantalla-instructivos .dd-item:hover { background: #f9f9f9; }
.pantalla-instructivos .dd-item.danger { color: #b91c1c; }
.pantalla-instructivos .dd-item.danger:hover { background: #fff1f2; }
.pantalla-instructivos .dd-text strong {
  display: block;
  font-size: .83rem;
  font-weight: 600;
  line-height: 1.2;
}
.pantalla-instructivos .dd-text span {
  display: block;
  font-size: .72rem;
  color: #888;
  margin-top: 1px;
}
.pantalla-instructivos .dd-item.danger .dd-text strong { color: #b91c1c; }
.pantalla-instructivos .dd-item.danger .dd-text span { color: #b91c1c; opacity: .7; }

/* NO se migraron dos reglas que traía el <style> viejo, `.coder-pill` y `.nombre-it-pill`:
   ninguna de las dos se usa en el marcado ni en el JS. Ya estaban muertas antes de la
   conversión, y copiarlas aquí solo habría movido el cadáver de sitio. */

/* Los badges de familia. `.badge` de Bootstrap da la forma; el color es de la taxonomía. */
.pantalla-instructivos .badge-it    { background: #dbeafe; color: #1d4ed8; }
.pantalla-instructivos .badge-uh    { background: #d1fae5; color: #065f46; }
.pantalla-instructivos .badge-tmo   { background: #fef3c7; color: #92400e; }
.pantalla-instructivos .badge-ficha { background: #ffe4e6; color: #9f1239; }

/* ¿Por qué no Bootstrap? No tiene zona de soltar archivos. Es la MISMA que
   `.pantalla-incidencias .foto-drop`; con ésta ya son dos pantallas, así que cumple la
   regla de admisión de §A y debería unificarse ahí. NO se hace en esta conversión a
   propósito: `foto-drop` vive en una pantalla ya commiteada y revisada, y meterla en el
   mismo cambio que las 3,282 líneas de instructivos amplía el radio de daño sin necesidad.
   Queda anotado en la bitácora como el siguiente candidato a §A. */
.pantalla-instructivos .upload-area {
  border: 1.5px dashed #d1d5db;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.pantalla-instructivos .upload-area:hover { border-color: #3b82f6; background: #eff6ff; }
.pantalla-instructivos .upload-area input[type="file"] { display: none; }
.pantalla-instructivos .upload-area svg { width: 28px; height: 28px; stroke: #9ca3af; fill: none; stroke-width: 1.5; }

/* ¿Por qué no Bootstrap? No hay utilidad de tamaño en píxeles. Es el cuadrito tintado que
   lleva el ícono de cada opción del menú de gestión; el tinte cambia según la acción. */
.pantalla-instructivos .dd-icon { width: 28px; height: 28px; }
.pantalla-instructivos .dd-icon svg { width: 14px; height: 14px; fill: none; stroke-width: 2; }
.pantalla-instructivos .dd-icon--update    { background: #f0fdf4; }
.pantalla-instructivos .dd-icon--update    svg { stroke: #16a34a; }
.pantalla-instructivos .dd-icon--actualizar{ background: #fffbeb; }
.pantalla-instructivos .dd-icon--actualizar svg { stroke: #d97706; }
.pantalla-instructivos .dd-icon--unlink    { background: #fffbeb; }
.pantalla-instructivos .dd-icon--unlink    svg { stroke: #d97706; }
.pantalla-instructivos .dd-icon--delete    { background: #fff1f2; }
.pantalla-instructivos .dd-icon--delete    svg { stroke: #dc2626; }
.pantalla-instructivos .dd-icon--tmo   { background: #fef3c7; }
.pantalla-instructivos .dd-icon--uh    { background: #d1fae5; }
.pantalla-instructivos .dd-icon--ficha { background: #ffe4e6; }

/* ¿Por qué no Bootstrap? No hay utilidad de `max-height` en píxeles. La lista de UH puede
   traer decenas de renglones dentro de un modal: sin tope, el modal crece hasta salirse de
   la pantalla y los botones de abajo quedan fuera de alcance. */
.pantalla-instructivos .uh-list { max-height: 260px; }

/* ¿Por qué no Bootstrap? El seleccionado se marca con una barra INTERIOR a la izquierda, no
   con un borde: un borde movería el texto 3 px al seleccionar y la lista bailaría. */
.pantalla-instructivos .uh-list__item.selected { background: #eff6ff; box-shadow: inset 3px 0 0 #3b82f6; }


/* ── .pantalla-visor ── */

/* ¿Por qué no Bootstrap? No tiene este gris. El lienzo detrás de las hojas va en el gris
   oscuro con que todo visor de PDF pinta su mesa de trabajo (es el mismo de Chrome y de
   Acrobat): sobre blanco, una hoja blanca no se distingue de su fondo y se pierde dónde
   empieza y acaba cada página. No es color de marca, es la convención del componente. */
.pantalla-visor #pdf-viewer { background: #525659; }

/* ¿Por qué no Bootstrap? `<canvas>` es `inline` por omisión, así que hereda el espacio de
   línea y deja una franja bajo cada hoja. Y el ancho tiene que ser 100 % con alto
   automático para que la página conserve su proporción al escalarse: la utilidad `w-100`
   no basta porque también hay que soltar el alto que PDF.js le fija en píxeles. */
.pantalla-visor .pdf-page canvas {
  display: block;
  width: 100%;
  height: auto;
}


/* ── .pantalla-incidencias ── */

/* La ÚNICA pantalla más ancha que el resto del sistema (decisión del usuario, 2026-09-05).
   ¿Por qué no Bootstrap? `.pagina` de §A topa en 1120 porque a más ancho el ojo pierde el
   renglón; aquí la tabla son ONCE columnas y a 1120 vive scrolleando de lado.
   1320 y no un número inventado: es el tope del contenedor `xxl` de Bootstrap, o sea el
   siguiente escalón de la misma escala.

   VA TAMBIÉN EN EL DASHBOARD, y eso no es de más. `por_planta` tuvo su propio ancho (1210)
   y se quitó el 2026-09-01 justo por esto: se veía más ancha que sus vecinas y el salto
   se notaba al cambiar de pestaña. El panel y el dashboard de incidencias son un solo
   recorrido —hay un botón de ida y otro de vuelta—, así que o se ensanchan los dos o se
   reproduce el mismo defecto. */
.pantalla-incidencias .pagina,
.pantalla-inc-dashboard .pagina { max-width: 1320px; }

/* ¿Por qué no Bootstrap? No hay utilidad de `min-width` en píxeles. Son ONCE columnas de
   texto —fecha, hora, operario, categoría, tipo, área, subárea, evidencia, estatus,
   observaciones y acciones—: sin un piso, el navegador las estruja hasta que cada
   encabezado se parte en tres renglones. Con él, la tabla scrollea dentro de
   `.table-responsive` y la página no se mueve, que es el criterio de 360 px del spec §9. */
.pantalla-incidencias .t-incidencias { min-width: 1600px; }

/* ¿Por qué no Bootstrap? No hay utilidades de tamaño en píxeles ni de `object-fit`. La
   miniatura tiene que ser del MISMO tamaño en todos los renglones aunque las fotos vengan
   de un celular en cualquier proporción; sin `object-fit: cover` una foto vertical estira
   su renglón y la tabla queda con los renglones de alturas distintas. */
.pantalla-incidencias .evidencia-thumb {
  width: 52px;
  height: 40px;
  object-fit: cover;
  cursor: pointer;
}

/* ¿Por qué no Bootstrap? No tiene zona de arrastrar-y-soltar para archivos. El truco es un
   <input type="file"> transparente estirado sobre la caja: así toda la zona es el control
   —y en un celular, «toca para tomar la foto» abre la cámara— sin script de por medio. */
.pantalla-incidencias .foto-drop {
  border: 1.5px dashed #CDD2E0;
  padding: .9rem 1rem;
  cursor: pointer;
  position: relative;
  transition: border-color .15s, background .15s;
}
.pantalla-incidencias .foto-drop:hover { border-color: #162566; background: #F7F9FF; }
.pantalla-incidencias .foto-drop input[type="file"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  width: 100%;
  height: 100%;
}
.pantalla-incidencias .foto-preview { width: 100%; max-height: 130px; object-fit: cover; }


/* ── .pantalla-inc-dashboard ── */

/* ¿Por qué no Bootstrap? Chart.js mide el lienzo contra la ALTURA de su contenedor; si el
   padre no la declara, el `<canvas>` colapsa a 0 y la gráfica no se ve. Bootstrap no tiene
   utilidades de altura en píxeles (solo `h-25`…`h-100`, que son porcentajes del padre y
   aquí devuelven el mismo problema un nivel más arriba).
   Tres alturas y no una: la barra de operarios crece con la lista, las apiladas necesitan
   sitio para su leyenda de abajo, y la línea de fechas se lee mejor achatada. */
.pantalla-inc-dashboard .chart-area       { position: relative; height: 200px; }
.pantalla-inc-dashboard .chart-area-ancha { position: relative; height: 220px; }
.pantalla-inc-dashboard .chart-area-alta  { position: relative; height: 260px; }
.pantalla-inc-dashboard .donut-chart      { width: 140px; height: 140px; }

/* ¿Por qué no Bootstrap? No hay utilidad de ancho/alto en píxeles. Es el cuadro tintado
   que enmarca el ícono de cada tarjeta de indicador; el tinte y el redondeo sí son
   utilidades (`bg-*-subtle rounded-3`), el tamaño no. */
.pantalla-inc-dashboard .stat-icon { width: 42px; height: 42px; }


/* ── .pantalla-roles ── */

/* ¿Por qué no Bootstrap? No hay utilidades de `cursor` ni de `user-select`. La cabecera
   del módulo y el renglón del permiso son zonas de clic que no son botones —una abre el
   acordeón, el otro es una <label> que marca su casilla—, y sin la manita no se lee que
   se pueden picar. El `user-select` evita que abrir y cerrar a golpes deje media pantalla
   seleccionada en azul. */
.pantalla-roles .mod-h { cursor: pointer; user-select: none; }
.pantalla-roles .perm  { cursor: pointer; }

/* ¿Por qué no Bootstrap? No hay utilidad de `transform: rotate`. El chevron apunta a la
   derecha cerrado y hacia abajo abierto; es la única señal de que la cabecera se abre. */
.pantalla-roles .chev { transition: transform .2s; }
.pantalla-roles .mod.open .chev { transform: rotate(90deg); }

/* ── .pantalla-plan-trabajo ── */

/* ¿Por qué no Bootstrap? Es un CALENDARIO: siete columnas iguales que nunca se apilan y
   que no se reparten en doceavos. La rejilla de Bootstrap es flex sobre 12 columnas —7 no
   divide a 12— y `row-cols-*` llega hasta 6. Un `display:grid` de siete columnas lo
   resuelve en una línea; con Bootstrap habría que inventar anchos de 14.28 %.

   El `min-width` es lo que hace que a 360 px el mes SCROLLEE de lado (dentro del
   `overflow-x-auto` que lo envuelve) en vez de aplastar las siete columnas hasta que no
   quepa un título. Es el mismo criterio que `.lin-tabla` en las tablas anchas. */
.pantalla-plan-trabajo .calendario {
  display: grid;
  grid-template-columns: repeat(7, minmax(160px, 1fr));
  min-width: 1120px;
}

/* ¿Por qué no Bootstrap? No hay utilidad de alto mínimo. Sin este piso, un día sin tareas
   colapsa a la altura de su número y la semana queda como una escalera. */
.pantalla-plan-trabajo .cal-celda { min-height: 110px; }

/* ¿Por qué no Bootstrap? `.rounded-circle` redondea, pero el círculo necesita medida fija
   para no deformarse con un número de una o dos cifras. Las utilidades de tamaño de
   Bootstrap son porcentajes (`w-25`, `h-50`), no píxeles. */
.pantalla-plan-trabajo .cal-hoy {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ¿Por qué no Bootstrap? No hay utilidad de ancho mínimo en píxeles. Sin él, las flechas
   de mes se recorren al cambiar de «Mayo» a «Septiembre» y el control baila bajo el
   cursor justo donde uno va a volver a picar. */
.pantalla-plan-trabajo .mes-label { min-width: 160px; }

/* ¿Por qué no Bootstrap? No hay componente de avatar ni utilidades de tamaño en píxeles.
   El círculo con las iniciales necesita medida fija: con `w-*` (porcentajes) se deforma
   según el ancho de la tarjeta y deja de ser un círculo. */
.pantalla-plan-trabajo .avatar {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
}


/* ── .pantalla-reporte-personal ── */

/* ¿Por qué no Bootstrap? Este acordeón lo abre y lo cierra un JS propio que además carga
   las indicaciones por API la primera vez. El `collapse` de Bootstrap haría lo visual pero
   no lo otro, y cambiarlo obligaría a reescribir ese JS — que funciona y no es parte de
   una migración visual (spec §10). Se conservan los nombres de clase porque el JS los
   escribe, no solo los lee. */
.pantalla-reporte-personal .acc-item {
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  overflow: hidden;
  background: #fff;
}
.pantalla-reporte-personal .acc-head { background: #f8f9fa; cursor: default; user-select: none; }
.pantalla-reporte-personal .acc-body { display: none; }
.pantalla-reporte-personal .acc-item.open .acc-body { display: block; }
.pantalla-reporte-personal .acc-item.is-checked { border-color: #bbf7d0; background: #f0fdf4; }
.pantalla-reporte-personal .acc-item.is-checked .acc-head { background: #dcfce7; }

/* La MISMA taxonomía de tipos de tarea que `mi_ruta`, y aquí en su tono pálido original:
   el reporte se lee sentado, con la pantalla completa, y no necesita el escalón extra que
   el usuario pidió para la lista del teléfono (2026-09-08). Si algún día se igualan, que
   sea una decisión y no un descuido. */
.pantalla-reporte-personal .acc-item.tipo-inicio          { border-left: 4px solid #90CAF9; background: #F1F8FF; }
.pantalla-reporte-personal .acc-item.tipo-inicio .acc-head { background: #E3F2FD; }
.pantalla-reporte-personal .acc-item.tipo-receso          { border-left: 4px solid #FFD54F; background: #FFFEF7; }
.pantalla-reporte-personal .acc-item.tipo-receso .acc-head { background: #FFF9E6; }
.pantalla-reporte-personal .acc-item.tipo-limpieza-equipo          { border-left: 4px solid #81C784; background: #F1F8F4; }
.pantalla-reporte-personal .acc-item.tipo-limpieza-equipo .acc-head { background: #E8F5E9; }
.pantalla-reporte-personal .acc-item.tipo-evento          { border-left: 4px solid #FFB74D; background: #FFF8F0; }
.pantalla-reporte-personal .acc-item.tipo-evento .acc-head { background: #FFF3E0; }

/* ¿Por qué no Bootstrap? El botón de completar tiene TRES estados y dos de ellos los
   escribe el JS (`is-checked` al palomear, `is-pending` mientras la petición viaja o
   espera en la cola offline). Un `btn-outline-success` cubriría el primero; el pulso del
   pendiente —que es lo que le dice a la operaria «esto todavía no se guardó»— no tiene
   equivalente. Va sobre `.btn.btn-sm`, así que hereda tamaño, tipografía y foco. */
.pantalla-reporte-personal .check-btn {
  border: 2px solid var(--bs-border-color);
  background: #fff;
  color: var(--bs-body-color);
}
.pantalla-reporte-personal .check-btn:hover { border-color: var(--bs-success); background: #f0fdf4; }
.pantalla-reporte-personal .check-btn.is-checked {
  background: var(--bs-success);
  border-color: var(--bs-success);
  color: #fff;
}
.pantalla-reporte-personal .check-btn.is-checked:hover { background: #166534; border-color: #166534; }

/* El reloj de arena solo se ve mientras la petición está en vuelo. */
.pantalla-reporte-personal .sync-indicator { display: none; }
.pantalla-reporte-personal .check-btn.is-pending .sync-indicator { display: inline; }

/* Pendiente: verde atenuado que late. Sincronizado: verde pleno y quieto. */
.pantalla-reporte-personal .check-btn.is-checked.is-pending {
  opacity: .65;
  animation: lux-pending-pulse 1.4s ease-in-out infinite;
}
@keyframes lux-pending-pulse {
  0%, 100% { opacity: .65; }
  50%      { opacity: .85; }
}
.pantalla-reporte-personal .check-btn.is-checked:not(.is-pending) { opacity: 1; animation: none; }

/* ¿Por qué no Bootstrap? `.spacer` no es estilo, es un ANCLA: el JS inserta la insignia de
   completado justo después de este elemento (`spacer.insertAdjacentElement('afterend')`).
   Se queda como un flex-grow sin contenido. */
.pantalla-reporte-personal .spacer { flex: 1; }


/* ── .pantalla-mi-ruta ── */

/* ¿Por qué no Bootstrap? Su paleta semántica no tiene morado, y aquí el morado ES la
   distinción: separa «Extraordinario» de los tres niveles de limpieza —que son grises de
   intensidad creciente— y del resto de los tipos de tarea. Reutilizar `primary` o `dark`
   lo volvería indistinguible de lo que ya está a su lado. (El morado de la INSIGNIA
   «Extraordinario» se fue a §A el 2026-09-08: lo comparte con el reporte del día. Este de
   aquí es el del NIVEL de limpieza, que solo existe en esta pantalla.) */
.pantalla-mi-ruta .nivel-extraordinario { background: #7c3aed; color: #fff; }

/* LA TAXONOMÍA DE TIPOS DE TAREA SE CONSERVA VERBATIM (2026-09-08).
   ¿Por qué no Bootstrap? Se intentó y el usuario lo rechazó el mismo día: traducidos a
   `bg-primary-subtle` y `bg-info-subtle`, «Inicio» y «Evento» quedaban los dos en la
   familia del azul —el navy de marca tiñe todos los `*-subtle` hacia el lila— y dos tipos
   distintos se leían como el mismo. Estos cuatro colores son pasteles elegidos uno por uno
   para distinguirse ENTRE SÍ, no para significar «primario» o «informativo»; es diseño de
   información, igual que la taxonomía de `instructivos`.

   El ancho del filo lo sigue poniendo `.filo` de §A: aquí solo se cambia el color.

   UN ESCALÓN MÁS QUE EL REPORTE (elección del usuario, 2026-09-08). Los fondos son los
   mismos tonos del reporte de ruta subidos un paso —del 50 al 100 de la escala Material—,
   porque a tamaño de teléfono los del 50 casi no se despegaban del blanco. Las dos
   pantallas ya no son idénticas y es a propósito: el reporte se lee sentado y esta se lee
   caminando.

   COMPLETAR NO CAMBIA EL FONDO DE UNA FILA CON TIPO (decisión del usuario, 2026-09-08,
   sobre tres variantes maquetadas). Lo que cambia es el BORDE, que pasa al tono firme de
   su familia, más la palomita verde y la hora. La alternativa era subir el fondo otro
   escalón al marcarla, y se descartó: el color de la fila dice QUÉ ES la tarea —inicio,
   receso, evento— y esa respuesta no cambia porque se haya hecho.

   Las filas SIN tipo —los SOP normales, que son la mayoría— sí cambian de fondo: pasan de
   blanco a verde. Ahí el color estaba libre y se usa para el estado. */
.pantalla-mi-ruta .marcada { background: #f0fdf4; border-color: #bbf7d0; }

.pantalla-mi-ruta .tipo-inicio           { border-left-color: #90CAF9; background: #E3F2FD; }
.pantalla-mi-ruta .tipo-inicio.marcada   { border-color: #64B5F6; }
.pantalla-mi-ruta .tipo-receso           { border-left-color: #FFD54F; background: #FFF9E6; }
.pantalla-mi-ruta .tipo-receso.marcada   { border-color: #FFCA28; }
.pantalla-mi-ruta .tipo-limpieza_equipo         { border-left-color: #81C784; background: #E8F5E9; }
.pantalla-mi-ruta .tipo-limpieza_equipo.marcada { border-color: #66BB6A; }
.pantalla-mi-ruta .tipo-evento           { border-left-color: #FFB74D; background: #FFF3E0; }
.pantalla-mi-ruta .tipo-evento.marcada   { border-color: #FFA726; }


/* ── .pantalla-empleados ── */

/* El ancho del modal de empleados. Bootstrap solo ofrece escalones —500 (normal) y 800
   (`modal-lg`)—: con el normal los pares de campos quedan estrujados y con `modal-lg` el
   modal se lee como una ventana enorme para ocho campos, que es lo que reportó el usuario
   el 2026-09-08. Se pone con la MISMA variable que usan esos dos escalones, así que no
   reconstruye nada de Bootstrap: le cambia el número.

   580 y no menos: los pares de campos («ID del empleado» + «Planta», «Username» + «Rol»)
   viven en `col-md-5`/`col-md-7`, y por debajo de ~560 el segundo de cada par empieza a
   cortar su etiqueta. Se llegó bajando de 800 a 640 y de 640 a 580 con el usuario viendo. */
.pantalla-empleados #modal-empleado { --bs-modal-width: 580px; }


/* ── .pantalla-plantas ── */

/* ¿Por qué no Bootstrap? La lista de divisiones dentro del modal necesita alto
   máximo con scroll propio. Bootstrap tiene .overflow-auto pero ninguna utilidad
   de max-height, y el valor depende del alto del modal. */
.pantalla-plantas #divs-body { max-height: 320px; overflow: auto; }

/* ¿Por qué no Bootstrap? No hay utilidad de letter-spacing. Los códigos de
   planta y de división son de 2 letras y sin el espaciado se leen apelmazados. */
.pantalla-plantas .codigo { letter-spacing: .05em; }


/* ── .pantalla-por-planta ──
   La pantalla con más excepciones de toda la migración, y no por descuido: su rejilla
   de consumo es una hoja de cálculo —ancho fijo repartido en %, celdas que se editan en
   su sitio, columnas de cálculo tintadas— y nada de eso lo expresa Bootstrap. */

/* Esta pantalla ensanchaba `.pagina` a 1210px para darle aire a la rejilla de consumo.
   Se quitó a petición del usuario (2026-09-01): quedaba visiblemente más ancha que las
   demás pantallas del módulo y el salto se notaba al cambiar de pestaña. La rejilla no
   se desborda por esto: sus columnas son porcentajes sobre `table-layout: fixed`, así
   que se reparten los 1120 igual, solo con las celdas algo más justas. */

/* Geometría fija: las dos sub-pestañas (químicos e insumos) quedan idénticas y la tabla
   nunca desborda, porque los anchos ya no dependen del contenido de cada una. Los % de
   cada columna los pone el <colgroup> que arma el JS (busca `var ANCHO`). */
.pantalla-por-planta .t-consumo { width: 100%; table-layout: fixed; }

/* Con geometría fija, lo que no cabe tiene que poder partirse o se sale de su celda.
   `break-word` y no `anywhere`: éste último parte a media palabra en cuanto puede y
   dejaba el encabezado como "UNIDA / D". */
.pantalla-por-planta .t-consumo td,
.pantalla-por-planta .t-consumo th { overflow-wrap: break-word; }

/* OJO CON LA ESPECIFICIDAD — esta es la trampa de esta pantalla.
   §A pinta los encabezados con `.tabla-card .table > thead > tr > th` (0,2,3): en
   mayúsculas, a .72rem, con 1rem de padding y `nowrap`. Un selector corto como
   `.pantalla-por-planta .t-consumo th` (0,2,1) PIERDE contra eso y la rejilla compacta
   se descuadraría en silencio — que es exactamente lo que ya le pasó una vez a este
   CSS cuando vivía dentro de la plantilla. Por eso va con el camino completo.
   El `nowrap` se apaga a propósito: con ancho fijo, un encabezado que no parte empuja
   la columna. */
.pantalla-por-planta .tabla-card .table.t-consumo > thead > tr > th {
  padding: .45rem .6rem;
  font-size: .8rem;
  letter-spacing: 0;
  text-transform: none;
  white-space: normal;
}
.pantalla-por-planta .tabla-card .table.t-consumo > tbody > tr > td {
  padding: .45rem .6rem;
  font-size: .85rem;
}

/* Un respiro entre el código y el nombre (2026-09-02). Los dos son texto que termina y
   empieza pegado al borde de su celda, y con .6rem de cada lado "QU-HI-DS-001" y "Alpha HP"
   se leían casi como una sola cadena.
   Va en el padding y NO en el ancho de la columna: ensanchar `codigo` en el JS movería toda
   la geometría de la rejilla, que está calibrada para sumar 100.
   El encabezado entra en el mismo selector para que "Químico" no se despegue de los nombres
   que titula. Y el camino va completo por lo que advierte el comentario de arriba: un
   selector corto pierde contra el `padding` de estas dos reglas y esto no aplicaría. */
.pantalla-por-planta .tabla-card .table.t-consumo > thead > tr > th.cell-nombre,
.pantalla-por-planta .tabla-card .table.t-consumo > tbody > tr > td.cell-nombre {
  padding-left: 2.5rem;
}

/* Estos tres SÍ no se parten: un número o un código cortado en dos no se lee. */
.pantalla-por-planta .t-consumo .num,
.pantalla-por-planta .t-consumo .cell-codigo,
.pantalla-por-planta .t-consumo .badge { white-space: nowrap; }

/* La única excepción al `white-space: normal` de los encabezados: «Acción» se partía en
   «Acció / n». El camino va COMPLETO a propósito —y con la clase al final— porque tiene
   que ganarle a la regla de arriba (0,4,3); un `.pantalla-por-planta .t-consumo th.col-accion`
   pierde y esto no aplicaría. Para que el nowrap no empuje la columna, el ancho de
   `accion` en el JS ya subió a 6.4% (busca `var ANCHO`): los dos cambios van juntos. */
.pantalla-por-planta .tabla-card .table.t-consumo > thead > tr > th.col-accion {
  white-space: nowrap;
}

/* Sin `nowrap`: con geometría fija, "Solicitar 58 piezas" se saldría de su columna en
   vez de ensancharla. Que se parta en dos renglones dentro del botón. */
.pantalla-por-planta .t-consumo td .btn-sm {
  padding: .25rem .45rem;
  font-size: .75rem;
  line-height: 1.25;
}

/* Colores tipo hoja de cálculo: promedio, requerido y existencia resaltados, y la
   existencia además en el color de su estatus. ¿Por qué no Bootstrap? `table-*` tiñe
   la fila entera, no una columna, y aquí lo que se compara de un vistazo es la columna. */
.pantalla-por-planta .t-consumo td.col-calc,
.pantalla-por-planta .t-consumo td.col-existencia { background: rgba(37, 99, 235, .08); }
.pantalla-por-planta .t-consumo th.col-calc,
.pantalla-por-planta .t-consumo th.col-existencia { background: rgba(37, 99, 235, .16); }
.pantalla-por-planta .t-consumo td.col-existencia { font-weight: 700; }
.pantalla-por-planta .t-consumo tr.r-suficiente td.col-existencia     { color: #16a34a; }
.pantalla-por-planta .t-consumo tr.r-insuficiente td.col-existencia   { color: #f59e0b; }
.pantalla-por-planta .t-consumo tr.r-sin_existencia td.col-existencia { color: #dc2626; }

/* Consumo editable en la propia rejilla: la celda se ve como celda, no como formulario,
   hasta que se toca (ahí se marca en ámbar para no perder de vista lo no guardado).
   ¿Por qué no `form-control-sm`? Ese trae su propio padding y su alto mínimo, pensados
   para un formulario; aquí el campo tiene que caber en una celda de 5.75% de ancho. */
.pantalla-por-planta input.cons-cell {
  width: 100%;
  max-width: 3.2rem;
  text-align: center;
  padding: .2rem;
  font-size: .78rem;
  border: 1px solid #CDD2E0;
  border-radius: 6px;
  background: #fff;
  color: #2E3444;
}
.pantalla-por-planta input.cons-cell:focus {
  outline: none;
  border-color: #162566;
  box-shadow: 0 0 0 .2rem rgba(22, 37, 102, .15);
}
/* El amarillo se aclaró un paso el 2026-09-02, de #fef9c3 a #fefce8. La celda no se
   apaga por eso: lo que grita «esto no se ha guardado» es el BORDE ámbar y la negrita,
   y el fondo solo acompaña. Si se aclara más, el fondo deja de distinguirse del blanco
   de la celda normal y el aviso se queda sostenido por el borde solo. */
.pantalla-por-planta input.cons-cell.sucio {
  border-color: #f59e0b;
  background: #fefce8;
  font-weight: 700;
}

/* Estatus como punto de color + texto, SIN fondo: en una rejilla con doce columnas, una
   píldora con fondo por renglón la convierte en un semáforo ilegible. */
.pantalla-por-planta .estatus-txt { display: inline-flex; align-items: center; gap: 6px; }
/* La forma y el tamaño del punto SE MUDARON A §A como `.punto` el 2026-09-05, cuando la
   leyenda del dashboard de incidencias pidió el mismo. Aquí quedan solo los colores, que
   sí son de esta pantalla: son los tres estatus de existencia. */
.pantalla-por-planta .edot-ok  { background: #16a34a; }
.pantalla-por-planta .edot-med { background: #f59e0b; }
.pantalla-por-planta .edot-bad { background: #dc2626; }

/* La barra de «Guardar» del modo captura. ¿Por qué no `d-flex`? Las utilidades de
   display de Bootstrap llevan `!important` y le ganarían al `display:none` inline que
   el JS prende y apaga para mostrarla — la barra se quedaría visible siempre. */
.pantalla-por-planta .cons-acciones {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-top: 1rem;
}
.pantalla-por-planta .cons-acciones .btn { margin-left: auto; }


/* ── .pantalla-requisicion-form ── */

/* ¿Por qué no Bootstrap? No tiene utilidad de `cursor`. Los renglones se abren para
   corregirlos arriba, y eso tiene que verse ANTES del clic: sin la manita, nadie
   descubre que la fila es interactiva. */
.pantalla-requisicion-form tbody tr[data-editar] { cursor: pointer; }

/* ¿Por qué no Bootstrap? Marca CUÁL renglón se está corrigiendo. El fondo se pone por
   la variable de estado de la tabla —no con `background`, que el hover repintaría— y se
   repite en `:hover` a propósito: `.table-hover` lo sobrescribiría al pasar el mouse y
   la fila abierta perdería su marca justo cuando la estás señalando.
   La barra lateral va como `border-left` y no como `box-shadow`: el `box-shadow` de la
   celda ya lo usa Bootstrap para pintar ese fondo, y ponerle otro lo borraría. */
.pantalla-requisicion-form tr.fila-editando,
.pantalla-requisicion-form tr.fila-editando:hover { --bs-table-bg-state: #E8EDFB; }
.pantalla-requisicion-form tr.fila-editando > td:first-child {
  border-left: 3px solid #162566;
}


/* ── .pantalla-requisicion-detalle ── */

/* ¿Por qué no Bootstrap? No hay utilidad de `min-width` en píxeles.

   HISTORIA, PORQUE ESTO YA DIO DOS VUELTAS. La tabla tuvo `table-layout:fixed` con
   las nueve columnas declarando ancho, para que no se reacomodara según lo largo
   que fuera el nombre del producto. El 2026-08-31 se quitó: con un nombre corto
   («Papel toalla») los 260 px fijos de Producto abrían un hueco muerto enorme
   contra la cantidad, y eso pesaba más que la consistencia entre requisiciones.

   Hoy las columnas toman lo que necesitan. Lo único que queda es este `min-width`,
   y NO es decorativo: sin él, a 360 px las nueve columnas se apretujan hasta partir
   cada palabra en su propia línea en vez de scrollear dentro de `.table-responsive`
   (criterio de cierre del spec §9.4). */
.pantalla-requisicion-detalle .lin-tabla { min-width: 980px; }

/* ¿Por qué no Bootstrap? No hay utilidad de max-width en píxeles, y `.form-control`
   es `width:100%`: el campo del precio se estiraba a todo lo ancho de su columna, que
   con las columnas al contenido es tan ancha como el encabezado «P. UNITARIO». Una
   caja de 200 px para escribir «50» promete un texto largo que no existe.

   AQUÍ VIVÍA `.zona`, el fondo azul de las dos celdas que llena compras. Se quitó el
   2026-08-31 y no conviene reponerlo: `almacen.requisiciones.cotizar` (proveedor) y
   `…crear` (precio) son candados DISTINTOS, así que a quien solo tiene el segundo se
   le tintaba una sola columna y quedaba un bloque de color suelto a media tabla. */
.pantalla-requisicion-detalle input[data-precio-linea] { max-width: 120px; }

/* Los dígitos tabulares SE MUDARON A §A el 2026-09-05 como `.num-tabular`: al convertir
   /admin/roles se volvieron la segunda pantalla que los pedía y ahí cumplen la regla de
   admisión. Las celdas de esta pantalla llevan ahora esa clase en vez de `.num`. */

/* Las flechitas del campo de precio SE MUDARON A §A el 2026-09-02: la pantalla de
   precios de referencia captura el mismo tipo de dato en la misma clase de celda, y con
   eso cumple la regla de admisión de §A —dos pantallas o más—. Busca `.no-spin` allá. */


/* ── .pantalla-precios ── */

/* ¿Por qué no Bootstrap? No hay utilidad de max-width en píxeles, y `.form-control` es
   `width:100%`: sin tope, la caja se estira a toda la columna. Una caja de 200 px para
   escribir «20» promete un texto largo que no existe — el mismo criterio y el mismo
   motivo que el precio del renglón en el detalle de la orden, unas líneas más arriba.
   Aquí son 90 y no 120 porque esta columna no lleva importes: son precios unitarios de
   producto, y con las flechitas ya fuera caben siete dígitos de sobra. */
.pantalla-precios input[data-precio] {
  max-width: 90px;
  display: inline-block;
}


/* ── .pantalla-seleccionar-planta ── */

/* ¿Por qué no Bootstrap? No hay utilidad de hover: `shadow-sm`/`shadow` pintan una sombra
   fija, no una que aparezca al acercarse. Y aquí el realce no es adorno — es la ÚNICA
   señal de que las tarjetas son botones. `.card` sobre un `<button>` se ve idéntica a una
   tarjeta de solo lectura, así que sin esto la pantalla no dice que se puede hacer clic.
   Son las 3 únicas reglas que sobreviven del <style> viejo de esa plantilla. */
.pantalla-seleccionar-planta .planta-btn {
  transition: border-color .14s, box-shadow .14s, transform .14s;
}
.pantalla-seleccionar-planta .planta-btn:hover {
  border-color: var(--bs-primary);
  box-shadow: 0 6px 20px rgba(var(--bs-primary-rgb), .12);
  transform: translateY(-2px);
}
.pantalla-seleccionar-planta .planta-btn:active { transform: translateY(0); }


/* ── .pantalla-sop-evento-crear ── */

/* `.inp-orden` SE MUDÓ A §A el 2026-09-09: al convertir `sop_crear` se volvió la segunda
   pantalla que lo pide —la misma columna «Orden», con el mismo JS de renumerado— y ahí
   cumple la regla de admisión de §A. Búscala allá. */


/* ── .pantalla-sop-panel ── */

/* ¿Por qué no Bootstrap? Esta pantalla tiene IDENTIDAD DE COLOR PROPIA que no sale de la
   paleta del sistema: verde para el SOP Regular, naranja para el SOP de Evento. Los dos
   colores distinguen los dos flujos de un vistazo —cada pestaña, su botón y el filo de su
   tarjeta de resultado—, y el spec §9 es explícito en que la migración NO rediseña.
   Queda anotado como decisión pendiente del usuario: si algún día los dos flujos se
   alinean al navy del sistema, este bloque entero desaparece. */
.pantalla-sop-panel {
  --sop-verde:          #2d6a4f;
  --sop-verde-claro:    #eaf3de;
  --sop-naranja:        #d96f2e;
  --sop-naranja-claro:  #fdf0e6;
}

/* Los dos botones de acción. Bootstrap 5.3 los lee de `--bs-btn-*`, no de una clase de
   color, así que se tematizan igual que `.btn-primary` en tema.css. */
.pantalla-sop-panel .btn-sop-regular {
  --bs-btn-bg: var(--sop-verde);          --bs-btn-border-color: var(--sop-verde);
  --bs-btn-hover-bg: #255a42;             --bs-btn-hover-border-color: #255a42;
  --bs-btn-active-bg: #1e4c37;            --bs-btn-active-border-color: #1e4c37;
  --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}
.pantalla-sop-panel .btn-sop-evento {
  --bs-btn-bg: var(--sop-naranja);        --bs-btn-border-color: var(--sop-naranja);
  --bs-btn-hover-bg: #c25f22;             --bs-btn-hover-border-color: #c25f22;
  --bs-btn-active-bg: #a8511d;            --bs-btn-active-border-color: #a8511d;
  --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}

/* El filo de la tarjeta de resultado. El ancho lo pone `.filo` de §A; aquí solo el color,
   porque estos dos no están en la paleta de `--bs-*`. */
.pantalla-sop-panel .filo-sop-regular { border-left-color: var(--sop-verde); }
.pantalla-sop-panel .filo-sop-evento  { border-left-color: var(--sop-naranja); }

/* Las pestañas. La caja la arman utilidades (`d-flex`, `flex-fill`, `p-3`, `border-start`);
   lo único que no puede darse con utilidades es el TINTE del estado activo, que es donde
   vive la distinción verde/naranja. La insignia y la pista solo existen en la activa. */
.pantalla-sop-panel .tab-btn { cursor: pointer; background: var(--bs-tertiary-bg); }
.pantalla-sop-panel .tab-btn.active { cursor: default; }
.pantalla-sop-panel .tab-name { color: var(--bs-secondary-color); }
.pantalla-sop-panel .tab-badge,
.pantalla-sop-panel .tab-hint { display: none; }
.pantalla-sop-panel .tab-badge {
  font-size: .68rem; font-weight: 700; letter-spacing: .06em; color: #fff;
}
.pantalla-sop-panel .tab-btn.active .tab-badge { display: inline-flex; }
.pantalla-sop-panel .tab-btn.active .tab-hint  { display: block; }

.pantalla-sop-panel .tab-btn.active[data-tab="regular"] { background: var(--sop-verde-claro); }
.pantalla-sop-panel .tab-btn.active[data-tab="regular"] .tab-name,
.pantalla-sop-panel .tab-btn.active[data-tab="regular"] .tab-hint { color: var(--sop-verde); }
.pantalla-sop-panel .tab-btn.active[data-tab="regular"] .tab-badge { background: var(--sop-verde); }

.pantalla-sop-panel .tab-btn.active[data-tab="evento"] { background: var(--sop-naranja-claro); }
.pantalla-sop-panel .tab-btn.active[data-tab="evento"] .tab-name,
.pantalla-sop-panel .tab-btn.active[data-tab="evento"] .tab-hint { color: var(--sop-naranja); }
.pantalla-sop-panel .tab-btn.active[data-tab="evento"] .tab-badge { background: var(--sop-naranja); }

/* Las pastillas de dato. `.badge` de Bootstrap es una etiqueta chica; éstas son cajas de
   lectura, con el alto de un control de formulario, que se leen en fila junto al botón.
   Son las mismas que ya existían y no cambian de forma en esta conversión. */
.pantalla-sop-panel .pill {
  display: inline-flex; align-items: center; gap: .6rem;
  min-height: 46px; padding: 0 .9rem;
  border: 1px solid var(--bs-border-color); background: #fff;
  border-radius: 999px; font-size: .98rem; font-weight: 600; line-height: 1;
}
.pantalla-sop-panel .pill-ok   { border-color: #cde8d5; background: #eef9f0; color: #226b3d; }
.pantalla-sop-panel .pill-warn { border-color: #ffe8a1; background: #fff8e1; color: #7a5b00; }
.pantalla-sop-panel .card-result-regular .pill-ok { border-color: #c0dd97; background: var(--sop-verde-claro);   color: var(--sop-verde); }
.pantalla-sop-panel .card-result-evento  .pill-ok { border-color: #f5c4b3; background: var(--sop-naranja-claro); color: var(--sop-naranja); }


/* ── .pantalla-sop-elementoset ── */

/* ¿Por qué no Bootstrap? La tabla tiene SEIS columnas y tres son selectores. Dentro de
   `.table-responsive` el ancho lo reparte el navegador, y sin un mínimo los tres se
   estrujan hasta que «KT-BA-001 — Kit Barrer» se lee como «KT-…». Con el mínimo la tabla
   rueda de lado, que es justo lo que `.table-responsive` está ahí para permitir. */
.pantalla-sop-elementoset .sel-kit,
.pantalla-sop-elementoset .sel-receta,
.pantalla-sop-elementoset .sel-consumo { min-width: 170px; }


/* ── .pantalla-asignacion ── */

/* Para quién es un renglón: todo el tipo o una sola operaria.

   ¿Por qué no Bootstrap? `.badge` trae su propia escala de color y su propio peso; estas
   dos son etiquetas de DATO, del mismo tamaño que el texto de la celda, y lo que tienen
   que hacer es oponer dos categorías —«todas» contra «una»— de un vistazo. El par
   azul/ámbar es el mismo que se maquetó y se aprobó en el mockup.

   La fila sombreada acompaña a la píldora ámbar en vez de sustituirla: el color solo no
   dice QUÉ significa, y la píldora sola se pierde en una tabla larga.

   Vive en §B —una sola pantalla la usa— y sube a §A el día que una segunda la pida. */
.pantalla-asignacion .quien { font-size: .74rem; font-weight: 600; padding: .12rem .5rem;
                              border-radius: 20px; display: inline-block; white-space: nowrap; }
.pantalla-asignacion .quien--todas { background: #E4E9FB; color: #2440A4; }
.pantalla-asignacion .quien--una   { background: #F6E7C4; color: #7A5B10; }
.pantalla-asignacion .fila-propia td { background: #FBF7EC; }


/* ── .pantalla-areas-subareas ── El aviso de «subárea heredada».

   Al escribir un código de subárea, la pantalla contesta en vivo con uno de CUATRO
   estados. Tres son de Bootstrap: ya existe → `alert-success`, es nueva → `alert-info`,
   hay un problema → `alert-danger`. El cuarto, «se hereda del glosario», iba en MORADO.

   ¿Por qué no Bootstrap? Sus ocho alertas no incluyen morado, y las que quedan libres
   no sirven: `alert-warning` y `alert-secondary` dirían «cuidado» y «da igual», y éste
   no es ni lo uno ni lo otro — es el único de los cuatro que no habla de si el código
   está libre, sino de DE DÓNDE viene. Por eso el morado lo separaba de los otros tres a
   simple vista, y ése era su trabajo.

   Se conserva el color exacto que tenía: la migración no rediseña (spec §9). Es la ÚNICA
   excepción que dejó esta pantalla, que llegó con 103 reglas propias. Los tonos son los
   de `alert-*` de Bootstrap aplicados al morado: fondo claro, texto oscuro del mismo
   matiz. Sube a §A el día que una segunda pantalla necesite un aviso morado. */
.pantalla-areas-subareas .alerta-heredado {
  background: #e8daef;
  color: #6c3483;
}


/* ── .pantalla-ejecucion ── El hueco de la barra fija.
   El punteado de `.upload-label` que vivía aquí subió a `.borde-punteado` en §A el
   2026-09-15, cuando `propuesta_form` pidió el mismo recuadro. */

/* ¿Por qué no Bootstrap? La barra de «Marcar como completada» va `fixed-bottom`, así que
   sale del flujo y tapa el final de la página. El hueco tiene que medir lo que mide la
   barra (~75 px con su padding) y la escala de espaciado de Bootstrap se queda corta:
   `pb-5` son 48 px y dejarían el textarea medio tapado.
   El selector va al hijo directo a propósito: la barra TAMBIÉN lleva `.pagina-movil` —la
   reusa para centrarse sobre el mismo ancho— y con `.pantalla-ejecucion .pagina-movil` se
   habría puesto el hueco a sí misma. */
.pantalla-ejecucion > .container { padding-bottom: 6rem; }


/* ── .pantalla-propuesta ── Anchos de campo que Bootstrap no expresa.

   ¿Por qué no Bootstrap? Sus utilidades de ancho son porcentajes (`w-25`, `w-50`) o el
   contenido (`w-auto`); no hay ninguna que diga «este campo mide 100 px». Y aquí la medida
   importa: los tres o cuatro campos de un renglón van en fila, y si cada uno se ajusta a su
   contenido la fila baila cada vez que la operaria escribe un número más largo.

   Los valores son los que ya tenía la pantalla en `style=`, sin redondear (spec §9: la
   migración no rediseña). */
.pantalla-propuesta .campo-cantidad   { width: 100px; }
.pantalla-propuesta .campo-costo      { width: 140px; }
.pantalla-propuesta .campo-cantidad-q { width:  70px; }
.pantalla-propuesta .campo-unidad     { width: 110px; }
.pantalla-propuesta .input-costo      { max-width: 90px; }
.pantalla-propuesta .btn-existe       { width:  70px; }

/* ¿Por qué no Bootstrap? Lo mismo que `.pagina-movil` de §A, con otro número: esta pantalla
   se abre en el teléfono, pero lleva renglones de tres y cuatro campos en fila y a 540 px no
   caben. 600 es lo que tenía. No sube a §A porque, por ahora, es de una sola pantalla. */
.pantalla-propuesta > .container { max-width: 600px; }

/* ¿Por qué no Bootstrap? La columna de importes del desglose tiene que medir lo mismo en
   todos los renglones para que los números queden alineados a la derecha en columna; sin un
   mínimo, cada importe se ajusta a su propio ancho y la columna se desalinea. `text-end` ya
   lo alinea dentro de su caja, pero no iguala las cajas. Es el `min-width` que tenía. */
.pantalla-propuesta .item-amt { min-width: 60px; }


/* ── .pantalla-se-panel ── */

/* ¿Por qué no Bootstrap? Bootstrap 5.3 no tiene utilidad de cursor. El renglón completo
   de una actividad lleva a su detalle (el código también es un <a> de verdad, para teclado
   y clic central); sin la manita nadie adivina que el renglón es clicable. */
.pantalla-se-panel tbody tr[data-href] { cursor: pointer; }

/* ¿Por qué no Bootstrap? Bootstrap 5.3 no trae line-clamp (solo `text-truncate`, que corta
   en UN renglón). La descripción se corta a DOS con puntos suspensivos; el texto completo
   va en el `title`. El ancho mínimo la vuelve la columna más ancha: sin él, con la tabla
   en layout automático, las columnas de chips y fechas le ganaban espacio. */
.pantalla-se-panel .col-descripcion { min-width: 16rem; }
.pantalla-se-panel .desc-2-renglones {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}


/* ── .pantalla-se-calendario ── */

/* ¿Por qué no Bootstrap? Las barras las dibuja FullCalendar (static/vendor/fullcalendar)
   con sus propias variables (--fc-event-*) y pinta el texto en su nodo interno
   .fc-event-main: las clases de chip de Bootstrap no llegan ahí. Aquí solo se le pasan
   los MISMOS colores de los chips de estatus: los de Bootstrap (--bs-*-bg-subtle /
   --bs-*-text-emphasis) y los de §A (--lx-*). La clase `ev-<estatus>` la pone
   se_calendario.js. */
.pantalla-se-calendario .fc-event.ev-autorizada {
  --fc-event-bg-color: var(--lx-morado-fondo); --fc-event-border-color: var(--lx-morado-fondo);
  --fc-event-text-color: var(--lx-morado-texto);
}
.pantalla-se-calendario .fc-event.ev-en_proceso {
  --fc-event-bg-color: var(--bs-warning-bg-subtle); --fc-event-border-color: var(--bs-warning-bg-subtle);
  --fc-event-text-color: var(--bs-warning-text-emphasis);
}
.pantalla-se-calendario .fc-event.ev-detenida {
  --fc-event-bg-color: var(--bs-danger-bg-subtle); --fc-event-border-color: var(--bs-danger-bg-subtle);
  --fc-event-text-color: var(--bs-danger-text-emphasis);
}
.pantalla-se-calendario .fc-event.ev-terminada {
  --fc-event-bg-color: var(--bs-success-bg-subtle); --fc-event-border-color: var(--bs-success-bg-subtle);
  --fc-event-text-color: var(--bs-success-text-emphasis);
}
/* Fuera de plazo (vencida, o terminada después de la estimada): borde naranja de 2 px.
   El color de fondo sigue siendo el de su estatus. */
.pantalla-se-calendario .fc-h-event.ev-fuera-plazo { border: 2px solid var(--lx-naranja-borde); }
/* En la vista de lista (móvil) FullCalendar pinta un punto con el borde del evento. */
.pantalla-se-calendario .fc-list-event.ev-fuera-plazo .fc-list-event-dot { border-color: var(--lx-naranja-borde); }

/* Botones de la barra (‹ › Hoy). ¿Por qué no Bootstrap? Los dibuja FullCalendar, no son
   .btn; su tamaño sale de `.fc .fc-button` y su color de sus variables --fc-button-*.
   Se les dan los valores de un `btn btn-sm btn-outline-secondary` (padding, letra y radio
   de btn-sm; gris de contorno que se rellena al apuntar) leyendo las variables de
   Bootstrap. Sin el tema bootstrap5 de FullCalendar: pediría Bootstrap Icons. */
.pantalla-se-calendario .fc {
  --fc-button-text-color: var(--bs-secondary-color);
  --fc-button-bg-color: transparent;
  --fc-button-border-color: var(--bs-border-color);
  --fc-button-hover-bg-color: var(--bs-secondary-bg);
  --fc-button-hover-border-color: var(--bs-border-color);
  --fc-button-active-bg-color: var(--bs-tertiary-bg);
  --fc-button-active-border-color: var(--bs-border-color);
}
.pantalla-se-calendario .fc .fc-button {
  padding: .25rem .5rem;
  font-size: .875rem;
  line-height: 1.5;
  border-radius: var(--bs-border-radius-sm);
}
.pantalla-se-calendario .fc .fc-toolbar { align-items: center; gap: .5rem; }

/* ── .pantalla-ofertas-comparar ── Comparar ofertas: lista con panel (2026-09-28).

   ¿Por qué no Bootstrap? Tres piezas no tienen equivalente:
   · La fila activa de la lista. `list-group-item.active` pinta la fila de azul relleno con
     texto blanco, y aquí el chip de estado (verde/ámbar/gris) tiene que seguir leyéndose:
     la activa se marca con fondo tenue y una barra a la izquierda, sobre `aria-current`,
     que es lo que también anuncia el lector de pantalla.
   · La tarjeta de oferta: su zona de datos es un <label> que elige con un clic (el radio
     va dentro); el equivalente y la evidencia quedan fuera del label. `.card` no da el estado «elegida» (borde doble en el azul de la marca) ni
     el «no se puede elegir» atenuado sin volverla ilegible.
   · El precio grande: ningún escalón de Bootstrap da 1.35rem en negritas con cifras
     tabulares.
   Nada de esto toca `display` de los paneles: se ocultan SOLO con el atributo `hidden`. */
.pantalla-ofertas-comparar .comparar-lista {
  border-right: 1px solid var(--bs-border-color);
}
@media (max-width: 767.98px) {
  .pantalla-ofertas-comparar .comparar-lista {
    border-right: 0;
    border-bottom: 1px solid var(--bs-border-color);
  }
}
.pantalla-ofertas-comparar .comparar-item {
  display: block; width: 100%; text-align: left;
  background: transparent; border: 0; border-top: 1px solid var(--bs-border-color);
  padding: .75rem 1rem; color: inherit;
}
.pantalla-ofertas-comparar .comparar-item:first-child { border-top: 0; }
.pantalla-ofertas-comparar .comparar-item:hover { background: var(--bs-tertiary-bg); }
.pantalla-ofertas-comparar .comparar-item:focus-visible {
  outline: 2px solid var(--bs-primary); outline-offset: -2px;
}
.pantalla-ofertas-comparar .comparar-item[aria-current="true"] {
  background: #EEF1FB; box-shadow: inset 3px 0 0 var(--bs-primary);
}
.pantalla-ofertas-comparar .oferta-card {
  display: flex; flex-direction: column; gap: .5rem;
  border: 1px solid var(--bs-border-color); border-radius: 10px;
  padding: .8rem .9rem; background: #fff;
}
/* La zona que elige: el <label> con el radio y los datos. El resto de la tarjeta
   (equivalente, evidencia) no elige: no lleva cursor de mano. */
.pantalla-ofertas-comparar .oferta-elegir {
  display: flex; flex-direction: column; gap: .35rem; cursor: pointer; margin: 0;
}
.pantalla-ofertas-comparar .oferta-no .oferta-elegir { cursor: default; }
.pantalla-ofertas-comparar .oferta-card:hover { border-color: #9AA7DA; }
.pantalla-ofertas-comparar .oferta-card.oferta-elegida {
  border: 2px solid var(--bs-primary); background: #EEF1FB; padding: calc(.8rem - 1px) calc(.9rem - 1px);
}
.pantalla-ofertas-comparar .oferta-card.oferta-no {
  background: var(--bs-tertiary-bg); color: var(--bs-secondary-color);
}
.pantalla-ofertas-comparar .oferta-precio {
  font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.2;
}
.pantalla-ofertas-comparar .oferta-mensaje { white-space: pre-line; }
/* La marca de la IA va dentro del precio grande: sin esto hereda su 1.35rem y «Llenada por
   la IA» se vuelve un letrero (prueba con la usuaria, 2026-10-07). */
.pantalla-ofertas-comparar .oferta-precio .badge { font-size: .72rem; font-weight: 600; }
/* «De dónde salió cada dato» (Etapa 2, opción B del mockup aprobado el 2026-10-07): un
   <details> dentro de la tarjeta, fuera del <label> que elige. Bootstrap no estiliza
   <details>; aquí solo el separador, el resumen como enlace y la lista dato → cita. */
.pantalla-ofertas-comparar .oferta-fuentes { border-top: 1px dashed var(--bs-border-color); padding-top: .45rem; }
.pantalla-ofertas-comparar .oferta-fuentes summary {
  cursor: pointer; color: var(--bs-primary); font-weight: 500; list-style: none;
}
.pantalla-ofertas-comparar .oferta-fuentes summary::-webkit-details-marker { display: none; }
.pantalla-ofertas-comparar .oferta-fuentes summary::before { content: "▸ "; }
.pantalla-ofertas-comparar .oferta-fuentes[open] summary::before { content: "▾ "; }
.pantalla-ofertas-comparar .oferta-fuentes summary:focus-visible {
  outline: 2px solid var(--bs-primary); outline-offset: 2px;
}
.pantalla-ofertas-comparar .oferta-fuentes dl {
  display: grid; grid-template-columns: max-content 1fr; gap: .3rem .75rem; margin-top: .5rem;
}
.pantalla-ofertas-comparar .oferta-fuentes dt { font-weight: 600; color: var(--bs-primary); }
.pantalla-ofertas-comparar .oferta-fuentes dd { margin: 0; min-width: 0; }
.pantalla-ofertas-comparar .oferta-fuentes q {
  quotes: "«" "»"; background: var(--bs-tertiary-bg); border-radius: 4px; padding: 0 .3rem;
}
.pantalla-ofertas-comparar .comparar-panel h2:focus { outline: none; }


/* Mensajes de WhatsApp agrupados: los de un episodio que espera la respuesta del proveedor
   («¿de cuál me habla?») en la bandeja (plan 2026-10-09, Tarea 9, «2A»), y los de una orden
   en su panel lateral (Tarea 10, «C»). */
.pantalla-whatsapp-mensajes .msg-dentro,
.pantalla-ordenes .msg-dentro {
  border-left: 3px solid var(--bs-border-color); padding-left: .75rem;
}
.pantalla-ordenes .panel-whatsapp { --bs-offcanvas-width: 460px; }
