/* Estilos por bloque (.oink-sec--inicio, --reto, --como-funciona…). Los añaden las tareas 4 a 8,
   cada bloque bajo un comentario con su id. */

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Bloque 0 · Cabecera (.oink-header)
   Sin JS va en absoluto sobre el hero y se va con el scroll: así nunca queda blanco sobre beige.
   Con JS (clase .oink-js en <html>, tarea 9) pasa a fija, y con .is-scrolled (scrollY > 80) toma el azul
   de la marca con una sombra suave, con un fundido de 200 ms ease (tarea 11).
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
.oink-header {
  position: absolute;
  inset: 0 0 auto;
  z-index: 10;                    /* por encima del contenido; por debajo del enlace de salto (30) */
  height: var(--oink-header-h);
  color: var(--oink-white);
}
.oink-js .oink-header { position: fixed; }
/* El fondo sólido y la sombra van en una capa que se funde (opacity, 200 ms ease: es un cambio de color, spec §5). Así la
   sombra no aparece de golpe ni se repinta en cada fotograma. z-index −1 dentro del contexto de la cabecera: debajo del logo,
   las anclas y el CTA. */
.oink-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-color: var(--oink-blue);
  box-shadow: 0 10px 30px -18px color-mix(in srgb, var(--oink-ink) 90%, transparent);
  opacity: 0;
  transition: opacity 200ms ease;
}
.oink-header.is-scrolled::before { opacity: 1; }

.oink-header__inner {
  display: flex;
  align-items: center;
  gap: 40px;
  height: 100%;
}

.oink-header__logo {
  display: inline-flex;
  align-items: center;
  min-width: 44px;
  min-height: 44px;
  flex-shrink: 0;
}
.oink-header__logo img { width: 110px; }

.oink-header__nav ul {
  display: flex;
  gap: 4px;
  padding: 0;
  list-style: none;
}
.oink-header__nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  text-decoration-thickness: 2px;
  text-underline-offset: 8px;
}
@media (hover: hover) and (pointer: fine) {
  /* El naranja solo como subrayado (spec §4), nunca como color de texto. */
  .oink-header__nav a:hover {
    text-decoration-line: underline;
    text-decoration-color: var(--oink-orange);
  }
}

.oink-header__cta {
  min-height: 44px;
  margin-inline-start: auto;
  padding: 0 22px;
  font-size: 0.9375rem;
}

/* Hasta 1023 px: solo logo y CTA, sin menú, como en móvil (spec §3). Entre 768 y 1023 el menú iba con la letra a 0,875rem y
   8 px de relleno, pero con los límites del panel del plugin (cinco entradas de 13 caracteres y un CTA de 23) no cabe de
   ninguna manera: a 768 el contenedor mide 692 px y solo el menú en una línea pide unos 545; se partía en dos o tres líneas
   y el botón se salía hasta 36 px del margen. Bajar la letra de 0,875rem está descartado (ningún texto baja de ahí). */
@media (max-width: 1023.98px) {
  .oink-header__inner { gap: 20px; }
  .oink-header__logo img { width: 96px; }
  .oink-header__nav { display: none; }
  .oink-header__cta { padding: 0 18px; font-size: 0.875rem; }
}

@media (max-width: 767.98px) {
  .oink-header__logo img { width: 88px; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Bloque 1 · #inicio · hero + barra de datos
   Hero con foto a sangre (Oink, 29-10; anexo 2026-10-29): a la derecha, la foto vertical (hero-grupo.webp) ocupa
   toda la mitad derecha de la sección, desde arriba (detrás de la cabecera, como un fondo) hasta abajo del todo y hasta
   el borde derecho de la ventana, sin esquinas, sin sombra y sin margen: solo el mapa azul de .oink-photo y nada encima.
   El texto y la barra de cifras van a la izquierda, con un hueco mínimo hasta el borde de la foto (80 px a 1440).
   < 768 px: una columna; la foto, una banda a sangre de todo el ancho en 4:5, entre el texto y las cifras.
   Toda la geometría se mide en cqi de la sección (su ancho real, sin la barra de scroll), así el texto y la foto crecen
   juntos y no se pisan a ningún ancho.
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
.oink-sec--inicio {
  container-type: inline-size;
  position: relative;             /* la foto se coloca respecto a la sección entera (detrás de la cabecera y hasta el borde) */
  isolation: isolate;
  overflow: clip;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  /* El ritmo vertical se ajusta al alto de la pantalla (svh): a 1366 × 768 la barra de datos aún se ve. */
  padding-block: calc(var(--oink-header-h) + clamp(12px, 2.5svh, 36px)) clamp(20px, 3.5svh, 40px);
  /* Azul plano de la marca (ajustes de Oink, §3): sin degradados, halos ni haces. El texto blanco mide su contraste
     contra este azul: 7,2:1 (el microcopy al 80 %, 5,1:1). */
  background-color: var(--oink-blue);
}

.oink-hero {
  /* --hero-w      ancho de este contenedor (la misma fórmula que .oink-container)
     --hero-photo  ancho de la foto: el 44 % de la sección (634 px a 1440, 450 a 1024); el 42 % entre 768 y 1023
     --hero-gap    hueco mínimo entre el texto (y la barra de cifras) y el borde de la foto: 80 px desde 1280, 64 desde
                   1024 y 40 entre 768 y 1023 (anexo §2)
     --hero-copy   ancho máximo del texto y de la barra: desde el borde izquierdo del contenedor hasta la foto, menos el
                   hueco. Lo vigilan las pruebas de hero-foto. */
  --hero-w: min(100cqi - 2 * var(--oink-gutter), 1200px);
  --hero-photo: 44cqi;
  --hero-gap: 64px;
  --hero-copy: calc(100cqi - var(--hero-photo) - (100cqi - var(--hero-w)) / 2 - var(--hero-gap));
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 1fr auto;
  row-gap: clamp(20px, 3.5svh, 44px);
}
@media (min-width: 1280px) {
  .oink-hero { --hero-gap: 80px; }
}

.oink-hero__copy {
  position: relative;             /* por encima de la foto (que va en absoluto), por si algún texto llegara a tocarla */
  z-index: 1;
  align-self: center;
  max-width: var(--hero-copy);
}

.oink-hero__copy .oink-eyebrow { margin-bottom: clamp(12px, 2svh, 20px); }

.oink-hero__title {
  /* Tres líneas: «Captación de clientes» mide 13,07 em en Montserrat 800 con −0,02 em, así que el cuerpo es el ancho
     del texto entre 13,2. En pantallas bajas manda el alto (8,6svh). Mínimo y techo, los de la spec (--fs-h1). */
  font-size: clamp(2.5rem, min(var(--hero-copy) / 13.2, 8.6svh), var(--fs-h1));
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  text-wrap: balance;
}

.oink-hero__lead {
  max-width: min(42rem, var(--hero-copy));   /* ≈ 60 caracteres por línea a 18 px; tope de la spec: 62 ch */
  margin-top: clamp(14px, 2.6svh, 28px);
  font-size: 1.125rem;
  line-height: 1.6;
  text-wrap: pretty;
}

.oink-hero__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: clamp(18px, 3svh, 32px);
}

.oink-hero__micro {
  max-width: 30rem;
  margin-top: 16px;
  font-size: 0.875rem;
  line-height: 1.5;
  color: rgb(255 255 255 / 0.8);  /* blanco al 80 % (spec) */
  text-wrap: pretty;
}

/* La foto, a sangre: en absoluto respecto a la sección, pegada arriba, abajo y al borde derecho, con el ancho
   --hero-photo. De .oink-photo (components.css) toma el fondo azul mientras carga y el print-color-adjust; aquí se le
   quitan las esquinas. Sin sombra, sin capas encima.
   Lleva el mapa azul #oink-mapa-azul como las demás fotos (Oink, 02-11, 1.1.1: se quita la excepción «en color natural»
   del 29-10; el filtro sale de .oink-photo > img) y va SIN CORTE, ni recto ni en diagonal: su borde izquierdo se funde con el azul liso del
   fondo con una mask-image de degradado sobre la propia imagen (--hero-fade: 200 px desde 1280, 160 entre 1024 y 1279).
   El texto queda sobre el azul liso, así que el contraste no cambia. La foto es 4:5 y la caja más estrecha que alta:
   object-fit: cover la escala al alto y recorta a los lados; object-position la ancla a la derecha, para que las personas
   queden en la parte opaca: la mujer del borde izquierdo del archivo (x 10–95) queda fuera del todo (anclada a la
   izquierda caía dentro del fundido) y las otras tres caras salen enteras y opacas (centro x 455–525 desde 1280, chica de
   blanco x 585–680 y hombre x 750–830). Va en absoluto y no como ítem de la rejilla: un ítem con aspect-ratio abarcando
   filas dejaba a Chrome maquetando sin terminar al cambiar el ancho (bisección en el informe). */
.oink-hero__photo {
  --hero-fade: 200px;
  position: absolute;
  inset: 0 0 0 auto;
  z-index: 0;
  width: var(--hero-photo);
  border-radius: 0;
}
.oink-hero__photo > img {
  object-position: 100% 50%;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--hero-fade));
  mask-image: linear-gradient(to right, transparent, #000 var(--hero-fade));
}

/* Entre 1024 y 1279 el texto mide unos 470 px de ancho: el subtítulo baja a 1rem para que el hero quepa en una pantalla
   de 768 de alto (1024 × 768). */
@media (min-width: 1024px) and (max-width: 1279.98px) {
  .oink-hero__lead { font-size: 1rem; }
  /* La caja mide 451 × 811 a 1024: con 160 px de fundido quedan opacos la chica de blanco y el hombre; la mujer del
     centro cae en el fundido (no cabe de otra forma). */
  .oink-hero__photo { --hero-fade: 160px; }
}

/* Barra de datos: el cristal, debajo del texto, con el mismo ancho máximo que él (respeta el hueco con la foto). */
.oink-hero__stats {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 28px;
  max-width: var(--hero-copy);
  padding: 18px 24px;
}

/* Las cifras van separadas por el trazo de luz de .oink-metric--sep (valores por defecto: 22 / 14 px, blanco al 18 %).
   Columnas iguales que solo se parten en dos filas si las cifras no caben ni repartiendo el sitio de otra forma (break-ui,
   tarea 12: con 1.109.000 se pisaban). min-width: min-content no deja que una columna sea más estrecha que su cifra (con
   el relleno del trazo). La base es pequeña e igual para todas (3rem, más que el relleno mayor, 40 px): así la fila solo se
   parte cuando la suma de los mínimos no cabe, y si cabe, el sitio que sobra se reparte a partes iguales, como la rejilla
   de columnas 1fr que había (mismos píxeles). Si una cifra no cabe en su tercio, esa columna crece y las demás ceden
   (ronda 1: con una base de 1/3 o 1/2 la fila se partía también con los datos reales, a 320 y entre 1.200 y 1.209 px). */
.oink-hero__metrics {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  row-gap: 12px;
  padding: 0;
  list-style: none;
}
.oink-hero__metrics > .oink-metric,
.oink-reto__metrics > .oink-metric,
.oink-campaign__metrics > .oink-metric { flex: 1 1 3rem; min-width: min-content; }
/* Cifra a la medida de la barra: «0,67 €» mide 3,4 em y tiene que caber en su columna (606 px a 1440; 470 a 1024). */
.oink-hero__metrics .oink-metric__value { font-size: clamp(1.75rem, 2.4cqi, 2.25rem); }

/* La línea de apoyo, debajo de las cifras. */
.oink-hero__source {
  flex: 1 1 100%;
  font-size: 0.875rem;
  line-height: 1.5;
  color: rgb(255 255 255 / 0.85);
  text-wrap: pretty;
}

/* ── #inicio en tableta vertical (768–1023 px): la foto, una banda a sangre entre el texto y las cifras ──
   A la derecha no cabe: con el 42 % de 768 la caja mide 323 × 1024 y, escalada al alto, solo enseña 371 px de los 960
   del archivo (el grupo va de 10 a 830). Así que va como en móvil, en flujo y de borde a borde, en 4:3 (768 × 576):
   object-fit: cover escala al ancho y la ventana vertical (720 de 1200, anclada al 25 %) deja todas las caras enteras. */
@media (min-width: 768px) and (max-width: 1023.98px) {
  .oink-hero {
    --hero-copy: var(--hero-w);
    grid-template-rows: auto;
    align-content: start;
    row-gap: 0;
  }
  .oink-hero__lead { font-size: 1rem; }
  .oink-hero__photo {
    position: relative;
    inset: auto;
    width: calc(100% + 2 * var(--oink-gutter));
    aspect-ratio: 4 / 3;
    margin: 32px calc(-1 * var(--oink-gutter)) 0;
  }
  /* La banda se funde con el azul por arriba y por abajo (64 px); anclada al 10 % para que la cabeza del hombre (la más
     alta, y 195 del archivo) quede por debajo del fundido de arriba con margen. */
  .oink-hero__photo > img {
    object-position: 50% 10%;
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 64px, #000 calc(100% - 64px), transparent);
    mask-image: linear-gradient(to bottom, transparent, #000 64px, #000 calc(100% - 64px), transparent);
  }
  .oink-hero__stats { max-width: none; margin-top: 24px; }
}

/* ── #inicio en móvil (< 768 px): una columna; texto, CTAs, la banda de la foto y la barra ──────── */
@media (max-width: 767.98px) {
  /* El mismo azul plano que en escritorio (ajustes de Oink): el microcopy al 80 % pasa de 4,5:1 sobre él (5,1:1). */
  .oink-sec--inicio { padding-block: calc(var(--oink-header-h) + 24px) 32px; }

  .oink-hero {
    --hero-copy: var(--hero-w);
    grid-template-rows: auto;
    align-content: start;
    row-gap: 0;
  }

  .oink-hero__lead { margin-top: 20px; font-size: 1rem; }
  .oink-hero__ctas { margin-top: 28px; }
  .oink-hero__ctas .oink-btn { flex: 1 1 auto; padding: 0 22px; }

  /* La banda: en flujo, a sangre de borde a borde (se come el margen lateral del contenedor), en 4:5 (se ve el archivo
     entero, con todas las caras), entre el microcopy y las cifras. */
  .oink-hero__photo {
    position: relative;           /* en flujo; sigue siendo el contenedor de su imagen (absoluta, de .oink-photo) */
    inset: auto;
    width: calc(100% + 2 * var(--oink-gutter));
    aspect-ratio: 4 / 5;
    margin: 28px calc(-1 * var(--oink-gutter)) 0;
  }
  /* El mismo fundido por arriba y por abajo que en tableta; se ve el archivo entero y las cabezas empiezan a 79 px. */
  .oink-hero__photo > img {
    object-position: 50% 50%;
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 64px, #000 calc(100% - 64px), transparent);
    mask-image: linear-gradient(to bottom, transparent, #000 64px, #000 calc(100% - 64px), transparent);
  }

  .oink-hero__stats {
    flex-direction: column;
    flex-wrap: nowrap;            /* en columna, wrap mediría la línea por su contenido y se saldría */
    align-items: stretch;
    gap: 14px;
    max-width: none;
    margin-top: 20px;
    padding: 18px 16px;
  }
  .oink-hero__metrics { --oink-sep-start: 12px; --oink-sep-end: 8px; }
  .oink-hero__metrics .oink-metric__value { font-size: 1.5rem; }
  .oink-hero__metrics .oink-metric__label { font-size: 0.8125rem; }   /* la única letra bajo 0,875rem: a 0,875 la fila se parte a 320–330 px (tokens.css) */
  .oink-hero__source { flex: none; font-size: 0.875rem; }
}

/* Móviles de 320–379 px: las cifras bajan un punto. */
@media (max-width: 379.98px) {
  .oink-hero__metrics { --oink-sep-start: 10px; --oink-sep-end: 6px; }
  .oink-hero__metrics .oink-metric__value { font-size: 1.25rem; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Bloque 2 · #reto · el reto (fondo beige)
   ≥ 768 px: texto a la izquierda y la foto a la derecha, estirada al alto del texto (no suma altura).
   < 768 px: una columna; la foto, con su propio aspect-ratio, debajo del texto.
   Las cifras van sobre el pie de la foto, en una placa beige (ajustes de Oink, anexo §4; components.css).
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
.oink-reto {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  column-gap: clamp(32px, 5vw, 72px);
}

.oink-reto__copy .oink-h2 { margin-bottom: 24px; }
.oink-reto__copy p {
  max-width: 62ch;
  color: var(--oink-gray);            /* 7,1:1 sobre beige */
  text-wrap: pretty;
}
.oink-reto__copy p + p { margin-top: 14px; }
.oink-reto__copy .oink-reto__punch {
  margin-top: 22px;
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.45;
  color: var(--oink-blue);            /* 7,0:1 sobre beige */
}

.oink-reto__photo { min-height: 340px; }

/* La placa de las cifras (components.css): abajo, a 16 px del borde de la foto y con 16 × 20 px de relleno, como en la
   propuesta aprobada. Su sombra (8 px) cae dentro de ese margen. */
.oink-reto__stats {
  inset: auto 16px 16px;
  padding: 16px 20px;
}

/* El mismo trazo (.oink-metric--sep) que separa las cifras de la barra del hero, en azul al 25 % sobre el beige (como en
   la tarjeta de campaña). */
.oink-reto__metrics {
  --oink-sep-line: color-mix(in srgb, var(--oink-blue) 25%, transparent);
  --oink-sep-end: 18px;
  display: flex;                      /* columnas iguales que se parten si una cifra no cabe (ver la barra del hero) */
  flex-wrap: wrap;
  row-gap: 14px;
  padding: 0;
  list-style: none;
}
.oink-reto__metrics .oink-metric__value { font-size: clamp(2.25rem, 3.3vw, 3.25rem); }
.oink-reto__metrics .oink-metric__label {
  font-size: 0.9375rem;
  color: var(--oink-blue);            /* todo el texto de la placa en azul pleno (7,0:1 sobre el beige) */
}

.oink-reto__source {
  margin-top: 16px;
  font-size: 0.875rem;
  line-height: 1.4;                   /* el color es el azul de la placa */
}

/* Tablet: la columna de la foto es estrecha y alta; las cifras, una encima de otra. */
@media (max-width: 1023.98px) {
  .oink-reto { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
  /* Cifras apiladas: el trazo pasa arriba de la segunda. */
  .oink-reto__metrics { display: grid; grid-template-columns: 1fr; row-gap: 18px; --oink-sep-end: 0px; }
  .oink-reto__metrics > .oink-metric--sep + .oink-metric--sep { padding: 18px 0 0; box-shadow: inset 0 1px var(--oink-sep-line); }
}

@media (max-width: 767.98px) {
  .oink-reto { grid-template-columns: minmax(0, 1fr); row-gap: 32px; }
  .oink-reto__photo { min-height: 0; aspect-ratio: 2 / 3; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Bloque 3 · #como-funciona · cómo funciona + entrega de leads (fondo blanco)
   Pasos: rejilla de 4 columnas; los iconos 3D se apoyan en la línea-camino (.oink-path), que va del centro
   del primer icono al del último. El paso 4 se separa con un panel beige detrás (::before, z −1: por eso
   la sección aísla su contexto de apilamiento). Orden de capas: panel beige < camino < iconos.
   Los corchetes cuelgan de los pasos 1 y 4 (posición absoluta bajo la fila; la lista les deja hueco).
   < 768 px: los pasos se apilan; icono a la izquierda sobre el camino vertical y los corchetes pasan a
   ser etiquetas encima del paso 01 y del 04. El camino entra por debajo del panel beige del 04.
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
.oink-sec--como-funciona { isolation: isolate; }
/* Los iconos traen aire transparente arriba: el titular puede ir más cerca. */
.oink-sec--como-funciona .oink-sec__head { margin-bottom: 28px; }

.oink-flow {
  --flow-gap: 32px;                   /* hueco entre pasos */
  --flow-icon: 92px;                  /* lado de los iconos 3D */
  --flow-col: calc((100% - 3 * var(--flow-gap)) / 4);
  --flow-brackets: 46px;              /* alto reservado bajo la fila para los corchetes */
}

.oink-flow__track { position: relative; }

/* La línea-camino: del centro del icono 1 al del 4, a la altura de las peanas (72 % del icono). Cada
   dirección lleva su SVG interior (.oink-path__frame) con preserveAspectRatio="none": a 1440 y 1280 px la
   escala es 1:1; en tablet se encoge algo más en horizontal que en vertical y el grosor apenas cambia. */
.oink-path {
  position: absolute;
  z-index: 0;
  top: 0;
  left: calc(var(--flow-icon) / 2);
  width: calc(100% - var(--flow-col));
  height: var(--flow-icon);
  overflow: visible;
  pointer-events: none;
}
.oink-path__line {
  fill: none;
  stroke: color-mix(in srgb, var(--oink-blue) 26%, var(--oink-white));
  stroke-width: 12;
  stroke-linecap: round;
}
.oink-path__frame { overflow: visible; }
.oink-path__line--v { display: none; }

/* Dibujo (spec §5; tarea 11): de 01 a 04 en 1.200 ms --ease-in-out cuando entran los pasos. Con pathLength="1", guion 1 y
   hueco 2: oculta (offset 1,01), ningún extremo de guion cae en la línea. Con guion y hueco de 1 y offset 1, el guion
   terminaba justo en el origen y el remate redondo dejaba un punto (y otro al final, donde empezaba el guion siguiente).
   Al terminar (offset 0) el guion la cubre entera. Solo con oink-reveal-on: sin main.js se ve dibujada. Como en la entrada de
   bloques, solo se anima el dibujo: ocultarla al cargar es instantáneo. Solo en pantalla: al imprimir sale dibujada.
   Y solo si los pasos llevan data-reveal (revisión final): sin él nadie les pone .is-visible y la línea se quedaría sin
   dibujar; así, una plantilla sin data-reveal la enseña dibujada (pierde la entrada, nada más). */
@media screen {
  html.oink-reveal-on .oink-flow__track:has(.oink-step[data-reveal]) .oink-path__line {
    stroke-dasharray: 1 2;
    stroke-dashoffset: 1.01;
  }
}
html.oink-reveal-on .oink-flow__track:has(.oink-step.is-visible) .oink-path__line {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1200ms var(--ease-in-out);
}

.oink-steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: var(--flow-gap);
  padding: 0 0 var(--flow-brackets);
  list-style: none;
}

.oink-step { position: relative; }

/* Cada paso entra cuando la línea toca su icono (en fila, desde 768 px). Con 1.200 ms de --ease-in-out el trazo llega al borde
   del icono 02 hacia los 510 ms, al del 03 hacia los 600 y al del 04 hacia los 880 (calculado sobre la curva; acelera en el
   centro, así que 02 y 03 llegan casi juntos y un escalonado lineal con --i no coincidiría). Sustituye a los 60 ms de --i;
   en móvil los pasos van apilados y entran uno a uno al bajar, con el escalonado normal. */
@media (min-width: 768px) {
  html.oink-reveal-on .oink-step.is-visible { transition-delay: var(--oink-step-at, 0ms); }
  .oink-step[data-step="2"] { --oink-step-at: 510ms; }
  .oink-step[data-step="3"] { --oink-step-at: 600ms; }
  .oink-step[data-step="4"] { --oink-step-at: 880ms; }
}

.oink-step__icon {
  position: relative;
  z-index: 1;                         /* por encima del camino */
  width: var(--flow-icon);
  height: var(--flow-icon);
  margin-bottom: 14px;
  filter: drop-shadow(0 10px 14px color-mix(in srgb, var(--oink-blue) 16%, transparent));
}

.oink-step__title {
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.3;
}
.oink-step__num {
  margin-inline-end: 6px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--oink-blue);
}
.oink-step__text {
  margin-top: 6px;
  color: var(--oink-gray);
  text-wrap: pretty;
}

/* Paso 4 · tu equipo: el panel beige llega hasta abajo del todo, así envuelve también su corchete. Sobre blanco, el beige
   apenas se distingue: lleva el filo interior azul al 14 % de las tarjetas beige (ajustes de Oink, §3). El «04» va en azul
   como el resto del título (los títulos ya no llevan tinta); lo que distingue el paso son el panel y el corchete. */
.oink-step--team::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -8px 0 calc(-1 * var(--flow-brackets) + 2px) -16px;
  border-radius: var(--radius-lg);
  background-color: var(--oink-beige);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--oink-blue) 14%, transparent);
}
.oink-step--team { padding-inline-end: 16px; }   /* el panel no pasa del borde del contenedor */
.oink-step--team .oink-step__text { color: color-mix(in srgb, var(--oink-gray) 85%, var(--oink-ink)); }

/* Corchetes: una U abierta hacia arriba bajo los pasos que abarca, con la etiqueta en el centro. */
.oink-bracket {
  position: absolute;
  top: calc(100% + 14px);
  left: 0;
  height: 14px;
}
.oink-bracket::before {
  content: "";
  position: absolute;
  inset: 0 var(--bracket-end, 0) 0 0;
  border: 2px solid currentColor;
  border-top: 0;
  border-radius: 0 0 12px 12px;
}
.oink-bracket__label {
  position: absolute;
  top: 100%;
  left: calc(50% - var(--bracket-end, 0px) / 2);
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: 0 14px;
  border-radius: var(--radius-pill);
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  transform: translate(-50%, -50%);
}

.oink-bracket--oink {
  width: calc(300% + 2 * var(--flow-gap));
  color: var(--oink-blue);
}
.oink-bracket--oink .oink-bracket__label {
  background-color: var(--oink-blue);
  color: var(--oink-white);
}

.oink-bracket--team {
  width: 100%;
  --bracket-end: 16px;               /* dentro del panel beige: el mismo margen a los dos lados */
  color: color-mix(in srgb, var(--oink-ink) 22%, var(--oink-beige));
}
.oink-bracket--team .oink-bracket__label {
  background-color: var(--oink-white);
  color: var(--oink-ink);
  box-shadow: 0 1px 2px rgb(11 12 31 / 0.08), 0 6px 14px -6px rgb(11 12 31 / 0.18);
}

/* La nota bajo el diagrama respira 32 px por arriba y por abajo (ajustes de Oink, §6; antes 14 y 0). El de abajo se funde con
   el margen superior de la franja de leads (36–40 px): lo que cuenta es que no quede pegada a los corchetes. */
.oink-flow__note {
  margin-top: 32px;
  margin-bottom: 32px;
  font-size: 1.0625rem;
  font-weight: 500;
  line-height: 1.5;
  text-wrap: pretty;
}

/* ── Entrega de leads: la hoja a la izquierda y, a su derecha, el titular y las dos tarjetas ───────── */
.oink-leads {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(0, 0.6fr) minmax(0, 0.6fr);
  grid-template-areas:
    "sheet head  head"
    "sheet excel crm";
  grid-template-rows: auto 1fr;
  column-gap: 16px;
  row-gap: 20px;
  margin-top: clamp(36px, 2.8vw, 40px);
}
.oink-leads__head { grid-area: head; align-self: end; }
.oink-leads__head .oink-eyebrow { margin-bottom: 12px; }
.oink-leads__title { font-size: clamp(1.5rem, 2.3vw, 2rem); }

.oink-lead-card--excel { grid-area: excel; }
.oink-lead-card--crm { grid-area: crm; }
.oink-lead-card {
  padding: 20px 20px 22px;
  border-radius: var(--radius-md);
  background-color: var(--oink-beige);   /* las herramientas de tu equipo: el beige de «Tu equipo» */
  /* Tarjeta beige sobre blanco: un filo interior azul al 14 % para que se distinga (ajustes de Oink, §3). */
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--oink-blue) 14%, transparent);
}
.oink-lead-card h3 {
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.3;
}
.oink-lead-card p {
  margin-top: 8px;
  color: var(--oink-gray);
  line-height: 1.55;
  text-wrap: pretty;
}

/* La hoja: una ventana de hoja de cálculo genérica (sin marcas), con datos ficticios. */
.oink-sheet {
  grid-area: sheet;
  display: flex;
  flex-direction: column;
  margin-inline-end: 24px;
  overflow: hidden;
  border-radius: var(--radius-md);
  background-color: var(--oink-white);
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--oink-blue) 12%, transparent),
    0 24px 48px -20px color-mix(in srgb, var(--oink-blue) 35%, transparent);
  font-size: 0.875rem;
  line-height: 1.2;
  --sheet-line: color-mix(in srgb, var(--oink-ink) 9%, transparent);
  --sheet-head: color-mix(in srgb, var(--oink-blue) 6%, var(--oink-white));
}

.oink-sheet__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  padding: 0 16px;
  background-color: var(--oink-blue);
  color: var(--oink-white);
}
.oink-sheet__file {
  display: inline-flex;
  white-space: nowrap;
  align-items: center;
  gap: 10px;
  font-weight: 700;
}
/* Icono de hoja: una cuadrícula de 2 × 3 dibujada con dos degradados (sin imagen). */
.oink-sheet__file::before {
  content: "";
  width: 16px;
  height: 16px;
  border-radius: 3px;
  background:
    linear-gradient(var(--oink-blue) 0 0) 50% 0 / 2px 100% no-repeat,
    linear-gradient(var(--oink-blue) 0 0) 0 34% / 100% 2px no-repeat,
    linear-gradient(var(--oink-blue) 0 0) 0 68% / 100% 2px no-repeat,
    var(--oink-white);
}
.oink-sheet__live {
  display: inline-flex;
  white-space: nowrap;
  align-items: center;
  gap: 8px;
  font-weight: 500;
}
.oink-sheet__live::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--oink-white);
  box-shadow: 0 0 0 3px rgb(255 255 255 / 0.3);
}

.oink-sheet__formula {
  display: flex;
  align-items: center;
  min-height: 34px;
  border-bottom: 1px solid var(--sheet-line);
  color: var(--oink-ink);
}
.oink-sheet__formula > span { padding: 0 12px; }
.oink-sheet__ref {
  min-width: 52px;
  font-weight: 700;
  box-shadow: inset -1px 0 var(--sheet-line);
}
.oink-sheet__fx {
  font-style: italic;
  font-weight: 700;
  color: var(--oink-gray);
}

.oink-sheet__table {
  flex: 1;
  width: 100%;
  border-collapse: collapse;
}
.oink-sheet__table :is(th, td) {
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--sheet-line);
  text-align: start;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.oink-sheet__table tr > :first-child { border-inline-start: 0; }
.oink-sheet__table tr > :last-child { border-inline-end: 0; }
.oink-sheet__table tbody tr:last-child > * { border-bottom: 0; }
.oink-sheet__table thead th {
  background-color: var(--sheet-head);
  font-weight: 700;
  color: var(--oink-ink);
}
/* Columna de números de fila, como en cualquier hoja. */
.oink-sheet__table :is(thead, tbody) tr > th:first-child {
  width: 40px;
  padding: 0 6px;
  background-color: var(--sheet-head);
  font-weight: 500;
  color: var(--oink-gray);
  text-align: center;
}
.oink-sheet__table td { color: var(--oink-ink); }
.oink-sheet__table td:nth-child(4),
.oink-sheet__table td:nth-child(5) { color: var(--oink-gray); }

/* Fila que aún no ha entrado: la clase solo la pone main.js (y la quita cada 1,5 s), así que sin JS se ven las 5.
   Sigue ocupando su sitio para que la hoja no cambie de alto. Entra (tarea 11) con un fundido y 8 px en 250 ms --ease-out;
   visibility no se anima, así que se pinta desde el primer fotograma. Solo se anima la entrada: pasar a pendiente (al
   cargar) es instantáneo. Solo en pantalla: al imprimir salen las 5 filas. */
.oink-sheet__rows tr:not(.is-pending) { transition: opacity 250ms var(--ease-out), transform 250ms var(--ease-out); }
@media screen {
  .oink-sheet__rows tr.is-pending {
    visibility: hidden;
    opacity: 0;
    transform: translateY(8px);
  }
}

/* La última fila que ha entrado: celda activa con el anillo azul, como la celda seleccionada. */
.oink-sheet__rows tr.is-latest > th:first-child {
  background-color: color-mix(in srgb, var(--oink-blue) 16%, var(--oink-white));
  color: var(--oink-blue);
  font-weight: 700;
}
.oink-sheet__rows tr.is-latest > .oink-sheet__name {
  box-shadow: inset 0 0 0 2px var(--oink-blue);
  font-weight: 700;
}

.oink-sheet__status {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 0 10px;
  border-radius: var(--radius-pill);
  background-color: var(--oink-beige);
  /* Beige sobre blanco: el filo interior azul al 14 % de las tarjetas beige (ajustes de Oink), para que se distinga. */
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--oink-blue) 14%, transparent);
  font-weight: 700;
  color: var(--oink-ink);
}
.oink-sheet__status--nuevo {
  background-color: color-mix(in srgb, var(--oink-blue) 10%, var(--oink-white));
  box-shadow: none;
  color: var(--oink-blue);
}
.oink-sheet__status--alta {
  background-color: var(--oink-blue);
  box-shadow: none;
  color: var(--oink-white);
}

/* ── #como-funciona en tablet: pasos más estrechos; la franja de leads, con el titular arriba ─────── */
@media (max-width: 1199.98px) {
  .oink-flow { --flow-gap: 24px; --flow-icon: 84px; }
  .oink-leads {
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    grid-template-areas:
      "head  head"
      "sheet excel"
      "sheet crm";
    grid-template-rows: auto auto 1fr;
    column-gap: 0;                    /* la hoja ya lleva su margen a la derecha */
    row-gap: 16px;
  }
  .oink-leads__head { margin-bottom: 8px; }
  .oink-lead-card--crm { align-self: start; }
}

@media (max-width: 1023.98px) {
  .oink-flow { --flow-gap: 20px; --flow-icon: 76px; }
  .oink-step__title { font-size: 1.0625rem; }
  .oink-sheet__table tr > :nth-child(4) { display: none; }   /* sin la columna del teléfono */
  .oink-sheet__live-label { display: none; }                  /* «Actualizado» no cabe: queda la hora */
}

/* ── #como-funciona en móvil (< 768 px): pasos apilados sobre el camino vertical ─────────────────── */
@media (max-width: 767.98px) {
  .oink-flow {
    --flow-icon: 64px;
    --flow-inset: 12px;               /* los pasos se separan del borde: así cabe el panel beige del 04 */
    --flow-tag: 40px;                 /* etiqueta «Oink» (30 px) y su margen (10 px) sobre el paso 01 */
  }

  /* El camino vertical va del centro del icono 01 hasta el final de la lista; por debajo del panel beige
     (z −2 < −1), así que se ve entrar en el paso 04 y no lo cruza. */
  .oink-path {
    z-index: -2;
    top: calc(var(--flow-tag) + var(--flow-icon) / 2);
    left: calc(var(--flow-inset) + var(--flow-icon) / 2 - 6px);
    width: 12px;
    /* Un SVG en absoluto no se estira con top + bottom (es un elemento reemplazado): alto explícito. */
    height: calc(100% - var(--flow-tag) - var(--flow-icon) / 2);
  }
  .oink-path__line { stroke-width: 10; }
  .oink-path__line--h { display: none; }
  .oink-path__line--v { display: inline; }

  .oink-steps {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 28px;
    padding-bottom: 0;
  }

  .oink-step {
    display: grid;
    grid-template-columns: var(--flow-icon) minmax(0, 1fr);
    grid-template-areas:
      ".    tag"
      "icon title"
      "icon text";
    grid-template-rows: auto auto 1fr;
    column-gap: 16px;
    align-items: start;
    padding-inline: var(--flow-inset);
  }
  .oink-step__icon { grid-area: icon; margin: 0; }
  .oink-step__title { grid-area: title; padding-top: 6px; }
  .oink-step__text { grid-area: text; margin-top: 4px; }

  .oink-step--team { padding-inline-end: var(--flow-inset); }
  .oink-step--team::before { inset: -14px 0; }

  /* Los corchetes pasan a ser etiquetas encima del paso (spec §3): «Oink» sobre el 01, «Tu equipo» sobre el 04. */
  .oink-bracket {
    grid-area: tag;
    position: static;
    width: auto;
    height: auto;
    justify-self: start;
    margin-bottom: 10px;
  }
  .oink-bracket::before { display: none; }
  .oink-bracket__label { position: static; transform: none; }

  .oink-flow__note { font-size: 1rem; }   /* los 32 px de arriba y abajo valen también en móvil */

  .oink-leads {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "head" "excel" "sheet" "crm";
    grid-template-rows: none;
  }
  .oink-sheet { margin-inline-end: 0; }
  .oink-sheet__bar { padding: 0 12px; }
  .oink-sheet__table :is(th, td) { padding: 0 8px; }
  .oink-sheet__table :is(thead, tbody) tr > th:first-child { width: 30px; }
}

/* Móviles de 320–379 px: la hoja deja también la hora (el nombre, el interés y el estado son lo que cuenta). */
@media (max-width: 379.98px) {
  .oink-sheet__table tr > :nth-child(5) { display: none; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Bloque 4 · #propuesta-valor · propuesta + para quién (fondo azul)
   El momento de marca: azul a sangre, titulares grandes y la franja de fotos a todo el ancho.
   ≥ 1024 px: la propuesta a la izquierda (≈ 63 %) y «para quién» a la derecha, pegado abajo, encima del
   carrusel. < 1024 px: una columna. El carrusel va fuera del contenedor, de borde a borde.
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
.oink-sec--propuesta-valor {
  isolation: isolate;
  overflow: clip;
  /* Abajo cierra la franja de fotos, con más aire que el padding normal (ajustes de Oink, §6: 104 px; antes 64).
     El azul es plano: ya no se hunde hacia el pie detrás del carrusel. */
  padding-bottom: 104px;
}

.oink-pv {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  column-gap: clamp(40px, 5vw, 72px);
  align-items: end;
}
.oink-pv .oink-eyebrow { margin-bottom: 12px; }

.oink-pv__body {
  max-width: 62ch;
  margin-top: 20px;
  text-wrap: pretty;
}

/* La frase del partner: más grande que el cuerpo, con «partner de captación deportiva» en el verde de la marca y sin
   subrayado (ajustes de Oink, §3). Verde sobre azul: 6,4:1. Solo aquí va el verde como texto, porque el fondo es azul. */
.oink-pv__partner {
  max-width: 34ch;
  margin-top: 20px;
  font-size: clamp(1.25rem, 0.95rem + 0.75vw, 1.5rem);
  font-weight: 700;
  line-height: 1.35;
  text-wrap: balance;
}
.oink-pv__mark {
  color: var(--oink-green);
  text-decoration-line: none;
}

/* «Para quién» es un sub-bloque: su h2 va un escalón por debajo del de la propuesta (como el de la franja de
   leads de #como-funciona). */
.oink-pv__para-title { font-size: clamp(1.5rem, 2.3vw, 2.125rem); }

.oink-pv__cierre {
  margin-top: 14px;
  font-weight: 500;
  text-wrap: pretty;
}
.oink-pv__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;                   /* área táctil */
  font-weight: 700;
  text-decoration-line: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 5px;
}
.oink-pv__arrow { flex: none; width: 20px; height: 20px; }
@media (hover: hover) and (pointer: fine) {
  .oink-pv__link:hover { text-decoration-color: var(--oink-orange); }
}

/* ── Carrusel de disciplinas ────────────────────────────────────────────────────────────────────────
   Un bucle continuo (spec §5; tarea 11): la pista avanza translateX(−50 %) en 40 s, lineal (movimiento
   constante), y vuelve a empezar. Las dos .oink-marquee__group son iguales y cada una lleva detrás el mismo
   hueco que separa las tarjetas, así que −50 % es justo un grupo y el bucle no salta. La copia (aria-hidden +
   inert) solo existe para cerrar el bucle. El ancho de tarjeta en vw hace que un grupo sea siempre más ancho
   que la pantalla, para que el bucle no deje huecos. La primera tarjeta se alinea con el contenedor (padding =
   margen del contenedor) y las tarjetas se desvanecen en los márgenes con una máscara.
   Se para con el ratón encima o con el foco (la región es enfocable). Con movimiento reducido (al final de la
   hoja) se queda quieto, sin la copia, y la pista se desplaza a mano con scroll-snap. */
.oink-marquee {
  --disc-w: clamp(168px, 14vw, 320px);
  --disc-gap: clamp(12px, 1.25vw, 20px);
  --marquee-edge: max(var(--oink-gutter), (100% - 1200px) / 2);
  margin-top: clamp(48px, 4.5vw, 64px);   /* aire entre el texto y las fotos (ajustes de Oink, §6; antes 24–32 px) */
  padding: 0 var(--marquee-edge) 8px;    /* abajo, aire para la barra de desplazamiento (movimiento reducido) */
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 var(--marquee-edge), #000 calc(100% - var(--marquee-edge)), transparent);
  mask-image: linear-gradient(90deg, transparent, #000 var(--marquee-edge), #000 calc(100% - var(--marquee-edge)), transparent);
}
/* La máscara se come el anillo de foco en los bordes (afecta a todo lo que pinta la región, también su outline). Con el
   foco de teclado se quita: el carrusel está parado y el anillo se ve entero. */
.oink-marquee:focus-visible {
  outline-offset: -2px;
  -webkit-mask-image: none;
  mask-image: none;
}

.oink-marquee__track {
  display: flex;
  width: max-content;
  animation: oink-marquee 40s linear infinite;
}
.oink-marquee:focus-within .oink-marquee__track { animation-play-state: paused; }
/* Con main.js, el bucle arranca cuando el carrusel entra en pantalla: así se ve empezar con la primera tarjeta alineada con el
   contenedor, y no en un punto cualquiera de una vuelta que lleva corriendo desde que cargó la página. Solo si la región lleva
   data-reveal (revisión final): sin él nadie le pone .is-visible, y el carrusel corre desde la carga en vez de quedarse parado. */
html.oink-reveal-on .oink-marquee[data-reveal]:not(.is-visible) .oink-marquee__track { animation-play-state: paused; }
@media (hover: hover) and (pointer: fine) {
  .oink-marquee:hover .oink-marquee__track { animation-play-state: paused; }
}
@keyframes oink-marquee {
  to { transform: translateX(-50%); }
}
.oink-marquee__group {
  display: flex;
  gap: var(--disc-gap);
  margin: 0;
  padding: 0 var(--disc-gap) 0 0;
  list-style: none;
}

.oink-disc {
  flex: none;
  width: var(--disc-w);
  scroll-snap-align: start;
}
/* La foto con el mapa azul de .oink-photo y la etiqueta en la placa beige pequeña (components.css): 8 px de radio y 5 px
   de sombra, 8 × 10 px de relleno y 14 px hasta el borde de la foto, con la sombra dentro. La palabra más larga,
   «Entrenamiento», mide 134 px a 17 px, 127 a 16 y 119 a 15 (Montserrat 700), y la tarjeta (--disc-w) mide 168 px
   hasta 1199 y 14vw de ahí en adelante: con 17 px y 14 + 10 px de margen y relleno hacen falta 186 px de tarjeta
   (1.328 px de pantalla) para dejar 3 px de aire. Por debajo de 1340 px la placa se acerca a 12 px del borde y la
   letra baja a 0,9375rem (15 px: 5 px de aire en la tarjeta de 168). Lo mide «ajustes: etiquetas de disciplina…». */
.oink-disc__photo {
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-md);
}
.oink-disc__label {
  inset: auto 14px 14px;
  padding: 8px 10px;
  border-radius: 8px;
  box-shadow: 5px 5px 0 var(--oink-orange);
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.25;
  text-wrap: balance;
}

/* Encuadres: las fotos son de stock y llevan marca. La foto se amplía un poco (la caja tiene la misma proporción
   que el archivo, así que object-position no recorta nada) para que la marca quede fuera o detrás de la placa:
   «SCHWINN», en el bastidor de la bici, sale del encuadre por abajo; la pala de pádel baja al pie, detrás de la placa
   «Pádel», donde «METALBONE» no se ve, y siguen a la vista la red, la pista y la pelota. */
.oink-disc--padel .oink-disc__photo img    { transform: scale(1.2); transform-origin: 65% 15%; }
.oink-disc--boutique .oink-disc__photo img { transform: scale(1.12); transform-origin: 50% 0; }

@media (max-width: 1339.98px) {
  .oink-disc__label { inset: auto 12px 12px; font-size: 0.9375rem; }
}

@media (max-width: 1023.98px) {
  .oink-pv { grid-template-columns: minmax(0, 1fr); }
  .oink-pv__para { margin-top: 40px; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Bloque 5 · #servicios · qué hacemos (fondo blanco)
   Con JS (tarea 9), desde 768 px: pestañas verticales a la izquierda y el panel activo a la derecha (texto +
   escenario con la imagen del servicio). El escenario tiene un alto fijo, así el bloque no cambia de alto al
   cambiar de pestaña. Por debajo de 768 px, acordeón. Sin JS: los 4 paneles apilados (components.css).
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
.oink-svc {
  --svc-stage-h: 420px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

/* Lista de pestañas: cuatro botones que llenan el alto del escenario; el activo, en azul. */
.oink-svc__list {
  flex-direction: column;
  gap: 8px;
}
.oink-svc__tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 4px;
  min-height: 64px;
  padding: 12px 20px;
  border: 0;
  border-radius: var(--radius-md);
  background-color: color-mix(in srgb, var(--oink-blue) 6%, var(--oink-white));
  color: var(--oink-ink);
  font: inherit;
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.25;
  text-align: start;
  cursor: pointer;
  transition: transform 160ms var(--ease-out);   /* al pulsar (propuesta 2); el color cambia sin fundido */
}
.oink-svc__tab:active { transform: scale(0.98); }   /* 0,98: en una pieza tan ancha, 0,97 se nota demasiado */
.oink-svc__num {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--oink-blue);
}
.oink-svc__tab .oink-svc__num { font-size: 0.9375rem; }
.oink-svc__tab[aria-selected="true"] {
  background-color: var(--oink-blue);
  color: var(--oink-white);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--oink-blue) 25%, transparent),
              0 14px 28px -14px color-mix(in srgb, var(--oink-blue) 80%, transparent);
}
.oink-svc__tab[aria-selected="true"] .oink-svc__num { color: rgb(255 255 255 / 0.85); }
@media (hover: hover) and (pointer: fine) {
  .oink-svc__tab[aria-selected="false"]:hover { background-color: color-mix(in srgb, var(--oink-blue) 11%, var(--oink-white)); }
}

/* Paneles: sin JS van apilados; cada uno, texto a la izquierda y escenario a la derecha. */
.oink-svc__panels {
  display: grid;
  row-gap: 24px;
}
.oink-svc__panel {
  display: grid;
  grid-template-columns: minmax(0, 0.78fr) minmax(0, 1fr);
  column-gap: clamp(28px, 3.4vw, 48px);
  align-items: start;
}
/* El texto arranca siempre a la misma altura: al cambiar de pestaña el titular no salta. */
.oink-svc__copy { padding-top: 28px; }

/* Rótulo del panel («01 Diagnóstico y estrategia»): solo sin JS y desde 768 px, que es cuando no hay pestaña
   ni disparador que diga qué servicio es. */
.oink-svc__kicker {
  display: none;
  margin-bottom: 10px;
  font-weight: 800;
  line-height: 1.3;
  color: var(--oink-blue);
}
.oink-svc__kicker .oink-svc__num { margin-inline-end: 4px; }

.oink-svc__title {
  font-size: clamp(1.375rem, 1.1rem + 0.55vw, 1.625rem);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.oink-svc__text {
  margin-top: 14px;
  color: var(--oink-gray);
  text-wrap: pretty;
}

/* Escenario de la imagen: un panel azul muy claro donde se apoya el producto. Mide lo mismo en los cuatro. */
.oink-svc__stage {
  position: relative;
  isolation: isolate;
  container-type: inline-size;
  display: grid;
  place-items: center;
  height: var(--svc-stage-h);
  overflow: hidden;
  border-radius: var(--radius-lg);
  background-color: color-mix(in srgb, var(--oink-blue) 7%, var(--oink-white));
  --mock-line: color-mix(in srgb, var(--oink-ink) 9%, transparent);
  /* Palomilla blanca para los círculos azules de «visto» (plan y notas del móvil). */
  --mock-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.5 8.5l2.3 2.3L11.5 6' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --mock-shadow: 0 1px 2px color-mix(in srgb, var(--oink-blue) 12%, transparent),
                 0 24px 48px -20px color-mix(in srgb, var(--oink-blue) 38%, transparent);
}

/* Disparador del acordeón (< 768 px). Sin JS es el rótulo de cada panel; con JS, el que está abierto va en azul
   y lleva un chevron que gira en 250 ms --ease-out (tarea 11). */
.oink-svc__trigger {
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 60px;
  padding: 12px 18px;
  border: 0;
  border-radius: var(--radius-md);
  background-color: color-mix(in srgb, var(--oink-blue) 6%, var(--oink-white));
  color: var(--oink-ink);
  font: inherit;
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.25;
  text-align: start;
  cursor: pointer;
}
html:not(.oink-js) .oink-svc__trigger { cursor: default; }   /* sin JS es solo un rótulo: no abre ni cierra nada */
.oink-js .oink-svc__trigger { transition: transform 160ms var(--ease-out); }   /* al pulsar (propuesta 2) */
.oink-js .oink-svc__trigger:active { transform: scale(0.98); }
/* El chevron baja 2 px cerrado y sube 2 px abierto (era un margin de ±4 px, que con el centrado del flex da ±2 px): va en el
   transform para que gire y se desplace a la vez, sin saltar. */
.oink-js .oink-svc__trigger::after {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  margin: 0 4px 0 auto;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  transform: translateY(-2px) rotate(45deg);
}
.oink-js .oink-svc__trigger[aria-expanded="true"] {
  background-color: var(--oink-blue);
  color: var(--oink-white);
}
.oink-js .oink-svc__trigger[aria-expanded="true"] .oink-svc__num { color: rgb(255 255 255 / 0.85); }
.oink-js .oink-svc__trigger[aria-expanded="true"]::after { transform: translateY(2px) rotate(-135deg); }
/* El giro, solo con el bloque ya en pantalla: al iniciar, main.js cierra tres disparadores y no tienen por qué girar. Con el
   teclado (Intro o Espacio en un disparador con el foco visible), el giro y el panel que se abre van al instante. */
.oink-js [data-tabs].is-visible .oink-svc__trigger::after { transition: transform 250ms var(--ease-out); }
.oink-js [data-tabs].is-visible .oink-svc__trigger:focus-visible::after { transition: none; }
.oink-js [data-tabs].is-visible:has(.oink-acc-trigger:focus-visible) [role="tabpanel"] { transition-duration: 0s; }

/* ── Modo pestañas (con JS, desde 768 px; solo en pantalla: al imprimir, los paneles van apilados como sin JS) ── */
@media (min-width: 768px) {
  html:not(.oink-js) .oink-svc__kicker { display: block; }
}
@media screen and (min-width: 768px) {
  .oink-js .oink-svc {
    grid-template-columns: clamp(208px, 23%, 280px) minmax(0, 1fr);
    column-gap: clamp(24px, 3vw, 40px);
  }
}

/* ── 01 · El plan de captación (documento en HTML, datos de ejemplo) ──────────────────────────────── */
.oink-plan {
  position: relative;
  width: min(100% - 48px, 340px);
  padding: 20px 22px 18px;
  border-radius: var(--radius-md);
  background-color: var(--oink-white);
  box-shadow: var(--mock-shadow);
  font-size: 0.875rem;
  line-height: 1.35;
  color: var(--oink-ink);
}
/* Segunda hoja detrás, algo girada: es un documento de varias páginas. */
.oink-plan::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-color: var(--oink-white);
  box-shadow: var(--mock-shadow);
  transform: translate(14px, 10px) rotate(3.5deg);
}
.oink-plan__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.oink-plan__doc {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 1rem;
  font-weight: 800;
}
/* Icono de documento: un rectángulo azul con tres renglones (degradados, sin imagen). */
.oink-plan__doc::before {
  content: "";
  width: 18px;
  height: 22px;
  border-radius: 4px;
  background:
    linear-gradient(var(--oink-white) 0 0) 4px 6px / 10px 2px no-repeat,
    linear-gradient(var(--oink-white) 0 0) 4px 10px / 10px 2px no-repeat,
    linear-gradient(var(--oink-white) 0 0) 4px 14px / 6px 2px no-repeat,
    var(--oink-blue);
}
.oink-plan__tag {
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background-color: var(--oink-beige);
  /* Beige sobre blanco: el filo interior azul al 14 % de las tarjetas beige (ajustes de Oink), para que se distinga. */
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--oink-blue) 14%, transparent);
  font-weight: 700;
  white-space: nowrap;
}
.oink-plan__meta {
  margin-top: 4px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--mock-line);
  color: var(--oink-gray);
}
.oink-plan__row {
  display: grid;
  gap: 6px;
  padding: 12px 0;
  border-bottom: 1px solid var(--mock-line);
}
.oink-plan__key {
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--oink-gray);
}
.oink-plan__val { font-size: 1rem; font-weight: 700; }
.oink-plan__note { color: var(--oink-gray); }
.oink-plan__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.oink-plan__chip {
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background-color: color-mix(in srgb, var(--oink-blue) 10%, var(--oink-white));
  font-weight: 700;
  color: var(--oink-blue);
}
.oink-plan__chip--main { background-color: var(--oink-blue); color: var(--oink-white); }
/* Reparto del presupuesto: una barra partida con 2 px de aire entre los dos tramos. */
.oink-plan__split {
  display: flex;
  gap: 2px;
  height: 10px;
}
.oink-plan__seg { border-radius: var(--radius-pill); }
.oink-plan__seg--a { flex: 70; background-color: var(--oink-blue); }
.oink-plan__seg--b { flex: 30; background-color: color-mix(in srgb, var(--oink-blue) 30%, var(--oink-white)); }
.oink-plan__legend {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-weight: 500;
}
.oink-plan__ok {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  font-weight: 700;
  color: var(--oink-blue);
}
/* Marca de visto: un círculo azul con la palomilla. */
.oink-plan__ok::before,
.oink-phone__notes li::before {
  content: "";
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--mock-check) center / 100% no-repeat, var(--oink-blue);
}

/* ── 02 · Tres anuncios: Stories, Feed y Reels (fotos tal cual, sin el mapa azul: imitan anuncios reales) ──── */
.oink-ads {
  --ad-w: min(28cqi, 144px);          /* Stories y Reels, 9:16 */
  --feed-w: min(33cqi, 166px);        /* Feed, 4:5 */
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(6px, 2cqi, 12px);
}
.oink-ad {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin: 0;
}
.oink-ad--story { order: 1; }
.oink-ad--feed  { order: 2; }
.oink-ad--reel  { order: 3; }

.oink-ad__frame {
  overflow: hidden;
  border-radius: 14px;
  box-shadow: var(--mock-shadow);
}
.oink-ad--feed .oink-ad__frame {
  width: var(--feed-w);
  background-color: var(--oink-white);
}
.oink-ad--story .oink-ad__frame,
.oink-ad--reel .oink-ad__frame {
  width: var(--ad-w);
  aspect-ratio: 9 / 16;
}
.oink-ad--feed .oink-ad__media { aspect-ratio: 4 / 5; border-radius: 0; }

.oink-ad__bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px;
  font-size: 0.875rem;
  line-height: 1.2;
}
.oink-ad__avatar {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: var(--oink-blue);
  box-shadow: 0 0 0 2px var(--oink-white), 0 0 0 3.5px color-mix(in srgb, var(--oink-blue) 45%, var(--oink-white));
}
.oink-ad__who { display: grid; min-width: 0; }
.oink-ad__name { font-weight: 700; color: var(--oink-ink); }
.oink-ad__sub { color: var(--oink-gray); }
.oink-ad__cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 38px;
  padding: 0 12px;
  background-color: color-mix(in srgb, var(--oink-blue) 7%, var(--oink-white));
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--oink-blue);
}
.oink-ad__chev {
  width: 7px;
  height: 7px;
  border: solid currentColor;
  border-width: 2px 2px 0 0;
  transform: rotate(45deg);
}

/* Encima de la foto (z-index 2): barras de progreso y avatar del Story, pegatina, play y pie del Reel. */
.oink-ad__top,
.oink-ad__sticker,
.oink-ad__play,
.oink-ad__caption { position: absolute; z-index: 2; }
.oink-ad__top {
  inset: 8px 8px auto;
  display: grid;
  gap: 8px;
}
.oink-ad__progress { display: flex; gap: 3px; }
.oink-ad__progress > span {
  flex: 1;
  height: 2px;
  border-radius: 1px;
  background-color: rgb(255 255 255 / 0.5);
  /* Sin capa sobre la foto (ajustes de Oink), las barras blancas se perdían sobre una foto clara: un canto y una sombra
     finos de tinta, solo aquí, dentro del anuncio. */
  box-shadow: 0 0 0 0.5px color-mix(in srgb, var(--oink-ink) 30%, transparent), 0 1px 3px color-mix(in srgb, var(--oink-ink) 40%, transparent);
}
.oink-ad__progress > span:first-child { background-color: var(--oink-white); }
.oink-ad__sticker {
  inset: 34% 8px auto;
  margin-inline: auto;
  width: fit-content;
  padding: 6px 10px;
  border-radius: 10px;
  background-color: var(--oink-white);
  font-size: 0.875rem;
  font-weight: 800;
  line-height: 1.2;
  text-align: center;
  text-wrap: balance;
  color: var(--oink-blue);
  transform: rotate(-3deg);
}
.oink-ad__play {
  inset: 0;
  width: 44px;
  height: 44px;
  margin: auto;
  border-radius: 50%;
  background-color: rgb(255 255 255 / 0.28);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.oink-ad__play::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 8px 0 8px 13px;
  border-color: transparent transparent transparent var(--oink-white);
  transform: translateX(2px);
}
.oink-ad__caption {
  inset: auto 10px 12px;
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--oink-white);
}
.oink-ad__cap { color: var(--oink-blue); background-color: var(--oink-white); }

/* Escenario estrecho (< 440 px: móviles y la columna de 1024 px con pestañas). En fila no cabe la barra del Feed
   (avatar + «Publicidad» piden 127 px), así que el Feed crece y va delante, y Stories y Reels asoman por detrás a
   los lados. Lo que queda tapado de ellos no lleva texto: la pegatina y el pie se quitan (son adorno, aria-hidden),
   y siguen las barras de progreso y el botón de reproducir. */
@container (max-width: 439.98px) {
  .oink-ads {
    --ad-w: min(32cqi, 132px);
    --feed-w: min(52cqi, 196px);
    --ad-overlap: 13cqi;              /* 32 + 52 + 32 − 2 × 13 = 90cqi: queda un 5 % de aire a cada lado */
    gap: 0;
  }
  .oink-ad--feed  { position: relative; z-index: 1; }
  .oink-ad--story { margin-inline-end: calc(-1 * var(--ad-overlap)); }
  .oink-ad--reel  { margin-inline-start: calc(-1 * var(--ad-overlap)); }
  .oink-ad--story .oink-ad__frame,
  .oink-ad--reel .oink-ad__frame { box-shadow: 0 1px 2px color-mix(in srgb, var(--oink-blue) 12%, transparent); }
  .oink-ad--feed .oink-ad__frame {
    box-shadow: 0 1px 2px color-mix(in srgb, var(--oink-blue) 14%, transparent),
                0 18px 36px -14px color-mix(in srgb, var(--oink-blue) 55%, transparent);
  }
  .oink-ad__sticker,
  .oink-ad__caption { display: none; }
}

/* ── 03 · Panel de métricas (HTML, datos de ejemplo) ──────────────────────────────────────────────── */
.oink-dash {
  width: min(100% - 40px, 400px);
  overflow: hidden;
  border-radius: var(--radius-md);
  background-color: var(--oink-white);
  box-shadow: var(--mock-shadow);
  font-size: 0.875rem;
  line-height: 1.3;
  color: var(--oink-ink);
}
.oink-dash__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  padding: 8px 16px;                  /* si la barra pasa a dos líneas (móvil estrecho), el texto no toca el borde */
  background-color: var(--oink-blue);
  font-weight: 700;
  color: var(--oink-white);
}
.oink-dash__live {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
}
.oink-dash__live::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--oink-white);
  box-shadow: 0 0 0 3px rgb(255 255 255 / 0.3);
}
/* Las tres cifras, con el separador compartido .oink-metric--sep en gris de cuadrícula. Etiqueta arriba (Elo One). */
.oink-dash__kpis {
  --oink-sep-line: var(--mock-line);
  --oink-sep-start: 14px;
  --oink-sep-end: 10px;
  display: grid;
  grid-template-columns: repeat(3, auto);   /* cada cifra mide su etiqueta y el sobrante se reparte: «Audiencias» cabe a 320 px */
  margin: 0;
  padding: 14px 16px;
  border-bottom: 1px solid var(--mock-line);
  list-style: none;
}
.oink-dash .oink-metric { gap: 4px; }
.oink-dash .oink-metric__label { font-size: 0.875rem; color: var(--oink-gray); }
.oink-dash .oink-metric__value { font-size: 1.5rem; }

.oink-dash__chart { padding: 14px 16px 0; }
.oink-dash__chart-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-weight: 700;
}
.oink-dash__delta {
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background-color: color-mix(in srgb, var(--oink-blue) 10%, var(--oink-white));
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--oink-blue);
}
/* Barras finas ancladas a la línea base, con el extremo redondeado de 4 px. Una sola serie: sin leyenda; solo
   se rotulan la primera y la última. */
.oink-dash__weeks {
  --plot-h: 118px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}
.oink-dash__week {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: calc(var(--plot-h) + 30px);
}
.oink-dash__val {
  margin-bottom: 6px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.oink-dash__col {
  width: min(44px, 60%);
  height: calc(var(--h) * (var(--plot-h) - 26px));
  border-radius: 4px 4px 0 0;
  background-color: color-mix(in srgb, var(--oink-blue) 26%, var(--oink-white));
}
.oink-dash__week--now .oink-dash__col { background-color: var(--oink-blue); }
.oink-dash__wk {
  align-self: stretch;
  padding-top: 6px;
  border-top: 1px solid color-mix(in srgb, var(--oink-ink) 18%, transparent);
  text-align: center;
  color: var(--oink-gray);
}
.oink-dash__foot {
  padding: 8px 16px 12px;
  color: var(--oink-gray);
}

/* ── 04 · La landing dentro de un móvil (HTML; la foto tal cual, sin el mapa azul: imita una landing real) ── */
.oink-svc__stage--04 { place-items: end center; }
.oink-phone {
  position: relative;
  width: 216px;
  height: calc(var(--svc-stage-h) - 4px);
  margin-bottom: -36px;               /* el móvil sale del escenario por abajo, cortado */
  padding: 10px 10px 0;
  border-radius: 38px 38px 0 0;
  background-color: var(--oink-ink);
  box-shadow: 0 30px 60px -24px color-mix(in srgb, var(--oink-blue) 55%, transparent);
}
.oink-phone__screen {
  position: relative;
  height: 100%;
  overflow: hidden;
  padding: 34px 12px 0;
  border-radius: 30px 30px 0 0;
  background-color: var(--oink-white);
  font-size: 0.875rem;
  line-height: 1.2;
  color: var(--oink-ink);
}
/* La isla de la cámara. */
.oink-phone__screen::before {
  content: "";
  position: absolute;
  top: 10px;
  left: 50%;
  width: 64px;
  height: 18px;
  border-radius: var(--radius-pill);
  background-color: var(--oink-ink);
  transform: translateX(-50%);
}
.oink-lp__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.oink-lp__logo { font-weight: 800; }
.oink-lp__menu {
  width: 16px;
  height: 10px;
  border-block: 2px solid currentColor;
}
.oink-lp__hero {
  height: 128px;
  border-radius: 12px;
}
.oink-lp__title {
  position: absolute;
  z-index: 2;
  inset: auto 10px 10px;
  font-size: 1.125rem;
  font-weight: 800;
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--oink-white);
  text-wrap: balance;
}
.oink-lp__form {
  display: flex;
  flex-direction: column;
  padding-top: 12px;
}
.oink-lp__label { font-weight: 700; }
.oink-lp__input {
  height: 32px;
  margin: 4px 0 10px;
  border: 1px solid color-mix(in srgb, var(--oink-ink) 18%, transparent);
  border-radius: 8px;
}
.oink-lp__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  border-radius: var(--radius-pill);
  background-color: var(--oink-blue);
  font-weight: 700;
  color: var(--oink-white);
}
/* Lo que incluye la landing, como notas que flotan junto al móvil (cuando el escenario mide 460 px o más). */
.oink-phone__notes { display: none; }

/* ── Notas junto al móvil: solo si el escenario deja sitio a los lados (≥ 460 px de ancho) ───────────────── */
@container (min-width: 460px) {
  .oink-phone__notes {
    position: absolute;
    inset: 0;
    display: block;
    margin: 0;
    padding: 0;
    list-style: none;
    pointer-events: none;
  }
  .oink-phone__notes li {
    position: absolute;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px 6px 8px;
    border-radius: var(--radius-pill);
    background-color: var(--oink-white);
    box-shadow: 0 1px 2px color-mix(in srgb, var(--oink-blue) 12%, transparent),
                0 10px 20px -10px color-mix(in srgb, var(--oink-blue) 40%, transparent);
    font-size: 0.875rem;
    font-weight: 700;
    line-height: 1.2;
    white-space: nowrap;
  }
  .oink-phone__notes li:nth-child(1) { top: 22%; left: 4%; }
  .oink-phone__notes li:nth-child(2) { top: 40%; right: 3%; }
  .oink-phone__notes li:nth-child(3) { top: 62%; left: 6%; }
  .oink-phone__notes li:nth-child(4) { top: 78%; right: 6%; }
}

/* ── #servicios en tablet (768–1023 px): el texto encima del escenario ──────────────────────────────── */
@media (max-width: 1023.98px) {
  .oink-svc__panel {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 24px;
  }
  /* Con pestañas, el texto ocupa siempre lo mismo: el bloque no salta al cambiar de servicio. La lista ya no
     llena el alto del panel (texto + escenario): cada pestaña mide lo suyo. */
  .oink-js .oink-svc__copy { min-height: 15.5rem; }
  .oink-svc__list { align-self: start; }
  .oink-svc__tab { flex: none; min-height: 72px; }
}

/* ── #servicios en móvil (< 768 px): acordeón ───────────────────────────────────────────────────────── */
@media (max-width: 767.98px) {
  .oink-svc__panels { row-gap: 8px; }
  /* En el acordeón cada escenario mide lo que su imagen; el del móvil conserva su alto (sale cortado por abajo). */
  .oink-svc__stage { height: auto; padding-block: 32px; }
  .oink-svc__stage--04 { height: var(--svc-stage-h); padding-block: 0; }
  .oink-svc__panel { padding: 16px 0 24px; row-gap: 20px; }
  .oink-js .oink-svc__copy { min-height: 0; }
  .oink-svc__copy { padding-top: 0; }
  .oink-dash { width: min(100% - 24px, 400px); }
  .oink-dash__kpis { --oink-sep-start: 10px; --oink-sep-end: 8px; padding-inline: 14px; }
  .oink-dash .oink-metric__value { font-size: 1.25rem; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Bloque 6 · #casos · casos reales (fondo azul; .oink-sec--deep es el mismo azul desde los ajustes de Oink)
   La prueba social: mandan las cifras (patrón Elo One: etiqueta pequeña encima de la cifra grande).
   Cabecera: el h2 a la izquierda y la intro a la derecha. El CTA cierra el bloque, después de los casos (el orden del copy;
   tarea 12: la página sigue por debajo de 7.500 px a 1440).
   Pestañas (tarea 9): píldoras en fila; por debajo de 768 px, chips que se desplazan en horizontal con scroll-snap,
   sin máscara para no recortar el anillo de foco. Sin JS: los tres casos apilados (components.css).
   Cada caso: la foto a la izquierda (5/12) con el club y el contexto en una placa beige y el pie «Imagen
   ilustrativa» arriba; a la derecha, «Qué hicimos» y una tarjeta beige por campaña. Desde 768 px los tres casos miden
   lo mismo (--caso-h, el alto del más largo): la página no salta al cambiar de pestaña. Por debajo, la foto va encima.
   La tarjeta de cada campaña va en beige con el texto en azul (ajustes de Oink): el azul ya no se remarca con otro azul.
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
.oink-casos__head {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  column-gap: clamp(32px, 5vw, 72px);
  align-items: end;
}
.oink-sec--casos .oink-sec__head { margin-bottom: 32px; }
.oink-casos__cta { margin-top: 32px; }
.oink-casos__intro {
  max-width: 44ch;
  font-size: 1.0625rem;
  color: rgb(255 255 255 / 0.88);
  text-wrap: pretty;
}

/* Pestañas: píldoras; la activa, blanca con el texto en azul (como el CTA principal). Desde 768 px la fila se
   parte si no cabe (break-ui, tarea 12: un club de nombre larguísimo daba scroll horizontal a 768); por debajo son chips. */
.oink-casos__list {
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 20px;
}
.oink-casos__tab {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 0 24px;
  border: 0;
  border-radius: var(--radius-pill);
  background-color: rgb(255 255 255 / 0.1);
  color: var(--oink-white);
  font: inherit;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 160ms var(--ease-out);   /* al pulsar (propuesta 2); el color cambia sin fundido */
}
.oink-casos__tab:active { transform: scale(0.97); }
.oink-casos__tab[aria-selected="true"] {
  background-color: var(--oink-white);
  color: var(--oink-blue);
}
@media (hover: hover) and (pointer: fine) {
  .oink-casos__tab[aria-selected="false"]:hover { background-color: rgb(255 255 255 / 0.18); }
}
/* Entre 768 y 1023 px, la letra y el relleno de los chips de móvil: tres nombres de 21 caracteres (el límite del panel del
   plugin, la longitud de «L’Esportiu de Llinars») miden unos 706 px a 1rem con 24 px de relleno y la lista mide 692 a 768:
   se partían en dos filas. A 0,9375rem con 18 px quedan en unos 636 px. Desde 1024 la lista mide 929 y caben a 1rem. */
@media (min-width: 768px) and (max-width: 1023.98px) {
  .oink-casos__tab { padding: 0 18px; font-size: 0.9375rem; }
}

.oink-casos__panels {
  display: grid;
  row-gap: 32px;                      /* sin JS: los tres casos apilados */
}

.oink-caso {
  --caso-h: 400px;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  column-gap: clamp(28px, 4vw, 56px);
  min-height: var(--caso-h);
}

/* La foto llena el alto del caso (la fila del grid), con el mapa azul de .oink-photo.
   Encuadres (A3, fotos con personas): las tres fotos van recortadas en el propio archivo para que las caras queden por
   encima de la placa del club en cualquier marco (1,2:1 a 1440, 4:3 por debajo de 768 y 1:1 por debajo de 480) y sin
   marcas a la vista, así que se sitúan centradas (object-fit: cover de .oink-photo), sin ampliación ni anclaje. */
/* «Imagen ilustrativa» (spec §14): arriba, en su píldora azul al 80 % con el texto en blanco (se queda como estaba:
   anexo §4). */
.oink-caso__pie {
  position: absolute;
  z-index: 2;                         /* encima de la foto */
  top: 16px;
  left: 16px;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background-color: color-mix(in srgb, var(--oink-blue) 80%, transparent);
  color: var(--oink-white);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.2;
}
/* El club y su contexto, en la placa beige (components.css): abajo, a 16 px del borde de la foto y con 16 × 20 px de
   relleno, como en la propuesta aprobada. El h3 del club va en azul por el --oink-title de la placa; el contexto hereda
   el azul de la placa. */
.oink-caso__id {
  inset: auto 16px 16px;
  padding: 16px 20px;
}
.oink-caso__club {
  font-size: clamp(1.5rem, 1.15rem + 0.8vw, 1.875rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.oink-caso__ctx {
  max-width: 34ch;
  margin-top: 8px;
  line-height: 1.45;
  text-wrap: pretty;
}

.oink-caso__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.oink-caso__label {
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.82);
}
.oink-caso__text {
  max-width: 62ch;
  margin-top: 10px;
  font-size: 1.0625rem;
  color: rgb(255 255 255 / 0.92);
  text-wrap: pretty;
}

/* Resultados: una tarjeta beige por campaña, con el nombre, las etiquetas y las cifras en azul (7,0:1) y la sombra desplazada
   8 × 8 px en naranja (ajustes de Oink, §3: el naranja solo como adorno). Llenan el alto que queda (la de Claror, sola, lo
   ocupa todo). La sombra no ocupa sitio: entre tarjetas hay 10 px de hueco y, por la derecha y por abajo, cae sobre el margen. */
.oink-caso__results {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 24px;
}
.oink-campaign {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
  column-gap: 24px;
  padding: 18px 24px;
  border-radius: var(--radius-md);
  background-color: var(--oink-beige);
  color: var(--oink-blue);
  box-shadow: 8px 8px 0 var(--oink-orange);
}
.oink-campaign__name {
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.3;
  text-wrap: balance;
}
/* Las dos cifras de la campaña, separadas por el trazo de .oink-metric--sep, en azul al 25 % sobre el beige. */
.oink-campaign__metrics {
  --oink-sep-line: color-mix(in srgb, var(--oink-blue) 25%, transparent);
  --oink-sep-start: 24px;
  --oink-sep-end: 16px;
  display: flex;                      /* columnas iguales que se parten si una cifra no cabe (ver la barra del hero) */
  flex-wrap: wrap;
  row-gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.oink-campaign .oink-metric { gap: 8px; }
/* Etiqueta encima de la cifra (Elo One). En el HTML va detrás de «154» para que se lea «154 leads». */
.oink-campaign .oink-metric__label {
  order: -1;
  font-size: 0.9375rem;
  color: var(--oink-blue);
}
.oink-campaign .oink-metric__label::first-letter { text-transform: uppercase; }
.oink-campaign .oink-metric__value { font-size: clamp(2.25rem, 1.6rem + 1.4vw, 3rem); }

/* Una sola campaña (Claror): el copy no le da nombre y la tarjeta lleva «Resultados» (la etiqueta de campo del
   documento). Ocupa todo el alto del caso, con «Resultados» y las cifras (más grandes) juntos y centrados en vertical:
   separados arriba y abajo dejaban un hueco de ~110 px en la primera tarjeta de la prueba social (tarea 12). */
.oink-campaign:only-child {
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
  row-gap: 16px;
  padding: 26px 32px 28px;
}
.oink-campaign:only-child .oink-metric__value { font-size: clamp(3rem, 1.9rem + 2.9vw, 4.5rem); }

/* ── #casos en tablet y portátil pequeño (< 1200 px): el nombre de la campaña, encima de sus cifras ───────── */
@media (max-width: 1199.98px) {
  .oink-caso { --caso-h: 460px; }
  .oink-campaign {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 12px;
    padding: 18px 20px;
  }
  /* La columna de texto es más estrecha: la cifra grande de Claror baja para que «1,41 €» quepa en su mitad. */
  .oink-campaign:only-child { padding: 22px 24px 24px; }
  .oink-campaign:only-child .oink-metric__value { font-size: clamp(2.25rem, 1rem + 2.6vw, 3.25rem); }
}

@media (max-width: 1023.98px) {
  .oink-casos__head { grid-template-columns: minmax(0, 1fr); row-gap: 20px; }
  .oink-caso { --caso-h: 530px; }
  .oink-campaign__metrics { --oink-sep-start: 18px; --oink-sep-end: 12px; }
}

/* ── #casos entre 768 y 1023 px: encuadre de las fotos (A3, ronda 1) ───────────────────────────────────────
   Aquí la caja de la foto es vertical (columna 5/12 con --caso-h: 530px: ≈ 282 × 530 a 768 y ≈ 330 × 530 a 900) y
   solo deja ver el 35–48 % del ancho del archivo, así que el recorte centrado partía caras por los bordes (comprobado
   con capturas a 768 y 900). Cada caso lleva su posición horizontal: Claror, la mujer entera y centrada (el hombre
   queda fuera); Llinars, la alumna del centro, la del fondo y el instructor enteros; Eleba, la del primer plano entera
   (la rubia, fuera en vez de partida). Desde 1024 px la caja es casi cuadrada y las caras caben centradas. */
@media (min-width: 768px) and (max-width: 1023.98px) {
  .oink-caso--claror .oink-caso__photo img { object-position: 80% 50%; }
  .oink-caso--llinars .oink-caso__photo img { object-position: 65% 50%; }
  .oink-caso--eleba .oink-caso__photo img { object-position: 35% 50%; }
}
/* Entre 1024 y 1099 px la caja sigue siendo vertical (376–407 × 460, el 55–59 % del ancho del archivo) y en Eleba la rubia
   del fondo quedaba partida por el borde derecho (revisión final de los ajustes, I3): al 30 % queda fuera en vez de partida,
   como a 768, y la del primer plano sigue entera. Desde 1100 cabe entera centrada. Claror y Llinars no lo necesitan: las
   caras caben centradas (la prueba de encuadre mide la ventana que se ve en cada ancho). */
@media (min-width: 1024px) and (max-width: 1099.98px) {
  .oink-caso--eleba .oink-caso__photo img { object-position: 30% 50%; }
}

/* ── #casos en móvil (< 768 px): chips con scroll horizontal y el caso en una columna ──────────────────── */
@media (max-width: 767.98px) {
  /* La lista sale hasta los bordes de la pantalla y deja dentro el margen del contenedor: el primer chip se alinea
     con el texto y los anillos de foco caben (6 px arriba y abajo). Sin máscara ni barra de desplazamiento. */
  .oink-casos__list {
    flex-wrap: nowrap;                /* chips en una fila que se desplaza */
    margin: 0 calc(-1 * var(--oink-gutter)) 16px;
    padding: 6px var(--oink-gutter);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--oink-gutter);
    scrollbar-width: none;
  }
  .oink-casos__tab {
    min-height: 44px;
    padding: 0 18px;
    font-size: 0.9375rem;
    scroll-snap-align: start;
  }

  .oink-caso {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 24px;
    min-height: 0;
  }
  /* La foto, 4:3; por debajo de 480 px, cuadrada, para que la placa del club no la llene entera. */
  .oink-caso__photo { aspect-ratio: 4 / 3; }
  .oink-caso__text { font-size: 1rem; }
  .oink-caso__results { margin-top: 20px; }
  .oink-casos__cta { margin-top: 24px; }
  .oink-campaign:only-child { padding: 20px; }
  .oink-campaign .oink-metric__value,
  .oink-campaign:only-child .oink-metric__value { font-size: 2rem; }
}

@media (max-width: 479.98px) {
  .oink-caso__photo { aspect-ratio: 1 / 1; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Bloque 7 · #planes + #faq · planes y preguntas frecuentes (fondo beige)
   Un mismo bloque visual: las dos tarjetas de plan (START en blanco, GROW en azul con .oink-sec--blue), el CTA con su
   microcopy y, debajo, la FAQ en dos columnas de 4 (una en móvil). Lo que incluye cada plan va en viñetas, en dos
   columnas cuando la tarjeta mide 520 px o más.
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
.oink-tiers {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(16px, 2vw, 24px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.oink-tier {
  container-type: inline-size;
  padding: clamp(24px, 2.8vw, 36px);
  border-radius: var(--radius-lg);
}
/* START, en blanco sobre el beige (tono, sin borde). GROW toma el azul de .oink-sec--blue. */
.oink-tier--start {
  background-color: var(--oink-white);
  box-shadow: 0 1px 2px rgb(11 12 31 / 0.04), 0 18px 40px -28px rgb(11 12 31 / 0.25);
}
/* GROW, destacada: el azul de marca y una sombra teñida que la levanta del beige. */
.oink-tier--grow {
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--oink-blue) 30%, transparent),
    0 28px 56px -28px color-mix(in srgb, var(--oink-blue) 85%, transparent);
}

.oink-tier__title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 14px;
  row-gap: 4px;
}
.oink-tier__name {
  font-size: clamp(2.25rem, 1.6rem + 1.6vw, 3rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
}
.oink-tier__kind {
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--oink-blue);
}
.oink-tier__for {
  max-width: 46ch;
  margin-top: 10px;
  color: var(--oink-gray);
  text-wrap: pretty;
}
.oink-tier__inc {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent);
  font-weight: 700;
  line-height: 1.3;
}
.oink-tier--grow .oink-tier__kind { color: rgb(255 255 255 / 0.85); }
.oink-tier--grow .oink-tier__for { color: rgb(255 255 255 / 0.9); }

/* Viñetas con una marca de visto (círculo + palomilla dibujados con CSS). La mayúscula inicial la pone el CSS: en el
   HTML cada viñeta es el trozo literal del copy. */
.oink-tier__list {
  display: grid;
  gap: 10px 20px;
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
}
.oink-tier__list li {
  position: relative;
  padding-inline-start: 28px;
  line-height: 1.45;
}
.oink-tier__list li::first-letter { text-transform: uppercase; }
.oink-tier__list li::before,
.oink-tier__list li::after {
  content: "";
  position: absolute;
}
.oink-tier__list li::before {
  top: 2px;
  left: 0;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background-color: color-mix(in srgb, var(--oink-blue) 12%, var(--oink-white));
}
.oink-tier__list li::after {
  top: 6px;
  left: 7px;
  width: 5px;
  height: 9px;
  border: solid var(--oink-blue);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.oink-tier--grow .oink-tier__list li::before { background-color: rgb(255 255 255 / 0.2); }
.oink-tier--grow .oink-tier__list li::after { border-color: var(--oink-white); }

@container (min-width: 480px) {
  .oink-tier__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.oink-tiers__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 24px;
  margin-top: 28px;
}
.oink-tiers__micro {
  max-width: 62ch;
  color: var(--oink-gray);
  text-wrap: pretty;
}

/* ── FAQ: dos columnas de tarjetas blancas; la pregunta es el <summary>, con un chevron propio ─────────── */
.oink-faq { margin-top: clamp(56px, 5vw, 72px); }
.oink-faq__title { margin-bottom: clamp(24px, 2.6vw, 36px); }
.oink-faq__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px clamp(16px, 2vw, 24px);
  align-items: start;
}
.oink-faq__col {
  display: grid;
  grid-template-columns: minmax(0, 1fr);   /* no auto: una palabra larguísima en una pregunta ensanchaba la columna (ajustes B1) */
  gap: 8px;
}
.oink-faq__item {
  border-radius: var(--radius-md);
  background-color: var(--oink-white);
}
.oink-faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 60px;
  padding: 14px 20px;
  border-radius: var(--radius-md);
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.35;
  list-style: none;
  cursor: pointer;
  /* El texto es un ítem flex anónimo (no se le puede poner min-width: 0): con break-word su min-content sería la palabra
     entera y se saldría de la caja. anywhere la deja partirse; con el copy real no cambia nada (ajustes B1). */
  overflow-wrap: anywhere;
}
.oink-faq__q::-webkit-details-marker { display: none; }
/* Chevron: hacia abajo cerrada, hacia arriba abierta. Gira en 250 ms --ease-out (tarea 11), también donde la altura no se
   anima. El ±2 px va en el transform (antes, un margin de ±4 px, que con el centrado del flex da ±2 px), para moverse a la
   vez que gira. */
.oink-faq__q::after {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  margin: 0 4px 0 0;
  border: solid var(--oink-blue);
  border-width: 0 2px 2px 0;
  transform: translateY(-2px) rotate(45deg);
  transition: transform 250ms var(--ease-out);
}
.oink-faq__item[open] > .oink-faq__q::after { transform: translateY(2px) rotate(-135deg); }
.oink-faq__q:focus-visible::after { transition: none; }   /* con el teclado, al instante (ver la apertura, abajo) */
/* La pregunta ya va en azul (es un título, components.css): el hover que la ponía en azul sobra. */
.oink-faq__a {
  padding: 0 20px 20px;
  color: var(--oink-gray);
}
.oink-faq__a p {
  max-width: 62ch;
  text-wrap: pretty;
}
/* Apertura (spec §5 y ruling 5; tarea 11): la respuesta (::details-content) pasa de 0 a su alto en 250 ms --ease-out donde el
   navegador sabe interpolar hasta auto (interpolate-size). Al cerrar, content-visibility cambia al terminar (allow-discrete):
   la respuesta se ve mientras se pliega. En el resto de navegadores abre y cierra al instante. Es la única animación de
   altura de la página: un acordeón no tiene equivalente con transform. Funciona sin JS. */
@supports (interpolate-size: allow-keywords) and selector(::details-content) {
  .oink-faq__item { interpolate-size: allow-keywords; }
  .oink-faq__item::details-content {
    block-size: 0;
    overflow: clip;
    transition: block-size 250ms var(--ease-out), content-visibility 250ms var(--ease-out) allow-discrete;
  }
  .oink-faq__item[open]::details-content { block-size: auto; }
  /* Con el teclado (Intro o Espacio en la pregunta con el foco visible) abre y cierra al instante: una acción de teclado
     no se anima, como las pestañas con flechas (propuesta 3). */
  .oink-faq__item:has(> .oink-faq__q:focus-visible)::details-content { transition: none; }
}

/* Desde 1024 px, cada pregunta reserva dos líneas: las de una columna y la otra quedan a la misma altura y las dos
   columnas se leen como filas. */
@media (min-width: 1024px) {
  .oink-faq__q { min-height: 70px; padding-block: 12px; }
}

@media (max-width: 767.98px) {
  .oink-tiers { grid-template-columns: minmax(0, 1fr); }
  .oink-faq__cols { grid-template-columns: minmax(0, 1fr); }
  .oink-faq__q { padding: 14px 16px; font-size: 1rem; }
  .oink-faq__a { padding: 0 16px 18px; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Bloque 8 · #propuesta · CTA final + formulario (fondo azul)
   El cierre de venta. ≥ 1024 px: a la izquierda (5/12) el h2, el subtítulo y la foto de recepción, que llena el alto
   que deja el texto, con el microcopy en una píldora blanca; a la derecha (7/12) la tarjeta blanca del formulario.
   < 1024 px: una columna (texto, foto apaisada y formulario).
   Dentro de la tarjeta, los campos van en dos columnas cuando caben (consulta de contenedor, ≥ 420 px de ancho útil):
   1–6 en parejas, 7 y 9 a todo el ancho y la 8 con su «¿Cuál?» al lado. El éxito ocupa la misma celda que los campos:
   al quitarle hidden, los campos pasan a visibility: hidden y la tarjeta no cambia de alto.
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
/* Azul plano (ajustes de Oink): sin la luz detrás de la tarjeta ni el azul que se hundía hacia el pie. */
.oink-sec--propuesta {
  isolation: isolate;
  overflow: clip;
}

.oink-cta {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  grid-template-rows: auto 1fr;
  column-gap: clamp(40px, 5vw, 72px);
  row-gap: 32px;
}
.oink-cta__intro { grid-area: 1 / 1; }
.oink-cta__photo { grid-area: 2 / 1; }
.oink-form       { grid-area: 1 / 2 / span 2; }

.oink-cta__lead {
  max-width: 40ch;
  margin-top: 20px;
  font-size: 1.125rem;
  line-height: 1.6;
  text-wrap: pretty;
}

/* La foto de recepción (A3): un entrenador atendiendo a una socia, con el mapa azul de .oink-photo. Va recortada en el
   archivo (las dos caras enteras en la caja 1,18:1 de escritorio y en la 3:2 de móvil); el 20 % vertical solo manda
   en la caja 16:7 de tablet, donde sube el encuadre para que no se corte la cara de la socia. Llena el alto que deja
   el texto junto a la tarjeta. Encima, el microcopy en una píldora blanca (se queda como estaba, anexo §4): aquí es
   donde «te responde una persona».
   Entre 1024 y 1199 px (revisión final de los ajustes, I3) la caja es vertical (372 × 425 a 1024, 402 × 422 a 1100) y
   solo deja ver el 58–66 % del ancho del archivo: centrada, la cara de la socia quedaba partida por el borde izquierdo
   a 1024 y pegada a él a 1100. Al 30 % salen enteras las dos caras en toda la franja; desde 1200 la caja es apaisada
   y no cambia nada. */
.oink-cta__photo { min-height: 240px; }
.oink-cta__photo > img { object-position: 50% 20%; }
@media (min-width: 1024px) and (max-width: 1199.98px) {
  .oink-cta__photo > img { object-position: 30% 20%; }
}
.oink-cta__micro {
  position: absolute;
  z-index: 2;                         /* encima de la foto */
  left: 16px;
  bottom: 16px;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100% - 32px);
  padding: 10px 18px 10px 14px;
  border-radius: 22px;
  background-color: var(--oink-white);
  color: var(--oink-ink);
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.35;
  text-wrap: balance;
  box-shadow: 0 1px 2px rgb(11 12 31 / 0.12), 0 10px 24px -10px color-mix(in srgb, var(--oink-ink) 50%, transparent);
}
/* Punto azul con halo: «hay alguien al otro lado». No late (tarea 11): un latido en bucle junto al formulario competiría con
   él, y el texto ya lo dice. */
.oink-cta__micro::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--oink-blue);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--oink-blue) 18%, transparent);
}

/* ── La tarjeta del formulario ──────────────────────────────────────────────────────────────────── */
.oink-form {
  container-type: inline-size;
  display: grid;
  padding: clamp(20px, 3.3vw, 40px);
  border-radius: var(--radius-lg);
  background-color: var(--oink-white);
  color: var(--oink-ink);
  /* Dos capas teñidas de tinta (sobre azul, una sombra azul no se vería): la tarjeta se levanta del azul sin borde. */
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--oink-ink) 30%, transparent),
    0 40px 80px -40px color-mix(in srgb, var(--oink-ink) 70%, transparent);
}
.oink-form > * { grid-area: 1 / 1; min-width: 0; }

.oink-form__fields {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 18px 20px;
}
.oink-form__submit {
  width: 100%;
  min-height: 56px;
  margin-top: 6px;
  font-size: 1.0625rem;
}
/* Enviando (OINK.enviar del plugin pendiente; main.js pone aria-busy): atenuado y con el cursor de espera, sin animación, para
   que se vea que el envío está en marcha y no se pulse otra vez (tarea 12). */
.oink-form__submit[aria-busy="true"] {
  opacity: 0.72;
  cursor: progress;
}

/* Error de envío (tarea 10b): main.js le quita hidden si OINK.enviar (lo define el plugin) rechaza. Misma letra y color que los
   errores de campo (--oink-error, 6,6:1 sobre blanco). En el HTML va justo antes del botón (el lector de pantalla lo anuncia
   por role="alert" al aparecer) y con order: 1 se ve justo debajo: el botón no se mueve y la tarjeta crece hacia abajo, sin
   animar ninguna altura. El margin-top de -8px acerca el error al botón (la rejilla ya separa 18px: quedan 10px).
   Entra fundiéndose y asentándose 4px en 200ms --ease-out; la transición va en el estado de llegada y @starting-style da el de partida. */
.oink-form__send-error {
  order: 1;
  margin-top: -8px;
  scroll-margin-bottom: 12px;   /* main.js lo trae a la vista y aún baja 4 px al asentarse: que no quede pegado al borde (tarea 12) */
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--oink-error);
  transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out);
}
@starting-style {
  .oink-form__send-error { opacity: 0; transform: translateY(-4px); }
}

@container (min-width: 420px) {
  .oink-form__fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .oink-field--wide,
  .oink-form__send-error,
  .oink-form__submit { grid-column: 1 / -1; }
}

/* Éxito (la lógica es de la tarea 10): en la misma celda que los campos, centrado. */
.oink-form__success {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 24px;
  text-align: center;
}
.oink-form__success[hidden] { display: none; }
.oink-form:has(> .oink-form__success:not([hidden])) > .oink-form__fields { visibility: hidden; }

/* Éxito animado (propuesta 1 aprobada; tarea 11). Solo si la tarjeta ya ha entrado (.is-visible): si no, está oculta y no
   hay nada que animar. Los campos se funden en 120 ms (la salida, más rápida que la entrada) y visibility cambia al final.
   El aviso espera 80 ms, cuando a los campos les queda menos de un 5 % (con --ease-out casi todo el fundido ocurre al
   principio): así «Recibido.» no se pinta encima de un formulario a medio irse. Entra fundiéndose y subiendo 8 px en
   250 ms --ease-out, y la marca de visto crece de 0,9 a 1 (nunca desde 0) 80 ms después que él. */
.oink-js .oink-form.is-visible > .oink-form__success { transition: opacity 250ms var(--ease-out) 80ms, transform 250ms var(--ease-out) 80ms; }
.oink-js .oink-form.is-visible .oink-form__success-mark { transition: opacity 250ms var(--ease-out) 160ms, transform 250ms var(--ease-out) 160ms; }
@starting-style {
  .oink-js .oink-form.is-visible > .oink-form__success { opacity: 0; transform: translateY(8px); }
  .oink-js .oink-form.is-visible .oink-form__success-mark { opacity: 0; transform: scale(0.9); }
}
.oink-js .oink-form.is-visible:has(> .oink-form__success:not([hidden])) > .oink-form__fields {
  opacity: 0;
  transition: opacity 120ms var(--ease-out), visibility 0s linear 120ms;
}
.oink-form__success:focus { outline: none; }   /* recibe el foco por programa (tabindex −1); no es un control */
.oink-form__success p {
  max-width: 24ch;
  font-size: 1.125rem;
  font-weight: 500;
  line-height: 1.5;
  text-wrap: balance;
}
.oink-form__success strong {
  display: block;
  margin-bottom: 6px;
  color: var(--oink-blue);
  font-size: clamp(1.75rem, 1.4rem + 1.2vw, 2.5rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
/* La marca de visto: un círculo azul y una palomilla dibujada con CSS (como las viñetas de los planes). */
.oink-form__success-mark {
  position: relative;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background-color: var(--oink-blue);
  box-shadow: 0 0 0 10px color-mix(in srgb, var(--oink-blue) 10%, transparent);
}
.oink-form__success-mark::after {
  content: "";
  position: absolute;
  top: 19px;
  left: 28px;
  width: 14px;
  height: 26px;
  border: solid var(--oink-white);
  border-width: 0 4px 4px 0;
  transform: rotate(45deg);
}

/* < 1024 px: una columna. La foto pasa a franja apaisada entre el texto y el formulario. */
@media (max-width: 1023.98px) {
  .oink-cta {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    row-gap: 28px;
  }
  .oink-cta__intro,
  .oink-cta__photo,
  .oink-form { grid-area: auto; }
  .oink-cta__photo { min-height: 0; aspect-ratio: 16 / 7; }
  .oink-cta__lead { max-width: 52ch; }
}

@media (max-width: 767.98px) {
  .oink-cta { row-gap: 24px; }
  .oink-cta__lead { margin-top: 16px; font-size: 1rem; }
  /* 3:2, la proporción del archivo: se ve la foto entera y la píldora (dos líneas) queda por debajo de las dos caras. */
  .oink-cta__photo { aspect-ratio: 3 / 2; border-radius: var(--radius-md); }
  .oink-cta__micro { left: 12px; bottom: 12px; max-width: calc(100% - 24px); padding: 8px 14px 8px 12px; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Pie (.oink-footer) · azul, compacto
   ≥ 768 px: una fila con la marca (logo y ciudades), el contacto y los enlaces legales a la derecha.
   < 768 px: apilado. Todos los enlaces miden 44 px de alto (área táctil).
   Va del mismo azul que #propuesta, encima: un filo superior blanco al 18 % los separa (ajustes de Oink, §3).
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
.oink-footer {
  padding-block: 40px;
  border-top: 1px solid color-mix(in srgb, var(--oink-white) 18%, transparent);
  background-color: var(--oink-blue);
  color: var(--oink-white);
}
.oink-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 48px;
}
.oink-footer__brand {
  display: flex;
  align-items: center;
  gap: 20px;
}
.oink-footer__logo { width: 137px; flex: none; }
.oink-footer__cities {
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.3;
}
.oink-footer ul {
  display: flex;
  flex-wrap: wrap;
  column-gap: 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.oink-footer a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 5px;
}
.oink-footer__legal { margin-inline-start: auto; }
.oink-footer__legal a {
  font-size: 0.875rem;
  color: rgb(255 255 255 / 0.85);     /* sobre el azul: 5,6:1 */
}
/* Crédito de la foto del hero (Oink, 29-10): la licencia de Magnific/Freepik obliga a atribuir. Una línea entera debajo
   de la fila, con la letra y el blanco al 85 % de los enlaces legales (5,6:1 sobre el azul). El enlace va subrayado
   siempre, para que se distinga dentro de la frase (el hover lo pasa a naranja, como los demás). Visible: nunca oculta. */
.oink-footer__credit {
  flex: 1 1 100%;
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: rgb(255 255 255 / 0.85);
}
.oink-footer__credit a {
  font-size: 0.875rem;
  color: rgb(255 255 255 / 0.85);
  text-decoration-line: underline;
  text-decoration-color: color-mix(in srgb, var(--oink-white) 45%, transparent);
}
@media (hover: hover) and (pointer: fine) {
  .oink-footer a:hover {
    text-decoration-line: underline;
    text-decoration-color: var(--oink-orange);   /* el naranja solo como subrayado (spec §4) */
  }
}

@media (max-width: 767.98px) {
  .oink-footer { padding-block: 32px 24px; }
  .oink-footer__inner { flex-direction: column; align-items: flex-start; gap: 12px; }
  .oink-footer__brand { flex-direction: column; align-items: flex-start; gap: 12px; }
  .oink-footer__logo { width: 110px; }
  .oink-footer__contact { flex-direction: column; }
  .oink-footer__legal { margin-inline-start: 0; }
  .oink-footer__legal ul { column-gap: 20px; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Movimiento reducido (prefers-reduced-motion: reduce; spec §5; tarea 11)
   Fuera los desplazamientos, las escalas, los giros y los bucles; se quedan los fundidos de opacidad y los
   cambios de color (la cabecera). Los contadores y la hoja ya los deja quietos main.js. Lo común (entrada de
   bloques, pestañas, botones y opciones) está al final de components.css.
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  /* Línea-camino: ya dibujada; entra con un fundido junto a los pasos, que vuelven al escalonado de 60 ms. Con la misma
     condición (y el mismo peso) que la regla que la oculta: sin data-reveal en los pasos, se ve desde el principio. */
  html.oink-reveal-on .oink-flow__track:has(.oink-step[data-reveal]) .oink-path__line { stroke-dasharray: none; }
  @media screen {
    html.oink-reveal-on .oink-flow__track:has(.oink-step[data-reveal]) .oink-path__line { opacity: 0; }
  }
  html.oink-reveal-on .oink-flow__track:has(.oink-step.is-visible) .oink-path__line {
    opacity: 1;
    transition: opacity 500ms var(--ease-out);
  }
  html.oink-reveal-on .oink-step.is-visible { transition-delay: calc(var(--i, 0) * 60ms); }

  .oink-sheet__rows tr:not(.is-pending) { transition-property: opacity; }
  .oink-sheet__rows tr.is-pending { transform: none; }

  /* Carrusel: quieto, sin la copia, y la pista se desplaza a mano con scroll-snap. */
  .oink-marquee {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scroll-padding-inline: var(--marquee-edge);
    scrollbar-width: thin;
    scrollbar-color: rgb(255 255 255 / 0.5) rgb(255 255 255 / 0.12);
  }
  .oink-marquee__track { animation: none; }
  .oink-marquee__group[aria-hidden="true"] { display: none; }

  /* Pulsar: sin escala. Chevrons y FAQ: cambian al instante. */
  .oink-svc__tab,
  .oink-casos__tab,
  .oink-js .oink-svc__trigger { transition: none; }
  .oink-svc__tab:active,
  .oink-casos__tab:active,
  .oink-js .oink-svc__trigger:active { transform: none; }
  .oink-js [data-tabs].is-visible .oink-svc__trigger::after,
  .oink-faq__q::after { transition: none; }
  .oink-faq__item::details-content { transition: none; }   /* aparte: en una lista, sin soporte se caería la regla entera */

  /* Éxito: solo los fundidos (sin subir ni crecer). */
  .oink-js .oink-form.is-visible > .oink-form__success,
  .oink-js .oink-form.is-visible .oink-form__success-mark { transition-property: opacity; }
  @starting-style {
    .oink-js .oink-form.is-visible > .oink-form__success,
    .oink-js .oink-form.is-visible .oink-form__success-mark { transform: none; }
  }

  /* Error de envío: solo el fundido (sin asentarse 4px). */
  .oink-form__send-error { transition-property: opacity; }
  @starting-style {
    .oink-form__send-error { transform: none; }
  }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   Impresión y PDF (tarea 12)
   Al imprimir no hay scroll ni nada que pulsar. Lo que oculta hasta entrar en pantalla ya va en @media screen (tarea 11),
   igual que las pestañas (components.css y el modo pestañas de #servicios): los paneles salen todos, apilados, como sin JS.
   La hoja de cálculo y los contadores salen en su estado final: lo pone main.js en «beforeprint».
   - Cabecera: en su sitio, una sola vez (fija, se repetía encima del contenido en cada página). Lleva el azul de fondo
     para que el logo blanco se lea, también si el navegador imprime sin fondos (print-color-adjust, con el prefijo
     -webkit- para Safari).
   - Fotos (.oink-photo) y placas beige (ajustes de Oink, tarea A2): sin «gráficos de fondo» (lo que trae el diálogo de
     Chrome) no se imprimen los fondos: las placas perderían el beige y la sombra naranja, y las píldoras sobre foto, su
     fondo. Con print-color-adjust: exact (lo heredan la placa y lo que lleva dentro) salen tal cual. El mapa azul es un
     filtro de la propia imagen, no un fondo: se imprime siempre (ronda 1 y tarea A2).
   - Disparadores del acordeón de #servicios: hacen de rótulo (sin chevron ni el azul del abierto), como sin JS.
   - Tarjetas y preguntas no se parten entre dos páginas.
   - Fondos oscuros con texto claro (revisión final): sin «gráficos de fondo» no se imprimían y el texto blanco quedaba
     blanco sobre blanco. Llevan print-color-adjust: exact, que se hereda: los bloques azules y el pie cubren todo lo de
     dentro; aparte va lo azul sobre blanco o beige (los botones azules y las etiquetas de los mockups).
   - FAQ (revisión final): las respuestas de las preguntas cerradas también se imprimen (::details-content visible).
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
@media print {
  .oink-js .oink-header,
  .oink-header {
    position: static;
    background-color: var(--oink-blue);
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .oink-header::before { content: none; }
  .oink-photo,
  .oink-reto__stats,
  .oink-caso__id,
  .oink-disc__label {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .oink-js .oink-svc__trigger::after { content: none; }
  .oink-js .oink-svc__trigger[aria-expanded] {
    background-color: color-mix(in srgb, var(--oink-blue) 6%, var(--oink-white));
    color: var(--oink-ink);
  }
  .oink-js .oink-svc__trigger[aria-expanded] .oink-svc__num { color: var(--oink-blue); }
  .oink-tier,
  .oink-campaign,
  .oink-faq__item,
  .oink-sheet,
  .oink-footer { break-inside: avoid; }
  .oink-sec--blue,
  .oink-sec--deep,
  .oink-footer,
  .oink-btn--on-light,
  .oink-bracket__label,
  .oink-sheet__bar,
  .oink-sheet__status--alta,
  .oink-plan__chip--main,
  .oink-dash__bar,
  .oink-lp__btn {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  /* Carrusel (revisión final de los ajustes, I1): las 8 disciplinas enteras, en filas. Se imprimía el estado de la animación
     dentro de overflow: hidden y la máscara (6 de 8 en A4) y, peor, la pista mide max-content (unos 2.900 px): aunque la
     región la recorte, Chrome la cuenta al ajustar la impresión a la página y encogía todo el documento al 67 %.
     animation: none no basta: hacen falta display: block y width: auto en la pista y flex-wrap en el grupo. Va después de
     las reglas de movimiento reducido y gana (overflow: visible tapa también el overflow-x: auto). */
  .oink-marquee { overflow: visible; -webkit-mask-image: none; mask-image: none; }
  .oink-marquee__track { display: block; width: auto; animation: none; }
  .oink-marquee__group { flex-wrap: wrap; padding-inline-end: 0; }
  .oink-marquee__group[aria-hidden="true"] { display: none; }
  .oink-disc { break-inside: avoid; }
  .oink-faq__item::details-content { content-visibility: visible; block-size: auto; }   /* aparte: sin soporte se caería la regla entera */
}
@media print and (min-width: 768px) {
  .oink-svc__kicker { display: block; }
}
