PersonalWebApplication/Client/src/index.css
cc 58284f3fe0 feat: add login/auth system + blog page with rainbow design
- Client: auth API wrapper (api/auth.ts) + useAuth hook with localStorage persistence

- Client: LoginPage/LoginForm with remember-me and loading states

- Client: BlogPage with hero section, rainbow spotlight cursor effect, post list

- Client: CSS rainbow gradient utilities for text/borders/backgrounds

- Server: POST /api/web/login with username/password verification + token

- Server: CORS extended to POST + Content-Type header

- Server: auth.rs token issuer, serde dependency for JSON

- Chore: gitignore Server/.vite

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 00:00:38 +08:00

220 lines
6.9 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.

/* ── Fonts (本地打包,离线/WSL 可用) ───────────────────────── */
@import '@fontsource-variable/fraunces/opsz.css';
@import '@fontsource-variable/fraunces/opsz-italic.css';
@import '@fontsource/hanken-grotesk/300.css';
@import '@fontsource/hanken-grotesk/400.css';
@import '@fontsource/hanken-grotesk/500.css';
@import '@fontsource/hanken-grotesk/600.css';
@import 'tailwindcss';
/* ── Design tokens暖调暗色编辑风──────────────────────────── */
@theme {
--color-bg: #17130f;
--color-surface: #221c16;
--color-text: #eae2d4;
--color-muted: #9b8f7e;
--color-accent: #c99a5b;
--color-accent-soft: #e0bd8a;
--color-line: #3a3027;
--font-display: 'Fraunces Variable', ui-serif, Georgia, serif;
--font-sans: 'Hanken Grotesk', system-ui, -apple-system, sans-serif;
}
/* ── Base ────────────────────────────────────────────────── */
html {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
body {
margin: 0;
min-height: 100svh;
background-color: var(--color-bg);
color: var(--color-text);
font-family: var(--font-sans);
font-weight: 400;
/* 隐藏系统光标,由 CursorFollower 接管(仅精确指针设备)*/
}
@media (pointer: fine) {
body.has-custom-cursor,
body.has-custom-cursor * {
cursor: none;
}
}
/* 选中文本配色 */
::selection {
background: var(--color-accent);
color: var(--color-bg);
}
/* 可见键盘焦点环 */
:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 2px;
}
/* ── 颗粒噪点(叠加在氛围面板上)─────────────────────────────── */
.grain::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
opacity: 0.06;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
mix-blend-mode: overlay;
}
/* ── 动态渐变 mesh缓慢漂移───────────────────────────────── */
@keyframes drift {
0% { transform: translate3d(-6%, -4%, 0) scale(1.15) rotate(0deg); }
50% { transform: translate3d(6%, 4%, 0) scale(1.25) rotate(8deg); }
100% { transform: translate3d(-6%, -4%, 0) scale(1.15) rotate(0deg); }
}
.mesh {
position: absolute;
inset: -25%;
background:
radial-gradient(40% 45% at 25% 30%, rgba(201, 154, 91, 0.45), transparent 70%),
radial-gradient(35% 40% at 75% 65%, rgba(140, 96, 64, 0.40), transparent 70%),
radial-gradient(45% 50% at 60% 20%, rgba(90, 70, 52, 0.40), transparent 70%);
filter: blur(40px);
animation: drift 26s ease-in-out infinite;
will-change: transform;
}
/* ── 标题下划线闪烁游标 ──────────────────────────────────────── */
@keyframes blink {
0%, 45% { opacity: 1; }
50%, 95% { opacity: 0; }
100% { opacity: 1; }
}
.cursor-bar {
animation: blink 1.15s steps(1, end) infinite;
}
/* ── 彩虹(仿 joshwcomeau─────────────────────────────────────
一条横向流动的多色渐变。首尾同色,配合 200% 宽度做无缝平移。
既可裁切到文字,也可铺在装饰条上。 */
@keyframes rainbow-pan {
to {
background-position: 200% center;
}
}
.rainbow-gradient {
background-image: linear-gradient(
90deg,
#ff5f6d,
#ffb13d,
#ffe14d,
#4ade80,
#38bdf8,
#a78bfa,
#f472b6,
#ff5f6d
);
background-size: 200% auto;
animation: rainbow-pan 6s linear infinite;
}
/* 把流动彩虹裁切进文字(始终显示彩虹色) */
.rainbow-text {
background-image: linear-gradient(
90deg,
#ff5f6d,
#ffb13d,
#ffe14d,
#4ade80,
#38bdf8,
#a78bfa,
#f472b6,
#ff5f6d
);
background-size: 200% auto;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
animation: rainbow-pan 6s linear infinite;
}
/* 把彩虹裁进文字但不强制颜色:默认用不透明文字色盖住,
hover 时把文字色设为 transparentgroup-hover:text-transparent即露出彩虹。 */
.rainbow-clip {
background-image: linear-gradient(
90deg,
#ff5f6d,
#ffb13d,
#ffe14d,
#4ade80,
#38bdf8,
#a78bfa,
#f472b6,
#ff5f6d
);
background-size: 200% auto;
-webkit-background-clip: text;
background-clip: text;
animation: rainbow-pan 6s linear infinite;
}
/* ── 整页彩虹极光背景(玻璃栏透出的就是它)──────────────────────
固定铺满视口、置于所有内容之下。多个彩色径向光斑缓慢漂移,
再大幅模糊成柔和极光。底色为暗色,避免内容区透出时发灰。 */
.aurora {
position: fixed;
inset: 0;
z-index: -10;
overflow: hidden;
background-color: var(--color-bg);
}
.aurora::before {
content: '';
position: absolute;
inset: -25%;
background:
radial-gradient(28% 30% at 18% 28%, rgba(255, 95, 109, 0.55), transparent 70%),
radial-gradient(26% 30% at 82% 26%, rgba(56, 189, 248, 0.50), transparent 70%),
radial-gradient(30% 34% at 72% 76%, rgba(167, 139, 250, 0.50), transparent 70%),
radial-gradient(28% 32% at 26% 80%, rgba(74, 222, 128, 0.45), transparent 70%),
radial-gradient(24% 28% at 50% 50%, rgba(255, 177, 61, 0.40), transparent 70%);
filter: blur(70px);
animation: drift 28s ease-in-out infinite;
will-change: transform;
}
/* ── 两侧液态玻璃竖栏 ─────────────────────────────────────────
backdrop-filter 把背后的极光磨成柔光;内侧一道高光边模拟玻璃厚度。 */
.glass-rail {
background: rgba(255, 255, 255, 0.04);
backdrop-filter: blur(16px) saturate(140%);
-webkit-backdrop-filter: blur(16px) saturate(140%);
box-shadow: inset 0 0 60px rgba(255, 255, 255, 0.03);
}
/* 中间内容纸张:也带轻微玻璃感(压暗 + 模糊背后极光保证可读) */
.glass-sheet {
background: rgba(23, 19, 15, 0.82);
backdrop-filter: blur(22px) saturate(120%);
-webkit-backdrop-filter: blur(22px) saturate(120%);
}
/* ── reduced-motion 降级 ────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
.mesh,
.cursor-bar,
.rainbow-gradient,
.rainbow-text,
.rainbow-clip,
.aurora::before {
animation: none;
}
}