// Copyright 2026 certctl LLC. All rights reserved. // SPDX-License-Identifier: BUSL-1.1 // // DesktopOnlyBanner — Phase 9 closure for FE-M2 (operator decision // 2026-05-14: certctl is desktop-only). Renders a top-of-viewport // notice when the viewport is narrower than the `lg` Tailwind // breakpoint (1024px) telling operators they're outside the // supported viewport. // // Visibility is gated by CSS media query (.desktop-only-banner in // src/index.css). Component dismissal persists to localStorage so an // operator who needs occasional narrow-viewport access doesn't see // the banner forever. // // Pairs with the operator's FE-M2 decision: rather than rip out the // 29 partial sm:/md:/lg: responsive classes (zero benefit at // desktop widths) OR ship full mobile (1+ sprint of QA + ongoing // maintenance), the project ships an HONEST signal — "we don't // promise mobile" — that doesn't claim support that isn't there. import { useEffect, useState } from 'react'; const STORAGE_KEY = 'certctl:desktop-only-banner-dismissed'; export default function DesktopOnlyBanner() { const [dismissed, setDismissed] = useState(() => { if (typeof localStorage === 'undefined') return false; try { return localStorage.getItem(STORAGE_KEY) === 'true'; } catch { return false; } }); useEffect(() => { if (dismissed && typeof localStorage !== 'undefined') { try { localStorage.setItem(STORAGE_KEY, 'true'); } catch { /* noop */ } } }, [dismissed]); if (dismissed) return null; return (
Desktop-only: certctl is designed for viewports ≥ 1024px. Some UI may render cramped at this width.
); }