refactor(canvas): 画布卡片 - 统一卡片层级与交互动效

This commit is contained in:
ddCat
2026-08-07 12:34:50 +08:00
parent 1973afc356
commit cab0baba56
2 changed files with 112 additions and 17 deletions

View File

@@ -125,6 +125,41 @@
--project-library-icon-surface: #ffffff;
--project-library-shadow: 0 8px 20px rgba(0, 0, 0, 0.06);
/* === 新卡片系统 Token(对应 docs/ui-design-system.md)=== */
/* 卡片表面 - 纯白卡片浮在浅灰页面上 */
--card-surface: #ffffff;
--card-surface-hover: #ffffff;
--card-surface-raised: #f8f8f8;
/* 卡片边框 - 极淡,靠投影建立层次 */
--card-border: rgba(17, 17, 17, 0.06);
--card-border-hover: rgba(17, 17, 17, 0.08);
/* 卡片投影 - 微妙轻盈,像Apple/Figma */
--card-elevation:
0 1px 2px rgba(0, 0, 0, 0.04),
0 2px 4px rgba(0, 0, 0, 0.02);
--card-elevation-hover:
0 4px 12px rgba(0, 0, 0, 0.06),
0 8px 24px rgba(0, 0, 0, 0.04),
0 12px 36px rgba(0, 0, 0, 0.02);
/* 画布卡片封面区 - 浅灰衬托内容 */
--canvas-cover-surface: #f5f5f5;
--canvas-icon-surface: #ffffff;
--canvas-icon-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
/* 媒体区背景 */
--media-surface: #f5f5f5;
/* 骨架屏 */
--skeleton-surface: linear-gradient(
90deg,
rgba(17, 17, 17, 0.04) 0%,
rgba(17, 17, 17, 0.06) 50%,
rgba(17, 17, 17, 0.04) 100%
);
/* 实心(反相)按钮:不要写 background:var(--foreground) + color:var(--background),
两者在不同层级里解析结果不稳定,会出现同色不可读的按钮。用显式配对 token。 */
--btn-solid-bg: #171717;
@@ -542,6 +577,36 @@
--project-library-icon-surface: #0d0d0d;
--project-library-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
/* === 新卡片系统 Token - Dark(对应 docs/ui-design-system.md)=== */
--card-surface: #1f1f1f;
--card-surface-hover: #242424;
--card-surface-raised: #2a2a2a;
--card-border: rgba(255, 255, 255, 0.08);
--card-border-hover: rgba(255, 255, 255, 0.14);
--card-elevation:
0 2px 6px rgba(0, 0, 0, 0.32),
0 4px 12px rgba(0, 0, 0, 0.24),
0 6px 20px rgba(0, 0, 0, 0.16);
--card-elevation-hover:
0 8px 20px rgba(0, 0, 0, 0.40),
0 12px 32px rgba(0, 0, 0, 0.32),
0 16px 48px rgba(0, 0, 0, 0.24);
--canvas-cover-surface: #171717;
--canvas-icon-surface: #0d0d0d;
--canvas-icon-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
--media-surface: #171717;
--skeleton-surface: linear-gradient(
90deg,
rgba(255, 255, 255, 0.05) 0%,
rgba(255, 255, 255, 0.08) 50%,
rgba(255, 255, 255, 0.05) 100%
);
--btn-solid-bg: #f5f5f5;
--btn-solid-fg: #131313;
}
@@ -3271,24 +3336,32 @@
.canvas-library-count { display: flex; align-items: baseline; gap: 6px; justify-self: end; color: color-mix(in srgb, var(--foreground) 38%, transparent); font-size: var(--fs-micro); white-space: nowrap; }
.canvas-library-count strong { color: var(--foreground); font-size: var(--fs-heading-lg); font-variant-numeric: tabular-nums; font-weight: 500; letter-spacing: .02em; }
.canvas-library-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); align-items: start; gap: 28px 18px; }
/* 画布库网格 - 优化间距(对应 Bento Grid 原则)*/
.canvas-library-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); align-items: start; gap: 28px 22px; }
.canvas-library-page .app-pagination-bar { position: static; margin-top: var(--space-4); border-color: var(--workspace-border); background: transparent; padding: var(--space-1-half) var(--space-2); backdrop-filter: none; }
.app-canvas-project-card { min-width: 0; cursor: pointer; color: var(--foreground); transition: transform 420ms var(--motion-ease-out); }
.app-canvas-create-card { display: flex; min-width: 0; cursor: pointer; flex-direction: column; align-items: stretch; border: 0; background: transparent; padding: 0; color: var(--foreground); text-align: left; transition: transform 420ms var(--motion-ease-out); }
.app-canvas-create-card:hover:not(:disabled), .app-canvas-create-card:focus-visible { transform: translateY(-7px); }
/* === 画布卡片重构(对应 docs/ui-design-system.md)=== */
.app-canvas-project-card { min-width: 0; cursor: pointer; color: var(--foreground); transition: transform 240ms var(--motion-ease-out), box-shadow 280ms var(--motion-ease-out), background-color 200ms ease-out, border-color 200ms ease-out; }
/* 创建卡片 - 更吸引人的设计 */
.app-canvas-create-card { display: flex; min-width: 0; cursor: pointer; flex-direction: column; align-items: stretch; border: 0; background: transparent; padding: 0; color: var(--foreground); text-align: left; transition: transform 240ms var(--motion-ease-out); }
.app-canvas-create-card:hover:not(:disabled), .app-canvas-create-card:focus-visible { transform: translateY(-6px); }
.app-canvas-create-card:active:not(:disabled) { transform: translateY(-3px) scale(0.995); transition-duration: 120ms; }
.app-canvas-create-card:focus-visible { outline: 0; }
.app-canvas-create-preview { display: grid; aspect-ratio: 16 / 9; place-items: center; overflow: hidden; border-radius: var(--r-2xl); background: var(--surface-card); box-shadow: var(--elevation-card), var(--elevation-hairline); transition: background-color 320ms ease-out, box-shadow 420ms var(--motion-ease-out); }
.app-canvas-create-card:hover:not(:disabled) .app-canvas-create-preview, .app-canvas-create-card:focus-visible .app-canvas-create-preview { background: color-mix(in srgb, var(--workspace-accent) 12%, var(--workspace-surface-strong)); box-shadow: 0 18px 36px color-mix(in srgb, var(--foreground) 12%, transparent); }
.app-canvas-create-icon { width: 38px; height: 38px; color: color-mix(in srgb, var(--foreground) 36%, transparent); stroke-width: 1.2; transition: color 260ms ease-out, transform 420ms var(--motion-ease-out); }
.app-canvas-create-preview { display: grid; aspect-ratio: 16 / 9; place-items: center; overflow: hidden; border-radius: var(--r-xl); background: var(--card-surface); box-shadow: var(--card-elevation); border: 2px dashed rgba(17, 17, 17, 0.12); transition: background-color 240ms ease-out, box-shadow 280ms var(--motion-ease-out), border-color 200ms ease-out, border-style 200ms ease-out; }
.app-canvas-create-card:hover:not(:disabled) .app-canvas-create-preview, .app-canvas-create-card:focus-visible .app-canvas-create-preview { background: var(--card-surface); border-color: var(--workspace-accent); border-style: solid; box-shadow: var(--card-elevation-hover), 0 0 0 3px color-mix(in srgb, var(--workspace-accent) 12%, transparent); }
.app-canvas-create-icon { width: 38px; height: 38px; color: color-mix(in srgb, var(--foreground) 32%, transparent); stroke-width: 1.2; transition: color 240ms ease-out, transform 280ms var(--motion-ease-out); }
.app-canvas-create-card:hover:not(:disabled) .app-canvas-create-icon { color: var(--workspace-accent); transform: scale(1.12) rotate(90deg); }
.app-canvas-create-title { margin-top: 14px; font-size: var(--fs-heading-lg); font-weight: 620; line-height: 1.25; }
.app-canvas-create-meta { margin-top: 6px; color: color-mix(in srgb, var(--foreground) 38%, transparent); font-size: var(--fs-caption); }
.app-canvas-create-card:disabled { cursor: not-allowed; opacity: .5; }
.app-canvas-project-card.is-library { overflow: hidden; border-radius: var(--r-2xl); background: var(--surface-card); box-shadow: var(--elevation-card), var(--elevation-hairline); content-visibility: auto; contain-intrinsic-size: 0 320px; }
.app-canvas-project-card.is-library .app-canvas-project-preview { overflow: hidden; border-radius: var(--r-2xl) var(--r-2xl) 0 0; background: var(--surface-card); }
.app-canvas-project-card.is-library:hover, .app-canvas-project-card.is-library:focus-within { background: var(--surface-card-hover); box-shadow: var(--elevation-card-hover), var(--elevation-hairline); transform: translateY(-7px); }
.app-canvas-project-card.is-library.is-selected { box-shadow: 0 0 0 3px color-mix(in srgb, var(--workspace-accent) 22%, transparent); border-radius: var(--r-2xl); }
/* 画布卡片 - 库视图 - 更明显的hover效果 */
.app-canvas-project-card.is-library { overflow: hidden; border-radius: var(--r-xl); background: var(--card-surface); box-shadow: var(--card-elevation); border: 1px solid var(--card-border); content-visibility: auto; contain-intrinsic-size: 0 320px; }
.app-canvas-project-card.is-library .app-canvas-project-preview { overflow: hidden; border-radius: var(--r-xl) var(--r-xl) 0 0; background: var(--canvas-cover-surface); }
.app-canvas-project-card.is-library:hover, .app-canvas-project-card.is-library:focus-within { background: var(--card-surface); box-shadow: var(--card-elevation-hover); border-color: var(--card-border-hover); transform: translateY(-6px); }
.app-canvas-project-card.is-library:active { transform: translateY(-3px) scale(0.995); transition-duration: 120ms; }
.app-canvas-project-card.is-library.is-selected { box-shadow: var(--card-elevation), 0 0 0 2px color-mix(in srgb, var(--workspace-accent) 32%, transparent); border-color: var(--workspace-accent); border-radius: var(--r-xl); }
.app-canvas-project-card.is-recent .app-canvas-project-preview { overflow: hidden; border-radius: var(--r-2xl) var(--r-2xl) 0 0; background: var(--workspace-surface-strong); transition: box-shadow 420ms var(--motion-ease-out), transform 420ms var(--motion-ease-out); }
.app-canvas-project-card.is-recent:hover .app-canvas-project-preview, .app-canvas-project-card.is-recent:focus-within .app-canvas-project-preview { box-shadow: 0 18px 36px color-mix(in srgb, var(--foreground) 13%, transparent); transform: translateY(-4px); }
@@ -3311,9 +3384,13 @@
.canvas-project-select.is-visible, .app-canvas-project-card:hover .canvas-project-select, .app-canvas-project-card:focus-within .canvas-project-select { opacity: 1; }
.canvas-project-checkbox { width: 14px; height: 14px; margin: 0; accent-color: var(--workspace-accent); }
.app-canvas-project-body { min-height: 90px; border-radius: 0 0 var(--r-2xl) var(--r-2xl); background: var(--surface-card); padding: 14px 10px 8px; transition: background-color 320ms ease-out; }
.app-canvas-project-body { min-height: 90px; border-radius: 0 0 var(--r-xl) var(--r-xl); background: transparent; padding: 14px 10px 8px; transition: background-color 200ms ease-out; }
.app-canvas-project-body.is-compact { min-height: 0; padding: 11px 1px 1px; }
.app-canvas-project-card:hover .app-canvas-project-body { background: var(--surface-card-hover); }
.app-canvas-project-card:hover .app-canvas-project-body { background: transparent; }
/* Focus状态 - 键盘导航可见 */
.app-canvas-project-card:focus:not(:focus-visible) { outline: none; box-shadow: var(--card-elevation); }
.app-canvas-project-card:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; box-shadow: var(--card-elevation), 0 0 0 4px color-mix(in srgb, var(--ring) 16%, transparent); }
.canvas-project-card-footer { margin-top: 12px; }
.canvas-project-heading-row { display: flex; min-width: 0; align-items: center; justify-content: space-between; gap: 10px; }
.canvas-project-title-button { min-width: 0; flex: 1; cursor: pointer; border: 0; background: transparent; padding: 0; text-align: left; }
@@ -3339,6 +3416,22 @@
.library-page .app-page-header { border-bottom: 0; padding-bottom: 4px; }
.library-page .app-page-header h1 { font-size: var(--fs-heading-lg); font-weight: 620; }
.library-page .app-page-header p { max-width: 560px; }
/* 页面头部按钮优化 - 去除重边框 */
.library-page .app-page-header .ant-btn,
.canvas-library-page .app-page-header .ant-btn {
border: 1px solid rgba(17, 17, 17, 0.08) !important;
background: #ffffff !important;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04) !important;
transition: all 180ms ease-out !important;
}
.library-page .app-page-header .ant-btn:hover,
.canvas-library-page .app-page-header .ant-btn:hover {
border-color: rgba(17, 17, 17, 0.12) !important;
background: #ffffff !important;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08) !important;
transform: translateY(-1px);
}
.library-primary-action { border: 0 !important; border-radius: var(--r-md) !important; background: var(--btn-solid-bg) !important; color: var(--btn-solid-fg) !important; box-shadow: none !important; font-weight: 620; }
.library-toolbar { min-height: 50px; margin-top: 8px; border-bottom: 0; padding: 7px 0 10px; }
.library-toolbar .ant-input-affix-wrapper,
@@ -3622,10 +3715,11 @@
.wallet-library-page .wallet-ledger-panel .app-table-surface { box-shadow: none; }
.library-loading-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 26px 18px; margin-top: 20px; }
.library-skeleton { aspect-ratio: 16 / 10; border-radius: var(--r-2xl); background: color-mix(in srgb, var(--foreground) 6%, transparent); animation: library-pulse 1.6s ease-in-out infinite; }
/* 画布骨架屏 - 使用新token */
.library-skeleton { aspect-ratio: 16 / 10; border-radius: var(--r-xl); background: var(--skeleton-surface); animation: library-pulse 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
.task-library-page .library-loading-grid { grid-template-columns: 1fr; gap: 2px; }
.task-library-page .library-loading-grid .library-skeleton { height: 92px; aspect-ratio: auto; border-radius: var(--r-lg); }
@keyframes library-pulse { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }
@keyframes library-pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 0.8; } }
@media (prefers-reduced-motion: reduce) { .library-skeleton { animation: none; } }
@media (max-width: 760px) {