Files
Space-Game/archive/legacy-static/js/pages/social.js
francy51 316a44661b Restructure into pnpm monorepo with game shell, docs, and SpacetimeDB backend
- Restructure flat static prototype into pnpm workspace monorepo
- apps/game: playable shell with R3F 3D scene, HUD, SpacetimeDB connection
- apps/docs: design docs and prototypes
- apps/site: landing page
- packages/ui: shared Button and Panel primitives
- services/spacetimedb: backend module (9 tables, 11 reducers)
- Archive legacy static files to archive/legacy-static/
- Game loop: connect, undock, target, approach, dock, mine, sell
- Add pnpm-workspace.yaml, tsconfig.base.json, spacetime.json
2026-05-31 17:56:56 -04:00

591 lines
38 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
window.GDD = window.GDD || {};
function SocialPage() {
const [activeSection, setActiveSection] = React.useState('progression');
const skillCategories = [
{
name: 'Combat',
color: 'var(--red)',
skills: ['Gunnery', 'Missiles', 'Shield Operation', 'Armor Tanking', 'Electronic Warfare'],
xpSource: 'Dealing damage, destroying NPCs, completing combat missions',
},
{
name: 'Industry',
color: 'var(--accent)',
skills: ['Mining', 'Refining', 'Manufacturing', 'Blueprint Research', 'Resource Processing'],
xpSource: 'Mining cycles, refining batches, manufactured items, research jobs',
},
{
name: 'Navigation',
color: 'var(--cyan)',
skills: ['Warp Drive Operation', 'Afterburner', 'Evasive Maneuvering', 'Capital Navigation'],
xpSource: 'Distance warped, systems visited, successful evasion from combat',
},
{
name: 'Trade',
color: 'var(--green)',
skills: ['Market Analysis', 'Broker Relations', 'Hauling', 'Contracting', 'Regional Trading'],
xpSource: 'Completed trades, market orders filled, cargo hauled between systems',
},
{
name: 'Leadership',
color: 'var(--purple)',
skills: ['Fleet Command', 'Wing Command', 'AI Coordination', 'Crew Management'],
xpSource: 'Fleet actions, AI crew task completions, group mission success (post-MVP)',
},
];
const chatChannels = [
{ name: 'Local', range: 'Current system', delay: 'Instant', description: 'Everyone in the same star system sees messages immediately. Core social channel.', color: 'var(--fg-bright)' },
{ name: 'Private Message', range: 'Based on distance', delay: 'Light-speed delayed', description: 'Direct messages to another player. Messages arrive after a delay proportional to light-years between systems. Across the galaxy = minutes of delay.', color: 'var(--cyan)' },
{ name: 'Trade', range: 'Station / Region', delay: 'Instant at station, delayed region-wide', description: 'Buy/sell offers, price checks, trade negotiations. Station-local is instant; regional relay has a 30s delay.', color: 'var(--green)' },
];
const bountyTiers = [
{ tier: 'Petty', threshold: '500 ISK', reward: '10% of bounty', visibility: 'Current system only', color: 'var(--muted)' },
{ tier: 'Standard', threshold: '5,000 ISK', reward: '15% of bounty', visibility: 'Current region (constellation cluster)', color: 'var(--cyan)' },
{ tier: 'Dangerous', threshold: '50,000 ISK', reward: '20% of bounty + kill bonus', visibility: 'All regions (galaxy-wide board)', color: 'var(--accent)' },
{ tier: 'Most Wanted', threshold: '500,000 ISK', reward: '25% + unique cosmetic reward', visibility: 'Galaxy-wide + leaderboard', color: 'var(--red)' },
];
return (
<div className="content-inner">
<h1 style={{ marginBottom: '8px' }}>Progression & Social</h1>
<p style={{ color: 'var(--fg-dim)', fontSize: '0.95rem', maxWidth: '680px' }}>
XP-based progression across five skill categories. Chat ranges from instant local to
light-speed-delayed private messages. Bounty system creates emergent player-driven justice
and piracy consequences. Designed for ~3-hour play sessions with meaningful progression per session.
</p>
{/* Tab navigation */}
<div style={{ display: 'flex', gap: 'var(--sp-2)', marginBottom: 'var(--sp-6)' }}>
{[
{ id: 'progression', label: 'XP & Skills' },
{ id: 'chat', label: 'Chat & Comms' },
{ id: 'bounty', label: 'Bounty System' },
{ id: 'waypoints', label: 'Waypoints' },
{ id: 'corps', label: 'Corporations' },
].map(t => (
<button key={t.id} className={`btn btn-sm${activeSection === t.id ? ' btn-primary' : ''}`}
onClick={() => setActiveSection(t.id)}>{t.label}</button>
))}
</div>
{/* PROGRESSION */}
{activeSection === 'progression' && (
<>
<div className="stat-grid">
<div className="stat-card">
<div className="stat-value" style={{ color: 'var(--accent)' }}>Action-based</div>
<div className="stat-label">XP Model</div>
</div>
<div className="stat-card">
<div className="stat-value" style={{ color: 'var(--cyan)' }}>5 Categories</div>
<div className="stat-label">Skill Trees</div>
</div>
<div className="stat-card">
<div className="stat-value" style={{ color: 'var(--green)' }}>~3 hours</div>
<div className="stat-label">Session Target</div>
</div>
<div className="stat-card">
<div className="stat-value" style={{ color: 'var(--purple)' }}>V Levels</div>
<div className="stat-label">Per Skill</div>
</div>
</div>
<div className="callout callout-info" style={{ marginBottom: 'var(--sp-5)' }}>
<strong>Design intent:</strong> XP comes from doing things, not waiting. A 3-hour mining session
should unlock at least one meaningful skill upgrade. Combat and trade have comparable XP rates
so no playstyle feels punished.
</div>
<div className="section-header">
<span className="section-num">SOC-SKL</span>
<h2 style={{ margin: 0 }}>Skill Categories</h2>
</div>
{skillCategories.map((cat, i) => (
<div key={i} className="card" style={{ borderLeft: `3px solid ${cat.color}`, marginBottom: 'var(--sp-4)' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 'var(--sp-3)', marginBottom: 'var(--sp-3)' }}>
<h4 style={{ color: cat.color, margin: 0 }}>{cat.name}</h4>
</div>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--sp-1)', marginBottom: 'var(--sp-3)' }}>
{cat.skills.map((s, j) => (
<span key={j} className="pill" style={{ background: 'var(--surface-raised)', color: cat.color, border: `1px solid ${cat.color}40`, fontSize: '0.7rem' }}>
{s}
</span>
))}
</div>
<div style={{ fontSize: '0.82rem', color: 'var(--fg-dim)' }}>
<strong style={{ color: 'var(--muted)' }}>XP source:</strong> {cat.xpSource}
</div>
</div>
))}
<div className="section-header" style={{ marginTop: 'var(--sp-6)' }}>
<span className="section-num">SOC-LVL</span>
<h2 style={{ margin: 0 }}>Level Progression</h2>
</div>
<div className="card card-accent">
<h4 style={{ marginBottom: 'var(--sp-4)' }}>XP Curve (per skill)</h4>
<div style={{ overflowX: 'auto' }}>
<table className="data-table">
<thead>
<tr>
<th>Level</th>
<th>Cumulative XP</th>
<th>Approx. Active Play</th>
<th>Typical Unlock</th>
</tr>
</thead>
<tbody>
<tr><td style={{ color: 'var(--muted)' }}>I</td><td className="mono">100</td><td className="mono">~15 min</td><td style={{ color: 'var(--fg-dim)' }}>Basic modules, rookie ships</td></tr>
<tr><td style={{ color: 'var(--green)' }}>II</td><td className="mono">500</td><td className="mono">~1 hour</td><td style={{ color: 'var(--fg-dim)' }}>Standard modules, refining</td></tr>
<tr><td style={{ color: 'var(--cyan)' }}>III</td><td className="mono">2,000</td><td className="mono">~3 hours</td><td style={{ color: 'var(--fg-dim)' }}>T2 modules, cruisers, manufacturing</td></tr>
<tr><td style={{ color: 'var(--purple)' }}>IV</td><td className="mono">8,000</td><td className="mono">~8 hours</td><td style={{ color: 'var(--fg-dim)' }}>Advanced fittings, battlecruisers</td></tr>
<tr><td style={{ color: 'var(--accent)' }}>V</td><td className="mono">32,000</td><td className="mono">~20 hours</td><td style={{ color: 'var(--fg-dim)' }}>Battleships, T2 ships, mastery</td></tr>
</tbody>
</table>
</div>
</div>
<div className="section-header" style={{ marginTop: 'var(--sp-8)' }}>
<span className="section-num">SOC-RESPEC</span>
<h2 style={{ margin: 0 }}>Respec (Skill Reallocation)</h2>
</div>
<div className="callout callout-info" style={{ marginBottom: 'var(--sp-5)' }}>
<strong>Mistakes should be fixable, but not free.</strong> Players can reallocate (respec) their skill points,
returning XP from one skill and applying it to another. This prevents permanent lock-in from early uninformed
decisions while making frequent respeccing uneconomical.
</div>
<div className="grid-2" style={{ marginBottom: 'var(--sp-6)' }}>
<div className="card" style={{ borderLeft: '3px solid var(--accent)' }}>
<h4 style={{ color: 'var(--accent)' }}>Respec Mechanics</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li><strong style={{ color: 'var(--fg)' }}>Cost:</strong> 20% XP penalty on reallocated points. Respeccing 1,000 XP returns 800 XP to redistribute.</li>
<li><strong style={{ color: 'var(--fg)' }}>Cooldown:</strong> 7 real-world days between respeccs. Cannot be bypassed.</li>
<li><strong style={{ color: 'var(--fg)' }}>Scope:</strong> Full respec (all skills) or single-skill respec. Full respec costs 30% instead of 20%.</li>
<li><strong style={{ color: 'var(--fg)' }}>Location:</strong> Must be docked at a station with a "Neural Remapping" facility (not all stations have this).</li>
<li><strong style={{ color: 'var(--fg)' }}>Preview:</strong> Before confirming, the respec UI shows the exact XP loss and resulting skill levels. No surprises.</li>
</ul>
</div>
<div className="card" style={{ borderLeft: '3px solid var(--cyan)' }}>
<h4 style={{ color: 'var(--cyan)' }}>Design Rationale</h4>
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-3) 0' }}>
The 20% cost ensures that respeccing is a meaningful decision, not a free toggle. A player who respeccs
from Mining to Gunnery loses 200 of their 1,000 mining XP they can try combat, but they've paid for the
privilege. The cooldown prevents rapid role-switching and preserves the value of specialization.
Players who plan their skill progression carefully are rewarded with more total XP than those who respec frequently.
</p>
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.72rem', color: 'var(--muted)' }}>
Example: Mining III (2,000 XP) \u2192 respec \u2192 receive 1,600 XP \u2192 invest in Gunnery (now Gunnery II at 500 XP + 1,100 banked)
</div>
</div>
</div>
</>
)}
{/* CHAT & COMMS */}
{activeSection === 'chat' && (
<>
<div className="section-header">
<span className="section-num">SOC-COM</span>
<h2 style={{ margin: 0 }}>Communication System</h2>
</div>
<p style={{ color: 'var(--fg-dim)', fontSize: '0.9rem', maxWidth: '680px', marginBottom: 'var(--sp-5)' }}>
Communication range is physical — messages travel at light speed. Local chat in the same system
is instant. Private messages to someone across the galaxy are delayed by minutes. This creates
meaningful tactical information asymmetry and makes relay networks valuable.
</p>
{chatChannels.map((ch, i) => (
<div key={i} className="card" style={{ borderLeft: `3px solid ${ch.color}`, marginBottom: 'var(--sp-4)' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 'var(--sp-3)', marginBottom: 'var(--sp-3)' }}>
<h4 style={{ color: ch.color, margin: 0 }}>{ch.name}</h4>
<span className="pill" style={{ background: 'var(--surface-raised)', color: 'var(--fg-dim)', border: '1px solid var(--border)', fontSize: '0.7rem' }}>
{ch.range}
</span>
</div>
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-2) 0' }}>{ch.description}</p>
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.75rem', color: 'var(--muted)' }}>
Delay: {ch.delay}
</div>
</div>
))}
<div className="section-header" style={{ marginTop: 'var(--sp-6)' }}>
<span className="section-num">SOC-PHYS</span>
<h2 style={{ margin: 0 }}>Light-Speed Delay Mechanics</h2>
</div>
<div className="card card-accent">
<h4 style={{ marginBottom: 'var(--sp-4)' }}>Message Travel Time</h4>
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', color: 'var(--fg-dim)', lineHeight: 2 }}>
<strong style={{ color: 'var(--fg)' }}>Same system:</strong> 0s (quantum relay)<br/>
<strong style={{ color: 'var(--fg)' }}>Adjacent system (1 gate):</strong> ~2s<br/>
<strong style={{ color: 'var(--fg)' }}>5 jumps:</strong> ~10s<br/>
<strong style={{ color: 'var(--fg)' }}>20 jumps:</strong> ~45s<br/>
<strong style={{ color: 'var(--fg)' }}>Across galaxy:</strong> ~23 minutes<br/>
<br/>
<span style={{ color: 'var(--muted)' }}>Formula: baseDelay × sqrt(gateDistance) × 2s</span>
</div>
</div>
<div className="grid-2" style={{ marginTop: 'var(--sp-5)' }}>
<div className="card">
<h4 style={{ color: 'var(--accent)' }}>Strategic implications</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li>Fleet commanders near the front have better intel</li>
<li>Market data is delayed — arbitrage exists between regions</li>
<li>Distress calls from deep null-sec arrive minutes late</li>
<li>Players can set up communication relay networks</li>
</ul>
</div>
<div className="card">
<h4 style={{ color: 'var(--cyan)' }}>Post-MVP channels</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li><strong>Corporation</strong> — instant for corp members (post-MVP)</li>
<li><strong>Fleet</strong> — instant for fleet members (post-MVP)</li>
<li><strong>Relay Beacons</strong> — player-placed structures that boost range</li>
<li><strong>Alliance</strong> — meta-corp channels (far future)</li>
</ul>
</div>
</div>
</>
)}
{/* BOUNTY SYSTEM */}
{activeSection === 'bounty' && (
<>
<div className="section-header">
<span className="section-num">SOC-BNT</span>
<h2 style={{ margin: 0 }}>Bounty System</h2>
</div>
<p style={{ color: 'var(--fg-dim)', fontSize: '0.9rem', maxWidth: '680px', marginBottom: 'var(--sp-5)' }}>
Any player can place a bounty on another player. Bounties create consequences for piracy
and emergent "space justice" dynamics. Higher bounties attract more bounty hunters and
increase visibility across the galaxy.
</p>
<div style={{ overflowX: 'auto' }}>
<table className="data-table">
<thead>
<tr><th>Tier</th><th>Bounty Threshold</th><th>Hunter Reward</th><th>Visibility (Sector-Specific)</th></tr>
</thead>
<tbody>
{bountyTiers.map((tier, i) => (
<tr key={i}>
<td><span className={`pill ${i === 0 ? 'pill-green' : i === 1 ? 'pill-cyan' : i === 2 ? 'pill-amber' : 'pill-red'}`}>
{tier.tier}
</span></td>
<td className="mono">{tier.threshold}</td>
<td style={{ color: 'var(--fg-dim)' }}>{tier.reward}</td>
<td style={{ color: tier.color }}>{tier.visibility}</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="grid-2" style={{ marginTop: 'var(--sp-5)' }}>
<div className="card" style={{ borderLeft: '3px solid var(--red)' }}>
<h4 style={{ color: 'var(--red)' }}>How bounties work</h4>
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', color: 'var(--fg-dim)', lineHeight: 2 }}>
1. Player A places bounty on Player B (ISK deducted immediately)<br/>
2. Bounty pool accumulates — multiple players can contribute<br/>
3. When Player B's ship is destroyed, bounty pays out<br/>
4. Payout = percentage of bounty pool based on tier<br/>
5. Killer gets the reward; remaining pool stays active<br/>
6. If Player B stays clean for 30 days, bounty decays 10%/week
</div>
</div>
<div className="card" style={{ borderLeft: '3px solid var(--green)' }}>
<h4 style={{ color: 'var(--green)' }}>Anti-abuse rules</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li>You cannot claim your own bounty (alt check)</li>
<li>Bounty payout never exceeds ship loss value</li>
<li>Minimum bounty placement: 500 ISK (prevents spam)</li>
<li>Bounty target must have negative security status or have committed a hostile act in the last 24h (<em>see Gameplay Security Levels</em>)</li>
<li>Kill feed shows bounty collected, not total pool</li>
</ul>
</div>
</div>
<div className="callout callout-info" style={{ marginTop: 'var(--sp-5)' }}>
<strong>Sector-specific bounties:</strong> Bounty visibility is sector-based, not galaxy-wide by default. A petty bounty
in Jita is invisible in Amarr. This means a pirate can be hunted in one region while operating freely in another.
Only Dangerous and Most Wanted bounties propagate galaxy-wide. This creates regional justice ecosystems and
makes bounty hunting a localized profession rather than a galaxy-wide pursuit.
</div>
<div className="callout callout-warn" style={{ marginTop: 'var(--sp-4)' }}>
<strong>Kill feed:</strong> A galaxy-wide feed shows ship destruction events with pilot names,
ship types, system, and bounty collected. This creates reputation dynamics and emergent
storylines "CMDR Worf has been destroyed in O-WAMW, 45,000 ISK bounty collected."
</div>
</>
)}
{/* WAYPOINTS */}
{activeSection === 'waypoints' && (
<>
<div className="section-header">
<span className="section-num">SOC-NAV</span>
<h2 style={{ margin: 0 }}>Waypoints & Bookmarks</h2>
</div>
<p style={{ color: 'var(--fg-dim)', fontSize: '0.9rem', maxWidth: '680px', marginBottom: 'var(--sp-5)' }}>
Players can bookmark arbitrary locations in space and create waypoint routes for navigation.
Bookmarks are personal; waypoints can be shared. Fleet beacons are visible to all fleet members
and create tactical rally points.
</p>
<div className="grid-2">
<div className="card" style={{ borderLeft: '3px solid var(--accent)' }}>
<h4 style={{ color: 'var(--accent)' }}>Bookmarks</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li>Save any point in space as a named bookmark</li>
<li>Personal only you see them</li>
<li>Can warp to any bookmark (if in range)</li>
<li>Used for: safe spots, mining positions, ambush points, salvage sites</li>
<li>Storage limit: 100 bookmarks per player (MVP)</li>
</ul>
</div>
<div className="card" style={{ borderLeft: '3px solid var(--cyan)' }}>
<h4 style={{ color: 'var(--cyan)' }}>Waypoints & Routes</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li>Create multi-stop routes through star systems</li>
<li>Autopilot follows route automatically (slower than manual)</li>
<li>Route avoids low-sec if preference set</li>
<li>Share routes with other players (trade routes, patrol paths)</li>
<li>Optimize for: shortest, safest, or most profitable</li>
</ul>
</div>
<div className="card" style={{ borderLeft: '3px solid var(--purple)' }}>
<h4 style={{ color: 'var(--purple)' }}>Fleet Beacons</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li>Visible to all fleet members on star map</li>
<li>Create rally points and tactical positions</li>
<li>Any fleet member can create a beacon</li>
<li>Beacons expire after 1 hour or when creator leaves fleet</li>
<li>Post-MVP feature designed into data model now</li>
</ul>
</div>
<div className="card" style={{ borderLeft: '3px solid var(--green)' }}>
<h4 style={{ color: 'var(--green)' }}>Map Annotations</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li>Mark systems with notes ("pirate camp", "good mining", "friendly station")</li>
<li>Notes visible on star map hover</li>
<li>Statistics overlay: jumps/hour, ship kills, pod kills</li>
<li>Color-code systems by danger level or personal preference</li>
<li>Export/import annotations for sharing</li>
</ul>
</div>
</div>
<div className="section-header" style={{ marginTop: 'var(--sp-6)' }}>
<span className="section-num">SOC-DB</span>
<h2 style={{ margin: 0 }}>Backend Tables (New)</h2>
</div>
<div className="callout callout-info" style={{ marginBottom: 'var(--sp-5)', fontSize: '0.82rem' }}>
<strong>Canonical location:</strong> These tables are also listed in the <em>Backend Tables</em> tab, which serves as the master schema reference. The definitions here include Social-specific context.
</div>
<div style={{ overflowX: 'auto' }}>
<table className="data-table">
<thead><tr><th>Table</th><th>Purpose</th><th>Key Fields</th></tr></thead>
<tbody>
<tr>
<td><code>bookmarks</code></td>
<td style={{ color: 'var(--fg-dim)' }}>Player-saved locations</td>
<td style={{ fontSize: '0.75rem', color: 'var(--muted)' }}>bookmark_id, player_id, system_id, x/y/z, name, created_at</td>
</tr>
<tr>
<td><code>waypoints</code></td>
<td style={{ color: 'var(--fg-dim)' }}>Multi-stop routes</td>
<td style={{ fontSize: '0.75rem', color: 'var(--muted)' }}>route_id, player_id, stops (ordered system list), name, shared</td>
</tr>
<tr>
<td><code>bounties</code></td>
<td style={{ color: 'var(--fg-dim)' }}>Bounty pool per target</td>
<td style={{ fontSize: '0.75rem', color: 'var(--muted)' }}>target_player_id, total_pool, tier, last_hostile_act</td>
</tr>
<tr>
<td><code>bounty_contributions</code></td>
<td style={{ color: 'var(--fg-dim)' }}>Individual bounty payments</td>
<td style={{ fontSize: '0.75rem', color: 'var(--muted)' }}>contribution_id, target_id, contributor_id, amount, timestamp</td>
</tr>
<tr>
<td><code>kill_feed</code></td>
<td style={{ color: 'var(--fg-dim)' }}>Ship destruction events</td>
<td style={{ fontSize: '0.75rem', color: 'var(--muted)' }}>kill_id, victim_id, killer_id, ship_type, system_id, bounty_collected, timestamp</td>
</tr>
<tr>
<td><code>player_skills</code></td>
<td style={{ color: 'var(--fg-dim)' }}>XP and levels per skill</td>
<td style={{ fontSize: '0.75rem', color: 'var(--muted)' }}>player_id, skill_name, xp, level, last_action_at</td>
</tr>
<tr>
<td><code>fleet_beacons</code></td>
<td style={{ color: 'var(--fg-dim)' }}>Temporary fleet rally points</td>
<td style={{ fontSize: '0.75rem', color: 'var(--muted)' }}>beacon_id, fleet_id, creator_id, system_id, x/y/z, expires_at</td>
</tr>
</tbody>
</table>
</div>
</>
)}
{/* CORPORATIONS & TERRITORY */}
{activeSection === 'corps' && (<>
<div className="section-header">
<span className="section-num">SOC-CORP</span>
<h2 style={{ margin: 0 }}>Corporations & Territory</h2>
</div>
<div className="callout callout-info" style={{ marginBottom: 'var(--sp-5)' }}>
<strong>Era 2 feature designed now, implemented in Phase 14.</strong>
Corporations ("corps") are player organizations: persistent groups with shared wallets, hangars, roles,
and territory claims. They are the endgame social structure the reason players stay for years. This spec
establishes the design direction so the backend schema can accommodate it without breaking changes.
Implementation details may evolve, but the core model is fixed.
</div>
<h3 style={{ marginBottom: 'var(--sp-4)' }}>Corporation Lifecycle</h3>
<div className="card card-accent" style={{ marginBottom: 'var(--sp-6)' }}>
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', color: 'var(--fg-dim)', lineHeight: 2.2 }}>
<span style={{ color: 'var(--cyan)' }}>1. Found</span> Any player pays 1,000,000 founding fee. Chooses name + ticker (35 chars). Becomes CEO. Minimum 1 member.
<br/>
<span style={{ color: 'var(--green)' }}>2. Recruit</span> CEO (or Director) sends invite. Player accepts. Member appears on corp roster. Corp chat channel auto-created.
<br/>
<span style={{ color: 'var(--accent)' }}>3. Operate</span> Members contribute to corp wallet (ISK tax on bounties/missions, optional). Shared hangar at corp HQ station. Roles control access.
<br/>
<span style={{ color: 'var(--purple)' }}>4. Claim</span> Corp anchors a structure in a null-sec system. Structure asserts sovereignty. System shows on sov map as corp territory.
<br/>
<span style={{ color: 'var(--red)' }}>5. Defend</span> Rival corps can contest sovereignty. Structure has a vulnerability window (CEO-configured, 4h/day). During vulnerability, structure can be attacked.
<br/>
<span style={{ color: 'var(--fg)' }}>6. Dissolve</span> If CEO disbands or corp drops below 3 members for 14 days, corp dissolves. Assets liquidated to CEO wallet. Territory unclaimed.
</div>
</div>
<h3 style={{ marginBottom: 'var(--sp-4)' }}>Corporation Roles</h3>
<div style={{ overflowX: 'auto', marginBottom: 'var(--sp-6)' }}>
<table className="data-table">
<thead>
<tr><th>Role</th><th>Permissions</th><th>Assignment</th></tr>
</thead>
<tbody>
{[
{ role: 'CEO', perms: 'All permissions. Can disband corp. Can transfer CEO role. Cannot be kicked.', assignment: 'Founder (auto). Transferable.' },
{ role: 'Director', perms: 'Invite/kick members, manage roles, corp wallet full access, anchor/destroy structures, set tax rate, configure vulnerability window.', assignment: 'Appointed by CEO or other Directors.' },
{ role: 'Accountant', perms: 'View corp wallet history. Pay bills. Set market orders from corp funds. Cannot withdraw ISK.', assignment: 'Appointed by Director+.' },
{ role: 'Pilot', perms: 'Access corp hangar (configured per station). Use corp fittings. Join corp fleet.', assignment: 'Default role for new members.' },
{ role: 'Recruit', perms: 'Corp chat access. View roster. No hangar access. No wallet access.', assignment: 'Probationary role (optional, 7-day default). Auto-promotes to Pilot.' },
].map((row, i) => (
<tr key={i}>
<td style={{ fontWeight: 600, color: ['var(--accent)', 'var(--cyan)', 'var(--green)', 'var(--purple)', 'var(--fg-dim)'][i] }}>{row.role}</td>
<td style={{ color: 'var(--fg-dim)', fontSize: '0.82rem' }}>{row.perms}</td>
<td style={{ color: 'var(--fg-dim)', fontSize: '0.82rem' }}>{row.assignment}</td>
</tr>
))}
</tbody>
</table>
</div>
<h3 style={{ marginBottom: 'var(--sp-4)' }}>Corporation Wallet & Tax</h3>
<div className="grid-2" style={{ marginBottom: 'var(--sp-6)' }}>
<div className="card" style={{ borderLeft: '3px solid var(--green)' }}>
<h4 style={{ color: 'var(--green)' }}>Corp Wallet</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li>Shared ISK balance separate from all member wallets</li>
<li>Funded by: tax on member income, voluntary donations, structure taxes, corp market orders</li>
<li>Spent on: structure fuel, alliance dues, SRP (ship replacement program), member bonuses</li>
<li>Full transaction log visible to Accountant+ roles</li>
<li>Withdrawal requires Director+ approval (or CEO)</li>
</ul>
</div>
<div className="card" style={{ borderLeft: '3px solid var(--accent)' }}>
<h4 style={{ color: 'var(--accent)' }}>Tax System</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li><strong style={{ color: 'var(--fg)' }}>Bounty tax:</strong> CEO sets % (0100%). Deducted from NPC bounties and mission rewards. Default 10%.</li>
<li><strong style={{ color: 'var(--fg)' }}>Market tax:</strong> Optional tax on market orders placed in corp-controlled stations. 05%. Set per station.</li>
<li><strong style={{ color: 'var(--fg)' }}>Refining tax:</strong> Optional tax on refining at corp-controlled facilities. 05%.</li>
<li>Tax revenue goes to corp wallet automatically</li>
<li>Members see their personal tax contribution in wallet history</li>
</ul>
</div>
</div>
<h3 style={{ marginBottom: 'var(--sp-4)' }}>Territory & Sovereignty</h3>
<div className="callout callout-info" style={{ marginBottom: 'var(--sp-5)' }}>
<strong>Null-sec only.</strong> Territory claims are only possible in null-sec (security 0.0). High-sec and low-sec systems
cannot be claimed. This preserves the "wild west" nature of null-sec as the player-driven frontier while keeping
NPC-controlled space as the shared commons.
</div>
<div className="grid-2" style={{ marginBottom: 'var(--sp-6)' }}>
<div className="card" style={{ borderLeft: '3px solid var(--red)' }}>
<h4 style={{ color: 'var(--red)' }}>Corporation Structures</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li><strong style={{ color: 'var(--fg)' }}>Starbase (Medium):</strong> Claims sovereignty in 1 system. Provides: refining bonus (+10%), market access, hangar, clone bay. Cost: 50M + fuel.</li>
<li><strong style={{ color: 'var(--fg)' }}>Citadel (Large):</strong> Claims constellation-wide influence. Provides: all Starbase bonuses + manufacturing slots + insurance desk. Cost: 500M + fuel.</li>
<li><strong style={{ color: 'var(--fg)' }}>Keepstar (XL):</strong> Regional capital. Provides: all Citadel bonuses + capital ship construction + super-capital docking. Cost: 5B + fuel. One per region.</li>
<li>Structures have shields, armor, and hull they can be destroyed during vulnerability windows</li>
<li>Structure destruction = loss of territory claim. System becomes unclaimed.</li>
</ul>
</div>
<div className="card" style={{ borderLeft: '3px solid var(--cyan)' }}>
<h4 style={{ color: 'var(--cyan)' }}>Sovereignty Mechanics</h4>
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
<li><strong style={{ color: 'var(--fg)' }}>Anchoring:</strong> Corp anchors structure in unclaimed null-sec system. 24-hour onlining timer. During onlining, structure is invulnerable.</li>
<li><strong style={{ color: 'var(--fg)' }}>Vulnerability window:</strong> CEO picks a 4-hour daily window (must overlap with corp prime time). Structure can only be attacked during this window.</li>
<li><strong style={{ color: 'var(--fg)' }}>Reinforcement:</strong> When structure shields reach 0%, it enters reinforcement (18h timer). Armor becomes targetable after timer expires.</li>
<li><strong style={{ color: 'var(--fg)' }}>Destruction:</strong> When structure hull reaches 0%, it explodes. Corp loses sovereignty. All items in corp hangar drop as loot (50%) or are destroyed (50%).</li>
<li><strong style={{ color: 'var(--fg)' }}>Strategic index:</strong> The longer a corp holds a system, the higher the strategic index (05). Higher index = longer reinforcement timer, stronger structure shields. Rewards long-term ownership.</li>
</ul>
</div>
</div>
<div className="callout callout-warn" style={{ marginBottom: 'var(--sp-5)' }}>
<strong>Design intent:</strong> Territory warfare is the endgame that keeps players engaged for years. A corp's home system
is its identity losing it is a major event, conquering one is a major achievement. The vulnerability window ensures
battles happen when both sides can participate (no 3 AM structure kills). The strategic index rewards corps that invest
in their territory rather than nomadic expansion. The goal is <em>meaningful conflict</em>, not meaningless destruction.
</div>
<div className="section-header">
<span className="section-num">SOC-CORP-DB</span>
<h2 style={{ margin: 0 }}>Backend Impact</h2>
</div>
<div className="card card-accent" style={{ marginBottom: 'var(--sp-5)' }}>
<h4 style={{ marginBottom: 'var(--sp-4)' }}>New Tables (Phase 14)</h4>
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', color: 'var(--fg-dim)', lineHeight: 2 }}>
<span style={{ color: 'var(--accent)' }}>corporations</span> <code>corp_id, name, ticker, ceo_player_id, founded_at, wallet_balance, tax_rate_bounty, tax_rate_market, tax_rate_refining, member_count, hq_station_id, vulnerability_window_start, vulnerability_window_hours, dissolved_at</code><br/>
<span style={{ color: 'var(--cyan)' }}>corp_members</span> <code>corp_id, player_id, role (enum), joined_at, tax_contribution_lifetime</code><br/>
<span style={{ color: 'var(--green)' }}>corp_wallet_journal</span> <code>entry_id, corp_id, entry_type (tax/donation/withdrawal/expense), amount, player_id, timestamp, description</code><br/>
<span style={{ color: 'var(--red)' }}>corp_structures</span> <code>structure_id, corp_id, system_id, structure_type (starbase/citadel/keepstar), shield/armor/hull, state (onlining/online/reinforced/vulnerable/destroyed), reinforced_at, vulnerability_start, strategic_index</code><br/>
<span style={{ color: 'var(--purple)' }}>corp_hangar</span> <code>hangar_id, corp_id, station_id, item_type, quantity, access_role_min</code><br/>
<span style={{ color: 'var(--fg)' }}>corp_fittings</span> <code>fitting_id, corp_id, name, ship_type, modules_json, created_by, access_role_min</code><br/>
<br/>
<span style={{ color: 'var(--cyan)' }}>Reducers:</span> <code>found_corp(name, ticker)</code>, <code>invite_member(player_id)</code>, <code>kick_member(player_id)</code>, <code>set_role(player_id, role)</code>, <code>anchor_structure(system_id, type)</code>, <code>attack_structure(structure_id)</code>, <code>reinforce_structure(structure_id)</code>, <code>destroy_structure(structure_id)</code>, <code>set_tax_rate(type, rate)</code>, <code>deposit_corp_wallet(amount)</code>, <code>withdraw_corp_wallet(amount, reason)</code>
</div>
</div>
<div className="callout callout-info">
<strong>Corp hangar integration:</strong> When a player is docked at a station with a corp hangar, they see a
"Corp Hangar" tab in the Inventory panel. Access is gated by role. Items in corp hangar can be used for corp
manufacturing jobs, corp market orders, or distributed to members. The hangar respects the same item/inventory
system as personal hangars it's just owned by the corp entity rather than a player entity.
</div>
</>)}
</div>
);
}
window.GDD.SocialPage = SocialPage;