Merge remote-tracking branch 'origin/master' into codex/generation-task-reliability
|
After Width: | Height: | Size: 393 KiB |
|
After Width: | Height: | Size: 512 KiB |
|
After Width: | Height: | Size: 525 KiB |
|
After Width: | Height: | Size: 674 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 400 KiB |
|
After Width: | Height: | Size: 473 KiB |
|
After Width: | Height: | Size: 499 KiB |
|
After Width: | Height: | Size: 685 KiB |
@@ -199,7 +199,7 @@ function createWorkflowFromResult(payload: WorkbenchResultActionPayload): WebCan
|
||||
description: payload.prompt || "从生成结果进入画布继续创作。",
|
||||
source: "blank",
|
||||
settings: {
|
||||
model: payload.resultType === "video" ? "Seedance 2.0" : "Nano Banana Pro",
|
||||
model: payload.resultType === "video" ? "Seedance 2.0" : "omni-水果 Pro",
|
||||
ratio: payload.resultType === "video" ? "16:9" : "1:1",
|
||||
duration: payload.resultType === "video" ? "6s" : "0s",
|
||||
resolution: payload.resultType === "video" ? "720p" : "2K",
|
||||
@@ -1011,7 +1011,7 @@ function App() {
|
||||
previewUrl: payload.resultUrl,
|
||||
params: payload.resultType === "video"
|
||||
? { model: "Kling V3 Omni", aspectRatio: "16:9", resolution: "720p", duration: "6s", videoMode: "text-to-video" }
|
||||
: { model: "Nano Banana Pro", aspectRatio: "1:1", imageSize: "2K" },
|
||||
: { model: "omni-水果 Pro", aspectRatio: "1:1", imageSize: "2K" },
|
||||
assetRef: payload.resultOssKey ? { url: payload.resultUrl, ossKey: payload.resultOssKey, mediaType: payload.resultType === "video" ? "video/mp4" : "image/png", sourceTaskId: payload.taskId } : undefined,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -481,7 +481,7 @@ function migrateLegacyWorkflowData(old: Record<string, unknown>, wrapper: Record
|
||||
description: String(wrapper.description || ""),
|
||||
source: (wrapper.source as WebCanvasWorkflow["source"]) || "blank",
|
||||
settings: {
|
||||
model: String(isRecord(old.settings) ? old.settings.model || "Nano Banana Pro" : "Nano Banana Pro"),
|
||||
model: String(isRecord(old.settings) ? old.settings.model || "omni-水果 Pro" : "omni-水果 Pro"),
|
||||
ratio: String(isRecord(old.settings) ? old.settings.ratio || "1:1" : "1:1"),
|
||||
duration: String(isRecord(old.settings) ? old.settings.duration || "0s" : "0s"),
|
||||
resolution: String(isRecord(old.settings) ? old.settings.resolution || "2K" : "2K"),
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ossAssets } from "../data/ossAssets";
|
||||
import { canManageCommunityCases, canReviewCommunity } from "../features/community-review/communityPermissions";
|
||||
import type { WebNavItem, WebNotification, WebUsageSummary, WebUserSession, WebViewKey } from "../types";
|
||||
import NotificationCenter from "./NotificationCenter";
|
||||
import BetaApplicationModal from "./BetaApplicationModal";
|
||||
import { AnimatedPanel } from "./AnimatedPanel";
|
||||
import AdminMonitor from "./AdminMonitor";
|
||||
import CookieConsentBanner from "./CookieConsentBanner";
|
||||
@@ -85,6 +86,7 @@ function AppShell({
|
||||
const [rechargeOpen, setRechargeOpen] = useState(false);
|
||||
const [RechargeModal, setRechargeModal] = useState<RechargeModalComponent | null>(null);
|
||||
const [infoOpen, setInfoOpen] = useState(false);
|
||||
const [betaOpen, setBetaOpen] = useState(false);
|
||||
const infoRef = useRef<HTMLDivElement>(null);
|
||||
const [openSubmenuKey, setOpenSubmenuKey] = useState<WebViewKey | null>(null);
|
||||
const [publicConfig, setPublicConfig] = useState<WebPublicConfig>({});
|
||||
@@ -343,6 +345,15 @@ function AppShell({
|
||||
<span className="brand-lockup__name">OmniAI</span>
|
||||
</button>
|
||||
<div className="web-topbar__actions">
|
||||
<button
|
||||
type="button"
|
||||
className="beta-apply-button"
|
||||
title="内测申请"
|
||||
aria-label="内测申请"
|
||||
onClick={() => setBetaOpen(true)}
|
||||
>
|
||||
内测申请
|
||||
</button>
|
||||
{session && (
|
||||
<NotificationCenter
|
||||
items={notifications}
|
||||
@@ -502,7 +513,7 @@ function AppShell({
|
||||
{rechargeOpen && RechargeModal ? (
|
||||
<RechargeModal open={rechargeOpen} onClose={() => setRechargeOpen(false)} currentBalance={displayedBalanceCents} />
|
||||
) : null}
|
||||
<CookieConsentBanner />
|
||||
<BetaApplicationModal open={betaOpen} onClose={() => setBetaOpen(false)} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
import { CloseOutlined, ExperimentOutlined } from "@ant-design/icons";
|
||||
import { useState } from "react";
|
||||
|
||||
interface BetaApplicationModalProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
/* ── Form state ── */
|
||||
interface BetaFormData {
|
||||
name: string;
|
||||
phone: string;
|
||||
wechat: string;
|
||||
industry: string;
|
||||
company: string;
|
||||
city: string;
|
||||
aiTools: string;
|
||||
aiDuration: string;
|
||||
aiTrack: string;
|
||||
aiDirection: string[];
|
||||
weeklyUsage: string;
|
||||
feedbackWilling: string;
|
||||
wantFeature: string[];
|
||||
selfStatement: string;
|
||||
signature: string;
|
||||
agreeRules: boolean;
|
||||
}
|
||||
|
||||
const INITIAL_FORM: BetaFormData = {
|
||||
name: "",
|
||||
phone: "",
|
||||
wechat: "",
|
||||
industry: "",
|
||||
company: "",
|
||||
city: "",
|
||||
aiTools: "",
|
||||
aiDuration: "",
|
||||
aiTrack: "",
|
||||
aiDirection: [],
|
||||
weeklyUsage: "",
|
||||
feedbackWilling: "",
|
||||
wantFeature: [],
|
||||
selfStatement: "",
|
||||
signature: "",
|
||||
agreeRules: false,
|
||||
};
|
||||
|
||||
/* ── Option groups (from the docx) ── */
|
||||
const AI_DURATION_OPTIONS = ["1年以内", "1-3年", "3-5年", "5年以上"];
|
||||
const AI_TRACK_OPTIONS = ["是,长期承接相关业务", "业余创作", "新手学习"];
|
||||
const AI_DIRECTION_OPTIONS = [
|
||||
"AI短剧批量制作", "漫剧剧情生成", "自媒体短视频", "电商图文及视频素材",
|
||||
"MCN商业内容", "企业宣传视频", "个人兴趣创作", "其他",
|
||||
];
|
||||
const WEEKLY_USAGE_OPTIONS = ["7次及以上", "1-3次", "空闲时间使用"];
|
||||
const FEEDBACK_OPTIONS = ["全力配合深度反馈", "简单体验留言", "仅使用不反馈"];
|
||||
const WANT_FEATURE_OPTIONS = [
|
||||
"一站式短剧漫剧完整AIGC工作流", "电商素材自动化创作流程",
|
||||
"多模态智能中枢全能创作", "批量自动化创作流程", "全新未公开AI创作玩法",
|
||||
];
|
||||
|
||||
/* ── Helper: single-select radio group ── */
|
||||
function RadioGroup({
|
||||
name, options, value, onChange,
|
||||
}: {
|
||||
name: string;
|
||||
options: string[];
|
||||
value: string;
|
||||
onChange: (v: string) => void;
|
||||
}) {
|
||||
return (
|
||||
<div className="beta-radio-group">
|
||||
{options.map((opt) => (
|
||||
<label key={opt} className="beta-radio">
|
||||
<input
|
||||
type="radio"
|
||||
name={name}
|
||||
checked={value === opt}
|
||||
onChange={() => onChange(opt)}
|
||||
/>
|
||||
<span>{opt}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ── Helper: multi-select checkbox group ── */
|
||||
function CheckboxGroup({
|
||||
options, value, onChange,
|
||||
}: {
|
||||
options: string[];
|
||||
value: string[];
|
||||
onChange: (v: string[]) => void;
|
||||
}) {
|
||||
return (
|
||||
<div className="beta-checkbox-group">
|
||||
{options.map((opt) => (
|
||||
<label key={opt} className="beta-checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={value.includes(opt)}
|
||||
onChange={() => {
|
||||
if (value.includes(opt)) {
|
||||
onChange(value.filter((item) => item !== opt));
|
||||
} else {
|
||||
onChange([...value, opt]);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<span>{opt}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ── Helper: text field ── */
|
||||
function TextField({
|
||||
label, value, onChange, placeholder,
|
||||
}: {
|
||||
label: string;
|
||||
value: string;
|
||||
onChange: (v: string) => void;
|
||||
placeholder?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="beta-text-field">
|
||||
<span className="beta-text-field__label">{label}</span>
|
||||
<input
|
||||
type="text"
|
||||
className="beta-text-field__input"
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
placeholder={placeholder ?? "请填写"}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const BetaApplicationModal = ({ open, onClose }: BetaApplicationModalProps) => {
|
||||
const [form, setForm] = useState<BetaFormData>(INITIAL_FORM);
|
||||
|
||||
const update = <K extends keyof BetaFormData>(key: K, value: BetaFormData[K]) => {
|
||||
setForm((prev) => ({ ...prev, [key]: value }));
|
||||
};
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
return (
|
||||
<div className="beta-application-modal" role="dialog" aria-modal="true" aria-labelledby="beta-modal-title">
|
||||
<button type="button" className="beta-application-modal__backdrop" onClick={onClose} aria-label="关闭内测申请弹窗" />
|
||||
|
||||
<section className="beta-application-modal__panel">
|
||||
{/* ── Header ── */}
|
||||
<header className="beta-modal-header">
|
||||
<div className="beta-modal-header__left">
|
||||
<ExperimentOutlined className="beta-modal-header__icon" />
|
||||
<div>
|
||||
<h2 id="beta-modal-title">OmniAI 内测体验官申请表</h2>
|
||||
<p className="beta-modal-header__subtitle">封闭限量内测 · 仅限 <strong>30 人</strong> · 赠送 <strong>500 元</strong> 通用调用积分</p>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" className="beta-modal-header__close" onClick={onClose} aria-label="关闭">
|
||||
<CloseOutlined />
|
||||
</button>
|
||||
</header>
|
||||
|
||||
{/* ── Body (scrollable document) ── */}
|
||||
<div className="beta-modal-body">
|
||||
|
||||
{/* 一、个人基础信息 */}
|
||||
<section className="beta-doc-section">
|
||||
<h3 className="beta-doc-section__title">一、个人基础信息</h3>
|
||||
<div className="beta-doc-grid">
|
||||
<TextField label="姓名 / 常用昵称" value={form.name} onChange={(v) => update("name", v)} />
|
||||
<TextField label="联系手机号码" value={form.phone} onChange={(v) => update("phone", v)} />
|
||||
<TextField label="微信账号" value={form.wechat} onChange={(v) => update("wechat", v)} />
|
||||
<TextField label="所在行业 / 职业" value={form.industry} onChange={(v) => update("industry", v)} />
|
||||
<TextField label="所属公司 / 机构" value={form.company} onChange={(v) => update("company", v)} />
|
||||
<TextField label="所在城市" value={form.city} onChange={(v) => update("city", v)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 二、AI从业与使用经历 */}
|
||||
<section className="beta-doc-section">
|
||||
<h3 className="beta-doc-section__title">二、AI 从业与使用经历</h3>
|
||||
<div className="beta-doc-grid">
|
||||
<TextField label="日常常用 AI 创作工具有哪些" value={form.aiTools} onChange={(v) => update("aiTools", v)} placeholder="例如:Midjourney / Stable Diffusion / ChatGPT 等" />
|
||||
<div className="beta-form-group">
|
||||
<span className="beta-form-group__label">AI 内容创作从业时长</span>
|
||||
<RadioGroup name="aiDuration" options={AI_DURATION_OPTIONS} value={form.aiDuration} onChange={(v) => update("aiDuration", v)} />
|
||||
</div>
|
||||
<div className="beta-form-group">
|
||||
<span className="beta-form-group__label">是否深耕 AI 短剧、漫剧、数字视频、电商赛道</span>
|
||||
<RadioGroup name="aiTrack" options={AI_TRACK_OPTIONS} value={form.aiTrack} onChange={(v) => update("aiTrack", v)} />
|
||||
</div>
|
||||
<div className="beta-form-group beta-form-group--full">
|
||||
<span className="beta-form-group__label">日常主要创作方向(可多选)</span>
|
||||
<CheckboxGroup options={AI_DIRECTION_OPTIONS} value={form.aiDirection} onChange={(v) => update("aiDirection", v)} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 三、内测使用意向调研 */}
|
||||
<section className="beta-doc-section">
|
||||
<h3 className="beta-doc-section__title">三、内测使用意向调研</h3>
|
||||
<div className="beta-doc-grid">
|
||||
<div className="beta-form-group">
|
||||
<span className="beta-form-group__label">每周可稳定登录使用内测平台次数</span>
|
||||
<RadioGroup name="weeklyUsage" options={WEEKLY_USAGE_OPTIONS} value={form.weeklyUsage} onChange={(v) => update("weeklyUsage", v)} />
|
||||
</div>
|
||||
<div className="beta-form-group">
|
||||
<span className="beta-form-group__label">是否愿意积极反馈产品 BUG、优化建议、功能需求</span>
|
||||
<RadioGroup name="feedback" options={FEEDBACK_OPTIONS} value={form.feedbackWilling} onChange={(v) => update("feedbackWilling", v)} />
|
||||
</div>
|
||||
<div className="beta-form-group beta-form-group--full">
|
||||
<span className="beta-form-group__label">本次最想体验 OmniAI 核心功能(可多选)</span>
|
||||
<CheckboxGroup options={WANT_FEATURE_OPTIONS} value={form.wantFeature} onChange={(v) => update("wantFeature", v)} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 四、申请自述 */}
|
||||
<section className="beta-doc-section">
|
||||
<h3 className="beta-doc-section__title">四、申请自述 <em className="beta-required">(必填)</em></h3>
|
||||
<p className="beta-doc-section__desc">请简述自身 AI 创作优势、业务需求,以及加入本次封闭内测的理由:</p>
|
||||
<textarea
|
||||
className="beta-textarea"
|
||||
value={form.selfStatement}
|
||||
onChange={(e) => update("selfStatement", e.target.value)}
|
||||
placeholder="请在此填写您的申请自述(必填)…"
|
||||
rows={6}
|
||||
/>
|
||||
</section>
|
||||
|
||||
{/* 五、内测规则知情同意书 */}
|
||||
<section className="beta-doc-section">
|
||||
<h3 className="beta-doc-section__title">五、内测规则知情同意书</h3>
|
||||
<ol className="beta-rules-list">
|
||||
<li>本次为封闭限量内测,仅限 <strong>30 人</strong>,按照资质匹配度 + 申请顺序筛选;</li>
|
||||
<li>内测赠送 <strong>500 元</strong> 通用调用积分,仅限内测期间使用,不可提现、不可转让、不可兑换现金;</li>
|
||||
<li>内测版本含未上线测试功能,存在功能不稳定、界面调整、参数优化等情况,申请人自愿理解包容;</li>
|
||||
<li>严禁私自泄露内测专属工作流、内部功能、测试接口、未发布技术方案等内部资料;</li>
|
||||
<li>审核通过后,官方将在 <strong>48 小时</strong> 内发放内测账号、登录权限及免费积分;</li>
|
||||
<li>正式版上线后,优质内测体验官可享受专属永久优惠权限与平台荣誉称号。</li>
|
||||
</ol>
|
||||
|
||||
<label className="beta-agree-row">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={form.agreeRules}
|
||||
onChange={(e) => update("agreeRules", e.target.checked)}
|
||||
/>
|
||||
<span>本人已完整阅读并同意以上全部内测规则,自愿遵守内测所有管理要求。</span>
|
||||
</label>
|
||||
|
||||
<div className="beta-doc-grid beta-doc-grid--two">
|
||||
<TextField label="申请人确认签字" value={form.signature} onChange={(v) => update("signature", v)} placeholder="请签署姓名" />
|
||||
<div className="beta-text-field">
|
||||
<span className="beta-text-field__label">申请填写日期</span>
|
||||
<input type="text" className="beta-text-field__input" value="2026年 月 日" readOnly />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
{/* ── Footer ── */}
|
||||
<footer className="beta-modal-footer">
|
||||
<button type="button" className="beta-modal-footer__btn beta-modal-footer__btn--secondary" onClick={onClose}>
|
||||
关闭
|
||||
</button>
|
||||
<button type="button" className="beta-modal-footer__btn beta-modal-footer__btn--primary" onClick={onClose}>
|
||||
提交申请
|
||||
</button>
|
||||
</footer>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BetaApplicationModal;
|
||||
@@ -58,13 +58,13 @@ export const defaultTextModelId = textModelOptions[0].id;
|
||||
|
||||
// --- Image model options ---
|
||||
export const imageModelOptions: CanvasOption[] = [
|
||||
{ value: "wan2.7-image", label: "wan 2.7 · 0.20 积分" },
|
||||
{ value: "wan2.7-image-pro", label: "wan 2.7 Pro · 0.20 积分" },
|
||||
{ value: "gpt-image-2", label: "GPT-Image-2 · 0.20 积分" },
|
||||
{ value: "gpt-image-2-vip", label: "GPT-Image-2 VIP · 0.20 积分" },
|
||||
{ value: "nano-banana-pro", label: "Nano Banana Pro · 0.20 积分" },
|
||||
{ value: "nano-banana-2", label: "Nano Banana 2 · 0.20 积分" },
|
||||
{ value: "nano-banana-fast", label: "Nano Banana · 0.20 积分" },
|
||||
{ value: "wan2.7-image", label: "wan 2.7" },
|
||||
{ value: "wan2.7-image-pro", label: "wan 2.7 Pro" },
|
||||
{ value: "gpt-image-2", label: "omni-GPT" },
|
||||
{ value: "gpt-image-2-vip", label: "omni-GPT VIP" },
|
||||
{ value: "nano-banana-pro", label: "omni-水果 Pro" },
|
||||
{ value: "nano-banana-2", label: "omni-水果 2" },
|
||||
{ value: "nano-banana-fast", label: "omni-水果" },
|
||||
];
|
||||
|
||||
export const imageRatioOptions: CanvasOption[] = [
|
||||
|
||||
@@ -842,6 +842,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
const skipInitialCloneAutoSaveRef = useRef(true);
|
||||
const skipNextCloneAutoSaveRef = useRef(false);
|
||||
const [activeTool, setActiveTool] = useState<ProductKitToolKey>("clone");
|
||||
useEffect(() => { setPreviewZoom(1); }, [activeTool]);
|
||||
const [setImages, setSetImages] = useState<CloneImageItem[]>([]);
|
||||
const [productSetPlatform, setProductSetPlatform] = useState(platformOptions[0]);
|
||||
const [productSetMarket, setProductSetMarket] = useState(marketOptions[0]);
|
||||
@@ -882,6 +883,30 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
const [videoOutfitRefFile, setVideoOutfitRefFile] = useState<File | null>(null);
|
||||
const [isCloneSettingsCollapsed, setIsCloneSettingsCollapsed] = useState(false);
|
||||
const [previewZoom, setPreviewZoom] = useState(1);
|
||||
|
||||
const handlePreviewWheel = (event: React.WheelEvent<HTMLElement>) => {
|
||||
if (!event.currentTarget) return;
|
||||
event.preventDefault();
|
||||
const container = event.currentTarget as HTMLElement;
|
||||
const rect = container.getBoundingClientRect();
|
||||
const cursorX = event.clientX - rect.left;
|
||||
const cursorY = event.clientY - rect.top;
|
||||
const zoomDelta = event.deltaY < 0 ? 1.08 : 0.92;
|
||||
|
||||
const nextZoom = Math.min(2, Math.max(0.25, previewZoom * zoomDelta));
|
||||
if (nextZoom === previewZoom) return;
|
||||
|
||||
const contentX = (cursorX + container.scrollLeft) / previewZoom;
|
||||
const contentY = (cursorY + container.scrollTop) / previewZoom;
|
||||
|
||||
setPreviewZoom(nextZoom);
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
container.scrollLeft = contentX * nextZoom - cursorX;
|
||||
container.scrollTop = contentY * nextZoom - cursorY;
|
||||
});
|
||||
};
|
||||
|
||||
const [requirement, setRequirement] = useState("");
|
||||
const [requirementImageMentionQuery, setRequirementImageMentionQuery] = useState<string | null>(null);
|
||||
const [cloneSettingName, setCloneSettingName] = useState("新建创作");
|
||||
@@ -2332,7 +2357,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
);
|
||||
|
||||
const setPreview = (
|
||||
<main className="product-clone-preview product-clone-preview--set" aria-label="AI商品套图预览">
|
||||
<main className="product-clone-preview product-clone-preview--set" aria-label="AI商品套图预览" onWheel={handlePreviewWheel}>
|
||||
<div className="product-clone-preview__headline">
|
||||
<h1>预览</h1>
|
||||
<p>
|
||||
@@ -2400,7 +2425,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
);
|
||||
|
||||
const clonePreview = (
|
||||
<main className="product-clone-preview clone-ai-preview" aria-label="电商AI作图预览">
|
||||
<main className="product-clone-preview clone-ai-preview" aria-label="电商AI作图预览" onWheel={handlePreviewWheel}>
|
||||
<header className="clone-ai-preview-header">
|
||||
<strong>预览</strong>
|
||||
<span>
|
||||
@@ -2610,7 +2635,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
);
|
||||
|
||||
const detailPreview = (
|
||||
<main className="product-clone-preview product-clone-preview--detail" aria-label="A+详情预览">
|
||||
<main className="product-clone-preview product-clone-preview--detail" aria-label="A+详情预览" onWheel={handlePreviewWheel}>
|
||||
<div className="product-clone-preview__headline">
|
||||
<h1>A+/详情页</h1>
|
||||
<p>
|
||||
@@ -2647,7 +2672,7 @@ function ProductClonePage(_props: ProductClonePageProps = {}) {
|
||||
);
|
||||
|
||||
const tryOnPreview = (
|
||||
<main className="product-clone-preview product-clone-preview--try-on" aria-label="服饰穿戴预览">
|
||||
<main className="product-clone-preview product-clone-preview--try-on" aria-label="服饰穿戴预览" onWheel={handlePreviewWheel}>
|
||||
<div className="product-clone-preview__headline">
|
||||
<h1>AI服饰穿戴</h1>
|
||||
<p>上传服装图,定制专属模特,即刻生成多种场景不同姿势套图。</p>
|
||||
|
||||
@@ -233,11 +233,11 @@ export const MODE_OPTIONS: WorkbenchOption[] = (Object.keys(MODE_META) as Workbe
|
||||
export const IMAGE_MODEL_OPTIONS: WorkbenchOption[] = [
|
||||
{ value: "wan2.7-image-pro", label: "wan 2.7 Pro 4K" },
|
||||
{ value: "wan2.7-image", label: "wan 2.7" },
|
||||
{ value: "gpt-image-2", label: "GPT-Image-2" },
|
||||
{ value: "gpt-image-2-vip", label: "GPT-Image-2 VIP" },
|
||||
{ value: "nano-banana-pro", label: "Nano Banana Pro" },
|
||||
{ value: "nano-banana-2", label: "Nano Banana 2" },
|
||||
{ value: "nano-banana-fast", label: "Nano Banana" },
|
||||
{ value: "gpt-image-2", label: "omni-GPT" },
|
||||
{ value: "gpt-image-2-vip", label: "omni-GPT VIP" },
|
||||
{ value: "nano-banana-pro", label: "omni-水果 Pro" },
|
||||
{ value: "nano-banana-2", label: "omni-水果 2" },
|
||||
{ value: "nano-banana-fast", label: "omni-水果" },
|
||||
];
|
||||
|
||||
export const VIDEO_MODEL_OPTIONS: WorkbenchOption[] = ENTERPRISE_VIDEO_MODEL_OPTIONS.map((option) => ({ ...option }));
|
||||
|
||||
@@ -0,0 +1,449 @@
|
||||
/* ── Beta Application Modal ── */
|
||||
/* Word-document style: paper-white panel, larger serif-ish typography, clear form fields */
|
||||
|
||||
.beta-application-modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1000;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.beta-application-modal__backdrop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border: 0;
|
||||
background: rgba(0, 0, 0, 0.58);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ── Panel: paper-like document ── */
|
||||
.beta-application-modal__panel {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: min(800px, 94vw);
|
||||
max-height: 90vh;
|
||||
overflow: hidden;
|
||||
border: 1px solid #d9d5cf;
|
||||
border-radius: 4px;
|
||||
background: #faf8f4;
|
||||
color: #1e1e1e;
|
||||
box-shadow:
|
||||
0 2px 0 #e8e4dc,
|
||||
0 4px 0 #d9d5cf,
|
||||
0 8px 32px rgba(0, 0, 0, 0.2),
|
||||
0 24px 80px rgba(0, 0, 0, 0.12);
|
||||
font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
/* ── Header ── */
|
||||
.beta-modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 28px 36px 20px;
|
||||
border-bottom: 2px solid #1e1e1e;
|
||||
flex-shrink: 0;
|
||||
background: #f5f1ea;
|
||||
}
|
||||
|
||||
.beta-modal-header__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.beta-modal-header__icon {
|
||||
font-size: 28px;
|
||||
color: #166534;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.beta-modal-header h2 {
|
||||
margin: 0;
|
||||
font-size: 22px;
|
||||
font-weight: 900;
|
||||
color: #1e1e1e;
|
||||
letter-spacing: 1px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.beta-modal-header__subtitle {
|
||||
margin: 2px 0 0;
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.beta-modal-header__subtitle strong {
|
||||
color: #166534;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.beta-modal-header__close {
|
||||
display: grid;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
place-items: center;
|
||||
border: 1px solid #d5cfc4;
|
||||
border-radius: 4px;
|
||||
background: #f5f1ea;
|
||||
color: #8c8276;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
flex-shrink: 0;
|
||||
transition: background 120ms ease, color 120ms ease;
|
||||
}
|
||||
|
||||
.beta-modal-header__close:hover {
|
||||
background: #ede6da;
|
||||
color: #1e1e1e;
|
||||
}
|
||||
|
||||
/* ── Scrollable body ── */
|
||||
.beta-modal-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 32px 40px;
|
||||
background: #faf8f4;
|
||||
}
|
||||
|
||||
/* ── Document sections ── */
|
||||
.beta-doc-section {
|
||||
margin-bottom: 28px;
|
||||
padding-bottom: 28px;
|
||||
border-bottom: 1px dashed #d9d2c5;
|
||||
}
|
||||
|
||||
.beta-doc-section:last-of-type {
|
||||
border-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.beta-doc-section__title {
|
||||
margin: 0 0 18px;
|
||||
font-size: 16px;
|
||||
font-weight: 900;
|
||||
color: #1e1e1e;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.beta-required {
|
||||
color: #dc2626;
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.beta-doc-section__desc {
|
||||
margin: 0 0 12px;
|
||||
font-size: 14px;
|
||||
color: #4b5563;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* ── Single-column grid for form fields ── */
|
||||
.beta-doc-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.beta-doc-grid--two {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
/* ── Text field (Word underline style) ── */
|
||||
.beta-text-field {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.beta-text-field__label {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #1e1e1e;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.beta-text-field__label::after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
.beta-text-field__input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #c5beb2;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
padding: 2px 0;
|
||||
font-size: 14px;
|
||||
font-family: inherit;
|
||||
color: #1e1e1e;
|
||||
line-height: 1.8;
|
||||
transition: border-color 140ms ease;
|
||||
}
|
||||
|
||||
.beta-text-field__input::placeholder {
|
||||
color: #c4c4c4;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.beta-text-field__input:focus {
|
||||
border-bottom-color: #166534;
|
||||
border-bottom-width: 2px;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.beta-text-field__input[readonly] {
|
||||
color: #6b7280;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* ── Form group (spans full row when needed) ── */
|
||||
.beta-form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.beta-form-group--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.beta-form-group__label {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #1e1e1e;
|
||||
}
|
||||
|
||||
.beta-form-group__label::after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
/* ── Radio group ── */
|
||||
.beta-radio-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px 14px;
|
||||
}
|
||||
|
||||
.beta-radio {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: #374151;
|
||||
padding: 3px 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.beta-radio input[type="radio"] {
|
||||
appearance: none;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 2px solid #b8b0a4;
|
||||
border-radius: 50%;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
transition: border-color 120ms ease, background 120ms ease;
|
||||
}
|
||||
|
||||
.beta-radio input[type="radio"]:checked {
|
||||
border-color: #166534;
|
||||
background: #166534;
|
||||
box-shadow: inset 0 0 0 3px #ffffff;
|
||||
}
|
||||
|
||||
.beta-radio:hover input[type="radio"] {
|
||||
border-color: #166534;
|
||||
}
|
||||
|
||||
.beta-radio span {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* ── Checkbox group ── */
|
||||
.beta-checkbox-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px 14px;
|
||||
}
|
||||
|
||||
.beta-checkbox {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: #374151;
|
||||
padding: 3px 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.beta-checkbox input[type="checkbox"] {
|
||||
appearance: none;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 2px solid #b8b0a4;
|
||||
border-radius: 3px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
transition: border-color 120ms ease, background 120ms ease;
|
||||
}
|
||||
|
||||
.beta-checkbox input[type="checkbox"]:checked {
|
||||
border-color: #166534;
|
||||
background: #166534;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
|
||||
background-size: 10px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.beta-checkbox:hover input[type="checkbox"] {
|
||||
border-color: #166534;
|
||||
}
|
||||
|
||||
.beta-checkbox span {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* ── Textarea ── */
|
||||
.beta-textarea {
|
||||
width: 100%;
|
||||
min-height: 140px;
|
||||
resize: vertical;
|
||||
border: 1px solid #c5beb2;
|
||||
border-radius: 4px;
|
||||
outline: none;
|
||||
background: #ffffff;
|
||||
padding: 12px 14px;
|
||||
font-size: 14px;
|
||||
font-family: inherit;
|
||||
color: #1e1e1e;
|
||||
line-height: 1.8;
|
||||
transition: border-color 140ms ease;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.beta-textarea::placeholder {
|
||||
color: #c4c4c4;
|
||||
}
|
||||
|
||||
.beta-textarea:focus {
|
||||
border-color: #166534;
|
||||
box-shadow: 0 0 0 2px rgba(22, 101, 52, 0.1);
|
||||
}
|
||||
|
||||
/* ── Rules list ── */
|
||||
.beta-rules-list {
|
||||
margin: 0 0 18px;
|
||||
padding-left: 22px;
|
||||
}
|
||||
|
||||
.beta-rules-list li {
|
||||
font-size: 14px;
|
||||
color: #374151;
|
||||
line-height: 1.9;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.beta-rules-list li strong {
|
||||
color: #166534;
|
||||
}
|
||||
|
||||
/* ── Agreement checkbox row ── */
|
||||
.beta-agree-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
margin-bottom: 18px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #166534;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.beta-agree-row input[type="checkbox"] {
|
||||
appearance: none;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border: 2px solid #b8b0a4;
|
||||
border-radius: 3px;
|
||||
margin-top: 2px;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
transition: border-color 120ms ease, background 120ms ease;
|
||||
}
|
||||
|
||||
.beta-agree-row input[type="checkbox"]:checked {
|
||||
border-color: #166534;
|
||||
background: #166534;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
|
||||
background-size: 12px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
/* ── Footer ── */
|
||||
.beta-modal-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 16px 36px 20px;
|
||||
border-top: 1px solid #e0dbd2;
|
||||
flex-shrink: 0;
|
||||
background: #f5f1ea;
|
||||
}
|
||||
|
||||
.beta-modal-footer__btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
padding: 0 24px;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
transition: opacity 120ms ease, transform 120ms ease;
|
||||
}
|
||||
|
||||
.beta-modal-footer__btn:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
.beta-modal-footer__btn--secondary {
|
||||
background: #e8e3d9;
|
||||
color: #5c5348;
|
||||
}
|
||||
|
||||
.beta-modal-footer__btn--secondary:hover {
|
||||
background: #dbd4c7;
|
||||
}
|
||||
|
||||
.beta-modal-footer__btn--primary {
|
||||
background: #166534;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.beta-modal-footer__btn--primary:hover {
|
||||
background: #14532d;
|
||||
}
|
||||
@@ -3,6 +3,10 @@
|
||||
@import "./shell/app-shell.css";
|
||||
@import "./components/primitives.css";
|
||||
@import "./components/legacy-components.css";
|
||||
@import "./components/recharge-modal.css";
|
||||
@import "./components/beta-application-modal.css";
|
||||
@import "./components/dropzone.css";
|
||||
@import "./components/skeleton.css";
|
||||
@import "./components/toast.css";
|
||||
@import "./components/page-transition.css";
|
||||
@import "./components/motion.css";
|
||||
|
||||
@@ -480,7 +480,7 @@
|
||||
.omni-home__feature-page.is-script,
|
||||
.omni-home__feature-page.is-model,
|
||||
.omni-home__feature-page.is-ecommerce {
|
||||
--home-showcase-page-pad-y: clamp(10px, 1.8vw, 24px);
|
||||
--home-showcase-page-pad-y: clamp(4px, 0.8vw, 12px);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 0;
|
||||
@@ -965,11 +965,12 @@
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: inherit;
|
||||
gap: clamp(30px, 2.6cqw, 56px);
|
||||
padding: clamp(24px, 2.2cqw, 46px) clamp(36px, 3.7cqw, 72px);
|
||||
padding: clamp(12px, 1.2cqw, 24px) clamp(24px, 2.4cqw, 48px);
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .left-panel,
|
||||
@@ -981,10 +982,10 @@
|
||||
|
||||
.omni-home-ecommerce-matrix .left-panel {
|
||||
display: flex;
|
||||
flex: 0 0 clamp(320px, 24cqw, 450px);
|
||||
flex: 0 0 clamp(360px, 29cqw, 540px);
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: clamp(16px, 1.1cqw, 26px);
|
||||
gap: clamp(22px, 1.6cqw, 34px);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@@ -997,7 +998,7 @@
|
||||
|
||||
.omni-home-ecommerce-matrix .hero-title {
|
||||
color: var(--matrix-text-primary);
|
||||
font-size: clamp(40px, 3cqw, 58px);
|
||||
font-size: clamp(48px, 3.6cqw, 72px);
|
||||
font-weight: 900;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.08;
|
||||
@@ -1009,7 +1010,7 @@
|
||||
|
||||
.omni-home-ecommerce-matrix .hero-desc {
|
||||
color: var(--matrix-text-secondary);
|
||||
font-size: clamp(16px, 1.2cqw, 22px);
|
||||
font-size: clamp(19px, 1.4cqw, 26px);
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.2px;
|
||||
line-height: 1.55;
|
||||
@@ -1018,20 +1019,20 @@
|
||||
.omni-home-ecommerce-matrix .features {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: clamp(12px, 0.95cqw, 18px);
|
||||
gap: clamp(16px, 1.2cqw, 24px);
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .feature-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
gap: 14px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--matrix-border-subtle);
|
||||
border-radius: var(--matrix-radius);
|
||||
background: var(--matrix-card-surface);
|
||||
min-height: clamp(70px, 4.6cqw, 92px);
|
||||
padding: clamp(16px, 1.2cqw, 24px);
|
||||
min-height: clamp(88px, 5.8cqw, 114px);
|
||||
padding: clamp(20px, 1.5cqw, 30px);
|
||||
box-shadow: var(--matrix-shadow-card);
|
||||
backdrop-filter: var(--matrix-glass-blur);
|
||||
-webkit-backdrop-filter: var(--matrix-glass-blur);
|
||||
@@ -1064,15 +1065,15 @@
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex: 0 0 clamp(44px, 2.8cqw, 56px);
|
||||
width: clamp(44px, 2.8cqw, 56px);
|
||||
height: clamp(44px, 2.8cqw, 56px);
|
||||
flex: 0 0 clamp(50px, 3.4cqw, 64px);
|
||||
width: clamp(50px, 3.4cqw, 64px);
|
||||
height: clamp(50px, 3.4cqw, 64px);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid rgba(0, 255, 136, 0.2);
|
||||
border-radius: var(--matrix-radius);
|
||||
background: linear-gradient(135deg, rgba(0, 255, 136, 0.15), rgba(168, 85, 247, 0.15));
|
||||
font-size: clamp(20px, 1.4cqw, 28px);
|
||||
font-size: clamp(24px, 1.6cqw, 32px);
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .feature-text {
|
||||
@@ -1082,15 +1083,15 @@
|
||||
|
||||
.omni-home-ecommerce-matrix .feature-text h4 {
|
||||
color: var(--matrix-text-primary);
|
||||
font-size: clamp(18px, 1.2cqw, 24px);
|
||||
font-size: clamp(20px, 1.4cqw, 26px);
|
||||
font-weight: 750;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .feature-text p {
|
||||
margin-top: 6px;
|
||||
margin-top: 8px;
|
||||
color: var(--matrix-text-dim);
|
||||
font-size: clamp(13px, 0.9cqw, 17px);
|
||||
font-size: clamp(15px, 1cqw, 19px);
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.1px;
|
||||
line-height: 1.5;
|
||||
@@ -1100,12 +1101,11 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
margin-top: auto;
|
||||
border: 1px solid var(--matrix-border-subtle);
|
||||
border-radius: var(--matrix-radius);
|
||||
background: var(--matrix-card-surface);
|
||||
min-height: clamp(72px, 4.6cqw, 92px);
|
||||
padding: clamp(14px, 1.1cqw, 22px) clamp(16px, 1.4cqw, 26px);
|
||||
min-height: clamp(88px, 5.8cqw, 114px);
|
||||
padding: clamp(18px, 1.4cqw, 28px) clamp(20px, 1.7cqw, 34px);
|
||||
box-shadow: var(--matrix-shadow-card);
|
||||
backdrop-filter: var(--matrix-glass-blur);
|
||||
-webkit-backdrop-filter: var(--matrix-glass-blur);
|
||||
@@ -1117,18 +1117,18 @@
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .step-icon {
|
||||
font-size: clamp(18px, 1.2cqw, 24px);
|
||||
font-size: clamp(22px, 1.4cqw, 28px);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .step-label {
|
||||
color: var(--matrix-text-secondary);
|
||||
font-size: clamp(12px, 0.82cqw, 16px);
|
||||
font-size: clamp(14px, 0.95cqw, 18px);
|
||||
font-weight: 650;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
@@ -1136,7 +1136,7 @@
|
||||
|
||||
.omni-home-ecommerce-matrix .step-sub {
|
||||
color: var(--matrix-text-dim);
|
||||
font-size: clamp(10px, 0.7cqw, 13px);
|
||||
font-size: clamp(11px, 0.78cqw, 14px);
|
||||
letter-spacing: 0.5px;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
@@ -1171,22 +1171,22 @@
|
||||
|
||||
.omni-home-ecommerce-matrix .center-panel {
|
||||
display: flex;
|
||||
flex: 0 0 clamp(310px, 22cqw, 430px);
|
||||
flex: 0 0 clamp(350px, 26cqw, 500px);
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
gap: 20px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .input-card {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
width: min(100%, clamp(310px, 21cqw, 420px));
|
||||
width: min(100%, clamp(350px, 24cqw, 480px));
|
||||
border: 1px solid var(--matrix-border-default);
|
||||
border-radius: var(--matrix-radius);
|
||||
background: var(--matrix-card-elevated);
|
||||
padding: clamp(20px, 1.45cqw, 30px);
|
||||
padding: clamp(24px, 1.7cqw, 36px);
|
||||
box-shadow: var(--matrix-shadow-elevated), 0 0 60px rgba(0, 255, 136, 0.08);
|
||||
backdrop-filter: var(--matrix-glass-blur);
|
||||
-webkit-backdrop-filter: var(--matrix-glass-blur);
|
||||
@@ -1218,12 +1218,12 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
margin-bottom: clamp(16px, 1.1cqw, 24px);
|
||||
margin-bottom: clamp(20px, 1.4cqw, 30px);
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .input-card-label {
|
||||
color: var(--matrix-cyan);
|
||||
font-size: clamp(14px, 1cqw, 18px);
|
||||
font-size: clamp(16px, 1.15cqw, 22px);
|
||||
font-weight: 800;
|
||||
letter-spacing: 1.2px;
|
||||
text-transform: uppercase;
|
||||
@@ -1235,7 +1235,7 @@
|
||||
border-radius: 6px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
color: var(--matrix-text-dim);
|
||||
font-size: clamp(12px, 0.9cqw, 16px);
|
||||
font-size: clamp(13px, 0.95cqw, 17px);
|
||||
letter-spacing: 0.5px;
|
||||
padding: 6px 12px;
|
||||
white-space: nowrap;
|
||||
@@ -1408,9 +1408,9 @@
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: clamp(16px, 1.35cqw, 28px);
|
||||
gap: clamp(22px, 1.6cqw, 34px);
|
||||
min-width: 0;
|
||||
padding-left: clamp(34px, 3.4cqw, 78px);
|
||||
padding-left: clamp(8px, 0.8cqw, 24px);
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .ai-node {
|
||||
@@ -1418,13 +1418,13 @@
|
||||
z-index: 4;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: clamp(12px, 1cqw, 18px);
|
||||
gap: clamp(14px, 1.15cqw, 22px);
|
||||
width: 100%;
|
||||
border: 1px solid var(--matrix-border-default);
|
||||
border-radius: var(--matrix-radius);
|
||||
background: var(--matrix-card-highlight);
|
||||
min-height: clamp(54px, 3.8cqw, 72px);
|
||||
padding: 12px clamp(16px, 1.4cqw, 26px);
|
||||
min-height: clamp(62px, 4.4cqw, 82px);
|
||||
padding: 14px clamp(18px, 1.6cqw, 30px);
|
||||
box-shadow: var(--matrix-shadow-card), var(--matrix-shadow-glow-purple);
|
||||
backdrop-filter: var(--matrix-glass-blur);
|
||||
-webkit-backdrop-filter: var(--matrix-glass-blur);
|
||||
@@ -1443,7 +1443,7 @@
|
||||
.omni-home-ecommerce-matrix .ai-node-title {
|
||||
flex-shrink: 0;
|
||||
color: var(--matrix-cyan);
|
||||
font-size: clamp(12px, 0.82cqw, 16px);
|
||||
font-size: clamp(14px, 0.95cqw, 18px);
|
||||
font-weight: 850;
|
||||
letter-spacing: 1.6px;
|
||||
text-transform: uppercase;
|
||||
@@ -1457,7 +1457,7 @@
|
||||
.omni-home-ecommerce-matrix .ai-node-list {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: clamp(8px, 0.75cqw, 14px);
|
||||
gap: clamp(10px, 0.85cqw, 16px);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@@ -1467,10 +1467,10 @@
|
||||
border-radius: 4px;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
color: var(--matrix-text-secondary);
|
||||
font-size: clamp(11px, 0.78cqw, 15px);
|
||||
font-size: clamp(12px, 0.85cqw, 16px);
|
||||
letter-spacing: 0.2px;
|
||||
line-height: 1.3;
|
||||
padding: 7px clamp(10px, 0.9cqw, 16px);
|
||||
padding: 8px clamp(12px, 1cqw, 18px);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -1478,28 +1478,28 @@
|
||||
.omni-home-ecommerce-matrix .output-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: clamp(14px, 1.1cqw, 22px);
|
||||
gap: clamp(16px, 1.3cqw, 26px);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .output-label {
|
||||
flex: 0 0 clamp(96px, 6.5cqw, 132px);
|
||||
flex: 0 0 clamp(72px, 5cqw, 100px);
|
||||
padding-right: 4px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .output-label h4 {
|
||||
color: var(--matrix-text-primary);
|
||||
font-size: clamp(18px, 1.3cqw, 25px);
|
||||
font-size: clamp(20px, 1.45cqw, 28px);
|
||||
font-weight: 850;
|
||||
letter-spacing: 0.3px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .output-label p {
|
||||
margin-top: 6px;
|
||||
margin-top: 8px;
|
||||
color: var(--matrix-text-dim);
|
||||
font-size: clamp(11px, 0.82cqw, 15px);
|
||||
font-size: clamp(12px, 0.9cqw, 16px);
|
||||
letter-spacing: 0.8px;
|
||||
line-height: 1.2;
|
||||
text-transform: uppercase;
|
||||
@@ -1516,14 +1516,14 @@
|
||||
.omni-home-ecommerce-matrix .output-cards {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: clamp(14px, 1.15cqw, 24px);
|
||||
gap: clamp(10px, 0.85cqw, 18px);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.omni-home-ecommerce-matrix .output-card {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
min-width: clamp(80px, 7cqw, 140px);
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--matrix-border-subtle);
|
||||
border-radius: var(--matrix-radius);
|
||||
|
||||
@@ -248,6 +248,43 @@
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.beta-apply-button {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
height: 36px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid rgba(var(--accent-rgb), 0.3);
|
||||
border-radius: 12px;
|
||||
background: rgba(var(--accent-rgb), 0.1);
|
||||
color: var(--accent);
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
transform 160ms ease,
|
||||
border-color 160ms ease,
|
||||
background 160ms ease;
|
||||
animation: beta-pulse 2.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.beta-apply-button:hover {
|
||||
border-color: var(--accent);
|
||||
background: rgba(var(--accent-rgb), 0.18);
|
||||
}
|
||||
|
||||
.beta-apply-button:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
@keyframes beta-pulse {
|
||||
0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.25); }
|
||||
50% { box-shadow: 0 0 0 6px rgba(var(--accent-rgb), 0); }
|
||||
}
|
||||
|
||||
.member-button {
|
||||
color: var(--accent);
|
||||
font-weight: 600;
|
||||
|
||||