kalei/initial mockups/assets/loading-animations.svg

389 lines
21 KiB
XML

<svg viewBox="0 0 700 820" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="grAmethyst" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#C4B5FD"><animate attributeName="stop-color" values="#C4B5FD;#DDD6FE;#C4B5FD" dur="4s" repeatCount="indefinite"/></stop>
<stop offset="100%" stop-color="#7C3AED"/>
</linearGradient>
<linearGradient id="grSapphire" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#93C5FD"/><stop offset="100%" stop-color="#2563EB"/>
</linearGradient>
<linearGradient id="grEmerald" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#6EE7B7"/><stop offset="100%" stop-color="#059669"/>
</linearGradient>
<linearGradient id="grAmber" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#FDE68A"/><stop offset="100%" stop-color="#D97706"/>
</linearGradient>
<linearGradient id="grRose" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#FBCFE8"/><stop offset="100%" stop-color="#DB2777"/>
</linearGradient>
<linearGradient id="grIndigo" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#A5B4FC"/><stop offset="100%" stop-color="#4338CA"/>
</linearGradient>
<linearGradient id="shimmerGrad" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#1C2240" stop-opacity="0"/>
<stop offset="50%" stop-color="#2A3158" stop-opacity="1"/>
<stop offset="100%" stop-color="#1C2240" stop-opacity="0"/>
</linearGradient>
<radialGradient id="successGlow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#10B981" stop-opacity="0.4"/>
<stop offset="100%" stop-color="#10B981" stop-opacity="0"/>
</radialGradient>
<filter id="glowSm" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="1.5" result="b"/><feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glowMd" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="3" result="b"/><feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glowLg" x="-80%" y="-80%" width="260%" height="260%">
<feGaussianBlur stdDeviation="6" result="b"/><feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="shimmer" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="2" result="b"/><feMerge><feMergeNode in="b"/><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<style>
text { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; }
.lbl { font-size: 9px; fill: #94A3B8; text-anchor: middle; font-weight: 500; }
.section-lbl { font-size: 11px; fill: #64748B; font-weight: 600; letter-spacing: 0.08em; }
</style>
</defs>
<rect width="700" height="820" fill="#050508"/>
<text x="350" y="28" font-size="13" font-weight="700" fill="#94A3B8" text-anchor="middle" letter-spacing="0.12em">LOADING AND ANIMATION STATES</text>
<text x="350" y="44" font-size="9" fill="#475569" text-anchor="middle">Spinners, skeleton shimmers, Turn animation, AI thinking, success burst, breathing logo</text>
<!-- Row 1: Spinners -->
<text x="24" y="74" class="section-lbl">SPINNERS</text>
<line x1="24" y1="80" x2="670" y2="80" stroke="#1C2240" stroke-width="0.5"/>
<!-- 1. Fragment Spinner — rotating diamond with trail -->
<g transform="translate(100, 140)">
<g filter="url(#glowMd)">
<g>
<animateTransform attributeName="transform" type="rotate" from="0" to="360" dur="1.5s" repeatCount="indefinite"/>
<!-- Trail fragments (fading) -->
<path d="M 0,-20 L 4,-16 L 0,-12 L -4,-16 Z" fill="url(#grAmethyst)" opacity="0.9"/>
<path d="M 0,-20 L 4,-16 L 0,-16 Z" fill="#fff" opacity="0.2"/>
<g transform="rotate(90)">
<path d="M 0,-20 L 4,-16 L 0,-12 L -4,-16 Z" fill="url(#grSapphire)" opacity="0.6"/>
</g>
<g transform="rotate(180)">
<path d="M 0,-20 L 4,-16 L 0,-12 L -4,-16 Z" fill="url(#grEmerald)" opacity="0.3"/>
</g>
<g transform="rotate(270)">
<path d="M 0,-20 L 4,-16 L 0,-12 L -4,-16 Z" fill="url(#grAmber)" opacity="0.15"/>
</g>
</g>
</g>
<text x="0" y="42" class="lbl">Fragment Spinner</text>
</g>
<!-- 2. Iris Spinner — mini kaleidoscope rotation -->
<g transform="translate(260, 140)">
<g filter="url(#glowMd)">
<g>
<animateTransform attributeName="transform" type="rotate" from="0" to="360" dur="3s" repeatCount="indefinite"/>
<g style="mix-blend-mode: screen;">
<path d="M 0,0 L 3,-1 L -2,20 L -3,1 Z" fill="url(#grAmethyst)" opacity="0.6">
<animate attributeName="fill-opacity" values="0.4;0.7;0.4" dur="2s" repeatCount="indefinite"/>
</path>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(60)">
<path d="M 0,0 L 3,-1 L -2,20 L -3,1 Z" fill="url(#grSapphire)" opacity="0.5"/>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(120)">
<path d="M 0,0 L 3,-1 L -2,20 L -3,1 Z" fill="url(#grEmerald)" opacity="0.5"/>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(180)">
<path d="M 0,0 L 3,-1 L -2,20 L -3,1 Z" fill="url(#grAmber)" opacity="0.6"/>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(240)">
<path d="M 0,0 L 3,-1 L -2,20 L -3,1 Z" fill="url(#grRose)" opacity="0.5"/>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(300)">
<path d="M 0,0 L 3,-1 L -2,20 L -3,1 Z" fill="url(#grIndigo)" opacity="0.5"/>
</g>
</g>
<circle r="3" fill="#fff" opacity="0.5">
<animate attributeName="opacity" values="0.3;0.7;0.3" dur="1.5s" repeatCount="indefinite"/>
</circle>
</g>
<text x="0" y="42" class="lbl">Iris Spinner (mini logo)</text>
</g>
<!-- 3. Dot Pulse Loader -->
<g transform="translate(420, 140)">
<g filter="url(#glowSm)">
<circle cx="-16" cy="0" r="4" fill="url(#grAmethyst)" opacity="0.3">
<animate attributeName="opacity" values="0.3;0.9;0.3" dur="1.2s" begin="0s" repeatCount="indefinite"/>
<animate attributeName="r" values="3;5;3" dur="1.2s" begin="0s" repeatCount="indefinite"/>
</circle>
<circle cx="0" cy="0" r="4" fill="url(#grSapphire)" opacity="0.3">
<animate attributeName="opacity" values="0.3;0.9;0.3" dur="1.2s" begin="0.2s" repeatCount="indefinite"/>
<animate attributeName="r" values="3;5;3" dur="1.2s" begin="0.2s" repeatCount="indefinite"/>
</circle>
<circle cx="16" cy="0" r="4" fill="url(#grEmerald)" opacity="0.3">
<animate attributeName="opacity" values="0.3;0.9;0.3" dur="1.2s" begin="0.4s" repeatCount="indefinite"/>
<animate attributeName="r" values="3;5;3" dur="1.2s" begin="0.4s" repeatCount="indefinite"/>
</circle>
</g>
<text x="0" y="28" class="lbl">Dot Pulse</text>
</g>
<!-- 4. Fragment Orbit Loader -->
<g transform="translate(580, 140)">
<g filter="url(#shimmer)">
<!-- Orbit path -->
<circle r="18" fill="none" stroke="#1C2240" stroke-width="0.4"/>
<!-- Orbiting fragment -->
<g>
<path d="M 0,-4 L 4,0 L 0,4 L -4,0 Z" fill="url(#grAmethyst)" opacity="0.8">
<animate attributeName="opacity" values="0.5;1;0.5" dur="1.8s" repeatCount="indefinite"/>
</path>
<animateMotion dur="1.8s" repeatCount="indefinite" path="M0,-18 A18,18 0 1 1 -0.1,-18"/>
</g>
<!-- Ghost trail -->
<g>
<path d="M 0,-3 L 3,0 L 0,3 L -3,0 Z" fill="#8B5CF6" opacity="0.3">
<animate attributeName="opacity" values="0.1;0.4;0.1" dur="1.8s" begin="0.3s" repeatCount="indefinite"/>
</path>
<animateMotion dur="1.8s" repeatCount="indefinite" path="M0,-18 A18,18 0 1 1 -0.1,-18" begin="0.3s"/>
</g>
</g>
<text x="0" y="38" class="lbl">Fragment Orbit</text>
</g>
<!-- Row 2: Skeleton Shimmers -->
<text x="24" y="204" class="section-lbl">SKELETON SHIMMERS</text>
<line x1="24" y1="210" x2="670" y2="210" stroke="#1C2240" stroke-width="0.5"/>
<!-- Text skeleton -->
<g transform="translate(175, 250)">
<rect x="-120" y="-8" width="160" height="10" rx="5" fill="#121628"/>
<rect x="-120" y="-8" width="40" height="10" rx="5" fill="url(#shimmerGrad)" opacity="0.5">
<animate attributeName="x" values="-160;120" dur="1.5s" repeatCount="indefinite"/>
</rect>
<rect x="-120" y="8" width="200" height="10" rx="5" fill="#121628"/>
<rect x="-120" y="8" width="40" height="10" rx="5" fill="url(#shimmerGrad)" opacity="0.5">
<animate attributeName="x" values="-160;160" dur="1.5s" begin="0.2s" repeatCount="indefinite"/>
</rect>
<rect x="-120" y="24" width="120" height="10" rx="5" fill="#121628"/>
<rect x="-120" y="24" width="40" height="10" rx="5" fill="url(#shimmerGrad)" opacity="0.5">
<animate attributeName="x" values="-160;80" dur="1.5s" begin="0.4s" repeatCount="indefinite"/>
</rect>
<text x="-20" y="54" class="lbl">Text skeleton shimmer</text>
</g>
<!-- Card skeleton -->
<g transform="translate(500, 250)">
<rect x="-80" y="-30" width="160" height="80" rx="10" fill="#0A0E1A" stroke="#1C2240" stroke-width="0.5"/>
<!-- Image placeholder -->
<rect x="-68" y="-20" width="40" height="40" rx="6" fill="#121628"/>
<rect x="-68" y="-20" width="20" height="40" rx="6" fill="url(#shimmerGrad)" opacity="0.4">
<animate attributeName="x" values="-88;-28" dur="1.5s" repeatCount="indefinite"/>
</rect>
<!-- Text lines -->
<rect x="-16" y="-16" width="80" height="8" rx="4" fill="#121628"/>
<rect x="-16" y="-16" width="20" height="8" rx="4" fill="url(#shimmerGrad)" opacity="0.4">
<animate attributeName="x" values="-36;64" dur="1.5s" begin="0.1s" repeatCount="indefinite"/>
</rect>
<rect x="-16" y="-2" width="60" height="8" rx="4" fill="#121628"/>
<rect x="-16" y="12" width="40" height="6" rx="3" fill="#121628"/>
<text x="0" y="66" class="lbl">Card skeleton shimmer</text>
</g>
<!-- Row 3: Turn Animation, AI Thinking -->
<text x="24" y="344" class="section-lbl">FEATURE ANIMATIONS</text>
<line x1="24" y1="350" x2="670" y2="350" stroke="#1C2240" stroke-width="0.5"/>
<!-- Turn Animation — kaleidoscope shift -->
<g transform="translate(175, 430)">
<g filter="url(#glowLg)">
<g>
<animateTransform attributeName="transform" type="rotate" from="0" to="60" dur="2s" repeatCount="indefinite"/>
<g style="mix-blend-mode: screen;">
<path d="M 0,0 L 6,-2 L -4,35 L -6,1 Z" fill="url(#grAmethyst)" opacity="0.5">
<animate attributeName="fill-opacity" values="0.3;0.6;0.3" dur="2s" repeatCount="indefinite"/>
</path>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(60)">
<path d="M 0,0 L 6,-2 L -4,35 L -6,1 Z" fill="url(#grSapphire)" opacity="0.45"/>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(120)">
<path d="M 0,0 L 6,-2 L -4,35 L -6,1 Z" fill="url(#grEmerald)" opacity="0.4"/>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(180)">
<path d="M 0,0 L 6,-2 L -4,35 L -6,1 Z" fill="url(#grAmber)" opacity="0.5"/>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(240)">
<path d="M 0,0 L 6,-2 L -4,35 L -6,1 Z" fill="url(#grRose)" opacity="0.45"/>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(300)">
<path d="M 0,0 L 6,-2 L -4,35 L -6,1 Z" fill="url(#grIndigo)" opacity="0.4"/>
</g>
</g>
<!-- Core pulse -->
<circle r="8" fill="#fff" opacity="0.4" filter="url(#glowMd)">
<animate attributeName="r" values="6;10;6" dur="2s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="0.3;0.6;0.3" dur="2s" repeatCount="indefinite"/>
</circle>
<circle r="3" fill="#fff" opacity="0.7"/>
</g>
<text x="0" y="60" class="lbl">Turn Animation (reframe moment)</text>
<text x="0" y="72" font-size="8" fill="#475569" text-anchor="middle">Rotates 60deg per cycle, pulses core</text>
</g>
<!-- AI Thinking — 3 fragments oscillating -->
<g transform="translate(475, 430)">
<g filter="url(#glowMd)">
<!-- Background bubble -->
<rect x="-50" y="-20" width="100" height="40" rx="20" fill="#121628" stroke="#1C2240" stroke-width="0.6"/>
<!-- Three oscillating fragments -->
<g transform="translate(-20, 0)">
<path d="M 0,-5 L 5,0 L 0,5 L -5,0 Z" fill="url(#grAmethyst)" opacity="0.4">
<animate attributeName="opacity" values="0.2;0.8;0.2" dur="1.5s" begin="0s" repeatCount="indefinite"/>
<animateTransform attributeName="transform" type="translate" values="-20,-3;-20,3;-20,-3" dur="1.5s" begin="0s" repeatCount="indefinite"/>
</path>
</g>
<g transform="translate(0, 0)">
<path d="M 0,-5 L 5,0 L 0,5 L -5,0 Z" fill="url(#grSapphire)" opacity="0.4">
<animate attributeName="opacity" values="0.2;0.8;0.2" dur="1.5s" begin="0.3s" repeatCount="indefinite"/>
<animateTransform attributeName="transform" type="translate" values="0,-3;0,3;0,-3" dur="1.5s" begin="0.3s" repeatCount="indefinite"/>
</path>
</g>
<g transform="translate(20, 0)">
<path d="M 0,-5 L 5,0 L 0,5 L -5,0 Z" fill="url(#grEmerald)" opacity="0.4">
<animate attributeName="opacity" values="0.2;0.8;0.2" dur="1.5s" begin="0.6s" repeatCount="indefinite"/>
<animateTransform attributeName="transform" type="translate" values="20,-3;20,3;20,-3" dur="1.5s" begin="0.6s" repeatCount="indefinite"/>
</path>
</g>
</g>
<text x="0" y="40" class="lbl">AI Thinking (Claude processing)</text>
</g>
<!-- Row 4: Success Burst, Breathing Logo -->
<text x="24" y="524" class="section-lbl">COMPLETION STATES</text>
<line x1="24" y1="530" x2="670" y2="530" stroke="#1C2240" stroke-width="0.5"/>
<!-- Success Burst -->
<g transform="translate(175, 610)">
<g filter="url(#glowLg)">
<!-- Burst ring -->
<circle r="30" fill="none" stroke="#10B981" stroke-width="2" opacity="0">
<animate attributeName="r" values="10;35;40" dur="1.5s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="0.6;0.3;0" dur="1.5s" repeatCount="indefinite"/>
</circle>
<circle r="20" fill="none" stroke="#6EE7B7" stroke-width="1" opacity="0">
<animate attributeName="r" values="8;25;30" dur="1.5s" begin="0.2s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="0.4;0.2;0" dur="1.5s" begin="0.2s" repeatCount="indefinite"/>
</circle>
<!-- Central checkmark fragment -->
<circle r="16" fill="url(#successGlow)" opacity="0.6">
<animate attributeName="opacity" values="0.4;0.8;0.4" dur="2s" repeatCount="indefinite"/>
</circle>
<path d="M 0,-10 L 10,0 L 0,10 L -10,0 Z" fill="url(#grEmerald)" opacity="0.9"/>
<path d="M 0,-10 L 10,0 L 0,0 Z" fill="#fff" opacity="0.2"/>
<path d="M -4,0 L -1,4 L 5,-3" fill="none" stroke="#fff" stroke-width="1.5" stroke-linecap="round"/>
<!-- Particle shards -->
<g>
<path d="M 0,-22 L 2,-20 L 0,-18 L -2,-20 Z" fill="#6EE7B7" opacity="0">
<animate attributeName="opacity" values="0;0.8;0" dur="1.5s" repeatCount="indefinite"/>
</path>
<g transform="rotate(72)"><path d="M 0,-22 L 2,-20 L 0,-18 L -2,-20 Z" fill="#6EE7B7" opacity="0">
<animate attributeName="opacity" values="0;0.7;0" dur="1.5s" begin="0.1s" repeatCount="indefinite"/>
</path></g>
<g transform="rotate(144)"><path d="M 0,-22 L 2,-20 L 0,-18 L -2,-20 Z" fill="#A7F3D0" opacity="0">
<animate attributeName="opacity" values="0;0.6;0" dur="1.5s" begin="0.2s" repeatCount="indefinite"/>
</path></g>
<g transform="rotate(216)"><path d="M 0,-22 L 2,-20 L 0,-18 L -2,-20 Z" fill="#6EE7B7" opacity="0">
<animate attributeName="opacity" values="0;0.7;0" dur="1.5s" begin="0.3s" repeatCount="indefinite"/>
</path></g>
<g transform="rotate(288)"><path d="M 0,-22 L 2,-20 L 0,-18 L -2,-20 Z" fill="#A7F3D0" opacity="0">
<animate attributeName="opacity" values="0;0.6;0" dur="1.5s" begin="0.4s" repeatCount="indefinite"/>
</path></g>
</g>
</g>
<text x="0" y="56" class="lbl">Success Burst (Turn complete, goal achieved)</text>
</g>
<!-- Breathing Logo -->
<g transform="translate(475, 610)">
<g filter="url(#glowMd)">
<!-- Outer breathing aura -->
<circle r="30" fill="#8B5CF6" opacity="0.04">
<animate attributeName="r" values="25;35;25" dur="5s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="0.02;0.08;0.02" dur="5s" repeatCount="indefinite"/>
</circle>
<!-- Mini 3-blade iris -->
<g>
<animateTransform attributeName="transform" type="rotate" from="0" to="360" dur="60s" repeatCount="indefinite"/>
<g style="mix-blend-mode: screen;">
<path d="M 0,0 L 3,-1 L -2,22 L -3,1 Z" fill="url(#grAmethyst)" opacity="0.4">
<animate attributeName="fill-opacity" values="0.3;0.5;0.3" dur="5s" repeatCount="indefinite"/>
</path>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(120)">
<path d="M 0,0 L 3,-1 L -2,22 L -3,1 Z" fill="url(#grSapphire)" opacity="0.35"/>
</g>
<g style="mix-blend-mode: screen;" transform="rotate(240)">
<path d="M 0,0 L 3,-1 L -2,22 L -3,1 Z" fill="url(#grEmerald)" opacity="0.35"/>
</g>
</g>
<circle r="4" fill="#fff" opacity="0.5" filter="url(#glowSm)">
<animate attributeName="opacity" values="0.3;0.7;0.3" dur="5s" repeatCount="indefinite"/>
<animate attributeName="r" values="3;5;3" dur="5s" repeatCount="indefinite"/>
</circle>
</g>
<text x="0" y="52" class="lbl">Breathing Logo (idle/splash)</text>
</g>
<!-- Row 5: Page Transition -->
<text x="24" y="700" class="section-lbl">TRANSITIONS</text>
<line x1="24" y1="706" x2="670" y2="706" stroke="#1C2240" stroke-width="0.5"/>
<!-- Page fade transition -->
<g transform="translate(175, 760)">
<g filter="url(#glowSm)">
<!-- "From" state -->
<rect x="-55" y="-20" width="40" height="40" rx="6" fill="#121628" stroke="#1C2240" stroke-width="0.5" opacity="0.4"/>
<text x="-35" y="2" font-size="7" fill="#475569" text-anchor="middle">From</text>
<!-- Arrow -->
<path d="M -8,0 L 8,0 M 4,-4 L 8,0 L 4,4" fill="none" stroke="#475569" stroke-width="0.8"/>
<!-- "To" state -->
<rect x="15" y="-20" width="40" height="40" rx="6" fill="#121628" stroke="#8B5CF6" stroke-width="0.5" opacity="0.8"/>
<text x="35" y="2" font-size="7" fill="#C4B5FD" text-anchor="middle">To</text>
</g>
<text x="0" y="40" class="lbl">Fade + slide up transition</text>
</g>
<!-- Fragment scatter transition -->
<g transform="translate(475, 760)">
<g filter="url(#glowSm)">
<!-- Scattered fragments converging -->
<path d="M -30,-15 L -26,-11 L -30,-7 L -34,-11 Z" fill="url(#grAmethyst)" opacity="0.3">
<animate attributeName="opacity" values="0;0.6;0" dur="2s" repeatCount="indefinite"/>
<animateTransform attributeName="transform" type="translate" values="-30,-15;0,0;-30,-15" dur="2s" repeatCount="indefinite"/>
</path>
<path d="M 25,-20 L 29,-16 L 25,-12 L 21,-16 Z" fill="url(#grSapphire)" opacity="0.3">
<animate attributeName="opacity" values="0;0.6;0" dur="2s" begin="0.2s" repeatCount="indefinite"/>
<animateTransform attributeName="transform" type="translate" values="25,-20;0,0;25,-20" dur="2s" begin="0.2s" repeatCount="indefinite"/>
</path>
<path d="M 20,18 L 24,22 L 20,26 L 16,22 Z" fill="url(#grEmerald)" opacity="0.3">
<animate attributeName="opacity" values="0;0.6;0" dur="2s" begin="0.4s" repeatCount="indefinite"/>
<animateTransform attributeName="transform" type="translate" values="20,18;0,0;20,18" dur="2s" begin="0.4s" repeatCount="indefinite"/>
</path>
<path d="M -28,12 L -24,16 L -28,20 L -32,16 Z" fill="url(#grAmber)" opacity="0.3">
<animate attributeName="opacity" values="0;0.6;0" dur="2s" begin="0.6s" repeatCount="indefinite"/>
<animateTransform attributeName="transform" type="translate" values="-28,12;0,0;-28,12" dur="2s" begin="0.6s" repeatCount="indefinite"/>
</path>
<!-- Center convergence point -->
<circle r="3" fill="#fff" opacity="0">
<animate attributeName="opacity" values="0;0.8;0" dur="2s" begin="0.8s" repeatCount="indefinite"/>
</circle>
</g>
<text x="0" y="40" class="lbl">Fragment scatter/converge transition</text>
</g>
<text x="350" y="812" font-size="8" fill="#334155" text-anchor="middle">All animations use SMIL for broad SVG compatibility — breathing, rotation, opacity, and transform animations</text>
</svg>