From 6f2f0eb490e00bed30f1b68be72004f956166275 Mon Sep 17 00:00:00 2001 From: ddCat <2695092045@qq.com> Date: Sat, 19 Sep 2026 20:28:16 +0800 Subject: [PATCH] =?UTF-8?q?refactor(web):=20=E6=A0=B7=E5=BC=8F=E4=BD=93?= =?UTF-8?q?=E7=B3=BB=20-=20=E6=8B=86=E5=88=86=E6=A8=A1=E5=9E=8B=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E3=80=81=E6=BB=9A=E5=8A=A8=E6=9D=A1=E4=B8=8E=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/application.tsx | 3 + .../canvas/canvas-file-upload-content.tsx | 1 + .../components/canvas/canvas-file-upload.css | 71 ++ .../plugins/builtin/editor/editor-shell.css | 73 ++ .../plugins/builtin/editor/editor-shell.tsx | 1 + web/src/pages/create/creation-scrollbars.css | 23 + web/src/pages/create/creation-workspace.tsx | 1 + web/src/styles/globals.css | 1031 +---------------- web/src/styles/shared/model-picker.css | 843 ++++++++++++++ web/src/styles/shared/overlays.css | 28 + web/src/styles/shared/scrollbars.css | 114 ++ web/test/canvas-file-upload-style.test.ts | 32 + web/test/model-picker-style-source.test.ts | 27 + web/test/scrollbar-style-source.test.ts | 32 + 14 files changed, 1287 insertions(+), 993 deletions(-) create mode 100644 web/src/components/canvas/canvas-file-upload.css create mode 100644 web/src/lib/plugins/builtin/editor/editor-shell.css create mode 100644 web/src/pages/create/creation-scrollbars.css create mode 100644 web/src/styles/shared/model-picker.css create mode 100644 web/src/styles/shared/overlays.css create mode 100644 web/src/styles/shared/scrollbars.css create mode 100644 web/test/canvas-file-upload-style.test.ts create mode 100644 web/test/model-picker-style-source.test.ts create mode 100644 web/test/scrollbar-style-source.test.ts diff --git a/web/src/application.tsx b/web/src/application.tsx index 52b71585a..dc57fef24 100644 --- a/web/src/application.tsx +++ b/web/src/application.tsx @@ -2,6 +2,9 @@ import React from "react"; import { createRoot } from "react-dom/client"; import "antd/dist/reset.css"; import "./styles/globals.css"; +import "./styles/shared/model-picker.css"; +import "./styles/shared/overlays.css"; +import "./styles/shared/scrollbars.css"; // 全局自举内置插件注册(editor-shell 等预设以模块副作用注册编辑器插槽): // 冷启动直达编辑器时素材/时间线等插槽不再为空。 import "@/lib/plugins/builtin"; diff --git a/web/src/components/canvas/canvas-file-upload-content.tsx b/web/src/components/canvas/canvas-file-upload-content.tsx index 95d11aebe..fb02e4bda 100644 --- a/web/src/components/canvas/canvas-file-upload-content.tsx +++ b/web/src/components/canvas/canvas-file-upload-content.tsx @@ -4,6 +4,7 @@ import { CanvasNodeType, type CanvasNodeData } from "@/types/canvas"; import { uploadVeilOpacity } from "@/lib/canvas/canvas-file-upload"; import type { CanvasTheme } from "@/lib/canvas-theme"; import { useCanvasNodeActions } from "./canvas-node-action-context"; +import "./canvas-file-upload.css"; export function CanvasFileUploadContent({ node, theme, reduceMotion = false }: { node: CanvasNodeData; theme: CanvasTheme; reduceMotion?: boolean }) { const { upload } = useCanvasNodeActions(); diff --git a/web/src/components/canvas/canvas-file-upload.css b/web/src/components/canvas/canvas-file-upload.css new file mode 100644 index 000000000..9f92857ad --- /dev/null +++ b/web/src/components/canvas/canvas-file-upload.css @@ -0,0 +1,71 @@ +/* Canvas file upload placeholder: a local component owns its visual state. */ +.canvas-file-upload { + --upload-glow-blue: color-mix(in srgb, var(--status-loading) 22%, transparent); + --upload-glow-mint: color-mix(in srgb, var(--status-success) 14%, transparent); + --upload-glow-warm: color-mix(in srgb, var(--status-warning) 12%, transparent); + position: relative; + isolation: isolate; + width: 100%; + height: 100%; + overflow: hidden; + background: var(--upload-surface); + color: var(--upload-text); +} + +.canvas-file-upload-glow { + transition: opacity 180ms ease-out; + position: absolute; + inset: -45%; + background: radial-gradient(ellipse at 28% 32%, var(--upload-glow-blue), transparent 48%), radial-gradient(ellipse at 75% 64%, var(--upload-glow-mint), transparent 46%), radial-gradient(ellipse at 55% 78%, var(--upload-glow-warm), transparent 42%); + animation: canvas-file-upload-drift 5s ease-in-out infinite alternate; + pointer-events: none; +} + +.canvas-file-upload-frost { + transition: opacity 180ms ease-out; + position: absolute; + inset: 0; + background: color-mix(in srgb, var(--upload-surface) 24%, transparent); + backdrop-filter: blur(20px) saturate(0.8); + pointer-events: none; +} + +.canvas-file-upload-frost::after { + content: ""; + position: absolute; + inset: -60%; + background: linear-gradient(110deg, transparent 35%, color-mix(in srgb, var(--upload-text) 4%, transparent) 47%, color-mix(in srgb, var(--upload-surface) 40%, transparent) 51%, transparent 65%); + animation: canvas-file-upload-sheen 4s ease-in-out infinite; +} + +.canvas-file-upload-copy { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: var(--space-2); + height: 100%; + padding: var(--space-5); + text-align: center; +} + +.canvas-file-upload-copy > svg { color: var(--upload-muted); } +.canvas-file-upload-label { font-size: var(--fs-caption); font-weight: 500; } +.canvas-file-upload-detail { max-width: 100%; font-size: var(--fs-tiny); color: var(--upload-muted); overflow-wrap: anywhere; } +.canvas-file-upload-retry { margin-top: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--r-md); background: color-mix(in srgb, var(--upload-text) 8%, transparent); font-size: var(--fs-caption); cursor: pointer; } +.canvas-file-upload-retry:hover { background: color-mix(in srgb, var(--upload-text) 12%, transparent); } +.canvas-file-upload-retry:focus-visible { outline: 2px solid var(--control-focus-ring); outline-offset: 2px; } + +@keyframes canvas-file-upload-drift { from { transform: translate(-8%, -4%) rotate(-8deg); } to { transform: translate(8%, 4%) rotate(12deg); } } +@keyframes canvas-file-upload-sheen { from { transform: translateX(-35%); } to { transform: translateX(35%); } } + +.canvas-file-upload[data-static] .canvas-file-upload-glow, +.canvas-file-upload[data-static] .canvas-file-upload-frost::after { animation: none; } +.canvas-file-upload[data-static] .canvas-file-upload-glow, +.canvas-file-upload[data-static] .canvas-file-upload-frost { transition: none; } + +@media (prefers-reduced-motion: reduce) { + .canvas-file-upload-glow, .canvas-file-upload-frost::after { animation: none; } + .canvas-file-upload-glow, .canvas-file-upload-frost { transition: none; } +} diff --git a/web/src/lib/plugins/builtin/editor/editor-shell.css b/web/src/lib/plugins/builtin/editor/editor-shell.css new file mode 100644 index 000000000..6f9851404 --- /dev/null +++ b/web/src/lib/plugins/builtin/editor/editor-shell.css @@ -0,0 +1,73 @@ +@layer utilities { + /* Editor workbench scrolling and range controls belong to the editor plugin, not the app shell. */ + .director-scroll { + scrollbar-width: thin; + scrollbar-color: rgba(255, 255, 255, 0.2) transparent; + } + .director-scroll::-webkit-scrollbar { + width: 8px; + height: 8px; + } + .director-scroll::-webkit-scrollbar-track { + background: transparent; + } + .director-scroll::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.18); + border-radius: 9999px; + border: 2px solid transparent; + background-clip: padding-box; + } + .director-scroll::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.3); + background-clip: padding-box; + border: 2px solid transparent; + } + .director-scroll::-webkit-scrollbar-corner { + background: transparent; + } + + .editor-slider { + -webkit-appearance: none; + appearance: none; + display: block; + width: 100%; + height: 18px; + background: transparent; + cursor: pointer; + } + .editor-slider::-webkit-slider-runnable-track { + height: 4px; + border-radius: 2px; + background: var(--director-sequencer-border); + box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.3); + } + .editor-slider::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + margin-top: -5px; + height: 14px; + width: 14px; + border-radius: 9999px; + background: var(--director-dock-fg-strong); + border: 2px solid var(--director-sequencer-surface); + box-shadow: 0 1px 3px rgb(0 0 0 / 0.45); + transition: transform 0.12s ease; + } + .editor-slider::-webkit-slider-thumb:hover { + transform: scale(1.15); + } + .editor-slider::-moz-range-track { + height: 4px; + border-radius: 2px; + background: var(--director-sequencer-border); + box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.3); + } + .editor-slider::-moz-range-thumb { + height: 14px; + width: 14px; + border-radius: 9999px; + background: var(--director-dock-fg-strong); + border: 2px solid var(--director-sequencer-surface); + box-shadow: 0 1px 3px rgb(0 0 0 / 0.45); + } +} diff --git a/web/src/lib/plugins/builtin/editor/editor-shell.tsx b/web/src/lib/plugins/builtin/editor/editor-shell.tsx index 12b3bdc91..d07488f77 100644 --- a/web/src/lib/plugins/builtin/editor/editor-shell.tsx +++ b/web/src/lib/plugins/builtin/editor/editor-shell.tsx @@ -9,6 +9,7 @@ import { EditorAssetIngest } from "./editor-asset-ingest"; import { EditorTranscription } from "./editor-transcription"; import { EditorExport } from "./editor-export"; import { EditorAiAssistant } from "./editor-ai-assistant"; +import "./editor-shell.css"; export const EDITOR_SHELL_PLUGIN_ID = "editor-shell"; diff --git a/web/src/pages/create/creation-scrollbars.css b/web/src/pages/create/creation-scrollbars.css new file mode 100644 index 000000000..b05ed08bb --- /dev/null +++ b/web/src/pages/create/creation-scrollbars.css @@ -0,0 +1,23 @@ +@layer utilities { + /* Creation surfaces use a compact, theme-aware scrollbar. */ + .creation-scrollbar { + scrollbar-color: color-mix(in srgb, var(--user-ink, #fff) 22%, transparent) transparent; + scrollbar-gutter: auto; + scrollbar-width: thin; + } + + .creation-scrollbar::-webkit-scrollbar { width: 6px; height: 6px; } + .creation-scrollbar::-webkit-scrollbar-track { background: transparent; } + .creation-scrollbar::-webkit-scrollbar-thumb { + border: 0; + border-radius: 999px; + background: color-mix(in srgb, var(--user-ink, #fff) 18%, transparent); + } + .creation-scrollbar::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--user-ink, #fff) 32%, transparent); } + + html:not(.dark) .creation-scrollbar { + scrollbar-color: color-mix(in srgb, var(--user-ink, #1b1b1f) 22%, transparent) transparent; + } + html:not(.dark) .creation-scrollbar::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--user-ink, #1b1b1f) 16%, transparent); } + html:not(.dark) .creation-scrollbar::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--user-ink, #1b1b1f) 28%, transparent); } +} diff --git a/web/src/pages/create/creation-workspace.tsx b/web/src/pages/create/creation-workspace.tsx index a066ea436..41dc93480 100644 --- a/web/src/pages/create/creation-workspace.tsx +++ b/web/src/pages/create/creation-workspace.tsx @@ -46,6 +46,7 @@ import { creationAttachmentKind, creationMediaAspectRatio, removeCreationAttachm import { conversationTimestamp, isImageAttachment, isVideoAttachment } from "./creation-conversations"; import { conversationTimeFormatter, countOptions, historyDayFormatter, messageTimeFormatter, modeLabels, qualityOptions, ratioOptions, resolutionOptions, shotScriptLabels, type CreationConversation, type CreationMessage, type CreationShotRailEntry, type CreationStatus } from "./creation-types"; import "./creation-product.css"; +import "./creation-scrollbars.css"; import { creationFeaturedWorks, inspirationSource } from "./creation-inspirations"; const CanvasPromptOptimizerDrawer = lazy(() => import("@/components/canvas/canvas-prompt-optimizer-drawer").then((module) => ({ default: module.CanvasPromptOptimizerDrawer }))); diff --git a/web/src/styles/globals.css b/web/src/styles/globals.css index bc2ee4f9c..398fba882 100644 --- a/web/src/styles/globals.css +++ b/web/src/styles/globals.css @@ -3046,42 +3046,6 @@ transform: rotate(180deg); } -.creation-model-picker.canvas-composer-model-picker { - width: min(210px, 25vw); - height: 36px; - border: 1px solid var(--creation-border); - border-radius: 8px; - background: color-mix(in srgb, var(--creation-surface-muted) 70%, transparent); - color: var(--creation-text); - padding: 0 9px; - font-size: 11px; - font-weight: 600; - } - -.creation-model-picker.canvas-composer-model-picker:hover, - .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { - border-color: var(--creation-border-strong); - background: var(--creation-surface-hover); - } - -.dark .creation-model-picker.canvas-composer-model-picker { - border: 1px solid rgba(255, 255, 255, .075); - background: rgba(38, 41, 48, .64); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, .035); - } - -.dark .creation-model-picker.canvas-composer-model-picker:hover, - .dark .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { - border-color: rgba(255, 255, 255, .13); - background: rgba(48, 52, 61, .82); - } - - .creation-model-picker .canvas-model-picker-trigger-icon { - width: 22px; - height: 22px; - border-radius: 6px; - } - .creation-submit-button { display: grid; width: 40px; @@ -3236,8 +3200,7 @@ filter: none !important; } - .creation-control-popover-surface, - .creation-model-picker-surface { + .creation-control-popover-surface { border: 1px solid rgba(220, 225, 231, .82) !important; border-radius: 14px !important; background: rgba(255, 255, 255, .78) !important; @@ -3249,15 +3212,13 @@ animation: creation-popover-enter var(--motion-dur-fast-calc) var(--motion-ease-out) both; } - .dark .creation-control-popover-surface, - .dark .creation-model-picker-surface { + .dark .creation-control-popover-surface { border-color: rgba(61, 66, 76, .72) !important; background: rgba(25, 27, 32, .92) !important; box-shadow: 0 20px 52px rgba(0, 0, 0, .34), inset 0 1px 0 rgba(255, 255, 255, .055) !important; } - .creation-control-popover-content, - .creation-model-picker-surface .ant-popover-inner-content { + .creation-control-popover-content { padding: 0 !important; } @@ -3489,88 +3450,6 @@ font-size: 16px; } - .creation-model-picker-menu { - width: min(384px, calc(100vw - 24px)) !important; - max-height: min(460px, calc(100vh - 24px)); - padding: 8px !important; - background: rgba(255, 255, 255, .7) !important; - color: #17191d !important; - } - - .dark .creation-model-picker-menu { - background: rgba(25, 27, 32, .7) !important; - color: #f2f4f6 !important; - } - - .creation-model-picker-menu .canvas-model-picker-group-label { - padding: 7px 8px 6px; - font-size: 11px; - } - - .creation-model-picker-heading { - display: flex; - min-width: 0; - align-items: center; - gap: 7px; - padding: 3px 8px 9px; - color: #929aa5; - font-size: 12px; - } - - .creation-model-picker-heading strong { - min-width: 0; - overflow: hidden; - color: #17191d; - font-weight: 520; - text-overflow: ellipsis; - white-space: nowrap; - } - - .dark .creation-model-picker-heading { - color: #69717c; - } - - .dark .creation-model-picker-heading strong { - color: #f2f4f6; - } - - .creation-model-picker-menu .canvas-model-picker-option { - min-height: 52px; - border-radius: 9px; - padding: 7px 9px; - transition: background-color 150ms ease, transform 120ms ease; - } - - .creation-model-picker-menu .canvas-model-picker-option:hover { - transform: translateY(-1px); - } - - .creation-model-picker-menu .canvas-model-picker-option > span:first-child { - gap: 12px; - } - - .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { - width: 34px; - height: 34px; - border: 1px solid #e6e8eb; - border-radius: 8px; - background: rgba(255, 255, 255, .66) !important; - } - - .dark .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { - border-color: #30343b; - background: rgba(35, 38, 44, .72) !important; - } - - .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:first-child { - font-size: 13px; - } - - .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:nth-child(2) { - margin-top: 5px; - font-size: 10px; - } - @keyframes creation-results-enter { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } @@ -3753,8 +3632,7 @@ gap: 10px; } -.creation-studio-control, - .creation-model-picker.canvas-composer-model-picker { +.creation-studio-control { display: inline-flex; height: 48px; min-width: 0; @@ -3773,8 +3651,7 @@ transition: transform 150ms var(--motion-ease-out), border-color 150ms ease, background-color 150ms ease; } -html:not(.dark) .creation-studio-control, - html:not(.dark) .creation-model-picker.canvas-composer-model-picker { +html:not(.dark) .creation-studio-control { border-color: rgba(32, 37, 45, .12); background: #f0f2f5; color: #20242a; @@ -3782,18 +3659,14 @@ html:not(.dark) .creation-studio-control, } .creation-studio-control:hover, - .creation-studio-control[aria-expanded="true"], - .creation-model-picker.canvas-composer-model-picker:hover, - .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { +.creation-studio-control[aria-expanded="true"] { border-color: rgba(255, 255, 255, .25); background: #292d34; transform: translateY(-1px); } html:not(.dark) .creation-studio-control:hover, - html:not(.dark) .creation-studio-control[aria-expanded="true"], - html:not(.dark) .creation-model-picker.canvas-composer-model-picker:hover, - html:not(.dark) .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { background: #e7eaee; border-color: rgba(32, 37, 45, .22); } +html:not(.dark) .creation-studio-control[aria-expanded="true"] { background: #e7eaee; border-color: rgba(32, 37, 45, .22); } .creation-studio-control:active { transform: scale(.98); } .creation-studio-control.is-mode { border-color: rgba(6, 182, 212, .36) !important; background: rgba(4, 73, 89, .28) !important; color: #18c2e1 !important; } @@ -3801,13 +3674,6 @@ html:not(.dark) .creation-studio-control:hover, .creation-studio-control > svg:last-child { width: 17px; height: 17px; color: var(--creation-muted); transition: transform 160ms var(--motion-ease-out); } .creation-studio-control > svg:last-child.is-open { transform: rotate(180deg); } -.creation-model-picker.canvas-composer-model-picker { - width: min(328px, 30vw); - justify-content: flex-start; - font-size: 15px; - } - .creation-model-picker .canvas-model-picker-trigger-icon { width: 25px; height: 25px; border-radius: 8px; } - .creation-studio-submit { display: grid; width: 58px; @@ -3970,8 +3836,7 @@ html:not(.dark) .creation-studio-control:hover, padding: 8px 14px 12px; } .creation-chat-controls { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 6px; } - .creation-chat-control, - .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { + .creation-chat-control { display: inline-flex; height: 32px; min-width: 0; @@ -3990,20 +3855,14 @@ html:not(.dark) .creation-studio-control:hover, transition: border-color 140ms ease, background-color 140ms ease, transform 140ms var(--motion-ease-out); } .creation-chat-control:hover, - .creation-chat-control[aria-expanded="true"], - .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover, - .creation-chat-composer .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { border-color: rgba(255, 255, 255, .12); background: #272b32; transform: translateY(-1px); } +.creation-chat-control[aria-expanded="true"] { border-color: rgba(255, 255, 255, .12); background: #272b32; transform: translateY(-1px); } .creation-chat-control:active { transform: scale(.98); } .creation-chat-control > svg { width: 15px; height: 15px; flex: 0 0 auto; } .creation-chat-control > svg:last-child { width: 14px; height: 14px; color: var(--creation-muted); transition: transform 160ms var(--motion-ease-out); } .creation-chat-control > svg:last-child.is-open { transform: rotate(180deg); } - .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { width: min(196px, 26vw); justify-content: flex-start; } - .creation-chat-composer .creation-model-picker .canvas-model-picker-trigger-icon { width: 19px; height: 19px; border-radius: 5px; } - html:not(.dark) .creation-chat-control, - html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { border-color: transparent; background: #f1f3f5; color: #262b32; } - html:not(.dark) .creation-chat-control:hover, - html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover { border-color: rgba(20, 26, 35, .2); background: #e9edf1; } + html:not(.dark) .creation-chat-control { border-color: transparent; background: #f1f3f5; color: #262b32; } + html:not(.dark) .creation-chat-control:hover { border-color: rgba(20, 26, 35, .2); background: #e9edf1; } .creation-control-popover-surface { border: 0 !important; @@ -4102,8 +3961,7 @@ html:not(.dark) .creation-studio-control:hover, .creation-chat-editor textarea { min-height: 68px; font-size: 14px; } .creation-chat-dock { align-items: flex-end; padding: 8px 9px 9px 12px; } .creation-chat-controls { max-width: calc(100% - 42px); gap: 5px; } -.creation-chat-control, .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { height: 34px; padding: 0 8px; font-size: 11px; } -.creation-chat-composer .creation-model-picker.canvas-composer-model-picker { width: min(152px, 48vw); } +.creation-chat-control { height: 34px; padding: 0 8px; font-size: 11px; } .creation-thread-stage { padding-top: 28px; } .creation-assistant-message { margin-bottom: 32px; } .creation-message-content, .creation-message-error { padding-left: 0; } @@ -4168,11 +4026,6 @@ html:not(.dark) .creation-studio-control:hover, padding: 0 9px; } -.creation-model-picker.canvas-composer-model-picker { - width: min(194px, 62vw); - height: 34px; - } - .creation-submit-button { width: 38px; height: 38px; @@ -4198,7 +4051,6 @@ html:not(.dark) .creation-studio-control:hover, padding: 10px; } - .creation-model-picker-menu, .creation-duration-panel { width: min(440px, calc(100vw - 96px)) !important; } @@ -4294,9 +4146,7 @@ html:not(.dark) .creation-studio-control:hover, } .creation-studio-controls { max-width: calc(100% - 58px); gap: 8px; } -.creation-studio-control, - .creation-model-picker.canvas-composer-model-picker { height: 42px; border-radius: 12px; padding: 0 11px; font-size: 12px; } -.creation-model-picker.canvas-composer-model-picker { width: min(150px, 44vw); } +.creation-studio-control { height: 42px; border-radius: 12px; padding: 0 11px; font-size: 12px; } .creation-studio-control > svg { width: 16px; height: 16px; } .creation-studio-submit { width: 50px; height: 50px; } } @@ -7369,15 +7219,6 @@ html:not(.dark) .creation-studio-control:hover, } } - .hide-scrollbar { - -ms-overflow-style: none; - scrollbar-width: none; - } - - .hide-scrollbar::-webkit-scrollbar { - display: none; - } - .prompt-filter-tag.ant-tag-checkable { margin: 0; border: 1px solid transparent; @@ -7406,116 +7247,6 @@ html:not(.dark) .creation-studio-control:hover, font-weight: 600; } - .thin-scrollbar { - scrollbar-color: rgba(120, 113, 108, 0.45) transparent; - scrollbar-width: thin; - } - - .script-column-picker { - display: flex; - flex-wrap: wrap; - gap: 6px 12px; - font-size: 12px; - } - - .thin-scrollbar::-webkit-scrollbar { - height: 4px; - width: 4px; - } - - .thin-scrollbar::-webkit-scrollbar-thumb { - background: rgba(120, 113, 108, 0.45); - border-radius: 999px; - } - - .storyboard-scrollbar { - overscroll-behavior: contain; - scrollbar-color: rgba(148, 163, 184, 0.72) rgba(120, 113, 108, 0.14); - scrollbar-gutter: stable; - scrollbar-width: auto; - } - - /* 表头与滚动行区共享同宽 scrollbar gutter,保证列线对齐;滚动条本身透明隐藏 */ - .storyboard-header-gutter { - overflow-x: hidden; - overflow-y: scroll; - scrollbar-color: transparent transparent; - scrollbar-gutter: stable; - scrollbar-width: auto; - } - - .storyboard-scrollbar::-webkit-scrollbar { - width: 12px; - } - - .storyboard-scrollbar::-webkit-scrollbar-track { - background: rgba(120, 113, 108, 0.14); - border-left: 1px solid rgba(120, 113, 108, 0.18); - } - - .storyboard-scrollbar::-webkit-scrollbar-thumb { - min-height: 40px; - border: 2px solid transparent; - border-radius: 999px; - background: rgba(148, 163, 184, 0.72); - background-clip: content-box; - } - - .storyboard-scrollbar::-webkit-scrollbar-thumb:hover { - background: rgba(186, 196, 210, 0.9); - background-clip: content-box; - } - - .hover-scrollbar { - scrollbar-color: transparent transparent; - scrollbar-width: thin; - } - - .hover-scrollbar:hover { - scrollbar-color: rgba(120, 113, 108, 0.5) transparent; - } - - .hover-scrollbar::-webkit-scrollbar { - height: 6px; - width: 6px; - } - - .hover-scrollbar::-webkit-scrollbar-thumb { - background: transparent; - border-radius: 999px; - } - - .hover-scrollbar:hover::-webkit-scrollbar-track { - background: rgba(120, 113, 108, 0.12); - border-radius: 999px; - } - - .hover-scrollbar:hover::-webkit-scrollbar-thumb { - background: rgba(120, 113, 108, 0.5); - } - - .hover-scrollbar-hint { - position: relative; - } - - .hover-scrollbar-hint::after { - background: rgba(120, 113, 108, 0.42); - border-radius: 999px; - bottom: 4px; - content: ""; - height: 3px; - left: 12px; - opacity: 0; - pointer-events: none; - position: absolute; - right: 12px; - transition: opacity 0.18s ease; - } - - .hover-scrollbar-hint:hover::after { - opacity: 1; - } - .canvas-control-select.ant-select .ant-select-content, .canvas-control-number.ant-input-number { border-color: rgba(120, 113, 108, 0.32) !important; @@ -7557,86 +7288,10 @@ html:not(.dark) .creation-studio-control:hover, } .canvas-composer-tools .canvas-composer-mode-button span, - .canvas-composer-tools .canvas-model-picker-label > span:nth-child(n + 2), - .canvas-composer-tools .canvas-composer-icon.ant-btn > span:not(.ant-btn-icon) { +.canvas-composer-tools .canvas-composer-icon.ant-btn > span:not(.ant-btn-icon) { display: none; } - .canvas-composer-tools .canvas-composer-model-picker { - width: 32px; - min-width: 32px; - } - - .canvas-composer-tools .canvas-composer-model-picker { - padding-inline: 7px !important; - } - - .canvas-composer-tools .canvas-model-picker-label { - min-width: 0; - } - - .canvas-composer-model-picker { - align-items: center; - appearance: none; - background: color-mix(in srgb, var(--workspace-surface-strong) 94%, var(--workspace-accent) 6%); - border: 0; - border-radius: 9px; - color: var(--foreground); - cursor: pointer; - display: flex; - font: inherit; - gap: 8px; - height: 32px; - justify-content: space-between; - line-height: 1; - max-width: 100%; - min-width: 0; - outline: none !important; - padding: 0 9px; - text-align: left; - transition: background-color var(--motion-instant) ease-out, color var(--motion-instant) ease-out; - } - - .canvas-composer-model-picker:hover { - background: color-mix(in srgb, var(--workspace-surface-strong) 88%, var(--workspace-accent) 12%); - } - - .canvas-composer-model-picker:focus, - .canvas-composer-model-picker:focus-visible, - .canvas-composer-model-picker[aria-expanded="true"] { - background: color-mix(in srgb, var(--workspace-surface-strong) 84%, var(--workspace-accent) 16%); - box-shadow: none !important; - outline: none !important; - } - - .canvas-model-picker-label { - flex: 1 1 auto; - overflow: hidden; - } - - .canvas-model-picker-trigger-icon { - align-items: center; - border-radius: 6px; - display: inline-flex; - flex: 0 0 22px; - height: 22px; - justify-content: center; - width: 22px; - } - - .canvas-model-picker-chevron { - color: color-mix(in srgb, var(--foreground) 52%, transparent); - flex: 0 0 14px; - height: 14px; - transition: transform var(--motion-instant) ease-out; - width: 14px; - } - - .canvas-model-picker-chevron.is-open { - transform: rotate(180deg); - } - - .canvas-model-picker-popover, .canvas-preset-picker-popover { filter: none !important; } @@ -7660,96 +7315,6 @@ html:not(.dark) .creation-studio-control:hover, padding: 0 !important; } - .canvas-model-picker-menu { - width: max-content !important; - min-width: max(var(--canvas-model-picker-trigger-width, 0px), 260px); - max-width: calc(100vw - 24px); - max-height: min(420px, calc(100vh - 32px)); - overflow-x: hidden; - overflow-y: auto; - padding: 4px; - } - - .canvas-model-picker-group + .canvas-model-picker-group { - border-top: 1px solid var(--workspace-border); - margin-top: 5px; - padding-top: 5px; - } - - .canvas-model-picker-group-label { - align-items: center; - display: flex; - font-size: 10px; - font-weight: 600; - gap: 6px; - letter-spacing: 0.02em; - min-width: 0; - padding: 5px 7px 4px; - } - - .canvas-model-picker-option { - align-items: center; - border: 0; - border-radius: 7px; - cursor: pointer; - display: flex; - gap: 8px; - max-width: 100%; - min-height: 40px; - min-width: 0; - outline: none; - overflow: hidden; - padding: 6px 7px; - text-align: left; - transition: background-color var(--motion-instant) ease-out; - width: 100%; - } - - .canvas-model-picker-option:hover { - background: color-mix(in srgb, var(--workspace-accent) 9%, transparent) !important; - } - - .canvas-model-picker-option[aria-selected="true"] { - background: color-mix(in srgb, var(--workspace-accent) 6%, transparent) !important; - } - - .canvas-model-picker-option:focus-visible { - background: color-mix(in srgb, var(--workspace-accent) 13%, transparent) !important; - outline: none; - } - - .canvas-model-picker-option > span:first-child { - flex: 1 1 auto; - min-width: 0; - overflow: hidden; - display: flex; - align-items: center; - width: 100%; - } - - .canvas-model-picker-popover .canvas-model-picker-option > span:first-child > span:nth-child(2) { - flex: 0 0 auto; - min-width: max-content; - overflow: visible; - } - - .canvas-model-picker-popover .canvas-model-picker-option > span:first-child > span:nth-child(2) > span { - overflow: visible; - text-overflow: clip; - } - - .canvas-model-picker-option-check { - flex: 0 0 14px; - height: 14px; - width: 14px; - } - - .canvas-model-picker-empty { - font-size: 11px; - padding: 22px 12px; - text-align: center; - } - .canvas-preset-picker-trigger:focus-visible, .canvas-preset-picker-trigger[aria-expanded="true"] { background: color-mix(in srgb, var(--workspace-accent) 18%, transparent) !important; @@ -7785,17 +7350,14 @@ html:not(.dark) .creation-studio-control:hover, color: color-mix(in srgb, var(--workspace-accent) 72%, var(--foreground)); } - html:not(.dark) .canvas-composer-model-picker, html:not(.dark) .canvas-generation-settings-trigger.ant-btn { background: rgba(15, 23, 42, 0.045) !important; color: #1f2937 !important; } - html:not(.dark) .canvas-composer-model-picker:hover, - html:not(.dark) .canvas-composer-model-picker[aria-expanded="true"], html:not(.dark) .canvas-generation-settings-trigger.ant-btn:hover, - html:not(.dark) .canvas-generation-settings-trigger.ant-btn:focus-visible, - html:not(.dark) .canvas-generation-settings-trigger.ant-btn[aria-expanded="true"] { +html:not(.dark) .canvas-generation-settings-trigger.ant-btn:focus-visible, +html:not(.dark) .canvas-generation-settings-trigger.ant-btn[aria-expanded="true"] { background: rgba(15, 23, 42, 0.075) !important; } @@ -7895,19 +7457,6 @@ html:not(.dark) .creation-studio-control:hover, display: inline-flex; min-width: 0; } - - .canvas-composer-tools .canvas-composer-model-picker { - width: auto; - min-width: 9rem; - } - - .canvas-composer-tools .canvas-composer-model-picker { - padding-inline: 10px !important; - } - - .canvas-composer-tools .canvas-model-picker-label > span:nth-child(n + 2) { - display: inline-flex; - } } .canvas-control-select.ant-select-focused .ant-select-content, @@ -9056,52 +8605,11 @@ html:not(.dark) .creation-studio-control:hover, } .canvas-prompt-optimizer-mode-trigger:focus-visible, - .canvas-prompt-optimizer-send:focus-visible, - .canvas-prompt-optimizer-model-picker:focus-visible { +.canvas-prompt-optimizer-send:focus-visible { outline: 2px solid color-mix(in srgb, var(--workspace-accent) 64%, transparent); outline-offset: 1px; } - .canvas-prompt-optimizer-model-picker.canvas-composer-model-picker { - flex: 1 1 132px; - width: 132px !important; - max-width: 132px; - min-width: 0 !important; - height: 28px !important; - border-color: transparent !important; - border-radius: var(--r-md) !important; - background: transparent !important; - padding: 0 6px !important; - color: color-mix(in srgb, var(--foreground) 62%, transparent) !important; - font-size: var(--fs-micro) !important; - } - - .canvas-prompt-optimizer-model-picker.canvas-composer-model-picker:hover, - .canvas-prompt-optimizer-model-picker.canvas-composer-model-picker[aria-expanded="true"] { - border-color: transparent !important; - background: color-mix(in srgb, var(--foreground) 7%, transparent) !important; - color: var(--foreground) !important; - } - - .canvas-prompt-optimizer-model-picker .canvas-model-picker-trigger-icon { - width: 18px; - height: 18px; - border-radius: 5px; - } - - .canvas-prompt-optimizer-model-picker .canvas-model-picker-label { - gap: 5px; - } - - .canvas-prompt-optimizer-model-picker .canvas-model-picker-chevron { - width: 11px; - height: 11px; - } - - .canvas-prompt-optimizer-model-popover .creation-model-picker-heading { - display: none; - } - .canvas-prompt-optimizer-mode-dropdown .ant-dropdown-menu { width: min(278px, calc(100vw - 32px)); min-width: 0; @@ -9620,10 +9128,6 @@ html:not(.dark) .creation-studio-control:hover, .canvas-prompt-optimizer-context { max-width: 120px; } - - .canvas-prompt-optimizer-model-picker.canvas-composer-model-picker { - max-width: 112px; - } } @container (max-width: 350px) { @@ -9648,11 +9152,6 @@ html:not(.dark) .creation-studio-control:hover, overflow: hidden; text-overflow: ellipsis; } - - .canvas-prompt-optimizer-model-picker.canvas-composer-model-picker { - max-width: 96px; - padding-inline: 3px !important; - } } .canvas-node-composer-header { @@ -10785,27 +10284,6 @@ html[data-theme-switching="true"] :where(.canvas-node-shell, .aceternity-comet-c color: var(--creation-text); } -.creation-scrollbar { - scrollbar-color: color-mix(in srgb, var(--user-ink, #fff) 22%, transparent) transparent; - scrollbar-gutter: auto; - scrollbar-width: thin; -} - -.creation-scrollbar::-webkit-scrollbar { width: 6px; height: 6px; } -.creation-scrollbar::-webkit-scrollbar-track { background: transparent; } -.creation-scrollbar::-webkit-scrollbar-thumb { - border: 0; - border-radius: 999px; - background: color-mix(in srgb, var(--user-ink, #fff) 18%, transparent); -} -.creation-scrollbar::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--user-ink, #fff) 32%, transparent); } - -html:not(.dark) .creation-scrollbar { - scrollbar-color: color-mix(in srgb, var(--user-ink, #1b1b1f) 22%, transparent) transparent; -} -html:not(.dark) .creation-scrollbar::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--user-ink, #1b1b1f) 16%, transparent); } -html:not(.dark) .creation-scrollbar::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--user-ink, #1b1b1f) 28%, transparent); } - html:not(.dark) .creation-home { --creation-bg: var(--workspace-page); --creation-surface: #ffffff; @@ -10933,8 +10411,7 @@ html:not(.dark) .creation-chat-reference:hover:not(:disabled) { background: rgba /* 录音条自身可压缩,避免波形 + 胶囊同时出现时把右侧控件挤到第二行。 */ .creation-chat-controls:has(> .voice-recording-inline) { flex-wrap: nowrap; } -.creation-chat-control, -.creation-chat-composer .creation-model-picker.canvas-composer-model-picker { +.creation-chat-control { display: inline-flex; height: 32px; min-width: 0; @@ -10952,9 +10429,7 @@ html:not(.dark) .creation-chat-reference:hover:not(:disabled) { background: rgba } .creation-chat-control:hover, -.creation-chat-control[aria-expanded="true"], -.creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover, -.creation-chat-composer .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { +.creation-chat-control[aria-expanded="true"] { border: 0; background: rgba(255, 255, 255, .075); color: var(--creation-text); @@ -10972,13 +10447,9 @@ html:not(.dark) .creation-chat-reference:hover:not(:disabled) { background: rgba .creation-chat-control > svg { width: 14px; height: 14px; } .creation-chat-control > svg:last-child { width: 12px; height: 12px; color: var(--creation-faint); } -.creation-chat-composer .creation-model-picker.canvas-composer-model-picker { width: min(180px, 30vw); justify-content: flex-start; } -.creation-chat-composer .creation-model-picker .canvas-model-picker-trigger-icon { width: 16px; height: 16px; border-radius: 4px; background: transparent !important; } -html:not(.dark) .creation-chat-control, -html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { background: transparent; color: var(--creation-muted); } -html:not(.dark) .creation-chat-control:hover, -html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover { background: rgba(29, 33, 37, .06); color: var(--creation-text); } +html:not(.dark) .creation-chat-control { background: transparent; color: var(--creation-muted); } +html:not(.dark) .creation-chat-control:hover { background: rgba(29, 33, 37, .06); color: var(--creation-text); } .creation-mode-capsule { display: inline-flex; @@ -11015,8 +10486,7 @@ html:not(.dark) .creation-chat-control[aria-pressed="true"], html:not(.dark) .creation-chat-control[aria-pressed="true"]:hover { background: var(--control-selected-bg); color: var(--control-selected-fg); } html:not(.dark) .creation-chat-control[aria-pressed="true"] > svg { color: var(--control-selected-fg); } -.creation-control-popover-surface, -.creation-model-picker-surface { +.creation-control-popover-surface { overflow: hidden; border: 0 !important; border-radius: 10px !important; @@ -11026,8 +10496,7 @@ html:not(.dark) .creation-chat-control[aria-pressed="true"] > svg { color: var(- -webkit-backdrop-filter: blur(18px) saturate(120%); } -.creation-control-popover-content, -.creation-model-picker-surface .ant-popover-inner-content { padding: 0 !important; } +.creation-control-popover-content { padding: 0 !important; } .creation-parameter-menu { width: 274px; padding: 10px 12px 12px; } .creation-parameter-section { display: grid; grid-template-columns: 38px minmax(0, 1fr); align-items: start; gap: 8px; } @@ -11072,17 +10541,6 @@ html:not(.dark) .creation-chat-control[aria-pressed="true"] > svg { color: var(- .creation-range-wrap input::-moz-range-thumb { width: 6px; height: 14px; border-radius: 4px; } .creation-range-labels { margin-top: 2px; color: var(--creation-faint); font-size: 9px; } -.creation-model-picker-menu { width: min(332px, calc(100vw - 24px)) !important; max-height: min(420px, calc(100vh - 24px)); padding: 7px !important; background: transparent !important; color: #f0f1f2 !important; } -.creation-model-picker-heading { display: flex; align-items: center; gap: 6px; padding: 4px 7px 7px; color: #8e949d; font-size: 10px; } -.creation-model-picker-heading strong { color: #e6e8eb; font-weight: 500; } -.creation-model-picker-menu .canvas-model-picker-group-label { padding: 6px 7px 5px; font-size: 10px; } -.creation-model-picker-menu .canvas-model-picker-option { min-height: 43px; border-radius: 6px; padding: 5px 7px; } -.creation-model-picker-menu .canvas-model-picker-option:hover { transform: none; } -.creation-model-picker-menu .canvas-model-picker-option > span:first-child { gap: 8px; } -.creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { width: 26px; height: 26px; border: 0; border-radius: 5px; background: rgba(255, 255, 255, .07) !important; } -.creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:first-child { font-size: 11px; } -.creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:nth-child(2) { margin-top: 3px; font-size: 9px; } - .creation-thread-stage { width: min(820px, calc(100% - 48px)); padding: 44px 0 22px; } .creation-thread-composer { width: min(820px, calc(100% - 48px)); padding: 8px 0 16px; } .creation-chat-composer.is-thread .creation-chat-writing-surface { min-height: 70px; padding: 12px 14px 4px; } @@ -11094,16 +10552,12 @@ html:not(.dark) .creation-chat-control[aria-pressed="true"] > svg { color: var(- .creation-new-button { border: 0; border-radius: 8px; background: rgba(255, 255, 255, .06); box-shadow: none; } .creation-new-button:hover { border: 0; background: rgba(255, 255, 255, .12); } -html:not(.dark) .creation-control-popover-surface, -html:not(.dark) .creation-model-picker-surface { background: rgba(255, 255, 255, .94) !important; box-shadow: 0 16px 38px rgba(28, 32, 37, .12) !important; } +html:not(.dark) .creation-control-popover-surface { background: rgba(255, 255, 255, .94) !important; box-shadow: 0 16px 38px rgba(28, 32, 37, .12) !important; } html:not(.dark) .creation-parameter-section h3, -html:not(.dark) .creation-duration-menu > div:first-child, -html:not(.dark) .creation-model-picker-menu { color: #727980 !important; } +html:not(.dark) .creation-duration-menu > div:first-child { color: #727980 !important; } html:not(.dark) .creation-choice-grid button { color: #737a82; } html:not(.dark) .creation-choice-grid button:hover { background: rgba(28, 32, 37, .06); color: #25292e; } -html:not(.dark) .creation-duration-menu strong, -html:not(.dark) .creation-model-picker-heading strong { color: #20242a; } -html:not(.dark) .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { background: rgba(28, 32, 37, .06) !important; } +html:not(.dark) .creation-duration-menu strong { color: #20242a; } @keyframes creation-composer-arrive { from { opacity: 0; transform: translateY(8px); } @@ -11116,8 +10570,7 @@ html:not(.dark) .creation-model-picker-menu .canvas-model-picker-option > span:f .creation-chat-dock { align-items: flex-end; padding: 4px 7px 8px 8px; } .creation-chat-controls { max-width: none; } .creation-chat-controls:has(> .voice-recording-inline) { flex-wrap: wrap; } -.creation-chat-control, .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { height: 29px; padding: 0 6px; font-size: 10px; } -.creation-chat-composer .creation-model-picker.canvas-composer-model-picker { width: min(136px, 42vw); } +.creation-chat-control { height: 29px; padding: 0 6px; font-size: 10px; } .creation-thread-stage, .creation-thread-composer { width: calc(100% - 28px); } .creation-parameter-menu { width: min(274px, calc(100vw - 24px)); } } @@ -11999,8 +11452,7 @@ html:not(.dark) .creation-duration-choices button:hover { background: rgba(28, 3 .creation-home .creation-chat-mention-editor { min-height: 60px; max-height: 320px; } .creation-home .creation-chat-dock { min-height: 48px; padding: 4px 12px 12px 16px; } -.creation-home .creation-chat-control, -.creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { +.creation-home .creation-chat-control { border: 0; background: transparent; box-shadow: none; @@ -12008,9 +11460,7 @@ html:not(.dark) .creation-duration-choices button:hover { background: rgba(28, 3 } .creation-home .creation-chat-control:hover, -.creation-home .creation-chat-control[aria-expanded="true"], -.creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover, -.creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { +.creation-home .creation-chat-control[aria-expanded="true"] { border: 0; background: rgba(255, 255, 255, .065); color: var(--creation-text); @@ -12018,8 +11468,7 @@ html:not(.dark) .creation-duration-choices button:hover { background: rgba(28, 3 } html:not(.dark) .creation-home .creation-chat-control:hover, -html:not(.dark) .creation-home .creation-chat-control[aria-expanded="true"], -html:not(.dark) .creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover { background: rgba(28, 32, 37, .06); } +html:not(.dark) .creation-home .creation-chat-control[aria-expanded="true"] { background: rgba(28, 32, 37, .06); } .creation-home .creation-chat-controls > .voice-recording-inline { max-width: 236px; @@ -12145,8 +11594,7 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background: /* 旧创作规则位于 utilities 层且使用 !important;必须在同层覆盖。 */ @layer utilities { - .creation-home .creation-chat-control, - .creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { + .creation-home .creation-chat-control { border: 0; background: transparent; box-shadow: none; @@ -12154,9 +11602,7 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background: } .creation-home .creation-chat-control:hover, - .creation-home .creation-chat-control[aria-expanded="true"], - .creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover, - .creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { +.creation-home .creation-chat-control[aria-expanded="true"] { border: 0; background: rgba(255, 255, 255, .065); color: var(--creation-text); @@ -15550,111 +14996,6 @@ html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 .creation-home .creation-media-error { width: 100%; margin-left: 0; } } -/* --- 编辑器工作台细滚动条(Concat thin-scroll 参照:8px 细轨 + 圆角滑块,明暗面板通用)--- */ -.director-scroll { - scrollbar-width: thin; - scrollbar-color: rgba(255, 255, 255, 0.2) transparent; -} -.director-scroll::-webkit-scrollbar { - width: 8px; - height: 8px; -} -.director-scroll::-webkit-scrollbar-track { - background: transparent; -} -.director-scroll::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.18); - border-radius: 9999px; - border: 2px solid transparent; - background-clip: padding-box; -} -.director-scroll::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.3); - background-clip: padding-box; - border: 2px solid transparent; -} -.director-scroll::-webkit-scrollbar-corner { - background: transparent; -} - -/* --- 编辑器 sunken 滑块(Concat 参照:凹陷轨道 + 圆点滑块,跟随主题 token)--- */ -.editor-slider { - -webkit-appearance: none; - appearance: none; - display: block; - width: 100%; - height: 18px; - background: transparent; - cursor: pointer; -} -.editor-slider::-webkit-slider-runnable-track { - height: 4px; - border-radius: 2px; - background: var(--director-sequencer-border); - box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.3); -} -.editor-slider::-webkit-slider-thumb { - -webkit-appearance: none; - appearance: none; - margin-top: -5px; - height: 14px; - width: 14px; - border-radius: 9999px; - background: var(--director-dock-fg-strong); - border: 2px solid var(--director-sequencer-surface); - box-shadow: 0 1px 3px rgb(0 0 0 / 0.45); - transition: transform 0.12s ease; -} -.editor-slider::-webkit-slider-thumb:hover { - transform: scale(1.15); -} -.editor-slider::-moz-range-track { - height: 4px; - border-radius: 2px; - background: var(--director-sequencer-border); - box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.3); -} -.editor-slider::-moz-range-thumb { - height: 14px; - width: 14px; - border-radius: 9999px; - background: var(--director-dock-fg-strong); - border: 2px solid var(--director-sequencer-surface); - box-shadow: 0 1px 3px rgb(0 0 0 / 0.45); -} - -/* ───────────────────────────────────────────────────────────── - * Select 弹层 / Tooltip 入场动画(kit 组件消费;描边 + 淡入) - * ───────────────────────────────────────────────────────────── */ -@keyframes ra-pop-in { - from { - opacity: 0; - transform: translateY(-3px) scale(0.985); - } - to { - opacity: 1; - transform: translateY(0) scale(1); - } -} - -.ra-pop-in { - transform-origin: var(--ra-pop-origin, top); - animation: ra-pop-in var(--ra-pop-duration, 150ms) var(--workspace-ease, cubic-bezier(0.4, 0, 0.2, 1)); -} -/* react-aria 弹层按 data-placement 选择弹出方向(select/tooltip/dropdown 通用)*/ -.ra-pop-in[data-placement^="top"] { --ra-pop-origin: bottom center; } -.ra-pop-in[data-placement^="bottom"] { --ra-pop-origin: top center; } -.ra-pop-in[data-placement^="left"] { --ra-pop-origin: right center; } -.ra-pop-in[data-placement^="right"] { --ra-pop-origin: left center; } - -@media (prefers-reduced-motion: reduce) { - .ra-pop-in { - animation: none; - } - - -} - /* —— 创建页空态推荐主卡(吸收 boardui pro-prompt 光晕卡形态)—— */ .creation-home .creation-hero-prompt { position: relative; @@ -15757,70 +15098,6 @@ html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 } .creation-history-group-head h4::after { content: ""; flex: 1; height: 1px; background: var(--creation-history-line); transform: translateY(-2px); } -/* 图片上传:浅磨砂与低饱和流光,和模型生成状态分离。 */ -.canvas-file-upload { - --upload-glow-blue: color-mix(in srgb, var(--status-loading) 22%, transparent); - --upload-glow-mint: color-mix(in srgb, var(--status-success) 14%, transparent); - --upload-glow-warm: color-mix(in srgb, var(--status-warning) 12%, transparent); - position: relative; - isolation: isolate; - width: 100%; - height: 100%; - overflow: hidden; - background: var(--upload-surface); - color: var(--upload-text); -} -.canvas-file-upload-glow { - transition: opacity 180ms ease-out; - position: absolute; - inset: -45%; - background: radial-gradient(ellipse at 28% 32%, var(--upload-glow-blue), transparent 48%), radial-gradient(ellipse at 75% 64%, var(--upload-glow-mint), transparent 46%), radial-gradient(ellipse at 55% 78%, var(--upload-glow-warm), transparent 42%); - animation: canvas-file-upload-drift 5s ease-in-out infinite alternate; - pointer-events: none; -} -.canvas-file-upload-frost { - transition: opacity 180ms ease-out; - position: absolute; - inset: 0; - background: color-mix(in srgb, var(--upload-surface) 24%, transparent); - backdrop-filter: blur(20px) saturate(0.8); - pointer-events: none; -} -.canvas-file-upload-frost::after { - content: ""; - position: absolute; - inset: -60%; - background: linear-gradient(110deg, transparent 35%, color-mix(in srgb, var(--upload-text) 4%, transparent) 47%, color-mix(in srgb, var(--upload-surface) 40%, transparent) 51%, transparent 65%); - animation: canvas-file-upload-sheen 4s ease-in-out infinite; -} -.canvas-file-upload-copy { - position: relative; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: var(--space-2); - height: 100%; - padding: var(--space-5); - text-align: center; -} -.canvas-file-upload-copy > svg { color: var(--upload-muted); } -.canvas-file-upload-label { font-size: var(--fs-caption); font-weight: 500; } -.canvas-file-upload-detail { max-width: 100%; font-size: var(--fs-tiny); color: var(--upload-muted); overflow-wrap: anywhere; } -.canvas-file-upload-retry { margin-top: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--r-md); background: color-mix(in srgb, var(--upload-text) 8%, transparent); font-size: var(--fs-caption); cursor: pointer; } -.canvas-file-upload-retry:hover { background: color-mix(in srgb, var(--upload-text) 12%, transparent); } -.canvas-file-upload-retry:focus-visible { outline: 2px solid var(--control-focus-ring); outline-offset: 2px; } -@keyframes canvas-file-upload-drift { from { transform: translate(-8%, -4%) rotate(-8deg); } to { transform: translate(8%, 4%) rotate(12deg); } } -@keyframes canvas-file-upload-sheen { from { transform: translateX(-35%); } to { transform: translateX(35%); } } -.canvas-file-upload[data-static] .canvas-file-upload-glow, -.canvas-file-upload[data-static] .canvas-file-upload-frost::after { animation: none; } -.canvas-file-upload[data-static] .canvas-file-upload-glow, -.canvas-file-upload[data-static] .canvas-file-upload-frost { transition: none; } -@media (prefers-reduced-motion: reduce) { - .canvas-file-upload-glow, .canvas-file-upload-frost::after { animation: none; } - .canvas-file-upload-glow, .canvas-file-upload-frost { transition: none; } -} - /* ===== 2026-09 user workspace alignment ===== 这一组规则只作用于真实用户端壳层和首页,后台与画布编辑器保持原有职责和交互。 几何基准:侧栏 216px、顶部 64px、导航行 44px、首页内容最大宽度 1180px。 */ @@ -17196,167 +16473,6 @@ html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 height: 12px; } -/* 品牌/模型两级菜单是 ModelPicker 默认结构,不能只写在 creation variant 下。 */ -.canvas-model-picker-brands { - display: grid; - gap: 4px; - width: 100%; -} -.canvas-model-picker-brand { - display: flex; - width: 100%; - min-height: 48px; - min-width: 0; - align-items: center; - gap: 10px; - border: 1px solid transparent; - border-radius: 10px; - padding: 8px 10px; - background: transparent; - color: inherit; - text-align: left; - cursor: pointer; -} -.canvas-model-picker-brand:hover, -.canvas-model-picker-brand.is-active { - border-color: var(--workspace-border); - background: var(--workspace-surface-hover); -} -.canvas-model-picker-brand-icon { - display: grid; - width: 32px; - height: 32px; - flex: 0 0 32px; - place-items: center; - border-radius: 9px; - background: var(--workspace-surface-hover); -} -.canvas-model-picker-brand-copy { - display: grid; - min-width: 0; - flex: 1; - gap: 2px; -} -.canvas-model-picker-brand-copy strong { - overflow: hidden; - font-size: 13px; - font-weight: 650; - text-overflow: ellipsis; - white-space: nowrap; -} -.canvas-model-picker-brand-copy small { - overflow: hidden; - color: color-mix(in srgb, currentColor 55%, transparent); - font-size: 10px; - text-overflow: ellipsis; - white-space: nowrap; -} -.canvas-model-picker-brand-arrow { - width: 14px; - height: 14px; - flex: 0 0 14px; - color: color-mix(in srgb, currentColor 48%, transparent); - transform: rotate(-90deg); -} -.canvas-model-picker-menu.is-brand-list { - width: min(360px, calc(100vw - 24px)) !important; -} -.canvas-model-picker-menu.is-model-list { - width: min(720px, calc(100vw - 24px)) !important; -} -.canvas-model-picker-two-pane { - display: grid; - width: 100%; - grid-template-columns: 250px minmax(0, 1fr); - gap: 14px; - min-width: 0; - align-items: start; -} -.canvas-model-picker-menu.is-model-list .canvas-model-picker-brand-rail { - display: grid; - align-content: start; - gap: 5px; - border-right: 1px solid var(--workspace-border); - padding-right: 14px; -} -.canvas-model-picker-menu.is-model-list .canvas-model-picker-brand { - width: 100%; -} -.canvas-model-picker-model-pane { - min-width: 0; -} -@media (max-width: 720px) { - .canvas-model-picker-menu:is(.is-brand-list, .is-model-list) { - width: calc(100vw - 24px) !important; - } - .canvas-model-picker-two-pane { - grid-template-columns: minmax(0, 1fr); - } - .canvas-model-picker-menu.is-model-list .canvas-model-picker-brand-rail { - display: none; - } -} -.canvas-model-picker-secondary-head { - display: flex; - min-width: 0; - align-items: center; - gap: 8px; - padding: 0 2px 8px; -} -.canvas-model-picker-back { - display: grid; - width: 28px; - height: 28px; - flex: 0 0 28px; - place-items: center; - border: 1px solid var(--workspace-border); - border-radius: 8px; - background: var(--workspace-surface-hover); - color: inherit; - cursor: pointer; -} -.canvas-model-picker-back svg { - width: 15px; - height: 15px; -} -.canvas-model-picker-secondary-head > span { - display: grid; - min-width: 0; - gap: 2px; -} -.canvas-model-picker-secondary-head strong { - overflow: hidden; - font-size: 13px; - text-overflow: ellipsis; - white-space: nowrap; -} -.canvas-model-picker-secondary-head small { - color: color-mix(in srgb, currentColor 52%, transparent); - font-size: 10px; -} - -/* 模型下拉:选中项与当前 hover/focus 项展示说明,其他项保持安静。 */ -.canvas-model-picker-option { - transition: background-color 160ms ease !important; -} - -.canvas-model-picker-option.is-previewed:not(:disabled) { - background: color-mix(in srgb, var(--workspace-accent) 8%, var(--workspace-surface-strong)) !important; -} - -.canvas-model-picker-description { - height: 16px; - line-height: 16px; - margin-top: 5px !important; - visibility: hidden; - opacity: 0; -} - -.canvas-model-picker-description.is-visible { - visibility: visible; - opacity: 1; -} - /* 顶栏积分中心:真实余额、充值、兑换与流水集中在一个消费型弹窗中。 */ .workspace-wallet-modal .ant-modal-container { display: flex; @@ -17852,10 +16968,8 @@ html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 @media (prefers-reduced-motion: reduce) { .creation-featured-card, - .creation-featured-media img, - .canvas-model-picker-option, - .canvas-model-picker-description, - .workspace-wallet-product { transition: none !important; } +.creation-featured-media img, +.workspace-wallet-product { transition: none !important; } .creation-featured-card:hover, .creation-featured-card:focus-visible, .workspace-wallet-product:hover, @@ -18847,8 +17961,7 @@ html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 background: transparent !important; } .app-user-workspace .creation-chat-controls { gap: 8px !important; } -.app-user-workspace .creation-chat-control, -.app-user-workspace .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { +.app-user-workspace .creation-chat-control { min-height: 40px !important; border-radius: 999px !important; background: var(--user-surface-muted) !important; @@ -18856,9 +17969,7 @@ html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 transition: background var(--user-motion), color var(--user-motion), transform var(--user-motion), box-shadow var(--user-motion) !important; } .app-user-workspace .creation-chat-control:hover, -.app-user-workspace .creation-chat-control[aria-expanded="true"], -.app-user-workspace .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover, -.app-user-workspace .creation-chat-composer .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { +.app-user-workspace .creation-chat-control[aria-expanded="true"] { background: var(--user-surface-hover) !important; color: var(--user-ink) !important; transform: translateY(-1px); @@ -18882,17 +17993,13 @@ html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 padding: 8px 16px 16px !important; border-top: 0 !important; } -.app-user-workspace .creation-launchpad .creation-chat-controls .creation-chat-control, -.app-user-workspace .creation-launchpad .creation-model-picker.canvas-composer-model-picker { +.app-user-workspace .creation-launchpad .creation-chat-controls .creation-chat-control { min-height: 36px !important; height: 36px !important; padding-inline: 12px; font-size: 12px; border: 0 !important; } -.app-user-workspace .creation-launchpad .creation-model-picker.canvas-composer-model-picker { - width: min(232px, 60cqw) !important; -} .app-user-workspace .creation-launchpad .creation-reference-add-button { border-style: dashed; border-color: var(--user-border); @@ -18902,39 +18009,6 @@ html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 transition: background var(--user-motion), border-color var(--user-motion), color var(--user-motion), transform var(--user-motion); } -/* 模型选择器:先选品牌,再选模型;品牌列表保持完整可见,不用内部滚动条。 */ -.app-user-workspace .creation-model-picker-menu { - max-height: none !important; - overflow: visible !important; - width: min(360px, calc(100vw - 24px)) !important; - padding: 10px !important; -} -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brands { display: grid; gap: 5px; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-subheading { display: flex; align-items: baseline; justify-content: space-between; padding: 3px 5px 8px; color: var(--user-ink); font-size: 12px; font-weight: 650; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-subheading small { color: var(--user-ink-soft); font-size: 10px; font-weight: 500; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand { display: flex; min-height: 58px; align-items: center; gap: 10px; border: 1px solid transparent; border-radius: 13px; padding: 8px 10px; background: transparent; color: var(--user-ink); text-align: left; transition: background-color 160ms ease, border-color 160ms ease; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand:hover { border-color: var(--user-border); background: var(--user-surface-hover); } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand-icon { display: grid; width: 34px; height: 34px; flex: 0 0 34px; place-items: center; border-radius: 11px; background: var(--user-surface-muted); color: var(--user-ink-muted); } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand-copy { display: grid; min-width: 0; flex: 1; gap: 4px; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand-copy strong { overflow: hidden; font-size: 13px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand-copy small { color: var(--user-ink-muted); font-size: 10px; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand-arrow { width: 15px; height: 15px; color: var(--user-ink-soft); transform: rotate(-90deg); } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-secondary-head { display: flex; align-items: center; gap: 8px; padding: 0 2px 9px; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-back { display: grid; width: 28px; height: 28px; place-items: center; border: 1px solid var(--user-border); border-radius: 9px; background: var(--user-surface-muted); color: var(--user-ink-muted); } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-back:hover { background: var(--user-surface-hover); color: var(--user-ink); } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-back svg { width: 15px; height: 15px; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-secondary-head > span { display: grid; gap: 2px; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-secondary-head strong { color: var(--user-ink); font-size: 13px; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-secondary-head small { color: var(--user-ink-soft); font-size: 10px; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option { min-height: 55px; border-radius: 12px; padding: 8px 9px; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { width: 32px; height: 32px; border-radius: 10px; background: var(--user-surface-muted) !important; color: var(--user-ink-muted); } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option:nth-child(3n) > span:first-child > span:first-child, -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option:nth-child(4n) > span:first-child > span:first-child { color: var(--user-ink-muted); background: var(--user-surface-muted) !important; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option .text-amber-600, -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option .dark\:text-amber-300 { display: inline-flex; align-items: center; gap: 5px; border-radius: 999px; background: color-mix(in srgb, #e28a17 12%, var(--user-surface)); color: #c66d00 !important; padding: 5px 8px; font-size: 11px; font-weight: 700; } -.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option .text-amber-600 svg { width: 13px; height: 13px; } -.dark .app-user-workspace .creation-model-picker-menu .canvas-model-picker-option .text-amber-600, -.dark .app-user-workspace .creation-model-picker-menu .canvas-model-picker-option .dark\:text-amber-300 { color: #f0a943 !important; background: color-mix(in srgb, #e28a17 18%, var(--user-surface)) !important; } .app-user-workspace .creation-launchpad .creation-mode-capsule .creation-chat-control:focus-visible, .app-user-workspace .creation-launchpad .suggest-card:focus-visible { outline: 2px solid var(--user-accent); @@ -19041,8 +18115,7 @@ html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 min-height: 44px !important; padding: 4px 10px 8px !important; } -.app-user-workspace .creation-chat-composer.is-thread .creation-chat-control, -.app-user-workspace .creation-chat-composer.is-thread .creation-model-picker.canvas-composer-model-picker { +.app-user-workspace .creation-chat-composer.is-thread .creation-chat-control { min-height: 32px !important; height: 32px !important; } @@ -19203,31 +18276,3 @@ html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 outline: var(--focus-ring-width, 2px) solid var(--control-focus-ring); outline-offset: 2px; } -.creation-model-picker-surface .creation-model-picker-menu { - max-height: none !important; - overflow: visible !important; - width: min(360px, calc(100vw - 24px)) !important; - padding: 10px !important; -} -.creation-model-picker-surface .canvas-model-picker-brands { display: grid; gap: 5px; } -.creation-model-picker-surface .canvas-model-picker-subheading { display: flex; align-items: baseline; justify-content: space-between; padding: 3px 5px 8px; color: var(--foreground); font-size: 12px; font-weight: 650; } -.creation-model-picker-surface .canvas-model-picker-subheading small { color: color-mix(in srgb, var(--foreground) 52%, transparent); font-size: 10px; font-weight: 500; } -.creation-model-picker-surface .canvas-model-picker-brand { display: flex; min-height: 58px; align-items: center; gap: 10px; border: 1px solid transparent; border-radius: 13px; padding: 8px 10px; background: transparent; color: var(--foreground); text-align: left; transition: background-color 160ms ease, border-color 160ms ease; } -.creation-model-picker-surface .canvas-model-picker-brand:hover { border-color: var(--workspace-border); background: var(--workspace-surface-hover); } -.creation-model-picker-surface .canvas-model-picker-brand-icon { display: grid; width: 34px; height: 34px; flex: 0 0 34px; place-items: center; border-radius: 11px; background: var(--workspace-surface-hover); color: var(--foreground); } -.creation-model-picker-surface .canvas-model-picker-brand-copy { display: grid; min-width: 0; flex: 1; gap: 4px; } -.creation-model-picker-surface .canvas-model-picker-brand-copy strong { overflow: hidden; font-size: 13px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; } -.creation-model-picker-surface .canvas-model-picker-brand-copy small { color: color-mix(in srgb, var(--foreground) 55%, transparent); font-size: 10px; } -.creation-model-picker-surface .canvas-model-picker-brand-arrow { width: 15px; height: 15px; color: color-mix(in srgb, var(--foreground) 48%, transparent); transform: rotate(-90deg); } -.creation-model-picker-surface .canvas-model-picker-secondary-head { display: flex; align-items: center; gap: 8px; padding: 0 2px 9px; } -.creation-model-picker-surface .canvas-model-picker-back { display: grid; width: 28px; height: 28px; place-items: center; border: 1px solid var(--workspace-border); border-radius: 9px; background: var(--workspace-surface-hover); color: var(--foreground); } -.creation-model-picker-surface .canvas-model-picker-back svg { width: 15px; height: 15px; } -.creation-model-picker-surface .canvas-model-picker-secondary-head > span { display: grid; gap: 2px; } -.creation-model-picker-surface .canvas-model-picker-secondary-head strong { color: var(--foreground); font-size: 13px; } -.creation-model-picker-surface .canvas-model-picker-secondary-head small { color: color-mix(in srgb, var(--foreground) 52%, transparent); font-size: 10px; } -.creation-model-picker-surface .canvas-model-picker-option { min-height: 55px; border-radius: 12px; padding: 8px 9px; } -.creation-model-picker-surface .canvas-model-picker-option > span:first-child > span:first-child { width: 32px; height: 32px; border-radius: 10px; background: color-mix(in srgb, var(--workspace-accent) 10%, var(--workspace-surface-strong)) !important; color: var(--workspace-accent); } -.creation-model-picker-surface .canvas-model-picker-option > span:first-child > span:first-child svg { color: currentColor !important; opacity: 1 !important; } -.creation-model-picker-surface .canvas-model-picker-option:nth-child(3n) > span:first-child > span:first-child { color: #d57b16; } -.creation-model-picker-surface .canvas-model-picker-option:nth-child(4n) > span:first-child > span:first-child { color: #25845d; } -.creation-model-picker-surface .canvas-model-picker-option .text-amber-600 { display: inline-flex; align-items: center; gap: 5px; border-radius: 999px; background: color-mix(in srgb, #e28a17 12%, var(--workspace-surface-strong)); color: #c66d00 !important; padding: 5px 8px; font-size: 11px; font-weight: 700; } diff --git a/web/src/styles/shared/model-picker.css b/web/src/styles/shared/model-picker.css new file mode 100644 index 000000000..e4152b745 --- /dev/null +++ b/web/src/styles/shared/model-picker.css @@ -0,0 +1,843 @@ +/* + * Shared ModelPicker styles. + * Keep this file globally loaded because the component renders its Ant Design + * popover through a portal and is reused across workspace, canvas, workflow, + * settings, and Agent routes. + */ + +@layer utilities { + +.creation-model-picker.canvas-composer-model-picker { + width: min(210px, 25vw); + height: 36px; + border: 1px solid var(--creation-border); + border-radius: 8px; + background: color-mix(in srgb, var(--creation-surface-muted) 70%, transparent); + color: var(--creation-text); + padding: 0 9px; + font-size: 11px; + font-weight: 600; + } + +.creation-model-picker.canvas-composer-model-picker:hover, +.creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { + border-color: var(--creation-border-strong); + background: var(--creation-surface-hover); + } + +.dark .creation-model-picker.canvas-composer-model-picker { + border: 1px solid rgba(255, 255, 255, .075); + background: rgba(38, 41, 48, .64); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .035); + } + +.dark .creation-model-picker.canvas-composer-model-picker:hover, +.dark .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { + border-color: rgba(255, 255, 255, .13); + background: rgba(48, 52, 61, .82); + } + + .creation-model-picker .canvas-model-picker-trigger-icon { + width: 22px; + height: 22px; + border-radius: 6px; + } + + .creation-model-picker-surface { + border: 1px solid rgba(220, 225, 231, .82) !important; + border-radius: 14px !important; + background: rgba(255, 255, 255, .78) !important; + box-shadow: 0 18px 46px rgba(20, 26, 35, .14), inset 0 1px 0 rgba(255, 255, 255, .78) !important; + overflow: hidden; + padding: 0 !important; + backdrop-filter: blur(28px) saturate(140%); + -webkit-backdrop-filter: blur(28px) saturate(140%); + animation: creation-popover-enter var(--motion-dur-fast-calc) var(--motion-ease-out) both; + } + + .dark .creation-model-picker-surface { + border-color: rgba(61, 66, 76, .72) !important; + background: rgba(25, 27, 32, .92) !important; + box-shadow: 0 20px 52px rgba(0, 0, 0, .34), inset 0 1px 0 rgba(255, 255, 255, .055) !important; + } + + .creation-model-picker-surface .ant-popover-inner-content { + padding: 0 !important; + } + + .creation-model-picker-menu { + width: min(384px, calc(100vw - 24px)) !important; + max-height: min(460px, calc(100vh - 24px)); + overflow-x: hidden; + overflow-y: auto; + padding: 8px !important; + background: rgba(255, 255, 255, .7) !important; + color: #17191d !important; + } + + .dark .creation-model-picker-menu { + background: rgba(25, 27, 32, .7) !important; + color: #f2f4f6 !important; + } + + .creation-model-picker-menu .canvas-model-picker-group-label { + padding: 7px 8px 6px; + font-size: 11px; + } + + .creation-model-picker-heading { + display: flex; + min-width: 0; + align-items: center; + gap: 7px; + padding: 3px 8px 9px; + color: #929aa5; + font-size: 12px; + } + + .creation-model-picker-heading strong { + min-width: 0; + overflow: hidden; + color: #17191d; + font-weight: 520; + text-overflow: ellipsis; + white-space: nowrap; + } + + .dark .creation-model-picker-heading { + color: #69717c; + } + + .dark .creation-model-picker-heading strong { + color: #f2f4f6; + } + + .creation-model-picker-menu .canvas-model-picker-option { + min-height: 52px; + border-radius: 9px; + padding: 7px 9px; + transition: background-color 150ms ease, transform 120ms ease; + } + + .creation-model-picker-menu .canvas-model-picker-option:hover { + transform: translateY(-1px); + } + + .creation-model-picker-menu .canvas-model-picker-option > span:first-child { + gap: 12px; + } + + .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { + width: 34px; + height: 34px; + border: 1px solid #e6e8eb; + border-radius: 8px; + background: rgba(255, 255, 255, .66) !important; + } + + .dark .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { + border-color: #30343b; + background: rgba(35, 38, 44, .72) !important; + } + + .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:first-child { + font-size: 13px; + } + + .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:nth-child(2) { + margin-top: 5px; + font-size: 10px; + } + +.creation-model-picker.canvas-composer-model-picker { + display: inline-flex; + height: 48px; + min-width: 0; + align-items: center; + justify-content: center; + gap: 10px; + border: 1px solid rgba(255, 255, 255, .12); + border-radius: 14px; + background: #202329; + color: #f1f3f5; + padding: 0 15px; + font-size: 14px; + font-weight: 600; + white-space: nowrap; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .055); + transition: transform 150ms var(--motion-ease-out), border-color 150ms ease, background-color 150ms ease; + } + +html:not(.dark) .creation-model-picker.canvas-composer-model-picker { + border-color: rgba(32, 37, 45, .12); + background: #f0f2f5; + color: #20242a; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .85); + } + +.creation-model-picker.canvas-composer-model-picker:hover, +.creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { + border-color: rgba(255, 255, 255, .25); + background: #292d34; + transform: translateY(-1px); + } + +html:not(.dark) .creation-model-picker.canvas-composer-model-picker:hover, +html:not(.dark) .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { background: #e7eaee; border-color: rgba(32, 37, 45, .22); } + +.creation-model-picker.canvas-composer-model-picker { + width: min(328px, 30vw); + justify-content: flex-start; + font-size: 15px; + } + .creation-model-picker .canvas-model-picker-trigger-icon { width: 25px; height: 25px; border-radius: 8px; } + .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { + display: inline-flex; + height: 32px; + min-width: 0; + align-items: center; + justify-content: center; + gap: 6px; + border: 1px solid rgba(255, 255, 255, .055); + border-radius: 8px; + background: rgba(30, 33, 39, .78); + color: #e6e9ed; + padding: 0 9px; + font-size: 11px; + font-weight: 600; + white-space: nowrap; + box-shadow: none; + transition: border-color 140ms ease, background-color 140ms ease, transform 140ms var(--motion-ease-out); + } + .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover, +.creation-chat-composer .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { border-color: rgba(255, 255, 255, .12); background: #272b32; transform: translateY(-1px); } + .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { width: min(196px, 26vw); justify-content: flex-start; } + .creation-chat-composer .creation-model-picker .canvas-model-picker-trigger-icon { width: 19px; height: 19px; border-radius: 5px; } + + html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { border-color: transparent; background: #f1f3f5; color: #262b32; } + html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover { border-color: rgba(20, 26, 35, .2); background: #e9edf1; } + @media (max-width: 800px) { +.creation-chat-composer .creation-model-picker.canvas-composer-model-picker { height: 34px; padding: 0 8px; font-size: 11px; } +.creation-chat-composer .creation-model-picker.canvas-composer-model-picker { width: min(152px, 48vw); } + +.creation-model-picker.canvas-composer-model-picker { + width: min(194px, 62vw); + height: 34px; + } + + .creation-model-picker-menu { + width: min(440px, calc(100vw - 96px)) !important; + } +.creation-model-picker.canvas-composer-model-picker { height: 42px; border-radius: 12px; padding: 0 11px; font-size: 12px; } +.creation-model-picker.canvas-composer-model-picker { width: min(150px, 44vw); } +} + + .canvas-composer-tools .canvas-model-picker-label > span:nth-child(n + 2) { + display: none; + } + + .canvas-composer-tools .canvas-composer-model-picker { + width: 32px; + min-width: 32px; + } + + .canvas-composer-tools .canvas-composer-model-picker { + padding-inline: 7px !important; + } + + .canvas-composer-tools .canvas-model-picker-label { + min-width: 0; + } + + .canvas-composer-model-picker { + align-items: center; + appearance: none; + background: color-mix(in srgb, var(--workspace-surface-strong) 94%, var(--workspace-accent) 6%); + border: 0; + border-radius: 9px; + color: var(--foreground); + cursor: pointer; + display: flex; + font: inherit; + gap: 8px; + height: 32px; + justify-content: space-between; + line-height: 1; + max-width: 100%; + min-width: 0; + outline: none !important; + padding: 0 9px; + text-align: left; + transition: background-color var(--motion-instant) ease-out, color var(--motion-instant) ease-out; + } + + .canvas-composer-model-picker:hover { + background: color-mix(in srgb, var(--workspace-surface-strong) 88%, var(--workspace-accent) 12%); + } + + .canvas-composer-model-picker:focus, +.canvas-composer-model-picker:focus-visible, +.canvas-composer-model-picker[aria-expanded="true"] { + background: color-mix(in srgb, var(--workspace-surface-strong) 84%, var(--workspace-accent) 16%); + box-shadow: none !important; + outline: none !important; + } + + .canvas-model-picker-label { + flex: 1 1 auto; + overflow: hidden; + } + + .canvas-model-picker-trigger-icon { + align-items: center; + border-radius: 6px; + display: inline-flex; + flex: 0 0 22px; + height: 22px; + justify-content: center; + width: 22px; + } + + .canvas-model-picker-chevron { + color: color-mix(in srgb, var(--foreground) 52%, transparent); + flex: 0 0 14px; + height: 14px; + transition: transform var(--motion-instant) ease-out; + width: 14px; + } + + .canvas-model-picker-chevron.is-open { + transform: rotate(180deg); + } + + .canvas-model-picker-popover { + filter: none !important; + } + + .canvas-model-picker-menu { + width: max-content !important; + min-width: max(var(--canvas-model-picker-trigger-width, 0px), 260px); + max-width: calc(100vw - 24px); + max-height: min(420px, calc(100vh - 32px)); + overflow-x: hidden; + overflow-y: auto; + padding: 4px; + } + + .canvas-model-picker-group + .canvas-model-picker-group { + border-top: 1px solid var(--workspace-border); + margin-top: 5px; + padding-top: 5px; + } + + .canvas-model-picker-group-label { + align-items: center; + display: flex; + font-size: 10px; + font-weight: 600; + gap: 6px; + letter-spacing: 0.02em; + min-width: 0; + padding: 5px 7px 4px; + } + + .canvas-model-picker-option { + align-items: center; + border: 0; + border-radius: 7px; + cursor: pointer; + display: flex; + gap: 8px; + max-width: 100%; + min-height: 40px; + min-width: 0; + outline: none; + overflow: hidden; + padding: 6px 7px; + text-align: left; + transition: background-color var(--motion-instant) ease-out; + width: 100%; + } + + .canvas-model-picker-option:hover { + background: color-mix(in srgb, var(--workspace-accent) 9%, transparent) !important; + } + + .canvas-model-picker-option[aria-selected="true"] { + background: color-mix(in srgb, var(--workspace-accent) 6%, transparent) !important; + } + + .canvas-model-picker-option:focus-visible { + background: color-mix(in srgb, var(--workspace-accent) 13%, transparent) !important; + outline: none; + } + + .canvas-model-picker-option > span:first-child { + flex: 1 1 auto; + min-width: 0; + overflow: hidden; + display: flex; + align-items: center; + width: 100%; + } + + .canvas-model-picker-popover .canvas-model-picker-option > span:first-child > span:nth-child(2) { + flex: 0 0 auto; + min-width: max-content; + overflow: visible; + } + + .canvas-model-picker-popover .canvas-model-picker-option > span:first-child > span:nth-child(2) > span { + overflow: visible; + text-overflow: clip; + } + + .canvas-model-picker-option-check { + flex: 0 0 14px; + height: 14px; + width: 14px; + } + + .canvas-model-picker-empty { + font-size: 11px; + padding: 22px 12px; + text-align: center; + } + + html:not(.dark) .canvas-composer-model-picker { + background: rgba(15, 23, 42, 0.045) !important; + color: #1f2937 !important; + } + + html:not(.dark) .canvas-composer-model-picker:hover, +html:not(.dark) .canvas-composer-model-picker[aria-expanded="true"] { + background: rgba(15, 23, 42, 0.075) !important; + } + + @container (min-width: 440px) { + + .canvas-composer-tools .canvas-composer-model-picker { + width: auto; + min-width: 9rem; + } + + .canvas-composer-tools .canvas-composer-model-picker { + padding-inline: 10px !important; + } + + .canvas-composer-tools .canvas-model-picker-label > span:nth-child(n + 2) { + display: inline-flex; + } +} + + .canvas-prompt-optimizer-model-picker:focus-visible { + outline: 2px solid color-mix(in srgb, var(--workspace-accent) 64%, transparent); + outline-offset: 1px; + } + + .canvas-prompt-optimizer-model-picker.canvas-composer-model-picker { + flex: 1 1 132px; + width: 132px !important; + max-width: 132px; + min-width: 0 !important; + height: 28px !important; + border-color: transparent !important; + border-radius: var(--r-md) !important; + background: transparent !important; + padding: 0 6px !important; + color: color-mix(in srgb, var(--foreground) 62%, transparent) !important; + font-size: var(--fs-micro) !important; + } + + .canvas-prompt-optimizer-model-picker.canvas-composer-model-picker:hover, +.canvas-prompt-optimizer-model-picker.canvas-composer-model-picker[aria-expanded="true"] { + border-color: transparent !important; + background: color-mix(in srgb, var(--foreground) 7%, transparent) !important; + color: var(--foreground) !important; + } + + .canvas-prompt-optimizer-model-picker .canvas-model-picker-trigger-icon { + width: 18px; + height: 18px; + border-radius: 5px; + } + + .canvas-prompt-optimizer-model-picker .canvas-model-picker-label { + gap: 5px; + } + + .canvas-prompt-optimizer-model-picker .canvas-model-picker-chevron { + width: 11px; + height: 11px; + } + + .canvas-prompt-optimizer-model-popover .creation-model-picker-heading { + display: none; + } + + @container (max-width: 420px) { + + .canvas-prompt-optimizer-model-picker.canvas-composer-model-picker { + max-width: 112px; + } +} + + @container (max-width: 350px) { + + .canvas-prompt-optimizer-model-picker.canvas-composer-model-picker { + max-width: 96px; + padding-inline: 3px !important; + } +} + .creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { + border: 0; + background: transparent; + box-shadow: none; + color: var(--creation-muted); + } + + .creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover, +.creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { + border: 0; + background: rgba(255, 255, 255, .065); + color: var(--creation-text); + transform: none; + } +} + +.creation-chat-composer .creation-model-picker.canvas-composer-model-picker { + display: inline-flex; + height: 32px; + min-width: 0; + align-items: center; + gap: 5px; + border: 0; + border-radius: var(--r-md); + background: transparent; + color: var(--creation-muted); + padding: 0 8px; + font-size: 11px; + font-weight: 500; + box-shadow: none; + transition: color var(--motion-state) ease, background-color var(--motion-state) ease, transform var(--motion-state) var(--motion-ease-out); +} + +.creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover, +.creation-chat-composer .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { + border: 0; + background: rgba(255, 255, 255, .075); + color: var(--creation-text); + transform: none; +} +.creation-chat-composer .creation-model-picker.canvas-composer-model-picker { width: min(180px, 30vw); justify-content: flex-start; } +.creation-chat-composer .creation-model-picker .canvas-model-picker-trigger-icon { width: 16px; height: 16px; border-radius: 4px; background: transparent !important; } + +html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { background: transparent; color: var(--creation-muted); } +html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover { background: rgba(29, 33, 37, .06); color: var(--creation-text); } + +.creation-model-picker-surface { + overflow: hidden; + border: 0 !important; + border-radius: 10px !important; + background: rgba(30, 32, 37, .92) !important; + box-shadow: 0 18px 44px rgba(0, 0, 0, .3) !important; + backdrop-filter: blur(18px) saturate(120%); + -webkit-backdrop-filter: blur(18px) saturate(120%); +} + +.creation-model-picker-surface .ant-popover-inner-content { padding: 0 !important; } + +.creation-model-picker-menu { width: min(332px, calc(100vw - 24px)) !important; max-height: min(420px, calc(100vh - 24px)); padding: 7px !important; background: transparent !important; color: #f0f1f2 !important; } +.creation-model-picker-heading { display: flex; align-items: center; gap: 6px; padding: 4px 7px 7px; color: #8e949d; font-size: 10px; } +.creation-model-picker-heading strong { color: #e6e8eb; font-weight: 500; } +.creation-model-picker-menu .canvas-model-picker-group-label { padding: 6px 7px 5px; font-size: 10px; } +.creation-model-picker-menu .canvas-model-picker-option { min-height: 43px; border-radius: 6px; padding: 5px 7px; } +.creation-model-picker-menu .canvas-model-picker-option:hover { transform: none; } +.creation-model-picker-menu .canvas-model-picker-option > span:first-child { gap: 8px; } +.creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { width: 26px; height: 26px; border: 0; border-radius: 5px; background: rgba(255, 255, 255, .07) !important; } +.creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:first-child { font-size: 11px; } +.creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:nth-child(2) { margin-top: 3px; font-size: 9px; } + +html:not(.dark) .creation-model-picker-surface { background: rgba(255, 255, 255, .94) !important; box-shadow: 0 16px 38px rgba(28, 32, 37, .12) !important; } +html:not(.dark) .creation-model-picker-menu { color: #727980 !important; } +html:not(.dark) .creation-model-picker-heading strong { color: #20242a; } +html:not(.dark) .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { background: rgba(28, 32, 37, .06) !important; } +@media (max-width: 680px) { +.creation-chat-composer .creation-model-picker.canvas-composer-model-picker { height: 29px; padding: 0 6px; font-size: 10px; } +.creation-chat-composer .creation-model-picker.canvas-composer-model-picker { width: min(136px, 42vw); } +} + +.creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { + border: 0; + background: transparent; + box-shadow: none; + color: var(--creation-muted); +} + +.creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover, +.creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { + border: 0; + background: rgba(255, 255, 255, .065); + color: var(--creation-text); + transform: none; +} + +html:not(.dark) .creation-home .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover { background: rgba(28, 32, 37, .06); } +.canvas-model-picker-brands { + display: grid; + gap: 4px; + width: 100%; +} +.canvas-model-picker-brand { + display: flex; + width: 100%; + min-height: 48px; + min-width: 0; + align-items: center; + gap: 10px; + border: 1px solid transparent; + border-radius: 10px; + padding: 8px 10px; + background: transparent; + color: inherit; + text-align: left; + cursor: pointer; +} +.canvas-model-picker-brand:hover, +.canvas-model-picker-brand.is-active { + border-color: var(--workspace-border); + background: var(--workspace-surface-hover); +} +.canvas-model-picker-brand-icon { + display: grid; + width: 32px; + height: 32px; + flex: 0 0 32px; + place-items: center; + border-radius: 9px; + background: var(--workspace-surface-hover); +} +.canvas-model-picker-brand-copy { + display: grid; + min-width: 0; + flex: 1; + gap: 2px; +} +.canvas-model-picker-brand-copy strong { + overflow: hidden; + font-size: 13px; + font-weight: 650; + text-overflow: ellipsis; + white-space: nowrap; +} +.canvas-model-picker-brand-copy small { + overflow: hidden; + color: color-mix(in srgb, currentColor 55%, transparent); + font-size: 10px; + text-overflow: ellipsis; + white-space: nowrap; +} +.canvas-model-picker-brand-arrow { + width: 14px; + height: 14px; + flex: 0 0 14px; + color: color-mix(in srgb, currentColor 48%, transparent); + transform: rotate(-90deg); +} +/* 品牌/模型两级菜单是 ModelPicker 默认结构,不能只写在 creation variant 下。 */ +.canvas-model-picker-menu.is-brand-list { + width: min(360px, calc(100vw - 24px)) !important; +} +.canvas-model-picker-menu.is-model-list { + width: min(720px, calc(100vw - 24px)) !important; +} +.canvas-model-picker-two-pane { + display: grid; + width: 100%; + grid-template-columns: 250px minmax(0, 1fr); + gap: 14px; + min-width: 0; + align-items: start; +} +.canvas-model-picker-menu.is-model-list .canvas-model-picker-brand-rail { + display: grid; + align-content: start; + gap: 5px; + border-right: 1px solid var(--workspace-border); + padding-right: 14px; +} +.canvas-model-picker-menu.is-model-list .canvas-model-picker-brand { + width: 100%; +} +.canvas-model-picker-model-pane { + min-width: 0; +} +@media (max-width: 720px) { + .canvas-model-picker-menu:is(.is-brand-list, .is-model-list) { + width: calc(100vw - 24px) !important; + } + .canvas-model-picker-two-pane { + grid-template-columns: minmax(0, 1fr); + } + .canvas-model-picker-menu.is-model-list .canvas-model-picker-brand-rail { + display: none; + } +} +.canvas-model-picker-secondary-head { + display: flex; + min-width: 0; + align-items: center; + gap: 8px; + padding: 0 2px 8px; +} +.canvas-model-picker-back { + display: grid; + width: 28px; + height: 28px; + flex: 0 0 28px; + place-items: center; + border: 1px solid var(--workspace-border); + border-radius: 8px; + background: var(--workspace-surface-hover); + color: inherit; + cursor: pointer; +} +.canvas-model-picker-back svg { + width: 15px; + height: 15px; +} +.canvas-model-picker-secondary-head > span { + display: grid; + min-width: 0; + gap: 2px; +} +.canvas-model-picker-secondary-head strong { + overflow: hidden; + font-size: 13px; + text-overflow: ellipsis; + white-space: nowrap; +} +.canvas-model-picker-secondary-head small { + color: color-mix(in srgb, currentColor 52%, transparent); + font-size: 10px; +} +/* 模型下拉:选中项与当前 hover/focus 项展示说明,其他项保持安静。 */ +.canvas-model-picker-option { + transition: background-color 160ms ease !important; +} + +.canvas-model-picker-option.is-previewed:not(:disabled) { + background: color-mix(in srgb, var(--workspace-accent) 8%, var(--workspace-surface-strong)) !important; +} + +.canvas-model-picker-description { + height: 16px; + line-height: 16px; + margin-top: 5px !important; + visibility: hidden; + opacity: 0; +} + +.canvas-model-picker-description.is-visible { + visibility: visible; + opacity: 1; +} + +@media (prefers-reduced-motion: reduce) { + .canvas-model-picker-option, +.canvas-model-picker-description { transition: none !important; } +} +.app-user-workspace .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { + min-height: 40px !important; + border-radius: 999px !important; + background: var(--user-surface-muted) !important; + color: var(--user-ink-muted) !important; + transition: background var(--user-motion), color var(--user-motion), transform var(--user-motion), box-shadow var(--user-motion) !important; +} +.app-user-workspace .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover, +.app-user-workspace .creation-chat-composer .creation-model-picker.canvas-composer-model-picker[aria-expanded="true"] { + background: var(--user-surface-hover) !important; + color: var(--user-ink) !important; + transform: translateY(-1px); + box-shadow: 0 8px 18px color-mix(in srgb, var(--user-ink) 8%, transparent); +} +.app-user-workspace .creation-launchpad .creation-model-picker.canvas-composer-model-picker { + min-height: 36px !important; + height: 36px !important; + padding-inline: 12px; + font-size: 12px; + border: 0 !important; +} +.app-user-workspace .creation-launchpad .creation-model-picker.canvas-composer-model-picker { + width: min(232px, 60cqw) !important; +} +/* 模型选择器:先选品牌,再选模型;品牌列表保持完整可见,不用内部滚动条。 */ +.app-user-workspace .creation-model-picker-menu.is-brand-list { + max-height: none !important; + overflow: visible !important; + width: min(360px, calc(100vw - 24px)) !important; + padding: 10px !important; +} +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brands { display: grid; gap: 5px; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-subheading { display: flex; align-items: baseline; justify-content: space-between; padding: 3px 5px 8px; color: var(--user-ink); font-size: 12px; font-weight: 650; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-subheading small { color: var(--user-ink-soft); font-size: 10px; font-weight: 500; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand { display: flex; min-height: 58px; align-items: center; gap: 10px; border: 1px solid transparent; border-radius: 13px; padding: 8px 10px; background: transparent; color: var(--user-ink); text-align: left; transition: background-color 160ms ease, border-color 160ms ease; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand:hover { border-color: var(--user-border); background: var(--user-surface-hover); } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand-icon { display: grid; width: 34px; height: 34px; flex: 0 0 34px; place-items: center; border-radius: 11px; background: var(--user-surface-muted); color: var(--user-ink-muted); } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand-copy { display: grid; min-width: 0; flex: 1; gap: 4px; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand-copy strong { overflow: hidden; font-size: 13px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand-copy small { color: var(--user-ink-muted); font-size: 10px; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-brand-arrow { width: 15px; height: 15px; color: var(--user-ink-soft); transform: rotate(-90deg); } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-secondary-head { display: flex; align-items: center; gap: 8px; padding: 0 2px 9px; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-back { display: grid; width: 28px; height: 28px; place-items: center; border: 1px solid var(--user-border); border-radius: 9px; background: var(--user-surface-muted); color: var(--user-ink-muted); } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-back:hover { background: var(--user-surface-hover); color: var(--user-ink); } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-back svg { width: 15px; height: 15px; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-secondary-head > span { display: grid; gap: 2px; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-secondary-head strong { color: var(--user-ink); font-size: 13px; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-secondary-head small { color: var(--user-ink-soft); font-size: 10px; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option { min-height: 55px; border-radius: 12px; padding: 8px 9px; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { width: 32px; height: 32px; border-radius: 10px; background: var(--user-surface-muted) !important; color: var(--user-ink-muted); } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option:nth-child(3n) > span:first-child > span:first-child, +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option:nth-child(4n) > span:first-child > span:first-child { color: var(--user-ink-muted); background: var(--user-surface-muted) !important; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option .text-amber-600, +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option .dark\:text-amber-300 { display: inline-flex; align-items: center; gap: 5px; border-radius: 999px; background: color-mix(in srgb, #e28a17 12%, var(--user-surface)); color: #c66d00 !important; padding: 5px 8px; font-size: 11px; font-weight: 700; } +.app-user-workspace .creation-model-picker-menu .canvas-model-picker-option .text-amber-600 svg { width: 13px; height: 13px; } +.dark .app-user-workspace .creation-model-picker-menu .canvas-model-picker-option .text-amber-600, +.dark .app-user-workspace .creation-model-picker-menu .canvas-model-picker-option .dark\:text-amber-300 { color: #f0a943 !important; background: color-mix(in srgb, #e28a17 18%, var(--user-surface)) !important; } +.app-user-workspace .creation-chat-composer.is-thread .creation-model-picker.canvas-composer-model-picker { + min-height: 32px !important; + height: 32px !important; +} +.creation-model-picker-surface .creation-model-picker-menu.is-model-list { + max-height: min(460px, calc(100vh - 24px)) !important; + overflow-x: hidden !important; + overflow-y: auto !important; +} +.creation-model-picker-surface .creation-model-picker-menu.is-brand-list { + max-height: none !important; + overflow: visible !important; + width: min(360px, calc(100vw - 24px)) !important; + padding: 10px !important; +} +.creation-model-picker-surface .canvas-model-picker-brands { display: grid; gap: 5px; } +.creation-model-picker-surface .canvas-model-picker-subheading { display: flex; align-items: baseline; justify-content: space-between; padding: 3px 5px 8px; color: var(--foreground); font-size: 12px; font-weight: 650; } +.creation-model-picker-surface .canvas-model-picker-subheading small { color: color-mix(in srgb, var(--foreground) 52%, transparent); font-size: 10px; font-weight: 500; } +.creation-model-picker-surface .canvas-model-picker-brand { display: flex; min-height: 58px; align-items: center; gap: 10px; border: 1px solid transparent; border-radius: 13px; padding: 8px 10px; background: transparent; color: var(--foreground); text-align: left; transition: background-color 160ms ease, border-color 160ms ease; } +.creation-model-picker-surface .canvas-model-picker-brand:hover { border-color: var(--workspace-border); background: var(--workspace-surface-hover); } +.creation-model-picker-surface .canvas-model-picker-brand-icon { display: grid; width: 34px; height: 34px; flex: 0 0 34px; place-items: center; border-radius: 11px; background: var(--workspace-surface-hover); color: var(--foreground); } +.creation-model-picker-surface .canvas-model-picker-brand-copy { display: grid; min-width: 0; flex: 1; gap: 4px; } +.creation-model-picker-surface .canvas-model-picker-brand-copy strong { overflow: hidden; font-size: 13px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; } +.creation-model-picker-surface .canvas-model-picker-brand-copy small { color: color-mix(in srgb, var(--foreground) 55%, transparent); font-size: 10px; } +.creation-model-picker-surface .canvas-model-picker-brand-arrow { width: 15px; height: 15px; color: color-mix(in srgb, var(--foreground) 48%, transparent); transform: rotate(-90deg); } +.creation-model-picker-surface .canvas-model-picker-secondary-head { display: flex; align-items: center; gap: 8px; padding: 0 2px 9px; } +.creation-model-picker-surface .canvas-model-picker-back { display: grid; width: 28px; height: 28px; place-items: center; border: 1px solid var(--workspace-border); border-radius: 9px; background: var(--workspace-surface-hover); color: var(--foreground); } +.creation-model-picker-surface .canvas-model-picker-back svg { width: 15px; height: 15px; } +.creation-model-picker-surface .canvas-model-picker-secondary-head > span { display: grid; gap: 2px; } +.creation-model-picker-surface .canvas-model-picker-secondary-head strong { color: var(--foreground); font-size: 13px; } +.creation-model-picker-surface .canvas-model-picker-secondary-head small { color: color-mix(in srgb, var(--foreground) 52%, transparent); font-size: 10px; } +.creation-model-picker-surface .canvas-model-picker-option { min-height: 55px; border-radius: 12px; padding: 8px 9px; } +.creation-model-picker-surface .canvas-model-picker-option > span:first-child > span:first-child { width: 32px; height: 32px; border-radius: 10px; background: color-mix(in srgb, var(--workspace-accent) 10%, var(--workspace-surface-strong)) !important; color: var(--workspace-accent); } +.creation-model-picker-surface .canvas-model-picker-option > span:first-child > span:first-child svg { color: currentColor !important; opacity: 1 !important; } +.creation-model-picker-surface .canvas-model-picker-option:nth-child(3n) > span:first-child > span:first-child { color: #d57b16; } +.creation-model-picker-surface .canvas-model-picker-option:nth-child(4n) > span:first-child > span:first-child { color: #25845d; } +.creation-model-picker-surface .canvas-model-picker-option .text-amber-600 { display: inline-flex; align-items: center; gap: 5px; border-radius: 999px; background: color-mix(in srgb, #e28a17 12%, var(--workspace-surface-strong)); color: #c66d00 !important; padding: 5px 8px; font-size: 11px; font-weight: 700; } diff --git a/web/src/styles/shared/overlays.css b/web/src/styles/shared/overlays.css new file mode 100644 index 000000000..e828ea8d5 --- /dev/null +++ b/web/src/styles/shared/overlays.css @@ -0,0 +1,28 @@ +/* Shared React Aria overlay entrance animation used by select and tooltip. */ +@keyframes ra-pop-in { + from { + opacity: 0; + transform: translateY(-3px) scale(0.985); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +.ra-pop-in { + transform-origin: var(--ra-pop-origin, top); + animation: ra-pop-in var(--ra-pop-duration, 150ms) var(--workspace-ease, cubic-bezier(0.4, 0, 0.2, 1)); +} + +/* React Aria exposes the placement on the floating element. */ +.ra-pop-in[data-placement^="top"] { --ra-pop-origin: bottom center; } +.ra-pop-in[data-placement^="bottom"] { --ra-pop-origin: top center; } +.ra-pop-in[data-placement^="left"] { --ra-pop-origin: right center; } +.ra-pop-in[data-placement^="right"] { --ra-pop-origin: left center; } + +@media (prefers-reduced-motion: reduce) { + .ra-pop-in { + animation: none; + } +} diff --git a/web/src/styles/shared/scrollbars.css b/web/src/styles/shared/scrollbars.css new file mode 100644 index 000000000..f52f1315b --- /dev/null +++ b/web/src/styles/shared/scrollbars.css @@ -0,0 +1,114 @@ +@layer utilities { + /* Shared scrollbar utilities used by canvas, project, settings and admin surfaces. */ + .hide-scrollbar { + -ms-overflow-style: none; + scrollbar-width: none; + } + + .hide-scrollbar::-webkit-scrollbar { + display: none; + } + + .thin-scrollbar { + scrollbar-color: rgba(120, 113, 108, 0.45) transparent; + scrollbar-width: thin; + } + + .thin-scrollbar::-webkit-scrollbar { + height: 4px; + width: 4px; + } + + .thin-scrollbar::-webkit-scrollbar-thumb { + background: rgba(120, 113, 108, 0.45); + border-radius: 999px; + } + + .storyboard-scrollbar { + overscroll-behavior: contain; + scrollbar-color: rgba(148, 163, 184, 0.72) rgba(120, 113, 108, 0.14); + scrollbar-gutter: stable; + scrollbar-width: auto; + } + + /* 表头与滚动行区共享同宽 scrollbar gutter,保证列线对齐;滚动条本身透明隐藏 */ + .storyboard-header-gutter { + overflow-x: hidden; + overflow-y: scroll; + scrollbar-color: transparent transparent; + scrollbar-gutter: stable; + scrollbar-width: auto; + } + + .storyboard-scrollbar::-webkit-scrollbar { + width: 12px; + } + + .storyboard-scrollbar::-webkit-scrollbar-track { + background: rgba(120, 113, 108, 0.14); + border-left: 1px solid rgba(120, 113, 108, 0.18); + } + + .storyboard-scrollbar::-webkit-scrollbar-thumb { + min-height: 40px; + border: 2px solid transparent; + border-radius: 999px; + background: rgba(148, 163, 184, 0.72); + background-clip: content-box; + } + + .storyboard-scrollbar::-webkit-scrollbar-thumb:hover { + background: rgba(186, 196, 210, 0.9); + background-clip: content-box; + } + + .hover-scrollbar { + scrollbar-color: transparent transparent; + scrollbar-width: thin; + } + + .hover-scrollbar:hover { + scrollbar-color: rgba(120, 113, 108, 0.5) transparent; + } + + .hover-scrollbar::-webkit-scrollbar { + height: 6px; + width: 6px; + } + + .hover-scrollbar::-webkit-scrollbar-thumb { + background: transparent; + border-radius: 999px; + } + + .hover-scrollbar:hover::-webkit-scrollbar-track { + background: rgba(120, 113, 108, 0.12); + border-radius: 999px; + } + + .hover-scrollbar:hover::-webkit-scrollbar-thumb { + background: rgba(120, 113, 108, 0.5); + } + + .hover-scrollbar-hint { + position: relative; + } + + .hover-scrollbar-hint::after { + background: rgba(120, 113, 108, 0.42); + border-radius: 999px; + bottom: 4px; + content: ""; + height: 3px; + left: 12px; + opacity: 0; + pointer-events: none; + position: absolute; + right: 12px; + transition: opacity 0.18s ease; + } + + .hover-scrollbar-hint:hover::after { + opacity: 1; + } +} diff --git a/web/test/canvas-file-upload-style.test.ts b/web/test/canvas-file-upload-style.test.ts new file mode 100644 index 000000000..4dd061d31 --- /dev/null +++ b/web/test/canvas-file-upload-style.test.ts @@ -0,0 +1,32 @@ +import { expect, test } from "bun:test"; + +test("画布文件上传占位样式由组件独立加载", async () => { + const [component, globals, styles] = await Promise.all([ + Bun.file(new URL("../src/components/canvas/canvas-file-upload-content.tsx", import.meta.url)).text(), + Bun.file(new URL("../src/styles/globals.css", import.meta.url)).text(), + Bun.file(new URL("../src/components/canvas/canvas-file-upload.css", import.meta.url)).text(), + ]); + + expect(component).toContain('import "./canvas-file-upload.css";'); + expect(globals).not.toContain(".canvas-file-upload {"); + expect(globals).not.toContain("@keyframes canvas-file-upload-drift"); + expect(styles).toContain(".canvas-file-upload {"); + expect(styles).toContain(".canvas-file-upload-retry:focus-visible"); + expect(styles).toContain("@keyframes canvas-file-upload-drift"); + expect(styles).toContain("@media (prefers-reduced-motion: reduce)"); +}); + +test("React Aria 浮层动画保留全局入口,但不再占用 globals.css", async () => { + const [application, globals, styles] = await Promise.all([ + Bun.file(new URL("../src/application.tsx", import.meta.url)).text(), + Bun.file(new URL("../src/styles/globals.css", import.meta.url)).text(), + Bun.file(new URL("../src/styles/shared/overlays.css", import.meta.url)).text(), + ]); + + expect(application).toContain('import "./styles/shared/overlays.css";'); + expect(globals).not.toContain("@keyframes ra-pop-in"); + expect(globals).not.toContain(".ra-pop-in {"); + expect(styles).toContain("@keyframes ra-pop-in"); + expect(styles).toContain('.ra-pop-in[data-placement^="bottom"]'); + expect(styles).toContain("prefers-reduced-motion: reduce"); +}); diff --git a/web/test/model-picker-style-source.test.ts b/web/test/model-picker-style-source.test.ts new file mode 100644 index 000000000..b48d58b83 --- /dev/null +++ b/web/test/model-picker-style-source.test.ts @@ -0,0 +1,27 @@ +import { expect, test } from "bun:test"; + +test("ModelPicker 样式独立加载,并保留模型列表的视口边界", async () => { + const [application, globals, pickerStyles] = await Promise.all([ + Bun.file(new URL("../src/application.tsx", import.meta.url)).text(), + Bun.file(new URL("../src/styles/globals.css", import.meta.url)).text(), + Bun.file(new URL("../src/styles/shared/model-picker.css", import.meta.url)).text(), + ]); + + expect(application).toContain('import "./styles/shared/model-picker.css";'); + expect(globals).not.toContain("canvas-model-picker"); + expect(pickerStyles).toContain(".canvas-model-picker-menu {"); + expect(pickerStyles).toContain("max-height: min(420px, calc(100vh - 32px));"); + + const creationMenu = pickerStyles.match(/\.creation-model-picker-menu \{([\s\S]*?)\}/)?.[1] || ""; + expect(creationMenu).toContain("max-height: min(460px, calc(100vh - 24px));"); + expect(creationMenu).toContain("overflow-y: auto;"); + expect(pickerStyles).toContain(".app-user-workspace .creation-model-picker-menu.is-brand-list"); + expect(pickerStyles).toContain(".creation-model-picker-surface .creation-model-picker-menu.is-model-list"); + expect(pickerStyles).toContain(".creation-model-picker-surface .creation-model-picker-menu.is-brand-list"); + + const modelList = pickerStyles.match(/\.creation-model-picker-surface \.creation-model-picker-menu\.is-model-list \{([\s\S]*?)\}/)?.[1] || ""; + expect(modelList).toContain("max-height: min(460px, calc(100vh - 24px)) !important;"); + expect(modelList).toContain("overflow-y: auto !important;"); + expect(pickerStyles).not.toContain(".app-user-workspace .creation-model-picker-menu {"); + expect(pickerStyles).not.toContain(".creation-model-picker-surface .creation-model-picker-menu {"); +}); diff --git a/web/test/scrollbar-style-source.test.ts b/web/test/scrollbar-style-source.test.ts new file mode 100644 index 000000000..753a8ce45 --- /dev/null +++ b/web/test/scrollbar-style-source.test.ts @@ -0,0 +1,32 @@ +import { expect, test } from "bun:test"; + +test("滚动条样式按复用边界拆分,并保持全局入口可用", async () => { + const [application, globals, shared, creation, creationWorkspace, editor, editorShell] = await Promise.all([ + Bun.file(new URL("../src/application.tsx", import.meta.url)).text(), + Bun.file(new URL("../src/styles/globals.css", import.meta.url)).text(), + Bun.file(new URL("../src/styles/shared/scrollbars.css", import.meta.url)).text(), + Bun.file(new URL("../src/pages/create/creation-scrollbars.css", import.meta.url)).text(), + Bun.file(new URL("../src/pages/create/creation-workspace.tsx", import.meta.url)).text(), + Bun.file(new URL("../src/lib/plugins/builtin/editor/editor-shell.css", import.meta.url)).text(), + Bun.file(new URL("../src/lib/plugins/builtin/editor/editor-shell.tsx", import.meta.url)).text(), + ]); + + expect(application).toContain('import "./styles/shared/scrollbars.css";'); + expect(globals).not.toContain(".hide-scrollbar {"); + expect(globals).not.toContain(".thin-scrollbar {"); + expect(globals).not.toContain(".storyboard-scrollbar {"); + expect(globals).not.toContain(".hover-scrollbar {"); + expect(globals).not.toContain(".creation-scrollbar {"); + expect(globals).not.toContain(".director-scroll {"); + expect(globals).not.toContain(".editor-slider {"); + + expect(shared).toContain(".hide-scrollbar {"); + expect(shared).toContain(".thin-scrollbar {"); + expect(shared).toContain(".storyboard-scrollbar {"); + expect(shared).toContain(".hover-scrollbar {"); + expect(creation).toContain(".creation-scrollbar {"); + expect(creationWorkspace).toContain('import "./creation-scrollbars.css";'); + expect(editor).toContain(".director-scroll {"); + expect(editor).toContain(".editor-slider {"); + expect(editorShell).toContain('import "./editor-shell.css";'); +});