import { HelpCircle } from 'lucide-react'; import { useTenant } from '../../services/TenantService.tsx'; import { leaveSandboxMode, reloadPage } from '../../environments/sandboxMode'; import { SandboxLandingNotice } from '../SandboxMode/SandboxLandingNotice'; import { useSandboxResetCountdown } from './sandboxResetCountdown'; import './SandboxBanner.css'; /** * THE SANDBOX BANNER - and the two things it must never do. * * IT READS NOTHING LOCAL. No build flag, no env var, no hostname, no prop. It renders the answer the * API gave and nothing else, because the whole security property of the sandbox is that the client is not * the thing that decides. See `TenantService` for why a token claim was rejected too. * * THREE STATES, AND THE THIRD IS THE ONE PEOPLE DELETE. * * sandbox say so, loudly and permanently * production say NOTHING - a banner on every real screen is noise that gets scrolled past, and * the absence of a sandbox banner is what production looks like * unknown say that we could not tell, and say it in a way that claims NEITHER * * THE THIRD STATE IS NOT DEFENSIVE CODING. Both wrong answers do harm and in opposite directions: a * production user shown a sandbox banner may treat real work as disposable; a sandbox user shown nothing * may treat test data as real. There is no safe default, so the honest state is its own state. * Collapsing `unknown` into either branch is the defect this card exists to prevent. */ export const SandboxBanner = () => { const { kind } = useTenant(); const resetsIn = useSandboxResetCountdown(kind === 'sandbox'); if (kind === 'production') return null; if (kind === 'sandbox') { return (