/* ==========================================================================
   app.css — Estilos del portal. Depende de tokens.css, que va cargado antes.
   Destino: vasp.cl/assets/app.css

   Sin estilos en línea en el HTML: la CSP no los permite, y esa restricción es
   justamente lo que vuelve inofensivo un dato mal escapado.
   ========================================================================== */

*{box-sizing:border-box}

body{
  margin:0; background:var(--fondo); color:var(--texto);
  font-family:var(--fuente); font-size:var(--txt-base); line-height:var(--txt-lh);
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3{margin:0; color:var(--texto-titulo); font-weight:var(--peso-semi); text-wrap:balance}
h1{font-size:var(--txt-h1); line-height:1.25}
h2{font-size:var(--txt-h2); line-height:1.3}
h3{font-size:var(--txt-h3)}
p{margin:0}
a{color:var(--hik-azul)}
a:hover{color:var(--hik-rojo)}
code{font-family:var(--fuente-mono,ui-monospace,monospace); font-size:.92em}
:focus-visible{outline:2px solid var(--hik-rojo); outline-offset:2px; border-radius:2px}
@media (prefers-reduced-motion:reduce){*{animation:none!important; transition:none!important}}

/* ── Estructura ───────────────────────────────────────────────────────────── */

.app{border-top:3px solid var(--hik-rojo); min-height:100vh}

.topbar{
  height:var(--alto-header); background:var(--fondo);
  border-bottom:1px solid var(--borde);
  display:flex; align-items:center; gap:var(--e4); padding:0 var(--e5);
  position:sticky; top:0; z-index:5;
}
.marca{
  display:flex; align-items:center; gap:var(--e3);
  font-weight:var(--peso-bold); color:var(--texto-titulo); text-decoration:none;
}
.marca:hover{color:var(--texto-titulo)}
.marca small{display:block; font-size:var(--txt-xs); font-weight:var(--peso-normal); color:var(--texto-tenue)}
.marca.vertical{flex-direction:column; text-align:center; gap:var(--e2); margin-bottom:var(--e5)}

.topbar .der{
  margin-left:auto; display:flex; align-items:center; gap:var(--e3);
  font-size:var(--txt-sm); color:var(--texto-suave);
}
.rol{
  font-size:10px; font-weight:var(--peso-bold); letter-spacing:.07em; text-transform:uppercase;
  background:var(--fondo-alt); color:var(--texto-suave); border:1px solid var(--borde);
  padding:2px 6px; border-radius:2px; margin-left:var(--e2);
}

.banner{
  display:flex; align-items:center; gap:var(--e3); flex-wrap:wrap;
  padding:var(--e3) var(--e5); background:#E8EFF7; color:var(--texto);
  border-bottom:1px solid var(--borde); font-size:var(--txt-sm);
}
.banner .etiqueta{
  font-size:10px; font-weight:var(--peso-bold); letter-spacing:.08em; text-transform:uppercase;
  background:var(--hik-azul); color:#fff; padding:3px 7px; border-radius:2px;
}
.banner .salir{margin-left:auto}

.marco-simple{padding:var(--e6) var(--e5) var(--e7); max-width:var(--ancho-max)}
.cabecera{margin-bottom:var(--e5)}
.cabecera p{color:var(--texto-suave); font-size:var(--txt-sm); margin-top:var(--e1)}

/* ── Piezas ───────────────────────────────────────────────────────────────── */

/* ── La tarjeta: una SECCIÓN, no una caja ────────────────────────────────────
   Antes era el patrón de siempre — borde, esquina redondeada y sombra — y con
   seis de ellas apiladas la página se volvía una bandeja de cajas flotando, que
   es lo que hace que todo se parezca a todo.
   Ahora la separa una regla superior gruesa, como en un informe impreso. Cuesta
   menos tinta, ordena mejor, y el peso lo lleva el título. */
.tarjeta{
  background:var(--fondo);
  border:0; border-top:2px solid var(--texto-titulo);
  border-radius:0; box-shadow:none;
  margin-bottom:var(--e6);
}
.tarjeta > .cuerpo{padding:var(--e4) 0 var(--e5)}
.texto{color:var(--texto-suave); max-width:60ch; margin-top:var(--e3)}
.texto:first-child{margin-top:0}

.btn{
  font:inherit; font-size:var(--txt-sm); font-weight:var(--peso-semi);
  padding:9px 18px; border-radius:var(--radio-btn); border:1px solid transparent;
  cursor:pointer; text-decoration:none; display:inline-flex; align-items:center; gap:7px;
}
.btn-p{background:var(--hik-rojo); color:#fff; width:100%; justify-content:center; margin-top:var(--e2)}
.btn-p:hover{background:var(--hik-rojo-oscuro); color:#fff}
.btn-s{background:var(--fondo); color:var(--texto-titulo); border-color:var(--borde-fuerte)}
.btn-s:hover{background:var(--fondo-hover); color:var(--texto-titulo)}
.btn-sm{padding:5px 12px; font-size:13px}
.btn.ancho{width:100%; justify-content:center; margin-top:var(--e4)}

/* ── Pantallas de acceso ──────────────────────────────────────────────────── */

.acceso-body{background:var(--fondo-alt)}
.acceso{
  min-height:100vh; display:flex; align-items:center; justify-content:center;
  padding:var(--e6) var(--e4);
}
.paso{width:100%; max-width:440px}
.login{
  background:var(--fondo); border:1px solid var(--borde); border-top:var(--acento) solid var(--hik-rojo);
  border-radius:var(--radio-card); box-shadow:var(--sombra-card); padding:var(--e6) var(--e5);
}

.campo{margin-bottom:var(--e4)}
.campo label{
  display:block; font-size:13px; font-weight:var(--peso-semi);
  color:var(--texto-titulo); margin-bottom:var(--e1);
}
input[type=text],input[type=email],input[type=password]{
  font:inherit; font-size:var(--txt-sm); padding:9px 12px; width:100%;
  border-radius:var(--radio); border:1px solid var(--borde-fuerte);
  background:var(--fondo); color:var(--texto);
}
input::placeholder{color:var(--texto-tenue)}
input.centrado{
  text-align:center; letter-spacing:.35em; font-size:20px;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
}

.ayuda{font-size:13px; color:var(--texto-tenue); margin-top:var(--e4); text-align:center}
.ayuda.izq{text-align:left; margin-top:var(--e2)}

/* Aviso: filo de color y texto, sin recuadro relleno. Un bloque de color a
   pantalla completa para decir «guardado» es más grito del que hace falta. */
.aviso{
  display:flex; gap:9px; padding:2px 0 2px 12px; border-radius:0;
  font-size:13.5px; margin-bottom:var(--e4);
  background:none; color:var(--error); border:0; border-left:3px solid currentColor;
}
.aviso.ok{color:var(--exito)}
.aviso.neutro{color:var(--texto-suave); border-left-color:var(--borde-fuerte)}

.pasos{margin:var(--e4) 0 0; padding-left:1.15em; color:var(--texto-suave); font-size:var(--txt-sm)}
.pasos li{margin-bottom:var(--e3)}
.pasos code{
  display:inline-block; background:var(--fondo-alt); border:1px solid var(--borde);
  padding:2px 6px; border-radius:2px; color:var(--texto-titulo);
}
.clave-manual{
  display:block!important; margin-top:var(--e2); font-size:16px; letter-spacing:.06em;
  word-break:break-all; padding:10px 12px!important; text-align:center;
}
.pasos .nota{display:block; color:var(--texto-tenue); font-size:12px; margin-top:var(--e1)}

.respaldo{
  list-style:none; margin:var(--e4) 0 0; padding:var(--e4);
  background:var(--fondo-alt); border:1px solid var(--borde); border-radius:var(--radio-card);
  display:grid; grid-template-columns:repeat(2,1fr); gap:var(--e2);
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:16px;
  color:var(--texto-titulo); text-align:center; letter-spacing:.04em;
}
@media (max-width:420px){.respaldo{grid-template-columns:1fr}}

/* El QR va siempre negro sobre blanco, también en tema oscuro: el lector
   necesita ese contraste y la zona de silencio. El marco blanco lo dibuja el
   propio SVG, así que aquí sólo se centra y se le da un borde suave. */
.qr{
  display:flex; justify-content:center; margin:var(--e4) 0 var(--e3);
}
.qr svg{
  border:1px solid var(--borde); border-radius:var(--radio);
  width:240px; height:240px; max-width:100%;
}
.centrado-txt{text-align:center; margin-left:auto; margin-right:auto}

.respaldo-det{margin-top:var(--e4); border-top:1px solid var(--borde); padding-top:var(--e3)}
.respaldo-det summary{
  cursor:pointer; font-size:13px; color:var(--texto-suave); font-weight:var(--peso-semi);
}
.respaldo-det[open] summary{margin-bottom:var(--e3)}

/* ── Lista de clientes (usuarios internos) ────────────────────────────────── */

.lista-clientes{
  list-style:none; margin:0; padding:0; display:grid; gap:1px;
  background:var(--borde); border:1px solid var(--borde);
  border-radius:var(--radio-card); overflow:hidden;
}
.lista-clientes a{
  display:flex; align-items:center; gap:var(--e3); padding:13px 16px;
  background:var(--fondo); text-decoration:none; color:var(--texto-titulo);
}
.lista-clientes a:hover{background:var(--fondo-hover); color:var(--texto-titulo)}
.lista-clientes .n{font-weight:var(--peso-semi); flex:1}
.lista-clientes .t{
  font-size:10px; font-weight:var(--peso-bold); letter-spacing:.08em;
  color:var(--texto-tenue); border:1px solid var(--borde); padding:2px 6px; border-radius:2px;
}

/* ── Barras de indicadores ───────────────────────────────────────────────────
   El ancho va por clase y no por style="" porque la CSP del portal no admite
   estilos en línea. En pasos de 5% basta: nadie mide una barra con regla. */
.barras{display:grid; gap:11px}
.barra{display:grid; grid-template-columns:150px minmax(0,1fr) 44px; gap:12px; align-items:center; font-size:13px}
.barra .e{color:var(--texto-suave); text-align:right; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.barra .pista{background:var(--fondo-alt); border-radius:2px; height:22px; overflow:hidden}
.barra .v{display:block; height:100%; border-radius:2px; background:var(--borde-fuerte)}
.barra .n{font-variant-numeric:tabular-nums; color:var(--texto-titulo); font-weight:var(--peso-semi); text-align:right}
.barra .v.e1{background:var(--borde-fuerte)}
.barra .v.e2{background:var(--hik-azul)}
.barra .v.e3{background:var(--alerta)}
.barra .v.e4{background:var(--biz-cctv)}
.barra .v.e5{background:var(--exito)}
.barra .v.e6{background:var(--texto-tenue)}
.w0{width:0%}
.w5{width:5%}
.w10{width:10%}
.w15{width:15%}
.w20{width:20%}
.w25{width:25%}
.w30{width:30%}
.w35{width:35%}
.w40{width:40%}
.w45{width:45%}
.w50{width:50%}
.w55{width:55%}
.w60{width:60%}
.w65{width:65%}
.w70{width:70%}
.w75{width:75%}
.w80{width:80%}
.w85{width:85%}
.w90{width:90%}
.w95{width:95%}
.w100{width:100%}

/* ── Marco con menú lateral ───────────────────────────────────────────────── */
.marco{display:grid; grid-template-columns:212px minmax(0,1fr); min-height:60vh}
@media (max-width:820px){.marco{grid-template-columns:1fr}}
.lateral{background:var(--fondo-alt); border-right:1px solid var(--borde); padding:var(--e4) 0}
@media (max-width:820px){
  .lateral{display:flex; gap:4px; overflow-x:auto; padding:var(--e2) var(--e3);
           border-right:0; border-bottom:1px solid var(--borde)}
}
.nav-t{font-size:11px;
       color:var(--texto-tenue); padding:0 var(--e5) var(--e2); font-weight:var(--peso-bold)}
@media (max-width:820px){.nav-t{display:none}}
.nav{display:flex; flex-direction:column}
@media (max-width:820px){.nav{flex-direction:row; gap:4px}}
.nav a{display:flex; align-items:center; padding:9px var(--e5); color:var(--texto-suave);
       text-decoration:none; font-size:var(--txt-sm);
       border-left:var(--acento) solid transparent;
       white-space:nowrap}
.nav a:hover{background:var(--fondo-hover); color:var(--texto-titulo)}
.nav a[aria-current="page"]{background:var(--fondo); color:var(--texto-titulo);
       font-weight:var(--peso-semi); border-left-color:var(--hik-rojo)}

/* ── El elemento seleccionado del menú ──────────────────────────────────────
   Bloque gris oscuro, texto blanco y el filo rojo más ancho que el resto.
   Antes era fondo blanco con texto oscuro y un filo de 4px: se distinguía del
   vecino por muy poco, y en una lista de siete no se encontraba de un vistazo.
   El rojo se ensancha aquí y solo aquí — un acento que mide igual que los
   demás no está acentuando nada. */
.nav a[aria-current="page"]{
  background:var(--sel-fondo); color:var(--texto-inverso);
  border-left-width:7px;
}
.nav a[aria-current="page"]:hover{background:var(--sel-fondo); color:var(--texto-inverso)}
@media (max-width:820px){
  .nav a[aria-current="page"]{border-left-width:0; border-bottom-width:7px}
}
@media (max-width:820px){
  .nav a{border-left:0; border-bottom:var(--acento) solid transparent;
         border-radius:var(--radio); padding:8px 12px}
  .nav a[aria-current="page"]{border-left:0; border-bottom-color:var(--hik-rojo)}
}
.lienzo{padding:var(--e5) var(--e5) var(--e7); max-width:var(--ancho-max); min-width:0}
@media (max-width:600px){.lienzo{padding:var(--e4) var(--e3) var(--e6)}}

.cabecera{display:flex; align-items:flex-end; justify-content:space-between;
          gap:var(--e4); flex-wrap:wrap; margin-bottom:var(--e5)}

/* ── Tarjetas y tablas ────────────────────────────────────────────────────── */
/* La cabecera ya no necesita su propia línea abajo: la regla de arriba separa. */
.tarjeta > .cab{padding:var(--e3) 0 var(--e3); border-bottom:0;
                display:flex; align-items:center; justify-content:space-between; gap:var(--e3)}
.tarjeta > .cab a{font-size:13px}

.tabla-cont{overflow-x:auto}
table{width:100%; border-collapse:collapse; font-size:var(--txt-sm)}
/* Cabecera de tabla: una regla debajo, no una banda gris. Es como se marca una
   cabecera en un informe impreso, y quita un bloque de color que competía con
   los datos. Sin mayúsculas: se leen peor y son la firma de cualquier panel
   generado. */
th{text-align:left; font-size:12px; color:var(--texto-tenue);
   font-weight:var(--peso-semi); padding:8px 14px 8px 0;
   background:none; border-bottom:1px solid var(--texto-titulo); white-space:nowrap}
th:last-child{padding-right:0}
td{padding:11px 14px 11px 0; border-bottom:1px solid var(--borde); vertical-align:top}
td:last-child{padding-right:0}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:var(--fondo-hover)}
.nomb{color:var(--texto-titulo); font-weight:var(--peso-semi); text-decoration:none}
.nomb:hover{color:var(--hik-rojo)}
.num{font-family:var(--fuente-mono); font-size:12.5px; color:var(--texto-suave); white-space:nowrap}
.num.grande{font-size:14px; margin-bottom:var(--e4)}
.fecha{font-variant-numeric:tabular-nums; color:var(--texto-suave); white-space:nowrap}

/* ── Indicadores de cabecera ──────────────────────────────────────────────── */
/* ── Cifras: columnas separadas por aire, no cajas ───────────────────────────
   La fila de tarjetas KPI con etiqueta en mayúsculas, número enorme y leyenda
   gris es la firma visual de cualquier página generada hoy. El dato es el mismo;
   lo que sobra es el marco. Una regla fina arriba y espacio entre columnas dice
   lo mismo sin el envoltorio. */
.tiles{display:grid; grid-template-columns:repeat(auto-fit,minmax(178px,1fr));
       gap:var(--e3) var(--e6); margin-bottom:var(--e6)}
.tile{background:none; border:0; border-top:1px solid var(--borde-fuerte);
      border-radius:0; box-shadow:none; padding:var(--e3) 0 0}
/* El acento va en la regla, no en un filo lateral pegado a una caja. */
.tile.acento{border-top:var(--acento) solid var(--hik-rojo)}
.tile .et{font-size:12px; color:var(--texto-suave)}
.tile .n{font-size:30px; font-weight:var(--peso-bold); color:var(--texto-titulo);
         line-height:1.15; margin-top:var(--e1); font-variant-numeric:tabular-nums}
.tile .pie{font-size:12px; color:var(--texto-tenue); margin-top:2px}

/* ── Píldoras de etapa ────────────────────────────────────────────────────── */
/* ── Estado: una marca, no una cápsula ───────────────────────────────────────
   La píldora redondeada con punto es de las formas más repetidas que hay. Aquí
   el estado se marca con un filo de color a la izquierda y el texto en su tono,
   sin fondo: pesa menos, se lee igual, y deja de competir con las etapas de la
   barra del pipeline, que ya usan color con otro significado. */
.pill{display:inline-flex; align-items:center; font-size:12.5px;
      font-weight:var(--peso-semi); padding:1px 0 1px 9px; border-radius:0;
      white-space:nowrap; border-left:3px solid currentColor; background:none !important}
.p-eval{color:var(--texto-suave)}
.p-cot{color:var(--hik-azul)}
.p-lic{color:var(--alerta)}
.p-orden{color:var(--biz-cctv)}
.p-ent{color:var(--exito)}
.p-cerrado{color:var(--texto-tenue)}

/* ── Filtros ──────────────────────────────────────────────────────────────── */
.filtros{display:flex; flex-wrap:wrap; gap:var(--e2); margin-bottom:var(--e4); align-items:center}
.filtros .busca{flex:1; min-width:180px; max-width:280px}
select{font:inherit; font-size:var(--txt-sm); padding:8px 11px; border-radius:var(--radio);
       border:1px solid var(--borde-fuerte); background:var(--fondo); color:var(--texto)}
.check{display:inline-flex; align-items:center; gap:7px; font-size:13px; color:var(--texto-suave)}
.check input{width:auto}

/* ── Ficha de proyecto ────────────────────────────────────────────────────── */
.dosCol{display:grid; grid-template-columns:minmax(0,1.4fr) minmax(0,1fr); gap:var(--e4)}
@media (max-width:900px){.dosCol{grid-template-columns:1fr}}
/* Acotado a `div`: `.datos` nació como rejilla de pares etiqueta/valor, y
   después se usó el mismo nombre en varias <table>. Sin el `div`, ese
   display:grid convertía esas tablas en rejillas y les rompia la maquetación. */
div.datos{display:grid; gap:var(--e3)}
div.datos > div{display:flex; align-items:center; gap:var(--e3); flex-wrap:wrap}
div.datos .et{font-size:12px; color:var(--texto-tenue); min-width:110px}
h3.sub{margin-top:var(--e5); margin-bottom:var(--e2); color:var(--texto-titulo);
       font-size:var(--txt-sm); font-weight:var(--peso-bold)}
.chips{display:flex; flex-wrap:wrap; gap:5px}
.chip{font-size:11.5px; padding:2px 8px; border-radius:2px; background:none;
      color:var(--texto-suave); border:1px solid var(--borde)}

.hitos{list-style:none; margin:0; padding:0; position:relative}
.hitos::before{content:""; position:absolute; left:7px; top:8px; bottom:8px;
               width:2px; background:var(--borde)}
.hitos li{position:relative; padding:0 0 var(--e4) 28px; font-size:var(--txt-sm)}
.hitos li:last-child{padding-bottom:0}
.hitos .m{position:absolute; left:0; top:3px; width:16px; height:16px; border-radius:50%;
          background:var(--fondo); border:2px solid var(--borde-fuerte)}
.hitos li.listo .m{background:var(--exito); border-color:var(--exito)}
.hitos li.curso .m{border-color:var(--hik-rojo)}
.hitos .t{color:var(--texto-titulo); font-weight:var(--peso-semi)}
.hitos .f{color:var(--texto-tenue); font-size:12.5px; font-variant-numeric:tabular-nums}

/* ── Avisos ───────────────────────────────────────────────────────────────── */
.avisos{display:grid; gap:var(--e4)}
.avi{display:flex; gap:var(--e3); align-items:flex-start}
.avi .b{width:3px; align-self:stretch; border-radius:2px; background:var(--hik-rojo); flex-shrink:0}
.avi .f{font-size:12px; color:var(--texto-tenue); font-variant-numeric:tabular-nums}
.avi .t{color:var(--texto-titulo); font-weight:var(--peso-semi); font-size:var(--txt-sm)}
.avi p{color:var(--texto-suave); font-size:13.5px; margin-top:2px}

/* ── Administración ───────────────────────────────────────────────────────── */
/* Una barra de pestañas NO se parte en dos filas: se queda en una línea y se
   desliza. Es lo que hace hikvision.com —`flex-wrap:nowrap` con desplazamiento
   lateral, comprobado el 2026-09-02 en core-technologies—, y es lo correcto
   aparte de la marca: partidas en dos filas dejan de leerse como un grupo de
   iguales y la segunda fila parece otra cosa.
   Ellos lo mueven con un carrusel en JavaScript; aquí la CSP no admite script
   embebido, y tampoco hace falta: el desbordamiento nativo hace lo mismo y
   además funciona con teclado y con gesto táctil. */
.subnav{display:flex; gap:2px; flex-wrap:nowrap; margin-bottom:var(--e5);
        border-bottom:1px solid var(--borde);
        overflow-x:auto; overscroll-behavior-x:contain}
/* Sin este `flex-shrink`, en lugar de desbordar se comprimirían los textos
   hasta partirse por la mitad. */
.subnav a{flex:0 0 auto}
.subnav a{padding:9px 0; margin-right:22px; text-decoration:none; color:var(--texto-suave);
          font-size:var(--txt-sm); border-bottom:var(--acento) solid transparent;
          margin-bottom:-1px}
.subnav a:hover{color:var(--texto-titulo)}
/* 3px y no 2. El acento vive justo encima de la regla superior de la primera
   tarjeta, que es negra y de ancho completo: a 2px, setenta píxeles de rojo
   contra una barra que cruza la pantalla, y el rojo desaparece. No era un
   color mal elegido, era una competencia perdida. */
.subnav a.activo{color:var(--texto-titulo); font-weight:var(--peso-semi);
                 border-bottom-color:var(--hik-rojo)}

.espacio{margin-top:var(--e5)}
.tenue{color:var(--texto-tenue)}
.recorte{font-size:12.5px; max-width:52ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}

.formulario{max-width:520px}
.formulario.ancho{max-width:none}
.rejilla{display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:var(--e4)}
.formulario textarea{
  font:inherit; font-size:var(--txt-sm); padding:9px 12px; width:100%;
  border-radius:var(--radio); border:1px solid var(--borde-fuerte);
  background:var(--fondo); color:var(--texto); resize:vertical;
}
.btn.corto{width:auto; justify-content:center}
input.corto{width:auto; min-width:190px}

.enlinea{display:inline-flex; align-items:center; gap:6px; margin:0}
.acciones{display:flex; gap:6px; flex-wrap:wrap}
.filtros.compacto{margin:0}

.alias-lista{list-style:none; margin:0 0 var(--e4); padding:0; display:grid; gap:var(--e2)}
.alias-lista li{display:flex; align-items:center; gap:var(--e2); flex-wrap:wrap;
                padding:8px 10px; background:var(--fondo-alt); border-radius:var(--radio)}
.alias-lista li .num{flex:1; white-space:normal; word-break:break-word}

/* La contraseña provisional: grande, legible y de un solo uso. */
.clave-provisional{
  font-family:var(--fuente-mono); font-size:22px; letter-spacing:.08em;
  text-align:center; padding:var(--e4); margin:var(--e4) 0;
  background:var(--fondo-alt); border:1px solid var(--borde-fuerte);
  border-radius:var(--radio-card); color:var(--texto-titulo); word-break:break-all;
}

.paginador{display:flex; align-items:center; gap:var(--e3); justify-content:center;
           padding:var(--e3); border-top:1px solid var(--borde); font-size:13px}

/* ── Documentos ───────────────────────────────────────────────────────────── */
.docs{display:grid; gap:1px; background:var(--borde); border-radius:var(--radio-card);
      overflow:hidden; border:1px solid var(--borde)}
.doc{background:var(--fondo); padding:14px 16px; display:flex; align-items:center;
     gap:var(--e3); flex-wrap:wrap}
.doc:hover{background:var(--fondo-hover)}
.doc .ic{width:38px; height:38px; border-radius:var(--radio); display:grid; place-items:center;
         font-size:11px; font-weight:var(--peso-bold); color:#fff; flex-shrink:0;
         background:var(--texto-tenue)}
.doc .ic.f-pdf{background:var(--hik-rojo)}
.doc .ic.f-ppt{background:var(--alerta)}
.doc .ic.f-doc{background:var(--hik-azul)}
.doc .ic.f-xls{background:var(--exito)}
.doc .ic.f-img{background:var(--biz-cctv)}
.doc .meta{flex:1; min-width:180px}
.doc .meta .t{color:var(--texto-titulo); font-weight:var(--peso-semi); font-size:var(--txt-sm)}
.doc .meta .s{color:var(--texto-tenue); font-size:12.5px; font-variant-numeric:tabular-nums}
input[type=file]{font:inherit; font-size:13px; color:var(--texto-suave)}

/* ── Productos de un proyecto ─────────────────────────────────────────────── */
.dosCol.ficha{grid-template-columns:minmax(0,1.9fr) minmax(0,1fr)}
@media (max-width:900px){.dosCol.ficha{grid-template-columns:1fr}}
table.productos{font-size:13px}
table.productos td{padding:7px 12px; border-bottom:0}
table.productos tr.grupo td{border-top:1px solid var(--borde); padding-top:12px}
table.productos tr.grupo:first-child td{border-top:0}
table.productos tbody tr:hover{background:transparent}
table.productos td:first-child{white-space:nowrap; color:var(--texto-titulo);
                               font-weight:var(--peso-semi)}
.biz{display:inline-block; width:8px; height:8px; border-radius:2px; margin-right:7px;
     vertical-align:baseline; background:var(--texto-tenue)}
.b-cctv{background:var(--biz-cctv)}
.b-noncctv{background:var(--biz-noncctv)}
.b-newbusiness{background:var(--biz-new)}
.b-software{background:var(--biz-software)}
.b-thermalproducts{background:var(--biz-thermal)}
.b-accessories{background:var(--biz-accesorios)}
.b-service{background:var(--biz-servicio)}
.b-rawmaterial{background:var(--biz-raw)}

table.productos td.der, table.productos th.der{text-align:right}
table.productos td.cant{font-variant-numeric:tabular-nums; color:var(--texto-titulo);
                        font-weight:var(--peso-semi); white-space:nowrap}
table.productos .linea{font-size:12px; font-weight:var(--peso-normal); margin-top:2px}
table.productos td:first-child{white-space:normal}

.apps{margin:var(--e3) 0 0; padding-left:1.15em; color:var(--texto-suave); font-size:var(--txt-sm)}
.apps li{margin-bottom:var(--e2)}

/* ═══ Marca VASP ═══════════════════════════════════════════════════════════
   Lockup tipográfico. Cuando llegue el arte oficial del portal de marca de
   Hikvision, el <span class="wm"> pasa a ser un <img> y esta regla se cambia
   por un ancho: el resto del lockup no se entera. */
.marca .wm{
  font-size:21px; font-weight:var(--peso-bold); letter-spacing:.055em;
  color:var(--hik-rojo); line-height:1; flex-shrink:0;
}
.marca-t{display:block; line-height:1.25}
.marca.vertical .wm{font-size:30px; letter-spacing:.07em}

/* ═══ Formulario de solicitud ══════════════════════════════════════════════ */

/* Lo oculta el JS de las cascadas. Sin JS no se aplica nunca, y entonces se
   ven todos los campos: más largo, pero completo. */
.oculto{display:none}

.solicitud{max-width:640px}
.solicitud fieldset{
  border:0; border-top:1px solid var(--borde); padding:var(--e5) 0 0;
  margin:var(--e6) 0 0;
}
.solicitud fieldset:first-of-type{border-top:0; margin-top:var(--e4); padding-top:0}
/* La leyenda del grupo es un título pequeño, no una etiqueta gritada. */
.solicitud legend{
  font-size:var(--txt-sm); font-weight:var(--peso-bold);
  color:var(--texto-titulo); padding:0 0 var(--e3);
}

/* Dos campos a lo ancho, en partes iguales. Se apilan en pantalla angosta. */
.par{display:grid; grid-template-columns:1fr 1fr; gap:var(--e4)}
@media (max-width:620px){.par{grid-template-columns:1fr}}

/* Monto y moneda, pegados: son un solo dato. */
.junto{display:flex; gap:var(--e2)}
.junto select{flex:0 0 auto}

/* Etiqueta de un grupo (radios, casillas) que no puede ser un <label>, porque
   un <label> apunta a un control y aquí hay varios. */
.campo .label{
  display:block; font-size:13px; font-weight:var(--peso-semi);
  color:var(--texto-titulo); margin-bottom:var(--e1);
}
.req{color:var(--hik-rojo); font-weight:var(--peso-normal)}
.err{color:var(--error); font-size:12.5px; margin-top:var(--e1)}
.campo .ayuda.izq{margin-top:var(--e1)}

.opciones{display:flex; gap:var(--e4); margin-top:var(--e1)}
.rejilla-check{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
  gap:6px var(--e3); margin-top:var(--e2);
}

/* ═══ Estado de una solicitud ══════════════════════════════════════════════
   Nombres propios (.etapas-sol) y no .pasos, que ya existe con otro sentido:
   la lista numerada del enrolamiento del segundo factor. */
.etapas-sol{display:flex; flex-wrap:wrap; gap:6px; margin-bottom:var(--e5)}
.etapa-sol{
  font-size:12px; padding:5px 11px; border-radius:2px;
  background:var(--fondo-alt); color:var(--texto-tenue); border:1px solid var(--borde);
}
.etapa-sol.hecho{color:var(--texto-suave)}
.etapa-sol.actual{
  background:var(--hik-rojo); border-color:var(--hik-rojo);
  color:#fff; font-weight:var(--peso-semi);
}
.etapa-sol.pend{opacity:.55}

/* "Cerrada" no es un error: .aviso a secas es rojo, y esto lo devuelve a un
   tono informativo. */
.aviso.neutro{background:var(--fondo-alt); color:var(--texto-suave); border-color:var(--borde)}

/* ═══ Ficha de datos ═══════════════════════════════════════════════════════ */
.ficha-dl{padding:var(--e4) 0; display:grid; grid-template-columns:auto 1fr; gap:var(--e3) var(--e5)}
.ficha-dl dt{
  font-size:12.5px; font-weight:var(--peso-semi); color:var(--texto-tenue);
  white-space:nowrap;
}
.ficha-dl dd{font-size:var(--txt-sm); color:var(--texto); min-width:0}
.ficha-dl dd .texto{margin-top:0; white-space:pre-line}
@media (max-width:620px){
  .ficha-dl{grid-template-columns:1fr; gap:var(--e1)}
  .ficha-dl dd{margin-bottom:var(--e3)}
}

.vacio{padding:var(--e6) var(--e5); text-align:center; color:var(--texto-suave)}
.chip-ojo{background:#FFF4E5; color:#8A5300}

/* Contador de solicitudes pendientes en la barra superior. */
.topbar .cuenta{
  display:inline-block; min-width:16px; padding:0 4px; margin-left:4px;
  border-radius:8px; background:var(--hik-rojo); color:#fff;
  font-size:11px; font-weight:var(--peso-semi); text-align:center;
  font-variant-numeric:tabular-nums;
}

/* Segundo nivel de pestañas dentro de una sección de administración. */
.subnav.sub2{margin:var(--e4) 0 var(--e3); font-size:var(--txt-xs)}
/* Fila de un valor de catálogo que está oculto: sigue ahí, pero apagado. */
tr.apagada td{opacity:.5}

/* Campo corto en línea, para el nombre del CRM en la lista de usuarios. */
.acciones input.crm{width:auto; font-size:12px; padding:5px 8px}

/* Etiqueta de categoría de una noticia. Colores distintos para que se separen
   de un vistazo, sin competir con el rojo de la marca. */
.chip.cat-gen{background:var(--fondo-alt); color:var(--texto-suave)}
.chip.cat-cap{background:#E8F0FE; color:#1A56A8}
.chip.cat-cert{background:#E7F5F0; color:#0F7554}
.avi .f .chip{margin-right:6px; vertical-align:middle}

/* ── Ficha de la cuenta en el inicio ─────────────────────────────────────── */
.ficha-cuenta .cuerpo{padding:var(--e4) 0}
.fc-fila{display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:var(--e5)}
/* Sin mayúsculas espaciadas: es el otro tic de las páginas generadas, y además
   se lee peor. Basta el tamaño y el color para que sea una etiqueta. */
.fc-bloque .et{
  font-size:var(--txt-xs); color:var(--texto-tenue);
  font-weight:var(--peso-semi); margin-bottom:4px;
}
.fc-bloque .n{
  font-size:var(--txt-h3); font-weight:var(--peso-semi);
  color:var(--texto-titulo); line-height:1.2;
}
.fc-bloque .n .fc-u{font-size:var(--txt-sm); font-weight:var(--peso-normal); color:var(--texto-suave)}
.fc-bloque a{font-size:var(--txt-sm); display:inline-block; margin-top:3px}
.fc-detalle{font-size:12px; margin-top:3px}
.fc-alerta{
  font-size:12px; font-weight:var(--peso-semi); color:var(--error); margin-top:5px;
}
.chip.chip-clasif{background:var(--hik-rojo); color:#fff; font-weight:var(--peso-bold)}
.chip.chip-key{background:#FFF4E5; color:#8A5300; font-weight:var(--peso-semi)}

/* Vigencia de una certificación. */
.cert-vencida{color:var(--error); font-weight:var(--peso-semi)}
.cert-pronto{color:#8A5300; font-weight:var(--peso-semi)}

/* Un paso del recorrido que aún no ha ocurrido: presente, pero apagado. */
.hitos li.pend .t{color:var(--texto-tenue); font-weight:var(--peso-normal)}
.hitos li.pend .m{border-color:var(--borde); background:var(--fondo)}
.hitos .sinf{font-style:italic; opacity:.7}

/* Logotipo oficial de VASP. La altura la fija el lockup, no el archivo: así una
   imagen de 2000px de ancho no rompe la barra. */
.marca .wm-img{height:22px; width:auto; display:block; flex-shrink:0}
.marca.vertical .wm-img{height:34px}

/* Cabecera de tabla que ordena al pulsarla. */
th a.ord{color:inherit; text-decoration:none; display:inline-block; white-space:nowrap}
th a.ord:hover{color:var(--hik-rojo)}
th.ord-activo a.ord{color:var(--texto-titulo); font-weight:var(--peso-bold)}

/* ── Gráfico anual de puntos ─────────────────────────────────────────────── */
.graf{width:100%; height:auto; display:block; margin-bottom:var(--e3)}
.graf .g-reja{stroke:var(--borde); stroke-width:1}
.graf .g-barra{fill:var(--hik-rojo)}
.graf .g-barra.g-ref{fill:var(--borde-fuerte)}
.graf .g-linea{fill:none; stroke:var(--hik-azul); stroke-width:2.5;
  stroke-linecap:round; stroke-linejoin:round}
.graf .g-nodo{fill:var(--fondo); stroke:var(--hik-azul); stroke-width:2.5}
.graf text{font-family:var(--fuente); text-anchor:middle}
.graf .g-anio{font-size:11px; fill:var(--texto-suave)}
.graf .g-anio.g-ref-txt{fill:var(--texto-tenue)}
.graf .g-valor{font-size:10px; fill:#fff; font-weight:600; font-variant-numeric:tabular-nums}
/* En las barras de años de referencia, que son grises claras, el blanco no se
   lee: ahí el número va oscuro. */
.graf .g-valor.g-ref-val{fill:var(--texto-titulo)}
.graf .g-num{font-size:10px; fill:var(--hik-azul); font-weight:600}
.graf .g-eje{font-size:10.5px}
.graf .g-eje-p{fill:var(--hik-rojo)}
.graf .g-eje-n{fill:var(--hik-azul)}

.leyenda{font-size:12px; color:var(--texto-suave); display:flex; align-items:center; gap:6px}
.leyenda .lg{display:inline-block; width:14px; height:10px; border-radius:2px}
.leyenda .lg-barra{background:var(--hik-rojo)}
.leyenda .lg-linea{background:var(--hik-azul); height:3px; margin-left:var(--e3)}

/* «3 de 12»: el número grande manda, el total acompaña. */
.tile .tile-de{font-size:var(--txt-sm); font-weight:var(--peso-normal);
  color:var(--texto-tenue); margin-left:5px}

/* ── El pipeline como un solo objeto ─────────────────────────────────────────
   Reemplaza la fila de cuatro tarjetas KPI. Cuatro cajas iguales no dicen qué
   mirar primero; una barra en proporción muestra dónde se acumula el trabajo. */
.pipeline{margin-bottom:var(--e5)}
/* Con separación entre tramos, no pegados: dos rojos vecinos se funden y el
   límite deja de verse. El color no debe ser lo único que distingue. */
.pipe-barra{display:flex; gap:2px; height:38px}
.pipe-barra > :first-child{border-radius:3px 0 0 3px}
.pipe-barra > :last-child{border-radius:0 3px 3px 0}
.pipe-barra > :only-child{border-radius:3px}
/* El número vive DENTRO de su tramo y la etiqueta justo debajo, alineada con él
   por las mismas clases de ancho.
   Se quitó la leyenda con cuadritos de color: el tramo que la etiqueta tiene
   encima YA es el color, y repetirlo era decir lo mismo dos veces. */
.pipe-seg{
  display:flex; align-items:center; justify-content:center;
  font-size:14px; font-weight:var(--peso-bold); color:#fff;
  min-width:2px; flex-shrink:0;
}
/* El rosa claro no da contraste con blanco: ahí el número va oscuro. */
/* Una escala del rojo de marca, de más lejos del cierre a más cerca. Ya no hay
   tramo negro: la orden recibida salió de la barra y se escribe debajo. */
.pipe-seg.e1{background:#F0A5AB; color:var(--texto-titulo)}
.pipe-seg.e2{background:#E24A57}
.pipe-seg.e3{background:var(--hik-rojo)}

/* El último tramo no lleva ancho: crece hasta llenar lo que el redondeo a pasos
   de 5% dejó fuera, y la barra cierra exacta. */
.pipe-resto{flex:1 1 auto; min-width:46px}

.pipe-pies{display:flex; gap:2px; margin-top:6px}
.pipe-pie{
  font-size:12.5px; color:var(--texto-suave); text-align:center;
  padding:0 4px; flex-shrink:0; line-height:1.3;
}
/* Sin nowrap ni recorte: en un tramo angosto la etiqueta se parte en dos
   líneas, y eso se lee. Cortarla con puntos suspensivos, no. */


/* Dos frases, no una: la orden recibida y lo entregado son cosas distintas, y
   se leen como frases, no como tarjetas. */
.pipe-cierre{
  margin-top:16px; padding-top:12px; border-top:1px solid var(--borde);
  display:flex; flex-wrap:wrap; gap:4px var(--e6);
}
.pipe-cierre p{display:flex; align-items:baseline; gap:9px; margin:0}
.pipe-nota{margin-top:10px; font-size:12px; color:var(--texto-tenue)}
.pipe-cierre .n{
  font-size:var(--txt-h2); font-weight:var(--peso-bold);
  color:var(--texto-titulo); font-variant-numeric:tabular-nums;
}
.pipe-cierre .t{font-size:var(--txt-sm); color:var(--texto-suave)}

/* En pantalla angosta los pies no caben en su tramo: se apilan bajo la barra. */

/* ── Cierre del cambio de lenguaje ───────────────────────────────────────────
   Tres reglas que valen para todo el portal y evitan tener que repetirlas. */

/* Cualquier celda numérica alineada y con cifras de ancho fijo: en una columna
   de números, que no bailen es la diferencia entre una tabla y un listado. */
.datos td.fecha, .datos td.num, .tile .n {
  font-variant-numeric: tabular-nums;
}

/* El título de sección es lo que carga el peso ahora que no hay caja. */
.tarjeta > .cab h2{font-size:var(--txt-h3); font-weight:var(--peso-bold); letter-spacing:-.01em}

/* Las tablas dentro de una sección ya no van pegadas a un borde: respiran
   contra la regla de arriba. */
.tarjeta > .tabla-cont{margin-top:var(--e2)}

/* Fecha estimada ya pasada: en rojo. Es lo único de la lista sobre lo que el
   cliente puede querer preguntar hoy, así que tiene que saltar. */
.fecha.atrasada{color:var(--error); font-weight:var(--peso-semi)}

/* Conjuntos de casillas en la tabla de Accesos (tipos de cliente, nivel VASP).
   En línea y pequeñas: son siete casillas por fila, y apiladas convertirían una
   tabla de veinte módulos en una pantalla de scroll. */
.conjunto{white-space:nowrap}
.conjunto label{
  display:inline-flex; align-items:center; gap:3px;
  margin-right:9px; font-size:12px; color:var(--texto-tenue);
}
.conjunto input{margin:0}

/* ── Noticias: enlaces y plegado ────────────────────────────────────────────
   El plegado es `<details>` nativo. La CSP prohíbe JavaScript en línea, y para
   abrir y cerrar un bloque no hace falta ninguno. */
.enlace{
  color:var(--hik-azul); text-decoration:underline;
  text-underline-offset:2px; word-break:break-word;
}
.enlace:hover{color:var(--hik-celeste)}

.avi-des summary{
  cursor:pointer; list-style:none;
  /* El marcador propio de Safari, aparte del de list-style. */
}
.avi-des summary::-webkit-details-marker{display:none}
.avi-des summary:focus-visible{outline:2px solid var(--hik-azul); outline-offset:3px}

.avi-corto{margin:0; color:var(--texto-tenue)}
.avi-largo{margin:6px 0 0}

/* Un control, no un texto. Como texto suelto no se leía como algo que se pueda
   pulsar — y con la noticia abierta, «Contraer» quedaba arriba mientras el
   cliente terminaba de leer abajo, sin nada evidente que tocar. Con forma de
   botón y un chevrón que gira, se reconoce sin explicarlo. */
.avi-mas{
  display:inline-flex; align-items:center; gap:6px;
  margin-top:var(--e2); padding:4px 10px;
  border:1px solid var(--borde-fuerte); border-radius:2px;
  background:var(--fondo);
  font-size:12px; font-weight:var(--peso-semi); color:var(--hik-azul);
}
.avi-des summary:hover .avi-mas{
  border-color:var(--hik-azul); background:var(--fondo-hover);
}

/* Dibujado con bordes: ni fuente de iconos ni archivo que cargar. */
.chev{
  width:6px; height:6px; margin-top:-3px;
  border-right:2px solid currentColor; border-bottom:2px solid currentColor;
  transform:rotate(45deg);
}
.chev-arriba{margin-top:2px; transform:rotate(-135deg)}

/* Abierta, el extracto sobra: lo que se lee es el cuerpo entero. Y el rótulo
   cambia de "Leer más" a "Leer menos" enseñando el otro, no ocultando los dos:
   sin nada en qué pulsar, una noticia abierta ya no se podía cerrar. */
.avi-des[open] .avi-corto{display:none}
.avi-cerrar{display:none}
.avi-des[open] .avi-abrir{display:none}
.avi-des[open] .avi-cerrar{display:inline-flex}

/* ── Noticias: superficie propia ────────────────────────────────────────────
   Todo lo demás del inicio —el pipeline, la ficha, los próximos proyectos— son
   datos DEL cliente, y comparten un mismo lenguaje: bloques separados por una
   regla superior, como un informe impreso. Las noticias no son datos suyos: son
   del portal HACIA él. Con la misma regla que los demás se leían como una
   sección más de su propia información.
   Se separan por superficie y no por borde ni sombra. Volver a la tarjeta
   redondeada con sombra sería recuperar justo el aspecto genérico que quitamos,
   y el rojo aquí es una regla de 2px —un acento—, nunca un fondo. */
.tarjeta.noticias-lado{
  background:var(--fondo-alt);
  border-top-color:var(--hik-rojo);
  padding:0 var(--e4) var(--e3);
  /* Sin esto la rejilla lo estira hasta la altura de la columna de al lado, y
     con dos noticias quedaba un panel de color medio vacío. */
  align-self:start;
}
.tarjeta.noticias-lado > .cab{padding-top:var(--e3)}
.tarjeta.noticias-lado > .cuerpo{padding-bottom:var(--e3)}

/* ── El cartel de una noticia ───────────────────────────────────────────────
   Plegada asoma una franja; abierta se ve entera. Es UNA sola imagen recortada
   por CSS, no dos: duplicarla la descargaría dos veces.
   El velo de abajo dice "hay más" sin escribirlo. Su color lo hereda del bloque
   donde esté, porque en la portada el panel de noticias tiene fondo propio y un
   degradado a blanco ahí se vería como una banda. */
.avi-img-prev{
  display:block; position:relative; margin-top:var(--e3);
  --velo:var(--fondo);
}
.noticias-lado .avi-img-prev{--velo:var(--fondo-alt)}
.avi-img-prev img{
  display:block; width:100%; height:auto;
  border:1px solid var(--borde); background:var(--fondo);
}
.avi-des:not([open]) .avi-img-prev{max-height:96px; overflow:hidden}
.avi-des:not([open]) .avi-img-prev::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:56px;
  background:linear-gradient(to bottom, transparent, var(--velo));
  pointer-events:none;
}

.avi-img-full{
  display:inline-block; margin-top:var(--e2);
  font-size:12px; color:var(--hik-azul);
}
.avi-img-full:hover{text-decoration:underline}

/* Flechas de orden en la lista de noticias. */
.orden-cel{white-space:nowrap; width:1%}
.btn-orden{
  border:1px solid var(--borde-fuerte); background:var(--fondo);
  color:var(--texto-titulo); cursor:pointer;
  width:24px; height:24px; line-height:1; border-radius:2px; padding:0;
}
.btn-orden:hover{border-color:var(--hik-azul); color:var(--hik-azul)}

/* En la edición no hay desplegable que la recorte: se limita a mano para que un
   cartel de 1.600px no ocupe la pantalla entera del formulario. */
.avi-img-prev.editando{max-width:300px; margin-bottom:var(--e2)}

/* ── Lista de integradores del distribuidor ─────────────────────────────────
   Plegada, una línea por integrador. La fila entera es el control: el nombre a
   la izquierda, el recuento empujado a la derecha, y el chevrón girando para
   decir si está abierta. Sin bordes ni sombras — el separador es una regla fina,
   como en el resto del portal. */
.grupo-cta{border-bottom:1px solid var(--borde)}
.grupo-cta summary{
  display:flex; align-items:center; gap:var(--e3);
  padding:var(--e3) var(--e2);
  cursor:pointer; list-style:none;
}
.grupo-cta summary::-webkit-details-marker{display:none}
.grupo-cta summary:hover{background:var(--fondo-hover)}
.grupo-cta summary:focus-visible{outline:2px solid var(--hik-azul); outline-offset:-2px}

/* Chevrón dibujado con bordes: sin fuente de iconos ni archivo que cargar. */
.grupo-cta summary::before{
  content:""; flex:0 0 auto; width:6px; height:6px; margin-left:2px;
  border-right:2px solid var(--texto-tenue);
  border-bottom:2px solid var(--texto-tenue);
  transform:rotate(-45deg); transition:transform .15s ease;
}
.grupo-cta[open] summary::before{transform:rotate(45deg)}
@media (prefers-reduced-motion:reduce){
  .grupo-cta summary::before{transition:none}
}

.grupo-cta .nomb{
  font-weight:var(--peso-semi); color:var(--texto-titulo);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* El recuento se va a la derecha: así todos quedan alineados en columna y se
   comparan de un vistazo, que es para lo que sirve esta lista. */
.grupo-cta .tenue{margin-left:auto; font-size:12px; white-space:nowrap}
.grupo-cta .chip{flex:0 0 auto}

/* La tabla de dentro es secundaria: sangrada, más pequeña y con la cabecera
   apagada. Lo que manda en esta pantalla es la lista de integradores. */
.grupo-cta > .tabla-cont{padding:0 var(--e2) var(--e4) var(--e5)}
.grupo-cta table{font-size:13px}
.grupo-cta thead th{
  font-size:11px; color:var(--texto-tenue);
  border-bottom:1px solid var(--borde); padding-bottom:4px;
}

/* Buscador dentro de la cabecera de una tarjeta: acompaña al título, no manda.
   Por eso es corto y va en línea — un campo a todo lo ancho ahí competiría con
   el h2 y parecería el asunto principal de la pantalla. */
.busca.corta{width:min(240px, 42vw); font-size:13px; padding:5px 9px}
.cab form.enlinea{display:flex; gap:6px; align-items:center; margin:0}

/* El ancla va en la clase, no en el atributo del SVG: `.graf text` fija
   text-anchor:middle por CSS, y el CSS gana a los atributos de presentación —
   escrito en el SVG no haría nada. */
.graf .g-eje.izq{text-anchor:end}
.graf .g-eje.der{text-anchor:start}

/* FOB bajo el eje, cuando la barra es demasiado estrecha para llevarlo dentro.
   En el rojo de las barras: así se sabe a qué serie pertenece sin más leyenda. */
.graf .g-valor-eje{font-size:9px; fill:var(--hik-rojo); font-weight:600;
                   font-variant-numeric:tabular-nums}

/* ═══ Guía de pasos del enrolamiento ═══════════════════════════════════════
   Mismo lenguaje que .etapa-sol —gris el pendiente, rojo el actual— pero con
   nombre propio: aquella dice en qué etapa va una solicitud, y esta en qué paso
   va el usuario. Mezclarlas ataría dos pantallas que no tienen nada que ver.

   Va numerada, y no es adorno: el problema que vino a resolver es que la gente
   se saltaba el paso 1. Ver "1 2 3" antes de empezar avisa de que hay un orden.

   Los números salen de un contador CSS y no del <ol>, porque el marcador nativo
   no se puede meter dentro del círculo. */
.guia{
  display:flex; gap:6px; list-style:none; padding:0;
  margin:0 0 var(--e5); counter-reset:guia;
}
.guia li{
  flex:1 1 0; counter-increment:guia;
  display:flex; align-items:center; justify-content:center; gap:6px;
  font-size:11.5px; padding:6px 4px; border-radius:2px; text-align:center;
  background:var(--fondo-alt); color:var(--texto-tenue); border:1px solid var(--borde);
}
.guia li::before{
  content:counter(guia);
  flex:0 0 auto; width:16px; height:16px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-size:10px; font-weight:var(--peso-semi);
  background:var(--borde); color:var(--texto-suave);
}
.guia li.hecho{color:var(--texto-suave)}
.guia li.hecho::before{
  content:"\2713";                      /* ✓ — el paso cumplido no lleva número */
  background:var(--exito); color:#fff;
}
.guia li.actual{
  background:var(--hik-rojo); border-color:var(--hik-rojo);
  color:#fff; font-weight:var(--peso-semi);
}
.guia li.actual::before{background:#fff; color:var(--hik-rojo)}

/* El título de cada paso. Va después de la guía y antes del texto: sin él, los
   tres pasos se parecen demasiado entre sí al cambiar de pantalla. */
.paso-t{
  font-size:15px; font-weight:var(--peso-semi); color:var(--texto-titulo);
  margin:0 0 var(--e3); line-height:1.35;
}

/* El aviso de lo que todos hacen mal. No es un error —no ha pasado nada aún—,
   así que no usa .aviso, que es rojo y alarma sin motivo. Es una advertencia
   previa, en ámbar, con la barra al costado para que se lea antes que el
   párrafo que la rodea. */
.alerta-suave{
  border-left:3px solid var(--alerta);
  background:var(--fondo-alt);
  padding:var(--e3);
  margin:var(--e4) 0;
  font-size:var(--txt-sm); line-height:1.55; color:var(--texto-suave);
}
.alerta-suave strong{color:var(--texto-titulo)}

/* La salida de emergencia de cada paso: pequeña y centrada, para que se vea sin
   competir con el botón de avanzar. */
.volver{margin:var(--e4) 0 0; text-align:center; font-size:var(--txt-sm)}
.volver a{color:var(--texto-suave)}
.volver a:hover{color:var(--texto-titulo)}

/* ═══ Acciones: lo que el cliente informa de un proyecto ═══════════════════ */

/* La pastilla que faltaba. Las etapas de proyecto no tienen un "malo" —la peor
   es `p-cerrado`, gris— porque una etapa nunca es un fracaso. Un proyecto
   perdido sí, y es el único estado de esta pantalla que hay que ver de lejos. */
.p-perd{color:var(--hik-rojo)}

/* Marca junto al nombre en la lista. Va aquí y no en una columna nueva porque
   la tabla se pinta desde cuatro sitios y cada columna hay que añadirla en los
   cuatro `thead`. */
.marca-acc{
  display:inline-block; margin-left:var(--e2);
  font-size:10.5px; font-weight:var(--peso-semi);
  letter-spacing:.04em; text-transform:uppercase;
  padding:1px 6px; border:1px solid currentColor; border-radius:2px;
  vertical-align:2px; white-space:nowrap;
}

/* La fila entera, apenas teñida. Lo bastante para encontrarla recorriendo la
   lista con la vista, no tanto como para que la tabla parezca un semáforo: en
   una cuenta con muchas informadas, un fondo fuerte deja de destacar nada. */
tr.con-accion > td{background:var(--fondo-alt)}

/* El diálogo en la ficha del proyecto. */
.acc-hist .acc-item{
  padding-bottom:var(--e4); margin-bottom:var(--e4);
  border-bottom:1px solid var(--borde);
}
.acc-hist .acc-item:last-child{padding-bottom:0; margin-bottom:0; border-bottom:none}
.acc-cab{
  display:flex; flex-wrap:wrap; align-items:center; gap:var(--e3);
  margin-bottom:var(--e2);
}
/* La respuesta del BD, sangrada bajo lo que dijo el cliente: son un diálogo, y
   en dos bloques idénticos no se sabe quién habla. */
.acc-resp{
  margin-top:var(--e3); padding-left:var(--e3);
  border-left:2px solid var(--borde-fuerte);
}
.acc-resp .et{display:block; margin-bottom:var(--e1)}

/* Cuatro opciones con texto largo: en fila se parten en dos líneas cada una y
   deja de leerse cuál es cuál. */
.opciones.apiladas{flex-direction:column; gap:var(--e2)}

/* Botones del encabezado: `.btn-p` nació para el envío de un formulario, con
   `width:100%` y margen superior. En la cabecera eso lo estira de lado a lado y
   lo descuelga del título. Aquí se le devuelve su tamaño natural. */
.cabecera .acciones .btn{width:auto; margin-top:0}

/* La llamada a informar, al pie de la ficha del proyecto.
   Separada por una regla y no metida en otra caja: la ficha ya es una sección,
   y anidar tarjetas dentro de tarjetas es lo que convierte una página en una
   bandeja de cajas. */
.cta-accion{
  margin-top:var(--e6); padding-top:var(--e4);
  border-top:1px solid var(--borde);
}
.cta-accion h3.sub{margin-top:0}
.cta-accion .btn-p{width:auto; margin-top:var(--e3)}

/* ═══ El término que se nombra ═════════════════════════════════════════════
   Rojo y en negrita, dentro del texto corrido. Es como hikvision.com marca lo
   que está nombrando —«Project Registration», «Silver, Gold, Platinum and
   Diamond»— comprobado el 2026-09-02 en la página del programa VASP.

   NO es lo mismo que <strong>, y por eso es una clase aparte. Aquí <strong>
   marca fechas, cifras y estados, que son muchos; si todos fueran rojos, el
   rojo dejaría de señalar nada. Esta clase se reserva para el NOMBRE de algo
   la primera vez que aparece en una pantalla.

   Regla para quien venga después: si al quitarle el rojo la frase sigue
   diciendo lo mismo, no era una clave — era énfasis, y va en <strong>. */
.clave{color:var(--hik-rojo); font-weight:var(--peso-bold)}


/* ═══ Soporte: el hilo del caso ════════════════════════════════════════════
   Un caso largo puede tener treinta entradas. Lo que tiene que resolver esta
   maquetación es que se sepa QUIÉN habla sin leer el nombre, y que los hechos
   del expediente no compitan con la conversación.

   Nada de globos de chat enfrentados: esto es un expediente, no un WhatsApp, y
   además se imprime y se cita. Los dos lados van alineados a la izquierda y se
   distinguen por el filo, que es el mismo recurso que ya usa el portal para
   marcar estado. */
.hilo{display:flex; flex-direction:column; gap:var(--e4); margin-bottom:var(--e6)}

.hilo-msg{
  border-left:var(--acento) solid var(--borde);
  padding:var(--e2) 0 var(--e2) var(--e4);
}
/* El cliente en rojo de marca, soporte en azul. No es decoración: en un hilo
   largo es lo único que permite seguir la conversación de un vistazo. */
.hilo-msg.de-cliente{border-left-color:var(--hik-rojo)}
.hilo-msg.de-soporte{border-left-color:var(--hik-azul)}

.hilo-cab{
  display:flex; align-items:baseline; gap:var(--e3); flex-wrap:wrap;
  margin-bottom:var(--e1); font-size:var(--txt-sm);
}
.hilo-cab strong{color:var(--texto-titulo)}
.hilo-cab .tenue{font-size:12px}
.hilo-cab .fecha{margin-left:auto}
.hilo-msg .texto{margin:0; white-space:pre-wrap; overflow-wrap:break-word}
.hilo-msg .docs{margin-top:var(--e2)}

/* Los hechos del expediente —lo tomó fulano, pasó a mengano, dio su visto
   bueno— van en una línea sobria y centrada. Son parte del registro oficial y
   por eso están en el hilo, pero no son conversación: con el mismo peso que un
   mensaje, treinta de ellos harían el caso ilegible. */
.hilo-sis{
  display:flex; align-items:center; justify-content:center; gap:var(--e3);
  flex-wrap:wrap; font-size:12px; color:var(--texto-tenue);
  padding:var(--e1) 0; border-top:1px solid var(--borde);
}


/* El enlace de un ticket: folio y asunto en un solo objetivo.
   Colgar el enlace solo del asunto dejaba filas con tres letras que pulsar. */
.tk-enlace{display:block; text-decoration:none}
.tk-enlace .num{display:block}
.tk-enlace .nomb{display:block; margin-top:1px}
.tk-enlace:hover .nomb{color:var(--hik-rojo)}


/* Novedades sin ver, en el menu del cliente.
   Un punto y no un numero: lo que importa es que hay algo, no cuantas cosas.
   Un contador invita a comparar «3 contra 1» cuando la accion es la misma —
   entrar a mirar—. El numero exacto va en el title, para quien lo quiera. */
.nav .nov{
  color:var(--hik-rojo); font-size:17px; line-height:0;
  margin-left:6px; vertical-align:middle;
}
