From 04939ee6e81193fce81f03bb2633e74358b65b3b Mon Sep 17 00:00:00 2001 From: anoracleofra-code Date: Thu, 26 Mar 2026 10:38:33 -0600 Subject: [PATCH] fix: bump text sizes across all mesh/infonet/settings components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 7px→11px, 8px→12px, 9px→13px, 10px→14px (text-sm) across MeshChat, MeshTerminal, InfonetTerminal (all sub-components), ShodanPanel, SettingsPanel, and OnboardingModal. 316 instances total. --- .../components/InfonetTerminal/BallotView.tsx | 6 +- .../components/InfonetTerminal/GateView.tsx | 30 +- .../InfonetTerminal/HashchainEvents.tsx | 6 +- .../InfonetTerminal/IdentityHUD.tsx | 10 +- .../InfonetTerminal/InfonetShell.tsx | 12 +- .../InfonetTerminal/LiveActivityLog.tsx | 4 +- .../components/InfonetTerminal/MarketView.tsx | 24 +- .../InfonetTerminal/MessagesView.tsx | 14 +- .../InfonetTerminal/NetworkStats.tsx | 2 +- .../InfonetTerminal/ProfileView.tsx | 44 +- .../InfonetTerminal/TerminalDashboard.tsx | 32 +- .../InfonetTerminal/TrendingPosts.tsx | 2 +- .../InfonetTerminal/WeatherWidget.tsx | 2 +- .../src/components/InfonetTerminal/index.tsx | 2 +- frontend/src/components/MeshChat.tsx | 434 +++++++++--------- frontend/src/components/MeshTerminal.tsx | 186 ++++---- frontend/src/components/OnboardingModal.tsx | 34 +- frontend/src/components/SettingsPanel.tsx | 204 ++++---- frontend/src/components/ShodanPanel.tsx | 58 +-- 19 files changed, 553 insertions(+), 553 deletions(-) diff --git a/frontend/src/components/InfonetTerminal/BallotView.tsx b/frontend/src/components/InfonetTerminal/BallotView.tsx index 166210f..d2b802b 100644 --- a/frontend/src/components/InfonetTerminal/BallotView.tsx +++ b/frontend/src/components/InfonetTerminal/BallotView.tsx @@ -40,7 +40,7 @@ export default function BallotView({ onBack }: { onBack: () => void }) {
-
+
Principle
@@ -48,7 +48,7 @@ export default function BallotView({ onBack }: { onBack: () => void }) {
-
+
Current stance
@@ -56,7 +56,7 @@ export default function BallotView({ onBack }: { onBack: () => void }) {
-
+
Testnet focus
diff --git a/frontend/src/components/InfonetTerminal/GateView.tsx b/frontend/src/components/InfonetTerminal/GateView.tsx index d29fd2c..9d57e91 100644 --- a/frontend/src/components/InfonetTerminal/GateView.tsx +++ b/frontend/src/components/InfonetTerminal/GateView.tsx @@ -524,7 +524,7 @@ export default function GateView({
-
+
{status?.has_local_access ? `LIVE ROOM READY • ${status.identity_scope || entryMode || 'gate'} access` : loading @@ -588,7 +588,7 @@ export default function GateView({
) : null} {voteNotice ? ( -
+
{voteNotice}
) : null} @@ -604,7 +604,7 @@ export default function GateView({ PINNED

{introMessage}

-
+
Fixed launch gate for the testnet catalog. Dynamic gate creation is disabled.
@@ -613,10 +613,10 @@ export default function GateView({ {threadedMessages.map(({ message, depth }) => message.system_seed ? (
-
+
{message.fixed_gate ? 'FIXED GATE NOTICE' : 'GATE NOTICE'}
-
+
{message.message}
@@ -632,7 +632,7 @@ export default function GateView({
0 ? 'border-gray-800/40 bg-black/10' : 'border-gray-800/70 bg-black/20'} px-3 py-3`}>
-
+
@{String(message.node_id || '').replace(/^!sb_/, '').slice(0, 8) || String(message.public_key || '').slice(0, 8) @@ -640,7 +640,7 @@ export default function GateView({ {isEncryptedGateEnvelope(message) ? ( ) : null} - {timeAgo(message.timestamp)} + {timeAgo(message.timestamp)}
Reply @@ -677,7 +677,7 @@ export default function GateView({ <> - + SCORE {(() => { const s = reps[String(message.event_id || '')] ?? 0; return s % 1 === 0 ? s : s.toFixed(1); })()} @@ -714,7 +714,7 @@ export default function GateView({
{replyContext ? ( -
+
Replying to @{replyContext.eventId.slice(0, 8)} @@ -745,7 +745,7 @@ export default function GateView({
@@ -43,8 +43,8 @@ export default function IdentityHUD({ currentDomain = 'TRANSPORT' }: { currentDo
{d.icon}
-

{d.name}

-

{d.visibility}

+

{d.name}

+

{d.visibility}

{isActive && ( @@ -63,7 +63,7 @@ export default function IdentityHUD({ currentDomain = 'TRANSPORT' }: { currentDo
-

+

CRITICAL: CROSS-DOMAIN LINKAGE IS PROTOCOL-FORBIDDEN. ROTATING IDENTITY PURGES ALL LOCAL SESSION CACHE.

@@ -76,7 +76,7 @@ export default function IdentityHUD({ currentDomain = 'TRANSPORT' }: { currentDo className={`flex items-center gap-3 px-4 py-2 border ${isExpanded ? 'border-cyan-500 bg-cyan-900/20' : 'border-gray-800 bg-gray-900/80'} backdrop-blur-md transition-all hover:border-cyan-400 group`} >
- Active Domain + Active Domain {domain.icon} {domain.name} diff --git a/frontend/src/components/InfonetTerminal/InfonetShell.tsx b/frontend/src/components/InfonetTerminal/InfonetShell.tsx index 07b355c..589a9c2 100644 --- a/frontend/src/components/InfonetTerminal/InfonetShell.tsx +++ b/frontend/src/components/InfonetTerminal/InfonetShell.tsx @@ -496,7 +496,7 @@ export default function InfonetShell({ isOpen, onClose, onOpenLiveGate }: Infone diff --git a/frontend/src/components/InfonetTerminal/LiveActivityLog.tsx b/frontend/src/components/InfonetTerminal/LiveActivityLog.tsx index 8edde1a..d4ba13c 100644 --- a/frontend/src/components/InfonetTerminal/LiveActivityLog.tsx +++ b/frontend/src/components/InfonetTerminal/LiveActivityLog.tsx @@ -198,14 +198,14 @@ export default function LiveActivityLog() { Live Network Telemetry - + FEEDS: {logs.length} EVENTS
{logs.length === 0 && (
Waiting for data stream...
diff --git a/frontend/src/components/InfonetTerminal/MarketView.tsx b/frontend/src/components/InfonetTerminal/MarketView.tsx index c85ff7b..e1e09b4 100644 --- a/frontend/src/components/InfonetTerminal/MarketView.tsx +++ b/frontend/src/components/InfonetTerminal/MarketView.tsx @@ -107,7 +107,7 @@ export default function MarketView({ onBack }: MarketViewProps) { ))}
- {filteredMarkets.length} RESULTS + {filteredMarkets.length} RESULTS
{/* Search Bar */} @@ -144,7 +144,7 @@ export default function MarketView({ onBack }: MarketViewProps) {
{market.title}
-
+
{market.category} {vol && VOL: {vol}} {vol24 && 24H: {vol24}} @@ -155,12 +155,12 @@ export default function MarketView({ onBack }: MarketViewProps) { {outcomes && outcomes.length > 0 ? ( <>
{outcomes[0].pct}%
-
{outcomes[0].name}
+
{outcomes[0].name}
) : ( <>
{pct}%
-
CONSENSUS
+
CONSENSUS
)}
@@ -169,21 +169,21 @@ export default function MarketView({ onBack }: MarketViewProps) { {/* Probability bar */} {outcomes && outcomes.length > 0 ? (
- {outcomes[0].name} + {outcomes[0].name}
- {outcomes[0].pct}% + {outcomes[0].pct}%
) : (
- YES + YES
- NO + NO
)} @@ -191,7 +191,7 @@ export default function MarketView({ onBack }: MarketViewProps) {
{market.sources?.map((s, si) => ( - ))} {consensus && consensus.total_picks > 0 && ( - + {consensus.total_picks} pick{consensus.total_picks !== 1 ? 's' : ''} {consensus.total_staked > 0 ? ` · ${consensus.total_staked.toFixed(1)} REP` : ''} @@ -209,7 +209,7 @@ export default function MarketView({ onBack }: MarketViewProps) { {/* Delta indicator */} {market.delta_pct != null && market.delta_pct !== 0 && ( - 0 ? 'text-green-400' : 'text-red-400'}`}> + 0 ? 'text-green-400' : 'text-red-400'}`}> {market.delta_pct > 0 ? '▲' : '▼'} {Math.abs(market.delta_pct).toFixed(1)}% )} @@ -219,7 +219,7 @@ export default function MarketView({ onBack }: MarketViewProps) { {outcomes && outcomes.length > 0 && (
{outcomes.slice(0, 5).map((outcome, oi) => ( -
+
{outcome.name}
diff --git a/frontend/src/components/InfonetTerminal/MessagesView.tsx b/frontend/src/components/InfonetTerminal/MessagesView.tsx index 945ac91..58496d8 100644 --- a/frontend/src/components/InfonetTerminal/MessagesView.tsx +++ b/frontend/src/components/InfonetTerminal/MessagesView.tsx @@ -1369,7 +1369,7 @@ export default function MessagesView({ onBack }: MessagesViewProps) {
-
+
{selectedMessage.transport || 'local'}
@@ -1681,7 +1681,7 @@ export default function MessagesView({ onBack }: MessagesViewProps) { setActiveTab('compose'); }} disabled={!dmLaneReady} - className="px-3 py-2 border border-cyan-500/30 text-cyan-300 text-[10px] tracking-[0.18em] uppercase disabled:opacity-50" + className="px-3 py-2 border border-cyan-500/30 text-cyan-300 text-sm tracking-[0.18em] uppercase disabled:opacity-50" > Compose @@ -1690,7 +1690,7 @@ export default function MessagesView({ onBack }: MessagesViewProps) { blockContact(peerId); setContacts(getContacts()); }} - className="px-3 py-2 border border-amber-500/30 text-amber-300 text-[10px] tracking-[0.18em] uppercase" + className="px-3 py-2 border border-amber-500/30 text-amber-300 text-sm tracking-[0.18em] uppercase" > Restrict @@ -1699,7 +1699,7 @@ export default function MessagesView({ onBack }: MessagesViewProps) { removeContact(peerId); setContacts(getContacts()); }} - className="px-3 py-2 border border-red-500/30 text-red-300 text-[10px] tracking-[0.18em] uppercase" + className="px-3 py-2 border border-red-500/30 text-red-300 text-sm tracking-[0.18em] uppercase" > Remove @@ -1764,7 +1764,7 @@ export default function MessagesView({ onBack }: MessagesViewProps) { unblockContact(peerId); setContacts(getContacts()); }} - className="px-4 py-2 border border-cyan-500/40 bg-cyan-950/20 text-cyan-300 text-[10px] tracking-[0.18em] uppercase" + className="px-4 py-2 border border-cyan-500/40 bg-cyan-950/20 text-cyan-300 text-sm tracking-[0.18em] uppercase" > Restore diff --git a/frontend/src/components/InfonetTerminal/NetworkStats.tsx b/frontend/src/components/InfonetTerminal/NetworkStats.tsx index 2846207..cd5de3f 100644 --- a/frontend/src/components/InfonetTerminal/NetworkStats.tsx +++ b/frontend/src/components/InfonetTerminal/NetworkStats.tsx @@ -55,7 +55,7 @@ export default function NetworkStats() { : stats.nodeEnabled ? 'SYNCING' : 'OFFLINE'; return ( -
+
NODE {nodeLabel} | MESH 0 ? 'text-green-400' : 'text-gray-600'}>{stats.meshtastic.toLocaleString()} diff --git a/frontend/src/components/InfonetTerminal/ProfileView.tsx b/frontend/src/components/InfonetTerminal/ProfileView.tsx index a4a0bc6..1e93114 100644 --- a/frontend/src/components/InfonetTerminal/ProfileView.tsx +++ b/frontend/src/components/InfonetTerminal/ProfileView.tsx @@ -187,11 +187,11 @@ export default function ProfileView({ onBack, persona, isCitizen, nodeId, public
-

Lit

+

Lit

{upvotes}

-

Dislikes

+

Dislikes

{downvotes}

@@ -202,21 +202,21 @@ export default function ProfileView({ onBack, persona, isCitizen, nodeId, public style={{ width: `${repProgress}%` }} />
-

+

Reputation is derived from live lit/dislike activity. Net rep can drop below zero even when the bar is clamped at zero.

-

Active Months

+

Active Months

0 MONTHS

-

No live citizenship accounting yet

+

No live citizenship accounting yet

-

Citizenship History

+

Citizenship History

0 MONTHS

-

Placeholder totals removed

+

Placeholder totals removed

@@ -227,7 +227,7 @@ export default function ProfileView({ onBack, persona, isCitizen, nodeId, public

{oracleRep.toFixed(1)} AVAILABLE

-

+

Win Rate {oracleProfile.win_rate}% • W {oracleProfile.predictions_won} / L {oracleProfile.predictions_lost}

@@ -237,7 +237,7 @@ export default function ProfileView({ onBack, persona, isCitizen, nodeId, public style={{ width: `${oracleProgress}%` }} />
-

+

Available: {oracleRep.toFixed(1)} | Locked: {oracleRepLocked.toFixed(1)} | Total: {oracleRepTotal.toFixed(1)}

@@ -251,7 +251,7 @@ export default function ProfileView({ onBack, persona, isCitizen, nodeId, public
-

Vote Correlation

+

Vote Correlation

@@ -261,14 +261,14 @@ export default function ProfileView({ onBack, persona, isCitizen, nodeId, public 0.00
-

NOT CALIBRATED

+

NOT CALIBRATED

-

Clustering Coefficient

-

0.00

+

Clustering Coefficient

+

0.00

@@ -276,8 +276,8 @@ export default function ProfileView({ onBack, persona, isCitizen, nodeId, public
-

Temporal Burst Detection

-

0.00

+

Temporal Burst Detection

+

0.00

@@ -285,7 +285,7 @@ export default function ProfileView({ onBack, persona, isCitizen, nodeId, public
-

+

Advanced network-health analytics are not calibrated for this profile yet. Live reputation above is authoritative; unresolved analytics stay zeroed.

@@ -299,27 +299,27 @@ export default function ProfileView({ onBack, persona, isCitizen, nodeId, public
-

Root

+

Root

NEVER PUBLIC

-

Transport

+

Transport

PUBLIC MESH

-

DM Alias

+

DM Alias

SEMI-OBFUSCATED

-

Gate Session

+

Gate Session

ANONYMOUS

-

Gate Persona

+

Gate Persona

{displayPersona}

-

Credits

+

Credits

0.00 AVAILABLE

diff --git a/frontend/src/components/InfonetTerminal/TerminalDashboard.tsx b/frontend/src/components/InfonetTerminal/TerminalDashboard.tsx index 3b42df5..7488dc7 100644 --- a/frontend/src/components/InfonetTerminal/TerminalDashboard.tsx +++ b/frontend/src/components/InfonetTerminal/TerminalDashboard.tsx @@ -70,7 +70,7 @@ export default function TerminalDashboard({ onNavigate, onComingSoon }: Terminal
GLOBAL THREAT INTERCEPT {threat && ( - + {threat.level} )} @@ -101,16 +101,16 @@ export default function TerminalDashboard({ onNavigate, onComingSoon }: Terminal {filteredNews.length > 0 ? filteredNews.map((article, i) => (
- = 7 ? 'text-red-400' : article.risk_score >= 4 ? 'text-yellow-400' : 'text-green-400' }`}> {article.risk_score >= 7 ? 'HIGH' : article.risk_score >= 4 ? 'MED' : 'LOW'} - {article.source} - {formatTime(article.pub_date)} + {article.source} + {formatTime(article.pub_date)} {article.breaking && ( - BREAKING + BREAKING )}

{article.title}

@@ -204,28 +204,28 @@ export default function TerminalDashboard({ onNavigate, onComingSoon }: Terminal
- Tracked Flights + Tracked Flights {flightCount.toLocaleString()}
- Tracked Vessels + Tracked Vessels {shipCount.toLocaleString()}
- Satellites + Satellites {satCount.toLocaleString()}
- Active Markets + Active Markets {markets.length}
- Correlations + Correlations {correlationCount}
- Threat Level - + Threat Level + {threat?.level || 'UNKNOWN'} {threat?.score != null ? `(${threat.score})` : ''}
@@ -234,9 +234,9 @@ export default function TerminalDashboard({ onNavigate, onComingSoon }: Terminal {/* Threat drivers */} {threat?.drivers && threat.drivers.length > 0 && (
- THREAT DRIVERS + THREAT DRIVERS {threat.drivers.slice(0, 3).map((driver, i) => ( -

• {driver}

+

• {driver}

))}
)} @@ -247,8 +247,8 @@ export default function TerminalDashboard({ onNavigate, onComingSoon }: Terminal
- Threat Score - {threat?.score ?? '—'}/100 + Threat Score + {threat?.score ?? '—'}/100
diff --git a/frontend/src/components/InfonetTerminal/TrendingPosts.tsx b/frontend/src/components/InfonetTerminal/TrendingPosts.tsx index 0585ab6..e6c4a10 100644 --- a/frontend/src/components/InfonetTerminal/TrendingPosts.tsx +++ b/frontend/src/components/InfonetTerminal/TrendingPosts.tsx @@ -10,7 +10,7 @@ export default function TrendingPosts() { Gates
-
+

TEST-NET ACTIVE

Gates are decentralized chatrooms running on the Infonet mesh. All messages are end-to-end encrypted via Wormhole.

Type gates or g/ to browse available rooms.

diff --git a/frontend/src/components/InfonetTerminal/WeatherWidget.tsx b/frontend/src/components/InfonetTerminal/WeatherWidget.tsx index 44b60ff..ffce375 100644 --- a/frontend/src/components/InfonetTerminal/WeatherWidget.tsx +++ b/frontend/src/components/InfonetTerminal/WeatherWidget.tsx @@ -28,7 +28,7 @@ export default function WeatherWidget() { const dateString = time.toLocaleDateString('en-US', { timeZone: loc.tz, month: 'short', day: 'numeric' }); return ( -
+
{dateString} {timeString} |
- + Infonet Sovereign Shell v0.1.1
diff --git a/frontend/src/components/MeshChat.tsx b/frontend/src/components/MeshChat.tsx index 0e6ed85..f234784 100644 --- a/frontend/src/components/MeshChat.tsx +++ b/frontend/src/components/MeshChat.tsx @@ -700,7 +700,7 @@ function RepBadge({ rep }: { rep: number }) { ? 'text-red-400' : 'text-gray-600'; return ( - + {rep >= 0 ? '+' : ''} {rep} @@ -3902,17 +3902,17 @@ const MeshChat = React.memo(function MeshChat({ className="flex justify-between items-center p-4 cursor-pointer hover:bg-[var(--bg-secondary)]/50 transition-colors border-b border-[var(--border-primary)]/50 shrink-0 select-none" >
- ── + ── MESH CHAT - ────────────────────────────── + ──────────────────────────────
{totalDmNotify > 0 && ( - {totalDmNotify} + {totalDmNotify} )} {expanded ? ( @@ -3944,7 +3944,7 @@ const MeshChat = React.memo(function MeshChat({ setActiveTab(tab.key); if (tab.key === 'dms') setDmView('contacts'); }} - className={`flex-1 flex items-center justify-center gap-1 py-1.5 text-[10px] font-mono tracking-wider transition-colors ${ + className={`flex-1 flex items-center justify-center gap-1 py-1.5 text-sm font-mono tracking-wider transition-colors ${ activeTab === tab.key ? 'text-cyan-300 bg-cyan-950/50 font-bold border-b border-cyan-500/50' : 'text-[var(--text-muted)] hover:text-cyan-600 border-b border-cyan-900/20' @@ -3970,28 +3970,28 @@ const MeshChat = React.memo(function MeshChat({
{privacyProfile === 'high' && !wormholeEnabled && ( -
+
High Privacy is ON but Wormhole is OFF. Private messaging is blocked until Wormhole is enabled.
)} {activeTab !== 'meshtastic' && wormholeEnabled && !wormholeReadyState && ( -
+
Wormhole secure mode is enabled but the local agent is not ready. Dead Drop is blocked until Wormhole is running.
)} {activeTab !== 'meshtastic' && wormholeEnabled && wormholeReadyState && ( -
+
Wormhole secure mode is active. Experimental private-lane operations are routed through the local agent and current secure transport paths.
)} {activeTab !== 'meshtastic' && wormholeEnabled && wormholeReadyState && !wormholeRnsReady && ( -
+
EXPERIMENTAL ENCRYPTION. Wormhole is up, gate chat is available, and Reticulum is still warming on the strongest lane. Direct private DM posture remains separate in this testnet build. @@ -3999,7 +3999,7 @@ const MeshChat = React.memo(function MeshChat({ )} {anonymousModeEnabled && !anonymousModeReady && ( -
+
Anonymous mode is active, but hidden transport is not ready. Dead Drop is blocked until Wormhole is running over Tor, I2P, or Mixnet.
@@ -4007,7 +4007,7 @@ const MeshChat = React.memo(function MeshChat({ {/* No identity warning */} {shouldShowIdentityWarning && ( -
+
Run connect in MeshTerminal first, or open
-
+
{selectedGateKeyStatus.has_local_access ? `Access live via ${selectedGateKeyStatus.identity_scope || 'member'} identity ${String(selectedGateKeyStatus.sender_ref || selectedGateKeyStatus.identity_node_id || '').slice(0, 16)}` : selectedGateKeyStatus.identity_scope === 'anonymous' ? 'Anonymous gate session is active, but this install has not synced gate access yet. Refresh or reopen the gate if it does not clear.' : 'No local gate key access yet. Enter the gate through Wormhole to unwrap the current epoch.'}
-
+
{selectedGateKeyStatus.key_commitment ? `KEY ${selectedGateKeyStatus.key_commitment.slice(0, 12)}` : 'KEY PENDING'} @@ -4225,7 +4225,7 @@ const MeshChat = React.memo(function MeshChat({ : ''}
{nativeAuditSummary && ( -
+
NATIVE AUDIT / @@ -4262,7 +4262,7 @@ const MeshChat = React.memo(function MeshChat({
)} {selectedGateKeyStatus.rekey_recommended_reason && ( -
+
Rekey recommendation: {selectedGateKeyStatus.rekey_recommended_reason.replace(/_/g, ' ')}
)} @@ -4272,7 +4272,7 @@ const MeshChat = React.memo(function MeshChat({ - + {selectedGatePersonaList.length > 0 ? 'Switch to a saved face if this install still cannot unlock the room anonymously.' : 'Create a gate-local face only if anonymous unlock still fails on this install.'} @@ -4292,17 +4292,17 @@ const MeshChat = React.memo(function MeshChat({ {selectedGateMeta && (
-
+
{selectedGateMeta.fixed ? 'FIXED GATE' : 'PRIVATE GATE'} / {selectedGateMeta.display_name || selectedGateMeta.gate_id}
{selectedGateMeta.description && ( -
+
{selectedGateMeta.description}
)} -
+
{selectedGateMeta.rules?.min_overall_rep ? `ENTRY FLOOR ${selectedGateMeta.rules.min_overall_rep} REP` : 'ENTRY FLOOR OPEN'} @@ -4322,7 +4322,7 @@ const MeshChat = React.memo(function MeshChat({ className="overflow-hidden border-b border-[var(--border-primary)]/30 shrink-0" >
-
+
Gates are rep-gated communities. Only nodes meeting the minimum reputation can post.
@@ -4333,17 +4333,17 @@ const MeshChat = React.memo(function MeshChat({ setGateError(''); }} placeholder="gate-id (alphanumeric + hyphens, max 32)" - className="w-full bg-[var(--bg-secondary)]/50 border border-[var(--border-primary)] text-[10px] font-mono text-cyan-300 px-2 py-1 outline-none placeholder:text-[var(--text-muted)]" + className="w-full bg-[var(--bg-secondary)]/50 border border-[var(--border-primary)] text-sm font-mono text-cyan-300 px-2 py-1 outline-none placeholder:text-[var(--text-muted)]" /> setNewGateName(e.target.value)} placeholder="Display Name (optional)" - className="w-full bg-[var(--bg-secondary)]/50 border border-[var(--border-primary)] text-[10px] font-mono text-cyan-300 px-2 py-1 outline-none placeholder:text-[var(--text-muted)]" + className="w-full bg-[var(--bg-secondary)]/50 border border-[var(--border-primary)] text-sm font-mono text-cyan-300 px-2 py-1 outline-none placeholder:text-[var(--text-muted)]" />
{gateError && ( -
+
{gateError}
)} @@ -4380,18 +4380,18 @@ const MeshChat = React.memo(function MeshChat({
{filteredInfoMessages.length === 0 && (
-
+
{selectedGate ? 'No messages in this gate yet' : 'Select a gate or browse all'}
{selectedGateMeta && (
-
+
SYSTEM WELCOME
-
+
{selectedGateMeta.welcome || selectedGateMeta.description || 'Private gate is live. Say something worth keeping.'}
-
+
Start with a source, a thesis, a clean question, or a useful observation.
@@ -4401,16 +4401,16 @@ const MeshChat = React.memo(function MeshChat({ {filteredInfoMessages.map((m, i) => ( m.system_seed ? (
-
+
{m.fixed_gate ? 'FIXED GATE NOTICE' : 'GATE NOTICE'}
-
+
{m.message}
) : (
-
+
{m.node_id ? (
{isEncryptedGateEnvelope(m) && ( -
+
EPOCH {m.epoch ?? 0} {m.sender_ref ? ` / ${m.sender_ref}` : ''}
@@ -4477,7 +4477,7 @@ const MeshChat = React.memo(function MeshChat({
0 ? 'text-cyan-500' : (reps[m.node_id] ?? 0) < 0 @@ -4536,7 +4536,7 @@ const MeshChat = React.memo(function MeshChat({ value={meshRegion} onChange={(e) => setMeshRegion(e.target.value)} title="Meshtastic MQTT root" - className="bg-[var(--bg-secondary)]/50 border border-[var(--border-primary)] text-[10px] font-mono text-cyan-300 px-2 py-1 outline-none focus:border-cyan-700/50" + className="bg-[var(--bg-secondary)]/50 border border-[var(--border-primary)] text-sm font-mono text-cyan-300 px-2 py-1 outline-none focus:border-cyan-700/50" style={{ width: '132px' }} > {meshRoots.map((r) => ( @@ -4548,7 +4548,7 @@ const MeshChat = React.memo(function MeshChat({ -
+
Example: `signalfox`, `source-a`, `ops-lantern`
@@ -5600,7 +5600,7 @@ const MeshChat = React.memo(function MeshChat({
{gatePersonaPromptError && ( -
+
{gatePersonaPromptError}
)} @@ -5614,8 +5614,8 @@ const MeshChat = React.memo(function MeshChat({
-
KEY SETUP
-
+
KEY SETUP
+
Get a public mesh key or enter Wormhole.
@@ -5629,7 +5629,7 @@ const MeshChat = React.memo(function MeshChat({
-
+
PUBLIC MESH
Public lane. One tap gets you a posting key. @@ -5641,10 +5641,10 @@ const MeshChat = React.memo(function MeshChat({
-
+
CURRENT STATE
-
+
Public mesh key: {hasPublicLaneIdentity ? 'active' : 'not issued'}
Public mesh address: {hasPublicLaneIdentity && publicMeshAddress ? publicMeshAddress.toUpperCase() : 'not ready'}
Wormhole lane: {wormholeEnabled && wormholeReadyState ? 'active' : wormholeEnabled ? 'starting' : 'off'}
@@ -5662,14 +5662,14 @@ const MeshChat = React.memo(function MeshChat({ void handleCreatePublicIdentity(); }} disabled={identityWizardBusy} - className="w-full text-left px-3 py-2 border border-green-500/30 bg-green-950/10 hover:bg-green-950/20 text-[10px] font-mono text-green-300 disabled:opacity-50" + className="w-full text-left px-3 py-2 border border-green-500/30 bg-green-950/10 hover:bg-green-950/20 text-sm font-mono text-green-300 disabled:opacity-50" > {hasPublicLaneIdentity ? 'MESH KEY ACTIVE' : publicMeshBlockedByWormhole ? 'TURN OFF WORMHOLE FOR MESH' : 'GET MESH KEY'} -
+
{hasPublicLaneIdentity ? 'Your public mesh key is already live for posting.' : publicMeshBlockedByWormhole @@ -5681,10 +5681,10 @@ const MeshChat = React.memo(function MeshChat({ @@ -5703,7 +5703,7 @@ const MeshChat = React.memo(function MeshChat({ @@ -5714,7 +5714,7 @@ const MeshChat = React.memo(function MeshChat({ setIdentityWizardOpen(false); onSettingsClick(); }} - className="px-3 py-2 border border-[var(--border-primary)] text-[10px] font-mono text-[var(--text-secondary)] hover:text-cyan-300 hover:border-cyan-500/40" + className="px-3 py-2 border border-[var(--border-primary)] text-sm font-mono text-[var(--text-secondary)] hover:text-cyan-300 hover:border-cyan-500/40" > OPEN SETTINGS @@ -5724,7 +5724,7 @@ const MeshChat = React.memo(function MeshChat({ {identityWizardStatus && (
)} -
+
Testnet note: mesh is public, gates use experimental encryption, and Dead Drop is the strongest current lane.
@@ -5747,10 +5747,10 @@ const MeshChat = React.memo(function MeshChat({
-
+
PRIVATE INFONET LOCKED
-
+
INFONET is the private Wormhole lane. Public perimeter traffic stays under MESH.
@@ -5764,7 +5764,7 @@ const MeshChat = React.memo(function MeshChat({
-
+
INFONET is the private lane now. Public perimeter traffic lives under the MESH @@ -5777,8 +5777,8 @@ const MeshChat = React.memo(function MeshChat({
-
-
TRUST MODES
+
+
TRUST MODES
PUBLIC / DEGRADED — public mesh and perimeter feeds.
EXPERIMENTAL ENCRYPTION — Wormhole lane active, strongest transport posture still warming.
PRIVATE / STRONG — Wormhole and Reticulum are both ready.
@@ -5790,7 +5790,7 @@ const MeshChat = React.memo(function MeshChat({ setInfonetUnlockOpen(false); onSettingsClick?.(); }} - className="px-3 py-1.5 border border-cyan-500/40 bg-cyan-950/20 text-[10px] font-mono text-cyan-300 hover:bg-cyan-950/35 transition-colors" + className="px-3 py-1.5 border border-cyan-500/40 bg-cyan-950/20 text-sm font-mono text-cyan-300 hover:bg-cyan-950/35 transition-colors" > OPEN WORMHOLE @@ -5799,7 +5799,7 @@ const MeshChat = React.memo(function MeshChat({ setInfonetUnlockOpen(false); openTerminal(); }} - className="px-3 py-1.5 border border-green-500/40 bg-green-950/20 text-[10px] font-mono text-green-300 hover:bg-green-950/35 transition-colors inline-flex items-center gap-1.5" + className="px-3 py-1.5 border border-green-500/40 bg-green-950/20 text-sm font-mono text-green-300 hover:bg-green-950/35 transition-colors inline-flex items-center gap-1.5" > TERMINAL @@ -5809,7 +5809,7 @@ const MeshChat = React.memo(function MeshChat({ setInfonetUnlockOpen(false); setActiveTab('meshtastic'); }} - className="px-3 py-1.5 border border-amber-500/40 bg-amber-950/20 text-[10px] font-mono text-amber-300 hover:bg-amber-950/35 transition-colors" + className="px-3 py-1.5 border border-amber-500/40 bg-amber-950/20 text-sm font-mono text-amber-300 hover:bg-amber-950/35 transition-colors" > GO TO MESH @@ -5824,10 +5824,10 @@ const MeshChat = React.memo(function MeshChat({
-
+
DEAD DROP LOCKED
-
+
Dead Drop is the private inbox lane. Public mesh does not substitute for it.
@@ -5841,7 +5841,7 @@ const MeshChat = React.memo(function MeshChat({
-
+
Need Wormhole activated.
Dead Drop handles private contacts, inbox requests, and message exchange on the @@ -5859,7 +5859,7 @@ const MeshChat = React.memo(function MeshChat({ setDeadDropUnlockOpen(false); onSettingsClick?.(); }} - className="px-3 py-1.5 border border-cyan-500/40 bg-cyan-950/20 text-[10px] font-mono text-cyan-300 hover:bg-cyan-950/35 transition-colors" + className="px-3 py-1.5 border border-cyan-500/40 bg-cyan-950/20 text-sm font-mono text-cyan-300 hover:bg-cyan-950/35 transition-colors" > OPEN WORMHOLE @@ -5868,7 +5868,7 @@ const MeshChat = React.memo(function MeshChat({ setDeadDropUnlockOpen(false); openTerminal(); }} - className="px-3 py-1.5 border border-green-500/40 bg-green-950/20 text-[10px] font-mono text-green-300 hover:bg-green-950/35 transition-colors inline-flex items-center gap-1.5" + className="px-3 py-1.5 border border-green-500/40 bg-green-950/20 text-sm font-mono text-green-300 hover:bg-green-950/35 transition-colors inline-flex items-center gap-1.5" > TERMINAL @@ -5878,7 +5878,7 @@ const MeshChat = React.memo(function MeshChat({ setDeadDropUnlockOpen(false); setActiveTab('meshtastic'); }} - className="px-3 py-1.5 border border-amber-500/40 bg-amber-950/20 text-[10px] font-mono text-amber-300 hover:bg-amber-950/35 transition-colors" + className="px-3 py-1.5 border border-amber-500/40 bg-amber-950/20 text-sm font-mono text-amber-300 hover:bg-amber-950/35 transition-colors" > GO TO MESH @@ -5896,24 +5896,24 @@ const MeshChat = React.memo(function MeshChat({ style={{ left: senderPopup.x, top: senderPopup.y }} >
- + {senderPopup.userId.slice(0, 16)}
{senderPopup.tab === 'infonet' && (
-
+
PUBLIC KEY
{senderPopup.publicKey || 'not advertised on this event'}
{senderPopup.publicKeyAlgo ? ( -
+
{senderPopup.publicKeyAlgo}
) : null} @@ -5924,14 +5924,14 @@ const MeshChat = React.memo(function MeshChat({ {mutedUsers.has(senderPopup.userId) ? ( ) : ( @@ -5942,13 +5942,13 @@ const MeshChat = React.memo(function MeshChat({ <> @@ -5965,7 +5965,7 @@ const MeshChat = React.memo(function MeshChat({ openChat(senderPopup.userId); setSenderPopup(null); }} - className="w-full flex items-center gap-2 px-3 py-1.5 text-[9px] font-mono text-green-300 hover:bg-green-950/20 transition-colors" + className="w-full flex items-center gap-2 px-3 py-1.5 text-[13px] font-mono text-green-300 hover:bg-green-950/20 transition-colors" > OPEN DM @@ -5975,7 +5975,7 @@ const MeshChat = React.memo(function MeshChat({ handleRequestAccess(senderPopup.userId); setSenderPopup(null); }} - className="w-full flex items-center gap-2 px-3 py-1.5 text-[9px] font-mono text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)]/50 transition-colors" + className="w-full flex items-center gap-2 px-3 py-1.5 text-[13px] font-mono text-[var(--text-secondary)] hover:bg-[var(--bg-secondary)]/50 transition-colors" > REQUEST CONTACT @@ -5986,12 +5986,12 @@ const MeshChat = React.memo(function MeshChat({ void handleBlockDM(senderPopup.userId); setSenderPopup(null); }} - className="w-full flex items-center gap-2 px-3 py-1.5 text-[9px] font-mono text-red-400/80 hover:bg-red-900/10 transition-colors" + className="w-full flex items-center gap-2 px-3 py-1.5 text-[13px] font-mono text-red-400/80 hover:bg-red-900/10 transition-colors" > BLOCK ) : ( -
+
CONTACT BLOCKED
)} @@ -6004,10 +6004,10 @@ const MeshChat = React.memo(function MeshChat({ {muteConfirm && (
-
+
CONFIRM MUTE
-
+
Mute {muteConfirm.slice(0, 16)}? Their messages will be hidden. You can unmute from Dead Drop > MUTED.
@@ -6017,13 +6017,13 @@ const MeshChat = React.memo(function MeshChat({ setMuteConfirm(null); setSenderPopup(null); }} - className="text-[9px] font-mono px-3 py-1 bg-[var(--bg-secondary)]/50 text-[var(--text-muted)] hover:bg-[var(--bg-secondary)] transition-colors" + className="text-[13px] font-mono px-3 py-1 bg-[var(--bg-secondary)]/50 text-[var(--text-muted)] hover:bg-[var(--bg-secondary)] transition-colors" > CANCEL diff --git a/frontend/src/components/MeshTerminal.tsx b/frontend/src/components/MeshTerminal.tsx index 7472402..fb0e854 100644 --- a/frontend/src/components/MeshTerminal.tsx +++ b/frontend/src/components/MeshTerminal.tsx @@ -4709,7 +4709,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou className={`group flex w-full items-center justify-between gap-3 text-[12px] leading-[1.8] whitespace-pre-wrap break-all border border-fuchsia-500/15 bg-fuchsia-500/[0.03] pr-3 text-left font-mono transition-all hover:border-fuchsia-400/35 hover:bg-fuchsia-500/[0.08] ${lineColor(line.type)} ${lineChrome}`} > {content} - + {line.actionLabel || 'OPEN'} @@ -4748,9 +4748,9 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou onClick={() => runQuickCommand(String(command))} className={`${cardBase} ${tone}`} > -
{title}
+
{title}
{desc}
-
+
{String(command)}
@@ -4769,7 +4769,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou ['PRIVATE DM INBOX', 'Check the experimental private dead drop', () => openSurface('inbox'), 'border-fuchsia-500/25 text-fuchsia-300'], ].map(([title, desc, action, tone]) => ( ))} @@ -4793,8 +4793,8 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou className={`${cardBase} border-fuchsia-500/25 text-fuchsia-300 hover:border-fuchsia-400/45 hover:bg-fuchsia-500/10`} >
-
{title}
-
{command}
+
{title}
+
{command}
{desc}
@@ -4806,22 +4806,22 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
-
PUBLIC MESH LANE
+
PUBLIC MESH LANE
{publicAgentReady ? `Public Agent active as ${nodeIdentity?.nodeId || 'unknown'}` : 'No public Agent yet. Type connect to create one for mesh posting.'}
-
+
Meshtastic traffic is public / observable. Wormhole is not required here.
-
WORMHOLE OBFUSCATED LANE
+
WORMHOLE OBFUSCATED LANE
{privateLaneLabel}
-
+
{privateLaneDetail}
@@ -4843,12 +4843,12 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou onClick={action} className={`${cardBase} border-emerald-500/25 text-emerald-300`} > -
{title}
+
{title}
{desc}
))}
-
MESH ROOT CARDS
+
MESH ROOT CARDS
{surfaceMeshLoading ? (
Loading mesh channels... @@ -4869,7 +4869,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou >
{region}
-
{count}
+
{count}
@@ -4911,12 +4911,12 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou onClick={action as () => void} className={`${cardBase} border-amber-400/25 text-amber-200`} > -
{title as string}
+
{title as string}
{desc as string}
))}
-
LIVE MARKET CARDS
+
LIVE MARKET CARDS
{surfaceMarketsLoading ? (
Loading market cards... @@ -4940,39 +4940,39 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou >
{title}
-
+
{pctValue}
-
{category}
+
{category}
{expanded && ( -
-
MARKET DETAIL
+
+
MARKET DETAIL
Question: {title}
Category: {category}
Consensus: {pctValue}
@@ -5004,12 +5004,12 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou onClick={action as () => void} className={`${cardBase} border-cyan-500/25 text-cyan-300`} > -
{title as string}
+
{title as string}
{desc as string}
))}
-
EXPERIMENTAL PRIVATE DM INBOX
+
EXPERIMENTAL PRIVATE DM INBOX
{surfaceInboxLoading ? (
Checking inbox... @@ -5027,7 +5027,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou >
{message.sender}
-
{message.age}
+
{message.age}
{message.text} @@ -5036,14 +5036,14 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou @@ -5052,7 +5052,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou ))}
)} -
CONTACT CARDS
+
CONTACT CARDS
{contactEntries.length === 0 ? (
No saved contacts yet. @@ -5068,25 +5068,25 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
{contact.alias || contactId}
-
+
{contact.blocked ? 'BLOCKED' : 'ACTIVE'}
{contact.alias && ( -
{contactId}
+
{contactId}
)}
@@ -5101,13 +5101,13 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou return (
-
+
GATES (EXPERIMENTAL ENCRYPTION)
@@ -5135,18 +5135,18 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
{(gate.display_name || gate.gate_id).toUpperCase()}
-
+
{gate.gate_id}
-
+
{typeof gate.message_count === 'number' ? `${gate.message_count} msgs` : 'catalog'}
{gate.description || 'Encrypted commons lane.'}
-
+
{minRep ? `REQ ${minRep} REP` : 'OPEN'} {gate.fixed ? 'FIXED LAUNCH GATE' : 'GATE'}
@@ -5154,14 +5154,14 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou @@ -5173,20 +5173,20 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou setSurfacePanel('gates'); setTimeout(() => inputRef.current?.focus(), 40); }} - className="border border-amber-400/25 bg-amber-400/8 px-3 py-1.5 text-[9px] tracking-[0.18em] text-amber-200 hover:bg-amber-400/14" + className="border border-amber-400/25 bg-amber-400/8 px-3 py-1.5 text-[13px] tracking-[0.18em] text-amber-200 hover:bg-amber-400/14" > POST
{expandedGateLoading === gate.gate_id && ( -
+
Loading gate detail...
)} @@ -5194,12 +5194,12 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
-
WELCOME
+
WELCOME
{expandedGateDetail.welcome || expandedGateDetail.description || 'Encrypted commons lane.'}
-
+
Creator {expandedGateDetail.creator_node_id || 'unknown'} @@ -5228,7 +5228,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
{expandedGateMessages.length > 0 && (
-
THREAD SNAPSHOT
+
THREAD SNAPSHOT
{expandedGateMessages.map((message, messageIndex) => (
-
{message.nodeId}
-
{message.age}
+
{message.nodeId}
+
{message.age}
{message.text}
{message.encrypted && ( -
+
EXPERIMENTAL ENCRYPTION
)} @@ -5249,7 +5249,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou @@ -5260,21 +5260,21 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou setGateReplyTarget(message.nodeId); setTimeout(() => inputRef.current?.focus(), 40); }} - className="border border-amber-400/20 bg-amber-400/8 px-3 py-1.5 text-[9px] tracking-[0.18em] text-amber-200 hover:bg-amber-400/14" + className="border border-amber-400/20 bg-amber-400/8 px-3 py-1.5 text-[13px] tracking-[0.18em] text-amber-200 hover:bg-amber-400/14" > REPLY @@ -5459,7 +5459,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou onSettingsClick(); }} disabled={privateLanePromptBusy} - className="border border-slate-500/20 bg-white/5 px-4 py-2 text-[10px] tracking-[0.22em] text-slate-400 transition-colors hover:bg-white/8 disabled:cursor-not-allowed disabled:opacity-50" + className="border border-slate-500/20 bg-white/5 px-4 py-2 text-sm tracking-[0.22em] text-slate-400 transition-colors hover:bg-white/8 disabled:cursor-not-allowed disabled:opacity-50" > ADVANCED @@ -5473,13 +5473,13 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
-
+
ENTER INFONET COMMONS
Gates live behind Wormhole in this build. Enter now?
-
+
{wormholeSecureRequired ? wormholeReadyState ? 'Yes takes you straight into the gates.' @@ -5490,14 +5490,14 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou @@ -5520,7 +5520,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou className="fixed top-0 left-1/2 -translate-x-1/2 z-[305] flex items-center gap-2 rounded-b border border-cyan-800/30 border-t-0 bg-cyan-950/40 px-4 py-1.5 text-cyan-700 transition-colors hover:bg-cyan-950/60 hover:text-cyan-300 hover:border-cyan-500/40" > - + TERMINAL @@ -5605,7 +5605,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
-
+
type clear to wipe output · gates require wormhole · mesh stays public
@@ -5617,22 +5617,22 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou openSurface('inbox'); runQuickCommand('inbox'); }} - className="border border-cyan-500/18 bg-cyan-500/8 px-2.5 py-1 text-[8px] tracking-[0.18em] text-cyan-300 transition-colors hover:bg-cyan-500/14" + className="border border-cyan-500/18 bg-cyan-500/8 px-2.5 py-1 text-[12px] tracking-[0.18em] text-cyan-300 transition-colors hover:bg-cyan-500/14" > PRIVATE DM INBOX {nodeIdentity && hasSovereignty() && ( - + {nodeIdentity.nodeId.slice(0, 14)} )} {terminalWriteLockReason && ( - + READ ONLY )} {busy && ( - + RUNNING )} @@ -5671,11 +5671,11 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
-
INFONET
+
INFONET
THE INFONET COMMONS
-
+
OPSINT DECK · COMMONS NODE
@@ -5683,7 +5683,7 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
-
+
INFONET · experimental encryption
@@ -5702,47 +5702,47 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
-
+
PARTICIPANT NODE
-
+
Automatic bootstrap and sync now live on the backend lane. This node can keep a local chain even with Wormhole off.
-
+
{nodeModeLabel}
-
+
-
CHAIN
+
CHAIN
{shortNodeHash(infonetNodeStatus?.head_hash, 18)}
-
+
{Number(infonetNodeStatus?.total_events || 0)} events • {Number(infonetNodeStatus?.known_nodes || 0)} nodes
-
PEERS
+
PEERS
{Number(infonetNodeStatus?.bootstrap?.sync_peer_count || 0)} sync
-
+
{Number(infonetNodeStatus?.bootstrap?.push_peer_count || 0)} push • {Number(infonetNodeStatus?.bootstrap?.bootstrap_peer_count || 0)} bootstrap
-
SYNC LOOP
+
SYNC LOOP
{nodeSyncLabel}
-
+
next {formatNodeTime(infonetNodeStatus?.sync_runtime?.next_sync_due_at)}
-
+
Bootstrap {nodeBootstrapLabel} @@ -5759,8 +5759,8 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
-
-
+
+
WORMHOLE OPTIONAL FOR NODE SYNC
@@ -5769,14 +5769,14 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
Turn Wormhole on for gates, obfuscated inbox, and the stronger obfuscated lane only.
-
+
obfuscated lane now: {privateLaneLabel}
@@ -5811,19 +5811,19 @@ export default function MeshTerminal({ isOpen, launchToken = 0, onClose, onDmCou
-
+
COMMAND LINE MESH / RADIO GATES / COMMONS OPS / DOSSIER {activeGateComposeId && ( - + POSTING TO g/{activeGateComposeId} )} {gateReplyTarget && ( - + REPLY @{gateReplyTarget} )} diff --git a/frontend/src/components/OnboardingModal.tsx b/frontend/src/components/OnboardingModal.tsx index 49164a4..7cde5fb 100644 --- a/frontend/src/components/OnboardingModal.tsx +++ b/frontend/src/components/OnboardingModal.tsx @@ -107,7 +107,7 @@ const OnboardingModal = React.memo(function OnboardingModal({

MISSION BRIEFING

- + FIRST-TIME SETUP
@@ -127,7 +127,7 @@ const OnboardingModal = React.memo(function OnboardingModal({
@@ -298,7 +298,7 @@ const OnboardingModal = React.memo(function OnboardingModal({
) : ( diff --git a/frontend/src/components/SettingsPanel.tsx b/frontend/src/components/SettingsPanel.tsx index 2bc30c8..96e289f 100644 --- a/frontend/src/components/SettingsPanel.tsx +++ b/frontend/src/components/SettingsPanel.tsx @@ -829,7 +829,7 @@ const SettingsPanel = React.memo(function SettingsPanel({

SYSTEM CONFIG

- + SETTINGS & DATA SOURCES
@@ -848,15 +848,15 @@ const SettingsPanel = React.memo(function SettingsPanel({
-
WORMHOLE FIRST-RUN
-
+
WORMHOLE FIRST-RUN
+
Wormhole join below does not need operator tools. API/news tabs do.
@@ -868,7 +868,7 @@ const SettingsPanel = React.memo(function SettingsPanel({ size={12} className={adminSessionReady ? 'text-green-400' : 'text-yellow-500'} /> - + OPERATOR TOOLS {adminSessionReady ? ( @@ -899,7 +899,7 @@ const SettingsPanel = React.memo(function SettingsPanel({ @@ -907,13 +907,13 @@ const SettingsPanel = React.memo(function SettingsPanel({ {activeTab === 'protocol' && ( )} @@ -923,7 +923,7 @@ const SettingsPanel = React.memo(function SettingsPanel({ {adminSessionMsg && (
@@ -934,7 +934,7 @@ const SettingsPanel = React.memo(function SettingsPanel({ )} {adminSessionMsg === 'BACKEND ADMIN KEY NOT CONFIGURED' && activeTab !== 'protocol' && ( -
+
This is not an old market/API key problem. The backend admin secret itself is not configured, so protected Settings tabs cannot load. @@ -945,18 +945,18 @@ const SettingsPanel = React.memo(function SettingsPanel({ const el = document.querySelector('input[type="password"]'); el?.focus(); }} - className="px-3 py-1.5 border border-yellow-400/40 bg-yellow-950/20 text-[9px] font-mono tracking-[0.18em] text-yellow-200 hover:bg-yellow-950/30" + className="px-3 py-1.5 border border-yellow-400/40 bg-yellow-950/20 text-[13px] font-mono tracking-[0.18em] text-yellow-200 hover:bg-yellow-950/30" > PASTE ADMIN KEY
-
+
Add ADMIN_KEY to{' '} backend/.env, restart the backend, then paste that same key above and unlock. @@ -967,14 +967,14 @@ const SettingsPanel = React.memo(function SettingsPanel({
{wormholeMsg && (
{wormholeMsg.text}
)} {wormholeNodeId && (
-
+
YOUR WORMHOLE IDENTITY
@@ -1082,7 +1082,7 @@ const SettingsPanel = React.memo(function SettingsPanel({ setTimeout(() => setWormholeKeyCopied(false), 2000); } catch { /* clipboard not available */ } }} - className="shrink-0 px-2 py-1 border border-cyan-500/30 text-cyan-400 hover:bg-cyan-950/30 transition-colors text-[9px] font-mono flex items-center gap-1" + className="shrink-0 px-2 py-1 border border-cyan-500/30 text-cyan-400 hover:bg-cyan-950/30 transition-colors text-[13px] font-mono flex items-center gap-1" title="Copy identity to clipboard" > {wormholeKeyCopied ? : } @@ -1100,7 +1100,7 @@ const SettingsPanel = React.memo(function SettingsPanel({
- + HIGH PRIVACY MODE (OPT-IN)
@@ -1109,19 +1109,19 @@ const SettingsPanel = React.memo(function SettingsPanel({ const next = privacyProfile !== 'high'; setHighPrivacy(next); }} - className={`px-2 py-1 border text-[9px] font-mono tracking-widest transition-colors ${privacyProfile === 'high' ? 'border-green-500/40 text-green-400 bg-green-950/20' : 'border-[var(--border-primary)] text-[var(--text-muted)] hover:text-[var(--text-secondary)]'}`} + className={`px-2 py-1 border text-[13px] font-mono tracking-widest transition-colors ${privacyProfile === 'high' ? 'border-green-500/40 text-green-400 bg-green-950/20' : 'border-[var(--border-primary)] text-[var(--text-muted)] hover:text-[var(--text-secondary)]'}`} > {privacyProfile === 'high' ? 'ON' : 'OFF'}
-

+

Enables High Privacy profile: session-only identity, stronger jitter, sharded transport (when available), and stricter sync behavior. High Privacy requires the local agent for mesh traffic and refuses clearnet fallback for obfuscated sends. This does not make you anonymous or fully hidden.

{privacyProfile === 'high' && ( -
+
Recommendation: use a reputable VPN or hidden transport. A VPN can help hide your IP from the backend and peers, but it does not eliminate metadata, endpoint compromise, or traffic analysis risks. @@ -1134,7 +1134,7 @@ const SettingsPanel = React.memo(function SettingsPanel({
- + EPHEMERAL SESSION ID (RECOMMENDED)
@@ -1146,21 +1146,21 @@ const SettingsPanel = React.memo(function SettingsPanel({ migratePrivacySensitiveBrowserState(); if (next) clearSessionIdentity(); }} - className={`px-2 py-1 border text-[9px] font-mono tracking-widest transition-colors ${sessionMode ? 'border-green-500/40 text-green-400 bg-green-950/20' : 'border-[var(--border-primary)] text-[var(--text-muted)] hover:text-[var(--text-secondary)]'}`} + className={`px-2 py-1 border text-[13px] font-mono tracking-widest transition-colors ${sessionMode ? 'border-green-500/40 text-green-400 bg-green-950/20' : 'border-[var(--border-primary)] text-[var(--text-muted)] hover:text-[var(--text-secondary)]'}`} > {sessionMode ? 'ON' : 'OFF'}
-

+

When enabled, agent keys are stored in session storage and reset on browser close. Your identity will not persist across restarts.

-
+
WIPE LOCAL MESH TRACES
-

+

Clears browser-held mesh identities, DM ratchet state, cached contacts, and privacy-sensitive browser storage. The local agent is not shut down.

@@ -1170,7 +1170,7 @@ const SettingsPanel = React.memo(function SettingsPanel({ void wipeLocalMeshTraces(); }} disabled={browserWipeBusy} - className={`shrink-0 px-2 py-1 border text-[9px] font-mono tracking-widest transition-colors ${ + className={`shrink-0 px-2 py-1 border text-[13px] font-mono tracking-widest transition-colors ${ browserWipeBusy ? 'border-[var(--border-primary)] text-[var(--text-muted)] opacity-60 cursor-not-allowed' : 'border-yellow-500/40 text-yellow-300 bg-yellow-950/20 hover:text-yellow-200' @@ -1181,7 +1181,7 @@ const SettingsPanel = React.memo(function SettingsPanel({
{browserWipeMsg && (
@@ -1195,25 +1195,25 @@ const SettingsPanel = React.memo(function SettingsPanel({
- + LOCAL MESH AGENT (OPT-IN)
-

+

Runs a local mesh agent that handles traffic directly, removing the backend as a central observer. Experimental — does not guarantee privacy or anonymity.

- + TRANSPORT
-
diff --git a/frontend/src/components/ShodanPanel.tsx b/frontend/src/components/ShodanPanel.tsx index 1a7dd24..522e9a0 100644 --- a/frontend/src/components/ShodanPanel.tsx +++ b/frontend/src/components/ShodanPanel.tsx @@ -505,7 +505,7 @@ export default function ShodanPanel({ SHODAN CONNECTOR
-
+
{currentResults.length.toLocaleString()} MAP @@ -522,7 +522,7 @@ export default function ShodanPanel({ {!isMinimized && ( <> -
+
@@ -536,7 +536,7 @@ export default function ShodanPanel({
-
+
{(['search', 'count', 'host'] as Mode[]).map((item) => (
{/* Size */}
-
SIZE
+
SIZE
{SIZE_OPTIONS.map((opt) => (
-
PRESETS / EXPORT
+
PRESETS / EXPORT
setPresetLabel(e.target.value)} placeholder="preset label" - className="flex-1 border border-green-900/50 bg-black/70 px-2 py-1.5 text-[10px] text-green-300 outline-none transition-colors focus:border-green-500/60" + className="flex-1 border border-green-900/50 bg-black/70 px-2 py-1.5 text-sm text-green-300 outline-none transition-colors focus:border-green-500/60" />
-
+
@@ -838,7 +838,7 @@ export default function ShodanPanel({ )}
-
+
SESSION STATUS @@ -852,7 +852,7 @@ export default function ShodanPanel({ @@ -863,16 +863,16 @@ export default function ShodanPanel({ {countSummary && (
-
FACETS
+
FACETS
{Object.entries(countSummary.facets).length === 0 ? ( -
No facet buckets returned.
+
No facet buckets returned.
) : ( Object.entries(countSummary.facets).map(([name, buckets]) => (
-
{name.toUpperCase()}
+
{name.toUpperCase()}
{buckets.map((bucket) => ( -
+
{bucket.value || 'UNKNOWN'} {bucket.count.toLocaleString()}
@@ -885,7 +885,7 @@ export default function ShodanPanel({ )} {hostSummary && ( -
+
{hostSummary.ip} {hostSummary.location_label || 'UNMAPPED'} @@ -905,7 +905,7 @@ export default function ShodanPanel({ {currentResults.length > 0 && (
-
+
MAPPED HOSTS {currentResults.length.toLocaleString()}
@@ -917,15 +917,15 @@ export default function ShodanPanel({ className="flex w-full items-center justify-between border border-green-950/40 bg-green-950/10 px-2 py-1.5 text-left transition-colors hover:border-green-700/60 hover:bg-green-950/20" >
-
+
{match.ip} {match.port ? `:${match.port}` : ''}
-
+
{match.location_label || match.org || 'UNMAPPED'}
-
+
{match.product || match.transport || 'HOST'}