/* ═══════════════════════════════════════════════════════════════════════
   OLIVIA — componentes de la plataforma

   ⚠️ LOS TOKENS NO ESTÁN ACÁ. Están en `tokens.css`, que viene de Claude
   Design y es la fuente. Este archivo SOLO compone: no define un color, no
   inventa un radio y no elige una tipografía. Si algo hace falta y no está
   en un token, se pide en Design — no se agrega acá.

   QUÉ CAMBIÓ AL TRAER LOS TOKENS DE VERDAD (11 ago 2026), porque la primera
   versión de esta hoja los había supuesto y erraba en cinco cosas:

     1. El fondo es BLANCO ABSOLUTO (--n-0), no un gris verdoso.
     2. El producto es CURVO, pero no ovalado — corregido por wdeza el 12 ago
        2026: «no exageres con que la plataforma es curva, usemos rectángulos
        con esquinas redondeadas». Design decía cápsula completa (999 px) en
        chips, botones y campos; hoy --r-1 vale 10 px. Ver tokens.css.
     3. LA SOMBRA ESTÁ PROHIBIDA en tarjetas. Solo la barra fija la lleva.
     4. El turquesa de marca es #00786F, no #0E9B94.
     5. El texto normativo literal va en SERIF (--ff-legal). Es el único
        lugar donde entra, y es el que distingue la prueba del comentario.

   Y la regla madre, que la primera versión sí respetaba y hay que sostener:
     · EL MATIZ pertenece al ESTADO del plazo — círculo, círculo medio,
       triángulo, rombo.
     · LA DENSIDAD DE GRIS pertenece al NIVEL DE VERIFICACIÓN — cuadrado
       lleno, medio, punteado. Sin matiz. NADA GRIS DISPARA UNA ALERTA.
     · EL COLOR DE MARCA NO ES SEMÁNTICO: jamás en un chip de estado.
   ═══════════════════════════════════════════════════════════════════════ */

/* La version va tambien en el import: sin ella el navegador se queda con
   los tokens viejos aunque olivia.css cambie, y un valor corregido acá
   —el radio, por ejemplo— no se ve nunca. */
@import url("tokens.css?v=13");

/* Las familias son Source Sans 3 y Source Serif 4. No se incrustan todavía:
   el archivo standalone de Design las referencia por un id interno del
   empaquetador, no como datos. Hasta traer los .woff2, la pila cae a la
   tipografía del sistema — que es lo que ya declara `--ff-ui`. Está anotado
   en /huecos: una fuente que falla en silencio cambia el ritmo de toda la
   pantalla y nadie sabe por qué. */

body { font-size: var(--fs-4); line-height: var(--lh-ui); }
button { background:none; border:none; cursor:pointer; text-align:left; }
a.link { text-decoration: underline; text-underline-offset: 2px; }

/* ══════════════════════════════════════════════════════════════════════════
   LA BARRA — UNA SOLA FILA

   🔴 La anterior tenía DOS pisos. El de abajo llevaba «Sus módulos /
   Configuración / Equipo» y el rótulo del entorno: 48 px fijos, en todas las
   pantallas, para dos destinos que se tocan el día del registro y casi nunca
   más —y uno de los tres, «Equipo», era una pestaña de Configuración con otro
   nombre—. Dos barras de menú arriba es lo primero que se nota mal.

   🔑 Una fila, y adentro dos bloques que no compiten porque no dicen lo
   mismo: a la IZQUIERDA quién es —la marca y la sociedad activa—, a la
   DERECHA qué puedo hacer —el módulo, el tema, el engranaje, yo—. En el medio
   no va nada: el hueco es lo que hace legible el reparto.

   Se conserva el papel teñido de marca y la línea de 3 px con el degradado
   del símbolo: es la única vez que ese degradado sale a la interfaz, y marca
   el borde del producto.

   La barra es `sticky` y nunca se va: dentro de un módulo, saber en cuál se
   está no puede depender de haber scrolleado hasta arriba.
   ══════════════════════════════════════════════════════════════════════════ */
/* 🔑 La altura es un token porque hay contenido que se pega DEBAJO de ella
   —el menú de configuración— y calcular ese `top` a mano fue lo que dejó ese
   menú metido detrás de la barra vieja. Se cambia acá y se corrige solo. */
:root{ --hz-h: 60px; }
@media (max-width: 640px){ :root{ --hz-h: 54px; } }

.hz{position:sticky;top:0;z-index:200;background:var(--shell-grad);
  border-bottom:1px solid var(--shell-line-hi);box-shadow:var(--sh-1);
  color:var(--tx-2);font-size:var(--fs-2)}
.hz-firma{position:absolute;left:0;right:0;top:0;height:3px;background:var(--grad-marca)}
.hz-fila{display:flex;align-items:center;gap:0;min-height:var(--hz-h);
  padding:0 clamp(14px,2.2vw,26px)}

/* ── la marca, que es el botón de casa ──────────────────────────────────
   🔑 Es un enlace, no un adorno, y tiene que verse: se levanta al pasar el
   puntero. Sin esa señal, un logo que navega es un secreto. */
.hz .marca{display:flex;align-items:center;flex:none;border-radius:8px;
  padding:4px 2px;transition:opacity .16s ease,transform .16s ease}
.hz .marca svg{height:27px;width:auto;display:block}
.hz .marca:hover{opacity:.72;transform:translateY(-1px)}
.hz .marca:active{transform:none}

/* ── la sociedad activa ─────────────────────────────────────────────────
   Estructura «Olivia │ Empresa». El nombre es CONTEXTO, no un control: por
   eso no tiene chrome de botón ni caret mientras haya una sola sociedad. */
.hz .emp{display:flex;align-items:baseline;gap:8px;min-width:0;flex:0 1 auto}
.hz .emp .sola{font-size:14px;font-weight:620;letter-spacing:-.01em;
  color:var(--tx-1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  min-width:0;max-width:42ch}
.hz .emp .rotulo{font-size:var(--fs-2);color:var(--tx-3);white-space:nowrap;flex:none}

/* 🔑 EL SELECTOR DE SOCIEDAD. Con una sola empresa el rótulo de arriba se
   queda como está —sin caret, sin menú—; con dos o más, `base.html` lo cambia
   por un `<button class="disparo">` dentro de `.emp.conmutable`. Es el mismo
   chrome que el conmutador de módulo de la derecha, y a propósito: son la
   misma clase de gesto —cambiar de contexto— y tienen que verse iguales. */
.hz .emp.conmutable{position:relative;align-items:center}
.hz .emp.conmutable .disparo{display:flex;align-items:center;gap:8px;height:36px;
  padding:0 10px;border-radius:10px;cursor:pointer;color:var(--tx-1);
  transition:background-color .16s ease}
.hz .emp.conmutable .disparo:hover{background:var(--n-0)}
.hz .emp.conmutable .caret{width:14px;height:14px;color:var(--tx-3);flex:none}
.hz .emp.conmutable .menu{position:absolute;left:0;top:calc(100% + 6px);
  min-width:280px;background:var(--bg);border:1px solid var(--line);
  border-radius:var(--r-3);box-shadow:var(--sh-1);padding:var(--sp-3);z-index:60}
.hz .emp.conmutable .menu[hidden]{display:none}

/* 🔴 Los renglones son `<button>` y no `<a>`: conmutar de sociedad cambia la
   sesión, así que es un `POST` dentro de un `<form class="menu">`. El botón no
   hereda la tipografía del documento —eso lo pone el navegador, no la hoja—,
   así que cada propiedad de texto va escrita. */
.hz .emp.conmutable .menu .cabm{font-size:var(--fs-1);font-weight:700;
  letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--tx-3);
  padding:var(--sp-3) var(--sp-4) var(--sp-4)}
.hz .emp.conmutable .menu .soc{display:flex;align-items:flex-start;gap:var(--sp-4);
  width:100%;padding:var(--sp-4);border-radius:var(--r-1);color:var(--tx-1);
  font-family:var(--ff-ui)}
.hz .emp.conmutable .menu .soc:hover{background:var(--brand-soft);color:var(--brand)}
.hz .emp.conmutable .menu .soc .quien{display:flex;flex-direction:column;gap:1px;
  line-height:1.3;min-width:0}
.hz .emp.conmutable .menu .soc b{font-size:var(--fs-3);font-weight:650}
.hz .emp.conmutable .menu .soc i{font-style:normal;font-size:var(--fs-1);
  color:var(--tx-3)}
/* La marca de la activa ocupa su hueco SIEMPRE, esté o no: si apareciera solo
   en una fila, las otras se correrían y el menú entero bailaría al conmutar. */
.hz .emp.conmutable .menu .soc .marca-aqui{width:14px;height:14px;flex:none;
  margin-top:2px;color:var(--brand)}
.hz .emp.conmutable .menu .soc .marca-aqui svg{width:100%;height:100%;display:block}
.hz .emp.conmutable .menu .soc.aqui{background:var(--brand-soft)}
.hz .emp.conmutable .menu .soc.aqui b{color:var(--brand)}
/* Los papeles se ven pero no bloquean: un papel OBSERVADO es lo único que hay
   que ir a arreglar y lleva el único cálido del sistema; lo que falta o está
   en revisión es gris, porque no es una alerta y nada gris dispara alertas. */
.hz .emp.conmutable .menu .soc .papeles.observada{color:var(--st-porvencer)}
.hz .emp.conmutable .menu .soc .papeles.pendiente,
.hz .emp.conmutable .menu .soc .papeles.sin_papeles{color:var(--tx-3)}
/* 🔴 Medido: a 375 px el menú arranca a 110 px del borde —logo y corte— y
   mide 280, o sea que se salía de la pantalla. En el teléfono se cuelga del
   viewport y no de la sociedad, y la razón social parte renglón en vez de
   cortarse: acá el nombre completo es el dato, no un adorno. */
@media (max-width: 640px){
  .hz .emp.conmutable .menu{position:fixed;left:8px;right:8px;
    top:calc(var(--hz-h) + 6px);min-width:0}
  .hz .emp.conmutable .menu .soc b{white-space:normal;overflow-wrap:anywhere}
}

/* ── la derecha ─────────────────────────────────────────────────────────
   El orden lo fijó wdeza: Selector de módulo │ Configuración │ Usuario. El
   tema entra como otro ícono junto al engranaje —es del mismo peso— y no
   antes del módulo, que es lo único de acá que cambia de contexto. */
.hz .r{margin-left:auto;display:flex;align-items:center;gap:6px;flex:none;
  padding-left:14px}

/* Los controles van en blanco pleno: sobre papel teñido, un control del mismo
   color del papel no se lee como control. */
.hz .ctl,.hz .conmuta .disparo{border:1px solid var(--shell-line);
  border-radius:11px;background:var(--n-0);color:var(--tx-2);
  transition:border-color .16s ease,color .16s ease,box-shadow .16s ease}
.hz .ctl:hover,.hz .conmuta .disparo:hover{border-color:var(--brand);color:var(--brand);
  box-shadow:0 4px 14px -8px color-mix(in srgb,var(--brand) 50%,transparent)}
.hz .ctl{width:36px;height:36px;display:grid;place-items:center;font-size:15px;
  line-height:1;flex:none}
.hz .ctl svg{width:17px;height:17px;display:block}
.hz .ctl:hover{text-decoration:none}
/* El engranaje encendido cuando se está DENTRO de configuración: sin el piso
   de destinos, es lo único que dice dónde estoy. */
.hz .ctl.on{border-color:var(--brand);color:var(--brand);background:var(--brand-soft)}

/* ── el conmutador de módulo ── */
.hz .conmuta{position:relative;flex:none}
.hz .conmuta .disparo{display:flex;align-items:center;gap:10px;height:36px;
  padding:0 11px 0 9px;cursor:pointer}
.hz .conmuta .mini{width:26px;height:20px;display:block;flex:none}
.hz .conmuta .mini svg{width:100%;height:100%;display:block}
/* Sin módulo actual va la rejilla, no la figura de un módulo cualquiera. */
.hz .conmuta .mini.rejilla{width:19px;height:19px;color:var(--tx-3)}
.hz .conmuta .txt{display:flex;flex-direction:column;line-height:1.15}
.hz .conmuta .txt i{font-style:normal;font-size:9.5px;font-weight:700;
  letter-spacing:.11em;text-transform:uppercase;color:var(--tx-3)}
.hz .conmuta .txt b{font-size:13px;font-weight:650;letter-spacing:-.008em;color:var(--tx-1)}
.hz .conmuta .caret{width:14px;height:14px;color:var(--tx-3);flex:none}
/* 🔴 El menú cuelga por la DERECHA. Con `left:0` —que es donde estaba cuando
   el conmutador vivía a la izquierda— se salía de la pantalla. */
.hz .conmuta .menu{position:absolute;right:0;top:calc(100% + 6px);min-width:272px;
  background:var(--bg);border:1px solid var(--line);border-radius:var(--r-3);
  box-shadow:var(--sh-1);padding:var(--sp-3);z-index:60}
.hz .conmuta .menu[hidden]{display:none}
.hz .conmuta .menu a,.hz .conmuta .menu .apagado{display:flex;align-items:center;
  gap:var(--sp-4);padding:var(--sp-3);border-radius:var(--r-1);color:var(--tx-1)}
.hz .conmuta .menu a:hover{background:var(--brand-soft);color:var(--brand);text-decoration:none}
.hz .conmuta .menu .apagado{opacity:.55}
.hz .conmuta .menu .quien{display:flex;flex-direction:column;line-height:1.25;min-width:0}
.hz .conmuta .menu .quien b{font-size:var(--fs-2);font-weight:650}
.hz .conmuta .menu .quien i{font-style:normal;font-size:var(--fs-1);color:var(--tx-3)}
.hz .conmuta .menu .sep{height:1px;background:var(--line);margin:var(--sp-3) 0}

/* ── la bandeja de LQG ──────────────────────────────────────────────────
   🔴 No se toca sin mirar /admin: es la única puerta del equipo de LQG a su
   propia pantalla, y esta barra es la misma que la de los clientes. */
.hz .r .bandeja{display:flex;align-items:center;gap:9px;height:36px;padding:0 12px;
  border-radius:10px;font-size:13px;font-weight:600;color:var(--tx-2)}
.hz .r .bandeja:hover{background:var(--n-0);color:var(--brand);text-decoration:none}
.hz .r .bandeja.on{background:var(--n-0);color:var(--tx-1)}
.hz .r .bandeja .n{display:inline-grid;place-items:center;min-width:19px;height:19px;
  padding:0 5px;border-radius:999px;background:var(--st-vencida);color:#fff;
  font-size:11px;font-weight:700;line-height:1}
.hz .corte{width:1px;height:26px;background:var(--shell-line);margin:0 12px;flex:none}

/* ── el teléfono ──────────────────────────────────────────────────────────
   🔑 Lo que se cae primero es lo que se puede recuperar de otra manera: el
   rótulo «Módulo» encima del nombre, el pie del rol, el nombre del usuario
   —que ya está en el avatar—. Lo que NUNCA se cae es en qué empresa estoy,
   en qué módulo estoy, y cómo llego a casa y a mi cuenta. */
@media (max-width: 900px){
  .hz .conmuta .txt i{display:none}
  .hz .emp .sola{max-width:26ch}
}
@media (max-width: 640px){
  .hz-fila{padding:0 12px}
  .hz .marca svg{height:22px}
  .hz .corte{margin:0 8px}
  .hz .emp .rotulo{display:none}
  .hz .emp .sola{font-size:12.5px;max-width:34vw}
  .hz .r{gap:3px;padding-left:8px}
  .hz .conmuta .txt{display:none}
  .hz .conmuta .disparo{padding:0 8px;gap:6px}
  .hz .r .usuario .quien{display:none}
  .hz .r .usuario .disparo{padding:0 6px;gap:6px}
  .hz .r .bandeja{padding:0 8px;font-size:0;gap:0}
  .hz .r .bandeja .n{font-size:11px}
}
/* 🔴 A 420 px la fila entera mide 438 px y algo tiene que ceder. NO cede el
   conmutador: sin el piso de destinos, es la navegación del producto, y un
   teléfono es donde más falta hace saber en qué módulo se está. Ceden los
   milímetros —el logo, el ancho de la razón social, el lado de los íconos—,
   que es lo que nadie mira. Medido a 375 px: 366 px de fila. */
@media (max-width: 420px){
  .hz-fila{padding:0 10px}
  .hz .marca svg{height:20px}
  .hz .corte{margin:0 6px}
  .hz .emp .sola{max-width:24vw}
  .hz .r{gap:2px;padding-left:6px}
  .hz .ctl{width:32px;height:32px}
  .hz .ctl svg{width:16px;height:16px}
  .hz .conmuta .disparo{height:32px;padding:0 6px}
}

/* ═══ SHELL ═══ */
.app{display:flex;align-items:stretch;min-height:100dvh}
.rail{width:60px;flex:none;background:var(--surface);border-right:1px solid var(--line);
  display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);overflow:visible;
  position:sticky;top:46px;height:calc(100dvh - 46px);padding:var(--sp-6) 0 var(--sp-6)}
/* .rail .simbolo salio con el logo redundante del rail (12 ago 2026). */
.rail a{width:42px;height:42px;border-radius:var(--r-1);display:grid;place-items:center;
  color:var(--n-4);position:relative;flex:none}
.rail a:hover{background:var(--sunken);color:var(--tx-1)}
.rail a.on{background:var(--brand-soft);color:var(--brand)}
.rail a svg{width:18px;height:18px}
.rail a .n{position:absolute;top:2px;right:2px;min-width:16px;height:16px;
  border-radius:var(--r-1);background:var(--st-vencida);color:#fff;font-size:9px;
  font-weight:700;display:grid;place-items:center;padding:0 3px}
/* el tooltip ES la etiqueta en un menú de solo íconos: nada de overflow acá */
.rail a:after{content:attr(data-t);position:absolute;left:calc(100% + 8px);top:50%;
  transform:translateY(-50%);background:var(--tx-1);color:var(--bg);
  padding:var(--sp-2) var(--sp-5);border-radius:var(--r-1);font-size:var(--fs-2);
  white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .12s;z-index:150}
.rail a:hover:after{opacity:1}
.rail .sep{width:24px;height:1px;background:var(--line);margin:var(--sp-4) 0}
/* .rail .me salio: la identidad vive en el menu de usuario de la barra. */

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.canvas{flex:1;padding:var(--pad-page) var(--pad-page) var(--sp-10)}
.wrap{max-width:780px;margin:0 auto;width:100%}
.wrap.ancho{max-width:1120px}
/* Novedades, a todo el ancho por el mismo motivo que las del módulo: tiene una
   lista y una ficha, no tres tarjetas.
   ⚠️ Configuración NO está acá: su regla vive al final del archivo, junto al
   resto de `.cfg`. Tenerla en dos sitios fue el error de ayer — la de abajo
   pisaba a ésta y el arreglo no se aplicaba nunca. */
.wrap.ancho:has(.li-tabs){max-width:none}

/* Y la misma distancia al menú superior que el resto del producto. wdeza:
   «mantén este criterio para todas las páginas». */
/* 🔴 EL RELLENO DE PÁGINA TAMBIÉN, no sólo el tope de ancho. Quitar
   `max-width` no alcanzaba: `.canvas` mantenía `--pad-page` a los lados y, en
   una ventana de 1920, Configuración medía 1.560 px contra 1.856 de la matriz.
   ⚠️ Y lo medí a 1500 px, donde las dos caen en el mismo número — y di el
   arreglo por hecho. Un ancho que sólo se prueba en un tamaño es un ancho que
   no se probó: wdeza lo vio en su pantalla, que es más grande que la mía. */
.canvas:has(.cfg),
.canvas:has(.li-tabs){padding:var(--sp-6) clamp(14px,2.2vw,26px) var(--sp-10)}

/* ── VOLVER: ninguna pantalla es un punto muerto ── */
.atras{display:inline-flex;align-items:center;gap:var(--sp-3);font-size:var(--fs-2);
  color:var(--tx-3);margin-bottom:var(--sp-6);min-height:34px;
  padding:0 var(--sp-5) 0 var(--sp-3);border-radius:var(--r-1)}
.atras:hover{color:var(--brand);background:var(--sunken);text-decoration:none}
.atras svg{width:15px;height:15px;flex:none}

.hd{display:flex;align-items:flex-start;gap:var(--sp-5);margin-bottom:var(--sp-9);
  flex-wrap:wrap}
.hd h1{font-size:var(--fs-8);font-weight:600;letter-spacing:var(--ls-tight);
  line-height:var(--lh-tight);margin:0;text-wrap:balance}
.hd .sub{font-size:var(--fs-4);color:var(--tx-2);margin-top:var(--sp-3);
  line-height:var(--lh-read)}
.hd .cli{margin-left:auto;font-size:var(--fs-3);color:var(--tx-2);display:flex;
  align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-6);
  border:1px solid var(--line);border-radius:var(--r-1);white-space:nowrap}

/* ══ TABLERO ══ */
.hero{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-4);
  padding:var(--sp-9);display:flex;align-items:center;gap:var(--sp-10);
  flex-wrap:wrap;justify-content:center;margin-bottom:var(--sp-9)}
.viz{position:relative;width:clamp(140px,17vw,168px);aspect-ratio:1;flex:none}
.viz svg{width:100%;height:100%;transform:rotate(-90deg)}
.viz .mid{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center}
.viz .mid .v{font-size:var(--fs-9);font-weight:600;letter-spacing:var(--ls-tight);
  line-height:1}
.viz .mid .l{font-size:var(--fs-2);color:var(--tx-3);margin-top:var(--sp-3);
  text-align:center;padding:0 var(--sp-5)}
.stats{flex:1 1 260px;min-width:0;display:flex;gap:var(--sp-8);flex-wrap:wrap}
.stat{flex:1 1 88px;min-width:88px}
.stat .k{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-3)}
.stat .k .t{font-size:var(--fs-2);color:var(--tx-2);white-space:nowrap}
.stat .v{font-size:var(--fs-9);font-weight:600;letter-spacing:var(--ls-tight);line-height:1}
.stat .u{font-size:var(--fs-2);color:var(--tx-3);margin-top:var(--sp-2)}
.stat.a .v{color:var(--st-vencida)}
.stat.t .v{color:var(--st-porvencer)}
.stat.x .v{color:var(--st-sinfirmar)}
/* El punto de color de la clave. Se usaba en cinco plantillas desde el
   principio y NO ESTABA DEFINIDO en ningún lado: el <span> ocupaba cero
   píxeles y nadie lo notó porque la etiqueta de al lado ya decía qué era.
   Un estilo que falta no da error, da una pantalla que se ve casi bien. */
.stat .sw{width:9px;height:9px;border-radius:var(--r-2);flex:none;
  background:var(--tx-3)}

/* 🔴 EL FILTRO PUESTO. `a.stat.on` la escribian CINCO plantillas y no estaba
   definida en ninguna hoja: la cifra elegida se veia igual que las otras, o
   sea que el tablero no decia que estaba mirando. Es el modo de falla mas
   caro de CSS — un estilo que falta no da error, da una pantalla que se ve
   casi bien. Vive aca y no en la hoja de un modulo porque `.stat` vive aca:
   con la regla en una hoja de modulo queda muerta en toda pantalla que cargue
   otra, que es lo que le pasaba a la casilla.
   El indigo es de SELECCION («esto es lo que estas mirando ahora»), nunca de
   estado: `tokens.css` y `docs/18 §12`. */
a.stat.on{background:var(--indigo-soft);
  box-shadow:inset 0 0 0 1px var(--indigo)}
a.stat.on:hover{background:var(--indigo-soft)}
a.stat.on .k .t{color:var(--indigo);font-weight:600}
.stat .sw.ind{background:var(--indigo)}
/* Una cifra que lleva a su detalle. Es la regla del tablero —todo número
   conecta— y por eso el estado es del bloque entero, no del texto: el área
   de clic tiene que ser la cifra grande, no un enlace subrayado al lado. */
a.stat{text-decoration:none;color:inherit;border-radius:var(--r-1);
  padding:var(--sp-3);margin:calc(var(--sp-3) * -1);transition:background .12s}
a.stat:hover{background:var(--brand-soft)}
a.stat:hover .v{text-decoration:underline;text-underline-offset:3px}

/* ── pestañas ──
   El token estaba reservado desde el primer día —tokens.css glosa
   `--brand-soft` como «fondo de selección, fila activa, tab activo»— y no
   había ninguna pestaña que lo usara. */
.tabs{display:flex;gap:var(--sp-2);border-bottom:1px solid var(--line);
  margin-bottom:var(--sp-8);flex-wrap:wrap}
.tabs a{padding:var(--sp-5) var(--sp-7);font-size:var(--fs-3);color:var(--tx-2);
  text-decoration:none;border-bottom:2px solid transparent;margin-bottom:-1px;
  border-radius:var(--r-1) var(--r-1) 0 0;white-space:nowrap}
.tabs a:hover{color:var(--tx-1);background:var(--sunken)}
.tabs a.on{color:var(--brand);border-bottom-color:var(--brand);
  background:var(--brand-soft);font-weight:600}

/* ── barra de filtros ──
   El estilo del activo ya vivía en tokens.css (`button[data-on="si"]`) y
   ninguna plantilla lo usaba. Acá se usa. */
.filtros{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;
  margin-bottom:var(--sp-6)}
.filtros .et{font-size:var(--fs-1);letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--tx-3);margin-right:var(--sp-2)}
.filtros a{display:inline-flex;align-items:center;gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-6);border:1px solid var(--line);
  border-radius:var(--r-1);font-size:var(--fs-2);color:var(--tx-2);
  text-decoration:none;background:var(--bg)}
.filtros a:hover{border-color:var(--line-hi);color:var(--tx-1)}
.filtros a.on{background:var(--brand-soft);border-color:var(--brand);
  color:var(--brand-ink);font-weight:600}
.filtros a .n{font-variant-numeric:tabular-nums;color:var(--tx-3)}
.filtros a.on .n{color:var(--brand)}
.filtros .limpiar{margin-left:auto;border-style:dashed}

/* ── el estado de una auditoría, tal como lo ve el cliente ──
   Es la única pantalla del producto donde una frase ES el dato. Por eso
   ocupa una línea entera y no un chip de ocho píxeles. */
.veredicto{display:flex;align-items:center;gap:var(--sp-5);
  padding:var(--sp-5) var(--sp-6);border-radius:var(--r-1);font-size:var(--fs-3);
  line-height:var(--lh-ui)}
.veredicto .ic{font-size:var(--fs-5);line-height:1;flex:none}
.veredicto.ok{background:var(--st-aldia-bg);color:var(--st-aldia)}
.veredicto.hall{background:var(--st-vencida-bg);color:var(--st-vencida)}
.veredicto.esp{background:var(--sunken);color:var(--tx-3)}
.veredicto.rev{background:var(--st-porvencer-bg);color:var(--st-porvencer)}

/* ── secciones y bloques ── */
.hsec{display:flex;align-items:baseline;gap:var(--sp-5);
  margin:var(--sp-10) 0 var(--sp-5);flex-wrap:wrap}
.hsec:first-child{margin-top:0}
.hsec h2{font-size:var(--fs-1);font-weight:700;letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--tx-3);margin:0}
.hsec .q{margin-left:auto;font-size:var(--fs-2);color:var(--tx-3)}
.hi{display:flex;flex-direction:column;gap:var(--sp-5)}
.card{display:flex;align-items:flex-start;gap:var(--sp-6);padding:var(--sp-6) var(--sp-7);
  background:var(--bg);border:1px solid var(--line);border-radius:var(--r-3);
  flex-wrap:wrap}
.card:hover{border-color:var(--line-hi)}
.card .bd{flex:1 1 240px;min-width:0}
.card .r1{display:flex;align-items:center;gap:var(--sp-4);margin-bottom:var(--sp-4);
  flex-wrap:wrap}
.card .tx{font-size:var(--fs-4);line-height:var(--lh-read)}
.card .mt{font-size:var(--fs-2);color:var(--tx-3);margin-top:var(--sp-3)}
.card .ac{display:flex;gap:var(--sp-3);flex:0 0 auto;margin-left:auto;
  align-items:center;flex-wrap:wrap}

/* ── prioridad: usa el matiz del ESTADO, que es de quien es ── */
.pri{font-size:var(--fs-1);font-weight:700;letter-spacing:var(--ls-caps);
  padding:var(--sp-2) var(--sp-4);border-radius:var(--r-1);flex:none;
  text-transform:uppercase}
.p1{background:var(--st-vencida-bg);color:var(--st-vencida)}
.p2{background:var(--st-porvencer-bg);color:var(--st-porvencer)}
.p3{background:var(--st-aldia-bg);color:var(--st-aldia)}
.p4{background:var(--sunken);color:var(--tx-3);border:1px solid var(--line)}

/* ── botones: cápsula completa ── */
.b{font-size:var(--fs-3);padding:0 var(--sp-7);min-height:40px;border-radius:var(--r-1);
  border:1px solid var(--line-hi);color:var(--tx-2);white-space:nowrap;
  display:inline-flex;align-items:center;background:var(--bg)}
.b:hover{border-color:var(--brand);color:var(--brand);text-decoration:none}
.b.p{background:var(--brand);border-color:var(--brand);color:var(--brand-ink);font-weight:600}
.b.p:hover{background:var(--brand-hi);border-color:var(--brand-hi);color:var(--brand-ink)}
.b.chico{min-height:32px;font-size:var(--fs-2);padding:0 var(--sp-5)}
/* El RUC que falta, dentro de la celda de la empresa. Se queda chico y en
   línea a propósito: es la excepción —una ficha incompleta—, no un campo del
   listado, y no debe pesar más que la razón social que tiene al lado. */
.adm-ruc{display:flex;gap:var(--sp-2);align-items:center;margin-top:var(--sp-2)}
.adm-ruc input{min-height:32px;font-size:var(--fs-2);width:11ch;
  padding:0 var(--sp-3);border:1px solid var(--ln-2);border-radius:var(--r-1);
  background:var(--sf-1);color:var(--tx-1)}
.adm-ruc input::placeholder{color:var(--tx-3)}
.adm-ruc input:focus{border-color:var(--brand);outline:none}

/* Las sociedades del grupo dentro del diálogo. Cada una es una fila
   clicable entera y no una casilla con una etiqueta al lado: el blanco de
   14px de un checkbox es un blanco de 14px también para el dedo. */
.socias-lista{display:flex;flex-direction:column;gap:var(--sp-2);
  margin:var(--sp-4) 0}
.socia{display:flex;gap:var(--sp-4);align-items:center;cursor:pointer;
  padding:var(--sp-3) var(--sp-4);border:1px solid var(--ln-2);
  border-radius:var(--r-1);background:var(--sf-1)}
.socia:hover{border-color:var(--brand)}
.socia input{width:16px;height:16px;accent-color:var(--brand);flex:none}
.socia span{display:flex;flex-direction:column;gap:2px;min-width:0}
.socia b{font-weight:600}

/* ── la nota que explica el producto ── */
.rule{font-size:var(--fs-2);color:var(--tx-3);line-height:var(--lh-read);
  background:var(--surface);padding:var(--sp-5) var(--sp-6);border-radius:var(--r-3);
  margin-top:var(--sp-6)}
.rule b{color:var(--tx-2)}

/* ══ EL RÓTULO DE HUECO ══
   Un paso que todavía hace una persona se implementa y se ROTULA. Usa el
   ámbar del estado «por vencer» a propósito: un hueco es algo que hay que
   atender, no un error. */
.hueco{display:flex;align-items:flex-start;gap:var(--sp-5);font-size:var(--fs-3);
  line-height:var(--lh-read);border:1px dashed var(--st-porvencer);
  background:var(--st-porvencer-bg);color:var(--st-porvencer);
  padding:var(--sp-5) var(--sp-6);border-radius:var(--r-3);margin:var(--sp-5) 0}
.hueco .ic{font-size:15px;line-height:1.2;flex:none}

/* ══ LOS DOS ALFABETOS ══
   Las siluetas las define tokens.css en `i[data-mark]`. Acá solo se les da
   color y compañía tipográfica. */
.est{display:inline-flex;align-items:center;gap:var(--sp-3);font-size:var(--fs-2);
  white-space:nowrap;color:var(--st-fg,var(--tx-2))}
.est-vencida{--st-fg:var(--st-vencida);font-weight:600}
.est-porvencer{--st-fg:var(--st-porvencer)}
.est-aldia{--st-fg:var(--st-aldia)}
.est-sinfirmar{--st-fg:var(--st-sinfirmar)}

.ver{display:inline-flex;align-items:center;gap:var(--sp-3);font-size:var(--fs-2);
  white-space:nowrap;color:var(--ver-fg,var(--ver-pendiente))}
.ver-primaria{--ver-fg:var(--ver-primaria)}
.ver-secundaria{--ver-fg:var(--ver-secundaria)}
.ver-a_verificar,.ver-pendiente{--ver-fg:var(--ver-pendiente)}

/* ── tablas ── */
.tabla{width:100%;border-collapse:collapse;font-size:var(--fs-3);
  background:var(--bg);border:1px solid var(--line);border-radius:var(--r-3);
  overflow:hidden}
.tabla th{text-align:left;font-size:var(--fs-1);letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--tx-3);font-weight:700;
  padding:var(--sp-5) var(--sp-6);border-bottom:1px solid var(--line);
  background:var(--surface)}
.tabla td{padding:var(--sp-5) var(--sp-6);border-bottom:1px solid var(--line);
  vertical-align:top}
.tabla tr:last-child td{border-bottom:none}
.tabla tr:hover td{background:var(--surface)}
.tabla .num{text-align:right;white-space:nowrap}
.scrollx{overflow-x:auto;border-radius:var(--r-3)}

/* ══ EL MENÚ DE USUARIO ══
   Reemplaza al enlace «Salir · Rosa», que decía muy poco para lo que se juega:
   quién entró, a qué empresa y con qué rol es lo que hay que poder comprobar de
   un vistazo antes de tocar un expediente. */
.usuario{position:relative}
.hz .r .usuario .disparo{display:flex;align-items:center;gap:var(--sp-4);
  padding:var(--sp-2) var(--sp-4) var(--sp-2) var(--sp-2);border-radius:var(--r-1);
  border:1px solid transparent;color:var(--tx-2)}
.hz .r .usuario .disparo:hover{background:var(--n-0);border-color:var(--shell-line)}
.usuario .av{width:28px;height:28px;border-radius:var(--r-2);background:var(--brand);
  color:var(--brand-ink);display:grid;place-items:center;flex:none;
  font-size:var(--fs-2);font-weight:700;letter-spacing:0}
.usuario .av.grande{width:38px;height:38px;font-size:var(--fs-3)}
.usuario .quien{display:flex;flex-direction:column;align-items:flex-start;
  line-height:1.2;min-width:0;max-width:190px}
/* Cortar por caracteres partía la razón social a mitad de palabra. Que el
   corte lo haga el navegador y se vea el puntito. */
.usuario .quien b,.usuario .quien i{max-width:100%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.usuario .quien b{font-size:var(--fs-2);font-weight:600;color:var(--tx-1)}
.usuario .quien i{font-style:normal;font-size:var(--fs-1);color:var(--tx-3)}
.usuario .caret{width:14px;height:14px;color:var(--tx-3);flex:none}
.usuario .menu{position:absolute;right:0;top:calc(100% + 6px);min-width:268px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-3);
  box-shadow:var(--sh-1);padding:var(--sp-3);z-index:300;display:flex;
  flex-direction:column;gap:var(--sp-1)}
.usuario .menu[hidden]{display:none}
.usuario .menu .cab{display:flex;gap:var(--sp-5);align-items:center;
  padding:var(--sp-5);border-radius:var(--r-1);background:var(--sunken);
  margin-bottom:var(--sp-2)}
.usuario .menu .datos{display:flex;flex-direction:column;gap:1px;min-width:0}
.usuario .menu .datos b{font-size:var(--fs-3);color:var(--tx-1)}
.usuario .menu .datos span{font-size:var(--fs-2);color:var(--tx-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.usuario .menu .datos .rol{text-transform:uppercase;letter-spacing:var(--ls-caps);
  font-size:var(--fs-1);color:var(--tx-3)}
.hz .r .usuario .menu a{display:flex;align-items:center;gap:var(--sp-5);
  padding:var(--sp-4) var(--sp-5);border-radius:var(--r-1);font-size:var(--fs-3);
  color:var(--tx-2)}
.hz .r .usuario .menu a svg{width:16px;height:16px;flex:none;color:var(--tx-3)}
.hz .r .usuario .menu a.salir{color:var(--st-vencida)}
.hz .r .usuario .menu a.salir svg{color:var(--st-vencida)}
.usuario .menu .sep{height:1px;background:var(--line);margin:var(--sp-2) var(--sp-3)}

/* ══ DESPLEGABLE PROPIO ══
   El `<select>` nativo abre su lista en una ventana del sistema operativo que
   se dibuja FUERA de la tarjeta y con los colores del SO: en el registro se
   veía un cuadro blanco azulado desbordando el formulario. Esto es la misma
   semántica —un `<select>` de verdad sigue abajo, oculto, y es el que se
   envía— con la lista dibujada dentro de la página. */
.desplegable{position:relative}
.desplegable>select{position:absolute;opacity:0;pointer-events:none;height:0;
  width:0;border:0;padding:0;margin:0}
.desplegable .actual{display:flex;align-items:center;justify-content:space-between;
  gap:var(--sp-4);width:100%;font-size:var(--fs-4);color:var(--tx-1);
  background:var(--bg);border:1px solid var(--line-hi);border-radius:var(--r-1);
  padding:var(--sp-5) var(--sp-6);min-height:42px;text-align:left}
.desplegable .actual:hover{border-color:var(--tx-3)}
.desplegable.abierto .actual{border-color:var(--brand)}
.desplegable .actual svg{width:16px;height:16px;color:var(--tx-3);flex:none;
  transition:transform .12s}
.desplegable.abierto .actual svg{transform:rotate(180deg)}
.desplegable .lista{position:absolute;left:0;right:0;top:calc(100% + 4px);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-3);
  box-shadow:var(--sh-1);padding:var(--sp-3);z-index:120;max-height:260px;
  overflow-y:auto;display:flex;flex-direction:column;gap:1px}
.desplegable .lista[hidden]{display:none}
.desplegable .lista button{text-align:left;width:100%;font-size:var(--fs-3);
  color:var(--tx-2);padding:var(--sp-4) var(--sp-5);border-radius:var(--r-1)}
.desplegable .lista button:hover{background:var(--sunken);color:var(--tx-1)}
.desplegable .lista button[aria-selected="true"]{background:var(--brand-soft);
  color:var(--brand);font-weight:600}
.desplegable .lista .grupo{font-size:var(--fs-1);text-transform:uppercase;
  letter-spacing:var(--ls-caps);color:var(--tx-3);padding:var(--sp-4) var(--sp-5) var(--sp-2)}

/* ══ CONTRASEÑA CON OJO ══ */
.clave{position:relative;display:flex}
.clave input{padding-right:44px}
.clave .ojo{position:absolute;right:6px;top:50%;transform:translateY(-50%);
  width:32px;height:32px;display:grid;place-items:center;border-radius:var(--r-1);
  color:var(--tx-3)}
.clave .ojo:hover{background:var(--sunken);color:var(--tx-1)}
.clave .ojo svg{width:18px;height:18px}

/* ── formularios: cápsula, como los botones ── */
.form{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-3);
  padding:var(--sp-7);display:flex;flex-direction:column;gap:var(--sp-6)}
.campo{display:flex;flex-direction:column;gap:var(--sp-3)}
.campo label{font-size:var(--fs-2);font-weight:600;color:var(--tx-2)}
.campo .ayuda{font-size:var(--fs-2);color:var(--tx-3);line-height:var(--lh-read)}
.campo input,.campo select,.campo textarea{font:inherit;font-size:var(--fs-4);
  color:var(--tx-1);background:var(--bg);border:1px solid var(--line-hi);
  border-radius:var(--r-1);padding:var(--sp-5) var(--sp-6);min-height:42px;width:100%}
.campo textarea{border-radius:var(--r-3);min-height:100px;resize:vertical;
  line-height:var(--lh-read)}
.campo input:focus,.campo select:focus,.campo textarea:focus{outline:none;
  border-color:var(--brand)}
.fila{display:flex;gap:var(--sp-5);flex-wrap:wrap}
.fila>*{flex:1 1 190px;min-width:0}

/* ══ LA CITA LITERAL — el único lugar con SERIF ══
   Es lo que distingue la prueba del comentario: el texto de la norma se lee
   como documento, no como interfaz. */
.cita{font-family:var(--ff-legal);font-size:var(--fs-6);line-height:var(--lh-legal);
  background:var(--sunken);border:1px solid var(--line);border-left:3px solid var(--line-hi);
  padding:var(--sp-6) var(--sp-7);border-radius:var(--r-3);margin:var(--sp-5) 0}
.cita .proc{font-family:var(--ff-ui);font-size:var(--fs-2);color:var(--tx-3);
  margin-bottom:var(--sp-4);letter-spacing:var(--ls-caps);text-transform:uppercase}
.cita .txt{white-space:pre-wrap;color:var(--tx-1)}

/* ── chips ── */
.chip{font-size:var(--fs-2);font-weight:600;padding:var(--sp-1) var(--sp-5);
  border-radius:var(--r-1);white-space:nowrap;display:inline-block}
.c-ext{background:var(--st-sinfirmar-bg);color:var(--st-sinfirmar)}
.c-alert{background:var(--st-vencida-bg);color:var(--st-vencida)}
.c-ok{background:var(--st-aldia-bg);color:var(--st-aldia)}
.c-tan{background:var(--st-porvencer-bg);color:var(--st-porvencer)}
.c-q{background:var(--sunken);color:var(--tx-3);border:1px solid var(--line)}

.srow{display:flex;align-items:center;gap:var(--sp-5);padding:var(--sp-5) 0;
  border-bottom:1px solid var(--line);flex-wrap:wrap;min-height:48px}
.srow:last-child{border-bottom:none}
.srow .bd{flex:1 1 180px;min-width:0}
.srow .n{font-size:var(--fs-4);font-weight:600}
.srow .s{font-size:var(--fs-2);color:var(--tx-3);margin-top:var(--sp-1)}
.srow .rt{text-align:right;flex:none;margin-left:auto}
.srow .rt .v{font-size:var(--fs-4);font-weight:600}
.srow .rt .u{font-size:var(--fs-2);color:var(--tx-3)}
.av{width:24px;height:24px;border-radius:var(--r-2);background:var(--sunken);
  color:var(--tx-2);display:grid;place-items:center;font-size:var(--fs-1);
  font-weight:700;flex:none}
.av.x{background:var(--st-sinfirmar-bg);color:var(--st-sinfirmar)}

.vacio{text-align:center;color:var(--tx-3);font-size:var(--fs-4);padding:var(--sp-10);
  border:1px dashed var(--line-hi);border-radius:var(--r-3);line-height:var(--lh-read)}
.mono{font-variant-numeric:tabular-nums;word-break:break-all}
.traza{font-size:var(--fs-2);color:var(--tx-2);background:var(--sunken);
  padding:var(--sp-5) var(--sp-6);border-radius:var(--r-3);line-height:var(--lh-read);
  overflow-x:auto;white-space:pre-wrap}
details.prov{margin-top:var(--sp-6);border-top:1px solid var(--line);padding-top:var(--sp-5)}
details.prov summary{font-size:var(--fs-2);color:var(--tx-3);cursor:pointer;
  min-height:32px;display:flex;align-items:center}
details.prov summary:hover{color:var(--brand)}

/* ══ CENTRO DE COMANDOS ══ */
.cmdzone{position:sticky;bottom:0;z-index:60;margin-top:var(--sp-11);
  padding:var(--sp-6) var(--pad-page) var(--sp-7);background:var(--bg)}
.cmdzone:before{content:'';position:absolute;left:0;right:0;bottom:100%;height:36px;
  background:linear-gradient(to bottom,transparent,var(--bg));pointer-events:none}
.cmdzone .box{max-width:780px;margin:0 auto}
.cmdlbl{font-size:var(--fs-1);font-weight:700;letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--tx-3);margin-bottom:var(--sp-4)}
.cmd{border:1px solid var(--line-hi);border-radius:var(--r-1);background:var(--bg);
  padding:0 var(--sp-3) 0 var(--sp-6);min-height:52px;display:flex;align-items:center;
  gap:var(--sp-5)}
.cmd:focus-within{border-color:var(--brand)}
.cmd .mk{width:24px;height:24px;flex:none;display:grid;place-items:center}
.cmd .mk svg{width:22px;height:22px}
.cmd input.ph{flex:1;min-width:0;border:none;background:none;font:inherit;
  font-size:var(--fs-5);color:var(--tx-1);padding:var(--sp-5) 0;outline:none}
.cmd input.ph::placeholder{color:var(--tx-3)}
.cmd .go{width:38px;height:38px;border-radius:var(--r-2);background:var(--brand);
  display:grid;place-items:center;flex:none;border:none}
.cmd .go:hover{background:var(--brand-hi)}
.cmd .go svg{width:16px;height:16px}
.cmdhint{display:flex;gap:var(--sp-3);margin-top:var(--sp-4);flex-wrap:wrap;
  align-items:center}
.cmdhint button{font-size:var(--fs-2);color:var(--tx-3);padding:var(--sp-3) var(--sp-5);
  border-radius:var(--r-1);border:1px solid var(--line);background:var(--bg);
  white-space:nowrap}
.cmdhint button:hover{border-color:var(--brand);color:var(--brand)}
.cmdhint .hist{font-size:var(--fs-2);color:var(--tx-3);margin-left:auto;
  padding:var(--sp-3) var(--sp-2);text-decoration:underline;text-underline-offset:2px}

/* la respuesta */
.resp .lead{font-size:var(--fs-7);line-height:var(--lh-tight);font-weight:600;
  letter-spacing:var(--ls-tight);margin-bottom:var(--sp-6);text-wrap:balance}
.pregunta{font-size:var(--fs-4);color:var(--tx-2);background:var(--surface);
  padding:var(--sp-5) var(--sp-6);border-radius:var(--r-3);margin-bottom:var(--sp-6)}
.pregunta .et{display:block;font-size:var(--fs-1);font-weight:700;
  letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--tx-3);
  margin-bottom:var(--sp-2)}

/* procedencia */
.pl{display:flex;gap:var(--sp-5);padding:var(--sp-4) 0;font-size:var(--fs-2);
  align-items:flex-start}
.pl .tp{font-size:var(--fs-1);font-weight:700;letter-spacing:var(--ls-caps);
  padding:var(--sp-1) var(--sp-3);border-radius:var(--r-1);flex:none;margin-top:1px;
  width:66px;text-align:center}
.tp-r{background:var(--sunken);color:var(--tx-2);border:1px solid var(--line)}
.tp-h{background:var(--st-porvencer-bg);color:var(--st-porvencer)}
.tp-ia{background:var(--brand-soft);color:var(--brand)}
.pl .tx{flex:1;min-width:0;color:var(--tx-2);line-height:var(--lh-read)}
.pl .tx b{color:var(--tx-1)}
.pl .src{font-size:var(--fs-1);color:var(--tx-3);margin-top:var(--sp-1);
  word-break:break-word}

/* ── portada de acceso ── */
.portada{max-width:520px;margin:0 auto;padding:var(--sp-12) var(--sp-6) var(--sp-11)}
.portada .marca{display:flex;justify-content:center;margin-bottom:var(--sp-9)}
.portada .marca svg{height:44px;width:auto}
.portada .titulo{text-align:center;font-size:var(--fs-7);font-weight:600;
  margin-bottom:var(--sp-3);letter-spacing:var(--ls-tight)}
.portada .lead{text-align:center;font-size:var(--fs-4);color:var(--tx-2);
  margin-bottom:var(--sp-9);line-height:var(--lh-read)}
.pie{text-align:center;font-size:var(--fs-3);color:var(--tx-2);
  margin-top:var(--sp-7);line-height:var(--lh-read)}
.pie.chico{font-size:var(--fs-2);color:var(--tx-3);margin-top:var(--sp-4)}


/* ══ LAS SILUETAS DE LOS DOS ALFABETOS ══
   ⚠️ La geometria ESPEJA `i[data-mark]` de tokens.css y tiene que seguir
   espejandola. Se repite acá por una razón concreta: media docena de estos
   chips llevan la clase calculada en la plantilla —`{{ 'est-vencida' if ... }}`—
   y meterles un `<i>` adentro obligaria a duplicar cada ternaria. Un ::before
   que cuelga de la misma clase no puede quedar desincronizado del color.

   Si cambia una forma en tokens.css, cambia acá. Son siete líneas. */
.est:before,.ver:before{content:'';display:inline-block;flex:none;color:inherit}

.est-aldia:before      {width:9px;height:9px;border-radius:50%;background:currentColor}
.est-porvencer:before  {width:9px;height:9px;border-radius:50%;border:1.5px solid currentColor;
                        background:linear-gradient(90deg,currentColor 50%,transparent 50%)}
.est-vencida:before    {width:11px;height:9px;background:currentColor;
                        clip-path:polygon(50% 0,100% 100%,0 100%)}
.est-sinfirmar:before  {width:8px;height:8px;border:1.6px solid currentColor;
                        transform:rotate(45deg)}

.ver-primaria:before   {width:9px;height:9px;background:currentColor;border-radius:2px}
.ver-secundaria:before {width:9px;height:9px;border:1.5px solid currentColor;border-radius:2px;
                        background:linear-gradient(180deg,currentColor 50%,transparent 50%)}
.ver-a_verificar:before,.ver-pendiente:before
                       {width:9px;height:9px;border:1.5px dashed currentColor;border-radius:2px}

/* ══════════════════════════════════════════════════════════════════════
   EL SELECTOR · tres botones, casi sin texto
   Cada módulo se reconoce por SU figura —el articulado, el terreno, la
   curva de carga— y no por un ícono genérico ni por un párrafo. El texto
   se reduce al nombre y al estado.
   ══════════════════════════════════════════════════════════════════════ */
.verapp{color:var(--tx-3);font-size:var(--fs-1)}
.hd-inicio{margin-bottom:var(--sp-8)}

/* ══════════════════════════════════════════════════════════════════════
   EL SELECTOR DE MÓDULOS

   🔑 Una figura y un nombre. Acá vivían además el encabezado con bajada, el
   chip de «en revisión», el subtítulo de cada tarjeta y la franja de estado
   al pie. wdeza los sacó de raíz: un selector selecciona, y el estado se ve
   —el módulo que no está contratado se apaga— en vez de escribirse.

   🔑 Y con tan poco en pantalla, el bloque va CENTRADO en la ventana. Pegado
   arriba, tres tarjetas chicas bajo una barra dejan dos tercios de pantalla
   vacíos abajo y se lee como una página que no terminó de cargar.
   ══════════════════════════════════════════════════════════════════════ */

/* El centrado se engancha por `:has()` y no por una clase en el `<body>`:
   así vale para esta pantalla y para ninguna otra, sin que la plantilla
   tenga que acordarse de declarar nada. Las de trabajo son largas y
   centrarlas sería un error. */
/* 🔑 El alto se REPARTE, no se calcula. El cuerpo es una columna flexible y
   lo que sobra después de la barra se lo lleva `.app`: así la pantalla se
   ajusta sola al tamaño disponible y no queda fija a ninguna medida.
   🔴 Restar `var(--hz-h)` parecía equivalente y no lo era: la barra declara
   60 px pero mide 61 con su borde, y ese píxel de más sacaba una barra de
   desplazamiento entera en una pantalla con tres tarjetas. Un número escrito
   a mano en dos sitios se desincroniza; repartir el espacio no. */
body:has(.botones){min-height:100dvh;display:flex;flex-direction:column}
body:has(.botones) .app{min-height:0;flex:1}
.canvas:has(.botones){display:flex;align-items:center;justify-content:center;
  /* 🔴 El relleno se reescribe simétrico: el del canvas es más grande abajo
     (`--sp-10` contra `--pad-page`), y centrar dentro de una caja con relleno
     desparejo no centra — quedaba 53 px más arriba de lo que debía. */
  padding-block:var(--pad-page)}
.canvas:has(.botones) .wrap{margin-block:0}

/* El aire entre tarjetas: 20 px las dejaba pegadas, leyéndose como una tira
   de tres y no como tres cosas entre las que se elige. Un selector necesita
   que se vea dónde termina una opción y empieza la otra. */
.botones{display:grid;gap:var(--sp-11);margin:0;
  grid-template-columns:repeat(3,minmax(0,1fr))}

/* 🔑 `aspect-ratio` y NO `min-height`: la proporción de la tarjeta es 6:5 y
   se mantiene igual en las tres columnas del escritorio y en la única del
   teléfono. Con altura mínima, el ancho variaba y la altura no, así que la
   misma tarjeta pasaba de 6:5 a casi 16:9 al angostar la ventana — la caja
   se deformaba, que es justo lo que no puede pasar cuando lo único que
   distingue a un módulo de otro es su figura. */
.bt{position:relative;display:flex;flex-direction:column;overflow:hidden;
  aspect-ratio:6/5;
  border:1px solid var(--line);border-radius:18px;background:var(--surface);
  text-decoration:none;color:inherit;
  transition:transform .22s cubic-bezier(.22,1,.36,1),border-color .18s,box-shadow .22s}
.bt-arte{flex:1;display:grid;place-items:center;min-height:0;
  padding:var(--sp-7) var(--sp-7) var(--sp-6);position:relative}
/* `max-height:100%` además del ancho: dentro de una caja de proporción fija,
   una figura que solo limita el ancho desborda en cuanto la tarjeta se
   angosta. */
.bt-arte svg{width:100%;max-width:224px;max-height:100%;height:auto;display:block}
.bt-pie{display:flex;align-items:center;gap:var(--sp-4);flex:none;
  padding:var(--sp-6) var(--sp-7);border-top:1px solid var(--line);
  background:var(--bg)}
.bt-pie b{font-size:18px;font-weight:700;letter-spacing:-.012em;line-height:1.2;
  color:var(--tx-1)}

/* El halo de color: es lo que le da vida sin agregar una palabra. Cada
   módulo trae el suyo, y los tres barren el azul y el verde de la marca. */
.bt::after{content:"";position:absolute;inset:-40% -30% 45% -30%;pointer-events:none;
  opacity:.55;transition:opacity .25s;z-index:0}
.bt-regulatorio::after{background:radial-gradient(50% 55% at 62% 62%,
  color-mix(in srgb,var(--brand-blue) 26%,transparent),transparent 72%)}
.bt-ambiental::after{background:radial-gradient(52% 56% at 38% 62%,
  color-mix(in srgb,var(--brand-green) 26%,transparent),transparent 72%)}
.bt-energia::after{background:radial-gradient(56% 58% at 50% 66%,
  color-mix(in srgb,var(--brand) 24%,transparent),transparent 72%)}
/* 🔴 La figura y el nombre por ENCIMA del halo. Al sacar la franja de estado
   esta regla se rompió y quedó pegada a la de abajo: el halo tapaba la
   figura sin que ninguna hoja diera error. */
.bt-arte,.bt-pie{position:relative;z-index:1}

.bt.listo{cursor:pointer}
.bt.listo:hover{transform:translateY(-4px);border-color:var(--brand);
  box-shadow:0 10px 30px -14px color-mix(in srgb,var(--brand) 55%,transparent)}
.bt.listo:hover::after{opacity:.95}
.bt.listo:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
.bt.pidiendo{border-style:dashed}
.bt.pronto{opacity:.62}
.bt.pronto::after{opacity:.25}

@media (max-width:1080px){
  .botones{grid-template-columns:1fr 1fr;gap:var(--sp-10)}
}

/* ── el teléfono ──
   Una columna, la MISMA proporción, y 20 % de margen a cada lado pedido por
   wdeza. Va en `vw` y no en `%` porque el porcentaje sería del contenedor y
   lo que él quiere medir es la ventana; por eso el canvas suelta su propio
   relleno lateral acá, o los dos se sumarían. */
@media (max-width:760px){
  .canvas:has(.botones){padding-inline:0}
  .botones{grid-template-columns:1fr;gap:var(--sp-9);padding-inline:20vw}
  .bt-arte{padding:var(--sp-6) var(--sp-6) var(--sp-4)}
  .bt-arte svg{max-width:none}
  .bt-pie{padding:var(--sp-5) var(--sp-6)}
  .bt-pie b{font-size:16.5px}
}

/* ══════════════════════════════════════════════════════════════════════
   CONFIGURACIÓN · las cuatro pantallas de la empresa
   ══════════════════════════════════════════════════════════════════════
   Menú LATERAL y no pestañas: son secciones de trabajo distintas, no
   vistas de lo mismo. En móvil se vuelve una fila que se desplaza, que es
   mejor que comprimir cuatro rótulos hasta hacerlos ilegibles.

   🔴 Y ACÁ ESTABA EL RECLAMO DE wdeza: «¿cuál es el sentido de no ocupar
   toda la pantalla y solo dejar ocupada una parte?». La respuesta era
   `.wrap.ancho{max-width:1120px}`, que está bien para el selector de
   módulos —tres tarjetas grandes— y sobra media pantalla cuando adentro
   hay una tabla de siete columnas y un organigrama. El `ancho` SÍ se
   estaba aplicando; lo que pasaba es que 1120 px no es ancho.

   Se ensancha por `:has(.cfg)` y no por un `ancho` nuevo en el contexto
   porque `base.html` no es de este agente: la plantilla imprime
   `{{ 'ancho' if ancho }}` y no admite una segunda clase. Un navegador sin
   `:has` cae al 1120 de antes, que es exactamente lo que había. */
/* 🔴 `none` Y NO 1560. Esta línea ya había ensanchado Configuración una vez,
   de 1120 a 1560, contestando un reclamo anterior de wdeza. Volvió a
   reclamarlo el 31-ago —«sigue sin ocupar la totalidad del ancho»— y tenía
   razón: 1560 en una pantalla de 1920 deja 180 px muertos a cada lado,
   mientras la matriz y el inventario van a 1856. Un tope intermedio arregla el
   síntoma y deja el problema.
   ⚠️ Y yo escribí una regla `max-width:none` 600 líneas MÁS ARRIBA creyendo
   que lo arreglaba: ésta la pisaba por venir después. Es la misma trampa que
   `docs/20 §3` ya cuenta —«una anulación de CSS vive después de lo que
   anula»— y la volví a pisar. Se arregla DONDE ESTABA, no con una regla
   nueva. */
.wrap.ancho:has(.cfg){max-width:none}

.cfg{display:grid;grid-template-columns:212px minmax(0,1fr);gap:var(--sp-9);
  align-items:start}
.cfg-menu{display:flex;flex-direction:column;gap:var(--sp-2);position:sticky;
  top:calc(var(--hz-h) + var(--sp-6))}
.cfg-menu a{display:flex;align-items:center;gap:var(--sp-5);
  padding:var(--sp-5) var(--sp-6);border-radius:var(--r-1);
  color:var(--tx-2);text-decoration:none;font-size:var(--fs-3)}
.cfg-menu a svg{width:18px;height:18px;flex:none}
.cfg-menu a:hover{background:var(--sunken);color:var(--tx-1)}
.cfg-menu a.on{background:var(--brand-soft);color:var(--brand);font-weight:600}
.cfg-cuerpo{min-width:0}

/* ── las migas ── el menú lateral desaparece en móvil y esto es lo único
   que queda diciendo dónde estoy. */
.migas{display:flex;align-items:center;gap:var(--sp-4);font-size:var(--fs-2);
  color:var(--tx-3);margin-bottom:var(--sp-5)}
.migas a{color:var(--tx-3)}
.migas a:hover{color:var(--brand)}

/* ── el encabezado de cada sección: título a la izquierda, acciones a la
   derecha. Es la estructura de SafeUp y funciona por una razón concreta:
   los botones de alta viven arriba, donde se los busca, y no al pie de una
   tabla de cuarenta filas. ── */
.cfg-hd{display:flex;align-items:flex-start;gap:var(--sp-6);flex-wrap:wrap;
  margin-bottom:var(--sp-8)}
.cfg-hd h1{margin:0;font-size:var(--fs-8);font-weight:600;
  letter-spacing:var(--ls-tight);line-height:var(--lh-tight)}
.cfg-hd .sub{font-size:var(--fs-4);color:var(--tx-2);margin-top:var(--sp-3);
  line-height:var(--lh-read);max-width:64ch}
.cfg-acc{margin-left:auto;display:flex;align-items:center;gap:var(--sp-3);
  flex-wrap:wrap}
.cfg-acc .b{white-space:nowrap}

/* ══════════════════════════════════════════════════════════════════════
   BUSCADOR Y PÍLDORAS DE FILTRO
   Filtran EN EL NAVEGADOR. La lista entera ya está pintada —son las
   personas de una empresa, no un corpus de mil normas— y un filtro que
   viaja a São Paulo cuesta ~100 ms para tachar filas que ya están acá.
   ══════════════════════════════════════════════════════════════════════ */
.buscador{display:flex;align-items:center;gap:var(--sp-5);flex-wrap:wrap;
  margin-bottom:var(--sp-7)}
.busca-caja{flex:1 1 340px;min-width:0;display:flex;align-items:center;
  gap:var(--sp-4);min-height:40px;padding:0 var(--sp-6);background:var(--bg);
  border:1px solid var(--line-hi);border-radius:var(--r-1)}
.busca-caja:focus-within{border-color:var(--brand)}
.busca-caja svg{width:16px;height:16px;color:var(--tx-3);flex:none}
.busca-caja input{flex:1;min-width:0;border:none;background:none;font:inherit;
  font-size:var(--fs-4);color:var(--tx-1);outline:none}
.busca-caja input::placeholder{color:var(--tx-3)}
.pildoras{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.pildora{display:inline-flex;align-items:center;gap:var(--sp-3);min-height:36px;
  padding:0 var(--sp-6);border:1px solid var(--line);border-radius:var(--r-1);
  background:var(--bg);color:var(--tx-2);font:inherit;font-size:var(--fs-2);
  cursor:pointer}
.pildora:hover{border-color:var(--line-hi);color:var(--tx-1)}
.pildora.on{background:var(--brand-soft);border-color:var(--brand);
  color:var(--brand);font-weight:650}
.pildora .n{font-variant-numeric:tabular-nums;color:var(--tx-3)}
.pildora.on .n{color:var(--brand)}

/* ══════════════════════════════════════════════════════════════════════
   TABLA DENSA · dos renglones por celda
   🔑 El correo va DEBAJO del nombre y el tipo de documento debajo del
   número, en gris y chico. Es lo que deja meter siete columnas de datos
   sin que la fila se vuelva ilegible: son pares —quién y su correo,
   número y su tipo—, no catorce columnas hermanas.
   ══════════════════════════════════════════════════════════════════════ */
.cfg-cuerpo table.tabla th{white-space:nowrap;text-align:left}
.tabla.densa td{vertical-align:top}
.tabla .sub2{display:block;margin-top:2px;font-size:var(--fs-2);
  font-weight:400;letter-spacing:0;color:var(--tx-3);text-transform:none}
.tabla .quien{display:flex;align-items:flex-start;gap:var(--sp-5);min-width:0}
.tabla .quien-tx{min-width:0}
.tabla .quien .av{width:30px;height:30px;flex:none;background:var(--brand-soft);
  color:var(--brand);font-size:var(--fs-2);font-weight:700;margin-top:1px}
.b.peligro{background:var(--st-vencida);border-color:var(--st-vencida)}
.b.peligro:hover{background:var(--st-vencida);border-color:var(--st-vencida);
  filter:brightness(1.08)}
.b.peligro:disabled{opacity:.4;cursor:not-allowed;filter:none}

/* ══════════════════════════════════════════════════ SOLO LECTURA ══
   El servidor ya lo impide (`permisos.veredicto()`); esto deja de OFRECERLO.
   `pointer-events:none` y no `display:none`: la persona tiene que poder VER
   el formulario y lo que dice —es su trabajo entenderlo— sin poder mandarlo.
   Esconderlo le ocultaria informacion que su rol si le permite mirar. */
.solo-lectura .cinta-lectura{position:sticky;top:0;z-index:60;
  padding:var(--sp-4) var(--sp-6);font-size:var(--fs-2);line-height:var(--lh-read);
  background:var(--st-porvencer);color:#fff;text-align:center}
.solo-lectura form button[type=submit],
.solo-lectura form input[type=file],
.solo-lectura form input[type=submit]{pointer-events:none;opacity:.38;
  filter:grayscale(1)}
/* Los controles que NO mandan nada siguen vivos: cerrar un dialogo, abrirlo,
   desplegar un combo. Un rol de lectura que no puede ni cerrar una ventana
   estaria roto, no restringido. */
.solo-lectura form button[type=button]{pointer-events:auto;opacity:1;
  filter:none}

/* ═══════════════════════════════════ LA PANTALLA DEL EXTERNO CONVOCADO ══
   Sin barra, sin menu, sin modulos: contesta UNA pregunta. Se le da un ancho
   de lectura y no el de la aplicacion —quien llega aca no esta trabajando en
   una matriz de doscientas filas, esta entregando un documento—. */
.ext-body{background:var(--surface)}
.ext{max-width:720px;margin:0 auto;padding:var(--sp-7) var(--sp-6) var(--sp-9);
  display:flex;flex-direction:column;gap:var(--sp-6)}
.ext-corta{min-height:60vh;justify-content:center}
.ext-cab{display:flex;align-items:center;justify-content:space-between;
  gap:var(--sp-5);flex-wrap:wrap;margin-bottom:var(--sp-3)}
.ext-logo{display:inline-flex;color:var(--brand)}
.ext-logo svg{height:26px;width:auto}
.ext-quien{font-size:var(--fs-2);color:var(--tx-3);text-align:right}
.ext-caja{background:var(--bg);border:1px solid var(--line);
  border-radius:var(--r-3);padding:var(--sp-6)}
.ext-caja h1{font-size:var(--fs-5);line-height:var(--lh-tight);margin:0 0 4px}
.ext-caja h2{font-size:var(--fs-3);margin:0 0 var(--sp-5)}
/* El encargo va ARRIBA del titulo y con mas peso: el titulo esta redactado
   para la matriz de la empresa, el encargo para esta persona. */
.ext-encargo{margin:0 0 var(--sp-5);font-size:var(--fs-3);color:var(--tx-1);
  line-height:var(--lh-read);border-left:3px solid var(--brand);
  padding-left:var(--sp-5)}
.ext-desc{margin:var(--sp-5) 0 0;font-size:var(--fs-2);color:var(--tx-2);
  line-height:var(--lh-read)}
.ext-datos{display:flex;gap:var(--sp-7);flex-wrap:wrap;margin-top:var(--sp-6)}
.ext-datos div{display:flex;flex-direction:column;gap:2px}
.ext-datos i{font-style:normal;font-size:11px;color:var(--tx-3);
  letter-spacing:var(--ls-caps);text-transform:uppercase}
.ext-lista{margin:0;padding-left:var(--sp-6);display:flex;flex-direction:column;
  gap:var(--sp-4);font-size:var(--fs-2);color:var(--tx-1);
  line-height:var(--lh-read)}
.ext-lista .sub2{display:block}
.ext-form{display:flex;flex-direction:column;gap:var(--sp-5)}
.ext-form .campo span{display:block;font-size:11px;color:var(--tx-3);
  letter-spacing:var(--ls-caps);text-transform:uppercase;margin-bottom:4px}
.ext-form input{width:100%}
@media (max-width:520px){
  .ext{padding:var(--sp-5) var(--sp-4) var(--sp-7)}
  .ext-quien{text-align:left}
}

/* EL COMBO CON BUSCADOR ========================================
   `combo.js` lo monta desde `base.html` sobre todo <select> con 9 o mas
   opciones, en cualquier pantalla. Por eso sus estilos son de la hoja base:
   estaban en `listas.css`, y las pantallas que no la cargan —Configuracion
   entre ellas— pintaban el panel desplegado, sin caja y comiendose media
   ficha. Medido en Configuracion › Usuarios, en el «Reporta a» del dialogo
   de una persona: `.cbx-panel` en `display:block` y `position:static`.
   Un guion global necesita estilos globales. */
/* El combo. `position:relative` es del contenedor porque el panel cuelga de
   él; sin eso el panel se ancla al viewport y aparece en otra parte de la
   pantalla al desplazarse la página. */
/* 🔴 `--r-1` Y NO `--r-2`. Éste es el defecto que wdeza llamó «la peor idea
   que has tenido», y no era una cuestión de gusto: **usé mal un token cuyo
   propio comentario dice para qué es**. `--r-2` vale `50%` y `tokens.css` lo
   glosa «avatares y marcas circulares: acá sí es círculo». Sobre una caja de
   34 px de alto y 300 de ancho, el 50 % no redondea la esquina: convierte el
   campo en una ELIPSE.

   Y era reincidencia. El propio `tokens.css` guarda la corrección de wdeza del
   12-ago: «no exageres con que la plataforma es curva, usemos rectángulos con
   esquinas redondeadas», que fue justamente por lo que `--r-1` bajó de 999 px a
   10. El token para chips, botones, campos y píldoras es `--r-1`, está escrito
   ahí, y no lo leí. */
.cbx{position:relative;display:flex;align-items:center;gap:var(--sp-3);
  min-width:0;
  /* 🔴 `flex:1 1 200px` NO VA EN LA BASE. Estaba escrito para la
     franja de Acotar, que es una fila: ahi los 200 px son ANCHO. Desde que
     `combo.js` se monta solo, el mismo combo cae dentro de `.campo`, que es
     una COLUMNA —y ahi los 200 px son ALTO—. Medido en el «Reporta a» del
     dialogo de una persona: un desplegable de 200 px de alto. El estirado
     vuelve a ser de cada franja, que es la que sabe si crece a lo ancho. */
  flex:0 1 auto;max-width:340px;
  border:1px solid var(--line);border-radius:var(--r-1);background:var(--bg);
  padding:0 var(--sp-3);min-height:34px;transition:border-color .12s}
.cbx:hover{border-color:var(--line-hi)}
.cbx.puesto{border-color:var(--brand);background:var(--brand-soft)}
.cbx-ico{flex:none;display:grid;place-items:center;color:var(--tx-3)}
.cbx-ico .ic{width:15px;height:15px}
.cbx.puesto .cbx-ico{color:var(--brand)}
/* El rótulo del eje sólo se ve cuando NO hay JavaScript: con el combo montado
   lo dice el propio botón, y repetirlo gasta la mitad del ancho. */
.cbx-rot{display:none;font-size:11px;color:var(--tx-3);white-space:nowrap}
.cbx > select{flex:1;min-width:0;font:inherit;font-size:var(--fs-2);
  border:0;background:transparent;color:var(--tx-1);min-height:32px;
  text-overflow:ellipsis}
.cbx > select:focus-visible{outline:2px solid var(--brand);outline-offset:1px}

/* Montado el combo, el `<select>` se va del flujo pero NO se quita del DOM ni
   se marca `disabled`: sigue siendo el campo que viaja en el formulario. */
.cbx.cbx-vivo > select{position:absolute;width:1px;height:1px;opacity:0;
  pointer-events:none}
.cbx-bt{flex:1;min-width:0;display:flex;align-items:center;gap:var(--sp-3);
  font:inherit;font-size:var(--fs-2);color:var(--tx-1);background:none;
  border:0;padding:0;min-height:32px;cursor:pointer;text-align:left}
.cbx-v{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.cbx.puesto .cbx-v{color:var(--brand);font-weight:600}
.cbx-fl{flex:none;width:8px;height:8px;border-right:1.6px solid var(--tx-3);
  border-bottom:1.6px solid var(--tx-3);transform:translateY(-2px) rotate(45deg)}
.cbx.abierto{border-color:var(--brand);outline:2px solid var(--brand);
  outline-offset:-1px}
.cbx.abierto .cbx-fl{transform:translateY(2px) rotate(-135deg)}

/* El panel. Ancho MÍNIMO el del combo y máximo mayor: los nombres de
   instrumento del OEFA pasan de 90 caracteres y cortarlos a 200 px deja
   quince opciones que empiezan igual. */
.cbx-panel{position:absolute;top:calc(100% + 4px);left:0;z-index:40;
  min-width:100%;width:max-content;max-width:min(460px,86vw);
  background:var(--bg);border:1px solid var(--line-hi);border-radius:var(--r-1);
  box-shadow:0 10px 28px rgba(0,0,0,.14);padding:var(--sp-3);
  display:none;flex-direction:column;gap:var(--sp-3)}
.cbx.abierto .cbx-panel{display:flex}
.cbx-busca{font:inherit;font-size:var(--fs-2);min-height:30px;
  padding:0 var(--sp-4);border:1px solid var(--line);border-radius:var(--r-1);
  background:var(--surface);color:var(--tx-1);width:100%}
.cbx-busca:focus-visible{border-color:var(--brand);outline:2px solid var(--brand);
  outline-offset:1px}
.cbx-lista{max-height:min(320px,46vh);overflow-y:auto;display:flex;
  flex-direction:column;gap:1px;scrollbar-width:thin}
.cbx-op{display:flex;align-items:center;gap:var(--sp-4);width:100%;
  font:inherit;font-size:var(--fs-2);color:var(--tx-1);text-align:left;
  background:none;border:0;border-radius:var(--r-1);padding:6px var(--sp-4);
  min-height:30px;cursor:pointer}
.cbx-op:hover,.cbx-op.foco{background:var(--surface)}
.cbx-op.on{background:var(--brand-soft);color:var(--brand);font-weight:600}
.cbx-op-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.cbx-op-r{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* El segundo renglón: cargo, tipo o código. Gris y más chico — es lo que
   DESAMBIGUA, no lo que se busca. */
.cbx-op-s{font-size:10.5px;color:var(--tx-3);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;letter-spacing:var(--ls-caps)}
.cbx-op.on .cbx-op-s{color:var(--brand)}
/* 🔑 La cuenta, alineada a la derecha. Es lo que contesta «¿esta unidad tiene
   compromisos?» ANTES de pulsarla — que es todo el motivo por el que las 21
   unidades del grupo se ofrecen y no sólo las 2 que tienen filas. */
.cbx-op-n{flex:none;font-size:11px;font-weight:700;color:var(--tx-2);
  font-variant-numeric:tabular-nums}
.cbx-op-n.cero{color:var(--tx-3);font-weight:500}
.cbx-op.cbx-vacia{color:var(--tx-2)}
.cbx-nada{margin:0;padding:var(--sp-3) var(--sp-4);font-size:var(--fs-2);
  color:var(--tx-3)}
/* 🔴 `.fuera` Y NO EL ATRIBUTO `hidden`. `[hidden]{display:none}` es regla del
   agente de usuario y pierde contra cualquier `display` de autor: con
   `.cbx-op{display:flex}` puesto, `x.hidden = true` no escondía una sola
   opción y el buscador parecía no filtrar. Es el mismo defecto que ya se pagó
   en el filtro del inventario (`docs/20 §1`). */
.cbx-op.fuera,.cbx-nada.fuera,.cbx-ir.fuera{display:none}

/* ══════════════════════════════════════════════════════ ZONA DE RIESGO ══
   El pie de la ficha de una persona, donde vive lo que no se deshace de un
   clic. Va separada con una línea y su propio fondo porque lo de arriba se
   guarda con «Guardar» y esto NO: manda su propio formulario. */
.zona-riesgo{margin-top:var(--sp-7);padding-top:var(--sp-6);
  border-top:1px solid var(--line)}
.zona-riesgo .zr-cab{display:flex;align-items:center;gap:var(--sp-4);
  margin-bottom:var(--sp-4)}
.zona-riesgo .ayuda{display:block;margin-bottom:var(--sp-5)}
.zona-riesgo .socia{margin-bottom:var(--sp-5)}
.zona-riesgo .socia span{font-size:var(--fs-2);color:var(--tx-2);
  line-height:var(--lh-read)}
.tabla td.acc{text-align:right;white-space:nowrap}
/* 🔴 LOS BOTONES SE ALINEAN EN UNA CAJA, NUNCA EN EL <td>. La pestaña de
   usuarios llevaba `style="display:flex"` sobre la celda misma: un <td> en
   flex deja de ser celda de tabla, se sale de la rejilla de alturas de la
   fila —medido: 57 px contra 65,4 de las otras siete— y su borde inferior cae
   ocho píxeles más arriba que el del resto. Eso es el desfase que wdeza vio
   en la columna «Editar». La celda vuelve a ser celda y el flex baja acá. */
.tabla td.acc>.acc-caja{display:flex;justify-content:flex-end;
  gap:var(--sp-3);flex-wrap:wrap;align-items:center}
.tabla .tx-larga{font-size:var(--fs-2);color:var(--tx-3);max-width:46ch}
/* La fila de la sociedad en la que uno está parado. */
.tabla tr.aqui td{background:var(--brand-soft)}
.tabla tr.aqui:hover td{background:var(--brand-soft)}
/* Una fila tachada por el filtro no se oculta a medias: desaparece. */
.tabla tr[hidden]{display:none}

.tpie{margin-top:var(--sp-5);font-size:var(--fs-2);color:var(--tx-3)}
.tpie b{color:var(--tx-2)}

/* ══════════════════════════════════════════════════════════════════════
   DIÁLOGOS · el alta masiva y el alta de a uno
   🔑 Son diálogos y no secciones más de la página. En SafeUp la carga
   masiva es un diálogo por un motivo que se nota apenas se mira la
   pantalla: el bloque de CSV siempre visible empuja la tabla —lo que se
   viene a mirar— hasta el pie de la página, todos los días, para una
   acción que se hace tres veces al año.
   ══════════════════════════════════════════════════════════════════════ */
.dlg{width:min(760px,94vw);padding:0;border:none;background:none;
  color:var(--tx-1)}
.dlg.ancho{width:min(940px,94vw)}
.dlg::backdrop{background:rgba(14,27,26,.5)}
.dlg-caja{display:flex;flex-direction:column;max-height:88dvh;
  background:var(--bg);border:1px solid var(--line);border-radius:var(--r-4);
  overflow:hidden}
.dlg-cab{display:flex;align-items:center;gap:var(--sp-5);
  padding:var(--sp-7) var(--sp-8);border-bottom:1px solid var(--line)}
.dlg-cab h2{margin:0;font-size:var(--fs-7);font-weight:600;
  letter-spacing:var(--ls-tight)}
.dlg-x{margin-left:auto;flex:none;width:32px;height:32px;border-radius:var(--r-1);
  border:1px solid var(--line);background:var(--bg);color:var(--tx-3);
  font-size:18px;line-height:1;cursor:pointer}
.dlg-x:hover{border-color:var(--line-hi);color:var(--tx-1)}
.dlg-cuerpo{display:flex;flex-direction:column;gap:var(--sp-6);
  padding:var(--sp-7) var(--sp-8);overflow-y:auto}
.dlg-pie{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap;
  padding:var(--sp-6) var(--sp-8);border-top:1px solid var(--line);
  background:var(--surface)}
.dlg-espacio{flex:1 1 auto}
.dlg .form{background:none;border:none;padding:0}

/* ── los dos recuadros de aviso dentro de un diálogo ──
   🔴 SafeUp los pinta azul y ámbar. Olivia es verde: se copia la
   ESTRUCTURA —un recuadro que explica el formato y otro que avisa lo que
   NO va a pasar— y no la paleta. El ámbar sí se conserva porque en este
   sistema visual ya significa algo: «por vencer», o sea atención sin
   alarma, que es exactamente el tono del segundo recuadro. */
.aviso{font-size:var(--fs-3);line-height:var(--lh-read);color:var(--tx-2);
  padding:var(--sp-6) var(--sp-7);border-radius:var(--r-3)}
.aviso b{color:var(--tx-1);font-weight:650}
.aviso.info{background:var(--brand-soft);border-left:3px solid var(--brand)}
.aviso.ojo{background:var(--st-porvencer-bg);
  border-left:3px solid var(--st-porvencer)}
.aviso .formato{display:block;margin:var(--sp-5) 0;padding:var(--sp-5) var(--sp-6);
  background:var(--bg);border:1px solid var(--line);border-radius:var(--r-1);
  font-family:ui-monospace,"Cascadia Mono","Consolas",monospace;
  font-size:var(--fs-2);color:var(--tx-2);overflow-x:auto;white-space:nowrap}

/* ── la zona de pegado ──
   Línea punteada porque es donde algo entra. El `input[type=file]` real se
   queda adentro del botón, invisible y clicable: el control nativo sigue
   siendo el que envía, así que sin CSS y sin JS el formulario funciona. */
.zona{border:1.5px dashed var(--line-hi);border-radius:var(--r-3);
  background:var(--surface);padding:var(--sp-6)}
.zona-cab{display:flex;align-items:center;gap:var(--sp-5);flex-wrap:wrap;
  margin-bottom:var(--sp-5)}
.zona-cab b{font-size:var(--fs-3);font-weight:650}
.zona-btn{margin-left:auto;position:relative;overflow:hidden;
  display:inline-flex;align-items:center;cursor:pointer}
.zona-btn input[type=file]{position:absolute;inset:0;width:100%;height:100%;
  opacity:0;cursor:pointer}
.zona textarea{width:100%;min-height:130px;resize:vertical;
  padding:var(--sp-5) var(--sp-6);background:var(--bg);
  border:1px solid var(--line);border-radius:var(--r-1);
  font-family:ui-monospace,"Cascadia Mono","Consolas",monospace;
  font-size:var(--fs-2);line-height:1.7;color:var(--tx-1)}
.zona textarea:focus{outline:none;border-color:var(--brand)}
.zona textarea::placeholder{color:var(--tx-3)}
.zona-pie{display:block;margin-top:var(--sp-4);font-size:var(--fs-2);
  color:var(--tx-3)}

/* ── casillas de módulo en el alta de una sociedad ── */
.casillas{display:grid;gap:var(--sp-4)}
.casilla{display:flex;align-items:flex-start;gap:var(--sp-5);
  padding:var(--sp-5) var(--sp-6);border:1px solid var(--line);
  border-radius:var(--r-1);cursor:pointer}
.casilla:hover{border-color:var(--line-hi)}
.casilla input{flex:none;margin-top:3px;accent-color:var(--brand)}
.casilla>span{display:flex;flex-direction:column;gap:2px;min-width:0}
.casilla b{font-size:var(--fs-3);font-weight:650}
.casilla i{font-style:normal;font-size:var(--fs-2);color:var(--tx-3);
  line-height:var(--lh-read)}

/* ══════════════════════════════════════════════════════════════════════
   LOS PAPELES DE HABILITACIÓN
   Ficha RUC, vigencia de poder y DNI del representante. El estado se ve y
   NO bloquea: la sociedad opera desde que se incorpora y LQG valida
   después. Por eso ninguna de estas tarjetas apaga nada de la pantalla.
   ══════════════════════════════════════════════════════════════════════ */
.papeles{display:grid;gap:var(--sp-5);margin-bottom:var(--sp-6);
  grid-template-columns:repeat(auto-fit,minmax(310px,1fr))}
.papel{display:flex;flex-direction:column;gap:var(--sp-4);
  padding:var(--sp-6) var(--sp-7);background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-3)}
.papel.validado{border-color:var(--st-aldia)}
.papel.observado{border-color:var(--st-vencida);background:var(--st-vencida-bg)}
.papel-cab{display:flex;align-items:flex-start;gap:var(--sp-5)}
.papel-quien{display:flex;flex-direction:column;gap:2px;min-width:0}
.papel-quien b{font-size:var(--fs-4);font-weight:650}
.papel-quien i{font-style:normal;font-size:var(--fs-2);color:var(--tx-3);
  line-height:var(--lh-read)}
.papel-cab .est,.papel-cab .chip{margin-left:auto;flex:none}
.papel-meta{font-size:var(--fs-2);color:var(--tx-3);line-height:var(--lh-read)}
.papel-form{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap;
  margin-top:auto;padding-top:var(--sp-5);border-top:1px solid var(--line)}
.papel-form input{flex:1 1 130px;min-width:0;font:inherit;font-size:var(--fs-2);
  padding:var(--sp-4) var(--sp-5);background:var(--bg);
  border:1px solid var(--line);border-radius:var(--r-1);color:var(--tx-1)}
.papel-form input:focus{outline:none;border-color:var(--brand)}
.papel-form input[type=file]{flex:1 1 100%;border-style:dashed;cursor:pointer}
.papel-form .b{flex:none}

/* ══════════════════════════════════════════════════════════════════════
   EL ORGANIGRAMA · de arriba hacia abajo, con líneas
   ══════════════════════════════════════════════════════════════════════
   🔑 Cajas apiladas de arriba hacia abajo y los hijos de un mismo jefe uno
   AL LADO DEL OTRO, con la horizontal que los reparte. La versión anterior
   era una lista con sangría: decía quién cuelga de quién y no dejaba ver la
   FORMA de la organización, que es para lo que alguien abre un organigrama.

   Las líneas son `::before` y `::after` sobre listas anidadas —el truco
   clásico— y no una librería de diagramas: dos pseudo-elementos por nodo,
   cero JavaScript, y se imprime.

     · cada `li` levanta media horizontal a cada lado y una vertical al medio;
     · al primero se le borra la mitad izquierda y al último la derecha, así
       la horizontal empieza y termina en el centro de las cajas de la punta;
     · el hijo único no lleva horizontal, solo el bajante del `ul`.
   ══════════════════════════════════════════════════════════════════════ */
.ogx{overflow-x:auto;padding:var(--sp-6) 0 var(--sp-8)}
.og,.og ul{display:flex;justify-content:center;list-style:none;margin:0;
  padding:var(--sp-7) 0 0;position:relative}
.og{padding-top:0}
.og li{display:flex;flex-direction:column;align-items:center;position:relative;
  padding:var(--sp-7) var(--sp-5) 0}
/* las dos mitades de la horizontal y el bajante */
.og li::before,.og li::after{content:"";position:absolute;top:0;right:50%;
  width:50%;height:var(--sp-7);border-top:1px solid var(--line)}
.og li::after{right:auto;left:50%;border-left:1px solid var(--line)}
.og li:first-child::before,.og li:last-child::after{border:none}
.og li:last-child::before{border-right:1px solid var(--line);
  border-radius:0 var(--sp-3) 0 0}
.og li:first-child::after{border-radius:var(--sp-3) 0 0 0}
.og li:only-child{padding-top:var(--sp-7)}
.og li:only-child::before{display:none}
.og li:only-child::after{left:50%;right:auto;width:0;border-radius:0;
  border-left:1px solid var(--line);border-top:none}
/* el bajante que sale del padre hacia la fila de hijos */
.og ul::before{content:"";position:absolute;top:0;left:50%;width:0;
  height:var(--sp-7);border-left:1px solid var(--line)}
/* la raíz no cuelga de nadie: sin líneas hacia arriba */
.og>li{padding-top:0}
.og>li::before,.og>li::after{display:none}

.og-caja{display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);
  width:186px;padding:var(--sp-6) var(--sp-5);text-align:center;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-3)}
.og-caja b{font-size:var(--fs-3);font-weight:650;line-height:var(--lh-ui);
  text-wrap:balance}
.og-caja i{font-style:normal;font-size:var(--fs-2);color:var(--tx-2);
  line-height:var(--lh-ui)}
.og-area{font-size:var(--fs-1);letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--tx-3)}
.og-av{width:38px;height:38px;border-radius:var(--r-2);display:grid;
  place-items:center;background:var(--brand-soft);color:var(--brand);
  font-size:var(--fs-3);font-weight:700;flex:none}
.og-pie{display:flex;align-items:center;justify-content:center;gap:var(--sp-3);
  flex-wrap:wrap;margin-top:var(--sp-2)}
.og-n{font-size:var(--fs-1);font-weight:700;letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--brand);background:var(--brand-soft);
  padding:var(--sp-1) var(--sp-4);border-radius:999px;white-space:nowrap}
/* Externo: caja punteada. La misma convención que ya usaba `.nodo.ext`. */
.og-caja.ext{background:var(--bg);border-style:dashed}
.og-caja.mas{width:auto;padding:var(--sp-4) var(--sp-6);font-size:var(--fs-2);
  color:var(--tx-3);border-style:dashed}

@media (max-width:820px){
  .cfg{grid-template-columns:1fr;gap:var(--sp-7)}
  .cfg-menu{position:static;flex-direction:row;overflow-x:auto;
    border-bottom:1px solid var(--line);padding-bottom:var(--sp-3)}
  .cfg-menu a{white-space:nowrap}
  .cfg-acc{margin-left:0;width:100%}
  .cfg-acc .b{flex:1 1 auto;justify-content:center}
  .buscador{gap:var(--sp-4)}
  .pildoras{overflow-x:auto;flex-wrap:nowrap;width:100%}
  .og-caja{width:158px}
}

/* Los dos botones de pedido en la tabla del Plan: en una fila, sin envolver
   —«Solicitar / Pedir demo» partido en dos renglones se lee como dos cosas
   distintas de la misma fila— y sin que la columna estire la tabla. */
.tabla td.acciones{white-space:nowrap;text-align:right}
.tabla td.acciones form{display:inline-flex;gap:var(--sp-3);justify-content:flex-end}



/* ══════════════════════════════════════════════════════════════════════════
   MÓDULO AMBIENTAL · PASO 1 — el inventario que el PIFA propone
   ══════════════════════════════════════════════════════════════════════════
   Tres decisiones gobiernan este bloque:

   1. **El mapa acompaña el scroll.** Antes se iba de vista al primer
      desplazamiento y dejaba de aportar. Es una columna pegajosa: al lado del
      titular en escritorio, banda fina bajo la barra en teléfono.
   2. **Seleccionar atenúa, no esconde.** Ocultar filas haría saltar la página
      y perdería el sitio donde estaba el ojo; y lo que se quiere ver es el
      CONTRASTE entre lo alcanzado y lo demás.
   3. **El color de las cifras es el degradado de MARCA, no un matiz de
      estado.** Los cuatro matices de plazo son intocables y no aparecen en
      esta pantalla: acá no hay ninguna obligación con vencimiento todavía. */

/* ── LA REJILLA ─────────────────────────────────────────────────────────
   🔑 En escritorio el mapa ocupa una columna que abarca las DOS filas, así
   que `position:sticky` lo mantiene a la vista mientras se recorre la lista
   —el rectángulo que limita a un elemento pegajoso es su área de rejilla—.
   En teléfono la rejilla se apaga a `display:block`: ahí el límite pasa a ser
   el bloque contenedor, que abarca todo, y el mapa se pega igual. Son dos
   mecanismos distintos para el mismo efecto, y por eso está escrito acá. */
.amb-cuerpo{
  display:grid;
  grid-template-columns:minmax(0,1fr) clamp(240px,26vw,320px);
  grid-template-areas:"dicho mapa" "lista mapa";
  gap:var(--sp-8) var(--sp-10);
  align-items:start}
.amb-dicho{grid-area:dicho;min-width:0}
.amb-mapa{grid-area:mapa;position:sticky;top:calc(var(--hz-h) + var(--sp-6));
  display:flex;flex-direction:column;gap:var(--sp-4);min-width:0}
.amb-lista{grid-area:lista;min-width:0}

/* ── EL TITULAR ─────────────────────────────────────────────────────────── */
.amb-h{font-size:var(--fs-8);font-weight:600;letter-spacing:var(--ls-tight);
  line-height:var(--lh-tight);color:var(--tx-1);margin:0;text-wrap:balance}
/* La cifra lleva el degradado de marca. Es la firma de la casa —la misma que
   la línea de 3 px del tope de la barra— y no significa nada por sí sola: no
   es un estado ni una verificación, así que no le roba alfabeto a nadie. */
.amb-cifra{font-weight:700;font-variant-numeric:tabular-nums;
  background:var(--grad-marca);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:var(--brand)}

.amb-malla{margin:var(--sp-6) 0 0;font-size:var(--fs-4);line-height:var(--lh-read);
  color:var(--tx-2);max-width:56ch;
  display:flex;align-items:baseline;gap:var(--sp-4);flex-wrap:wrap}
.amb-vinc{font-size:var(--fs-7);font-weight:700;line-height:1;
  font-variant-numeric:tabular-nums;
  background:var(--grad-marca);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:var(--brand)}
.amb-malla b{color:var(--tx-1);font-weight:600}

.amb-p{font-size:var(--fs-4);line-height:var(--lh-read);color:var(--tx-2);
  margin:var(--sp-6) 0 0;max-width:56ch}
.amb-dicho .veredicto{margin-top:var(--sp-7)}

/* ── EL MAPA ────────────────────────────────────────────────────────────── */
.amb-mapa-lienzo{background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-3);padding:var(--sp-5);display:flex;justify-content:center}
.amb-mapa .mapa{width:100%;height:auto;display:block;max-height:56vh}
.amb-mapa .mapa .dep path{fill:var(--n-0);stroke:var(--line);
  stroke-width:.018;vector-effect:non-scaling-stroke}

/* El punto lleno se queda; el hueco se destildó. La distinción es de FORMA y
   no de color: destildar algo no lo pone en rojo, lo saca. */
.amb-mapa .mapa .pt{fill:var(--brand);stroke:var(--n-0);stroke-width:.05;
  cursor:pointer;transition:fill .12s,opacity .12s,r .12s}
.amb-mapa .mapa .pt:hover{r:.24}
.amb-mapa .mapa .pt:focus-visible{outline:none;stroke:var(--tx-1);stroke-width:.09}
.amb-mapa .mapa .pt.fuera{fill:none;stroke:var(--n-4);stroke-width:.07;opacity:.8}
/* Con algo seleccionado: lo alcanzado crece, lo demás se apaga. */
.amb-mapa .mapa .pt.enfocado{r:.28;stroke-width:.07}
.amb-mapa .mapa .pt.apagado{opacity:.16}

.amb-mapa-pie{font-size:var(--fs-2);color:var(--tx-3);text-align:center;
  line-height:var(--lh-ui);display:flex;flex-direction:column;
  align-items:center;gap:var(--sp-3)}
.amb-limpiar{font:inherit;font-size:var(--fs-2);padding:var(--sp-2) var(--sp-5);
  border:1px solid var(--line);background:var(--bg);color:var(--tx-2);
  border-radius:var(--r-1);cursor:pointer}
.amb-limpiar:hover{border-color:var(--brand);color:var(--brand)}

/* ── LA LISTA ───────────────────────────────────────────────────────────── */
.amb-grupo{border:1px solid var(--line);border-radius:var(--r-3);
  margin-bottom:var(--sp-7);overflow:hidden}
.amb-cab{display:flex;align-items:baseline;gap:var(--sp-5);
  padding:var(--sp-5) var(--sp-7);background:var(--surface);
  border-bottom:1px solid var(--line)}
.amb-tit{font-size:var(--fs-1);font-weight:700;letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--tx-2)}
.amb-n{margin-left:auto;font-size:var(--fs-2);color:var(--tx-3);
  font-variant-numeric:tabular-nums}
.amb-vacio{padding:var(--sp-7);font-size:var(--fs-3);color:var(--tx-3)}

/* 🔑 La fila ya NO es una etiqueta que envuelve todo. Lo era, y eso hacía que
   cualquier clic —incluido el del botón de foco— destildara la casilla. Ahora
   la etiqueta envuelve SOLO la casilla, y el resto de la fila puede tener sus
   propios controles. */
.amb-fila{display:flex;align-items:flex-start;gap:var(--sp-5);
  padding:var(--sp-5) var(--sp-7);border-bottom:1px solid var(--line);
  transition:background .1s,opacity .12s}
.amb-fila:last-child{border-bottom:none}
.amb-fila:hover{background:var(--surface)}
.amb-marca{display:flex;align-items:center;padding-top:3px;cursor:pointer;flex:none}
.amb-marca input{width:16px;height:16px;margin:0;accent-color:var(--brand);
  cursor:pointer}
.oculto{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
  clip-path:inset(50%);white-space:nowrap}

/* Destildada: se apaga, NO se tacha ni se pinta de rojo. Sacar una unidad del
   inventario es una decisión normal, no un error. */
.amb-fila.fuera{opacity:.45}
/* Con foco puesto en otra cosa. */
.amb-fila.apagada{opacity:.28}
.amb-fila.enfocada{background:var(--brand-soft);
  box-shadow:inset 3px 0 0 var(--brand)}
.amb-fila.ligada{background:var(--surface);box-shadow:inset 3px 0 0 var(--line-hi)}

.amb-bd{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--sp-3)}

/* 🔑 El nombre es editable SIEMPRE y no detrás de un botón «editar»: el
   encargo dice mínima fricción, y un campo que se ve como texto hasta que se
   lo toca no le pide a nadie que entre en un modo. */
.amb-nombre{width:100%;font:inherit;font-size:var(--fs-4);color:var(--tx-1);
  background:transparent;border:1px solid transparent;border-radius:var(--r-1);
  padding:var(--sp-2) var(--sp-4);margin:calc(var(--sp-2) * -1) calc(var(--sp-4) * -1);
  transition:border-color .1s,background .1s}
.amb-fila:hover .amb-nombre{border-color:var(--line)}
.amb-nombre:focus{outline:none;border-color:var(--brand);background:var(--n-0);
  box-shadow:0 0 0 3px var(--brand-soft)}

.amb-meta{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap;
  font-size:var(--fs-2);color:var(--tx-3);line-height:var(--lh-ui)}
.amb-cod{font-variant-numeric:tabular-nums;letter-spacing:.02em}
.amb-fecha{font-variant-numeric:tabular-nums}
.amb-et{padding:0 var(--sp-4);border:1px solid var(--line);
  border-radius:999px;white-space:nowrap;line-height:18px}
/* Un hueco del registro del OEFA. Punteado y en tinta, nunca en ámbar: es una
   ausencia de dato, no un plazo por vencer. */
.amb-et.sin{border-style:dashed;color:var(--ver-pendiente)}
.amb-et.mio{border-color:var(--brand);color:var(--brand)}

/* El botón de foco: el código de la unidad y el conteo del instrumento. Se ve
   pulsable sin gritar — es una herramienta, no una acción principal. */
.amb-foco{font:inherit;font-size:var(--fs-2);font-variant-numeric:tabular-nums;
  letter-spacing:.02em;padding:0 var(--sp-4);line-height:18px;
  border:1px solid var(--line);border-radius:999px;background:var(--bg);
  color:var(--tx-2);cursor:pointer;white-space:nowrap;
  transition:border-color .1s,color .1s,background .1s}
.amb-foco:hover{border-color:var(--brand);color:var(--brand);
  background:var(--brand-soft)}
.amb-foco:focus-visible{outline:2px solid var(--brand);outline-offset:1px}
.amb-fila.enfocada .amb-foco{border-color:var(--brand);color:var(--brand);
  background:var(--n-0)}
.amb-liga{color:var(--tx-3)}

/* ── EL PIE ─────────────────────────────────────────────────────────────── */
.amb-pie{display:flex;align-items:flex-start;gap:var(--sp-8);flex-wrap:wrap;
  margin-top:var(--sp-9);padding-top:var(--sp-7);
  border-top:1px solid var(--line)}
.amb-pie .rule{flex:1 1 320px;margin:0}
.amb-acc{margin-left:auto;display:flex;gap:var(--sp-4);flex:none}

/* ── TELÉFONO ───────────────────────────────────────────────────────────── */
@media (max-width:820px){
  /* La rejilla se apaga: en flujo de bloque el elemento pegajoso se limita al
     bloque contenedor —que abarca titular, mapa y lista— y así el mapa
     acompaña TODO el recorrido en vez de solo su fila. */
  .amb-cuerpo{display:block}
  .amb-dicho{margin-bottom:var(--sp-7)}
  .amb-h{font-size:var(--fs-7)}

  /* De columna a banda: el mapa a la izquierda, lo que dice a la derecha. Una
     figura de 130 px de alto sigue siendo reconocible y no se come la
     pantalla — el Perú es alto y angosto, así que ocupa ~90 px de ancho. */
  .amb-mapa{position:sticky;top:var(--hz-h);z-index:5;
    flex-direction:row;align-items:center;gap:var(--sp-5);
    background:var(--bg);border-bottom:1px solid var(--line);
    padding:var(--sp-4) 0;margin-bottom:var(--sp-6)}
  .amb-mapa-lienzo{padding:var(--sp-3);flex:none}
  /* 🔴 Alto explícito y ancho automático, NO al revés. Con `width:auto` sobre
     un SVG dentro de un contenedor flex el navegador resuelve 0 y el mapa
     desaparece sin dejar hueco — medido: 0 px de alto. Fijando el alto, el
     `preserveAspectRatio` del propio SVG calcula el ancho. */
  .amb-mapa .mapa{height:132px;width:auto;max-height:none}
  .amb-mapa-pie{text-align:left;align-items:flex-start;flex:1;min-width:0}

  .amb-acc{margin-left:0;width:100%}
  .amb-acc .b{flex:1 1 auto;justify-content:center}
}

/* ══════════════════════════════════════════════════════════════════════════
   LA BARRA EN TELÉFONO — dos controles menos
   ══════════════════════════════════════════════════════════════════════════
   🔑 A 375 px la fila llevaba seis cosas: marca, empresa, módulo, tema,
   engranaje y usuario. wdeza la llamó sobrecargada y tiene razón; lo que
   sobra son justo los dos que él mismo había clasificado como «se tocan
   poco»: el tema es una preferencia y la configuración se entra el día del
   registro. Bajan al menú de usuario, que ya está ahí y no cuesta un píxel.

   Lo que NO se cae sigue sin caerse: en qué empresa estoy, en qué módulo
   estoy, cómo llego a casa y a mi cuenta. */
/* El botón del menú tiene que verse EXACTAMENTE como el enlace de al lado:
   un `<button>` trae su propia tipografía, su borde y su fondo, y si no se los
   quita se nota que uno es un botón y el otro un enlace aunque hagan lo mismo
   de cara al usuario. */
.hz .r .usuario .menu button[role="menuitem"]{
  display:flex;align-items:center;gap:var(--sp-5);width:100%;
  padding:var(--sp-4) var(--sp-5);border:0;border-radius:var(--r-1);
  background:transparent;font:inherit;font-size:var(--fs-3);
  color:var(--tx-2);text-align:left;cursor:pointer}
.hz .r .usuario .menu button[role="menuitem"] svg{width:16px;height:16px;
  flex:none;color:var(--tx-3)}
.hz .r .usuario .menu button[role="menuitem"]:hover{background:var(--brand-soft);
  color:var(--brand)}

.usuario .menu .solo-movil{display:none}
@media (max-width:640px){
  .hz .r > #thm,
  .hz .r > a.ctl[href="/configuracion"]{display:none}
  .usuario .menu a.solo-movil,
  .usuario .menu button.solo-movil{display:flex}
  .usuario .menu .sep.solo-movil{display:block}
}

/* El segundo renglón de cada sociedad en el diálogo de reparto: quién FIRMA
   la matriz de compromisos de esa sociedad. Sangrado y en gris porque
   depende del de arriba — es un matiz del acceso, no un acceso más.
   Ver `32-quien-firma-la-matriz.sql`. */
.socia.socia-firma{margin-left:var(--sp-6);font-size:var(--fs-1);
  color:var(--tx-2)}
.socia.socia-firma .sub2{display:block;color:var(--tx-3)}


/* ══════════════════════════════════════════════════════════════════════════
   LA CAMPANITA — wdeza, 29-ago-2026

   «Cualquier aviso debe aparecer en el ícono de notificaciones a la derecha en
   el menú superior… el criterio aplica para todas las vistas del módulo.»

   🔴 EN REPOSO NO LLEVA PUNTO Y NO DESAPARECE. La campana muda ES la respuesta
   «no hay nada»: esconderla dejaría a la persona sin forma de comprobarlo, que
   es justamente lo que hacía un botón «Novedades 0».
   ========================================================================== */
.ctl.campana{position:relative}
.ctl.campana.hay{color:var(--st-porvencer)}
/* El contador no toma el rojo de «vencida»: una novedad del registro público
   NO está verificada y no dispara ningún plazo. Ámbar es «mírame», rojo sería
   «llegaste tarde», y son cosas distintas. */
.campana-n{position:absolute;top:2px;right:0;min-width:15px;height:15px;
  padding:0 4px;border-radius:var(--r-1);background:var(--st-porvencer);
  color:#fff;font-size:9.5px;font-weight:700;font-style:normal;line-height:15px;
  text-align:center;font-variant-numeric:tabular-nums;
  box-shadow:0 0 0 1.5px var(--shell-bg,var(--n-0))}


/* ══════════════════════════════════════════════════════════════════════════
   EL SELECTOR DE SOCIEDADES — opciones del mismo tamaño

   wdeza, 29-ago-2026: «El selector de sociedades tiene una lista deforme…
   homogeniza el tamaño de las opciones de la lista.»

   Eran dos causas y ya se fue la primera —el renglón de «sin papeles», que
   sólo llevaba una de las tres—. La que queda es que un nombre largo envuelve
   a dos líneas y otro no: «COMPAÑIA TRANSMISORA NORPERUANA S.A.C» mide 38
   caracteres y «CONELSUR LT S.A.C.» 18.

   🔑 Se corrige con UNA LÍNEA Y PUNTOS SUSPENSIVOS, no fijando un alto: el
   alto fijo deja la opción corta con un hueco y sigue viéndose despareja. Y el
   nombre completo no se pierde — va en el `title` y en la barra, que es donde
   se lee cuál está activa.
   ========================================================================== */
.hz .conmuta .menu .quien b,
.hz .emp.conmutable .menu .soc .quien b{
  display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.hz .conmuta .menu .soc,
.hz .emp.conmutable .menu .soc{align-items:center}


/* ══════════════════════════════════════════════════════════════════════════
   🔴 EL PISO DE TAMAÑO DE UN ÍCONO — la red que faltaba

   wdeza, 30-ago-2026, sobre una pantalla con dos logotipos de 600 px donde
   debía haber dos íconos de 15: «No entiendo qué hiciste, pero claramente no
   hiciste caso a mi pedido.»

   La causa no fue el diseño: fue que agregué reglas a `panel.css` y **no subí
   su `?v=`**. Su navegador siguió con la hoja vieja en caché, así que los
   `<svg>` nuevos se quedaron sin ninguna regla que los midiera — y un `<svg>`
   sin `width` ni `height` declarados no falla: ocupa TODO lo que le den.

   Mis bancos no lo veían porque cada corrida de Playwright arranca con la
   caché fría y siempre bajaba la hoja nueva. **Un banco que nunca reusa la
   caché no puede ver un fallo de caché.**

   Esta regla es la red: el juego de íconos del módulo emite `class="ic"`
   (`_iconos.html`), así que con un tamaño por omisión el peor caso de una
   versión olvidada pasa de «un logotipo tapando la tarjeta» a «un ícono un
   poco más chico de la cuenta». Cualquier regla posterior la pisa sin
   esfuerzo: es un piso, no una imposición.
   ========================================================================== */
.ic{width:16px;height:16px;flex:none}


/* ── CONFIGURACIÓN › CLASES DE COMPROMISO ─────────────────────────────────
   El vocabulario de la matriz, configurable por el cliente (migración `40`).
   🔴 Los ocho tonos salen de `categoria.css`, que es el arco de CATEGORÍA.
   Nunca los cuatro `--st-*`: ésos son del plazo, y una clase no es un plazo. */
/* ⚠️ 4px y no `--r-1`: sobre una caja de 18px, 10px de radio da un CÍRCULO, y
   el círculo en este sistema es del avatar y de nada más. Una muestra de color
   es una muestra, no una persona. */
.cl-muestra{display:inline-block;width:18px;height:18px;border-radius:4px;
  background:var(--n-3);border:0;padding:0;vertical-align:-3px;
  margin-right:var(--sp-3)}
button.cl-muestra{cursor:pointer}
button.cl-muestra.on{box-shadow:0 0 0 2px var(--n-0),0 0 0 4px var(--tx-1)}
.cl-muestra.t1{background:var(--t1)} .cl-muestra.t2{background:var(--t2)}
.cl-muestra.t3{background:var(--t3)} .cl-muestra.t4{background:var(--t4)}
.cl-muestra.t5{background:var(--t5)} .cl-muestra.t6{background:var(--t6)}
.cl-muestra.t7{background:var(--t7)} .cl-muestra.t8{background:var(--t8)}
.cl-tonos{display:flex;gap:var(--sp-3);margin:calc(-1 * var(--sp-3)) 0 var(--sp-5)}
.cfg-nota{font-style:normal;font-size:var(--fs-2);color:var(--tx-3)}
/* ⚠️ Vive en `olivia.css` y no en `ambiental.css`: la pantalla de
   configuración no carga la hoja del módulo, y un chip definido allí habría
   salido sin fondo ni borde — el mismo defecto que ya costó el sello de la
   malla, que usaba un token de una hoja que su pantalla no cargaba. */
.cfg-apagada{display:inline-block;font-size:var(--fs-1);
  letter-spacing:var(--ls-caps);text-transform:uppercase;font-weight:600;
  padding:1px var(--sp-3);border-radius:var(--r-1);
  background:var(--n-2);color:var(--tx-3);border:1px solid var(--n-3)}
.cfg-socs{margin-bottom:var(--sp-5)}
/* Una clase apagada se ve apagada y NO se esconde: sigue en la tabla porque
   los compromisos que la usan siguen mostrándola. */
tr.apagada{opacity:.6}
td.der{text-align:right;white-space:nowrap}
td.der .b{margin-left:var(--sp-2)}
td.der form.en-linea{display:inline}

/* ── CONFIGURACIÓN › CLASIFICACIONES ──────────────────────────────────────
   Una caja por clasificación, con su cabecera y su tabla de tipos. La
   pantalla se organiza POR OBJETO porque ésa es la regla que pidió wdeza —
   «cada objeto tiene distintas naturalezas, no deberían poder compartir
   clasificación»— y la estructura de la pantalla la dice sin explicarla. */
.clasif{border:1px solid var(--n-3);border-radius:var(--r-1);
  margin-bottom:var(--sp-5);overflow:hidden}
.clasif.apagada{opacity:.62}
.clasif-hd{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap;
  padding:var(--sp-4) var(--sp-5);background:var(--n-1);
  border-bottom:1px solid var(--n-3)}
.clasif-hd b{font-size:var(--fs-4)}
.clasif-hd code{font-size:var(--fs-2);color:var(--tx-3)}
.clasif-acc{margin-left:auto;display:flex;gap:var(--sp-3);align-items:center}
.clasif-acc form.en-linea{display:inline}
.clasif .tabla{margin:0}
.hsec .q .b{vertical-align:middle}
