/* Estilos base de la Suite, construidos SOBRE los tokens.
 * Alcance E01: solo lo necesario para la pagina temporal de arranque.
 *
 * box-sizing: hasta la identidad visual v2.0 lo ponia Bootstrap de forma
 * global (*, *::before, *::after) y suite.css nunca lo declaraba por su
 * cuenta -- al retirar Bootstrap (cero clases suyas en uso) se fue tambien
 * este reset sin que nada lo sustituyera. Con content-box por defecto del
 * navegador, cualquier campo con width:100% + padding + borde (los
 * .suite-editable__input del panel de Ofertas, entre otros) se dibuja MAS
 * ANCHO que su contenedor -- eso es lo que se veia como texto "demasiado
 * grande" o superpuesto: no era el tamano de fuente, era el modelo de caja.
 */
*, *::before, *::after {
  box-sizing: border-box;
}

/* iPhone (2.113): sin esto, Safari agranda el texto por su cuenta al girar
   el telefono en horizontal. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* Un <fieldset> no encoge por debajo de su contenido mas ancho (min-width:
   min-content del navegador): a 320 px se salia de la pantalla (2.113). */
fieldset { min-width: 0; }

/* Navegar de una pagina a otra sin el destello en blanco (2.118, ADR-045):
   transicion entre documentos (Safari 18.2+, Chrome 126+; donde no existe,
   no pasa nada). La cabecera no se mueve: solo funde el contenido. */
@view-transition { navigation: auto; }
.suite-cabecera { view-transition-name: suite-cabecera; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--dur-rapido); }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

body {
  margin: 0;
  background: var(--c-fondo);
  color: var(--c-texto);
  font-family: var(--f-sans);
  font-size: var(--fs-base);
  line-height: 1.5;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.suite-contenedor {
  width: 100%;
  max-width: 1000px;
  margin-inline: auto;
  padding-inline: var(--sp-4);
}

.suite-navbar {
  background: var(--c-superficie);
  border-bottom: 1px solid var(--c-borde);
  box-shadow: var(--sh-sm);
}
.suite-navbar__interior {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  height: 56px;
}
.suite-marca {
  font-weight: var(--fw-semi);
  font-size: var(--fs-lg);
  color: var(--c-primario);
  letter-spacing: -.01em;
}
.suite-navbar__meta {
  font-size: var(--fs-sm);
  color: var(--c-texto-suave);
}

.suite-principal { flex: 1; padding-block: var(--sp-12); }

.suite-arranque {
  background: var(--c-superficie);
  border: 1px solid var(--c-borde);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-md);
  padding: var(--sp-10);
  max-width: 560px;
  margin-inline: auto;
  text-align: center;
}
.suite-arranque__titulo {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-3xl);
  font-weight: var(--fw-semi);
  letter-spacing: -.02em;
}
.suite-arranque__version {
  margin: 0 0 var(--sp-6);
  color: var(--c-texto-suave);
  font-size: var(--fs-sm);
  font-family: var(--f-mono);
}
.suite-arranque__estado {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-8);
  color: var(--c-exito);
  font-weight: var(--fw-medio);
}

.suite-punto {
  width: 9px; height: 9px; border-radius: 50%;
  display: inline-block; background: currentColor;
}
.suite-punto--ok { color: var(--c-exito); }

.suite-datos {
  margin: 0; text-align: left;
  border-top: 1px solid var(--c-borde);
}
.suite-datos__fila {
  display: flex; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--c-borde);
}
.suite-datos dt { color: var(--c-texto-suave); font-size: var(--fs-sm); margin: 0; }
.suite-datos dd { margin: 0; font-weight: var(--fw-medio); font-variant-numeric: tabular-nums; }

.suite-modulos {
  margin: var(--sp-6) 0 0; padding: 0; list-style: none;
  text-align: left; font-size: var(--fs-sm); font-family: var(--f-mono);
}
.suite-modulos li { padding: var(--sp-2) 0; border-bottom: 1px solid var(--c-borde); }

.suite-error__codigo {
  font-family: var(--f-mono); font-size: var(--fs-3xl);
  color: var(--c-texto-suave); margin: 0 0 var(--sp-2);
}
.suite-error__ref { font-size: var(--fs-sm); color: var(--c-texto-suave); }

.suite-pie {
  border-top: 1px solid var(--c-borde);
  padding-block: var(--sp-4);
  color: var(--c-texto-suave);
  font-size: var(--fs-xs);
  text-align: center;
}

@media (max-width: 640px) {
  .suite-arranque { padding: var(--sp-6); }
  .suite-datos__fila { flex-direction: column; gap: var(--sp-1); }
}

/* =====================================================================
   Utilidades atomicas -- la CSP (style-src, sin unsafe-inline, ver
   security/cabeceras.py) prohibe CUALQUIER atributo style="..." en las
   plantillas: no es opcional, la pagina ignora el estilo en silencio si
   se usa. Estas cubren los casos repetidos varias veces entre pantallas
   (color/cursor/alineacion/espaciado sobre un token ya existente); lo
   que es propio de una sola pantalla lleva su propia clase con nombre,
   junto al resto de sus estilos, no aqui. */
.u-cursor-pointer { cursor: pointer; }
.u-mono { font-family: var(--f-mono); }
.u-fs-xs { font-size: var(--fs-xs); }
.u-fs-sm { font-size: var(--fs-sm); }
.u-derecha { text-align: right; }
.u-centro { text-align: center; }
.u-input-corto { width: 5em; }
.u-mt-0 { margin-top: 0; }
.u-mt-1 { margin-top: var(--sp-1); }
.u-mt-4 { margin-top: var(--sp-4); }
.u-mt-8 { margin-top: var(--sp-8); }
.u-mb-2 { margin-bottom: var(--sp-2); }
.u-mb-3 { margin-bottom: var(--sp-3); }
.u-pre-wrap { white-space: pre-wrap; }
.u-texto-exito { color: var(--c-exito); }
.u-texto-peligro { color: var(--c-peligro); }
.u-texto-aviso { color: var(--c-aviso); }
.u-texto-primario { color: var(--c-primario); }
.u-texto-morado { color: var(--c-morado); }
.u-texto-rosa { color: var(--c-rosa); }
.u-texto-gris { color: var(--c-texto-suave); }
.u-texto-suave { color: var(--c-texto-suave); }
.u-fw-semi { font-weight: var(--fw-semi); }
.u-fondo-exito { background: var(--c-exito); }
.u-fondo-peligro { background: var(--c-peligro); }
.u-fondo-aviso { background: var(--c-aviso); }
.u-fondo-morado { background: var(--c-morado); }
.u-fondo-primario { background: var(--c-primario); }
.u-fondo-rosa { background: var(--c-rosa); }
.u-fondo-gris { background: var(--c-borde); }
.u-fila {
  display: flex; align-items: center; gap: var(--sp-2);
}
.u-fila--separada { justify-content: space-between; }
.u-fila--fin { justify-content: flex-end; }

/* =====================================================================
   E03.01 — Cascarón de aplicación: cabecera, lateral, contenido, pie
   Todo construido sobre tokens. Ni un valor visual literal (N-46).
   ===================================================================== */

.suite-app { display: flex; flex-direction: column; min-height: 100vh; }
/* En Safari, 100vh incluye lo que tapa la barra de direcciones: dvh es el
   alto visible de verdad (2.113). Quien no lo entiende se queda con vh. */
@supports (height: 100dvh) {
  body, .suite-app { min-height: 100dvh; }
}

/* --- Cabecera ------------------------------------------------------- */
.suite-cabecera {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4);
  height: 56px; padding-inline: var(--sp-4);
  background: var(--c-superficie-alta);
  border-bottom: 1px solid var(--c-borde);
  position: sticky; top: 0; z-index: var(--z-desplegable);
}
.suite-cabecera__izq, .suite-cabecera__der {
  display: flex; align-items: center; gap: var(--sp-3);
}
.suite-marca {
  display: flex; align-items: center; gap: var(--sp-2);
  text-decoration: none; color: var(--c-texto);
}
.suite-marca__texto { font-size: var(--fs-lg); font-weight: var(--fw-normal); letter-spacing: -.01em; }
.suite-marca__texto strong { font-weight: var(--fw-semi); color: var(--c-primario); }

.suite-boton-menu {
  display: none; flex-direction: column; gap: 4px;
  background: none; border: 0; cursor: pointer; padding: var(--sp-2);
}
.suite-boton-menu span {
  display: block; width: 18px; height: 2px; border-radius: 2px; background: var(--c-texto);
}

/* --- Selector de tema (identidad visual v2.0) -------------------------
   El boton siempre muestra el icono de a DONDE se va a cambiar, no el
   tema actual: en claro se ve la luna (pulsar para oscuro), en oscuro el
   sol (pulsar para claro). Ambos iconos viven siempre en el DOM; solo se
   alterna cual se ve, sin JS de por medio -- puro CSS sobre [data-tema]. */
.suite-alternar-tema__luna { display: none; }
[data-tema="oscuro"] .suite-alternar-tema__sol { display: none; }
[data-tema="oscuro"] .suite-alternar-tema__luna { display: inline-flex; }

/* Notificaciones (ADR-044): la bandeja de la campana */
.suite-notificaciones { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.suite-notificacion {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  background: var(--c-superficie); border: 1px solid var(--c-borde-sutil); border-radius: var(--r-lg);
  padding: var(--sp-2);
}
.suite-notificacion.es-nueva { border-color: var(--c-primario-200); background: var(--c-primario-50); }
.suite-notificacion__abrir { flex: 1 1 auto; min-width: 0; margin: 0; }
.suite-notificacion__boton {
  display: grid; gap: var(--sp-1); width: 100%; min-height: var(--toque-min); padding: var(--sp-2);
  background: none; border: 0; text-align: left; color: var(--c-texto); cursor: pointer; font: inherit;
}
.suite-notificacion__titulo { font-weight: var(--fw-semi); overflow-wrap: anywhere; }
.suite-notificacion.es-nueva .suite-notificacion__titulo::before {
  content: ""; display: inline-block; width: var(--sp-2); height: var(--sp-2); margin-right: var(--sp-2);
  border-radius: var(--r-pill); background: var(--c-primario); vertical-align: middle;
}
.suite-notificacion__cuerpo { white-space: pre-line; color: var(--c-texto-suave); overflow-wrap: anywhere; }
.suite-notificacion__meta { font-size: var(--fs-xs); color: var(--c-texto-terciario); }
.suite-ajustes-lista { display: grid; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.suite-ajustes-lista .suite-seccion-caja { align-items: flex-start; }
.suite-lista-dispositivos { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.suite-lista-dispositivos li { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }

/* Indicadores de la cabecera (ADR-044): la campana con sus no leidas */
.suite-indicador {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--toque-min); min-height: var(--toque-min);
  color: var(--c-texto); border-radius: var(--r-pill); text-decoration: none;
}
.suite-indicador:hover { background: var(--c-superficie-sutil); }
.suite-indicador__cuenta {
  position: absolute; top: var(--sp-1); right: var(--sp-1);
  min-width: var(--sp-4); height: var(--sp-4); padding: 0 var(--sp-1);
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-pill); background: var(--c-peligro); color: var(--c-texto-invertido);
  font-size: var(--fs-2xs); font-weight: var(--fw-semi); line-height: 1;
}
/* Buscador global (ADR-047): en la cabecera, campo en pantallas anchas y
   lupa en las estrechas; y su pagina de resultados. */
.u-oculto-accesible {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.suite-buscador-cabecera { display: flex; align-items: center; margin: 0; }
.suite-buscador-cabecera input {
  width: 16rem; min-height: var(--sp-8); padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--c-borde); border-radius: var(--r-pill);
  background: var(--c-superficie-entrada); color: var(--c-texto); font: inherit; font-size: var(--fs-sm);
}
.suite-buscador-cabecera input:focus-visible {
  outline: none; border-color: var(--c-primario); box-shadow: 0 0 0 2px var(--c-primario-suave);
}
.suite-buscar-icono { display: none; }
/* Dos clases: le gana a la regla general de .suite-filtros (flex y campos pequenos) */
.suite-filtros.suite-buscador-pagina { display: grid; gap: var(--sp-3); margin-bottom: var(--sp-6); }
.suite-buscador-pagina__fila { display: flex; gap: var(--sp-2); width: 100%; max-width: var(--ancho-lectura); }
.suite-buscador-pagina .suite-buscador-pagina__fila input {
  flex: 1 1 auto; min-width: 0; min-height: var(--toque-min); padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--c-borde); border-radius: var(--r-md);
  background: var(--c-superficie-entrada); color: var(--c-texto); font: inherit; font-size: var(--fs-base);
}
.suite-buscador-pagina .suite-buscador-pagina__fila input:focus-visible {
  outline: none; border-color: var(--c-primario); box-shadow: 0 0 0 2px var(--c-primario-suave);
}
.suite-buscador-pagina__modulos {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin: 0; padding: 0; border: 0;
}
.suite-buscador-pagina__en { font-size: var(--fs-sm); color: var(--c-texto-suave); }
.suite-chip {
  display: inline-flex; align-items: center; gap: var(--sp-1); min-height: var(--sp-8);
  padding: var(--sp-1) var(--sp-3); border: 1px solid var(--c-borde); border-radius: var(--r-pill);
  background: var(--c-superficie); font-size: var(--fs-sm); cursor: pointer;
}
.suite-buscador-pagina .suite-chip input { margin: 0; padding: 0; }
.suite-chip.es-elegido { border-color: var(--c-primario); background: var(--c-primario-50); color: var(--c-primario); }
.suite-chip__cuenta { font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--c-texto-suave); }
.suite-resultados { margin-bottom: var(--sp-6); }
.suite-resultados__grupo {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2);
  margin: 0 0 var(--sp-2); font-size: var(--fs-base); font-weight: var(--fw-semi);
}
.suite-resultados__modulo { font-size: var(--fs-xs); font-weight: var(--fw-medio); color: var(--c-texto-suave); }
.suite-resultados__cuenta {
  font-size: var(--fs-2xs); padding: 0 var(--sp-2); border-radius: var(--r-pill);
  background: var(--c-superficie-sutil); color: var(--c-texto-suave);
}
.suite-resultados__solo {
  display: inline-flex; align-items: center; min-height: var(--toque-min); padding: 0 var(--sp-2);
  margin-left: auto; font-size: var(--fs-xs); font-weight: var(--fw-medio);
}
.suite-resultados__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.suite-resultado {
  display: grid; gap: var(--sp-0-5); min-height: var(--toque-min); padding: var(--sp-2) var(--sp-3);
  background: var(--c-superficie); border: 1px solid var(--c-borde-sutil); border-radius: var(--r-lg);
  color: var(--c-texto); text-decoration: none;
}
.suite-resultado:hover { border-color: var(--c-primario-200); box-shadow: var(--sh-sm); }
.suite-resultado__titulo {
  display: inline-flex; align-items: center; gap: var(--sp-2); font-weight: var(--fw-semi); overflow-wrap: anywhere;
}
.suite-resultado__detalle { font-size: var(--fs-sm); color: var(--c-texto-suave); overflow-wrap: anywhere; }
.suite-resultado__fecha { font-size: var(--fs-xs); color: var(--c-texto-terciario); }
.suite-resultado mark, .suite-resultados mark {
  background: var(--c-aviso-bg); color: inherit; border-radius: var(--r-sm); padding: 0;
}
.suite-resultados__mas { margin: var(--sp-2) 0 0; font-size: var(--fs-sm); color: var(--c-texto-suave); }
.suite-vacio kbd {
  padding: 0 var(--sp-1); border: 1px solid var(--c-borde); border-radius: var(--r-sm);
  font-family: var(--f-mono); font-size: var(--fs-xs);
}
.suite-lateral .suite-lateral__buscar { display: none; }
@media (max-width: 1023px) {
  .suite-buscador-cabecera { display: none; }
  .suite-buscar-icono { display: inline-flex; }
  .suite-lateral .suite-lateral__buscar { display: flex; }
}
@media (max-width: 359px) {
  /* A 320 px la lupa no cabe junto a la campana, el tema y «Salir»: queda
     la entrada «Buscar» del menu lateral. */
  .suite-buscar-icono { display: none; }
}
/* Plazos de pedidos (ADR-048): el panel, un bloque por modulo */
.suite-plazos {
  display: grid; gap: var(--sp-2); margin: 0 0 var(--sp-4); padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--c-borde-sutil); border-radius: var(--r-lg); background: var(--c-superficie);
}
.suite-plazos__titulo { padding: 0 var(--sp-1); font-weight: var(--fw-semi); }
.suite-plazos__campo { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin: 0; }
.suite-plazos .suite-plazos__campo label { flex: 0 0 11rem; margin: 0; }
.suite-plazos .suite-plazos__campo input[type="number"] { width: 6rem; }
/* Sugerencias (2.122): la lista de los campos con <datalist> (suite.js).
   Posicion y alto los pone el script (CSSOM, permitido por la CSP). */
.suite-sugerencias {
  position: fixed; z-index: var(--z-desplegable); list-style: none; margin: 0; padding: var(--sp-1);
  max-height: 16rem; overflow-y: auto; overscroll-behavior: contain;
  background: var(--c-superficie); border: 1px solid var(--c-borde); border-radius: var(--r-md);
  box-shadow: var(--sh-lg); font-size: var(--fs-sm);
}
.suite-sugerencias[hidden] { display: none; }
.suite-sugerencias__opcion {
  display: flex; align-items: baseline; gap: var(--sp-2); min-height: var(--sp-8); padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-sm); cursor: pointer; overflow-wrap: anywhere;
}
.suite-sugerencias__opcion:hover, .suite-sugerencias__opcion.es-activa { background: var(--c-primario-50); }
.suite-sugerencias__opcion.es-actual { font-weight: var(--fw-semi); color: var(--c-primario); }
.suite-sugerencias__opcion.es-actual::after { content: "✓"; margin-left: auto; }
.suite-sugerencias__etiqueta { font-size: var(--fs-xs); color: var(--c-texto-suave); font-weight: var(--fw-normal); }
.suite-sugerencias__mas { padding: var(--sp-1) var(--sp-2); font-size: var(--fs-xs); color: var(--c-texto-suave); }
@media (pointer: coarse) {
  .suite-sugerencias { font-size: var(--fs-base); }
  .suite-sugerencias__opcion { min-height: var(--toque-min); align-items: center; }
}
/* «Mi dia» (ADR-052): lo pendiente por secciones, con «Mañana» al lado */
.suite-mi-dia { margin-bottom: var(--sp-6); }
.suite-mi-dia__seccion {
  display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-2);
  font-size: var(--fs-base); font-weight: var(--fw-semi);
}
.suite-mi-dia__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.suite-mi-dia__item {
  display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-1) var(--sp-2) var(--sp-1) 0;
  background: var(--c-superficie); border: 1px solid var(--c-borde-sutil); border-radius: var(--r-lg);
}
.suite-mi-dia--urgente .suite-mi-dia__item { box-shadow: inset 3px 0 0 var(--c-peligro); }
.suite-mi-dia--hoy .suite-mi-dia__item { box-shadow: inset 3px 0 0 var(--c-primario); }
.suite-mi-dia__enlace {
  flex: 1 1 auto; min-width: 0; display: grid; gap: var(--sp-0-5); min-height: var(--toque-min);
  padding: var(--sp-2) var(--sp-3); color: var(--c-texto); text-decoration: none;
}
.suite-mi-dia__titulo { font-weight: var(--fw-semi); overflow-wrap: anywhere; }
.suite-mi-dia__detalle { font-size: var(--fs-sm); color: var(--c-texto-suave); overflow-wrap: anywhere; }
.suite-mi-dia__modulo { font-size: var(--fs-xs); color: var(--c-texto-terciario); }
.suite-mi-dia__item .suite-btn { min-height: var(--toque-min); }
.suite-usuario { display: flex; align-items: center; gap: var(--sp-2); }
.suite-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--c-primario-suave); color: var(--c-primario);
  font-weight: var(--fw-semi); font-size: var(--fs-sm);
}
.suite-usuario__datos { display: flex; flex-direction: column; line-height: 1.2; }
.suite-usuario__nombre { font-size: var(--fs-sm); font-weight: var(--fw-medio); }
.suite-usuario__rol { font-size: var(--fs-xs); color: var(--c-texto-suave); }
.suite-salir { margin: 0; }

/* --- Cuerpo y lateral ----------------------------------------------- */
.suite-cuerpo { display: flex; flex: 1; align-items: stretch; }

/* Paginas con un listado grande de verdad (Ofertas, primera en usarlo):
   la pagina en si no hace scroll -- cabecera, resumen PDTE/acciones,
   filtros y paginacion se quedan siempre a la vista; solo la tabla se
   desplaza por dentro, con la cabecera de columnas (.suite-tabla th ya
   trae position:sticky, solo le faltaba un contenedor con scroll donde
   pegarse) siempre visible mientras se baja por las filas.

   Opt-in via {% block clase_body %}...suite-app--tabla-fija{% endblock %},
   no cambia el comportamiento de ninguna otra pantalla -- son selectores
   descendientes de esta clase, no reglas de .suite-app a secas. Pura
   cascada flex (alto fijo arriba del todo, min-height:0 en cada nivel
   intermedio para que no gane el "al menos tan alto como mi contenido"
   de por defecto, overflow-y:auto solo en el nivel que debe desplazarse):
   nada de calc(100vh - Npx) por niveles -- ese calculo a mano fue
   exactamente el error del panel lateral (ver mas abajo), aqui flexbox
   reparte el espacio solo. */
.suite-app--tabla-fija { height: 100vh; overflow: hidden; }
@supports (height: 100dvh) { .suite-app--tabla-fija { height: 100dvh; } }
.suite-app--tabla-fija .suite-cuerpo { min-height: 0; }
.suite-app--tabla-fija .suite-lateral { overflow-y: auto; }
.suite-app--tabla-fija .suite-contenido {
  display: flex; flex-direction: column; min-height: 0; overflow: hidden;
}
/* Todo lo que NO es la tabla en si se queda a su tamano natural, nunca
   crece: cabecera (titulo+acciones), resumen PDTE (Ofertas), barra de
   .suite-estadisticas (Alertas), y el formulario de busqueda -- sea la
   fila .suite-filtros (Ofertas/Tickets) o un <form class="suite-formulario">
   de un solo campo (Tracer/Tiendas). */
.suite-app--tabla-fija .suite-encabezado,
.suite-app--tabla-fija .suite-resumen-acciones,
.suite-app--tabla-fija .suite-filtros,
.suite-app--tabla-fija .suite-estadisticas,
.suite-app--tabla-fija > .suite-cuerpo .suite-contenido > form.suite-formulario,
.suite-app--tabla-fija .suite-formulario__acciones {
  flex: 0 0 auto;
}
/* El area que crece y desplaza por dentro: .suite-listado-panel si hay
   panel lateral (Ofertas/Tracer), o .suite-tabla-marco directamente si
   no lo hay (Tiendas/Zonas/Alertas) -- el selector no distingue niveles
   de anidamiento, sirve para los dos casos por igual. */
.suite-app--tabla-fija .suite-listado-panel { flex: 1 1 auto; min-height: 0; }
.suite-app--tabla-fija .suite-listado-panel__principal {
  display: flex; flex-direction: column; min-height: 0;
}
.suite-app--tabla-fija .suite-tabla-marco { flex: 0 1 auto; min-height: 0; overflow-y: auto; }
/* 2.125: con una fila desplegada (p. ej. la ficha entera de una instalacion
   de Caixa, mucho mas alta que el hueco que deja la tabla bajo los filtros),
   la pagina vuelve a desplazarse entera. Dentro del marco fijo la ficha se
   quedaba en unos pocos pixeles al pie de la pantalla (medido en iPad: 70
   px a la vista de 830) y solo «volvia» al hacer zoom. suite.js pone la
   clase al desplegar y la quita al plegar. */
.suite-app--tabla-fija.suite-app--con-detalle { height: auto; overflow: visible; }
.suite-app--tabla-fija.suite-app--con-detalle .suite-contenido { display: block; overflow: visible; }
.suite-app--tabla-fija.suite-app--con-detalle .suite-listado-panel,
.suite-app--tabla-fija.suite-app--con-detalle .suite-panel-filtros { display: block; }
.suite-app--tabla-fija.suite-app--con-detalle .suite-tabla-marco { overflow-y: visible; }
/* Tickets: filtros en barra lateral persistente (.suite-panel-filtros),
   no en .suite-listado-panel -- misma idea, otra forma. El contenido
   (busqueda + tabla + paginacion) es la columna que crece; la barra de
   filtros solo se desplaza por dentro si ella sola no cupiera.

   `align-items: stretch`, no el `flex-start` de la regla base de
   `.suite-panel-filtros`: sin esto, exactamente el mismo bug que ya
   documentaba el comentario de `.suite-listado-panel` un poco mas
   abajo -- `flex-start` deja que `.suite-panel-filtros__contenido`
   (y por tanto `.suite-tabla-marco` dentro) crezca a su alto NATURAL
   de contenido en vez de encajar en el alto disponible, asi que
   `overflow:hidden` en `.suite-contenido` corta el resto sin dar
   scroll -- no es que falte scroll, el contenido desaparece. No se
   habia notado porque Tickets rara vez tiene filas de sobra para
   que el desbordamiento se vea; confirmado con Visitas Previas (cxb,
   26 filas) en un navegador real, no solo leyendo el CSS. */
.suite-app--tabla-fija .suite-panel-filtros { flex: 1 1 auto; min-height: 0; align-items: stretch; }
.suite-app--tabla-fija .suite-sidebar-filtros { flex: 0 0 auto; overflow-y: auto; }
.suite-app--tabla-fija .suite-panel-filtros__contenido {
  display: flex; flex-direction: column; min-height: 0;
}
/* El panel lateral (Ver -> detalle) tenia su propio max-height calculado
   a mano (calc(100vh - 88px - ...), pensado para cuando la pagina entera
   hacia scroll y el panel arrancaba justo debajo de la cabecera). Aqui ya
   no vale: con el resumen y los filtros tambien fijos por encima, el
   panel arranca mas abajo de lo que ese numero suponia, y se volvia a
   salir de la pantalla. align-items:stretch en vez de flex-start le da
   la altura REAL de la fila (la misma que ya reparte flexbox para la
   tabla), sin adivinar ningun pixel -- solo en desktop, que es donde
   .suite-listado-panel es una fila de verdad; en movil el panel usa
   position:fixed (mas abajo) y esto no le afecta. */
@media (min-width: 1024px) {
  .suite-app--tabla-fija .suite-listado-panel { align-items: stretch; }
  .suite-app--tabla-fija .suite-panel-lateral.es-visible {
    position: static;
    max-height: none;
  }
}

.suite-lateral {
  width: 232px; flex-shrink: 0;
  padding: var(--sp-4) var(--sp-3);
  background: var(--c-superficie);
  border-right: 1px solid var(--c-borde);
}
.suite-lateral__grupo {
  margin: var(--sp-4) var(--sp-3) var(--sp-2);
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--c-texto-suave);
}
.suite-lateral__grupo:first-child { margin-top: 0; }
.suite-lateral__enlace {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  color: var(--c-texto); text-decoration: none;
  font-size: var(--fs-sm);
}
.suite-lateral__enlace:hover { background: var(--c-superficie-sutil); }
.suite-lateral__enlace.es-activo {
  background: var(--c-primario-suave); color: var(--c-primario);
  font-weight: var(--fw-medio);
}
.suite-icono { flex-shrink: 0; }

.suite-contenido {
  flex: 1; min-width: 0;
  /* Ancho completo en TODA la Suite (mantenedor, 12-oct-2026: «sin
     espacios blancos en laterales, todos los modulos ocupando el ancho
     completo»). Antes habia un tope de lectura de 1600px centrado; ya no.
     Solo queda un margen interior minimo para que nada toque el borde. */
  padding: var(--sp-6) var(--sp-5);
}
/* Opt-in historico (Ofertas, calendario...): ya es el comportamiento por
   defecto; se conserva la clase para no tocar las plantillas que la usan. */
.suite-app--ancho .suite-contenido { max-width: none; }

/* --- Encabezado de página ------------------------------------------- */
.suite-encabezado {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-4); margin-bottom: var(--sp-8);
}
.suite-encabezado__titulo {
  margin: 0 0 var(--sp-1); font-size: var(--fs-2xl);
  font-weight: var(--fw-semi); letter-spacing: -.02em;
}
.suite-encabezado__sub { margin: 0; color: var(--c-texto-suave); font-size: var(--fs-sm); }
.suite-encabezado__acciones { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.suite-seccion {
  margin: var(--sp-8) 0 var(--sp-4);
  font-size: var(--fs-sm); font-weight: var(--fw-semi);
  text-transform: uppercase; letter-spacing: .06em; color: var(--c-texto-suave);
}

/* --- Tarjetas de módulo --------------------------------------------- */
.suite-tarjetas {
  display: grid; gap: var(--sp-4);
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.suite-tarjeta {
  display: flex; flex-direction: column; gap: var(--sp-2);
  padding: var(--sp-5);
  background: var(--c-superficie);
  border: 1px solid var(--c-borde); border-radius: var(--r-xl);
  text-decoration: none; color: var(--c-texto);
  transition: background var(--dur-normal) var(--ease-defecto),
              border-color var(--dur-normal) var(--ease-defecto),
              box-shadow var(--dur-normal) var(--ease-defecto),
              transform var(--dur-normal) var(--ease-defecto);
}
.suite-tarjeta:hover {
  background: var(--c-superficie-sutil);
  border-color: var(--c-borde-foco);
  box-shadow: var(--sh-md);
  transform: translateY(-1px);
}
.suite-tarjeta__icono {
  width: 40px; height: 40px; border-radius: var(--r-md);
  display: grid; place-items: center;
  background: var(--c-primario-suave); color: var(--c-primario);
  margin-bottom: var(--sp-1);
}
.suite-tarjeta--sistema .suite-tarjeta__icono {
  background: var(--c-borde); color: var(--c-texto-suave);
}
.suite-tarjeta__nombre { font-weight: var(--fw-semi); }
.suite-tarjeta__desc { font-size: var(--fs-sm); color: var(--c-texto-suave); flex: 1; }
.suite-tarjeta__pie {
  font-size: var(--fs-xs); color: var(--c-texto-suave);
  font-family: var(--f-mono);
  display: flex; align-items: center; gap: var(--sp-2);
}
.suite-etiqueta {
  padding: 1px var(--sp-2); border-radius: var(--r-sm);
  background: var(--c-borde); font-family: var(--f-sans);
}

/* --- Estado vacío ---------------------------------------------------- */
.suite-vacio {
  padding: var(--sp-10); text-align: center;
  background: var(--c-superficie);
  border: 1px dashed var(--c-borde); border-radius: var(--r-lg);
}
.suite-vacio__titulo { margin: 0 0 var(--sp-2); font-weight: var(--fw-semi); }
.suite-vacio__texto { margin: 0; color: var(--c-texto-suave); font-size: var(--fs-sm); }

/* --- Zona de arrastrar-y-soltar (panel de importacion centralizado):
   <label> envolviendo el <input type="file"> real (oculto) -- clicar en
   cualquier punto de la zona abre el selector nativo sin JS para eso;
   dragover/drop si llevan JS (suite.js, componente "dropzone-importar"). */
.suite-dropzone {
  display: block; cursor: pointer; text-align: center;
  padding: var(--sp-6); margin-bottom: var(--sp-3);
  border: 2px dashed var(--c-borde); border-radius: var(--r-lg);
  background: var(--c-fondo);
  transition: border-color var(--dur-rapido) var(--ease-defecto),
              background var(--dur-rapido) var(--ease-defecto);
}
.suite-dropzone:hover, .suite-dropzone.es-sobre {
  border-color: var(--c-primario); background: var(--c-primario-suave);
}
.suite-dropzone__texto { color: var(--c-texto-suave); font-size: var(--fs-sm); }
.suite-dropzone__resultados { list-style: none; margin: 0; padding: 0; font-size: var(--fs-xs); }
.suite-dropzone__resultados li {
  padding: var(--sp-1) 0; border-bottom: 1px solid var(--c-borde);
  color: var(--c-texto-suave); font-family: var(--f-mono);
}
.suite-dropzone__resultados li:last-child { border-bottom: 0; }
.suite-dropzone__resultados li.es-ok { color: var(--c-exito); }
.suite-dropzone__resultados li.es-error { color: var(--c-peligro); }

/* --- Botones --------------------------------------------------------- */
.suite-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--sp-2);
  height: 32px; padding: 0 var(--sp-3);
  border-radius: var(--r-md); border: 1px solid var(--c-borde);
  background: transparent; color: var(--c-texto);
  font-family: inherit; font-size: var(--fs-sm); font-weight: var(--fw-medio);
  cursor: pointer; text-decoration: none;
  transition: background var(--dur-rapido) var(--ease-defecto),
              border-color var(--dur-rapido) var(--ease-defecto);
}
.suite-btn:hover { background: var(--c-superficie-sutil); }
.suite-btn:focus-visible {
  outline: none; border-color: var(--c-primario);
  box-shadow: 0 0 0 2px var(--c-primario-suave);
}
.suite-btn--primario {
  background: var(--c-primario); border-color: var(--c-primario); color: var(--c-texto-invertido);
}
.suite-btn--primario:hover { background: var(--c-primario-fuerte); border-color: var(--c-primario-fuerte); }
.suite-btn--fantasma { background: transparent; border-color: transparent; color: var(--c-texto-suave); }
.suite-btn--fantasma:hover { background: var(--c-superficie-sutil); color: var(--c-texto); }
.suite-btn--peligro { color: var(--c-peligro); border-color: var(--c-borde); }
.suite-btn--peligro:hover { background: var(--c-peligro); border-color: var(--c-peligro); color: var(--c-texto-invertido); }
.suite-btn--sm { height: 28px; padding: 0 var(--sp-2); font-size: var(--fs-xs); }
.suite-btn--ancho { width: 100%; padding-block: var(--sp-3); }
.suite-btn[disabled] { opacity: .45; cursor: not-allowed; }

/* --- Formularios ----------------------------------------------------- */
.suite-formulario { max-width: 640px; }
.suite-grupo {
  border: 1px solid var(--c-borde); border-radius: var(--r-lg);
  padding: var(--sp-3) var(--sp-4); margin: 0 0 var(--sp-4);
  background: var(--c-superficie);
  font-size: var(--fs-xs);
}
.suite-grupo legend {
  padding-inline: var(--sp-2); font-size: var(--fs-2xs);
  font-weight: var(--fw-semi); color: var(--c-texto-suave);
  text-transform: uppercase; letter-spacing: .06em;
}
/* Cada <p> del panel de detalle (Ofertas/Tracer) es una fila "etiqueta:
   valor" -- sin esta regla hereda el margen de parrafo por defecto del
   navegador (Bootstrap lo neutralizaba; se fue con el, sin sustituto). */
.suite-grupo p { margin: 0 0 var(--sp-2); }
.suite-grupo p:last-child { margin-bottom: 0; }

/* Vista de detalle (paneles laterales de Ofertas/Tracer y la pagina
   completa de Tickets): solo lectura en su mayoria, mas fila que campo
   de formulario -- soporta mucha mas densidad que .suite-grupo generico
   (que tambien viste formularios reales, con <label>+<input>, donde ese
   aire hace falta). Modificador aparte para no apretar formularios que
   no son esto. */
.suite-grupo--densa { padding: var(--sp-1) var(--sp-2); line-height: 1.2; }
.suite-grupo--densa legend { margin-bottom: var(--sp-0-5); }
.suite-grupo--densa p { margin: 0 0 var(--sp-0-5); }

/* Contenedor de las fichas de una vista de detalle: en el panel lateral
   (420px) una columna es lo unico que cabe, la propia rejilla lo decide
   sola (auto-fit no crea una segunda columna sin sitio para ella); en
   una pagina completa (Tickets) reparte varias fichas cortas en la
   misma fila en vez de apilarlas, que es lo que de verdad libera alto
   de pantalla. .suite-grupo--ancha fuerza una ficha (una tabla, texto
   largo) a ocupar la fila entera aunque haya sitio para mas columnas. */
.suite-detalle-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--sp-2); align-items: start;
}
.suite-detalle-grid > .suite-grupo { margin: 0; }
.suite-grupo--ancha { grid-column: 1 / -1; }
.suite-campo { margin-bottom: var(--sp-4); }
/* `__etiqueta`: el titulo de un dato que no se edita (no es un <label>: no
   hay campo al que apuntar). Mismo aspecto. */
.suite-campo label, .suite-campo__etiqueta {
  display: block; margin-bottom: var(--sp-1);
  font-size: var(--fs-sm); font-weight: var(--fw-medio);
}
.suite-campo input[type="text"], .suite-campo input[type="email"],
.suite-campo input[type="password"], .suite-campo input[type="time"],
.suite-campo input[type="date"], .suite-campo input[type="number"],
.suite-campo input[type="tel"], .suite-campo input[type="url"],
.suite-campo input[type="search"],
.suite-campo select, .suite-campo textarea {
  width: 100%; padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--c-borde); border-radius: var(--r-sm);
  background: var(--c-superficie-entrada); color: var(--c-texto);
  font-family: inherit; font-size: var(--fs-sm);
  transition: border-color var(--dur-rapido) var(--ease-defecto);
}
/* Campos dentro de una tabla editable (p. ej. Ajustes de la Suite): mismo
   aspecto que en un formulario, mas compactos. */
.suite-tabla input[type="text"], .suite-tabla input[type="number"], .suite-tabla select {
  width: 100%; min-width: 4em; padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--c-borde); border-radius: var(--r-sm);
  background: var(--c-superficie-entrada); color: var(--c-texto);
  font-family: inherit; font-size: var(--fs-sm);
}
.suite-tabla input.u-input-corto { width: 5em; }
.suite-campo input:focus-visible, .suite-campo select:focus-visible,
.suite-campo textarea:focus-visible {
  outline: none; border-color: var(--c-primario);
  box-shadow: 0 0 0 2px var(--c-primario-suave);
}
/* Campo de texto + botón adosado en la misma fila (Aperturas: botón de
   ficha de contacto junto al campo de técnico de obra / contacto PRL).
   El input debe encogerse frente al botón, no al revés -- dentro de un
   `.u-fila` normal su `width: 100%` se lleva todo el ancho y empuja el
   botón fuera de la caja. */
.suite-campo__fila { display: flex; align-items: center; gap: var(--sp-2); }
.suite-campo__fila input { flex: 1 1 auto; min-width: 0; width: auto; }
.suite-campo__fila > button { flex: 0 0 auto; }

.suite-campo--casilla label {
  display: flex; align-items: baseline; gap: var(--sp-2);
  font-weight: var(--fw-normal); cursor: pointer;
}
.suite-obligatorio { color: var(--c-peligro); }
.suite-ayuda { display: block; margin-top: var(--sp-1); font-size: var(--fs-xs); color: var(--c-texto-suave); }
.suite-formulario__acciones { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.suite-en-linea { display: inline; margin: 0; }
/* Formulario ancho: los bloques (fieldset) se reparten en columnas y
   llenan la pantalla en vez de quedarse en una columna de 760px con el
   resto en blanco (ancho completo, 12-oct-2026). En movil, una columna.
   Todo lo que no es un bloque (acciones, avisos, titulos) ocupa la fila.
   Se aplica tambien a cualquier formulario con bloques (:has), sin tener
   que marcarlo; los formularios sueltos sin bloques no cambian. */
.suite-formulario--ancho,
.suite-formulario:has(> .suite-grupo) {
  max-width: none;
  display: flex; flex-wrap: wrap; gap: var(--sp-4); align-items: flex-start;
}
.suite-formulario--ancho > .suite-grupo,
.suite-formulario:has(> .suite-grupo) > .suite-grupo { flex: 1 1 380px; margin: 0; min-width: 0; }
.suite-formulario--ancho > :not(.suite-grupo),
.suite-formulario:has(> .suite-grupo) > :not(.suite-grupo) { flex: 0 0 100%; }
/* Un bloque que necesita toda la fila (una tabla editable ancha). */
.suite-formulario > .suite-grupo.suite-grupo--completo { flex: 0 0 100%; }

/* Fila de campos cortos, Visitas Previas (cxb): agrupa 2-4 .suite-campo
   en la misma linea en vez de apilarlos a ancho completo uno bajo otro --
   .suite-campo por si solo siempre ocupa el 100% del fieldset, bien para
   un campo largo (direccion, descripcion) pero desperdicia la mitad de
   la fila en uno corto (ciudad, fecha). --estrecho para los que no
   necesitan crecer tanto como sus vecinos (p.ej. "Ciudad" junto a
   "Direccion"). */
.suite-campos-fila { display: flex; gap: var(--sp-4); flex-wrap: wrap; }
.suite-campos-fila > .suite-campo { flex: 1 1 220px; }
.suite-campo--estrecho { max-width: 220px; }
.suite-campos-fila > .suite-campo--estrecho { flex: 0 1 220px; }

/* Vista de detalle a pantalla completa con columna principal + barra
   lateral, Visitas Previas (cxb): la columna principal es una lectura
   de arriba a abajo (situacion, analisis, conectividad, formato), la
   lateral agrupa lo que se consulta suelto -- comparativa rapida de
   medidas, fotos, metadatos -- sin competir por ancho con el texto. */
.suite-detalle-columnas {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 340px);
  gap: var(--sp-6); align-items: start;
}
.suite-detalle-columnas__principal > .suite-grupo,
.suite-detalle-columnas__lateral > .suite-grupo { margin: 0 0 var(--sp-4); }
.suite-detalle-columnas__principal > .suite-grupo:last-child,
.suite-detalle-columnas__lateral > .suite-grupo:last-child { margin-bottom: 0; }
@media (max-width: 900px) {
  /* minmax(0, 1fr) y no 1fr: con 1fr la columna crece hasta el ancho minimo
     de su contenido (una tabla ancha) y toda la pagina se sale por la
     derecha en el movil; asi la tabla se desplaza dentro de su marco. */
  .suite-detalle-columnas { grid-template-columns: minmax(0, 1fr); }
}

/* --- Grupo de opciones (radio), Visitas Previas (cxb, T3) ------------ */
.suite-opciones { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.suite-opcion {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--c-borde); border-radius: var(--r-md);
  font-size: var(--fs-sm); font-weight: var(--fw-normal); cursor: pointer;
  transition: border-color var(--dur-rapido) var(--ease-defecto),
              background var(--dur-rapido) var(--ease-defecto);
}
.suite-opcion:has(input:checked) { border-color: var(--c-primario); background: var(--c-primario-suave); }
.suite-opcion input { margin: 0; }

/* Ancho × alto (× profundidad), Visitas Previas (cxb, T3) */
.suite-dimensiones { display: flex; align-items: center; gap: var(--sp-2); max-width: 420px; }
.suite-dimensiones input { flex: 1; min-width: 0; }
.suite-dimensiones__sep { color: var(--c-texto-suave); }

/* Casillas de "secciones ocultas del PDF", Visitas Previas (cxb, T3) */
.suite-opciones-informe { display: grid; gap: var(--sp-2); grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.suite-seccion-caja {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--c-borde); border-radius: var(--r-md);
  font-size: var(--fs-sm); cursor: pointer;
}
.suite-seccion-caja.es-marcada { border-color: var(--c-peligro); background: var(--c-peligro-bg); }
.suite-seccion-caja input { margin: 0; }

/* Registro fotografico, Visitas Previas (cxb, T4) */
.suite-galeria-fotos {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  margin-bottom: var(--sp-3);
}
.suite-galeria-fotos__item {
  display: block; position: relative; aspect-ratio: 4 / 3;
  border: 1px solid var(--c-borde); border-radius: var(--r-md);
  overflow: hidden; background: var(--c-superficie);
}
.suite-galeria-fotos__item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.suite-galeria-fotos__quitar {
  position: absolute; inset-inline: 0; bottom: 0;
  display: flex; align-items: center; gap: var(--sp-1);
  padding: var(--sp-1) var(--sp-2);
  background: var(--c-superposicion); color: var(--c-texto-invertido);
  font-size: var(--fs-2xs); cursor: pointer;
}
.suite-galeria-fotos__quitar input { margin: 0; }

/* --- Avisos ---------------------------------------------------------- */
.suite-avisos { margin-bottom: var(--sp-6); display: grid; gap: var(--sp-2); }
.suite-aviso {
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-md); border-left: 3px solid var(--c-borde);
  background: var(--c-superficie); font-size: var(--fs-sm);
}
.suite-aviso--ok     { border-left-color: var(--c-exito);   color: var(--c-exito); }
.suite-aviso--error  { border-left-color: var(--c-peligro); color: var(--c-peligro); }
.suite-aviso--aviso  { border-left-color: var(--c-aviso);   color: var(--c-aviso); }

/* --- Avisos plegables (Preparar facturación): misma mecanica que
   .suite-documentacion (<details> nativo, sin JS) -- la lista de avisos
   podia superar la decena de lineas y se comia la pantalla entera antes
   de llegar a la tabla (reportado por el mantenedor). */
.suite-avisos-desplegable {
  background: var(--c-superficie); border: 1px solid var(--c-borde);
  border-radius: var(--r-lg); margin-bottom: var(--sp-4);
}
.suite-avisos-desplegable__resumen {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4); cursor: pointer;
  font-weight: var(--fw-medio); list-style: none;
}
.suite-avisos-desplegable__resumen::-webkit-details-marker { display: none; }
.suite-avisos-desplegable__resumen::before {
  content: "▸"; color: var(--c-texto-suave); display: inline-block;
  transition: transform var(--dur-rapido) var(--ease-defecto);
}
.suite-avisos-desplegable[open] .suite-avisos-desplegable__resumen::before { transform: rotate(90deg); }
.suite-avisos-desplegable__cuerpo {
  padding: 0 var(--sp-4) var(--sp-4); border-top: 1px solid var(--c-borde);
}
.suite-avisos-desplegable__cuerpo .suite-avisos { margin: var(--sp-3) 0 0; }

/* --- Tabla ----------------------------------------------------------- */
.suite-tabla-marco {
  overflow-x: auto;
  background: var(--c-superficie);
  border: 1px solid var(--c-borde); border-radius: var(--r-lg);
}
.suite-tabla { width: 100%; border-collapse: collapse; font-size: var(--fs-xs); }
.suite-tabla th {
  text-align: left; padding: var(--sp-1) var(--sp-2);
  font-size: var(--fs-2xs); font-weight: var(--fw-medio);
  text-transform: uppercase; letter-spacing: .06em; color: var(--c-texto-terciario);
  background: var(--c-superficie-alta);
  border-bottom: 1px solid var(--c-borde); white-space: nowrap;
  position: sticky; top: 0; z-index: 2;
}
.suite-tabla td {
  padding: var(--sp-1) var(--sp-2); border-bottom: 1px solid var(--c-borde-sutil);
  vertical-align: middle;
}
.suite-tabla tr:last-child td { border-bottom: 0; }
.suite-tabla tbody tr:hover { background: var(--c-superficie-sutil); }
.suite-tabla tr.es-inactivo { opacity: .55; }
.suite-tabla__suave { color: var(--c-texto-suave); }
.suite-tabla__acciones { text-align: right; white-space: nowrap; }

/* --- Variante densa (E05.07, Ofertas): tablas con muchas columnas
   editables no caben con el espaciado genérico -- ancho fijo por
   columna (declarado en cada <th>, no aquí) para que el texto truncado
   con ellipsis funcione de verdad dentro de una celda (poco fiable en
   table-layout:auto) y para que ninguna fila outlier (un enlace o una
   etiqueta más larga que el resto) estire la columna entera. */
.suite-tabla--densa { table-layout: fixed; }
.suite-tabla--densa th, .suite-tabla--densa td { padding: var(--sp-1) var(--sp-2); }

/* Anchos por columna de Ofertas (14 columnas, suman 100%): por
   nth-child en vez de style="width" en cada <th> -- la CSP (style-src
   sin unsafe-inline) bloquea cualquier atributo style, en silencio. */
.suite-tabla--ofertas th:nth-child(1)  { width: 9.5%; }
.suite-tabla--ofertas th:nth-child(2),
.suite-tabla--ofertas td:nth-child(2)  { width: 6%; text-align: right; }
.suite-tabla--ofertas th:nth-child(3)  { width: 4.5%; }
.suite-tabla--ofertas th:nth-child(4)  { width: 9%; }
.suite-tabla--ofertas th:nth-child(5)  { width: 9%; }
.suite-tabla--ofertas th:nth-child(6)  { width: 9%; }
.suite-tabla--ofertas th:nth-child(7)  { width: 7%; }
.suite-tabla--ofertas th:nth-child(8)  { width: 6.5%; }
.suite-tabla--ofertas th:nth-child(9)  { width: 6.5%; }
.suite-tabla--ofertas th:nth-child(10) { width: 9%; }
.suite-tabla--ofertas th:nth-child(11) { width: 10%; }
.suite-tabla--ofertas th:nth-child(12),
.suite-tabla--ofertas td:nth-child(12) { width: 3.5%; text-align: center; }
.suite-tabla--ofertas th:nth-child(13) { width: 3.5%; text-align: center; }
.suite-tabla--ofertas th:nth-child(14) { width: 7%; }

/* Filas alternas (a peticion del mantenedor: "que se diferencie facil
   una fila de otra"). Reutiliza los dos tonos de superficie que ya
   existen -- el marco de la tabla ya pinta --c-superficie de fondo, asi
   que solo hace falta un segundo tono en las filas pares, no un color
   nuevo. El propio :hover se repite despues para que siga ganando en
   una fila par (misma especificidad, gana el que va despues). */
.suite-tabla--ofertas tbody tr:nth-child(even) { background: var(--c-fondo); }
.suite-tabla--ofertas tbody tr:hover { background: var(--c-superficie-sutil); }
/* Ofertas facturadas: efecto "cerrado", un tono claramente mas oscuro
   que cualquiera de las dos franjas de arriba (gana a ambas por ir
   despues, misma especificidad) -- no toca el texto ni usa opacity
   (.es-inactivo ya significa otra cosa: registro no vigente). */
.suite-tabla--ofertas tbody tr.suite-fila-cerrada { background: var(--c-superficie-cerrada); }

.suite-tabla__truncado {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.suite-tabla__truncado--140 { max-width: 140px; }
.suite-tabla__acciones .suite-btn { margin-left: var(--sp-1); }

/* Tablas de listado con muchas columnas (Ofertas 14, Tickets/Alertas 12,
   Tracer 11): sin un minimo, se aplastan hasta ilegibles en pantallas
   estrechas en vez de desbordar -- .suite-tabla-marco ya tiene
   overflow-x:auto para eso, pero necesita algo que desbordar. En movil
   esto es exactamente lo que hace scroll horizontal la tabla en vez de
   comprimir cada columna a la nada. */
.suite-tabla--ancha { min-width: 960px; }

/* --- Columnas fijas al desplazar (Aperturas: las 10 columnas propias
   de la apertura siempre visibles, el desglose de pedidos por
   proveedor se desliza al lado -- "inmovilizar paneles" de una hoja de
   cálculo). `.suite-tabla__fijo` es reutilizable por cualquier tabla
   ancha futura; el ancho/posición de cada columna es propio de
   Aperturas (27 columnas reales, no las 14 de Ofertas) y vive bajo
   `.suite-tabla--aperturas` para no arrastrar estos números a otra
   tabla. `width:100%` de `.suite-tabla` queda sustituido por `auto`:
   con table-layout:fixed y anchos en px (no %), la tabla debe poder
   crecer más allá del contenedor -- eso es lo que da el scroll
   horizontal real en vez de comprimir 27 columnas a la fuerza. */
.suite-tabla__fijo { position: sticky; z-index: 1; background: var(--c-superficie); }
.suite-tabla thead th.suite-tabla__fijo { z-index: 3; }
.suite-tabla tbody tr:hover td.suite-tabla__fijo { background: var(--c-superficie-sutil); }

/* Aperturas, tablero de trabajo (17-oct-2026): ya no es la hoja ancha
   del Excel (27 columnas con un bloque por proveedor fijo), sino 9
   columnas que caben sin desplazar. Toda la fila abre la ventana con la
   apertura completa (`data-abre-panel-lateral` en el <tr>). */
.ap-fila { cursor: pointer; }
.ap-fila:hover td, .ap-fila:focus-visible td { background: var(--c-superficie-sutil); }
.ap-fila--alerta td:first-child { box-shadow: inset 3px 0 0 var(--c-peligro); }
.ap-cuenta {
  display: inline-block; min-width: 1.5em; margin-left: var(--sp-1); padding: 0 var(--sp-1);
  border-radius: var(--r-sm); background: var(--c-superficie-sutil); color: var(--c-texto);
  font-family: var(--f-mono); font-size: var(--fs-xs); text-align: center;
}
.ap-fases { flex-wrap: wrap; }
.ap-fases .ap-fases--vacia { color: var(--c-texto-terciario); }

/* Ficha de la apertura: cabecera con fase y proximo paso, el proceso en
   una linea y dos columnas (proceso | tienda y contactos). La misma en la
   pagina completa y en la ventana del tablero. */
.ap-ficha__cabecera {
  display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--sp-3);
  padding-bottom: var(--sp-3); border-bottom: 1px solid var(--c-borde);
}
.ap-ficha__titulo { font-size: var(--fs-lg); }
.ap-ficha__paso { margin: var(--sp-2) 0 0; }
.ap-ficha__fechas, .ap-datos {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-6); margin: var(--sp-2) 0 0;
}
.ap-datos--columna { flex-direction: column; gap: var(--sp-2); }
.ap-dato dt { color: var(--c-texto-suave); font-size: var(--fs-xs); }
.ap-dato dd { margin: 0; }
.ap-proceso {
  display: flex; flex-wrap: wrap; gap: var(--sp-1); list-style: none; padding: 0; margin: var(--sp-3) 0;
  counter-reset: paso;
}
.ap-proceso__paso {
  counter-increment: paso; padding: var(--sp-1) var(--sp-2); border-radius: var(--r-sm);
  background: var(--c-superficie-sutil); color: var(--c-texto-terciario); font-size: var(--fs-sm);
}
.ap-proceso__paso::before { content: counter(paso) ". "; }
.ap-proceso__paso.es-hecho { background: var(--c-exito-bg); color: var(--c-exito); }
.ap-proceso__paso.es-actual { background: var(--c-primario); color: var(--c-texto-invertido); font-weight: var(--fw-semi); }
.ap-ficha__preparacion { flex-wrap: wrap; margin-bottom: var(--sp-3); }
.ap-compra + .ap-compra { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--c-borde-sutil); }
.ap-subtitulo { margin: var(--sp-4) 0 var(--sp-2); font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.ap-col-marcar { width: 32px; }
.ap-compra__cabecera, .ap-compra__estado, .ap-compra__pedido {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
}
.ap-compra__cabecera { justify-content: space-between; }
.ap-compra__estado { flex: 1 1 260px; min-width: 0; }
.ap-input-proveedor { width: 14em; min-width: 10em; max-width: 100%; }

/* Anchos por columna de Instalaciones (cxb, 12 columnas -- cabinet, nº
   de cabinets, nº de serie e instalador se quitaron de esta tabla,
   viven solo en el panel "Ver"). Mismo criterio que
   .suite-tabla--aperturas justo arriba. */
.suite-tabla--instalaciones { width: auto; }
.suite-tabla--instalaciones .ci-col-fecha        { width: 90px;  left: 0; }
.suite-tabla--instalaciones .ci-col-sucursal     { width: 220px; left: 90px; }
.suite-tabla--instalaciones .ci-col-formato      { width: 140px; left: 310px; border-right: 2px solid var(--c-borde); }
.suite-tabla--instalaciones .ci-col-hora         { width: 70px; }
.suite-tabla--instalaciones .ci-col-pedido       { width: 90px; }
.suite-tabla--instalaciones .ci-col-entregado    { width: 90px; }
.suite-tabla--instalaciones .ci-col-packing      { width: 110px; }
.suite-tabla--instalaciones .ci-col-factura      { width: 110px; }
.suite-tabla--instalaciones .ci-col-albaran      { width: 110px; }
.suite-tabla--instalaciones .ci-col-notas        { width: 160px; }
.suite-tabla--instalaciones .ci-col-intervenciones { width: 110px; }
.suite-tabla--instalaciones .ci-col-acciones     { width: 70px; }

/* Filas alternas + fila "cerrada" (entregado) -- mismo patron que
   .suite-tabla--ofertas (suite-fila-cerrada ahi es "facturada"; aqui
   es "entregado", mismo significado: ya no hay nada pendiente). Las
   celdas fijas (.suite-tabla__fijo) traen su propio fondo solido para
   tapar el contenido que se desliza por debajo -- sin estas reglas
   extra se quedarian siempre con el fondo base, sin alternar ni
   marcar "cerrada" igual que el resto de la fila. */
.suite-tabla--instalaciones tbody tr:nth-child(even) { background: var(--c-fondo); }
.suite-tabla--instalaciones tbody tr:nth-child(even) td.suite-tabla__fijo { background: var(--c-fondo); }
.suite-tabla--instalaciones tbody tr:hover { background: var(--c-superficie-sutil); }
.suite-tabla--instalaciones tbody tr:hover td.suite-tabla__fijo { background: var(--c-superficie-sutil); }
.suite-tabla--instalaciones tbody tr.suite-fila-cerrada { background: var(--c-superficie-cerrada); }
.suite-tabla--instalaciones tbody tr.suite-fila-cerrada td.suite-tabla__fijo { background: var(--c-superficie-cerrada); }

.suite-distintivo {
  display: inline-flex; align-items: center; padding: 2px var(--sp-2); white-space: nowrap;
  border-radius: var(--r-sm); font-size: var(--fs-2xs); font-weight: var(--fw-semi);
  text-transform: uppercase; letter-spacing: .04em;
}
.suite-distintivo--ok      { background: var(--c-exito-bg);   color: var(--c-exito); }
.suite-distintivo--gris    { background: var(--c-superficie-sutil); color: var(--c-texto-suave); }
.suite-distintivo--aviso   { background: var(--c-aviso-bg);   color: var(--c-aviso); }
.suite-distintivo--peligro { background: var(--c-peligro-bg); color: var(--c-peligro); }
.suite-distintivo--morado  { background: var(--c-morado-bg);  color: var(--c-morado); }
.suite-distintivo--info    { background: var(--c-info-bg);    color: var(--c-info); }

/* --- Edición inline (E05.07, primera pieza de B4) --------------------
   Celda de tabla editable sin abrir otra página. El borde del input es
   visible en reposo (no solo al pasar el ratón/enfocar): con muchas
   columnas editables seguidas, un campo transparente hasta el hover no
   se distingue de una celda de solo lectura -- corregido tras verificar
   el panel real en navegador. */
.suite-editable { display: flex; align-items: center; gap: var(--sp-1); flex-wrap: nowrap; min-width: 0; }
.suite-editable--centrado { justify-content: center; }
/* El input es lo unico que debe repartirse el espacio libre -- cualquier
   otro hijo directo (marcador *, enlace a ticket vinculado, estado del
   guardado) se queda a su tamano natural, o compite por sitio y gana el
   que menos se puede permitir perder (visto en la columna TASK). */
.suite-editable > span, .suite-editable > a { flex-shrink: 0; }
.suite-editable__input {
  font-family: inherit; font-size: var(--fs-xs); color: var(--c-texto); min-width: 0;
}
.suite-editable__input:not([type="checkbox"]) {
  flex: 1 1 auto; min-width: 32px;
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--c-borde); border-radius: var(--r-sm);
  background: var(--c-superficie-entrada);
  transition: border-color var(--dur-rapido) var(--ease-defecto);
}
/* Enlace compacto a una entidad vinculada (p.ej. el ticket de la columna
   TASK): solo la flecha, nunca el codigo entero -- el codigo completo
   sigue disponible en el title al pasar el raton. "Que sea clicable basta,
   no hace falta que se lea entero en la celda" (feedback del mantenedor). */
.suite-editable__enlace {
  color: var(--c-primario); text-decoration: none;
  font-weight: var(--fw-semi); font-size: var(--fs-sm); line-height: 1;
}
.suite-editable__enlace:hover { text-decoration: underline; }
.suite-editable__input:not([type="checkbox"]):hover { border-color: var(--c-primario); }
.suite-editable__input:not([type="checkbox"]):focus-visible {
  outline: none; border-color: var(--c-primario); background: var(--c-superficie-entrada);
  box-shadow: 0 0 0 2px var(--c-primario-suave);
}
.suite-editable__input[type="checkbox"] { width: 16px; height: 16px; }
.suite-editable__input[readonly], .suite-editable__input[disabled] { opacity: .6; }
.suite-editable__estado {
  font-size: var(--fs-xs); color: var(--c-texto-suave); white-space: nowrap;
}
.suite-editable__estado.es-ok    { color: var(--c-exito); }
.suite-editable__estado.es-error { color: var(--c-peligro); }
.suite-editable__personalizado.es-oculto { display: none; }
/* Autoguardado (ADR-042, 2.109): el boton de guardar se oculta y en su
   sitio se ve si se ha guardado. */
.es-oculto { display: none !important; }
/* Formularios de «añadir» de las fichas, plegados tras su boton (2.110) */
.suite-plegable { margin: var(--sp-2) 0 var(--sp-3); }
.suite-plegable > summary { list-style: none; cursor: pointer; }
.suite-plegable > summary::-webkit-details-marker { display: none; }
.suite-plegable[open] > summary { margin-bottom: var(--sp-2); }
.suite-autoguardado {
  display: inline-block; min-height: 1.4em; font-size: var(--fs-xs); color: var(--c-texto-suave);
  margin-left: var(--sp-2);
}
.suite-autoguardado.es-ok    { color: var(--c-exito); }
.suite-autoguardado.es-error { color: var(--c-peligro); font-weight: var(--fw-semi); }
/* Textos largos sin espacios (rutas del share, enlaces, codigos) no
   ensanchan las tablas de una ficha (descuadre del desplegable, 2.109) */
.ap-ficha .suite-tabla td { overflow-wrap: anywhere; }

/* --- Estado automatico de oferta (E05.07) — 9 colores, uno por estado,
   igual que el codigo real (ea-badge/ea-fact/ea-pfact/...). Paleta propia
   de estado (identidad visual v2.0 §4.3): nunca el indigo de marca, para
   que un estado no se confunda con cromo de interfaz. */
.suite-distintivo--pdte-aprobacion { background: var(--c-pdte-aprobacion-bg); color: var(--c-pdte-aprobacion); }
.suite-distintivo--pdte-sat        { background: var(--c-pdte-sat-bg);        color: var(--c-pdte-sat); }
.suite-distintivo--pdte-compra     { background: var(--c-pdte-compra-bg);     color: var(--c-pdte-compra); }
.suite-distintivo--pdte-tracer     { background: var(--c-pdte-tracer-bg);     color: var(--c-pdte-tracer); }
.suite-distintivo--pdte-facturar   { background: var(--c-pdte-facturar-bg);   color: var(--c-pdte-facturar); }
.suite-distintivo--facturada       { background: var(--c-superficie-sutil); color: var(--c-facturada); }
.suite-distintivo--cancelado       { background: var(--c-superficie-sutil); color: var(--c-cancelado); }
/* Rentabilidad DIA E1: rechazo del cliente y ofertas «L» del Tracker sin clasificar */
.suite-distintivo--rechazada        { background: var(--c-peligro-bg); color: var(--c-peligro); }
.suite-distintivo--l-sin-clasificar { background: var(--c-aviso-bg); color: var(--c-aviso); }
/* --c-lanzado/--c-enviado (tokens.css) quedan definidos para Tickets, que
   ya usa esos dos textos de estado, pero ningun badge los consume todavia
   -- no se construye el componente que nadie pide aun (N-76). */

/* --- Badge P/W ciclable (E05.07): boton, no solo texto -- un clic pasa
   al siguiente estado. */
.suite-pw {
  border: none; cursor: pointer; font-family: var(--f-mono);
  padding: 1px var(--sp-2); border-radius: var(--r-sm);
  font-size: var(--fs-xs); font-weight: var(--fw-medio);
}
.suite-pw--p { background: var(--c-borde); color: var(--c-aviso); }
.suite-pw--w { background: var(--c-borde); color: var(--c-exito); }
.suite-pw--n { background: var(--c-borde); color: var(--c-texto-suave); }

/* --- Icono de PDF de bono SAP (E05.07) -------------------------------
   SVG con stroke="currentColor" en vez del emoji anterior (📎): un emoji
   se pinta con su propia paleta fija y no responde a `color`, así que el
   verde/gris de .es-con-pdf nunca se veía -- "para diferenciarlo" (el
   mantenedor) exigía un trazo que sí siga el color del span. */
.sap-icono { cursor: pointer; color: var(--c-texto-suave); }
.sap-icono svg { display: block; }
.sap-icono.es-con-pdf { color: var(--c-exito); }

/* --- Color del campo TRACER segun el estado del parte (E05.07) ------- */
.suite-editable__input--tracer-cancelado  { color: var(--c-peligro); font-weight: var(--fw-semi); }
.suite-editable__input--tracer-completado { color: var(--c-exito);   font-weight: var(--fw-semi); }
.suite-editable__input--tracer-en-curso   { color: var(--c-aviso);   font-weight: var(--fw-semi); }
.suite-editable__input--tracer-sin-info   { color: var(--c-texto-suave); }

/* --- Modal minimo (E05.07, primera pieza que de verdad lo necesita:
   conflictos de TASK, PDF de bono SAP, facturacion) -------------------- */
.suite-modal {
  display: none; position: fixed; inset: 0; z-index: var(--z-modal);
  background: var(--c-superposicion); backdrop-filter: blur(4px);
  align-items: center; justify-content: center; padding: var(--sp-4);
}
.suite-modal.es-visible { display: flex; }
.suite-modal__caja {
  background: var(--c-superficie); border: 1px solid var(--c-borde);
  border-radius: var(--r-2xl); box-shadow: var(--sh-lg);
  padding: var(--sp-6); width: 100%; max-width: 560px; max-height: 85vh; overflow-y: auto;
}
.suite-modal__caja--ancha { max-width: 760px; }
.suite-modal__cabecera {
  display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-4);
}
.suite-modal__cabecera button {
  background: none; border: 0; font-size: var(--fs-lg); color: var(--c-texto-suave); cursor: pointer;
}
.suite-modal__cuerpo > * + * { margin-top: var(--sp-3); }
.suite-modal__pie { display: flex; gap: var(--sp-3); margin-top: var(--sp-5); flex-wrap: wrap; }
.suite-modal__rejilla { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
@media (max-width: 639px) {
  .suite-modal__rejilla { grid-template-columns: 1fr; }
}

/* --- Barra de estadisticas densa (E05.07): franja horizontal con scroll,
   a diferencia de .suite-tarjeta (pensada para 4-5 KPIs, no para 19). */
.suite-estadisticas {
  display: flex; overflow-x: auto; background: var(--c-superficie);
  border: 1px solid var(--c-borde); border-radius: var(--r-lg); margin-bottom: var(--sp-6);
}
.suite-estadisticas__item {
  padding: var(--sp-2) var(--sp-4); border-right: 1px solid var(--c-borde);
  font-family: var(--f-mono); font-size: var(--fs-xs); color: var(--c-texto-suave);
  white-space: nowrap; flex-shrink: 0;
}
.suite-estadisticas__item:last-child { border-right: none; }
.suite-estadisticas__item strong {
  display: block; font-size: var(--fs-base); font-weight: var(--fw-semi);
  font-family: var(--f-sans); color: var(--c-texto); margin-bottom: 1px;
}
.suite-estadisticas__item--exito strong   { color: var(--c-exito); }
.suite-estadisticas__item--aviso strong   { color: var(--c-aviso); }
.suite-estadisticas__item--peligro strong { color: var(--c-peligro); }
.suite-estadisticas__item--morado strong  { color: var(--c-morado); }
.suite-estadisticas__item--primario strong{ color: var(--c-primario); }

/* --- Fila de filtros compacta (E05.07): mas densa que .suite-formulario
   generico -- son 12 controles, no un formulario de alta. */
.suite-filtros {
  display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center;
  margin-bottom: var(--sp-4);
}
.suite-filtros select, .suite-filtros input {
  padding: var(--sp-1) var(--sp-2); font-size: var(--fs-xs);
  border: 1px solid var(--c-borde); border-radius: var(--r-sm);
  background: var(--c-superficie); color: var(--c-texto);
}
.suite-filtros__busqueda { width: 210px; max-width: 100%; }
.suite-filtros__busqueda-larga { width: 320px; max-width: 100%; }
.suite-filtros__material { width: 185px; max-width: 100%; }

/* --- Sidebar de filtros verticales (E05.08, Incidencias) ------------- */
.suite-panel-filtros { display: flex; gap: var(--sp-6); align-items: flex-start; }
.suite-sidebar-filtros {
  width: 200px; flex-shrink: 0;
  background: var(--c-superficie); border: 1px solid var(--c-borde);
  border-radius: var(--r-lg); padding: var(--sp-4);
}
.suite-sidebar-filtros__titulo {
  font-size: var(--fs-xs); font-weight: var(--fw-semi); text-transform: uppercase;
  letter-spacing: .06em; color: var(--c-texto-suave);
  margin: var(--sp-4) 0 var(--sp-2);
}
.suite-sidebar-filtros__titulo:first-child { margin-top: 0; }
.suite-sidebar-filtros label {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); padding: var(--sp-1) 0; cursor: pointer;
}
/* `select`/`input[type=date]` sueltos (fuera de `.suite-campo`, que ya
   los viste): sin esta regla el navegador les da su ancho nativo segun
   el texto de la opcion mas larga, que puede superar los 200px del
   sidebar y desbordar la caja -- le paso exacto a Formato Recomendado
   en Visitas Previas (cxb), con el mismo hueco heredado en Tickets
   (dia). Mismos tokens que `.suite-campo select` para que ambos
   contextos se vean como el mismo control. */
.suite-sidebar-filtros select,
.suite-sidebar-filtros input[type="date"] {
  display: block; width: 100%; max-width: 100%; box-sizing: border-box;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--c-borde); border-radius: var(--r-sm);
  background: var(--c-superficie-entrada); color: var(--c-texto);
  font-family: inherit; font-size: var(--fs-sm);
}
.suite-sidebar-filtros select {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.suite-sidebar-filtros select:focus-visible,
.suite-sidebar-filtros input[type="date"]:focus-visible {
  outline: none; border-color: var(--c-primario);
  box-shadow: 0 0 0 2px var(--c-primario-suave);
}
.suite-panel-filtros__contenido { flex: 1; min-width: 0; }
@media (max-width: 767px) {
  .suite-panel-filtros { flex-direction: column; gap: var(--sp-4); }
  .suite-sidebar-filtros { width: 100%; }
}

/* --- Badges de SLA (E05.08) — pill compacta, reutiliza tokens ya
   existentes (nada nuevo que anadir a tokens.css). */
.suite-sla {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px var(--sp-2);
  border-radius: var(--r-pill); font-size: var(--fs-2xs); font-weight: var(--fw-medio);
  font-family: var(--f-mono);
}
.suite-sla--ok    { background: var(--c-exito-bg);   color: var(--c-exito); }
.suite-sla--warn  { background: var(--c-aviso-bg);   color: var(--c-aviso); }
.suite-sla--ko    { background: var(--c-peligro-bg); color: var(--c-peligro); }
.suite-sla--na    { background: var(--c-superficie-sutil); color: var(--c-texto-suave); }

/* --- Dashboard (E05.09): tarjetas KPI, graficos canvas y paneles
   colapsables de anomalias, sobre los mismos tokens de siempre. */
.suite-kpi-grid {
  /* auto-fit: las tarjetas se reparten TODO el ancho (ancho completo,
     12-oct-2026); con auto-fill quedaban columnas vacias a la derecha. */
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--sp-3); margin-bottom: var(--sp-6);
}
.suite-kpi {
  position: relative; overflow: hidden;
  background: var(--c-superficie); border: 1px solid var(--c-borde);
  border-radius: var(--r-md); padding: var(--sp-4);
  box-shadow: var(--sh-sm);
}
.suite-kpi::before {
  content: ""; position: absolute; top: 0; left: 0; width: 3px; height: 100%;
  background: var(--c-texto-suave);
}
.suite-kpi--clicable { cursor: pointer; }
.suite-kpi__valor {
  font-family: var(--f-mono); font-size: var(--fs-2xl); font-weight: var(--fw-semi);
  margin-bottom: 2px; color: var(--c-texto);
}
.suite-kpi__etiqueta { font-size: var(--fs-sm); color: var(--c-texto); }
.suite-kpi__subtitulo {
  font-family: var(--f-mono); font-size: var(--fs-xs); color: var(--c-texto-suave);
  margin-top: 3px;
}
.suite-kpi__exportar {
  position: absolute; top: 5px; right: 5px;
  font-size: var(--fs-xs); font-family: var(--f-mono);
  padding: 1px 4px; border: 1px solid var(--c-borde); border-radius: var(--r-sm);
  color: var(--c-texto-suave);
}
.suite-kpi--primario::before { background: var(--c-primario); }
.suite-kpi--primario .suite-kpi__valor { color: var(--c-primario); }
.suite-kpi--aviso::before { background: var(--c-aviso); }
.suite-kpi--aviso .suite-kpi__valor { color: var(--c-aviso); }
.suite-kpi--exito::before { background: var(--c-exito); }
.suite-kpi--exito .suite-kpi__valor { color: var(--c-exito); }
.suite-kpi--peligro::before { background: var(--c-peligro); }
.suite-kpi--peligro .suite-kpi__valor { color: var(--c-peligro); }
.suite-kpi--morado::before { background: var(--c-morado); }
.suite-kpi--morado .suite-kpi__valor { color: var(--c-morado); }
.suite-kpi--rosa::before { background: var(--c-rosa); }
.suite-kpi--rosa .suite-kpi__valor { color: var(--c-rosa); }
/* El resumen PDTE de Ofertas (E05.07, mejora posterior) reutiliza la
   tarjeta KPI como enlace filtrado en vez de como div de solo lectura. */
a.suite-kpi { display: block; text-decoration: none; color: inherit; }

/* Cabecera compacta de un listado (Ofertas): el resumen PDTE + los
   botones de accion en la misma fila, sin titulo de pagina (el propio
   listado ya dice de que pantalla se trata) ni el aire de una tarjeta
   de dashboard -- aqui son 5-9 numeros de un vistazo, no el punto focal
   de la pantalla. Modificadores aparte de .suite-kpi/-grid para no
   encoger las tarjetas reales del Dashboard (E05.09), que si necesitan
   ese tamano. */
.suite-resumen-acciones { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.suite-resumen-acciones > .suite-kpi-grid { flex: 1 1 auto; margin-bottom: 0; }
/* auto-fit, no auto-fill: con pocas tarjetas (5, el resumen PDTE) y sitio
   de sobra, auto-fill sigue creando columnas vacias que se quedan con su
   parte de hueco -- auto-fit las colapsa a 0 y dejar que las tarjetas
   reales se repartan el ancho entero hasta la caja de acciones. */
.suite-kpi-grid--compacta { grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: var(--sp-2); }
.suite-kpi--compacta { padding: var(--sp-1) var(--sp-2); }
.suite-kpi--compacta .suite-kpi__valor { font-size: var(--fs-lg); margin-bottom: 0; }
.suite-kpi--compacta .suite-kpi__etiqueta { font-size: var(--fs-2xs); }
/* Caja de acciones: mismo lenguaje visual que una tarjeta KPI (borde,
   fondo, sombra), sin la franja de color -- no es una categoria, es un
   grupo de botones. */
.suite-caja-acciones {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3); background: var(--c-superficie);
  border: 1px solid var(--c-borde); border-radius: var(--r-md); box-shadow: var(--sh-sm);
}

.suite-graficos {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--sp-3); margin-bottom: var(--sp-6);
}
.suite-grafico {
  background: var(--c-superficie); border: 1px solid var(--c-borde);
  border-radius: var(--r-md); padding: var(--sp-3);
}
.suite-grafico__titulo {
  font-family: var(--f-mono); font-size: var(--fs-xs); text-transform: uppercase;
  letter-spacing: .06em; color: var(--c-texto-suave); margin-bottom: var(--sp-3);
}
.suite-grafico__cuerpo { display: flex; align-items: center; gap: var(--sp-3); }
.suite-grafico__leyenda { font-size: var(--fs-xs); display: flex; flex-direction: column; gap: 4px; }
.suite-grafico__leyenda-fila { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
.suite-grafico__leyenda-punto {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; display: inline-block;
}

.suite-panel-colapsable {
  background: var(--c-superficie); border: 1px solid var(--c-borde);
  border-radius: var(--r-md); overflow: hidden; margin-bottom: var(--sp-3);
}
.suite-panel-colapsable__cabecera {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--c-borde);
  font-family: var(--f-mono); font-size: var(--fs-xs); color: var(--c-texto);
}
.suite-panel-colapsable__titulo { display: flex; align-items: center; gap: var(--sp-2); }
.suite-panel-colapsable__punto {
  width: 7px; height: 7px; border-radius: 50%; display: inline-block; flex-shrink: 0;
}
.suite-panel-colapsable__acciones { display: flex; align-items: center; gap: var(--sp-2); }
.suite-panel-colapsable__contador { font-family: var(--f-mono); font-size: var(--fs-lg); font-weight: var(--fw-semi); }
.suite-panel-colapsable__cuerpo { max-height: 260px; overflow: auto; }

/* --- Documentacion de modulo (<details> nativo, sin JS -- se abre y
   cierra solo con el navegador, no necesita data-componente). */
.suite-documentacion {
  background: var(--c-superficie); border: 1px solid var(--c-borde);
  border-radius: var(--r-lg); margin-bottom: var(--sp-4);
}
.suite-documentacion__resumen {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4); cursor: pointer;
  font-weight: var(--fw-medio); list-style: none;
}
.suite-documentacion__resumen::-webkit-details-marker { display: none; }
.suite-documentacion__resumen::before {
  content: "▸"; color: var(--c-texto-suave); display: inline-block;
  transition: transform var(--dur-rapido) var(--ease-defecto);
}
.suite-documentacion[open] .suite-documentacion__resumen::before { transform: rotate(90deg); }
.suite-documentacion__cuerpo {
  padding: 0 var(--sp-4) var(--sp-4); border-top: 1px solid var(--c-borde);
}
.suite-documentacion__cuerpo h3 {
  font-size: var(--fs-sm); font-weight: var(--fw-semi); margin: var(--sp-4) 0 var(--sp-1);
}
.suite-documentacion__cuerpo h3:first-child { margin-top: var(--sp-3); }
.suite-documentacion__cuerpo p {
  margin: 0 0 var(--sp-2); color: var(--c-texto-suave); font-size: var(--fs-sm); line-height: 1.5;
}
.suite-documentacion__cuerpo dl { margin: 0; }
.suite-documentacion__cuerpo dt { font-weight: var(--fw-medio); font-size: var(--fs-sm); margin-top: var(--sp-2); }
.suite-documentacion__cuerpo dd {
  margin: 0 0 var(--sp-1); color: var(--c-texto-suave); font-size: var(--fs-sm);
}

/* --- Zonas (E05.10): fila de cabecera de grupo dentro de una tabla. */
.suite-tabla__grupo td {
  background: var(--c-fondo); color: var(--c-texto-suave);
  font-size: var(--fs-xs); font-weight: var(--fw-semi); text-transform: uppercase;
  letter-spacing: .06em; padding: var(--sp-1) var(--sp-3);
}

/* --- Informe imprimible (E05.10): página sin cabecera/menú (block
   cascaron vacío), pensada para Ctrl+P / exportar a PDF desde el propio
   navegador. */
.suite-informe {
  max-width: 900px; margin: 0 auto; padding: var(--sp-8) var(--sp-6);
  color: var(--c-texto); font-family: var(--f-sans);
  min-width: 0;            /* hijo del body flex: que pueda encoger (2.113) */
}
@media (max-width: 479px) { .suite-informe { padding: var(--sp-4) var(--sp-3); } }
.suite-informe__cabecera { margin-bottom: var(--sp-6); }
.suite-informe__titulo { margin: 0 0 var(--sp-1); font-size: var(--fs-xl); font-weight: var(--fw-semi); }
.suite-informe__meta { color: var(--c-texto-suave); font-size: var(--fs-sm); }
.suite-informe__grupo {
  margin: var(--sp-6) 0 var(--sp-2); font-size: var(--fs-base); font-weight: var(--fw-semi);
  border-bottom: 1px solid var(--c-borde); padding-bottom: var(--sp-2);
}
.suite-informe__acciones { margin-bottom: var(--sp-6); }
@media print {
  .suite-informe__acciones { display: none; }
  .suite-informe { max-width: none; padding: 0; }
}

/* Informe A4 horizontal (Garantias, T9): pagina con nombre para no
   afectar al resto de informes (Zonas sigue en vertical, por defecto,
   sin tocarlo) -- `@page` no admite scoping por clase directamente,
   `page:` en el elemento si asigna esa pagina con nombre solo a el. */
@page suite-informe-horizontal { size: A4 landscape; margin: 1.2cm; }
.suite-informe--horizontal { page: suite-informe-horizontal; }
.suite-informe__grupo--salto:not(:first-of-type) { break-before: page; }

/* --- Acceso ---------------------------------------------------------- */
.suite-acceso {
  display: grid; place-items: center; min-height: 100vh;
  background: var(--c-fondo);
}
@supports (height: 100dvh) { .suite-acceso { min-height: 100dvh; } }
.suite-acceso__marco { width: 100%; max-width: 400px; padding: var(--sp-4); }
.suite-acceso__tarjeta {
  background: var(--c-superficie);
  border: 1px solid var(--c-borde); border-radius: var(--r-lg);
  box-shadow: var(--sh-md); padding: var(--sp-8);
}
.suite-acceso__tarjeta--centro { text-align: center; }
.suite-acceso__marca {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-2);
  margin-bottom: var(--sp-6);
}
.suite-acceso__titulo {
  margin: 0 0 var(--sp-6); font-size: var(--fs-xl);
  font-weight: var(--fw-semi); text-align: center;
}
.suite-acceso__pie {
  margin: var(--sp-4) 0 0; text-align: center;
  font-size: var(--fs-xs); color: var(--c-texto-suave); font-family: var(--f-mono);
}

/* --- Pie ------------------------------------------------------------- */
.suite-pie {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-2);
  padding: var(--sp-4);
  border-top: 1px solid var(--c-borde);
  color: var(--c-texto-suave); font-size: var(--fs-xs);
}
.suite-pie__sep { opacity: .5; }

/* --- Módulo en desarrollo -------------------------------------------- */
.suite-desarrollo {
  padding: var(--sp-12); text-align: center;
  background: var(--c-superficie);
  border: 1px dashed var(--c-borde); border-radius: var(--r-lg);
}
.suite-desarrollo__icono { color: var(--c-texto-suave); margin-bottom: var(--sp-4); }
.suite-desarrollo__titulo { margin: 0 0 var(--sp-2); font-size: var(--fs-xl); font-weight: var(--fw-semi); }
.suite-desarrollo__texto { margin: 0; color: var(--c-texto-suave); }

/* --- Panel lateral de detalle (E05.07, mejora posterior — Ofertas):
   "Ver" ya no navega a otra pagina, inyecta el fragmento `panel()` aqui
   dentro. Colapsado por defecto (ancho 0) para que no ocupe espacio;
   `.es-visible` lo abre y el listado se encoge porque ambos viven en el
   mismo contenedor flex `.suite-listado-panel`. */
.suite-listado-panel { display: flex; align-items: flex-start; }
.suite-listado-panel__principal { flex: 1 1 auto; min-width: 0; }
.suite-panel-lateral {
  flex: 0 0 0; width: 0; overflow: hidden;
  background: var(--c-superficie); border: 1px solid var(--c-borde); border-radius: var(--r-xl);
  box-shadow: var(--sh-lg);
  transition: flex-basis var(--dur-rapido) var(--ease-defecto),
              width var(--dur-rapido) var(--ease-defecto),
              margin-left var(--dur-rapido) var(--ease-defecto);
}
.suite-panel-lateral:not(.es-visible) { border-width: 0; box-shadow: none; }
.suite-panel-lateral.es-visible {
  flex: 0 0 420px; width: 420px; margin-left: var(--sp-4);
  /* El listado puede ser mas alto que la pantalla; el panel no debe
     crecer con el ni forzar scroll de pagina -- se queda pegado cerca
     de arriba y, si su propio contenido no cabe, desplaza por dentro.
     88px = 56px de .suite-cabecera + var(--sp-8) de .suite-contenido. */
  position: sticky; top: var(--sp-4);
  max-height: calc(100vh - 88px - var(--sp-4));
  overflow-y: auto;
  /* Sin esto, max-height NO se respeta: los hijos de un contenedor flex
     (.suite-listado-panel) parten de min-height:auto -- "al menos tan
     alto como mi contenido" -- que gana por delante de max-height. Gotcha
     clasico de flexbox, no un descuido de calculo. */
  min-height: 0;
}
/* width:100%, no 420px fijo -- el ancho real lo decide el contenedor
   (.suite-panel-lateral), que en movil se limita a 100vw (mas abajo). Con
   un ancho fijo aqui, el panel desbordaba por dentro aunque el contenedor
   ya estuviera correctamente acotado a la pantalla. */
.suite-panel-lateral__interior { width: 100%; padding: var(--sp-2); }
.suite-panel-lateral__cabecera {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3);
  margin-bottom: var(--sp-2); padding-bottom: var(--sp-1); border-bottom: 1px solid var(--c-borde);
  font-size: var(--fs-sm);
}

/* Panel lateral que flota sobre el contenido en vez de encogerlo
   (calendarios, global y el propio de Instalaciones cxb -- peticion del
   mantenedor: la rejilla de un calendario no debe perder ancho al abrir
   el detalle de una entrada, a diferencia de una tabla, que si puede
   encoger razonablemente para hacerle sitio). Mismo tratamiento que el
   panel ya usa en movil (position:fixed, bloque de abajo), aplicado aqui
   a cualquier ancho de pantalla -- solo a los contenedores marcados con
   este modificador; el resto de .suite-panel-lateral (Ofertas, Tracer,
   Aperturas, el propio listado de Instalaciones) sigue encogiendo la
   columna principal como hasta ahora. Tres clases a proposito (mas
   especifico que la regla base .suite-panel-lateral.es-visible de
   arriba y que la de movil, ambas dos clases), para no depender del
   orden de aparicion en la hoja de estilos. */
.suite-panel-lateral.suite-panel-lateral--flotante.es-visible {
  position: fixed; inset: 56px var(--sp-4) auto auto; z-index: var(--z-modal);
  width: min(420px, calc(100vw - 2 * var(--sp-4))); margin-left: 0;
  max-height: calc(100vh - 56px - var(--sp-8)); overflow-y: auto;
  box-shadow: var(--sh-lg);
}


/* --- Adaptación a pantalla ------------------------------------------- */
@media (max-width: 1023px) {
  .suite-boton-menu { display: flex; }
  .suite-lateral {
    position: fixed; inset: 56px auto 0 0; z-index: var(--z-modal);
    transform: translateX(-100%); transition: transform var(--dur-rapido) var(--ease-defecto);
    box-shadow: var(--sh-md);
  }
  .suite-lateral.es-visible { transform: translateX(0); }
  .suite-contenido { padding: var(--sp-6) var(--sp-4); }
  /* .suite-app--tabla-fija fija el body a 100vh/overflow:hidden para que
     solo la tabla desplace por dentro -- pensado para pantallas grandes
     con aire de sobra por encima y por debajo del listado. Por debajo de
     este ancho no hay ese aire: en Tickets, cuyo panel de filtros
     verticales (.suite-panel-filtros, columna en movil) ya supera el alto
     disponible el solo, el reparto flex dejaba el contenido -- la tabla
     entera -- a 0px de alto (medido con Playwright en movil, no una
     suposicion). Mas fiable que parchear pantalla a pantalla: por debajo
     de este ancho toda pagina --tabla-fija vuelve a ser una pagina normal
     que se desplaza entera, igual que cualquier otra. */
  .suite-app--tabla-fija { height: auto; overflow: visible; }
  .suite-app--tabla-fija .suite-contenido { display: block; overflow: visible; }
  .suite-app--tabla-fija .suite-listado-panel { display: block; }
  .suite-app--tabla-fija .suite-panel-filtros { display: block; }
  .suite-panel-lateral.es-visible {
    position: fixed; inset: 56px 0 0 auto; z-index: var(--z-modal);
    flex-basis: min(420px, 100vw); width: min(420px, 100vw);
    margin-left: 0; border-radius: 0; box-shadow: var(--sh-md);
    /* La base .suite-panel-lateral trae overflow:hidden (para la
       transicion de ancho en desktop) -- en movil el panel ya esta
       acotado a la pantalla por el inset de arriba, asi que un
       contenido mas alto que eso debe desplazarse por dentro, no
       recortarse en silencio. */
    max-height: none; overflow-y: auto;
  }
}
/* Calendario de Instalaciones (cxb) -- vista de mes/semana, primera
   rejilla de fechas de la Suite. Reutiliza .suite-listado-panel/
   .suite-panel-lateral ya existentes para el panel lateral de detalle;
   esto es solo la rejilla y las tarjetas de cada dia.

   Pase de compacidad (20 ago 2026, a peticion directa del mantenedor:
   "ocupa demasiado, hazlo mas visual"): altura de fila reducida +
   maximo 3 tarjetas por dia en vista de mes (con enlace "+N mas" a la
   semana, en vez de dejar que un dia cargado estire toda la fila del
   mes -- ninguna rejilla de calendario real deja crecer sin limite),
   acento de color por estado en vez de un glifo aparte (mas facil de
   escanear de un vistazo), sucursal y hora en la misma linea. */
.suite-calendario__nav {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  margin-bottom: var(--sp-3); flex-wrap: wrap;
}
.suite-calendario__nav .suite-filtros { margin-bottom: 0; }
.suite-calendario__titulo { font-size: var(--fs-base); min-width: 11ch; }
.suite-calendario { border: 1px solid var(--c-borde); border-radius: var(--r-lg); overflow: hidden; }
.suite-calendario__cabecera-dias {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  background: var(--c-superficie-alta); border-bottom: 1px solid var(--c-borde);
}
.suite-calendario__cabecera-dias span {
  padding: var(--sp-1) var(--sp-2); text-align: center;
  font-size: var(--fs-2xs); font-weight: var(--fw-semi); color: var(--c-texto-suave);
  text-transform: uppercase; letter-spacing: .04em;
}
.suite-calendario__fila { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.suite-calendario__fila + .suite-calendario__fila { border-top: 1px solid var(--c-borde); }
.suite-calendario__dia {
  min-width: 0; min-height: 68px; padding: var(--sp-1) var(--sp-1) var(--sp-2);
  border-left: 1px solid var(--c-borde);
}
.suite-calendario__dia:first-child { border-left: none; }
.suite-calendario__dia.es-otro-mes { background: var(--c-superficie-alta); color: var(--c-texto-terciario); }
.suite-calendario__dia.es-otro-mes .suite-calendario__numero { color: var(--c-texto-terciario); }
.suite-calendario__numero {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 var(--sp-1);
  font-size: var(--fs-xs); font-weight: var(--fw-medio); border-radius: var(--r-pill);
}
.suite-calendario__dia.es-hoy .suite-calendario__numero {
  background: var(--c-primario); color: var(--c-superficie); font-weight: var(--fw-semi);
}
.suite-calendario__chips { display: flex; flex-direction: column; gap: 3px; margin-top: 3px; }
.suite-calendario__mas {
  font-size: var(--fs-2xs); color: var(--c-texto-suave); text-decoration: none;
  padding: 1px var(--sp-1);
}
.suite-calendario__mas:hover { color: var(--c-primario); text-decoration: underline; }

.suite-calendario--semana { display: grid; grid-template-columns: repeat(7, 1fr); }
.suite-calendario__columna { padding: var(--sp-2); border-left: 1px solid var(--c-borde); min-height: 320px; }
.suite-calendario__columna:first-child { border-left: none; }
.suite-calendario__columna.es-hoy { background: var(--c-primario-suave); }
.suite-calendario__cabecera-columna {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: var(--sp-2); padding-bottom: var(--sp-1);
  border-bottom: 1px solid var(--c-borde); font-size: var(--fs-xs); color: var(--c-texto-suave);
}

.suite-calendario__chip {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--c-superficie); border: 1px solid var(--c-borde-sutil);
  border-left: 3px solid var(--c-cliente, var(--c-borde-sutil)); border-radius: var(--r-sm);
  padding: 3px var(--sp-2); font-family: inherit; font-size: var(--fs-2xs); color: var(--c-texto);
  transition: border-color var(--dur-rapido) var(--ease-defecto), box-shadow var(--dur-rapido) var(--ease-defecto);
}
.suite-calendario__chip:hover { border-color: var(--c-primario); box-shadow: var(--sh-sm); }
/* Calendario global (ADR-041): rojo = alerta; atenuado = ya hecho */
a.suite-calendario__chip { text-decoration: none; color: inherit; display: block; }
.suite-calendario__chip--alerta { box-shadow: inset 3px 0 0 var(--c-peligro); }
.suite-calendario__chip-tracer { overflow-wrap: anywhere; }
/* Movil: en el mes, cada dia dice cuantos eventos tiene (la lista «Lo que
   viene», debajo, da el detalle); los chips no caben en 1/7 de pantalla. */
.suite-calendario__cuenta { display: none; }
.suite-calendario__chip--hecho { opacity: .55; }
.suite-agenda { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-1); }
.suite-agenda__item a {
  display: grid; gap: 2px; padding: var(--sp-2); border-radius: var(--r-sm); min-height: var(--toque-min);
  color: inherit; text-decoration: none; box-shadow: inset 3px 0 0 var(--c-borde);
}
.suite-agenda__item a:hover { background: var(--c-superficie-sutil); }
.suite-agenda__item--alerta a { box-shadow: inset 3px 0 0 var(--c-peligro); }
.suite-agenda__fecha { font-size: var(--fs-xs); color: var(--c-texto-suave); font-variant-numeric: tabular-nums; }
.suite-agenda__titulo { font-size: var(--fs-sm); }
.suite-agenda__detalle { font-size: var(--fs-xs); color: var(--c-texto-suave); }
.suite-calendario__chip.es-pedido { background: var(--c-aviso-bg); border-left-color: var(--c-aviso); }
.suite-calendario__chip.es-entregado { background: var(--c-exito-bg); border-left-color: var(--c-exito); }
.suite-calendario__chip.es-cancelada { background: var(--c-peligro-bg); border-left-color: var(--c-peligro); }
.suite-calendario__chip-modulo {
  display: inline-block; padding: 0 var(--sp-1); border-radius: var(--r-sm);
  font-size: var(--fs-2xs); font-weight: var(--fw-semi); background: var(--c-superficie-alta);
  color: var(--c-cliente, var(--c-texto-suave)); flex-shrink: 0;
}
.suite-calendario__chip-linea { display: flex; align-items: baseline; gap: var(--sp-1); min-width: 0; }
.suite-calendario__chip-hora { font-weight: var(--fw-semi); flex-shrink: 0; }
.suite-calendario__chip-sucursal {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.suite-calendario__chip-tracer { display: block; color: var(--c-texto-suave); }

@media (max-width: 899px) {
  .suite-calendario--semana { grid-template-columns: 1fr; }
  .suite-calendario__columna { border-left: none; border-top: 1px solid var(--c-borde); }
  .suite-calendario__columna:first-child { border-top: none; }
}

/* --- Calendario global: filtros ampliados + panel de resumen/alertas
   (peticion del mantenedor, 20 de agosto de 2026: "esto es un panel de
   vista rapida, no un calendario al uso"). Rango de fechas y casillas de
   estado/ocultar reutilizan .suite-filtros (fila flex ya existente);
   .suite-calendario-dashboard es la unica pieza de layout nueva, dos
   columnas junto a la rejilla ya existente. */
.suite-filtros__fecha { display: inline-flex; align-items: center; gap: var(--sp-1); font-size: var(--fs-xs); }
.suite-filtros__fecha input {
  padding: var(--sp-1) var(--sp-2); font-size: var(--fs-xs);
  border: 1px solid var(--c-borde); border-radius: var(--r-sm);
  background: var(--c-superficie); color: var(--c-texto);
}
.suite-filtros__casillas { border: none; margin: 0; padding: 0; }
.suite-filtros__casillas legend {
  padding: 0; margin-bottom: 2px; font-size: var(--fs-2xs); font-weight: var(--fw-semi);
  color: var(--c-texto-suave); text-transform: uppercase; letter-spacing: .04em;
}
.suite-filtros__casillas-lista { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); align-items: center; }
.suite-filtros__casillas-lista label {
  display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-xs); white-space: nowrap;
}

.suite-calendario-dashboard { display: flex; align-items: flex-start; gap: var(--sp-4); }
.suite-calendario-dashboard .suite-listado-panel { flex: 1 1 0; min-width: 0; }
.suite-calendario-resumen {
  flex: 0 0 22rem; min-width: 0;
  background: var(--c-superficie); border: 1px solid var(--c-borde); border-radius: var(--r-lg);
  padding: var(--sp-4);
}
.suite-calendario-resumen__titulo { font-size: var(--fs-base); font-weight: var(--fw-semi); margin: 0 0 var(--sp-3); }
.suite-calendario-resumen__bloque { margin-bottom: var(--sp-5); }
.suite-calendario-resumen__bloque:last-child { margin-bottom: 0; }
.suite-calendario-resumen__bloque h3 {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--c-texto-suave);
  text-transform: uppercase; letter-spacing: .04em; margin: 0 0 var(--sp-2);
}
.suite-calendario-resumen__contador {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 var(--sp-1); border-radius: var(--r-pill);
  font-size: var(--fs-2xs); font-weight: var(--fw-semi);
  background: var(--c-superficie-alta); color: var(--c-texto-suave);
}
.suite-calendario-resumen__contador.es-peligro { background: var(--c-peligro-bg); color: var(--c-peligro); }

/* "Por estado" reutiliza .suite-kpi-grid/.suite-kpi (mismo componente
   que el Dashboard de DIA Manager) -- sin CSS propio aqui. */

.suite-calendario-resumen__atrasados { display: flex; flex-direction: column; gap: var(--sp-1); list-style: none; margin: 0; padding: 0; }
/* La regla de arriba declara `display`, que sin esto le gana a la
   `display:none` implicita de `[hidden]` (misma especificidad,
   0,1,0 -- la hoja de autor gana a la de usuario en el empate). Sin
   esta linea "+N mas" no oculta nada: se ve descubierto por captura
   real con Playwright. */
.suite-calendario-resumen__atrasados[hidden] { display: none; }
.suite-calendario-resumen__atrasado {
  display: flex; align-items: center; gap: var(--sp-2); width: 100%; text-align: left; cursor: pointer;
  background: var(--c-peligro-bg); border: 1px solid var(--c-borde-sutil);
  border-left: 3px solid var(--c-cliente, var(--c-peligro));
  border-radius: var(--r-sm); padding: 3px var(--sp-2); font-family: inherit; font-size: var(--fs-2xs); color: var(--c-texto);
}
.suite-calendario-resumen__atrasado:hover { border-color: var(--c-peligro); box-shadow: var(--sh-sm); }
.suite-calendario-resumen__atrasado-fecha { font-weight: var(--fw-semi); flex-shrink: 0; }
.suite-calendario-resumen__mas { margin-top: var(--sp-1); }

@media (max-width: 899px) {
  .suite-calendario-dashboard { flex-direction: column; }
  .suite-calendario-dashboard .suite-listado-panel,
  .suite-calendario-resumen { width: 100%; flex: 1 1 auto; }
}
@media (max-width: 767px) {
  .suite-calendario--mes .suite-calendario__chips { display: none; }
  .suite-calendario--mes .suite-calendario__dia { min-height: 48px; }
  .suite-calendario__cuenta {
    display: flex; align-items: center; justify-content: center; margin: var(--sp-1) auto 0;
    min-width: var(--sp-5); height: var(--sp-5); border-radius: var(--r-pill);
    font-size: var(--fs-2xs); font-weight: var(--fw-semi);
    background: var(--c-primario-50); color: var(--c-primario);
  }
  .suite-calendario__cuenta--alerta { background: var(--c-peligro-bg); color: var(--c-peligro); }
}
@media (max-width: 639px) {
  .suite-usuario__datos { display: none; }
  /* En el movil el nombre y el rol ya no se ven: queda la inicial sola, que
     no aporta y con la campana (2.115) no cabe en la cabecera. */
  .suite-usuario { display: none; }
  .suite-encabezado { flex-direction: column; }
  .suite-tarjetas { grid-template-columns: 1fr; }
}
@media (max-width: 479px) {
  /* Debajo de esto el simbolo + los botones de la cabecera (tema, atras,
     menu, avatar, salir) ya no caben junto al texto "MontelvaSuite" --
     se queda solo el simbolo, como en el favicon. */
  .suite-marca__texto { display: none; }
  .suite-contenido { padding: var(--sp-4) var(--sp-3); }
  .suite-encabezado__titulo { font-size: var(--fs-xl); }
}
@media (max-width: 399px) {
  /* Telefonos de 320 a 390 px (2.113; 2.115 con la campana: a 375 px se
     salia 12 px): la cabecera no cabe. Se juntan los botones. */
  .suite-cabecera, .suite-cabecera__izq, .suite-cabecera__der { gap: var(--sp-1); }
  /* «Atras» se queda en la flecha (sigue su aria-label y su zona de toque) */
  .suite-boton-atras__texto { display: none; }
}

/* Logo propio elegido en «Ajustes de la Suite» (ADR-033) */
.suite-marca__logo { height: 28px; width: auto; max-width: 140px; object-fit: contain; }
.suite-campo input[type="color"] {
  flex: 0 0 3rem; width: 3rem; height: 2rem; padding: 2px; border: 1px solid var(--c-borde);
  border-radius: var(--r-sm); background: var(--c-superficie-entrada); cursor: pointer;
}

/* =====================================================================
   ESTILO «SENCILLO Y SOFISTICADO» (13-oct-2026, peticion del mantenedor:
   «me gusta estilo Apple»). Capa final que afina los componentes sobre los
   tokens: fondo gris claro con tarjetas blancas, cabecera translucida,
   menu lateral tipo macOS, botones en pildora, titulos grandes sin
   mayusculas forzadas y tablas limpias. Todo con tokens: los colores
   siguen siendo editables desde «Ajustes de la Suite». Para volver al
   estilo anterior basta con quitar este bloque y los valores de tokens.css.
   ===================================================================== */
body {
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  letter-spacing: -.003em; text-rendering: optimizeLegibility;
}
a { color: var(--c-primario); }

/* Cabecera translucida */
.suite-cabecera {
  background: var(--c-cabecera);
  -webkit-backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--c-borde-sutil);
  height: 52px;
}
.suite-marca__texto { font-weight: var(--fw-semi); letter-spacing: -.02em; }
.suite-marca__texto strong { font-weight: var(--fw-semi); }

/* Menu lateral tipo macOS */
.suite-lateral {
  background: var(--c-fondo); border-right: 1px solid var(--c-borde-sutil);
  padding: var(--sp-5) var(--sp-3);
}
.suite-lateral__grupo {
  text-transform: none; letter-spacing: 0; font-size: var(--fs-xs);
  font-weight: var(--fw-semi); color: var(--c-texto-terciario);
  margin: var(--sp-5) var(--sp-3) var(--sp-1);
}
.suite-lateral__enlace {
  border-radius: 8px; padding: 7px var(--sp-3); font-size: var(--fs-sm);
  transition: background var(--dur-rapido) var(--ease-defecto);
}
.suite-lateral__enlace:hover { background: rgb(0 0 0 / .05); }
[data-tema="oscuro"] .suite-lateral__enlace:hover { background: rgb(255 255 255 / .07); }
.suite-lateral__enlace.es-activo {
  background: var(--c-primario); color: var(--c-texto-invertido); font-weight: var(--fw-medio);
}
.suite-lateral__enlace.es-activo .suite-icono { color: var(--c-texto-invertido); }

/* Titulos */
.suite-encabezado { margin-bottom: var(--sp-6); }
.suite-encabezado__titulo { font-size: 2rem; font-weight: var(--fw-fuerte); letter-spacing: -.03em; line-height: 1.15; }
.suite-encabezado__sub { font-size: var(--fs-base); color: var(--c-texto-suave); margin-top: var(--sp-1); }
.suite-seccion {
  text-transform: none; letter-spacing: -.015em; font-size: var(--fs-xl);
  font-weight: var(--fw-semi); color: var(--c-texto); margin: var(--sp-8) 0 var(--sp-3);
}
h3 { font-size: var(--fs-base); font-weight: var(--fw-semi); letter-spacing: -.01em; }

/* Botones en pildora */
.suite-btn {
  border-radius: var(--r-pill); height: 34px; padding: 0 var(--sp-4);
  border-color: transparent; background: var(--c-superficie-sutil); color: var(--c-texto);
  font-weight: var(--fw-medio); letter-spacing: -.01em;
}
.suite-btn:hover { background: var(--c-borde-sutil); }
[data-tema="oscuro"] .suite-btn:hover { background: var(--c-borde); }
.suite-btn--primario { background: var(--c-primario); border-color: var(--c-primario); color: #fff; }
.suite-btn--primario:hover { background: var(--c-primario-fuerte); border-color: var(--c-primario-fuerte); }
.suite-btn--fantasma { background: transparent; }
.suite-btn--peligro { background: var(--c-peligro-bg); color: var(--c-peligro); border-color: transparent; }
.suite-btn--sm { height: 28px; padding: 0 var(--sp-3); font-size: var(--fs-xs); }
.suite-btn:focus-visible { box-shadow: 0 0 0 4px var(--c-borde-foco); }
summary.suite-btn { list-style: none; }
summary.suite-btn::-webkit-details-marker { display: none; }

/* Tarjetas, bloques y resumenes: blancos sobre el fondo gris */
.suite-tarjeta {
  border: 0; border-radius: var(--r-xl); background: var(--c-superficie);
  box-shadow: var(--sh-sm); padding: var(--sp-6);
}
.suite-tarjeta:hover { background: var(--c-superficie); border-color: transparent; box-shadow: var(--sh-md); transform: translateY(-2px); }
.suite-tarjeta__icono { border-radius: 12px; }
.suite-tarjeta__nombre { font-weight: var(--fw-semi); letter-spacing: -.015em; }
.suite-grupo {
  border: 0; border-radius: var(--r-lg); background: var(--c-superficie);
  box-shadow: var(--sh-sm); padding: var(--sp-5) var(--sp-5) var(--sp-4); font-size: var(--fs-sm);
}
.suite-grupo legend {
  float: left; width: 100%; padding: 0; margin: 0 0 var(--sp-3);
  text-transform: none; letter-spacing: -.01em; font-size: var(--fs-base);
  font-weight: var(--fw-semi); color: var(--c-texto);
}
.suite-grupo legend + * { clear: both; }
.suite-kpi {
  border: 0; border-radius: var(--r-lg); box-shadow: var(--sh-sm); padding: var(--sp-5);
}
.suite-kpi::before { display: none; }
.suite-kpi__valor {
  font-family: var(--f-sans); font-size: 1.75rem; font-weight: var(--fw-semi);
  letter-spacing: -.025em; font-variant-numeric: tabular-nums;
}
.suite-kpi__etiqueta { color: var(--c-texto-suave); font-size: var(--fs-sm); }
.suite-kpi__subtitulo { font-family: var(--f-sans); color: var(--c-texto-terciario); }

/* Tablas limpias */
.suite-tabla-marco { border: 0; border-radius: var(--r-lg); box-shadow: var(--sh-sm); background: var(--c-superficie); }
.suite-tabla { font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
.suite-tabla th {
  text-transform: none; letter-spacing: 0; font-size: var(--fs-xs); font-weight: var(--fw-medio);
  color: var(--c-texto-suave); background: var(--c-superficie); padding: var(--sp-3) var(--sp-3);
  border-bottom: 1px solid var(--c-borde-sutil);
}
.suite-tabla td { padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--c-borde-sutil); }
.suite-tabla tbody tr:hover { background: var(--c-superficie-alta); }
[data-tema="oscuro"] .suite-tabla tbody tr:hover { background: var(--c-superficie-sutil); }

/* Distintivos en pildora, sin mayusculas */
.suite-distintivo {
  border-radius: var(--r-pill); text-transform: none; letter-spacing: 0;
  font-size: var(--fs-xs); font-weight: var(--fw-medio); padding: 2px 10px;
}

/* Campos */
.suite-campo input[type="text"], .suite-campo input[type="email"], .suite-campo input[type="password"],
.suite-campo input[type="time"], .suite-campo input[type="date"], .suite-campo input[type="number"],
.suite-campo input[type="tel"], .suite-campo input[type="url"], .suite-campo input[type="search"],
.suite-campo select, .suite-campo textarea {
  border-radius: var(--r-md); padding: 9px var(--sp-3); font-size: var(--fs-sm);
}
.suite-campo input:focus-visible, .suite-campo select:focus-visible, .suite-campo textarea:focus-visible {
  border-color: var(--c-primario); box-shadow: 0 0 0 4px var(--c-borde-foco); outline: none;
}
.suite-campo label, .suite-campo__etiqueta { font-weight: var(--fw-medio); color: var(--c-texto); }
.suite-tabla input[type="text"], .suite-tabla input[type="number"], .suite-tabla select { border-radius: 8px; }

/* Avisos (mensajes) y vacios */
.suite-aviso { border-radius: var(--r-md); }
.suite-vacio { border: 0; border-radius: var(--r-lg); background: var(--c-superficie); box-shadow: var(--sh-sm); }

/* Pantalla de acceso */
.suite-acceso { background: var(--c-fondo); }
.suite-acceso__tarjeta { border: 0; border-radius: var(--r-2xl); box-shadow: var(--sh-lg); }

/* Pie */
.suite-pie { border-top: 1px solid var(--c-borde-sutil); color: var(--c-texto-terciario); background: var(--c-fondo); }
/* Subtitulo dentro de un titulo de seccion («Horas de trabajo · 3 h · …») */
.suite-seccion .suite-tabla__suave { font-size: var(--fs-base); font-weight: var(--fw-normal); letter-spacing: 0; }

/* --- Menu lateral fijo y contraible (ADR-034) ------------------------- */
.suite-lateral__contraer {
  display: flex; align-items: center; gap: var(--sp-3); width: 100%;
  margin-top: var(--sp-5); padding: 7px var(--sp-3); border: 0; border-radius: 8px;
  background: transparent; color: var(--c-texto-suave); font: inherit; font-size: var(--fs-sm);
  cursor: pointer; text-align: left;
}
.suite-lateral__contraer:hover { background: rgb(0 0 0 / .05); color: var(--c-texto); }
[data-tema="oscuro"] .suite-lateral__contraer:hover { background: rgb(255 255 255 / .07); }
.suite-lateral__contraer-mas { display: none; }
@media (min-width: 1024px) {
  /* Fijo a la ventana, no `sticky`: con sticky el contenedor y el pie lo
     empujaban hacia arriba al llegar al final de la pagina. El contenido y
     el pie reservan su ancho (232px, 68px en iconos, 0 oculto). */
  .suite-lateral {
    position: fixed; top: 52px; bottom: 0; left: 0;
    overflow-y: auto; z-index: var(--z-desplegable);
  }
  .suite-cuerpo:has(> .suite-lateral),
  .suite-cuerpo:has(> .suite-lateral) + .suite-pie { padding-left: 232px; }
  .lateral-iconos .suite-cuerpo:has(> .suite-lateral),
  .lateral-iconos .suite-cuerpo:has(> .suite-lateral) + .suite-pie { padding-left: 68px; }
  .lateral-oculto .suite-cuerpo:has(> .suite-lateral),
  .lateral-oculto .suite-cuerpo:has(> .suite-lateral) + .suite-pie { padding-left: 0; }
  .suite-boton-menu { display: flex; }
  .lateral-oculto .suite-lateral { display: none; }
  /* Solo iconos (el nombre sale al pasar el raton: atributo title) */
  .lateral-iconos .suite-lateral { width: 68px; padding-inline: var(--sp-2); }
  .lateral-iconos .suite-lateral__enlace { justify-content: center; padding: 9px 0; }
  .lateral-iconos .suite-lateral__enlace span,
  .lateral-iconos .suite-lateral__contraer-texto,
  .lateral-iconos .suite-lateral__contraer-menos { display: none; }
  .lateral-iconos .suite-lateral__contraer-mas { display: inline; }
  .lateral-iconos .suite-lateral__contraer { justify-content: center; padding-inline: 0; }
  .lateral-iconos .suite-lateral__grupo {
    font-size: 0; height: 1px; margin: var(--sp-3) var(--sp-2); background: var(--c-borde-sutil);
  }
  .lateral-iconos .suite-lateral__grupo:first-child { display: none; }
}
@media (max-width: 1023px) {
  .suite-lateral__contraer { display: none; }
}
.u-nowrap { white-space: nowrap; }
/* Columnas de cifras (21-oct-2026): `.suite-tabla th` alineaba a la
   izquierda TODAS las cabeceras y ganaba a `.u-derecha`, asi que la cabecera
   de una columna de importes quedaba a un lado y sus cifras al otro. */
.suite-tabla th.u-derecha, .suite-tabla td.u-derecha { text-align: right; }
.suite-tabla th.u-centro, .suite-tabla td.u-centro { text-align: center; }

/* Tablas en cebra (Caixa, 21-oct-2026): una fila de cada dos con fondo,
   y la que esta bajo el raton resaltada. Las filas de detalle desplegado
   no cuentan para alternar. */
.suite-tabla--cebra > tbody > tr:nth-child(even of :not(.suite-fila-detalle)) > td { background: var(--c-superficie-sutil); }
.suite-tabla--cebra > tbody > tr:not(.suite-fila-detalle):hover > td { background: var(--c-primario-50); }
.suite-tabla--cebra > tbody > tr.ap-fila[aria-expanded="true"] > td { background: var(--c-primario-50); }
/* Sobre una fila con fondo, los botones y las etiquetas grises (que usan ese
   mismo fondo) pasan a blanco para no desaparecer. */
.suite-tabla--cebra > tbody > tr:nth-child(even of :not(.suite-fila-detalle)) > td :is(.suite-btn:not(.suite-btn--primario):not(.suite-btn--fantasma):not(.suite-btn--peligro), .suite-distintivo--gris),
.suite-tabla--cebra > tbody > tr:not(.suite-fila-detalle):hover > td :is(.suite-btn:not(.suite-btn--primario):not(.suite-btn--fantasma):not(.suite-btn--peligro), .suite-distintivo--gris) {
  background: var(--c-superficie);
}
/* Leyenda de colores de un tablero */
.ap-leyenda { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); font-size: var(--fs-xs); color: var(--c-texto-suave); }
.ap-leyenda__alerta { display: inline-block; width: 3px; height: var(--sp-4); background: var(--c-peligro); vertical-align: middle; }

/* --- Graficos SVG pintados en el servidor (Rentabilidad DIA, E2) ---------
   Geometria en atributos (x, y, width: la CSP los permite); colores solo
   por clase y desde tokens. Texto en tinta de texto, nunca del color de la
   serie; rejilla y ejes en lineas finas continuas. La paleta facturado
   (primario) / coste (rosa) pasa el validador de daltonismo en claro y en
   oscuro. Cada marca lleva <title>: tooltip nativo sin JavaScript. */
.suite-graficos {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  gap: var(--sp-3); margin-bottom: var(--sp-6);
}
.suite-graficos__caja {
  background: var(--c-superficie); border: 1px solid var(--c-borde);
  border-radius: var(--r-md); padding: var(--sp-4); box-shadow: var(--sh-sm); min-width: 0;
}
.suite-graficos__caja--ancha { grid-column: 1 / -1; }
.suite-graficos__titulo { font-size: var(--fs-sm); font-weight: var(--fw-semi); margin: 0 0 var(--sp-1); }
.suite-graficos__leyenda { display: flex; gap: var(--sp-4); font-size: var(--fs-xs); color: var(--c-texto-suave); margin-bottom: var(--sp-2); }
.suite-graficos__leyenda span { display: inline-flex; align-items: center; gap: var(--sp-1); }
.suite-svg { display: block; width: 100%; height: auto; overflow: visible; }
.suite-svg .g-primario { fill: var(--c-primario); }
.suite-svg .g-rosa { fill: var(--c-rosa); }
.suite-svg .g-pista { fill: var(--c-superficie-sutil); }
.suite-svg .g-rejilla { stroke: var(--c-borde-sutil); stroke-width: 1; }
.suite-svg .g-eje { stroke: var(--c-borde); stroke-width: 1; }
.suite-svg .g-texto { fill: var(--c-texto); font-size: var(--fs-xs); font-family: var(--f-sans); }
.suite-svg .g-texto-suave { fill: var(--c-texto-suave); font-size: var(--fs-xs); font-family: var(--f-sans); }
.suite-svg .g-cifra { fill: var(--c-texto); font-size: var(--fs-xs); font-weight: var(--fw-semi); font-family: var(--f-sans); }
.suite-svg rect:hover { opacity: .8; }
/* Cuadro de incidencias (Dia, 2.96): marcas que son enlaces al desglose.
   La zona transparente amplia el area de toque a toda la fila o columna. */
.suite-svg .g-zona { fill: transparent; }
.suite-svg .g-enlace { cursor: pointer; }
.suite-svg .g-enlace:hover .g-zona { fill: var(--c-superficie-sutil); }
.suite-svg .g-enlace:focus-visible { outline: 2px solid var(--c-primario); outline-offset: 2px; }
.suite-svg .g-parcial { fill-opacity: .45; }
.suite-svg .g-referencia { stroke: var(--c-texto-suave); stroke-width: 1; }
/* Barras enlazadas: cada fila es un enlace de 44 px al desglose; en el
   teléfono, etiqueta y cifra arriba y la barra debajo. */
.suite-barras { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-1); }
.suite-barras__fila {
  display: grid; grid-template-columns: minmax(8em, 13em) 1fr auto; align-items: center; gap: var(--sp-3);
  min-height: var(--toque-min); padding: 0 var(--sp-2); border-radius: var(--r-sm);
  color: inherit; text-decoration: none; font-size: var(--fs-sm);
}
.suite-barras__fila:hover { background: var(--c-superficie-sutil); }
.suite-barras__fila:focus-visible { outline: 2px solid var(--c-primario); outline-offset: 2px; }
.suite-barras__etiqueta { color: var(--c-texto-suave); }
.suite-svg.suite-barras__pista { width: 100%; height: var(--sp-3); }
.suite-barras__cifra { font-weight: var(--fw-semi); font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (max-width: 767px) {
  .suite-barras__fila { grid-template-columns: 1fr auto; row-gap: var(--sp-1); padding-block: var(--sp-2); }
  .suite-barras__pista { grid-column: 1 / -1; grid-row: 2; }
}

/* Compraventa: banda «Búsquedas en pausa» encima del menú del módulo */
.cv-pausa { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-4); }
/* Recuento dentro de un botón primario (pestañas activas): legible sobre el azul */
.suite-btn--primario .suite-tabla__suave { color: inherit; opacity: .85; }

/* Bundles (ADR-036): las piezas de un equipo del catalogo van juntas bajo
   una fila de cabecera, en Compras de la apertura y en los articulos de la
   oferta. */
.ap-bundle__cabecera td { background: var(--c-superficie-sutil); border-top: 1px solid var(--c-borde); }
.ap-bundle__pieza .ap-bundle__pn { padding-left: var(--sp-5); }
.ap-bundle + tbody tr:first-child td { border-top: 1px solid var(--c-borde); }
.suite-tabla select.ap-input-proveedor { width: 9em; min-width: 9em; }
.ap-bundle__pn { overflow-wrap: anywhere; min-width: 7em; }
/* Caixa, segundas visitas (2.97): una línea de lectura por visita, con sus
   acciones, y su formulario en un desplegable «Editar». */
.ap-revisita { border-top: 1px solid var(--c-borde); padding: var(--sp-3) 0; }
.ap-revisita--hecha .ap-revisita__linea > :not(.ap-revisita__acciones) { opacity: .7; }
.ap-revisita__linea { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.ap-revisita__acciones { display: inline-flex; gap: var(--sp-2); margin-left: auto; }
.ap-revisita__editar > summary {
  display: inline-flex; align-items: center; min-height: var(--toque-min); cursor: pointer;
  color: var(--c-primario); font-size: var(--fs-sm);
}
/* SAP y su PDF en el presupuesto de la apertura */
.ap-sap__pdf { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1); margin-top: var(--sp-1); }
.ap-sap__pdf input[type="file"] { max-width: 14em; font-size: var(--fs-xs); }
.suite-tabla input.ap-sap__numero { width: 9em; }

/* --- Aperturas, 18-oct-2026: tablero de lectura rapida y detalle desplegable
   bajo la fila, con pestanas (radios + CSS, sin JS en linea). --------- */
.suite-tabla--aperturas td { vertical-align: top; }
.ap-col-tienda .ap-tienda__codigo { display: block; font-family: var(--f-mono); font-weight: var(--fw-semi); }
.ap-tienda__nombre, .ap-tienda__direccion, .ap-fecha, .ap-dias, .ap-tecnico, .ap-paso { display: block; }
.ap-tienda__direccion, .ap-tecnico { font-size: var(--fs-xs); }
.ap-dias { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--c-primario); }
.ap-dias--alerta { color: var(--c-peligro); }
.ap-dias--pasada { color: var(--c-texto-suave); font-weight: var(--fw-normal); }
.ap-col-compras .suite-distintivo, .ap-col-tracer > * { display: inline-block; margin: 0 var(--sp-1) var(--sp-1) 0; }
.ap-col-tracer .u-mono { display: block; }
.ap-col-paso .ap-paso { margin-top: var(--sp-1); font-size: var(--fs-sm); }
.ap-fila[aria-expanded="true"] td { background: var(--c-primario-50); border-bottom-color: transparent; }
.suite-fila-detalle > td { padding: 0; background: var(--c-superficie-sutil); }
.suite-fila-detalle__interior {
  margin: 0 var(--sp-2) var(--sp-3); padding: var(--sp-4); background: var(--c-superficie);
  border: 1px solid var(--c-borde); border-top: 3px solid var(--c-primario); border-radius: 0 0 var(--r-xl) var(--r-xl);
  box-shadow: var(--sh-md); cursor: default;
}
.ap-pestanas { margin-top: var(--sp-3); }
.ap-pestanas__radio { position: absolute; opacity: 0; pointer-events: none; }
.ap-pestanas__nav {
  display: flex; flex-wrap: wrap; gap: var(--sp-1); border-bottom: 1px solid var(--c-borde); margin-bottom: var(--sp-3);
}
.ap-pestanas__nav label {
  padding: var(--sp-2) var(--sp-3); cursor: pointer; color: var(--c-texto-suave); font-size: var(--fs-sm);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.ap-pestanas__nav label:hover { color: var(--c-texto); }
.ap-pestana-panel { display: none; }
.ap-pestana-panel > .suite-grupo { margin: 0 0 var(--sp-3); }
.suite-fila-detalle__interior .ap-ficha__cabecera { padding-bottom: var(--sp-2); }
.suite-fila-detalle__interior .ap-ficha__preparacion { margin-top: var(--sp-2); }
.ap-pestanas__radio:nth-of-type(1):checked ~ .ap-pestanas__paneles > .ap-pestana-panel:nth-child(1) { display: block; }
.ap-pestanas__radio:nth-of-type(1):checked ~ .ap-pestanas__nav > label:nth-child(1) { color: var(--c-primario); border-bottom-color: var(--c-primario); font-weight: var(--fw-semi); }
.ap-pestanas__radio:nth-of-type(1):focus-visible ~ .ap-pestanas__nav > label:nth-child(1) { outline: 2px solid var(--c-borde-foco); outline-offset: 2px; }
.ap-pestanas__radio:nth-of-type(2):checked ~ .ap-pestanas__paneles > .ap-pestana-panel:nth-child(2) { display: block; }
.ap-pestanas__radio:nth-of-type(2):checked ~ .ap-pestanas__nav > label:nth-child(2) { color: var(--c-primario); border-bottom-color: var(--c-primario); font-weight: var(--fw-semi); }
.ap-pestanas__radio:nth-of-type(2):focus-visible ~ .ap-pestanas__nav > label:nth-child(2) { outline: 2px solid var(--c-borde-foco); outline-offset: 2px; }
.ap-pestanas__radio:nth-of-type(3):checked ~ .ap-pestanas__paneles > .ap-pestana-panel:nth-child(3) { display: block; }
.ap-pestanas__radio:nth-of-type(3):checked ~ .ap-pestanas__nav > label:nth-child(3) { color: var(--c-primario); border-bottom-color: var(--c-primario); font-weight: var(--fw-semi); }
.ap-pestanas__radio:nth-of-type(3):focus-visible ~ .ap-pestanas__nav > label:nth-child(3) { outline: 2px solid var(--c-borde-foco); outline-offset: 2px; }
.ap-pestanas__radio:nth-of-type(4):checked ~ .ap-pestanas__paneles > .ap-pestana-panel:nth-child(4) { display: block; }
.ap-pestanas__radio:nth-of-type(4):checked ~ .ap-pestanas__nav > label:nth-child(4) { color: var(--c-primario); border-bottom-color: var(--c-primario); font-weight: var(--fw-semi); }
.ap-pestanas__radio:nth-of-type(4):focus-visible ~ .ap-pestanas__nav > label:nth-child(4) { outline: 2px solid var(--c-borde-foco); outline-offset: 2px; }
.ap-pestanas__radio:nth-of-type(5):checked ~ .ap-pestanas__paneles > .ap-pestana-panel:nth-child(5) { display: block; }
.ap-pestanas__radio:nth-of-type(5):checked ~ .ap-pestanas__nav > label:nth-child(5) { color: var(--c-primario); border-bottom-color: var(--c-primario); font-weight: var(--fw-semi); }
.ap-pestanas__radio:nth-of-type(5):focus-visible ~ .ap-pestanas__nav > label:nth-child(5) { outline: 2px solid var(--c-borde-foco); outline-offset: 2px; }
.ap-pestanas__radio:nth-of-type(6):checked ~ .ap-pestanas__paneles > .ap-pestana-panel:nth-child(6) { display: block; }
.ap-pestanas__radio:nth-of-type(6):checked ~ .ap-pestanas__nav > label:nth-child(6) { color: var(--c-primario); border-bottom-color: var(--c-primario); font-weight: var(--fw-semi); }
.ap-pestanas__radio:nth-of-type(6):focus-visible ~ .ap-pestanas__nav > label:nth-child(6) { outline: 2px solid var(--c-borde-foco); outline-offset: 2px; }
.ap-pestanas__radio:nth-of-type(7):checked ~ .ap-pestanas__paneles > .ap-pestana-panel:nth-child(7) { display: block; }
.ap-pestanas__radio:nth-of-type(7):checked ~ .ap-pestanas__nav > label:nth-child(7) { color: var(--c-primario); border-bottom-color: var(--c-primario); font-weight: var(--fw-semi); }
.ap-pestanas__radio:nth-of-type(7):focus-visible ~ .ap-pestanas__nav > label:nth-child(7) { outline: 2px solid var(--c-borde-foco); outline-offset: 2px; }
.ap-pestanas__radio:nth-of-type(8):checked ~ .ap-pestanas__paneles > .ap-pestana-panel:nth-child(8) { display: block; }
.ap-pestanas__radio:nth-of-type(8):checked ~ .ap-pestanas__nav > label:nth-child(8) { color: var(--c-primario); border-bottom-color: var(--c-primario); font-weight: var(--fw-semi); }
.ap-pestanas__radio:nth-of-type(8):focus-visible ~ .ap-pestanas__nav > label:nth-child(8) { outline: 2px solid var(--c-borde-foco); outline-offset: 2px; }
/* Formularios dentro de las pestañas: rejilla compacta y fila de alta */
.ap-form { margin: 0 0 var(--sp-3); }
.ap-form__rejilla { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-2); }
.ap-campo { margin: 0; }
.ap-campo--ancho { margin-bottom: var(--sp-2); }
.ap-form--linea { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.ap-form--linea input[type="text"] { flex: 1 1 160px; min-width: 0; }
/* Campos sueltos de una fila de acciones (pedido de un proveedor, poner
   proveedor a las marcadas...): mismo aspecto que en un formulario, mas
   compactos, como dentro de una tabla (2.108). */
.ap-form--linea input[type="text"], .ap-form--linea input[type="number"], .ap-form--linea select {
  padding: var(--sp-1) var(--sp-2); border: 1px solid var(--c-borde); border-radius: var(--r-sm);
  background: var(--c-superficie-entrada); color: var(--c-texto); font-family: inherit; font-size: var(--fs-sm);
}
.ap-input-pn { max-width: 12em; }
.ap-input-uds { width: 6em; }
.ap-input-factura { width: 9em; }
.ap-input-importe { width: 8em; }
.ap-fila-envolvente { flex-wrap: wrap; }
.ap-tabla-pedidos input[type="text"] { min-width: 8em; }
.ap-pedido--pendiente td { background: var(--c-pdte-compra-bg); }
/* Economia de la apertura (venta y coste del Tracker + gastos extra) */
.ap-economia { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin: 0 0 var(--sp-2); }
.ap-economia__dato { padding: var(--sp-2) var(--sp-3); border: 1px solid var(--c-borde); border-radius: var(--r-lg); min-width: 9em; }
.ap-economia__dato dt { font-size: var(--fs-xs); color: var(--c-texto-suave); }
.ap-economia__dato dd { margin: 0; font-weight: var(--fw-semi); font-family: var(--f-mono); }
.ap-economia__dato--positivo { border-color: var(--c-exito); background: var(--c-exito-bg); }
.ap-economia__dato--negativo { border-color: var(--c-peligro); background: var(--c-peligro-bg); }
.ap-totales { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-2) 0 var(--sp-3); }


/* =====================================================================
   ADR-039 — Móvil e iOS (20-oct-2026): toda la Suite usable desde un
   iPhone, como web instalable y dentro de la app de iOS. Medido con
   WebKit (motor de Safari) en un iPhone 14, no a ojo. Va al final a
   proposito: solo ajusta, nunca cambia el escritorio.
   ===================================================================== */

/* Saltar al contenido (teclado y lectores de pantalla) */
.suite-saltar {
  position: absolute; left: var(--sp-2); top: var(--sp-2); z-index: var(--z-aviso);
  transform: translateY(-200%);
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-md);
  background: var(--c-superficie-alta); color: var(--c-texto); box-shadow: var(--sh-md);
}
.suite-saltar:focus { transform: none; }

/* Muesca, isla dinamica y barra de inicio (viewport-fit=cover) */
.suite-cabecera {
  height: calc(var(--alto-cabecera) + env(safe-area-inset-top, 0px));
  padding-top: env(safe-area-inset-top, 0px);
  padding-left: max(var(--sp-4), env(safe-area-inset-left, 0px));
  padding-right: max(var(--sp-4), env(safe-area-inset-right, 0px));
}
.suite-app { padding-bottom: env(safe-area-inset-bottom, 0px); }

/* Pantallas tactiles: nada que obligue a ampliar ni a apuntar con precision */
@media (pointer: coarse) {
  /* !important a proposito: es un requisito de iOS (menos de 16 px = Safari
     amplia la pagina al tocar el campo) y debe ganar a cualquier regla mas
     especifica de un formulario o una tabla. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="color"]),
  select, textarea { font-size: var(--fs-base) !important; min-height: var(--toque-min); }
  .suite-btn, .suite-btn--sm { height: auto; min-height: var(--toque-min); }
  /* La flecha al ticket vinculado, junto a la TASK de una oferta */
  .suite-editable__enlace {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: var(--toque-min); min-height: var(--toque-min);
  }
  .suite-boton-menu { min-width: var(--toque-min); min-height: var(--toque-min); }
  .ap-pestanas__nav label { display: inline-flex; align-items: center; min-height: var(--toque-min); }
  input[type="checkbox"], input[type="radio"] { width: var(--casilla-tactil); height: var(--casilla-tactil); }
  /* El logo, los «xls» del dashboard, el P/W de Ofertas y los enlaces
     secundarios (`.suite-enlaces`) tambien son para el dedo (2.93.0) */
  .suite-marca, .suite-kpi__exportar, .suite-pw {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: var(--toque-min); min-height: var(--toque-min);
  }
  .suite-enlaces a { display: inline-flex; align-items: center; min-height: var(--toque-min); padding-inline: var(--sp-1); }
}

/* Telefono */
@media (max-width: 767px) {
  .suite-lateral, .suite-panel-lateral.es-visible {
    top: calc(var(--alto-cabecera) + env(safe-area-inset-top, 0px));
  }
  /* Las botoneras saltan de linea en vez de salirse de la pantalla */
  .u-fila { flex-wrap: wrap; }
  .suite-btn { white-space: nowrap; }
  .suite-filtros > input, .suite-filtros > select { flex: 1 1 100%; }
  .suite-filtros.es-plegado { display: none; }
  /* Indicadores de dos en dos: uno por fila obligaba a bajar mucho (2.93.0) */
  .suite-kpi-grid:not(.suite-kpi-grid--compacta) { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); }
  .suite-filtros-alternar { margin-bottom: var(--sp-3); }
  .ap-form__rejilla { grid-template-columns: 1fr; }
  /* Pestañas del desplegable: una fila que se desliza con el dedo */
  .ap-pestanas__nav { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .ap-pestanas__nav label { flex: 0 0 auto; white-space: nowrap; }
  /* Filtros de fase de un tablero: una linea que se desliza; las fases sin
     nada no se muestran en el telefono */
  .ap-fases { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .ap-fases > * { flex: 0 0 auto; }
  .ap-fases .ap-fases--vacia { display: none; }

  /* Tableros (Aperturas, Instalaciones, Oficinas, Visitas, Tipos de LED):
     cada fila es una tarjeta; cada dato lleva su etiqueta (data-etiqueta). */
  .suite-tabla--aperturas { width: 100%; }
  .suite-tabla--aperturas thead { display: none; }
  .suite-tabla--aperturas, .suite-tabla--aperturas tbody, .suite-tabla--aperturas tr,
  .suite-tabla--aperturas td { display: block; }
  .suite-tabla--aperturas tr.ap-fila { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--c-borde); }
  .suite-tabla--aperturas tr.ap-fila td { padding: var(--sp-1) 0; border: 0; }
  .suite-tabla--aperturas td[data-etiqueta]::before {
    content: attr(data-etiqueta); display: block;
    font-size: var(--fs-2xs); color: var(--c-texto-terciario); text-transform: uppercase;
  }
  .suite-tabla--aperturas td.u-derecha { text-align: left; }
  .suite-tabla--aperturas .u-fila--fin { justify-content: flex-start; }
  .suite-tabla--aperturas .ap-fila--alerta td:first-child { box-shadow: none; }
  .suite-tabla--aperturas tr.ap-fila--alerta { box-shadow: inset 3px 0 0 var(--c-peligro); }
  /* Cebra en tarjetas: el fondo, en la tarjeta entera (no celda a celda) */
  .suite-tabla--aperturas.suite-tabla--cebra > tbody > tr:nth-child(even of :not(.suite-fila-detalle)) { background: var(--c-superficie-sutil); }
  .suite-tabla--aperturas.suite-tabla--cebra > tbody > tr:nth-child(even of :not(.suite-fila-detalle)) > td,
  .suite-tabla--aperturas.suite-tabla--cebra > tbody > tr:not(.suite-fila-detalle):hover > td { background: transparent; }
  .suite-fila-detalle > td { display: block; }
  .suite-fila-detalle__interior { margin: 0; padding: var(--sp-3); border-radius: 0; }

  /* 2.110 · Cualquier tabla, en tarjetas (suite.js pone las etiquetas de
     la cabecera y la clase): una tarjeta por fila, sin desplazar a lo
     ancho. `suite-tabla--sin-tarjetas` la deja como tabla. */
  .suite-tabla--tarjetas { width: 100%; }
  .suite-tabla--tarjetas > thead { display: none; }
  .suite-tabla--tarjetas, .suite-tabla--tarjetas > tbody, .suite-tabla--tarjetas > tfoot,
  .suite-tabla--tarjetas > tbody > tr, .suite-tabla--tarjetas > tfoot > tr,
  .suite-tabla--tarjetas > tbody > tr > td, .suite-tabla--tarjetas > tfoot > tr > td,
  .suite-tabla--tarjetas > tfoot > tr > th { display: block; }
  .suite-tabla--tarjetas > tbody > tr, .suite-tabla--tarjetas > tfoot > tr {
    padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--c-borde);
  }
  .suite-tabla--tarjetas > tbody > tr > td, .suite-tabla--tarjetas > tfoot > tr > td,
  .suite-tabla--tarjetas > tfoot > tr > th {
    padding: var(--sp-1) 0; border: 0; text-align: left; white-space: normal;
  }
  .suite-tabla--tarjetas td[data-etiqueta]::before {
    content: attr(data-etiqueta); display: block;
    font-size: var(--fs-2xs); color: var(--c-texto-terciario); text-transform: uppercase;
  }
  .suite-tabla--tarjetas td:empty { display: none; }
  .suite-tabla--tarjetas .suite-tabla__acciones { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
  .suite-tabla--tarjetas .u-fila--fin { justify-content: flex-start; }
  .suite-tabla--tarjetas > tfoot > tr { background: var(--c-superficie-sutil); font-weight: var(--fw-semi); }
  .suite-tabla--tarjetas.suite-tabla--cebra > tbody > tr:nth-child(even of :not(.suite-fila-detalle)) { background: var(--c-superficie-sutil); }
  .suite-tabla--tarjetas.suite-tabla--cebra > tbody > tr > td { background: transparent; }
  .suite-tabla-marco:has(> .suite-tabla--tarjetas) { overflow-x: visible; }

  /* Barras de botones: el principal a la vista, el resto en «⋯ Más» */
  .suite-mas { position: relative; }
  .suite-mas > summary { list-style: none; cursor: pointer; }
  .suite-mas > summary::-webkit-details-marker { display: none; }
  .suite-mas__lista {
    position: absolute; right: 0; top: calc(100% + var(--sp-1)); z-index: var(--z-desplegable);
    display: flex; flex-direction: column; align-items: stretch; gap: var(--sp-1);
    min-width: 13rem; padding: var(--sp-2);
    background: var(--c-superficie); border: 1px solid var(--c-borde); border-radius: var(--r-md); box-shadow: var(--sh-lg);
  }
  .suite-mas__lista > a, .suite-mas__lista > form, .suite-mas__lista > button,
  .suite-mas__lista > form > button { width: 100%; justify-content: flex-start; }

  /* Filtros laterales plegados tras su boton; leyendas fuera (ocupan sitio) */
  .suite-sidebar-filtros.es-plegado { display: none; }
  .suite-panel-filtros { flex-direction: column; gap: var(--sp-3); }
  .suite-sidebar-filtros { width: 100%; }
  .ap-leyenda { display: none; }
  /* Resumen + acciones (Ofertas de Dia): uno debajo de otro; los
     indicadores, de tres en tres */
  .suite-resumen-acciones { flex-direction: column; align-items: stretch; }
  .suite-resumen-acciones > .suite-kpi-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .suite-resumen-acciones > .suite-caja-acciones { align-self: flex-start; }
  /* Importes y codigos de una tarjeta: en una linea */
  .suite-tabla--tarjetas td.u-derecha { white-space: nowrap; }
  /* En tarjeta, ninguna celda guarda el ancho ni la alineacion de su
     columna (Ofertas fija anchos por columna) y ningun campo se sale */
  .suite-tabla--tarjetas > tbody > tr > td { width: auto !important; min-width: 0; text-align: left !important; }
  .suite-tabla--tarjetas input, .suite-tabla--tarjetas select, .suite-tabla--tarjetas textarea { max-width: 100%; }
  .suite-tabla--tarjetas .suite-editable { flex-wrap: wrap; }
  table.suite-tabla--tarjetas { min-width: 0 !important; table-layout: auto; }
}

/* Quien pide menos movimiento en el sistema, no lo recibe */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* App de iOS (ADR-040): bloqueo con Face ID y privacidad en segundo plano.
   Solo existen dentro de la app (app-ios.js pone las clases). */
.app-bloqueo {
  position: fixed; inset: 0; z-index: var(--z-aviso);
  display: grid; place-items: center; background: var(--c-fondo);
}
.app-bloqueo__caja { display: grid; gap: var(--sp-4); justify-items: center; text-align: center; }
.app-bloqueo__titulo { font-size: var(--fs-xl); font-weight: var(--fw-semi); color: var(--c-texto); }
.app-bloqueada .suite-cuerpo, .app-en-segundo-plano .suite-cuerpo { visibility: hidden; }
.suite-texto-legal { max-width: var(--ancho-lectura); line-height: 1.6; }
.suite-texto-legal h2 { font-size: var(--fs-lg); margin: var(--sp-6) 0 var(--sp-2); }
.suite-texto-legal ul { padding-left: var(--sp-5); display: grid; gap: var(--sp-2); }

