rework the site: gruvbox editorial default with a desktop-mode toggle; drop the terminal layout and phone desktop

This commit is contained in:
Martin Dvořák 2026-09-30 07:49:31 +00:00
commit 86692637de
19 changed files with 1350 additions and 1664 deletions

View file

@ -2,27 +2,30 @@
> The source code for my personal website, **[dvorakmortonxd.dev](https://dvorakmortonxd.dev)**.
This is not a normal portfolio page. It ships **two fully interactive shells** and picks
which one to show based on the saved theme and the device, all from the same content:
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:
- **`skeuo`** (default) — a KDE Plasma / Windows-style **desktop simulation**: draggable
snap-to-grid icons, resizable/floating windows, a Start menu, taskbar and live clock.
On phones it becomes an **iOS-style home screen** with a widget grid, dock, drag-to-reorder
and an iOS launch animation.
- **`terminal`** — a **Gruvbox TUI** version of the site: TUI panels, an animated ASCII
train background, a clickable easter-egg logo, and a working in-browser terminal (Alacritty)
with commands like `help`, `ls`, `cat`, `neofetch`, `emerge`, `ssh` and more.
- **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.
- **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
on phones.
Both shells surface the same personal content: socials, self-hosted services with **live
Both modes surface the same personal content: socials, self-hosted services with **live
up/down health checks**, a hardware collection, coding projects, a **GitDXD contribution
heatmap**, a gym SBD panel and links to friends' sites.
heatmap**, gym SBD and links to friends' sites.
## ✨ Features
- **Two themes / shells** — KDE-style desktop and Gruvbox terminal, toggled from either UI
and persisted in `localStorage` (applied pre-paint to avoid a flash).
- **Phone vs. desktop detection** — a user-agent sniff on `<html data-device>` decides whether
the desktop or the mobile home screen is shown.
- **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.
- **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.
@ -58,13 +61,14 @@ heatmap**, a gym SBD panel and links to friends' sites.
- **Framework:** Next.js 16 (App Router, Turbopack)
- **Language:** TypeScript, React 19 (client components everywhere interactivity lives)
- **Styling:** hand-written CSS — `src/app/page.css` (terminal theme), `src/app/skeuo.css`
(desktop + mobile), `src/app/globals.css` (base/reset). Tailwind v4 is imported for the
base layer but the UI is custom CSS.
- **Fonts:** Monocraft (self-hosted in `public/`, used by the terminal theme; the desktop
theme uses the system sans stack)
- **Images:** `next/image`
- **Version:** `2.1.0` (see `package.json`)
- **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.
- **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).
- **Version:** `3.0.0` (see `package.json`)
## 🚀 Running Locally
@ -164,33 +168,34 @@ they contend for `:3000` and `.next/dev/lock`.
```
src/app/
page.tsx → renders <ThemeRoot/>, imports the two theme stylesheets
layout.tsx → html shell + metadata, injects ThemeScript
globals.css → base/reset styles + Tailwind import
page.css → terminal theme styles
skeuo.css → desktop + mobile home styles
page.tsx → renders <ThemeRoot/>, imports the theme stylesheets
layout.tsx → html shell + metadata; loads the fonts; injects ThemeScript
globals.css → gruvbox editorial design system (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
data.ts → socials, codingProjects, techProjects, friends, wallpapers
revival-inc/page.tsx → embeds the bundled game at /public/revival-inc/index.html
api/
heatmap/route.ts → contribution heatmap proxy
activities/route.ts → GitDXD activity feed proxy
frame/route.ts → header-stripping proxy for unframeable friend sites
ping/route.ts → service health check (HTTP + Minecraft)
components/
ThemeRoot.tsx → picks which shell(s) to mount
ThemeRoot.tsx → gruvbox editorial vs. Desktop mode
ThemeScript.tsx → pre-paint script: theme + device detection
useTheme.ts → theme state via useSyncExternalStore
TerminalLayout.tsx → the Gruvbox terminal shell
EditorialSite.tsx → the gruvbox editorial page (nav, hero, sections)
editorial-ui.tsx → editorial primitives: Section, ServiceRow, Contributions, …
WindowsDesktop.tsx → desktop shell: icons, windows, taskbar, Start menu
MobileHome.tsx → phone shell: iOS home screen + app view
WinWindow.tsx → one draggable/resizable window
apps.tsx → APPS registry, window contents, in-app terminal
useDesktopIcons.ts → desktop icon grid + drag/drop logic
useDragOrder.ts → list reordering (mobile grid/dock)
ServiceButton.tsx → service link + live status dot
ContributionHeatmap.tsx → heatmap + recent commits widget
useDragOrder.ts → list reordering (used inside apps)
ServiceButton.tsx → desktop service link + live status dot
ContributionHeatmap.tsx → desktop heatmap + recent commits widget
Clock.tsx → live clock
JokerLogo.tsx → logo with click easter egg
SlBackground.tsx → animated ASCII train background
scripts/
dev-server.mjs → custom dev server: live updates without the dev-only debug surface
deploy/