style: overhaul design to authentic Google Gemini Material 3 Dark theme
MindSift CI & Docker Release / Lint, Build & Unit Tests (push) Successful in 2m8s
MindSift CI & Docker Release / Build & Push Docker Image (push) Successful in 1m45s

This commit is contained in:
sandrodach committed 2026-10-24 18:32:03 +02:00
1 parent 10323867e9
commit 31aa43c460
11 files changed
+413 -444

No files matched your search

@@ -1,5 +1,5 @@
import React, { useEffect, useRef, useState } from 'react';
import { Mic, MicOff, Send, Sparkles, Calendar, AlertTriangle, CheckCircle2 } from 'lucide-react';
import { Mic, MicOff, ArrowUp, Sparkles, Calendar, Check } from 'lucide-react';
import { PriorityLevel, Thought } from '../../lib/types';
import { api, triggerHaptic } from '../../lib/api';
@@ -122,7 +122,7 @@ export const InstantCaptureBar: React.FC<InstantCaptureBarProps> = ({
setDueDate('');
setShowOptions(false);
setJustSaved(true);
setTimeout(() => setJustSaved(false), 1800);
setTimeout(() => setJustSaved(false), 1600);
onCaptured(created);
inputRef.current?.focus();
} finally {
@@ -133,20 +133,15 @@ export const InstantCaptureBar: React.FC<InstantCaptureBarProps> = ({
return (
<div className="w-full max-w-3xl mx-auto">
<form onSubmit={handleSubmit} className="relative">
{/* Google Gemini Style Input Capsule */}
<div
className={`flex items-center h-14 px-4 sm:px-5 rounded-full bg-[#1e1f20] gemini-border gemini-input-glow transition-all duration-200 ${
isListening ? 'border-[#c58af9] shadow-purple-glow' : ''
className={`flex items-center h-14 px-4 sm:px-5 rounded-full bg-[#1e1f20] border transition-colors duration-150 ${
isListening
? 'border-[#a8c7fa] bg-[#1e1f20]'
: 'border-[#3c4043] focus-within:border-[#a8c7fa]'
}`}
>
<Sparkles
className={`w-5 h-5 mr-3 flex-shrink-0 transition-colors ${
isListening
? 'text-[#c58af9] animate-pulse'
: justSaved
? 'text-[#81c995]'
: 'text-[#8ab4f8]'
}`}
/>
<Sparkles className="w-4 h-4 mr-3 flex-shrink-0 text-[#a8c7fa]" />
<input
ref={inputRef}
@@ -155,10 +150,10 @@ export const InstantCaptureBar: React.FC<InstantCaptureBarProps> = ({
onChange={(e) => setContent(e.target.value)}
placeholder={
isListening
? 'Ich höre zu… sprich deinen Gedanken aus'
? 'Ich höre zu…'
: 'Gedanke, Idee oder Zutat sofort festhalten… (Taste C oder /)'
}
className="w-full bg-transparent text-[#e3e3e3] placeholder-[#9aa0a6] text-sm sm:text-base focus:outline-none"
className="w-full bg-transparent text-[#e3e3e3] placeholder-[#8e918f] text-sm sm:text-base focus:outline-none"
autoComplete="off"
/>
@@ -167,11 +162,11 @@ export const InstantCaptureBar: React.FC<InstantCaptureBarProps> = ({
<button
type="button"
onClick={() => setShowOptions((prev) => !prev)}
title="Priorität & Fälligkeitsdatum"
className={`h-9 px-3 rounded-full text-xs font-medium flex items-center gap-1.5 transition-colors ${
title="Priorität & Fälligkeit"
className={`h-8 px-2.5 rounded-full text-xs flex items-center gap-1.5 transition-colors ${
showOptions || priority !== 'normal' || dueDate
? 'bg-[#8ab4f8]/20 text-[#8ab4f8] border border-[#8ab4f8]/40'
: 'text-[#9aa0a6] hover:bg-[#282a2c] hover:text-[#e3e3e3]'
? 'bg-[#282a2c] text-[#a8c7fa] border border-[#a8c7fa]/30'
: 'text-[#8e918f] hover:text-[#e3e3e3] hover:bg-[#282a2c]'
}`}
>
<Calendar className="w-3.5 h-3.5" />
@@ -180,39 +175,39 @@ export const InstantCaptureBar: React.FC<InstantCaptureBarProps> = ({
</span>
</button>
{/* Voice Dictation Pill Button */}
{/* Voice Dictation Button */}
<button
type="button"
onClick={toggleVoiceDictation}
title="Spracheingabe (Diktieren)"
className={`w-9 h-9 rounded-full flex items-center justify-center transition-all ${
title="Spracheingabe"
className={`w-8 h-8 rounded-full flex items-center justify-center transition-colors ${
isListening
? 'bg-[#c58af9] text-[#0b0f19] animate-pulse'
: 'bg-[#282a2c] text-[#9aa0a6] hover:text-[#e3e3e3] hover:bg-[#323538]'
? 'bg-[#004a77]/50 text-[#a8c7fa]'
: 'text-[#8e918f] hover:text-[#e3e3e3] hover:bg-[#282a2c]'
}`}
>
{isListening ? <MicOff className="w-4 h-4" /> : <Mic className="w-4 h-4" />}
</button>
{/* Instant Send Pill Button */}
{/* Instant Send Button */}
<button
type="submit"
disabled={!content.trim() || isSubmitting}
className={`h-9 px-4 rounded-full font-medium text-xs sm:text-sm flex items-center gap-1.5 transition-all ${
className={`h-8 px-3.5 rounded-full font-medium text-xs flex items-center gap-1.5 transition-colors ${
content.trim()
? 'bg-[#8ab4f8] text-[#0b0f19] hover:bg-[#a1c2fa] shadow-sm cursor-pointer'
: 'bg-[#282a2c] text-[#5f6368] cursor-not-allowed'
? 'bg-[#a8c7fa] text-[#041e49] hover:bg-[#b8d4ff] cursor-pointer'
: 'bg-[#282a2c] text-[#8e918f] cursor-not-allowed'
}`}
>
{justSaved ? (
<>
<CheckCircle2 className="w-4 h-4 text-[#0b0f19]" />
<Check className="w-3.5 h-3.5" />
<span className="hidden sm:inline">Gespeichert</span>
</>
) : (
<>
<Send className="w-3.5 h-3.5" />
<span className="hidden sm:inline">Einfrieren</span>
<ArrowUp className="w-3.5 h-3.5" />
<span className="hidden sm:inline">Sichern</span>
</>
)}
</button>
@@ -221,10 +216,9 @@ export const InstantCaptureBar: React.FC<InstantCaptureBarProps> = ({
{/* Expandable Quick Metadata Pills */}
{showOptions && (
<div className="mt-2.5 px-4 py-2.5 rounded-full bg-[#131314] gemini-border flex flex-wrap items-center justify-between gap-2 text-xs animate-fadeIn">
<div className="mt-2 px-4 py-2.5 rounded-2xl bg-[#1e1f20] border border-[#3c4043] flex flex-wrap items-center justify-between gap-2 text-xs">
<div className="flex items-center gap-1.5">
<AlertTriangle className="w-3.5 h-3.5 text-[#9aa0a6] mr-1" />
<span className="text-[#9aa0a6] mr-1">Priorität:</span>
<span className="text-[#8e918f] mr-1">Priorität:</span>
{(['low', 'normal', 'high', 'urgent'] as PriorityLevel[]).map((p) => {
const labels: Record<PriorityLevel, string> = {
low: 'Niedrig',
@@ -241,9 +235,9 @@ export const InstantCaptureBar: React.FC<InstantCaptureBarProps> = ({
className={`px-3 py-1 rounded-full transition-colors ${
active
? p === 'urgent'
? 'bg-[#f28b82] text-[#0b0f19] font-semibold'
: 'bg-[#8ab4f8] text-[#0b0f19] font-semibold'
: 'bg-[#1e1f20] text-[#9aa0a6] hover:text-[#e3e3e3]'
? 'bg-[#f28b82]/20 text-[#f28b82] border border-[#f28b82]/40 font-medium'
: 'bg-[#282a2c] text-[#a8c7fa] border border-[#a8c7fa]/30 font-medium'
: 'bg-[#131314] text-[#8e918f] hover:text-[#e3e3e3]'
}`}
>
{labels[p]}
@@ -253,12 +247,12 @@ export const InstantCaptureBar: React.FC<InstantCaptureBarProps> = ({
</div>
<div className="flex items-center gap-2">
<span className="text-[#9aa0a6]">Fällig am:</span>
<span className="text-[#8e918f]">Fällig am:</span>
<input
type="date"
value={dueDate}
onChange={(e) => setDueDate(e.target.value)}
className="bg-[#1e1f20] text-[#e3e3e3] px-3 py-1 rounded-full gemini-border text-xs focus:outline-none focus:border-[#8ab4f8]"
className="bg-[#131314] text-[#e3e3e3] px-3 py-1 rounded-full border border-[#3c4043] text-xs focus:outline-none focus:border-[#a8c7fa]"
/>
</div>
</div>