summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoryu-co <bot@soryu.co>2026-05-06 13:56:35 +0000
committersoryu-co <bot@soryu.co>2026-05-06 13:56:35 +0000
commit697e6d842cf662f33e0b679859c2fc9365222d2d (patch)
treea4601b1dc280e08d277a8ca959912856acab7176
parent9948609a01e8d132a030b82694413d67aa6be822 (diff)
downloadsoryu-697e6d842cf662f33e0b679859c2fc9365222d2d.tar.gz
soryu-697e6d842cf662f33e0b679859c2fc9365222d2d.zip
Replace PC-98 character image with tactical observability mesh SVG
- New /public/mission-tactical.svg (~9KB, license-clean, hand-crafted): amber wireframe globe + magenta mesh links, GitS:SAC-style HUD chrome (corner brackets, scanlines, telemetry strip, NODE-001 TYO label, pulsing origin node), kanji watermark. - Uses CSS palette vars (amber #e8b87a / magenta #d96a8a / cyan #9ad7e0). - .mission-image switched to object-fit:contain with a dark fill so the vector renders fully and never crops; pc98 mission-pan animation is killed for the SVG path.
-rw-r--r--frontend/public/mission-tactical.svg210
-rw-r--r--frontend/src/components/LandingPage.tsx2
-rw-r--r--frontend/src/styles/heisei.css15
3 files changed, 225 insertions, 2 deletions
diff --git a/frontend/public/mission-tactical.svg b/frontend/public/mission-tactical.svg
new file mode 100644
index 0000000..cd4095a
--- /dev/null
+++ b/frontend/public/mission-tactical.svg
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600" role="img" aria-label="Tactical observability mesh"
+ font-family="'JetBrains Mono', 'Inter', monospace">
+ <defs>
+ <!-- Background gradient: deep dusk -> night -->
+ <radialGradient id="bgGlow" cx="50%" cy="55%" r="65%">
+ <stop offset="0%" stop-color="#1a2548"/>
+ <stop offset="55%" stop-color="#0e1530"/>
+ <stop offset="100%" stop-color="#070a18"/>
+ </radialGradient>
+ <!-- Globe fill: very subtle inner depth -->
+ <radialGradient id="globeFill" cx="38%" cy="36%" r="65%">
+ <stop offset="0%" stop-color="rgba(232,184,122,0.08)"/>
+ <stop offset="60%" stop-color="rgba(217,106,138,0.04)"/>
+ <stop offset="100%" stop-color="rgba(11,17,36,0)"/>
+ </radialGradient>
+ <!-- Soft glow for active nodes -->
+ <radialGradient id="nodeGlow">
+ <stop offset="0%" stop-color="#e8b87a" stop-opacity="0.85"/>
+ <stop offset="60%" stop-color="#e8b87a" stop-opacity="0.10"/>
+ <stop offset="100%" stop-color="#e8b87a" stop-opacity="0"/>
+ </radialGradient>
+ <radialGradient id="nodeMag">
+ <stop offset="0%" stop-color="#d96a8a" stop-opacity="0.95"/>
+ <stop offset="60%" stop-color="#d96a8a" stop-opacity="0.10"/>
+ <stop offset="100%" stop-color="#d96a8a" stop-opacity="0"/>
+ </radialGradient>
+ <!-- Scanline pattern -->
+ <pattern id="scan" width="2" height="3" patternUnits="userSpaceOnUse">
+ <rect width="2" height="3" fill="rgba(0,0,0,0)"/>
+ <rect width="2" height="1" fill="rgba(240,234,223,0.025)"/>
+ </pattern>
+ <!-- Pulse animation for the central reticle -->
+ <filter id="softGlow" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="1.6" result="b"/>
+ <feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
+ </filter>
+ </defs>
+
+ <!-- Backdrop -->
+ <rect width="600" height="600" fill="url(#bgGlow)"/>
+ <rect width="600" height="600" fill="url(#scan)"/>
+
+ <!-- Outer hairline frame + corner brackets (matches Heisei UI language) -->
+ <g stroke="rgba(240,234,223,0.55)" fill="none" stroke-width="1">
+ <!-- corner brackets, 18px legs -->
+ <path d="M14,14 L14,32 M14,14 L32,14"/>
+ <path d="M586,14 L568,14 M586,14 L586,32"/>
+ <path d="M14,586 L14,568 M14,586 L32,586"/>
+ <path d="M586,586 L568,586 M586,586 L586,568"/>
+ </g>
+ <rect x="14" y="14" width="572" height="572" fill="none"
+ stroke="rgba(240,234,223,0.10)" stroke-width="0.5"/>
+
+ <!-- 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>
+ </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>
+ <text x="568" y="54" text-anchor="end">v1.0.0 / LIVE</text>
+ </g>
+
+ <!-- Faint grid behind the globe -->
+ <g stroke="rgba(154,215,224,0.08)" stroke-width="0.5" fill="none">
+ <line x1="60" y1="300" x2="540" y2="300"/>
+ <line x1="300" y1="60" x2="300" y2="540"/>
+ </g>
+
+ <!-- ============ GLOBE ============ -->
+ <!-- Centered at (300,320), radius 200 -->
+ <g transform="translate(300 320)">
+ <!-- Filled disc -->
+ <circle r="200" fill="url(#globeFill)"/>
+ <!-- Equator + main rings (orthographic projection) -->
+ <g fill="none" stroke="rgba(232,184,122,0.55)" stroke-width="1.1">
+ <circle r="200"/>
+ </g>
+ <!-- Latitude ellipses (front-only effect via stroke-dasharray on back) -->
+ <g fill="none" stroke="rgba(232,184,122,0.42)" stroke-width="0.7">
+ <ellipse rx="200" ry="170"/>
+ <ellipse rx="200" ry="120"/>
+ <ellipse rx="200" ry="60"/>
+ <ellipse rx="200" ry="0.4"/> <!-- equator line emphasis -->
+ </g>
+ <!-- Longitude ellipses (rotated) -->
+ <g fill="none" stroke="rgba(232,184,122,0.42)" stroke-width="0.7">
+ <ellipse rx="60" ry="200"/>
+ <ellipse rx="120" ry="200"/>
+ <ellipse rx="170" ry="200"/>
+ </g>
+ <!-- Tilted accent rings for depth -->
+ <g fill="none" stroke="rgba(217,106,138,0.55)" stroke-width="0.9"
+ transform="rotate(-22)">
+ <ellipse rx="200" ry="80"/>
+ </g>
+ <g fill="none" stroke="rgba(154,215,224,0.45)" stroke-width="0.7"
+ transform="rotate(28)">
+ <ellipse rx="200" ry="40"/>
+ </g>
+
+ <!-- ============ 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)"/>
+ </g>
+
+ <!-- Active nodes (amber primary) -->
+ <g>
+ <!-- Tokyo (origin / pulse) -->
+ <circle cx="60" cy="-90" r="14" fill="url(#nodeGlow)"/>
+ <circle cx="60" cy="-90" r="3" fill="#e8b87a"/>
+ <circle cx="60" cy="-90" r="3" fill="none" stroke="#e8b87a" stroke-width="1">
+ <animate attributeName="r" values="3;18;3" dur="3s" repeatCount="indefinite"/>
+ <animate attributeName="opacity" values="1;0;1" dur="3s" repeatCount="indefinite"/>
+ </circle>
+
+ <!-- Other nodes -->
+ <circle cx="-120" cy="-70" r="10" fill="url(#nodeGlow)"/>
+ <circle cx="-120" cy="-70" r="2.4" fill="#e8b87a"/>
+
+ <circle cx="150" cy="60" r="12" fill="url(#nodeMag)"/>
+ <circle cx="150" cy="60" r="2.6" fill="#d96a8a"/>
+
+ <circle cx="-30" cy="130" r="9" fill="url(#nodeGlow)"/>
+ <circle cx="-30" cy="130" r="2.2" fill="#e8b87a"/>
+
+ <!-- Smaller relays -->
+ <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"/>
+ </g>
+ </g>
+
+ <!-- Node label (Tokyo origin) -->
+ <g font-size="7.5" letter-spacing="1.5" fill="rgba(240,234,223,0.78)">
+ <line x1="60" y1="-90" x2="120" y2="-130" stroke="rgba(232,184,122,0.55)" stroke-width="0.6"/>
+ <text x="124" y="-127" fill="#e8b87a">NODE-001 · TYO</text>
+ <text x="124" y="-117">42ms · 99.998%</text>
+ </g>
+ </g>
+
+ <!-- Concentric reticle around the globe -->
+ <g fill="none" stroke="rgba(232,184,122,0.30)" stroke-width="0.6" stroke-dasharray="2 4">
+ <circle r="225"/>
+ </g>
+ <g fill="none" stroke="rgba(232,184,122,0.18)" stroke-width="0.5">
+ <circle r="245"/>
+ </g>
+ </g>
+
+ <!-- ============ HUD CROSSHAIR (centered) ============ -->
+ <g stroke="rgba(232,184,122,0.55)" stroke-width="0.8" fill="none">
+ <line x1="300" y1="100" x2="300" y2="130"/>
+ <line x1="300" y1="510" x2="300" y2="540"/>
+ <line x1="80" y1="320" x2="110" y2="320"/>
+ <line x1="490" y1="320" x2="520" y2="320"/>
+ </g>
+
+ <!-- ============ Bottom telemetry strip ============ -->
+ <g transform="translate(0 555)">
+ <!-- Mini bar chart -->
+ <g fill="#9ad7e0" opacity="0.7">
+ <rect x="32" y="0" width="3" height="14"/>
+ <rect x="38" y="4" width="3" height="10"/>
+ <rect x="44" y="-2" width="3" height="16"/>
+ <rect x="50" y="2" width="3" height="12"/>
+ <rect x="56" y="-4" width="3" height="18"/>
+ <rect x="62" y="0" width="3" height="14"/>
+ <rect x="68" y="-3" width="3" height="17"/>
+ <rect x="74" y="1" width="3" height="13"/>
+ <rect x="80" y="-5" width="3" height="19"/>
+ <rect x="86" y="-1" width="3" height="15"/>
+ <rect x="92" y="3" width="3" height="11"/>
+ <rect x="98" y="-6" width="3" height="20"/>
+ <rect x="104" y="-2" width="3" height="16"/>
+ <rect x="110" y="0" width="3" height="14"/>
+ </g>
+ <text x="32" y="32" font-size="8" letter-spacing="1.6" fill="rgba(240,234,223,0.45)">TELEMETRY · 1m</text>
+
+ <!-- Stat blocks -->
+ <g font-size="9" letter-spacing="1.6" fill="rgba(240,234,223,0.7)">
+ <text x="240" y="6" fill="rgba(154,215,224,0.85)">VELOCITY</text>
+ <text x="240" y="22" fill="#f0eadf" font-size="14" letter-spacing="0.5">603 km/h</text>
+
+ <text x="380" y="6" fill="rgba(154,215,224,0.85)">ENERGY</text>
+ <text x="380" y="22" fill="#f0eadf" font-size="14" letter-spacing="0.5">32.0 MJ</text>
+
+ <text x="500" y="6" fill="rgba(154,215,224,0.85)">UPTIME</text>
+ <text x="500" y="22" fill="#e8b87a" font-size="14" letter-spacing="0.5">99.998%</text>
+ </g>
+ </g>
+
+ <!-- Subtle vertical kanji watermark on the right -->
+ <g font-family="'Noto Serif JP', serif" font-size="11" letter-spacing="6"
+ fill="rgba(240,234,223,0.18)" writing-mode="tb">
+ <text x="572" y="120">観測</text>
+ </g>
+</svg>
diff --git a/frontend/src/components/LandingPage.tsx b/frontend/src/components/LandingPage.tsx
index 708cbb1..2c543a6 100644
--- a/frontend/src/components/LandingPage.tsx
+++ b/frontend/src/components/LandingPage.tsx
@@ -176,7 +176,7 @@ export function LandingPage({ onLogin }: LandingPageProps) {
{activePanel === 'mission' ? (
<div className="mission-screen" role="region" aria-label="Mission">
<h1 className="mission-headline">Building real‑time systems for mission-critical observability and surveillance </h1>
- <img src="/PC98Doukuusei.webp" alt="Mission montage" className="mission-image" />
+ <img src="/mission-tactical.svg" alt="Tactical observability mesh" className="mission-image" />
<p className="mission-paragraph">
We deliver low‑latency streaming & infrastructure that turns live data into
reliable, secure insight. Target selection, monitoring and full end to end observability
diff --git a/frontend/src/styles/heisei.css b/frontend/src/styles/heisei.css
index 2500ff8..c56791a 100644
--- a/frontend/src/styles/heisei.css
+++ b/frontend/src/styles/heisei.css
@@ -442,10 +442,13 @@ body { background: var(--hz-night); color: var(--hz-ink); }
box-shadow:
0 24px 60px -24px rgba(8, 10, 24, 0.85),
0 0 0 1px var(--hz-line);
- filter: saturate(0.85) brightness(0.92);
+ filter: none; /* tactical SVG renders flat */
height: clamp(180px, 36vh, 360px);
width: 100%;
display: block;
+ object-fit: contain; /* show full reticle, no crop */
+ background: rgba(11, 17, 36, 0.6);
+ animation: none; /* kill pc98 mission-pan */
}
/* ----- Desktop (≥1025px): image on the left, copy on the right ----- */
@@ -472,6 +475,16 @@ body { background: var(--hz-night); color: var(--hz-ink); }
object-fit: cover;
/* Pc98 sets `grid-area: hero` etc — clear leftover row hints */
grid-area: auto;
+ /* Tactical SVG: render whole frame, no pan/crop, no filter */
+ animation: none !important;
+ filter: none !important;
+ background: rgba(11, 17, 36, 0.6);
+ object-fit: contain;
+ object-position: center;
+ padding: 0;
+ box-shadow:
+ 0 24px 60px -24px rgba(8, 10, 24, 0.85),
+ 0 0 0 1px var(--hz-line);
}
/* Right-column text: each block owns its own accent rule */
.mission-screen .mission-headline,