/* ================================================================
   DEKEVA — Accesibilidad y resiliencia
   Se carga en TODAS las páginas (landings, bare landings y blog),
   siempre después del CSS específico, desde dkv_enqueue_assets().

   Reglas transversales que no pertenecen a ninguna landing concreta:
   contraste sobre fondos oscuros, foco de teclado, skip link,
   cursor custom condicionado, motion reducido y modo sin GSAP.
================================================================ */

/* ================================================================
   1. CONTRASTE — --muted sobre bloques de fondo oscuro
   ----------------------------------------------------------------
   :root define --muted en un gris que cumple AA sobre fondo claro
   (#6b6b68 → 5,35:1 sobre blanco). Ese mismo gris sobre el negro de
   marca bajaría a 3,4:1, así que en los bloques oscuros se recupera
   un gris claro (#b4b3af → 9,27:1). Como --muted se hereda, basta
   con redefinirla en el contenedor: todos los color:var(--muted)
   de dentro la toman sin tocar una sola regla más.
================================================================ */
.section-calidad,
.section-deki-web,
.section-credo,
.section-ia,
.section-place,
.section-deki-terminal,
.section-casos.deploy-mode,
.calidad-stat,
.deki-web-card,
.ia-card,
.place-col,
.deployment-card,
.paq-card.is-featured,
.arch-col--center .arch-node,
.newsletter,
.site-footer {
  --muted: var(--muted-on-dark, #b4b3af);
}

/* ================================================================
   2. FOCO DE TECLADO (WCAG 2.4.7)
   ----------------------------------------------------------------
   No había ninguna regla de foco en el tema: con cursor:none activo,
   navegar con teclado era completamente a ciegas.
================================================================ */
:focus-visible {
  outline: 2px solid var(--blue, #032FD4);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Sobre fondo oscuro el azul de marca no contrasta (2,19:1): blanco. */
.section-calidad :focus-visible,
.section-cta :focus-visible,
.section-credo :focus-visible,
.section-ia :focus-visible,
.section-place :focus-visible,
.section-deki-web :focus-visible,
.section-deki-terminal :focus-visible,
.paq-card.is-featured :focus-visible,
.newsletter :focus-visible,
.site-footer :focus-visible {
  outline-color: #fff;
}

/* ================================================================
   3. SKIP LINK — saltar el header (WCAG 2.4.1)
================================================================ */
.dkv-skip {
  position: fixed;
  top: 0;
  left: 1rem;
  z-index: 10001;
  transform: translateY(-200%);
  background: var(--blue, #032FD4);
  color: #fff;
  font-family: var(--f-body, system-ui, sans-serif);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: .04em;
  text-decoration: none;
  padding: .85rem 1.4rem;
  transition: transform .2s ease;
}
.dkv-skip:focus {
  transform: translateY(0);
  outline: 2px solid #fff;
  outline-offset: -6px;
}
/* el destino recibe foco por programa: no debe dibujar contorno */
[tabindex="-1"]:focus:not(:focus-visible) { outline: none; }

/* ================================================================
   4. CURSOR CUSTOM — sólo cuando el JS lo ha montado de verdad
   ----------------------------------------------------------------
   El CSS de cada landing declara body{cursor:none}. El cursor de
   sustitución lo dibuja initCursor(), que corre después de window.load:
   hasta entonces —y para siempre si el JS no arranca— el usuario se
   quedaba sin ningún cursor visible. Ahora cursor:none depende de una
   clase que sólo pone el JS cuando el cursor custom está en pantalla.
================================================================ */
body:not(.dkv-cursor-on),
body:not(.dkv-cursor-on) a,
body:not(.dkv-cursor-on) button,
body:not(.dkv-cursor-on) [data-magnetic] {
  cursor: auto;
}
body:not(.dkv-cursor-on) a,
body:not(.dkv-cursor-on) button,
body:not(.dkv-cursor-on) [data-magnetic] {
  cursor: pointer;
}

/* ================================================================
   5. FAQ — lo cerrado no debe ser tabulable ni legible por lector
   ----------------------------------------------------------------
   max-height:0 + overflow:hidden lo oculta a la vista, pero los
   enlaces de dentro seguían recibiendo foco y el lector los leía.
   visibility:hidden lo saca del árbol; el retardo deja terminar la
   animación de cierre (max-height .55s).
================================================================ */
.faq-answer {
  visibility: hidden;
  transition: max-height .55s var(--ease-lux, cubic-bezier(.76,0,.24,1)),
              visibility 0s linear .55s;
}
.faq-item.open .faq-answer {
  visibility: visible;
  transition: max-height .55s var(--ease-lux, cubic-bezier(.76,0,.24,1)),
              visibility 0s linear 0s;
}

/* ================================================================
   6. MODO DEGRADADO — GSAP no ha cargado
   ----------------------------------------------------------------
   GSAP se sirve desde jsdelivr. Si esa petición falla (red corporativa,
   bloqueador, CDN caído) el preloader se quedaba cubriendo la pantalla
   y el hero permanecía en opacity:0. El JS marca .no-gsap y aquí se
   revela todo para que la página siga siendo legible y usable.
================================================================ */
.no-gsap #preloader,
.no-gsap #page-transition,
.no-gsap .cursor__dot,
.no-gsap .cursor__ring,
.no-gsap .cursor-trail {
  display: none !important;
}
.no-gsap #smooth-wrapper,
.no-gsap #smooth-content {
  transform: none !important;
}
.no-gsap .svc-hero-title,
.no-gsap .svc-hero-line-text,
.no-gsap .svc-hero-sub,
.no-gsap .svc-hero-stamp,
.no-gsap .svc-hero-watermark,
.no-gsap .svc-breadcrumb,
.no-gsap .btn-hero,
.no-gsap .btn-hero-ghost,
.no-gsap .ent-card,
.no-gsap .proceso-step,
.no-gsap .paq-card,
.no-gsap .calidad-stat,
.no-gsap .faq-item,
.no-gsap .caso-card,
.no-gsap [style*="opacity:0"],
.no-gsap [style*="opacity: 0"] {
  opacity: 1 !important;
  transform: none !important;
  visibility: visible !important;
}
.no-gsap .svc-hero-rule { transform: scaleX(1) !important; }

/* ================================================================
   7. MOTION REDUCIDO (prefers-reduced-motion)
   ----------------------------------------------------------------
   Las landings de servicio llevan ScrollSmoother (secuestra el scroll),
   rastro de cursor y reveals por scroll. Para quien pide menos
   movimiento, el JS no arranca ScrollSmoother ni el rastro; aquí se
   neutraliza el resto y se revela el contenido que animaba GSAP.
================================================================ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }

  #preloader,
  #page-transition,
  .cursor__dot,
  .cursor__ring,
  .cursor-trail,
  .ticker-track {
    display: none !important;
  }

  .svc-hero-title,
  .svc-hero-line-text,
  .svc-hero-sub,
  .svc-hero-stamp,
  .svc-breadcrumb,
  .btn-hero,
  .btn-hero-ghost,
  .ent-card,
  .proceso-step,
  .paq-card,
  .calidad-stat,
  .faq-item,
  .caso-card {
    opacity: 1 !important;
    transform: none !important;
  }

  /* la respuesta abierta debe seguir apareciendo, sin animar */
  .faq-item.open .faq-answer { visibility: visible !important; }

  #smooth-wrapper,
  #smooth-content { transform: none !important; }
}
