From bd55cf80f266dc1b01ef90cc77338014ff568494 Mon Sep 17 00:00:00 2001 From: YESWmeshade <392950974@qq.com> Date: Tue, 9 Dec 2025 21:01:04 +0800 Subject: [PATCH 1/6] feat(theme): adjust primary color via CSS variables --- src/tailwind.css | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/tailwind.css b/src/tailwind.css index 9c0f814..e3bb3b1 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -1,3 +1,40 @@ @import "tailwindcss"; - @custom-variant dark (&:where(.dark, .dark *)); + +@theme { + --color-background: hsl(0 0% 100%); + --color-foreground: hsl(222.2 84% 4.9%); + --color-primary: hsl(221.2 83.2% 53.3%); + + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-primary: var(--primary); + + --rp-c-bg: var(--color-background); + --rp-c-text: var(--color-foreground); + --rp-c-brand: var(--color-primary); + --rp-c-brand-light: color-mix(in srgb, var(--color-primary) 80%, transparent); +} + +:root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + --primary: 221.2 83.2% 53.3%; +} + +.dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + --primary: 217.2 91.2% 59.8%; +} + +@layer base { + body { + @apply bg-background text-foreground; + } +} +@layer components { + .rspress-doc a { + @apply text-primary hover:underline; + } +} From c0f94c49de2ddf67562f3e7bccc3efbaed1dea60 Mon Sep 17 00:00:00 2001 From: YESWmeshade <392950974@qq.com> Date: Mon, 12 Jan 2026 18:45:03 +0800 Subject: [PATCH 2/6] refactor(ui): replace hardcoded styles with Tailwind CSS variables --- src/list.tsx | 8 ++-- src/prompt.tsx | 10 ++--- src/sender.tsx | 25 +++++------ src/tailwind.css | 107 +++++++++++++++++++++++++++++++++++------------ 4 files changed, 100 insertions(+), 50 deletions(-) diff --git a/src/list.tsx b/src/list.tsx index 763bb93..6b2aa2b 100644 --- a/src/list.tsx +++ b/src/list.tsx @@ -1,3 +1,5 @@ +import "./tailwind.css"; + import clsx from "clsx"; import { twMerge } from "tailwind-merge"; @@ -130,7 +132,7 @@ export const List = ({ key={key} role-slot="list-group" aria-label={String(groupContent || "")} - className={clsx("font-bold dark:text-gray-400 py-2 px-4 text-sm")} + className={clsx("font-bold text-muted-foreground py-2 px-4 text-sm")} style={listGroupStyle} > {String(groupContent || " ")} @@ -153,8 +155,8 @@ export const List = ({ key={key} role-slot="list-item" className={twMerge( - clsx("py-2 px-4 hover:bg-gray-200 text-gray-600 cursor-pointer", { - "bg-blue-500 text-white hover:bg-blue-600": isSelected, + clsx("py-2 px-4 hover:bg-accent text-foreground cursor-pointer", { + "bg-primary hover:bg-primary/90 text-primary-foreground hover:bg-primary-hover": isSelected, }), )} id={`lo_id_${index}`} diff --git a/src/prompt.tsx b/src/prompt.tsx index a24b53f..9642ac2 100644 --- a/src/prompt.tsx +++ b/src/prompt.tsx @@ -21,7 +21,7 @@ const promptsVariants = cva("flex", { }); const promptVariants = cva( - "flex flex-col justify-center bg-white border border-gray-200 rounded-lg hover:border-gray-300 hover:shadow-sm transition-all duration-150 cursor-pointer", + "flex flex-col justify-center bg-background-elevated border-border hover:border-border/80", { variants: { size: { @@ -38,7 +38,7 @@ const promptVariants = cva( }, ); -const promptTitleVariants = cva("font-medium text-gray-900", { +const promptTitleVariants = cva("font-medium text-foreground", { variants: { size: { xs: "text-sm", @@ -53,7 +53,7 @@ const promptTitleVariants = cva("font-medium text-gray-900", { }, }); -const promptDescriptionVariants = cva("text-gray-600", { +const promptDescriptionVariants = cva("text-muted-foreground", { variants: { size: { xs: "text-xs", @@ -106,7 +106,7 @@ export function PromptTitle({ ? twMerge(clsx(promptTitleVariants({ size, className }))) : twMerge( clsx( - "font-medium text-gray-900", + "font-medium text-foreground", "[div[data-size='xs']_&]:text-sm", "[div[data-size='sm']_&]:text-base", "[div[data-size='default']_&]:text-base", @@ -130,7 +130,7 @@ export function PromptDescription({ ? twMerge(clsx(promptDescriptionVariants({ size, className }))) : twMerge( clsx( - "text-gray-600", + "text-muted-foreground", "[div[data-size='xs']_&]:text-xs", "[div[data-size='sm']_&]:text-sm", "[div[data-size='default']_&]:text-sm", diff --git a/src/sender.tsx b/src/sender.tsx index 241b3d6..3ce3072 100644 --- a/src/sender.tsx +++ b/src/sender.tsx @@ -21,7 +21,7 @@ export function InputCount({ ...props }: InputCountProps) { return ( - + {count} / {limit} ); @@ -58,7 +58,7 @@ export function SenderButton({ data-slot="sender-button" className={twMerge( clsx( - "flex h-8 w-8 items-center justify-center rounded-full bg-blue-500 hover:bg-blue-500/90 text-white cursor-pointer", + "flex items-center justify-center cursor-pointer size-icon-button rounded-full bg-primary text-primary-foreground hover:bg-primary-hover", className, ), )} @@ -66,7 +66,7 @@ export function SenderButton({ > {icon ?? ( {isSending @@ -211,15 +211,15 @@ export function Sender({ data-slot="sender" className={twMerge( clsx( - "relative px-1 flex flex-col items-center border rounded-2xl", - "border-gray-200 dark:border-gray-700 shadow-sm transition-all duration-300 hover:shadow-md", - "focus-within:ring-2 focus-within:ring-blue-500 focus-within:border-blue-500", + "relative px-1 flex flex-col items-center border rounded-xl", + "border-border shadow-sm transition-all duration-normal hover:shadow-md", + "focus-within:ring-2 focus-within:ring-ring focus-within:border-primary", className, ), )} {...props} > -
+
diff --git a/src/tailwind.css b/src/tailwind.css index e3bb3b1..b7eb2a4 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -2,39 +2,92 @@ @custom-variant dark (&:where(.dark, .dark *)); @theme { - --color-background: hsl(0 0% 100%); - --color-foreground: hsl(222.2 84% 4.9%); - --color-primary: hsl(221.2 83.2% 53.3%); - - --color-background: var(--background); - --color-foreground: var(--foreground); - --color-primary: var(--primary); - - --rp-c-bg: var(--color-background); - --rp-c-text: var(--color-foreground); - --rp-c-brand: var(--color-primary); - --rp-c-brand-light: color-mix(in srgb, var(--color-primary) 80%, transparent); -} + /* 1. color */ + --color-background: oklch(1 0 0); /* white */ + --color-foreground: oklch(0.2 0 0); /* gray-700 */ + + --color-background-elevated: oklch(1 0 0); /* white */ + + --color-primary: oklch(0.62 0.21 260); /* blue-500 */ + --color-primary-foreground: oklch(1 0 0); /* white */ + + --color-muted: oklch(0.6 0 0); /* gray-400 */ + --color-muted-foreground: oklch(0.55 0 0); + + --color-accent: oklch(0.96 0 0); + --color-accent-foreground: oklch(0.2 0 0); + + --color-border: oklch(0.87 0.01 260); /* gray-200 */ + --color-scrollbar: oklch(0.87 0.01 260); /* gray-300 */ + --color-scrollbar-hover: oklch(0.7 0.01 260); /* gray-400 */ + --color-ring: oklch(0.62 0.21 260); /* primary */ + + /* 2. Rounded Corner */ + --radius-lg: 0.5rem; /* rounded-lg */ + --radius-xl: 1rem; /* rounded-2xl */ + --radius-full: 9999px; /* rounded-full */ + + /* 3. shadow */ + --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1); + --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1); + --shadow-elevated: 0 10px 15px -3px rgb(253 230 138 / 0.3); /* amber-50 */ + + /* 4. Type */ + --size-icon-button: 2rem; /* h-8 w-8 */ + --height-textarea-max: 8rem; /* max-h-32 */ + --height-dropdown-max: 16rem; /* max-h-64 */ -:root { - --background: 0 0% 100%; - --foreground: 222.2 84% 4.9%; - --primary: 221.2 83.2% 53.3%; + /* 5. Motion */ + --duration-normal: 300ms; + + /* 6. Spacing */ + --spacing-1: 0.25rem; + --spacing-2: 0.5rem; /* py-2 */ + --spacing-4: 1rem; /* px-4, gap-4 */ } .dark { - --background: 222.2 84% 4.9%; - --foreground: 210 40% 98%; - --primary: 217.2 91.2% 59.8%; -} + @theme { + --color-background: oklch(0.15 0.01 260); + --color-foreground: oklch(0.9 0 0); + --color-background-elevated: oklch(0.13 0 0); + --color-border: oklch(0.3 0.01 260); + + --color-accent: oklch(0.26 0 0); + --color-muted: oklch(0.65 0 0); + --color-muted-foreground: oklch(0.65 0 0); -@layer base { - body { - @apply bg-background text-foreground; + --color-scrollbar: oklch(0.26 0 0); + --color-scrollbar-hover: oklch(0.4 0 0); + + --shadow-elevated: 0 10px 15px -3px rgb(0 0 0 / 0.5), 0 0 0 1px oklch(1 0 0 / 0.05); } } + + @layer components { - .rspress-doc a { - @apply text-primary hover:underline; + .bg-primary-hover { + background-color: color-mix(in oklab, var(--color-primary) 90%, transparent); } -} + .custom-scrollbar { + scrollbar-gutter: stable; + + &::-webkit-scrollbar { + width: 0.375rem; /* w-1.5 */ + } + + &::-webkit-scrollbar-thumb { + border-radius: 9999px; + cursor: auto; + background-color: var(--color-scrollbar); + + &:hover { + background-color: var(--color-scrollbar-hover); + } + } + + &::-webkit-scrollbar-track { + margin-top: var(--spacing-3); + } + } +} \ No newline at end of file From e9cefe7a357682f2b1207f4202a8a0a71d9c3693 Mon Sep 17 00:00:00 2001 From: YESWmeshade <392950974@qq.com> Date: Mon, 12 Jan 2026 18:54:36 +0800 Subject: [PATCH 3/6] refactor(ui): replace hardcoded styles with Tailwind CSS variables --- src/tailwind.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tailwind.css b/src/tailwind.css index b7eb2a4..24be95f 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -90,4 +90,4 @@ margin-top: var(--spacing-3); } } -} \ No newline at end of file +} From ca787dd51aa3149335268b3c07e423eaee3e693c Mon Sep 17 00:00:00 2001 From: YESWmeshade <392950974@qq.com> Date: Tue, 13 Jan 2026 14:25:23 +0800 Subject: [PATCH 4/6] refactor(ui): replace hardcoded styles with Tailwind CSS variables --- src/button.tsx | 10 +-- src/file-upload.tsx | 2 +- src/list.tsx | 20 ++++-- src/prompt.tsx | 30 ++++---- src/sender.tsx | 21 +++--- src/tailwind.css | 165 +++++++++++++++++++++++++------------------- 6 files changed, 142 insertions(+), 106 deletions(-) diff --git a/src/button.tsx b/src/button.tsx index f7f0f58..d518c4e 100644 --- a/src/button.tsx +++ b/src/button.tsx @@ -6,16 +6,16 @@ import type * as React from "react"; import { twMerge } from "tailwind-merge"; const buttonVariants = cva( - "cursor-pointer inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors text-white dark:text-white/80", + "inline-flex items-center justify-center rounded-mc-btn text-sm font-medium transition-colors text-mc-btn-fg", { variants: { variant: { - default: "bg-blue-500 hover:bg-blue-500/90 gap-1", + default: "bg-mc-btn hover:bg-mc-btn-hv gap-mc-btn-gap", link: "underline-offset-4 hover:underline", }, size: { - default: "px-4 py-2", - icon: "p-2", + default: "px-mc-btn-px py-mc-btn-py", + icon: "p-mc-2", }, }, defaultVariants: { @@ -33,7 +33,7 @@ function Button({ }: React.ComponentProps<"button"> & VariantProps) { return (