docs(readme): единая визуальная система Tachyon с анимированными баннерами для Telegram-бота, Watchdog, LuCI UI, CLI API и футера

This commit is contained in:
Dushnilin
2026-08-15 20:33:15 +03:00
parent 954596c26f
commit b1c336ccad
7 changed files with 516 additions and 10 deletions
+94
View File
@@ -0,0 +1,94 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 150" width="100%" height="100%">
<defs>
<radialGradient id="cli-bg" cx="50%" cy="50%" r="75%">
<stop offset="0%" stop-color="#1E1B4B" stop-opacity="0.3"/>
<stop offset="60%" stop-color="#0F172A" stop-opacity="0.95"/>
<stop offset="100%" stop-color="#020617" stop-opacity="0.98"/>
</radialGradient>
<linearGradient id="cli-border" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#10B981" stop-opacity="0.3"/>
<stop offset="50%" stop-color="#00F0FF" stop-opacity="0.7"/>
<stop offset="100%" stop-color="#8B5CF6" stop-opacity="0.3"/>
</linearGradient>
<filter id="cli-glow" filterUnits="userSpaceOnUse" x="0" y="0" width="1200" height="150">
<feGaussianBlur stdDeviation="3" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<style>
@keyframes pulseCliDot {
0%, 100% { transform: scale(1); opacity: 0.9; }
50% { transform: scale(1.3); opacity: 0.3; }
}
@keyframes cliStreamFlow {
0% { stroke-dashoffset: 120; }
100% { stroke-dashoffset: 0; }
}
.cli-dot { animation: pulseCliDot 2s ease-in-out infinite; }
.cli-stream { stroke-dasharray: 12 24; animation: cliStreamFlow 2.5s linear infinite; }
.cli-title { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 800; font-size: 15px; fill: #FFFFFF; }
.cli-desc { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 500; font-size: 12px; fill: #94A3B8; }
.cli-tag { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11px; font-weight: 700; fill: #34D399; }
.cli-subtag { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 10px; font-weight: 600; fill: #94A3B8; }
</style>
<!-- Container Box -->
<rect width="1200" height="150" rx="14" fill="url(#cli-bg)" stroke="url(#cli-border)" stroke-width="1.5"/>
<!-- Left Header with Terminal Icon -->
<g transform="translate(35, 25)">
<rect width="44" height="44" rx="10" fill="#065F46" fill-opacity="0.25" stroke="#10B981" stroke-width="1.2"/>
<text x="11" y="29" font-size="22">🛠️</text>
<text x="56" y="20" class="cli-title">CLI Terminal Control &amp; HTTP REST Agent API (OpenAPI 3.0)</text>
<text x="56" y="38" class="cli-desc">Полнофункциональный консольный интерфейс и REST API для интеграции с LLM-агентами (GPTs, N8N, Dify)</text>
</g>
<!-- Animated Connection Stream -->
<g transform="translate(35, 80)">
<line x1="0" y1="28" x2="1130" y2="28" stroke="#1E293B" stroke-width="1.5"/>
<line x1="0" y1="28" x2="1130" y2="28" stroke="#10B981" stroke-width="2" class="cli-stream" filter="url(#cli-glow)"/>
</g>
<!-- 4 Feature Badges -->
<g transform="translate(35, 95)">
<!-- Badge 1: OpenAPI Spec -->
<g transform="translate(0, 0)">
<rect width="180" height="34" rx="6" fill="#0B132B" stroke="#10B981" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#10B981" class="cli-dot"/>
<text x="24" y="16" class="cli-tag">OPENAPI 3.0.3</text>
<text x="24" y="28" class="cli-subtag">/openapi.json Schema</text>
</g>
<!-- Badge 2: Bearer Token Auth -->
<g transform="translate(195, 0)">
<rect width="180" height="34" rx="6" fill="#0B132B" stroke="#00F0FF" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#00F0FF" class="cli-dot"/>
<text x="24" y="16" class="cli-tag" fill="#00F0FF">BEARER AUTH TOKEN</text>
<text x="24" y="28" class="cli-subtag">Granular READ / WRITE</text>
</g>
<!-- Badge 3: LLM Agent Ready -->
<g transform="translate(390, 0)">
<rect width="180" height="34" rx="6" fill="#0B132B" stroke="#C084FC" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#C084FC" class="cli-dot"/>
<text x="24" y="16" class="cli-tag" fill="#C084FC">LLM AGENT READY</text>
<text x="24" y="28" class="cli-subtag">ChatGPT, N8N, Dify</text>
</g>
<!-- Badge 4: Native Internet Fallback -->
<g transform="translate(585, 0)">
<rect width="190" height="34" rx="6" fill="#0B132B" stroke="#F59E0B" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#F59E0B" class="cli-dot"/>
<text x="24" y="16" class="cli-tag" fill="#FBBF24">RESTORE INTERNET</text>
<text x="24" y="28" class="cli-subtag">1-Click Native Fallback</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

+49
View File
@@ -0,0 +1,49 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 100" width="100%" height="100%">
<defs>
<linearGradient id="footer-grad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#00F0FF" stop-opacity="0"/>
<stop offset="30%" stop-color="#38BDF8" stop-opacity="0.5"/>
<stop offset="50%" stop-color="#8B5CF6" stop-opacity="0.8"/>
<stop offset="70%" stop-color="#C084FC" stop-opacity="0.5"/>
<stop offset="100%" stop-color="#00F0FF" stop-opacity="0"/>
</linearGradient>
<filter id="heart-glow" filterUnits="userSpaceOnUse" x="0" y="0" width="1200" height="100">
<feGaussianBlur stdDeviation="3" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<style>
@keyframes heartBeating {
0%, 100% { transform: scale(1); }
30% { transform: scale(1.3); }
50% { transform: scale(1.1); }
70% { transform: scale(1.35); }
}
@keyframes streamFlowFooter {
0% { stroke-dashoffset: 160; }
100% { stroke-dashoffset: 0; }
}
.heart-icon { transform-origin: 600px 58px; animation: heartBeating 1.6s ease-in-out infinite; }
.footer-wire { stroke-dasharray: 10 30; animation: streamFlowFooter 2.5s linear infinite; }
.foot-text { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 600; font-size: 14px; fill: #94A3B8; }
.foot-brand { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 800; font-size: 15px; fill: #F8FAFC; letter-spacing: 0.5px; }
</style>
<!-- Top Cyber Laser Line -->
<line x1="100" y1="12" x2="1100" y2="12" stroke="url(#footer-grad)" stroke-width="1.5"/>
<line x1="200" y1="12" x2="1000" y2="12" stroke="#00F0FF" stroke-width="2" class="footer-wire"/>
<!-- Footer Content -->
<g transform="translate(600, 58)" text-anchor="middle">
<!-- Heart Symbol -->
<text x="-135" y="5" font-size="18" fill="#EF4444" class="heart-icon" filter="url(#heart-glow)">❤️</text>
<text x="0" y="5" class="foot-text">Crafted with passion for the global <tspan class="foot-brand" fill="#00F0FF">OpenWrt</tspan> &amp; <tspan class="foot-brand" fill="#C084FC">Tachyon</tspan> Community</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

+94
View File
@@ -0,0 +1,94 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 150" width="100%" height="100%">
<defs>
<radialGradient id="luci-bg" cx="50%" cy="50%" r="75%">
<stop offset="0%" stop-color="#0F172A" stop-opacity="0.95"/>
<stop offset="60%" stop-color="#090D16" stop-opacity="0.98"/>
<stop offset="100%" stop-color="#020617" stop-opacity="1"/>
</radialGradient>
<linearGradient id="luci-border" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#38BDF8" stop-opacity="0.3"/>
<stop offset="50%" stop-color="#00F0FF" stop-opacity="0.8"/>
<stop offset="100%" stop-color="#818CF8" stop-opacity="0.3"/>
</linearGradient>
<filter id="luci-glow" filterUnits="userSpaceOnUse" x="0" y="0" width="1200" height="150">
<feGaussianBlur stdDeviation="3" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<style>
@keyframes pulseWebDot {
0%, 100% { transform: scale(1); opacity: 0.9; }
50% { transform: scale(1.3); opacity: 0.3; }
}
@keyframes luciStreamFlow {
0% { stroke-dashoffset: 120; }
100% { stroke-dashoffset: 0; }
}
.luci-dot { animation: pulseWebDot 2s ease-in-out infinite; }
.luci-stream { stroke-dasharray: 12 24; animation: luciStreamFlow 2.5s linear infinite; }
.luci-title { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 800; font-size: 15px; fill: #FFFFFF; }
.luci-desc { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 500; font-size: 12px; fill: #94A3B8; }
.luci-tag { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11px; font-weight: 700; fill: #00F0FF; }
.luci-subtag { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 10px; font-weight: 600; fill: #94A3B8; }
</style>
<!-- Container Box -->
<rect width="1200" height="150" rx="14" fill="url(#luci-bg)" stroke="url(#luci-border)" stroke-width="1.5"/>
<!-- Left Header with Monitor Icon -->
<g transform="translate(35, 25)">
<rect width="44" height="44" rx="10" fill="#0369A1" fill-opacity="0.25" stroke="#38BDF8" stroke-width="1.2"/>
<text x="11" y="29" font-size="22">🖥️</text>
<text x="56" y="20" class="luci-title">Modern LuCI Web UI (TypeScript &amp; Reactive State)</text>
<text x="56" y="38" class="luci-desc">Интерактивный дашборд OpenWrt: замер задержек RTT, потоковый терминал установки и управление правилами</text>
</g>
<!-- Animated Connection Stream -->
<g transform="translate(35, 80)">
<line x1="0" y1="28" x2="1130" y2="28" stroke="#1E293B" stroke-width="1.5"/>
<line x1="0" y1="28" x2="1130" y2="28" stroke="#00F0FF" stroke-width="2" class="luci-stream" filter="url(#luci-glow)"/>
</g>
<!-- 4 Feature Badges -->
<g transform="translate(35, 95)">
<!-- Badge 1: TypeScript Engine -->
<g transform="translate(0, 0)">
<rect width="175" height="34" rx="6" fill="#0B132B" stroke="#00F0FF" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#00F0FF" class="luci-dot"/>
<text x="24" y="16" class="luci-tag">TYPESCRIPT CORE</text>
<text x="24" y="28" class="luci-subtag">Strict Type-Safe Build</text>
</g>
<!-- Badge 2: RTT Matrix -->
<g transform="translate(190, 0)">
<rect width="180" height="34" rx="6" fill="#0B132B" stroke="#10B981" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#10B981" class="luci-dot"/>
<text x="24" y="16" class="luci-tag" fill="#34D399">RTT LATENCY MATRIX</text>
<text x="24" y="28" class="luci-subtag">Real-Time Ping Heatmap</text>
</g>
<!-- Badge 3: Streaming Log Terminal -->
<g transform="translate(385, 0)">
<rect width="185" height="34" rx="6" fill="#0B132B" stroke="#C084FC" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#C084FC" class="luci-dot"/>
<text x="24" y="16" class="luci-tag" fill="#C084FC">STREAMING LOGS</text>
<text x="24" y="28" class="luci-subtag">Live RPC Output Stream</text>
</g>
<!-- Badge 4: Commit Tracking -->
<g transform="translate(585, 0)">
<rect width="190" height="34" rx="6" fill="#0B132B" stroke="#F59E0B" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#F59E0B" class="luci-dot"/>
<text x="24" y="16" class="luci-tag" fill="#FBBF24">COMMIT-LEVEL TRACK</text>
<text x="24" y="28" class="luci-subtag">Same-Release SHA Check</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

+110
View File
@@ -0,0 +1,110 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 150" width="100%" height="100%">
<defs>
<radialGradient id="tg-bg" cx="50%" cy="50%" r="75%">
<stop offset="0%" stop-color="#0284C7" stop-opacity="0.25"/>
<stop offset="60%" stop-color="#0F172A" stop-opacity="0.9"/>
<stop offset="100%" stop-color="#030712" stop-opacity="0.98"/>
</radialGradient>
<linearGradient id="tg-border" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#38BDF8" stop-opacity="0.3"/>
<stop offset="50%" stop-color="#0284C7" stop-opacity="0.8"/>
<stop offset="100%" stop-color="#818CF8" stop-opacity="0.3"/>
</linearGradient>
<filter id="tg-glow" filterUnits="userSpaceOnUse" x="0" y="0" width="1200" height="150">
<feGaussianBlur stdDeviation="3" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<style>
@keyframes pulseTgDot {
0%, 100% { transform: scale(1); opacity: 0.9; }
50% { transform: scale(1.3); opacity: 0.3; }
}
@keyframes tgWaveDash {
0% { stroke-dashoffset: 120; }
100% { stroke-dashoffset: 0; }
}
.tg-dot { animation: pulseTgDot 2s ease-in-out infinite; }
.tg-stream { stroke-dasharray: 12 24; animation: tgWaveDash 2.5s linear infinite; }
.tg-title { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 800; font-size: 15px; fill: #FFFFFF; }
.tg-desc { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 500; font-size: 12px; fill: #94A3B8; }
.tg-cmd { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 12px; font-weight: 700; fill: #38BDF8; }
.tg-btn-txt { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11px; font-weight: 600; fill: #F8FAFC; }
.tg-status { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11px; font-weight: 700; fill: #10B981; }
</style>
<!-- Container Box -->
<rect width="1200" height="150" rx="14" fill="url(#tg-bg)" stroke="url(#tg-border)" stroke-width="1.5"/>
<!-- Left Header with Telegram Icon -->
<g transform="translate(35, 25)">
<rect width="44" height="44" rx="10" fill="#0284C7" fill-opacity="0.25" stroke="#38BDF8" stroke-width="1.2"/>
<text x="11" y="29" font-size="22">📱</text>
<text x="56" y="20" class="tg-title">Interactive Telegram Bot Management &amp; Remote Control</text>
<text x="56" y="38" class="tg-desc">Мгновенный контроль роутера из мессенджера: запуск AI Doctor, переключение серверов и списков</text>
</g>
<!-- Animated Connecting Data Track -->
<g transform="translate(35, 80)">
<line x1="0" y1="28" x2="1130" y2="28" stroke="#1E293B" stroke-width="1.5"/>
<line x1="0" y1="28" x2="1130" y2="28" stroke="#38BDF8" stroke-width="2" class="tg-stream" filter="url(#tg-glow)"/>
</g>
<!-- Interactive Telegram Command Badges -->
<g transform="translate(35, 95)">
<!-- Cmd 1: /ai_doctor -->
<g transform="translate(0, 0)">
<rect width="125" height="32" rx="6" fill="#0B132B" stroke="#0284C7" stroke-width="1"/>
<text x="12" y="20" class="tg-cmd">/ai_doctor</text>
</g>
<!-- Cmd 2: /fix -->
<g transform="translate(135, 0)">
<rect width="90" height="32" rx="6" fill="#0B132B" stroke="#818CF8" stroke-width="1"/>
<text x="12" y="20" class="tg-cmd" fill="#C084FC">/fix &lt;code&gt;</text>
</g>
<!-- Cmd 3: /restart -->
<g transform="translate(235, 0)">
<rect width="95" height="32" rx="6" fill="#0B132B" stroke="#10B981" stroke-width="1"/>
<text x="12" y="20" class="tg-cmd" fill="#34D399">/restart</text>
</g>
<!-- Cmd 4: /status -->
<g transform="translate(340, 0)">
<rect width="85" height="32" rx="6" fill="#0B132B" stroke="#F59E0B" stroke-width="1"/>
<text x="12" y="20" class="tg-cmd" fill="#FBBF24">/status</text>
</g>
<!-- Cmd 5: /backup -->
<g transform="translate(435, 0)">
<rect width="90" height="32" rx="6" fill="#0B132B" stroke="#64748B" stroke-width="1"/>
<text x="12" y="20" class="tg-cmd" fill="#94A3B8">/backup</text>
</g>
</g>
<!-- Right Floating HUD Status Widgets -->
<g transform="translate(850, 25)">
<!-- Widget: Telegram Bot Online -->
<g transform="translate(0, 0)">
<rect width="140" height="32" rx="6" fill="#0B132B" stroke="#10B981" stroke-width="1"/>
<circle cx="14" cy="16" r="3.5" fill="#10B981" class="tg-dot"/>
<text x="26" y="20" class="tg-status">BOT ACTIVE</text>
</g>
<!-- Widget: Ping RTT -->
<g transform="translate(150, 0)">
<rect width="130" height="32" rx="6" fill="#0B132B" stroke="#38BDF8" stroke-width="1"/>
<text x="12" y="20" class="tg-btn-txt" fill="#38BDF8">RTT: 18ms</text>
<circle cx="115" cy="16" r="3.5" fill="#38BDF8"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

+111
View File
@@ -0,0 +1,111 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 150" width="100%" height="100%">
<defs>
<radialGradient id="wd-bg" cx="50%" cy="50%" r="75%">
<stop offset="0%" stop-color="#1E1B4B" stop-opacity="0.35"/>
<stop offset="60%" stop-color="#0F172A" stop-opacity="0.9"/>
<stop offset="100%" stop-color="#030712" stop-opacity="0.98"/>
</radialGradient>
<linearGradient id="wd-border" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#10B981" stop-opacity="0.3"/>
<stop offset="50%" stop-color="#34D399" stop-opacity="0.8"/>
<stop offset="100%" stop-color="#00F0FF" stop-opacity="0.3"/>
</linearGradient>
<filter id="wd-glow" filterUnits="userSpaceOnUse" x="0" y="0" width="1200" height="150">
<feGaussianBlur stdDeviation="3" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<style>
@keyframes rotateRadar {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes pulseWdDot {
0%, 100% { transform: scale(1); opacity: 0.9; }
50% { transform: scale(1.3); opacity: 0.3; }
}
@keyframes wdStreamFlow {
0% { stroke-dashoffset: 120; }
100% { stroke-dashoffset: 0; }
}
.radar-sweep { transform-origin: 1110px 75px; animation: rotateRadar 6s linear infinite; }
.wd-dot { animation: pulseWdDot 1.8s ease-in-out infinite; }
.wd-stream { stroke-dasharray: 12 24; animation: wdStreamFlow 2.5s linear infinite; }
.wd-title { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 800; font-size: 15px; fill: #FFFFFF; }
.wd-desc { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-weight: 500; font-size: 12px; fill: #94A3B8; }
.wd-tag { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11px; font-weight: 700; fill: #10B981; }
.wd-subtag { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 10px; font-weight: 600; fill: #94A3B8; }
</style>
<!-- Container Box -->
<rect width="1200" height="150" rx="14" fill="url(#wd-bg)" stroke="url(#wd-border)" stroke-width="1.5"/>
<!-- Left Header with Shield Icon -->
<g transform="translate(35, 25)">
<rect width="44" height="44" rx="10" fill="#047857" fill-opacity="0.25" stroke="#10B981" stroke-width="1.2"/>
<text x="11" y="29" font-size="22">🛡️</text>
<text x="56" y="20" class="wd-title">Autonomous Watchdog &amp; Resilience Subsystem</text>
<text x="56" y="38" class="wd-desc">Непрерывный мониторинг каждые 5-15 секунд: защита от утечек памяти, DNS-петель и сбоев питания</text>
</g>
<!-- Animated Connection Stream -->
<g transform="translate(35, 80)">
<line x1="0" y1="28" x2="1000" y2="28" stroke="#1E293B" stroke-width="1.5"/>
<line x1="0" y1="28" x2="1000" y2="28" stroke="#10B981" stroke-width="2" class="wd-stream" filter="url(#wd-glow)"/>
</g>
<!-- 4 Architectural Protection Badges -->
<g transform="translate(35, 95)">
<!-- Badge 1: Atomic tmp+mv -->
<g transform="translate(0, 0)">
<rect width="165" height="34" rx="6" fill="#0B132B" stroke="#10B981" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#10B981" class="wd-dot"/>
<text x="24" y="16" class="wd-tag">ATOMIC WRITE</text>
<text x="24" y="28" class="wd-subtag">tmp + mv Safe Configs</text>
</g>
<!-- Badge 2: Loop Guard -->
<g transform="translate(180, 0)">
<rect width="175" height="34" rx="6" fill="#0B132B" stroke="#38BDF8" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#38BDF8" class="wd-dot"/>
<text x="24" y="16" class="wd-tag" fill="#38BDF8">LOOP PREVENTION</text>
<text x="24" y="28" class="wd-subtag">Max 3 restarts / 10 min</text>
</g>
<!-- Badge 3: GOMEMLIMIT OOM -->
<g transform="translate(370, 0)">
<rect width="180" height="34" rx="6" fill="#0B132B" stroke="#C084FC" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#C084FC" class="wd-dot"/>
<text x="24" y="16" class="wd-tag" fill="#C084FC">OOM WATCHDOG</text>
<text x="24" y="28" class="wd-subtag">Dynamic GOMEMLIMIT</text>
</g>
<!-- Badge 4: Hot Reload -->
<g transform="translate(565, 0)">
<rect width="165" height="34" rx="6" fill="#0B132B" stroke="#F59E0B" stroke-opacity="0.5" stroke-width="1"/>
<circle cx="12" cy="17" r="3" fill="#F59E0B" class="wd-dot"/>
<text x="24" y="16" class="wd-tag" fill="#FBBF24">HOT-RELOAD</text>
<text x="24" y="28" class="wd-subtag">Zero TCP Dropped</text>
</g>
</g>
<!-- Right Radar Scanner Scope -->
<g transform="translate(1110, 75)">
<circle r="36" fill="#090E1A" stroke="#10B981" stroke-opacity="0.4" stroke-width="1.5"/>
<circle r="24" fill="none" stroke="#10B981" stroke-opacity="0.25" stroke-width="1" stroke-dasharray="4 4"/>
<circle r="12" fill="none" stroke="#10B981" stroke-opacity="0.4" stroke-width="1"/>
<line x1="-36" y1="0" x2="36" y2="0" stroke="#1E293B" stroke-width="1"/>
<line x1="0" y1="-36" x2="0" y2="36" stroke="#1E293B" stroke-width="1"/>
<!-- Radar Line Beam -->
<line x1="0" y1="0" x2="36" y2="0" stroke="#10B981" stroke-width="2" class="radar-sweep" filter="url(#wd-glow)"/>
<circle cx="0" cy="0" r="3" fill="#34D399"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB