/* Componentes reutilizables (prefijo .oink-): base, foco, contenedor, secciones, botones, eyebrow, chip,
   tarjeta de cristal, tarjeta de métrica (con su separador --sep), pestañas, campo de formulario (con sus
   opciones en píldora y la casilla), foto en azul (filtro) y placa beige. Al final, la entrada de bloques y el movimiento reducido de lo común
   (tarea 11). Los valores salen de tokens.css; aquí no se redefine ninguno.
   En Elementor: la base va a «CSS adicional» (pide la clase oink-landing en lo que envuelve la landing; ver la guía) y cada
   clase .oink- se pone en «Clases CSS» del widget. */

/* ── Variables de maqueta (no son tokens de marca) ──────────────────────────────────────────────── */
:root {
  --oink-gutter: clamp(16px, 4vw, 40px);   /* margen lateral del contenedor: 16 px en móvil, 40 px en escritorio */
  --oink-header-h: 80px;                    /* alto de la cabecera; las anclas dejan este hueco arriba */
  --oink-ring: var(--oink-blue);            /* color del anillo de foco sobre fondos claros */
}

@media (max-width: 767.98px) {
  :root { --oink-header-h: 64px; }
}

/* ── Base: solo dentro del envoltorio .oink-landing (revisión final, I1) ─────────────────────────────────────────────────
   Con el shortcode [oink_landing] la landing va dentro de una página del tema, y en página completa wp_footer pinta en el
   mismo <body> el banner de cookies y la barra de administración: una base global (*, html, body, h2, a, img…) los cambiaría.
   Por eso todo va dentro de <div class="oink-landing">, que envuelve el enlace de salto, la cabecera, main y el pie:
   - los reinicios de elementos van como .oink-landing :where(…): pesan una clase (0,1,0), lo mismo que los componentes, que
     van después y mandan; y más que las reglas de elemento del tema (h2, a, img), que así no se cuelan dentro;
   - las anclas, touch-action y el foco llevan :where(.oink-landing) delante, que no suma: la especificidad de siempre;
   - lo que antes se heredaba de body (letra, interlineado, color, suavizado, text-size-adjust) se hereda del envoltorio;
   - el margen y el fondo del body, solo con body.oink-page, que pone la plantilla de página completa del plugin
     (body_class). Con el shortcode el body es del tema. */
.oink-landing,
.oink-landing *,
.oink-landing ::before,
.oink-landing ::after { box-sizing: border-box; }

body.oink-page {
  margin: 0;
  background-color: var(--oink-white);
}

.oink-landing {
  --oink-title: var(--oink-blue);           /* color de los títulos sobre claro (ajustes de Oink); los bloques azules lo ponen en blanco */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--oink-ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Una palabra que no cabe en su línea se parte (el panel del plugin admite hasta 60 letras seguidas en títulos, párrafos y
     preguntas; sin esto, a 390 daba 314 px de scroll horizontal). break-word, no anywhere: solo actúa cuando la palabra
     desborda y no cambia el min-content, así que el copy real se parte igual que antes (ajustes B1, 2026-10-28). */
  overflow-wrap: break-word;
}

.oink-landing :where(h1, h2, h3, h4, p, ul, ol, figure, blockquote) { margin: 0; }
.oink-landing :where(img, svg, video) { display: block; max-width: 100%; height: auto; border: 0; }   /* border: el del tema no entra */
.oink-landing :where(a) { color: inherit; }

/* Las anclas de la cabecera no dejan el destino debajo de ella (punto de riesgo 3). */
:where(.oink-landing) main [id] { scroll-margin-top: var(--oink-header-h); }
/* Tampoco el foco que entra por arriba: con Mayús+Tab, Firefox y Safari dejan el elemento pegado al borde de arriba, debajo de
   la cabecera fija (WCAG 2.4.11). 12 px más, para que se vea también el anillo (tarea 12; es el margen que ya llevaban los
   disparadores del acordeón). */
:where(.oink-landing) main :is(a[href], button, summary, input, select, textarea, [tabindex]) { scroll-margin-top: calc(var(--oink-header-h) + 12px); }

/* Móvil (mobile-native; tarea 12): un toque responde al momento, sin la espera del doble toque. Los controles con su propio
   «pulsar» (scale) no llevan además el destello del navegador, y una pulsación larga no selecciona su texto. El texto de
   contenido se sigue pudiendo seleccionar. */
.oink-landing :where(a[href], button, summary, label, [role="tab"]) { touch-action: manipulation; }
.oink-btn,
:where(.oink-landing) [role="tab"],
.oink-acc-trigger {
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}

/* ── Foco: anillo de 2 px que contrasta sobre claro (azul) y sobre azul (blanco) ─────────────────── */
:where(.oink-landing) :focus-visible {
  outline: 2px solid var(--oink-ring);
  outline-offset: 3px;
}

.oink-sec--blue,
.oink-sec--deep,
.oink-header,
.oink-footer,
.oink-skip { --oink-ring: var(--oink-white); }   /* el enlace de salto aparece sobre el hero azul */

/* Tarjeta clara dentro de una sección azul (el formulario de #propuesta): el anillo vuelve a ser azul. */
.oink-form { --oink-ring: var(--oink-blue); }

/* Enlace «Saltar al formulario»: fuera de la vista hasta que recibe el foco con el teclado. */
.oink-skip {
  position: absolute;
  top: 12px;
  left: 16px;
  z-index: 30;                    /* por encima de la cabecera (10) */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 20px;
  border-radius: var(--radius-pill);
  background-color: var(--oink-white);
  color: var(--oink-ink);
  font-weight: 700;
  text-decoration: none;
  transform: translateY(calc(-100% - 24px));
}
.oink-skip:focus { transform: none; }

/* Solo para lectores de pantalla: un titular que estructura la página aunque el copy no lo muestre (el h2 «Planes»). */
.oink-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── Contenedor de 1200 px ─────────────────────────────────────────────────────────────────────── */
.oink-container {
  width: min(100% - 2 * var(--oink-gutter), 1200px);
  margin-inline: auto;
}

/* ── Secciones: padding vertical de la escala y fondos de la marca ──────────────────────────────── */
.oink-sec {
  position: relative;
  padding-block: var(--space-section);
}
/* Un solo azul (ajustes de Oink): --deep es el mismo azul plano (la clase se queda, el HTML y el plugin la usan en #casos) y
   --cream es el beige (la clase conserva su nombre por lo mismo). Los dos bloques azules ponen los títulos en blanco. */
.oink-sec--blue,
.oink-sec--deep  { --oink-title: var(--oink-white); background-color: var(--oink-blue); color: var(--oink-white); }
.oink-sec--cream { background-color: var(--oink-beige); color: var(--oink-ink); }

/* ── Botones: píldora. Principal verde flúor sobre azul; con --on-light, azul sobre claro ────────── */
.oink-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0 28px;
  border: 0;
  border-radius: var(--radius-pill);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  /* Al pulsar, scale(0.97) en 160 ms --ease-out (spec §5); el fondo y el texto del hover, con ease (cambio de color). */
  transition: transform 160ms var(--ease-out), background-color 160ms ease, color 160ms ease;
}
.oink-btn:active:not(:disabled) { transform: scale(0.97); }

/* Sobre azul, el principal va en el verde de la marca con el texto azul (hero con foto, Oink 29-10): 6,4:1 en los dos
   sentidos. Hover y foco, en blanco con el texto azul (7,2:1), abajo. */
.oink-btn--primary {
  background-color: var(--oink-green);
  color: var(--oink-blue);
  /* Dos capas suaves teñidas de tinta (sobre azul, una sombra azul no se vería): la píldora se despega del fondo sin borde. */
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--oink-ink) 30%, transparent),
    0 12px 28px -10px color-mix(in srgb, var(--oink-ink) 55%, transparent);
}

/* El contorno es parte del botón (no de una tarjeta): se dibuja con una sombra interior del color del texto. */
.oink-btn--ghost {
  background-color: transparent;
  color: var(--oink-white);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, currentColor 70%, transparent);
}

.oink-btn--primary.oink-btn--on-light {
  background-color: var(--oink-blue);
  color: var(--oink-white);
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--oink-blue) 25%, transparent),
    0 12px 28px -12px color-mix(in srgb, var(--oink-blue) 70%, transparent);
}
.oink-btn--ghost.oink-btn--on-light { color: var(--oink-blue); }

/* Hover (160 ms ease, arriba). Sobre azul, el principal ya es verde: su hover (y el del contorno, para que no se confunda
   con él) pasa a blanco con el texto azul (hero con foto, Oink 29-10). Sobre claro sigue la regla de los ajustes de Oink:
   fondo verde y texto azul en el principal y en el contorno --on-light. El contorno del --ghost va en currentColor, así
   que pasa a azul con el texto. Las reglas --on-light van después y con más peso: mandan sobre las de arriba.
   El anillo de foco no cambia: sigue en --oink-ring (blanco sobre azul, azul sobre claro), 3 px por fuera, sobre el fondo
   del bloque y nunca verde sobre verde ni blanco sobre blanco. */
@media (hover: hover) and (pointer: fine) {
  .oink-btn--primary:hover,
  .oink-btn--ghost:hover {
    background-color: var(--oink-white);
    color: var(--oink-blue);
  }
  .oink-btn--primary.oink-btn--on-light:hover,
  .oink-btn--ghost.oink-btn--on-light:hover {
    background-color: var(--oink-green);
    color: var(--oink-blue);
  }
}
/* Con el foco de teclado, el principal sobre azul se pone también en blanco con el texto azul (el mismo estado que el
   hover): el anillo blanco va 3 px por fuera, sobre el azul del bloque, y se sigue viendo. El --on-light no cambia. */
.oink-btn--primary:not(.oink-btn--on-light):focus-visible {
  background-color: var(--oink-white);
  color: var(--oink-blue);
}

/* ── Eyebrow: etiqueta corta en mayúsculas sobre un titular (solo donde el copy la trae) ──────────── */
.oink-eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Sobre fondo claro (blanco o beige), el eyebrow va en azul: 7,2:1 sobre blanco y 7,0:1 sobre beige. */
.oink-eyebrow--on-light { color: var(--oink-blue); }

/* En los bloques azules (OINK SPORTS GROWTH, NOT JUST ADS, MADE FOR MEMBERSHIPS) va en píldora verde con el texto azul,
   como la etiqueta «SOCIAL MEDIA» del ejemplo de Oink: 4 px de radio y relleno 5 × 9 px (ajustes de Oink, §3). Sigue siendo
   un bloque (fit-content: mide lo que su texto), así los márgenes de cada uso no cambian. */
.oink-sec--blue .oink-eyebrow:not(.oink-eyebrow--on-light),
.oink-sec--deep .oink-eyebrow:not(.oink-eyebrow--on-light) {
  width: fit-content;
  padding: 5px 9px;
  border-radius: 4px;
  background-color: var(--oink-green);
  color: var(--oink-blue);
}

/* ── Títulos (ajustes de Oink, §3): azules sobre claro y blancos sobre azul ──────────────────────────
   Son los h1–h3 (también los de pasos, tarjetas y servicios) y las preguntas de la FAQ. El color es --oink-title: azul en
   .oink-landing y blanco en .oink-sec--blue y --deep (arriba); como se hereda del bloque más cercano, la tarjeta GROW
   (.oink-sec--blue dentro de #planes, que es beige) sigue con el título en blanco. El texto corrido no cambia: tinta y gris. */
.oink-landing :is(h1, h2, h3, .oink-faq__q) { color: var(--oink-title); }

/* ── Titular de sección (h2): Montserrat 800 en mayúsculas, al tamaño del token --fs-h2 ──────────── */
.oink-h2 {
  font-size: var(--fs-h2);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  text-wrap: balance;
}

/* Cabecera de sección: eyebrow (si el copy lo trae) y h2. */
.oink-sec__head { margin-bottom: clamp(28px, 3.4vw, 44px); }
.oink-sec__head .oink-eyebrow { margin-bottom: 12px; }

/* ── Chip: etiqueta en píldora; el fondo es el propio color del texto al 12 %, así sirve en claro y en azul ── */
.oink-chip {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  background-color: color-mix(in srgb, currentColor 12%, transparent);
  font-size: 0.875rem;                /* ninguna etiqueta baja de 0,875rem */
  font-weight: 700;
  line-height: 1.2;
}

/* ── Tarjeta de cristal (spec §4). Sin backdrop-filter: blanco al 18 % sólido ───────────────────── */
.oink-glass {
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  background-color: var(--glass-bg-solid);
  /* Brillo de 1 px en el canto superior: la luz del fondo «toca» el cristal. Sin sombra ancha (ya hay borde). */
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.2);
}

@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .oink-glass {
    background-color: var(--glass-bg);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
  }
}

/* ── Tarjeta de métrica: cifra grande y etiqueta pequeña; el orden visual es el del HTML ────────── */
.oink-metric {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.oink-metric__value {
  font-size: clamp(2rem, 1.25rem + 1.6vw, 3rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.oink-metric__label {
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.35;
  color: color-mix(in srgb, currentColor 82%, transparent);
}

/* --sep: cifras en fila separadas por un trazo fino de 1 px (un trazo de luz sobre azul, no un borde de tarjeta).
   Lo usan la barra del hero, el reto y el panel de métricas de #servicios. Cada uso ajusta con variables:
   --oink-sep-line   color del trazo (blanco al 18 % por defecto: sobre azul)
   --oink-sep-start  aire entre el trazo y la cifra que lo sigue
   --oink-sep-end    aire entre una cifra y el trazo siguiente */
.oink-metric--sep:not(:last-child) { padding-inline-end: var(--oink-sep-end, 14px); }
.oink-metric--sep + .oink-metric--sep {
  padding-inline-start: var(--oink-sep-start, 22px);
  box-shadow: inset 1px 0 var(--oink-sep-line, rgb(255 255 255 / 0.18));
}

/* ── Pestañas (patrón ARIA de tabs sobre [data-tabs]; el JS es de la tarea 9) ──────────────────────
   Sin JS no hay pestañas (spec §10): la lista no se ve y los paneles van apilados, todos visibles. Con
   data-tabs-mobile="accordion", por debajo de 768 px cada panel lleva delante su .oink-acc-trigger; sin JS hace
   de rótulo del panel. Con .oink-js en <html> (tarea 9): desde 768 px se ve la lista y solo el panel activo (el JS
   pone hidden en los demás); por debajo, el acordeón (o la lista, si el bloque no pide acordeón).
   Aquí solo va qué se ve en cada modo; el aspecto de la lista, las pestañas y los disparadores es de cada bloque.
   En Elementor: «Pestañas anidadas», que en móvil pasan a acordeón. */
[data-tabs] [role="tablist"],
.oink-acc-trigger { display: none; }
/* Al abrir un disparador se pliega el panel de arriba y el disparador sube: main.js lo vuelve a poner a la vista, bajo la cabecera. */
.oink-acc-trigger { scroll-margin-top: calc(var(--oink-header-h) + 12px); }
/* Las pestañas solo existen en pantalla. Al imprimir (o guardar como PDF) no hay nada que pulsar: los paneles salen todos,
   apilados y sin la lista, como sin JS (tarea 12; el resto de la impresión va al final de sections.css). */
@media screen {
  .oink-js [data-tabs] [role="tabpanel"][hidden] { display: none; }
}

@media screen and (min-width: 768px) {
  .oink-js [data-tabs] [role="tablist"] { display: flex; }
}
@media (max-width: 767.98px) {
  [data-tabs-mobile="accordion"] .oink-acc-trigger { display: flex; }
}
@media screen and (max-width: 767.98px) {
  .oink-js [data-tabs]:not([data-tabs-mobile="accordion"]) [role="tablist"] { display: flex; }
}

/* Cambio de pestaña (spec §5; tarea 11). Solo cuando el bloque ya ha entrado en pantalla (.is-visible): así no se anima el
   reparto inicial de hidden que hace main.js al cargar, ni un bloque que nadie ve. El panel que entra se funde y sube 8 px en
   200 ms (@starting-style: sale de display none). */
.oink-js [data-tabs].is-visible [role="tabpanel"] {
  transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out);
}
@starting-style {
  .oink-js [data-tabs].is-visible [role="tabpanel"] { opacity: 0; transform: translateY(8px); }
}
/* Modo pestañas (≥ 768 px): los paneles comparten celda, así el que sale (en 120 ms, más deprisa que la entrada) se funde
   encima del que entra sin mover nada, y display cambia al terminar (allow-discrete). Sin soporte, sale al instante. En el
   acordeón móvil el que se cierra se va al momento: si se quedara 120 ms, empujaría la página. Solo en pantalla: al imprimir
   los paneles van apilados, no en la misma celda. */
@media screen and (min-width: 768px) {
  .oink-js [data-tabs].is-visible [role="tabpanel"] { grid-area: 1 / 1; }
  .oink-js [data-tabs].is-visible [role="tabpanel"][hidden] {
    opacity: 0;
    pointer-events: none;   /* mientras se funde, los clics van al panel que entra */
    transition-property: opacity, display;
    transition-duration: 120ms;
    transition-timing-function: var(--ease-out);
    transition-behavior: allow-discrete;
  }
}
/* Con las flechas, Inicio o Fin (main.js pone data-kbd), el cambio es instantáneo (propuesta 3 aprobada): una acción de
   teclado no se anima, y tres pulsaciones seguidas serían tres fundidos solapados. */
.oink-js [data-tabs].is-visible[data-kbd] [role="tabpanel"] { transition-duration: 0s; }

/* ── Campo de formulario (spec §4 y §8; tarea 8) ─────────────────────────────────────────────────────
   .oink-field: la etiqueta siempre visible encima (nunca solo un placeholder), el control y su <p> de error debajo. El
   error vacío no ocupa sitio (un <p> sin texto mide 0 y el margen solo va cuando tiene texto); se mantiene en el árbol
   de accesibilidad para que aria-live lo anuncie. El estado de error lo pone aria-invalid="true" en el control.
   Pensado para fondo claro (la tarjeta blanca del formulario):
   - el borde de los campos es --oink-field-line, la tinta al 50 % sobre blanco (3,7:1; WCAG 1.4.11 pide 3:1);
   - los controles van a 16 px (1rem) como mínimo: con menos, iOS hace zoom al enfocar (mobile-native).
   Variantes: --choices (un <fieldset> con su <legend> y opciones .oink-choice en píldora) y --check (.oink-check).
   En Elementor: el widget Form (o Fluent Forms) con estas clases en «Clases CSS» o su CSS en «CSS adicional». */
.oink-field {
  --oink-field-line: color-mix(in srgb, var(--oink-ink) 50%, var(--oink-white));
  --oink-field-fill: color-mix(in srgb, var(--oink-blue) 3%, var(--oink-white));
  display: flex;
  flex-direction: column;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;                          /* también es un <fieldset> */
}
.oink-field[hidden] { display: none; }

.oink-field__label {
  float: left;                        /* en el <legend>: deja de ser la leyenda del borde y se comporta como un hijo más */
  width: 100%;
  margin-bottom: 8px;
  padding: 0;
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--oink-ink);
}
.oink-field__opt { font-weight: 500; color: var(--oink-gray); }

.oink-field__control {
  width: 100%;
  min-height: 52px;
  margin: 0;
  padding: 0 16px;
  border: 1.5px solid var(--oink-field-line);
  border-radius: 12px;
  background-color: var(--oink-field-fill);
  color: var(--oink-ink);
  font-family: inherit;
  font-size: 1rem;                    /* 16 px: sin zoom en iOS */
  font-weight: 500;
  line-height: 1.3;
  -webkit-appearance: none;
  appearance: none;
}
.oink-field__control::placeholder {
  color: var(--oink-gray);            /* 6,9:1 sobre el relleno: el placeholder también pasa AA */
  font-weight: 400;
  opacity: 1;
}
.oink-field__control:focus { border-color: var(--oink-blue); background-color: var(--oink-white); }
/* Con error: el borde en --oink-error y engrosado con una sombra interior (sin mover el texto), y el relleno teñido. */
.oink-field__control[aria-invalid="true"] {
  border-color: var(--oink-error);
  background-color: color-mix(in srgb, var(--oink-error) 4%, var(--oink-white));
  box-shadow: inset 0 0 0 0.5px var(--oink-error);
}

/* Desplegable: sin la flecha del sistema; el chevron va en la envoltura (como el de la FAQ). Mientras no se elige
   nada, el texto va en el gris del placeholder. */
.oink-select { position: relative; display: block; }
.oink-select > .oink-field__control { padding-right: 48px; cursor: pointer; }
.oink-select > .oink-field__control:has(option[value=""]:checked) { color: var(--oink-gray); font-weight: 400; }
.oink-select::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 20px;
  width: 9px;
  height: 9px;
  margin-top: -7px;
  border: solid var(--oink-blue);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
  pointer-events: none;
}

.oink-field__error {
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--oink-error);
}
.oink-field__error:not(:empty) { margin-top: 6px; }

/* Opciones (radios) en píldora: toda la píldora es el área táctil (48 px de alto). El círculo es el propio input
   (appearance: none) de 22 px; marcado: aro azul y punto. El anillo de foco va en la píldora entera. */
.oink-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.oink-choice {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 20px 0 14px;
  border-radius: var(--radius-pill);
  background-color: color-mix(in srgb, var(--oink-blue) 6%, var(--oink-white));
  font-weight: 500;
  line-height: 1.25;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform 160ms var(--ease-out);   /* al pulsar, como los botones (propuesta 2) */
}
.oink-choice:active { transform: scale(0.97); }
.oink-choice:has(:checked) {
  background-color: color-mix(in srgb, var(--oink-blue) 12%, var(--oink-white));
  box-shadow: inset 0 0 0 1.5px var(--oink-blue);
  font-weight: 700;
}
.oink-choice:has(:focus-visible) {
  outline: 2px solid var(--oink-ring);
  outline-offset: 2px;
}
.oink-choice__input {
  flex: none;
  width: 22px;
  height: 22px;
  margin: 0;
  border: 2px solid var(--oink-field-line);
  border-radius: 50%;
  background-color: var(--oink-white);
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}
.oink-choice__input:checked {
  border-color: var(--oink-blue);
  background-color: var(--oink-blue);
  box-shadow: inset 0 0 0 4px var(--oink-white);
}
.oink-choice__input:focus-visible { outline: none; }   /* lo dibuja la píldora */
@media (hover: hover) and (pointer: fine) {
  .oink-choice:hover .oink-choice__input:not(:checked) { border-color: var(--oink-blue); }
}

/* Casilla (privacidad): la fila entera mide 44 px; la casilla, 24 px con la marca de visto dibujada con CSS. El enlace
   del texto es un enlace dentro de una frase (excepción de área táctil de WCAG 2.5.8). */
.oink-check {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  font-weight: 500;
  line-height: 1.4;
  cursor: pointer;
}
.oink-check__input {
  display: grid;
  place-content: center;
  flex: none;
  width: 24px;
  height: 24px;
  margin: 0;
  border: 2px solid var(--oink-field-line);
  border-radius: 6px;
  background-color: var(--oink-white);
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}
.oink-check__input::before {
  content: "";
  width: 6px;
  height: 12px;
  margin-top: -3px;
  border: solid var(--oink-white);
  border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg);
  opacity: 0;
}
.oink-check__input:checked { border-color: var(--oink-blue); background-color: var(--oink-blue); }
.oink-check__input:checked::before { opacity: 1; }
.oink-check__input[aria-invalid="true"] { border-color: var(--oink-error); }
.oink-check a {
  color: var(--oink-blue);
  font-weight: 700;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}

/* ── Foto en azul: mapa de degradado (ajustes de Oink, anexo §4; tarea A2) ────────────────────────────
   El archivo no se toca: la imagen pasa a escala de grises y se vuelve a colorear con un mapa de tres tramos, de
   azul muy oscuro a casi blanco pasando por el azul de marca. Es el filtro SVG #oink-mapa-azul, en línea al principio
   de <body> en index.html (feColorMatrix saturate 0 y feComponentTransfer con una tabla por canal; los valores son
   los de la propuesta aprobada). Va con CSS, así que las fotos que se suban luego desde el panel del plugin salen
   igual. Sin capas encima: ni tinte ni degradado --scrim; el texto que va sobre foto lleva su placa beige (abajo).
   La foto llena la caja (object-fit: cover), así que la caja necesita un tamaño: el alto de su fila de grid o un
   aspect-ratio. Mientras carga, el fondo es el azul de marca. Los anuncios y el móvil de #servicios (.oink-ads,
   .oink-phone) imitan anuncios reales: sus fotos van tal cual, sin filtro.
   En Elementor: la imagen del widget con este mismo filter en «CSS adicional», y el <svg> en la plantilla (ver la guía). */
.oink-photo {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background-color: var(--oink-blue);   /* mientras carga la foto */
}

.oink-photo > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: url(#oink-mapa-azul);
}
.oink-ads .oink-photo > img,
.oink-phone .oink-photo > img { filter: none; }

/* ── Placa beige sobre foto (anexo §4): las cifras del reto, el club de cada caso y las etiquetas de las disciplinas ──
   Fondo beige, todo el texto en azul (7,0:1; también el h3 del caso, por --oink-title, aunque #casos sea un bloque
   azul) y la sombra desplazada en naranja, como la tarjeta de campaña. 12 px de radio y 8 px de sombra; la etiqueta de
   las disciplinas, más pequeña, lleva 8 y 5 px (sections.css). Cada uso pone su sitio, su relleno y su margen, para
   que la placa y su sombra queden dentro de la foto a cualquier ancho. El marcado no cambia (la placa es el bloque
   que ya llevaba el texto), por eso van aquí los tres selectores de bloque. Al imprimir, print-color-adjust: exact
   (al final de sections.css) conserva el beige y la sombra aunque no se impriman los fondos. */
.oink-reto__stats,
.oink-caso__id,
.oink-disc__label {
  --oink-title: var(--oink-blue);
  position: absolute;
  z-index: 2;                           /* por encima de la foto */
  border-radius: 12px;
  background-color: var(--oink-beige);
  color: var(--oink-blue);
  box-shadow: 8px 8px 0 var(--oink-orange);
}

/* ── Entrada de bloques (spec §5; tarea 11) ────────────────────────────────────────────────────────────────────────
   Cada [data-reveal] sube 16 px y se funde en 500 ms --ease-out al entrar en pantalla (main.js pone .is-visible una vez),
   con 60 ms entre hermanos (--i, lo pone main.js en los hijos de [data-reveal-stagger]). Es de marketing: puede pasar de
   300 ms. Solo se oculta bajo oink-reveal-on, que pone main.js después de crear el IntersectionObserver: la clase .oink-js la pone
   un script en línea que no sabe si main.js llegará a ejecutarse, y entonces todo tiene que verse.
   La transición va solo en .is-visible: ocultar (al poner oink-reveal-on) es instantáneo y solo se anima la entrada. Si el
   navegador pintó parte de la página antes de main.js, nada se desvanece para volver a aparecer.
   Solo en pantalla: al imprimir (o guardar como PDF) no hay scroll que los haga entrar y saldrían en blanco. */
@media screen {
  html.oink-reveal-on [data-reveal]:not(.is-visible) {
    opacity: 0;
    transform: translateY(16px);
  }
}
html.oink-reveal-on [data-reveal].is-visible {
  transition: opacity 500ms var(--ease-out), transform 500ms var(--ease-out);
  transition-delay: calc(var(--i, 0) * 60ms);
}
/* Con el teclado (Tab) el foco puede llegar a un bloque antes de que entre: se ve al instante, sin esperar al fundido. */
html.oink-reveal-on [data-reveal]:focus-within {
  opacity: 1;
  transform: none;
}

/* ── Movimiento reducido (prefers-reduced-motion: reduce; spec §5) ─────────────────────────────────────────────────
   Fuera los desplazamientos y las escalas; se quedan los fundidos de opacidad y los cambios de color. */
@media (prefers-reduced-motion: reduce) {
  html.oink-reveal-on [data-reveal]:not(.is-visible) { transform: none; }
  html.oink-reveal-on [data-reveal].is-visible { transition-property: opacity; }

  .oink-js [data-tabs].is-visible [role="tabpanel"] { transition-property: opacity; }
  @starting-style {
    .oink-js [data-tabs].is-visible [role="tabpanel"] { transform: none; }
  }

  .oink-btn { transition: background-color 160ms ease, color 160ms ease; }
  .oink-choice { transition: none; }
  .oink-btn:active:not(:disabled),
  .oink-choice:active { transform: none; }
}
