/* ===================================================================
   ADEI ERP — Estilos base
   Colores oficiales de ADEI (definidos en CLAUDE.md).
   Mantener esta identidad visual desde el primer momento.
   =================================================================== */

:root {
  --adei-navy:        #16264D; /* navy principal */
  --adei-fondo-osc:   #0E1B38; /* fondo oscuro */
  --adei-azul-medio:  #1E3A6E; /* azul medio */
  --adei-fondo-claro: #F4F6FA; /* fondo claro */
  --adei-verde:       #10B981; /* verde (ok / éxito) */
  --adei-rojo:        #EF4444; /* rojo (error / alerta) */
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  background: var(--adei-fondo-claro);
  color: var(--adei-navy);
}

/* Cabecera superior con el navy de ADEI */
.adei-cabecera {
  background: var(--adei-navy);
  color: #fff;
  padding: 14px 28px;
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}

.adei-cabecera .marca-enlace {
  display: flex;
  align-items: baseline;
  gap: 12px;
  text-decoration: none;
  color: #fff;
}

.adei-cabecera .marca {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 1px;
}

.adei-cabecera .subtitulo {
  font-size: 13px;
  opacity: 0.75;
  font-weight: 400;
}

/* Barra de navegación entre módulos */
.adei-nav {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.adei-nav a {
  color: #fff;
  text-decoration: none;
  font-size: 14px;
  padding: 7px 14px;
  border-radius: 8px;
  opacity: 0.85;
}

.adei-nav a:hover {
  background: var(--adei-azul-medio);
  opacity: 1;
}

/* ── Zona central de contenido (B1, 2026-08-04) ──
   Estaba clavada en 980 px. Con el lateral de 234, en un monitor de 1920 se quedaba casi
   la mitad de la pantalla en blanco a los lados.

   ⚠️ EL TOPE POR DEFECTO SUBE, PERO SIGUE HABIENDO TOPE. 1180 da aire a fichas y
   formularios sin que un párrafo llegue a 1.900 px de ancho, que se lee peor que a 900 —
   y en un formulario deja la etiqueta a un palmo de su casilla.

   Las pantallas de TABLA piden lo contrario, y lo piden ellas: ver `.ancho-completo`. */
.adei-contenido {
  max-width: 1180px;
  margin: 32px auto;
  padding: 0 24px;
}

/* ── El ancho de las pantallas de trabajo ──
   Sin tope: presupuesto, certificación, catálogo, suministros y compañía son tablas de
   muchas columnas, y cada píxel que se les quita es una columna que hay que ir a buscar
   con el scroll horizontal.

   ⚠️ NO quita el `overflow-x: auto` de `.tabla-scroll`, y no debe: en un portátil de 1366
   esas tablas siguen sin caber. Lo que hace es que en un monitor grande **no haga falta**. */
.adei-contenido.ancho-completo {
  max-width: none;
}

.adei-tarjeta {
  background: #fff;
  border: 1px solid #e3e8f0;
  border-radius: 12px;
  padding: 32px;
  box-shadow: 0 6px 20px rgba(14, 27, 56, 0.06);
}

.adei-tarjeta h1 {
  margin-top: 0;
  color: var(--adei-navy);
}

/* Etiqueta verde de "todo correcto" */
.adei-ok {
  display: inline-block;
  background: var(--adei-verde);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  padding: 4px 12px;
  border-radius: 999px;
  margin-bottom: 18px;
}

/* Pie con datos de contacto de ADEI */
.adei-pie {
  text-align: center;
  color: var(--adei-azul-medio);
  font-size: 13px;
  margin: 40px 0 24px;
}

/* ===================================================================
   Componentes de los módulos (listas, fichas, formularios)
   =================================================================== */

/* Cabecera de cada sección: título a la izquierda, acciones a la derecha */
.cabecera-seccion {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.cabecera-seccion h1 {
  margin: 0;
  font-size: 24px;
}

.cabecera-seccion .contador {
  display: inline-block;
  background: var(--adei-fondo-claro);
  border: 1px solid #d8e0ee;
  color: var(--adei-azul-medio);
  font-size: 14px;
  font-weight: 600;
  padding: 1px 10px;
  border-radius: 999px;
  margin-left: 6px;
  vertical-align: middle;
}

/* Botones */
.boton {
  display: inline-block;
  background: #fff;
  border: 1px solid #d3dbe8;
  color: var(--adei-navy);
  font-size: 14px;
  font-weight: 600;
  padding: 9px 16px;
  border-radius: 8px;
  cursor: pointer;
  text-decoration: none;
}

.boton:hover { border-color: var(--adei-azul-medio); }

.boton-primario {
  background: var(--adei-navy);
  border-color: var(--adei-navy);
  color: #fff;
}
.boton-primario:hover { background: var(--adei-azul-medio); }

.boton-peligro {
  background: #fff;
  border-color: var(--adei-rojo);
  color: var(--adei-rojo);
}
.boton-peligro:hover { background: var(--adei-rojo); color: #fff; }

/* Tabla de listados */
.tabla {
  width: 100%;
  border-collapse: collapse;
  background: #fff;
  border: 1px solid #e3e8f0;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 6px 20px rgba(14, 27, 56, 0.06);
}

.tabla th, .tabla td {
  text-align: left;
  padding: 12px 16px;
  border-bottom: 1px solid #eef2f8;
  font-size: 14px;
}

.tabla th {
  background: var(--adei-fondo-claro);
  color: var(--adei-azul-medio);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.tabla tbody tr:last-child td { border-bottom: none; }
.fila-clic { cursor: pointer; }
.fila-clic:hover { background: #f7f9fc; }

/* Etiquetas de colores (cliente / proveedor / contacto) */
.etiqueta {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: 999px;
  margin: 1px 2px;
  background: #e8edf6;
  color: var(--adei-azul-medio);
}
.etiqueta-cliente   { background: #e7f0ff; color: #1E3A6E; }
.etiqueta-proveedor { background: #e6f7f0; color: #0a7a55; }
.etiqueta-contacto  { background: #f3eafe; color: #6b3fa0; }
.etiqueta-oficio    { background: #fff3e0; color: #9a5b00; }

/* 📨 UNA PARTIDA QUE YA SE SACO A LICITAR (2026-09-01). Va pegada a su casilla bloqueada:
   sin la etiqueta, lo que se ve es una casilla que no se enciende -- «el ERP no me hace
   caso». Discreta a proposito: es una explicacion, no una alarma. */
.etiqueta-licitada {
  display: inline-block; margin-left: 4px; padding: 0 4px; border-radius: 4px;
  background: #eef2f8; color: #1E3A6E; font-size: .72em; text-decoration: none;
  vertical-align: middle; white-space: nowrap;
}
.etiqueta-licitada:hover { background: #dde6f5; }
/* La de una licitacion YA CERRADA es historia, no un freno: se puede volver a pedir. */
.etiqueta-licitada-vieja { background: #f2f2f2; color: #666; }

/* 📝 EL ALCANCE DE UNA LINEA DE LICITACION (2026-09-01). Plegado y discreto: con 33 lineas,
   treinta y tres parrafos abiertos convierten la pantalla de comparar en un muro. */
.lic-alcance { margin-top: 3px; }
.lic-alcance > summary { cursor: pointer; color: #666; font-size: .8em; }
.lic-alcance textarea { width: 100%; min-width: 260px; font-size: .85em; margin: 4px 0; }
.lic-alcance-solo-ver { color: #666; font-style: italic; }
/* Estado de las obras */
.etiqueta-activa    { background: #e6f7f0; color: #0a7a55; }
.etiqueta-archivada { background: #eceff4; color: #6b7280; }
/* 🧪 OBRA DE PRUEBA (2026-09-11). Ámbar y no rojo: no es un error ni una alarma, es un dato
   de la obra. El rojo de la casa (#EF4444) significa «algo va mal» y aquí no va nada mal —
   lo que dice es que `partir_limpio.py` la vaciará. */
.etiqueta-prueba    { background: #fef3c7; color: #92400e; }

/* Filtro por estado (Obras): fila de botones activa/archivada/todas */
.filtro-estado {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}

/* Código de obra en el listado (referencia interna, discreta) */
.codigo {
  font-family: "Consolas", "SFMono-Regular", monospace;
  font-size: 12px;
  color: var(--adei-azul-medio);
}

/* ── Presupuesto en árbol ── */
.etiqueta-capitulo    { background: #e7f0ff; color: #1E3A6E; }
.etiqueta-subcapitulo { background: #eef2fa; color: #3a4a6b; }
.etiqueta-partida     { background: #f4f6fa; color: #6b7280; }
.etiqueta-borrador    { background: #fff3e0; color: #9a5b00; }
.etiqueta-aprobado    { background: #e6f7f0; color: #0a7a55; }

.contexto-obra { padding: 16px 24px; margin-bottom: 16px; }
.contexto-obra .datos { grid-template-columns: 110px 1fr; margin: 0; }

.tabla-presupuesto td { vertical-align: top; }
.fila-nivel-0 { background: #f6f9ff; }
.fila-nivel-0 .nodo-titulo strong { font-weight: 800; }
.fila-nivel-1 .nodo-titulo strong { font-weight: 700; }
.nodo-titulo { display: inline-block; }
.nodo-texto { color: var(--adei-azul-medio); font-size: 13px; margin-top: 4px; white-space: pre-wrap; }
/* Marca material / mano de obra por partida (Suministros, Fase 4). */
.partida-marca { display: flex; gap: 6px; margin-top: 5px; flex-wrap: wrap; }
.partida-marca form { margin: 0; }
.marca-btn { font-size: 11px; padding: 2px 8px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--adei-borde, #dbe1ec); background: #fff; color: var(--adei-gris, #6b7280); white-space: nowrap; }
.marca-btn:hover { border-color: var(--adei-azul-medio); }
.marca-btn.marca-on { background: #e7f0ff; border-color: var(--adei-azul-medio); color: var(--adei-azul-medio); font-weight: 700; }

/* LA ETIQUETA DE GREMIO de una partida (Gantt · paso 0B). Vive junto a las marcas
   de material/mano de obra: es otra etiqueta, no es dinero. Sin gremio va apagado;
   con gremio se enciende, para que de un vistazo se vea lo que falta por etiquetar. */
.gremio-sel { font-size: 11px; padding: 2px 8px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--adei-borde, #dbe1ec); background: #fff;
  color: var(--adei-gris, #6b7280); max-width: 190px; }
.gremio-sel:hover { border-color: var(--adei-azul-medio); }
.gremio-sel.gremio-on { background: #fff3e0; border-color: #9a5b00; color: #9a5b00; font-weight: 700; }

/* ── Resumen del presupuesto POR GREMIO (Gantt · paso 0C) ── */
/* La fila «sin gremio» se resalta: no es un gremio más, es lo que falta por
   etiquetar (y lo que se quedaría fuera de la planificación). */
.fila-sin-gremio { background: #fff8ec; }
.fila-sin-gremio td { color: #7a4f00; }

/* Barra del peso de cada gremio sobre el total (de un vistazo: quién manda). */
.barra-peso {
  width: 100%; min-width: 54px; height: 7px; background: #eef2f8;
  border-radius: 999px; overflow: hidden; margin-bottom: 3px;
}
.barra-peso-relleno { height: 100%; background: var(--adei-azul-medio); border-radius: 999px; }
.peso-num { font-size: 11px; color: var(--adei-gris, #6b7280); }

/* Recordatorio de partidas sin gremio: avisa, NO bloquea. */
.aviso-gremios {
  background: #fff8ec;
  border: 1px solid #f0d9ae;
  color: #7a4f00;
  padding: 10px 16px;
  border-radius: 8px;
  margin-bottom: 16px;
  font-size: 14px;
}

/* Las casillas de «¿qué gremios hace?» en la ficha de un proveedor (paso 0F).
   Son muchas (una por gremio), así que van en columnas y con scroll si hace falta. */
.gremios-casillas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 2px 12px;
  max-height: 240px;
  overflow-y: auto;
  padding: 10px 12px;
  border: 1px solid #dfe4ee;
  border-radius: 8px;
  background: #fff;
}

.gremios-casillas .check-inline {
  font-size: 13px;
  font-weight: 400;
}

/* LAS ENTRADAS EN OBRA de un gremio (Gantt · paso 0E). Plegado: lo normal es que un
   gremio entre UNA vez, y esa mayoría no tiene que ver ningún ruido. */
.entradas-gremio > summary {
  cursor: pointer;
  font-size: 13px;
}

.lista-entradas {
  margin: 8px 0;
  padding-left: 20px;
  font-size: 13px;
}

.lista-entradas li {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 4px;
}

.lista-entradas li form {
  display: inline-flex;
  gap: 4px;
  margin: 0;
}

/* El reparto del importe de un gremio dividido, dentro del resumen por gremio. */
.fila-entrada-gremio {
  background: #fafbfd;
  font-size: 13px;
  color: #4a5568;
}

.entrada-flecha {
  color: #94a3b8;
  padding-left: 18px;
}

.entrada-num {
  color: #64748b;
  margin-right: 6px;
}

/* Proponer un gremio que no está en la lista (Gantt · paso 0D). Va plegado para
   no distraer: solo lo abre quien de verdad echa en falta un oficio. */
.gremio-proponer {
  margin: 0 0 16px;
  padding: 8px 14px;
  background: var(--fondo-claro, #f4f6fa);
  border: 1px solid #dfe4ee;
  border-radius: 8px;
  font-size: 14px;
}

.gremio-proponer > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--navy, #16264d);
}

.gremio-proponer .form-inline {
  margin-top: 10px;
}

/* Mini-formularios dentro del desplegable de Acciones de cada nodo */
.nodo-acciones > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--adei-azul-medio);
}
.nodo-acciones[open] > summary { margin-bottom: 8px; }
.mini-form { display: flex; gap: 6px; margin-bottom: 6px; flex-wrap: wrap; }
.mini-form input[type="text"] {
  flex: 1; min-width: 140px; font: inherit; font-size: 13px;
  padding: 6px 9px; border: 1px solid #d3dbe8; border-radius: 6px;
}
.mini-form-col {
  display: flex; flex-direction: column; gap: 6px;
  margin: 8px 0; padding: 8px 0; border-top: 1px solid #eef2f8;
}
.mini-form-col input, .mini-form-col textarea {
  font: inherit; font-size: 13px; padding: 6px 9px;
  border: 1px solid #d3dbe8; border-radius: 6px;
}
.acciones-fila-nodo { display: flex; gap: 4px; }
.acciones-fila-nodo form { display: inline; }

/* Columnas numéricas del presupuesto */
.tabla-presupuesto .col-num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tabla-presupuesto th.col-num { text-align: right; }
.col-venta { background: #f3f7ff; }

/* ── Fase 5 · bloque 0: edición rápida del presupuesto ── */

/* EL AVISO DE MARGEN BAJO. Amarillo, no rojo, y a propósito: no es un error, es algo
   que hay que mirar. Un margen del 8 % puede ser una decisión comercial consciente. */
.tabla-presupuesto .margen-bajo {
  background: #FEF3C7;
  color: #92400E;
  font-weight: 600;
}

/* Las celdas que se editan con doble clic se insinúan, sin gritar. */
.tabla-presupuesto [data-editar] { cursor: cell; }
.tabla-presupuesto [data-editar]:hover { outline: 1px dashed #1E3A6E; outline-offset: -2px; }

.col-alcance {
  font-size: .86em;
  color: #444;
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.col-alcance.col-vacia { color: #9AA3B2; }
.col-foto { text-align: center; }

/* ══ 🐛 EL BUG DEL DOBLE CLIC EN EL ALCANCE (C1, reproducido y arreglado el 2026-08-04) ══
   Diego: *«el doble clic pierde lo que había y no se ve lo que se escribe»*. Reproducido
   antes de tocar (regla B), y **el texto NO se perdía**: el editor se abre con `data-valor`,
   que lleva el alcance ENTERO — comprobado ejecutando el JS en `tests/test_alcance_
   editable_js.py`. Empezar por ahí habría sido arreglar código sano.

   Lo que fallaba era la PANTALLA. Las tres reglas de arriba —220 px, `overflow: hidden` y
   `white-space: nowrap`— son correctas para LEER una lista de 293 partidas, pero el doble
   clic mete dentro de esa celda un `<textarea rows="3">`: tres líneas en una caja que
   recorta lo que sobra y prohíbe los saltos. El texto estaba ahí y no se veía.

   ⚠️ NO SE ARREGLA QUITANDO EL TRUNCADO: sin él, un alcance de 200 caracteres por fila
   revienta la tabla entera con 293 partidas. La celda deja de recortar **solo mientras se
   está editando**, que es cuando `abrirEditor()` le pone `data-editando="1"`. */
.col-alcance[data-editando='1'] {
  max-width: none;
  overflow: visible;
  white-space: normal;
}
/* Y el editor tiene que caber: metido en una celda de tabla y sin ancho mínimo, el
   textarea se queda en un hilo y el arreglo no se nota. */
.col-alcance[data-editando='1'] textarea {
  min-width: 340px;
  resize: vertical;
}

/* ── La pestañita del alcance (C1, 2026-08-04) ──
   Plegado por defecto: con 293 partidas, el alcance entero en cada fila hace la tabla
   ilegible — que es justo por lo que la columna truncaba—. Desplegado, se lee completo. */
.alcance-plegable { font-size: .95em; }
.alcance-pesta {
  cursor: pointer;
  list-style: none;
  color: var(--adei-azul-medio);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.alcance-pesta::-webkit-details-marker { display: none; }
.alcance-pesta:hover { text-decoration: underline; }
.alcance-avance { color: #444; }
/* Desplegado, el texto manda sobre el truncado de la celda: si no, se abriría para seguir
   viéndose cortado, que es peor que no abrirse. */
.alcance-plegable[open] { white-space: normal; }
.alcance-entero {
  white-space: pre-wrap;
  margin-top: 4px;
  padding: 6px 8px;
  background: var(--adei-fondo-claro);
  border-left: 2px solid var(--adei-azul-medio);
  border-radius: 0 4px 4px 0;
  min-width: 260px;
}

/* ⭐⭐ EL EDITOR DE CELDA FLOTA: NO OCUPA SITIO EN LA TABLA (C1, 2026-08-07).
 *
 * Diego, dos veces: «repiensa toda la pantalla, no debería generar esa vibración» y «se amplía
 * mucho el cuadro y mueve todas las celdas». Mientras el editor viviera DENTRO del flujo de la
 * celda, eso no se podía prometer: cualquier cosa que se meta dentro de un `<td>` empuja.
 *
 * `position: absolute` lo saca del flujo → **ocupa cero** → la fila mide lo que medía. Es la
 * diferencia entre «hacerlo pequeño» (que es lo que se intentó dos veces y falló) y **quitarle
 * la capacidad de empujar**.
 *
 * ⚠️ EL ANCLA ES LA CELDA (`position: relative` abajo). Sin eso el editor se colgaría del
 * primer antepasado posicionado —que aquí sería la página— y aparecería en una esquina, lejos
 * de la casilla que se está editando. */
.editor-celda {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 40;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: flex-start;
  min-width: 240px;
  padding: 6px;
  background: #fff;
  border: 1px solid var(--adei-azul-medio, #1E3A6E);
  border-radius: 6px;
  box-shadow: 0 6px 18px rgba(14, 27, 56, .18);
  text-align: left;
}
.editor-celda input, .editor-celda textarea { width: 100%; font: inherit; }

/* ⚠️ LAS COLUMNAS NUMÉRICAS ABREN HACIA LA IZQUIERDA. Viven en la mitad derecha de la tabla
 * (Ud., Medición, Coste/Ud., Margen), así que un desplegable de 240 px que creciera hacia la
 * derecha se saldría de la pantalla en las últimas. Se decide **por el tipo de columna en el
 * CSS**, no midiendo en JS: medir obligaría a un DOM de verdad y estas pantallas se prueban
 * ejecutando el script contra un DOM simulado. */
.col-num > .editor-celda { left: auto; right: 0; }

/* La celda es el ancla, y **solo mientras se edita**: un `position: relative` permanente en
 * cada `<td>` de 293 filas es trabajo de más para el navegador y no hace falta.
 *
 * 🔴🔴 ANTES ESTABA ESCRITO PARA TRES TABLAS POR SU NOMBRE Y ESO ERA UN BUG ESPERANDO
 * (2026-08-28). Diego, estrenando el doble clic en la ficha de contactos: «cuando doy doble
 * clic para editar, la pantalla para escribir sale desviada de donde debería estar». La tabla
 * de contactos es `.tabla` a secas, así que su `<td>` NO era `position: relative` y el editor
 * —que es `position: absolute`— se colgaba del primer antepasado posicionado que encontrara,
 * o sea LEJOS de la celda.
 *
 * ⚠️ Es la regla (H): la regla cubría una FAMILIA y no las demás, y salía bien mientras nadie
 * estrenara la cuarta pantalla. Ahora el ancla es el ATRIBUTO, que es lo que de verdad
 * significa «esta celda se está editando»: ninguna pantalla futura tiene que acordarse de
 * apuntarse a una lista. Y el coste sigue siendo cero cuando no se edita — el selector solo
 * casa con la celda que lleva la marca puesta. */
td[data-editando='1'] {
  position: relative;
}

/* 🗑️🗑️ AQUÍ VIVÍA `.col-num[data-editando='1'] { white-space: normal }` (2026-08-05), Y SE
 * RETIRA DICIENDO QUE **EL ARREGLO SE INVIRTIÓ** — que es lo que manda la regla (L) de la casa:
 * lo que se borra sin decir que cambió de sentido vuelve en el próximo encargo.
 *
 * Aquella regla dejaba que la celda **partiera en dos líneas** mientras se editaba, para que el
 * campo y sus dos botones cupieran. Resolvía «no se ve lo que escribo»… **haciendo la fila más
 * alta**, o sea agravando la queja de al lado —«se amplía mucho el cuadro y mueve todas las
 * celdas»—, que es la que Diego ha repetido dos veces y en dos pantallas.
 *
 *     ANTES  que el campo quepa DENTRO de la celda   ->  la celda crece  ->  la fila salta
 *     AHORA  que el editor NO ESTE dentro            ->  la celda no cambia  ->  nada se mueve
 *
 * Con el editor flotando (arriba), la celda ya no contiene nada nuevo, así que el `nowrap` de
 * la columna **no estorba** y se queda como estaba para las 293 filas. Mantener aquella regla
 * hoy sería una línea que no hace nada con un comentario que promete que sí — y en esta casa
 * eso se acaba copiando a otros cinco sitios. */

/* El campo sigue siendo el elástico del editor: dentro de un flex, un elemento **ignora su
 * `width` al apretarse** y solo respeta su `min-width`. Ya no hay columna estrecha que lo
 * apriete —el editor tiene su propio `min-width` y flota—, pero esto es lo que reparte el sitio
 * entre el campo y los dos botones cuando el editor es el más justo posible. */
.editor-celda input { min-width: 7ch; flex: 1 1 10ch; }

/* L1 · el botón de deshacer del editor de celda (2026-08-05).
   ⚠️ Se DESACTIVA, no se esconde: un botón que aparece y desaparece según lo que escribes
   mueve los de al lado justo mientras alguien apunta con el ratón. Apagado se ve que está
   y que ahora mismo no hay nada que deshacer. */
.boton-deshacer { white-space: nowrap; }
.boton-deshacer[disabled] { opacity: .45; cursor: default; }

/* La barra de licitar: sale sola cuando hay algo marcado. */
.barra-licitar {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  padding: 10px 14px;
  margin: 10px 0;
  background: #F4F6FA;
  border: 1px solid #16264D;
  border-radius: 6px;
  box-shadow: 0 -2px 8px rgba(14, 27, 56, .12);
}
.barra-licitar label { display: flex; gap: 4px; align-items: center; font-size: .9em; }
.barra-licitar button[disabled] { opacity: .5; cursor: not-allowed; }
.col-subtotal { font-weight: 700; color: var(--adei-navy); }
.fila-total td { background: var(--adei-navy); color: #fff; font-weight: 800; font-size: 14px; }
.nota-presupuesto { margin-top: 10px; }

/* Rejilla de los 4 números de una partida en su formulario de edición */
.rejilla-numeros { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.rejilla-numeros label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; font-weight: 600; color: var(--adei-azul-medio); }
.rejilla-numeros input { font: inherit; font-size: 13px; padding: 6px 9px; border: 1px solid #d3dbe8; border-radius: 6px; }
.boton-mini-peligro { border-color: var(--adei-rojo); color: var(--adei-rojo); }
.boton-mini-peligro:hover { background: var(--adei-rojo); color: #fff; }
/* Botón mini en estado "activo" (p.ej. una línea ya marcada como opcional) */
.boton-mini-activo { border-color: var(--adei-azul-medio); background: #e7f0ff; color: var(--adei-azul-medio); font-weight: 700; }

/* ── Barra de márgenes globales (paso C) ── */
.margenes-globales {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 18px;
  background: linear-gradient(90deg, var(--adei-navy), var(--adei-azul-medio));
  color: #fff; padding: 14px 20px; border-radius: 12px; margin-bottom: 16px;
}
.margenes-globales .mg-campo { display: flex; flex-direction: column; gap: 4px; min-width: 190px; }
.margenes-globales .mg-campo label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; opacity: .9; }
.margenes-globales .mg-campo input {
  font: inherit; font-size: 15px; font-weight: 700; text-align: right;
  padding: 7px 10px; border: none; border-radius: 7px; width: 110px;
}
.margenes-globales .mg-campo small { font-size: 10px; opacity: .8; }
.margenes-globales .mg-total { flex: 1; min-width: 170px; text-align: right; display: flex; flex-direction: column; gap: 2px; }
.mg-total-label { font-size: 11px; text-transform: uppercase; letter-spacing: .4px; opacity: .85; }
.mg-total-valor { font-size: 24px; font-weight: 800; }
.mg-total-valor.mg-negativo { color: #fca5a5; }
.mg-total-nota { font-size: 10px; opacity: .8; }
.margenes-globales .boton-primario { align-self: flex-end; }

/* ── 🗑️ Vaciar el presupuesto (a la derecha, discreto: se usa una vez y da miedo) ── */
.vaciar-presupuesto { display: flex; justify-content: flex-end; margin: -6px 0 16px; }
.vaciar-presupuesto form { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.vaciar-nota { font-size: 11px; color: var(--adei-gris, #6b7280); }
.vaciar-frenado {
  margin: 0; font-size: 12px; max-width: 640px; text-align: right;
  color: var(--adei-gris, #6b7280); border-right: 3px solid var(--adei-rojo, #EF4444);
  padding-right: 10px; line-height: 1.45;
}

/* ── 4 tarjetas de resumen ── */
/* ── El resumen del presupuesto (C1, 2026-08-04) ──
   Se queda PEGADO ARRIBA al hacer scroll. Con 293 partidas, los totales estaban en la
   primera pantalla y no se volvían a ver: se editaba un precio en la fila 200 sin saber qué
   le hacía al margen. Ahora acompañan.

   ⚠️ ESTO NO ES «el resumen a la derecha» QUE PIDE EL PROTOTIPO, y no se ha hecho a medias
   a propósito: mover el resumen a una columna lateral es reestructurar la pantalla —tabla y
   panel en una rejilla de dos columnas—, y eso hay que VERLO con el presupuesto real de 293
   partidas antes de darlo por bueno. Está anotado en `herramientas/DUDAS_BACKLOG.md`.

   ⚠️ `position: sticky` y NO tocar el `overflow` de nada: el prototipo mete el scroll en un
   panel interior, y aquí eso dejaría `window.scrollY` clavado en 0 y mataría
   `mantener_scroll.js` en las 68 pantallas sin dar un error. Es el mismo aviso de B1. */
.resumen-presupuesto {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 16px;
  position: sticky; top: 0; z-index: 4;
  background: var(--adei-fondo-claro);
  padding: 10px 0;
}
.tarjeta-resumen {
  background: #fff; border: 1px solid #e3e9f2; border-radius: 10px;
  padding: 14px 16px; display: flex; flex-direction: column; gap: 3px;
}
.tarjeta-resumen .tr-titulo { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--adei-azul-medio); }
.tarjeta-resumen .tr-valor { font-size: 22px; font-weight: 800; color: var(--adei-navy); }
.tarjeta-resumen .tr-valor.tr-coste { color: var(--adei-azul-medio); }
.tarjeta-resumen .tr-valor.tr-beneficio { color: var(--adei-verde); }
.tarjeta-resumen .tr-valor.tr-rojo { color: var(--adei-rojo); }
.tarjeta-resumen .tr-valor.tr-ambar { color: var(--adei-ambar, #F59E0B); }  /* estado intermedio (revisado, sin confirmar) */
.tarjeta-resumen .tr-nota { font-size: 11px; color: #6b7280; }
/* ── La tarjeta de «con las opciones» (2026-08-04) ──
   Va apagada a propósito: el número que manda es el del cliente, y este de al lado no puede
   competir con él de un vistazo. Es el mismo criterio por el que la tarjeta solo aparece
   cuando hay algo opcional. */
/* ── C2 · Qué se toca y qué no, en la certificación (2026-08-04) ──
   La tabla tiene ocho columnas numéricas y **solo una se puede tocar**: la medición actual.
   Nada lo decía: había que descubrirlo pinchando en «Certificar».

   ⚠️ ESTO NO ES UN PERMISO NI UN FRENO — el precio firmado no se edita porque no hay ruta
   que lo edite, y una certificación cerrada consolida MEDICIÓN, no precios. Esto solo hace
   VISIBLE la regla que ya existía. */
.col-bloqueada { background: repeating-linear-gradient(
    45deg, transparent, transparent 6px, rgba(22, 38, 77, .035) 6px, rgba(22, 38, 77, .035) 12px); }
.col-editable { background: rgba(16, 185, 129, .07); }

/* ── La cámara de la fila (C1, 2026-08-04) ──
   El `<input type="file">` se esconde y el que se ve es su `<label>`: un icono que ocupa lo
   que una celda de tabla puede permitirse. Pinchar la etiqueta abre el selector igual. */
.foto-rapida { display: inline; }
.foto-camara { cursor: pointer; font-size: 15px; opacity: .45; }
.foto-camara:hover { opacity: 1; }
.foto-camara input[type="file"] { display: none; }
.cert-alcance { margin-top: 4px; }

.tarjeta-resumen.tarjeta-opcional { background: var(--adei-fondo-claro); border-style: dashed; }
.tarjeta-resumen.tarjeta-opcional .tr-valor { font-size: 18px; color: var(--adei-azul-medio); }
@media (max-width: 820px) { .resumen-presupuesto { grid-template-columns: repeat(2, 1fr); } }

/* ── Líneas marcadas como OPCIONAL ── */
.etiqueta-opcional { background: #fff3e0; color: #9a5b00; margin-left: 6px; font-size: 10px; }
.fila-opcional { background: #fbfaf5 !important; }
.fila-opcional .nodo-titulo strong { color: #9a5b00; }
.col-opcional { color: #9a5b00; font-style: italic; }

/* ── Barras de aprobar / aprobado (paso E) ── */
.barra-aprobar, .barra-aprobado {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 12px 18px; border-radius: 11px; margin-bottom: 16px;
}
.barra-aprobar { background: #eef4ff; border: 1px solid #cfe0ff; color: var(--adei-azul-medio); }
.barra-aprobar span { flex: 1; font-size: 13px; }
.barra-aprobado { background: linear-gradient(90deg, var(--adei-navy), var(--adei-azul-medio)); color: #fff; }
.barra-aprobado .ba-info { flex: 1; display: flex; flex-direction: column; gap: 3px; }
.barra-aprobado .ba-info strong { font-size: 14px; }
.barra-aprobado .ba-detalle { font-size: 11px; opacity: .85; }
.barra-aprobado .boton { background: rgba(255,255,255,.16); color: #fff; border-color: transparent; }
.barra-aprobado .boton:hover { background: rgba(255,255,255,.28); }

/* ── Marca de origen de la medición en la tabla (📐 desglose / ✍ a mano) ── */
.med-marca { font-size: 11px; margin-left: 2px; cursor: help; }
.med-mano { color: var(--adei-azul-medio); }

/* ── Desglose de medición (paso D) ── */
.desglose-medicion {
  margin: 8px 0; padding: 10px 12px; border: 1px dashed #cdd7e6;
  border-radius: 8px; background: #fafbfe;
}
.dm-cabecera { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; font-size: 12px; color: var(--adei-azul-medio); }
.dm-aviso { color: #9a5b00; font-size: 11px; }
.dm-linea { display: flex; align-items: center; gap: 4px; margin-bottom: 5px; }
.dm-fila { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; flex: 1; }
.dm-fila input { font: inherit; font-size: 12px; padding: 5px 7px; border: 1px solid #d3dbe8; border-radius: 6px; }
.dm-concepto { flex: 1; min-width: 130px; }
.dm-num { width: 62px; text-align: right; }
.dm-x { color: var(--adei-azul-medio); font-weight: 700; }
.dm-parcial { min-width: 66px; text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--adei-navy); }
.dm-nueva { margin-top: 4px; padding-top: 8px; border-top: 1px solid #eef2f8; }
.dm-total { margin-top: 6px; font-size: 13px; color: var(--adei-navy); }
.dm-ayuda { margin: 6px 0 0; font-size: 11px; color: #6b7280; }
.nuevo-capitulo { margin-top: 16px; padding: 16px 24px; }
.nuevo-capitulo > summary { cursor: pointer; font-weight: 600; color: var(--adei-azul-medio); }
.nuevo-capitulo[open] > summary { margin-bottom: 12px; }

/* ── Fases de una obra ── */
.cabecera-fases {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.plazo-total {
  font-size: 13px;
  font-weight: 600;
  color: var(--adei-azul-medio);
  background: var(--adei-fondo-claro);
  border: 1px solid #d8e0ee;
  border-radius: 999px;
  padding: 2px 12px;
}
/* Plazo con ampliaciones por órdenes de cambio (paso E). */
.plazo-ampliado { font-weight: 500; }
.plazo-ampliado .plazo-mas { color: var(--adei-navy); font-weight: 600; }
.plazo-ampliado strong { color: var(--adei-verde); }

.lista-fases {
  list-style: none;
  counter-reset: none;
  padding: 0;
  margin: 12px 0 0;
}
.fase {
  border: 1px solid #e3e8f0;
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 10px;
}
.fase-fila {
  display: flex;
  align-items: center;
  gap: 12px;
}
.fase-num {
  flex: none;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--adei-navy);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  border-radius: 999px;
}
.fase-nombre { flex: 1; font-weight: 600; }
.fase-plazo { color: var(--adei-azul-medio); font-size: 13px; white-space: nowrap; }
.fase-acciones { display: flex; gap: 4px; }
.fase-notas { margin: 8px 0 0; font-size: 14px; }

/* Botón pequeño (subir/bajar fase) */
.boton-mini {
  background: #fff;
  border: 1px solid #d3dbe8;
  color: var(--adei-navy);
  font-size: 13px;
  line-height: 1;
  padding: 5px 8px;
  border-radius: 6px;
  cursor: pointer;
}
.boton-mini:hover { border-color: var(--adei-azul-medio); }

/* Bloques plegables (añadir / editar fase) */
.fase-editar, .fase-anadir { margin-top: 10px; }
.fase-editar > summary, .fase-anadir > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--adei-azul-medio);
  padding: 4px 0;
}
.fase-editar .formulario, .fase-anadir .formulario { margin-top: 10px; }
.fase-editar > form[action$="borrar"] { margin-top: 8px; }

/* ── A5 · Las tres vistas de Contactos, dentro de la pantalla (2026-08-04) ──
   Sustituyen a las tres entradas que había en el lateral. La marcada usa el navy de la
   casa: es la única forma de saber en qué vista estás desde que el lateral solo dice
   «Contactos». */
.chips-filtro {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.chip-filtro {
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  color: var(--adei-azul-medio);
  background: #fff;
  border: 1px solid #d3dbe8;
  border-radius: 999px;
  padding: 5px 14px;
}
.chip-filtro:hover { border-color: var(--adei-azul-medio); }
.chip-filtro.activo {
  color: #fff;
  background: var(--adei-navy);
  border-color: var(--adei-navy);
}
.chip-filtro:focus-visible {
  outline: 2px solid var(--adei-azul-medio);
  outline-offset: 2px;
}

/* Buscador (por nombre en las tres vistas; por oficio y marca en proveedores) */
.buscador {
  display: flex;
  gap: 8px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.buscador input[type="search"] {
  flex: 1;
  min-width: 220px;
  font: inherit;
  padding: 9px 12px;
  border: 1px solid #d3dbe8;
  border-radius: 8px;
}
.buscador input[type="search"]:focus {
  outline: none;
  border-color: var(--adei-azul-medio);
  box-shadow: 0 0 0 3px rgba(30, 58, 110, 0.12);
}

.ayuda { color: var(--adei-azul-medio); font-size: 12px; }

/* ── Valoraciones (estrellas) ── */
.estrellas { color: #f0a500; letter-spacing: 2px; font-size: 16px; }
.sin-valorar { color: #9aa3b2; font-size: 13px; }

.valoracion-actual {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 4px 0 6px;
}
.valoracion-actual .estrellas { font-size: 22px; }
.valoracion-meta { color: var(--adei-azul-medio); font-size: 13px; }

.form-valorar {
  display: flex;
  flex-direction: column;
  gap: 14px;
  border-top: 1px solid #eef2f8;
  margin-top: 16px;
  padding-top: 16px;
}

/* Selector de estrellas pinchable. El truco: las estrellas van en el HTML de
   5 a 1 y se muestran al revés (row-reverse) para verlas de 1 a 5; así, al
   pasar el ratón o marcar una, se pintan ella y las anteriores. */
.estrellas-elegir {
  display: inline-flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
  gap: 2px;
}
.estrellas-elegir input { display: none; }
.estrellas-elegir label {
  font-size: 28px;
  color: #d3dbe8;
  cursor: pointer;
  line-height: 1;
}
.estrellas-elegir label:hover,
.estrellas-elegir label:hover ~ label,
.estrellas-elegir input:checked ~ label {
  color: #f0a500;
}

.historial { list-style: none; padding: 0; margin: 8px 0 0; }
.historial li {
  padding: 8px 0;
  border-bottom: 1px solid #eef2f8;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.historial li:last-child { border-bottom: none; }
.historial-nota { color: var(--adei-navy); }

/* Formularios */
.formulario { display: flex; flex-direction: column; gap: 16px; }

.subtitulo-form {
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--adei-azul-medio);
  border-bottom: 1px solid #eef2f8;
  padding-bottom: 6px;
  margin: 8px 0 0;
}

.campo { display: flex; flex-direction: column; gap: 6px; }
.campo > span { font-size: 13px; font-weight: 600; color: var(--adei-navy); }
.obligatorio { color: var(--adei-rojo); font-style: normal; }

.campo input, .campo textarea, .campo select {
  font: inherit;
  padding: 9px 12px;
  border: 1px solid #d3dbe8;
  border-radius: 8px;
  background: #fff;
  color: var(--adei-navy);
}
.campo input:focus, .campo textarea:focus, .campo select:focus {
  outline: none;
  border-color: var(--adei-azul-medio);
  box-shadow: 0 0 0 3px rgba(30, 58, 110, 0.12);
}

.rejilla-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.campo-ancho { grid-column: 1 / -1; }

.etiquetas-campo {
  border: 1px solid #e3e8f0;
  border-radius: 10px;
  padding: 12px 16px;
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
}
.etiquetas-campo legend { font-size: 13px; font-weight: 600; padding: 0 6px; }
.check { display: flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; }
.check input { width: 17px; height: 17px; }

.acciones-form { display: flex; gap: 10px; align-items: center; }

/* Ficha (detalle) */
.datos {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 8px 16px;
  margin: 10px 0 20px;
}
.datos dt { color: var(--adei-azul-medio); font-size: 13px; font-weight: 600; }
.datos dd { margin: 0; }
.etiquetas-ficha { margin: 0 0 12px; }
.notas { white-space: pre-wrap; }
.volver { margin-top: 18px; }
.volver a { color: var(--adei-azul-medio); text-decoration: none; }
.vacio { text-align: center; }
.vacio p { color: var(--adei-azul-medio); margin-bottom: 16px; }

/* ===== Certificación a cliente (Fase 1) ===== */
.cert-no-habilitada { padding: 40px 24px; }
.cert-no-habilitada .cnh-icono { font-size: 34px; margin-bottom: 8px; }

/* La tabla es ancha (4 bloques): permitir scroll horizontal sin romper la caja. */
.tabla-scroll { overflow-x: auto; border-radius: 12px; }
/* ⚠️ Subido de 1120 a 1300 el 2026-08-07: «Certificación Anterior» pasó de UNA columna a
   TRES (duda 23). Sin subirlo, las columnas se estrechan hasta partir los importes en dos
   líneas — que es peor que el scroll, porque no se ve que falte nada. */
.tabla-certificacion { min-width: 1300px; }
.tabla-certificacion th, .tabla-certificacion td { padding: 8px 10px; font-size: 13px; }
.tabla-certificacion .col-num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tabla-certificacion th.col-num { text-align: right; }
.tabla-certificacion .col-tipo { width: 70px; }

/* Cabecera con los cuatro bloques de color (como el prototipo). */
.tabla-certificacion .bloque { text-align: center; }
.tabla-certificacion .bloque-firmado    { background: #eef2ff; color: var(--adei-azul-medio); }
.tabla-certificacion .bloque-adicional  { background: #fff3e0; color: #9a5b00; }
.tabla-certificacion .bloque-anterior   { background: #f3f4f6; color: #6b7280; }
.tabla-certificacion .bloque-actual     { background: #d1fae5; color: #065f46; }
.tabla-certificacion .bloque-diferencia { background: var(--adei-navy); color: #fff; }
/* ⭐ EL OBJETIVO — solo en la certificacion a SUBCONTRATA, y con un color que en la del
   cliente NO EXISTE (Diego, 2026-09-03). Es lo unico de esa tabla que es NUESTRO: lo que la
   partida costaba en el presupuesto, y no se le enseña a nadie de fuera.
   ⚠️ NO puede ser el violeta (#efe7fb): ese ya significa «precio estimado» en esta misma
   familia de tablas, y dos cosas distintas del mismo color en la pantalla del dinero es
   exactamente el error que empuja a la persona a equivocarse. */
.tabla-certificacion .bloque-objetivo { background: #fce7f3; color: #9d174d; }

/* 🎨 LAS PARTIDAS QUE ASUMIMOS NOSOTROS (Diego, 2026-09-03): no estaban presupuestadas, asi que
   su coste sale del margen de la obra. Van en el MISMO tono que la columna del objetivo --el
   burdeos-- porque hablan de lo mismo: de lo NUESTRO. Un cuarto color nuevo aqui obligaria a
   aprenderse otro significado.
   ⚠️ Va ANTES que `.fila-alerta` para que la alerta gane: si ademas se ha certificado de mas,
   eso es lo urgente y lo que tiene que verse. */
.tabla-certificacion .fila-asumida > td { background: #fdf2f8; }
.tabla-certificacion .fila-asumida .nodo-titulo,
.tabla-certificacion .fila-asumida td:first-child { color: #9d174d; }

/* 📊 EL RESUMEN DE LA OBRA, arriba de la certificacion a subcontrata (2026-09-03). */
.resumen-compra {
  border: 1px solid #dfe5f0; border-radius: 8px; background: #fff;
  padding: 12px 14px; margin: 0 0 14px;
}
.rc-titulo { font-size: 12px; font-weight: 700; color: var(--adei-navy, #16264D);
             text-transform: uppercase; letter-spacing: .4px; margin-bottom: 10px; }
.rc-cifras { display: flex; flex-wrap: wrap; gap: 10px; }
.rc-dato {
  flex: 1 1 150px; min-width: 140px; padding: 8px 10px;
  border-radius: 6px; background: #f6f9ff; border-left: 3px solid #dfe5f0;
}
.rc-etiqueta { display: block; font-size: 11px; color: #6b7280; text-transform: uppercase;
               letter-spacing: .3px; }
.rc-dato strong { display: block; font-size: 18px; font-variant-numeric: tabular-nums;
                  color: var(--adei-navy, #16264D); margin: 2px 0 1px; }
.rc-dato small { display: block; font-size: 10px; color: #9ca3af; line-height: 1.25; }
/* ⚠️ CADA ZONA CON EL COLOR QUE YA TIENE EN LA TABLA: quien mira el resumen y baja a la tabla
   reconoce de que columna habla cada cifra sin leer la etiqueta. */
.rc-objetivo { border-left-color: #9d174d; background: #fdf2f8; }
.rc-contratado { border-left-color: #1E3A6E; background: #eef2ff; }
.rc-certificado { border-left-color: #047857; background: #d1fae5; }
/* 💰 Lo facturado y lo pagado (2026-09-03): gris, porque no es dinero de OBRA sino de banco —
   y mezclarlo de color con las zonas de la certificación invitaría a compararlos sin más. */
.rc-pagado { border-left-color: #6b7280; background: #f3f4f6; }
.rc-pie { margin-top: 10px; font-size: 12px; }
.rc-mal { color: var(--adei-rojo, #EF4444); font-weight: 700; }
.rc-bien { color: var(--adei-verde, #10B981); font-weight: 700; }
.rc-asumido { color: #9d174d; }

/* 🏢 El resumen por empresa, y el objetivo de toda la obra (2026-09-03). */
.rc-obra { border-left-color: #6b7280; background: #f3f4f6; }
.tabla-empresas { width: 100%; margin-top: 4px; }
.tabla-empresas th, .tabla-empresas td { padding: 6px 8px; font-size: 12px; }
.tabla-empresas .col-num { text-align: right; white-space: nowrap;
                           font-variant-numeric: tabular-nums; }
/* ⚠️ La fila de la subcontrata que se está mirando, marcada: con quince, sin esto hay que
   buscar el nombre para saber en cuál se está. */
.tabla-empresas .fila-esta > td { background: #eef2ff; font-weight: 600; }
/* 📋 El alcance debajo de la partida: gris y pequeño, para que no compita con el título. */
.alcance-linea { color: #6b7280; font-style: italic; }
.tabla-certificacion .bloque small { font-weight: 400; font-size: 9px; }

/* Línea separadora entre bloques. */
.tabla-certificacion .sep { border-left: 2px solid #dfe5f0; }

/* Encabezados (capítulo/subcapítulo) y partidas. */
.tabla-certificacion .fila-cert-encabezado.fila-nivel-0 { background: #eaf0f9; border-top: 2px solid #dfe5f0; }
.tabla-certificacion .fila-cert-encabezado.fila-nivel-1 { background: #f4f6fa; }
.tabla-certificacion .fila-cert-encabezado td { font-weight: 700; color: var(--adei-navy); }
/* ⭐ LA FILA DEL CAPITULO VA ENTERA DEL MISMO COLOR (Diego, 2026-09-04): *«en certificacion a
   cliente, cuando sale un capitulo toda su fila tiene que ir del mismo color. No salga
   cambiando segun la columna»*.

   🔴 EL FONDO DEL CAPITULO SE PINTA EN EL `<tr>`, pero **el fondo de una celda tapa el de su
   fila**: `.col-bloqueada` (las rayas del precio firmado) y `.col-editable` (el verde de lo que
   se puede tocar) llevan `background` propio, asi que la fila del capitulo salia a parches --
   rayada en unas columnas y verdosa en otras.

   ⚠️ Y NO ES SOLO FEO: esos dos fondos existen para decir «esto se edita» y «esto no», y en una
   fila de capitulo **no se edita nada** (el capitulo no tiene medicion propia, es la suma de
   sus partidas). Pintarlos ahi es afirmar lo contrario de lo que pasa.

   ⚠️ VA ANTES DE LA REGLA DE LAS OC: un capitulo de orden de cambio tiene su propio color y
   ese SI debe ganar -- por eso esta regla se queda arriba y no al final del bloque. */
.tabla-certificacion .fila-cert-encabezado td.col-bloqueada,
.tabla-certificacion .fila-cert-encabezado td.col-editable,
.tabla-certificacion .fila-cert-encabezado td.cert-vivas { background: transparent; }
/* ⭐ Y EL TEXTO, TAMBIEN DE UN SOLO COLOR. Diego lo pidio como «toda su fila del mismo
   color», y midiendo salio que lo que cambiaba no era el fondo --que es uniforme-- sino EL
   TEXTO: tres colores en la misma fila, ganando por especificidad.

       .fila-cert-encabezado td            (0,2,1)  navy
       .avance                             (0,2,0)  verde  -> vive en un <small> DENTRO del td,
                                                    asi que el color del td no le llega
       .col-diferencia.dif-neg             (0,3,0)  rojo   -> le GANA a la del encabezado

   ⚠️ LO QUE SE PIERDE, Y SE DICE: el verde del avance y el rojo de la desviacion siguen
   saliendo EN LAS PARTIDAS, que es donde se decide algo. En la fila del capitulo eran un
   resumen de resumenes, y el color competia con el del propio capitulo.

   ⚠️ `td *` ES LO QUE ALCANZA AL <small>: sin el, el avance seguiria verde por mucho que se
   suba la especificidad del `td` -- no es que pierda, es que apunta a otro elemento. */
.tabla-certificacion .fila-cert-encabezado td,
.tabla-certificacion .fila-cert-encabezado td *,
.tabla-certificacion .fila-cert-encabezado td.col-diferencia,
.tabla-certificacion .fila-cert-encabezado td.col-diferencia.dif-neg {
  color: var(--adei-navy);
}
/* ⭐⭐ Y LA FILA **CORTA EN HORIZONTAL**, que es lo que Diego pedia de verdad: *«quiero que la
   fila donde pone DEMOLICIONES sea de un color y corte todo en horizontal. Color principal el
   de la fila, no el color de la columna»*.

   🔴 NO ERA UN FONDO. Se listaron TODAS las reglas del CSS con `background` que pueden caer en
   esa fila y son cuatro, las cuatro uniformes: el fondo ya era de un solo color. Lo que partia
   la fila en trozos eran **las lineas verticales** de `.sep` --el `border-left` de 2 px que
   separa las zonas--, que la atravesaban de arriba abajo y la hacian leerse como cinco cajas en
   vez de como una banda.

   ⚠️ EN LAS PARTIDAS SE QUEDAN, y ahi hacen falta: con 16 columnas de numeros son lo unico que
   dice donde acaba «Contratado» y empieza «Adicionales». Lo que no tiene sentido es partir la
   fila que precisamente **agrupa** todo lo que va debajo.

   ⚠️ Va DESPUES de `.sep` para ganarle: misma especificidad no, mas --(0,2,1) contra (0,2,0)--,
   pero el orden se respeta igual por si alguien iguala la del separador. */
.tabla-certificacion .fila-cert-encabezado td { border-left: 0; }
.tabla-certificacion .col-total { font-weight: 700; }
.tabla-certificacion .avance { color: #059669; font-size: 10px; }
.tabla-certificacion .col-diferencia { font-weight: 800; color: var(--adei-verde); }
.tabla-certificacion .col-diferencia.dif-neg { color: var(--adei-rojo); }
.tabla-certificacion .fila-opcional td { color: #9a5b00; background: #fffaf2; }
.tabla-certificacion .fila-opcional-total td { background: #fff3e0; color: #9a5b00; font-weight: 700; }

/* Líneas que vienen de una orden de cambio (paso D4): pastilla + realce sutil. */
.etiqueta-oc { background: var(--adei-navy); color: #fff; margin-left: 6px; font-size: 10px; letter-spacing: .3px; }
.tabla-certificacion .fila-oc td { background: #f5f8ff; }
.tabla-certificacion .fila-oc.fila-cert-encabezado td { background: #eef3ff; }

/* Partidas con precio ESTIMADO (por cerrar): violeta, salen aparte y NO se
   certifican (mejora «precio estimado por partida», paso 3). Va DESPUÉS de
   .fila-oc porque una estimada también es línea de OC (gana el violeta). */
.etiqueta-estimado { background: #efe7fb; color: #6b3fc0; margin-left: 6px; font-size: 10px; font-weight: 600; }
/* Badge de partida con el precio YA cerrado (paso 5): verde, gemelo del estimado. */
.etiqueta-cerrado { background: #e6f7f0; color: #0a7a55; margin-left: 6px; font-size: 10px; font-weight: 600; }
.oc-precio-rastro { color: #6b3fc0; }
.tabla-certificacion .fila-estimada td { color: #6b3fc0; background: #efe7fb; }
.tabla-certificacion .fila-estimada-total td { background: #efe7fb; color: #6b3fc0; font-weight: 700; }
.tabla-certificacion .cert-bloqueada { font-size: 11px; font-weight: 600; color: #6b3fc0; white-space: nowrap; }

/* Columna "Certificar": desplegable con los mini-formularios de avance. */
.tabla-certificacion .col-acciones { width: 96px; }
.cert-editar > summary {
  cursor: pointer; font-size: 11px; font-weight: 600;
  color: var(--adei-azul-medio); list-style: none; white-space: nowrap;
  padding: 4px 8px; background: #eef2ff; border-radius: 6px; text-align: center;
}
.cert-editar[open] > summary { margin-bottom: 8px; }
.cert-mini { display: block; margin-bottom: 10px; }
.cert-mini:last-child { margin-bottom: 0; }
.cert-mini label { display: block; font-size: 10px; color: #6b7280; margin-bottom: 3px; }
.cert-mini small { display: block; font-size: 9px; color: #9ca3af; margin-top: 2px; }
.cert-mini-fila { display: flex; align-items: center; gap: 4px; }
.cert-mini-fila input {
  width: 66px; padding: 4px 6px; font-size: 12px; text-align: right;
  border: 1px solid #d3dbe8; border-radius: 6px;
}
/* ── Suministros: la DESCRIPCIÓN (la de la partida y la de la compra) y su edición ── */
.sum-descripcion { margin: 4px 0 2px; }
.sum-descripcion > summary {
  cursor: pointer; font-size: 11px; color: #6b7280; list-style: none; display: inline-block;
}
.sum-desc-propia {
  font-size: 9px; font-weight: 700; color: #065f46; background: #d1fae5;
  padding: 1px 5px; border-radius: 5px;
}
.sum-desc-bloque { margin: 6px 0 0; padding-left: 10px; border-left: 3px solid #dfe5f0; }
/* La escrita a mano se distingue de la del presupuesto: quien la lee tiene que saber si
   eso lo firmó el cliente o lo apuntó un compañero. */
.sum-desc-mia { border-left-color: var(--adei-verde); }
.sum-desc-de { display: block; font-size: 9px; text-transform: uppercase;
               letter-spacing: .04em; color: #9ca3af; }
.sum-desc-bloque p { margin: 2px 0 0; font-size: 12px; color: #374151; white-space: pre-wrap; }
.sum-desc-foto { display: block; margin-top: 4px; max-width: 220px; max-height: 160px;
                 border-radius: 8px; border: 1px solid #dfe5f0; }
.sum-editar-titulo > summary {
  cursor: pointer; font-size: 11px; font-weight: 600; color: var(--adei-azul-medio);
  list-style: none; padding: 3px 8px; background: #eef2ff; border-radius: 6px;
}
.sum-editar-titulo form { margin-top: 6px; max-width: 320px; }
.sum-editar-titulo label { display: block; font-size: 10px; color: #6b7280; margin: 4px 0 2px; }
.sum-editar-titulo input, .sum-editar-titulo textarea {
  width: 100%; padding: 4px 6px; font-size: 12px;
  border: 1px solid #d3dbe8; border-radius: 6px;
}

.cert-pct-signo { font-size: 12px; color: #6b7280; margin-left: -2px; }

/* «➕ Partida nueva» en la fila del capítulo → crea/alimenta su orden de cambio.
   Color de ADICIONAL (el naranja del bloque «Presup. Adicionales»), no el azul de
   «Certificar»: son dos cosas distintas y confundirlas cuesta un documento. */
/* APLICAR UN % AL CAPÍTULO ENTERO (2026-08-08). Va PLEGADO y en azul, no en ámbar como
   «partida nueva»: aquélla crea una orden de cambio —algo que el cliente tendrá que aprobar—
   y ésta solo rellena casillas que se pueden corregir a mano. Dos avisos del mismo color
   dirían que las dos cosas pesan igual. */
.cert-pct-cap { margin-top: 6px; margin-right: 10px; font-weight: 400;
                display: inline-block; }
.cert-pct-cap > summary { cursor: pointer; font-size: 11px; font-weight: 600;
                          color: var(--adei-azul-medio, #1E3A6E); list-style: none;
                          display: inline-block; }
.cert-pct-cap > summary::-webkit-details-marker { display: none; }
.cert-pct-cap > summary:hover { text-decoration: underline; }

/* ➕ EL RENGLON DE PARTIDA NUEVA EN LA CERTIFICACION (Diego, 2026-09-01).

   🔄 SUSTITUYE AL `<details class="cert-adicional">`, que se abria dentro de la celda del
   capitulo con las casillas apiladas en vertical. Diego: *«se ve bastante mal anadir una nueva
   partida. Que salga una fila como si fuese de certificacion y ahi relleno los diferentes
   campos necesarios»*. Ahora es una FILA con cada campo bajo su columna.

   ⚠ EL FONDO LA SEPARA DE LAS PARTIDAS DE VERDAD: en una tabla de dinero, una fila editable
   que se ve igual que las demas invita a teclear en la que no es. */
tr.fila-nueva-partida > td { background: #FFFDF5; border-top: 1px dashed #E5C79A; }
tr.fila-nueva-partida input, tr.fila-nueva-partida select {
  font-size: 12px; padding: 3px 6px; border: 1px solid #d3dbe8; border-radius: 5px;
}
tr.fila-nueva-partida .col-num input { text-align: right; }
/* El disparador, en la celda del capitulo. Se parece al `<summary>` de antes A PROPOSITO:
   Diego lo pidio «como antes», y lo que cambia es lo que ABRE, no como se llama. */
.cert-abre-nueva {
  margin-top: 6px; cursor: pointer; font-size: 11px; font-weight: 600; color: #9a5b00;
  padding: 3px 10px; background: #fff3e0; border: 1px solid #f0d5ab; border-radius: 6px;
}
.cert-abre-nueva:hover { background: #ffe8c9; }
.cert-abre-nueva[aria-expanded="true"] { background: #ffe0b2; }
.cert-nueva-mas { color: #9a5b00; font-weight: 700; text-align: center; }
.cert-nueva-form { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.cert-nueva-titulo { flex: 1 1 14rem; min-width: 10rem; }
/* 🔒 Lo interno (coste, gremio, texto) NO tiene columna a proposito: esta tabla es la del
   CLIENTE y el coste no sale en ella ni en el PDF. Se separa y se apaga. */
.cert-nueva-interno {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin-top: 5px; padding: 5px 8px; border-left: 3px solid #E5C79A;
  background: #FFF8E9; border-radius: 4px;
}
.cert-nueva-tit { font-size: 10px; font-weight: 700; color: #9a5b00; letter-spacing: .3px; }
.cert-nueva-texto { flex: 1 1 12rem; min-width: 8rem; }
/* 🎯 El aviso de «no vendas por menos de / no pagues mas de», al lado de la casilla.
   ⚠ Se ve, y en el color del aviso de la casa: es un guardarrail, no una nota. */
.cert-sugerido {
  display: block; margin-top: 3px; font-size: 11px; font-weight: 700;
  color: #9a5b00; white-space: normal; text-align: right;
}
tr.fila-nueva-partida-nota > td { background: #FFFDF5; padding-top: 0; }
tr.fila-nueva-partida-nota .ayuda { font-size: 11px; }

/* Barra del periodo actual + botón de cerrar. */
.cert-periodo-barra {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 10px 16px; margin-bottom: 12px;
  background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 10px;
}
.cert-periodo-barra .spacer { flex: 1; }
.cert-periodo-num { font-size: 13px; color: #065f46; }
.cert-periodo-diff { font-size: 12px; color: #6b7280; }
.cert-periodo-diff strong { color: var(--adei-verde); }
.cert-periodo-diff strong.dif-neg { color: var(--adei-rojo); }

/* Histórico de cierres. */
.cert-historico { margin-top: 20px; }
.cert-historico .col-num { text-align: right; font-variant-numeric: tabular-nums; }
.cert-historico th.col-num { text-align: right; }

@media (max-width: 640px) {
  .rejilla-2 { grid-template-columns: 1fr; }
  .datos { grid-template-columns: 1fr; gap: 2px 0; }
  .datos dd { margin-bottom: 8px; }
}

/* ===================================================================
   Usuario en cabecera y pantalla de entrada (Fase 2, login)
   =================================================================== */

/* Bloque "quién soy + Salir", empujado a la derecha de la cabecera. */
.adei-usuario {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
}
.adei-usuario-nombre { font-size: 14px; font-weight: 600; color: #fff; }
.adei-usuario-rol {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .4px;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--adei-azul-medio);
  color: #fff;
  opacity: .9;
}
.adei-usuario form { display: inline; margin: 0; }
.boton-salir {
  background: rgba(255, 255, 255, .12);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, .35);
  border-radius: 8px;
  padding: 6px 14px;
  font-size: 14px;
  cursor: pointer;
}
.boton-salir:hover { background: rgba(255, 255, 255, .24); }

/* Equipo de la obra (paso E). */
.subtitulo-equipo { font-size: 14px; margin: 18px 0 8px; color: var(--adei-azul-medio); }
.lista-equipo { list-style: none; margin: 0 0 12px; padding: 0; }
.lista-equipo .miembro {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid #eef1f6;
}
.miembro-nombre { font-weight: 600; }
.lista-equipo .miembro form { display: inline; margin: 0; margin-left: auto; }
.form-anadir-persona { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.form-anadir-persona select { padding: 8px 10px; border: 1px solid #cdd5e3; border-radius: 8px; }

/* Contactos de la obra (agenda) — pieza reutilizable. */
.lista-contactos { list-style: none; margin: 0 0 12px; padding: 0; }
.contacto-fila { display: flex; align-items: center; gap: 10px; padding: 8px 0;
  border-bottom: 1px solid #eef1f6; flex-wrap: wrap; }
.contacto-email { font-size: 12px; color: var(--adei-gris, #6b7280); }
.contacto-email .sin-email { color: #b0663a; font-style: italic; }
.contacto-fila form { margin: 0; }
.contacto-copia { margin-left: auto; }
.contacto-copia .doc-check { font-size: 12px; color: var(--adei-gris, #6b7280); }
.contacto-copia .doc-check.contacto-copia-on { color: var(--adei-verde, #10B981); font-weight: 700; }
.form-anadir-contacto { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.form-anadir-contacto select, .form-anadir-contacto input[type="text"] {
  padding: 8px 10px; border: 1px solid #cdd5e3; border-radius: 8px; }

/* Jefe/proyectista como usuarios (paso E4). Pista del texto antiguo en gris y la
   etiqueta "Jefe:/Proy.:" de la lista de obras, pequeña y discreta. */
.pista-antigua { color: #6b7280; }
.pista-antigua em { font-style: normal; font-size: 11px; color: #9aa3b2; }
.col-personas { font-size: 13px; line-height: 1.5; }
.rol-mini { color: #9aa3b2; font-size: 11px; text-transform: uppercase; letter-spacing: .03em; }

/* Gestión de usuarios (paso D). */
.fila-inactiva { opacity: .55; }
.etiqueta-activo { background: #dcfce7; color: #166534; }
.etiqueta-inactivo { background: #fee2e2; color: #991b1b; }
.acciones-fila { display: flex; gap: 8px; align-items: center; }
.acciones-fila form { display: inline; margin: 0; }
/* Separar un poco las tarjetas apiladas en la ficha de edición. */
.formulario.adei-tarjeta + .formulario.adei-tarjeta { margin-top: 18px; }

/* Caja centrada de la pantalla de entrada. */
.login-caja {
  max-width: 420px;
  margin: 48px auto;
}
.login-caja h1 { margin-top: 0; }
.login-intro { color: var(--adei-azul-medio); margin-top: -6px; }
.login-error {
  background: #fef2f2;
  border: 1px solid var(--adei-rojo);
  color: var(--adei-rojo);
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 14px;
}

/* ── Órdenes de cambio (Fase 3, paso B) ── */
.subtitulo-obra { font-size: 14px; font-weight: 400; color: var(--adei-azul-medio); }
.der { text-align: right; }
.neg { color: var(--adei-rojo); }
.pos { color: var(--adei-verde); }

/* Listado agrupado por estado. */
.bloque-oc { margin-bottom: 22px; }
.bloque-oc-cab { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.bloque-oc-cab h2 { margin: 0; font-size: 15px; }
.badge-oc { color: #fff; font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 10px; }
.oc-num { font-weight: 700; color: var(--adei-azul-medio); white-space: nowrap; }
.oc-sub { font-size: 12px; color: #6b7280; }
.oc-meta { font-size: 10px; color: #9aa3b2; margin-top: 2px; }
.oc-estimado { color: #9a5b00; }
.oc-acciones { white-space: nowrap; }
.oc-acciones form { display: inline; margin: 0; }
.oc-aprob { font-size: 11px; color: var(--adei-verde); font-weight: 600; }
.oc-rech { font-size: 11px; color: var(--adei-rojo); }
/* A escala (pasada de visibilidad): cada orden despliega sus partidas en solo lectura.
   La flecha va pegada al número; el detalle es una fila que empieza plegada. Ver la lista. */
.plegar-oc { margin-right: 4px; vertical-align: middle; }
.oc-detalle-fila > td { padding: 0; background: #f7f9fc; }
.oc-detalle { padding: 6px 12px 12px; }
.oc-detalle-meta { display: flex; flex-wrap: wrap; gap: 6px 20px; font-size: 12px;
  color: #475569; margin: 6px 0 10px; }
.tabla-oc-detalle { margin: 0; font-size: 13px; }
.tabla-oc-detalle .neg { color: var(--adei-rojo); }

/* Cabecera de la lista de órdenes: varios botones a la derecha. */
.oc-cab-acciones { display: flex; gap: 8px; align-items: center; }

/* Botón «Precios por cerrar» y formulario de cierre (paso 4): violeta, el mismo
   color de las estimadas en la certificación. */
.boton-estimado { border-color: #6b3fc0; color: #6b3fc0; }
.oc-cerrar-precio { display: flex; flex-direction: column; gap: 8px; max-width: 340px; }
.oc-cerrar-precio label { font-size: 12px; font-weight: 600; color: #4b5563; display: flex; flex-direction: column; gap: 3px; }
.oc-cerrar-precio input { padding: 6px 8px; font-size: 13px; }
.oc-cerrar-precio .boton { margin-top: 2px; align-self: flex-start; }

/* Resumen de órdenes de cambio en la ficha de la obra (paso F3). */
.oc-resumen { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.oc-resumen-pill { font-size: 13px; padding: 3px 12px; border-radius: 999px; border: 1px solid #d8e0ee; }
.oc-resumen-pill strong { font-size: 15px; }
.oc-pill-aprob { background: #e6f7f0; color: #0a7a55; border-color: #bfe8d6; }
.oc-pill-pend  { background: #fff3e0; color: #9a5b00; border-color: #f0dcc0; }
.oc-pill-rech  { background: #fdeaea; color: #991b1b; border-color: #f2cccc; }
.oc-resumen-importe { margin-left: auto; font-size: 13px; color: #6b7280; }
.oc-resumen-importe strong { font-size: 16px; color: var(--adei-navy); }
.oc-resumen-importe strong.neg { color: var(--adei-rojo); }

/* Ficha completa de una orden de cambio (paso F). */
.oc-ficha-cab h1 .oc-num { margin-right: 6px; }
.oc-aprobacion .datos { margin: 0; }
.oc-neto { text-align: right; font-size: 14px; margin: 6px 2px 22px; }
.oc-neto strong { font-size: 16px; color: var(--adei-navy); }
.oc-neto strong.neg, .tabla-oc-ficha .neg { color: var(--adei-rojo); }
.oc-motivo-ficha { font-size: 12px; color: #6b7280; margin-top: 3px; }
.oc-justif-enlace { font-weight: 600; color: var(--adei-azul-medio); }

/* Pantalla «Partidas no aprobadas» (Ajuste 2, paso B). */
.oc-noap-intro { color: #6b7280; font-size: 13px; margin: -6px 0 18px; max-width: 720px; }
.tabla-noap th:last-child { width: 42%; }
.oc-noap-quien { font-size: 13px; white-space: nowrap; }
.oc-noap-motivo { display: flex; gap: 8px; align-items: flex-start; margin: 0; }
.oc-noap-motivo textarea {
  flex: 1; resize: vertical; min-height: 40px; padding: 6px 8px;
  border: 1px solid #d3dbe8; border-radius: 8px; font: inherit; font-size: 13px;
}
.oc-noap-motivo textarea:focus { outline: none; border-color: var(--adei-azul-medio); }

/* Formulario: caja de partidas. */
.campo-check { display: flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; }
.campo-check input { width: 17px; height: 17px; }
.oc-partidas-caja { background: #F4F6FA; border-radius: 10px; padding: 12px; }
.oc-partidas-cab { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.oc-partidas-tit { font-weight: 700; font-size: 13px; color: var(--adei-navy); flex: 1; }
.oc-partidas-tit em { font-weight: 400; color: #9aa3b2; font-size: 11px; font-style: normal; }
.oc-fila { background: #fff; border: 1px solid #e3e8f0; border-radius: 8px; padding: 8px; margin-bottom: 6px; }
.oc-fila-l1 { display: flex; gap: 6px; align-items: center; margin-bottom: 6px; }
.oc-fila-l2 { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr auto; gap: 6px; align-items: center; }
.oc-fila .fi { font: inherit; font-size: 12px; padding: 5px 8px; border: 1px solid #d3dbe8; border-radius: 6px; background: #fff; color: var(--adei-navy); width: 100%; }
.oc-fila .oc-cod { max-width: 70px; }
.oc-fila .oc-tit { flex: 1; }
.oc-principal { font-size: 11px; display: flex; align-items: center; gap: 4px; white-space: nowrap; cursor: pointer; }
.oc-depende { font-size: 11px; display: flex; align-items: center; gap: 4px; white-space: nowrap; color: var(--adei-azul-medio); }
.oc-estimado-chk { font-size: 11px; display: flex; align-items: center; gap: 4px; white-space: nowrap; cursor: pointer; color: #9a5b00; }
/* Etiqueta «≈ estimado» (precio provisional) y aviso del OK para avanzar. */
.oc-est-tag { background: #fff3e0; color: #9a5b00; font-size: 10px; }
.oc-avanzar-aviso { background: #fff8ee; border: 1px solid #f0dcc0; border-radius: 8px; padding: 10px 12px; margin-top: 14px; font-size: 13px; color: #7a4a00; }
.oc-depende select { font: inherit; font-size: 11px; padding: 3px 6px; border: 1px solid #d3dbe8; border-radius: 6px; background: #fff; color: var(--adei-navy); max-width: 180px; }
.oc-fila-total { font-size: 11px; font-weight: 700; color: var(--adei-verde); text-align: right; white-space: nowrap; }
.oc-fila-total.neg { color: var(--adei-rojo); }
.oc-totales { font-size: 13px; background: #fff; border: 1px solid #86EFAC; border-radius: 8px; padding: 10px; margin-top: 10px; }
.oc-tot-linea { display: flex; justify-content: space-between; }
.oc-tot-margen { border-top: 1px dashed #ccc; margin-top: 4px; padding-top: 4px; }

@media (max-width: 640px) {
  .oc-fila-l2 { grid-template-columns: 1fr 1fr; }
}

/* Pantalla de aprobar. */
.oc-aprobar-info { font-size: 13px; color: var(--adei-azul-medio); background: #F4F6FA; border-radius: 8px; padding: 10px 12px; }
.oc-aprob-fila { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border: 1px solid #e3e8f0; border-radius: 7px; margin-bottom: 5px; background: #fff; font-size: 13px; cursor: pointer; }
.oc-aprob-tit { flex: 1; }
/* Grupos en la pantalla de aprobar: la principal manda, sus dependientes van sangradas. */
.oc-grupo { border: 1px solid #dbe3f0; border-radius: 9px; padding: 8px; margin-bottom: 10px; background: #F8FAFD; }
.oc-grupo-cab { font-size: 11px; font-weight: 700; color: var(--adei-azul-medio); text-transform: uppercase; letter-spacing: .04em; margin: 0 2px 6px; }
.oc-grupo .oc-aprob-fila.oc-dep { margin-left: 22px; border-style: dashed; }
.oc-grupo-indep { border-color: #BFDBFE; background: #EFF6FF; }
.oc-aprob-fila.oc-bloqueada { opacity: .6; cursor: not-allowed; }
.oc-plazo-caja { background: #FEF2F2; border: 1px solid #FECACA; border-radius: 8px; padding: 10px 12px; }
.oc-plazo-tit { font-weight: 700; font-size: 13px; color: var(--adei-rojo); margin-bottom: 6px; }
.oc-plazo-fila { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; font-size: 13px; }
.oc-plazo-sem input { width: 90px; font: inherit; padding: 5px 8px; border: 1px solid #d3dbe8; border-radius: 6px; margin-left: 4px; }
.oc-ok-caja { background: #EFF6FF; border: 1px solid #BFDBFE; border-radius: 8px; padding: 10px 12px; }
.oc-ok-tit { font-weight: 700; font-size: 13px; color: #1D4ED8; margin-bottom: 8px; }

/* ── Impresión (paso F4): ficha de la orden lista para imprimir / guardar como
   PDF. Se ocultan la cabecera del sitio, el pie y todo lo marcado como no-print
   (botones de navegación), y se limpia el aspecto para que salga un documento
   sobrio, útil como justificante para el cliente. ── */
@media print {
  .adei-cabecera,
  .adei-pie,
  .no-print { display: none !important; }

  body { background: #fff; }
  .adei-contenido { margin: 0; padding: 0; max-width: none; }

  /* Tarjetas planas (sin sombra) y sin cortarse a mitad de página. */
  .adei-tarjeta { box-shadow: none; border: 1px solid #d8d8d8; break-inside: avoid; }
  .tabla { break-inside: auto; }
  tr { break-inside: avoid; }

  /* Enlaces como texto normal (en papel no se pincha). */
  a { color: inherit; text-decoration: none; }

  /* Respetar los colores de las etiquetas/pastillas al imprimir. */
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ── Aviso de confirmación (flash "✓ guardado") ──
   Aparece un momento tras guardar y se desvanece solo (sin JavaScript). Da la
   señal de "ha funcionado" sin que haya que salir a comprobarlo. */
.aviso-ok {
  background: var(--adei-verde);
  color: #fff;
  font-weight: 600;
  padding: 10px 16px;
  border-radius: 8px;
  margin-bottom: 16px;
  box-shadow: 0 2px 6px rgba(16, 185, 129, .25);
  /* Visible del todo unos 3 s y luego se atenúa hasta desaparecer. */
  animation: aviso-ok-fade 4s ease forwards;
}
@keyframes aviso-ok-fade {
  0%   { opacity: 0; transform: translateY(-4px); }
  8%   { opacity: 1; transform: translateY(0); }
  75%  { opacity: 1; }
  100% { opacity: 0; visibility: hidden; }
}

/* Banner "acta enviada y bloqueada" (Paso E de actas). A diferencia del aviso de
   guardado, este NO se desvanece: recuerda de forma permanente que el acta está
   cerrada mientras se mira. Tono sobrio (ámbar de "candado"), no de error. */
.aviso-bloqueada {
  background: #fff8e6;
  color: #8a5b00;
  border: 1px solid #f0d38a;
  padding: 10px 16px;
  border-radius: 8px;
  margin-bottom: 12px;
  line-height: 1.4;
}

/* ── 📋 Temas a tratar de un acta (Paso B) ── */
.lista-temas { list-style: none; padding: 0; margin: 0 0 14px; }
.tema-fila { display: flex; align-items: center; gap: 8px; padding: 4px 0; }
.tema-form { display: flex; align-items: center; gap: 8px; flex: 1; margin: 0; }
.tema-texto { flex: 1; }
/* Punto ya tratado: tachado y atenuado. */
.tema-hecho { text-decoration: line-through; color: #6b7280; }
.tema-nuevo { display: flex; gap: 8px; margin: 0; }
.tema-nuevo input[type="text"] { flex: 1; }
/* Punto que ya pasó a tratados: pista discreta en verde. */
.tema-pasado { font-size: 12px; color: #0a7a55; white-space: nowrap; }

/* ── ✅ Temas tratados de un acta (Paso C1) ── */
.tratado {
  border: 1px solid var(--adei-borde, #dbe1ec);
  border-left: 3px solid var(--adei-verde);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 12px;
  background: #fff;
}
.tratado .formulario { margin: 0; }
/* Pista de que el tratado nació de un punto del orden del día. */
.tratado-origen { font-size: 12px; color: #0a7a55; margin: 0 0 6px; }
/* Casilla "impacta planificación" en línea con su texto. */
.check-inline { display: flex; align-items: center; gap: 8px; font-size: 13px; align-self: end; padding-bottom: 8px; }
.check-inline input[type="checkbox"] { width: auto; }
.tratado-nuevo { margin-top: 6px; }
.tratado-nuevo > summary { cursor: pointer; font-weight: 600; color: var(--adei-azul-medio); }
/* 📷 Fotos del tratado (Paso C2; galería de varias). */
.tratado-fotos { display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap; margin: 4px 0 2px; }
.tratado-foto-item { display: flex; flex-direction: column; gap: 5px; align-items: center; }
.tratado-foto-mini img {
  max-width: 140px; max-height: 140px;
  border-radius: 8px; border: 1px solid var(--adei-borde, #dbe1ec); display: block;
}
.tratado-foto-add { align-self: flex-end; }

/* ── 📎 Documentación reclamada de un acta (Paso D) ── */
.lista-docs { list-style: none; padding: 0; margin: 0 0 14px; }
.doc-fila { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 7px 0; border-bottom: 1px solid var(--adei-borde, #dbe1ec); }
.doc-form { display: flex; align-items: center; gap: 8px; flex: 1; margin: 0; flex-wrap: wrap; }
.doc-desc { flex: 1; min-width: 160px; }
.doc-quien, .doc-fecha { flex: 0 0 auto; }
/* Documento ya recibido: descripción tachada y atenuada. */
.doc-recibido .doc-desc, .doc-recibido span.doc-desc { text-decoration: line-through; color: #6b7280; }
/* Aviso de vencida: rojo. */
.doc-vencida { font-size: 11px; font-weight: 700; color: var(--adei-rojo); white-space: nowrap; }
.doc-nuevo { display: flex; gap: 8px; flex-wrap: wrap; margin: 0; }
.doc-nuevo input[type="text"] { flex: 1; min-width: 180px; }

/* ── Estado del documento (fleco Paso D): zona SIEMPRE activa con recibido +
      archivo + revisado por ADEI. Va en su propia línea, debajo de los datos. ── */
.doc-estado { order: 2; flex: 1 1 100%; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 2px 0 2px 2px; font-size: 13px; }
.doc-recibido-form { display: flex; align-items: center; gap: 12px; margin: 0; flex: 0 0 auto; }
.doc-quitar-archivo { display: flex; align-items: center; margin: 0; flex: 0 0 auto; }
/* Bloque «Revisado por ADEI»: ocupa su propia línea dentro del estado. */
.doc-revision { flex: 1 1 100%; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0; }
.doc-revision-edit { display: flex; align-items: center; gap: 6px; margin: 0; flex: 1 1 240px; }
.doc-revision-quitar { margin: 0; flex: 0 0 auto; }
/* Campo del comentario de la revisión: qué se vio, posibles cambios. */
.doc-com-icono { flex: 0 0 auto; }
.doc-com-input { flex: 1; min-width: 140px; }
/* Casilla + texto (recibido / revisado): clicable, alineada. */
.doc-check { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; white-space: nowrap; }
.doc-check input { margin: 0; }
/* Adjuntar / cambiar archivo: parece un enlace de acción. */
.doc-adjuntar { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; color: var(--adei-azul-medio); font-weight: 600; white-space: nowrap; }
.doc-adjuntar:hover { text-decoration: underline; }
.doc-archivo { color: var(--adei-azul-medio); font-weight: 600; text-decoration: none; white-space: nowrap; }
.doc-archivo:hover { text-decoration: underline; }
/* Sello del visto bueno de ADEI: verde. */
.doc-sello-revisado { color: var(--adei-verde); font-weight: 700; white-space: nowrap; }
/* Recordatorio de control de calidad: ámbar, sobrio. */
.doc-pendiente-revisar { color: #B45309; font-weight: 600; white-space: nowrap; }
/* Generar OC desde el comentario de la revisión (Paso F). */
.doc-generar-oc { flex: 0 0 auto; color: var(--adei-azul-medio); font-weight: 700; text-decoration: none; white-space: nowrap; }
.doc-generar-oc:hover { text-decoration: underline; }

/* ── 🔄 Órdenes de cambio nacidas en un acta (Paso F) ── */
.lista-oc-acta { list-style: none; padding: 0; margin: 0 0 14px; }
.oc-acta-fila { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--adei-borde, #dbe1ec); flex-wrap: wrap; }
.oc-acta-link { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 200px; text-decoration: none; color: inherit; }
.oc-acta-link:hover .oc-acta-tit { text-decoration: underline; }
.oc-acta-cod { font-weight: 700; color: var(--adei-azul-medio); flex: 0 0 auto; }
.oc-acta-tit { font-weight: 600; }
.oc-acta-estado { flex: 0 0 auto; font-size: 12px; font-weight: 700; white-space: nowrap; }
.oc-estado-pendiente { color: #9a5b00; }
.oc-estado-aprobada { color: #0a7a55; }
.oc-estado-rechazada { color: #991b1b; }
.oc-acta-importe { flex: 0 0 auto; font-weight: 700; white-space: nowrap; }
.oc-acta-importe.neg { color: var(--adei-rojo); }
/* Aviso de origen en el formulario y la ficha de la OC. */
.oc-origen-acta, .oc-nacio-acta { margin: 0 0 14px; padding: 8px 12px; border-radius: 8px;
  background: rgba(30, 58, 110, 0.08); color: var(--adei-azul-medio); font-size: 14px; }
.oc-nacio-acta a { color: var(--adei-azul-medio); font-weight: 700; }

/* ── 📐 Planos (Fase 4) — Paso F4: leyenda del semáforo por tipo ── */
.planos-leyenda { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: -6px 0 18px; font-size: 12px;
  color: var(--adei-gris, #6b7280); }
.planos-leyenda .ley { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }

/* ── 📐 Planos A ESCALA: plegar cada tipo + FILTRAR POR GREMIO (pasada de visibilidad) ──
   Solo enseña/esconde y pliega; la lógica de Planos no se toca. Ver el <script> de la hoja. */
.plano-tipo.grupo-plegado > *:not(.cabecera-fases) { display: none; }
.plano-tipo.oculto-filtro { display: none; }
/* La barra de chips de gremio (el filtro). Los gremios salen del Gantt. */
.planos-gremios-barra { display: flex; flex-wrap: wrap; gap: 6px; margin: 0.6rem 0 0.2rem; }
.gremio-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px;
  background: #EEF1F6; border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 999px;
  font-size: 13px; font-weight: 600; color: var(--adei-navy, #16264D); cursor: pointer; }
.gremio-chip:hover { border-color: #1E3A6E; }
.gremio-chip .contador { background: rgba(22, 38, 77, 0.10); }
.gremio-chip-activo { background: var(--adei-navy, #16264D); color: #fff; border-color: var(--adei-navy, #16264D); }
.gremio-chip-activo .contador { background: rgba(255, 255, 255, 0.22); color: #fff; }
/* Las etiquetas de gremio sobre la cabecera de cada tipo (a qué oficios sirve). */
.tipo-gremio-chip { display: inline-block; margin-left: 4px; padding: 1px 7px; border-radius: 999px;
  background: #E7EDF7; color: #1E3A6E; font-size: 11px; font-weight: 600; vertical-align: middle; }
.tipo-gremio-sin { background: #F1F0EC; color: var(--adei-gris, #6b7280); font-style: italic; }

/* ── 📐 Planos (Fase 4) — Paso A: tipos de plano de la obra ── */
.lista-tipos-plano { list-style: none; padding: 0; margin: 0 0 14px; display: flex; flex-wrap: wrap; gap: 8px; }
.tipo-plano-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 6px 5px 12px;
  background: #EEF1F6; border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 999px; }
.tipo-plano-nombre { font-size: 13px; font-weight: 600; color: var(--adei-navy, #16264D); white-space: nowrap; }
.tipo-plano-chip form { margin: 0; display: flex; }
.tipo-plano-x { border: none; background: transparent; cursor: pointer; color: #94a3b8; font-size: 16px;
  line-height: 1; padding: 0 2px; border-radius: 50%; }
.tipo-plano-x:hover { color: #fff; background: var(--adei-rojo); }
.tipo-plano-nuevo { display: flex; gap: 8px; flex-wrap: wrap; margin: 0; }
.tipo-plano-nuevo input[type="text"] { flex: 1; min-width: 180px; }

/* ── 📐 Planos (Fase 4) — Paso B: planos de cada tipo ── */
.lista-planos { list-style: none; padding: 0; margin: 0 0 12px; }
.plano-fila { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--adei-borde, #dbe1ec); flex-wrap: wrap; }
.plano-miniatura { flex: 0 0 auto; display: block; }
.plano-miniatura img { width: 56px; height: 56px; object-fit: cover; border-radius: 6px; border: 1px solid var(--adei-borde, #dbe1ec); display: block; }
.plano-icono { flex: 0 0 auto; font-size: 34px; width: 56px; text-align: center; }
.plano-datos { flex: 1; min-width: 180px; }
.plano-nombre { font-weight: 700; color: var(--adei-navy, #16264D); text-decoration: none; }
.plano-nombre:hover { text-decoration: underline; }
.plano-meta { font-size: 11px; color: var(--adei-gris, #6b7280); margin-top: 2px; }
.plano-nuevo { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 0; }
.plano-nuevo input[type="text"] { flex: 1; min-width: 160px; }
/* Versiones de un plano (Paso C). */
.plano-titulo-linea { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.plano-version-badge { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .3px;
  color: #fff; background: var(--adei-verde, #10B981); border-radius: 999px; padding: 2px 8px; white-space: nowrap; }
.plano-nota { color: var(--adei-gris, #6b7280); font-style: italic; }
/* Checklist de decisiones por tipo (Paso E). */
.plano-checklist { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--adei-borde, #dbe1ec); }
.plano-checklist-tit { font-size: 13px; font-weight: 700; color: var(--adei-navy, #16264D); margin: 0 0 8px; }
.lista-decisiones { list-style: none; padding: 0; margin: 0 0 12px; }
.decision-fila { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 6px 0;
  border-bottom: 1px solid var(--adei-borde, #dbe1ec); }
.decision-texto { flex: 1; min-width: 160px; font-weight: 600; }
.decision-fila.estado-si .decision-texto { color: var(--adei-verde, #10B981); }
.decision-fila.estado-no .decision-texto { color: #6b7280; text-decoration: line-through; }
.decision-form { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0; }
.decision-comentario { min-width: 140px; }
.decision-borrar { margin: 0; }
.decision-sello { font-size: 10px; font-weight: 700; color: var(--adei-verde, #10B981); white-space: nowrap; }
.decision-nueva { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 0; }
.decision-nueva input[type="text"] { flex: 1; min-width: 180px; }
.decision-proponer { display: inline-flex; align-items: center; gap: 5px; font-size: 12px;
  color: var(--adei-azul-medio); cursor: pointer; white-space: nowrap; }

/* Pantalla de sugerencias a la plantilla (Paso E·3, solo admin). */
.lista-sugerencias { list-style: none; padding: 0; margin: 0; }
.sugerencia-fila { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 10px 0;
  border-bottom: 1px solid var(--adei-borde, #dbe1ec); }
.sugerencia-datos { flex: 1; min-width: 220px; }
.sugerencia-tipo { display: inline-block; font-size: 10px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .3px; color: #fff; background: var(--adei-azul-medio); border-radius: 999px; padding: 2px 8px; margin-right: 6px; }
.sugerencia-texto { font-weight: 700; color: var(--adei-navy, #16264D); }
.sugerencia-meta { font-size: 11px; color: var(--adei-gris, #6b7280); margin-top: 3px; }
.sugerencia-acciones { display: flex; gap: 6px; flex: 0 0 auto; }
.sugerencia-acciones form { margin: 0; }
.sugerencia-fila.decidida { opacity: .75; }
.sugerencia-estado { font-size: 11px; font-weight: 700; white-space: nowrap; }
.estado-sug-aprobada { color: var(--adei-verde, #10B981); }
.estado-sug-descartada { color: var(--adei-rojo, #EF4444); }
.sugerencia-nueva-texto { font-size: 16px; font-weight: 700; color: var(--adei-navy, #16264D); margin: 0 0 6px; }

/* Confirmaciones del plano (Paso D): empresa / interiorista / cliente. */
.plano-confirmaciones { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; margin: 4px 0 8px; }
.plano-conf { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.plano-conf .doc-check { font-size: 12px; color: var(--adei-gris, #6b7280); }
.plano-conf .doc-check.plano-conf-ok { color: var(--adei-verde, #10B981); font-weight: 700; }
.plano-conf-sello { font-size: 10px; color: var(--adei-verde, #10B981); font-weight: 700; white-space: nowrap; }
.plano-versiones { list-style: none; padding: 0; margin: 6px 0; font-size: 12px; }
.version-fila { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 5px 0;
  border-bottom: 1px dashed var(--adei-borde, #dbe1ec); color: var(--adei-gris, #6b7280); }
.version-num { flex: 0 0 auto; color: var(--adei-navy, #16264D); }
.version-info { flex: 1; min-width: 140px; }
.version-actual-tag { font-size: 9px; font-weight: 800; text-transform: uppercase; color: var(--adei-verde, #10B981); }
.plano-version-nueva { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 8px 0 0; }
.plano-version-nueva input[type="text"] { flex: 1; min-width: 160px; }

/* ── 📧 Seguimiento semanal (Fase 4) — Paso A ── */
/* Aviso del estado de la semana en curso (enviado / pendiente). */
.seg-aviso { padding: 10px 14px; border-radius: 8px; font-size: 13px; margin: 0 0 16px; line-height: 1.4; }
.seg-aviso-ok { background: #F0FDF4; border: 1px solid #86EFAC; color: #166534; }
.seg-aviso-pendiente { background: #FEF2F2; border: 1px solid #FCA5A5; color: #991B1B; }
/* Rango de semana en la ficha del parte. */
.seg-semana { background: var(--adei-fondo-claro, #F4F6FA); border-radius: 8px; padding: 8px 12px;
  font-size: 13px; color: var(--adei-navy, #16264D); margin: 0 0 16px; }
/* Resumen del contenido en la lista (recorte de «realizados»). */
.seg-resumen { font-size: 12px; color: var(--adei-gris, #6b7280); white-space: pre-line;
  max-height: 3em; overflow: hidden; }
/* Rastro de auditoría al pie de la ficha (Decisión 4). */
.seg-rastro { font-size: 11px; color: var(--adei-gris, #6b7280); margin: 14px 0 0; }
/* Contador de remate en la lista (Paso D). */
.seg-remate { font-size: 13px; color: var(--adei-navy, #16264D); margin: 0 0 14px; }
/* Acciones de un parte enviado (reabrir / borrar admin) y borrar borrador. */
.seg-acciones-enviado { margin-top: 14px; gap: 10px; }
.seg-borrar-borrador { margin: 16px 0 0; }
/* Fotos/vídeos del parte (Paso B). */
.seg-archivos { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--adei-borde, #dbe1ec); }
.seg-contador { font-size: 11px; font-weight: 700; margin-left: 8px; }
.seg-contador-ok { color: var(--adei-verde, #10B981); }
.seg-contador-falta { color: var(--adei-ambar, #F59E0B); }
.seg-galeria { display: flex; flex-wrap: wrap; gap: 10px; margin: 6px 0 12px; }
.seg-archivo { position: relative; width: 96px; }
.seg-archivo img { width: 96px; height: 96px; object-fit: cover; border-radius: 8px;
  border: 1px solid var(--adei-borde, #dbe1ec); display: block; }
.seg-archivo-icono { display: flex; align-items: center; justify-content: center;
  width: 96px; height: 96px; font-size: 40px; background: var(--adei-fondo-claro, #F4F6FA);
  border-radius: 8px; border: 1px solid var(--adei-borde, #dbe1ec); }
.seg-archivo form { position: absolute; top: -6px; right: -6px; margin: 0; }
.seg-archivo-x { width: 22px; height: 22px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--adei-rojo, #EF4444); color: #fff; font-size: 15px; line-height: 1; }
.seg-subir { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 0; }

/* ── 📦 Hoja de Suministros (Fase 4) — Paso B ── */
.rejilla-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }
@media (max-width: 720px) { .rejilla-3 { grid-template-columns: 1fr; } }
.lista-opciones { list-style: none; padding: 0; margin: 0 0 12px; }
.opcion-fila { display: flex; align-items: center; gap: 10px; padding: 7px 0; flex-wrap: wrap;
  border-bottom: 1px solid var(--adei-borde, #dbe1ec); }
.opcion-fila form { margin: 0; }
.opcion-check { flex: 0 0 auto; }
.opcion-nombre { font-weight: 600; color: var(--adei-navy, #16264D); }
.opcion-prov { font-size: 12px; color: var(--adei-gris, #6b7280); }
.opcion-precio { margin-left: auto; font-weight: 700; color: var(--adei-navy, #16264D); white-space: nowrap; }
/* Precio por unidad (discreto) y total de la línea (el que manda), Paso D·bis. */
.precio-unit { font-weight: 500; font-size: 12px; color: var(--adei-gris, #6b7280); margin-right: 8px; }
.precio-total { font-weight: 700; }
.opcion-elegida { background: #f0fbf6; border-radius: 6px; }
.opcion-tag-elegida { font-size: 10px; font-weight: 800; text-transform: uppercase; color: #fff;
  background: var(--adei-verde, #10B981); border-radius: 999px; padding: 2px 8px; }
.opcion-nueva { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 0; }
.opcion-nueva input[type="text"] { flex: 1; min-width: 140px; }
.opcion-nueva .campo-precio { flex: 0 0 110px; min-width: 90px; }
/* Estancias / zonas (Paso C). */
.lista-estancias { list-style: none; padding: 0; margin: 0 0 12px; display: flex; flex-wrap: wrap; gap: 8px; }
.estancia-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 6px 5px 12px;
  background: #EEF1F6; border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 999px;
  font-size: 13px; font-weight: 600; color: var(--adei-navy, #16264D); }
.estancia-chip form { margin: 0; display: flex; }
.estancia-x { border: none; background: transparent; cursor: pointer; color: #94a3b8; font-size: 16px;
  line-height: 1; padding: 0 2px; border-radius: 50%; }
.estancia-x:hover { color: #fff; background: var(--adei-rojo, #EF4444); }
.estancia-nueva { display: flex; gap: 8px; flex-wrap: wrap; margin: 0; }
.estancia-nueva input[type="text"] { flex: 1; min-width: 180px; }
/* Grupo de necesidades de una estancia, y cada necesidad dentro. */
.estancia-grupo .suministro { padding: 12px 0; border-top: 1px solid var(--adei-borde, #dbe1ec); }
.estancia-grupo .suministro:first-of-type { border-top: none; }
/* A escala (pasada de visibilidad): el grupo de estancia se pliega y el buscador filtra.
   Solo enseña/esconde; la lógica de suministros no se toca. Ver el <script> de la hoja. */
.estancia-grupo.grupo-plegado .suministro { display: none; }
.suministro.oculto-busqueda { display: none; }
.estancia-grupo.oculto-busqueda { display: none; }
.plegar-grupo { vertical-align: middle; }
.suministro-titulo { font-size: 15px; color: var(--adei-navy, #16264D); margin: 0; }
.suministro-acciones { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.suministro-acciones form { margin: 0; }
/* Cantidad + unidad editables junto a cada necesidad (Paso D·bis). */
.etiqueta-cantidad { background: var(--adei-navy, #16264D); color: #fff; }
.etiqueta-trozo { background: #FEF3C7; color: #92400E; }
/* Unidad anulada (Paso D·bis·2b): sigue a la vista, tachada y en gris. */
.etiqueta-anulada { background: var(--adei-rojo, #EF4444); color: #fff; }
.suministro-anulado { opacity: 0.72; background: #F7F8FA; }
.texto-anulado { text-decoration: line-through; color: var(--adei-gris, #6b7280); }
.rastro-anulacion { font-size: 12px; color: var(--adei-gris, #6b7280); margin: 0 0 10px;
  border-left: 3px solid var(--adei-rojo, #EF4444); padding-left: 10px; }
.rastro-reactivada { border-left-color: var(--adei-verde, #10B981); }
/* El diferencial a la vista (Paso D·bis·2c). */
.tarjeta-cambios { border-left: 4px solid var(--adei-azul-medio, #1E3A6E); }
.tabla-cambios { width: 100%; border-collapse: collapse; font-size: 14px; }
.tabla-cambios th, .tabla-cambios td { padding: 8px 10px; border-bottom: 1px solid var(--adei-borde, #dbe1ec); }
.tabla-cambios thead th { font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--adei-gris, #6b7280); }
.tabla-cambios tfoot td { border-bottom: none; border-top: 2px solid var(--adei-navy, #16264D); }
.cambio-capitulo { font-size: 11px; color: var(--adei-gris, #6b7280); margin-left: 6px; }
.cambio-mas { color: var(--adei-rojo, #EF4444); font-weight: 700; white-space: nowrap; }
.cambio-menos { color: var(--adei-verde, #10B981); font-weight: 700; white-space: nowrap; }
.etiqueta-mas { background: var(--adei-rojo, #EF4444); color: #fff; }
.etiqueta-menos { background: var(--adei-verde, #10B981); color: #fff; }
.etiqueta-presupuestada { background: #E5E9F0; color: var(--adei-navy, #16264D); }
.anular-form { display: flex; gap: 4px; align-items: center; }
.anular-form .campo-motivo { width: 130px; font-size: 12px; padding: 4px 8px;
  border-radius: 8px; border: 1px solid #cdd5e3; }
.cantidad-editar { display: flex; gap: 4px; align-items: center; }
.cantidad-editar input { font-size: 12px; padding: 4px 8px; border-radius: 8px; border: 1px solid #cdd5e3; }
.cantidad-editar .campo-cantidad { width: 62px; text-align: right; }
.cantidad-editar .campo-unidad { width: 56px; }
.estancia-mover select { font-size: 12px; padding: 4px 8px; border-radius: 8px; border: 1px solid #cdd5e3; }


/* ── Suministros · Paso E1: comparar y confirmar ── */
/* Compra cerrada: la necesidad entera se ve en verde, con candado. */
.etiqueta-confirmada { background: var(--adei-verde, #10B981); color: #fff; }
.etiqueta-barata { background: #ECFDF5; color: #047857; }
.suministro-confirmado { background: #F3FBF7; }
.boton-mini-ok { border-color: var(--adei-verde, #10B981); color: #047857; font-weight: 700; }
.boton-mini-ok:hover { background: var(--adei-verde, #10B981); color: #fff; }
/* Qué falta para poder confirmar (en vez de esconder el botón sin explicar por qué). */
.falta-confirmar { font-size: 11px; color: var(--adei-gris, #6b7280); font-style: italic; }

/* GREMIOS · por qué un gremio NO se puede borrar. Mismo criterio que arriba: en vez de
   esconder el botón sin más, se dice el motivo (lo usan 3 partidas, está en el Gantt…).
   Un botón que desaparece sin explicación empuja a la persona a equivocarse. */
.no-borrable {
  display: block;
  max-width: 260px;
  font-size: 11px;
  line-height: 1.35;
  color: var(--adei-gris, #6b7280);
  font-style: italic;
}
/* Rastro de la confirmación / de la reapertura (mismo lenguaje que el de la anulación). */
.rastro-confirmacion { font-size: 12px; color: var(--adei-gris, #6b7280); margin: 0 0 10px;
  border-left: 3px solid var(--adei-verde, #10B981); padding-left: 10px; }
.rastro-reabierta { border-left-color: #F59E0B; }
/* Las dos comparaciones de cada opción: contra la más barata y contra el presupuesto. */
.opcion-compara { display: flex; gap: 10px; flex-wrap: wrap; font-size: 11px;
  color: var(--adei-gris, #6b7280); }
.compara-barata { white-space: nowrap; }
/* Editor en línea de una opción: se despliega al pulsar el lápiz (sin JavaScript). */
.opcion-editar { display: inline-block; }
.opcion-editar summary { list-style: none; cursor: pointer; display: inline-block; }
.opcion-editar summary::-webkit-details-marker { display: none; }
.opcion-editar form { display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
  margin-top: 8px; padding: 8px; background: var(--adei-fondo-claro, #F4F6FA);
  border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 10px; }
.opcion-editar input, .opcion-editar select { font-size: 12px; padding: 4px 8px;
  border-radius: 8px; border: 1px solid #cdd5e3; }

/* ── Suministros · Paso E2: pestañas (sin confirmar / confirmadas) ── */
.pestanas { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 14px; }
.pestana { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px;
  border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 999px; background: #fff;
  color: var(--adei-navy, #16264D); font-size: 13px; font-weight: 700; text-decoration: none; }
.pestana:hover { background: var(--adei-fondo-claro, #F4F6FA); }
.pestana-activa { background: var(--adei-navy, #16264D); color: #fff;
  border-color: var(--adei-navy, #16264D); }
.pestana-activa .contador { background: rgba(255, 255, 255, .22); color: #fff; }
.pestanas-total { margin-left: auto; font-size: 12px; color: var(--adei-gris, #6b7280); }
.pestanas-total strong { color: var(--adei-navy, #16264D); }

/* ── Suministros · Paso E3: la marca (y la agenda que la aprende sola) ── */
.etiqueta-marca { background: #EEF2FF; color: #3730A3; }
/* La marca que ya se le ha COMPRADO de verdad (no solo mencionado): destacada. */
.etiqueta-marca-usada { background: var(--adei-azul-medio, #1E3A6E); color: #fff; }
.marca-usos { display: inline-block; min-width: 16px; padding: 0 4px; margin-left: 2px;
  border-radius: 999px; background: rgba(255, 255, 255, .25); font-weight: 800; }
.campo-marca { width: 110px; }
/* La fecha del precio: pequeña, gris, siempre a la vista (los precios caducan). */
.precio-fecha { font-size: 10px; color: var(--adei-gris, #6b7280); margin-left: 6px;
  white-space: nowrap; }

/* ── Suministros · Paso E4: la sugerencia al revés (marca → quién la trabaja) ── */
.sugerencia-marca { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  width: 100%; margin-top: 6px; padding: 6px 10px; border-radius: 10px;
  background: #EEF2FF; border: 1px dashed #C7D2FE; }
.sugerencia-marca form { margin: 0; }
.sugerencia-marca-titulo { font-size: 11px; font-weight: 700; color: #3730A3; }
.sugerencia-prov { background: #fff; border-color: #C7D2FE; color: var(--adei-navy, #16264D); }
.sugerencia-prov:hover { background: var(--adei-navy, #16264D); color: #fff; }
.sugerencia-prov .marca-usos { background: var(--adei-azul-medio, #1E3A6E); color: #fff; }
.sugerencia-estrellas { color: #F59E0B; font-size: 10px; }
.sugerencia-elegida { background: var(--adei-verde, #10B981); color: #fff;
  border-color: var(--adei-verde, #10B981); }
/* El buscador de la agenda con sus dos campos (oficio y marca). */
.buscador input[type="search"] { min-width: 200px; }

/* ── Suministros · Paso F1: el broche (sobrecoste → orden de cambio) ── */
/* El sello de una línea ya volcada a una OC (sigue a la vista, Decisión 3). */
.etiqueta-oc { background: var(--adei-azul-medio, #1E3A6E); color: #fff;
  text-decoration: none; }
.etiqueta-oc:hover { background: var(--adei-navy, #16264D); }
/* Pantalla de confirmación: el resumen de cabecera. */
.resumen-oc { display: flex; gap: 26px; flex-wrap: wrap; margin: 10px 0 4px; }
.resumen-dato { display: flex; flex-direction: column; gap: 2px; }
.resumen-etiqueta { font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--adei-gris, #6b7280); }
.resumen-dato strong { font-size: 20px; color: var(--adei-navy, #16264D); }
/* El porqué de cada importe, escrito bajo la partida (va también al texto de la OC). */
.oc-desglose { font-size: 11px; color: var(--adei-gris, #6b7280); margin-top: 4px;
  border-left: 3px solid var(--adei-borde, #dbe1ec); padding-left: 8px; }
.oc-conversion { font-size: 11px; color: var(--adei-azul-medio, #1E3A6E); margin-top: 4px; }
.campo-margen { width: 72px; text-align: right; font-size: 13px; padding: 5px 8px;
  border-radius: 8px; border: 1px solid #cdd5e3; }

/* ── Suministros · Paso F0·a: los dos precios (PVP / coste) y el margen ── */
.opcion-coste { display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  font-size: 11px; }
/* Coste REAL (hay factura): en firme. */
.coste-real { color: var(--adei-navy, #16264D); font-weight: 700; white-space: nowrap; }
/* Coste OBJETIVO estimado: en gris y con ≈. NUNCA debe parecer una factura. */
.coste-estimado { color: var(--adei-gris, #6b7280); font-style: italic;
  white-space: nowrap; }
.opcion-margen { color: #047857; font-weight: 700; white-space: nowrap; }
.margen-estimado { color: var(--adei-gris, #6b7280); font-weight: 600; font-style: italic; }
.ayuda-inline { font-style: normal; font-weight: 400; font-size: 11px;
  color: var(--adei-gris, #6b7280); }

/* ── Suministros · Paso F2: agrupar la orden de cambio (bloques = grupos de la OC) ── */
.fila-bloque td { background: var(--adei-fondo-claro, #F4F6FA);
  border-top: 2px solid var(--adei-navy, #16264D); }
.bloque-nota { font-size: 11px; color: var(--adei-gris, #6b7280); margin-left: 8px;
  font-style: italic; }
.etiqueta-principal { background: #FEF3C7; color: #92400E; }
.oc-marcar { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.oc-marcar input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--adei-navy, #16264D); }

/* ── CERTIFICACIÓN · LO QUE QUEDA VIVO (adicional de medición en unidades) ── */
/* La partida firmada a la que una OC dio de baja unidades: se enseña qué queda certificable. */
.cert-certificable { font-size: 11px; color: #9a5b00; margin-top: 2px; }
.cert-baja { color: #9a5b00; font-weight: 600; }

/* 🚫 LA PARTIDA SOLO INTERNA (Diego, 2026-08-27): «señalarlas con un sombreado diferente rojo
   para que no se pierdan entre el presupuesto».
   ⚠️ ROJO **MUY** CLARO Y CON BORDE A LA IZQUIERDA, no el rojo de la casa a saco: son filas de
   una tabla que se lee entera y un fondo saturado en varias filas hace ilegible el numero de al
   lado -- que es lo que se viene a leer. El borde es lo que se ve de reojo al bajar.
   ⚠️ Y GANA AL DE «opcional» cuando la fila es las dos cosas: lo de dentro se distingue por el
   rotulo, pero el aviso que hay que ver de lejos es que **el cliente no la ve**. */
.tabla .fila-solo-interna > td { background: #FEF2F2; }
.tabla .fila-solo-interna > td:first-child { box-shadow: inset 3px 0 0 #EF4444; }

/* 🧩 LOS TRABAJOS DE DENTRO, EN ROJO TAMBIEN (Diego, 2026-08-27): «las subpartidas, para ser
   mas visual, marcarlas en rojo tambien en el ERP».
   ⚠️ MISMO ROJO QUE LO «SOLO INTERNO», y no es pereza: las dos cosas significan **exactamente
   lo mismo** --el cliente no lo ve-- y darles dos colores obligaria a aprenderse dos.
   ⚠️ Y EL FONDO ES MAS CLARO QUE EL BORDE a proposito: son filas de una tabla que se lee
   entera, y un fondo saturado hace ilegible el numero de al lado, que es lo que se viene a
   leer. Lo que se ve de reojo al bajar es el borde. */
.tabla .fila-subpartida > td { background: #FEF2F2; }
.tabla .fila-subpartida > td:first-child { box-shadow: inset 3px 0 0 #EF4444; }

/* El nombre del trabajo, en el rojo de la casa: es lo que se lee al recorrer la columna. */
.tabla .fila-subpartida .nodo-titulo { color: #B91C1C; }

/* La etiqueta «solo interna», discreta: el aviso fuerte ya lo da la fila entera. */
.etiqueta-interna { background: #FEE2E2; color: #B91C1C; }

/* ⭐⭐ LO REESCRITO, EN ROJO (Diego, 2026-08-27): «el texto que cambiemos saldria en rojo para
   notificar que se esta cambiando titulo o texto por algo en especial».
   ⚠️ Rojo de la casa (#EF4444), el mismo que el del contrato en negociacion: en esta casa el
   rojo ya significa «esto no es lo que se pacto de origen», y estrenar un color nuevo para lo
   mismo obliga a aprenderse dos.
   ⚠️ Y LLEVA SUBRAYADO DE PUNTOS ademas del color: un rojo a secas desaparece en una impresion
   en blanco y negro -- y estas pantallas se imprimen. */
.cert-reescrito {
  color: #EF4444;
  text-decoration: underline dotted #EF4444;
  text-underline-offset: 2px;
}

/* La casilla de texto del editor flotante. ⚠️ Ancho fijo y no `100%`: dentro de un editor que
   esta FUERA DEL FLUJO, un `100%` se mide contra la celda --que puede tener 40 px-- y el campo
   sale como una ranura. */
.cert-edit-texto { width: 320px; max-width: 60vw; font-family: inherit; font-size: 13px; }
textarea.cert-edit-texto { resize: vertical; }
/* Aviso (NO tope): se está certificando más de lo contratado. */
.fila-cert-partida.fila-exceso td { background: #fff8e6; }
.cert-exceso { font-size: 11px; color: #9a5b00; font-weight: 600; margin-top: 2px; }
/* La baja, en la ficha de la orden de cambio (va dentro de su partida). */
.oc-sustituye { font-size: 12px; color: #9a5b00; margin-top: 3px;
  border-left: 3px solid #9a5b00; padding-left: 8px; }

/* ── OC · LA SUSTITUCIÓN: qué unidades del presupuesto se lleva por delante el cambio.
      No es otra partida: es un dato PEGADO a ella (por eso se aprueba con ella). ── */
.oc-fila-l3 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 6px; padding-top: 6px; border-top: 1px dashed var(--adei-borde, #dbe1ec); }
.oc-sust-tit { font-size: 12px; color: #9a5b00; font-weight: 600; white-space: nowrap; }
.oc-sust-nodo { flex: 1 1 240px; min-width: 180px; }
.oc-sust-uds { width: 120px; }
.oc-sust-info { font-size: 12px; color: var(--adei-gris, #6b7280); }
.oc-sust-info.activa { color: #9a5b00; font-weight: 600; }
.oc-sust-ayuda { display: block; margin-top: 4px; font-size: 11px; font-style: normal;
  color: var(--adei-gris, #6b7280); }

/* ── Suministros · EL ANTES Y EL DESPUÉS (la OC habla como una OC a mano) ── */
/* Cada cambio son dos partidas atadas: la que QUITA lo presupuestado y la que PONE lo
   nuevo. Se pintan juntas para que se lea de un vistazo de dónde sale el neto. */
.oc-par { margin: 6px 0 4px; border-left: 3px solid var(--adei-borde, #dbe1ec); padding-left: 10px; }
.oc-par-fila { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; padding: 2px 0; }
.oc-par-marca { flex: 0 0 auto; }
.oc-par-tit { flex: 1 1 auto; }
.oc-par-cuenta { flex: 0 0 auto; color: var(--adei-gris, #6b7280); white-space: nowrap; }
.oc-par-importe { flex: 0 0 auto; font-weight: 700; white-space: nowrap; min-width: 92px;
  text-align: right; }
.oc-par-quita .oc-par-tit { color: #9a5b00; }
.oc-par-pone .oc-par-tit { color: var(--adei-navy, #16264D); }

/* ── Suministros · Paso F3: los flecos ── */
/* Fleco 1: aviso de que alguna partida nacerá con el PRECIO POR CERRAR (violeta, el
   mismo color con el que las OC marcan una partida estimada: es la misma idea). */
.aviso-por-cerrar { border-left: 3px solid #6b3fc0; padding-left: 10px; }
/* Fleco 2: la hoja y la orden ya no dicen lo mismo. Es un AVISO, no un error: hay que
   verlo (ámbar), no esconderlo. */
.fila-descuadre td { background: #fff8e6; }
.aviso-descuadre { color: #9a5b00; font-size: 12px; margin-top: 4px; display: block; }
.aviso-descuadre strong { white-space: nowrap; }
.form-inline { display: inline; }
.boton-desvincular { background: none; border: 1px solid #9a5b00; color: #9a5b00;
  font-size: 11px; padding: 2px 8px; border-radius: 4px; cursor: pointer; margin-left: 6px; }
.boton-desvincular:hover { background: #9a5b00; color: #fff; }
.rastro-desvinculada { color: var(--adei-gris, #6b7280); font-size: 11px; font-style: italic; }
/* Fleco 3: de dónde nació la orden (gemelo de .oc-nacio-acta). */
.oc-nacio-suministros { background: #eef3ff; border-left: 3px solid var(--adei-azul-medio, #1E3A6E);
  padding: 8px 12px; border-radius: 4px; font-size: 13px; }

/* ══════════ Suministros · EL REMATE (Paso G) ══════════ */

/* El RESUMEN: las cuatro cifras de la obra en material, de un vistazo. */
.sum-resumen { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px; margin-bottom: 16px; }
.sum-kpi { background: #fff; border: 1px solid #e3e9f2; border-left: 4px solid var(--adei-azul-medio, #1E3A6E);
  border-radius: 10px; padding: 12px 14px; display: flex; flex-direction: column; gap: 3px; }
.sum-kpi-tit { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--adei-azul-medio, #1E3A6E); }
.sum-kpi-cifra { font-size: 21px; font-weight: 700; color: var(--adei-navy, #16264D);
  font-variant-numeric: tabular-nums; }
.sum-kpi-pie { font-size: 11px; color: var(--adei-gris, #6b7280); line-height: 1.4; }
.sum-kpi-bueno { border-left-color: var(--adei-verde, #10B981); }
.sum-kpi-bueno .sum-kpi-cifra { color: #059669; }
.sum-kpi-malo { border-left-color: var(--adei-rojo, #EF4444); }
.sum-kpi-malo .sum-kpi-cifra { color: var(--adei-rojo, #EF4444); }
/* El ≈ del coste estimado: se ve que NO es una factura. */
.sum-aprox { color: var(--adei-gris, #6b7280); font-weight: 400; }
/* EL EDITOR DE LA CERTIFICACIÓN (2026-08-08). Va DENTRO de `.editor-celda`, que es quien lo
   saca del flujo: aquí solo se le da forma. Compacto y en columna porque son dos caminos —
   metros y %— y hay que ver los dos sin leer. */
.cert-editor      { display: flex; flex-direction: column; gap: 4px; min-width: 210px; }
.cert-editor form { display: flex; align-items: center; gap: 4px; margin: 0; }
.cert-editor input { width: 90px; font-size: 12px; padding: 2px 4px; }
.cert-edit-lbl    { font-size: 11px; color: var(--adei-gris, #6b7280); min-width: 96px;
                    text-align: right; }
.cert-edit-pie    { font-size: 10px; color: var(--adei-gris, #6b7280); }

/* GASTOS GENERALES (2026-08-08). El aviso de «esto es estructura» va SIEMPRE y en gris, no
   en rojo: no es una alarma, es la frontera con las facturas de proveedor -- y esa frontera
   hay que verla cada vez que se apunta algo, no solo cuando algo va mal. */
.aviso-estructura { font-size: 13px; color: #475569; background: #f8fafc;
                    border-left: 3px solid #94a3b8; border-radius: 6px;
                    padding: 8px 12px; margin: 0 0 12px; }
.etiqueta-casa    { display: inline-block; font-size: 11px; font-weight: 700;
                    color: #475569; background: #e2e8f0; border-radius: 999px;
                    padding: 2px 9px; }

/* LA REGLA DE VISIBILIDAD DE LA AGENDA (2026-08-08). Candado, no alarma: no ha pasado nada
   malo, es que esas fichas no son para todo el mundo. Por eso azul y no rojo. */
.aviso-visibilidad { font-size: 13px; color: #1e3a6e; background: #eef3ff;
                     border-left: 3px solid #1E3A6E; border-radius: 6px;
                     padding: 8px 12px; margin: 0 0 12px; }

/* MI FICHA (2026-08-08, encargo §5): el trabajador propone y el administrador valida.
   Los tres estados se distinguen por COLOR y por SÍMBOLO, no solo por color: «pendiente» y
   «rechazado» son dos noticias muy distintas y el símbolo se lee aunque el color no se vea. */
.etiqueta-pendiente { display: inline-block; font-size: 11px; font-weight: 700;
                      color: #92400e; background: #fef3c7; border-radius: 999px;
                      padding: 2px 9px; }
.etiqueta-aceptado  { display: inline-block; font-size: 11px; font-weight: 700;
                      color: #065f46; background: #d1fae5; border-radius: 999px;
                      padding: 2px 9px; }
.etiqueta-rechazado { display: inline-block; font-size: 11px; font-weight: 700;
                      color: #991b1b; background: #fee2e2; border-radius: 999px;
                      padding: 2px 9px; }
.valor-anterior     { color: #94a3b8; text-decoration: line-through; }
.acciones-cambio    { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.acciones-cambio form { display: flex; align-items: center; gap: 6px; margin: 0; }
.acciones-cambio input[type=text] { font-size: 12px; padding: 3px 6px; min-width: 150px; }
.boton-suave        { background: #f1f5f9; color: #475569; }
.boton-suave:hover  { background: #e2e8f0; }

/* EL CONTROL DE COSTES DE POSTVENTA (2026-08-08). Los dos topes se pintan APAGADOS mientras
   se cumplen y ENCENDIDOS al pasarlos: si el rojo estuviera siempre, no diría nada. */
.control-postventa        { margin: 0 0 14px; }
.tope-pasado              { color: #991b1b; font-weight: 700; }
.aviso-tope               { font-size: 13px; color: #92400e; background: #fffbeb;
                            border-left: 3px solid #d97706; border-radius: 6px;
                            padding: 8px 12px; margin: 8px 0 0; }
.aviso-tope-rojo          { color: #7f1d1d; background: #fef2f2; border-left-color: #b91c1c; }
.etiqueta-sin-valorar     { display: inline-block; font-size: 11px; font-weight: 700;
                            color: #92400e; background: #fef3c7; border-radius: 999px;
                            padding: 2px 9px; margin-left: 6px; }

/* LO QUE SOBRÓ DEL AÑO ANTERIOR Y CADUCA EL 31 DE MARZO (2026-08-08). Se pinta ámbar porque
   es una cuenta atrás, y ROJO cuando ya se perdieron: son dos noticias distintas. */
.arrastre          { background: #fffbeb; border-left: 3px solid #d97706; border-radius: 6px;
                     padding: 8px 12px; margin: 10px 0 0; font-size: 13px; }
.arrastre p        { margin: 0 0 4px; }
.arrastre p:last-child { margin-bottom: 0; }
.arrastre-caducado { background: #fef2f2; border-left-color: #b91c1c; color: #7f1d1d; }

.ayuda-pendiente { background: #fff8ec; border-left: 3px solid #d97706; padding: 8px 12px;
  border-radius: 4px; }

/* A7 (2/2) · Aviso AMARILLO de gremios sin presupuesto en el Gantt (avisar, no borrar). */
.gantt-sin-presupuesto { background: #fef9e7; border: 1px solid #f0d264;
  border-left: 4px solid #d97706; border-radius: 8px; padding: 12px 14px; margin: 14px 0;
  display: flex; flex-direction: column; gap: 8px; }
.gantt-sin-presupuesto p { margin: 0; }
/* PLEGADA POR DEFECTO (⊕) — casi 40 filas taparían el Gantt. La cabecera canta cuántas son;
   la lista se abre para decidir. `<details>` nativo, como cada barra del Gantt. */
.sin-pres-plegado > summary {
  cursor: pointer; list-style: none; padding: 2px 0;
  color: var(--adei-navy, #16264D);
}
.sin-pres-plegado > summary::-webkit-details-marker { display: none; }
.sin-pres-plegado > summary::before { content: "⊕"; font-weight: 700; margin-right: 6px; }
.sin-pres-plegado[open] > summary::before { content: "⊖"; }
.sin-pres-plegado[open] > summary { margin-bottom: 8px; }
.sin-pres-plegado > p { margin: 0 0 8px; }
/* Una fila por línea, cada una con SU botón: se sacan de la obra una a una, porque unas no
   irán y a otras solo les faltará etiquetar el presupuesto. */
.lista-sin-presupuesto { list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px; }
.lista-sin-presupuesto li { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 4px 0; border-top: 1px solid #f0e2b8; }
.lista-sin-presupuesto li:first-child { border-top: 0; }
.lista-sin-presupuesto form { align-self: center; flex: 0 0 auto; }
.sin-pres-nombre { color: var(--adei-navy, #16264D); }

/* ═══ LA CAPTURA SEMANAL: dos casillas por línea y a guardar ═══
   Tiene que ser RÁPIDA de barrer con la vista: las acabadas se apagan, las que están en
   curso se marcan, y las columnas de marcar son anchas para poder pulsarlas en el móvil. */
.tabla-semana { width: 100%; border-collapse: collapse; font-size: 13px; margin: 14px 0; }
.tabla-semana th, .tabla-semana td {
  padding: 6px 8px; border-bottom: 1px solid var(--adei-borde, #D7DEEA); text-align: left;
  vertical-align: top; }
.tabla-semana thead th { background: var(--adei-claro, #F4F6FA);
  color: var(--adei-navy, #16264D); font-size: 12px; }
.tabla-semana .col-marca { width: 74px; text-align: center; }
.tabla-semana .col-marca input { width: 18px; height: 18px; cursor: pointer; }
.semana-nombre { display: block; color: var(--adei-navy, #16264D); }
.celda-plan, .celda-real { font-size: 12px; color: var(--adei-gris, #6b7280);
  font-variant-numeric: tabular-nums; }
.fila-acabada { opacity: .55; }                      /* ya está: estorba menos */
.fila-en-curso { background: #FFFDF3; }              /* empezada y sin cerrar */
.marca-hecha { color: var(--adei-verde, #10B981); font-weight: 700; }
.semana-pie { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 10px; }

@media (max-width: 720px) {
  .tabla-semana .celda-plan { display: none; }       /* en móvil manda lo real */
  .tabla-semana th, .tabla-semana td { padding: 8px 4px; }
}

/* Ratios más viejos que la plantilla. Verde: no es un problema ni una falta — es
   conocimiento nuevo esperando a que alguien decida traerlo. */
.gantt-ratios-viejos { background: #ECFDF5; border: 1px solid #A7E8CD;
  border-left: 4px solid var(--adei-verde, #10B981); border-radius: 8px;
  padding: 12px 14px; margin: 14px 0; }
.gantt-ratios-viejos > p { margin: 0 0 6px; }
.lista-ratios { list-style: none; margin: 0 0 10px; padding: 0;
  display: flex; flex-direction: column; gap: 4px; }
.lista-ratios li { display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; }
.ratio-salto { font-size: 12px; color: var(--adei-gris, #6b7280);
  font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Lo que la PODA se llevó: líneas de la plantilla que faltan y sí tienen presupuesto.
   Azul (no amarillo): no es «decide tú», es «aquí falta algo y se arregla con un botón». */
.gantt-faltan { background: #EEF4FF; border: 1px solid #B9CCF0;
  border-left: 4px solid var(--adei-azul-medio, #1E3A6E); border-radius: 8px;
  padding: 12px 14px; margin: 14px 0; }
.gantt-faltan > p { margin: 0 0 6px; }
.lista-faltan { list-style: none; margin: 0 0 10px; padding: 0;
  display: flex; flex-direction: column; gap: 4px; }

/* A7 (2/2 bis) · Los gremios DEJADOS FUERA de la obra (reversible, no se ha borrado nada).
   En gris a propósito: están apagados, no en alarma — la caja amarilla es para lo que hay
   que decidir; esto ya está decidido. */
.gantt-excluidas { background: #f4f6fa; border: 1px solid #d7dce6;
  border-left: 4px solid #9aa3b2; border-radius: 8px; padding: 12px 14px; margin: 14px 0; }
.gantt-excluidas > p { margin: 0 0 8px; }
.lista-excluidas { list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px; }
.lista-excluidas li { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 4px 0; border-top: 1px solid #e5e8ef; }
.lista-excluidas li:first-child { border-top: 0; }
.excluida-nombre { color: #6b7280; text-decoration: line-through; }
.excluida-nombre .gantt-gremio { text-decoration: none; }

/* Índice de HOJAS DE PEDIDO (una tarjeta por proveedor). */
.pedidos-lista { display: flex; flex-direction: column; gap: 12px; }
.pedido-resumen { font-size: 13px; color: var(--adei-navy, #16264D); margin: 6px 0 2px; }
.pedido-total { font-size: 13px; color: var(--adei-gris, #6b7280); margin: 0; }
.pedido-total strong { color: var(--adei-navy, #16264D); font-variant-numeric: tabular-nums; }
.pedido-ojo { color: #9a5b00; }

/* EL DOCUMENTO: la hoja de pedido tal como la verá el proveedor (y como se imprime). */
.documento { padding: 26px 30px; }
.doc-cabecera { display: flex; justify-content: space-between; align-items: flex-start;
  gap: 20px; border-bottom: 2px solid var(--adei-navy, #16264D); padding-bottom: 14px; }
.doc-emisor { display: flex; gap: 12px; align-items: center; }
.doc-marca { font-size: 26px; font-weight: 800; letter-spacing: .08em;
  color: var(--adei-navy, #16264D); }
.doc-emisor-datos { font-size: 11px; color: var(--adei-gris, #6b7280); line-height: 1.5; }
.doc-titulo { text-align: right; }
.doc-titulo h2 { margin: 0; font-size: 17px; color: var(--adei-navy, #16264D); }
.doc-fecha { font-size: 12px; color: var(--adei-gris, #6b7280); margin-top: 2px; }
.doc-partes { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 18px 0 22px; }
.doc-parte { font-size: 12px; color: var(--adei-navy, #16264D); line-height: 1.55; }
.doc-parte-tit { font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--adei-gris, #6b7280); margin-bottom: 3px; }
.doc-parte-nombre { font-weight: 700; font-size: 14px; }
.doc-estancia { font-size: 13px; color: var(--adei-azul-medio, #1E3A6E); margin: 18px 0 6px; }
.tabla-pedido td, .tabla-pedido th { font-size: 13px; }
.tabla-pedido .der { font-variant-numeric: tabular-nums; }
.doc-necesidad { font-size: 11px; color: var(--adei-gris, #6b7280); margin-top: 2px; }
/* Sin precio cerrado: la casilla se deja EN BLANCO para que la rellene el proveedor.
   Nunca se imprime aquí el coste objetivo (lo leería como un precio ya pactado). */
.doc-pendiente { color: var(--adei-gris, #9ca3af); font-style: italic; }
.doc-total { display: flex; justify-content: flex-end; align-items: baseline; gap: 16px;
  margin-top: 18px; padding-top: 12px; border-top: 2px solid var(--adei-navy, #16264D);
  font-size: 14px; color: var(--adei-navy, #16264D); }
.doc-total strong { font-size: 20px; font-variant-numeric: tabular-nums; }
.doc-nota { font-size: 12px; color: #9a5b00; background: #fff8ec; border-radius: 6px;
  padding: 8px 12px; margin-top: 12px; }

/* La medición VIVA de una partida de OC que otra orden sustituyó en parte (cambiar algo que
   ya cambiaste): es lo que queda por ejecutar, no lo que se firmó en su día. */
.tabla-certificacion .cert-vivas { font-weight: 700; }
.cert-small-baja { color: #9a5b00; }

/* La REFERENCIA VIVA: el material que ya se cambió en una orden aprobada. Lo que el cliente
   paga hoy por él no es lo del presupuesto, y la diferencia se calcula contra ESE importe. */
.ref-sello { display: inline-block; font-size: 10px; font-weight: 700; color: #3730A3;
  background: #EEF2FF; border-radius: 999px; padding: 1px 7px; margin-left: 4px; }
.ref-vacia { color: var(--adei-gris, #9ca3af); }
.fila-desviacion td { font-size: 12px; color: var(--adei-gris, #6b7280); border-top: 1px dashed #dbe3f0; }
.fila-desviacion small { display: block; font-size: 10px; }

/* ══════════ EL GUARDARRAÍL DE MARGEN en las órdenes de cambio ══════════
   Cuando falta el coste o falta la venta, el ERP calcula el que falta con el margen firmado.
   Es una ESTIMACIÓN (nunca se guarda) y se ve como tal: gris, cursiva, con su ≈. */
.oc-gr { display: none; }
.oc-gr.activo { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 4px 2px 0; padding: 5px 10px; background: #FFFBEB; border: 1px dashed #FDE68A;
  border-radius: 7px; font-size: 12px; color: #92400E; }
.oc-gr em { font-style: italic; }
.oc-gr b { font-weight: 700; }
.gr-det { color: var(--adei-gris, #6b7280); font-size: 11px; }
.gr-usar { background: #fff; border: 1px solid #FDE68A; color: #92400E; border-radius: 6px;
  padding: 2px 9px; font: inherit; font-size: 11px; font-weight: 600; cursor: pointer; }
.gr-usar:hover { background: #92400E; color: #fff; }

/* En la ficha y en la pantalla de aprobar (solo lectura). */
.oc-guardarrail { margin: 5px 0 2px; padding: 6px 10px; background: #FFFBEB;
  border-left: 3px solid #F59E0B; border-radius: 4px; font-size: 12px; color: #92400E; }
.oc-guardarrail .gr-detalle { display: block; font-size: 11px; color: var(--adei-gris, #6b7280);
  font-style: italic; }
.oc-guardarrail-mini { display: block; margin-top: 3px; font-size: 11px; color: #92400E; }
.oc-guardarrail-mini em { color: var(--adei-gris, #6b7280); font-style: italic; }
/* El MARGEN de la partida: si el coste es estimado, el margen también lo es (≈, gris). */
.oc-margen-linea { font-size: 12px; color: var(--adei-navy, #16264D); margin-top: 3px; }
.oc-margen-linea.margen-estimado { color: var(--adei-gris, #6b7280); font-style: italic; }
.oc-margen-linea .gr-detalle { font-size: 11px; color: var(--adei-gris, #9ca3af); }

/* ══════════ PRESENTACIÓN FLEXIBLE de la orden de cambio (jugada comercial) ══════════
   El mismo cambio, dos presentaciones al cliente: solo el extra, o el antes/después. La
   aprobación no cambia (sigue haciendo falta su OK escrito): cambia lo que ve en el papel. */
.oc-vista { background: #F8FAFD; border: 1px solid #dbe3f0; border-radius: 10px;
  padding: 12px 14px; margin-bottom: 16px; }
.oc-vista-tit { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--adei-azul-medio, #1E3A6E); margin-bottom: 8px; }
.oc-vista-ops { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.oc-vista-ayuda { font-size: 12px; color: var(--adei-gris, #6b7280); line-height: 1.5; margin: 0; }
.oc-vista-ayuda strong { color: var(--adei-navy, #16264D); }

/* Lo que el cliente lee en el papel: qué documento tiene delante. */
.oc-doc-intro { background: #EFF6FF; border-left: 3px solid var(--adei-azul-medio, #1E3A6E);
  border-radius: 4px; padding: 9px 12px; margin-bottom: 14px; font-size: 13px;
  color: var(--adei-navy, #16264D); }

/* 🔒 SOLO PARA TI: el coste, el margen y el guardarraíl. NUNCA se imprimen (llevan .no-print):
   este documento se le manda al cliente, y enseñarle tu margen sería regalárselo. */
.oc-interno { border: 1px dashed #d3dbe8; border-radius: 7px; padding: 6px 10px; margin-top: 6px;
  background: #FCFDFF; }
.oc-interno-tit { display: block; font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--adei-gris, #9ca3af); margin-bottom: 3px; }
.oc-solo-tu { font-size: 10px; color: var(--adei-gris, #9ca3af); font-style: italic;
  margin-left: 6px; }

/* ═══════════════════════════════════════════════════════════════════════════
   LA PLANTILLA TIPO DEL GANTT (Fase 4, Bloque A, paso A2)
   La plantilla se DIBUJA como la obra tipo, no como una lista de formularios:
   «esta espera es corta» no se decide mirando un número en una casilla, se decide
   VIENDO la obra. Cada fila es un <details>: la barra arriba, el editor dentro.
   ═══════════════════════════════════════════════════════════════════════════ */

.plantilla-resumen {
  display: flex; flex-wrap: wrap; gap: 18px; align-items: baseline;
  margin: 14px 0 18px; padding: 10px 14px;
  background: var(--adei-claro, #F4F6FA); border-radius: 8px;
}
.plantilla-resumen strong { font-size: 18px; color: var(--adei-navy, #16264D); }

.tarjeta-avisos { border-left: 4px solid var(--adei-rojo, #EF4444); }
.lista-avisos { margin: 8px 0 0; padding-left: 20px; }
.lista-avisos li { margin-bottom: 6px; line-height: 1.4; }

.gantt { border: 1px solid var(--adei-borde, #D7DEEA); border-radius: 8px; overflow: hidden; }

.gantt-fila { border-bottom: 1px solid var(--adei-borde, #D7DEEA); }
.gantt-fila:last-child { border-bottom: none; }
.gantt-fila > summary {
  display: grid; grid-template-columns: 300px 1fr 70px;
  gap: 12px; align-items: center;
  padding: 7px 12px; cursor: pointer; list-style: none;
}
.gantt-fila > summary:hover { background: var(--adei-claro, #F4F6FA); }
.gantt-fila[open] > summary { background: var(--adei-claro, #F4F6FA); font-weight: 600; }

.gantt-nombre { display: flex; flex-direction: column; font-size: 13px; }
.gantt-gremio { font-size: 11px; color: var(--adei-gris, #6b7280); font-weight: 400; }
.gantt-sin-gremio { font-style: italic; }

/* EL EJE DE TIEMPO (2026-08-08, encargo §7). ⚠️ MISMA REJILLA QUE `summary` —300px | 1fr |
   70px— y la misma pista: si el eje no compartiera la caja de las barras, señalaría a un sitio
   distinto del que marca, y un eje desplazado medio centímetro es peor que ninguno porque
   nadie lo duda. Se queda PEGADO ARRIBA al bajar: un eje que se pierde al desplazar la lista
   obliga a subir para leer la fecha, que es justo lo que se venía a evitar. */
.gantt-eje { display: grid; grid-template-columns: 300px 1fr 70px; gap: 12px;
  padding: 4px 12px 6px; position: sticky; top: 0; z-index: 3;
  background: #fff; border-bottom: 1px solid var(--adei-borde, #D7DEEA); }
.gantt-eje-pista { position: relative; height: 26px; }
.gantt-eje-marca { position: absolute; top: 0; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; line-height: 1.15;
  white-space: nowrap; }
/* La rayita que baja hasta las barras: sin ella la etiqueta flota y hay que adivinar a qué
   columna pertenece. */
.gantt-eje-marca::after { content: ""; display: block; width: 1px; height: 6px;
  background: var(--adei-borde, #D7DEEA); margin-top: 2px; }
.gantt-eje-num { font-size: 11px; font-weight: 700; color: var(--adei-navy, #16264D);
  font-variant-numeric: tabular-nums; }
.gantt-eje-dia { font-size: 10px; color: var(--adei-gris, #6b7280);
  font-variant-numeric: tabular-nums; }

/* La pista donde vive la barra. El ancho es el 100% = la obra entera. */
.gantt-pista { position: relative; height: 20px; background: #EDF1F8; border-radius: 3px; }
.gantt-barra {
  position: absolute; top: 0; height: 20px; min-width: 3px;
  background: var(--adei-azul-medio, #1E3A6E); border-radius: 3px;
  font-size: 10px; color: #fff; text-align: center; line-height: 20px;
}
.gantt-sem {
  font-size: 11px; color: var(--adei-gris, #6b7280);
  text-align: right; font-variant-numeric: tabular-nums;
}

/* Cada clase de línea se reconoce de un vistazo. */
.gantt-hito   .gantt-barra { background: #B45309; min-width: 6px; }   /* el hito del cliente */
.gantt-pedido .gantt-barra { background: #0F766E; }                   /* los tres pedidos */
.gantt-apoyo  .gantt-barra { background: #94A3B8; }                   /* mediciones, papeleo */
/* La COLA no es una barra: es una raya a rayas. No bloquea a nadie. */
.gantt-cola .gantt-barra {
  background: repeating-linear-gradient(45deg, #CBD5E1, #CBD5E1 4px, #E2E8F0 4px, #E2E8F0 8px);
  color: var(--adei-gris, #6b7280); min-width: 40px;
}

/* ═══ B1 · EL CHECKLIST DE REVISIÓN de cada línea ═══ */
.linea-checklist > summary { cursor: pointer; padding: 6px 4px; }
.linea-revisada { opacity: .72; }          /* hecha: estorba menos, pero sigue consultable */
.marca-pendiente { color: var(--adei-gris, #6b7280); font-weight: 700; }
.con-repasos { color: #B45309; font-size: 12px; font-weight: 600; }
.lista-puntos { list-style: none; margin: 8px 0; padding: 0;
  display: flex; flex-direction: column; gap: 5px; }
.lista-puntos label { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.lista-puntos input[type=checkbox] { width: 17px; height: 17px; }
.form-revision { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.campo-foto { font-size: 13px; }
/* Un punto que ha puesto el jefe de obra: se distingue del know-how heredado. */
.badge-sugerencia { font-size: 10px; text-transform: uppercase; letter-spacing: .3px;
  padding: 1px 6px; border-radius: 9px; margin-left: 6px; font-weight: 700; }
.badge-pendiente { background: #FEF3C7; color: #92400E; }
.badge-aceptada  { background: #D1FAE5; color: #065F46; }
.badge-rechazada { background: #F3F4F6; color: #6B7280; }
.repasos-linea { border-top: 1px dashed var(--adei-borde, #D7DEEA); margin-top: 10px;
  padding-top: 8px; }
.repasos-linea h4 { margin: 0 0 6px; font-size: 13px; }
.repaso { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; padding: 4px 0; font-size: 13px; }
.punto { border-bottom: 1px solid var(--adei-borde, #D7DEEA); padding: 6px 0; }
.punto:last-child { border-bottom: 0; }
.punto-marca { font-size: 13px; }
/* Los ajustes de cada punto se PLIEGAN (2026-08-08): en una línea de 30 puntos había cuatro
   controles por fila y el que se usa en obra es la casilla. Plegar no cambia lo que se
   envía — un `<details>` cerrado sigue mandando sus campos—, y eso tiene prueba: las listas
   `est_punto`/`est_valor` casan por POSICIÓN. */
.punto-detalle { margin: 2px 0 0 25px; font-size: 12px; color: var(--adei-gris, #6b7280); }
.punto-detalle[open] > .punto-ajustes { margin-bottom: 4px; }
.punto-detalle > *:not(summary) { display: inline-flex; align-items: center; gap: 6px;
  margin-right: 10px; }
.punto-ajustes { cursor: pointer; font-size: 11px; color: #94a3b8;
  list-style: none; user-select: none; }
.punto-ajustes::before { content: "⚙ "; }
.punto-ajustes:hover { color: var(--adei-azul-medio, #1E3A6E); }

/* El contador por línea: cuánto llevas sin abrirla. Con 215 puntos reales dentro, saber
   «¿me queda algo de fontanería?» obligaba a desplegar y leerla entera. */
.contador-puntos { display: inline-block; font-size: 11px; font-weight: 700;
  color: #92400e; background: #fef3c7; border-radius: 999px; padding: 1px 8px;
  margin-left: 6px; font-variant-numeric: tabular-nums; }
.contador-completo { color: #065f46; background: #d1fae5; }
/* Un punto marcado que pide foto y no la tiene: es lo único que frena la revisión. */
.punto-sin-foto { background: #FEF9E7; }
.aviso-punto { display: block; margin-left: 25px; color: #B45309; font-weight: 600; }
.galeria-gremio { border: 1px dashed var(--adei-borde, #D7DEEA); border-radius: 8px;
  padding: 10px 12px; margin: 10px 0; width: 100%; }
.galeria-gremio h4 { margin: 0 0 6px; font-size: 14px; }
.galeria-vacia { border-color: #d97706; background: #fffdf5; }

/* ═══ PUNTO 4 · el panel de RATIOS APRENDIDOS ═══ */
.tabla-ratios { width: 100%; border-collapse: collapse; font-size: 13px; margin: 12px 0; }
.tabla-ratios th, .tabla-ratios td {
  padding: 6px 8px; border-bottom: 1px solid var(--adei-borde, #D7DEEA); text-align: left; }
.tabla-ratios thead th { background: var(--adei-claro, #F4F6FA);
  color: var(--adei-navy, #16264D); font-size: 12px; }
.tabla-ratios td:not(:first-child):not(:nth-child(2)) {
  text-align: right; font-variant-numeric: tabular-nums; }
/* Una sola obra detrás no es un histórico, y la fila lo dice. */
.pocas-obras { color: #B45309; }

/* ═══ A5 · ARRASTRAR LAS BARRAS ═══
   Solo las que TIENEN una flecha que mover se ofrecen: si una barra no se puede arrastrar,
   mejor que ni invite a intentarlo. */
.barra-movible { cursor: grab; }
.barra-movible:hover { outline: 2px solid rgba(255, 255, 255, .7); outline-offset: -2px; }
.barra-arrastrando { cursor: grabbing; opacity: .45; }

/* El FANTASMA: dónde caería la barra al soltar, con las semanas movidas encima. */
.gantt-fantasma {
  position: absolute; top: 0; height: 20px; min-width: 3px;
  border: 2px dashed var(--adei-navy, #16264D); border-radius: 3px;
  background: rgba(30, 58, 110, .12); pointer-events: none;
}
.gantt-fantasma::after {
  content: attr(data-semanas);
  position: absolute; top: -19px; left: 0; white-space: nowrap;
  font-size: 11px; font-weight: 700; color: #fff;
  background: var(--adei-navy, #16264D); border-radius: 3px; padding: 1px 5px;
}

/* ═══ BLOQUE B · LA CAPA REAL: la sombra sobre el plan ═══
   La barra IDEAL se apaga cuando hay realidad encima (deja de ser la protagonista y pasa a
   ser la referencia), y la REAL se pinta como una franja sólida en la mitad de abajo: se
   ve de un golpe si sobresale por la derecha (tarde) o por la izquierda (adelantada). */
.gantt-barra-fantasma { opacity: .32; }
.gantt-barra-real {
  position: absolute; top: 11px; height: 9px; min-width: 3px;
  background: var(--adei-navy, #16264D); border-radius: 3px;
  border: 1px solid rgba(255, 255, 255, .55);
}
.gantt-barra-real.real-tarde  { background: var(--adei-rojo, #EF4444); }
.gantt-barra-real.real-pronto { background: var(--adei-verde, #10B981); }
/* En curso (empezó pero no ha acabado): a rayas, porque su final aún no es un dato. */
.gantt-barra-real.real-en-curso {
  background-image: repeating-linear-gradient(45deg,
    rgba(255,255,255,.45), rgba(255,255,255,.45) 3px, transparent 3px, transparent 6px);
}

/* ═══ LA TERCERA LÍNEA · **PLAN**: el ritmo de la casa (2026-08-09) ═══
   Solo aparece en las líneas donde esta obra ha puesto SU ritmo y sale distinto. Va DETRÁS
   de las otras dos y en trazo discontinuo, sin relleno: es la vara de medir, no un hecho —
   nadie tiene que confundirla con lo que va a pasar. Encima de ella se leen la barra de la
   obra (sólida) y la real (franja de abajo), que son las que mandan. */
.gantt-barra-plan {
  position: absolute; top: -4px; height: 7px; min-width: 3px;
  border: 1px dashed var(--adei-azul-medio, #1E3A6E); border-radius: 3px;
  background: transparent; pointer-events: none;
}

/* La previsión, en la cabecera, junto a lo firmado. */
.previsto { font-size: 12px; }
.previsto-tarde  { color: var(--adei-rojo, #EF4444); font-weight: 600; }
.previsto-pronto { color: var(--adei-verde, #10B981); font-weight: 600; }

/* El bloque de «lo que pasó de verdad» dentro del editor de la línea. */
.bloque-real { border-left: 3px solid var(--adei-navy, #16264D); padding-left: 10px; }

/* PREVISTO vs REAL por gremio — el cimiento de los ratios aprendidos (Punto 4). */
.gantt-desviacion { margin: 14px 0; background: var(--adei-claro, #F4F6FA);
  border: 1px solid var(--adei-borde, #D7DEEA); border-radius: 8px; padding: 10px 14px; }
.gantt-desviacion > summary { cursor: pointer; font-weight: 600;
  color: var(--adei-navy, #16264D); }
.gantt-desviacion[open] > summary { margin-bottom: 10px; }
.tabla-desviacion { width: 100%; border-collapse: collapse; font-size: 13px; }
.tabla-desviacion th, .tabla-desviacion td {
  text-align: left; padding: 5px 8px; border-bottom: 1px solid var(--adei-borde, #D7DEEA); }
.tabla-desviacion td:not(:first-child) { text-align: right;
  font-variant-numeric: tabular-nums; }
.desvio-tarde  { color: var(--adei-rojo, #EF4444); font-weight: 600; }
.desvio-pronto { color: var(--adei-verde, #10B981); font-weight: 600; }

/* ── El editor de una línea ── */
.gantt-editor {
  padding: 14px 16px 18px 16px; background: #fff;
  border-top: 1px dashed var(--adei-borde, #D7DEEA);
  display: flex; flex-direction: column; gap: 16px;
}
.editor-bloque {
  display: flex; flex-direction: column; gap: 10px;
  padding: 12px; border: 1px solid var(--adei-borde, #D7DEEA); border-radius: 6px;
}
.editor-bloque h4 { margin: 0; font-size: 13px; }
.editor-bloque h4 .ayuda { font-weight: 400; }
.editor-campos { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; }
.editor-campos label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; }
.editor-campos input[type="text"], .editor-campos select { padding: 5px 8px; }
.editor-check { flex-direction: row !important; align-items: flex-start; gap: 7px !important;
                max-width: 460px; line-height: 1.35; }

.lista-flechas { list-style: none; margin: 0; padding: 0; display: flex;
                 flex-direction: column; gap: 6px; }
.lista-flechas li { display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
                    padding: 5px 8px; background: var(--adei-claro, #F4F6FA);
                    border-radius: 4px; font-size: 12px; }
.lista-flechas form { display: flex; gap: 5px; align-items: center; margin: 0; }
.lista-flechas label { display: flex; gap: 4px; align-items: center; }
.flecha-de { flex: 1; min-width: 170px; font-weight: 600; }
.flecha-nueva { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; font-size: 12px; }

.celda-fecha { white-space: nowrap; font-variant-numeric: tabular-nums;
               color: var(--adei-gris, #6b7280); font-size: 12px; }

@media (max-width: 860px) {
  .gantt-fila > summary { grid-template-columns: 1fr; }
  .gantt-pista { display: none; }   /* en el móvil la barra no cabe: manda la lista */
}

/* ── ⭐ EL HITO PREVIO (paso A2b) ──
   Va SOBRE LA PROPIA FILA, a la altura de su semana, con una rayita hasta la barra.
   Esa es la decisión que mata el ruido: 44 líneas siguen siendo 44 filas. Si el hito
   fuera una línea aparte, el Gantt tendría 88 y sería ilegible. */
.hito-marca {
  position: absolute; top: 1px; transform: translateX(-50%);
  font-size: 12px; line-height: 18px; z-index: 2; cursor: help;
  color: var(--adei-gris, #6b7280);
}
.hito-marca.hito-visible { color: #B45309; font-size: 13px; }   /* lo ve el cliente */
.hito-marca.hito-tarde   { color: var(--adei-rojo, #EF4444); }  /* cae antes de empezar */

/* La rayita: del hito hasta el principio de la barra. Es el TIEMPO PREVIO, y verlo es
   justo lo que Diego quiere calibrar. */
.hito-rayita {
  position: absolute; top: 9px; height: 2px; z-index: 1;
  border-top: 2px dotted #B9C4D8;
}

/* La agenda de avisos y la lista del cliente. */
.celda-sem {
  white-space: nowrap; font-variant-numeric: tabular-nums; font-weight: 700;
  color: var(--adei-navy, #16264D); width: 70px;
}
.fila-alerta { background: #FEF2F2; }
.fila-alerta .celda-sem { color: var(--adei-rojo, #EF4444); }

/* Confirmar precios de subcontrata: sobrecoste JUSTIFICADO (ámbar) vs sin justificar
   (rojo, que es `fila-alerta`). Se distinguen porque son dos cosas distintas: pagar de
   más con un motivo escrito es una decisión; sin motivo, es lo que frena la emisión. */
.fila-aviso { background: #FFFBEB; }

/* ── El histórico de precios en el presupuesto (bloque 4) ──
   El rojo avisa en las DOS direcciones, y no es un descuido: presupuestar muy POR DEBAJO
   de lo que siempre se ha pagado es el caso peor y el que nadie mira (esa partida no se
   va a poder contratar a ese precio, así que el margen ya está perdido). */
.hist-alerta { background: #FEF2F2; }
.hist-rango { display: block; color: #64748B; font-size: 11px; white-space: nowrap; }
.hist-desv  { display: block; font-weight: 700; font-size: 11px; }
.hist-alerta .hist-desv { color: var(--adei-rojo, #EF4444); }
/* El «≈» marca un emparejamiento por parecido FLOJO (< 80 %). Que se vea distinto es
   justo el punto: una sugerencia dudosa que parece firme es peor que ninguna. */
.hist-flojo { color: #B45309; font-weight: 700; }
.hist-segura { color: #065F46; font-weight: 700; }

/* ── NUESTRO número contra el histórico: /preciario y las líneas de licitación (2026-07-30) ──
   TRES tramos, no dos, y es una decisión de Diego con su motivo: al decidir UNA partida un
   aviso basta; al repasar una lista larga (714 filas de tarifa, o las líneas de una
   licitación) sin tramos no se sabe por dónde empezar. Los umbrales viven en
   `historico_precios.py` (TRAMO_AMARILLO / TRAMO_ROJO) y CONVIVEN con DESVIACION_QUE_AVISA,
   que sigue gobernando el aviso binario al RECIBIR una oferta y no se toca.
   ⚠️ El color va por MAGNITUD, en las dos direcciones: la tarifa por DEBAJO de lo que se
   paga es el caso peor y el que nadie mira. */
.hist-medio { font-weight: 700; font-size: 11px; color: #1E3A6E; white-space: nowrap; }
.hist-revisa { color: #B45309; font-size: 11px; }
.desv-verde    { color: #065F46; font-weight: 700; white-space: nowrap; }
.desv-amarillo { color: #B45309; font-weight: 700; white-space: nowrap; }
.desv-rojo     { color: var(--adei-rojo, #EF4444); font-weight: 700; white-space: nowrap; }

/* ── Lo que ESA empresa cobró antes, bajo la casilla de confirmar precio (2026-08-29) ──
   ⚠️ VA DEBAJO DEL INPUT, no en una columna aparte: el dato sirve en el instante de
   teclear, y al otro extremo de la fila obliga a mirar a otro sitio justo al decidir.
   ⚠️ `align-items: flex-end` porque la celda es `.col-num` (texto a la derecha): sin esto
   el bloque se alinearía a la izquierda y dejaría de leerse como parte de la casilla.
   ⚠️ El color lo pone `nivel_al_confirmar()`, que es ASIMÉTRICA a propósito y NO es la
   misma pregunta que `nivel_desviacion` de aquí arriba: aquí el precio lo pide OTRO y ya
   está cerrado con él, así que cerrar POR DEBAJO de lo que se venía pagando es la buena
   noticia por la que se negocia, no una alarma. */
.hist-empresa {
  display: flex; flex-direction: column; align-items: flex-end;
  gap: 1px; margin-top: 4px; line-height: 1.3;
}
.hist-empresa .hist-rango { white-space: normal; text-align: right; }
.hist-empresa .hist-flojo { font-size: 11px; white-space: normal; text-align: right; }

/* ── La barra de administrador del catálogo y sus filtros (2026-07-30) ── */
.prec-barra-admin { display: flex; flex-wrap: wrap; gap: 1rem; align-items: flex-start;
  margin: 0.6rem 0; }
/* El contador de pendientes SOLO se pinta si hay algo (ver la plantilla): un «0
   pendientes» permanente enseña a no mirar la campana. */
.prec-pendientes { background: #FFFBEB; border: 1px solid #FDE68A; border-radius: 6px;
  padding: 0.6rem 0.9rem; }
.prec-cambios { background: var(--adei-fondo-claro, #F4F6FA);
  border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 6px; padding: 0.6rem 0.9rem;
  font-size: 13px; }
.prec-cambios-lista { margin: 0.3rem 0 0; padding-left: 1.1rem; }
.prec-cambios-lista li { margin-bottom: 2px; }
/* Los chips del filtro. Mismo aspecto que los de gremio de Planos, con nombre propio para
   no meter un `.chip` genérico en la hoja global. */
.prec-filtros { display: flex; flex-wrap: wrap; gap: 6px; margin: 0.5rem 0 0.2rem; }
.prec-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px;
  background: #EEF1F6; border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 999px;
  font-size: 13px; font-weight: 600; color: var(--adei-navy, #16264D); cursor: pointer; }
.prec-chip:hover { border-color: #1E3A6E; }
.prec-chip-activo { background: var(--adei-navy, #16264D); color: #fff;
  border-color: var(--adei-navy, #16264D); }

/* ── El panel del histórico al añadir una partida a una licitación (2026-07-30) ──
   Se pinta SOLO si hay coincidencia: un bloque permanente con «—» en cuatro líneas es ruido
   y hace creer que está roto. El borde ámbar marca un parecido FLOJO, porque una sugerencia
   dudosa que parece firme es peor que ninguna. */
.hist-panel { background: var(--adei-fondo-claro, #F4F6FA);
  border: 1px solid var(--adei-borde, #dbe1ec); border-left: 4px solid #1E3A6E;
  border-radius: 6px; padding: 0.7rem 1rem; margin: 0.8rem 0; }
.hist-panel-flojo { border-left-color: #B45309; background: #FFFBEB; }
.hist-detalle { margin: 0.4rem 0; padding-left: 1.2rem; font-size: 14px; }
.hist-detalle li { margin-bottom: 2px; }
.origen-etiqueta {
  background: #E0E7FF; color: #3730A3; padding: 1px 6px; border-radius: 3px;
  font-size: 11px; white-space: nowrap;
}

.hist-sugerencia {
  background: #EFF6FF; border-left: 4px solid var(--adei-azul-medio, #1E3A6E);
  padding: 10px 14px; margin: 10px 0; border-radius: 4px;
}
.hist-sugerencia p { margin: 4px 0; }
.hist-mini { width: auto; margin: 6px 0; font-size: 13px; }
.hist-mini th, .hist-mini td { padding: 2px 12px 2px 0; text-align: left; }
.fila-precio { display: flex; gap: 4px; align-items: center; justify-content: flex-end; }
.fila-precio input { text-align: right; }
.tarjeta-cliente { border-left: 4px solid #B45309; }

.etiqueta-contratacion { background: #E0E7FF; color: #3730A3; }
.etiqueta-planos       { background: #DBEAFE; color: #1E40AF; }
.etiqueta-material     { background: #D1FAE5; color: #065F46; }
.etiqueta-otro         { background: #F1F5F9; color: #475569; }

.editor-hito { border-left: 3px solid #B45309; }

/* ── LOS DOS HITOS PREVIOS (paso A2c) ──
   Van los DOS sobre la misma barra, cada uno a la altura de su semana:
   ⭐ ámbar = lo que el cliente tiene que tener decidido · ◆ gris = lo que hace ADEI.
   Son dos porque son DOS COSAS EN DOS MOMENTOS: si se juntan en uno, o avisas tarde al
   cliente o contratas demasiado pronto. */
.hito-marca.hito-visible { color: #B45309; font-size: 13px; z-index: 3; }
.hito-rayita.rayita-cliente { border-top-color: #E7C08A; }

.hito-fila {
  align-items: center; gap: 10px; padding: 8px 10px; border-radius: 6px;
}
.hito-fila-cliente { background: #FFF7ED; border-left: 3px solid #B45309; }
.hito-fila-interno { background: var(--adei-claro, #F4F6FA); border-left: 3px solid #94A3B8; }
.hito-icono { font-size: 15px; }
.editor-hito { border-left: 3px solid #B45309; gap: 8px; }

/* ── EL CHECKLIST DEL PLANO (paso A2d) ──
   NO se guarda en el hito: se LEE del módulo de Planos. Dos listas paralelas que dicen
   lo mismo acaban descuadradas (la lección de los oficios contra los gremios). */
.checklist-plano {
  margin: 2px 0 2px 26px; padding: 8px 12px; font-size: 12px;
  background: #FFFDF7; border-left: 2px dotted #E7C08A; border-radius: 0 4px 4px 0;
}
.checklist-plano ul { margin: 5px 0 0; padding-left: 18px; color: var(--adei-gris, #6b7280); }
.checklist-plano li { margin-bottom: 2px; }
.sin-checklist { margin: 0; line-height: 1.4; }

/* ── LA DOSIFICACIÓN ──
   No se le mandan al cliente las 38 decisiones de golpe: se agobia y no hace ninguna.
   Se le manda lo del próximo tramo. Y esto SOLO se puede hacer porque cada planimetría
   es la de SU gremio, con SU fecha. Agrupadas, no habría tramos. */
.filtro-periodo {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  padding: 10px 12px; margin-bottom: 12px;
  background: #FFF7ED; border-radius: 6px; font-size: 13px;
}
.filtro-periodo label { display: flex; gap: 5px; align-items: center; }
.filtro-periodo .ayuda { flex-basis: 100%; font-style: italic; margin: 0; }

/* ── LOS PLANOS QUE NECESITA UNA LÍNEA DEL GANTT (reconciliación, pasos 3-5) ──
   Muchos a muchos: el alicatador necesita el de BAÑOS y el de COCINA. El checklist de
   cada plano NO se guarda aquí: es EL MISMO del módulo de Planos. Una sola lista, dos
   sitios donde se ve. */
.planos-linea {
  display: flex; flex-direction: column; gap: 10px;
  padding: 12px; border: 1px solid var(--adei-borde, #D7DEEA);
  border-left: 3px solid #0F766E; border-radius: 6px;
}
.planos-linea h5 { margin: 0; font-size: 13px; }
.planos-linea h5 .ayuda { font-weight: 400; }

.plano-caja {
  padding: 8px 10px; background: #F0FDFA; border-radius: 5px; font-size: 12px;
}
.plano-cabecera { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.plano-cabecera form { margin: 0; }

.requisitos { list-style: none; margin: 7px 0 0; padding: 0;
              display: flex; flex-direction: column; gap: 4px; }
.requisitos li { display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
                 padding: 4px 6px; background: #fff; border-radius: 4px;
                 border-left: 3px solid #0F766E; }
.requisitos li.req-documentacion { border-left-color: #B45309; background: #FFFBF5; }
.requisitos form { display: flex; gap: 4px; align-items: center; margin: 0; }
.requisitos input[type="text"] { min-width: 220px; padding: 3px 6px; font-size: 12px; }
.requisitos select { font-size: 11px; padding: 2px 4px; }

/* ── LA FECHA DE PLANOS LA MANDA EL GANTT (paso A3) ──
   Nunca se ven dos fechas: si el plano está en una línea del Gantt, la fecha sale de
   ahí; si no, vale la manual. Y se dice de dónde viene. */
.fecha-manda-el-gantt {
  padding: 6px 10px; margin: 6px 0 10px; border-radius: 5px;
  background: #EFF6FF; border-left: 3px solid var(--adei-azul-medio, #1E3A6E);
}
.fecha-del-gantt {
  display: inline-flex; align-items: center; padding: 3px 8px;
  background: #EFF6FF; border-radius: 4px; font-size: 12px; font-weight: 600;
  color: var(--adei-navy, #16264D); white-space: nowrap; cursor: help;
}
/* El estado de los planos en la barra del Gantt de la obra. */
.plano-ok    { color: #047857; font-weight: 600; }
.plano-falta { color: var(--adei-rojo, #EF4444); font-weight: 600; }

/* ── EL IMPORTADOR DE EXCEL ──
   La previsualización es innegociable: el árbol y EL CONTROL antes de escribir nada. */
.control-ok { border-left: 4px solid var(--adei-verde, #10B981); }
.control-cifra { font-size: 16px; margin: 6px 0; }
.control-cifra strong { font-size: 20px; color: var(--adei-navy, #16264D); }

.arbol-importado {
  max-height: 480px; overflow-y: auto; margin-top: 10px;
  border: 1px solid var(--adei-borde, #D7DEEA); border-radius: 6px;
  font-size: 12px;
}
.nodo-cap, .nodo-part {
  display: flex; gap: 10px; align-items: baseline;
  padding: 4px 10px; border-bottom: 1px solid #EDF1F8;
}
.nodo-cap { background: var(--adei-claro, #F4F6FA); font-weight: 700;
            color: var(--adei-navy, #16264D); }
.nodo-cap.nodo-opcional { background: #FFF7ED; color: #B45309; }
.nivel-1 { padding-left: 26px; }
.nivel-2 { padding-left: 46px; }
.nivel-3 { padding-left: 66px; }
.nodo-codigo { min-width: 58px; font-variant-numeric: tabular-nums; font-weight: 700; }
.nodo-origen { min-width: 110px; font-family: ui-monospace, monospace; font-size: 10px;
               color: var(--adei-gris, #6b7280); cursor: help; }
.nodo-titulo { flex: 1; }
.nodo-med, .nodo-coste, .nodo-margen { color: var(--adei-gris, #6b7280);
                                       white-space: nowrap; font-variant-numeric: tabular-nums; }
.nodo-margen { color: #047857; }
.nodo-importe { min-width: 96px; text-align: right; font-weight: 600;
                font-variant-numeric: tabular-nums; }

/* ── El presupuesto vacío: los dos caminos (Excel primero) ───────────────── */
.vacio .dos-caminos {
  margin: 1.2rem 0 0.4rem;
}
.boton-grande {
  display: inline-block;
  font-size: 1.05rem;
  padding: 0.75rem 1.4rem;
}
.vacio .o-bien {
  margin: 1.1rem 0 0.6rem;
  text-align: center;
  opacity: 0.7;
}

/* ══════════════════════════════════════════════════════════════════════════
   EL ÁRBOL PLEGABLE DEL PRESUPUESTO (pasada de escala: 293 partidas)
   ══════════════════════════════════════════════════════════════════════════ */
.fila-oculta { display: none; }

.plegar {
  background: none;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--navy, #16264D);
  cursor: pointer;
  font-size: 0.8rem;
  line-height: 1;
  margin-right: 4px;
  padding: 3px 5px;
  width: 22px;
}
.plegar:hover { background: rgba(30, 58, 110, 0.10); }
.plegar:focus-visible { outline: 2px solid #1E3A6E; outline-offset: 1px; }
.plegar-hueco { display: inline-block; margin-right: 4px; width: 22px; }

/* ══════════════════════════════════════════════════════════════════════════
   CERTIFICACIÓN · VISTA MÓVIL (tarjeta por partida) — paso 1/5 de móviles
   La tabla de 17 columnas no cabe en un móvil ni plegando. Un SOLO breakpoint
   intercambia la tabla (escritorio) por tarjetas (móvil). Solo lectura.
   ══════════════════════════════════════════════════════════════════════════ */
.cert-movil { display: none; }               /* en escritorio manda la tabla */
@media (max-width: 720px) {
  .cert-desktop { display: none; }
  .cert-movil { display: block; }
}
.cert-movil-lista { margin-top: 0.4rem; }
.barra-arbol-movil { padding: 0.6rem 0.7rem; }
/* La cabecera plegable de un capítulo/subcapítulo. */
.cert-m-cajon { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  background: #F4F6FA; border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 8px;
  padding: 8px 10px; margin: 10px 0 4px; font-size: 0.95rem; color: var(--adei-navy, #16264D); }
.cert-m-cajon.cert-m-nivel-1 { margin-left: 12px; }
.cert-m-cajon.cert-m-nivel-2 { margin-left: 24px; }
.cert-m-cajon-txt { flex: 1 1 auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cert-m-cajon-total { font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cert-m-cod { color: #64748B; font-size: 0.85rem; font-variant-numeric: tabular-nums; }
/* La tarjeta de una partida. */
.cert-m-card { border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 10px;
  padding: 10px 12px; margin: 6px 0; background: #fff; }
.cert-m-card.cert-m-nivel-2 { margin-left: 12px; }
.cert-m-card-cab { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.cert-m-desc { font-weight: 600; color: var(--adei-navy, #16264D); }
.cert-m-datos { display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; margin: 0; }
.cert-m-datos dt { color: #64748B; font-size: 0.88rem; }
.cert-m-datos dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.cert-m-total { font-weight: 700; }
.cert-m-estado { font-size: 0.85rem; font-weight: 600; }
.est-ok { color: var(--adei-verde, #10B981); }
.est-pend { color: #64748B; }
.est-bloq { color: #B45309; }
.est-opc { color: #94a3b8; }
.cert-m-oc { border-left: 3px solid var(--adei-azul-medio, #1E3A6E); }
.cert-m-opcional { opacity: 0.72; }
.cert-m-opcional .cert-m-desc { text-decoration: line-through; }

/* ══════════════════════════════════════════════════════════════════════════
   PRESUPUESTO · VISTA MÓVIL (tarjeta por partida) — paso 2/5 de móviles
   La tabla ancha del presupuesto no cabe en un móvil. Mismo patrón que la de
   certificación: un breakpoint intercambia tabla (escritorio) por tarjetas (móvil).
   ══════════════════════════════════════════════════════════════════════════ */
.presup-movil { display: none; }             /* en escritorio manda la tabla */
@media (max-width: 720px) {
  .presup-desktop { display: none; }
  .presup-movil { display: block; }
}
.presup-movil-lista { margin-top: 0.4rem; }
.presup-m-cajon { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  background: #F4F6FA; border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 8px;
  padding: 8px 10px; margin: 10px 0 4px; font-size: 0.95rem; color: var(--adei-navy, #16264D); }
.presup-m-cajon.presup-m-nivel-1 { margin-left: 12px; }
.presup-m-cajon.presup-m-nivel-2 { margin-left: 24px; }
.presup-m-cajon-txt { flex: 1 1 auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.presup-m-cajon-total { font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
.presup-m-cod { color: #64748B; font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.presup-m-card { border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 10px;
  padding: 10px 12px; margin: 6px 0; background: #fff; }
.presup-m-card.presup-m-nivel-2 { margin-left: 12px; }
.presup-m-card.presup-m-nivel-3 { margin-left: 24px; }
.presup-m-card-cab { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.presup-m-desc { font-weight: 600; color: var(--adei-navy, #16264D); }
.presup-m-datos { display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; margin: 0; }
.presup-m-datos dt { color: #64748B; font-size: 0.88rem; }
.presup-m-datos dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.presup-m-total { font-weight: 700; }
.presup-m-opcional { opacity: 0.72; }
.presup-m-opcional .presup-m-desc { text-decoration: line-through; }

/* ══════════════════════════════════════════════════════════════════════════
   SUMINISTROS · VISTA MÓVIL (tarjeta multi-opción) — paso 3/5 de móviles
   La hoja de escritorio (tarjetas con varias opciones y muchos formularios) no cabe
   en un móvil. Un breakpoint intercambia el escritorio por tarjetas plegables por
   estancia, solo lectura. Mismo patrón que certificación/presupuesto.
   ══════════════════════════════════════════════════════════════════════════ */
.sum-movil { display: none; }                /* en escritorio manda la hoja completa */
@media (max-width: 720px) {
  .sum-desktop { display: none; }
  .sum-movil { display: block; }
}
.sum-movil-lista { margin-top: 0.4rem; }
/* La cabecera plegable de una estancia. */
.sum-m-grupo { margin: 10px 0; }
.sum-m-grupo-cab { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  background: #F4F6FA; border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 8px;
  padding: 8px 10px; font-size: 0.95rem; color: var(--adei-navy, #16264D); }
.sum-m-plegado .sum-m-card { display: none; }        /* estancia plegada: sus tarjetas, no */
.sum-m-grupo.oculto-busqueda { display: none; }
/* La tarjeta de una necesidad. */
.sum-m-card { border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 10px;
  padding: 10px 12px; margin: 6px 0 6px 12px; background: #fff; }
.sum-m-card.oculto-busqueda { display: none; }
.sum-m-card-cab { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.sum-m-nec { font-weight: 600; color: var(--adei-navy, #16264D); }
.sum-m-estado { font-size: 0.82rem; font-weight: 600; margin-left: auto; }
.est-anul { color: var(--adei-gris, #6b7280); }
.sum-m-anulada { opacity: 0.72; }
.sum-m-confirmada { border-left: 3px solid var(--adei-verde, #10B981); }
/* Las opciones (dos precios: PVP vs coste real / objetivo). */
.sum-m-opciones { display: flex; flex-direction: column; gap: 6px; }
.sum-m-op { border-top: 1px solid #eef1f6; padding-top: 6px; }
.sum-m-op:first-child { border-top: 0; padding-top: 0; }
.sum-m-op-elegida { background: #ECFDF5; border-radius: 6px; padding: 6px; }
.sum-m-op-nombre { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  font-weight: 600; color: var(--adei-navy, #16264D); margin-bottom: 3px; }
.sum-m-op-check { font-weight: 400; }
.sum-m-prov { color: #64748B; font-size: 0.85rem; font-weight: 400; }
.sum-m-datos { display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; margin: 0; }
.sum-m-datos dt { color: #64748B; font-size: 0.88rem; }
.sum-m-datos dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.sum-m-total { font-weight: 700; }
.sum-m-aprox { color: #94a3b8; }
.sum-m-vacia { color: #94a3b8; font-size: 0.88rem; margin: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   ÓRDENES DE CAMBIO · VISTA MÓVIL (tarjeta por orden) — paso 4/5 de móviles
   La tabla ancha por sección no cabe en un móvil. Un breakpoint intercambia el
   escritorio por tarjetas plegables por sección (Pendientes/Aprobadas/Rechazadas),
   solo lectura. Mismo patrón que suministros.
   ══════════════════════════════════════════════════════════════════════════ */
.oc-movil { display: none; }                 /* en escritorio manda la tabla por sección */
@media (max-width: 720px) {
  .oc-desktop { display: none; }
  .oc-movil { display: block; }
}
.oc-movil-lista { margin-top: 0.4rem; }
/* La cabecera plegable de una sección. */
.oc-m-sec { margin: 10px 0; }
.oc-m-sec-cab { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  background: #F4F6FA; border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 8px;
  padding: 8px 10px; font-size: 0.95rem; color: var(--adei-navy, #16264D); }
.oc-m-plegado .oc-m-card { display: none; }          /* sección plegada: sus tarjetas, no */
.oc-m-sec.oculto-busqueda { display: none; }
/* La tarjeta de una orden. */
.oc-m-card { border: 1px solid var(--adei-borde, #dbe1ec); border-radius: 10px;
  padding: 10px 12px; margin: 6px 0 6px 12px; background: #fff; }
.oc-m-card.oculto-busqueda { display: none; }
.oc-m-card-cab { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 3px; }
.oc-m-cod { color: #64748B; font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.oc-m-tit { font-weight: 600; color: var(--adei-navy, #16264D); }
.oc-m-partidas { color: #64748B; font-size: 0.85rem; margin-bottom: 6px; }
.oc-m-datos { display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; margin: 0; }
.oc-m-datos dt { color: #64748B; font-size: 0.88rem; }
.oc-m-datos dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.oc-m-neto { font-weight: 700; }
.oc-m-neto.neg { color: var(--adei-rojo, #EF4444); }
.oc-m-estado { font-weight: 600; }

/* ══════════════════════════════════════════════════════════════════════════
   PLANOS · VISTA MÓVIL (tarjeta por tipo) — paso 5/5 de móviles
   La pantalla de escritorio (tarjetas por tipo con formularios) no cabe en un móvil.
   Un breakpoint intercambia el escritorio por tarjetas plegables de solo lectura, con
   CHIPS de gremio que FILTRAN (no anidan: un tipo lo usan varios gremios).
   ══════════════════════════════════════════════════════════════════════════ */
.planos-movil { display: none; }             /* en escritorio manda la pantalla completa */
@media (max-width: 720px) {
  .planos-desktop { display: none; }
  .planos-movil { display: block; }
}
.planos-movil-lista { margin-top: 0.4rem; }
/* Los chips de gremio (filtran; el activo, resaltado). */
.planos-m-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 0.5rem; }
.planos-m-chip { background: #F4F6FA; border: 1px solid var(--adei-borde, #dbe1ec);
  border-radius: 999px; padding: 4px 10px; font-size: 0.85rem; cursor: pointer;
  color: var(--adei-navy, #16264D); }
.planos-m-chip-activo { background: var(--adei-azul-medio, #1E3A6E); color: #fff;
  border-color: var(--adei-azul-medio, #1E3A6E); }
/* La cabecera plegable de un tipo. */
.planos-m-tipo { margin: 10px 0; border: 1px solid var(--adei-borde, #dbe1ec);
  border-radius: 10px; background: #fff; }
.planos-m-tipo.oculto-filtro { display: none; }        /* el filtro de gremio/búsqueda */
.planos-m-tipo-cab { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 8px 10px; font-size: 0.95rem; color: var(--adei-navy, #16264D); }
.planos-m-plegado .planos-m-cuerpo { display: none; }  /* tipo plegado: su cuerpo, no */
.planos-m-cuerpo { padding: 0 12px 10px; }
.planos-m-plano { border-top: 1px solid #eef1f6; padding-top: 6px; margin-top: 6px; }
.planos-m-nombre { font-weight: 600; color: var(--adei-navy, #16264D); }
.planos-m-datos { display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; margin: 4px 0 0; }
.planos-m-datos dt { color: #64748B; font-size: 0.88rem; }
.planos-m-datos dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.planos-m-estado { font-weight: 600; }
.planos-m-vacia { color: #94a3b8; font-size: 0.88rem; margin: 6px 0 0; }

/* El resumen del capítulo PLEGADO: qué hay dentro sin abrirlo. */
.resumen-cajon {
  color: #64748B;
  font-size: 0.82rem;
  font-weight: 400;
  margin-left: 6px;
}

/* Los capítulos, más marcados: son el índice cuando todo está plegado. */
.tabla-presupuesto .fila-nivel-0 > td { background: #F4F6FA; }
.tabla-presupuesto .fila-nivel-0 .nodo-titulo strong { color: #16264D; }

.barra-arbol-botones {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.buscador {
  border: 1px solid #CBD5E1;
  border-radius: 6px;
  flex: 1 1 260px;
  font-size: 0.95rem;
  min-width: 200px;
  padding: 0.5rem 0.7rem;
}
.buscador:focus { border-color: #1E3A6E; outline: none; }
.buscador-resultado { color: #64748B; font-size: 0.88rem; }

/* ── El contador de «sin gremio»: ¿me falta algo? ── */
.contador-gremios {
  align-items: center;
  background: #FEF3C7;
  border-left: 4px solid #F59E0B;
  border-radius: 6px;
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin-top: 0.8rem;
  padding: 0.7rem 0.9rem;
}
.contador-gremios.todo-ok {
  background: #ECFDF5;
  border-left-color: #10B981;
}

/* ══════════════════════════════════════════════════════════════════════════
   PASO G · EL GREMIO POR CAPÍTULO
   ══════════════════════════════════════════════════════════════════════════ */
.form-gremio-cap {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.form-gremio-cap .gremio-sel { min-width: 220px; }
.form-gremio-cap .pisar {
  color: #B45309;
  font-size: 0.8rem;
  white-space: nowrap;
}

/* Las dudosas SE VEN: no se aplican en bloque y hay que mirarlas. */
.fila-cap-gremio.seg-revisa > td { background: #FFFBEB; }
.fila-cap-gremio.seg-ninguna > td { background: #F8FAFC; }
.fila-cap-gremio.cap-completo > td { background: #F0FDF4; }
.aviso-revisa { color: #B45309; }
.sin-gremio-cnt { color: #B45309; font-weight: 600; }
.todas-ok { color: #10B981; font-weight: 600; }

/* ══════════════════════════════════════════════════════════════════════════════
   EL SELECTOR DE PARTIDA POR CAPÍTULOS  (pasada de «obra real»)

   Nace en el «🔻 Sustituye» de las órdenes de cambio, pero se escribe para ser
   REUTILIZABLE: el presupuesto y la certificación tienen el mismo problema (293
   partidas en lista plana). Por eso las clases se llaman `selector-*` y no
   `oc-*`: no hay nada aquí que sepa de órdenes de cambio.

   EL MÓVIL ES EL OBJETIVO, no un extra: esto se usa EN OBRA. En pantalla ancha es
   una ventana centrada; en el móvil ocupa la pantalla entera, y los botones son
   grandes de verdad (44 px es lo que necesita un dedo, no un ratón).
   ══════════════════════════════════════════════════════════════════════════════ */
.selector-fondo {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(14, 27, 56, .55);          /* el fondo oscuro de ADEI, translúcido */
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
}
.selector-fondo[hidden] { display: none; }

.selector-caja {
  background: #fff; border-radius: 12px;
  width: 100%; max-width: 720px;
  max-height: 85vh; display: flex; flex-direction: column;
  box-shadow: 0 18px 50px rgba(14, 27, 56, .35);
}
.selector-cab {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 14px 16px; border-bottom: 1px solid #E5E9F2;
}
.selector-cab h3 { margin: 0; font-size: 16px; color: #16264D; }

.selector-barra {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 12px 16px; border-bottom: 1px solid #E5E9F2;
}
.selector-barra .buscador { flex: 1; min-width: 180px; }

/* «No sustituye nada» vive FUERA de la lista y del buscador: es el estado por
   defecto y siempre tiene que estar a un dedo, se esté buscando lo que se esté. */
.selector-ninguna {
  margin: 10px 16px 0; padding: 10px 12px;
  border: 1px dashed #C7D0E0; border-radius: 8px; background: #F4F6FA;
  color: #55617A; font-size: 13px; cursor: pointer; text-align: left;
}
.selector-ninguna:hover { border-color: #1E3A6E; color: #16264D; }

.selector-lista { overflow-y: auto; padding: 10px 16px 16px; }

.selector-cap { margin-bottom: 6px; }
.selector-cap-cab {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 11px 12px; min-height: 44px;
  background: #EAF0F9; border: 1px solid #D8E1F0; border-radius: 8px;
  cursor: pointer; text-align: left; font-size: 13px; color: #16264D;
}
.selector-cap.abierto .selector-cap-cab { border-radius: 8px 8px 0 0; }
.selector-cap-cab:hover { background: #DDE7F6; }
.selector-flecha { color: #1E3A6E; font-size: 11px; width: 12px; }
.selector-cap-cod { font-family: ui-monospace, Menlo, Consolas, monospace;
                    font-size: 11px; font-weight: 700; color: #1E3A6E; }
.selector-cap-tit { flex: 1; font-weight: 600; }
.selector-cap-n {
  background: #fff; border: 1px solid #D8E1F0; border-radius: 10px;
  padding: 1px 8px; font-size: 11px; color: #55617A;
}

.selector-partida {
  width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 11px 12px; min-height: 44px;
  background: #fff; border: 1px solid #E5E9F2; border-top: none;
  cursor: pointer; text-align: left; font-size: 13px; color: #16264D;
}
.selector-partida:hover { background: #EFF6FF; }
.selector-cap .selector-partida:last-child { border-radius: 0 0 8px 8px; }
.selector-cod { font-family: ui-monospace, Menlo, Consolas, monospace;
                font-size: 10px; color: #55617A; min-width: 54px; }
.selector-tit { flex: 1; }
.selector-quedan { font-size: 11px; color: #55617A; white-space: nowrap; }

.selector-vacio { padding: 24px; text-align: center; color: #8A93A6; font-size: 13px; }

/* El botón que abre el selector, en la fila de la partida. */
.oc-sust-btn {
  text-align: left; cursor: pointer; background: #fff;
  color: #8A93A6; font-style: italic;
}
.oc-sust-btn-puesto { color: #16264D; font-style: normal; font-weight: 600; }
.oc-sust-btn:hover { border-color: #1E3A6E; }

/* ── EL MÓVIL: pantalla completa. Es donde se usa esto (en obra). ── */
@media (max-width: 640px) {
  .selector-fondo { padding: 0; }
  .selector-caja { max-width: none; max-height: none; height: 100%; border-radius: 0; }
  .selector-barra { position: sticky; top: 0; background: #fff; z-index: 1; }
  .selector-cap-tit { font-size: 12px; }
  /* En el móvil, el código y las unidades se apilan bajo el título en vez de
     apretujarse: con «02.1.1» y «4 ud» compitiendo, el título no se lee. */
  .selector-partida { flex-wrap: wrap; gap: 2px 10px; padding: 12px; }
  .selector-tit { flex-basis: 100%; order: 1; font-weight: 600; }
  .selector-cod { order: 2; }
  .selector-quedan { order: 3; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   ADJUDICAR A SUBCONTRATISTAS (Fase 5 · bloque previo) — bloques por GREMIO

   Lo que tiene que saltar a la vista es UNA cosa: que se está quedando algo FUERA.
   Desmarcar es legítimo (son los colchones), pero un colchón que no se ve se
   convierte en un olvido: trabajo cobrado al cliente que no tiene quien lo haga.
   ══════════════════════════════════════════════════════════════════════════════ */
.adj-bloque { margin: 14px 0; }
.adj-gremio {
  border: 1px solid #D7DDE8; border-radius: 12px; background: #fff; overflow: hidden;
}
.adj-gremio-cab {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 14px; cursor: pointer; background: #F4F6FA; font-size: 14px;
}
.adj-gremio-nombre { font-weight: 700; color: #16264D; }
.adj-gremio-n, .adj-gremio-total { color: #5A6478; font-size: 13px; }
.adj-gremio-total { margin-left: auto; font-variant-numeric: tabular-nums; }
.adj-gremio-hecho { color: #10B981; font-weight: 600; font-size: 13px; }
.adj-tabla { margin: 0; }
.adj-col-check { width: 38px; text-align: center; }
/* La ya adjudicada se apaga: sigue estando (se puede MEZCLAR), pero no es lo normal. */
.adj-ya td { background: #FAFBFD; color: #6B7488; }

.adj-pie {
  display: flex; gap: 24px; flex-wrap: wrap;
  padding: 10px 14px; border-top: 1px solid #E5E9F0; font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.adj-pie-si strong { color: #10B981; }
.adj-pie-no strong { color: #5A6478; }
/* Con colchón, el «se queda fuera» deja de ser gris y pide que lo mires. */
.adj-con-colchon .adj-pie-no strong { color: #EF4444; }
.adj-con-colchon .adj-gremio { border-color: #F2C14E; }
/* ⚠️ UNA SOLA `.adj-acciones` (2026-09-02): se escribió una segunda para la barra de
   «deseleccionar todas» y una red de la casa la cazó — dos reglas con el mismo nombre las FUNDE
   el navegador, y así se aplastó el checklist entero con la bolita del tablero. Es la misma zona
   (las acciones de adjudicar), así que se unifica en vez de renombrar. */
.adj-acciones { padding: 10px 14px 14px; display: flex; align-items: center; gap: .6em;
                flex-wrap: wrap; }

/* ══════════════════════════════════════════════════════════════════════════════
   LICITACIÓN (Fase 5)

   Una sola cosa que separar visualmente: la columna de lo que SE PIDE frente a la
   de lo que la partida COSTABA. Son dos lados de la misma tabla y confundirlos es
   confundir el objetivo con la propuesta — que es justo el error que este módulo
   tiene que hacer imposible.
   ══════════════════════════════════════════════════════════════════════════════ */
.lic-prop {
  background: #F0F7FF;
  color: #1E3A6E;
  font-weight: 600;
}

/* ── 📄 Las dos ranuras del importador (venta / coste) ── */
.ranuras-excel { display: flex; flex-wrap: wrap; gap: 12px; margin: 14px 0 10px; }
.ranura {
  flex: 1; min-width: 250px; display: flex; flex-direction: column; gap: 2px;
  padding: 10px 12px; border-radius: 10px; border: 1px solid #e5e7eb;
  background: var(--adei-fondo-claro, #F4F6FA); position: relative;
}
.ranura-llena { border-left: 4px solid var(--adei-verde, #10B981); }
.ranura-vacia { border-left: 4px solid #d1d5db; }
.ranura-titulo {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .4px; color: var(--adei-navy, #16264D);
}
.ranura-nombre { font-size: 14px; font-weight: 700; color: var(--adei-verde, #10B981);
  word-break: break-all; padding-right: 26px; }
.ranura-ninguno { color: #9ca3af; font-weight: 400; font-style: italic; }
.ranura-fecha { font-size: 11px; color: #6b7280; }
.ranura-quitar { position: absolute; top: 8px; right: 8px; }
.boton-x {
  background: none; border: none; cursor: pointer; font-size: 15px;
  line-height: 1; padding: 2px; border-radius: 6px;
}
.boton-x:hover { background: #fee2e2; }
.aviso-cruce {
  margin: 10px 0; padding: 10px 14px; border-radius: 10px; font-size: 13px;
  background: #fff7ed; border-left: 4px solid #f59e0b; color: #7c2d12;
}

/* ── Margen a tres niveles en «crear presupuesto desde catálogo» ── */
.prec-cap-fila td { background: var(--adei-fondo-claro, #F4F6FA); font-size: 13px; }
.prec-margen-cap, .prec-margen-partida {
  cursor: pointer; border-bottom: 1px dashed #9ca3af; padding-bottom: 1px;
  white-space: nowrap;
}
.prec-margen-cap:hover, .prec-margen-partida:hover { background: #e0e7ff; }
/* ⚠️ Amarillo = margen por debajo del umbral. NO es un tope: en E9 hay 15 partidas a
   margen 0 legítimas (suministros). Avisa, no impide. */
.prec-margen-bajo {
  background: #fef3c7; color: #92400e; font-weight: 700;
  border-radius: 4px; padding: 1px 5px;
}

/* ── El hub de «crear presupuesto»: tres opciones grandes ── */
.hub-opciones { display: flex; flex-wrap: wrap; gap: 16px; margin: 18px 0 22px; }
.hub-opcion {
  flex: 1; min-width: 270px; max-width: 420px; display: flex; flex-direction: column;
  gap: 6px; padding: 18px 20px 16px; border-radius: 14px; text-decoration: none;
  border: 1px solid #d7dbe4; background: #fff; color: inherit; position: relative;
  border-top: 4px solid var(--adei-azul-medio, #1E3A6E);
}
a.hub-opcion:hover { border-color: var(--adei-navy, #16264D); background: var(--adei-fondo-claro, #F4F6FA); }
/* Apagada = no lleva a ninguna parte, y se nota. Un boton que parece vivo y no hace
   nada es peor que uno que se ve apagado. */
.hub-opcion-apagada { opacity: .55; cursor: not-allowed; border-top-color: #9ca3af; }
.hub-letra {
  position: absolute; top: 14px; right: 16px; font-size: 26px; font-weight: 800;
  color: #d7dbe4;
}
.hub-titulo { font-size: 17px; font-weight: 800; color: var(--adei-navy, #16264D); padding-right: 34px; }
.hub-texto { font-size: 13px; line-height: 1.45; color: #4b5563; }
.hub-nota { font-size: 11px; text-transform: uppercase; letter-spacing: .4px; color: #6b7280; margin-top: 4px; }
.hub-nota-falta { color: #92400e; background: #fef3c7; border-radius: 4px; padding: 2px 6px; align-self: flex-start; text-transform: none; letter-spacing: 0; }
.lista-obras-elegir { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: 10px; }

/* ⚠️ LA FRANJA DE «ESTA NO ES LA BASE REAL» (2026-08-01). Naranja de aviso, ancho
   completo y ARRIBA DEL TODO: tiene que ser lo primero que se ve, porque la demo y la
   base de verdad se ven exactamente igual y confundirlas cuesta una tarde de trabajo. */
.aviso-base-demo {
  background: #fef3c7; color: #92400e; border-bottom: 3px solid #f59e0b;
  padding: 8px 16px; font-size: 13px; line-height: 1.4; text-align: center;
}
.aviso-base-demo code {
  background: #fde68a; border-radius: 3px; padding: 1px 5px; font-size: 12px;
}

/* ═══════════════ TABLERO DE CONTABILIDAD ═══════════════
   Los gráficos son barras de CSS a propósito: un `div` con un ancho. Traer una librería de
   gráficos dejaría la pantalla en blanco el día que no cargue el JS, y ese coste ya está
   escrito en esta casa (el precedente de `presupuesto_edicion.js`). */
.tablero-titulo { margin: 0 0 2px; }
.tablero-fecha  { margin: 0 0 18px; color: #64748b; font-size: 13px; }

.tablero-kpis {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px; margin-bottom: 18px;
}
.kpi {
  background: #fff; border-radius: 8px; padding: 14px 16px;
  border-left: 4px solid var(--adei-azul-medio);
  box-shadow: 0 1px 3px rgba(22, 38, 77, .10);
  display: flex; flex-direction: column; gap: 3px;
}
.kpi-verde   { border-left-color: var(--adei-verde); }
.kpi-rojo    { border-left-color: var(--adei-rojo); }
.kpi-azul    { border-left-color: var(--adei-azul-medio); }
.kpi-naranja { border-left-color: #f59e0b; }
.kpi-etiqueta { font-size: 12px; color: #64748b; text-transform: uppercase;
                letter-spacing: .4px; }
.kpi-numero   { font-size: 24px; font-weight: 700; color: var(--adei-navy); }
.kpi-nota     { font-size: 11px; color: #94a3b8; }

.tablero-rejilla {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start;
}
.tablero-columna { display: flex; flex-direction: column; gap: 16px; }

.tarjeta {
  background: #fff; border-radius: 8px; padding: 16px 18px;
  box-shadow: 0 1px 3px rgba(22, 38, 77, .10);
}
.tarjeta h2 { margin: 0 0 12px; font-size: 15px; color: var(--adei-navy); }

.tabla-tablero { width: 100%; border-collapse: collapse; font-size: 13px; }
.tabla-tablero th { text-align: left; font-size: 11px; text-transform: uppercase;
                    letter-spacing: .4px; color: #94a3b8; padding: 0 6px 6px;
                    border-bottom: 1px solid #e2e8f0; }
.tabla-tablero td { padding: 5px 6px; }
.tabla-tablero .der, .tabla-tablero th.der { text-align: right; }
.celda-etiqueta { color: #334155; }
.celda-n        { text-align: right; color: #94a3b8; width: 42px; }
.celda-importe  { text-align: right; font-variant-numeric: tabular-nums;
                  font-weight: 600; white-space: nowrap; }
.celda-roja     { color: var(--adei-rojo); }
.celda-barra    { padding: 0 6px 8px; }

.barra { display: block; height: 6px; border-radius: 3px; min-width: 2px; }
.barra-azul     { background: var(--adei-azul-medio); }
.barra-amarilla { background: #f59e0b; }
.barra-roja     { background: var(--adei-rojo); }

/* 🔴🔴 SE LLAMABA `.punto` Y APLASTABA EL CHECKLIST ENTERO (2026-08-08).
   Esta bolita decorativa del tablero y el `<li class="punto">` del checklist compartían
   nombre. No se pisaban —no tienen ni una propiedad en común— y por eso era PEOR: se
   SUMABAN, así que cada punto del checklist se renderizaba como un cuadrado de 8×8 con el
   texto desbordando. Es literalmente lo que Diego describió: «todo pisado, difícil leer o
   apuntar». Ninguna prueba podía verlo: las dos pantallas salían verdes por separado.
   La bolita es lo que se renombra porque no tiene semántica propia: es un adorno. */
.bolita { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
         margin-right: 4px; vertical-align: middle; }
.bolita-azul     { background: var(--adei-azul-medio); }
.bolita-amarilla { background: #f59e0b; }
.bolita-roja     { background: var(--adei-rojo); }

.tablero-leyenda { font-size: 11px; color: #94a3b8; margin: -6px 0 10px; }
.tablero-vacio   { font-size: 13px; color: #64748b; margin: 10px 0 0; }
.tablero-aviso   { font-size: 12px; color: #92400e; background: #fffbeb;
                   border-radius: 6px; padding: 8px 10px; margin: 10px 0 0; }

.tablero-nota    { font-size: 12px; color: #64748b; margin: 0 0 10px; }

/* EL REPARTO POR SOCIEDADES (2026-08-08). La fila «sin sociedad» va la primera Y se pinta:
   son las facturas sin CIF ni pie legal, y en gris se leerían como un residuo del listado. */
.fila-sin-sociedad td       { background: #fef2f2; }
.etiqueta-sin-sociedad      { display: inline-block; font-size: 11px; font-weight: 700;
                              color: #991b1b; background: #fee2e2; border-radius: 999px;
                              padding: 2px 9px; }

.tabla-vencimientos tbody tr { border-top: 1px solid #f1f5f9; }
.fila-vencida td, .fila-rojo td { background: #fef2f2; }
.fila-amarillo td { background: #fffbeb; }
.numero-doc { font-family: Consolas, "SFMono-Regular", monospace; font-size: 12px; }
.sin-fecha  { color: #94a3b8; font-style: italic; font-size: 12px; }

@media (max-width: 900px) {
  .tablero-rejilla { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EL ARMAZÓN: LATERAL + BARRA + CONTENIDO  (2026-08-02)
   ═══════════════════════════════════════════════════════════════════════════

   Traducido del prototipo `builderp-v3.html` (que es la especificación viva) al
   vocabulario de esta casa. Los seis colores de identidad YA eran los mismos allí
   y aquí, byte a byte, así que no se ha tocado ni uno: su `--nd` es nuestro
   `--adei-fondo-osc` y su `--or`, `--adei-azul-medio`. Lo que faltaba era el
   armazón, porque este ERP tenía barra horizontal y no lateral.

   ⚠️⚠️ LO ÚNICO QUE NO SE COPIA TAL CUAL, Y ES A PROPÓSITO: allí el `body` lleva
   `height:100vh; overflow:hidden` y quien hace scroll es el panel de contenido.
   Aquí NO se puede: `mantener_scroll.js` guarda y restaura `window.scrollY`, y
   con el scroll movido a un div interior ese valor se quedaría clavado en 0 —o
   sea, el «vuelve donde estabas» dejaría de funcionar en las 68 pantallas SIN
   DAR UN SOLO ERROR—. El lateral se queda quieto con `position: sticky`, que se
   ve igual y deja el scroll donde siempre estuvo: en la página.

   ⚠️ El CUERPO de las pantallas NO se toca. `.adei-contenido` conserva su
   `max-width` y su centrado: tablas, formularios y fichas siguen exactamente
   como estaban. Esto es armazón, no un rediseño.
   ═══════════════════════════════════════════════════════════════════════════ */

.adei-armazon { display: flex; align-items: flex-start; min-height: 100vh; }
.adei-principal { flex: 1; min-width: 0; display: flex; flex-direction: column;
                  min-height: 100vh; }

/* ── El lateral oscuro (su #sb: 234px sobre --nd) ── */
.adei-lateral {
  width: 234px; flex-shrink: 0;
  background: var(--adei-fondo-osc);
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
  display: flex; flex-direction: column;
}
.lat-marca { padding: 18px 16px 14px; border-bottom: 1px solid rgba(255,255,255,.06); }
.lat-marca-enlace { display: flex; flex-direction: column; gap: 6px; text-decoration: none; }
.lat-logo {
  color: #fff; font-weight: 800; font-size: 20px; letter-spacing: -1px; line-height: 1;
  border: 2.5px solid currentColor; border-radius: 5px; padding: 3px 8px 4px;
  align-self: flex-start;
}
.lat-subtitulo { color: #6B7689; font-size: 9px; letter-spacing: 1.4px;
                 text-transform: uppercase; }

/* ── La cabecera de obra: la vuelta, y de quién estamos hablando ── */
.lat-obra { padding: 12px 16px; border-bottom: 1px solid rgba(255,255,255,.06); }
.lat-volver { color: rgba(255,255,255,.5); font-size: 11px; text-decoration: none;
              display: block; }
.lat-volver:hover { color: #fff; }
.lat-obra-nombre { color: #fff; font-weight: 700; font-size: 13px; margin-top: 6px;
                   line-height: 1.3; }

/* ── Secciones e items (sus .s-sec / .s-lbl / .ni / .n-ic) ── */
.lat-sec { padding: 11px 9px 3px; }
.lat-lbl {
  color: rgba(255,255,255,.2); font-size: 9px; font-weight: 700; letter-spacing: 1.7px;
  text-transform: uppercase; padding: 0 7px; margin-bottom: 3px;
}
.lat-item {
  display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-radius: 6px;
  color: rgba(255,255,255,.5); font-size: 12px; font-weight: 500;
  text-decoration: none; transition: .15s;
}
.lat-item:hover { background: rgba(255,255,255,.07); color: rgba(255,255,255,.85); }
.lat-item.activo { background: var(--adei-azul-medio); color: #fff; }
.lat-ic { font-size: 13px; width: 17px; text-align: center; flex-shrink: 0; }

/* ── El pie del lateral: quién eres y la salida (sus .s-ft / .u-pill) ── */
.lat-pie { margin-top: auto; padding: 11px 9px;
           border-top: 1px solid rgba(255,255,255,.06); }
.lat-usuario { display: flex; align-items: center; gap: 8px; padding: 7px 9px; }
.lat-avatar {
  width: 27px; height: 27px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(135deg, var(--adei-azul-medio), #0E1B38);
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 11px;
}
.lat-usuario-datos { display: flex; flex-direction: column; min-width: 0; }
.lat-usuario-nombre { color: #fff; font-size: 12px; font-weight: 600;
                      overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lat-usuario-rol { color: rgba(255,255,255,.4); font-size: 10px; }
.lat-pie .boton-salir { margin: 6px 9px 0; }

/* ── La barra superior, ahora BLANCA (su .topbar: 54px + borde) ── */
.adei-cabecera {
  background: #fff; color: var(--adei-navy);
  border-bottom: 1px solid #E2E7EF;
  padding: 0 22px; height: 54px; gap: 12px; flex-wrap: nowrap; flex-shrink: 0;
}
.adei-cabecera .marca-enlace { color: var(--adei-navy); }
.adei-cabecera .marca { font-size: 17px; }
.adei-cabecera .subtitulo { opacity: .55; font-size: 12px; }
.adei-contenido { flex: 1; }

/* ── El botón del lateral en móvil: escondido en escritorio ── */
.lat-boton-movil {
  display: none; background: none; border: 1px solid #E2E7EF; border-radius: 6px;
  font-size: 16px; line-height: 1; padding: 6px 10px; cursor: pointer;
  color: var(--adei-navy);
}
.lat-velo { display: none; }

@media (max-width: 860px) {
  /* El lateral pasa a cajón deslizante, igual que en el prototipo. */
  .adei-lateral {
    position: fixed; top: 0; left: 0; height: 100%; width: 260px; z-index: 999;
    transform: translateX(-100%); transition: transform .28s ease;
    box-shadow: 0 0 40px rgba(0,0,0,.3);
  }
  .adei-lateral.abierto { transform: translateX(0); }
  .lat-boton-movil { display: block; }
  .lat-velo { display: block; position: fixed; inset: 0; z-index: 998;
              background: rgba(0,0,0,.45); }
  .lat-velo[hidden] { display: none; }
  .adei-cabecera { padding: 0 12px; height: 52px; gap: 8px; }
  .adei-cabecera .subtitulo { display: none; }
}

/* ═══════════════ LIBRO DIARIO ═══════════════ */
.ld-filtros { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end;
              margin: 14px 0; padding: 12px; background: var(--adei-fondo-claro, #F4F6FA);
              border: 1px solid #dde3ee; border-radius: 8px; }
.ld-filtros label { display: flex; flex-direction: column; gap: 3px;
                    font-size: 11px; text-transform: uppercase; letter-spacing: .3px;
                    color: #5a6478; font-weight: 700; }
.ld-filtros input, .ld-filtros select { padding: 5px 7px; border: 1px solid #c8d0e0;
                    border-radius: 5px; font-size: 13px; font-family: inherit; }
.ld-filtros input[type="search"] { min-width: 220px; }

.ld-alarma { margin: 12px 0; padding: 10px 12px; border-radius: 8px;
             background: #fdecec; border: 1px solid var(--adei-rojo, #EF4444);
             color: #8a1c1c; font-size: 13px; }
.ld-chip-mal { display: inline-block; margin: 2px 3px; padding: 1px 7px;
               background: #fff; border: 1px solid var(--adei-rojo, #EF4444);
               border-radius: 999px; font-size: 12px; font-weight: 700; }

.ld-tabla { margin-top: 10px; }
.ld-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ld-numero { font-weight: 700; white-space: nowrap; }
.ld-cuenta { white-space: nowrap; }
/* La línea de arriba de cada asiento lo separa del anterior: es lo que hace legible un
   libro diario cuando hay decenas de apuntes seguidos. */
.ld-inicio > td { border-top: 2px solid #c8d0e0; padding-top: 7px; }
.ld-sigue > td { border-top: 1px dotted #e4e8f0; }
.ld-totales > td { border-top: 2px solid var(--adei-navy, #16264D); padding-top: 8px;
                   background: var(--adei-fondo-claro, #F4F6FA); }
.ld-nota { font-size: 11px; color: #5a6478; font-style: italic; }

.ld-vacio { margin: 22px 0; padding: 18px 20px; border-radius: 8px;
            background: var(--adei-fondo-claro, #F4F6FA); border: 1px solid #dde3ee;
            max-width: 760px; line-height: 1.5; }
.ld-vacio p { margin: 0 0 8px; }
.ld-vacio p:last-child { margin-bottom: 0; }


/* ═══ CRM · el kanban de leads (G1, 2026-08-05) ═══
   ⚠️ SCROLL HORIZONTAL EN LA TIRA, no en la página. Son OCHO columnas: dejando que crezca la
   página, todo lo demás (los caídos, el formulario) se iría a la derecha y quedaría fuera de
   la pantalla en un portátil. La tira se desplaza sola y el resto se queda quieto. */
.crm-kanban {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding-bottom: 10px;
  margin-bottom: 16px;
}
.crm-columna {
  flex: 0 0 210px;
  background: var(--adei-fondo-claro, #F4F6FA);
  border: 1px solid #D5DAE4;
  border-radius: 8px;
  padding: 8px;
}
.crm-columna h2 {
  font-size: .82rem;
  margin: 0 0 8px;
  color: #16264D;
  text-transform: uppercase;
  letter-spacing: .02em;
}
.crm-tarjeta {
  display: block;
  background: #fff;
  border: 1px solid #D5DAE4;
  border-left: 3px solid #1E3A6E;
  border-radius: 6px;
  padding: 7px 9px;
  margin-bottom: 7px;
  text-decoration: none;
  color: inherit;
  font-size: .86rem;
}
.crm-tarjeta:hover { border-color: #16264D; }
/* ══ ARRASTRAR LOS LEADS (2026-08-08) ══
   La mano avisa de que la tarjeta se puede coger. ⚠️ Solo en las arrastrables: un lead que ya
   es obra viene con `draggable="false"` y enseñarle la mano prometería algo que no pasa. */
.crm-tarjeta[draggable="true"] { cursor: grab; }
.crm-tarjeta[draggable="true"]:active { cursor: grabbing; }
/* Mientras viaja, la tarjeta se apaga: sin eso no se sabe cuál se está moviendo. */
.crm-arrastrando { opacity: .45; }
/* ⚠️ LA DIANA SE VE, y no es adorno: sin ella se suelta a ciegas y el lead acaba en la
   columna de al lado. Solo se enciende la columna que SÍ cambia algo — la de origen no. */
.crm-diana {
  border-color: #1E3A6E;
  border-style: dashed;
  background: rgba(30, 58, 110, 0.07);
}
.crm-importe { color: #16264D; font-weight: 600; }
/* El sello de «ya es obra»: se ve sin gritar. Un lead convertido no es un aviso, es un dato. */
.crm-sello { color: #10B981; font-weight: 600; }
.crm-vacia { text-align: center; opacity: .4; margin: 4px 0; }


/* ═══ CRM · G5 · el tablero de negociación (2026-08-05) ═══
   ⚠️ El scroll horizontal va en la TABLA, no en la página: con veinte gremios la tabla no
   cabe, y dejar crecer la página mandaría el aviso de «esto no adjudica» fuera de la vista. */
.tabla-ancha { overflow-x: auto; }
.tablero-crm { min-width: 1100px; font-size: .82rem; }
/* La primera columna se queda pegada: sin ella, al desplazarse a la derecha no se sabe de
   qué proyecto es la fila que se está tocando — y ahí se asigna la subcontrata equivocada. */
.tablero-crm .col-pegajosa { position: sticky; left: 0; background: #fff; z-index: 1; }
.tablero-crm thead .col-pegajosa { background: var(--adei-fondo-claro, #F4F6FA); z-index: 2; }
.tablero-crm .col-gremio { font-size: .7rem; }
.tablero-crm .col-equipo { background: #F2F6FC; }
.sel-mini { font-size: .78rem; padding: 2px 4px; max-width: 130px; }

/* ══ T1 · EL MODAL DE LA PARTIDA (2026-08-06, duda 7) ══
 * ⚠️ `hidden` LO ESCONDE DE VERDAD, y por eso el JS lo enciende y apaga con esa propiedad y no
 * con una clase: `[hidden]` lo saca también del árbol de accesibilidad, así que un lector de
 * pantalla no lee un formulario que no está abierto. Con `display:none` en una clase propia
 * habría dos formas de esconderlo y una acabaría ganando por especificidad. */
.adei-modal[hidden] { display: none; }
.adei-modal {
  position: fixed;
  inset: 0;
  background: rgba(14, 27, 56, .55);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 4vh 1rem;
  overflow-y: auto;
  z-index: 100;
}
.adei-modal-caja {
  background: #fff;
  border-radius: 8px;
  padding: 1.25rem 1.5rem;
  max-width: 680px;
  width: 100%;
  box-shadow: 0 8px 32px rgba(14, 27, 56, .3);
}
/* ⚠️ La foto se limita por ALTO y con `auto` de ancho: fijando los dos, una foto apaisada
 * saldría estirada — y una foto deformada del material es peor que ninguna, porque el cliente
 * elige por ella (es la misma regla que ya rige en el PDF de suministros). */
.modal-foto { max-height: 220px; width: auto; max-width: 100%; display: block; margin: .5rem 0; }

/* Las pestañas del modal: CLIENTE y PROVEEDOR.
 * ⚠️ `[hidden]` va con su propia regla y ANTES, por lo mismo que arriba: `.modal-hoja` no
 * cambia el `display`, así que un `hidden` del navegador basta — pero si algún día se le
 * pone `display:block`, esta regla es la que tiene que ganar. */
.modal-hoja[hidden] { display: none; }
.modal-pestanas { display: flex; gap: .25rem; margin: .75rem 0 1rem; border-bottom: 2px solid #e3e8f0; }
.modal-pesta {
  background: none;
  border: none;
  border-bottom: 3px solid transparent;
  margin-bottom: -2px;
  padding: .5rem .9rem;
  font: inherit;
  font-weight: 600;
  color: #5b6a86;
  cursor: pointer;
}
.modal-pesta.activa { color: #16264D; border-bottom-color: #16264D; }
/* ⚠️ El botón apagado se VE apagado. Está apagado mientras no ha cargado la partida, y un
 * botón que no responde sin decir por qué hace pensar que la pantalla está rota. */
.modal-hoja button[disabled] { opacity: .45; cursor: not-allowed; }
.modal-hoja-foto { border-top: 1px solid #e3e8f0; margin-top: 1rem; padding-top: .75rem; }

/* ── 📊📌 PLEGAR EL ANÁLISIS DEL PRESUPUESTO (2026-08-07) ──
 *
 * Diego: «HISTORICO Y ORIGEN. Poder ocultarlo para desplegar, y solo salir un indicativo si
 * hay algo que difiere». Son 265 px de una tabla que no cabía, y la mayor parte del tiempo lo
 * que hace falta saber de ellas es **si hay algo raro**, no el detalle.
 *
 * ⚠️⚠️ PLEGAR NO PUEDE ESCONDER EL AVISO, que es lo único que aquí podía salir caro: el
 * indicativo ⚠️ de las partidas que se desvían de lo que ya se pagó **sobrevive al plegado**,
 * y por eso vive FUERA de `.hist-detalle`. Esconder una columna es comodidad; esconder que un
 * precio se sale de lo pagado antes sería enseñar un presupuesto sin su guardarraíl. */
.analisis-plegado .col-origen { display: none; }
.analisis-plegado .col-historico { width: 34px; }
.analisis-plegado .hist-detalle { display: none; }
.hist-indicador { font-size: .95em; }

/* El botón dice en qué estado está, no qué pasará al pulsarlo: «📊 Histórico y origen» con la
 * marca de encendido/apagado se lee igual antes y después de pulsar. */
#plegar-analisis[aria-pressed='true'] {
  background: var(--adei-fondo-claro, #F4F6FA);
  color: var(--adei-navy, #16264D);
  opacity: .75;
}

/* ── «Mis tareas»: la FECHA LÍMITE y lo VENCIDO (2026-08-07, duda 12) ──
   ⚠️ El rojo se gasta una sola vez. Si lo llevaran también las que vencen pronto, el ojo
   dejaría de distinguir «hay que hacerlo ya» de «hay que hacerlo esta semana», que es
   justamente la distinción por la que existe este punto. Lo cercano va en ámbar. */
.chip-plazo {
  font-size: 10px; font-weight: 700; padding: 2px 7px; border-radius: 6px;
  background: #eef2ff; color: var(--adei-azul-medio); white-space: nowrap;
}
.chip-plazo-cerca   { background: #fff3e0; color: #9a5b00; }
.chip-plazo-vencido { background: #fee2e2; color: #991b1b; }
.tarea-vencida      { border-left: 4px solid var(--adei-rojo); background: #fffafa; }
.contador-vencidas  { background: #fee2e2; color: #991b1b; }

/* ══ VACACIONES · LOS DOS CALENDARIOS (2026-08-07) ══
   🐛 LA MITAD DE ESTO TAPA UN FALLO REAL Y VIEJO: la rejilla del equipo
   (`/ausencias/calendario`) pintaba `cal-fuera`, `cal-pedida`, `cal-finde`, `cal-festivo` y
   `cal-cuenta` desde el 2026-08-05 y **ninguna de las cinco existía en el CSS**. O sea que la
   pantalla que existe para mirar «quién está fuera antes de aprobar» salía con todos los días
   del mismo color, y lo único que distinguía un día libre era un `●` diminuto. La lógica
   estaba bien y la pantalla no lo enseñaba — la regla (A) de esta casa, exacta. */

/* ── Rejilla del EQUIPO: persona × día ── */
.tabla-calendario th, .tabla-calendario td { text-align: center; padding: 4px 6px; font-size: 12px; }
.tabla-calendario td:first-child, .tabla-calendario th:first-child {
  text-align: left; white-space: nowrap; font-weight: 600; }
.cal-finde   { background: #f1f3f7; color: #9ca3af; }
.cal-festivo { background: #fef3c7; color: #92400e; }
/* ⚠️ APROBADA y PEDIDA con colores DISTINTOS, no dos tonos del mismo: una es un hecho y la
   otra todavía no. Confundirlas hace que alguien no pida unos días por una petición que
   luego se rechaza. */
.cal-fuera   { background: #d1fae5; color: #065f46; font-weight: 700; }
.cal-pedida  { background: #fff3e0; color: #9a5b00; font-weight: 700; }
.cal-cuenta  { background: var(--adei-navy); color: #fff; }

/* ── Rejilla MENSUAL de MIS días (mes a mes) ── */
.cabecera-mes { align-items: baseline; gap: 10px; }
.cal-mes { width: 100%; max-width: 520px; border-collapse: separate; border-spacing: 4px; }
.cal-mes th { font-size: 11px; color: #6b7280; font-weight: 700; padding-bottom: 2px; }
.cal-dia {
  height: 46px; width: 14.28%; border-radius: 8px; background: #fff;
  border: 1px solid #e6ebf3; vertical-align: top; padding: 4px 6px;
}
.cal-num   { font-size: 12px; color: #374151; }
.cal-marca { display: block; text-align: center; font-size: 14px; line-height: 1; }
/* Los días de los meses vecinos SE PINTAN, apagados: recortarlos descoloca las columnas y el
   lunes deja de estar debajo del lunes, que es lo único que hace legible un calendario. */
.cal-otro-mes { opacity: .35; }
.cal-hoy { box-shadow: inset 0 0 0 2px var(--adei-azul-medio); }
.cal-dia.cal-mio-aprobado { background: #d1fae5; border-color: #6ee7b7; }
.cal-dia.cal-mio-pedido   { background: #fff3e0; border-color: #f0d5ab; }
.cal-dia.cal-festivo      { background: #fef3c7; border-color: #fcd34d; }
.cal-dia.cal-finde        { background: #f4f6fa; }
.cal-leyenda { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.cal-chip { font-size: 10px; padding: 2px 8px; border-radius: 6px;
            background: #f1f3f7; color: #4b5563; }

/* ══ ACCESOS DIRECTOS de la cabecera (2026-08-07, sección 1 del encargo) ══
   Cuatro atajos a la derecha: Tablón · Fichar · Mis tareas · Calendario.
   ⚠️ `margin-left: auto` los empuja a la derecha sin sacar la marca de su sitio, y el
   `flex-wrap` que ya tenía la cabecera hace que en una pantalla estrecha caigan debajo en vez
   de comerse el logo. En móvil se esconden: ahí manda el lateral deslizante, y repetir los
   mismos cuatro en una cabecera de 360 px la deja sin sitio para nada más. */
.adei-cabecera .atajos { display: flex; gap: 6px; margin-left: auto; flex-wrap: wrap; }
.adei-cabecera .atajo {
  color: #fff; text-decoration: none; font-size: 12px; font-weight: 600;
  padding: 6px 12px; border-radius: 8px; background: rgba(255, 255, 255, .10);
  white-space: nowrap;
}
.adei-cabecera .atajo:hover  { background: rgba(255, 255, 255, .20); }
.adei-cabecera .atajo.activo { background: #fff; color: var(--adei-navy); }
@media (max-width: 760px) {
  .adei-cabecera .atajos { display: none; }
}

/* ── Ajustes de la casa (2026-08-07) ── */
.ajuste-fila { margin-bottom: 10px; }
.ajuste-cab { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.ajuste-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 6px; }
.ajuste-acciones form { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ajuste-acciones small { color: #9ca3af; font-size: 10px; }

/* ── OC · la descripción/alcance de cada partida (2026-08-08) ──
   Plegable: la fila de una partida ya tiene trece controles y una caja de texto siempre
   abierta se come la pantalla en obra. Nace abierta si ya hay algo escrito — escondido tras
   un triángulo cerrado, quien edite la orden no sabría que hay texto y guardaría creyendo
   que está vacío. */
.oc-fila-texto { margin: 4px 0 2px; }
.oc-fila-texto > summary {
  cursor: pointer; font-size: 11px; color: #6b7280; list-style: none; display: inline-block;
}
.oc-fila-texto textarea {
  width: 100%; margin-top: 4px; padding: 5px 7px; font-size: 12px;
  border: 1px solid #d3dbe8; border-radius: 6px; font-family: inherit;
}

/* ── Gremios · lo que ADEI sabe de cada uno (2026-08-08) ── */
.gremio-checklist > summary { cursor: pointer; font-size: 12px; list-style: none; }
.gremio-puntos { margin: 6px 0 0 16px; padding: 0; font-size: 11px; color: #4b5563; }
/* ⚠️ El texto va ENTERO y con saltos: Diego lo pidió «VISIBLE, NO recortado». Un `nowrap`
   o un `text-overflow: ellipsis` aquí volvería a cortarlo, que es lo que se viene a
   arreglar. */
.gremio-puntos li { margin-bottom: 3px; white-space: normal; }
.etiqueta-foto { background: #fff3e0; color: #9a5b00; }
.gremio-ratio {
  font-weight: 700; font-variant-numeric: tabular-nums; color: var(--adei-azul-medio);
}

/* ── Subcontrata · el CONTRATO FIRMADO (2026-08-08) ── */
.adj-contrato { display: block; margin: 8px 0 2px; font-size: 12px; }
.adj-contrato input { display: block; margin-top: 3px; font-size: 12px; }
/* ⚠️ El aviso va en ROJO y junto al botón: un requisito que aparece como un `required` mudo
   se lee como una pega del programa, no como «esto compromete dinero». */
.adj-contrato-nota { color: #991b1b; margin: 2px 0 8px; }
.adj-contrato-celda form { display: flex; align-items: center; gap: 4px; margin-top: 4px; }
.adj-contrato-celda input[type="file"] { font-size: 10px; max-width: 150px; }
.etiqueta-sin-contrato { background: #fee2e2; color: #991b1b; }

/* ── Licitación · pedir precio a VARIAS empresas en copia oculta (2026-08-08) ── */
.lic-correo { display: inline-block; vertical-align: top; }
.lic-correo > summary { cursor: pointer; list-style: none; display: inline-block; }
.lic-correo form { margin-top: 8px; padding: 10px; background: #f4f6fa;
                   border: 1px solid #dfe5f0; border-radius: 10px; max-width: 380px; }
/* ⚠️ Una por línea: en una fila corrida, con quince proveedores, marcar la que toca es una
   lotería — y aquí equivocarse es mandarle la petición de precio a quien no era. */
.lic-correo-uno { display: block; font-size: 12px; margin-bottom: 3px; }

/* ── Postventa global (2026-08-08) ── */
.pv-filtro { text-decoration: none; color: #4b5563; font-size: 12px;
             padding: 4px 10px; border-radius: 8px; background: #f1f3f7; }
.pv-filtro.activo { background: var(--adei-navy); color: #fff; font-weight: 700; }
/* ⚠️ «Abierta» en rojo: es lo único que pide acción. Si los tres estados fueran del mismo
   color, la pantalla diría cuántas hay pero no qué hacer. */
.pv-abierta  { background: #fee2e2; color: #991b1b; }
.pv-subsanada { background: #fff3e0; color: #9a5b00; }
.pv-cerrada  { background: #d1fae5; color: #065f46; }

/* ── Acta · el checklist de planos vencido (2026-08-08) ── */
.planos-vencidos { margin: 6px 0 8px 18px; padding: 0; font-size: 12px; }
.planos-vencidos li { margin-bottom: 4px; }

/* ── Importar mediciones · ¿incluir los costes? (2026-08-08) ── */
.med-costes { display: block; margin: 12px 0 2px; font-size: 13px; }

/* ── Presupuesto · el renglón vacío al final de cada cajón (2026-08-08) ── */
.fila-renglon-nuevo td { background: #fafbfd; border-top: 1px dashed #dfe5f0; padding: 4px 8px; }
.renglon-nuevo { display: flex; align-items: center; gap: 6px; }
/* ⚠️ Apagado a propósito: es una invitación, no una partida. Con el mismo peso visual que
   una fila de verdad, la tabla parecería tener una partida vacía en cada capítulo. */
.renglon-mas { color: #9ca3af; font-size: 14px; }
.renglon-nuevo input[type="text"] {
  flex: 1; max-width: 420px; padding: 4px 8px; font-size: 12px;
  border: 1px dashed #cbd5e1; border-radius: 6px; background: #fff;
}
.renglon-nuevo input[type="text"]:focus { border-style: solid; }

/* ── Preciario · los DOS textos de la partida (2026-08-08) ── */
.prec-textos { margin-top: 3px; }
.prec-textos > summary { cursor: pointer; font-size: 11px; color: #6b7280; list-style: none; }
.prec-txt-dos { font-size: 9px; font-weight: 700; background: #eef2ff;
                color: var(--adei-azul-medio); padding: 1px 5px; border-radius: 5px; }
.prec-txt { margin: 5px 0 0; padding-left: 10px; border-left: 3px solid #dfe5f0; }
/* ⚠️ El del gremio se distingue del del cliente: son dos destinatarios y confundirlos es,
   literalmente, prometerle a una empresa cosas que no se le están pagando. */
.prec-txt-gremio { border-left-color: #9a5b00; }
.prec-txt-de { display: block; font-size: 9px; text-transform: uppercase;
               letter-spacing: .04em; color: #9ca3af; }
.prec-txt p { margin: 2px 0 0; font-size: 12px; color: #374151; white-space: pre-wrap; }

/* ── Preciario · agrupado por capítulo (2026-08-08) ── */
.prec-cap td { background: #eaf0f9; border-top: 2px solid #dfe5f0; padding: 6px 10px; }
.prec-cap strong { color: var(--adei-navy); }
.prec-cap-cod { font-family: monospace; font-size: 11px; color: #6b7280; margin-right: 6px; }

/* ── Preciario · «usar la media» del histórico (2026-08-08) ── */
.hist-usar { margin-top: 4px; }
/* ⚠️ Se DESTACA cuando la fila ya está en un tramo que existe (amarillo o rojo). No es un
   umbral nuevo: es la misma señal que ya pinta la fila, dicha también en el botón. */
.hist-usar-sugerida button { border-color: #9a5b00; background: #fff3e0; color: #9a5b00;
                             font-weight: 700; }

/* ── Facturas de proveedor · el % de avance (2026-08-08) ── */
.pct-cert { font-weight: 700; color: var(--adei-azul-medio); }
.pct-fact { color: #6b7280; }
/* ⚠️ Solo se marca cuando el facturado va POR DELANTE del certificado. Marcar los dos
   siempre haría que la señal no dijera nada. */
.pct-adelantado { color: #991b1b; font-weight: 700; }

/* ── Subcontrata · el PLAZO pactado (2026-08-08) ── */
.sub-plazo { white-space: nowrap; font-size: 12px; }
.sub-penal { color: #9a5b00; }
/* ⚠️ Rojo: sin plazo no hay retraso que reclamar, así que la penalización del contrato del
   cliente se queda sin nada detrás. No es un hueco administrativo. */
.etiqueta-sin-plazo { background: #fee2e2; color: #991b1b; }
.sub-plazo-editar > summary { cursor: pointer; font-size: 11px; color: var(--adei-azul-medio); }
.sub-plazo-editar form { margin-top: 4px; }
.sub-plazo-editar label { display: block; font-size: 10px; color: #6b7280; }
.sub-plazo-editar input { width: 110px; padding: 3px 6px; font-size: 12px;
                          border: 1px solid #d3dbe8; border-radius: 6px; }

/* ═══ ⏳ EL PRESUPUESTO CARGADO POR CAPÍTULOS (2026-08-08 · duda 43) ═══ */
.presupuesto-perezoso { margin: 6px 0 10px; }
/* ⏳ El filtro «solo las que no estan completas» (Diego, 2026-09-01).
   ⚠ SE VE, y no es adorno: mientras esta puesto hay partidas escondidas en LA pantalla del
   dinero. Un filtro discreto es un filtro que se olvida uno de que tiene puesto. */
.cert-filtro {
  margin: 6px 0 10px; padding: .4rem .7rem;
  border-left: 3px solid var(--adei-azul-medio, #1E3A6E);
  background: var(--adei-fondo-claro, #F4F6FA); border-radius: 4px;
}
.cert-filtro small { display: block; color: #64748B; }
/* Mientras viajan las filas. Sin señal, un capítulo lento se lee como un clic perdido y se
   vuelve a pulsar — que es justo lo que duplicaría la petición. */
.cajon-cargando { opacity: .6; }
/* ⚡ La celda mientras viaja el guardado (2026-08-25). Es MUY breve --medido: 3 ms de
   servidor-- asi que no lleva spinner ni nada que parpadee: solo se apaga un poco.
   Un indicador aparatoso para 3 ms se ve como un fallo, no como progreso. */
.celda-guardando { opacity: .55; }

/* ⚡ LAS UNIDADES A UN CLIC, dentro del editor de la celda (2026-08-25).
   Un `<datalist>` filtra por lo que hay escrito, y el editor abre con la unidad actual dentro:
   por eso «solo salia la actual». Estos botones no dependen de eso. */
.editor-chips { display: flex; flex-wrap: wrap; gap: 4px; width: 100%; }
.editor-chip {
  font: inherit;
  font-size: .85em;
  padding: 2px 8px;
  border: 1px solid var(--adei-azul-medio, #1E3A6E);
  background: var(--adei-fondo-claro, #F4F6FA);
  border-radius: 999px;
  cursor: pointer;
}
.editor-chip:hover { background: var(--adei-azul-medio, #1E3A6E); color: #fff; }

/* 📤 EL DESPLEGABLE DE EXPORTAR (2026-08-25). Un `<details>`: sin JavaScript, con teclado. */
.menu-exportar { position: relative; display: inline-block; }
.menu-exportar > summary { list-style: none; cursor: pointer; }
.menu-exportar > summary::-webkit-details-marker { display: none; }
.menu-exportar-hoja {
  position: absolute;
  z-index: 60;
  top: calc(100% + 4px);
  left: 0;
  min-width: 250px;
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--adei-azul-medio, #1E3A6E);
  border-radius: 6px;
  box-shadow: 0 6px 18px rgba(14, 27, 56, .18);
  padding: 4px;
}
.menu-exportar-hoja a {
  padding: 8px 10px;
  border-radius: 4px;
  text-decoration: none;
  color: inherit;
  white-space: nowrap;
}
.menu-exportar-hoja a:hover { background: var(--adei-fondo-claro, #F4F6FA); }

/* ⭐ EL RENGLÓN DE «NUEVA PARTIDA»: escribirla, o cogerla del preciario (2026-08-26). */
/* ⚠️ EL AVISO ROJO: «esto NO se firma así». Es el mismo rojo que el de los datos que faltan
   (`ROJO_FALTA` del PDF), a propósito: lo que falta y lo que está sin acordar se leen igual de
   urgentes, y dos rojos distintos en la misma casa no dicen nada. */
.aviso-rojo {
  border: 1px solid var(--adei-rojo, #EF4444);
  background: #FEF2F2;
  border-radius: 6px;
  padding: 10px 12px;
  margin: 10px 0;
}

.renglon-o { color: #5a6580; margin: 0 4px; }
.renglon-filtro {
  width: 110px;
  padding: 3px 6px;
  border: 1px solid #cbd3e4;
  border-radius: 4px;
}
.renglon-preciario {
  max-width: 320px;
  padding: 3px 6px;
  border: 1px solid #cbd3e4;
  border-radius: 4px;
  background: #fff;
}
@media (max-width: 900px) { .renglon-preciario { max-width: 150px; } }

/* 📏 LA LISTA DE PARTIDAS SIN MEDIR (2026-08-26). Cada una salta a su fila.
   ⚠️ Con `max-height` y scroll: si un presupuesto recien importado tiene 200 sin medir, la
   lista empujaria la tabla fuera de la pantalla y el aviso taparia justo lo que hay que
   arreglar. */
.lista-sin-medir {
  margin: 8px 0 0;
  padding-left: 20px;
  max-height: 190px;
  overflow-y: auto;
  columns: 2;
  column-gap: 24px;
}
.lista-sin-medir li { break-inside: avoid; margin: 2px 0; }
.lista-sin-medir a { color: inherit; }
.lista-sin-medir a:hover { text-decoration: underline; }
@media (max-width: 900px) { .lista-sin-medir { columns: 1; } }

/* ⭐ LA VENTANA DE OPCIONES (2026-08-26, Diego: «que salga una ventana con las opciones de si
   quiero incluir desglose de medicion, textos, imagenes. Con o sin precios»).
   ⚠️ Sigue siendo el MISMO `<details>`: casillas y radios, sin JavaScript nuevo. */
.menu-exportar-opciones { min-width: 340px; padding: 10px 12px; gap: 2px; }
.menu-exportar-opciones .ayuda { margin: 8px 0 2px; }
.menu-exportar-opciones .ayuda:first-child { margin-top: 0; }
.menu-exportar-opciones label {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 4px 2px;
  border-radius: 4px;
  cursor: pointer;
  line-height: 1.35;
}
.menu-exportar-opciones label:hover { background: var(--adei-fondo-claro, #F4F6FA); }
.menu-exportar-opciones label small { color: #5a6580; }
.menu-exportar-botones {
  display: flex;
  gap: 8px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid #dde3ee;
}

/* 🔽 «ACCIONES» FLOTA (2026-08-25, decisión de Diego: «que salga como un desplegable, así no me
   mueve visualmente todas las partidas»).

   Es EXACTAMENTE la lección del editor de celda, que ya se pagó dos veces: un panel que se
   despliega DENTRO de la fila la hace crecer, y con ella toda la tabla por debajo — la pantalla
   «da un salto» y pierdes de vista la partida que estabas mirando. Flotando (`position:
   absolute`) el panel **ocupa cero**, así que la fila no puede crecer.

   ⚠️ La fila es el ancla (`position: relative` de abajo). Sin eso el panel se colgaría del
   primer antepasado posicionado y saldría en una esquina, lejos de su partida. */
.tabla-presupuesto td { position: relative; }
.nodo-acciones[open] > summary { font-weight: 600; }
.nodo-acciones-hoja { display: none; }
.nodo-acciones[open] > .nodo-acciones-hoja {
  display: block;
  position: absolute;
  z-index: 50;
  top: 100%;
  right: 0;
  min-width: 260px;
  background: #fff;
  border: 1px solid var(--adei-azul-medio, #1E3A6E);
  border-radius: 6px;
  box-shadow: 0 6px 18px rgba(14, 27, 56, .18);
  padding: 8px;
  text-align: left;
}
.cajon-error { background: rgba(239, 68, 68, 0.08); }
.cajon-aviso { color: #EF4444; font-weight: 600; }
/* La partida a la que lleva el buscador se marca un momento: sin eso, con el capítulo abierto
   y 40 filas nuevas en pantalla, «te lleva» significa dejarte delante de un muro de filas. */
.fila-encontrada { background: rgba(16, 185, 129, 0.18) !important; transition: background .4s; }
.buscar-resultados {
  border: 1px solid #D5DAE4;
  border-radius: 6px;
  padding: 6px 10px;
  margin: 6px 0 10px;
  background: var(--adei-fondo-claro, #F4F6FA);
  max-height: 320px;
  overflow-y: auto;
}
.buscar-lista { list-style: none; margin: 0; padding: 0; }
.buscar-lista li { padding: 2px 0; }
.buscar-lista a { color: #16264D; text-decoration: none; font-size: .88rem; }
.buscar-lista a:hover { text-decoration: underline; }

/* ═══ TABLERO · el proveedor FIRMADO frente al previsto (2026-08-08) ═══ */
/* ⚠️ Se distingue a simple vista de un desplegable de previsión: en verde y con su ✍️. Que
   las dos cosas se vean iguales es lo que hace que alguien lea una previsión como un
   contrato — y le pida una certificación a quien no tiene el trabajo. */
.tablero-firmado { color: #0F7A5A; font-weight: 600; text-decoration: none; font-size: .82rem; }
.tablero-firmado:hover { text-decoration: underline; }
.tablero-sin-plazo { color: #B45309; font-weight: 600; }

/* ⚠️ El contrato que ya se ha pasado de su fecha. En rojo y con su ⚠️, no solo en rojo: quien
   mire en blanco y negro —o imprima la pantalla— tiene que verlo igual. */
.sub-tarde { color: #EF4444; font-weight: 600; }
/* ⚠️ «Falta cuándo empieza» NO es «sin plazo»: se pactó cuánto dura y falta desde cuándo. Dos
   estados distintos, dos marcas — con la misma, un contrato CON plazo se leería como si no lo
   tuviera. En ámbar, que es «incompleto», no en rojo, que es «no hay nada». */
.etiqueta-falta-inicio { color: #B45309; font-weight: 600; }

/* ═══ §8 · cambiar de subcontrata desde la certificación (2026-08-09) ═══ */
.cert-subcontratas {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin: 0 0 14px; padding: 8px 10px;
  background: var(--adei-fondo-claro, #F4F6FA);
  border: 1px solid #D5DAE4; border-radius: 8px;
}
/* ⚠️ Los contratos de la MISMA empresa van pegados y con su nombre delante: es lo que hace ver
   de un vistazo que Pepe lleva dos gremios — el caso en que se certifica uno y se olvida el
   otro, que es dinero pagado de menos. */
.cert-sub-grupo { display: inline-flex; align-items: center; gap: 5px; }
.cert-sub-nombre { font-size: .82rem; color: #16264D; }
.cert-sub-chip {
  display: inline-block; padding: 3px 9px; border-radius: 999px;
  border: 1px solid #D5DAE4; background: #fff;
  font-size: .8rem; color: #16264D; text-decoration: none;
}
.cert-sub-chip:hover { border-color: #16264D; }
.cert-sub-activo { background: var(--adei-navy, #16264D); color: #fff; border-color: #16264D; }

/* ═══ 🧵 EL HILO DE LA OBRA (§13 · 2026-08-09) ═══ */
.hilo { list-style: none; margin: 0; padding: 0; }
.hilo-eslabon {
  display: flex; gap: 10px; align-items: baseline;
  padding: 7px 0 7px 12px;
  /* La línea vertical que los une: es lo que hace que se lea como una CADENA y no como una
     lista suelta — y el punto entero es que se ve dónde se corta. */
  border-left: 3px solid #D5DAE4;
}
.hilo-hecho { border-left-color: #10B981; }
.hilo-cortado { border-left-color: #EF4444; background: rgba(239, 68, 68, 0.05); }
/* ⚠️ «Todavía no toca» NO va en rojo ni en verde: en gris. Pintar de rojo lo que aún no ha
   llegado enseña a no mirar los rojos, y entonces el que importa tampoco se mira. */
.hilo-pendiente { border-left-color: #D5DAE4; opacity: .75; }
.hilo-marca { flex: 0 0 auto; }
.hilo-cuerpo { flex: 1 1 auto; font-size: .9rem; }

/* ⭐ EL CHECKLIST DE SUBSANACIÓN de una incidencia de postventa (V2 §23.2, 2026-08-09).
   Abierto por defecto cuando queda algo: lo que falta tiene que verse sin pulsar nada. */
.pv-checklist { margin: .6rem 0; }
.pv-checklist > summary { cursor: pointer; font-size: 14px; }
.lista-puntos-pv { list-style: none; margin: .4rem 0; padding-left: 0; }
.lista-puntos-pv li {
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  padding: .15rem 0; border-bottom: 1px solid rgba(22, 38, 77, .08);
}
.lista-puntos-pv .form-inline { display: inline; margin: 0; }
/* Hecho: tachado y apagado. Se sigue leyendo —hace falta para saber qué se hizo— pero deja
   de competir por la atención con lo que aún está pendiente. */
.lista-puntos-pv li.punto-hecho > span:first-of-type {
  text-decoration: line-through; opacity: .55;
}

/* ── 📐 EL DESGLOSE DE LA CERTIFICACION (2026-08-27) ──────────────────────────────────
   Diego: «click en MEDICION de una linea -> desglose». Va como un boton pequeño DENTRO de la
   celda y no en el clic de la celda: el doble clic es el editor rapido, que es lo que se usa
   cuarenta veces seguidas al certificar un mes. Misma decision que en el presupuesto (25/08).
   ⚠️ `position: absolute` para que NO haga crecer la fila: la celda de medicion es estrecha y
   un elemento en flujo la ensancharia, desalineando la tabla del dinero. */
.cert-desglose-boton {
  position: absolute;
  right: 2px;
  bottom: 1px;
  font-size: 11px;
  line-height: 1;
  text-decoration: none;
  opacity: 0.45;
}
.cert-desglose-boton:hover { opacity: 1; }
/* La celda tiene que ser el ancla del absoluto, o el boton se iria a la esquina de la tabla. */
td[data-cert-medicion] { position: relative; }

/* La linea del desglose que NACIO CERTIFICANDO: se ve, que es lo que pidio Diego
   («si se dejara expresado como orden de cambio de medicion para darle visibilidad»). */
.fila-exceso td { background: #FFFBEB; }

/* ══ 👥 LA AGENDA: PERSONAS DENTRO DE LA EMPRESA (Diego, 2026-08-28) ══ */
.agenda-personas > summary { cursor: pointer; color: var(--adei-azul-medio, #1E3A6E); }
.agenda-personas-lista { margin: .35rem 0 0; padding-left: 1.1rem; }
.agenda-personas-lista li { margin-bottom: .35rem; }

/* 🔴 EL MISMO NOMBRE CON DOS CIF. Diego: «remárcalas en rojo para comprobar cuál es el
   verdadero». El ERP no elige: enseña los dos. */
.cif-en-conflicto { color: #EF4444; }

/* ⚠️ LA COLUMNA DE ACCIONES DE LA AGENDA (Diego, 2026-08-28: «actualmente se están pisando»).
   El botón de borrar vive dentro de un `<form>`, que es un elemento de BLOQUE: al lado de un
   enlace en línea se montaban uno sobre otro. Se ponen en fila con su hueco, y el formulario
   deja de ocupar una línea entera para él solo. */
/* 🔴 NO SE LLAMA `.col-acciones`, Y ES UN NOMBRE QUE ESTUVE A PUNTO DE PISAR: esa clase ya
   la usan las tres plantillas de CERTIFICACIÓN, así que una regla sin acotar habría
   convertido en `flex` las celdas de LA PANTALLA DEL DINERO — sin dar ningún error y sin que
   nadie relacionara las dos cosas. Lo cazó una prueba que buscaba la regla y encontró OTRA. */
.agenda-acciones { display: flex; gap: 6px; align-items: center; white-space: nowrap; }
.agenda-acciones form { display: inline-flex; margin: 0; }

/* 🔤 LA BARRA DE LETRAS DE LA AGENDA (Diego, 2026-08-28).
   ⚠️ La letra grande y el contador pequeño DEBAJO: con los dos del mismo tamaño, el ojo lee
   «A3 B12 C7» como una sola cosa y la barra deja de servir para lo que existe. */
.barra-letras { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; margin: .6rem 0; }
.barra-letras .letra {
  display: inline-flex; flex-direction: column; align-items: center; line-height: 1;
  min-width: 2.1rem; padding: 4px 6px; border: 1px solid #d7dce6; border-radius: 6px;
  text-decoration: none; color: var(--adei-navy, #16264D); background: #fff;
}
.barra-letras .letra small { font-size: .62rem; opacity: .6; margin-top: 2px; }
.barra-letras .letra:hover { background: var(--adei-fondo-claro, #F4F6FA); }
.barra-letras .letra-activa {
  background: var(--adei-navy, #16264D); color: #fff; border-color: var(--adei-navy, #16264D);
}
.barra-letras .letra-activa small { opacity: .8; }

/* 🔎 CONVERTIR UN POSIBLE: la foto al lado del formulario (Diego, 2026-08-28).
   ⚠️ EN DOS COLUMNAS Y NO UNA DEBAJO DE OTRA: el punto entero es leer el CIF del rótulo
   MIENTRAS se teclea. Con la foto arriba y el formulario abajo hay que subir y bajar por cada
   campo, que es lo mismo que tenerla en otra pestaña. En móvil se apilan, que ahí no hay sitio
   para dos columnas y la foto se puede ampliar. */
.convertir-posible { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; align-items: start; }
.convertir-foto img { max-width: 100%; border-radius: 8px; border: 1px solid #d7dce6; }
@media (max-width: 900px) { .convertir-posible { grid-template-columns: 1fr; } }

/* 🔴 LAS PESTAÑAS DEL BANCO DE POSIBLES, CON NOMBRE PROPIO. Se llamaron `.pestanas` y la red
   de clases repetidas lo cazó: **esa clase ya la usan el tablero del CRM y suministros**, así
   que la regla se les habría aplicado a las tres pantallas. Es el mismo susto que
   `.col-acciones` esta misma tarde, y el aviso de esa red cita el destrozo histórico: «así se
   aplastó el checklist entero con la bolita del tablero». */
/* Las pestanas de filtro. ⚠️ EL NOMBRE NEUTRO ES `adei-pestanas`: nacio en «posibles»
   y ya la usan las licitaciones. Se anade el alias en el MISMO bloque en vez de copiar
   las reglas: dos copias «identicas» solo pueden divergir en silencio (regla G). */
.posibles-pestanas, .adei-pestanas { display: flex; flex-wrap: wrap; gap: 6px; margin: .6rem 0; }
.posibles-pestanas .posibles-pestana, .adei-pestanas .adei-pestana {
  padding: 6px 12px; border: 1px solid #d7dce6; border-radius: 6px; text-decoration: none;
  color: var(--adei-navy, #16264D); background: #fff;
}
.posibles-pestanas .posibles-pestana small,
.adei-pestanas .adei-pestana small { opacity: .6; }
.posibles-pestanas .posibles-pestana-activa, .adei-pestanas .adei-pestana-activa {
  background: var(--adei-navy, #16264D); color: #fff; border-color: var(--adei-navy, #16264D);
}
.posibles-pestanas .posibles-pestana-activa small,
.adei-pestanas .adei-pestana-activa small { opacity: .8; }

/* ⬇️ Plegar y desplegar los gremios de ADJUDICAR (Diego, 2026-08-28). */
.adj-mandos { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: .6rem 0; }
/* ⚠️ «Sin adjudicar» en el color de aviso y NO en rojo: no está mal, está por hacer. El rojo
   de esta casa significa «no se puede seguir», y gastarlo aquí lo devalúa donde sí frena. */
.adj-gremio-pendiente {
  margin-left: auto; padding: 2px 8px; border-radius: 10px;
  background: #FEF3C7; color: #92400E; font-size: .78rem; white-space: nowrap;
}

/* 🧮 LA MATRIZ DE COMPARATIVA (Diego, 2026-08-29 · paso 2).
   ⚠️ Nombre PROPIO (`comp-*`): en esta casa se han pisado DOS clases en una tarde
   (`col-acciones` y `pestanas`), y la red de clases repetidas cita el destrozo historico. */
.tabla-comparativa th.comp-empresa { min-width: 8.5rem; }
.tabla-comparativa td.comp-celda { white-space: nowrap; }
/* El precio mas bajo de la fila. ⚠️ Con FONDO y no solo con color de letra: en una matriz de
   1.172 celdas, un color de texto se pierde entre los numeros de al lado. */
.tabla-comparativa .comp-mejor { background: #ECFDF5; }
.tabla-comparativa .comp-mejor strong { color: #047857; }
.comp-barato { color: #047857; }

/* ══════ 🎨 LOS TRES COLORES DE LA COMPARATIVA (Diego, 2026-09-01) ══════
   negro        lo que la empresa DIJO
   comp-deducido   repartido de SU PROPIO total -> «aclarar con la subcontrata»
   comp-imputado   ROJO: lo que le ponemos NOSOTROS porque no puede hacerla,
                   «sin cerrar con el proveedor»
   ⚠️ NINGUNO DE LOS DOS ULTIMOS SE GUARDA como precio de esa empresa: se calculan al pintar.
   ⚠️ El fondo va suave a proposito: encima se pinta `comp-mejor`, y dos fondos fuertes
      peleando dejan la celda ilegible. */
.tabla-comparativa .comp-imputado { color: #EF4444; background: #FEF2F2; }
.tabla-comparativa .comp-imputado strong { color: #EF4444; }
.tabla-comparativa .comp-deducido { color: #9a5b00; background: #FFFBEB; }
.tabla-comparativa .comp-deducido strong { color: #9a5b00; }
.comp-imputado-aviso { color: #EF4444; }
.comp-deducido-aviso { color: #9a5b00; }
/* «Incluida en otra»: NO suma, y por eso se pinta apagada — pero SIGUE EXISTIENDO, porque si
   esa empresa gana la partida entra en su contrato a cero apuntando a la que la absorbe. */
.comp-incluida { color: #666; font-style: italic; }
.comp-subcabecera th { border-top: 0; padding-top: 0; color: #666; }

/* 📨 DE QUE PRE-LICITACION VIENE EL COSTE de una partida (2026-09-01). Discreto: es la
   procedencia de un numero, no una alarma. */
.origen-licitacion { font-size: .72em; color: #1E3A6E; text-decoration: none; }
.origen-licitacion:hover { text-decoration: underline; }

/* 📥 EL MENU DE DESCARGA de la licitacion (2026-09-01): cuatro combinaciones en dos casillas.
   ⚠ FLOTA (`position: absolute`): desplegarlo no puede empujar la tabla de la comparativa,
   que es la leccion del 19/08 con el editor de celda. */
.lic-descarga { display: inline-block; position: relative; }
.lic-descarga > summary { cursor: pointer; list-style: none; }
.lic-descarga[open] > form {
  position: absolute; z-index: 30; background: #fff; border: 1px solid #d7dde8;
  border-radius: 6px; padding: 10px 12px; min-width: 320px; box-shadow: 0 6px 18px #0002;
}
.lic-descarga form label { display: block; margin: 4px 0; }

/* ✏️ LO QUE SE PIDE, EDITABLE A DOBLE CLIC (2026-09-01). El editor flota (`editor_flotante`),
   asi que la fila NO se mueve — es el bug que se arreglo mal dos veces en agosto. */
.lic-editable { cursor: cell; }
/* ⚠️ LA MEDICION TOCADA A MANO SE VE: un numero que alguien decidio no se lee igual que uno
   que sale de un porcentaje, y con 33 lineas hay que poder distinguirlas de un vistazo. */
.lic-a-mano { background: #FFFBEB; }
.lic-a-mano-marca { color: #9a5b00; font-size: .7em; }

/* ⏳ EL MENOR DE LOS ULTIMOS 6 MESES (2026-09-01). Verde: es el numero con el que NO pagar de
   mas, no una alarma. */
.hist-minimo { color: #047857; }

/* 🏭 LA FECHA TOPE DEL PEDIDO (2026-09-01). Ambar: no es un retraso todavia, es algo que hay
   que hacer ANTES de una fecha. En rojo se confundiria con «va tarde», que es otra cosa. */
.sub-fabrica { color: #9a5b00; }

/* ➡️ EL PASO SIGUIENTE (2026-09-01). Verde: no es una alarma, es que hay algo que hacer y se
   sabe cual. */
.adei-siguiente-paso { border-left: 4px solid #10B981; }

/* 💰 SE COMPRA A OTRO PRECIO (2026-09-02). Verde por defecto: comprar mas barato tambien
   «difiere» y es una BUENA noticia -- pintarlo todo de alarma enseña a ignorarlo. Solo se pone
   ambar cuando cuesta MAS de lo presupuestado, que es lo que se come el margen. */
.compra-difiere { color: #047857; }
.compra-difiere.compra-cara { color: #9a5b00; }

/* 📥 UN PRECIO QUE VIENE DEL EXCEL DE LA EMPRESA (2026-09-02). Se marca para que se vea CUAL
   ha puesto el ERP y cual has tecleado tu: son dos afirmaciones distintas y la pantalla no
   puede darlas por iguales. */
.oferta-importada { background: #ECFDF5; border-color: #10B981; }

/* 🗑️ QUITAR UNA PARTIDA DE LA LICITACION (2026-09-02). En linea con el titulo y discreto: es
   una operacion poco frecuente («por si se me colo alguna») y un boton grande por fila en 293
   filas convierte la tabla en un campo de minas. */
.lic-quitar { display: inline; margin-left: .4em; }
.lic-quitar .boton-icono { background: none; border: 0; cursor: pointer; opacity: .45;
                           font-size: .95em; padding: 0 .2em; }
.lic-quitar .boton-icono:hover { opacity: 1; }

/* 🔍 AÑADIR PARTIDAS: grupos plegables y buscador (2026-09-02). */
.anadir-controles { display: flex; align-items: center; gap: .6em; flex-wrap: wrap;
                    margin: .6em 0; }
.anadir-buscar input { min-width: 16em; padding: .3em .5em; }
.grupo-partidas { border: 1px solid #D7DCE5; border-radius: 6px; margin-bottom: .5em; }
.grupo-partidas > summary { cursor: pointer; padding: .5em .7em; background: #F4F6FA; }
.grupo-partidas[open] > summary { border-bottom: 1px solid #D7DCE5; }
.boton-activo { background: #16264D; color: #fff; }

/* 🔍 BUSCAR LA EMPRESA A LA QUE PEDIR PRECIO, y elegir a QUIEN de dentro (2026-09-02). */
.lic-buscar-empresa input { min-width: 20em; padding: .3em .5em; }
.lic-a-quien { color: #5b6472; margin-left: .5em; }
.lic-puesto { color: #1E3A6E; }
/* Las personas van SANGRADAS bajo su empresa: sin eso, con 20 empresas con contactos la lista
   se lee como si fueran 68 empresas. */
.lic-contactos { margin: 0 0 .5em 2em; padding-left: .7em; border-left: 2px solid #D7DCE5; }
.lic-contacto-uno { display: block; padding: .1em 0; }

/* 🎨 LOS BOTONES DEL PIE DE LA COMPARATIVA (2026-09-02): iconos sin texto y EN LINEA, con el
   motivo del descarte a su izquierda. Con cuatro empresas, «⭐ Elegir esta» y «🚫 Descartar»
   escritos ocupaban dos lineas por columna y empujaban la tabla a lo ancho. */
.comp-descartar input { width: 8em; font-size: .85em; padding: .15em .3em; }
.boton-icono-accion { cursor: pointer; border: 1px solid #D7DCE5; border-radius: 5px;
                      background: #fff; padding: .2em .45em; font-size: 1em; line-height: 1; }
.boton-icono-accion:hover { border-color: #16264D; }
.boton-icono-accion.boton-primario { background: #16264D; color: #fff; border-color: #16264D; }
.boton-icono-accion.boton-peligro { border-color: #EF4444; }

/* 🔴 EL CARTEL DE «PRECIOS CAMBIADOS A MANO» (2026-09-02). Ambar, no rojo: no esta roto ni es
   un error -- es trabajo a medias esperando el papel. El rojo de esta casa significa «para». */
.comp-sin-papel { border: 1px solid #F59E0B; background: #FFFBEB; border-radius: 5px;
                  padding: .35em .5em; margin: .3em 0; text-align: left; max-width: 15em; }

/* 🗑️ LA BARRA DE «QUITAR LAS MARCADAS» (2026-09-02). Va arriba Y abajo de la comparativa: con
   293 filas, una que solo este arriba obliga a subir al principio despues de marcar la ultima. */
.lic-barra-marcadas { display: flex; align-items: center; gap: .9em; flex-wrap: wrap;
                      padding: .4em .6em; margin: .4em 0;
                      background: #F4F6FA; border: 1px solid #D7DCE5; border-radius: 6px; }
.lic-barra-marcadas kbd { background: #fff; border: 1px solid #D7DCE5; border-radius: 3px;
                          padding: 0 .3em; font-size: .9em; }
.lic-col-marca { width: 1.8em; text-align: center; }
.lic-sin-papel { color: #B45309; }

/* 🔍 La lista de empresas al apuntar una oferta: con la caja vacia no sale nadie, asi que solo
   ocupa cuando se busca. El tope de alto evita que 357 filas empujen el formulario. */
.lic-lista-empresas { max-height: 16em; overflow-y: auto; }
.lic-lista-empresas:empty { display: none; }

/* 💰 El signo del margen de compra en la tabla de lo adjudicado: comprar por debajo del objetivo
   es bueno y por encima es malo, y en una tabla de once columnas el signo se pierde. */
.sub-margen-bien { color: #10B981; }
.sub-margen-mal { color: #EF4444; }

/* ➕ La partida nueva del contrato de subcontrata: los dos destinos, uno debajo del otro y con
   su explicacion al lado. Puestos en linea se leen como dos etiquetas y se elige la primera. */
.sub-partida-nueva { margin: .8rem 0; }
.sub-quien-paga { border: 1px solid #D7DCE5; border-radius: 6px; padding: .6em .8em;
                  margin: .6em 0; }
.sub-quien-paga legend { font-weight: 700; padding: 0 .4em; }
.sub-quien-paga > label { display: block; margin: .35em 0; }
.sub-quien-paga small { display: block; margin-left: 1.6em; }

/* 🪜 LOS DOS PASOS de adjudicar: pactar y sacar los papeles, luego adjuntar el firmado. */
.lic-pasos { display: flex; gap: .5rem; list-style: none; padding: 0; margin: .6rem 0 1rem;
             flex-wrap: wrap; counter-reset: paso; }
.lic-pasos li { counter-increment: paso; padding: .35em .7em; border-radius: 999px;
                background: #F4F6FA; border: 1px solid #D7DCE5; font-size: .9em; color: #64748B; }
.lic-pasos li::before { content: counter(paso) ". "; font-weight: 700; }
.lic-paso-ahora { background: #16264D !important; color: #fff !important;
                  border-color: #16264D !important; }

/* 📎 El formulario de justificar, DENTRO del cartel que dice que falta el papel. */
.comp-justificar { margin-top: .35em; display: flex; flex-direction: column; gap: .25em; }
.comp-justificar input[type="file"] { font-size: .8em; max-width: 100%; }
.comp-justificar input[type="text"] { font-size: .85em; padding: .15em .3em; }
.comp-caro { color: #B45309; }
/* ⚠️ La rechazada se APAGA, no se esconde: comparar es ver por que se descarto una. */
.tabla-comparativa th.comp-rechazada { opacity: .55; }
.comp-descuadre { color: #B45309; white-space: normal; }

/* 🧩 EL ESTADO DE CADA CELDA (Diego, 2026-08-29 · punto 2b).
   ⚠⚠ POR CLASE Y NO CON `style=` EN CADA `<td>`: son 1.172 celdas con la obra real. Un
   estilo en linea por celda es peso muerto en la pagina Y deja el color fuera del CSS, o sea
   fuera de donde se cambia el dia que Diego pida otro.
   ⚠ El fondo va MUY suave a proposito: encima se pinta `comp-mejor`, y dos fondos fuertes
   peleando dejarian ilegible justo la celda que hay que mirar. */
.tabla-comparativa td.comp-estado-pendiente   { background: #F8FAFC; }
.tabla-comparativa td.comp-estado-confirmada { background: #ECFDF5; }
.tabla-comparativa td.comp-estado-rechazada  { background: #FEF2F2; opacity: .75; }
/* ⚠ UNA RECHAZADA CON PRECIO SE TACHA PERO SE LEE. Con tres estados, «rechazada» es tambien
   la oferta que descartamos NOSOTROS, y su precio es informacion: «comparar es ver POR QUE se
   descarto una». Lo que no se ensena nunca es el 0 de una celda SIN precio, y de eso se
   encarga `CeldaComparativa.tiene_precio()`, no el CSS. */
.tabla-comparativa td.comp-estado-rechazada strong { text-decoration: line-through; }
.comp-no-puede { color: var(--adei-rojo, #EF4444); text-decoration: none; }
.comp-marca-confirmada { color: #047857; font-weight: 700; }
.comp-marca-rechazada { color: var(--adei-rojo, #EF4444); font-weight: 700; }

/* El filtro por estado. ⚠ Oculta FILAS, nunca celdas: ver `comparativa_filtro.js`. */
.comp-filtros {
  display: flex; flex-wrap: wrap; gap: .75rem; align-items: center;
  margin: .5rem 0 .75rem; padding: .5rem .75rem;
  background: var(--adei-fondo-claro, #F4F6FA); border-radius: 6px;
}
.comp-filtros label { display: inline-flex; align-items: center; gap: .25rem; font-size: 13px; }
.comp-cuantas { margin-left: auto; }
/* La accion de descartar, en el pie de su columna. */
/* 🎨 UNA SOLA `.comp-accion` (2026-09-02). Se escribió una segunda para los iconos del pie y
   una red de la casa la cazó: dos reglas con el mismo nombre las FUNDE el navegador, y así se
   aplastó el checklist entero con la bolita del tablero. Es la misma zona, así que se unifica en
   vez de renombrar — `inline-flex` y `align-items` entran aquí. */
.comp-accion { display: inline-flex; align-items: center; flex-wrap: wrap; gap: .25rem;
               margin: .4rem .15em 0;
               justify-content: flex-end; }
/* ⚠ Una partida cotizada cuyas celdas se han caido TODAS: no es «nadie la cotizo», es que
   hay que volver a licitarla. Se dice distinto porque se arregla distinto. */
.tabla-comparativa tr.comp-sin-nadie > td:first-child { border-left: 3px solid #EF4444; }

/* 🏢 LO QUE ESA EMPRESA NOS COBRO ANTES (Diego, 2026-08-29 · paso 3).
   ⚠️ APAGADO A PROPOSITO: es contexto, no la oferta. El numero con el que se decide es el de
   arriba; si este pesara lo mismo, la celda tendria dos precios y ninguno mandaria. */
.comp-suyo { color: #1E3A6E; opacity: .75; cursor: help; }

/* ☑️ El aviso de que una marca NO se ha guardado (2026-08-29). Rojo de la casa: no es un
   detalle de estilo, es que la pantalla esta diciendo algo distinto de lo que hay en la base. */
.aviso-marcas { color: #EF4444; font-weight: 600; margin-left: .5rem; }

/* ══ 🧾 LAS CERTIFICACIONES QUE PAGA UNA FACTURA DE PROVEEDOR (2026-09-04) ═══════════════
   Casillas y no un desplegable: una factura puede recoger DOS certificaciones cerradas.

   ⚠️ EL NOMBRE ES NUEVO A PROPÓSITO. `.campo` y `.casilla` ya las usan media docena de
   pantallas, y en esta casa ya han salido tres sustos de un nombre reutilizado en una
   tarde — el peor, una regla sin acotar que iba a convertir en `flex` las celdas de LA
   pantalla del dinero. */
.casilla-periodo {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 4px 0;
  font-weight: normal;
}
.casilla-periodo input[type="checkbox"] { flex: none; margin: 0; }
.casilla-periodo span { flex: 1; }

/* La certificación que ya paga otra factura: se ve, pero no se puede volver a marcar. */
.casilla-ocupada { opacity: 0.62; }
.casilla-ocupada strong { color: #1E3A6E; }

/* 📂 LAS CERTIFICACIONES YA FACTURADAS, PLEGADAS (2026-09-04). Diego: «que salgan primero las
   que quedan abiertas y las que salgan ya pagadas o cerradas en desplegable».
   ⚠️ `<details>` nativo: sin JS, funciona con el JS apagado. */
.periodos-pagados { margin: 6px 0 2px; }
.periodos-pagados > summary {
  cursor: pointer;
  color: #1E3A6E;
  font-size: .92em;
  padding: 3px 0;
}
.periodos-pagados > summary:hover { text-decoration: underline; }


/* ── MI JORNADA (fase 6) ─────────────────────────────────────────────────────────────────
   Tres clases, y el prefijo `jor-` no es capricho: `.tr-beneficio` / `.tr-rojo` viven DENTRO
   de `.tarjeta-resumen .tr-valor` y no pintan nada fuera de una tarjeta, asi que reutilizarlas
   en una celda de tabla habria dejado el texto del color de siempre **sin que nada fallara**
   -- exactamente el fallo de `.tabla-certificacion .sep` del 03/09, que llevaba desde que
   nacio la pantalla. Se comprobo antes de escribir esto.

   ⚠️ `.jor-mal` se usa para «sin cerrar», que NO es un error: es un dato que falta. Va en rojo
   porque en un parte de horas un hueco es justo lo que hay que ir a arreglar. */
.jor-bien { color: var(--adei-verde, #10B981); font-weight: 700; }
.jor-mal  { color: var(--adei-rojo,  #EF4444); font-weight: 700; }
.jor-incidencia { margin-bottom: 4px; }
.jor-incidencia + .jor-incidencia { border-top: 1px solid #e3e9f2; padding-top: 4px; }
