feat(monitor/frontend): about modal (meme + project explainer, ethos-minimal)

Native <dialog> opened from the TopStrip ? icon via useUIStore.aboutOpen.
Ref-driven showModal()/close() in useEffect, onClose synced to the store
so Escape closes both the dialog and the store flag in one round trip
(no listener fight). Three short paragraphs: the meme origin, the data
sources, and the keyboard shortcuts. The kbd-styled spans (mono +
1px --fg-4 outline) call out F and Esc.

No animation on open/close beyond the browser's default <dialog>
showModal transition (which is OS UI, not decoration). No backdrop-click
to close — Escape and the close button are enough; backdrop-click adds
a fragile target===dialog comparison for marginal value. ::backdrop
gets a 60% black tint so it reads as a modal, not a layer cake.

prose line-height 1.4 (looser than the 1.25 table tightness because
prose needs readability — operator-density still applies but Tufte
data-ink isn't violated by paragraph leading).

Plan 5 Task 23 Design QA: no illustration, no confetti, no tooltip
arrows, monochrome border, native ::backdrop only.
This commit is contained in:
CarterPerez-dev 2026-05-03 09:43:27 -04:00
parent 21f54390df
commit 71e0529960
3 changed files with 136 additions and 0 deletions

View File

@ -0,0 +1,74 @@
// ©AngelaMos | 2026
// About.module.scss
.dialog {
background: var(--bg-panel);
color: var(--fg-1);
border: 1px solid var(--fg-4);
padding: 0;
max-width: 480px;
width: 90%;
font-family: var(--font-sans);
font-size: var(--type-body);
&::backdrop {
background: rgb(0, 0, 0, 60%);
}
}
.head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 12px;
border-bottom: 1px solid var(--fg-4);
}
.title {
font-size: var(--type-label);
letter-spacing: var(--letter-spacing-label);
text-transform: uppercase;
color: var(--fg-2);
}
.close {
display: inline-flex;
align-items: center;
justify-content: center;
height: 24px;
width: 24px;
background: transparent;
border: 0;
padding: 0;
color: var(--fg-3);
cursor: pointer;
&:hover {
color: var(--fg-1);
}
&:focus-visible {
outline: 1px solid var(--fg-2);
outline-offset: 1px;
}
}
.body {
display: flex;
flex-direction: column;
gap: 10px;
padding: 12px;
color: var(--fg-2);
line-height: 1.4;
p {
margin: 0;
}
}
.kbd {
font-family: var(--font-mono);
color: var(--fg-1);
border: 1px solid var(--fg-4);
padding: 0 4px;
}

View File

@ -0,0 +1,60 @@
// ©AngelaMos | 2026
// About.tsx
import { useEffect, useRef } from 'react'
import { FiX } from 'react-icons/fi'
import { useUIStore } from '@/stores/ui'
import styles from './About.module.scss'
export function About(): React.ReactElement {
const isOpen = useUIStore((s) => s.aboutOpen)
const close = useUIStore((s) => s.closeAbout)
const dialogRef = useRef<HTMLDialogElement>(null)
useEffect(() => {
const dialog = dialogRef.current
if (!dialog) return
if (isOpen && !dialog.open) {
dialog.showModal()
} else if (!isOpen && dialog.open) {
dialog.close()
}
}, [isOpen])
return (
<dialog ref={dialogRef} className={styles.dialog} onClose={close}>
<header className={styles.head}>
<span className={styles.title}>Monitoring the Situation</span>
<button
type="button"
className={styles.close}
onClick={close}
aria-label="Close"
>
<FiX aria-hidden />
</button>
</header>
<div className={styles.body}>
<p>
"Monitoring the situation" is a Twitter/X meme from June 2025. This is
the version that actually monitors the situation.
</p>
<p>
Operator-grade real-time dashboard pulling live data from ten
high-signal feeds: DShield mass-scan, Cloudflare Radar BGP/outage, NVD +
EPSS CVE velocity, CISA KEV, ransomware.live, Coinbase BTC/ETH ticks,
USGS earthquakes, NOAA SWPC space weather, Wikipedia ITN + GDELT theme
spikes, and the ISS live position. Single Go binary backend, React 19
frontend, Postgres + Redis, served behind a Cloudflare Tunnel.
</p>
<p>
<span className={styles.kbd}>F</span> enters presentation mode (full
viewport, chrome hidden). <span className={styles.kbd}>Esc</span> exits
or closes this dialog.
</p>
</div>
</dialog>
)
}
About.displayName = 'About'

View File

@ -11,6 +11,7 @@ import { KEVPanel } from '@/pages/panels/KEVPanel'
import { RansomwarePanel } from '@/pages/panels/RansomwarePanel'
import { SpaceWeatherPanel } from '@/pages/panels/SpaceWeatherPanel'
import { useUIStore } from '@/stores/ui'
import { About } from './About'
import { AlertBanner } from './AlertBanner'
import { BottomTicker } from './BottomTicker'
import styles from './Dashboard.module.scss'
@ -47,6 +48,7 @@ export function Dashboard(): React.ReactElement {
</aside>
</main>
<BottomTicker />
<About />
</div>
)
}