/* =============================================================================
   EUROCOMP — estilo compartido
   Una sola hoja para el portal del cliente y el cotizador interno.

   Hasta ahora cada pantalla llevaba su propia copia de estos colores y
   componentes. Cambiar un azul obligaba a cambiarlo en seis lugares, y alguno
   siempre quedaba viejo. Con esto el manual de estilo deja de ser algo que hay
   que recordar y pasa a cumplirse solo.

   Los nombres viejos del cotizador (--paper, --panel, --ink, --accent) se
   conservan como alias al final de :root, para que se pueda enganchar sin
   renombrar seis mil lineas.

   Repaso visual (4 sep): misma identidad de marca (navy/azul), pero con más
   profundidad -- tipografía real (Inter/JetBrains Mono, antes solo declaradas
   de nombre y nunca cargadas), sombras en capas en vez de una línea plana,
   una barra superior con degradé sutil, botones y foco con transición suave,
   scrollbar propio. Ningún nombre de variable ni de clase cambió -- todo lo
   que ya usaba estilo.css se ve mejor solo, sin tocar el HTML de cada pantalla.
   ============================================================================= */

/* Acá había un @import de Google Fonts (Inter y JetBrains Mono).
   Se sacó: la red de EUROCOMP bloquea fonts.googleapis.com igual que bloquea
   el CDN y npm, así que ese import nunca resolvía. Y un @import que no resuelve
   no es gratis -- el navegador frena el pintado de la hoja hasta que la
   petición se cae sola, o sea que cada pantalla arrancaba con una espera de
   más para no traer nada.

   Las tipografías no se pierden: --letra y --mono ya tenían una lista de
   respaldo (Segoe UI, system-ui, Consolas...), que es lo que se estaba usando
   en realidad todo este tiempo. Se ve exactamente igual que hasta ahora, sin
   la espera.

   Si algún día se quieren de verdad: se bajan los .woff2 a app/fuentes/ y se
   declaran con @font-face local, igual que se hizo con las librerías en
   app/lib/. No dependería de la red. */

:root{
  /* --- Identidad ------------------------------------------------------- */
  --navy:#0C1D32;          /* azul institucional: encabezados, texto */
  --navy-profundo:#071120; /* extremo oscuro para degradés de la barra */
  --azul:#007AAD;          /* acento: enlaces, foco, acciones */
  --azul-osc:#005F87;      /* el mismo, presionado */
  --azul-vivo:#0EA5E9;     /* acento más vivo, para degradés y glow */
  --fondo:#EEF3F7;         /* gris azulado del fondo */
  --blanco:#FFFFFF;        /* bloques de contenido */

  /* --- Estados. Los de siempre, sin inventar nada ----------------------- */
  --ok:#1B7F4B;     --ok-bg:#E8F5EE;
  --err:#C0392B;    --err-bg:#FBEAEA;
  --avi:#B8860B;    --avi-bg:#FDF6E3;
  --inf:#007AAD;    --inf-bg:#E8F2F8;

  /* --- La marca, como tercer lado del hilo -------------------------------
     Un presupuesto puede tener tres voces: el cliente, EUROCOMP y la marca
     (va en copia visible del correo). Necesitaba un color propio: si usara
     el azul se confundiria con EUROCOMP, y el ambar ya es el de las notas
     internas. Violeta no lo usa nada mas en todo el sistema. */
  --marca:#6D4AA8;  --marca-bg:#F2EEFA;

  /* --- Grises de trabajo ----------------------------------------------- */
  --borde:#C9D4DD;         /* bordes de tarjetas y campos */
  --linea:#EEF2F5;         /* separadores suaves dentro de una tabla */
  --tenue:#5B6B7A;         /* texto secundario */
  --hueco:#F6F8FA;         /* fondos apenas marcados */

  /* --- Tipografia ------------------------------------------------------- */
  --letra: "Inter", "Segoe UI", system-ui, -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif;
  --mono: "JetBrains Mono", "SFMono-Regular", Consolas, ui-monospace, monospace;

  /* --- Escala de radios --------------------------------------------------
     Un valor fijo por tamaño de elemento, en vez de "lo que quedaba bien" en
     cada CSS. Todo lo demás en esta hoja se apoya en estos cinco números. */
  --r-xs:4px;   /* detalles chicos: code, badges internos */
  --r-sm:8px;   /* campos, botones chicos, chips internos */
  --r-md:12px;  /* bloques y botones normales */
  --r-lg:16px;  /* tarjetas grandes, modales */
  --r-xl:24px;  /* superficies grandes o decorativas */
  --r-pill:999px; /* cápsula completa: chips, contador */

  /* --- Grosor de borde ---------------------------------------------------
     Fino para separar, regular para marcar foco/selección, grueso para una
     franja de color con intención (ej. mensaje propio en el chat). */
  --b-fino:1px;
  --b-regular:2px;
  --b-grueso:4px;

  /* --- Medidas (alias históricos, ahora anclados a la escala) ------------ */
  --radio:var(--r-md);       /* bloques y botones */
  --radio-chico:var(--r-sm); /* campos y botones chicos */
  --facil:cubic-bezier(.4,0,.2,1);   /* easing compartido para toda transición */

  /* --- Iconografía --------------------------------------------------------
     Tres tamaños fijos nada más -- lo que hoy es 13px en un lado y 16px en
     otro, sin motivo, pasa a ser siempre uno de estos tres. */
  --ico-sm:14px;
  --ico-md:18px;
  --ico-lg:22px;

  /* --- Elevación -----------------------------------------------------
     Cinco niveles con nombre, cada superficie usa el que le toca según qué
     tan "encima" de todo está -- no una sombra repetida a ojo en cada regla.
     Doble capa (una de contacto corta + una ambient larga) para que se vea
     con volumen real y no como un borde con blur. */
  --e1:none;                                                              /* plano: fondo, estado presionado */
  --e2:0 1px 2px rgba(12,29,50,.05), 0 3px 10px -4px rgba(12,29,50,.14);  /* apenas levantado: hover leve, fila de tabla */
  --e3:0 1px 2px rgba(12,29,50,.06), 0 8px 24px -12px rgba(12,29,50,.18); /* tarjeta en reposo -- el nivel de siempre */
  --e4:0 2px 4px rgba(12,29,50,.08), 0 16px 32px -14px rgba(12,29,50,.24);/* tarjeta al pasar el mouse, menú desplegable */
  --e5:0 3px 10px rgba(7,17,32,.22), 0 24px 60px -18px rgba(7,17,32,.5);  /* modal, popover: encima de todo */

  /* Par soft-UI: luz arriba-izquierda + sombra abajo-derecha, en vez de una
     sombra sola -- la diferencia entre "una caja con blur" y algo con
     volumen real, tipo Raised/Pressed layer. Se usa en tarjetas y botones;
     el fondo sigue siendo blanco sobre gris azulado (no monocromático como
     la referencia) porque acá hay números que leer todo el día, y el
     neumorfismo puro (tarjeta y fondo del mismo color) resta contraste. */
  --alto:-5px -5px 12px rgba(255,255,255,.85), 7px 9px 20px -6px rgba(12,29,50,.22);
  --hundido:inset 3px 3px 6px rgba(12,29,50,.16), inset -2px -2px 5px rgba(255,255,255,.6);

  --sombra:var(--e3);
  --sombra-hover:var(--e4);
  --sombra-barra:0 1px 0 rgba(255,255,255,.06) inset, 0 10px 30px -8px rgba(3,10,20,.55);
  --anillo-foco:0 0 0 4px rgba(0,122,173,.16);

  /* --- Alias del cotizador --------------------------------------------- */
  --ink:var(--navy); --paper:var(--fondo); --panel:var(--blanco);
  --line:var(--borde); --navy-2:var(--navy); --steel:var(--azul);
  --accent:var(--azul); --accent-2:var(--azul-osc);
  --good:var(--ok); --muted:var(--tenue);
}

*{ box-sizing:border-box }

/* Bug de toda la vida, recién visible al mirar bien las capturas: [hidden]
   es una regla del navegador con prioridad baja, así que CUALQUIER clase que
   declare "display" (como .globo, .chip, .tarjeta) le gana y el elemento
   sigue mostrándose aunque tenga el atributo hidden. Por eso los contadores
   en 0 (Solicitudes, Marca) se veían igual en vez de desaparecer. Con esto,
   hidden vuelve a ganar siempre, sin tener que acordarse de pisarlo clase por
   clase. */
[hidden]{ display:none !important }

html{ scroll-behavior:smooth }

body{
  margin:0;
  background:var(--fondo);
  color:var(--navy);
  font:14px/1.55 var(--letra);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

h1, h2, h3, h4{ font-weight:700; letter-spacing:-.01em }

/* Scrollbar propio -- fino, del color de la marca, no el gris genérico del
   sistema operativo. Firefox usa la versión "thin" de las dos líneas de
   abajo; el resto de los navegadores, las reglas ::-webkit-*. */
*{ scrollbar-width:thin; scrollbar-color:var(--borde) transparent; }
::-webkit-scrollbar{ width:10px; height:10px; }
::-webkit-scrollbar-track{ background:transparent; }
::-webkit-scrollbar-thumb{ background:#B7C4D0; border-radius:10px; border:2px solid var(--fondo); }
::-webkit-scrollbar-thumb:hover{ background:#9CACBB; }

::selection{ background:rgba(0,122,173,.22); color:var(--navy) }

/* =============================================================================
   Iconos
   Miden lo mismo que la letra que los rodea y toman su color. Nunca emojis:
   un emoji cambia de dibujo en cada sistema operativo y no se puede teñir.
   ============================================================================= */
.ico{ width:1em; height:1em; flex:none; vertical-align:-.125em }
.ico-lg{ width:1.35em; height:1.35em }

/* =============================================================================
   Barra superior
   Degradé sutil en vez de un navy plano, con un filo de acento abajo que
   también es degradé -- da la sensación de un panel con luz propia en vez
   de una franja de color sólido.
   ============================================================================= */
.barra{
  background:linear-gradient(155deg, var(--navy) 0%, var(--navy-profundo) 130%);
  color:#fff;
  padding:14px 26px;
  display:flex; align-items:center; gap:18px; flex-wrap:wrap;
  position:sticky; top:0; z-index:10;
  box-shadow:var(--sombra-barra);
  border-bottom:2px solid transparent;
  background-image:
    linear-gradient(155deg, var(--navy) 0%, var(--navy-profundo) 130%),
    linear-gradient(90deg, var(--azul-vivo), var(--azul) 55%, transparent);
  background-origin:border-box;
  background-clip:padding-box, border-box;
}
.barra .marca{ font-size:17px; font-weight:700; letter-spacing:-.01em }
.barra .marca span{ opacity:.6; font-weight:400; letter-spacing:0 }

.barra nav{ margin-left:auto; display:flex; gap:8px; align-items:center }
.barra nav a{
  color:#fff; text-decoration:none; font-size:13px; opacity:.75;
  padding:6px 10px; border-radius:var(--radio-chico);
  display:inline-flex; align-items:center; gap:6px;
  transition:opacity .16s var(--facil), background .16s var(--facil), transform .16s var(--facil);
}
.barra nav a:hover{ opacity:1; background:rgba(255,255,255,.1); transform:translateY(-1px) }
.barra nav a.on{ opacity:1; background:rgba(255,255,255,.14) }

/* =============================================================================
   Bloques
   ============================================================================= */
main{ max-width:1060px; margin:22px auto; padding:0 20px 70px }
.ancho-comodo{ max-width:1000px }

.bloque{
  background:var(--blanco);
  border:1px solid rgba(12,29,50,.05);
  border-radius:var(--radio);
  padding:20px 22px; margin-bottom:16px;
  box-shadow:var(--alto);
  transition:box-shadow .2s var(--facil);
}
.bloque h2{ margin:0 0 4px; font-size:16px; font-weight:700 }
.sub{ color:var(--tenue); font-size:13px; margin:0 0 16px }

.tarjeta{
  border:1px solid var(--borde); border-radius:var(--radio);
  padding:16px 18px; margin-bottom:14px;
  background:var(--blanco);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.6);
  transition:box-shadow .2s var(--facil), border-color .2s var(--facil), transform .2s var(--facil);
}
.tarjeta.abierta{ border:var(--b-regular) solid var(--azul); box-shadow:var(--e4), inset 0 1px 0 rgba(255,255,255,.6) }
/* Solo las tarjetas que de verdad se pueden abrir (tienen un .cab clickeable
   adentro) reaccionan al pasar el mouse -- así el hover sigue siendo una
   pista real de "esto hace algo", no decoración puesta en todos lados. */
.tarjeta:has(.cab[data-abrir]):hover,
.tarjeta:has([data-abrir-hist]):hover{
  box-shadow:var(--e4), inset 0 1px 0 rgba(255,255,255,.6); border-color:#AFC0CE; transform:translateY(-1px);
}

.vacio{ text-align:center; color:var(--tenue); padding:36px 20px }
.vacio .ico-vacio{ width:38px; height:38px; color:var(--borde); margin:0 0 10px; display:inline-block }
.vacio.cargando{ padding:24px 20px; font-size:13px }

/* Spinner -- para "Cargando…" en vez de dejar solo el texto quieto. */
.spin{
  width:16px; height:16px; margin-right:8px; vertical-align:-3px;
  border:var(--b-regular) solid var(--linea); border-top-color:var(--azul);
  border-radius:50%; display:inline-block; animation:girar .7s linear infinite;
}
@keyframes girar{ to{ transform:rotate(360deg) } }

/* Skeleton -- filas fantasma con un brillo que se desplaza, para listas que
   todavía no tienen datos pero ya sabemos que van a ser filas de tabla o
   tarjetas. Se usa mientras se espera el fetch, en vez de "Cargando…". */
.skeleton{ background:var(--hueco); border-radius:var(--r-sm); overflow:hidden; position:relative; }
.skeleton::after{
  content:''; position:absolute; inset:0; transform:translateX(-100%);
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.7), transparent);
  animation:brillo 1.3s infinite;
}
@keyframes brillo{ 100%{ transform:translateX(100%) } }
.skeleton-linea{ height:13px; margin:8px 0; }
.skeleton-linea.corta{ width:40%; }
.skeleton-fila{ display:flex; gap:10px; align-items:center; padding:10px 4px; }
.skeleton-fila .skeleton{ flex:none; }
.skeleton-fila .skeleton.avatar{ width:32px; height:32px; border-radius:50%; }
.skeleton-fila .skeleton.linea{ flex:1; height:12px; }

/* =============================================================================
   Chips de estado
   ============================================================================= */
.chip{
  display:inline-flex; align-items:center; gap:6px;
  padding:3px 10px; border-radius:var(--r-pill);
  font-size:12px; font-weight:600; white-space:nowrap;
  box-shadow:0 0 0 1px rgba(12,29,50,.04) inset;
}
.chip svg{ width:var(--ico-sm); height:var(--ico-sm) }
.c-ok  { background:var(--ok-bg);  color:var(--ok)  }
.c-err { background:var(--err-bg); color:var(--err) }
.c-avi { background:var(--avi-bg); color:var(--avi) }
.c-inf { background:var(--inf-bg); color:var(--inf) }
.c-gris{ background:#EEF1F4;       color:var(--tenue) }  /* "en producción": ni aviso ni error, solo informativo */

/* Contador rojo al lado de un enlace: solicitudes, aprobaciones sin ver. */
.globo{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:19px; height:19px; padding:0 6px; margin-left:6px;
  border-radius:var(--r-pill); background:var(--err); color:#fff;
  font-size:11.5px; font-weight:700; line-height:1; vertical-align:middle;
  box-shadow:0 0 0 3px rgba(192,57,43,.18);
}

/* =============================================================================
   Tablas
   ============================================================================= */
table{ width:100%; border-collapse:collapse; font-size:13px }
th{
  text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.5px;
  color:var(--tenue); border-bottom:2px solid var(--borde); padding:8px 10px;
  font-weight:700;
}
td{ padding:8px 10px; border-bottom:1px solid var(--linea); vertical-align:top }
td.num, th.num{ text-align:right; font-variant-numeric:tabular-nums; font-family:var(--mono) }
tr.apagada td{ opacity:.5 }
tbody tr{ transition:background .12s var(--facil) }
tbody tr:hover{ background:var(--hueco) }

/* Códigos, números de parte, números de presupuesto. */
.codigo{ font-family:var(--mono); font-size:12px; color:var(--tenue); letter-spacing:.02em }

/* =============================================================================
   Formularios
   ============================================================================= */
label{
  display:block; font-size:11.5px; font-weight:600;
  color:var(--tenue); margin-bottom:4px;
}
input, select, textarea{
  font:inherit; padding:8px 10px;
  border:1px solid var(--borde); border-radius:var(--radio-chico);
  background:#fff; color:var(--navy);
  transition:border-color .16s var(--facil), box-shadow .16s var(--facil);
}
input:focus, select:focus, textarea:focus{
  outline:none; border-color:var(--azul); box-shadow:var(--anillo-foco);
}
/* El <select> nativo se dibuja más bajo que un input del mismo padding y con
   la flecha del sistema operativo: puesto al lado de un buscador nunca
   terminaba de alinearse. Con flecha propia queda de la misma altura. */
select{
  appearance:none; -webkit-appearance:none;
  padding-right:28px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%236A7C93' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 10px center;
}
textarea{ resize:vertical; min-height:38px }

/* =============================================================================
   Botones
   ============================================================================= */
button{
  border:0; border-radius:var(--radio-chico);
  padding:9px 16px; font:inherit; font-weight:600; cursor:pointer;
  display:inline-flex; align-items:center; gap:7px;
  transition:background .16s var(--facil), box-shadow .16s var(--facil),
             transform .16s var(--facil), border-color .16s var(--facil), opacity .16s var(--facil);
}
button:disabled{ opacity:.55; cursor:default }
button:active:not(:disabled){ transform:translateY(1px) }

.primario  { background:linear-gradient(155deg, var(--azul-vivo), var(--azul-osc)); color:#fff;
             box-shadow:0 1px 2px rgba(0,95,135,.15), 0 8px 18px -8px rgba(0,122,173,.55) }
.primario:hover:not(:disabled){ box-shadow:0 1px 2px rgba(0,95,135,.2), 0 10px 22px -6px rgba(0,122,173,.65); transform:translateY(-1px) }
.primario:active:not(:disabled){ box-shadow:inset 2px 2px 5px rgba(0,50,75,.4); transform:translateY(1px) }
.aprobar   { background:linear-gradient(155deg, #22A667, var(--ok)); color:#fff;
             box-shadow:0 8px 18px -8px rgba(27,127,75,.5) }
.aprobar:hover:not(:disabled){ transform:translateY(-1px) }
.aprobar:active:not(:disabled){ box-shadow:inset 2px 2px 5px rgba(10,60,30,.4); transform:translateY(1px) }
.cambios   { background:transparent; color:var(--avi); border:1px solid var(--avi) }
.rechazar  { background:transparent; color:var(--err); border:1px solid var(--err) }
.secundario{ background:transparent; color:var(--azul); border:1px solid var(--azul);
             padding:7px 12px; font-size:13px }
.secundario:hover:not(:disabled){ background:var(--inf-bg) }
.mini      { background:transparent; color:var(--azul); border:1px solid var(--borde);
             padding:5px 10px; font-size:12.5px }
.mini:hover:not(:disabled){ border-color:var(--azul); background:var(--inf-bg) }
.mini.peligro{ color:var(--err); border-color:#E6C3BF }
.mini.peligro:hover:not(:disabled){ background:var(--err-bg); border-color:var(--err) }

/* Icono suelto sin borde, para "eliminar esta fila" en tablas angostas
   (carritos, filas editables) donde un .mini con su borde/padding no entra. */
.btn-x{ background:none; border:0; color:var(--err); font-size:16px; line-height:1;
        cursor:pointer; padding:2px 4px; border-radius:6px;
        transition:background .16s var(--facil), opacity .16s var(--facil) }
.btn-x:hover{ opacity:1; background:var(--err-bg) }

/* =============================================================================
   Interruptor (switch)
   Para una casilla que en realidad es un sí/no de una sola opción -- "solo
   disponible ahora", "nota interna" -- no una selección múltiple en una
   lista. Se activa agregando class="switch" al <input type="checkbox">
   existente; no hace falta envolverlo en nada.
   ============================================================================= */
.switch{
  appearance:none; -webkit-appearance:none; margin:0;
  width:38px; height:22px; border-radius:var(--r-pill); flex:none;
  background:#D7DEE5; border:1px solid var(--borde); position:relative; cursor:pointer;
  box-shadow:inset 0 1px 3px rgba(12,29,50,.15);
  transition:background .18s var(--facil), border-color .18s var(--facil), box-shadow .18s var(--facil);
}
.switch::after{
  content:''; position:absolute; top:1px; left:1px; width:18px; height:18px;
  border-radius:50%; background:#fff;
  box-shadow:0 1px 3px rgba(12,29,50,.3), 0 1px 1px rgba(12,29,50,.15);
  transition:transform .18s var(--facil);
}
.switch:checked{
  background:linear-gradient(155deg, var(--azul-vivo), var(--azul-osc)); border-color:transparent;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.12), 0 0 8px rgba(0,122,173,.35);
}
.switch:checked::after{ transform:translateX(16px) }
.switch:focus-visible{ outline:none; box-shadow:var(--anillo-foco) }
.switch:disabled{ opacity:.5; cursor:default }

/* Selector de archivo.
   Sin esto sale el cromo crudo del navegador -- un boton gris «Choose File» y
   un «No file chosen» en ingles, en medio de un formulario en espanol. Ya se
   habia arreglado en el cotizador, que tiene sus estilos propios; esto lo
   trae a las pantallas que sí usan esta hoja (marca.html, fichas.html). */
input[type=file]{
  font-family:inherit; font-size:12.5px; color:var(--tenue);
  width:100%; padding:8px 10px; border:1px dashed var(--borde);
  border-radius:var(--radio-chico); background:var(--hueco); cursor:pointer;
  transition:border-color .15s var(--facil), background .15s var(--facil);
}
input[type=file]:hover{ border-color:var(--azul-vivo); background:var(--inf-bg) }
input[type=file]:focus-visible{ outline:none; border-color:var(--azul-vivo); box-shadow:var(--anillo-foco) }
input[type=file]::file-selector-button{
  font-family:inherit; font-size:12.5px; font-weight:600;
  margin-right:10px; padding:6px 12px; cursor:pointer;
  border:1px solid var(--borde); border-radius:var(--r-sm);
  background:var(--blanco); color:var(--azul-osc);
  transition:background .15s var(--facil), border-color .15s var(--facil);
}
input[type=file]:hover::file-selector-button{ background:var(--inf-bg); border-color:var(--azul-vivo) }

/* Botón de la barra superior, sobre el navy. */
.barra button{
  background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.28); color:#fff;
  border-radius:var(--radio-chico); padding:6px 12px; font-size:12.5px;
  backdrop-filter:blur(6px);
}
.barra button:hover:not(:disabled){ background:rgba(255,255,255,.16); border-color:rgba(255,255,255,.4) }

/* =============================================================================
   Avisos
   ============================================================================= */
.caja-err, .caja-ok, .caja-avi{
  border-radius:var(--radio-chico); padding:12px 14px; margin-top:12px; font-size:13.5px;
  border:1px solid transparent;
}
.caja-err{ background:var(--err-bg); color:var(--err); border-color:#F2CFC9 }
.caja-ok { background:var(--ok-bg);  color:var(--ok);  border-color:#C9E7D6 }
.caja-avi{ background:var(--avi-bg); color:var(--avi); border-color:#F2E3B0 }
.caja-ok code, .caja-err code, .caja-avi code{
  background:#fff; padding:2px 7px; border-radius:4px;
  color:var(--navy); border:1px solid var(--borde); font-family:var(--mono);
}

/* =============================================================================
   Conversación
   ============================================================================= */
.msg{
  border-left:3px solid var(--borde); border-radius:0 8px 8px 0;
  padding:7px 12px; margin-bottom:8px; background:var(--hueco); font-size:13px;
}
.msg.de-eurocomp{ border-left-color:var(--azul); background:var(--inf-bg) }
.msg.de-marca{ border-left-color:var(--marca); background:var(--marca-bg) }
.msg.interno{ border-left-color:var(--avi); background:var(--avi-bg) }
.msg .de{
  font-size:11px; color:var(--tenue); font-weight:600;
  text-transform:uppercase; letter-spacing:.4px; margin-bottom:2px;
}
/* Las dos etiquetas de la línea de autor. Vivían sueltas dentro de portal.html
   y aprobaciones.html no las tenía: el mismo mensaje salía con etiqueta de un
   lado y sin nada del otro. */
.msg .de .lado-marca, .msg .de .por-correo{
  display:inline-block; padding:1px 7px; border-radius:var(--r-pill);
  font-size:10.5px; font-weight:700; letter-spacing:.02em; text-transform:none;
}
.msg .de .lado-marca{ background:var(--marca-bg); color:var(--marca) }
.msg .de .por-correo{ background:var(--inf-bg); color:var(--azul) }

/* =============================================================================
   Reportes
   Tarjetas de KPI y contenedores de gráfico -- genéricos, para cualquier
   pantalla que necesite mostrar números grandes o un canvas de Chart.js
   dentro de una tarjeta que combine con el resto del sistema.
   ============================================================================= */
.kpis{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr));
  gap:14px; margin-bottom:16px;
}
.kpi{
  background:var(--blanco); border:1px solid rgba(12,29,50,.05);
  border-radius:var(--radio); padding:16px 18px; box-shadow:var(--alto);
  display:flex; align-items:flex-start; gap:12px;
  min-width:0; /* si no, un valor largo (ej. un monto) estira la tarjeta fuera de su columna */
}
.kpi .kpi-ico{
  flex:none; width:36px; height:36px; border-radius:var(--r-sm);
  display:flex; align-items:center; justify-content:center;
  background:var(--inf-bg); color:var(--azul);
}
.kpi .kpi-ico svg{ width:var(--ico-md); height:var(--ico-md) }
.kpi.c-ok  .kpi-ico{ background:var(--ok-bg);  color:var(--ok) }
.kpi.c-avi .kpi-ico{ background:var(--avi-bg); color:var(--avi) }
.kpi.c-err .kpi-ico{ background:var(--err-bg); color:var(--err) }
.kpi .kpi-cuerpo{ min-width:0 } /* el hijo flex tambien necesita el suyo -- el del padre no alcanza */
.kpi .kpi-valor{
  font-size:22px; font-weight:800; color:var(--navy); line-height:1.15; letter-spacing:-.01em;
  overflow-wrap:break-word;
}
.kpi .kpi-etiqueta{ font-size:12px; color:var(--tenue); margin-top:2px }
.kpi .kpi-detalle{ font-size:11.5px; color:var(--tenue); margin-top:4px }

.graficos{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(360px, 1fr));
  gap:16px; margin-bottom:16px;
}
.graficos .bloque.ancho{ grid-column:1 / -1 }
.grafico-caja{ position:relative; height:260px }
.grafico-caja.chico{ height:190px }
.bloque .sub-num{ font-size:12px; color:var(--tenue); margin:-2px 0 14px }

/* =============================================================================
   Tablet y ventanas angostas de escritorio (761px – 1000px)

   Justo arriba del corte de teléfono la barra de arriba todavía muestra todos
   los enlaces, y con seis destinos + Salir mide 859px: en un iPad en vertical
   (768px) se salía de la pantalla. Acá los achica y los deja envolver a una
   segunda línea en vez de desbordar.
   ============================================================================= */
@media (max-width:1000px){
  .barra{ flex-wrap:wrap; row-gap:8px }
  .barra nav{ margin-left:auto; flex-wrap:wrap; justify-content:flex-end; gap:5px }
  .barra nav a{ font-size:12.5px; padding:7px 9px }
  main{ padding:0 16px 40px }
}

/* =============================================================================
   Teléfono y tablet en vertical (todas las pantallas del portal)

   Los clientes integradores abren el portal desde el celular en obra, y el
   equipo de EUROCOMP consulta desde el suyo. El corte está en 760px, no en
   640, porque una tablet en vertical sufre lo mismo que un teléfono.

   Tres reglas que valen para toda la app:
     * NADA se sale de la pantalla. Lo ancho (una tabla) se desplaza DENTRO
       de su bloque, nunca la página entera.
     * Nada que haya que tocar mide menos de 44px de alto. Es la medida que
       recomienda Apple y es la diferencia entre acertar y errar con el pulgar.
     * Ningún campo por debajo de 16px: iOS hace zoom solo al enfocarlo y
       después el usuario queda con la página corrida.

   Los enlaces de la barra de arriba los esconde navmovil.js, que los baja a
   la barra fija de abajo; acá la barra de arriba queda con marca, campana y
   Salir.
   ============================================================================= */
@media (max-width:760px){
  html, body{ overflow-x:hidden }
  body{ -webkit-text-size-adjust:100% }

  /* --- Barra de arriba: marca + campana + salir ------------------------- */
  .barra{ padding:10px 14px; gap:10px; position:sticky; top:0; z-index:800 }
  .barra .marca{ font-size:15px }
  .barra .marca span{ display:none }
  .barra nav{ gap:6px; justify-content:flex-end; flex-wrap:nowrap }
  .barra button{ padding:9px 11px; font-size:12.5px; min-height:40px }

  /* --- Contenido -------------------------------------------------------- */
  main{ margin:12px auto; padding:0 12px 24px }
  .bloque{ padding:14px; margin-bottom:12px; border-radius:14px }
  .bloque h2{ font-size:15.5px }
  .tarjeta{ padding:12px }
  h1{ font-size:19px }

  /* --- Áreas de toque ---------------------------------------------------- */
  button, .btn, a.btn, label.btn-carga, [role="button"]{ min-height:44px }
  button.mini, .mini{ min-height:38px; padding:8px 12px; font-size:12.5px }
  /* dentro de una fila de tabla el mínimo aprieta de más: ahí alcanza 36 */
  td button, td .mini, td a.mini{ min-height:36px }
  .barra nav a{ min-height:40px; display:inline-flex; align-items:center }

  /* --- Formularios ------------------------------------------------------- */
  /* !important a propósito: varias pantallas fijan 12.5px con un selector más
     específico (por ejemplo `td.pegar input`), y ese tamaño es justo el que
     hace que iOS haga zoom solo al enfocar el campo. */
  input, select, textarea{ font-size:16px !important; min-height:44px }
  textarea{ min-height:88px }
  /* :not(.switch) importa: sin eso, esta regla (0,1,1) le gana a `.switch`
     (0,1,0) y el interruptor pasa de 38x22 a 20x20 en el telefono. La perilla
     sigue midiendo 18px y desplazandose 16, asi que se sale de la pista y
     queda flotando encima del texto de al lado. Se veia en marca.html, pero
     le pasaba a TODOS los interruptores del proyecto en pantalla chica. */
  input[type=checkbox]:not(.switch), input[type=radio]{ min-height:0; width:20px; height:20px }
  /* Y de paso se agranda para el dedo, sin romper la proporcion. */
  .switch{ width:44px; height:26px; min-height:0 }
  .switch::after{ width:22px; height:22px }
  .switch:checked::after{ transform:translateX(18px) }
  label{ font-size:13px }
  .campo, .fila-campos{ display:block; width:100% }
  .fila-campos > *{ width:100%; margin-bottom:10px }

  /* --- Tablas: se desplazan dentro del bloque, con aviso de que hay más --- */
  .bloque table, .bloque .tabla-envoltorio, .tabla-scroll{
    display:block; overflow-x:auto; max-width:100%; -webkit-overflow-scrolling:touch;
    /* sombra al borde derecho mientras quede algo por ver */
    background:
      linear-gradient(90deg, var(--blanco) 30%, rgba(255,255,255,0)) left / 24px 100% no-repeat,
      linear-gradient(270deg, var(--blanco) 30%, rgba(255,255,255,0)) right / 24px 100% no-repeat,
      radial-gradient(farthest-side at 0 50%, rgba(12,29,50,.14), transparent) left / 10px 100% no-repeat,
      radial-gradient(farthest-side at 100% 50%, rgba(12,29,50,.14), transparent) right / 10px 100% no-repeat;
    background-attachment:local, local, scroll, scroll;
  }
  table{ font-size:12.5px }
  td, th{ padding:9px 8px; white-space:nowrap }
  td.envuelve, th.envuelve{ white-space:normal; min-width:150px }

  /* --- Números y gráficos ------------------------------------------------ */
  .kpis{ grid-template-columns:1fr 1fr; gap:10px }
  .kpi .kpi-valor{ font-size:19px }
  .graficos{ grid-template-columns:1fr }
  .grafico-caja{ height:210px }
  .grafico-caja.chico{ height:170px }
  .chip{ font-size:11.5px; padding:5px 9px }

  /* --- Diálogos --------------------------------------------------------- */
  dialog, .modal, .modal-caja{ width:calc(100vw - 24px); max-width:none; margin:12px auto }
}

/* Pantallas muy angostas (iPhone SE / mini) */
@media (max-width:400px){
  main{ padding:0 9px 24px }
  .bloque{ padding:12px }
  .kpis{ grid-template-columns:1fr }
  .barra .marca{ font-size:14px }
}

/* =============================================================================
   Impresión
   El PDF que el cliente le manda a su cliente sale de acá: fondo blanco,
   sin sombras, sin barras de navegación.
   ============================================================================= */
@media print{
  body{ background:#fff }
  .barra, nav, button{ display:none !important }
  .bloque{ box-shadow:none; border:1px solid var(--borde) }
}
