/* =============================================================================
   AlvaradoGraphics — Base: reset, tipografía, retícula y utilidades
   ========================================================================== */

/* -- Reset -------------------------------------------------------------------
   Moderno y mínimo: solo lo que realmente hace falta. */

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

* { margin: 0; }

/* El atributo `hidden` sólo aplica `display: none` con especificidad de agente
   de usuario, así que cualquier `display: flex` o `grid` en una clase lo anula
   en silencio. Sin esta regla, los paneles marcados como ocultos seguían
   ocupando espacio. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Compensa la altura de la barra fija al saltar a un ancla. */
  scroll-padding-top: 6rem;
}

body {
  min-height: 100svh;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  font-weight: 400;
  overflow-x: hidden;

  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;

  /* Las cifras tabulares evitan que los números bailen al animarse un contador. */
  font-variant-numeric: tabular-nums;

  transition: background-color var(--duration-base) var(--ease-out),
              color var(--duration-base) var(--ease-out);
}

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

input, button, textarea, select { font: inherit; color: inherit; }

button { background: none; border: none; cursor: pointer; }

p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }

ul, ol { list-style: none; padding: 0; }

a { color: inherit; text-decoration: none; }

:target { scroll-margin-top: 7rem; }

/* -- Tipografía -------------------------------------------------------------- */

.display {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  /* `balance` reparte las palabras entre líneas para que no quede una sola
     colgando al final — el detalle que separa un titular compuesto de uno
     simplemente escrito. */
  text-wrap: balance;
}

.display-xl { font-family: var(--font-display); font-weight: 400;
  font-size: var(--text-5xl); line-height: 0.92;
  letter-spacing: -0.04em; text-wrap: balance; }

.display-lg { font-family: var(--font-display); font-weight: 400;
  font-size: var(--text-4xl); line-height: 0.95;
  letter-spacing: -0.035em; text-wrap: balance; }

.display-md { font-family: var(--font-display); font-weight: 400;
  font-size: var(--text-3xl); line-height: 1.0;
  letter-spacing: -0.03em; text-wrap: balance; }

.display-sm { font-family: var(--font-display); font-weight: 400;
  font-size: var(--text-2xl); line-height: 1.08;
  letter-spacing: -0.025em; text-wrap: balance; }

.display-xs { font-family: var(--font-display); font-weight: 400;
  font-size: var(--text-xl); line-height: 1.15;
  letter-spacing: -0.02em; text-wrap: balance; }

/* La cursiva de Instrument Serif es notablemente más expresiva que la redonda;
   se reserva para una o dos palabras por titular, nunca para frases enteras. */
.display em, .display-xl em, .display-lg em,
.display-md em, .display-sm em, .display-xs em {
  font-style: italic;
  color: var(--accent);
}

/* Etiqueta de sección: mono, versalitas espaciadas. Es el recurso que ordena
   la página sin añadir peso visual. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-muted);
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.eyebrow::before {
  content: '';
  width: 1.75rem;
  height: 1px;
  background: var(--accent);
  flex: none;
}

.eyebrow--plain::before { display: none; }

.lede {
  font-size: var(--text-md);
  line-height: var(--leading-snug);
  color: var(--ink-soft);
  max-width: 38ch;
  text-wrap: pretty;
}

.prose {
  max-width: var(--shell-text);
  color: var(--ink-soft);
  text-wrap: pretty;
}

.prose p + p { margin-top: 1.35em; }

.prose strong { color: var(--ink); font-weight: 600; }

/* Numeración de índice, estilo catálogo. */
.index-num {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink-faint);
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
}

/* -- Retícula ----------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--shell-max);
  margin-inline: auto;
  padding-inline: var(--shell-pad);
}

.shell--narrow { max-width: 62rem; }
.shell--text   { max-width: var(--shell-text); }

.section    { padding-block: var(--section-y); }
.section--sm { padding-block: var(--section-y-sm); }

/* Línea divisoria superior: la estructura se marca con filetes, no con cajas.
   Es el recurso más característico del diseño editorial impreso. */
.section--ruled { border-top: 1px solid var(--rule); }

/* Encabezado de sección de dos columnas: etiqueta a la izquierda, contenido a
   la derecha. Rompe la simetría centrada que tenía el sitio anterior, donde
   todas las secciones eran idénticas y el ojo no encontraba dónde detenerse. */
.section-head {
  display: grid;
  gap: var(--space-md);
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}

@media (min-width: 56rem) {
  .section-head {
    grid-template-columns: 14rem 1fr;
    gap: var(--space-xl);
    align-items: start;
  }
  .section-head__aside { padding-top: 0.65rem; }
}

.section-head__title { font-size: var(--text-3xl); }
.section-head__intro { margin-top: var(--space-md); max-width: 46ch; }

.rule {
  height: 1px;
  background: var(--rule);
  border: 0;
  margin: 0;
}

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

.stack > * + * { margin-top: var(--flow, var(--space-md)); }

.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}

.text-muted  { color: var(--ink-muted); }
.text-soft   { color: var(--ink-soft); }
.text-accent { color: var(--accent); }

.mono {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
}

/* Oculto visualmente pero legible por lectores de pantalla. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Salto al contenido: obligatorio para navegación por teclado. El sitio
   anterior no lo tenía, así que llegar al contenido exigía tabular por toda
   la navegación en cada página. */
.skip-link {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -120%);
  z-index: var(--z-float);
  background: var(--ink);
  color: var(--paper);
  padding: 0.85rem 1.5rem;
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  transition: transform var(--duration-fast) var(--ease-out);
}

.skip-link:focus { transform: translate(-50%, 0); }

/* -- Foco --------------------------------------------------------------------
   `:focus-visible` muestra el anillo solo en navegación por teclado, no al
   hacer clic con el ratón. El sitio anterior desactivaba el outline sin
   sustituirlo, lo que dejaba la navegación por teclado completamente a ciegas. */

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}

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

/* -- Barra de desplazamiento -------------------------------------------------- */

@supports (scrollbar-width: thin) {
  html { scrollbar-width: thin; scrollbar-color: var(--rule-strong) transparent; }
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--rule-strong);
  border-radius: 100px;
  border: 3px solid var(--paper);
}
::-webkit-scrollbar-thumb:hover { background: var(--ink-faint); }

/* =============================================================================
   Animaciones de entrada
   =============================================================================
   Se usa `animation-timeline: view()` donde el navegador lo soporta: el reveal
   queda ligado al scroll por el compositor, sin JavaScript y sin tirones. El
   IntersectionObserver queda solo como respaldo para navegadores antiguos.
   ========================================================================== */

@keyframes rise {
  from { opacity: 0; transform: translateY(clamp(1rem, 3vw, 2.5rem)); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes revealClip {
  from { opacity: 0; clip-path: inset(0 0 100% 0); }
  to   { opacity: 1; clip-path: inset(0 0 0 0); }
}

@keyframes scaleIn {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}

/* Respaldo con IntersectionObserver (JS añade .is-visible). */
.reveal {
  opacity: 0;
  transform: translateY(clamp(1rem, 3vw, 2.5rem));
  transition: opacity var(--duration-reveal) var(--ease-out),
              transform var(--duration-reveal) var(--ease-out);
}

.reveal.is-visible { opacity: 1; transform: none; }

/* Escalonado para listas: cada elemento entra un poco después del anterior. */
.reveal[data-delay="1"] { transition-delay: 80ms; }
.reveal[data-delay="2"] { transition-delay: 160ms; }
.reveal[data-delay="3"] { transition-delay: 240ms; }
.reveal[data-delay="4"] { transition-delay: 320ms; }
.reveal[data-delay="5"] { transition-delay: 400ms; }

/* Versión nativa ligada al scroll, cuando está disponible. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal {
      opacity: 1;
      transform: none;
      transition: none;
      animation: rise linear both;
      animation-timeline: view();
      /* Entra cuando el elemento asoma por abajo y termina antes de llegar
         al centro, de modo que se lee ya asentado. */
      animation-range: entry 0% cover 26%;
    }
  }
}

/* -- Movimiento reducido -----------------------------------------------------
   Obligatorio: las animaciones continuas provocan malestar real a personas con
   sensibilidad vestibular. El sitio anterior ignoraba esta preferencia por
   completo, incluidas las partículas en bucle infinito del hero. */

@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 { opacity: 1 !important; transform: none !important; }

  html { scroll-behavior: auto; }
}

/* =============================================================================
   Transiciones entre páginas
   =============================================================================
   La View Transitions API hace que navegar de la portada a un proyecto se sienta
   como una aplicación nativa en vez de una recarga completa. Degrada de forma
   invisible en navegadores que no la implementan.
   ========================================================================== */

@view-transition { navigation: auto; }

@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) {
    animation: fade var(--duration-base) var(--ease-out) reverse;
  }
  ::view-transition-new(root) {
    animation: rise var(--duration-base) var(--ease-out);
  }

  /* La portada del proyecto se transforma de la tarjeta a la cabecera en vez de
     desaparecer y reaparecer: es la continuidad la que da la sensación de app. */
  ::view-transition-old(project-cover),
  ::view-transition-new(project-cover) {
    animation: none;
    mix-blend-mode: normal;
    height: 100%;
    object-fit: cover;
  }
}

/* Impresión: fondo blanco, sin elementos flotantes. */
@media print {
  .site-nav, .site-footer, .whatsapp-dock, .theme-toggle, .skip-link { display: none !important; }
  body { background: #fff; color: #000; }
  .reveal { opacity: 1 !important; transform: none !important; }
}
