/* Carta — la herramienta. Vive sobre el cielo, no a pantalla completa. */ .taller { position: relative; z-index: 1; min-height: 100dvh; display: flex; align-items: center; justify-content: center; padding: var(--e-7); } .carta { position: relative; width: min(var(--m-carta-ancho), 100%); height: min(var(--m-carta-alto), calc(100dvh - var(--e-11))); display: grid; grid-template-columns: minmax(0, 1fr) var(--m-panel-ancho); border-radius: var(--r-xl); overflow: hidden; /* La carta es el vidrio: el cielo se ve a través suyo (por eso el desenfoque), y cada mitad pinta encima lo suyo (el escenario, su propio velo oscuro; el panel, nada, para que este vidrio se le note debajo). */ background: var(--vidrio-fondo); backdrop-filter: var(--vidrio-desenfoque); -webkit-backdrop-filter: var(--vidrio-desenfoque); color: var(--texto-principal); box-shadow: var(--vidrio-sombra), var(--sombra-carta), 0 0 0 1px var(--borde-carta); } /* El borde: un degradado de 1px recortado con mask, no un `border` plano. Y el grano: una textura fija, que pone js/cielo.js en --grano al arrancar. */ .carta::before, .carta::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; } .carta::before { padding: 1px; background: var(--vidrio-borde-degradado); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); /* token-libre: máscara, no es color de diseño */ -webkit-mask-composite: xor; mask-composite: exclude; } .carta::after { background-image: var(--grano); background-size: var(--vidrio-grano-tamano); opacity: var(--vidrio-grano-opacidad); mix-blend-mode: overlay; } /* ── Escenario: la imagen, entera, nunca recortada a sangre ──────────── */ .escenario { position: relative; display: flex; align-items: center; justify-content: center; padding: var(--e-11); background: var(--superficie-escenario); overflow: hidden; } .escenario__lienzo { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; } /* ── La pila: antes debajo, después encima ──────────────────────────── Las dos capas son la misma imagen pasada por el proceso. La de después se descubre de arriba abajo con una línea, como cuando arrastras el separador de un antes/después. Cuando un paso del proceso cambie el archivo, la capa de después apunta a ese resultado y esto sigue funcionando igual. */ .pila { position: relative; display: inline-block; max-width: 100%; max-height: 100%; line-height: 0; border-radius: var(--r-s); overflow: hidden; box-shadow: var(--sombra-imagen); } .pila[data-giro] { transform: rotate(var(--giro-imagen)); } .escenario__imagen { max-width: 100%; max-height: 100%; width: auto; height: auto; } .pila__despues { position: absolute; inset: 0; width: 100%; height: 100%; clip-path: inset(0 0 100% 0); } /* El frente: una banda de luz difuminada que recorre la imagen de arriba abajo. Por su centro va pasando el revelado —de ahí para arriba ya está la imagen que ha salido del proceso—, pero sin ninguna línea que lo señale. */ .pila__frente { position: absolute; left: 0; right: 0; top: 0; height: var(--m-difuminado-alto); max-height: 60%; transform: translateY(-50%); background: var(--revelado-difuminado); filter: blur(var(--revelado-suavizado)); opacity: 0; pointer-events: none; } /* Mientras se aplica, el frente va descubriendo la imagen que sale del proceso. La de partida no se toca: nada de apagarla ni desaturarla, que marcaba un borde duro al pasar y se leía como un blanco y negro. */ .app[data-fase="aplicando"] .pila__despues { animation: revela var(--t-aplicando) var(--curva-calma) forwards; } .app[data-fase="aplicando"] .pila__frente { animation: baja var(--t-aplicando) var(--curva-calma) forwards; } .app[data-fase="hecho"] .pila__despues { clip-path: inset(0 0 0 0); } /* El velo de la magia, sobre la imagen (js/aurora.js pone la opacidad, con la misma campana que la distorsión): tres manchas radiales en los tres colores de la aurora, `screen` para solo aclarar. En reposo no se ve. */ .pila__velo-magia { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; background: radial-gradient(45% 45% at 30% 35%, rgb(var(--c-teal-rgb) / 0.5) 0%, rgb(var(--c-teal-rgb) / 0) 70%), radial-gradient(45% 45% at 70% 30%, rgb(var(--c-violeta-rgb) / 0.45) 0%, rgb(var(--c-violeta-rgb) / 0) 70%), radial-gradient(50% 50% at 55% 75%, rgb(var(--c-rosa-rgb) / 0.4) 0%, rgb(var(--c-rosa-rgb) / 0) 70%); filter: blur(var(--aurora-velo-difuminado)); mix-blend-mode: screen; pointer-events: none; } .pila[data-comparando="si"] .pila__velo-magia { display: none; } /* Comparar: antes y después lado a lado, en vez de revelado superpuesto. */ .pila[data-comparando="si"] { display: flex; align-items: center; gap: var(--e-4); } .pila[data-comparando="si"] .pila__despues { position: relative; inset: auto; width: auto; height: auto; clip-path: none; } .pila[data-comparando="si"] .pila__frente { display: none; } .pila[data-comparando="si"] .escenario__imagen { max-width: calc(50% - var(--e-2)); } @keyframes revela { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } } @keyframes baja { 0% { top: 0; opacity: 0; } 6% { opacity: 1; } 94% { opacity: 1; } 100% { top: 100%; opacity: 0; } } .escenario__hueco { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--e-6); width: 78%; height: 76%; border: 1px dashed var(--borde-hueco); border-radius: var(--r-l); font-size: var(--f-m); color: var(--texto-escenario); text-align: center; padding: var(--e-7); } .escenario__sello { position: absolute; left: var(--e-10); bottom: var(--e-8); font-size: var(--f-sm); color: var(--texto-escenario-tenue); } /* Las acciones pertenecen a la imagen: se descubren ahí, no en un paso repetido del formulario. */ .herramientas-imagen { position: absolute; bottom: var(--e-6); left: 50%; z-index: 2; display: flex; gap: var(--e-2); transform: translateX(-50%); } .icono { display: inline-flex; align-items: center; justify-content: center; width: var(--m-icono); height: var(--m-icono); padding: var(--e-0); border: 1px solid var(--borde-menu); border-radius: var(--r-circulo); background: var(--superficie-herramientas); color: var(--texto-herramientas); font-size: var(--f-md); line-height: 1; } /* Los iconos de la imagen son vidrio, igual que la carta. */ .icono--herramienta { position: relative; backdrop-filter: var(--vidrio-desenfoque); -webkit-backdrop-filter: var(--vidrio-desenfoque); box-shadow: var(--vidrio-sombra), var(--sombra-imagen); } .icono--herramienta::before, .icono--herramienta::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; } .icono--herramienta::before { padding: 1px; background: var(--vidrio-borde-degradado); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); /* token-libre: máscara, no es color de diseño */ -webkit-mask-composite: xor; mask-composite: exclude; } .icono--herramienta::after { background-image: var(--grano); background-size: var(--vidrio-grano-tamano); opacity: var(--vidrio-grano-opacidad); mix-blend-mode: overlay; } .icono--herramienta svg { width: var(--e-7); height: var(--e-7); fill: none; stroke: currentColor; stroke-width: var(--m-trazo-simbolo); stroke-linecap: round; stroke-linejoin: round; } .icono--herramienta:disabled { opacity: 0.48; cursor: default; } .menu-imagen { position: absolute; bottom: calc(100% + var(--e-3)); left: var(--e-0); width: var(--m-menu-imagen); padding: var(--e-4); border: 1px solid var(--borde-sutil); border-radius: var(--r-m); background: var(--superficie-menu); backdrop-filter: var(--vidrio-desenfoque); -webkit-backdrop-filter: var(--vidrio-desenfoque); box-shadow: var(--vidrio-sombra), var(--sombra-imagen); color: var(--texto-principal); } .menu-imagen::before, .menu-imagen::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; } .menu-imagen::before { padding: 1px; background: var(--vidrio-borde-degradado); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); /* token-libre: máscara, no es color de diseño */ -webkit-mask-composite: xor; mask-composite: exclude; } .menu-imagen::after { background-image: var(--grano); background-size: var(--vidrio-grano-tamano); opacity: var(--vidrio-grano-opacidad); mix-blend-mode: overlay; } .menu-imagen__accion, .menu-imagen__titulo { display: block; width: 100%; padding: var(--e-3) var(--e-2); background: none; border: 0; color: var(--texto-secundario); font-size: var(--f-sm); text-align: left; } .menu-imagen__accion:hover { color: var(--texto-principal); } .menu-imagen__titulo { color: var(--texto-tenue); } .menu-imagen .miniaturas { padding: 0 var(--e-2) var(--e-2); } /* El enlace del hueco vive sobre el cielo, no sobre la carta. */ .escenario__hueco .enlace { color: var(--texto-escenario); border-bottom-color: var(--borde-hueco); } .escenario__hueco .enlace:hover { color: var(--texto-escenario-fuerte); border-bottom-color: var(--borde-hueco-fuerte); } /* ── El momento de aplicar ───────────────────────────────────────────── */ .anillo { position: absolute; width: var(--m-anillo); height: var(--m-anillo); max-width: 90%; max-height: 90%; border: 1px solid var(--aplicando-anillo); border-radius: var(--r-circulo); pointer-events: none; animation: respira var(--t-respiracion) var(--curva-calma) infinite; } .anillo--tarde { animation-delay: calc(var(--t-respiracion) / 2); } @keyframes respira { 0% { transform: scale(0.84); opacity: 0; } 40% { opacity: 0.75; } 100% { transform: scale(1.26); opacity: 0; } } /* ── Panel: los pasos ────────────────────────────────────────────────── */ .panel { /* Referencia de tamaño para las cuatro acciones del proceso. */ container-type: inline-size; display: flex; flex-direction: column; padding: var(--e-8) var(--e-6) var(--e-6); /* Sin fondo propio: el vidrio de .carta se le nota debajo. Solo la línea que lo separa del escenario es suya. */ background: none; border-left: 1px solid var(--borde-panel); overflow-y: auto; } .panel__paso + .panel__paso { margin-top: var(--e-8); } .panel__eleccion { display: flex; align-items: center; gap: var(--e-5); flex-wrap: wrap; } .panel__cierre { display: flex; flex-direction: column; gap: var(--e-4); margin-top: auto; padding-top: var(--e-8); } .panel__nota { font-size: var(--f-s); color: var(--texto-tenue); text-align: center; margin: 0; min-height: calc(var(--f-s) * var(--f-alto-normal)); } .panel__grupo { display: flex; flex-direction: column; gap: var(--e-3); } /* ── Estrecho: una sola columna, imagen arriba ───────────────────────── */ @media (max-width: 900px) { .taller { padding: var(--m-margen-ventana-movil); /* Centrada: el margen de arriba y el de abajo son el mismo. `safe` evita que se corte por arriba si la carta no cupiera. */ align-items: safe center; } .carta { grid-template-columns: minmax(0, 1fr); /* El alto de la zona de la imagen lo fija la rejilla, no el contenido: así la carta mide lo mismo con imagen y sin ella. */ grid-template-rows: var(--m-escenario-movil) auto; height: auto; } .escenario { padding: var(--e-6); min-height: var(--m-escenario-estrecho); } .escenario__sello { left: var(--e-7); bottom: var(--e-5); } .herramientas-imagen { bottom: var(--e-5); } .pila[data-comparando="si"] { flex-direction: column; } .pila[data-comparando="si"] .escenario__imagen { max-width: 100%; max-height: calc(50% - var(--e-2)); } .panel { border-left: 0; border-top: 1px solid var(--borde-panel); padding: var(--e-6); overflow-y: visible; } .panel__paso + .panel__paso { margin-top: var(--e-7); } .panel__cierre { padding-top: var(--e-6); gap: var(--e-3); } } /* Pantallas de móvil pequeñas: todo lo necesario para aplicar cabe sin scroll. */ @media (max-width: 640px) { .escenario { min-height: var(--m-escenario-movil); padding: var(--e-5); } /* El primer vistazo pertenece a la imagen; los controles continúan debajo. */ .panel { padding: var(--e-5); } .panel__paso + .panel__paso { margin-top: var(--e-6); } .panel__cierre { padding-top: var(--e-5); } }