/* ════════════════════════════════════════════════════
   studio.css — dropzone, visor, controles, grilla, preload
════════════════════════════════════════════════════ */
/* height (no min-height): con min-height, al no haber una talla principal
   definida, flexbox no tiene de dónde repartir/quitarle espacio a los hijos
   flex:1 (.tp-drop/.tp-viewer) — simplemente crece para caber todo el
   contenido, y si ese contenido (sobre todo .tp-controles, con más botones
   ahora que antes) supera 100svh, la página queda más alta que el viewport y
   aparece scroll — se notaba sobre todo al salir de pantalla completa,
   momento en que .tp-controles vuelve de golpe al flujo normal. Con height
   fija, .tp-app SÍ tiene una talla principal definida, así que .tp-viewer
   (min-height:0) y su canvas-envoltorio (también min-height:0) se encogen
   para ceder el espacio exacto que pide .tp-controles, en vez de desbordar. */
.tp-app {
  position: relative; /* para que .tp-preload (absolute) cubra exactamente esta área */
  height: 100svh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* [hidden] tiene la misma especificidad que .tp-drop/.tp-viewer y el navegador
   la aplica ANTES que las hojas de estilo de autor — sin esta regla, el
   "display: flex" de abajo le gana al "display: none" de [hidden] y ambas
   secciones quedan visibles a la vez. */
.tp-drop[hidden],
.tp-viewer[hidden],
.tp-preload[hidden],
.tp-modal[hidden] { display: none; }

/* ── Dropzone ─────────────────────────────── */
/* Textura de fondo propia de este rediseño: anillos concéntricos tenues,
   como el anillo de árboles/copas del logo visto desde arriba — reemplaza la
   notación de pliegues heredada de perigami (ver CLAUDE.md §9). Solo vive en
   el estado vacío — en el visor competiría con el planeta ya generado. */
.tp-drop {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--gap-l);
  transition: background .15s;
  overflow: hidden;
}
.tp-drop::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cg fill='none' stroke='%23e0a63a' stroke-width='1'%3E%3Ccircle cx='70' cy='70' r='10'/%3E%3Ccircle cx='70' cy='70' r='24' stroke-dasharray='4 5'/%3E%3Ccircle cx='70' cy='70' r='40' stroke-dasharray='2 6'/%3E%3Ccircle cx='8' cy='8' r='5'/%3E%3Ccircle cx='132' cy='120' r='6'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 140px 140px;
  opacity: .10;
  animation: tp-textura-deriva 90s linear infinite;
  pointer-events: none;
}
.tp-drop::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 62% 52% at 50% 42%, rgba(224, 166, 58, .12) 0%, transparent 68%);
  animation: tp-fondo-pulso 10s ease-in-out infinite;
  pointer-events: none;
}
@keyframes tp-textura-deriva {
  from { background-position: 0 0; }
  to   { background-position: 140px 140px; }
}
@keyframes tp-fondo-pulso {
  0%, 100% { opacity: .35; }
  50%      { opacity: 1; }
}
.tp-drop--sobre-arrastre { background: var(--acento-tenue); }
.tp-drop__inner {
  position: relative;
  z-index: 1;
  max-width: 520px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gap-s);
}
.tp-drop__logo { width: clamp(120px, 22vw, 190px); height: auto; margin: 0; filter: drop-shadow(0 6px 18px rgba(0, 0, 0, .45)); }
.tp-drop__titulo {
  font-family: var(--fuente-display);
  font-weight: 600;
  font-size: clamp(1.3rem, 4vw, 1.8rem);
  color: var(--texto-brillante);
  margin: 0;
  letter-spacing: -0.01em;
}
.tp-drop__texto { color: var(--texto-tenue); margin: 0 0 var(--gap-s); }

/* ── Visor ────────────────────────────────── */
.tp-viewer {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
/* El canvas es siempre cuadrado y centrado (ver ajustarTamanoCanvas en app.js) —
   ya no hace falta una guía punteada aparte: lo que se ve EN el canvas es
   exactamente el encuadre que se exporta. */
.tp-viewer__canvas-envoltorio {
  position: relative;
  flex: 1;
  min-height: 0;
  background: #000;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
#tpCanvas { display: block; touch-action: none; cursor: grab; }
#tpCanvas:active { cursor: grabbing; }

/* El logo de marca (ver assets/tps_logo_sm.png) reemplaza el texto "Tiny
   Planet Studio" que antes iba abajo a la derecha — vive abajo a la
   izquierda; el rincón superior derecho ahora lo ocupa el botón de pantalla
   completa (.tp-boton-flotante, ver más abajo). */
.tp-viewer__marca-agua {
  position: absolute;
  bottom: var(--gap-s);
  left: var(--gap-s);
  width: clamp(34px, 5vw, 48px);
  height: auto;
  opacity: .8;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .5));
  pointer-events: none;
  z-index: 2;
}

/* Botones flotantes sobre el canvas — "pantalla completa" en el rincón donde
   antes vivía el logo del header (arriba a la derecha); "restablecer vista"
   en el rincón simétrico, arriba a la izquierda, antes vacío. A diferencia de
   la marca de agua, estos SÍ son interactivos (pointer-events auto). */
.tp-boton-flotante {
  position: absolute;
  top: var(--gap-s);
  right: var(--gap-s);
  z-index: 4;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  line-height: 1;
  color: var(--texto);
  background: rgba(8, 5, 2, .55);
  border: 1px solid var(--borde);
  clip-path: var(--chaflan);
  cursor: pointer;
  transition: border-color .15s, color .15s, background .15s;
}
.tp-boton-flotante--izq { right: auto; left: var(--gap-s); }
.tp-boton-flotante:hover { border-color: var(--acento); color: var(--acento); background: rgba(8, 5, 2, .75); }

/* ── Grilla (toggle) ──────────────────────────
   El ecuador (horizonte real, en cualquier modo/mirada/pan) se dibuja DENTRO
   del shader — ver uGrilla en viewer.js, necesita la dirección 3D final.
   El centro horizontal y el marco de margen son overlays CSS puros: no
   dependen de la proyección, son guías de encuadre de la pantalla misma. */
.tp-grilla {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  opacity: 0;
  transition: opacity .2s;
}
.tp-grilla.is-activa { opacity: 1; }
.tp-grilla__centro {
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 1px;
  background: var(--acento-2);
  box-shadow: 0 0 4px var(--acento-2);
}
.tp-grilla__marco {
  position: absolute;
  inset: 1rem;
  border: 1px dashed var(--acento-2);
  opacity: .7;
}

/* ── Controles ────────────────────────────── */
/* Grid de 3 columnas (borde-fijo / 1fr / borde-fijo): "Nueva imagen" a la
   izquierda, "Descargar" a la derecha, y el bloque modo+zoom+proporción+
   grilla centrado en el espacio restante — así queda centrado respecto a la
   barra completa, no solo "lo que sobra" de un flex normal. */
.tp-controles {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--gap-s);
  padding: var(--gap-s) var(--gap-m);
  border-top: 1px solid var(--borde);
  background: var(--bg2);
}
.tp-controles__centro {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--gap-s);
  min-width: 0;
}

/* En pantalla completa el panel sale del flujo y se superpone al canvas
   (que así ocupa toda la altura disponible) para poder autoocultarse como la
   taskbar de Windows — ver el temporizador en app.js. Fuera de pantalla
   completa el panel sigue en flujo normal y siempre visible; estas reglas no
   tienen efecto ahí porque .tp-app--pantalla-completa nunca se aplica. */
.tp-app--pantalla-completa .tp-viewer { position: relative; }
.tp-app--pantalla-completa .tp-controles {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 10;
  border-top: none;
  background: linear-gradient(to top, rgba(8, 5, 2, .9), rgba(8, 5, 2, .6) 65%, transparent);
  transition: transform .32s cubic-bezier(.4, 0, .2, 1), opacity .32s cubic-bezier(.4, 0, .2, 1);
}
.tp-app--pantalla-completa .tp-controles--oculto {
  transform: translateY(100%);
  opacity: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .tp-app--pantalla-completa .tp-controles { transition: none; }
}
.tp-controles__modos { display: flex; gap: 4px; background: var(--bg3); clip-path: var(--chaflan); padding: 4px; }
.tp-modo {
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--texto-tenue);
  background: transparent;
  border: none;
  clip-path: var(--chaflan);
  padding: 8px 12px;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.tp-modo[aria-selected="true"] { background: var(--acento); color: var(--acento-texto); }

.tp-slider { display: flex; align-items: center; gap: 8px; font-size: 0.8rem; font-weight: 700; color: var(--texto-tenue); }
.tp-slider input[type="range"] { accent-color: var(--acento-2); width: clamp(100px, 18vw, 180px); }

.tp-select-envoltorio { display: flex; align-items: center; gap: 8px; font-size: 0.8rem; font-weight: 700; color: var(--texto-tenue); }
.tp-select {
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--texto);
  background: var(--bg3);
  border: 1px solid var(--borde);
  clip-path: var(--chaflan);
  padding: 6px 10px;
  cursor: pointer;
}
.tp-select:hover { border-color: var(--acento); }

@media (max-width: 720px) {
  .tp-controles { grid-template-columns: 1fr; }
  .tp-controles__modos { justify-content: center; }
  .tp-controles > #tpNuevaImagen,
  .tp-controles > #tpDescargar { width: 100%; }
}

/* ── Preload: la hoja plana se pliega hasta ser un planeta ──
   Se ve mientras se lee/decodifica el archivo (variable con fotos grandes de
   360°) — un bucle continuo, no una animación de una sola vez, porque no se
   sabe de antemano cuánto va a tardar. */
.tp-preload {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--gap-m);
  background: var(--bg);
}
.tp-preload__escena {
  position: relative;
  width: 100px;
  height: 100px;
  perspective: 420px;
}
.tp-preload__hoja {
  position: absolute;
  left: 50%; top: 50%;
  width: 84px; height: 42px; /* 2:1, como una miniatura equirectangular */
  margin: -21px 0 0 -42px;
  border: 1px dashed var(--acento);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='14'%3E%3Cpath d='M0 10 L14 4 L28 10' fill='none' stroke='%23e0a63a' stroke-width='1' stroke-dasharray='3 2'/%3E%3C/svg%3E");
  background-size: 28px 14px;
  transform-origin: center;
  animation: tp-hoja-pliegue 2.4s cubic-bezier(.45, 0, .2, 1) infinite;
}
.tp-preload__planeta {
  position: absolute;
  left: 50%; top: 50%;
  width: 56px; height: 56px;
  margin: -28px 0 0 -28px;
  border-radius: 50%; /* la única forma redonda a propósito: es literalmente el planeta */
  border: 1px solid var(--acento);
  background:
    radial-gradient(circle at 32% 28%, rgba(224, 166, 58, .35), transparent 55%),
    var(--bg3);
  box-shadow: var(--glow);
  animation: tp-planeta-emerge 2.4s cubic-bezier(.45, 0, .2, 1) infinite;
}
@keyframes tp-hoja-pliegue {
  0%       { opacity: 1; transform: rotateX(0deg)  scale(1); }
  30%, 70% { opacity: 0; transform: rotateX(78deg) scale(.55); }
  100%     { opacity: 1; transform: rotateX(0deg)  scale(1); }
}
@keyframes tp-planeta-emerge {
  0%   { opacity: 0; transform: scale(.35) rotate(0deg); }
  30%  { opacity: 1; transform: scale(1)   rotate(120deg); }
  70%  { opacity: 1; transform: scale(1)   rotate(300deg); }
  100% { opacity: 0; transform: scale(.35) rotate(400deg); }
}
.tp-preload__texto {
  font-size: .8rem;
  font-weight: 700;
  color: var(--texto-tenue);
  letter-spacing: .04em;
}

@media (prefers-reduced-motion: reduce) {
  .tp-drop::before, .tp-drop::after,
  .tp-preload__hoja, .tp-preload__planeta {
    animation: none !important;
  }
  .tp-preload__hoja { opacity: 1; }
  .tp-preload__planeta { opacity: 0; }
}

/* ── Modal de descarga ────────────────────────
   Único punto donde se distingue Gratis (funcional, con marca de agua) de Pro
   (deshabilitado, "Próximamente" hasta que exista pasarela de pago) — el
   botón de la barra de controles ya no elige por sí solo, solo abre esto. */
.tp-modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--gap-m);
}
.tp-modal__fondo {
  position: absolute;
  inset: 0;
  background: rgba(8, 5, 2, 0.72);
}
.tp-modal__panel {
  position: relative;
  z-index: 1;
  width: min(520px, 100%);
  background: var(--bg2);
  border: 1px solid var(--borde);
  clip-path: var(--chaflan);
  padding: var(--gap-l) var(--gap-m) var(--gap-m);
}
.tp-modal__cerrar {
  position: absolute;
  top: var(--gap-s);
  right: var(--gap-s);
  background: transparent;
  border: none;
  color: var(--texto-tenue);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  padding: 6px;
}
.tp-modal__cerrar:hover { color: var(--texto-brillante); }
.tp-modal__titulo {
  font-family: var(--fuente-display);
  font-weight: 600;
  color: var(--texto-brillante);
  margin: 0 0 var(--gap-m);
  font-size: clamp(1.1rem, 3vw, 1.4rem);
  text-align: center;
}
.tp-modal__opciones {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gap-s);
}
.tp-modal__opcion {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
  background: var(--bg3);
  border: 1px solid var(--borde);
  clip-path: var(--chaflan);
  padding: var(--gap-m) var(--gap-s);
}
.tp-modal__opcion h3 { margin: 0; color: var(--texto-brillante); font-family: var(--fuente-display); font-weight: 600; }
.tp-modal__opcion p { margin: 0 0 4px; color: var(--texto-tenue); font-size: 0.85rem; }
.tp-modal__opcion .tp-boton { width: 100%; }

@media (max-width: 480px) {
  .tp-modal__opciones { grid-template-columns: 1fr; }
}

/* ── Elegir qué comprar, correo, y "¿ya compraste?" ────────── */
.tp-elegir {
  display: flex; flex-direction: column; gap: 4px; width: 100%;
  font-size: 0.78rem; color: var(--texto); text-align: left;
}
.tp-elegir label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.tp-elegir input { accent-color: var(--acento); }
.tp-modal__precio { margin: 0; font-size: 1.15rem; font-weight: 700; color: var(--acento); }

.tp-field { display: flex; flex-direction: column; gap: 4px; width: 100%; text-align: left; }
.tp-field span { font-size: 0.7rem; letter-spacing: .04em; text-transform: uppercase; color: var(--texto-tenue); }
.tp-field input[type="email"] {
  background: var(--bg3); border: 1px solid var(--borde); color: var(--texto);
  font-family: inherit; font-size: 0.85rem; padding: 8px 10px;
}
.tp-field input[type="email"]:focus-visible { outline: 1px solid var(--acento); outline-offset: 1px; }

.tp-aviso {
  margin: 0; font-size: 0.78rem; color: #e2574c;
  border-left: 2px solid currentColor; padding-left: 8px; text-align: left;
}
.tp-aviso[hidden] { display: none; }

.tp-link {
  display: block; width: 100%;
  background: none; border: none; padding: 0; margin: 2px 0 0;
  font-family: inherit; font-size: 0.72rem;
  color: var(--acento-2); text-decoration: underline; cursor: pointer;
}
.tp-link:hover, .tp-link:focus-visible { color: var(--acento); }

.tp-modal__nota { margin: 0 0 var(--gap-s); font-size: 0.82rem; color: var(--texto-tenue); text-align: center; }

/* ── Pantalla de resultado ────────────────────────────────── */
.tp-resultado { text-align: center; padding: 4px 4px 0; }
.tp-resultado__icono { width: 44px; height: 44px; margin: 0 auto 12px; }
.tp-resultado__icono--ok { color: var(--acento); }
.tp-resultado__icono--error { color: #e2574c; }
.tp-resultado__icono--espera { color: var(--texto-tenue); animation: tp-girar 1.4s linear infinite; }
@keyframes tp-girar { to { transform: rotate(360deg); } }
.tp-resultado h3 {
  margin: 0 0 8px; font-family: var(--fuente-display); font-weight: 600;
  color: var(--texto-brillante); font-size: 1rem;
}
.tp-resultado p { margin: 0 0 14px; font-size: 0.85rem; color: var(--texto-tenue); }
.tp-resultado .tp-boton { width: auto; padding-left: 20px; padding-right: 20px; }

/* ── Toast ────────────────────────────────── */
.tp-toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  background: var(--bg3);
  border: 1px solid var(--borde);
  color: var(--texto-brillante);
  padding: 10px 18px;
  clip-path: var(--chaflan);
  font-size: 0.8rem;
  font-weight: 700;
  z-index: 50;
  max-width: min(90vw, 420px);
  text-align: center;
}
