summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontend/public/logo/makima-logo.svg7
-rw-r--r--frontend/src/components/LandingPage.tsx58
-rw-r--r--frontend/src/styles/mobile.css4
-rw-r--r--frontend/src/styles/pc98.css44
4 files changed, 98 insertions, 15 deletions
diff --git a/frontend/public/logo/makima-logo.svg b/frontend/public/logo/makima-logo.svg
new file mode 100644
index 0000000..4872d43
--- /dev/null
+++ b/frontend/public/logo/makima-logo.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
+ <circle cx="12" cy="12" r="10" stroke="#003366" stroke-width="2" />
+ <circle cx="12" cy="12" r="7" stroke="#003366" stroke-width="1.6" />
+ <circle cx="12" cy="12" r="4" stroke="#003366" stroke-width="1.6" />
+ <circle cx="12" cy="12" r="1.6" fill="#003366" />
+</svg>
diff --git a/frontend/src/components/LandingPage.tsx b/frontend/src/components/LandingPage.tsx
index ea8dfbc..f22c1bd 100644
--- a/frontend/src/components/LandingPage.tsx
+++ b/frontend/src/components/LandingPage.tsx
@@ -13,8 +13,8 @@ export function LandingPage({ onLogin }: LandingPageProps) {
const [velocity, setVelocity] = useState(0)
const [energy, setEnergy] = useState(0)
const [ramped, setRamped] = useState(false)
- const [pendingAction, setPendingAction] = useState<null | 'makima' | 'mission'>(null)
- const [missionMode, setMissionMode] = useState(false)
+ const [pendingAction, setPendingAction] = useState<null | 'makimaRedirect'>(null)
+ const [activePanel, setActivePanel] = useState<null | 'mission' | 'makima'>(null)
// Fade-in landing page content after mount
useEffect(() => {
@@ -79,21 +79,24 @@ export function LandingPage({ onLogin }: LandingPageProps) {
}, [])
const handleLoadingComplete = () => {
- if (pendingAction === 'makima') {
+ if (pendingAction === 'makimaRedirect') {
window.location.assign('https://makima.jp')
return
}
onLogin()
}
- const handleMakima = () => {
- setPendingAction('makima')
+ const handleLogin = () => {
+ setPendingAction('makimaRedirect')
setLoading(true)
}
const handleMission = () => {
- // Toggle screen transformation instead of modal/drawer
- setMissionMode((m) => !m)
+ setActivePanel((mode) => (mode === 'mission' ? null : 'mission'))
+ }
+
+ const handleMakimaPanel = () => {
+ setActivePanel((mode) => (mode === 'makima' ? null : 'makima'))
}
return (
@@ -148,7 +151,7 @@ export function LandingPage({ onLogin }: LandingPageProps) {
</div>
{/* Minimal overlay: masthead, issue badge, and CTA */}
- <div className={`taisho-cover ${missionMode ? 'mission-mode' : ''}`}>
+ <div className={`taisho-cover ${activePanel ? 'mission-mode' : ''}`}>
<div className="cover-backdrop" aria-hidden="true" />
<div className="cover-content">
{/* Masthead + Issue badge (kept) */}
@@ -161,7 +164,7 @@ export function LandingPage({ onLogin }: LandingPageProps) {
</div>
{/* Hero area becomes Mission content when in mission mode */}
- {missionMode ? (
+ {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" />
@@ -171,22 +174,47 @@ export function LandingPage({ onLogin }: LandingPageProps) {
to make vital decisions where it matters most.
</p>
</div>
+ ) : activePanel === 'makima' ? (
+ <div className="mission-screen makima-screen" role="region" aria-label="Makima">
+ <h1 className="mission-headline makima-headline">makima.jp | concentric listening lattice for contested domains</h1>
+ <img src="/logo/makima-logo.svg" alt="Makima concentric circle logo" className="mission-image makima-logo" />
+ <p className="mission-paragraph">
+ The makima.jp listening system fuses wideband capture, correlation, and operator tooling into a single
+ persistent layer that hears everything—terrestrial, orbital, and opportunistic—and hands it to crews
+ with zero friction. It is built to be quiet, relentless, and to surface intent faster than any human
+ watch can keep up.
+ </p>
+ <p className="mission-paragraph">
+ Value for espionage, defense, and warfare is direct: clandestine signal interception that maps networks,
+ blue-force protection through resilient spectrum awareness, and kinetic decisioning that pairs telemetry
+ with targeting in seconds. The <ruby>支配<rt>しはい</rt></ruby> operations system sits at the core, orchestrating
+ tasking, interdiction, and human review so every intercepted whisper is actionable.
+ </p>
+ <div className="mission-paragraph makima-value">
+ <strong>Operational payoffs:</strong>
+ <ul className="makima-list">
+ <li>Espionage: concentric-capture mesh and cross-correlation expose command paths, covert beacons, and exfiltration routes.</li>
+ <li>Defense: resilient horizon-to-satellite coverage spots intrusion, spectrum denial, and spoofing before they degrade mission links.</li>
+ <li>Warfare: targeting flows fuse the signal graph with effects, pushing lethal updates to crews through <ruby>支配<rt>しはい</rt></ruby> without slowing tempo.</li>
+ </ul>
+ </div>
+ </div>
) : (
<div className="hero" />
)}
- {/* CTA row spanning full width: left Mission/Contact, right Login */}
+ {/* CTA row spanning full width: left Mission/MAKIMA, right Login */}
<div className="cta-area">
<div className="cta-left">
<button className="taisho-cta" onClick={handleMission}>
- <span className="cta-text">{missionMode ? 'Close' : 'Mission'}</span>
+ <span className="cta-text">{activePanel === 'mission' ? 'Close' : 'Mission'}</span>
</button>
- <button className="taisho-cta" onClick={() => {/* placeholder contact */}}>
- <span className="cta-text">Contact</span>
+ <button className="taisho-cta" onClick={handleMakimaPanel}>
+ <span className="cta-text">{activePanel === 'makima' ? 'Close' : 'MAKIMA'}</span>
</button>
</div>
<div className="cta-right">
- <button className="taisho-cta" onClick={handleMakima}>
+ <button className="taisho-cta" onClick={handleLogin}>
<span className="cta-icon">▶</span>
<span className="cta-text">Login</span>
</button>
@@ -196,7 +224,7 @@ export function LandingPage({ onLogin }: LandingPageProps) {
</div>
{/* Bottom stats: Velocity + Energy only (hidden in mission mode) */}
- {!missionMode && (
+ {!activePanel && (
<div className="bottom-stats">
<div className="rf-stats">
<div className="rf-stat">
diff --git a/frontend/src/styles/mobile.css b/frontend/src/styles/mobile.css
index a36290c..3b2e9c8 100644
--- a/frontend/src/styles/mobile.css
+++ b/frontend/src/styles/mobile.css
@@ -46,4 +46,8 @@
}
.modern-landing-page.manga-style .issue-badge .led-heart::before { top: -3px; }
.modern-landing-page.manga-style .issue-badge .led-heart::after { left: 3px; }
+
+ .makima-logo { padding: 14px; }
+ .makima-list { gap: 4px; }
+ .makima-list li { font-size: 12px; line-height: 1.45; }
}
diff --git a/frontend/src/styles/pc98.css b/frontend/src/styles/pc98.css
index 83b9c1e..710d11a 100644
--- a/frontend/src/styles/pc98.css
+++ b/frontend/src/styles/pc98.css
@@ -1903,6 +1903,50 @@ button:focus-visible {
0% { object-position: 50% 0%; }
100% { object-position: 50% 100%; }
}
+
+.makima-screen {
+ grid-template-rows: auto auto auto;
+ gap: 14px;
+}
+
+.makima-headline {
+ color: #d6f2ff;
+ letter-spacing: 0.75px;
+}
+
+.makima-logo {
+ object-fit: contain;
+ background: radial-gradient(circle at 30% 30%, rgba(102, 204, 255, 0.16), transparent 40%), rgba(0, 16, 40, 0.65);
+ padding: 22px;
+ border: 2px solid #66ccff;
+ box-shadow: 0 6px 18px rgba(0,0,0,0.45), inset 0 0 0 1px rgba(102, 204, 255, 0.25);
+}
+
+.makima-screen .mission-paragraph {
+ color: #e2f6ff;
+}
+
+.makima-value strong {
+ display: block;
+ margin-bottom: 6px;
+ color: #9fe3ff;
+ letter-spacing: 0.4px;
+ font-size: 13px;
+}
+
+.makima-list {
+ margin: 8px 0 0;
+ padding-left: 18px;
+ display: grid;
+ gap: 6px;
+}
+
+.makima-list li {
+ color: #d8f3ff;
+ font-family: 'MS Gothic', monospace;
+ font-size: 13px;
+ line-height: 1.6;
+}
.hero-frame {
position: relative;
width: 100%;