/* Rilup, estilos compartidos del sitio público.
   Paleta oficial (brand sheet 2026-08), la misma de la app y de functions/p:
   Brasa #FE5901 · Carbon #17110B · CarbonSurface #241B10 · Crema #F4EDDF
   GrisCálido #8A7F70 · RojoAlerta #C62E24
   Sin dependencias externas: ni fuentes remotas, ni CDNs, ni analytics. */

:root {
  --brasa: #FE5901;
  --carbon: #17110B;
  --surface: #241B10;
  --crema: #F4EDDF;
  --gris: #8A7F70;
  --borde: #33281c;
  --ancho: 720px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--carbon);
  color: var(--crema);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  line-height: 1.6;
  font-size: 17px;
  overflow-wrap: break-word;
}

a { color: var(--brasa); }

/* ---------- La marca ---------- */

/* El dactilograma de Rilup. Definido una vez como <symbol> y reusado con <use>;
   el color lo pone `currentColor`, igual que el sello de la app. */
.mark { fill: currentColor; display: block; height: 1em; width: auto; }

.wordmark {
  color: var(--brasa);
  font-weight: 800;
  letter-spacing: -0.5px;
  text-decoration: none;
}

/* ---------- Estructura ---------- */

.wrap { max-width: var(--ancho); margin: 0 auto; padding: 0 20px; }

header.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 20px;
  max-width: var(--ancho);
  margin: 0 auto;
}
header.top .brand { display: flex; align-items: center; gap: 8px; text-decoration: none; }
header.top .brand .mark { color: var(--brasa); height: 26px; }
header.top .brand span { font-size: 22px; }
header.top nav { display: flex; gap: 18px; font-size: 14px; }
header.top nav a { color: var(--gris); text-decoration: none; }
header.top nav a:hover { color: var(--crema); }

/* padding-block (no el atajo) para no pisar el padding horizontal de .wrap */
/* El ritmo de las secciones y su linea divisoria.
   ────────────────────────────────────────────────────────────────────────────
   Mas espacio ABAJO que arriba, y no es un capricho: la linea le pertenece a la seccion que ABRE.
   Con 48 px por lado, simetricos, la linea quedaba a la misma distancia de las dos y el ojo la
   leia pegada al contenido anterior, como si lo cerrara de golpe. Ahora hay 68 px antes de la
   linea y 56 despues, asi que la linea entra con el bloque nuevo en vez de rematar el viejo. */
section { padding-block: 56px 68px; border-top: 1px solid var(--borde); }
/* El rotulo naranjo baja un poco mas: entre la linea y el, tiene que caber una pausa. Sin ella
   el ojo lee "linea-rotulo" como un solo objeto y parece un error de maquetado. */
section > .eyebrow:first-child { margin-top: 10px; }
section:first-of-type { border-top: 0; }

h1, h2, h3 { line-height: 1.2; }

h1 {
  font-size: 40px;
  margin: 16px 0 0;
  letter-spacing: -1px;
}
h2 {
  font-size: 26px;
  margin: 0 0 8px;
  letter-spacing: -0.4px;
}
h3 { font-size: 18px; margin: 22px 0 6px; }

.eyebrow {
  color: var(--brasa);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 3px;
  text-transform: uppercase;
  margin: 0 0 14px;
}

.lead { font-size: 20px; }
.muted { color: var(--gris); }
.small { font-size: 14px; }

/* ---------- Hero ---------- */

.hero { text-align: center; padding-block: 32px 56px; }
.hero .mark { color: var(--brasa); height: 76px; margin: 0 auto; }
.hero h1 { font-size: 44px; }
.hero .promesa {
  font-size: 21px;
  margin: 20px auto 0;
  max-width: 30ch;
}
.hero .sub { color: var(--gris); margin: 14px auto 0; max-width: 44ch; }

/* ---------- Botones ---------- */

.cta {
  display: inline-block;
  background: var(--brasa);
  color: var(--crema);
  text-decoration: none;
  padding: 14px 30px;
  border-radius: 999px;
  font-weight: 700;
  margin-top: 28px;
}
.cta:hover { filter: brightness(1.08); }
.cta-nota { color: var(--gris); font-size: 13px; margin-top: 12px; }

/* ---------- Bloques ---------- */

.card {
  background: var(--surface);
  border-radius: 14px;
  padding: 20px;
  margin-top: 16px;
}

.rule { border-left: 3px solid var(--brasa); padding-left: 16px; margin: 22px 0; }
.rule h3 { margin-bottom: 2px; }
.rule p { color: var(--gris); margin: 0; font-size: 15px; }

/* Pasos numerados de la atestación */
ol.pasos { list-style: none; counter-reset: paso; padding: 0; margin: 24px 0 0; }
ol.pasos li {
  counter-increment: paso;
  position: relative;
  padding-left: 52px;
  margin-bottom: 22px;
}
ol.pasos li::before {
  content: counter(paso);
  position: absolute;
  left: 0;
  top: 0;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--brasa);
  color: var(--brasa);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
}
ol.pasos li b { display: block; }
ol.pasos li span { color: var(--gris); font-size: 15px; }

/* Prueba / no prueba */
.dos { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 24px; }
.dos > div { flex: 1 1 260px; }
.dos h3 { font-size: 15px; letter-spacing: 1px; text-transform: uppercase; }
.dos .si h3 { color: var(--brasa); }
.dos .no h3 { color: var(--gris); }
.dos ul { margin: 8px 0 0; padding-left: 20px; font-size: 15px; }
.dos li { margin-bottom: 8px; }
.dos .no li { color: var(--gris); }

/* Los dos estados del sello */
.sellos { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 24px; }
.sellos > div { flex: 1 1 260px; background: var(--surface); border-radius: 14px; padding: 18px; }
.sello { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-size: 15px; }
.sello .mark { height: 18px; }
.sello.off { color: var(--gris); }
.sello.on { color: var(--brasa); }
.sellos p { font-size: 15px; color: var(--gris); margin: 10px 0 0; }

/* Firma del manifiesto */
.firma { text-align: center; margin-top: 36px; }
.firma .only { color: var(--brasa); font-size: 13px; letter-spacing: 2px; font-weight: 700; }
.firma .autor { color: var(--gris); font-size: 13px; margin-top: 6px; }

.divisor {
  border: 0;
  border-top: 1px solid var(--brasa);
  width: 120px;
  margin: 36px auto;
}

/* ---------- Pie ---------- */

footer {
  border-top: 1px solid var(--borde);
  padding: 32px 20px 56px;
  text-align: center;
  color: var(--gris);
  font-size: 14px;
}
footer .links { display: flex; flex-wrap: wrap; gap: 6px 20px; justify-content: center; margin-bottom: 16px; }
footer a { text-decoration: none; }
footer a:hover { text-decoration: underline; }

/* ---------- Móvil ---------- */

@media (max-width: 560px) {
  body { font-size: 16px; }
  .hero { padding-block: 20px 40px; }
  .hero .mark { height: 60px; }
  .hero h1 { font-size: 34px; }
  .hero .promesa { font-size: 19px; }
  h1 { font-size: 32px; }
  h2 { font-size: 23px; }
  section { padding: 40px 0; }
  header.top nav { display: none; }
  .cta { display: block; }
}

/* Páginas de texto largo (manifiesto) */
.texto { max-width: 680px; margin: 0 auto; padding: 8px 20px 64px; }
.texto h1 { color: var(--brasa); }
.texto p { margin: 16px 0; }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* ---- Los mundos: lo que vas a encontrar (landing emocional) ---------------- */
.mundos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px 28px;
  margin-top: 26px;
}
/* (los mundos ya no usan h3 ni p: van en figure/figcaption mas abajo) */

/* Frase ancla del relato: el giro de "algo se perdió" a "Rilup existe para eso" */
.destacado {
  font-size: 21px;
  font-weight: 700;
  color: var(--brasa);
  border-left: 3px solid var(--brasa);
  padding-left: 16px;
  margin: 24px 0;
}
@media (max-width: 560px) {
  .destacado { font-size: 18px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Las demostraciones, con capturas de verdad
   ═══════════════════════════════════════════════════════════════════════════
   La primera versión dibujaba los gestos en CSS con rectángulos. Cristóbal: "no se entiende", y
   tenía razón. Un esquema de la app solo se entiende si ya sabes cómo es la app, o sea que le
   servía justamente a quien no lo necesitaba.

   Ahora son sus capturas reales, animadas: la misma pantalla en dos estados y el cruce entre
   ellos. La foto editada y la original, la publicación y su certificado, la publicación y su
   mapa. No hay que explicar qué representa cada rectángulo porque no hay rectángulos. */

.demos { display: grid; gap: 30px; grid-template-columns: repeat(2, 1fr); margin-top: 28px; }

/* Respira mas ARRIBA que abajo: eso es lo que ata el titulo al parrafo que explica y lo separa
   de la imagen que ilustra. Al reves, el titulo flota entre las dos sin pertenecer a ninguna. */
.demo h3 { font-size: 17.5px; font-weight: 700; letter-spacing: .3px; margin: 22px 0 8px; }
.demo p  { color: var(--gris); font-size: 14.5px; margin: 0; line-height: 1.55; }
@media (max-width: 640px) {
  /* En telefono se APILA, con la imagen chica y centrada.
     ──────────────────────────────────────────────────────────────────────────
     Antes intente imagen y texto lado a lado, con la imagen al 38% y el texto al lado. En un
     iPhone angosto se veia bien y en el Android de Cristobal se rompio: `.demo` tiene tres hijos
     (la escena, el titulo y el parrafo) y una rejilla los coloca en orden, asi que el titulo
     quedaba a la derecha de la imagen y el parrafo debajo de la imagen, en una columna del 38%
     de ancho. Se leia como cuatro palabras por linea.

     Se podia arreglar con colocacion explicita o envolviendo el texto en un div. No lo hago: dos
     columnas en una pantalla de telefono dejan el texto en 200 px utiles, que es peor que
     apilado aunque este bien colocado. Apilar es la respuesta simple y es la correcta. */
  .demos { grid-template-columns: 1fr; gap: 34px; }
  .escena { max-width: 230px; }
}

/* La escena tiene TOPE de ancho, y es lo que faltaba.
   ────────────────────────────────────────────────────────────────────────────
   Una captura de telefono mide 0,45 de ancho por 1 de alto. Sin tope, en una columna de 340 px
   se estiraba a 750 px de alto, y en un telefono a pantalla completa a mas de 800: la imagen se
   comia la pantalla entera y el texto que la explica quedaba a un scroll de distancia, o sea sin
   relacion visible con lo que describe. Por eso "los portes no calzan con los textos".

   Con tope, la escena y su parrafo caben juntos en un golpe de vista, que es la unica forma de
   que un pie de foto funcione como pie de foto. */
.escena {
  position: relative; border: 1px solid var(--borde); border-radius: 14px;
  overflow: hidden; background: var(--surface);
  max-width: 250px; margin: 0 auto;
}
.escena img { display: block; width: 100%; height: auto; }
/* `top/left/right/bottom` y no `inset`.
   ────────────────────────────────────────────────────────────────────────────
   `inset` llego a Safari de iPhone en la 14.5. En una version anterior la linea entera se ignora,
   y entonces una imagen `position: absolute` sin desplazamientos se queda en su sitio del flujo:
   las dos caras dejan de superponerse y se apilan una debajo de la otra. Eso es exactamente lo
   que se vio en el iPhone de Cristobal, con las tres fotos una tras otra en vez de la animacion.
   La forma larga funciona en todo lo que existe y no cuesta nada. */
.escena img.b { position: absolute; top: 0; left: 0; right: 0; bottom: 0; }

/* El toque. Del tamaño de un pulgar, porque es lo que muestra. */
.toque {
  position: absolute; width: 17%; padding-bottom: 17%; height: 0; border-radius: 50%;
  background: rgba(255,255,255,.20); border: 2px solid rgba(255,255,255,.75);
  transform: translate(-50%, -50%); pointer-events: none;
}
/* Con `aspect-ratio` disponible se usa esa, que es lo correcto; el relleno de arriba es el
   respaldo para iOS anterior a la 15, donde sin alto el circulo del gesto no se ve. */
@supports (aspect-ratio: 1 / 1) {
  .toque { padding-bottom: 0; height: auto; aspect-ratio: 1; }
}

/* 1 · Mantener presionado: la editada se va y aparece la original */
@keyframes cruzar { 0%,18% { opacity: 0 } 30%,70% { opacity: 1 } 82%,100% { opacity: 0 } }
@keyframes presionar {
  0%,10%   { opacity: 0; transform: translate(-50%,-50%) scale(1.35) }
  20%,72%  { opacity: 1; transform: translate(-50%,-50%) scale(1) }
  84%,100% { opacity: 0; transform: translate(-50%,-50%) scale(1) }
}
/* Solo cruza la LAMINA, igual que el giro del sello. Las dos capturas son de sesiones
   distintas (miden 1423 y 1420 px de alto, con la lamina en sitios que no coinciden), asi que
   cruzar la pantalla completa hacia saltar toda la app: cabecera, fichas y barra inferior
   cambiaban de tamaño y de posicion. Recortadas a la misma caja, lo unico que cambia es lo que
   de verdad cambia en la app. */
.g-original .tarjeta .b { animation: cruzar 5s ease-in-out infinite; }
.g-original .toque { left: 50%; top: 44%; animation: presionar 5s ease-in-out infinite; }

/* 2 · Tocar el sello: SOLO LA TARJETA se da vuelta.
   ────────────────────────────────────────────────────────────────────────────
   La primera versión giraba la captura entera, con barra de estado, cabecera, pestañas y barra
   inferior incluidas. Cristóbal: "se está dando vuelta toda la imagen en vez de la tarjeta". Y
   eso no es un detalle estético: en la app el teléfono no se da vuelta, se da vuelta UNA tarjeta
   dentro de una pantalla que se queda quieta. Girar todo mostraba un gesto que no existe.

   Así que el fondo es la captura CON EL HUECO VACÍO y encima va solo la lámina, en sus dos
   caras. El hueco importa: con la captura completa detrás, al aplastarse la tarjeta asomaba la
   misma foto por los lados y se leía como dos imágenes superpuestas en vez de una tarjeta
   dándose vuelta. Detrás de una tarjeta que gira tiene que haber pantalla, no otra copia de la
   tarjeta. La caja está en porcentajes medidos sobre la captura (x 2.5%, y 15.6%, 95% de
   ancho, 61.56% de alto), que es lo que hace que la lámina caiga exactamente sobre su hueco por
   grande o chica que se vea la imagen.

   Las dos caras miden igual a propósito: el certificado es más corto que la foto y se rellenó
   con el fondo de la app en vez de estirarlo. Estirado, al girar se vería un salto de tamaño
   justo en el instante en que hay que creer que es la misma tarjeta. */
.tarjeta { position: absolute; left: 2.5%; top: 12.4%; width: 95%; height: 63.9%; }
.tarjeta img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }

@keyframes girar { 0%,26% { transform: scaleX(1) } 40% { transform: scaleX(.03) }
                   54%,88% { transform: scaleX(1) } 100% { transform: scaleX(1) } }
@keyframes caraA { 0%,34% { opacity: 1 } 42%,84% { opacity: 0 } 94%,100% { opacity: 1 } }
@keyframes caraB { 0%,38% { opacity: 0 } 46%,82% { opacity: 1 } 92%,100% { opacity: 0 } }
@keyframes tocar {
  0%,8%    { opacity: 0; transform: translate(-50%,-50%) scale(1.4) }
  16%,24%  { opacity: 1; transform: translate(-50%,-50%) scale(.85) }
  32%,100% { opacity: 0; transform: translate(-50%,-50%) scale(.85) }
}
.g-sello .tarjeta   { animation: girar 5s ease-in-out infinite; }
.g-sello .tarjeta .a { animation: caraA 5s linear infinite; }
.g-sello .tarjeta .b { animation: caraB 5s linear infinite; }
.g-sello .toque { left: 76%; top: 79.7%; animation: tocar 5s ease-in-out infinite; }

/* 3 · Tocar el lugar: la pantalla entera cambia, y acá eso SÍ es lo que pasa.
   El mapa se abre a pantalla completa, no por detrás de la publicación, así que un giro de
   tarjeta seria mentir sobre el gesto. Se cruza la pantalla completa. */
.g-lugar img.b  { animation: cruzar 5s ease-in-out infinite; }
.g-lugar .toque { left: 44%; top: 79.7%; animation: tocar 5s ease-in-out infinite; }

/* Quien pidió menos movimiento ve la primera pantalla, quieta. Una animación en bucle molesta de
   verdad a alguien con sensibilidad vestibular, y acá la imagen detenida dice casi lo mismo. */
@media (prefers-reduced-motion: reduce) {
  .demo *, .demo .caras { animation: none !important; }
  .demo .toque { display: none; }
  .escena img.b { opacity: 0; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   Súmate: la inscripción y su encuesta
   ═══════════════════════════════════════════════════════════════════════════ */

.sumate { background: var(--surface); border-top: 1px solid var(--borde);
          border-bottom: 1px solid var(--borde); padding: 40px 0; margin-top: 48px; }
.sumate h2 { margin-top: 0; }

.campo { display: block; width: 100%; margin: 6px 0 18px; padding: 13px 14px;
         background: var(--carbon); color: var(--crema); font: inherit;
         border: 1px solid var(--borde); border-radius: 10px; }
.campo:focus-visible { outline: 2px solid var(--brasa); outline-offset: 2px; }

.pregunta { margin: 22px 0 0; font-weight: 700; font-size: 16px; }
.pregunta + .ayuda { color: var(--gris); font-size: 13.5px; margin: 2px 0 10px; }

/* Las opciones son etiquetas grandes y tocables, no radios diminutos: esto se responde con el
   pulgar en un teléfono, y un radio de 14 px es una trampa. */
.ops { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 4px; }
.ops label { cursor: pointer; }
.ops input { position: absolute; opacity: 0; pointer-events: none; }
.ops span { display: inline-block; padding: 9px 14px; border-radius: 999px;
            border: 1px solid var(--borde); font-size: 14.5px; line-height: 1.2; }
.ops input:checked + span { border-color: var(--brasa); color: var(--brasa);
                            background: rgba(254,89,1,.08); }
.ops input:focus-visible + span { outline: 2px solid var(--brasa); outline-offset: 2px; }

.trampa { position: absolute; left: -9999px; }
.aviso { margin-top: 14px; font-size: 14.5px; }
.aviso.ok  { color: var(--brasa); font-weight: 700; }
.aviso.mal { color: #ff8f7a; }

/* Los desplegables de la encuesta. Nativos y no una lista de casillas: el selector del sistema
   ocupa una línea, se responde con el pulgar y ya lo conoce todo el mundo. Un formulario que se
   ve corto se contesta; uno que se ve largo se abandona en la segunda pregunta. */
select.campo {
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--gris) 50%),
    linear-gradient(135deg, var(--gris) 50%, transparent 50%);
  background-position: calc(100% - 19px) 21px, calc(100% - 13px) 21px;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 40px;
}
/* El desplegable abierto lo pinta el sistema, y ahí no manda nuestro CSS: hay que darle a las
   opciones un fondo propio o en algunos Android salen texto claro sobre blanco. */
select.campo option { background: var(--carbon); color: var(--crema); }

/* El video del carrete, con la marca del grabador tapada.
   ────────────────────────────────────────────────────────────────────────────
   La grabacion trae la marca de agua del grabador de pantalla pegada abajo, y una marca ajena en
   una pagina que habla de procedencia es lo peor que podria aparecer ahi.

   El primer intento fue acortar el cuadro. Cristobal: "se acorta y queda raro", y era cierto: al
   lado de tres escenas que muestran el telefono entero, una a la que le falta el final se lee
   como un error de maquetado y no como una decision.

   Asi que el cuadro vuelve a estar completo y la marca se TAPA con una franja del color de la
   barra de navegacion, muestreado de la captura del mismo telefono: #231B10 arriba y #16130C
   abajo, que es como se degrada de verdad. Cubre desde el 92,5% del alto, o sea la zona de la
   marca, sin llegar a las etiquetas de la barra de la app.

   Se hace en CSS y no rehaciendo el archivo: no hay ffmpeg aca, y aunque lo hubiera, recodificar
   un video entero para arreglar una franja lo degrada completo. El dia que haya una grabacion
   limpia, se borra este bloque y no queda rastro. */
.recorte {
  position: relative; width: 100%; overflow: hidden;
  /* Respaldo para navegadores sin `aspect-ratio` (Chrome anterior a 88, WebView viejo de
     Android): sin alto declarado el contenedor mide cero y el video simplemente no aparece.
     1233/576 = 214,06%. */
  padding-top: 214.06%;
}
@supports (aspect-ratio: 1 / 1) {
  .recorte { padding-top: 0; aspect-ratio: 576 / 1233; }
}
/* El alto va declarado, NO en `auto`.
   ────────────────────────────────────────────────────────────────────────────
   Con `height: auto` el navegador necesita saber cuanto mide el video para darle alto, y eso solo
   lo sabe cuando llegan los metadatos. Al envolverlo en `.recorte` le quite los atributos
   width/height, asi que hasta que el archivo respondiera el elemento medía CERO de alto: ni el
   video ni el poster tenian donde dibujarse. En un navegador que carga rapido no se nota; en un
   iPhone con la conexion mala, o con el ahorro de datos, el hueco se queda vacio.

   El alto se deduce de la geometria y no del archivo: el contenedor muestra 1233 px de video y el
   video mide 1280, asi que el video ocupa 1280/1233 = 103,81% del alto del contenedor, y el
   desplazamiento de 47 px que esconde la barra de estado es el 3,81% de ese mismo alto. */
.recorte video {
  position: absolute; top: -3.81%; left: 0; display: block;
  width: 100%; height: 103.81%; object-fit: cover;
}
.recorte::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 7.8%;
  background: linear-gradient(180deg, #231B10 0%, #201A11 55%, #16130C 100%);
}

/* En el lugar, el mapa se abre ENCIMA de todo, tarjeta incluida, porque en la app es una pantalla
   completa y no el reverso de la publicacion. */
.g-lugar img.b { z-index: 2; }

/* ═══════════════════════════════════════════════════════════════════════════
   El muro: dos cintas de capturas que se deslizan solas
   ═══════════════════════════════════════════════════════════════════════════
   "Encuentro que está un poco fome la web, para ser de una red social." Tenía razón, y el número
   lo confirmaba: 369 palabras antes de la primera imagen. Alguien entraba y leía cuatro párrafos
   de concepto antes de ver cómo se ve Rilup.

   Ahora lo primero después del titular es contenido moviéndose. Una red social no se explica, se
   muestra: si en tres segundos se ve una iguana, una escalada, unas manos tocando piano y una
   feria, ya se entendió qué clase de sitio es esto.

   Dos cintas en sentidos OPUESTOS. Una sola en un sentido se lee como un carrusel de banco; dos
   cruzándose se lee como un muro vivo. La de abajo va más lenta para que no compitan.

   La lista de piezas va DUPLICADA en el HTML, y no es un descuido: el bucle se hace desplazando
   la tira hasta la mitad exacta de su ancho, y en ese punto la segunda copia está donde estaba la
   primera. Sin la copia, al llegar al final habría un salto visible. */

.muro { overflow: hidden; padding: 4px 0 8px; }
.cinta { overflow: hidden; margin-bottom: 12px; }
.tira { display: flex; gap: 12px; width: max-content; animation: correr 60s linear infinite; }
.tira.derecha { animation-direction: reverse; }
.cinta.lenta .tira { animation-duration: 88s; }
@keyframes correr { from { transform: translateX(0) } to { transform: translateX(-50%) } }

/* Al pasar el cursor se detiene, para poder mirar una. En un teléfono no aplica y da igual:
   ahí la cinta ya es el movimiento y no hay puntero que la detenga. */
.muro:hover .tira { animation-play-state: paused; }

.pieza { margin: 0; position: relative; flex: 0 0 auto; width: 158px; }

/* ── Algunas piezas se dan vuelta y enseñan lo que llevan detrás ──────────────
   Un carrusel de fotos lo tiene cualquiera. Lo que solo tiene Rilup es que detrás de cada foto
   hay algo que la respalda, así que cada cierto rato una pieza se gira y aparece su certificado
   o su mapa. Es la app resumida en dos segundos, sin una sola palabra.

   El giro se hace aplastando el ancho, la misma técnica que las demostraciones de más abajo: la
   lectura es "se dio vuelta" y no depende de perspectivas 3D, que cada navegador resuelve
   distinto y Safari viejo directamente no.

   Ciclo largo, 16 s, con retrasos escalonados. Si giraran a la vez se leería como un efecto de
   la página; una tras otra se lee como que cada publicación tiene lo suyo detrás. Y con el ciclo
   largo la mayor parte del tiempo el muro es lo que dice ser, un muro de fotos.

   El dorso CORRESPONDE a su foto: el mapa va con el cerro sobre la ciudad, que es la zona que
   marca, y el certificado con las artes marciales bajo techo, porque solo afirma "Santiago,
   Chile". Un certificado ajeno debajo de una foto sería, en esta página, lo peor posible. */
.pieza .dorso { position: absolute; top: 0; left: 0; opacity: 0; }
.pieza.gira .frente,
.pieza.gira .dorso { animation: voltear 16s ease-in-out infinite; animation-delay: inherit; }
.pieza.gira .dorso { animation-name: voltear-dorso; }

@keyframes voltear {
  0%, 22%   { transform: scaleX(1); opacity: 1 }
  27%       { transform: scaleX(.04); opacity: 1 }
  29%, 44%  { transform: scaleX(.04); opacity: 0 }
  49%       { transform: scaleX(.04); opacity: 1 }
  54%, 100% { transform: scaleX(1); opacity: 1 }
}
@keyframes voltear-dorso {
  0%, 24%   { transform: scaleX(.04); opacity: 0 }
  29%       { transform: scaleX(.04); opacity: 1 }
  34%, 42%  { transform: scaleX(1); opacity: 1 }
  47%       { transform: scaleX(.04); opacity: 1 }
  49%, 100% { transform: scaleX(.04); opacity: 0 }
}
.pieza img {
  display: block; width: 100%; height: auto; border-radius: 12px;
  border: 1px solid var(--borde); background: var(--surface);
}
/* El sello sobre cada pieza. Es la marca de la app y acá hace el mismo trabajo: decir que eso
   que estás mirando trae algo detrás que lo respalda. */
.pieza figcaption {
  position: absolute; left: 8px; right: 8px; bottom: 8px;
  display: flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; color: var(--crema);
  text-shadow: 0 1px 6px rgba(0,0,0,.9);
}
.pieza .sello { height: 13px; width: auto; fill: var(--brasa); flex: 0 0 auto; }

@media (min-width: 700px) { .pieza { width: 190px; } }

/* Sin movimiento: las cintas se quedan quietas y se pueden arrastrar con el dedo. Una cinta
   infinita en bucle es de las cosas que de verdad marean a alguien con sensibilidad vestibular. */
@media (prefers-reduced-motion: reduce) {
  .tira { animation: none; }
  .cinta { overflow-x: auto; }
  .pieza.gira .frente, .pieza.gira .dorso { animation: none; }
  .pieza .dorso { display: none; }
}

/* ── Los seis mundos, con foto ────────────────────────────────────────────────
   Eran 128 palabras describiendo en prosa lo que se puede ver. Una sección que dice "mira lo que
   hay" sin mostrar nada era justo lo que sobraba. */
.mundos { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 20px; }
@media (max-width: 640px) { .mundos { grid-template-columns: repeat(2, 1fr); gap: 10px; } }

.mundo { margin: 0; position: relative; }
.mundo img {
  display: block; width: 100%; height: auto; border-radius: 12px;
  border: 1px solid var(--borde); background: var(--surface);
}
.mundo figcaption {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 40px 13px 13px;
  border-radius: 0 0 12px 12px;
  background: linear-gradient(180deg, transparent, rgba(10,7,4,.88));
}
.mundo figcaption b {
  display: block; font-size: 15.5px; font-weight: 700;
  letter-spacing: .3px; margin-bottom: 5px;
}
.mundo figcaption span {
  display: block; color: #cdbfae; font-size: 12.5px; line-height: 1.4;
}

/* ── Proyectos, eventos y clubes ─────────────────────────────────────────────
   Van aparte de los seis mundos porque son otra cosa: los mundos dicen QUE vas a ver, estos dicen
   que HACE la app. Y llevan mas texto que un mundo a proposito, porque ninguno se entiende con
   una palabra: "eventos" lo tiene cualquier red social, y lo que aqui lo hace distinto es la
   frase que explica por que no se puede colar uno desde el sillon de la casa. */
.unicos { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 22px; }
@media (max-width: 700px) { .unicos { grid-template-columns: 1fr; gap: 22px; } }

.unico { margin: 0; }
.unico img {
  display: block; width: 100%; height: auto; border-radius: 12px;
  border: 1px solid var(--borde); background: var(--surface);
}
.unico figcaption { padding-top: 10px; }
.unico figcaption b {
  display: block; color: var(--brasa); font-size: 16.5px; font-weight: 700;
  letter-spacing: .3px; margin-bottom: 7px;
}
.unico figcaption span { color: var(--gris); font-size: 14px; line-height: 1.5; }

@media (max-width: 700px) {
  /* En telefono, imagen chica al lado del texto: apilado, cada uno ocupaba una pantalla entera
     y estos tres se leen mejor de corrido, uno tras otro. */
  .unico { display: grid; grid-template-columns: 34% 1fr; gap: 14px; align-items: start; }
  .unico figcaption { padding-top: 0; }
}
