2 Commits

Author SHA1 Message Date
ludan 5811cbac16 feat: refactor ecommerce toolbar from mode tabs to scenario-based tabs with rich template cards
- EcommercePage.tsx:
  - Introduce CommerceScenarioKey type (popular/poster/mainImage/scene/festival/model/background/retouch/salesVideo) and CommerceScenarioTemplate interface with scenario/output/desc/badge fields
  - Add commerceScenarioOptions (9 scenario tabs with icons) replacing cloneOutputOptions as toolbar data source; each scenario maps to an output mode via commerceScenarioOutputMap
  - Add commerceScenarioTemplates (16 templates across 8 scenarios) with thumbnail, badge, title, and description; popularCommerceScenarioTemplates aggregates cross-scenario highlights for the "热门" default tab
  - Replace activeCloneTemplateCards with activeCommerceScenarioTemplates filtered by scenario; popular tab shows highlights, others show scenario-specific templates
  - handleCommerceScenarioClick: switch scenario, auto-toggle output mode, toggle template strip visibility; clicking active scenario toggles strip; popular tab preserves current output
  - handleCloneTemplateCardClick: auto-switch output mode to match template, fill prompt, focus textarea with 80ms delayed re-focus for reliability
  - Template card markup upgraded: media thumbnail (94px cover image with hover scale), body with badge pill, title, and 2-line description
  - Active scenario button shows close indicator (CloseOutlined) when strip is open
  - Template strip defaults to visible (isCloneTemplateStripVisible initial true)
  - Add "左右滑动查看更多" scroll hint for narrow viewports
- ecommerce-standalone.css (+355 lines):
  - Scenario tabs: horizontal flex scroll with hidden scrollbar, pill-shaped buttons (grid: 24px icon + fluid label), per-scenario color accent via --mode-accent custom property (pink for popular, orange for poster/festival, green for mainImage/scene/background, blue for model/retouch/salesVideo)
  - Active/open states: radial gradient glow, lifted shadow, intensified border color
  - Icon slot: 24px rounded square with tinted background and inset highlight
  - Close indicator: absolute top-right circle with hover scale
  - Template cards: 2-column grid (94px media + fluid body), badge capsule, thumbnail with hover scale(1.035), title 820 weight, 2-line description clamp
  - Responsive: ≤1024px 2-col card grid, ≤900px scroll-hint visible + left-aligned tabs, ≤640px horizontal scroll cards with snap, compact card sizing
2026-06-16 19:11:50 +08:00
stringadmin 3469071819 Merge pull request 'Main merge work' (#19) from main-merge-work into main
Reviewed-on: #19
2026-06-16 06:38:21 +00:00
2 changed files with 589 additions and 118 deletions
+234 -118
View File
@@ -272,6 +272,7 @@ interface ProductClonePageProps {
type ProductCloneStatus = "idle" | "ready" | "generating" | "done" | "failed";
type ProductSetOutputKey = "set" | "detail" | "model" | "video";
type CloneOutputKey = ProductSetOutputKey | "hot";
type CommerceScenarioKey = "popular" | "poster" | "mainImage" | "scene" | "festival" | "model" | "background" | "retouch" | "salesVideo";
type CloneSetCountKey = "selling" | "white" | "scene";
type CloneModelPanelTab = "scene" | "model";
type CloneVideoQualityKey = "standard" | "high" | "ultra";
@@ -288,6 +289,12 @@ type CloneTemplateAsset = {
prompt: string;
mediaUrl: string;
};
interface CommerceScenarioTemplate extends CloneTemplateAsset {
scenario: Exclude<CommerceScenarioKey, "popular">;
output: ProductSetOutputKey;
desc: string;
badge: string;
}
type TryOnModelSource = "ai" | "library";
type TryOnStatus = "idle" | "modeling" | "ready" | "generating" | "done" | "failed";
type DetailStatus = "idle" | "ready" | "generating" | "done" | "failed";
@@ -1037,112 +1044,193 @@ const productSetOutputOptions: Array<{ key: ProductSetOutputKey; label: string;
const cloneOutputOptions: Array<{ key: ProductSetOutputKey; label: string; desc: string; icon: ReactNode }> = [
...productSetOutputOptions,
];
const cloneTemplateCards: Record<Exclude<CloneOutputKey, "hot">, CloneTemplateAsset[]> = {
set: [
{
id: "set-main",
title: "商品套图主图",
prompt: "生成一组统一风格的商品套图,包含主图、卖点图、场景图和细节图,主体清晰,色调统一,符合电商平台展示规范。",
mediaUrl: ossAssets.ecommerce.productSet.main,
},
{
id: "set-scene",
title: "商品套图场景",
prompt: "生成生活化场景商品套图,突出商品在真实环境中的使用感、氛围感和转化卖点。",
mediaUrl: ossAssets.ecommerce.productSet.scene,
},
{
id: "set-detail",
title: "商品套图细节",
prompt: "生成突出材质、工艺和边缘细节的商品套图,画面干净,信息聚焦,适合电商详情展示。",
mediaUrl: ossAssets.ecommerce.productSet.detail,
},
{
id: "set-selling",
title: "商品套图卖点",
prompt: "生成强调核心卖点和对比优势的商品套图,信息层级清晰,适合列表页和转化场景。",
mediaUrl: ossAssets.ecommerce.productSet.selling,
},
],
detail: [
{
id: "detail-hero",
title: "详情图头图",
prompt: "生成适用于 A+ 详情页的头图模块,突出品牌感、主卖点和视觉中心,版式清晰高级。",
mediaUrl: ossAssets.ecommerce.detail.longPage,
},
{
id: "detail-grid-a",
title: "详情图模块 A",
prompt: "生成模块化详情长图,重点展示产品卖点、功能说明和适用场景,适合滚动阅读。",
mediaUrl: ossAssets.ecommerce.detail.gridA,
},
{
id: "detail-grid-b",
title: "详情图模块 B",
prompt: "生成模块化详情长图,强化材质、规格和使用说明,视觉简洁,信息明确。",
mediaUrl: ossAssets.ecommerce.detail.gridB,
},
{
id: "detail-grid-c",
title: "详情图模块 C",
prompt: "生成模块化详情页内容,突出品牌叙事、细节拆解和购买理由,保持统一排版。",
mediaUrl: ossAssets.ecommerce.detail.gridC,
},
],
model: [
{
id: "model-dress-a",
title: "模特图穿搭 A",
prompt: "生成真人模特穿搭展示图,突出服装版型、上身效果和整体气质,姿态自然。",
mediaUrl: ossAssets.ecommerce.tryOn.dressA,
},
{
id: "model-dress-b",
title: "模特图穿搭 B",
prompt: "生成适合商品展示的模特图,强调衣型、垂感和真实穿着效果,画面干净。",
mediaUrl: ossAssets.ecommerce.tryOn.dressB,
},
{
id: "model-woman",
title: "模特图女模",
prompt: "生成自然站姿的女模特展示图,适合服饰、配件和穿搭类商品展示。",
mediaUrl: ossAssets.ecommerce.tryOn.modelWoman,
},
{
id: "model-man",
title: "模特图男模",
prompt: "生成真实感更强的男模特展示图,突出上身效果、轮廓和场景氛围。",
mediaUrl: ossAssets.ecommerce.tryOn.modelMan,
},
],
video: [
{
id: "video-hook",
title: "短视频开场",
prompt: "生成适合电商短视频的开场镜头,节奏明确,第一秒就突出产品和核心看点。",
mediaUrl: ossAssets.ecommerce.inspiration.tiktokPreference,
},
{
id: "video-scene",
title: "短视频场景",
prompt: "生成生活化使用场景的短视频分镜,画面连贯,围绕商品使用过程展开。",
mediaUrl: ossAssets.ecommerce.inspiration.officeStyleSet,
},
{
id: "video-review",
title: "短视频口播",
prompt: "生成适合口播讲解的电商短视频结构,包含产品亮点、卖点说明和收尾引导。",
mediaUrl: ossAssets.ecommerce.inspiration.asinListing,
},
{
id: "video-conversion",
title: "短视频转化",
prompt: "生成以转化为目标的短视频分镜,强化开头钩子、卖点展示和行动引导。",
mediaUrl: ossAssets.ecommerce.inspiration.competitorListing,
},
],
const commerceScenarioOptions: Array<{ key: CommerceScenarioKey; label: string; desc: string; icon: ReactNode }> = [
{ key: "popular", label: "热门", desc: "高频模板", icon: <FireOutlined /> },
{ key: "poster", label: "海报生成", desc: "活动视觉", icon: <LayoutOutlined /> },
{ key: "mainImage", label: "商品主图", desc: "主图转化", icon: <FileImageOutlined /> },
{ key: "scene", label: "场景图", desc: "生活氛围", icon: <AppstoreOutlined /> },
{ key: "festival", label: "节日风格图", desc: "节点营销", icon: <GlobalOutlined /> },
{ key: "model", label: "模特图", desc: "真人展示", icon: <SkinOutlined /> },
{ key: "background", label: "更换背景", desc: "背景重构", icon: <ClearOutlined /> },
{ key: "retouch", label: "无痕改图", desc: "精修优化", icon: <EditOutlined /> },
{ key: "salesVideo", label: "带货视频", desc: "短视频脚本", icon: <VideoCameraOutlined /> },
];
const commerceScenarioOutputMap: Record<Exclude<CommerceScenarioKey, "popular">, ProductSetOutputKey> = {
poster: "set",
mainImage: "set",
scene: "set",
festival: "set",
model: "model",
background: "set",
retouch: "set",
salesVideo: "video",
};
const commerceScenarioTemplates: CommerceScenarioTemplate[] = [
{
id: "poster-campaign-clean",
scenario: "poster",
output: "set",
title: "新品活动海报",
desc: "适合首发、上新、促销专题的主视觉",
badge: "高频推荐",
prompt: "帮我生成一张电商新品活动海报,突出产品主体、核心卖点和促销氛围,画面干净高级,适合店铺首页和广告投放。",
mediaUrl: ossAssets.ecommerce.detail.longPage,
},
{
id: "poster-social-drop",
scenario: "poster",
output: "set",
title: "社媒种草海报",
desc: "更适合小红书、朋友圈、站外广告",
badge: "热门模板",
prompt: "生成一张社媒种草风格商品海报,突出产品质感、生活方式和一句清晰卖点,画面轻盈、有品牌感。",
mediaUrl: ossAssets.ecommerce.inspiration.officeStyleSet,
},
{
id: "main-clean-product",
scenario: "mainImage",
output: "set",
title: "高转化商品主图",
desc: "白底/浅场景,主体清楚,卖点明确",
badge: "高频推荐",
prompt: "生成一张高转化商品主图,产品主体居中清晰,背景简洁,突出核心卖点和材质细节,适合电商搜索列表展示。",
mediaUrl: ossAssets.ecommerce.productSet.main,
},
{
id: "main-selling-point",
scenario: "mainImage",
output: "set",
title: "卖点强化主图",
desc: "适合列表点击率优化",
badge: "点击率优先",
prompt: "生成一张卖点强化商品主图,保留产品真实质感,加入清晰卖点表达和轻量信息层级,适合提升列表点击率。",
mediaUrl: ossAssets.ecommerce.productSet.selling,
},
{
id: "scene-lifestyle",
scenario: "scene",
output: "set",
title: "生活方式场景图",
desc: "把商品放进真实使用环境",
badge: "高频推荐",
prompt: "生成生活方式商品场景图,把产品自然放入真实使用环境,突出使用感、氛围和购买理由,画面真实且商业化。",
mediaUrl: ossAssets.ecommerce.productSet.scene,
},
{
id: "scene-premium",
scenario: "scene",
output: "set",
title: "高级质感场景",
desc: "适合品牌调性和详情页氛围图",
badge: "品牌感",
prompt: "生成高级质感商品场景图,背景克制、光影柔和,突出产品材质、轮廓和品牌调性,适合详情页和广告素材。",
mediaUrl: ossAssets.ecommerce.detail.gridA,
},
{
id: "festival-seasonal",
scenario: "festival",
output: "set",
title: "节日营销图",
desc: "适合大促、节庆、节点活动",
badge: "节点营销",
prompt: "生成节日营销风格商品图,结合节日氛围和促销视觉,但保持产品主体清晰、信息不过载,适合电商活动投放。",
mediaUrl: ossAssets.ecommerce.detail.gridB,
},
{
id: "festival-gift",
scenario: "festival",
output: "set",
title: "礼赠氛围图",
desc: "适合礼盒、礼品、节日送礼场景",
badge: "热门模板",
prompt: "生成礼赠氛围商品图,突出节日送礼感、包装质感和温暖情绪,画面高级克制,适合活动页与社媒投放。",
mediaUrl: ossAssets.ecommerce.detail.gridC,
},
{
id: "model-natural-fit",
scenario: "model",
output: "model",
title: "自然穿搭模特图",
desc: "突出上身效果、版型和真实穿着",
badge: "高频推荐",
prompt: "生成自然穿搭模特图,突出服饰上身效果、版型和整体气质,模特姿态自然,适合服饰电商详情与主图展示。",
mediaUrl: ossAssets.ecommerce.tryOn.dressA,
},
{
id: "model-street",
scenario: "model",
output: "model",
title: "街拍模特场景",
desc: "更适合年轻化、生活方式品牌",
badge: "风格推荐",
prompt: "生成街拍风格模特图,模特自然展示商品,背景有生活气息,突出穿搭氛围、比例和品牌调性。",
mediaUrl: ossAssets.ecommerce.tryOn.modelWoman,
},
{
id: "background-clean",
scenario: "background",
output: "set",
title: "商品换浅色背景",
desc: "保留主体,重构干净商业背景",
badge: "高频推荐",
prompt: "为商品更换干净浅色商业背景,保留产品主体、边缘和材质细节,整体画面适合电商主图和广告素材。",
mediaUrl: ossAssets.ecommerce.productSet.detail,
},
{
id: "background-scene",
scenario: "background",
output: "set",
title: "商品换场景背景",
desc: "从普通拍摄变成真实使用场景",
badge: "场景增强",
prompt: "为商品更换真实使用场景背景,保持主体比例和边缘自然,增强生活化氛围和商业转化感。",
mediaUrl: ossAssets.ecommerce.productSet.scene,
},
{
id: "retouch-clean",
scenario: "retouch",
output: "set",
title: "白底精修图",
desc: "修正瑕疵、增强质感和边缘细节",
badge: "高频推荐",
prompt: "对商品图进行无痕精修,清理瑕疵、优化光影和边缘细节,保持商品真实结构,输出干净高级的电商图。",
mediaUrl: ossAssets.ecommerce.productSet.main,
},
{
id: "retouch-premium",
scenario: "retouch",
output: "set",
title: "质感增强图",
desc: "强化材质、反光和商品高级感",
badge: "精修模板",
prompt: "对商品图进行质感增强,强化材质、光泽、纹理和立体感,画面自然不过度修饰,适合商业广告素材。",
mediaUrl: ossAssets.ecommerce.productSet.selling,
},
{
id: "sales-video-hook",
scenario: "salesVideo",
output: "video",
title: "带货视频开场",
desc: "第一秒抓住注意力,快速进入卖点",
badge: "高频推荐",
prompt: "生成电商带货短视频脚本和分镜,第一秒突出产品和痛点,随后展示核心卖点、使用场景和行动引导。",
mediaUrl: ossAssets.ecommerce.inspiration.tiktokPreference,
},
{
id: "sales-video-demo",
scenario: "salesVideo",
output: "video",
title: "使用演示视频",
desc: "适合讲解型、种草型短视频",
badge: "转化优先",
prompt: "生成商品使用演示短视频分镜,围绕使用过程、关键卖点和效果对比展开,节奏清晰,适合带货转化。",
mediaUrl: ossAssets.ecommerce.inspiration.asinListing,
},
];
const popularCommerceScenarioTemplates = commerceScenarioOptions
.filter((option): option is { key: Exclude<CommerceScenarioKey, "popular">; label: string; desc: string; icon: ReactNode } => option.key !== "popular")
.map((option) => commerceScenarioTemplates.find((template) => template.scenario === option.key))
.filter((template): template is CommerceScenarioTemplate => Boolean(template));
const cloneSetCountOptions: Array<{
key: CloneSetCountKey;
title: string;
@@ -1660,8 +1748,9 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
const [imageWorkbenchResultUrl, setImageWorkbenchResultUrl] = useState<string | null>(null);
const [imageWorkbenchProgress, setImageWorkbenchProgress] = useState(0);
const [isProductUploadDragging, setIsProductUploadDragging] = useState(false);
const [activeCommerceScenario, setActiveCommerceScenario] = useState<CommerceScenarioKey>("popular");
const [cloneOutput, setCloneOutput] = useState<CloneOutputKey>(defaultCloneOutput);
const [isCloneTemplateStripVisible, setIsCloneTemplateStripVisible] = useState(false);
const [isCloneTemplateStripVisible, setIsCloneTemplateStripVisible] = useState(true);
const [videoHistoryVisible, setVideoHistoryVisible] = useState(false);
const [isVideoWorkspaceVisible, setIsVideoWorkspaceVisible] = useState(false);
const [videoPlanTrigger, setVideoPlanTrigger] = useState(0);
@@ -2165,7 +2254,9 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
const selectedProductSetOutput =
productSetOutputOptions.find((option) => option.key === productSetOutput) ?? productSetOutputOptions[0]!;
const selectedCloneOutput = cloneOutputOptions.find((option) => option.key === cloneOutput) ?? cloneOutputOptions[1]!;
const activeCloneTemplateCards = cloneTemplateCards[cloneOutput === "hot" ? "set" : cloneOutput];
const activeCommerceScenarioTemplates = activeCommerceScenario === "popular"
? popularCommerceScenarioTemplates
: commerceScenarioTemplates.filter((template) => template.scenario === activeCommerceScenario);
const cloneRequirementPlaceholder =
cloneOutput === "model"
? "建议包含以下信息:产品名称、核心卖点、期望场景、模特外貌描述(如小麦色皮肤、齐刘海、眼角有泪痣)、具体参数"
@@ -3559,13 +3650,18 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
);
};
const handleCloneModeTabClick = (nextOutput: CloneOutputKey) => {
if (nextOutput === cloneOutput) {
const handleCommerceScenarioClick = (nextScenario: CommerceScenarioKey) => {
if (nextScenario === activeCommerceScenario) {
setIsCloneTemplateStripVisible((visible) => !visible);
setComposerMenu(null);
return;
}
handleCloneOutputChange(nextOutput);
setActiveCommerceScenario(nextScenario);
setIsCloneTemplateStripVisible(true);
setComposerMenu(null);
if (nextScenario === "popular") return;
const mappedOutput = commerceScenarioOutputMap[nextScenario];
if (mappedOutput !== cloneOutput) handleCloneOutputChange(mappedOutput);
};
const handleCloneMarketChange = (nextMarket: string) => {
@@ -5608,6 +5704,12 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
textarea.setSelectionRange(nextValue.length, nextValue.length);
textarea.scrollIntoView({ behavior: "smooth", block: "center" });
}
window.setTimeout(() => {
const latestTextarea = requirementTextareaRef.current;
if (!latestTextarea) return;
latestTextarea.focus();
latestTextarea.setSelectionRange(nextValue.length, nextValue.length);
}, 80);
});
};
@@ -5643,7 +5745,10 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
}
};
const handleCloneTemplateCardClick = (card: CloneTemplateAsset) => {
const handleCloneTemplateCardClick = (card: CommerceScenarioTemplate) => {
if (card.output !== cloneOutput) handleCloneOutputChange(card.output);
setIsCloneTemplateStripVisible(true);
setComposerMenu(null);
void addTemplateImageToComposer(card);
applyComposerPrompt(card.prompt);
};
@@ -5980,19 +6085,23 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
onChange={handleSmartCutoutUpload}
aria-label="上传智能抠图素材"
/>
<div className="ecom-command-mode-tabs" aria-label="生成模式">
{cloneOutputOptions.map((option) => (
<div className="ecom-command-mode-tabs ecom-command-scenario-tabs" aria-label="电商场景">
{commerceScenarioOptions.map((option) => (
<button
key={option.key}
type="button"
className={cloneOutput === option.key ? "is-active" : ""}
onClick={() => handleCloneModeTabClick(option.key)}
className={`${activeCommerceScenario === option.key ? "is-active" : ""}${activeCommerceScenario === option.key && isCloneTemplateStripVisible ? " is-open" : ""}`}
onClick={() => handleCommerceScenarioClick(option.key)}
>
<span className={`ecom-command-mode-icon ecom-command-mode-icon--${option.key}`} aria-hidden="true">{option.icon}</span>
<strong>{option.label}</strong>
{activeCommerceScenario === option.key && isCloneTemplateStripVisible ? (
<span className="ecom-command-scenario-close" aria-hidden="true"><CloseOutlined /></span>
) : null}
</button>
))}
</div>
<span className="ecom-command-scenario-scroll-hint" aria-hidden="true"></span>
<div className="clone-ai-input-wrapper ecom-command-composer">
{productImages.length ? (
<div className="ecom-command-asset-popover" aria-label={`已上传素材,${productImages.length}/${maxCloneProductImages}`}>
@@ -6086,8 +6195,8 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
{renderComposerMenu()}
</div>
{(status === "idle" || status === "ready") && !showMainVideoWorkspace && isCloneTemplateStripVisible ? (
<section className={`ecom-command-template-strip ecom-command-template-strip--${cloneOutput}`} aria-label="模板卡片">
{activeCloneTemplateCards.map((card) => (
<section className={`ecom-command-template-strip ecom-command-template-strip--${activeCommerceScenario}`} aria-label="模板卡片">
{activeCommerceScenarioTemplates.map((card) => (
<button
key={card.id}
type="button"
@@ -6099,7 +6208,14 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
handleCloneTemplateCardClick(card);
}}
>
<span className="ecom-command-template-card__blank" aria-hidden="true" />
<span className="ecom-command-template-card__media" aria-hidden="true">
<img src={card.mediaUrl} alt="" loading="lazy" />
</span>
<span className="ecom-command-template-card__body">
<span className="ecom-command-template-card__badge">{card.badge}</span>
<strong>{card.title}</strong>
<em>{card.desc}</em>
</span>
</button>
))}
</section>
+355
View File
@@ -17433,3 +17433,358 @@ html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[d
margin-left: 0 !important;
}
}
/* Ecommerce home scenario templates */
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs.ecom-command-mode-tabs {
display: flex !important;
align-items: stretch !important;
justify-content: center !important;
gap: 9px !important;
width: min(100%, 1180px) !important;
margin: 0 auto 10px !important;
padding: 5px 0 !important;
overflow-x: auto !important;
scrollbar-width: none !important;
scroll-snap-type: x proximity !important;
border: 0 !important;
border-radius: 0 !important;
background: transparent !important;
box-shadow: none !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs.ecom-command-mode-tabs::-webkit-scrollbar {
display: none !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs.ecom-command-mode-tabs button {
--mode-accent: #1073cc;
position: relative !important;
display: grid !important;
grid-template-columns: 24px minmax(0, 1fr) !important;
grid-template-rows: auto !important;
align-items: center !important;
justify-items: start !important;
gap: 8px !important;
flex: 0 0 auto !important;
width: auto !important;
min-width: 104px !important;
min-height: 40px !important;
padding: 7px 12px !important;
scroll-snap-align: start !important;
border: 1px solid rgba(16, 32, 44, 0.07) !important;
border-radius: 20px !important;
background: rgba(255, 255, 255, 0.6) !important;
color: rgba(16, 32, 44, 0.68) !important;
box-shadow:
0 2px 6px rgba(16, 32, 44, 0.03),
inset 0 1px 0 rgba(255, 255, 255, 0.92) !important;
text-align: left !important;
cursor: pointer !important;
transition:
background 180ms ease,
border-color 180ms ease,
color 180ms ease,
box-shadow 180ms ease,
transform 180ms ease !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs.ecom-command-mode-tabs button:hover {
background: rgba(255, 255, 255, 0.86) !important;
border-color: color-mix(in srgb, var(--mode-accent) 22%, transparent) !important;
color: rgba(16, 32, 44, 0.86) !important;
box-shadow:
0 8px 18px color-mix(in srgb, var(--mode-accent) 10%, transparent),
inset 0 1px 0 rgba(255, 255, 255, 0.95) !important;
transform: translateY(-1px) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs.ecom-command-mode-tabs button.is-active {
background:
radial-gradient(circle at 24% 16%, color-mix(in srgb, var(--mode-accent) 14%, transparent), transparent 54%),
rgba(255, 255, 255, 0.98) !important;
border-color: color-mix(in srgb, var(--mode-accent) 35%, transparent) !important;
color: rgba(16, 32, 44, 0.96) !important;
box-shadow:
0 10px 24px color-mix(in srgb, var(--mode-accent) 14%, transparent),
inset 0 1px 0 rgba(255, 255, 255, 0.98) !important;
transform: translateY(-1px) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs.ecom-command-mode-tabs button.is-open {
background:
radial-gradient(circle at 24% 16%, color-mix(in srgb, var(--mode-accent) 18%, transparent), transparent 50%),
rgba(255, 255, 255, 1) !important;
border-color: color-mix(in srgb, var(--mode-accent) 45%, transparent) !important;
box-shadow:
0 12px 28px color-mix(in srgb, var(--mode-accent) 16%, transparent),
inset 0 1px 0 rgba(255, 255, 255, 1) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs.ecom-command-mode-tabs button:focus-visible {
outline: 2px solid color-mix(in srgb, var(--mode-accent) 45%, transparent) !important;
outline-offset: 2px !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs .ecom-command-mode-icon {
grid-row: auto !important;
display: inline-grid !important;
width: 24px !important;
min-width: 24px !important;
height: 24px !important;
place-items: center !important;
border: 0 !important;
border-radius: 8px !important;
background: color-mix(in srgb, var(--mode-accent) 10%, rgba(255, 255, 255, 0.9)) !important;
color: var(--mode-accent) !important;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8) !important;
font-size: 13px !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button.is-active .ecom-command-mode-icon,
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button.is-open .ecom-command-mode-icon {
background: color-mix(in srgb, var(--mode-accent) 16%, rgba(255, 255, 255, 0.95)) !important;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.9),
0 2px 6px color-mix(in srgb, var(--mode-accent) 12%, transparent) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs strong {
min-width: 0 !important;
max-width: 88px !important;
overflow: hidden !important;
color: rgba(16, 32, 44, 0.82) !important;
font-size: 12.5px !important;
font-weight: 760 !important;
letter-spacing: -0.01em !important;
line-height: 1 !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button.is-active strong,
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button.is-open strong {
color: rgba(16, 32, 44, 0.95) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs .ecom-command-scenario-close {
position: absolute !important;
top: 4px !important;
right: 4px !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
width: 15px !important;
height: 15px !important;
border-radius: 50% !important;
background: rgba(16, 32, 44, 0.05) !important;
color: rgba(16, 32, 44, 0.42) !important;
font-size: 9px !important;
transition:
background 160ms ease,
color 160ms ease,
transform 160ms ease !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs .ecom-command-scenario-close:hover {
background: rgba(16, 32, 44, 0.1) !important;
color: rgba(16, 32, 44, 0.7) !important;
transform: scale(1.08) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-scroll-hint {
display: none !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs .ecom-command-scenario-close .anticon {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
line-height: 1 !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button:has(.ecom-command-mode-icon--popular) {
--mode-accent: #c04468;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button:has(.ecom-command-mode-icon--poster),
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button:has(.ecom-command-mode-icon--festival) {
--mode-accent: #cc6b14;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button:has(.ecom-command-mode-icon--mainImage),
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button:has(.ecom-command-mode-icon--scene),
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button:has(.ecom-command-mode-icon--background) {
--mode-accent: #0f8f72;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button:has(.ecom-command-mode-icon--model),
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button:has(.ecom-command-mode-icon--retouch),
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs button:has(.ecom-command-mode-icon--salesVideo) {
--mode-accent: #1073cc;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-strip {
grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
gap: 12px !important;
width: min(100%, 1180px) !important;
margin: 16px auto 10px !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-card {
display: grid !important;
grid-template-columns: 94px minmax(0, 1fr) !important;
align-items: stretch !important;
gap: 12px !important;
aspect-ratio: auto !important;
min-height: 132px !important;
padding: 10px !important;
border-radius: 18px !important;
text-align: left !important;
background:
radial-gradient(circle at 20% 0%, rgba(30, 189, 219, 0.08), transparent 46%),
linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(247, 252, 254, 0.94)) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-card__media {
position: relative !important;
display: block !important;
width: 94px !important;
min-width: 94px !important;
height: 112px !important;
overflow: hidden !important;
border: 1px solid rgba(30, 189, 219, 0.14) !important;
border-radius: 14px !important;
background: rgba(232, 249, 253, 0.6) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-card__media img {
display: block !important;
width: 100% !important;
height: 100% !important;
object-fit: cover !important;
transition: transform 220ms ease !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-card:hover .ecom-command-template-card__media img {
transform: scale(1.035) !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-card__body {
display: grid !important;
align-content: center !important;
gap: 7px !important;
min-width: 0 !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-card__badge {
justify-self: start !important;
max-width: 100% !important;
padding: 4px 8px !important;
overflow: hidden !important;
border-radius: 999px !important;
background: rgba(232, 249, 253, 0.9) !important;
color: #0f829b !important;
font-size: 10px !important;
font-weight: 760 !important;
line-height: 1 !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-card__body strong {
min-width: 0 !important;
overflow: hidden !important;
color: #10202c !important;
font-size: 15px !important;
font-weight: 820 !important;
line-height: 1.25 !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-card__body em {
display: -webkit-box !important;
min-width: 0 !important;
overflow: hidden !important;
color: rgba(85, 111, 126, 0.78) !important;
font-size: 12px !important;
font-style: normal !important;
font-weight: 620 !important;
line-height: 1.45 !important;
-webkit-line-clamp: 2 !important;
-webkit-box-orient: vertical !important;
}
@media (max-width: 1024px) {
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-strip {
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}
}
@media (max-width: 900px) {
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs.ecom-command-mode-tabs {
justify-content: flex-start !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-scroll-hint {
display: block !important;
width: min(100%, 1180px) !important;
margin: -4px auto 6px !important;
text-align: center !important;
font-size: 11px !important;
font-weight: 480 !important;
line-height: 1 !important;
color: rgba(16, 32, 44, 0.36) !important;
}
}
@media (max-width: 640px) {
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs.ecom-command-mode-tabs {
width: 100% !important;
margin-bottom: 8px !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs.ecom-command-mode-tabs button {
min-width: 112px !important;
min-height: 44px !important;
padding: 7px 10px !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs .ecom-command-mode-icon {
width: 24px !important;
min-width: 24px !important;
height: 24px !important;
font-size: 13px !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-scenario-tabs strong {
font-size: 12px !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-strip {
display: flex !important;
gap: 10px !important;
width: 100% !important;
margin-top: 12px !important;
overflow-x: auto !important;
scrollbar-width: none !important;
scroll-snap-type: x mandatory !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-strip::-webkit-scrollbar {
display: none !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-card {
grid-template-columns: 84px minmax(0, 1fr) !important;
flex: 0 0 min(86vw, 360px) !important;
min-height: 118px !important;
scroll-snap-align: start !important;
}
html body #root .ecommerce-standalone.ecommerce-standalone .product-clone-page[data-tool="clone"][data-tool="clone"]:not(.is-history-detail) .ecom-command-template-card__media {
width: 84px !important;
min-width: 84px !important;
height: 98px !important;
}
}