/* laCardio · Heart Age Challenge — tema kiosco táctil vertical
   Paleta y tipografías extraídas exactamente del PDF `mock up app_ LA CARDIO.pdf` */

@font-face {
  font-family: 'DxGrafik';
  src: url('../fonts/DxGrafik-SemiBold.otf') format('opentype');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Raleway';
  src: url('../fonts/Raleway-Variable.ttf') format('truetype-variations'),
       url('../fonts/Raleway-Variable.ttf') format('truetype');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Colores exactos muestreados del PDF (sRGB) */
  --navy-deep: #001c56;
  --navy: #002875;
  --navy-mid: #0a3384;
  --navy-card: #032151;
  --red: #f80040;
  --red-dark: #d10035;
  --blue-accent: #2c39d1;
  --blue-accent-dark: #232fb0;
  --sky: #b0d9ec;
  --white: #ffffff;
  --text-muted: rgba(255, 255, 255, 0.78);
  --text-faint: rgba(255, 255, 255, 0.5);
  --card-bg: rgba(255, 255, 255, 0.06);
  --card-border: rgba(255, 255, 255, 0.14);
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  --font-display: 'DxGrafik', 'Raleway', sans-serif;
  --font-body: 'Raleway', 'Segoe UI', system-ui, sans-serif;
}

* { box-sizing: border-box; }

svg:not([width]) { width: 1em; height: 1em; vertical-align: middle; }

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  /* Cadena de fallback para Safari iOS viejo: 100% -> -webkit-fill-available
     (soluciona el clásico "100vh más alto que el área visible" cuando la
     barra de herramientas de Safari se expande/colapsa) -> 100dvh (el
     correcto en navegadores modernos, incluido Safari reciente). */
  height: 100%;
  height: -webkit-fill-available;
  height: 100dvh;
  overflow: hidden;
  overscroll-behavior: none;
  background: var(--navy);
  color: var(--white);
  font-family: var(--font-body);
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}
/* El user-select:none de arriba (evita selección de texto accidental al
 * tocar botones/etiquetas en el kiosco) se hereda hasta los <input>/<select>
 * — y en varios navegadores móviles (confirmado también fuera de iOS) un
 * campo de texto con user-select:none heredado deja de poder recibir foco
 * al tocarlo: el teclado nunca aparece y no se puede escribir nada. Se
 * revierte sólo para los campos de formulario, que si necesitan seleccionar
 * texto para poder editarlo. */
input, select, textarea {
  -webkit-user-select: text;
  user-select: text;
}

#app {
  position: relative;
  /* Lienzo fijo 9:16 (diseño 1080×1920) que SIEMPRE cabe dentro del viewport y
   * se escala como un bloque único — nunca se deforma (opción B). En pantallas
   * más anchas que 9:16 lo limita la altura; en más angostas (celular vertical)
   * lo limita el ancho, con letterbox negro arriba/abajo. */
  width: min(100vw, calc(100dvh * 9 / 16));
  height: min(100dvh, calc(100vw * 16 / 9));
  background: var(--navy);
  overflow: hidden;
  box-shadow: 0 0 80px rgba(0, 0, 0, 0.6);
  /* #app es el "contenedor" de referencia para todas las unidades cqw del
   * resto del CSS (ver más abajo: prácticamente todo lo que antes usaba vw
   * ahora usa cqw). Esto es lo que soluciona de raíz que el diseño se
   * desborde de la "tarjeta" 9:16 cuando ésta es más angosta que la
   * pantalla real (tablets en vertical, y sobre todo laptop/PC en
   * horizontal, donde la tarjeta puede llegar a ser 3 veces más angosta
   * que la ventana real) — antes "vw" siempre medía la ventana completa
   * sin importar el ancho real de la tarjeta; "cqw" mide el ancho real de
   * #app siempre, sea cual sea el modo (pantalla completa en celular,
   * tarjeta encajonada en tablet/laptop). #app en sí mismo sigue usando vw
   * (no cqw) porque es el que define el contenedor — no puede medirse
   * contra sí mismo.
   * container-type: size (no inline-size) para que ADEMÁS de cqw funcione cqh,
   * y así posicionar todo pixel-exacto contra el lienzo fijo (1cqw≈10.8px,
   * 1cqh≈19.2px del diseño 1080×1920). */
  container-type: size;
}

/* Letterbox SIEMPRE: el lienzo 9:16 (#app, ya dimensionado arriba para caber
   siempre) se centra en un fondo negro en TODO dispositivo — celular vertical
   incluido — para que el diseño escale como bloque y nunca se deforme ni se
   estire a lo ancho. */
html, body { background: #000; }
body { display: flex; align-items: center; justify-content: center; }

/* Ajustes específicos para celular real (no el kiosco de 65") — el resto del
 * sitio sigue calibrado 1:1 contra el PDF a la resolución del kiosco; esto
 * sólo corrige proporciones que se ven distinto en una pantalla angosta. */

.screen-root {
  position: relative;
  width: 100%;
  height: 100%;
}

.screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: calc(4cqh + var(--safe-top)) 6cqw calc(4cqh + var(--safe-bottom));
  opacity: 0;
  transform: translateY(24px) scale(0.99);
  animation: screen-in 480ms cubic-bezier(.19,1,.22,1) forwards;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

@keyframes screen-in {
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.screen.screen-leaving {
  animation: screen-out 260ms ease forwards;
}

@keyframes screen-out {
  to { opacity: 0; transform: translateY(-16px) scale(0.99); }
}

/* Fondo de anillos tipo latido, decorativo, presente en casi todas las pantallas */
.heartbeat-rings {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
  opacity: 0.5;
}
.heartbeat-rings svg { position: absolute; bottom: -10%; left: 50%; transform: translateX(-50%); width: 140cqw; max-width: none; }

.screen > * { position: relative; z-index: 1; }

/* Marca — "Somos → laCardio" */
/* Lockup "Somos ⟶ laCardio" al tamaño del artboard: texto de 499px de ancho
 * total (46.2cqw) con el corazón rojo (46×38px) flotando ENCIMA de
 * "laCardio". El tamaño anterior (2.6cqw) era menos de la mitad del arte. */
.brand {
  display: flex;
  align-items: center;
  gap: 0.35em;
  font-size: 5cqw;
  font-weight: 500;
  font-family: var(--font-body);
  color: var(--white);
}
.brand .brand-arrow-svg {
  width: 6cqw;
  height: auto;
  flex-shrink: 0;
}
.brand .brand-word-wrap { position: relative; display: inline-block; }
/* Header de marca centrado (lo dibuja topBar() en vivo, en vez del texto que
 * antes venía horneado en el fondo). El .brand interior queda del ancho de su
 * contenido y se centra como bloque. */
.brand-header {
  display: flex;
  justify-content: center;
  /* Aire entre el stepper y el lockup, como el artboard (el texto "Somos"
   * arranca en y≈290px del lienzo; antes quedaba pegado a los números). */
  margin-top: 4.5cqh;
  margin-bottom: 2cqh;
}

/* ===== Splash pixel-exacto ==================================================
 * Todo posicionado en absoluto contra el lienzo 9:16. Coords del artboard
 * 1080×1920 (extraídas del Illustrator): cqw = px_x / 10.8, cqh = px_y / 19.2.
 * El texto va en HTML vivo, el fondo es limpio y el corazón es una capa
 * translúcida (opacidad ~0.33, medida directamente del .ai). */
.splash-logo-tl {
  position: absolute;
  left: 9.1cqw;
  top: 2.4cqh;
  height: 5.3cqh;
  width: auto;
  z-index: 3;
}
/* Corazón animado del splash — mismo asset/animación (latido + ECG + flujo de
 * arterias) que Medición/Signos vitales (.heart-anim-*, ver más abajo), pero
 * agrandado y posicionado para fundirse con "AGE"/"CHALLENGE" como en el
 * mockup del cliente, en vez del heart-solo.png estático semitransparente
 * que había antes. Nunca gated (sin .heart-anim-gated): late solo desde que
 * carga la pantalla, como en Signos vitales. */
.splash-heart-anim {
  position: absolute;
  left: 40cqw;
  top: 15.5cqh;
  width: 54cqw;
  aspect-ratio: 2496 / 2772;
  z-index: 1;
  pointer-events: none;
}
.splash-heart-anim > *,
.splash-heart-anim .heart-anim-heart-group > * {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.splash-title {
  position: absolute;
  left: 10.56cqw;
  top: 18.5cqh;
  margin: 0;
  z-index: 2;
  font-family: var(--font-display);
  font-weight: 600;
  text-transform: uppercase;
  line-height: 1;
}
.splash-title .st-line { position: absolute; left: 0; display: block; white-space: nowrap; }
.st-heart { color: var(--red); font-size: 21.3cqw; top: 0; }
.st-age { color: var(--sky); font-size: 21.3cqw; top: 9.4cqh; }
.st-challenge { color: var(--white); font-size: 12.22cqw; top: 19.4cqh; }
.splash-brand {
  position: absolute;
  top: 48cqh;
  left: 50%;
  transform: translateX(-50%);
  width: 70cqw;
  height: auto;
  z-index: 2;
}
.splash-btn {
  position: absolute;
  left: 22.96cqw;
  top: 75.42cqh;
  width: 57.41cqw;
  height: 5.52cqh;
  z-index: 3;
  background: var(--red);
  color: var(--white);
  border: none;
  border-radius: 999px;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 4.2cqw;
  cursor: pointer;
}
.splash-btn .sb-label {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  white-space: nowrap;
}
/* Flecha vectorial del botón (línea + chevron), geometría del artboard:
 * en el diseño va de x774 a x825 (ancho 51px ≈ 4.72cqw), a 43px del borde
 * derecho del botón (≈ 3.98cqw), centrada verticalmente. */
.splash-btn .sb-arrow {
  position: absolute;
  right: 3.98cqw;
  top: 50%;
  transform: translateY(-50%);
  width: 4.72cqw;
  height: auto;
  color: var(--white);
}
/* Franja del splash: misma que .badge-anos del resto (esquinas superiores
 * redondeadas, altura ajustada al contenido con poco padding, pegada al
 * borde inferior). Antes era una barra fija de 11.7cqh sin bordes, y el texto
 * corto se veía perdido/pequeño dentro. */
.splash-footer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  background: var(--red);
  border-radius: 28px 28px 0 0;
  padding: 1.3cqh 6cqw calc(1.3cqh + var(--safe-bottom));
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.splash-footer .disclaimer-text { font-size: 3.2cqw; }
.brand .brand-lead { color: var(--white); font-weight: 300; }
/* Corazón del logo (corazon_lacardio.png, subido por el cliente) ENCIMA de
 * "laCardio" — medido del artboard: rojo visible ≈46×38px sobre la zona "aC",
 * con ~6px de aire respecto del texto. El PNG trae el corazón dentro de un
 * círculo navy (invisible sobre el fondo azul), por eso va algo más grande. */
.brand .brand-heart {
  position: absolute;
  left: 2%;
  bottom: 90%;
  width: 5.2cqw;
  height: auto;
}
.brand .brand-word { font-weight: 700; }

/* Logo "laCardio" como imagen (corazón + texto ya compuestos por el
 * diseñador) — proporción real 1128:416. Se ajusta por altura; el ancho
 * sigue solo (nunca se distorsiona). El tamaño se afina a mano según
 * feedback visual directo. */
/* El corazoncito (blanco y rojo comparten esta clase — lacardioLogo() en
 * ui.js) late en loop, como el resto de los corazones/badges de la app. */
.lacardio-logo {
  height: 7cqw;
  width: auto;
  display: block;
  animation: lacardio-logo-beat 1.2s ease-in-out infinite;
}
@keyframes lacardio-logo-beat {
  0%, 100% { transform: scale(1); }
  10% { transform: scale(1.16); }
  20% { transform: scale(1); }
  30% { transform: scale(1.07); }
  40% { transform: scale(1); }
}

.topbar {
  display: flex;
  flex-direction: column;
  gap: 3cqh;
  margin-bottom: 2cqh;
}

/* Progreso — barra simple (no usada por defecto; se deja como respaldo) */
.progress-wrap { display: flex; align-items: center; gap: 3cqw; }
.progress-track {
  flex: 1;
  height: 8px;
  border-radius: 999px;
  background: rgba(255,255,255,0.14);
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--blue-accent);
  transition: width 500ms ease;
}
.progress-label { font-family: var(--font-body); font-size: 1.6cqw; font-weight: 700; color: var(--white); white-space: nowrap; }

/* Progreso — círculos numerados conectados, como en el PDF */
.step-dots {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  flex: 1;              /* ocupa el ancho: las líneas (flex:1) reparten los 6 círculos */
}
.step-dot {
  flex-shrink: 0;
  /* Tamaño FIJO en cqw = proporción del artboard (círculo de 85px = 7.87cqw).
   * Como el lienzo es 9:16 fijo y escala como bloque, los 6 círculos siempre
   * caben y se ven idénticos en cualquier dispositivo (ya no dependen de
   * window.innerWidth ni se recortan). Ver windowSize=6 en topBar(). */
  width: 7.87cqw;
  height: 7.87cqw;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 4.6cqw;
  font-weight: 600;
  border: 0.28cqw solid var(--sky);
}
.step-dot.done { background: var(--blue-accent); border-color: var(--blue-accent); color: var(--white); }
.step-dot.current { background: var(--white); border-color: var(--white); color: var(--navy); }
.step-dot.pending { background: transparent; color: var(--white); }
.step-line { flex: 1 1 auto; min-width: 1.5cqw; height: 0.14cqw; background: var(--sky); opacity: 1; }
.step-dots-row { display: flex; align-items: center; justify-content: center; gap: 2.6cqw; }
.step-dots-count { font-family: var(--font-body); font-size: 3.24cqw; font-weight: 700; color: var(--white); white-space: nowrap; }

.spacer { flex: 1; }

/* Tipografía */
.title-xl {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 0.98;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}
/* Tamaños medidos directamente del PDF (fuente de verdad): la hoja del splash
   mide exactamente 1080×1920pt — el mismo ancho que la mitad del kiosco real
   (2160px físicos, pantalla de 65" en vertical) — así que 1pt del PDF = 2px
   CSS reales. HEART/AGE = 240.97pt → 22.31cqw; CHALLENGE = 137.29pt → 12.71cqw.
   El mínimo es sólo un piso de seguridad para ventanas de previsualización
   angostas; en el kiosco real el vw manda y reproduce el PDF exacto. */
.title-xl .lg { font-size: 22.31cqw; }
.title-xl .sm { font-size: 12.71cqw; }

.title-lg {
  font-family: var(--font-body);
  font-size: 4cqw;
  font-weight: 800;
  line-height: 1.15;
  /* Red de seguridad: si un tamaño de fuente grande (p.ej. el de
   * "Interpretando", que se pisa con un font-size inline propio) no le cabe
   * a una palabra larga ("orientación", "personalizada") en un celular
   * angosto, que la palabra se parta en vez de desbordar la tarjeta/pantalla. */
  overflow-wrap: break-word;
}
.title-md {
  font-family: var(--font-body);
  font-size: 2.8cqw;
  font-weight: 800;
  line-height: 1.25;
}
/* NOTA: DxGrafik-SemiBold.otf tiene glifos rotos en minúsculas (p.ej. "c", "í") —
   sólo es seguro usarlo en texto 100% mayúsculas (o con text-transform:uppercase) o dígitos.
   Ver .title-xl, .section-title, .ppm-badge .val, .step-dot, .rate-ring .num. */
.eyebrow {
  font-family: var(--font-body);
  font-size: 1.6cqw;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--white);
}
.section-title {
  font-family: var(--font-display);
  font-size: 4.6cqw;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--sky);
  text-transform: uppercase;
}
.body-text { font-family: var(--font-body); font-size: 2cqw; font-weight: 400; color: var(--text-muted); line-height: 1.5; }
.disclaimer-text {
  font-family: var(--font-body);
  font-size: 1.9cqw;
  font-weight: 400;
  color: var(--text-muted);
  line-height: 1.4;
  text-align: center;
}
.disclaimer-text strong { font-weight: 800; color: var(--white); }
/* Disclaimer de Resultados: medido del artboard p14 (cap 26px = 3.3cqw) y
 * TODO en blanco (no el gris muteado del disclaimer genérico). */
.resultados-disclaimer .disclaimer-text { font-size: 2.7cqw; color: var(--white); line-height: 1.35; }
.accent-red { color: var(--red); }
.accent-sky { color: var(--sky); }
.accent-white { color: var(--white); }

/* Botones táctiles grandes — píldoras planas de color sólido, como en el PDF */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  border: none;
  border-radius: 999px;
  padding: 2.6cqh 4cqw;
  font-family: var(--font-body);
  font-size: 2.4cqw;
  font-weight: 800;
  cursor: pointer;
  color: var(--white);
  min-height: 64px;
  /* Como hijo flex de .screen/.center-col, sin esto el botón se ENCOGE de
   * alto cuando el contenido de arriba crece y su píldora se ve aplastada.
   * (Los .btn dentro de .btn-row llevan flex:1 con más especificidad, así que
   * esos no se ven afectados por este flex-shrink:0.) */
  flex-shrink: 0;
  transition: transform 120ms ease, filter 120ms ease;
  touch-action: manipulation;
}
.btn:active { transform: scale(0.97); filter: brightness(0.92); }
.btn-primary { background: var(--red); box-shadow: 0 12px 30px -10px rgba(248,0,64,0.55); }
.btn-accent { background: var(--blue-accent); box-shadow: 0 12px 30px -10px rgba(44,57,209,0.55); }
.btn-ghost { background: rgba(255,255,255,0.08); border: 1px solid var(--card-border); }
/* Botón oscuro (pantalla "Recomendaciones", rediseño según mockup del
 * cliente) — no pulsa como .btn-primary/.btn-accent a propósito: el ícono
 * animado arriba ya se encarga de llamar la atención, y un botón quieto
 * se siente más "call to action calmado" en vez de dos cosas moviéndose. */
.btn-navy { background: var(--navy-card); border: 2px solid rgba(255,255,255,0.25); }
/* Pulso ambiente continuo — el mismo del botón "Comenzar" original, ahora
 * en todos los botones principales del kiosco (llama la atención en cada
 * pantalla, no sólo en el splash). */
.btn-primary, .btn-accent { animation: pulse 4s infinite; }
@keyframes pulse {
  0% { transform: scale(1); }
  10% { transform: scale(1.1); }
  20% { transform: scale(1); }
}
.btn-block { width: 100%; }
.btn[disabled] { opacity: 0.4; pointer-events: none; }
.btn .arrow { font-size: 1.2em; line-height: 1; }

.btn-row { display: flex; gap: 3cqw; }
.btn-row .btn { flex: 1; }
/* "Iniciar medición" (Medición) — el texto se partía en dos líneas.
 * width:100% explícito acá porque .btn-block (mismo valor) no se estaba
 * aplicando bien en este contexto puntual (bug de cascada no resuelto del
 * todo, ver historial); nowrap fuerza que "Iniciar medición" quede en una
 * sola línea, como se pidió. */
#idle-actions { display: flex; justify-content: center; }
#idle-actions .btn { white-space: nowrap; width: 57.4cqw; min-height: 0; height: 5.5cqh; padding: 0 4cqw; font-weight: 400; }

/* Popup propio (reemplaza alert() nativo — ver showAlert() en ui.js) */
.kiosk-alert-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 10, 40, 0.78);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6cqw;
  z-index: 1000;
  /* Sin animación de entrada a propósito: para un aviso legal obligatorio no
     podemos arriesgarnos a que quede en opacity:0 si la animación no llega
     a correr (pestaña sin foco, etc.) — tiene que verse siempre, de una. */
  opacity: 1;
}
.kiosk-alert-box {
  background: var(--navy-card);
  border-radius: 24px;
  padding: 4cqh 4.5cqw;
  max-width: 640px;
  width: 100%;
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.kiosk-alert-title {
  font-family: var(--font-display);
  font-size: 2.4cqw;
  font-weight: 700;
  color: var(--white);
  margin-bottom: 1.4cqh;
  text-transform: uppercase;
}
.kiosk-alert-msg {
  font-family: var(--font-body);
  font-size: 1.7cqw;
  line-height: 1.55;
  color: var(--white);
  margin-bottom: 2.6cqh;
}
.kiosk-alert-box .btn { width: 100%; }

/* (El botón "Comenzar" del splash ahora lo maneja .splash-btn pixel-exacto —
 * se eliminó la vieja regla #btn-start que forzaba width:40% y le ganaba por
 * especificidad de ID, descuadrando la proporción del artboard.) */

/* Tarjetas / opciones */
.card {
  background: var(--navy-card);
  border: none;
  border-radius: 28px;
  padding: 3cqh;
  position: relative;
  overflow: hidden;
  /* Sin esto, una .card sin ancho explícito (p.ej. dentro de .center-col,
   * que usa align-items:center en vez de stretch) se dimensiona a
   * "fit-content": si su texto más largo pide más ancho del que hay
   * disponible, la tarjeta simplemente crece más allá del viewport en vez
   * de ajustar el texto — se vio en "Interpretando" con el texto grande.
   * max-width:100% la limita al espacio real del contenedor y fuerza el
   * ajuste de línea normal en vez de desbordar. */
  max-width: 100%;
}
.card .card-heart-bg {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 135%;
  max-width: none;
  opacity: 0.3;
  pointer-events: none;
  z-index: 0;
}
.card > * { position: relative; z-index: 1; }

.option-list { display: flex; flex-direction: column; gap: 1.6cqh; }
.option-list.row { flex-direction: row; flex-wrap: wrap; gap: 1.4cqh 1.4cqw; }
.option-list.compact { gap: 1.2cqh; }
.option-btn.compact { padding: 1.3cqh 4cqw; min-height: 0; height: 4.7cqh; font-size: 3.4cqw; }
.option-btn.chip { flex: 0 0 auto; padding: 1.8cqh 2.4cqw; min-height: 48px; }
.option-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  text-align: left;
  padding: 2.6cqh 3cqw;
  border-radius: 999px;
  border: 2px solid rgba(255,255,255,0.16);
  background: var(--navy-card);
  color: var(--white);
  font-family: var(--font-body);
  font-size: 2.4cqw;
  font-weight: 800;
  cursor: pointer;
  min-height: 72px;
  transition: border-color 150ms ease, background 150ms ease, transform 120ms ease;
}
.option-btn:active { transform: scale(0.98); }
.option-btn.selected {
  border-color: var(--red);
  background: var(--red);
}
.option-btn .check { display: none; }

/* Inputs — medidas tomadas directamente del PDF (fuente de verdad): la hoja
 * de Registro mide 1080×1920pt, el rectángulo real de cada campo (p.ej.
 * "NOMBRE COMPLETO") mide 596.4×49.4pt, centrado (márgenes de 241.8pt =
 * 22.4cqw a cada lado ⇒ 55.2cqw de ancho). Etiquetas a 20pt = 1.85cqw, texto de
 * campo a 23.4pt = 2.17cqw. */
.field { display: flex; flex-direction: column; gap: 0.18cqh; margin-bottom: 1.2cqh; }
.field label {
  /* Antes iba en MAYÚSCULAS por CSS (text-transform: uppercase) para
   * calzar con el artboard, con el HTML en frase normal debajo. A pedido
   * del cliente ahora se ve tal cual está escrito en el archivo (minúscula),
   * sin transformar el case acá. */
  font-family: var(--font-body);
  font-size: 1.8cqw;
  color: var(--white);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.field input, .field select {
  font-family: var(--font-body);
  /* Valor del campo ~2.6cqw (artboard), con piso de 16px para evitar el zoom
   * automático de Safari iOS al enfocar (sólo afecta pantallas angostas). */
  font-size: 2.6cqw;
  font-weight: 400;
  /* Alto del campo ~2.55cqh (artboard = 49px de 1920): padding vertical chico. */
  padding: 0.62cqh 1.9cqw;
  border-radius: 1.15cqw;
  border: 1px solid rgba(176, 217, 236, 0.18);
  background: var(--navy-card);
  color: var(--white);
  outline: none;
}
.field input:focus, .field select:focus { box-shadow: 0 0 0 2px var(--blue-accent); }
.field input::placeholder { color: var(--text-faint); }
.field select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.1cqw center;
  background-size: 1.6cqw;
  padding-right: 3.2cqw;
}
.field select option { background: var(--navy-card); color: var(--white); }
.checkbox-row { display: flex; align-items: flex-start; gap: 1em; }
.checkbox-row input { width: 1.6em; height: 1.6em; margin-top: 0.15em; flex-shrink: 0; }
.checkbox-row span { font-size: 1.8cqw; color: var(--text-muted); }

/* Corazón animado con ECG (slide 3 · Medición) — entregado por el diseñador
 * en corazonfinal/corazon_animado.html; las 4 imágenes embebidas se
 * extrajeron a assets/img/heart-anim/ para no inflar este CSS con base64
 * (~2.3MB) y permitir que el navegador las cachee como archivos normales. */
.heart-anim-escena {
  position: relative;
  /* max-width:100% además del 92cqw: "vw" siempre se mide contra
   * el viewport real del navegador, no contra la "tarjeta" 9:16 de #app —
   * en el modo tablet/iPad (ver @media min-aspect-ratio:9/16 más arriba),
   * la tarjeta puede ser más angosta que 92cqw/720px del viewport real, y
   * sin este tope el corazón se salía de la tarjeta hacia la derecha. */
  width: 50cqw;
  max-width: 100%;
  aspect-ratio: 2496 / 2772;
  margin: 0 auto;
  /* Sin transition en width a propósito: probado y confirmado que animar
   * width cuando el valor usa min(Ncqw, ...) se queda pegado (bug/rareza
   * de motor de render, verificado con getAnimations() — la transición
   * nunca avanzaba de localTime:0) y el achique en .result-shown no
   * llegaba a aplicarse nunca. Sin transición, el cambio es instantáneo
   * pero al menos funciona. */
}
/* El achique en .result-shown (ver @container de abajo) sólo cubría
 * celular/tablet — "nunca en el kiosco" decía el comentario original,
 * pero medido en el kiosco real (1080×1920) la tarjeta de ajuste de
 * SpO2/Pulso sí generaba ~111px de scroll ahí también (reportado por el
 * cliente: "bajando el zoom al 80% se auto-ajusta", señal clásica de que
 * el contenido es más alto de lo que cabe). Mismo criterio, sólo que con
 * un achique más suave (el kiosco tiene más margen que un celular). */
  /* Estado "resultado": la tarjeta de ajuste (SpO2/Pulso) aparece como OVERLAY
   * flotante sobre el corazón (sin encoger nada) → no suma altura ni genera
   * scroll. El corazón (opaco navy-card) la cubre; el corazón late detrás. */
  /* Tarjeta de ajuste pegada al fondo del stack (justo encima del botón), y el
   * texto "Lectura capturada..." (mismo tamaño 5cqw que "Estamos escuchando")
   * anclado justo ENCIMA de la tarjeta. Ambos absolute → no suman altura. */
  .medicion-stack.result-shown #adjust-card {
    position: absolute;
    bottom: 3.5cqh;
    left: 50%;
    transform: translateX(-50%);
    width: 86cqw;
    z-index: 5;
    box-shadow: 0 20px 50px -18px rgba(0,0,0,0.75);
  }
  .medicion-stack.result-shown #status-text {
    position: absolute;
    bottom: 24cqh;
    left: 0;
    right: 0;
    font-size: 5cqw;
    line-height: 1.15;
    text-align: center;
    margin: 0;
    z-index: 5;
  }
/* Un poco más chico sólo en celular/tablet (nunca en el kiosco, cuya
 * "tarjeta" nunca entra en este @container) — es el elemento que más
 * espacio vertical ocupa en "Medición". Primero se bajó a 78cqw (reportado
 * en iPad que hacía falta arrastrar), pero seguía haciendo falta bajar el
 * zoom del navegador al 80% para verse completo — bajado más, a 68cqw. */
.heart-anim-escena > *, .heart-anim-heart-group > * {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.heart-anim-ecg-base { opacity: .55; }
.heart-anim-ecg-glow {
  -webkit-mask: url('../img/heart-anim/ecg-glow-mask.png') center / contain no-repeat;
  mask: url('../img/heart-anim/ecg-glow-mask.png') center / contain no-repeat;
  background: linear-gradient(90deg,
      transparent 0%, rgba(150,225,255,0) 35%,
      rgba(150,225,255,.95) 50%,
      rgba(150,225,255,0) 65%, transparent 100%);
  background-size: 45% 100%;
  background-repeat: no-repeat;
  mix-blend-mode: screen;
  animation: heart-anim-barrido 3s linear infinite;
}
@keyframes heart-anim-barrido {
  0% { background-position: -50% 0; }
  100% { background-position: 150% 0; }
}
.heart-anim-heart-group {
  position: absolute; inset: 0;
  transform-origin: 51% 49%;
  /* Usa la misma --beat-duration que #rate-ring (ver setBeat() en
   * 03-medicion.js) — así el corazón late al ritmo real medido, no a un
   * ritmo genérico fijo. 1.2s es el valor de respaldo antes de que se
   * mida cualquier cosa (~50 ppm). */
  animation: heart-anim-latido var(--beat-duration, 1.2s) ease-in-out infinite;
  will-change: transform;
}
@keyframes heart-anim-latido {
  0%   { transform: scale(1.000); }
  12%  { transform: scale(1.045); }
  24%  { transform: scale(1.000); }
  34%  { transform: scale(1.024); }
  46%  { transform: scale(1.000); }
  100% { transform: scale(1.000); }
}
.heart-anim-corazon-base {
  filter: drop-shadow(0 0 10px rgba(80,120,255,.15));
}
.heart-anim-arterias-flow {
  -webkit-mask: url('../img/heart-anim/arterias-flow-mask.png') center / contain no-repeat;
  mask: url('../img/heart-anim/arterias-flow-mask.png') center / contain no-repeat;
  background: repeating-linear-gradient(175deg,
      rgba(255,0,40,0)      0px,
      rgba(255,0,40,0)     62px,
      rgba(255,25,55,1)    88px,
      rgba(230,0,40,.95)  108px,
      rgba(255,0,40,0)    132px);
  background-size: 100% 210px;
  mix-blend-mode: screen;
  filter: blur(1px);
  animation: heart-anim-flujo 1.8s linear infinite;
}
@keyframes heart-anim-flujo {
  from { background-position: 0 -210px; }
  to   { background-position: 0 0px; }
}
/* Pedido del cliente (pantalla "Medición"): el corazón debe entrar quieto
 * y sólo cobrar vida cuando el usuario toca "Iniciar medición" o "Simular
 * medición" — ver startHeartAnim()/.running en 03-medicion.js. Se aplica
 * sólo a la instancia marcada con .heart-anim-gated (la de Medición); el
 * corazón de "Signos vitales" no lleva esa clase y sigue animándose solo
 * como siempre. */
.heart-anim-gated:not(.running) .heart-anim-heart-group,
.heart-anim-gated:not(.running) .heart-anim-ecg-glow,
.heart-anim-gated:not(.running) .heart-anim-arterias-flow {
  animation-play-state: paused;
}

/* Barra roja inferior — antes contenía la imagen "53 años", ahora el texto
 * de pie de pantalla (ver footerNote() en ui.js) de portada, registro y
 * checkeo. Pegada abajo SIEMPRE, sin importar la resolución — se probaron
 * dos enfoques que fallaban en la práctica: (1) position:absolute puro se
 * podía montar encima de otro contenido si el contenido de arriba era
 * alto; (2) margin-top:auto (+ position:sticky) dejaba de funcionar en
 * cuanto el contenido de arriba necesitaba scroll (o directamente no se
 * comportaba igual en todos los navegadores). La solución robusta: el
 * contenido de arriba de cada pantalla va DENTRO de .screen-scroll (que
 * es la que hace scroll si hace falta — ver esa clase), y .badge-anos
 * queda como hermana DESPUÉS, con flex-shrink:0 — así nunca puede
 * "esconderse" arriba del fold ni superponerse: si algo tiene que ceder
 * espacio, cede el contenido de arriba (que scrollea internamente), nunca
 * la franja de abajo. */
.badge-anos {
  flex-shrink: 0;
  background: var(--red);
  border-radius: 28px 28px 0 0;
  /* Padding vertical en cqh (no vh) para que sea proporcional y no cambie con
   * el dispositivo; reducido para que la franja sea más delgada. */
  padding: 1.3cqh 6cqw calc(1.3cqh + var(--safe-bottom));
  /* Foot bar: llega hasta el borde inferior real del lienzo. .screen tiene
   * padding-bottom (4cqh + safe) que dejaba un hueco navy debajo de la franja.
   * Con position:relative + bottom negativo la bajamos hasta el borde SIN
   * alterar el flujo flex (así el botón de arriba no queda tapado, cosa que sí
   * pasaba con margin-bottom negativo). */
  position: relative;
  bottom: calc(-4cqh - var(--safe-bottom));
  text-align: center;
  z-index: 2;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Franja fucsia en TODAS las pantallas. Con texto: se ajusta al contenido con
 * poco padding (delgada). Vacía (.slim): una barra fina visible, más baja. */
.badge-anos.slim { min-height: 6cqh; }
/* Envoltorio para todo el contenido de una pantalla que termina en
 * .badge-anos (portada, registro, checkeo) — absorbe el scroll interno si
 * el contenido no cabe, dejando la banda roja siempre visible abajo.
 * min-height:0 es necesario: sin esto, un hijo flex:1 nunca se encoge por
 * debajo del tamaño de su contenido (el mínimo por defecto es "auto", no
 * 0), así que su overflow-y:auto nunca llegaría a activarse. */
.screen-scroll {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.badge-anos .disclaimer-text {
  /* Tamaño en cqw puro (sin clamp px) para que la proporción del texto sea
   * idéntica en cualquier dispositivo. Ancho acotado + text-wrap:balance para
   * que caiga en ~3 renglones de ancho parejo. */
  font-size: 2.8cqw;
  font-weight: 600;
  color: var(--white);
  line-height: 1.32;
  max-width: 58cqw;
  margin-inline: auto;
  text-wrap: balance;
}
.badge-anos .disclaimer-text strong { color: var(--white); }

/* Insignia ppm — arriba a la derecha de las tarjetas de cuestionario.
   Placa ancha con una foto recortada del corazón a la izquierda y el
   anillo con el número a la derecha (rediseño v2). */
.ppm-badge {
  position: absolute;
  top: -2cqh;
  right: 4cqw;
  width: 24cqw;
  height: 18cqw;
  background: var(--red);
  border-radius: 26px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  overflow: visible;
  box-shadow: 0 14px 30px -12px rgba(248,0,64,0.7);
  z-index: 3;
}
/* Colocación EXACTA del artboard 4 (rects del .ai): el asset corazón+ECG
 * (heart-ecg.png, extraído con su máscara alfa del Illustrator) va colocado
 * a offset −39%,−39% del badge con tamaño 117%×198%, y las esquinas del
 * badge lo recortan (overflow hidden). Así quedan visibles el corazón a la
 * izquierda Y los trazos tenues de ECG alrededor, como en el arte. */
.ppm-badge-heart-photo {
  position: absolute;
  left: -39.2%;
  top: -39.1%;
  width: 116.6%;
  height: 198%;
  max-width: none;
  object-fit: fill;
  pointer-events: none;
}
.ppm-badge .ring {
  position: relative;
  width: 11.5cqw;
  height: 11.5cqw;
  margin-right: 10%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
/* Gauge = anillo blanco ABIERTO en la parte baja (SVG arco), como el artboard;
 * el mini-corazón se ubica en esa apertura. */
.ppm-badge .ring-arc {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.ppm-badge .val {
  font-family: var(--font-display);
  font-size: 3.8cqw;
  font-weight: 600;
  color: var(--white);
  line-height: 1;
}
.ppm-badge .unit {
  font-family: var(--font-body);
  font-size: 1.2cqw;
  font-weight: 700;
  color: var(--white);
  margin-top: 0.15em;
}
.ppm-badge .mini-heart {
  position: absolute;
  bottom: -14%;
  left: 50%;
  transform: translateX(-50%);
  width: 34%;
  height: 34%;
  border-radius: 50%;
  background: var(--navy);
  display: flex; align-items: center; justify-content: center;
}
.ppm-badge .mini-heart svg { width: 58%; height: 58%; color: var(--white); }
/* Mini-corazón = el asset del logo subido por el cliente (corazon_lacardio.png:
 * círculo navy + corazón rojo con cola, idéntico al del artboard). */
.ppm-badge .mini-heart img { display: block; width: 100%; height: 100%; }
/* Badge de ppm "independiente" — usado en Interpretando y en las 7 pantallas
 * del Cuestionario (misma función renderCuestionario para todas). Cuadrado
 * redondeado (squircle) con reborde celeste, como en el PDF v4, con un
 * latido + glow expansivo para que se sienta "vivo". */
.ppm-badge.standalone {
  position: static;
  width: 24cqw;
  height: 24cqw;
  justify-content: center;
  margin: 0 auto 3cqh;
  border-radius: 32%;
  border: 2px solid var(--sky);
  animation: ppm-badge-beat 1.15s ease-in-out infinite, ppm-badge-glow 1.15s ease-in-out infinite;
}
.ppm-badge.standalone .ring {
  width: 15.5cqw;
  height: 15.5cqw;
  margin-right: 0;
}
.ppm-badge.standalone .ppm-badge-heart-photo { display: none; }
.ppm-badge.standalone .val { font-size: 5.6cqw; }
.ppm-badge.standalone .mini-heart svg { color: var(--red); }
.ppm-badge.standalone .mini-heart { animation: ppm-badge-heart-beat 1.15s ease-in-out infinite; }
/* Badge del Cuestionario (mockup nuevo n03): cuadro rojo CENTRADO, montado
 * sobre el borde superior de la tarjeta, SIN la foto del corazón a full color.
 * Sólo anillo abierto + "75 ppm" + mini-corazón. Medidas del mockup: caja
 * 251×285px (23×26cqw), anillo Ø 0.83 del ancho, mini-corazón centrado abajo. */
.ppm-badge.cuestionario-badge {
  position: absolute;
  top: 0.5cqh;
  left: 50%;
  transform: translateX(-50%);
  width: 23cqw;
  height: 26cqw;
  justify-content: center;
  border: 0.28cqw solid var(--sky);
  overflow: visible;
}
.ppm-badge.cuestionario-badge .ppm-badge-heart-photo { display: none; }
.ppm-badge.cuestionario-badge .ring { width: 19cqw; height: 19cqw; margin-right: 0; }
.ppm-badge.cuestionario-badge .val {
  position: absolute;
  left: 0; right: 0;
  top: 50%;
  transform: translateY(-50%);
  text-align: center;
  font-size: 8.5cqw;
}
.ppm-badge.cuestionario-badge .unit {
  position: absolute;
  left: 0; right: 0;
  top: calc(40% + 4.4cqw);
  text-align: center;
  margin-top: 0;
  font-size: 2.6cqw;
}
/* Mini-corazón centrado en la apertura inferior del anillo (cy 0.82 de la caja
 * del mockup). Va relativo a .ring, por eso el bottom negativo. */
.ppm-badge.cuestionario-badge .mini-heart { width: 24%; height: 24%; bottom: -14%; }
/* Pregunta del cuestionario: arranca por DEBAJO del borde inferior del badge
 * de ppm (así lo resuelve el artboard en las preguntas de varias líneas — el
 * badge invade la esquina de la tarjeta pero nunca tapa texto). El margen
 * sube el inicio del texto a y≈700px del lienzo (badge termina en ≈690). */
.cuestionario-pregunta {
  /* El badge compacto (25cqw) termina antes; la pregunta puede arrancar más
   * arriba sin quedar tapada. */
  margin-top: 1.8cqh;
  margin-bottom: 2.5cqh;
  /* Medido del arte: avance de línea ≈66px con tinta de ~55px → ≈5.6cqw
   * (el 6.6cqw anterior quedaba un ~18% más grande que el artboard). */
  font-size: 5.6cqw;
  line-height: 1.08;
}
/* Preguntas largas (texto original de la app, más extenso que el del arte):
 * tipografía algo menor para que la tarjeta no crezca hasta pisar el botón. */
.cuestionario-pregunta.pregunta-larga {
  font-size: 4.6cqw;
  line-height: 1.15;
}
@keyframes ppm-badge-beat {
  0%, 100% { transform: scale(1); }
  10% { transform: scale(1.07); }
  20% { transform: scale(1); }
  30% { transform: scale(1.045); }
  40% { transform: scale(1); }
}
@keyframes ppm-badge-glow {
  0%, 100% { box-shadow: 0 14px 30px -12px rgba(248,0,64,0.7), 0 0 0 0 rgba(248,0,64,0.45); }
  20% { box-shadow: 0 14px 30px -12px rgba(248,0,64,0.9), 0 0 0 16px rgba(248,0,64,0); }
  100% { box-shadow: 0 14px 30px -12px rgba(248,0,64,0.7), 0 0 0 0 rgba(248,0,64,0.45); }
}
@keyframes ppm-badge-heart-beat {
  0%, 100% { transform: translateX(-50%) scale(1); }
  15% { transform: translateX(-50%) scale(1.25); }
  30% { transform: translateX(-50%) scale(1); }
}

/* Badge de ppm como imagen (Cuestionario, ver ppmBadgeImage() en ui.js) —
 * mismo latido que .ppm-badge.standalone (ppm-badge-beat/glow) para que se
 * sienta igual de "vivo". margin-bottom negativo para que baje y quede
 * tocando/superpuesta a la tarjeta de la pregunta, como se pidió. */
.ppm-badge-image {
  display: block;
  width: 30cqw;
  position: absolute;
  top: 0;
  right: -1cqw;
  margin: 0;
  z-index: 3;
  border-radius: 32%;
  animation: ppm-badge-beat 1.15s ease-in-out infinite, ppm-badge-glow 1.15s ease-in-out infinite;
}

/* Stepper numérico grande (vitales manuales) */
.stepper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4cqw;
}
.stepper button {
  width: 8cqw;
  height: 8cqw;
  border-radius: 50%;
  border: 2px solid var(--card-border);
  background: rgba(255,255,255,0.08);
  color: var(--white);
  font-size: 4cqw;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.stepper button:active { transform: scale(0.92); }
.stepper .value { font-family: var(--font-display); min-width: 4ch; text-align: center; font-size: 8cqw; font-weight: 600; }
.stepper .unit { font-size: 2cqw; color: var(--text-muted); }

/* Los campos de SpO2/Pulso son <input> editables (el usuario puede tocarlos
 * y escribir el valor a mano, no solo usar los +/-) — se ven igual que el
 * texto de antes, con un subrayado sutil que aparece al enfocarlos. */
.stepper input.value {
  width: 2.2ch;
  background: transparent;
  border: none;
  border-bottom: 3px solid rgba(255,255,255,0.25);
  color: var(--white);
  outline: none;
  -moz-appearance: textfield;
  padding: 0 0.05em 0.05em;
}
.stepper input.value:focus { border-bottom-color: var(--blue-accent); }
.stepper input.value::-webkit-outer-spin-button,
.stepper input.value::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Utilidades de layout */
.center-col { display: flex; flex-direction: column; align-items: center; text-align: center; justify-content: center; gap: 2.4cqh; }
/* "Interpretando" (pantalla de análisis IA) es la única pantalla sin topBar()
 * ni ningún título propio arriba — su primer elemento (el badge de ppm)
 * vivía directo dentro de .center-col, que centra TODO el grupo
 * verticalmente. El texto "Somos → laCardio" de esta pantalla no es un
 * elemento real: viene horneado en el fondo (screen-bg.jpg, ver
 * screenBackground() en ui.js). Cuando el contenido total del grupo es
 * corto (p.ej. con el texto grande recortado para que quepa en celular),
 * el centrado empuja el badge hacia arriba y termina superpuesto encima de
 * ese texto horneado — verificado con captura de pantalla real. Se ancla
 * arriba en vez de centrar el grupo, igual que hacen "Signos vitales" y
 * "Resultados" (que sí libran ese texto de forma confiable). */
/* Los 20cqh (y un calc(20cqh + 5cm) huérfano de un @container ya eliminado,
 * que seguía aplicando SIEMPRE y bajaba todo ~570px generando scroll) eran
 * para esquivar un "Somos → laCardio" horneado en el fondo viejo. Con el
 * fondo limpio y el lockup vivo del topBar ya no hay nada que esquivar:
 * ancla arriba con un aire pequeño. */
.interpretando-stage {
  justify-content: flex-start;
  padding-top: 2cqh;
}
.medicion-stack { gap: 0.6cqh; position: relative; }
/* "Estamos escuchando a tu corazón..." — mensaje grande del artboard 3
 * (medido: cap ~4cqw → font ~5cqw), no el .body-text chico (2cqw). */
#status-text {
  font-size: 5cqw;
  color: var(--white);
  font-weight: 400;
  line-height: 1.2;
  margin-top: 1.5cqh;
}
#adjust-card { padding: 2cqh; border: 2px solid var(--white); }
#adjust-card .stepper { margin-top: 0.4cqh !important; }
/* Botón ESTÁNDAR del kiosco (el artboard usa el mismo botón en todas las
 * pantallas, sólo cambia el color): 57.4cqw × 5.5cqh, texto centrado 4.2cqw
 * peso 300 y flecha vectorial (línea+chevrón) suelta hacia el borde derecho
 * — misma geometría que el "Comenzar" del splash (.splash-btn). Colores:
 * .btn-primary (rojo CTA) / .btn-accent (azul #2c39d1 = el del artboard). */
.btn-std {
  position: relative;
  width: 57.4cqw;
  margin-left: auto;
  margin-right: auto;
  padding: 0 4cqw;
  font-size: 4.2cqw;
  font-weight: 300;
  min-height: 0;
  height: 5.5cqh;
}
.btn-std .btn-vector-arrow {
  position: absolute;
  right: 3.98cqw;
  top: 50%;
  transform: translateY(-50%);
  width: 4.72cqw;
  height: auto;
  color: var(--white);
}
.grow { flex: 1; display: flex; flex-direction: column; }

/* Imagen real del corazón anatómico extraída del PDF */
.heart-illustration-bg {
  position: absolute;
  pointer-events: none;
  z-index: 0;
  opacity: 0.95;
}

/* Fondo de pantalla completa (JPG entregado por el diseñador) — reemplaza la
 * composición manual de corazón + anillos con opacidad/posición ajustada a
 * mano. background-size:cover lo hace responsivo: cubre toda la pantalla y
 * recorta lo que sobre, sin estirar ni distorsionar, sea cual sea el tamaño
 * real del archivo. */
.screen-bg-image {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  z-index: 0;
  pointer-events: none;
}

/* Tarjeta oscura redondeada detrás del corazón (pantalla "Signos vitales") */
.heart-card {
  position: relative;
  width: 46cqw;
  height: 46cqw;
  background: var(--navy-card);
  border-radius: 32px;
  margin: 0 auto;
}
.heart-card .heart-illustration-bg {
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 82%;
}
/* Versión "espectacular" con el corazón animado (late + ECG + flujo de
 * sangre) en vez de la imagen estática — tarjeta más grande, con un halo
 * rojo que respira detrás, sincronizado más o menos con el latido. */
.heart-card-anim {
  width: 56cqw;
  height: 56cqw;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--sky);
  animation: heart-card-halo 1.15s ease-in-out infinite;
}
@keyframes heart-card-halo {
  0%, 100% { box-shadow: 0 0 0 0 rgba(248,0,64,0.55), 0 20px 50px -20px rgba(0,0,0,0.6); }
  20% { box-shadow: 0 0 0 26px rgba(248,0,64,0), 0 20px 50px -20px rgba(0,0,0,0.6); }
}

/* Ícono circular con borde azul (pantalla Registro). Tamaño en cqw puro
 * (artboard: 180px = 16.6cqw) → misma proporción en todo dispositivo. */
.icon-circle {
  width: 16.6cqw;
  height: 16.6cqw;
  border-radius: 50%;
  border: 0.23cqw solid var(--blue-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.icon-circle svg { width: 52%; height: 52%; color: var(--white); }

/* transform (no margin) a propósito: sólo usada acá (Registro) — sube el
 * encabezado un poco sin afectar el flujo/alto del resto de campos (que
 * ya está muy ajustado contra el scroll, ver .registro-form-wrap). */
.header-with-icon { display: flex; align-items: flex-start; gap: 3cqw; margin-bottom: 2.5cqh; }
/* Título "Registro" y subtítulo en cqw puro (artboard: 4.8cqw / 3.1cqw) para
 * que el bloque tenga la misma proporción en cualquier dispositivo. */
.header-with-icon .title-lg { font-size: 4.8cqw; line-height: 1.1; }
.header-with-icon .body-text { font-size: 3.1cqw; line-height: 1.3; }
/* Registro sigue necesitando más compactación — reportado que hacía falta
 * bajar el zoom del navegador al 80% para ver todo. El kiosco nunca entra
 * en este @container (su "tarjeta" siempre es ≥1080px), sigue exactamente
 * igual. */

/* Espacio sobre el formulario de Registro y sobre las filas de Heart Score
 * en Resultados — valor original del kiosco (calibrado contra el PDF) acá;
 * el recorte para que quepa en celular/tablet sin scroll de más vive sólo
 * en el @container de más abajo, así el kiosco no cambia. Usa @container
 * (no @media): en iPad la "tarjeta" es más angosta que el dispositivo real
 * (ver .fingerprint-frame para la explicación completa de por qué). */
/* justify-content:center reparte el espacio libre que sobra dentro del
 * wrap (es flex:1 vía .grow) arriba Y abajo de los campos, en vez de
 * dejarlo todo amontonado debajo del checkbox (que es lo que pasaba con
 * el flex-start por defecto — se veía un hueco raro entre el checkbox y
 * el botón "Siguiente", como si el botón hubiera quedado "pegado" a la
 * banda roja). Con esto los campos bajan usando ese espacio ya existente,
 * sin pedir más alto real — no debería generar scroll nuevo. */
/* flex:0 0 auto (no grow): el form-wrap se dimensiona por su contenido y
 * .screen-scroll hace scroll si no cabe, en vez de que el contenido rebase el
 * espacio flex y se encime con el botón "Siguiente" de abajo. */
.registro-form-wrap { margin-top: 2cqh; justify-content: flex-start; flex: 0 0 auto; }
/* Medido del artboard p14: las 4 cajas ocupan y630–1385 del lienzo, apiladas
 * con ~17px de aire (0.9cqh) — el margin-top 11.5cqh anterior + 6.6cqh entre
 * cajas empujaban todo fuera del lienzo y generaban scroll. */
.resultados-scores-wrap { margin-top: 0.4cqh; }
/* (El tamaño/tipografía del botón de Registro ahora lo da .btn-std — acá
 * sólo queda su separación propia respecto de la banda roja.) */
.registro-btn-next { margin-bottom: 3.5cqh; }

/* Tarjeta clara sobre fondo navy (pantalla Recomendaciones) */
.card-light {
  background: var(--white);
  color: var(--navy-deep);
  border-radius: 28px;
  padding: 3cqh;
  display: flex;
  align-items: flex-start;
  gap: 2.6cqw;
}
.card-light .icon-slot { width: 9cqw; flex-shrink: 0; }
.card-light .msg { font-family: var(--font-body); font-size: 2.2cqw; font-weight: 700; line-height: 1.35; }
.card-light .msg .navy { color: var(--navy-deep); }
.card-light .msg .blue { color: var(--blue-accent); }
.card-light .msg .red { color: var(--red); }
.card-light.form-card { flex-direction: column; }
.card-light.form-card .title-lg { color: var(--navy-deep); }
.card-light.form-card .body-text { color: var(--navy-mid); font-weight: 500; }
.field-light { display: flex; align-items: center; gap: 0.6em; padding: 1.6cqh 0; border-bottom: 2px solid rgba(0,40,117,0.18); }
.field-light label { font-family: var(--font-body); font-weight: 800; color: var(--navy-deep); font-size: 1.9cqw; white-space: nowrap; }
.field-light input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.9cqw;
  color: var(--navy-deep);
}
.field-light input::placeholder { color: rgba(0,40,117,0.4); }
.checkbox-row-light { display: flex; align-items: flex-start; gap: 0.8em; margin-top: 2cqh; }
.checkbox-row-light input { width: 1.4em; height: 1.4em; margin-top: 0.15em; flex-shrink: 0; accent-color: var(--navy-deep); }
.checkbox-row-light span { font-family: var(--font-body); font-size: 1.7cqw; color: var(--navy-deep); font-weight: 500; }

/* ===================================================================
   Pantalla 3 — Medición: corazón futurista latiendo + ECG + anillos
   =================================================================== */
.heart-stage {
  position: relative;
  width: 42cqw;
  height: 42cqw;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
}

.heart-rings-pulse {
  position: absolute;
  inset: 0;
  border-radius: 50%;
}
.heart-rings-pulse span {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid rgba(255, 27, 71, 0.55);
  animation: ring-pulse var(--beat-duration, 900ms) cubic-bezier(.2,.8,.3,1) infinite;
  opacity: 0;
}
.heart-rings-pulse span:nth-child(2) { animation-delay: calc(var(--beat-duration, 900ms) * 0.33); }
.heart-rings-pulse span:nth-child(3) { animation-delay: calc(var(--beat-duration, 900ms) * 0.66); }

@keyframes ring-pulse {
  0% { transform: scale(0.55); opacity: 0.9; border-color: var(--red); }
  70% { opacity: 0.25; }
  100% { transform: scale(1.35); opacity: 0; border-color: var(--sky); }
}

.heart-core {
  position: relative;
  width: 46%;
  height: 46%;
  filter: drop-shadow(0 0 18px rgba(255, 27, 71, 0.75)) drop-shadow(0 0 42px rgba(78, 79, 245, 0.45));
  animation: heartbeat var(--beat-duration, 900ms) ease-in-out infinite;
  z-index: 2;
}
.heart-core svg { width: 100%; height: 100%; }

@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  18% { transform: scale(1.16); }
  32% { transform: scale(0.96); }
  45% { transform: scale(1.08); }
  60% { transform: scale(1); }
}

.heart-sparkles {
  position: absolute;
  inset: -10%;
  z-index: 1;
  pointer-events: none;
}
.heart-sparkles i {
  position: absolute;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: var(--sky);
  opacity: 0;
  animation: sparkle-twinkle 2.4s ease-in-out infinite;
  box-shadow: 0 0 6px 1px rgba(174, 219, 242, 0.9);
}
@keyframes sparkle-twinkle {
  0%, 100% { opacity: 0; transform: scale(0.5); }
  50% { opacity: 1; transform: scale(1.4); }
}

.ecg-strip {
  width: 100%;
  height: 9cqh;
  margin: 1cqh 0;
  overflow: hidden;
}
.ecg-strip svg { width: 100%; height: 100%; overflow: visible; }
.ecg-strip .ecg-scroll {
  animation: ecg-scroll 2400ms linear infinite;
}
.ecg-strip path {
  fill: none;
  stroke: var(--sky);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 6px rgba(174, 219, 242, 0.7));
}
@keyframes ecg-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-1400px); }
}

/* Icono de huella dactilar dentro de marco de esquinas (pantalla "Frecuencia Cardiaca") */
.fingerprint-frame {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  text-align: left;
  gap: 3cqw;
  /* Valor original del kiosco (calibrado contra el PDF) — el recorte para
   * que quepa en celular/iPad sin tanto scroll vive sólo en el @container
   * de más abajo, así el kiosco (que nunca entra en esa condición, su
   * "tarjeta" siempre es ancha) no cambia. */
  margin-top: 4cqh;
  margin-bottom: 2.7cqh;
}
.fingerprint-icon-wrap {
  position: relative;
  width: 16cqw;
  height: 16cqw;
  flex-shrink: 0;
  overflow: hidden;
  border-radius: 12px;
}
.fingerprint-icon-img { display: block; width: 100%; height: 100%; object-fit: contain; }
/* Franja de luz que barre la huella de arriba a abajo en loop, como si la
 * estuviera leyendo en ese momento — pedido explícito del cliente. */
.fingerprint-scan-line {
  position: absolute;
  left: 10%;
  right: 10%;
  height: 3px;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, var(--sky) 40%, var(--white) 50%, var(--sky) 60%, transparent);
  box-shadow: 0 0 10px 2px rgba(174,219,242,0.85);
  animation: fingerprint-scan 2.2s ease-in-out infinite;
}
@keyframes fingerprint-scan {
  0% { top: 14%; opacity: 0; }
  12% { opacity: 1; }
  50% { top: 86%; opacity: 1; }
  88% { opacity: 1; }
  100% { top: 86%; opacity: 0; }
}
/* En fila, este encabezado (ícono + "Frecuencia Cardiaca..." + instrucción)
 * necesita más ancho del que tiene cualquier celular real — se salía de la
 * pantalla ~30-60px por ambos lados, verificado de 320 a 430px de ancho
 * (hasta el iPhone Pro Max más grande).
 * Primer intento: apilar ícono arriba y texto abajo (columna) — evitaba el
 * desborde horizontal pero hacía la sección bastante más alta (~130px más),
 * empeorando el scroll que ya sobraba en esta pantalla. En vez de apilar,
 * se achica el ícono y se deja que el texto haga salto de línea normal
 * (white-space: normal en vez de nowrap) DENTRO de la misma fila — mucho
 * más compacto en alto y ya no se desborda a los lados. */
.fingerprint-frame .title-md { font-size: 4.2cqw; color: var(--white); }
.fingerprint-frame .body-text { font-size: 2.6cqw; color: var(--white); white-space: nowrap; }
/* IMPORTANTE: este bloque va DESPUÉS de las reglas base de arriba a
 * propósito — con la misma especificidad, en CSS gana la que aparece
 * último en el archivo, así que si este @media quedara antes (como pasó
 * la primera vez, bug real ya corregido), las reglas base lo pisarían y
 * el achique nunca se aplicaría en celular.
 * Usa @container (no @media): un iPad en modo tarjeta tiene una "tarjeta"
 * de ~640-770px de ancho aunque el dispositivo real mida 820-1370px — con
 * @media eso nunca se consideraba "angosto" y el margen completo del
 * kiosco (hasta 170px) se quedaba, sumando al scroll de esta pantalla
 * (reportado en iPad: "toca arrastrar hacia abajo para ver la pantalla
 * completa"). @container mide el ancho real de la tarjeta, no el del
 * dispositivo. El umbral es 900px (no 600px) a propósito: tiene que cubrir
 * hasta la tarjeta más ancha entre los iPads (iPad Pro 12.9" ≈ 768px) y
 * seguir quedando muy por debajo del kiosco real (nunca se encajona,
 * siempre ≥1080px de ancho), para no tocarlo. */

/* Anillo de frecuencia cardiaca con número + ppm + burbuja de corazón (pantalla 3) */
/* Badge ppm de Medición: cuadro rojo redondeado con gauge celeste dentro,
 * posicionado absoluto arriba-derecha sobre el corazón (como el artboard 3).
 * Antes era un círculo con reborde celeste centrado abajo. */
.rate-ring {
  position: absolute;
  top: 6cqh;
  right: 4cqw;
  width: 24cqw;
  height: 24cqw;
  background: var(--red);
  border-radius: 4.5cqw;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 14px 30px -12px rgba(248,0,64,0.7);
  z-index: 3;
}
.rate-ring-gauge {
  width: 74%;
  height: 74%;
  border-radius: 50%;
  border: 0.5cqw solid var(--sky);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.rate-ring .num {
  font-family: var(--font-display);
  font-size: 7cqw;
  font-weight: 600;
  line-height: 1;
  color: var(--white);
}
.rate-ring .unit {
  font-family: var(--font-body);
  font-size: 2.4cqw;
  font-weight: 800;
  color: var(--white);
  margin-top: -0.1em;
}
.rate-ring .mini-heart {
  position: absolute;
  bottom: -1.8cqw;
  left: 50%;
  transform: translateX(-50%);
  width: 6cqw;
  height: 6cqw;
  border-radius: 50%;
  background: var(--blue-accent);
  display: flex; align-items: center; justify-content: center;
}
.rate-ring .mini-heart svg { width: 55%; height: 55%; color: var(--white); }
.rate-ring.beating { animation: ring-tick var(--beat-duration, 900ms) ease-in-out infinite; }
@keyframes ring-tick {
  0%, 100% { transform: scale(1); }
  20% { transform: scale(1.035); }
  40% { transform: scale(0.995); }
}
/* Más compacto en celular/tablet — mismo criterio que el resto de
 * "Medición" (el kiosco nunca entra en este @container). */

.reading-value {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 0.25em;
}
.reading-value .num { font-family: var(--font-display); font-size: 9cqw; font-weight: 600; }
.reading-value .unit { font-size: 2.4cqw; color: var(--text-muted); font-weight: 700; }
.reading-grid { display: flex; gap: 6cqw; justify-content: center; }
.reading-grid .reading-item { text-align: center; }
.reading-grid .reading-label { font-size: 1.6cqw; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.06em; }
/* La tarjeta de ajuste de SpO2/Pulso (aparece recién al terminar de medir)
 * añade bastante alto de golpe — reportado que, al mostrar la lectura,
 * "Medición" pasaba de caber perfecto a necesitar scroll (~157px medidos).
 * Más compacta sólo en celular/tablet. */

/* ===================================================================
   Pantalla 13 — Interpretando: panel de IA, halo neuronal en movimiento
   =================================================================== */
.ai-orb-stage {
  position: relative;
  width: 34cqw;
  height: 34cqw;
  margin: 0 auto;
}
.ai-orb-core {
  position: absolute;
  inset: 18%;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, rgba(174,219,242,0.9), rgba(78,79,245,0.55) 45%, rgba(255,27,71,0.35) 75%, transparent 100%);
  filter: blur(0.5px);
  animation: orb-breathe 3.2s ease-in-out infinite;
  box-shadow: 0 0 60px 10px rgba(78,79,245,0.45);
}
@keyframes orb-breathe {
  0%, 100% { transform: scale(1); filter: brightness(1) blur(0.5px); }
  50% { transform: scale(1.08); filter: brightness(1.25) blur(1px); }
}
.ai-orb-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1.5px dashed rgba(174, 219, 242, 0.5);
  animation: orb-spin 9s linear infinite;
}
.ai-orb-ring.reverse { inset: 8%; border-color: rgba(255,27,71,0.45); animation-duration: 6s; animation-direction: reverse; }
.ai-orb-ring.outer { inset: -10%; border-style: solid; border-color: rgba(255,255,255,0.12); animation-duration: 14s; }
@keyframes orb-spin { to { transform: rotate(360deg); } }

.ai-orb-particles span {
  position: absolute;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--white);
  top: 50%; left: 50%;
  box-shadow: 0 0 8px 2px rgba(174,219,242,0.8);
  animation: orbit-particle 4.5s linear infinite;
}
@keyframes orbit-particle {
  from { transform: rotate(0deg) translateX(var(--orbit-r, 130px)) rotate(0deg); opacity: 0.9; }
  to { transform: rotate(360deg) translateX(var(--orbit-r, 130px)) rotate(-360deg); opacity: 0.9; }
}

.ai-status-text {
  min-height: 1.6em;
  font-family: var(--font-body);
  font-size: 2cqw;
  color: var(--sky);
  font-weight: 700;
}
.ai-status-text::after {
  content: '';
  display: inline-block;
  width: 0;
  animation: dots-cycle 1.4s steps(4) infinite;
}
@keyframes dots-cycle {
  0% { content: ''; }
}

.thinking-strip {
  display: flex;
  gap: 6px;
  justify-content: center;
  margin-top: 1cqh;
}
.thinking-strip span {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--sky);
  animation: think-bounce 1.2s ease-in-out infinite;
}
.thinking-strip span:nth-child(2) { animation-delay: 0.15s; }
.thinking-strip span:nth-child(3) { animation-delay: 0.3s; }
@keyframes think-bounce {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.5; }
  40% { transform: translateY(-10px); opacity: 1; }
}

.floating-tag {
  position: absolute;
  padding: 0.9em 1.5em;
  border-radius: 999px;
  border: 2px solid var(--white);
  background: transparent;
  color: var(--white);
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 2.1cqw;
  white-space: nowrap;
  opacity: 0;
  animation: tag-in 600ms ease forwards, tag-cardiac 1.2s ease-in-out infinite, tag-drift 5.5s ease-in-out infinite;
}
.floating-tag.emphasis { background: var(--navy-card); font-size: 2.6cqw; }
/* Deriva lenta y orgánica — se suma al latido sin pelearle la propiedad
 * `transform` (usa margin, no transform), así cada etiqueta "flota" a la
 * deriva ademas de latir. Cada tag arranca en un punto distinto del ciclo
 * gracias al mismo animationDelay escalonado que ya trae desde JS. */
@keyframes tag-drift {
  0%, 100% { margin-left: 0; margin-top: 0; }
  25% { margin-left: 10px; margin-top: -10px; }
  50% { margin-left: -8px; margin-top: 6px; }
  75% { margin-left: 8px; margin-top: 9px; }
}
@keyframes tag-in {
  from { opacity: 0; transform: translateY(10px) scale(0.9); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
/* "Actividad cardíaca" — cada etiqueta late (lub-dub) con brillo rojo y
 * sombra que se expande, como si el corazón del centro les mandara el pulso.
 * El animationDelay escalonado (puesto desde JS) hace que la ola se sienta
 * como si viajara de una etiqueta a otra, no todas al tiempo. */
@keyframes tag-cardiac {
  0% { transform: scale(1) translateY(0); border-color: var(--white); box-shadow: 0 0 0 0 rgba(248,0,64,0); }
  10% { transform: scale(1.16) translateY(-4px); border-color: var(--red); box-shadow: 0 0 20px 4px rgba(248,0,64,0.75); }
  20% { transform: scale(1) translateY(0); border-color: var(--white); box-shadow: 0 0 0 0 rgba(248,0,64,0); }
  30% { transform: scale(1.09) translateY(-2px); border-color: var(--red); box-shadow: 0 0 14px 2px rgba(248,0,64,0.55); }
  40% { transform: scale(1) translateY(0); border-color: var(--white); box-shadow: 0 0 0 0 rgba(248,0,64,0); }
  100% { transform: scale(1) translateY(0); border-color: var(--white); box-shadow: 0 0 0 0 rgba(248,0,64,0); }
}

/* Heart Score result icons — ahora son imágenes reales (círculo rojo +
 * reborde celeste + ícono ya vienen en el PNG), ver assets/img/score-icons/. */
.score-badge {
  width: 11.4cqw;
  height: 11.4cqw;
  border-radius: 50%;
  flex-shrink: 0;
  display: block;
  animation: score-badge-beat 1.3s ease-in-out infinite;
}
/* Late con glow rojo — igual espíritu que el badge de ppm y las etiquetas
 * flotantes de Signos vitales, para que se sienta "vivo" en toda la app. */
@keyframes score-badge-beat {
  0%, 100% { transform: scale(1); box-shadow: 0 10px 22px -10px rgba(0,0,0,0.6); }
  10% { transform: scale(1.16); box-shadow: 0 10px 22px -10px rgba(0,0,0,0.6), 0 0 20px 4px rgba(248,0,64,0.75); }
  20% { transform: scale(1); box-shadow: 0 10px 22px -10px rgba(0,0,0,0.6); }
  30% { transform: scale(1.08); box-shadow: 0 10px 22px -10px rgba(0,0,0,0.6), 0 0 14px 2px rgba(248,0,64,0.55); }
  40% { transform: scale(1); box-shadow: 0 10px 22px -10px rgba(0,0,0,0.6); }
}
/* La fila activa (el resultado real) late más fuerte y con glow blanco —
 * para que resalte sobre su propio fondo rojo sólido. */
.score-item.active .score-badge { animation: score-badge-beat-active 1.3s ease-in-out infinite; }
@keyframes score-badge-beat-active {
  0%, 100% { transform: scale(1); box-shadow: 0 10px 22px -10px rgba(0,0,0,0.6); }
  10% { transform: scale(1.24); box-shadow: 0 10px 22px -10px rgba(0,0,0,0.6), 0 0 28px 6px rgba(255,255,255,0.85); }
  20% { transform: scale(1); box-shadow: 0 10px 22px -10px rgba(0,0,0,0.6); }
  30% { transform: scale(1.12); box-shadow: 0 10px 22px -10px rgba(0,0,0,0.6), 0 0 18px 3px rgba(255,255,255,0.6); }
  40% { transform: scale(1); box-shadow: 0 10px 22px -10px rgba(0,0,0,0.6); }
}
/* Vuelta a íconos y cajas SEPARADOS (sin superposición) — el fondo nuevo
 * (resultados-heart-score-bg.jpg) ya trae su propio panel oscuro dibujado
 * en la imagen, así que .score-row no necesita fingir uno propio "de más";
 * el ícono va afuera, con espacio real (gap), no encima del borde. Cada
 * fila sigue siendo su propia caja con fondo, y hay más separación vertical
 * entre una fila y la siguiente que antes. Todo el grupo sangra a la
 * derecha y va corrido un poco más a la derecha que el resto del contenido. */
.resultados-scores-wrap { margin-left: 12.7cqw; margin-right: -6cqw; }
.score-item {
  display: flex;
  align-items: center;
  gap: 3.5cqw;
  margin-bottom: 0.9cqh;
}
.score-item:last-child { margin-bottom: 0; }
.score-row {
  flex: 1;
  background: var(--navy-card);
  border: 2px solid var(--white);
  /* Como el artboard p14: la caja sangra hasta el borde derecho del lienzo
   * (el wrap trae margin-right:-6cqw = anula el padding de .screen) con las
   * esquinas DERECHAS rectas — sólo se redondean las izquierdas. Antes tenía
   * radio en las 4 y sobre-sangraba, dejando la esquina redonda cortada fuera
   * de pantalla (se veía "roto de golpe"). Radio izq medido: ~24px = 2.4cqw. */
  border-radius: 2.4cqw 0 0 2.4cqw;
  border-right: none;
  padding: 1.5cqh 5cqw;
}
/* Tamaños medidos del artboard (cap-height ÷0.72): título 40px = 3.6cqw,
 * descripción 33px = 3cqw. Antes 3cqw/2.1cqw se veían chicos. */
.score-row .title-md { color: var(--sky); margin-bottom: 0.35em; font-size: 3.6cqw; }
.score-row .body-text { color: var(--white); font-size: 3cqw; line-height: 1.25; }
.score-item.active .score-row { background: var(--red); }
.score-item.active .title-md,
.score-item.active .body-text { color: var(--white); }
/* Más compactas en celular/tablet (el kiosco nunca entra en este
 * @container, sigue igual). */

@media (prefers-reduced-motion: reduce) {
  .screen, .screen.screen-leaving { animation: none !important; opacity: 1 !important; transform: none !important; }
  .heart-core, .rate-ring.beating, .heart-rings-pulse span, .ecg-strip path, .ai-orb-core, .ai-orb-ring, .ai-orb-particles span, .thinking-strip span {
    animation-duration: 3s !important;
  }
}

/* ===================================================================
   Aviso "gira tu dispositivo" — el diseño es 100% vertical (ver comentario
   de .title-xl: calibrado pixel a pixel contra un PDF de proporción exacta
   9:16). En horizontal, la tarjeta de #app (ver @media min-aspect-ratio:9/16
   más arriba) puede quedar muy angosta — en un celular acostado llega a
   medir apenas ~220px de ancho real — y como el resto del CSS usa `vw`
   (que siempre se mide contra el viewport real, no contra esa tarjeta),
   todo se ve sobredimensionado y desbordado dentro de ella. En vez de
   rediseñar cada pantalla para horizontal (un proyecto aparte), pedimos
   que giren el dispositivo. Sólo se activa en pantallas TÁCTILES en
   horizontal (hover:none + pointer:coarse = celulares/tablets reales) para
   no interferir con una ventana de PC/laptop angosta, que sigue mostrando
   la tarjeta centrada de siempre.
   =================================================================== */
.rotate-prompt {
  display: none;
}
@media (orientation: landscape) and (hover: none) and (pointer: coarse) {
  #app, #screen-root { display: none; }
  .rotate-prompt {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2vh;
    position: fixed;
    inset: 0;
    background: var(--navy);
    color: var(--white);
    text-align: center;
    padding: 6vh 10cqw;
    z-index: 2000;
  }
  .rotate-prompt svg {
    width: clamp(56px, 12vh, 96px);
    height: clamp(56px, 12vh, 96px);
    color: var(--sky);
    animation: lacardio-logo-beat 1.6s ease-in-out infinite;
  }
  .rotate-prompt-title {
    font-family: var(--font-display);
    font-size: clamp(20px, 4vh, 30px);
    font-weight: 700;
    text-transform: uppercase;
  }
  .rotate-prompt-text {
    font-family: var(--font-body);
    font-size: clamp(15px, 2.4vh, 19px);
    color: var(--text-muted);
    max-width: 46ch;
  }
}

/* ===================================================================
   Pantalla "Checkeo" (16-checkeo.js, antes "Recomendaciones") — cierre/CTA
   del flujo: logo, dos líneas de texto, ícono de calendario+corazón
   animado, botón "Agenda tu chequeo" y banda roja (.badge-anos) al pie.
   La lista de recomendaciones de la IA que antes vivía acá se movió a
   15-resultado-ia.js, junto con el resumen (que antes vivía en Resultados).
   =================================================================== */
/* Pantalla "Recomendaciones" (artboard p15) ==========================
 * Título grande celeste + tarjeta TRANSLÚCIDA con los tips (texto blanco) +
 * tarjeta blanca con ícono calendario y el CTA de 3 colores + botón rojo.
 * Medidas del arte: título cap 50px (6.4cqw); tarjeta de tips x194–868
 * (62cqw, centrada) con bullets ~3.2cqw; tarjeta blanca y657–1329. */
.reco-title {
  text-align: center;
  color: #B0D9EC;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 6.4cqw;
  letter-spacing: 0.01em;
  margin: 3cqh 0 3.2cqh;
}
/* Tarjeta translúcida (mockup n12) con scroll interno cuando la IA devuelve
 * muchas recomendaciones. Dos capas:
 *   .reco-panel  = frame translúcido FIJO (no scrollea) — el "contenedor" que
 *                  se ve; empieza a 12cqw de la izquierda del .reco-outer para
 *                  dejar sitio a los corazones que lo montan por la izquierda.
 *   .reco-scroll = la lista, superpuesta (inset:0), que hace overflow-y:auto.
 * Los corazones sangran hacia la izquierda del panel PERO siguen dentro de la
 * caja de scroll (a >0 de su borde), así que no se recortan. El botón
 * "Siguiente" queda siempre visible porque el frame es flex:1 min-height:0 y
 * cede su alto en vez de empujar. */
.reco-grow { min-height: 0; }
.reco-title { flex-shrink: 0; }
.reco-outer {
  position: relative;
  flex: 1;
  min-height: 0;
  margin: 0 1cqw 3cqh 1cqw;
}
.reco-panel {
  position: absolute;
  top: 0; bottom: 0; right: 0; left: 12cqw;
  background: rgba(255,255,255,0.05);
  border: 1.5px solid rgba(255,255,255,0.3);
  border-radius: 26px;
  pointer-events: none;
}
.reco-scroll {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 3.2cqh 3cqw 3.2cqh 18cqw;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.4) transparent;
}
.reco-scroll::-webkit-scrollbar { width: 1.4cqw; }
.reco-scroll::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.38); border-radius: 999px; }
.reco-scroll::-webkit-scrollbar-track { background: transparent; }
.reco-scroll ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 2.6cqh; }
.reco-scroll li {
  position: relative;
  font-family: var(--font-body);
  font-size: 3.7cqw;
  font-weight: 400;
  color: var(--white);
  line-height: 1.25;
  min-height: 8.5cqw;
  display: flex;
  align-items: center;
}
.reco-scroll li .reco-bullet { flex: 1; }
.reco-scroll li .reco-bullet::before { content: "\00B7\00A0"; }
/* Corazón montado en el borde izquierdo del panel (a ~7cqw del borde de la
 * caja de scroll → nunca se recorta), centrado con el bullet. */
.reco-scroll .reco-heart {
  position: absolute;
  left: -11cqw;
  top: 50%;
  transform: translateY(-50%);
  width: 10.3cqw;
  height: auto;
}
/* Indicador "hay más para leer": degradado que desvanece el texto en el borde
 * inferior del panel + chevron rebotando. Se oculta al llegar al final o si la
 * lista no hace scroll (clase .at-end, la pone el JS). */
.reco-fade {
  position: absolute;
  left: 12cqw;
  right: 0;
  bottom: 0;
  height: 11cqh;
  border-radius: 0 0 26px 26px;
  background: linear-gradient(to bottom, rgba(4,12,45,0) 0%, rgba(4,12,45,0.55) 55%, rgba(4,12,45,0.9) 100%);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: 1.2cqh;
  pointer-events: none;
  opacity: 1;
  transition: opacity 260ms ease;
}
.reco-outer.at-end .reco-fade { opacity: 0; }
.reco-fade svg {
  width: 5.5cqw;
  height: auto;
  color: var(--sky);
  animation: reco-chevron-bounce 1.5s ease-in-out infinite;
}
@keyframes reco-chevron-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(0.7cqh); }
}
@media (prefers-reduced-motion: reduce) {
  .reco-fade svg { animation: none; }
}
.recomendaciones-lead { text-align: center; }
.recomendaciones-lead-line1 {
  font-family: var(--font-body);
  font-size: 2.6cqw;
  font-weight: 500;
  color: var(--white);
}
.recomendaciones-lead-line2 {
  font-family: var(--font-display);
  font-size: 4.4cqw;
  font-weight: 600;
  color: var(--sky);
  text-transform: uppercase;
  letter-spacing: 0.01em;
  margin-top: 0.3em;
}
.recomendaciones-icon-wrap { margin-top: 5cqh; }
.recomendaciones-icon {
  display: block;
  width: 40cqw;
  height: auto;
  object-fit: contain;
  animation: recomendaciones-icon-beat 1.5s ease-in-out infinite;
}
@keyframes recomendaciones-icon-beat {
  0%, 100% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(248,0,64,0)); }
  10% { transform: scale(1.08); filter: drop-shadow(0 0 18px rgba(248,0,64,0.55)); }
  20% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(248,0,64,0)); }
  30% { transform: scale(1.04); filter: drop-shadow(0 0 10px rgba(248,0,64,0.35)); }
  40% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(248,0,64,0)); }
}
/* El botón "Agenda tu chequeo..." ahora vive DENTRO del .center-col (junto
 * al ícono), no como hermano suelto después del .grow — antes el espacio
 * sobrante del flex se acumulaba entero entre el ícono y el botón
 * (quedaba "muy separado", como lo describió el cliente); adentro del
 * grupo centrado usa el mismo gap:2.4cqh que el resto, así que el espacio
 * es el mismo que hay entre cualquier otro par de elementos de la pantalla.
 * También un poco más grande que un .btn normal, como se pidió. */
.btn-agendar {
  margin-top: 1cqh;
  font-size: 2.7cqw;
  padding-top: 2.9cqh;
  padding-bottom: 2.9cqh;
}
