/*
 * ops.css — "Lenguaje de operación" del CRM.
 *
 * Para pantallas de TRABAJO con listas largas (análisis, facturas, cobranzas, personas…):
 * denso y silencioso, pensado para escanear cientos de filas rápido. Distinto del molde
 * "tarjeta de dashboard" (cs-card), que sigue bien para paneles con pocos números.
 *
 * Reglas del lenguaje:
 *   · Todo en grises salvo LA señal → un solo acento ámbar (--act) para "hay que actuar".
 *   · Números en monoespaciada tabular, alineados a la derecha (los dígitos alinean).
 *   · Hairlines en vez de tarjetas; encabezado y filtros fijos.
 *   · Jerarquía por PESO, no por color (ABC A fuerte → C tenue).
 *
 * Todo bajo el prefijo .ops para no filtrar al resto del CRM. Se activa envolviendo el
 * contenido en <div class="ops">. Estrenado en admin/analisis.php (2026-07-20).
 */

/* ── Lenguaje de operación (piloto). Prefijo .ops para no filtrar al resto del CRM. ── */
.ops{ --line:hsl(var(--bc)/.12); --line2:hsl(var(--bc)/.07); --mut:hsl(var(--bc)/.55);
      --act:#f59e0b; --mono:'JetBrains Mono',ui-monospace,monospace; color:hsl(var(--bc)); }
.ops .n{ font-family:var(--mono); font-variant-numeric:tabular-nums; }

/* Barra de filtros: una línea, se pega arriba al scrollear la lista. */
.ops-bar{ position:sticky; top:0; z-index:6; display:flex; flex-wrap:wrap; align-items:center; gap:.5rem 1rem;
          padding:.6rem .1rem; background:hsl(var(--b1)); border-bottom:1px solid var(--line); }
.ops-bar .grp{ display:flex; align-items:center; gap:.4rem; }
.ops-bar label, .ops-sub .lbl{ font-size:.75rem; text-transform:uppercase; letter-spacing:.09em; color:var(--mut); }
.ops-fld{ height:36px; padding:0 .6rem; border:1px solid var(--line); border-radius:6px; background:hsl(var(--b2));
          color:hsl(var(--bc)); font-size:.9rem; font-family:var(--mono); }
.ops-fld:focus{ outline:none; border-color:hsl(var(--bc)/.4); }
/* Acción primaria: azul Meta (--p) + texto blanco (--pc). Acento FIJO → contrasta igual en
   claro y oscuro (no depende del modo). Antes era un botón "inverso" --bc/--b1, frágil. */
.ops-go{ height:36px; padding:0 1rem; border:0; border-radius:6px; background:hsl(var(--p)); color:hsl(var(--pc));
         font-weight:700; font-size:.8rem; cursor:pointer; }
.ops-go:hover{ background:hsl(var(--pf)); }
/* Botones de FORMATO: el color dice qué sale antes de leer el texto — verde la planilla que
   abre Excel, primario la hoja para imprimir o guardar como PDF. Van con ícono en línea (svg,
   no fuente de íconos: se pintan con currentColor y no dependen de que cargue nada). */
.ops-fmt{ height:36px; padding:0 .9rem; border:0; border-radius:6px; font-weight:700; font-size:.8rem;
          cursor:pointer; display:inline-flex; align-items:center; gap:.4rem; text-decoration:none;
          line-height:1; font-family:inherit; }
.ops-fmt svg{ width:15px; height:15px; flex:none; }
.ops-fmt.xls{ background:hsl(var(--su)); color:hsl(var(--suc)); }
.ops-fmt.pdf{ background:hsl(var(--p));  color:hsl(var(--pc)); }
.ops-fmt:hover{ filter:brightness(.92); }

.ops-chk{ display:inline-flex; align-items:center; gap:.4rem; font-size:.85rem; color:var(--mut); cursor:pointer; user-select:none; }
.ops-chk input{ accent-color:var(--act); }

/* Segunda fila fina: períodos + CSV. */
.ops-sub{ display:flex; flex-wrap:wrap; align-items:center; gap:.35rem; padding:.5rem .1rem; border-bottom:1px solid var(--line2); }
.ops-sub .lbl{ margin-right:.2rem; }   /* tamaño y color: regla compartida con .ops-bar label */
.chip{ font-size:.95rem; font-family:var(--mono); padding:.28rem .7rem; border:1px solid var(--line); border-radius:20px;
       color:var(--mut); text-decoration:none; white-space:nowrap; }
.chip:hover{ border-color:hsl(var(--bc)/.35); color:hsl(var(--bc)); }
.chip.on{ background:hsl(var(--p)); color:hsl(var(--pc)); border-color:hsl(var(--p)); }

/* KPIs: tira delgada, no tarjetas. */
.ops-kpis{ display:flex; flex-wrap:wrap; gap:0; margin:.9rem 0; border:1px solid var(--line); border-radius:8px; overflow:hidden; background:hsl(var(--b2)); }
.ops-kpi{ flex:1 1 0; min-width:140px; padding:.7rem 1rem; border-right:1px solid var(--line2); }
.ops-kpi:last-child{ border-right:0; }
.ops-kpi .k{ font-size:.72rem; text-transform:uppercase; letter-spacing:.09em; color:var(--mut); }
.ops-kpi .v{ font-family:var(--mono); font-variant-numeric:tabular-nums; font-size:1.5rem; font-weight:700; line-height:1.1; margin-top:.15rem; }
.ops-kpi .s{ font-size:.85rem; color:var(--mut); }
.ops-kpi.act .v{ color:var(--act); }
/* KPI que además es filtro (los tramos de antigüedad en Cobranzas). */
a.ops-kpi{ text-decoration:none; color:inherit; cursor:pointer; }
a.ops-kpi:hover{ background:hsl(var(--bc)/.04); }
.ops-kpi.on{ background:hsl(var(--bc)/.07); box-shadow:inset 0 -2px 0 var(--act); }

/* Tabla: contenedor con scroll propio + encabezado fijo → la lista larga no pierde columnas. */
.ops-tblwrap{ max-height:calc(100vh - 300px); overflow:auto; border:1px solid var(--line); border-radius:8px; background:hsl(var(--b2)); }
.ops-tbl{ width:100%; border-collapse:collapse; font-size:1.1rem; }
.ops-tbl thead th{ position:sticky; top:0; z-index:2; background:hsl(var(--b2)); text-align:left;
    font-size:.8rem; text-transform:uppercase; letter-spacing:.06em; color:var(--mut); font-weight:600;
    padding:.55rem .7rem; border-bottom:1px solid var(--line); white-space:nowrap; }
.ops-tbl td{ padding:.5rem .7rem; border-bottom:1px solid var(--line2); vertical-align:middle; }
.ops-tbl tbody tr:hover{ background:hsl(var(--bc)/.03); }
.ops-tbl tbody tr:last-child td{ border-bottom:0; }
.ops-tbl .r{ text-align:right; white-space:nowrap; }
.ops-tbl tr.low td:first-child{ box-shadow:inset 3px 0 0 var(--act); }   /* señal: filete ámbar SOLO en la 1ª celda */
.ops-tbl .nowrap{ white-space:nowrap; }
.ops-tbl td{ max-width:26rem; overflow-wrap:anywhere; }   /* ninguna celda empuja la tabla fuera */
.ops-tbl tr.clic{ cursor:pointer; }
.ops-tbl tr.dim td{ opacity:.45; }        /* anulada / borrador: presente pero apagada */

/* Fila de totales.
   🪤 NO usar position:sticky acá. La tabla es border-collapse:collapse y los navegadores
   manejan mal el sticky sobre celdas en ese modo: la fila se escapaba del contenedor y
   se desbordaba hacia abajo. El encabezado sí puede ser sticky (top funciona bien); el
   pie no. Los totales igual están arriba en la tira de KPIs, así que no se pierden. */
.ops-tbl tfoot td{ background:hsl(var(--b2));
    border-top:1px solid var(--line); font-weight:700; padding:.55rem .7rem; }

/* Tag genérico quieto (tipo de persona, estado…): gris, sin sumar paleta. */
.tg{ display:inline-block; font-family:var(--mono); font-size:.9rem; color:var(--mut);
     border:1px solid var(--line); border-radius:4px; padding:.05rem .4rem; white-space:nowrap; }
.tg.off{ opacity:.55; }                    /* inactivo / apagado */
.tg.act{ color:var(--act); border-color:hsl(38 92% 50% / .45); }   /* pide acción */

/* Encabezado ordenable (th_orden_ops): el mismo contrato htmx, sin peso visual.
   La flecha solo se enciende en la columna por la que se está ordenando. */
.ops-tbl thead a{ color:inherit; text-decoration:none; display:inline-flex; align-items:center; gap:.3rem; cursor:pointer; user-select:none; }
.ops-tbl thead a:hover{ color:hsl(var(--bc)); }
.ops-tbl thead a .ord{ font-size:.65rem; opacity:.25; }
.ops-tbl thead a.on{ color:hsl(var(--bc)); }
.ops-tbl thead a.on .ord{ opacity:1; color:var(--act); }
.dot{ display:inline-block; width:.5rem; height:.5rem; border-radius:50%; background:hsl(var(--bc)/.3); }
.dot.ok{ background:#22c55e; }

.pname{ display:flex; align-items:center; gap:.5rem; min-width:0; }
/* 🪤 `display:block` no es decorativo: el nombre suele ser un <a>, y en un elemento
   INLINE `max-width` y `text-overflow` no hacen absolutamente nada — por eso un nombre
   largo empujaba la tabla fuera de la pantalla. Con block sí recorta. */
.pname .nm, .ops-tbl .nm{ display:block; max-width:22rem; overflow:hidden;
    text-overflow:ellipsis; white-space:nowrap; font-weight:600; }
.pname .sku{ font-family:var(--mono); font-size:.9rem; color:var(--mut); }
.excl{ opacity:0; border:0; background:none; color:var(--mut); cursor:pointer; font-size:1rem; line-height:1; padding:.1rem; }
.ops-tbl tr:hover .excl{ opacity:.5; } .excl:hover{ opacity:1 !important; color:var(--act); }

/* ABC por PESO (grayscale), no por color: la importancia se lee sin sumar otra paleta. */
.abc{ font-family:var(--mono); font-weight:800; font-size:.88rem; }
.abc.A{ color:hsl(var(--bc)); } .abc.B{ color:hsl(var(--bc)/.7); } .abc.C{ color:hsl(var(--bc)/.4); }
.pat{ font-family:var(--mono); font-size:.72rem; color:var(--mut); border:1px solid var(--line); border-radius:4px; padding:0 .3rem; margin-left:.25rem; }

.sub{ font-size:.95rem; color:var(--mut); }
.warnmark{ color:var(--act); font-family:var(--mono); }
.repo{ font-family:var(--mono); font-weight:800; color:var(--act); }
.muted{ color:hsl(var(--bc)/.3); }
.ops-foot{ font-size:.85rem; color:var(--mut); margin-top:.7rem; line-height:1.6; }
.ops-foot b{ color:hsl(var(--bc)/.75); }

/* ── Responsive ──────────────────────────────────────────────────────────────
 * ops.css es para pantallas de OPERACIÓN de escritorio (análisis, facturas…), donde
 * una tabla densa es lo mejor. En pantallas chicas degrada con gracia (scroll lateral,
 * KPIs y filtros que se apilan) para el uso ocasional desde tablet/celular.
 *
 * ⚠️ Los portales de CLIENTE y VENDEDOR se usan sobre todo en el celular: NO deben usar
 * esta tabla densa. Van con diseño mobile-first propio (tarjetas, targets grandes, nav
 * inferior) — la reforma tipo app ya prevista. ops.css NO se aplica ahí. */
@media (max-width: 820px) {
  .ops-tblwrap{ max-height:none; }
  .ops-tbl{ font-size:1rem; min-width:720px; }        /* scroll lateral antes que romper */
  .ops-kpi{ min-width:calc(50% - 1px); }                /* KPIs 2 por fila */
  .ops-bar{ position:static; }                          /* en móvil no fijar (poca altura) */
  .ops-sub .grp{ width:100%; margin-top:.3rem; }        /* CSV baja a su propia línea */
}
@media (max-width: 480px) {
  .ops-kpi{ min-width:100%; border-right:0; border-bottom:1px solid var(--line2); }
  .pname .nm{ max-width:52vw; }
}

/* ── Casillas confiables (bug recurrente — ver docs/diseno/DESIGN-crm.md) ──────
   DaisyUI dibuja el tilde de `.checkbox` con gradientes que dependen de variables
   del tema (--chkbg/--chkfg). Cuando el tema las pisa, el tilde queda INVISIBLE:
   la casilla SÍ está marcada, pero no se ve → parece que "no se marca". Además el
   modal cuelga del <body>, fuera del scope donde viven esas variables.
   Solución: restaurar el checkbox NATIVO, que siempre muestra su estado, con el
   ámbar de la marca como acento. Gana por especificidad y por orden de carga
   (ops.css va después del CDN de DaisyUI). */
input[type="checkbox"].checkbox,
input[type="checkbox"].chk {
  appearance: auto; -webkit-appearance: auto;
  width: 1.05rem; height: 1.05rem; min-height: 1.05rem;
  accent-color: #f59e0b;
  border: 0; box-shadow: none; background: none;
  border-radius: 3px; cursor: pointer; opacity: 1;
}
input[type="checkbox"].checkbox-sm { width: .95rem; height: .95rem; min-height: .95rem; }

/* Mismo bug, mismo fix, para `.radio` (usa las mismas variables de tema --chkbg/--chkfg
   para el punto interior). Visto en pedido.php: el modal de Revisión cuelga del <body>, el
   punto quedaba invisible aunque el radio sí cambiaba de estado. */
input[type="radio"].radio {
  appearance: auto; -webkit-appearance: auto;
  width: 1.05rem; height: 1.05rem; min-height: 1.05rem;
  accent-color: #f59e0b;
  border: 0; box-shadow: none; background: none;
  cursor: pointer; opacity: 1;
}
input[type="radio"].radio-sm { width: .95rem; height: .95rem; min-height: .95rem; }

/* Banner de entorno sandbox. No se puede cerrar a propósito: un banner que se descarta
   deja de cumplir su función a los dos minutos, que es cuando alguien se confunde de entorno. */
.sandbox-banner {
    position: sticky; top: 0; z-index: 100;
    background: #b45309; color: #fff;
    padding: .4rem .9rem;
    font-size: .82rem; font-weight: 600; letter-spacing: .02em;
    text-align: center;
    display: flex; align-items: center; justify-content: center; gap: .8rem;
}
.sandbox-banner a { color: #fff; text-decoration: underline; font-weight: 500; }
body.has-sidebar .sandbox-banner { position: static; }
/* El fondo del diálogo VIVE EN theme.css, como `dialog { … }` — no acá.
   Acá estuvo primero como `.modal{background:#060a13}`, un hex fijo que pintaba de negro los
   modales también en el tema claro (lo detectó el PR #61 → #67). Se cambió por el token, y
   después se movió a la base: con `.modal` quedaban afuera los tres diálogos que no llevan esa
   clase, que eran justamente los que salían negros. Ver el comentario de theme.css. */
