/* =============================================================================
   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{
  /* --- Tema oscuro (27 sep) --------------------------------------------
     Ivan pidió pasar todo el sistema al look "vidrio premium" que se probó
     primero como maqueta aparte: fondo oscuro, tarjetas con más profundidad,
     un acento en degradé para los llamados a la acción principales. Mismo
     método que ya se usaba acá: los NOMBRES no cambian (--fondo, --blanco,
     --borde, etc.), solo los valores -- así ninguna pantalla necesita
     tocarse por este cambio, todas heredan solas.

     Dos variantes, elegidas por pantalla según cuánto tiempo seguido se mira:
       - Negro puro (el default de acá abajo): para las pantallas que un
         cliente o la marca ven un rato y se van -- login, portal del
         cliente, ficha de producto, lo que ve Hikvision. Ahí importa más el
         impacto visual que la fatiga.
       - Gris intermedio (bloque .tema-suave más abajo, opt-in agregando esa
         clase al <body>): para las herramientas que el equipo tiene abierta
         toda la jornada -- cotizador, bandeja, revisión. Fondo gris carbón
         en vez de negro puro, menos contraste duro, para no cansar la vista
         en sesiones largas.

     Antes de esto el sistema era azul institucional sobre fondo claro. Esa
     identidad no se pierde: --navy y --navy-profundo (la barra superior, la
     pastilla de los h2) quedan igual que siempre, ya eran los tonos más
     oscuros de toda la hoja. Lo que cambia es el fondo y las superficies
     alrededor.

     OJO con --navy: antes hacía doble trabajo, era el color del texto
     (body, h3/h4, inputs) Y el color de fondo de la barra/pastillas. Un
     mismo valor no puede ser "casi negro" para fondo Y "casi blanco" para
     texto a la vez, así que se separó: --navy sigue siendo la superficie
     oscura de la barra (sin cambios), y el texto ahora usa --ink, una
     variable nueva. Las tres reglas que usaban var(--navy) para texto
     (más abajo en este archivo) se cambiaron a var(--ink). */

  /* --- Identidad ------------------------------------------------------- */
  --navy:#0B1030;          /* superficie oscura: barra superior, pastilla de h2 -- sin cambios */
  --navy-profundo:#060920; /* extremo oscuro para degradés de la barra -- sin cambios */
  --ink:#F5F6FB;           /* NUEVO: texto principal (antes esto era var(--navy)) */
  --azul:#5B8CFF;          /* acento: enlaces, foco, acciones -- mismo azul, más brillante para leerse sobre oscuro */
  --azul-osc:#3D6BFF;      /* el mismo, presionado */
  --azul-vivo:#7C8CFF;     /* acento más vivo, para degradés y glow -- vira a cian */
  --fondo:#05071A;         /* negro casi puro */
  --blanco:#0E1330;        /* bloques de contenido -- sigue llamándose "blanco" por los seis mil usos en el resto de la hoja, ahora es la tarjeta oscura */

  /* --- Acento en degradé (29/09: azul eléctrico -> violeta, antes rosa-violeta-cian) ---
     Para los llamados a la acción principales y algunos detalles puntuales
     (nunca como fondo grande de una superficie completa -- eso destiñe todo
     lo que tiene encima, bug que ya se pisó y se corrigió varias veces en
     las maquetas). */
  --grad: linear-gradient(120deg, #3D6BFF 0%, #6C4DF6 60%, #8B5CF6 100%);

  /* --- Estados. Los de siempre, ahora para fondo oscuro ------------------ */
  --ok:#3DDC97;     --ok-bg:rgba(46,209,145,.16);
  --err:#FF6B7A;    --err-bg:rgba(255,92,135,.16);
  --avi:#F0AC3F;    --avi-bg:rgba(240,172,63,.16);
  --inf:#7EA2FF;    --inf-bg:rgba(91,140,255,.16);

  /* --- La marca, como tercer lado del hilo -------------------------------
     Mismo motivo de siempre: un presupuesto puede tener tres voces (cliente,
     EUROCOMP, la marca) y necesitaba un color propio que no se confundiera
     con el azul de EUROCOMP ni el ámbar de las notas internas. */
  --marca:#A78BFA;  --marca-bg:rgba(139,92,246,.16);

  /* --- Grises de trabajo ----------------------------------------------- */
  --borde:rgba(130,145,255,.18);  /* bordes de tarjetas y campos */
  --linea:rgba(130,145,255,.10);  /* separadores suaves dentro de una tabla */
  --tenue:#8E95B8;                /* texto secundario */
  --hueco:#141A3A;                /* fondos apenas marcados -- un paso más claro que --blanco */

  /* --- Tipografia -------------------------------------------------------
     Sigue sin haber @import de Google Fonts -- la red de EUROCOMP lo
     bloquea (ver comentario original más arriba). La sensación "premium" de
     las maquetas se logra con más peso y tracking más apretado en los
     títulos, no con una tipografía distinta. */
  --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 -- sin cambios, es geometría, no color ----------- */
  --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 -- sin cambios ------------------------------------ */
  --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 -- sin cambios ----------------------------------------- */
  --ico-sm:14px;
  --ico-md:18px;
  --ico-lg:22px;

  /* --- Elevación -----------------------------------------------------
     Mismos cinco niveles, recalculados para fondo oscuro: una sombra clara
     (rgba blanco) no se nota casi nada sobre un fondo casi negro, así que
     acá el volumen se arma con sombra ambient más oscura (negro puro, no el
     navy-tint de antes) y un filo de luz fino arriba en vez del par
     neumórfico -5px/7px de antes (ese truco necesita que tarjeta y fondo
     sean del mismo tono; acá los queremos bien diferenciados a propósito,
     por la regla de "cuidado con los colores" -- una tarjeta que se
     confunde con el fondo es tan mala como una que sangra color). */
  --e1:none;                                                          /* plano: fondo, estado presionado */
  --e2:0 1px 2px rgba(0,0,0,.3), 0 3px 10px -4px rgba(0,0,0,.4);      /* apenas levantado: hover leve, fila de tabla */
  --e3:0 1px 2px rgba(0,0,0,.35), 0 8px 24px -12px rgba(0,0,0,.55);   /* tarjeta en reposo -- el nivel de siempre */
  --e4:0 2px 4px rgba(0,0,0,.4), 0 16px 32px -14px rgba(0,0,0,.6);    /* tarjeta al pasar el mouse, menú desplegable */
  --e5:0 3px 10px rgba(0,0,0,.5), 0 24px 60px -18px rgba(0,0,0,.7);   /* modal, popover: encima de todo */

  --alto:inset 0 1px 0 rgba(255,255,255,.06), 0 16px 32px -16px rgba(0,0,0,.6);
  --hundido:inset 2px 2px 5px rgba(0,0,0,.5), inset -1px -1px 2px rgba(255,255,255,.04);

  --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(124,140,255,.25);

  /* --- Alias del cotizador --------------------------------------------- */
  --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);
}

/* --- Variante "gris intermedio" para herramientas de uso diario ---------
   Se activa agregando class="tema-suave" al <body> de esa pantalla (por
   ahora pensado para: cotizador, bandeja/aprobaciones, revisión de la
   marca -- lo que el equipo tiene abierto toda la jornada). Redefine solo
   fondo y superficies; acentos, estados, tipografía y radios se heredan
   igual que en el resto del sistema. */
body.tema-suave{
  --fondo:#0B0F2A;
  --blanco:#141A3C;
  --hueco:#1B2248;
  --borde:rgba(130,145,255,.16);
  --linea:rgba(130,145,255,.09);
  --tenue:#9AA1C4;
}

*{ 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;
  /* 29/09: paleta azul electrico -> violeta. Dos brillos fijos detras de todo (no animados). */
  background:radial-gradient(1100px 560px at 88% -8%, rgba(108,77,246,.22), transparent 60%),
             radial-gradient(900px 520px at -8% 28%, rgba(61,107,255,.14), transparent 62%),
             var(--fondo);
  background-attachment:fixed;
  color:var(--ink);
  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:rgba(255,255,255,.18); border-radius:10px; border:2px solid var(--fondo); }
::-webkit-scrollbar-thumb:hover{ background:rgba(255,255,255,.28); }

::selection{ background:rgba(91,140,255,.32); color:var(--ink) }

/* =============================================================================
   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(255,255,255,.06);
  border-radius:var(--radio);
  padding:20px 22px; margin-bottom:16px;
  box-shadow:var(--alto);
  transition:box-shadow .2s var(--facil);
}
/* El titulo de un bloque es la misma pastilla azul marino que usa el
   cotizador en sus secciones ("Cliente", "Punto de partida"): una sola linea
   de diseno en todas las pantallas, no titulos planos sobre blanco. */
.bloque h2{
  display:inline-flex; align-items:center; gap:7px;
  margin:0 0 10px; font-size:13px; font-weight:700; color:#fff;
  background:var(--navy); padding:6px 13px; border-radius:8px;
  letter-spacing:.01em;
}
.bloque h2 .ico{ width:14px; height:14px }
.bloque h2 + .sub{ margin-top:0 }
.sub{ color:var(--tenue); font-size:13px; margin:0 0 16px }
/* Los titulos de segundo nivel (sub-bloques dentro de una ficha) van como
   etiqueta clara, para no competir con la pastilla del bloque. */
.bloque h3, .bloque h4{ margin:0 0 6px; font-size:13px; font-weight:700; color:var(--ink) }

.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,.07);
  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,.07) }
/* 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,.07); border-color:rgba(255,255,255,.22); transform:translateY(-1px);
}

.vacio{
  text-align:center; color:var(--tenue); padding:28px 20px; font-size:13.5px;
  border:1px dashed var(--borde); border-radius:var(--radio-chico); background:var(--hueco);
  margin:4px 0;
}
/* El estado vacio lleva su icono (una bandeja) para que no sea una linea de
   texto suelta en medio del bloque; el que ya trae .ico-vacio propio no lo
   duplica. */
.vacio:not(.cargando):not(:has(.ico-vacio))::before{
  content:""; display:block; width:34px; height:34px; margin:0 auto 8px; opacity:.55;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236A7C93' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 12l2.5-7h13L21 12v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/%3E%3Cpath d='M3 12h5l1.5 2.5h5L16 12h5'/%3E%3C/svg%3E") center/contain no-repeat;
}
.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; border-style:solid; border-color:var(--linea); background:transparent }

/* 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,.14), 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(255,255,255,.05) 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:rgba(255,255,255,.08); 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(255,107,122,.25);
}

/* =============================================================================
   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:var(--hueco); color:var(--ink);
  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 }
/* Un campo con etiqueta arriba (.campo) llena su celda. Sin esto, cada input
   medía lo que el navegador quiere (unos 20 caracteres) y los formularios
   de Clientes, Solicitudes, Ajustes o Marca quedaban con cajitas cortas y
   huecos al lado: "fuera de diseño", como lo describió Ivan. */
.campo input:not([type=checkbox]):not([type=radio]):not([type=file]),
.campo select, .campo textarea{ width:100%; box-sizing:border-box; min-width:0 }
.campo{ min-width:0 }

/* =============================================================================
   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);
}
/* Un boton apagado tiene que PARECER apagado.
   Con solo `opacity:.55`, un boton primario azul con degradé sigue viendose
   azul y sigue invitando a apretarlo -- y despues no pasa nada. En el
   catalogo eso pasa en cada producto sin precio: "Agregar" se veia igual de
   celeste que los que si se pueden agregar. Apagado quiere decir gris plano,
   sin degradé y sin sombra: se ve de lejos que ese no va. */
button:disabled{ opacity:.6; cursor:not-allowed }
button:disabled, button.primario:disabled, button.secundario:disabled{
  background:var(--hueco) !important; background-image:none !important;
  color:var(--tenue) !important; border:1px solid var(--borde) !important;
  box-shadow:none !important; transform:none !important;
}
button:disabled svg{ stroke:var(--tenue) }
button:active:not(:disabled){ transform:translateY(1px) }

/* =============================================================================
   EL FOCO: DÓNDE ESTOY PARADO
   =============================================================================
   Los campos de texto ya tenían su anillo (más arriba). Lo que no lo tenía era
   todo lo demás: botones, enlaces, pestañas, chips, resúmenes desplegables. Y
   eso es casi toda la pantalla.

   A quién le importa: a quien navega con teclado porque no puede usar el
   mouse, a quien usa un lector de pantalla, y a cualquiera que aprieta Tab
   para pasar de un campo al siguiente sin soltar el teclado -- que en un
   formulario de presupuesto es la forma rápida de trabajar. Sin anillo de
   foco, apretás Tab tres veces y ya no sabés dónde estás.

   Va con `:focus-visible` y no con `:focus` a propósito: `:focus` también se
   dispara al hacer clic con el mouse, y entonces cada botón queda con un
   anillo pegado después de apretarlo. `:focus-visible` lo muestra cuando el
   navegador entiende que hiciste falta verlo -- teclado sí, clic no.

   Y el `outline` transparente no es decorativo: en el modo de alto contraste
   de Windows las sombras desaparecen, y sin esa línea el foco volvería a ser
   invisible justo para quien más lo necesita.
   ============================================================================= */
button:focus-visible,
a:focus-visible,
summary:focus-visible,
.chip:focus-visible,
[role="button"]:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible{
  outline:2px solid transparent;
  outline-offset:2px;
  box-shadow:0 0 0 2px var(--blanco), 0 0 0 4px var(--azul);
  border-radius:var(--radio-chico);
}
/* Sobre fondo oscuro (la barra de arriba) el anillo blanco se pierde: ahí el
   separador va en el color del propio fondo. */
.barra button:focus-visible,
.barra a:focus-visible{
  box-shadow:0 0 0 2px var(--navy), 0 0 0 4px var(--azul-vivo);
}

/* =============================================================================
   TAMAÑO MÍNIMO PARA EL DEDO
   =============================================================================
   Un botón de 9px de relleno mide unos 36px de alto. En una pantalla táctil el
   mínimo cómodo es 44: abajo de eso se falla el toque y hay que repetirlo, que
   en un botón de "Aprobar presupuesto" es exactamente donde no se quiere
   dudar. Solo se aplica en pantallas táctiles -- con mouse, 36px está bien y
   agrandar todo dejaría los formularios con aire de más.
   ============================================================================= */
@media (pointer:coarse){
  button, .btn, a.btn, label.btn-carga, [role="button"]{ min-height:44px }
  input:not([type=checkbox]):not([type=radio]), select, textarea{ min-height:44px }
  /* Los chips son etiquetas, no botones: solo se agrandan los que se pueden
     apretar. */
  .chip[role="button"], button.chip{ min-height:36px }
}

/* =============================================================================
   MOVIMIENTO REDUCIDO
   =============================================================================
   Hay gente a la que el movimiento en pantalla le produce mareo o dolor de
   cabeza -- es un problema físico, no una preferencia estética -- y lo deja
   configurado en su sistema. Respetarlo es una línea de CSS.

   No se apaga todo: las transiciones de color se dejan, porque son las que
   dicen "este botón respondió". Lo que se saca es lo que se mueve.
   ============================================================================= */
@media (prefers-reduced-motion:reduce){
  *, *::before, *::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  button:active:not(:disabled){ transform:none }
}

/* 29/09 (Ivan): el boton principal es VIDRIO violeta -- translucido, con contorno y un brillo arriba.
   El degradé (--grad) queda para detalles (barras de progreso, titulos), no para botones. */
.primario  { background:rgba(124,92,255,.18); color:#E9E2FF; border:1px solid rgba(150,120,255,.60);
             backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
             box-shadow:inset 0 1px 0 rgba(255,255,255,.10), 0 8px 22px -14px rgba(124,92,255,.85) }
.primario:hover:not(:disabled){ background:rgba(124,92,255,.30); border-color:rgba(175,150,255,.90); color:#fff; box-shadow:inset 0 1px 0 rgba(255,255,255,.14), 0 10px 26px -12px rgba(124,92,255,.95); transform:translateY(-1px) }
.primario:active:not(:disabled){ box-shadow:inset 2px 2px 5px rgba(0,0,0,.35); 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:rgba(255,107,122,.35) }
.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:rgba(255,255,255,.14); border:1px solid var(--borde); position:relative; cursor:pointer;
  box-shadow:inset 0 1px 3px rgba(0,0,0,.35);
  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(0,0,0,.4), 0 1px 1px rgba(0,0,0,.25);
  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(124,140,255,.4);
}
.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
   ============================================================================= */
/* Estas tres cajas siempre traen algo que acaba de pasar: un error, una
   confirmación, un aviso. Se escriben con innerHTML desde el javascript, o
   sea que aparecen sin que nadie las esté mirando. El role="status" va en
   el HTML de cada pantalla; esto es solo el recordatorio de por qué. */
.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:rgba(255,107,122,.35) }
.caja-ok { background:var(--ok-bg);  color:var(--ok);  border-color:rgba(61,220,151,.35) }
.caja-avi{ background:var(--avi-bg); color:var(--avi); border-color:rgba(240,172,63,.35) }
.caja-ok code, .caja-err code, .caja-avi code{
  background:rgba(0,0,0,.25); padding:2px 7px; border-radius:4px;
  color:var(--ink); 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;
  /* Los saltos de línea del mensaje se respetan. Sin esto, un correo de tres
     párrafos llegaba al portal convertido en un bloque corrido de texto: se
     leía como un error de la página y era solo CSS que faltaba. Y las
     direcciones largas se cortan en vez de estirar la tarjeta a lo ancho. */
  white-space:pre-wrap; overflow-wrap:anywhere; line-height:1.55;
}
/* La línea de autor no hereda el pre-wrap: es una sola línea armada a mano y
   con `pre-wrap` los espacios de la plantilla se veían dobles. */
.msg .de{ white-space:normal; }

/* Lo que llegó y todavía no se leyó. Se marca el mensaje, no solo la tarjeta:
   con la conversación abierta la pastilla de "sin leer" de arriba ya no se
   ve, y había que adivinar cuál era el mensaje nuevo. */
.msg.sin-leer{ box-shadow:0 0 0 2px var(--avi-bg), 0 0 0 3px var(--avi); }
.hilo-separador{
  display:flex; align-items:center; gap:8px; margin:14px 0 8px;
  font-size:10.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--avi);
}
.hilo-separador::before, .hilo-separador::after{
  content:""; flex:1; height:1px; background:currentColor; opacity:.35;
}
.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) }

/* Un mensaje que llego POR CORREO se muestra como un correo (29/09): cabecera
   con quien lo manda y cuando, el texto nuevo arriba y lo citado ("El ...
   escribio:", "> ...", "De: ...") plegado abajo en vez de un bloque corrido. */
.msg.correo{ border-left-color:var(--azul); background:var(--hueco); padding:0; overflow:hidden; white-space:normal }
.msg.correo.de-marca{ border-left-color:var(--marca) }
.msg.correo .correo-cab{ display:flex; align-items:center; gap:10px; padding:9px 12px;
  border-bottom:1px solid var(--linea); white-space:normal }
.msg.correo .correo-ico{ flex:none; width:28px; height:28px; border-radius:50%; display:flex;
  align-items:center; justify-content:center; background:var(--inf-bg); color:var(--azul); font-size:14px }
.msg.correo.de-marca .correo-ico{ background:var(--marca-bg); color:var(--marca) }
.msg.correo .correo-de{ min-width:0; flex:1; font-size:12.5px; line-height:1.35 }
.msg.correo .correo-de b{ display:block; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.msg.correo .correo-de span{ color:var(--tenue); font-size:11.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; display:block }
.msg.correo .correo-fecha{ flex:none; font-size:11.5px; color:var(--tenue); white-space:nowrap }
.msg.correo .correo-cuerpo{ padding:10px 12px; white-space:pre-wrap }
.msg.correo .citado{ margin:0 12px 10px; white-space:normal }
.msg.correo .citado summary{ cursor:pointer; font-size:12px; color:var(--azul); list-style:none }
.msg.correo .citado summary::-webkit-details-marker{ display:none }
.msg.correo .citado > div{ white-space:pre-wrap; margin-top:6px; padding-left:10px;
  border-left:2px solid var(--linea); color:var(--tenue); font-size:12.5px; max-height:320px; overflow:auto }
.correo-ref{ display:flex; align-items:center; gap:10px; padding:10px 12px; margin:0 0 12px;
  border:1px solid var(--linea); border-radius:var(--radio-chico); background:var(--hueco); font-size:13px }
.correo-ref .correo-ico{ flex:none; width:30px; height:30px; border-radius:50%; display:flex; align-items:center;
  justify-content:center; background:var(--marca-bg); color:var(--marca) }
.correo-ref .txt{ min-width:0; flex:1 }
.correo-ref .txt b{ display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.correo-ref .txt span{ font-size:11.5px; color:var(--tenue) }
.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(220px, 1fr));
  gap:14px; margin-bottom:16px;
}
.kpi{
  background:var(--blanco); border:1px solid rgba(255,255,255,.06);
  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; flex:1; container-type:inline-size } /* el hijo flex tambien necesita el suyo -- el del padre no alcanza */
.kpi .kpi-valor{
  font-size:22px; font-weight:800; color:var(--ink); line-height:1.15; letter-spacing:-.01em;
  /* Un monto no se parte por la mitad ("USD 259 / ,559"): entra achicandose. */
  white-space:nowrap; font-size:clamp(15px, 1.5vw, 22px);
  /* Se achica segun el ANCHO DE LA TARJETA (no de la ventana): "USD 2,419,366.00" entra entero.
     Si igual no entra, se corta con "..." adentro de la tarjeta en vez de salirse. */
  font-size:clamp(13px, 10cqi, 22px);
  overflow:hidden; text-overflow:ellipsis;
}
.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:12.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(0,0,0,.35), transparent) left / 10px 100% no-repeat,
      radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.35), 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:clamp(13px, 10cqi, 19px) }
  /* en el celular el icono va arriba: el monto usa todo el ancho de la tarjeta */
  .kpi{ flex-direction:column; align-items:stretch; gap:8px; padding:14px }
  .kpi .kpi-ico{ align-self:flex-start }
  .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.
   ============================================================================= */

/* =============================================================================
   COMPONENTES APROBADOS (29/09/2026) -- ver app/GUIA-DE-DISENO.md, seccion 8.
   Cualquier pantalla nueva usa ESTAS clases; no inventar otra version.
   ============================================================================= */
/* 8.1 titulo de seccion: rotulo fino + bolita turquesa + linea que se desvanece */
.tit-mod{ display:flex; align-items:center; gap:9px; margin:0 0 14px; padding:0 0 9px;
  font-size:12px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:#C9BEFF;
  background:linear-gradient(90deg, rgba(124,92,255,.9), rgba(91,140,255,.35) 40%, transparent 80%) 0 100% / 100% 1px no-repeat; }
.tit-mod::before{ content:""; width:9px; height:9px; border-radius:50%; flex:none;
  background:radial-gradient(circle at 32% 28%, #fff 0 14%, rgba(255,255,255,.45) 26%, transparent 46%),
             radial-gradient(circle at 50% 62%, #3FE6FF 0 52%, #0A7F9E 100%);
  box-shadow:0 0 10px rgba(63,230,255,.95), 0 0 2px rgba(63,230,255,1); }
/* 8.2 modulo activo */
.modulo{ position:relative; border:1px solid rgba(130,145,255,.12); transition:border-color .25s var(--facil), box-shadow .25s var(--facil); }
.modulo::before{ content:""; position:absolute; left:18px; right:18px; top:-1px; height:2px; border-radius:2px;
  background:linear-gradient(90deg, transparent, #3FE6FF 20%, #8B5CF6 80%, transparent);
  box-shadow:0 0 12px rgba(63,230,255,.6); opacity:0; transition:opacity .25s var(--facil); }
.modulo:focus-within{ border-color:rgba(165,145,255,.75);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), 0 0 0 1px rgba(124,92,255,.35), 0 22px 50px -18px rgba(108,77,246,.85), 0 0 44px -10px rgba(63,230,255,.28); }
.modulo:focus-within::before{ opacity:1; }
.modulo:focus-within .tit-mod{ color:#F1ECFF; background-image:linear-gradient(90deg, rgba(63,230,255,.95), rgba(124,92,255,.75) 35%, transparent 85%); }
.modulo:focus-within .tit-mod::before{ animation:bolita-late 2.4s ease-in-out infinite; }
.modulo:focus-within:has(.modulo:focus-within){ border-color:rgba(130,145,255,.12); box-shadow:none; }
.modulo:focus-within:has(.modulo:focus-within)::before{ opacity:0; }
@keyframes bolita-late{
  0%,100%{ box-shadow:0 0 10px rgba(63,230,255,.95), 0 0 2px rgba(63,230,255,1); transform:scale(1); }
  50%    { box-shadow:0 0 18px rgba(63,230,255,1), 0 0 5px rgba(63,230,255,1); transform:scale(1.18); } }
@media (prefers-reduced-motion:reduce){ .modulo:focus-within .tit-mod::before{ animation:none } }
/* 8.4 bolita de estado 3D */
.bolita{ display:inline-block; flex:none; width:12px; height:12px; border-radius:50%; --pt-c:#F5B642; --pt-o:#8F5605;
  background:radial-gradient(circle at 32% 28%, rgba(255,255,255,.95) 0 11%, rgba(255,255,255,.35) 22%, transparent 42%),
             radial-gradient(circle at 50% 62%, var(--pt-c) 0 52%, var(--pt-o) 100%);
  box-shadow:0 0 0 1px rgba(255,255,255,.10), 0 2px 4px rgba(0,0,0,.55), 0 0 10px -1px var(--pt-c),
             inset 0 -2px 3px rgba(0,0,0,.35), inset 0 1px 1px rgba(255,255,255,.35); }
.bolita.ok{ --pt-c:#3DDC97; --pt-o:#0E6B44; } .bolita.err{ --pt-c:#FF6B7A; --pt-o:#8E1A2A; }
.bolita.turq{ --pt-c:#3FE6FF; --pt-o:#0A7F9E; }
/* 8.5 chips: siempre dentro de .chips */
.chips{ display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
.chips:empty{ display:none; }
/* 8.6 tarjeta que carga */
.ficha-carga{ position:relative; cursor:pointer; padding-bottom:34px;
  transition:border-color .2s var(--facil), box-shadow .2s var(--facil), transform .2s var(--facil); }
.ficha-carga .fcargar{ position:absolute; bottom:8px; right:10px; display:inline-flex; align-items:center; gap:4px;
  font-size:10.5px; font-weight:700; padding:3px 8px; border-radius:999px; color:#E9E2FF;
  background:rgba(124,92,255,.18); border:1px solid rgba(150,120,255,.55); opacity:0; transition:opacity .2s var(--facil); }
.ficha-carga .fcargar svg{ width:11px; height:11px; }
.ficha-carga:hover, .ficha-carga:focus-visible{ border-color:rgba(165,145,255,.7); outline:none; transform:translateY(-2px);
  box-shadow:0 0 0 1px rgba(124,92,255,.3), 0 14px 30px -16px rgba(108,77,246,.9), 0 0 26px -10px rgba(63,230,255,.35); }
.ficha-carga:hover .fcargar, .ficha-carga:focus-visible .fcargar, .ficha-carga.vacia .fcargar{ opacity:1; }
@media (hover:none){ .ficha-carga .fcargar{ opacity:.85 } }
/* 8.7 placa de total */
.placa-total{ display:flex; justify-content:space-between; align-items:center; gap:12px; padding:11px 14px; border-radius:12px;
  background:linear-gradient(135deg, rgba(91,140,255,.14), rgba(139,92,246,.18)); border:1px solid rgba(150,130,255,.38);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10), 0 10px 26px -16px rgba(124,92,255,.9); font-weight:700; }
.placa-total .importe{ font-size:20px; font-weight:800; font-family:var(--mono);
  background:linear-gradient(90deg, #A9C0FF, #C9B8FF); -webkit-background-clip:text; background-clip:text; color:transparent; }
/* 8.8 interruptor */
input[type=checkbox].interruptor{ appearance:none; -webkit-appearance:none; margin:0; width:36px; height:21px; border-radius:999px; flex:none;
  position:relative; cursor:pointer; background:rgba(8,11,34,.9); border:1px solid rgba(130,145,255,.22); box-shadow:inset 0 2px 4px rgba(0,0,0,.55);
  transition:background .18s var(--facil), box-shadow .18s var(--facil); }
input[type=checkbox].interruptor::after{ content:''; position:absolute; top:1px; left:1px; width:17px; height:17px; border-radius:50%;
  background:radial-gradient(circle at 34% 30%, #fff 0 18%, #D9DEF5 40%, #9AA3C9 100%);
  box-shadow:0 2px 4px rgba(0,0,0,.5), inset 0 -1px 2px rgba(0,0,0,.2); transition:transform .18s var(--facil); }
input[type=checkbox].interruptor:checked{ background:linear-gradient(120deg, #3D6BFF, #8B5CF6); border-color:rgba(175,150,255,.7);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.25), 0 0 14px rgba(124,92,255,.6); }
input[type=checkbox].interruptor:checked::after{ transform:translateX(15px); }
/* 8.10 texto buscado resaltado */
mark.hl{ background:rgba(63,230,255,.16); color:#8FF3FF; border-radius:3px; padding:0 1px; box-shadow:inset 0 -1px 0 rgba(63,230,255,.6); }
/* 8.14 (30/09) TODAS las pantallas: el titulo de un .bloque ES un .tit-mod y el
   .bloque ES un .modulo. Asi ninguna pagina vieja queda con la pastilla navy. */
.bloque{ position:relative; border:1px solid rgba(130,145,255,.12);
  background:linear-gradient(180deg, rgba(20,26,64,.92), rgba(12,16,44,.92));
  transition:border-color .25s var(--facil), box-shadow .25s var(--facil); }
.bloque::before{ content:""; position:absolute; left:18px; right:18px; top:-1px; height:2px; border-radius:2px; pointer-events:none;
  background:linear-gradient(90deg, transparent, #3FE6FF 20%, #8B5CF6 80%, transparent);
  box-shadow:0 0 12px rgba(63,230,255,.6); opacity:0; transition:opacity .25s var(--facil); }
.bloque:focus-within{ border-color:rgba(165,145,255,.75);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), 0 0 0 1px rgba(124,92,255,.35), 0 22px 50px -18px rgba(108,77,246,.85), 0 0 44px -10px rgba(63,230,255,.28); }
.bloque:focus-within::before{ opacity:1; }
.bloque:focus-within:has(.bloque:focus-within){ border-color:rgba(130,145,255,.12); box-shadow:var(--alto); }
.bloque:focus-within:has(.bloque:focus-within)::before{ opacity:0; }
.bloque h2{ display:flex; align-items:center; gap:9px; margin:0 0 14px; padding:0 0 9px; border-radius:0;
  font-size:12px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:#C9BEFF;
  background:linear-gradient(90deg, rgba(124,92,255,.9), rgba(91,140,255,.35) 40%, transparent 80%) 0 100% / 100% 1px no-repeat; }
.bloque h2::before{ content:""; width:9px; height:9px; border-radius:50%; flex:none;
  background:radial-gradient(circle at 32% 28%, #fff 0 14%, rgba(255,255,255,.45) 26%, transparent 46%),
             radial-gradient(circle at 50% 62%, #3FE6FF 0 52%, #0A7F9E 100%);
  box-shadow:0 0 10px rgba(63,230,255,.95), 0 0 2px rgba(63,230,255,1); }
.bloque h2:has(> .ico, > svg)::before{ display:none; }
.bloque h2 > .ico, .bloque h2 > svg{ color:#3FE6FF; filter:drop-shadow(0 0 6px rgba(63,230,255,.6)); }
.bloque:focus-within h2{ color:#F1ECFF; background-image:linear-gradient(90deg, rgba(63,230,255,.95), rgba(124,92,255,.75) 35%, transparent 85%); }
.bloque:focus-within h2::before{ animation:bolita-late 2.4s ease-in-out infinite; }
.bloque h2 + .sub{ margin-top:-4px }
@media (prefers-reduced-motion:reduce){ .bloque:focus-within h2::before{ animation:none } }
@media (max-width:640px){ .bloque h2{ font-size:11.5px; letter-spacing:.1em } }

/* 8.15 (30/09) botones de segundo nivel y "Elegir archivo": vidrio suave, misma familia */
.secundario, .mini{ background:rgba(124,92,255,.07); color:#C9BEFF; border:1px solid rgba(150,120,255,.38);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06); }
.secundario:hover:not(:disabled), .mini:hover:not(:disabled){ background:rgba(124,92,255,.20); border-color:rgba(175,150,255,.85); color:#fff;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12), 0 8px 20px -12px rgba(124,92,255,.9); }
.mini.peligro{ background:rgba(255,107,122,.06); color:#FF8A96; border-color:rgba(255,107,122,.38) }
input[type=file]::file-selector-button{ background:rgba(124,92,255,.18); color:#E9E2FF; border:1px solid rgba(150,120,255,.6);
  border-radius:9px; box-shadow:inset 0 1px 0 rgba(255,255,255,.10); }
input[type=file]:hover::file-selector-button{ background:rgba(124,92,255,.32); border-color:rgba(175,150,255,.9); }
/* 8.16 modulo activo del menu de arriba: vidrio violeta con filo turquesa abajo */
.barra nav a.on{ background:rgba(124,92,255,.22); color:#fff;
  box-shadow:inset 0 0 0 1px rgba(150,120,255,.55), inset 0 1px 0 rgba(255,255,255,.12), inset 0 -2px 0 rgba(63,230,255,.8), 0 0 18px -4px rgba(124,92,255,.7); }
/* 8.17 cajas de explicacion dentro de un bloque: vidrio, no losa azul */
.bloque .explica{ background:linear-gradient(135deg, rgba(91,140,255,.10), rgba(139,92,246,.10)); border:1px solid rgba(150,130,255,.26);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06); }

/* 8.18 pestanas/solapas elegidas (fichas, marca, portal): vidrio violeta, no navy plano */
body .tabs button.on, body .solapas button.on{ background:rgba(124,92,255,.24); border-color:rgba(165,140,255,.75); color:#fff;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14), 0 0 18px -6px rgba(124,92,255,.9); }

/* 8.19 enlaces sueltos dentro del texto: celeste legible, nunca el azul por defecto */
.bloque a:not([class]), .sub a:not([class]){ color:#9DB4FF; text-decoration-color:rgba(157,180,255,.45); text-underline-offset:2px }
.bloque a:not([class]):hover, .sub a:not([class]):hover{ color:#8FF3FF }

/* 8.20 (30/09) CHIPS: una sola medida y una sola forma en TODAS las pantallas
   (equipo, marca, portal y cotizador, que tiene la misma copia como .pc).
   22px, pildora, vidrio del color de su tono, borde del mismo color.
   Tonos: c-ok verde · c-avi ambar · c-err rojo · c-inf azul · c-gris gris · c-turq turquesa.
   .fuerte = pide accion (borde mas marcado y un leve brillo). */
.chip, .pc{ --r:142,149,184; --c:#C3C8E4;
  display:inline-flex; align-items:center; gap:5px; height:22px; padding:0 9px; border-radius:999px;
  font-size:11px; font-weight:700; line-height:1; letter-spacing:.01em; white-space:nowrap; vertical-align:middle;
  color:var(--c); background:rgba(var(--r),.12); border:1px solid rgba(var(--r),.38); box-shadow:inset 0 1px 0 rgba(255,255,255,.08); }
.chip svg, .pc svg{ width:11px; height:11px; flex:none; }
.c-ok, .pc.ok{ --r:61,220,151; --c:#7FF0BF } .c-err, .pc.err{ --r:255,107,122; --c:#FF9AA5 }
.c-avi, .c-adv, .pc.avi{ --r:240,172,63; --c:#FFD27A } .c-inf, .pc.inf{ --r:91,140,255; --c:#B9CBFF }
.c-gris, .pc.neu{ --r:142,149,184; --c:#C3C8E4 } .c-turq, .pc.turq{ --r:63,230,255; --c:#8FF3FF }
.chip.c-ok, .chip.c-err, .chip.c-avi, .chip.c-adv, .chip.c-inf, .chip.c-gris, .chip.c-turq{ background:rgba(var(--r),.12); color:var(--c); }
.chip.fuerte, .pc.fuerte{ background:rgba(var(--r),.22); border-color:rgba(var(--r),.62); box-shadow:inset 0 1px 0 rgba(255,255,255,.12), 0 0 12px -4px rgba(var(--r),.8); }
@media (max-width:640px){ .chip{ font-size:11px; padding:0 9px } }

a.mini, a.secundario{ display:inline-flex; align-items:center; gap:6px; text-decoration:none; border-radius:var(--radio-chico); }

/* 8.24 (30/09) SEGMENTO: elegir una opción entre pocas (Antes/Después de la galería).
   Una cápsula hundida con las opciones adentro; la elegida en vidrio violeta con filo turquesa. */
.segmento{ display:inline-flex; flex-wrap:nowrap; align-items:center; gap:2px; padding:3px; border-radius:12px; max-width:100%;
  background:rgba(8,11,34,.6); border:1px solid rgba(130,145,255,.22); box-shadow:inset 0 1px 3px rgba(0,0,0,.45);
  overflow-x:auto; scrollbar-width:none; -webkit-overflow-scrolling:touch; }
.segmento::-webkit-scrollbar{ display:none; }
.segmento > button{ flex:none; margin:0 !important; background:transparent !important; border:0 !important; box-shadow:none !important;
  color:#9AA1C4 !important; font-weight:600 !important; font-size:12.5px; padding:6px 13px !important; border-radius:9px !important;
  white-space:nowrap; min-height:0; display:inline-flex; align-items:center; gap:6px; cursor:pointer;
  transition:background .2s cubic-bezier(.32,.72,0,1), color .2s, box-shadow .2s; }
.segmento > button:hover{ color:#E6E9FF !important; background:rgba(124,92,255,.10) !important; }
.segmento > button.on, .segmento > button.activo{ color:#fff !important; background:rgba(124,92,255,.26) !important;
  box-shadow:inset 0 0 0 1px rgba(165,140,255,.75), inset 0 -2px 0 #3FE6FF, 0 0 16px -6px rgba(124,92,255,.9) !important; }
.segmento > button .n{ opacity:.65; font-weight:700; }
.segmento > button.on .n, .segmento > button.activo .n{ opacity:.9; }
.segmento:not(.ancho){ width:fit-content; }
.segmento.ancho{ display:flex; } .segmento.ancho > button{ flex:1 1 0; justify-content:center; }

/* 8.13 barras de desplazamiento */
::-webkit-scrollbar{ width:10px; height:10px; }
::-webkit-scrollbar-thumb{ background:linear-gradient(180deg, #3D4FB0, #5B3FB8); border-radius:10px; border:2px solid var(--fondo); }
::-webkit-scrollbar-thumb:hover{ background:linear-gradient(180deg, #5B6FE0, #7B5CE8); }
html{ scrollbar-color:#4A4FB8 transparent; }

@media print{
  body{ background:#fff }
  .barra, nav, button{ display:none !important }
  .bloque{ box-shadow:none; border:1px solid var(--borde) }
}
