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,184 @@
|
||||
/* ============================================================
|
||||
RetroBlog — globals
|
||||
Shared, theme-agnostic skeleton. Visual identity lives in the
|
||||
per-theme files imported below, each scoped to
|
||||
[data-theme="..."]. This file only handles reset + layout
|
||||
structure that every skin reuses.
|
||||
============================================================ */
|
||||
|
||||
@import "../themes/xp.css";
|
||||
@import "../themes/ninex.css";
|
||||
@import "../themes/ps2.css";
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* ---- structural layout (positioning only; themes paint) ---- */
|
||||
|
||||
.rb-desktop {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 0 40px; /* room for the fixed taskbar */
|
||||
}
|
||||
|
||||
.rb-window {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
margin: 24px auto;
|
||||
width: min(920px, calc(100% - 32px));
|
||||
}
|
||||
|
||||
.rb-titlebar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex: 0 0 auto;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.rb-titlebar-text {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.rb-titlebar-buttons {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.rb-menubar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.rb-spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.rb-content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.rb-statusbar {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.rb-status-grow {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* taskbar pinned to viewport bottom */
|
||||
.rb-taskbar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 0 6px;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.rb-tasks {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rb-tray {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* ---- post list ---- */
|
||||
|
||||
.rb-post-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.rb-post-card-head {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.rb-post-card-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.rb-post-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.rb-post-tags {
|
||||
display: inline-flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.rb-readmore {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.rb-article-meta {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.rb-switcher {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
:root {
|
||||
color-scheme: light;
|
||||
}
|
||||
Reference in New Issue
Block a user