/* ════════════════════════════════════════════════════════════
   DESIGN TOKENS — Clay × Linear/Stripe direction
   ════════════════════════════════════════════════════════════ */
:root {
  /* Typography — Instrument Sans para títulos (h1/h2/h3), Inter para
     cuerpo, metadata (eyebrows) y componentes UI (tags, stats). Ganador
     de la prueba A/B/C; decisión final, ya no es condicional. */
  --font-sans: "Inter", system-ui, -apple-system, sans-serif;
  --font-label: "Inter", system-ui, -apple-system, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "IBM Plex Mono", monospace;
  --font-display: "Instrument Sans", "Inter", system-ui, -apple-system, sans-serif;
  --font-ui: "Inter", system-ui, -apple-system, sans-serif;

  /* Escala un poco más generosa (referencia de aire tipo Clay, sin exagerar) */
  --text-display: clamp(3.35rem, 7.8vw, 6.85rem);
  --text-h2:      clamp(2.35rem, 4.7vw, 3.5rem);
  --text-h3:      1.375rem;
  --text-deck:    clamp(1.2rem, 0.7vw + 1.05rem, 1.45rem);
  --text-body:    1.075rem;
  --text-small:   0.875rem;
  --text-mono:    0.75rem;

  --leading-display: 0.96;
  --leading-tight:   1.15;
  --leading-body:    1.6;

  /* Instrument Sans es más abierto que Inter — con el tracking viejo
     (-0.04em, calibrado para Inter) las letras llegan a tocarse en tamaños
     grandes. -0.035em es el valor que ya usan los case studies
     (shared/case-theme.css) sin que se toquen: misma familia, mismo criterio.
     El home estaba en -0.015em, lo que dejaba el display suelto y con una voz
     distinta a la del interior del sitio. Unificado. */
  --tracking-display: -0.035em;
  --tracking-h2:      -0.012em;
  --tracking-mono:     0.14em;

  /* Color */
  --color-bg:            #FAFAF8;
  --color-surface:       #FFFFFF;
  /* Escalón claro de la rampa cálida. Era #F4F4F2 (gris frío, spread R-B de
     2) y convivía con el hundido #EFECE6 de los cases (cálido, spread 9): dos
     grises de temperatura distinta en el mismo documento se leen como
     descuido, no como jerarquía. #F5F3EE mantiene la ligereza pero cae en la
     misma familia: bg #FAFAF8 → surface-2 #F5F3EE → sunken #EFECE6, cada
     escalón un poco más cálido conforme oscurece. */
  --color-surface-2:     #F5F3EE;
  --color-ink:           #101012;
  --color-panel:         #0C0C0D;
  --color-panel-edge:    rgba(255,255,255,0.08);
  --color-panel-text:    #FAFAF8;
  --color-panel-muted:   #8E8E93;
  --color-body:          #52525B;
  --color-caption:       #71717A;
  --color-border:        #E7E5E4;
  --color-border-strong: #D6D3D1;
  /* Familia cálida a saturación contenida (76%), no al 100% como el #FF4D00
     anterior. El resto de la paleta está medido —fondo hueso, negro roto,
     rampa de grises afinada por temperatura— y el acento era lo único al
     tope: leía a startup, no al rigor que reclama la copy.
     Se mantiene cálido a propósito: las tres marcas de los cases son frías
     (Kivo 150°, Prestio 172°, Pivot 229°), así que este naranja es lo único
     que hace que la página sea suya y no un contenedor de marcas ajenas.
     Descartado #4F46E5: quedaba a 14° de la marca de Pivot —el ojo los lee
     como el mismo color— y es el indigo por defecto de la categoría. */
  --color-accent:        #E04A1E;
  /* Versión para texto: 4.96:1 sobre el fondo, pasa AA. El primario se queda
     para superficie y detalle, donde 3.89:1 basta. */
  --color-accent-ink:    #C2410C;

  /* Spacing */
  --space-2xs: 0.25rem;
  --space-xs:  0.5rem;
  --space-sm:  0.75rem;
  --space-md:  1rem;
  --space-lg:  1.5rem;
  --space-xl:  2.5rem;
  --space-2xl: 4rem;
  --space-section: clamp(6rem, 12vw, 10rem);

  /* Surfaces */
  --radius-card: 16px;
  --radius-pill: 999px;
  /* Sombras neutras · acento solo en CTAs / selection / focus / 1 detalle */
  --shadow-rest:  0 1px 2px rgba(16, 16, 18, 0.04), 0 4px 16px -6px rgba(16, 16, 18, 0.08);
  --shadow-hover: 0 2px 4px rgba(16, 16, 18, 0.05), 0 12px 28px -10px rgba(16, 16, 18, 0.12);
  --transition-card: transform 200ms cubic-bezier(0.2,0,0,1), box-shadow 200ms cubic-bezier(0.2,0,0,1);

  --container: 1360px;
}

/* ── Base ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  letter-spacing: -0.011em;
  color: var(--color-body);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-optical-sizing: auto;
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
  text-rendering: optimizeLegibility;
}

h1, h2, h3 {
  font-family: var(--font-display);
  text-wrap: balance;
  font-optical-sizing: auto;
}

p {
  text-wrap: pretty;
}
.container { max-width: var(--container); margin: 0 auto; padding: 0 clamp(1.25rem, 4vw, 2.5rem); }
section { padding: calc(var(--space-section) / 2) 0; }
a { color: inherit; text-decoration: none; }

.eyebrow {
  font: 400 var(--text-mono)/1 var(--font-label);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--color-caption);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}
/* Punto de acento solo en el eyebrow del hero (una vez, apertura). En los de
   sección ("Proyectos", "Contacto", etc.) se quitó: al repetirse cuatro veces
   diluían el color de acento.
   Nota: esos eyebrows iban numerados ("01 — Proyectos"). Se retiró el número
   porque prometía una secuencia inexistente — Proyectos, Enfoque y Stack son
   miradas paralelas, no pasos. La numeración se conserva en los case studies,
   donde sí ordena un argumento (01 Arquitectura → 02 Flujo core → 03 Uso en
   calle) y allí es un componente propio, .decision__eyebrow-num. */
.hero .eyebrow::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--color-accent);
  flex: none;
}
.mono-tag {
  font: 400 var(--text-mono)/1 var(--font-label);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
}

/* ── Header (Clay.global inspired) ── */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  color: var(--color-ink);
  transform: translateY(0);
  transition:
    transform 0.75s cubic-bezier(0.19, 1, 0.22, 1),
    background-color 0.35s cubic-bezier(0.19, 1, 0.22, 1),
    backdrop-filter 0.35s cubic-bezier(0.19, 1, 0.22, 1),
    -webkit-backdrop-filter 0.35s cubic-bezier(0.19, 1, 0.22, 1),
    color 0.35s ease;
}
.site-header.is-hidden {
  transform: translateY(-100%);
  pointer-events: none;
}
.site-header.is-scrolled:not(.is-menu-open) {
  background: rgba(250, 250, 248, 0.82);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.site-header.is-menu-open {
  color: var(--color-panel-text);
}

.site-header.is-menu-open .header-cta {
  background: var(--color-surface);
  color: var(--color-ink);
  box-shadow: 0 1px 2px rgba(16, 16, 18, 0.06);
}
.site-header.is-menu-open .header-cta:hover {
  background: var(--color-surface-2);
}
.site-header.is-menu-open .header-burger__line {
  background: var(--color-panel-text);
}
.header-menu-bg {
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  height: 100dvh; /* barras dinámicas del navegador móvil; 100vh queda de reserva */
  background: var(--color-panel);
  transform: translateY(-100.5%);
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
  pointer-events: none;
}
.site-header.is-menu-open .header-menu-bg {
  transform: translateY(0);
  /* Captura los clics del telón: sin esto, ahora que el menú es absoluto,
     un toque fuera de los enlaces atravesaría hasta el contenido de detrás. */
  pointer-events: auto;
}
.header-bar {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  height: 64px;
  margin: 0 24px;
}
.header-logo {
  margin-right: auto;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  color: inherit;
  font-size: 24px;
  transition: opacity 0.35s ease;
}
.header-logo:hover { opacity: 0.72; }
.header-nav {
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
}
.header-nav__links {
  display: flex;
  align-items: center;
  gap: 17px;
  list-style: none;
}
.header-nav__link {
  position: relative;
  display: inline-block;
  padding: 5px 10px;
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: inherit;
  transition: color 0.2s ease;
  text-decoration: none;
}
/* Underline animado · estilo Clay (scaleX desde la izquierda) */
.header-nav__link::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 3px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.4s cubic-bezier(0.19, 1, 0.22, 1);
  pointer-events: none;
  will-change: transform;
}
.header-nav__link:hover::after,
.header-nav__link:focus-visible::after,
.header-nav__link.is-active::after {
  transform: scaleX(1);
}
/* Si hay activa y haces hover en otra, la activa se apaga un momento (más Clay) */
.header-nav__links:hover .header-nav__link.is-active:not(:hover)::after {
  transform: scaleX(0);
}
.header-nav__link:focus-visible {
  outline: none;
}
@media (prefers-reduced-motion: reduce) {
  .header-nav__link::after {
    transition: none;
  }
}

/* Anclas bajo header fijo */
#work,
#approach,
#stack,
#contact,
#graphic,
#ux,
#illustration,
#process {
  scroll-margin-top: 88px;
}
.header-cta {
  display: inline-flex;
  align-items: center;
  margin-left: 7px;
  padding: 12px 18px;
  border-radius: var(--radius-pill);
  background: var(--color-ink);
  color: #fff;
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  box-shadow: 0 1px 2px rgba(16, 16, 18, 0.08);
  transition:
    background 0.33s cubic-bezier(0.16, 1, 0.3, 1),
    color 0.33s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.2s ease;
}
.header-cta:hover {
  background: #000;
  transform: translateY(-1px);
}
.header-menu-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-left: 10px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  flex: none;
}
.header-burger {
  position: relative;
  display: block;
  width: 40px;
  height: 40px;
}
.header-burger__line {
  position: absolute;
  left: 8px;
  width: 24px;
  height: 2px;
  background: currentColor;
  transition:
    top 0.2s ease 0.2s,
    transform 0.2s ease,
    background-color 0.35s ease;
}
.header-burger__line--top { top: 14px; }
.header-burger__line--bottom { top: 24px; }
.site-header.is-menu-open .header-burger__line--top {
  top: 19px;
  transform: rotate(45deg);
  transition-delay: 0s, 0.22s, 0s;
}
.site-header.is-menu-open .header-burger__line--bottom {
  top: 19px;
  transform: rotate(-45deg);
  transition-delay: 0s, 0.22s, 0s;
}
/* Absoluto, no en flujo. Antes era position:relative y solo se ocultaba con
   opacity:0, así que seguía ocupando su alto DENTRO de .site-header, que es
   fixed: en un móvil de 375px el header medía ~368px (bar 64 + menú 304) y
   ese bloque invisible se tragaba los toques en el 45% superior de la
   pantalla, porque .site-header no lleva pointer-events:none.
   Con position:absolute el header vuelve a medir lo que mide la barra. */
.header-mobile-menu {
  position: absolute;
  top: 64px; /* = alto de .header-bar en móvil */
  left: 0;
  right: 0;
  z-index: 1;
  padding: 28px 24px 40px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.site-header.is-menu-open .header-mobile-menu {
  opacity: 1;
  pointer-events: auto;
}
.header-mobile-menu__links {
  display: flex;
  flex-direction: column;
  gap: 8px;
  list-style: none;
}
.header-mobile-menu__link {
  display: inline-block;
  padding: 10px 0;
  font-size: clamp(1.75rem, 8vw, 2.25rem);
  font-weight: 550;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--color-panel-text);
  transition: opacity 0.2s ease;
  text-decoration: none;
}
.header-mobile-menu__link:hover { opacity: 0.65; }
body.is-menu-open { overflow: hidden; }

/* ── Header en móvil ──────────────────────────────────────────────
   A 24px de logo, el CTA a tamaño de cuerpo y la hamburguesa, la barra pedía
   ~412px y desbordaba en cualquier teléfono por debajo de 414. El CTA no se
   puede esconder: hay una regla que lo repinta en blanco con el menú abierto,
   así que está pensado para verse ahí. Se escala en dos pasos. */
@media (max-width: 767px) {
  .header-bar { margin: 0 16px; }
  .header-logo { font-size: 19px; }
  .header-cta { padding: 10px 14px; font-size: var(--text-small); }
}

/* Por debajo de 360px ni así cabe: el nombre cede y queda la marca sola. */
@media (max-width: 359px) {
  .header-logo span { display: none; }
}

@media (min-width: 768px) {
  .header-menu-btn,
  .header-mobile-menu {
    display: none;
  }
  .header-bar {
    height: 72px;
    margin: 0 40px;
  }
  .header-logo { font-size: 24px; }
  .header-nav__links { gap: 20px; }
  .header-nav__link { padding: 6px 10px; }
  .header-nav__link::after { left: 10px; right: 10px; bottom: 4px; }
  .header-cta { padding: 13px 20px; font-size: 0.9375rem; }
}
@media (min-width: 1250px) {
  .header-bar {
    height: 80px;
    max-width: 1440px;
    margin-left: auto;
    margin-right: auto;
    padding: 0 35px;
  }
  .header-nav__links { gap: 23px; }
  .header-nav__link { padding: 10px; }
  .header-nav__link::after { left: 10px; right: 10px; bottom: 6px; }
  .header-cta { padding: 14px 22px; margin-left: 12px; }
}

/* Credenciales del hero · dónde ha trabajado.
   Fuera del subtítulo a propósito: son la prueba, no el argumento. En una
   línea propia se escanean sin leerse, que es como funciona un "trusted by".
   Texto, no logos: usar marcas ajenas sugiere respaldo, y no lo hay. */
.hero-credentials {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  margin: var(--space-xl) 0 0;
  padding: var(--space-md) 0 0;
  border-top: 1px solid var(--color-border);
  list-style: none;
  font-size: var(--text-small);
  color: var(--color-caption);
}
.hero-credentials li {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.hero-credentials li + li::before {
  content: "";
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--color-border-strong);
  flex: none;
  margin-right: 1rem;
}
.hero-credentials strong {
  color: var(--color-ink);
  font-weight: 600;
}

@media (max-width: 767px) {
  /* En móvil el separador sobra: cada credencial va en su renglón. */
  .hero-credentials { flex-direction: column; gap: 0.4rem; }
  .hero-credentials li + li::before { display: none; }
}

/* Buttons */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-xs);
  font-size: var(--text-small); font-weight: 500;
  padding: 0.625rem 1.25rem;
  border-radius: var(--radius-pill);
  transition: var(--transition-card);
}

.btn--ink {
  background: var(--color-ink);
  color: #fff;
  font-weight: 500;
  border: 1px solid rgba(255,255,255,0.1); /* subtle definition */
}

.btn--ink:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-hover);
  background: #000;
  color: #fff;
  border-color: rgba(255,255,255,0.15);
}
.btn--text {
  padding: 0.625rem 0;
  color: var(--color-ink);
  font-weight: 500;
  text-decoration: none;
}
.btn--text .arrow { transition: transform 200ms cubic-bezier(0.2,0,0,1); color: var(--color-accent-ink); }
.btn--text:hover .arrow { transform: translateX(4px); }

/* ── Hero · tradicional ── */
.hero {
  position: relative;
  overflow-x: clip;
  padding: var(--space-section) 0 calc(var(--space-section) * 0.7);
}

.hero .container {
  position: relative;
}

.hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  gap: clamp(2rem, 5vw, 3.5rem);
}

.hero .eyebrow {
  margin: 0 0 1.25rem;
}

.hero h1 {
  /* No usa --text-display, a diferencia de .cta-panel h2, que sí lo mantiene.
     A 109px este titular ocupaba 5 líneas y 526px de alto contra los 301px
     del collage de la derecha: la tipografía aplastaba a la evidencia, que
     es justo lo que demuestra el trabajo. Bajado a ~88px y ensanchado a
     20ch cae en 4 líneas y equilibra con .hero-stage.
     El "Hablemos." del contacto no tiene ese problema —es corto— y por eso
     se queda en el token compartido. */
  font-size: clamp(3.35rem, 6.2vw, 5.5rem);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  /* 700 = mismo peso que .story-deck en los case studies. A 550 el display
     era el único punto del sitio con voz ligera: gritaba en tamaño
     y susurraba en carácter. */
  font-weight: 700;
  color: var(--color-ink);
  max-width: 20ch;
  margin: 0 0 var(--space-xl);
  text-wrap: balance;
}

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

.hero .subtitle {
  max-width: 52ch;
  font-size: 1.2rem;
  line-height: 1.55;
  letter-spacing: -0.014em;
  color: var(--color-body);
  margin: 0 0 var(--space-xl);
  text-wrap: pretty;
}

.hero-ctas {
  display: flex;
  align-items: center;
  gap: var(--space-xl);
  flex-wrap: wrap;
}

/* ── Hero stage · collage de proof visual (Kivo + PRESTIO) ── */
.hero-stage {
  position: relative;
  margin-top: var(--space-2xl);
}

.hero-stage::before {
  content: "";
  position: absolute;
  inset: -14% -12%;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(62% 62% at 68% 28%, rgba(0, 205, 102, 0.34) 0%, transparent 72%);
}

.hero-stage__base {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  aspect-ratio: 1728 / 1117;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--color-surface);
  box-shadow: var(--shadow-rest);
}

.hero-stage__base img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left top;
}

/* Planos flotantes · marco + sombra profunda para despegarlos del base
   (que ahora actúa como fondo, sin borde). */
.hero-stage__float {
  display: none;
  position: absolute;
  z-index: 2;
  border-radius: 14px;
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  box-shadow:
    0 2px 6px rgba(16, 16, 18, 0.06),
    0 28px 60px -24px rgba(16, 16, 18, 0.28);
}

.hero-stage__float img {
  display: block;
  width: 100%;
  height: auto;
}

.hero-stage__float--phone {
  width: 30%;
  left: -7%;
  bottom: -10%;
  z-index: 3;
}

.hero-stage__float--toast {
  width: 46%;
  right: -6%;
  top: -8%;
}

/* ── Sections ── */
.section-head { margin-bottom: var(--space-2xl); }
.section-head h2 {
  font-size: var(--text-h2);
  letter-spacing: var(--tracking-h2);
  line-height: var(--leading-tight);
  font-weight: 550;
  color: var(--color-ink);
  margin-top: var(--space-md);
  max-width: 24ch;
}
/* Deck / standfirst · escalón editorial entre el h2 y el cuerpo:
   sin él, un h2 de hasta 3.5rem cae directo a body (1.075rem).

   El :not(.eyebrow) es obligatorio. El eyebrow también es un <p> dentro de
   .section-head, y ".section-head p" (0,1,1) le gana a ".eyebrow" (0,1,0)
   además de venir después en el archivo: sin excluirlo, los eyebrows de
   sección salían a tamaño de deck, sin el tracking de versalita y en color
   de cuerpo — descuadrados frente a los del hero y el panel de CTA, que no
   viven aquí dentro y sí conservaban su estilo. */
.section-head p:not(.eyebrow) {
  max-width: 54ch;
  margin-top: var(--space-md);
  font-size: var(--text-deck);
  line-height: 1.5;
  letter-spacing: -0.012em;
  color: var(--color-body);
}

/* ── Bento ── */
.bento {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-auto-rows: minmax(180px, auto);
  gap: var(--space-lg);
}
.cell {
  background: var(--color-surface);
  border: none;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-rest);
  transition: var(--transition-card);
  overflow: hidden;
  display: flex; flex-direction: column;
  position: relative;
}
.cell:hover { transform: translateY(-2px); box-shadow: var(--shadow-hover); }
.cell--anchor {
  /* Ancho completo desde que se retiró la celda de stats, que ocupaba las
     3 columnas restantes de esta fila. */
  grid-column: span 12;
  grid-row: span 1;
  /* KIVO brand #00CD66 · negro + glow. Base fría, misma que PRESTIO/Pivot
     para que las 3 cards compartan la misma temperatura de negro. */
  background:
    radial-gradient(
      90% 80% at 100% 0%,
      rgba(0, 205, 102, 0.22) 0%,
      transparent 55%
    ),
    linear-gradient(
      145deg,
      rgba(0, 205, 102, 0.3) 0%,
      rgba(0, 160, 80, 0.14) 38%,
      rgba(16, 18, 19, 0) 70%
    ),
    linear-gradient(165deg, #181c1e 0%, #16191b 48%, #101213 100%);
}
.cell--half   { grid-column: span 6; }
.cell-pad { padding: var(--space-xl); }

/* Anchor cell — Kivo */
.cell--anchor .cell-pad {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-lg) var(--space-xl) var(--space-lg);
}
.cell--anchor h3 { color: var(--color-panel-text); font-size: 1.725rem; letter-spacing: -0.02em; font-weight: 550; }
/* Tinte verde de marca, igual criterio que PRESTIO/Pivot — verificado
   ≥4.5:1 contra el punto más claro real del wash, no solo la esquina oscura. */
.cell--anchor p { color: #9EB8AE; max-width: 46ch; font-size: 0.9375rem; line-height: 1.5; }
.cell--anchor .tag-row { margin-bottom: var(--space-xs); }
.tag-row { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: var(--space-sm); }
.tag,
.stack-tag {
  border: 1px solid var(--color-border);
  padding: 4px 8px;
  border-radius: 4px;
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: normal;
  text-transform: none;
  color: var(--color-body);
}
.cell--anchor .tag {
  border-color: var(--color-panel-edge);
  color: #9EB8AE;
}
.case-link {
  margin-top: var(--space-xs);
  font-size: var(--text-small); font-weight: 500;
  display: inline-flex; gap: var(--space-xs);
  color: var(--color-ink);
  text-decoration: none;
}
/* Stretched link: el hit-area cubre toda la card (.cell ya es
   position:relative), no solo el texto — el hover ya sugiere que
   toda la card es clickeable, esto lo hace cierto. */
.case-link::after {
  content: "";
  position: absolute;
  inset: 0;
}
/* El color sale de --cell-arrow: cada card usa el de su marca. Antes Kivo
   era el único que se quedaba con el naranja del acento mientras Prestio y
   Pivot ya usaban el suyo. */
.case-link .arrow {
  color: var(--cell-arrow, var(--color-accent-ink));
  transition: transform 200ms cubic-bezier(0.2, 0, 0, 1);
  text-decoration: none;
}
.cell:hover .case-link .arrow { transform: translateX(4px); }
.cell--anchor .case-link { color: var(--color-panel-text); }

/* CONTRASTE · Los textos de 13-14px de Prestio y Pivot subieron de
   luminosidad para pasar AA (4.5:1). Se conservan tono y saturación: solo
   sube la L, así el sistema de derivar cada color de su marca se mantiene.
   Kivo no cambió porque ya pasaba (4.78 en los tags).
   Medido componiendo las tres capas del background en la posición real de
   cada elemento, no en el punto más claro de la card: el backgroundColor
   de estas celdas es transparente —el color vive en un background
   shorthand con gradientes apilados— así que cualquier medición que mire
   backgroundColor da un resultado falso. */
/* Verde de Kivo (#00CD66) aclarado y desaturado con el mismo criterio que
   Prestio y Pivot: de 100%/40% de saturación y luminosidad a 59%/59%. */
.cell--anchor { --cell-arrow: #57D493; }

/* Case card screenshot (index bento) */
.mock-dash--photo {
  display: block;
  flex: 0 0 auto;
  width: 100%;
  height: clamp(230px, 34.5vh, 368px);
  max-height: clamp(230px, 34.5vh, 368px);
  margin: 0;
  border: none;
  background: transparent;
  object-fit: cover;
  object-position: left top;
}

/* Aquí vivían los estilos de .cell--stat (la celda de cifras de Kivo).
   Eliminados junto con su markup: ver el comentario en index.html, dentro
   de .bento. */

/* Half cells — projects 02 & 03 */
.cell--half .cell-pad { padding-bottom: var(--space-md); }
.cell--half h3 { font-size: var(--text-h3); letter-spacing: -0.015em; font-weight: 550; color: var(--color-ink); margin: var(--space-sm) 0 var(--space-2xs); }
.cell--half .desc { font-size: var(--text-small); max-width: 48ch; }
.cell--half .case-link { margin-top: var(--space-sm); }

/* Half cells — dark panel + gradient (PRESTIO & Pivot) */
.cell--half.cell--prestio { --cell-arrow: #8EBDB5; }
.cell--half.cell--pivot   { --cell-arrow: #839AE9; }

/* PRESTIO · #2C635C — base más fría para que el teal no se enturbie
   mezclado con el café de la base cálida original (se leía casi como
   el verde de KIVO). Glow con un teal más claro/vívido, wash con el
   hex de marca real. */
.cell--half.cell--prestio {
  background:
    radial-gradient(
      90% 80% at 100% 0%,
      rgba(47, 163, 150, 0.36) 0%,
      transparent 55%
    ),
    linear-gradient(
      145deg,
      rgba(47, 163, 150, 0.42) 0%,
      rgba(44, 99, 92, 0.24) 42%,
      rgba(16, 18, 19, 0) 85%
    ),
    linear-gradient(165deg, #181c1e 0%, #16191b 48%, #101213 100%);
  border-color: var(--color-panel-edge);
}

/* Pivot · #1A36B8 — misma base fría; glow/wash con más presencia
   para que el índigo se note sin perder el tono premium/oscuro. */
.cell--half.cell--pivot {
  background:
    radial-gradient(
      90% 80% at 100% 0%,
      rgba(74, 100, 216, 0.32) 0%,
      transparent 55%
    ),
    linear-gradient(
      145deg,
      rgba(52, 72, 196, 0.44) 0%,
      rgba(26, 54, 184, 0.22) 42%,
      rgba(16, 18, 19, 0) 82%
    ),
    linear-gradient(165deg, #181c1e 0%, #16191b 48%, #101213 100%);
  border-color: var(--color-panel-edge);
}

.cell--half.cell--prestio h3,
.cell--half.cell--pivot h3 { color: var(--color-panel-text); }

/* Texto largo con un tinte sutil del color de marca de cada card, en vez
   del gris neutro compartido. Verificado contra el punto más claro real
   del fondo (esquina superior del cell-pad, donde el wash pega más
   fuerte) — no solo contra la esquina oscura: ambos ≥4.5:1 ahí. */
.cell--half.cell--prestio .desc { color: #ABBFBF; }
.cell--half.cell--pivot .desc { color: #A1A6C2; }

.cell--half.cell--prestio .tag,
.cell--half.cell--pivot .tag {
  border-color: var(--color-panel-edge);
}
.cell--half.cell--prestio .tag { color: #ABBFBF; }
.cell--half.cell--pivot .tag { color: #A1A6C2; }

.cell--half.cell--prestio .case-link,
.cell--half.cell--pivot .case-link { color: var(--color-panel-text); }

/* El color lo toma .case-link .arrow de --cell-arrow; aquí solo se declara. */

.cell--half.cell--prestio .mock-stage,
.cell--half.cell--pivot .mock-stage {
  /* Sin stroke entre copy/gradient e imagen */
  border-top: none;
}

.cell--half.cell--prestio .mock-stage,
.cell--half.cell--pivot .mock-stage {
  /* Sin caja propia: se funde con el degradado de la card */
  background: transparent;
}

.mock-stage {
  flex: 1; min-height: 200px;
  background: var(--color-surface-2);
  border-top: 1px solid var(--color-border);
  display: flex; align-items: flex-end; justify-content: center;
  padding: var(--space-lg) var(--space-lg) 0;
  overflow: hidden;
}

.mock-stage--photo {
  padding: 0;
  align-items: stretch;
  min-height: 0;
}

.mock-stage-img {
  display: block;
  width: 100%;
  height: auto;
}


/* ── Stack ──
   El markup real del stack usa .stack-grid / .stack-item (más abajo).
   Aquí vivía un .stack-list/.stack-row de una versión anterior, sin ningún
   consumidor en el HTML de ninguna página. Eliminado. */

/* ── CTA panel ── */
.cta { padding-bottom: var(--space-section); }
/* Único panel cálido del sitio, y a propósito. Los tres cases van en frío
   (Kivo #00CD66, PRESTIO #2C635C, Pivot #1A36B8): la página recorre el
   trabajo en frío y gira a cálido justo donde deja de mostrar y empieza a
   pedir. Además es el cuarto panel oscuro de la página — sin este giro se
   lee como una celda más del bento en vez de como un cierre.
   Cierra en --color-accent-ink (#C2410C) y no en el acento puro (#E04A1E):
   a plena saturación el degradado se vuelve marcador fluorescente; un paso
   por debajo lee como brasa. Para más calor, subir el último tramo a
   var(--color-accent). */
.cta-panel {
  background: linear-gradient(135deg,
    var(--color-panel) 0%,
    #17100D 42%,
    #7A2A08 78%,
    var(--color-accent-ink) 100%);
  border-radius: calc(var(--radius-card) * 1.5);
  padding: clamp(3rem, 8vw, 6rem);
  position: relative; overflow: hidden;
}
/* Trama de fondo · queda solo en la mitad oscura, detrás del texto. Antes
   cubría también el naranja, que es donde peor se veía. */
.cta-panel::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: radial-gradient(circle, rgba(255,255,255,0.07) 1px, transparent 1px);
  background-size: 26px 26px;
  mask-image: linear-gradient(115deg, rgba(0,0,0,0.9) 0%, transparent 55%);
  -webkit-mask-image: linear-gradient(115deg, rgba(0,0,0,0.9) 0%, transparent 55%);
}

.cta-panel .eyebrow { color: var(--color-panel-muted); }
.cta-panel h2 {
  font-size: var(--text-display);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  font-weight: 700; /* mismo peso de display que el h1 del hero */
  color: var(--color-panel-text);
  margin: var(--space-lg) 0 var(--space-md);
}
/* :not(.eyebrow) por el mismo motivo que en .section-head: el margen inferior
   es para el párrafo de cuerpo (separarlo de .cta-actions), pero también caía
   sobre el eyebrow y lo alejaba del h2 mucho más que en las otras secciones. */
.cta-panel p:not(.eyebrow) { color: var(--color-panel-muted); max-width: 44ch; margin-bottom: var(--space-2xl); }
/* Regla única: antes estaba partida en dos bloques, este y otro más abajo
   junto a .btn-pill. Los dos declaraban display, gap y flex-wrap, así que el
   segundo pisaba al primero en silencio — el gap real era 1rem, no
   var(--space-xl), pero había que leer las dos para saberlo. Se conserva el
   valor que ganaba, que es el calibrado para los .btn-pill del markup actual.
   .email-link / .cta-secondary se eliminaron: ninguna página los instancia. */
.cta-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 1.5rem;
  position: relative;
}

/* ── Footer ── */
.site-footer { border-top: 1px solid var(--color-border); padding: var(--space-xl) 0; }
.site-footer .container {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-lg); flex-wrap: wrap;
}
.site-footer .mono-tag { color: var(--color-caption); }
.footer-nav { display: flex; gap: var(--space-lg); }
.footer-nav a {
  font-size: var(--text-small);
  color: var(--color-caption);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}
.footer-nav a:hover { color: var(--color-ink); }

/* ── Responsive ── */
@media (min-width: 981px) {
  /* Era 1.24fr 0.76fr. El collage necesita ancho para que el dashboard de
     Kivo del fondo se lea como UI y no como ruido gris: a 0.76fr quedaba
     tan chico que solo el toast y el teléfono eran legibles. */
  .hero-grid {
    grid-template-columns: 1.08fr 0.92fr;
  }
  .hero-stage {
    margin-top: 0;
  }
  .hero-stage__float {
    display: block;
  }
}
@media (max-width: 980px) {
  .cell--anchor, .cell--half { grid-column: 1 / -1; }
  .cell--anchor { grid-row: auto; }
}
@media (max-width: 767px) {
  .header-nav__links { display: none; }
}

/* ============================================
   CLEANED / POLISHED STYLES
   ============================================ */

/* Approach · columnas abiertas (sin caja) */
.grid-cards {
  display: grid;
  /* min() evita el desborde: con minmax(280px,…) a secas, en un viewport de
     280px el contenido mide 240px y la columna se queda en 280, sacando la
     página de la pantalla. */
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: clamp(2rem, 4vw, 3rem);
}

.card-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 0;
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
}

/* Contact CTA · las reglas de superficie del panel viven en el bloque
   "── CTA panel ──" de arriba: --color-panel + dot-grid enmascarado +
   padding clamp(3rem,8vw,6rem).
   Aquí había un segundo bloque .cta-panel que las pisaba: gradiente a
   #E04A1E, padding 3rem fijo (perdía hasta 3rem de aire en pantallas
   grandes) y dot-grid encima del naranja. Se eliminó el bloque, pero el
   gradiente era buena idea mal implementada: está de vuelta arriba, sobre
   el padding fluido y con la máscara del dot-grid invertida.
   Solo se conserva aquí .cta-actions, cuyo gap sí está calibrado para los
   .btn-pill del markup actual. */
/* .cta-actions vive ahora en el bloque "── CTA panel ──" de arriba, unificado */

.btn-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: #ffffff;
  color: #101012;
  padding: 14px 24px;
  border-radius: 999px;
  font-weight: 500;
  font-size: 0.9375rem;
  transition: transform 0.2s, box-shadow 0.2s;
  text-decoration: none;
  border: none;
}

.btn-pill:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(16, 16, 18, 0.16);
}

.btn-pill.dark {
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(8px);
}

.btn-pill.dark:hover {
  background: rgba(255, 255, 255, 0.15);
}

/* Approach · icono + texto */
.card-icon {
  margin-bottom: 1rem;
}

.card-icon img {
  width: 72px;
  height: auto;
  display: block;
}

.card-item h3 {
  margin: 0 0 0.75rem;
  font-size: var(--text-h3);
  font-weight: 550;
  letter-spacing: -0.015em;
  color: var(--color-ink);
}

.card-item p {
  font-size: var(--text-small);
  line-height: 1.55;
  margin: 0;
  max-width: 36ch;
  color: var(--color-body);
}

/* Stack grid */
.stack-grid {
  display: grid;
  /* minmax a 350px: a los 1392px del shell caben 3 columnas, no 4. Con 5
     items eso deja 3+2 (fila corta intencional) en vez de 4+1 (huérfano).
     El min(…, 100%) evita overflow horizontal a 320px de viewport, igual
     que antes. */
  grid-template-columns: repeat(auto-fit, minmax(min(350px, 100%), 1fr));
  gap: 3rem 2rem;
}

.stack-item__head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 1.25rem;
}

.stack-item__icon {
  width: 24px;
  height: 24px;
  flex: none;
}

.stack-item__title {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 500;
  color: var(--color-ink);
}

.stack-item__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.stack-item__desc {
  margin: 0;
  font-size: 1rem;
  color: var(--color-body);
  line-height: 1.5;
}

/* .section-head--spaced se movió a _wip/studio/studio.css: era su
   único consumidor y studio ya no forma parte del sitio. */


