/* Borabe — hero-v2 (última edición: 2026-05-04) */
:root {
  color-scheme: light;

  /* Paleta mayo 2026: SIN beige. Base blanco frío azulado + azul rey/celeste.
     Inks y líneas con tinte azul (chroma bajo), no cálido. */
  --bg: #f2f4fa;
  --bg-deep: #e6ebf6;
  --paper: rgba(248, 250, 255, 0.8);
  --paper-strong: rgba(248, 250, 255, 0.94);
  --ink: #0e1220;
  --ink-soft: #565d72;
  --ink-faint: rgba(14, 18, 32, 0.5);
  --line: rgba(14, 18, 32, 0.1);
  --line-strong: rgba(14, 18, 32, 0.18);
  --accent: #bcc6d6;
  --accent-deep: #5B9BE8;   /* celeste — énfasis sobre navy */
  --royal: #2a52ad;          /* azul rey (tomado del fondo de Identidad) — énfasis sobre claro */
  --shadow-soft: 0 22px 50px -32px rgba(14, 18, 40, 0.18);
  --shadow-strong: 0 34px 90px -44px rgba(14, 18, 40, 0.26);

  /* Pivot tipográfico (abr 2026): familia única "Switzer" — Fontshare.
     Los tres tokens apuntan a la misma familia; los acentos editoriales
     usan italic o letter-spacing, no cambio de familia. */
  --font-sans: "Switzer", system-ui, sans-serif;
  --font-serif: "Switzer", system-ui, sans-serif;
  --font-mono: "Switzer", system-ui, sans-serif;

  --max: 1320px;
  --pad: clamp(20px, 4vw, 48px);
  --space: clamp(40px, 5vw, 72px);
  --radius-sm: 16px;
  --radius-md: 28px;
  --radius-lg: 40px;
  --radius-pill: 999px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* Reservar espacio del scrollbar SIEMPRE — evita que elementos fixed (slide
     del estudio) y elementos static (signature post-swap) tengan anchos
     distintos. Sin esto, el contenido centrado se "shifta" ~8px al swap. */
  scrollbar-gutter: stable;
  /* Cualquier anclaje (#servicios, #estudio, etc.) deja aire arriba para
     el topbar — el título nunca queda pegado al techo del viewport. */
  scroll-padding-top: 110px;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-sans);
  font-weight: 500;
  color: var(--ink);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background:
    radial-gradient(circle at 14% 16%, rgba(188, 198, 214, 0.26), transparent 26%),
    radial-gradient(circle at 82% 14%, rgba(255, 255, 255, 0.7), transparent 20%),
    linear-gradient(180deg, #faf8f3 0%, var(--bg) 44%, var(--bg-deep) 100%);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

/* Cursor personalizado — círculo que sigue al puntero (js/cursor.js).
   El cursor nativo se oculta solo cuando el JS está activo. Sobre zonas
   oscuras marcadas con data-cursor="light" el círculo se vuelve beige. */
.has-custom-cursor,
.has-custom-cursor * {
  cursor: none;
}

.cursor {
  position: fixed;
  left: 0;
  top: 0;
  width: 76px;
  height: 76px;
  margin: -38px 0 0 -38px;
  border-radius: 50%;
  border: 1px solid rgba(18, 18, 20, 0.95);
  background: rgba(18, 18, 20, 0.16);
  pointer-events: none;
  z-index: 9999;
  opacity: 0;
  transition:
    border-color 0.28s ease,
    background-color 0.28s ease,
    width 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    height 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    margin 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.2s ease;
  will-change: transform;
}

.cursor.is-visible {
  opacity: 1;
}

.cursor.is-light {
  border-color: rgba(244, 241, 235, 0.95);
  background: rgba(244, 241, 235, 0.2);
}

/* En zonas marcadas data-cursor="hidden" (Servicios — la órbita YA hace
   de cursor), el círculo nativo se desvanece para no competir. */
.cursor.is-hidden {
  opacity: 0;
}

/* Modo adaptativo (Resultado): mix-blend-mode difference invierte el cursor
   contra lo que tenga detrás → visible sobre el negro de la diagonal Y
   sobre el celeste. Blanco como base porque invertido da oscuro sobre
   claro y claro sobre oscuro. */
.cursor.is-adaptive {
  mix-blend-mode: difference;
  border-color: rgba(255, 255, 255, 0.95);
  background: rgba(255, 255, 255, 0.25);
}

/* Burbuja interna "Visitar": centrada sobre el punto del cursor. Escala con
   transform (GPU) → fluido, sin recalcular layout en cada frame. */
.cursor__ring {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 84px;
  height: 84px;
  margin: -42px 0 0 -42px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.78);
  background: rgba(18, 18, 20, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: scale(0.35);
  transform-origin: center;
  transition:
    transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.3s ease;
  pointer-events: none;
}
.cursor__label {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #f2f4fa;
}

/* Estado "Visitar": el aro base desaparece (solo el punto) y la burbuja
   escala suave a su tamaño. */
.cursor.is-label {
  mix-blend-mode: normal;
  border-color: transparent;
  background: transparent;
}
.cursor.is-label .cursor__ring {
  opacity: 1;
  transform: scale(1);
}

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

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

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

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

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

::selection {
  background: rgba(127, 143, 169, 0.26);
  color: var(--ink);
}

.bg-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

.bg-layer--grain {
  z-index: 0;
  opacity: 0.045;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncA type='table' tableValues='0 0.45'/></feComponentTransfer></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 240px 240px;
}

.bg-layer--halo {
  z-index: 0;
  background:
    radial-gradient(circle at 18% 24%, rgba(255, 255, 255, 0.46), transparent 24%),
    radial-gradient(circle at 78% 32%, rgba(188, 198, 214, 0.22), transparent 26%);
}

.bg-layer--lines {
  z-index: 0;
  opacity: 0.22;
  background-image:
    linear-gradient(to right, rgba(18, 18, 20, 0.035) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(18, 18, 20, 0.035) 1px, transparent 1px);
  background-size: 120px 120px;
  mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.7), transparent 88%);
}

.topbar {
  position: fixed;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  width: min(calc(100% - 20px), 1280px);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 14px 24px 14px 28px;
  border: 1px solid rgba(18, 18, 20, 0.08);
  border-radius: 26px;
  /* Blanco celeste frío — antes era crema cálido, ya no pega con la página */
  background: rgba(248, 250, 253, 0.72);
  backdrop-filter: blur(18px);
  box-shadow: 0 12px 36px -28px rgba(18, 18, 20, 0.18);
  transition:
    top 0.45s var(--ease),
    opacity 0.3s var(--ease),
    background-color 0.35s var(--ease),
    border-color 0.35s var(--ease),
    box-shadow 0.35s var(--ease),
    backdrop-filter 0.35s var(--ease);
}

.topbar__right {
  display: inline-flex;
  align-items: center;
  gap: clamp(18px, 2vw, 32px);
}

/* Estado "naked" — mientras estás en el hero, la barra NO tiene chrome.
   Solo se ven los elementos internos (logo, nav, CTA). */
.topbar--naked {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* Sobre el hero azul rey, los links de nav en --ink-soft (gris tenue)
   casi no se ven. En estado naked los subimos a --ink fuerte, igual que
   el título, para que contrasten contra el azul. */
.topbar--naked .topnav a {
  color: var(--ink);
}

/* Sobre el hero: punto más grande y de azul chillón (eléctrico), con ondas
   tipo eco — anillos de sombra (oscuros, poca opacidad) que salen del círculo
   de forma escalonada. */
.topbar--naked .topbar__link-dot {
  width: 11px;
  height: 11px;
  background: #2f6cf5;
  border: 0.5px solid #000;
  box-shadow: none;
}
/* Dos ondas escalonadas (se leen como olas continuas saliendo del punto). */
.topbar--naked .topbar__link-dot::before,
.topbar--naked .topbar__link-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid rgba(8, 14, 40, 0.38);
  /* Detrás del punto: las ondas salen de atrás, no se meten al círculo. */
  z-index: -1;
  animation: dotRipple 2.8s ease-out infinite;
}
.topbar--naked .topbar__link-dot::after {
  animation-delay: 1.4s;
}
@keyframes dotRipple {
  0% {
    transform: scale(1);
    opacity: 0.45;
  }
  100% {
    transform: scale(3.6);
    opacity: 0;
  }
}

.topbar--hidden {
  top: -100px;
  opacity: 0;
  pointer-events: none;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}

.brand__mark {
  width: 26px;
  height: 26px;
}

.brand__sep {
  display: inline-block;
  width: 1px;
  height: 18px;
  background: var(--ink);
  margin: 0 4px;
}

.brand__word {
  font-size: 1.08rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.brand__mark {
  width: 34px;
  height: 34px;
}

.brand__word {
  font-family: var(--font-serif);
  font-size: 1.8rem;
  line-height: 1;
  letter-spacing: -0.04em;
}

/* Hover de la marca: el isotipo da una vuelta completa (gesto de
   "reiniciar / volver al inicio") y la marca crece un poco. Sin cambio de
   color: en el hero el fondo es azul y un hover azul no se vería. El giro
   es lento (1.1s) y con curva pareja para que se sienta suave. */
.brand {
  transition: transform 0.4s var(--ease);
}

.brand__mark {
  transition: transform 1.1s ease-in-out;
}

.brand:hover {
  transform: scale(1.06);
}

.brand:hover .brand__mark {
  transform: rotate(360deg);
}

.topnav {
  display: flex;
  justify-content: center;
  gap: 0.35rem;
}

.topnav a {
  position: relative;
  padding: 6px 10px;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--ink-soft);
  transition: color 0.22s ease;
}

.topnav a::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 3px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.42s var(--ease);
}

.topnav a:hover {
  color: var(--ink);
}

.topnav a:hover::after {
  transform: scaleX(1);
}

/* CTA del topbar — pill compacto, más chico que el nav, pero resalta
   por fondo dark sólido vs. nav de texto suave. */
.topbar__cta {
  padding: 5px 12px 5px 14px;
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  border-radius: var(--radius-pill);
  gap: 6px;
}

.topbar__cta [aria-hidden="true"] {
  font-size: 0.9em;
}

/* CTA editorial inline — reemplaza el pill negro genérico.
   Estructura: punto + texto + línea-flecha. El texto tiene underline
   animado en hover. Pensado para que el CTA del header se sienta como
   parte del lenguaje editorial, no como botón de e-commerce. */
.topbar__sep {
  width: 1px;
  height: 16px;
  background: rgba(18, 18, 20, 0.5);
  flex-shrink: 0;
}

.topbar__link {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 4px 2px;
  font-family: var(--font-sans);
  font-size: 1.02rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
  position: relative;
  white-space: nowrap;
}

.topbar__link-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--royal);
  box-shadow: 0 0 0 3px rgba(45, 82, 227, 0.14);
  flex-shrink: 0;
  position: relative;
}

/* Pulso muy sutil — recuerda que es un CTA activo sin gritar. */
.topbar__link-dot::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 1px solid rgba(45, 82, 227, 0.45);
  animation: ctaDotPulse 2.6s var(--ease) infinite;
}

@keyframes ctaDotPulse {
  0%, 100% { transform: scale(0.6); opacity: 0; }
  50%      { transform: scale(1.4); opacity: 0.7; }
  80%      { transform: scale(1.8); opacity: 0; }
}

.topbar__link-text {
  position: relative;
  font-weight: 600;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0% 1px;
  background-position: 0 100%;
  transition: background-size 0.42s var(--ease);
}

.topbar__link:hover .topbar__link-text {
  background-size: 100% 1px;
}

.topbar__link-arrow {
  display: inline-flex;
  align-items: center;
  transition: transform 0.32s var(--ease);
}

.topbar__link:hover .topbar__link-arrow {
  transform: translateX(4px);
}

@media (max-width: 720px) {
  .topbar__link-text {
    display: none;
  }
  .topbar__sep {
    display: none;
  }
}

.nav-toggle {
  display: none;
  width: 40px;
  height: 40px;
  padding: 0;
  margin: 0;
  background: transparent;
  border: 1px solid rgba(18, 18, 20, 0.14);
  border-radius: 14px;
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  transition: background-color 0.22s ease, border-color 0.22s ease;
}

.nav-toggle:hover {
  background: rgba(18, 18, 20, 0.05);
}

.nav-toggle__bar {
  display: block;
  width: 16px;
  height: 1.5px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform 0.28s ease, opacity 0.22s ease;
}

body[data-nav-open="true"] .nav-toggle__bar:first-child {
  transform: translateY(3.25px) rotate(45deg);
}

body[data-nav-open="true"] .nav-toggle__bar:last-child {
  transform: translateY(-3.25px) rotate(-45deg);
}

.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 45;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(2rem, 6vw, 3rem);
  padding: 110px clamp(24px, 8vw, 48px) clamp(32px, 8vw, 56px);
  background: rgba(255, 252, 247, 0.94);
  backdrop-filter: blur(22px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.32s ease;
}

.mobile-menu[data-open="true"] {
  opacity: 1;
  pointer-events: auto;
}

.mobile-menu__nav {
  display: flex;
  flex-direction: column;
  gap: clamp(0.5rem, 2vw, 1rem);
}

.mobile-menu__nav a {
  font-family: var(--font-serif);
  font-size: clamp(2.4rem, 10vw, 3.4rem);
  line-height: 1.02;
  letter-spacing: -0.03em;
  color: var(--ink);
  text-decoration: none;
  transform: translateY(14px);
  opacity: 0;
  transition: transform 0.42s ease, opacity 0.42s ease;
}

.mobile-menu[data-open="true"] .mobile-menu__nav a {
  transform: translateY(0);
  opacity: 1;
}

.mobile-menu[data-open="true"] .mobile-menu__nav a:nth-child(1) { transition-delay: 0.08s; }
.mobile-menu[data-open="true"] .mobile-menu__nav a:nth-child(2) { transition-delay: 0.14s; }
.mobile-menu[data-open="true"] .mobile-menu__nav a:nth-child(3) { transition-delay: 0.20s; }
.mobile-menu[data-open="true"] .mobile-menu__nav a:nth-child(4) { transition-delay: 0.26s; }

.mobile-menu__footer {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: flex-start;
}

.mobile-menu__cta {
  align-self: flex-start;
  font-size: 1rem;
}

.mobile-menu__email {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  text-decoration: none;
}

body[data-nav-open="true"] {
  overflow: hidden;
}

.section {
  position: relative;
  z-index: 1;
  max-width: var(--max);
  margin: 0 auto;
  padding: var(--space) var(--pad);
}

.eyebrow,
.section-label {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.eyebrow strong {
  font-family: var(--font-sans);
  font-size: 0.84rem;
  letter-spacing: -0.03em;
  text-transform: none;
  color: var(--ink);
}

.eyebrow__sep {
  width: 22px;
  height: 1px;
  background: var(--line-strong);
}

.section-headline {
  display: grid;
  gap: 0.9rem;
  max-width: 62rem;
  margin-bottom: clamp(1.6rem, 4vw, 3rem);
}

.section-headline h2,
.contact__head h2 {
  margin: 0;
  max-width: 22ch;
  font-size: clamp(2.1rem, 3.6vw, 3.3rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-weight: 600;
  text-wrap: balance;
}
.contact__head h2 {
  margin-inline: auto;
}
.contact__head h2 em {
  font-style: italic;
  font-weight: 600;
  /* énfasis sólo por italic, mismo color que el resto del título */
}

.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.92rem 1.26rem;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  transition: transform 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.cta:hover {
  transform: translateY(-1px);
}

.cta--dark {
  background: var(--ink);
  color: #f7f4ee;
  box-shadow: 0 16px 28px -18px rgba(18, 18, 20, 0.34);
}

.cta--ghost {
  border: 1px solid var(--line-strong);
  background: rgba(255, 252, 247, 0.5);
  color: var(--ink);
}

.cta--light {
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.08);
  color: #f7f4ee;
}

.cta--lg {
  padding: 1rem 1.36rem;
}

/* CTAs FLAT — sin pill, look editorial. Usado en el hero principal. */
.cta-flat {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  font-family: var(--font-sans);
  font-size: 0.92rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-decoration: none;
  border-radius: 4px;
  transition:
    background-color 0.24s var(--ease),
    color 0.24s var(--ease),
    border-color 0.24s var(--ease),
    transform 0.2s var(--ease);
  position: relative;
  white-space: nowrap;
}

.cta-flat:hover {
  transform: translateY(-1px);
}

.cta-flat--primary {
  background: var(--ink);
  color: #f7f4ee;
  border: 1px solid var(--ink);
}
.cta-flat--primary:hover {
  background: transparent;
  color: var(--ink);
}

.cta-flat--ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--ink);
}
.cta-flat--ghost:hover {
  background: var(--ink);
  color: #f7f4ee;
}

.cta-flat > span[aria-hidden="true"] {
  transition: transform 0.24s var(--ease);
}
.cta-flat:hover > span[aria-hidden="true"] {
  transform: translateX(3px);
}

/* Hero v3 — pineado fullscreen. Las secciones siguientes lo cubren al scrollear. */
.hero {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 100vh;
  height: 100dvh;
  z-index: 0;
  display: flex;
  align-items: center;
  padding: 118px var(--pad);
  overflow: hidden;
  isolation: isolate;
}

/* Hero monopo — adaptaci&oacute;n al lenguaje Borabe.
   Modelo: fondo beige (del body) + UNA forma de color con grano coloreado. */
.hero--monopo {
  background: transparent;
}

/* Forma org&aacute;nica de color (SVG fullscreen). El path se morfea en JS.
   Mascarado con bordes difuminados para que se sienta como tinta/acuarela. */
.hero-blob {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  pointer-events: none;
  display: block;
}

/* Forma orgánica unida: SVG dentro de .hero__atmos.
   Una sola masa que fluye desde la esquina inferior izq hacia arriba-der,
   con azul → celeste → beige cálido → vino → coral en su recorrido.
   No abarca toda la pantalla — deja respiración beige en la diagonal opuesta. */
.hero__atmos {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-color: var(--bg, #f2f4fa);
  overflow: hidden;
}
.hero__atmos-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
/* Cinta 3D propia (Three.js) — anclada en la mitad-izquierda del hero,
   sube de la esquina inferior izquierda topando arriba. */
.hero__ribbon3d {
  position: absolute;
  left: -8%;
  bottom: -10%;
  width: 60%;
  height: 130%;
  display: block;
  pointer-events: none;
  background: transparent;
}

/* Grano SVG sutil como capa superior — no anima. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.2;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' seed='7'/><feColorMatrix values='0 0 0 0 0.07 0 0 0 0 0.07 0 0 0 0 0.08 0 0 0 0.9 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 220px 220px;
  mix-blend-mode: multiply;
}

@media (prefers-reduced-motion: reduce) {
  .hero::before { animation: none; }
}

/* Glow fluido del lado derecho del hero: masas suaves de celeste + azul +
   toque ámbar, muy difuminadas, que respiran solas y se desplazan hacia el
   cursor cuando entra al hero (parallax suave). Va sobre el azul rey, debajo
   del texto (z-index:-1, después del blob → encima del blob, detrás del texto). */
.hero__glow {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 64%;
  z-index: -1;
  pointer-events: none;
  --gx: 0.5;
  --gy: 0.5;
  background:
    radial-gradient(38% 48% at calc(72% + (var(--gx) - 0.5) * 12%) calc(40% + (var(--gy) - 0.5) * 16%), rgba(91, 155, 232, 0.6), transparent 60%),
    radial-gradient(32% 42% at calc(88% + (var(--gx) - 0.5) * 9%) calc(66% + (var(--gy) - 0.5) * 12%), rgba(47, 98, 224, 0.5), transparent 62%),
    radial-gradient(24% 28% at 82% 28%, rgba(198, 139, 62, 0.26), transparent 60%);
  filter: blur(34px);
  opacity: 0.5;
  mix-blend-mode: screen;
  transition: opacity 0.6s ease;
  animation: heroGlowDrift 14s ease-in-out infinite;
}
.hero__glow.is-active {
  opacity: 0.95;
}
@keyframes heroGlowDrift {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50% { transform: translate3d(-2%, 2%, 0) scale(1.05); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__glow { animation: none; }
}

.hero__inner {
  max-width: 980px;
  margin: 0 auto;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(16px, 2vw, 26px);
}

.hero__kicker {
  justify-content: center;
}

/* Título asimétrico estilo monopo — cada línea con offset propio */
.hero .hero__title {
  max-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0;
  line-height: 0.98;
  /* fit-content + el align-items:center del .hero__inner → el bloque de la
     cascada queda centrado en la sección, conservando la sangría. */
  width: fit-content;
  margin: 0;
}

.hero__title-line {
  display: block;
}

/* Título del hero unido en bloque, con sangría progresiva (cascada estilo
   monopo) — ya no escalonado izquierda/centro/derecha. */
.hero__title-line--left {
  align-self: flex-start;
  margin-left: 0;
}

.hero__title-line--mid {
  align-self: flex-start;
  margin-left: 0.85em;
}

.hero__title-line--right {
  align-self: flex-start;
  margin-left: 1.7em;
}

/* Movimiento del título — al disparar el slide del Estudio, las líneas 1 y 3
   ("Páginas web" / "tu negocio.") se abren un poco a la izquierda y la línea 2
   ("que hacen crecer") a la derecha. Se abren poquito (8vw) y se atenúan de a
   poco mientras el panel sube — pero NO desaparecen (quedan al 20%). */
.hero__title-line {
  transition: transform 1.8s cubic-bezier(0.33, 0, 0.4, 1),
              opacity 1.8s ease;
}
.hero.is-leaving .hero__title-line--left,
.hero.is-leaving .hero__title-line--right {
  transform: translateX(-8vw);
  opacity: 0.2;
}
.hero.is-leaving .hero__title-line--mid {
  transform: translateX(8vw);
  opacity: 0.2;
}

/* Fade del bottom del hero — franja limpia para que el foot sea legible
   sobre el shader saturado. Soft top, casi opaco al final. */
.hero::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 60%;
  background: linear-gradient(
    180deg,
    transparent 0%,
    rgba(244, 241, 235, 0.06) 18%,
    rgba(244, 241, 235, 0.18) 36%,
    rgba(244, 241, 235, 0.38) 55%,
    rgba(244, 241, 235, 0.62) 72%,
    rgba(244, 241, 235, 0.82) 88%,
    rgba(244, 241, 235, 0.94) 100%
  );
  /* Reduce un poco el blanco SOLO en los costados (centro intacto) para que
     no cale visualmente en las orillas. */
  -webkit-mask-image: linear-gradient(
    90deg,
    rgba(0, 0, 0, 0.55) 0%,
    rgba(0, 0, 0, 1) 22%,
    rgba(0, 0, 0, 1) 78%,
    rgba(0, 0, 0, 0.55) 100%
  );
  mask-image: linear-gradient(
    90deg,
    rgba(0, 0, 0, 0.55) 0%,
    rgba(0, 0, 0, 1) 22%,
    rgba(0, 0, 0, 1) 78%,
    rgba(0, 0, 0, 0.55) 100%
  );
  pointer-events: none;
  z-index: 0;
}

/* Foot del hero — 3 columnas ancladas al bottom con descriptor fuerte
   + línea muted + flecha de scroll. Sin separador. */
.hero__foot {
  position: absolute;
  left: clamp(28px, 4vw, 48px);
  right: clamp(28px, 4vw, 48px);
  bottom: clamp(20px, 3.5vh, 34px);
  display: grid;
  grid-template-columns: 1fr 1fr 1fr auto;
  column-gap: clamp(20px, 3.5vw, 56px);
  row-gap: 0;
  align-items: end;
  z-index: 2;
}

.hero__foot-col {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.hero__foot-strong {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.35;
  color: var(--ink);
}

.hero__foot-muted {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 500;
  line-height: 1.35;
  color: rgba(18, 18, 20, 0.78);
}

.hero__foot-arrow {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  color: rgba(18, 18, 20, 0.82);
  align-self: end;
  justify-self: end;
  line-height: 1;
}

.hero__foot-arrow svg {
  animation: heroScrollBounce 2.2s var(--ease) infinite;
}

@media (max-width: 860px) {
  .hero__foot {
    grid-template-columns: 1fr 1fr;
    row-gap: 16px;
    column-gap: 24px;
  }
  .hero__foot-arrow {
    grid-column: 2 / 3;
    justify-self: end;
  }
}

@media (max-width: 520px) {
  .hero__foot {
    grid-template-columns: 1fr;
    row-gap: 12px;
    padding-top: 14px;
  }
  .hero__foot-arrow {
    position: absolute;
    right: 0;
    top: 14px;
  }
}

.hero__kicker {
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.hero__kicker strong {
  font-weight: 500;
  color: var(--ink);
}

.hero__kicker-sep {
  width: 18px;
  height: 1px;
  background: var(--line-strong);
}

.hero__scroll-hint {
  position: absolute;
  bottom: clamp(24px, 4vw, 44px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-faint);
  pointer-events: none;
}

.hero__scroll-arrow {
  font-size: 1rem;
  letter-spacing: 0;
  animation: heroScrollBounce 1.8s var(--ease) infinite;
}

@keyframes heroScrollBounce {
  0%, 100% { transform: translateY(0); opacity: 0.5; }
  50% { transform: translateY(6px); opacity: 1; }
}

/* Cover scroll — las secciones después del hero entran desde abajo
   cubriendo el hero pineado. */
main {
  position: relative;
  z-index: 1;
}

/* Wrapper que da la altura de "pin time" — 200vh
   permiten 1 viewport para slide-in + 1 viewport de pinneo.
   bg transparente: el dark vive en .signature, así el panel solo
   aparece cuando realmente sube. */
.signature-wrap {
  position: relative;
  z-index: 1;
  margin-top: 100vh;
  margin-top: 100dvh;
  height: 200vh;
  height: 200dvh;
  background: transparent;
  overflow: hidden; /* clipea la signature translateada offscreen */
}

/* Signature pineado dentro del wrap — sticky top 0, 100vh de alto */
.signature {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  /* Panel negro editorial que entra desde la derecha (estilo akaru).
     Negro sólido — la transición vive en .work::before. */
  background: #0d0d0f;
  color: #eef2fb;
  display: flex;
  align-items: center;
  /* Estado inicial: offscreen a la derecha. JS lo actualiza con el scroll. */
  transform: translate3d(100vw, 0, 0);
  will-change: transform;
  /* Clipea el glow y el watermark de la Variante A al panel */
  overflow: hidden;
}

/* Texto dentro del signature negro adapta colores */
.signature .section-label {
  color: rgba(238, 242, 251, 0.55);
}

.signature__title {
  color: #eef2fb;
}

.signature__title em {
  color: #5B9BE8;
}

.signature__lede {
  color: rgba(238, 242, 251, 0.74);
}

.signature__lede strong {
  color: #eef2fb;
}

.signature__pillar-num {
  color: #5B9BE8;
}

.signature__pillar-text {
  color: rgba(238, 242, 251, 0.7);
}

.services {
  position: relative;
  z-index: 1;
  background: #f6f9fd;
}

/* ── Tema NAVY: Contacto + Footer ────────────────────────────────────
   Adoptan el navy revelado tras Identidad como fondo (con granito y
   formas), y re-definen las CSS vars de color a tonos CLAROS → todo el
   texto que usa var(--ink/--ink-soft/--line...) se re-tematiza solo.
   --accent-deep (celeste) se mantiene: brilla sobre el navy. */
.contact,
.footer {
  --ink: #eef2fb;
  --ink-soft: rgba(238, 242, 251, 0.74);
  --ink-faint: rgba(238, 242, 251, 0.46);
  --line: rgba(238, 242, 251, 0.07);
  --line-strong: rgba(238, 242, 251, 0.18);
  /* aplicar el --ink claro como color base → el texto que HEREDA color
     (h2 con reveal, email…) deja de salir negro sobre el navy */
  color: var(--ink);
  position: relative;
  z-index: 1;
  /* FONDO CONTINUO: background-attachment fixed → el navy + glows quedan
     anclados al viewport, así Contacto y Footer comparten EXACTAMENTE el
     mismo fondo y se ven "pegados", sin costura entre secciones. Los glows
     blancos + tonos navy variados le dan profundidad (menos plano/cansado). */
  background:
    radial-gradient(38% 32% at 20% 14%, rgba(255, 255, 255, 0.08), transparent 72%),
    radial-gradient(34% 30% at 78% 62%, rgba(255, 255, 255, 0.05), transparent 70%),
    radial-gradient(44% 40% at 86% 18%, #2a52ad, transparent 72%),
    radial-gradient(48% 50% at 92% 94%, #0a1130, transparent 64%),
    radial-gradient(42% 44% at 6% 84%, #1a346f, transparent 70%),
    radial-gradient(70% 60% at 50% 48%, #15265f, transparent 82%),
    #0F1A52;
  background-attachment: fixed;
  /* Sombra suave en la unión superior: mezcla la costura con la sección de
     arriba (Identidad → Contacto, y Contacto → Footer) y da profundidad. */
  box-shadow: inset 0 96px 80px -56px rgba(6, 10, 36, 0.6);
}
/* Granito (feTurbulence) sobre el navy — también fixed para que sea
   continuo entre Contacto y Footer. */
.contact::after,
.footer::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  background-attachment: fixed;
  opacity: 0.14;
  mix-blend-mode: overlay;
}
.contact > *,
.footer > * {
  position: relative;
  z-index: 1;
}
/* CTA del form sobre navy: botón claro con texto navy (alto contraste). */
.contact .cta--dark {
  background: #eef2fb;
  color: #0F1A52;
  box-shadow: 0 18px 36px -20px rgba(0, 0, 0, 0.55);
}
/* Estado del envío (FormSubmit ok/err) — sigue viviendo aquí porque
   depende del tema navy. */
.contact-form__status[data-state="ok"] {
  color: var(--accent-deep);
}
.contact-form__status[data-state="err"] {
  color: #ff9b8a;
}

/* ── Identidad · section → card ──────────────────────────────────────
   El track da el "scroll room"; .reveal-sticky pinea un viewport; el JS
   encoge la card (.identity) con scale + border-radius, revelando el
   fondo navy con granito y formas detrás. */
.reveal-track {
  position: relative;
  z-index: 2;            /* sobre la órbita de Servicios dentro de su zona */
  height: 220vh;
  /* MISMO navy FIJO que Contacto/Footer en toda la pista → cuando el sticky
     se despega no aparece ninguna franja clara; el navy es continuo de
     Identidad → Contacto (la card clara lo tapa hasta que encoge). */
  background:
    radial-gradient(38% 32% at 20% 14%, rgba(255, 255, 255, 0.08), transparent 72%),
    radial-gradient(34% 30% at 78% 62%, rgba(255, 255, 255, 0.05), transparent 70%),
    radial-gradient(44% 40% at 86% 18%, #2a52ad, transparent 72%),
    radial-gradient(48% 50% at 92% 94%, #0a1130, transparent 64%),
    radial-gradient(42% 44% at 6% 84%, #1a346f, transparent 70%),
    radial-gradient(70% 60% at 50% 48%, #15265f, transparent 82%),
    #0F1A52;
  background-attachment: fixed;
}
.reveal-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Fondo revelado: navy + FORMAS (radial-gradients de tonos navy) +
   GRANITO (feTurbulence fractalNoise) encima. */
.reveal-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  /* MISMO fondo navy FIJO que Contacto/Footer → el navy es uno solo y
     continuo de Identidad → Contacto → Footer, sin línea/costura entre
     secciones (al estar fixed, todos comparten el mismo fondo del viewport). */
  background:
    radial-gradient(38% 32% at 20% 14%, rgba(255, 255, 255, 0.08), transparent 72%),
    radial-gradient(34% 30% at 78% 62%, rgba(255, 255, 255, 0.05), transparent 70%),
    radial-gradient(44% 40% at 86% 18%, #2a52ad, transparent 72%),
    radial-gradient(48% 50% at 92% 94%, #0a1130, transparent 64%),
    radial-gradient(42% 44% at 6% 84%, #1a346f, transparent 70%),
    radial-gradient(70% 60% at 50% 48%, #15265f, transparent 82%),
    #0F1A52;
  background-attachment: fixed;
}
.reveal-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  background-attachment: fixed;
  opacity: 0.14;
  mix-blend-mode: overlay;
  pointer-events: none;
}
/* La card celeste — el JS le aplica transform (scale) y border-radius. */
.reveal-track .identity {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  background: #f6f9fd;
  transform-origin: center center;
  will-change: transform, border-radius;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 40px 120px -40px rgba(8, 16, 48, 0.55);
}

/* Sección Resultado — fondo celeste limpio. El "toque de negro" lo da
   la masa negra de Estudio que se prolonga hacia abajo via .work::before
   con un clip-path diagonal cayendo de izq→der. Sin bandas intermedias. */
.work {
  position: relative;
  /* z-index 2 (sobre Servicios): como Servicios sube y se encima un poco,
     así la card y su SOMBRA quedan por encima y no se ven recortadas. */
  z-index: 2;
  background: #f6f9fd;
  /* menos aire abajo → todo lo que sigue (Servicios, etc.) sube */
  padding-bottom: clamp(20px, 3vw, 48px);
}

/* La transición Estudio→Resultado vive en el propio panel de Estudio: su
   borde inferior se recorta en cascada con un mask, así el negro y sus luces
   se funden de una pieza al celeste — ver body[data-stage="post-intro"]
   .signature y .signature-wrap. */

/* === Resultado · Portafolio — Parte 1: layout base ===================== */
.work .port__head {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  max-width: 1340px;
  margin: 0 auto;
  text-align: right;
  /* el título se superpone arriba del sticky; se oculta al scrollear hacia
     abajo y reaparece al subir (.is-tucked vía JS). Transición lenta. */
  padding-top: clamp(88px, 13vh, 168px);
  padding-bottom: clamp(16px, 3vh, 38px);
  transition: transform 1.1s cubic-bezier(0.33, 1, 0.68, 1),
              opacity 0.8s ease;
}
.work .port__head.is-tucked {
  transform: translateY(-118%);
  opacity: 0;
}
.work .port__title {
  margin: 12px 0 0 auto;
  max-width: 16ch;
  font-size: clamp(2.4rem, 4.4vw, 3.8rem);
  font-weight: 600;
  letter-spacing: -0.032em;
  line-height: 1.06;
}
.work .port__title em {
  font-style: italic;
  color: inherit;
}

.port__stage {
  max-width: 1340px;
  margin: 0 auto;
  display: grid;
  /* 1fr · auto · 1fr → la imagen (columna central) queda centrada en
     la sección; la info se acomoda a su lado izquierdo. */
  grid-template-columns: 1fr auto 1fr;
  gap: clamp(28px, 4vw, 60px);
  align-items: center;
}
.port__info {
  position: relative;
  justify-self: end;
  width: 300px;
  max-width: 300px;
  /* alto fijo para las 2 versiones de texto apiladas (absolute) */
  min-height: 270px;
}
/* cada proyecto tiene su bloque de texto; se apilan y solo uno se ve. El JS
   cruza opacidad + un desplazamiento leve (arriba/abajo según el scroll). */
.port__text {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  opacity: 0;
  will-change: opacity, transform;
}
.port__text:first-child { opacity: 1; }
.port__count {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  margin-bottom: 22px;
}
.port__count b { color: var(--royal); }
.port__kind {
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  /* baja tantito el kicker para que no choque con el negro diagonal de arriba */
  margin-top: clamp(20px, 3.5vh, 40px);
  margin-bottom: 12px;
}
.port__name {
  font-size: clamp(1.9rem, 3vw, 2.8rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.04;
  margin-bottom: 18px;
}
.port__desc {
  font-size: 1.04rem;
  color: var(--ink-soft);
  max-width: 32ch;
  margin-bottom: 30px;
}
.port__cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ink);
  text-decoration: none;
  padding-bottom: 4px;
  border-bottom: 1.5px solid var(--ink);
  transition: gap 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}
.port__cta:hover {
  gap: 16px;
  color: var(--royal);
  border-color: var(--royal);
}

/* UNA card de imagen — fija. Las tomas (.port__shot) se apilan adentro y se
   sustituyen con crossfade; ninguna se mueve → la sombra no se ve cortada. */
.port__media {
  position: relative;
  width: min(54vw, 680px);
  /* proporción real de la imagen (1600×860) para que calce sin recorte. */
  aspect-ratio: 1600 / 860;
  /* tantito a la derecha + bajada para que en reposo no quede pegada al título */
  margin-left: clamp(20px, 4vw, 64px);
  transform: translateY(36px);
  transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
  transform-origin: left center;
}
/* zoom al entrar al showcase: como el título ya se fue hacia arriba, la card
   crece Y sube hacia ese espacio liberado (no hacia abajo). */
.port__media.is-zoomed {
  transform: translateY(-26px) scale(1.22);
}
.port__shot {
  position: absolute;
  inset: 0;
  opacity: 0;
  will-change: opacity;
}
.port__shot:first-child { opacity: 1; }
.port__shot .mock,
.port__shot .mock__screen {
  height: 100%;
}
.port__media .mock {
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 44px 90px -36px rgba(20, 30, 55, 0.42);
  transition: box-shadow 0.5s ease;
}
.port__media:hover .mock {
  box-shadow: 0 56px 110px -34px rgba(45, 82, 227, 0.4);
}
.port__media .mock__bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 14px 18px;
  background: #e9eef5;
}
.port__media .mock__bar i {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: #c4ccd8;
}
.port__media .mock__bar em {
  margin-left: 16px;
  font-style: normal;
  font-size: 0.8rem;
  color: #8a93a3;
}
.port__media .mock__screen {
  aspect-ratio: 1600 / 860;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  padding: clamp(28px, 3.5vw, 52px);
  /* fondo cool (queda cubierto por la foto); wordmark + hint en azul rey */
  background: linear-gradient(150deg, #16213f, #0d1018);
  color: var(--royal);
}
/* Foto real del proyecto dentro del mockup */
.port__media .mock__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}
/* Sin velo: la imagen del proyecto se ve limpia (ya no hay texto encima). */
.port__media .mock__brand {
  position: relative;
  z-index: 2;
  font-size: clamp(2.4rem, 4.5vw, 4.4rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.port__media .mock__line {
  position: relative;
  z-index: 1;
  height: 10px;
  border-radius: 6px;
  margin-top: 14px;
  background: rgba(255, 255, 255, 0.2);
}
.port__media .ml-1 { width: 42%; }
.port__media .ml-2 { width: 26%; }
.port__media .mock__hint {
  position: absolute;
  top: 18px;
  right: 20px;
  z-index: 2;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.7);
  display: flex;
  align-items: center;
  gap: 7px;
}
.port__media .mock__hint::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--royal);
}

@media (max-width: 880px) {
  .port__stage { grid-template-columns: 1fr; gap: 36px; }
  .port__info { justify-self: start; max-width: none; }
  .port__media { width: 100%; }
}

/* === Resultado · showcase fijado — UNA card, imagen sustituible ======== */
/* Track alto → la transición se reparte sobre más scroll: un flick rápido
   avanza menos animación y hay más "descanso" para leer cada proyecto antes y
   después del crossfade. El ritmo fino lo controla el JS (rueda más lenta). */
.port__track {
  position: relative;
  height: 300vh;
  height: 300dvh;
  flex-shrink: 0;
}
.port__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}
/* contenedor centrado del proyecto; el JS le suma un desplazamiento mientras
   el título está visible. SIN overflow → las sombras nunca se cortan. */
.port__deck {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  z-index: 1;
  transform: translateY(-50%);
  transition: transform 1.1s cubic-bezier(0.33, 1, 0.68, 1);
}

/* Mockup del 2º proyecto (Morea) — foto real del proyecto (mock__screen--photo),
   mismo tratamiento que Atico: foto a sangre + velo oscuro + nombre encima. */

/* Sin pin ni swap (movimiento reducido o móvil): apilado normal. */
@media (prefers-reduced-motion: reduce), (max-width: 880px) {
  .port__track { height: auto; }
  .port__sticky { position: static; height: auto; overflow: visible; }
  .work .port__head { position: static; }
  .port__deck {
    position: static;
    transform: none !important;
    padding-top: clamp(50px, 8vh, 120px);
    padding-bottom: clamp(50px, 8vh, 120px);
  }
  .port__info { min-height: 0; }
  .port__text {
    position: relative;
    opacity: 1 !important;
    transform: none !important;
  }
  .port__text + .port__text { margin-top: 40px; }
  .port__media { aspect-ratio: auto; }
  .port__shot {
    position: relative;
    opacity: 1 !important;
  }
  .port__shot + .port__shot { margin-top: 24px; }
  .port__shot .mock,
  .port__shot .mock__screen { height: auto; }
}
/* ======================================================================= */

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

.hero__title {
  margin: 0;
  max-width: 18ch;
  font-size: clamp(2.6rem, 6vw, 5.2rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
  font-weight: 600;
  text-wrap: balance;
  padding-bottom: 0.08em;
}

.hero__title em {
  font-style: normal;
  font-weight: 600;
  color: inherit;
  white-space: nowrap;
}

.hero__lede {
  max-width: 46ch;
  margin: 0;
  font-size: clamp(1.05rem, 1.1vw, 1.22rem);
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink-soft);
}

.hero__actions,
.hero__notes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.hero__notes span {
  padding: 0.62rem 0.82rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: rgba(255, 252, 247, 0.55);
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.hero__stage {
  position: relative;
  min-height: 560px;
  display: block;
  --mx: 0;
  --my: 0;
  transform: perspective(1200px) rotateX(calc(var(--my) * -3deg)) rotateY(calc(var(--mx) * 3deg));
  transition: transform 0.35s var(--ease);
}

.hero-spec {
  position: relative;
  border-radius: var(--radius-md);
  background: #fffaf3;
  border: 1px solid rgba(18, 18, 20, 0.08);
  box-shadow: 0 28px 80px -40px rgba(18, 18, 20, 0.22);
  padding: clamp(28px, 3.2vw, 44px) clamp(24px, 3vw, 40px);
  min-height: 560px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.hero-spec__topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: clamp(48px, 6vw, 76px);
}

.hero-spec__topbar span:first-child::before {
  content: "— ";
  color: var(--accent-deep);
}

.hero-spec__feature {
  position: relative;
}

.hero-spec__feature::before {
  content: "";
  position: absolute;
  left: -24px;
  top: 12px;
  bottom: 12px;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--accent-deep), transparent);
  opacity: 0.32;
}

.hero-spec__word {
  font-style: italic;
  font-weight: 600;
  font-size: clamp(2.6rem, 5vw, 4.4rem);
  line-height: 0.95;
  letter-spacing: -0.025em;
  margin: 0;
  color: var(--ink);
}

.hero-spec__dot {
  color: var(--accent-deep);
  font-style: normal;
}

.hero-spec__detail {
  margin: 14px 0 0;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.hero-spec__detail span + span {
  margin-left: 12px;
  padding-left: 12px;
  border-left: 1px solid rgba(18, 18, 20, 0.15);
}

.hero-spec__grid {
  margin: clamp(40px, 5vw, 60px) 0 0;
  display: grid;
  grid-template-columns: 64px 1fr;
  column-gap: 20px;
  row-gap: clamp(16px, 2vw, 22px);
  align-items: start;
}

.hero-spec__grid dt {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-top: 5px;
}

.hero-spec__grid dd {
  margin: 0;
}

.hero-spec__line {
  font-size: clamp(0.98rem, 1.2vw, 1.12rem);
  line-height: 1.4;
  color: var(--ink);
  margin: 0;
}

/* Cada muestra renderiza en SU peso para ilustrar la escala viva */
.hero-spec__grid dd:nth-of-type(1) { font-weight: 400; color: var(--ink-soft); }
.hero-spec__grid dd:nth-of-type(2) { font-weight: 500; }
.hero-spec__grid dd:nth-of-type(3) { font-weight: 600; }

.hero-spec__line em {
  font-style: italic;
  font-weight: inherit;
  color: var(--accent-deep);
}

.hero__column {
  display: grid;
  gap: 1rem;
}

.hero__column--tall {
  padding-top: 56px;
}

.hero__column--wide {
  padding-bottom: 48px;
}

.hero__subgrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.hero-block {
  position: relative;
  overflow: hidden;
  border-radius: 34px;
  border: 1px solid var(--line);
  background: var(--paper);
  box-shadow: var(--shadow-soft);
}

.hero-block--statement {
  min-height: 190px;
  padding: 1.4rem;
}

.hero-block__kicker,
.hero-block__label,
.case__tag {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.hero-block--statement p {
  margin: 0.75rem 0 0;
  max-width: 8ch;
  font-family: var(--font-serif);
  font-size: clamp(2rem, 2.8vw, 3rem);
  line-height: 0.9;
  letter-spacing: -0.05em;
}

.hero-block__meta {
  display: flex;
  gap: 0.45rem;
  flex-wrap: wrap;
  margin-top: 1.1rem;
}

.hero-block__meta span {
  padding: 0.45rem 0.62rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.12);
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(247, 244, 238, 0.72);
}

.hero-block--dark {
  background: linear-gradient(180deg, rgba(18, 18, 20, 0.98), rgba(31, 33, 39, 0.96));
  color: #f7f4ee;
}

.hero-block--frame {
  min-height: 330px;
  padding: 1rem;
}

.hero-frame {
  height: 100%;
  border-radius: 28px;
  border: 1px solid rgba(18, 18, 20, 0.08);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.86), rgba(241, 238, 232, 0.74));
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 0.85rem;
  padding: 1rem;
}

.hero-frame__window {
  width: 100%;
  display: flex;
  gap: 0.34rem;
  align-items: center;
  padding-bottom: 0.3rem;
}

.hero-frame__window span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(18, 18, 20, 0.18);
}

.hero-frame__hero {
  width: 100%;
  min-height: 92px;
  border-radius: 22px;
  background:
    radial-gradient(circle at 82% 20%, rgba(188, 198, 214, 0.34), transparent 22%),
    linear-gradient(180deg, rgba(18, 18, 20, 0.08), rgba(18, 18, 20, 0.04));
  border: 1px solid rgba(18, 18, 20, 0.06);
}

.hero-frame__caption {
  width: 100%;
  display: grid;
  gap: 0.42rem;
}

.hero-frame__caption span {
  display: block;
  height: 10px;
  border-radius: 999px;
  background: rgba(18, 18, 20, 0.12);
}

.hero-frame__caption span:first-child {
  width: 52%;
}

.hero-frame__caption span:last-child {
  width: 34%;
}

.hero-frame__bar {
  width: min(72%, 240px);
  height: 16px;
  border-radius: 999px;
  background: rgba(18, 18, 20, 0.86);
}

.hero-frame__bar--mid {
  width: 54%;
  height: 10px;
  background: rgba(18, 18, 20, 0.28);
}

.hero-frame__bar--short {
  width: 34%;
  height: 10px;
  background: rgba(18, 18, 20, 0.16);
}

.hero-frame__grid {
  width: min(70%, 250px);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.8rem;
}

.hero-frame__grid span {
  aspect-ratio: 1;
  border-radius: 18px;
  background: rgba(18, 18, 20, 0.08);
}

.hero-block--feature {
  min-height: 450px;
  background:
    radial-gradient(circle at 18% 18%, rgba(188, 198, 214, 0.26), transparent 24%),
    linear-gradient(180deg, rgba(255, 252, 247, 0.92), rgba(240, 238, 233, 0.84));
}

.hero-block__top {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.9rem 1rem;
  border-bottom: 1px solid rgba(18, 18, 20, 0.08);
  background: rgba(255, 255, 255, 0.4);
}

.hero-block__top span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(18, 18, 20, 0.22);
}

.hero-block__top small {
  margin-left: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.hero-block__body {
  height: calc(100% - 48px);
  display: grid;
  place-items: center;
  gap: 1.1rem;
  padding: 1.4rem;
}

.hero-block__mark {
  color: var(--accent-deep);
}

.hero-block__caption {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  justify-content: center;
}

.hero-block__stats {
  width: min(76%, 320px);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.6rem;
}

.hero-block__stats span {
  min-height: 72px;
  border-radius: 18px;
  border: 1px solid rgba(18, 18, 20, 0.06);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.72), rgba(241, 238, 232, 0.72));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

.hero-block__caption span {
  padding: 0.5rem 0.72rem;
  border-radius: 999px;
  border: 1px solid rgba(18, 18, 20, 0.08);
  background: rgba(255, 255, 255, 0.66);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.hero-block--soft {
  min-height: 144px;
  padding: 1rem;
  display: grid;
  align-content: end;
  gap: 0.4rem;
}

.hero-block--soft strong {
  font-size: 1.15rem;
  letter-spacing: -0.03em;
}

.hero-block__mini-ui {
  display: grid;
  gap: 0.42rem;
  margin-top: 0.7rem;
}

.hero-block__mini-ui span {
  display: block;
  height: 10px;
  border-radius: 999px;
  background: rgba(18, 18, 20, 0.14);
}

.hero-block__mini-ui span:nth-child(1) {
  width: 86%;
}

.hero-block__mini-ui span:nth-child(2) {
  width: 64%;
}

.hero-block__mini-ui span:nth-child(3) {
  width: 42%;
}

.hero-block__mini-ui--split {
  grid-template-columns: 1fr 1fr;
  gap: 0.55rem;
}

.hero-block__mini-ui--split span {
  width: 100%;
  min-height: 52px;
  height: auto;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.46);
  border: 1px solid rgba(18, 18, 20, 0.06);
}

.hero-block--tint {
  background:
    radial-gradient(circle at 84% 14%, rgba(188, 198, 214, 0.32), transparent 24%),
    rgba(255, 252, 247, 0.8);
}

.hero__metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.9rem;
  margin-top: 1rem;
}

.hero__metrics article,
.proof-card {
  padding: 1.1rem;
  border-radius: 24px;
  border: 1px solid var(--line);
  background: rgba(255, 252, 247, 0.56);
  box-shadow: var(--shadow-soft);
}

.proof-card {
  position: relative;
  padding: clamp(24px, 2.6vw, 34px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow: hidden;
}

.proof-card__kicker {
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-deep);
  margin-bottom: 6px;
}

.hero__metrics strong,
.proof-card strong {
  display: block;
  font-size: clamp(1.25rem, 1.8vw, 1.65rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--ink);
}

.hero__metrics span,
.proof-card p {
  color: var(--ink-soft);
  line-height: 1.5;
  font-size: 0.95rem;
  margin: 0;
}

.proof-card__accent {
  display: block;
  width: 28px;
  height: 2px;
  background: var(--accent-deep);
  margin-top: 10px;
  opacity: 0.7;
}

.marquee {
  position: relative;
  z-index: 2;
  overflow: hidden;
  background: rgba(18, 18, 20, 0.98);
  color: #f7f4ee;
}

.marquee__track {
  display: inline-flex;
  min-width: max-content;
  gap: 1.6rem;
  padding: 0.9rem 0;
  animation: ticker 28s linear infinite;
}

.marquee__track span {
  display: inline-flex;
  align-items: center;
  gap: 1.6rem;
  font-family: var(--font-serif);
  font-size: clamp(1rem, 0.6vw + 0.92rem, 1.4rem);
  font-style: italic;
}

.marquee__track span::after {
  content: "•";
  color: rgba(255, 255, 255, 0.36);
}

/* Manifiesto centrado — rompe el ritmo title-left / cards-right. */
.signature {
  /* Mismo padding lateral que el estado post-intro (ver regla
     body[data-stage="post-intro"] .signature) para que el swap entre
     "deslizándose" y "fija" no cambie el ancho del contenido — si no,
     se ve un reacomodo al terminar de entrar la sección. */
  padding: clamp(60px, 8vw, 120px) clamp(28px, 4.5vw, 72px);
  text-align: center;
  justify-content: center;
}

.signature__manifesto {
  /* Ancho generoso para que el título grande quepa en 2 líneas */
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(24px, 3.2vw, 40px);
  /* Por encima del glow de fondo */
  position: relative;
  z-index: 1;
}

.signature .section-label {
  justify-content: center;
  font-size: 0.76rem;
  /* Bajado un poco respecto al borde superior del manifiesto */
  margin-top: 18px;
}

.signature__title {
  margin: 0;
  /* El título ya NO se parte por palabras en el JS (ver hero-v2.js): así
     text-wrap: balance reparte las líneas parejas y nunca se distorsiona,
     crezca lo que crezca. El <br> del HTML separa las dos frases. */
  max-width: none;
  font-size: clamp(2rem, 3.8vw, 3rem);
  font-weight: 600;
  line-height: 1.16;
  letter-spacing: -0.028em;
  color: #eef2fb;
  text-wrap: balance;
}

.signature__title em {
  font-style: normal;
  font-weight: 600;
  color: inherit;
}

.signature__title br {
  display: block;
}

.signature__lede {
  margin: 0;
  /* Los saltos van a mano (<br>) para formar la pirámide invertida:
     3 líneas de más a menos palabras. Sin max-width en ch para no
     forzar quiebres extra. */
  max-width: none;
  font-size: clamp(1.15rem, 1.6vw, 1.42rem);
  font-weight: 500;
  line-height: 1.55;
  color: rgba(238, 242, 251, 0.74);
}

.signature__lede strong {
  color: #eef2fb;
  font-weight: 600;
}

.signature__pillars {
  list-style: none;
  padding: 0;
  margin: clamp(28px, 4vw, 48px) 0 0;
  width: 100%;
  max-width: 960px;
  display: flex;
  gap: clamp(28px, 5vw, 64px);
  text-align: left;
}

.signature__pillars li {
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1 1 240px;
  max-width: 280px;
  min-width: 200px;
  text-align: left;
}

/* Divisor vertical fino entre columnas (no antes de la primera). Reemplaza
   la línea horizontal + ticks que se veían como diagrama/mapa conceptual. */
.signature__pillars li + li {
  border-left: 1px solid rgba(91, 155, 232, 0.45);
  padding-left: clamp(28px, 5vw, 64px);
}

.signature__pillar-num {
  font-family: var(--font-mono, var(--font-sans));
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #5B9BE8;
  padding-top: 2px;
  flex-shrink: 0;
}

.signature__pillar-text {
  font-size: 0.98rem;
  font-weight: 500;
  line-height: 1.4;
  color: rgba(238, 242, 251, 0.7);
}

/* Remate de calificación ("para quién es"): cierra Estudio antes de Trabajo.
   Más chico que los pilares para no competir; separador fino arriba; énfasis
   por italic (sin color partido). */
.signature__qualifier {
  margin: clamp(28px, 4vw, 44px) 0 0;
  padding-top: clamp(22px, 3vw, 32px);
  border-top: 1px solid rgba(91, 155, 232, 0.28);
  max-width: 640px;
  font-size: clamp(1rem, 1.3vw, 1.12rem);
  font-weight: 500;
  line-height: 1.5;
  color: rgba(238, 242, 251, 0.6);
}

.signature__qualifier em {
  font-style: italic;
  font-weight: 500;
  color: #eef2fb;
}

/* Orphan: .signature__layout/grid/manifesto/sig-panel ya no se usan
   en el HTML. Se limpian en el chore issue #11. */
.signature__layout {
  display: grid;
  grid-template-columns: minmax(280px, 0.55fr) minmax(0, 1fr);
  gap: clamp(1rem, 3vw, 2rem);
  align-items: start;
}

.manifesto {
  padding: 1.35rem;
  border-radius: 32px;
  border: 1px solid var(--line);
  background: rgba(255, 252, 247, 0.64);
  box-shadow: var(--shadow-soft);
}

.manifesto__index {
  display: inline-flex;
  margin-bottom: 0.9rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.manifesto p {
  margin: 0;
  font-family: var(--font-serif);
  font-size: clamp(1.6rem, 2.1vw, 2.4rem);
  line-height: 0.96;
  letter-spacing: -0.04em;
}

.manifesto strong {
  color: var(--accent-deep);
}

.signature__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

.sig-panel {
  min-height: 220px;
  padding: 1.2rem;
  border-radius: 30px;
  border: 1px solid var(--line);
  background: rgba(255, 252, 247, 0.62);
  box-shadow: var(--shadow-soft);
}

.sig-panel span {
  display: inline-flex;
  margin-bottom: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.sig-panel h3 {
  margin: 0;
  max-width: 12ch;
  font-size: 1.28rem;
  line-height: 1;
  letter-spacing: -0.04em;
}

.sig-panel__ui {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.6rem;
  margin-top: 1rem;
}

.sig-panel__ui span {
  min-height: 62px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(18, 18, 20, 0.06);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.72);
}

.sig-panel__ui span:first-child {
  grid-column: span 2;
  min-height: 16px;
  border-radius: 999px;
  background: rgba(18, 18, 20, 0.12);
}

.sig-panel__ui--dark span {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.1);
}

.sig-panel__ui--dark span:first-child {
  background: rgba(255, 255, 255, 0.18);
}

.sig-panel--dark {
  background: linear-gradient(180deg, rgba(18, 18, 20, 0.98), rgba(31, 33, 39, 0.96));
  color: #f7f4ee;
}

.sig-panel--light {
  background:
    radial-gradient(circle at 80% 18%, rgba(188, 198, 214, 0.28), transparent 24%),
    rgba(255, 252, 247, 0.72);
}

.sig-panel--image {
  padding: 0;
  overflow: hidden;
}

.sig-panel__art {
  height: 100%;
  min-height: 220px;
  position: relative;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.8), rgba(236, 232, 226, 0.9));
}

.sig-panel__art span {
  position: absolute;
  border-radius: 24px;
  background: rgba(18, 18, 20, 0.08);
}

.sig-panel__art span:nth-child(1) {
  inset: 12% 52% 58% 12%;
}

.sig-panel__art span:nth-child(2) {
  inset: 12% 12% 58% 52%;
  background: rgba(188, 198, 214, 0.32);
}

.sig-panel__art span:nth-child(3) {
  inset: 34% 12% 40% 12%;
  background: rgba(18, 18, 20, 0.14);
}

.sig-panel__art span:nth-child(4) {
  inset: 64% 12% 22% 12%;
  border-radius: 999px;
  background: rgba(18, 18, 20, 0.12);
}

.sig-panel__art span:nth-child(5) {
  inset: 76% 12% 12% 38%;
  border-radius: 999px;
  background: rgba(18, 18, 20, 0.08);
}

.sig-panel--quote {
  display: grid;
  place-items: end start;
}

.sig-panel--quote p {
  margin: 0;
  max-width: 10ch;
  font-family: var(--font-serif);
  font-size: clamp(1.8rem, 2vw, 2.7rem);
  line-height: 0.9;
  letter-spacing: -0.05em;
}

.work__layout {
  display: grid;
  grid-template-columns: 1.08fr 0.92fr;
  gap: 1rem;
}

.case {
  display: grid;
  gap: 1rem;
  padding: 14px;
  border-radius: 28px;
  border: 1px solid var(--line);
  background: rgba(255, 252, 247, 0.68);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

.case--feature {
  grid-row: span 2;
}

/* Frame interno: el "mockup teaser" — cada caso tiene su paleta propia */
.case__frame {
  position: relative;
  border-radius: 18px;
  padding: clamp(22px, 2.6vw, 36px);
  min-height: 240px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(40px, 6vw, 80px);
  background: var(--case-bg, #1a1210);
  color: var(--case-fg, #f4e8d5);
  overflow: hidden;
  isolation: isolate;
}

.case--feature .case__frame {
  min-height: 360px;
}

.case__meta-bar {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.72;
}

.case__brandmark {
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: -0.01em;
  text-transform: none;
  opacity: 1;
}

.case__industry {
  font-weight: 500;
}

.case__hero {
  margin: 0;
  font-size: clamp(1.6rem, 2.4vw, 2.4rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.025em;
  max-width: 14ch;
  text-wrap: balance;
}

.case--feature .case__hero {
  font-size: clamp(2rem, 3vw, 3rem);
}

.case__hero em {
  font-style: italic;
  font-weight: 600;
  color: var(--case-accent, #c8974a);
}

.case__foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: lowercase;
  opacity: 0.65;
}

.case__year {
  font-weight: 500;
  letter-spacing: 0.14em;
  opacity: 0.7;
}

.case__copy {
  padding: 6px 10px 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.case__copy h4 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.case__copy p {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.45;
  color: var(--ink-soft);
  max-width: 40ch;
}

/* ── Paletas por caso ───────────────────────── */
.case--atico {
  --case-bg: #1c140f;
  --case-fg: #f4e8d5;
  --case-accent: var(--royal);
}
.case--atico .case__frame::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--case-accent), transparent);
  opacity: 0.42;
}

.case--morea {
  --case-bg: #e6e3dc;
  --case-fg: #1a1f2b;
  --case-accent: #45556f;
}
.case--morea .case__frame::before {
  content: "";
  position: absolute;
  left: clamp(22px, 2.6vw, 36px);
  right: clamp(22px, 2.6vw, 36px);
  top: 50%;
  height: 1px;
  background: rgba(26, 31, 43, 0.14);
  z-index: -1;
}

.case--sola {
  --case-bg: #e9e7d4;
  --case-fg: #1b1f15;
  --case-accent: var(--royal);
}
.case--sola .case__frame::after {
  content: "";
  position: absolute;
  top: clamp(22px, 2.6vw, 36px);
  right: clamp(22px, 2.6vw, 36px);
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1.5px solid var(--case-accent);
  opacity: 0.55;
}

/* CTA banner debajo del grid */
.work__cta {
  margin-top: clamp(32px, 5vw, 48px);
  padding: clamp(24px, 3vw, 36px) clamp(24px, 3vw, 40px);
  border-radius: 24px;
  border: 1px solid var(--line);
  background: rgba(255, 252, 247, 0.72);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}

.work__cta p {
  margin: 0;
  font-size: clamp(1.1rem, 1.6vw, 1.4rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.case__visual {
  position: relative;
  min-height: 220px;
  overflow: hidden;
  border-radius: 22px;
  border: 1px solid rgba(18, 18, 20, 0.08);
}

.case__chrome,
.case__paper,
.case__footer-band,
.case__product-base,
.case__studio-panel {
  position: absolute;
}

.case__chrome {
  top: 0;
  left: 0;
  right: 0;
  height: 44px;
  display: flex;
  align-items: center;
  gap: 0.34rem;
  padding: 0 0.9rem;
  background: rgba(255, 255, 255, 0.52);
  border-bottom: 1px solid rgba(18, 18, 20, 0.06);
}

.case__chrome span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(18, 18, 20, 0.16);
}

.case__chrome--dark {
  background: rgba(255, 255, 255, 0.06);
  border-bottom-color: rgba(255, 255, 255, 0.08);
}

.case__chrome--dark span {
  background: rgba(255, 255, 255, 0.22);
}

.case__paper {
  top: 58px;
  left: 10%;
  right: 10%;
  bottom: 14%;
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.72);
  box-shadow: 0 20px 30px -24px rgba(18, 18, 20, 0.22);
}

.case--feature .case__visual {
  min-height: 520px;
}

.case__copy {
  display: grid;
  gap: 0.45rem;
  max-width: 28ch;
}

.case__copy h3 {
  margin: 0;
  font-size: clamp(1.25rem, 1.6vw, 1.9rem);
  line-height: 1;
  letter-spacing: -0.04em;
}

.case__copy p {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.case--dark .case__copy p,
.case--dark .case__tag {
  color: rgba(247, 244, 238, 0.72);
}

.case__visual--legal {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(236, 232, 226, 0.92)),
    radial-gradient(circle at 84% 14%, rgba(188, 198, 214, 0.24), transparent 20%);
}

.case__line,
.case__seal,
.case__tile,
.case__orbit,
.case__center-mark {
  position: absolute;
}

.case__line {
  left: 12%;
  border-radius: 999px;
  background: rgba(18, 18, 20, 0.86);
}

.case__line--a {
  top: 28%;
  width: 52%;
  height: 18px;
}

.case__line--b {
  top: 37%;
  width: 68%;
  height: 10px;
  background: rgba(18, 18, 20, 0.26);
}

.case__seal {
  right: 12%;
  top: 18%;
  width: 92px;
  height: 92px;
  border-radius: 50%;
  border: 1px dashed rgba(18, 18, 20, 0.22);
}

.case__footer-band {
  left: 10%;
  right: 10%;
  bottom: 9%;
  height: 18px;
  border-radius: 999px;
  background: rgba(18, 18, 20, 0.08);
}

.case__visual--product {
  background:
    radial-gradient(circle at 18% 20%, rgba(188, 198, 214, 0.24), transparent 22%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(236, 232, 226, 0.92));
}

.case__tile {
  width: 34%;
  aspect-ratio: 1;
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.88);
  border: 1px solid rgba(18, 18, 20, 0.08);
  box-shadow: 0 14px 22px -18px rgba(18, 18, 20, 0.18);
}

.case__tile:nth-child(1) {
  top: 22%;
  left: 10%;
}

.case__tile:nth-child(2) {
  top: 22%;
  right: 10%;
  background: rgba(188, 198, 214, 0.34);
}

.case__tile:nth-child(3) {
  left: 28%;
  bottom: 20%;
}

.case__product-base {
  left: 18%;
  right: 18%;
  bottom: 10%;
  height: 20px;
  border-radius: 999px;
  background: rgba(18, 18, 20, 0.08);
}

.case__visual--studio {
  background:
    radial-gradient(circle at 20% 18%, rgba(188, 198, 214, 0.2), transparent 22%),
    radial-gradient(circle at 82% 80%, rgba(255, 255, 255, 0.12), transparent 18%),
    rgba(15, 16, 20, 0.98);
}

.case__studio-panel {
  top: 72px;
  width: 22%;
  bottom: 18%;
  border-radius: 22px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.04);
}

.case__studio-panel--left {
  left: 9%;
}

.case__studio-panel--right {
  right: 9%;
}

.case__orbit {
  left: 50%;
  top: 50%;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.14);
  transform: translate(-50%, -50%);
}

.case__orbit--one {
  width: 64%;
  aspect-ratio: 1;
  animation: spin 18s linear infinite;
}

.case__orbit--two {
  width: 42%;
  aspect-ratio: 1;
  border-style: dashed;
  animation: spinReverse 14s linear infinite;
}

.case__center-mark {
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  color: rgba(247, 244, 238, 0.82);
}

/* === Servicios — fila de 4 piezas, mismo lenguaje que los pilares de
   Estudio: palabra-nombre italic azul + título + descripción + tags.
   Sin imágenes grandes, sin cards opacas, sin numerales. Cabe en 1
   pantalla. ============================================================= */

/* Aislamos el stacking context para que el canvas del fondo viva DENTRO
   de la sección y el contenido siempre quede encima. NO usamos
   overflow:hidden aquí — recortaría títulos por el borde superior
   (regla feedback-no-cortes-secciones). */
.services {
  isolation: isolate;
  overflow: visible;
}
.services .section-headline,
.services .section-headline h2 {
  overflow: visible;
}

/* Canvas de partículas tipo Antigravity — POSITION: FIXED al viewport.
   Esto garantiza que las coords del canvas son IGUALES a las del cursor
   (clientX, clientY): sin transformaciones de getBoundingClientRect,
   sin offsets posibles. El JS solo dibuja partículas cuando el cursor
   está dentro del bounding rect de .services. */
.services__particles {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 0;
}

/* Todo el contenido directo de la sección debe quedar por encima del bg. */
.services > *:not(.services__particles) {
  position: relative;
  z-index: 1;
}

/* ── Proceso: timeline horizontal (4 fases en fila). Mismo fondo que
   Servicios para que se lean como una sola zona continua. Sin numerales:
   un punto sobre una línea continua marca cada fase. ── */
.process {
  background: #f6f9fd;
  /* Pega con Servicios: sin padding superior, la zona clara es continua. */
  padding-top: clamp(1rem, 2vw, 2rem);
}

.process__lede {
  margin: 0 0 clamp(2.2rem, 4.5vw, 3.4rem);
  max-width: 46ch;
  font-size: clamp(1.08rem, 1.35vw, 1.3rem);
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* Escalera descendente. Cada escalón baja y se recorre a la derecha; la
   línea y los círculos se dibujan en la capa SVG (process-stair.js) y se
   animan al entrar. El indentado lo da --stair-inc. */
.process__stair {
  position: relative;
  --stair-inc: clamp(2.2rem, 8vw, 9rem);
}

/* Capa SVG por detrás del texto: la línea + los círculos. */
.process__lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  z-index: 0;
}

.process__lines path {
  fill: none;
  stroke: var(--royal);
  stroke-width: 1.5;
  stroke-linejoin: round;
  /* pathLength="1" lo pone el JS: la línea se "dibuja" de 1 → 0. */
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.7s cubic-bezier(0.65, 0, 0.35, 1);
}

.process__lines circle {
  fill: var(--royal);
  opacity: 0;
  transform: scale(0);
  transform-box: fill-box;
  transform-origin: center;
  transition: opacity 0.4s ease, transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Al entrar (clase puesta por el JS): se dibuja la línea y aparecen los
   círculos en secuencia (el delay por círculo lo pone el JS). */
.process__stair.is-drawn .process__lines path {
  stroke-dashoffset: 0;
}
.process__stair.is-drawn .process__lines circle {
  opacity: 1;
  transform: scale(1);
}

.process__steps {
  position: relative;
  z-index: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(1.4rem, 3vw, 2.6rem);
}

.process-step {
  position: relative;
  padding-left: clamp(1.7rem, 2.4vw, 2.3rem);
  max-width: 30rem;
}
.process-step:nth-child(2) { margin-left: var(--stair-inc); }
.process-step:nth-child(3) { margin-left: calc(var(--stair-inc) * 2); }
.process-step:nth-child(4) { margin-left: calc(var(--stair-inc) * 3); }

.process-step__name {
  margin: 0 0 0.45rem;
  font-size: clamp(1.1rem, 1.4vw, 1.35rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.2;
  color: var(--ink);
}

.process-step__what {
  margin: 0;
  font-size: clamp(0.96rem, 1.05vw, 1.08rem);
  font-weight: 500;
  line-height: 1.45;
  color: var(--ink-soft);
}

/* Móvil: la escalera se aplana (sin indent) para no salirse de pantalla;
   queda una lista vertical limpia. El JS recalcula la línea recta. */
@media (max-width: 600px) {
  .process-step:nth-child(2),
  .process-step:nth-child(3),
  .process-step:nth-child(4) {
    margin-left: 0;
  }
}

.services__lede {
  margin: 0 0 clamp(2rem, 4vw, 3rem);
  max-width: 44ch;
  color: var(--ink-soft);
  font-size: clamp(0.95rem, 1.05vw, 1.08rem);
  line-height: 1.55;
}

.services__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(24px, 3vw, 56px);
  max-width: 86rem;
  margin-inline: auto;
  width: 100%;
}

.service {
  display: grid;
  gap: 1.1rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--line-strong);
}

.service h3 {
  margin: 0;
  font-size: clamp(1.55rem, 2.15vw, 2.25rem);
  letter-spacing: -0.025em;
  font-weight: 600;
  color: var(--accent-deep);
  line-height: 1.1;
}

/* Última palabra solo en itálica — hereda el mismo celeste del h3, así el
   título es de UN solo color (sin contraste de dos tonos). */
.service h3 em {
  font-style: italic;
}

.service p {
  margin: 0;
  font-size: clamp(1.02rem, 1.18vw, 1.22rem);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 32ch;
}

/* ── Tablet: 2×2 para que respire ── */
@media (max-width: 980px) {
  .services__list {
    grid-template-columns: repeat(2, 1fr);
    gap: 28px;
    max-width: 44rem;
  }
}
/* ── Móvil: apilado ── */
@media (max-width: 540px) {
  .services__list {
    grid-template-columns: 1fr;
    gap: 22px;
    max-width: 28rem;
  }
}


/* ── Contacto · CARD DE CRISTAL sobre navy ────────────────────────────
   Form clásico (label arriba + input por línea) dentro de una CARD de
   vidrio: backdrop-filter blur grande, border claro fino, fondo
   translúcido para que el navy con sus halos se asome detrás. La idea
   es que el form se "plante" sobre el navy con presencia premium tipo
   Stripe/Linear, no que se funda con el fondo. */
/* Layout 2 columnas: izq título + canales (mail / whatsapp), der la
   mampara. Ambos arrancan al MISMO top (align-items: start). En mobile
   se apilan en una sola columna, card abajo. */
.contact__layout {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.1fr);
  gap: clamp(36px, 5vw, 88px);
  align-items: start;
}

.contact__head {
  display: grid;
  gap: 16px;
  text-align: left;
}

.contact__head h2 {
  margin: 0;
  margin-inline: 0;
  max-width: 14ch;
}

.contact__head .contact__lede {
  margin: 0;
  font-size: clamp(1rem, 1.1vw, 1.18rem);
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 36ch;
}

/* Canales directos (mail + WhatsApp) bajo el título. Cada uno es un
   link en bloque con label arriba y el valor grande tipo "firma".
   Hover: el valor se tinta celeste + underline crece. */
.contact__channels {
  display: grid;
  gap: clamp(18px, 2vw, 26px);
  margin-top: clamp(20px, 3vw, 32px);
  padding-top: clamp(20px, 3vw, 28px);
  border-top: 1px solid rgba(238, 242, 251, 0.18);
}

.contact-channel {
  display: grid;
  gap: 6px;
  text-decoration: none;
  color: inherit;
}

.contact-channel__label {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.contact-channel__value {
  font-family: var(--font-sans);
  font-weight: 600;
  font-style: italic;
  font-size: clamp(1.35rem, 2.2vw, 1.9rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
  width: max-content;
  max-width: 100%;
  padding-bottom: 4px;
  border-bottom: 1.5px solid transparent;
  transition: color 0.22s ease, border-color 0.22s ease;
}

.contact-channel:hover .contact-channel__value {
  color: var(--accent-deep);
  border-bottom-color: var(--accent-deep);
}

/* Card de cristal — MAMPARA DE BAÑO con vapor y sarro. La idea: una
   placa de vidrio empañada blanco-lechoso sobre el navy. Detrás se
   intuye el navy + halos pero todo está velado, blando, dulce. Sobre
   el vidrio aparecen manchas de vapor + granito blanco (el "sarro"),
   logradas con multi-stack de radial-gradients + una textura SVG
   blanca por encima. */
.glass-form {
  position: relative;
  width: 100%;
  padding: clamp(28px, 4vw, 52px);
  display: grid;
  gap: clamp(22px, 2.6vw, 30px);
  isolation: isolate; /* contiene los pseudo-elementos al border-radius */
  border-radius: 24px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  /* Re-tematizamos el INTERIOR de la card a texto oscuro porque ya no
     es navy: el cristal blanco-lechoso necesita tipografía navy para
     que se lea cómoda. Solo afecta lo de dentro de .glass-form. */
  --ink: #0F1A52;
  --ink-soft: rgba(15, 26, 82, 0.72);
  --ink-faint: rgba(15, 26, 82, 0.42);
  --line-strong: rgba(15, 26, 82, 0.18);
  color: var(--ink);
  /* Capa base del vidrio empañado (sin texturas — esas van en ::before
     y ::after). Gradiente blanco suave con dirección de vapor que sube. */
  background:
    /* vapor: nubes blancas más densas arriba */
    radial-gradient(120% 80% at 50% -10%, rgba(255, 255, 255, 0.55), transparent 70%),
    /* base blanca translúcida — el "fondo lechoso" del vidrio */
    linear-gradient(180deg, rgba(255, 255, 255, 0.42), rgba(255, 255, 255, 0.32));
  backdrop-filter: blur(28px) saturate(135%) brightness(1.05);
  -webkit-backdrop-filter: blur(28px) saturate(135%) brightness(1.05);
  /* Sombra ambiental + halo blanco brillante en el borde superior
     (el filo del cristal pegado a la luz). */
  box-shadow:
    0 50px 100px -40px rgba(0, 0, 0, 0.55),
    0 8px 32px -10px rgba(0, 0, 0, 0.25),
    inset 0 1px 0 rgba(255, 255, 255, 0.85),
    inset 0 -1px 0 rgba(15, 26, 82, 0.06);
}

/* Manchas de vapor — blobs blancos de distintos tamaños distribuidos
   por la card. Esto es lo que da el "no es plano, está empañado de
   verdad". */
.glass-form::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(160px 110px at 12% 18%, rgba(255, 255, 255, 0.55), transparent 70%),
    radial-gradient(220px 160px at 82% 30%, rgba(255, 255, 255, 0.42), transparent 72%),
    radial-gradient(180px 140px at 28% 72%, rgba(255, 255, 255, 0.38), transparent 70%),
    radial-gradient(200px 150px at 88% 86%, rgba(255, 255, 255, 0.5), transparent 72%),
    radial-gradient(140px 100px at 55% 45%, rgba(255, 255, 255, 0.3), transparent 70%);
  mix-blend-mode: screen;
  opacity: 0.9;
}

/* Sarro — granito blanco fino sobre el cristal. SVG inline con
   feTurbulence; mix-blend overlay para que los puntitos blancos se
   integren al cristal sin verse como ruido sucio. */
.glass-form::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='s'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.6 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23s)'/%3E%3C/svg%3E");
  background-size: 240px 240px;
  mix-blend-mode: overlay;
  opacity: 0.35;
}

/* Filas de 2 columnas (nombre/correo, marca/proyecto). */
.glass-form__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(18px, 2vw, 26px);
}

/* g-field = glass-field. Un label arriba + input/textarea abajo. */
.g-field {
  display: grid;
  gap: 8px;
  position: relative;
}

.g-field__label {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  transition: color 0.2s ease;
}

/* Inputs sobre la mampara: blanco MÁS sólido (más opaco que la card)
   para leer como "campos" claros y no fundirse con el vidrio. Texto
   navy oscuro, borde navy fino. */
.g-field input,
.g-field textarea {
  width: 100%;
  font: inherit;
  font-family: var(--font-sans);
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.62);
  border: 1px solid rgba(15, 26, 82, 0.14);
  border-radius: 12px;
  padding: 14px 16px;
  outline: none;
  transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.g-field textarea {
  min-height: 7em;
  line-height: 1.5;
  resize: vertical;
}

.g-field input::placeholder,
.g-field textarea::placeholder {
  color: rgba(15, 26, 82, 0.4);
  font-weight: 500;
}

.g-field input:hover,
.g-field textarea:hover {
  background: rgba(255, 255, 255, 0.78);
  border-color: rgba(15, 26, 82, 0.26);
}

.g-field:focus-within .g-field__label {
  color: var(--accent-deep);
}

.g-field input:focus,
.g-field textarea:focus {
  background: #ffffff;
  border-color: var(--accent-deep);
  box-shadow: 0 0 0 4px rgba(91, 155, 232, 0.22);
}

/* Footer del form: status izq, CTA der. CTA dentro de la mampara
   debe ser OSCURO (la card es blanca), no claro: invertimos el
   tratamiento del .contact .cta--dark que es claro por defecto. */
.glass-form__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding-top: clamp(6px, 1vw, 12px);
}

.glass-form__footer .contact-form__status {
  margin: 0;
  font-size: 0.92rem;
  color: var(--ink-soft);
}

.glass-form .cta--dark {
  background: #0F1A52;
  color: #ffffff;
  box-shadow: 0 18px 36px -16px rgba(15, 26, 82, 0.55);
}
.glass-form .cta--dark:hover {
  background: #1a2a78;
}

/* visually-hidden — utilidad para labels accesibles ocultos. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Sección Identidad — cierre con isotipo animado ──────────────── */
.identity {
  position: relative;
  z-index: 1;
  background: #f6f9fd;
  padding: clamp(80px, 10vw, 140px) var(--pad);
}

.identity__layout {
  max-width: var(--max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: clamp(24px, 4vw, 72px);
  align-items: center;
}

.identity__side {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 340px;
}

.identity__side--left {
  justify-self: start;
}

.identity__side--right {
  justify-self: end;
}

.identity__title {
  margin: 0;
  font-size: clamp(1.7rem, 2.6vw, 2.4rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.025em;
  color: var(--ink);
  text-wrap: balance;
}

.identity__title em {
  font-style: italic;
  font-weight: 600;
  color: var(--accent-deep);
}

.identity__caption {
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0;
}

.identity__body {
  margin: 0;
  font-size: 0.98rem;
  font-weight: 500;
  line-height: 1.55;
  color: var(--ink-soft);
}

.identity__detail {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding-top: 18px;
  border-top: 1px solid var(--line-strong);
}
.identity__detail strong {
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent-deep);
}
.identity__detail span {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--ink);
}

/* Isotipo animado */
.identity__stage {
  width: clamp(220px, 27vw, 340px);
  height: clamp(220px, 27vw, 340px);
}

.identity__stage svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

.identity__isotype {
  color: var(--ink);
}

/* Isotipo REAL de Borabe (mismos paths exactos que el header): 2 arcos
   (.identity__sat) + círculo (.identity__core), entrelazados. Tras el
   dibujado de entrada el JS quita el dash → trazos sólidos y CERRADOS (el
   dash dejaba un hueco en el punto de cierre del círculo, ~3 en punto). */

@media (max-width: 860px) {
  .identity__layout {
    grid-template-columns: 1fr;
    gap: 32px;
    text-align: center;
  }
  .identity__side--left,
  .identity__side--right {
    justify-self: center;
    align-items: center;
    max-width: 420px;
  }
  .identity__side--left .section-label,
  .identity__side--left .identity__title,
  .identity__side--right .identity__caption {
    text-align: center;
  }
  .identity__stage {
    order: -1;
    justify-self: center;
  }
  .identity__detail {
    justify-content: center;
  }
}

.footer {
  padding: clamp(56px, 6vw, 84px) var(--pad) clamp(24px, 3vw, 32px);
  /* fondo navy + granito definido en el tema navy (.contact, .footer) */
}

.footer__inner {
  max-width: var(--max);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: clamp(32px, 4vw, 52px);
}

/* banda superior: voz (izq) + utilidad (der) */
.footer__top {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: clamp(32px, 5vw, 72px);
  padding-bottom: clamp(28px, 3.5vw, 40px);
  border-bottom: 1px solid var(--line-strong);
}

.footer__voice {
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2vw, 24px);
}

/* lockup: isotipo + Borabe → elemento grande, arriba del statement
   (bookend del lockup chico del topbar) */
.footer__lockup {
  display: flex;
  align-items: center;
  gap: clamp(12px, 1.6vw, 22px);
  color: var(--ink);
  padding: 0.08em 0;
}

.footer__lockmark {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--ink);
}

.footer__lockmark svg {
  width: clamp(2.6rem, 4.6vw, 4.4rem);
  height: auto;
  transition: transform 1.1s cubic-bezier(0.16, 1, 0.3, 1);
}

.footer__lockup:hover .footer__lockmark svg {
  transform: rotate(360deg);
}

.footer__wordmark {
  font-family: var(--font-serif);
  font-weight: 600;
  line-height: 0.95;
  letter-spacing: -0.04em;
  font-size: clamp(2.6rem, 5vw, 4.6rem);
  color: var(--ink);
}

/* statement → secundario, más pequeño bajo el lockup */
.footer__statement {
  margin: 0;
  max-width: 32ch;
  font-size: clamp(1.05rem, 1.6vw, 1.45rem);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink-soft);
  text-wrap: balance;
}

.footer__statement em {
  font-style: italic;
  font-weight: 500;
  color: var(--accent-deep);
}

/* utilidad: navegación + contacto */
.footer__utility {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(40px, 5vw, 80px);
}

.footer__group {
  display: flex;
  flex-direction: column;
  gap: 11px;
}

.footer__grouplabel {
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 5px;
}

.footer__link {
  color: var(--ink);
  text-decoration: none;
  font-size: 0.98rem;
  font-weight: 500;
  line-height: 1.3;
  width: fit-content;
  transition: color 0.2s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.footer__link:hover {
  color: var(--accent-deep);
  transform: translateX(3px);
}

.footer__muted {
  color: var(--ink-soft);
  font-size: 0.92rem;
  font-weight: 500;
  line-height: 1.3;
}

/* meta inferior (fino) — sin raya propia; la única línea es la del top */
.footer__meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px 24px;
  color: var(--ink-faint);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.reveal,
.service,
.case,
.proof-card,
.sig-panel,
.manifesto,
.glass-form,
.contact__head,
[data-reveal="words"] {
  opacity: 0;
  transform: translateY(24px);
  will-change: opacity, transform;
}

/* Signature: el slide del panel cubre el hero; las letras animan EN PARALELO
   con el slide (controladas por JS: fireIntent agrega .is-visible al inicio).
   Override: entrada horizontal desde la izquierda + fade, sin clip vertical. */
.signature {
  opacity: 1;
}

/* El panel oculta el overflow horizontal para que las letras puedan entrar
   desde fuera del viewport sin generar scrollbar. */
.signature {
  overflow-x: hidden;
}

/* Reveal en signature: fade in en su lugar final, sin slide horizontal.
   El movimiento del slide era la sección entera subiendo — los textos solo
   aparecen, no se desplazan. */
.signature [data-reveal="words"],
.signature .reveal {
  opacity: 0;
  transform: none;
  transition: opacity 0.9s var(--ease);
}

.signature [data-reveal="words"].is-visible,
.signature .reveal.is-visible {
  opacity: 1;
}

.signature .word {
  overflow: visible;
  padding-bottom: 0;
  margin-bottom: 0;
}

/* Sobrescribe la regla global .is-visible .word__inner (línea ~2696) que
   hace que cada palabra del título haga slide vertical 110%→0%. En el
   signature queremos que las palabras NO se muevan — solo que el título
   completo haga fade vía .reveal. */
.signature .word__inner,
.signature [data-reveal="words"].is-visible .word__inner {
  transform: none !important;
  opacity: 1 !important;
  transition: none !important;
}

/* Entradas direccionales — "sale de los lados" tipo akaru */
[data-reveal-from="left"] {
  transform: translate3d(-80px, 16px, 0);
}

[data-reveal-from="right"] {
  transform: translate3d(80px, 16px, 0);
}

.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: opacity 0.9s var(--ease), transform 1.1s var(--ease);
}

/* Para cards grandes (cases) — entrada más pronunciada */
.case[data-reveal-from] {
  transition-delay: 0.05s;
}

.case[data-reveal-from="left"] {
  transform: translate3d(-120px, 0, 0);
}

.case[data-reveal-from="right"] {
  transform: translate3d(120px, 0, 0);
}

/* Stagger en proof-cards */
.proof-card:nth-child(1) { transition-delay: 0s; }
.proof-card:nth-child(2) { transition-delay: 0.12s; }
.proof-card:nth-child(3) { transition-delay: 0.24s; }

/* Stagger en los 4 servicios */
.services__list .service:nth-child(1) { transition-delay: 0s; }
.services__list .service:nth-child(2) { transition-delay: 0.09s; }
.services__list .service:nth-child(3) { transition-delay: 0.18s; }
.services__list .service:nth-child(4) { transition-delay: 0.27s; }

/* Pillars: fade-in stagger en su lugar (sin slide). */
.signature__pillars li {
  opacity: 0;
  transform: none;
  transition: opacity 0.7s var(--ease);
}
.signature__pillars li:nth-child(1) { transition-delay: 0.05s; }
.signature__pillars li:nth-child(2) { transition-delay: 0.15s; }
.signature__pillars li:nth-child(3) { transition-delay: 0.25s; }
.signature__pillars.is-visible li {
  opacity: 1;
}

/* === Estudio · Variante A — cards + profundidad de fondo === */
/* Glow radial azul-gris detrás del título. Tamaño grande (920px); el ancho
   se topa al viewport para no provocar scroll horizontal. En post-intro el
   panel deja de recortar (overflow:visible), así el glow se extiende hacia
   abajo y se desvanece solo en el negro de la extensión — sin "luz mocha". */
.signature::before {
  content: "";
  position: absolute;
  top: -6%;
  left: 50%;
  width: min(900px, 96vw);
  /* altura relativa al viewport → el glow SIEMPRE se desvanece dentro del
     panel de Estudio, nunca llega al borde donde empieza el negro de .work
     (que lo recortaría = "luz mocha"). transparent 52% lo contiene aún más. */
  height: min(900px, 66dvh);
  transform: translateX(-50%);
  background: radial-gradient(circle at 50% 46%, rgba(91, 155, 232, 0.22), transparent 54%);
  pointer-events: none;
  z-index: 0;
}

/* Difuminado del borde inferior — el panel negro se funde hacia
   la sección Resultado en vez de cortar en línea recta */
/* La transición ya no vive en el Estudio: ahora el negro se "agrega" sobre
   el blanco desde el borde superior de .work (ver regla .work::before). */

/* Pilares — línea "blueprint": cada concepto cuelga de la hairline superior
   con un tick celeste. Sin cajas; jerarquía por tipografía. */
.signature__pillars li {
  flex: 1 1 0%;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  max-width: none;
  min-width: 0;
  padding: 26px 0 0;
  position: relative;
  cursor: default;
  transition:
    opacity 0.7s var(--ease),
    transform 0.4s var(--ease);
}

/* Tick celeste colgando de la línea, centrado sobre cada pilar; crece en hover */

/* Palabra-concepto (Intención / Jerarquía / Presencia): grande, peso 600;
   se vuelve celeste italic en hover. */
.signature__pillars li .signature__pillar-num {
  font-family: var(--font-sans);
  font-size: clamp(1.3rem, 2vw, 1.7rem);
  font-weight: 600;
  font-style: italic;
  letter-spacing: -0.01em;
  text-transform: none;
  line-height: 1;
  padding: 0;
  color: #eef2fb;
  transition: color 0.3s ease;
}
/* Hover: la palabra NO cambia (ni color ni itálica); solo se alarga el tick. */

.signature__pillars li .signature__pillar-text {
  font-size: 1rem;
  line-height: 1.45;
}

/* Móvil: la fila se apila con su propia hairline por pilar */
@media (max-width: 680px) {
  .signature__pillars {
    flex-direction: column;
    gap: 0;
    border-top: 0;
  }
  .signature__pillars li {
    padding: 22px 0;
    border-top: 1px solid rgba(91, 155, 232, 0.45);
  }
  .signature__pillars li:first-child {
    border-top: 0;
  }
}

[data-reveal="words"] {
  transform: none;
}

.word {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  /* Padding vertical para ascenders/descenders en los reveals con slide-up.
     Margin negativo IGUAL al padding → clip area expandida, layout intacto. */
  padding-top: 0.25em;
  padding-bottom: 0.25em;
  margin-top: -0.25em;
  margin-bottom: -0.25em;
}

/* IMPORTANTE — para los títulos de section-headline y contact__head,
   el reveal usa opacity-only (sin slide). No overflow, no clip, nunca
   recorta ascenders. Esta es la regla DEFINITIVA contra el corte de
   "Cuatro piezas." y similares (feedback-no-cortes-secciones). */
.section-headline .word,
.contact__head .word {
  overflow: visible;
  padding-top: 0;
  padding-bottom: 0;
  margin-top: 0;
  margin-bottom: 0;
}
.section-headline .word__inner,
.contact__head .word__inner {
  transform: none !important;
  opacity: 0;
  transition: opacity 0.9s var(--ease);
}
.section-headline [data-reveal="words"].is-visible .word__inner,
.contact__head [data-reveal="words"].is-visible .word__inner {
  opacity: 1;
}

.word__inner {
  display: inline-block;
  transform: translateY(110%);
  transition: transform 1.3s var(--ease);
}

.is-visible .word__inner {
  transform: translateY(0);
}

@keyframes spin {
  to {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}

@keyframes spinReverse {
  to {
    transform: translate(-50%, -50%) rotate(-360deg);
  }
}

@keyframes ticker {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

@media (max-width: 1140px) {
  .hero__layout,
  .signature__layout,
  .contact__layout {
    grid-template-columns: 1fr;
  }

  .contact__head {
    max-width: 38rem;
  }

  .hero__stage {
    min-height: 540px;
  }

  .work__layout {
    grid-template-columns: 1fr;
  }

  .case--feature {
    grid-row: auto;
  }

  .case--feature .case__visual {
    min-height: 300px;
  }

  .proof__grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 860px) {
  .topbar {
    grid-template-columns: auto 1fr auto;
  }

  .topnav {
    display: none;
  }

  .topbar__cta {
    display: none;
  }

  .nav-toggle {
    display: inline-flex;
  }

  .hero__layout {
    gap: 1.2rem;
  }

  .hero__title {
    max-width: none;
  }

  .hero__stage {
    grid-template-columns: 1fr;
    min-height: auto;
    transform: none;
  }

  .hero__column--tall,
  .hero__column--wide {
    padding: 0;
  }

  .hero-block--feature {
    min-height: 340px;
  }

  .hero__metrics,
  .signature__grid {
    grid-template-columns: 1fr;
  }

  /* Card de cristal: las filas de 2 columnas se apilan en una sola en
     mobile, y el footer del form también baja a columna. */
  .glass-form__row {
    grid-template-columns: 1fr;
  }

  .glass-form__footer {
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .glass-form__footer .cta {
    justify-content: center;
  }

  .glass-form__footer .contact-form__status {
    text-align: center;
  }

  .footer__top {
    flex-direction: column;
  }

  .footer__meta {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (max-width: 560px) {
  .footer__utility {
    gap: 32px;
  }
}

@media (max-width: 560px) {
  .topbar {
    top: 10px;
    width: calc(100% - 14px);
    padding: 12px;
  }

  .brand__word {
    font-size: 1.55rem;
  }

  .hero {
    padding-top: 108px;
    padding-bottom: 96px;
  }

  .hero__title {
    font-size: clamp(2rem, 8.5vw, 3rem);
    line-height: 1.04;
  }

  .hero-block,
  .manifesto,
  .sig-panel,
  .case {
    border-radius: 24px;
  }

  .hero__subgrid {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation: none !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }

  .reveal,
  .service,
  .case,
  .proof-card,
  .sig-panel,
  .manifesto,
  .glass-form,
  .contact__head,
  [data-reveal="words"],
  .word__inner {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ================================================================
   STAGE TRANSITION — intro (hero + slide del estudio) → main page
   Cuando el slide del estudio termina y el usuario empuja un poco más,
   se dispara una transición: overlay beige cubre, hero desaparece,
   estudio queda como sección 1 normal (sin pin/sticky), scroll a 0.
   Solo refresh restaura la intro.
   ================================================================ */

/* Crossfade nativo del browser para la transición intro → main page.
   Las pseudo-elementos ::view-transition-old/new controlan el fade. */
@supports (view-transition-name: none) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.55s;
    animation-timing-function: var(--ease);
  }
}

/* Estado post-intro: hero fuera, estudio normalizado como sección normal */
body[data-stage="post-intro"] .hero {
  display: none !important;
}

body[data-stage="post-intro"] .signature-wrap {
  margin-top: 0 !important;
  height: auto !important;
  overflow: visible !important;
  /* El wrap = signature panel limpio, rectangular, sin recortes. La diagonal
     vive en .work::before (extiende hacia arriba al wrap y cae con clip-path
     hasta detrás de la card de proyectos). Así la transición es UNA sola
     masa negra continua, sin gaps ni bandas intermedias. */
  background: #0d0d0f;
  padding-bottom: 0;
}

body[data-stage="post-intro"] .signature {
  position: static !important;
  /* Altura fija = mismo alto que mientras se desliza (NO height:auto), para
     que el contenido centrado quede exactamente donde estaba y no se vea
     ningún reacomodo vertical al terminar de "instalarse" la sección.
     min-height fijado también para anular el min-height de la regla
     .section post-intro, que si no podría estirar la sección. */
  height: 100dvh !important;
  min-height: 100dvh !important;
  transform: translate3d(0, 0, 0) !important;
  will-change: transform;
  display: flex !important;
  flex-direction: row !important;
  align-items: center !important;
  justify-content: center !important;
  padding: clamp(60px, 8vw, 120px) clamp(28px, 4.5vw, 72px) !important;
  /* sin recorte vertical: el glow puede extenderse hacia abajo y fundirse en
     el negro de la extensión del wrap, en vez de cortarse en el borde. */
  overflow: visible !important;
}

/* Detrás del wrap, lo que la cascada (mask) deja transparente revela el
   fondo de main = celeste, unido sin costura a la sección .work. */
body[data-stage="post-intro"] main {
  background: #f6f9fd;
}

/* Cada sección post-intro = 1 pantalla completa (full width + 100vh).
   Sin huecos laterales, contenido centrado vertical. */
body[data-stage="post-intro"] .section,
body[data-stage="post-intro"] .work,
body[data-stage="post-intro"] .services,
body[data-stage="post-intro"] .proof,
body[data-stage="post-intro"] .contact,
body[data-stage="post-intro"] .identity {
  max-width: none !important;
  width: 100% !important;
  min-height: 100vh;
  margin-left: 0 !important;
  margin-right: 0 !important;
  padding-left: clamp(28px, 4.5vw, 72px);
  padding-right: clamp(28px, 4.5vw, 72px);
  padding-top: clamp(40px, 5vw, 72px);
  padding-bottom: clamp(40px, 5vw, 72px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Resultado: padding-top 0 → port__sticky (con el negro pinneado) arranca
   justo donde termina Estudio, sin gap celeste entre el negro de Estudio
   y el negro de la diagonal. Cierra con menos aire abajo. */
body[data-stage="post-intro"] .work {
  justify-content: flex-start;
  padding-top: 0;
  padding-bottom: clamp(20px, 3vw, 48px);
}

/* Identidad es la CARD dentro del track: anula el comportamiento de
   sección full-height (min-height 100vh) para que llene el sticky y el
   JS la pueda encoger. La specificity (0,3,1) gana sobre la regla combo. */
body[data-stage="post-intro"] .reveal-track .identity {
  min-height: 0;
  height: 100%;
  padding-top: clamp(50px, 8vh, 110px);
  padding-bottom: clamp(50px, 8vh, 110px);
}

/* El negro de Resultado vive en .port__sticky (pinned por port__track).
   Así tiene RELEASE NATURAL: cuando el showcase termina y port__track
   scrollea hasta el final, .port__sticky se suelta y el negro se va CON
   la sección → la siguiente sección queda limpia, sin negro pegado.
   .port__sticky full-bleed (margin negativo rompe el padding de .work)
   → el negro va de lado a lado, sin orillas blancas. */
body[data-stage="post-intro"] .port__sticky {
  margin-left: calc(-1 * clamp(28px, 4.5vw, 72px));
  margin-right: calc(-1 * clamp(28px, 4.5vw, 72px));
}

/* Diagonal negra con borde DEGRADADO (SVG mask + feGaussianBlur). El path
   se extiende fuera del viewBox (-60 / 1260) para que solo el borde
   diagonal inferior se difumine, no el techo ni los lados. Cae de izq
   (32%) a der (50%). z-index 0 → card y título van encima. */
body[data-stage="post-intro"] .port__sticky::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 100%;
  background: #0d0d0f;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 1000' preserveAspectRatio='none'><defs><filter id='softdiag' x='-20%' y='-20%' width='140%' height='140%'><feGaussianBlur stdDeviation='17'/></filter></defs><path fill='white' filter='url(%23softdiag)' d='M-60,-60 H1260 V450 Q600,430 -60,260 Z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 1000' preserveAspectRatio='none'><defs><filter id='softdiag' x='-20%' y='-20%' width='140%' height='140%'><feGaussianBlur stdDeviation='17'/></filter></defs><path fill='white' filter='url(%23softdiag)' d='M-60,-60 H1260 V450 Q600,430 -60,260 Z'/></svg>");
  -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  pointer-events: none;
  z-index: 0;
}

/* port__head (z-index 2) y port__deck (z-index 1) ya vienen por encima
   del negro (z-index 0) desde el CSS base — el título sigue flotando
   sobre la card. No hace falta override.

   Como .port__sticky es full-bleed, el contenido centrado necesita su
   propio padding lateral para no pegar a los bordes en pantallas angostas. */
body[data-stage="post-intro"] .port__head,
body[data-stage="post-intro"] .port__stage {
  padding-left: clamp(28px, 4.5vw, 72px);
  padding-right: clamp(28px, 4.5vw, 72px);
}

/* El bloque del proyecto queda alineado con la card (centrado), sin empuje
   extra que lo bajara hasta cortarse abajo. */
body[data-stage="post-intro"] .port__info {
  transform: none;
}

/* Título y label en colores claros — mismo lenguaje que Estudio.
   Quedan VISIBLES sobre el negro pinneado. Al scrollear, el título
   sube vía .is-tucked (transform translateY) mientras el negro queda
   estático. La italic blue (em) mantiene su color propio. */
body[data-stage="post-intro"] .work .port__title {
  color: #eef2fb;
}
body[data-stage="post-intro"] .work .port__head .section-label {
  color: rgba(238, 242, 251, 0.55);
}

/* Servicios — sección con contenido CENTRADO verticalmente para que el
   título nunca quede en el borde superior del viewport. scroll-margin-top
   asegura que los anclajes (#servicios) dejen aire arriba para el topbar
   y no peguen el título al techo. Ver feedback-no-cortes-secciones. */
body[data-stage="post-intro"] .services {
  justify-content: center;
  padding-top: clamp(110px, 14vh, 200px);
  padding-bottom: clamp(80px, 10vh, 160px);
  scroll-margin-top: 110px;
}

/* En post-intro: cuando el observer agrega .is-visible, forzamos a final
   state. La specificity de .case[data-reveal-from] (0,2,1) gana sobre
   .is-visible (0,1,0), por eso necesitamos esta regla más específica.
   Importante: NO forzamos a final state sin .is-visible → respetamos
   la animación de entrada cuando el observer dispara. */
body[data-stage="post-intro"] .case[data-reveal-from].is-visible,
body[data-stage="post-intro"] [data-reveal-from].is-visible,
body[data-stage="post-intro"] .reveal.is-visible,
body[data-stage="post-intro"] [data-reveal="words"].is-visible {
  transform: translate3d(0, 0, 0) !important;
  opacity: 1 !important;
}

/* Subir contraste de textos del Estudio en post-intro (sobre bg #0d0d0f).
   Hay un conflicto con la definición de línea 1401 que pinta el title en
   var(--ink) (oscuro). Forzamos paleta cream/oro. */
body[data-stage="post-intro"] .signature__title {
  color: #eef2fb !important;
}

body[data-stage="post-intro"] .signature__title em {
  color: #eef2fb !important;
}

body[data-stage="post-intro"] .signature__lede {
  color: rgba(238, 242, 251, 0.92) !important;
}

body[data-stage="post-intro"] .signature__lede strong {
  color: #eef2fb !important;
}

body[data-stage="post-intro"] .signature__pillar-text {
  color: rgba(238, 242, 251, 0.7);
}

body[data-stage="post-intro"] .signature__pillar-num {
  color: #eef2fb;
}

body[data-stage="post-intro"] .signature .section-label {
  color: rgba(238, 242, 251, 0.78);
}
