Files
investment-sandbox/components/modules/tech/AiSpecialSilo.tsx
2026-06-13 15:16:57 +02:00

670 lines
30 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import React, { useState, useEffect } from 'react';
import { LineChart, Line, ResponsiveContainer } from 'recharts';
import 'katex/dist/katex.min.css';
import TechMathModal from './TechMathModal';
import TechBlueprintModal from './TechBlueprintModal';
import {
Cpu, AlertCircle, BookOpen, Activity, Zap, TrendingUp, TrendingDown,
ArrowUpRight, ArrowDownRight, Minus, Server, Wallet
} from 'lucide-react';
interface TickerMetricData {
quarter: string;
value: number;
}
interface SupplyChainDataPoint {
quarter: string;
nvdaInvTurnover: number;
aggregateObligations: number;
velocityIndex: number;
}
interface Payload {
dates: string[];
liveDataAvailable: boolean;
timestamp: number;
metrics: {
monetizationGap: {
name: string;
tickers: Record<string, {
current: number;
previous: number;
trend: 'UP' | 'DOWN' | 'FLAT';
segmentRevenueGrowth: number;
capexGrowth: number;
roiToCapex: number;
data: {
quarter: string;
monetizationGap: number;
roiToCapex: number;
segmentRevenueGrowth: number;
capexGrowth: number;
}[];
}>;
};
supplyChain: {
name: string;
unit: string;
currentVelocity: number;
previousVelocity: number;
currentTurnover: number;
currentObligations: number;
trend: 'UP' | 'DOWN' | 'FLAT';
data: SupplyChainDataPoint[];
};
infrastructure: {
name: string;
tickers: Record<string, {
currentDE: number;
currentCapExDep: number;
trendDE: 'UP' | 'DOWN' | 'FLAT';
data: {
quarter: string;
de: number;
capexDep: number;
debt: number;
equity: number;
}[];
}>;
};
sloan: {
name: string;
tickers: Record<string, {
currentSloan: number;
currentRegime: 'SAFE' | 'ANOMALY';
data: {
quarter: string;
accruals: number;
sloanRatio: number;
regime: 'SAFE' | 'ANOMALY';
}[];
}>;
};
};
}
export default function AiSpecialSilo() {
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [payload, setPayload] = useState<Payload | null>(null);
const [activeTab, setActiveTab] = useState<'matrix' | 'supply_chain'>('matrix');
const [isMathModalOpen, setIsMathModalOpen] = useState(false);
const [isBlueprintModalOpen, setIsBlueprintModalOpen] = useState(false);
const [isShieldActive, setIsShieldActive] = useState(false);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
setError(null);
try {
const response = await fetch('/api/tech/ai');
if (response.ok) {
const data = await response.json();
setPayload(data);
setIsShieldActive(!!data.isShieldActive);
} else {
setError('Error fetching AI Tech Hyper-Leverage metrics.');
}
} catch (err) {
console.error('Fetch tech metrics error:', err);
setError('Network error loading AI Special Silo data.');
} finally {
setLoading(false);
}
};
fetchData();
}, []);
if (loading) {
return (
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-8 text-slate-100 shadow-xl min-h-[450px] flex flex-col items-center justify-center space-y-4">
<div className="w-10 h-10 rounded-full border-2 border-teal-400 border-t-transparent animate-spin" />
<div className="text-slate-400 text-sm font-mono animate-pulse">Ingesting quarterly balance sheets & tech indicators...</div>
</div>
);
}
if (error || !payload) {
return (
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 text-slate-100 shadow-xl min-h-[400px] flex items-center justify-center">
<div className="text-rose-400 font-semibold flex items-center gap-2">
<AlertCircle className="w-5 h-5" /> {error || 'Error loading data.'}
</div>
</div>
);
}
const { monetizationGap, supplyChain, infrastructure, sloan } = payload.metrics;
// HSL Status Colors based on metric thresholds
const getMonetizationStatus = () => {
const gaps = Object.values(monetizationGap.tickers).map(t => t.current);
const minGap = Math.min(...gaps);
if (minGap < -15) return 'RED';
if (minGap < 0) return 'AMBER';
return 'GREEN';
};
const getSupplyChainStatus = () => {
const vel = supplyChain.currentVelocity;
if (vel < 1.8 || supplyChain.trend === 'DOWN') return 'RED';
if (vel < 3.0) return 'AMBER';
return 'GREEN';
};
const getInfrastructureStatus = () => {
const ratios = Object.values(infrastructure.tickers).map(t => t.currentCapExDep);
const maxRatio = Math.max(...ratios);
const des = Object.values(infrastructure.tickers).map(t => t.currentDE);
const maxDE = Math.max(...des);
if (maxRatio > 4.0 || maxDE > 1.2) return 'RED';
if (maxRatio > 2.5 || maxDE > 0.8) return 'AMBER';
return 'GREEN';
};
const getSloanStatus = () => {
const hasAnomaly = Object.values(sloan.tickers).some(t => t.currentRegime === 'ANOMALY');
return hasAnomaly ? 'ANOMALY' : 'SAFE';
};
const monetizationStatus = getMonetizationStatus();
const supplyStatus = getSupplyChainStatus();
const infraStatus = getInfrastructureStatus();
const sloanStatus = getSloanStatus();
// Helper for trend icons
const renderTrendIcon = (trend: 'UP' | 'DOWN' | 'FLAT', isDangerUp = false) => {
const baseClass = "w-3.5 h-3.5 inline-block align-middle";
if (trend === 'UP') {
return <ArrowUpRight className={`${baseClass} ${isDangerUp ? 'text-rose-400' : 'text-emerald-400'}`} />;
}
if (trend === 'DOWN') {
return <ArrowDownRight className={`${baseClass} ${isDangerUp ? 'text-emerald-400' : 'text-rose-400'}`} />;
}
return <Minus className={`${baseClass} text-slate-500`} />;
};
return (
<div className="space-y-6">
{/* ⚠️ Dynamic Rate-Limit Fallback Banner */}
{!payload.liveDataAvailable && (
<div className="bg-rose-955/40 border border-rose-800/80 text-rose-400 text-xs rounded-xl p-4 flex items-center gap-3 shadow-[0_0_15px_rgba(244,63,94,0.15)] animate-pulse">
<AlertCircle className="w-5 h-5 text-rose-400 shrink-0" />
<div className="flex-1">
<span className="font-bold font-mono uppercase tracking-wider block mb-0.5">[ API Limit - Fallback Archive Active]</span>
Real-time API balance sheet fetches are rate-limited (FMP HTTP 429). The workstation has initialized fallback calculations using the high-fidelity historical archive.
</div>
</div>
)}
{/* HEADER SECTION */}
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 text-slate-100 shadow-xl relative overflow-hidden">
<div className="absolute top-0 right-0 w-32 h-32 bg-teal-500/10 rounded-full blur-3xl -z-10" />
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
<div className="space-y-1">
<span className="text-teal-400 text-xs font-semibold uppercase tracking-wider">AI & Tech Silo</span>
<h2 className="text-2xl font-extrabold text-white flex flex-wrap items-center gap-2">
<Zap className="text-teal-400 w-6 h-6" />
<span>AI Hyper-Leverage & CapEx Matrix</span>
{isShieldActive ? (
<span className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-bold bg-amber-500/10 text-amber-400 border border-amber-500/20 shadow-[0_0_10px_rgba(245,158,11,0.15)] ml-2 animate-pulse">
<span className="w-1.5 h-1.5 rounded-full bg-amber-500" />
DEV ARCHIVE ACTIVE (0 CALLS)
</span>
) : (
<span className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-bold bg-emerald-500/10 text-emerald-400 border border-emerald-500/20 shadow-[0_0_10px_rgba(16,185,129,0.15)] ml-2">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-ping" />
LIVE API ENDPOINT (FMP CORPO)
</span>
)}
</h2>
<p className="text-xs text-slate-400">
Monitors Big Tech capital expenditures, segment revenues, and inventory velocities to diagnose infrastructure bubbles.
</p>
</div>
<div className="flex items-center gap-3 w-full md:w-auto justify-end">
<button
onClick={() => setIsMathModalOpen(true)}
className="flex items-center gap-1.5 px-4 py-2.5 rounded-xl bg-slate-950/80 hover:bg-slate-900 border border-slate-800 hover:border-slate-700 transition-all font-semibold text-xs tracking-wider text-teal-400 w-full md:w-auto justify-center h-11 cursor-pointer"
>
<BookOpen className="w-4 h-4" />
<span>📖 Quantitative Handbook</span>
</button>
<button
onClick={() => setIsBlueprintModalOpen(true)}
className="flex items-center gap-1.5 px-4 py-2.5 rounded-xl bg-slate-950/80 hover:bg-slate-900 border border-slate-800 hover:border-slate-700 transition-all font-semibold text-xs tracking-wider text-teal-400 w-full md:w-auto justify-center h-11 cursor-pointer animate-pulse-slow"
>
<Cpu className="w-4 h-4" />
<span> Operational Blueprint</span>
</button>
<div className="bg-slate-950/80 border border-slate-800 rounded-xl px-4 py-2 text-right shrink-0 h-11 flex flex-col justify-center">
<div className="text-[9px] text-slate-500 uppercase font-mono">Archive State</div>
<div className="font-mono text-xs text-slate-300">
{new Date(payload.timestamp).toLocaleTimeString()}
</div>
</div>
</div>
</div>
</div>
{/* 🚥 4 LARGE GLOWING NEON-AMPEL CARDS */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
{/* CARD 1: ROI-to-CapEx & Monetization Gap */}
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-850 rounded-2xl p-5 relative overflow-hidden shadow-lg flex flex-col justify-between min-h-[140px]">
<div className="absolute top-0 right-0 w-24 h-24 bg-gradient-to-br from-indigo-500/10 to-transparent rounded-full blur-2xl pointer-events-none" />
<div className="flex justify-between items-start">
<div className="space-y-1">
<div className="text-[10px] text-indigo-400 uppercase font-bold tracking-widest font-mono">1. ROI-to-CapEx & Monetization Gap</div>
<div className="text-lg font-black text-white leading-tight">Monetization Gap</div>
<div className="text-[10px] text-slate-400">YoY Segment Rev Growth minus CapEx Growth</div>
</div>
<span className={`w-3.5 h-3.5 rounded-full ${
monetizationStatus === 'GREEN' ? 'bg-emerald-500 shadow-[0_0_10px_#10b981]' :
monetizationStatus === 'AMBER' ? 'bg-amber-500 shadow-[0_0_10px_#fbbf24]' :
'bg-rose-500 shadow-[0_0_10px_#f43f5e] animate-pulse'
}`} />
</div>
<div className="mt-4 pt-4 border-t border-slate-850 flex justify-between items-end">
<div>
<div className="text-[9px] uppercase font-mono text-slate-500">Max Divergence</div>
<div className="font-mono text-xl font-bold text-slate-200">
{Math.min(...Object.values(monetizationGap.tickers).map(t => t.current)).toFixed(1)}%
</div>
</div>
<div className="text-right">
<div className="text-[9px] uppercase font-mono text-slate-500">Global Trend</div>
<div className="text-xs font-semibold text-slate-300 flex items-center gap-1 justify-end">
{renderTrendIcon(monetizationStatus === 'GREEN' ? 'UP' : 'DOWN')}
<span>{monetizationStatus === 'GREEN' ? 'Stable' : monetizationStatus === 'AMBER' ? 'Diverging' : 'Bubble Risk'}</span>
</div>
</div>
</div>
</div>
{/* CARD 2: Nvidia Supply-Chain Velocity */}
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-850 rounded-2xl p-5 relative overflow-hidden shadow-lg flex flex-col justify-between min-h-[140px]">
<div className="absolute top-0 right-0 w-24 h-24 bg-gradient-to-br from-teal-500/10 to-transparent rounded-full blur-2xl pointer-events-none" />
<div className="flex justify-between items-start">
<div className="space-y-1">
<div className="text-[10px] text-teal-400 uppercase font-bold tracking-widest font-mono">2. Supply-Chain Commitments</div>
<div className="text-lg font-black text-white leading-tight">Nvidia SC Velocity</div>
<div className="text-[10px] text-slate-400">Buyer commitments relative to NVDA inventory</div>
</div>
<span className={`w-3.5 h-3.5 rounded-full ${
supplyStatus === 'GREEN' ? 'bg-emerald-500 shadow-[0_0_10px_#10b981]' :
supplyStatus === 'AMBER' ? 'bg-amber-500 shadow-[0_0_10px_#fbbf24]' :
'bg-rose-500 shadow-[0_0_10px_#f43f5e] animate-pulse'
}`} />
</div>
<div className="mt-4 pt-4 border-t border-slate-850 flex justify-between items-end">
<div>
<div className="text-[9px] uppercase font-mono text-slate-500">Velocity Index</div>
<div className="font-mono text-xl font-bold text-slate-200">
{supplyChain.currentVelocity}x
</div>
</div>
<div className="text-right">
<div className="text-[9px] uppercase font-mono text-slate-500">NVDA Inv Turnover</div>
<div className="font-mono text-xs font-bold text-slate-355">
{supplyChain.currentTurnover}x
</div>
</div>
</div>
</div>
{/* CARD 3: Tech Infrastructure Leverage */}
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-850 rounded-2xl p-5 relative overflow-hidden shadow-lg flex flex-col justify-between min-h-[140px]">
<div className="absolute top-0 right-0 w-24 h-24 bg-gradient-to-br from-purple-500/10 to-transparent rounded-full blur-2xl pointer-events-none" />
<div className="flex justify-between items-start">
<div className="space-y-1">
<div className="text-[10px] text-purple-400 uppercase font-bold tracking-widest font-mono">3. Cluster Construction Leverage</div>
<div className="text-lg font-black text-white leading-tight">Infrastructure Leverage</div>
<div className="text-[10px] text-slate-400">Aggressive CapEx-to-Depreciation ratios</div>
</div>
<span className={`w-3.5 h-3.5 rounded-full ${
infraStatus === 'GREEN' ? 'bg-emerald-500 shadow-[0_0_10px_#10b981]' :
infraStatus === 'AMBER' ? 'bg-amber-500 shadow-[0_0_10px_#fbbf24]' :
'bg-rose-500 shadow-[0_0_10px_#f43f5e] animate-pulse'
}`} />
</div>
<div className="mt-4 pt-4 border-t border-slate-850 flex justify-between items-end">
<div>
<div className="text-[9px] uppercase font-mono text-slate-500">Max CapEx/Dep</div>
<div className="font-mono text-xl font-bold text-slate-200">
{Math.max(...Object.values(infrastructure.tickers).map(t => t.currentCapExDep)).toFixed(1)}x
</div>
</div>
<div className="text-right">
<div className="text-[9px] uppercase font-mono text-slate-500">Structural Debt</div>
<div className="font-mono text-xs font-bold text-slate-355">
Max D/E: {Math.max(...Object.values(infrastructure.tickers).map(t => t.currentDE)).toFixed(2)}
</div>
</div>
</div>
</div>
{/* CARD 4: Sloan Earnings Quality */}
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-850 rounded-2xl p-5 relative overflow-hidden shadow-lg flex flex-col justify-between min-h-[140px]">
<div className="absolute top-0 right-0 w-24 h-24 bg-gradient-to-br from-teal-500/10 to-transparent rounded-full blur-2xl pointer-events-none" />
<div className="flex justify-between items-start">
<div className="space-y-1">
<div className="text-[10px] text-teal-400 uppercase font-bold tracking-widest font-mono">4. Earnings Accrual Integrity</div>
<div className="text-lg font-black text-white leading-tight">Sloan Earnings Quality</div>
<div className="text-[10px] text-slate-400">Richard Sloan Accounting Anomaly Radar</div>
</div>
<span className={`w-3.5 h-3.5 rounded-full ${
sloanStatus === 'SAFE' ? 'bg-emerald-500 shadow-[0_0_10px_#10b981]' :
'bg-rose-500 shadow-[0_0_10px_#f43f5e] animate-pulse'
}`} />
</div>
<div className="mt-4 pt-4 border-t border-slate-850 flex justify-between items-end">
<div>
<div className="text-[9px] uppercase font-mono text-slate-500">Max Accrual Spread</div>
<div className="font-mono text-xl font-bold text-slate-200">
{Math.max(...Object.values(sloan.tickers).map(t => Math.abs(t.currentSloan))).toFixed(1)}%
</div>
</div>
<div className="text-right">
<div className="text-[9px] uppercase font-mono text-slate-500">Silo Status</div>
<div className="text-xs font-semibold text-slate-300 flex items-center gap-1 justify-end">
{sloanStatus === 'SAFE' ? (
<span className="text-emerald-400">Safe Regime</span>
) : (
<span className="text-rose-400 animate-pulse font-bold">Anomaly Warning</span>
)}
</div>
</div>
</div>
</div>
</div>
{/* DETAILED LEDGER GRID */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* PANEL A: ROI-TO-CAPEX & MONETIZATION GAPS */}
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 shadow-xl space-y-4">
<div className="space-y-0.5">
<h3 className="text-sm font-bold text-white flex items-center gap-2">
<Activity className="w-4 h-4 text-indigo-400" /> Monetization Gap & Segment Returns
</h3>
<p className="text-[10px] text-slate-400">
Compares quarterly segment revenue growth trends against CapEx growth.
</p>
</div>
<div className="space-y-3">
{Object.entries(monetizationGap.tickers).map(([ticker, metrics]) => {
const currentGap = metrics.current;
const gapColorClass = currentGap >= 0
? 'text-emerald-400'
: currentGap >= -15
? 'text-amber-400 font-semibold'
: 'text-rose-400 font-bold animate-pulse';
const strokeColor = currentGap >= 0
? '#10b981'
: currentGap >= -15
? '#fbbf24'
: '#f43f5e';
return (
<div key={ticker} className="bg-slate-950/40 border border-slate-850 rounded-xl p-3 flex justify-between items-center hover:bg-slate-900/60 transition-colors">
<div className="space-y-0.5 w-1/4">
<div className="text-xs font-bold text-slate-200">{ticker}</div>
<div className="text-[9px] text-slate-500 font-mono">
Seg Rev QoQ: {metrics.segmentRevenueGrowth > 0 ? '+' : ''}{metrics.segmentRevenueGrowth}%
</div>
</div>
{/* Sparkline for Monetization Gap */}
<div className="w-1/3 h-8">
<ResponsiveContainer width="100%" height="100%">
<LineChart data={metrics.data}>
<Line
type="monotone"
dataKey="monetizationGap"
stroke={strokeColor}
strokeWidth={1.5}
dot={false}
/>
</LineChart>
</ResponsiveContainer>
</div>
<div className="text-right w-1/3 space-y-0.5">
<div className="text-xs font-mono text-slate-400">
ROI: <span className="font-semibold text-slate-200">{metrics.roiToCapex}%</span>
</div>
<div className={`font-mono text-sm font-bold ${gapColorClass}`}>
Gap: {currentGap > 0 ? '+' : ''}{currentGap}%
</div>
</div>
</div>
);
})}
</div>
</div>
{/* PANEL B: TECH INFRASTRUCTURE LEVERAGE & CLUSTER HEALTH */}
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 shadow-xl space-y-4">
<div className="space-y-0.5">
<h3 className="text-sm font-bold text-white flex items-center gap-2">
<Server className="w-4 h-4 text-purple-400" /> Cluster Construction & Leverage Ratios
</h3>
<p className="text-[10px] text-slate-400">
Tracks structural debt loads and CapEx spending compared to depreciation rate vectors.
</p>
</div>
<div className="space-y-3">
{Object.entries(infrastructure.tickers).map(([ticker, metrics]) => {
const currentCapExDep = metrics.currentCapExDep;
const highlightClass = currentCapExDep > 4.0
? 'text-rose-400 font-bold animate-pulse'
: currentCapExDep > 2.5
? 'text-amber-400 font-semibold'
: 'text-emerald-400';
const strokeColor = currentCapExDep > 4.0
? '#f43f5e'
: currentCapExDep > 2.5
? '#fbbf24'
: '#10b981';
return (
<div key={ticker} className="bg-slate-950/40 border border-slate-850 rounded-xl p-3 flex justify-between items-center hover:bg-slate-900/60 transition-colors">
<div className="space-y-0.5 w-1/4">
<div className="text-xs font-bold text-slate-200">{ticker}</div>
<div className="text-[9px] text-slate-500 font-mono">
D/E: {metrics.currentDE.toFixed(2)}
</div>
</div>
{/* Sparkline for D/E Ratio */}
<div className="w-1/3 h-8">
<ResponsiveContainer width="100%" height="100%">
<LineChart data={metrics.data}>
<Line
type="monotone"
dataKey="de"
stroke={strokeColor}
strokeWidth={1.5}
dot={false}
/>
</LineChart>
</ResponsiveContainer>
</div>
<div className="text-right w-1/3">
<div className="text-[9px] text-slate-500 uppercase font-mono">CapEx/Depreciation</div>
<div className={`font-mono text-sm font-bold ${highlightClass}`}>
{currentCapExDep.toFixed(1)}x
</div>
</div>
</div>
);
})}
</div>
</div>
{/* PANEL D: SLOAN EARNINGS QUALITY ACCRUAL RADAR */}
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 shadow-xl space-y-4">
<div className="space-y-0.5">
<h3 className="text-sm font-bold text-white flex items-center gap-2">
<Activity className="w-4 h-4 text-emerald-400" /> Sloan Accrual Quality Radar
</h3>
<p className="text-[10px] text-slate-400">
Richard Sloan Accrual Index. Anomalies (&gt;10% or &lt;-10%) indicate aggressive accounting.
</p>
</div>
<div className="space-y-3">
{Object.entries(sloan.tickers).map(([ticker, metrics]) => {
const currentSloan = metrics.currentSloan;
const isAnomaly = metrics.currentRegime === 'ANOMALY';
const highlightClass = isAnomaly
? 'text-rose-400 font-bold animate-pulse'
: 'text-emerald-400';
const strokeColor = isAnomaly
? '#f43f5e'
: '#10b981';
return (
<div key={ticker} className="bg-slate-950/40 border border-slate-850 rounded-xl p-3 flex justify-between items-center hover:bg-slate-900/60 transition-colors">
<div className="space-y-0.5 w-1/4">
<div className="text-xs font-bold text-slate-200">{ticker}</div>
<div className="text-[9px] text-slate-500 font-mono">
Regime: {metrics.currentRegime}
</div>
</div>
{/* Sparkline for Sloan Ratio */}
<div className="w-1/3 h-8">
<ResponsiveContainer width="100%" height="100%">
<LineChart data={metrics.data}>
<Line
type="monotone"
dataKey="sloanRatio"
stroke={strokeColor}
strokeWidth={1.5}
dot={false}
/>
</LineChart>
</ResponsiveContainer>
</div>
<div className="text-right w-1/3">
<div className="text-[9px] text-slate-500 uppercase font-mono">Sloan Ratio</div>
<div className={`font-mono text-sm font-bold ${highlightClass}`}>
{currentSloan.toFixed(2)}%
</div>
</div>
</div>
);
})}
</div>
</div>
</div>
{/* PANEL C: SUPPLY CHAIN FLOW DETAILS */}
<div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 shadow-xl space-y-4">
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4 border-b border-slate-850 pb-4">
<div className="space-y-0.5">
<h3 className="text-sm font-bold text-white flex items-center gap-2">
<Cpu className="w-4 h-4 text-teal-400" /> Nvidia Supply-Chain Velocity Timeline
</h3>
<p className="text-[10px] text-slate-400">
Tracks the velocity of purchase commitments from top buyers (MSFT, GOOGL, META) relative to Nvidia's inventories.
</p>
</div>
<div className="flex items-center gap-4 text-xs font-mono text-slate-400 bg-slate-900/80 border border-slate-850 px-3 py-1.5 rounded-xl">
<div>
NVDA Inventory: <span className="text-slate-200 font-semibold">{supplyChain.data[supplyChain.data.length - 1].aggregateObligations / 1000}B$</span>
</div>
<div className="border-l border-slate-800 pl-4">
Commitments: <span className="text-slate-200 font-semibold">{supplyChain.currentObligations / 1000}B$</span>
</div>
</div>
</div>
<div className="overflow-x-auto">
<table className="w-full border-collapse text-left text-xs text-slate-400 font-mono">
<thead>
<tr className="border-b border-slate-850 text-[10px] text-slate-555 uppercase">
<th className="py-2">Quarter</th>
<th className="py-2 text-right">Nvidia Inventory Turnover</th>
<th className="py-2 text-right">Top Buyer Commitments</th>
<th className="py-2 text-right">Velocity Index</th>
<th className="py-2 text-center">Trend Indicator</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-850">
{supplyChain.data.map((row, idx) => {
const prevRow = idx > 0 ? supplyChain.data[idx - 1] : row;
const rowTrend = row.velocityIndex > prevRow.velocityIndex
? 'UP'
: row.velocityIndex < prevRow.velocityIndex
? 'DOWN'
: 'FLAT';
const velocityClass = row.velocityIndex < 2.0
? 'text-rose-400 font-semibold font-bold'
: row.velocityIndex < 3.0
? 'text-amber-400'
: 'text-emerald-400';
return (
<tr key={row.quarter} className="hover:bg-slate-900/20 transition-colors">
<td className="py-3 font-semibold text-slate-300">{row.quarter}</td>
<td className="py-3 text-right text-slate-300">{row.nvdaInvTurnover.toFixed(2)}x</td>
<td className="py-3 text-right text-slate-355">{(row.aggregateObligations / 1000).toFixed(1)}B$</td>
<td className="py-3 text-right"><span className={velocityClass}>{row.velocityIndex.toFixed(2)}x</span></td>
<td className="py-3 text-center">{renderTrendIcon(rowTrend, row.velocityIndex < 2.5)}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
{/* Modulerklärung Modal */}
<TechMathModal
isOpen={isMathModalOpen}
onClose={() => setIsMathModalOpen(false)}
/>
<TechBlueprintModal
isOpen={isBlueprintModalOpen}
onClose={() => setIsBlueprintModalOpen(false)}
/>
</div>
);
}