web/next.config.mjs | Next.js 构建配置:静态导出、图片不走优化、禁用开发环境左下角 Next Dev Indicator,并移除 Next 16 已不支持的 eslint 顶层配置,避免本地 dev 出现配置 Issue 提示。 |
- web/app/globals.css | 全局主题变量、登录页视觉样式、信息流工作台玻璃拟态 token、ReactFlow 样式引用,以及本地开发态 nextjs-portal 遮挡隐藏规则。工作台在 skg-board-theme 内按 Figma 本地 MCP 参考改成黑灰玻璃系统:深灰背景、#383838 胶囊侧栏、rgba(255,255,255,.1) 玻璃面、backdrop-filter: blur(5px)、20px 圆角、10px 10px 10px rgba(0,0,0,.3) 阴影和绿黄状态色;新增 skg-board-shell、skg-board-rail、skg-glass-card、skg-glass-card--flat、skg-status-orb 等样式。主/次按钮、指标卡和空状态继续走统一类,避免各板块散写不同玻璃效果。 |
+ web/app/globals.css | 全局主题变量、登录页视觉样式、信息流工作台玻璃拟态 token、ReactFlow 样式引用,以及本地开发态 nextjs-portal 遮挡隐藏规则。工作台在 skg-board-theme 内按 Figma 本地 MCP 参考改成黑灰玻璃系统:深灰背景、#383838 胶囊侧栏、rgba(255,255,255,.1) 玻璃面、backdrop-filter: blur(5px)、20px 圆角、10px 10px 10px rgba(0,0,0,.3) 阴影和绿黄状态色;新增 skg-board-shell、skg-board-rail、skg-glass-card、skg-glass-card--flat、skg-status-orb 等样式。侧栏改为 448px 高的中段悬停胶囊,展开时在同一侧栏内承载素材输入抽屉。明暗主题已分开维护 shell、panel、glass、stat、action 和音频波形 token;暗色压低灰雾和面板底色,明亮模式改为暖白工作台,避免指标卡、按钮和波形继续残留黑底/白线;顶部指标卡增加紫、黄绿、琥珀、青绿、绿色光斑变量,接近原版多色玻璃卡效果。主/次按钮、指标卡和空状态继续走统一类,避免各板块散写不同玻璃效果。 |
web/app/page.tsx | 产品工作台主状态:jobs、activeJobId、生成任务状态;主渲染为全屏左侧工具条 + 可滑出的素材输入抽屉 + 右侧信息流广告复刻工作表;“开始分析”会把 job 放入并行素材分析队列,下载完成后触发 triggerTranscribe 解析音频,并触发 analyzeJob 自动抽 12 张参考帧,形成“音频文案路 + 视频视觉路”同步推进;音频失败时会忽略失败状态下残留的半成品 transcript,允许再次触发音频解析;底部吸附音频条和旧全局浮动主题按钮不再从主界面渲染,避免和工作台内的明暗模式切换重复。 |
- web/components/ad-recreation-board.tsx | 信息流广告复刻工作表:外壳按 Figma “Dashboard Glassmorphism”参考整体改为黑灰玻璃工作台,WorkbenchRail 默认收起为 65px 工具条,只保留真实动作入口:素材任务、资源库和主题切换;点击素材任务按钮时,skg-board-rail 切换 is-open,从左侧展开 320px 素材输入抽屉。顶部从登录页式 brand strip 改为轻量生产控制条,左侧显示 Marketing Production Console 和“信息流广告复刻工作台”,右侧保留素材/当前/视频/文案段/背景音指标,但改成深色玻璃 stat 卡片。主内容只保留源视频拆解工作区,素材输入的数据流、接口、模型调用和状态推导不变。工作台外层已取消 1800x1000 固定基准画布、ResizeObserver 档位计算和 CSS zoom 整页缩放,改为正常流式桌面容器:min-height: 100vh、width: 100%、max-width: 1920px,并保留 min-width: 1280px 作为最低操作宽度;核心列宽不再被整体缩放,文字、图标和边线由浏览器原生字号渲染,避免小数缩放导致发虚。buildWorkflowSteps 仍统一生成 01-09 流程顺序、状态和判定依据,WorkflowStepBadge / PipelineLane / 分镜列标题也继续共用同一套编号;但完整 WorkflowOrderBar、右侧素材/视频/音频/文案/参考帧需求 chips、文案依据下拉和“音频文案、抽帧参考、主体重构、产品素材池”四个状态条不再默认渲染在工作区顶部。侧边素材输入面板只负责链接/上传和任务切换,不再重复放横版原视频预览;主画布源视频工作区直接进入核心操作。讲话人、节奏和背景音分析仍写入 AudioScript,但不再作为“音频解析结果”卡片默认渲染;源视频工作区撤销右上“布局调节”临时面板,不再读取或写入 localStorage["skg-source-workspace-layout:v1"];当前固定为左侧原视频列 380px、9:16 视频高 500px、逐句时间轴最大高 360px、参考帧池 140px、主体空态 78px;转换层不再固定拉长,按内容自然高度显示,内容过多时最多到 560px 后在自身区域内滚动;上方是按 9:16 显示的竖版原视频播放器,播放器内覆盖“当前点抽帧”,按当前播放秒数手动补参考帧,播放器下方是逐句时间轴,英文和中文都最多显示两行;右侧上方是无标题的波形与切点参考框,下方主体链路改为上方参考帧池 + 转换层、下方主体元素结果栏。音频波形用参考图式的连续灰色包络显示响度、停顿和密集爆点,顶部把低/中/高密度按钮和当前播放秒数、总时长、鼠标指针停点秒数直接放在波形上方。视频播放时通过 requestAnimationFrame 平滑驱动波形播放线,同时同步高亮并滚动当前句;点击音频波形或字幕行会跳转原视频时间。音频波形下方同框渲染无标题的 TimelineFilmstrip 临时画面胶片,前端按低/中/高密度从源视频 canvas 截取预览缩略图,并按 frame.time / duration 的百分比定位到和波形同一条时间轴上;波形与胶片之间不显示分隔横线,胶片轨道贴近波形,缩略图轻微上下错落并倾斜重叠排列,hover 时用同一张胶片卡在原位置生成固定顶层克隆,约 4.8 倍放大并自动限制在视口内,避免被工作区、滚动容器或相邻面板遮挡;单击胶片只跳转视频时间点,不写入任务数据,双击胶片或拖进参考帧池时才调用手动抽帧并正式加入 job.frames,已加入的胶片显示“已添加”;胶片预览按 job、视频、密度和时长缓存,未切换低/中/高时返回页面不重新扫视频。参考帧池的主入口是“自动抽帧 12 张”,一键按动作峰值目标重新抽取 12 张源视频参考帧,优先抓手势、表情变化、节奏点和镜头变化;缩略图按竖版完整比例显示不裁切,点选状态直接叠在参考帧池缩略图上,鼠标停留会通过固定浮层放大展示完整帧。转换层改为轻量对话式生图确认区并拿到主操作宽度:左侧参考帧可点 + 或直接拖入转换层,本地图片拖入会通过 uploadReferenceFrame 保存为参考帧;转换层上方是参考输入区,下方不再显示当前要求摘要、保留元素副本或对话记录计数,只保留带张数控件的“发送消息”输入 composer;模型确认类回复不再逐条展示,生成英文 prompt 后发送区主按钮直接切换为“确认生成 N 张”,点击后才调用主体套图生成。主体元素结果栏在转换层下方,空态只占紧凑提示;有结果时按每次生成的套图文件夹显示,左侧横向展示当前套图,右侧切换套图包,保留单张重生和删除;缩略图上提供“重新生成这一张”和“删除这一张”,单张重生会用 replace_views=true 替换同一视角。前端对卡通重构传 subject_style=cartoon_subject,其他方向传 subject_style=source_actor;形象锁定或自主描述空文本可走 reconstruction_mode=same,其他参考创新走 similar 并把参考帧作为 /images/edits 的 image refs 一起提交。主体生成完成后会形成 subject_consensus_brief。音频结果下方是信息流复刻分镜工作台:顶部产品参考区是“同一产品素材池”,不限量上传产品图,不做不同产品身份判断;上传原图推荐长边 1200-2000px、短边至少 600px,但后端会统一生成最长边 1600px、JPEG 92 的 AI 工作副本,并回显尺寸、自动转换和风险标注;上传后按“套在脖子上的 U 形肩颈按摩仪”进行同一产品批量识别,左/右按佩戴者身体左右、上/下按佩戴方向,额外标注内外侧、开口方向、局部结构点、背景类型、用途标签、生成风险和备注,用户只检查备注,鼠标悬停通过固定浮层显示大图预览,能盖过滚动容器和分镜框架;缺视角补图失败时保留重试入口。脚本区在分镜行上方提供“作者想法”和“整片改写”,每行新口播文案可直接编辑并可单段 AI 改写。每条音频分镜默认是左侧三字段、右侧横向视频候选轨;高级区仍保留首尾帧 prompt、产品出现方式和旧 6 字段。ModelTrace 会在音频解析、产品识别/补图、主体重构视图包、脚本改写等入口旁直接展示模型名;生图入口会显示 gpt-image-2 / gemini-3-pro-image-preview 链路和短时熔断规则,点击后用固定浮层展示模型链路、输入输出和回退逻辑。旧分镜卡、抽帧控制和视频生成组件仍保留在文件里,但当前主路径不渲染。 |
+ web/components/ad-recreation-board.tsx | 信息流广告复刻工作表:外壳按 Figma “Dashboard Glassmorphism”参考整体改为黑灰玻璃工作台,WorkbenchRail 默认收起为停在页面中段的 65px 胶囊工具条,只保留真实动作入口:素材任务、资源库和主题切换;鼠标移入或键盘聚焦侧栏时,skg-board-rail 切换 is-open 并从左侧展开 320px 素材输入抽屉,点击素材任务按钮可固定展开。顶部从登录页式 brand strip 改为轻量生产控制条,左侧显示 Marketing Production Console 和“信息流广告复刻工作台”,右侧保留素材/当前/视频/文案段/背景音指标,并用紫、黄绿、琥珀、青绿、绿色光斑卡片增强原版玻璃拟态的颜色层次。主内容只保留源视频拆解工作区,素材输入的数据流、接口、模型调用和状态推导不变。工作台外层已取消 1800x1000 固定基准画布、ResizeObserver 档位计算和 CSS zoom 整页缩放,改为正常流式桌面容器:min-height: 100vh、width: 100%、max-width: 1920px,并保留 min-width: 1280px 作为最低操作宽度;核心列宽不再被整体缩放,文字、图标和边线由浏览器原生字号渲染,避免小数缩放导致发虚。buildWorkflowSteps 仍统一生成 01-09 流程顺序、状态和判定依据,WorkflowStepBadge / PipelineLane / 分镜列标题也继续共用同一套编号;但完整 WorkflowOrderBar、右侧素材/视频/音频/文案/参考帧需求 chips、文案依据下拉和“音频文案、抽帧参考、主体重构、产品素材池”四个状态条不再默认渲染在工作区顶部。侧边素材输入面板只负责链接/上传和任务切换,不再重复放横版原视频预览;主画布源视频工作区直接进入核心操作。讲话人、节奏和背景音分析仍写入 AudioScript,但不再作为“音频解析结果”卡片默认渲染;源视频工作区撤销右上“布局调节”临时面板,不再读取或写入 localStorage["skg-source-workspace-layout:v1"];当前固定为左侧原视频列 380px、9:16 视频高 500px、逐句时间轴最大高 360px、参考帧池 140px、主体空态 78px;转换层不再固定拉长,按内容自然高度显示,内容过多时最多到 560px 后在自身区域内滚动;上方是按 9:16 显示的竖版原视频播放器,播放器内覆盖“当前点抽帧”,按当前播放秒数手动补参考帧,播放器下方是逐句时间轴,英文和中文都最多显示两行;右侧上方是无标题的波形与切点参考框,下方主体链路改为上方参考帧池 + 转换层、下方主体元素结果栏。音频波形用参考图式的连续灰色包络显示响度、停顿和密集爆点,并通过 skg-audio-waveform 读取明暗主题变量,避免明亮模式继续使用黑底/白色波形;顶部把低/中/高密度按钮和当前播放秒数、总时长、鼠标指针停点秒数直接放在波形上方。视频播放时通过 requestAnimationFrame 平滑驱动波形播放线,同时同步高亮并滚动当前句;点击音频波形或字幕行会跳转原视频时间。音频波形下方同框渲染无标题的 TimelineFilmstrip 临时画面胶片,前端按低/中/高密度从源视频 canvas 截取预览缩略图,并按 frame.time / duration 的百分比定位到和波形同一条时间轴上;波形与胶片之间不显示分隔横线,胶片轨道贴近波形,缩略图轻微上下错落并倾斜重叠排列,hover 时用同一张胶片卡在原位置生成固定顶层克隆,约 4.8 倍放大并自动限制在视口内,避免被工作区、滚动容器或相邻面板遮挡;单击胶片只跳转视频时间点,不写入任务数据,双击胶片或拖进参考帧池时才调用手动抽帧并正式加入 job.frames,已加入的胶片显示“已添加”;胶片预览按 job、视频、密度和时长缓存,未切换低/中/高时返回页面不重新扫视频。参考帧池的主入口是“自动抽帧 12 张”,一键按动作峰值目标重新抽取 12 张源视频参考帧,优先抓手势、表情变化、节奏点和镜头变化;缩略图按竖版完整比例显示不裁切,点选状态直接叠在参考帧池缩略图上,鼠标停留会通过固定浮层放大展示完整帧。转换层改为轻量对话式生图确认区并拿到主操作宽度:左侧参考帧可点 + 或直接拖入转换层,本地图片拖入会通过 uploadReferenceFrame 保存为参考帧;转换层上方是参考输入区,下方不再显示当前要求摘要、保留元素副本或对话记录计数,只保留带张数控件的“发送消息”输入 composer;模型确认类回复不再逐条展示,生成英文 prompt 后发送区主按钮直接切换为“确认生成 N 张”,点击后才调用主体套图生成。主体元素结果栏在转换层下方,空态只占紧凑提示;有结果时按每次生成的套图文件夹显示,左侧横向展示当前套图,右侧切换套图包,保留单张重生和删除;缩略图上提供“重新生成这一张”和“删除这一张”,单张重生会用 replace_views=true 替换同一视角。前端对卡通重构传 subject_style=cartoon_subject,其他方向传 subject_style=source_actor;形象锁定或自主描述空文本可走 reconstruction_mode=same,其他参考创新走 similar 并把参考帧作为 /images/edits 的 image refs 一起提交。主体生成完成后会形成 subject_consensus_brief。音频结果下方是信息流复刻分镜工作台:顶部产品参考区是“同一产品素材池”,不限量上传产品图,不做不同产品身份判断;上传原图推荐长边 1200-2000px、短边至少 600px,但后端会统一生成最长边 1600px、JPEG 92 的 AI 工作副本,并回显尺寸、自动转换和风险标注;上传后按“套在脖子上的 U 形肩颈按摩仪”进行同一产品批量识别,左/右按佩戴者身体左右、上/下按佩戴方向,额外标注内外侧、开口方向、局部结构点、背景类型、用途标签、生成风险和备注,用户只检查备注,鼠标悬停通过固定浮层显示大图预览,能盖过滚动容器和分镜框架;缺视角补图失败时保留重试入口。脚本区在分镜行上方提供“作者想法”和“整片改写”,每行新口播文案可直接编辑并可单段 AI 改写。每条音频分镜默认是左侧三字段、右侧横向视频候选轨;高级区仍保留首尾帧 prompt、产品出现方式和旧 6 字段。ModelTrace 会在音频解析、产品识别/补图、主体重构视图包、脚本改写等入口旁直接展示模型名;生图入口会显示 gpt-image-2 / gemini-3-pro-image-preview 链路和短时熔断规则,点击后用固定浮层展示模型链路、输入输出和回退逻辑。旧分镜卡、抽帧控制和视频生成组件仍保留在文件里,但当前主路径不渲染。 |
SourceSubjectPipeline | 源视频工作区主体管线主路径:上方是竖向 参考帧池 和宽幅 转换层,下方是 主体元素 结果栏。参考帧池固定 140px,转换层不再固定高度,按内容自然显示并以 560px 为最大高度,超出后在自身区域内滚动;主体空态固定为 78px 紧凑提示。参考帧池保留自动 12 张、胶片拖入正式成帧、点击勾选和删除;参考帧缩略图保持小尺寸固定宽度、aspect-[9/16] 和 object-contain 显示,hover 预览通过 MediaAssetTile 的左侧紧凑浮层显示,并新增 + 操作把参考帧送入转换层。转换层是轻量对话式生图确认区:顶部选择 GPT 套件或 Gemini 套件,参考输入区支持左侧 +、拖拽参考帧、胶片拖入和本地图片拖拽上传(上传图会写入 job.frames),下方固定为带张数控件的“发送消息”输入 composer,不再重复显示当前要求摘要、保留元素副本或收起记录计数;模型确认类回复不再逐条显示,复刻、参考创意换人物、卡通风格和人物占比等常用意图也不再显示为独立快捷 chip;识别结果里的特征 chip 是“保留元素”选择,点亮表示随下一条消息提交给 subject-agent/message,再次点击取消,清空按钮一次性取消全部,单次点击不再直接请求模型;subject-agent/message 返回英文 generation_prompt_en 后不再自动弹窗,标题右侧显示“提示词就绪”,底部主按钮从“发送消息”切换为“确认生成 N 张”;用户继续输入会更新需求,点击确认生成才调用 generateSubjectAssets。后端会为每次主体套图注入同一份 pack bible:参考创新模式锁定同一个全新主体和同一套服装,源形象锁定模式锁定参考帧里的可见主体、体态、发型、服装和配色;后处理会裁出白底主体并允许放大到画布高度上限约 96%,实测典型主体有效高度约 90%,避免模型生成“小人 + 大白边”。主体元素结果栏按每次生成的 pack_id 组织成“套图文件夹”:左侧横向展开当前选中套图,右侧显示可滚动的套图包列表;同一方向可保留多套,生成中按 pack 显示 2/6 这类进度,单张完成就替换对应占位卡;空态只显示紧凑提示,不再占右侧整列。缩略图复用 MediaAssetTile,支持 hover 放大、单张重生和删除。旧下方 SourceReferenceBuildPanel 不再主路径渲染。 |
AudioStoryboardPlanPanel 三字段候选生成 | 当前分镜主路径:每行是左右双栏,左侧默认显示 skg_copy_*、scene_one_line_*、action_one_line_* 三组中英字段,右侧直接显示视频候选横向轨。用户改中文镜像后,字段失焦会通过 refineStoryboard 优化对应英文主值,失败时退回 translateText;英文仍是后续 prompt 主值。quickPlanStoryboard 把三字段和主体 brief 展开为完整 StoryboardScene,generateStoryboardVideo 的 count 可由单行数字控件选择,候选新生成后持续向右追加,不再用 4-grid 撑高每行。整片生成同样可选择每行数量,并以 concurrency=1 按行排队提交。产品素材池、批量控制、每行主体区和高级区都可折叠,高级抽屉仍展示旧 6 字段、首尾帧 prompt 和首尾帧资产槽,但客户默认不用先处理首尾帧。 |
web/components/resource-library/library-drawer.tsx | 全局资源中心浮窗:由工作台顶部“资源库”按钮打开,叠加在工作台上方但不阻塞主界面;尺寸、位置和当前 Tab 写入 localStorage["skg-resource-library-drawer"]。提示词 Tab 固定 5 列(场景描述、视频描述、主体描述、SKG 文案、产品角度),每列先显示 use_count 排名前 5 的“常用”,再按月份倒序分组;提示词节点常驻复制按钮,hover 可选英文/中文/双语复制,并调用 use 接口。素材 Tab 固定 4 列(主体、产品、场景、视频),节点不可拖动,按月份倒序硬编码排列;“应用到当前 job”只调用后端复制接口,得到普通 ImageRef(kind="asset") 后再写入产品素材池或复制 ID。浮窗顶部最近 24 小时横条混合显示提示词和素材;新建提示词、上传素材、删除前查引用、详情侧栏都在该组件内完成。 |
- AdRecreationBoard 主题切换 | 左侧 65px 工具条底部有 Sun / Moon 图标按钮,切换 skg-board-theme--light 类名,并把选择写入 localStorage["skg-board-theme"]。暗色仍是默认模式;明亮模式只改变工作台外观,不改变任务、素材、分镜、模型调用或接口数据。 |
+ AdRecreationBoard 主题切换 | 左侧中段 65px 胶囊工具条上方图标组里有 Sun / Moon 图标按钮,切换 skg-board-theme--light 类名,并把选择写入 localStorage["skg-board-theme"]。暗色仍是默认模式;明亮模式只改变工作台外观,不改变任务、素材、分镜、模型调用或接口数据。 |
SourceReferenceBuildPanel | 旧的“相似主体 / 主体模板”大面板代码仍保留在文件里,方便以后恢复模板库复用、入库命名和自定义视图选择;但当前源视频工作区主路径已经由 SourceSubjectPipeline 承接,不再在页面下方渲染这块,避免和“参考帧池 → 转换层 → 主体元素”重复。 |
web/components/media-asset-tile.tsx | 项目内媒体素材缩略图基底组件:图片、视频、抽帧、产品图、相似主体图、首尾帧和视频候选默认从这里获得统一交互。组件负责缩略图显示、顶层固定浮层 hover 放大、删除按钮、重新生成等操作按钮、忙碌遮罩和图片/视频共用预览,避免每个新板块重复手写不同的媒体交互。hover 预览支持 previewPlacement 和 previewMaxWidth,参考帧池用左侧紧凑预览避免遮住转换层;画面胶片是例外:为了保持胶片原位浏览,不使用额外弹出预览,只让胶片缩略图自己在轨道内放大。 |
web/app/login/page.tsx | 生产登录页:访问账号/访问密钥表单、保持登录、错误/成功状态;当前只在原版 Digital Oasis 动态背景上叠加一个组合登录框,桌面端左侧是动态角色,右侧是图标化登录表单;面板左上角展示官网 SKG 字标和中文“营销内容工作台”系统标识。 |
@@ -1132,6 +1132,30 @@ ProductRefStateItem {
变更记录
这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。
+
+
+ 2026-05-21 · 侧栏中段悬停与多色玻璃卡
+ UI
+ Figma Reference
+
+
+
问题:侧栏按整高工具条处理后不像原版参考图,资源库和明暗按钮被压到底部;顶部指标卡也偏全灰,缺少原版紫、黄绿、琥珀、青绿色光斑的玻璃层次。
+
改动:WorkbenchRail 改成停留在页面中段的 448px 胶囊侧栏,鼠标移入或键盘聚焦时自动展开素材输入抽屉,点击素材任务可固定展开;资源库和明暗切换移到侧栏上方图标组。Metric 新增多色 variant,顶部五个指标分别使用紫、黄绿、琥珀、青绿和绿色光斑。
+
影响:侧栏不再作为整高导航存在;后续应按“中段悬停抽屉 + 顶部真实动作图标”描述。配色增强只影响视觉层,不改变素材任务、资源库、主题切换或指标数据。
+
+
+
+
+ 2026-05-21 · 明暗主题色阶重新扫描修正
+ UI
+ Theme
+
+
+
问题:玻璃工作台暗色模式整体灰雾偏重;明亮模式仍有黑色 stat 卡、黑底按钮和偏白音频波形残留,导致同一版面里明暗语义混在一起。
+
改动:web/app/globals.css 重新分离暗色和明亮模式的 shell、panel、glass、stat、action 与音频波形 token;暗色压低背景和卡片底色,明亮模式改为暖白面板、浅色指标卡和绿黄主按钮。AudioWaveform 改用 skg-audio-waveform 主题类,不再把黑底、白色包络和播放线写死在组件里。
+
影响:这是纯视觉修正,不改变素材任务、字幕时间轴、波形点击跳转、胶片抽帧、模型调用或任何接口数据;后续调色应优先调整主题 token,不要在组件里新增孤立的黑白 Tailwind 色值。
+
+
2026-05-21 · 逐句时间轴向下加高
@@ -1152,8 +1176,8 @@ ProductRefStateItem {
问题:侧栏图标条里的流程状态图标容易被理解成可导航入口,但多数没有独立操作;素材输入也不应该常驻挤占主画布,而应该由真实入口唤出。
-
改动:WorkbenchRail 默认收起为 65px 工具条,只保留素材任务、资源库和主题切换三个真实动作;点击素材任务后,skg-board-rail 增加 is-open 并从左侧展开 320px MaterialColumn 抽屉。旧的源视频、音频、参考帧、主体套图和视频候选状态图标不再放在侧栏里冒充按钮,状态继续由顶部指标和主工作区各自展示。
-
影响:后续描述布局时应说“左侧工具条点击素材任务滑出素材输入面板,右侧主画布视频拆解工作区”;素材任务状态、开始分析、上传和任务切换接口不受影响。
+
改动:WorkbenchRail 默认收起为 65px 中段胶囊工具条,只保留素材任务、资源库和主题切换三个真实动作;鼠标移入、键盘聚焦或点击素材任务后,skg-board-rail 增加 is-open 并从左侧展开 320px MaterialColumn 抽屉。旧的源视频、音频、参考帧、主体套图和视频候选状态图标不再放在侧栏里冒充按钮,状态继续由顶部指标和主工作区各自展示。
+
影响:后续描述布局时应说“左侧中段胶囊工具条悬停滑出素材输入面板,右侧主画布视频拆解工作区”;素材任务状态、开始分析、上传和任务切换接口不受影响。
diff --git a/web/app/globals.css b/web/app/globals.css
index 2775da0..b74c772 100644
--- a/web/app/globals.css
+++ b/web/app/globals.css
@@ -491,11 +491,20 @@ nextjs-portal {
--skg-glass-bg: rgba(255, 255, 255, 0.1);
--skg-glass-bg-soft: rgba(255, 255, 255, 0.055);
--skg-rail: #383838;
+ --skg-wave-bg: rgba(0, 0, 0, 0.35);
+ --skg-wave-fill: rgba(209, 213, 219, 0.74);
+ --skg-wave-stroke-1: rgba(229, 231, 235, 0.7);
+ --skg-wave-stroke-2: rgba(229, 231, 235, 0.52);
+ --skg-wave-grid: rgba(255, 255, 255, 0.14);
+ --skg-wave-marker: rgba(255, 255, 255, 0.12);
+ --skg-wave-hover: rgba(207, 250, 254, 0.7);
+ --skg-wave-playhead: #a7f3d0;
+ --skg-wave-playhead-shadow: rgba(110, 231, 183, 0.85);
color: var(--skg-text-1);
background:
- radial-gradient(circle at 20% 18%, rgba(162, 198, 56, 0.11), transparent 28%),
- radial-gradient(circle at 86% 78%, rgba(200, 205, 25, 0.12), transparent 28%),
- linear-gradient(120deg, #202020 0%, #242424 48%, #171717 100%);
+ radial-gradient(circle at 20% 18%, rgba(162, 198, 56, 0.09), transparent 28%),
+ radial-gradient(circle at 86% 78%, rgba(200, 205, 25, 0.1), transparent 28%),
+ linear-gradient(120deg, #171717 0%, #202020 48%, #101010 100%);
}
.skg-board-theme::before {
@@ -518,8 +527,8 @@ nextjs-portal {
z-index: 0;
pointer-events: none;
background:
- linear-gradient(180deg, rgba(0, 0, 0, 0.18), transparent 45%, rgba(0, 0, 0, 0.38)),
- linear-gradient(90deg, rgba(0, 0, 0, 0.34), transparent 36%, rgba(0, 0, 0, 0.2));
+ linear-gradient(180deg, rgba(0, 0, 0, 0.2), transparent 45%, rgba(0, 0, 0, 0.42)),
+ linear-gradient(90deg, rgba(0, 0, 0, 0.38), transparent 36%, rgba(0, 0, 0, 0.22));
}
.skg-board-ambient {
@@ -532,17 +541,17 @@ nextjs-portal {
.skg-board-panel {
border-color: var(--skg-border) !important;
background:
- radial-gradient(circle at 88% 22%, rgba(162, 198, 56, 0.08), transparent 38%),
- linear-gradient(180deg, rgba(255, 255, 255, 0.105), rgba(255, 255, 255, 0.052)),
- rgba(36, 36, 36, 0.68) !important;
+ radial-gradient(circle at 88% 22%, rgba(162, 198, 56, 0.06), transparent 38%),
+ linear-gradient(180deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.032)),
+ rgba(30, 30, 30, 0.78) !important;
box-shadow: var(--skg-shadow-card);
backdrop-filter: blur(5px);
}
.skg-board-topbar {
background:
- linear-gradient(100deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0.045) 58%, rgba(162, 198, 56, 0.08)),
- rgba(38, 38, 38, 0.72) !important;
+ linear-gradient(100deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.038) 58%, rgba(162, 198, 56, 0.07)),
+ rgba(28, 28, 28, 0.84) !important;
}
.skg-board-theme input:focus,
@@ -566,16 +575,21 @@ nextjs-portal {
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 24px;
background:
- linear-gradient(180deg, rgba(255, 255, 255, 0.032), rgba(255, 255, 255, 0.012)),
- rgba(26, 26, 26, 0.58);
+ linear-gradient(180deg, rgba(255, 255, 255, 0.026), rgba(255, 255, 255, 0.01)),
+ rgba(18, 18, 18, 0.72);
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.38);
backdrop-filter: blur(8px);
}
.skg-board-rail {
width: 65px;
- min-height: 514px;
- overflow: hidden;
+ height: 448px;
+ min-height: 448px;
+ align-self: flex-start;
+ top: 96px;
+ margin-top: clamp(72px, 13vh, 116px);
+ z-index: 30;
+ overflow: visible;
transition: width 220ms ease;
}
@@ -585,10 +599,14 @@ nextjs-portal {
.skg-board-rail__strip {
width: 65px;
- min-height: 514px;
+ height: 448px;
+ min-height: 448px;
border: 1px solid #383838;
border-radius: 0 70px 70px 0;
- background: #383838;
+ background:
+ radial-gradient(circle at 86% 18%, rgba(162, 198, 56, 0.1), transparent 28%),
+ linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012)),
+ #383838;
box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.3);
overflow: hidden;
transition: width 220ms ease, border-radius 220ms ease;
@@ -601,6 +619,7 @@ nextjs-portal {
.skg-board-rail__iconbar {
width: 65px;
+ height: 100%;
}
.skg-board-rail__logo {
@@ -626,9 +645,16 @@ nextjs-portal {
}
.skg-board-rail__drawer {
+ height: 100%;
animation: skgRailDrawerIn 220ms ease both;
}
+.skg-board-rail__drawer .skg-board-panel {
+ height: 100%;
+ min-height: 0 !important;
+ border-radius: 0 30px 30px 0;
+}
+
@keyframes skgRailDrawerIn {
from {
opacity: 0;
@@ -644,9 +670,9 @@ nextjs-portal {
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 20px;
background:
- radial-gradient(circle at 80% 86%, rgba(162, 198, 56, 0.18), transparent 36%),
- linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.052)),
- rgba(56, 56, 56, 0.62);
+ radial-gradient(circle at 80% 86%, rgba(162, 198, 56, 0.13), transparent 36%),
+ linear-gradient(180deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.034)),
+ rgba(38, 38, 38, 0.76);
box-shadow: var(--skg-shadow-card);
backdrop-filter: blur(5px);
}
@@ -654,8 +680,30 @@ nextjs-portal {
.skg-glass-card--flat {
border-radius: 16px;
background:
- linear-gradient(180deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.035)),
- rgba(24, 24, 24, 0.52);
+ linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.022)),
+ rgba(18, 18, 18, 0.62);
+}
+
+.skg-audio-waveform {
+ border-color: rgba(255, 255, 255, 0.1) !important;
+ background: var(--skg-wave-bg) !important;
+}
+
+.skg-audio-waveform__center {
+ background: var(--skg-wave-grid);
+}
+
+.skg-audio-waveform__segment {
+ background: var(--skg-wave-marker);
+}
+
+.skg-audio-waveform__hover {
+ background: var(--skg-wave-hover);
+}
+
+.skg-audio-waveform__playhead {
+ background: var(--skg-wave-playhead);
+ box-shadow: 0 0 16px var(--skg-wave-playhead-shadow);
}
.skg-status-orb {
@@ -673,22 +721,31 @@ nextjs-portal {
}
.skg-board-theme--light {
- --skg-bg-1: #faf8f4;
- --skg-bg-2: #ffffff;
+ --skg-bg-1: #f4f1e8;
+ --skg-bg-2: #fbfaf5;
--skg-bg-3: rgba(0, 0, 0, 0.03);
- --skg-border: rgba(0, 0, 0, 0.08);
- --skg-text-1: #0a0a0a;
- --skg-text-2: rgba(0, 0, 0, 0.62);
- --skg-text-3: rgba(0, 0, 0, 0.34);
+ --skg-border: rgba(72, 78, 56, 0.14);
+ --skg-text-1: #20241b;
+ --skg-text-2: rgba(32, 36, 27, 0.68);
+ --skg-text-3: rgba(32, 36, 27, 0.42);
--skg-success: #059669;
--skg-warn: #b7791f;
--skg-danger: #e11d48;
--skg-info: #0891b2;
+ --skg-wave-bg: rgba(255, 255, 255, 0.74);
+ --skg-wave-fill: rgba(80, 90, 70, 0.42);
+ --skg-wave-stroke-1: rgba(47, 57, 44, 0.46);
+ --skg-wave-stroke-2: rgba(47, 57, 44, 0.3);
+ --skg-wave-grid: rgba(72, 78, 56, 0.16);
+ --skg-wave-marker: rgba(72, 78, 56, 0.14);
+ --skg-wave-hover: rgba(23, 96, 111, 0.52);
+ --skg-wave-playhead: #10b981;
+ --skg-wave-playhead-shadow: rgba(16, 185, 129, 0.36);
color: var(--skg-text-1);
background:
- radial-gradient(circle at 50% 0%, rgba(232, 212, 168, 0.18), transparent 31%),
- radial-gradient(circle at 4% 100%, rgba(214, 179, 106, 0.12), transparent 28%),
- linear-gradient(126deg, #faf8f4 0%, #f4efe5 48%, #ffffff 100%);
+ radial-gradient(circle at 50% 0%, rgba(232, 212, 168, 0.16), transparent 31%),
+ radial-gradient(circle at 4% 100%, rgba(143, 176, 113, 0.1), transparent 28%),
+ linear-gradient(126deg, #f5f2e9 0%, #ece7dc 48%, #fbfaf5 100%);
}
.skg-board-theme--light::before {
@@ -715,17 +772,50 @@ nextjs-portal {
.skg-board-theme--light .skg-board-panel {
border-color: rgba(82, 93, 62, 0.16) !important;
background:
- linear-gradient(180deg, rgba(255, 255, 255, 0.78), rgba(255, 255, 255, 0.48)),
- rgba(249, 246, 236, 0.7) !important;
+ radial-gradient(circle at 88% 18%, rgba(143, 176, 113, 0.12), transparent 36%),
+ linear-gradient(180deg, rgba(255, 255, 255, 0.86), rgba(249, 247, 239, 0.64)),
+ rgba(246, 243, 234, 0.84) !important;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.78),
- 0 18px 48px rgba(65, 55, 30, 0.1);
+ 0 18px 48px rgba(65, 55, 30, 0.12);
}
.skg-board-theme--light .skg-board-topbar {
background:
- linear-gradient(100deg, rgba(214, 179, 106, 0.14), rgba(143, 176, 113, 0.08) 42%, rgba(255, 255, 255, 0.58)),
- rgba(252, 249, 241, 0.82) !important;
+ linear-gradient(100deg, rgba(214, 179, 106, 0.1), rgba(143, 176, 113, 0.07) 42%, rgba(255, 255, 255, 0.72)),
+ rgba(250, 248, 241, 0.9) !important;
+}
+
+.skg-board-theme--light .skg-board-shell {
+ border-color: rgba(72, 78, 56, 0.14);
+ background:
+ linear-gradient(180deg, rgba(255, 255, 255, 0.72), rgba(246, 243, 235, 0.62)),
+ rgba(246, 243, 235, 0.74);
+ box-shadow: 0 24px 70px rgba(74, 68, 44, 0.13);
+}
+
+.skg-board-theme--light .skg-board-rail__strip {
+ border-color: #3f4239;
+ background:
+ radial-gradient(circle at 86% 18%, rgba(162, 198, 56, 0.12), transparent 28%),
+ linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012)),
+ #3f4239;
+ box-shadow: 10px 10px 26px rgba(74, 68, 44, 0.18);
+}
+
+.skg-board-theme--light .skg-glass-card {
+ border-color: rgba(72, 78, 56, 0.16);
+ background:
+ radial-gradient(circle at 80% 86%, rgba(143, 176, 113, 0.12), transparent 36%),
+ linear-gradient(180deg, rgba(255, 255, 255, 0.84), rgba(246, 243, 235, 0.64)),
+ rgba(250, 248, 241, 0.82);
+ box-shadow: 0 16px 42px rgba(74, 68, 44, 0.12);
+}
+
+.skg-board-theme--light .skg-glass-card--flat {
+ background:
+ linear-gradient(180deg, rgba(255, 255, 255, 0.7), rgba(246, 243, 235, 0.5)),
+ rgba(255, 255, 255, 0.54);
}
.skg-board-theme--light .skg-board-theme-toggle {
@@ -862,9 +952,15 @@ nextjs-portal {
}
.skg-stat-card {
+ --skg-stat-glow:
+ radial-gradient(circle at 92% 86%, rgba(162, 198, 56, 0.22), transparent 48%);
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 12px;
+ position: relative;
+ isolation: isolate;
+ overflow: hidden;
background:
+ var(--skg-stat-glow),
linear-gradient(180deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0.045)),
rgba(0, 0, 0, 0.16);
color: #ffffff;
@@ -872,6 +968,36 @@ nextjs-portal {
backdrop-filter: blur(5px);
}
+.skg-stat-card--violet {
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 82%, rgba(126, 87, 194, 0.74), transparent 48%),
+ radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.08), transparent 32%);
+}
+
+.skg-stat-card--lime {
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 84%, rgba(200, 205, 25, 0.72), transparent 48%),
+ radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.08), transparent 32%);
+}
+
+.skg-stat-card--gold {
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 84%, rgba(214, 179, 106, 0.7), transparent 48%),
+ radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.08), transparent 32%);
+}
+
+.skg-stat-card--teal {
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 84%, rgba(68, 162, 150, 0.7), transparent 48%),
+ radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.08), transparent 32%);
+}
+
+.skg-stat-card--green {
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 84%, rgba(84, 190, 104, 0.72), transparent 48%),
+ radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.08), transparent 32%);
+}
+
.skg-stat-card__label {
color: rgba(255, 255, 255, 0.48);
}
@@ -943,27 +1069,75 @@ nextjs-portal {
}
.skg-board-theme--light .skg-stat-card {
- background: #0a0a0a;
- color: #fff;
- box-shadow: 0 10px 24px -12px rgba(133, 96, 21, 0.38);
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 84%, rgba(143, 176, 113, 0.2), transparent 50%);
+ border-color: rgba(72, 78, 56, 0.14);
+ background:
+ var(--skg-stat-glow),
+ linear-gradient(180deg, rgba(255, 255, 255, 0.82), rgba(246, 243, 235, 0.58)),
+ rgba(255, 255, 255, 0.56);
+ color: #20241b;
+ box-shadow: 0 12px 28px rgba(74, 68, 44, 0.1);
+}
+
+.skg-board-theme--light .skg-stat-card--violet {
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 84%, rgba(126, 87, 194, 0.22), transparent 50%),
+ radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.5), transparent 34%);
+}
+
+.skg-board-theme--light .skg-stat-card--lime {
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 84%, rgba(200, 205, 25, 0.28), transparent 50%),
+ radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.5), transparent 34%);
+}
+
+.skg-board-theme--light .skg-stat-card--gold {
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 84%, rgba(214, 179, 106, 0.26), transparent 50%),
+ radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.5), transparent 34%);
+}
+
+.skg-board-theme--light .skg-stat-card--teal {
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 84%, rgba(68, 162, 150, 0.24), transparent 50%),
+ radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.5), transparent 34%);
+}
+
+.skg-board-theme--light .skg-stat-card--green {
+ --skg-stat-glow:
+ radial-gradient(circle at 94% 84%, rgba(84, 190, 104, 0.24), transparent 50%),
+ radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.5), transparent 34%);
}
.skg-board-theme--light .skg-stat-card__label {
- color: rgba(255, 255, 255, 0.54);
+ color: rgba(32, 36, 27, 0.48);
}
.skg-board-theme--light .skg-stat-card__value {
- color: #fff;
+ color: #20241b;
}
.skg-board-theme--light .skg-primary-action {
- background: #0a0a0a;
- color: #fff;
- box-shadow: 0 10px 24px -12px rgba(133, 96, 21, 0.42);
+ background: linear-gradient(135deg, #c8cd19, #a2c638);
+ color: #10140d;
+ box-shadow: 0 12px 28px rgba(128, 144, 37, 0.2);
}
.skg-board-theme--light .skg-primary-action:hover {
- background: #252525;
+ background: linear-gradient(135deg, #d6db25, #b0d83d);
+}
+
+.skg-board-theme--light .skg-secondary-action {
+ border-color: rgba(72, 78, 56, 0.16);
+ background: rgba(255, 255, 255, 0.5);
+ color: rgba(32, 36, 27, 0.72);
+}
+
+.skg-board-theme--light .skg-secondary-action:hover {
+ border-color: rgba(143, 176, 113, 0.38);
+ background: rgba(143, 176, 113, 0.12);
+ color: #20241b;
}
.skg-board-theme--light .skg-empty-state {
diff --git a/web/components/ad-recreation-board.tsx b/web/components/ad-recreation-board.tsx
index 4685272..383cf93 100644
--- a/web/components/ad-recreation-board.tsx
+++ b/web/components/ad-recreation-board.tsx
@@ -2515,11 +2515,11 @@ export function AdRecreationBoard({
源视频分析、转换层确认、主体套图、逐句分镜和视频候选集中生产。
-
-
-
-
-
+
+
+
+
+
@@ -2599,27 +2599,38 @@ function WorkbenchRail({
boardTheme: BoardThemeMode
materialPanel: ReactNode
}) {
+ const [hoverOpen, setHoverOpen] = useState(false)
+ const railOpen = materialOpen || hoverOpen
+
return (
-