refactor(shadow): introduce shadow-card utility and extend tailwind-merge

This commit is contained in:
zetaloop
2026-02-25 19:31:39 +08:00
parent feef03670a
commit c55d533925
26 changed files with 63 additions and 52 deletions
+6 -6
View File
@@ -23,7 +23,7 @@ export default function DashboardPage() {
<h1 className="text-2xl font-bold"></h1>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<ListOrdered className="h-4 w-4 text-muted-foreground" />
@@ -34,7 +34,7 @@ export default function DashboardPage() {
</div>
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Star className="h-4 w-4 text-muted-foreground" />
@@ -43,7 +43,7 @@ export default function DashboardPage() {
<div className="text-2xl font-bold">{isOwner ? shop.rating : player.rating}</div>
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium">{isOwner ? "签约打手" : "完成率"}</CardTitle>
{isOwner ? (
@@ -65,7 +65,7 @@ export default function DashboardPage() {
)}
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium">{isOwner ? "本月收入" : "服务数"}</CardTitle>
{isOwner ? (
@@ -82,7 +82,7 @@ export default function DashboardPage() {
</Card>
</div>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle className="text-base"></CardTitle>
<Button variant="ghost" size="sm" asChild>
@@ -114,7 +114,7 @@ export default function DashboardPage() {
</Card>
{!isOwner && (
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -145,7 +145,7 @@ export default function NewServicePage() {
</Link>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle></CardTitle>
</CardHeader>
+1 -1
View File
@@ -54,7 +54,7 @@ export default function ServicesPage() {
</Button>
</div>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -83,7 +83,7 @@ export default function EmployeesPage() {
</Button>
</div>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<div className="flex items-center justify-between">
<CardTitle className="text-base"> ({shopPlayers.length})</CardTitle>
@@ -58,7 +58,7 @@ export default function ShopIncomePage() {
<h1 className="text-2xl font-bold"></h1>
<div className="grid gap-4 sm:grid-cols-3">
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<DollarSign className="h-4 w-4 text-muted-foreground" />
@@ -67,7 +67,7 @@ export default function ShopIncomePage() {
<div className="text-2xl font-bold">¥{totalIncome.toFixed(2)}</div>
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<CreditCard className="h-4 w-4 text-muted-foreground" />
@@ -76,7 +76,7 @@ export default function ShopIncomePage() {
<div className="text-2xl font-bold">¥{thisMonthIncome.toFixed(2)}</div>
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<ArrowUpRight className="h-4 w-4 text-muted-foreground" />
@@ -87,7 +87,7 @@ export default function ShopIncomePage() {
</Card>
</div>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle></CardTitle>
</CardHeader>
@@ -44,7 +44,7 @@ export default function ShopOrdersPage() {
</div>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<ListOrdered className="h-4 w-4 text-muted-foreground" />
@@ -53,7 +53,7 @@ export default function ShopOrdersPage() {
<div className="text-2xl font-bold">{totalOrders}</div>
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Clock className="h-4 w-4 text-muted-foreground" />
@@ -62,7 +62,7 @@ export default function ShopOrdersPage() {
<div className="text-2xl font-bold">{activeOrders}</div>
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<CheckCircle className="h-4 w-4 text-muted-foreground" />
@@ -71,7 +71,7 @@ export default function ShopOrdersPage() {
<div className="text-2xl font-bold">{completedOrders}</div>
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<AlertCircle className="h-4 w-4 text-muted-foreground" />
@@ -82,7 +82,7 @@ export default function ShopOrdersPage() {
</Card>
</div>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle></CardTitle>
</CardHeader>
+7 -7
View File
@@ -65,7 +65,7 @@ function ShopManagementContent({
</div>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<ListOrdered className="h-4 w-4 text-muted-foreground" />
@@ -74,7 +74,7 @@ function ShopManagementContent({
<div className="text-2xl font-bold">{shop.totalOrders}</div>
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Star className="h-4 w-4 text-muted-foreground" />
@@ -83,7 +83,7 @@ function ShopManagementContent({
<div className="text-2xl font-bold">{shop.rating}</div>
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Users className="h-4 w-4 text-muted-foreground" />
@@ -92,7 +92,7 @@ function ShopManagementContent({
<div className="text-2xl font-bold">{shop.playerCount}</div>
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<DollarSign className="h-4 w-4 text-muted-foreground" />
@@ -107,7 +107,7 @@ function ShopManagementContent({
</Card>
</div>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -139,7 +139,7 @@ function ShopManagementContent({
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -184,7 +184,7 @@ function ShopManagementContent({
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -66,7 +66,7 @@ function ShopRulesForm({
</div>
<div className="grid gap-6">
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -100,7 +100,7 @@ function ShopRulesForm({
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -126,7 +126,7 @@ function ShopRulesForm({
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -141,7 +141,7 @@ function ShopTemplatesEditor({
</div>
</div>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -184,7 +184,7 @@ function ShopTemplatesEditor({
</CardContent>
</Card>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
+1 -1
View File
@@ -5,7 +5,7 @@ export default function HelpPage() {
return (
<div className="container mx-auto max-w-3xl px-4 py-8 space-y-6">
<h1 className="text-2xl font-bold tracking-tighter leading-tight"></h1>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
+1 -1
View File
@@ -37,7 +37,7 @@ export default function HomePage() {
type="text"
name="q"
placeholder="搜索陪玩、店铺、游戏..."
className="w-full border-border bg-card shadow-[0_4px_16px_-2px_rgba(0,0,0,0.08),0_8px_24px_-4px_rgba(0,0,0,0.1)] transition-shadow focus:shadow-[0_8px_30px_-4px_rgba(0,0,0,0.12),0_12px_40px_-8px_rgba(0,0,0,0.14)]"
className="w-full border-border bg-card shadow-card transition-shadow focus:shadow-card-hover"
/>
</form>
</div>
+1 -1
View File
@@ -34,7 +34,7 @@ export default async function PlayerDetailPage({ params }: { params: Promise<{ i
<div className="container mx-auto py-8 px-4 max-w-5xl">
<div className="flex flex-col md:flex-row gap-8 mb-8">
<div className="flex-shrink-0">
<Avatar className="w-32 h-32 border-4 border-background shadow-[var(--shadow-card)]">
<Avatar className="w-32 h-32 border-4 border-background shadow-card">
<AvatarImage src={player.user.avatar} alt={player.user.nickname} />
<AvatarFallback>{player.user.nickname[0]}</AvatarFallback>
</Avatar>
+1 -1
View File
@@ -30,7 +30,7 @@ export default async function PostDetailPage({ params }: { params: Promise<{ id:
</Link>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader className="pb-3">
<div className="flex items-center gap-3">
<Avatar className="h-10 w-10">
+1 -1
View File
@@ -101,7 +101,7 @@ export default function NewPostPage() {
</Link>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="tracking-tighter leading-tight"></CardTitle>
</CardHeader>
+1 -1
View File
@@ -4,7 +4,7 @@ export default function PrivacyPage() {
return (
<div className="container mx-auto max-w-3xl px-4 py-8 space-y-6">
<h1 className="text-2xl font-bold tracking-tighter leading-tight"></h1>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base">使</CardTitle>
</CardHeader>
+1 -1
View File
@@ -567,7 +567,7 @@ function SearchPageContent() {
icon={<Search />}
type="search"
placeholder="搜索陪玩、游戏、标签..."
className="border-border bg-card shadow-[var(--shadow-card)] transition-shadow focus:shadow-[var(--shadow-card-hover)]"
className="border-border bg-card shadow-card transition-shadow focus:shadow-card-hover"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
+1 -1
View File
@@ -5,7 +5,7 @@ export default function TermsPage() {
return (
<div className="container mx-auto max-w-3xl px-4 py-8 space-y-6">
<h1 className="text-2xl font-bold tracking-tighter leading-tight"></h1>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
+1 -1
View File
@@ -35,7 +35,7 @@ export default async function UserProfilePage({ params }: { params: Promise<{ id
return (
<div className="container mx-auto max-w-4xl px-4 py-8 space-y-6">
<div className="flex items-center gap-6 mb-8">
<Avatar className="w-24 h-24 border-4 border-background shadow-[var(--shadow-card)]">
<Avatar className="w-24 h-24 border-4 border-background shadow-card">
<AvatarImage src={user.avatar} alt={user.nickname} />
<AvatarFallback>{user.nickname[0]}</AvatarFallback>
</Avatar>
+1 -1
View File
@@ -62,7 +62,7 @@ export default function ChatDetailPage({ params }: { params: Promise<{ id: strin
return (
<div className="container mx-auto max-w-3xl px-4 py-8 h-[calc(100vh-3.5rem)] flex flex-col">
<Card className="flex-1 flex flex-col overflow-hidden hover:shadow-[var(--shadow-card)]">
<Card className="flex-1 flex flex-col overflow-hidden hover:shadow-card-hover">
<div className="border-b px-4 py-3 flex items-center gap-3 bg-muted/30">
<Link href="/chat" className="text-muted-foreground hover:text-foreground">
<ArrowLeft className="h-5 w-5" />
+1 -1
View File
@@ -58,7 +58,7 @@ export default function ChatListPage() {
})}
{sessions.length === 0 && (
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardContent className="py-8 text-center text-sm text-muted-foreground">
<MessageSquare className="h-12 w-12 mx-auto mb-2 opacity-50" />
+2 -2
View File
@@ -159,7 +159,7 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
</Link>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<div className="flex items-center justify-between">
<CardTitle></CardTitle>
@@ -393,7 +393,7 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
</Link>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<AlertTriangle className="h-5 w-5 text-yellow-500" />
+2 -2
View File
@@ -126,14 +126,14 @@ function OrderListContent({
<TabsContent value={tab} className="mt-4 space-y-4">
{filtered.length === 0 ? (
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardContent className="py-8 text-center text-sm text-muted-foreground">
</CardContent>
</Card>
) : (
filtered.map((order) => (
<Card key={order.id} className="hover:shadow-[var(--shadow-card)]">
<Card key={order.id} className="hover:shadow-card-hover">
<CardHeader className="pb-3">
<div className="flex items-center justify-between">
<CardTitle className="text-base">{order.service.title}</CardTitle>
+1 -1
View File
@@ -86,7 +86,7 @@ export default function ReviewPage({ params }: { params: Promise<{ id: string }>
</Link>
<Card className="hover:shadow-[var(--shadow-card)]">
<Card className="hover:shadow-card-hover">
<CardHeader>
<CardTitle></CardTitle>
<p className="text-sm text-muted-foreground">
+7 -4
View File
@@ -46,6 +46,8 @@
--radius-2xl: calc(var(--radius) + 8px);
--radius-3xl: calc(var(--radius) + 12px);
--radius-4xl: calc(var(--radius) + 16px);
--shadow-card: var(--card-shadow);
--shadow-card-hover: var(--card-shadow-hover);
}
:root {
@@ -82,8 +84,9 @@
--sidebar-accent-foreground: oklch(0.36 0.1 46.65);
--sidebar-border: oklch(0.94 0 0);
--sidebar-ring: oklch(0.701 0.189 46.65);
--shadow-card: 0 1px 2px 0 rgba(0, 0, 0, 0.03), 0 2px 8px -1px rgba(0, 0, 0, 0.04);
--shadow-card-hover: 0 2px 8px -2px rgba(0, 0, 0, 0.06), 0 6px 20px -4px rgba(0, 0, 0, 0.08);
--card-shadow: 0 1px 3px 0 rgba(30, 40, 55, 0.04), 0 4px 12px -2px rgba(30, 40, 55, 0.06);
--card-shadow-hover:
0 4px 16px -2px rgba(30, 40, 55, 0.07), 0 8px 24px -4px rgba(30, 40, 55, 0.09);
}
.dark {
@@ -119,8 +122,8 @@
--sidebar-accent-foreground: oklch(0.98 0.01 46.65);
--sidebar-border: oklch(0.23 0 0);
--sidebar-ring: oklch(0.701 0.189 46.65);
--shadow-card: 0 1px 2px 0 rgba(255, 255, 255, 0.02), 0 2px 8px -1px rgba(0, 0, 0, 0.15);
--shadow-card-hover: 0 2px 8px -2px rgba(0, 0, 0, 0.12), 0 6px 20px -4px rgba(0, 0, 0, 0.18);
--card-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.08), 0 4px 12px -2px rgba(0, 0, 0, 0.12);
--card-shadow-hover: 0 4px 16px -2px rgba(0, 0, 0, 0.14), 0 8px 24px -4px rgba(0, 0, 0, 0.18);
}
@layer base {