import { lazy, Suspense, useState, type ReactNode } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { PageHeader } from '../components/ui/PageHeader'; import { Callout } from '../components/ui/Callout'; import { Disclosure } from '../components/ui/Disclosure'; import { Badge } from '../components/ui/Badge'; import { SkeletonCard, SkeletonTable } from '../components/ui/Skeleton'; import { useAuthStore } from '../stores/authStore'; import { getEventStudy, getRegimeConfig, getRegimeFundamentals, getRegimeMonitor, refreshRegimeFundamentals, updateRegimeConfig, updateRegimeFundamentals, } from '../api/regime'; import type { CapexState, EventStudyReport, GoodNewsReaction, RegimeBand, RegimeConfig, RegimeFundamentalOverlay, RegimeFundamentals, RegimeFundamentalsUpdate, RegimeMonitor, RegimeReading, } from '../lib/types'; const RegimeChart = lazy(() => import('../components/regime/RegimeChart')); const BAND_STYLES: Record = { stable: { text: 'text-emerald-400', bar: 'bg-emerald-400', ring: 'border-emerald-400/30', label: 'Stable' }, watch: { text: 'text-amber-400', bar: 'bg-amber-400', ring: 'border-amber-400/30', label: 'Watch' }, elevated: { text: 'text-orange-400', bar: 'bg-orange-400', ring: 'border-orange-400/30', label: 'Elevated' }, breaking: { text: 'text-red-400', bar: 'bg-red-400', ring: 'border-red-400/30', label: 'High stress' }, }; function TrendChip({ label, delta }: { label: string; delta: number | null | undefined }) { if (delta == null) { return {label}: n/a; } const color = delta === 0 ? 'text-gray-400' : delta > 0 ? 'text-red-400' : 'text-emerald-400'; const arrow = delta === 0 ? '→' : delta > 0 ? '↑' : '↓'; return ( {label}: {arrow} {delta > 0 ? '+' : ''}{delta} ); } function ScoreGauge({ label, reading, footnote, }: { label: string; reading: RegimeReading | undefined; footnote: ReactNode; }) { const score = reading?.score; const complete = reading?.band != null; const style = complete ? BAND_STYLES[reading.band as RegimeBand] : null; const position = Math.min(100, Math.max(0, score ?? 0)); const bands = reading?.bands; // No fallback ticks: the two axes have different thresholds, so guessing a // shared set would mislabel one of them. Render none rather than wrong ones. const ticks = bands ? [bands.watch, bands.elevated, bands.breaking] : []; return (
{label}
{score == null ? '—' : Math.round(score)} {score != null && / 100}
{style?.label ?? 'Incomplete'} coverage {Math.round(reading?.coverage ?? 0)}%
{score != null && ( <> {/* The quadrant divider is each axis's watch/elevated boundary, so it is already the middle tick below — drawing it again was two marks for one threshold. */}
{/* Thresholds come from the reading: the two axes no longer share them. */}
0 {ticks.map((tick) => ( {tick} ))} 100
)}

{footnote}

); } const CAPEX_TONE: Record = { raising: 'text-emerald-400', holding: 'text-amber-400', cutting: 'text-red-400', unknown: 'text-gray-500', }; const OVERLAY_TITLE = 'Fundamental overlay · context, not scored'; function FundamentalOverlayCard({ overlay }: { overlay: RegimeFundamentalOverlay }) { const capex = overlay.capex ?? {}; const reaction = overlay.good_news_stock_down; // Nothing collected: the stored default is "unknown" for every hyperscaler // and "mixed" for the reaction, which are placeholders, not a reading. if (overlay.observed === false) { return (
{OVERLAY_TITLE}

No observation collected yet. An admin can collect one under Admin · Monitor settings. It is context only — it never enters State or Warning.

); } return (
{OVERLAY_TITLE}
{overlay.source && {overlay.source}} {/* When pending, the line below is the single carrier of this date. */} {overlay.effective_date && !overlay.pending && · effective {overlay.effective_date}} {overlay.pending && } {overlay.stale && }
{/* A pending observation is still shown — it is the freshest read we have, and nothing here is scored. The date says when the stored point-in-time record picks it up. */} {overlay.pending && (

Shown as collected. The point-in-time record picks it up{' '} {overlay.effective_date ?? 'next session'} — observations are never backdated.

)}
Hyperscaler capex guidance {overlay.capex_stress ?? 'n/a'}
{Object.entries(capex).map(([symbol, state]) => (
{symbol} {state}
))}
Good news, stock down {overlay.earnings_stress ?? 'n/a'}
{reaction === 'yes' ? 'Yes — beats sold into' : reaction === 'no' ? 'No — ordinary reactions' : 'Mixed'}
{overlay.reasoning &&

{overlay.reasoning}

}
); } /** One table for both axes — they share a shape, and two panels invited * comparing numbers that are not on the same scale. */ function PillarTable({ state, warning }: { state: RegimeReading; warning: RegimeReading }) { const groups: { title: string; reading: RegimeReading }[] = [ { title: 'State', reading: state }, { title: 'Warning', reading: warning }, ]; return (
{groups.map(({ title, reading }) => ( {reading.pillars.map((pillar) => ( ))} ))}
Pillar / sensor Score Weight Contribution
{title} {reading.score ?? '—'} · {Math.round(reading.coverage)}% coverage
{pillar.label}
{pillar.sensors.map((sensor) => (
{sensor.id} {sensor.label}:{' '} {sensor.score == null ? 'n/a' : sensor.score}
))}
{pillar.score ?? '—'} {pillar.weight} {pillar.available ? pillar.contribution.toFixed(1) : '—'}
); } function MetaChip({ label, value, title }: { label: string; value: ReactNode; title?: string }) { return ( {label} {value} ); } /** Provenance strip — replaces three separate prose blocks. */ function MetaStrip({ data }: { data: RegimeMonitor }) { const quality = data.data_quality; const basket = data.basket; const days = (value: number | null | undefined) => (value == null ? '—' : `${value}d`); return (
{basket && ( )}
); } function EventStudyBody({ report }: { report: EventStudyReport }) { const metrics = report.metrics; return (
{report.generated_at && generated {new Date(report.generated_at).toLocaleDateString()}} {report.sample && test {report.sample.test_start} → {report.sample.end}}

{report.summary}

{metrics && (
{[ ['Warned', `${metrics.events_warned}/${metrics.events}`], ['Missed', metrics.events_missed], ['False alarms/year', metrics.false_alarms_per_year.toFixed(1)], ['Median lead', metrics.median_lead_days == null ? '—' : `${metrics.median_lead_days}d`], ].map(([label, value]) => (
{label}
{value}
))}
)} {report.events && report.events.length > 0 && (
{report.events.map((event) => ( ))}
Correction Warned Lead
{event.date} {event.warned ? 'yes' : 'no'} {event.lead_days == null ? '—' : `${event.lead_days}d`}
)} {report.reliability && (report.reliability.underpowered || report.reliability.sensor_coverage_mismatch) && (
{report.reliability.underpowered && (

Underpowered. Only {report.reliability.events_in_holdout} of{' '} {report.reliability.events_detected} detected corrections fall in the test period ( {report.reliability.minimum_events}+ needed). Read the direction, not the ratio.

)} {report.reliability.sensor_coverage_mismatch && (

Sensor coverage differs across the split.{' '} {report.reliability.train_full_sensor_share}% of training sessions had all{' '} {report.reliability.sensors_expected} Warning sensors versus{' '} {report.reliability.holdout_full_sensor_share}% of test sessions {report.params?.credit_sensor_from && ` — credit history begins ${report.params.credit_sensor_from}`} . The threshold was frozen on a partly different construct than it is measured against.

)}
)}
); } function EventStudyPanel() { const study = useQuery({ queryKey: ['regime', 'event-study'], queryFn: getEventStudy }); return ( {study.isLoading && } {study.data === null && Not run yet — trigger “Event Study” in Admin → Jobs.} {study.data && !study.data.available && {study.data.reason ?? 'No data'}} {study.data?.available && } ); } const SELECT_CLASS = 'rounded-md border border-white/[0.08] bg-white/[0.03] px-2 py-1.5 text-xs text-gray-200'; const CAPEX_OPTIONS: { value: CapexState; label: string }[] = [ { value: 'raising', label: 'Raising' }, { value: 'holding', label: 'Holding' }, { value: 'cutting', label: 'Cutting' }, { value: 'unknown', label: 'Unknown' }, ]; function FundamentalsEditor({ data, onSave, onRefresh, saving, refreshing, }: { data: RegimeFundamentals; onSave: (body: RegimeFundamentalsUpdate) => void; onRefresh: () => void; saving: boolean; refreshing: boolean; }) { const [capex, setCapex] = useState>(() => ({ ...data.capex })); const [reaction, setReaction] = useState(data.good_news_stock_down); const knownCapex = Object.values(capex).filter((state) => state !== 'unknown'); // Mirrors _CAPEX_STATE_SCORES: raising 0, holding 50, cutting 100. Holding is // the deceleration case and used to score identically to raising. const capexPoints = knownCapex.reduce((sum, state) => sum + (state === 'cutting' ? 100 : state === 'holding' ? 50 : 0), 0); const derivedF1 = knownCapex.length >= 3 ? Math.round((capexPoints / knownCapex.length) * 10) / 10 : null; const derivedF3 = reaction === 'yes' ? 100 : reaction === 'no' ? 0 : null; return (
Source: {data.source} {data.fetched_at && · fetched {new Date(data.fetched_at).toLocaleDateString()}} {data.effective_date && · effective {data.effective_date}} {data.locked && }
{data.reasoning &&

{data.reasoning}

}
F1 · Capex guidance by hyperscaler score {derivedF1 ?? 'n/a'}
{Object.entries(capex).map(([symbol, state]) => ( ))}

Raising = 0, holding = 50, cutting = 100; at least three known names required.

{data.locked && }
); } function ConfigEditor({ data, onSave, saving }: { data: RegimeConfig; onSave: (updates: Partial) => void; saving: boolean }) { const [basket, setBasket] = useState(data.breadth_basket.join(', ')); const [staleness, setStaleness] = useState(data.fundamental_staleness_days); const symbols = basket.split(/[\s,]+/).map((symbol) => symbol.trim().toUpperCase()).filter(Boolean); return (