655 lines
29 KiB
TypeScript
655 lines
29 KiB
TypeScript
'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 {
|
||
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 [isMathModalOpen, setIsMathModalOpen] = 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-ARCHIV AKTIV (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 ENDPUNKT (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-955/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>📖 Modulerklärung</span>
|
||
</button>
|
||
|
||
<div className="bg-slate-955/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-955/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-955/40 border border-slate-850 rounded-xl p-3 flex justify-between items-center hover:bg-slate-955/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 (>10% or <-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-955/40 border border-slate-850 rounded-xl p-3 flex justify-between items-center hover:bg-slate-955/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-955/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-955/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)}
|
||
/>
|
||
|
||
</div>
|
||
);
|
||
}
|