This commit is contained in:
parent
34dc5b0f87
commit
40f7d0bb92
|
|
@ -184,6 +184,25 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Heartbeat animation for buttons */
|
||||||
|
@keyframes heartbeat {
|
||||||
|
0%, 100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
10% {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
30% {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Animation utility classes */
|
/* Animation utility classes */
|
||||||
.animate-fade-in {
|
.animate-fade-in {
|
||||||
animation: fadeIn 0.6s ease-out;
|
animation: fadeIn 0.6s ease-out;
|
||||||
|
|
@ -205,6 +224,11 @@
|
||||||
animation: scaleUp 0.5s ease-out;
|
animation: scaleUp 0.5s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Heartbeat animation for call-to-action buttons */
|
||||||
|
.animate-heartbeat {
|
||||||
|
animation: heartbeat 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
/* Stagger delays for sequential animations */
|
/* Stagger delays for sequential animations */
|
||||||
.animate-delay-100 {
|
.animate-delay-100 {
|
||||||
animation-delay: 0.1s;
|
animation-delay: 0.1s;
|
||||||
|
|
@ -257,21 +281,21 @@
|
||||||
GRADIENT UTILITIES
|
GRADIENT UTILITIES
|
||||||
======================================== */
|
======================================== */
|
||||||
|
|
||||||
/* Gradient Backgrounds - Purple/Pink theme */
|
/* Gradient Backgrounds - Blue/Pink in light, Blue/Purple in dark */
|
||||||
.gradient-bg-primary {
|
.gradient-bg-primary {
|
||||||
background: linear-gradient(135deg, #9333EA 0%, #EC4899 100%);
|
background: linear-gradient(135deg, #3B82F6 0%, #EC4899 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .gradient-bg-primary {
|
.dark .gradient-bg-primary {
|
||||||
background: linear-gradient(135deg, #7C3AED 0%, #DB2777 100%);
|
background: linear-gradient(135deg, #3B82F6 0%, #8B5CF6 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.gradient-bg-secondary {
|
.gradient-bg-secondary {
|
||||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
background: linear-gradient(135deg, #60A5FA 0%, #F472B6 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .gradient-bg-secondary {
|
.dark .gradient-bg-secondary {
|
||||||
background: linear-gradient(135deg, #c471ed 0%, #c94b4b 100%);
|
background: linear-gradient(135deg, #60A5FA 0%, #A78BFA 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.gradient-bg-accent {
|
.gradient-bg-accent {
|
||||||
|
|
@ -410,16 +434,30 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gradient Text - Purple/Pink theme */
|
/* Gradient Text - Blue/Pink in light, Blue/Purple in dark */
|
||||||
.gradient-text-primary {
|
.gradient-text-primary {
|
||||||
background: linear-gradient(135deg, #9333EA 0%, #EC4899 100%);
|
background: linear-gradient(135deg, #3B82F6 0%, #EC4899 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .gradient-text-primary {
|
||||||
|
background: linear-gradient(135deg, #3B82F6 0%, #8B5CF6 100%);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gradient-text-secondary {
|
.gradient-text-secondary {
|
||||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
background: linear-gradient(135deg, #60A5FA 0%, #F472B6 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .gradient-text-secondary {
|
||||||
|
background: linear-gradient(135deg, #60A5FA 0%, #A78BFA 100%);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export default function HomePage() {
|
||||||
<Link href="/analysis">
|
<Link href="/analysis">
|
||||||
<Button
|
<Button
|
||||||
size="lg"
|
size="lg"
|
||||||
className="bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 shadow-lg hover:shadow-xl transition-shadow"
|
className="bg-gradient-to-r from-blue-500 to-pink-500 dark:from-blue-600 dark:to-purple-600 hover:from-blue-600 hover:to-pink-600 dark:hover:from-blue-700 dark:hover:to-purple-700 shadow-lg hover:shadow-xl transition-all animate-heartbeat"
|
||||||
>
|
>
|
||||||
開始分析
|
開始分析
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -335,7 +335,7 @@ export default function HomePage() {
|
||||||
<Link href="/analysis">
|
<Link href="/analysis">
|
||||||
<Button
|
<Button
|
||||||
size="lg"
|
size="lg"
|
||||||
className="bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 text-lg px-8 py-6 shadow-lg hover:shadow-2xl transition-all"
|
className="bg-gradient-to-r from-blue-500 to-pink-500 dark:from-blue-600 dark:to-purple-600 hover:from-blue-600 hover:to-pink-600 dark:hover:from-blue-700 dark:hover:to-purple-700 text-lg px-8 py-6 shadow-lg hover:shadow-2xl transition-all animate-heartbeat"
|
||||||
>
|
>
|
||||||
開始分析 →
|
開始分析 →
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -491,7 +491,7 @@ function WorkflowStep({
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="flex gap-4 items-start">
|
<div className="flex gap-4 items-start">
|
||||||
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-gradient-to-r from-blue-600 to-purple-600 text-white flex items-center justify-center font-bold">
|
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-gradient-to-r from-blue-500 to-pink-500 dark:from-blue-600 dark:to-purple-600 text-white flex items-center justify-center font-bold">
|
||||||
{number}
|
{number}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -151,47 +151,36 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="analysts"
|
name="analysts"
|
||||||
render={() => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
{ANALYSTS.map((analyst) => (
|
{ANALYSTS.map((analyst) => (
|
||||||
<FormField
|
<FormItem
|
||||||
key={analyst.value}
|
key={analyst.value}
|
||||||
control={form.control}
|
className="flex flex-row items-start space-x-3 space-y-0"
|
||||||
name="analysts"
|
>
|
||||||
render={({ field }) => {
|
<FormControl>
|
||||||
return (
|
<Checkbox
|
||||||
<FormItem
|
checked={field.value?.includes(analyst.value)}
|
||||||
key={analyst.value}
|
onCheckedChange={(checked) => {
|
||||||
className="flex flex-row items-start space-x-3 space-y-0"
|
return checked
|
||||||
>
|
? field.onChange([
|
||||||
<FormControl>
|
...(field.value ?? []),
|
||||||
<Checkbox
|
analyst.value,
|
||||||
checked={field.value?.includes(
|
])
|
||||||
analyst.value
|
: field.onChange(
|
||||||
)}
|
field.value?.filter(
|
||||||
onCheckedChange={(checked) => {
|
(value: string) =>
|
||||||
return checked
|
value !== analyst.value
|
||||||
? field.onChange([
|
)
|
||||||
...(field.value ?? []),
|
);
|
||||||
analyst.value,
|
}}
|
||||||
])
|
/>
|
||||||
: field.onChange(
|
</FormControl>
|
||||||
field.value?.filter(
|
<FormLabel className="font-normal cursor-pointer">
|
||||||
(value: string) =>
|
{analyst.label}
|
||||||
value !== analyst.value
|
</FormLabel>
|
||||||
)
|
</FormItem>
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormLabel className="font-normal cursor-pointer">
|
|
||||||
{analyst.label}
|
|
||||||
</FormLabel>
|
|
||||||
</FormItem>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
|
@ -798,7 +787,7 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="w-full bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 shadow-lg hover:shadow-xl transition-all"
|
className="w-full bg-gradient-to-r from-blue-500 to-pink-500 dark:from-blue-600 dark:to-purple-600 hover:from-blue-600 hover:to-pink-600 dark:hover:from-blue-700 dark:hover:to-purple-700 shadow-lg hover:shadow-xl transition-all animate-heartbeat"
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
size="lg"
|
size="lg"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { ThemeToggle } from "@/components/theme/ThemeToggle";
|
||||||
|
|
||||||
export function Header() {
|
export function Header() {
|
||||||
return (
|
return (
|
||||||
<header className="border-b bg-gradient-to-r from-blue-600 to-purple-600 text-white">
|
<header className="border-b bg-gradient-to-r from-blue-500 to-pink-500 dark:from-blue-600 dark:to-purple-600 text-white">
|
||||||
<div className="container mx-auto px-4 py-6">
|
<div className="container mx-auto px-4 py-6">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<Link href="/" className="flex items-center gap-2">
|
<Link href="/" className="flex items-center gap-2">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue