siftlode/frontend/src/index.css

226 lines
5.8 KiB
CSS
Raw Normal View History

@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--font-scale: 1.06;
}
/* Make native controls (date picker, scrollbars) follow the theme. */
html[data-theme="dark"] {
color-scheme: dark;
}
html[data-theme="light"] {
color-scheme: light;
}
html {
font-size: calc(16px * var(--font-scale));
background: var(--bg);
}
body {
margin: 0;
color: var(--fg);
/* Ambient backdrop so translucent "glass" surfaces have soft color to refract. */
background:
radial-gradient(1100px 620px at 12% -8%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 60%),
radial-gradient(1000px 700px at 112% 8%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 55%),
var(--bg);
background-attachment: fixed;
}
/* ===== Liquid-glass surface system (theme-aware, GPU-light) ===== */
.glass {
/* Frosted overlay surface: translucent enough that the blurred backdrop shows
through (the glassy look), opaque enough that the background isn't distracting.
The strong blur turns whatever is behind into soft colour, not a sharp image. */
2026-06-11 22:49:04 +02:00
background: color-mix(in srgb, var(--surface) 78%, transparent);
backdrop-filter: blur(30px) saturate(1.8);
-webkit-backdrop-filter: blur(30px) saturate(1.8);
border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
box-shadow:
inset 0 1px 0 color-mix(in srgb, #fff 16%, transparent),
0 18px 44px -16px rgba(0, 0, 0, 0.6);
}
.glass-card {
/* No backdrop-filter here: cards render in bulk (feed grid) over a solid background
where blur adds almost nothing visually but is GPU-expensive and triggers reflow.
Translucency + border + depth keep the look; blur is reserved for .glass overlays. */
background: color-mix(in srgb, var(--card) 84%, transparent);
border: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
box-shadow:
inset 0 1px 0 color-mix(in srgb, #fff 8%, transparent),
0 8px 22px -14px rgba(0, 0, 0, 0.45);
}
.glass-hover:hover {
border-color: color-mix(in srgb, var(--accent) 55%, transparent);
box-shadow:
inset 0 1px 0 color-mix(in srgb, #fff 12%, transparent),
0 14px 30px -14px rgba(0, 0, 0, 0.5);
}
/* Performance mode (Settings → Appearance) drops the expensive blur + soft shadows. */
html[data-perf="1"] .glass,
html[data-perf="1"] .glass-card {
backdrop-filter: none;
-webkit-backdrop-filter: none;
background: var(--surface);
box-shadow: 0 2px 8px -4px rgba(0, 0, 0, 0.4);
}
html[data-perf="1"] body {
background: var(--bg);
}
/* Skip layout/paint for off-screen feed cards so long lists stay smooth while
scrolling. contain-intrinsic-size reserves an approximate box so the scrollbar
stays stable; `auto` lets the browser remember each card's real size after it
has rendered once. */
.cv-card {
content-visibility: auto;
contain-intrinsic-size: auto 320px;
}
.cv-row {
content-visibility: auto;
contain-intrinsic-size: auto 96px;
}
/* ===== Motion ===== */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes overlayIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes overlayOut {
from { opacity: 1; }
to { opacity: 0; }
}
@keyframes panelIn {
from { transform: translateX(100%); }
to { transform: translateX(0); }
}
@keyframes panelOut {
from { transform: translateX(0); }
to { transform: translateX(100%); }
}
@keyframes popIn {
from { opacity: 0; transform: translateY(-6px) scale(0.97); }
to { opacity: 1; transform: none; }
}
/* ===== 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;
}
/* Toast auto-dismiss countdown bar (shrinks left-to-right to zero) */
@keyframes toastbar {
from {
transform: scaleX(1);
}
to {
transform: scaleX(0);
}
}
/* Thin, theme-aware scrollbars */
* {
scrollbar-color: var(--border) transparent;
}
*::-webkit-scrollbar {
width: 10px;
height: 10px;
}
*::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: 8px;
}