refactor(web): 样式体系 - 拆分模型选择、滚动条与编辑器样式
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -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();
|
||||
|
||||
71
web/src/components/canvas/canvas-file-upload.css
Normal file
71
web/src/components/canvas/canvas-file-upload.css
Normal file
@@ -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; }
|
||||
}
|
||||
73
web/src/lib/plugins/builtin/editor/editor-shell.css
Normal file
73
web/src/lib/plugins/builtin/editor/editor-shell.css
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
|
||||
23
web/src/pages/create/creation-scrollbars.css
Normal file
23
web/src/pages/create/creation-scrollbars.css
Normal file
@@ -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); }
|
||||
}
|
||||
@@ -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 })));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
843
web/src/styles/shared/model-picker.css
Normal file
843
web/src/styles/shared/model-picker.css
Normal file
@@ -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; }
|
||||
28
web/src/styles/shared/overlays.css
Normal file
28
web/src/styles/shared/overlays.css
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
114
web/src/styles/shared/scrollbars.css
Normal file
114
web/src/styles/shared/scrollbars.css
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
32
web/test/canvas-file-upload-style.test.ts
Normal file
32
web/test/canvas-file-upload-style.test.ts
Normal file
@@ -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");
|
||||
});
|
||||
27
web/test/model-picker-style-source.test.ts
Normal file
27
web/test/model-picker-style-source.test.ts
Normal file
@@ -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 {");
|
||||
});
|
||||
32
web/test/scrollbar-style-source.test.ts
Normal file
32
web/test/scrollbar-style-source.test.ts
Normal file
@@ -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";');
|
||||
});
|
||||
Reference in New Issue
Block a user