v3: brutalist, geocities and nyt on the token system — single light-dark() palettes, radius scale instead of per-selector overrides

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
khannurien
2026-09-19 19:34:32 +00:00
parent 971cc4988e
commit 7c91e68cd1
3 changed files with 130 additions and 640 deletions

View File

@@ -3,132 +3,31 @@
Palette: Eggshell · Burnt Peach · Twilight Indigo · Muted Teal · Apricot Cream
══════════════════════════════════════════════════════════════════════ */
/* ── Dark variant (default for this theme) ────────────────────────── */
/* ── Palette (light-dark: see tokens.css) ─────────────────────────── */
:root[data-style="brutalist"] {
--color-text: #f4f1de; /* Eggshell */
--color-text-secondary: #c8c5b2;
--color-text-muted: #8e8c80;
--color-on-accent: #3d405b; /* Twilight Indigo on Apricot Cream */
--color-bg: #252838; /* darkened Twilight Indigo */
--color-surface: #2e3145;
--color-border: #4a4e6a;
--color-border-subtle: rgba(74, 78, 106, 0.4);
--color-accent: #f2cc8f; /* Apricot Cream */
--color-accent-hover: #d4a860;
--color-link: #f2cc8f;
--color-link-hover: #d4a860;
--color-danger: #e07a5f; /* Burnt Peach */
--color-danger-bg: #3a1e18;
--color-danger-hover: #c85a40;
--color-success: #81b29a; /* Muted Teal */
--color-success-bg: #1a2e26;
--color-success-hover: #5a9878;
--color-overlay: rgba(0, 0, 0, 0.6);
--color-header-user-bg: rgba(242, 204, 143, 0.07);
--color-header-user-bg-hover: rgba(242, 204, 143, 0.14);
--color-option-bg: #222436;
--color-option-border: #252838;
}
/* ── Light via system preference (auto color-scheme) ──────────────── */
@media (prefers-color-scheme: light) {
:root[data-style="brutalist"]:not([data-color-scheme]) {
--color-text: #3d405b; /* Twilight Indigo */
--color-text-secondary: #5a5e80;
--color-text-muted: #7a7e9a;
--color-on-accent: #f4f1de; /* Eggshell on Burnt Peach */
--color-bg: #f4f1de; /* Eggshell */
--color-surface: #f8f5e8;
--color-border: #8a8da8;
--color-border-subtle: rgba(61, 64, 91, 0.25);
--color-accent: #e07a5f; /* Burnt Peach — visible against Eggshell */
--color-accent-hover: #c05040;
--color-link: #b85a3a; /* darkened Burnt Peach for legibility */
--color-link-hover: #943020;
--color-danger: #c04030;
--color-danger-bg: #fae4e0;
--color-danger-hover: #a02820;
--color-success: #3a7860;
--color-success-bg: #e0f0ea;
--color-success-hover: #286048;
--color-overlay: rgba(0, 0, 0, 0.5);
--color-header-user-bg: rgba(224, 122, 95, 0.08);
--color-header-user-bg-hover: rgba(224, 122, 95, 0.16);
--color-option-bg: #ede9d4;
--color-option-border: #e0dcc8;
}
}
/* ── Manual dark override ─────────────────────────────────────────── */
:root[data-style="brutalist"][data-color-scheme="dark"] {
color-scheme: dark;
--color-text: #f4f1de;
--color-text-secondary: #c8c5b2;
--color-text-muted: #8e8c80;
--color-on-accent: #3d405b;
--color-bg: #252838;
--color-surface: #2e3145;
--color-border: #4a4e6a;
--color-border-subtle: rgba(74, 78, 106, 0.4);
--color-accent: #f2cc8f;
--color-accent-hover: #d4a860;
--color-link: #f2cc8f;
--color-link-hover: #d4a860;
--color-danger: #e07a5f;
--color-danger-bg: #3a1e18;
--color-danger-hover: #c85a40;
--color-success: #81b29a;
--color-success-bg: #1a2e26;
--color-success-hover: #5a9878;
--color-overlay: rgba(0, 0, 0, 0.6);
--color-header-user-bg: rgba(242, 204, 143, 0.07);
--color-header-user-bg-hover: rgba(242, 204, 143, 0.14);
--color-option-bg: #222436;
--color-option-border: #252838;
}
/* ── Manual light override ────────────────────────────────────────── */
:root[data-style="brutalist"][data-color-scheme="light"] {
color-scheme: light;
--color-text: #3d405b;
--color-text-secondary: #5a5e80;
--color-text-muted: #7a7e9a;
--color-on-accent: #f4f1de;
--color-bg: #f4f1de;
--color-surface: #f8f5e8;
--color-border: #8a8da8;
--color-border-subtle: rgba(61, 64, 91, 0.25);
--color-accent: #e07a5f;
--color-accent-hover: #c05040;
--color-link: #b85a3a;
--color-link-hover: #943020;
--color-danger: #c04030;
--color-danger-bg: #fae4e0;
--color-danger-hover: #a02820;
--color-success: #3a7860;
--color-success-bg: #e0f0ea;
--color-success-hover: #286048;
--color-overlay: rgba(0, 0, 0, 0.5);
--color-header-user-bg: rgba(224, 122, 95, 0.08);
--color-header-user-bg-hover: rgba(224, 122, 95, 0.16);
--color-option-bg: #ede9d4;
--color-option-border: #e0dcc8;
--color-text: light-dark(#3d405b, #f4f1de);
--color-text-secondary: light-dark(#5a5e80, #c8c5b2);
--color-text-muted: light-dark(#7a7e9a, #8e8c80);
--color-on-accent: light-dark(#f4f1de, #3d405b);
--color-bg: light-dark(#f4f1de, #252838);
--color-surface: light-dark(#f8f5e8, #2e3145);
--color-border: light-dark(#8a8da8, #4a4e6a);
--color-border-subtle: light-dark(rgba(61, 64, 91, 0.25), rgba(74, 78, 106, 0.4));
--color-accent: light-dark(#e07a5f, #f2cc8f);
--color-accent-hover: light-dark(#c05040, #d4a860);
--color-link: light-dark(#b85a3a, #f2cc8f);
--color-link-hover: light-dark(#943020, #d4a860);
--color-danger: light-dark(#c04030, #e07a5f);
--color-danger-bg: light-dark(#fae4e0, #3a1e18);
--color-danger-hover: light-dark(#a02820, #c85a40);
--color-success: light-dark(#3a7860, #81b29a);
--color-success-bg: light-dark(#e0f0ea, #1a2e26);
--color-success-hover: light-dark(#286048, #5a9878);
--color-overlay: light-dark(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.6));
--color-header-user-bg: light-dark(rgba(224, 122, 95, 0.08), rgba(242, 204, 143, 0.07));
--color-header-user-bg-hover: light-dark(rgba(224, 122, 95, 0.16), rgba(242, 204, 143, 0.14));
--color-option-bg: light-dark(#ede9d4, #222436);
--color-option-border: light-dark(#e0dcc8, #252838);
}
/* ══════════════════════════════════════════════════════════════════════
@@ -138,6 +37,14 @@
/* ── Typography ──────────────────────────────────────────────────── */
[data-style="brutalist"] {
--font-body: "Space Grotesk", "Saira", sans-serif;
/* Hard edges everywhere App.css uses the radius scale. */
--radius-xs: 0;
--radius-sm: 0;
--radius-md: 0;
--radius-lg: 0;
--radius-xl: 0;
--radius-full: 0;
font-family: var(--font-body);
font-weight: 500;
}
@@ -148,6 +55,16 @@
letter-spacing: 0.03em;
}
/* Circles App.css draws with a literal 50% (not the radius scale) — square
them off too. */
[data-style="brutalist"] .avatar-img,
[data-style="brutalist"] .avatar-initials,
[data-style="brutalist"] .avatar-change-overlay,
[data-style="brutalist"] .notif-icon,
[data-style="brutalist"] .notif-dot {
border-radius: 0;
}
/* ── Buttons — square corners, modest hard shadow ────────────────── */
/* `.dump-fab` is exempt from the generic button chrome — it keeps its own
shape, shadow and animations — but this hard-edged theme squares it off. */
@@ -157,7 +74,6 @@
}
[data-style="brutalist"] button:not(.dump-fab, .chat-fab) {
border-radius: 0;
border: 2px solid var(--color-border);
font-weight: 700;
box-shadow: 2px 2px 0 var(--color-border);
@@ -170,18 +86,6 @@
transform: translate(2px, 2px);
}
/* In the light variant the resting text colour is dark, but on hover the
danger button fills with the dark --color-danger-hover. Force light text on
hover so the label stays legible. */
@media (prefers-color-scheme: light) {
:root[data-style="brutalist"]:not([data-color-scheme]) .btn-danger:hover {
color: #fff;
}
}
:root[data-style="brutalist"][data-color-scheme="light"] .btn-danger:hover {
color: #fff;
}
/* Ghost / icon-only buttons — keep borderless, no press effect */
[data-style="brutalist"] .modal-close-btn,
[data-style="brutalist"] .playlist-remove-btn,
@@ -234,13 +138,11 @@
/* ── Segmented controls / visibility-toggle ──────────────────────── */
[data-style="brutalist"] .visibility-toggle {
border-radius: 0;
border: 2px solid var(--color-border);
box-shadow: 2px 2px 0 var(--color-border);
}
[data-style="brutalist"] .visibility-toggle button {
border-radius: 0;
border: none;
box-shadow: none;
}
@@ -253,7 +155,6 @@
/* ── Cards ───────────────────────────────────────────────────────── */
[data-style="brutalist"] .dump-card,
[data-style="brutalist"] .playlist-card {
border-radius: 0;
border: 2px solid var(--color-border);
box-shadow: 3px 3px 0 var(--color-border);
transition:
@@ -280,7 +181,6 @@
/* ── Dump post detail header ─────────────────────────────────────── */
[data-style="brutalist"] .dump-post-header {
border-radius: 0;
border: 2px solid var(--color-border);
box-shadow: 3px 3px 0 var(--color-border);
}
@@ -291,7 +191,6 @@
}
[data-style="brutalist"] .app-header-user {
border-radius: 0;
border: 2px solid var(--color-border);
box-shadow: 2px 2px 0 var(--color-border);
transition: box-shadow 0.08s ease, transform 0.08s ease, background 0.1s;
@@ -319,29 +218,15 @@
box-shadow: 2px 2px 0 var(--color-accent);
}
/* ── Category management chips / inline editor ───────────────────── */
[data-style="brutalist"] .category-chip,
[data-style="brutalist"] .category-editor,
[data-style="brutalist"] .category-editor-btn,
[data-style="brutalist"] .dump-card-category-chip,
[data-style="brutalist"] .profile-role-chip {
border-radius: 0;
}
[data-style="brutalist"] .category-editor {
box-shadow: 2px 2px 0 var(--color-accent);
}
/* ── Search bar ──────────────────────────────────────────────────── */
[data-style="brutalist"] .search-bar-input,
[data-style="brutalist"] .search-bar-btn {
border-radius: 0;
}
/* ── Modals ──────────────────────────────────────────────────────── */
[data-style="brutalist"] .modal-card,
[data-style="brutalist"] .confirm-modal {
border-radius: 0;
border: 2px solid var(--color-border);
box-shadow: 4px 4px 0 var(--color-border);
}
@@ -364,19 +249,10 @@
border-bottom-width: 2px;
}
/* ── Avatars — square ────────────────────────────────────────────── */
[data-style="brutalist"] .avatar-img,
[data-style="brutalist"] .avatar-initials {
border-radius: 0;
}
[data-style="brutalist"] .avatar-change-overlay {
border-radius: 0;
}
/* ── Rich content cards ──────────────────────────────────────────── */
[data-style="brutalist"] .rich-content-card {
border-radius: 0;
box-shadow: 3px 3px 0 var(--color-border);
}
@@ -405,31 +281,14 @@
box-shadow: 3px 3px 0 var(--color-accent);
}
/* ── File drop zone ──────────────────────────────────────────────── */
[data-style="brutalist"] .fdz {
border-radius: 0;
}
/* ── Global persistent player ────────────────────────────────────── */
[data-style="brutalist"] .global-player {
border-radius: 0;
border: 2px solid var(--color-border);
box-shadow: 0 0 0 2px var(--color-border);
}
[data-style="brutalist"] .global-player-iframe-wrap,
[data-style="brutalist"] .global-player-media-wrap,
[data-style="brutalist"] .global-player .audio-player,
[data-style="brutalist"] .global-player .video-player {
border-radius: 0;
}
/* Queue UI: square off the artwork and the stream progress bar. */
[data-style="brutalist"] .global-player-artwork,
[data-style="brutalist"] .audio-player-track--stream::before,
[data-style="brutalist"] .audio-player-track--stream .audio-player-fill {
border-radius: 0;
}
[data-style="brutalist"] .global-player .audio-player-btn {
background: transparent;
@@ -451,38 +310,20 @@
/* ── Notification items ──────────────────────────────────────────── */
[data-style="brutalist"] .notification-item {
border-radius: 0;
border: 2px solid var(--color-border);
box-shadow: 2px 2px 0 var(--color-border);
}
[data-style="brutalist"] .notifications-unread-pill {
border-radius: 0;
}
[data-style="brutalist"] .notif-dot {
border-radius: 0;
box-shadow: none;
}
[data-style="brutalist"] .notif-icon {
border-radius: 0;
}
/* ── Notification badge ──────────────────────────────────────────── */
[data-style="brutalist"] .notification-badge {
border-radius: 0;
}
/* ── Markdown code ───────────────────────────────────────────────── */
[data-style="brutalist"] .md code,
[data-style="brutalist"] .md pre {
border-radius: 0;
}
/* ── User result items (search) ──────────────────────────────────── */
[data-style="brutalist"] .user-result-item {
border-radius: 0;
border: 2px solid var(--color-border);
box-shadow: 2px 2px 0 var(--color-border);
transition: box-shadow 0.08s ease, transform 0.08s ease, border-color 0.1s;
@@ -494,14 +335,9 @@
transform: translate(-2px, -2px);
}
/* ── Feed tab bar ────────────────────────────────────────────────── */
[data-style="brutalist"] .feed-tab {
border-radius: 0;
}
/* ── btn-primary ─────────────────────────────────────────────────── */
[data-style="brutalist"] .btn-primary {
border-radius: 0;
border: 2px solid var(--color-border);
box-shadow: 2px 2px 0 var(--color-border);
transition: box-shadow 0.08s ease, transform 0.08s ease;
@@ -519,7 +355,6 @@
/* ── btn-border ──────────────────────────────────────────────────── */
[data-style="brutalist"] .btn-border {
border-radius: 0;
box-shadow: 2px 2px 0 var(--color-border);
}
@@ -528,28 +363,11 @@
transform: translate(2px, 2px);
}
/* ── Comment actions ─────────────────────────────────────────────── */
[data-style="brutalist"] .comment-submit-btn,
[data-style="brutalist"] .comment-action-btn {
border-radius: 0;
}
/* ── Error card ──────────────────────────────────────────────────── */
[data-style="brutalist"] .error-card {
border-radius: 0;
}
/* ── Category switcher dropdown ──────────────────────────────────── */
/* The trigger reuses .feed-sort-btn, so it already wears this theme's button
chrome and lines up with the sort tabs. The menu keeps the shared popover
frame (matching .user-menu-dropdown here); only flatten its option buttons
so they read as list rows rather than chunky bevelled buttons. */
[data-style="brutalist"] .category-switcher-menu {
border-radius: 0;
}
[data-style="brutalist"] .category-switcher-option {
border: none !important;
border-radius: 0;
box-shadow: none !important;
}
[data-style="brutalist"] .category-switcher-option:hover:not(:disabled) {
@@ -557,7 +375,3 @@
box-shadow: none !important;
}
/* ── Journal masonry cards ───────────────────────────────────────── */
[data-style="brutalist"] .journal-card {
border-radius: 0;
}