/* ============================================================================
   BASE — reset ligero, accesibilidad, grano. Cargar después de tokens.css.
   ============================================================================ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;           /* fallback nativo cuando Lenis está apagado */
  background: var(--ground);
  /* El nav es fixed y mide de 73px (360-390) a 128px (2560): sin esto, un salto por ancla
     deja el encabezado de destino en y=0, o sea tapado por completo. Se descubrió en la
     pasada del Note 8 saltando a #contact-title. Va en el contenedor de scroll y no ancla
     por ancla, para que un encabezado nuevo lo herede solo.
     El clamp es por ANCHO a propósito: el padding del nav es 2vw sobre un root fluido, así
     que el nav crece con el ancho y no con el alto. La primera versión usaba vh y se quedaba
     corta en ultrawide (a 2560 daba 101px contra un nav de 128). Verificado sin tapados en
     360, 390, 768, 1200, 1440 y 2560. */
  scroll-padding-block-start: clamp(96px, 7vw, 150px);
}

body {
  font-family: var(--font-body);   /* Inter: default de lectura; el display se declara por clase */
  font-optical-sizing: auto;
  font-weight: 400;
  color: var(--ink);
  /* sin fondo en body: el <html> es el respaldo (detrás del canvas fijo z-index:-1);
     así el terreno persistente asoma en las secciones transparentes (hero/contacto/footer) */
  line-height: 1.5;
  min-height: 100vh;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Lenis: solo cuando la clase está presente (JS la añade si el motion está encendido).
   Si Lenis no arranca, el scroll nativo funciona intacto. */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: clip; }

img, canvas, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
ul { list-style: none; padding: 0; }

::selection { background: var(--accent); color: var(--ground); }

/* --- Foco visible: anillo teal (--accent-bright) con contraste ≥3:1, nunca suprimido por el cursor custom --- */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--accent-bright);
  outline-offset: 3px;
  border-radius: 2px;
}

/* --- Utilidades de accesibilidad --- */
.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;
}
.skip-link {
  position: fixed; top: 0; left: 0; z-index: 100;
  background: var(--accent); color: var(--ground);
  padding: 0.75rem 1.25rem; font-family: var(--font-mono); font-size: var(--fs-label);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  transform: translateY(-120%); transition: transform var(--d-fast) var(--ease-swift);
}
.skip-link:focus { transform: translateY(0); }

/* --- Grano: overlay fijo, decorativo, no bloquea el puntero. Mata el look flat-vector. --- */
.grain {
  position: fixed; inset: 0; z-index: 80; pointer-events: none;
  opacity: 0.05; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --- Contrato reduced-motion: se respeta por media query Y por el toggle en página --- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
html[data-motion="off"] { scroll-behavior: auto; }
html[data-motion="off"] *, html[data-motion="off"] *::before, html[data-motion="off"] *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
}
/* El grano no se anima, pero bajo reduced-motion lo dejamos estático (ya lo es). */
