feat: retro blog engine with swappable OS/console themes
Next.js 16 (App Router, TS) + SQLite (better-sqlite3) + marked. Core: a shared semantic HTML skeleton (rb- classes in Shell.tsx) that each theme reskins via a scoped [data-theme="..."] CSS file. Theme is persisted in a cookie, resolved server-side in the root layout, and swapped live by the client switcher (no reload, no FOUC). - DB auto-migrates and seeds posts on first run (data/blog.db, gitignored) - Pages: post list, post detail (markdown), about - Themes shipped: Windows XP (Luna), Windows 9x, PlayStation 2 - Adding a skin = registry entry + one scoped CSS file Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import Link from "next/link";
|
||||
import type { ReactNode } from "react";
|
||||
import { type ThemeId } from "@/themes/registry";
|
||||
import ThemeSwitcher from "./ThemeSwitcher";
|
||||
import Clock from "./Clock";
|
||||
|
||||
// Shared, theme-agnostic page chrome. Every theme restyles these `rb-` classes
|
||||
// to look like its own OS/console. The HTML skeleton never changes.
|
||||
export default function Shell({
|
||||
theme,
|
||||
title,
|
||||
children,
|
||||
}: {
|
||||
theme: ThemeId;
|
||||
title: string;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="rb-desktop">
|
||||
<div className="rb-window" role="application">
|
||||
<div className="rb-titlebar">
|
||||
<span className="rb-titlebar-icon" aria-hidden />
|
||||
<span className="rb-titlebar-text">{title} — RetroBlog</span>
|
||||
<div className="rb-titlebar-buttons" aria-hidden>
|
||||
<button className="rb-tb-btn rb-tb-min" tabIndex={-1}>
|
||||
<span>_</span>
|
||||
</button>
|
||||
<button className="rb-tb-btn rb-tb-max" tabIndex={-1}>
|
||||
<span>□</span>
|
||||
</button>
|
||||
<button className="rb-tb-btn rb-tb-close" tabIndex={-1}>
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav className="rb-menubar" aria-label="Main">
|
||||
<Link className="rb-menu-link" href="/">
|
||||
Home
|
||||
</Link>
|
||||
<Link className="rb-menu-link" href="/about">
|
||||
About
|
||||
</Link>
|
||||
<a
|
||||
className="rb-menu-link"
|
||||
href="https://github.com"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Links
|
||||
</a>
|
||||
<span className="rb-spacer" />
|
||||
<ThemeSwitcher initial={theme} />
|
||||
</nav>
|
||||
|
||||
<div className="rb-content">{children}</div>
|
||||
|
||||
<div className="rb-statusbar">
|
||||
<span className="rb-status-cell">Ready</span>
|
||||
<span className="rb-status-cell rb-status-grow">
|
||||
RetroBlog v0.1
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rb-taskbar">
|
||||
<button className="rb-start">
|
||||
<span className="rb-start-logo" aria-hidden />
|
||||
start
|
||||
</button>
|
||||
<div className="rb-tasks">
|
||||
<button className="rb-task rb-task-active">
|
||||
<span className="rb-task-icon" aria-hidden />
|
||||
RetroBlog
|
||||
</button>
|
||||
</div>
|
||||
<div className="rb-tray">
|
||||
<Clock />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user