summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoryu-co <bot@soryu.co>2026-05-06 14:05:35 +0000
committersoryu-co <bot@soryu.co>2026-05-06 14:05:35 +0000
commit416424dbf1bc6b105b8e2c8176fff8fce5c53979 (patch)
tree7af3d5913eb3931c849bb05d36839d3aeb135746
parent697e6d842cf662f33e0b679859c2fc9365222d2d (diff)
downloadsoryu-416424dbf1bc6b105b8e2c8176fff8fce5c53979.tar.gz
soryu-416424dbf1bc6b105b8e2c8176fff8fce5c53979.zip
Animate mission tactical SVG: flowing data along mesh links
- Each of 6 mesh arcs now has an id (#arc1..#arc6) with two layered animations: a flowing stroke-dashoffset (so the lines themselves appear to ripple), and a separate breathing opacity cycle. - 8 packet circles ride the arcs via <animateMotion> + <mpath>, with staggered begin times (0s..2.0s) and varied durations (2.6s..4.0s) so traffic feels asynchronous, not metronomic. - Amber arcs carry amber packets, magenta arcs carry magenta packets. - Hub nodes now have layered radial pulses (filled core + expanding ring) on independent timings; cyan relay dots blink gently. - REC indicator pulses 1.4s. All animations are SVG-native (no JS, no external library); browsers respect prefers-reduced-motion via UA defaults on <animate>.
-rw-r--r--frontend/public/mission-tactical.svg163
1 files changed, 144 insertions, 19 deletions
diff --git a/frontend/public/mission-tactical.svg b/frontend/public/mission-tactical.svg
index cd4095a..342af2a 100644
--- a/frontend/public/mission-tactical.svg
+++ b/frontend/public/mission-tactical.svg
@@ -55,7 +55,9 @@
<!-- Tactical header strip -->
<g font-size="9" letter-spacing="2.5" fill="rgba(240,234,223,0.55)">
<text x="32" y="40">SORYU // OBSERVABILITY MESH</text>
- <text x="568" y="40" text-anchor="end" fill="#e8b87a">REC ●</text>
+ <text x="568" y="40" text-anchor="end" fill="#e8b87a">REC <tspan fill="#d96a8a">●</tspan>
+ <animate attributeName="opacity" values="1;0.4;1" dur="1.4s" repeatCount="indefinite"/>
+ </text>
</g>
<g font-size="8" letter-spacing="1.8" fill="rgba(240,234,223,0.40)">
<text x="32" y="54">35.6764°N · 139.6500°E</text>
@@ -103,14 +105,113 @@
<!-- ============ NODES + MESH LINKS ============ -->
<!-- Coordinates roughly evoke continents on a tilted globe -->
<g>
- <!-- Mesh links (curved arcs above the surface) -->
- <g fill="none" stroke="rgba(232,184,122,0.55)" stroke-width="0.8" stroke-linecap="round" filter="url(#softGlow)">
- <path d="M -120,-70 Q -40,-180 60,-90"/>
- <path d="M 60,-90 Q 130,-30 150, 60"/>
- <path d="M 150, 60 Q 60,150 -30,130"/>
- <path d="M -30,130 Q -120,80 -120,-70"/>
- <path d="M -120,-70 Q 0,-30 150, 60" stroke="rgba(217,106,138,0.55)"/>
- <path d="M 60,-90 Q -10, 60 -30,130" stroke="rgba(217,106,138,0.45)"/>
+ <!-- Mesh links: each path has an id so animated pulses can ride along it.
+ The arc itself shows a flowing dash pattern, and a glowing dot
+ travels along it via <animateMotion>. -->
+ <g fill="none" stroke-linecap="round">
+ <!-- arc 1 (amber) NODE-A → TYO -->
+ <path id="arc1" d="M -120,-70 Q -40,-180 60,-90"
+ stroke="rgba(232,184,122,0.55)" stroke-width="0.9"
+ stroke-dasharray="2 6" stroke-dashoffset="0" filter="url(#softGlow)">
+ <animate attributeName="stroke-dashoffset" from="0" to="-32" dur="1.6s" repeatCount="indefinite"/>
+ <animate attributeName="opacity" values="0.65;1;0.65" dur="2.6s" repeatCount="indefinite"/>
+ </path>
+ <!-- arc 2 (amber) TYO → SE -->
+ <path id="arc2" d="M 60,-90 Q 130,-30 150, 60"
+ stroke="rgba(232,184,122,0.55)" stroke-width="0.9"
+ stroke-dasharray="2 6" filter="url(#softGlow)">
+ <animate attributeName="stroke-dashoffset" from="0" to="-32" dur="1.9s" repeatCount="indefinite"/>
+ <animate attributeName="opacity" values="0.65;1;0.65" dur="2.9s" repeatCount="indefinite"/>
+ </path>
+ <!-- arc 3 (amber) SE → SW -->
+ <path id="arc3" d="M 150, 60 Q 60,150 -30,130"
+ stroke="rgba(232,184,122,0.55)" stroke-width="0.9"
+ stroke-dasharray="2 6" filter="url(#softGlow)">
+ <animate attributeName="stroke-dashoffset" from="0" to="-32" dur="2.1s" repeatCount="indefinite"/>
+ <animate attributeName="opacity" values="0.6;0.95;0.6" dur="3.1s" repeatCount="indefinite"/>
+ </path>
+ <!-- arc 4 (amber) SW → NW (closes ring) -->
+ <path id="arc4" d="M -30,130 Q -120,80 -120,-70"
+ stroke="rgba(232,184,122,0.55)" stroke-width="0.9"
+ stroke-dasharray="2 6" filter="url(#softGlow)">
+ <animate attributeName="stroke-dashoffset" from="0" to="-32" dur="1.7s" repeatCount="indefinite"/>
+ <animate attributeName="opacity" values="0.6;0.9;0.6" dur="2.7s" repeatCount="indefinite"/>
+ </path>
+ <!-- arc 5 (magenta) NW → SE diagonal -->
+ <path id="arc5" d="M -120,-70 Q 0,-30 150, 60"
+ stroke="rgba(217,106,138,0.55)" stroke-width="0.9"
+ stroke-dasharray="3 7" filter="url(#softGlow)">
+ <animate attributeName="stroke-dashoffset" from="0" to="-40" dur="2.4s" repeatCount="indefinite"/>
+ <animate attributeName="opacity" values="0.55;0.95;0.55" dur="3.4s" repeatCount="indefinite"/>
+ </path>
+ <!-- arc 6 (magenta) TYO → SW diagonal -->
+ <path id="arc6" d="M 60,-90 Q -10, 60 -30,130"
+ stroke="rgba(217,106,138,0.45)" stroke-width="0.8"
+ stroke-dasharray="3 7" filter="url(#softGlow)">
+ <animate attributeName="stroke-dashoffset" from="0" to="-40" dur="2.8s" repeatCount="indefinite"/>
+ <animate attributeName="opacity" values="0.5;0.9;0.5" dur="3.8s" repeatCount="indefinite"/>
+ </path>
+ </g>
+
+ <!-- Traveling data packets (glowing dots ride each arc).
+ Each packet is a tiny circle with <animateMotion> referencing
+ the arc path via <mpath>. Stagger begin times so packets feel asynchronous. -->
+ <g>
+ <!-- amber packets -->
+ <circle r="2.4" fill="#e8b87a" filter="url(#softGlow)">
+ <animateMotion dur="2.8s" repeatCount="indefinite" rotate="auto" begin="0s">
+ <mpath href="#arc1"/>
+ </animateMotion>
+ <animate attributeName="opacity" values="0;1;1;0" keyTimes="0;0.1;0.9;1" dur="2.8s" repeatCount="indefinite"/>
+ </circle>
+ <circle r="2.0" fill="#e8b87a" filter="url(#softGlow)">
+ <animateMotion dur="2.8s" repeatCount="indefinite" rotate="auto" begin="1.2s">
+ <mpath href="#arc1"/>
+ </animateMotion>
+ <animate attributeName="opacity" values="0;1;1;0" keyTimes="0;0.1;0.9;1" dur="2.8s" repeatCount="indefinite" begin="1.2s"/>
+ </circle>
+
+ <circle r="2.4" fill="#e8b87a" filter="url(#softGlow)">
+ <animateMotion dur="3.2s" repeatCount="indefinite" rotate="auto" begin="0.4s">
+ <mpath href="#arc2"/>
+ </animateMotion>
+ <animate attributeName="opacity" values="0;1;1;0" keyTimes="0;0.08;0.92;1" dur="3.2s" repeatCount="indefinite" begin="0.4s"/>
+ </circle>
+
+ <circle r="2.4" fill="#e8b87a" filter="url(#softGlow)">
+ <animateMotion dur="3.0s" repeatCount="indefinite" rotate="auto" begin="0.9s">
+ <mpath href="#arc3"/>
+ </animateMotion>
+ <animate attributeName="opacity" values="0;1;1;0" keyTimes="0;0.1;0.9;1" dur="3.0s" repeatCount="indefinite" begin="0.9s"/>
+ </circle>
+
+ <circle r="2.4" fill="#e8b87a" filter="url(#softGlow)">
+ <animateMotion dur="2.6s" repeatCount="indefinite" rotate="auto" begin="1.6s">
+ <mpath href="#arc4"/>
+ </animateMotion>
+ <animate attributeName="opacity" values="0;1;1;0" keyTimes="0;0.1;0.9;1" dur="2.6s" repeatCount="indefinite" begin="1.6s"/>
+ </circle>
+
+ <!-- magenta packets (longer arcs, brighter core) -->
+ <circle r="2.6" fill="#d96a8a" filter="url(#softGlow)">
+ <animateMotion dur="3.6s" repeatCount="indefinite" rotate="auto" begin="0.2s">
+ <mpath href="#arc5"/>
+ </animateMotion>
+ <animate attributeName="opacity" values="0;1;1;0" keyTimes="0;0.08;0.92;1" dur="3.6s" repeatCount="indefinite" begin="0.2s"/>
+ </circle>
+ <circle r="2.0" fill="#d96a8a" filter="url(#softGlow)">
+ <animateMotion dur="3.6s" repeatCount="indefinite" rotate="auto" begin="2.0s">
+ <mpath href="#arc5"/>
+ </animateMotion>
+ <animate attributeName="opacity" values="0;1;1;0" keyTimes="0;0.08;0.92;1" dur="3.6s" repeatCount="indefinite" begin="2.0s"/>
+ </circle>
+
+ <circle r="2.4" fill="#d96a8a" filter="url(#softGlow)">
+ <animateMotion dur="4.0s" repeatCount="indefinite" rotate="auto" begin="1.0s">
+ <mpath href="#arc6"/>
+ </animateMotion>
+ <animate attributeName="opacity" values="0;1;1;0" keyTimes="0;0.08;0.92;1" dur="4.0s" repeatCount="indefinite" begin="1.0s"/>
+ </circle>
</g>
<!-- Active nodes (amber primary) -->
@@ -123,23 +224,47 @@
<animate attributeName="opacity" values="1;0;1" dur="3s" repeatCount="indefinite"/>
</circle>
- <!-- Other nodes -->
+ <!-- Other nodes — subtle independent pulses -->
<circle cx="-120" cy="-70" r="10" fill="url(#nodeGlow)"/>
- <circle cx="-120" cy="-70" r="2.4" fill="#e8b87a"/>
+ <circle cx="-120" cy="-70" r="2.4" fill="#e8b87a">
+ <animate attributeName="opacity" values="0.7;1;0.7" dur="2.2s" repeatCount="indefinite"/>
+ </circle>
+ <circle cx="-120" cy="-70" r="2.4" fill="none" stroke="#e8b87a" stroke-width="0.8">
+ <animate attributeName="r" values="2.4;13;2.4" dur="3.4s" repeatCount="indefinite" begin="0.7s"/>
+ <animate attributeName="opacity" values="0.9;0;0.9" dur="3.4s" repeatCount="indefinite" begin="0.7s"/>
+ </circle>
<circle cx="150" cy="60" r="12" fill="url(#nodeMag)"/>
- <circle cx="150" cy="60" r="2.6" fill="#d96a8a"/>
+ <circle cx="150" cy="60" r="2.6" fill="#d96a8a">
+ <animate attributeName="opacity" values="0.7;1;0.7" dur="2.8s" repeatCount="indefinite" begin="0.4s"/>
+ </circle>
+ <circle cx="150" cy="60" r="2.6" fill="none" stroke="#d96a8a" stroke-width="0.8">
+ <animate attributeName="r" values="2.6;14;2.6" dur="3.6s" repeatCount="indefinite" begin="1.4s"/>
+ <animate attributeName="opacity" values="0.9;0;0.9" dur="3.6s" repeatCount="indefinite" begin="1.4s"/>
+ </circle>
<circle cx="-30" cy="130" r="9" fill="url(#nodeGlow)"/>
- <circle cx="-30" cy="130" r="2.2" fill="#e8b87a"/>
+ <circle cx="-30" cy="130" r="2.2" fill="#e8b87a">
+ <animate attributeName="opacity" values="0.7;1;0.7" dur="2.4s" repeatCount="indefinite" begin="1.1s"/>
+ </circle>
- <!-- Smaller relays -->
+ <!-- Smaller relays — gentle blink so they feel alive -->
<g fill="#9ad7e0">
- <circle cx="-160" cy="40" r="1.6"/>
- <circle cx="20" cy="-160" r="1.6"/>
- <circle cx="170" cy="-30" r="1.6"/>
- <circle cx="-80" cy="170" r="1.6"/>
- <circle cx="100" cy="160" r="1.6"/>
+ <circle cx="-160" cy="40" r="1.6">
+ <animate attributeName="opacity" values="0.4;1;0.4" dur="2.0s" repeatCount="indefinite" begin="0.0s"/>
+ </circle>
+ <circle cx="20" cy="-160" r="1.6">
+ <animate attributeName="opacity" values="0.4;1;0.4" dur="2.4s" repeatCount="indefinite" begin="0.5s"/>
+ </circle>
+ <circle cx="170" cy="-30" r="1.6">
+ <animate attributeName="opacity" values="0.4;1;0.4" dur="2.8s" repeatCount="indefinite" begin="1.0s"/>
+ </circle>
+ <circle cx="-80" cy="170" r="1.6">
+ <animate attributeName="opacity" values="0.4;1;0.4" dur="2.2s" repeatCount="indefinite" begin="1.5s"/>
+ </circle>
+ <circle cx="100" cy="160" r="1.6">
+ <animate attributeName="opacity" values="0.4;1;0.4" dur="2.6s" repeatCount="indefinite" begin="2.0s"/>
+ </circle>
</g>
</g>