/* ===== Prototipo v3 =========================================================
   Un solo aparato en el escenario, que se transforma: telefono para los
   mensajes, laptop para el disco y el escritorio, telefono otra vez para las
   fotos. Cada escena vive adentro de la ventana o la app que le corresponde,
   porque el marco es lo que da el contexto. */

/* ponytail-keep: el !important no es pereza. El atributo hidden es display:none de
   la hoja del navegador, y cualquier display del autor le gana: los satelites y la
   nube son display:grid, asi que aparecian en las seis escenas aunque estuvieran
   marcados hidden. */
.vida [hidden] { display: none !important; }

.vida { padding: 6vh 0 9vh; }
.vida-intro { margin-bottom: 5vh; }
.vida-intro p { color: var(--muted); max-width: 46ch; margin-top: 10px; }
.vida-pista { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 0 60px; align-items: start; }

/* ---- la columna que corre ---- */
.paso {
  min-height: 48vh; padding-right: 8px;
  display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 0 22px; align-content: center;
}
.paso:last-child { min-height: 38vh; }
.paso-marca { font-size: .72rem; letter-spacing: .15em; text-transform: uppercase; color: var(--muted); opacity: .7; margin-bottom: 14px; display: block; }
.paso h3 { font-size: clamp(1.15rem, 2.4vw, 1.5rem); line-height: 1.25; margin: 0 0 12px; }
.paso p { color: var(--muted); margin: 0; max-width: 40ch; }
@media (prefers-reduced-motion: no-preference) {
  .paso-texto > :not(.paso-resultado), .paso-vineta {
    opacity: .28; transform: translateY(14px);
    transition: opacity 500ms ease, transform 700ms cubic-bezier(.22, 1, .3, 1),
                border-color 600ms ease, box-shadow 600ms ease;
  }
  .paso.activo .paso-texto > :not(.paso-resultado), .paso.activo .paso-vineta { opacity: 1; transform: none; }
  /* Lo ya curado queda a media luz aunque no sea el paso que se lee: es parte del recorrido. */
  .paso.resuelto:not(.activo) .paso-vineta { opacity: .8; }
  .paso.activo .paso-texto > :nth-child(2) { transition-delay: 60ms }
  .paso.activo .paso-texto > :nth-child(3) { transition-delay: 120ms }
}

/* ---- el escenario ---- */
.vida-escena { position: sticky; top: 13vh; }
.escenario {
  --acento: #4356c9;
  --k: 1;
  position: relative; height: 470px;
  display: grid; place-items: center;
}
/* El halo toma el color de la escena: es lo que hace que cada sintoma se sienta
   distinto sin cambiar nada del resto. */
/* ponytail-keep: el halo se queda adentro de la caja del escenario y el derrame lo
   hace el blur, no el tamaño. Medía 130% con aspect-ratio 1, o sea un circulo mas
   ancho que su contenedor, y eso estiraba el documento 49px a la derecha: aparecia
   scroll horizontal en toda la portada. Antes no se notaba porque el recuadro de
   vidrio tenia overflow hidden y lo recortaba; al sacar la caja se fue el recorte.
   El blur derrama tinta pero no cuenta para el area scrolleable, asi que el brillo
   sigue saliendose y la pagina no. */
.halo {
  position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, color-mix(in srgb, var(--acento) 40%, transparent), transparent 70%);
  filter: blur(54px); opacity: .55; transition: background 900ms ease, opacity 900ms ease;
}

/* ---- el aparato que se transforma ---- */
/* El aparato es solo la caja que mide; el marco fisico vive en .tapa, que es lo
   que rota al abrirse. La base tiene que quedar afuera de la tapa o rotaria con
   ella, que es justo lo que hacia que se vieran desenganchadas. */
.aparato {
  --ancho: 196px; --alto: 371px; --radio: 30px; --marco: 9px;
  position: relative; z-index: 2;
  width: var(--ancho); height: var(--alto);
  scale: var(--k);
  perspective: 1100px; perspective-origin: 50% 90%;
  transition: width 820ms cubic-bezier(.3, 1.02, .3, 1), height 820ms cubic-bezier(.3, 1.02, .3, 1);
}
.tapa {
  position: absolute; inset: 0; padding: var(--marco); border-radius: var(--radio);
  /* La bisagra esta abajo: es por donde se abre. */
  transform-origin: 50% 100%; transform-style: preserve-3d;
  background: linear-gradient(150deg, light-dark(#c8ccd8, #55596b), light-dark(#9aa0b2, #2e3140) 46%, light-dark(#b9bfcd, #43465a));
  box-shadow: 0 0 0 1px light-dark(#ffffffaa, #ffffff1a), 0 30px 54px -28px #000c, inset 0 1px 1px #ffffff40;
  transition: border-radius 820ms ease, padding 820ms ease;
}
.aparato[data-aparato="laptop"] { --ancho: 438px; --alto: 274px; --radio: 15px; --marco: 11px; }

.pantalla {
  position: relative; width: 100%; height: 100%; overflow: hidden;
  border-radius: calc(var(--radio) - var(--marco) + 2px);
  background: light-dark(#f2f4f9, #12141c);
  transition: border-radius 820ms ease;
}
/* El brillo del vidrio: sin esto el aparato parece un rectangulo, no una pantalla. */
.pantalla::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 9;
  background: linear-gradient(112deg, #ffffff00 38%, light-dark(#ffffff55, #ffffff0f) 46%, #ffffff00 56%);
}
/* La isla dinamica: adentro de la pantalla, centrada en la barra de estado, como
   en el telefono de verdad. Antes estaba montada sobre el marco, pegada al borde.
   18.5 sale de 9 de marco + 15 de media barra de estado - 5.5 de media isla. */
.isla {
  position: absolute; z-index: 8; left: 50%; top: 18.5px; translate: -50% 0;
  width: 36px; height: 11px; border-radius: 99px; background: #050608;
  box-shadow: 0 0 0 .5px #ffffff12;
  transition: opacity 400ms ease, scale 500ms cubic-bezier(.3, 1.4, .4, 1);
}
/* El lente de la camara adentro de la isla. */
.isla::after {
  content: ""; position: absolute; right: 5px; top: 50%; translate: 0 -50%;
  width: 5px; height: 5px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #4a5d96, #0b0d16 62%);
}
.aparato[data-aparato="laptop"] .isla { opacity: 0; scale: .3; }
/* La camarita de la laptop, al reves. */
.ojito {
  position: absolute; z-index: 8; left: 50%; top: 4px; translate: -50% 0;
  width: 5px; height: 5px; border-radius: 50%; background: #0b0c12;
  box-shadow: inset 0 0 0 1px #ffffff22; opacity: 0; transition: opacity 400ms ease 300ms;
}
.aparato[data-aparato="laptop"] .ojito { opacity: 1; }
/* La base de la laptop crece desde el aparato cuando se transforma. */
.base {
  position: absolute; left: 50%; top: 100%; translate: -50% 0;
  width: calc(var(--ancho) + 86px); height: 12px;
  background: linear-gradient(light-dark(#aeb4c4, #3b3e4f), light-dark(#8f96a8, #23252f));
  clip-path: polygon(0 0, 100% 0, 97.6% 100%, 2.4% 100%);
  border-radius: 0 0 8px 8px; box-shadow: 0 16px 24px -18px #000b;
  /* ponytail-keep: sin scale propio. Antes la base se estiraba de .45 a 1 en 780ms
     mientras el marco crecia en 820ms y la opacidad entraba en 400: tres tiempos
     distintos para dos piezas que son un solo objeto, y se veian despegarse. Ahora
     el ancho la sigue sola, porque sale de --ancho, y lo unico propio es el fundido. */
  opacity: 0; transform-origin: 50% 0;
  transition: opacity 340ms ease, width 820ms cubic-bezier(.3, 1.02, .3, 1);
}
.base::after {
  content: ""; position: absolute; left: 50%; top: 0; translate: -50% 0;
  width: 74px; height: 4px; border-radius: 0 0 6px 6px; background: light-dark(#7f8698, #171922);
}
.aparato[data-aparato="laptop"] .base { opacity: 1; }

/* La laptop se abre desde cerrada del todo: la tapa arranca acostada sobre la
   base, casi de canto contra la vista, y se levanta desde la bisagra. Con -74
   arrancaba entreabierta y no se leia como abrir sino como un aparato torcido.
   El -89.5 y no -90: a 90 exactos la tapa no tiene alto y algunos navegadores
   la saltean en vez de dibujar la rayita del canto. El bezier pasa apenas de
   cero y vuelve, que es el rebote de una tapa que se abre de un envion.
   La animacion arranca sola cuando el selector empieza a coincidir. */
@media (prefers-reduced-motion: no-preference) {
  .aparato[data-aparato="laptop"] .tapa { animation: abrir-tapa 1150ms cubic-bezier(.3, 1.12, .45, 1) both; }
  @keyframes abrir-tapa {
    0%, 20% { transform: rotateX(-89.5deg); }
    100%    { transform: rotateX(0deg); }
  }
  /* La pantalla se enciende mientras se abre, no aparece encendida. */
  .aparato[data-aparato="laptop"] .pantalla { animation: encender-pantalla 1150ms ease-out both; }
  @keyframes encender-pantalla { 0%, 48% { filter: brightness(.06) saturate(0) } 100% { filter: none } }
  .aparato[data-aparato="laptop"] .base { transition-delay: 0s; }
}

/* ---- las fichas adentro de la pantalla ---- */
.ficha {
  position: absolute; inset: 0; opacity: 0; visibility: hidden;
  transform: scale(.96) translateY(10px);
  transition: opacity 380ms ease, transform 560ms cubic-bezier(.22, 1, .3, 1), visibility 0s 380ms;
}
.ficha.al-frente { opacity: 1; visibility: visible; transform: none; transition-delay: 0s, 0s, 0s; }

/* ---- la barra del sistema =================================================
   La navegacion vive adentro del aparato, en la franja donde el sistema
   confiesa su estado: barra de menus cuando es laptop, barra de estado cuando
   es telefono. Es el mismo rincon donde en la vida real se instala solo el
   icono del antivirus que pide plata, y vaciarlo es el trabajo de Francisco. */
.barra-sistema {
  position: absolute; z-index: 7; inset: 0 0 auto; display: flex; align-items: center;
  height: var(--alto-barra, 21px); padding: 0 8px; gap: 8px;
  font-size: 10px; letter-spacing: .02em; color: light-dark(#4a5062, #aeb6c9);
  background: light-dark(#ffffffc9, #0e1017c9);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid light-dark(#0000001f, #ffffff14);
  transition: height 820ms ease, padding 820ms ease;
}
[data-aparato="telefono"] .barra-sistema { --alto-barra: 30px; padding: 0 10px; }
.barra-hueco { flex: 1; }
/* En el telefono la isla se come el centro de la franja. */
[data-aparato="telefono"] .barra-hueco { min-width: 68px; }

/* ponytail-keep: la X NO cambia nunca. Antes se convertia en tilde al resolver
   todo, y el argumento que se leia era "el problema era Fran, y cuando se
   arregla, Fran desaparece". Es su logo: tiene que ser la constante, no el
   estado. Lo resuelto se marca con el relleno de los iconos, no con la marca. */
.barra-marca { display: flex; align-items: center; gap: 6px; flex: none; }
.marca-x { width: 11px; height: 11px; flex: none; overflow: visible; }
.x-trazo { fill: light-dark(#a8850b, #fffc00); }
.x-cuerpo { transform-box: fill-box; transform-origin: center; }
@media (prefers-reduced-motion: no-preference) {
  .barra-marca.festeja .x-cuerpo { animation: festejo 700ms cubic-bezier(.34, 1.56, .64, 1); }
  @keyframes festejo { 45% { transform: rotate(200deg) scale(1.25) } to { transform: rotate(360deg) } }
}
/* La ranura del nombre de la app activa. El rotulo es lo que declara que los
   cuatro iconos de la derecha son navegacion y no parte del dibujo. */
.barra-nombre { font-weight: 600; white-space: nowrap; opacity: .9; }
.barra-nombre .rotulo { font-weight: 400; letter-spacing: .13em; text-transform: uppercase; opacity: .55; font-size: 9px; }

.barra-sintomas { display: flex; align-items: center; gap: 9px; flex: none; }
.sint {
  position: relative; display: grid; place-items: center; width: 14px; height: 14px;
  color: currentColor; opacity: .45; border-radius: 4px;
  transition: opacity 260ms ease, color 600ms ease;
}
/* El area de toque real es de 30x26 y no se ve: a 14px el dibujo es un blanco imposible. */
.sint::after { content: ""; position: absolute; inset: -6px -8px; }
.sint svg { width: 100%; height: 100%; }
.sint:hover, .sint:focus-visible { opacity: 1; }
.sint:focus-visible { outline: 2px solid light-dark(#a8850b, #fffc00); outline-offset: 3px; }
.sint[aria-current="step"] { opacity: 1; }
.sint[aria-current="step"]::before {
  content: ""; position: absolute; left: 50%; bottom: -5px; translate: -50% 0;
  width: 14px; height: 2px; border-radius: 2px; background: var(--acento);
  transition: background 700ms ease;
}
/* Contorno es pendiente, macizo es resuelto. Sin cruz y sin tilde: los dos
   simbolos arrastran un significado que acá no corresponde. */
.sint .glifo { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transition: fill 500ms ease; }
.sint.resuelto { opacity: 1; color: light-dark(#1d7a56, #4ce0ac); }
.sint.resuelto .glifo { fill: currentColor; stroke: currentColor; }
/* "resuelto" tiene que llegarle al lector de pantalla: el relleno del icono no
   lo dice, y depender solo del color deja afuera a quien no lo distingue. */
.solo-lector { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* En forma de telefono la franja es una barra de estado, y ahi el nombre de la app
   no va: ademas no entra: en 186px la X, la palabra, el hueco de la isla, los cuatro
   iconos y el contador se pisaban, y la isla tapaba el rotulo. */
/* ponytail-keep: estas medidas estan contadas, no elegidas. La pantalla del
   telefono mide 178 (196 menos 9 de marco a cada lado) y la barra deja 10 de
   padding por lado. La isla va centrada: ocupa de 71 a 107. Los cuatro iconos
   con sus tres huecos son 4 x 10.5 + 3 x 4.5 = 55.5 y terminan en 168, asi que
   arrancan en 112.5: 5.5 de aire con la isla. Con 186 de ancho no entraban y la
   isla habia que achicarla y subirla al marco, que es lo que se veia pegado al
   borde. Con el nombre de la app y el contador tampoco entran: por eso se van. */
[data-aparato="telefono"] .barra-nombre,
[data-aparato="telefono"] .barra-cuenta { display: none; }
[data-aparato="telefono"] .barra-sintomas { gap: 4.5px; }
[data-aparato="telefono"] .sint { width: 10.5px; height: 10.5px; }
[data-aparato="telefono"] .barra-hueco { min-width: 40px; }


.barra-cuenta { flex: none; font-variant-numeric: tabular-nums; opacity: .5; min-width: 19px; text-align: right; }
.barra-cuenta.completa { opacity: 1; color: light-dark(#1d7a56, #4ce0ac); font-weight: 600; }

/* La franja se come alto util: los carteles del antivirus arrancan arriba y sin
   esto quedan tapados por la barra. */
.ficha { top: 21px; }
[data-aparato="telefono"] .ficha { top: 30px; }

/* ---- la invitacion a tocar ---- */
@media (prefers-reduced-motion: no-preference) {
  .invita { animation: invitar 2.1s ease-out infinite; }
  @keyframes invitar {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--acento) 70%, transparent) }
    72%, 100% { box-shadow: 0 0 0 11px transparent }
  }
}

/* ===== ventana de escritorio, el marco de tres escenas ===== */
.ventana { position: absolute; inset: 0; display: flex; flex-direction: column; background: light-dark(#f7f8fc, #191c25); }
.ventana-barra {
  display: flex; align-items: center; gap: 6px; padding: 8px 11px; flex: none;
  background: light-dark(#e8eaf1, #21242f); border-bottom: 1px solid light-dark(#00000012, #ffffff10);
}
.semaforo { width: 9px; height: 9px; border-radius: 50%; display: block; }
.semaforo.r { background: #ff5f57 } .semaforo.a { background: #febc2e } .semaforo.v { background: #28c840 }
.ventana-titulo { margin-left: 8px; font-size: .72rem; color: light-dark(#5a6072, #99a0b5); letter-spacing: .02em; }
.ventana-cuerpo { flex: 1; padding: 18px 20px; display: flex; flex-direction: column; justify-content: center; gap: 13px; color: light-dark(#1d2233, #e6e9f2); }

/* ===== 1. el chat, adentro del telefono ===== */
.app-chat { position: absolute; inset: 0; display: flex; flex-direction: column; background: light-dark(#ece5dd, #0f1419); }
.chat-barra {
  /* 9 arriba y no 30: los 30 eran el lugar de la isla de antes de que existiera la
     barra de estado, y dejaban una franja vacia arriba de "Fran X". */
  display: flex; align-items: center; gap: 8px; padding: 9px 11px 9px; flex: none;
  background: light-dark(#f6f6f6, #1f2c33); border-bottom: 1px solid light-dark(#0000000f, #ffffff0d);
}
.chat-atras { color: light-dark(#3a7bd5, #7fb3ff); font-size: 1.1rem; line-height: 1; }
.chat-avatar { width: 27px; height: 27px; border-radius: 50%; background: #2b2470; display: grid; place-items: center; flex: none; }
.chat-avatar svg { width: 14px; height: 14px; fill: #fffc00; }
.chat-quien { font-size: .74rem; font-weight: 600; color: light-dark(#111, #eaeef5); line-height: 1.25; }
.chat-quien small { display: block; font-size: .62rem; font-weight: 400; color: light-dark(#667, #8aa); }
.chat-hilo { flex: 1; padding: 12px 10px; display: flex; flex-direction: column; gap: 7px; overflow: hidden; }
.burbuja { padding: 7px 11px; font-size: .74rem; line-height: 1.42; max-width: 84%; box-shadow: 0 2px 5px -3px #0006; position: relative; }
.burbuja.suya { align-self: flex-end; border-radius: 12px 12px 3px 12px; background: light-dark(#2f6df0, #3f63d8); color: #fff; }
.burbuja.mia { align-self: flex-start; border-radius: 12px 12px 12px 3px; background: light-dark(#e7e9ef, #262b36); color: light-dark(#111, #e8ecf3); }
.hora { display: block; text-align: right; font-size: .55rem; opacity: .5; margin-top: 2px; }
.chat-entrada {
  flex: none; display: flex; align-items: center; gap: 7px; padding: 7px 10px 11px;
  background: light-dark(#f6f6f6, #1f2c33); font-size: .68rem; color: light-dark(#8a8a8a, #7b8794);
}
.chat-campo { flex: 1; background: light-dark(#fff, #2a3942); border-radius: 99px; padding: 6px 11px; }
.chat-mic { width: 22px; height: 22px; border-radius: 50%; background: light-dark(#2f6df0, #3f63d8); flex: none; display: grid; place-items: center; }
.chat-mic svg { width: 11px; height: 11px; fill: #fff; }
/* Los puntitos no son un globo aparte: son el estado previo del MISMO globo, que
   despues se convierte en el mensaje. Colgados arriba de todo no significaban nada,
   porque una animacion de "esta escribiendo" solo tiene sentido si despues llega algo. */
.burbuja[data-dice="callado"] { display: none; }
.burbuja .dicho { display: none; }
.burbuja[data-dice="dicho"] .puntitos { display: none; }
.burbuja[data-dice="dicho"] .dicho { display: inline; }
.puntitos { display: inline-flex; gap: 4px; padding: 1px 0; }
.puntitos i { width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: .45; display: block; }
@media (prefers-reduced-motion: no-preference) {
  .puntitos i { animation: puntear 1.25s ease-in-out infinite; }
  .puntitos i:nth-child(2) { animation-delay: .16s } .puntitos i:nth-child(3) { animation-delay: .32s }
  @keyframes puntear { 0%, 60%, 100% { opacity: .3; transform: translateY(0) } 30% { opacity: 1; transform: translateY(-3px) } }
  .burbuja[data-dice] { animation: llegar 460ms cubic-bezier(.34, 1.56, .64, 1); }
  @keyframes llegar { from { opacity: 0; transform: translateY(8px) scale(.9) } to { opacity: 1; transform: none } }
}

/* ===== 2. el disco ===== */
.disco-barra { display: flex; gap: 2px; padding: 5px; border-radius: 9px; min-height: 44px; background: light-dark(#00000010, #ffffff0a); border: 1px solid light-dark(#00000014, #ffffff12); }
/* ponytail-keep: ancho fijo, no flex 1. Con flex 1 los bloques que quedaban se
   estiraban para tapar el hueco del que se borraba, y el disco se veia igual de
   lleno despues de limpiar. El disco tiene un tamaño: lo que se borra deja lugar,
   los de la derecha corren a la izquierda y el espacio libre se junta al final.
   --n lo pone el guion, que es el que crea los bloques, para no tener el numero
   escrito a mano en dos lados. */
.bloque {
  flex: 0 0 calc((100% - (var(--n, 24) - 1) * 2px) / var(--n, 24)); border-radius: 4px;
  background: light-dark(#7d8bc4, #4a5580);
  transition: flex-basis 460ms cubic-bezier(.34, 1.3, .64, 1), margin 460ms cubic-bezier(.34, 1.3, .64, 1),
              opacity 160ms ease, transform 220ms ease, background 400ms ease;
}
.bloque.sistema { background: light-dark(#b9c0d6, #353c55); }
.bloque.basura { background: light-dark(#e2624a, #c9553e); cursor: pointer; }
.bloque.basura:hover { transform: translateY(-5px); }
/* El margen negativo se come el hueco de 2px que el gap le seguiria dejando. */
.bloque.fuera { flex-basis: 0; margin-right: -2px; opacity: 0; transform: scale(.2); pointer-events: none; }
.disco-leyenda { display: flex; gap: 13px; font-size: .62rem; color: light-dark(#5a6072, #99a0b5); }
.disco-leyenda span { display: flex; align-items: center; gap: 5px; }
.disco-leyenda i { width: 8px; height: 8px; border-radius: 2px; display: block; }
.disco-libre { margin: 0; font-size: .78rem; font-weight: 600; }
.disco-libre b { font-variant-numeric: tabular-nums; }
.disco-alerta { font-size: .68rem; color: light-dark(#c2371f, #ff8a6d); transition: opacity 400ms ease; }
.disco-ok .disco-alerta { opacity: 0; }
.disco-ok .disco-libre { color: light-dark(#1d7a56, #4ce0ac); }

/* ===== 3. el escritorio invadido ===== */
.escritorio { position: absolute; inset: 0; display: flex; flex-direction: column;
  background: linear-gradient(145deg, light-dark(#5b6ea8, #1b2a4a), light-dark(#8e7aa8, #3a2a4d)); }
.escritorio-iconos { padding: 12px; display: flex; flex-direction: column; gap: 11px; width: 62px; }
.icono-esc { display: grid; gap: 3px; justify-items: center; font-size: .53rem; color: #ffffffcc; text-shadow: 0 1px 2px #0008; }
.icono-esc i { width: 25px; height: 21px; border-radius: 3px 3px 3px 3px; background: #ffffff35; box-shadow: inset 0 1px 0 #ffffff55; display: block; }
.barra-tareas {
  margin-top: auto; flex: none; display: flex; align-items: center; justify-content: space-between;
  padding: 5px 10px; background: light-dark(#ffffffcc, #10131be0); backdrop-filter: blur(8px);
  font-size: .6rem; color: light-dark(#333, #dfe4ee);
}
.win-logo { width: 13px; height: 13px; display: grid; grid: 1fr 1fr / 1fr 1fr; gap: 1.5px; }
.win-logo i { background: light-dark(#3a7bd5, #7fb3ff); border-radius: 1px; }
.popup {
  position: absolute; width: 78%; padding: 10px 12px; border-radius: 8px;
  background: light-dark(#fffffff7, #262a36f7); border: 1px solid light-dark(#00000018, #ffffff18);
  box-shadow: 0 18px 34px -18px #000d; font-size: .68rem; color: light-dark(#1d2233, #e6e9f2);
  left: 50%; top: 50%; translate: -50% -50%;
}
.popup b { display: block; font-size: .73rem; margin-bottom: 2px; }
.popup small { color: light-dark(#5a6072, #99a0b5); font-size: .62rem; }
.popup .escudo { position: absolute; left: 11px; top: 10px; width: 17px; height: 18px; }
.popup.con-escudo { padding-left: 36px; }
.popup .cerrar {
  position: absolute; top: 4px; right: 5px; width: 19px; height: 19px; border: 0; border-radius: 4px;
  background: none; cursor: pointer; color: light-dark(#666, #aab); font-size: .75rem; line-height: 1; padding: 0;
}
.popup .cerrar:hover { background: #e2624a; color: #fff; }
.popup .pagar { margin-top: 8px; display: inline-block; padding: 4px 10px; border-radius: 5px; background: light-dark(#e2624a, #c9553e); color: #fff; font-size: .63rem; font-weight: 600; }
@media (prefers-reduced-motion: no-preference) {
  .popup { animation: brotar 380ms cubic-bezier(.34, 1.56, .64, 1); }
  @keyframes brotar { from { opacity: 0; scale: .84 } }
  .popup.yendose { animation: absorber 300ms cubic-bezier(.55, 0, .8, .3) forwards; transform-origin: calc(100% - 14px) 14px; }
  @keyframes absorber { to { opacity: 0; transform: scale(.05); } }
}
.popups-calma {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%; text-align: center; width: 80%;
  opacity: 0; transition: opacity 600ms ease 200ms; color: #fff; text-shadow: 0 2px 6px #0009;
}
.rendido .popups-calma { opacity: 1; }
.popups-calma strong { display: block; font-size: .85rem; }
.popups-calma span { font-size: .68rem; opacity: .8; }
.escudo-ok { width: 34px; height: 34px; display: block; position: relative; }

/* ===== 4. las particiones ===== */
.particion-cajas { display: flex; gap: 3px; align-items: stretch; }
.parte {
  flex-grow: 1; flex-basis: 0; min-width: 0; padding: 9px 11px; border-radius: 7px;
  border: 1px solid light-dark(#00000018, #ffffff14); background: light-dark(#ffffffcc, #ffffff0a);
  transition: flex-grow 800ms cubic-bezier(.22, 1, .3, 1), opacity 500ms ease, padding 700ms, border-width 700ms;
}
.parte-nombre { font-size: .7rem; font-weight: 700; letter-spacing: .04em; display: flex; justify-content: space-between; }
.parte-nombre small { font-weight: 400; opacity: .6; }
.parte-llenado { height: 8px; border-radius: 99px; margin-top: 8px; background: light-dark(#00000014, #ffffff14); overflow: hidden; }
.parte-llenado i { display: block; height: 100%; border-radius: 99px; transition: width 1s cubic-bezier(.22, 1, .3, 1), background 700ms ease; }
.parte-c .parte-llenado i { width: 97%; background: light-dark(#e2624a, #ff6b4d); }
.parte-d .parte-llenado i { width: 3%; background: light-dark(#7d8bc4, #6b76a8); }
.parte-libres { display: block; margin-top: 6px; font-size: .62rem; opacity: .7; font-variant-numeric: tabular-nums; }
.particion.moviendo .parte-c .parte-llenado i { width: 100%; }
.particion.moviendo .parte-d .parte-llenado i { width: 0; }
.particion.unida .parte-d { flex-grow: 0; flex-basis: 0; padding-inline: 0; opacity: 0; border-width: 0; overflow: hidden; }
.particion.unida .parte-c { flex-grow: 2; }
.particion.unida .parte-c .parte-llenado i { width: 50%; background: light-dark(#1d7a56, #4ce0ac); }
.particion.unida .parte-c .parte-libres { color: light-dark(#1d7a56, #4ce0ac); opacity: 1; font-weight: 600; }
/* ponytail-keep: min-width y padding en cero. Es un boton dentro de un flex, y el
   min-width:auto de los items flex lo deja clavado en 12px: la pared no termina de
   irse nunca y queda una rayita en el medio del disco ya unido. */
.muro {
  position: relative; width: 13px; min-width: 0; padding: 0; border: 0; border-radius: 3px; cursor: pointer;
  background: repeating-linear-gradient(45deg, light-dark(#00000026, #ffffff26) 0 3px, transparent 3px 6px), light-dark(#00000014, #ffffff12);
  transition: all 700ms cubic-bezier(.22, 1, .3, 1);
}
/* El area de toque real llega a 44px sin que la pared se vea gorda. */
.muro::after { content: ""; position: absolute; inset: -10px -16px; }
.muro:hover { background: repeating-linear-gradient(45deg, light-dark(#00000040, #ffffff40) 0 3px, transparent 3px 6px), light-dark(#0000001f, #ffffff1c); }
.particion.unida .muro { width: 0; opacity: 0; }

/* ===== 5. las fotos: el telefono lleno y los satelites alrededor ===== */
.app-fotos { position: absolute; inset: 0; padding: 30px 8px 10px; background: light-dark(#f2f4f9, #12141c); overflow: hidden; }
.vida .foto { position: absolute; width: 27px; height: 27px; border-radius: 5px; border: 1.5px solid light-dark(#ffffffe0, #ffffff24);
  background: linear-gradient(140deg, #8fa8d8, #c9b3d8); box-shadow: 0 4px 9px -5px #000a; transition: all 1s cubic-bezier(.22, 1, .3, 1); }
.vida .foto.dup { opacity: .45; }
.vida .sin-duplicados .foto.dup { opacity: 0; scale: 1.6; filter: blur(3px); }
/* Los satelites viven afuera del aparato: el problema es justamente que las fotos
   no estan en un solo lugar. */
.satelite {
  position: absolute; z-index: 3; display: grid; justify-items: center; gap: 5px;
  font-size: .6rem; letter-spacing: .04em; color: var(--muted);
  transition: opacity 700ms ease, transform 900ms cubic-bezier(.22, 1, .3, 1);
}
.satelite-caja {
  width: 54px; height: 38px; border-radius: 7px; position: relative;
  background: linear-gradient(150deg, light-dark(#d9dde8, #3b3f52), light-dark(#b7bdcd, #262936));
  box-shadow: 0 10px 20px -12px #000b, inset 0 1px 0 #ffffff40;
}
.satelite-caja::after { content: ""; position: absolute; left: 8px; bottom: 7px; width: 22px; height: 3px; border-radius: 9px; background: light-dark(#8f96a8, #6ad39f); }
.satelite.carpeta .satelite-caja { background: linear-gradient(150deg, #7ea8e8, #4a6bb8); border-radius: 3px 9px 7px 7px; }
.satelite.carpeta .satelite-caja::before { content: ""; position: absolute; left: 0; top: -4px; width: 22px; height: 6px; border-radius: 3px 3px 0 0; background: #7ea8e8; }
.satelite.carpeta .satelite-caja::after { display: none; }
.satelite.izq { left: 4%; top: 30%; }
.satelite.der { right: 4%; top: 46%; }
.juntas-todo .satelite { opacity: 0; transform: translateY(14px) scale(.8); }
.foto-suelta { position: absolute; z-index: 3; width: 23px; height: 23px; border-radius: 4px;
  border: 1.5px solid light-dark(#ffffffe0, #ffffff24); background: linear-gradient(140deg, #8fa8d8, #c9b3d8);
  box-shadow: 0 5px 11px -6px #000a; transition: all 1s cubic-bezier(.22, 1, .3, 1); }
.juntas-todo .foto-suelta { opacity: 0; scale: .4; }
.juntar {
  position: absolute; z-index: 7; left: 50%; top: 52%; translate: -50% -50%;
  width: 54px; height: 54px; border-radius: 50%; border: 1px solid var(--canto); cursor: pointer;
  background: light-dark(#ffffffef, #232734ef); color: var(--fg); display: grid; place-items: center;
  box-shadow: 0 14px 28px -14px #000c; transition: all 500ms cubic-bezier(.34, 1.56, .64, 1);
}
.juntar svg { width: 25px; height: 25px; }
.juntar:hover { scale: 1.1; }
.juntas-todo .juntar { opacity: 0; scale: .55; pointer-events: none; }
.nube-lista {
  position: absolute; z-index: 6; left: 50%; bottom: 16px; translate: -50% 0; text-align: center; width: 100%;
  opacity: 0; transition: opacity 700ms ease 700ms; font-size: .76rem; color: var(--muted);
}
.juntas-todo .nube-lista { opacity: 1; }
.precio-chip { display: inline-block; margin-top: 5px; padding: 4px 11px; border-radius: 99px; font-weight: 600;
  background: light-dark(#1d7a5622, #4ce0ac22); color: light-dark(#1d7a56, #4ce0ac); font-size: .78rem; }

/* ===== 6. el remate ===== */
.tienda { position: absolute; inset: 0; display: grid; place-items: center; background: light-dark(#f7f8fc, #191c25); }
.brillo-nuevo {
  position: absolute; width: 150%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, light-dark(#fffc0033, #fffc0022), transparent 60%); filter: blur(22px);
}
.precio-grande { position: relative; z-index: 3; text-align: center; color: light-dark(#1d2233, #e6e9f2); }
.precio-grande b { display: block; font-size: 1.05rem; letter-spacing: -.01em; }
.precio-grande span { display: block; margin-top: 4px; font-size: .6rem; letter-spacing: .1em; text-transform: uppercase; opacity: .5; }
.chispa { position: absolute; width: 9px; height: 9px; opacity: 0; }
.chispa path { fill: light-dark(#d4a900, #fffc00); }
@media (prefers-reduced-motion: no-preference) {
  .al-frente .chispa { animation: chispear 2.4s ease-in-out infinite; }
  .al-frente .chispa:nth-child(2) { animation-delay: .8s } .al-frente .chispa:nth-child(3) { animation-delay: 1.6s }
  @keyframes chispear { 0%, 100% { opacity: 0; scale: .4 } 50% { opacity: 1; scale: 1.25 } }
}
/* ponytail-keep: acá habia un tachon con la X de la marca cruzando el aparato.
   Dos problemas: tachar con el propio logo lo vuelve el simbolo del "no", y el
   gesto entero era negativo. Ahora la etiqueta se cae y la MISMA maquina aparece
   funcionando, que es el argumento de verdad: no comprás otra, ésta anda. */
.vida .tienda, .vida .reparada {
  position: absolute; inset: 0;
  transition: opacity 620ms ease, transform 780ms cubic-bezier(.22, 1, .3, 1);
}
.vida .reparada {
  display: flex; flex-direction: column; opacity: 0; transform: scale(1.04);
  background: linear-gradient(145deg, light-dark(#5b6ea8, #1b2a4a), light-dark(#8e7aa8, #3a2a4d));
}
.reparada-nota {
  margin: auto; text-align: center; color: #fff; text-shadow: 0 2px 7px #0009; padding: 0 18px;
}
.reparada-nota b { display: block; font-size: .92rem; }
.reparada-nota span { font-size: .64rem; opacity: .82; }
.escenario[data-escena="remate"].reparado .tienda { opacity: 0; transform: scale(.94); }
.escenario[data-escena="remate"].reparado .reparada { opacity: 1; transform: none; }



/* ---- movimiento reducido ---- */
@media (prefers-reduced-motion: reduce) {
  .vida *, .vida *::before, .vida *::after { transition: none !important; animation: none !important; }
  .paso-texto > *, .paso-vineta { opacity: 1; transform: none; }
  .escenario[data-escena="remate"]:not(.reparado) .etiqueta-precio { opacity: 1; }
}

/* ---- telefono ---- */
@media (max-width: 900px) {
  .vida-pista { grid-template-columns: 1fr; }
  .vida-escena { position: sticky; top: 66px; z-index: 4; order: -1; margin-bottom: 24px; }

  /* ponytail-keep: el fondo del escenario fijo no es la caja que sacamos. Acá arriba
     el aparato queda clavado y el texto le pasa por debajo, y sin nada opaco se leian
     encimados el titular de un sintoma y el dibujo del otro. Va a sangre y sin bordes
     ni esquinas redondeadas justamente para que no vuelva a leerse como tarjeta, y se
     desvanece abajo para que el texto no salga cortado con un filo. */
  .vida-escena::before {
    content: ""; position: absolute; z-index: -1; pointer-events: none;
    top: -78px; bottom: 0; left: 50%; width: 100vw; transform: translateX(-50%);
    background: light-dark(#edf1f8f2, #090e1bf2);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 30px), transparent);
            mask-image: linear-gradient(to bottom, #000 calc(100% - 30px), transparent);
  }
  /* ponytail-keep: nada de overflow-x aca. Lo habia puesto para contener el 100vw
     del fondo, y lo que hacia era recortarlo justo a el: clip corta en la caja de
     .vida, que mide lo que el envoltorio, asi que el fondo a sangre quedaba con
     margenes a los costados y volvia a leerse como panel flotante. Lo que evita el
     desborde lateral es el min-width 0 de las columnas, no un recorte. */

  /* ponytail-keep: min-width 0 en las dos columnas. Una pista de grilla 1fr no baja
     del ancho minimo de su contenido, y la laptop mide 438: con el minimo automatico
     estiraba la grilla entera a 438 adentro de un envoltorio de 335, el dibujo salia
     descentrado y el texto se iba por el costado. El overflow-x:clip tapaba la prueba
     en vez de arreglarlo. */
  .vida-pista, .vida-texto, .vida-escena { min-width: 0; }

  /* El escenario fijo ocupa 400px + los 66 de la barra: sin esto, al tocar un
     sintoma de la barra el paso aterriza justo debajo del aparato y no se ve. */
  .paso { scroll-margin-top: 60vh; }

  /* ponytail-keep: nada de scale en el telefono. Escalar el aparato achica tambien
     su letra, y la barra del sistema es de 10px: a .7 quedaba en 7 y no se leia.
     En vez de achicar, la laptop ocupa todo el ancho y el alto sale del aspecto. */
  .escenario { height: 400px; --k: 1; }
  /* El que llega a los bordes es el contenedor, no el dibujo: a ras del envoltorio
     el aparato se lee como recortado, le falta aire a los costados. */
  .aparato {
    --ancho: calc(100% - 30px); width: calc(100% - 30px); height: auto;
    aspect-ratio: 438 / 274; max-width: calc(100% - 30px);
  }
  .aparato[data-aparato="telefono"] {
    /* El telefono se queda angosto: a todo el ancho quedaria de 634px de alto. */
    --ancho: 196px; width: 196px; aspect-ratio: 196 / 371;
  }
  /* La base se desborda a los costados por diseño; acá tiene que caber en la pantalla. */
  .base { width: calc(100% + 26px); }
  .paso { min-height: 44vh; }
  .lengueta { font-size: .68rem; padding: 8px 3px; }
  .lengueta span:not(.num) { display: none; }
  .lengueta .num { display: inline; }
  /* El fondo va en la fila entera y no en cada boton: con los huecos de 7px entre
     lenguetas el titular igual se colaba por el medio. */
  .lenguetas {
    position: relative; z-index: 2; padding-bottom: 8px;
    background: light-dark(#f4f1f6e8, #11151fe8);
    backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  }
  .lengueta { background: light-dark(#ffffffcc, #ffffff10); }
}

/* ===== los iconos que acompañan cada titular ==============================
   Linea, un solo color, 52px y un unico detalle que se mueve. Con relleno y
   varios colores competirian con el aparato de la derecha y quedarian de
   calcomania; asi acompañan al texto sin pelearle. */
.vineta {
  width: 42px; height: 42px; overflow: visible;
  color: var(--tinte, var(--muted)); stroke: currentColor; fill: none;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
  transition: color 600ms ease;
}
.vineta .relleno { fill: currentColor; stroke: none; }
.paso[data-paso="chat"]       { --tinte: light-dark(#4356c9, #8f9cf0) }
.paso[data-paso="disco"]      { --tinte: light-dark(#c2371f, #ff8a6d) }
.paso[data-paso="antivirus"]  { --tinte: light-dark(#c2371f, #ff8a6d) }
.paso[data-paso="particion"]  { --tinte: light-dark(#4356c9, #a9b2f0) }
.paso[data-paso="fotos"]      { --tinte: light-dark(#6b4a8f, #c9a8e8) }
.paso[data-paso="remate"]     { --tinte: light-dark(#a8850b, #fffc00) }

@media (prefers-reduced-motion: no-preference) {
  /* El detalle se mueve solo en el paso que estas leyendo, no en los seis a la vez. */
  .paso.activo .humito { animation: humear 3.1s ease-out infinite; }
  .paso.activo .humito:nth-of-type(2) { animation-delay: 1s }
  .paso.activo .humito:nth-of-type(3) { animation-delay: 2s }
  @keyframes humear {
    0%   { opacity: 0; transform: translate(0, 0) scale(.5) }
    28%  { opacity: .85 }
    100% { opacity: 0; transform: translate(4px, -13px) scale(1.5) }
  }
  .paso.activo .rebalsa { animation: rebalsar 2.4s ease-in-out infinite; }
  @keyframes rebalsar { 0%, 100% { transform: translateY(0) } 50% { transform: translateY(-3px) } }
  .paso.activo .late { animation: latir 2.2s ease-in-out infinite; transform-origin: center; transform-box: fill-box; }
  @keyframes latir { 0%, 100% { transform: scale(1) } 50% { transform: scale(1.09) } }
  .paso.activo .vuela { animation: volar-foto 3s ease-in-out infinite; transform-box: fill-box; }
  @keyframes volar-foto { 0%, 100% { transform: translate(0, 0) rotate(0) } 50% { transform: translate(5px, -4px) rotate(9deg) } }
}

/* Las fotos sueltas se ubican contra el escenario entero, no contra la pantalla:
   estan fuera del telefono porque ese es justamente el problema. */
.fuera-de-pantalla { position: absolute; inset: 0; z-index: 3; pointer-events: none; }


/* =============================================================================
   SEGUNDA VIDA
   La columna de texto es un recorrido: un hilo une los seis pasos y se va
   llenando con los colores de la historia. Cada nodo tiene una viñeta con dos
   estados, y cuando se arregla algo en el aparato, el dibujo de al lado tambien
   se cura. Y cada escena gana su mundo: papelera, bandeja del sistema, pared que
   se raja, nube que sincroniza, etiqueta colgada de un hilo.
   ============================================================================= */

/* ---- el recorrido ---- */
.vida-texto { position: relative; }
.hilo {
  position: absolute; left: 27px; width: 2px; top: 0; height: 0; border-radius: 2px; pointer-events: none;
  background: repeating-linear-gradient(to bottom, light-dark(#00000024, #ffffff24) 0 5px, transparent 5px 10px);
}
/* El degradado mide el hilo entero y no lo que esta lleno: asi el relleno va
   descubriendo los colores de la historia a medida que avanza, en vez de
   estirar los cuatro colores en el tramo que haya. */
.hilo-lleno {
  position: absolute; left: 0; top: 0; width: 100%; height: var(--lleno, 0px); border-radius: inherit;
  background: linear-gradient(to bottom,
    light-dark(#4356c9, #8f9cf0), light-dark(#c2371f, #ff8a6d) 30%,
    light-dark(#4356c9, #a9b2f0) 58%, light-dark(#6b4a8f, #c9a8e8) 78%, light-dark(#a8850b, #fffc00));
  background-size: 100% var(--hilo-total, 100%);
  transition: height 800ms cubic-bezier(.22, 1, .3, 1);
}

.paso-vineta {
  position: relative; z-index: 1; align-self: start;
  width: 56px; height: 56px; border-radius: 17px; display: grid; place-items: center;
  background: var(--cristal); border: 1px solid var(--canto);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 10px 24px -18px #000a;
}
.paso.activo .paso-vineta {
  border-color: color-mix(in srgb, var(--tinte) 55%, transparent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--tinte) 14%, transparent), 0 10px 24px -18px #000a;
}
.paso.resuelto .paso-vineta { border-color: light-dark(#1d7a5680, #4ce0ac66); }
.paso.resuelto .vineta { color: light-dark(#1d7a56, #4ce0ac); }
.paso-texto { min-width: 0; }

/* Los dos estados de la viñeta: lo roto se infla y se va, lo sano entra con rebote. */
.vineta .antes, .vineta .despues {
  transform-box: view-box; transform-origin: 50% 50%;
  transition: opacity 450ms ease, transform 700ms cubic-bezier(.34, 1.56, .64, 1);
}
.vineta .despues { opacity: 0; transform: scale(.55); }
.paso.resuelto .vineta .antes { opacity: 0; transform: scale(1.35); }
.paso.resuelto .vineta .despues { opacity: 1; transform: none; }

/* La linea de resultado: esta en el DOM desde el principio, asi un lector de
   pantalla escucha el desenlace aunque no pueda jugar; a la vista aparece recien
   cuando el sintoma se arregla. */
.paso p.paso-resultado {
  display: flex; gap: 8px; align-items: baseline; margin: 0; max-height: 0; opacity: 0; overflow: hidden;
  color: light-dark(#1d7a56, #4ce0ac); font-weight: 600;
  transition: max-height 600ms cubic-bezier(.22, 1, .3, 1), opacity 500ms ease 120ms, margin 600ms ease;
}
.paso-resultado::before { content: "→"; flex: none; }
.paso.resuelto p.paso-resultado { max-height: 5em; opacity: 1; margin-top: 12px; }

@media (prefers-reduced-motion: no-preference) {
  .paso.activo .columpio { animation: columpio-vineta 2.4s ease-in-out infinite alternate; transform-box: view-box; transform-origin: 50% 8%; }
  @keyframes columpio-vineta { from { transform: rotate(-7deg) } to { transform: rotate(6deg) } }
}

/* ---- vida de fondo: motas en la luz y el aparato que flota apenas ---- */
.motas { position: absolute; inset: 8% 6%; z-index: 1; pointer-events: none; }
.motas i {
  position: absolute; bottom: 0; width: 3px; height: 3px; border-radius: 50%; opacity: 0;
  background: color-mix(in srgb, var(--acento) 55%, white);
  box-shadow: 0 0 7px color-mix(in srgb, var(--acento) 70%, transparent);
  transition: background 900ms ease, box-shadow 900ms ease;
}
.motas i:nth-child(1) { left: 8% }  .motas i:nth-child(2) { left: 21% }
.motas i:nth-child(3) { left: 34% } .motas i:nth-child(4) { left: 47% }
.motas i:nth-child(5) { left: 60% } .motas i:nth-child(6) { left: 72% }
.motas i:nth-child(7) { left: 84% } .motas i:nth-child(8) { left: 93% }
@media (prefers-reduced-motion: no-preference) {
  .motas i { animation: mota 10s linear infinite; }
  .motas i:nth-child(2) { animation-duration: 12s; animation-delay: -4s }
  .motas i:nth-child(3) { animation-duration: 9s;  animation-delay: -7s }
  .motas i:nth-child(4) { animation-duration: 13s; animation-delay: -2s }
  .motas i:nth-child(5) { animation-duration: 11s; animation-delay: -9s }
  .motas i:nth-child(6) { animation-duration: 10s; animation-delay: -5s }
  .motas i:nth-child(7) { animation-duration: 14s; animation-delay: -11s }
  .motas i:nth-child(8) { animation-duration: 9s;  animation-delay: -1s }
  @keyframes mota {
    0%   { opacity: 0;  translate: 0 0 }
    15%  { opacity: .75 }
    50%  { translate: 12px -170px }
    85%  { opacity: .45 }
    100% { opacity: 0;  translate: -6px -340px }
  }
  .aparato { animation: flotar 6s ease-in-out infinite alternate; }
  @keyframes flotar { from { translate: 0 2px } to { translate: 0 -5px } }
}

/* ---- 1. el chat: tildes y "escribiendo…" ---- */
.tildes {
  width: 13px; height: 8px; margin-left: 3px; vertical-align: -1px; display: none;
  fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
  transition: color 300ms ease;
}
.burbuja[data-tildes] .tildes { display: inline-block; }
.burbuja[data-tildes="1"] .tildes path:nth-child(2) { display: none; }
/* El globo del cliente ya es azul: el tilde de leido azul no se veria. Va celeste
   casi blanco, y la linea de la hora se enciende entera, como en el telefono. */
.burbuja[data-tildes="leido"] .tildes { color: #8ff0ff; }
.burbuja[data-tildes="leido"] .hora { opacity: .95; }
.chat-quien small { transition: color 300ms ease; }
.chat-quien small.escribe { color: light-dark(#2f6df0, #7fb3ff); }

/* ---- 2. el disco: papelera, bollos y el lugar que se libera ---- */
.disco-barra { position: relative; }
/* La franja libre crece desde la derecha a medida que se borra. --libre es la
   fraccion borrada; el 10px es el padding de la barra, que no es disco. */
.disco-barra::after {
  content: "libre"; position: absolute; top: 5px; bottom: 5px; right: 5px;
  width: calc((100% - 10px) * var(--libre, 0)); border-radius: 4px; opacity: 0;
  display: grid; place-items: center; overflow: hidden; white-space: nowrap;
  font-size: 0; letter-spacing: .14em; text-transform: uppercase; font-weight: 700;
  color: light-dark(#1d7a56, #4ce0ac);
  background: repeating-linear-gradient(-45deg, light-dark(#1d7a5622, #4ce0ac1f) 0 4px, transparent 4px 8px);
  box-shadow: inset 0 0 0 1px light-dark(#1d7a5655, #4ce0ac44);
  transition: width 460ms cubic-bezier(.34, 1.3, .64, 1), opacity 300ms ease;
}
.disco-barra.con-libre::after { opacity: 1; }
:lang(en) .disco-barra::after { content: "free"; }
/* La palabra entra recien cuando hay lugar: en 12px mostraba "IBR" cortado. */
.disco-barra.libre-ancho::after { font-size: 8.5px; }

.alerta-ico { width: 11px; height: 11px; vertical-align: -1.5px; margin-right: 4px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
@media (prefers-reduced-motion: no-preference) {
  .disco:not(.disco-ok) .disco-barra { animation: alarma 1.9s ease-in-out infinite; }
  @keyframes alarma {
    0%, 100% { box-shadow: 0 0 0 0 #e2624a00 }
    50%      { box-shadow: 0 0 0 2px #e2624a40, 0 0 18px -3px #e2624a70 }
  }
  .disco:not(.disco-ok) .alerta-ico { animation: parpadeo 1.4s ease-in-out infinite; }
  @keyframes parpadeo { 50% { opacity: .35 } }
}

.tacho {
  position: absolute; right: 12px; bottom: 11px; z-index: 3; width: 25px; height: 25px;
  color: light-dark(#5a6072, #99a0b5);
}
.tacho svg { width: 100%; height: 100%; overflow: visible; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.tacho-tapa { transform-box: fill-box; transform-origin: 0% 100%; }
@media (prefers-reduced-motion: no-preference) {
  /* El rojo va adentro de la animacion y no en la clase: como clase quedaba pegado
     despues del ultimo bollo, y la papelera ya vaciada seguia en alarma. */
  .tacho.traga { animation: enrojecer 420ms ease-out; }
  @keyframes enrojecer { 25%, 55% { color: light-dark(#c2371f, #ff8a6d) } }
  .tacho.traga .tacho-tapa { animation: tragar 420ms cubic-bezier(.34, 1.56, .64, 1); }
  @keyframes tragar { 30% { transform: rotate(-40deg) translate(-1px, -2px) } }
  .tacho.traga svg { animation: sacudon 420ms ease-out; }
  @keyframes sacudon { 45% { transform: translateY(1.5px) scaleY(.94) } }
}
.tacho-cuenta {
  position: absolute; top: -6px; right: -8px; min-width: 15px; height: 15px; padding: 0 4px; border-radius: 99px;
  display: grid; place-items: center; font-size: 8.5px; font-weight: 700; color: #fff; background: #e2624a;
  font-variant-numeric: tabular-nums; box-shadow: 0 2px 6px -1px #0006;
  scale: 0; transition: scale 320ms cubic-bezier(.34, 1.56, .64, 1);
}
.tacho-cuenta.hay { scale: 1; }
/* El bollo de papel: una mancha irregular con brillo, no un circulo perfecto. */
.bollo {
  position: absolute; z-index: 4; width: 11px; height: 10px; margin: -5px 0 0 -5.5px; pointer-events: none;
  border-radius: 45% 55% 50% 50% / 52% 44% 56% 48%;
  background: radial-gradient(circle at 34% 30%, #ffffffaa, transparent 42%), light-dark(#e2624a, #c9553e);
  box-shadow: inset -1.5px -1.5px 2px #0005, 0 3px 5px -2px #0007;
}
.pizca { position: absolute; z-index: 4; width: 4px; height: 4px; margin: -2px 0 0 -2px; border-radius: 50%; pointer-events: none; background: light-dark(#8f96a8, #aab0c0); }

/* ---- 3. el antivirus: escaneo eterno, cuenta regresiva, bandeja ---- */
.escaneo { display: block; height: 4px; margin-top: 7px; border-radius: 99px; overflow: hidden; background: light-dark(#0000001a, #ffffff1a); }
.escaneo i { display: block; height: 100%; border-radius: inherit; background: light-dark(#e2624a, #ff6b4d); transform-origin: 0 50%; transform: scaleX(.97); }
.escaneo-txt { display: block; margin-top: 3px; font-size: .54rem; opacity: .65; }
/* .popup b es display block para el titulo del cartel, y la cuenta regresiva es otro
   b: sin esto se iba a su propio renglon y el cartel crecia una linea. */
.popup .cuenta-atras { display: inline; font-size: inherit; margin: 0; font-variant-numeric: tabular-nums; font-weight: 700; color: light-dark(#c2371f, #ff8a6d); }
@media (prefers-reduced-motion: no-preference) {
  /* Llega a 97 y vuelve a cero: el escaneo de estos programas no termina nunca. */
  .escaneo i { animation: escanear 3.4s cubic-bezier(.2, .8, .3, 1) infinite; }
  @keyframes escanear { 0% { transform: scaleX(0) } 68%, 90% { transform: scaleX(.97) } 100% { transform: scaleX(0) } }
  /* Cada cartel que vuelve llega un poco mas nervioso que el anterior. */
  .popup.insiste { animation: brotar 380ms cubic-bezier(.34, 1.56, .64, 1), temblar 460ms ease-in-out 380ms; }
  @keyframes temblar {
    15% { transform: rotate(-3deg) } 30% { transform: rotate(3deg) }
    45% { transform: rotate(-2deg) } 60% { transform: rotate(1.5deg) } 75%, 100% { transform: none }
  }
  .pagar.ruega { animation: rogar 1.7s ease-in-out infinite; }
  @keyframes rogar {
    0%, 66%, 100% { transform: none } 72% { transform: rotate(-5deg) scale(1.06) }
    78% { transform: rotate(5deg) scale(1.06) } 84% { transform: rotate(-3deg) } 90% { transform: rotate(2deg) }
  }
}
.bandeja { display: flex; align-items: center; gap: 7px; }
.bandeja i { width: 11px; height: 12px; display: grid; place-items: center; transition: opacity 400ms ease, translate 520ms cubic-bezier(.34, 1.56, .64, 1); }
.bandeja svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }
.trampa { color: #e2624a; }
.defensor { color: light-dark(#1d7a56, #4ce0ac); opacity: 0; translate: 0 7px; }
.defensor svg { fill: currentColor; }
.rendido .trampa { opacity: 0; translate: 0 -8px; }
.rendido .defensor { opacity: 1; translate: 0 0; transition-delay: 350ms; }
.reparada .trampa { display: none; }
.reparada .defensor { opacity: 1; translate: 0 0; }
@media (prefers-reduced-motion: no-preference) {
  .escritorio:not(.rendido) .trampa { animation: latido-rojo 1.2s ease-in-out infinite; }
  @keyframes latido-rojo { 50% { transform: scale(1.25); filter: drop-shadow(0 0 3px #e2624a) } }
}
.escudo-caja { position: relative; display: block; width: 34px; height: 34px; margin: 0 auto 7px; }
.escudo-caja .escudo-ok { color: light-dark(#c9f5e3, #4ce0ac); }
.anillo { position: absolute; inset: -5px; border-radius: 50%; border: 2px solid #4ce0ac; opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .rendido .escudo-caja { animation: subir-escudo 720ms cubic-bezier(.34, 1.56, .64, 1) 200ms both; }
  @keyframes subir-escudo { from { transform: translateY(48px) scale(.4); opacity: 0 } }
  .rendido .anillo { animation: onda 1.3s ease-out 700ms 2; }
  @keyframes onda { from { opacity: .95; transform: scale(.7) } to { opacity: 0; transform: scale(2.2) } }
}

/* ---- 4. la particion: la pared se raja, se cae, y los datos cruzan ---- */
.particion { position: relative; }
.grieta {
  position: absolute; inset: 3px 0; width: 100%; height: calc(100% - 6px); pointer-events: none;
  fill: none; stroke: light-dark(#1d2233, #fff); stroke-width: 1.4; stroke-linejoin: round; stroke-linecap: round;
  vector-effect: non-scaling-stroke; stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0;
}
.particion.agrietada .grieta { opacity: .9; stroke-dashoffset: 0; transition: stroke-dashoffset 220ms ease-out; }
.particion.rota .muro { opacity: 0; transition: opacity 60ms linear, width 700ms cubic-bezier(.22, 1, .3, 1); }
.pedazo {
  position: absolute; z-index: 5; border-radius: 1.5px; pointer-events: none;
  background: repeating-linear-gradient(45deg, light-dark(#0000004d, #ffffff4d) 0 2px, light-dark(#00000026, #ffffff26) 2px 4px);
}
.dato {
  position: absolute; z-index: 5; width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; border-radius: 1.5px; pointer-events: none;
  background: light-dark(#7d8bc4, #8f9cf0); box-shadow: 0 0 6px light-dark(#7d8bc488, #8f9cf099);
}

/* ---- 5. las fotos: vagan, vuelan en arco, la nube sincroniza ---- */
@media (prefers-reduced-motion: no-preference) {
  .foto-suelta { animation: vagar var(--d, 4s) ease-in-out var(--r, 0s) infinite alternate; }
  @keyframes vagar { from { translate: 0 0; rotate: -5deg } to { translate: 3px -7px; rotate: 5deg } }
}
.juntar .sincro { display: none; }
.juntar.sincroniza .nube-ico { display: none; }
.juntar.sincroniza .sincro { display: block; }
.juntar.sincroniza { color: light-dark(#1d7a56, #4ce0ac); }
@media (prefers-reduced-motion: no-preference) {
  .juntar.sincroniza .sincro { animation: girar 850ms linear infinite; }
  @keyframes girar { to { rotate: 360deg } }
}

/* ---- 6. el remate: vidriera, etiqueta colgada, y la misma maquina despierta ---- */
.tienda { overflow: hidden; }
.tienda::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; translate: -120% 0;
  background: linear-gradient(105deg, transparent 35%, light-dark(#ffffffa0, #ffffff24) 50%, transparent 65%);
}
@media (prefers-reduced-motion: no-preference) {
  .ficha.al-frente .tienda::after { animation: vidriera 3.4s ease-in-out 700ms infinite; }
  @keyframes vidriera { 0% { translate: -120% 0 } 45%, 100% { translate: 120% 0 } }
}
/* La etiqueta cuelga de un hilo desde el borde del aparato y se columpia sobre
   ese punto. El giro sale del transform-origin, que esta arriba del todo. */
.etiqueta-precio {
  position: absolute; z-index: 9; right: 18px; top: -3px; padding-top: 20px;
  transform-origin: 50% 0; pointer-events: none; opacity: 0; transition: opacity 400ms ease;
}
.etiqueta-precio::before {
  content: ""; position: absolute; left: 50%; top: 0; width: 1px; height: 22px; translate: -50% 0;
  transform-origin: 50% 0; background: light-dark(#7d8394, #aab0c0);
}
.etiqueta-cuerpo {
  position: relative; display: block; white-space: nowrap;
  padding: 7px 11px 5px; border-radius: 7px 7px 9px 9px;
  font-weight: 700; font-size: .8rem; font-variant-numeric: tabular-nums;
  background: light-dark(#fff, #262a36); border: 1px solid var(--canto); box-shadow: 0 12px 26px -14px #000b;
}
/* El ojalito por donde pasa el hilo. */
.etiqueta-cuerpo::before {
  content: ""; position: absolute; left: 50%; top: 3px; width: 4px; height: 4px; translate: -50% 0;
  border-radius: 50%; background: light-dark(#d9dce4, #12141c); box-shadow: inset 0 0 0 1px light-dark(#b9bdc9, #3a3e4c);
}
.escenario[data-escena="remate"] .etiqueta-precio { opacity: 1; transition-delay: 250ms; }
.escenario[data-escena="remate"].reparado .etiqueta-precio { opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .escenario[data-escena="remate"]:not(.reparado) .etiqueta-precio { animation: columpio 2.6s ease-in-out infinite alternate; }
  @keyframes columpio { from { rotate: -7deg } to { rotate: 6deg } }
  /* Se corta el hilo, pega un saltito y cae girando: nadie la compro. */
  .escenario[data-escena="remate"].reparado .etiqueta-precio { opacity: 1; animation: descolgar 950ms cubic-bezier(.5, 0, .8, .35) forwards; }
  .escenario[data-escena="remate"].reparado .etiqueta-precio::before { animation: cortar 160ms ease-in forwards; }
  @keyframes descolgar {
    0%   { rotate: 0deg;  translate: 0 0;       opacity: 1 }
    12%  { rotate: -4deg; translate: 0 -5px }
    75%  { opacity: 1 }
    100% { rotate: 42deg; translate: 22px 190px; opacity: 0 }
  }
  @keyframes cortar { to { transform: scaleY(.1); opacity: 0 } }
  /* La maquina reparada no aparece: se enciende, con el fogonazo de una pantalla que despierta. */
  .escenario[data-escena="remate"].reparado .reparada { animation: despertar 800ms ease-out; }
  @keyframes despertar { 0% { filter: brightness(2.4) saturate(.3) } 100% { filter: none } }
}

/* ---- telefono ---- */
@media (max-width: 900px) {
  /* ponytail-keep: medidas contadas. La laptop del telefono mide 305x191, y sacando
     la barra del sistema y la de la ventana le quedan unos 143px de alto a la
     ventana de Almacenamiento. Con el padding y los huecos de escritorio el
     contenido pedia 148: el justify-content center lo recortaba arriba y abajo, y
     se perdian los GB libres y la alerta, que son justo el punto de la escena. */
  .ventana-cuerpo { padding: 10px 14px; gap: 8px; }
  .disco-barra { min-height: 32px; padding: 4px; }
  .disco-leyenda { gap: 9px; font-size: .56rem; }
  .disco-libre { font-size: .72rem; }
  .tacho { width: 21px; height: 21px; right: 9px; bottom: 8px; }
  /* El escritorio del telefono tiene 148px de alto con la barra de tareas adentro,
     y el primer cartel, con su escaneo, media 126: se salia por abajo al torcerse. */
  .popup.con-escudo { width: 84%; padding: 7px 9px 7px 29px; font-size: .62rem; }
  .popup b { font-size: .66rem; }
  .popup .escudo { left: 8px; top: 8px; width: 14px; height: 15px; }
  .popup .pagar { margin-top: 5px; padding: 3px 8px; font-size: .58rem; }
  .escaneo { margin-top: 5px; }
  .escaneo-txt { display: none; }

  .paso { grid-template-columns: 46px minmax(0, 1fr); gap: 0 16px; }
  .paso-vineta { width: 46px; height: 46px; border-radius: 14px; }
  .vineta { width: 34px; height: 34px; }
  .hilo { left: 22px; }
}
