diff --git a/frontend/src/components/CardStyles.tsx b/frontend/src/components/CardStyles.tsx index 52ca586..c6f6ee6 100644 --- a/frontend/src/components/CardStyles.tsx +++ b/frontend/src/components/CardStyles.tsx @@ -1,177 +1,210 @@ import type { CSSProperties } from 'react'; -// 统一的卡片样式配置 -export const cardStyles = { - // 基础卡片样式 - base: { - borderRadius: 12, - transition: 'all 0.3s ease', +const bookshelfBaseShadow = ` + 0 10px 22px -12px color-mix(in srgb, var(--ant-color-text) 28%, transparent), + inset 0 1px 0 color-mix(in srgb, var(--ant-color-bg-container) 82%, transparent) +`; + +const bookshelfHoverShadow = ` + 0 16px 30px -12px color-mix(in srgb, var(--ant-color-text) 34%, transparent), + inset 0 1px 0 color-mix(in srgb, var(--ant-color-bg-container) 88%, transparent) +`; + +const bookshelfNewBaseShadow = ` + 0 10px 24px -14px color-mix(in srgb, var(--ant-color-text) 30%, transparent), + inset 0 1px 0 color-mix(in srgb, var(--ant-color-bg-container) 84%, transparent) +`; + +const bookshelfNewHoverShadow = ` + 0 16px 30px -12px color-mix(in srgb, var(--ant-color-text) 36%, transparent), + inset 0 1px 0 color-mix(in srgb, var(--ant-color-bg-container) 90%, transparent) +`; + +const promptTemplateBaseShadow = ` + 0 6px 16px color-mix(in srgb, var(--ant-color-text) 11%, transparent), + 0 1px 0 color-mix(in srgb, var(--ant-color-white) 42%, transparent) inset +`; + +// BookshelfPage 样式(书架/书本卡片) +export const bookshelfCardStyles = { + container: { + display: 'grid', + gridTemplateColumns: 'repeat(auto-fill, minmax(270px, 1fr))', + gap: '20px 18px', + padding: '8px 0 16px', + alignItems: 'stretch', } as CSSProperties, - // 悬浮效果 - hoverable: { - cursor: 'pointer', - position: 'relative' as const, - } as CSSProperties, - - // 角色卡片样式 - character: { - // height: 320, - display: 'flex', - flexDirection: 'column', - borderColor: 'var(--color-info)', - borderRadius: 12, - } as CSSProperties, - - // 组织卡片样式 - organization: { - // height: 320, - display: 'flex', - flexDirection: 'column', - borderColor: 'var(--color-success)', - backgroundColor: 'var(--color-bg-base)', // 使用柔和的背景色 - borderRadius: 12, - } as CSSProperties, - - // 项目卡片样式 - 书籍风格 (Book Style) - project: { + projectCard: { height: '100%', - borderRadius: '6px 16px 16px 6px', // 左侧稍直(书脊),右侧圆润 + borderRadius: '4px 12px 12px 4px', overflow: 'hidden', - background: '#fff', - // 基础阴影 + 书籍厚度阴影 - boxShadow: ` - 0 2px 8px rgba(0, 0, 0, 0.04), - 4px 0 8px rgba(0, 0, 0, 0.02) - `, - transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', - border: '1px solid rgba(0,0,0,0.02)', - borderLeft: '6px solid var(--color-primary)', // 书脊效果 + background: 'linear-gradient(180deg, color-mix(in srgb, var(--ant-color-bg-container) 96%, var(--ant-color-text) 4%) 0%, color-mix(in srgb, var(--ant-color-bg-container) 88%, var(--ant-color-text) 12%) 100%)', + boxShadow: bookshelfBaseShadow, + transition: 'transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), border-color 0.3s ease', + border: '1px solid color-mix(in srgb, var(--ant-color-text) 18%, transparent)', display: 'flex', flexDirection: 'column', position: 'relative', + transformOrigin: 'center bottom', + transformStyle: 'preserve-3d', } as CSSProperties, - // 新建项目卡片样式 - 统一书籍风格 - newProjectBook: { + newProjectCard: { height: '100%', - borderRadius: '6px 16px 16px 6px', + borderRadius: 12, overflow: 'hidden', - background: '#fff', - // 基础阴影 + 书籍厚度阴影 (与普通项目一致) - boxShadow: ` - 0 2px 8px rgba(0, 0, 0, 0.04), - 4px 0 8px rgba(0, 0, 0, 0.02) - `, - border: '1px solid rgba(0,0,0,0.02)', - borderLeft: '6px solid var(--color-primary)', // 与普通项目一致的书脊颜色 + background: 'linear-gradient(180deg, color-mix(in srgb, var(--ant-color-bg-container) 94%, var(--ant-color-warning) 6%) 0%, color-mix(in srgb, var(--ant-color-bg-container) 86%, var(--ant-color-warning) 14%) 100%)', + boxShadow: bookshelfNewBaseShadow, + border: '2px dashed color-mix(in srgb, var(--ant-color-warning) 40%, var(--ant-color-border) 60%)', display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', - transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', + transition: 'transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease, background-color 0.3s ease', position: 'relative', } as CSSProperties, - - // 书架风格容器 - bookshelf: { - display: 'grid', - gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', - gap: '24px', - padding: '24px 0', - } as CSSProperties, - - // 卡片内容区域样式 - body: { - padding: 20, - display: 'flex', - flexDirection: 'column' as const, - } as CSSProperties, - - // 卡片描述区域样式(固定高度,内容截断) - description: { - marginTop: 12, - maxHeight: 200, - overflow: 'hidden' as const, - } as CSSProperties, - - // 文本截断样式 - ellipsis: { - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap' as const, - } as CSSProperties, - - // 多行文本截断 - ellipsisMultiline: (lines: number = 2) => ({ - display: '-webkit-box', - WebkitLineClamp: lines, - WebkitBoxOrient: 'vertical' as const, - overflow: 'hidden', - textOverflow: 'ellipsis', - } as CSSProperties), }; -// 卡片悬浮动画 - 增强版 (Subtle Lift) -export const cardHoverHandlers = { +export const bookshelfCardHoverHandlers = { onMouseEnter: (e: React.MouseEvent) => { const target = e.currentTarget; - target.style.transform = 'translateY(-6px) rotateY(-2deg)'; // 悬浮时轻微翻起 - - // 统一书本悬浮态 - target.style.boxShadow = ` - -2px 0 4px rgba(0, 0, 0, 0.1), // 书脊阴影加深 - 8px 12px 24px rgba(0, 0, 0, 0.12) - `; + if (target.dataset.cardStyle !== 'bookshelf-book') { + return; + } + if (target.dataset.bookKind === 'new') { + target.style.transform = 'translateY(-6px)'; + target.style.boxShadow = bookshelfNewHoverShadow; + target.style.borderColor = 'color-mix(in srgb, var(--ant-color-warning) 48%, var(--ant-color-border) 52%)'; + target.style.background = 'linear-gradient(180deg, color-mix(in srgb, var(--ant-color-bg-container) 92%, var(--ant-color-warning) 8%) 0%, color-mix(in srgb, var(--ant-color-bg-container) 82%, var(--ant-color-warning) 18%) 100%)'; + return; + } + + target.style.transform = 'translateY(-8px) rotateX(2deg)'; + target.style.boxShadow = bookshelfHoverShadow; + target.style.borderColor = 'color-mix(in srgb, var(--ant-color-primary) 28%, var(--ant-color-border) 72%)'; }, onMouseLeave: (e: React.MouseEvent) => { const target = e.currentTarget; - target.style.transform = 'translateY(0) rotateY(0)'; - - // 统一恢复基础阴影 - target.style.boxShadow = ` - 0 2px 8px rgba(0, 0, 0, 0.04), - 4px 0 8px rgba(0, 0, 0, 0.02) - `; + if (target.dataset.cardStyle !== 'bookshelf-book') { + return; + } + + const isNewBook = target.dataset.bookKind === 'new'; + target.style.transform = 'translateY(0) rotateX(0)'; + target.style.boxShadow = isNewBook ? bookshelfNewBaseShadow : bookshelfBaseShadow; + target.style.borderColor = isNewBook + ? 'color-mix(in srgb, var(--ant-color-warning) 40%, var(--ant-color-border) 60%)' + : 'color-mix(in srgb, var(--ant-color-text) 18%, transparent)'; + if (isNewBook) { + target.style.background = 'linear-gradient(180deg, color-mix(in srgb, var(--ant-color-bg-container) 94%, var(--ant-color-warning) 6%) 0%, color-mix(in srgb, var(--ant-color-bg-container) 86%, var(--ant-color-warning) 14%) 100%)'; + } }, }; -// 响应式网格配置 -export const gridConfig = { - gutter: [16, 16] as [number, number], +// PromptTemplates 页面卡片样式 +export const promptTemplateCardStyles = { + templateCard: { + height: '100%', + borderRadius: 14, + overflow: 'hidden', + border: '1px solid color-mix(in srgb, var(--ant-color-text) 8%, transparent)', + background: 'linear-gradient(180deg, color-mix(in srgb, var(--ant-color-bg-container) 97%, var(--ant-color-primary) 3%) 0%, var(--ant-color-bg-container) 100%)', + boxShadow: promptTemplateBaseShadow, + transition: 'transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.28s cubic-bezier(0.22, 1, 0.36, 1), border-color 0.28s ease', + } as CSSProperties, +}; + +export const promptTemplateCardHoverHandlers = { + onMouseEnter: (e: React.MouseEvent) => { + const target = e.currentTarget; + target.style.transform = 'translateY(-6px)'; + target.style.boxShadow = ` + 0 14px 24px color-mix(in srgb, var(--ant-color-text) 16%, transparent), + 0 1px 0 color-mix(in srgb, var(--ant-color-white) 48%, transparent) inset + `; + target.style.borderColor = 'color-mix(in srgb, var(--ant-color-primary) 24%, transparent)'; + }, + onMouseLeave: (e: React.MouseEvent) => { + const target = e.currentTarget; + target.style.transform = 'translateY(0)'; + target.style.boxShadow = promptTemplateBaseShadow; + target.style.borderColor = 'color-mix(in srgb, var(--ant-color-text) 8%, transparent)'; + }, +}; + +export const promptTemplateGridConfig = { xs: 24, sm: 12, lg: 8, xl: 6, }; -// 角色卡片网格配置 -export const characterGridConfig = { - gutter: 0, // 移除 gutter,避免负边距 - xs: 24, // 手机:1列 - sm: 12, // 平板:2列 - md: 12, // 中等屏幕:3列 - lg: 6, // 大屏:4列 - xl: 6, // 超大屏:4列 - xxl: 5, // 超超大屏:6列 +// WorldSetting 页面卡片样式 +export const worldSettingCardStyles = { + sectionCard: { + borderRadius: 14, + border: '1px solid color-mix(in srgb, var(--ant-color-text) 7%, transparent)', + boxShadow: '0 4px 12px color-mix(in srgb, var(--ant-color-text) 8%, transparent)', + background: 'linear-gradient(180deg, color-mix(in srgb, var(--ant-color-bg-container) 98%, var(--ant-color-primary) 2%) 0%, var(--ant-color-bg-container) 100%)', + transition: 'box-shadow 0.24s ease, border-color 0.24s ease', + } as CSSProperties, }; -// 文本样式 -export const textStyles = { +// Characters 页面(CharacterCard + 网格)样式 +export const characterCardStyles = { + characterCard: { + display: 'flex', + flexDirection: 'column', + borderRadius: 12, + } as CSSProperties, + + organizationCard: { + display: 'flex', + flexDirection: 'column', + backgroundColor: 'var(--ant-color-bg-layout)', + borderRadius: 12, + } as CSSProperties, + + nameEllipsis: { + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + } as CSSProperties, + + descriptionBlock: { + marginTop: 12, + maxHeight: 200, + overflow: 'hidden', + } as CSSProperties, +}; + +export const charactersPageGridConfig = { + gutter: 0, + xs: 24, + sm: 12, + md: 12, + lg: 6, + xl: 6, + xxl: 5, +}; + +// 页面通用文本样式(仅用于信息展示,不与卡片结构耦合) +export const commonTextStyles = { label: { fontSize: 12, - color: 'rgba(0, 0, 0, 0.45)', + color: 'color-mix(in srgb, var(--ant-color-text) 55%, transparent)', } as CSSProperties, value: { fontSize: 14, - color: 'rgba(0, 0, 0, 0.85)', + color: 'var(--ant-color-text)', } as CSSProperties, description: { fontSize: 12, - color: 'rgba(0, 0, 0, 0.45)', + color: 'color-mix(in srgb, var(--ant-color-text) 55%, transparent)', lineHeight: 1.6, } as CSSProperties, -}; \ No newline at end of file +};