/* =====================================================
   base.css — Reset, tipografía base, contenedor, utilidades
   Mobile-first · Vanilla
   ===================================================== */

/* ---------- Reset minimalista (modern normalize) ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: var(--header-height);
}

body {
  font-family: var(--font-family);
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--text-main);
  background: var(--bg-primary);
  min-height: 100vh;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern" 1, "liga" 1;
}

/* Lock de scroll mientras el menú móvil está abierto.
   `overflow:hidden` bloquea scroll vertical y horizontal sin saltar
   la página (a diferencia de position:fixed en iOS). */
body.menu-open {
  overflow: hidden;
  touch-action: none;
  overscroll-behavior: contain;
}

/* ---------- Brand watermark (marca de agua decorativa) ----------
   Contenedor fixed a pantalla completa con z-index bajo que aloja el
   logo de la marca a muy baja opacidad. JS lo anima con parallax de
   scroll + mouse follow (lerp) usando exclusivamente transform3d.
   pointer-events: none → no bloquea interacción. aria-hidden porque
   es puramente decorativo (los AT lo ignoran). */
.brand-watermark {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.brand-watermark__img {
  width: clamp(420px, 60vmin, 980px);
  height: auto;
  opacity: 0.06;
  user-select: none;
  -webkit-user-drag: none;
  /* will-change: hint al compositor para que prepare la capa.
     Sólo transform (el filter svg sólo se aplica en desktop ≥ 1024px
     vía esta misma regla base). */
  will-change: transform;
  transform: translate3d(0, 0, 0);
  /* Filtro SVG de agua: el JS anima baseFrequency y scale continuamente
     para crear ondas que se mueven como una superficie líquida.
     Modulado por la posición del mouse (más ripple cerca de los bordes).
     Desactivado en móvil vía media query abajo. */
  filter: url(#brand-watermark-ripple);
}

@media (prefers-reduced-motion: reduce) {
  .brand-watermark__img {
    opacity: 0.05;
    filter: none;
  }
}

/* Mobile performance: el filtro SVG feTurbulence+feDisplacementMap del
   watermark es el mayor costo de paint en gama media (recompone continuo
   en cada frame). Bajo 1024px lo desactivamos — la marca sigue visible
   (logo + baja opacidad) sin el efecto líquido. */
@media (max-width: 1024px) {
  .brand-watermark__img {
    filter: none !important;
    will-change: auto;
  }
}

/* ---------- SVG defs (filtros reutilizables) ----------
   Bloque oculto que aloja definiciones SVG (filtros, gradientes, etc.).
   display:none NO sirve aquí porque algunos navegadores no procesan
   filtros SVG en elementos display:none → usamos tamaño cero. */
.svg-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Reduce CLS: reserve space for scrollbar gutter */
html { scrollbar-gutter: stable; }

/* ---------- Scrollbar (cyber vibe) ----------
   Estiliza el scrollbar de la página (no el de paneles internos,
   que ya tienen reglas más específicas en sus secciones).

   - Webkit/Blink (Chrome, Edge, Safari, Brave, Opera):
     thumb con el cyan accent + glow al hover.
   - Firefox: `scrollbar-color` + `scrollbar-width` (sintaxis simple).

   El thumb lleva un `border: 2px transparent` + `background-clip:
   content-box` para que el área clickeable sea de 10px aunque el
   "tubo" visible cyan quede de 6px — más fino, más cyber. */

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: rgba(11, 15, 25, 0.4);
  border-radius: 999px;
}

::-webkit-scrollbar-thumb {
  background: var(--accent-border-strong);
  border: 2px solid transparent;
  background-clip: content-box;
  border-radius: 999px;
  transition:
    background-color var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth);
}

::-webkit-scrollbar-thumb:hover,
::-webkit-scrollbar-thumb:active {
  background: var(--accent-color);
  box-shadow: 0 0 12px var(--accent-glow);
}

::-webkit-scrollbar-corner {
  background: transparent;
}

/* Firefox — sólo donde se soporta (le precede webkit por capacidad).
   Formato: <thumb> <track>. */
@supports (scrollbar-color: auto) {
  html {
    scrollbar-color: rgba(73, 197, 182, 0.4) rgba(11, 15, 25, 0.4);
    scrollbar-width: thin;
  }
}

/* ---------- Headings & typography ---------- */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-family);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--text-main);
}

h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); }

p {
  color: var(--text-muted);
  line-height: 1.7;
}

a {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-smooth);
}

a:hover { color: var(--accent-color); }

button {
  font-family: inherit;
  cursor: pointer;
  border: none;
  background: none;
  color: inherit;
}

img, svg, video {
  max-width: 100%;
  height: auto;
  display: block;
}

ul, ol {
  list-style: none;
}

/* ---------- Layout containers ---------- */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding-inline: var(--container-pad);
}

.section {
  position: relative;
  padding-block: var(--space-9);
}

@media (min-width: 768px) {
  .section { padding-block: var(--space-10); }
}

/* ---------- Skip link (a11y) ---------- */
.skip-link {
  position: absolute;
  top: -100px;
  left: var(--space-3);
  background: var(--accent-color);
  color: var(--bg-primary);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  font-weight: 600;
  z-index: var(--z-modal);
  transition: top var(--dur-fast) var(--ease-smooth);
}

.skip-link:focus {
  top: var(--space-3);
  color: var(--bg-primary);
}

/* ---------- Focus styles (a11y) ---------- */
:focus-visible {
  outline: 2px solid var(--accent-color);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* ---------- Selection ---------- */
::selection {
  background: var(--accent-glow);
  color: var(--text-main);
}

/* ---------- i18n visibility ----------
   No usamos display:none por elemento porque todos los textos
   llevan AMBOS atributos (data-lang-es y data-lang-en) en el mismo nodo.
   El JS de i18n.js actualiza el textContent en cada cambio de idioma.
   Esta regla sólo afecta a nodos que sólo tengan UN idioma (p.ej. links
   cuyo target es visible en ambos idiomas sin texto).
*/
html[data-lang="es"] [data-lang-en-only] { display: none; }
html[data-lang="en"] [data-lang-es-only] { display: none; }

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

/* ---------- Reveal on scroll (animation engine) ---------- */
/* "Elegant" entrance: combined fade + slide + scale with smooth easing. */
.reveal {
  opacity: 0;
  transform: translateY(48px) scale(0.96);
  transition:
    opacity 1000ms var(--ease-out-expo),
    transform 1000ms var(--ease-out-expo);
  will-change: opacity, transform;
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* Stagger delays for groups — wider gaps for an elegant cascade */
.reveal[data-delay="1"] { transition-delay: 140ms; }
.reveal[data-delay="2"] { transition-delay: 320ms; }
.reveal[data-delay="3"] { transition-delay: 500ms; }
.reveal[data-delay="4"] { transition-delay: 680ms; }
.reveal[data-delay="5"] { transition-delay: 860ms; }

/* "Reveal-up" variant — only translateY, no scale (for text-heavy elements) */
.reveal-up {
  opacity: 0;
  transform: translateY(36px);
  transition:
    opacity 900ms var(--ease-out-expo),
    transform 900ms var(--ease-out-expo);
}

.reveal-up.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* "Reveal-blur" variant — blur-in + slide-up para tarjetas.
   El desenfoque simula un enfoque progresivo al entrar al viewport. */
.reveal-blur {
  opacity: 0;
  transform: translateY(30px);
  filter: blur(10px);
  transition:
    opacity 900ms var(--ease-out-expo),
    transform 900ms var(--ease-out-expo),
    filter 900ms var(--ease-out-expo);
}

.reveal-blur.is-visible {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

/* Stagger 100ms para .reveal-blur (servicios) */
.reveal-blur[data-delay="1"] { transition-delay: 100ms; }
.reveal-blur[data-delay="2"] { transition-delay: 200ms; }
.reveal-blur[data-delay="3"] { transition-delay: 300ms; }
.reveal-blur[data-delay="4"] { transition-delay: 400ms; }
.reveal-blur[data-delay="5"] { transition-delay: 500ms; }

/* "Reveal-soft" variant — solo fade + blur (sin slide).
   Para títulos y subtítulos que quieren una entrada suave. */
.reveal-soft {
  opacity: 0;
  filter: blur(10px);
  transition:
    opacity 1100ms var(--ease-out-expo),
    filter 1100ms var(--ease-out-expo);
}

.reveal-soft.is-visible {
  opacity: 1;
  filter: blur(0);
}

/* ---------- Utilities ---------- */
.mono { font-family: var(--font-mono); }
.display { font-family: var(--font-display); font-weight: 700; }
.accent { color: var(--accent-color); }
.muted { color: var(--text-muted); }
.dim { color: var(--text-dim); }
.uppercase { text-transform: uppercase; letter-spacing: 0.05em; }

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