From a87259a2eeda08d81994c780735b46f2f3d0c337 Mon Sep 17 00:00:00 2001 From: lintsinghua Date: Thu, 27 Nov 2025 22:34:23 +0800 Subject: [PATCH] feat: update UI with new branding, logo, and modern terminal-inspired styling --- frontend/index.html | 7 + frontend/src/app/App.tsx | 4 +- frontend/src/assets/styles/globals.css | 359 +++++++++++++++++---- frontend/src/components/layout/Sidebar.tsx | 36 +-- frontend/src/components/ui/button.tsx | 18 +- frontend/src/components/ui/input.tsx | 6 +- frontend/src/pages/AdminDashboard.tsx | 9 +- frontend/src/pages/AuditTasks.tsx | 9 +- frontend/src/pages/Dashboard.tsx | 26 +- frontend/src/pages/InstantAnalysis.tsx | 7 +- frontend/src/pages/Login.tsx | 26 +- frontend/src/pages/ProjectDetail.tsx | 7 +- frontend/src/pages/Projects.tsx | 110 +++---- frontend/src/pages/RecycleBin.tsx | 13 +- frontend/src/pages/Register.tsx | 2 +- frontend/src/pages/TaskDetail.tsx | 2 +- frontend/tailwind.config.js | 109 +++++-- 17 files changed, 524 insertions(+), 226 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 7dcb069..cdf8c78 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -6,6 +6,13 @@ XCodeReviewer + + + + + diff --git a/frontend/src/app/App.tsx b/frontend/src/app/App.tsx index 99b50ef..977ea78 100644 --- a/frontend/src/app/App.tsx +++ b/frontend/src/app/App.tsx @@ -19,9 +19,7 @@ function AppLayout() { className={`transition-all duration-300 min-h-screen ${collapsed ? "md:ml-20" : "md:ml-64" }`} > -
- -
+ ); diff --git a/frontend/src/assets/styles/globals.css b/frontend/src/assets/styles/globals.css index b168702..4f888cc 100644 --- a/frontend/src/assets/styles/globals.css +++ b/frontend/src/assets/styles/globals.css @@ -2,67 +2,110 @@ @tailwind components; @tailwind utilities; +/* + XCodeReviewer Design System + Aesthetic: Terminal Retro + Pixel Art + Mechanical + Cassette Futurism + Core Palette: Orange, Deep Red, Signal Green, Grey + Philosophy: Clean, legible, harmonious - simplified linework for reduced eye strain +*/ + @layer base { :root { - --background: 210 20% 98%; - --foreground: 220 10% 10%; + /* Background & Surface - Soft light grey for comfort */ + --background: 0 0% 96%; + --foreground: 0 0% 15%; - --card: 0 0% 100%; - --card-foreground: 220 10% 10%; + /* Card & Surfaces - Clean white with subtle warmth */ + --card: 0 0% 98%; + --card-foreground: 0 0% 15%; - --popover: 0 0% 100%; - --popover-foreground: 220 10% 10%; + /* Popover */ + --popover: 0 0% 98%; + --popover-foreground: 0 0% 15%; - --primary: 220 100% 50%; + /* Primary - Vibrant Orange (Core brand color) */ + --primary: 16 100% 58%; --primary-foreground: 0 0% 100%; - --secondary: 15 100% 50%; + /* Secondary - Deep Red (Accent & warnings) */ + --secondary: 4 70% 52%; --secondary-foreground: 0 0% 100%; - --muted: 210 20% 90%; - --muted-foreground: 220 10% 40%; + /* Success/Active - Signal Green */ + --success: 145 100% 45%; + --success-foreground: 0 0% 100%; - --accent: 180 100% 40%; + /* Muted - Neutral Grey tones */ + --muted: 0 0% 88%; + --muted-foreground: 0 0% 45%; + + /* Accent - Mechanical Grey-Blue */ + --accent: 210 15% 50%; --accent-foreground: 0 0% 100%; - --destructive: 0 100% 50%; + /* Destructive - Deep Red variant */ + --destructive: 4 70% 52%; --destructive-foreground: 0 0% 100%; - --border: 0 0% 0%; - --input: 0 0% 0%; - --ring: 220 100% 50%; + /* Borders & Inputs - Simplified grey */ + --border: 0 0% 75%; + --input: 0 0% 75%; + --ring: 16 100% 58%; - --radius: 0rem; + /* Border radius - Sharp pixel aesthetic */ + --radius: 2px; + + /* Simplified shadows - subtle depth */ + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08); + --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.1); + --shadow-focus: 0 0 0 2px rgba(255, 107, 44, 0.25); } .dark { - --background: 220 10% 10%; - --foreground: 210 20% 98%; + /* Dark mode - balanced, not too dim */ + --background: 220 15% 12%; + --foreground: 0 0% 92%; - --card: 220 10% 15%; - --card-foreground: 210 20% 98%; + /* Surfaces - subtle elevation */ + --card: 220 15% 16%; + --card-foreground: 0 0% 92%; - --popover: 220 10% 15%; - --popover-foreground: 210 20% 98%; + --popover: 220 15% 16%; + --popover-foreground: 0 0% 92%; - --primary: 220 100% 50%; - --primary-foreground: 0 0% 100%; + /* Primary - Orange (slightly desaturated for dark mode) */ + --primary: 16 95% 60%; + --primary-foreground: 0 0% 10%; - --secondary: 15 100% 50%; - --secondary-foreground: 0 0% 100%; + /* Secondary - Deep Red */ + --secondary: 4 65% 55%; + --secondary-foreground: 0 0% 10%; - --muted: 220 10% 20%; - --muted-foreground: 210 20% 60%; + /* Success - Signal Green (slightly muted) */ + --success: 145 90% 48%; + --success-foreground: 0 0% 10%; - --accent: 180 100% 40%; - --accent-foreground: 0 0% 100%; + /* Muted - Darker grey tones */ + --muted: 220 15% 22%; + --muted-foreground: 0 0% 60%; - --destructive: 0 100% 50%; - --destructive-foreground: 0 0% 100%; + /* Accent */ + --accent: 210 15% 45%; + --accent-foreground: 0 0% 95%; - --border: 0 0% 100%; - --input: 0 0% 100%; - --ring: 220 100% 50%; + /* Destructive */ + --destructive: 4 65% 55%; + --destructive-foreground: 0 0% 10%; + + /* Borders - softer in dark mode */ + --border: 220 15% 28%; + --input: 220 15% 28%; + --ring: 16 95% 60%; + + /* Dark mode shadows */ + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3); + --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.4); + --shadow-focus: 0 0 0 2px rgba(255, 107, 44, 0.3); } } @@ -73,45 +116,249 @@ body { @apply bg-background text-foreground font-mono antialiased; + /* Smooth transitions for theme changes */ + transition: background-color 0.2s ease, color 0.2s ease; + } + + /* Typography Hierarchy - Clean & Legible */ + h1 { + @apply font-display font-bold tracking-tight text-3xl; + letter-spacing: -0.02em; + } + + h2 { + @apply font-display font-bold tracking-tight text-2xl; + letter-spacing: -0.01em; + } + + h3 { + @apply font-display font-bold tracking-tight text-xl; + } + + h4 { + @apply font-display font-semibold tracking-tight text-lg; } - h1, - h2, - h3, - h4, h5, h6 { - @apply font-display font-bold tracking-tight; + @apply font-display font-semibold text-base; + } + + /* Improved focus states */ + button:focus-visible, + input:focus-visible, + textarea:focus-visible, + select:focus-visible { + outline: none; + box-shadow: var(--shadow-focus); + } + + /* Smooth scrolling */ + html { + scroll-behavior: smooth; } } @layer utilities { - .retro-border { - @apply border-2 border-black; - box-shadow: 4px 4px 0px 0px rgba(0, 0, 0, 1); + + /* Simplified Terminal Border - 1px for cleaner look */ + .terminal-border { + @apply border border-border; + box-shadow: var(--shadow-sm); } - .retro-card { - @apply bg-white border-2 border-black p-4; - box-shadow: 4px 4px 0px 0px rgba(0, 0, 0, 1); + /* Enhanced Terminal Border with subtle elevation */ + .terminal-border-elevated { + @apply border border-border; + box-shadow: var(--shadow-md); } - .retro-btn { - @apply bg-primary text-white font-bold py-2 px-4 border-2 border-black transition-all; - box-shadow: 4px 4px 0px 0px rgba(0, 0, 0, 1); + /* Terminal Card - Clean and minimal */ + .terminal-card { + @apply bg-card border border-border p-4 rounded-sm; + box-shadow: var(--shadow-sm); + transition: box-shadow 0.2s ease; } - .retro-btn:hover { - box-shadow: 2px 2px 0px 0px rgba(0, 0, 0, 1); - transform: translate(2px, 2px); + .terminal-card:hover { + box-shadow: var(--shadow-md); } - .retro-btn:active { + /* Button Variants - Simplified with 1px borders */ + .terminal-btn { + @apply font-mono font-semibold py-2 px-4 border border-border rounded-sm transition-all duration-150; + box-shadow: var(--shadow-sm); + } + + .terminal-btn:hover:not(:disabled) { + box-shadow: var(--shadow-md); + transform: translateY(-1px); + } + + .terminal-btn:active:not(:disabled) { box-shadow: none; - transform: translate(4px, 4px); + transform: translateY(0); } - .retro-input { - @apply bg-white border-2 border-black p-2 focus:outline-none focus:ring-2 focus:ring-primary shadow-none; + .terminal-btn:disabled { + @apply opacity-50 cursor-not-allowed; + } + + /* Primary Button - Orange */ + .terminal-btn-primary { + @apply terminal-btn bg-primary text-primary-foreground; + border-color: hsl(16 100% 50%); + } + + .terminal-btn-primary:hover:not(:disabled) { + background: hsl(16 100% 52%); + } + + /* Secondary Button - Deep Red */ + .terminal-btn-secondary { + @apply terminal-btn bg-secondary text-secondary-foreground; + border-color: hsl(4 70% 45%); + } + + .terminal-btn-secondary:hover:not(:disabled) { + background: hsl(4 70% 56%); + } + + /* Success Button - Signal Green */ + .terminal-btn-success { + @apply terminal-btn text-white; + background: hsl(var(--success)); + border-color: hsl(145 100% 38%); + } + + .terminal-btn-success:hover:not(:disabled) { + background: hsl(145 100% 48%); + } + + /* Ghost Button - Outline only */ + .terminal-btn-ghost { + @apply terminal-btn bg-transparent; + } + + .terminal-btn-ghost:hover:not(:disabled) { + @apply bg-muted; + } + + /* Input Fields - Simplified */ + .terminal-input { + @apply bg-background border border-input px-3 py-2 rounded-sm font-mono text-sm; + transition: border-color 0.15s ease, box-shadow 0.15s ease; + } + + .terminal-input:focus { + outline: none; + border-color: hsl(var(--primary)); + box-shadow: var(--shadow-focus); + } + + .terminal-input::placeholder { + @apply text-muted-foreground; + opacity: 0.6; + } + + /* Badge Components */ + .terminal-badge { + @apply inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-mono font-semibold; + border: 1px solid transparent; + } + + .terminal-badge-orange { + @apply terminal-badge bg-primary text-primary-foreground; + border-color: hsl(16 100% 50%); + } + + .terminal-badge-red { + @apply terminal-badge bg-secondary text-secondary-foreground; + border-color: hsl(4 70% 45%); + } + + .terminal-badge-green { + @apply terminal-badge text-white; + background: hsl(var(--success)); + border-color: hsl(145 100% 38%); + } + + .terminal-badge-grey { + @apply terminal-badge bg-muted text-muted-foreground; + border-color: hsl(var(--border)); + } + + /* Code Block Styling */ + .terminal-code { + @apply bg-muted border border-border rounded-sm p-3 font-mono text-sm overflow-x-auto; + } + + /* Scanline Effect - Subtle CRT aesthetic */ + .terminal-scanline { + position: relative; + overflow: hidden; + } + + .terminal-scanline::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(to bottom, + transparent 50%, + rgba(0, 0, 0, 0.02) 50%); + background-size: 100% 4px; + pointer-events: none; + z-index: 1; + } + + /* Pixel Grid Background - Very subtle */ + .terminal-pixel-grid { + background-image: + linear-gradient(rgba(0, 0, 0, 0.02) 1px, transparent 1px), + linear-gradient(90deg, rgba(0, 0, 0, 0.02) 1px, transparent 1px); + background-size: 8px 8px; + } + + /* Status Indicators */ + .status-indicator { + @apply w-2 h-2 rounded-full inline-block; + } + + .status-active { + background: hsl(var(--success)); + box-shadow: 0 0 4px hsl(var(--success)); + } + + .status-warning { + background: hsl(var(--primary)); + box-shadow: 0 0 4px hsl(var(--primary)); + } + + .status-error { + background: hsl(var(--secondary)); + box-shadow: 0 0 4px hsl(var(--secondary)); + } + + .status-inactive { + @apply bg-muted-foreground; + } + + /* Divider */ + .terminal-divider { + @apply border-t border-border my-4; + } + + /* Panel - For sections/containers */ + .terminal-panel { + @apply bg-card border border-border rounded-sm p-6; + box-shadow: var(--shadow-sm); + } + + /* Smooth transitions */ + .terminal-transition { + transition: all 0.15s ease; } } \ No newline at end of file diff --git a/frontend/src/components/layout/Sidebar.tsx b/frontend/src/components/layout/Sidebar.tsx index b58c583..2d1b541 100644 --- a/frontend/src/components/layout/Sidebar.tsx +++ b/frontend/src/components/layout/Sidebar.tsx @@ -13,8 +13,7 @@ import { FileText, ChevronLeft, ChevronRight, - Github, - Terminal + Github } from "lucide-react"; import routes from "@/app/routes"; @@ -46,7 +45,7 @@ export default function Sidebar({ collapsed, setCollapsed }: SidebarProps) { -
+
没有访问令牌? navigate('/register')}>申请访问
diff --git a/frontend/src/pages/ProjectDetail.tsx b/frontend/src/pages/ProjectDetail.tsx index d99487a..d0307a7 100644 --- a/frontend/src/pages/ProjectDetail.tsx +++ b/frontend/src/pages/ProjectDetail.tsx @@ -313,9 +313,12 @@ export default function ProjectDetail() { return ( -
+
+ {/* Decorative Background */} +
+ {/* 页面标题 */} -
+
- + @@ -394,7 +394,7 @@ export default function Projects() {
- + setCreateForm({ ...createForm, name: e.target.value })} placeholder="输入项目名称" - className="retro-input" + className="terminal-input" />
@@ -427,10 +427,10 @@ export default function Projects() { value={createForm.repository_type} onValueChange={(value: any) => setCreateForm({ ...createForm, repository_type: value })} > - + - + GITHUB GITLAB OTHER @@ -447,7 +447,7 @@ export default function Projects() { onChange={(e) => setCreateForm({ ...createForm, description: e.target.value })} placeholder="// 项目描述..." rows={3} - className="retro-input min-h-[100px]" + className="terminal-input min-h-[100px]" />
@@ -459,7 +459,7 @@ export default function Projects() { value={createForm.repository_url} onChange={(e) => setCreateForm({ ...createForm, repository_url: e.target.value })} placeholder="https://github.com/user/repo" - className="retro-input" + className="terminal-input" />
@@ -469,7 +469,7 @@ export default function Projects() { value={createForm.default_branch} onChange={(e) => setCreateForm({ ...createForm, default_branch: e.target.value })} placeholder="main" - className="retro-input" + className="terminal-input" />
@@ -479,7 +479,7 @@ export default function Projects() {
{supportedLanguages.map((lang) => ( @@ -507,10 +507,10 @@ export default function Projects() {
- -
@@ -525,7 +525,7 @@ export default function Projects() { value={createForm.name} onChange={(e) => setCreateForm({ ...createForm, name: e.target.value })} placeholder="输入项目名称" - className="retro-input" + className="terminal-input" />
@@ -537,7 +537,7 @@ export default function Projects() { onChange={(e) => setCreateForm({ ...createForm, description: e.target.value })} placeholder="// 项目描述..." rows={3} - className="retro-input min-h-[100px]" + className="terminal-input min-h-[100px]" />
@@ -546,7 +546,7 @@ export default function Projects() {
{supportedLanguages.map((lang) => ( @@ -592,7 +592,7 @@ export default function Projects() {
- +
)} -
+
@@ -631,7 +631,7 @@ export default function Projects() {
-
@@ -645,49 +645,49 @@ export default function Projects() { {/* Stats Section */} {projects.length > 0 && (
-
+

项目总数

{projects.length}

-
+
-
+

活跃

{projects.filter(p => p.is_active).length}

-
+
-
+

GitHub

{projects.filter(p => p.repository_type === 'github').length}

-
+
-
+

GitLab

{projects.filter(p => p.repository_type === 'gitlab').length}

-
+
@@ -696,17 +696,17 @@ export default function Projects() { )} {/* Search and Filter */} -
+
setSearchTerm(e.target.value)} - className="retro-input pl-10 w-full" + className="terminal-input pl-10 w-full" />
- @@ -716,10 +716,10 @@ export default function Projects() {
{filteredProjects.length > 0 ? ( filteredProjects.map((project) => ( -
+
-
+
{getRepositoryIcon(project.repository_type)}
@@ -783,20 +783,20 @@ export default function Projects() {
- -
- -
@@ -805,7 +805,7 @@ export default function Projects() { )) ) : (
-
+

{searchTerm ? '未找到匹配项' : '未初始化项目'} @@ -814,7 +814,7 @@ export default function Projects() { {searchTerm ? '调整搜索参数' : '初始化第一个项目以开始'}

{!searchTerm && ( - @@ -834,7 +834,7 @@ export default function Projects() { {/* Edit Dialog */} - + @@ -850,7 +850,7 @@ export default function Projects() { id="edit-name" value={editForm.name} onChange={(e) => setEditForm({ ...editForm, name: e.target.value })} - className="retro-input" + className="terminal-input" />

@@ -860,7 +860,7 @@ export default function Projects() { value={editForm.description} onChange={(e) => setEditForm({ ...editForm, description: e.target.value })} rows={3} - className="retro-input" + className="terminal-input" />
@@ -874,7 +874,7 @@ export default function Projects() { id="edit-repo-url" value={editForm.repository_url} onChange={(e) => setEditForm({ ...editForm, repository_url: e.target.value })} - className="retro-input" + className="terminal-input" />
@@ -885,10 +885,10 @@ export default function Projects() { value={editForm.repository_type} onValueChange={(value: any) => setEditForm({ ...editForm, repository_type: value })} > - + - + GITHUB GITLAB OTHER @@ -902,7 +902,7 @@ export default function Projects() { id="edit-default-branch" value={editForm.default_branch} onChange={(e) => setEditForm({ ...editForm, default_branch: e.target.value })} - className="retro-input" + className="terminal-input" />
@@ -915,7 +915,7 @@ export default function Projects() {
handleToggleLanguage(lang)} @@ -938,10 +938,10 @@ export default function Projects() {
- -
@@ -950,7 +950,7 @@ export default function Projects() { {/* Delete Dialog */} - + @@ -962,7 +962,7 @@ export default function Projects() {
-
+

系统通知:

  • > 项目移至回收站
  • @@ -974,10 +974,10 @@ export default function Projects() {
- 取消 + 取消 确认删除 diff --git a/frontend/src/pages/RecycleBin.tsx b/frontend/src/pages/RecycleBin.tsx index c3c0536..b35e568 100644 --- a/frontend/src/pages/RecycleBin.tsx +++ b/frontend/src/pages/RecycleBin.tsx @@ -113,19 +113,22 @@ export default function RecycleBin() { if (loading) { return ( -
+
-
-

加载中...

+
+

加载中...

); } return ( -
+
+ {/* Decorative Background */} +
+ {/* 页面标题 */} -
+

diff --git a/frontend/src/pages/Register.tsx b/frontend/src/pages/Register.tsx index fc7d75f..612e9ab 100644 --- a/frontend/src/pages/Register.tsx +++ b/frontend/src/pages/Register.tsx @@ -33,7 +33,7 @@ export default function Register() { }; return ( -
+
注册账号 diff --git a/frontend/src/pages/TaskDetail.tsx b/frontend/src/pages/TaskDetail.tsx index 121fed4..94c825a 100644 --- a/frontend/src/pages/TaskDetail.tsx +++ b/frontend/src/pages/TaskDetail.tsx @@ -414,7 +414,7 @@ export default function TaskDetail() { if (loading) { return ( -
+
); diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index a0dbdda..42ebfdd 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -18,11 +18,22 @@ export default { }, }, extend: { + // Typography - Pixel-perfect monospace for terminal aesthetic fontFamily: { - mono: ['"Space Mono"', '"Courier New"', 'monospace'], + mono: ['"JetBrains Mono"', '"Roboto Mono"', '"Courier New"', 'monospace'], sans: ['"Inter"', 'system-ui', 'sans-serif'], - display: ['"Orbitron"', 'sans-serif'], + display: ['"Orbitron"', '"Rajdhani"', 'sans-serif'], }, + fontSize: { + 'xs': ['0.75rem', { lineHeight: '1rem', letterSpacing: '0.01em' }], + 'sm': ['0.875rem', { lineHeight: '1.25rem', letterSpacing: '0.01em' }], + 'base': ['1rem', { lineHeight: '1.5rem', letterSpacing: '0' }], + 'lg': ['1.125rem', { lineHeight: '1.75rem', letterSpacing: '-0.01em' }], + 'xl': ['1.25rem', { lineHeight: '1.75rem', letterSpacing: '-0.01em' }], + '2xl': ['1.5rem', { lineHeight: '2rem', letterSpacing: '-0.02em' }], + '3xl': ['1.875rem', { lineHeight: '2.25rem', letterSpacing: '-0.02em' }], + }, + // Extended Color System colors: { border: 'hsl(var(--border))', input: 'hsl(var(--input))', @@ -37,6 +48,10 @@ export default { DEFAULT: 'hsl(var(--secondary))', foreground: 'hsl(var(--secondary-foreground))', }, + success: { + DEFAULT: 'hsl(var(--success))', + foreground: 'hsl(var(--success-foreground))', + }, destructive: { DEFAULT: 'hsl(var(--destructive))', foreground: 'hsl(var(--destructive-foreground))', @@ -57,27 +72,50 @@ export default { DEFAULT: 'hsl(var(--card))', foreground: 'hsl(var(--card-foreground))', }, - // Cassette Futurism Palette - retro: { - orange: '#FF3D00', - teal: '#00E5FF', - pink: '#FF00FF', - yellow: '#FFEA00', - dark: '#1A1A1A', - light: '#F5F7FA', + // Core Palette - Direct color access + terminal: { + orange: '#FF6B2C', // Vibrant Orange + 'orange-dark': '#E55A1F', + red: '#D32F2F', // Deep Red + 'red-dark': '#B71C1C', + green: '#00E676', // Signal Green + 'green-dark': '#00C853', + grey: { + 50: '#F5F5F5', + 100: '#E0E0E0', + 200: '#BDBDBD', + 300: '#9E9E9E', + 400: '#757575', + 500: '#616161', + 600: '#424242', + 700: '#303030', + 800: '#212121', + 900: '#1A1A1A', + } } }, + // Simplified Border Radius borderRadius: { lg: 'var(--radius)', - md: 'calc(var(--radius) - 2px)', - sm: 'calc(var(--radius) - 4px)', + md: 'var(--radius)', + sm: 'var(--radius)', none: '0', }, + // Refined Shadows - Subtle and clean boxShadow: { - 'retro': '4px 4px 0px 0px rgba(0,0,0,1)', - 'retro-hover': '2px 2px 0px 0px rgba(0,0,0,1)', - 'neon': '0 0 5px theme("colors.primary.DEFAULT"), 0 0 20px theme("colors.primary.DEFAULT")', + 'sm': 'var(--shadow-sm)', + 'md': 'var(--shadow-md)', + 'lg': '0 4px 6px rgba(0, 0, 0, 0.12)', + 'focus': 'var(--shadow-focus)', + // Minimal retro effect for special cases + 'terminal': '1px 1px 0px rgba(0, 0, 0, 0.15)', + 'terminal-md': '2px 2px 0px rgba(0, 0, 0, 0.15)', + // Glow effects for status indicators + 'glow-orange': '0 0 8px rgba(255, 107, 44, 0.4)', + 'glow-red': '0 0 8px rgba(211, 47, 47, 0.4)', + 'glow-green': '0 0 8px rgba(0, 230, 118, 0.4)', }, + // Refined Animations keyframes: { 'accordion-down': { from: { height: '0' }, @@ -87,28 +125,45 @@ export default { from: { height: 'var(--radix-accordion-content-height)' }, to: { height: '0' }, }, - 'glitch': { - '0%, 100%': { transform: 'translate(0)' }, - '20%': { transform: 'translate(-2px, 2px)' }, - '40%': { transform: 'translate(-2px, -2px)' }, - '60%': { transform: 'translate(2px, 2px)' }, - '80%': { transform: 'translate(2px, -2px)' }, + // Subtle fade in + 'fade-in': { + '0%': { opacity: '0' }, + '100%': { opacity: '1' }, }, + // Slide in from bottom + 'slide-up': { + '0%': { transform: 'translateY(10px)', opacity: '0' }, + '100%': { transform: 'translateY(0)', opacity: '1' }, + }, + // Subtle pulse for status indicators + 'pulse-glow': { + '0%, 100%': { opacity: '1' }, + '50%': { opacity: '0.7' }, + }, + // Terminal cursor blink + 'blink': { + '0%, 100%': { opacity: '1' }, + '50%': { opacity: '0' }, + }, + // Simplified scanline 'scanline': { '0%': { transform: 'translateY(-100%)' }, '100%': { transform: 'translateY(100%)' }, }, - 'pulse-slow': { - '0%, 100%': { opacity: '1' }, - '50%': { opacity: '0.5' }, - } }, animation: { 'accordion-down': 'accordion-down 0.2s ease-out', 'accordion-up': 'accordion-up 0.2s ease-out', - 'glitch': 'glitch 0.3s cubic-bezier(.25, .46, .45, .94) both infinite', + 'fade-in': 'fade-in 0.15s ease-out', + 'slide-up': 'slide-up 0.2s ease-out', + 'pulse-glow': 'pulse-glow 2s ease-in-out infinite', + 'blink': 'blink 1s step-end infinite', 'scanline': 'scanline 8s linear infinite', - 'pulse-slow': 'pulse-slow 3s ease-in-out infinite', + }, + // Spacing adjustments for pixel-perfect layouts + spacing: { + '18': '4.5rem', + '88': '22rem', }, }, },