/*
  Demos ópticas (Tarea 12): el enfoque del examen de la vista, el polarizado de las gafas de sol y la lupa de las lentillas. El marcado está
  en parts/demo-enfoque.php, demo-polarizado.php y demo-lupa.php, que pide el contenido con [ole_demo tipo="…"] (inc/wp/atajos.php); este
  CSS y los scripts de assets/js/demos/ solo se cargan en las páginas que llevan una demo (inc/wp/recursos.php).

  Cada demo es una tarjeta gris (.demo) con su rótulo (.etq, de base.css, y un punto del color de su servicio: examen azul, lentillas lima y
  gafas de sol sol), lo que se prueba y, debajo, la ayuda (.demo__pie). Se ven solo con JavaScript (la clase js de <html>): sin él no
  podrían hacer nada; y si el script de una demo no llega, su etiqueta quita la clase js (recursos.php) y se esconden.

  El enfoque copia del planteamiento (planteamiento/index.html: .optotipo, .pregunta, .op y .estado) el texto desenfocado y los botones
  redondos 1 y 2. El polarizado, el mar dibujado con degradados y dos recortes (montañas y playa), los destellos que titilan y la lente: la
  misma escena sin destellos, más oscura y saturada, recortada con una elipse. La lupa es nueva: la lente es un círculo (clip-path: circle())
  sobre una copia del texto a escala 1,6 desde el centro de la lente.

  La lente. lente.js pone en la escena --x, --y, --rx y --ry (px) y la clase escena--lista; todo lo demás es CSS. Antes de eso la lente no
  tiene tamaño y el aro está oculto. La escena deja desplazar la página con el dedo y ampliarla con el pellizco (touch-action: pan-y
  pinch-zoom, y con la página ya ampliada, también pan-x: ver .escena--ampliada) y la lente se agarra con el dedo (el aro, con
  touch-action: none, es el asa; con un ratón no se agarra nada: la lente sigue al puntero sin pulsar y el aro no recoge los clics, para
  poder seleccionar el texto de la lupa); la escena recibe el foco del teclado y se mueve con las flechas.

  Colores. Texto en --ink y --ink2 (nunca --ink3 en texto pequeño). Sol y Lima, siempre con texto oscuro: aquí solo son el punto del rótulo y
  el mar, que no llevan texto.

  Movimiento. Cada animación es un fenómeno óptico real (DESIGN.md §6): el texto que se aclara y los destellos del sol en el agua que titilan.
  Lo que se mueve solo no tiene botón de pausa, así que (WCAG 2.2.2) dura 5 s como mucho, contados desde que la escena entra en pantalla:
  los destellos titilan solo mientras la escena lleva la clase escena--en-marcha, que pone y quita lente.js, y después quedan congelados.
  Con prefers-reduced-motion: reduce, todo quieto: base.css deja las transiciones en casi cero (el texto cambia de golpe), aquí los
  destellos se quedan fijos y lente.js deja la lente quieta; seguir al puntero, al dedo o a las flechas no es una animación (lo mueve quien
  lo usa) y va directo, sin suavizado, transición ni inercia, con o sin esa preferencia.
*/

/* ---------------------------------------------------------- la tarjeta */
.demo {
  --c: var(--azul);
  display: none;
  max-width: 46rem;
  padding: 28px;
  border-radius: var(--r);
  background: var(--cal2);
}

.js .demo {
  display: block;
}

.demo--polarizado { --c: var(--sol); }
.demo--lupa { --c: var(--lima); }

.demo__etq {
  margin-bottom: 18px;
}

.demo__etq::before {
  content: "";
  display: inline-block;
  width: .75rem;
  height: .75rem;
  margin-right: .7em;
  border-radius: 50%;
  background: var(--c);
  vertical-align: -.05em;
}

.demo__pie {
  margin: 0;
  color: var(--ink2);
  font-size: .9375rem;
  line-height: 1.5;
}

@media (max-width: 800px) {
  .demo {
    padding: 20px;
  }
}

/* ---------------------------------------------------------- enfoque */
.demo__optotipo {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 190px;
  margin-bottom: 20px;
  padding: 26px;
  overflow: hidden;
  border-radius: 16px;
  background: var(--cal);
  text-align: center;
}

/* La frase que se enfoca. El desenfoque de la primera ronda sale de --desenfoque, que la parte pone en la demo con la misma cifra que le
   da al script (OLE_DEMO_DESENFOQUE, inc/logica/demos.php): así el primer pintado ya sale desenfocado y no salta al llegar el script, que
   después cambia el filtro con un filter en línea. */
.demo__texto {
  margin: 0;
  font-size: clamp(1.625rem, 3vw, 2.375rem);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.1;
  overflow-wrap: break-word;
  text-wrap: balance;
  filter: blur(var(--desenfoque));
  transition: filter .35s ease;
}

.demo__pregunta {
  min-height: 1.6em;
  margin: 0 0 14px;
  font-size: 1.3125rem;
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.3;
}

.demo__acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 14px;
  margin-bottom: 20px;
}

.demo__ops {
  display: flex;
  gap: 12px;
}

.demo__ops[hidden],
.demo__otra[hidden] {
  display: none;
}

.demo__op {
  width: 66px;
  height: 66px;
  padding: 0;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  font: 800 1.625rem/1 var(--f);
  cursor: pointer;
  transition: background .2s, color .2s;
}

/* Con el foco del teclado (:focus-visible, no el de un clic) el botón se rellena de tinta, como con el ratón encima: es la opción que se
   está mirando. El anillo de base.css va además. El :hover, solo con un puntero que pasa por encima (con el dedo se queda pegado). */
.demo__op:focus-visible {
  background: var(--ink);
  color: #fff;
}

@media (hover: hover) {
  .demo__op:hover {
    background: var(--ink);
    color: #fff;
  }
}

.demo__estado {
  margin: 0 0 0 auto;
  color: var(--ink2);
  font-size: .875rem;
}

/* ---------------------------------------------------------- la escena de la lente */
/* Compartida por el polarizado (.escena--mar) y la lupa (.escena--lupa). Capas, de abajo arriba: el fondo (.escena__fondo), la lente
   (.escena__lente, recortada con la forma de la lente) y el aro (.escena__montura). */
.escena {
  --x: 50%;
  --y: 50%;
  --rx: 0px;
  --ry: 0px;
  position: relative;
  margin-bottom: 16px;
  overflow: hidden;
  border-radius: 16px;
  touch-action: pan-y pinch-zoom;       /* el dedo desplaza la página en vertical y el pellizco amplía, por encima de la escena */
  -webkit-tap-highlight-color: transparent;
}

/* La página ampliada con el pellizco se desplaza también a los lados. lente.js pone esta clase mientras la página está ampliada
   (visualViewport.scale > 1): con solo pan-y, quien ampliaba la página no podía moverse en horizontal con un gesto que empezara sobre la
   escena. Con la página a su tamaño no se pide: el navegador se quedaría los arrastres en horizontal aunque no hubiera nada que desplazar,
   y la lente, que un dedo arrastra en horizontal sin problema, dejaría de seguirlos. */
.escena--ampliada {
  touch-action: pan-x pan-y pinch-zoom;
}

/* La lente va directa adonde la lleva quien la mueve: sin transición. Sin esta regla, con «reducir movimiento» (base.css deja las duraciones en
   .01ms, no en 0) cada cambio de --x o de --y crearía una transición de .01ms sobre left, top, clip-path o transform-origin: no se vería,
   pero seguiría siendo una animación en marcha. */
.escena__lente,
.escena__aumento,
.escena__montura {
  transition-property: none;
}

/* La capa de la lente no recoge ni punteros ni selección: lo que se ve a través de ella (la copia agrandada del texto de la lupa) es una
   copia, y el texto de verdad, el de debajo, se puede seleccionar y copiar una sola vez. */
.escena__lente {
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}

/* El aro. Con un ratón la lente sigue al puntero sin pulsar nada: no hay nada que agarrar, así que el aro deja pasar los clics (el texto de
   debajo se puede seleccionar) y el cursor es el de siempre. Si el puntero principal es un dedo (un móvil o una tableta), el aro es el asa:
   recoge el toque y no deja que la página se mueva mientras se arrastra la lente (touch-action: none), y el cursor es el de agarre. Es el puntero
   principal y no «algún puntero grueso» (any-pointer): un portátil con pantalla táctil y ratón tiene los dos, y con el aro recogiéndolo todo se
   tragaba los clics del ratón y no se podía seleccionar el texto de debajo. Lo que agarra la lente no depende de este aro (lente.js decide por
   dónde cae el puntero): un lápiz en un equipo sin táctil, o un dedo en un portátil, la arrastran igual. */
.escena__montura {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: calc(var(--rx) * 2);
  height: calc(var(--ry) * 2);
  translate: -50% -50%;
  border: 5px solid var(--ink);
  border-radius: 50%;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .25);
  pointer-events: none;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  visibility: hidden;
}

@media (pointer: coarse) {
  .escena__montura {
    pointer-events: auto;
    cursor: grab;
  }

  .escena__montura:active {
    cursor: grabbing;
  }
}

.escena--lista .escena__montura {
  visibility: visible;
}

/* ---------------------------------------------------------- polarizado */
.escena--mar {
  /* Los destellos: cuántos hay en la escena más grande y la superficie de esa escena, en px² (polarizado.js reparte los de las demás con la
     misma densidad y recalcula si cambia el tamaño). La superficie es la de la escena más grande de verdad: el ancho útil de la tarjeta,
     46rem menos el relleno de 28px por cada lado (.demo, arriba), que son 680px, por el alto máximo de la escena, 25rem, que son 400px
     (height, abajo). Si cambia alguna de esas medidas, se cambia aquí; la prueba de los destellos comprueba que sigue siendo cierta. */
  --destellos: 120;
  --destellos-area: 272000;
  height: clamp(16rem, 48vw, 25rem);
  user-select: none;
  -webkit-user-select: none;
}

/* El mar: cielo con el sol, horizonte y agua. El fondo y la lente son la misma escena. */
.escena--mar .escena__fondo,
.escena--mar .escena__lente {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 74% 15%, rgba(255, 255, 255, .95) 0, rgba(255, 255, 255, .55) 7%, rgba(255, 255, 255, 0) 24%),
    linear-gradient(to bottom, #b9def0 0%, #e7f5fb 36%, #9ccfe7 36.4%, #3d9bc9 52%, #0f6698 78%, #0a4f7c 100%);
}

.escena--mar :is(.escena__fondo, .escena__lente)::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 22%;
  height: 14.5%;
  background: #8db4c7;
  opacity: .55;
  clip-path: polygon(0 70%, 8% 40%, 16% 55%, 27% 18%, 38% 48%, 47% 30%, 58% 62%, 66% 44%, 75% 70%, 84% 52%, 100% 76%, 100% 100%, 0 100%);
}

.escena--mar :is(.escena__fondo, .escena__lente)::after {
  content: "";
  position: absolute;
  left: -2%;
  bottom: 0;
  width: 24%;
  height: 72%;
  background: #d9c7a5;
  opacity: .95;
  clip-path: polygon(0 0, 40% 6%, 62% 22%, 70% 48%, 100% 100%, 0 100%);
}

/* Los reflejos del sol en el agua: elipses blancas que titilan (los pone polarizado.js, con su tamaño --w, su duración --d y su retraso
   --del). Solo titilan mientras la escena se mueve sola (lleva escena--en-marcha: a la vista y dentro de sus 5 s); fuera de eso, en pausa. */
.destello {
  position: absolute;
  width: var(--w);
  height: calc(var(--w) * .32);
  margin-left: calc(var(--w) * -.5);
  border-radius: 50%;
  background: radial-gradient(ellipse at center, #fff 0, rgba(255, 255, 255, .9) 35%, rgba(255, 255, 255, 0) 72%);
  animation: titila var(--d) ease-in-out var(--del) infinite;
  animation-play-state: paused;
}

.escena--en-marcha .destello {
  animation-play-state: running;
}

@keyframes titila {
  0%, 100% { opacity: .12; scale: .55 1; }
  50% { opacity: 1; scale: 1 1; }
}

/* La lente: la misma escena, sin destellos, más oscura y saturada, recortada con la elipse de la lente. Dentro no hay reflejo. */
.escena--mar .escena__lente {
  filter: saturate(1.45) brightness(.8) contrast(1.12);
  clip-path: ellipse(var(--rx) var(--ry) at var(--x) var(--y));
}

/* ---------------------------------------------------------- lupa */
/* El texto de debajo y su copia agrandada llevan la misma caja (el mismo relleno, el mismo ancho y el mismo alto), así que cada línea cae
   en el mismo sitio: la copia, a escala 1,6 desde el centro de la lente, es lo que se ve a través de ella. */
.escena--lupa {
  display: grid;
  min-height: 14rem;
  background: var(--cal);
}

.escena--lupa :is(.escena__fondo, .escena__aumento) {
  display: grid;
  align-content: center;
  padding: 28px;
}

.escena__texto {
  margin: 0;
  color: var(--ink);
  font-size: 1rem;
  line-height: 1.6;
}

.escena--lupa .escena__lente {
  position: absolute;
  inset: 0;
  background: var(--cal);
  clip-path: circle(var(--rx) at var(--x) var(--y));
}

.escena__aumento {
  height: 100%;
  transform: scale(1.6);
  transform-origin: var(--x) var(--y);
}

@media (max-width: 800px) {
  .escena--lupa :is(.escena__fondo, .escena__aumento) {
    padding: 20px;
  }
}

/* ---------------------------------------------------------- movimiento reducido */
/* Con «reducir movimiento», todo quieto: los destellos se quedan fijos y visibles (el texto del enfoque ya cambia de golpe: base.css deja las
   transiciones en casi cero, y lente.js deja la lente quieta, sin andar sola). Seguir al puntero, al dedo o a las flechas no es una animación. */
@media (prefers-reduced-motion: reduce) {
  .destello {
    animation: none;
    opacity: .7;
  }
}
