diff --git a/README.md b/README.md index 648f2e3..47dd62d 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ **在线体验:[https://kvideo.pages.dev/](https://kvideo.pages.dev/)** +[![Version](https://img.shields.io/badge/Version-4.6.0-blue?style=for-the-badge)](https://github.com/KuekHaoYang/KVideo) [![Next.js](https://img.shields.io/badge/Next.js-16.1-black?style=for-the-badge&logo=next.js)](https://nextjs.org/) [![React](https://img.shields.io/badge/React-19.2-blue?style=for-the-badge&logo=react)](https://react.dev/) [![Tailwind CSS](https://img.shields.io/badge/Tailwind-4.0-38B2AC?style=for-the-badge&logo=tailwind-css)](https://tailwindcss.com/) @@ -24,11 +25,12 @@ 项目的视觉设计基于 **"Liquid Glass"** 设计系统,这是一套融合了以下特性的现代化 UI 设计语言: -- **玻璃拟态效果**:通过 `backdrop-filter` 实现的磨砂半透明效果,让 UI 元素如同真实的玻璃材质 -- **通用柔和度**:统一使用 `rounded-2xl` 和 `rounded-full` 两种圆角半径,创造和谐的视觉体验 -- **光影交互**:悬停和聚焦状态下的内发光效果,模拟光线被"捕获"的物理现象 -- **流畅动画**:基于物理的 `cubic-bezier` 曲线,实现自然的加速和减速过渡 -- **深度层级**:清晰的 z-axis 层次结构,增强空间感和交互反馈 +- **玻璃拟态效果**:通过 `backdrop-filter: blur(25px) saturate(180%)` 实现的磨砂半透明效果,让 UI 元素如同真实的玻璃材质,动态反射和折射背景内容 +- **通用柔和度**:严格使用 `rounded-2xl`(1.5rem)和 `rounded-full`(9999px)两种圆角半径,创造和谐统一的视觉体验 +- **光影交互**:悬停和聚焦状态下的内发光效果(lensing),模拟光线被"捕获"的物理现象,配合动态阴影响应用户交互 +- **流畅动画**:基于物理的 `cubic-bezier(0.2, 0.8, 0.2, 1)` 曲线,实现自然的加速和减速过渡 +- **深度层级**:清晰的 z-axis 层次结构,主交互层始终在视觉最前方,背景元素通过更多模糊和更低饱和度自然后退 +- **固定渐变背景**:`background-attachment: fixed` 的渐变背景,让玻璃效果在滚动时保持一致的视觉效果 ## 核心功能 diff --git a/app/styles/effects.css b/app/styles/effects.css index 3a49490..dc74acf 100644 --- a/app/styles/effects.css +++ b/app/styles/effects.css @@ -1,71 +1,38 @@ +/* Effects - Liquid Glass Design System */ @keyframes pulse { - - 0%, - 100% { - opacity: 1; - } - - 50% { - opacity: 0.5; - } + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } } @keyframes spin { - to { - transform: rotate(360deg); - } + to { transform: rotate(360deg); } } @keyframes spin-slow { - from { - transform: rotate(0deg); - } - - to { - transform: rotate(360deg); - } + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } } @keyframes spin-reverse { - from { - transform: rotate(360deg); - } - - to { - transform: rotate(0deg); - } + from { transform: rotate(360deg); } + to { transform: rotate(0deg); } } @keyframes bounce-subtle { - - 0%, - 100% { - transform: translateY(0); - } - - 50% { - transform: translateY(-5px); - } + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-5px); } } @keyframes shimmer { - 0% { - transform: translateX(-100%); - } - - 100% { - transform: translateX(100%); - } + 0% { transform: translateX(-100%); } + 100% { transform: translateX(100%); } } @keyframes float { - - 0%, - 100% { + 0%, 100% { transform: translateY(0) translateX(0); opacity: 0.3; } - 50% { transform: translateY(-20px) translateX(10px); opacity: 0.8; @@ -73,13 +40,19 @@ } @keyframes gradient-x { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} - 0%, - 100% { - background-position: 0% 50%; - } +/* Lensing inner-glow effect for interactive elements */ +.glass-glow:hover { + box-shadow: + 0 8px 24px var(--shadow-color), + inset 0 1px 0 rgba(255, 255, 255, 0.15); +} - 50% { - background-position: 100% 50%; - } -} \ No newline at end of file +.glass-glow:focus-visible { + box-shadow: + 0 0 0 3px color-mix(in srgb, var(--accent-color) 30%, transparent), + inset 0 1px 0 rgba(255, 255, 255, 0.15); +} diff --git a/app/styles/glass.css b/app/styles/glass.css index 828dece..e405061 100644 --- a/app/styles/glass.css +++ b/app/styles/glass.css @@ -1,36 +1,42 @@ -/* Glass Components */ +/* Glass Components - Liquid Glass Design System */ .glass-card { - background: var(--bg-color); - opacity: 1; + background: var(--glass-bg); + backdrop-filter: blur(25px) saturate(180%); + -webkit-backdrop-filter: blur(25px) saturate(180%); border-radius: var(--radius-2xl); - box-shadow: var(--shadow-sm); + box-shadow: var(--shadow-md); border: 1px solid var(--glass-border); - transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; - transform: translateZ(0); - will-change: transform; + transition: all var(--transition-fluid); + position: relative; } .glass-card:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-md); + transform: translateY(-5px) scale(1.02); + box-shadow: 0 8px 24px var(--shadow-color); + z-index: 10; } .glass-input { + width: 100%; background: var(--glass-bg); + backdrop-filter: blur(10px) saturate(150%); + -webkit-backdrop-filter: blur(10px) saturate(150%); border: 1px solid var(--glass-border); border-radius: var(--radius-2xl); color: var(--text-color); - transition: border-color 0.2s ease, box-shadow 0.2s ease; + transition: all var(--transition-fluid); } .glass-input:focus { outline: none; border-color: var(--accent-color); - box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.3); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-color) 30%, transparent); } .glass-button { + display: inline-flex; + align-items: center; + justify-content: center; background: var(--accent-color); color: white; border: none; @@ -45,7 +51,7 @@ .glass-button:hover { transform: translateY(-2px); filter: brightness(1.1); - box-shadow: var(--shadow-md); + box-shadow: 0 4px 8px var(--shadow-color); } .glass-button:active { @@ -53,6 +59,15 @@ filter: brightness(0.95); } +.glass-button:disabled { + background-color: var(--text-color-secondary); + opacity: 0.5; + cursor: not-allowed; + transform: none; + filter: none; + box-shadow: none; +} + .glass-badge { display: inline-flex; align-items: center; @@ -64,3 +79,26 @@ background-color: var(--accent-color); color: white; } + +.glass-badge-secondary { + background: var(--glass-bg); + border: 1px solid var(--glass-border); + color: var(--text-color); +} + +/* Glass backdrop for modals/drawers */ +.glass-backdrop { + background-color: rgba(0, 0, 0, 0.3); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); +} + +/* Glass popover/dropdown */ +.glass-popover { + background: var(--glass-bg); + backdrop-filter: blur(25px) saturate(180%); + -webkit-backdrop-filter: blur(25px) saturate(180%); + border-radius: var(--radius-2xl); + box-shadow: var(--shadow-md); + border: 1px solid var(--glass-border); +} diff --git a/app/styles/transitions.css b/app/styles/transitions.css index 9c156c5..0d44c78 100644 --- a/app/styles/transitions.css +++ b/app/styles/transitions.css @@ -1,9 +1,9 @@ +/* Transitions - Liquid Glass Design System */ @keyframes fade-in { from { opacity: 0; transform: translateY(10px); } - to { opacity: 1; transform: translateY(0); @@ -15,7 +15,6 @@ opacity: 0; transform: translateY(20px); } - to { opacity: 1; transform: translateY(0); @@ -25,9 +24,8 @@ @keyframes scale-in { 0% { opacity: 0; - transform: scale(0.9) translateY(10px); + transform: scale(0.95) translateY(10px); } - 100% { opacity: 1; transform: scale(1) translateY(0); @@ -39,10 +37,9 @@ opacity: 1; transform: scale(1) translateY(0); } - 100% { opacity: 0; - transform: scale(0.9) translateY(-10px); + transform: scale(0.95) translateY(-10px); } } @@ -51,7 +48,6 @@ opacity: 0; transform: translateY(-10px) scale(0.95); } - to { opacity: 1; transform: translateY(0) scale(1); @@ -59,23 +55,13 @@ } @keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } + from { opacity: 0; } + to { opacity: 1; } } @keyframes slideInRight { - from { - transform: translateX(100%); - } - - to { - transform: translateX(0); - } + from { transform: translateX(100%); } + to { transform: translateX(0); } } @keyframes fadeInUp { @@ -83,9 +69,36 @@ opacity: 0; transform: translateY(8px); } - to { opacity: 1; transform: translateY(0); } -} \ No newline at end of file +} + +@keyframes toast-in { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Utility animation classes */ +.animate-fade-in { + animation: fade-in 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); +} + +.animate-slide-up { + animation: slide-up 0.3s cubic-bezier(0.2, 0.8, 0.2, 1); +} + +.animate-scale-in { + animation: scale-in 0.3s cubic-bezier(0.2, 0.8, 0.2, 1); +} + +.animate-toast-in { + animation: toast-in 0.5s cubic-bezier(0.2, 0.8, 0.2, 1); +} diff --git a/app/styles/variables.css b/app/styles/variables.css index 57ea282..99edb7f 100644 --- a/app/styles/variables.css +++ b/app/styles/variables.css @@ -1,35 +1,35 @@ -/* CSS Custom Properties */ +/* CSS Custom Properties - Liquid Glass Design System */ :root { --font-family-system: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif; /* Light Mode Palette */ - --bg-color-light: #f2f4f7; - --bg-image-light: none; + --bg-color-light: #f0f2f5; + --bg-image-light: linear-gradient(120deg, #fdfbfb 0%, #ebedee 100%); --text-color-light: #1d1d1f; --text-color-secondary-light: #6e6e73; - --accent-color-light: #0056b3; - --glass-bg-light: rgba(255, 255, 255, 0.95); - --glass-border-light: rgba(0, 0, 0, 0.05); - --shadow-color-light: rgba(0, 0, 0, 0.05); + --accent-color-light: #007aff; + --glass-bg-light: rgba(242, 242, 247, 0.8); + --glass-border-light: rgba(255, 255, 255, 0.5); + --shadow-color-light: rgba(0, 0, 0, 0.1); /* Dark Mode Palette */ --bg-color-dark: #121212; - --bg-image-dark: linear-gradient(120deg, #1a1a1a 0%, #121212 100%); + --bg-image-dark: linear-gradient(120deg, #272B30 0%, #121212 100%); --text-color-dark: #f5f5f7; --text-color-secondary-dark: #8e8e93; - --accent-color-dark: #1A6DBF; - --glass-bg-dark: rgba(30, 30, 30, 0.9); - --glass-border-dark: rgba(255, 255, 255, 0.1); + --accent-color-dark: #0a84ff; + --glass-bg-dark: rgba(28, 28, 30, 0.75); + --glass-border-dark: rgba(60, 60, 60, 0.7); --shadow-color-dark: rgba(0, 0, 0, 0.3); /* Universal Variables */ --radius-2xl: 1.5rem; --radius-full: 9999px; - --shadow-sm: 0 1px 2px var(--shadow-color); - --shadow-md: 0 4px 6px var(--shadow-color); - --transition-fluid: 0.3s ease; + --shadow-sm: 0 2px 4px var(--shadow-color); + --shadow-md: 0 4px 12px var(--shadow-color); + --transition-fluid: 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); - /* Active Theme Variables */ + /* Active Theme Variables (default: light) */ --bg-color: var(--bg-color-light); --bg-image: var(--bg-image-light); --text-color: var(--text-color-light); @@ -39,7 +39,7 @@ --glass-border: var(--glass-border-light); --shadow-color: var(--shadow-color-light); - --background: #f2f4f7; + --background: #f0f2f5; --foreground: #1d1d1f; } @@ -55,8 +55,10 @@ body { background-color: var(--bg-color); background-image: var(--bg-image); + background-attachment: fixed; color: var(--text-color); font-family: var(--font-family-system); + transition: background 0.3s ease; -webkit-overflow-scrolling: touch; overscroll-behavior-y: none; @@ -75,4 +77,4 @@ body.dark, --background: #121212; --foreground: #f5f5f7; -} \ No newline at end of file +} diff --git a/components/layout/Navbar.tsx b/components/layout/Navbar.tsx index 6a303d2..ad8c2e0 100644 --- a/components/layout/Navbar.tsx +++ b/components/layout/Navbar.tsx @@ -24,19 +24,35 @@ export function Navbar({ onReset, isPremiumMode = false }: NavbarProps) { const handleLogout = () => { clearSession(); - // Navigate to root to clear search query params window.location.href = '/'; }; + const iconBtnClass = ` + w-8 h-8 sm:w-10 sm:h-10 + flex items-center justify-center + rounded-[var(--radius-full)] + bg-[var(--glass-bg)] + border border-[var(--glass-border)] + text-[var(--text-color)] + hover:bg-[color-mix(in_srgb,var(--accent-color)_10%,transparent)] + transition-all duration-200 + cursor-pointer + `; + return ( -