/**
 * CSS Loader Templates for Custom Animated Preloader
 * Each template uses uniquely prefixed classes and keyframes.
 * Color is controlled via --swap-loader-color CSS custom property.
 */

/* === Template 1: Dot Reveal === */
.swap-tpl-1 {
    width: 60px;
    aspect-ratio: 4;
    background: radial-gradient(circle closest-side, var(--swap-loader-color, #fff) 90%, #0000) 0/calc(100%/3) 100% space;
    clip-path: inset(0 100% 0 0);
    animation: ct1 1s steps(4) infinite
}

@keyframes ct1 {
    to {
        clip-path: inset(0 -34% 0 0)
    }
}

/* === Template 2: Dancing Dots === */
.swap-tpl-2 {
    width: 60px;
    aspect-ratio: 2;
    --_g: no-repeat radial-gradient(circle closest-side, var(--swap-loader-color, #fff) 90%, #0000);
    background: var(--_g) 0% 50%, var(--_g) 50% 50%, var(--_g) 100% 50%;
    background-size: calc(100%/3) 50%;
    animation: ct2 1s infinite linear
}

@keyframes ct2 {
    20% {
        background-position: 0% 0%, 50% 50%, 100% 50%
    }

    40% {
        background-position: 0% 100%, 50% 0%, 100% 50%
    }

    60% {
        background-position: 0% 50%, 50% 100%, 100% 0%
    }

    80% {
        background-position: 0% 50%, 50% 50%, 100% 100%
    }
}

/* === Template 3: Dot Squeeze === */
.swap-tpl-3 {
    width: 60px;
    aspect-ratio: 4;
    --c: var(--swap-loader-color, #fff) 90%, #0000;
    background: radial-gradient(circle closest-side at left 6px top 50%, var(--c)), radial-gradient(circle closest-side, var(--c)), radial-gradient(circle closest-side at right 6px top 50%, var(--c));
    background-size: 100% 100%;
    background-repeat: no-repeat;
    animation: ct3 1s infinite alternate
}

@keyframes ct3 {
    to {
        width: 25px;
        aspect-ratio: 1
    }
}

/* === Template 4: Dot Orbit === */
.swap-tpl-4 {
    width: 15px;
    aspect-ratio: 1;
    position: relative
}

.swap-tpl-4::before,
.swap-tpl-4::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: var(--swap-loader-color, #fff)
}

.swap-tpl-4::before {
    box-shadow: -25px 0 var(--swap-loader-color, #fff);
    animation: ct4a 1s infinite linear
}

.swap-tpl-4::after {
    transform: rotate(0deg) translateX(25px);
    animation: ct4b 1s infinite linear
}

@keyframes ct4a {
    100% {
        transform: translateX(25px)
    }
}

@keyframes ct4b {
    100% {
        transform: rotate(-180deg) translateX(25px)
    }
}

/* === Template 5: Dot Wave === */
.swap-tpl-5 {
    color: var(--swap-loader-color, #fff);
    width: 4px;
    aspect-ratio: 1;
    border-radius: 50%;
    box-shadow: 19px 0 0 7px, 38px 0 0 3px, 57px 0 0 0;
    transform: translateX(-38px);
    animation: ct5 .5s infinite alternate linear
}

@keyframes ct5 {
    50% {
        box-shadow: 19px 0 0 3px, 38px 0 0 7px, 57px 0 0 3px
    }

    100% {
        box-shadow: 19px 0 0 0, 38px 0 0 3px, 57px 0 0 7px
    }
}

/* === Template 6: Dot Carousel === */
.swap-tpl-6 {
    --s: 15px;
    width: calc(var(--s)*2.33);
    aspect-ratio: 1;
    display: flex;
    justify-content: space-between;
    animation: ct6a 1s infinite
}

.swap-tpl-6::before,
.swap-tpl-6::after {
    content: "";
    width: var(--s);
    --_g: no-repeat radial-gradient(farthest-side, var(--swap-loader-color, #fff) 94%, #0000);
    background: var(--_g) top, var(--_g) bottom;
    background-size: 100% var(--s);
    transform-origin: 50% calc(100% - var(--s)/2);
    animation: inherit;
    animation-name: ct6b
}

.swap-tpl-6::after {
    --_s: -1
}

@keyframes ct6a {
    100% {
        transform: translateY(calc(var(--s) - 100%))
    }
}

@keyframes ct6b {
    100% {
        transform: rotate(calc(var(--_s, 1)*-180deg))
    }
}

/* === Template 7: Dot Exchange === */
.swap-tpl-7 {
    height: 15px;
    aspect-ratio: 4;
    --_g: no-repeat radial-gradient(farthest-side, var(--swap-loader-color, #fff) 90%, #0000);
    background: var(--_g) left, var(--_g) right;
    background-size: 25% 100%;
    display: grid
}

.swap-tpl-7::before,
.swap-tpl-7::after {
    content: "";
    height: inherit;
    aspect-ratio: 1;
    grid-area: 1/1;
    margin: auto;
    border-radius: 50%;
    transform-origin: -100% 50%;
    background: var(--swap-loader-color, #fff);
    animation: ct7 1s infinite linear
}

.swap-tpl-7::after {
    transform-origin: 200% 50%;
    --s: -1;
    animation-delay: -.5s
}

@keyframes ct7 {

    58%,
    100% {
        transform: rotate(calc(var(--s, 1)*1turn))
    }
}

/* === Template 8: Bar Bounce === */
.swap-tpl-8 {
    width: 45px;
    aspect-ratio: 1;
    --c: no-repeat linear-gradient(var(--swap-loader-color, #fff) 0 0);
    background: var(--c), var(--c), var(--c);
    animation: ct8a 1s infinite, ct8b 1s infinite
}

@keyframes ct8a {

    0%,
    100% {
        background-size: 20% 100%
    }

    33%,
    66% {
        background-size: 20% 40%
    }
}

@keyframes ct8b {

    0%,
    33% {
        background-position: 0 0, 50% 100%, 100% 0
    }

    66%,
    100% {
        background-position: 0 100%, 50% 0, 100% 100%
    }
}

/* === Template 9: Bar Cascade === */
.swap-tpl-9 {
    width: 45px;
    aspect-ratio: .75;
    --c: no-repeat linear-gradient(var(--swap-loader-color, #fff) 0 0);
    background: var(--c) 0% 50%, var(--c) 50% 50%, var(--c) 100% 50%;
    background-size: 20% 50%;
    animation: ct9 1s infinite linear
}

@keyframes ct9 {
    20% {
        background-position: 0% 0%, 50% 50%, 100% 50%
    }

    40% {
        background-position: 0% 100%, 50% 0%, 100% 50%
    }

    60% {
        background-position: 0% 50%, 50% 100%, 100% 0%
    }

    80% {
        background-position: 0% 50%, 50% 50%, 100% 100%
    }
}

/* === Template 10: Bar Matrix === */
.swap-tpl-10 {
    width: 45px;
    aspect-ratio: 1;
    --c: no-repeat linear-gradient(var(--swap-loader-color, #fff) 0 0);
    background: var(--c), var(--c), var(--c), var(--c), var(--c), var(--c);
    animation: ct10a .5s infinite alternate, ct10b 2s infinite
}

@keyframes ct10a {

    0%,
    10% {
        background-size: 20% 100%
    }

    100% {
        background-size: 20% 20%
    }
}

@keyframes ct10b {

    0%,
    49.9% {
        background-position: 0 0, 0 100%, 50% 50%, 50% 50%, 100% 0, 100% 100%
    }

    50%,
    100% {
        background-position: 0 50%, 0 50%, 50% 0, 50% 100%, 100% 50%, 100% 50%
    }
}

/* === Template 11: Bar Shuffle === */
.swap-tpl-11 {
    width: 45px;
    aspect-ratio: 1;
    --c: no-repeat linear-gradient(var(--swap-loader-color, #fff) 0 0);
    background: var(--c), var(--c), var(--c);
    animation: ct11a 1s infinite, ct11b 1s infinite
}

@keyframes ct11a {

    0%,
    100% {
        background-size: 20% 100%
    }

    33%,
    66% {
        background-size: 20% 40%
    }
}

@keyframes ct11b {

    0%,
    33% {
        background-position: 0 0, 50% 100%, 100% 100%
    }

    66%,
    100% {
        background-position: 100% 0, 0 100%, 50% 100%
    }
}

/* === Template 12: Walking Dots === */
.swap-tpl-12 {
    width: 40px;
    height: 20px;
    --c: no-repeat radial-gradient(farthest-side, var(--swap-loader-color, #fff) 93%, #0000);
    background: var(--c) 0 0, var(--c) 50% 0;
    background-size: 8px 8px;
    position: relative;
    clip-path: inset(-200% -100% 0 0);
    animation: ct12a 1.5s linear infinite
}

.swap-tpl-12::before {
    content: "";
    position: absolute;
    width: 8px;
    height: 12px;
    background: var(--swap-loader-color, #fff);
    left: -16px;
    top: 0;
    animation: ct12b 1.5s linear infinite, ct12c 0.5s cubic-bezier(0, 200, .8, 200) infinite
}

.swap-tpl-12::after {
    content: "";
    position: absolute;
    inset: 0 0 auto auto;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--swap-loader-color, #fff);
    animation: ct12d 1.5s linear infinite
}

@keyframes ct12a {

    0%,
    30% {
        background-position: 0 0, 50% 0
    }

    33% {
        background-position: 0 100%, 50% 0
    }

    41%,
    63% {
        background-position: 0 0, 50% 0
    }

    66% {
        background-position: 0 0, 50% 100%
    }

    74%,
    100% {
        background-position: 0 0, 50% 0
    }
}

@keyframes ct12b {
    90% {
        transform: translateY(0)
    }

    95% {
        transform: translateY(15px)
    }

    100% {
        transform: translateY(15px);
        left: calc(100% - 8px)
    }
}

@keyframes ct12c {
    100% {
        top: -0.1px
    }
}

@keyframes ct12d {

    0%,
    80%,
    100% {
        transform: translate(0)
    }

    90% {
        transform: translate(26px)
    }
}

/* === Template 13: Ring Spin === */
.swap-tpl-13 {
    width: 50px;
    aspect-ratio: 1;
    border-radius: 50%;
    border: 8px solid;
    border-color: var(--swap-loader-color, #fff) #0000;
    animation: ct13 1s infinite
}

@keyframes ct13 {
    to {
        transform: rotate(.5turn)
    }
}

/* === Template 14: Triangle Fold === */
.swap-tpl-14 {
    width: 40px;
    aspect-ratio: 1;
    background: #25b09b;
    clip-path: polygon(0 0, 100% 0, 100% 100%);
    animation: ct14 2s infinite cubic-bezier(0.3, 1, 0, 1)
}

@keyframes ct14 {
    25% {
        clip-path: polygon(0 0, 100% 0, 0 100%)
    }

    50% {
        clip-path: polygon(0 0, 100% 100%, 0 100%)
    }

    75% {
        clip-path: polygon(100% 0, 100% 100%, 0 100%)
    }

    100% {
        clip-path: polygon(100% 0, 100% 100%, 0 0)
    }
}

/* === Template 15: Diamond Pulse === */
.swap-tpl-15 {
    width: 40px;
    aspect-ratio: 1;
    color: #f03355;
    position: relative;
    background: conic-gradient(from 134deg at top, currentColor 92deg, #0000 0) top, conic-gradient(from -46deg at bottom, currentColor 92deg, #0000 0) bottom;
    background-size: 100% 50%;
    background-repeat: no-repeat
}

.swap-tpl-15::before {
    content: '';
    position: absolute;
    inset: 0;
    --g: currentColor 14.5px, #0000 0 calc(100% - 14.5px), currentColor 0;
    background: linear-gradient(45deg, var(--g)), linear-gradient(-45deg, var(--g));
    animation: ct15 1.5s infinite cubic-bezier(0.3, 1, 0, 1)
}

@keyframes ct15 {
    33% {
        inset: -10px;
        transform: rotate(0deg)
    }

    66% {
        inset: -10px;
        transform: rotate(90deg)
    }

    100% {
        inset: 0;
        transform: rotate(90deg)
    }
}

/* === Template 16: Box Fold === */
.swap-tpl-16 {
    width: 40px;
    height: 20px;
    background: orange;
    position: relative;
    animation: ct16a 1.5s infinite linear
}

.swap-tpl-16::before,
.swap-tpl-16::after {
    content: "";
    position: absolute;
    background: inherit;
    bottom: 100%;
    width: 50%;
    height: 100%;
    animation: inherit;
    animation-name: ct16b
}

.swap-tpl-16::before {
    left: 0;
    transform-origin: bottom left;
    --s: -1
}

.swap-tpl-16::after {
    right: 0;
    transform-origin: bottom right
}

@keyframes ct16a {

    0%,
    10% {
        transform: translateY(0%) scaleY(1)
    }

    49.99% {
        transform: translateY(-50%) scaleY(1)
    }

    50% {
        transform: translateY(-50%) scaleY(-1)
    }

    90%,
    100% {
        transform: translateY(-100%) scaleY(-1)
    }
}

@keyframes ct16b {

    10%,
    90% {
        transform: rotate(0deg)
    }

    50% {
        transform: rotate(calc(var(--s, 1)*180deg))
    }
}

/* === Template 17: Pinwheel === */
.swap-tpl-17 {
    width: 40px;
    height: 40px;
    color: #f03355;
    background: conic-gradient(from -45deg at top 20px left 50%, #0000, currentColor 1deg 90deg, #0000 91deg), conic-gradient(from 45deg at right 20px top 50%, #0000, currentColor 1deg 90deg, #0000 91deg), conic-gradient(from 135deg at bottom 20px left 50%, #0000, currentColor 1deg 90deg, #0000 91deg), conic-gradient(from -135deg at left 20px top 50%, #0000, currentColor 1deg 90deg, #0000 91deg);
    animation: ct17 1.5s infinite cubic-bezier(0.3, 1, 0, 1)
}

@keyframes ct17 {
    50% {
        width: 60px;
        height: 60px;
        transform: rotate(180deg)
    }

    100% {
        transform: rotate(360deg)
    }
}

/* === Template 18: Triangle Dance === */
.swap-tpl-18 {
    width: 40px;
    aspect-ratio: 1;
    display: grid
}

.swap-tpl-18::before,
.swap-tpl-18::after {
    content: "";
    grid-area: 1/1;
    background: orange;
    clip-path: polygon(0 0, 101% 0, 0 100%);
    animation: ct18 2s infinite
}

.swap-tpl-18::after {
    --s: -1, -1
}

@keyframes ct18 {

    0%,
    10% {
        transform: scale(var(--s, 1)) translate(0, 0) rotate(0deg)
    }

    33% {
        transform: scale(var(--s, 1)) translate(20px, -20px) rotate(0deg)
    }

    66% {
        transform: scale(var(--s, 1)) translate(20px, -20px) rotate(180deg)
    }

    90%,
    100% {
        transform: scale(var(--s, 1)) translate(0px, 0px) rotate(180deg)
    }
}

/* === Template 19: Block Progress === */
.swap-tpl-19 {
    width: 90px;
    height: 14px;
    background: repeating-linear-gradient(90deg, var(--swap-loader-color, #fff) 0 calc(25% - 5px), #0000 0 25%) left/calc(4*100%/3) 100%;
    animation: ct19 0.5s infinite linear
}

@keyframes ct19 {
    100% {
        background-position: right
    }
}

/* === Template 20: Dot Progress === */
.swap-tpl-20 {
    width: 90px;
    height: 14px;
    background: radial-gradient(circle closest-side, var(--swap-loader-color, #fff) 92%, #0000) calc(100%/3) 0/calc(100%/4) 100%;
    animation: ct20 0.5s infinite linear
}

@keyframes ct20 {
    100% {
        background-position: 0 0
    }
}

/* === Template 21: Dot Bounce Wave === */
.swap-tpl-21 {
    width: 90px;
    height: 14px;
    --c: var(--swap-loader-color, #fff) 92%, #0000;
    background: radial-gradient(circle closest-side, var(--c)) calc(100%/-4) 0, radial-gradient(circle closest-side, var(--c)) calc(100%/4) 0;
    background-size: calc(100%/2) 100%;
    animation: ct21 1.5s infinite
}

@keyframes ct21 {
    0% {
        background-position: calc(100%/-4) 0, calc(100%/4) 0
    }

    50% {
        background-position: calc(100%/-4) -14px, calc(100%/4) 14px
    }

    100% {
        background-position: calc(100%/4) -14px, calc(3*100%/4) 14px
    }
}

/* === Template 22: Dot Zigzag === */
.swap-tpl-22 {
    width: 90px;
    height: 14px;
    --c: var(--swap-loader-color, #fff) 92%, #0000;
    background: radial-gradient(circle 7px at bottom, var(--c)) 0 0, radial-gradient(circle 7px at top, var(--c)) 0 100%;
    background-size: calc(100%/4) 50%;
    background-repeat: repeat-x;
    animation: ct22 1s infinite
}

@keyframes ct22 {

    80%,
    100% {
        background-position: calc(100%/3) 0, calc(100%/-3) 100%
    }
}

/* === Template 23: Conic Zigzag === */
.swap-tpl-23 {
    width: 90px;
    height: 14px;
    --c: var(--swap-loader-color, #fff) 90deg, #0000 0;
    background: conic-gradient(from 135deg at top, var(--c)) 0 0, conic-gradient(from -45deg at bottom, var(--c)) 0 100%;
    background-size: calc(100%/4) 50%;
    background-repeat: repeat-x;
    animation: ct23 1s infinite
}

@keyframes ct23 {

    80%,
    100% {
        background-position: calc(100%/3) 0, calc(100%/-3) 100%
    }
}

/* === Template 24: Ball Bounce === */
.swap-tpl-24 {
    height: 60px;
    aspect-ratio: 2;
    position: relative
}

.swap-tpl-24::before {
    content: "";
    position: absolute;
    inset: 100% 75% -3px 0;
    background: #524656;
    animation: ct24a 1s linear infinite alternate
}

.swap-tpl-24::after {
    content: "";
    position: absolute;
    inset: auto 42.5% 0;
    aspect-ratio: 1;
    border-radius: 50%;
    background: #CF4647;
    animation: ct24b 1s cubic-bezier(0, 700, 1, 700) infinite alternate, ct24c 1s linear infinite alternate
}

@keyframes ct24a {

    0%,
    30% {
        translate: 0% -2px;
        rotate: 20deg
    }

    70%,
    to {
        translate: 300% -2px;
        rotate: -20deg
    }
}

@keyframes ct24b {

    0%,
    2% {
        bottom: 0%
    }

    98%,
    to {
        bottom: .1%
    }
}

@keyframes ct24c {
    0% {
        translate: -220%
    }

    to {
        translate: 220%
    }
}

/* === Template 25: Glow Ring === */
.swap-tpl-25 {
    height: 60px;
    aspect-ratio: 1;
    padding: 8px;
    border-radius: 50%;
    box-sizing: border-box;
    position: relative;
    mask: conic-gradient(#000 0 0) content-box exclude, conic-gradient(#000 0 0);
    filter: blur(8px)
}

.swap-tpl-25::before {
    content: "";
    position: absolute;
    inset: 0;
    background: conic-gradient(#0000 35%, #C02942, #0000 65%);
    animation: ct25 1.5s linear infinite
}

@keyframes ct25 {
    to {
        rotate: 1turn
    }
}

/* === Template 26: Dual Glow Ring === */
.swap-tpl-26 {
    height: 60px;
    aspect-ratio: 1;
    padding: 8px;
    border-radius: 50%;
    box-sizing: border-box;
    position: relative;
    mask: conic-gradient(#000 0 0) content-box exclude, conic-gradient(#000 0 0);
    filter: blur(8px)
}

.swap-tpl-26::before {
    content: "";
    position: absolute;
    inset: 0;
    background: repeating-conic-gradient(#0000 0 5%, #C02942, #0000 20% 50%);
    animation: ct26 1.5s linear infinite
}

@keyframes ct26 {
    to {
        rotate: 1turn
    }
}

/* === Template 27: 3D Cube === */
.swap-tpl-27 {
    width: 50px;
    aspect-ratio: 1;
    display: grid;
    grid: 50%/50%;
    color: #25b09b;
    --_g: no-repeat linear-gradient(currentColor 0 0);
    background: var(--_g), var(--_g), var(--_g);
    background-size: 50.1% 50.1%;
    animation: ct27a 1.5s infinite steps(1) alternate, ct27b 3s infinite steps(1)
}

.swap-tpl-27::before {
    content: "";
    background: currentColor;
    transform: perspective(150px) rotateY(0deg) rotateX(0deg);
    transform-origin: bottom right;
    animation: ct27c 1.5s infinite linear alternate
}

@keyframes ct27a {
    0% {
        background-position: 0 100%, 100% 100%, 100% 0
    }

    33% {
        background-position: 100% 100%, 100% 100%, 100% 0
    }

    66% {
        background-position: 100% 0, 100% 0, 100% 0
    }
}

@keyframes ct27b {
    0% {
        transform: scaleX(1) rotate(0deg)
    }

    50% {
        transform: scaleX(-1) rotate(-90deg)
    }
}

@keyframes ct27c {
    16.5% {
        transform: perspective(150px) rotateX(-90deg) rotateY(0deg) rotateX(0deg);
        filter: grayscale(0.8)
    }

    33% {
        transform: perspective(150px) rotateX(-180deg) rotateY(0deg) rotateX(0deg)
    }

    66% {
        transform: perspective(150px) rotateX(-180deg) rotateY(-180deg) rotateX(0deg)
    }

    100% {
        transform: perspective(150px) rotateX(-180deg) rotateY(-180deg) rotateX(-180deg);
        filter: grayscale(0.8)
    }
}

/* === Template 28: Circle Pulse === */
.swap-tpl-28 {
    height: 50px;
    aspect-ratio: 1.5;
    display: flex;
    gap: 8px
}

.swap-tpl-28::before,
.swap-tpl-28::after {
    content: "";
    border: 6px solid #BD1550;
    border-radius: 50%;
    box-sizing: content-box;
    margin: auto;
    aspect-ratio: 1;
    animation: ct28 infinite 1s steps(4, jump-none)
}

.swap-tpl-28::after {
    animation-direction: reverse
}

@keyframes ct28 {
    0% {
        width: 0%
    }

    to {
        width: 75%
    }
}

/* === Template 29: Bar Slide === */
.swap-tpl-29 {
    width: 100px;
    height: 16px;
    -webkit-mask: linear-gradient(90deg, #000 70%, #0000 0) left/20% 100%;
    background: linear-gradient(var(--swap-loader-color, #fff) 0 0) left -25% top 0/20% 100% no-repeat #555;
    animation: ct29 1s infinite steps(6)
}

@keyframes ct29 {
    100% {
        background-position: right -25% top 0
    }
}

/* === Template 30: Ripple === */
.swap-tpl-30 {
    width: 20px;
    aspect-ratio: 1;
    border-radius: 50%;
    background: var(--swap-loader-color, #fff);
    box-shadow: 0 0 0 0 #fff4;
    animation: ct30 1s infinite
}

@keyframes ct30 {
    100% {
        box-shadow: 0 0 0 30px #0000
    }
}

/* === Template 31: Triple Ripple === */
.swap-tpl-31 {
    width: 20px;
    aspect-ratio: 1;
    border-radius: 50%;
    background: var(--swap-loader-color, #fff);
    box-shadow: 0 0 0 0 #fff4;
    animation: ct31 1.5s infinite linear;
    position: relative
}

.swap-tpl-31::before,
.swap-tpl-31::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    box-shadow: 0 0 0 0 #fff4;
    animation: inherit;
    animation-delay: -0.5s
}

.swap-tpl-31::after {
    animation-delay: -1s
}

@keyframes ct31 {
    100% {
        box-shadow: 0 0 0 40px #0000
    }
}

/* === Template 32: Pac-Man === */
.swap-tpl-32 {
    width: 80px;
    height: 20px;
    padding: 2px 0;
    box-sizing: border-box;
    display: flex;
    animation: ct32a 3s infinite steps(6);
    background: linear-gradient(var(--swap-loader-color, #fff) 0 0) 0 0/0% 100% no-repeat, radial-gradient(circle 3px, #eeee89 90%, #0000) 0 0/20% 100% #333;
    overflow: hidden
}

.swap-tpl-32::before {
    content: "";
    width: 20px;
    transform: translate(-100%);
    border-radius: 50%;
    background: #ffff2d;
    animation: ct32b .25s .153s infinite steps(5) alternate, ct32c 3s infinite linear
}

@keyframes ct32a {
    100% {
        background-size: 120% 100%, 20% 100%
    }
}

@keyframes ct32b {
    0% {
        clip-path: polygon(50% 50%, 100% 0, 100% 0, 0 0, 0 100%, 100% 100%, 100% 100%)
    }

    100% {
        clip-path: polygon(50% 50%, 100% 65%, 100% 0, 0 0, 0 100%, 100% 100%, 100% 35%)
    }
}

@keyframes ct32c {
    100% {
        transform: translate(80px)
    }
}

/* === Template 33: Gyroscope === */
.swap-tpl-33 {
    width: 40px;
    aspect-ratio: 1;
    border-radius: 50%;
    color: var(--swap-loader-color, #fff);
    border: 2px solid;
    box-sizing: border-box;
    position: relative;
    transform-origin: left;
    animation: ct33 1s infinite linear
}

.swap-tpl-33::before,
.swap-tpl-33::after {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    margin: auto;
    width: 50%;
    aspect-ratio: 1;
    border-radius: 50%;
    border: 2px solid;
    box-sizing: content-box;
    transform-origin: 50% calc(100% - 4px);
    animation: inherit
}

.swap-tpl-33::after {
    inset: auto 0 calc(100% + 2px);
    animation-duration: 0.5s;
    animation-direction: reverse;
    transform-origin: 50% calc(200% - 2px)
}

@keyframes ct33 {
    100% {
        transform: rotate(1turn)
    }
}

/* === Template 34: Puzzle Conic === */
.swap-tpl-34 {
    width: 50px;
    aspect-ratio: 1;
    --g1: conic-gradient(from 90deg at 3px 3px, #0000 90deg, var(--swap-loader-color, #fff) 0);
    --g2: conic-gradient(from -90deg at 22px 22px, #0000 90deg, var(--swap-loader-color, #fff) 0);
    background: var(--g1), var(--g1), var(--g1), var(--g2), var(--g2), var(--g2);
    background-size: 25px 25px;
    background-repeat: no-repeat;
    animation: ct34 1.5s infinite
}

@keyframes ct34 {
    0% {
        background-position: 0 0, 0 100%, 100% 100%
    }

    25% {
        background-position: 100% 0, 0 100%, 100% 100%
    }

    50% {
        background-position: 100% 0, 0 0, 100% 100%
    }

    75% {
        background-position: 100% 0, 0 0, 0 100%
    }

    100% {
        background-position: 100% 100%, 0 0, 0 100%
    }
}

/* === Template 35: Puzzle Bars === */
.swap-tpl-35 {
    width: 75px;
    height: 25px;
    --g1: conic-gradient(from 90deg at left 3px top 3px, #0000 90deg, var(--swap-loader-color, #fff) 0);
    --g2: conic-gradient(from -90deg at bottom 3px right 3px, #0000 90deg, var(--swap-loader-color, #fff) 0);
    background: var(--g1), var(--g1), var(--g1), var(--g2), var(--g2), var(--g2);
    background-position: left, center, right;
    background-repeat: no-repeat;
    animation: ct35 1s infinite
}

@keyframes ct35 {
    0% {
        background-size: 25px 100%, 25px 100%, 25px 100%
    }

    20% {
        background-size: 25px 50%, 25px 100%, 25px 100%
    }

    40% {
        background-size: 25px 50%, 25px 50%, 25px 100%
    }

    60% {
        background-size: 25px 100%, 25px 50%, 25px 50%
    }

    80% {
        background-size: 25px 100%, 25px 100%, 25px 50%
    }

    100% {
        background-size: 25px 100%, 25px 100%, 25px 100%
    }
}

/* === Template 36: Puzzle Bars Tall === */
.swap-tpl-36 {
    width: 75px;
    height: 45px;
    --g1: conic-gradient(from 90deg at left 3px top 3px, #0000 90deg, var(--swap-loader-color, #fff) 0);
    --g2: conic-gradient(from -90deg at bottom 3px right 3px, #0000 90deg, var(--swap-loader-color, #fff) 0);
    background: var(--g1), var(--g1), var(--g1), var(--g2), var(--g2), var(--g2);
    background-position: left, center, right;
    background-repeat: no-repeat;
    animation: ct36 1s infinite
}

@keyframes ct36 {
    0% {
        background-size: 25px 50%, 25px 50%, 25px 50%
    }

    25% {
        background-size: 25px 100%, 25px 50%, 25px 50%
    }

    50% {
        background-size: 25px 50%, 25px 100%, 25px 50%
    }

    75% {
        background-size: 25px 50%, 25px 50%, 25px 100%
    }

    100% {
        background-size: 25px 50%, 25px 50%, 25px 50%
    }
}

/* === Template 37: Puzzle Wave === */
.swap-tpl-37 {
    width: 75px;
    height: 45px;
    --g1: conic-gradient(from 90deg at left 3px top 3px, #0000 90deg, var(--swap-loader-color, #fff) 0);
    --g2: conic-gradient(from -90deg at bottom 3px right 3px, #0000 90deg, var(--swap-loader-color, #fff) 0);
    background: var(--g1), var(--g1), var(--g1), var(--g2), var(--g2), var(--g2);
    background-position: left, center, right;
    background-repeat: no-repeat;
    animation: ct37 1s infinite alternate
}

@keyframes ct37 {

    0%,
    2% {
        background-size: 25px 50%, 25px 50%, 25px 50%
    }

    20% {
        background-size: 25px 25%, 25px 50%, 25px 50%
    }

    40% {
        background-size: 25px 100%, 25px 25%, 25px 50%
    }

    60% {
        background-size: 25px 50%, 25px 100%, 25px 25%
    }

    80% {
        background-size: 25px 50%, 25px 50%, 25px 100%
    }

    98%,
    100% {
        background-size: 25px 50%, 25px 50%, 25px 50%
    }
}

/* === Template 38: Pill Toggle === */
.swap-tpl-38 {
    width: 65px;
    height: 30px;
    position: relative
}

.swap-tpl-38::before {
    content: "";
    position: absolute;
    border-radius: 50px;
    box-shadow: 0 0 0 3px inset var(--swap-loader-color, #fff);
    animation: ct38 0.75s infinite alternate
}

@keyframes ct38 {
    0% {
        inset: 0 35px 0 0
    }

    50% {
        inset: 0 0 0 0
    }

    100% {
        inset: 0 0 0 35px
    }
}

/* === Template 39: Ring Orbit === */
.swap-tpl-39 {
    width: 55px;
    aspect-ratio: 1;
    --g: radial-gradient(farthest-side, #0000 calc(95% - 3px), var(--swap-loader-color, #fff) calc(100% - 3px) 98%, #0000 101%) no-repeat;
    background: var(--g), var(--g), var(--g);
    background-size: 30px 30px;
    animation: ct39 1.5s infinite
}

@keyframes ct39 {
    0% {
        background-position: 0 0, 0 100%, 100% 100%
    }

    25% {
        background-position: 100% 0, 0 100%, 100% 100%
    }

    50% {
        background-position: 100% 0, 0 0, 100% 100%
    }

    75% {
        background-position: 100% 0, 0 0, 0 100%
    }

    100% {
        background-position: 100% 100%, 0 0, 0 100%
    }
}

/* === Template 40: Block Chase === */
.swap-tpl-40 {
    width: 16px;
    aspect-ratio: 1;
    background: #3FB8AF;
    box-shadow: 30px 0 #FF3D7F;
    animation: ct40a 1s infinite alternate, ct40b .5s infinite alternate
}

@keyframes ct40a {

    0%,
    40% {
        transform: rotate(0)
    }

    80%,
    100% {
        transform: rotate(.5turn)
    }
}

@keyframes ct40b {

    80%,
    100% {
        box-shadow: 16px 0 #FF3D7F
    }
}

/* === Template 41: Block Flip === */
.swap-tpl-41 {
    width: 16px;
    aspect-ratio: 1;
    background: #3FB8AF;
    position: relative;
    animation: ct41a 2.5s infinite linear alternate
}

.swap-tpl-41::before {
    content: "";
    position: absolute;
    inset: 0;
    background: #FF3D7F;
    transform: translate(100%);
    transform-origin: top left;
    animation: ct41b .5s infinite alternate
}

@keyframes ct41a {

    0%,
    19.9%,
    80%,
    100% {
        transform: scale(1, 1)
    }

    20%,
    39.9% {
        transform: scale(-1, 1)
    }

    40%,
    59.9% {
        transform: scale(-1, -1)
    }

    60%,
    79.9% {
        transform: scale(1, -1)
    }
}

@keyframes ct41b {

    0%,
    20% {
        transform: translate(100%) rotate(0)
    }

    80%,
    100% {
        transform: translate(100%) rotate(-180deg)
    }
}

/* === Template 42: Grid Trail === */
.swap-tpl-42 {
    height: 50px;
    aspect-ratio: 1;
    --c: no-repeat linear-gradient(var(--swap-loader-color, #fff) 0 0);
    background: var(--c), var(--c), var(--c), var(--c);
    background-size: 33.4% 33.4%;
    animation: ct42 2s infinite linear
}

@keyframes ct42 {
    0% {
        background-position: 0 0, 50% 0, 0 50%, 50% 50%
    }

    12.5% {
        background-position: 50% 0, 100% 0, 0 50%, 50% 50%
    }

    25% {
        background-position: 50% 0, 100% 0, 50% 50%, 100% 50%
    }

    37.5% {
        background-position: 50% 0, 100% 50%, 50% 50%, 100% 100%
    }

    50% {
        background-position: 50% 50%, 100% 50%, 50% 100%, 100% 100%
    }

    62.5% {
        background-position: 50% 50%, 100% 50%, 0 100%, 50% 100%
    }

    75% {
        background-position: 0 50%, 50% 50%, 0 100%, 50% 100%
    }

    87.5% {
        background-position: 0 0, 50% 50%, 0 50%, 50% 100%
    }

    100% {
        background-position: 0 0, 50% 0, 0 50%, 50% 50%
    }
}

/* === Template 43: Eyes Blink === */
.swap-tpl-43 {
    display: inline-flex;
    gap: 10px
}

.swap-tpl-43::before,
.swap-tpl-43::after {
    content: "";
    height: 20px;
    aspect-ratio: 1;
    border-radius: 50%;
    background: linear-gradient(#222 0 0) top/100% 40% no-repeat, radial-gradient(farthest-side, #000 95%, #0000) 50%/8px 8px no-repeat var(--swap-loader-color, #fff);
    animation: ct43 1.5s infinite alternate ease-in
}

@keyframes ct43 {

    0%,
    70% {
        background-size: 100% 40%, 8px 8px
    }

    85% {
        background-size: 100% 120%, 8px 8px
    }

    100% {
        background-size: 100% 40%, 8px 8px
    }
}

/* === Template 44: Eyes Look === */
.swap-tpl-44 {
    display: inline-flex;
    gap: 10px
}

.swap-tpl-44::before,
.swap-tpl-44::after {
    content: "";
    height: 20px;
    aspect-ratio: 1;
    border-radius: 50%;
    background: linear-gradient(#222 0 0) top/100% 40% no-repeat, radial-gradient(farthest-side, #000 95%, #0000) 50%/8px 8px no-repeat var(--swap-loader-color, #fff);
    animation: 2.5s infinite;
    animation-name: ct44a, ct44b
}

@keyframes ct44a {

    0%,
    40%,
    100% {
        background-size: 100% 40%, 8px 8px
    }

    50%,
    80% {
        background-size: 100% 0%, 8px 8px
    }
}

@keyframes ct44b {

    0%,
    50% {
        background-position: top, 50% 50%
    }

    60%,
    65% {
        background-position: top, 70% 50%
    }

    70%,
    75% {
        background-position: top, 30% 50%
    }

    90%,
    100% {
        background-position: top, 50% 50%
    }
}

/* === Template 45: Eyes Spin === */
.swap-tpl-45 {
    display: inline-flex;
    gap: 10px
}

.swap-tpl-45::before,
.swap-tpl-45::after {
    content: "";
    height: 20px;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(farthest-side, #000 95%, #0000) 35% 35%/6px 6px no-repeat var(--swap-loader-color, #fff);
    transform: scaleX(var(--s, 1)) rotate(0deg);
    animation: ct45 1s infinite linear
}

.swap-tpl-45::after {
    --s: -1;
    animation-delay: -0.1s
}

@keyframes ct45 {
    100% {
        transform: scaleX(var(--s, 1)) rotate(360deg)
    }
}

/* === Template 46: Square Draw === */
.swap-tpl-46 {
    width: 35px;
    aspect-ratio: 1;
    --c: no-repeat linear-gradient(#046D8B 0 0);
    background: var(--c) 0 0, var(--c) 100% 0, var(--c) 100% 100%, var(--c) 0 100%;
    animation: ct46 1s infinite alternate
}

@keyframes ct46 {
    0% {
        background-size: 0 4px, 4px 0, 0 4px, 4px 0
    }

    25% {
        background-size: 100% 4px, 4px 0, 0 4px, 4px 0
    }

    50% {
        background-size: 100% 4px, 4px 100%, 0 4px, 4px 0
    }

    75% {
        background-size: 100% 4px, 4px 100%, 100% 4px, 4px 0
    }

    90%,
    100% {
        background-size: 100% 4px, 4px 100%, 100% 4px, 4px 100%
    }
}

/* === Template 47: Grid Chain === */
.swap-tpl-47 {
    width: 50px;
    height: 20px;
    display: grid;
    color: #046D8B
}

.swap-tpl-47::before,
.swap-tpl-47::after {
    content: "";
    grid-area: 1/1;
    --c: #0000 calc(100%/3), #046D8B 0 calc(2*100%/3), #0000 0;
    --c1: linear-gradient(90deg, var(--c));
    --c2: linear-gradient(0deg, var(--c));
    background: var(--c1), var(--c2), var(--c1), var(--c2);
    background-size: 300% 4px, 4px 300%;
    background-repeat: no-repeat;
    animation: ct47 1.5s infinite
}

.swap-tpl-47::after {
    animation-delay: -.75s
}

@keyframes ct47 {
    0% {
        background-position: 50% 0, 100% 100%, 0 100%, 0 0
    }

    25% {
        background-position: 0 0, 100% 50%, 0 100%, 0 0
    }

    50% {
        background-position: 0 0, 100% 0, 50% 100%, 0 0
    }

    75% {
        background-position: 0 0, 100% 0, 100% 100%, 0 50%
    }

    75.01% {
        background-position: 100% 0, 100% 0, 100% 100%, 0 50%
    }

    100% {
        background-position: 50% 0, 100% 0, 100% 100%, 0 100%
    }
}

/* === Template 48: Snake Trail === */
.swap-tpl-48 {
    width: 90px;
    height: 14px;
    box-shadow: 0 3px 0 var(--swap-loader-color, #fff);
    position: relative;
    clip-path: inset(-40px 0 -5px)
}

.swap-tpl-48::before {
    content: "";
    position: absolute;
    inset: auto calc(50% - 17px) 0;
    height: 50px;
    --g: no-repeat linear-gradient(#ccc 0 0);
    background: var(--g), var(--g), var(--g), var(--g);
    background-size: 16px 14px;
    animation: ct48a 2s infinite linear, ct48b 2s infinite linear
}

@keyframes ct48a {

    0%,
    100% {
        background-position: 0 -50px, 100% -50px
    }

    17.5% {
        background-position: 0 100%, 100% -50px, 0 -50px, 100% -50px
    }

    35% {
        background-position: 0 100%, 100% 100%, 0 -50px, 100% -50px
    }

    52.5% {
        background-position: 0 100%, 100% 100%, 0 calc(100% - 16px), 100% -50px
    }

    70%,
    98% {
        background-position: 0 100%, 100% 100%, 0 calc(100% - 16px), 100% calc(100% - 16px)
    }
}

@keyframes ct48b {

    0%,
    70% {
        transform: translate(0)
    }

    100% {
        transform: translate(200%)
    }
}

/* === Template 49: Triple Bounce === */
.swap-tpl-49 {
    width: 25px;
    aspect-ratio: 1;
    background: #60B99A;
    animation: ct49 1.5s infinite
}

@keyframes ct49 {

    0%,
    100% {
        transform: translate(-30px, -30px);
        box-shadow: 0 0 #F77825, 0 0 #554236
    }

    40% {
        transform: translate(30px, 30px);
        box-shadow: -10px -10px #F77825, -20px -20px #554236
    }

    50% {
        transform: translate(30px, 30px);
        box-shadow: 0 0 #F77825, 0 0 #554236
    }

    90% {
        transform: translate(-30px, -30px);
        box-shadow: 10px 10px #F77825, 20px 20px #554236
    }
}

/* === Template 50: Triple Wave === */
.swap-tpl-50 {
    width: 28px;
    aspect-ratio: 1;
    border-radius: 50%;
    background: #F10C49;
    animation: ct50 1.5s infinite
}

@keyframes ct50 {

    0%,
    100% {
        transform: translate(-35px);
        box-shadow: 0 0 #F4DD51, 0 0 #E3AAD6
    }

    40% {
        transform: translate(35px);
        box-shadow: -15px 0 #F4DD51, -30px 0 #E3AAD6
    }

    50% {
        transform: translate(35px);
        box-shadow: 0 0 #F4DD51, 0 0 #E3AAD6
    }

    90% {
        transform: translate(-35px);
        box-shadow: 15px 0 #F4DD51, 30px 0 #E3AAD6
    }
}

/* === Template 51: Triple Origin === */
.swap-tpl-51 {
    width: 28px;
    aspect-ratio: 1;
    border-radius: 50%;
    background: #E3AAD6;
    transform-origin: top;
    display: grid;
    animation: ct51a 1s infinite linear
}

.swap-tpl-51::before,
.swap-tpl-51::after {
    content: "";
    grid-area: 1/1;
    background: #F4DD51;
    border-radius: 50%;
    transform-origin: top;
    animation: inherit;
    animation-name: ct51b
}

.swap-tpl-51::after {
    background: #F10C49;
    --s: 180deg
}

@keyframes ct51a {

    0%,
    20% {
        transform: rotate(0)
    }

    100% {
        transform: rotate(360deg)
    }
}

@keyframes ct51b {
    50% {
        transform: rotate(var(--s, 90deg))
    }

    100% {
        transform: rotate(0)
    }
}

/* === Template 52: Dot Spiral === */
.swap-tpl-52 {
    width: 22px;
    aspect-ratio: 1;
    border-radius: 50%;
    background: #F10C49;
    animation: ct52 1.5s infinite linear
}

@keyframes ct52 {
    0% {
        box-shadow: 0 -30px #F4DD51, calc(30px*0.707) calc(-30px*0.707) #E3AAD6, 30px 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6
    }

    12.5% {
        box-shadow: 0 0 #F4DD51, calc(30px*0.707) calc(-30px*0.707) #E3AAD6, 30px 0 #F4DD51, calc(30px*0.707) calc(30px*0.707) #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6
    }

    25% {
        box-shadow: 0 0 #F4DD51, 0 0 #E3AAD6, 30px 0 #F4DD51, calc(30px*0.707) calc(30px*0.707) #E3AAD6, 0 30px #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6
    }

    37.5% {
        box-shadow: 0 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, calc(30px*0.707) calc(30px*0.707) #E3AAD6, 0 30px #F4DD51, calc(-30px*0.707) calc(30px*0.707) #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6
    }

    50% {
        box-shadow: 0 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6, 0 30px #F4DD51, calc(-30px*0.707) calc(30px*0.707) #E3AAD6, -30px 0 #F4DD51, 0 0 #E3AAD6
    }

    62.5% {
        box-shadow: 0 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, calc(-30px*0.707) calc(30px*0.707) #E3AAD6, -30px 0 #F4DD51, calc(-30px*0.707) calc(-30px*0.707) #E3AAD6
    }

    75% {
        box-shadow: 0 -30px #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6, -30px 0 #F4DD51, calc(-30px*0.707) calc(-30px*0.707) #E3AAD6
    }

    87.5% {
        box-shadow: 0 -30px #F4DD51, calc(30px*0.707) calc(-30px*0.707) #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, calc(-30px*0.707) calc(-30px*0.707) #E3AAD6
    }

    100% {
        box-shadow: 0 -30px #F4DD51, calc(30px*0.707) calc(-30px*0.707) #E3AAD6, 30px 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6, 0 0 #F4DD51, 0 0 #E3AAD6
    }
}

/* === Template 53: Triangle Spin === */
.swap-tpl-53 {
    height: 40px;
    aspect-ratio: .866;
    display: grid;
    background: conic-gradient(from -121deg at right, #0000, #BF1E62 1deg 60deg, #0000 61deg);
    animation: ct53 2s infinite linear;
    transform-origin: 33% 50%
}

.swap-tpl-53::before,
.swap-tpl-53::after {
    content: "";
    grid-area: 1/1;
    background: conic-gradient(from -121deg at right, #0000, #FFA588 1deg 60deg, #0000 61deg);
    transform-origin: inherit;
    animation: inherit
}

.swap-tpl-53::after {
    background: conic-gradient(from -121deg at right, #0000, #027B7F 1deg 60deg, #0000 61deg);
    animation-duration: 3s
}

@keyframes ct53 {
    100% {
        transform: rotate(1turn)
    }
}

/* === Template 54: Cross Burst === */
.swap-tpl-54 {
    width: 50px;
    aspect-ratio: 1;
    background: linear-gradient(#60B99A 0 0) calc(1*100%/3) 50%/25% 50%, linear-gradient(#60B99A 0 0) calc(2*100%/3) 50%/25% 50%, linear-gradient(#f77825 0 0) 50% calc(1*100%/3)/50% 25%, linear-gradient(#f77825 0 0) 50% calc(2*100%/3)/50% 25%, linear-gradient(#554236 0 0) calc(1*100%/3) calc(1*100%/3)/25% 25%, linear-gradient(#554236 0 0) calc(2*100%/3) calc(1*100%/3)/25% 25%, linear-gradient(#554236 0 0) calc(1*100%/3) calc(2*100%/3)/25% 25%, linear-gradient(#554236 0 0) calc(2*100%/3) calc(2*100%/3)/25% 25%;
    background-repeat: no-repeat;
    animation: ct54 1s infinite alternate
}

@keyframes ct54 {

    90%,
    100% {
        background-position: 0 50%, 100% 50%, 50% 0, 50% 100%, 0 0, 100% 0, 0 100%, 100% 100%
    }
}

/* === Template 55: Blob Morph === */
.swap-tpl-55 {
    width: 50px;
    aspect-ratio: 1;
    background: #006cff;
    border-radius: 50%;
    animation: ct55 3s infinite linear
}

@keyframes ct55 {
    12.5% {
        border-radius: 37% 63% 70% 30%/30% 62% 38% 70%
    }

    25% {
        border-radius: 50% 50% 70% 30%/52% 62% 38% 48%
    }

    37.5% {
        border-radius: 33% 67% 18% 82%/52% 75% 25% 48%
    }

    50% {
        border-radius: 73% 27% 18% 82%/52% 32% 68% 48%
    }

    62.5% {
        border-radius: 73% 27% 74% 26%/64% 32% 68% 36%
    }

    75% {
        border-radius: 84% 16% 15% 85%/55% 79% 21% 45%
    }

    87.5% {
        border-radius: 12% 88% 69% 31%/10% 66% 34% 90%
    }
}
