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

html, body,
h1, h2, h3, h4, h5, h6,
p, ul, ol, figure { margin: 0; padding: 0; }

ul { list-style: none; }

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

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

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

/* =========================================
   Tokens
   ========================================= */
/* :root = tema CLARO por defecto.
   El tema OSCURO se activa con [data-theme="dark"] en <html>.
   --bg-rgb existe para poder usar el color de fondo con alpha
   en gradientes (rgba(var(--bg-rgb), 0.45)), que también flippean. */
:root {
  --bg:        #F2EEE3;
  --bg-deep:   #E8E4D7;
  --bg-rgb:    242, 238, 227;
  --ink:       #0E0E10;
  --ink-hover: #1d1d20;
  --ink-soft:  #3A3A3D;
  --muted:     #8B8B8F;
  --line:      rgba(14, 14, 16, 0.10);
  --accent:    #2C3FFF;
  --green:     #16B055;

  --radius-pill: 999px;

  --font-sans:  'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-serif: 'Playfair Display', 'Times New Roman', serif;
}

/* Tema OSCURO — sobrescribe sólo los tokens cromáticos.
   Tipografía, radios y acentos se mantienen. */
:root[data-theme="dark"] {
  --bg:        #0E0E10;
  --bg-deep:   #18181B;
  --bg-rgb:    14, 14, 16;
  --ink:       #F2EEE3;
  --ink-hover: #E0DCD1;
  --ink-soft:  #C5C5C9;
  --muted:     #6E6E72;
  --line:      rgba(242, 238, 227, 0.12);
  --accent:    #5A6BFF;
}

/* Transición global suave al alternar tema.
   Sólo afecta a propiedades cromáticas para no degradar otras animaciones. */
html,
body,
.topbar,
.site-header::after,
.modal__panel,
.contact-link,
.contact-link-icon,
.pill,
.servicio-row,
.proyecto-row,
.btn-primary,
.btn-submit {
  transition:
    background-color .35s ease,
    color .35s ease,
    border-color .35s ease;
}

html, body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body { padding-top: 62px; }

/* =========================================
   Fixed top navigation
   ========================================= */
.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  /* Grid 1fr auto 1fr: brand y actions ocupan columnas iguales,
     el nav queda en la columna central -> centrado real respecto al viewport. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  padding: 16px 40px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

/* =========================================
   Site header
   ========================================= */
.site-header {
  position: relative;
  overflow: hidden;
}

.site-header-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  opacity: 0.9;
  pointer-events: none;
}

.site-header::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      to bottom,
      rgba(var(--bg-rgb), 0.45) 0%,
      rgba(var(--bg-rgb), 0)    18%,
      rgba(var(--bg-rgb), 0)    82%,
      rgba(var(--bg-rgb), 0.45) 100%
    );
  z-index: 0;
  pointer-events: none;
}

.hero { position: relative; z-index: 1; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  font-size: 14px;
  color: var(--ink);
}

.brand-dot {
  width: 9px;
  height: 9px;
  background: var(--accent);
  border-radius: 50%;
}

.topnav {
  display: flex;
  gap: 36px;
}

.topnav a {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink);
  transition: opacity 0.2s ease;
}

.topnav a:hover { opacity: 0.55; }

/* =========================================
   Menú hamburguesa (móvil)
   ----------------------------------------
   El botón está oculto en escritorio y solo aparece en ≤900px
   (ver media query más abajo). Las 3 barras se animan a una "X"
   cuando el botón tiene aria-expanded="true".
   El área táctil es de 44x44px (recomendación de accesibilidad).
   ========================================= */
.nav-toggle {
  display: none;              /* visible solo en ≤900px */
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  flex-shrink: 0;
}

.nav-toggle__bars {
  position: relative;
  display: block;
  width: 20px;
  height: 14px;
}

.nav-toggle__bars span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: transform .3s ease, opacity .2s ease, top .3s ease;
}

.nav-toggle__bars span:nth-child(1) { top: 0; }
.nav-toggle__bars span:nth-child(2) { top: 6px; }
.nav-toggle__bars span:nth-child(3) { top: 12px; }

/* Estado abierto: barra superior e inferior forman la "X",
   la del medio se desvanece. */
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1) {
  top: 6px;
  transform: rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3) {
  top: 6px;
  transform: rotate(-45deg);
}

/* Fondo oscuro detrás del drawer. Oculto vía [hidden] cuando el menú
   está cerrado; el JS quita [hidden] y luego togglea .is-visible. */
.nav-backdrop {
  position: fixed;
  inset: 0;
  z-index: 90;               /* debajo del topbar (100) y del drawer (110) */
  background: rgba(14, 14, 16, 0.45);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity .3s ease;
}

.nav-backdrop[hidden] { display: none; }
.nav-backdrop.is-visible { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .nav-toggle__bars span,
  .nav-backdrop { transition: none; }
}

/* Cluster derecho del topbar: agrupa theme-toggle + lang-toggle
   y se alinea al borde derecho de su columna del grid. */
.topbar__actions {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  justify-self: end;
}

.lang-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  font-size: 12px;
  letter-spacing: 0.04em;
}

.lang-btn {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  padding: 0;
  letter-spacing: 0.04em;
  transition: color 0.2s ease;
}

.lang-btn.is-active {
  color: var(--ink);
  font-weight: 600;
}

.lang-btn:hover { color: var(--ink); }

.lang-sep { color: var(--muted); }

/* ---- Hero ---- */
.hero {
  position: relative;
  /* Bottom reducido para acercar el puente al final del hero. */
  padding: 44px 40px 40px;
}

.hero-meta {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink);
  text-shadow: 0 1px 2px rgba(var(--bg-rgb), 0.85);
  padding-bottom: 56px;
}

.hero-title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(60px, 11vw, 170px);
  line-height: 0.95;
  letter-spacing: -0.02em;
  margin-bottom: 88px;
}

.hero-title-line {
  display: block;
  white-space: nowrap;
}

.hero-title-accent {
  font-style: italic;
  font-weight: 400;
  color: var(--accent);
}

.hero-bottom {
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
  gap: 40px;
  flex-wrap: wrap;
}

.hero-cta {
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}

/* Status pill */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--ink-soft);
}

.status-pulse {
  position: relative;
  width: 8px;
  height: 8px;
  background: var(--green);
  border-radius: 50%;
}

.status-pulse::before {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  background: var(--green);
  opacity: 0.3;
  animation: pulse 1.8s ease-out infinite;
}

@keyframes pulse {
  0%   { transform: scale(0.7); opacity: 0.4; }
  100% { transform: scale(2.1); opacity: 0; }
}

.status-label {
  font-weight: 700;
  color: var(--ink);
  letter-spacing: 0.06em;
}

/* CTA button */
.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius-pill);
  font-size: 14px;
  font-weight: 500;
  transition: transform 0.2s ease, background 0.2s ease;
}

.btn-primary:hover {
  background: var(--ink-hover);
  transform: translateY(-1px);
}

.btn-primary svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Vertical text */
.hero-vertical {
  position: absolute;
  top: 50%;
  right: 14px;
  transform: translateY(-50%);
  writing-mode: vertical-rl;
  font-size: 10px;
  letter-spacing: 0.45em;
  text-transform: uppercase;
  color: var(--muted);
}

/* =========================================
   Page sections — base común
   ========================================= */
main { display: block; }

main > section {
  padding-block: clamp(80px, 11vw, 160px);
  padding-inline: clamp(20px, 4vw, 60px);
  max-width: 1440px;
  margin: 0 auto;
  position: relative;
}

main > section + section {
  border-top: 1px solid var(--line);
}

/* La primera sección de <main> recibe menos padding superior:
   el bloque .bridge ya ocupa parte del espacio entre hero y "Sobre nosotros". */
main > section:first-of-type {
  padding-block-start: clamp(32px, 4.5vw, 72px);
}

/* =========================================
   Bridge — puente editorial entre hero y "Sobre nosotros"
   ----------------------------------------
   Pausa minimal: sin caja, sin borde, sin íconos.
   Tres niveles tipográficos: eyebrow / servicios / ancla en serif.
   ========================================= */
.bridge {
  max-width: 1440px;
  margin: 0 auto;
  padding-block: clamp(36px, 4.5vw, 64px);
  padding-inline: clamp(20px, 4vw, 60px);
  text-align: center;
}

.bridge__eyebrow {
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 20px;
}

.bridge__services {
  display: flex;
  justify-content: center;
  align-items: baseline;
  flex-wrap: wrap;
  list-style: none;
  padding: 0;
  margin: 0 auto;
  font-family: var(--font-sans);
  font-size: clamp(15px, 1.4vw, 18px);
  font-weight: 400;
  color: var(--ink);
  line-height: 1.6;
}

.bridge__services li {
  position: relative;
  padding: 0 18px;
}

/* Punto medio entre items (no después del último).
   En mobile, cuando pase a columna, lo ocultamos. */
.bridge__services li:not(:last-child)::after {
  content: "·";
  position: absolute;
  right: -3px;
  top: 50%;
  transform: translateY(-55%);
  color: var(--muted);
  font-weight: 700;
}

/* ---- Bridge variante "quote" (entre Servicios y Proyectos) ----
   Sin eyebrow ni lista: solo una frase en serif itálica + flecha guía. */
.bridge--quote {
  padding-block: clamp(16px, 2vw, 32px);
}

.bridge__quote {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  /* 44px → 56px: presencia editorial real. */
  font-size: clamp(2.75rem, 4.5vw, 3.5rem);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink-soft);
  max-width: 26ch;
  margin: 0 auto;
}

/* Flecha guía hacia "Trabajos recientes".
   Color violeta (var(--accent)), centrada, con bounce sutil. */
.bridge__arrow {
  display: flex;
  justify-content: center;
  margin-top: clamp(32px, 3.5vw, 40px);
  color: var(--accent);
  animation: bridge-arrow-bounce 1.5s ease-in-out infinite;
}

.bridge__arrow svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@keyframes bridge-arrow-bounce {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(3px); }
}

/* Respetar a usuarios que prefieren menos movimiento. */
@media (prefers-reduced-motion: reduce) {
  .bridge__arrow { animation: none; }
}

/* Recorta el aire entre "Proceso" y "Proyectos" para acomodar el bridge
   sin agrandar el gap total. Reducción ~40-50% respecto al default
   clamp(80px, 11vw, 160px) que viene de "main > section". */
#proceso   { padding-block-end:   clamp(24px, 3vw, 48px); }
#proyectos { padding-block-start: clamp(24px, 3vw, 48px); }

/* Recorte suave entre "Sobre nosotros" (stats) y "Servicios".
   Reducción ~30% respecto al default — solo lo justo para apretar el ritmo. */
#sobre-mi   { padding-block-end:   clamp(56px, 7.5vw, 110px); }
#servicios  { padding-block-start: clamp(56px, 7.5vw, 110px); }

/* Recorte suave entre "Servicios" y "Proceso" (sin bridge entremedio). */
#servicios  { padding-block-end:   clamp(56px, 7.5vw, 110px); }
#proceso    { padding-block-start: clamp(56px, 7.5vw, 110px); }

/* Recorte entre "Proyectos" y "Contacto" (~40% respecto al default). */
#proyectos  { padding-block-end:   clamp(48px, 6vw, 96px); }
#contacto   { padding-block-start: clamp(48px, 6vw, 96px); }


/* Etiquetas de sección */
.section-meta,
.seccion-label,
.left .label {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 32px;
}

/* H2 de sección — serif grande, similar al hero pero más contenido */
main > section h2 {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(2.25rem, 5vw, 4.25rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin-bottom: 56px;
  max-width: 22ch;
}

/* =========================================
   Sobre mí
   ========================================= */
.sobre-mi {
  display: grid;
  /* ~40 / 60: foto a la izquierda, contenido a la derecha. */
  grid-template-columns: 2fr 3fr;
  gap: clamp(40px, 6vw, 96px);
  align-items: center;
}

.sobre-columna-der h2 { margin-bottom: 40px; }

.sobre-columna-der p {
  /* 20px (mínimo) → 22px (máximo). */
  font-size: clamp(1.25rem, 1.5vw, 1.375rem);
  line-height: 1.7;
  color: var(--ink-soft);
  max-width: 60ch;
}

/* ---- Foto editorial ---- */
.sobre-foto {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;           /* retrato editorial */
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-deep);    /* placeholder mientras carga */
  border: 1px solid var(--line);
  box-shadow:
    0 30px 60px -28px rgba(0, 0, 0, 0.32),
    0 14px 28px -16px rgba(0, 0, 0, 0.18);
  transition: box-shadow .35s ease, transform .5s cubic-bezier(.22, 1, .36, 1);
}

.sobre-foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Overlay sutil: degradado oscuro en la base de la foto.
   Suma profundidad sin oscurecer la imagen, integra con la paleta. */
.sobre-foto::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0)    55%,
    rgba(0, 0, 0, 0.18) 100%
  );
  pointer-events: none;
}

/* En tema oscuro la sombra se intensifica para “despegar” el bloque. */
[data-theme="dark"] .sobre-foto {
  box-shadow:
    0 32px 70px -28px rgba(0, 0, 0, 0.65),
    0 14px 28px -16px rgba(0, 0, 0, 0.45);
}
[data-theme="dark"] .sobre-foto::after {
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0)    50%,
    rgba(0, 0, 0, 0.28) 100%
  );
}

.stats {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 3vw, 48px);
  margin-top: clamp(56px, 8vw, 112px);
  padding-top: 56px;
  border-top: 1px solid var(--line);
}

.stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  position: relative;
}

.stat:not(:last-child)::after {
  content: '';
  position: absolute;
  right: -1.5vw;
  top: 8px;
  bottom: 8px;
  width: 1px;
  background: var(--line);
}

.stat-numero {
  font-family: var(--font-serif);
  font-weight: 400;
  font-style: italic;
  font-size: clamp(3rem, 6vw, 5.5rem);
  line-height: 0.9;
  color: var(--ink);
}

.stat-label {
  font-size: 13px;
  color: var(--muted);
  letter-spacing: 0.02em;
}

/* =========================================
   Servicios + Proyectos (mismo patrón de fila)
   ========================================= */
.servicios h2,
.proyectos h2 { margin-bottom: 64px; }

.servicios-list,
.proyectos-list {
  border-top: 1px solid var(--line);
}

/* Filas (servicios usa <button>, proyectos <div>; ambos comparten estilos) */
.servicio-row,
.proyecto-row {
  display: grid;
  grid-template-columns: 80px minmax(180px, 1fr) 2fr auto;
  gap: clamp(20px, 3vw, 48px);
  align-items: center;
  width: 100%;
  text-align: left;
  padding: clamp(24px, 3vw, 40px) 0;
  border-bottom: 1px solid var(--line);
  transition: padding 0.45s cubic-bezier(0.2, 0.8, 0.2, 1), background 0.3s ease;
  cursor: pointer;
  position: relative;
}

.servicio-row:hover,
.servicio-row:focus-visible,
.proyecto-row:hover {
  padding-inline-start: 24px;
  outline: none;
}

.servicio-row::before,
.proyecto-row::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 0;
  height: 1px;
  background: var(--accent);
  transition: width 0.45s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.servicio-row:hover::before,
.servicio-row:focus-visible::before,
.proyecto-row:hover::before {
  width: 16px;
}

.servicio-num,
.proyecto-num {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.5rem, 2.5vw, 2.25rem);
  color: var(--accent);
  line-height: 1;
}

.servicio-row > span:nth-of-type(2),
.proyecto-row > span:nth-of-type(2) {
  font-size: clamp(1.15rem, 1.8vw, 1.625rem);
  font-weight: 500;
  letter-spacing: -0.01em;
}

.servicio-row > span:nth-of-type(3),
.proyecto-row > span:nth-of-type(3) {
  font-size: 0.95rem;
  color: var(--ink-soft);
  line-height: 1.55;
  max-width: 52ch;
}

.badge-wrap {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}

.servicio-badge,
.proyecto-badge {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  color: var(--ink);
  white-space: nowrap;
}

.servicio-year,
.proyecto-year {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.02em;
}

/* =========================================
   Proceso — "Cómo trabajamos"
   ----------------------------------------
   Mobile-first: timeline vertical con rail + círculos numerados.
   Desktop (≥901px): stepper horizontal de 5 columnas con conector.
   La animación de entrada (.is-visible) la dispara IntersectionObserver
   desde script.js, con stagger por índice.
   ========================================= */
.proceso h2 { margin-bottom: 20px; }

.proceso-lead {
  font-size: clamp(1.05rem, 1.5vw, 1.25rem);
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 56ch;
  margin-bottom: clamp(56px, 7vw, 96px);
}

/* ---- Lista de pasos: base mobile (vertical) ---- */
.proceso-steps {
  list-style: none;
  padding: 0;
  margin: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 36px;
}

/* Rail vertical detrás de los círculos.
   Va de un círculo al siguiente — recortado al primer/último centro
   para que no sobresalga. */
.proceso-steps::before {
  content: '';
  position: absolute;
  top: 22px;
  bottom: 22px;
  left: 21px;          /* centro del círculo de 44px */
  width: 1px;
  background: var(--line);
}

.proceso-step {
  position: relative;
  padding-left: 64px;
  /* Estado inicial para animación de scroll (revertido por .is-visible) */
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity .6s ease,
    transform .6s cubic-bezier(.22, 1, .36, 1);
}

.proceso-step.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.proceso-step-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  min-height: 44px;    /* alinea el head al alto del círculo absoluto */
}

/* Círculo numerado: posicionado absoluto sobre el rail.
   En tema oscuro/claro se ve igual gracias a los tokens. */
.proceso-num {
  position: absolute;
  left: 0;
  top: 0;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--line);
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: 1.15rem;
  color: var(--accent);
  line-height: 1;
  z-index: 1;
  transition: border-color .3s ease, transform .3s ease;
}

.proceso-step.is-visible .proceso-num {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--line));
}

/* Pill de duración: mismo lenguaje que .servicio-badge / .proyecto-badge */
.proceso-duracion {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}

.proceso-step-title {
  font-family: var(--font-sans);
  font-size: clamp(1.2rem, 1.8vw, 1.5rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 8px;
  color: var(--ink);
}

.proceso-step-desc {
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 52ch;
}

/* ---- CTA al final de la sección ---- */
.proceso-cta-wrap {
  margin-top: clamp(56px, 7vw, 96px);
  padding-top: clamp(32px, 4vw, 48px);
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: flex-start;
}

/* Hereda .btn-primary; este modificador solo sirve por si en el futuro
   se quiere diferenciar la CTA de la del hero. */
.proceso-cta { gap: 12px; }

/* ---- Desktop: stepper horizontal de 5 columnas ----
   Cambia el eje de flex y reposiciona el rail como línea horizontal. */
@media (min-width: 901px) {
  .proceso-steps {
    flex-direction: row;
    align-items: flex-start;
    gap: clamp(16px, 2vw, 32px);
  }

  /* Línea horizontal entre los centros del primer y último círculo.
     Con 5 columnas equidistantes (flex:1), los centros caen a 10% y 90%. */
  .proceso-steps::before {
    top: 22px;
    bottom: auto;
    left: 10%;
    right: 10%;
    width: auto;
    height: 1px;
  }

  .proceso-step {
    flex: 1;
    min-width: 0;
    padding-left: 0;
    padding-top: 64px;
    text-align: center;
  }

  .proceso-num {
    left: 50%;
    transform: translate(-50%, 0);
  }

  /* Mantener el círculo centrado al animar — el translateY del estado
     inicial vive en .proceso-step, no en el círculo. */
  .proceso-step.is-visible .proceso-num {
    transform: translate(-50%, 0);
  }

  .proceso-step-head {
    flex-direction: column;
    gap: 14px;
    align-items: center;
    min-height: 0;
    margin-bottom: 16px;
  }

  /* En desktop la duración queda debajo del círculo, antes del título.
     Reordeno con order para no tocar el HTML. */
  .proceso-num      { order: 1; }
  .proceso-duracion { order: 2; }

  .proceso-step-desc {
    margin-inline: auto;
  }

  .proceso-cta-wrap {
    justify-content: center;
  }
}

/* Accesibilidad: usuarios con prefers-reduced-motion ven la sección
   ya "visible" sin animación. */
@media (prefers-reduced-motion: reduce) {
  .proceso-step {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* =========================================
   Contacto
   ========================================= */
.contacto {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* Gap más generoso entre columnas: ahora ambas viven sobre el mismo fondo,
     necesitan respiración para no leerse como un único bloque. */
  gap: clamp(56px, 8vw, 120px);
  align-items: start;
}

.contacto .left {
  display: flex;
  flex-direction: column;
  gap: 56px;
  position: sticky;
  top: 100px;
}

.left-title {
  font-family: var(--font-serif);
  font-size: clamp(2.25rem, 4.5vw, 4rem);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin-bottom: 28px;
}

.left-title em {
  color: var(--accent);
  font-weight: 400;
}

.left-desc {
  font-size: 1rem;
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: 42ch;
}

/* Lista de links de contacto */
.contact-links {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--line);
}

.contact-link {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 22px 0;
  border-bottom: 1px solid var(--line);
  font-size: clamp(1rem, 1.4vw, 1.2rem);
  font-weight: 500;
  color: var(--ink);
  transition: padding 0.3s ease, color 0.3s ease;
}

.contact-link:hover {
  padding-inline-start: 12px;
  color: var(--accent);
}

.contact-link-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--line);
  border-radius: 50%;
  flex-shrink: 0;
  transition: background 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}

.contact-link:hover .contact-link-icon {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}

.contact-link-icon svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Columna derecha — formulario editorial.
   Sin caja, sin border-radius, sin background propio: vive directamente
   sobre el fondo del sitio, igual que la columna izquierda. */
.contacto .right {
  display: flex;
  flex-direction: column;
  gap: clamp(40px, 4.5vw, 56px);
}

/* Header del form: "Escribime" + "Disponible ahora".
   Sin línea inferior — la jerarquía ahora viene del tracking y del color,
   no de cajas o separadores. */
.form-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
}

/* "ESCRIBIME": sub-label, claramente subordinado al "04 — Contacto" de la izquierda. */
.form-header .label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Status: detalle a la derecha, no compite visualmente con el label. */
.status-dot {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.status-dot::before {
  content: '';
  width: 7px;
  height: 7px;
  background: var(--green);
  border-radius: 50%;
  box-shadow: 0 0 0 3px rgba(22, 176, 85, 0.18);
}

#form-wrap {
  display: flex;
  flex-direction: column;
  gap: clamp(32px, 4vw, 48px);
}

.selector-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 16px;
}

.service-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* Pills: tipográficos, no botones de UI genérica.
   Borde fino del color del texto, fondo transparente. */
.pill {
  padding: 8px 16px;
  background: transparent;
  border: 1px solid var(--ink);
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink);
  transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease, transform 0.2s ease;
}

/* Hover suave: fondo violeta translúcido, borde y texto en accent. */
.pill:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-color: var(--accent);
  color: var(--accent);
}

.pill:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Estado activo: inversión completa, sigue funcionando en ambos temas. */
.pill.is-active {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}

.pill:active { transform: scale(0.96); }

/* Form fields: grid 2-col en desktop, full-width los .full. */
.fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* Aire vertical generoso (32-40px) para que respire como el resto del sitio. */
  gap: clamp(32px, 3.5vw, 40px) clamp(20px, 2vw, 28px);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.field.full { grid-column: 1 / -1; }

/* Labels en mayúsculas pequeñas, mismo lenguaje que el selector-label
   y la "ESCRIBIME": coherencia total. */
.field label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Inputs minimal-editorial: solo línea inferior, sin fondo. */
.field input,
.field textarea {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--ink);
  padding: 12px 0;
  font: inherit;
  font-size: clamp(16px, 1.2vw, 17px);
  color: var(--ink);
  transition: border-color 0.2s ease;
  font-family: inherit;
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--muted);
  opacity: 0.75;
}

.field input:focus,
.field textarea:focus {
  outline: none;
  border-bottom-color: var(--accent);
}

.field textarea {
  /* Textarea con el mismo lenguaje: solo línea inferior, sin resize visible. */
  resize: none;
  min-height: 120px;
  line-height: 1.5;
}

.form-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
  margin-top: clamp(16px, 2vw, 24px);
}

.form-note {
  font-size: 12px;
  line-height: 1.55;
  color: var(--muted);
  max-width: 28ch;
}

.btn-submit {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 28px;
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius-pill);
  font-size: 14px;
  font-weight: 500;
  transition: transform 0.2s ease, background 0.2s ease;
}

.btn-submit:hover {
  background: var(--accent);
  transform: translateY(-1px);
}

.btn-submit svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Mensaje de éxito del form — oculto por defecto.
   JS le agrega .is-visible al enviar y lo quita a los 4s. */
.success-msg {
  display: none;
  text-align: center;
  padding: 24px 0;
  animation: success-in 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.success-msg.is-visible { display: block; }

.success-msg .check {
  width: 48px;
  height: 48px;
  margin: 0 auto 16px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.success-msg .check svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.success-msg h3 {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: 1.5rem;
  margin-bottom: 8px;
}

.success-msg p {
  font-size: 13px;
  color: var(--muted);
}

@keyframes success-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* =========================================
   Footer (estilo editorial · fondo cálido oscuro)
   -----------------------------------------
   Paleta local: marrón profundo + crema + naranja-coral accent.
   Tokens declarados en .site-footer para no afectar al resto del site.
   Estructura:
   1) footer-main   → 5 columnas (marca, explorar, horarios, contacto, ubicación)
   2) footer-bottom → copyright + legal + status
   ========================================= */
.site-footer {
  --f-bg:       #0E1838;
  --f-bg-deep:  #08102A;
  --f-text:     #F2EEE3;
  --f-text-soft: rgba(242, 238, 227, 0.72);
  --f-muted:    rgba(242, 238, 227, 0.45);
  --f-line:     rgba(242, 238, 227, 0.09);
  --f-accent:   #6C8AFF;

  background: var(--f-bg);
  color: var(--f-text);
  border-top: 0;
  padding: 0;
  position: relative;
}

/* ---------- 1. Grid principal ---------- */
.footer-main {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1.1fr 1.1fr 1fr;
  gap: 48px clamp(24px, 3vw, 56px);
  padding: 88px clamp(24px, 5vw, 80px) 72px;
}

.footer-col { min-width: 0; }

/* ----- Columna de marca ----- */
.footer-col--brand { max-width: 340px; }

.footer-logo {
  display: inline-block;
  margin-bottom: 24px;
}

.footer-logo-name {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(28px, 2.6vw, 36px);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--f-text);
}

/* El punto actúa como "period" del nombre — se ancla al baseline
   para que parezca un punto tipográfico final, no un bullet flotante. */
.footer-logo-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--f-accent);
  vertical-align: baseline;
  margin-left: 3px;
}

.footer-tagline {
  font-size: 14px;
  line-height: 1.65;
  color: var(--f-text-soft);
  margin-bottom: 32px;
}

/* ----- Redes sociales ----- */
.footer-socials {
  display: flex;
  gap: 8px;
}

.footer-socials a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--f-line);
  color: var(--f-text);
  transition: background 0.25s ease, border-color 0.25s ease,
              color 0.25s ease, transform 0.25s ease;
}

.footer-socials a svg { width: 16px; height: 16px; }

.footer-socials a:hover {
  background: var(--f-accent);
  border-color: var(--f-accent);
  color: var(--f-bg);
  transform: translateY(-2px);
}

/* ----- Columnas de texto ----- */
.footer-col-title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--f-accent);
  margin-bottom: 26px;
}

.footer-list {
  display: flex;
  flex-direction: column;
  gap: 13px;
}

.footer-list li {
  font-size: 14px;
  line-height: 1.45;
  color: var(--f-text-soft);
}

.footer-list a {
  color: var(--f-text-soft);
  transition: color 0.2s ease;
}

.footer-list a:hover { color: var(--f-text); }

/* Último ítem destacado (en accent). Estilo del shot: separación visual
   con un poco de margin-top y color accent en lugar del soft. */
.footer-list .is-accent {
  margin-top: 6px;
}

.footer-list .is-accent,
.footer-list .is-accent a {
  color: var(--f-accent);
  font-weight: 500;
}

.footer-list .is-accent a:hover {
  color: var(--f-text);
}

/* ---------- 2. Barra inferior ---------- */
.footer-bottom {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  padding: 22px clamp(24px, 5vw, 80px);
  border-top: 1px solid var(--f-line);
  background: var(--f-bg-deep);
}

.footer-copy {
  font-size: 12px;
  color: var(--f-muted);
  letter-spacing: 0.02em;
}

.footer-copy strong {
  font-weight: 600;
  color: var(--f-text-soft);
}

.footer-legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 6px;
}

.footer-legal li { display: inline-flex; align-items: center; }

.footer-legal li + li::before {
  content: '·';
  margin-right: 6px;
  color: var(--f-muted);
}

.footer-legal button {
  font-size: 12px;
  color: var(--f-text-soft);
  padding: 4px 2px;
  letter-spacing: 0.01em;
  transition: color 0.2s ease;
}

.footer-legal button:hover {
  color: var(--f-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.footer-meta {
  display: flex;
  justify-content: flex-end;
}

.footer-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--f-text-soft);
  letter-spacing: 0.02em;
}

.footer-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 3px rgba(22, 176, 85, 0.22);
  animation: footer-pulse 2.4s ease-in-out infinite;
}

@keyframes footer-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(22, 176, 85, 0.22); }
  50%      { box-shadow: 0 0 0 6px rgba(22, 176, 85, 0.06); }
}

/* =========================================
   Modales de servicios
   ---------------------------------------------------------
   Estados: [hidden] = display:none. .is-open = opacity 1 + scale 1.
   El JS togglea .is-open con doble rAF tras quitar [hidden] para que
   la transición se dispare correctamente.
   ========================================================= */
.modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.modal[hidden] { display: none; }

.modal.is-open {
  opacity: 1;
  pointer-events: auto;
}

.modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(14, 14, 16, 0.45);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  cursor: pointer;
}

.modal__panel {
  position: relative;
  max-width: 760px;
  width: 100%;
  max-height: calc(100vh - 48px);
  background: var(--bg);
  border-radius: 24px;
  border: 1px solid var(--line);
  padding: clamp(32px, 4.5vw, 64px);
  overflow-y: auto;
  transform: scale(0.96) translateY(20px);
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
  outline: none;
}

.modal.is-open .modal__panel {
  transform: scale(1) translateY(0);
}

.modal__close {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  color: var(--ink);
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.modal__close:hover,
.modal__close:focus-visible {
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
  outline: none;
  transform: rotate(90deg);
}

.modal__close svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.modal__header {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 20px;
  padding-bottom: 28px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 40px;
}

.modal__num {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(2.5rem, 5vw, 4rem);
  color: var(--accent);
  line-height: 1;
}

.modal__title {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.6vw, 2.25rem);
  letter-spacing: -0.01em;
  line-height: 1.1;
  margin: 0;
  max-width: none;
}

.modal__tag {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  align-self: start;
  margin-top: 6px;
}

.modal__price {
  margin-bottom: 40px;
}

.modal__price-from {
  display: block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 12px;
}

.modal__price-amount {
  display: block;
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(72px, 11vw, 120px);
  line-height: 0.9;
  letter-spacing: -0.02em;
  color: var(--accent);
}

.modal__desc {
  font-size: clamp(1rem, 1.2vw, 1.125rem);
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: 60ch;
  margin-bottom: 48px;
}

.modal__included {
  margin-bottom: 48px;
}

.modal__included-title {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 24px;
}

.modal__included-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 32px;
}

.modal__included-list li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--ink);
}

.modal__check {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 2px;
}

.modal__check svg {
  width: 12px;
  height: 12px;
  stroke: currentColor;
  stroke-width: 3;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.modal__actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  padding-top: 32px;
  border-top: 1px solid var(--line);
}

.modal__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 24px;
  border-radius: var(--radius-pill);
  font-size: 14px;
  font-weight: 500;
  transition: transform 0.2s ease, background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.modal__cta--primary {
  background: var(--ink);
  color: #fff;
  flex: 1;
  min-width: 220px;
}

.modal__cta--primary:hover,
.modal__cta--primary:focus-visible {
  background: var(--accent);
  transform: translateY(-1px);
  outline: none;
}

.modal__cta--secondary {
  border: 1px solid var(--line);
  color: var(--ink);
}

.modal__cta--secondary:hover,
.modal__cta--secondary:focus-visible {
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
  outline: none;
}

.modal__cta svg {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- Variante: modales legales ----------
   Layout más denso: cuerpo de texto con headings + párrafos, sin precio
   ni grid de incluidos. Numerador "§" en lugar de "01/02...".
   ----------------------------------------------- */
.modal--legal .modal__panel {
  max-width: 720px;
}

.modal--legal .modal__num {
  font-style: normal;
  font-size: clamp(2rem, 4vw, 3rem);
  color: var(--accent);
  opacity: 0.7;
}

.modal--legal .modal__header {
  margin-bottom: 16px;
}

.modal__legal-meta {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 28px;
}

.modal__legal-body {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-bottom: 36px;
  max-height: 50vh;
  overflow-y: auto;
  padding-right: 8px;

  /* Scrollbar discreta */
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

.modal__legal-body::-webkit-scrollbar { width: 6px; }
.modal__legal-body::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: 999px;
}

.modal__legal-body h3 {
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink);
  margin-top: 8px;
}

.modal__legal-body h3:first-child { margin-top: 0; }

.modal__legal-body p,
.modal__legal-body ul {
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink-soft);
}

.modal__legal-body ul {
  list-style: disc;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.modal__legal-body a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

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

@media (prefers-reduced-motion: reduce) {
  .modal, .modal__panel, .modal__close, .modal__cta { transition: none; }
  .footer-status-dot { animation: none; }
}

/* =========================================
   Responsive
   ========================================= */
@media (max-width: 900px) {
  /* En mobile volvemos a flex con wrap: el nav baja a una fila completa
     debajo de la marca y el cluster de acciones. */
  .topbar {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    padding: 16px 24px;
    gap: 12px;
  }
  /* Mostrar el botón hamburguesa. */
  .nav-toggle { display: inline-flex; }

  /* El nav pasa a ser un drawer deslizante desde la derecha.
     Cerrado: fuera de pantalla (translateX 100%) e inerte.
     Abierto (.is-open): entra a la vista. */
  .topnav {
    position: fixed;
    top: 0;
    right: 0;
    z-index: 95;                        /* sobre el backdrop (90), bajo el topbar (100) */
    flex-direction: column;
    justify-content: flex-start;
    gap: 4px;
    width: min(80vw, 320px);
    height: 100vh;
    height: 100dvh;                     /* respeta la barra del navegador móvil */
    padding: 88px 24px 32px;            /* deja aire bajo el topbar fijo */
    background: var(--bg);
    border-left: 1px solid var(--line);
    box-shadow: -20px 0 60px -30px rgba(0, 0, 0, 0.5);
    transform: translateX(100%);
    transition: transform .35s cubic-bezier(.22, 1, .36, 1);
    overflow-y: auto;
  }

  .topnav.is-open { transform: translateX(0); }

  /* Cada enlace ocupa toda la fila con un área táctil cómoda (≥44px). */
  .topnav a {
    display: flex;
    align-items: center;
    min-height: 52px;
    padding: 0 12px;
    font-size: 1.05rem;
    border-bottom: 1px solid var(--line);
  }
  .topnav a:last-child { border-bottom: 0; }

  .hero { padding: 32px 24px 28px; }

  /* Bridge: servicios en columna, sin separadores. */
  .bridge__services { flex-direction: column; gap: 8px; }
  .bridge__services li { padding: 0; }
  .bridge__services li:not(:last-child)::after { display: none; }
  .hero-meta { flex-wrap: wrap; gap: 10px 24px; padding-bottom: 36px; }
  .hero-title { font-size: clamp(44px, 13vw, 120px); margin-bottom: 56px; }
  /* En móvil dejamos que el título fluya a varias líneas: "Web Development"
     no entra en una sola línea en pantallas angostas y con nowrap se cortaba. */
  .hero-title-line { white-space: normal; }
  .hero-bottom { flex-direction: column; align-items: flex-start; }
  .hero-vertical { display: none; }

  /* Sobre mí */
  .sobre-mi { grid-template-columns: 1fr; }
  /* Foto centrada y con ancho razonable: no full-width agresivo. */
  .sobre-foto { max-width: min(420px, 80%); margin-inline: auto; }
  .stats { grid-template-columns: 1fr; gap: 32px; }
  .stat:not(:last-child)::after { display: none; }

  /* Servicios + Proyectos */
  .servicio-row,
  .proyecto-row {
    grid-template-columns: 50px 1fr;
    grid-template-areas:
      "num title"
      ".   desc"
      ".   badge";
    gap: 12px;
    padding: 28px 0;
  }
  .servicio-row > .servicio-num,
  .proyecto-row > .proyecto-num { grid-area: num; }
  .servicio-row > span:nth-of-type(2),
  .proyecto-row > span:nth-of-type(2) { grid-area: title; }
  .servicio-row > span:nth-of-type(3),
  .proyecto-row > span:nth-of-type(3) { grid-area: desc; }
  .badge-wrap {
    grid-area: badge;
    flex-direction: row;
    align-items: center;
  }

  /* Contacto */
  .contacto { grid-template-columns: 1fr; }
  .contacto .left { position: static; gap: 40px; }
  .fields { grid-template-columns: 1fr; }
  .form-footer { flex-direction: column; align-items: stretch; }
  .btn-submit { justify-content: center; }

  /* Footer */
  .footer-main {
    grid-template-columns: 1fr 1fr;
    gap: 40px 32px;
    padding: 64px 28px 56px;
  }
  .footer-col--brand {
    grid-column: 1 / -1;
    max-width: 540px;
  }
  .footer-bottom {
    grid-template-columns: 1fr;
    text-align: center;
    gap: 14px;
    padding: 24px 28px 28px;
  }
  .footer-legal { justify-content: center; }
  .footer-meta { justify-content: center; }

  /* Modales legales en mobile */
  .modal--legal .modal__num { font-size: 2rem; }
  .modal__legal-body { max-height: none; }

  /* Modal full-screen en mobile */
  .modal { padding: 0; align-items: stretch; }
  .modal__panel {
    max-width: 100%;
    max-height: 100vh;
    min-height: 100vh;
    border-radius: 0;
    border: 0;
    padding: 24px 20px 32px;
  }
  .modal__header {
    grid-template-columns: auto 1fr;
    grid-template-areas:
      "num title"
      "tag tag";
    gap: 14px;
  }
  .modal__num { grid-area: num; }
  .modal__title { grid-area: title; }
  .modal__tag { grid-area: tag; justify-self: start; }
  .modal__included-list { grid-template-columns: 1fr; }
  .modal__actions { flex-direction: column-reverse; }
  .modal__cta--primary,
  .modal__cta--secondary { width: 100%; }
}

@media (max-width: 560px) {
  /* El nav NO se oculta: sigue siendo el drawer accesible vía hamburguesa.
     (Antes hacía display:none y dejaba el teléfono sin navegación.) */
  .hero-title { font-size: clamp(38px, 13vw, 80px); }

  /* Footer mobile cerrado */
  .footer-main { grid-template-columns: 1fr; padding: 56px 24px 44px; gap: 36px; }
  .footer-col--brand { max-width: 100%; }
  .footer-logo-name { font-size: 28px; }
}

/* =========================================
   Botón flotante de WhatsApp
   ========================================= */
.wa-float {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 1000;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;

  background: linear-gradient(135deg, #25D366 0%, #128C7E 100%);
  color: #fff;

  box-shadow:
    0 10px 24px rgba(18, 140, 126, 0.35),
    0 4px 10px rgba(0, 0, 0, 0.12);

  transition:
    transform .35s cubic-bezier(.22, 1, .36, 1),
    box-shadow .35s ease;

  /* Animación de entrada */
  animation: wa-enter .7s cubic-bezier(.22, 1, .36, 1) .4s both;
}

.wa-float:hover,
.wa-float:focus-visible {
  transform: translateY(-3px) scale(1.08);
  box-shadow:
    0 16px 36px rgba(18, 140, 126, 0.45),
    0 6px 14px rgba(0, 0, 0, 0.15),
    0 0 0 6px rgba(37, 211, 102, 0.18);
  outline: none;
}

.wa-float:active { transform: translateY(-1px) scale(1.03); }

/* Logo */
.wa-float__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.25));
}

.wa-float__icon svg {
  width: 100%;
  height: 100%;
  fill: #fff;
}

/* Tooltip elegante */
.wa-float__tooltip {
  position: absolute;
  right: calc(100% + 14px);
  top: 50%;
  transform: translateY(-50%) translateX(8px);

  white-space: nowrap;
  padding: 10px 14px;
  border-radius: 10px;

  background: #0E0E10;
  color: #F2EEE3;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .01em;

  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.18);
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s ease, transform .25s ease;
}

.wa-float__tooltip::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -5px;
  width: 10px;
  height: 10px;
  background: #0E0E10;
  transform: translateY(-50%) rotate(45deg);
  border-radius: 2px;
}

.wa-float:hover .wa-float__tooltip,
.wa-float:focus-visible .wa-float__tooltip {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

@keyframes wa-enter {
  0%   { opacity: 0; transform: translateY(24px) scale(.6); }
  60%  { opacity: 1; transform: translateY(-4px) scale(1.05); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* Respetar usuarios que prefieren menos movimiento */
@media (prefers-reduced-motion: reduce) {
  .wa-float { animation: none; }
  .wa-float,
  .wa-float__tooltip { transition: none; }
}

/* Mobile: ligeramente más chico y un poco más cerca del borde */
@media (max-width: 560px) {
  .wa-float {
    width: 56px;
    height: 56px;
    right: 18px;
    bottom: 18px;
  }
  .wa-float__icon { width: 30px; height: 30px; }
  /* En mobile el tooltip puede chocar con el borde — lo ocultamos */
  .wa-float__tooltip { display: none; }
}

/* =========================================
   Theme toggle (claro/oscuro)
   ----------------------------------------
   Botón circular minimalista. Apila dos iconos
   (sol y luna) y los intercambia con opacidad +
   rotación + escala para una transición suave.
   ========================================= */
.theme-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  flex-shrink: 0;
  transition:
    background-color .25s ease,
    border-color .25s ease,
    color .25s ease,
    transform .25s ease;
}

.theme-toggle:hover {
  background: var(--bg-deep);
  transform: translateY(-1px);
}

.theme-toggle:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(var(--bg-rgb), 0.0), 0 0 0 2px var(--accent);
}

.theme-toggle__icon {
  position: absolute;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition:
    opacity .4s ease,
    transform .5s cubic-bezier(.22, 1, .36, 1);
}

/* Estado por defecto (tema claro): muestra SOL, oculta LUNA */
.theme-toggle__icon--sun  { opacity: 1; transform: rotate(0)      scale(1); }
.theme-toggle__icon--moon { opacity: 0; transform: rotate(-90deg) scale(.4); }

/* Tema oscuro: oculta SOL, muestra LUNA */
[data-theme="dark"] .theme-toggle__icon--sun  { opacity: 0; transform: rotate(90deg) scale(.4); }
[data-theme="dark"] .theme-toggle__icon--moon { opacity: 1; transform: rotate(0)     scale(1);  }

/* La luna se rellena en dark para verse más nítida */
[data-theme="dark"] .theme-toggle__icon--moon { fill: currentColor; }

/* =========================================
   Overrides específicos del tema OSCURO
   ----------------------------------------
   La mayoría del diseño hereda los tokens y se
   adapta solo. Estos son los pocos casos donde
   un color hardcoded ('color: #fff' sobre un
   fondo que ahora es claro) hay que invertir.
   ========================================= */
[data-theme="dark"] .btn-primary,
[data-theme="dark"] .btn-submit,
[data-theme="dark"] .pill.is-active,
[data-theme="dark"] .modal__close:hover,
[data-theme="dark"] .modal__close:focus-visible,
[data-theme="dark"] .modal__cta--primary,
[data-theme="dark"] .modal__cta--secondary:hover,
[data-theme="dark"] .modal__cta--secondary:focus-visible {
  color: var(--bg);
}

/* El video del hero en oscuro: lo atenuamos para integrar mejor. */
[data-theme="dark"] .site-header-bg { opacity: 0.55; }

/* Responsive: en mobile el toggle queda alineado con el lang-toggle.
   El topbar ya tiene flex-wrap, así que no hay que ajustar más. */
/* En móvil/táctil agrandamos las áreas táctiles a ≥44px (accesibilidad).
   El ícono se mantiene del mismo tamaño visual; crece solo la zona tocable. */
@media (max-width: 900px) {
  .theme-toggle { width: 44px; height: 44px; }
  .lang-toggle { padding: 7px 16px; min-height: 44px; }
  .lang-btn { min-width: 32px; min-height: 32px; }
}

/* =========================================
   Animaciones de entrada (scroll-reveal)
   ----------------------------------------
   Sistema declarativo: cualquier elemento con [data-reveal] arranca
   oculto (opacity 0 + transform) y se revela cuando entra al viewport.
   El IntersectionObserver de script.js le agrega .is-revealed.

   Variantes por valor del atributo:
     data-reveal           -> sube desde abajo (fade-in-up)   [default]
     data-reveal="left"    -> entra desde la izquierda
     data-reveal="right"   -> entra desde la derecha
     data-reveal="scale"   -> aparece con un leve zoom

   Solo animamos opacity y transform (no fuerzan re-layout → 60fps).
   El stagger entre hermanos lo calcula el JS vía data-reveal-group.
   ========================================= */
[data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity .6s ease-out,
    transform .7s cubic-bezier(.22, 1, .36, 1);
}

[data-reveal="left"]  { transform: translateX(-44px); }
[data-reveal="right"] { transform: translateX(44px); }
[data-reveal="scale"] { transform: scale(0.96); }

[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

/* ---- Entrada del hero al cargar (no depende de scroll ni de JS) ----
   Si el JS fallara, el contenido igual queda visible al terminar la animación. */
@keyframes hero-fade-up {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}

.hero-meta   { animation: hero-fade-up .7s ease-out both; }
.hero-title  { animation: hero-fade-up .8s ease-out .08s both; }
.hero-bottom { animation: hero-fade-up .8s ease-out .18s both; }

/* =========================================
   Mejoras de hover (sutiles, suaves)
   ----------------------------------------
   Solo opacity/transform/box-shadow. Escala máx. ~1.03.
   ========================================= */
/* Botones principales: leve elevación + escala + sombra suave. */
.btn-primary,
.btn-submit,
.modal__cta--primary {
  transition:
    transform .3s ease,
    background .25s ease,
    box-shadow .3s ease;
}

.btn-primary:hover,
.btn-submit:hover,
.proceso-cta:hover,
.modal__cta--primary:hover {
  transform: translateY(-2px) scale(1.02);
  box-shadow: 0 12px 26px -12px rgba(0, 0, 0, 0.4);
}

/* Foto editorial de "Sobre nosotros": flota suavemente al hover.
   La transición ya estaba declarada en .sobre-foto. */
.sobre-foto:hover {
  transform: translateY(-6px) scale(1.01);
  box-shadow:
    0 40px 80px -28px rgba(0, 0, 0, 0.4),
    0 18px 34px -16px rgba(0, 0, 0, 0.22);
}

/* Filas de servicios/proyectos: tinte de fondo muy sutil al hover,
   acompañando al desplazamiento de padding y la línea de acento ya existentes. */
.servicio-row:hover,
.proyecto-row:hover {
  background: color-mix(in srgb, var(--accent) 4%, transparent);
}

/* =========================================
   Accesibilidad: desactivar movimiento
   ----------------------------------------
   Anula reveals, entrada del hero y los desplazamientos de hover
   para usuarios con prefers-reduced-motion.
   ========================================= */
@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .hero-meta,
  .hero-title,
  .hero-bottom { animation: none !important; }

  .btn-primary:hover,
  .btn-submit:hover,
  .proceso-cta:hover,
  .modal__cta--primary:hover,
  .sobre-foto:hover { transform: none; }
}

/* =========================================
   Proyectos — tarjetas con screenshot
   ----------------------------------------
   Reemplaza la lista de filas por un grid de tarjetas: imagen arriba,
   título + descripción + stack en badges + link a la demo.
   Usa los tokens del sitio (se adapta a claro/oscuro solo).
   ========================================= */
.proyectos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: clamp(20px, 3vw, 32px);
}

.proyecto-card {
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 18px 40px -28px rgba(0, 0, 0, 0.35);
  /* Esta transición cubre tanto el hover como la animación de scroll-reveal. */
  transition:
    transform .4s cubic-bezier(.22, 1, .36, 1),
    box-shadow .4s ease,
    opacity .6s ease-out;
}

.proyecto-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.45);
}

[data-theme="dark"] .proyecto-card {
  box-shadow: 0 22px 46px -28px rgba(0, 0, 0, 0.7);
}

/* Screenshot: ratio fijo para que todas las tarjetas queden parejas. */
.proyecto-card__media {
  display: block;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--bg-deep);
}

.proyecto-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .5s cubic-bezier(.22, 1, .36, 1);
}

.proyecto-card:hover .proyecto-card__media img { transform: scale(1.04); }

.proyecto-card__body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: clamp(20px, 2.5vw, 28px);
  flex: 1;
}

.proyecto-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}

.proyecto-card__title {
  font-family: var(--font-sans);
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}

.proyecto-card__year {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

.proyecto-card__desc {
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.proyecto-card__stack {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Link "Ver demo": empujado al fondo de la tarjeta para alinear todas. */
.proyecto-card__demo {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 8px;
  padding: 11px 20px;
  background: var(--ink);
  color: var(--bg);
  border-radius: var(--radius-pill);
  font-size: 0.9rem;
  font-weight: 600;
  transition: transform .3s ease, background .25s ease;
}

.proyecto-card__demo:hover {
  background: var(--accent);
  color: #fff;
  transform: scale(1.03);
}

.proyecto-card__demo svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (prefers-reduced-motion: reduce) {
  .proyecto-card,
  .proyecto-card__media img,
  .proyecto-card__demo { transition: none; }
  .proyecto-card:hover { transform: none; }
  .proyecto-card:hover .proyecto-card__media img { transform: none; }
  .proyecto-card__demo:hover { transform: none; }
}
