/* Componentes compartidos por los cuatro módulos. Cada vista compone con estas piezas;
   ninguna vista inventa su propia tarjeta ni su propio chip. */

/* ── rejilla y tarjetas ───────────────────────────────────────────────── */
.ops .rejilla { display: grid; gap: 14px; }
.ops .tarjeta {
  background: linear-gradient(180deg, var(--s2), var(--s2-2));
  border: 1px solid var(--linea); border-radius: var(--r-l);
  box-shadow: var(--sombra-1); padding: 16px 18px;
  display: flex; flex-direction: column; min-width: 0;
}
.ops .tarjeta--foco { border-color: rgba(79, 140, 255, .34); box-shadow: var(--sombra-2); }
.ops .tarjeta-cab { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.ops .tarjeta-cab h2 {
  font-family: var(--display); font-weight: 600; font-size: 14.5px; letter-spacing: -.02em;
  margin: 0; color: var(--tx);
}
.ops .tarjeta-cab .nota { margin-left: auto; font-size: 12px; color: var(--tx-dim); }

/* ── KPI ──────────────────────────────────────────────────────────────── */
.ops .kpi-et { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--tx-dim); }
.ops .kpi-val {
  font-family: var(--display); font-weight: 600; letter-spacing: -.035em; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--tx); margin-top: 6px; font-size: 34px;
}
.ops .kpi-val--xl {
  font-size: clamp(34px, 3.4vw, 46px);
  background: linear-gradient(92deg, #7aa8ff, var(--c-azul-dato) 46%, var(--c-menta));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.ops .kpi-val--sm { font-size: 24px; }
.ops .kpi-pie { font-size: 12.5px; color: var(--tx-dim); margin-top: 7px; }

/* ── chips de estado (color + texto, nunca color solo) ────────────────── */
.ops .chip {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px;
  border-radius: 999px; padding: 3px 10px; white-space: nowrap;
  border: 1px solid transparent;
}
.ops .chip::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.ops .chip--azul { color: var(--c-azul-tx); background: rgba(79, 140, 255, .13); border-color: rgba(79, 140, 255, .3); }
.ops .chip--menta { color: var(--c-menta-tx); background: rgba(46, 230, 197, .12); border-color: rgba(46, 230, 197, .3); }
.ops .chip--ambar { color: var(--c-ambar-tx); background: rgba(232, 181, 59, .13); border-color: rgba(232, 181, 59, .32); }
.ops .chip--coral { color: var(--c-coral-tx); background: rgba(224, 104, 92, .14); border-color: rgba(224, 104, 92, .34); }
.ops .chip--gris { color: var(--tx-mu); background: var(--velo-fuerte); border-color: var(--linea); }
.ops .chip--liso::before { display: none; }

/* ── botones ──────────────────────────────────────────────────────────── */
.ops .btn {
  font-family: var(--display); font-weight: 600; font-size: 13.5px; letter-spacing: -.01em;
  border-radius: var(--r-s); padding: 10px 16px; cursor: pointer; border: 1px solid transparent;
  transition: background-color var(--t-rapido), border-color var(--t-rapido);
  display: inline-flex; align-items: center; gap: 8px; justify-content: center;
}
.ops .btn--primario { background: var(--c-cta); color: #fff; box-shadow: 0 10px 22px -12px rgba(29, 78, 216, .9); }
.ops .btn--primario:hover { background: #2258e8; }
.ops .btn--fantasma { background: transparent; color: var(--tx-mu); border-color: var(--linea); }
.ops .btn--fantasma:hover { color: var(--tx); border-color: var(--linea-fuerte); }
.ops .btn--foco { background: var(--c-crema); color: var(--tx-inv); }
.ops .btn--foco:hover { background: var(--c-crema-h); }
.ops .btn[disabled] { opacity: .5; cursor: not-allowed; }

/* ── controles: buscador, selects, tabs, segmentado ───────────────────── */
.ops .buscador { display: flex; align-items: center; gap: 8px; border: 1px solid var(--linea);
  border-radius: var(--r-s); padding: 0 10px; height: 36px; background: var(--velo); }
.ops .buscador input { border: 0; background: transparent; outline: none; width: 100%; min-width: 0;
  font-size: 13.5px; }
.ops .buscador input::placeholder { color: var(--tx-dim); }
.ops .selector {
  height: 36px; padding: 0 12px; border: 1px solid var(--linea); border-radius: var(--r-s);
  background: var(--velo); font-size: 13.5px; cursor: pointer;
}
.ops .tabs { display: flex; gap: 3px; }
.ops .tabs button {
  font-family: var(--display); font-weight: 600; font-size: 12.5px; color: var(--tx-mu);
  background: transparent; border: 1px solid transparent; border-radius: var(--r-s);
  padding: 6px 12px; cursor: pointer;
}
.ops .tabs button[aria-selected='true'] {
  color: var(--tx); background: var(--velo-fuerte); border-color: var(--linea);
}
.ops .tabs .cuenta { margin-left: 6px; color: var(--tx-dim); }

/* ── tablas y listas ──────────────────────────────────────────────────── */
.ops .tabla { width: 100%; border-collapse: collapse; font-size: 13.5px; font-variant-numeric: tabular-nums; }
.ops .tabla th {
  text-align: left; font-family: var(--display); font-weight: 600; font-size: 12px;
  letter-spacing: .07em; text-transform: uppercase; color: var(--tx-dim);
  padding: 0 10px 9px 0; border-bottom: 1px solid var(--linea);
}
.ops .tabla td { padding: 10px 10px 10px 0; border-bottom: 1px solid var(--linea-suave); color: var(--tx-mu); }
.ops .tabla .der { text-align: right; color: var(--tx); }
.ops .tabla tbody tr { cursor: pointer; transition: background-color var(--t-rapido); }
.ops .tabla tbody tr:hover { background: rgba(79, 140, 255, .06); }
.ops .tabla tbody tr[aria-selected='true'] { background: rgba(79, 140, 255, .12); }
.ops .tabla tbody tr:focus-visible { outline: 2px solid var(--c-menta); outline-offset: -2px; }
.ops .vacio { padding: 26px 4px; color: var(--tx-dim); font-size: 13.5px; text-align: center; }

.ops .avatar {
  width: 24px; height: 24px; border-radius: 50%; display: inline-grid; place-items: center;
  font-family: var(--display); font-weight: 600; font-size: 10.5px; color: #0a1024;
  margin-right: 9px; vertical-align: -7px;
}
.ops .avatar--azul { background: linear-gradient(140deg, #9fc0ff, #4f8cff); }
.ops .avatar--ambar { background: linear-gradient(140deg, #f3d9a0, #e8b53b); }
.ops .avatar--menta { background: linear-gradient(140deg, #7fead9, #2ee6c5); }
.ops .avatar--violeta { background: linear-gradient(140deg, #c0a9ff, #8b5cff); }
.ops .avatar--gris { background: linear-gradient(140deg, #a8b6c9, #6d7889); }

/* ── panel lateral de detalle (3.er plano) ────────────────────────────── */
.ops .detalle {
  background: linear-gradient(180deg, var(--s3), var(--s3-2));
  border: 1px solid var(--linea-elev); border-radius: var(--r-l); box-shadow: var(--sombra-2);
  padding: 18px; display: flex; flex-direction: column; gap: 14px; min-width: 0;
  animation: ops-detalleEntra var(--t-medio) var(--e-salida) both;
}
@keyframes ops-detalleEntra { from { opacity: 0; transform: translateX(10px); } to { opacity: 1; transform: none; } }
.ops .detalle-cab { display: flex; align-items: flex-start; gap: 10px; }
.ops .detalle-cab h3 { font-family: var(--display); font-weight: 600; font-size: 16px;
  letter-spacing: -.02em; margin: 0; }
.ops .detalle-cab .cerrar {
  margin-left: auto; background: transparent; border: 1px solid var(--linea); color: var(--tx-mu);
  border-radius: 6px; width: 28px; height: 28px; cursor: pointer; line-height: 1;
}
.ops .campos { display: grid; grid-template-columns: auto 1fr; gap: 7px 14px; font-size: 13px; }
.ops .campos dt { color: var(--tx-dim); }
.ops .campos dd { margin: 0; color: var(--tx); text-align: right; font-variant-numeric: tabular-nums; }

/* secuencia Pedido → Albarán → Factura */
.ops .flujo-doc { display: flex; align-items: center; gap: 8px; }
.ops .flujo-doc .paso {
  flex: 1; text-align: center; font-size: 12px; padding: 9px 6px; border-radius: var(--r-s);
  border: 1px dashed var(--linea); color: var(--tx-dim);
}
.ops .flujo-doc .paso.hecho {
  border-style: solid; border-color: rgba(46, 230, 197, .34);
  background: rgba(46, 230, 197, .09); color: var(--c-menta-tx);
}
.ops .flujo-doc .paso b { display: block; font-family: var(--display); font-weight: 600;
  font-size: 12.5px; color: inherit; }
.ops .flujo-doc .flecha { color: var(--tx-dim); font-size: 12px; }

/* ── avisos ───────────────────────────────────────────────────────────── */
.ops .aviso {
  display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px;
  border-radius: var(--r-m); border: 1px solid;
}
.ops .aviso--critico { background: rgba(224, 104, 92, .09); border-color: rgba(224, 104, 92, .34); }
.ops .aviso--plan { background: rgba(46, 230, 197, .08); border-color: rgba(46, 230, 197, .3); }
.ops .aviso--info { background: rgba(79, 140, 255, .08); border-color: rgba(79, 140, 255, .28); }
.ops .aviso-ico { width: 26px; height: 26px; border-radius: 8px; flex: none; display: grid;
  place-items: center; font-size: 14px; }
.ops .aviso--critico .aviso-ico { background: rgba(224, 104, 92, .18); color: var(--c-coral-tx); }
.ops .aviso--plan .aviso-ico { background: rgba(46, 230, 197, .16); color: var(--c-menta-tx); }
.ops .aviso-cuerpo { min-width: 0; }
.ops .aviso-cuerpo b { display: block; font-family: var(--display); font-weight: 600; font-size: 14px;
  margin-bottom: 3px; }
.ops .aviso-cuerpo p { margin: 0; font-size: 13px; color: var(--tx-mu); }
.ops .aviso .btn { margin-left: auto; flex: none; align-self: center; }

/* ── barras de composición (stock sano/comprometido/…) ────────────────── */
.ops .barra-comp { display: flex; height: 12px; border-radius: 999px; overflow: hidden;
  background: var(--velo-fuerte); }
.ops .barra-comp i { display: block; height: 100%; }
.ops .leyenda { display: flex; flex-wrap: wrap; gap: 10px 18px; margin-top: 10px; font-size: 12.5px;
  color: var(--tx-mu); }
.ops .leyenda span { display: inline-flex; align-items: center; gap: 7px; }
.ops .leyenda i { width: 9px; height: 9px; border-radius: 3px; }
.ops .leyenda b { color: var(--tx); font-variant-numeric: tabular-nums; }

/* ── modal de confirmación ────────────────────────────────────────────── */
.ops .velo {
  position: fixed; inset: 0; z-index: 60; background: var(--velo-modal);
  backdrop-filter: blur(5px); display: grid; place-items: center; padding: 20px;
  animation: ops-veloEntra var(--t-rapido) ease both;
}
@keyframes ops-veloEntra { from { opacity: 0; } to { opacity: 1; } }
.ops .modal {
  width: min(560px, 100%); background: linear-gradient(180deg, var(--s3), var(--s3-2));
  border: 1px solid var(--linea-elev); border-radius: var(--r-xl); box-shadow: var(--sombra-3);
  padding: 22px; animation: ops-modalEntra var(--t-medio) var(--e-salida) both;
}
@keyframes ops-modalEntra { from { opacity: 0; transform: translateY(12px) scale(.985); } to { opacity: 1; transform: none; } }
/* `color` explícito: la web tiene `.modal h2 { color: var(--crema) }` (styles.css:1271) y
   este diálogo se monta DENTRO de la página. Sobre claro el titular salía en crema, ilegible. */
.ops .modal h2 { font-family: var(--display); font-weight: 600; font-size: 19px; letter-spacing: -.03em;
  margin: 0 0 6px; color: var(--tx); }
.ops .modal .sub { margin: 0 0 16px; font-size: 13.5px; color: var(--tx-mu); }
.ops .modal .acciones { display: flex; gap: 10px; margin-top: 18px; }
.ops .modal .acciones .btn { flex: 1; }

/* ── timeline de automatismos ─────────────────────────────────────────── */
.ops .timeline { list-style: none; margin: 0; padding: 0; position: relative; }
.ops .timeline::before { content: ''; position: absolute; left: 11px; top: 12px; bottom: 12px;
  width: 1px; background: var(--linea); }
.ops .timeline li { position: relative; display: flex; gap: 12px; padding: 9px 0; cursor: pointer;
  border-radius: var(--r-s); transition: background-color var(--t-rapido); }
.ops .timeline li:hover { background: var(--velo); }
.ops .timeline li[aria-selected='true'] { background: rgba(79, 140, 255, .1); }
.ops .timeline .nodo { width: 23px; height: 23px; border-radius: 50%; flex: none; z-index: 1;
  display: grid; place-items: center; background: var(--s1); border: 2px solid var(--linea);
  font-size: 11px; }
.ops .timeline .nodo.ok { border-color: var(--c-ok); color: var(--c-ok); }
.ops .timeline .nodo.incidencia { border-color: var(--c-ambar); color: var(--c-ambar); }
.ops .timeline .nodo.nuevo { border-color: var(--c-menta); color: var(--c-menta);
  box-shadow: 0 0 0 4px rgba(46, 230, 197, .12); }
.ops .timeline .cuerpo { min-width: 0; flex: 1; }
.ops .timeline .cuerpo b { display: block; font-size: 13.5px; font-weight: 500; color: var(--tx); }
.ops .timeline .cuerpo span { font-size: 12.5px; color: var(--tx-dim); }
.ops .timeline .hora { font-size: 12.5px; color: var(--tx-dim); font-variant-numeric: tabular-nums; }

/* ── gráficos ─────────────────────────────────────────────────────────── */
.ops .grafico { width: 100%; display: block; }
.ops .grafico .rejilla-y { stroke: var(--linea); stroke-width: 1; }
.ops .grafico .linea { fill: none; stroke: url(#trazo); stroke-width: 2.4; stroke-linecap: round;
  stroke-linejoin: round; }
.ops .grafico .area { fill: url(#relleno); }
.ops .grafico .punto { fill: var(--s2-2); stroke: var(--c-menta); stroke-width: 2.2; }
.ops .grafico .barra { fill: var(--c-azul-dato); transition: fill var(--t-rapido); }
.ops .grafico .barra.activa { fill: var(--c-crema); }
.ops .eje-x { display: flex; justify-content: space-between; margin-top: 7px; font-size: 12px;
  color: var(--tx-dim); }

.ops .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; }

/* ── barras interactivas (componente graficoBarras) ───────────────────── */
.ops .barras { display: flex; align-items: flex-end; gap: 6px; height: var(--alto, 140px); }
.ops .barras .barra-btn {
  flex: 1; min-width: 0; background: transparent; border: 0; padding: 0; cursor: pointer;
  display: flex; flex-direction: column; justify-content: flex-end; align-items: center;
  height: 100%; gap: 7px; border-radius: 6px;
}
.ops .barras .barra-btn i {
  display: block; width: 100%; height: var(--v); border-radius: 5px 5px 2px 2px;
  background: linear-gradient(180deg, var(--c-azul-dato), rgba(110, 134, 245, .35));
  transition: background var(--t-rapido), transform var(--t-rapido);
  transform-origin: 50% 100%;
}
.ops .barras .barra-btn em {
  font-style: normal; font-size: 12px; color: var(--tx-dim); white-space: nowrap;
}
.ops .barras .barra-btn:hover i, .ops .barras .barra-btn.activa i {
  background: linear-gradient(180deg, var(--c-crema), var(--c-crema-2));
}
.ops .barras .barra-btn.activa em { color: var(--tx); }

/* ── módulo Ventas ────────────────────────────────────────────────────── */
.ops .ventas-arriba {
  display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: 14px; margin-bottom: 14px;
}
.ops .ventas-doble { display: grid; grid-template-columns: minmax(0, 1fr) 388px; gap: 14px; align-items: start; }

/* rótulo vivo del gráfico: alto fijo para que el valor no empuje a las barras */
.ops .ventas-rotulo { min-height: 96px; margin-bottom: 12px; }
.ops .ventas-barras { gap: 12px; }

.ops .ventas-kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.ops .ventas-reparto { margin-top: auto; padding-top: 18px; }
.ops .ventas-sub {
  font-family: var(--display); font-weight: 600; font-size: 12px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--tx-dim); margin: 0 0 9px;
}
.ops .ventas-reparto .ventas-sub:not(:first-child) { margin-top: 16px; }

/* controles de la lista */
.ops .ventas-controles { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.ops .ventas-controles .buscador { flex: 1 1 180px; max-width: 300px; }
.ops .ventas-controles .tabs { margin-left: auto; flex: none; }
.ops .ventas-lupa { color: var(--tx-dim); flex: none; }

.ops .ventas-tabla td { vertical-align: middle; }
.ops .ventas-id { font-weight: 500; color: var(--tx); font-variant-numeric: tabular-nums; }
.ops .ventas-centrado { display: flex; width: fit-content; margin: -6px auto 4px; }

/* detalle */
.ops .ventas-detalle .detalle-cab .chip { margin-left: auto; }
.ops .ventas-cliente { display: flex; align-items: center; font-size: 13px; color: var(--tx-mu); margin-top: 4px; }
.ops .ventas-cliente .avatar { vertical-align: 0; }
.ops .ventas-seccion { display: block; }
.ops .ventas-lineas { font-size: 13px; }
.ops .ventas-lineas th { padding-bottom: 7px; }
.ops .ventas-lineas td { padding: 8px 8px 8px 0; vertical-align: top; }
.ops .ventas-lineas th:last-child, .ops .ventas-lineas td:last-child { padding-right: 0; }
.ops .ventas-lineas tbody tr { cursor: default; }
.ops .ventas-lineas tbody tr:hover { background: transparent; }
.ops .ventas-ref-nombre { display: block; font-size: 12px; color: var(--tx-dim); }
.ops .ventas-causa { display: flex; flex-direction: column; gap: 10px; }
.ops .ventas-ancho { width: 100%; }

@media (max-width: 1080px) {
  .ops .ventas-doble { grid-template-columns: 1fr; }
  .ops .ventas-detalle { animation: none; }
}
@media (max-width: 900px) {
  .ops .ventas-arriba { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
  .ops .ventas-sec { display: none; }
  .ops .ventas-kpis { grid-template-columns: 1fr; gap: 14px; }
  .ops .ventas-rotulo { min-height: 84px; }
  .ops .ventas-controles { flex-wrap: wrap; gap: 10px; }
  .ops .ventas-controles .buscador { flex: 1 1 100%; max-width: none; }
  .ops .ventas-controles .tabs {
    margin-left: 0; width: 100%; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px;
  }
  .ops .ventas-controles .tabs::-webkit-scrollbar { display: none; }
  .ops .ventas-controles .tabs button { flex: 0 0 auto; padding: 7px 10px; }
  /* la lista se queda en lo esencial: pedido, cliente, importe y estado */
  .ops .ventas-tabla { font-size: 13px; }
  .ops .ventas-tabla th, .ops .ventas-tabla td { padding-right: 7px; }
  .ops .ventas-tabla .avatar { display: none; }
  .ops .ventas-tabla .chip { white-space: normal; }
  .ops .flujo-doc { gap: 5px; }
  .ops .flujo-doc .paso { padding: 8px 4px; }
}

/* ══ módulo Automatismos (.auto-) ═══════════════════════════════════════ */
.ops .auto-vista .vista-cab { margin-bottom: 0; }
.ops .auto-vista .vista-cab p { max-width: 92ch; }

/* cifras de cabecera: tres bloques separados, no tres tarjetas iguales */
.ops .auto-cifras { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.ops .auto-cifras > div + div { border-left: 1px solid var(--linea-suave); padding-left: 20px; }

/* foco (registro) + detalle de la ejecución */
/* el detalle ocupa la columna derecha completa: el registro y los procesos se apilan
   a su izquierda y no dejan un hueco muerto bajo el registro */
.ops .auto-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) 350px; gap: 14px; align-items: start;
  grid-template-areas: 'registro detalle' 'procesos detalle';
}
.ops .auto-registro { grid-area: registro; }
.ops .auto-detalle { grid-area: detalle; }
.ops .auto-procesos-tarjeta { grid-area: procesos; }
.ops .auto-tabs { margin-left: auto; }
.ops .auto-vista .timeline .cuerpo b { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.ops .auto-vista .timeline li[aria-selected='true'] .nodo { background: var(--s2-2); }
/* con una sola ejecución (filtro Incidencias) el raíl vertical sobra */
.ops .auto-vista .timeline:has(li:only-child)::before { display: none; }

.ops .auto-det-sub { display: block; margin-top: 3px; font-size: 12.5px; color: var(--tx-dim); }
.ops .auto-det-chip { margin-left: auto; flex: none; }
.ops .auto-det-txt { margin: 0; font-size: 13px; color: var(--tx-mu); }
.ops .auto-det-tit {
  margin: 0 0 11px; font-family: var(--display); font-weight: 600; font-size: 12px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--tx-dim);
}
.ops .auto-det-cta { width: 100%; }

/* regla legible: cuándo salta y qué hace */
.ops .auto-regla {
  display: grid; gap: 7px; padding: 11px 13px; border-radius: var(--r-m);
  border: 1px solid var(--linea-suave); background: var(--velo);
}
.ops .auto-regla-fila { display: grid; grid-template-columns: 74px minmax(0, 1fr); gap: 10px; align-items: baseline; }
.ops .auto-regla-et { font-size: 12px; letter-spacing: .05em; text-transform: uppercase; color: var(--tx-dim); }
.ops .auto-regla-fila p { margin: 0; font-size: 13px; color: var(--tx-mu); }

/* cadena causal de la ejecución de la demo */
.ops .auto-cadena { list-style: none; margin: 0; padding: 0; display: grid; gap: 13px; counter-reset: paso; }
.ops .auto-cadena li { position: relative; padding-left: 31px; counter-increment: paso; }
.ops .auto-cadena li::before {
  content: counter(paso); position: absolute; left: 0; top: 0; width: 22px; height: 22px;
  border-radius: 50%; display: grid; place-items: center; font-family: var(--display);
  font-weight: 600; font-size: 12px; color: var(--c-azul);
  background: rgba(79, 140, 255, .14); border: 1px solid rgba(79, 140, 255, .34);
}
.ops .auto-cadena li::after {
  content: ''; position: absolute; left: 11px; top: 25px; bottom: -13px; width: 1px; background: var(--linea);
}
.ops .auto-cadena li:last-child::after { display: none; }
.ops .auto-cadena li:last-child::before {
  color: var(--c-menta); background: rgba(46, 230, 197, .14); border-color: rgba(46, 230, 197, .34);
}
.ops .auto-cadena b { display: block; font-size: 13px; font-weight: 500; color: var(--tx); }
.ops .auto-cadena p { margin: 3px 0 0; font-size: 12.5px; color: var(--tx-mu); }

/* procesos conectados */
.ops .auto-procesos { display: grid; gap: 10px; }
.ops .auto-proceso {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.9fr) auto; gap: 18px;
  align-items: center; padding: 13px 15px; border: 1px solid var(--linea);
  border-radius: var(--r-m); background: var(--velo);
}
.ops .auto-proceso .auto-regla { border: 0; background: transparent; padding: 0; }
.ops .auto-proceso-id b {
  display: block; font-family: var(--display); font-weight: 600; font-size: 14px; letter-spacing: -.01em;
}
.ops .auto-proceso-meta { display: flex; align-items: center; gap: 9px; margin-top: 6px; }
.ops .auto-proceso-meta span { font-size: 12.5px; color: var(--tx-dim); font-variant-numeric: tabular-nums; }
.ops .auto-proceso-cifras { text-align: right; max-width: 200px; }
.ops .auto-proceso-cifras b {
  display: block; font-family: var(--display); font-weight: 600; font-size: 22px;
  letter-spacing: -.03em; line-height: 1.1; font-variant-numeric: tabular-nums;
}
.ops .auto-proceso-cifras span { font-size: 12.5px; color: var(--tx-dim); }
.ops .auto-proceso--pausado { border-style: dashed; background: transparent; }
.ops .auto-proceso--pausado .auto-proceso-id b, .ops .auto-proceso--pausado .auto-proceso-cifras b { color: var(--tx-dim); }
.ops .auto-proceso--pausado .auto-regla { opacity: .6; }
.ops .auto-proceso--ligado { border-color: rgba(79, 140, 255, .42); background: rgba(79, 140, 255, .07); }

@media (max-width: 980px) {
  .ops .auto-grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: none; }
  .ops .auto-registro, .ops .auto-detalle, .ops .auto-procesos-tarjeta { grid-area: auto; }
  .ops .auto-proceso { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .ops .auto-proceso-cifras { max-width: none; text-align: left; display: flex; align-items: baseline; gap: 9px; }
  .ops .auto-proceso-cifras b { font-size: 19px; }
}
@media (max-width: 560px) {
  .ops .auto-cifras { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .ops .auto-cifras > div {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; padding: 12px 0;
  }
  .ops .auto-cifras > div:first-child { padding-top: 0; }
  .ops .auto-cifras > div:last-child { padding-bottom: 0; }
  .ops .auto-cifras > div + div { border-left: 0; padding-left: 0; border-top: 1px solid var(--linea-suave); }
  .ops .auto-cifras .kpi-val { margin-top: 0; text-align: right; }
  .ops .auto-cifras .kpi-pie { grid-column: 1 / -1; margin-top: 5px; }
  .ops .auto-regla-fila { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .ops .auto-vista .timeline .hora { align-self: flex-start; }
  /* la cabecera de tarjeta se parte: título arriba, controles a ancho completo */
  .ops .auto-vista .tarjeta-cab { flex-wrap: wrap; }
  .ops .auto-vista .tarjeta-cab .nota { width: 100%; margin-left: 0; }
  .ops .auto-tabs { width: 100%; margin-left: 0; }
  .ops .auto-tabs button { flex: 1; }
}

/* ══ Módulo Resumen (prefijo .res-) ═══════════════════════════════════════
   Una alerta a todo el ancho, el foco de ventas con dos apoyos a su derecha y
   los automatismos cerrando. Nada más: la portada respira. */
.ops .res-flujo { display: grid; gap: 14px; }
.ops .res-grid { grid-template-columns: minmax(0, 1.62fr) minmax(304px, 1fr); align-items: start; }
.ops .res-col { align-content: start; }

.ops .res-alerta { align-items: center; }
.ops .res-alerta .aviso-ico { align-self: flex-start; margin-top: 1px; }

/* foco: cifra + variación + tendencia */
.ops .res-cifra { display: flex; align-items: baseline; gap: 8px 18px; flex-wrap: wrap; }
.ops .res-var { display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--tx-dim); }
.ops .res-graf { margin-top: 18px; }

/* fila de apoyo dentro de una tarjeta */
.ops .res-linea {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--linea-suave);
}
.ops .res-linea-tit { font-family: var(--display); font-weight: 600; font-size: 13.5px; color: var(--tx); }
.ops .res-linea-sub { font-size: 12.5px; color: var(--tx-dim); font-variant-numeric: tabular-nums; margin-top: 2px; }
.ops .res-btn-ancho { width: 100%; margin-top: 14px; }
.ops .res-btn-cab { margin-left: auto; padding: 7px 12px; font-size: 12.5px; white-space: nowrap; }

.ops .res-cab-kpi { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.ops .res-cab-kpi .chip { flex: none; margin-top: 3px; }
.ops .res-comp { margin-top: 16px; }
.ops .res-plan { margin: 12px 0 0; color: var(--c-menta-tx); }

/* automatismos: historial + dos cifras */
.ops .res-auto { display: grid; grid-template-columns: minmax(0, 1fr) 236px; gap: 18px 26px; align-items: start; }
.ops .res-auto-stats {
  display: grid; gap: 18px; padding-left: 24px; border-left: 1px solid var(--linea-suave);
}
.ops .res-auto .timeline li { padding: 0; }
.ops .res-auto-fila {
  flex: 1; min-width: 0; display: flex; align-items: flex-start; gap: 12px;
  background: transparent; border: 0; color: inherit; text-align: left; cursor: pointer;
  padding: 9px 10px 9px 0; border-radius: var(--r-s);
}
.ops .res-auto-fila .cuerpo b { margin-bottom: 1px; }
.ops .res-auto-fila .hora { white-space: nowrap; }

/* tablet: el foco pasa a todo el ancho y los dos apoyos se reparten la fila */
@media (max-width: 900px) {
  .ops .res-grid { grid-template-columns: 1fr; }
  .ops .res-col { grid-template-columns: 1fr 1fr; align-items: start; }
  .ops .res-auto { grid-template-columns: 1fr; }
  .ops .res-auto-stats {
    grid-template-columns: 1fr 1fr; padding-left: 0; border-left: 0;
    padding-top: 16px; border-top: 1px solid var(--linea-suave);
  }
}
/* móvil: columna única, controles a ancho completo */
@media (max-width: 720px) {
  .ops .res-col { grid-template-columns: 1fr; }
  .ops .res-alerta { display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 12px; }
  .ops .res-alerta .btn { grid-column: 1 / -1; margin-left: 0; width: 100%; }
  .ops .res-auto-stats { grid-template-columns: 1fr; gap: 14px; }
  .ops .res-auto-fila { padding-right: 0; }
  .ops .res-cifra { gap: 6px 14px; }
}

/* ── módulo 3 · Almacén ───────────────────────────────────────────────── */
.ops .alm-ctrl { margin-left: auto; display: flex; align-items: center; gap: 9px; }
.ops .alm-ctrl label { font-size: 12.5px; color: var(--tx-dim); }

.ops .alm-rejilla {
  display: grid; gap: 14px; align-items: start;
  grid-template-columns: minmax(0, 1.5fr) minmax(300px, 1fr);
}

/* estado del almacén: composición a la izquierda, cobertura a la derecha */
.ops .alm-estado { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 18px 28px; align-items: center; }
.ops .alm-estado-kpi { border-left: 1px solid var(--linea); padding-left: 28px; min-width: 232px; }
.ops .alm-pie { margin: 12px 0 0; font-size: 12.5px; color: var(--tx-dim); max-width: 66ch; }

/* recomendación: causalidad numerada, no una cifra suelta */
.ops .alm-reco { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 13px; counter-reset: paso; }
.ops .alm-reco li { position: relative; padding-left: 31px; counter-increment: paso; }
.ops .alm-reco li::before {
  content: counter(paso); position: absolute; left: 0; top: 1px;
  width: 21px; height: 21px; border-radius: 50%; display: grid; place-items: center;
  font-family: var(--display); font-weight: 600; font-size: 11.5px; color: var(--c-azul-tx);
  background: rgba(79, 140, 255, .13); border: 1px solid rgba(79, 140, 255, .3);
}
.ops .alm-reco b, .ops .alm-lead b {
  display: block; font-family: var(--display); font-weight: 600; font-size: 12px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--tx-dim); margin-bottom: 3px;
}
.ops .alm-reco p { margin: 0; font-size: 14px; color: var(--tx-mu); }
.ops .alm-lead { margin: 16px 0 0; font-size: 14px; color: var(--tx-mu); }

.ops .alm-pedidos { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.ops .alm-ped {
  display: inline-flex; align-items: baseline; gap: 8px; cursor: pointer;
  background: var(--velo); border: 1px solid var(--linea); border-radius: 999px;
  padding: 6px 14px; font-size: 12.5px; color: var(--tx-mu);
  transition: background-color var(--t-rapido), border-color var(--t-rapido), color var(--t-rapido);
}
.ops .alm-ped:hover { background: rgba(79, 140, 255, .11); border-color: rgba(79, 140, 255, .38); color: var(--tx); }
.ops .alm-ped b { font-family: var(--display); font-weight: 600; font-size: 13.5px; color: var(--tx); }
.ops .alm-ped em { font-style: normal; font-size: 12px; color: var(--tx-dim); }

.ops .alm-acciones { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px; margin-top: 18px; }
.ops .alm-acciones-pie { font-size: 12.5px; color: var(--tx-dim); }

/* estado tras ejecutar */
.ops .alm-estado-rep { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin-top: 14px; }
.ops .alm-estado-rep span { font-size: 12.5px; color: var(--tx-dim); }
.ops .alm-campos-rep { margin: 14px 0 0; max-width: 520px; }

/* tabla de referencias */
.ops .alm-t { margin-top: 2px; }
/* las magnitudes se agrupan a la derecha: la columna de referencia absorbe el ancho sobrante */
.ops .alm-t .alm-c-op { width: 130px; }
.ops .alm-t .alm-c-saldo { width: 96px; }
.ops .alm-t .alm-c-estado { width: 190px; }
.ops .alm-t tbody tr[aria-current='true'] { background: rgba(79, 140, 255, .12); }
.ops .alm-ref b { font-family: var(--display); font-weight: 600; font-size: 13.5px; color: var(--tx); }
.ops .alm-ref span { display: block; font-size: 12.5px; color: var(--tx-dim); }
.ops .alm-neg { color: var(--c-coral-tx); }
.ops .alm-ok { color: var(--c-menta-tx); }

/* detalle de referencia */
.ops .alm-detalle { position: sticky; top: 82px; }
.ops .alm-detalle .detalle-cab { gap: 12px; }
.ops .alm-sub { margin: 3px 0 0; font-size: 12.5px; color: var(--tx-dim); }
.ops .alm-detalle-chip { margin-left: auto; }
.ops .alm-rot-cab {
  display: flex; justify-content: space-between; gap: 12px; margin-bottom: 8px;
  font-size: 12.5px; color: var(--tx-dim);
}
.ops .alm-entrada {
  margin: 0; font-size: 13px; color: var(--tx-mu); padding: 10px 13px; border-radius: var(--r-s);
  border-left: 2px solid var(--linea); background: var(--velo);
}
.ops .alm-entrada.tarde { border-left-color: var(--c-coral); }
.ops .alm-entrada.ok { border-left-color: var(--c-menta); }

@media (max-width: 1080px) {
  .ops .alm-rejilla { grid-template-columns: 1fr; }
  /* en una columna el detalle va DESPUÉS de la lista que lo selecciona */
  .ops .alm-rejilla > .alm-detalle { position: static; order: 2; }
}
@media (max-width: 760px) {
  .ops .alm-cab { flex-wrap: wrap; }
  .ops .alm-rejilla .tarjeta-cab { flex-wrap: wrap; row-gap: 3px; }
  .ops .alm-rejilla .tarjeta-cab .nota { margin-left: 0; }
  .ops .alm-ctrl { margin-left: 0; width: 100%; }
  .ops .alm-ctrl select { flex: 1; min-width: 0; }
  .ops .alm-estado { grid-template-columns: 1fr; gap: 16px; }
  .ops .alm-estado-kpi {
    border-left: 0; padding-left: 0; min-width: 0;
    border-top: 1px solid var(--linea-suave); padding-top: 16px;
  }
  .ops .alm-c-op, .ops .alm-c-saldo { display: none; }
  .ops .alm-t .alm-c-estado { width: auto; }
  .ops .alm-t td, .ops .alm-t th { padding-right: 0; }
  .ops .alm-reco li { padding-left: 28px; }
  .ops .alm-acciones .btn { width: 100%; }
  .ops .alm-ped { flex-wrap: wrap; }
}

/* punto final del gráfico de área: capa CSS para que no se deforme (ver ui.js) */
.ops .grafico-punto { position: absolute; width: 9px; height: 9px; border-radius: 50%;
  background: var(--s2-2); border: 2.2px solid var(--c-menta); transform: translate(-50%, -50%);
  pointer-events: none; }

/* ── Almacén: sumario ejecutable antes del pliegue (auditoría, punto 5) ────── */
.ops .alm-sumario { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 12px 0 4px; }
.ops .alm-sum-item { background: var(--velo); border: 1px solid var(--linea);
  border-radius: var(--r-m); padding: 10px 12px; min-width: 0; }
.ops .alm-sum-item dt { font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--tx-dim); margin: 0 0 4px; }
.ops .alm-sum-item dd { margin: 0; font-size: 13.5px; color: var(--tx); }
.ops .alm-detalle-reco { margin-top: 12px; border-top: 1px solid var(--linea-suave); padding-top: 10px; }
.ops .alm-detalle-reco > summary { cursor: pointer; font-family: var(--display); font-weight: 600;
  font-size: 13px; color: var(--tx-mu); list-style: none; padding: 4px 0; }
.ops .alm-detalle-reco > summary::-webkit-details-marker { display: none; }
.ops .alm-detalle-reco > summary::before { content: '▸ '; color: var(--tx-dim); }
.ops .alm-detalle-reco[open] > summary::before { content: '▾ '; }
.ops .alm-detalle-reco > summary:hover { color: var(--tx); }

/* ── móvil: el detalle de pedido se abre como hoja inferior, no al final de la página ── */
@media (max-width: 760px) {
  .ops .alm-sumario { grid-template-columns: 1fr; gap: 8px; }
  .ops .ventas-detalle {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 50; margin: 0;
    max-height: 82vh; overflow-y: auto; border-radius: var(--r-xl) var(--r-xl) 0 0;
    box-shadow: var(--sombra-hoja);
    animation: ops-hojaEntra var(--t-medio) var(--e-salida) both;
  }
  .ops .ventas-detalle::before {
    content: ''; display: block; width: 40px; height: 4px; border-radius: 999px;
    background: var(--linea); margin: 0 auto 12px;
  }
  @keyframes ops-hojaEntra { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
}

/* ══ Módulo 0 · Inicio, el lanzador (prefijo .ini- / .mod) ═══════════════════
   La jerarquía es deliberada y NO es la rejilla uniforme de iconos de un ERP clásico:
   las cuatro baldosas activas son tarjetas con dato y estado, y las áreas fuera del
   alcance de la demo son fichas pequeñas y apagadas. Lo que se puede tocar se ve que
   se puede tocar. */
.ops .ini { display: flex; flex-direction: column; gap: 22px; }

.ops .ini-cab h1 {
  font-family: var(--display); font-weight: 600; font-size: 28px; letter-spacing: -.035em;
  line-height: 1.08; margin: 4px 0 0; text-wrap: balance;
}
.ops .ini-cab p { margin: 9px 0 0; font-size: 14px; color: var(--tx-mu); max-width: 68ch; }

/* la alerta principal, aquí en peso de línea (la caja grande vive en Resumen) */
.ops .ini-atencion {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--linea); border-radius: var(--r-m);
  background: var(--s1);
}
.ops .ini-atencion--critica {
  border-color: rgba(224, 104, 92, .38); background: rgba(224, 104, 92, .07);
}
.ops .ini-atencion-ico { display: grid; place-items: center; color: var(--c-ambar); flex: 0 0 auto; }
.ops .ini-atencion--critica .ini-atencion-ico { color: var(--c-coral); }
.ops .ini-atencion p { margin: 0; font-size: 13px; color: var(--tx-mu); min-width: 0; }
.ops .ini-atencion p b { color: var(--tx); font-family: var(--display); font-weight: 600; }
.ops .ini-atencion .btn { margin-left: auto; flex: 0 0 auto; }

/* ── las cuatro baldosas activas ──────────────────────────────────────── */
.ops .ini-rejilla {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 246px), 1fr));
}

.ops .mod {
  position: relative; overflow: hidden; width: 100%; height: 100%;
  display: flex; flex-direction: column; gap: 6px; text-align: left;
  padding: 16px 16px 15px; cursor: pointer;
  background: var(--s2); border: 1px solid var(--linea); border-radius: var(--r-l);
  box-shadow: var(--sombra-1);
  transition: transform var(--t-rapido) var(--e-salida),
              border-color var(--t-rapido), background-color var(--t-rapido);
}
.ops .mod:hover { transform: translateY(-2px); border-color: var(--linea-fuerte); background: var(--s3); }
.ops .mod:active { transform: translateY(0); }
/* franja de severidad: el estado se lee por FORMA, no solo por color */
.ops .mod::before {
  content: ''; position: absolute; inset: 0 auto 0 0; width: 3px; background: transparent;
}
.ops .mod--atencion { border-color: rgba(224, 104, 92, .34); }
.ops .mod--atencion::before { background: var(--c-coral); }
.ops .mod--plan::before { background: var(--c-ambar); }

.ops .mod-fila { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ops .mod-ico {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: var(--r-s);
  color: var(--c-azul); background: rgba(79, 140, 255, .12);
  border: 1px solid rgba(79, 140, 255, .22);
}
.ops .mod--atencion .mod-ico {
  color: var(--c-coral); background: rgba(224, 104, 92, .12);
  border-color: rgba(224, 104, 92, .26);
}
.ops .mod-nom {
  font-family: var(--display); font-weight: 600; font-size: 16.5px; letter-spacing: -.02em;
  color: var(--tx); margin-top: 4px;
}
.ops .mod-desc { font-size: 12.5px; color: var(--tx-dim); line-height: 1.45; }
.ops .mod-cifra {
  font-family: var(--display); font-weight: 600; font-size: 24px; letter-spacing: -.035em;
  color: var(--tx); margin-top: auto; padding-top: 12px; font-variant-numeric: tabular-nums;
}
.ops .mod--atencion .mod-cifra { color: var(--c-coral-tx); }
.ops .mod-pie { font-size: 12px; color: var(--tx-dim); line-height: 1.4; }

/* ── el resto del sistema: presente, apagado y declarado como ausente ─── */
.ops .ini-alcance { border-top: 1px solid var(--linea-suave); padding-top: 18px; }
.ops .ini-alcance h2 {
  font-family: var(--display); font-weight: 600; font-size: 14px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--tx-dim); margin: 0;
}
.ops .ini-alcance > p { margin: 6px 0 13px; font-size: 12.5px; color: var(--tx-dim); max-width: 62ch; }
.ops .ini-off {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 168px), 1fr));
}
.ops .mod-off {
  display: flex; align-items: center; gap: 10px; padding: 11px 13px;
  border: 1px dashed var(--linea); border-radius: var(--r-m);
  background: rgba(255, 255, 255, .015); color: var(--tx-dim);
}
.ops .mod-off .mod-ico {
  width: 28px; height: 28px; color: var(--tx-dim);
  background: rgba(255, 255, 255, .04); border-color: var(--linea);
}
.ops .mod-off .mod-nom { font-size: 13.5px; color: var(--tx-mu); margin-top: 0; }
.ops .mod-off-et { margin-left: auto; font-size: 11.5px; color: var(--tx-dim); white-space: nowrap; }

.ops .ini-pie { margin: 0; font-size: 11.5px; color: var(--tx-dim); }

@media (max-width: 760px) {
  .ops .ini-cab h1 { font-size: 23px; }
  .ops .mod-cifra { font-size: 21px; }
  /* el botón no puede estrangular el texto de la alerta: baja a su propia línea */
  .ops .ini-atencion { flex-wrap: wrap; }
  .ops .ini-atencion p { flex: 1 1 60%; }
  .ops .ini-atencion .btn { margin-left: 0; flex: 1 1 100%; }
  /* a dos columnas, «No incluido» se salía de la ficha */
  .ops .ini-off { grid-template-columns: 1fr; }
}

/* ══ Módulo 0 · Inicio, la HOME de módulos (prefijo .hom-) ═══════════════════
   Boceto A «Escritorio», portado a la app real. DOS PLANOS y UNA cámara:
   la rejilla viva (los módulos que se abren) y, una capa por debajo, el zócalo
   inclinado con los que esta demo no simula. El 3D no decora: dice «hay más
   máquina, apagada». Los filetes de 1 px cruzan del plano de arriba al de abajo
   y convergen con él: líneas de fuga comunes, una sola operación de cámara.
   Nada que ver con el bloque `.ini-*`/`.mod*` de arriba, que es del panel del
   capítulo (know_how.html) y se queda como está. */
.ops .hom {
  flex: 1 1 auto; display: flex; flex-direction: column;
  perspective: 1500px;          /* UNA sola cámara para toda la escena */
  /* el zócalo se va por debajo del encuadre a propósito: se recorta aquí (en la caja de
     la vista, que llega justo al borde del lienzo) para que ese sangrado no abra scroll */
  overflow: hidden;
  /* la entrada del lanzador es el stagger de sus piezas, no un fundido del bloque:
     dos entradas a la vez = ninguna se lee */
  animation: none;
}

/* `minmax(0,1fr)`, no `1fr`: con `1fr` (= minmax(auto,1fr)) el mínimo es el CONTENIDO, así que
   entre 761 y 830 px la cuarta baldosa se salía 93 px del contenedor sin scroll que la rescatara
   (medido a 768: `.ops-scroll` acaba en x=753 y el módulo en x=846) y las cuatro dejaban de
   medir lo mismo. */
.ops .hom-rejilla {
  display: grid; gap: 8px;
  grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1fr) 1px minmax(0, 1fr) 1px minmax(0, 1fr);
}
.ops .hom-fil { width: 1px; height: calc(100% + 32px); background: var(--linea); }

/* ── rejilla viva: el protagonista del lienzo ──────────────────────────── */
.ops .hom-viva {
  position: relative; z-index: 2; flex: 1 1 auto; max-height: 280px;
  /* sombra del plano de arriba PROYECTADA sobre el de abajo: la única señal de 3D
     que sobrevive en móvil, donde la inclinación se apaga */
  box-shadow: var(--sombra-2);
}
.ops .hom-bal {
  position: relative; display: flex; flex-direction: column; align-items: flex-start;
  justify-content: space-between; text-align: left;
  width: 100%; height: 100%; min-height: 200px; padding: 24px; cursor: pointer;
  background: var(--s2); border: 1px solid var(--linea); border-radius: var(--r-xl);
  transition: transform var(--t-medio) var(--e-salida), border-color var(--t-rapido) var(--e-salida);
}
.ops .hom-bal::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  opacity: 0; box-shadow: var(--sombra-2); transition: opacity var(--t-medio) var(--e-salida);
}
.ops .hom-bal:hover { transform: translateY(-4px); border-color: var(--linea-fuerte); }
.ops .hom-bal:hover::after { opacity: 1; }
.ops .hom-bal:active { transform: translateY(-1px); }
/* icono y chip en la MISMA fila, no el chip en absoluto sobre el icono: posicionado, entre
   761 y 1000 px el chip caía encima del icono (medido a 900: 28 px de solape; a 768, total). */
.ops .hom-cab {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 10px; width: 100%; min-width: 0;
}
.ops .hom-ico {
  flex: 0 0 auto; width: 38px; height: 38px; border-radius: var(--r-s);
  display: grid; place-items: center; background: var(--velo-fuerte); color: var(--tx);
}
.ops .hom-tx { display: block; }
.ops .hom-nom {
  display: block; font-family: var(--display); font-weight: 600; font-size: 23px;
  letter-spacing: -.032em; line-height: 1.05; margin: 0 0 4px; color: var(--tx);
}
.ops .hom-sen { display: block; font-size: 13px; line-height: 1.45; color: var(--tx-dim); }
/* la cifra EMPATA con el nombre (23px): un protagonista por fotograma */
.ops .hom-cifra { display: flex; align-items: baseline; gap: 8px; margin-top: 8px; font-family: var(--display); }
/* peso 700, no 600: el azul del dato da 3,29:1 sobre blanco, que es AA **como texto grande**
   (≥18,66 px en negrita). A 600 —semi-negrita— el umbral aplicable sería discutible, y a 390 px
   la cifra baja a 20 px. Con 700 la baldosa cumple sin depender de la interpretación, y el azul
   de marca sigue siendo el único color del fotograma, como en el boceto. */
.ops .hom-cifra b {
  font-weight: 700; font-size: 23px; letter-spacing: -.035em; line-height: 1;
  color: var(--c-azul-dato); font-variant-numeric: tabular-nums;
}
.ops .hom-delta {
  font-family: var(--body); font-size: 12px; font-weight: 500; color: var(--tx-mu);
  background: var(--velo-fuerte); border-radius: 999px; padding: 3px 8px;
}
/* píldora de foco con el dato en color: dentro de ella el acento conserva su valor de
   marca (misma excepción que shell.css, el puerto del rail), porque sobre la superficie
   clara a pelo la menta da 1,6:1 y el coral 3,1:1. */
.ops .hom-chip {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  background: var(--c-crema); color: var(--tx-inv); border-radius: 999px;
  padding: 4px 10px 4px 8px; font-size: 12px; font-weight: 500; line-height: 1.4;
}
.ops .hom-pt { width: 7px; height: 7px; border-radius: 50%; background: #2ee6c5; }
.ops .hom-chip--alerta svg { color: #e0685c; }
/* La baldosa de ENTRADA (por la que se seguiría) es el único objeto de contraste máximo del
   encuadre, como en el boceto. No lleva `aria-current`: no estás en ese módulo, se te sugiere
   —el dato semántico sería falso y el peso visual ya lo dice todo. */
.ops .hom-bal--entrada { background: var(--c-crema); border-color: var(--c-crema); color: var(--tx-inv); }
.ops .hom-bal--entrada .hom-nom,
.ops .hom-bal--entrada .hom-sen,
.ops .hom-bal--entrada .hom-delta,
.ops .hom-bal--entrada .hom-ico { color: inherit; }
/* dentro de la píldora oscura, el chip (que ES una píldora oscura) se invierte o desaparece */
.ops .hom-bal--entrada .hom-ico,
.ops .hom-bal--entrada .hom-delta { background: rgba(255, 255, 255, .12); }
.ops .hom-bal--entrada .hom-chip { background: rgba(255, 255, 255, .14); color: var(--tx-inv); }

/* ── zócalo: los módulos sin activar, misma rejilla, una capa más abajo ─── */
.ops .hom-aire { flex: 0 0 32px; }
/* bisagra en el borde que toca la rejilla viva; el plano CAE HACIA ATRÁS, así sus lados
   convergen hacia dentro y el trapecio se ve. Sangra por los tres lados del lienzo. */
.ops .hom-hundido {
  position: relative; z-index: 1; flex: 1 1 auto; min-height: 224px;
  /* -34 sería el borde del lienzo; los 76 de más son los que la propia inclinación se come
     (el canto de abajo se va hacia el fondo y sube en pantalla ~13%): sin ellos el plano
     terminaba EN CUADRO, con un filo diagonal y carta blanca debajo. Medido a 1440×900. */
  margin: 0 -22px -110px; padding: 40px 22px;
  border-radius: var(--r-xxl) var(--r-xxl) 0 0;
  background: var(--hueco, var(--s1));
  transform: rotateX(-15deg) scale(1.03); transform-origin: 50% 0;
  overflow: hidden;
}
/* Las fichas van PEGADAS a la bisagra, como en el boceto: el encuadre real es ~250 px más
   alto que la tarjeta del boceto (allí flotaba sobre la mesa, aquí llega al borde de la
   pantalla) y ese sobrante se lo queda el suelo, que se va del encuadre. Probado repartirlo
   (fichas centradas en el plano, p3c): los dos planos dejan de leerse como capas contiguas. */
.ops .hom-hundido .hom-rejilla { grid-auto-rows: 144px; }
/* el cableado no se detiene en el borde: cruza el plano y converge con él */
.ops .hom-hundido .hom-fil { height: 1200px; margin-top: -40px; }
.ops .hom-off {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  min-height: 144px; padding: 16px; border-radius: var(--r-l);
  background: var(--velo); border: 1px solid var(--linea-suave); color: var(--tx-mu);
}
.ops .hom-off-nom {
  font-family: var(--display); font-weight: 500; font-size: 16px; letter-spacing: -.025em;
  color: var(--tx-mu); line-height: 1.2; margin-top: auto;
}
.ops .hom-off-chip {
  font-size: 12px; font-weight: 500; color: var(--tx-dim); white-space: nowrap;
  border: 1px solid var(--linea-fuerte); border-radius: 999px; padding: 2px 8px;
}

/* entrada: stagger de 60 ms, sólo transform/opacity. El gate de reduced-motion de
   tokens.css deja el fotograma final intacto. */
@keyframes ops-homEntra { from { opacity: 0; transform: translateY(12px); } }
.ops .hom-anim { animation: ops-homEntra .52s var(--e-entrada) both; animation-delay: calc(var(--i) * 60ms); }

/* Entre 1000 y 1250 la fila de cuatro sigue cabiendo, pero la baldosa baja de ~215 px de caja
   interior y la cifra deja de caber con su delta al lado: medido a 1024, «362.760 €» partía el
   símbolo a un segundo renglón. La cifra y su variación se apilan (es la misma solución que ya
   usa el móvil) y el nombre cede 2 px. */
@media (max-width: 1250px) {
  .ops .hom-cifra { flex-direction: column; align-items: flex-start; gap: 6px; }
  .ops .hom-nom { font-size: 21px; }
}

/* Por debajo de 1000 px la fila de cuatro deja de caber: el rail ya está contraído y al lienzo
   le quedan ~650-900 px, donde cada baldosa bajaría de 160 px y el nombre se parte. Pasa a 2×2 y
   se apaga la inclinación: con dos columnas el trapecio ya no tiene líneas de fuga que convergan
   y el 3D se vuelve decoración —justo lo que el contrato prohíbe. Sobrevive el hueco y la sombra
   proyectada, que es lo que dice «capa de abajo de la misma máquina». */
@media (max-width: 1000px) {
  .ops .hom { perspective: none; }
  .ops .hom-fil { display: none; }
  .ops .hom-rejilla { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .ops .hom-viva { flex: 0 0 auto; max-height: none; }
  .ops .hom-bal { min-height: 168px; height: auto; padding: 18px; }
  .ops .hom-nom { font-size: 20px; }
  .ops .hom-hundido {
    min-height: 0; margin: 0 -22px -40px; padding: 28px 22px 40px;
    border-radius: var(--r-xl) var(--r-xl) 0 0; transform: none;
  }
  .ops .hom-hundido .hom-rejilla { grid-auto-rows: auto; }
  .ops .hom-off { min-height: 108px; }
}

@media (max-width: 760px) {
  .ops .hom-bal { padding: 16px; }
  .ops .hom-ico { width: 32px; height: 32px; }
  .ops .hom-sen { font-size: 12px; }
  .ops .hom-cifra { flex-direction: column; align-items: flex-start; gap: 6px; }
  .ops .hom-cifra b { font-size: 20px; }
  .ops .hom-chip { padding: 3px 8px 3px 7px; }
  /* -40 es justo el borde inferior del lienzo (padding 14 del móvil + sangrado) */
  .ops .hom-hundido { margin: 0 -14px -40px; padding: 24px 14px 40px; }
  .ops .hom-off { min-height: 96px; }
}

/* ══ ajustes de componente que sólo tienen sentido en CLARO ═══════════════ */

/* La cifra display iba en degradado azul claro→menta con el texto en
   `transparent`: sobre blanco quedaba casi invisible. En claro es una sola
   tinta, la del dato (3,1:1 — texto grande, AA), como en el boceto. */
.ops-capa .kpi-val--xl {
  background: none; color: var(--c-azul-dato); -webkit-text-fill-color: var(--c-azul-dato);
}

/* ── el velo de MARCA sobre negro se vuelve mobiliario lavanda sobre blanco ──────
   Todo este grupo es el mismo patrón: en oscuro, `rgba(79,140,255,α)` es una luz azul que
   insinúa un borde o un relleno; en claro es una mancha periwinkle sobre blanco, y acaba
   pintando de lavanda cosas que no significan «azul» (la tarjeta de foco de los cuatro
   módulos, la fila seleccionada, el hover de una píldora). En claro el mobiliario es NEUTRO
   —línea y velo de tinta— y el azul se reserva al dato. */
.ops-capa .tarjeta--foco { border-color: var(--linea-fuerte); }
.ops-capa .btn--primario { box-shadow: none; }   /* la luz aditiva no existe sobre claro */

/* UN solo idioma para «esto está seleccionado» en toda la aplicación: velo de tinta + filete
   a la izquierda. Antes convivían tres (banda lavanda en Almacén, banda neutra en Ventas y
   Automatismos, píldora tinta en rail/periodo/pestañas). */
.ops-capa .tabla tbody tr:hover,
.ops-capa .timeline li:hover { background: var(--velo); }
.ops-capa .tabla tbody tr[aria-selected='true'],
.ops-capa .alm-t tbody tr[aria-current='true'],
.ops-capa .timeline li[aria-selected='true'] {
  background: var(--velo-fuerte); box-shadow: inset 2px 0 0 var(--tx);
}
.ops-capa .tabla tbody tr:focus-visible { outline-color: var(--tx); }
.ops-capa .alm-ped:hover { background: var(--velo-fuerte); border-color: var(--linea-fuerte); }

/* la pestaña activa marcaba con 1,18:1 contra la tarjeta —un fantasma justo debajo del
   periodo, que es una píldora tinta a 16,9:1. Mismo estado, mismo objeto. */
.ops-capa .tabs button[aria-selected='true'] {
  color: var(--tx-inv); background: var(--c-crema); border-color: var(--c-crema);
}
.ops-capa .tabs button[aria-selected='true'] .cuenta { color: inherit; opacity: .72; }
.ops-capa .tabs button[aria-selected='true']:focus-visible { outline-color: var(--tx-inv); }

/* numerales y estados de proceso: el azul se queda, pero con el matiz del azul CLARO */
.ops-capa .auto-cadena li::before,
.ops-capa .alm-reco li::before {
  color: var(--c-azul); background: rgba(47, 71, 189, .10); border-color: rgba(47, 71, 189, .26);
}
.ops-capa .auto-cadena li:last-child::before {
  color: var(--c-menta); background: rgba(13, 125, 107, .10); border-color: rgba(13, 125, 107, .26);
}
.ops-capa .auto-proceso--ligado { border-color: rgba(47, 71, 189, .34); background: rgba(47, 71, 189, .06); }

/* Ficha del zócalo: sobre el plano mentolado la ficha ACLARA (así se despega del
   suelo), mientras que en oscuro el mismo papel lo hace el velo de tinta. */
.ops-capa .hom-off { background: rgba(255, 255, 255, .52); border-color: rgba(14, 21, 18, .06); }

/* Bordes de chip: a α .30 sobre blanco el contorno desaparecía. */
.ops-capa .chip--azul { border-color: rgba(47, 71, 189, .3); }
.ops-capa .chip--menta { border-color: rgba(13, 125, 107, .3); }
.ops-capa .chip--ambar { border-color: rgba(138, 100, 16, .3); }
.ops-capa .chip--coral { border-color: rgba(178, 60, 47, .3); }

/* Gradientes del gráfico de área: se declaran como atributos en ui.js, y ahí
   el extremo menta (1,5:1) desaparecía sobre blanco. `stop-color` es propiedad
   CSS, así que se corrige desde aquí sin tocar el componente. */
.ops-capa .grafico #relleno stop { stop-color: var(--c-azul-dato); }
.ops-capa .grafico #relleno stop:first-child { stop-opacity: .30; }
.ops-capa .grafico #trazo stop:first-child { stop-color: var(--c-azul); }
.ops-capa .grafico #trazo stop:last-child { stop-color: var(--c-menta); }

/* Las barras degradaban a `rgba(110,134,245,.35)`: sobre negro eso es un pie
   más oscuro, sobre blanco es blanco. La barra perdía la base y flotaba
   (visto en la captura, peor a 390). En claro la mancha de dato es PLANA. */
.ops-capa .barras .barra-btn i { background: var(--c-azul-dato); }
.ops-capa .barras .barra-btn:hover i,
.ops-capa .barras .barra-btn.activa i { background: var(--c-crema); }
