From f59d1d0f19f08bab33a3c60ad98d76f398e7dbba Mon Sep 17 00:00:00 2001 From: Leo <98382335+gaoziman@users.noreply.github.com> Date: Sun, 19 Oct 2025 21:51:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=85=A8=E5=B1=80=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E5=92=8C=E4=B8=BB=E9=A2=98=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 配置紫色主题(#7C3AED → #EC4899) - 实现导航菜单简洁下划线样式 - 添加自定义滚动条样式 - 添加渐变背景类 - 添加瀑布流布局样式 - 添加动画效果和过渡 - 统一视觉风格和交互体验 --- src/global.css | 287 ++++++++++++++++++++++++++++++++++++++++++++ src/theme/colors.ts | 133 ++++++++++++++++++++ src/theme/index.ts | 10 ++ src/theme/tokens.ts | 151 +++++++++++++++++++++++ 4 files changed, 581 insertions(+) create mode 100644 src/global.css create mode 100644 src/theme/colors.ts create mode 100644 src/theme/index.ts create mode 100644 src/theme/tokens.ts diff --git a/src/global.css b/src/global.css new file mode 100644 index 0000000..1b72aaa --- /dev/null +++ b/src/global.css @@ -0,0 +1,287 @@ +/* 全局样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', 'PingFang SC', 'Microsoft YaHei', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* 按钮文字增强 - 提升主按钮文字可读性 */ +.ant-btn-primary { + font-weight: 600 !important; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) !important; + letter-spacing: 0.03em !important; + color: #FFFFFF !important; +} + +.ant-btn-primary:hover { + text-shadow: 0 1px 4px rgba(0, 0, 0, 0.25) !important; + color: #FFFFFF !important; +} + +.ant-btn-primary:active { + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) !important; + color: #FFFFFF !important; +} + +/* 自定义滚动条 - 紫色主题 */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: #F5F3FF; + border-radius: 4px; +} + +::-webkit-scrollbar-thumb { + background: #DDD6FE; + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: #C4B5FD; +} + +/* 渐变背景类 - 紫色主题 */ +.gradient-bg-purple { + background: linear-gradient(135deg, #7C3AED 0%, #EC4899 100%); +} + +.gradient-bg-purple-blue { + background: linear-gradient(135deg, #8B5CF6 0%, #6366F1 100%); +} + +.gradient-bg-purple-pink { + background: linear-gradient(120deg, #A78BFA 0%, #F472B6 100%); +} + +.gradient-bg-success { + background: linear-gradient(135deg, #10B981 0%, #059669 100%); +} + +/* 玻璃态效果 */ +.glass-effect { + background: rgba(255, 255, 255, 0.8); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.3); +} + +/* 卡片悬浮动效 */ +.hover-card { + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + cursor: pointer; +} + +.hover-card:hover { + transform: translateY(-4px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); +} + +/* 图片网格 */ +.image-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 16px; +} + +@media (max-width: 768px) { + .image-grid { + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + gap: 12px; + } +} + +/* 淡入动画 */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.fade-in { + animation: fadeIn 0.5s ease-out; +} + +/* 页面容器 */ +.page-container { + padding: 24px; + min-height: calc(100vh - 64px - 70px); + background: linear-gradient(180deg, #FAFAF9 0%, #F5F3FF 100%); +} + +@media (max-width: 768px) { + .page-container { + padding: 16px; + } +} + +/* 代码字体 */ +.code-font { + font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; + font-size: 13px; +} + +/* 文本溢出省略 */ +.text-ellipsis { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.text-ellipsis-2 { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-overflow: ellipsis; +} + +/* 拖拽上传区域样式 - 紫色主题 */ +.upload-dropzone { + border: 2px dashed #DDD6FE; + border-radius: 12px; + background: #FAFAF9; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.upload-dropzone:hover, +.upload-dropzone.drag-active { + border-color: #7C3AED; + background: linear-gradient(135deg, #F5F3FF 0%, #FAF5FF 100%); + box-shadow: 0 4px 20px rgba(124, 58, 237, 0.15); +} + +/* 图片预览遮罩 */ +.image-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.6); + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 0.3s; +} + +.image-card:hover .image-overlay { + opacity: 1; +} + +/* 瀑布流布局样式 */ +.masonry-grid { + display: flex; + margin-left: -16px; /* 列间距的一半 */ + width: auto; +} + +.masonry-grid_column { + padding-left: 16px; /* 列间距 */ + background-clip: padding-box; +} + +.masonry-grid_column > * { + margin-bottom: 0; /* 卡片自身已有margin-bottom */ +} + +/* 顶部导航菜单样式 - 简洁下划线设计 */ +.top-nav-menu.ant-menu-horizontal { + line-height: 62px !important; +} + +/* 菜单项默认样式 */ +.top-nav-menu .ant-menu-item { + padding: 0 20px !important; + margin: 0 8px !important; + border-radius: 0 !important; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important; + color: #666666 !important; + font-weight: 500 !important; + position: relative !important; + background: transparent !important; +} + +/* 隐藏默认的底部边框 */ +.top-nav-menu .ant-menu-item::after { + display: none !important; +} + +/* 创建自定义下划线(使用 ::before 伪元素)*/ +.top-nav-menu .ant-menu-item::before { + content: '' !important; + position: absolute !important; + bottom: 0 !important; + left: 50% !important; + transform: translateX(-50%) !important; + width: 0 !important; + height: 3px !important; + background: linear-gradient(90deg, #7C3AED 0%, #EC4899 100%) !important; + border-radius: 2px 2px 0 0 !important; + transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important; +} + +/* 菜单项悬停样式 */ +.top-nav-menu .ant-menu-item:hover { + background: transparent !important; + color: #7C3AED !important; +} + +/* 悬停时下划线显示(部分宽度)*/ +.top-nav-menu .ant-menu-item:hover::before { + width: 50% !important; + opacity: 0.6 !important; +} + +/* 菜单项选中样式 - 紫色文字 + 底部下划线 */ +.top-nav-menu .ant-menu-item-selected { + background: transparent !important; + color: #7C3AED !important; + font-weight: 600 !important; +} + +/* 选中状态的下划线(完整宽度)*/ +.top-nav-menu .ant-menu-item-selected::before { + width: 70% !important; + opacity: 1 !important; +} + +/* 选中状态的图标颜色 */ +.top-nav-menu .ant-menu-item-selected .anticon { + color: #7C3AED !important; +} + +/* 悬停状态的图标颜色 */ +.top-nav-menu .ant-menu-item:hover .anticon { + color: #7C3AED !important; +} + +/* 选中状态悬停时 */ +.top-nav-menu .ant-menu-item-selected:hover { + background: transparent !important; + color: #6D28D9 !important; +} + +/* 选中状态悬停时下划线更明显 */ +.top-nav-menu .ant-menu-item-selected:hover::before { + width: 80% !important; + opacity: 1 !important; +} + +/* 选中状态悬停时图标颜色 */ +.top-nav-menu .ant-menu-item-selected:hover .anticon { + color: #6D28D9 !important; +} diff --git a/src/theme/colors.ts b/src/theme/colors.ts new file mode 100644 index 0000000..ce2583d --- /dev/null +++ b/src/theme/colors.ts @@ -0,0 +1,133 @@ +// PicStack 颜色常量 - 统一管理所有颜色,避免硬编码 + +/** + * 主色系 - 深紫色系(高对比度) + */ +export const PRIMARY_COLORS = { + /** 深紫色 - 主按钮、主要交互 */ + PRIMARY: '#5B21B6', + /** 中深紫 - 悬停状态、链接 */ + PRIMARY_HOVER: '#6D28D9', + /** 中紫色 - 信息提示、次要交互 */ + PRIMARY_LIGHT: '#7C3AED', + /** 浅紫色 - 装饰元素 */ + PRIMARY_LIGHTER: '#8B5CF6', + /** 超深紫 - 按钮激活状态 */ + PRIMARY_DARK: '#4C1D95', +} as const; + +/** + * 功能色系 + */ +export const FUNCTIONAL_COLORS = { + /** 成功色 - 翡翠绿 */ + SUCCESS: '#10B981', + /** 成功色深色 */ + SUCCESS_DARK: '#059669', + /** 警告色 - 琥珀色 */ + WARNING: '#F59E0B', + /** 警告色深色 */ + WARNING_DARK: '#D97706', + /** 错误色 - 红色 */ + ERROR: '#EF4444', + /** 错误色深色 */ + ERROR_DARK: '#DC2626', + /** 信息色 - 中紫色 */ + INFO: '#7C3AED', +} as const; + +/** + * 渐变色 - 强调/高亮 + */ +export const ACCENT_COLORS = { + /** 粉色 - 渐变、高亮 */ + PINK: '#EC4899', + /** 粉紫色 */ + PURPLE_PINK: '#A78BFA', +} as const; + +/** + * 背景色系 + */ +export const BACKGROUND_COLORS = { + /** 基础背景 */ + BASE: '#FAFAF9', + /** 容器背景 */ + CONTAINER: '#FFFFFF', + /** 布局背景 - 淡紫色 */ + LAYOUT: '#F5F3FF', + /** 超浅紫背景 */ + LIGHT_PURPLE: '#FAF5FF', +} as const; + +/** + * 文本色系 + */ +export const TEXT_COLORS = { + /** 主文本 */ + PRIMARY: '#1F2937', + /** 副文本 */ + SECONDARY: '#4B5563', + /** 弱文本 */ + TERTIARY: '#9CA3AF', + /** 禁用文本 */ + DISABLED: '#D1D5DB', +} as const; + +/** + * 边框色系 + */ +export const BORDER_COLORS = { + /** 常规边框 */ + DEFAULT: '#E5E7EB', + /** 浅边框 */ + LIGHT: '#F3F4F6', + /** 激活边框 */ + ACTIVE: '#5B21B6', + /** 悬停边框 */ + HOVER: '#7C3AED', +} as const; + +/** + * Tag 组件专用颜色 + */ +export const TAG_COLORS = { + /** 主要标签 - 紫色 */ + PRIMARY: 'purple', + /** 成功标签 - 绿色 */ + SUCCESS: 'green', + /** 警告标签 - 橙色 */ + WARNING: 'orange', + /** 错误标签 - 红色 */ + ERROR: 'red', + /** 信息标签 - 紫色 */ + INFO: 'purple', +} as const; + +/** + * 渐变配置 + */ +export const GRADIENTS = { + /** 主渐变 - 紫粉渐变 */ + PRIMARY: 'linear-gradient(135deg, #7C3AED 0%, #EC4899 100%)', + /** 紫蓝渐变 */ + PURPLE_BLUE: 'linear-gradient(135deg, #8B5CF6 0%, #6366F1 100%)', + /** 紫粉渐变 */ + PURPLE_PINK: 'linear-gradient(120deg, #A78BFA 0%, #F472B6 100%)', + /** 成功渐变 */ + SUCCESS: 'linear-gradient(135deg, #10B981 0%, #059669 100%)', +} as const; + +// 导出所有颜色的集合 +export const COLORS = { + ...PRIMARY_COLORS, + ...FUNCTIONAL_COLORS, + ...ACCENT_COLORS, + ...BACKGROUND_COLORS, + ...TEXT_COLORS, + ...BORDER_COLORS, + GRADIENTS, + TAG: TAG_COLORS, +} as const; + +export default COLORS; diff --git a/src/theme/index.ts b/src/theme/index.ts new file mode 100644 index 0000000..85f11fd --- /dev/null +++ b/src/theme/index.ts @@ -0,0 +1,10 @@ +import type { ThemeConfig } from 'antd'; +import { themeTokens, componentTokens } from './tokens'; + +export const theme: ThemeConfig = { + token: themeTokens, + components: componentTokens, + cssVar: true, +}; + +export * from './tokens'; diff --git a/src/theme/tokens.ts b/src/theme/tokens.ts new file mode 100644 index 0000000..a20e660 --- /dev/null +++ b/src/theme/tokens.ts @@ -0,0 +1,151 @@ +// Ant Design 主题 Token 配置 - 紫色渐变系 +export const themeTokens = { + // 主色系 - 深紫色系(优化对比度) + colorPrimary: '#5B21B6', // 深紫色(提升按钮文字对比度) + colorSuccess: '#10B981', // 翡翠绿(上传成功) + colorWarning: '#F59E0B', // 琥珀色(警告) + colorError: '#EF4444', // 红色(错误) + colorInfo: '#7C3AED', // 中紫色(信息提示) + colorLink: '#6D28D9', // 链接色(中深紫) + + // 背景色 - 柔和紫调 + colorBgBase: '#FAFAF9', // 最外层背景(极浅暖灰) + colorBgContainer: '#FFFFFF', // 容器背景(纯白) + colorBgElevated: '#FFFFFF', // 悬浮背景(纯白) + colorBgLayout: '#F5F3FF', // 布局背景(极淡紫) + + // 文本色 + colorTextBase: '#1F2937', // 主文本(深灰) + colorTextSecondary: '#4B5563', // 副文本(中灰) + colorTextTertiary: '#9CA3AF', // 弱文本(浅灰) + colorTextQuaternary: '#D1D5DB', // 禁用文本(超浅灰) + + // 边框 - 紫调边框 + colorBorder: '#E5E7EB', // 常规边框 + colorBorderSecondary: '#F3F4F6', // 浅边框 + + // 字体 + fontSize: 14, + fontSizeHeading1: 32, + fontSizeHeading2: 24, + fontSizeHeading3: 18, + fontSizeHeading4: 16, + fontSizeHeading5: 14, + fontFamily: "'Inter', 'PingFang SC', 'Microsoft YaHei', sans-serif", + + // 圆角 - 更现代的圆角 + borderRadius: 10, + borderRadiusLG: 16, + borderRadiusSM: 6, + borderRadiusXS: 4, + + // 阴影 - 柔和阴影 + boxShadow: '0 2px 12px rgba(124, 58, 237, 0.08)', + boxShadowSecondary: '0 4px 20px rgba(124, 58, 237, 0.12)', + + // 控件高度 + controlHeight: 38, + controlHeightLG: 44, + controlHeightSM: 30, + + // 禁用线框模式 + wireframe: false, +}; + +// 组件级 Token 配置 - 深紫色主题 +export const componentTokens = { + Button: { + primaryShadow: '0 4px 12px rgba(91, 33, 182, 0.3)', + controlHeight: 38, + controlHeightLG: 44, + fontWeight: 600, // 加粗文字 + primaryColor: '#5B21B6', // 深紫色主按钮 + colorPrimary: '#5B21B6', + colorPrimaryHover: '#6D28D9', // 悬停时稍浅 + colorPrimaryActive: '#4C1D95', // 点击时更深 + defaultBorderColor: '#E5E7EB', + defaultColor: '#4B5563', + }, + + Card: { + boxShadow: '0 2px 12px rgba(124, 58, 237, 0.06)', + borderRadiusLG: 16, + }, + + Upload: { + colorBorder: '#E5E7EB', + colorBgContainerDisabled: '#F9FAFB', + }, + + Table: { + headerBg: '#F9FAFB', + headerColor: '#1F2937', + rowHoverBg: '#F5F3FF', + borderColor: '#F3F4F6', + }, + + Input: { + activeBorderColor: '#5B21B6', + hoverBorderColor: '#7C3AED', + controlHeight: 38, + }, + + Select: { + optionSelectedBg: '#EDE9FE', + optionSelectedColor: '#5B21B6', + controlHeight: 38, + }, + + Tabs: { + itemSelectedColor: '#5B21B6', + itemHoverColor: '#7C3AED', + inkBarColor: '#5B21B6', + }, + + Menu: { + itemSelectedBg: '#F5F3FF', + itemSelectedColor: '#5B21B6', + itemHoverBg: '#FAFAF9', + itemActiveBg: '#EDE9FE', + }, + + Modal: { + contentBg: '#FFFFFF', + headerBg: '#FFFFFF', + borderRadiusLG: 16, + }, + + Message: { + contentBg: '#FFFFFF', + }, + + Badge: { + statusSize: 8, + }, + + Progress: { + defaultColor: '#5B21B6', + }, + + Statistic: { + titleFontSize: 14, + contentFontSize: 24, + }, + + Switch: { + colorPrimary: '#5B21B6', + colorPrimaryHover: '#6D28D9', + }, + + Slider: { + trackBg: '#5B21B6', + trackHoverBg: '#6D28D9', + handleColor: '#5B21B6', + handleActiveColor: '#6D28D9', + }, + + Tag: { + defaultBg: '#F5F3FF', + defaultColor: '#5B21B6', + }, +};