feat: M4 (part 2) — React reader UI with theming
- Vite + React + TS + Tailwind SPA served by FastAPI (multi-stage Docker build) - Four color schemes (Midnight default, Forest, Slate, YouTube) x dark/light, adjustable text size; persisted to user preferences and localStorage - Header search, grid/list toggle, theme menu; sidebar filters (show state, sort, include Shorts/live, language + topic tag chips with any/all matching) - Infinite-scroll feed of video cards; click opens youtube.com in a new tab; per-video watched / saved / hidden actions with optimistic updates - SPA fallback routing; login screen for unauthenticated users
This commit is contained in:
parent
9a377b7e7e
commit
e56502789f
20 changed files with 1194 additions and 4 deletions
121
frontend/src/index.css
Normal file
121
frontend/src/index.css
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--font-scale: 1.06;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: calc(16px * var(--font-scale));
|
||||
background: var(--bg);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
/* ===== Color schemes (accent + neutrals), each with dark + light ===== */
|
||||
|
||||
/* Midnight — deep navy/slate with blue accent (default) */
|
||||
html[data-scheme="midnight"][data-theme="dark"] {
|
||||
--bg: #0b1020;
|
||||
--surface: #121a2e;
|
||||
--card: #161f38;
|
||||
--border: #243049;
|
||||
--fg: #e6e9f0;
|
||||
--muted: #97a3c0;
|
||||
--accent: #6d8cff;
|
||||
--accent-fg: #0b1020;
|
||||
}
|
||||
html[data-scheme="midnight"][data-theme="light"] {
|
||||
--bg: #f4f6fc;
|
||||
--surface: #ffffff;
|
||||
--card: #ffffff;
|
||||
--border: #dde3f0;
|
||||
--fg: #1a2238;
|
||||
--muted: #5b6685;
|
||||
--accent: #3b5bdb;
|
||||
--accent-fg: #ffffff;
|
||||
}
|
||||
|
||||
/* Forest — dark slate with teal/green accent */
|
||||
html[data-scheme="forest"][data-theme="dark"] {
|
||||
--bg: #0a1512;
|
||||
--surface: #0f1f1a;
|
||||
--card: #12241e;
|
||||
--border: #1f3a30;
|
||||
--fg: #e6f0ec;
|
||||
--muted: #90b1a4;
|
||||
--accent: #2dd4bf;
|
||||
--accent-fg: #04110d;
|
||||
}
|
||||
html[data-scheme="forest"][data-theme="light"] {
|
||||
--bg: #f1f7f4;
|
||||
--surface: #ffffff;
|
||||
--card: #ffffff;
|
||||
--border: #d6e7e0;
|
||||
--fg: #102a22;
|
||||
--muted: #4d6b60;
|
||||
--accent: #0d9488;
|
||||
--accent-fg: #ffffff;
|
||||
}
|
||||
|
||||
/* Slate — neutral grey with warm orange accent (muted in dark) */
|
||||
html[data-scheme="slate"][data-theme="dark"] {
|
||||
--bg: #15171c;
|
||||
--surface: #1b1e25;
|
||||
--card: #1f232b;
|
||||
--border: #2c313b;
|
||||
--fg: #e7e9ee;
|
||||
--muted: #9aa1ad;
|
||||
--accent: #e8913c;
|
||||
--accent-fg: #1a1206;
|
||||
}
|
||||
html[data-scheme="slate"][data-theme="light"] {
|
||||
--bg: #f6f7f9;
|
||||
--surface: #ffffff;
|
||||
--card: #ffffff;
|
||||
--border: #e3e6eb;
|
||||
--fg: #1c1f26;
|
||||
--muted: #5d636e;
|
||||
--accent: #d97706;
|
||||
--accent-fg: #ffffff;
|
||||
}
|
||||
|
||||
/* YouTube — near-black with red accent */
|
||||
html[data-scheme="youtube"][data-theme="dark"] {
|
||||
--bg: #0f0f0f;
|
||||
--surface: #181818;
|
||||
--card: #1f1f1f;
|
||||
--border: #303030;
|
||||
--fg: #f1f1f1;
|
||||
--muted: #aaaaaa;
|
||||
--accent: #ff3b46;
|
||||
--accent-fg: #ffffff;
|
||||
}
|
||||
html[data-scheme="youtube"][data-theme="light"] {
|
||||
--bg: #ffffff;
|
||||
--surface: #f9f9f9;
|
||||
--card: #ffffff;
|
||||
--border: #e5e5e5;
|
||||
--fg: #0f0f0f;
|
||||
--muted: #606060;
|
||||
--accent: #ff0033;
|
||||
--accent-fg: #ffffff;
|
||||
}
|
||||
|
||||
/* Thin, theme-aware scrollbars */
|
||||
* {
|
||||
scrollbar-color: var(--border) transparent;
|
||||
}
|
||||
*::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
border-radius: 8px;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue