/* ============================================================
   VEBRA CORE — Sistema de diseño
   TEMA OSCURO ÚNICO · centro de control

   No hay modo claro. Es una decisión, no un olvido: la marca vive
   en consola, y sostener dos paletas duplica cada medición de
   contraste sin que nadie pida la otra.

   Toda cifra de este archivo está MEDIDA, no estimada.
   Superficies de referencia: #0B0D0F (página) y #14171C (tarjeta).
   ============================================================ */

:root{
  /* ---------- LOS SIETE DEL ENCARGO ----------
     La cara pública del sistema. Quien abra este archivo buscando
     --accent-cyan lo encuentra en la primera pantalla. */
  --bg-main:#0B0D0F;        /* fondo principal — el 60 % */
  --bg-card:#14171C;        /* tarjetas, bloques y el menú */
  --text-main:#FFFFFF;      /* 19.47:1 sobre el fondo — el 30 % */
  --text-muted:#94A3B8;     /*  7.59:1 sobre fondo · 7.01:1 sobre tarjeta */
  --accent-cyan:#00E5FF;    /* 12.66:1 — el 10 % */
  --accent-glow:rgba(0, 229, 255, 0.4);
  --border-color:#1E232A;   /* filete técnico. 1.23:1 → SOLO decorativo */

  /* ---------- lo que el encargo no nombra pero el sistema necesita ----------
     --border-color delimita bien una tarjeta, pero un CONTROL necesita 3:1
     (WCAG 1.4.11) o su silueta se disuelve. De ahí el borde fuerte. */
  --borde-fuerte:#667180;   /* 3.93:1 sobre fondo · 3.63:1 sobre tarjeta */
  --bg-elevado:#1A1F26;     /* un paso por encima de la tarjeta */
  --bg-consola:#14171C;     /* la banda de identidad física */
  --tinta-sobre-cian:#0B0D0F;   /* 12.66:1 — la tinta del botón cian */
  --texto-medio:#CBD5E1;    /* 13.11:1 · el escalón entre blanco y apagado */

  /* ---------- alias de compatibilidad ----------
     Los usan cientos de reglas escritas para el tema claro. Apuntan aquí,
     así que el sistema tiene una sola fuente de verdad y ningún componente
     necesita tocarse. */
  --blanco:var(--bg-card);
  --platino:var(--bg-main);
  --platino-2:var(--bg-elevado);
  --antracita:var(--bg-consola);
  --antracita-2:var(--bg-elevado);
  --carbono:#06080A;
  --bg-cloud:var(--bg-card);
  --text-muted-oscuro:var(--text-muted);
  --tinta:var(--text-main);
  --tinta-media:var(--texto-medio);
  --apagado:var(--text-muted);
  --borde:var(--border-color);

  /* ---------- acento: dos papeles ----------
     Sobre fondo oscuro el cian ya es legible como TEXTO (12.66:1), así que
     desaparece el tercer papel que hacía falta en claro. Sigue sin ser fondo
     de texto claro: encima solo va tinta oscura. */
  --cian:var(--accent-cyan);
  --cian-suave:#5CEEFF;
  --cian-texto:var(--accent-cyan);

  /* ACCIÓN — el azul de relleno. Como TEXTO sobre tarjeta #1D4ED8 solo da
     2.68:1, de ahí que el de texto sea otro tono. */
  --cobalto:#2563EB;        /* 5.17:1 con blanco encima */
  --cobalto-hover:#3B82F6;
  --cobalto-suave:#131B2B;
  --cobalto-texto:#60A5FA;  /* 7.66 fondo · 7.07 tarjeta · 6.51 elevado */

  /* ---------- semánticos: nunca solos, siempre con icono o texto ---------- */
  --exito:#4ADE9B;   --exito-fondo:#0F2A1E;
  --alerta:#E0B255;  --alerta-fondo:#2E2412;
  --critico:#F08A8A; --critico-fondo:#2E1616;

  /* ---------- efectos ---------- */
  /* el color de la etiqueta técnica: lo redefine cada superficie oscura */
  --color-eyebrow:var(--accent-cyan);   /* 12.66:1 sobre el fondo oscuro */
  --glow:0 0 0 1px rgb(0 229 255 / .55), 0 0 18px -2px rgb(0 229 255 / .45);
  --glow-suave:0 0 24px -6px rgb(0 229 255 / .38);
  --glow-boton:0 0 20px var(--accent-glow);
  --panel:0 1px 2px rgb(0 0 0 / .5), 0 10px 30px -14px rgb(0 0 0 / .7);
  --anillo:0 0 0 3px color-mix(in srgb, var(--accent-cyan) 35%, transparent);

  /* ---------- tipografía ---------- */
  --f-display:"Plus Jakarta Sans", system-ui, -apple-system, sans-serif;
  --f-sans:Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Consolas, monospace;

  --t-xs:.75rem; --t-sm:.875rem; --t-base:1rem; --t-lg:1.125rem;
  --t-xl:clamp(1.25rem, 1.1rem + .7vw, 1.5rem);
  --t-2xl:clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
  --t-3xl:clamp(2rem, 1.5rem + 2.4vw, 3rem);
  --t-4xl:clamp(2.5rem, 1.6rem + 4.2vw, 4.5rem);

  /* ---------- espaciado: rejilla base de 4 px ----------
     Todo múltiplo de 4. Es lo que hace que "precisión matemática"
     se perciba sin que nadie sepa por qué. */
  --s-1:.25rem; --s-2:.5rem;  --s-3:.75rem; --s-4:1rem;
  --s-6:1.5rem; --s-8:2rem;   --s-12:3rem;  --s-16:4rem;
  --s-24:6rem;  --s-32:8rem;

  /* ---------- radios: 10 px por defecto ----------
     Ni cuadrado (agresivo, anticuado) ni muy redondeado (blando, consumo). */
  --r-sm:6px; --r:10px; --r-lg:14px; --r-xl:20px; --r-full:9999px;

  /* ---------- movimiento: una sola curva en todo el sistema ---------- */
  --curva:cubic-bezier(.16, 1, .3, 1);
  --dur:200ms;

  color-scheme:dark;
}



/* ============================================================
   PALETA CLARA — variante para comparar
   ------------------------------------------------------------
   El sistema por defecto es OSCURO (el :root de arriba). Esta
   variante se activa poniendo data-paleta="clara" en <html>.

   Va en un atributo PROPIO y no en data-theme ni en
   prefers-color-scheme a propósito: así la elección de paleta de
   marca no se mezcla con la preferencia de tema del visitante, que
   es otra decisión y de otro dueño.

   Cifras medidas sobre #FFFFFF (página) y #F8F9FA (tarjeta).
   ============================================================ */
:root[data-paleta="clara"]{
  --bg-main:#FFFFFF;
  --bg-card:#F8F9FA;
  --text-main:#1A1D20;      /* 16.93:1 sobre blanco */
  --text-muted:#5A626A;     /*  6.19:1 sobre blanco · 5.88:1 sobre tarjeta */
  --accent-cyan:#00E5FF;    /* el mismo cian: es la marca, no el tema */
  --accent-glow:rgba(0, 229, 255, 0.4);
  --border-color:#DDE3EA;

  --borde-fuerte:#7C8794;   /* 3.65:1 sobre blanco */
  --bg-elevado:#E8ECF0;
  --bg-consola:#1A1D20;     /* aquí la banda SÍ corta: oscura sobre claro */
  --tinta-sobre-cian:#1A1D20;
  --texto-medio:#3D4650;
  --carbono:#0B0F14;
  --text-muted-oscuro:#A9B4C0;   /* 8.72:1 sobre la banda de consola */

  /* sobre claro el cian NO es legible como texto (1.54:1): vuelve el
     tercer papel del acento, un cian oscurecido solo para texto */
  --cian-texto:#0E7490;     /* 5.36:1 sobre blanco */
  --cobalto:#1D4ED8;        /* 6.70:1 con blanco encima */
  --cobalto-hover:#1743B8;
  --cobalto-suave:#EFF4FE;
  --cobalto-texto:#1D4ED8;

  --exito:#0F7B4F;    --exito-fondo:#E8F5EF;
  --alerta:#9A5B00;   --alerta-fondo:#FDF3E3;
  --critico:#C02626;  --critico-fondo:#FDECEC;

  --panel:0 1px 2px rgb(11 15 20 / .04), 0 8px 24px -12px rgb(11 15 20 / .12);
  color-scheme:light;
}
/* En la paleta clara el cian no se lee (1.54:1 sobre blanco) y la etiqueta
   vuelve al antracita — salvo dentro de una banda oscura, donde el antracita
   sería invisible y el cian rinde 11.0:1. Se resuelve por superficie: */
:root[data-paleta="clara"]{ --color-eyebrow:var(--text-main) }
:root[data-paleta="clara"] .sec--consola,
:root[data-paleta="clara"] .cierre,
:root[data-paleta="clara"] footer{ --color-eyebrow:var(--accent-cyan) }

/* ============================================================
   Base
   ============================================================ */
*{box-sizing:border-box}
html{background:var(--bg-main);scroll-behavior:smooth}
body{
  margin:0;
  background:var(--bg-main);
  color:var(--tinta);
  font-family:var(--f-sans);
  font-size:var(--t-base);          /* 16px. Nunca menos en cuerpo. */
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4{font-family:var(--f-display);margin:0;text-wrap:balance;letter-spacing:-.025em;line-height:1.15}
p{margin:0;max-width:68ch}
a{color:inherit}
img,svg{max-width:100%}
code,.mono{font-family:var(--f-mono)}
::selection{background:var(--cobalto);color:#fff}

/* El foco NUNCA se quita sin reemplazo. */
:focus-visible{outline:2px solid var(--cobalto);outline-offset:2px}

.env{max-width:1180px;margin:0 auto;padding:0 clamp(1.25rem, 4vw, 2.5rem)}

/* Etiqueta técnica: señalética, no lectura. Siempre mayúsculas con tracking. */
/* Etiqueta técnica: señalética, no lectura.
   Sobre fondo claro el cian era ilegible (1.54:1) y hubo que ponerla en
   antracita. Sobre #0B0D0F rinde 12.66:1, así que vuelve al cian, que es
   donde el encargo la quería: un indicador técnico, no un titular. */
.eyebrow{
  font-family:var(--f-mono);font-size:var(--t-xs);font-weight:600;
  text-transform:uppercase;letter-spacing:.2em;color:var(--color-eyebrow);
}

/* Cifras en columna: sin esto las tablas bailan. */
.tabular{font-variant-numeric:tabular-nums}

/* ============================================================
   ISOTIPO — dónde vive y por qué se pinta así
   ------------------------------------------------------------
   Los archivos:
     assets/marca/isotipo.svg            uso general, de 24 px en adelante
     assets/marca/isotipo-compacto.svg   por debajo de 24 px, trazo engordado
     assets/marca/isotipo-contenido.svg  con área de respeto, para terceros
     assets/marca/lockup-horizontal.svg  isotipo + palabra
     assets/marca/mascota.svg            Nodo — pieza distinta, otro trabajo

   No va como <img> sino como MÁSCARA CSS. El motivo: una máscara se rellena
   con `background-color: currentColor`, así que la misma pieza sirve en
   tinta sobre blanco, en blanco sobre antracita y en cian, sin exportar tres
   archivos ni arriesgar que uno se quede sin actualizar.

   En HTML basta <span class="marca"></span>: hereda el color del texto que
   la rodea. No lleva texto dentro, así que solo necesita nombre accesible
   cuando es el único contenido de un enlace.

   Al portarlo a React/Tailwind: o se conserva la máscara
   (`mask-image:url(...)` + `bg-current`), o se pasa a componente SVG en
   línea con `fill="currentColor"`. Lo que NO sirve es <img>: pierde la
   herencia de color y obliga a mantener los tres archivos a mano.
   ============================================================ */
.marca{
  display:inline-block;background-color:currentColor;flex-shrink:0;
  width:32px;height:32px;
  -webkit-mask:url("marca/isotipo.svg") center/contain no-repeat;
  mask:url("marca/isotipo.svg") center/contain no-repeat;
}
.marca--compacta{
  -webkit-mask-image:url("marca/isotipo-compacto.svg");
  mask-image:url("marca/isotipo-compacto.svg");
}

/* ============================================================
   Botones
   ============================================================ */
.btn{
  font-family:var(--f-sans);font-weight:600;font-size:.92rem;
  padding:.72rem 1.35rem;border-radius:var(--r);border:1px solid transparent;
  cursor:pointer;text-decoration:none;display:inline-flex;align-items:center;gap:.5rem;
  min-height:44px;                  /* objetivo táctil */
  transition:background-color var(--dur) var(--curva),
             border-color var(--dur) var(--curva),
             box-shadow var(--dur) var(--curva),
             transform var(--dur) var(--curva);
}
.btn--primario{background:var(--cobalto);color:#fff}
.btn--primario:hover{background:var(--cobalto-hover);transform:translateY(-1px)}
.btn--primario:active{transform:translateY(0)}

.btn--secundario{background:var(--blanco);color:var(--tinta);border-color:var(--borde-fuerte)}
.btn--secundario:hover{border-color:var(--cian);box-shadow:var(--glow-suave)}
.btn--secundario:active{transform:scale(.985)}

/* ============================================================
   Superficies
   ============================================================ */
.tarjeta{
  background:var(--bg-cloud);
  border:1px solid var(--borde);      /* ultrafino, pero SIEMPRE visible */
  border-radius:var(--r);
  padding:var(--s-6);box-shadow:var(--panel);
  transition:all .3s ease;
}
/* El cian se enciende solo al pasar por encima. Va acompañado del halo y del
   desplazamiento a propósito: #00E5FF sobre #F8F9FA da 1.46:1 de contorno, muy
   por debajo del 3:1 que pide WCAG 1.4.11, así que no puede ser la única señal
   de estado. El borde base gris es el que delimita la tarjeta; el cian solo
   añade. */
.tarjeta--viva:hover{
  border-color:var(--accent-cyan);
  box-shadow:0 0 20px var(--accent-glow);
  transform:translateY(-2px);
}
.tarjeta--viva:focus-visible{
  border-color:var(--accent-cyan);
  box-shadow:0 0 20px var(--accent-glow);
}
@media (prefers-reduced-motion:reduce){
  .tarjeta{transition:none}
  .tarjeta--viva:hover{transform:none}
}
/* Bloque oscuro: el único hábitat donde el cian rinde de verdad (9.86:1). */
.oscuro{background:var(--antracita);color:#F0F3F6;border-radius:var(--r-lg);padding:var(--s-8)}
.oscuro .eyebrow{color:var(--cian)}

/* ============================================================
   Formularios
   ============================================================ */
.campo{display:flex;flex-direction:column;gap:.35rem}
.campo>label{
  font-family:var(--f-mono);font-size:.68rem;text-transform:uppercase;
  letter-spacing:.1em;color:color-mix(in srgb, var(--tinta) 70%, transparent);
}
.campo input,.campo select,.campo textarea{
  font-family:var(--f-sans);font-size:.92rem;color:var(--tinta);
  background:var(--platino-2);
  border:1px solid var(--borde-fuerte);   /* 3:1 — WCAG 1.4.11 */
  border-radius:8px;padding:.68rem .85rem;width:100%;
  transition:border-color var(--dur) var(--curva),
             box-shadow var(--dur) var(--curva),
             background-color var(--dur) var(--curva);
}
.campo input:hover,.campo select:hover,.campo textarea:hover{border-color:var(--apagado)}
.campo input:focus,.campo select:focus,.campo textarea:focus{
  outline:none;background:var(--blanco);border-color:var(--cobalto);box-shadow:var(--anillo);
}
.campo input::placeholder,.campo textarea::placeholder{color:var(--apagado);opacity:1}

/* ============================================================
   Estado en vivo — reservado a lo que de verdad está ocurriendo.
   Si parpadea algo estático, la señal se devalúa y deja de significar nada.
   ============================================================ */
.punto-vivo{
  width:8px;height:8px;border-radius:50%;background:var(--cian);display:inline-block;flex-shrink:0;
  position:relative;
}
/* El anillo es un pseudoelemento propio, no una box-shadow animada.
   Animar box-shadow obliga al navegador a repintar el elemento en cada
   fotograma; transform y opacity los resuelve el compositor sin repintar.
   Se ve igual y deja de costar. */
.punto-vivo::after{
  content:"";position:absolute;inset:0;border-radius:50%;
  border:1px solid var(--cian);opacity:0;
}
@media (prefers-reduced-motion:no-preference){
  .punto-vivo::after{animation:latido 2.4s var(--curva) infinite}
  @keyframes latido{
    0%  {transform:scale(1);   opacity:.6}
    70% {transform:scale(3);   opacity:0}
    100%{transform:scale(3);   opacity:0}
  }
}

/* No es un extra: para alguien con trastorno vestibular, ignorar esta
   preferencia produce mareo real. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important;
  }
}

/* ============================================================
   Portada de idioma (primera visita)
   ------------------------------------------------------------
   Nace oculta: solo el script del <head> la enciende con .gate-on
   en <html>. Un visitante sin JS jamás queda atrapado frente a dos
   botones que no responden.

   Va oscura en los dos temas a propósito. No es una sección del
   sitio: es el umbral. Y es el único sitio donde el cian manda,
   porque sobre antracita rinde 9.86:1.
   ============================================================ */
.gate{display:none}
html.gate-on{overflow:hidden}
html.gate-on .gate{
  position:fixed;inset:0;z-index:1300;display:flex;
  align-items:center;justify-content:center;padding:var(--s-6);
  background:#0B0F14;overflow-y:auto;
}
.gate::before{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(58% 50% at 50% 0%, rgb(34 211 238 / .17), transparent 68%);
}
.gate::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(rgb(255 255 255 / .05) 1px, transparent 1px),
                   linear-gradient(90deg, rgb(255 255 255 / .05) 1px, transparent 1px);
  background-size:56px 56px;
  mask-image:radial-gradient(65% 55% at 50% 35%, #000, transparent 78%);
  -webkit-mask-image:radial-gradient(65% 55% at 50% 35%, #000, transparent 78%);
}
.gate-panel{position:relative;width:100%;max-width:600px;text-align:center}
@media (prefers-reduced-motion:no-preference){
  .gate-panel{animation:gate-entra .55s var(--curva) both}
  @keyframes gate-entra{from{opacity:0;transform:translateY(14px) scale(.985)}to{opacity:1;transform:none}}
}
.gate .marca{color:var(--cian);width:44px;height:44px;margin-bottom:var(--s-6)}
.gate .gate-t{
  font-size:clamp(1.6rem, 1.2rem + 2.2vw, 2.3rem);font-weight:800;color:#fff;
  margin-bottom:var(--s-8);display:flex;flex-direction:column;gap:.15rem;
}
.gate .gate-t .alt{color:rgb(255 255 255 / .58);font-size:.82em}

.gate-ops{display:grid;grid-template-columns:1fr 1fr;gap:.85rem}
@media (max-width:560px){.gate-ops{grid-template-columns:1fr}}
.gate-op{
  position:relative;display:flex;align-items:center;justify-content:space-between;gap:1rem;
  text-align:left;cursor:pointer;padding:1.15rem 1.25rem;border-radius:var(--r-lg);
  background:rgb(255 255 255 / .045);border:1px solid rgb(255 255 255 / .14);color:#fff;
  font-family:var(--f-sans);min-height:44px;
  transition:background-color var(--dur) var(--curva),
             border-color var(--dur) var(--curva),
             transform var(--dur) var(--curva);
}
.gate-op b{font-size:1.08rem;font-weight:600;letter-spacing:-.01em;display:block}
.gate-op i{font-style:normal;font-size:.79rem;color:rgb(255 255 255 / .62)}
.gate-op svg{width:19px;height:19px;flex-shrink:0;color:rgb(255 255 255 / .45);
             transition:transform var(--dur) var(--curva), color var(--dur) var(--curva)}
.gate-op:hover{background:rgb(255 255 255 / .09);border-color:var(--cian)}
.gate-op:hover svg{transform:translateX(4px);color:#fff}
.gate-op:focus-visible{outline:2px solid var(--cian);outline-offset:3px}
.gate-op:active{transform:scale(.985)}
/* La sugerida por el navegador va marcada, pero las dos pesan igual:
   es una sugerencia, no una decisión tomada por el visitante. */
.gate-op.sug{border-color:rgb(34 211 238 / .78);background:rgb(34 211 238 / .12)}
.gate-op.sug svg{color:#fff}

.gate-pie{
  display:flex;align-items:center;justify-content:center;gap:.45rem;flex-wrap:wrap;
  margin:var(--s-8) auto 0;font-size:.78rem;color:rgb(255 255 255 / .55);max-width:none;
}
.gate.saliendo{opacity:0;transition:opacity .3s ease}
@media (prefers-reduced-motion:reduce){.gate.saliendo{transition:none}}

/* ============================================================
   Contacto: botón flotante + ventana con formulario
   ============================================================ */
.fab{position:fixed;right:1.25rem;bottom:1.25rem;z-index:998;
     box-shadow:0 12px 30px -10px color-mix(in srgb,var(--cobalto) 55%,transparent),
                0 4px 12px -4px rgb(0 0 0 / .3)}
/* En móvil se queda el círculo: una píldora con texto a 375 px se come el
   ancho y tapa contenido mientras el visitante lee. */
@media (max-width:560px){
  .fab{right:1rem;bottom:1rem;padding:0;width:54px;height:54px;justify-content:center;border-radius:50%}
  .fab .et{display:none}
}
html.gate-on .fab{display:none}

/* z-index 1100: sobre el widget flotante (1000), debajo de la portada de idioma (1300).
   La regla :target es la red sin JS — el enlace apunta al id de verdad. */
.modal{display:none;position:fixed;inset:0;z-index:1100;
       align-items:center;justify-content:center;padding:var(--s-6);overflow-y:auto}
.modal:target,.modal.abierta{display:flex}
html.modal-abierta{overflow:hidden}
.modal-fondo{position:fixed;inset:0;background:rgb(6 8 10 / .72);backdrop-filter:blur(3px)}
.modal-caja{position:relative;width:100%;max-width:620px;margin:auto;
            background:var(--blanco);border:1px solid var(--borde);border-radius:var(--r-lg);
            box-shadow:0 30px 70px -25px rgb(0 0 0 / .5)}
@media (prefers-reduced-motion:no-preference){
  .modal-caja{animation:modal-entra .3s var(--curva) both}
  @keyframes modal-entra{from{opacity:0;transform:translateY(16px) scale(.99)}to{opacity:1;transform:none}}
}
.modal-cuerpo{padding:clamp(1.5rem,4vw,2.25rem)}
.modal-cuerpo h2{font-size:var(--t-xl);font-weight:700;margin:var(--s-3) 0 var(--s-2)}
.modal-bajada{color:var(--apagado);font-size:.92rem;margin-bottom:var(--s-6)}
.modal-x{position:absolute;top:.75rem;right:.75rem;z-index:2;cursor:pointer;
         width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;
         background:var(--platino-2);border:1px solid var(--borde);color:var(--tinta);
         transition:background-color var(--dur) var(--curva),border-color var(--dur) var(--curva)}
.modal-x svg{width:17px;height:17px}
.modal-x:hover{border-color:var(--borde-fuerte);background:var(--platino)}
@media (max-width:560px){
  .modal{padding:0}
  .modal-caja{max-width:none;min-height:100vh;border-radius:0;border:0}
}

/* ---- formulario ---- */
.form-fila{display:grid;grid-template-columns:1fr 1fr;gap:.9rem}
@media (max-width:520px){.form-fila{grid-template-columns:1fr}}
.campo{margin-bottom:.9rem}
.campo>label .opt{text-transform:none;letter-spacing:0;font-size:.68rem;
                  color:color-mix(in srgb,var(--tinta) 55%,transparent)}
.campo>label .opt::before{content:'— '}
.campo textarea{resize:vertical;min-height:112px;line-height:1.55}
/* El color no va solo: quien no distingue rojo de gris necesita leer qué pasó. */
.campo-err{font-size:.75rem;color:var(--critico);display:none;margin-top:.15rem}
.campo.mal .campo-err{display:block}
.campo.mal input,.campo.mal textarea,.campo.mal select{border-color:var(--critico)}
.campo.mal input:focus,.campo.mal textarea:focus{
  box-shadow:0 0 0 3px color-mix(in srgb,var(--critico) 22%,transparent)}
/* Honeypot: fuera de pantalla y NO display:none — hay bots que se saltan lo
   oculto pero rellenan lo que existe en el DOM. */
.trampa{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form-enviar{width:100%;justify-content:center;margin-top:.3rem}
.form-enviar[disabled]{opacity:.65;cursor:progress}
.form-aviso{font-size:.72rem;color:var(--apagado);margin:.9rem 0 0;line-height:1.5;max-width:none}
.form-general{font-size:.82rem;color:var(--critico);margin:.9rem 0 0;display:none}
.form-general.on{display:block}
.form-exito{text-align:center;padding:var(--s-8) var(--s-2)}
.form-exito .tick{width:52px;height:52px;border-radius:50%;background:var(--exito-fondo);color:var(--exito);
                  display:flex;align-items:center;justify-content:center;margin:0 auto var(--s-4)}
.form-exito .tick svg{width:26px;height:26px}
.form-exito h2{font-size:var(--t-xl);margin-bottom:.5rem}
.form-exito p{font-size:.92rem;color:var(--apagado);margin:0 auto var(--s-6);max-width:34ch}

/* ============================================================
   Páginas de servicio — plantilla compartida por los tres pilares
   ------------------------------------------------------------
   Mismo esqueleto en las tres: quien compara dos servicios necesita
   encontrar la misma información en el mismo sitio. La diferencia
   va en el contenido, nunca en la estructura.
   ============================================================ */
.miga{display:flex;align-items:center;gap:.5rem;font-family:var(--f-mono);font-size:.7rem;
      color:var(--apagado);margin-bottom:var(--s-6)}
.miga a{color:var(--apagado);text-decoration:none}
.miga a:hover{color:var(--tinta)}
.miga svg{width:12px;height:12px;opacity:.6}

.serv-hero{padding:clamp(2.5rem,6vw,4rem) 0 clamp(2.5rem,6vw,4rem);position:relative;overflow:hidden}
.serv-hero::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:linear-gradient(var(--borde) 1px,transparent 1px),
                   linear-gradient(90deg,var(--borde) 1px,transparent 1px);
  background-size:56px 56px;opacity:.45;
  mask-image:radial-gradient(55% 70% at 80% 0%,#000,transparent 70%);
  -webkit-mask-image:radial-gradient(55% 70% at 80% 0%,#000,transparent 70%)}
.serv-hero h1{font-size:var(--t-3xl);font-weight:800;margin:var(--s-3) 0 var(--s-4);max-width:19ch}
.serv-hero .lede{font-size:var(--t-lg);color:var(--tinta-media);max-width:56ch;margin-bottom:var(--s-8)}

/* síntomas: autodiagnóstico. Si se ve en dos, sigue leyendo. */
.sintomas{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--borde);
          border:1px solid var(--borde);border-radius:var(--r);overflow:hidden}
@media (max-width:760px){.sintomas{grid-template-columns:1fr}}
.sintoma{background:var(--blanco);padding:var(--s-6);display:grid;
         grid-template-columns:auto 1fr;gap:.85rem;align-items:start;font-size:.92rem}
.sintoma svg{width:18px;height:18px;color:var(--cian-texto);flex-shrink:0;margin-top:.2rem}

/* entregables: sustantivos con nombre, no adjetivos.
   Esta es la sección que decide si te toman en serio. */
.entregables{display:grid;gap:.6rem}
.entregable{background:var(--blanco);border:1px solid var(--borde);border-radius:var(--r);
            padding:var(--s-6);display:grid;grid-template-columns:auto 1fr;gap:var(--s-4);align-items:start}
.entregable .idx{font-family:var(--f-mono);font-size:.72rem;color:var(--cian-texto);
                 font-variant-numeric:tabular-nums;padding-top:.2rem}
.entregable h3{font-size:1rem;font-weight:700;margin-bottom:.3rem}
.entregable p{font-size:.89rem;color:var(--apagado)}

/* preguntas frecuentes: <details> nativo — teclado y lector de pantalla
   funcionan sin una línea de JS, y se pueden buscar con Ctrl+F. */
.faq{display:grid;gap:.5rem}
.faq details{background:var(--blanco);border:1px solid var(--borde);border-radius:var(--r);
             transition:border-color var(--dur) var(--curva)}
.faq details[open]{border-color:color-mix(in srgb,var(--cian) 45%,var(--borde))}
.faq summary{cursor:pointer;padding:var(--s-4) var(--s-6);font-weight:600;font-size:.95rem;
             list-style:none;display:flex;align-items:center;justify-content:space-between;gap:1rem}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:'';width:9px;height:9px;flex-shrink:0;
  border-right:2px solid var(--cian-texto);border-bottom:2px solid var(--cian-texto);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform var(--dur) var(--curva)}
.faq details[open] summary::after{transform:rotate(225deg) translate(-2px,-2px)}
.faq summary:focus-visible{outline:2px solid var(--cobalto);outline-offset:-2px;border-radius:var(--r)}
.faq .resp{padding:0 var(--s-6) var(--s-6);font-size:.9rem;color:var(--apagado);max-width:70ch}

/* evidencia honesta: cuando no hay caso, se dice qué se entrega y ya */
.aviso-honesto{background:var(--alerta-fondo);color:var(--alerta);border-radius:var(--r);
               padding:var(--s-6);font-size:.9rem;max-width:none}

/* ============================================================
   Demos — marco de aplicación
   Los dos demos heredados usaban una hoja del sitio antiguo. Se traen
   al sistema nuevo en vez de arrastrar dos CSS en paralelo: dos hojas
   con el mismo propósito acaban divergiendo siempre.
   ============================================================ */
.demo-topbar{background:var(--antracita);color:#F0F3F6;padding:.7rem 0}
.demo-topbar .inner{max-width:1180px;margin:0 auto;padding:0 clamp(1.25rem,4vw,2.5rem);
  display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.demo-topbar .who{font-size:.85rem;display:flex;align-items:center;gap:.6rem}
.demo-topbar .who b{font-family:var(--f-display);font-weight:700}
.demo-topbar .back{font-size:.8rem;color:#A9B4C0;text-decoration:none}
.demo-topbar .back:hover{color:#fff}

.app-window{border:1px solid var(--borde);border-radius:var(--r-lg);overflow:hidden;
  background:var(--blanco);box-shadow:var(--panel)}
.app-chrome{background:var(--platino-2);padding:.6rem 1rem;display:flex;align-items:center;gap:.7rem;
  border-bottom:1px solid var(--borde)}
.app-chrome .dots{display:flex;gap:.35rem}
.app-chrome .dots i{width:9px;height:9px;border-radius:50%;background:var(--borde-fuerte);display:block}
.app-chrome .addr{font-family:var(--f-mono);font-size:.72rem;color:var(--apagado);
  background:var(--blanco);border:1px solid var(--borde);border-radius:5px;padding:.15rem .6rem}
.app-chrome .live{margin-left:auto;font-family:var(--f-mono);font-size:.66rem;color:var(--cian-texto);
  display:flex;align-items:center;gap:.35rem}
.app-chrome .live i{width:6px;height:6px;border-radius:50%;background:var(--cian);display:block}
@media (prefers-reduced-motion:no-preference){.app-chrome .live i{animation:latido 2.4s var(--curva) infinite}}
.app-body{padding:1.3rem}

.app-toolbar{display:flex;gap:.6rem;align-items:center;flex-wrap:wrap;margin-bottom:1rem;
  padding-bottom:1rem;border-bottom:1px solid var(--borde)}
.fld{display:flex;flex-direction:column;gap:.2rem}
.fld label{font-family:var(--f-mono);font-size:.64rem;text-transform:uppercase;letter-spacing:.05em;
  color:var(--apagado)}
.fld select,.fld input{font-family:inherit;font-size:.84rem;padding:.4rem .6rem;border-radius:6px;
  border:1px solid var(--borde-fuerte);background:var(--blanco);color:var(--tinta)}
.pill{font-family:var(--f-mono);font-size:.68rem;padding:.2rem .6rem;border-radius:var(--r-full);font-weight:600}
.pill-warn{background:var(--alerta-fondo);color:var(--alerta)}
.pill-good{background:var(--exito-fondo);color:var(--exito)}

/* ============================================================
   Casos
   ============================================================ */
.caso-hero{padding:clamp(2.5rem,6vw,4rem) 0}
.caso-hero h1{font-size:var(--t-3xl);font-weight:800;margin:var(--s-3) 0 var(--s-4);max-width:20ch}
.caso-hero .lede{font-size:var(--t-lg);color:var(--tinta-media);max-width:58ch}
.caso-cifras{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--borde);
  border:1px solid var(--borde);border-radius:var(--r);overflow:hidden;margin-top:var(--s-8)}
@media (max-width:760px){.caso-cifras{grid-template-columns:repeat(2,1fr)}}
.caso-cifras div{background:var(--blanco);padding:var(--s-4) var(--s-6)}
.caso-cifras b{display:block;font-family:var(--f-mono);font-size:1.35rem;font-weight:500;
  font-variant-numeric:tabular-nums;letter-spacing:-.02em;margin-bottom:.2rem}
.caso-cifras span{font-size:.78rem;color:var(--apagado)}

.relato{display:grid;gap:.6rem}
.relato-fila{display:grid;grid-template-columns:120px 1fr;gap:var(--s-6);align-items:start;
  background:var(--blanco);border:1px solid var(--borde);border-radius:var(--r);padding:var(--s-6)}
@media (max-width:620px){.relato-fila{grid-template-columns:1fr;gap:.4rem}}
.relato-fila .k{font-family:var(--f-mono);font-size:.68rem;text-transform:uppercase;letter-spacing:.08em;
  color:var(--cian-texto);padding-top:.15rem}
.relato-fila .v{font-size:.94rem}

.galeria{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:var(--s-4)}
.shot{border:1px solid var(--borde);border-radius:var(--r);overflow:hidden;background:var(--blanco);
  transition:border-color var(--dur) var(--curva),box-shadow var(--dur) var(--curva)}
.shot:hover{border-color:color-mix(in srgb,var(--cian) 55%,transparent);box-shadow:var(--glow-suave)}
.shot img{display:block;width:100%;height:auto;cursor:zoom-in}
.shot .cap{padding:var(--s-4) var(--s-6) var(--s-6)}
.shot .cap :is(h3,h4){font-size:.95rem;font-weight:700;margin-bottom:.25rem}
.shot .cap p{font-size:.83rem;color:var(--apagado)}

/* visor de capturas: se abre con clic Y con teclado */
.lupa{position:fixed;inset:0;background:rgb(6 8 10 / .92);display:none;z-index:1200;
  align-items:center;justify-content:center;flex-direction:column;gap:var(--s-4);padding:var(--s-8) var(--s-4)}
.lupa.abierta{display:flex}
.lupa img{max-width:100%;max-height:84vh;object-fit:contain;border-radius:var(--r)}
.lupa figcaption{color:#E6EDF3;font-size:.88rem;text-align:center;max-width:70ch}
.lupa .cerrar{position:absolute;top:1.2rem;right:1.4rem;width:40px;height:40px;border-radius:50%;
  background:rgb(255 255 255 / .12);border:1px solid rgb(255 255 255 / .25);color:#fff;cursor:pointer;
  display:flex;align-items:center;justify-content:center}
.lupa .cerrar svg{width:18px;height:18px}
.lupa .cerrar:hover{background:rgb(255 255 255 / .22);border-color:#fff}

/* tarjetas de caso — usadas en la portada y en /trabajo */
.casos{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-6)}
@media (max-width:900px){.casos{grid-template-columns:1fr}}
.caso{display:flex;flex-direction:column;text-decoration:none;color:inherit}
.ventana{border:1px solid var(--borde);border-radius:var(--r);overflow:hidden;background:var(--blanco);
  box-shadow:var(--panel);
  transition:border-color var(--dur) var(--curva),box-shadow var(--dur) var(--curva)}
.caso:hover .ventana{border-color:color-mix(in srgb,var(--cian) 55%,transparent);box-shadow:var(--glow-suave)}
.barra{display:flex;align-items:center;gap:.3rem;padding:.5rem .7rem;background:var(--platino-2);
  border-bottom:1px solid var(--borde)}
.barra i{width:7px;height:7px;border-radius:50%;background:var(--borde-fuerte);display:block}
.barra .ruta{margin-left:.5rem;font-family:var(--f-mono);font-size:.64rem;color:var(--apagado)}
.ventana img{display:block;width:100%;height:auto}
.caso .cuerpo{padding:var(--s-6) 0 0}
.caso :is(h2,h3){font-size:1.1rem;font-weight:700;margin:.5rem 0 .4rem}
.caso .cuerpo p{font-size:.9rem;color:var(--apagado)}
.caso .datos{display:flex;gap:var(--s-6);margin:var(--s-4) 0;flex-wrap:wrap}
.caso .datos div b{display:block;font-family:var(--f-mono);font-size:1.05rem;font-weight:500;
  font-variant-numeric:tabular-nums}
.caso .datos div span{font-size:.76rem;color:var(--apagado)}
.caso:hover .ir{gap:.65rem}
.ir{transition:gap var(--dur) var(--curva)}

/* Condición del diagnóstico: aplica a los tres pasos, no a uno.
   Va con borde superior cian porque es la letra pequeña que sí conviene leer. */
.nota-precio{margin-top:var(--s-6);padding-top:var(--s-4);border-top:2px solid var(--cian);
  font-size:.88rem;color:var(--tinta-media);max-width:64ch}

/* ============================================================
   Barra de navegación en pantallas estrechas
   ------------------------------------------------------------
   Por debajo de ~430 px no caben a la vez el logotipo, el
   conmutador de idioma y el botón de acción: la barra desbordaba
   y arrastraba scroll horizontal a toda la página. Un iPhone SE
   (375) y buena parte de Android (360) entran en ese rango.

   Se retira el botón de la barra y no el conmutador, porque el
   botón flotante ya cubre el contacto durante todo el scroll,
   mientras que el idioma no tiene otro sitio donde vivir — y es
   justo lo que necesita quien entró en el idioma equivocado.
   ============================================================ */
@media (max-width:430px){
  .nav-links .btn{display:none}
  .nav-in{gap:var(--s-3)}
}
/* Más abajo todavía, la palabra de la marca cede y queda el isotipo:
   una marca cortada a la mitad comunica peor que una marca sola. */
@media (max-width:340px){
  .nav-logo .txt{display:none}
}

/* ============================================================
   Grabación de recorrido con capítulos
   ------------------------------------------------------------
   Video a la izquierda, capítulos a la derecha. El video ocupa poco
   más de la mitad del ancho a propósito: el archivo es de 1920 px y
   mostrado a ~640 css nunca se estira, ni en pantalla HiDPI.
   preload="none" — son 23 y 41 MB: no se descargan hasta que
   alguien le da al play.
   ============================================================ */
.rec{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);gap:var(--s-6);align-items:start}
@media (max-width:900px){.rec{grid-template-columns:1fr;gap:var(--s-4)}}
.rec-marco{border:1px solid var(--borde);border-radius:var(--r);overflow:hidden;
  background:var(--blanco);box-shadow:var(--panel)}
.rec-marco video{width:100%;display:block;background:var(--antracita);aspect-ratio:1920/984}
.rec-texto{position:sticky;top:5rem}
@media (max-width:900px){.rec-texto{position:static}}
.rec-n{font-family:var(--f-mono);font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--cian-texto);margin:0 0 .45rem}
.rec-titulo{font-size:var(--t-lg);font-weight:700;margin:0 0 .5rem;min-height:2.4em}
.rec-desc{color:var(--apagado);font-size:.9rem;margin:0;min-height:4.5em}
@media (max-width:900px){.rec-titulo,.rec-desc{min-height:0}}
.rec-lista{list-style:none;margin:var(--s-4) 0 0;padding:0;border-top:1px solid var(--borde)}
.rec-lista li{border-bottom:1px solid var(--borde);position:relative}
.rec-lista button{width:100%;text-align:left;background:transparent;border:0;cursor:pointer;
  display:flex;align-items:baseline;gap:.7rem;padding:.55rem .2rem;color:var(--apagado);
  font-family:var(--f-sans);font-size:.85rem;
  transition:color var(--dur) var(--curva),background-color var(--dur) var(--curva)}
.rec-lista button:hover{color:var(--tinta);background:var(--platino-2)}
.rec-lista button time{font-family:var(--f-mono);font-size:.72rem;color:var(--apagado);
  font-variant-numeric:tabular-nums;flex-shrink:0}
.rec-lista li.on button{color:var(--tinta);font-weight:600}
.rec-lista li.on button time{color:var(--cian-texto)}
/* barra cian en el capítulo que está sonando */
.rec-lista li.on::before{content:'';position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--cian)}

/* ---- panel de canales del botón flotante ---- */
.fab-panel{position:fixed;right:1.25rem;bottom:5.5rem;z-index:999;
  width:min(21rem,calc(100vw - 2.5rem));border-radius:var(--r-lg);overflow:hidden;
  background:var(--blanco);border:1px solid var(--borde);
  box-shadow:0 26px 60px -22px rgb(0 0 0 / .55)}
.fab-panel[hidden]{display:none}
@media (prefers-reduced-motion:no-preference){
  .fab-panel{animation:fab-sube .26s var(--curva) both}
  @keyframes fab-sube{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
}
@media (max-width:560px){.fab-panel{right:1rem;bottom:5rem}}
/* verde de marca oscurecido: sobre --primary puro el texto blanco daría 3.8:1
   y aquí hay frases enteras encima */
.fab-tel{background:var(--verde-solido,color-mix(in srgb,var(--cobalto) 88%,black));
  color:#fff;text-align:center;padding:1.3rem 1.2rem}
.fab-tel .k{display:block;font-size:1rem;font-family:var(--f-display);font-weight:700;margin-bottom:.3rem}
.fab-tel .pais{display:block;font-size:.76rem;color:rgb(255 255 255 / .9);margin-bottom:.15rem}
.fab-tel .num{display:inline-block;font-family:var(--f-display);font-size:1.4rem;font-weight:800;
  color:#fff;text-decoration:none;letter-spacing:-.01em;border-bottom:1px solid transparent}
.fab-tel .num:hover{border-bottom-color:rgb(255 255 255 / .7)}
.fab-ops{padding:.4rem}
.fab-op{display:flex;align-items:flex-start;gap:.75rem;width:100%;text-align:left;cursor:pointer;
  background:transparent;border:0;border-radius:11px;padding:.85rem .9rem;color:var(--tinta);
  font-family:var(--f-sans);text-decoration:none;transition:background-color var(--dur) var(--curva)}
.fab-op:hover{background:var(--platino-2)}
.fab-op .ico{width:21px;height:21px;flex-shrink:0;color:var(--cian-texto);margin-top:.1rem}
.fab-op .ico svg{width:100%;height:100%;display:block}
.fab-op .txt{display:flex;flex-direction:column;gap:.16rem;min-width:0}
.fab-op b{font-size:.93rem;font-weight:600}
.fab-op i{font-style:normal;font-size:.78rem;color:color-mix(in srgb,var(--tinta) 68%,transparent);line-height:1.4}
html.gate-on .fab-panel{display:none}

/* ============================================================
   NODO — mascota y asistente guiado
   ------------------------------------------------------------
   La mascota va en SVG en línea (no <img>) para que herede los
   tokens del tema y para poder animarle los estados desde CSS.
   Tres estados y ni uno más: inactivo, pensando, resuelto.
   ============================================================ */
.nodo{width:100%;height:100%;display:block;overflow:visible}
.nodo-nucleo{fill:var(--cian)}
.nodo-cuerpo{fill:var(--platino-2);stroke:var(--borde-fuerte)}
.nodo-visor{fill:var(--antracita)}
.nodo-ojo{fill:var(--cian)}
.nodo-barrido{fill:var(--cian-suave);opacity:0}

/* flotación de reposo: 3 px, lenta. Un personaje quieto parece apagado;
   uno que se mueve mucho distrae de la página que hay detrás. */
@media (prefers-reduced-motion:no-preference){
  .nodo-av .nodo{animation:nodo-flota 4s var(--curva) infinite}
  @keyframes nodo-flota{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
  /* el núcleo late aparte, más lento: es el "pulso" de la marca */
  .nodo-nucleo{animation:nodo-pulso 2.8s var(--curva) infinite;transform-origin:24px 6px}
  @keyframes nodo-pulso{0%,100%{opacity:1}50%{opacity:.45}}

  /* PENSANDO: los ojos se achatan a una línea y el visor se barre */
  .pensando .nodo-ojo{animation:nodo-achata .9s var(--curva) infinite}
  @keyframes nodo-achata{0%,100%{transform:scaleY(1)}50%{transform:scaleY(.28)}}
  .nodo-ojo{transform-origin:center;transform-box:fill-box}
  .pensando .nodo-barrido{animation:nodo-barre 1.1s linear infinite}
  @keyframes nodo-barre{
    0%{opacity:0;transform:translateX(0)}
    15%{opacity:.85}
    85%{opacity:.85}
    100%{opacity:0;transform:translateX(15px)}
  }
  /* EL DISPARADOR LATE en cian mientras el panel está cerrado.
     Se para en cuanto se abre: un indicador que sigue llamando cuando ya le
     hicieron caso deja de significar nada. Y late el halo, no el botón:
     animar box-shadow obliga a repintar cada fotograma. */
  .nodo-fab::after{
    content:'';position:absolute;inset:-4px;border-radius:inherit;
    border:1.5px solid var(--accent-cyan);opacity:0;pointer-events:none;
    animation:fab-late 2.6s var(--curva) infinite;
  }
  .nodo-fab.activo::after{animation:none}
  /* RESUELTO: los ojos se ensanchan un instante. Sin boca: Nodo no sonríe. */
  .resuelto .nodo-ojo{animation:nodo-ok .5s var(--curva)}
  @keyframes nodo-ok{0%{transform:scaleY(1)}45%{transform:scaleY(.35) scaleX(1.35)}100%{transform:scaleY(1)}}
  @keyframes fab-late{
    0%  {transform:scale(.94); opacity:0}
    40% {opacity:.7}
    100%{transform:scale(1.18); opacity:0}
  }

  /* Los mismos dos estados sobre el render, que no tiene piezas internas que
     mover: el anillo cian sustituye al barrido del visor, y un latido de
     escala sustituye al gesto de los ojos. */
  .nodo-av.pensando::after{animation:nodo-anillo 1.1s var(--curva) infinite}
  @keyframes nodo-anillo{
    0%  {transform:scale(.88); opacity:0}
    35% {opacity:.85}
    100%{transform:scale(1.35); opacity:0}
  }
  .nodo-av.resuelto .nodo--render{animation:nodo-ok-render .5s var(--curva)}
  @keyframes nodo-ok-render{0%,100%{transform:scale(1)}45%{transform:scale(1.12)}}
}

.nodo-zona{position:fixed;right:1.25rem;bottom:1.25rem;z-index:1000;
  display:flex;flex-direction:column;align-items:flex-end;gap:.7rem}
html.gate-on .nodo-zona,html.modal-abierta .nodo-zona{display:none}

/* ---- botón flotante ---- */
.nodo-fab{display:inline-flex;align-items:center;gap:.55rem;cursor:pointer;
  background:var(--blanco);color:var(--tinta);border:1px solid var(--borde-fuerte);
  border-radius:var(--r-full);padding:.5rem 1.1rem .5rem .6rem;
  font-family:var(--f-sans);font-size:.9rem;font-weight:600;min-height:52px;
  box-shadow:var(--panel);
  transition:border-color var(--dur) var(--curva),box-shadow var(--dur) var(--curva),
             transform var(--dur) var(--curva)}
.nodo-fab{position:relative}
.nodo-fab:hover{border-color:var(--accent-cyan);box-shadow:0 0 20px var(--accent-glow);transform:translateY(-2px)}
.nodo-fab.activo{border-color:var(--cian)}
/* Los huecos crecen de 38/34 px a 48/44 porque ahora llevan el render, que por
   debajo de 44 se vuelve ilegible: la esfera, los paneles y la palabra VEBRA
   se funden en una mancha azul. El avatar de 28 px junto a cada mensaje sigue
   con el dibujo de trazo, que sí está hecho para ese tamaño. */
.nodo-av{display:block;width:48px;height:48px;flex-shrink:0}
.nodo-av--fab{width:44px;height:44px}
@media (max-width:560px){
  .nodo-zona{right:1rem;bottom:1rem}
  .nodo-fab{padding:.45rem;border-radius:50%;min-height:0}
  .nodo-fab .et{display:none}
  .nodo-av--fab{width:48px;height:48px}
}

/* ---- la mascota como render ----
   Un PNG no se puede repintar desde CSS, así que los estados que antes movían
   el visor y los ojos del SVG aquí actúan sobre la pieza entera: escala y un
   anillo cian alrededor. Mismo vocabulario, distinto soporte. */
.nodo--render{display:block;width:100%;height:100%;object-fit:contain}
.nodo-av{position:relative}
.nodo-av:has(.nodo--render)::after{
  content:"";position:absolute;inset:-3px;border-radius:50%;
  border:1.5px solid var(--cian);opacity:0;pointer-events:none}

/* ---- panel ---- */
.nodo-panel{width:min(23rem,calc(100vw - 2.5rem));max-height:min(34rem,calc(100vh - 8rem));
  display:flex;flex-direction:column;border-radius:var(--r-lg);overflow:hidden;
  background:var(--platino);border:1px solid var(--borde);
  box-shadow:0 26px 60px -22px rgb(0 0 0 / .5)}
.nodo-panel[hidden]{display:none}
@media (prefers-reduced-motion:no-preference){
  .nodo-panel{animation:nodo-sube .28s var(--curva) both}
  @keyframes nodo-sube{from{opacity:0;transform:translateY(14px) scale(.985)}to{opacity:1;transform:none}}
}
.nodo-top{display:flex;align-items:center;gap:.6rem;padding:.7rem .6rem .7rem 1rem;
  background:var(--blanco);border-bottom:1px solid var(--borde)}
.nodo-id{display:flex;flex-direction:column;margin-right:auto;line-height:1.25}
.nodo-id b{font-family:var(--f-display);font-size:.95rem;font-weight:700}
.nodo-id i{font-style:normal;font-size:.72rem;color:var(--apagado)}
.nodo-ico{width:32px;height:32px;border:0;background:transparent;color:var(--apagado);cursor:pointer;
  border-radius:8px;display:flex;align-items:center;justify-content:center;
  transition:background-color var(--dur) var(--curva),color var(--dur) var(--curva)}
.nodo-ico svg{width:17px;height:17px}
.nodo-ico:hover{background:var(--platino-2);color:var(--tinta)}

.nodo-hilo{flex:1;overflow-y:auto;padding:1rem .9rem;display:flex;flex-direction:column;gap:.65rem}
.nodo-msg{display:flex;align-items:flex-start;gap:.5rem;max-width:92%}
.nodo-av--msg{width:28px;height:28px;margin-top:.1rem}
.nodo-txt{margin:0;padding:.6rem .8rem;border-radius:13px;font-size:.87rem;line-height:1.5;
  background:var(--blanco);border:1px solid var(--borde);color:var(--tinta);max-width:none}
.nodo-msg.mia{align-self:flex-end;max-width:88%}
/* el mensaje del visitante en cobalto sólido: 6.7:1, no en cian */
.nodo-msg.mia .nodo-txt{background:var(--cobalto);border-color:transparent;color:#fff;
  border-top-right-radius:4px}
.nodo-msg:not(.mia) .nodo-txt{border-top-left-radius:4px}

/* esqueleto de texto mientras se prepara la respuesta */
.nodo-esqueleto{display:flex;flex-direction:column;gap:.4rem;padding:.7rem .8rem;
  background:var(--blanco);border:1px solid var(--borde);border-radius:13px;border-top-left-radius:4px}
.nodo-esqueleto i{display:block;height:8px;border-radius:99px;background:var(--platino-2)}
.nodo-esqueleto i:first-child{width:120px}
.nodo-esqueleto i:last-child{width:72px}
@media (prefers-reduced-motion:no-preference){
  .nodo-esqueleto i{animation:nodo-late 1.1s var(--curva) infinite}
  .nodo-esqueleto i:last-child{animation-delay:.15s}
  @keyframes nodo-late{
    0%,100%{background:var(--platino-2)}
    50%{background:color-mix(in srgb,var(--cian) 45%,var(--platino-2))}
  }
}

/* ---- botones de respuesta rápida ---- */
.nodo-ops{display:flex;flex-direction:column;gap:.4rem;align-items:flex-end}
.nodo-op{cursor:pointer;text-align:right;text-decoration:none;
  background:var(--blanco);color:var(--cobalto-texto);border:1px solid var(--cobalto-texto);
  border-radius:var(--r);padding:.55rem .85rem;font-family:var(--f-sans);
  font-size:.85rem;font-weight:600;min-height:40px;max-width:100%;
  transition:background-color var(--dur) var(--curva),color var(--dur) var(--curva),
             transform var(--dur) var(--curva)}
.nodo-op:hover{background:var(--cobalto);color:#fff}
.nodo-op:active{transform:scale(.985)}
.nodo-op.fuerte{background:var(--cobalto);color:#fff}
.nodo-op.fuerte:hover{background:var(--cobalto-hover)}

.nodo-pie{padding:.6rem .9rem .8rem;margin:0;font-size:.72rem;line-height:1.45;
  color:var(--apagado);background:var(--blanco);border-top:1px solid var(--borde);max-width:none}

/* ============================================================
   Correcciones medidas de Nodo
   ============================================================ */

/* ============================================================
   CTA PRINCIPAL — el único botón cian de la página
   ------------------------------------------------------------
   El cian NUNCA lleva texto claro encima: con blanco da 1.5:1.
   Con la tinta oscura da 12.66:1, mejor que cualquier otro botón
   del sistema. Se reserva a la acción principal: si hubiera dos
   botones cian, dejaría de señalar cuál importa.

   La tinta es --tinta-sobre-cian y no --text-main a propósito: el
   cian es el mismo en las dos paletas, así que lo que va encima
   tampoco puede cambiar con ellas.
   ============================================================ */
.btn--cian{
  background:var(--accent-cyan);
  color:var(--tinta-sobre-cian);      /* 12.66:1 */
  border-color:var(--accent-cyan);
  font-weight:700;
  transition:all .3s ease;
}
.btn--cian:hover{
  /* El resplandor perimetral pedido. El fondo NO cambia de color al pasar por
     encima: mover el fondo y encender el halo a la vez son dos señales para un
     solo suceso, y el halo ya lo dice. */
  box-shadow:var(--glow-boton);
  transform:translateY(-2px);
}
.btn--cian:active{transform:translateY(0)}
.btn--cian:focus-visible{outline:2px solid var(--tinta);outline-offset:3px}
@media (prefers-reduced-motion:reduce){
  .btn--cian{transition:none}
  .btn--cian:hover{transform:none}
}

/* ============================================================
   Hero: retícula de nodos
   ------------------------------------------------------------
   No es adorno abstracto: la silueta que forman los enlaces es
   la V del isotipo, y el cuadrado del centro es su núcleo. El
   pulso recorre los enlaces hacia el núcleo — el dato que entra
   y queda protegido, que es literalmente lo que vende la empresa.
   ============================================================ */
/* Reparto medido, no elegido a ojo: con 1fr 1fr el arte pasa de 440 a 512 px
   y el vacío vertical frente al bloque de texto baja de 200 a 128, sin que el
   titular cambie de las 5 líneas que tiene en cualquiera de los repartos. */
.hero-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,4rem);align-items:center}
@media (max-width:960px){.hero-grid{grid-template-columns:1fr;gap:var(--s-8)}}
.hero-arte{position:relative;aspect-ratio:1;max-width:520px;width:100%;justify-self:center}
/* en una sola columna el arte encabeza la página; 380 en tablet y 320
   en móvil, que es lo que cabe dejando aire a los lados */
@media (max-width:960px){.hero-arte{max-width:380px;order:-1}}
@media (max-width:560px){.hero-arte{max-width:320px}}
.hero-arte svg{width:100%;height:100%;display:block;overflow:visible}
/* El render del hero. Flota igual que la mascota del asistente —es el mismo
   personaje a otra escala— y reposo.js lo detiene al salir de pantalla. */
.hero-arte picture,
.hero-arte img{display:block;width:100%;height:auto}
@media (prefers-reduced-motion:no-preference){
  .hero-arte img{animation:hero-flota 6s var(--curva) infinite}
  @keyframes hero-flota{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
}
.ha-enlace{stroke:var(--borde-fuerte);stroke-width:1.2;fill:none;opacity:.55}
.ha-enlace-vivo{stroke:var(--cian);stroke-width:1.6;fill:none;
  stroke-dasharray:5 160;opacity:.9}
.ha-nodo{fill:var(--blanco);stroke:var(--borde-fuerte);stroke-width:1.4}
.ha-nodo-cian{fill:var(--cian);stroke:none}
.ha-nucleo{fill:var(--cian)}
.ha-halo{fill:none;stroke:var(--cian);stroke-width:1.2;opacity:0}
.ha-rotulo{font-family:var(--f-mono);font-size:7px;letter-spacing:.1em;
  text-transform:uppercase;fill:var(--apagado)}
@media (prefers-reduced-motion:no-preference){
  .ha-enlace-vivo{animation:ha-fluye 3.4s linear infinite}
  @keyframes ha-fluye{to{stroke-dashoffset:-165}}
  .ha-halo{animation:ha-late 3s var(--curva) infinite}
  @keyframes ha-late{0%{transform:scale(.7);opacity:.7}70%{transform:scale(1.5);opacity:0}100%{opacity:0}}
  .ha-nodo-cian{animation:ha-brilla 2.6s var(--curva) infinite}
  .ha-nodo-cian:nth-of-type(2){animation-delay:.5s}
  .ha-nodo-cian:nth-of-type(3){animation-delay:1s}
  @keyframes ha-brilla{0%,100%{opacity:1}50%{opacity:.4}}
}

/* ============================================================
   MODO CONSOLA — la identidad física
   ------------------------------------------------------------
   Corta la página a un fondo oscuro de lado a lado. El contraste
   ES el argumento de la sección: valida solidez justo cuando el
   visitante ya decidió que le interesa.

   Van dibujos vectoriales planos y no fotografías de catálogo:
   una foto de archivo con un logo pegado encima se reconoce al
   instante y resta la credibilidad que esta sección venía a dar.

   Contrastes medidos sobre #1A1D20:
     blanco  16.93:1   ·   cian  11.0:1   ·   apagado claro  8.72:1
   ============================================================ */
.sec--consola{
  background:var(--bg-consola);
  border-top:0;
  padding:clamp(3.5rem,8vw,6rem) 0;
  position:relative;overflow:hidden;
}
.sec--consola::before{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(46% 55% at 82% 0%, rgb(0 229 255 / .16), transparent 66%);
}
.sec--consola>*{position:relative}
.merch-cab{max-width:56ch;margin-bottom:var(--s-12)}
.merch-cab h2{font-size:var(--t-2xl);font-weight:800;color:#FFFFFF;margin:var(--s-3) 0}
.merch-cab p{color:var(--text-muted-oscuro)}
.merch-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s-6)}
@media (max-width:820px){.merch-grid{grid-template-columns:1fr;gap:var(--s-4)}}
.merch-pieza{
  background:rgb(255 255 255 / .04);
  border:1px solid rgb(255 255 255 / .1);
  border-radius:var(--r-lg);
  padding:var(--s-6);text-align:center;
  transition:all .3s ease;
}
.merch-pieza:hover{border-color:var(--accent-cyan);box-shadow:0 0 20px var(--accent-glow)}
.merch-pieza svg{width:96px;height:96px;margin:0 auto var(--s-4);display:block}
.merch-pieza b{display:block;color:#FFFFFF;font-family:var(--f-display);
  font-size:1.02rem;font-weight:700;margin-bottom:.4rem}
.merch-pieza span{display:block;color:var(--text-muted-oscuro);font-size:.9rem;line-height:1.55}
.merch-nota{margin-top:var(--s-12);max-width:70ch;
  color:var(--text-muted-oscuro);font-size:.86rem;line-height:1.6}
@media (prefers-reduced-motion:reduce){.merch-pieza{transition:none}}

/* ============================================================
   ENLACE DE SALTO
   Primer foco de cada página. Fuera de pantalla mientras nadie lo pide, y
   sólido en cuanto el teclado llega: quien navega con tabulador no debería
   recorrer la cabecera entera en las diez páginas.
   ============================================================ */
.saltar{position:absolute;left:var(--s-4);top:-3rem;z-index:1300;
        padding:.6rem 1rem;border-radius:var(--r);
        background:var(--cobalto);color:#fff;font-weight:600;font-size:.9rem;
        text-decoration:none;transition:top var(--dur) var(--curva)}
.saltar:focus,
.saltar:focus-visible{top:var(--s-4);outline:2px solid var(--tinta);outline-offset:2px}
@media (prefers-reduced-motion:reduce){.saltar{transition:none}}

/* ============================================================
   REPOSO DE ANIMACIONES
   Lo aplica assets/reposo.js sobre los contenedores marcados con
   .anima-en-vista cuando salen de pantalla. Pausar no reinicia:
   al volver, la animación continúa donde se quedó.
   ============================================================ */
.anima-en-vista.en-reposo,
.anima-en-vista.en-reposo *{animation-play-state:paused}


/* ===== ARMAZÓN DE PÁGINA =====================================
   Barra, conmutador de idioma, secciones, cierre y pie: lo que
   repiten las diez páginas. Vivía copiado dentro del <style> de
   cada archivo —19,9 KB idénticos que el navegador volvía a
   descargar en cada visita porque el HTML no se cachea—. Aquí se
   descarga una vez y vale para todo el sitio.

   Va al final del archivo a propósito: es la posición que estas
   reglas ocupaban antes respecto del resto de la hoja, y moverlas
   más arriba cambiaría quién gana en los empates de especificidad.
   ============================================================ */
.nav-in{max-width:1180px;margin:0 auto;padding:.85rem clamp(1.25rem,4vw,2.5rem);
          display:flex;align-items:center;gap:var(--s-6)}
.nav-logo{display:flex;align-items:center;gap:.6rem;text-decoration:none;color:var(--tinta)}
.nav-logo .txt{font-family:var(--f-display);font-size:1.05rem;line-height:1}
.nav-logo .txt b{font-weight:800;letter-spacing:-.02em}
.nav-logo .txt i{font-style:normal;font-weight:600;letter-spacing:.06em;margin-left:.3em}
.nav-links{margin-left:auto;display:flex;align-items:center;gap:var(--s-6);font-size:.88rem}
.nav-links a:not(.btn){color:var(--apagado);text-decoration:none}
.nav-links a:not(.btn):hover{color:var(--tinta)}
@media (max-width:880px){.nav-links .oculta-movil{display:none}}
.idioma{display:inline-flex;align-items:center;gap:.15rem;padding:.22rem .22rem .22rem .5rem;
          border:1px solid var(--borde);border-radius:var(--r-full);background:var(--platino-2)}
.idioma .globo{width:15px;height:15px;color:var(--apagado);margin-right:.1rem}
.idioma button{border:0;cursor:pointer;background:transparent;
                 color:color-mix(in srgb,var(--tinta) 76%,transparent);
                 font-family:var(--f-sans);font-weight:700;font-size:.74rem;letter-spacing:.045em;
                 padding:.45rem .62rem;border-radius:var(--r-full);line-height:1;
                 transition:background-color var(--dur) var(--curva),color var(--dur) var(--curva)}
.idioma button:hover{color:var(--tinta);background:color-mix(in srgb,var(--tinta) 9%,transparent)}
.idioma button.on{background:var(--cobalto);color:#fff}
.sec-cab{max-width:64ch;margin-bottom:var(--s-8)}
.sec-cab h2{font-size:var(--t-2xl);font-weight:700;margin:var(--s-3) 0 var(--s-3)}
.cierre p{color:#A9B4C0;margin:0 auto var(--s-8);max-width:52ch}
footer{padding:var(--s-12) 0;border-top:1px solid var(--borde);color:var(--apagado);font-size:.85rem}
.foot-in{display:flex;justify-content:space-between;gap:var(--s-6);flex-wrap:wrap;align-items:center}
.nav{position:sticky;top:0;z-index:30;background:color-mix(in srgb,var(--platino) 92%,transparent);
       backdrop-filter:blur(10px);border-bottom:1px solid var(--borde)}
.sec{padding:clamp(3rem,7vw,4.5rem) 0;border-top:1px solid var(--borde)}
.cierre{text-align:center;padding:clamp(2.5rem,6vw,4rem) var(--s-6)}

/* ============================================================
   CONMUTADOR DE PALETA
   ------------------------------------------------------------
   Vive en la barra, junto al de idioma: las dos son preferencias
   de presentación y se buscan en el mismo sitio.

   El borde usa --borde-fuerte y no --border-color: es un CONTROL,
   y WCAG 1.4.11 pide 3:1 para su contorno. El filete decorativo
   de las tarjetas (1.23:1) no vale aquí.
   ============================================================ */
.paleta{
  display:inline-flex;align-items:center;gap:.4rem;
  padding:.42rem .7rem;min-height:36px;
  border:1px solid var(--borde-fuerte);border-radius:var(--r-full);
  background:transparent;color:var(--text-main);
  font-family:var(--f-sans);font-size:.78rem;font-weight:600;
  letter-spacing:.02em;line-height:1;cursor:pointer;
  transition:border-color var(--dur) var(--curva),
             background-color var(--dur) var(--curva),
             box-shadow var(--dur) var(--curva);
}
.paleta svg{width:15px;height:15px;flex-shrink:0}
.paleta:hover{border-color:var(--accent-cyan);box-shadow:0 0 14px var(--accent-glow)}
.paleta:focus-visible{outline:2px solid var(--accent-cyan);outline-offset:2px}
/* por debajo de 900 px queda solo el icono: el nombre lo da aria-label */
@media (max-width:900px){
  .paleta .et{
    position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap;
  }
  .paleta{padding:.42rem;border-radius:50%}
}
@media (prefers-reduced-motion:reduce){.paleta{transition:none}}

/* ============================================================
   MANUAL DE MARCA v1.0 — bloques derivados del documento
   ------------------------------------------------------------
   Dos piezas que existen porque el manual las pide, y que siguen
   sus reglas al pie de la letra:

     .disciplinas  Las siete disciplinas de la página 4. Son
                   etiquetas de trazo, sin relleno sólido, como
                   manda la sección de iconografía. El separador
                   es un filete, no un punto decorativo.

     .valores      Los cinco valores de la página 6. Numeración
                   real —01…05— porque el manual los numera y
                   porque el orden dice algo: solidez primero,
                   cercanía al final.

   El acento de ambos usa --cian-texto y no --accent-cyan: el
   primero conmuta con la paleta clara (5.36:1 sobre blanco), el
   segundo es el mismo cian en las dos y ahí daría 1.5:1.
   ============================================================ */
.disciplinas{
  margin-top:var(--s-12);padding-top:var(--s-8);
  border-top:1px solid var(--borde);
}
.disciplinas-cab{
  font-size:var(--t-xs);text-transform:uppercase;letter-spacing:.09em;
  color:var(--cian-texto);margin:0 0 var(--s-4);font-weight:600;
}
.disciplinas ul{
  list-style:none;margin:0;padding:0;
  display:flex;flex-wrap:wrap;gap:var(--s-2) var(--s-3);
}
.disciplinas li{
  font-size:var(--t-sm);color:var(--apagado);
  border:1px solid var(--borde-fuerte);border-radius:var(--r-full);
  padding:.34rem .85rem;background:none;
}

.valores{list-style:none;margin:var(--s-6) 0 0;padding:0;counter-reset:v}
.valores li{
  counter-increment:v;display:grid;
  grid-template-columns:2.6rem 1fr;gap:0 var(--s-4);
  padding:var(--s-4) 0;border-top:1px solid var(--borde);
}
.valores li::before{
  content:counter(v,decimal-leading-zero);
  font-family:var(--f-mono);font-size:var(--t-sm);font-weight:600;
  color:var(--cian-texto);grid-row:1 / span 2;padding-top:.15rem;
}
.valores li b{font-weight:600;color:var(--tinta);font-size:var(--t-base)}
.valores li span{color:var(--apagado);font-size:.95rem;line-height:1.6;margin-top:.2rem}
@media (max-width:560px){
  .valores li{grid-template-columns:2.1rem 1fr}
}
