/*
 * Gestifácil CMS · Editor visual · EFECTOS PÚBLICOS (equipo D)
 * 120 efectos «gfx-<nombre>» parametrizables con variables CSS en los estilos del elemento:
 *   --gfx-dur   duración (p. ej. 800ms)        --gfx-delay  retardo (p. ej. 200ms)
 *   --gfx-int   intensidad, número (1 = normal) --gfx-color  color principal del efecto
 * Entrada: ocultos solo con html.gfx-js (lo pone gf-efectos.js) y visibles al recibir .gfx-in.
 * Escalonado: .gfx-escalonado anima los hijos uno tras otro (--gfx-i lo pone el JS; paso --gfx-paso, 90ms).
 * Selector doble .gfx-x.gfx-x: gana al CSS del tema, pero los estilos del editor (.gf-ID.gf-ID, que van después) siguen mandando.
 * Animaciones de varias categorías se combinan (entrada + continuo + texto…) gracias a variables privadas.
 * Generado por editor/test/D_generar_efectos.js: si cambias algo aquí, cámbialo también allí.
 */

/* ---- Variables privadas: no se heredan (evita que un hijo repita el efecto del padre) ---- */
@property --gfx-ae{syntax:"*";inherits:false}
@property --gfx-ah{syntax:"*";inherits:false}
@property --gfx-ac{syntax:"*";inherits:false}
@property --gfx-at{syntax:"*";inherits:false}
@property --gfx-af{syntax:"*";inherits:false}
@property --gfx-k{syntax:"*";inherits:false}
@property --gfx-d0{syntax:"*";inherits:false}
@property --gfx-ease{syntax:"*";inherits:false}
@property --gfx-t0{syntax:"*";inherits:false}
@property --gfx-i{syntax:"*";inherits:false}
@property --gfx-ang{syntax:"<angle>";inherits:false;initial-value:0deg}
@keyframes gfx-k-ang{to{--gfx-ang:360deg}}
@keyframes gfx-k-seguro{to{opacity:1}}

/* ---- Combinación de animaciones de todas las categorías ---- */
:is(.gfx-aparecer,.gfx-desde-abajo,.gfx-desde-arriba,.gfx-desde-izquierda,.gfx-desde-derecha,.gfx-diagonal,.gfx-acercar,.gfx-alejar,.gfx-girar-entrada,.gfx-rebote-entrada,.gfx-gelatina-entrada,.gfx-voltear-x,.gfx-voltear-y,.gfx-enfocar,.gfx-cortina,.gfx-mascara,.gfx-circulo-revelar,.gfx-escribir,.gfx-caer,.gfx-desplegar,.gfx-velocidad,.gfx-pulso-hover,.gfx-sacudir,.gfx-flotar,.gfx-latir,.gfx-respirar,.gfx-girar-lento,.gfx-balanceo,.gfx-parpadeo,.gfx-rebote-continuo,.gfx-vaiven,.gfx-onda,.gfx-neon-pulso,.gfx-gelatina,.gfx-moneda,.gfx-ken-burns,.gfx-arcoiris,.gfx-zumbido,.gfx-orbitar,.gfx-blob-animado,.gfx-texto-degradado-animado,.gfx-neon,.gfx-maquina,.gfx-brillo-texto,.gfx-glitch,.gfx-fondo-degradado-animado),.gfx-escalonado > *{animation:var(--gfx-ae,none),var(--gfx-ah,none),var(--gfx-ac,none),var(--gfx-at,none),var(--gfx-af,none)}

/* ---- Transiciones comunes de «al pasar el ratón» y filtros ---- */
:is(.gfx-elevar,.gfx-crecer,.gfx-encoger,.gfx-empujar,.gfx-rotar-hover,.gfx-hundir,.gfx-subrayado,.gfx-subrayado-crece,.gfx-sombra-crece,.gfx-inclinar-3d,.gfx-fondo-desliza,.gfx-resplandor,.gfx-anillo,.gfx-contorno-relleno,.gfx-espaciado-hover,.gfx-bn-a-color,.gfx-color-a-bn,.gfx-sepia,.gfx-vintage,.gfx-duotono,.gfx-desenfoque,.gfx-enfocar-hover,.gfx-alto-contraste,.gfx-saturado,.gfx-apagado,.gfx-invertir,.gfx-brillo-hover,.gfx-oscurecer-hover,.gfx-sombra-forma){transition-property:translate,scale,rotate,transform,box-shadow,background-color,background-size,background-position,color,filter,opacity,outline-color,outline-offset,letter-spacing,text-decoration-color,text-underline-offset,border-color;transition-duration:var(--gfx-dur,var(--gfx-t0,350ms));transition-timing-function:cubic-bezier(.2,.8,.2,1);transition-delay:var(--gfx-delay,0ms)}
:is(.gfx-inclinar-3d){--gfx-t0:450ms}
:is(.gfx-fondo-desliza,.gfx-espaciado-hover,.gfx-brillo-hover,.gfx-oscurecer-hover){--gfx-t0:400ms}
:is(.gfx-contorno-relleno){--gfx-t0:600ms}
:is(.gfx-bn-a-color,.gfx-color-a-bn,.gfx-sepia,.gfx-vintage,.gfx-duotono,.gfx-desenfoque,.gfx-enfocar-hover,.gfx-alto-contraste,.gfx-saturado,.gfx-apagado,.gfx-invertir,.gfx-sombra-forma){--gfx-t0:500ms}

/* ---- Entrada: estado oculto (solo con JS y si el usuario no pide menos movimiento) ---- */
@media (prefers-reduced-motion:no-preference){
html.gfx-js :is(.gfx-aparecer,.gfx-desde-abajo,.gfx-desde-arriba,.gfx-desde-izquierda,.gfx-desde-derecha,.gfx-diagonal,.gfx-acercar,.gfx-alejar,.gfx-girar-entrada,.gfx-rebote-entrada,.gfx-gelatina-entrada,.gfx-voltear-x,.gfx-voltear-y,.gfx-enfocar,.gfx-cortina,.gfx-mascara,.gfx-circulo-revelar,.gfx-escribir,.gfx-caer,.gfx-desplegar,.gfx-velocidad):not(.gfx-in):not(.gfx-escalonado),html.gfx-js .gfx-escalonado:not(.gfx-in) > *{opacity:0;animation:gfx-k-seguro 1ms linear 6s forwards}
}
:is(.gfx-aparecer,.gfx-desde-abajo,.gfx-desde-arriba,.gfx-desde-izquierda,.gfx-desde-derecha,.gfx-diagonal,.gfx-acercar,.gfx-alejar,.gfx-girar-entrada,.gfx-rebote-entrada,.gfx-gelatina-entrada,.gfx-voltear-x,.gfx-voltear-y,.gfx-enfocar,.gfx-cortina,.gfx-mascara,.gfx-circulo-revelar,.gfx-escribir,.gfx-caer,.gfx-desplegar,.gfx-velocidad).gfx-in:not(.gfx-escalonado),.gfx-escalonado.gfx-in > *{--gfx-ae:var(--gfx-k,gfx-k-desde-abajo) var(--gfx-dur,var(--gfx-d0,700ms)) var(--gfx-ease,cubic-bezier(.22,.8,.24,1)) calc(var(--gfx-delay,0ms) + var(--gfx-i,0) * var(--gfx-paso,90ms)) backwards}
.gfx-escalonado > *{--gfx-k:inherit;--gfx-d0:inherit;--gfx-ease:inherit}

/* ======================================================= ENTRADA · al aparecer en pantalla */
/* Aparecer: Aparece suavemente, pasando de transparente a visible. */
.gfx-aparecer.gfx-aparecer{--gfx-k:gfx-k-aparecer}
@keyframes gfx-k-aparecer{from{opacity:0}}
/* Subir desde abajo: Sube un poco mientras aparece. El clásico que queda bien en todo. */
.gfx-desde-abajo.gfx-desde-abajo{--gfx-k:gfx-k-desde-abajo}
@keyframes gfx-k-desde-abajo{from{opacity:0;translate:0 calc(40px * var(--gfx-int,1))}}
/* Bajar desde arriba: Baja desde arriba mientras aparece. */
.gfx-desde-arriba.gfx-desde-arriba{--gfx-k:gfx-k-desde-arriba}
@keyframes gfx-k-desde-arriba{from{opacity:0;translate:0 calc(-40px * var(--gfx-int,1))}}
/* Entrar por la izquierda: Se desliza desde la izquierda mientras aparece. */
.gfx-desde-izquierda.gfx-desde-izquierda{--gfx-k:gfx-k-desde-izquierda}
@keyframes gfx-k-desde-izquierda{from{opacity:0;translate:calc(-60px * var(--gfx-int,1)) 0}}
/* Entrar por la derecha: Se desliza desde la derecha mientras aparece. */
.gfx-desde-derecha.gfx-desde-derecha{--gfx-k:gfx-k-desde-derecha}
@keyframes gfx-k-desde-derecha{from{opacity:0;translate:calc(60px * var(--gfx-int,1)) 0}}
/* Desde la esquina: Llega en diagonal desde abajo a la izquierda. */
.gfx-diagonal.gfx-diagonal{--gfx-k:gfx-k-diagonal}
@keyframes gfx-k-diagonal{from{opacity:0;translate:calc(-50px * var(--gfx-int,1)) calc(50px * var(--gfx-int,1))}}
/* Acercarse (zoom): Crece desde un tamaño más pequeño hasta su tamaño real. */
.gfx-acercar.gfx-acercar{--gfx-k:gfx-k-acercar}
@keyframes gfx-k-acercar{from{opacity:0;scale:calc(1 - .25 * var(--gfx-int,1))}}
/* Alejarse (zoom): Empieza grande y se coloca en su sitio encogiendo. */
.gfx-alejar.gfx-alejar{--gfx-k:gfx-k-alejar}
@keyframes gfx-k-alejar{from{opacity:0;scale:calc(1 + .25 * var(--gfx-int,1))}}
/* Girar al entrar: Aparece girando ligeramente y creciendo. */
.gfx-girar-entrada.gfx-girar-entrada{--gfx-k:gfx-k-girar-entrada}
@keyframes gfx-k-girar-entrada{from{opacity:0;rotate:calc(-15deg * var(--gfx-int,1));scale:.85}}
/* Rebote: Aparece con un rebote alegre, como una pelota. */
.gfx-rebote-entrada.gfx-rebote-entrada{--gfx-k:gfx-k-rebote-entrada;--gfx-d0:900ms;--gfx-ease:ease-out}
@keyframes gfx-k-rebote-entrada{0%{opacity:0;scale:.3}50%{opacity:1;scale:calc(1 + .08 * var(--gfx-int,1))}70%{scale:calc(1 - .05 * var(--gfx-int,1))}85%{scale:calc(1 + .02 * var(--gfx-int,1))}100%{scale:1}}
/* Gelatina: Entra estirándose y encogiéndose como una gelatina. */
.gfx-gelatina-entrada.gfx-gelatina-entrada{--gfx-k:gfx-k-gelatina-entrada;--gfx-d0:900ms;--gfx-ease:ease-out}
@keyframes gfx-k-gelatina-entrada{0%{opacity:0;scale:calc(1 + .25 * var(--gfx-int,1)) calc(1 - .25 * var(--gfx-int,1))}30%{opacity:1;scale:calc(1 - .2 * var(--gfx-int,1)) calc(1 + .2 * var(--gfx-int,1))}50%{scale:calc(1 + .1 * var(--gfx-int,1)) calc(1 - .1 * var(--gfx-int,1))}70%{scale:calc(1 - .04 * var(--gfx-int,1)) calc(1 + .04 * var(--gfx-int,1))}100%{scale:1 1}}
/* Voltear (horizontal): Se da la vuelta sobre el eje horizontal, como una persiana. */
.gfx-voltear-x.gfx-voltear-x{--gfx-k:gfx-k-voltear-x}
@keyframes gfx-k-voltear-x{from{opacity:0;transform:perspective(900px) rotateX(calc(80deg * var(--gfx-int,1)))}to{transform:perspective(900px) rotateX(0deg)}}
/* Voltear (vertical): Se da la vuelta sobre el eje vertical, como una carta. */
.gfx-voltear-y.gfx-voltear-y{--gfx-k:gfx-k-voltear-y}
@keyframes gfx-k-voltear-y{from{opacity:0;transform:perspective(900px) rotateY(calc(-80deg * var(--gfx-int,1)))}to{transform:perspective(900px) rotateY(0deg)}}
/* De borroso a nítido: Aparece desenfocado y se enfoca poco a poco. */
.gfx-enfocar.gfx-enfocar{--gfx-k:gfx-k-enfocar;--gfx-d0:900ms}
@keyframes gfx-k-enfocar{from{opacity:0;filter:blur(calc(14px * var(--gfx-int,1)));scale:1.04}}
/* Cortina: Se descubre de izquierda a derecha, como al abrir una cortina. */
.gfx-cortina.gfx-cortina{--gfx-k:gfx-k-cortina;--gfx-d0:900ms;--gfx-ease:cubic-bezier(.65,0,.35,1)}
@keyframes gfx-k-cortina{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
/* Subir tras una máscara: El contenido sube desde una línea invisible, muy elegante en títulos. */
.gfx-mascara.gfx-mascara{--gfx-k:gfx-k-mascara;--gfx-d0:800ms}
@keyframes gfx-k-mascara{from{translate:0 100%;clip-path:inset(0 0 100% 0)}to{translate:0 0;clip-path:inset(0 0 0 0)}}
/* Revelar en círculo: Se descubre desde el centro con un círculo que se abre. */
.gfx-circulo-revelar.gfx-circulo-revelar{--gfx-k:gfx-k-circulo-revelar;--gfx-d0:900ms;--gfx-ease:cubic-bezier(.65,0,.35,1)}
@keyframes gfx-k-circulo-revelar{from{clip-path:circle(0% at 50% 50%)}to{clip-path:circle(75% at 50% 50%)}}
/* Escribir: Se descubre a saltos, como si se escribiera. Ideal para títulos de una línea. */
.gfx-escribir.gfx-escribir{--gfx-k:gfx-k-escribir;--gfx-d0:1600ms;--gfx-ease:steps(24,end)}
@keyframes gfx-k-escribir{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
/* Caer: Cae desde arriba con un pequeño giro. */
.gfx-caer.gfx-caer{--gfx-k:gfx-k-caer;--gfx-ease:cubic-bezier(.34,1.56,.64,1)}
@keyframes gfx-k-caer{from{opacity:0;translate:0 calc(-80px * var(--gfx-int,1));rotate:-8deg}}
/* Desplegar: Se despliega hacia abajo desde su borde superior. */
.gfx-desplegar.gfx-desplegar{--gfx-k:gfx-k-desplegar}
@keyframes gfx-k-desplegar{from{opacity:0;scale:1 0;transform-origin:50% 0}to{transform-origin:50% 0}}
/* Entrada rápida: Entra a toda velocidad desde la izquierda con efecto de inclinación. */
.gfx-velocidad.gfx-velocidad{--gfx-k:gfx-k-velocidad;--gfx-ease:ease-out}
@keyframes gfx-k-velocidad{0%{opacity:0;translate:calc(-120px * var(--gfx-int,1)) 0;transform:skewX(30deg)}60%{opacity:1;transform:skewX(-10deg)}80%{transform:skewX(4deg)}100%{transform:skewX(0deg)}}

/* ======================================================= HOVER · al pasar el ratón */
/* Elevar: Se levanta un poco y proyecta sombra, invitando a hacer clic. */
.gfx-elevar.gfx-elevar:hover{translate:0 calc(-8px * var(--gfx-int,1));box-shadow:0 calc(16px * var(--gfx-int,1)) calc(30px * var(--gfx-int,1)) -12px rgb(15 23 42 / .35)}
/* Crecer: Se agranda ligeramente al pasar el ratón. */
.gfx-crecer.gfx-crecer:hover{scale:calc(1 + .06 * var(--gfx-int,1))}
/* Encoger: Se hace un poco más pequeño, como si se hundiera. */
.gfx-encoger.gfx-encoger:hover{scale:calc(1 - .05 * var(--gfx-int,1))}
/* Empujar a la derecha: Se desplaza un poco a la derecha. Muy útil en enlaces y botones con flecha. */
.gfx-empujar.gfx-empujar:hover{translate:calc(6px * var(--gfx-int,1)) 0}
/* Inclinarse: Gira un poco y crece, con un toque desenfadado. */
.gfx-rotar-hover.gfx-rotar-hover:hover{rotate:calc(-3deg * var(--gfx-int,1));scale:1.03}
/* Presionar: Baja un poco y se marca por dentro, como un botón pulsado. */
.gfx-hundir.gfx-hundir:hover{translate:0 calc(3px * var(--gfx-int,1));box-shadow:inset 0 3px 10px rgb(0 0 0 / .25)}
/* Destello que cruza: Una franja de luz atraviesa el elemento. Usa el pseudo-elemento ::after. */
:where(.gfx-brillo-cruza.gfx-brillo-cruza){position:relative;overflow:hidden}
.gfx-brillo-cruza.gfx-brillo-cruza::after{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(105deg,transparent 35%,rgb(255 255 255 / calc(.55 * var(--gfx-int,1))) 50%,transparent 65%);translate:-120% 0}
.gfx-brillo-cruza.gfx-brillo-cruza:hover::after{translate:120% 0;transition:translate var(--gfx-dur,800ms) ease var(--gfx-delay,0ms)}
/* Subrayado que sube: Aparece un subrayado que sube hasta el texto. Para títulos y enlaces. */
.gfx-subrayado.gfx-subrayado{text-decoration-line:underline;text-decoration-color:transparent;text-decoration-thickness:calc(2px * var(--gfx-int,1));text-underline-offset:.55em}
.gfx-subrayado.gfx-subrayado:hover{text-decoration-color:var(--gfx-color,currentColor);text-underline-offset:.2em}
/* Subrayado que crece: Una línea crece de izquierda a derecha bajo el elemento. Para botones y enlaces. */
.gfx-subrayado-crece.gfx-subrayado-crece{background-image:linear-gradient(var(--gfx-color,currentColor),var(--gfx-color,currentColor));background-repeat:no-repeat;background-position:0 100%;background-size:0% calc(2px * var(--gfx-int,1));box-decoration-break:clone;-webkit-box-decoration-break:clone}
.gfx-subrayado-crece.gfx-subrayado-crece:hover{background-size:100% calc(2px * var(--gfx-int,1))}
/* Borde que se dibuja: Un borde se dibuja alrededor del elemento. Usa ::before y ::after. */
:where(.gfx-borde-dibuja.gfx-borde-dibuja){position:relative}
.gfx-borde-dibuja.gfx-borde-dibuja::before,.gfx-borde-dibuja.gfx-borde-dibuja::after{content:"";position:absolute;width:0;height:0;border:calc(2px * var(--gfx-int,1)) solid transparent;box-sizing:border-box;pointer-events:none;border-radius:inherit}
.gfx-borde-dibuja.gfx-borde-dibuja::before{top:0;left:0}
.gfx-borde-dibuja.gfx-borde-dibuja::after{bottom:0;right:0}
.gfx-borde-dibuja.gfx-borde-dibuja:hover::before{width:100%;height:100%;border-top-color:var(--gfx-color,#4f46e5);border-right-color:var(--gfx-color,#4f46e5);transition:width calc(var(--gfx-dur,1s) / 4) ease-out,height calc(var(--gfx-dur,1s) / 4) ease-out calc(var(--gfx-dur,1s) / 4)}
.gfx-borde-dibuja.gfx-borde-dibuja:hover::after{width:100%;height:100%;border-bottom-color:var(--gfx-color,#4f46e5);border-left-color:var(--gfx-color,#4f46e5);transition:border-color 0s linear calc(var(--gfx-dur,1s) / 2),width calc(var(--gfx-dur,1s) / 4) ease-out calc(var(--gfx-dur,1s) / 2),height calc(var(--gfx-dur,1s) / 4) ease-out calc(var(--gfx-dur,1s) * .75)}
/* Sombra que crece: La sombra se hace más grande y suave, dando sensación de profundidad. */
.gfx-sombra-crece.gfx-sombra-crece{box-shadow:0 2px 6px rgb(15 23 42 / .12)}
.gfx-sombra-crece.gfx-sombra-crece:hover{box-shadow:0 calc(22px * var(--gfx-int,1)) calc(45px * var(--gfx-int,1)) -14px rgb(15 23 42 / .38)}
/* Inclinación 3D: Se inclina en perspectiva como una tarjeta que se gira hacia ti. */
.gfx-inclinar-3d.gfx-inclinar-3d:hover{transform:perspective(900px) rotateX(calc(7deg * var(--gfx-int,1))) rotateY(calc(-9deg * var(--gfx-int,1)));box-shadow:calc(12px * var(--gfx-int,1)) calc(18px * var(--gfx-int,1)) 34px -14px rgb(15 23 42 / .35)}
/* Girar el icono: El icono que hay dentro da una vuelta completa al pasar el ratón. */
.gfx-girar-icono.gfx-girar-icono :is(.gfp-icono,svg:not(.gfp-icono svg)){transition:rotate var(--gfx-dur,600ms) cubic-bezier(.2,.8,.2,1) var(--gfx-delay,0ms)}
.gfx-girar-icono.gfx-girar-icono:hover :is(.gfp-icono,svg:not(.gfp-icono svg)){rotate:calc(360deg * var(--gfx-int,1))}
/* Fondo que se desliza: Un color de fondo entra deslizándose y el texto pasa a blanco. */
.gfx-fondo-desliza.gfx-fondo-desliza{background-image:linear-gradient(var(--gfx-color,#4f46e5),var(--gfx-color,#4f46e5));background-repeat:no-repeat;background-position:0 0;background-size:0% 100%}
.gfx-fondo-desliza.gfx-fondo-desliza:hover{background-size:100% 100%;color:#fff}
/* Latido al pasar: Late suavemente mientras el ratón está encima. */
.gfx-pulso-hover.gfx-pulso-hover:hover{--gfx-ah:gfx-k-pulso var(--gfx-dur,1s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-pulso{50%{scale:calc(1 + .05 * var(--gfx-int,1))}}
/* Sacudir: Tiembla de lado a lado, para llamar la atención. */
.gfx-sacudir.gfx-sacudir:hover{--gfx-ah:gfx-k-sacudir var(--gfx-dur,500ms) ease-in-out var(--gfx-delay,0ms)}
@keyframes gfx-k-sacudir{20%{translate:calc(-6px * var(--gfx-int,1)) 0}40%{translate:calc(6px * var(--gfx-int,1)) 0}60%{translate:calc(-4px * var(--gfx-int,1)) 0}80%{translate:calc(3px * var(--gfx-int,1)) 0}}
/* Zoom de la imagen: La imagen de dentro se amplía sin salirse de su marco. Para tarjetas e imágenes. */
:where(.gfx-zoom-imagen.gfx-zoom-imagen){overflow:hidden}
.gfx-zoom-imagen.gfx-zoom-imagen img{transition:scale var(--gfx-dur,600ms) cubic-bezier(.2,.8,.2,1) var(--gfx-delay,0ms)}
.gfx-zoom-imagen.gfx-zoom-imagen:hover img{scale:calc(1 + .1 * var(--gfx-int,1))}
/* Destacar al pasar (desenfoca el resto): Ponlo en una fila o rejilla: al pasar por un hijo, los demás se desenfocan. */
.gfx-desenfocar-vecinos.gfx-desenfocar-vecinos > *{transition:filter var(--gfx-dur,350ms) ease var(--gfx-delay,0ms),opacity var(--gfx-dur,350ms) ease var(--gfx-delay,0ms)}
.gfx-desenfocar-vecinos.gfx-desenfocar-vecinos:hover > :not(:hover){filter:blur(calc(2px * var(--gfx-int,1)));opacity:.55}
/* Resplandor de color: Se ilumina con un halo del color elegido. */
.gfx-resplandor.gfx-resplandor:hover{box-shadow:0 0 0 calc(2px * var(--gfx-int,1)) var(--gfx-color,#6366f1),0 0 calc(24px * var(--gfx-int,1)) var(--gfx-color,#6366f1)}
/* Anillo exterior: Aparece un contorno separado del elemento que se aleja un poco. */
.gfx-anillo.gfx-anillo{outline:2px solid transparent;outline-offset:0}
.gfx-anillo.gfx-anillo:hover{outline-color:var(--gfx-color,#4f46e5);outline-offset:calc(6px * var(--gfx-int,1))}

/* ======================================================= CONTINUO · animación en bucle */
/* Flotar: Sube y baja muy despacio, como si flotara. */
.gfx-flotar.gfx-flotar{--gfx-ac:gfx-k-flotar var(--gfx-dur,3s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-flotar{50%{transform:translateY(calc(-10px * var(--gfx-int,1)))}}
/* Latir: Late como un corazón, dos pulsos y una pausa. */
.gfx-latir.gfx-latir{--gfx-ac:gfx-k-latir var(--gfx-dur,1.6s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-latir{0%,40%,100%{transform:scale(1)}10%,30%{transform:scale(calc(1 + .08 * var(--gfx-int,1)))}20%{transform:scale(1)}}
/* Respirar: Crece y se desvanece un poco, con ritmo tranquilo. */
.gfx-respirar.gfx-respirar{--gfx-ac:gfx-k-respirar var(--gfx-dur,4s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-respirar{50%{transform:scale(calc(1 + .04 * var(--gfx-int,1)));opacity:.88}}
/* Girar sin parar: Gira lentamente sin detenerse. Ideal para iconos o sellos. */
.gfx-girar-lento.gfx-girar-lento{--gfx-ac:gfx-k-girar-lento var(--gfx-dur,12s) linear var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-girar-lento{to{transform:rotate(360deg)}}
/* Balanceo: Se balancea a un lado y a otro como un péndulo. */
.gfx-balanceo.gfx-balanceo{--gfx-ac:gfx-k-balanceo var(--gfx-dur,2.4s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-balanceo{25%{transform:rotate(calc(5deg * var(--gfx-int,1)))}75%{transform:rotate(calc(-5deg * var(--gfx-int,1)))}}
/* Parpadeo suave: Se atenúa y vuelve a aparecer suavemente. */
.gfx-parpadeo.gfx-parpadeo{--gfx-ac:gfx-k-parpadeo var(--gfx-dur,2.4s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-parpadeo{50%{opacity:calc(1 - .55 * var(--gfx-int,1))}}
/* Botar: Bota de vez en cuando, como una pelota. */
.gfx-rebote-continuo.gfx-rebote-continuo{--gfx-ac:gfx-k-rebote-continuo var(--gfx-dur,2s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-rebote-continuo{0%,20%,50%,80%,100%{transform:translateY(0)}40%{transform:translateY(calc(-16px * var(--gfx-int,1)))}60%{transform:translateY(calc(-7px * var(--gfx-int,1)))}}
/* Vaivén: Se desplaza a izquierda y derecha suavemente. */
.gfx-vaiven.gfx-vaiven{--gfx-ac:gfx-k-vaiven var(--gfx-dur,3s) ease-in-out var(--gfx-delay,0ms) infinite alternate}
@keyframes gfx-k-vaiven{50%{transform:translateX(calc(12px * var(--gfx-int,1)))}}
/* Onda expansiva: Emite ondas de color hacia fuera, como un radar. Perfecto para botones de llamada. */
.gfx-onda.gfx-onda{--gfx-ac:gfx-k-onda var(--gfx-dur,1.8s) ease-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-onda{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--gfx-color,#6366f1) 60%,transparent)}100%{box-shadow:0 0 0 calc(18px * var(--gfx-int,1)) color-mix(in srgb,var(--gfx-color,#6366f1) 0%,transparent)}}
/* Brillo de neón: Un halo de luz de color que se enciende y se apaga. */
.gfx-neon-pulso.gfx-neon-pulso{--gfx-ac:gfx-k-neon-pulso var(--gfx-dur,2s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-neon-pulso{0%,100%{box-shadow:0 0 calc(6px * var(--gfx-int,1)) color-mix(in srgb,var(--gfx-color,#22d3ee) 70%,transparent)}50%{box-shadow:0 0 calc(10px * var(--gfx-int,1)) var(--gfx-color,#22d3ee),0 0 calc(28px * var(--gfx-int,1)) var(--gfx-color,#22d3ee)}}
/* Gelatina: Se estira y encoge rítmicamente, con mucha gracia. */
.gfx-gelatina.gfx-gelatina{--gfx-ac:gfx-k-gelatina var(--gfx-dur,2.5s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-gelatina{0%,60%,100%{transform:scale(1,1)}10%{transform:scale(calc(1 + .12 * var(--gfx-int,1)),calc(1 - .12 * var(--gfx-int,1)))}20%{transform:scale(calc(1 - .1 * var(--gfx-int,1)),calc(1 + .1 * var(--gfx-int,1)))}30%{transform:scale(calc(1 + .05 * var(--gfx-int,1)),calc(1 - .05 * var(--gfx-int,1)))}40%{transform:scale(1,1)}}
/* Moneda que gira: Gira en 3D sobre sí mismo como una moneda. */
.gfx-moneda.gfx-moneda{--gfx-ac:gfx-k-moneda var(--gfx-dur,4s) linear var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-moneda{to{transform:perspective(600px) rotateY(360deg)}}
/* Zoom lento (Ken Burns): Acercamiento muy lento y continuo. Precioso en imágenes de portada. */
.gfx-ken-burns.gfx-ken-burns{--gfx-ac:gfx-k-ken-burns var(--gfx-dur,14s) ease-in-out var(--gfx-delay,0ms) infinite alternate}
@keyframes gfx-k-ken-burns{from{transform:scale(1)}to{transform:scale(calc(1 + .12 * var(--gfx-int,1))) translate(-2%,-2%)}}
/* Arcoíris: Los colores van cambiando poco a poco recorriendo todo el arcoíris. */
.gfx-arcoiris.gfx-arcoiris{--gfx-ac:gfx-k-arcoiris var(--gfx-dur,8s) linear var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-arcoiris{to{filter:hue-rotate(360deg)}}
/* Llamar la atención: Cada pocos segundos da un pequeño meneo para atraer la mirada. */
.gfx-zumbido.gfx-zumbido{--gfx-ac:gfx-k-zumbido var(--gfx-dur,4s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-zumbido{0%,12%,100%{transform:rotate(0)}2%,6%,10%{transform:rotate(calc(-6deg * var(--gfx-int,1)))}4%,8%{transform:rotate(calc(6deg * var(--gfx-int,1)))}}
/* Orbitar: Describe pequeños círculos, como si estuviera en órbita. */
.gfx-orbitar.gfx-orbitar{--gfx-ac:gfx-k-orbitar var(--gfx-dur,6s) linear var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-orbitar{from{transform:rotate(0deg) translateX(calc(8px * var(--gfx-int,1))) rotate(0deg)}to{transform:rotate(360deg) translateX(calc(8px * var(--gfx-int,1))) rotate(-360deg)}}
/* Mancha viva: La forma cambia de contorno orgánicamente, como una gota. */
.gfx-blob-animado.gfx-blob-animado{--gfx-ac:gfx-k-blob-animado var(--gfx-dur,8s) ease-in-out var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-blob-animado{0%,100%{border-radius:60% 40% 30% 70% / 60% 30% 70% 40%}33%{border-radius:30% 60% 70% 40% / 50% 60% 30% 60%}66%{border-radius:50% 50% 35% 65% / 35% 55% 45% 65%}}
/* Borde que gira: Un borde de luz da vueltas alrededor del elemento. Usa ::before. */
:where(.gfx-borde-giratorio.gfx-borde-giratorio){position:relative}
.gfx-borde-giratorio.gfx-borde-giratorio::before{content:"";position:absolute;inset:0;padding:calc(3px * var(--gfx-int,1));border-radius:inherit;pointer-events:none;background:conic-gradient(from var(--gfx-ang),var(--gfx-color,#6366f1),transparent 25%,#ec4899 50%,transparent 75%,var(--gfx-color,#6366f1));-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box exclude,linear-gradient(#000 0 0);animation:gfx-k-ang var(--gfx-dur,3s) linear var(--gfx-delay,0ms) infinite}

/* ======================================================= TEXTO */
/* Texto en degradado: Rellena las letras con un degradado de color. */
.gfx-texto-degradado.gfx-texto-degradado{background-image:linear-gradient(90deg,var(--gfx-color,#4f46e5),var(--gfx-color-2,#ec4899));background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;caret-color:var(--gfx-color,#4f46e5)}
/* Degradado en movimiento: Las letras se rellenan con un degradado que fluye sin parar. */
.gfx-texto-degradado-animado.gfx-texto-degradado-animado{background-image:linear-gradient(90deg,var(--gfx-color,#4f46e5),#ec4899,#f59e0b,var(--gfx-color,#4f46e5));background-size:300% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;caret-color:var(--gfx-color,#4f46e5);--gfx-at:gfx-k-flujo var(--gfx-dur,6s) linear var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-flujo{to{background-position:300% 0}}
/* Texto con contorno: Letras huecas, solo con el borde dibujado. */
.gfx-texto-contorno.gfx-texto-contorno{color:transparent;-webkit-text-fill-color:transparent;-webkit-text-stroke:calc(1.5px * var(--gfx-int,1)) var(--gfx-color,#0f172a);caret-color:var(--gfx-color,#0f172a)}
/* Contorno que se rellena: Letras huecas que se rellenan de color al pasar el ratón. */
.gfx-contorno-relleno.gfx-contorno-relleno{-webkit-text-stroke:calc(1.2px * var(--gfx-int,1)) var(--gfx-color,#4f46e5);color:transparent;-webkit-text-fill-color:transparent;background-image:linear-gradient(var(--gfx-color,#4f46e5),var(--gfx-color,#4f46e5));background-repeat:no-repeat;background-size:0% 100%;background-clip:text;-webkit-background-clip:text}
.gfx-contorno-relleno.gfx-contorno-relleno:hover{background-size:100% 100%}
/* Sombra larga: Una sombra sólida y alargada en diagonal, estilo cartel. */
.gfx-sombra-larga.gfx-sombra-larga{text-shadow:1px 1px 0 var(--gfx-color,#c7d2fe),2px 2px 0 var(--gfx-color,#c7d2fe),3px 3px 0 var(--gfx-color,#c7d2fe),4px 4px 0 var(--gfx-color,#c7d2fe),5px 5px 0 var(--gfx-color,#c7d2fe),6px 6px 0 var(--gfx-color,#c7d2fe),7px 7px 0 var(--gfx-color,#c7d2fe),8px 8px 0 var(--gfx-color,#c7d2fe),9px 9px 0 var(--gfx-color,#c7d2fe),10px 10px 0 var(--gfx-color,#c7d2fe),11px 11px 0 var(--gfx-color,#c7d2fe),12px 12px 0 var(--gfx-color,#c7d2fe),13px 13px 0 var(--gfx-color,#c7d2fe),14px 14px 0 var(--gfx-color,#c7d2fe)}
/* Sombra suave: Una sombra difusa que hace legible el texto sobre fotos. */
.gfx-sombra-suave-texto.gfx-sombra-suave-texto{text-shadow:0 2px calc(12px * var(--gfx-int,1)) rgb(0 0 0 / .45),0 1px 2px rgb(0 0 0 / .3)}
/* Texto en 3D: Las letras ganan volumen con capas de sombra. */
.gfx-texto-3d.gfx-texto-3d{text-shadow:0 1px 0 var(--gfx-color,#cbd5e1),0 2px 0 var(--gfx-color,#cbd5e1),0 3px 0 var(--gfx-color,#94a3b8),0 4px 0 var(--gfx-color,#94a3b8),0 5px 0 var(--gfx-color,#64748b),0 6px 1px rgb(0 0 0 / .1),0 0 5px rgb(0 0 0 / .1),0 3px 5px rgb(0 0 0 / .2),0 8px 10px rgb(0 0 0 / .2),0 14px 18px rgb(0 0 0 / .15)}
/* Resaltado con rotulador: Un trazo de rotulador aparece bajo el texto cuando entra en pantalla. */
.gfx-resaltado.gfx-resaltado{text-decoration-line:underline;text-decoration-skip-ink:none;text-decoration-color:var(--gfx-color,#fde047);text-decoration-thickness:.42em;text-underline-offset:-.28em;transition:text-decoration-thickness var(--gfx-dur,900ms) cubic-bezier(.2,.8,.2,1) var(--gfx-delay,0ms),text-decoration-color var(--gfx-dur,900ms) ease var(--gfx-delay,0ms)}
html.gfx-js .gfx-resaltado.gfx-resaltado:not(.gfx-in){text-decoration-thickness:0;text-decoration-color:transparent}
/* Subrayado ondulado: Un subrayado en zigzag suave, informal y llamativo. */
.gfx-subrayado-ondulado.gfx-subrayado-ondulado{text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:var(--gfx-color,#ec4899);text-decoration-thickness:calc(2px * var(--gfx-int,1));text-underline-offset:.25em;text-decoration-skip-ink:none}
/* Letrero de neón: Letras brillantes que zumban como un neón. Queda mejor sobre fondo oscuro. */
.gfx-neon.gfx-neon{color:#fff;text-shadow:0 0 4px #fff,0 0 10px var(--gfx-color,#22d3ee),0 0 22px var(--gfx-color,#22d3ee),0 0 42px var(--gfx-color,#22d3ee);--gfx-at:gfx-k-neon var(--gfx-dur,5s) linear var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-neon{0%,18%,22%,25%,53%,57%,100%{opacity:1}20%,24%,55%{opacity:.55}}
/* Máquina de escribir: El texto se escribe y se borra en bucle. Ajusta la duración a la longitud del texto. */
.gfx-maquina.gfx-maquina{--gfx-at:gfx-k-maquina var(--gfx-dur,5s) steps(22,end) var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-maquina{0%{clip-path:inset(0 100% 0 0)}45%,75%{clip-path:inset(0 0 0 0)}100%{clip-path:inset(0 100% 0 0)}}
/* Brillo que recorre: Un reflejo de luz recorre las letras una y otra vez. */
.gfx-brillo-texto.gfx-brillo-texto{background-image:linear-gradient(110deg,var(--gfx-color,#334155) 40%,#fff 50%,var(--gfx-color,#334155) 60%);background-size:250% 100%;background-position:100% 0;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;caret-color:var(--gfx-color,#334155);--gfx-at:gfx-k-brillo var(--gfx-dur,3s) linear var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-brillo{to{background-position:-150% 0}}
/* Texto con imagen: Las letras muestran un estampado de color. Pon una imagen de fondo al elemento para usarla dentro del texto. */
.gfx-texto-imagen.gfx-texto-imagen{background-image:repeating-linear-gradient(45deg,var(--gfx-color,#4f46e5) 0 10px,#ec4899 10px 20px,#f59e0b 20px 30px);background-size:cover;background-position:center;background-clip:text;-webkit-background-clip:text;color:transparent;-webkit-text-fill-color:transparent;caret-color:var(--gfx-color,#4f46e5)}
/* Glitch: Interferencias de colores como una pantalla estropeada, a ratos. */
.gfx-glitch.gfx-glitch{--gfx-at:gfx-k-glitch var(--gfx-dur,3s) steps(1,end) var(--gfx-delay,0ms) infinite}
@keyframes gfx-k-glitch{0%,86%,100%{text-shadow:none;translate:0 0}88%{text-shadow:calc(-3px * var(--gfx-int,1)) 0 #ff004c,calc(3px * var(--gfx-int,1)) 0 #00e5ff;translate:1px 0}90%{text-shadow:calc(3px * var(--gfx-int,1)) 0 #ff004c,calc(-3px * var(--gfx-int,1)) 0 #00e5ff;translate:-1px 0}92%{text-shadow:calc(-2px * var(--gfx-int,1)) 1px #ff004c,calc(2px * var(--gfx-int,1)) -1px #00e5ff;translate:0 1px}94%{text-shadow:none;translate:0 0}}
/* Letras que se separan: Las letras se separan con elegancia al pasar el ratón. */
.gfx-espaciado-hover.gfx-espaciado-hover:hover{letter-spacing:calc(.08em * var(--gfx-int,1))}

/* ======================================================= FONDO */
/* Degradado de color: Un degradado diagonal desde el color elegido hacia rosa. */
.gfx-fondo-degradado.gfx-fondo-degradado{background-image:linear-gradient(135deg,var(--gfx-color,#4f46e5),color-mix(in srgb,var(--gfx-color,#4f46e5) 40%,#ec4899))}
/* Degradado animado: Un degradado de varios colores que se mueve lentamente. */
.gfx-fondo-degradado-animado.gfx-fondo-degradado-animado{background-image:linear-gradient(120deg,var(--gfx-color,#4f46e5),#ec4899,#f59e0b,#22d3ee,var(--gfx-color,#4f46e5));background-size:400% 400%;--gfx-af:gfx-k-fondo var(--gfx-dur,14s) ease-in-out var(--gfx-delay,0ms) infinite alternate}
@keyframes gfx-k-fondo{0%{background-position:0% 50%}100%{background-position:100% 50%}}
/* Lunares: Un estampado de puntitos sobre el color de fondo. */
.gfx-puntos.gfx-puntos{background-image:radial-gradient(color-mix(in srgb,var(--gfx-color,#4f46e5) 35%,transparent) calc(1.5px * var(--gfx-int,1)),transparent calc(1.5px * var(--gfx-int,1) + .5px));background-size:22px 22px}
/* Rayas diagonales: Rayas finas en diagonal, discretas. */
.gfx-rayas.gfx-rayas{background-image:repeating-linear-gradient(45deg,color-mix(in srgb,var(--gfx-color,#4f46e5) 12%,transparent) 0 10px,transparent 10px 20px)}
/* Cuadrícula: Líneas finas en cuadrícula, como papel milimetrado. */
.gfx-cuadricula.gfx-cuadricula{background-image:linear-gradient(color-mix(in srgb,var(--gfx-color,#4f46e5) 15%,transparent) 1px,transparent 1px),linear-gradient(90deg,color-mix(in srgb,var(--gfx-color,#4f46e5) 15%,transparent) 1px,transparent 1px);background-size:28px 28px,28px 28px}
/* Cuadros de ajedrez: Cuadros alternos muy suaves. */
.gfx-cuadros.gfx-cuadros{background-image:conic-gradient(color-mix(in srgb,var(--gfx-color,#4f46e5) 10%,transparent) 25%,transparent 0 50%,color-mix(in srgb,var(--gfx-color,#4f46e5) 10%,transparent) 0 75%,transparent 0);background-size:32px 32px}
/* Zigzag: Un estampado en zigzag, alegre y dinámico. */
.gfx-zigzag.gfx-zigzag{background-image:linear-gradient(135deg,color-mix(in srgb,var(--gfx-color,#4f46e5) 14%,transparent) 25%,transparent 25%),linear-gradient(225deg,color-mix(in srgb,var(--gfx-color,#4f46e5) 14%,transparent) 25%,transparent 25%),linear-gradient(315deg,color-mix(in srgb,var(--gfx-color,#4f46e5) 14%,transparent) 25%,transparent 25%),linear-gradient(45deg,color-mix(in srgb,var(--gfx-color,#4f46e5) 14%,transparent) 25%,transparent 25%);background-size:24px 24px;background-position:-12px 0,-12px 0,0 0,0 0}
/* Malla de colores: Manchas de color difuminadas en las esquinas, muy moderno. */
.gfx-malla.gfx-malla{background-image:radial-gradient(at 0% 0%,color-mix(in srgb,var(--gfx-color,#4f46e5) 45%,transparent) 0,transparent 55%),radial-gradient(at 100% 0%,rgb(236 72 153 / .35) 0,transparent 50%),radial-gradient(at 100% 100%,rgb(34 211 238 / .35) 0,transparent 55%),radial-gradient(at 0% 100%,rgb(245 158 11 / .3) 0,transparent 50%)}
/* Foco de luz: Un halo de luz de color que cae desde arriba. */
.gfx-foco-luz.gfx-foco-luz{background-image:radial-gradient(ellipse at 50% 0%,color-mix(in srgb,var(--gfx-color,#4f46e5) 35%,transparent),transparent 65%)}
/* Cristal esmerilado: Fondo translúcido que desenfoca lo que hay detrás (glassmorphism). Ponlo sobre una foto o un fondo de color. */
.gfx-cristal.gfx-cristal{background-color:rgb(255 255 255 / .18);-webkit-backdrop-filter:blur(calc(14px * var(--gfx-int,1))) saturate(160%);backdrop-filter:blur(calc(14px * var(--gfx-int,1))) saturate(160%);border:1px solid rgb(255 255 255 / .35);box-shadow:0 8px 32px rgb(15 23 42 / .18)}
/* Grano sutil: Una textura de grano muy fina que da calidez a los fondos lisos. */
.gfx-ruido.gfx-ruido{background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .16 0'/></filter><rect width='160' height='160' filter='url(%23n)'/></svg>")}
/* Aurora: Luces de colores difuminadas que se mueven despacio por detrás del contenido. Usa ::before. */
:where(.gfx-aurora.gfx-aurora){position:relative;isolation:isolate;overflow:hidden}
.gfx-aurora.gfx-aurora::before{content:"";position:absolute;inset:-50%;z-index:-1;pointer-events:none;background:radial-gradient(closest-side,color-mix(in srgb,var(--gfx-color,#6366f1) 55%,transparent),transparent) 20% 30% / 50% 50% no-repeat,radial-gradient(closest-side,rgb(34 211 238 / .45),transparent) 75% 40% / 45% 45% no-repeat,radial-gradient(closest-side,rgb(236 72 153 / .4),transparent) 45% 75% / 55% 55% no-repeat;filter:blur(30px);animation:gfx-k-aurora var(--gfx-dur,16s) ease-in-out var(--gfx-delay,0ms) infinite alternate}
@keyframes gfx-k-aurora{0%{transform:rotate(0deg) translate(0,0)}50%{transform:rotate(25deg) translate(6%,-4%)}100%{transform:rotate(-15deg) translate(-5%,5%)}}
/* Parallax (fondo fijo): La imagen de fondo se queda quieta al hacer scroll. Pon una imagen de fondo al elemento. En móviles se ve normal. */
.gfx-parallax.gfx-parallax{background-attachment:fixed;background-size:cover;background-position:center}
/* Velo oscuro: Oscurece el fondo (o la foto de fondo) para que el texto blanco se lea bien. */
.gfx-velo-oscuro.gfx-velo-oscuro{box-shadow:inset 0 0 0 100vmax rgb(15 23 42 / calc(.45 * var(--gfx-int,1)));color:#fff}

/* ======================================================= FORMA Y SOMBRA */
/* Esquinas muy redondeadas: Esquinas grandes y suaves, aspecto amable y moderno. */
.gfx-redondeado.gfx-redondeado{border-radius:calc(24px * var(--gfx-int,1))}
/* Píldora: Extremos totalmente redondos, como una cápsula. Ideal para botones y etiquetas. */
.gfx-pildora.gfx-pildora{border-radius:999px}
/* Círculo: Convierte el elemento en un círculo perfecto (recorta lo que sobresale). */
.gfx-circulo.gfx-circulo{border-radius:50%;aspect-ratio:1;overflow:hidden}
.gfx-circulo.gfx-circulo img{width:100%;height:100%;object-fit:cover}
/* Mancha orgánica: Una forma redondeada irregular, natural y desenfadada. */
.gfx-blob.gfx-blob{border-radius:60% 40% 30% 70% / 60% 30% 70% 40%;overflow:hidden}
/* Corte diagonal: El borde inferior se corta en diagonal. Perfecto para portadas. */
.gfx-corte-diagonal.gfx-corte-diagonal{clip-path:polygon(0 0,100% 0,100% calc(100% - 60px * var(--gfx-int,1)),0 100%)}
/* Doble diagonal: Bordes superior e inferior inclinados, muy dinámico. */
.gfx-bisel.gfx-bisel{clip-path:polygon(0 calc(40px * var(--gfx-int,1)),100% 0,100% calc(100% - 40px * var(--gfx-int,1)),0 100%)}
/* Punta de flecha: El borde inferior termina en punta, señalando lo que viene después. */
.gfx-flecha-abajo.gfx-flecha-abajo{clip-path:polygon(0 0,100% 0,100% calc(100% - 36px * var(--gfx-int,1)),50% 100%,0 calc(100% - 36px * var(--gfx-int,1)))}
/* Hexágono: Recorta el elemento en forma de hexágono. */
.gfx-hexagono.gfx-hexagono{clip-path:polygon(25% 0,75% 0,100% 50%,75% 100%,25% 100%,0 50%)}
/* Borde festoneado: El borde inferior forma ondas redondeadas, como un toldo. */
.gfx-ondas-borde.gfx-ondas-borde{-webkit-mask:radial-gradient(calc(12px * var(--gfx-int,1)) at 50% 100%,transparent 98%,#000) 50% 0 / calc(24px * var(--gfx-int,1)) 100% repeat-x;mask:radial-gradient(calc(12px * var(--gfx-int,1)) at 50% 100%,transparent 98%,#000) 50% 0 / calc(24px * var(--gfx-int,1)) 100% repeat-x}
/* Sombra suave: Sombra difusa y realista, el toque profesional para tarjetas. */
.gfx-sombra-suave.gfx-sombra-suave{box-shadow:0 1px 2px rgb(15 23 42 / .06),0 calc(10px * var(--gfx-int,1)) calc(30px * var(--gfx-int,1)) -8px rgb(15 23 42 / .22)}
/* Sombra dura: Sombra sólida desplazada y borde negro, estilo cómic o neobrutalista. */
.gfx-sombra-dura.gfx-sombra-dura{border:2px solid #0f172a;box-shadow:calc(6px * var(--gfx-int,1)) calc(6px * var(--gfx-int,1)) 0 var(--gfx-color,#0f172a)}
/* Sombras en capas: Dos sombras sólidas de color escalonadas, muy gráfico. */
.gfx-sombra-capas.gfx-sombra-capas{box-shadow:calc(6px * var(--gfx-int,1)) calc(6px * var(--gfx-int,1)) 0 var(--gfx-color,#4f46e5),calc(12px * var(--gfx-int,1)) calc(12px * var(--gfx-int,1)) 0 color-mix(in srgb,var(--gfx-color,#4f46e5) 45%,transparent)}
/* Relieve suave (neumórfico): Parece moldeado en la propia superficie, con luz y sombra. */
.gfx-neumorfico.gfx-neumorfico{background-color:#e8edf3;border-radius:20px;box-shadow:calc(8px * var(--gfx-int,1)) calc(8px * var(--gfx-int,1)) calc(16px * var(--gfx-int,1)) #c5ccd6,calc(-8px * var(--gfx-int,1)) calc(-8px * var(--gfx-int,1)) calc(16px * var(--gfx-int,1)) #fff}
/* Borde en degradado: Un borde con degradado de color. Usa ::before. */
:where(.gfx-borde-degradado.gfx-borde-degradado){position:relative}
.gfx-borde-degradado.gfx-borde-degradado::before{content:"";position:absolute;inset:0;padding:calc(2px * var(--gfx-int,1));border-radius:inherit;pointer-events:none;background:linear-gradient(135deg,var(--gfx-color,#4f46e5),#ec4899,#f59e0b);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box exclude,linear-gradient(#000 0 0)}
/* Marco doble: Un borde y un contorno separado, como un marco con paspartú. */
.gfx-marco-doble.gfx-marco-doble{border:2px solid var(--gfx-color,#4f46e5);outline:2px solid var(--gfx-color,#4f46e5);outline-offset:calc(5px * var(--gfx-int,1))}
/* Esquina doblada: La esquina superior derecha parece doblada, como una hoja de papel. Usa ::after. */
:where(.gfx-esquina-doblada.gfx-esquina-doblada){position:relative}
.gfx-esquina-doblada.gfx-esquina-doblada{clip-path:polygon(0 0,calc(100% - 28px * var(--gfx-int,1)) 0,100% calc(28px * var(--gfx-int,1)),100% 100%,0 100%)}
.gfx-esquina-doblada.gfx-esquina-doblada::after{content:"";position:absolute;top:0;right:0;width:calc(28px * var(--gfx-int,1));height:calc(28px * var(--gfx-int,1));pointer-events:none;background:linear-gradient(to left bottom,transparent 50%,rgb(0 0 0 / .22) 50%);border-bottom-left-radius:4px}
/* Inclinado: Ligeramente girado, como una nota pegada en la pared. */
.gfx-inclinado.gfx-inclinado{rotate:calc(-2deg * var(--gfx-int,1))}
/* Marco de foto: Borde blanco ancho y sombra, como una foto instantánea. */
.gfx-marco-foto.gfx-marco-foto{background-color:#fff;padding:10px 10px 34px;box-shadow:0 10px 24px -8px rgb(15 23 42 / .35)}

/* ======================================================= FILTROS */
/* Blanco y negro → color: En blanco y negro; recupera el color al pasar el ratón. */
.gfx-bn-a-color.gfx-bn-a-color{filter:grayscale(1)}
.gfx-bn-a-color.gfx-bn-a-color:hover{filter:grayscale(0)}
/* Color → blanco y negro: A color; pasa a blanco y negro al pasar el ratón. */
.gfx-color-a-bn.gfx-color-a-bn{filter:grayscale(0)}
.gfx-color-a-bn.gfx-color-a-bn:hover{filter:grayscale(1)}
/* Sepia: Tono marrón cálido de foto antigua. */
.gfx-sepia.gfx-sepia{filter:sepia(calc(.8 * var(--gfx-int,1)))}
/* Vintage: Colores apagados y cálidos, como una foto de los 70. */
.gfx-vintage.gfx-vintage{filter:sepia(.45) contrast(1.1) saturate(.85) brightness(1.05)}
/* Duotono azul: La imagen en dos tonos azulados, muy de revista. */
.gfx-duotono.gfx-duotono{filter:grayscale(1) sepia(1) saturate(4) hue-rotate(190deg) brightness(.95)}
/* Desenfocado: Desenfoca el elemento. Útil para fondos detrás de texto. */
.gfx-desenfoque.gfx-desenfoque{filter:blur(calc(4px * var(--gfx-int,1)))}
/* Borroso que se aclara: Desenfocado hasta que pasas el ratón por encima. */
.gfx-enfocar-hover.gfx-enfocar-hover{filter:blur(calc(4px * var(--gfx-int,1)))}
.gfx-enfocar-hover.gfx-enfocar-hover:hover{filter:blur(0)}
/* Alto contraste: Colores más intensos y negros más profundos. */
.gfx-alto-contraste.gfx-alto-contraste{filter:contrast(calc(1 + .4 * var(--gfx-int,1))) saturate(1.15)}
/* Colores vivos: Aumenta la saturación para que los colores destaquen. */
.gfx-saturado.gfx-saturado{filter:saturate(calc(1 + .8 * var(--gfx-int,1)))}
/* Suave y luminoso: Colores lavados y luminosos, aspecto delicado. */
.gfx-apagado.gfx-apagado{filter:saturate(.55) brightness(1.08) contrast(.92)}
/* Invertir colores: Invierte los colores conservando los tonos (efecto negativo). */
.gfx-invertir.gfx-invertir{filter:invert(1) hue-rotate(180deg)}
/* Iluminar al pasar: Se ilumina un poco al pasar el ratón. */
.gfx-brillo-hover.gfx-brillo-hover:hover{filter:brightness(calc(1 + .15 * var(--gfx-int,1))) saturate(1.1)}
/* Oscurecer al pasar: Se oscurece al pasar el ratón, ideal para mostrar un texto encima. */
.gfx-oscurecer-hover.gfx-oscurecer-hover:hover{filter:brightness(calc(1 - .3 * var(--gfx-int,1)))}
/* Sombra que sigue la forma: Sombra que sigue el contorno real (logotipos PNG, iconos, recortes). */
.gfx-sombra-forma.gfx-sombra-forma{filter:drop-shadow(0 calc(10px * var(--gfx-int,1)) calc(12px * var(--gfx-int,1)) rgb(15 23 42 / .3))}

/* ---- Menos movimiento: sin animaciones ni transiciones; todo visible ---- */
@media (prefers-reduced-motion:reduce){
[class*="gfx-"],[class*="gfx-"]::before,[class*="gfx-"]::after,.gfx-escalonado > *,.gfx-zoom-imagen img,.gfx-girar-icono :is(.gfp-icono,svg){animation:none!important;transition:none!important}
}
/* ---- Impresión: todo visible y quieto ---- */
@media print{
[class*="gfx-"],.gfx-escalonado > *{animation:none!important;opacity:1!important;clip-path:none}
}
