/* Emberium Deck - modern CSS effects used by this template. Each effect is one class: fx-NAME. */

/* ===== Modern CSS Animations ===== */
/* Morphing Blob - Turns a shape or a photo frame into an organic blob that slowly changes its outline. */
.fx-morphing-blob {
  border-radius: 42% 58% 63% 37% / 41% 44% 56% 59%;
  background: linear-gradient(135deg, var(--wt-primary), var(--wt-secondary));
  overflow: hidden;
  animation: fx-morphing-blob-morph 9s ease-in-out infinite;
}
.fx-morphing-blob img { width: 100%; height: 100%; object-fit: cover; display: block; }
@keyframes fx-morphing-blob-morph {
  0%, 100% { border-radius: 42% 58% 63% 37% / 41% 44% 56% 59%; }
  33% { border-radius: 70% 30% 46% 54% / 30% 39% 61% 70%; }
  66% { border-radius: 30% 70% 70% 30% / 53% 30% 70% 47%; }
}
@media (prefers-reduced-motion: reduce) {
  .fx-morphing-blob, .fx-morphing-blob::before, .fx-morphing-blob::after, .fx-morphing-blob *, .fx-morphing-blob *::before, .fx-morphing-blob *::after { animation: none !important; transition: none !important; }
}
/* Particle Float - Fills a card or panel with small glowing particles that rise behind its content. */
.fx-particle-float { position: relative; isolation: isolate; overflow: hidden; }
.fx-particle-float::before, .fx-particle-float::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    radial-gradient(circle at 12% 30%, rgba(var(--wt-primary-rgb), .7) 0 2px, transparent 3px),
    radial-gradient(circle at 38% 80%, rgba(var(--wt-accent-rgb), .7) 0 3px, transparent 4px),
    radial-gradient(circle at 62% 45%, rgba(var(--wt-secondary-rgb), .6) 0 2px, transparent 3px),
    radial-gradient(circle at 86% 15%, rgba(var(--wt-primary-rgb), .6) 0 3px, transparent 4px);
  background-size: 160px 160px;
  animation: fx-particle-float-rise 10s linear infinite;
}
.fx-particle-float::after { background-size: 230px 230px; opacity: .6; animation: fx-particle-float-rise-slow 16s linear infinite; }
@keyframes fx-particle-float-rise { to { background-position: 0 -160px; } }
@keyframes fx-particle-float-rise-slow { to { background-position: 0 -230px; } }
@media (prefers-reduced-motion: reduce) {
  .fx-particle-float, .fx-particle-float::before, .fx-particle-float::after, .fx-particle-float *, .fx-particle-float *::before, .fx-particle-float *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Clip-path Effects ===== */
/* Triangle Spin - Cuts an element into a triangle and spins it slowly - great for loaders and decorative badges. */
.fx-triangle-spin {
  -webkit-clip-path: polygon(50% 4%, 96% 88%, 4% 88%); clip-path: polygon(50% 4%, 96% 88%, 4% 88%);
  background: linear-gradient(160deg, var(--wt-primary), var(--wt-accent));
  animation: fx-triangle-spin-spin 6s linear infinite;
}
@keyframes fx-triangle-spin-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .fx-triangle-spin, .fx-triangle-spin::before, .fx-triangle-spin::after, .fx-triangle-spin *, .fx-triangle-spin *::before, .fx-triangle-spin *::after { animation: none !important; transition: none !important; }
}
/* Shape Shifter - A twelve-corner circle that snaps into a plus sign on hover - handy for add buttons and icons. */
.fx-shape-shifter {
  -webkit-clip-path: polygon(30.9% 3.8%, 56.5% 0.4%, 80.4% 10.3%, 96.2% 30.9%, 99.6% 56.5%, 89.7% 80.4%, 69.1% 96.2%, 43.5% 99.6%, 19.6% 89.7%, 3.8% 69.1%, 0.4% 43.5%, 10.3% 19.6%); clip-path: polygon(30.9% 3.8%, 56.5% 0.4%, 80.4% 10.3%, 96.2% 30.9%, 99.6% 56.5%, 89.7% 80.4%, 69.1% 96.2%, 43.5% 99.6%, 19.6% 89.7%, 3.8% 69.1%, 0.4% 43.5%, 10.3% 19.6%);
  transition: clip-path .5s cubic-bezier(.68, -.4, .27, 1.4), transform .5s;
  background: linear-gradient(135deg, var(--wt-primary), var(--wt-secondary));
}
.fx-shape-shifter:hover, .fx-shape-shifter:focus-visible { -webkit-clip-path: polygon(35% 0, 65% 0, 65% 35%, 100% 35%, 100% 65%, 65% 65%, 65% 100%, 35% 100%, 35% 65%, 0 65%, 0 35%, 35% 35%); clip-path: polygon(35% 0, 65% 0, 65% 35%, 100% 35%, 100% 65%, 65% 65%, 65% 100%, 35% 100%, 35% 65%, 0 65%, 0 35%, 35% 35%); transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) {
  .fx-shape-shifter, .fx-shape-shifter::before, .fx-shape-shifter::after, .fx-shape-shifter *, .fx-shape-shifter *::before, .fx-shape-shifter *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Filter Effects ===== */
/* Invert Colors - Flips an image or card to its negative on hover while hue-rotate keeps the colours recognisable. */
.fx-invert-colors { transition: filter .4s ease; }
.fx-invert-colors:hover, .fx-invert-colors:focus-visible { filter: invert(1) hue-rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
  .fx-invert-colors, .fx-invert-colors::before, .fx-invert-colors::after, .fx-invert-colors *, .fx-invert-colors *::before, .fx-invert-colors *::after { animation: none !important; transition: none !important; }
}
/* Duotone Effect - Turns any photo into a two-colour print in the theme colours; put the class on a wrapper around the img. */
.fx-duotone-effect { position: relative; display: inline-block; overflow: hidden; isolation: isolate; background: var(--wt-accent); }
.fx-duotone-effect img { display: block; filter: grayscale(1) contrast(1.2) brightness(1.1); mix-blend-mode: multiply; transition: filter .5s; }
.fx-duotone-effect::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: var(--wt-primary); mix-blend-mode: lighten; transition: opacity .5s;
}
.fx-duotone-effect:hover::after { opacity: 0; }
.fx-duotone-effect:hover img { filter: grayscale(0); mix-blend-mode: normal; }
@media (prefers-reduced-motion: reduce) {
  .fx-duotone-effect, .fx-duotone-effect::before, .fx-duotone-effect::after, .fx-duotone-effect *, .fx-duotone-effect *::before, .fx-duotone-effect *::after { animation: none !important; transition: none !important; }
}
/* Glitch Filter - Short bursts of hue, contrast and position jumps make an image look like a corrupted signal. */
.fx-glitch-filter { animation: fx-glitch-filter-glitch 3.5s steps(1) infinite; }
@keyframes fx-glitch-filter-glitch {
  0%, 86%, 100% { filter: none; transform: none; }
  88% { filter: hue-rotate(90deg) saturate(3) contrast(1.6); transform: translate(-4px, 1px); }
  90% { filter: invert(.15) contrast(2); transform: translate(4px, -2px) skewX(6deg); }
  92% { filter: hue-rotate(-70deg) saturate(2); transform: translate(-2px, 0); }
  94% { filter: brightness(1.6); transform: translate(2px, 1px); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-glitch-filter, .fx-glitch-filter::before, .fx-glitch-filter::after, .fx-glitch-filter *, .fx-glitch-filter *::before, .fx-glitch-filter *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Transform Effects ===== */
/* 3D Card Tilt - Tilts a card in 3D with a moving glare on hover - a pure CSS take on the mouse-follow tilt. */
.fx-3d-card-tilt {
  position: relative; overflow: hidden; transform-style: preserve-3d;
  transform: perspective(900px) rotateX(0deg) rotateY(0deg);
  transition: transform .55s cubic-bezier(.2, .8, .2, 1), box-shadow .55s;
}
.fx-3d-card-tilt::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .45) 48%, transparent 62%);
  transform: translateX(-60%); transition: transform .7s ease, opacity .4s;
}
.fx-3d-card-tilt:hover, .fx-3d-card-tilt:focus-within {
  transform: perspective(900px) rotateX(8deg) rotateY(-12deg) translateY(-4px);
  box-shadow: 18px 22px 40px -18px rgba(var(--wt-primary-rgb), .55);
}
.fx-3d-card-tilt:hover::after, .fx-3d-card-tilt:focus-within::after { opacity: 1; transform: translateX(60%); }
@media (prefers-reduced-motion: reduce) {
  .fx-3d-card-tilt, .fx-3d-card-tilt::before, .fx-3d-card-tilt::after, .fx-3d-card-tilt *, .fx-3d-card-tilt *::before, .fx-3d-card-tilt *::after { animation: none !important; transition: none !important; }
}
/* Matrix Transform - Uses a single matrix() to scale, skew and lift a tile at once on hover. */
.fx-matrix-transform { transition: transform .5s cubic-bezier(.34, 1.56, .64, 1), box-shadow .5s; }
.fx-matrix-transform:hover, .fx-matrix-transform:focus-visible { transform: matrix(1.05, -.08, .12, 1.05, 0, -8); box-shadow: 0 20px 30px -16px rgba(var(--wt-primary-rgb), .5); }
@media (prefers-reduced-motion: reduce) {
  .fx-matrix-transform, .fx-matrix-transform::before, .fx-matrix-transform::after, .fx-matrix-transform *, .fx-matrix-transform *::before, .fx-matrix-transform *::after { animation: none !important; transition: none !important; }
}
/* Scale & Rotate - A springy scale-and-twist on hover for icons, avatars, logos and small buttons. */
.fx-scale-rotate { transition: transform .45s cubic-bezier(.34, 1.8, .64, 1); }
.fx-scale-rotate:hover, .fx-scale-rotate:focus-visible { transform: scale(1.15) rotate(-8deg); }
@media (prefers-reduced-motion: reduce) {
  .fx-scale-rotate, .fx-scale-rotate::before, .fx-scale-rotate::after, .fx-scale-rotate *, .fx-scale-rotate *::before, .fx-scale-rotate *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Transitions ===== */
/* Neon Fill Button - An outline button that fills with colour from the left and glows; works on any .btn or link. */
.fx-neon-fill-button, .btn.fx-neon-fill-button {
  position: relative; isolation: isolate; overflow: hidden; z-index: 0;
  color: var(--wt-primary-ink); background: transparent; border: 2px solid var(--wt-primary);
  transition: color .35s ease, box-shadow .35s ease;
}
.fx-neon-fill-button::before {
  content: ""; position: absolute; inset: 0; z-index: -1; background: var(--wt-primary);
  transform: scaleX(0); transform-origin: left center; transition: transform .4s cubic-bezier(.7, 0, .3, 1);
}
.fx-neon-fill-button:hover, .fx-neon-fill-button:focus-visible, .btn.fx-neon-fill-button:hover, .btn.fx-neon-fill-button:focus-visible {
  color: var(--wt-on-primary, #fff); border-color: var(--wt-primary);
  box-shadow: 0 0 12px rgba(var(--wt-primary-rgb), .6), 0 0 32px rgba(var(--wt-primary-rgb), .35);
}
.fx-neon-fill-button:hover::before, .fx-neon-fill-button:focus-visible::before { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .fx-neon-fill-button, .fx-neon-fill-button::before, .fx-neon-fill-button::after, .fx-neon-fill-button *, .fx-neon-fill-button *::before, .fx-neon-fill-button *::after { animation: none !important; transition: none !important; }
}
/* Magnetic Hover - Fakes a magnetic pull: the element lifts toward the pointer and its icon leans further with an elastic ease. */
.fx-magnetic-hover { transition: transform .45s cubic-bezier(.34, 1.56, .64, 1), box-shadow .45s; }
.fx-magnetic-hover > * { display: inline-block; transition: transform .45s cubic-bezier(.34, 1.56, .64, 1); }
.fx-magnetic-hover:hover, .fx-magnetic-hover:focus-visible { transform: translate(3px, -4px) scale(1.06); box-shadow: -6px 12px 22px -10px rgba(var(--wt-primary-rgb), .6); }
.fx-magnetic-hover:hover > *, .fx-magnetic-hover:focus-visible > * { transform: translate(3px, -2px); }
@media (prefers-reduced-motion: reduce) {
  .fx-magnetic-hover, .fx-magnetic-hover::before, .fx-magnetic-hover::after, .fx-magnetic-hover *, .fx-magnetic-hover *::before, .fx-magnetic-hover *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern CSS Gradient Effects ===== */
/* Mesh Gradient - Soft blobs of the theme colours blended into a slowly drifting mesh - perfect for hero panels. */
.fx-mesh-gradient {
  background-color: var(--wt-primary);
  background-image:
    radial-gradient(at 15% 20%, var(--wt-accent) 0, transparent 55%),
    radial-gradient(at 85% 15%, var(--wt-secondary) 0, transparent 50%),
    radial-gradient(at 75% 85%, var(--wt-accent) 0, transparent 50%),
    radial-gradient(at 20% 90%, var(--wt-secondary) 0, transparent 55%);
  background-size: 160% 160%;
  color: var(--wt-on-primary, #fff);
  animation: fx-mesh-gradient-drift 14s ease-in-out infinite alternate;
}
@keyframes fx-mesh-gradient-drift { from { background-position: 0% 0%; } to { background-position: 100% 100%; } }
@media (prefers-reduced-motion: reduce) {
  .fx-mesh-gradient, .fx-mesh-gradient::before, .fx-mesh-gradient::after, .fx-mesh-gradient *, .fx-mesh-gradient *::before, .fx-mesh-gradient *::after { animation: none !important; transition: none !important; }
}
/* Gradient Shadow - A colourful multi-tone glow under cards and images built from layered tinted shadows. */
.fx-gradient-shadow {
  box-shadow: -14px 12px 30px -10px rgba(var(--wt-primary-rgb), .55), 14px 12px 30px -10px rgba(var(--wt-secondary-rgb), .55), 0 22px 36px -14px rgba(var(--wt-accent-rgb), .55);
  transition: box-shadow .4s ease, transform .4s ease;
}
.fx-gradient-shadow:hover, .fx-gradient-shadow:focus-visible {
  transform: translateY(-4px);
  box-shadow: -20px 18px 40px -10px rgba(var(--wt-primary-rgb), .7), 20px 18px 40px -10px rgba(var(--wt-secondary-rgb), .7), 0 30px 46px -14px rgba(var(--wt-accent-rgb), .7);
}
@media (prefers-reduced-motion: reduce) {
  .fx-gradient-shadow, .fx-gradient-shadow::before, .fx-gradient-shadow::after, .fx-gradient-shadow *, .fx-gradient-shadow *::before, .fx-gradient-shadow *::after { animation: none !important; transition: none !important; }
}

/* ===== Modern Shadow Effects ===== */
/* Glassmorphism - A frosted translucent panel with an inner highlight and soft drop shadow for overlays on images or gradients. */
.fx-glassmorphism {
  color: #fff;
  background: linear-gradient(135deg, rgba(255, 255, 255, .22), rgba(255, 255, 255, .08));
  border: 1px solid rgba(255, 255, 255, .3);
  -webkit-backdrop-filter: blur(14px) saturate(160%); backdrop-filter: blur(14px) saturate(160%);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18), inset 0 1px 0 rgba(255, 255, 255, .45);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .fx-glassmorphism { background: rgba(var(--wt-primary-rgb), .85); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-glassmorphism, .fx-glassmorphism::before, .fx-glassmorphism::after, .fx-glassmorphism *, .fx-glassmorphism *::before, .fx-glassmorphism *::after { animation: none !important; transition: none !important; }
}
/* Colored Shadows - Tinted shadows in the primary colour (override with --fx-shadow-rgb) that make buttons and images glow softly. */
.fx-colored-shadows {
  box-shadow: 0 14px 28px -12px rgba(var(--fx-shadow-rgb, var(--wt-primary-rgb)), .65);
  transition: box-shadow .35s ease, transform .35s ease;
}
.fx-colored-shadows:hover, .fx-colored-shadows:focus-visible { transform: translateY(-3px); box-shadow: 0 20px 36px -12px rgba(var(--fx-shadow-rgb, var(--wt-primary-rgb)), .8); }
@media (prefers-reduced-motion: reduce) {
  .fx-colored-shadows, .fx-colored-shadows::before, .fx-colored-shadows::after, .fx-colored-shadows *, .fx-colored-shadows *::before, .fx-colored-shadows *::after { animation: none !important; transition: none !important; }
}
/* Outline Glow - A glowing focus ring for inputs, buttons and cards that appears on hover and keyboard focus. */
.fx-outline-glow { outline: 2px solid transparent; outline-offset: 2px; transition: box-shadow .3s ease, border-color .3s ease; }
.fx-outline-glow:hover, .fx-outline-glow:focus, .fx-outline-glow:focus-visible, .fx-outline-glow:focus-within {
  border-color: var(--wt-primary);
  box-shadow: 0 0 0 3px rgba(var(--wt-primary-rgb), .3), 0 0 18px rgba(var(--wt-primary-rgb), .45);
}
@media (prefers-reduced-motion: reduce) {
  .fx-outline-glow, .fx-outline-glow::before, .fx-outline-glow::after, .fx-outline-glow *, .fx-outline-glow *::before, .fx-outline-glow *::after { animation: none !important; transition: none !important; }
}

/* ===== Advanced Animated Backgrounds ===== */
/* Scrolling - A fine blueprint grid that scrolls diagonally forever and fades out towards the edges. */
.fx-bg-scrolling { position: relative; isolation: isolate; overflow: hidden; }
.fx-bg-scrolling::before, .fx-bg-scrolling::after { content: ""; position: absolute; pointer-events: none; z-index: -1; }
.fx-bg-scrolling::before {
  inset: 0;
  background-image:
    linear-gradient(rgba(var(--wt-primary-rgb), .16) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--wt-primary-rgb), .16) 1px, transparent 1px);
  background-size: 36px 36px;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 30%, transparent 78%); mask-image: radial-gradient(ellipse at center, #000 30%, transparent 78%);
  animation: fx-bg-scrolling-scroll 6s linear infinite;
}
@keyframes fx-bg-scrolling-scroll { to { background-position: 36px 36px; } }
@media (prefers-reduced-motion: reduce) {
  .fx-bg-scrolling, .fx-bg-scrolling::before, .fx-bg-scrolling::after, .fx-bg-scrolling *, .fx-bg-scrolling *::before, .fx-bg-scrolling *::after { animation: none !important; transition: none !important; }
}
/* Parallax - Three layers of dots and soft orbs drift at different speeds, giving the section a sense of depth. */
.fx-bg-parallax { position: relative; isolation: isolate; overflow: hidden; }
.fx-bg-parallax::before, .fx-bg-parallax::after { content: ""; position: absolute; pointer-events: none; z-index: -1; }
.fx-bg-parallax::before {
  inset: 0;
  background-image:
    radial-gradient(circle, rgba(var(--wt-primary-rgb), .35) 0 1px, transparent 1.5px),
    radial-gradient(circle, rgba(var(--wt-secondary-rgb), .4) 0 2px, transparent 2.5px);
  background-size: 24px 24px, 70px 70px;
  animation: fx-bg-parallax-layers 20s linear infinite;
}
.fx-bg-parallax::after {
  inset: 0;
  background-image:
    radial-gradient(circle, rgba(var(--wt-accent-rgb), .22) 0 18px, transparent 32px),
    radial-gradient(circle, rgba(var(--wt-primary-rgb), .18) 0 26px, transparent 44px);
  background-size: 220px 220px, 340px 340px;
  background-position: 30px 60px, 180px 10px;
  animation: fx-bg-parallax-near 20s linear infinite;
}
@keyframes fx-bg-parallax-layers { to { background-position: -24px 0, -140px 0; } }
@keyframes fx-bg-parallax-near { to { background-position: -410px 60px, -500px 10px; } }
@media (prefers-reduced-motion: reduce) {
  .fx-bg-parallax, .fx-bg-parallax::before, .fx-bg-parallax::after, .fx-bg-parallax *, .fx-bg-parallax *::before, .fx-bg-parallax *::after { animation: none !important; transition: none !important; }
}
