:root {
  --ipsos-azul: #121b5a;
  --ipsos-azul-2: #2f469c;
  --ipsos-teal: #14a19e;
  --ipsos-teal-claro: #1dafad;
  --ipsos-oscuro: #001127;
  --gris-fondo: #f4f5fa;
  --gris-borde: #dfe2ee;
}

/* Tamaño base más grande: con esto, todos los textos que usan rem en toda
   la app (labels, inputs, tablas, notas chiquitas) crecen proporcionalmente,
   sin tener que tocar cada archivo uno por uno. */
html { font-size: 18px; }

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: 'Barlow', 'Roboto', 'Noto Sans', Arial, Helvetica, sans-serif;
  font-weight: 400;
  line-height: 1.55;
  background: var(--gris-fondo);
  color: #1c1f2e;
}

.topbar {
  background: var(--ipsos-azul);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1.5rem;
  /* Menú fijo arriba: queda siempre a la vista al hacer scroll en pantallas
     largas (Grilla CLT, Tarifas de Ballpark, etc.), en vez de desaparecer. */
  position: sticky;
  top: 0;
  z-index: 100;
  box-shadow: 0 2px 6px rgba(0,0,0,0.15);
}
.topbar .marca { display: flex; align-items: center; gap: 0.6rem; font-weight: 700; font-size: 1.15rem; }
.topbar .marca img { height: 25px; }
.topbar nav a { color: #fff; text-decoration: none; margin-left: 1.4rem; font-size: 1rem; font-weight: 500; }
.topbar nav a:hover { color: var(--ipsos-teal-claro); }

/* Nombre del usuario más chico y el botón "Salir" en rojo, para que se
   distinga a simple vista del resto de los links del menú. */
.topbar .nombre-usuario { color: #fff; font-size: 0.75rem; opacity: 0.85; margin-left: 1.4rem; }
.topbar .btn-salir {
  background: #c0392b;
  color: #fff;
  padding: 0.35rem 0.9rem;
  border-radius: 6px;
  margin-left: 0.6rem;
  font-weight: 600;
}
.topbar .btn-salir:hover { background: #a3291b; color: #fff; }

/* Botones "Cerrar" de los modales (Simulador de OP/Precio, Summary PL) —
   mismo rojo que "Salir" del menú, para que se reconozcan como la forma
   de salir/cerrar en toda la app. */
.btn-cerrar {
  background: #c0392b;
  color: #fff;
  border: none;
  border-radius: 6px;
  font-weight: 600;
  cursor: pointer;
}
.btn-cerrar:hover { background: #a3291b; }

/* Botón "Exportar a Excel" del modal Summary PL — verde, como el ícono de
   Excel, para que se distinga de un vistazo del resto de las acciones. */
.btn-excel {
  background: #1e7145;
  color: #fff;
  border: none;
  border-radius: 6px;
  font-weight: 600;
  cursor: pointer;
}
.btn-excel:hover { background: #175c37; }

/* Botones "Editar solicitud"/"Eliminar solicitud" del Detalle del Job
   (2026-09-20, pedido de Javier: que se vean "más profesionales y
   visuales") — ícono + texto, con la misma paleta que ya usa el resto de
   la app para acciones normales/de riesgo (azul institucional para Editar,
   rojo suave para Eliminar, igual que ".btn-peligro" en otras pantallas),
   pero con más presencia: sombra suave, borde más definido y una leve
   reacción al pasar el mouse/hacer click. */
.acciones-job-cabecera { display: flex; gap: 0.7rem; flex-shrink: 0; }
.acciones-job-cabecera .btn-accion {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.6rem 1.15rem;
  border-radius: 7px;
  font-family: inherit;
  line-height: 1.2;
  font-weight: 600;
  font-size: 0.92rem;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  border: 1.5px solid transparent;
  box-shadow: 0 1px 2px rgba(18, 27, 90, 0.1);
  transition: background 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease, transform 0.05s ease;
}
.acciones-job-cabecera .btn-accion svg { width: 1.05rem; height: 1.05rem; flex-shrink: 0; }
.acciones-job-cabecera .btn-accion:hover { box-shadow: 0 3px 8px rgba(18, 27, 90, 0.18); transform: translateY(-1px); }
.acciones-job-cabecera .btn-accion:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(18, 27, 90, 0.1); }
.acciones-job-cabecera .btn-editar { background: #fff; color: var(--ipsos-azul-2); border-color: var(--ipsos-azul-2); }
.acciones-job-cabecera .btn-editar:hover { background: var(--ipsos-azul-2); color: #fff; }
.acciones-job-cabecera .btn-eliminar { background: #fff; color: #a3221b; border-color: #e8938a; }
.acciones-job-cabecera .btn-eliminar:hover { background: #c0392b; color: #fff; border-color: #c0392b; }

.contenido { padding: 1.5rem; max-width: 1100px; margin: 0 auto; }
/* Pantallas con tablas anchas (muchas columnas numéricas, como Tarifas de
   Ballpark) piden más espacio que el resto de la app — layout_top($titulo, true).
   2026-09-28, pedido de Javier: en vez de un ancho fijo (antes 1600px), usar
   95% del ancho de la ventana — así la Bandeja de Operaciones (y el resto de
   las pantallas "anchas": Mis solicitudes, Tarifas de Ballpark, Clientes,
   Usuarios) aprovechan mejor una pantalla grande, y se siguen adaptando en
   una más chica en vez de quedar recortadas a 1600px fijos. */
.contenido.contenido-ancho { max-width: 95vw; }

h1, h2, h3 { color: var(--ipsos-azul); }

.tarjeta {
  background: #fff;
  border: 1px solid var(--gris-borde);
  border-radius: 10px;
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.25rem;
}

.centro-pantalla {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ipsos-oscuro);
}
.tarjeta-login {
  background: #fff;
  border-radius: 12px;
  padding: 2rem 2.2rem;
  width: 100%;
  max-width: 400px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.25);
}

label { display: block; font-size: 0.95rem; font-weight: 500; margin: 0.9rem 0 0.3rem; color: #333; }
input, select, textarea {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--gris-borde);
  border-radius: 6px;
  font-size: 1.05rem;
  font-family: inherit;
  color: #1c1f2e;
}
textarea { resize: vertical; }

/* Campos que se muestran como porcentaje (IIBB, Margen operativo objetivo,
   % extra de Observadores en "Tarifas de Ballpark"): se ven más claros con
   un "%" pegado al campo que como fracción con varios decimales. */
.input-pct { position: relative; }
.input-pct input { padding-right: 2rem; }
.input-pct span {
  position: absolute;
  right: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  color: #999;
  pointer-events: none;
}

/* Celdas "amarillas" del modal Summary PL / PL Ops (Detalle del Job) y del
   Simulador de OP/Precio (Grilla CLT) — mismo color que el Excel original
   para las celdas que se completan a mano. */
.pl-yellow { background: #fffbe0; font-weight: 600; }

/* Modal "Summary PL" (Detalle del Job): letra más chica que el resto de la
   app y más ancho de ventana, para que entren cómodas las dos tablas
   (Summary PL / PL Ops) lado a lado sin tener que hacer scroll horizontal. */
.modal-summary-pl { max-width: 90vw; }
.tabla-compacta th, .tabla-compacta td { padding: 0.35rem 0.5rem; font-size: 0.82rem; }
.tabla-compacta input[type="number"] { font-size: 0.82rem; padding: 0.25rem 0.4rem; width: 100%; box-sizing: border-box; }

/* Detalle del Job (jobs_detalle.php) más compacto — Service Line pidió que
   la pantalla que se abre desde "Mis solicitudes → Ver" se vea menos
   espaciada, con menos scroll, sin tener que abrir varias pantallas para
   ver una sola solicitud. Escapado a .pagina-compacta (sólo esta pantalla
   por ahora) para no tocar el resto de la app (Tarifas, Grilla CLT, etc.),
   que siguen con la letra/padding normal. */
.pagina-compacta .tarjeta { padding: 0.85rem 1.1rem; margin-bottom: 0.85rem; }
.pagina-compacta h2 { margin: 0 0 0.6rem; font-size: 1.3rem; }
.pagina-compacta h3 { margin: 0 0 0.5rem; font-size: 1.1rem; }
.pagina-compacta h4 { margin: 0.6rem 0 0.4rem; font-size: 1rem; }
.pagina-compacta p { margin: 0.4rem 0; }
.pagina-compacta table th,
.pagina-compacta table td { padding: 0.3rem 0.55rem; font-size: 0.88rem; }
.pagina-compacta details table th,
.pagina-compacta details table td { padding: 0.25rem 0.5rem; font-size: 0.84rem; }
.pagina-compacta .badge { font-size: 0.8rem; }

/* Campos de cada línea (jobs_detalle.php) en dos columnas — Javier pidió
   probar que entre más información en una sola pantalla. CSS multi-columna:
   reparte las filas solas entre las dos columnas (llena la primera, sigue
   en la segunda), sin tener que calcular a mano cuántas van en cada una.
   break-inside:avoid evita que una fila se corte a la mitad entre columnas.
   El desglose del Ballpark (que tiene su propia tabla adentro) usa
   column-span:all para ocupar el ancho completo en vez de achicarse a media
   columna. */
.pagina-compacta .campos-2col { column-count: 2; column-gap: 2.2rem; margin: 0.3rem 0 0.6rem; }
.pagina-compacta .campo-fila { display: flex; gap: 0.6rem; break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 0.28rem 0.4rem; border-bottom: 1px solid #eee; font-size: 0.85rem; align-items: baseline; }
.pagina-compacta .campo-fila .campo-label { flex: 0 0 44%; color: #666; }
.pagina-compacta .campo-fila .campo-valor { flex: 1; min-width: 0; }
.pagina-compacta .campo-fila.destacado { font-weight: 600; }
.pagina-compacta .campo-fila.span-completo { column-span: all; display: block; border-bottom: none; padding-top: 0.5rem; }
/* Filas cebra — mismo criterio que ya se usa en Bandeja de Operaciones/Mis
   solicitudes (fondo alternado cada dos filas). Se excluye .span-completo
   (el desglose del Ballpark) porque ocupa todo el ancho y ya tiene su
   propio estilo. */
.pagina-compacta .campo-fila:nth-of-type(even):not(.span-completo) { background: #fafbfd; }

/* Detalle del Job (jobs_detalle.php) 20% más ancho — Javier pidió que se
   vea más grande. El ancho normal de la app (.contenido) es 1100px; acá se
   usan 1320px (1100 × 1.2). Se engancha con :has() al wrapper
   .pagina-compacta que ya identifica sólo esta pantalla, así no hace falta
   tocar layout_top()/.contenido-ancho (1600px), que usan otras pantallas
   (Bandeja de Operaciones, Mis solicitudes, Tarifas de Ballpark, Clientes)
   con un ancho distinto. */
.contenido:has(> .pagina-compacta) { max-width: 1320px; }

.btn-primario {
  margin-top: 1.3rem;
  width: 100%;
  background: var(--ipsos-teal);
  color: #fff;
  border: none;
  border-radius: 6px;
  padding: 0.7rem 1rem;
  font-size: 1.05rem;
  font-weight: 600;
  cursor: pointer;
}
.btn-primario:hover { background: var(--ipsos-teal-claro); }
.btn-secundario {
  background: #fff;
  color: var(--ipsos-azul-2);
  border: 1px solid var(--ipsos-azul-2);
  border-radius: 6px;
  padding: 0.55rem 0.95rem;
  cursor: pointer;
  font-size: 1rem;
  font-weight: 500;
}

table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 0.6rem 0.65rem; border-bottom: 1px solid var(--gris-borde); font-size: 1rem; }
th { color: var(--ipsos-azul); font-weight: 600; }

/* Bandeja de Operaciones: con la columna "Enviado el" quedaba muy apretada
   (8 columnas en el mismo padding chico de las tablas de detalle) — más
   padding en filas y encabezado, cebra y resaltado al pasar el mouse, igual
   que se hizo antes con la tabla de Tarifas de Ballpark. */
.tabla-bandeja th, .tabla-bandeja td { padding: 1rem 1.1rem; }
.tabla-bandeja thead tr { background: var(--gris-fondo); }
.tabla-bandeja tbody tr:nth-child(even) { background: #fafbfd; }
.tabla-bandeja tbody tr:hover { background: #eef1fa; }

/* Mis solicitudes: Javier pidió filas más bajas para que entren más jobs por
   pantalla (al menos un 20% más bajas). Se escapa a .pagina-mis-solicitudes
   (sólo esta pantalla) para no achicar también la Bandeja de Operaciones, que
   usa la misma clase .tabla-bandeja con el padding grande de siempre. */
.pagina-mis-solicitudes .tabla-bandeja th,
.pagina-mis-solicitudes .tabla-bandeja td { padding: 0.5rem 1.1rem; }

.badge {
  display: inline-block;
  background: var(--gris-fondo);
  border: 1px solid var(--gris-borde);
  color: var(--ipsos-azul-2);
  border-radius: 20px;
  padding: 0.2rem 0.75rem;
  font-size: 0.88rem;
  font-weight: 500;
}
.badge.final { background: var(--ipsos-teal); color: #fff; border-color: var(--ipsos-teal); }

/* Colores por estado de la columna/etiqueta "Estado" (cotizaciones.estado) —
   pedido de Javier (2026-09-20), para distinguir de un vistazo en qué punto
   está cada solicitud, en las tres pantallas donde se muestra (Detalle del
   Job, Bandeja de Operaciones, Mis solicitudes). Los estados sin color
   definido acá (borrador, lista_para_revision) se quedan con el gris neutro
   de siempre. */
.badge.estado-enviada { background: #fff1e0; color: #b56404; border-color: #f3cd97; }
.badge.estado-cancelada { background: #fdecea; color: #a3221b; border-color: #f5c2bd; }
.badge.estado-en_costeo { background: var(--ipsos-azul); color: #ffe066; border-color: var(--ipsos-azul); }
.badge.estado-aprobada { background: #e6f6ea; color: #1c7430; border-color: #b8e6c3; }
/* Faltaba 'lista_para_revision' acá (2026-09-28, al armar el tablero
   Kanban) — se agrega con la misma familia teal que ya usa el resto de la
   marca, distinta de las otras cuatro. */
.badge.estado-lista_para_revision { background: #e6f7f6; color: #0f766e; border-color: #b7e5e1; }

/* Panel "Revisá la cotización" del Detalle del Job (2026-10-14, pedido de
   Javier: circuito de revisión de la Service Line — ver includes/revision.php).
   Mismo teal que el badge de "Lista para revisión"; el de "Cambios pedidos"
   usa el naranja de "Enviada" para que Operaciones lo note. */
.tarjeta-revision { border-left: 4px solid #0f766e; background: #f4fbfa; }
.tarjeta-revision.tarjeta-cambios { border-left-color: #b56404; background: #fffaf2; }
.acciones-revision { display: flex; gap: 0.75rem; align-items: flex-start; flex-wrap: wrap; }
.acciones-revision .btn-primario { width: auto; margin: 0; }
.pedir-cambios { flex: 1 1 18rem; }
.pedir-cambios > summary { list-style: none; display: inline-block; cursor: pointer; margin: 0; }
.pedir-cambios > summary::-webkit-details-marker { display: none; }
.pedir-cambios[open] > summary { margin-bottom: 0.6rem; }
.pedir-cambios textarea { width: 100%; }
/* Aviso de las Grillas cuando la versión final está en revisión o aprobada y
   no se puede "Calcular y guardar" (ver revision_motivo_bloqueo()). */
.aviso-bloqueo-revision {
  border-left: 4px solid #0f766e; background: #f4fbfa; color: #134e4a;
  padding: 0.75rem 1rem; border-radius: 6px; margin-bottom: 1rem;
}
.btn-primario:disabled { opacity: 0.5; cursor: not-allowed; }

/* ============ Tableros Kanban (Bandeja de Operaciones / Mis solicitudes) ============
   2026-09-28, pedido de Javier: reemplazar las tablas de ambas pantallas por
   un tablero estilo Kanban (Opción 2 de 3 mockups que revisó y eligió) — una
   columna por Service Line en la Bandeja de Operaciones, o por estado en Mis
   solicitudes (una sola Service Line no tiene sentido agrupada por Service
   Line — ver comentario en solicitudes_mias.php). Comparten estas clases. */
.barra-kanban {
  background: var(--ipsos-azul);
  color: #fff;
  border-radius: 10px;
  padding: 0.7rem 1.1rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}
.barra-kanban h2 { color: #fff; margin: 0; font-size: 1.1rem; white-space: nowrap; }
/* 2026-09-28, pedido de Javier: achicar el buscador y los chips de estado
   para que entren todos en una sola fila junto con el título y la pastilla
   de rol — antes, con textos como "Lista para revisión", se pasaban a una
   segunda línea con más facilidad de lo que hacía falta. El buscador puede
   encogerse hasta 6rem (flex-shrink) antes de que el resto de la fila se
   vaya a una segunda línea. */
.barra-kanban input[type="text"] {
  width: 10rem;
  min-width: 6rem;
  flex-shrink: 1;
  border: none;
  border-radius: 20px;
  padding: 0.3rem 0.7rem;
  font-size: 0.8rem;
}
/* 2026-09-28, pedido de Javier: filtros por Mes y por Cliente en "Mis
   solicitudes" (primer <select> que usa esta barra) — mismo criterio de
   achicar que el resto de la barra: ancho tope chico y texto truncado con
   "…" para que una opción larga (un mes con año, o un cliente con nombre
   largo) no rompa la fila de una sola línea que ya se había logrado antes. */
.barra-kanban select {
  width: auto;
  max-width: 8.5rem;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 1;
  border: none;
  border-radius: 20px;
  padding: 0.3rem 0.7rem;
  font-size: 0.8rem;
}
.barra-kanban .contador-kanban { color: #c7cdf0; font-size: 0.72rem; white-space: nowrap; }
.barra-kanban .pastilla-rol {
  background: rgba(255,255,255,0.22);
  color: #fff;
  border-radius: 20px;
  padding: 0.2rem 0.6rem;
  font-size: 0.72rem;
  font-weight: 700;
  white-space: nowrap;
}
.barra-kanban .relleno { flex: 1; }

/* Variante teal de la barra superior — usada para el título "Tarifas de
   Ballpark — IUU" (2026-09-28, pedido de Javier: "envolvé el título con el
   color verde, como los items que existen dentro de Tarifas de Ballpark —
   IUU"), para que quede igual de envuelto que el título principal de la
   página, pero con el mismo teal que ya usan las tarjetas de esa sección. */
.barra-kanban.barra-kanban-iuu { background: var(--ipsos-teal); }

.chips-estado { display: flex; gap: 0.3rem; flex-wrap: wrap; }
.chip-estado {
  border: none;
  background: rgba(255,255,255,0.16);
  color: #fff;
  border-radius: 20px;
  padding: 0.25rem 0.6rem;
  font-size: 0.76rem;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
}
.chip-estado.activo { background: #fff; color: var(--ipsos-azul); }

/* 2026-09-28, pedido de Javier: achicar un poco cada columna para que las 6
   Service Lines de la Bandeja de Operaciones (CEX/Health/MSU/INNO/CHP/OP)
   entren en una sola pantalla sin que la última (OP) quede afuera de la
   ventana — antes cada columna medía 17.5rem (315px), y 6 columnas + 5
   espacios no entraban ni en el ancho máximo de la página (1600px). Bajado
   a 13.5rem (243px) de columna y 0.65rem de espacio entre columnas: 6
   columnas completas entran en ~1526px, con margen incluso en notebooks de
   pantalla más chica. Comparte clase con "Mis solicitudes" (agrupada por
   estado, 5 columnas) — ahí este cambio sólo la deja más compacta, no
   rompe nada. Si la ventana es más angosta todavía, .tablero-kanban sigue
   teniendo scroll horizontal como respaldo.

   2026-09-28 (segundo ajuste, mismo día): las columnas tenían un ancho FIJO
   (13.5rem) y no se estiraban, así que con la barra superior ahora al 95%
   del ancho de la ventana (ver .contenido-ancho), quedaba un espacio vacío
   a la derecha de la última columna en vez de llegar hasta el borde de la
   barra, como pidió Javier. "flex: 1 1 13.5rem" hace que las columnas
   crezcan parejas para ocupar todo el ancho disponible (13.5rem queda como
   mínimo, no como tamaño fijo); max-width evita que en un monitor
   gigante cada columna quede absurdamente ancha. */
/* 2026-09-28 (tercer ajuste, mismo día): pedido de Javier de que las
   columnas queden todas con la misma altura, en vez de que cada una se
   achique o se agrande según cuántas tarjetas tenga adentro. "align-items:
   flex-start" (el valor de antes) hacía justamente lo contrario: cada
   columna tomaba su propia altura de contenido. Cambiado a "stretch" (el
   valor por defecto de flexbox, escrito explícito para que quede claro):
   ahora todas las columnas de una fila toman la altura de la más alta.
   Para que esa altura pareja se note también visualmente (no sólo el marco
   blanco, sino el espacio de "Sin solicitudes" ocupando el resto), la
   columna pasa a ser ella misma un flex column y el cuerpo crece con
   flex:1 para rellenar lo que le sobra debajo de las tarjetas. */
.tablero-kanban { display: flex; gap: 0.65rem; overflow-x: auto; padding-bottom: 0.5rem; align-items: stretch; }
.columna-kanban {
  flex: 1 1 13.5rem;
  min-width: 13.5rem;
  max-width: 22rem;
  background: #fff;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 6px rgba(18,27,90,0.08);
  display: flex;
  flex-direction: column;
}
.columna-kanban-header {
  padding: 0.7rem 0.75rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: #fff;
  font-weight: 700;
  font-size: 0.88rem;
  flex-shrink: 0;
}
.columna-kanban-contador {
  background: rgba(255,255,255,0.28);
  border-radius: 12px;
  padding: 0.1rem 0.55rem;
  font-size: 0.76rem;
}
.columna-kanban-cuerpo {
  padding: 0.55rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-height: 65vh;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}
.columna-kanban-vacio, .columna-kanban-sin-resultados { font-size: 0.8rem; color: #aaa; padding: 0.4rem 0.2rem; }
.columna-kanban-sin-resultados { display: none; }

/* 2026-09-28 (pedido de Javier): las tarjetas dentro de una columna quedaban
   con distinta altura según cuánto contenido tuvieran (Cliente, la
   herramienta, botones de admin), así que el borde gris de cada una se
   notaba "cortado" en un lugar distinto — un JS en cada pantalla Kanban
   (`igualarAlturaTarjetasKanban()`) mide la tarjeta más alta y fija esa
   altura en todas por igual. "flex-shrink: 0" es necesario para que esa
   altura fija se respete de verdad: sin esto, en una columna con muchas
   tarjetas (que ya de por sí puede superar el límite de `max-height: 65vh`
   de `.columna-kanban-cuerpo`), flexbox achicaba las tarjetas para que
   entraran todas — rompiendo la igualación recién hecha con JS. Con
   flex-shrink:0, las tarjetas mantienen su altura fija y, si no entran
   todas, la columna simplemente scrollea (como ya hacía antes). */
.tarjeta-kanban {
  background: #fff;
  border: 1px solid var(--gris-borde);
  border-radius: 10px;
  padding: 0.7rem 0.8rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  box-shadow: 0 1px 3px rgba(18,27,90,0.06);
  flex-shrink: 0;
}
.tarjeta-kanban.oculta { display: none; }
.tarjeta-kanban-top { display: flex; justify-content: space-between; align-items: center; gap: 0.4rem; }
.tarjeta-kanban-job { font-weight: 700; color: var(--ipsos-azul); font-size: 0.85rem; text-decoration: none; }
.tarjeta-kanban-job:hover { text-decoration: underline; }
.tarjeta-kanban .badge { font-size: 0.68rem; padding: 0.08rem 0.55rem; }
.tarjeta-kanban-nombre { font-weight: 600; font-size: 0.88rem; line-height: 1.3; }
.tarjeta-kanban-cliente { font-size: 0.8rem; color: #777; }
.tarjeta-kanban-owner { display: flex; align-items: center; gap: 0.45rem; }
.tarjeta-kanban-owner-nombre { font-size: 0.78rem; color: #555; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tarjeta-kanban-fecha { font-size: 0.72rem; color: #999; white-space: nowrap; }
.tarjeta-kanban-solicitante { font-size: 0.72rem; color: #999; }
/* 2026-09-28 (pedido de Javier): en la Bandeja de Operaciones todos los
   usuarios de Operaciones/Admin ven TODAS las solicitudes (a diferencia de
   Service Line, donde cada uno ve sólo las propias) — así que hace falta
   mostrar quién de Operaciones está cotizando cada Job, para que no se
   pisen el trabajo sin saberlo entre varias personas. Gris neutro a
   propósito (a diferencia del avatar de "Owner", que usa el color de la
   Service Line) para que se note de un vistazo que es una persona de
   adentro de Operaciones, no un contacto de la Service Line. Sólo aparece
   una vez que alguien efectivamente abrió y guardó una Grilla — antes de
   eso no hay nadie asignado todavía. */
.tarjeta-kanban-operador { display: flex; align-items: center; gap: 0.45rem; }
.tarjeta-kanban-operador-nombre { font-size: 0.76rem; color: #666; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.avatar-iniciales {
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  color: #fff;
  font-size: 0.62rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.avatar-iniciales-operador { background: #6b7280; }
.tarjeta-kanban-herramienta {
  display: inline-block;
  background: #eef1fa;
  color: var(--ipsos-azul-2);
  border-radius: 5px;
  padding: 0.05rem 0.5rem;
  font-size: 0.7rem;
  font-weight: 600;
}

.tarjeta-kanban-acciones { display: flex; gap: 0.4rem; margin-top: 0.2rem; }
.btn-mini {
  flex: 1;
  text-align: center;
  border-radius: 6px;
  padding: 0.3rem 0;
  font-size: 0.72rem;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
  border: 1px solid var(--gris-borde);
  background: #fff;
}
.btn-mini-editar { color: var(--ipsos-azul-2); border-color: var(--ipsos-azul-2); }
.btn-mini-editar:hover { background: var(--ipsos-azul-2); color: #fff; }
.btn-mini-eliminar { color: #a3221b; border-color: #e8938a; }
.btn-mini-eliminar:hover { background: #c0392b; color: #fff; border-color: #c0392b; }

.error { background: #fdecea; color: #a3221b; border: 1px solid #f5c2bd; border-radius: 6px; padding: 0.65rem 0.85rem; margin-top: 1rem; font-size: 0.98rem; }
.ok { background: #e8f7f3; color: #0d6b5f; border: 1px solid #b9e6db; border-radius: 6px; padding: 0.65rem 0.85rem; margin-top: 1rem; font-size: 0.98rem; }

.linea-solicitud { border: 1px dashed var(--gris-borde); border-radius: 8px; padding: 1rem; margin-bottom: 1rem; position: relative; }
.linea-solicitud .acciones { position: absolute; top: 0.8rem; right: 1rem; display: flex; gap: 0.5rem; }
.fila { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.fila > div { min-width: 0; }

fieldset.bloque-metodologia, div.bloque-metodologia {
  border: 1px dashed var(--gris-borde);
  border-radius: 8px;
  padding: 0.8rem 1rem;
  margin: 0.6rem 0 1rem;
}
fieldset.bloque-metodologia { margin-left: 0; margin-right: 0; }

/* Tablas editables de admin_tarifas.php: cada fila es su propio <form> (no un
   <tr>, porque un <form> no puede envolver una fila de tabla válidamente), así
   que se armaron con CSS grid, prolijas como una tabla real: header con fondo
   propio, filas cebra, resaltado al pasar el mouse, y scroll horizontal (en
   vez de achicar las columnas) cuando no entran todas en el ancho disponible.

   OJO: la cantidad de columnas del grid (grid-template-columns) tiene que
   coincidir exactamente con la cantidad de <div> de cada fila. Si no coinciden,
   el/los últimos <div> se caen a una línea aparte — fue justo el bug que hacía
   que "Guardar"/"Eliminar" apareciera debajo de cada fila en vez de al final,
   en la misma línea (faltaba una columna: había 13 <div> por fila de tarifa
   -Clave, LOI, Incidencia, Metodología, 8 numéricas y Acciones- pero el grid
   sólo definía 12). */
.tabla-scroll { overflow-x: auto; border: 1px solid var(--gris-borde); border-radius: 8px; }
.tabla-scroll .fila-tarifa,
.tabla-scroll .fila-tarifa-header,
.tabla-scroll .fila-tarifa-dp,
.tabla-scroll .fila-tarifa-dp-header,
.tabla-scroll .fila-config-entrega,
.tabla-scroll .fila-config-entrega-header,
.tabla-scroll .fila-usuario,
.tabla-scroll .fila-usuario-header,
.tabla-scroll .fila-cliente,
.tabla-scroll .fila-cliente-header {
  padding-left: 0.85rem;
  padding-right: 0.85rem;
}
.tabla-scroll form:last-of-type { border-bottom: none; }

.fila-tarifa, .fila-tarifa-header {
  display: grid;
  grid-template-columns: 4.5rem 4rem 5rem 7rem repeat(8, minmax(5.5rem, 1fr)) 9rem;
  min-width: 78rem;
  gap: 0.6rem;
  align-items: center;
  padding: 0.65rem 0;
  border-bottom: 1px solid var(--gris-borde);
}
.fila-tarifa-dp, .fila-tarifa-dp-header {
  display: grid;
  grid-template-columns: 11rem 9rem 9rem 9rem;
  min-width: 38rem;
  gap: 0.6rem;
  align-items: center;
  padding: 0.65rem 0;
  border-bottom: 1px solid var(--gris-borde);
}
.fila-usuario, .fila-usuario-header {
  display: grid;
  grid-template-columns: minmax(9rem, 1.1fr) minmax(12rem, 1.4fr) minmax(8.5rem, 0.9fr) minmax(9rem, 0.9fr) minmax(23rem, 1.4fr);
  min-width: 66rem;
  gap: 0.6rem;
  align-items: center;
  padding: 0.65rem 0;
  border-bottom: 1px solid var(--gris-borde);
}
/* Cada celda de nombre/email/rol/Service Line tiene DOS versiones adentro —
   el texto fijo (.campo-vista) y el campo editable (.campo-editar) — y el
   atributo data-modo del <form> (puesto por usuarioModo() en JS) decide cuál
   se ve. Por default (data-modo="ver") se ve el texto; "Editar" cambia a
   data-modo="editar" y ahí se ven los inputs/selects en su lugar; "Resetear
   contraseña" cambia a data-modo="reset", que deja los datos como texto fijo
   pero cambia qué botones se muestran (Confirmar/Cancelar + el campo de
   contraseña, en vez de Editar/Resetear/Bloquear). */
.fila-usuario .campo-editar { display: none; }
.fila-usuario[data-modo="editar"] .campo-vista { display: none; }
.fila-usuario[data-modo="editar"] .campo-editar { display: inline-block; width: 100%; }
.fila-usuario .acciones-editar, .fila-usuario .acciones-reset { display: none; }
.fila-usuario[data-modo="editar"] .acciones-ver,
.fila-usuario[data-modo="reset"] .acciones-ver { display: none; }
.fila-usuario[data-modo="editar"] .acciones-editar { display: flex; }
.fila-usuario[data-modo="reset"] .acciones-reset { display: flex; }
/* Antes decía "flex-wrap: wrap" — con la columna de Acciones angosta, eso
   hacía que "Bloquear" se cayera a una segunda línea debajo de "Editar"/
   "Resetear contraseña", agrandando esa fila y desalineándola de las demás.
   Ahora la columna es lo bastante ancha para los tres botones en una sola
   línea (ver el grid-template-columns de arriba) y esto fuerza que nunca
   más se envuelvan — si la ventana es angosta, .tabla-scroll ya da scroll
   horizontal en vez de romper el alto de la fila. */
.fila-usuario .acciones-tarifa { flex-wrap: nowrap; gap: 0.35rem; }
/* Botones más chicos que el resto de la app (Editar/Resetear contraseña/
   Bloquear/Guardar/Confirmar/Cancelar), para que entren cómodos en una sola
   línea en la columna de Acciones sin necesitar tanto ancho. */
.fila-usuario .acciones-tarifa .btn-secundario { padding: 0.28rem 0.5rem; font-size: 0.72rem; }
.fila-usuario .campo-password-nueva { width: 8rem; flex: 0 0 auto; padding: 0.28rem 0.4rem; font-size: 0.72rem; }

.fila-tarifa-header, .fila-tarifa-dp-header, .fila-config-entrega-header, .fila-usuario-header, .fila-cliente-header {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ipsos-azul);
  background: var(--gris-fondo);
  border-bottom: 2px solid var(--gris-borde);
}
/* Etiquetas como "Supervisión/día" no tienen un espacio donde el navegador
   pueda cortar la línea — sin esto, si la columna es más angosta que la
   palabra completa, el texto se desborda y queda superpuesto con el título
   de la columna vecina en vez de bajar a una segunda línea. */
.fila-tarifa-header > div, .fila-tarifa-dp-header > div, .fila-config-entrega-header > div, .fila-usuario-header > div, .fila-cliente-header > div {
  overflow-wrap: anywhere;
  line-height: 1.25;
}
.fila-tarifa:hover, .fila-tarifa-dp:hover, .fila-config-entrega:hover, .fila-usuario:hover, .fila-cliente:hover { background: var(--gris-fondo); }
.fila-tarifa:nth-of-type(even):not(.fila-tarifa-header),
.fila-tarifa-dp:nth-of-type(even):not(.fila-tarifa-dp-header),
.fila-usuario:nth-of-type(even):not(.fila-usuario-header),
.fila-cliente:nth-of-type(even):not(.fila-cliente-header) { background: #fafaff; }
.fila-tarifa input, .fila-tarifa-dp input, .fila-config-entrega input {
  padding: 0.4rem 0.5rem;
  font-size: 0.92rem;
  margin: 0;
}
.fila-usuario select {
  padding: 0.35rem 0.4rem;
  font-size: 0.9rem;
  margin: 0;
}
.fila-tarifa input[type="number"], .fila-tarifa-dp input[type="number"], .fila-config-entrega input[type="number"] {
  text-align: right;
}
.fila-tarifa code, .fila-tarifa-dp code { font-size: 0.85rem; background: var(--gris-fondo); padding: 0.15rem 0.4rem; border-radius: 4px; }
.fila-usuario .badge { font-size: 0.75rem; padding: 0.1rem 0.55rem; margin-left: 0.4rem; }
.acciones-tarifa { display: flex; gap: 0.5rem; flex-wrap: nowrap; }
.acciones-tarifa .btn-secundario { padding: 0.4rem 0.7rem; font-size: 0.85rem; white-space: nowrap; }
.acciones-tarifa .btn-peligro { color: #a3221b; border-color: #f0aba3; }
.acciones-tarifa .btn-peligro:hover { background: #fdecea; }
.acciones-tarifa .btn-secundario:disabled { opacity: 0.5; cursor: not-allowed; }

.fila-config-entrega, .fila-config-entrega-header {
  display: grid;
  grid-template-columns: 6rem repeat(3, minmax(8rem, 1fr)) 7rem;
  min-width: 40rem;
  gap: 0.6rem;
  align-items: center;
  padding: 0.65rem 0;
  border-bottom: 1px solid var(--gris-borde);
}

.fila-cliente, .fila-cliente-header {
  display: grid;
  grid-template-columns: minmax(9rem, 1.1fr) 4.5rem 5rem 5.5rem 5rem 5.5rem minmax(6rem, 0.7fr) minmax(7rem, 0.8fr) minmax(9rem, 1.1fr) 9rem;
  min-width: 78rem;
  gap: 0.6rem;
  align-items: center;
  padding: 0.65rem 0;
  border-bottom: 1px solid var(--gris-borde);
}
.fila-cliente input, .fila-cliente select, .fila-cliente textarea { padding: 0.4rem 0.5rem; font-size: 0.92rem; margin: 0; }
/* Billing Schedule es de varios renglones (ver admin_clientes.php): se puede agrandar a mano hacia abajo. */
.fila-cliente textarea { resize: vertical; min-height: 2.4rem; }

.fila-config-general {
  display: grid;
  grid-template-columns: repeat(2, minmax(11rem, 1fr)) 7rem;
  gap: 1rem;
  align-items: end;
}
.fila-config-general label { margin: 0 0 0.3rem; }
.fila-config-general input { margin: 0; text-align: right; }

/* ============ Tarjetas acordeón (Tarifas de Ballpark) ============
   2026-09-28, pedido de Javier: "adaptar la página Tarifas de Ballpark a
   este estilo" (el de los tableros Kanban recién armados) — mismo lenguaje
   visual (barra superior azul, tarjetas con sombra y bordes redondeados) y,
   además, reorganizado en tarjetas colapsables por categoría, para que la
   pantalla no se sienta tan abrumadora de entrada (son muchas tablas
   seguidas). Reutiliza <details>/<summary> nativo del navegador — igual
   criterio que ya usaba la sección "Tarifas por concepto" de IUU. */
.tarjeta-acordeon {
  background: #fff;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 6px rgba(18,27,90,0.08);
  margin-bottom: 1.1rem;
}
.tarjeta-acordeon > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.9rem 1.1rem;
  color: #fff;
  background: var(--ipsos-azul);
  font-weight: 700;
  font-size: 1.02rem;
}
/* Las tarjetas de la sección IUU usan el teal de la marca en vez del azul,
   para separar visualmente esa sección (sólo Service Line IUU) del resto
   del Ballpark general — mismo criterio de color que ya usa el resto de la
   app para acentos (botón primario, badge "final"), sin reusar los colores
   de Service Line del Kanban (acá no representan una Service Line puntual). */
.tarjeta-acordeon.acordeon-iuu > summary { background: var(--ipsos-teal); }
.tarjeta-acordeon > summary::-webkit-details-marker { display: none; }
.tarjeta-acordeon > summary::before {
  content: '▸';
  display: inline-block;
  font-size: 0.85rem;
  transition: transform 0.15s ease;
}
.tarjeta-acordeon[open] > summary::before { transform: rotate(90deg); }
.tarjeta-acordeon-meta {
  margin-left: auto;
  background: rgba(255,255,255,0.22);
  border-radius: 20px;
  padding: 0.15rem 0.75rem;
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}
.tarjeta-acordeon-meta.alerta { background: #ffe066; color: var(--ipsos-oscuro); }
.tarjeta-acordeon-cuerpo { padding: 1.1rem 1.25rem 1.25rem; }
.tarjeta-acordeon-cuerpo > p:first-child { margin-top: 0; }

/* Sub-acordeones adentro de una tarjeta (un concepto de IUU adentro de
   "Tarifas por concepto") — más chicos y sin el color de fondo de la
   tarjeta principal, para que se note que están un nivel adentro. */
.tarjeta-acordeon-cuerpo details {
  border: 1px solid var(--gris-borde);
  border-radius: 8px;
  margin-top: 0.6rem;
  overflow: hidden;
}
.tarjeta-acordeon-cuerpo details summary {
  list-style: none;
  cursor: pointer;
  padding: 0.55rem 0.85rem;
  background: var(--gris-fondo);
  font-weight: 600;
  color: var(--ipsos-azul);
}
.tarjeta-acordeon-cuerpo details summary::-webkit-details-marker { display: none; }
.tarjeta-acordeon-cuerpo details summary::before {
  content: '▸ ';
  display: inline-block;
  transition: transform 0.15s ease;
}
.tarjeta-acordeon-cuerpo details[open] summary::before { transform: rotate(90deg); }
.tarjeta-acordeon-cuerpo details[open] summary { border-bottom: 1px solid var(--gris-borde); }
.tarjeta-acordeon-cuerpo details .tabla-scroll { border: none; border-radius: 0; margin: 0.5rem 0.85rem 0.75rem; }

/* Clientes (admin_clientes.php) — mismo pedido de Javier de unificar el
   estilo (2026-09-28): sombra en vez del borde fino que usa .tarjeta
   genérica, igual criterio visual que las columnas del Kanban. */
.tarjeta-clientes {
  background: #fff;
  border-radius: 12px;
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.25rem;
  box-shadow: 0 2px 6px rgba(18,27,90,0.08);
}
.fila-cliente.oculta { display: none; }

/* ===================== Celulares y tablets =====================
   2026-10-14, pedido de Javier: "que la aplicación sea responsiva para
   celulares". Hasta acá todo el CSS era sólo de escritorio (y faltaba el
   <meta name="viewport">, así que un celular mostraba la página de
   escritorio achicada). Todo lo de pantallas chicas vive en este bloque, al
   final, para no tocar cómo se ve en una compu.

   Criterio:
   - Menú: a 900px o menos se colapsa detrás del botón ☰ (.btn-menu, en
     includes/layout.php).
   - A 760px o menos: grillas de campos apiladas (las de 2 columnas pasan a
     1; las de 4, como Precio/GM/OP/IIBB, pasan a 2), menos márgenes, y lo
     que no entra a lo ancho (tablas de muchas columnas) se desplaza de
     costado DENTRO de su tarjeta, nunca la página entera.
   - Muchas pantallas tienen la grilla escrita en el atributo style="" de
     cada <div> (no en una clase), por eso algunas reglas usan selectores de
     atributo con !important — es la única forma de pisar un style="".
     Las filas de tablas de Tarifas (.fila-config-entrega) quedan afuera a
     propósito: son filas de una tabla, siguen siendo filas y se desplazan. */

.btn-menu { display: none; }

@media (max-width: 900px) {
  .topbar { padding: 0.55rem 0.9rem; flex-wrap: wrap; }
  .topbar .marca { font-size: 1rem; }
  .btn-menu {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.6rem; height: 2.4rem; padding: 0; margin-left: auto;
    background: transparent; border: 1px solid rgba(255,255,255,0.35); border-radius: 6px; cursor: pointer;
  }
  /* Ícono ☰ (y ✕ con el menú abierto) dibujado con CSS: no depende de fuentes ni imágenes. */
  .btn-menu span, .btn-menu span::before, .btn-menu span::after {
    display: block; width: 1.2rem; height: 2px; background: #fff; border-radius: 2px; position: relative;
    transition: transform 0.15s ease, background 0.15s ease;
  }
  .btn-menu span::before, .btn-menu span::after { content: ''; position: absolute; left: 0; }
  .btn-menu span::before { top: -6px; }
  .btn-menu span::after { top: 6px; }
  .topbar.menu-abierto .btn-menu span { background: transparent; }
  .topbar.menu-abierto .btn-menu span::before { top: 0; transform: rotate(45deg); }
  .topbar.menu-abierto .btn-menu span::after { top: 0; transform: rotate(-45deg); }

  .topbar nav { display: none; width: 100%; flex-direction: column; padding: 0.4rem 0 0.2rem; }
  .topbar.menu-abierto nav { display: flex; }

  /* Tablets: las columnas del Kanban bajan de fila en vez de quedar
     escondidas a la derecha (en pantallas táctiles la barra de scroll
     horizontal casi no se ve). En escritorio sigue el scroll horizontal de
     siempre; en celular (≤760px) van apiladas, ver más abajo. */
  .tablero-kanban { flex-wrap: wrap; overflow-x: visible; }
  .topbar nav a, .topbar .nombre-usuario {
    margin-left: 0; padding: 0.7rem 0.2rem; border-top: 1px solid rgba(255,255,255,0.12); font-size: 1rem;
  }
  .topbar .nombre-usuario { opacity: 0.7; font-size: 0.85rem; }
  .topbar .btn-salir { margin: 0.5rem 0 0.3rem; text-align: center; padding: 0.6rem; border-top: none; }
}

@media (max-width: 760px) {
  html { font-size: 16px; }

  .contenido, .contenido.contenido-ancho, .contenido:has(> .pagina-compacta) { padding: 0.85rem 0.7rem; max-width: 100%; }
  .tarjeta, .tarjeta-clientes { padding: 0.9rem 0.85rem; }
  h2 { font-size: 1.3rem; line-height: 1.25; }
  /* Una tabla o grilla más ancha que la pantalla se desplaza dentro de su
     tarjeta (la página nunca se corre de costado). */
  .tarjeta, .tarjeta-acordeon-cuerpo, .tarjeta-clientes, dialog { overflow-x: auto; }
  /* break-word (no anywhere): corta un texto largo sólo si no entra, y nunca
     parte un monto ("292.295,00") — con anywhere quedaba "292.295" / ",00". */
  td, th { overflow-wrap: break-word; }
  /* Montos alineados a la derecha en las tablas de 2 columnas (concepto | monto). */
  .tarjeta table td:last-child { white-space: nowrap; }

  /* Login / registro / confirmar mail */
  .centro-pantalla { padding: 1rem; }
  .tarjeta-login { padding: 1.5rem 1.25rem; }
  .tarjeta-login h1 { font-size: 1.6rem; }

  /* Formularios en grilla: apilados. */
  .fila { grid-template-columns: 1fr; gap: 0; }
  .fila-config-general { grid-template-columns: 1fr 1fr !important; gap: 0.75rem; }
  .fila-config-general > div { min-width: 0; overflow-wrap: anywhere; }
  .contenido [style*="grid-template-columns:1fr 1fr"],
  dialog [style*="grid-template-columns:1fr 1fr"] { grid-template-columns: 1fr !important; }
  .contenido [style*="grid-template-columns:repeat(4"]:not(.fila-config-entrega):not(.fila-config-entrega-header) { grid-template-columns: 1fr 1fr !important; }

  /* Detalle del Job: una sola columna de datos, y botones que bajan de línea. */
  .pagina-compacta .campos-2col { column-count: 1; }
  .pagina-compacta .campo-fila .campo-label { flex-basis: 45%; }
  .pagina-compacta .campo-fila .campo-valor { overflow-wrap: anywhere; }
  .acciones-job-cabecera { flex-wrap: wrap; width: 100%; }
  .acciones-job-cabecera .btn-accion, .acciones-job-cabecera form { flex: 1 1 auto; }
  .acciones-job-cabecera form .btn-accion { width: 100%; justify-content: center; }
  .acciones-job-cabecera .btn-accion { justify-content: center; }
  .acciones-revision > form, .acciones-revision .btn-primario { width: 100%; }
  .pedir-cambios { flex-basis: 100%; }

  /* Nueva solicitud: los botones de cada línea dejan de flotar arriba a la
     derecha (se encimaban con "Línea 1") y pasan a su propia fila. */
  .linea-solicitud { padding: 0.8rem; }
  .linea-solicitud .acciones { position: static; justify-content: flex-end; margin-bottom: 0.4rem; flex-wrap: wrap; }

  /* Kanban: las columnas van una debajo de la otra (no de costado). Con
     columnas lado a lado, en "Mis solicitudes" la primera ("Enviada") podía
     estar vacía y el Job quedar en "Lista para revisión", fuera de la
     pantalla — sin ninguna pista de que había que deslizar. Apiladas, se
     recorren con el scroll normal y no queda nada escondido. */
  .tablero-kanban { flex-direction: column; overflow-x: visible; gap: 0.75rem; }
  .columna-kanban { flex: none; min-width: 0; max-width: none; width: 100%; }
  .columna-kanban-cuerpo { max-height: none; overflow-y: visible; }
  /* igualarAlturaTarjetasKanban() fija por JS la altura de las tarjetas para
     emparejarlas entre columnas lado a lado; apiladas no hace falta, y dejaba
     espacio vacío dentro de cada tarjeta. */
  .tarjeta-kanban { height: auto !important; }
  .barra-kanban { padding: 0.65rem 0.8rem; }
  .barra-kanban h2 { white-space: normal; flex-basis: 100%; }
  .barra-kanban input[type="text"] { flex: 1 1 100%; width: auto; font-size: 0.9rem; padding: 0.45rem 0.8rem; }
  .barra-kanban select { flex: 1 1 45%; max-width: none; font-size: 0.85rem; padding: 0.4rem 0.7rem; }
  .barra-kanban .relleno { display: none; }

  /* Acordeones de Tarifas */
  .tarjeta-acordeon > summary { padding: 0.8rem 0.9rem; font-size: 0.95rem; line-height: 1.3; }
  .tarjeta-acordeon-cuerpo { padding: 0.85rem; }
  .tarjeta-acordeon-cuerpo details .tabla-scroll { margin: 0.5rem 0; }

  /* Ventanas emergentes (Summary PL, Simulador de OP/Precio): pantalla completa. */
  dialog { width: 100% !important; max-width: 100vw !important; max-height: 100dvh; margin: 0; border-radius: 0 !important; }
  .modal-summary-pl { max-width: 100vw; }
  /* Dentro de una ventana, si una tabla no entra se desplaza sólo ella (no
     la ventana entera con su título y botones). min-width:0 hace falta para
     que el ítem de la grilla no se estire al ancho de la tabla. */
  dialog [style*="grid-template-columns"] > * { min-width: 0; overflow-x: auto; }
  dialog .tabla-compacta th, dialog .tabla-compacta td { padding: 0.3rem 0.3rem; font-size: 0.76rem; }

  /* Botones de acción más fáciles de tocar con el dedo. */
  .btn-secundario, .btn-primario { min-height: 2.5rem; }
  .acciones-tarifa .btn-secundario { min-height: 0; }
}
