diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/config.ts b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/config.ts
index 8c0d2244..d6fcfb30 100644
--- a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/config.ts
+++ b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/config.ts
@@ -69,6 +69,7 @@ export const ROUTES = {
export const STORAGE_KEYS = {
AUTH: 'auth-storage',
UI: 'ui-storage',
+ PRESENTATION_MODE: 'monitor:presentation-mode',
} as const
export const QUERY_CONFIG = {
diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/BottomTicker.tsx b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/BottomTicker.tsx
index 7d914a7e..471c96eb 100644
--- a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/BottomTicker.tsx
+++ b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/BottomTicker.tsx
@@ -2,14 +2,17 @@
// BottomTicker.tsx
import { useTicker } from '@/stores/ticker'
+import { useUIStore } from '@/stores/ui'
import styles from './BottomTicker.module.scss'
const MS_PER_SECOND = 1000
const SECONDS_PER_MINUTE = 60
const SECONDS_PER_HOUR = 3600
-export function BottomTicker(): React.ReactElement {
+export function BottomTicker(): React.ReactElement | null {
const items = useTicker((s) => s.items)
+ const isPresentation = useUIStore((s) => s.presentationMode)
+ if (isPresentation) return null
return (
{items.length > 0 && (
diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/Dashboard.module.scss b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/Dashboard.module.scss
index 1bf97f83..f9b301f6 100644
--- a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/Dashboard.module.scss
+++ b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/Dashboard.module.scss
@@ -41,3 +41,17 @@
overflow-y: auto;
border-left: 1px solid var(--fg-4);
}
+
+.root.presentation {
+ .grid {
+ grid-template-columns: 280px 1fr 280px;
+ }
+
+ .left {
+ border-right: 0;
+ }
+
+ .right {
+ border-left: 0;
+ }
+}
diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/Dashboard.tsx b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/Dashboard.tsx
index 5a28da01..45621d2b 100644
--- a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/Dashboard.tsx
+++ b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/Dashboard.tsx
@@ -1,14 +1,23 @@
// ©AngelaMos | 2026
// Dashboard.tsx
+import { useUIStore } from '@/stores/ui'
import { AlertBanner } from './AlertBanner'
import { BottomTicker } from './BottomTicker'
import styles from './Dashboard.module.scss'
+import { presentationMode } from './presentationMode'
import { TopStrip } from './TopStrip'
export function Dashboard(): React.ReactElement {
+ presentationMode.useGlobalShortcut()
+ const isPresentation = useUIStore((s) => s.presentationMode)
+
+ const rootClass = isPresentation
+ ? `${styles.root} ${styles.presentation}`
+ : styles.root
+
return (
-
+
diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/TopStrip.tsx b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/TopStrip.tsx
index eab6f1d5..c31f9862 100644
--- a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/TopStrip.tsx
+++ b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/TopStrip.tsx
@@ -11,10 +11,11 @@ import styles from './TopStrip.module.scss'
const CLOCK_TICK_MS = 1000
-export function TopStrip(): React.ReactElement {
+export function TopStrip(): React.ReactElement | null {
const [now, setNow] = useState(() => new Date())
const isAuthenticated = useAuthStore((s) => s.isAuthenticated)
const openAbout = useUIStore((s) => s.openAbout)
+ const isPresentation = useUIStore((s) => s.presentationMode)
const navigate = useNavigate()
useEffect(() => {
@@ -22,6 +23,8 @@ export function TopStrip(): React.ReactElement {
return () => clearInterval(id)
}, [])
+ if (isPresentation) return null
+
return (
diff --git a/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/presentationMode.ts b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/presentationMode.ts
new file mode 100644
index 00000000..a2687360
--- /dev/null
+++ b/PROJECTS/advanced/monitor-the-situation-dashboard/frontend/src/pages/dashboard/presentationMode.ts
@@ -0,0 +1,52 @@
+// ©AngelaMos | 2026
+// presentationMode.ts
+
+import { useEffect } from 'react'
+import { STORAGE_KEYS } from '@/config'
+import { useUIStore } from '@/stores/ui'
+
+function readInitial(): boolean {
+ return localStorage.getItem(STORAGE_KEYS.PRESENTATION_MODE) === '1'
+}
+
+function persist(on: boolean): void {
+ if (on) {
+ localStorage.setItem(STORAGE_KEYS.PRESENTATION_MODE, '1')
+ } else {
+ localStorage.removeItem(STORAGE_KEYS.PRESENTATION_MODE)
+ }
+}
+
+function isTypingInForm(target: EventTarget | null): boolean {
+ if (!(target instanceof HTMLElement)) return false
+ if (target.isContentEditable) return true
+ return (
+ target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement
+ )
+}
+
+export const presentationMode = {
+ readInitial,
+ useGlobalShortcut(): void {
+ const setMode = useUIStore((s) => s.setPresentationMode)
+
+ useEffect(() => {
+ setMode(readInitial())
+
+ function onKey(e: KeyboardEvent): void {
+ if (e.key === 'f' || e.key === 'F') {
+ if (isTypingInForm(e.target)) return
+ const next = !useUIStore.getState().presentationMode
+ setMode(next)
+ persist(next)
+ } else if (e.key === 'Escape') {
+ setMode(false)
+ persist(false)
+ }
+ }
+
+ document.addEventListener('keydown', onKey)
+ return () => document.removeEventListener('keydown', onKey)
+ }, [setMode])
+ },
+}