fix: replace near-black NASA dashboard void with mission blue panels
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m15s
CI/CD Pipeline / Security Scanning (push) Successful in 2m33s
CI/CD Pipeline / Lint and Format (push) Failing after 46s
CI/CD Pipeline / Terraform Validation (push) Failing after 22s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 24s
Validation / validate-genesis (push) Successful in 25s
Validation / validate-terraform (push) Failing after 29s
Validation / validate-kubernetes (push) Failing after 10s
Validation / validate-smart-contracts (push) Failing after 11s
Validation / validate-security (push) Failing after 1m37s
Validation / validate-documentation (push) Failing after 20s

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-28 18:42:12 -07:00
parent 5fc98ed803
commit 3c7abd5a01
3 changed files with 166 additions and 84 deletions

View File

@@ -1,60 +1,120 @@
import { Link, Outlet, useLocation } from 'react-router-dom';
import { useRef } from 'react';
import WalletConnect from '../wallet/WalletConnect';
import WalletDisconnectNotice from '../wallet/WalletDisconnectNotice';
import NasaIcon, { type NasaIconName } from '../icons/NasaIcon';
const PRODUCTS: { path: string; label: string; icon: NasaIconName }[] = [
{ path: '/central-bank', label: 'Central Bank', icon: 'central-bank' },
{ path: '/office-24', label: 'Office 24', icon: 'office' },
{ path: '/trade', label: 'DBIS Trade', icon: 'trade' },
{ path: '/swap', label: 'Digital Swap', icon: 'swap' },
];
export default function OmnlProductLayout() {
const location = useLocation();
const userInitiatedDisconnectRef = useRef(false);
const isActive = (path: string) => location.pathname.startsWith(path);
return (
<div className="omnl-app min-h-screen flex flex-col">
<WalletDisconnectNotice userInitiatedDisconnectRef={userInitiatedDisconnectRef} />
<header className="omnl-app-header sticky top-0 z-50 border-b">
<div className="max-w-[1600px] mx-auto px-4 h-14 flex items-center gap-4">
<Link to="/central-bank" className="flex items-center gap-2 shrink-0">
<span className="w-8 h-8 border border-[#1e4a8a] bg-[#0a1224] text-[#00d4ff] font-bold flex items-center justify-center text-sm">
<NasaIcon name="satellite" size={16} className="nasa-icon--telemetry" />
</span>
<span className="nasa-nav-brand font-semibold hidden sm:inline text-sm">OMNL Mission Control</span>
</Link>
import { Link, Outlet, useLocation } from 'react-router-dom';
import { useRef } from 'react';
import WalletConnect from '../wallet/WalletConnect';
import WalletDisconnectNotice from '../wallet/WalletDisconnectNotice';
import NasaIcon, { type NasaIconName } from '../icons/NasaIcon';
const PRODUCTS: { path: string; label: string; icon: NasaIconName }[] = [
{ path: '/central-bank', label: 'Central Bank', icon: 'central-bank' },
{ path: '/office-24', label: 'Office 24', icon: 'office' },
{ path: '/trade', label: 'DBIS Trade', icon: 'trade' },
{ path: '/swap', label: 'Digital Swap', icon: 'swap' },
];
export default function OmnlProductLayout() {
const location = useLocation();
const userInitiatedDisconnectRef = useRef(false);
const isActive = (path: string) => location.pathname.startsWith(path);
return (
<div className="omnl-app min-h-screen flex flex-col">
<WalletDisconnectNotice userInitiatedDisconnectRef={userInitiatedDisconnectRef} />
<header className="omnl-app-header sticky top-0 z-50 border-b">
<div className="max-w-[1600px] mx-auto px-4 h-14 flex items-center gap-4">
<Link to="/central-bank" className="flex items-center gap-2 shrink-0">
<span className="w-8 h-8 border border-[#2d6bb8] bg-[#163a6b] text-[#00d4ff] font-bold flex items-center justify-center text-sm">
<NasaIcon name="satellite" size={16} className="nasa-icon--telemetry" />
</span>
<span className="nasa-nav-brand font-semibold hidden sm:inline text-sm">OMNL Mission Control</span>
</Link>
<nav className="flex items-center gap-1 flex-1 overflow-x-auto" aria-label="OMNL products">
{PRODUCTS.map(({ path, label, icon }) => (
<Link
key={path}
to={path}
className={`nasa-nav-link shrink-0 ${isActive(path) ? 'nasa-nav-link--active' : ''}`}
>
<NasaIcon name={icon} size={14} />
{label}
</Link>
))}
</nav>
<Link
to="/"
className="nasa-nav-link hidden md:inline shrink-0 !border-transparent"
>
<NasaIcon name="bridge" size={14} />
Bridge
</Link>
<WalletConnect onBeforeDisconnect={() => { userInitiatedDisconnectRef.current = true; }} />
</div>
</header>
<main className="flex-1">
<Outlet />
</main>
</div>
);
}

View File

@@ -169,8 +169,8 @@ export default function BinanceTradePanel() {
</div>
<div className="flex-1 grid grid-cols-1 xl:grid-cols-[1fr_280px] min-h-[320px]">
<div className="trade-chart bg-[#0b0e11] border-b xl:border-b-0 xl:border-r border-[#2b3139] p-4">
<div className="h-full min-h-[240px] rounded border border-[#2b3139] bg-[#181a20] flex items-end justify-around px-2 pb-2 gap-1">
<div className="trade-chart border-b xl:border-b-0 xl:border-r border-[#2d6bb8] p-4">
<div className="trade-chart__canvas h-full flex items-end justify-around px-2 pb-2 gap-1">
{Array.from({ length: 24 }, (_, i) => (
<div
key={i}
@@ -184,13 +184,13 @@ export default function BinanceTradePanel() {
</div>
<p className="text-xs text-[#848e9c] mt-2 text-center">Live chart · connect WebSocket feed for production</p>
</div>
<div className="trade-book hidden xl:block bg-[#181a20] p-2">
<div className="trade-book hidden xl:block p-2">
<p className="text-xs text-[#848e9c] uppercase px-2 py-1">Order book</p>
<OrderBookMock price={displayPrice} />
</div>
</div>
<div className="trade-recent border-t border-[#2b3139] bg-[#181a20] p-3 max-h-[140px] overflow-y-auto">
<div className="trade-recent border-t border-[#2d6bb8] p-3 max-h-[140px] overflow-y-auto">
<p className="text-xs text-[#848e9c] uppercase mb-2">Recent trades</p>
<div className="grid grid-cols-3 gap-2 text-xs font-mono text-[#848e9c]">
{((swap.monitor as { swaps?: { status: string; amountIn: string; createdAt: string }[] })?.swaps ?? [])
@@ -207,8 +207,8 @@ export default function BinanceTradePanel() {
</section>
{/* Trade panel */}
<aside className="trade-panel w-full lg:w-[320px] shrink-0 border-l border-[#2b3139] bg-[#181a20] flex flex-col">
<div className="flex border-b border-[#2b3139]">
<aside className="trade-panel w-full lg:w-[320px] shrink-0 border-l border-[#2d6bb8] flex flex-col">
<div className="flex border-b border-[#2d6bb8]">
<button
type="button"
className={`flex-1 py-3 text-sm font-semibold ${side === 'buy' ? 'text-[#0ecb81] border-b-2 border-[#0ecb81]' : 'text-[#848e9c]'}`}

View File

@@ -2,23 +2,31 @@
.omnl-app,
.nasa-mission-root {
--nasa-bg: #05070d;
--nasa-panel: #0a1224;
--nasa-panel-border: #1e4a8a;
--nasa-bg: #0f2847;
--nasa-bg-deep: #0a1a30;
--nasa-panel: #163a6b;
--nasa-panel-elevated: #1c4680;
--nasa-panel-border: #2d6bb8;
--nasa-telemetry: #00d4ff;
--nasa-nominal: #3dff8a;
--nasa-caution: #ffb347;
--nasa-critical: #fc3d21;
--nasa-text: #e8f4ff;
--nasa-muted: #7a9bb8;
--nasa-muted: #9bb8d4;
--nasa-mono: 'Share Tech Mono', ui-monospace, monospace;
}
html:has(.omnl-app),
html:has(.omnl-app) body {
background: var(--nasa-bg);
min-height: 100%;
}
.omnl-app {
background:
radial-gradient(ellipse at 20% 0%, rgba(11, 61, 145, 0.35) 0%, transparent 55%),
radial-gradient(ellipse at 80% 100%, rgba(0, 212, 255, 0.08) 0%, transparent 50%),
var(--nasa-bg);
radial-gradient(ellipse at 15% 0%, rgba(45, 107, 184, 0.45) 0%, transparent 50%),
radial-gradient(ellipse at 85% 100%, rgba(0, 212, 255, 0.12) 0%, transparent 45%),
linear-gradient(180deg, var(--nasa-bg) 0%, var(--nasa-bg-deep) 100%);
color: var(--nasa-text);
}
@@ -39,7 +47,7 @@
.nasa-panel, .dash-card, .o24-card, .cb-card {
position: relative;
background: linear-gradient(180deg, rgba(10, 18, 36, 0.95) 0%, rgba(5, 10, 22, 0.98) 100%);
background: linear-gradient(180deg, rgba(28, 70, 128, 0.92) 0%, rgba(22, 58, 107, 0.96) 100%);
border: 1px solid var(--nasa-panel-border);
border-radius: 2px;
padding: 1.15rem 1.25rem;
@@ -68,7 +76,7 @@
.nasa-header {
border: 1px solid var(--nasa-panel-border);
background: rgba(11, 61, 145, 0.12);
background: rgba(22, 58, 107, 0.55);
padding: 1rem 1.25rem;
}
@@ -201,7 +209,7 @@
.dash-banner--error .dash-banner__title { color: var(--nasa-critical); }
.dash-banner--loading {
background: rgba(10, 18, 36, 0.8);
background: rgba(22, 58, 107, 0.85);
}
.dash-stat-label {
@@ -273,7 +281,7 @@
font-size: 0.7rem;
letter-spacing: 0.04em;
color: var(--nasa-text);
background: rgba(10, 18, 36, 0.8);
background: rgba(22, 58, 107, 0.75);
border: 1px solid var(--nasa-panel-border);
transition: border-color 0.15s, color 0.15s;
}
@@ -323,7 +331,7 @@
width: 100%;
min-height: 44px;
padding: 0.5rem 0.75rem;
background: #05070d;
background: var(--nasa-panel-elevated);
border: 1px solid var(--nasa-panel-border);
color: var(--nasa-text);
font-family: var(--nasa-mono);
@@ -337,13 +345,13 @@
}
.nasa-inset-panel {
background: rgba(5, 7, 13, 0.6);
border: 1px solid rgba(30, 74, 138, 0.5);
background: rgba(15, 40, 71, 0.55);
border: 1px solid rgba(45, 107, 184, 0.55);
padding: 1rem;
}
.omnl-app-header {
background: rgba(5, 7, 13, 0.95) !important;
background: rgba(15, 40, 71, 0.92) !important;
border-color: var(--nasa-panel-border) !important;
box-shadow: 0 2px 16px rgba(0, 0, 0, 0.5);
}
@@ -396,7 +404,7 @@
display: grid;
grid-template-columns: 240px 1fr;
min-height: calc(100vh - 56px);
background: var(--nasa-bg);
background: transparent;
}
.trade-markets, .trade-panel, .trade-pair-header, .trade-recent, .trade-book {
@@ -404,8 +412,22 @@
border-color: var(--nasa-panel-border) !important;
}
.trade-center { min-height: 0; background: var(--nasa-bg); }
.trade-chart { background: var(--nasa-bg) !important; border-color: var(--nasa-panel-border) !important; }
.trade-center {
min-height: 0;
background: rgba(15, 40, 71, 0.35);
}
.trade-chart {
background: var(--nasa-panel) !important;
border-color: var(--nasa-panel-border) !important;
}
.trade-chart__canvas {
min-height: 240px;
border-radius: 2px;
border: 1px solid var(--nasa-panel-border);
background: linear-gradient(180deg, rgba(22, 58, 107, 0.95) 0%, rgba(15, 40, 71, 0.98) 100%);
}
.trade-market-row:hover { background: rgba(0, 212, 255, 0.08); }
.trade-market-row--active {
background: rgba(0, 212, 255, 0.12);