/*
  Animations ported from Magic UI (magicui.design, via the Magic UI MCP) to plain CSS for Blazor.
  Each block names its source component. Triggers are set by js/pono.js (IntersectionObserver).
*/

/* ---- blur-fade: fade + un-blur + small slide when scrolled into view ---- */
.mu-blur-fade {
    opacity: 0;
    filter: blur(var(--mu-blur, 6px));
    transform: translateY(calc(var(--mu-offset, 6px) * -1));
    transition: opacity var(--mu-duration, .5s) ease-out, filter var(--mu-duration, .5s) ease-out, transform var(--mu-duration, .5s) ease-out;
    transition-delay: calc(.04s + var(--mu-delay, 0s));
    will-change: opacity, filter, transform;
}
.mu-blur-fade.up { transform: translateY(var(--mu-offset, 6px)); }
.mu-blur-fade.is-visible { opacity: 1; filter: blur(0); transform: none; }
/* After the reveal, drop the filter entirely: an ancestor filter breaks background-clip:text (aurora/shiny text) in Chromium. */
.mu-blur-fade.is-done { filter: none; will-change: auto; transition: none; }

/* ---- text-animate (blurInUp, by word): each word blurs in, staggered ---- */
.mu-text-animate .mu-seg {
    display: inline-block;
    white-space: pre;
    opacity: 0;
    filter: blur(10px);
    transform: translateY(20px);
    animation: mu-blur-in-up var(--mu-duration, .45s) ease-out forwards;
    animation-delay: calc(var(--mu-delay, 0s) + var(--i, 0) * var(--mu-stagger, .08s));
}
.mu-text-animate.wait .mu-seg { animation-play-state: paused; }
@keyframes mu-blur-in-up { to { opacity: 1; filter: blur(0); transform: none; } }

/* ---- ripple: concentric circles gently pulsing behind content ---- */
.mu-ripple {
    position: absolute; inset: 0; pointer-events: none; user-select: none; overflow: hidden;
    -webkit-mask-image: radial-gradient(circle at center, #000 30%, transparent 72%);
    mask-image: radial-gradient(circle at center, #000 30%, transparent 72%);
}
.mu-ripple > span {
    position: absolute; top: 50%; left: 50%; border-radius: 50%;
    border: 1px solid var(--mu-ripple-color, rgba(191, 227, 220, .6));
    background: var(--mu-ripple-fill, rgba(191, 227, 220, .06));
    transform: translate(-50%, -50%) scale(1);
    animation: mu-ripple var(--mu-duration, 2s) ease calc(var(--i, 0) * .2s) infinite;
}
@keyframes mu-ripple { 0%, 100% { transform: translate(-50%, -50%) scale(1); } 50% { transform: translate(-50%, -50%) scale(.9); } }

/* ---- orbiting-circles: items travel around a circular path ---- */
.mu-orbit-stage { position: relative; display: grid; place-items: center; }
.mu-orbit-path { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.mu-orbit-path circle { fill: none; stroke: currentColor; stroke-opacity: .14; }
.mu-orbit-item {
    position: absolute; display: flex; align-items: center; justify-content: center;
    width: var(--icon-size, 30px); height: var(--icon-size, 30px);
    animation: mu-orbit calc(var(--duration, 20) * 1s) linear infinite;
}
.mu-orbit-item.reverse { animation-direction: reverse; }
@keyframes mu-orbit {
    0% { transform: rotate(calc(var(--angle) * 1deg)) translateY(calc(var(--radius) * 1px)) rotate(calc(var(--angle) * -1deg)); }
    100% { transform: rotate(calc(var(--angle) * 1deg + 360deg)) translateY(calc(var(--radius) * 1px)) rotate(calc((var(--angle) * -1deg) - 360deg)); }
}

/* Narrow phones: shrink the whole orbit so the labels keep a margin from the panel edge. */
@media (max-width: 420px) { .mu-orbit-stage { transform: scale(.88); } }

/* ---- number-ticker ---- */
.mu-ticker { display: inline-block; font-variant-numeric: tabular-nums; letter-spacing: .02em; }

/* ---- aurora-text: drifting warm gradient inside text ---- */
.mu-aurora-wrap { position: relative; display: inline-block; }
.mu-aurora { position: relative; display: inline-block; background-size: 200% auto; -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
    animation: mu-aurora 8s ease-in-out infinite alternate; }
@keyframes mu-aurora {
    0% { background-position: 0% 50%; } 25% { background-position: 50% 100%; } 50% { background-position: 100% 50%; }
    75% { background-position: 50% 0%; } 100% { background-position: 0% 50%; }
}

/* ---- shine-border: light travelling around the parent's edge ---- */
.mu-shine { position: absolute; inset: 0; pointer-events: none; border-radius: inherit; padding: var(--border-width, 1px);
    background-size: 300% 300%; will-change: background-position;
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor;
    mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); mask-composite: exclude;
    animation: mu-shine var(--duration, 14s) infinite linear; }
@keyframes mu-shine { 0% { background-position: 0% 0%; } 50% { background-position: 100% 100%; } to { background-position: 0% 0%; } }

/* ---- animated-shiny-text: occasional glare across text (base colour: --shiny-base) ---- */
.mu-shiny {
    background-image: linear-gradient(90deg, transparent, rgba(255, 255, 255, .95) 50%, transparent), linear-gradient(var(--shiny-base, currentColor), var(--shiny-base, currentColor));
    background-size: var(--shiny-width, 100px) 100%, 100% 100%; background-repeat: no-repeat;
    background-position: calc(-100% - var(--shiny-width, 100px)) 0, 0 0;
    -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;
    animation: mu-shiny 8s infinite;
}
@keyframes mu-shiny {
    0%, 90%, 100% { background-position: calc(-100% - var(--shiny-width, 100px)) 0, 0 0; }
    30%, 60% { background-position: calc(100% + var(--shiny-width, 100px)) 0, 0 0; }
}

/* ---- light-rays: warm sun rays swaying from above ---- */
.mu-rays { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.mu-rays > span { position: absolute; top: -12%; left: var(--ray-left); width: var(--ray-width); height: var(--light-rays-length, 70vh);
    transform-origin: top; transform: translateX(-50%) rotate(var(--ray-rotate)); border-radius: 999px; opacity: 0;
    background: linear-gradient(to bottom, var(--light-rays-color), transparent); mix-blend-mode: screen; filter: blur(var(--light-rays-blur, 36px));
    animation: mu-ray ease-in-out infinite; }
@keyframes mu-ray {
    0% { opacity: 0; transform: translateX(-50%) rotate(calc(var(--ray-rotate) - var(--ray-swing))); }
    50% { opacity: var(--ray-intensity); transform: translateX(-50%) rotate(calc(var(--ray-rotate) + var(--ray-swing))); }
    100% { opacity: 0; transform: translateX(-50%) rotate(calc(var(--ray-rotate) - var(--ray-swing))); }
}

/* ---- particles canvas ---- */
.mu-particles { position: absolute; inset: 0; pointer-events: none; }

/* Respect the OS "reduce motion" setting. */
@media (prefers-reduced-motion: reduce) {
    .mu-blur-fade, .mu-text-animate .mu-seg { opacity: 1 !important; filter: none !important; transform: none !important; animation: none !important; transition: none !important; }
    .mu-ripple > span, .mu-orbit-item, .mu-aurora, .mu-shine, .mu-shiny, .mu-rays > span { animation: none !important; }
    .mu-rays > span { opacity: .35; }
}
