/* TOKENS */
:root {
  --black: #15120D;
  --black-soft: #1E1911;
  --black-card: #241E14;
  --hairline-dark: #3C3323;
  --cream: #F4EDE1;
  --cream-deep: #ECE2CD;
  --paper: #FAF6EE;
  --ink: #1C1812;
  --ink-soft: #4A4238;
  --muted: #8C8171;
  --gold: #B8863E;
  --gold-bright: #D1A256;
  --gold-dim: #8A6530;
  --hairline-light: #DED2BC;
  --white: #FFFFFF;

  --font-display: 'Bodoni Moda', 'Times New Roman', serif;
  --font-body: 'Manrope', -apple-system, sans-serif;

  --ease-motion: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-color: cubic-bezier(0.4, 0, 0.2, 1);
  --dur-hover: 220ms;
  --dur-tap: 140ms;

  --pad-inline: clamp(24px, 5vw, 96px);
  --wrap-max: 1600px;
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; background: var(--black); }
body {
  background: var(--black);
  color: var(--cream);
  font-family: var(--font-body);
  font-weight: 400;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--gold); color: var(--black); }
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
button { font: inherit; cursor: pointer; background: none; border: none; color: inherit; }

a:focus-visible, button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
}

/* full-bleed section + inner wrap: NO global container max-width */
.wrap {
  max-width: var(--wrap-max);
  margin: 0 auto;
  padding-inline: var(--pad-inline);
  position: relative;
}
section { padding-block: clamp(72px, 11vw, 160px); position: relative; }
section[id] { scroll-margin-top: 88px; }
.bg-dark { background: var(--black); color: var(--cream); }
.bg-light { background: var(--cream); color: var(--ink); }
.bg-paper { background: var(--paper); color: var(--ink); }

/* TYPE */
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 500; letter-spacing: -0.01em; line-height: 1.02; }
em, .italic { font-style: italic; }

/* Section head system: dramatic scale (64–110px on desktop), secondary text small */
.sec-head { margin-bottom: clamp(56px, 7vw, 96px); max-width: 1080px; }
/* Ceiling 4rem = 64px (project override, tighter than house-style's 72px):
   section headings must not exceed two lines on desktop. */
.sec-title { font-size: clamp(2.25rem, 4.1vw, 4rem); line-height: 1.06; letter-spacing: -0.015em; }
.bg-dark .sec-title { color: var(--cream); }
.sec-lede { margin-top: 26px; }

.eyebrow-hero {
  display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--font-body); font-size: 12px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--gold-bright); margin-bottom: 28px;
}
.eyebrow-hero::before { content: ''; width: 28px; height: 1px; background: var(--gold); }

.lede { font-size: 1.05rem; line-height: 1.65; font-weight: 300; max-width: 46ch; }
.bg-dark .lede { color: rgba(244, 237, 225, 0.72); }
.bg-light .lede, .bg-paper .lede { color: var(--ink-soft); }

/* NAV: hidden at rest, appears with scroll hysteresis. transform + opacity only. */
.site-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 200;
  padding: 22px var(--pad-inline);
  display: flex; align-items: center; justify-content: space-between;
  background: rgba(21, 18, 13, 0.86);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--hairline-dark);
  opacity: 0;
  transform: translateY(-16px);
  pointer-events: none;
  transition: opacity 420ms var(--ease-motion), transform 420ms var(--ease-motion);
}
.site-nav.is-visible { opacity: 1; transform: translateY(0); pointer-events: auto; }

.brand { display: inline-flex; align-items: center; gap: 12px; }
.brand-mark { width: 26px; height: 26px; position: relative; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.brand-mark::before { content: ''; position: absolute; inset: 0; border: 1.5px solid var(--gold); transform: rotate(45deg); transition: border-color var(--dur-hover) var(--ease-color); }
.brand-mark::after { content: ''; width: 5px; height: 5px; background: var(--gold); border-radius: 50%; transition: background var(--dur-hover) var(--ease-color); }
.brand-word { font-family: var(--font-display); font-weight: 500; font-size: 19px; color: var(--cream); transition: color var(--dur-hover) var(--ease-color); }
/* Colour-only hovers are gated too: on touch an ungated :hover sticks after
   the tap and leaves the element looking permanently focused. */
@media (hover: hover) and (pointer: fine) {
  .brand:hover .brand-mark::before { border-color: var(--gold-bright); }
  .brand:hover .brand-mark::after { background: var(--gold-bright); }
  .brand:hover .brand-word { color: var(--white); }
}

.nav-links { display: flex; align-items: center; gap: 36px; list-style: none; }
.nav-links a { font-size: 13px; letter-spacing: 0.03em; color: rgba(244,237,225,0.68); position: relative; padding-bottom: 5px; transition: color 200ms var(--ease-color); }
.nav-links a::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--gold); transform: scaleX(0); transform-origin: left; transition: transform 200ms var(--ease-motion); }
@media (hover: hover) and (pointer: fine) {
  .nav-links a:hover { color: var(--cream); }
  .nav-links a:hover::after { transform: scaleX(1); }
}

.nav-cta { display: inline-flex; align-items: center; gap: 8px; padding: 10px 18px; border: 1px solid var(--gold-dim); color: var(--gold-bright); font-size: 12px; letter-spacing: 0.04em; transition: border-color var(--dur-hover) var(--ease-color), background var(--dur-hover) var(--ease-color), box-shadow var(--dur-hover) var(--ease-color), transform 210ms var(--ease-motion); }
.nav-cta svg { width: 14px; height: 14px; }

.nav-toggle { display: none; width: 36px; height: 36px; align-items: center; justify-content: center; color: var(--cream); transition: color var(--dur-hover) var(--ease-color), transform 210ms var(--ease-motion); }
.nav-toggle svg { width: 20px; height: 20px; }
.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded="true"] .icon-open { display: none; }
.nav-toggle[aria-expanded="true"] .icon-close { display: block; }

.mobile-panel { position: fixed; inset: 0; z-index: 190; background: var(--black); display: flex; flex-direction: column; padding: 100px 28px 40px; transform: translateX(100%); transition: transform 420ms var(--ease-motion); }
.mobile-panel.open { transform: translateX(0); }
.mobile-panel ul { list-style: none; display: flex; flex-direction: column; gap: 2px; }
/* Scoped to the list so it can't override the panel CTA's own text colour
   (an unscoped `.mobile-panel a` outranks `.btn-gold` and leaves cream-on-gold). */
.mobile-panel ul a {
  display: block;
  font-family: var(--font-display); font-size: 2rem; font-weight: 500;
  padding: 13px 0; border-bottom: 1px solid var(--hairline-dark); color: var(--cream);
  transition: color var(--dur-hover) var(--ease-color), border-color var(--dur-hover) var(--ease-color), transform var(--dur-tap) var(--ease-motion);
}
@media (hover: hover) and (pointer: fine) {
  .mobile-panel ul a:hover { color: var(--gold-bright); border-color: var(--gold-dim); }
}
@media (prefers-reduced-motion: no-preference) {
  .mobile-panel ul a:active { transform: scale(0.94); }
}
.mobile-panel .nav-cta { margin-top: 36px; align-self: flex-start; padding: 15px 26px; font-size: 12.5px; }

/* BUTTONS */
.btn {
  display: inline-flex; align-items: center; gap: 11px;
  padding: 17px 30px; font-size: 12.5px; letter-spacing: 0.05em; text-transform: uppercase;
  border: 1px solid transparent;
  transition:
    background var(--dur-hover) var(--ease-color),
    color var(--dur-hover) var(--ease-color),
    border-color var(--dur-hover) var(--ease-color),
    box-shadow var(--dur-hover) var(--ease-color),
    transform 210ms var(--ease-motion);
}
.btn svg { width: 16px; height: 16px; transition: transform var(--dur-hover) var(--ease-motion); }
.btn-gold { background: var(--gold); color: var(--black); border-color: var(--gold); }
.btn-line { background: transparent; color: var(--white); border-color: rgba(255,255,255,0.32); }
.btn-ink { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* Hover feedback, calibrated by hierarchy. Gated to fine pointers so a tap on
   touch never leaves an element stuck in its hover state.
   On near-black grounds a neutral shadow is invisible, so the "growing shadow"
   is rendered as a gold glow with a real offset — never a zero-offset halo. */
@media (hover: hover) and (pointer: fine) {
  /* Primary CTA: brightening fill + strongest glow */
  .btn-gold:hover {
    background: var(--gold-bright); border-color: var(--gold-bright);
    box-shadow: 0 12px 30px -10px rgba(184, 134, 62, 0.6);
  }
  /* Secondary / outline: deliberately quieter */
  .btn-line:hover {
    border-color: var(--gold); color: var(--gold-bright);
    box-shadow: 0 8px 22px -12px rgba(184, 134, 62, 0.4);
  }
  /* Nav CTA is an outline button at nav scale: quietest of the three */
  .nav-cta:hover {
    border-color: var(--gold); background: rgba(184, 134, 62, 0.1);
    box-shadow: 0 6px 18px -10px rgba(184, 134, 62, 0.5);
  }
  .nav-toggle:hover { color: var(--gold-bright); }
}

/* The spatial half of the same hover, split out so reduced-motion keeps the
   colour and glow above while losing only the movement. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .btn-gold:hover { transform: translateY(-3px); }
  .btn-gold:hover svg { transform: translateX(3px); }
  .btn-line:hover { transform: translateY(-2px); }
  .nav-cta:hover { transform: translateY(-1px); }
  .nav-toggle:hover { transform: scale(1.07); }   /* icon button: scale, no lift */
}

/* Tap feedback. After the hover rules so a press always wins over a lift. */
@media (prefers-reduced-motion: no-preference) {
  .btn:active, .nav-cta:active, .nav-toggle:active, .brand:active,
  .nav-links a:active, .footer-col a:active {
    transform: scale(0.94);
    transition: transform var(--dur-tap) var(--ease-motion);
  }
}

/* CONTACTO FLOTANTE
   Píldora con texto, no un círculo con ícono: el glifo solo obliga a adivinar
   qué hace. Esquinas cuadradas como todo lo demás. Oculto hasta pasar el hero
   —con la misma histéresis del nav— para no duplicar el CTA que ya está visible
   arriba. Anima transform y opacity, nunca display ni width. */
.float-cta {
  position: fixed; right: clamp(18px, 2.4vw, 34px); bottom: clamp(18px, 2.4vw, 34px);
  z-index: 180;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 14px 20px;
  background: var(--gold); color: var(--black);
  border: 1px solid var(--gold);
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
  box-shadow: 0 12px 30px -12px rgba(0, 0, 0, 0.55);
  opacity: 0; transform: translateY(14px); pointer-events: none;
  transition:
    opacity 320ms var(--ease-color),
    transform 320ms var(--ease-motion),
    background var(--dur-hover) var(--ease-color),
    color var(--dur-hover) var(--ease-color),
    box-shadow var(--dur-hover) var(--ease-color);
}
.float-cta.is-visible { opacity: 1; transform: translateY(0); pointer-events: auto; }
.float-cta svg { width: 17px; height: 17px; flex-shrink: 0; }

@media (hover: hover) and (pointer: fine) {
  /* CTA primario: se aclara y la sombra crece. */
  .float-cta:hover { background: var(--gold-bright); border-color: var(--gold-bright); box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.68); }
}
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .float-cta:hover { transform: translateY(-3px); }
}
@media (prefers-reduced-motion: no-preference) {
  .float-cta:active { transform: scale(0.94); transition: transform var(--dur-tap) var(--ease-motion); }
}
/* Con reduced-motion no se desliza al entrar: solo aparece. */
@media (prefers-reduced-motion: reduce) {
  .float-cta { transform: none; transition: opacity 320ms var(--ease-color), background var(--dur-hover) var(--ease-color); }
  .float-cta.is-visible { transform: none; }
}
/* En pantalla estrecha el texto SE QUEDA —es lo que lo hace legible—, solo
   encoge el espaciado. */
@media (max-width: 560px) {
  .float-cta { padding: 12px 16px; font-size: 11.5px; gap: 8px; }
  .float-cta svg { width: 15px; height: 15px; }
}
/* Mientras el panel móvil está abierto estorba y compite con su propio CTA. */
.mobile-panel.open ~ .float-cta { opacity: 0; pointer-events: none; }

/* HERO */
.hero {
  position: relative;
  min-height: 100vh;
  display: flex; align-items: center;
  padding-top: clamp(120px, 14vh, 180px);
  overflow: hidden;
  /* Dos pozos de luz cálida, ambos dorados. El primero está donde se apoya la
     marca; era verde esmeralda porque existía para iluminar el cristal 3D, y
     al retirarse el cristal quedó como un segundo tono sin dueño. Vuelve al
     único acento del sistema. */
  background:
    radial-gradient(ellipse 80% 60% at 78% 45%, rgba(184,134,62,0.11), transparent 60%),
    radial-gradient(ellipse 60% 50% at 15% 80%, rgba(184,134,62,0.09), transparent 60%),
    var(--black);
}
/* Trazos del hero: la segunda capa de movimiento que pide la regla de portada
   con vida (la primera es la entrada escalonada de .hero-copy). Opacidad muy
   baja y deriva de 48 y 63 segundos —períodos primos entre sí, para que las dos
   capas no vuelvan a coincidir y el patrón nunca se lea como un bucle—.
   Solo transform, así que corre en el compositor y no toca el layout. */
.hero-lines {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  z-index: 0;
}
.hero-lines line, .hero-lines circle {
  fill: none;
  stroke: var(--gold);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.hero-lines .hl-drift-a { opacity: 0.09; animation: hl-a 48s ease-in-out infinite; }
.hero-lines .hl-drift-b { opacity: 0.055; animation: hl-b 63s ease-in-out infinite; }
@keyframes hl-a {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(-26px, 16px, 0); }
}
@keyframes hl-b {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(22px, -18px, 0); }
}
/* El contenido del hero va por encima de los trazos. */
.hero .wrap, .hero-mark, .scroll-cue { position: relative; z-index: 1; }

/* HERO MARK — the nav's diamond-and-dot at protagonist scale.
   Three nested elements, each owning exactly one transform, so the mouse tilt
   and the idle rotation can never overwrite one another:
   .hero-mark (position) > .hero-mark-tilt (JS mouse tilt) > .hero-mark-spin (CSS idle spin) */
.hero-mark {
  position: absolute; z-index: 1;
  top: 50%; right: clamp(24px, 8vw, 150px);
  transform: translateY(-50%);
  width: clamp(170px, 23vw, 330px); aspect-ratio: 1;
  pointer-events: none;
  perspective: 900px;
}
.hero-mark-tilt {
  width: 100%; height: 100%;
  transform-style: preserve-3d;
  /* Colour/UI curve, per house-style, for the pointer-driven tilt */
  transition: transform 280ms var(--ease-color);
}
.hero-mark-spin {
  position: relative;
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  animation: mark-spin 34s linear infinite;
}
/* The diamond is a square rotated 45°, exactly as in the nav mark.
   inset 18% keeps the rotated square's diagonal inside the box (a 45° rotation
   multiplies the footprint by √2, so a smaller inset would clip the points).
   Stroke and dot are sized as a share of the box so the mark keeps the nav
   logo's proportions instead of thinning into a hairline at hero scale. */
.hero-mark-diamond {
  position: absolute; inset: 18%;
  /* px/vw only — border-width rejects percentages, and an invalid value here
     silently drops the border to zero and the diamond vanishes entirely. */
  border: clamp(2.5px, 0.34vw, 5px) solid var(--gold);
  transform: rotate(45deg);
  transition: border-color 280ms var(--ease-color), box-shadow 280ms var(--ease-color);
}
.hero-mark-dot {
  position: relative;
  width: 13%; aspect-ratio: 1;
  background: var(--gold);
  border-radius: 50%;
  transition: background 280ms var(--ease-color), box-shadow 280ms var(--ease-color), transform 280ms var(--ease-color);
}
@keyframes mark-spin { to { transform: rotate(360deg); } }

/* Pointer proximity: brighter edge, and the gold dot lights up. */
.hero-mark.is-near .hero-mark-diamond {
  border-color: var(--gold-bright);
  box-shadow: 0 0 34px -6px rgba(184, 134, 62, 0.45);
}
.hero-mark.is-near .hero-mark-dot {
  background: var(--gold-bright);
  transform: scale(1.18);
  box-shadow: 0 0 22px 4px rgba(209, 162, 86, 0.55);
}

/* CTA echo: same mark, smaller, idle-only (no pointer tilt). */
.cta-mark {
  position: relative; justify-self: center;
  width: clamp(150px, 22vw, 260px); aspect-ratio: 1;
  pointer-events: none;
}

.hero .wrap { z-index: 2; width: 100%; }
/* Widened to match the reduced headline size: at 640px the smaller type broke
   "Sitios web que hacen" across two lines and left an orphan word. */
.hero-copy { max-width: 860px; }
/* Ceiling 5rem = 80px (project override, tighter than house-style's 88px). */
.hero h1 { font-size: clamp(2.5rem, 4.9vw, 5rem); color: var(--white); line-height: 1.06; margin-bottom: 30px; }
.hero h1 em { color: var(--gold-bright); font-style: italic; font-weight: 400; }
.hero .lede { color: rgba(255,255,255,0.76); font-size: 1.1rem; margin-bottom: 44px; }
.hero-ctas { display: flex; gap: 18px; flex-wrap: wrap; align-items: center; }

/* Orchestrated hero entrance: eyebrow → headline → lede → CTAs, blur-masked rise */
.hero-copy > * {
  opacity: 0;
  transform: translateY(28px);
  filter: blur(6px);
  animation: hero-in 700ms var(--ease-motion) forwards;
}
.hero-copy > :nth-child(1) { animation-delay: 120ms; }
.hero-copy > :nth-child(2) { animation-delay: 240ms; }
.hero-copy > :nth-child(3) { animation-delay: 380ms; }
.hero-copy > :nth-child(4) { animation-delay: 520ms; }
@keyframes hero-in {
  to { opacity: 1; transform: translateY(0); filter: blur(0); }
}

.scroll-cue {
  position: absolute; bottom: 40px; left: var(--pad-inline);
  display: flex; align-items: center; gap: 12px;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(255,255,255,0.45); z-index: 2;
}
.scroll-cue::after {
  content: ''; width: 40px; height: 1px;
  background: linear-gradient(90deg, var(--gold), transparent);
  transform-origin: left;
  animation: cue-sweep 2.4s var(--ease-motion) infinite;
}
@keyframes cue-sweep {
  0% { transform: scaleX(0); opacity: 0; }
  25% { opacity: 1; }
  70% { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}

/* MANIFESTO: word-by-word reveal */
.manifesto .wrap { max-width: 1400px; }
.manifesto p {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(2rem, 4.1vw, 4rem);   /* 64px ceiling for big pull quotes */
  line-height: 1.12; letter-spacing: -0.01em; color: var(--ink);
  /* px, not ch: the old 20ch cap was set for a much larger size and now forces
     the second sentence onto a third line. */
  max-width: 1150px;
}
.manifesto em { color: var(--gold-dim); font-style: italic; }
.reveal-words .w {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.35em);
  transition:
    opacity 500ms var(--ease-motion) calc(var(--i) * 55ms),
    transform 500ms var(--ease-motion) calc(var(--i) * 55ms);
}
.reveal-words.in .w { opacity: 1; transform: none; }

/* SERVICIOS: asymmetric editorial rows */
.pillars { display: flex; flex-direction: column; border-top: 1px solid var(--hairline-dark); }
/* Los numerales I/II/III salieron: eran etiqueta ordinal decorativa — el orden
   de los tres pilares no es una secuencia que el lector deba seguir ni un
   ranking, así que borrarlos no le cuesta nada. La asimetría de la sección NO
   dependía de ellos: la produce la alternancia de alineación (impares a la
   izquierda, pares a la derecha), que se conserva intacta. Con el numeral fuera,
   la columna de 140px que lo sostenía ya no tiene contenido y desaparece en vez
   de quedar como sangría vacía. */
.pillar-row {
  display: grid; grid-template-columns: 1fr;
  padding: 36px 0;
  border-bottom: 1px solid var(--hairline-dark);
  align-items: start;
  cursor: default;              /* rows are not links */
  transition:
    background var(--dur-hover) var(--ease-color),
    border-color var(--dur-hover) var(--ease-color);
}
.pillar-body { max-width: 62ch; transition: transform var(--dur-hover) var(--ease-motion); }
.pillar-row:nth-child(even) .pillar-body { margin-left: auto; text-align: right; }
.pillar-row:nth-child(even) .pillar-body p { margin-left: auto; }
/* ~half the section title (which caps at 64px), so these read as a level down
   rather than as four competing headlines. */
.pillar-body h3 { font-size: clamp(1.35rem, 2.05vw, 2rem); color: var(--cream); margin-bottom: 12px; line-height: 1.15; }
.pillar-body p { color: rgba(244,237,225,0.66); font-size: 1rem; font-weight: 300; max-width: 46ch; }

/* Whole-row hover. Gated to fine pointers: on touch the resting state stands. */
@media (hover: hover) and (pointer: fine) {
  .pillar-row:hover {
    background: rgba(244, 237, 225, 0.03);   /* felt, not seen */
    border-bottom-color: var(--gold-dim);
  }
  .pillar-row:hover h3 { color: var(--gold-bright); }
}
/* El texto se desplaza HACIA DENTRO de la columna, nunca hacia fuera.
   Las direcciones estaban invertidas: venían de cuando el numeral ocupaba una
   columna de 140px dentro de la fila y el texto derivaba hacia él, que era un
   movimiento hacia el interior. Al quitar el numeral, el cuerpo quedó a ras del
   límite de contenido del .wrap, y esos mismos signos pasaron a empujar el
   texto 6px FUERA de la línea de alineación que respeta el resto de la página
   —hacia el canalón—. Se notaba sobre todo en la fila par, alineada a la
   derecha, donde parecía que la última letra se escapaba.
   Ahora las impares entran hacia la derecha y la par hacia la izquierda: el
   movimiento se conserva y nada cruza el límite.
   Solo movimiento — con reduced motion se pierde y queda el cambio de color. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .pillar-row:hover .pillar-body { transform: translateX(6px); }
  .pillar-row:nth-child(even):hover .pillar-body { transform: translateX(-6px); }
}

/* DEMO / PORTFOLIO */
.demo-wrap { max-width: 1240px; margin: 0 auto; perspective: 2400px; }
.browser-frame {
  background: var(--white); border-radius: 6px; overflow: hidden;
  box-shadow: 0 70px 130px -30px rgba(0,0,0,0.35), 0 0 0 1px rgba(0,0,0,0.04);
  transform: rotateX(6deg) rotateY(-4deg) rotateZ(0.4deg);
  transition: transform 300ms var(--ease-motion);
  transform-style: preserve-3d;
}
/* Decorative showcase, not a control — kept inside the hover band so it reads
   as the same system as every real button. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .browser-frame:hover { transform: rotateX(2deg) rotateY(-1deg) rotateZ(0deg) scale(1.01); }
}
.browser-bar { background: var(--cream-deep); padding: 15px 20px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--hairline-light); }
.browser-dots { display: flex; gap: 7px; }
.browser-dots span { width: 10px; height: 10px; border-radius: 50%; background: #D6C9AE; }
/* La píldora de 100px es deliberada y NO rompe la regla de esquinas cuadradas:
   esto no es UI de OptiSite, es la simulación del cromo de OTRO navegador, y
   las barras de dirección reales son píldoras. Cuadrarla haría que el mockup
   dejara de leerse como un navegador. Misma lógica que los tres puntos
   circulares de al lado. */
.browser-url { background: var(--paper); border: 1px solid var(--hairline-light); border-radius: 100px; padding: 6px 18px; font-size: 12px; color: var(--ink-soft); flex: 1; max-width: 400px; margin: 0 auto; text-align: center; }
.browser-body { padding: 56px 48px; display: grid; grid-template-columns: 1.3fr 1fr; gap: 40px; align-items: center; }
.browser-body h4 { font-family: var(--font-display); font-size: clamp(1.7rem, 2.6vw, 2.6rem); font-weight: 500; margin-bottom: 16px; color: var(--ink); }
.browser-body > div:first-child p { color: var(--ink-soft); font-size: 14px; margin-bottom: 22px; }
.browser-visual {
  aspect-ratio: 1;
  background:
    radial-gradient(circle at 30% 18%, rgba(209,162,86,0.28), transparent 55%),
    linear-gradient(135deg, var(--black) 0%, var(--black-card) 100%);
  display: flex; align-items: center; justify-content: center;
  padding: clamp(20px, 3vw, 40px);
}
.mini-book { width: 100%; max-width: 300px; display: flex; flex-direction: column; gap: 18px; }
.mini-title { font-family: var(--font-display); font-style: italic; font-size: 1.4rem; color: var(--gold-bright); }
.mini-days, .mini-times { display: flex; gap: 8px; }
.mini-days span, .mini-times span {
  flex: 1; text-align: center; padding: 9px 6px;
  border: 1px solid var(--hairline-dark); color: rgba(244,237,225,0.6);
  font-size: 11.5px; letter-spacing: 0.04em;
}
.mini-days .on, .mini-times .on { background: var(--gold); border-color: var(--gold); color: var(--black); font-weight: 600; }
.mini-wa {
  margin-top: 6px; padding: 12px 16px; text-align: center;
  background: var(--cream); color: var(--black);
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
}

/* PROCESO — cuatro pasos, deliberadamente NO clonados.
   Anchos desiguales y desplazamiento vertical alterno, en el mismo lenguaje
   que la sección de sectores: escalas mixtas y elementos fuera de la retícula.
   Sin rejilla de bordes verticales: cada paso lleva solo una regla superior
   corta, y el desnivel es lo que marca la separación. */
.timeline {
  display: grid;
  grid-template-columns: 1.15fr 0.92fr 1.08fr 0.85fr;   /* anchos desiguales */
  gap: clamp(20px, 3vw, 48px);
  align-items: start;
}
.step { padding-top: 26px; border-top: 1px solid var(--hairline-dark); }
/* Los pares caen; el último cae un poco más. La escalera es lo que impide
   que se lean como cuatro cajas iguales. */
.step:nth-child(2) { margin-top: 54px; }
.step:nth-child(3) { margin-top: 18px; }
.step:nth-child(4) { margin-top: 78px; }
/* La regla superior del paso destacado toma el acento, como ancla de lectura. */
.step:first-child { border-top-color: var(--gold-dim); }
.step:first-child .step-title { font-size: clamp(1.75rem, 2.5vw, 2.5rem); }
/* No marker: the step title is the first element in the column and carries the
   hierarchy the number used to. Larger than a normal h3, still clearly under
   the section title so it never competes with it. */
.step-title {
  font-size: clamp(1.6rem, 2.2vw, 2.15rem);
  color: var(--cream); line-height: 1.1; margin-bottom: 0;
}
.step-desc { color: rgba(244,237,225,0.62); font-size: 14px; line-height: 1.6; font-weight: 300; margin-top: 16px; }

/* SECTORES — una frase con una sola palabra que rota. */
.rotator { margin-top: clamp(24px, 3vw, 40px); text-align: center; }
/* fit-content es funcional, no estético: esta caja es la que escucha el hover
   para pausar. Siendo flex de nivel bloque ocupaba los 1296px de la columna,
   así que 389px (el 30%) pausaban la rotación sin tener una sola letra debajo
   —y justo a la altura donde queda el cursor al traer la frase al centro—.
   Ahora el área sensible coincide con el texto visible. */
.rotator-line {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(1.75rem, 3.4vw, 3.5rem);   /* 28px móvil → 56px escritorio */
  line-height: 1.25; color: var(--ink);
  display: flex; flex-wrap: wrap;
  align-items: baseline; justify-content: center;
  gap: 0 0.32em;
  width: fit-content; max-width: 100%; margin-inline: auto;
}

/* El slot reserva de antemano el ancho de la palabra MÁS LARGA: todos los
   sectores viven apilados en la misma celda del grid como sizers invisibles,
   así que el ancho es el del más ancho y la frase no se reacomoda en cada
   cambio. Un salto de layout aquí arruinaría el efecto entero.
   overflow:hidden es lo que recorta las palabras al entrar y salir. */
.rotator-slot {
  display: inline-grid;
  overflow: hidden;
  text-align: left;
  vertical-align: baseline;
}
.rotator-slot > * { grid-area: 1 / 1; white-space: nowrap; }
.rw-sizer { visibility: hidden; pointer-events: none; }
.rw-live {
  font-style: italic; color: var(--gold);
  will-change: transform, opacity;
}
/* Cada letra entra por abajo con un escalonado corto de izquierda a derecha. */
.rw-live .ltr {
  display: inline-block;
  transform: translateY(100%);
  opacity: 0;
  animation: rw-in 560ms var(--ease-motion) forwards;
  animation-delay: calc(var(--i) * 25ms);
}
@keyframes rw-in { to { transform: translateY(0); opacity: 1; } }
/* La saliente sube y se desvanece como una sola pieza. */
.rw-live.is-out { animation: rw-out 560ms var(--ease-motion) forwards; }
@keyframes rw-out { to { transform: translateY(-100%); opacity: 0; } }

/* Solo para lectores de pantalla: la lista completa de sectores. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* La sección encoge: ahora es una frase, no una nube ni dos cintas. */
/* Sin override de padding: esta sección tenía clamp(56px, 7vw, 100px) —residuo
   de cuando el rotador sustituyó a la cinta y la sección encogió— y era la
   ÚNICA de la página fuera del ritmo estándar de clamp(72px, 11vw, 160px).
   Eso hacía que el hueco anterior midiera 258px y el siguiente 317px, y el
   salto se notaba justo al llegar a precios. Ahora todos los cortes miden lo
   mismo. */
#sectores .sec-head { margin-bottom: clamp(36px, 4.5vw, 60px); }

/* PRECIOS — tres tarjetas asimétricas, no una retícula.
   Sin bordes verticales en ninguna parte: la separación la hace el espacio
   en blanco, y dentro de la tarjeta una sola línea horizontal fina. */
.plans {
  display: grid;
  grid-template-columns: 1fr 1.22fr 1fr;  /* la recomendada es más ancha */
  /* stretch, no start: con `start` cada tarjeta medía lo que midiera su texto y
     las tres terminaban a alturas distintas. Estirándolas todas al alto de la
     fila, el `margin-top: auto` del botón por fin tiene espacio libre que
     empujar y los tres botones se anclan al fondo. El desfase superior no se
     pierde: lo sigue produciendo el margin-top de .plan-side, que baja el
     inicio de las laterales sin mover su base. */
  gap: clamp(16px, 2.2vw, 34px);
  max-width: 1240px;
}
.plan {
  display: flex; flex-direction: column;
  padding: 40px 34px;
  transition:
    transform var(--dur-hover) var(--ease-motion),
    box-shadow var(--dur-hover) var(--ease-color),
    background var(--dur-hover) var(--ease-color);
}
/* Las dos laterales: sobre el fondo claro, compactas, sin caja cerrada.
   Solo una línea de acento arriba que reacciona al hover. */
.plan-side {
  background: rgba(28, 24, 18, 0.03);
  border-top: 2px solid var(--hairline-light);
  margin-top: 34px;                        /* quedan por debajo de la destacada */
}
/* La recomendada: más alta, más ancha, fondo oscuro, y sobresale
   verticalmente por arriba y por abajo respecto a las otras dos. */
.plan-featured {
  background: var(--black);
  border-top: 2px solid var(--gold);
  /* Abajo 40px, igual que las laterales, y NO 52px: el relleno inferior es lo
     que separa el botón de la base de la tarjeta, así que si difiere los
     botones dejan de alinearse aunque las cajas sí lo estén. Arriba conserva
     los 52px, que es donde el aire extra se nota. */
  padding: 52px 40px 40px;
  box-shadow: 0 30px 60px -34px rgba(28, 24, 18, 0.5);
}
.plan-flag {
  align-self: flex-start;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  font-weight: 600; color: var(--gold-bright);
  margin-bottom: 18px;
}
.plan-name {
  font-family: var(--font-display); font-weight: 500;
  font-size: 1.25rem; letter-spacing: 0.01em;
  color: var(--ink); margin-bottom: 10px;
}
.plan-featured .plan-name { color: var(--cream); }
/* El precio es lo más grande de la tarjeta: fuerte salto de escala
   respecto al nombre del plan (1.25rem contra ~3rem). */
.plan-price {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(2.4rem, 3.4vw, 3.2rem);
  line-height: 1; color: var(--ink); margin-bottom: 8px;
}
.plan-featured .plan-price { font-size: clamp(2.8rem, 4vw, 3.75rem); color: var(--gold-bright); }
.plan-unit { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.plan-featured .plan-unit { color: rgba(244, 237, 225, 0.55); }
.plan-pitch {
  font-size: 14px; line-height: 1.55; font-weight: 300; color: var(--ink-soft);
  margin: 22px 0; padding-top: 22px;
  border-top: 1px solid var(--hairline-light);   /* la única línea, horizontal */
}
.plan-featured .plan-pitch { color: rgba(244, 237, 225, 0.7); border-top-color: var(--hairline-dark); }
/* Lo que SÍ incluye, alineado a la izquierda y legible. Lo que no incluye
   sencillamente no aparece: sin guiones ni equis. */
.plan-list { list-style: none; display: flex; flex-direction: column; gap: 11px; margin-bottom: 32px; }
.plan-list li {
  position: relative; padding-left: 20px;
  font-size: 14.5px; line-height: 1.45; color: var(--ink-soft);
}
.plan-list li::before {
  content: ''; position: absolute; left: 0; top: 0.55em;
  width: 6px; height: 1px; background: var(--gold-dim);
}
.plan-featured .plan-list li { color: rgba(244, 237, 225, 0.82); }
.plan-featured .plan-list li::before { background: var(--gold); }
.plan-btn { margin-top: auto; justify-content: center; }
/* Contorno sobre fondo claro, para las dos laterales. */
.btn-outline-ink { background: transparent; color: var(--ink); border-color: rgba(28, 24, 18, 0.28); }

@media (hover: hover) and (pointer: fine) {
  .plan-side:hover { background: rgba(28, 24, 18, 0.05); border-top-color: var(--gold); }
  .plan-featured:hover { box-shadow: 0 40px 70px -32px rgba(28, 24, 18, 0.6); }
  .btn-outline-ink:hover { border-color: var(--gold-dim); color: var(--gold-dim); background: rgba(184, 134, 62, 0.06); }
}
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .plan:hover { transform: translateY(-6px); }
}

/* Nota al pie: texto suelto, no un componente. Sin caja, sin borde y sin fondo
   —encerrarla la convertiría en otra tarjeta y devolvería el efecto retícula.
   Alineada al borde izquierdo del bloque de planes, con aire suficiente arriba. */
.plans-note {
  margin-top: 38px;
  max-width: 72ch;
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--muted);
}

/* Maintenance: one retainer that applies to both plans, so it belongs in a band
   under the table rather than as a third column. */
.price-maintenance {
  display: flex; align-items: center; justify-content: space-between;
  gap: 32px; flex-wrap: wrap;
  margin-top: 34px; padding: 26px 30px;
  background: var(--cream-deep);
  border: 1px solid var(--hairline-light);
}
.pm-label {
  display: block;
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--gold-dim); font-weight: 600; margin-bottom: 8px;
}
.pm-note { color: var(--ink-soft); font-size: 14px; line-height: 1.5; max-width: 52ch; }
.pm-figure { display: flex; align-items: baseline; gap: 12px; flex-shrink: 0; }
.pm-price { font-family: var(--font-display); font-size: 2rem; font-weight: 500; color: var(--ink); line-height: 1; }
.pm-unit { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }

/* FAQ */
.faq-list { max-width: 900px; border-top: 1px solid var(--hairline-light); }
.faq-item { border-bottom: 1px solid var(--hairline-light); }
.faq-q {
  width: 100%; padding: 28px 6px; display: flex; align-items: center; justify-content: space-between;
  gap: 24px; text-align: left;
  transition: background var(--dur-hover) var(--ease-color);
}
.faq-q-text { font-family: var(--font-display); font-size: 1.4rem; font-weight: 500; color: var(--ink); line-height: 1.25; transition: color var(--dur-hover) var(--ease-color); }
.faq-toggle { width: 28px; height: 28px; flex-shrink: 0; border: 1px solid var(--hairline-light); border-radius: 50%; position: relative; transition: background var(--dur-hover) var(--ease-color), border-color var(--dur-hover) var(--ease-color), transform 210ms var(--ease-motion); }
/* A full-width row must not lift or scale — it would break the hairline rhythm.
   The affordance is the toggle: the row washes, the circle is what reacts and presses. */
@media (hover: hover) and (pointer: fine) {
  .faq-q:hover { background: rgba(184, 134, 62, 0.05); }
  .faq-q:hover .faq-q-text { color: var(--gold-dim); }
  .faq-q:hover .faq-toggle { border-color: var(--gold); }
}
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .faq-q:hover .faq-toggle { transform: scale(1.07); }
}
@media (prefers-reduced-motion: no-preference) {
  .faq-q:active .faq-toggle { transform: scale(0.94); transition: transform var(--dur-tap) var(--ease-motion); }
}
.faq-toggle svg { position: absolute; inset: 0; margin: auto; width: 12px; height: 12px; color: var(--ink); transition: transform var(--dur-hover) var(--ease-motion); }
.faq-item.open .faq-toggle { background: var(--ink); border-color: var(--ink); }
.faq-item.open .faq-toggle svg { transform: rotate(135deg); color: var(--paper); }
/* 0fr→1fr is the only way to animate to auto height; it is a layout animation
   by necessity, so it stays inside the dropdown/disclosure budget (150–250ms). */
.faq-a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 250ms var(--ease-motion); }
.faq-item.open .faq-a { grid-template-rows: 1fr; }
.faq-a-inner { min-height: 0; overflow: hidden; }
.faq-a-body { padding: 0 56px 30px 6px; color: var(--ink-soft); font-size: 14.5px; line-height: 1.65; font-weight: 300; max-width: 62ch; }

/* CTA FINAL with the brand-mark echo */
.cta-final { overflow: hidden; position: relative; }
.cta-final .wrap {
  display: grid; grid-template-columns: 1.05fr 0.95fr;
  align-items: center; gap: clamp(32px, 5vw, 72px);
}
.cta-final h2 { font-size: clamp(2.25rem, 4.1vw, 4rem); color: var(--white); margin-bottom: 26px; line-height: 1.06; }
.cta-final .lede { margin-bottom: 44px; }
/* Rescatado de contacto.html al eliminarla: era el único dato de esa página
   que no estaba en ningún otro lado. Es una promesa concreta de fricción cero,
   por eso va debajo de los botones y no dentro del lede — se lee después de
   decidir escribir, no antes. */
.cta-note {
  margin-top: clamp(22px, 2.4vw, 32px);
  font-size: 13.5px;
  font-weight: 300;
  line-height: 1.7;
  color: rgba(244, 237, 225, 0.55);
}

/* FOOTER */
footer { background: var(--black); border-top: 1px solid var(--hairline-dark); padding: 88px 0 34px; }
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 52px; padding-bottom: 52px; margin-bottom: 52px; border-bottom: 1px solid var(--hairline-dark); }
.footer-brand { display: flex; flex-direction: column; gap: 16px; }
.footer-brand .brand-word { font-size: 28px; }
.footer-tag { color: rgba(244,237,225,0.5); font-size: 14px; max-width: 320px; line-height: 1.6; font-weight: 300; }
.footer-col h4 { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--gold); margin-bottom: 20px; font-weight: 600; }
.footer-col a, .footer-col p { display: block; color: rgba(244,237,225,0.56); font-size: 14px; margin-bottom: 11px; transition: color var(--dur-hover) var(--ease-color), transform var(--dur-tap) var(--ease-motion); font-weight: 300; }
@media (hover: hover) and (pointer: fine) {
  .footer-col a:hover { color: var(--gold-bright); }
}
.footer-bottom { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; font-size: 12px; color: rgba(244,237,225,0.4); letter-spacing: 0.03em; }

/* REVEAL system (500ms rise 40px, stagger 80ms).
   .reveal-stagger children share .reveal's hidden base so group staggers actually fire. */
.reveal, .reveal-stagger {
  opacity: 0; transform: translateY(40px);
  transition: opacity 500ms var(--ease-motion), transform 500ms var(--ease-motion);
}
.pillar-row.reveal-stagger:nth-child(even) { transform: translateY(40px) translateX(36px); }
.reveal.in, .reveal-group.in .reveal-stagger { opacity: 1; transform: translateY(0) translateX(0); }
.reveal-group.in .reveal-stagger:nth-child(1) { transition-delay: 0ms; }
.reveal-group.in .reveal-stagger:nth-child(2) { transition-delay: 80ms; }
.reveal-group.in .reveal-stagger:nth-child(3) { transition-delay: 160ms; }
.reveal-group.in .reveal-stagger:nth-child(4) { transition-delay: 240ms; }
.reveal-group.in .reveal-stagger:nth-child(5) { transition-delay: 320ms; }
.reveal-group.in .reveal-stagger:nth-child(6) { transition-delay: 400ms; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* Ambient loops stop. Transitions are deliberately left alive: every hover
     transform is gated behind (prefers-reduced-motion: no-preference), so what
     survives here is colour/shadow feedback — which is exactly what a
     reduced-motion visitor should keep. Movement is the problem, colour isn't. */
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
  .reveal, .reveal-stagger, .reveal-words .w { opacity: 1; transform: none; transition: none; }
  .hero-copy > * { opacity: 1; transform: none; filter: none; animation: none; }
  .faq-a { transition: none; }
  .site-nav, .site-nav.is-visible { transform: none; transition: opacity 200ms var(--ease-color); }
  .mobile-panel { transition: none; }
  /* Hero mark: fully static — no idle spin, no pointer tilt. The colour change
     on proximity survives, per house-style (movement is the problem, colour isn't). */
  .hero-mark-spin { animation: none; }
  /* Los trazos se quedan quietos en su posición de origen, no desaparecen:
     son textura, y no molestan mientras no se muevan. */
  .hero-lines .hl-drift-a, .hero-lines .hl-drift-b { animation: none; transform: none; }
  .hero-mark-tilt { transform: none !important; transition: none; }
  .hero-mark.is-near .hero-mark-dot { transform: none; }
}

/* RESPONSIVE */
@media (max-width: 1080px) {
  .cta-final .wrap { grid-template-columns: 1fr; }
  .cta-mark { order: -1; width: clamp(140px, 32vw, 200px); }
}
@media (max-width: 900px) {
  section { padding-block: clamp(56px, 14vw, 96px); }
  .site-nav { padding: 18px 24px; }
  .nav-links { display: none; }
  .site-nav .nav-cta { display: none; }
  .nav-toggle { display: flex; }
  /* Mobile: the mark gets its own in-flow band above the copy — no overlap possible */
  .hero { min-height: 100vh; flex-direction: column; justify-content: flex-end; align-items: stretch; padding-top: 0; padding-bottom: 88px; gap: 20px; }
  .hero-mark {
    position: relative; inset: auto; top: auto; right: auto; transform: none;
    align-self: center; margin-top: 96px;
    width: clamp(130px, 40vw, 190px);
  }
  .hero-ctas { width: 100%; flex-direction: column; align-items: stretch; }
  .hero-ctas .btn { justify-content: center; }
  .pillar-row, .pillar-row:nth-child(even) { grid-template-columns: 1fr; gap: 20px; }
  .pillar-row:nth-child(even) .pillar-mark { order: 0; text-align: left; }
  .pillar-row:nth-child(even) .pillar-body { order: 1; margin-left: 0; text-align: left; max-width: none; }
  .browser-body { grid-template-columns: 1fr; padding: 28px 22px; }
  .browser-frame { transform: none; }
  /* En una columna la escalera no aporta nada y solo dejaría huecos raros:
     los pasos vuelven a apilarse parejos, separados por su regla superior. */
  .timeline { grid-template-columns: 1fr; gap: 0; }
  .step { padding: 26px 0 30px; margin-top: 0 !important; }
  .step:first-child .step-title { font-size: clamp(1.6rem, 2.2vw, 2.15rem); }
  .plans { grid-template-columns: 1fr; max-width: 460px; gap: 20px; }
  .plan-side { margin-top: 0; }
  .plan, .plan-featured { padding: 32px 26px; }
  .rotator-line { gap: 0 0.25em; }
  .price-maintenance { flex-direction: column; align-items: flex-start; gap: 18px; padding: 22px; }
  .footer-grid { grid-template-columns: 1fr; gap: 36px; }
  .footer-bottom { flex-direction: column; }
  h1 { font-size: 2.75rem !important; }
}
