/* ==========================================================================
   Servex — sistema de diseño
   Interfaz en el azul del logo: índigo profundo y tonos claros.

   El azul del wordmark de Servex (#1B1464) dejó de ser exclusivo del logo y
   pasó a vestir la interfaz entera: es --sx-deep, el punto más profundo de la
   escala. El naranja del catálogo sí sigue reservado al logo, y por eso su
   valor solo se escribe en brand.js — el anillo y la regla son lo único cálido
   del demo, y ese contrapunto es lo que sostiene una interfaz por lo demás
   fría. verificar.mjs lo impone.
   ========================================================================== */

:root {
  /* Acento — escala índigo, derivada del logo.
     Los nueve pasos comparten el matiz exacto del wordmark (245°) y anclan su
     saturación a la del propio logo (67%), no a la del celeste anterior (95%):
     trasladar aquella saturación a 245° daba violetas eléctricos (#5242FB) que
     no se leen como Servex.
     Los pasos no son decorativos, salen de medir contraste sobre blanco: los
     índigos claros visten superficies, los profundos cargan acciones. */
  --sx-accent-50:  #F3F2FA;   /* fondos de icono, bandas, barra lateral       */
  --sx-accent-100: #E6E4F4;   /* bordes suaves y separadores                  */
  --sx-accent-200: #C9C5E9;   /* rejilla del mapa, contornos                  */
  --sx-accent-300: #A49CD9;   /* anillos y marcadores decorativos — 2,5:1     */
  --sx-accent-500: #8B82D0;   /* trazos e ilustración — 3,6:1, nunca con texto */
  --sx-accent-600: #3B2F9E;   /* hover y bordes marcados — 10,1:1             */
  --sx-accent:     #241B7F;   /* botones, enlaces y CTA — 13,7:1 con blanco, AA */
  --sx-deep:       #1B1464;   /* el azul del logo — texto sobre claro, 15,8:1 */
  --sx-deep-50:    #EEEDF6;   /* pie de página y bandas de cierre             */

  /* Verde de WhatsApp — la única excepción al índigo, y la segunda del sistema
     entera. No es un color de Servex: es la marca de un tercero, y funciona
     precisamente porque se reconoce antes de leer el botón. Por eso se escribe
     tal cual viene, sin adaptarlo a la escala. El naranja del logo sigue
     siendo el otro extranjero, y sigue viviendo solo en brand.js.
     Ojo con el texto que va encima: ver la variante --wa más abajo. */
  --sx-wa:     #25D366;
  --sx-wa-600: #1EBE5B;   /* hover */

  /* Neutros.
     `--sx-mute` viste todo el texto secundario: subtítulos, pies de tarjeta,
     etiquetas de la barra lateral. El gris anterior (#8A8A96) se quedaba en
     3,4:1 sobre blanco y 3,0:1 sobre el pie — por debajo del 4,5:1 que pide
     AA para texto pequeño. Este gris azulado pasa sobre las cuatro superficies
     del sistema (blanco 5,4 · barra lateral 5,1 · surface 5,1 · pie 4,9) y de
     paso armoniza con la escala celeste. */
  --sx-ink:     #101014;
  --sx-slate:   #5A5A66;
  --sx-mute:    #5F6B7A;
  --sx-line:    #EEEFEF;
  --sx-surface: #F7F8FA;
  --sx-white:   #FFFFFF;

  /* Semáforo — usados en radar, contratos y pipeline.
     Los tonos van más profundos que un semáforo típico porque aquí siempre
     llevan texto encima sobre su propio fondo pálido: el verde y el ámbar
     brillantes se quedaban en 3,1:1 y 2,7:1, ilegibles en una etiqueta de
     11 px. Estos pasan AA sobre su fondo y sobre blanco. */
  --sx-open:      #14713A;  /* ventana de compra abierta — 5,5:1 */
  --sx-open-bg:   #E8F6EE;
  --sx-soon:      #8A5A08;  /* próxima — 5,4:1 */
  --sx-soon-bg:   #FDF4E0;
  --sx-closed:    #5F6B7A;  /* fuera de ventana — 4,8:1 */
  --sx-closed-bg: #F1F1F3;
  --sx-risk:      #C0392B;  /* riesgo / estancado — 4,7:1 */
  --sx-risk-bg:   #FBEAE7;

  /* Marcas de datos.
     Dos series necesitan un frío y un cálido: probadas contra el validador, las
     combinaciones frías no se distinguen — celeste + teal cae bajo el mínimo de
     croma y separa solo ΔE 13,8 en visión normal, y celeste + violeta baja a
     ΔE 7,8 para deuteranopía. El índigo del logo contra este ámbar separa mucho
     más que el celeste al que sustituye: ΔE 110 en visión normal y 118 en
     deuteranopía, frente a 28,4 y 24,6.
     El ámbar es deliberadamente más apagado y oscuro que el naranja del logo,
     para que no se lea como la marca reapareciendo dentro de un gráfico. */
  --sx-data-1: #3B2F9E;   /* serie índigo — ingreso ya contratado */
  --sx-data-2: #B45309;   /* serie ámbar  — negocio nuevo         */

  /* Tipografía */
  --sx-font: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
             system-ui, "Helvetica Neue", Arial, sans-serif;
  --sx-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Layout */
  --sx-container: 1200px;
  --sx-gutter: 80px;

  /* Elevación */
  --sx-shadow-sm: 0 2px 4px rgba(16, 16, 20, .04);
  --sx-shadow-md: 0 6px 20px rgba(16, 16, 20, .07);
  --sx-shadow-lg: 0 18px 50px rgba(16, 16, 20, .12);

  /* Radios — el Nexcent usa dos formas y no son intercambiables */
  --sx-r-card: 8px;
  --sx-r-btn: 4px;
  --sx-r-pill: 999px;

  /* Movimiento.
     Cuatro duraciones y tres curvas para todo el demo. Antes cada componente
     inventaba la suya (.14 · .16 · .18 · .2 · .22) y el conjunto no tenía
     ritmo: dos elementos vecinos respondían a velocidades distintas sin razón.
     El escalón es la intención, no el componente:
       1 → el elemento acusa el toque (hover, press)
       2 → un estado cambia (activo, plegado, sobrevuelo de zona)
       3 → algo entra o sale de la pantalla (revelados, ficha lateral)
       4 → una cifra o una barra recorre su valor, y hay que poder seguirla
     Ninguna pasa de 520 ms: por encima de eso el movimiento deja de acompañar
     y empieza a hacer esperar. */
  --sx-dur-1: 140ms;
  --sx-dur-2: 220ms;
  --sx-dur-3: 340ms;
  --sx-dur-4: 520ms;

  /* Salida rápida y frenada larga: el elemento parece tener peso y llegar
     solo, en vez de detenerse porque se acabó el tiempo. */
  --sx-ease:    cubic-bezier(.22, .61, .36, 1);
  --sx-ease-in: cubic-bezier(.55, .06, .68, .19);
  --sx-ease-io: cubic-bezier(.65, 0, .35, 1);

  /* Retardo por elemento dentro de una serie. anim.js lo escribe pieza a
     pieza; el valor de aquí es el que rige cuando nadie lo toca. */
  --sx-d: 0ms;
}

/* ---------- Reset ---------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* Los enlaces del menú saltan a su sección; el desplazamiento la conecta con
     el sitio del que venía. El bloque de movimiento reducido de más abajo lo
     desactiva. */
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--sx-font);
  color: var(--sx-slate);
  background: var(--sx-white);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  color: var(--sx-ink);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }

a {
  color: var(--sx-accent);
  text-decoration: none;
}
a:hover { color: var(--sx-accent-600); }

/* Piso de calidad: foco visible siempre, sin excepciones */
:focus-visible {
  outline: 2px solid var(--sx-accent);
  outline-offset: 3px;
  border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Revelado ----------
   El estado de partida (invisible y desplazado) cuelga de `.sx-anim`, una
   clase que anim.js escribe en <html> al arrancar. Es deliberado y no un
   rodeo: si el script no llega a ejecutarse —o si el sistema pide movimiento
   reducido, en cuyo caso anim.js no la escribe— ningún selector aplica y la
   página se ve entera. Ocultar con CSS lo que solo JavaScript puede devolver
   es la forma más común de dejar una página en blanco, y este archivo se
   abre con doble clic sin red delante de un cliente.

   Dos primitivas y ninguna más. `rise` para el texto y las tarjetas, que
   suben a su sitio; `fig` para mapas, gráficos y fotografías, que no se
   desplazan porque su encuadre es la información. */

.sx-anim .sx-rise,
.sx-anim .sx-fig {
  opacity: 0;
  transition: opacity var(--sx-dur-3) var(--sx-ease) var(--sx-d),
              transform var(--sx-dur-3) var(--sx-ease) var(--sx-d);
  will-change: opacity, transform;
}
.sx-anim .sx-rise { transform: translate3d(0, 14px, 0); }
.sx-anim .sx-fig  { transform: scale(.985); }

.sx-anim .sx-rise.is-in,
.sx-anim .sx-fig.is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* ---------- Barras fijas ----------
   La barra del sitio y la cabecera del sistema son translúcidas y quedan
   ancladas arriba. Con la página sin desplazar no tienen nada detrás y la
   sombra sobraría; en cuanto el contenido empieza a pasar por debajo, es lo
   único que las despega de él. Las dos reglas viven aquí, y no en su propia
   hoja, porque la clase es la misma y compartirla entre landing.css y os.css
   haría saltar el aviso de colisión del ensamblador. */

.nav, .head { transition: box-shadow var(--sx-dur-2) var(--sx-ease); }
.nav.sx-fija  { box-shadow: 0 1px 16px rgba(16, 16, 20, .07); }
.head.sx-fija { box-shadow: 0 1px 14px rgba(16, 16, 20, .06); }

/* ---------- Acuse de recibo ----------
   Un realce que se apaga solo, para confirmar que la acción del usuario tuvo
   efecto: la tarjeta que aterriza en otra columna, la respuesta que sustituye
   a la anterior. Va sobre `box-shadow` y no sobre el fondo para no pisar el
   color propio de cada componente. */

/* El anillo arranca y termina con extensión cero —invisible— en lugar de
   desvanecerse hacia `transparent`: interpolar un color hacia transparente
   pasa por un gris intermedio en varios navegadores, y ese gris se vería. */
@keyframes sx-destello {
  0%, 100% { box-shadow: 0 0 0 0 var(--sx-accent-200); }
  30%      { box-shadow: 0 0 0 3px var(--sx-accent-200); }
}
.sx-anim .sx-destello { animation: sx-destello 700ms var(--sx-ease) 1; }

/* ---------- Contenedor ---------- */

.sx-container {
  width: 100%;
  max-width: calc(var(--sx-container) + var(--sx-gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--sx-gutter);
}

@media (max-width: 900px) {
  :root { --sx-gutter: 32px; }
}
@media (max-width: 520px) {
  :root { --sx-gutter: 20px; }
}

/* ---------- Botones ----------
   pill  → nav y hero (acción principal de la marca)
   btn   → dentro de secciones (radius 4px)
   Las dos formas vienen del Nexcent y se mantienen separadas a propósito. */

.sx-pill,
.sx-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 1px solid transparent;
  background: var(--sx-accent);
  color: var(--sx-white);
  font-weight: 500;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--sx-dur-2) var(--sx-ease),
              color var(--sx-dur-2) var(--sx-ease),
              border-color var(--sx-dur-2) var(--sx-ease),
              box-shadow var(--sx-dur-2) var(--sx-ease),
              transform var(--sx-dur-1) var(--sx-ease-io);
}

.sx-pill {
  padding: 13px 26px;
  border-radius: var(--sx-r-pill);
}

.sx-btn {
  padding: 15px 32px;
  border-radius: var(--sx-r-btn);
}

.sx-pill:hover,
.sx-btn:hover {
  background: var(--sx-accent-600);
  color: var(--sx-white);
  box-shadow: var(--sx-shadow-md);
}

/* El botón cede bajo el dedo y vuelve. La escala se queda en 0,98 y el
   desplazamiento en 1 px: por debajo de eso no se percibe, y por encima el
   botón empuja a sus vecinos y se lee como un fallo de maquetación. */
.sx-pill:active,
.sx-btn:active {
  transform: translateY(1px) scale(.98);
  box-shadow: none;
  transition-duration: var(--sx-dur-1);
}

/* Variante secundaria: contorno */
.sx-pill--ghost,
.sx-btn--ghost {
  background: transparent;
  color: var(--sx-deep);
  border-color: var(--sx-line);
}
.sx-pill--ghost:hover,
.sx-btn--ghost:hover {
  background: var(--sx-white);
  color: var(--sx-deep);
  border-color: var(--sx-accent);
}

/* Variante WhatsApp — el único botón no índigo del sitio.
   El texto va en --sx-deep y no en blanco, que es lo que haría WhatsApp: sobre
   este verde el blanco se queda en 2,1:1 y sería el único elemento de la
   interfaz por debajo de AA, en un sistema que anota el contraste de cada
   token. El azul del logo sobre el mismo verde llega a 7,9:1. El verde —que es
   lo que hace reconocible el canal de un vistazo— no se toca. */
.sx-pill--wa,
.sx-btn--wa {
  background: var(--sx-wa);
  color: var(--sx-deep);
  border-color: transparent;
}
.sx-pill--wa:hover,
.sx-btn--wa:hover {
  background: var(--sx-wa-600);
  color: var(--sx-deep);
}

/* Enlace con flecha — el patrón "Readmore →" del Nexcent */
.sx-arrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
  font-size: 15px;
  color: var(--sx-accent);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.sx-arrow svg { transition: transform var(--sx-dur-2) var(--sx-ease); }
.sx-arrow:hover svg { transform: translateX(4px); }

/* ---------- El anillo ----------
   Elemento firma: el óvalo naranja que en el logo rodea la última letra.
   Reaparece como marcador del mapa, contorno de icono y punto de carrusel. */

.sx-ring {
  border: 2px solid var(--sx-accent);
  border-radius: var(--sx-r-pill);
  background: transparent;
}

/* ---------- Utilidades ---------- */

.sx-accent { color: var(--sx-accent); }
.sx-eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sx-mute);
}
.sx-num { font-variant-numeric: tabular-nums; }

.sx-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
