/* ==================================================================== fuentes
   Merriweather para los titulos y Plus Jakarta Sans para el texto: las dos de
   Google Fonts, licencia OFL.

   Servidas desde /static y no desde el CDN de Google a proposito. La app promete
   que no sale nada a internet, y un <link> a fonts.gstatic.com lo desmentiria en
   la primera carga; ademas asi la tipografia es la misma con y sin conexion.

   Son las versiones VARIABLES -de ahi los rangos de peso en cada cara- porque aca se
   usan pesos intermedios (450, 480, 550). Con archivos de peso fijo esos valores
   redondearian al mas cercano y se perderia el ajuste fino.

   Ojo con los rangos: no son iguales. Merriweather va de 300 a 900 -y ademas trae
   un eje de ancho, de ahi el font-stretch- y Jakarta de 200 a 800; cada cara
   declara lo suyo. Declarar un rango mas ancho del que la
   fuente tiene no la hace mas fina ni mas negra: el navegador recorta al limite
   real y la declaracion queda mintiendo.

   Cada familia viene partida en latin y latin-ext con su unicode-range, tal como
   los sirve Google: el navegador baja el segundo solo si la pagina lo necesita. */
@font-face {
  font-family: 'Merriweather';
  font-style: normal;
  font-weight: 300 900;
  font-stretch: 87% 112%;
  font-display: swap;
  src: url('/static/fuentes/merriweather-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Merriweather';
  font-style: normal;
  font-weight: 300 900;
  font-stretch: 87% 112%;
  font-display: swap;
  src: url('/static/fuentes/merriweather-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/static/fuentes/jakarta-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/static/fuentes/jakarta-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ============================================================================
   Filmina — vidrio liquido sobre negro.

   Tres reglas:
   1. El contenido manda. La diapositiva y el guion tienen contraste y tamaño;
      todo lo demas (barras, botones) es cromo callado y translucido.
   2. Nada de cajas dentro de cajas. Los controles flotan sueltos sobre el
      fondo, no dentro de barras que ocupan el ancho entero.
   3. Los bordes son pelos de luz, no lineas. La separacion la hace el
      desenfoque y la sombra difusa, no el contraste del borde.

   Hay dos temas, y ninguna regla de mas abajo sabe cual esta puesto: todo el
   color vive en estas dos listas de variables y el resto de la hoja solo las
   nombra. El tema claro no es el oscuro invertido: sobre blanco el vidrio no
   puede ser un velo de luz (seria invisible), asi que pasa a ser una sombra
   finisima, y el muneco, que sobre negro era una esfera blanca, se vuelve
   negro. Ya no hay nada que elegir ni nadie que elija: el sitio y el visor
   traen "oscuro" escrito en el <html>, sin script antes de pintar y sin ajuste
   de tema. La lista clara sigue aca porque la usa .invertido, que es de donde
   sale el visor dibujado de la portada.

   Un pedazo de pagina puede pedir el tema contrario al puesto: lo que lleve
   .invertido se lleva la otra lista entera. Lo usa el sitio para dibujar el
   visor, que es negro sobre la pagina blanca y blanco sobre la negra; y como se
   lleva la lista COMPLETA, lo de adentro -el muneco, el vidrio del dock, el
   puntero- cae solo en el tema que le toca. Las variables se heredan, asi que
   la declaracion que cae sobre el elemento mismo le gana a la heredada del
   :root por mas especifica que esa sea: no hay ninguna especificidad que pelear.
   ========================================================================= */

:root,
:root[data-tema="claro"] .invertido {
  color-scheme: dark;

  --fondo: #000;
  --text: #f5f5f7;
  --text-2: rgba(245, 245, 247, .72);
  --muted: rgba(245, 245, 247, .55);
  --faint: rgba(245, 245, 247, .32);
  /* El mismo gris, pero macizo. Un icono de trazos que se cruzan no puede
     ir en un color transparente: donde dos trazos se pisan el color se
     suma y la union se ve, como una soldadura mal hecha. */
  --faint-macizo: #4e4e4f;

  /* Vidrio: una pelicula casi transparente. El grosor lo da el blur. */
  --glass: rgba(255, 255, 255, .015);
  --glass-hi: rgba(255, 255, 255, .036);
  --glass-hi-2: rgba(255, 255, 255, .07);
  --edge: rgba(255, 255, 255, .09);
  --edge-hi: rgba(255, 255, 255, .18);
  --edge-max: rgba(255, 255, 255, .55);
  --halo: rgba(255, 255, 255, .06);

  /* El canto superior: la unica linea nitida que tiene una lamina. */
  --canto: inset 0 1px 0 rgba(255, 255, 255, .14);
  --canto-hi: inset 0 1px 0 rgba(255, 255, 255, .24);

  --sombra: 0 10px 34px rgba(0, 0, 0, .5);
  --sombra-lg: 0 24px 70px rgba(0, 0, 0, .6);
  /* Sobre negro la sombra no se ve (negro sobre negro), asi que el filo lo
     dibuja solo el pelo de luz. Y tiene que aguantar el peor caso: una
     diapositiva de fondo negro, donde el papel y la pared son el mismo color y
     ese pelo es lo unico que las separa. Por eso va 1px entero y no medio: a
     .5px el navegador lo reparte entre dos filas de pixeles y lo que queda es
     la mitad de brillo, justo en el caso en que mas hace falta. */
  --sombra-papel: 0 40px 90px rgba(0, 0, 0, .7), 0 0 0 1px rgba(255, 255, 255, .2);

  /* Lo opaco: la accion principal, la perilla encendida, la barra llena. */
  --solido: #f5f5f7;
  --solido-hi: #fff;
  --sobre-solido: #000;
  --sombra-solido: 0 10px 30px rgba(0, 0, 0, .55), 0 0 0 .5px rgba(255, 255, 255, .4);

  --pista: rgba(255, 255, 255, .14);
  --perilla-sombra: 0 1px 3px rgba(0, 0, 0, .45);
  --seleccion: rgba(255, 255, 255, .22);
  --foco: rgba(255, 255, 255, .75);
  --scroll: rgba(235, 235, 245, .2);
  --scroll-hi: rgba(235, 235, 245, .38);

  /* Laminas que tapan: el panel de ajustes, el menu del desplegable, y el
     plan B para el navegador que no sabe desenfocar. */
  --panel: rgba(11, 11, 13, .92);
  --menu: #1c1c1e;
  --opaco: rgba(26, 26, 28, .94);
  /* El velo que apaga el fondo cuando algo lo tapa entero. No es opaco: el
     fondo tiene que seguir estando, desenfocado, o lo que hay adelante deja de
     leerse como una puerta abierta sobre la pagina. */
  --velo: rgba(0, 0, 0, .55);
  /* El oro de la llave: el unico lugar tibio de la app, y va donde va a
     proposito -esto es lo que se compra-. Es el mismo en los dos temas: el oro
     no cambia de color con la luz de la pagina. */
  --oro: #EFBC3E;
  /* Las otras dos piezas de las laminas: el acero de la tuerca y el celeste de
     la burbuja. Van al lado del oro por lo mismo: el color es del objeto y no de la
     pantalla donde se apoya. */
  --acero: #c9ced8;
  --celeste: #b9d2e6;
  /* Los tres puntos de la burbuja. Oscuros y macizos, que es lo unico que se
     lee adentro de una pieza clara. */
  --burbuja-punto: #57626f;

  /* El profesor. */
  --cara-cuerpo: radial-gradient(circle at 31% 25%,
    #ffffff, #f1f2f5 34%, #ced1da 72%, #a7abb8 100%);
  --cara-sombra: 0 .1em .3em rgba(0, 0, 0, .6), inset 0 -.07em .14em rgba(0, 0, 0, .16);
  --cara-ojo: #0b0c10;
  --cara-brillo: rgba(255, 255, 255, .6);
  --cara-aura: radial-gradient(circle,
    rgba(255, 255, 255, .3), rgba(255, 255, 255, .08) 44%, transparent 70%);
  --cara-punto: rgba(255, 255, 255, .8);
  /* La lagrima. Sobre la esfera blanca tiene que ser un azul con cuerpo: un
     azul palido se pierde contra el cuerpo y deja de leerse como agua. */
  --cara-lagrima: rgba(86, 148, 224, .92);

  /* El puntero sobre la diapositiva. El color se elige en ajustes, asi que sale
     como terna aparte: el tema pone las opacidades -que no son las mismas sobre
     negro que sobre blanco- y el color elegido solo cambia el tono. */
  /* Los tres colores del puntero viven aca, en un solo lugar, porque los usan
     tanto el recuadro sobre la diapositiva como los puntitos de ajustes: lo que
     se elige es literalmente lo que se ve. */
  --tono-azul: 120, 168, 255;
  --tono-amarillo: 202, 138, 4;
  --tono-violeta: 150, 100, 245;

  --marca-tono: var(--tono-azul);
  --marca-hondo: 25, 75, 165;
  --marca: 0 0 0 2px rgba(var(--marca-tono), .95),
           0 0 0 7px rgba(var(--marca-tono), .18),
           0 14px 38px rgba(var(--marca-hondo), .22);

  /* El verde del hueco acertado. Es el segundo color que tiene la interfaz
     ademas del de borrar, y esta por lo mismo que el rojo: en el hueco, lo
     unico que se compara es una palabra contra otra, y decir cual de las dos es
     con una palabra mas -"bien", "mal"- seria poner un cartel donde alcanza con
     el color. Verde y rojo, y nada mas que ahi. */
  --acierto: #a9e2b4;
  --acierto-borde: rgba(120, 214, 140, .55);

  /* Borrar: el otro color de toda la interfaz. */
  --peligro: #ffb9b1;
  --peligro-hi: #ffd6d1;
  --peligro-fondo: rgba(255, 86, 74, .18);
  --peligro-fondo-hi: rgba(255, 86, 74, .3);
  --peligro-borde: rgba(255, 120, 110, .45);

  --blur: saturate(180%) blur(40px);
  --blur-sm: saturate(160%) blur(22px);

  --ease: cubic-bezier(.32, .72, 0, 1);
  --resorte: cubic-bezier(.22, 1.18, .36, 1);
}

/* --------------------------------------------------------------- modo claro */
/* Papel blanco y gris claro. El vidrio deja de ser luz y pasa a ser sombra: la
   misma pelicula finisima, pero tintada de negro, que sobre el blanco se lee
   como un gris apenas insinuado. Las sombras se aflojan (sobre blanco, una
   sombra fuerte ensucia) y todo lo que estaba en blanco solido -el boton de
   play, la perilla del interruptor, la barra llena- se da vuelta a negro. */

:root[data-tema="claro"],
:root:not([data-tema="claro"]) .invertido {
  color-scheme: light;

  --fondo: #fff;
  --text: #111113;
  --text-2: rgba(17, 17, 19, .74);
  --muted: rgba(17, 17, 19, .56);
  --faint: rgba(17, 17, 19, .38);
  --faint-macizo: #a5a5a6;

  --glass: rgba(0, 0, 0, .022);
  --glass-hi: rgba(0, 0, 0, .042);
  --glass-hi-2: rgba(0, 0, 0, .075);
  --edge: rgba(0, 0, 0, .1);
  --edge-hi: rgba(0, 0, 0, .2);
  --edge-max: rgba(0, 0, 0, .45);
  --halo: rgba(0, 0, 0, .05);

  --canto: inset 0 1px 0 rgba(255, 255, 255, .9);
  --canto-hi: inset 0 1px 0 rgba(255, 255, 255, 1);

  --sombra: 0 8px 24px rgba(0, 0, 0, .09);
  --sombra-lg: 0 20px 56px rgba(0, 0, 0, .12);
  /* Sobre negro la diapositiva se recortaba sola y la sombra no se veia: podia
     ser enorme. Sobre blanco es papel blanco sobre pared blanca, y hay que
     dibujar el filo a mano.

     Lo que manda es que los dos tonos esten separados. Cuando la linea y el
     pico de la sombra caen en el mismo gris -una al 8% da #e9e9e9, una sombra
     al 7% pegada al lado da #eeeeee- no ves un borde con profundidad debajo:
     ves una sola mancha difusa de 25px. La linea al 8% da #eaeaeb, casi un
     susurro, y para que igual se siga leyendo como linea la sombra baja con
     ella: en los costados su pico queda cerca de #f5f5f5, once niveles mas
     clara. Ese hueco entre los dos grises es lo que no se puede cerrar; el
     valor absoluto de la linea se puede bajar todo lo que uno quiera mientras
     la sombra la acompane, pero aca ya estamos cerca del piso: mas claro que
     esto y la diapositiva deja de tener filo. El orden importa: el anillo va
     primero para que pinte encima. */
  --sombra-papel: 0 0 0 1px rgba(0, 0, 0, .08),
                  0 2px 6px rgba(0, 0, 0, .03),
                  0 8px 20px rgba(0, 0, 0, .045);

  --solido: #111113;
  --solido-hi: #000;
  --sobre-solido: #fff;
  --sombra-solido: 0 8px 22px rgba(0, 0, 0, .22), 0 0 0 .5px rgba(0, 0, 0, .06);

  --pista: rgba(0, 0, 0, .13);
  --perilla-sombra: 0 1px 3px rgba(0, 0, 0, .26);
  --seleccion: rgba(0, 0, 0, .14);
  --foco: rgba(0, 0, 0, .55);
  --scroll: rgba(0, 0, 0, .2);
  --scroll-hi: rgba(0, 0, 0, .36);

  --panel: rgba(255, 255, 255, .94);
  --menu: #fff;
  --opaco: rgba(250, 250, 251, .97);
  --velo: rgba(245, 245, 247, .6);

  /* El muneco negro, con la luz cayendo de arriba a la izquierda igual que
     antes: lo que cambia es que ahora aclara el grafito en vez del blanco. */
  --cara-cuerpo: radial-gradient(circle at 31% 25%,
    #55565e, #35363c 34%, #191a1e 72%, #050507 100%);
  --cara-sombra: 0 .09em .26em rgba(0, 0, 0, .3), inset 0 -.07em .14em rgba(0, 0, 0, .45);
  --cara-ojo: #f7f8fa;
  /* El ojo claro sobre el cuerpo oscuro es la misma imagen dada vuelta, asi que
     el brillo tambien se da vuelta: aca el reflejo es el hueco oscuro. */
  --cara-brillo: rgba(9, 10, 13, .5);
  /* Sobre blanco un resplandor blanco no existe: el aura se vuelve un halo de
     sombra, que se abre igual cuando habla. */
  --cara-aura: radial-gradient(circle,
    rgba(17, 17, 19, .22), rgba(17, 17, 19, .07) 44%, transparent 70%);
  --cara-punto: rgba(17, 17, 19, .7);
  /* Sobre el muneco negro pasa lo contrario: el azul tiene que ser claro, o la
     lagrima se hunde en el cuerpo. */
  --cara-lagrima: rgba(146, 198, 255, .95);

  --tono-azul: 38, 104, 235;
  --tono-violeta: 124, 58, 226;
  /* El amarillo no cambia: ya es ambar, y el papel de la diapositiva es blanco
     en los dos temas. */

  --marca-hondo: 25, 75, 165;
  --marca: 0 0 0 2px rgba(var(--marca-tono), .95),
           0 0 0 7px rgba(var(--marca-tono), .14),
           0 14px 38px rgba(var(--marca-hondo), .16);

  --peligro: #c02a1d;
  --peligro-hi: #8f1d13;
  --peligro-fondo: rgba(255, 86, 74, .12);
  --peligro-fondo-hi: rgba(255, 86, 74, .2);
  --peligro-borde: rgba(214, 60, 48, .35);
}

/* El color elegido. Van despues de los dos temas para ganarles por orden, y
   apuntan al token del tono, asi que cada uno agarra solo la version que
   corresponda al tema puesto. La sombra honda es la version oscura del tono. */
:root[data-indicador="amarillo"] { --marca-tono: var(--tono-amarillo); --marca-hondo: 150, 103, 8; }
:root[data-indicador="violeta"]  { --marca-tono: var(--tono-violeta);  --marca-hondo: 78, 45, 160; }

/* La serif de los titulos es la misma del sitio. Va suelta y no en las listas
   de color de mas arriba: no cambia con el tema. */
:root { --serif: "Merriweather", Georgia, "Times New Roman", serif; }

* { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  display: flex;
  flex-direction: column;
  background: var(--fondo);
  color: var(--text);
  font: 450 14.5px/1.5 "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  letter-spacing: -.011em;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--seleccion); }

/* ------------------------------------------------------------------ iconos */

.iconos { display: none; }

button svg, .icono-doc, #drop .icono {
  display: block;
  width: 20px; height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --------------------------------------------------------------- controles */

button, select, input { font: inherit; color: inherit; }

button {
  -webkit-appearance: none;
  appearance: none;
  display: grid;
  place-items: center;
  background: var(--glass-hi);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid var(--edge);
  border-radius: 999px;
  color: var(--text);
  cursor: pointer;
  box-shadow: var(--sombra), var(--canto);
  transition: background .2s var(--ease), transform .3s var(--resorte),
              border-color .2s var(--ease), opacity .2s var(--ease);
}
button:hover:not(:disabled):not(.activo) { background: var(--glass-hi-2); border-color: var(--edge-hi); }
button:active:not(:disabled) { transform: scale(.93); }
button:disabled { opacity: .25; cursor: default; }

.icono-btn { width: 38px; height: 38px; padding: 0; }

/* Encendido: mientras su panel esta abierto, el boton se queda solido.
   El hover esta excluido a mano de las reglas de arriba y de las del dock
   porque las dos le ganaban en especificidad y le devolvian el fondo
   translucido, pero no el color: el icono se quedaba del color del panel
   -blanco en claro, negro en oscuro- contra el vidrio, o sea invisible. Y el
   mouse esta justo encima siempre que acabas de abrirlo. */
.icono-btn.activo { background: var(--solido); border-color: transparent; color: var(--sobre-solido); }
.icono-btn.activo:hover:not(:disabled) { background: var(--solido-hi); }

/* La accion principal: la unica pieza opaca del cromo. */
button.primary {
  background: var(--solido);
  border-color: transparent;
  color: var(--sobre-solido);
  box-shadow: var(--sombra-solido);
}
button.primary:hover:not(:disabled) { background: var(--solido-hi); }

:focus-visible { outline: 2px solid var(--foco); outline-offset: 3px; }

::-webkit-scrollbar { width: 9px; }
::-webkit-scrollbar-thumb {
  background: var(--scroll);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: 99px;
}
::-webkit-scrollbar-thumb:hover { background: var(--scroll-hi); background-clip: content-box; }
::-webkit-scrollbar-track { background: transparent; }


/* --------------------------------------------------------------- el arranque
   La primera vez, y una sola vez. Ocupa la ventana entera y no una lamina
   flotando sobre la portada: no hay ninguna portada abajo que valga la pena
   dejar a la vista -no hay documentos, no hay modelo bajado- y una ventanita
   pide que la cierren, que es justo lo contrario de lo que hay que hacer.

   Una pantalla por idea, y cada idea se muestra antes de contarse: el dibujo
   arriba, el titulo abajo y una sola frase. Lo que no entra en una frase no
   es para el primer arranque. */

#onboarding {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 40px 24px 132px;
  overflow-y: auto;
  text-align: center;
}
/* La clase va en <html> y no en el <body>: la pone el script de la cabecera,
   que corre antes de que exista el body. */
html.arrancando #setup, html.arrancando #abajo { display: none; }
/* Una regla por pieza y no un [hidden] global: aca todo lo que se esconde es
   un flex, y un display de clase le gana al del atributo. */
#onboarding[hidden], .ob-paso[hidden], .ob-pie button[hidden] { display: none; }

/* ---- el idioma ---- */
/* Debajo de la bajada y en la fila, como un renglon mas de la pantalla. Se
   probo flotando -para que la primera midiera lo mismo que las otras cuatro y
   el titulo no se moviera al pasar- y no: en una ventana baja el pie lo tapaba
   con el boton de seguir. Contando para el alto no lo tapa nunca, porque el
   hueco del pie ya esta reservado en el padding de abajo del arranque. */
.ob-idioma {
  margin-top: 4px;
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
  animation: llegar .5s var(--ease) both;
}
.ob-idioma svg {
  flex-shrink: 0;
  width: 15px; height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}
/* El mismo desplegable de los ajustes: sin caja, con la flechita dibujada a
   mano. Que sea el mismo importa, porque es el mismo ajuste. */
.ob-idioma select {
  -webkit-appearance: none;
  appearance: none;
  padding: 3px 18px 3px 6px;
  border: none;
  border-radius: 9px;
  background: transparent;
  color: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 8px) calc(50% + 1px), calc(100% - 4px) calc(50% + 1px);
  background-size: 4.5px 4.5px;
  background-repeat: no-repeat;
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
.ob-idioma:hover { color: var(--text); }
.ob-idioma select:hover { background-color: var(--glass-hi-2); }
.ob-idioma select option { background: var(--menu); color: var(--text); font-weight: 400; }

.ob-paso {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: 100%;
  max-width: 460px;
  animation: llegar .5s var(--ease) both;
}
/* Donde se corta el titulo largo va escrito a mano, con un <br> adentro del
   texto: librado al ancho de la ventana, en una pantalla grande entra todo en
   un renglon larguisimo. El balance se queda para los cortos, que en una
   ventana angosta si se parten solos. */
.ob-paso h2 {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(26px, 3.4vw, 34px);
  font-weight: 400;
  letter-spacing: -.02em;
  line-height: 1.16;
  text-wrap: balance;
}
/* La medida esta elegida a mano y no por comodidad: a 29ch las cinco bajadas
   caen en tres renglones parejos. Mas ancha, la ultima linea de alguna queda
   con dos palabras colgando; mas angosta, dos de ellas se van a cuatro. */
.ob-paso > p {
  margin: 0;
  max-width: 29ch;
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.55;
  text-wrap: pretty;
}

/* El dibujo vive en una caja de alto fijo: sin eso, cada pantalla mide lo que
   mide su dibujo y el titulo salta de lugar en lugar al pasar de una a otra.
   Con el alto quieto, lo unico que cambia entre pantallas es lo que se cuenta. */
.ob-arte {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 188px;
  margin-bottom: 4px;
}

/* ---- 1. la lamina y su guion ---- */
/* El lector, dibujado en chico: a la izquierda la diapositiva con un bloque
   encendido, a la derecha el parrafo que lo explica. Que esten al lado y que
   se enciendan juntos es toda la idea del programa. */
.ob-maqueta {
  display: flex;
  align-items: stretch;
  gap: 12px;
  width: 100%;
  max-width: 340px;
}
.ob-lamina, .ob-guion {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 13px;
  border-radius: 14px;
  border: 1px solid var(--edge);
  background: var(--glass);
}
.ob-lamina { flex: 1.15; }
.ob-guion  { flex: 1; justify-content: flex-start; }

/* Las rayas que hacen de texto. Van un poco mas encendidas que una pista
   vacia: son el contenido del dibujo, no el fondo por donde algo avanza. */
.ob-bloque, .ob-renglon {
  display: block;
  height: 6px;
  border-radius: 99px;
  background: var(--edge-hi);
}
.ob-bloque.ob-tit { height: 9px; width: 70%; background: var(--faint); }
.ob-bloque.corto, .ob-renglon.corto { width: 55%; }

/* El bloque marcado lleva el mismo recuadro que pone el lector de verdad: el
   color del indicador, redondeado y con aire alrededor. */
.ob-bloque.marcado {
  position: relative;
  background: rgba(var(--marca-tono), .5);
}
.ob-bloque.marcado::after {
  content: '';
  position: absolute;
  inset: -5px -6px;
  border-radius: 7px;
  border: 1px solid rgb(var(--marca-tono));
  animation: ob-latir 2.6s var(--ease) infinite;
}
.ob-renglon.activo { background: var(--text-2); }

/* La onda: siete barras que suben y bajan corridas entre si. Es lo unico que
   dice "en voz alta" sin escribirlo. */
.ob-onda { display: flex; align-items: flex-end; gap: 3px; height: 16px; margin-top: 6px; }
.ob-onda i {
  display: block;
  width: 3px;
  border-radius: 99px;
  background: var(--faint);
  animation: ob-onda 1.1s var(--ease) infinite;
}
.ob-onda i:nth-child(1) { height: 5px;  animation-delay: 0s; }
.ob-onda i:nth-child(2) { height: 11px; animation-delay: .1s; }
.ob-onda i:nth-child(3) { height: 16px; animation-delay: .2s; }
.ob-onda i:nth-child(4) { height: 9px;  animation-delay: .3s; }
.ob-onda i:nth-child(5) { height: 14px; animation-delay: .4s; }
.ob-onda i:nth-child(6) { height: 7px;  animation-delay: .5s; }
.ob-onda i:nth-child(7) { height: 12px; animation-delay: .6s; }
.ob-onda.grande { height: 22px; gap: 4px; margin-top: 12px; }
.ob-onda.grande i { width: 4px; }

@keyframes ob-onda { 50% { transform: scaleY(.35); } }
@keyframes ob-latir { 50% { opacity: .35; } }

/* ---- 2. la pregunta ---- */
/* La tarjeta que corta la clase, con el hueco a la mitad de la frase. El hueco
   es el unico pedazo que no es una raya gris: es lo que hay que contestar. */
.ob-tarjeta {
  display: flex;
  flex-direction: column;
  gap: 9px;
  width: 100%;
  max-width: 300px;
  padding: 18px 18px 16px;
  border-radius: 16px;
  border: 1px solid var(--edge);
  background: var(--glass-hi);
}
.ob-tarjeta .ob-renglon { width: 100%; }
.ob-tarjeta .con-hueco {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 80%;
  height: 6px;
  background: none;
}
.ob-tarjeta .con-hueco::before,
.ob-tarjeta .con-hueco::after {
  content: '';
  height: 6px;
  border-radius: 99px;
  background: var(--edge-hi);
}
.ob-tarjeta .con-hueco::before { flex: 1.2; }
.ob-tarjeta .con-hueco::after  { flex: .7; }
.ob-hueco {
  width: 46px; height: 14px;
  border-radius: 5px;
  border: 1px dashed rgb(var(--marca-tono));
  background: rgba(var(--marca-tono), .14);
  animation: ob-latir 2.6s var(--ease) infinite;
}
.ob-opciones { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.ob-opcion {
  height: 22px;
  border-radius: 8px;
  border: 1px solid transparent;
  background: var(--glass);
}
.ob-opcion.elegida { border-color: var(--edge-hi); background: var(--glass-hi-2); }

/* ---- 3. la carpeta y el candado ---- */
/* Los mismos del sitio. Ahi estan sueltos sobre la franja; aca van juntos y en
   diagonal, que es como se ven dos cosas apoyadas sobre una mesa. */
.ob-guardado { position: relative; display: flex; align-items: flex-end; }
.ob-guardado .carpeta {
  width: 132px; height: auto;
  transform: rotate(-7deg);
  filter: drop-shadow(0 14px 26px rgba(0, 0, 0, .45));
}
.ob-guardado .candado {
  width: 58px; height: auto;
  margin-left: -12px; margin-bottom: -6px;
  transform: rotate(9deg);
  filter: drop-shadow(0 10px 20px rgba(0, 0, 0, .5));
}

.carpeta .c-atras  { fill: url(#ob-c-atras); }
.carpeta .c-frente { fill: url(#ob-c-frente); }
.carpeta .s-atras-1  { stop-color: rgb(var(--tono-azul)); stop-opacity: .5; }
.carpeta .s-atras-2  { stop-color: rgb(var(--tono-azul)); stop-opacity: .3; }
.carpeta .s-frente-1 { stop-color: rgb(var(--tono-azul)); stop-opacity: .88; }
.carpeta .s-frente-2 { stop-color: rgb(var(--tono-azul)); stop-opacity: .7; }
.carpeta .s-frente-3 { stop-color: rgb(var(--tono-azul)); stop-opacity: .55; }
.carpeta .c-canto-atras,
.carpeta .c-canto-frente,
.carpeta .c-labio { fill: none; stroke-linecap: round; }
.carpeta .c-canto-atras  { stroke: #fff; stroke-opacity: .3; stroke-width: .9; }
.carpeta .c-canto-frente { stroke: #fff; stroke-opacity: .16; stroke-width: .9; }
.carpeta .c-labio { stroke: #fff; stroke-opacity: .5; stroke-width: 1.1; }
.carpeta .c-lustre   { fill: #fff; opacity: .1; }
.carpeta .c-lustre-2 { fill: #fff; opacity: .055; }
.carpeta .c-hoja   { fill: #fbfbfd; }
.carpeta .c-hoja-2 { fill: #fff; opacity: .45; }
.carpeta .c-renglon { fill: none; stroke: #c9c9cf; stroke-width: 1.4; stroke-linecap: round; }

.candado .k-cuerpo { fill: url(#ob-k-cuerpo); }
.candado .s-k-1 { stop-color: rgb(var(--tono-amarillo)); stop-opacity: .92; }
.candado .s-k-2 { stop-color: rgb(var(--tono-amarillo)); stop-opacity: .76; }
.candado .s-k-3 { stop-color: rgb(var(--tono-amarillo)); stop-opacity: .6; }
.candado .k-arco { fill: none; stroke: url(#ob-k-arco); stroke-width: 5; stroke-linecap: round; }
.candado .s-k-arco-1 { stop-color: #fff; stop-opacity: .5; }
.candado .s-k-arco-2 { stop-color: #fff; stop-opacity: .26; }
.candado .k-arco-luz { fill: none; stroke: #fff; stroke-opacity: .34; stroke-width: 1.1; stroke-linecap: round; }
.candado .k-labio,
.candado .k-canto { fill: none; stroke-linecap: round; }
.candado .k-labio { stroke: #fff; stroke-opacity: .5; stroke-width: 1.1; }
.candado .k-canto { stroke: #fff; stroke-opacity: .2; stroke-width: .9; }
.candado .k-lustre   { fill: #fff; opacity: .12; }
.candado .k-lustre-2 { fill: #fff; opacity: .06; }
.candado .k-ojo { fill: #000; fill-opacity: .42; }

/* ---- 4. el que explica ---- */
/* El cerebro con un halo que respira. Mientras se baja no hay nada que mirar
   -son varios minutos y una barra- asi que algo tiene que estar vivo. */
.ob-cerebro { position: relative; display: grid; place-items: center; }
.ob-cerebro svg {
  position: relative;
  width: 74px; height: 74px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--text-2);
}
.ob-aura {
  position: absolute;
  width: 150px; height: 150px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--marca-tono), .2), transparent 68%);
  animation: ob-respirar 3.4s var(--ease) infinite;
}
@keyframes ob-respirar { 50% { transform: scale(1.14); opacity: .55; } }

.ob-descarga {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  width: 100%;
  max-width: 300px;
  min-height: 42px;
  margin-top: 6px;
}
/* La barra de la descarga del modelo. No es del arranque: la misma descarga se
   mira desde dos lados -el arranque y el lector, si le diste a empezar antes de
   que terminara- y tiene que verse igual en los dos. */
.descarga-barra {
  width: 100%;
  height: 3px;
  border-radius: 99px;
  background: var(--pista);
  overflow: hidden;
}
.descarga-barra i {
  display: block;
  height: 100%;
  border-radius: 99px;
  background: var(--solido);
  transition: width .4s var(--ease);
}
.descarga-cuanto { color: var(--faint); font-size: 12.5px; }
.descarga-cuanto.mal { color: var(--peligro); }

/* La barra y, debajo, los gigas de un lado y el boton del otro. */
.descarga { display: flex; flex-direction: column; gap: 7px; width: 100%; }

/* La corta, para la fila de los ajustes: todo en un renglon y a lo ancho que
   sobre, que ahi el nombre del modelo ya se lleva casi todo. Los gigas no van
   aca sino en la linea del detalle, debajo del nombre. */
.descarga.corta {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  width: 132px;
}
.descarga.corta .descarga-barra { flex: 1; }
.descarga-pie {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}

/* En pausa la barra se apaga a la mitad: quieta y encendida se lee como una
   descarga andando que no avanza, que es lo que uno mira preocupado. */
.descarga-barra.quieta i { background: var(--faint); }

/* El boton de pausar. Chico y callado: lo que importa de esta pantalla es
   cuanto falta, no lo que se puede hacer con la espera. */
.descarga-pausa {
  flex-shrink: 0;
  width: 24px; height: 24px;
  padding: 0;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  color: var(--faint);
}
/* El triangulo del play no esta centrado adentro de su cuadro: va corrido a la
   derecha, que es como se dibuja siempre -un triangulo centrado por su caja se
   ve corrido a la izquierda- pero en un boton de 24 eso se nota. Se lo devuelve
   al medio optico. Las dos barras de la pausa si estan centradas y no se tocan. */
.descarga-pausa svg { width: 13px; height: 13px; }
.descarga-pausa[data-pausa="seguir"] svg { transform: translateX(-.6px); }
.descarga-pausa:hover:not(:disabled) { background: var(--glass-hi); color: var(--text); }
.ob-listo { display: flex; align-items: center; gap: 7px; color: var(--muted); font-size: 13px; }
/* El tilde no esta adentro de un boton, asi que las reglas de trazo de los
   iconos no lo alcanzan: sin esto se dibuja relleno de negro sobre negro. */
.ob-listo svg {
  width: 15px; height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---- 5. el oido ---- */
.ob-micro { position: relative; display: flex; flex-direction: column; align-items: center; }
.ob-micro svg {
  width: 52px; height: 52px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--text-2);
}
/* A la izquierda, como en los ajustes: son dos renglones que se leen, no un
   cartel. Lo de arriba de esta pantalla si va centrado. */
.ob-elegir {
  display: flex; flex-direction: column; gap: 6px;
  width: 100%; max-width: 340px; margin-top: 8px;
  text-align: left;
}
/* Las dos opciones son las mismas filas de los ajustes, pero aca si se eligen,
   y una fila que se elige tiene que verse apretable antes de tocarla: canto
   dibujado, un poco mas de vidrio y el redondel de la derecha, que es lo unico
   que dice "una de las dos" sin escribirlo. En los ajustes no lleva redondel
   porque alla no se elige nada: se muestra lo que hay bajado. */
.ob-elegir .voz {
  padding: 13px 15px;
  border-color: var(--edge);
  background: var(--glass-hi);
  cursor: pointer;
}
.ob-elegir .voz:hover { background: var(--glass-hi-2); border-color: var(--edge-hi); }
.ob-elegir .voz:active { transform: scale(.985); }
.ob-elegir .voz.elegida { border-color: var(--solido); background: var(--glass-hi-2); }

.ob-marca {
  flex-shrink: 0;
  width: 19px; height: 19px;
  border-radius: 50%;
  border: 1.5px solid var(--edge-hi);
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
/* Elegida: el anillo se enciende y aparece el punto del medio. Va de degrade
   radial y no de un hijo mas: es un solo elemento y una sola transicion. */
.voz.elegida .ob-marca {
  border-color: var(--solido);
  background: radial-gradient(circle, var(--solido) 0 4.5px, transparent 4.5px);
}

/* ---- el pie ---- */
/* Fijo abajo y no al final de la columna: lo que se sigue esta siempre en el
   mismo lugar, aunque una pantalla mida mas que la otra.

   No es una tarjeta: no lleva borde ni vidrio ni sombra. Lo unico que hace el
   degrade es que el dibujo de arriba no se meta por abajo de los botones. */
.ob-pie {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 41;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
  padding: 24px 24px 44px;
  background: linear-gradient(to top, var(--fondo) 62%, transparent);
}
html:not(.arrancando) .ob-pie { display: none; }
/* La misma medida que los botones de las preguntas: es el mismo boton de la
   misma app, y la mano ya sabe que alto tiene. */
.ob-pie button { padding: 10px 17px; font-size: 13.5px; font-weight: 500; }
.ob-pie .primary { min-width: 132px; }
.ob-secundario {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--faint);
}
.ob-secundario:hover:not(:disabled) { background: var(--glass-hi); color: var(--text); }

/* Cuantas quedan. Cinco pantallas sin saber cuantas son se sienten infinitas. */
.ob-puntos { display: flex; align-items: center; gap: 6px; }
.ob-puntos i {
  display: block;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--pista);
  transition: background .3s var(--ease), width .3s var(--ease);
}
.ob-puntos i.aca { width: 16px; border-radius: 99px; background: var(--muted); }
.ob-puntos i.visto { background: var(--faint); }

@media (max-width: 560px) {
  .ob-arte { height: 150px; }
  .ob-maqueta { max-width: 280px; }
}

/* ----------------------------------------------------------------- portada */

#setup {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 40px 24px;
  overflow-y: auto;
  /* Con varios archivos abiertos la lista pasa el borde de abajo de la ventana
     y ahi se cortaba en seco, a mitad de un renglon, como si la pantalla se
     hubiera quedado sin papel. Esto la apaga en los ultimos milimetros: el
     corte deja de ser un tajo y se lee como que sigue.

     Va de mascara y no de degradado encima porque encima habria que pintarlo
     del color del fondo, y el fondo cambia con el tema; la mascara no pinta
     nada, apaga lo que haya. */
  --desvanecido: 72px;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - var(--desvanecido)), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - var(--desvanecido)), transparent);
}
/* Nada de la portada se achica para entrar. Es una columna flex, asi que por
   defecto todo cede cuando no hay alto suficiente -y la tarjeta, que ademas
   recorta lo que se le sale, se comia adentro la flecha y los formatos en
   cuanto la ventana era un poco baja. Si no entra, se baja: para eso esta el
   scroll de arriba. */
#setup > * { flex-shrink: 0; }
/* Y cuando tampoco entra centrado, el centrado no puede comerse el principio:
   'safe center' deja de centrar y arranca de arriba en cuanto hay desborde, asi
   la cara y el aire que tiene encima quedan siempre alcanzables con el scroll.
   Va aparte por si el navegador no conoce la palabra: el centrado de arriba
   sigue valiendo. */
@supports (justify-content: safe center) {
  #setup { justify-content: safe center; }
}
.hero {
  position: relative;      /* el globo se cuelga de aca */
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  /* De que tamano es el profesor de la portada. Va como medida y no como numero
     suelto porque el globo lo necesita para saber donde termina la cabeza. */
  --cara-portada: clamp(56px, 8vw, 76px);
  /* El profesor no arranca pegado al borde: un respiro arriba y la portada
     entera baja un poco, que es lo que la hace ver menos apretada. */
  margin-top: 28px;
  margin-bottom: 14px;
  animation: llegar .8s var(--ease) both;
}

/* En la portada el profesor no trabaja: es el que te recibe. Va arriba del
   titulo, grande pero sin pasarlo, y de ahi no se mueve -el que viaja entre el
   centro y el encabezado es el del lector, que es otra pieza. */
.hero .cara { margin-bottom: 22px; }
.cara[data-lugar="portada"] { font-size: var(--cara-portada, 76px); }
/* Lo que el profesor tiene para decir de lo que acabas de traer. Que el archivo
   no es de los que sabe leer, que el PDF esta escaneado, que no se pudo abrir:
   todo eso es una respuesta a algo que acabas de hacer, y una respuesta la da
   alguien. Antes salia como un renglon gris al pie de la portada, lejos de la
   cara y lejos de la tarjeta, y habia que ir a buscarlo.

   Sale de la cabeza, a la derecha, con la colita apuntando a la cara. Va
   colgado y no en la columna a proposito: asi el titulo no se corre ni la
   portada da un salto cada vez que el te contesta algo.

   Es opaco, y es la unica pieza de la portada que lo es. El resto son vidrios
   -casi transparentes: el fondo se ve a traves-, y ahi la colita no se podria
   pegar al globo sin que se marcara el canto de abajo cruzandola. Opaco ademas
   es lo que lo hace un globo de historieta y no otra tarjeta mas. */
.globo {
  position: absolute;
  top: 3px;
  left: calc(50% + var(--cara-portada) / 2 + 14px);
  width: max-content;
  /* Nunca se pasa del borde: lo que hay del centro de la cara para afuera,
     menos la cabeza, el hueco y el margen de la portada. */
  max-width: min(272px, calc(50vw - var(--cara-portada) / 2 - 62px));
  padding: 10px 14px 11px;
  border-radius: 15px;
  border: 1px solid var(--edge);
  background: var(--opaco);
  box-shadow: var(--sombra), var(--canto);
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--text);
  text-align: left;
  text-wrap: pretty;
  cursor: default;
  /* Crece desde la colita, que es de donde sale. */
  transform-origin: 0 22px;
  animation: globo .42s var(--resorte) both;
}
/* La colita: un cuadrado girado, con el canto en los dos lados que quedan
   para afuera. Monta medio cuerpo sobre el globo, y como el globo es opaco, lo
   que tapa queda tapado: no se marca el borde cruzandola por atras. */
.globo::after {
  content: '';
  position: absolute;
  left: -5px; top: 16px;
  width: 10px; height: 10px;
  background: var(--opaco);
  border-left: 1px solid var(--edge);
  border-bottom: 1px solid var(--edge);
  border-radius: 0 0 0 3px;
  transform: rotate(45deg);
}
/* Irse es mas rapido que llegar: lo que dijo ya lo leiste. */
.globo.yendose { animation: globo-apagar .22s var(--ease) both; }

/* Angosto no hay lugar al costado de la cabeza: el globo se pone debajo, en la
   columna, y la colita apunta para arriba. Ahi si corre el titulo, pero es eso
   o un globo de dos palabras por renglon. */
@media (max-width: 720px) {
  .globo {
    position: static;
    max-width: min(330px, 86vw);
    margin: -8px 0 20px;
    transform-origin: 50% 0;
    animation-name: globo-abajo;
  }
  .globo::after {
    left: 50%; top: -5px;
    margin-left: -5px;
    border: 0;
    border-top: 1px solid var(--edge);
    border-left: 1px solid var(--edge);
    border-radius: 3px 0 0 0;
  }
}

/* La portada no dice como se llama el programa ni que hace: eso ya lo sabe el
   que la abrio. Pregunta, que es lo unico que falta contestar, y la respuesta
   se contesta soltando el archivo en la tarjeta de abajo.

   Va en la serif y no en la Jakarta del resto: es la unica frase de la app que
   no es interfaz -no es un boton, ni un cartel, ni un dato- y la serif es lo
   que la separa del cromo y la acerca al papel que estas por traer. */
#setup h1 {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(31px, 4.6vw, 46px);
  font-weight: 500;
  letter-spacing: -.022em;
  line-height: 1.12;
}

/* El ancho y la entrada viven aca, que es lo que se mueve; la tarjeta ocupa la
   zona entera y las hojas de formato van adentro de ella, asi que nada asoma
   por el borde de abajo y el aire que sigue es el de siempre.

   El nombre lleva el apellido a proposito: el sitio tiene su propia .zona -la
   tarjeta de la demo de arrastre- y carga esta hoja ademas de la suya. Con el
   nombre pelado, el position y el z-index de aca le caian encima y le tapaban
   el archivo y el puntero que cruzan la tarjeta, que es justo lo unico que esa
   demo tiene para mostrar. Lo que se comparte entre la app y el sitio se
   comparte a proposito; esto no. */
.zona-drop {
  position: relative;
  width: min(580px, 92vw);
  z-index: 1;
  animation: llegar .8s .06s var(--ease) both;
}

#drop {
  position: relative;
  z-index: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  /* El aire de abajo esta nombrado porque las hojas de formato lo usan: se
     hunden ese tanto mas unos pixeles, y asi el canto de la tarjeta las tapa
     siempre igual, tambien cuando en el telefono el relleno achica. */
  --pad-drop: 44px;
  --pad-drop-x: 28px;
  padding: var(--pad-drop) var(--pad-drop-x);
  border-radius: 26px;
  border: 1px solid var(--edge);
  background: var(--glass);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  box-shadow: var(--sombra-lg), var(--canto);
  cursor: pointer;
  overflow: hidden;
  transition: background .25s var(--ease), border-color .25s var(--ease),
              transform .4s var(--resorte), box-shadow .3s var(--ease);
}
#drop .icono {
  width: 26px; height: 26px;
  margin-bottom: 12px;
  color: var(--faint);
  transition: color .25s var(--ease), transform .4s var(--resorte);
}
#drop .big { font-size: 16.5px; font-weight: 550; letter-spacing: -.015em; }
#drop .small { color: var(--muted); font-size: 13.5px; }
#drop:hover { background: var(--glass-hi); border-color: var(--edge-hi); }
#drop:hover .icono { color: var(--text); transform: translateY(-2px); }
#drop.over {
  transform: scale(1.015);
  border-color: var(--edge-max);
  background: var(--glass-hi-2);
  box-shadow: var(--sombra-lg), var(--canto-hi), 0 0 0 5px var(--halo);
}
#drop.over .icono { color: var(--text); transform: translateY(-4px); }
/* Con algo adentro deja de ser un selector: no se ilumina al pasar por encima
   ni cambia el cursor, porque lo que hay que apretar es el boton. */
#drop.con-archivo { cursor: default; }
#drop.con-archivo:hover { background: var(--glass); border-color: var(--edge); }

/* ---- la tarjeta con lo que trajiste ---- */
/* Mismo ancho y mismo vidrio: no es otra tarjeta, es la misma dada vuelta. */
/* La invitacion no es una caja: sus piezas siguen siendo hijas de la tarjeta y
   se apilan como siempre. Lo unico que gana al estar envuelta es poder irse
   entera cuando entra la otra cara. Y el hidden hay que escribirlo aca: contra
   display:contents, el del navegador pierde por especificidad.

   Y no se va del todo: se apaga. Sigue ocupando lo que ocupaba, que es lo que
   mantiene la tarjeta del mismo tamano cuando traes un archivo -encogerse al
   recibir algo seria al reves de lo que pasa-. La otra cara se apoya encima,
   fuera del flujo, y se centra en el alto que la invitacion sostiene. Sale mas
   barato que copiar a mano una altura que cambia con el ancho de la ventana. */
#drop .invitacion { display: contents; }
#drop .invitacion[hidden] { visibility: hidden; }
#drop .traido {
  position: absolute;
  inset: var(--pad-drop) var(--pad-drop-x);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: stretch;
  gap: 14px;
  animation: revelar .35s var(--ease) both;
}
#drop .traido[hidden] { display: none; }
#drop .traido .linea {
  display: flex; align-items: center; gap: 11px;
  min-width: 0;
}
/* El nombre se queda con lo que ocupa y se corta si no entra; lo que sobra del
   renglon es del dato de al lado, que asi empieza pegado al nombre en vez de
   irse contra la cruz. */
#drop .traido .nombre {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 16.5px; font-weight: 550; letter-spacing: -.015em;
}
#drop .traido .icono-doc { width: 17px; height: 17px; color: var(--faint); flex-shrink: 0; }
#drop .traido .icono-btn { width: 30px; height: 30px; flex-shrink: 0; }

/* Cuantas diapositivas trajo, al lado del nombre y en el tono de un dato. Es
   el mismo lugar donde antes se decia "Convirtiendo...", y no hay barra: no
   habia un porcentaje que poner -el servidor convierte de un tiron y contesta
   una sola vez, al final-, asi que lo unico cierto es que esta pasando algo.
   Eso lo dice el palpito, y se apaga solo cuando la tarjeta queda lista. */
#drop .traido .paso {
  /* Crece para empujar la cruz contra el canto, y se achica casi nada: cuando
     el renglon no da -un nombre largo en el telefono-, el que se corta es el
     nombre, que sigue diciendo cual es con la mitad de las letras. "128
     diapositivas" cortado en "128 ..." no dice nada. */
  flex: 1 .08 auto;
  /* Y por debajo de la cuenta de diapositivas no baja: ese es el piso. Lo unico
     mas largo que puede decir es que la version gratis lee hasta cien, y eso si
     se corta antes que el nombre entero. */
  min-width: 7.5em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--muted); font-size: 13.5px;
}
#drop:not(.listo) .traido .paso { animation: palpito 2.9s var(--ease) infinite; }

#drop #empezar {
  margin-top: 12px;
  padding: 13px 22px;
  border-radius: 500px;
  font-size: 15.5px; font-weight: 550; letter-spacing: -.015em;
}

/* Los formatos que entran van adentro del recuadro y debajo del renglon que
   dice donde soltar: son lo que hay que traer, y el recuadro es el lugar donde
   se sueltan. Asomando por abajo de la tarjeta se leian como una nota al pie;
   adentro, la tarjeta entera dice "esto es lo que entra y aca va".

   Se hunden por el canto de abajo: se comen el relleno entero y ocho pixeles
   mas, que el overflow de la tarjeta corta. Ocho y no mas porque la sigla
   tiene que entrar entera -una hoja de color con media palabra cortada no dice
   que formato es-, y lo que se pierde es el borde de abajo, que no dice nada.
   Tapadas hasta ahi se leen como hojas metidas adentro y no como cuatro iconos
   apoyados.

   Son parte de la invitacion, asi que se van con ella cuando llega un archivo,
   sin regla propia. */
#formatos {
  margin-top: 26px;
  margin-bottom: calc(var(--pad-drop) * -1 - 8px);
  display: flex; align-items: flex-start; justify-content: center;
  gap: 17px;
  /* Soltar y hacer clic siguen siendo de la tarjeta: las hojas son un dibujo,
     no botones. */
  pointer-events: none;
}
/* La luz va en el envoltorio y no en el <svg>. Un filtro de CSS puesto sobre un
   <svg> se recorta a la region de filtro que manda SVG -el alto y ancho de la
   hoja mas un diez por ciento-, asi que un desenfoque de veintidos pixeles
   sobre un icono de treinta y ocho se corta a los cuatro: la luz quedaba
   cuadrada, con el canto marcado a los costados. En un elemento de HTML no hay
   region que la ate y se apaga sola. */
#formatos .formato {
  width: 38px; height: 47px; display: block;
  transform-origin: 50% 50%;
  /* Abajo de cada hoja queda una luz de su propio color, desenfocada: el rojo
     del PDF tira rojo sobre el vidrio y el azul del Keynote tira azul. Sale de
     currentColor, que ya es el color del formato, asi que agregar uno nuevo
     sigue siendo una linea. Van dos: una corta y fuerte que la apoya, y una
     larga y suave que la despega del fondo. La sombra negra queda al final
     para que la hoja no flote sobre su propia luz. */
  filter:
    drop-shadow(0 5px 9px color-mix(in srgb, currentColor 52%, transparent))
    drop-shadow(0 11px 22px color-mix(in srgb, currentColor 34%, transparent))
    drop-shadow(0 6px 16px rgba(0, 0, 0, .45));
}
#formatos .formato .papel { width: 100%; height: 100%; display: block; }
/* Inclinadas y alternadas, como quedan cuatro hojas tiradas sobre la mesa. Los
   angulos no son el mismo espejado: a nueve y nueve la fila se lee como un
   zigzag dibujado, y lo que tiene que parecer es que quedaron asi. Las que van
   hacia la derecha bajan dos pixeles, que es lo que hace que no se lean como
   una sola linea. */
#formatos .formato:nth-child(1) { transform: rotate(-9deg); }
#formatos .formato:nth-child(2) { transform: rotate(6deg) translateY(2px); }
#formatos .formato:nth-child(3) { transform: rotate(-5deg); }
#formatos .formato:nth-child(4) { transform: rotate(8deg) translateY(2px); }

/* El mismo vidrio que la carpeta y el candado del sitio: el color nunca es
   opaco, entra por arriba a la izquierda y se va abriendo hacia abajo a la
   derecha. El color se declara UNA vez por formato, en color, y las tres
   paradas lo toman con currentColor: asi agregar un formato es una linea y no
   cuatro. */
#formatos .formato .f-s1 { stop-color: currentColor; stop-opacity: .95; }
#formatos .formato .f-s2 { stop-color: currentColor; stop-opacity: .78; }
#formatos .formato .f-s3 { stop-color: currentColor; stop-opacity: .6; }

#formatos .pdf  { color: #E5252A; }
#formatos .ppt,
#formatos .pptx { color: #CE5A24; }
#formatos .key  { color: #1E8FE1; }

/* El doblez es el reves de la hoja: mas claro, no mas oscuro. Una esquina
   doblada deja ver el dorso del papel, que recibe la luz de frente. */
#formatos .formato .f-doblez { fill: #fff; fill-opacity: .34; }
/* Los dos lustres son el reflejo de una ventana sobre el plastico: una franja
   ancha y otra fina, las dos en diagonal y recortadas por la hoja. */
#formatos .formato .f-lustre   { fill: #fff; opacity: .2; }
#formatos .formato .f-lustre-2 { fill: #fff; opacity: .08; }
#formatos .formato .f-labio,
#formatos .formato .f-canto { fill: none; stroke-linecap: round; }
#formatos .formato .f-labio { stroke: #fff; stroke-opacity: .55; stroke-width: 1; }
#formatos .formato .f-canto { stroke: #fff; stroke-opacity: .3; stroke-width: .9; }

/* La sigla va en blanco y con la tipografia de la app: si se la deja al SVG, el
   navegador le pone su serif por defecto. */
#formatos .formato text { fill: #fff; font-family: inherit; letter-spacing: -.02em; }

/* El hueco de abajo es el que le devuelve el ultimo archivo a la vista: cuando
   la lista termina, el desvanecido cae sobre este aire y no sobre el renglon.
   Lo lleva la lista y no la portada entera porque es la lista lo que desborda;
   sin archivos no hay nada que se corte y la portada sigue centrada como
   estaba. */
#recientes {
  width: min(580px, 92vw);
  padding-bottom: var(--desvanecido);
  z-index: 1;
  animation: llegar .8s .12s var(--ease) both;
}
#recientes h3 {
  margin: 4px 0 8px 4px;
  font-size: 13px; font-weight: 500;
  color: var(--faint);
  letter-spacing: -.01em;
}
.reciente {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 14px;
  margin-bottom: 4px;
  border-radius: 14px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.reciente .icono-doc { width: 17px; height: 17px; color: var(--faint); flex-shrink: 0; }
.reciente .titulo { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reciente .cuenta {
  color: var(--faint); font-size: 13px; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Cuantas diapositivas quedaron sin entender, y el camino de vuelta a la
   primera. El numero y el senalador, y nada mas: es el mismo dibujo que marca
   los parrafos en el guion, asi que la fila no necesita explicarlo con
   palabras y no le come el lugar al nombre del documento. Lo que es, lo dice al
   pasar por encima. */
.reciente .marcadas {
  flex-shrink: 0;
  display: flex;
  gap: 4px;
  padding: 3px 7px 3px 10px;
  background: transparent;
  border-color: var(--edge);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.reciente .marcadas svg { width: 13px; height: 13px; fill: currentColor; stroke: none; }
.reciente .marcadas:hover { background: var(--glass-hi-2); color: var(--text); }
.reciente:hover {
  background: var(--glass-hi);
  border-color: var(--edge);
  -webkit-backdrop-filter: var(--blur-sm);
  backdrop-filter: var(--blur-sm);
}
.reciente:hover .icono-doc { color: var(--text); }

#aviso {
  width: min(580px, 92vw);
  padding: 12px 16px;
  border-radius: 14px;
  font-size: 13.5px;
  color: var(--muted);
  border: 1px solid var(--edge);
  background: var(--glass);
  -webkit-backdrop-filter: var(--blur-sm);
  backdrop-filter: var(--blur-sm);
}

/* -------------------------------------------------------------- el plan */
/* Lo que queda de la version gratis. En estado normal es la pieza mas callada
   de la portada: un renglon, una barra de un pelo y una linea gris. No tiene
   borde ni vidrio a proposito, para que no compita con la tarjeta de arriba,
   que es donde hay que soltar el archivo.

   Cuando se acaban las presentaciones, la misma pieza se levanta: aparece el
   vidrio, el texto sube a primer plano y el enlace de comprar se vuelve la
   accion principal. No es otra tarjeta ni otro lugar; es esta, que pasa a
   importar. */

#plan {
  width: min(580px, 92vw);
  padding: 14px 16px;
  border-radius: 16px;
  border: 1px solid transparent;
  animation: llegar .8s .16s var(--ease) both;
  transition: background .3s var(--ease), border-color .3s var(--ease),
              padding .3s var(--ease);
}

.plan-linea {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 13px;
}
.plan-nombre { font-weight: 550; letter-spacing: -.01em; color: var(--text-2); }
.plan-cuenta {
  margin-left: auto;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

/* La barra es de un pelo: dice de un vistazo por donde vas y no pide que la
   mires. La parte llena es la misma tinta que el resto del cromo, no un color
   de alarma: que queden tres presentaciones no es un problema. */
.plan-barra {
  height: 3px;
  margin: 9px 0 8px;
  border-radius: 999px;
  background: var(--pista);
  overflow: hidden;
}
.plan-barra i {
  display: block; height: 100%;
  border-radius: 999px;
  background: var(--solido);
  transition: width .6s var(--ease);
}

/* El pie, todo en un renglon: comprar, la cuenta y la llave. Son tres cosas
   cortas, y apiladas ocupaban tres lineas para decir lo que entra en una. */
.plan-pie {
  display: flex; align-items: center; gap: 14px;
  margin-top: 10px;
}
.plan-nota { flex: 1; min-width: 0; margin: 0; font-size: 12.5px; color: var(--faint); line-height: 1.45; }

/* Una clase con display le gana al hidden del navegador, que es apenas un
   display:none sin especificidad ninguna. Sin esto, el formulario de la clave
   estaria siempre a la vista y los botones seguirian ahi con la app ya
   comprada. */
.plan-comprar[hidden], .plan-forma[hidden] { display: none; }

/* Comprar es un enlace mientras queden presentaciones: no hay nada que
   apurar. Con la cuenta en cero se convierte en boton, abajo. */
.plan-comprar {
  color: var(--text-2);
  font-size: 12.5px; font-weight: 550;
  text-decoration: none;
  border-bottom: 1px solid var(--edge-hi);
  padding-bottom: 1px;
  transition: color .2s var(--ease), border-color .2s var(--ease);
}
.plan-comprar:hover { color: var(--text); border-color: var(--edge-max); }

/* "Ya la compre" es una llave y no una frase: es la puerta de servicio, y la
   usa el que vuelve con la clave en la mano, que ya sabe que viene a hacer.
   Escrita ocupaba en la fila lo mismo que la oferta y discutia con ella. */
.plan-tengo {
  width: 30px; height: 30px;
  flex-shrink: 0;
  /* Del mismo oro que la grande: es la misma llave, y es lo que abre. Va un
     poco apagada de entrada -no es la accion principal de la fila- y se
     enciende del todo cuando le apoyas el puntero. */
  color: var(--oro);
  opacity: .72;
}
/* Maciza y no de alambre, al reves que el resto de los iconos: es la unica
   figura de la fila y a 17px un pelo de 1.7 se pierde contra el texto de al
   lado. Y va rellena y de una sola pieza -aro, cuerpo y dientes en un solo
   path- y no dibujada con tres trazos: el color de este boton es
   semitransparente, y tres trazos que se pisan suman opacidad justo en las
   uniones, que es donde se veian dos rayas mas claras cruzando la llave. Una
   figura sola se pinta una sola vez y no tiene donde sumar. */
.plan-tengo svg { width: 17px; height: 17px; }
.plan-tengo:hover:not(:disabled) { opacity: 1; }
.plan-comprar, .plan-tengo { flex-shrink: 0; }

/* ---- las laminas que tapan la pantalla ---- */
/* Tapa la pantalla entera. El fondo no se va: queda atras, desenfocado y
   apagado, que es lo que dice que esto es una puerta abierta sobre la portada y
   no otra pantalla. Va en position:fixed y cuelga del body, no del #setup: el
   #setup tiene su propio scroll, y adentro de una caja que scrollea una lamina
   que tapa todo se va con el scroll. */
.hoja {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--velo);
  -webkit-backdrop-filter: blur(22px) saturate(120%);
  backdrop-filter: blur(22px) saturate(120%);
  animation: revelar .25s var(--ease) both;
}
.hoja[hidden] { display: none; }
/* Al cerrarse no desaparece: se apaga. Abrir algo que tapa la pantalla entera y
   despues sacarlo de un tiron es un corte, y lo que habia atras aparece como si
   fuera otra pagina. Yendose, el velo se suelta y la lamina se hunde un poco,
   que es el mismo gesto de entrada al reves. */
.hoja.yendose { animation: apagarse .22s var(--ease) both; }
.hoja.yendose .lamina { animation: hundirse .22s var(--ease) both; }

.hoja .lamina {
  position: relative;
  width: min(430px, 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 34px 30px 30px;
  border-radius: 26px;
  border: 1px solid var(--edge);
  background: var(--glass-hi);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  box-shadow: var(--sombra-lg), var(--canto);
  animation: brotar .45s var(--ease) both;
}
/* Lo que corona cada lamina es una PIEZA y no un icono: es lo unico que hay
   que mirar ahi, asi que va grande y con el mismo vidrio que las hojas de
   formato. Son tres -la llave, la tuerca y el globo- y se dibujan igual: el
   degrade que cae de arriba a la izquierda con sus tres paradas en
   currentColor, los dos lustres cruzando por dentro del recorte y el pelo de
   luz en el canto. Lo unico que cambia entre una y otra es el color, que es del
   objeto: el oro es el unico lugar tibio de la app y va en la llave a proposito
   -eso es lo que se compra-, la tuerca es de acero y la burbuja es celeste. */
.hoja .pieza {
  width: 76px; height: 76px;
  display: block;
  /* Centrada aunque la lamina no centre: la de los ajustes y la de contarnos
     algo alinean su contenido a la izquierda, porque son cosas que se leen
     renglon por renglon, y la pieza igual va al medio. */
  align-self: center;
  /* El aire de abajo va escrito aca y no queda librado al gap de la lamina: el
     dibujo no llena el cuadro del svg, asi que el hueco que se ve es menor que
     el que dice el numero. */
  margin-bottom: 12px;
  /* Sombra y nada mas. La pieza ya es lo unico con color de la lamina; sumarle
     ademas su propia luz atras la convertia en una mancha y le comia el filo. */
  filter: drop-shadow(0 12px 26px rgba(0, 0, 0, .5));
  animation: brotar .6s .1s var(--ease) both;
}
.hoja .llave  { color: var(--oro); }
.hoja .tuerca { color: var(--acero); }
.hoja .burbuja { color: var(--celeste); }
.hoja .b-punto { fill: var(--burbuja-punto); }

/* Casi opaca: la pieza es de un material, no un vidrio de color. Lo que la hace vidrio
   es el degrade, el lustre y el canto, no la transparencia -sobre el negro de
   la lamina, dejarla pasar la volvia un ocre apagado. */
.hoja .k-s1 { stop-color: currentColor; stop-opacity: 1; }
.hoja .k-s2 { stop-color: currentColor; stop-opacity: .92; }
.hoja .k-s3 { stop-color: currentColor; stop-opacity: .78; }
.hoja .k-lustre   { fill: #fff; opacity: .22; }
.hoja .k-lustre-2 { fill: #fff; opacity: .1; }
/* El canto: el pelo de luz que separa la pieza del fondo, igual que en las
   laminas del resto de la app. */
.hoja .k-canto {
  fill: none;
  stroke: #fff; stroke-opacity: .32; stroke-width: 1.6;
  stroke-linejoin: round;
}
.hoja h2 {
  margin: 0;
  font-family: var(--serif);
  font-size: 25px; font-weight: 500;
  letter-spacing: -.02em;
}
.hoja p {
  margin: 0;
  max-width: 34ch;
  color: var(--muted);
  font-size: 13.5px; line-height: 1.5;
}
/* La cruz va en la esquina de la lamina, no arriba de todo: lo que se cierra es
   esta ventana, y el gesto tiene que salir de ella. */
.cerrar-hoja {
  position: absolute;
  top: 10px; right: 10px;
  width: 32px; height: 32px;
  background: none; border-color: transparent; box-shadow: none;
  color: var(--faint);
}
.cerrar-hoja:hover:not(:disabled) { background: var(--glass-hi-2); color: var(--text); }

/* Adentro de la lamina el formulario ocupa el ancho entero: es lo unico que hay
   que hacer ahi, no un renglon mas de una tarjeta. */
#activar .plan-forma { width: 100%; margin-top: 8px; }
#activar .plan-forma input { padding: 12px 15px; font-size: 14px; border-radius: 13px; }
#activar .plan-forma button { height: 44px; padding: 0 22px; font-size: 14px; }
#activar .mal {
  margin: 0;
  max-width: 34ch;
  color: var(--peligro);
  font-size: 13px; line-height: 1.45;
  animation: revelar .25s var(--ease) both;
}
#activar .mal[hidden] { display: none; }

.plan-forma { display: flex; gap: 8px; margin-top: 10px; }
.plan-forma input {
  flex: 1; min-width: 0;
  padding: 9px 13px;
  border-radius: 11px;
  border: 1px solid var(--edge);
  background: var(--glass-hi);
  font-size: 13px;
  letter-spacing: .04em;
  text-transform: uppercase;
  transition: border-color .2s var(--ease);
}
.plan-forma input::placeholder { color: var(--faint); letter-spacing: .02em; }
.plan-forma input:focus { outline: none; border-color: var(--edge-max); }
.plan-forma.mal input { border-color: var(--peligro-borde); }
.plan-forma button { padding: 0 18px; height: 38px; font-size: 13px; font-weight: 550; }

/* La cuenta en cero. Lo unico que cambia es el peso: el mismo cartel, ahora
   adelante. */
#plan.sin-cupo {
  padding: 18px;
  border-color: var(--edge);
  background: var(--glass);
  -webkit-backdrop-filter: var(--blur-sm);
  backdrop-filter: var(--blur-sm);
  box-shadow: var(--sombra), var(--canto);
}
#plan.sin-cupo .plan-nombre { color: var(--text); }
#plan.sin-cupo .plan-nota { color: var(--text-2); font-size: 13px; }
#plan.sin-cupo .plan-comprar {
  padding: 9px 18px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--solido);
  color: var(--sobre-solido);
  box-shadow: var(--sombra-solido);
}
#plan.sin-cupo .plan-comprar:hover { background: var(--solido-hi); }

/* Ya pagada: no hay cuenta que llevar, asi que la barra no esta. Queda el
   nombre, la clave en chiquito y el gracias. */
#plan.pro .plan-barra { display: none; }
#plan.pro .plan-nota { margin-top: 8px; }
#plan.pro .plan-cuenta { font-size: 11.5px; letter-spacing: .06em; }

/* ------------------------------------------------------------------ lector */

#lector { position: relative; z-index: 1; flex: 1; display: none; min-height: 0; }
body.leyendo #setup { display: none; }
body.leyendo #lector { display: block; }

/* Arriba no hay barra: hay dos piezas sueltas flotando. */
header {
  position: absolute;
  top: 16px; right: 20px;
  z-index: 30;
  display: flex; align-items: center; gap: 8px;
  animation: caer .6s var(--ease) both;
}
/* El nombre del archivo no es un control: es el encabezado de la columna.
   Alto igual al de la X para que las dos cosas caigan sobre la misma linea. */
.cabecera {
  height: 38px;
  flex-shrink: 0;
  display: flex; align-items: center;
  /* La X y el tiempo que falta flotan justo encima, asi que este es el hueco
     que el titulo les cede. No puede ser fijo: "Quedan 2 h 05 min" ocupa mucho
     mas que "Quedan 3 min" y a veces el dato ni se muestra, asi que lo mide el
     JS. El 46 es solo el fallback para el primer pintado, con la X sola. */
  padding-right: var(--hueco-header, 46px);
}
.doc-nombre {
  color: #fff;
  font-size: 13px;
  min-width: 0;
  overflow: hidden; white-space: nowrap;
  animation: llegar .7s .1s var(--ease) both;
}
/* Cuando el nombre no entra se desvanece, en vez de cortarse con puntos
   suspensivos: el corte duro parece parte del nombre, el degradado se lee como
   lo que es. Va como mascara y no como degradado de fondo para que funcione
   igual sobre cualquier cosa que haya detras.
   Solo cuando de verdad sobra texto: aplicado siempre le comeria el final a un
   titulo corto que entraba entero. */
.doc-nombre.recortado {
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 38px), transparent);
  mask-image: linear-gradient(90deg, #000 calc(100% - 38px), transparent);
}

main {
  position: absolute;
  inset: 0;
  display: flex;
  gap: 20px;
  padding: 16px 20px 20px;
  min-height: 0;
}

/* Sin recorte a proposito. La diapositiva ya viene acotada por max-width y
   max-height a la caja del visor, asi que nunca puede desbordarlo: medido, el
   desborde es cero o negativo en cualquier tamano de ventana. Con overflow:auto
   no habia entonces nada que scrollear, y lo unico que recortaba era la sombra
   del papel, justo en el lado por el que la diapositiva queda a ras -los
   costados en una ventana ancha, arriba y abajo en una angosta-, dejando media
   pagina sin borde. Sobre negro no se notaba porque ahi la sombra es invisible.
   La sombra cae sobre el padding de main, que esta vacio. */
#visor {
  flex: 1;
  min-height: 0;
  display: flex; align-items: center; justify-content: center;
  overflow: visible;
  min-width: 0;
}

/* La diapositiva no lleva marco: es papel apoyado sobre el negro. */
#lienzo {
  position: relative;
  line-height: 0;
  border-radius: 14px;
  box-shadow: var(--sombra-papel);
  animation: llegar .5s var(--ease) both;
}
#lienzo img {
  max-width: 100%;
  max-height: calc(100vh - 36px);
  border-radius: 14px;
  display: block;
}

/* ---------------------------------------------------------- mirar de cerca */
/* Dos dedos que se abren sobre la lamina la agrandan. No hay controles: el
   gesto es el control, y lo pone el js en el transform del lienzo.

   Aca arriba el visor no recorta a proposito -para no comerse la sombra del
   papel-, y eso vale mientras la diapositiva entra entera. Agrandada no entra,
   y sin recorte se le iria encima del guion y de los controles: mientras dura
   el zoom, entonces, el visor recorta. La sombra no se extrana porque ya no hay
   negro alrededor que la pueda mostrar. */
body.con-zoom #visor { overflow: hidden; border-radius: 14px; }
/* De cerca la lamina se agarra y se corre. De lejos no: un cursor de mano
   invitando a arrastrar algo que no se mueve es una promesa que no se cumple. */
body.con-zoom #lienzo { cursor: grab; }
body.con-zoom.paseando #lienzo { cursor: grabbing; }
/* Nada de transition en el transform: el dibujo tiene que ir pegado a los
   dedos. Una transicion, por corta que sea, se siente como que el gesto va
   atrasado. */

/* ------------------------------------------------------- cambio de diapositiva */
/* Pasar de una a otra no es cambiar el src de golpe: la que sale se queda un
   momento encima, opaca, y se disuelve dejando ver la que ya esta abajo.

   Que la que sale vaya ARRIBA y entera es lo que evita el bajon de opacidad
   del medio: si las dos se cruzaran a media opacidad, por un instante se
   transparentaria el fondo entre las dos y el papel parpadearia.

   No hay movimiento de ningun tipo, y es a proposito. Las dos tienen que medir
   exactamente lo mismo: si la que entra estuviera apenas escalada, quedaria un
   anillo de esa diferencia en todo el perimetro donde la que se va se disuelve
   contra el fondo en vez de contra la que llega. Con una diapositiva de color
   plano no se ve; con una foto que llega hasta el borde se lee como si la
   imagen estuviera cortada. Por lo mismo tampoco se desplaza: un deslizamiento
   obligaria ademas a recortar el lienzo, y ahi se cortaria el halo de los
   indicadores que tocan el borde de la pagina. */

#fantasma {
  position: absolute;
  top: 0; left: 0;
  /* Su tamano lo fija el js en px, con el que tenia la que salio: si la
     diapositiva nueva viene con otra proporcion, el lienzo cambia de alto y
     estirar el cuadro que se va lo deformaria justo mientras se desvanece. */
  max-width: none;
  max-height: none;
  opacity: 0;
  pointer-events: none;
  transition: opacity .34s var(--ease);
}
#fantasma.visible { opacity: 1; }

/* El puntero: un marco que rodea la seccion que se esta explicando y se desliza
   hasta la siguiente.

   Enmarca, no tapa. No lleva relleno ni backdrop-filter: cualquier velo sobre
   el papel, por suave que sea, estorba justo donde hay que leer. Todo el dibujo
   (trazo y halo) crece HACIA AFUERA del recuadro via box-shadow, y el recuadro
   ya viene con aire de sobra respecto del texto. */
.marca {
  position: absolute;
  border-radius: 14px;
  pointer-events: none;
  opacity: 0;
  background: transparent;
  /* trazo nitido, halo que lo despega del papel, y profundidad */
  box-shadow: var(--marca);
  transition: opacity .3s var(--ease),
              left .5s var(--resorte), top .5s var(--resorte),
              width .5s var(--resorte), height .5s var(--resorte);
}
.marca.visible { opacity: 1; }

/* Sin lamina, sin borde, sin sombra: la explicacion es texto apoyado sobre la
   pantalla. Lo unico que la delimita es el desvanecido de los extremos. */
aside {
  width: 372px;
  flex-shrink: 0;
  display: flex; flex-direction: column;
  min-height: 0;
  animation: entrar .6s var(--ease) both;
}

/* ------------------------------------------------------------ teleprompter */
/* El guion no es una lista: es una cinta que pasa. Lo que sono se apaga hacia
   arriba, lo que viene asoma desde abajo, y los dos extremos se disuelven. */

/* Cuando la cara termina de pensar y se va arriba, el guion vuelve a aparecer
   en el mismo cuadro en que ella arranca el viaje, y verlo llegar de golpe
   debajo de algo que todavia esta volando se lee como un error. Asi que espera:
   se revela cuando ella ya casi aterrizo. El retardo cuenta desde que el guion
   vuelve a mostrarse, que es exactamente cuando empieza el viaje. */
#guion {
  animation: revelar .45s .45s var(--ease) both;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 4px;
  scroll-behavior: smooth;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 20%, #000 74%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 20%, #000 74%, transparent);
}
#guion::-webkit-scrollbar { width: 0; }

/* Aire arriba y abajo para que el primer y el ultimo parrafo puedan llegar al
   centro de la columna. Va como contenido y no como padding: con border-box, el
   padding le pone un alto minimo a la columna y el reproductor se cae afuera. */
#guion::before { content: ""; display: block; height: 34vh; }
#guion::after { content: ""; display: block; height: 42vh; }

.seg {
  position: relative;
  padding: 10px 2px;
  margin-bottom: 14px;
  cursor: pointer;
  font-size: 18px;
  line-height: 1.55;
  letter-spacing: -.014em;
  color: var(--text);
  opacity: .26;
  transform: scale(.985);
  transform-origin: left center;
  transition: opacity .5s var(--ease), transform .5s var(--resorte),
              filter .5s var(--ease);
  filter: blur(.5px);
}
.seg:hover { opacity: .6; filter: none; }
.seg.listo { opacity: .34; filter: none; }

/* Lo que no se entendio queda un punto mas presente que el resto de la cinta.
   Es poco a proposito: sigue siendo un parrafo que ya paso, no una alarma. Pero
   tiene que poder encontrarse de un vistazo al volver, y con la opacidad de los
   demas no se encontraria. */
.seg.marcada { opacity: .5; filter: none; }

/* El senalador va detras de la ultima palabra del parrafo, no flotando al
   costado: en una columna de 372 puntos, un boton a la derecha se le viene
   encima al texto justo en el renglon mas largo. Mientras no este marcado no se
   ve, y aparece al pasar por encima, igual que la papelera de los recientes. */
.seg-duda, .seg-invento {
  display: inline-grid;
  vertical-align: -4px;
  width: 20px; height: 20px;
  margin-left: 4px;
  padding: 0;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  color: var(--faint);
  opacity: 0;
  transition: opacity .2s var(--ease), color .2s var(--ease),
              transform .3s var(--resorte);
}
.seg-duda svg, .seg-invento svg { width: 15px; height: 15px; }
.seg:hover .seg-duda, .seg-duda:focus-visible,
.seg:hover .seg-invento, .seg-invento:focus-visible { opacity: 1; }
.seg-duda:hover, .seg-invento:hover { color: var(--text); }

/* Marcado es el mismo dibujo macizo. No es otro icono ni es de otro color: el
   unico color de la interfaz es el de eliminar, y no entender algo no es un
   peligro ni un error. */
.seg-duda.marcada { opacity: 1; color: var(--text-2); }
.seg-duda.marcada svg { fill: currentColor; stroke: none; }

/* El segundo senalador, el de lo que la lamina no dice, se comporta igual que
   el otro: escondido hasta que pasas por encima, sin color y del mismo tamano.
   Son dos cosas del mismo rango -no entendi esto, esto no era cierto- y una de
   las dos gritando le sacaria el lugar a la otra.
   Lo que no tiene es estado marcado, porque no es un interruptor: marcar abre
   una revision, y de la revision sale el parrafo corregido o no sale nada. */
.seg.revisando .seg-invento { opacity: 1; color: var(--text-2); }
.seg.revisando .seg-invento svg { animation: ob-latir 1.1s ease-in-out infinite; }

/* Lo que contesto la revision, debajo del parrafo. Chico y apagado: es una
   respuesta de una linea y se va sola a los pocos segundos. */
.seg-nota {
  display: block;
  margin-top: 6px;
  font-size: 12.5px;
  line-height: 1.4;
  letter-spacing: -.005em;
  color: var(--faint);
  animation: llegar .35s var(--ease);
}

/* El parrafo que acaba de cambiar de texto. Un destello y nada mas: si no se
   avisa, el que estaba leyendo ve otra frase donde habia una y no entiende que
   paso. */
.seg.rehecha { opacity: 1; filter: none; }
.seg.rehecha .seg-txt { animation: llegar .5s var(--ease); }

/* El parrafo que suena: el resto sale de foco y este queda nitido y mas grande. */
.seg.activo {
  opacity: 1;
  filter: none;
  transform: scale(1);
  font-size: 17.5px;
  font-weight: 480;
  line-height: 1.5;
  letter-spacing: -.019em;
}

/* ----------------------------------------------------------- la pregunta */
/* Se acabo la diapositiva y, antes de pasar, el profesor pregunta una cosa.
   Ocupa el lugar del guion en vez de apoyarse encima: mientras se piensa la
   respuesta no puede quedar nada mas que leer, porque todo lo demas ES la
   respuesta. Por eso tambien se desenfoca la lamina.

   Es la tercera escena que se apodera de la columna, despues de la espera y del
   final, y se arma igual que ellas: centrada, una sola cosa que leer y nada de
   cromo alrededor. */

#pregunta {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  padding: 20px 6px;
  overflow-y: auto;
  animation: llegar .5s var(--ease) both;
}
/* Igual que el cartel de la espera: el display de aca le gana al [hidden] del
   HTML, asi que hay que apagarlo a mano. */
#pregunta[hidden] { display: none; }
body.preguntando #guion { display: none; }

/* La pregunta va en la serif de los titulos. No es la voz del profesor leyendo
   -eso es el guion- sino la unica linea de la pantalla, y tiene que leerse como
   algo que alguien te pregunta y espera. */
.pregunta-txt {
  margin: 0;
  max-width: 300px;
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.45;
  letter-spacing: -.012em;
  text-align: center;
  text-wrap: balance;
}

/* La consigna de la abierta va pegada a la pregunta, no a 24px como el resto de
   la tarjeta: es parte de lo que se acaba de leer y no otra cosa que leer. Y va
   en chico y en gris, que no es lo que se pregunta sino como se contesta. */
.pregunta-consigna {
  margin: -14px 0 0;
  max-width: 300px;
  color: var(--faint);
  font-size: 12.5px;
  line-height: 1.5;
  text-align: center;
}
.pregunta-consigna[hidden] { display: none; }

/* La respuesta llega debajo, del tamano y el tono del guion: no es el titulo de
   la escena, es con lo que se compara lo que uno habia pensado. El filo de
   arriba es lo unico que las separa, y no hace falta mas. */
.pregunta-resp {
  margin: 0;
  max-width: 300px;
  padding-top: 22px;
  border-top: 1px solid var(--edge);
  color: var(--text-2);
  font-size: 15.5px;
  line-height: 1.55;
  text-align: center;
  text-wrap: pretty;
  animation: llegar .4s var(--ease) both;
}

/* Los botones respiran aparte de la respuesta. El aire de la tarjeta alcanza
   entre la pregunta y lo que sigue, pero entre lo que acabas de leer y el boton
   que lo da por leido tiene que haber un poco mas: es la diferencia entre
   terminar de leer y apretar sin haber terminado. */
.pregunta-pie { display: flex; margin-top: 14px; }
.pregunta-juicio { display: flex; gap: 8px; }
.pregunta-juicio[hidden] { display: none; }
#pregunta button { padding: 10px 17px; font-size: 13.5px; font-weight: 500; }
/* El boton del hueco es uno solo y cambia de palabra segun si escribiste algo,
   asi que cambia de ancho. El ancho lo mide el js y lo escribe en pixeles: sin
   eso no hay nada que transicionar -de un auto a otro auto no se puede- y el
   boton daria un salto justo cuando estas mirando lo que dice. */
#ver-respuesta { white-space: nowrap; transition: width .3s var(--ease); }
#pregunta button[hidden] { display: none; }

/* La lamina se apaga mientras se piensa: con la respuesta a la vista, contestar
   no es acordarse, es leer. No se tapa ni se saca, se desenfoca, que es lo que
   separa "no mires" de "no esta": el papel sigue ahi, con su sombra y su canto,
   y lo unico que no se puede leer es lo que dice.

   Al ver la respuesta vuelve, y vuelve con el recuadro encendido justo donde
   esa respuesta vive. Eso es lo que convierte un "no la tenia" en un "estaba
   aca". */
#pagina { transition: filter .5s var(--ease); }
body.preguntando #pagina { filter: blur(16px) brightness(.72); }
body.preguntando.respondida #pagina { filter: none; }

/* ---- la de opcion multiple ---- */
/* Cuatro botones del mismo vidrio que el resto, uno debajo del otro. En fila
   quedarian cuatro cajas angostas con el texto partido en cuatro renglones, y
   lo que hay que comparar es justamente el texto. */
.pregunta-opciones {
  display: flex;
  flex-direction: column;
  gap: 7px;
  width: 100%;
}
.pregunta-opciones[hidden] { display: none; }
.opcion {
  padding: 11px 15px;
  border-radius: 14px;
  font-size: 14px;
  line-height: 1.4;
  text-align: left;
  place-items: start;
}
/* Ya contestada: la buena se pone solida -es la unica pieza opaca que tiene la
   app, y aca dice "esta era"- y la que se eligio, si no era, se apaga en el
   unico color que hay. Las otras dos se corren del medio sin desaparecer: siguen
   estando para poder leerlas. */
.opcion:disabled { opacity: .4; }
.opcion.buena:disabled {
  opacity: 1;
  background: var(--solido);
  border-color: transparent;
  color: var(--sobre-solido);
  box-shadow: var(--sombra-solido);
}
.opcion.mala:disabled {
  opacity: 1;
  background: var(--peligro-fondo);
  border-color: var(--peligro-borde);
  color: var(--peligro);
}

/* ---- la del hueco ---- */
/* El hueco es un subrayado del ancho de lo que va adentro. Cuando se completa,
   la palabra cae ahi mismo: verla entrar en su lugar dice mas que un cartel al
   pie, y deja la frase entera para leerla de una. */
.hueco-marca {
  display: inline-block;
  min-width: 5.5ch;
  padding: 0 .12em;
  border-bottom: 2px solid var(--edge-hi);
  text-align: center;
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.hueco-marca.buena { color: var(--acierto); border-color: var(--acierto-borde); }
.hueco-marca.mala { color: var(--peligro); border-color: var(--peligro-borde); }
/* Puesta sin veredicto: la palabra que iba, cuando lo escrito no coincidio o
   cuando se pidio verla. El rojo de las opciones no va aca: ahi el programa
   sabe cual apretaste, y en el hueco lo unico que sabe es que lo que escribiste
   no es igual, que no es lo mismo que decir que no la sabias. */
.hueco-marca.revelada { border-color: var(--edge-max); }

.pregunta-hueco { display: flex; width: 100%; }
.pregunta-hueco[hidden] { display: none; }
.pregunta-hueco input {
  flex: 1;
  min-width: 0;
  padding: 11px 15px;
  border-radius: 13px;
  border: 1px solid var(--edge);
  background: var(--glass-hi);
  color: var(--text);
  font-size: 14px;
}
.pregunta-hueco input:focus { outline: 2px solid var(--foco); outline-offset: 2px; }

/* ---- explicamelo vos ---- */
/* El boton de hablar es el unico redondo grande de la app y esta solo en el
   medio: es lo unico que hay que hacer ahi. Mientras graba late, que es la
   unica manera de que no queden dudas de que el microfono esta abierto. */
.pregunta-hablar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.pregunta-hablar[hidden] { display: none; }
#grabar {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 20px;
  font-size: 14px;
  font-weight: 500;
}
#grabar svg { width: 17px; height: 17px; }
#grabar.grabando {
  background: var(--peligro-fondo);
  border-color: var(--peligro-borde);
  color: var(--peligro);
  box-shadow: none;
  animation: palpito 2s var(--ease) infinite;
}
/* La onda de lo que estas diciendo, entre la consigna y el boton.

   Cada barra es un pedacito de tiempo y guarda lo mas fuerte que sono ahi; la
   fila entera son los ultimos tres segundos y corre hacia la izquierda mientras
   hablas. En gris y no en rosa: el rosa es el boton, que es lo que tenes que
   apretar cuando terminaste. La onda no te pide nada, solo te muestra que el
   microfono te esta agarrando, asi que va del color del resto del texto.

   Va con transicion corta y lineal, no con una curva: cada barra salta a su
   altura y ahi se queda hasta que la corren. Una curva con rebote le pondria un
   vaiven que tu voz no tuvo. */
.hablar-onda {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 30px;
  color: var(--text-2);
  animation: revelar .3s var(--ease) both;
}
.hablar-onda[hidden] { display: none; }
.hablar-onda i {
  width: 3px;
  height: 100%;
  border-radius: 99px;
  background: currentColor;
  transform: scaleY(.06);
  transition: transform .07s linear;
}

/* Va arriba de la onda y del boton, y no al pie: pegado abajo se leia como la
   etiqueta del boton, que es lo unico que no es. Queda mas cerca de la consigna
   que de la fila de abajo -doce contra veintiocho- porque es de ahi: es en que
   anda lo que te pidieron, no que hacer con el boton.

   Las cifras van tabulares para que el reloj no se ensanche al pasar de 0:09 a
   0:10, y cuando no dice nada desaparece en vez de guardar el hueco: la pantalla
   con la que empezas es la consigna y el boton, sin un renglon vacio en el
   medio. El boton se corre igual al arrancar -entra la onda, que mide treinta-
   asi que reservar trece no le ahorraba el salto a nadie. */
.hablar-estado {
  margin: -12px 0 14px;
  color: var(--muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.hablar-estado:empty { display: none; }

/* Lo que se te entendio, en chico y en gris: es para mirarlo de refilon y ver
   que el microfono agarro lo que dijiste, no para leerlo.

   Casi siempre no entra entero, y el texto se iba en un corte al ras: una
   linea partida por la mitad parece un error de dibujo, no un texto que sigue.
   Los dos bordes se desvanecen, entonces, y el que se desvanece es el que
   tiene algo del otro lado: arriba del todo no hay velo hasta que empezas a
   bajar, y abajo el velo se va justo cuando llegas al final. El js mide cuanto
   queda a cada lado y lo pone en estas dos medidas -de ahi que el velo entre y
   salga solo mientras rodas, sin saltos-.

   La barra de scroll no esta: es un texto de mirar de refilon, y una barra al
   costado es cromo a escala de un parrafo que nadie va a arrastrar. El velo ya
   dice que hay mas. */
.pregunta-dicho {
  --velo-arriba: 0px;
  --velo-abajo: 0px;
  margin: 0;
  max-width: 300px;
  max-height: 22vh;
  overflow-y: auto;
  scrollbar-width: none;
  color: var(--faint);
  font-size: 12.5px;
  line-height: 1.5;
  text-align: center;
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0, #000 var(--velo-arriba),
    #000 calc(100% - var(--velo-abajo)), transparent 100%);
  mask-image: linear-gradient(to bottom,
    transparent 0, #000 var(--velo-arriba),
    #000 calc(100% - var(--velo-abajo)), transparent 100%);
}
.pregunta-dicho::-webkit-scrollbar { display: none; }
.pregunta-dicho[hidden] { display: none; }

/* ---- los dos botones de abajo ---- */
/* Como esta puesta la app y lo que tengas para decirnos. Van en la esquina, del
   tamano de lo que son: dos cosas que se usan una vez y despues no. Solo en la
   portada, porque adentro de una clase no se toca nada de esto. */
#abajo {
  position: fixed;
  left: 16px; bottom: 16px;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  animation: llegar .8s .2s var(--ease) both;
}
body.leyendo #abajo { display: none; }

/* Los dos botones: el icono y la palabra, en un renglon. Sin lamina y sin
   borde, como los atajos del pie del lector: son dos cosas que estan ahi por si
   las necesitas, no dos acciones que la portada te este ofreciendo. */
.abajo-btn {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 10px;
  border-radius: 11px;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  color: var(--faint);
  font-size: 13px;
  transition: background .2s var(--ease), color .2s var(--ease);
}
/* El icono va en el gris macizo y no en el del texto: el de los ajustes son
   dos rayas y dos circulos que se tocan, y con un gris transparente cada
   encuentro queda mas claro que el resto y el dibujo se ve remendado. */
.abajo-btn svg { width: 16px; height: 16px; color: var(--faint-macizo); }
.abajo-btn:hover:not(:disabled) { background: var(--glass-hi); color: var(--text); }
.abajo-btn:hover:not(:disabled) svg { color: var(--text); }
.abajo-btn:active:not(:disabled) { transform: none; }

/* ---- adentro de las laminas nuevas ---- */
/* Los ajustes de la app y el formulario de contarnos algo son texto a la
   izquierda, no un cartel centrado: son cosas que se leen renglon por renglon.
   La lamina centra por defecto porque la de la clave es un anuncio. */
#ajustes-app .lamina, #opinion .lamina { align-items: stretch; text-align: left; }
#ajustes-app h2, #opinion h2 { text-align: center; }
#ajustes-app p { max-width: none; }

/* En contarnos algo el texto es una sola frase debajo del titulo, asi que va
   centrada como el titulo y angosta a proposito: dos renglones que miden
   parecido se leen de un vistazo, y uno largo con una palabra sola colgando
   abajo, no. */
#opinion p {
  max-width: 30ch;
  margin-inline: auto;
  text-align: center;
  text-wrap: balance;
}

#ajustes-app h3 {
  margin: 14px 0 0;
  font-size: 13px; font-weight: 500;
  color: var(--faint);
  letter-spacing: -.01em;
}
.lamina-nota {
  margin: 0;
  color: var(--faint);
  font-size: 12.5px;
  line-height: 1.45;
}
.lamina-nota.mal { color: var(--peligro); }

#ajustes-app .fila {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 2px;
  font-size: 13.5px;
  color: var(--text-2);
}
#ajustes-app select {
  -webkit-appearance: none;
  appearance: none;
  padding: 3px 19px 3px 9px;
  border: none;
  border-radius: 9px;
  background: transparent;
  color: var(--text);
  font-size: 13.5px; font-weight: 500;
  text-align: right;
  cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 9px) calc(50% + 1px), calc(100% - 5px) calc(50% + 1px);
  background-size: 4.5px 4.5px;
  background-repeat: no-repeat;
}
#ajustes-app select option { background: var(--menu); color: var(--text); }

/* ---- la lista de modelos ---- */
/* Una fila por modelo: cual es, cuanto pesa y que se puede hacer con el. La que
   esta bajada lleva el canto encendido, igual que el documento abierto.

   La fila no se toca: lo unico que se aprieta es su boton. Antes se elegia
   tocandola, cuando se podian tener las dos voces a la vez; ahora se tiene una
   sola y la bajada es la puesta, asi que no queda nada que elegir ahi. */
#voces-lista, #modelo-lista { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.voz {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 12px;
  border-radius: 14px;
  border: 1px solid transparent;
  background: var(--glass);
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.voz.puesta { border-color: var(--edge-hi); background: var(--glass-hi); }
.voz-quien { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.voz-nombre {
  font-size: 13.5px; font-weight: 500;
  /* Un nombre de modelo es largo y lleno de puntos y dos puntos: partido en
     dos renglones deja de leerse como un nombre. Si no entra, se corta. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.voz-detalle { color: var(--faint); font-size: 12px; }
/* El :not() es por el de pausar, que entra a esta fila cuando el modelo se
   esta bajando y no es una accion de la fila: es un icono cuadrado de 24 con
   su propia medida. Con este padding de aca se quedaba sin ancho por dentro
   -24 de caja menos 24 de padding- y el dibujo se le salia por la derecha. */
.voz button:not(.descarga-pausa) {
  flex-shrink: 0;
  padding: 6px 12px;
  font-size: 12.5px;
  background: var(--glass-hi);
  box-shadow: none;
}
.voz-estado { flex-shrink: 0; color: var(--faint); font-size: 12.5px; }

.voz .voz-quitar { color: var(--muted); }
.voz .voz-quitar:hover:not(:disabled) { color: var(--peligro); border-color: var(--peligro-borde); }

/* La barra de la descarga: la misma de un pelo que la del plan. Lo que se baja
   son cientos de megas y lo unico que hace falta saber es que avanza. */
.voz-barra {
  flex: 1;
  max-width: 110px;
  height: 3px;
  border-radius: 99px;
  background: var(--pista);
  overflow: hidden;
}
.voz-barra i {
  display: block;
  height: 100%;
  border-radius: 99px;
  background: var(--solido);
  transition: width .4s var(--ease);
}

/* ---- contanos ---- */
/* El formulario arranca despues de un silencio. Lo de arriba es lo que hay que
   leer y lo de abajo es lo que hay que hacer, y pegados se leen como una sola
   cosa larga. */
.opinion-forma { display: flex; flex-direction: column; gap: 8px; margin: 16px 0 2px; }
.opinion-forma input, .opinion-forma textarea {
  width: 100%;
  padding: 11px 14px;
  border-radius: 13px;
  border: 1px solid var(--edge);
  background: var(--glass-hi);
  color: var(--text);
  font: inherit;
  font-size: 14px;
}
.opinion-forma textarea { resize: none; line-height: 1.5; }
.opinion-forma input:focus, .opinion-forma textarea:focus {
  outline: 2px solid var(--foco);
  outline-offset: 2px;
}
.opinion-forma input::placeholder, .opinion-forma textarea::placeholder { color: var(--faint); }
/* El boton se despega de las casillas. Con el mismo aire que hay entre el
   nombre y el mensaje parecia una tercera casilla, y lo que hace no es recibir
   texto: lo manda. */
.opinion-forma button { height: 44px; margin-top: 14px; font-size: 14px; }

/* ------------------------------------------------------------- la espera */
/* Mientras el profesor piensa no hay guion que leer. En vez de dejar la columna
   con una linea de texto arriba y el resto en negro, la espera la ocupa entera:
   la cara en el centro y el aviso apoyado debajo. */

#estado {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 34px;
  padding: 20px 6px;
  color: var(--text);
  font-size: 15px;
}
/* Sin esto, el display de arriba le gana al atributo [hidden] del HTML y el
   cartel "Preparando la explicacion" queda visible para siempre, aun con la
   narracion ya sonando. */
#estado[hidden] { display: none; }

/* El guion ya viene vacio cuando se espera (se limpia al cambiar de pagina).
   Plegarlo es lo que deja la cara en el centro real de la columna, y no
   empujada contra el techo por una caja vacia que reclama la mitad del alto. */
#estado:not([hidden]) + #guion { display: none; }

/* Lo mismo al revés: el cartel no se adelanta a la cara que esta bajando. Las
   dos animaciones tocan la opacidad, y la de mas abajo manda mientras corre;
   como la segunda no tiene relleno, durante su retardo gobierna la primera. */
#estado-txt {
  max-width: 250px;
  text-align: center;
  font-weight: 480;
  letter-spacing: -.014em;
  text-wrap: balance;
  animation:
    revelar .45s .45s var(--ease) both,
    palpito 2.9s .9s var(--ease) infinite;
}
/* Un error no late: el cartel queda fijo y la cara ya no esta trabajando. Se
   revela igual que el otro, eso si: la cara sigue teniendo que llegar. */
#estado[data-modo="error"] #estado-txt { animation: revelar .45s .45s var(--ease) both; }

/* El final del documento usa la misma escena que la espera, pero al reves: la
   cara vuelve al centro en grande, y donde estaba el aviso de lo que faltaba
   queda el de que no falta mas. Tampoco late, por lo mismo que el error: no hay
   nada cocinandose detras. Y va un punto mas grande y mas firme que el otro
   porque no es un cartel de paso, es la ultima linea que vas a leer. */
#estado[data-modo="fin"] #estado-txt {
  animation: revelar .45s .45s var(--ease) both;
  font-size: 17px;
  font-weight: 520;
}

/* Lo que falta de la descarga, debajo del cartel. Va angosto y centrado como
   el texto de arriba: es la misma escena, no un panel aparte. */
#estado-baja {
  display: flex;
  width: min(230px, 80%);
  margin-top: -18px;   /* el gap de 34 del cartel es demasiado para su propio pie */
  animation: revelar .45s .45s var(--ease) both;
}
#estado-baja[hidden] { display: none; }

/* Adelantarse. Va al pie del cartel, y es cromo callado como todo lo que no es
   el contenido: el vidrio de siempre, el texto en blanco y el alto que ya
   tienen los botones de las preguntas, asi la mano no aprende una medida nueva.
   Nada de solido aca: la unica pieza opaca de la app es la accion principal, y
   esta no lo es. Entra despues del cartel para que se lea primero lo que se
   esta esperando y recien despues lo que se puede hacer al respecto. */
#priorizar {
  margin-top: -18px;   /* el gap de 34 del cartel es demasiado para su propio pie */
  padding: 9px 16px;
  font-size: 13px;
  font-weight: 500;
  animation: revelar .45s .7s var(--ease) both;
}
#priorizar[hidden] { display: none; }
/* Apretado: se queda diciendo lo que hizo en vez de desaparecer. Desaparecer
   parecia que no lo habia tomado, y volver al texto de antes invitaba a
   apretarlo otra vez cuando ya no habia nada que adelantar. */
#priorizar:disabled { opacity: 1; color: var(--faint); cursor: default; }

/* ------------------------------------------------------------- el profesor */
/* Un circulo con cara, y siempre el mismo: mientras piensa se pone en el centro
   de la columna, en grande; cuando termina se va arriba, chico, al lado del
   nombre del documento, y desde ahi te habla. No son dos dibujos que se
   relevan: el que estaba en el centro es el que sube. El viaje lo anima el js.

   No se mueve. Vive al lado del guion, y cualquier vaiven de fondo, por suave
   que sea, te tira del ojo justo mientras leés: no flota, no cabecea, no mira
   para los costados. Lo unico que se mueve solo es el parpadeo. Todo lo demas
   es una pose por animo, que se acomoda una vez y se queda quieta.

   Cada capa mueve una sola cosa, y por eso ninguna pisa a la otra:

     .cara      el viaje entre los dos sitios          transform, desde el js
     .inclina   como ladea la cabeza cada animo        variable --tilt
     .aura      el resplandor que enciende la voz      variable --voz

   Adentro esta todo en em, asi que el dibujo es uno solo y sirve igual a 132px
   que a 32px: entre un sitio y el otro lo unico que cambia es el font-size. */

.cara {
  position: relative;
  width: 1em; height: 1em;
  flex-shrink: 0;
  --voz: 0;          /* cuanto suena la voz en este cuadro, de 0 a 1 */
  --tilt: 0deg;      /* cuanto ladea la cabeza */
  transform-origin: 0 0;
  transition: transform .9s var(--ease);
}
.cara[data-lugar="centro"] { font-size: 132px; }
.cara[data-lugar="arriba"] { font-size: 32px; }

/* El hueco de arriba se reserva siempre, tambien mientras la cara esta en el
   centro: si apareciera y desapareciera, el nombre del documento daria un salto
   justo cuando la cara esta llegando. */
#cara-slot {
  width: 32px; height: 32px; flex-shrink: 0; margin-right: 11px;
  transition: transform .9s var(--ease);
}

/* Y crece cuando acertaste. A 32px en el canto de arriba, el salto queda lejos
   de donde tenes los ojos al contestar, que es el medio de la columna; un tercio
   mas grande se ve sin tener que ir a buscarlo. Dura lo que dura el festejo y
   despues vuelve, asi que el nombre del documento nunca se corre: lo que crece
   es un transform, y un transform no empuja a nadie.

   El tamano lo pone el hueco y no la cara: la cara usa su propio transform para
   viajar entre el encabezado y el centro de la columna, y dos cosas escribiendo
   el mismo transform se pisan.

   Se agranda de golpe, con resorte, y vuelve despacio con la transicion de
   arriba: un festejo entra de un salto y se apaga de a poco. */
#cara-slot.festeja { transform: scale(1.3); transition: transform .45s var(--resorte); }

.cara .inclina, .cara .cuerpo, .cara .ojos {
  position: absolute;
  inset: 0;
}
.cara .inclina { transform: rotate(var(--tilt)); transition: transform .9s var(--resorte); }

/* El cuerpo: una esfera contra el fondo -blanca sobre el negro, negra sobre el
   blanco-, con la luz cayendo de arriba a la izquierda como en todo el resto
   de la interfaz. */
.cara .cuerpo {
  border-radius: 50%;
  background: var(--cara-cuerpo);
  box-shadow: var(--cara-sombra);
}

/* El resplandor vive detras y desbordado: nunca toca el canto de la esfera. Es
   lo que se enciende con la voz, y es la unica manera en que se nota que esta
   hablando: enciende, no se mueve. */
.cara .aura {
  position: absolute;
  inset: -27%;
  border-radius: 50%;
  background: var(--cara-aura);
  filter: blur(.09em);
  opacity: calc(.12 + var(--voz) * .8);
  transition: opacity .12s linear;
}

/* Los ojos son dos ovalos, y nada mas. Cada animo es ese mismo par movido:
   achatado, girado o corrido. Como de un animo a otro lo unico que cambia es
   el transform, la transicion la hace el navegador y nunca hay un salto. */
.cara .ojos {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .1em;
  /* Grandes, largos y apoyados apenas por encima del ecuador. Es lo que lo
     separa de cualquier otro circulo con dos rayitas: un par chico y centrado
     se lee como un indicador; este par, alto y bien arriba, se lee como
     alguien mirandote. */
  padding-bottom: .045em;
}
.cara .ojo {
  width: .19em; height: .335em;
  transition: transform .65s var(--resorte);
}
/* Capsulas altas: las puntas redondas del todo, pero los lados rectos. Es el
   punto mas redondo al que se puede llegar sin volverlo un ovalo -el radio es
   la mitad del ancho del ojo, y de ahi no pasa. Va en em y no en porcentaje a
   proposito: asi no se estira con el ojo, y cuando el animo lo achata las
   puntas se quedan igual de blandas. */
.cara .ojo i {
  position: relative;
  display: block;
  width: 100%; height: 100%;
  border-radius: .095em;
  background: var(--cara-ojo);
  transition: transform .1s var(--ease), border-radius .5s var(--ease);
}

/* El reflejo. Una sola mota, arriba a la izquierda como toda la luz de la
   interfaz, y la misma en los dos ojos: es lo unico que separa una mirada de
   dos agujeros. Se apaga cuando el ojo se cierra, porque un brillo aplastado
   contra el parpado se ve como una falla y no como luz. */
.cara .ojo i::after {
  content: '';
  position: absolute;
  top: 13%; left: 17%;
  width: 29%; height: 16.5%;
  border-radius: 50%;
  background: var(--cara-brillo);
  transition: opacity .3s var(--ease);
}
.cara.parpadea .ojo i::after,
.cara[data-animo="dormido"] .ojo i::after,
.cara[data-animo="contento"] .ojo i::after { opacity: 0; }
/* Parpadear es lo unico que toca el ojo por dentro: asi no le pisa el animo. */
.cara.parpadea .ojo i { transform: scaleY(.07); }

/* Pensando: ladea la cabeza y entrecierra los ojos. */
.cara[data-animo="pensando"] { --tilt: -6deg; }
.cara[data-animo="pensando"] .ojo { transform: scaleY(.88); }
/* Sin voz que lo encienda, el resplandor late solo: es la senal de que algo se
   esta cocinando, y late lento para que no compita con nada. */
.cara[data-animo="pensando"] .aura { animation: aura 3.8s var(--ease) infinite; }

/* Escuchando: mientras hablas vos. Ladea la cabeza para el otro lado que
   cuando piensa -prestar el oido no es lo mismo que darle vueltas a algo- y
   abre los ojos un pelo. No hay puntitos: todavia no esta cocinando nada.
   Lo que la enciende es tu voz. El resplandor se mueve con --voz, que es la
   misma variable con la que marca las silabas cuando habla ella, solo que
   ahora la escribe tu microfono: no hay una animacion de fondo que le invente
   un ritmo que vos no tuviste.
   Lo unico suyo es que cada tanto asiente, que es lo que hace cualquiera que
   esta escuchando y no tiene nada que decir todavia. Va cada tres segundos y
   medio y es apenas un cabeceo: mas seguido seria un muneco de auto. */
.cara[data-animo="escuchando"] { --tilt: 7deg; }
.cara[data-animo="escuchando"] .ojo { transform: scale(1.06, 1.1); }
.cara[data-animo="escuchando"] .inclina { animation: asiente 3.5s var(--ease) infinite; }

/* El cabeceo lleva el --tilt puesto en cada cuadro, igual que el salto: la
   animacion escribe el mismo transform que .inclina ya tenia, asi que si no lo
   repitiera, la cabeza se enderezaria de golpe al empezar. */
@keyframes asiente {
  0%, 60%, 100% { transform: rotate(var(--tilt)) translateY(0); }
  68%           { transform: rotate(calc(var(--tilt) + 2.5deg)) translateY(3.5%); }
  76%           { transform: rotate(var(--tilt)) translateY(0); }
  84%           { transform: rotate(calc(var(--tilt) + 1.6deg)) translateY(2%); }
  92%           { transform: rotate(var(--tilt)) translateY(0); }
}

/* Mirando: lo que pasa no pasa adentro de su cabeza, esta llegando de afuera,
   asi que no piensa -no hay puntitos- sino que mira. Los ojos se van despacio
   a un lado y al otro, con una pausa en cada punta, que es como mira alguien
   que espera algo: no barren de corrido, se detienen a ver. Un pelo mas
   abiertos que en reposo, que es lo unico que separa mirar de vigilar. */
.cara[data-animo="mirando"] { --tilt: -3deg; }
.cara[data-animo="mirando"] .ojo { transform: scale(1.06, 1.08); }
.cara[data-animo="mirando"] .ojos { animation: ojea 4.2s var(--ease) infinite; }
.cara[data-animo="mirando"] .aura { animation: aura 2.6s var(--ease) infinite; }

@keyframes ojea {
  0%,  8%  { transform: translate(0, 0); }
  20%, 34% { transform: translate(.055em, -.012em); }
  46%, 60% { transform: translate(-.055em, -.012em); }
  72%, 80% { transform: translate(.03em, .015em); }
  92%, 100% { transform: translate(0, 0); }
}

/* Hablando: no hay animacion de fondo. Lo que marca las silabas es --voz, o sea
   el audio mismo; si el navegador no dejo enganchar el analizador, el
   resplandor pulsa solo para que igual se note que esta hablando. */
.cara.sin-voz[data-animo="hablando"] .aura { animation: aura 2.4s var(--ease) infinite; }

/* Contento, dormido y confundido: el mismo par de ovalos, movido. Contento
   ademas arquea el ojo; si fuera otra rayita se confundiria con el dormido. */
.cara[data-animo="contento"] .ojo { transform: translateY(-16%) scale(1.2, .42); }
.cara[data-animo="contento"] .ojo i { border-radius: 100% 100% .05em .05em; }
.cara[data-animo="dormido"] { --tilt: 5deg; }
.cara[data-animo="dormido"] .ojo { transform: translateY(18%) scaleY(.13); }
.cara[data-animo="confundido"] { --tilt: 9deg; }
.cara[data-animo="confundido"] .ojo:first-child { transform: rotate(-20deg) scale(.95, .62); }
.cara[data-animo="confundido"] .ojo:last-child { transform: translateY(-12%) scaleY(1.06); }

/* Festejando: es la misma risa que suelta el profesor en la portada cuando le
   apoyas el puntero en el boton de descargar, puesta ahora al final del
   documento. Arquea los ojos como el contento, ladea la cabeza, enciende el
   resplandor y se sacude.

   El resplandor no puede salir de --voz como el de hablando: esa variable la
   escribe el js en el style del elemento cuadro a cuadro, y al callar la deja
   en cero, que le gana a cualquier regla de aca. Asi que la risa enciende el
   aura directamente, en el mismo valor al que llegaria --voz: .32.

   Y no se rie para siempre. En la portada la risa dura lo que dura el puntero
   encima, dos o tres segundos; aca el festejo se queda hasta que hagas algo,
   asi que se rie tres veces y despues se queda sonriendo. Un muneco de 132px
   sacudiendose sin parar en el medio de la columna deja de ser un festejo y
   pasa a ser algo que hay que apagar. */
.cara[data-animo="festejando"] { --tilt: -7deg; }
.cara[data-animo="festejando"] .ojo { transform: translateY(-16%) scale(1.2, .42); }
.cara[data-animo="festejando"] .ojo i { border-radius: 100% 100% .05em .05em; }
.cara[data-animo="festejando"] .ojo i::after { opacity: 0; }
.cara[data-animo="festejando"] .aura { opacity: .38; }
/* La sacudida va en el cuerpo y no en la cara entera: la cara tiene el origen
   del transform en la esquina -lo usa el viaje entre el centro y el
   encabezado- y un scale ahi saldria disparado en diagonal. Los ojos viajan
   con el cuerpo porque cuelgan de el, que es lo que hace que se lea como una
   cabeza sacudiendose y no como una pelota con dos cosas encima. */
.cara[data-animo="festejando"] .cuerpo { animation: risa .9s var(--ease) 3; }

/* ---- los tres gestos de la portada ---- */
/* La que te recibe es la unica que reacciona: no tiene guion al lado del que
   distraer, y lo que pasa en la portada -traes algo, lo soltas, borras algo- le
   pasa a ella. La del lector no hace ninguno de estos tres.

   Esperando: la tenes agarrada encima de la tarjeta y todavia no la soltaste.
   Abre grande los ojos y se endereza. Es el unico animo que dura lo que dura
   tu mano: mientras el archivo este en el aire. */
.cara[data-animo="esperando"] { --tilt: -3deg; }
.cara[data-animo="esperando"] .ojo { transform: translateY(-6%) scale(1.1, 1.14); }
.cara[data-animo="esperando"] .aura { opacity: .3; }

/* Saltando: la soltaste. Se agacha, salta, cae y se acomoda, dos veces, con los
   ojos arqueados de contento. El salto va en .inclina y no en .cuerpo para que
   el resplandor viaje con la cabeza en vez de quedarse abajo como un charco; de
   ahi que la inclinacion vaya escrita adentro de cada cuadro, que es el
   transform que .inclina ya tenia puesto. */
.cara[data-animo="saltando"] { --tilt: -5deg; }
.cara[data-animo="saltando"] .ojo { transform: translateY(-16%) scale(1.2, .42); }
.cara[data-animo="saltando"] .ojo i { border-radius: 100% 100% .05em .05em; }
.cara[data-animo="saltando"] .ojo i::after { opacity: 0; }
.cara[data-animo="saltando"] .inclina { animation: salto .8s var(--ease) 2; }

/* Triste: borraste algo. No pone cara de drama: baja los parpados hasta la
   mitad, arquea el ojo para abajo -el mismo arco del contento dado vuelta- y
   ladea apenas la cabeza para el otro lado. */
.cara[data-animo="triste"] { --tilt: 4deg; }
.cara[data-animo="triste"] .ojo { transform: translateY(13%) scaleY(.5); }
.cara[data-animo="triste"] .ojo i { border-radius: .05em .05em 100% 100%; }
.cara[data-animo="triste"] .ojo i::after { opacity: 0; }

/* ---- lo que pasa si lo tocas ---- */
/* La de la portada es ademas la unica a la que se le puede pegar un dedazo: no
   esta trabajando, no tiene guion al lado, y un muneco que te mira todo el
   tiempo pide que lo toquen. Asi que contesta, y contesta en dos escalones.

   El primero es el sobresalto: pestanea de golpe y pega un respingo, como
   cualquiera al que le tocan la cabeza sin avisar. Dura medio segundo y se
   termina ahi.

   El segundo llega si le insistis: a la tercera seguida se pone a llorar. No es
   un castigo ni un cartel, es lo que hace gracioso haber insistido, y se le
   pasa solo.

   El respingo va en .inclina, igual que el salto: asi el resplandor se sacude
   con la cabeza en vez de quedarse abajo como un charco, y por eso la
   inclinacion va escrita adentro de cada cuadro. */
.cara[data-lugar="portada"] { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.cara.sobresalto .inclina { animation: respingo .55s var(--ease); }

/* Llorando: el mismo par de ojos del triste, todavia mas cerrado, la cabeza
   ladeada para el otro lado, el resplandor casi apagado -no esta contento ni
   esta trabajando- y el cuerpo temblando muy despacio. El temblor va en .cuerpo
   y no en .inclina para que el respingo de cada dedazo nuevo siga entrando
   encima sin pisarlo: uno tiembla, el otro pega el salto. */
.cara[data-animo="llorando"] { --tilt: 4deg; }
.cara[data-animo="llorando"] .ojo { transform: translateY(12%) scale(1.08, .34); }
.cara[data-animo="llorando"] .ojo i { border-radius: .05em .05em 100% 100%; }
.cara[data-animo="llorando"] .ojo i::after { opacity: 0; }
.cara[data-animo="llorando"] .aura { opacity: .14; }
.cara[data-animo="llorando"] .cuerpo { animation: puchero 1.2s var(--ease) infinite; }

/* Las dos lagrimas. Viven en su propia capa y no colgando del ojo a proposito:
   el ojo esta aplastado por el animo, y una gota adentro de ese transform
   saldria aplastada tambien. Aca abajo estan las dos quietas, cada una debajo
   de su ojo -medio hueco mas medio ojo del centro, que es donde cae el par- y
   lo unico que las mueve es la animacion.

   Cada gota hace el ciclo entero: se junta en el borde del parpado, se hincha,
   se suelta estirandose y se apaga antes de llegar al canto de la cara, que es
   lo que la deja caer sin que haya que dibujar donde termina. Van desfasadas
   porque dos gotas cayendo al mismo tiempo se leen como una cosa sola. */
.cara .lagrimas { position: absolute; inset: 0; }
.cara .lagrimas i {
  position: absolute;
  top: 52%;
  width: .075em; height: .1em;
  margin-left: -.0375em;
  /* La punta arriba y la panza abajo: una gota, no una pastilla. */
  border-radius: 50% 50% 50% 50% / 64% 64% 36% 36%;
  background: var(--cara-lagrima);
  box-shadow: inset .012em .018em .022em rgba(255, 255, 255, .5);
  opacity: 0;
}
.cara .lagrimas i:first-child { left: calc(50% - .145em); }
.cara .lagrimas i:last-child  { left: calc(50% + .145em); }
.cara[data-animo="llorando"] .lagrimas i { animation: lagrima 1.5s var(--ease) infinite; }
.cara[data-animo="llorando"] .lagrimas i:last-child { animation-delay: .62s; }

/* La mirada. Los dos ojos se corren juntos hacia donde esta el puntero: el js
   escribe cuanto, en em, y solo en la de la portada. Sin esas variables el par
   queda centrado, que es como estaba antes. */
.cara[data-lugar="portada"] .ojos {
  transform: translate(var(--mira-x, 0em), var(--mira-y, 0em));
  transition: transform .18s var(--ease);
}

/* Los tres puntitos sobre la cabeza, y solo mientras piensa. Son los unicos que
   se mueven de fondo, y se los permite porque mientras se espera no hay guion
   abajo del que puedan distraer: son el aviso de que algo se esta cocinando. */
.cara .pensamiento {
  position: absolute;
  left: 50%; bottom: 100%;
  margin-bottom: .22em;   /* despegados de la cabeza: son un globo, no un sombrero */
  display: flex; gap: .055em;
  transform: translateX(-50%);
  opacity: 0;
  transition: opacity .45s var(--ease);
}
.cara .pensamiento i {
  width: .05em; height: .05em;
  border-radius: 50%;
  background: var(--cara-punto);
}
.cara[data-animo="pensando"] .pensamiento { opacity: 1; }
.cara[data-animo="pensando"] .pensamiento i { animation: puntito 1.6s var(--ease) infinite; }
/* Los retardos van con la misma especificidad que la regla de arriba: si no,
   el atajo `animation` de aquella se los vuelve a poner en cero. */
.cara[data-animo="pensando"] .pensamiento i:nth-child(2) { animation-delay: .2s; }
.cara[data-animo="pensando"] .pensamiento i:nth-child(3) { animation-delay: .4s; }

@keyframes puntito {
  0%, 100% { opacity: .25; transform: translateY(0); }
  45%      { opacity: 1;   transform: translateY(-45%); }
}
@keyframes aura {
  0%, 100% { opacity: .5; transform: scale(.95); }
  50%      { opacity: .95; transform: scale(1.05); }
}
@keyframes palpito {
  0%, 100% { opacity: .62; }
  50%      { opacity: 1; }
}
/* Aplasta y estira, que es como se rie cualquier cosa dibujada: cae y rebota
   perdiendo fuerza, y el ciclo cierra donde empezo para que no haya salto ni al
   encadenar una vuelta con la siguiente ni al terminar. La usan los dos que se
   rien: el del final del documento y el de la portada. */
@keyframes risa {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  14%      { transform: translateY(-4%) scale(.975, 1.04); }
  30%      { transform: translateY(2%) scale(1.04, .965); }
  46%      { transform: translateY(-2.5%) scale(.99, 1.025); }
  62%      { transform: translateY(1%) scale(1.02, .982); }
  80%      { transform: translateY(-.8%) scale(1, 1.005); }
}

/* El respingo: se aplasta contra el dedo y vuelve rebotando. Es la risa al
   reves -empieza por el golpe en vez de por el salto- y cierra donde empezo
   para que el segundo dedazo no arranque de un tiron. */
@keyframes respingo {
  0%, 100% { transform: rotate(var(--tilt)) translateY(0) scale(1, 1); }
  16%      { transform: rotate(var(--tilt)) translateY(5%) scale(1.11, .89); }
  44%      { transform: rotate(var(--tilt)) translateY(-3.5%) scale(.955, 1.06); }
  72%      { transform: rotate(var(--tilt)) translateY(1%) scale(1.025, .978); }
}

/* El puchero: el temblor de estar llorando. Es chiquisimo a proposito -menos de
   un uno por ciento- porque lo que tiene que hacer es que la cara no se quede
   quieta, no que se sacuda: sacudirse ya es otra cosa. */
@keyframes puchero {
  0%, 100% { transform: translate(0, 0) scale(1, 1); }
  25%      { transform: translate(-.7%, .4%) scale(1.012, .988); }
  50%      { transform: translate(.6%, 0) scale(.993, 1.007); }
  75%      { transform: translate(-.3%, .35%) scale(1.007, .993); }
}

/* La gota: se junta, se hincha, se suelta estirandose y se apaga cayendo. */
@keyframes lagrima {
  0%   { opacity: 0; transform: translateY(-.015em) scale(.35, .35); }
  16%  { opacity: 1; transform: translateY(0) scale(1, 1); }
  30%  { opacity: 1; transform: translateY(.02em) scale(1.06, 1.06); }
  42%  { opacity: 1; transform: translateY(.09em) scale(.84, 1.28); }
  78%  { opacity: .85; transform: translateY(.34em) scale(.9, 1.16); }
  100% { opacity: 0; transform: translateY(.48em) scale(.86, 1.1); }
}

/* El globo llega desde la colita, que es de donde lo estaria diciendo. */
@keyframes globo {
  from { opacity: 0; transform: scale(.82) translateX(-10px); }
}
@keyframes globo-abajo {
  from { opacity: 0; transform: scale(.86) translateY(-10px); }
}
@keyframes globo-apagar {
  to { opacity: 0; transform: scale(.96); }
}

/* --------------------------------------------------------------------- dock */

footer {
  position: relative;
  z-index: 20;
  flex-shrink: 0;
  display: flex; align-items: center; gap: 6px;
  padding: 7px;
  border-radius: 999px;
  border: 1px solid var(--edge);
  background: var(--glass-hi);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  box-shadow: var(--sombra-lg), var(--canto);
  animation: asomar .6s var(--ease) both;
}
/* Dentro del dock los botones no repiten el vidrio: serian cajas en cajas. */
footer .icono-btn, header .icono-btn {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
footer .icono-btn:hover:not(:disabled):not(.activo),
header .icono-btn:hover:not(:disabled):not(.activo) {
  background: var(--glass-hi-2);
}
header .icono-btn {
  background: var(--glass-hi);
  border-color: var(--edge);
  box-shadow: var(--sombra), var(--canto);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
}

/* Cuanto falta para terminar de escuchar. No es un control: es un dato, asi
   que va como texto suelto, sin lamina ni borde. Alto igual al de la X para
   que las dos cosas caigan sobre la misma linea.

   El texto se apoya a la DERECHA de su caja, contra la X. La caja tiene el
   ancho clavado de la frase mas larga que puede llegar a decir -"Less than
   1 min left"- para que no parpadee al cambiar de diapositiva, y eso son 113 px
   donde "6 min left" ocupa 52: alineado a la izquierda, el dato quedaba a 69 px
   de la X, colgado en medio de la nada y pegado al titulo, como si se hubiera
   caido de lugar. El aire sobra igual, pero va del lado donde no hay nada. */
#restante {
  height: 38px;
  display: flex; align-items: center; justify-content: flex-end;
  padding-right: 4px;
  color: var(--muted);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Escondido, pero sin irse. Al cambiar de diapositiva el numero deja de ser
   fiable y se oculta: si ademas dejara de ocupar lugar, el encabezado se
   angostaria, el titulo se estiraria para llenar el hueco y volveria a
   encogerse al reaparecer. Ese ida y vuelta es el parpadeo. */
#restante[hidden] { visibility: hidden; }

#play { width: 40px; height: 40px; padding: 0; }
#play svg { width: 17px; height: 17px; }
footer .icono-btn { width: 34px; height: 34px; }
footer .icono-btn svg { width: 18px; height: 18px; }

/* Cifras tabulares y ancho minimo: el numero cambia sin mover el resto. */
#pos {
  padding-left: 4px;
  min-width: 52px;
  color: var(--muted);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
  text-align: center;
  white-space: nowrap;
}

#barra {
  flex: 1;
  min-width: 28px;
  height: 3px;
  margin: 0 6px;
  border-radius: 99px;
  background: var(--pista);
  overflow: hidden;
  transition: height .2s var(--ease);
}
footer:hover #barra { height: 5px; }
#barra div {
  height: 100%; width: 0;
  border-radius: 99px;
  background: var(--solido);
  transition: width .2s linear;
}

/* -------------------------------------------------------------- volver */
/* El cartel se apoya sobre el dock, del lado del boton de atras, que es el que
   lo hizo aparecer. No va adentro: el dock esta lleno y una pieza mas ahi lo
   ensancharia cada vez que aparece, moviendo todo lo demas de lugar. Flotando
   arriba entra y sale sin correr nada.

   Es el unico boton del dock que conserva el vidrio, y es a proposito: los de
   adentro no lo llevan porque serian cajas dentro de una caja, y este no esta
   adentro de ninguna. Brota desde su esquina de abajo, que es de donde viene.

   Con una pregunta en pantalla no aparece: ahi lo unico que hay que hacer es
   contestarla, y un atajo para irse a otra lamina es la unica salida que esa
   pantalla no tiene que ofrecer. */
/* El hueco por el que asoma, apoyado sobre el canto de arriba del dock. Lo
   unico que hace es recortar: la pastilla baja, cruza ese canto y deja de
   verse, que es lo que la hace salir de ABAJO de la barra en vez de aparecer
   flotando encima. Un z-index negativo no alcanzaba -un hijo con z negativo se
   dibuja arriba del fondo de su padre, no debajo-, y esto ademas no le toca el
   apilado a ningun boton del dock.

   Se estira catorce a cada lado porque el recorte tambien corta a lo ancho, y
   la sombra de la pastilla se dibuja fuera de su caja. Y no atrapa el puntero:
   es aire con una pastilla adentro, y el guion de abajo se sigue pudiendo
   tocar en todo el resto. */
.volver-hueco {
  position: absolute;
  bottom: 100%;
  left: -14px; right: -14px;
  height: 62px;
  overflow: hidden;
  pointer-events: none;
}

#volver {
  position: absolute;
  pointer-events: auto;
  bottom: 10px;
  left: 14px;
  padding: 8px 14px;
  font-size: 12.5px;
  font-weight: 500;
  white-space: nowrap;
  /* Guardada: bajada lo suyo mas el hueco, que es justo meterse entera debajo
     del dock. El visible va con retardo y no en cero para que no desaparezca
     antes de llegar: se apaga cuando ya no se la ve, que es lo que la saca del
     tabulador y de los clics sin sacarla de la animacion. */
  visibility: hidden;
  opacity: 0;
  transform: translateY(calc(100% + 10px));
  transition: transform .45s var(--ease), opacity .2s .22s var(--ease),
              visibility 0s .45s;
}
/* Afuera. Sube con resorte -se pasa un pelo y se acomoda, como algo que
   asoma- y se enciende enseguida, sin esperar a llegar. */
#volver.afuera {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition: transform .5s var(--resorte), opacity .22s var(--ease),
              visibility 0s;
}
body.preguntando #volver { display: none; }

/* --------------------------------------------------------------- ajustes */

#panel-ajustes {
  position: absolute;
  bottom: calc(100% + 12px);
  right: 0;
  width: 290px;
  padding: 7px;
  border-radius: 22px;
  border: 1px solid var(--edge);
  background: var(--panel);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  box-shadow: var(--sombra-lg), var(--canto);
  transform-origin: bottom right;
  animation: brotar .3s var(--resorte) both;
}
#panel-ajustes .fila {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 11px;
  border-radius: 14px;
  font-size: 13.5px;
  color: var(--text-2);
}
#panel-ajustes .fila:hover { background: var(--glass-hi); }

/* Los desplegables no parecen desplegables: son el valor y un chevron. */
#panel-ajustes select {
  -webkit-appearance: none;
  appearance: none;
  max-width: 62%;
  padding: 3px 19px 3px 9px;
  border: none;
  border-radius: 9px;
  background: transparent;
  color: var(--text);
  font-size: 13.5px;
  font-weight: 500;
  text-align: right;
  text-overflow: ellipsis;
  cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 9px) calc(50% + 1px), calc(100% - 5px) calc(50% + 1px);
  background-size: 4.5px 4.5px;
  background-repeat: no-repeat;
  transition: background-color .15s var(--ease);
}
#panel-ajustes select:hover { background-color: var(--glass-hi-2); }
#panel-ajustes select option { background: var(--menu); color: var(--text); font-weight: 400; }

/* Interruptor estilo sistema. */
/* El color del indicador va pegado a su interruptor y no en una fila propia: es
   un detalle de lo mismo, no otro ajuste. Tres puntos del color real -pintados
   con el mismo token que pinta el recuadro- asi lo que se elige es exactamente
   lo que se va a ver sobre la diapositiva. */
.mando { display: flex; align-items: center; gap: 13px; }
.tonos { display: flex; gap: 7px; }
.tono {
  -webkit-appearance: none;
  appearance: none;
  width: 14px; height: 14px;
  margin: 0;
  border-radius: 50%;
  background: rgb(var(--t));
  cursor: pointer;
  transition: transform .2s var(--resorte);
}
.tono:hover { transform: scale(1.18); }
/* El anillo del elegido va como outline y no como box-shadow: el outline-offset
   deja el hueco transparente, asi que muestra el fondo que haya detras en vez de
   obligarnos a adivinarlo con un color solido que no matchearia ni el panel
   translucido ni la fila resaltada. */
.tono:checked { outline: 2px solid rgb(var(--t)); outline-offset: 2.5px; }
.tono:focus-visible { outline: 2px solid var(--text); outline-offset: 2.5px; }

.tono[value="azul"]     { --t: var(--tono-azul); }
.tono[value="amarillo"] { --t: var(--tono-amarillo); }
.tono[value="violeta"]  { --t: var(--tono-violeta); }

.switch { display: flex; }
.switch input {
  -webkit-appearance: none;
  appearance: none;
  position: relative;
  width: 38px; height: 22px;
  margin: 0;
  border-radius: 99px;
  background: var(--pista);
  cursor: pointer;
  transition: background .25s var(--ease);
}
.switch input::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--perilla-sombra);
  transition: transform .3s var(--resorte);
}
.switch input:checked { background: var(--solido); }
.switch input:checked::after { transform: translateX(16px); background: var(--sobre-solido); }

/* Los atajos, a la vista bajo el reproductor: texto suelto, sin lamina. */
.atajos {
  flex-shrink: 0;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 4px 14px;
  padding: 20px 4px 2px;
  color: var(--faint);
  font-size: 12px;
  animation: llegar .7s .15s var(--ease) both;
}
.atajos span { display: flex; align-items: center; gap: 5px; }
/* El renglon de arriba y abajo dice una cosa o la otra segun lo que esas dos
   teclas hagan en ese momento: con la de opciones en pantalla recorren las
   cuatro, y el resto del tiempo cambian de parrafo. Un atajo escrito que no es
   el que anda es peor que no escribir ninguno. Va por el tipo de pregunta y no
   por 'hay una pregunta abierta': en las otras tres hay un solo boton a la
   vista, asi que las flechas siguen siendo las de siempre. */
.atajos .con-opciones { display: none; }
body[data-pregunta="opciones"] .atajos .sin-opciones { display: none; }
body[data-pregunta="opciones"] .atajos .con-opciones { display: flex; }
kbd {
  min-width: 17px;
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--glass-hi);
  color: var(--muted);
  font: 11px/1.5 inherit;
  text-align: center;
}

/* -------------------------------------------------------------- entradas */

/* El salto: se agacha, sale para arriba estirado, cae y se aplasta, y se
   acomoda. Aplastar y estirar es lo que hace que un circulo pese; sin eso el
   mismo recorrido se lee como un ascensor. Cierra donde empezo para que las dos
   vueltas se encadenen sin salto y para que al terminar no de un tiron. */
@keyframes salto {
  0%, 100% { transform: rotate(var(--tilt)) translateY(0) scale(1, 1); }
  16%      { transform: rotate(var(--tilt)) translateY(5%) scale(1.07, .93); }
  40%      { transform: rotate(var(--tilt)) translateY(-19%) scale(.94, 1.07); }
  62%      { transform: rotate(var(--tilt)) translateY(0) scale(1.08, .92); }
  82%      { transform: rotate(var(--tilt)) translateY(-4%) scale(.985, 1.015); }
}
@keyframes apagarse { to { opacity: 0; } }
@keyframes hundirse { to { opacity: 0; transform: scale(.97) translateY(8px); } }
@keyframes llegar { from { opacity: 0; transform: translateY(12px); } }
@keyframes caer   { from { opacity: 0; transform: translateY(-14px); } }
@keyframes asomar { from { opacity: 0; transform: translateY(16px); } }
@keyframes entrar { from { opacity: 0; transform: translateX(18px); } }
@keyframes brotar { from { opacity: 0; transform: scale(.92) translateY(8px); } }
@keyframes revelar { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  /* La cara se queda quieta, pero encendida: el aviso de "estoy pensando" no
     puede depender del movimiento. */
  .cara .aura, .cara .ojos, .cara .cuerpo, .cara .inclina, .cara .pensamiento i,
  .cara .lagrimas i,
  #drop .traido .paso, #estado-txt, #guion {
    animation: none !important;
  }
  .cara[data-animo="pensando"] .aura { opacity: .85; }
  .cara[data-animo="mirando"] .aura { opacity: .85; }
  /* Igual que el resplandor: si la gota no puede caer, se queda puesta. Una
     cara que llora sin lagrima es solo una cara con los ojos raros. */
  .cara[data-animo="llorando"] .lagrimas i { opacity: 1; }
  /* Sin transiciones, crecer y volver serian dos saltos de tamano al lado del
     nombre. La que acerto se queda del tamano de siempre, con la sonrisa
     puesta, que es lo que estaba diciendo. */
  #cara-slot.festeja { transform: none; }
  #estado-txt { opacity: 1; }
  #guion { scroll-behavior: auto; }
}

/* --------------------------------------------------------------- angosto */

@media (max-width: 1040px) {
  aside { width: 320px; }
  main { gap: 16px; }
}

/* Angosto: la columna pasa debajo de la diapositiva. Ocultarla dejaria la app
   sin controles, porque ahora el reproductor vive adentro. */
@media (max-width: 860px) {
  main { flex-direction: column; gap: 12px; padding: 14px; }
  aside { width: auto; max-height: 44%; }
  /* Con la columna tumbada hay la mitad de alto: la cara se achica en vez de
     empujar el aviso fuera de la vista. */
  .cara[data-lugar="centro"] { font-size: 94px; }
  #estado { gap: 22px; }
  header { top: 10px; right: 14px; }
  /* Con la columna abajo, el encabezado flota sobre la diapositiva y ya no se
     le viene encima al titulo: el hueco seria ancho tirado. */
  .cabecera { padding-right: 0; }
  #lienzo img { max-height: calc(56vh - 40px); }
}

@media (max-width: 560px) {
  #barra { margin: 0 4px; }
  #pos { min-width: 46px; padding-left: 2px; font-size: 12px; }
  #setup { padding: 28px 18px; --desvanecido: 56px; }
  .hero { margin-top: 14px; }
  .hero .cara { margin-bottom: 16px; }
  #drop { --pad-drop: 36px; --pad-drop-x: 22px; }
  #panel-ajustes { width: min(290px, calc(100vw - 32px)); }
}

/* Si el navegador no sabe desenfocar, el vidrio se vuelve casi opaco para que
   el texto siga siendo legible. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  footer, #drop, #aviso, #plan.sin-cupo, header .icono-btn, #panel-ajustes {
    background: var(--opaco);
  }
}

/* -------------------------------------------------------------- eliminar */

/* La papelera no compite con el titulo: solo aparece al pasar por encima. */
.reciente .borrar {
  width: 30px; height: 30px;
  flex-shrink: 0;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  color: var(--faint);
  opacity: 0;
}
.reciente .borrar svg { width: 16px; height: 16px; }
.reciente:hover .borrar, .reciente .borrar:focus-visible { opacity: 1; }
.reciente .borrar:hover:not(:disabled) {
  background: var(--glass-hi-2);
  border-color: var(--edge);
  color: var(--text);
}

/* Borrar no se pregunta en un dialogo: el propio boton pasa a texto y se
   pinta. El unico color de toda la interfaz, y es para esto. */
.reciente .borrar.confirmando,
header .icono-btn.confirmando {
  width: auto;
  padding: 0 13px;
  opacity: 1;
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: -.01em;
  color: var(--peligro);
  background: var(--peligro-fondo);
  border-color: var(--peligro-borde);
  box-shadow: none;
}
.reciente .borrar.confirmando:hover:not(:disabled),
header .icono-btn.confirmando:hover:not(:disabled) {
  background: var(--peligro-fondo-hi);
  color: var(--peligro-hi);
}
