From b08a7918da5fba9f7c411cacf242bbbd5d891c59 Mon Sep 17 00:00:00 2001 From: ludan <251918489@qq.com> Date: Thu, 4 Jun 2026 09:40:28 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=E5=89=A7=E6=9C=AC=E8=AF=84?= =?UTF-8?q?=E5=88=86=E5=B7=A6=E4=BE=A7=E9=9D=A2=E6=9D=BF=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E3=80=81=E7=94=B5=E5=95=86=E5=85=8B=E9=9A=86?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E7=AB=AF=E9=80=82=E9=85=8D=E3=80=81=E8=A7=86?= =?UTF-8?q?=E8=A7=89=E7=BB=86=E8=8A=82=E7=B2=BE=E4=BF=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【剧本评分左侧面板滚动重构】 - 新增 script-eval-v5-left-main 滚动容器,上传区/AI信息/历史记录统一在容器内滚动 - 底部操作按钮(开始评测/导出报告)独立于滚动区外,始终可见可点击 - 历史评测列表增加 max-height 限制,超出区域内置滚动条 - 自定义窄滚动条(品牌绿半透明 thumb),保持视觉干净 - 短视口(≤760px/820px)压缩上传区和历史列表最小高度 【剧本评分视觉精修】 - 左侧面板增加渐变背景层次与分区微光分割线 - 上传区增加 ::after 伪元素径向光晕,hover 时品牌绿边框增强 - 已上传状态上传区增加绿色边框高亮(is-ready/is-complete) - 底部操作栏背景层次加深,导出按钮 hover 增加绿色反馈 - 右侧面板增加底部径向渐变,上传引导卡标题提亮 - 顶部状态栏背景加深,模糊效果增强 【电商克隆移动端适配增强】 - 900px/620px/480px 三级断点增加顶部预留空间,避免与导航重叠 - Logo 区域定位从 sticky 改为 static,避免滚动时遮挡内容 - 设置面板在窄屏下调整内边距与边距 【Token 用量页精简】 - 移除指标卡片序号角标,保持卡片视觉简洁 --- .../script-tokens/ScriptTokensPage.tsx | 192 ++++++------ src/features/script-tokens/TokenUsagePage.tsx | 3 +- src/styles/pages/ecommerce.css | 46 ++- src/styles/pages/script-tokens-v5.css | 294 ++++++++++++++++++ 4 files changed, 434 insertions(+), 101 deletions(-) diff --git a/src/features/script-tokens/ScriptTokensPage.tsx b/src/features/script-tokens/ScriptTokensPage.tsx index 4b8887b..b490d94 100644 --- a/src/features/script-tokens/ScriptTokensPage.tsx +++ b/src/features/script-tokens/ScriptTokensPage.tsx @@ -362,109 +362,111 @@ function ScriptTokensPage() {
{/* Left Panel */} diff --git a/src/features/script-tokens/TokenUsagePage.tsx b/src/features/script-tokens/TokenUsagePage.tsx index 9aa5646..085241c 100644 --- a/src/features/script-tokens/TokenUsagePage.tsx +++ b/src/features/script-tokens/TokenUsagePage.tsx @@ -277,9 +277,8 @@ function TokenUsagePage({ ) : null}
- {metricCards.map((card, index) => ( + {metricCards.map((card) => (
- {String(index + 1).padStart(2, "0")} {card.label} {card.value} {card.hint} diff --git a/src/styles/pages/ecommerce.css b/src/styles/pages/ecommerce.css index fae888d..be67177 100644 --- a/src/styles/pages/ecommerce.css +++ b/src/styles/pages/ecommerce.css @@ -8008,9 +8008,8 @@ } .product-clone-page[data-tool="clone"] .clone-ai-logo { - position: sticky; - top: 0; - z-index: 3; + position: static; + z-index: auto; margin: -18px -18px 2px; padding: 16px 18px 14px; border-bottom-color: var(--ecm-line); @@ -8513,7 +8512,7 @@ } .product-clone-page[data-tool="clone"] .clone-ai-logo { - margin: -14px -14px 0; + margin: 0; padding: 14px 54px 12px 14px; } @@ -8792,3 +8791,42 @@ padding-top: 14px; } } + +/* Mobile clone header alignment: keep the tool title in normal flow, but attach it to the top nav rhythm. */ +@media (max-width: 900px) { + .product-clone-page[data-tool="clone"] { + padding-top: 59px; + } + + .product-clone-page[data-tool="clone"] > .product-clone-shell { + min-height: calc(100% - 59px); + } + + .product-clone-page[data-tool="clone"] .clone-ai-panel { + padding-top: 0; + } + + .product-clone-page[data-tool="clone"] .clone-ai-logo { + margin: 0 -18px 2px; + } +} + +@media (max-width: 620px) { + .product-clone-page[data-tool="clone"] .clone-ai-panel { + padding: 0 14px 14px; + } + + .product-clone-page[data-tool="clone"] .clone-ai-logo { + margin: 0 -14px 0; + } +} + +@media (max-width: 480px) { + .product-clone-page[data-tool="clone"] { + padding-top: 59px; + } + + .product-clone-page[data-tool="clone"] > .product-clone-shell { + min-height: calc(100% - 59px); + } +} diff --git a/src/styles/pages/script-tokens-v5.css b/src/styles/pages/script-tokens-v5.css index 932c360..4114e1c 100644 --- a/src/styles/pages/script-tokens-v5.css +++ b/src/styles/pages/script-tokens-v5.css @@ -3421,3 +3421,297 @@ font-size: 13px; } } + +/* Script review left panel overflow guard: keep actions available while history remains scrollable. */ +.script-eval-v5-left { + overflow: hidden; +} + +.script-eval-v5-left-main { + display: flex; + flex: 1 1 auto; + flex-direction: column; + min-height: 0; + overflow-x: hidden; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: rgb(0 255 136 / 35%) transparent; +} + +.script-eval-v5-left-main::-webkit-scrollbar, +.script-eval-v5-history-list::-webkit-scrollbar { + width: 6px; +} + +.script-eval-v5-left-main::-webkit-scrollbar-track, +.script-eval-v5-history-list::-webkit-scrollbar-track { + background: transparent; +} + +.script-eval-v5-left-main::-webkit-scrollbar-thumb, +.script-eval-v5-history-list::-webkit-scrollbar-thumb { + border-radius: 999px; + background: rgb(0 255 136 / 28%); +} + +.script-eval-v5-left-main .script-eval-v5-lp-section.is-fill { + flex: 0 0 auto; + min-height: 210px; +} + +.script-eval-v5-left-main .script-eval-v5-history-list { + min-height: 128px; + max-height: clamp(160px, 28vh, 300px); + overflow-y: auto; +} + +.script-eval-v5-lp-bottom { + position: static; + z-index: auto; + flex-shrink: 0; + margin-top: 0; +} + +@media (max-height: 820px) and (min-width: 901px) { + .script-eval-v5-left-main .script-eval-v5-lp-section.is-fill { + flex-basis: auto; + min-height: 190px; + } + + .script-eval-v5-left-main .script-eval-v5-history-list { + min-height: 118px; + max-height: clamp(142px, 23vh, 220px); + } +} + +@media (max-width: 900px) { + .script-eval-v5-left-main { + overscroll-behavior: contain; + } +} + +@media (max-width: 680px) { + .script-eval-v5-left { + overflow: visible; + } + + .script-eval-v5-left-main { + flex: 0 0 auto; + overflow: visible; + } + + .script-eval-v5-left-main .script-eval-v5-lp-section.is-fill { + min-height: 224px; + } + + .script-eval-v5-left-main .script-eval-v5-history-list { + min-height: 132px; + max-height: min(260px, 42vh); + } + + .script-eval-v5-history-empty { + min-height: 118px; + } +} + +/* Final commercial polish for the script scoring workspace. */ +.script-eval-v5 { + background: + radial-gradient(circle at 12% 0%, rgb(0 255 136 / 5%), transparent 28%), + linear-gradient(180deg, #0d1010 0%, #090b0b 100%); +} + +.script-eval-v5-page { + background: + linear-gradient(90deg, rgb(0 255 136 / 4%), transparent 24%), + linear-gradient(180deg, rgb(255 255 255 / 1.8%), transparent 180px); +} + +.script-eval-v5-left { + background: + linear-gradient(180deg, rgb(255 255 255 / 4%), transparent 180px), + linear-gradient(90deg, rgb(0 255 136 / 4%), transparent 32%), + var(--v5-panel); +} + +.script-eval-v5-left-main { + scroll-padding-block: 18px; +} + +.script-eval-v5-left-main .script-eval-v5-lp-section { + flex-shrink: 0; + padding-inline: 22px; + background: + linear-gradient(180deg, rgb(255 255 255 / 1.8%), transparent 80px); +} + +.script-eval-v5-left-main .script-eval-v5-lp-section + .script-eval-v5-lp-section { + box-shadow: inset 0 1px 0 rgb(255 255 255 / 2.5%); +} + +.script-eval-v5-lp-label { + color: #91a09b; +} + +.script-eval-v5-upload-zone { + display: grid; + place-items: center; + overflow: hidden; + isolation: isolate; +} + +.script-eval-v5-upload-zone::after { + content: ""; + position: absolute; + inset: 1px; + z-index: -1; + border-radius: inherit; + background: + radial-gradient(circle at 50% 18%, rgb(0 255 136 / 11%), transparent 38%), + linear-gradient(180deg, rgb(255 255 255 / 2%), transparent 60%); + opacity: 0.78; + pointer-events: none; +} + +.script-eval-v5-upload-zone:focus-visible { + outline: 2px solid rgb(0 255 136 / 42%); + outline-offset: 3px; +} + +.script-eval-v5.is-ready .script-eval-v5-upload-zone, +.script-eval-v5.is-complete .script-eval-v5-upload-zone { + border-color: rgb(0 255 136 / 28%); + background: + linear-gradient(180deg, rgb(0 255 136 / 8%), rgb(255 255 255 / 2.5%)), + rgb(255 255 255 / 2.8%); +} + +.script-eval-v5-upload-done { + width: min(100%, 320px); + padding: 14px 14px; + box-shadow: inset 0 1px 0 rgb(255 255 255 / 8%); +} + +.script-eval-v5-info-grid { + display: grid; + grid-template-columns: 1fr; +} + +.script-eval-v5-info-item { + min-height: 42px; + box-shadow: inset 0 1px 0 rgb(255 255 255 / 3%); +} + +.script-eval-v5-info-empty, +.script-eval-v5-history-empty { + color: #82918c; + background: + linear-gradient(180deg, rgb(255 255 255 / 3.2%), rgb(255 255 255 / 1.8%)); +} + +.script-eval-v5-left-main .script-eval-v5-lp-section.is-fill { + background: + linear-gradient(180deg, rgb(0 255 136 / 3.4%), transparent 92px), + linear-gradient(180deg, rgb(255 255 255 / 1.8%), transparent); +} + +.script-eval-v5-history-list { + padding: 2px 8px 2px 0; +} + +.script-eval-v5-history-item { + min-height: 68px; + box-shadow: inset 0 1px 0 rgb(255 255 255 / 3%); +} + +.script-eval-v5-lp-bottom { + padding: 18px 22px 22px; + background: + linear-gradient(180deg, rgb(255 255 255 / 2.2%), transparent 60px), + #111414; + box-shadow: inset 0 1px 0 rgb(255 255 255 / 3.5%); +} + +.script-eval-v5-export-btn { + border-color: rgb(255 255 255 / 7%); + background: + linear-gradient(180deg, rgb(255 255 255 / 3.5%), rgb(255 255 255 / 1.8%)), + #111414; + color: #7f8d88; +} + +.script-eval-v5-export-btn:not(:disabled):hover { + border-color: rgb(0 255 136 / 22%); + color: #c7d5d0; + background: + linear-gradient(180deg, rgb(0 255 136 / 8%), rgb(255 255 255 / 2%)), + #111414; +} + +.script-eval-v5-eval-btn:disabled, +.script-eval-v5-export-btn:disabled { + opacity: 0.48; + cursor: not-allowed; +} + +.script-eval-v5-right-topbar { + backdrop-filter: blur(14px); + background: + linear-gradient(180deg, rgb(18 22 21 / 92%), rgb(12 14 14 / 88%)); +} + +.script-eval-v5-right-content:not(.is-report) { + background: + radial-gradient(circle at 50% 43%, rgb(0 255 136 / 5%), transparent 32%), + linear-gradient(180deg, transparent, rgb(0 0 0 / 12%)); +} + +.script-eval-v5-upload-card-title { + color: #f0fff8; +} + +.script-eval-v5-upload-card-desc { + max-width: 540px; + color: #96a5a0; +} + +.script-eval-v5-statusbar { + background: + linear-gradient(180deg, rgb(17 20 20 / 84%), rgb(10 12 12 / 92%)); +} + +@media (max-height: 760px) and (min-width: 901px) { + .script-eval-v5-left-main .script-eval-v5-lp-section { + padding-block: 12px; + } + + .script-eval-v5-upload-zone { + min-height: 156px; + } + + .script-eval-v5-left-main .script-eval-v5-lp-section.is-fill { + min-height: 176px; + } + + .script-eval-v5-left-main .script-eval-v5-history-list { + min-height: 110px; + } +} + +@media (max-width: 680px) { + .script-eval-v5-left-main .script-eval-v5-lp-section { + padding-inline: 16px; + } + + .script-eval-v5-upload-zone { + min-height: 164px; + } + + .script-eval-v5-lp-bottom { + padding: 14px 16px 18px; + } + + .script-eval-v5-right-content:not(.is-report) { + padding-top: 22px; + } +} From fb4011bf1f21584243f2ce6232d317f7fceeac2a Mon Sep 17 00:00:00 2001 From: ludan <251918489@qq.com> Date: Thu, 4 Jun 2026 13:16:38 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=E4=B8=AA=E4=BA=BA=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E8=A7=86=E8=A7=89=E9=87=8D=E6=9E=84=E3=80=81=E7=94=BB?= =?UTF-8?q?=E5=B8=83=E7=BD=91=E7=82=B9=E8=83=8C=E6=99=AF=E3=80=81=E5=89=A7?= =?UTF-8?q?=E6=9C=AC=E8=AF=84=E5=88=86=E8=89=B2=E8=B0=83=E7=BB=9F=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【个人中心视觉重构】 - 列表卡片新增媒体预览缩略图(图片/视频/项目/资产),支持 image/video 两种媒体类型 - 新增 renderCardPreview 通用预览组件,自动识别视频格式并渲染
diff --git a/src/styles/pages/script-tokens-v5.css b/src/styles/pages/script-tokens-v5.css index 4114e1c..f8d25db 100644 --- a/src/styles/pages/script-tokens-v5.css +++ b/src/styles/pages/script-tokens-v5.css @@ -3715,3 +3715,217 @@ padding-top: 22px; } } + +/* Ecommerce-aligned tone pass: restrained dark SaaS surfaces, no depth shadows. */ +.script-eval-v5 { + --v5-bg: #0d0d0f; + --v5-bg2: #151719; + --v5-bg3: #181b1d; + --v5-bg4: #1d2022; + --v5-bg5: #222629; + --v5-border: rgba(255, 255, 255, 0.08); + --v5-border2: rgba(255, 255, 255, 0.12); + --v5-panel: #151719; + --v5-panel-2: #181b1d; + --v5-panel-3: #101214; + --v5-line: rgba(255, 255, 255, 0.08); + --v5-line-strong: rgba(0, 255, 136, 0.24); + --v5-green-deep: rgba(0, 255, 136, 0.055); + --v5-green-soft: rgba(0, 255, 136, 0.09); + --v5-green-border: rgba(0, 255, 136, 0.24); + --v5-shadow-soft: none; + --v5-shadow-tight: none; + background: + radial-gradient(circle at 24% 0%, rgba(0, 255, 136, 0.038), transparent 34%), + linear-gradient(180deg, rgba(255, 255, 255, 0.018), transparent 160px), + var(--v5-bg); +} + +.script-eval-v5-page { + background: + linear-gradient(90deg, rgba(255, 255, 255, 0.014), transparent 24%, transparent 76%, rgba(255, 255, 255, 0.012)), + transparent; +} + +.script-eval-v5-left, +.script-eval-v5-right { + background: var(--v5-panel); + box-shadow: none; +} + +.script-eval-v5-left { + border-right-color: var(--v5-line); +} + +.script-eval-v5-left-main .script-eval-v5-lp-section, +.script-eval-v5-left-main .script-eval-v5-lp-section.is-fill { + background: transparent; + border-bottom-color: var(--v5-line); + box-shadow: none; +} + +.script-eval-v5-lp-label { + color: #a7b3af; + letter-spacing: 0.02em; +} + +.script-eval-v5-lp-label::before { + background: var(--v5-green); + box-shadow: none; + opacity: 0.72; +} + +.script-eval-v5-upload-zone, +.script-eval-v5-info-empty, +.script-eval-v5-history-empty, +.script-eval-v5-info-item, +.script-eval-v5-history-item, +.script-eval-v5-loading, +.script-eval-v5-illustration-hit, +.script-eval-report__score-block, +.script-eval-report__chart-card, +.script-eval-report__path-card, +.script-eval-report__finding-group p { + border-color: var(--v5-line); + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.032), transparent 58%), + var(--v5-panel-2); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.025); +} + +.script-eval-v5-upload-zone { + border-style: dashed; +} + +.script-eval-v5-upload-zone::after { + display: none; +} + +.script-eval-v5-upload-zone:hover, +.script-eval-v5-upload-zone:focus-visible, +.script-eval-v5.is-ready .script-eval-v5-upload-zone, +.script-eval-v5.is-complete .script-eval-v5-upload-zone { + border-color: var(--v5-green-border); + background: + radial-gradient(circle at 50% 0%, rgba(0, 255, 136, 0.075), transparent 58%), + var(--v5-panel-3); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.028); +} + +.script-eval-v5-upload-icon, +.script-eval-v5-upload-card-icon { + border-color: rgba(0, 255, 136, 0.18); + border-radius: 10px; + background: rgba(0, 255, 136, 0.09); + box-shadow: none; +} + +.script-eval-v5-upload-btn, +.script-eval-v5-eval-btn { + background: var(--v5-green); + color: #061014; + box-shadow: none; +} + +.script-eval-v5-upload-btn:hover, +.script-eval-v5-eval-btn:hover:not(:disabled) { + background: var(--v5-green-dim); + transform: none; + box-shadow: none; +} + +.script-eval-v5-upload-done, +.script-eval-v5-history-item.is-active, +.script-eval-v5-error, +.script-eval-report__chart-note, +.script-eval-report__grade { + box-shadow: none; +} + +.script-eval-v5-upload-done { + border-color: var(--v5-green-border); + background: + linear-gradient(180deg, rgba(0, 255, 136, 0.085), rgba(0, 255, 136, 0.035)), + var(--v5-panel-2); +} + +.script-eval-v5-history-item:hover { + border-color: rgba(255, 255, 255, 0.13); + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.045), transparent 58%), + var(--v5-panel-2); + transform: none; + box-shadow: none; +} + +.script-eval-v5-history-item.is-active { + border-color: var(--v5-green-border); + background: + linear-gradient(90deg, rgba(0, 255, 136, 0.08), rgba(0, 255, 136, 0.025)), + var(--v5-panel-2); +} + +.script-eval-v5-lp-bottom, +.script-eval-v5-right-topbar, +.script-eval-v5-statusbar { + background: rgba(21, 23, 25, 0.96); + border-color: var(--v5-line); + box-shadow: none; + backdrop-filter: none; +} + +.script-eval-v5-export-btn, +.script-eval-v5-action-btn, +.script-eval-v5-retry-btn { + border-color: var(--v5-line); + background: rgba(255, 255, 255, 0.035); + color: #aeb8b1; + box-shadow: none; +} + +.script-eval-v5-export-btn:hover:not(:disabled), +.script-eval-v5-action-btn:hover, +.script-eval-v5-retry-btn:hover { + border-color: var(--v5-green-border); + background: rgba(0, 255, 136, 0.07); + color: #d9fff0; +} + +.script-eval-v5-right-content:not(.is-report) { + background: + radial-gradient(circle at 50% 0%, rgba(0, 255, 136, 0.034), transparent 44%), + transparent; +} + +.script-eval-v5-illustration-hit:hover, +.script-eval-v5-illustration-hit:focus-visible { + background: + linear-gradient(180deg, rgba(0, 255, 136, 0.06), transparent 58%), + var(--v5-panel-2); + box-shadow: none; +} + +.script-eval-report { + --report-bg: #0d0d0f; + --report-panel: #151719; + --report-panel-2: #101214; + --report-row: #181b1d; + --report-border: rgba(255, 255, 255, 0.08); + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.018), transparent 180px), + var(--report-bg); +} + +.script-eval-report::before, +.script-eval-report::after { + opacity: 0.28; +} + +.script-eval-report__bar-fill { + box-shadow: none; +} + +.script-eval-v5.is-complete .script-eval-v5-status-dot, +.script-eval-v5.is-ready .script-eval-v5-status-dot { + box-shadow: none; +} diff --git a/src/styles/themes/dark-green.css b/src/styles/themes/dark-green.css index 84993ce..d8b7e40 100644 --- a/src/styles/themes/dark-green.css +++ b/src/styles/themes/dark-green.css @@ -6849,6 +6849,649 @@ } } +/* Profile center: responsive workspace refinement. */ +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard { + background: + linear-gradient(180deg, rgba(var(--accent-rgb), 0.035), transparent 220px), + var(--dg-page); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__banner { + height: clamp(156px, 18vw, 214px); + background: + linear-gradient(135deg, rgba(var(--accent-rgb), 0.1), transparent 36%), + linear-gradient(180deg, rgba(255, 255, 255, 0.035), transparent), + var(--bg-surface); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__banner-overlay { + background: + linear-gradient(180deg, rgba(13, 13, 15, 0.12), rgba(13, 13, 15, 0.72)), + linear-gradient(90deg, rgba(13, 13, 15, 0.68), transparent 42%); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__body { + grid-template-columns: minmax(270px, 300px) minmax(0, 1fr); + gap: clamp(18px, 2.4vw, 30px); + width: min(1180px, calc(100% - 48px)); + min-height: auto; + margin-top: -58px; + padding-bottom: clamp(36px, 5vw, 64px); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__sidebar, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__account-card, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__main-tabs, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__section, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__review-item, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__empty-state, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__upload-card { + border-color: rgba(255, 255, 255, 0.075); + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.026), transparent), + rgba(21, 23, 25, 0.96); + box-shadow: none; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__sidebar { + gap: 16px; + padding: clamp(16px, 2vw, 22px); + border-radius: var(--radius-md); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__avatar-ring::before { + opacity: 0.45; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__avatar-ring .profile-page__avatar, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__avatar { + width: 82px; + height: 82px; + border-width: 3px; + box-shadow: none; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__avatar-edit { + width: 82px; + height: 82px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__avatar-badge { + box-shadow: none; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__username { + font-size: clamp(19px, 1.7vw, 22px); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__bio-display, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__bio { + border-color: rgba(255, 255, 255, 0.07); + background: rgba(255, 255, 255, 0.024); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__bio-display span { + text-align: left; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__counts { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 8px; + padding: 0; + border: 0; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__count { + min-width: 0; + padding: 12px 8px; + border: 1px solid rgba(255, 255, 255, 0.065); + border-radius: var(--radius-sm); + background: rgba(255, 255, 255, 0.024); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__count strong { + font-size: clamp(18px, 1.5vw, 22px); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__account-card { + display: grid; + gap: 10px; + width: 100%; + padding: 11px; + border: 1px solid rgba(255, 255, 255, 0.075); + border-radius: var(--radius-sm); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__account-card .profile-page__list-tabs { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + width: 100%; + padding: 3px; + border-color: rgba(255, 255, 255, 0.06); + background: rgba(255, 255, 255, 0.02); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__account-card .profile-page__list-tabs button { + min-width: 0; + min-height: 30px; + padding: 0 8px; + overflow: hidden; + font-size: 12px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__account-card .profile-page__upload-card--meta { + grid-template-columns: 1fr; + gap: 8px; + padding: 0; + border: 0; + background: transparent; + box-shadow: none; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__account-card .profile-page__meta-item { + min-height: auto; + padding: 10px 11px; + background: rgba(255, 255, 255, 0.022); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__account-card .profile-page__meta-item strong { + font-size: 15px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__share-btn { + min-height: 42px; + border-radius: 10px; + font-size: 13px; + font-weight: 650; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__share-btn:hover { + transform: none; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__share-btn--primary { + background: var(--accent); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__share-btn--secondary { + border-color: rgba(255, 255, 255, 0.08); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__main { + gap: 16px; + min-width: 0; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__main-tabs { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 6px; + min-height: 50px; + margin: 0; + padding: 5px; + border-radius: var(--radius-md); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__main-tabs button { + min-width: 0; + min-height: 40px; + padding: 0 12px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__section { + display: grid; + gap: 14px; + padding: clamp(14px, 1.8vw, 18px); + border: 1px solid rgba(255, 255, 255, 0.075); + border-radius: var(--radius-md); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__section-label { + display: flex; + align-items: center; + gap: 8px; + color: var(--fg-body); + font-size: 15px; + font-weight: 700; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__section-label::before { + content: ""; + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--accent); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-grid, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__review-list { + gap: 12px; + max-height: none; + overflow: visible; + padding-right: 0; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-grid { + grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__review-list { + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card { + min-height: 128px; + padding: 15px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card { + grid-template-columns: 92px minmax(0, 1fr); + align-items: stretch; + gap: 12px; + min-height: 116px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-preview { + position: relative; + display: flex; + align-items: center; + justify-content: center; + min-width: 0; + min-height: 88px; + overflow: hidden; + border: 1px solid rgba(255, 255, 255, 0.065); + border-radius: 10px; + background: + linear-gradient(135deg, rgba(var(--accent-rgb), 0.055), transparent 64%), + rgba(255, 255, 255, 0.024); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-preview:not(.has-media) { + border-color: rgba(255, 255, 255, 0.07); + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.035), transparent), + rgba(255, 255, 255, 0.018); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-preview img, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-preview video { + width: 100%; + height: 100%; + min-height: 88px; + object-fit: cover; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-placeholder { + display: inline-flex; + align-items: center; + justify-content: center; + width: 38px; + height: 38px; + border: 1px solid rgba(var(--accent-rgb), 0.18); + border-radius: 12px; + background: rgba(var(--accent-rgb), 0.07); + color: rgba(var(--accent-rgb), 0.92); + font-size: 16px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-badge { + position: absolute; + top: 7px; + right: 7px; + max-width: calc(100% - 14px); + overflow: hidden; + padding: 3px 7px; + border-radius: 999px; + border: 1px solid rgba(var(--accent-rgb), 0.22); + background: rgba(8, 14, 12, 0.76); + color: var(--accent); + font-size: 10px; + font-weight: 700; + line-height: 1; + text-overflow: ellipsis; + white-space: nowrap; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-head { + gap: 8px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-head strong { + min-width: 0; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__delete-project { + flex: 0 0 26px; + width: 26px; + height: 26px; + margin: -3px -2px 0 0; + border: 1px solid rgba(255, 255, 255, 0.075); + border-radius: 8px; + background: rgba(255, 255, 255, 0.026); + color: var(--fg-soft); + opacity: 0.72; + transition: border-color var(--transition-fast), background var(--transition-fast), color var(--transition-fast), opacity var(--transition-fast); +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__delete-project:hover, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__delete-project:focus-visible { + border-color: rgba(255, 118, 118, 0.28); + background: rgba(255, 118, 118, 0.08); + color: #ff9a9d; + opacity: 1; + outline: none; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-body { + display: grid; + align-content: start; + gap: 8px; + min-width: 0; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card:hover, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__review-item:hover { + border-color: rgba(var(--accent-rgb), 0.28); + transform: none; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__empty-state { + min-height: 240px; + padding: clamp(30px, 4vw, 46px) 24px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-bar { + margin-bottom: 0; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-tabs { + width: fit-content; + max-width: 100%; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-tabs button { + white-space: nowrap; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__upload-card--meta { + grid-template-columns: repeat(2, minmax(0, 1fr)); + padding: 12px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__meta-item { + min-height: 78px; +} + +@media (max-width: 960px) { + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__body { + grid-template-columns: 1fr; + width: min(760px, calc(100% - 36px)); + margin-top: -44px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__sidebar { + display: grid; + grid-template-columns: minmax(0, 1.2fr) minmax(220px, 0.8fr); + align-items: start; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__sidebar-head { + grid-row: span 5; + align-items: flex-start; + text-align: left; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__counts { + align-self: stretch; + } +} + +@media (max-width: 640px) { + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__banner { + height: 140px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__body { + width: min(100% - 28px, 560px); + margin-top: -30px; + padding-bottom: 84px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__sidebar { + display: flex; + gap: 12px; + padding: 16px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__sidebar-head { + align-items: center; + text-align: center; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__avatar-ring .profile-page__avatar, + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__avatar { + width: 72px; + height: 72px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__avatar-edit { + width: 72px; + height: 72px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__counts { + gap: 6px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__count { + padding: 10px 6px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__main-tabs { + display: flex; + overflow-x: auto; + scrollbar-width: none; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__main-tabs::-webkit-scrollbar { + display: none; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__main-tabs button { + flex: 0 0 auto; + min-width: 88px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__section { + padding: 14px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-grid, + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__review-list { + grid-template-columns: 1fr; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card { + min-height: 118px; + padding: 13px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card { + grid-template-columns: 88px minmax(0, 1fr); + gap: 10px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-preview, + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-preview img, + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-preview video { + min-height: 82px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-head { + align-items: center; + flex-direction: row; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__upload-card--meta { + grid-template-columns: 1fr; + } +} + +@media (max-width: 420px) { + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__body { + width: min(100% - 20px, 420px); + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__counts { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__share-btn { + min-height: 40px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card { + grid-template-columns: 78px minmax(0, 1fr); + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-preview, + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-preview img, + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__list-card-preview video { + min-height: 76px; + } +} + +/* Profile center: lock media card rhythm for dense libraries. */ +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card { + grid-template-columns: 92px minmax(0, 1fr); + height: 126px; + min-height: 126px; + max-height: 126px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-preview { + width: 92px; + height: 96px; + min-height: 96px; + max-height: 96px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-preview img, +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-preview video { + height: 96px; + min-height: 96px; + max-height: 96px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-body { + display: grid; + grid-template-rows: 18px 36px 18px; + align-content: space-between; + gap: 8px; + height: 96px; + min-height: 96px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-head { + min-height: 18px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-head strong { + display: block; + width: 100%; + line-height: 1.25; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card p { + min-height: 36px; + max-height: 36px; + line-height: 1.5; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-meta { + align-self: end; + min-height: 18px; +} + +.web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-meta span:last-child { + color: var(--fg-soft); +} + +@media (max-width: 640px) { + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card { + grid-template-columns: 88px minmax(0, 1fr); + height: 112px; + min-height: 112px; + max-height: 112px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-preview { + width: 88px; + height: 86px; + min-height: 86px; + max-height: 86px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-preview img, + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-preview video { + height: 86px; + min-height: 86px; + max-height: 86px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-body { + grid-template-rows: 16px 32px 16px; + gap: 6px; + height: 86px; + min-height: 86px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card p { + min-height: 32px; + max-height: 32px; + line-height: 1.45; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-meta { + min-height: 16px; + } +} + +@media (max-width: 420px) { + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card { + grid-template-columns: 78px minmax(0, 1fr); + height: 104px; + min-height: 104px; + max-height: 104px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-preview { + width: 78px; + height: 78px; + min-height: 78px; + max-height: 78px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-preview img, + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-preview video { + height: 78px; + min-height: 78px; + max-height: 78px; + } + + .web-shell[data-ui-theme="dark-green"] .profile-page--dashboard .profile-page__media-card .profile-page__list-card-body { + height: 78px; + min-height: 78px; + } +} + /* Ecommerce generation page: keep its carousel and composer independent from the community carousel rules that share class names. */ .web-shell[data-ui-theme="dark-green"] .ecommerce-landing-page { @@ -8948,18 +9591,23 @@ /* Canvas SaaS polish: refined production-tool surfaces without changing canvas behavior. */ .web-shell[data-ui-theme="dark-green"][data-view="canvas"] .canvas-page .studio-canvas { - background: + background-image: radial-gradient(circle at 18% 8%, rgba(var(--accent-rgb), 0.055), transparent 30%), radial-gradient(circle at 72% 88%, rgba(255, 255, 255, 0.035), transparent 28%), - linear-gradient(rgba(255, 255, 255, 0.026) 1px, transparent 1px), - linear-gradient(90deg, rgba(255, 255, 255, 0.026) 1px, transparent 1px), - var(--dg-page); + radial-gradient( + circle, + rgba(148, 163, 184, 0.34) 0 var(--canvas-bg-dot, 1.35px), + transparent calc(var(--canvas-bg-dot, 1.35px) + 0.55px) + ); + background-color: var(--dg-page); + background-position: + center, + center, + var(--canvas-bg-x, 0px) var(--canvas-bg-y, 0px); background-size: auto, auto, - 24px 24px, - 24px 24px, - auto; + var(--canvas-bg-size, 24px) var(--canvas-bg-size, 24px); color: var(--fg-body); } From c4ef9cc6bade39ec6727323d4c4b3fc68ad4a6bc Mon Sep 17 00:00:00 2001 From: ludan <251918489@qq.com> Date: Thu, 4 Jun 2026 16:23:43 +0800 Subject: [PATCH 3/6] Merge origin/master: resolve CSS conflicts script-tokens-v5.css: keep both SaaS polish rules and master's additions dark-green.css: keep both profile/canvas polish and master's additions --- src/styles/pages/script-tokens-v5.css | 2 -- src/styles/themes/dark-green.css | 4 ---- 2 files changed, 6 deletions(-) diff --git a/src/styles/pages/script-tokens-v5.css b/src/styles/pages/script-tokens-v5.css index f13933a..f8d25db 100644 --- a/src/styles/pages/script-tokens-v5.css +++ b/src/styles/pages/script-tokens-v5.css @@ -2649,7 +2649,6 @@ min-height: 52px; } } -<<<<<<< ours /* ===== Commercial SaaS polish for script review page ===== */ .script-eval-v5 { @@ -3930,4 +3929,3 @@ .script-eval-v5.is-ready .script-eval-v5-status-dot { box-shadow: none; } ->>>>>>> theirs diff --git a/src/styles/themes/dark-green.css b/src/styles/themes/dark-green.css index 8b743ba..ce421cd 100644 --- a/src/styles/themes/dark-green.css +++ b/src/styles/themes/dark-green.css @@ -6089,7 +6089,6 @@ box-shadow: none; } -<<<<<<< ours .web-shell[data-ui-theme="dark-green"] .profile-page__meta-item small { overflow: hidden; color: var(--fg-soft); @@ -8397,7 +8396,6 @@ .web-shell[data-ui-theme="dark-green"] .canvas-page .studio-canvas-node-resize-handle::before, .web-shell[data-ui-theme="dark-green"] .canvas-page .studio-canvas-node-resize-handle::after { background: var(--dg-button-text); ->>>>>>> theirs } .web-shell[data-ui-theme="dark-green"] .canvas-page .studio-canvas-save-asset { @@ -8797,7 +8795,6 @@ } } -<<<<<<< ours /* Ecommerce final polish: keep selected option states refined in the dark-green theme. */ .web-shell[data-ui-theme="dark-green"][data-view="ecommerce"] .product-clone-page[data-tool="clone"] :is( .clone-ai-module-list button, @@ -8917,7 +8914,6 @@ --commerce-panel: #151719; --commerce-soft: #101214; background: #0d0d0f; ->>>>>>> theirs } .web-shell[data-ui-theme="dark-green"] .omni-commerce-panel, From e8a42dafde6eb5417b866769e1dc5fd29e37a568 Mon Sep 17 00:00:00 2001 From: ludan <251918489@qq.com> Date: Thu, 4 Jun 2026 16:29:38 +0800 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=86=B2=E7=AA=81=E5=AF=BC=E8=87=B4=E7=9A=84CSS=E6=9C=AA?= =?UTF-8?q?=E9=97=AD=E5=90=88=E8=8A=B1=E6=8B=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/themes/dark-green.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/styles/themes/dark-green.css b/src/styles/themes/dark-green.css index ce421cd..bcf25f0 100644 --- a/src/styles/themes/dark-green.css +++ b/src/styles/themes/dark-green.css @@ -8393,6 +8393,8 @@ .web-shell[data-ui-theme="dark-green"][data-view="workbench"] .ai-workbench-page.is-active .ai-chat-messages-surface { padding-top: 86px; } +} + .web-shell[data-ui-theme="dark-green"] .canvas-page .studio-canvas-node-resize-handle::before, .web-shell[data-ui-theme="dark-green"] .canvas-page .studio-canvas-node-resize-handle::after { background: var(--dg-button-text); @@ -8907,6 +8909,8 @@ .web-shell[data-ui-theme="dark-green"][data-view="canvas"] .studio-canvas-project-bar__status, .web-shell[data-ui-theme="dark-green"][data-view="canvas"] .studio-canvas-project-bar__autosave-status { color: var(--fg-muted); +} + .web-shell[data-ui-theme="dark-green"] .omni-commerce-page { --commerce-ink: #f3f5f2; --commerce-muted: #aeb8b1; From b81128d7cadef68649ae094efe3aaf19b66b39d5 Mon Sep 17 00:00:00 2001 From: Stringadmin Date: Thu, 4 Jun 2026 18:27:12 +0800 Subject: [PATCH 5/6] fix: harden ecommerce media history for launch --- scripts/smoke-generation-mocked.mjs | 72 +++++++ src/api/keyServerClient.ts | 4 +- .../ecommerce/ecommerceVideoService.ts | 179 +++++++++++++++++- 3 files changed, 244 insertions(+), 11 deletions(-) create mode 100644 scripts/smoke-generation-mocked.mjs diff --git a/scripts/smoke-generation-mocked.mjs b/scripts/smoke-generation-mocked.mjs new file mode 100644 index 0000000..f078568 --- /dev/null +++ b/scripts/smoke-generation-mocked.mjs @@ -0,0 +1,72 @@ +import fs from "node:fs"; +import path from "node:path"; +import process from "node:process"; + +const repoRoot = process.cwd(); +const failures = []; + +function read(relativePath) { + return fs.readFileSync(path.join(repoRoot, relativePath), "utf8"); +} + +function assertMatch(label, content, pattern) { + if (!pattern.test(content)) { + failures.push(label); + } +} + +function assertNoMatch(label, content, pattern) { + if (pattern.test(content)) { + failures.push(label); + } +} + +const serverConnection = read("src/api/serverConnection.ts"); +const generationClient = read("src/api/aiGenerationClient.ts"); +const ecommerceVideoService = read("src/features/ecommerce/ecommerceVideoService.ts"); +const workbenchPersistence = read("src/features/workbench/workbenchResultPersistence.ts"); + +assertMatch( + "serverConnection must build same-origin /api URLs", + serverConnection, + /return\s+`\/api\/\$\{cleanPath\}`;/, +); +assertNoMatch( + "frontend generation flow must not use fixed VITE environment config", + `${serverConnection}\n${generationClient}`, + /\b(?:import\.meta\.env|VITE_[A-Z0-9_]+)\b/, +); +assertNoMatch( + "frontend generation flow must not call provider hosts directly", + generationClient, + /dashscope\.aliyuncs\.com|\/dashscope-api\b|Bearer\s+sk-/i, +); +assertMatch("image generation must go through the app API", generationClient, /buildApiUrl\("ai\/image"\)/); +assertMatch("video generation must go through the app API", generationClient, /buildApiUrl\("ai\/video"\)/); +assertMatch("binary uploads must go through the app OSS API", generationClient, /buildApiUrl\("oss\/upload-binary"\)/); +assertMatch("URL uploads must go through the app OSS API", generationClient, /buildApiUrl\("oss\/upload-by-url"\)/); +assertMatch( + "ecommerce video history must durable-copy media before saving", + ecommerceVideoService, + /buildDurableVideoHistoryPayload\(payload\)/, +); +assertMatch( + "ecommerce video history must filter temporary provider URLs on read", + ecommerceVideoService, + /items:\s*history\.items\.map\(removeTemporaryHistoryUrls\)/, +); +assertMatch( + "workbench results must persist generated media through OSS", + workbenchPersistence, + /uploadAssetByUrl\(/, +); + +if (failures.length) { + console.error("Mocked generation smoke check failed:"); + for (const failure of failures) { + console.error(`- ${failure}`); + } + process.exit(1); +} + +console.log("Mocked generation smoke check passed."); diff --git a/src/api/keyServerClient.ts b/src/api/keyServerClient.ts index 1acf077..151a551 100644 --- a/src/api/keyServerClient.ts +++ b/src/api/keyServerClient.ts @@ -913,7 +913,7 @@ export const keyServerClient = { async getProjectContent(projectId: string): Promise { const stored = readStoredSession(); if (!stored) { - throw new Error("闇€瑕佸厛鐧诲綍"); + throw new Error("需要先登录"); } const safeProjectId = encodeURIComponent(projectId.trim()); @@ -1000,7 +1000,7 @@ export const keyServerClient = { async deleteProject(projectId: string, options?: DeleteProjectOptions): Promise { const stored = readStoredSession(); if (!stored) { - throw new Error("闇€瑕佸厛鐧诲綍"); + throw new Error("需要先登录"); } const path = options?.cleanupUserData ? `projects/${encodeURIComponent(projectId)}?cleanupUserData=1` : `projects/${encodeURIComponent(projectId)}`; diff --git a/src/features/ecommerce/ecommerceVideoService.ts b/src/features/ecommerce/ecommerceVideoService.ts index 7f85cfa..d3d304a 100644 --- a/src/features/ecommerce/ecommerceVideoService.ts +++ b/src/features/ecommerce/ecommerceVideoService.ts @@ -19,6 +19,102 @@ import type { PlanStep, } from "./ecommerceVideoTypes"; +type UploadAssetByUrl = typeof aiGenerationClient.uploadAssetByUrl; + +interface DurableMediaUrl { + url: string | null; + originalUrl?: string | null; + ossKey?: string | null; +} + +const TEMP_MEDIA_HOST_RE = /^file\d*\.aitohumanize\.com$/i; +const OSS_MEDIA_HOST_RE = /\.oss-[^.]+\.aliyuncs\.com$/i; + +function isTemporaryProviderUrl(url: string): boolean { + try { + return TEMP_MEDIA_HOST_RE.test(new URL(url).hostname); + } catch { + return false; + } +} + +function isDurableOssUrl(url: string): boolean { + try { + const parsed = new URL(url); + return parsed.protocol === "https:" && OSS_MEDIA_HOST_RE.test(parsed.hostname); + } catch { + return false; + } +} + +function getMediaExtension(url: string, mimeType: string): string { + const normalizedMime = mimeType.split(";")[0]?.trim().toLowerCase(); + if (normalizedMime === "image/jpeg") return "jpg"; + if (normalizedMime === "image/png") return "png"; + if (normalizedMime === "image/webp") return "webp"; + if (normalizedMime === "image/gif") return "gif"; + if (normalizedMime === "video/mp4") return "mp4"; + if (normalizedMime === "video/webm") return "webm"; + if (normalizedMime === "video/quicktime") return "mov"; + + try { + const matched = new URL(url).pathname.match(/\.([a-z0-9]{2,5})$/i); + if (matched?.[1]) return matched[1].toLowerCase(); + } catch { + // Keep mime fallback below. + } + + return mimeType.startsWith("video/") ? "mp4" : "png"; +} + +function buildDurableMediaName(prefix: string, url: string, mimeType: string): string { + const normalized = prefix + .trim() + .replace(/[\\/:*?"<>|]+/g, "-") + .replace(/\s+/g, " ") + .slice(0, 80) + .trim(); + return `${normalized || "ecommerce-video-media"}.${getMediaExtension(url, mimeType)}`; +} + +export async function resolveDurableMediaUrl( + url: string | null | undefined, + options: { + mediaType: "image" | "video"; + namePrefix: string; + scope?: string; + uploadAssetByUrl?: UploadAssetByUrl; + }, +): Promise { + const sourceUrl = String(url || "").trim(); + if (!sourceUrl) return { url: null }; + if (isDurableOssUrl(sourceUrl)) return { url: sourceUrl }; + + const mimeType = options.mediaType === "video" ? "video/mp4" : "image/png"; + const uploadAssetByUrl = options.uploadAssetByUrl || aiGenerationClient.uploadAssetByUrl.bind(aiGenerationClient); + + try { + const uploaded = await uploadAssetByUrl({ + sourceUrl, + name: buildDurableMediaName(options.namePrefix, sourceUrl, mimeType), + mimeType, + scope: options.scope || "ecommerce-video-history", + }); + return { + url: uploaded.url || null, + originalUrl: sourceUrl, + ossKey: uploaded.ossKey || null, + }; + } catch (error) { + const message = error instanceof Error ? error.message : String(error || ""); + console.warn("[ecommerce-video] history media persistence failed:", message); + if (isTemporaryProviderUrl(sourceUrl)) { + return { url: null, originalUrl: sourceUrl }; + } + return { url: sourceUrl }; + } +} + export interface PlanCallbacks { onStepStart: (step: PlanStep) => void; onStepDone: (step: PlanStep) => void; @@ -268,6 +364,15 @@ export interface VideoHistoryScene { videoUrl?: string | null; } +interface SaveVideoHistoryPayload { + title: string; + config: Record; + plan: Record; + scenes: VideoHistoryScene[]; + sourceImageUrls: string[]; + uploadAssetByUrl?: UploadAssetByUrl; +} + export interface VideoHistoryItem { id: number; title: string; @@ -293,22 +398,74 @@ function getAuthHeaders(): Record { return token ? { Authorization: `Bearer ${token}` } : {}; } -export async function saveVideoHistory(payload: { - title: string; - config: Record; - plan: Record; - scenes: VideoHistoryScene[]; - sourceImageUrls: string[]; -}): Promise<{ id: number; createdAt: string }> { +export async function buildDurableVideoHistoryPayload(payload: SaveVideoHistoryPayload): Promise { + const uploadAssetByUrl = payload.uploadAssetByUrl; + const scenes = await Promise.all( + payload.scenes.map(async (scene) => { + const [image, video] = await Promise.all([ + resolveDurableMediaUrl(scene.imageUrl, { + mediaType: "image", + namePrefix: `ecommerce-scene-${scene.sceneId}-image`, + uploadAssetByUrl, + }), + resolveDurableMediaUrl(scene.videoUrl, { + mediaType: "video", + namePrefix: `ecommerce-scene-${scene.sceneId}-video`, + uploadAssetByUrl, + }), + ]); + return { + ...scene, + imageUrl: image.url, + videoUrl: video.url, + }; + }), + ); + + const sourceImageUrls = ( + await Promise.all( + payload.sourceImageUrls.map((url, index) => + resolveDurableMediaUrl(url, { + mediaType: "image", + namePrefix: `ecommerce-source-${index + 1}`, + uploadAssetByUrl, + }), + ), + ) + ) + .map((item) => item.url) + .filter((url): url is string => Boolean(url)); + + return { + ...payload, + scenes, + sourceImageUrls, + }; +} + +export async function saveVideoHistory(payload: SaveVideoHistoryPayload): Promise<{ id: number; createdAt: string }> { + const { uploadAssetByUrl: _uploadAssetByUrl, ...historyPayload } = await buildDurableVideoHistoryPayload(payload); const res = await fetch(API_BASE, { method: "POST", headers: { "Content-Type": "application/json", ...getAuthHeaders() }, - body: JSON.stringify(payload), + body: JSON.stringify(historyPayload), }); if (!res.ok) throw new Error("保存历史记录失败"); return res.json(); } +function removeTemporaryHistoryUrls(item: VideoHistoryItem): VideoHistoryItem { + return { + ...item, + scenes: item.scenes.map((scene) => ({ + ...scene, + imageUrl: scene.imageUrl && !isTemporaryProviderUrl(scene.imageUrl) ? scene.imageUrl : null, + videoUrl: scene.videoUrl && !isTemporaryProviderUrl(scene.videoUrl) ? scene.videoUrl : null, + })), + sourceImageUrls: item.sourceImageUrls.filter((url) => !isTemporaryProviderUrl(url)), + }; +} + export async function fetchVideoHistory( limit = 20, offset = 0, @@ -318,7 +475,11 @@ export async function fetchVideoHistory( { headers: getAuthHeaders() }, ); if (!res.ok) throw new Error("获取历史记录失败"); - return res.json(); + const history = (await res.json()) as VideoHistoryListResponse; + return { + ...history, + items: history.items.map(removeTemporaryHistoryUrls), + }; } export async function deleteVideoHistory(id: number): Promise { From 3493f169c02f2d1ba77dbd40b197f1d99da1ded4 Mon Sep 17 00:00:00 2001 From: Stringadmin Date: Thu, 4 Jun 2026 19:00:50 +0800 Subject: [PATCH 6/6] fix: use public model config and disable source maps --- src/api/modelCapabilitiesClient.ts | 2 +- vite.config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/modelCapabilitiesClient.ts b/src/api/modelCapabilitiesClient.ts index 85b0f8b..33ce1f4 100644 --- a/src/api/modelCapabilitiesClient.ts +++ b/src/api/modelCapabilitiesClient.ts @@ -71,7 +71,7 @@ export const modelCapabilitiesClient = { let payload: unknown; try { - payload = await serverRequest(`config/profile?name=${encodeURIComponent(name)}`); + payload = await serverRequest(`public/config/profile?name=${encodeURIComponent(name)}`); } catch (error) { if (isOptionalApiRouteMissing(error)) { modelCapabilitiesRouteMissing = true; diff --git a/vite.config.ts b/vite.config.ts index 5dea423..49aaa45 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -25,7 +25,7 @@ export default defineConfig(() => ({ drop: ["console", "debugger"], }, build: { - sourcemap: "hidden", + sourcemap: false, rollupOptions: { output: { manualChunks(id: string) {