Files
warpbox-dev/backend/static/css/16-retro.css
Daniel Legt ffe4201f05 feat(theme): introduce retro Windows 98-inspired theme
Add a new "retro" theme option that mimics the classic Windows 98 aesthetic, providing a nostalgic alternative to the modern and classic dark themes.

Changes include:
- Defining CSS variables for the retro theme in `00-base.css` (pixel fonts, silver/gray colors, and classic window shadows).
- Adding custom styling for cards, headers, buttons, and title bars to replicate classic OS windows.
- Adding a star background GIF (`stars1.gif`).
- Excluding the retro theme from modern "revamp" styles in `15-revamp.css`.
- Updating `CLAUDE.md` with instructions on screenshot verification.
2026-05-31 16:17:20 +03:00

394 lines
11 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* "retro" theme flourishes — modelled on danlegt.com.
*
* Windows 98 chrome over a black pixel-star desktop, PixeloidSans pixel font,
* crisp (non-antialiased, pixelated) rendering. Scoped entirely to
* :root[data-theme="retro"] so it never touches the other themes.
*
* CSP-safe: external stylesheet + self-hosted fonts only (font-src 'self'),
* no inline styles, no remote assets. The starfield is pure CSS so we don't
* depend on img-src for a background gif.
*/
/* Self-hosted pixel fonts (mirrored locally — GGBotNet PixeloidSans is free,
PixelOperator is CC0). ------------------------------------------------- */
@font-face {
font-family: "PixeloidSans";
src: url("/static/fonts/pixeloid_sans/PixeloidSans.ttf") format("truetype");
font-weight: normal;
font-display: swap;
}
@font-face {
font-family: "PixeloidSans";
src: url("/static/fonts/pixeloid_sans/PixeloidSans-Bold.ttf") format("truetype");
font-weight: bold;
font-display: swap;
}
@font-face {
font-family: "PixelOperatorMono";
src: url("/static/fonts/pixel_operator/PixelOperatorMono.ttf") format("truetype");
font-weight: normal;
font-display: swap;
}
@font-face {
font-family: "PixelOperatorMono";
src: url("/static/fonts/pixel_operator/PixelOperatorMono-Bold.ttf") format("truetype");
font-weight: bold;
font-display: swap;
}
/* Crisp, pixelated, non-smoothed rendering like the source site. */
:root[data-theme="retro"] {
font-smooth: never;
-webkit-font-smoothing: none;
-moz-osx-font-smoothing: unset;
}
:root[data-theme="retro"] img,
:root[data-theme="retro"] .thumb-link img,
:root[data-theme="retro"] .preview-stage img {
image-rendering: pixelated;
}
/* Square everything — Win98 had no rounded corners. */
:root[data-theme="retro"] *,
:root[data-theme="retro"] *::before,
:root[data-theme="retro"] *::after {
border-radius: 0 !important;
}
/* Black desktop with the tiled starfield mirrored from danlegt.com. */
:root[data-theme="retro"] body {
background-color: #000000;
background-image: url("/static/backgrounds/stars1.gif");
background-repeat: repeat;
background-attachment: fixed;
image-rendering: pixelated;
}
/* Selection + focus use the classic dotted/navy treatment. */
:root[data-theme="retro"] ::selection {
background: #000078;
color: #ffffff;
}
:root[data-theme="retro"] :focus-visible {
outline: 1px dotted #000000;
outline-offset: -4px;
}
/* Header: thin flat silver toolbar with a bottom bevel. */
:root[data-theme="retro"] .site-header {
background: #c0c0c0;
backdrop-filter: none;
-webkit-backdrop-filter: none;
border-bottom: 2px solid #404040;
box-shadow: inset 0 1px 0 #ffffff;
}
:root[data-theme="retro"] .nav {
min-height: 2.1rem;
}
:root[data-theme="retro"] .site-header .button {
min-height: 1.6rem;
padding: 0.15rem 0.6rem;
}
:root[data-theme="retro"] .brand {
color: #000000;
font-size: 0.95rem;
}
:root[data-theme="retro"] .brand-mark {
width: 1.4rem;
height: 1.4rem;
background: linear-gradient(90deg, #000078, 80%, #0f80cd);
color: #ffffff;
font-size: 0.75rem;
box-shadow: inset -1px -1px 0 #404040, inset 1px 1px 0 #6f6fff;
}
/* Cards are raised silver windows with black text. */
:root[data-theme="retro"] .card {
background: linear-gradient(to bottom, #ffffff, 4%, #c0c0c0 8%);
background-color: #c0c0c0;
color: #000000;
border: 1px solid #000000;
box-shadow: var(--shadow);
backdrop-filter: none;
-webkit-backdrop-filter: none;
}
/* Headings become Win98 active title bars. */
:root[data-theme="retro"] h1 {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
margin: -0.35rem -0.35rem 1rem;
padding: 0.35rem 0.5rem;
background: linear-gradient(to right, #000078, 80%, #0f80cd);
color: #ffffff;
font-size: 1rem;
font-weight: 700;
letter-spacing: 0;
text-shadow: none;
}
/* Fake window control button on the right of every title bar. */
:root[data-theme="retro"] h1::after {
content: "✕";
display: grid;
place-items: center;
width: 1.15rem;
height: 1rem;
background: #c0c0c0;
color: #000000;
font-size: 0.7rem;
font-weight: 700;
box-shadow: inset -1px -1px 0 #404040, inset 1px 1px 0 #ffffff, inset -2px -2px 0 #808080, inset 2px 2px 0 #dfdfdf;
}
/* Links: classic blue, underlined, purple when visited. */
:root[data-theme="retro"] a:not(.button):not(.brand) {
color: #0000ee;
text-decoration: underline;
}
:root[data-theme="retro"] a:not(.button):not(.brand):visited {
color: #551a8b;
}
:root[data-theme="retro"] a:not(.button):not(.brand):hover {
color: #ee0000;
}
/* Buttons: grey beveled chunks that press in when active. */
:root[data-theme="retro"] .button,
:root[data-theme="retro"] button {
background: #c0c0c0;
color: #000000;
border: 1px solid #000000;
font-weight: 700;
box-shadow: inset -1px -1px 0 #404040, inset 1px 1px 0 #ffffff, inset -2px -2px 0 #808080, inset 2px 2px 0 #dfdfdf;
}
:root[data-theme="retro"] .button:hover,
:root[data-theme="retro"] button:hover {
background: #d4d0c8;
}
:root[data-theme="retro"] .button:active,
:root[data-theme="retro"] button:active,
:root[data-theme="retro"] .button.is-active {
background: #c0c0c0;
box-shadow: inset 1px 1px 0 #404040, inset -1px -1px 0 #ffffff, inset 2px 2px 0 #808080, inset -2px -2px 0 #dfdfdf;
padding-top: calc(0.45rem + 1px);
padding-left: calc(0.85rem + 1px);
}
/* The primary call-to-action gets the blue title-bar gradient. */
:root[data-theme="retro"] .button-primary {
background: linear-gradient(to right, #000078, 80%, #0f80cd);
color: #ffffff;
}
:root[data-theme="retro"] .button-primary:hover {
background: linear-gradient(to right, #0a0a9a, 80%, #1a90dd);
}
:root[data-theme="retro"] .button-danger {
background: #c0c0c0;
color: #c00000;
border-color: #000000;
}
/* Inputs and selects look sunken (inset bevel). */
:root[data-theme="retro"] input,
:root[data-theme="retro"] select,
:root[data-theme="retro"] textarea {
background: #ffffff;
color: #000000;
border: 1px solid #000000;
box-shadow: inset 1px 1px 0 #808080, inset -1px -1px 0 #ffffff;
}
:root[data-theme="retro"] input:focus,
:root[data-theme="retro"] select:focus {
outline: 1px dotted #000000;
outline-offset: -3px;
}
/* Labels inside windows read black, not muted-grey-on-grey. */
:root[data-theme="retro"] label span,
:root[data-theme="retro"] .stack-form label,
:root[data-theme="retro"] .form-footer p,
:root[data-theme="retro"] .drop-copy,
:root[data-theme="retro"] .drop-meta,
:root[data-theme="retro"] .upload-subtitle,
:root[data-theme="retro"] .download-subtitle,
:root[data-theme="retro"] .muted-copy,
:root[data-theme="retro"] .kicker,
:root[data-theme="retro"] .checkbox-field span {
color: #1a1a1a;
}
/* Desktop-level text (outside the grey windows) reads light on the black sky. */
:root[data-theme="retro"] .docs-header,
:root[data-theme="retro"] .docs-header p,
:root[data-theme="retro"] .docs-header .kicker {
color: #cfd8ff;
}
:root[data-theme="retro"] .docs-header code {
color: #ffffff;
}
/* Drop zone: a sunken white field with a dashed navy border. */
:root[data-theme="retro"] .drop-zone {
background: #ffffff;
border: 2px dashed #000078;
box-shadow: inset 2px 2px 0 #808080, inset -2px -2px 0 #ffffff;
}
:root[data-theme="retro"] .drop-zone:hover,
:root[data-theme="retro"] .drop-zone.is-dragging {
background: #fffff0;
border-color: #0f80cd;
}
:root[data-theme="retro"] .drop-icon {
color: #000078;
}
/* The hero "Welcome" badge becomes a high-contrast blinking pixel sticker
that sits on the black desktop above the window. */
:root[data-theme="retro"] .hero-eyebrow {
background: linear-gradient(to right, #000078, 80%, #0f80cd);
border: 1px solid #000000;
color: #ffffff;
font-weight: 700;
text-transform: uppercase;
box-shadow: inset -1px -1px 0 #404040, inset 1px 1px 0 #6f6fff;
}
:root[data-theme="retro"] .hero-eyebrow::before {
content: "★ ";
color: #ffff66;
animation: retro-blink 1.1s steps(1, end) infinite;
}
:root[data-theme="retro"] .hero-eyebrow::after {
content: " ★";
color: #ffff66;
animation: retro-blink 1.1s steps(1, end) 0.55s infinite;
}
@keyframes retro-blink {
50% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
:root[data-theme="retro"] .hero-eyebrow::before,
:root[data-theme="retro"] .hero-eyebrow::after {
animation: none;
}
}
/* Badges become square chips. */
:root[data-theme="retro"] .badge {
background: #ffffff;
color: #000000;
border: 1px solid #000000;
box-shadow: inset 1px 1px 0 #808080;
}
/* File / result rows: flat white with a sunken hairline. */
:root[data-theme="retro"] .download-item,
:root[data-theme="retro"] .result-item {
background: #ffffff;
color: #000000;
border: 1px solid #000000;
box-shadow: inset 1px 1px 0 #dfdfdf, inset -1px -1px 0 #808080;
}
:root[data-theme="retro"] .file-main,
:root[data-theme="retro"] .download-item small,
:root[data-theme="retro"] .result-item code {
color: #000000;
}
:root[data-theme="retro"] .file-emblem {
background: #000078;
color: #ffffff;
border: 1px solid #000000;
box-shadow: inset -1px -1px 0 #404040, inset 1px 1px 0 #4a4aff;
}
/* Code blocks use the pixel mono font. */
:root[data-theme="retro"] code,
:root[data-theme="retro"] pre,
:root[data-theme="retro"] pre code {
font-family: "PixelOperatorMono", ui-monospace, monospace;
color: #000000;
}
:root[data-theme="retro"] pre {
background: #ffffff;
border: 1px solid #000000;
box-shadow: inset 1px 1px 0 #808080;
}
/* Progress bar: blocky segmented Win98 look. */
:root[data-theme="retro"] .progress {
background: #ffffff;
border: 1px solid #000000;
box-shadow: inset 1px 1px 0 #808080;
}
:root[data-theme="retro"] .progress span {
background: repeating-linear-gradient(90deg, #000078 0 8px, transparent 8px 10px), #0f80cd;
}
/* Chunky retro scrollbars (WebKit/Blink). */
:root[data-theme="retro"] ::-webkit-scrollbar {
width: 16px;
height: 16px;
}
:root[data-theme="retro"] ::-webkit-scrollbar-track {
background: #dfdfdf;
}
:root[data-theme="retro"] ::-webkit-scrollbar-thumb {
background: #c0c0c0;
border: 1px solid #000000;
box-shadow: inset -1px -1px 0 #808080, inset 1px 1px 0 #ffffff;
}
/* Footer sits on the black desktop: white pixel text + a wink to the old web. */
:root[data-theme="retro"] .site-footer {
color: #ffffff;
}
:root[data-theme="retro"] .site-footer a,
:root[data-theme="retro"] .footer-links a:not(.button) {
color: #66ccff;
}
:root[data-theme="retro"] .theme-picker > span {
color: #ffffff;
}
:root[data-theme="retro"] .site-footer::after {
content: "✩ Best viewed in 1024×768 ✩";
font-weight: 700;
}
@media (max-width: 720px) {
:root[data-theme="retro"] .site-footer::after {
display: none;
}
}