From 134c3e8539bc0b84169e9485ea954a48f5633ee4 Mon Sep 17 00:00:00 2001 From: YannAhlgrim Date: Thu, 9 Oct 2025 10:12:45 +0200 Subject: [PATCH] frontend mvp --- frontend/pages/index.js | 80 +++++-------- frontend/styles/globals.css | 231 ++++++++++++++++++++++++++++++++++-- 2 files changed, 247 insertions(+), 64 deletions(-) diff --git a/frontend/pages/index.js b/frontend/pages/index.js index 14b3f00..93fc66b 100644 --- a/frontend/pages/index.js +++ b/frontend/pages/index.js @@ -41,16 +41,16 @@ export default function Home() { return (
- {/* Header */} -
+
-

+

🎤 Voice Assistant

+
{/* Main Interface */} -
+
{/* Recording Section */}
@@ -70,23 +70,21 @@ export default function Home() { onTouchStart={handleStartRecording} onTouchEnd={handleStopRecording} disabled={isProcessing} - className={`record-button w-40 h-40 rounded-full border-none text-white text-lg font-semibold + className={`record-button w-60 h-60 rounded-full border-none text-white text-lg font-semibold cursor-pointer ${recording - ? 'bg-gradient-to-r from-red-500 to-red-600 recording-pulse shadow-red-500/50' + ? 'record-button--recording' : isProcessing - ? 'bg-gradient-to-r from-yellow-500 to-orange-500 shadow-yellow-500/50' - : 'bg-gradient-to-r from-blue-500 to-purple-600 shadow-blue-500/50' + ? 'record-button--processing' + : 'record-button--idle' } - ${isProcessing ? 'cursor-not-allowed opacity-75' : 'cursor-pointer hover:shadow-xl'} - disabled:cursor-not-allowed disabled:opacity-75 `} >
-
+
{recording ? '🎙️' : isProcessing ? '⏳' : '🎤'}
-
- {recording ? 'Recording...' : isProcessing ? 'Processing...' : 'Hold / Click'} +
+ {recording ? 'Recording...' : isProcessing ? 'Processing...' : 'Hold to Record'}
@@ -94,30 +92,30 @@ export default function Home() { {/* Status indicators */}
-
-
- Recording +
+ Recording
-
-
- Processing +
+ Processing
{/* Audio Playback Section */} -
+

🔊 Audio Response

-

Your AI assistant's response will play here

+

Your AI assistant's response will play here

-
+
- - {/* Instructions */} -
-
-

💡 How to Use

-
-
-
1️⃣
-

Press & Hold
Hold the button down while speaking

-
-
-
2️⃣
-

Or Click Toggle
Click once to start, click again to stop

-
-
-
3️⃣
-

Listen
Your AI assistant will respond with audio

-
-
-
-
-
) } diff --git a/frontend/styles/globals.css b/frontend/styles/globals.css index c0428cd..75578c9 100644 --- a/frontend/styles/globals.css +++ b/frontend/styles/globals.css @@ -1,39 +1,246 @@ @import "tailwindcss"; +:root { + /* Primary Theme Colors */ + --color-primary: #3b82f6; /* Blue-500 */ + --color-primary-dark: #2563eb; /* Blue-600 */ + --color-primary-light: #60a5fa; /* Blue-400 */ + + --color-secondary: #8b5cf6; /* Purple-500 */ + --color-secondary-dark: #7c3aed; /* Purple-600 */ + --color-secondary-light: #a78bfa; /* Purple-400 */ + + --color-accent: #ec4899; /* Pink-500 */ + --color-accent-light: #f472b6; /* Pink-400 */ + + /* Status Colors */ + --color-success: #10b981; /* Emerald-500 */ + --color-success-light: #34d399; /* Emerald-400 */ + --color-warning: #f59e0b; /* Yellow-500 */ + --color-warning-light: #fbbf24; /* Yellow-400 */ + --color-error: #ef4444; /* Red-500 */ + --color-error-light: #f87171; /* Red-400 */ + + /* Background Colors */ + --color-bg-primary: #0f172a; /* Slate-900 */ + --color-bg-secondary: #1e293b; /* Slate-800 */ + --color-bg-tertiary: #334155; /* Slate-700 */ + --color-bg-overlay: rgba(255, 255, 255, 0.1); + --color-bg-overlay-dark: rgba(0, 0, 0, 0.2); + + /* Text Colors */ + --color-text-primary: #ffffff; + --color-text-secondary: #cbd5e1; /* Slate-300 */ + --color-text-muted: #94a3b8; /* Slate-400 */ + --color-text-inverse: #1e293b; /* Slate-800 */ + + /* Border Colors */ + --color-border-light: rgba(255, 255, 255, 0.2); + --color-border-medium: rgba(255, 255, 255, 0.3); + --color-border-dark: rgba(255, 255, 255, 0.1); + + /* Gradient Definitions */ + --gradient-primary: linear-gradient(135deg, var(--color-primary), var(--color-secondary)); + --gradient-secondary: linear-gradient(135deg, var(--color-secondary), var(--color-accent)); + --gradient-background: linear-gradient(135deg, var(--color-bg-primary) 0%, var(--color-secondary-dark) 50%, var(--color-bg-primary) 100%); + --gradient-text: linear-gradient(135deg, var(--color-primary-light), var(--color-secondary-light), var(--color-accent-light)); + + /* Shadow Definitions */ + --shadow-primary: 0 25px 50px -12px rgba(59, 130, 246, 0.25); + --shadow-secondary: 0 25px 50px -12px rgba(139, 92, 246, 0.25); + --shadow-error: 0 25px 50px -12px rgba(239, 68, 68, 0.25); + --shadow-success: 0 25px 50px -12px rgba(16, 185, 129, 0.25); + --shadow-warning: 0 25px 50px -12px rgba(245, 158, 11, 0.25); +} @layer base { body { - @apply bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900; + background: var(--gradient-background); @apply min-h-screen; + color: var(--color-text-primary); } } @layer components { + /* Recording Button Styles */ .record-button { - @apply relative overflow-hidden; - @apply transition-all duration-300 ease-in-out; - @apply transform hover:scale-105 active:scale-95; - @apply shadow-2xl; + position: relative; + overflow: hidden; + transition: all 0.3s ease-in-out; + transform-origin: center; + box-shadow: var(--shadow-primary); + } + + .record-button:hover { + transform: scale(1.05); + } + + .record-button:active { + transform: scale(0.95); } .record-button::before { content: ''; - @apply absolute inset-0 bg-gradient-to-r from-transparent via-white to-transparent; - @apply opacity-0 translate-x-[-100%]; - @apply transition-all duration-700; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); + opacity: 0; + transform: translateX(-100%); + transition: all 0.7s ease; } .record-button:hover::before { - @apply opacity-20 translate-x-[100%]; + opacity: 1; + transform: translateX(100%); } + /* Recording Button States */ + .record-button--idle { + background: var(--gradient-primary); + box-shadow: var(--shadow-primary); + } + + .record-button--recording { + background: linear-gradient(135deg, var(--color-error), var(--color-error-light)); + box-shadow: var(--shadow-error); + animation: recording-pulse 1.5s ease-in-out infinite; + } + + .record-button--processing { + background: linear-gradient(135deg, var(--color-warning), var(--color-warning-light)); + box-shadow: var(--shadow-warning); + opacity: 0.8; + cursor: not-allowed; + } + + /* Audio Visualizer Styles */ .audio-visualizer { - @apply relative overflow-hidden rounded-xl; + position: relative; + overflow: hidden; + border-radius: 0.75rem; + background: var(--color-bg-overlay); + backdrop-filter: blur(10px); + border: 1px solid var(--color-border-light); } .audio-visualizer::after { content: ''; - @apply absolute inset-0 bg-gradient-to-r from-blue-500/20 to-purple-500/20; - @apply animate-pulse; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(90deg, + rgba(59, 130, 246, 0.1), + rgba(139, 92, 246, 0.1) + ); + animation: pulse 2s ease-in-out infinite; } + + /* Status Indicators */ + .status-indicator { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + border-radius: 9999px; + transition: all 0.3s ease; + border: 1px solid var(--color-border-dark); + } + + .status-indicator--active { + background: var(--color-bg-overlay); + border-color: var(--color-border-medium); + } + + .status-indicator--recording { + background: rgba(239, 68, 68, 0.1); + color: var(--color-error-light); + border-color: var(--color-error); + } + + .status-indicator--processing { + background: rgba(245, 158, 11, 0.1); + color: var(--color-warning-light); + border-color: var(--color-warning); + } + + /* Utility Classes */ + .glass-panel { + background: var(--color-bg-overlay); + backdrop-filter: blur(16px); + border: 1px solid var(--color-border-light); + border-radius: 1rem; + } + + .gradient-text { + background: var(--gradient-text); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + } + + .pulse-dot { + width: 0.5rem; + height: 0.5rem; + border-radius: 50%; + animation: pulse 2s ease-in-out infinite; + } + + .pulse-dot--error { + background-color: var(--color-error-light); + } + + .pulse-dot--warning { + background-color: var(--color-warning-light); + } + + .pulse-dot--inactive { + background-color: var(--color-text-muted); + } + + /* Animations */ + @keyframes recording-pulse { + 0%, 100% { + box-shadow: var(--shadow-error); + } + 50% { + box-shadow: var(--shadow-error), 0 0 0 10px rgba(239, 68, 68, 0.1); + } + } + + @keyframes pulse { + 0%, 100% { + opacity: 0.5; + } + 50% { + opacity: 1; + } + } + + /* Theme Color Utility Classes */ + .bg-theme-primary { background-color: var(--color-primary); } + .bg-theme-secondary { background-color: var(--color-secondary); } + .bg-theme-accent { background-color: var(--color-accent); } + .bg-theme-success { background-color: var(--color-success); } + .bg-theme-warning { background-color: var(--color-warning); } + .bg-theme-error { background-color: var(--color-error); } + + .text-theme-primary { color: var(--color-primary); } + .text-theme-secondary { color: var(--color-secondary); } + .text-theme-accent { color: var(--color-accent); } + .text-theme-success { color: var(--color-success); } + .text-theme-warning { color: var(--color-warning); } + .text-theme-error { color: var(--color-error); } + .text-theme-muted { color: var(--color-text-muted); } + + .border-theme-light { border-color: var(--color-border-light); } + .border-theme-medium { border-color: var(--color-border-medium); } + .border-theme-primary { border-color: var(--color-primary); } + .border-theme-error { border-color: var(--color-error); } + .border-theme-warning { border-color: var(--color-warning); } + .border-theme-success { border-color: var(--color-success); } } \ No newline at end of file