/* ════════════════════════════════════════════════════════════════
   El sistema de diseño de Horizun.

   Reescrito el 7-ago con la identidad real de la marca (navy #13213D,
   azul de acción #1E56C9, Inter servida desde esta misma carpeta) y una
   regla de fondo: la plataforma no muestra MÁS información — la muestra
   MEJOR. Jerarquía por tamaño, peso, espacio y color con significado;
   no por negrita y tarjetas.

   Tres decisiones que gobiernan todo:

   1 · EL COLOR COMUNICA ESTADO, NO DECORA. El azul es la acción; el
       verde/ámbar/rojo son estados; el morado queda RESERVADO para lo
       generado o sugerido por IA. Nada más se pinta.

   2 · SEPARAR CON BORDE Y SUPERFICIE, NO CON SOMBRA. Las sombras
       quedan para lo que de verdad flota: menús, drawers, buscador.

   3 · LOS TOKENS GOBIERNAN. Cambiar un valor aquí cambia la
       plataforma entera. Un color escrito a mano en una pantalla es
       deuda, no estilo.

   La responsividad de la versión anterior se conserva completa: la app
   de campo es ESTA app en un teléfono, no otra.
   ════════════════════════════════════════════════════════════════ */

/* ── Tipografía de marca, servida local ─────────────────────────
   La plataforma tiene que funcionar en una obra sin señal: nada se pide
   a un CDN. Inter variable cubre 100–900 en un archivo. */
@font-face{
  font-family:'Inter var';
  src:url('fonts/InterVariable.woff2') format('woff2');
  font-weight:100 900; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'Plex Mono';
  src:url('fonts/PlexMono-400.woff2') format('woff2');
  font-weight:400; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'Plex Mono';
  src:url('fonts/PlexMono-500.woff2') format('woff2');
  font-weight:500; font-style:normal; font-display:swap;
}

:root{
  /* ── Color ─────────────────────────────────────────────────── */
  --paper:#F5F7FA; --card:#FFFFFF; --card-2:#F8FAFC; --panel:#FFFFFF;
  --ink:#172033; --muted:#667085; --faint:#8A94A6;
  --linea:#E2E7EE; --linea-fuerte:#CBD4DF; --divisor:#EDF0F4;
  /* El filo de las cajas: el navy de la marca, a un pelo de grosor. Es
     lo que separa un recuadro de otro sin usar sombras ni fondos. */
  --linea-caja:#13213D;
  --acc:#1E56C9; --acc-soft:#E8EFFC; --acc-line:#B7CCF3; --acc-hover:#1748B5;
  --ok:#177A4C; --ok-soft:#E5F3EB; --ok-line:#A6D5BB;
  --warn:#96570A; --warn-soft:#FBF1DC; --warn-line:#E3BE7E;
  --crit:#B82942; --crit-soft:#FBE9EC; --crit-line:#E5A5B0;
  --ia:#6D34C4; --ia-soft:#F1EBFB; --ia-line:#CBB2EE;
  --neu-soft:#EEF1F5;
  /* La marca: navy del sidebar y sus derivados. */
  --nav:#13213D; --nav-2:#1B2C4F; --nav-3:#22355C;
  --nav-ink:#B9C3D6; --nav-faint:#75839F; --nav-linea:#24335A;
  --nav-acc:#4C7DE8;

  /* ── Color por área del menú ───────────────────────────────────
     Cada bloque del producto tiene su color en el menú, para saber
     dónde se está parado sin leer. Es orientación, NO estado: vive
     solo en el sidebar navy y nunca entra al contenido, donde el
     color sigue significando crítico / bien / advertencia.
     El morado no aparece: está reservado para lo que calcule un
     modelo, y aquí no hay ninguno. */
  --area-inicio:#5B8DEF;
  --area-crm:#2FB3A4;
  --area-erp:#E0A33E;
  --area-tecnico:#56BEDE;
  --area-academia:#5FB868;
  --area-admin:#94A4C0;
  --area-portal:#E08A6B;

  /* Tokens con alias viejos: había estilos en línea que los usaban y un
     token que no existe falla en silencio. Se declaran para que nada
     quede sin borde mientras se terminan de barrer. */
  --line:var(--linea); --line-strong:var(--linea-fuerte);
  --accent:var(--acc); --fondo2:var(--card-2);

  /* El crítico que carga peso: el badge «N críticas» y nada más. Y el
     amarillo de urgencia media, que solo existe en la semántica de
     urgencias — no es un color para pintar pantallas. */
  --crit-fuerte:#8F1D2C;
  --med:#B8860B; --med-soft:#FAF3DE;

  /* ── Estados sólidos (9-ago, brief del ERP) ─────────────────────
     Un ESTADO lleva fondo oscuro saturado y texto blanco — se
     reconoce desde el otro lado de la sala y pasa WCAG AA. Los tonos
     suaves quedan para CONTENEDORES (avisos, celdas), nunca para el
     badge. La metadata («5 etapas», un código) sigue clara. */
  --st-crit:#B42336; --st-ok:#18794E; --st-warn:#9A5B08;
  --st-info:#2459C4; --st-neu:#526174;

  /* ── Elevación (mínima: el borde separa, la sombra flota) ──── */
  --sombra:0 1px 2px rgba(23,32,51,.05);
  --sombra-md:0 2px 6px rgba(23,32,51,.06), 0 8px 20px rgba(23,32,51,.06);
  --sombra-lg:0 12px 36px rgba(23,32,51,.16);
  /* La de las tarjetas del tablero: profundidad que casi no se ve. */
  --sombra-suave:0 8px 22px rgba(15,35,70,.07);
  --sombra-suave-hover:0 10px 26px rgba(15,35,70,.10);

  /* ── Forma y ritmo ─────────────────────────────────────────── */
  --r-sm:8px; --r:10px; --r-lg:12px; --r-xl:14px; --r-full:999px;
  --gap:16px;
  --ancho:min(1560px, 100%);
  --menu:260px;
  /* La altura del encabezado se mide, no se declara: deja de ser una
     sola fila en pantallas angostas y hay cuatro cosas colgadas de ella. */
  --h:56px;

  /* ── Tipografía ────────────────────────────────────────────── */
  --fh:'Inter var','Segoe UI Variable Text','Segoe UI',-apple-system,'Helvetica Neue',Arial,sans-serif;
  --fm:'Plex Mono','Cascadia Code',ui-monospace,'SF Mono',Consolas,monospace;
}

@media (prefers-color-scheme:dark){:root{
  --paper:#0C111B; --card:#151C2A; --card-2:#111826; --panel:#151C2A;
  --ink:#E7ECF4; --muted:#98A4B8; --faint:#68758C;
  --linea:#232D40; --linea-fuerte:#324159; --divisor:#1B2434;
  /* En oscuro el navy desaparece contra el fondo: el filo se aclara. */
  --linea-caja:#3E4E6E;
  --acc:#5B92F5; --acc-soft:#16233E; --acc-line:#2E4C82; --acc-hover:#7CA9FF;
  --ok:#46C287; --ok-soft:#10271C; --ok-line:#2C5A42;
  --warn:#F0B45C; --warn-soft:#2A2110; --warn-line:#6B5017;
  --crit:#F0788C; --crit-soft:#2C141A; --crit-line:#5E2831;
  --ia:#B79AE8; --ia-soft:#1E1533; --ia-line:#463270;
  --neu-soft:#1A2333;
  --nav:#0D1526; --nav-2:#16223C; --nav-3:#1D2C4C;
  --nav-ink:#AEB9CD; --nav-faint:#66748F; --nav-linea:#1D2841;
  --nav-acc:#5B92F5;
  --crit-fuerte:#C24357;
  --med:#DDB44A; --med-soft:#2A2410;
  --st-crit:#C13247; --st-ok:#1F8A5C; --st-warn:#AD6A10;
  --st-info:#3568D4; --st-neu:#5D6D82;
  --sombra:0 1px 2px rgba(0,0,0,.32);
  --sombra-md:0 2px 6px rgba(0,0,0,.34), 0 8px 20px rgba(0,0,0,.30);
  --sombra-lg:0 12px 36px rgba(0,0,0,.55);
  --sombra-suave:0 8px 22px rgba(0,0,0,.32);
  --sombra-suave-hover:0 10px 26px rgba(0,0,0,.38);
}}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--paper); color:var(--ink);
  font-family:var(--fh); font-size:14px; line-height:1.5;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
:focus-visible{outline:2px solid var(--acc); outline-offset:2px; border-radius:4px}

/* Los iconos son SVG de trazo (subconjunto de Lucide, vendido adentro):
   heredan el color del texto, que es como el color deja de decorar. */
.ic{width:18px; height:18px; flex-shrink:0; vertical-align:-3.5px}
.ic-16{width:16px; height:16px; vertical-align:-3px}
.ic-20{width:20px; height:20px; vertical-align:-4px}

/* ════════ Barra superior ════════
   Navy, del mismo azul del sidebar: la aplicación queda enmarcada por
   la marca en dos lados y el contenido claro respira dentro. Lleva el
   contexto (proyecto), el buscador global, la campana y quién opera. */

header{
  background:var(--nav); color:#fff; min-height:64px; padding:0 20px;
  display:flex; align-items:center; gap:12px;
  position:sticky; top:0; z-index:40;
  border-bottom:1px solid var(--nav-linea);
}
/* La marca vive en el sidebar; en el encabezado solo queda en angosto,
   cuando el sidebar está oculto. Sobre navy va el sello blanco. */
header .mk{display:none; width:26px; height:26px; flex-shrink:0}
header .mk img{width:100%; height:100%; display:block}
header b{display:none}
header .sp{display:none}

/* El contexto: en qué proyecto estoy parado — y el selector para
   cambiarlo, porque una constructora lleva varios a la vez.
   Se dimensiona a su contenido: el nombre del proyecto tiene que
   leerse ENTERO sin abrir el desplegable. */
#proy{
  font-family:var(--fh); font-size:12.5px; color:#fff; font-weight:600;
  background:var(--nav-2); border:1px solid var(--nav-linea);
  border-radius:var(--r-sm); padding:6px 10px;
  /* Se dimensiona al proyecto de nombre más largo y NO se encoge: en un
     flex, un select cede espacio antes que el buscador y el nombre
     queda cortado justo cuando hay que saber en qué obra se está. */
  width:auto; max-width:none; flex:0 0 auto;
  cursor:pointer; transition:border-color .12s;
}
#proy:hover:not(:disabled){border-color:var(--nav-acc)}
#proy:disabled{cursor:default; opacity:1; color:var(--nav-ink); background:transparent; border-color:transparent}
#proy option{background:var(--nav); color:#fff}

/* ── El perfil: avatar + nombre + menú ──────────────────────────
   La foto es la de la persona (la sube ella); sin foto, iniciales.
   El botón entero abre el menú — no un caret de 12 px. */
#perfil{
  margin-left:auto; display:flex; align-items:center; gap:9px;
  background:transparent; border:1px solid transparent; border-radius:var(--r-sm);
  padding:5px 8px 5px 5px; cursor:pointer; font-family:inherit; color:#fff;
  transition:background .15s, border-color .15s; max-width:min(38vw, 240px);
}
#perfil:hover{background:var(--nav-2); border-color:var(--nav-linea)}
#perfil .perfil-chev{flex-shrink:0; color:#fff}
#quien{
  font-size:12.8px; color:#fff; font-weight:600;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0;
}
#menu-perfil{
  position:fixed; top:calc(var(--h) + 6px); right:14px; z-index:55;
  width:min(280px, calc(100vw - 28px));
  background:var(--card); border:1px solid var(--linea); border-radius:var(--r-lg);
  box-shadow:var(--sombra-md); padding:6px; display:none;
}
#menu-perfil.on{display:block}
.mp-cab{
  display:flex; align-items:center; gap:11px; padding:10px 10px 12px;
  border-bottom:1px solid var(--divisor); margin-bottom:6px;
}
.mp-datos{min-width:0}
.mp-datos b{font-size:13.5px; display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.mp-datos .tsub{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.mp-item{
  display:block; width:100%; text-align:left; background:transparent; border:0;
  border-radius:var(--r-sm); padding:9px 10px; font-size:13px; color:var(--ink);
  cursor:pointer; font-family:inherit; transition:background .15s;
}
.mp-item:hover{background:var(--card-2)}
.mp-salir{color:var(--crit)}
/* Toda la letra de la barra va en blanco: el «Ver como», los
   selectores, el nombre de quien opera y los iconos. */
header .rl{
  font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:#fff; margin-right:4px; font-weight:600;
}
header select{
  background:var(--nav-2); color:#fff; border:1px solid var(--nav-linea);
  border-radius:var(--r-sm); padding:6px 10px; font-size:12.5px; font-family:inherit;
  max-width:210px;
}
header select:hover{border-color:var(--nav-acc)}
header select option{background:var(--nav); color:#fff}
header select#usuario{flex:0 1 auto; min-width:0}

/* Los botones de icono de la barra (campana, densidad) sobre navy. */
header .btn.gh{color:#fff}
header .btn.gh:hover{background:var(--nav-2); color:#fff}

.menu-btn{
  display:none; background:transparent; border:1px solid var(--nav-linea); color:#fff;
  border-radius:var(--r-sm); width:36px; height:34px;
  cursor:pointer; flex-shrink:0; align-items:center; justify-content:center;
}
.menu-btn:hover{background:var(--nav-2)}

/* ════════ Estructura ════════ */

.app{display:flex; min-height:calc(100vh - var(--h))}
.sidebar{
  width:var(--menu); background:var(--nav); color:var(--nav-ink);
  padding:0 0 30px; flex-shrink:0;
  position:sticky; top:var(--h); height:calc(100vh - var(--h)); overflow-y:auto;
  scrollbar-width:thin; scrollbar-color:var(--nav-3) transparent;
}
main{
  flex:1; min-width:0;
  width:var(--ancho); margin:0 auto;
  padding:clamp(16px, 2.5vw, 30px) clamp(14px, 2.5vw, 32px) 80px;
}

/* La marca, arriba del sidebar: el sello y el nombre compuesto en la
   tipografía de la casa. El wordmark es texto a propósito — nítido a
   cualquier tamaño y del color que el tema mande. */
.marca{
  display:flex; align-items:center; gap:10px; padding:19px 20px 17px;
  border-bottom:1px solid var(--nav-linea); margin-bottom:8px;
}
.marca img{width:30px; height:30px; display:block}
.marca .wm{
  color:#fff; font-size:15.5px; font-weight:650; letter-spacing:.14em;
}

/* Cada grupo lleva su color de área (`--area`, que pone el menú al
   armarse). Si algún grupo no lo declara, cae al azul de la marca.

   TODO EL TEXTO DEL MENÚ VA EN BLANCO. La jerarquía la hacen el tamaño,
   la caja alta y el espacio — no un gris más apagado: sobre navy, un
   gris que se lee bien de día desaparece en una pantalla con brillo. */
.navsec{
  font-size:10.5px; letter-spacing:.07em; text-transform:uppercase; color:#fff;
  font-weight:650; padding:20px 20px 7px;
  display:flex; align-items:center; gap:8px;
}
/* La marca del área: una barra corta del color del bloque. */
.navsec::before{
  content:''; width:3px; height:13px; border-radius:2px; flex-shrink:0;
  background:var(--area, var(--nav-acc));
}
/* El grupo colapsable del mapa completo (administración): la cabecera
   es un control, con su contador y su flecha. */
/* Una línea blanca tenue arriba de cada grupo: separa un bloque del
   siguiente sin meter otro color al sidebar. Va en TODOS los menús —el
   mapa completo y el de los roles operativos—, y también sobre el
   primero, que es el que lo separa de «Prioridades». */
.navsec{margin-top:8px; border-top:1px solid rgba(255,255,255,.13)}
.navsec.plegable{
  cursor:pointer; user-select:none;
  padding:19px 20px 8px; transition:color .12s;
}
.navsec.plegable:hover{color:#fff}
.navsec .chev{
  width:13px; height:13px; flex-shrink:0; margin-left:auto;
  transition:transform .15s; transform:rotate(-90deg);
}
.navsec.abierto .chev{transform:none}
/* La opción es una cápsula con margen, no una franja de borde a borde:
   la activa se marca con superficie más clara y el filo de su área. */
.navitem{
  margin:1px 10px; padding:8px 10px 8px 9px; font-size:13px; cursor:pointer;
  display:flex; align-items:center; gap:11px; border-radius:9px;
  transition:background .15s;
  color:#fff;
  border-left:3px solid transparent;
}
.navitem:hover{background:var(--nav-2)}
.navitem.active{
  background:var(--nav-3); font-weight:600;
  border-left-color:var(--area, var(--nav-acc));
}
.navitem .ni{
  width:20px; display:flex; align-items:center; justify-content:center; flex-shrink:0;
  color:#fff;
}
.navitem:hover .ni,.navitem.active .ni{color:var(--area, var(--nav-acc))}
.navitem .ni svg{width:17px; height:17px}
.navfoot{
  font-size:11px; color:#fff; opacity:.8; padding:16px 18px 0; line-height:1.55;
  border-top:1px solid var(--nav-linea); margin-top:14px;
}

/* ════════ Encabezado de pantalla ════════ */

h1{font-size:clamp(21px, 2.6vw, 29px); margin:0 0 5px; letter-spacing:-.018em; font-weight:700}
.q{color:var(--muted); font-size:14px; margin-bottom:24px; max-width:72ch}

/* ════════ Indicadores ════════
   Sin franja de color decorativa: valor grande, etiqueta pequeña y un
   punto de estado solo cuando el estado existe. El «?» de auditoría se
   queda — cada número dice de dónde sale, y eso es del producto. */

.kpis{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));
  gap:var(--gap); margin-bottom:22px;
}
.kpi{
  background:var(--card); border:1px solid var(--linea-caja); border-radius:var(--r);
  padding:14px 16px; position:relative;
}
.kl{
  font-size:10.5px; letter-spacing:.07em; text-transform:uppercase;
  color:var(--muted); font-weight:600;
  display:flex; align-items:center; gap:6px;
}
/* El punto de estado, pegado a la etiqueta. Solo existe si hay estado. */
.kpi.ok .kl::before,.kpi.warn .kl::before,.kpi.crit .kl::before{
  content:''; width:7px; height:7px; border-radius:var(--r-full); flex-shrink:0;
}
.kpi.ok .kl::before{background:var(--ok)}
.kpi.warn .kl::before{background:var(--warn)}
.kpi.crit .kl::before{background:var(--crit)}
.kpi.crit .kv{color:var(--crit)}
.kv{
  font-size:clamp(22px, 2.2vw, 27px); font-weight:700; margin:7px 0 3px;
  font-variant-numeric:tabular-nums; letter-spacing:-.02em; line-height:1.1;
}
.kd{font-size:11.8px; color:var(--muted); line-height:1.45}

.kpi[data-expl]{cursor:pointer; transition:border-color .12s, box-shadow .12s}
.kpi[data-expl]:hover{border-color:var(--acc-line); box-shadow:var(--sombra)}
.kpi[data-expl]::after{
  content:'?'; position:absolute; top:11px; right:12px;
  width:17px; height:17px; border-radius:var(--r-full);
  background:transparent; border:1px solid var(--linea-fuerte);
  color:var(--faint); font-size:10.5px; font-weight:600;
  display:grid; place-items:center;
}
.kpi[data-expl]:hover::after{background:var(--acc); border-color:var(--acc); color:#fff}

.bar{height:5px; background:var(--divisor); border-radius:var(--r-full); margin-top:9px; overflow:hidden}
.bar i{display:block; height:100%; border-radius:var(--r-full); background:var(--acc)}

/* ════════ Paneles ════════
   Planos: borde 1px, cabecera sin degradado, título que no grita. La
   sombra no separa contenido pegado al fondo. */

.panel{
  background:var(--panel); border:1px solid var(--linea-caja); border-radius:var(--r);
  margin-bottom:var(--gap); overflow:hidden;
}
.panel-h{
  padding:12px 16px; border-bottom:1px solid var(--divisor);
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
}
.panel-h h3{margin:0; font-size:13.5px; font-weight:600; letter-spacing:-.005em}
.panel-b{padding:16px}

/* ════════ Tablas ════════ */

.tabla-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch}
table{width:100%; border-collapse:collapse; min-width:520px}
.panel-b>.tabla-scroll>table{min-width:0}
th{
  text-align:left; font-size:10px; letter-spacing:.07em; text-transform:uppercase;
  color:var(--muted); padding:8px 12px; border-bottom:1px solid var(--linea);
  font-weight:600; white-space:nowrap; background:var(--card-2);
}
td{padding:10px 12px; border-bottom:1px solid var(--divisor); vertical-align:top; font-size:13.2px}
tbody tr:last-child td{border-bottom:0}
tbody tr{transition:background .1s}
tbody tr:hover{background:var(--card-2)}
.num{text-align:right; font-variant-numeric:tabular-nums}
.tprim{font-weight:600; line-height:1.35}
/* `anywhere`: un NIT, un correo o un código largo sin espacios se parte
   antes que desbordar la pantalla — a cualquier ancho. */
.tsub{font-size:11.8px; color:var(--muted); margin-top:2px; line-height:1.45; overflow-wrap:anywhere}

/* Densidad de las tablas. La cómoda es la de siempre; la compacta es
   para revisar listas largas en escritorio sin que la pantalla se
   vuelva un ascensor. Se cambia con el botón del encabezado y se
   recuerda. En teléfono no aplica: ahí las tablas ya se reacomodan
   solas y quitarles aire las volvería intocables. */
body.compacta td{padding:6px 10px; font-size:12.6px}
body.compacta th{padding:5px 10px}
body.compacta .tsub{margin-top:1px}
@media (max-width:767px){
  #densidad{display:none !important}
  body.compacta td{padding:10px 12px; font-size:13.2px}
  body.compacta th{padding:8px 12px}
}

/* ════════ Piezas ════════ */

/* El badge de estado: un solo sistema para toda la plataforma. Radio
   contenido —no cápsula—, punto semántico, y el texto dice el estado
   (el color solo lo refuerza: accesibilidad). */
/* La regla del sistema (brief del ERP, 9-ago): ESTADO = fondo sólido
   con texto blanco; METADATA = fondo claro. Un «Vencido» se reconoce
   desde lejos; un «5 etapas» no compite con él. El punto semántico se
   vuelve blanco translúcido sobre el sólido. */
.pill{
  display:inline-flex; align-items:center; gap:6px;
  padding:2px 9px; border-radius:6px;
  font-size:11px; font-weight:600; white-space:nowrap; line-height:1.6;
}
.pill::before{content:''; width:6px; height:6px; border-radius:var(--r-full); flex-shrink:0}
.p-ok{background:var(--st-ok); color:#fff}
.p-warn{background:var(--st-warn); color:#fff}
.p-crit{background:var(--st-crit); color:#fff}
.p-acc{background:var(--st-info); color:#fff}
.p-gris{background:var(--st-neu); color:#fff}
.p-ok::before,.p-warn::before,.p-crit::before,.p-acc::before,.p-gris::before{
  background:rgba(255,255,255,.75);
}
/* La metadata no es un estado: sigue clara y callada. */
.p-neu{background:var(--neu-soft); color:var(--muted); font-weight:550}
.p-neu::before{background:var(--faint)}
.p-ia{background:var(--ia-soft); color:var(--ia)} .p-ia::before{background:var(--ia)}
/* Una pill que es solo un número (contador) o un código no lleva punto. */
.pill.n::before,.pill.mono::before{display:none}
.pill.mono{font-family:var(--fm); font-size:10.5px; font-weight:500}

.btn{
  background:var(--acc); color:#fff; border:1px solid transparent; border-radius:var(--r-sm);
  padding:7px 14px; font-size:12.8px; font-weight:550; cursor:pointer;
  font-family:inherit; line-height:1.4; transition:background .12s;
  white-space:nowrap; display:inline-flex; align-items:center; gap:7px; justify-content:center;
}
.btn:hover{background:var(--acc-hover)}
.btn:active{transform:translateY(1px)}
.btn.sec{background:var(--card); color:var(--ink); border-color:var(--linea-fuerte)}
.btn.sec:hover{background:var(--card-2); border-color:var(--faint)}
.btn.gh{background:transparent; color:var(--acc); border-color:transparent; padding:6px 8px}
.btn.gh:hover{background:var(--acc-soft)}
.btn:disabled{opacity:.45; cursor:not-allowed}

/* El control segmentado: elegir UNA vista entre pocas. Es el botón
   secundario partido en opciones — la elegida se marca con el azul de
   acción y las demás se quedan calladas. Para filtros y ventanas de
   vista, no para acciones que cambian datos. */
.seg{
  display:inline-flex; border:1px solid var(--linea-fuerte);
  border-radius:var(--r-sm); overflow:hidden; background:var(--card);
}
.seg button{
  background:transparent; border:0; border-left:1px solid var(--divisor);
  padding:5px 11px; font-size:12px; font-weight:550; color:var(--muted);
  cursor:pointer; font-family:inherit; white-space:nowrap; line-height:1.4;
}
.seg button:first-child{border-left:0}
.seg button:hover{color:var(--ink); background:var(--card-2)}
.seg button.on{background:var(--acc); color:#fff}

/* El aviso: precisión, no superficie pintada. Borde izquierdo semántico
   sobre fondo de tarjeta — un bloque rojo entero grita más de lo que
   informa. */
.aviso{
  border-radius:var(--r-sm); padding:12px 15px; margin-bottom:var(--gap);
  font-size:13px; line-height:1.6; display:flex; gap:12px; align-items:flex-start;
  background:var(--card); border:1px solid var(--linea);
  border-left-width:3px; border-left-color:var(--linea-fuerte);
}
.aviso>div:first-child{font-size:16px; line-height:1.3; flex-shrink:0}
.aviso.crit{border-left-color:var(--crit); background:var(--card)}
.aviso.crit>div:first-child{color:var(--crit)}
.aviso.warn{border-left-color:var(--warn)}
.aviso.warn>div:first-child{color:var(--warn)}
.aviso.ok{border-left-color:var(--ok)}
.aviso.ok>div:first-child{color:var(--ok)}
.aviso b{display:block; margin-bottom:2px; font-size:13.3px; font-weight:600}

/* La nota morada del prototipo, ahora en su sitio: explicación en voz
   baja. No compite con el contenido. */
.nota{
  font-size:12.3px; color:var(--muted); line-height:1.65;
  border-left:2px solid var(--acc-line); padding:8px 14px;
  margin-top:14px;
}
.nota b{color:var(--ink); font-weight:600}
.mono{font-family:var(--fm); font-size:11.5px; color:var(--faint)}
/* La miniatura de una evidencia real: pequeña, con borde, clicable a
   futuro. La evidencia sin bytes (la del ejemplo) no la muestra. */
.mini-foto{
  width:44px; height:44px; object-fit:cover; border-radius:6px;
  border:1px solid var(--linea-fuerte); flex-shrink:0; background:var(--card-2);
}
.fila{display:flex; gap:9px; align-items:center; flex-wrap:wrap}
.vacio{text-align:center; padding:40px 22px; color:var(--muted); font-size:13.3px}
/* `minmax(0,1fr)` y no `1fr`: una pista `1fr` se puede estirar hasta el
   ancho MINIMO de su contenido, y basta un `width:44%` dentro de una
   tabla —cuyo bloque contenedor queda indefinido— para que el navegador
   la resuelva enorme. Con eso la Ficha del proyecto hacia scrollear la
   pagina entera a 768 px: 1445 px de cuerpo sobre 753 de pantalla. */
.row2{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:var(--gap)}

input[type=number],input[type=text],input[type=password],select,textarea{
  background:var(--card); border:1px solid var(--linea-fuerte); border-radius:var(--r-sm);
  padding:7px 11px; font-size:13px; color:var(--ink); font-family:inherit; width:130px;
  transition:border-color .12s, box-shadow .12s;
}
input:focus,select:focus,textarea:focus{
  border-color:var(--acc); box-shadow:0 0 0 3px var(--acc-soft); outline:none;
}
input::placeholder,textarea::placeholder{color:var(--faint)}
label{font-size:11.5px; color:var(--muted); font-weight:600}
a{color:var(--acc)}

/* ════════ Esqueleto de carga ════════
   Mientras la pantalla pide sus datos no se escribe «Cargando…»: se
   dibuja la forma de lo que viene, sin parpadeo. */
.skel{display:grid; gap:var(--gap)}
.skel i{
  display:block; border-radius:var(--r); background:var(--card);
  border:1px solid var(--linea); position:relative; overflow:hidden;
}
.skel i::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, var(--card-2), transparent);
  animation:skel 1.2s infinite;
}
@keyframes skel{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
.skel .s-kpis{height:88px}
.skel .s-panel{height:220px}

/* ════════ El toast ════════
   Confirmación breve de una acción que salió bien. Lo que falla ya
   tiene su aviso con la regla; esto es el «hecho» que faltaba. */
#toast{
  position:fixed; bottom:22px; left:50%; transform:translate(-50%, 8px);
  background:var(--nav); color:#fff; font-size:12.8px; font-weight:550;
  padding:9px 16px; border-radius:var(--r-sm); box-shadow:var(--sombra-lg);
  opacity:0; pointer-events:none; transition:opacity .18s, transform .18s;
  z-index:70; display:flex; align-items:center; gap:8px; max-width:min(480px, 90vw);
}
#toast.on{opacity:1; transform:translate(-50%, 0)}
#toast .ic{color:var(--ok)}

/* ════════ La cadena de pasos ════════ */

.cadena{display:flex; gap:6px; overflow-x:auto; padding-bottom:4px}
.cd{
  flex:1; min-width:104px; display:flex; flex-direction:column; align-items:center; gap:6px;
  text-align:center; position:relative; padding-top:2px;
}
.cd::after{
  content:''; position:absolute; top:14px; left:calc(50% + 18px); right:calc(-50% + 18px);
  height:2px; background:var(--linea);
}
.cd:last-child::after{display:none}
.cd-ok::after{background:var(--ok)}
.cd-n{
  width:28px; height:28px; border-radius:var(--r-full); display:grid; place-items:center;
  font-weight:650; font-size:12px; background:var(--card-2); color:var(--faint);
  border:1px solid var(--linea-fuerte); position:relative; z-index:1;
}
.cd-ok .cd-n{background:var(--ok); color:#fff; border-color:var(--ok)}
.cd-hoy .cd-n{background:var(--acc); color:#fff; border-color:var(--acc)}
.cd-t{font-size:10.5px; line-height:1.35; color:var(--faint)}
.cd-ok .cd-t{color:var(--ink)}
.cd-hoy .cd-t{color:var(--acc); font-weight:650}
/* El paso donde la cadena está ATASCADA: rojo, no azul — hay algo
   detenido esperando exactamente ahí. */
.cd-bloq .cd-n{background:var(--st-crit); color:#fff; border-color:var(--st-crit)}
.cd-bloq .cd-t{color:var(--crit); font-weight:650}

/* ════════ La entrada ════════ */

/* ════════ La entrada ════════
   Página independiente, sin el shell interno: el navy de la marca a la
   izquierda con el producto como protagonista, y el formulario a la
   derecha. La primera impresión es la plataforma, no un prototipo. */

body.en-entrada header{display:none}
#entrada{
  display:grid; grid-template-columns:55% 45%;
  min-height:100vh; gap:0;
}
.ent-marca{
  background:var(--nav); color:#fff; display:flex; align-items:center;
  padding:clamp(28px, 5.5vw, 80px); overflow:hidden;
}
.ent-marca-cuerpo{max-width:640px; width:100%}
.ent-logo{display:flex; align-items:center; gap:13px; margin-bottom:clamp(28px, 5vh, 52px)}
.ent-logo img{width:52px; height:52px}
.ent-logo b{font-size:21px; letter-spacing:.16em; font-weight:650; color:#fff}
.ent-tit{
  font-size:clamp(30px, 3.4vw, 46px); line-height:1.08; letter-spacing:-.028em;
  margin:0 0 16px; font-weight:700; max-width:15ch; color:#fff;
}
.ent-sub{color:var(--nav-ink); font-size:15.5px; line-height:1.6; margin:0 0 26px; max-width:44ch}
.ent-lista{
  list-style:none; margin:0; padding:0;
  display:flex; gap:22px; flex-wrap:wrap;
}
.ent-lista li{display:flex; gap:8px; align-items:center; font-size:13.2px; color:var(--nav-ink)}
.ent-lista li>span{flex-shrink:0; color:var(--nav-acc); display:flex}
.ent-lista li>span svg{width:16px; height:16px}
.ent-lista b{font-weight:600; color:#fff}

/* La ventana del producto: la captura real del «Hoy». Se enciende sola
   cuando el archivo existe — nunca un tablero dibujado con datos falsos. */
.ent-preview{
  margin:clamp(26px, 5vh, 44px) 0 0; border-radius:12px; overflow:hidden;
  border:1px solid rgba(255,255,255,.14); background:var(--nav-2);
  box-shadow:0 24px 60px rgba(0,0,0,.4);
}
.ent-preview-marco{
  height:26px; display:flex; align-items:center; gap:6px; padding:0 12px;
  background:rgba(255,255,255,.06); border-bottom:1px solid rgba(255,255,255,.08);
}
.ent-preview-marco i{width:9px; height:9px; border-radius:50%; background:rgba(255,255,255,.22)}
.ent-preview img{display:block; width:100%}

/* El formulario: superficie clara, 420 de ancho, sin tarjeta pesada. */
.ent-caja{
  background:var(--card); display:flex; align-items:center; justify-content:center;
  padding:clamp(22px, 4vw, 64px);
}
.ent-form{width:100%; max-width:420px}
.ent-form h2{margin:0 0 5px; font-size:24px; font-weight:700; letter-spacing:-.02em}
.ent-form-sub{margin:0 0 26px; color:var(--muted); font-size:13.8px}
.ent-campo{display:block; margin-bottom:15px; font-size:12.5px; font-weight:600; color:var(--ink)}
.ent-campo input{
  width:100%; margin-top:6px; height:46px; padding:0 13px;
  font-size:14px; border-radius:9px;
}
.ent-clave{position:relative; display:block}
.ent-clave input{padding-right:44px}
#e-ver{
  position:absolute; right:5px; top:50%; transform:translateY(calc(-50% + 3px));
  background:transparent; border:0; cursor:pointer; color:var(--faint);
  width:36px; height:36px; display:grid; place-items:center; border-radius:7px;
}
#e-ver:hover{color:var(--ink); background:var(--card-2)}
#e-ver svg{width:18px; height:18px}
.ent-btn{width:100%; height:46px; font-size:14px; border-radius:9px; margin-top:4px}
/* Los tres huecos de mensaje de las pantallas de entrada. Van juntos
   porque son lo mismo: lo que la pantalla le contesta a alguien que
   todavía no ha entrado. `#o-error` y `#n-error` —los de «olvidé mi
   contraseña» y «poner contraseña nueva»— no tenían NINGUNA regla, así
   que «Las dos no coinciden» salía del color del texto normal y del
   tamaño de un párrafo, sin distinguirse de las instrucciones de
   encima. */
#e-error, #o-error, #n-error{color:var(--crit); font-size:12.5px; margin-top:10px; min-height:1em}
/* ⚠ Y el ÉXITO no puede salir en rojo. `.ent-ok` ya existía, pero un
   selector de id pesa más que uno de clase y `--crit` ganaba siempre:
   «Contraseña cambiada. Ya puedes entrar.» —el minuto en que alguien
   acaba de recuperar el acceso a su cuenta— se le confirmaba en el
   color con el que esta misma pantalla le dice que se equivocó. */
#e-error.ent-ok, #o-error.ent-ok, #n-error.ent-ok{color:var(--ok)}
.ent-seguro{
  display:flex; align-items:center; gap:7px; justify-content:center;
  margin-top:16px; font-size:12px; color:var(--muted); cursor:default;
}
.ent-seguro svg{width:14px; height:14px; color:var(--ok)}
.ent-div{
  display:flex; align-items:center; gap:12px; margin:20px 0 14px;
  font-size:11.5px; color:var(--faint); text-transform:lowercase;
}
.ent-div::before,.ent-div::after{content:''; flex:1; height:1px; background:var(--divisor)}
.ent-pie{margin-top:30px; text-align:center; font-size:11.5px; color:var(--faint)}

/* El modal de la demostración: perfiles por rol, con iniciales — la
   foto real exige sesión (leer archivos es un permiso) y aparece al
   entrar. */
#modal-demo{
  position:fixed; inset:0; z-index:70; display:none;
  background:rgba(13,21,38,.5); place-items:center; padding:18px;
}
#modal-demo.on{display:grid}
.md-caja{
  background:var(--card); border:1px solid var(--linea); border-radius:16px;
  box-shadow:var(--sombra-lg); width:100%; max-width:520px; max-height:90vh; overflow:auto;
}
.md-h{padding:18px 22px 14px; border-bottom:1px solid var(--divisor); display:flex; gap:12px; align-items:flex-start}
.md-h h3{margin:0 0 3px; font-size:16.5px; font-weight:700}
.md-h .cerrar{
  margin-left:auto; background:transparent; border:0; color:var(--faint);
  font-size:18px; cursor:pointer; line-height:1; padding:2px 6px;
}
.md-h .cerrar:hover{color:var(--ink)}
.md-b{padding:14px 22px 20px; display:grid; gap:8px}
.md-rol{
  display:flex; gap:12px; align-items:center; text-align:left; width:100%;
  padding:11px 13px; border-radius:11px; cursor:pointer; font-family:inherit;
  background:var(--card); border:1px solid var(--linea); color:var(--ink);
  transition:border-color .15s, background .15s;
}
.md-rol:hover{border-color:var(--acc); background:var(--acc-soft)}
.md-rol b{font-size:13.5px; font-weight:600; display:block}
.md-rol span{font-size:11.8px; color:var(--muted)}
.md-rol.principal{border-color:var(--acc-line)}

@media (max-width:1024px){
  #entrada{grid-template-columns:1fr 1fr}
}
@media (max-width:860px){
  #entrada{grid-template-columns:1fr}
  .ent-caja{order:-1; min-height:100vh}
  .ent-marca{padding:28px 22px 36px}
  .ent-preview{display:none}
  .ent-tit{font-size:26px; max-width:none}
}

/* ════════ El inventario visual ════════ */

.unidades{display:grid; grid-template-columns:repeat(auto-fill, minmax(84px, 1fr)); gap:9px}
.u{
  display:flex; flex-direction:column; align-items:flex-start; justify-content:center; gap:2px;
  padding:9px 10px; min-height:56px; border-radius:var(--r-sm); cursor:pointer;
  font-family:inherit; text-align:left; border:1px solid var(--linea-fuerte);
  background:var(--card-2); color:var(--ink);
  transition:border-color .12s, box-shadow .12s;
}
.u:hover:not(:disabled){border-color:var(--faint); box-shadow:var(--sombra)}
.u:disabled{cursor:default}
.u-cod{font-weight:650; font-size:13.5px; letter-spacing:-.01em}
.u-area{font-size:10.5px; color:var(--muted)}
.u-ok{background:var(--ok-soft); border-color:var(--ok-line)}
.u-ok .u-cod{color:var(--ok)}
.u-warn{background:var(--warn-soft); border-color:var(--warn-line)}
.u-warn .u-cod{color:var(--warn)}
.u-crit{background:var(--crit-soft); border-color:var(--crit-line)}
.u-crit .u-cod{color:var(--crit)}
.u-leyenda{
  display:inline-block; width:9px; height:9px; border-radius:3px; margin-right:4px;
  border:1px solid var(--linea-fuerte); vertical-align:baseline;
}

/* ════════ El «Hoy»: la lista de atención ════════

   Deja de ser una grilla de tarjetas del mismo peso. Es UNA lista
   vertical ordenada por urgencia, con el grupo crítico primero: lo que
   la pantalla contesta es «¿qué resuelvo ahora?», y una grilla obliga a
   escanear en dos dimensiones para saberlo. */

.at-grupo{
  font-size:10px; letter-spacing:.1em; text-transform:uppercase; font-weight:650;
  color:var(--muted); margin:18px 0 8px; display:flex; align-items:center; gap:8px;
}
.at-grupo:first-child{margin-top:0}
.at-grupo::before{content:''; width:7px; height:7px; border-radius:var(--r-full); background:var(--faint)}
.at-grupo.crit{color:var(--crit)} .at-grupo.crit::before{background:var(--crit)}
.at-grupo.warn{color:var(--warn)} .at-grupo.warn::before{background:var(--warn)}
.at-lista{display:flex; flex-direction:column; gap:8px}
.alerta{
  display:flex; gap:13px; align-items:flex-start;
  background:var(--card); border:1px solid var(--linea); border-radius:var(--r);
  padding:12px 14px 12px 16px; position:relative; overflow:hidden;
  transition:border-color .12s, box-shadow .12s;
}
.alerta::before{content:''; position:absolute; inset:0 auto 0 0; width:3px; background:var(--linea-fuerte)}
.alerta.crit::before{background:var(--crit)}
.alerta.warn::before{background:var(--warn)}
.alerta.neu::before{background:var(--acc)}
.alerta:hover{border-color:var(--linea-fuerte); box-shadow:var(--sombra)}
.al-ic{
  width:34px; height:34px; border-radius:var(--r-sm); flex-shrink:0;
  display:grid; place-items:center; background:var(--neu-soft); color:var(--muted);
}
.al-ic svg{width:17px; height:17px}
.alerta.crit .al-ic{background:var(--crit-soft); color:var(--crit)}
.alerta.warn .al-ic{background:var(--warn-soft); color:var(--warn)}
.alerta.neu .al-ic{background:var(--acc-soft); color:var(--acc)}
.al-cuerpo{min-width:0; flex:1}
.al-tit{font-weight:600; font-size:13.5px; line-height:1.35; letter-spacing:-.005em}
.al-det{font-size:12.3px; color:var(--muted); line-height:1.5; margin-top:2px}
.al-cta{flex-shrink:0; align-self:center; display:flex; gap:8px; align-items:center}

/* Compatibilidad con pantallas que aún usan la grilla vieja. */
.tarjetas{display:grid; grid-template-columns:repeat(auto-fill, minmax(330px, 1fr)); gap:var(--gap)}
.tj{
  display:grid; grid-template-columns:auto 1fr; grid-template-areas:"ic cuerpo" "pie pie";
  gap:4px 13px; position:relative; overflow:hidden;
  background:var(--card); border:1px solid var(--linea); border-radius:var(--r);
  padding:15px 16px 13px 19px;
  transition:border-color .12s, box-shadow .12s;
}
.tj:hover{border-color:var(--linea-fuerte); box-shadow:var(--sombra)}
.tj::before{content:''; position:absolute; inset:0 auto 0 0; width:3px; background:var(--linea-fuerte)}
.tj-crit::before{background:var(--crit)}
.tj-warn::before{background:var(--warn)}
.tj-neu::before{background:var(--acc)}
.tj-ic{
  grid-area:ic; width:34px; height:34px; border-radius:var(--r-sm);
  display:grid; place-items:center; font-size:16px; background:var(--neu-soft);
}
.tj-crit .tj-ic{background:var(--crit-soft); color:var(--crit)}
.tj-warn .tj-ic{background:var(--warn-soft); color:var(--warn)}
.tj-neu .tj-ic{background:var(--acc-soft); color:var(--acc)}
.tj-cuerpo{grid-area:cuerpo; min-width:0}
.tj-tit{font-weight:600; font-size:13.5px; line-height:1.35}
.tj-det{font-size:12.3px; color:var(--muted); line-height:1.5; margin-top:3px}
.tj-pie{
  grid-area:pie; display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  margin-top:11px; padding-top:11px; border-top:1px solid var(--divisor);
}
.tj-pie .btn{margin-left:auto}

/* ════════ El cronograma dibujado ════════
   La barra normal es azul de acción; verde solo lo terminado, ámbar el
   riesgo, rojo el atraso. El color del Gantt es estado, no adorno. */

.gantt{position:relative; --g-nom:210px; --g-sep:14px}
.g-fila{display:flex; align-items:center; gap:var(--g-sep); padding:5px 0}
.g-nom{flex:0 0 var(--g-nom); min-width:0}
.g-pista{
  position:relative; flex:1; height:30px; min-width:0;
  border-radius:var(--r-sm); background:var(--card-2);
}
.g-mes{
  position:absolute; top:0; bottom:0; display:block;
  border-left:1px solid var(--linea);
}
.g-cab{padding-bottom:2px}
.g-cab .g-pista{height:20px; background:transparent}
.g-etq{
  position:absolute; top:2px; padding-left:5px;
  font-size:10px; letter-spacing:.07em; text-transform:uppercase;
  color:var(--faint); font-weight:600;
}
.g-barra{
  position:absolute; top:5px; height:20px; border-radius:5px;
  overflow:hidden; display:flex; align-items:center;
  min-width:10px; background:var(--acc);
}
.g-barra i{display:block; height:100%; background:rgba(255,255,255,.34)}
.g-pct{
  position:absolute; right:8px; font-size:10px; font-weight:650; color:#fff;
  text-shadow:0 1px 2px rgba(0,0,0,.35); letter-spacing:.02em;
}
.g-ok{background:var(--ok)}
.g-warn{background:var(--warn)}
.g-crit{background:var(--crit)}
.g-freno{
  position:absolute; top:4px; margin-left:-19px; line-height:22px;
  background:transparent; border:0; padding:0; cursor:pointer; color:var(--crit);
}
.g-freno:hover{color:var(--crit-fuerte)}

.g-hoy{
  position:absolute; top:22px; bottom:0; width:2px; background:var(--acc);
  opacity:.75; pointer-events:none;
  left:calc(var(--g-nom) + var(--g-sep) + (100% - var(--g-nom) - var(--g-sep)) * var(--x));
}
.g-hoy span{
  position:absolute; top:-16px; left:50%; transform:translateX(-50%);
  background:var(--acc); color:#fff; font-size:9.5px; font-weight:650;
  padding:1px 6px; border-radius:var(--r-full); letter-spacing:.06em;
}

/* ════════ El desglose: drawer lateral ════════
   Deja de ser un modal centrado que tapa: entra por la derecha y el
   contexto queda a la vista. Es el mismo patrón para revisar sin
   perder dónde se estaba. */

#desglose{
  position:fixed; inset:0; z-index:60; display:none;
  background:rgba(13,21,38,.42);
}
#desglose.on{display:block}
#desglose .caja{
  position:absolute; top:0; right:0; bottom:0;
  background:var(--card); border-left:1px solid var(--linea-fuerte);
  box-shadow:var(--sombra-lg); width:min(440px, 100%);
  display:flex; flex-direction:column;
  animation:drawer .18s ease-out;
}
@keyframes drawer{from{transform:translateX(24px); opacity:.4}to{transform:none; opacity:1}}
#desglose .dh{
  padding:16px 20px; border-bottom:1px solid var(--linea);
  display:flex; align-items:flex-start; gap:12px; flex-shrink:0;
}
#desglose .dh h3{margin:0; font-size:15px; letter-spacing:-.01em; font-weight:650}
#desglose .dh .cerrar{
  margin-left:auto; background:transparent; border:0; color:var(--faint);
  font-size:18px; cursor:pointer; line-height:1; padding:2px 6px;
}
#desglose .dh .cerrar:hover{color:var(--ink)}
#desglose .db{padding:8px 20px 18px; overflow-y:auto; flex:1}
#desglose .dfila{
  display:flex; gap:12px; padding:9px 0; border-bottom:1px solid var(--divisor);
  font-size:13px; align-items:flex-start;
}
#desglose .dfila:last-child{border-bottom:0}
#desglose .dk{color:var(--muted); min-width:44%}
#desglose .dv{font-weight:600; margin-left:auto; text-align:right}
#desglose .dpie{
  font-size:12px; color:var(--muted); line-height:1.6; flex-shrink:0;
  border-top:1px solid var(--linea); padding:13px 20px; background:var(--card-2);
}

/* ════════ El buscador ════════
   En el centro de la barra clara. Nunca por debajo de 190 px: por ahí
   se alcanza todo lo que no está en el menú. */

#cajabuscar{position:relative; margin-left:8px; flex:1 1 300px; min-width:190px; max-width:460px}
/* El buscador es la puerta a todo lo que no está en el menú, y por eso
   es lo único claro de la barra: se ve primero. */
#buscar{
  width:100%; background:#fff; color:var(--acc); font-weight:550;
  border:1px solid #fff;
  border-radius:var(--r-sm); padding:7px 11px; font-size:12.8px; font-family:inherit;
}
#buscar:hover{border-color:var(--nav-acc)}
#buscar:focus{border-color:var(--nav-acc); outline:none}
#buscar::placeholder{color:var(--acc); opacity:.65; font-weight:500}
#resultados{
  position:absolute; top:38px; left:0; width:min(480px, 92vw); max-height:70vh; overflow-y:auto;
  background:var(--card); border:1px solid var(--linea-fuerte); border-radius:var(--r);
  box-shadow:var(--sombra-lg); z-index:50; display:none;
}
#resultados .bgrupo{
  font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:var(--faint);
  padding:10px 14px 5px; border-top:1px solid var(--divisor); font-weight:650;
}
#resultados .bgrupo:first-child{border-top:0}
#resultados .bitem{padding:9px 14px; cursor:pointer; display:flex; gap:10px; align-items:flex-start}
#resultados .bitem:hover,#resultados .bitem.sel{background:var(--acc-soft)}
#resultados .bt{font-size:12.8px; font-weight:600; color:var(--ink)}
#resultados .bs{font-size:11.5px; color:var(--muted)}
#resultados .bc{
  font-size:10.5px; color:var(--faint); font-family:var(--fm);
  margin-left:auto; white-space:nowrap; padding-left:8px;
}
#resultados .bnota{padding:10px 14px; font-size:11.5px; color:var(--faint); border-top:1px solid var(--divisor)}

/* ════════ La campana y sus notificaciones ════════ */

#campana{position:relative; padding:6px 10px; line-height:1; color:#fff}
#campana:hover{color:#fff}
#campana-n{
  position:absolute; top:-4px; right:-4px;
  background:var(--crit); color:#fff;
  border-radius:var(--r-full); font-size:10px; font-weight:650;
  min-width:16px; height:16px; padding:0 4px;
  display:none; align-items:center; justify-content:center;
}
#campana-n.on{display:inline-flex}
#notifs-panel{
  display:none; position:fixed; z-index:60;
  top:calc(var(--h) + 6px); right:10px;
  width:min(400px, calc(100vw - 20px)); max-height:70vh; overflow:auto;
  background:var(--panel); border:1px solid var(--linea-fuerte);
  border-radius:var(--r); box-shadow:var(--sombra-lg);
}
#notifs-panel.on{display:block}
.notif-item{display:flex; gap:10px; padding:11px 14px;
  border-bottom:1px solid var(--divisor); cursor:pointer}
.notif-item:hover{background:var(--card-2)}
.notif-item .punto{width:8px; height:8px; border-radius:50%; margin-top:6px;
  background:var(--crit); flex:none}
.notif-item.leida .punto{background:transparent}
.notif-item .cuando{font-size:11px; color:var(--faint); margin-top:3px}

/* ════════════════════════════════════════════════════════════════
   Lo que cambia con el tamaño de la pantalla.
   ════════════════════════════════════════════════════════════════ */

/* ── Portátil: el menú se reduce a iconos ──────────────────────── */
@media (max-width:1180px){
  :root{--menu:64px}
  .marca{justify-content:center; padding:15px 0 13px}
  .marca .wm{display:none}
  .navitem{justify-content:center; padding:11px 0; gap:0}
  .navitem span:not(.ni){
    position:absolute; left:64px; background:var(--nav); color:#fff;
    padding:6px 11px; border-radius:var(--r-sm); font-size:12.5px; white-space:nowrap;
    box-shadow:var(--sombra-md); opacity:0; pointer-events:none; transition:opacity .1s;
    z-index:30;
  }
  .navitem{position:relative}
  .navitem:hover span:not(.ni){opacity:1}
  .navsec,.navfoot{display:none}
}

/* ── Tableta y teléfono: el menú sale por encima ───────────────── */
@media (max-width:900px){
  :root{--menu:250px}
  :root{--h:104px}
  header{flex-wrap:wrap; padding:8px 12px; align-content:center; row-gap:8px}
  header .mk{display:block}
  #usuario{order:8}
  #cajabuscar{order:9; flex:1 1 200px; min-width:170px; max-width:none; margin-left:0}
  .menu-btn{display:flex}
  .sidebar{
    position:fixed; top:var(--h); left:0; height:calc(100vh - var(--h)); z-index:45;
    transform:translateX(-100%); visibility:hidden;
    transition:transform .2s ease;
    box-shadow:var(--sombra-lg);
  }
  body.menu-abierto .sidebar{transform:translateX(0); visibility:visible}
  body.menu-abierto::after{
    content:''; position:fixed; inset:var(--h) 0 0 0; background:rgba(13,21,38,.45); z-index:44;
  }
  .marca{justify-content:flex-start; padding:15px 18px 13px}
  .marca .wm{display:block}
  .navitem{justify-content:flex-start; padding:11px 18px; gap:11px}
  .navitem span:not(.ni){position:static; background:none; padding:0; box-shadow:none; opacity:1; pointer-events:auto}
  .navsec,.navfoot{display:block}
  .row2{grid-template-columns:minmax(0,1fr)}
  #proy{max-width:150px; font-size:12px}
  header select#usuario{max-width:160px}
}

/* ── Lo que se toca con el dedo se toca con el dedo ───────────── */
@media (pointer:coarse){
  .btn{min-height:44px; padding:11px 18px; font-size:13.5px}
  .btn.gh{min-height:40px}
  .seg button{min-height:40px; padding:5px 13px}
  input[type=number],input[type=text],input[type=password],select,textarea{
    min-height:44px; font-size:16px;   /* 16px evita que el teléfono haga zoom al enfocar */
  }
  .navitem{padding:13px 18px}
  .menu-btn{width:44px; height:40px}
  #desglose .dh .cerrar{padding:8px 12px; font-size:22px}
  .kpi[data-expl]::after{width:22px; height:22px; font-size:12px}
}

/* ── Teléfono: las tablas dejan de ser tablas ──────────────────── */
@media (max-width:620px){
  :root{--gap:12px}
  .kpis{grid-template-columns:1fr 1fr; gap:10px}
  .kpi{padding:12px 13px}
  .kv{font-size:21px}
  .kl{font-size:9.5px}
  .kd{font-size:11px}
  header{padding:8px 11px 10px; gap:9px}
  /* En teléfono la barra ya va apretada: los dos rótulos se caen.

     El de proyecto se defiende solo con su contenido —«SDM-SE5 · Torre
     Tirá» no se confunde con nada—. El de «Ver como» NO: lo que enseña
     es un nombre de persona, y justo al lado va el perfil con ESE MISMO
     nombre. Quedaban dos desplegables idénticos y sin rótulo, y uno de
     los dos es suplantar a otra persona.

     Así que en teléfono no se ENTRA a ver como alguien —es una tarea de
     escritorio, no de obra— pero si ya se está dentro el selector sigue
     ahí: es la salida, y dejar a alguien encerrado dentro de otra cuenta
     por el ancho de la pantalla sería peor que el ruido que se evita. */
  #lbl-vercomo, #lbl-proy{display:none !important}
  body:not(.suplantando) header select#usuario{display:none !important}
  header select#usuario{max-width:132px}
  #cajabuscar{max-width:none}
  .panel-b{padding:14px}
  .aviso{padding:11px 13px; font-size:12.8px}
  .alerta{flex-wrap:wrap}
  .al-cta{margin-left:47px}

  .gantt{--g-nom:0px; --g-sep:0px}
  .g-fila{flex-direction:column; align-items:stretch; gap:3px; padding:7px 0}
  .g-nom{flex:none}
  .g-cab{display:none}
  .g-hoy{top:0}
  .g-hoy span{top:0}

  .tabla-scroll{overflow-x:visible}
  table,thead,tbody,tr,td{display:block; width:100%}
  table{min-width:0}
  thead{display:none}
  tbody tr{
    border:1px solid var(--linea); border-radius:var(--r-sm);
    margin-bottom:10px; padding:4px 0; background:var(--card);
  }
  tbody tr:hover{background:var(--card)}
  td{
    border-bottom:1px solid var(--divisor); padding:9px 13px;
    display:flex; gap:12px; align-items:flex-start; flex-wrap:wrap;
  }
  /* ⚠ Y LO QUE VA DENTRO DE LA CELDA SE APILA.

     La celda es una fila flex —etiqueta a la izquierda, valor a la
     derecha— y eso vale mientras el valor sea UNA cosa. La celda de una
     actividad lleva tres: el nombre, el código con su frente y la barra
     de avance con su porcentaje. Los tres se repartían la fila como
     hermanos, y a 375 px salían 95 px para el nombre, 45 para el código
     —«ACT-021 · Torre A · Piso 5» leyéndose en vertical, un trozo por
     renglón— y 21 px para la barra, que a ese ancho ya no es una barra.

     Con `flex-wrap` y esto, el primer hijo se queda al lado de la
     etiqueta y los demás bajan a su propio renglón, alineados bajo él.
     No desbordaba —por eso no lo cazó la medición de ancho— pero era
     ilegible, que en la pantalla que se abre de pie en la obra es el
     mismo fallo. */
  td > *:not(:first-child){flex:1 1 100%; margin-left:calc(38% + 12px)}
  td:last-child{border-bottom:0}
  /* La etiqueta de cada valor sale del propio encabezado de la tabla:
     la pone la plataforma al pintar (data-col), no cada pantalla. */
  td::before{
    content:attr(data-col); flex:0 0 38%;
    font-size:10px; letter-spacing:.07em; text-transform:uppercase;
    color:var(--muted); font-weight:600; padding-top:2px;
  }
  td:not([data-col])::before{display:none}
  td.num{text-align:left}
}

/* El arbol de la estructura: con la sangria por profundidad mas el nombre,
   el codigo, el tipo, el estado y las dos acciones, a 375 px la fila pedia
   414 px sobre 345 y se salia del panel. Las acciones bajan a su linea. */
@media (max-width:760px){
  .nd-fila{flex-wrap:wrap}
  .nd-cuerpo{min-width:0; flex:1 1 100%}
  .nd-acc{flex:1 0 100%; margin-top:4px}
  .panel-b.arbol{overflow-x:auto}
}

/* La columna «Se puede comprar» llevaba `width:220px` escrito en linea, y
   en modo tarjeta —donde la celda es flex y su etiqueta se lleva el 38%—
   ese ancho fijo no se podia soltar: el contenido pedia 251 px sobre 220
   y se salia. Como clase, el movil si lo puede soltar. */
.col-compra{width:220px}
@media (max-width:760px){ .col-compra{width:auto; min-width:0} }

/* La fila de una regla de notificacion lleva tres bloques —la frase, el
   contador y el interruptor— y a 375 px no caben en una linea: sin esto
   la fila se salia del panel. */
@media (max-width:760px){
  .nr-fila{flex-wrap:wrap}
  .nr-fila > *{min-width:0}
  /* La frase se lleva la linea entera; el contador y el interruptor bajan
     debajo. Reparirla en tres columnas dejaba la frase en 156 px y el
     codigo tecnico del evento —«factura_proveedor · causar»— se salia. */
  .nr-frase{flex:1 0 100%}
  .nr-frase .pill.mono{white-space:normal; word-break:break-word}
}

@media (max-width:400px){
  .kpis{grid-template-columns:1fr}
}

/* ── Pantalla grande: se aprovecha ─────────────────────────────── */
@media (min-width:1600px){
  :root{--gap:20px}
  body{font-size:14.5px}
}

@media (prefers-reduced-motion:reduce){
  *{transition:none !important; animation:none !important}
}

/* ════════ El avatar ════════
   Foto real si la persona la subió; si no, sus iniciales. Nunca una
   cara inventada. La imagen llega por fetch con permiso (una <img> no
   manda el token) — mientras llega, las iniciales sostienen el sitio. */

.avatar{
  position:relative; display:inline-grid; place-items:center; flex-shrink:0;
  border-radius:50%; overflow:hidden;
  background:var(--acc-soft); color:var(--acc);
}
.avatar img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover}
.av-ini{font-weight:650; letter-spacing:.02em; user-select:none}
.av-24{width:24px; height:24px} .av-24 .av-ini{font-size:9px}
.av-28{width:28px; height:28px} .av-28 .av-ini{font-size:10px}
.av-32{width:32px; height:32px} .av-32 .av-ini{font-size:11px}
.av-40{width:40px; height:40px} .av-40 .av-ini{font-size:13.5px}
.av-56{width:56px; height:56px} .av-56 .av-ini{font-size:19px}
.av-grupo{display:inline-flex; align-items:center}
.av-grupo .avatar{margin-left:-8px; box-shadow:0 0 0 2px var(--card)}
.av-grupo .avatar:first-child{margin-left:0}
.av-mas{
  margin-left:-8px; box-shadow:0 0 0 2px var(--card);
  background:var(--neu-soft); color:var(--muted);
}

/* ════════ El tablero del «Hoy» ════════
   El estilo de tarjeta es UNO para toda la zona: superficie blanca,
   borde claro, radio 14, sombra que casi no se ve. Cada tarjeta no
   inventa su propio diseño. */

.hoy-card{
  background:var(--card); border:1px solid var(--linea-caja); border-radius:var(--r-xl);
  box-shadow:var(--sombra-suave); padding:18px 20px;
  transition:box-shadow .18s, border-color .18s, transform .18s;
}

/* ── Los indicadores: número protagonista + anillo de estado ──── */

/* Dos arriba y dos abajo: cuatro indicadores en una fila quedan
   estrechos y obligan a leer de lado a lado; en dos por dos el ojo los
   toma de a pares. */
.kpis-r{
  display:grid; grid-template-columns:repeat(2, 1fr);
  gap:var(--gap); margin-bottom:var(--gap);
}
@media (max-width:720px){ .kpis-r{grid-template-columns:1fr} }
.kpi.kpir{
  display:flex; align-items:center; gap:16px; min-height:128px;
  border-radius:var(--r-xl); box-shadow:var(--sombra-suave); padding:18px 20px;
  transition:box-shadow .18s, border-color .18s, transform .18s;
}
/* La elevación es SIEMPRE la misma: la tarjeta se ve levantada de
   entrada, no solo cuando el cursor pasa por encima. Un realce que solo
   aparece al señalar no existe para quien mira la pantalla de lejos —ni
   para quien la usa en una tableta—. */
.kpi.kpir:hover{transform:translateY(-1px)}
.kpir-radial{position:relative; width:72px; height:72px; flex-shrink:0}
.kpir-radial svg{width:100%; height:100%; transform:rotate(-90deg)}
.kpir-radial .aro-pista{fill:none; stroke:var(--divisor); stroke-width:6}
.kpir-radial .aro-arco{fill:none; stroke-width:6; stroke-linecap:round}
.kpir-radial .kpir-ic{
  position:absolute; inset:0; display:grid; place-items:center; color:var(--muted);
}
.kpir-radial .kpir-ic svg{width:22px; height:22px; transform:none}
.kpir.acc .aro-arco{stroke:var(--acc)} .kpir.acc .kpir-ic{color:var(--acc)}
.kpir.ok .aro-arco{stroke:var(--ok)}   .kpir.ok .kpir-ic{color:var(--ok)}
.kpir.warn .aro-arco{stroke:var(--warn)} .kpir.warn .kpir-ic{color:var(--warn)}
.kpir.crit .aro-arco{stroke:var(--crit)} .kpir.crit .kpir-ic{color:var(--crit)}
/* El cero es un estado limpio, no una gráfica vacía: aro quieto y gris. */
.kpir.cero .aro-arco{stroke:var(--linea)} .kpir.cero .kpir-ic{color:var(--faint)}
.kpir-cuerpo{min-width:0; flex:1}
.kpir-v{
  font-size:clamp(30px, 2.6vw, 38px); font-weight:750; line-height:1.05;
  letter-spacing:-.025em; font-variant-numeric:tabular-nums;
}
.kpir.crit .kpir-v{color:var(--crit)}
/* Un valor con letras («Alcanzado», «Faltan 4») no es un número de 38px. */
.kpir-v.txt{font-size:clamp(17px, 1.6vw, 21px); line-height:1.2; letter-spacing:-.01em}
.kpir-l{font-size:14.5px; font-weight:600; margin-top:3px; letter-spacing:-.005em}
.kpir-d{font-size:12.3px; color:var(--muted); margin-top:1px; line-height:1.45}
/* La flecha al detalle, y el «?» del desglose se queda: cada número
   sigue diciendo de dónde sale. */
.kpir-ir{
  align-self:flex-start; flex-shrink:0; width:30px; height:30px;
  border-radius:50%; border:1px solid var(--linea); background:transparent;
  color:var(--muted); cursor:pointer; display:grid; place-items:center;
  transition:background .15s, color .15s, border-color .15s;
}
.kpir-ir:hover{background:var(--acc); border-color:var(--acc); color:#fff}
.kpir-ir svg{width:15px; height:15px}
.kpi.kpir[data-expl]::after{top:auto; bottom:12px; right:14px}

/* ── Requiere tu atención ─────────────────────────────────────── */

.aten{border-radius:var(--r-xl); box-shadow:var(--sombra-suave); overflow:hidden}
.aten .panel-h{padding:14px 20px}
.aten.con-criticas .panel-h{
  background:var(--crit-soft); border-bottom-color:var(--crit-line);
}
.aten-ic{
  width:30px; height:30px; border-radius:var(--r-sm); flex-shrink:0;
  display:grid; place-items:center; background:var(--crit-soft); color:var(--crit);
}
.aten.con-criticas .aten-ic{background:#fff; }
@media (prefers-color-scheme:dark){ .aten.con-criticas .aten-ic{background:var(--card)} }
.aten-ic svg{width:17px; height:17px}
/* El badge que carga el peso: rojo oscuro, texto blanco, imposible de
   perder. No un puntico. */
.badge-crit{
  background:var(--crit-fuerte); color:#fff; font-weight:650; font-size:11.5px;
  border-radius:7px; padding:3px 10px; letter-spacing:.01em; white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.aten-orden{display:inline-flex; align-items:center; gap:6px; font-size:11.8px; color:var(--muted)}
.aten .alerta{padding:16px 18px; border-radius:var(--r-lg)}
.aten .alerta::before{width:4px}
.aten .al-tit{font-size:15px; font-weight:650}
.aten .al-det{font-size:13px; margin-top:3px}
.aten .al-cta .btn{padding:9px 22px; border-radius:8px}
.aten .al-urg{
  font-size:10px; letter-spacing:.08em; text-transform:uppercase; font-weight:650;
  display:inline-flex; align-items:center; gap:6px; margin-bottom:3px;
}
.aten .al-urg::before{content:''; width:7px; height:7px; border-radius:50%; background:currentColor}
.aten .al-urg.crit{color:var(--crit)} .aten .al-urg.warn{color:var(--warn)}
.aten .al-urg.med{color:var(--med)} .aten .al-urg.neu{color:var(--muted)}

/* ── La zona analítica: cuatro tarjetas del mismo sistema ─────── */

.zona-ana{
  display:grid; grid-template-columns:1fr 1.1fr 1fr 1fr; gap:var(--gap);
  margin-top:var(--gap); align-items:stretch;
}
@media (max-width:1280px){ .zona-ana{grid-template-columns:1fr 1fr} }
@media (max-width:680px){ .zona-ana{grid-template-columns:1fr} }
.ana-card{display:flex; flex-direction:column; min-width:0}
.ana-h{display:flex; align-items:center; gap:8px; margin-bottom:14px}
.ana-h h3{margin:0; font-size:15px; font-weight:650; letter-spacing:-.005em; flex:1 1 auto; min-width:0}
/* El acompanante de la derecha cede antes que el titulo. Sin esto, a 375 px
   «el expediente se armo solo mientras la obra ocurria» empujaba el h3 de
   Reclamaciones hasta 11 px de ancho: el titulo del panel desaparecia y la
   nota al margen se quedaba con la fila entera. */
.ana-h > .tsub{flex:0 1 auto; min-width:0}
@media (max-width:760px){ .ana-h{flex-wrap:wrap} .ana-h > .tsub{margin-left:0 !important; flex-basis:100%} }
.ana-h .btn.gh{font-size:12px; padding:4px 6px; white-space:nowrap}
.ana-pie{
  margin-top:auto; padding-top:12px; border-top:1px solid var(--divisor);
  font-size:11.8px; color:var(--muted); display:flex; align-items:center; gap:6px;
}
.ana-pie svg{width:14px; height:14px; flex-shrink:0}
.ana-vacio{
  flex:1; display:grid; place-items:center; text-align:center;
  color:var(--muted); font-size:12.6px; line-height:1.6; padding:18px 8px;
}
.ana-vacio b{color:var(--ink)}

/* Distribución por urgencia: la dona y su leyenda. */
.dona-caja{display:flex; align-items:center; gap:18px}
.dona{position:relative; width:124px; height:124px; flex-shrink:0}
.dona svg{width:100%; height:100%; transform:rotate(-90deg)}
.dona circle{fill:none; stroke-width:12}
.dona-centro{
  position:absolute; inset:0; display:grid; place-items:center; text-align:center;
}
.dona-centro b{
  font-size:26px; font-weight:750; line-height:1; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; display:block;
}
.dona-centro span{font-size:10.5px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em}
.dona-leyenda{flex:1; min-width:0; display:flex; flex-direction:column; gap:8px}
.dl-fila{display:flex; align-items:center; gap:8px; font-size:12.8px}
.dl-fila i{width:9px; height:9px; border-radius:3px; flex-shrink:0}
.dl-fila .dl-n{margin-left:auto; font-weight:650; font-variant-numeric:tabular-nums}
.dl-fila .dl-pct{color:var(--muted); font-variant-numeric:tabular-nums; width:38px; text-align:right}

/* La línea de la semana. */
.grafica-linea{width:100%; height:auto; display:block}
.grafica-linea .gl-grid{stroke:var(--divisor); stroke-width:1}
.grafica-linea .gl-linea{stroke:var(--warn); stroke-width:2; fill:none}
.grafica-linea .gl-area{fill:var(--warn); opacity:.07}
.grafica-linea .gl-punto{fill:var(--card); stroke:var(--warn); stroke-width:2; cursor:pointer}
.grafica-linea .gl-dia{font-size:9.5px; fill:var(--muted)}
.grafica-linea .gl-num{font-size:9px; fill:var(--faint)}
/* El tooltip de la casa: navy, no el del navegador. */
.gl-tip{
  position:absolute; pointer-events:none; display:none; z-index:5;
  background:var(--nav); color:#fff; font-size:11.5px; line-height:1.45;
  border-radius:8px; padding:6px 10px; box-shadow:var(--sombra-md);
  transform:translate(-50%, calc(-100% - 8px)); white-space:nowrap;
}
.gl-tip b{font-variant-numeric:tabular-nums}
.gl-tip.on{display:block}

/* Equipo y próximas: filas de lista con separador sutil. */
.fila-persona,.fila-prox{
  display:flex; align-items:center; gap:11px; padding:9px 0;
  border-bottom:1px solid var(--divisor);
}
.fila-persona:last-of-type,.fila-prox:last-of-type{border-bottom:0}
.fp-datos{min-width:0; flex:1}
.fp-nombre{font-size:13.2px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.fp-rol{font-size:11.5px; color:var(--muted)}
.fp-n{
  font-size:12px; font-weight:650; font-variant-numeric:tabular-nums;
  background:var(--neu-soft); color:var(--ink); border-radius:7px; padding:2px 9px;
}
.fp-n.crit{background:var(--crit-soft); color:var(--crit)}
.fila-prox .al-ic{width:32px; height:32px}
.fila-prox .al-ic svg{width:16px; height:16px}

/* ── El panel informativo del pie ─────────────────────────────── */

.panel-info{
  display:flex; gap:14px; align-items:flex-start;
  background:var(--acc-soft); border:1px solid var(--acc-line);
  border-radius:var(--r-lg); padding:16px 18px; margin-top:var(--gap);
  font-size:12.8px; line-height:1.65; color:var(--ink);
}
.panel-info b{font-weight:650}
.pi-ic{
  width:32px; height:32px; border-radius:50%; flex-shrink:0;
  background:var(--nav); color:#fff; display:grid; place-items:center;
}
.pi-ic svg{width:16px; height:16px}

/* ════════ El sistema CRM ════════
   Los componentes del rediseño del Hoy, extendidos al CRM. La
   consistencia viene del SISTEMA (tokens, radios, sombras, badges),
   no de repetir el mismo layout en dieciséis pantallas. */

/* Subtítulo de bloque dentro de un grupo del menú: organiza, no navega. */
.navsub{
  font-size:9px; letter-spacing:.09em; text-transform:uppercase;
  color:#fff; opacity:.8; font-weight:650;
  padding:12px 22px 3px; user-select:none;
}

/* Los KPIs compactos: el mismo kpi() de siempre (con su desglose y su
   «?»), en talla pequeña — para las pantallas donde el protagonista es
   otra cosa. */
.kpis.kpis-c{gap:10px; margin-bottom:var(--gap)}
.kpis-c .kpi{padding:10px 14px; border-radius:var(--r)}
.kpis-c .kv{font-size:20px; margin:4px 0 1px}
.kpis-c .kl{font-size:10px}
.kpis-c .kd{font-size:11px}
.kpis-c .kpi[data-expl]::after{top:9px; right:10px; width:15px; height:15px; font-size:9.5px}

/* El estado vacío elegante: dice qué es el lugar y ofrece el camino. */
.estado-vacio{
  display:grid; place-items:center; text-align:center;
  padding:56px 24px; color:var(--muted);
}
.estado-vacio .ev-ic{
  width:52px; height:52px; border-radius:14px; display:grid; place-items:center;
  background:var(--acc-soft); color:var(--acc); margin:0 auto 14px;
}
.estado-vacio .ev-ic svg{width:24px; height:24px}
.estado-vacio h3{margin:0 0 6px; font-size:16px; color:var(--ink); font-weight:650}
.estado-vacio p{margin:0 auto 16px; font-size:13px; line-height:1.6; max-width:44ch}
.estado-vacio .fila{justify-content:center}

/* El callout discreto: una línea de contexto con icono, no un párrafo.
   Lo largo vive detrás de «¿Cómo se calcula?», que abre el drawer. */
.callout{
  display:flex; gap:10px; align-items:flex-start; flex-wrap:wrap;
  background:var(--card-2); border:1px solid var(--linea); border-radius:var(--r);
  padding:10px 14px; margin:12px 0; font-size:12.4px; line-height:1.55; color:var(--muted);
}
.callout b{color:var(--ink); font-weight:600}
.callout>svg{width:15px; height:15px; flex-shrink:0; margin-top:2px; color:var(--acc)}
.callout .btn.gh{margin-left:auto; align-self:center; font-size:12px; white-space:nowrap}

/* Barra apilada: un total repartido en estados, con su leyenda. */
.apilada{margin:4px 0 8px}
.apilada-b{display:flex; height:14px; border-radius:var(--r-full); overflow:hidden; background:var(--divisor)}
.apilada-b i{display:block; height:100%}
.apilada-l{display:flex; flex-wrap:wrap; gap:14px; margin-top:8px; font-size:12px; color:var(--muted)}
.apilada-l span{display:inline-flex; align-items:center; gap:6px}
.apilada-l i{width:9px; height:9px; border-radius:3px}
.apilada-l b{color:var(--ink); font-variant-numeric:tabular-nums}
.t-ok{background:var(--ok)} .t-warn{background:var(--warn)} .t-crit{background:var(--crit)}
.t-acc{background:var(--acc)} .t-neu{background:var(--linea-fuerte)} .t-med{background:var(--med)}

/* Comparar dos avances (obra vs ventas): misma escala, brecha dicha. */
.comparar{display:flex; flex-direction:column; gap:10px; margin:6px 0}
.comparar .cp-fila{display:grid; grid-template-columns:150px 1fr 52px; gap:12px; align-items:center}
.comparar .cp-l{font-size:12.6px; color:var(--muted)}
.comparar .cp-n{font-size:13.5px; font-weight:700; text-align:right; font-variant-numeric:tabular-nums}
.comparar .bar{margin:0}

/* El countdown: la fecha que no se negocia, imposible de no ver. */
.countdown{
  text-align:center; padding:10px 18px; border-radius:var(--r-lg);
  background:var(--card-2); border:1px solid var(--linea); min-width:86px;
}
.countdown b{
  display:block; font-size:30px; font-weight:750; line-height:1;
  font-variant-numeric:tabular-nums; letter-spacing:-.02em;
}
.countdown span{font-size:10px; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); font-weight:600}
.countdown.crit{border-color:var(--crit-line); background:var(--crit-soft)}
.countdown.crit b{color:var(--crit)}
.countdown.warn{border-color:var(--warn-line); background:var(--warn-soft)}
.countdown.warn b{color:var(--warn)}

/* El pipeline del embudo: una tarjeta por etapa, clicable, la elegida
   en azul. El valor y el conteo son los reales de cada etapa. */
.pipeline{
  display:grid; grid-auto-flow:column; grid-auto-columns:minmax(128px, 1fr);
  gap:8px; overflow-x:auto; padding-bottom:6px; margin-bottom:var(--gap);
}
.pl-etapa{
  background:var(--card); border:1px solid var(--linea); border-radius:var(--r);
  padding:10px 12px; cursor:pointer; text-align:left; font-family:inherit;
  transition:border-color .15s, box-shadow .15s, background .15s; min-width:0;
}
.pl-etapa:hover{border-color:var(--acc-line); box-shadow:var(--sombra-suave)}
.pl-etapa.on{background:var(--acc); border-color:var(--acc); color:#fff}
.pl-etapa.on .pl-p, .pl-etapa.on .pl-sub{color:rgba(255,255,255,.75)}
.pl-nom{
  font-size:10px; letter-spacing:.06em; text-transform:uppercase; font-weight:650;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.pl-p{font-size:11px; color:var(--muted); margin-top:2px; font-variant-numeric:tabular-nums}
.pl-n{font-size:19px; font-weight:750; margin-top:5px; font-variant-numeric:tabular-nums; line-height:1.1}
.pl-sub{font-size:11px; color:var(--muted); font-variant-numeric:tabular-nums; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}

/* La cola de prioridad: el puntaje manda y se ve. */
.cola-fila{
  display:flex; gap:14px; align-items:flex-start;
  background:var(--card); border:1px solid var(--linea); border-radius:var(--r-lg);
  padding:14px 16px; margin-bottom:10px; box-shadow:var(--sombra-suave);
}
.cf-score{
  flex-shrink:0; width:58px; text-align:center; border-radius:var(--r);
  padding:8px 4px 7px; background:var(--card-2); border:1px solid var(--linea);
}
.cf-score b{display:block; font-size:24px; font-weight:750; line-height:1; font-variant-numeric:tabular-nums}
.cf-score span{font-size:9px; letter-spacing:.08em; text-transform:uppercase; font-weight:650; color:var(--muted)}
.cf-score.alta{background:var(--crit-soft); border-color:var(--crit-line)}
.cf-score.alta b, .cf-score.alta span{color:var(--crit)}
.cf-score.media{background:var(--warn-soft); border-color:var(--warn-line)}
.cf-score.media b, .cf-score.media span{color:var(--warn)}
.cf-chips{display:flex; flex-wrap:wrap; gap:6px; margin-top:7px}

/* El inbox de la bandeja. */
.inbox{display:grid; grid-template-columns:minmax(280px, 380px) 1fr; gap:var(--gap); align-items:start}
@media (max-width:960px){ .inbox{grid-template-columns:1fr} }
.hilo{
  display:flex; gap:11px; align-items:flex-start; padding:12px 14px; cursor:pointer;
  border-bottom:1px solid var(--divisor); transition:background .12s;
}
.hilo:hover{background:var(--card-2)}
.hilo.on{background:var(--acc-soft)}
.hilo:last-child{border-bottom:0}
.hilo-datos{min-width:0; flex:1}
.hilo-quien{font-size:13px; font-weight:600; display:flex; gap:8px; align-items:baseline}
.hilo-quien .tsub{margin:0}
.hilo-prev{
  font-size:12.3px; color:var(--muted); margin-top:2px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.hilo-meta{flex-shrink:0; text-align:right; font-size:11px; color:var(--muted)}
.mensajes{display:flex; flex-direction:column; gap:10px; padding:4px 0}
.msg{max-width:72%; border-radius:12px; padding:9px 13px; font-size:13px; line-height:1.5}
.msg.cliente{align-self:flex-start; background:var(--card-2); border:1px solid var(--linea); border-bottom-left-radius:4px}
.msg.asesor{align-self:flex-end; background:var(--acc-soft); border:1px solid var(--acc-line); border-bottom-right-radius:4px}
.msg .tsub{margin-top:4px}

/* Sala de ventas: lo que funciona sin señal y lo que no, en dos
   columnas que se leen desde la otra punta del salón. */
/* La agenda como línea de tiempo. *//* La agenda como línea de tiempo. */
.agenda-linea{position:relative; padding-left:20px}
.agenda-linea::before{content:''; position:absolute; left:5px; top:8px; bottom:8px; width:2px; background:var(--divisor)}
.ag-item{position:relative; display:flex; gap:12px; align-items:flex-start; padding:10px 0}
.ag-item::before{
  content:''; position:absolute; left:-19px; top:16px; width:10px; height:10px;
  border-radius:50%; background:var(--card); border:2px solid var(--acc);
}
.ag-item.vencido::before{border-color:var(--crit)}
.ag-item.cerrado::before{border-color:var(--linea-fuerte)}
.ag-hora{flex-shrink:0; width:84px; font-variant-numeric:tabular-nums; font-weight:650; font-size:13px}
.ag-hora .tsub{font-weight:400}
.ag-cuerpo{flex:1; min-width:0}
.ag-item.vencido .ag-cuerpo{border-left:3px solid var(--crit); padding-left:10px; margin-left:-13px}

/* ════════ El calendario de la agenda comercial ════════ */
.cal-h{flex-wrap:wrap; gap:10px}
.cal-nav{display:flex; align-items:center; gap:6px}
.cal-nav h3{margin:0; min-width:132px; text-transform:capitalize}
.cal-flecha{padding:2px 10px; font-size:17px; line-height:1.1}

/* El selector de vista: dos opciones, la puesta con fondo. No es el
   interruptor de `.toggle`, que dice encendido o apagado. */
.segmento{display:inline-flex; border:1px solid var(--linea-fuerte); border-radius:var(--r-full);
  overflow:hidden; background:var(--fondo2)}
.segmento button{
  border:0; background:transparent; cursor:pointer; padding:5px 14px;
  font:inherit; font-size:12.5px; color:var(--faint);
}
.segmento button.on{background:var(--acc); color:#fff; font-weight:600}

.cal-b{padding:14px 16px}
.cal-scroll{overflow-x:auto}
.cal-mes{
  display:grid; grid-template-columns:repeat(7, minmax(104px, 1fr)); gap:1px;
  background:var(--linea); border:1px solid var(--linea); border-radius:var(--r);
  overflow:hidden; min-width:728px;
}
.cal-dow{
  background:var(--fondo2); padding:7px 9px; font-size:11px; font-weight:650;
  letter-spacing:.04em; text-transform:uppercase; color:var(--faint);
}
.cal-celda{
  position:relative; background:var(--card); min-height:104px; padding:5px 6px 7px;
  display:flex; flex-direction:column; gap:4px;
}
.cal-celda.fuera{background:var(--fondo2)}
.cal-celda.fuera .cal-num{color:var(--faint)}
.cal-celda.hoy{box-shadow:inset 0 0 0 2px var(--acc)}
/* Cubre el hueco libre del día y queda DEBAJO de los compromisos: por
   eso tocar un chip lo abre y tocar el resto agenda ese día. */
.cal-agregar{position:absolute; inset:0; border:0; background:transparent; cursor:pointer; z-index:0}
.cal-agregar:hover{background:var(--acc-soft)}
.cal-num{position:relative; z-index:1; font-size:12px; font-weight:650; align-self:flex-start;
  pointer-events:none}
.cal-celda.hoy .cal-num{
  background:var(--acc); color:#fff; border-radius:var(--r-full);
  min-width:21px; height:21px; display:grid; place-items:center;
}
.cal-evs{position:relative; z-index:1; display:grid; gap:3px}
.cal-ev{
  display:flex; align-items:baseline; gap:5px; width:100%; text-align:left;
  border:0; border-radius:4px; padding:3px 6px; cursor:pointer;
  font:inherit; font-size:11.5px; line-height:1.25;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.cal-ev i{font-style:normal; font-variant-numeric:tabular-nums; opacity:.8; font-size:10.5px}
.cal-ev:hover{filter:brightness(1.08)}
.cal-mas{
  border:0; background:transparent; cursor:pointer; font:inherit; font-size:11px;
  color:var(--faint); text-align:left; padding:1px 6px;
}
.cal-mas:hover{color:var(--acc); text-decoration:underline}

/* Los cinco estados de un compromiso, con fondo sólido y letra blanca:
   la misma regla de los badges de estado del resto de la plataforma. */
.ev-acc{background:var(--acc); color:#fff}
.ev-warn{background:var(--warn); color:#fff}
.ev-crit{background:var(--crit); color:#fff}
.ev-ok{background:var(--ok); color:#fff}
.ev-gris{background:var(--linea-fuerte); color:var(--ink)}

.cal-leyenda{display:flex; flex-wrap:wrap; gap:14px; margin-top:11px}
.cal-leyenda span{display:flex; align-items:center; gap:6px}
.cal-leyenda i{width:11px; height:11px; border-radius:3px; display:inline-block}

@media (max-width:760px){
  .cal-h{gap:8px}
  .cal-nav h3{min-width:0; font-size:14px}
  .cal-b{padding:12px}
  .cal-celda{min-height:82px}
}

/* ════════ Encuestas: las gráficas y el constructor ════════
   Dos gráficas de barras hechas con caja y color, sin librería y sin
   SVG: lo que hay que leer es la altura y la clase, y eso una columna
   lo dice igual. El color es el mismo de siempre —rojo detractor, gris
   pasivo, verde promotor— así que la leyenda es la misma de la agenda. */
.dist{display:grid; grid-template-columns:repeat(11, 1fr); gap:5px; align-items:end; height:148px}
.dist-col{display:flex; flex-direction:column; justify-content:flex-end; height:100%; gap:4px}
.dist-b{border-radius:4px 4px 0 0; min-height:3px; width:100%}
.dist-n{font-size:11px; font-weight:650; text-align:center; color:var(--faint);
  font-variant-numeric:tabular-nums; min-height:14px}
.dist-x{font-size:11px; text-align:center; color:var(--faint); font-variant-numeric:tabular-nums}

.mes-graf{display:flex; gap:12px; align-items:flex-end; height:148px}
.mes-col{flex:1; display:flex; flex-direction:column; justify-content:flex-end; gap:4px; height:100%}
.mes-pila{display:flex; flex-direction:column; border-radius:4px 4px 0 0; overflow:hidden;
  min-height:4px}
.mes-pila i{display:block; width:100%}

/* Una respuesta escrita no se resume: se lee. */
.citas{display:grid; gap:7px}
.cita{font-size:12.8px; color:var(--ink); border-left:2px solid var(--linea-fuerte);
  padding-left:10px}

/* El constructor de encuestas: una fila por pregunta, con su tipo. */
.preg-lista{display:grid; gap:8px}
.preg-fila{display:flex; align-items:center; gap:9px; flex-wrap:wrap}
.preg-fila input[type="text"]{flex:1; min-width:200px}
.preg-fila select{width:190px}
.preg-n{width:22px; height:22px; flex-shrink:0; border-radius:var(--r-full);
  background:var(--fondo2); border:1px solid var(--linea); display:grid; place-items:center;
  font-size:11px; font-weight:650; color:var(--faint)}

/* El resumen de cada pregunta dentro del panel de detalle. */
.preg-res{padding:11px 0; border-bottom:1px solid var(--divisor)}
.preg-res:last-child{border-bottom:0}

@media (max-width:760px){
  .dist{gap:3px; height:120px}
  .dist-n,.dist-x{font-size:10px}
  .preg-fila select{width:100%}
}

/* ════════ El formulario de la encuesta, como lo ve el cliente ════════
   No se parece al resto de la plataforma a propósito: quien lo recibe
   no es un usuario de Horizun, es alguien que compró un apartamento y
   abre un enlace. Escala en botones —no en una lista desplegable—
   porque una escala de recomendación se contesta señalando, no
   escogiendo de un menú. */
.form-enc{max-width:560px; margin:0 auto}
.fe-cab{text-align:center; padding:6px 0 18px; border-bottom:1px solid var(--divisor); margin-bottom:18px}
.fe-marca{font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--acc); margin-bottom:7px}
.fe-cab h2{margin:0 0 5px; font-size:19px; font-weight:700}
.fe-cab p{margin:0}

.fe-preg{margin-bottom:20px}
.fe-q{display:flex; gap:9px; align-items:flex-start; font-size:14px; font-weight:600;
  line-height:1.45; margin-bottom:10px}
.fe-n{width:21px; height:21px; flex-shrink:0; border-radius:var(--r-full); background:var(--acc);
  color:#fff; display:grid; place-items:center; font-size:11px; font-weight:700; margin-top:1px}
.fe-obl{color:var(--crit); margin-left:2px}

.fe-ops{display:flex; gap:5px; flex-wrap:wrap}
.fe-nps .fe-op{flex:1; min-width:34px}
.fe-escala .fe-op{min-width:44px}
.fe-sino .fe-op{min-width:86px}
.fe-op{
  padding:9px 6px; border:1px solid var(--linea-fuerte); background:var(--card);
  color:var(--ink); border-radius:var(--r-sm); cursor:pointer; font:inherit; font-size:13.5px;
  font-weight:600; font-variant-numeric:tabular-nums; transition:background .12s, border-color .12s;
}
.fe-op:hover{border-color:var(--acc); background:var(--acc-soft)}
/* Marcada: el color dice de qué lado del indicador cae la respuesta. */
.fe-op.on{color:#fff; border-color:transparent}
.fe-op.tok.on{background:var(--ok)}
.fe-op.tcrit.on{background:var(--crit)}
.fe-op.tneu.on{background:var(--linea-fuerte); color:var(--ink)}
.fe-op.tacc.on,.fe-sino .fe-op.on{background:var(--acc)}
.fe-extremos{display:flex; justify-content:space-between; margin-top:6px; font-size:11px}

.fe-texto{
  width:100%; padding:10px 12px; font:inherit; font-size:13.5px; background:var(--card-2);
  color:var(--ink); border:1px solid var(--linea-fuerte); border-radius:var(--r-sm);
  resize:vertical;
}
.fe-pie{display:flex; align-items:center; gap:12px; padding-top:16px;
  border-top:1px solid var(--divisor); margin-top:6px}
.fe-pie .btn{min-width:150px; justify-content:center}

/* En grande, para poder leerlo. */
#modal-form{
  position:fixed; inset:0; z-index:70; display:none;
  background:rgba(13,21,38,.5); place-items:center; padding:18px;
}
#modal-form.on{display:grid}
.fe-caja-md{max-width:640px}

/* Y la misma pieza, encajada al lado del constructor. */
.fe-marco{
  border:1px solid var(--linea-caja); border-radius:var(--r); background:var(--card-2);
  padding:18px 20px; max-height:520px; overflow:auto;
}
.fe-marco .form-enc{max-width:none}

@media (max-width:560px){
  .fe-nps{display:grid; grid-template-columns:repeat(6, 1fr)}
  .fe-nps .fe-op{min-width:0; padding:11px 2px}
  .fe-cab h2{font-size:17px}
  .fe-pie{flex-wrap:wrap}
  .fe-pie .btn{width:100%}
}

/* ════════ Resultados por campaña ════════
   Una fila por campaña: nombre e inversión, las dos barras en la misma
   escala de conteos, y el valor ganado como cifra. */
.camp-graf{display:grid; gap:13px}
.cg-fila{display:grid; grid-template-columns:minmax(150px, 210px) 1fr minmax(120px, auto);
  gap:14px; align-items:center; min-width:0}
.cg-etq{min-width:0}
.cg-etq .tprim{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.cg-barras{display:grid; gap:4px}
.cg-b{display:flex; align-items:center; gap:8px}
.cg-b i{display:block; height:13px; border-radius:4px; min-width:2px}
.cg-b span{font-size:11.5px; color:var(--faint); font-variant-numeric:tabular-nums; white-space:nowrap}
.cg-valor{text-align:right}
.cg-valor b{display:block; font-size:13.5px; font-variant-numeric:tabular-nums}
@media (max-width:700px){
  .cg-fila{grid-template-columns:1fr; gap:6px}
  .cg-valor{text-align:left}
}

/* ════════ La gráfica de un reporte corrido ════════
   Barras horizontales: la etiqueta a la izquierda, la barra a escala y
   el valor exacto al final. La comparación se hace con el ojo; el
   número fino sigue en la tabla. */
.rep-graf{display:grid; gap:7px}
.rg-fila{display:grid; grid-template-columns:minmax(110px, 220px) 1fr auto;
  gap:10px; align-items:center; min-width:0}
.rg-etq{font-size:12.4px; color:var(--muted); overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap}
.rg-barra{height:14px; background:var(--divisor); border-radius:4px; overflow:hidden}
.rg-barra i{display:block; height:100%; background:var(--acc); border-radius:4px}
.rg-v{font-size:12px; font-variant-numeric:tabular-nums; font-weight:650; white-space:nowrap}
@media (max-width:560px){ .rg-fila{grid-template-columns:90px 1fr auto} }

.rep-frec{padding:5px 8px; font:inherit; font-size:12.3px; background:var(--card-2);
  color:var(--ink); border:1px solid var(--linea-fuerte); border-radius:var(--r-sm)}

/* La versión de una cotización: la viva destaca, la reemplazada calla. */
.versiones{display:flex; gap:8px; flex-wrap:wrap; margin:2px 0 10px}
.version{
  border:1px solid var(--linea); border-radius:var(--r-sm); padding:5px 12px;
  font-size:12px; color:var(--muted); background:var(--card-2);
  font-variant-numeric:tabular-nums;
}
.version.viva{background:var(--acc-soft); border-color:var(--acc-line); color:var(--acc); font-weight:650}

/* La tarjeta de proyecto del portafolio. */
.proyectos-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(300px, 1fr)); gap:var(--gap)}
.proy-card{display:flex; flex-direction:column; gap:0; padding:0; overflow:hidden}
.proy-card .pc-cab{padding:16px 18px 12px; border-bottom:1px solid var(--divisor)}
.proy-card .pc-cuerpo{padding:12px 18px; flex:1}
.proy-card .pc-pie{padding:12px 18px; border-top:1px solid var(--divisor); display:flex; align-items:center; gap:10px}
.pc-datos{display:grid; grid-template-columns:1fr 1fr; gap:8px 14px; font-size:12.4px}
.pc-datos .tsub{margin:0}
.pc-datos b{font-variant-numeric:tabular-nums}

/* Las señales de una tarjeta. Cada una nombra lo que hay que ir a
   resolver, así que lleva a la pantalla que lo resuelve — y por eso es
   un botón. Cuando el rol no alcanza esa pantalla se pinta como texto:
   un enlace que no lleva a ninguna parte es peor que una frase. */
.pc-senal{
  display:block; width:100%; text-align:left; background:transparent; border:0;
  padding:2px 0; font-family:inherit; font-size:11.8px; line-height:1.45;
  overflow-wrap:anywhere; cursor:pointer; border-radius:var(--r-sm);
}
.pc-senal:hover{text-decoration:underline}
/* En teléfono la señal se toca con el dedo, no se señala con un cursor:
   21 px de alto es la mitad de lo que un dedo acierta. */
@media (max-width:767px){
  .pc-senal{min-height:44px; display:flex; align-items:center}
}

/* La banda de métricas de la ficha del proyecto: una sola pieza. */
.banda-mets{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr));
  border:1px solid var(--linea); border-radius:var(--r-lg); overflow:hidden;
  background:var(--card); box-shadow:var(--sombra-suave); margin-bottom:var(--gap);
}
.banda-mets .kpi{border:0; border-left:1px solid var(--divisor); border-radius:0; box-shadow:none}
.banda-mets .kpi:first-child{border-left:0}

/* La vista 360: columna principal + contexto a la derecha. */
.dos-col{display:grid; grid-template-columns:minmax(0, 1fr) minmax(280px, 340px); gap:var(--gap); align-items:start}
/* Dos columnas iguales, cuando las dos piezas pesan lo mismo. Clase y
   no estilo en línea: lo de abajo tiene que poder ganarle. */
.dos-col.mitades{grid-template-columns:1fr 1fr}
/* Cuando la pieza fija va a la izquierda —una matriz, un panel de
   filtros— y lo que crece va a la derecha. */
.dos-col.izq{grid-template-columns:minmax(280px, 380px) minmax(0, 1fr)}
@media (max-width:1020px){
  .dos-col,.dos-col.mitades,.dos-col.izq{grid-template-columns:minmax(0, 1fr)}
}

/* La cabecera de una ficha (oportunidad, proyecto): quién es, en qué
   está y quién responde — antes de cualquier número. */
.ficha-cab{
  display:flex; gap:16px; align-items:flex-start; flex-wrap:wrap;
  background:var(--card); border:1px solid var(--linea); border-radius:var(--r-xl);
  box-shadow:var(--sombra-suave); padding:18px 20px; margin-bottom:var(--gap);
}
.ficha-cab h2{margin:0; font-size:19px; font-weight:700; letter-spacing:-.015em}
.ficha-cab .fc-sub{font-size:13px; color:var(--muted); margin-top:3px}
.ficha-cab .fc-datos{flex:1; min-width:220px}
.ficha-cab .fc-pills{display:flex; gap:6px; flex-wrap:wrap; margin-top:9px}
.ficha-cab .fc-lado{display:flex; gap:18px; align-items:center; flex-wrap:wrap}
.fc-resp{display:flex; gap:9px; align-items:center}
.fc-resp .tsub{margin:0}

/* NPS honesto: sin muestra suficiente no hay gauge. */
.nps-caja{display:flex; align-items:center; gap:20px}
.nps-v{font-size:44px; font-weight:750; line-height:1; font-variant-numeric:tabular-nums; letter-spacing:-.03em}
.resp-score{
  flex-shrink:0; width:52px; height:52px; border-radius:12px;
  display:grid; place-items:center; font-size:19px; font-weight:750;
  font-variant-numeric:tabular-nums;
}
.resp-score.ok{background:var(--ok-soft); color:var(--ok)}
.resp-score.warn{background:var(--warn-soft); color:var(--warn)}
.resp-score.crit{background:var(--crit-soft); color:var(--crit)}

/* El interruptor de una regla de automatización. */
.toggle{
  position:relative; width:38px; height:22px; border-radius:var(--r-full);
  background:var(--linea-fuerte); border:0; cursor:pointer; flex-shrink:0;
  transition:background .15s;
}
.toggle::after{
  content:''; position:absolute; top:3px; left:3px; width:16px; height:16px;
  border-radius:50%; background:#fff; transition:left .15s;
  box-shadow:0 1px 2px rgba(0,0,0,.25);
}
.toggle[aria-checked="true"]{background:var(--ok)}
.toggle[aria-checked="true"]::after{left:19px}

/* ════════ La biblioteca de evidencia ════════
   Galería primero: la evidencia se reconoce mirándola, no leyendo su
   nombre de archivo. La huella sin bytes (el ejemplo sembrado) muestra
   su marcador — nunca una imagen fingida. */
.galeria{display:grid; grid-template-columns:repeat(auto-fill, minmax(210px, 1fr)); gap:14px}
.gal-card{
  margin:0; border:1px solid var(--linea); border-radius:var(--r-lg); overflow:hidden;
  background:var(--card); cursor:pointer; box-shadow:var(--sombra-suave);
  transition:box-shadow .18s, border-color .18s;
}
.gal-card:hover{box-shadow:var(--sombra-suave-hover); border-color:var(--acc-line)}
.gal-marco{position:relative; aspect-ratio:4/3; background:var(--card-2); overflow:hidden}
.gal-img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover}
.gal-ph{
  position:absolute; inset:0; display:grid; place-items:center; text-align:center;
  color:var(--faint); font-size:10.5px; line-height:1.5; gap:0; align-content:center;
}
.gal-ph svg{width:26px; height:26px; margin-bottom:6px}
.gal-badge{position:absolute; top:8px; left:8px}
.gal-card figcaption{padding:9px 11px}

/* ════════ La matriz de riesgos ════════
   3×3 porque el dominio maneja tres niveles — una 5×5 sería inventar
   granularidad. Los tonos son suaves (es un contenedor, no un badge);
   el conteo carga el peso. */
.matriz{
  display:grid; grid-template-columns:auto repeat(3, 1fr); gap:5px;
  max-width:340px;
}
.mz-cab{
  font-size:9.5px; letter-spacing:.06em; text-transform:uppercase; font-weight:650;
  color:var(--muted); text-align:center; padding-bottom:2px; align-self:end;
}
.mz-lado{
  font-size:9.5px; letter-spacing:.06em; text-transform:uppercase; font-weight:650;
  color:var(--muted); align-self:center; padding-right:6px; text-align:right;
}
.mz-celda{
  aspect-ratio:2.1; border-radius:8px; border:1px solid transparent;
  display:grid; place-items:center; font-size:16px; font-weight:750;
  font-variant-numeric:tabular-nums; cursor:pointer; font-family:inherit;
  transition:border-color .15s, transform .15s;
}
.mz-celda:disabled{cursor:default; opacity:.55}
.mz-celda:not(:disabled):hover{border-color:var(--acc); transform:translateY(-1px)}
.mz-celda.on{border-color:var(--acc); box-shadow:0 0 0 2px var(--acc-soft)}
.mz-ok{background:var(--ok-soft); color:var(--ok)}
.mz-warn{background:var(--warn-soft); color:var(--warn)}
.mz-crit{background:var(--crit-soft); color:var(--crit)}
.mz-eje{min-height:0}

/* ════════ La cadena de evidencia (reclamaciones) ════════
   El rastro se lee como cadena: RFI → respuesta → plano → foto →
   bitácora. Y la probanza como puntos: cuántas de las comprobaciones
   están — un 1/5 se ve rojo sin leer nada. */
.cadena-ev{display:inline-flex; align-items:center; gap:4px; flex-wrap:wrap}
.ev-pieza{
  font-family:var(--fm); font-size:10.5px; color:var(--ink);
  background:var(--neu-soft); border:1px solid var(--linea);
  border-radius:6px; padding:1px 7px; white-space:nowrap;
}
.ev-fl{color:var(--faint); font-size:11px}
.ev-puntos{display:inline-flex; gap:3px}
.ev-puntos i{
  width:9px; height:9px; border-radius:50%;
  background:var(--crit-soft); border:1px solid var(--crit-line);
}
.ev-puntos i.si{background:var(--st-ok); border-color:var(--st-ok)}

/* ════════ El visor de plano ════════
   El protagonista es el dibujo: un contenedor técnico gris que ocupa
   la pantalla, no una tarjetica. */
.visor-area{
  background:var(--card-2); border:1px solid var(--linea); border-radius:var(--r-lg);
  min-height:calc(100vh - var(--h) - 210px); display:flex; flex-direction:column;
  justify-content:center; overflow:auto;
}
.visor-lienzo{padding:18px; text-align:center}

/* ════════ El plano DWG dibujado (web/plano.js) ════════
   El lienzo es oscuro como el espacio modelo de AutoCAD, en los dos temas:
   los colores de las capas están pensados para ese fondo. */
.visor-cad{display:flex; flex-direction:column; flex:1; min-height:min(78vh, 900px); align-self:stretch}
.visor-cad-marco{flex:1; display:flex; min-height:0}
.cad-cargando{margin:auto; color:var(--muted); display:flex; gap:8px; align-items:center; padding:40px}
.cad{display:flex; flex-direction:column; flex:1; min-height:0}
.cad-barra{display:flex; flex-wrap:wrap; gap:6px; padding:8px; border-bottom:1px solid var(--linea); background:var(--card)}
.cad-b{padding:5px 10px; font-size:12.5px}
.cad-b.activo{background:var(--acc-soft); color:var(--acc); border-color:var(--acc-line)}
.cad-lienzo{position:relative; flex:1; min-height:360px; overflow:hidden; background:#10151f}
.cad-lienzo canvas{position:absolute; inset:0; display:block}
.cad-capas{position:absolute; top:8px; right:8px; bottom:8px; width:min(280px, 80%); overflow:auto;
  background:var(--card); color:var(--ink); border:1px solid var(--linea); border-radius:var(--r);
  box-shadow:var(--sombra-lg); padding:8px; font-size:12.5px}
.cad-capas-cab{display:flex; gap:6px; margin-bottom:6px; position:sticky; top:-8px; background:var(--card); padding:4px 0}
.cad-capa{display:flex; gap:8px; align-items:center; padding:3px 2px; cursor:pointer; overflow-wrap:anywhere}
.cad-muestra{width:12px; height:12px; border-radius:3px; flex:none; border:1px solid var(--linea-fuerte)}
.cad-estado{font:12px var(--fm); color:var(--muted); padding:5px 10px; min-height:26px; border-top:1px solid var(--linea); background:var(--card)}
.cad-nota{padding:6px 10px}
.visor-lienzo img{
  max-width:100%; border:1px solid var(--linea-fuerte); border-radius:6px;
  background:#fff; box-shadow:var(--sombra-md);
}

/* ════════ El radar de madurez ════════
   Una sola serie en azul sobre una retícula gris: el nivel real de
   cada frente, sin decoración. */
.radar{width:100%; max-width:280px; height:auto}
.rd-grid{fill:none; stroke:var(--divisor); stroke-width:1}
.rd-serie{fill:var(--acc); fill-opacity:.16; stroke:var(--acc); stroke-width:2}
.rd-punto{fill:var(--acc)}
.rd-etq{font-size:9.5px; fill:var(--muted); font-weight:600}

/* ════════ Administración · el sistema de gobierno ════════ */

/* El chip de alcance junto a la pregunta de la pantalla: dice si lo que
   se ve es de la ORGANIZACIÓN (el selector de proyecto no la filtra) o
   del PROYECTO abierto. */
.alc{
  display:inline-flex; align-items:center; gap:5px; vertical-align:middle;
  font-size:10px; font-weight:650; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted); background:var(--card-2); border:1px solid var(--linea);
  border-radius:var(--r-full); padding:2px 9px; margin-right:8px;
}
.alc svg{width:11px; height:11px}

/* Texto de apoyo con tono semántico, sin fondo. */
.txt-warn{color:var(--warn)}
.txt-crit{color:var(--crit)}

/* Un elemento suelto que abre su desglose (fuera de una tarjeta KPI). */
.expl-i[data-expl]{cursor:pointer}
.expl-i[data-expl]:hover{text-decoration:underline; text-decoration-color:var(--faint); text-underline-offset:3px}

/* El banner de previsualización de un portal externo: dentro del
   encabezado, en su propia fila, imposible de perder de vista. */
header{flex-wrap:wrap}
#banner-prev{
  flex-basis:100%; order:-1; display:flex; align-items:center; gap:8px;
  margin:0 -20px; padding:7px 20px; background:var(--nav); color:#fff; font-size:12.5px;
}
#banner-prev svg{flex-shrink:0}
#banner-prev b{font-weight:650; white-space:nowrap}
#banner-prev span{color:rgba(255,255,255,.72); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0}
#banner-prev .btn{
  margin-left:auto; flex-shrink:0; background:#fff; color:var(--nav);
  border-color:#fff; padding:4px 12px; font-size:12px;
}

/* El modal de una acción sensible: botón → impacto → motivo →
   confirmación. Hereda la caja del modal de la demo. */
#modal-conf{
  position:fixed; inset:0; z-index:70; display:none;
  background:rgba(13,21,38,.5); place-items:center; padding:18px;
}
#modal-conf.on{display:grid}
#modal-conf .md-caja{max-width:480px}
.mc-impacto{display:grid; gap:8px; margin:2px 0 14px}
.mc-impacto>div{display:flex; gap:9px; align-items:flex-start; font-size:12.8px; color:var(--muted); line-height:1.5}
.mc-impacto svg{width:15px; height:15px; flex-shrink:0; margin-top:2px; color:var(--warn)}
.mc-campo{display:block; font-size:11.5px; font-weight:600; color:var(--muted); margin-bottom:11px}
.mc-campo input,.mc-campo select,.mc-campo textarea{
  display:block; width:100%; margin-top:4px; padding:9px 11px; font-size:13px;
  background:var(--card-2); color:var(--ink); border:1px solid var(--linea-fuerte);
  border-radius:var(--r-sm); font-family:inherit;
}
.mc-campo textarea{resize:vertical; min-height:74px; line-height:1.55}
/* Varias respuestas a la vez. Hizo falta para declarar a qué se expone
   una persona: alguien opera la grúa Y trabaja en altura, y un
   desplegable de una sola opción obligaría a escoger — que es mentir. */
/* Un botón que el rol de quien entró no puede usar. Se APAGA y no se
   esconde: un maestro que no encuentra el botón de aprobar cree que la
   plataforma no lo tiene; uno que lo ve apagado, y con un título que
   dice «esto lo aprueba dirección de obra», sabe a quién buscar — que
   es lo único que le sirve a esa hora en la obra. */
/* El enlace de «¿Olvidaste tu contraseña?» y sus dos paneles. Es un
   botón y no un <a>: no navega a ninguna parte, cambia el panel. */
.ent-olvide{
  display:block; width:100%; margin-top:10px; padding:6px; background:none; border:0;
  color:var(--acc); font:inherit; font-size:12.5px; cursor:pointer; text-align:center;
}
.ent-olvide:hover{text-decoration:underline}
.ent-ok{color:var(--ok); font-size:12.5px; margin-top:8px; line-height:1.5}

.btn.sin-permiso, .btn.sin-permiso:hover{
  opacity:.42; cursor:not-allowed; filter:grayscale(.7);
  background:var(--card-2); color:var(--faint); border-color:var(--linea);
}
.mc-casillas{display:flex; flex-direction:column; gap:2px; margin-top:5px}
.mc-casilla{display:flex; gap:9px; align-items:flex-start; padding:8px 10px;
  border:1px solid var(--linea); border-radius:var(--r-sm); cursor:pointer;
  font-weight:400; color:var(--ink); background:var(--card-2)}
.mc-casilla:hover{border-color:var(--linea-fuerte)}
.mc-casilla input{width:16px; height:16px; margin:1px 0 0; flex:none; accent-color:var(--acc)}
.mc-casilla span{display:block; font-size:12.5px; line-height:1.45}
.mc-casilla b{display:block; font-size:12.5px; font-weight:600}
.mc-casilla .tsub{display:block; margin-top:1px}
.mc-casilla:has(input:checked){border-color:var(--acc-line); background:var(--acc-soft)}
#mc-vista{min-height:0}
.mc-pie{display:flex; gap:9px; justify-content:flex-end; margin-top:4px}
.btn.peligro{background:var(--st-crit); border-color:var(--st-crit); color:#fff}
.btn.peligro:hover{filter:brightness(1.08)}

/* Puesta en marcha: la cabecera de progreso del setup. */
.setup-cab .setup-fila{display:flex; gap:22px; align-items:flex-start; flex-wrap:wrap}
.setup-izq{flex:1; min-width:220px}
.setup-n{font-size:26px; font-weight:700; letter-spacing:-.02em; margin-top:2px}
.setup-pct{color:var(--muted); font-size:17px; font-weight:600}
.setup-metas{display:flex; gap:16px; margin-top:8px; font-size:12.5px; color:var(--muted); flex-wrap:wrap}
.setup-metas svg{vertical-align:-3px; margin-right:3px}
.setup-cta{
  min-width:200px; text-align:right; display:flex; flex-direction:column;
  gap:4px; align-items:flex-end;
}
.setup-cta .btn{margin-top:6px}
.setup-bar{height:9px; margin-top:16px}
.setup-bar i{background:var(--acc)}

/* El checklist de pasos. */
.chk{display:grid; gap:2px; padding-top:8px; padding-bottom:8px}
.chk-paso{
  display:flex; gap:12px; align-items:flex-start; padding:11px 6px;
  border-bottom:1px solid var(--divisor);
}
.chk-paso:last-child{border-bottom:0}
.chk-ic{
  width:26px; height:26px; border-radius:var(--r-full); flex-shrink:0;
  display:grid; place-items:center; margin-top:1px;
  border:1.5px solid var(--linea-fuerte); color:var(--faint);
}
.chk-paso.listo .chk-ic{background:var(--st-ok); border-color:var(--st-ok); color:#fff}
.chk-paso.actual .chk-ic{border-color:var(--acc); color:var(--acc)}
.chk-paso.bloq .chk-ic{background:var(--st-crit); border-color:var(--st-crit); color:#fff}
.chk-paso.listo .tprim{color:var(--muted)}
.chk-cuerpo{flex:1; min-width:0}
.chk-min{flex-shrink:0; font-size:11.5px; color:var(--faint); font-variant-numeric:tabular-nums; margin-top:4px}
.chk-crit{margin-top:5px}
.chk-crit summary{
  cursor:pointer; font-size:11.5px; color:var(--acc); list-style:none; width:fit-content;
}
.chk-crit summary::before{content:'▸ '; font-size:10px}
.chk-crit[open] summary::before{content:'▾ '}
.chk-crit>div{font-size:12px; color:var(--muted); padding:6px 0 2px; line-height:1.55}

/* El importador: la tira del wizard y el área de pegado. */
.wiz{display:flex; align-items:center; gap:10px; margin-bottom:var(--gap); flex-wrap:wrap}
.wiz-p{display:inline-flex; align-items:center; gap:7px; font-size:12.5px; color:var(--faint); font-weight:600}
.wiz-p i{
  width:24px; height:24px; border-radius:var(--r-full); font-style:normal; font-size:11.5px;
  display:grid; place-items:center; border:1.5px solid var(--linea-fuerte); color:var(--faint);
}
.wiz-p.actual{color:var(--ink)}
.wiz-p.actual i{border-color:var(--acc); background:var(--acc); color:#fff}
.wiz-p.hecho{color:var(--muted)}
.wiz-p.hecho i{border-color:var(--st-ok); background:var(--st-ok); color:#fff}
.wiz-sep{flex:0 0 22px; height:1px; background:var(--linea-fuerte)}
.imp-cols{display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-bottom:10px}
.imp-cols .kl{margin-right:4px}
.imp-area{
  width:100%; font-family:var(--fm); font-size:12px; padding:11px;
  background:var(--card-2); color:var(--ink); border:1px dashed var(--linea-fuerte);
  border-radius:var(--r-md);
}
.imp-area:focus{border-style:solid; border-color:var(--acc); outline:none}
.plegado{margin-bottom:var(--gap)}
.plegado>summary{
  cursor:pointer; list-style:none; font-size:13px; font-weight:600; color:var(--ink);
  padding:11px 14px; background:var(--card); border:1px solid var(--linea); border-radius:var(--r-md);
  display:flex; align-items:center; gap:8px;
}
.plegado>summary svg{color:var(--muted)}
.plegado[open]>summary{border-bottom-left-radius:0; border-bottom-right-radius:0}

/* La cabecera de organización (Empresa, País y contratación). */
.org-cab .org-fila{display:flex; gap:16px; align-items:center; flex-wrap:wrap}
.org-ic{
  width:46px; height:46px; border-radius:var(--r-md); flex-shrink:0;
  background:var(--nav); color:#fff; display:grid; place-items:center;
}
.org-ic svg{width:22px; height:22px}
.org-id{flex:1; min-width:240px}
.org-nombre{font-size:21px; font-weight:700; letter-spacing:-.02em}
.org-mets{
  display:flex; flex-direction:column; gap:6px; font-size:12.8px; color:var(--muted);
  border-left:1px solid var(--divisor); padding-left:18px;
}
.org-mets b{color:var(--ink)}

/* La línea de tiempo de la identidad. */
.tl-id{display:grid; gap:0}
.tl-hito{display:flex; gap:13px; position:relative; padding-bottom:16px}
.tl-hito:last-child{padding-bottom:0}
.tl-hito::before{
  content:''; position:absolute; left:5px; top:14px; bottom:0; width:1.5px;
  background:var(--divisor);
}
.tl-hito:last-child::before{display:none}
.tl-hito>i{
  width:12px; height:12px; border-radius:var(--r-full); flex-shrink:0; margin-top:4px;
  background:var(--card); border:2px solid var(--faint); position:relative; z-index:1;
}
.tl-hito.vivo>i{border-color:var(--ok); background:var(--ok)}
.tl-hito:not(.vivo) .tprim{color:var(--muted); font-weight:500}

/* El árbol de la estructura. */
.arbol{padding-top:6px; padding-bottom:6px}
.nd-fila{
  display:flex; align-items:center; gap:9px; padding:7px 6px 7px calc(6px + var(--prof, 0) * 22px);
  border-bottom:1px solid var(--divisor);
}
.arbol>.nd-fila:last-child{border-bottom:0}
.nd-tog{
  width:22px; height:22px; flex-shrink:0; display:grid; place-items:center;
  background:transparent; border:0; border-radius:var(--r-sm); cursor:pointer; color:var(--faint);
}
.nd-tog:hover{background:var(--card-2); color:var(--ink)}
.nd-tog svg{width:14px; height:14px; transition:transform .15s}
.nd-tog.cerrado svg{transform:rotate(-90deg)}
.nd-tog.vacio{cursor:default}
.nd-cuerpo{flex:1; min-width:0; display:flex; align-items:baseline; gap:9px; flex-wrap:wrap}
.nd-conteo{font-size:11.5px; color:var(--faint)}

/* Las plantillas por tipo de obra, como tarjetas. */
.plantilla-cards{display:grid; grid-template-columns:repeat(auto-fill, minmax(240px, 1fr)); gap:11px}
.plantilla-card{
  border:1px solid var(--linea); border-radius:var(--r-md); padding:13px 15px;
  background:var(--card-2);
}
.plantilla-card.aplicada{border-color:var(--ok-line); background:var(--ok-soft)}
.plantilla-cadena{font-size:12px; color:var(--muted); margin-top:7px; line-height:1.6}
.plantilla-cadena span{color:var(--faint)}

/* El diagrama de un flujo de aprobación. */
.flujo-diag{display:grid; gap:0; max-width:640px}
.fd-paso{
  display:flex; gap:12px; align-items:flex-start; padding:11px 13px;
  border:1px solid var(--linea); border-radius:var(--r-md); background:var(--card-2);
}
.fd-paso.hueco{border-color:var(--warn-line); background:var(--warn-soft)}
.fd-n{
  width:24px; height:24px; border-radius:var(--r-full); flex-shrink:0; margin-top:1px;
  background:var(--nav); color:#fff; font-size:11.5px; font-weight:700;
  display:grid; place-items:center;
}
.fd-cuerpo{flex:1; min-width:0}
.fd-quien{display:flex; align-items:center; gap:8px; margin-top:5px; flex-wrap:wrap; font-size:12.5px}
.fd-plazo{flex-shrink:0; font-size:11.5px; color:var(--faint); font-variant-numeric:tabular-nums; margin-top:4px}
.fd-linea{width:1.5px; height:14px; background:var(--linea-fuerte); margin-left:24px}

/* Las reglas de notificación como frases. */
.nr-lista{display:grid; gap:0}
.nr-fila{
  display:flex; gap:14px; align-items:flex-start; padding:12px 6px;
  border-bottom:1px solid var(--divisor);
}
.nr-fila:last-child{border-bottom:0}
.nr-frase{flex:1; min-width:0; font-size:13px; line-height:1.6}
.nr-k{
  font-size:10px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--faint);
}
.nr-msj{font-size:12.3px; color:var(--muted); margin-top:3px; font-style:italic}
.nr-gen{
  flex-shrink:0; text-align:center; min-width:56px; padding-top:2px;
}
.nr-gen b{display:block; font-size:17px; font-variant-numeric:tabular-nums}
.nr-gen span{font-size:10.5px; color:var(--faint)}

/* Los canales, como tarjetas compactas. */
.canales{display:grid; grid-template-columns:repeat(auto-fill, minmax(230px, 1fr)); gap:11px}
.canal-card{
  display:flex; gap:11px; align-items:center; padding:13px 15px;
  border:1px solid var(--linea); border-radius:var(--r-md); background:var(--card-2);
}
.canal-ic{color:var(--muted); flex-shrink:0}
.canal-cuerpo{flex:1; min-width:0}
.canal-card .pill{flex-shrink:0}

/* El menú de acciones «⋯» de una fila. */
.accmenu{position:relative}
.accmenu summary{
  list-style:none; cursor:pointer; width:30px; height:30px; border-radius:var(--r-sm);
  display:grid; place-items:center; color:var(--muted); border:1px solid transparent;
}
.accmenu summary:hover{background:var(--card-2); border-color:var(--linea)}
.accmenu[open] summary{background:var(--card-2); border-color:var(--linea-fuerte)}
/* Cerrado no ocupa: `display:grid` en la regla de abajo le ganaba al
   `display:none` que el navegador le pone a lo que hay dentro de un
   `<details>` cerrado, así que el menú existía —con su ancho y su
   posición— aunque nadie lo hubiera abierto. Se veía midiendo: doce
   menús colgando 111 px fuera del borde izquierdo en teléfono. */
.accmenu:not([open]) .accmenu-m{display:none}
.accmenu-m{
  position:absolute; right:0; top:34px; z-index:30; min-width:170px;
  background:var(--card); border:1px solid var(--linea); border-radius:var(--r-md);
  box-shadow:var(--sombra-md); padding:5px; display:grid; gap:1px;
  /* Al entrar «Quitar «Director de nuevos negocios»» el menú creció:
     se le pone techo y las entradas largas parten en vez de salirse. */
  max-width:min(260px, calc(100vw - 24px));
}
.accmenu-m .mp-item{white-space:normal; overflow-wrap:anywhere}
/* En teléfono la tabla se reacomoda y la celda de acciones queda pegada
   al borde izquierdo: anclado a la derecha, el menú abría 111 px FUERA
   de la pantalla. Aquí se ancla al otro lado. */
@media (max-width:767px){
  .accmenu-m{right:auto; left:0}
}

/* La cabecera del drawer «Mi perfil». */
.perfil-cab{
  display:flex; align-items:center; gap:14px; padding-bottom:14px; margin-bottom:8px;
  border-bottom:1px solid var(--divisor);
}

/* Las tarjetas de acceso externo. */
.ext-card .ext-fila{display:flex; gap:14px; align-items:flex-start; flex-wrap:wrap}
.ext-ic{
  width:40px; height:40px; border-radius:var(--r-md); flex-shrink:0;
  background:var(--card-2); border:1px solid var(--linea); color:var(--muted);
  display:grid; place-items:center;
}
.ext-cuerpo{flex:1; min-width:230px}
.ext-acciones{display:flex; flex-direction:column; gap:7px; align-items:stretch; flex-shrink:0}
.pv-lista{display:grid; gap:7px}
.pv-si,.pv-no{display:flex; gap:9px; align-items:flex-start; font-size:12.8px; line-height:1.5}
.pv-si svg{color:var(--ok); flex-shrink:0; margin-top:2px}
.pv-no svg{color:var(--crit); flex-shrink:0; margin-top:2px}
.pv-no span{color:var(--muted)}

@media (max-width:620px){
  .org-mets{border-left:0; padding-left:0; flex-direction:row; flex-wrap:wrap; gap:12px}
  .setup-cta{text-align:left; align-items:flex-start}
  .ext-acciones{flex-direction:row; flex-wrap:wrap; width:100%}
  .fd-plazo{display:none}
  #banner-prev span{display:none}
}

/* ── Imprimir ───────────────────────────────────────────────────
   El reporte semanal y el corte se imprimen o se guardan como PDF con
   el diálogo del navegador: sale el contenido, no la aplicación. */
@media print{
  header,.sidebar,.menu-btn,.btn,#desglose,#toast,#notifs-panel,#menu-perfil,#modal-demo,.nota{display:none !important}
  .app{display:block}
  main{width:100%; padding:0}
  body{background:#fff; color:#000; font-size:12px}
  .panel,.kpi,.aviso{box-shadow:none; border-color:#bbb; break-inside:avoid}
  .kpis{grid-template-columns:repeat(4, 1fr)}
  a{color:#000; text-decoration:none}
}

/* ── Las vistas del modelo ────────────────────────────────────────
   Tiras abajo, la escogida en grande arriba. Es la disposición de
   cualquier visor de coordinación, y por eso no hay que explicarla. */
.tiras { display: flex; gap: 8px; overflow-x: auto; padding: 4px 2px 10px; }
.tira {
  flex: 0 0 148px; display: flex; flex-direction: column; gap: 6px; padding: 6px;
  background: var(--fondo-2); border: 1px solid var(--linea); border-radius: var(--r);
  cursor: pointer; text-align: left; font: inherit; color: inherit;
}
.tira:hover { border-color: var(--acc); }
.tira.sel { border-color: var(--acc); box-shadow: 0 0 0 2px color-mix(in srgb, var(--acc) 25%, transparent); }
.tira img { width: 100%; height: 84px; object-fit: cover; border-radius: 3px; background: var(--fondo); }
.tira span { font-size: 11px; line-height: 1.25; color: var(--txt-2); }
.visor-lienzo #vista-grande { width: 100%; max-height: min(62vh, 700px); object-fit: contain; }


/* ── El aviso de la señal ──────────────────────────────────────
   Fijo abajo y no arriba: en un teléfono, arriba está la barra del
   sistema y el pulgar no llega. Y con `env(safe-area-inset-bottom)`
   porque en un iPhone la barra de inicio se come esos píxeles.

   No es un adorno: es la única señal de que lo que acaba de hacer el
   maestro está guardado en su teléfono y todavía no en la obra. */
#senal {
  position: fixed;
  left: 12px; right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  /* ⚠ POR DEBAJO DEL CAJÓN DE DETALLE (60) Y DE LOS MODALES (70).
     Tenía 60, el mismo que `#desglose`, y como se añade al final del
     documento ganaba el empate: se pintaba encima del pie del cajón y
     tapaba tres de sus cinco botones —Corregir, Suspender, Liquidar—,
     que además está anclado abajo y no se puede desplazar para
     esquivarlo. Los botones quedaban muertos: el clic se lo comía el
     aviso.

     Y este aviso solo aparece cuando NO HAY SEÑAL o hay cola pendiente,
     o sea justo en la obra, que es el caso para el que se hizo. */
  z-index: 55;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 11px 14px;
  border-radius: 12px;
  font-size: 14px; font-weight: 500;
  box-shadow: 0 6px 24px -8px rgba(0,0,0,.4);
}
#senal .btn { padding: 5px 11px; font-size: 13px; }
#senal b { font-variant-numeric: tabular-nums; }
.senal-sin  { background: var(--crit);  color: #fff; }
.senal-cola { background: var(--warn);  color: #1b1300; }
.senal-ok   { display: none; }
@media (min-width: 900px) {
  /* En escritorio no ocupa el ancho entero: ahí la señal casi nunca
     falta y el aviso sería una franja roja de lado a lado por nada. */
  #senal { left: auto; right: 18px; max-width: 420px; }
}
