/* Los tokens del sistema de diseño de Play Jump Park (Saltia), en una hoja.
   GENERADO por `tema/construir-hoja.py` desde `diseno/playjump-design-system/`: no se edita a mano.
   Cada fichero va tal cual y en el orden de su styles.css; lo único distinto es que las fuentes se
   sirven desde el propio dominio (fuentes.css) en vez del @import de Google Fonts.
   sha256 de cada origen:
   5738165d52347633  tokens/fonts.css
   71ec6bf8ad3b65f1  tokens/colors.css
   3730b692d5212148  tokens/typography.css
   c364ac552c5571ef  tokens/space.css
   593dc9098610a23a  tokens/shape.css
   0cfe985f7ede6ad9  tokens/motion.css
   7ecea7e850989e82  tokens/base.css */

/* ── fuentes.css ── */
/* Las fuentes del sistema Saltia, servidas desde el propio dominio.
   GENERADO por `tema/traer-fuentes.py` del repo de la instancia: no se edita a mano.
   Cada @font-face es el que Google entrega al @import del diseño, con la url() cambiada. */
/* vietnamese */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 900;
  font-stretch: 75% 125%;
  font-display: swap;
  src: url(../fuentes/archivo-400-900-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 900;
  font-stretch: 75% 125%;
  font-display: swap;
  src: url(../fuentes/archivo-400-900-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 900;
  font-stretch: 75% 125%;
  font-display: swap;
  src: url(../fuentes/archivo-400-900-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fuentes/dm-mono-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fuentes/dm-mono-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(../fuentes/dm-mono-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(../fuentes/dm-mono-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url(../fuentes/figtree-300-800-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url(../fuentes/figtree-300-800-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── tokens/fonts.css ── */
/* Webfonts servidas desde Google Fonts (no se entregaron binarios de marca).
   Archivo  -> display / titulares (eje de anchura 62–125 para titulares comprimidos o expandidos)
   Figtree  -> UI y texto corrido
   DM Mono  -> horarios, códigos de reserva, datos */

:root {
  --font-display: "Archivo", "Archivo Expanded", system-ui, sans-serif; /* @kind font */
  --font-ui: "Figtree", system-ui, -apple-system, sans-serif; /* @kind font */
  --font-mono: "DM Mono", ui-monospace, "SFMono-Regular", monospace;

  /* Ejes variables de Archivo usados en titulares */
  --display-width-wide: 112; /* @kind font */   /* héroes, números grandes */
  --display-width-normal: 100; /* @kind font */ /* titulares de sección */
  --display-width-tight: 88; /* @kind font */   /* etiquetas y overlines */
}

/* ── tokens/colors.css ── */
/* Play Jump Park · color
   La paleta sale del logotipo (cian, lima, naranja, magenta) y de las fotos del
   parque (azul de las camas, amarillo y magenta de las colchonetas).
   Ambiente claro: blanco y aire; la tinta azulada solo en el pie, el velo de las
   fotos y las capas flotantes. Un único color de acción: el naranja del logo. */

:root {
  /* ── Tinta azulada: texto, superficies oscuras y bordes ──── */
  --ink-900: #0b2e4a;
  --ink-800: #123d5f;
  --ink-700: #1c4e74;
  --ink-600: #3d5a72;
  --ink-500: #5c768d;
  --ink-400: #93a9bb;
  --ink-300: #bbccd8;
  --ink-200: #dae7ef;
  --ink-100: #edf4f8;
  --ink-050: #f7fbfd;
  --snow: #ffffff;

  /* ── Acción: naranja del logotipo. ÚNICO color de CTA ────── */
  --flare-700: #b84203;
  --flare-600: #e4550a;
  --flare-500: #ff6a13;
  --flare-400: #ff8f4d;
  --flare-200: #ffd7b8;
  --flare-100: #fff1e6;

  /* ── Cian de marca (del logo y de los neones del parque) ─── */
  --aqua-700: #065b7e;
  --aqua-600: #0e8fc4;
  --aqua-500: #17c8f5;
  --aqua-400: #74ddfa;
  --aqua-100: #e6f7ff;

  /* ── Lima del logotipo: energía, detalles sobre tinta ────── */
  --volt-700: #556e00;
  --volt-600: #97c300;
  --volt-500: #b6e80f;
  --volt-400: #cdf14f;
  --volt-100: #f0fbcb;

  /* ── Magenta y amarillo del parque: acentos, nunca acción ── */
  --berry-700: #a81454;
  --berry-600: #d41e6b;
  --berry-500: #ff3d8b;
  --berry-400: #ff7cb0;
  --berry-100: #ffe0ee;
  --sun-600: #d9a400;
  --sun-500: #ffc400;
  --sun-100: #fff4cf;

  /* ── Semánticos de estado ─────────────────────────────────── */
  --success-600: #0b6236;
  --success-500: #17a94a;
  --success-100: #ddf5e4;
  --warn-600: #c47f00;
  --warn-500: #f5a300;
  --warn-100: #fff0cf;
  --danger-600: #b81b2d;
  --danger-500: #e0263b;
  --danger-100: #ffe1e4;

  /* ── Marca (alias de lectura directa) ─────────────────────── */
  --brand-500: var(--aqua-600);
  --brand-bright: var(--aqua-500);
  --brand-deep: var(--aqua-700);
  --brand-soft: var(--aqua-100);

  /* ── Alias semánticos: usar SIEMPRE estos en componentes ──── */
  --bg-page: var(--snow);
  --bg-subtle: var(--ink-050);
  --bg-muted: var(--ink-100);
  --bg-brand-soft: var(--aqua-100);
  --bg-ink: var(--ink-900);
  --bg-ink-soft: var(--ink-800);
  --surface-card: var(--snow);
  --surface-card-ink: var(--ink-800);
  /* Cristal claro: la isla y las capas flotantes sobre fondo claro */
  --surface-glass: rgba(255, 255, 255, 0.86);
  --surface-glass-border: rgba(11, 46, 74, 0.12);
  /* Cristal oscuro: solo cuando la capa flota sobre foto o vídeo */
  --surface-glass-ink: rgba(11, 46, 74, 0.72);
  --surface-glass-ink-border: rgba(255, 255, 255, 0.16);
  /* Cristal de lo que flota sobre la página (la isla de enlace, LinkIsland, 29-09):
     se ve pasar el contenido por debajo, desenfocado. Al 82 %: blanco 9,5:1 y el
     secundario 5:1 sobre una página blanca. También la isla (28-09): en reposo, con un
     panel abierto, con las cookies, los avisos y el pago fallido. */
  --surface-glass-ink-float: rgba(11, 46, 74, 0.82);

  --text-strong: var(--ink-900);
  --text-body: var(--ink-600);
  --text-muted: var(--ink-500);
  --text-inverse: var(--snow);
  --text-inverse-muted: rgba(255, 255, 255, 0.72);
  --text-link: var(--aqua-700);
  --text-link-hover: var(--flare-700);

  --border-subtle: var(--ink-200);
  --border-strong: var(--ink-900);
  --border-inverse: rgba(255, 255, 255, 0.18);

  --action-bg: var(--flare-500);
  /* Con el naranja del logo, el texto va en tinta (4,87:1) y el hover ACLARA (6,18:1) */
  --action-bg-hover: var(--flare-400);
  --action-bg-press: var(--flare-500);
  --action-fg: var(--ink-900);
  --action-quiet-bg: var(--ink-100);
  --action-quiet-fg: var(--ink-900);
  --action-quiet-border: rgba(9, 46, 74, 0.14);
  --focus-ring: var(--flare-500);

  /* ── Controles: campos, casillas, opciones, horas, cantidades ──
     Los componentes de formulario usan SOLO estos, nunca primitivos: así la
     misma pieza sirve sobre claro y sobre tinta (data-surface="ink"). */
  --control-bg: var(--snow);
  --control-bg-solid: var(--snow); /* el mismo, opaco: autorrelleno del navegador */
  --control-bg-hover: var(--ink-050);
  --control-bg-disabled: var(--ink-100);
  --control-border: var(--ink-200);
  --control-border-strong: var(--ink-900); /* foco, elegido, botón activo */
  --control-fg: var(--ink-900);
  --control-fg-disabled: var(--ink-500); /* «Completo» se lee: 4,3:1 sobre su fondo */
  --control-selected-bg: var(--ink-900);
  --control-selected-fg: var(--snow);
  --control-selected-note: var(--volt-500);
  --text-danger: var(--danger-600);
  --border-danger: var(--danger-500);
  --text-low: var(--flare-700); /* «Quedan 3» */
  --text-positive: var(--success-600); /* descuentos, ahorro */
  --icon-accent: var(--aqua-600);
  /* Carga: el hueco del Skeleton y la cama del BounceLoader */
  --skeleton-base: var(--ink-100);
  --skeleton-sheen: var(--ink-050);
  --loader-bed: var(--ink-900);

  /* ── Superficie de tinta: la capa grande de la isla (la compra, Mi cuenta) y
     cualquier capa oscura. El resto de la isla es cristal (--surface-glass-ink-float). ── */
  --ink-surface: rgba(11, 46, 74, 0.94); /* sobre blanco, 12:1 con blanco y 6:1 con el texto secundario */
  --ink-surface-border: rgba(255, 255, 255, 0.16);

  /* ── Avisos: fondo, borde e icono por tono (sobre claro) ── */
  --notice-info-bg: var(--aqua-100);
  --notice-info-border: rgba(6, 91, 126, 0.18);
  --notice-info-fg: var(--aqua-700);
  --notice-warn-bg: var(--warn-100);
  --notice-warn-border: rgba(196, 127, 0, 0.3);
  --notice-warn-fg: #7a5200;
  --notice-danger-bg: var(--danger-100);
  --notice-danger-border: rgba(184, 27, 45, 0.24);
  --notice-danger-fg: var(--danger-600);
  --notice-success-bg: var(--success-100);
  --notice-success-border: rgba(11, 98, 54, 0.2);
  --notice-success-fg: var(--success-600);
  --notice-neutral-bg: var(--ink-050);
  --notice-neutral-border: rgba(9, 46, 74, 0.08);
  --notice-neutral-fg: var(--ink-900);
  --notice-text: var(--ink-900);

  /* ── Zonas: SIN código de color (decisión 20-09-2026).
     Kids y Jump se distinguen por nombre, edad y foto, no por color.
     Los alias siguen existiendo para no romper componentes. ── */
  --zone-kids: var(--aqua-600);
  --zone-jump: var(--ink-900);
  --zone-party: var(--aqua-700);
  --zone-mini: var(--zone-kids);
  --zone-big: var(--zone-jump);
  --zone-mini-soft: var(--aqua-100);
  --zone-big-soft: var(--ink-100);
  --zone-party-soft: var(--aqua-100);

  /* ── Franjas de sección ───────────────────────────────────── */
  --band-ink: var(--ink-900);
  --band-brand: var(--aqua-600);
  --band-volt: var(--volt-500);
  --band-aqua: var(--aqua-500);
  --band-berry: var(--berry-500);
  --band-flare: var(--flare-500);
  --band-subtle: var(--ink-050);

  /* Velo sobre foto o vídeo: contraste garantizado con cualquier fotograma */
  --scrim-video: linear-gradient(180deg, rgba(9, 46, 74, 0.5) 0%, rgba(9, 46, 74, 0.12) 38%, rgba(9, 46, 74, 0.9) 88%); /* @kind color */
  --scrim-card: linear-gradient(180deg, rgba(9, 46, 74, 0) 30%, rgba(9, 46, 74, 0.88) 100%); /* @kind color */
  /* Héroe con el texto en columna a la izquierda: el velo cubre la columna (560px
     cubre titular, texto, precio y botón a cualquier ancho) y se abre a la derecha,
     donde el vídeo enseña la acción. Paradas en px: la columna mide lo mismo en
     una tarjeta de 760 que en una de 1140. */
  --scrim-hero: linear-gradient(90deg, rgba(9, 46, 74, 0.9) 0, rgba(9, 46, 74, 0.82) 560px, rgba(9, 46, 74, 0.28) 920px, rgba(9, 46, 74, 0.1) 100%); /* @kind color */
  /* Héroe apilado (móvil): el vídeo arriba y limpio, y funde a tinta por abajo
     para que el titular entre por su borde sin corte. */
  --scrim-hero-stack: linear-gradient(180deg, rgba(9, 46, 74, 0.42) 0%, rgba(9, 46, 74, 0) 22%, rgba(9, 46, 74, 0) 38%, rgba(9, 46, 74, 0.78) 70%, var(--ink-900) 100%); /* @kind color */
  /* La firma (logo + nota de Google) sobre el vídeo limpio del héroe apilado: un velo
     corto arriba, solo detrás de la firma (la capa mide 128px). A 0,7 hasta 64px, la
     nota en blanco pasa AA sobre cualquier fotograma, también uno blanco. */
  --scrim-firma: linear-gradient(180deg, rgba(9, 46, 74, 0.74) 0, rgba(9, 46, 74, 0.7) 64px, rgba(9, 46, 74, 0) 100%); /* @kind color */
  /* Héroe centrado con el contenido lleno: no hay lado libre, velo parejo. */
  --scrim-hero-center: linear-gradient(180deg, rgba(9, 46, 74, 0.56) 0%, rgba(9, 46, 74, 0.64) 46%, rgba(9, 46, 74, 0.88) 100%); /* @kind color */
}

/* ── Sobre tinta ──
   Dentro de la isla, de la compra o de cualquier capa oscura, se marca el
   contenedor con data-surface="ink" y los mismos componentes cambian solos.
   Contraste medido sobre --ink-surface: texto 13,9:1; secundario (72 %) 7,9:1;
   bordes de control (38 %) 3,1:1, el mínimo de un borde que hay que ver (WCAG
   1.4.11). Un solo gris secundario: nada de 60, 70, 78 u 86 % sueltos. */
[data-surface="ink"] {
  --text-strong: var(--snow);
  --text-body: rgba(255, 255, 255, 0.88);
  --text-muted: rgba(255, 255, 255, 0.72);
  --text-link: var(--aqua-400);
  --text-link-hover: var(--snow);
  --border-subtle: rgba(255, 255, 255, 0.16);
  --edge-subtle: inset 0 0 0 var(--bw-hair) var(--border-subtle); /* el mismo filo, con el borde de la tinta */
  --border-strong: var(--snow);
  --bg-subtle: rgba(255, 255, 255, 0.07);
  --bg-muted: rgba(255, 255, 255, 0.05);
  --surface-card: rgba(255, 255, 255, 0.06);

  --control-bg: rgba(255, 255, 255, 0.08);
  --control-bg-solid: #1f4059;
  --control-bg-hover: rgba(255, 255, 255, 0.14);
  --control-bg-disabled: rgba(255, 255, 255, 0.04);
  --control-border: rgba(255, 255, 255, 0.38);
  --control-border-strong: var(--snow);
  --control-fg: var(--snow);
  --control-fg-disabled: rgba(255, 255, 255, 0.58); /* 4,6:1: una hora completa se lee, tachada */
  --control-selected-bg: var(--snow);
  --control-selected-fg: var(--ink-900);
  --control-selected-note: var(--aqua-700);
  --text-danger: #ff9aa6;
  --border-danger: #ff9aa6;
  --text-low: var(--sun-500);
  --text-positive: var(--volt-500);
  --icon-accent: var(--aqua-400);
  --skeleton-base: rgba(255, 255, 255, 0.08);
  --skeleton-sheen: rgba(255, 255, 255, 0.16);
  --loader-bed: var(--snow);

  --action-quiet-bg: rgba(255, 255, 255, 0.1);
  --action-quiet-fg: var(--snow);
  --action-quiet-border: rgba(255, 255, 255, 0.38);

  --notice-info-bg: rgba(116, 221, 250, 0.12);
  --notice-info-border: rgba(116, 221, 250, 0.34);
  --notice-info-fg: var(--aqua-400);
  --notice-warn-bg: rgba(255, 196, 0, 0.12);
  --notice-warn-border: rgba(255, 196, 0, 0.5);
  --notice-warn-fg: var(--sun-500);
  --notice-danger-bg: rgba(255, 154, 166, 0.12);
  --notice-danger-border: rgba(255, 154, 166, 0.5);
  --notice-danger-fg: #ff9aa6;
  --notice-success-bg: rgba(182, 232, 15, 0.12);
  --notice-success-border: rgba(182, 232, 15, 0.42);
  --notice-success-fg: var(--volt-500);
  --notice-neutral-bg: rgba(255, 255, 255, 0.07);
  --notice-neutral-border: rgba(255, 255, 255, 0.16);
  --notice-neutral-fg: var(--snow);
  --notice-text: rgba(255, 255, 255, 0.92);

  --ring: 0 0 0 3px rgba(255, 106, 19, 0.6);
  color: var(--text-body);
}

/* ── tokens/typography.css ── */
:root {
  /* ── Escala display (marketing, fluida) ───────────────────── */
  --fs-display-xl: clamp(3.25rem, 7vw, 6.5rem); /* @kind font */
  --fs-display-l: clamp(2.5rem, 5vw, 4.5rem); /* @kind font */
  --fs-display-m: clamp(2rem, 3.4vw, 3rem); /* @kind font */

  /* ── Escala fija (UI, tablas, tarjetas) ───────────────────── */
  --fs-h1: 2.5rem; /* @kind font */
  --fs-h2: 2rem; /* @kind font */
  --fs-h3: 1.5rem; /* @kind font */
  --fs-h4: 1.25rem; /* @kind font */
  --fs-lead: 1.25rem; /* @kind font */
  --fs-body: 1rem; /* @kind font */
  --fs-body-sm: 0.9375rem; /* @kind font */
  --fs-caption: 0.8125rem; /* @kind font */
  --fs-overline: 0.75rem;

  /* ── Altura de línea ──────────────────────────────────────── */
  --lh-display: 0.92; /* @kind font */
  --lh-tight: 1.05; /* @kind font */
  --lh-heading: 1.15; /* @kind font */
  --lh-body: 1.55; /* @kind font */
  --lh-loose: 1.7; /* @kind font */

  /* ── Grosor ───────────────────────────────────────────────── */
  --fw-regular: 400; /* @kind font */
  --fw-medium: 500; /* @kind font */
  --fw-semibold: 600; /* @kind font */
  --fw-bold: 700; /* @kind font */
  --fw-black: 900; /* @kind font */

  /* ── Tracking ─────────────────────────────────────────────── */
  --tracking-display: -0.035em; /* @kind font */
  --tracking-heading: -0.02em; /* @kind font */
  --tracking-body: 0; /* @kind font */
  --tracking-overline: 0; /* @kind font */

  /* ── Roles compuestos (atajos) ────────────────────────────── */
  --type-display: var(--fw-black) var(--fs-display-l) / var(--lh-display) var(--font-display); /* @kind font */
  --type-h2: var(--fw-bold) var(--fs-h2) / var(--lh-heading) var(--font-display); /* @kind font */
  --type-h3: var(--fw-bold) var(--fs-h3) / var(--lh-heading) var(--font-display); /* @kind font */
  --type-lead: var(--fw-regular) var(--fs-lead) / var(--lh-body) var(--font-ui); /* @kind font */
  --type-body: var(--fw-regular) var(--fs-body) / var(--lh-body) var(--font-ui); /* @kind font */
  --type-label: var(--fw-semibold) var(--fs-body-sm) / 1.2 var(--font-ui); /* @kind font */
  --type-overline: var(--fw-semibold) var(--fs-body-sm) / 1.3 var(--font-ui); /* @kind font */
  --type-mono: var(--fw-medium) var(--fs-caption) / 1.4 var(--font-mono); /* @kind font */
}

/* ── tokens/space.css ── */
:root {
  /* Escala base 4px */
  --space-0: 0; /* @kind spacing */
  --space-1: 4px; /* @kind spacing */
  --space-2: 8px; /* @kind spacing */
  --space-3: 12px; /* @kind spacing */
  --space-4: 16px; /* @kind spacing */
  --space-5: 20px; /* @kind spacing */
  --space-6: 24px; /* @kind spacing */
  --space-8: 32px; /* @kind spacing */
  --space-10: 40px; /* @kind spacing */
  --space-12: 48px; /* @kind spacing */
  --space-16: 64px; /* @kind spacing */
  --space-20: 80px; /* @kind spacing */
  --space-24: 96px; /* @kind spacing */
  --space-32: 128px;

  /* Ritmo de página */
  --section-y: clamp(64px, 8vw, 120px); /* @kind spacing */
  --section-y-tight: clamp(40px, 5vw, 72px); /* @kind spacing */
  --gutter: clamp(20px, 4vw, 48px); /* @kind spacing */
  --container: 1240px; /* @kind spacing */
  --container-narrow: 760px;

  /* Primera pantalla (26-09): el héroe y la isla en una sola retícula.
     Móvil y tableta: el mismo aire en todo — --gutter a los lados del héroe y de
     la isla, sobre el héroe y bajo la isla. Escritorio: --island-inset sobre la
     isla, entre la isla y el héroe, y bajo el héroe. --island-h lo publica la
     isla medida (su fila en reposo); aquí, el de una fila. --hero-screen es el
     alto de la tarjeta del héroe que cierra la primera pantalla. */
  --island-inset: var(--space-4); /* @kind spacing */
  --island-h: 62px; /* @kind spacing */
  --fold-gap: var(--space-4); /* @kind spacing */
  --hero-top: var(--gutter); /* @kind spacing */
  --hero-screen: calc(100svh - 3 * var(--gutter) - var(--island-h));

  /* Densidades internas */
  --pad-card: var(--space-6); /* @kind spacing */
  --pad-card-lg: var(--space-8); /* @kind spacing */
  --gap-grid: var(--space-6); /* @kind spacing */
  --gap-inline: var(--space-3);

  /* Alturas de control (mínimo táctil 44px) */
  --control-sm: 40px; /* @kind spacing */
  --control-md: 48px; /* @kind spacing */
  --control-lg: 56px; /* @kind spacing */
  --control-xl: 64px; /* @kind spacing */
}

/* Desde 900px la isla va arriba: el aire vertical es --island-inset. */
@media (min-width: 900px) {
  :root {
    --hero-top: var(--island-inset);
    --hero-screen: calc(100svh - 3 * var(--island-inset) - var(--island-h));
  }
}

/* ── tokens/shape.css ── */
:root {
  /* ── Radios ───────────────────────────────────────────────── */
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-2xl: 36px;
  --r-pill: 999px;

  /* ── Bordes ───────────────────────────────────────────────── */
  --bw-hair: 1px; /* @kind other */
  --bw-solid: 2px; /* @kind other */
  --bw-chunky: 3px; /* @kind other */
  --border-card: var(--bw-hair) solid var(--border-subtle); /* @kind other */
  --border-card-ink: var(--bw-hair) solid var(--border-inverse);

  /* ── Sombras: cortas, difusas y frías (nunca negro puro) ──── */
  --shadow-xs: 0 1px 2px rgba(9, 46, 74, 0.06);
  --shadow-sm: 0 2px 6px rgba(9, 46, 74, 0.07);
  --shadow-md: 0 8px 20px -6px rgba(9, 46, 74, 0.14);
  --shadow-lg: 0 20px 44px -12px rgba(9, 46, 74, 0.22);
  --shadow-island: 0 14px 34px -12px rgba(9, 46, 74, 0.35), 0 0 0 1px rgba(11, 46, 74, 0.06) inset;
  /* El cristal de la isla: sombra honda y el filo de luz arriba. La isla de la web
     (ParkIsland) y la de las páginas de enlace (LinkIsland) comparten esta y nada más. */
  --shadow-island-float: 0 18px 44px -18px rgba(9, 46, 74, 0.72), inset 0 1px 0 rgba(255, 255, 255, 0.14);
  --shadow-cta: 0 10px 24px -8px rgba(255, 106, 19, 0.55);
  --shadow-inset-hair: inset 0 0 0 1px rgba(9, 46, 74, 0.06);
  /* El filo del bloque suave (28-09): --bg-subtle va SIEMPRE con él. El gris solo da
     1,04:1 con el blanco y en pantallas antiguas o al sol desaparece; la línea da
     1,26:1 y es lo último que se pierde. Sombra por dentro, no borde: no mueve la caja.
     Sobre tinta se redefine en colors.css, con el borde de la tinta. */
  --edge-subtle: inset 0 0 0 var(--bw-hair) var(--border-subtle); /* @kind shadow */

  /* ── Desenfoque (solo en capas flotantes sobre vídeo) ─────── */
  --blur-island: saturate(160%) blur(20px); /* @kind other */
  --blur-veil: saturate(120%) blur(8px); /* @kind other */

  /* ── Anillo de foco ───────────────────────────────────────── */
  --ring: 0 0 0 3px rgba(255, 106, 19, 0.38); /* @kind shadow */
  --ring-offset: 0 0 0 2px var(--bg-page), 0 0 0 5px rgba(255, 106, 19, 0.5);

  /* ── Relaciones de aspecto de medios ──────────────────────── */
  --ar-hero: 21 / 9; /* @kind other */
  --ar-wide: 16 / 9; /* @kind other */
  --ar-card: 4 / 3; /* @kind other */
  --ar-portrait: 3 / 4; /* @kind other */
  --ar-story: 9 / 16; /* @kind other */
}

/* ── tokens/motion.css ── */
:root {
  /* ── Duraciones ───────────────────────────────────────────── */
  --dur-instant: 90ms; /* @kind other */
  --dur-fast: 150ms; /* @kind other */
  --dur-base: 240ms; /* @kind other */
  --dur-slow: 380ms; /* @kind other */
  --dur-island: 480ms;   /* el morph de lo que se toca: abrir, cerrar, responder (29-09) */
  --dur-island-calma: 820ms; /* @kind other */   /* el morph de lo que trae el scroll: lento y suave (29-09) */
  --dur-reveal: 700ms;   /* entradas al hacer scroll */
  --dur-bote: 620ms; /* @kind other */   /* la firma: el bote de lo que empuja (botón principal, la acción de la isla) */
  --dur-close: 300ms; /* @kind other */   /* cerrar es más corto que abrir */
  --dur-count: 900ms; /* @kind other */   /* cifras que cuentan (4,9) */
  --dur-nudge: 700ms; /* @kind other */   /* el bote de «hay más abajo» (ScrollNudge) */
  --nudge-delay: 4500ms; /* @kind other */   /* tiempo quieto arriba antes del bote */
  --nudge-distance: 14px; /* @kind other */

  /* ── Curvas ───────────────────────────────────────────────── */
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1); /* @kind other */
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* @kind other */
  --ease-spring: cubic-bezier(0.22, 1.2, 0.36, 1); /* @kind other */   /* rebote corto: la firma del parque */
  --ease-island: cubic-bezier(0.3, 1.12, 0.3, 1); /* @kind other */   /* el morph de la isla: un rebote corto y suave (29-09, antes 1.35) */

  /* ── Transiciones compuestas ──────────────────────────────── */
  --t-hover: all var(--dur-fast) var(--ease-out); /* @kind other */
  --t-press: transform var(--dur-instant) var(--ease-out); /* @kind other */
  --t-card: transform var(--dur-base) var(--ease-spring), box-shadow var(--dur-base) var(--ease-out); /* @kind other */
  /* El morph de la isla: abrir el menú y, desde el 28-09, cada cambio de situación en reposo. */
  --t-island: width var(--dur-island) var(--ease-island), height var(--dur-island) var(--ease-island), border-radius var(--dur-island) var(--ease-island), transform var(--dur-base) var(--ease-out);
  /* El tono de la acción de la isla (naranja ↔ secundaria): el mismo tiempo que el morph, sin rebote (el color no rebota). */
  --t-island-tone: background-color var(--dur-island) var(--ease-in-out), color var(--dur-island) var(--ease-in-out), box-shadow var(--dur-island) var(--ease-in-out); /* @kind other */

  /* ── Desplazamientos de estado ────────────────────────────── */
  --lift-hover: -3px; /* @kind other */
  --lift-card: -6px; /* @kind other */
  --scale-press: 0.97; /* @kind other */
  --scale-pop: 1.03; /* @kind other */
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-instant: 1ms; /* @kind other */
    --dur-fast: 1ms; /* @kind other */
    --dur-base: 1ms; /* @kind other */
    --dur-slow: 1ms; /* @kind other */
    --dur-island: 1ms; /* @kind other */
    --dur-island-calma: 1ms; /* @kind other */
    --dur-reveal: 1ms; /* @kind other */
    --lift-hover: 0px; /* @kind other */
    --lift-card: 0px; /* @kind other */
    --scale-press: 1; /* @kind other */
    --scale-pop: 1; /* @kind other */
    --nudge-distance: 0px; /* @kind other */
    --dur-bote: 1ms; /* @kind other */
    --dur-close: 1ms; /* @kind other */
    --dur-count: 1ms; /* @kind other */
  }
}

/* ── tokens/base.css ── */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--text-body);
  font: var(--type-body);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  margin: 0;
  color: var(--text-strong);
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  line-height: var(--lh-heading);
  letter-spacing: var(--tracking-heading);
  font-variation-settings: "wdth" var(--display-width-normal);
  text-wrap: balance;
}
h1 { font-size: var(--fs-h1); line-height: var(--lh-tight); letter-spacing: var(--tracking-display); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); font-weight: var(--fw-bold); }
h4 { font-size: var(--fs-h4); font-weight: var(--fw-bold); }

p { margin: 0; text-wrap: pretty; }

a { color: var(--text-link); text-decoration: none; text-underline-offset: 3px; transition: var(--t-hover); }
a:hover { color: var(--text-link-hover); text-decoration: underline; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-radius: var(--r-sm);
}

/* El foco que pone el código (el titular de un paso, tabindex="-1") no lleva
   anillo: el anillo es para quien navega con el teclado por controles. */
[tabindex="-1"]:focus, [tabindex="-1"]:focus-visible { outline: none; box-shadow: none; }

::selection { background: var(--aqua-100); color: var(--ink-900); }

/* Autorrelleno del navegador: sin esto pinta el campo de amarillo o de blanco,
   también sobre tinta, y el texto blanco desaparece. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--control-fg);
  caret-color: var(--control-fg);
  box-shadow: 0 0 0 1000px var(--control-bg-solid) inset;
  transition: background-color 9999s ease-out 0s;
}

/* Campos a 16px como mínimo: con menos, el iPhone amplía la página al tocarlos. */
input, select, textarea { font-size: max(16px, 1em); }

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

/* Keyframes del sistema: referenciables desde estilos en línea de los componentes.
   Vocabulario corto (26-09): sube (pj-rise), aparece (pj-pop, pj-fade-in), cambia
   (pj-island-swap), paso (pj-step-fwd / back) y bote (pj-bote, la firma: solo para lo
   que empuja). Aparte, los cuatro momentos especiales: Listo (pj-outcome-*), la
   invitación (confeti, banderines, burbujas, pj-bar-rise, pj-chip-pop) y la carga
   (pj-bounce-*, pj-sheen); y la temporada de la isla (pj-luz, pj-parpadeo, pj-brota,
   pj-mece, pj-pelota, pj-estalla, pj-fugaz, pj-copo, pj-lapiz, pj-hoja, pj-gota). Nada nuevo sin mirar antes si ya existe. */
/* El bote (firma B del laboratorio): sube, se pasa 4px y aterriza con un 3 % de
   aplastamiento. Con --dur-bote y timing linear: las curvas van por tramo. */
/* Plazas en directo (TimeSlotPicker): la casilla destella una vez, la cifra baja y la hora llena se tacha. */
@keyframes pj-destello { from { background-color: color-mix(in srgb, var(--text-low) 24%, var(--control-bg)); } }
@keyframes pj-baja { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@keyframes pj-tachar { from { background-size: 0 2px; } to { background-size: 100% 2px; } }
@keyframes pj-trazo { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
@keyframes pj-bote { 0% { opacity: 0; transform: translateY(18px); animation-timing-function: cubic-bezier(0.2, 0.8, 0.3, 1); } 45% { opacity: 1; transform: translateY(-4px); animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.5); } 68% { transform: translateY(0) scale(1.015, 0.97); animation-timing-function: cubic-bezier(0.2, 0.8, 0.3, 1); } 100% { opacity: 1; transform: none; } }
@keyframes pj-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
@keyframes pj-pop { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: scale(1); } }
@keyframes pj-island-in { from { opacity: 0; transform: translateY(-14px) scale(0.96); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes pj-island-swap { from { opacity: 0; transform: translateY(5px) scale(0.985); filter: blur(6px); } 55% { filter: blur(0); } to { opacity: 1; transform: none; filter: blur(0); } }
/* Lo que la isla deja de decir (28-09): se desenfoca y se va mientras lo nuevo entra con pj-island-swap. */
@keyframes pj-island-swap-out { from { opacity: 1; transform: none; filter: blur(0); } to { opacity: 0; transform: scale(1.03); filter: blur(6px); } }
@keyframes pj-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes pj-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes pj-sheen { from { background-position: -140% 0; } to { background-position: 240% 0; } }
/* Desenlace de la compra (OutcomeHeader): el único momento con movimiento */
@keyframes pj-outcome-pop { 0% { transform: scale(0.3); opacity: 0; } 60% { transform: scale(1.1); opacity: 1; } 100% { transform: scale(1); } }
@keyframes pj-outcome-ring { 0% { transform: scale(0.9); opacity: 0.9; } 100% { transform: scale(2); opacity: 0; } }
@keyframes pj-outcome-burst { 0% { opacity: 0; transform: rotate(var(--a)) translateY(0) scale(0.4); } 25% { opacity: 1; } 100% { opacity: 0; transform: rotate(var(--a)) translateY(-62px) rotate(90deg) scale(1); } }
@keyframes pj-spin { to { transform: rotate(360deg); } }
/* El cursor de la casilla activa (CodeInput): parpadea como el del sistema. */
@keyframes pj-caret { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
/* BounceLoader: una bola que bota en una cama elástica. Cae con gravedad, se
   aplasta al tocar, la cama cede y cambia de color en cada bote (cian, lima,
   amarillo, magenta: los colores del parque; el naranja es de la acción). */
@keyframes pj-bounce-ball {
  0%, 100% { transform: translateY(-0.52em) scale(1, 1); animation-timing-function: cubic-bezier(0.45, 0, 0.9, 0.5); }
  44% { transform: translateY(0) scale(1.06, 0.94); animation-timing-function: linear; }
  50% { transform: translateY(0.05em) scale(1.24, 0.76); animation-timing-function: cubic-bezier(0.1, 0.5, 0.55, 1); }
  58% { transform: translateY(-0.06em) scale(0.92, 1.1); animation-timing-function: cubic-bezier(0.1, 0.5, 0.55, 1); }
}
@keyframes pj-bounce-bed { 0%, 40%, 64%, 100% { transform: scaleY(0.18); } 50% { transform: scaleY(1); } }
@keyframes pj-bounce-shadow { 0%, 100% { transform: scaleX(0.45); opacity: 0.18; } 50% { transform: scaleX(1); opacity: 0.42; } }
@keyframes pj-bounce-hue { 0%, 12.4% { background: var(--aqua-500); } 12.5%, 37.4% { background: var(--volt-500); } 37.5%, 62.4% { background: var(--sun-500); } 62.5%, 87.4% { background: var(--berry-500); } 87.5%, 100% { background: var(--aqua-500); } }
/* Pasos de la compra con dirección: avanzar entra por la derecha; Volver, por la izquierda */
@keyframes pj-step-fwd { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes pj-step-back { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: none; } }
/* La invitación: el confeti cae una vez al abrirla o al cambiar de tema (InviteCard animate).
   Con «reducir movimiento», aparece en su sitio. */
/* Cada tema trae la suya: fiesta estalla desde la chapa y cuelga sus banderines; sereno sube burbujas. La chapa de edad salta con el rebote del parque. */
@keyframes pj-confetti-pop { from { opacity: 0; transform: scale(0) rotate(var(--r, 0deg)); } 70% { opacity: 1; transform: scale(1.25) rotate(var(--r, 0deg)); } to { opacity: 1; transform: scale(1) rotate(var(--r, 0deg)); } }
@keyframes pj-pennant-drop { from { opacity: 0; transform: translateY(-110%); } to { opacity: 1; transform: none; } }
@keyframes pj-bubble-rise { from { opacity: 0; transform: translateY(26px) scale(0.7); } to { opacity: 1; transform: none; } }
@keyframes pj-bubble-in { from { opacity: 0; transform: translateY(8px) scale(0.92); } to { opacity: 1; transform: none; } }
@keyframes pj-bar-rise { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@keyframes pj-chip-pop { from { opacity: 0; transform: scale(0.4); } 70% { opacity: 1; transform: scale(1.08); } to { opacity: 1; transform: scale(1); } }
@keyframes pj-confetti-fall { from { opacity: 0; transform: translateY(-56px) rotate(calc(var(--r, 0deg) - 140deg)); } 60% { opacity: 1; } to { opacity: 1; transform: translateY(0) rotate(var(--r, 0deg)); } }
/* Temporadas de la isla (ParkIsland season, 26-09): llegan una vez y se quedan. El gato
   y el huevo que se asoma reutilizan pj-bote; el confeti, pj-confetti-fall; flores, huevos y
   globos, pj-chip-pop; los banderines, pj-pennant-drop; el lápiz, pj-trazo; la nube, pj-pop. */
@keyframes pj-luz-on { 0% { opacity: 0.15; } 35% { opacity: 1; } 55% { opacity: 0.35; } 100% { opacity: 1; } }
@keyframes pj-luz { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
@keyframes pj-parpadeo { 0%, 93%, 100% { transform: scaleY(1); } 96.5% { transform: scaleY(0.1); } }
@keyframes pj-brota { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes pj-mece { 0%, 100% { transform: rotate(0deg); } 30% { transform: rotate(-4deg); } 70% { transform: rotate(4deg); } }
@keyframes pj-pelota { 0% { opacity: 0; transform: translateY(-72px); animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); } 6% { opacity: 1; } 36% { transform: translateY(0) scale(1.2, 0.78); animation-timing-function: cubic-bezier(0, 0.55, 0.45, 1); } 58% { transform: translateY(-20px) scale(0.95, 1.05); animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); } 75% { transform: translateY(0) scale(1.1, 0.88); animation-timing-function: cubic-bezier(0, 0.55, 0.45, 1); } 88% { transform: translateY(-5px) scale(1); animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); } 100% { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes pj-pelota-gira { from { transform: rotate(0deg); } to { transform: rotate(200deg); } }
@keyframes pj-estalla { from { opacity: 0; transform: rotate(var(--a, 0deg)) translateY(0) scale(0.4); } 25% { opacity: 1; } to { opacity: 1; transform: rotate(var(--a, 0deg)) translateY(calc(-1 * var(--rad, 5px))) scale(1); } }
@keyframes pj-estela { 0% { opacity: 1; transform: scaleY(0); } 60% { opacity: 1; transform: scaleY(1); } 100% { opacity: 0; transform: scaleY(1); } }
@keyframes pj-fugaz { from { opacity: 0; transform: translate(-64px, -24px); } 20% { opacity: 1; } to { opacity: 1; transform: translate(0, 0); } }
@keyframes pj-cola { 0%, 70% { opacity: 1; } 100% { opacity: 0; } }
@keyframes pj-copo { 0% { opacity: 0; transform: translate(-4px, -40px); } 15% { opacity: 1; } 50% { transform: translate(3px, -20px); } 85% { opacity: 1; } 100% { opacity: 0; transform: translate(0, 0); } }
@keyframes pj-lapiz { from { transform: translateX(calc(-1 * var(--l, 0px))); } to { transform: translateX(0); } }
@keyframes pj-hoja { 0% { opacity: 0; transform: translate(-14px, -56px) rotate(calc(var(--r, 0deg) - 80deg)); } 12% { opacity: 1; } 40% { transform: translate(10px, -34px) rotate(calc(var(--r, 0deg) + 40deg)); } 70% { transform: translate(-6px, -12px) rotate(calc(var(--r, 0deg) - 25deg)); } 100% { opacity: 1; transform: translate(0, 0) rotate(var(--r, 0deg)); } }
@keyframes pj-gota { 0% { opacity: 0; transform: translateY(0); } 20% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; transform: translateY(5px); } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } }

.pj-ink { background: var(--bg-ink); color: var(--text-inverse); }
.pj-ink h1, .pj-ink h2, .pj-ink h3, .pj-ink h4 { color: var(--text-inverse); }
.pj-container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.pj-num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* Entre páginas (26-09): la página se funde en corto y la isla se queda (se llama
   pj-isla). De la portada al producto, la foto elegida se convierte en la cabecera:
   ZoneCard / PlanDoor y VideoHero comparten transitionName. Donde el navegador no
   tiene View Transitions entre documentos, la página carga sin más. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: pj-vt-out var(--dur-fast) var(--ease-out) both; }
::view-transition-new(root) { animation: pj-vt-in var(--dur-base) var(--ease-out) var(--dur-fast) both; }
::view-transition-group(*) { animation-duration: 480ms; animation-timing-function: var(--ease-out); }
@keyframes pj-vt-out { to { opacity: 0; } }
@keyframes pj-vt-in { from { opacity: 0; transform: translateY(8px); } }
@media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } }

/* Llegada limpia (VideoHero, 27-09): lo que la línea de la isla corta al llegar no se ve
   hasta el primer scroll. Solo opacidad: nada se mueve y los lectores de pantalla lo leen. */
[data-llegada="oculto"] { opacity: 0 !important; pointer-events: none; }
[data-llegada="visto"] { transition: opacity var(--dur-base) var(--ease-out); }
@media print { [data-llegada] { opacity: 1 !important; } }
