From 40824dbcb1ff90abea3f8baa79d3dac5417759fb Mon Sep 17 00:00:00 2001 From: Martin Dvorak Date: Wed, 30 Sep 2026 08:20:50 +0000 Subject: [PATCH] rename the editorial theme to "web" and make it the landing view (stop persisting the theme, so a reload never opens the desktop) --- README.md | 37 +++++++++++++------------ agents.md | 19 ++++++------- src/app/components/ThemeRoot.tsx | 6 ++-- src/app/components/ThemeScript.tsx | 12 +++----- src/app/components/WindowsDesktop.tsx | 4 +-- src/app/components/apps.tsx | 4 +-- src/app/components/useTheme.ts | 25 ++++++----------- src/app/globals.css | 40 +++++++++++++-------------- src/app/layout.tsx | 2 +- src/app/skeuo.css | 2 +- 10 files changed, 70 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index fd8214c..b86db0b 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ It's an **editorial-style personal site** in a **gruvbox** palette, with the whole KDE desktop simulation kept behind a "Desktop mode" button. Two modes, one content set: -- **Gruvbox editorial** (default) — a technical-print layout: serif headlines, mono labels in - the margin, hairline rules and a data strip. No images at all; the only graphics are the - social icons, used as monochrome CSS masks. +- **Web** (default) — the editorial site: a technical-print layout painted in the gruvbox + palette, with serif headlines, mono labels in the margin, hairline rules and a data strip. No + images at all; the only graphics are the social icons, used as monochrome CSS masks. - **Desktop mode** — the KDE Plasma / Windows-style **desktop simulation**: draggable snap-to-grid icons, resizable/floating windows, a Start menu, taskbar, live clock and a working in-browser terminal (Alacritty). Reachable from the "Desktop mode" button and hidden @@ -19,13 +19,13 @@ heatmap**, gym SBD and links to friends' sites. ## ✨ Features -- **Gruvbox editorial by default** — a technical-print layout: serif headlines, mono labels in - the margin, hairline rules, a data strip. Text and type only — the sole graphics are the - social icons, rendered as monochrome CSS masks. -- **Desktop mode (desktop-only)** — a "Desktop mode" button swaps to the KDE-style desktop; - the choice persists in `localStorage` (applied pre-paint to avoid a flash). Phones never get - it: the pre-paint script forces gruvbox and CSS hides the button, so the old iOS-style phone - home screen is gone. +- **Web theme is the landing view** — the site always opens on the editorial page; the theme is + deliberately not persisted, so a reload never drops you into the desktop. A technical-print + layout with serif headlines, mono labels in the margin, hairline rules and a data strip. Text + and type only — the sole graphics are the social icons, rendered as monochrome CSS masks. +- **Desktop mode (desktop-only)** — a "Desktop mode" button swaps to the KDE-style desktop for + the session. Phones never get it: the buttons are hidden, so the old iOS-style phone home + screen is gone. - **Draggable desktop icons** — free placement that snaps to a measured grid, one icon per cell, with a follow-the-cursor drag ghost. Icons shrink on cramped viewports so they never collide. @@ -61,10 +61,11 @@ heatmap**, gym SBD and links to friends' sites. - **Framework:** Next.js 16 (App Router, Turbopack) - **Language:** TypeScript, React 19 (client components everywhere interactivity lives) -- **Styling:** `src/app/globals.css` is the gruvbox editorial design system (CSS custom - properties, Tailwind v4 `@theme`/`@utility`, base + scroll reveals). `editorial.css` holds - page helpers; `page.css` keeps the shared component styles the desktop apps still use, and - `skeuo.css` is the KDE desktop. The editorial page itself is built from Tailwind utilities. +- **Styling:** `src/app/globals.css` is the web editorial design system — the gruvbox palette as + CSS custom properties, plus Tailwind v4 `@theme`/`@utility`, base and scroll reveals. + `editorial.css` holds page helpers; `page.css` keeps the shared component styles the desktop + apps still use, and `skeuo.css` is the KDE desktop. The editorial page is built from Tailwind + utilities. - **Fonts:** Newsreader (display) + IBM Plex Sans/Mono (body/labels) via `next/font/google`; the desktop keeps its system sans stack. - **Images:** `next/image` — but the editorial page uses none (social SVGs as monochrome masks only). @@ -170,7 +171,7 @@ they contend for `:3000` and `.next/dev/lock`. src/app/ page.tsx → renders , imports the theme stylesheets layout.tsx → html shell + metadata; loads the fonts; injects ThemeScript - globals.css → gruvbox editorial design system (tokens, @utility classes, base) + globals.css → web editorial design system (gruvbox palette; tokens, @utility classes, base) editorial.css → editorial page helpers (social masks, heatmap) page.css → shared component styles still used by the desktop apps skeuo.css → KDE desktop styles @@ -182,10 +183,10 @@ src/app/ frame/route.ts → header-stripping proxy for unframeable friend sites ping/route.ts → service health check (HTTP + Minecraft) components/ - ThemeRoot.tsx → gruvbox editorial vs. Desktop mode - ThemeScript.tsx → pre-paint script: theme + device detection + ThemeRoot.tsx → web editorial vs. Desktop mode + ThemeScript.tsx → pre-paint script: device detection useTheme.ts → theme state via useSyncExternalStore - EditorialSite.tsx → the gruvbox editorial page (nav, hero, sections) + EditorialSite.tsx → the web editorial page (nav, hero, sections) editorial-ui.tsx → editorial primitives: Section, ServiceRow, Contributions, … WindowsDesktop.tsx → desktop shell: icons, windows, taskbar, Start menu WinWindow.tsx → one draggable/resizable window diff --git a/agents.md b/agents.md index b647fc5..a1a8a00 100644 --- a/agents.md +++ b/agents.md @@ -34,7 +34,7 @@ When in doubt, prefer updating. A stale README **or** agents.md is treated as a ## What this project is Personal portfolio site for **dvorakmortonxd.dev**. The default view is a -**gruvbox editorial page** (a technical-print layout, no images); a "Desktop mode" +**web editorial page** (a technical-print layout, no images); a "Desktop mode" button swaps to a **KDE Plasma desktop simulation**. Phones only ever get the editorial page. @@ -77,7 +77,7 @@ token.** Do not print it, copy it into new files, or push it anywhere else. src/app/ page.tsx → renders , imports the theme stylesheets layout.tsx → html shell, metadata, next/font, ThemeScript - globals.css → gruvbox editorial design system (tokens, @utility, base, reveals) + globals.css → web editorial design system (gruvbox palette; tokens, @utility, base, reveals) editorial.css → editorial page helpers (social masks, heatmap) page.css → shared component styles used by the desktop apps skeuo.css → KDE Plasma desktop styles @@ -90,7 +90,7 @@ src/app/ frame/route.ts → header-stripping proxy so an unframeable friend site loads in a window; host allowlist components/ ThemeRoot.tsx → editorial page by default, desktop when theme === "skeuo" - EditorialSite.tsx → the gruvbox editorial page (nav, hero, sections) + EditorialSite.tsx → the web editorial page (nav, hero, sections) editorial-ui.tsx → editorial primitives: Reveal, Section, ServiceRow, Contributions, … WindowsDesktop.tsx → "skeuo" theme, desktop: icons, windows, taskbar WinWindow.tsx → a single draggable/resizable window @@ -109,19 +109,18 @@ scripts/ ``` ### How UI selection works -1. `ThemeScript` runs before paint. It reads `localStorage.theme` and sets - `data-theme` (`gruvbox` | `skeuo`) and `data-device` (`phone` | `desktop`) on - `` from a user-agent sniff. On a phone it forces `gruvbox` and CSS hides - every `.desktop-toggle`, so the desktop is unreachable there. +1. `ThemeScript` runs before paint and sets `data-device` (`phone` | `desktop`) + from a user-agent sniff. It does **not** read a stored theme, so the page always + lands on `web`. CSS hides every `.desktop-toggle` on phones. 2. `useTheme()` (in `useTheme.ts`) reads `data-theme` via `useSyncExternalStore`; - `setTheme` writes the attribute, persists to `localStorage`, and dispatches - `theme-change`. + `setTheme` sets the attribute and dispatches `theme-change`. Nothing is + persisted, so a reload returns to `web`. 3. `ThemeRoot` renders `EditorialSite` unless `theme === "skeuo"`, in which case it mounts `WindowsDesktop` instead. The editorial page stays mounted (hidden) while the desktop is up so its scroll position survives; the desktop mounts on demand (phones can never reach `skeuo`). -Modes: `gruvbox` = the default editorial site, `skeuo` = KDE Plasma desktop. +Modes: `web` = the editorial site (default/landing), `skeuo` = KDE Plasma desktop. The editorial page is **asset-free** apart from the social SVGs, which are used as monochrome CSS masks (`.social-mask` in `editorial.css`). `linkedin.svg` is a filled diff --git a/src/app/components/ThemeRoot.tsx b/src/app/components/ThemeRoot.tsx index 9366806..99b322f 100644 --- a/src/app/components/ThemeRoot.tsx +++ b/src/app/components/ThemeRoot.tsx @@ -4,9 +4,9 @@ import { useTheme } from "./useTheme"; import EditorialSite from "./EditorialSite"; import WindowsDesktop from "./WindowsDesktop"; -// The gruvbox editorial site is the default. Phones can never reach the KDE -// desktop: ThemeScript forces gruvbox there (ignoring a stored "skeuo") and CSS -// hides the Desktop-mode buttons, so `theme === "skeuo"` is desktop-only. +// The web editorial site is the default and always the landing view (the theme +// is not persisted). Phones can never reach the KDE desktop: the Desktop-mode +// buttons are hidden there, so `theme === "skeuo"` only happens on desktop. // // The editorial page stays mounted (hidden) while the desktop is up, so its // scroll position survives a round-trip. The desktop mounts on demand. diff --git a/src/app/components/ThemeScript.tsx b/src/app/components/ThemeScript.tsx index 8779772..4e47a61 100644 --- a/src/app/components/ThemeScript.tsx +++ b/src/app/components/ThemeScript.tsx @@ -3,14 +3,10 @@ import { useRef } from "react"; import { useServerInsertedHTML } from "next/navigation"; -// Runs before paint so the saved theme and the phone/desktop split are applied -// without a flash. It is injected with useServerInsertedHTML so the